diff --git a/third_party/flatbuffers/.appveyor/check-generate-code.bat b/third_party/flatbuffers/.appveyor/check-generate-code.bat
new file mode 100644
index 0000000..ba7398a
--- /dev/null
+++ b/third_party/flatbuffers/.appveyor/check-generate-code.bat
@@ -0,0 +1,41 @@
+:: 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.
+set buildtype=Release
+if "%1"=="-b" set buildtype=%2
+
+cd tests
+call generate_code.bat -b %buildtype% || goto FAIL
+
+:: TODO: Release and Debug builds produce differences here for some reason.
+git checkout HEAD -- monster_test.bfbs
+git checkout HEAD -- arrays_test.bfbs
+
+git -c core.autocrlf=true diff --exit-code --quiet || goto :DIFFFOUND
+goto SUCCESS
+
+:DIFFFOUND
+@echo "" >&2
+@echo "ERROR: ********************************************************" >&2
+@echo "ERROR: The following differences were found after running the" >&2
+@echo "ERROR: tests/generate_code.sh script.  Maybe you forgot to run" >&2
+@echo "ERROR: it after making changes in a generator or schema?" >&2
+@echo "ERROR: ********************************************************" >&2
+@echo "" >&2
+@git -c core.autocrlf=true --no-pager diff --binary
+
+:FAIL
+set EXITCODE=1
+:SUCCESS
+cd ..
+EXIT /B %EXITCODE%
\ No newline at end of file
diff --git a/third_party/flatbuffers/.bazelci/presubmit.yml b/third_party/flatbuffers/.bazelci/presubmit.yml
new file mode 100644
index 0000000..a6e38fd
--- /dev/null
+++ b/third_party/flatbuffers/.bazelci/presubmit.yml
@@ -0,0 +1,18 @@
+---
+buildifier: latest
+platforms:
+  ubuntu1604:
+    build_targets:
+    - "..."
+    test_targets:
+    - "..."
+  ubuntu1804:
+    build_targets:
+    - "..."
+    test_targets:
+    - "..."
+  macos:
+    build_targets:
+    - "..."
+    test_targets:
+    - "..."
diff --git a/third_party/flatbuffers/.clang-format b/third_party/flatbuffers/.clang-format
new file mode 100644
index 0000000..7da2b43
--- /dev/null
+++ b/third_party/flatbuffers/.clang-format
@@ -0,0 +1,13 @@
+---
+Language: Cpp
+BasedOnStyle: Google
+DerivePointerAlignment: false
+PointerAlignment: Right
+IndentPPDirectives: AfterHash
+Cpp11BracedListStyle: false
+AlwaysBreakTemplateDeclarations: false
+AllowShortCaseLabelsOnASingleLine: true
+SpaceAfterTemplateKeyword: false
+AllowShortBlocksOnASingleLine: true
+...
+
diff --git a/third_party/flatbuffers/.editorconfig b/third_party/flatbuffers/.editorconfig
new file mode 100644
index 0000000..6c54966
--- /dev/null
+++ b/third_party/flatbuffers/.editorconfig
@@ -0,0 +1,7 @@
+root = true
+# Don't set line endings to avoid conflict with core.autocrlf flag.
+# Line endings on checkout/checkin are controlled by .gitattributes file.
+[*]
+indent_style = space
+indent_size = 2
+insert_final_newline = true
diff --git a/third_party/flatbuffers/.gitattributes b/third_party/flatbuffers/.gitattributes
new file mode 100644
index 0000000..4cab1f4
--- /dev/null
+++ b/third_party/flatbuffers/.gitattributes
@@ -0,0 +1,2 @@
+# Set the default behavior, in case people don't have core.autocrlf set.
+* text=auto
diff --git a/third_party/flatbuffers/.github/ISSUE_TEMPLATE.md b/third_party/flatbuffers/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 0000000..a053fe4
--- /dev/null
+++ b/third_party/flatbuffers/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,12 @@
+Thank you for submitting an issue!
+
+Please make sure you include the names of the affected language(s), compiler version(s), operating system version(s), and FlatBuffers version(s) in your issue title.
+
+This helps us get the correct maintainers to look at your issue. Here are examples of good titles:
+
+- Crash when accessing FlatBuffer [C++, gcc 4.8, OS X, master]
+- Flatc converts a protobuf 'bytes' field to 'string' in fbs schema file [all languages, FlatBuffers 1.4]
+
+Include other details as appropriate.
+
+Thanks!
diff --git a/third_party/flatbuffers/.github/PULL_REQUEST_TEMPLATE.md b/third_party/flatbuffers/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..8199465
--- /dev/null
+++ b/third_party/flatbuffers/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,16 @@
+Thank you for submitting a PR!
+
+Please make sure you include the names of the affected language(s) in your PR title.
+This helps us get the correct maintainers to look at your issue.
+
+If you make changes to any of the code generators, be sure to run
+`cd tests && sh generate_code.sh` (or equivalent .bat) and include the generated
+code changes in the PR. This allows us to better see the effect of the PR.
+
+If your PR includes C++ code, please adhere to the Google C++ Style Guide,
+and don't forget we try to support older compilers (e.g. VS2010, GCC 4.6.3),
+so only some C++11 support is available.
+
+Include other details as appropriate.
+
+Thanks!
diff --git a/third_party/flatbuffers/.github/stale.yml b/third_party/flatbuffers/.github/stale.yml
new file mode 100644
index 0000000..84ff87b
--- /dev/null
+++ b/third_party/flatbuffers/.github/stale.yml
@@ -0,0 +1,18 @@
+# Number of days of inactivity before an issue becomes stale
+daysUntilStale: 365
+# Number of days of inactivity before a stale issue is closed
+daysUntilClose: 14
+# Issues with these labels will never be considered stale
+exemptLabels:
+  - pinned
+  - security
+# Label to use when marking an issue as stale
+staleLabel: stale
+# Comment to post when marking an issue as stale. Set to `false` to disable
+markComment: >
+  This issue has been automatically marked as stale because it has not had
+  activity for 1 year. It will be automatically closed if no further activity occurs.
+  To keep it open, simply post a new comment. Maintainers will re-open on
+  new activity. Thank you for your contributions.
+# Comment to post when closing a stale issue. Set to `false` to disable
+closeComment: false
diff --git a/third_party/flatbuffers/.gitignore b/third_party/flatbuffers/.gitignore
new file mode 100644
index 0000000..b7b41ac
--- /dev/null
+++ b/third_party/flatbuffers/.gitignore
@@ -0,0 +1,118 @@
+*_wire.txt
+*_wire.bin
+.DS_Store
+*.o
+*.o.d
+*.class
+*.a
+*.swp
+*~
+*.vcxproj
+*.vcxproj.filters
+*.vcxproj.user
+*.sln
+*.suo
+*.opendb
+*.keystore
+**/.vs/**
+**/bin/**
+!tests/rust_usage_test/bin/**
+**/gen/**
+**/libs/**
+**/obj/**
+**/*.dir/**
+**/CMakeFiles/**
+**/cmake_install.cmake
+**/install_manifest.txt
+**/CMakeCache.txt
+**/CMakeTestfile.cmake
+**/CPackConfig.cmake
+**/CPackSourceConfig.cmake
+**/compile_commands.json
+**/Debug/**
+**/Release/**
+**/RelWithDebInfo/**
+**/x64/ #build artifacts from VS
+build.xml
+local.properties
+project.properties
+proguard-project.txt
+linklint_results
+Makefile
+flatc
+flatc.exe
+flathash
+flathash.exe
+flattests
+flattests.exe
+flatsamplebinary
+flatsamplebinary.exe
+flatsampletext
+flatsampletext.exe
+flatsamplebfbs
+flatsamplebfbs.exe
+grpctest
+grpctest.exe
+snapshot.sh
+tags
+tests/dart_gen
+tests/go_gen
+tests/monsterdata_java_wire.mon
+tests/monsterdata_java_wire_sp.mon
+tests/monsterdata_go_wire.mon
+tests/monsterdata_javascript_wire.mon
+tests/monsterdata_lobster_wire.mon
+tests/monsterdata_rust_wire.mon
+tests/unicode_test.mon
+tests/ts/
+tests/php/
+CMakeLists.txt.user
+CMakeScripts/**
+CTestTestfile.cmake
+FlatbuffersConfigVersion.cmake
+FlatBuffers.cbp
+build/Xcode/FlatBuffers.xcodeproj/project.xcworkspace/**
+build/Xcode/FlatBuffers.xcodeproj/xcuserdata/**
+FlatBuffers.xcodeproj/
+java/.idea
+java/*.iml
+.idea
+*.iml
+target
+**/*.pyc
+build/VS2010/FlatBuffers.sdf
+build/VS2010/FlatBuffers.opensdf
+build/VS2010/ipch/**/*.ipch
+*.so
+Testing/Temporary
+.cproject
+.settings/
+.project
+net/**/obj
+node_modules/
+android/.externalNativeBuild/
+android/.gradle/
+android/build/
+samples/android/.externalNativeBuild/
+samples/android/.gradle/
+samples/android/build/
+js/flatbuffers.mjs
+/bazel-bin
+/bazel-flatbuffers
+/bazel-genfiles
+/bazel-out
+/bazel-testlogs
+.ninja_deps
+.ninja_log
+build.ninja
+rules.ninja
+.vscode
+dart/.pub/
+dart/.packages
+dart/pubspec.lock
+dart/.dart_tool/
+dart/build/
+dart/doc/api/
+Cargo.lock
+.corpus**
+.seed**
diff --git a/third_party/flatbuffers/.travis.yml b/third_party/flatbuffers/.travis.yml
new file mode 100644
index 0000000..fd2959f
--- /dev/null
+++ b/third_party/flatbuffers/.travis.yml
@@ -0,0 +1,221 @@
+env:
+  global:
+    # Set at the root level as this is ignored when set under matrix.env.
+    - GCC_VERSION="4.9"
+    # Fail on first error if UBSAN or ASAN enabled for a target
+    - UBSAN_OPTIONS=halt_on_error=1
+    - ASAN_OPTIONS=halt_on_error=1
+    # Travis machines have 2 cores
+    - JOBS=2
+    - MAKEFLAGS="-j 2"
+
+conan-linux: &conan-linux
+  os: linux
+  dist: xenial
+  language: python
+  python: "3.7"
+  services:
+    - docker
+  install:
+    - ./conan/travis/install.sh
+  script:
+    - ./conan/travis/build.sh
+  if: tag IS present
+
+conan-linux-master: &conan-linux-master
+  os: linux
+  dist: xenial
+  language: python
+  python: "3.7"
+  services:
+    - docker
+  install:
+    - 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./conan/travis/install.sh; fi'
+  script:
+    - 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./conan/travis/build.sh; fi'
+  branches:
+    only:
+    - master
+
+conan-osx: &conan-osx
+  os: osx
+  language: generic
+  install:
+    - ./conan/travis/install.sh
+  script:
+    - ./conan/travis/build.sh
+  if: tag IS present
+
+matrix:
+  include:
+    #- language: python
+    #  python: "2.7"
+    #  install:
+    #    - "pip install wheel twine"
+    #  script:
+    #    - "cd python/"
+    #    - 'VERSION="$TRAVIS_TAG" python setup.py sdist bdist_wheel'
+    #    - "cd ../"
+    #  deploy:
+    #    # Checkpointed release builds.
+    #    - provider: script
+    #      script: .travis/deploy-python.sh
+    #      skip_cleanup: true
+    #      on:
+    #        tags: true
+    #        # all_branches must be set with tags: true. See below post:
+    #        # https://stackoverflow.com/a/27775257/1076585
+    #        all_branches: true
+    #    # Produce a new build for the cutting edge when master changes.
+    #    - provider: script
+    #      script: .travis/deploy-python.sh
+    #      skip_cleanup: true
+    #      on:
+    #        branch: master
+    - language: cpp
+      os:
+        - linux
+
+      addons:
+        apt:
+          packages:
+            - docker-ce
+      script:
+        - bash .travis/build-and-run-docker-test-containers.sh
+
+    - language: cpp
+      os:
+        - linux
+
+      compiler:
+        - gcc
+
+      env:
+        matrix:
+          - BUILD_TYPE=Debug
+          - BUILD_TYPE=Release
+
+      before_install:
+      - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi
+      - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq; fi
+      - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -qq g++-$GCC_VERSION; fi
+      - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -qq gcc-$GCC_VERSION; fi
+      - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo ln -s -v -f $(which g++-$GCC_VERSION) /usr/bin/g++; fi
+      - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo ln -s -v -f $(which gcc-$GCC_VERSION) /usr/bin/gcc; fi
+
+      script:
+      - bash .travis/check-sources.sh
+      - bash grpc/build_grpc.sh
+      - cmake .
+        -DCMAKE_BUILD_TYPE=$BUILD_TYPE
+        -DFLATBUFFERS_BUILD_GRPCTEST=ON
+        -DGRPC_INSTALL_PATH=$TRAVIS_BUILD_DIR/google/grpc/install
+        -DPROTOBUF_DOWNLOAD_PATH=$TRAVIS_BUILD_DIR/google/grpc/third_party/protobuf
+        -DFLATBUFFERS_CODE_SANITIZE=ON
+      - cmake --build . -- -j${JOBS}
+      - LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/google/grpc/install/lib ctest --extra-verbose --output-on-failure
+      - bash .travis/check-generate-code.sh
+
+    - language: cpp
+      os: osx
+      osx_image: xcode9.3
+      env:
+        matrix:
+          - BUILD_TYPE=Debug
+          - BUILD_TYPE=Release
+
+      script:
+      - bash grpc/build_grpc.sh
+      - cmake .
+        -DCMAKE_BUILD_TYPE=$BUILD_TYPE
+        -DFLATBUFFERS_BUILD_GRPCTEST=ON
+        -DGRPC_INSTALL_PATH=$TRAVIS_BUILD_DIR/google/grpc/install
+        -DPROTOBUF_DOWNLOAD_PATH=$TRAVIS_BUILD_DIR/google/grpc/third_party/protobuf
+        -DFLATBUFFERS_CODE_SANITIZE=ON
+      - cmake --build . -- -j${JOBS}
+      - DYLD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/google/grpc/install/lib ctest --extra-verbose --output-on-failure
+      - bash .travis/check-generate-code.sh
+
+    - <<: *conan-linux-master
+      env: CONAN_GCC_VERSIONS=8 CONAN_DOCKER_IMAGE=conanio/gcc8
+    - <<: *conan-linux
+      env: CONAN_GCC_VERSIONS=4.9 CONAN_DOCKER_IMAGE=conanio/gcc49
+    - <<: *conan-linux
+      env: CONAN_GCC_VERSIONS=5 CONAN_DOCKER_IMAGE=conanio/gcc5
+    - <<: *conan-linux
+      env: CONAN_GCC_VERSIONS=6 CONAN_DOCKER_IMAGE=conanio/gcc6
+    - <<: *conan-linux
+      env: CONAN_GCC_VERSIONS=7 CONAN_DOCKER_IMAGE=conanio/gcc7
+    - <<: *conan-linux
+      env: CONAN_GCC_VERSIONS=8 CONAN_DOCKER_IMAGE=conanio/gcc8
+    - <<: *conan-linux
+      env: CONAN_GCC_VERSIONS=9 CONAN_DOCKER_IMAGE=conanio/gcc9
+    - <<: *conan-linux
+      env: CONAN_CLANG_VERSIONS=3.9 CONAN_DOCKER_IMAGE=conanio/clang39
+    - <<: *conan-linux
+      env: CONAN_CLANG_VERSIONS=4.0 CONAN_DOCKER_IMAGE=conanio/clang40
+    - <<: *conan-linux
+      env: CONAN_CLANG_VERSIONS=5.0 CONAN_DOCKER_IMAGE=conanio/clang50
+    - <<: *conan-linux
+      env: CONAN_CLANG_VERSIONS=6.0 CONAN_DOCKER_IMAGE=conanio/clang60
+    - <<: *conan-linux
+      env: CONAN_CLANG_VERSIONS=7.0 CONAN_DOCKER_IMAGE=conanio/clang7
+    - <<: *conan-linux
+      env: CONAN_CLANG_VERSIONS=8 CONAN_DOCKER_IMAGE=conanio/clang8
+    - <<: *conan-osx
+      osx_image: xcode7.3
+      env: CONAN_APPLE_CLANG_VERSIONS=7.3
+    - <<: *conan-osx
+      osx_image: xcode8.3
+      env: CONAN_APPLE_CLANG_VERSIONS=8.1
+    - <<: *conan-osx
+      osx_image: xcode9
+      env: CONAN_APPLE_CLANG_VERSIONS=9.0
+    - <<: *conan-osx
+      osx_image: xcode9.4
+      env: CONAN_APPLE_CLANG_VERSIONS=9.1
+    - <<: *conan-osx
+      osx_image: xcode10.2
+      env: CONAN_APPLE_CLANG_VERSIONS=10.0
+
+    - language: android
+      sudo: true
+      dist: trusty
+      android:
+        components:
+          - tools
+          - platform-tools
+          - build-tools-25.0.2
+          - android-25
+          - extra-android-m2repository
+      compiler:
+        - gcc
+
+      before_install:
+        # Output something every 10 minutes or Travis kills the job
+        - while sleep 540; do echo "=====[ $SECONDS seconds still running ]====="; done &
+        # Install the r17c version of the NDK that still so that we can continue to test with gnustl
+        # and stlport.
+        - export ANDROID_NDK_HOME=$HOME/android-ndk
+        - NDK_ZIP=$ANDROID_NDK_HOME/ndk.zip
+        - mkdir -p $ANDROID_NDK_HOME
+        - curl -o $NDK_ZIP https://dl.google.com/android/repository/android-ndk-r17c-linux-x86_64.zip
+        - unzip -q -d $ANDROID_NDK_HOME $NDK_ZIP
+        - rm $NDK_ZIP
+        - mv $ANDROID_NDK_HOME/android-ndk-*/* $ANDROID_NDK_HOME
+        - rmdir $ANDROID_NDK_HOME/android-ndk-*
+        - export CMAKE=$(which cmake)
+        # libc required for prebuilt llvm toolchain the NDK r17c.
+        - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq; fi
+        - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -qq libc6; fi
+        # Setup environment for Linux build which is required to build the sample.
+        - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi
+        - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq; fi
+        - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -qq g++-$GCC_VERSION; fi
+        - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -qq gcc-$GCC_VERSION; fi
+        - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo ln -s -v -f $(which g++-$GCC_VERSION) /usr/bin/g++; fi
+        - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo ln -s -v -f $(which gcc-$GCC_VERSION) /usr/bin/gcc; fi
+      script:
+        - failed=0; for build_gradle in $(git ls-files | grep build.gradle); do ( cd "$(dirname "${build_gradle}")" && ./gradlew build ) || failed=1; done; exit $((failed))
+        # Kill the sleep loop
+        - kill %1
diff --git a/third_party/flatbuffers/.travis/build-and-run-docker-test-containers.sh b/third_party/flatbuffers/.travis/build-and-run-docker-test-containers.sh
new file mode 100755
index 0000000..e6039bf
--- /dev/null
+++ b/third_party/flatbuffers/.travis/build-and-run-docker-test-containers.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+#
+# 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.
+set -e
+
+# build flatc on debian once to speed up the test loop below
+docker build -t build_flatc_debian_stretch -f tests/docker/Dockerfile.testing.build_flatc_debian_stretch .
+BUILD_CONTAINER_ID=$(docker create --read-only build_flatc_debian_stretch)
+docker cp ${BUILD_CONTAINER_ID}:/code/flatc flatc_debian_stretch
+
+for f in $(ls tests/docker/languages | sort)
+do
+        # docker pull sometimes fails for unknown reasons, probably travisci-related. this retries the pull we need a few times.
+        REQUIRED_BASE_IMAGE=$(cat tests/docker/languages/${f} | head -n 1  | awk ' { print $2 } ')
+
+        set +e
+        n=0
+        until [ $n -ge 5 ]
+        do
+           docker pull $REQUIRED_BASE_IMAGE && break
+           n=$[$n+1]
+           sleep 1
+        done
+        set -e
+
+        docker build -t $(echo ${f} | cut -f 3- -d .) -f tests/docker/languages/${f} .
+        echo "TEST OK: ${f}"
+done
diff --git a/third_party/flatbuffers/.travis/check-generate-code.sh b/third_party/flatbuffers/.travis/check-generate-code.sh
new file mode 100755
index 0000000..37d81bb
--- /dev/null
+++ b/third_party/flatbuffers/.travis/check-generate-code.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+#
+# 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.
+set -e
+
+cd tests
+./generate_code.sh
+cd ..
+
+# TODO: Linux and macos builds produce differences here for some reason.
+git checkout HEAD -- tests/monster_test.bfbs
+git checkout HEAD -- tests/arrays_test.bfbs
+
+if ! git diff --quiet; then
+  echo >&2
+  echo "ERROR: ********************************************************" >&2
+  echo "ERROR: The following differences were found after running the" >&2
+  echo "ERROR: tests/generate_code.sh script.  Maybe you forgot to run" >&2
+  echo "ERROR: it after making changes in a generator or schema?" >&2
+  echo "ERROR: ********************************************************" >&2
+  echo >&2
+  git diff --binary --exit-code
+fi
diff --git a/third_party/flatbuffers/.travis/check-sources.sh b/third_party/flatbuffers/.travis/check-sources.sh
new file mode 100644
index 0000000..3e6dbf1
--- /dev/null
+++ b/third_party/flatbuffers/.travis/check-sources.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+#
+# 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.
+set -e
+
+if [ -n "$1" ]; then
+  scan_dir="$1"
+else
+  scan_dir="$( pwd )"
+fi
+
+py_checker="$0.py"
+
+echo "scan root directory = '$scan_dir'"
+python3 --version
+# Scan recursively and search all *.cpp and *.h files using regex patterns.
+# Assume that script running from a root of Flatbuffers working dir.
+python3 $py_checker "ascii" "$scan_dir/include" "\.h$"
+python3 $py_checker "ascii" "$scan_dir/src"     "\.cpp$"
+python3 $py_checker "ascii" "$scan_dir/tests"   "\.h$"
+python3 $py_checker "utf-8" "$scan_dir/tests"   "\.cpp$"
diff --git a/third_party/flatbuffers/.travis/check-sources.sh.py b/third_party/flatbuffers/.travis/check-sources.sh.py
new file mode 100644
index 0000000..2b001d7
--- /dev/null
+++ b/third_party/flatbuffers/.travis/check-sources.sh.py
@@ -0,0 +1,35 @@
+import os
+import re
+import sys
+
+def check_encoding(encoding, scan_dir, regex_pattern):
+  fname = None
+  try:
+    assert encoding in ['ascii', 'utf-8'], "unexpected encoding"
+    cmp = re.compile(regex_pattern)
+    for root, dirs, files in os.walk(scan_dir):
+      fname = root
+      cmp_list = [f for f in files if cmp.search(f) is not None]
+      for f in cmp_list:
+        fname = os.path.join(root, f)
+        with open(fname, mode='rb') as test_file:
+          btext = test_file.read()
+        # check encoding
+        btext.decode(encoding=encoding, errors="strict")
+        if encoding == "utf-8" and btext.startswith(b'\xEF\xBB\xBF'):
+          raise ValueError("unexpected BOM in file")
+        # check LF line endings
+        LF = btext.count(b'\n')
+        CR = btext.count(b'\r')
+        if CR!=0:
+          raise ValueError("invalid line endings: LF({})/CR({})".format(LF, CR))
+  except Exception as err:
+    print("ERROR with [{}]: {}".format(fname, err))
+    return -1
+  else:
+    return 0
+
+if __name__ == "__main__":
+  # python check-sources.sh.py 'ascii' '.' '.*\.(cpp|h)$'
+  res = check_encoding(sys.argv[1], sys.argv[2], sys.argv[3])
+  sys.exit(0 if res == 0 else -1)
diff --git a/third_party/flatbuffers/.travis/deploy-python.sh b/third_party/flatbuffers/.travis/deploy-python.sh
new file mode 100755
index 0000000..4cc0346
--- /dev/null
+++ b/third_party/flatbuffers/.travis/deploy-python.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+PROD_REPOSITORY="https://upload.pypi.org/legacy/"
+TEST_REPOSITORY="https://test.pypi.org/legacy/"
+
+twine upload \
+    --username "$PYPI_USERNAME" \
+    --password "$PYPI_PASSWORD" \
+    --repository-url "$PROD_REPOSITORY" \
+    "$DIR/../python/dist/"*
+
diff --git a/third_party/flatbuffers/BUILD b/third_party/flatbuffers/BUILD
new file mode 100644
index 0000000..520f98a
--- /dev/null
+++ b/third_party/flatbuffers/BUILD
@@ -0,0 +1,225 @@
+licenses(["notice"])
+
+package(
+    default_visibility = ["//visibility:public"],
+    features = [
+        "-layering_check",
+        "-parse_headers",
+    ],
+)
+
+exports_files([
+    "LICENSE",
+])
+
+load(":build_defs.bzl", "flatbuffer_cc_library")
+
+# Public flatc library to compile flatbuffer files at runtime.
+cc_library(
+    name = "flatbuffers",
+    srcs = [
+        "src/code_generators.cpp",
+        "src/idl_gen_fbs.cpp",
+        "src/idl_gen_general.cpp",
+        "src/idl_gen_text.cpp",
+        "src/idl_parser.cpp",
+        "src/reflection.cpp",
+        "src/util.cpp",
+    ],
+    hdrs = [":public_headers"],
+    includes = ["include/"],
+    linkstatic = 1,
+)
+
+# Public C++ headers for the Flatbuffers library.
+filegroup(
+    name = "public_headers",
+    srcs = [
+        "include/flatbuffers/base.h",
+        "include/flatbuffers/code_generators.h",
+        "include/flatbuffers/flatbuffers.h",
+        "include/flatbuffers/flexbuffers.h",
+        "include/flatbuffers/hash.h",
+        "include/flatbuffers/idl.h",
+        "include/flatbuffers/minireflect.h",
+        "include/flatbuffers/reflection.h",
+        "include/flatbuffers/reflection_generated.h",
+        "include/flatbuffers/stl_emulation.h",
+        "include/flatbuffers/util.h",
+    ],
+)
+
+# Public flatc compiler library.
+cc_library(
+    name = "flatc_library",
+    srcs = [
+        "src/code_generators.cpp",
+        "src/flatc.cpp",
+        "src/idl_gen_fbs.cpp",
+        "src/idl_parser.cpp",
+        "src/reflection.cpp",
+        "src/util.cpp",
+    ],
+    hdrs = [
+        "include/flatbuffers/flatc.h",
+        ":public_headers",
+    ],
+    includes = [
+        "grpc/",
+        "include/",
+    ],
+)
+
+# Public flatc compiler.
+cc_binary(
+    name = "flatc",
+    srcs = [
+        "grpc/src/compiler/config.h",
+        "grpc/src/compiler/cpp_generator.cc",
+        "grpc/src/compiler/cpp_generator.h",
+        "grpc/src/compiler/go_generator.cc",
+        "grpc/src/compiler/go_generator.h",
+        "grpc/src/compiler/java_generator.cc",
+        "grpc/src/compiler/java_generator.h",
+        "grpc/src/compiler/schema_interface.h",
+        "src/flatc_main.cpp",
+        "src/idl_gen_cpp.cpp",
+        "src/idl_gen_dart.cpp",
+        "src/idl_gen_general.cpp",
+        "src/idl_gen_kotlin.cpp",
+        "src/idl_gen_go.cpp",
+        "src/idl_gen_grpc.cpp",
+        "src/idl_gen_js_ts.cpp",
+        "src/idl_gen_json_schema.cpp",
+        "src/idl_gen_lobster.cpp",
+        "src/idl_gen_lua.cpp",
+        "src/idl_gen_php.cpp",
+        "src/idl_gen_python.cpp",
+        "src/idl_gen_rust.cpp",
+        "src/idl_gen_text.cpp",
+        "src/util.cpp",
+    ],
+    includes = [
+        "grpc/",
+        "include/",
+    ],
+    deps = [
+        ":flatc_library",
+    ],
+)
+
+cc_library(
+    name = "runtime_cc",
+    hdrs = [
+        "include/flatbuffers/base.h",
+        "include/flatbuffers/flatbuffers.h",
+        "include/flatbuffers/flexbuffers.h",
+        "include/flatbuffers/stl_emulation.h",
+        "include/flatbuffers/util.h",
+    ],
+    includes = ["include/"],
+    linkstatic = 1,
+)
+
+# Test binary.
+cc_test(
+    name = "flatbuffers_test",
+    testonly = 1,
+    srcs = [
+        "include/flatbuffers/minireflect.h",
+        "include/flatbuffers/registry.h",
+        "src/code_generators.cpp",
+        "src/idl_gen_fbs.cpp",
+        "src/idl_gen_general.cpp",
+        "src/idl_gen_text.cpp",
+        "src/idl_parser.cpp",
+        "src/reflection.cpp",
+        "src/util.cpp",
+        "tests/namespace_test/namespace_test1_generated.h",
+        "tests/namespace_test/namespace_test2_generated.h",
+        "tests/native_type_test_impl.h",
+        "tests/native_type_test_impl.cpp",
+        "tests/test.cpp",
+        "tests/test_assert.cpp",
+        "tests/test_assert.h",
+        "tests/test_builder.cpp",
+        "tests/test_builder.h",
+        "tests/union_vector/union_vector_generated.h",
+        ":public_headers",
+    ],
+    copts = [
+        "-DFLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE",
+        "-DBAZEL_TEST_DATA_PATH",
+    ],
+    data = [
+        ":tests/include_test/include_test1.fbs",
+        ":tests/include_test/sub/include_test2.fbs",
+        ":tests/monster_test.bfbs",
+        ":tests/monster_test.fbs",
+        ":tests/monsterdata_test.golden",
+        ":tests/monsterdata_test.json",
+        ":tests/prototest/imported.proto",
+        ":tests/prototest/test.golden",
+        ":tests/prototest/test.proto",
+        ":tests/prototest/test_union.golden",
+        ":tests/unicode_test.json",
+        ":tests/union_vector/union_vector.fbs",
+        ":tests/union_vector/union_vector.json",
+        ":tests/monster_extra.fbs",
+        ":tests/monsterdata_extra.json",
+        ":tests/arrays_test.bfbs",
+        ":tests/arrays_test.fbs",
+        ":tests/arrays_test.golden",
+        ":tests/native_type_test.fbs",
+    ],
+    includes = [
+        "include/",
+        "tests/",
+    ],
+    deps = [
+        ":monster_extra_cc_fbs",
+        ":monster_test_cc_fbs",
+        ":arrays_test_cc_fbs",
+        ":native_type_test_cc_fbs",
+    ],
+)
+
+# Test bzl rules
+
+flatbuffer_cc_library(
+    name = "monster_test_cc_fbs",
+    srcs = ["tests/monster_test.fbs"],
+    include_paths = ["tests/include_test"],
+    includes = [
+        "tests/include_test/include_test1.fbs",
+        "tests/include_test/sub/include_test2.fbs",
+    ],
+)
+
+flatbuffer_cc_library(
+    name = "monster_extra_cc_fbs",
+    srcs = ["tests/monster_extra.fbs"],
+)
+
+flatbuffer_cc_library(
+    name = "arrays_test_cc_fbs",
+    srcs = ["tests/arrays_test.fbs"],
+    flatc_args = [
+        "--gen-object-api",
+        "--gen-compare",
+        "--no-includes",
+        "--gen-mutable",
+        "--reflect-names",
+        "--cpp-ptr-type flatbuffers::unique_ptr",
+        "--scoped-enums" ],
+)
+
+flatbuffer_cc_library(
+    name = "native_type_test_cc_fbs",
+    srcs = ["tests/native_type_test.fbs"],
+    flatc_args = [
+        "--gen-object-api",
+        "--gen-mutable",
+        "--cpp-ptr-type flatbuffers::unique_ptr" ],
+)
+
diff --git a/third_party/flatbuffers/CMake/BuildFlatBuffers.cmake b/third_party/flatbuffers/CMake/BuildFlatBuffers.cmake
new file mode 100644
index 0000000..835f4b8
--- /dev/null
+++ b/third_party/flatbuffers/CMake/BuildFlatBuffers.cmake
@@ -0,0 +1,152 @@
+# 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.
+
+# General function to create FlatBuffer build rules for the given list of
+# schemas.
+#
+# flatbuffers_schemas: A list of flatbuffer schema files to process.
+#
+# schema_include_dirs: A list of schema file include directories, which will be
+# passed to flatc via the -I parameter.
+#
+# custom_target_name: The generated files will be added as dependencies for a
+# new custom target with this name. You should add that target as a dependency
+# for your main target to ensure these files are built. You can also retrieve
+# various properties from this target, such as GENERATED_INCLUDES_DIR,
+# BINARY_SCHEMAS_DIR, and COPY_TEXT_SCHEMAS_DIR.
+#
+# additional_dependencies: A list of additional dependencies that you'd like
+# all generated files to depend on. Pass in a blank string if you have none.
+#
+# generated_includes_dir: Where to generate the C++ header files for these
+# schemas. The generated includes directory will automatically be added to
+# CMake's include directories, and will be where generated header files are
+# placed. This parameter is optional; pass in empty string if you don't want to
+# generate include files for these schemas.
+#
+# binary_schemas_dir: If you specify an optional binary schema directory, binary
+# schemas will be generated for these schemas as well, and placed into the given
+# directory.
+#
+# copy_text_schemas_dir: If you want all text schemas (including schemas from
+# all schema include directories) copied into a directory (for example, if you
+# need them within your project to build JSON files), you can specify that
+# folder here. All text schemas will be copied to that folder.
+#
+# IMPORTANT: Make sure you quote all list arguments you pass to this function!
+# Otherwise CMake will only pass in the first element.
+# Example: build_flatbuffers("${fb_files}" "${include_dirs}" target_name ...)
+function(build_flatbuffers flatbuffers_schemas
+                           schema_include_dirs
+                           custom_target_name
+                           additional_dependencies
+                           generated_includes_dir
+                           binary_schemas_dir
+                           copy_text_schemas_dir)
+
+  # Test if including from FindFlatBuffers
+  if(FLATBUFFERS_FLATC_EXECUTABLE)
+    set(FLATC_TARGET "")
+    set(FLATC ${FLATBUFFERS_FLATC_EXECUTABLE})
+  else()
+    set(FLATC_TARGET flatc)
+    set(FLATC flatc)
+  endif()
+  set(FLATC_SCHEMA_ARGS --gen-mutable)
+  if(FLATBUFFERS_FLATC_SCHEMA_EXTRA_ARGS)
+    set(FLATC_SCHEMA_ARGS
+      ${FLATBUFFERS_FLATC_SCHEMA_EXTRA_ARGS}
+      ${FLATC_SCHEMA_ARGS}
+      )
+  endif()
+
+  set(working_dir "${CMAKE_CURRENT_SOURCE_DIR}")
+
+  set(schema_glob "*.fbs")
+  # Generate the include files parameters.
+  set(include_params "")
+  set(all_generated_files "")
+  foreach (include_dir ${schema_include_dirs})
+    set(include_params -I ${include_dir} ${include_params})
+    if (NOT ${copy_text_schemas_dir} STREQUAL "")
+      # Copy text schemas from dependent folders.
+      file(GLOB_RECURSE dependent_schemas ${include_dir}/${schema_glob})
+      foreach (dependent_schema ${dependent_schemas})
+        file(COPY ${dependent_schema} DESTINATION ${copy_text_schemas_dir})
+      endforeach()
+    endif()
+  endforeach()
+
+  foreach(schema ${flatbuffers_schemas})
+    get_filename_component(filename ${schema} NAME_WE)
+    # For each schema, do the things we requested.
+    if (NOT ${generated_includes_dir} STREQUAL "")
+      set(generated_include ${generated_includes_dir}/${filename}_generated.h)
+      add_custom_command(
+        OUTPUT ${generated_include}
+        COMMAND ${FLATC} ${FLATC_SCHEMA_ARGS}
+        -o ${generated_includes_dir}
+        ${include_params}
+        -c ${schema}
+        DEPENDS ${FLATC_TARGET} ${schema} ${additional_dependencies}
+        WORKING_DIRECTORY "${working_dir}")
+      list(APPEND all_generated_files ${generated_include})
+    endif()
+
+    if (NOT ${binary_schemas_dir} STREQUAL "")
+      set(binary_schema ${binary_schemas_dir}/${filename}.bfbs)
+      add_custom_command(
+        OUTPUT ${binary_schema}
+        COMMAND ${FLATC} -b --schema
+        -o ${binary_schemas_dir}
+        ${include_params}
+        ${schema}
+        DEPENDS ${FLATC_TARGET} ${schema} ${additional_dependencies}
+        WORKING_DIRECTORY "${working_dir}")
+      list(APPEND all_generated_files ${binary_schema})
+    endif()
+
+    if (NOT ${copy_text_schemas_dir} STREQUAL "")
+      file(COPY ${schema} DESTINATION ${copy_text_schemas_dir})
+    endif()
+  endforeach()
+
+  # Create a custom target that depends on all the generated files.
+  # This is the target that you can depend on to trigger all these
+  # to be built.
+  add_custom_target(${custom_target_name}
+                    DEPENDS ${all_generated_files} ${additional_dependencies})
+
+  # Register the include directory we are using.
+  if (NOT ${generated_includes_dir} STREQUAL "")
+    include_directories(${generated_includes_dir})
+    set_property(TARGET ${custom_target_name}
+      PROPERTY GENERATED_INCLUDES_DIR
+      ${generated_includes_dir})
+  endif()
+
+  # Register the binary schemas dir we are using.
+  if (NOT ${binary_schemas_dir} STREQUAL "")
+    set_property(TARGET ${custom_target_name}
+      PROPERTY BINARY_SCHEMAS_DIR
+      ${binary_schemas_dir})
+  endif()
+
+  # Register the text schema copy dir we are using.
+  if (NOT ${copy_text_schemas_dir} STREQUAL "")
+    set_property(TARGET ${custom_target_name}
+      PROPERTY COPY_TEXT_SCHEMAS_DIR
+      ${copy_text_schemas_dir})
+  endif()
+endfunction()
diff --git a/third_party/flatbuffers/CMake/DESCRIPTION.txt b/third_party/flatbuffers/CMake/DESCRIPTION.txt
new file mode 100644
index 0000000..3698b03
--- /dev/null
+++ b/third_party/flatbuffers/CMake/DESCRIPTION.txt
@@ -0,0 +1,4 @@
+FlatBuffers is a cross platform serialization library architected for
+maximum memory efficiency. It allows you to directly access serialized
+data without parsing/unpacking it first, while still having great 
+forwards/backwards compatibility.
diff --git a/third_party/flatbuffers/CMake/FindFlatBuffers.cmake b/third_party/flatbuffers/CMake/FindFlatBuffers.cmake
new file mode 100644
index 0000000..aad9a6b
--- /dev/null
+++ b/third_party/flatbuffers/CMake/FindFlatBuffers.cmake
@@ -0,0 +1,61 @@
+# Copyright 2014 Stefan.Eilemann@epfl.ch
+# 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.
+
+# Find the flatbuffers schema compiler
+#
+# Output Variables:
+# * FLATBUFFERS_FLATC_EXECUTABLE the flatc compiler executable
+# * FLATBUFFERS_FOUND
+#
+# Provides:
+# * FLATBUFFERS_GENERATE_C_HEADERS(Name <files>) creates the C++ headers
+#   for the given flatbuffer schema files.
+#   Returns the header files in ${Name}_OUTPUTS
+
+set(FLATBUFFERS_CMAKE_DIR ${CMAKE_CURRENT_LIST_DIR})
+
+find_program(FLATBUFFERS_FLATC_EXECUTABLE NAMES flatc)
+find_path(FLATBUFFERS_INCLUDE_DIR NAMES flatbuffers/flatbuffers.h)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(flatbuffers
+  DEFAULT_MSG FLATBUFFERS_FLATC_EXECUTABLE FLATBUFFERS_INCLUDE_DIR)
+
+if(FLATBUFFERS_FOUND)
+  function(FLATBUFFERS_GENERATE_C_HEADERS Name)
+    set(FLATC_OUTPUTS)
+    foreach(FILE ${ARGN})
+      get_filename_component(FLATC_OUTPUT ${FILE} NAME_WE)
+      set(FLATC_OUTPUT
+        "${CMAKE_CURRENT_BINARY_DIR}/${FLATC_OUTPUT}_generated.h")
+      list(APPEND FLATC_OUTPUTS ${FLATC_OUTPUT})
+
+      add_custom_command(OUTPUT ${FLATC_OUTPUT}
+        COMMAND ${FLATBUFFERS_FLATC_EXECUTABLE}
+        ARGS -c -o "${CMAKE_CURRENT_BINARY_DIR}/" ${FILE}
+        DEPENDS ${FILE}
+        COMMENT "Building C++ header for ${FILE}"
+        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+    endforeach()
+    set(${Name}_OUTPUTS ${FLATC_OUTPUTS} PARENT_SCOPE)
+  endfunction()
+
+  set(FLATBUFFERS_INCLUDE_DIRS ${FLATBUFFERS_INCLUDE_DIR})
+  include_directories(${CMAKE_BINARY_DIR})
+else()
+  set(FLATBUFFERS_INCLUDE_DIR)
+endif()
+
+include("${FLATBUFFERS_CMAKE_DIR}/BuildFlatBuffers.cmake")
\ No newline at end of file
diff --git a/third_party/flatbuffers/CMake/FlatbuffersConfig.cmake b/third_party/flatbuffers/CMake/FlatbuffersConfig.cmake
new file mode 100644
index 0000000..107d78e
--- /dev/null
+++ b/third_party/flatbuffers/CMake/FlatbuffersConfig.cmake
@@ -0,0 +1,4 @@
+include("${CMAKE_CURRENT_LIST_DIR}/FlatbuffersTargets.cmake" OPTIONAL)
+include("${CMAKE_CURRENT_LIST_DIR}/FlatcTargets.cmake" OPTIONAL)
+include("${CMAKE_CURRENT_LIST_DIR}/FlatbuffersSharedTargets.cmake" OPTIONAL)
+
diff --git a/third_party/flatbuffers/CMake/FlatbuffersConfigVersion.cmake.in b/third_party/flatbuffers/CMake/FlatbuffersConfigVersion.cmake.in
new file mode 100644
index 0000000..a553ab1
--- /dev/null
+++ b/third_party/flatbuffers/CMake/FlatbuffersConfigVersion.cmake.in
@@ -0,0 +1,11 @@
+set(PACKAGE_VERSION "@VERSION_MAJOR@.@VERSION_MINOR@.@VERSION_PATCH@")
+
+# Check whether the requested PACKAGE_FIND_VERSION is compatible
+if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
+  set(PACKAGE_VERSION_COMPATIBLE FALSE)
+else()
+  set(PACKAGE_VERSION_COMPATIBLE TRUE)
+  if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
+    set(PACKAGE_VERSION_EXACT TRUE)
+  endif()
+endif()
diff --git a/third_party/flatbuffers/CMake/PackageDebian.cmake b/third_party/flatbuffers/CMake/PackageDebian.cmake
new file mode 100644
index 0000000..f587ff7
--- /dev/null
+++ b/third_party/flatbuffers/CMake/PackageDebian.cmake
@@ -0,0 +1,39 @@
+# ------------------- Debianization ---------------------
+if (UNIX)
+
+    # Set build environment
+    SET(CPACK_GENERATOR "TGZ;DEB")
+    SET(CPACK_SOURCE_TGZ "ON")
+
+    # Common package information
+    SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY
+        "FlatBuffers is an efficient cross platform serialization library for C++, with support for Java, C# and Go. It was created at Google specifically for game development and other performance-critical applications.")
+    SET(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/google/flatbuffers")
+    SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Vitaly Isaev <vitalyisaev2@gmail.com>")
+
+    SET(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR})
+    SET(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR})
+    SET(CPACK_PACKAGE_VERSION_PATCH ${VERSION_PATCH})
+    SET(CPACK_PACKAGE_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_COMMIT}")
+    SET(CPACK_DEBIAN_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}")
+
+    # Derive architecture
+    IF(NOT CPACK_DEBIAN_PACKAGE_ARCHITECTURE)
+      FIND_PROGRAM(DPKG_CMD dpkg)
+      IF(NOT DPKG_CMD)
+        MESSAGE(STATUS "Can not find dpkg in your path, default to i386.")
+        SET(CPACK_DEBIAN_PACKAGE_ARCHITECTURE i386)
+      ENDIF(NOT DPKG_CMD)
+      EXECUTE_PROCESS(COMMAND "${DPKG_CMD}" --print-architecture
+        OUTPUT_VARIABLE CPACK_DEBIAN_PACKAGE_ARCHITECTURE
+        OUTPUT_STRIP_TRAILING_WHITESPACE
+        )
+    ENDIF(NOT CPACK_DEBIAN_PACKAGE_ARCHITECTURE)
+
+    # Package name
+    SET(CPACK_DEBIAN_PACKAGE_NAME "flatbuffers")
+    SET(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/LICENSE.txt)
+    SET(CPACK_PACKAGE_FILE_NAME
+        "${CPACK_DEBIAN_PACKAGE_NAME}_${CPACK_DEBIAN_PACKAGE_VERSION}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}")
+
+endif(UNIX)
diff --git a/third_party/flatbuffers/CMake/PackageRedhat.cmake b/third_party/flatbuffers/CMake/PackageRedhat.cmake
new file mode 100644
index 0000000..4545e72
--- /dev/null
+++ b/third_party/flatbuffers/CMake/PackageRedhat.cmake
@@ -0,0 +1,34 @@
+if (UNIX)
+    set(CPACK_GENERATOR "RPM")
+    set(CPACK_SOURCE_TGZ "ON")
+
+    set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "FlatBuffers serialization library and schema compiler.")
+    
+    set(CPACK_RPM_PACKAGE_HOMEPAGE "https://github.com/google/flatbuffers")
+    set(CPACK_RPM_PACKAGE_MAINTAINER "Marc Butler <mockbutler@gmail.com>")
+
+    set(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR})
+    set(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR})
+    set(CPACK_PACKAGE_VERSION_PATCH ${VERSION_PATCH})
+    set(CPACK_PACKAGE_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_COMMIT}")
+    set(CPACK_RPM_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}")
+
+    set(CPACK_RPM_PACKAGE_NAME "flatbuffers")
+
+    # Assume this is not a cross complation build.
+    if(NOT CPACK_RPM_PACKAGE_ARCHITECTURE)
+        set(CPACK_RPM_PACKAGE_ARCHITECTURE "${CMAKE_SYSTEM_PROCESSOR}")
+    endif(NOT CPACK_RPM_PACKAGE_ARCHITECTURE)
+
+    set(CPACK_RPM_PACKAGE_VENDOR "Google, Inc.")
+    set(CPACK_RPM_PACKAGE_LICENSE "Apache 2.0")
+    set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/LICENSE.txt)
+    set(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_SOURCE_DIR}/CMake/DESCRIPTION.txt)
+
+    # This may reduce rpm compatiblity with very old systems.
+    set(CPACK_RPM_COMPRESSION_TYPE lzma)
+    
+    set(CPACK_RPM_PACKAGE_NAME "flatbuffers")
+    set(CPACK_PACKAGE_FILE_NAME
+        "${CPACK_RPM_PACKAGE_NAME}_${CPACK_RPM_PACKAGE_VERSION}_${CPACK_RPM_PACKAGE_ARCHITECTURE}")
+endif(UNIX)
diff --git a/third_party/flatbuffers/CMake/Version.cmake b/third_party/flatbuffers/CMake/Version.cmake
new file mode 100644
index 0000000..db6613b
--- /dev/null
+++ b/third_party/flatbuffers/CMake/Version.cmake
@@ -0,0 +1,11 @@
+find_program(GIT git)
+execute_process(
+    COMMAND ${GIT} describe
+    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+    OUTPUT_VARIABLE GIT_DESCRIBE_DIRTY
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+string(REGEX REPLACE "^v([0-9]+)\\..*" "\\1" VERSION_MAJOR "${GIT_DESCRIBE_DIRTY}")
+string(REGEX REPLACE "^v[0-9]+\\.([0-9]+).*" "\\1" VERSION_MINOR "${GIT_DESCRIBE_DIRTY}")
+string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" VERSION_PATCH "${GIT_DESCRIBE_DIRTY}")
+string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.[0-9]+\\-([0-9]+).*" "\\1" VERSION_COMMIT "${GIT_DESCRIBE_DIRTY}")
diff --git a/third_party/flatbuffers/CMakeLists.txt b/third_party/flatbuffers/CMakeLists.txt
new file mode 100644
index 0000000..7da75f4
--- /dev/null
+++ b/third_party/flatbuffers/CMakeLists.txt
@@ -0,0 +1,482 @@
+cmake_minimum_required(VERSION 2.8)
+# generate compile_commands.json
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+include(CheckCXXSymbolExists)
+
+project(FlatBuffers)
+
+# NOTE: Code coverage only works on Linux & OSX.
+option(FLATBUFFERS_CODE_COVERAGE "Enable the code coverage build option." OFF)
+option(FLATBUFFERS_BUILD_TESTS "Enable the build of tests and samples." ON)
+option(FLATBUFFERS_INSTALL "Enable the installation of targets." ON)
+option(FLATBUFFERS_BUILD_FLATLIB "Enable the build of the flatbuffers library"
+       ON)
+option(FLATBUFFERS_BUILD_FLATC "Enable the build of the flatbuffers compiler"
+       ON)
+option(FLATBUFFERS_BUILD_FLATHASH "Enable the build of flathash" ON)
+option(FLATBUFFERS_BUILD_GRPCTEST "Enable the build of grpctest" OFF)
+option(FLATBUFFERS_BUILD_SHAREDLIB
+       "Enable the build of the flatbuffers shared library"
+       OFF)
+option(FLATBUFFERS_LIBCXX_WITH_CLANG "Force libc++ when using Clang" ON)
+# NOTE: Sanitizer check only works on Linux & OSX (gcc & llvm).
+option(FLATBUFFERS_CODE_SANITIZE
+      "Add '-fsanitize' flags to 'flattests' and 'flatc' targets."
+      OFF)
+option(FLATBUFFERS_PACKAGE_REDHAT
+       "Build an rpm using the 'package' target."
+       OFF)
+option(FLATBUFFERS_PACKAGE_DEBIAN
+       "Build an deb using the 'package' target."
+       OFF)
+
+if(NOT FLATBUFFERS_BUILD_FLATC AND FLATBUFFERS_BUILD_TESTS)
+    message(WARNING
+    "Cannot build tests without building the compiler. Tests will be disabled.")
+    set(FLATBUFFERS_BUILD_TESTS OFF)
+endif()
+
+if(DEFINED FLATBUFFERS_MAX_PARSING_DEPTH)
+  # Override the default recursion depth limit.
+  add_definitions(-DFLATBUFFERS_MAX_PARSING_DEPTH=${FLATBUFFERS_MAX_PARSING_DEPTH})
+  message(STATUS "FLATBUFFERS_MAX_PARSING_DEPTH: ${FLATBUFFERS_MAX_PARSING_DEPTH}")
+endif()
+
+# Auto-detect locale-narrow 'strtod_l' and  'strtoull_l' functions.
+if(NOT DEFINED FLATBUFFERS_LOCALE_INDEPENDENT)
+  set(FLATBUFFERS_LOCALE_INDEPENDENT 0)
+  if(MSVC)
+    check_cxx_symbol_exists(_strtof_l stdlib.h FLATBUFFERS_HAS_STRTOF_L)
+    check_cxx_symbol_exists(_strtoui64_l stdlib.h FLATBUFFERS_HAS_STRTOULL_L)
+  else()
+    check_cxx_symbol_exists(strtof_l stdlib.h FLATBUFFERS_HAS_STRTOF_L)
+    check_cxx_symbol_exists(strtoull_l stdlib.h FLATBUFFERS_HAS_STRTOULL_L)
+  endif()
+  if(FLATBUFFERS_HAS_STRTOF_L AND FLATBUFFERS_HAS_STRTOULL_L)
+    set(FLATBUFFERS_LOCALE_INDEPENDENT 1)
+  endif()
+endif()
+add_definitions(-DFLATBUFFERS_LOCALE_INDEPENDENT=$<BOOL:${FLATBUFFERS_LOCALE_INDEPENDENT}>)
+
+set(FlatBuffers_Library_SRCS
+  include/flatbuffers/code_generators.h
+  include/flatbuffers/base.h
+  include/flatbuffers/flatbuffers.h
+  include/flatbuffers/hash.h
+  include/flatbuffers/idl.h
+  include/flatbuffers/util.h
+  include/flatbuffers/reflection.h
+  include/flatbuffers/reflection_generated.h
+  include/flatbuffers/stl_emulation.h
+  include/flatbuffers/flexbuffers.h
+  include/flatbuffers/registry.h
+  include/flatbuffers/minireflect.h
+  src/code_generators.cpp
+  src/idl_parser.cpp
+  src/idl_gen_text.cpp
+  src/reflection.cpp
+  src/util.cpp
+)
+
+set(FlatBuffers_Compiler_SRCS
+  ${FlatBuffers_Library_SRCS}
+  src/idl_gen_cpp.cpp
+  src/idl_gen_dart.cpp
+  src/idl_gen_general.cpp
+  src/idl_gen_kotlin.cpp
+  src/idl_gen_go.cpp
+  src/idl_gen_js_ts.cpp
+  src/idl_gen_php.cpp
+  src/idl_gen_python.cpp
+  src/idl_gen_lobster.cpp
+  src/idl_gen_lua.cpp
+  src/idl_gen_rust.cpp
+  src/idl_gen_fbs.cpp
+  src/idl_gen_grpc.cpp
+  src/idl_gen_json_schema.cpp
+  src/flatc.cpp
+  src/flatc_main.cpp
+  grpc/src/compiler/schema_interface.h
+  grpc/src/compiler/cpp_generator.h
+  grpc/src/compiler/cpp_generator.cc
+  grpc/src/compiler/go_generator.h
+  grpc/src/compiler/go_generator.cc
+  grpc/src/compiler/java_generator.h
+  grpc/src/compiler/java_generator.cc
+)
+
+set(FlatHash_SRCS
+  include/flatbuffers/hash.h
+  src/flathash.cpp
+)
+
+set(FlatBuffers_Tests_SRCS
+  ${FlatBuffers_Library_SRCS}
+  src/idl_gen_fbs.cpp
+  tests/test.cpp
+  tests/test_assert.h
+  tests/test_assert.cpp
+  tests/test_builder.h
+  tests/test_builder.cpp
+  tests/native_type_test_impl.h
+  tests/native_type_test_impl.cpp
+  # file generate by running compiler on tests/monster_test.fbs
+  ${CMAKE_CURRENT_BINARY_DIR}/tests/monster_test_generated.h
+  # file generate by running compiler on tests/arrays_test.fbs
+  ${CMAKE_CURRENT_BINARY_DIR}/tests/arrays_test_generated.h
+  # file generate by running compiler on tests/native_type_test.fbs
+  ${CMAKE_CURRENT_BINARY_DIR}/tests/native_type_test_generated.h
+)
+
+set(FlatBuffers_Sample_Binary_SRCS
+  include/flatbuffers/flatbuffers.h
+  samples/sample_binary.cpp
+  # file generated by running compiler on samples/monster.fbs
+  ${CMAKE_CURRENT_BINARY_DIR}/samples/monster_generated.h
+)
+
+set(FlatBuffers_Sample_Text_SRCS
+  ${FlatBuffers_Library_SRCS}
+  samples/sample_text.cpp
+  # file generated by running compiler on samples/monster.fbs
+  ${CMAKE_CURRENT_BINARY_DIR}/samples/monster_generated.h
+)
+
+set(FlatBuffers_Sample_BFBS_SRCS
+  ${FlatBuffers_Library_SRCS}
+  src/idl_gen_general.cpp
+  samples/sample_bfbs.cpp
+  # file generated by running compiler on samples/monster.fbs
+  ${CMAKE_CURRENT_BINARY_DIR}/samples/monster_generated.h
+)
+
+set(FlatBuffers_GRPCTest_SRCS
+  include/flatbuffers/flatbuffers.h
+  include/flatbuffers/grpc.h
+  include/flatbuffers/util.h
+  src/util.cpp
+  tests/monster_test.grpc.fb.h
+  tests/test_assert.h
+  tests/test_builder.h
+  tests/monster_test.grpc.fb.cc
+  tests/test_assert.cpp
+  tests/test_builder.cpp
+  grpc/tests/grpctest.cpp
+  grpc/tests/message_builder_test.cpp
+  # file generated by running compiler on samples/monster.fbs
+  ${CMAKE_CURRENT_BINARY_DIR}/samples/monster_generated.h
+)
+
+# source_group(Compiler FILES ${FlatBuffers_Compiler_SRCS})
+# source_group(Tests FILES ${FlatBuffers_Tests_SRCS})
+
+if(EXISTS "${CMAKE_TOOLCHAIN_FILE}")
+  # do not apply any global settings if the toolchain
+  # is being configured externally
+  message(STATUS "Using toolchain file: ${CMAKE_TOOLCHAIN_FILE}.")
+elseif(APPLE)
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=libc++")
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -Werror -Wextra -Wno-unused-parameter")
+  set(FLATBUFFERS_PRIVATE_CXX_FLAGS "-Wold-style-cast")
+elseif(CMAKE_COMPILER_IS_GNUCXX)
+  if(CYGWIN)
+    set(CMAKE_CXX_FLAGS
+      "${CMAKE_CXX_FLAGS} -std=gnu++11")
+  else(CYGWIN)
+    set(CMAKE_CXX_FLAGS
+      "${CMAKE_CXX_FLAGS} -std=c++0x")
+  endif(CYGWIN)
+  set(CMAKE_CXX_FLAGS
+    "${CMAKE_CXX_FLAGS} -Wall -pedantic -Werror -Wextra -Werror=shadow")
+  set(FLATBUFFERS_PRIVATE_CXX_FLAGS "-Wold-style-cast")
+  if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.4)
+    if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0)
+      set(CMAKE_CXX_FLAGS
+        "${CMAKE_CXX_FLAGS} -faligned-new -Werror=implicit-fallthrough=2")
+    endif()
+    set(CMAKE_CXX_FLAGS
+      "${CMAKE_CXX_FLAGS} -Wunused-result -Werror=unused-result -Wunused-parameter -Werror=unused-parameter")
+  endif()
+
+  # Certain platforms such as ARM do not use signed chars by default
+  # which causes issues with certain bounds checks.
+  set(CMAKE_CXX_FLAGS
+    "${CMAKE_CXX_FLAGS} -fsigned-char")
+
+elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
+  set(CMAKE_CXX_FLAGS
+      "${CMAKE_CXX_FLAGS} -std=c++0x -Wall -pedantic -Werror -Wextra -Wno-unused-parameter")
+  set(FLATBUFFERS_PRIVATE_CXX_FLAGS "-Wold-style-cast")
+  if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.8)
+    list(APPEND FLATBUFFERS_PRIVATE_CXX_FLAGS "-Wimplicit-fallthrough" "-Wextra-semi" "-Werror=unused-private-field") # enable warning
+  endif()
+  if(FLATBUFFERS_LIBCXX_WITH_CLANG)
+    if(NOT "${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
+      set(CMAKE_CXX_FLAGS
+          "${CMAKE_CXX_FLAGS} -stdlib=libc++")
+    endif()
+    if(NOT ("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD" OR
+            "${CMAKE_SYSTEM_NAME}" MATCHES "Linux"))
+      set(CMAKE_EXE_LINKER_FLAGS
+          "${CMAKE_EXE_LINKER_FLAGS} -lc++abi")
+    endif()
+  endif()
+
+  # Certain platforms such as ARM do not use signed chars by default
+  # which causes issues with certain bounds checks.
+  set(CMAKE_CXX_FLAGS
+    "${CMAKE_CXX_FLAGS} -fsigned-char")
+
+elseif(MSVC)
+  # Visual Studio pedantic build settings
+  # warning C4512: assignment operator could not be generated
+  # warning C4316: object allocated on the heap may not be aligned
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /WX /wd4512 /wd4316")
+endif()
+
+if(FLATBUFFERS_CODE_COVERAGE)
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fprofile-arcs -ftest-coverage")
+  set(CMAKE_EXE_LINKER_FLAGS
+      "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
+endif()
+
+function(add_fsanitize_to_target _target _sanitizer)
+  # FLATBUFFERS_CODE_SANITIZE: boolean {ON,OFF,YES,NO} or string with list of sanitizer.
+  # List of sanitizer is string starts with '=': "=address,undefined,thread,memory".
+  if((${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") OR
+    ((${CMAKE_CXX_COMPILER_ID} MATCHES "GNU") AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9"))
+  )
+    set(_sanitizer_flags "=address,undefined")
+    if(_sanitizer MATCHES "=.*")
+      # override default by user-defined sanitizer list
+      set(_sanitizer_flags ${_sanitizer})
+    endif()
+    target_compile_options(${_target} PRIVATE
+      -g -fsigned-char -fno-omit-frame-pointer
+      "-fsanitize${_sanitizer_flags}")
+    target_link_libraries(${_target} PRIVATE
+      "-fsanitize${_sanitizer_flags}")
+    set_property(TARGET ${_target} PROPERTY POSITION_INDEPENDENT_CODE ON)
+    message(STATUS "Sanitizer ${_sanitizer_flags} added to ${_target}")
+  endif()
+endfunction()
+
+if(BIICODE)
+  include(biicode/cmake/biicode.cmake)
+  return()
+endif()
+
+include_directories(include)
+include_directories(grpc)
+
+if(FLATBUFFERS_BUILD_FLATLIB)
+  add_library(flatbuffers STATIC ${FlatBuffers_Library_SRCS})
+  # CMake > 2.8.11: Attach header directory for when build via add_subdirectory().
+  target_include_directories(flatbuffers INTERFACE
+    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+  target_compile_options(flatbuffers PRIVATE "${FLATBUFFERS_PRIVATE_CXX_FLAGS}")
+endif()
+
+if(FLATBUFFERS_BUILD_FLATC)
+  add_executable(flatc ${FlatBuffers_Compiler_SRCS})
+  target_compile_options(flatc PRIVATE "${FLATBUFFERS_PRIVATE_CXX_FLAGS}")
+  if(FLATBUFFERS_CODE_SANITIZE AND NOT WIN32)
+    add_fsanitize_to_target(flatc ${FLATBUFFERS_CODE_SANITIZE})
+  endif()
+  if(NOT FLATBUFFERS_FLATC_EXECUTABLE)
+    set(FLATBUFFERS_FLATC_EXECUTABLE $<TARGET_FILE:flatc>)
+  endif()
+  if(MSVC)
+    # Make flatc.exe not depend on runtime dlls for easy distribution.
+    target_compile_options(flatc PUBLIC $<$<CONFIG:Release>:/MT>)
+  endif()
+endif()
+
+if(FLATBUFFERS_BUILD_FLATHASH)
+  add_executable(flathash ${FlatHash_SRCS})
+endif()
+
+if(FLATBUFFERS_BUILD_SHAREDLIB)
+  add_library(flatbuffers_shared SHARED ${FlatBuffers_Library_SRCS})
+
+  # Shared object version: "major.minor.micro"
+  # - micro updated every release when there is no API/ABI changes
+  # - minor updated when there are additions in API/ABI
+  # - major (ABI number) updated when there are changes in ABI (or removals)
+  set(FlatBuffers_Library_SONAME_MAJOR "1")
+  set(FlatBuffers_Library_SONAME_FULL "${FlatBuffers_Library_SONAME_MAJOR}.11.0")
+  set_target_properties(flatbuffers_shared PROPERTIES OUTPUT_NAME flatbuffers
+                        SOVERSION "${FlatBuffers_Library_SONAME_MAJOR}"
+                        VERSION "${FlatBuffers_Library_SONAME_FULL}")
+endif()
+
+function(compile_flatbuffers_schema_to_cpp_opt SRC_FBS OPT)
+  get_filename_component(SRC_FBS_DIR ${SRC_FBS} PATH)
+  string(REGEX REPLACE "\\.fbs$" "_generated.h" GEN_HEADER ${SRC_FBS})
+  add_custom_command(
+    OUTPUT ${GEN_HEADER}
+    COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}" -c --gen-mutable
+            --gen-object-api -o "${SRC_FBS_DIR}"
+            --cpp-ptr-type flatbuffers::unique_ptr # Used to test with C++98 STLs
+            --reflect-names ${OPT}
+            -I "${CMAKE_CURRENT_SOURCE_DIR}/tests/include_test"
+            "${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
+    DEPENDS flatc)
+endfunction()
+
+function(compile_flatbuffers_schema_to_cpp SRC_FBS)
+    compile_flatbuffers_schema_to_cpp_opt(${SRC_FBS} "--no-includes;--gen-compare")
+endfunction()
+
+function(compile_flatbuffers_schema_to_binary SRC_FBS)
+  get_filename_component(SRC_FBS_DIR ${SRC_FBS} PATH)
+  string(REGEX REPLACE "\\.fbs$" ".bfbs" GEN_BINARY_SCHEMA ${SRC_FBS})
+  add_custom_command(
+    OUTPUT ${GEN_BINARY_SCHEMA}
+    COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}" -b --schema -o "${SRC_FBS_DIR}"
+            "${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
+    DEPENDS flatc)
+endfunction()
+
+if(FLATBUFFERS_BUILD_TESTS)
+  compile_flatbuffers_schema_to_cpp(tests/monster_test.fbs)
+  compile_flatbuffers_schema_to_cpp_opt(tests/native_type_test.fbs "")
+  compile_flatbuffers_schema_to_cpp_opt(tests/arrays_test.fbs --scoped-enums)
+  include_directories(${CMAKE_CURRENT_BINARY_DIR}/tests)
+  add_executable(flattests ${FlatBuffers_Tests_SRCS})
+  set_property(TARGET flattests
+    PROPERTY COMPILE_DEFINITIONS FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
+    FLATBUFFERS_DEBUG_VERIFICATION_FAILURE=1)
+  if(FLATBUFFERS_CODE_SANITIZE)
+    if(WIN32)
+      target_compile_definitions(flattests PRIVATE FLATBUFFERS_MEMORY_LEAK_TRACKING)
+      message(STATUS "Sanitizer MSVC::_CrtDumpMemoryLeaks added to flattests")
+    else()
+      add_fsanitize_to_target(flattests ${FLATBUFFERS_CODE_SANITIZE})
+    endif()
+  endif()
+
+  compile_flatbuffers_schema_to_cpp(samples/monster.fbs)
+  include_directories(${CMAKE_CURRENT_BINARY_DIR}/samples)
+  add_executable(flatsamplebinary ${FlatBuffers_Sample_Binary_SRCS})
+  add_executable(flatsampletext ${FlatBuffers_Sample_Text_SRCS})
+  add_executable(flatsamplebfbs ${FlatBuffers_Sample_BFBS_SRCS})
+endif()
+
+if(FLATBUFFERS_BUILD_GRPCTEST)
+  if(CMAKE_COMPILER_IS_GNUCXX)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-parameter -Wno-shadow")
+  endif()
+  if(NOT GRPC_INSTALL_PATH)
+    message(SEND_ERROR "GRPC_INSTALL_PATH variable is not defined. See grpc/README.md")
+  endif()
+  if(NOT PROTOBUF_DOWNLOAD_PATH)
+    message(SEND_ERROR "PROTOBUF_DOWNLOAD_PATH variable is not defined. See grpc/README.md")
+  endif()
+  INCLUDE_DIRECTORIES(${GRPC_INSTALL_PATH}/include)
+  INCLUDE_DIRECTORIES(${PROTOBUF_DOWNLOAD_PATH}/src)
+  LINK_DIRECTORIES(${GRPC_INSTALL_PATH}/lib)
+  add_executable(grpctest ${FlatBuffers_GRPCTest_SRCS})
+  target_link_libraries(grpctest grpc++_unsecure grpc_unsecure gpr pthread dl)
+endif()
+
+include(CMake/Version.cmake)
+
+if(FLATBUFFERS_INSTALL)
+  include(GNUInstallDirs)
+
+  install(DIRECTORY include/flatbuffers DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
+
+  set(FB_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/flatbuffers")
+
+  configure_file(CMake/FlatbuffersConfigVersion.cmake.in FlatbuffersConfigVersion.cmake @ONLY)
+  install(
+      FILES "CMake/FlatbuffersConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/FlatbuffersConfigVersion.cmake"
+      DESTINATION ${FB_CMAKE_DIR}
+  )
+
+  if(FLATBUFFERS_BUILD_FLATLIB)
+    if(CMAKE_VERSION VERSION_LESS 3.0)
+      install(
+        TARGETS flatbuffers EXPORT FlatbuffersTargets
+        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+      )
+    else()
+      install(
+        TARGETS flatbuffers EXPORT FlatbuffersTargets
+        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+        INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
+      )
+    endif()
+
+    install(EXPORT FlatbuffersTargets
+      FILE FlatbuffersTargets.cmake
+      NAMESPACE flatbuffers::
+      DESTINATION ${FB_CMAKE_DIR}
+    )
+  endif()
+
+  if(FLATBUFFERS_BUILD_FLATC)
+    install(
+      TARGETS flatc EXPORT FlatcTargets
+      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    )
+
+    install(
+      EXPORT FlatcTargets
+      FILE FlatcTargets.cmake
+      NAMESPACE flatbuffers::
+      DESTINATION ${FB_CMAKE_DIR}
+    )
+  endif()
+
+  if(FLATBUFFERS_BUILD_SHAREDLIB)
+    if(CMAKE_VERSION VERSION_LESS 3.0)
+      install(
+        TARGETS flatbuffers_shared EXPORT FlatbuffersSharedTargets
+        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+        RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}
+        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+      )
+    else()
+      install(
+        TARGETS flatbuffers_shared EXPORT FlatbuffersSharedTargets
+        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+        RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}
+        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+        INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
+      )
+    endif()
+
+  install(
+      EXPORT FlatbuffersSharedTargets
+      FILE FlatbuffersSharedTargets.cmake
+      NAMESPACE flatbuffers::
+      DESTINATION ${FB_CMAKE_DIR}
+    )
+  endif()
+endif()
+
+if(FLATBUFFERS_BUILD_TESTS)
+  enable_testing()
+
+  file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/tests" DESTINATION
+       "${CMAKE_CURRENT_BINARY_DIR}")
+  add_test(NAME flattests COMMAND flattests)
+  if(FLATBUFFERS_BUILD_GRPCTEST)
+    add_test(NAME grpctest COMMAND grpctest)
+  endif()
+endif()
+
+include(CMake/BuildFlatBuffers.cmake)
+
+if(UNIX)
+    # Use of CPack only supported on Linux systems.
+    if(FLATBUFFERS_PACKAGE_DEBIAN)
+        include(CMake/PackageDebian.cmake)
+    endif()
+    if (FLATBUFFERS_PACKAGE_REDHAT)
+        include(CMake/PackageRedhat.cmake)
+    endif()
+    include(CPack)
+endif()
diff --git a/third_party/flatbuffers/CONTRIBUTING.md b/third_party/flatbuffers/CONTRIBUTING.md
new file mode 100644
index 0000000..17428ad
--- /dev/null
+++ b/third_party/flatbuffers/CONTRIBUTING.md
@@ -0,0 +1,42 @@
+Contributing    {#contributing}
+============
+
+Want to contribute? Great! First, read this page (including the small print at
+the end).
+
+# Before you contribute
+Before we can use your code, you must sign the
+[Google Individual Contributor License Agreement](https://developers.google.com/open-source/cla/individual?csw=1)
+(CLA), which you can do online. The CLA is necessary mainly because you own the
+copyright to your changes, even after your contribution becomes part of our
+codebase, so we need your permission to use and distribute your code. We also
+need to be sure of various other things—for instance that you'll tell us if you
+know that your code infringes on other people's patents. You don't have to sign
+the CLA until after you've submitted your code for review and a member has
+approved it, but you must do it before we can put your code into our codebase.
+Before you start working on a larger contribution, you should get in touch with
+us first through the issue tracker with your idea so that we can help out and
+possibly guide you. Coordinating up front makes it much easier to avoid
+frustration later on.
+
+# Code reviews
+All submissions, including submissions by project members, require review. We
+use Github pull requests for this purpose.
+
+Some tips for good pull requests:
+* Use our code
+  [style guide](https://google.github.io/styleguide/cppguide.html).
+  When in doubt, try to stay true to the existing code of the project.
+* Write a descriptive commit message. What problem are you solving and what
+  are the consequences? Where and what did you test? Some good tips:
+  [here](http://robots.thoughtbot.com/5-useful-tips-for-a-better-commit-message)
+  and [here](https://www.kernel.org/doc/Documentation/SubmittingPatches).
+* If your PR consists of multiple commits which are successive improvements /
+  fixes to your first commit, consider squashing them into a single commit
+  (`git rebase -i`) such that your PR is a single commit on top of the current
+  HEAD. This make reviewing the code so much easier, and our history more
+  readable.
+
+# The small print
+Contributions made by corporations are covered by a different agreement than
+the one above, the Software Grant and Corporate Contributor License Agreement.
diff --git a/third_party/flatbuffers/LICENSE.txt b/third_party/flatbuffers/LICENSE.txt
new file mode 100644
index 0000000..a4c5efd
--- /dev/null
+++ b/third_party/flatbuffers/LICENSE.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright 2014 Google Inc.
+
+   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.
diff --git a/third_party/flatbuffers/WORKSPACE b/third_party/flatbuffers/WORKSPACE
new file mode 100644
index 0000000..2ccde84
--- /dev/null
+++ b/third_party/flatbuffers/WORKSPACE
@@ -0,0 +1,18 @@
+workspace(name = "com_github_google_flatbuffers")
+
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+
+http_archive(
+    name = "io_bazel_rules_go",
+    urls = [
+        "https://storage.googleapis.com/bazel-mirror/github.com/bazelbuild/rules_go/releases/download/0.18.6/rules_go-0.18.6.tar.gz",
+        "https://github.com/bazelbuild/rules_go/releases/download/0.18.6/rules_go-0.18.6.tar.gz",
+    ],
+    sha256 = "f04d2373bcaf8aa09bccb08a98a57e721306c8f6043a2a0ee610fd6853dcde3d",
+)
+
+load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
+
+go_rules_dependencies()
+
+go_register_toolchains()
diff --git a/third_party/flatbuffers/android/.project b/third_party/flatbuffers/android/.project
new file mode 100644
index 0000000..e7d5931
--- /dev/null
+++ b/third_party/flatbuffers/android/.project
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (c) 2014 Google, Inc.
+
+     This software is provided 'as-is', without any express or implied
+     warranty.  In no event will the authors be held liable for any damages
+     arising from the use of this software.
+     Permission is granted to anyone to use this software for any purpose,
+     including commercial applications, and to alter it and redistribute it
+     freely, subject to the following restrictions:
+     1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+     2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+     3. This notice may not be removed or altered from any source distribution.
+ -->
+<projectDescription>
+    <name>FlatBufferTest</name>
+</projectDescription>
diff --git a/third_party/flatbuffers/android/AndroidManifest.xml b/third_party/flatbuffers/android/AndroidManifest.xml
new file mode 100644
index 0000000..846fd13
--- /dev/null
+++ b/third_party/flatbuffers/android/AndroidManifest.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2013 Google, Inc.
+
+     This software is provided 'as-is', without any express or implied
+     warranty.  In no event will the authors be held liable for any damages
+     arising from the use of this software.
+     Permission is granted to anyone to use this software for any purpose,
+     including commercial applications, and to alter it and redistribute it
+     freely, subject to the following restrictions:
+     1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+     2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+     3. This notice may not be removed or altered from any source distribution.
+ -->
+<!-- BEGIN_INCLUDE(manifest) -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.example.FlatBufferTest">
+
+    <uses-feature android:glEsVersion="0x00020000"></uses-feature>
+
+    <!-- This .apk has no Java code itself, so set hasCode to false. -->
+    <application android:label="@string/app_name"
+                 android:hasCode="false"
+                 android:allowBackup="false">
+        <!-- Our activity is the built-in NativeActivity framework class.
+             This will take care of integrating with our NDK code. -->
+        <activity android:name="android.app.NativeActivity"
+                android:label="@string/app_name"
+                android:configChanges="orientation|keyboardHidden"
+                android:screenOrientation="landscape">
+            <!-- Tell NativeActivity the name of or .so -->
+            <meta-data android:name="android.app.lib_name"
+                    android:value="FlatBufferTest" />
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
+<!-- END_INCLUDE(manifest) -->
diff --git a/third_party/flatbuffers/android/build.gradle b/third_party/flatbuffers/android/build.gradle
new file mode 100644
index 0000000..5e9809b
--- /dev/null
+++ b/third_party/flatbuffers/android/build.gradle
@@ -0,0 +1,108 @@
+// Copyright (c) 2017 Google, Inc.
+//
+// This software is provided 'as-is', without any express or implied
+// warranty.  In no event will the authors be held liable for any damages
+// arising from the use of this software.
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would be
+// appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+// misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+
+buildscript {
+  repositories {
+    jcenter()
+  }
+  dependencies {
+    classpath 'com.android.tools.build:gradle:2.3.0'
+  }
+}
+
+allprojects {
+  repositories {
+    jcenter()
+  }
+}
+
+apply plugin: 'com.android.application'
+
+android {
+  compileSdkVersion 25
+  buildToolsVersion '25.0.2'
+
+  sourceSets {
+    main {
+      manifest.srcFile 'AndroidManifest.xml'
+      res.srcDirs = ['res']
+    }
+  }
+
+  externalNativeBuild {
+    ndkBuild {
+      path "jni/Android.mk"
+    }
+  }
+
+  defaultConfig {
+    applicationId 'com.example.FlatBufferTest'
+    // This is the platform API where NativeActivity was introduced.
+    minSdkVersion 9
+    targetSdkVersion 25
+    versionCode 1
+    versionName "1.0"
+
+    buildTypes {
+      release {
+        minifyEnabled false
+      }
+    }
+
+    externalNativeBuild {
+      ndkBuild {
+        targets "FlatBufferTest"
+        arguments "-j" + Runtime.getRuntime().availableProcessors()
+        abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
+      }
+    }
+  }
+
+  lintOptions {
+    abortOnError false
+  }
+
+  // Build with each STL variant.
+  productFlavors {
+    stlport {
+      applicationIdSuffix ".stlport"
+      versionNameSuffix "-stlport"
+      externalNativeBuild {
+        ndkBuild {
+          arguments "APP_STL=stlport_static"
+        }
+      }
+    }
+    gnustl {
+      applicationIdSuffix ".gnustl"
+      versionNameSuffix "-gnustl"
+      externalNativeBuild {
+        ndkBuild {
+          arguments "APP_STL=gnustl_static"
+        }
+      }
+    }
+    libcpp {
+      applicationIdSuffix ".libcpp"
+      versionNameSuffix "-libcpp"
+      externalNativeBuild {
+        ndkBuild {
+          arguments "APP_STL=c++_static"
+        }
+      }
+    }
+  }
+}
diff --git a/third_party/flatbuffers/android/gradle/wrapper/gradle-wrapper.jar b/third_party/flatbuffers/android/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..b4163b8
--- /dev/null
+++ b/third_party/flatbuffers/android/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/third_party/flatbuffers/android/gradle/wrapper/gradle-wrapper.properties b/third_party/flatbuffers/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..1e1168c
--- /dev/null
+++ b/third_party/flatbuffers/android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Mon Jun 19 11:54:59 PDT 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.0-all.zip
diff --git a/third_party/flatbuffers/android/gradlew b/third_party/flatbuffers/android/gradlew
new file mode 100755
index 0000000..cccdd3d
--- /dev/null
+++ b/third_party/flatbuffers/android/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+    echo "$*"
+}
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Escape application args
+save () {
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+    echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+  cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/third_party/flatbuffers/android/gradlew.bat b/third_party/flatbuffers/android/gradlew.bat
new file mode 100644
index 0000000..f955316
--- /dev/null
+++ b/third_party/flatbuffers/android/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/third_party/flatbuffers/android/jni/Android.mk b/third_party/flatbuffers/android/jni/Android.mk
new file mode 100644
index 0000000..e29c872
--- /dev/null
+++ b/third_party/flatbuffers/android/jni/Android.mk
@@ -0,0 +1,65 @@
+# Copyright (c) 2013 Google, Inc.
+#
+# This software is provided 'as-is', without any express or implied
+# warranty.  In no event will the authors be held liable for any damages
+# arising from the use of this software.
+# Permission is granted to anyone to use this software for any purpose,
+# including commercial applications, and to alter it and redistribute it
+# freely, subject to the following restrictions:
+# 1. The origin of this software must not be misrepresented; you must not
+# claim that you wrote the original software. If you use this software
+# in a product, an acknowledgment in the product documentation would be
+# appreciated but is not required.
+# 2. Altered source versions must be plainly marked as such, and must not be
+# misrepresented as being the original software.
+# 3. This notice may not be removed or altered from any source distribution.
+
+LOCAL_PATH := $(call my-dir)/../..
+
+include $(LOCAL_PATH)/android/jni/include.mk
+LOCAL_PATH := $(call realpath-portable,$(LOCAL_PATH))
+
+# Empty static library so that other projects can include just the basic
+# FlatBuffers headers as a module.
+include $(CLEAR_VARS)
+LOCAL_MODULE := flatbuffers
+LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
+LOCAL_EXPORT_CPPFLAGS := -std=c++11 -fexceptions -Wall \
+    -DFLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
+
+include $(BUILD_STATIC_LIBRARY)
+
+# static library that additionally includes text parsing/generation/reflection
+# for projects that want richer functionality.
+include $(CLEAR_VARS)
+LOCAL_MODULE := flatbuffers_extra
+LOCAL_SRC_FILES := src/idl_parser.cpp \
+                   src/idl_gen_text.cpp \
+                   src/reflection.cpp \
+                   src/util.cpp \
+                   src/code_generators.cpp
+LOCAL_STATIC_LIBRARIES := flatbuffers
+LOCAL_ARM_MODE := arm
+include $(BUILD_STATIC_LIBRARY)
+
+# FlatBuffers test
+include $(CLEAR_VARS)
+LOCAL_MODULE := FlatBufferTest
+LOCAL_SRC_FILES := android/jni/main.cpp \
+                   tests/test.cpp \
+                   tests/test_assert.h \
+                   tests/test_builder.h \
+                   tests/test_assert.cpp \
+                   tests/test_builder.cpp \
+                   tests/native_type_test_impl.h \
+                   tests/native_type_test_impl.cpp \
+                   src/idl_gen_fbs.cpp \
+                   src/idl_gen_general.cpp
+LOCAL_LDLIBS := -llog -landroid -latomic
+LOCAL_STATIC_LIBRARIES := android_native_app_glue flatbuffers_extra
+LOCAL_ARM_MODE := arm
+include $(BUILD_SHARED_LIBRARY)
+
+$(call import-module,android/native_app_glue)
+
+$(call import-add-path,$(LOCAL_PATH)/../..)
diff --git a/third_party/flatbuffers/android/jni/Application.mk b/third_party/flatbuffers/android/jni/Application.mk
new file mode 100644
index 0000000..ca9e800
--- /dev/null
+++ b/third_party/flatbuffers/android/jni/Application.mk
@@ -0,0 +1,20 @@
+# Copyright (c) 2014 Google, Inc.
+#
+# This software is provided 'as-is', without any express or implied
+# warranty.  In no event will the authors be held liable for any damages
+# arising from the use of this software.
+# Permission is granted to anyone to use this software for any purpose,
+# including commercial applications, and to alter it and redistribute it
+# freely, subject to the following restrictions:
+# 1. The origin of this software must not be misrepresented; you must not
+# claim that you wrote the original software. If you use this software
+# in a product, an acknowledgment in the product documentation would be
+# appreciated but is not required.
+# 2. Altered source versions must be plainly marked as such, and must not be
+# misrepresented as being the original software.
+# 3. This notice may not be removed or altered from any source distribution.
+APP_PLATFORM := android-9
+APP_PROJECT_PATH := $(call my-dir)/..
+APP_STL ?= stlport_static
+APP_ABI := armeabi-v7a
+APP_CPPFLAGS += -std=c++11
diff --git a/third_party/flatbuffers/android/jni/build_flatc.bat b/third_party/flatbuffers/android/jni/build_flatc.bat
new file mode 100644
index 0000000..0b3f2ad
--- /dev/null
+++ b/third_party/flatbuffers/android/jni/build_flatc.bat
@@ -0,0 +1,68 @@
+@rem Copyright (c) 2013 Google, Inc.
+@rem
+@rem This software is provided 'as-is', without any express or implied
+@rem warranty.  In no event will the authors be held liable for any damages
+@rem arising from the use of this software.
+@rem Permission is granted to anyone to use this software for any purpose,
+@rem including commercial applications, and to alter it and redistribute it
+@rem freely, subject to the following restrictions:
+@rem 1. The origin of this software must not be misrepresented; you must not
+@rem claim that you wrote the original software. If you use this software
+@rem in a product, an acknowledgment in the product documentation would be
+@rem appreciated but is not required.
+@rem 2. Altered source versions must be plainly marked as such, and must not be
+@rem misrepresented as being the original software.
+@rem 3. This notice may not be removed or altered from any source distribution.
+@echo off
+
+setlocal enabledelayedexpansion
+
+set thispath=%~dp0
+
+rem Path to cmake passed in by caller.
+set cmake=%1
+rem Path to cmake project to build.
+set cmake_project_path=%2
+
+rem Newest and oldest version of Visual Studio that it's possible to select.
+set visual_studio_version_max=20
+set visual_studio_version_min=8
+
+rem Determine the newest version of Visual Studio installed on this machine.
+set visual_studio_version=
+for /L %%a in (%visual_studio_version_max%,-1,%visual_studio_version_min%) do (
+  echo Searching for Visual Studio %%a >&2
+  reg query HKLM\SOFTWARE\Microsoft\VisualStudio\%%a.0 /ve 1>NUL 2>NUL
+  if !ERRORLEVEL! EQU 0 (
+    set visual_studio_version=%%a
+    goto found_vs
+  )
+)
+echo Unable to determine whether Visual Studio is installed. >&2
+exit /B 1
+:found_vs
+
+rem Map Visual Studio version to cmake generator name.
+if "%visual_studio_version%"=="8" (
+  set cmake_generator=Visual Studio 8 2005
+)
+if "%visual_studio_version%"=="9" (
+  set cmake_generator=Visual Studio 9 2008
+)
+if %visual_studio_version% GEQ 10 (
+  set cmake_generator=Visual Studio %visual_studio_version%
+)
+rem Set visual studio version variable for msbuild.
+set VisualStudioVersion=%visual_studio_version%.0
+
+rem Generate Visual Studio solution.
+echo Generating solution for %cmake_generator%. >&2
+cd "%cmake_project_path%"
+%cmake% -G"%cmake_generator%"
+if %ERRORLEVEL% NEQ 0 (
+  exit /B %ERRORLEVEL%
+)
+
+rem Build flatc
+python %thispath%\msbuild.py flatc.vcxproj
+if ERRORLEVEL 1 exit /B 1
diff --git a/third_party/flatbuffers/android/jni/include.mk b/third_party/flatbuffers/android/jni/include.mk
new file mode 100644
index 0000000..b53e257
--- /dev/null
+++ b/third_party/flatbuffers/android/jni/include.mk
@@ -0,0 +1,237 @@
+# 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.
+
+# This file contains utility functions for Android projects using Flatbuffers.
+# To use this file, include it in your project's Android.mk by calling near the
+# top of your android makefile like so:
+#
+#     include $(FLATBUFFERS_DIR)/android/jni/include.mk
+#
+# You will also need to import the flatbuffers module using the standard
+# import-module function.
+#
+# The main functionality this file provides are the following functions:
+# flatbuffers_fbs_to_h: Converts flatbuffer schema paths to header paths.
+# flatbuffers_header_build_rule:
+#     Creates a build rule for a schema's generated header. This build rule
+#     has a dependency on the flatc compiler which will be built if necessary.
+# flatbuffers_header_build_rules:
+#     Creates build rules for generated headers for each schema listed and sets
+#     up depenedendies.
+#
+# More information and example usage can be found in the comments preceeding
+# each function.
+
+# Targets to build the Flatbuffers compiler as well as some utility definitions
+ifeq (,$(FLATBUFFERS_INCLUDE_MK_))
+FLATBUFFERS_INCLUDE_MK_ := 1
+
+# Portable version of $(realpath) that omits drive letters on Windows.
+realpath-portable = $(join $(filter %:,$(subst :,: ,$1)),\
+                      $(realpath $(filter-out %:,$(subst :,: ,$1))))
+
+PROJECT_OS := $(OS)
+ifeq (,$(OS))
+PROJECT_OS := $(shell uname -s)
+else
+ifneq ($(findstring Windows,$(PROJECT_OS)),)
+PROJECT_OS := Windows
+endif
+endif
+
+# The following block generates build rules which result in headers being
+# rebuilt from flatbuffers schemas.
+
+FLATBUFFERS_CMAKELISTS_DIR := \
+  $(call realpath-portable,$(dir $(lastword $(MAKEFILE_LIST)))/../..)
+
+# Directory that contains the FlatBuffers compiler.
+ifeq (Windows,$(PROJECT_OS))
+FLATBUFFERS_FLATC_PATH?=$(FLATBUFFERS_CMAKELISTS_DIR)
+FLATBUFFERS_FLATC := $(lastword \
+                       $(wildcard $(FLATBUFFERS_FLATC_PATH)/*/flatc.exe) \
+                       $(wildcard $(FLATBUFFERS_FLATC_PATH)/flatc.exe))
+endif
+ifeq (Linux,$(PROJECT_OS))
+FLATBUFFERS_FLATC_PATH?=$(FLATBUFFERS_CMAKELISTS_DIR)
+FLATBUFFERS_FLATC := $(FLATBUFFERS_FLATC_PATH)/flatc
+endif
+ifeq (Darwin,$(PROJECT_OS))
+FLATBUFFERS_FLATC_PATH?=$(FLATBUFFERS_CMAKELISTS_DIR)
+FLATBUFFERS_FLATC := $(lastword \
+                       $(wildcard $(FLATBUFFERS_FLATC_PATH)/*/flatc) \
+                       $(wildcard $(FLATBUFFERS_FLATC_PATH)/flatc))
+endif
+
+FLATBUFFERS_FLATC_ARGS?=
+
+# Search for cmake.
+CMAKE_ROOT := \
+  $(call realpath-portable,$(LOCAL_PATH)/../../../../../../prebuilts/cmake)
+ifeq (,$(CMAKE))
+ifeq (Linux,$(PROJECT_OS))
+CMAKE := $(wildcard $(CMAKE_ROOT)/linux-x86/current/bin/cmake*)
+endif
+ifeq (Darwin,$(PROJECT_OS))
+CMAKE := \
+  $(wildcard $(CMAKE_ROOT)/darwin-x86_64/current/*.app/Contents/bin/cmake)
+endif
+ifeq (Windows,$(PROJECT_OS))
+CMAKE := $(wildcard $(CMAKE_ROOT)/windows/current/bin/cmake*)
+endif
+endif
+ifeq (,$(CMAKE))
+CMAKE := cmake
+endif
+
+# Windows friendly portable local path.
+# GNU-make doesn't like : in paths, must use relative paths on Windows.
+ifeq (Windows,$(PROJECT_OS))
+PORTABLE_LOCAL_PATH =
+else
+PORTABLE_LOCAL_PATH = $(LOCAL_PATH)/
+endif
+
+# Generate a host build rule for the flatbuffers compiler.
+ifeq (Windows,$(PROJECT_OS))
+define build_flatc_recipe
+	$(FLATBUFFERS_CMAKELISTS_DIR)\android\jni\build_flatc.bat \
+        $(CMAKE) $(FLATBUFFERS_CMAKELISTS_DIR)
+endef
+endif
+ifeq (Linux,$(PROJECT_OS))
+define build_flatc_recipe
+	+cd $(FLATBUFFERS_CMAKELISTS_DIR) && \
+      $(CMAKE) . && \
+      $(MAKE) flatc
+endef
+endif
+ifeq (Darwin,$(PROJECT_OS))
+define build_flatc_recipe
+	cd $(FLATBUFFERS_CMAKELISTS_DIR) && "$(CMAKE)" -GXcode . && \
+        xcodebuild -target flatc
+endef
+endif
+ifeq (,$(build_flatc_recipe))
+ifeq (,$(FLATBUFFERS_FLATC))
+$(error flatc binary not found!)
+endif
+endif
+
+# Generate a build rule for flatc.
+ifeq ($(strip $(FLATBUFFERS_FLATC)),)
+flatc_target := build_flatc
+.PHONY: $(flatc_target)
+FLATBUFFERS_FLATC := \
+  python $(FLATBUFFERS_CMAKELISTS_DIR)/android/jni/run_flatc.py \
+    $(FLATBUFFERS_CMAKELISTS_DIR)
+else
+flatc_target := $(FLATBUFFERS_FLATC)
+endif
+$(flatc_target):
+	$(call build_flatc_recipe)
+
+# $(flatbuffers_fbs_to_h schema_dir,output_dir,path)
+#
+# Convert the specified schema path to a Flatbuffers generated header path.
+# For example:
+#
+# $(call flatbuffers_fbs_to_h,$(MY_PROJ_DIR)/schemas,\
+#   $(MY_PROJ_DIR)/gen/include,$(MY_PROJ_DIR)/schemas/example.fbs)
+#
+# This will convert the file path `$(MY_PROJ_DIR)/schemas/example.fbs)` to
+# `$(MY_PROJ_DIR)/gen/include/example_generated.h`
+define flatbuffers_fbs_to_h
+$(subst $(1),$(2),$(patsubst %.fbs,%_generated.h,$(3)))
+endef
+
+# $(flatbuffers_header_build_rule schema_file,schema_dir,output_dir,\
+#   schema_include_dirs)
+#
+# Generate a build rule that will convert a Flatbuffers schema to a generated
+# header derived from the schema filename using flatbuffers_fbs_to_h. For
+# example:
+#
+# $(call flatbuffers_header_build_rule,$(MY_PROJ_DIR)/schemas/example.fbs,\
+#   $(MY_PROJ_DIR)/schemas,$(MY_PROJ_DIR)/gen/include)
+#
+# The final argument, schema_include_dirs, is optional and is only needed when
+# the schema files depend on other schema files outside their own directory.
+define flatbuffers_header_build_rule
+$(eval \
+  $(call flatbuffers_fbs_to_h,$(2),$(3),$(1)): $(1) $(flatc_target)
+	$(call host-echo-build-step,generic,Generate) \
+      $(subst $(LOCAL_PATH)/,,$(call flatbuffers_fbs_to_h,$(2),$(3),$(1)))
+	$(hide) $$(FLATBUFFERS_FLATC) $(FLATBUFFERS_FLATC_ARGS) \
+      $(foreach include,$(4),-I $(include)) -o $$(dir $$@) -c $$<)
+endef
+
+# TODO: Remove when the LOCAL_PATH expansion bug in the NDK is fixed.
+# Override the default behavior of local-source-file-path to workaround
+# a bug which prevents the build of deeply nested projects when NDK_OUT is
+# set.
+local-source-file-path=\
+$(if $(call host-path-is-absolute,$1),$1,$(call \
+    realpath-portable,$(LOCAL_PATH)/$1))
+
+
+# $(flatbuffers_header_build_rules schema_files,schema_dir,output_dir,\
+#   schema_include_dirs,src_files,[build_target],[dependencies]))
+#
+# $(1) schema_files: Space separated list of flatbuffer schema files.
+# $(2) schema_dir: Directory containing the flatbuffer schemas.
+# $(3) output_dir: Where to place the generated files.
+# $(4) schema_include_dirs: Directories to include when generating schemas.
+# $(5) src_files: Files that should depend upon the headers generated from the
+#   flatbuffer schemas.
+# $(6) build_target: Name of a build target that depends upon all generated
+#   headers.
+# $(7) dependencies: Space seperated list of additional build targets src_files
+#   should depend upon.
+#
+# Use this in your own Android.mk file to generate build rules that will
+# generate header files for your flatbuffer schemas as well as automatically
+# set your source files to be dependent on the generated headers. For example:
+#
+# $(call flatbuffers_header_build_rules,$(MY_PROJ_SCHEMA_FILES),\
+#   $(MY_PROJ_SCHEMA_DIR),$(MY_PROJ_GENERATED_OUTPUT_DIR),
+#   $(MY_PROJ_SCHEMA_INCLUDE_DIRS),$(LOCAL_SRC_FILES))
+#
+# NOTE: Due problesm with path processing in ndk-build when presented with
+# deeply nested projects must redefine LOCAL_PATH after include this makefile
+# using:
+#
+# LOCAL_PATH := $(call realpath-portable,$(LOCAL_PATH))
+#
+define flatbuffers_header_build_rules
+$(foreach schema,$(1),\
+  $(call flatbuffers_header_build_rule,\
+    $(schema),$(strip $(2)),$(strip $(3)),$(strip $(4))))\
+$(foreach src,$(strip $(5)),\
+  $(eval $(call local-source-file-path,$(src)): \
+    $(foreach schema,$(strip $(1)),\
+      $(call flatbuffers_fbs_to_h,$(strip $(2)),$(strip $(3)),$(schema)))))\
+$(if $(6),\
+  $(foreach schema,$(strip $(1)),\
+    $(eval $(6): \
+      $(call flatbuffers_fbs_to_h,$(strip $(2)),$(strip $(3)),$(schema)))),)\
+$(if $(7),\
+  $(foreach src,$(strip $(5)),\
+      $(eval $(call local-source-file-path,$(src)): $(strip $(7)))),)\
+$(if $(7),\
+  $(foreach dependency,$(strip $(7)),\
+      $(eval $(6): $(dependency))),)
+endef
+
+endif  # FLATBUFFERS_INCLUDE_MK_
diff --git a/third_party/flatbuffers/android/jni/main.cpp b/third_party/flatbuffers/android/jni/main.cpp
new file mode 100644
index 0000000..0d64349
--- /dev/null
+++ b/third_party/flatbuffers/android/jni/main.cpp
@@ -0,0 +1,26 @@
+/*
+ * 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 <android_native_app_glue.h>
+
+extern int main(int argc, char **argv);
+
+void android_main(android_app *app) {
+  // Make sure glue isn't stripped.
+  app_dummy();
+
+  main(0, NULL);
+}
diff --git a/third_party/flatbuffers/android/jni/msbuild.py b/third_party/flatbuffers/android/jni/msbuild.py
new file mode 100644
index 0000000..5f92d70
--- /dev/null
+++ b/third_party/flatbuffers/android/jni/msbuild.py
@@ -0,0 +1,77 @@
+#!/usr/bin/python
+# 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.
+
+"""Simple script that locates the newest MSBuild in one of several locations.
+
+This script will find the highest version number of MSBuild and run it,
+passing its arguments through to MSBuild.
+"""
+
+import glob
+import os
+import re
+import string
+import subprocess
+import sys
+
+SYSTEMROOT = os.getenv("SYSTEMROOT", "c:\\windows")
+PROGRAM_FILES = os.getenv("ProgramFiles", "c:\\Program Files")
+PROGRAM_FILES_X86 = os.getenv("ProgramFiles(x86)", "c:\\Program Files (x86)")
+
+SEARCH_FOLDERS = [ PROGRAM_FILES + "\\MSBuild\\*\\Bin\\MSBuild.exe",
+                   PROGRAM_FILES_X86 + "\\MSBuild\\*\\Bin\\MSBuild.exe",
+                   SYSTEMROOT + "\\Microsoft.NET\Framework\\*\\MSBuild.exe" ]
+
+def compare_version(a, b):
+  """Compare two version number strings of the form W.X.Y.Z.
+
+  The numbers are compared most-significant to least-significant.
+  For example, 12.345.67.89 > 2.987.88.99.
+
+  Args:
+    a: First version number string to compare
+    b: Second version number string to compare
+
+  Returns:
+    0 if the numbers are identical, a positive number if 'a' is larger, and
+    a negative number if 'b' is larger.
+  """
+  aa = string.split(a, ".")
+  bb = string.split(b, ".")
+  for i in range(0, 4):
+    if aa[i] != bb[i]:
+      return cmp(int(aa[i]), int(bb[i]))
+  return 0
+
+def main():
+  msbuilds = []
+
+  for folder in SEARCH_FOLDERS:
+    for file in glob.glob(folder):
+      p = subprocess.Popen([file, "/version"], stdout=subprocess.PIPE)
+      out, err = p.communicate()
+      match = re.search("^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+$", out, re.M)
+      if match:
+        msbuilds.append({ 'ver':match.group(), 'exe':file })
+  msbuilds.sort(lambda x, y: compare_version(x['ver'], y['ver']), reverse=True)
+  if len(msbuilds) == 0:
+    print "Unable to find MSBuild.\n"
+    return -1;
+  cmd = [msbuilds[0]['exe']]
+  cmd.extend(sys.argv[1:])
+  return subprocess.call(cmd)
+
+if __name__ == '__main__':
+  sys.exit(main())
diff --git a/third_party/flatbuffers/android/jni/run_flatc.py b/third_party/flatbuffers/android/jni/run_flatc.py
new file mode 100755
index 0000000..cda13bb
--- /dev/null
+++ b/third_party/flatbuffers/android/jni/run_flatc.py
@@ -0,0 +1,46 @@
+#!/usr/bin/python
+# 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.
+
+import os
+import platform
+import subprocess
+import sys
+
+EXECUTABLE_EXTENSION = '.exe' if platform.system() == 'Windows' else ''
+# Paths to search for flatc relative to the current working directory.
+FLATC_SEARCH_PATHS = [os.path.curdir, 'Release', 'Debug']
+
+def main():
+  """Script that finds and runs flatc built from source."""
+  if len(sys.argv) < 2:
+    sys.stderr.write('Usage: run_flatc.py flatbuffers_dir [flatc_args]\n')
+    return 1
+  cwd = os.getcwd()
+  flatc = ''
+  flatbuffers_dir = sys.argv[1]
+  for path in FLATC_SEARCH_PATHS:
+    current = os.path.join(flatbuffers_dir, path,
+                           'flatc' + EXECUTABLE_EXTENSION)
+    if os.path.exists(current):
+      flatc = current
+      break
+  if not flatc:
+    sys.stderr.write('flatc not found\n')
+    return 1
+  command = [flatc] + sys.argv[2:]
+  return subprocess.call(command)
+
+if __name__ == '__main__':
+  sys.exit(main())
diff --git a/third_party/flatbuffers/android/res/values/strings.xml b/third_party/flatbuffers/android/res/values/strings.xml
new file mode 100644
index 0000000..ec75239
--- /dev/null
+++ b/third_party/flatbuffers/android/res/values/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2014 Google, Inc.
+
+     This software is provided 'as-is', without any express or implied
+     warranty.  In no event will the authors be held liable for any damages
+     arising from the use of this software.
+     Permission is granted to anyone to use this software for any purpose,
+     including commercial applications, and to alter it and redistribute it
+     freely, subject to the following restrictions:
+     1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+     2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+     3. This notice may not be removed or altered from any source distribution.
+ -->
+<resources>
+    <string name="app_name">FlatBufferTest</string>
+</resources>
diff --git a/third_party/flatbuffers/appveyor.yml b/third_party/flatbuffers/appveyor.yml
new file mode 100644
index 0000000..75a63c8
--- /dev/null
+++ b/third_party/flatbuffers/appveyor.yml
@@ -0,0 +1,105 @@
+branches:
+  only:
+    - master
+
+os: Visual Studio 2015
+
+environment:
+
+  global:
+    # Workaround for https://github.com/conda/conda-build/issues/636
+    PYTHONIOENCODING: UTF-8
+    CONDA_INSTALL_LOCN: "C:\\Miniconda35-x64"
+
+  matrix:
+    - CMAKE_VS_VERSION: "10 2010"
+      MONSTER_EXTRA: "skip"
+
+    - CMAKE_VS_VERSION: "12 2013"
+      MONSTER_EXTRA: "skip"
+
+    - CMAKE_VS_VERSION: "14 2015"
+      MONSTER_EXTRA: ""
+
+platform:
+  - x86
+  - x64
+
+configuration:
+  - Debug
+  - Release
+
+before_build:
+  - set MONSTER_EXTRA=%MONSTER_EXTRA%
+  - cmake -G"Visual Studio %CMAKE_VS_VERSION%" -DFLATBUFFERS_CODE_SANITIZE=1 .
+  # This cuts down on a lot of noise generated by xamarin warnings.
+  - del "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets"
+
+build:
+  project: ALL_BUILD.vcxproj
+  verbosity: minimal
+
+after_build:
+  - python conan/appveyor/install.py
+  - python conan/appveyor/build.py
+
+install:
+  - set PATH=%CONDA_INSTALL_LOCN%;%CONDA_INSTALL_LOCN%\scripts;%PATH%;
+  - curl -sSf -o rustup-init.exe https://win.rustup.rs/
+  - rustup-init.exe -y
+  - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
+  - rustc -V
+  - cargo -V
+
+test_script:
+  - call .appveyor\check-generate-code.bat -b %CONFIGURATION%
+  - "cd tests"
+  - rem "Building all code"
+  - generate_code.bat -b %CONFIGURATION%
+  - 7z a GeneratedMyGameCode.zip MyGame\
+  - rem "---------------- C++ -----------------"
+  - "cd .."
+  - "%CONFIGURATION%\\flattests.exe"
+  - "cd tests"
+  - rem "---------------- Java -----------------"
+  - "java -version"
+  - "JavaTest.bat"
+  - rem "---------------- Rust ----------------"
+  - "RustTest.bat"
+  - rem "---------------- JS -----------------"
+  - "node --version"
+  - "..\\%CONFIGURATION%\\flatc -b -I include_test monster_test.fbs unicode_test.json"
+  - "node JavaScriptTest ./monster_test_generated"
+  - rem "-------------- Python ---------------"
+  - where python
+  - python --version
+  - where pip
+  - pip --version
+  - where conda
+  - conda --version
+  - rem "installing flatbuffers python library"
+  - pip install ../python
+  - rem "testing without installing Numpy"
+  - python py_test.py 0 0 0
+  - rem "testing after installing Numpy - disabled"
+  # FIXME: This has a LOT of unnecessary dependencies and makes the tests fail
+  # with timeouts.
+  # - conda install --yes numpy
+  # - python py_test.py 0 0 0
+  - rem "---------------- C# -----------------"
+  # Have to compile this here rather than in "build" above because AppVeyor only
+  # supports building one project??
+  - "cd FlatBuffers.Test"
+  - "msbuild.exe /property:Configuration=Release;OutputPath=tempcs /verbosity:minimal FlatBuffers.Test.csproj"
+  - "tempcs\\FlatBuffers.Test.exe"
+  # Run tests with UNSAFE_BYTEBUFFER
+  - "msbuild.exe /property:Configuration=Release;UnsafeByteBuffer=true;OutputPath=tempcsUnsafe /verbosity:minimal FlatBuffers.Test.csproj"
+  - "tempcsUnsafe\\FlatBuffers.Test.exe"
+  # TODO: add more languages.
+  - "cd ..\\.."
+
+artifacts:
+  - path: $(CONFIGURATION)\flatc.exe
+    name: flatc.exe
+  - path: tests\GeneratedMyGameCode.zip
+    name: GeneratedMyGameCode.zip
diff --git a/third_party/flatbuffers/build_defs.bzl b/third_party/flatbuffers/build_defs.bzl
new file mode 100644
index 0000000..a92f0ed
--- /dev/null
+++ b/third_party/flatbuffers/build_defs.bzl
@@ -0,0 +1,237 @@
+# Description:
+#   BUILD rules for generating flatbuffer files in various languages.
+
+"""
+Rules for building C++ flatbuffers with Bazel.
+"""
+
+flatc_path = "@com_github_google_flatbuffers//:flatc"
+
+DEFAULT_INCLUDE_PATHS = [
+    "./",
+    "$(GENDIR)",
+    "$(BINDIR)",
+]
+
+DEFAULT_FLATC_ARGS = [
+    "--gen-object-api",
+    "--gen-compare",
+    "--no-includes",
+    "--gen-mutable",
+    "--reflect-names",
+    "--cpp-ptr-type flatbuffers::unique_ptr",
+]
+
+def flatbuffer_library_public(
+        name,
+        srcs,
+        outs,
+        language_flag,
+        out_prefix = "",
+        includes = [],
+        include_paths = DEFAULT_INCLUDE_PATHS,
+        flatc_args = DEFAULT_FLATC_ARGS,
+        reflection_name = "",
+        reflection_visibility = None,
+        output_to_bindir = False):
+    """Generates code files for reading/writing the given flatbuffers in the requested language using the public compiler.
+
+    Args:
+      name: Rule name.
+      srcs: Source .fbs files. Sent in order to the compiler.
+      outs: Output files from flatc.
+      language_flag: Target language flag. One of [-c, -j, -js].
+      out_prefix: Prepend this path to the front of all generated files except on
+          single source targets. Usually is a directory name.
+      includes: Optional, list of filegroups of schemas that the srcs depend on.
+      include_paths: Optional, list of paths the includes files can be found in.
+      flatc_args: Optional, list of additional arguments to pass to flatc.
+      reflection_name: Optional, if set this will generate the flatbuffer
+        reflection binaries for the schemas.
+      reflection_visibility: The visibility of the generated reflection Fileset.
+      output_to_bindir: Passed to genrule for output to bin directory.
+
+
+    This rule creates a filegroup(name) with all generated source files, and
+    optionally a Fileset([reflection_name]) with all generated reflection
+    binaries.
+    """
+    include_paths_cmd = ["-I %s" % (s) for s in include_paths]
+
+    # '$(@D)' when given a single source target will give the appropriate
+    # directory. Appending 'out_prefix' is only necessary when given a build
+    # target with multiple sources.
+    output_directory = (
+        ("-o $(@D)/%s" % (out_prefix)) if len(srcs) > 1 else ("-o $(@D)")
+    )
+    genrule_cmd = " ".join([
+        "SRCS=($(SRCS));",
+        "for f in $${SRCS[@]:0:%s}; do" % len(srcs),
+        "$(location %s)" % (flatc_path),
+        " ".join(include_paths_cmd),
+        " ".join(flatc_args),
+        language_flag,
+        output_directory,
+        "$$f;",
+        "done",
+    ])
+    native.genrule(
+        name = name,
+        srcs = srcs + includes,
+        outs = outs,
+        output_to_bindir = output_to_bindir,
+        tools = [flatc_path],
+        cmd = genrule_cmd,
+        message = "Generating flatbuffer files for %s:" % (name),
+    )
+    if reflection_name:
+        reflection_genrule_cmd = " ".join([
+            "SRCS=($(SRCS));",
+            "for f in $${SRCS[@]:0:%s}; do" % len(srcs),
+            "$(location %s)" % (flatc_path),
+            "-b --schema",
+            " ".join(flatc_args),
+            " ".join(include_paths_cmd),
+            language_flag,
+            output_directory,
+            "$$f;",
+            "done",
+        ])
+        reflection_outs = [
+            (out_prefix + "%s.bfbs") % (s.replace(".fbs", "").split("/")[-1])
+            for s in srcs
+        ]
+        native.genrule(
+            name = "%s_srcs" % reflection_name,
+            srcs = srcs + includes,
+            outs = reflection_outs,
+            output_to_bindir = output_to_bindir,
+            tools = [flatc_path],
+            cmd = reflection_genrule_cmd,
+            message = "Generating flatbuffer reflection binary for %s:" % (name),
+        )
+        native.Fileset(
+            name = reflection_name,
+            out = "%s_out" % reflection_name,
+            entries = [
+                native.FilesetEntry(files = reflection_outs),
+            ],
+            visibility = reflection_visibility,
+        )
+
+def flatbuffer_cc_library(
+        name,
+        srcs,
+        srcs_filegroup_name = "",
+        out_prefix = "",
+        includes = [],
+        include_paths = DEFAULT_INCLUDE_PATHS,
+        flatc_args = DEFAULT_FLATC_ARGS,
+        visibility = None,
+        srcs_filegroup_visibility = None,
+        gen_reflections = False):
+    '''A cc_library with the generated reader/writers for the given flatbuffer definitions.
+
+    Args:
+      name: Rule name.
+      srcs: Source .fbs files. Sent in order to the compiler.
+      srcs_filegroup_name: Name of the output filegroup that holds srcs. Pass this
+          filegroup into the `includes` parameter of any other
+          flatbuffer_cc_library that depends on this one's schemas.
+      out_prefix: Prepend this path to the front of all generated files. Usually
+          is a directory name.
+      includes: Optional, list of filegroups of schemas that the srcs depend on.
+          ** SEE REMARKS BELOW **
+      include_paths: Optional, list of paths the includes files can be found in.
+      flatc_args: Optional list of additional arguments to pass to flatc
+          (e.g. --gen-mutable).
+      visibility: The visibility of the generated cc_library. By default, use the
+          default visibility of the project.
+      srcs_filegroup_visibility: The visibility of the generated srcs filegroup.
+          By default, use the value of the visibility parameter above.
+      gen_reflections: Optional, if true this will generate the flatbuffer
+        reflection binaries for the schemas.
+
+    This produces:
+      filegroup([name]_srcs): all generated .h files.
+      filegroup(srcs_filegroup_name if specified, or [name]_includes if not):
+          Other flatbuffer_cc_library's can pass this in for their `includes`
+          parameter, if they depend on the schemas in this library.
+      Fileset([name]_reflection): (Optional) all generated reflection binaries.
+      cc_library([name]): library with sources and flatbuffers deps.
+
+    Remarks:
+      ** Because the genrule used to call flatc does not have any trivial way of
+        computing the output list of files transitively generated by includes and
+        --gen-includes (the default) being defined for flatc, the --gen-includes
+        flag will not work as expected. The way around this is to add a dependency
+        to the flatbuffer_cc_library defined alongside the flatc included Fileset.
+        For example you might define:
+
+        flatbuffer_cc_library(
+            name = "my_fbs",
+            srcs = [ "schemas/foo.fbs" ],
+            includes = [ "//third_party/bazz:bazz_fbs_includes" ],
+        )
+
+        In which foo.fbs includes a few files from the Fileset defined at
+        //third_party/bazz:bazz_fbs_includes. When compiling the library that
+        includes foo_generated.h, and therefore has my_fbs as a dependency, it
+        will fail to find any of the bazz *_generated.h files unless you also
+        add bazz's flatbuffer_cc_library to your own dependency list, e.g.:
+
+        cc_library(
+            name = "my_lib",
+            deps = [
+                ":my_fbs",
+                "//third_party/bazz:bazz_fbs"
+            ],
+        )
+
+        Happy dependent Flatbuffering!
+    '''
+    output_headers = [
+        (out_prefix + "%s_generated.h") % (s.replace(".fbs", "").split("/")[-1])
+        for s in srcs
+    ]
+    reflection_name = "%s_reflection" % name if gen_reflections else ""
+
+    srcs_lib = "%s_srcs" % (name)
+    flatbuffer_library_public(
+        name = srcs_lib,
+        srcs = srcs,
+        outs = output_headers,
+        language_flag = "-c",
+        out_prefix = out_prefix,
+        includes = includes,
+        include_paths = include_paths,
+        flatc_args = flatc_args,
+        reflection_name = reflection_name,
+        reflection_visibility = visibility,
+    )
+    native.cc_library(
+        name = name,
+        hdrs = [
+            ":" + srcs_lib,
+        ],
+        srcs = [
+            ":" + srcs_lib,
+        ],
+        features = [
+            "-parse_headers",
+        ],
+        deps = [
+            "@com_github_google_flatbuffers//:runtime_cc",
+        ],
+        includes = [],
+        linkstatic = 1,
+        visibility = visibility,
+    )
+
+    # A filegroup for the `srcs`. That is, all the schema files for this
+    # Flatbuffer set.
+    native.filegroup(
+        name = srcs_filegroup_name if srcs_filegroup_name else "%s_includes" % (name),
+        srcs = srcs,
+        visibility = srcs_filegroup_visibility if srcs_filegroup_visibility != None else visibility,
+    )
diff --git a/third_party/flatbuffers/composer.json b/third_party/flatbuffers/composer.json
new file mode 100644
index 0000000..807709c
--- /dev/null
+++ b/third_party/flatbuffers/composer.json
@@ -0,0 +1,18 @@
+{
+  "name": "google/flatbuffers",
+  "type": "library",
+  "description": "FlatBuffers for PHP",
+  "keywords": ["google", "flatbuffers", "serialization"],
+  "homepage": "https://github.com/google/flatbuffers",
+  "license": "Apache-2.0",
+  "require": {
+    "php": ">=5.4"
+  },
+  "require-dev": {
+  },
+  "autoload": {
+    "psr-4": {
+      "Google\\FlatBuffers\\": "php"
+    }
+  }
+}
\ No newline at end of file
diff --git a/third_party/flatbuffers/conan/CMakeLists.txt b/third_party/flatbuffers/conan/CMakeLists.txt
new file mode 100644
index 0000000..d32a013
--- /dev/null
+++ b/third_party/flatbuffers/conan/CMakeLists.txt
@@ -0,0 +1,12 @@
+cmake_minimum_required(VERSION 2.8)
+
+message(STATUS "Conan FlatBuffers Wrapper")
+
+include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
+conan_basic_setup()
+
+if (WIN32 AND MSVC AND FLATBUFFERS_BUILD_SHAREDLIB)
+    set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
+endif(WIN32 AND MSVC AND FLATBUFFERS_BUILD_SHAREDLIB)
+
+include(${CMAKE_SOURCE_DIR}/CMakeListsOriginal.txt)
diff --git a/third_party/flatbuffers/conan/appveyor/build.py b/third_party/flatbuffers/conan/appveyor/build.py
new file mode 100644
index 0000000..9bac46d
--- /dev/null
+++ b/third_party/flatbuffers/conan/appveyor/build.py
@@ -0,0 +1,8 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+import os
+
+if os.getenv("APPVEYOR_REPO_TAG") != "true":
+    print("Skip build step. It's not TAG")
+else:
+    os.system("python conan/build.py")
diff --git a/third_party/flatbuffers/conan/appveyor/install.py b/third_party/flatbuffers/conan/appveyor/install.py
new file mode 100644
index 0000000..962c7da
--- /dev/null
+++ b/third_party/flatbuffers/conan/appveyor/install.py
@@ -0,0 +1,8 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+import os
+
+if os.getenv("APPVEYOR_REPO_TAG") != "true":
+    print("Skip step. It's not TAG")
+else:
+    os.system("pip install conan conan-package-tools")
diff --git a/third_party/flatbuffers/conan/build.py b/third_party/flatbuffers/conan/build.py
new file mode 100644
index 0000000..5545631
--- /dev/null
+++ b/third_party/flatbuffers/conan/build.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+import os
+import re
+import subprocess
+from cpt.packager import ConanMultiPackager
+
+
+def set_appveyor_environment():
+    if os.getenv("APPVEYOR") is not None:
+        compiler_version = os.getenv("CMAKE_VS_VERSION").split(" ")[0].replace('"', '')
+        os.environ["CONAN_VISUAL_VERSIONS"] = compiler_version
+        os.environ["CONAN_STABLE_BRANCH_PATTERN"] = "master"
+        ci_platform = os.getenv("Platform").replace('"', '')
+        ci_platform = "x86" if ci_platform == "x86" else "x86_64"
+        os.environ["CONAN_ARCHS"] = ci_platform
+        os.environ["CONAN_BUILD_TYPES"] = os.getenv("Configuration").replace('"', '')
+
+
+def get_branch():
+    try:
+        for line in subprocess.check_output("git branch", shell=True).decode().splitlines():
+            line = line.strip()
+            if line.startswith("*") and " (HEAD detached" not in line:
+                return line.replace("*", "", 1).strip()
+        return ""
+    except Exception:
+        pass
+    return ""
+
+
+def get_version():
+    version = get_branch()
+    if os.getenv("TRAVIS", False):
+        version = os.getenv("TRAVIS_BRANCH")
+
+    if os.getenv("APPVEYOR", False):
+        version = os.getenv("APPVEYOR_REPO_BRANCH")
+        if os.getenv("APPVEYOR_REPO_TAG") == "true":
+            version = os.getenv("APPVEYOR_REPO_TAG_NAME")
+
+    match = re.search(r"v(\d+\.\d+\.\d+.*)", version)
+    if match:
+        return match.group(1)
+    return version
+
+
+def get_reference(username):
+    return "flatbuffers/{}@google/stable".format(get_version())
+
+
+if __name__ == "__main__":
+    login_username = os.getenv("CONAN_LOGIN_USERNAME", "aardappel")
+    username = os.getenv("CONAN_USERNAME", "google")
+    upload = os.getenv("CONAN_UPLOAD", "https://api.bintray.com/conan/aardappel/flatbuffers")
+    stable_branch_pattern = os.getenv("CONAN_STABLE_BRANCH_PATTERN", r"v\d+\.\d+\.\d+.*")
+    test_folder = os.getenv("CPT_TEST_FOLDER", os.path.join("conan", "test_package"))
+    upload_only_when_stable = os.getenv("CONAN_UPLOAD_ONLY_WHEN_STABLE", True)
+    set_appveyor_environment()
+
+    builder = ConanMultiPackager(reference=get_reference(username),
+                                 username=username,
+                                 login_username=login_username,
+                                 upload=upload,
+                                 stable_branch_pattern=stable_branch_pattern,
+                                 upload_only_when_stable=upload_only_when_stable,
+                                 test_folder=test_folder)
+    builder.add_common_builds(pure_c=False)
+    builder.run()
diff --git a/third_party/flatbuffers/conan/test_package/CMakeLists.txt b/third_party/flatbuffers/conan/test_package/CMakeLists.txt
new file mode 100644
index 0000000..9c1c78c
--- /dev/null
+++ b/third_party/flatbuffers/conan/test_package/CMakeLists.txt
@@ -0,0 +1,9 @@
+project(test_package CXX)
+cmake_minimum_required(VERSION 2.8.11)
+
+include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
+conan_basic_setup()
+
+add_executable(${PROJECT_NAME} test_package.cpp)
+target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS})
+set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 11)
diff --git a/third_party/flatbuffers/conan/test_package/conanfile.py b/third_party/flatbuffers/conan/test_package/conanfile.py
new file mode 100644
index 0000000..735e31d
--- /dev/null
+++ b/third_party/flatbuffers/conan/test_package/conanfile.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from conans import ConanFile, CMake
+import os
+
+
+class TestPackageConan(ConanFile):
+    settings = "os", "compiler", "build_type", "arch"
+    generators = "cmake"
+
+    def build(self):
+        cmake = CMake(self)
+        cmake.configure()
+        cmake.build()
+
+    def test(self):
+        bin_path = os.path.join("bin", "test_package")
+        self.run(bin_path, run_environment=True)
+        self.run("flatc --version", run_environment=True)
+        self.run("flathash fnv1_16 conan", run_environment=True)
diff --git a/third_party/flatbuffers/conan/test_package/test_package.cpp b/third_party/flatbuffers/conan/test_package/test_package.cpp
new file mode 100644
index 0000000..df7d577
--- /dev/null
+++ b/third_party/flatbuffers/conan/test_package/test_package.cpp
@@ -0,0 +1,35 @@
+/*
+ * 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 <cstdlib>
+#include <iostream>
+#include "flatbuffers/util.h"
+
+// Test to validate Conan package generated
+
+int main(int /*argc*/, const char * /*argv*/ []) {
+
+  const std::string filename("conanbuildinfo.cmake");
+
+  if (flatbuffers::FileExists(filename.c_str())) {
+    std::cout << "File " << filename << " exists.\n";
+  } else {
+    std::cout << "File " << filename << " does not exist.\n";
+    return EXIT_FAILURE;
+  }
+
+  return EXIT_SUCCESS;
+}
diff --git a/third_party/flatbuffers/conan/travis/build.sh b/third_party/flatbuffers/conan/travis/build.sh
new file mode 100755
index 0000000..069ced2
--- /dev/null
+++ b/third_party/flatbuffers/conan/travis/build.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+set -e
+set -x
+
+if [[ "$(uname -s)" == 'Darwin' ]]; then
+    if which pyenv > /dev/null; then
+        eval "$(pyenv init -)"
+    fi
+    pyenv activate conan
+fi
+
+conan user
+python conan/build.py
diff --git a/third_party/flatbuffers/conan/travis/install.sh b/third_party/flatbuffers/conan/travis/install.sh
new file mode 100755
index 0000000..f4208d8
--- /dev/null
+++ b/third_party/flatbuffers/conan/travis/install.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+set -e
+set -x
+
+if [[ "$(uname -s)" == 'Darwin' ]]; then
+    brew update || brew update
+    brew outdated pyenv || brew upgrade pyenv
+    brew install pyenv-virtualenv
+    brew install cmake || true
+
+    if which pyenv > /dev/null; then
+        eval "$(pyenv init -)"
+    fi
+
+    pyenv install 2.7.10
+    pyenv virtualenv 2.7.10 conan
+    pyenv rehash
+    pyenv activate conan
+fi
+
+pip install -U conan_package_tools conan
diff --git a/third_party/flatbuffers/conanfile.py b/third_party/flatbuffers/conanfile.py
new file mode 100644
index 0000000..bdd832c
--- /dev/null
+++ b/third_party/flatbuffers/conanfile.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""Conan recipe package for Google FlatBuffers
+"""
+import os
+import shutil
+from conans import ConanFile, CMake, tools
+
+
+class FlatbuffersConan(ConanFile):
+    name = "flatbuffers"
+    license = "Apache-2.0"
+    url = "https://github.com/google/flatbuffers"
+    homepage = "http://google.github.io/flatbuffers/"
+    author = "Wouter van Oortmerssen"
+    topics = ("conan", "flatbuffers", "serialization", "rpc", "json-parser")
+    description = "Memory Efficient Serialization Library"
+    settings = "os", "compiler", "build_type", "arch"
+    options = {"shared": [True, False], "fPIC": [True, False]}
+    default_options = {"shared": False, "fPIC": True}
+    generators = "cmake"
+    exports = "LICENSE.txt"
+    exports_sources = ["CMake/*", "include/*", "src/*", "grpc/*", "CMakeLists.txt", "conan/CMakeLists.txt"]
+
+    def source(self):
+        """Wrap the original CMake file to call conan_basic_setup
+        """
+        shutil.move("CMakeLists.txt", "CMakeListsOriginal.txt")
+        shutil.move(os.path.join("conan", "CMakeLists.txt"), "CMakeLists.txt")
+
+    def config_options(self):
+        """Remove fPIC option on Windows platform
+        """
+        if self.settings.os == "Windows":
+            self.options.remove("fPIC")
+
+    def configure_cmake(self):
+        """Create CMake instance and execute configure step
+        """
+        cmake = CMake(self)
+        cmake.definitions["FLATBUFFERS_BUILD_TESTS"] = False
+        cmake.definitions["FLATBUFFERS_BUILD_SHAREDLIB"] = self.options.shared
+        cmake.definitions["FLATBUFFERS_BUILD_FLATLIB"] = not self.options.shared
+        cmake.configure()
+        return cmake
+
+    def build(self):
+        """Configure, build and install FlatBuffers using CMake.
+        """
+        cmake = self.configure_cmake()
+        cmake.build()
+
+    def package(self):
+        """Copy Flatbuffers' artifacts to package folder
+        """
+        cmake = self.configure_cmake()
+        cmake.install()
+        self.copy(pattern="LICENSE.txt", dst="licenses")
+        self.copy(pattern="FindFlatBuffers.cmake", dst=os.path.join("lib", "cmake", "flatbuffers"), src="CMake")
+        self.copy(pattern="flathash*", dst="bin", src="bin")
+        self.copy(pattern="flatc*", dst="bin", src="bin")
+        if self.settings.os == "Windows" and self.options.shared:
+            if self.settings.compiler == "Visual Studio":
+                shutil.move(os.path.join(self.package_folder, "lib", "%s.dll" % self.name),
+                            os.path.join(self.package_folder, "bin", "%s.dll" % self.name))
+            elif self.settings.compiler == "gcc":
+                shutil.move(os.path.join(self.package_folder, "lib", "lib%s.dll" % self.name),
+                            os.path.join(self.package_folder, "bin", "lib%s.dll" % self.name))
+
+    def package_info(self):
+        """Collect built libraries names and solve flatc path.
+        """
+        self.cpp_info.libs = tools.collect_libs(self)
+        self.user_info.flatc = os.path.join(self.package_folder, "bin", "flatc")
diff --git a/third_party/flatbuffers/dart/CHANGELOG.md b/third_party/flatbuffers/dart/CHANGELOG.md
new file mode 100644
index 0000000..5e2d2de
--- /dev/null
+++ b/third_party/flatbuffers/dart/CHANGELOG.md
@@ -0,0 +1,14 @@
+# CHANGELOG
+
+## 1.9.2
+
+- Ensure `_writeString` adds enough padding to null terminate strings.
+
+## 1.9.1
+
+- Changed constant identifiers to be compatible with Dart 2.x
+- No longer supports Dart 1.x
+
+## 1.9.0
+
+- Initial release, supports Dart 1.x and many dev versions of Dart 2.x
\ No newline at end of file
diff --git a/third_party/flatbuffers/dart/LICENSE b/third_party/flatbuffers/dart/LICENSE
new file mode 100644
index 0000000..b2ae013
--- /dev/null
+++ b/third_party/flatbuffers/dart/LICENSE
@@ -0,0 +1,233 @@
+The code in lib/flat_buffers.dart is based on code that was releases under the 
+following license:
+
+Copyright 2012, the Dart project authors. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Google Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+To the extent permissible, the changes to that code and the other assets in 
+this package are licensed under the Apache2 license:
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright 2014 Google Inc.
+
+   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.
diff --git a/third_party/flatbuffers/dart/README.md b/third_party/flatbuffers/dart/README.md
new file mode 100644
index 0000000..11bc0c4
--- /dev/null
+++ b/third_party/flatbuffers/dart/README.md
@@ -0,0 +1,13 @@
+# FlatBuffers for Dart
+
+This package is used to read and write FlatBuffer files in Dart.
+
+Most consumers will want to use the [`flatc`](https://github.com/google/flatbuffers)
+compiler to generate Dart code from a FlatBuffers IDL schema.  For example, the
+`monster_my_game.sample_generated.dart` was generated with `flatc` from
+`monster.fbs` in the example folder. The generated classes can be used to read
+or write binary files that are interoperable with other languages and platforms
+supported by FlatBuffers, as illustrated in the `example.dart` in the
+examples folder.
+
+Additional documentation and examples are available [at the FlatBuffers site](https://google.github.io/flatbuffers/index.html)
\ No newline at end of file
diff --git a/third_party/flatbuffers/dart/example/example.dart b/third_party/flatbuffers/dart/example/example.dart
new file mode 100644
index 0000000..d95bb31
--- /dev/null
+++ b/third_party/flatbuffers/dart/example/example.dart
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2018 Dan Field. 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.
+ */
+
+import 'package:flat_buffers/flat_buffers.dart' as fb;
+import './monster_my_game.sample_generated.dart' as myGame;
+
+// Example how to use FlatBuffers to create and read binary buffers.
+
+void main() {
+  builderTest();
+  objectBuilderTest();
+}
+
+void builderTest() {
+  final builder = new fb.Builder(initialSize: 1024);
+  final int weaponOneName = builder.writeString("Sword");
+  final int weaponOneDamage = 3;
+
+  final int weaponTwoName = builder.writeString("Axe");
+  final int weaponTwoDamage = 5;
+
+  final swordBuilder = new myGame.WeaponBuilder(builder)
+    ..begin()
+    ..addNameOffset(weaponOneName)
+    ..addDamage(weaponOneDamage);
+  final int sword = swordBuilder.finish();
+
+  final axeBuilder = new myGame.WeaponBuilder(builder)
+    ..begin()
+    ..addNameOffset(weaponTwoName)
+    ..addDamage(weaponTwoDamage);
+  final int axe = axeBuilder.finish();
+
+  // Serialize a name for our monster, called "Orc".
+  final int name = builder.writeString('Orc');
+
+  // Create a list representing the inventory of the Orc. Each number
+  // could correspond to an item that can be claimed after he is slain.
+  final List<int> treasure = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+  final inventory = builder.writeListUint8(treasure);
+  final weapons = builder.writeList([sword, axe]);
+
+  // Struct builders are very easy to reuse.
+  final vec3Builder = new myGame.Vec3Builder(builder);
+
+  vec3Builder.finish(4.0, 5.0, 6.0);
+  vec3Builder.finish(1.0, 2.0, 3.0);
+  // Set his hit points to 300 and his mana to 150.
+  final int hp = 300;
+  final int mana = 150;
+
+  final monster = new myGame.MonsterBuilder(builder)
+    ..begin()
+    ..addNameOffset(name)
+    ..addInventoryOffset(inventory)
+    ..addWeaponsOffset(weapons)
+    ..addEquippedType(myGame.EquipmentTypeId.Weapon)
+    ..addEquippedOffset(axe)
+    ..addHp(hp)
+    ..addMana(mana)
+    ..addPos(vec3Builder.finish(1.0, 2.0, 3.0))
+    ..addColor(myGame.Color.Red);
+
+  final int monsteroff = monster.finish();
+  final buffer = builder.finish(monsteroff);
+  if (verify(buffer)) {
+    print(
+        "The FlatBuffer was successfully created with a builder and verified!");
+  }
+}
+
+void objectBuilderTest() {
+  // Create the builder here so we can use it for both weapons and equipped
+  // the actual data will only be written to the buffer once.
+  var axe = new myGame.WeaponObjectBuilder(name: 'Axe', damage: 5);
+
+  var monsterBuilder = new myGame.MonsterObjectBuilder(
+    pos: new myGame.Vec3ObjectBuilder(x: 1.0, y: 2.0, z: 3.0),
+    mana: 150,
+    hp: 300,
+    name: 'Orc',
+    inventory: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
+    color: myGame.Color.Red,
+    weapons: [new myGame.WeaponObjectBuilder(name: 'Sword', damage: 3), axe],
+    equippedType: myGame.EquipmentTypeId.Weapon,
+    equipped: axe,
+  );
+
+  var buffer = monsterBuilder.toBytes();
+
+  // We now have a FlatBuffer we can store on disk or send over a network.
+
+  // ** file/network code goes here :) **
+
+  // Instead, we're going to access it right away (as if we just received it).
+  if (verify(buffer)) {
+    print(
+        "The FlatBuffer was successfully created with an object builder and verified!");
+  }
+}
+
+bool verify(List<int> buffer) {
+  // Get access to the root:
+  var monster = new myGame.Monster(buffer);
+
+  // Get and test some scalar types from the FlatBuffer.
+  assert(monster.hp == 80);
+  assert(monster.mana == 150); // default
+  assert(monster.name == "MyMonster");
+
+  // Get and test a field of the FlatBuffer's `struct`.
+  var pos = monster.pos;
+  assert(pos != null);
+  assert(pos.z == 3.0);
+
+  // Get a test an element from the `inventory` FlatBuffer's `vector`.
+  var inv = monster.inventory;
+  assert(inv != null);
+  assert(inv.length == 10);
+  assert(inv[9] == 9);
+
+  // Get and test the `weapons` FlatBuffers's `vector`.
+  var expected_weapon_names = ["Sword", "Axe"];
+  var expected_weapon_damages = [3, 5];
+  var weps = monster.weapons;
+  for (int i = 0; i < weps.length; i++) {
+    assert(weps[i].name == expected_weapon_names[i]);
+    assert(weps[i].damage == expected_weapon_damages[i]);
+  }
+
+  // Get and test the `Equipment` union (`equipped` field).
+  assert(monster.equippedType.value == myGame.EquipmentTypeId.Weapon.value);
+  assert(monster.equippedType == myGame.EquipmentTypeId.Weapon);
+
+  assert(monster.equipped is myGame.Weapon);
+  var equipped = monster.equipped as myGame.Weapon;
+  assert(equipped.name == "Axe");
+  assert(equipped.damage == 5);
+
+  print(monster);
+  return true;
+}
diff --git a/third_party/flatbuffers/dart/example/monster_my_game.sample_generated.dart b/third_party/flatbuffers/dart/example/monster_my_game.sample_generated.dart
new file mode 100644
index 0000000..2c7c10d
--- /dev/null
+++ b/third_party/flatbuffers/dart/example/monster_my_game.sample_generated.dart
@@ -0,0 +1,440 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+// ignore_for_file: unused_import, non_constant_identifier_names
+
+library my_game.sample;
+
+import 'dart:typed_data' show Uint8List;
+import 'package:flat_buffers/flat_buffers.dart' as fb;
+
+
+class Color {
+  final int value;
+  const Color._(this.value);
+
+  factory Color.fromValue(int value) {
+    if (value == null) return null;
+    if (!values.containsKey(value)) {
+      throw new StateError('Invalid value $value for bit flag enum Color');
+    }
+    return values[value];
+  }
+
+  static const int minValue = 0;
+  static const int maxValue = 2;
+  static bool containsValue(int value) => values.containsKey(value);
+
+  static const Color Red = const Color._(0);
+  static const Color Green = const Color._(1);
+  static const Color Blue = const Color._(2);
+  static get values => {0: Red,1: Green,2: Blue,};
+
+  static const fb.Reader<Color> reader = const _ColorReader();
+
+  @override
+  String toString() {
+    return 'Color{value: $value}';
+  }
+}
+
+class _ColorReader extends fb.Reader<Color> {
+  const _ColorReader();
+
+  @override
+  int get size => 1;
+
+  @override
+  Color read(fb.BufferContext bc, int offset) =>
+      new Color.fromValue(const fb.Int8Reader().read(bc, offset));
+}
+
+class EquipmentTypeId {
+  final int value;
+  const EquipmentTypeId._(this.value);
+
+  factory EquipmentTypeId.fromValue(int value) {
+    if (value == null) return null;
+    if (!values.containsKey(value)) {
+      throw new StateError('Invalid value $value for bit flag enum EquipmentTypeId');
+    }
+    return values[value];
+  }
+
+  static const int minValue = 0;
+  static const int maxValue = 1;
+  static bool containsValue(int value) => values.containsKey(value);
+
+  static const EquipmentTypeId NONE = const EquipmentTypeId._(0);
+  static const EquipmentTypeId Weapon = const EquipmentTypeId._(1);
+  static get values => {0: NONE,1: Weapon,};
+
+  static const fb.Reader<EquipmentTypeId> reader = const _EquipmentTypeIdReader();
+
+  @override
+  String toString() {
+    return 'EquipmentTypeId{value: $value}';
+  }
+}
+
+class _EquipmentTypeIdReader extends fb.Reader<EquipmentTypeId> {
+  const _EquipmentTypeIdReader();
+
+  @override
+  int get size => 1;
+
+  @override
+  EquipmentTypeId read(fb.BufferContext bc, int offset) =>
+      new EquipmentTypeId.fromValue(const fb.Uint8Reader().read(bc, offset));
+}
+
+class Vec3 {
+  Vec3._(this._bc, this._bcOffset);
+
+  static const fb.Reader<Vec3> reader = const _Vec3Reader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  double get x => const fb.Float32Reader().read(_bc, _bcOffset + 0);
+  double get y => const fb.Float32Reader().read(_bc, _bcOffset + 4);
+  double get z => const fb.Float32Reader().read(_bc, _bcOffset + 8);
+
+  @override
+  String toString() {
+    return 'Vec3{x: $x, y: $y, z: $z}';
+  }
+}
+
+class _Vec3Reader extends fb.StructReader<Vec3> {
+  const _Vec3Reader();
+
+  @override
+  int get size => 12;
+
+  @override
+  Vec3 createObject(fb.BufferContext bc, int offset) => 
+    new Vec3._(bc, offset);
+}
+
+class Vec3Builder {
+  Vec3Builder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  int finish(double x, double y, double z) {
+    fbBuilder.putFloat32(z);
+    fbBuilder.putFloat32(y);
+    fbBuilder.putFloat32(x);
+    return fbBuilder.offset;
+  }
+
+}
+
+class Vec3ObjectBuilder extends fb.ObjectBuilder {
+  final double _x;
+  final double _y;
+  final double _z;
+
+  Vec3ObjectBuilder({
+    double x,
+    double y,
+    double z,
+  })
+      : _x = x,
+        _y = y,
+        _z = z;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+
+    fbBuilder.putFloat32(_z);
+    fbBuilder.putFloat32(_y);
+    fbBuilder.putFloat32(_x);
+    return fbBuilder.offset;
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
+class Monster {
+  Monster._(this._bc, this._bcOffset);
+  factory Monster(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<Monster> reader = const _MonsterReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  Vec3 get pos => Vec3.reader.vTableGet(_bc, _bcOffset, 4, null);
+  int get mana => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 6, 150);
+  int get hp => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 8, 100);
+  String get name => const fb.StringReader().vTableGet(_bc, _bcOffset, 10, null);
+  List<int> get inventory => const fb.ListReader<int>(const fb.Uint8Reader()).vTableGet(_bc, _bcOffset, 14, null);
+  Color get color => new Color.fromValue(const fb.Int8Reader().vTableGet(_bc, _bcOffset, 16, 2));
+  List<Weapon> get weapons => const fb.ListReader<Weapon>(Weapon.reader).vTableGet(_bc, _bcOffset, 18, null);
+  EquipmentTypeId get equippedType => new EquipmentTypeId.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 20, null));
+  dynamic get equipped {
+    switch (equippedType?.value) {
+      case 1: return Weapon.reader.vTableGet(_bc, _bcOffset, 22, null);
+      default: return null;
+    }
+  }
+  List<Vec3> get path => const fb.ListReader<Vec3>(Vec3.reader).vTableGet(_bc, _bcOffset, 24, null);
+
+  @override
+  String toString() {
+    return 'Monster{pos: $pos, mana: $mana, hp: $hp, name: $name, inventory: $inventory, color: $color, weapons: $weapons, equippedType: $equippedType, equipped: $equipped, path: $path}';
+  }
+}
+
+class _MonsterReader extends fb.TableReader<Monster> {
+  const _MonsterReader();
+
+  @override
+  Monster createObject(fb.BufferContext bc, int offset) => 
+    new Monster._(bc, offset);
+}
+
+class MonsterBuilder {
+  MonsterBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  void begin() {
+    fbBuilder.startTable();
+  }
+
+  int addPos(int offset) {
+    fbBuilder.addStruct(0, offset);
+    return fbBuilder.offset;
+  }
+  int addMana(int mana) {
+    fbBuilder.addInt16(1, mana);
+    return fbBuilder.offset;
+  }
+  int addHp(int hp) {
+    fbBuilder.addInt16(2, hp);
+    return fbBuilder.offset;
+  }
+  int addNameOffset(int offset) {
+    fbBuilder.addOffset(3, offset);
+    return fbBuilder.offset;
+  }
+  int addInventoryOffset(int offset) {
+    fbBuilder.addOffset(5, offset);
+    return fbBuilder.offset;
+  }
+  int addColor(Color color) {
+    fbBuilder.addInt8(6, color?.value);
+    return fbBuilder.offset;
+  }
+  int addWeaponsOffset(int offset) {
+    fbBuilder.addOffset(7, offset);
+    return fbBuilder.offset;
+  }
+  int addEquippedType(EquipmentTypeId equippedType) {
+    fbBuilder.addUint8(8, equippedType?.value);
+    return fbBuilder.offset;
+  }
+  int addEquippedOffset(int offset) {
+    fbBuilder.addOffset(9, offset);
+    return fbBuilder.offset;
+  }
+  int addPathOffset(int offset) {
+    fbBuilder.addOffset(10, offset);
+    return fbBuilder.offset;
+  }
+
+  int finish() {
+    return fbBuilder.endTable();
+  }
+}
+
+class MonsterObjectBuilder extends fb.ObjectBuilder {
+  final Vec3ObjectBuilder _pos;
+  final int _mana;
+  final int _hp;
+  final String _name;
+  final List<int> _inventory;
+  final Color _color;
+  final List<WeaponObjectBuilder> _weapons;
+  final EquipmentTypeId _equippedType;
+  final dynamic _equipped;
+  final List<Vec3ObjectBuilder> _path;
+
+  MonsterObjectBuilder({
+    Vec3ObjectBuilder pos,
+    int mana,
+    int hp,
+    String name,
+    List<int> inventory,
+    Color color,
+    List<WeaponObjectBuilder> weapons,
+    EquipmentTypeId equippedType,
+    dynamic equipped,
+    List<Vec3ObjectBuilder> path,
+  })
+      : _pos = pos,
+        _mana = mana,
+        _hp = hp,
+        _name = name,
+        _inventory = inventory,
+        _color = color,
+        _weapons = weapons,
+        _equippedType = equippedType,
+        _equipped = equipped,
+        _path = path;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+    final int nameOffset = fbBuilder.writeString(_name);
+    final int inventoryOffset = _inventory?.isNotEmpty == true
+        ? fbBuilder.writeListUint8(_inventory)
+        : null;
+    final int weaponsOffset = _weapons?.isNotEmpty == true
+        ? fbBuilder.writeList(_weapons.map((b) => b.getOrCreateOffset(fbBuilder)).toList())
+        : null;
+    final int equippedOffset = _equipped?.getOrCreateOffset(fbBuilder);
+    final int pathOffset = _path?.isNotEmpty == true
+        ? fbBuilder.writeListOfStructs(_path)
+        : null;
+
+    fbBuilder.startTable();
+    if (_pos != null) {
+      fbBuilder.addStruct(0, _pos.finish(fbBuilder));
+    }
+    fbBuilder.addInt16(1, _mana);
+    fbBuilder.addInt16(2, _hp);
+    if (nameOffset != null) {
+      fbBuilder.addOffset(3, nameOffset);
+    }
+    if (inventoryOffset != null) {
+      fbBuilder.addOffset(5, inventoryOffset);
+    }
+    fbBuilder.addInt8(6, _color?.value);
+    if (weaponsOffset != null) {
+      fbBuilder.addOffset(7, weaponsOffset);
+    }
+    fbBuilder.addUint8(8, _equippedType?.value);
+    if (equippedOffset != null) {
+      fbBuilder.addOffset(9, equippedOffset);
+    }
+    if (pathOffset != null) {
+      fbBuilder.addOffset(10, pathOffset);
+    }
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
+class Weapon {
+  Weapon._(this._bc, this._bcOffset);
+  factory Weapon(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<Weapon> reader = const _WeaponReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  String get name => const fb.StringReader().vTableGet(_bc, _bcOffset, 4, null);
+  int get damage => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 6, null);
+
+  @override
+  String toString() {
+    return 'Weapon{name: $name, damage: $damage}';
+  }
+}
+
+class _WeaponReader extends fb.TableReader<Weapon> {
+  const _WeaponReader();
+
+  @override
+  Weapon createObject(fb.BufferContext bc, int offset) => 
+    new Weapon._(bc, offset);
+}
+
+class WeaponBuilder {
+  WeaponBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  void begin() {
+    fbBuilder.startTable();
+  }
+
+  int addNameOffset(int offset) {
+    fbBuilder.addOffset(0, offset);
+    return fbBuilder.offset;
+  }
+  int addDamage(int damage) {
+    fbBuilder.addInt16(1, damage);
+    return fbBuilder.offset;
+  }
+
+  int finish() {
+    return fbBuilder.endTable();
+  }
+}
+
+class WeaponObjectBuilder extends fb.ObjectBuilder {
+  final String _name;
+  final int _damage;
+
+  WeaponObjectBuilder({
+    String name,
+    int damage,
+  })
+      : _name = name,
+        _damage = damage;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+    final int nameOffset = fbBuilder.writeString(_name);
+
+    fbBuilder.startTable();
+    if (nameOffset != null) {
+      fbBuilder.addOffset(0, nameOffset);
+    }
+    fbBuilder.addInt16(1, _damage);
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
diff --git a/third_party/flatbuffers/dart/lib/flat_buffers.dart b/third_party/flatbuffers/dart/lib/flat_buffers.dart
new file mode 100644
index 0000000..e251260
--- /dev/null
+++ b/third_party/flatbuffers/dart/lib/flat_buffers.dart
@@ -0,0 +1,1241 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:collection';
+import 'dart:convert';
+import 'dart:math';
+import 'dart:typed_data';
+
+const int _sizeofUint8 = 1;
+const int _sizeofUint16 = 2;
+const int _sizeofUint32 = 4;
+const int _sizeofUint64 = 8;
+const int _sizeofInt8 = 1;
+const int _sizeofInt16 = 2;
+const int _sizeofInt32 = 4;
+const int _sizeofInt64 = 8;
+const int _sizeofFloat32 = 4;
+const int _sizeofFloat64 = 8;
+
+/// Callback used to invoke a struct builder's finish method.
+///
+/// This callback is used by other struct's `finish` methods to write the nested
+/// struct's fields inline.
+typedef void StructBuilder();
+
+/// Buffer with data and some context about it.
+class BufferContext {
+  final ByteData _buffer;
+
+  factory BufferContext.fromBytes(List<int> byteList) {
+    Uint8List uint8List = _asUint8List(byteList);
+    ByteData buf = new ByteData.view(uint8List.buffer, uint8List.offsetInBytes);
+    return new BufferContext._(buf);
+  }
+
+  BufferContext._(this._buffer);
+
+  int derefObject(int offset) {
+    return offset + _getUint32(offset);
+  }
+
+  Uint8List _asUint8LIst(int offset, int length) =>
+      _buffer.buffer.asUint8List(_buffer.offsetInBytes + offset, length);
+
+  double _getFloat64(int offset) =>
+      _buffer.getFloat64(offset, Endian.little);
+
+  double _getFloat32(int offset) =>
+      _buffer.getFloat32(offset, Endian.little);
+
+  int _getInt64(int offset) =>
+      _buffer.getInt64(offset, Endian.little);
+
+  int _getInt32(int offset) =>
+      _buffer.getInt32(offset, Endian.little);
+
+  int _getInt16(int offset) =>
+      _buffer.getInt16(offset, Endian.little);
+
+  int _getInt8(int offset) => _buffer.getInt8(offset);
+
+  int _getUint64(int offset) =>
+      _buffer.getUint64(offset, Endian.little);
+
+  int _getUint32(int offset) =>
+      _buffer.getUint32(offset, Endian.little);
+
+  int _getUint16(int offset) =>
+      _buffer.getUint16(offset, Endian.little);
+
+  int _getUint8(int offset) => _buffer.getUint8(offset);
+
+  /// If the [byteList] is already a [Uint8List] return it.
+  /// Otherwise return a [Uint8List] copy of the [byteList].
+  static Uint8List _asUint8List(List<int> byteList) {
+    if (byteList is Uint8List) {
+      return byteList;
+    } else {
+      return new Uint8List.fromList(byteList);
+    }
+  }
+}
+
+/// Class implemented by typed builders generated by flatc.
+abstract class ObjectBuilder {
+  int _firstOffset;
+
+  /// Can be used to write the data represented by this builder to the [Builder]
+  /// and reuse the offset created in multiple tables.
+  ///
+  /// Note that this method assumes you call it using the same [Builder] instance
+  /// every time. The returned offset is only good for the [Builder] used in the
+  /// first call to this method.
+  int getOrCreateOffset(Builder fbBuilder) {
+    _firstOffset ??= finish(fbBuilder);
+    return _firstOffset;
+  }
+
+  /// Writes the data in this helper to the [Builder].
+  int finish(Builder fbBuilder);
+
+  /// Convenience method that will create a new [Builder], [finish]es the data,
+  /// and returns the buffer as a [Uint8List] of bytes.
+  Uint8List toBytes();
+}
+
+/// Class that helps building flat buffers.
+class Builder {
+  final int initialSize;
+
+  /// The list of existing VTable(s).
+  //final List<_VTable> _vTables = <_VTable>[];
+  final List<int> _vTables = <int>[];
+
+  ByteData _buf;
+
+  /// The maximum alignment that has been seen so far.  If [_buf] has to be
+  /// reallocated in the future (to insert room at its start for more bytes) the
+  /// reallocation will need to be a multiple of this many bytes.
+  int _maxAlign;
+
+  /// The number of bytes that have been written to the buffer so far.  The
+  /// most recently written byte is this many bytes from the end of [_buf].
+  int _tail;
+
+  /// The location of the end of the current table, measured in bytes from the
+  /// end of [_buf], or `null` if a table is not currently being built.
+  int _currentTableEndTail;
+
+  _VTable _currentVTable;
+
+  /// Map containing all strings that have been written so far.  This allows us
+  /// to avoid duplicating strings.
+  ///
+  /// Allocated only if `internStrings` is set to true on the constructor.
+  Map<String, int> _strings;
+
+  /// Creates a new FlatBuffers Builder.
+  ///
+  /// `initialSize` is the initial array size in bytes.  The [Builder] will
+  /// automatically grow the array if/as needed.  `internStrings`, if set to
+  /// true, will cause [writeString] to pool strings in the buffer so that
+  /// identical strings will always use the same offset in tables.
+  Builder({this.initialSize: 1024, bool internStrings = false}) {
+    if (internStrings == true) {
+      _strings = new Map<String, int>();
+    }
+    reset();
+  }
+
+  /// Add the [field] with the given boolean [value].  The field is not added if
+  /// the [value] is equal to [def].  Booleans are stored as 8-bit fields with
+  /// `0` for `false` and `1` for `true`.
+  void addBool(int field, bool value, [bool def]) {
+    _ensureCurrentVTable();
+    if (value != null && value != def) {
+      _prepare(_sizeofUint8, 1);
+      _trackField(field);
+      _buf.setInt8(_buf.lengthInBytes - _tail, value ? 1 : 0);
+    }
+  }
+
+  /// Add the [field] with the given 32-bit signed integer [value].  The field is
+  /// not added if the [value] is equal to [def].
+  void addInt32(int field, int value, [int def]) {
+    _ensureCurrentVTable();
+    if (value != null && value != def) {
+      _prepare(_sizeofInt32, 1);
+      _trackField(field);
+      _setInt32AtTail(_buf, _tail, value);
+    }
+  }
+
+  /// Add the [field] with the given 32-bit signed integer [value].  The field is
+  /// not added if the [value] is equal to [def].
+  void addInt16(int field, int value, [int def]) {
+    _ensureCurrentVTable();
+    if (value != null && value != def) {
+      _prepare(_sizeofInt16, 1);
+      _trackField(field);
+      _setInt16AtTail(_buf, _tail, value);
+    }
+  }
+
+  /// Add the [field] with the given 8-bit signed integer [value].  The field is
+  /// not added if the [value] is equal to [def].
+  void addInt8(int field, int value, [int def]) {
+    _ensureCurrentVTable();
+    if (value != null && value != def) {
+      _prepare(_sizeofInt8, 1);
+      _trackField(field);
+      _setInt8AtTail(_buf, _tail, value);
+    }
+  }
+
+  void addStruct(int field, int offset) {
+    _ensureCurrentVTable();
+    _trackField(field);
+    _currentVTable.addField(field, offset);
+  }
+
+  /// Add the [field] referencing an object with the given [offset].
+  void addOffset(int field, int offset) {
+    _ensureCurrentVTable();
+    if (offset != null) {
+      _prepare(_sizeofUint32, 1);
+      _trackField(field);
+      _setUint32AtTail(_buf, _tail, _tail - offset);
+    }
+  }
+
+  /// Add the [field] with the given 32-bit unsigned integer [value].  The field
+  /// is not added if the [value] is equal to [def].
+  void addUint32(int field, int value, [int def]) {
+    _ensureCurrentVTable();
+    if (value != null && value != def) {
+      _prepare(_sizeofUint32, 1);
+      _trackField(field);
+      _setUint32AtTail(_buf, _tail, value);
+    }
+  }
+
+  /// Add the [field] with the given 32-bit unsigned integer [value].  The field
+  /// is not added if the [value] is equal to [def].
+  void addUint16(int field, int value, [int def]) {
+    _ensureCurrentVTable();
+    if (value != null && value != def) {
+      _prepare(_sizeofUint16, 1);
+      _trackField(field);
+      _setUint16AtTail(_buf, _tail, value);
+    }
+  }
+
+  /// Add the [field] with the given 8-bit unsigned integer [value].  The field
+  /// is not added if the [value] is equal to [def].
+  void addUint8(int field, int value, [int def]) {
+    _ensureCurrentVTable();
+    if (value != null && value != def) {
+      _prepare(_sizeofUint8, 1);
+      _trackField(field);
+      _setUint8AtTail(_buf, _tail, value);
+    }
+  }
+
+  /// Add the [field] with the given 32-bit float [value].  The field
+  /// is not added if the [value] is equal to [def].
+  void addFloat32(int field, double value, [double def]) {
+    _ensureCurrentVTable();
+    if (value != null && value != def) {
+      _prepare(_sizeofFloat32, 1);
+      _trackField(field);
+      _setFloat32AtTail(_buf, _tail, value);
+    }
+  }
+
+  /// Add the [field] with the given 64-bit double [value].  The field
+  /// is not added if the [value] is equal to [def].
+  void addFloat64(int field, double value, [double def]) {
+    _ensureCurrentVTable();
+    if (value != null && value != def) {
+      _prepare(_sizeofFloat64, 1);
+      _trackField(field);
+      _setFloat64AtTail(_buf, _tail, value);
+    }
+  }
+
+  /// Add the [field] with the given 64-bit unsigned integer [value].  The field
+  /// is not added if the [value] is equal to [def].
+  void addUint64(int field, int value, [double def]) {
+    _ensureCurrentVTable();
+    if (value != null && value != def) {
+      _prepare(_sizeofUint64, 1);
+      _trackField(field);
+      _setUint64AtTail(_buf, _tail, value);
+    }
+  }
+
+  /// Add the [field] with the given 64-bit unsigned integer [value].  The field
+  /// is not added if the [value] is equal to [def].
+  void addInt64(int field, int value, [double def]) {
+    _ensureCurrentVTable();
+    if (value != null && value != def) {
+      _prepare(_sizeofInt64, 1);
+      _trackField(field);
+      _setInt64AtTail(_buf, _tail, value);
+    }
+  }
+
+  /// End the current table and return its offset.
+  int endTable() {
+    if (_currentVTable == null) {
+      throw new StateError('Start a table before ending it.');
+    }
+    // Prepare for writing the VTable.
+    _prepare(_sizeofInt32, 1);
+    int tableTail = _tail;
+    // Prepare the size of the current table.
+    _currentVTable.tableSize = tableTail - _currentTableEndTail;
+    // Prepare the VTable to use for the current table.
+    int vTableTail;
+    {
+      _currentVTable.computeFieldOffsets(tableTail);
+      // Try to find an existing compatible VTable.
+      // Search backward - more likely to have recently used one
+      for (int i = _vTables.length - 1; i >= 0; i--) {
+        final int vt2Offset = _vTables[i];
+        final int vt2Start = _buf.lengthInBytes - vt2Offset;
+        final int vt2Size = _buf.getUint16(vt2Start, Endian.little);
+
+        if (_currentVTable._vTableSize == vt2Size &&
+            _currentVTable._offsetsMatch(vt2Start, _buf)) {
+          vTableTail = vt2Offset;
+          break;
+        }
+      }
+      // Write a new VTable.
+      if (vTableTail == null) {
+        _prepare(_sizeofUint16, _currentVTable.numOfUint16);
+        vTableTail = _tail;
+        _currentVTable.tail = vTableTail;
+        _currentVTable.output(_buf, _buf.lengthInBytes - _tail);
+        _vTables.add(_currentVTable.tail);
+      }
+    }
+    // Set the VTable offset.
+    _setInt32AtTail(_buf, tableTail, vTableTail - tableTail);
+    // Done with this table.
+    _currentVTable = null;
+    return tableTail;
+  }
+
+  /// This method low level method can be used to return a raw piece of the buffer
+  /// after using the the put* methods.
+  ///
+  /// Most clients should prefer calling [finish].
+  Uint8List lowFinish() {
+    int alignedTail = _tail + ((-_tail) % _maxAlign);
+    return _buf.buffer.asUint8List(_buf.lengthInBytes - alignedTail);
+  }
+
+  /// Finish off the creation of the buffer.  The given [offset] is used as the
+  /// root object offset, and usually references directly or indirectly every
+  /// written object.  If [fileIdentifier] is specified (and not `null`), it is
+  /// interpreted as a 4-byte Latin-1 encoded string that should be placed at
+  /// bytes 4-7 of the file.
+  Uint8List finish(int offset, [String fileIdentifier]) {
+    _prepare(max(_sizeofUint32, _maxAlign), fileIdentifier == null ? 1 : 2);
+    int alignedTail = _tail + ((-_tail) % _maxAlign);
+    _setUint32AtTail(_buf, alignedTail, alignedTail - offset);
+    if (fileIdentifier != null) {
+      for (int i = 0; i < 4; i++) {
+        _setUint8AtTail(_buf, alignedTail - _sizeofUint32 - i,
+            fileIdentifier.codeUnitAt(i));
+      }
+    }
+    return _buf.buffer.asUint8List(_buf.lengthInBytes - alignedTail);
+  }
+
+  /// Writes a Float64 to the tail of the buffer after preparing space for it.
+  ///
+  /// Updates the [offset] pointer.  This method is intended for use when writing structs to the buffer.
+  void putFloat64(double value) {
+    _prepare(_sizeofFloat64, 1);
+    _setFloat32AtTail(_buf, _tail, value);
+  }
+
+  /// Writes a Float32 to the tail of the buffer after preparing space for it.
+  ///
+  /// Updates the [offset] pointer.  This method is intended for use when writing structs to the buffer.
+  void putFloat32(double value) {
+    _prepare(_sizeofFloat32, 1);
+    _setFloat32AtTail(_buf, _tail, value);
+  }
+
+  /// Writes a Int64 to the tail of the buffer after preparing space for it.
+  ///
+  /// Updates the [offset] pointer.  This method is intended for use when writing structs to the buffer.
+  void putInt64(int value) {
+    _prepare(_sizeofInt64, 1);
+    _setInt64AtTail(_buf, _tail, value);
+  }
+
+  /// Writes a Uint32 to the tail of the buffer after preparing space for it.
+  ///
+  /// Updates the [offset] pointer.  This method is intended for use when writing structs to the buffer.
+  void putInt32(int value) {
+    _prepare(_sizeofInt32, 1);
+    _setInt32AtTail(_buf, _tail, value);
+  }
+
+  /// Writes a Uint16 to the tail of the buffer after preparing space for it.
+  ///
+  /// Updates the [offset] pointer.  This method is intended for use when writing structs to the buffer.
+  void putInt16(int value) {
+    _prepare(_sizeofInt16, 1);
+    _setInt16AtTail(_buf, _tail, value);
+  }
+
+  /// Writes a Uint8 to the tail of the buffer after preparing space for it.
+  ///
+  /// Updates the [offset] pointer.  This method is intended for use when writing structs to the buffer.
+  void putInt8(int value) {
+    _prepare(_sizeofInt8, 1);
+    _buf.setInt8(_buf.lengthInBytes - _tail, value);
+  }
+
+  /// Writes a Uint64 to the tail of the buffer after preparing space for it.
+  ///
+  /// Updates the [offset] pointer.  This method is intended for use when writing structs to the buffer.
+  void putUint64(int value) {
+    _prepare(_sizeofUint64, 1);
+    _setUint64AtTail(_buf, _tail, value);
+  }
+
+  /// Writes a Uint32 to the tail of the buffer after preparing space for it.
+  ///
+  /// Updates the [offset] pointer.  This method is intended for use when writing structs to the buffer.
+  void putUint32(int value) {
+    _prepare(_sizeofUint32, 1);
+    _setUint32AtTail(_buf, _tail, value);
+  }
+
+  /// Writes a Uint16 to the tail of the buffer after preparing space for it.
+  ///
+  /// Updates the [offset] pointer.  This method is intended for use when writing structs to the buffer.
+  void putUint16(int value) {
+    _prepare(_sizeofUint16, 1);
+    _setUint16AtTail(_buf, _tail, value);
+  }
+
+  /// Writes a Uint8 to the tail of the buffer after preparing space for it.
+  ///
+  /// Updates the [offset] pointer.  This method is intended for use when writing structs to the buffer.
+  void putUint8(int value) {
+    _prepare(_sizeofUint8, 1);
+    _buf.setUint8(_buf.lengthInBytes - _tail, value);
+  }
+
+  /// Reset the builder and make it ready for filling a new buffer.
+  void reset() {
+    _buf = new ByteData(initialSize);
+    _maxAlign = 1;
+    _tail = 0;
+    _currentVTable = null;
+    if (_strings != null) {
+      _strings = new Map<String, int>();
+    }
+  }
+
+  /// Start a new table.  Must be finished with [endTable] invocation.
+  void startTable() {
+    if (_currentVTable != null) {
+      throw new StateError('Inline tables are not supported.');
+    }
+    _currentVTable = new _VTable();
+    _currentTableEndTail = _tail;
+  }
+
+  /// Finish a Struct vector.  Most callers should preferto use [writeListOfStructs].
+  ///
+  /// Most callers should prefer [writeListOfStructs].
+  int endStructVector(int count) {
+    putUint32(count);
+    return _tail;
+  }
+
+  /// Writes a list of Structs to the buffer, returning the offset
+  int writeListOfStructs(List<ObjectBuilder> structBuilders) {
+    _ensureNoVTable();
+    for (int i = structBuilders.length - 1; i >= 0; i--) {
+      structBuilders[i].finish(this);
+    }
+    return endStructVector(structBuilders.length);
+  }
+
+  /// Write the given list of [values].
+  int writeList(List<int> values) {
+    _ensureNoVTable();
+    _prepare(_sizeofUint32, 1 + values.length);
+    final int result = _tail;
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= _sizeofUint32;
+    for (int value in values) {
+      _setUint32AtTail(_buf, tail, tail - value);
+      tail -= _sizeofUint32;
+    }
+    return result;
+  }
+
+  /// Write the given list of 64-bit float [values].
+  int writeListFloat64(List<double> values) {
+    _ensureNoVTable();
+    _prepare(4, 1 + (2 * values.length));
+    final int result = _tail;
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= _sizeofUint32;
+    for (double value in values) {
+      _setFloat64AtTail(_buf, tail, value);
+      tail -= _sizeofFloat64;
+    }
+    return result;
+  }
+
+  /// Write the given list of 32-bit float [values].
+  int writeListFloat32(List<double> values) {
+    _ensureNoVTable();
+    _prepare(_sizeofFloat32, 1 + values.length);
+    final int result = _tail;
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= _sizeofUint32;
+    for (double value in values) {
+      _setFloat32AtTail(_buf, tail, value);
+      tail -= _sizeofFloat32;
+    }
+    return result;
+  }
+
+  /// Write the given list of signed 64-bit integer [values].
+  int writeListInt64(List<int> values) {
+    _ensureNoVTable();
+    _prepare(_sizeofUint32, 2 * values.length);
+    final int result = _tail;
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= _sizeofUint32;
+    for (int value in values) {
+      _setInt64AtTail(_buf, tail, value);
+      tail -= _sizeofInt64;
+    }
+    return result;
+  }
+
+  /// Write the given list of signed 64-bit integer [values].
+  int writeListUint64(List<int> values) {
+    _ensureNoVTable();
+    _prepare(_sizeofUint32, 2 * values.length);
+    final int result = _tail;
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= _sizeofUint32;
+    for (int value in values) {
+      _setUint64AtTail(_buf, tail, value);
+      tail -= _sizeofUint64;
+    }
+    return result;
+  }
+
+  /// Write the given list of signed 32-bit integer [values].
+  int writeListInt32(List<int> values) {
+    _ensureNoVTable();
+    _prepare(_sizeofUint32, 1 + values.length);
+    final int result = _tail;
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= _sizeofUint32;
+    for (int value in values) {
+      _setInt32AtTail(_buf, tail, value);
+      tail -= _sizeofInt32;
+    }
+    return result;
+  }
+
+  /// Write the given list of unsigned 32-bit integer [values].
+  int writeListUint32(List<int> values) {
+    _ensureNoVTable();
+    _prepare(_sizeofUint32, 1 + values.length);
+    final int result = _tail;
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= _sizeofUint32;
+    for (int value in values) {
+      _setUint32AtTail(_buf, tail, value);
+      tail -= _sizeofUint32;
+    }
+    return result;
+  }
+
+  /// Write the given list of signed 16-bit integer [values].
+  int writeListInt16(List<int> values) {
+    _ensureNoVTable();
+    _prepare(_sizeofUint32, 1, additionalBytes: 2 * values.length);
+    final int result = _tail;
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= _sizeofUint32;
+    for (int value in values) {
+      _setInt16AtTail(_buf, tail, value);
+      tail -= _sizeofInt16;
+    }
+    return result;
+  }
+
+  /// Write the given list of unsigned 16-bit integer [values].
+  int writeListUint16(List<int> values) {
+    _ensureNoVTable();
+    _prepare(_sizeofUint32, 1, additionalBytes: 2 * values.length);
+    final int result = _tail;
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= _sizeofUint32;
+    for (int value in values) {
+      _setUint16AtTail(_buf, tail, value);
+      tail -= _sizeofUint16;
+    }
+    return result;
+  }
+
+  /// Write the given list of bools as unsigend 8-bit integer [values].
+  int writeListBool(List<bool> values) {
+    return writeListUint8(values?.map((b) => b ? 1 : 0)?.toList());
+  }
+
+  /// Write the given list of signed 8-bit integer [values].
+  int writeListInt8(List<int> values) {
+    _ensureNoVTable();
+    _prepare(_sizeofUint32, 1, additionalBytes: values.length);
+    final int result = _tail;
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= _sizeofUint32;
+    for (int value in values) {
+      _setInt8AtTail(_buf, tail, value);
+      tail -= _sizeofUint8;
+    }
+    return result;
+  }
+
+  /// Write the given list of unsigned 8-bit integer [values].
+  int writeListUint8(List<int> values) {
+    _ensureNoVTable();
+    _prepare(_sizeofUint32, 1, additionalBytes: values.length);
+    final int result = _tail;
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= _sizeofUint32;
+    for (int value in values) {
+      _setUint8AtTail(_buf, tail, value);
+      tail -= _sizeofUint8;
+    }
+    return result;
+  }
+
+  /// Write the given string [value] and return its offset, or `null` if
+  /// the [value] is `null`.
+  int writeString(String value) {
+    _ensureNoVTable();
+    if (value != null) {
+      if (_strings != null) {
+        return _strings.putIfAbsent(value, () => _writeString(value));
+      } else {
+        return _writeString(value);
+      }
+    }
+    return null;
+  }
+
+  int _writeString(String value) {
+    // TODO(scheglov) optimize for ASCII strings
+    List<int> bytes = utf8.encode(value);
+    int length = bytes.length;
+    _prepare(4, 1, additionalBytes: length + 1);
+    final int result = _tail;
+    _setUint32AtTail(_buf, _tail, length);
+    int offset = _buf.lengthInBytes - _tail + 4;
+    for (int i = 0; i < length; i++) {
+      _buf.setUint8(offset++, bytes[i]);
+    }
+    return result;
+  }
+
+  /// Throw an exception if there is not currently a vtable.
+  void _ensureCurrentVTable() {
+    if (_currentVTable == null) {
+      throw new StateError('Start a table before adding values.');
+    }
+  }
+
+  /// Throw an exception if there is currently a vtable.
+  void _ensureNoVTable() {
+    if (_currentVTable != null) {
+      throw new StateError(
+          'Cannot write a non-scalar value while writing a table.');
+    }
+  }
+
+  /// The number of bytes that have been written to the buffer so far.  The
+  /// most recently written byte is this many bytes from the end of the buffer.
+  int get offset => _tail;
+
+  /// Zero-pads the buffer, which may be required for some struct layouts.
+  void pad(int howManyBytes) {
+    for (int i = 0; i < howManyBytes; i++) putUint8(0);
+  }
+
+  /// Prepare for writing the given `count` of scalars of the given `size`.
+  /// Additionally allocate the specified `additionalBytes`. Update the current
+  /// tail pointer to point at the allocated space.
+  void _prepare(int size, int count, {int additionalBytes = 0}) {
+    // Update the alignment.
+    if (_maxAlign < size) {
+      _maxAlign = size;
+    }
+    // Prepare amount of required space.
+    int dataSize = size * count + additionalBytes;
+    int alignDelta = (-(_tail + dataSize)) % size;
+    int bufSize = alignDelta + dataSize;
+    // Ensure that we have the required amount of space.
+    {
+      int oldCapacity = _buf.lengthInBytes;
+      if (_tail + bufSize > oldCapacity) {
+        int desiredNewCapacity = (oldCapacity + bufSize) * 2;
+        int deltaCapacity = desiredNewCapacity - oldCapacity;
+        deltaCapacity += (-deltaCapacity) % _maxAlign;
+        int newCapacity = oldCapacity + deltaCapacity;
+        ByteData newBuf = new ByteData(newCapacity);
+        newBuf.buffer
+            .asUint8List()
+            .setAll(deltaCapacity, _buf.buffer.asUint8List());
+        _buf = newBuf;
+      }
+    }
+    // Update the tail pointer.
+    _tail += bufSize;
+  }
+
+  /// Record the offset of the given [field].
+  void _trackField(int field) {
+    _currentVTable.addField(field, _tail);
+  }
+
+  static void _setFloat64AtTail(ByteData _buf, int tail, double x) {
+    _buf.setFloat64(_buf.lengthInBytes - tail, x, Endian.little);
+  }
+
+  static void _setFloat32AtTail(ByteData _buf, int tail, double x) {
+    _buf.setFloat32(_buf.lengthInBytes - tail, x, Endian.little);
+  }
+
+  static void _setUint64AtTail(ByteData _buf, int tail, int x) {
+    _buf.setUint64(_buf.lengthInBytes - tail, x, Endian.little);
+  }
+
+  static void _setInt64AtTail(ByteData _buf, int tail, int x) {
+    _buf.setInt64(_buf.lengthInBytes - tail, x, Endian.little);
+  }
+
+  static void _setInt32AtTail(ByteData _buf, int tail, int x) {
+    _buf.setInt32(_buf.lengthInBytes - tail, x, Endian.little);
+  }
+
+  static void _setUint32AtTail(ByteData _buf, int tail, int x) {
+    _buf.setUint32(_buf.lengthInBytes - tail, x, Endian.little);
+  }
+
+  static void _setInt16AtTail(ByteData _buf, int tail, int x) {
+    _buf.setInt16(_buf.lengthInBytes - tail, x, Endian.little);
+  }
+
+  static void _setUint16AtTail(ByteData _buf, int tail, int x) {
+    _buf.setUint16(_buf.lengthInBytes - tail, x, Endian.little);
+  }
+
+  static void _setInt8AtTail(ByteData _buf, int tail, int x) {
+    _buf.setInt8(_buf.lengthInBytes - tail, x);
+  }
+
+  static void _setUint8AtTail(ByteData _buf, int tail, int x) {
+    _buf.setUint8(_buf.lengthInBytes - tail, x);
+  }
+}
+
+/// Reader of lists of boolean values.
+///
+/// The returned unmodifiable lists lazily read values on access.
+class BoolListReader extends Reader<List<bool>> {
+  const BoolListReader();
+
+  @override
+  int get size => _sizeofUint32;
+
+  @override
+  List<bool> read(BufferContext bc, int offset) =>
+      new _FbBoolList(bc, bc.derefObject(offset));
+}
+
+/// The reader of booleans.
+class BoolReader extends Reader<bool> {
+  const BoolReader() : super();
+
+  @override
+  int get size => _sizeofUint8;
+
+  @override
+  bool read(BufferContext bc, int offset) => bc._getInt8(offset) != 0;
+}
+
+/// The reader of lists of 64-bit float values.
+///
+/// The returned unmodifiable lists lazily read values on access.
+class Float64ListReader extends Reader<List<double>> {
+  const Float64ListReader();
+
+  @override
+  int get size => _sizeofFloat64;
+
+  @override
+  List<double> read(BufferContext bc, int offset) =>
+      new _FbFloat64List(bc, bc.derefObject(offset));
+}
+
+class Float32ListReader extends Reader<List<double>> {
+  const Float32ListReader();
+
+  @override
+  int get size => _sizeofFloat32;
+
+  @override
+  List<double> read(BufferContext bc, int offset) =>
+      new _FbFloat32List(bc, bc.derefObject(offset));
+}
+
+class Float64Reader extends Reader<double> {
+  const Float64Reader();
+
+  @override
+  int get size => _sizeofFloat64;
+
+  @override
+  double read(BufferContext bc, int offset) => bc._getFloat64(offset);
+}
+
+class Float32Reader extends Reader<double> {
+  const Float32Reader();
+
+  @override
+  int get size => _sizeofFloat32;
+
+  @override
+  double read(BufferContext bc, int offset) => bc._getFloat32(offset);
+}
+
+class Int64Reader extends Reader<int> {
+  const Int64Reader() : super();
+  @override
+  int get size => _sizeofInt64;
+
+  @override
+  int read(BufferContext bc, int offset) => bc._getInt64(offset);
+}
+
+/// The reader of signed 32-bit integers.
+class Int32Reader extends Reader<int> {
+  const Int32Reader() : super();
+
+  @override
+  int get size => _sizeofInt32;
+
+  @override
+  int read(BufferContext bc, int offset) => bc._getInt32(offset);
+}
+
+/// The reader of signed 32-bit integers.
+class Int16Reader extends Reader<int> {
+  const Int16Reader() : super();
+
+  @override
+  int get size => _sizeofInt16;
+
+  @override
+  int read(BufferContext bc, int offset) => bc._getInt16(offset);
+}
+
+/// The reader of 8-bit signed integers.
+class Int8Reader extends Reader<int> {
+  const Int8Reader() : super();
+
+  @override
+  int get size => _sizeofInt8;
+
+  @override
+  int read(BufferContext bc, int offset) => bc._getInt8(offset);
+}
+
+/// The reader of lists of objects.
+///
+/// The returned unmodifiable lists lazily read objects on access.
+class ListReader<E> extends Reader<List<E>> {
+  final Reader<E> _elementReader;
+
+  const ListReader(this._elementReader);
+
+  @override
+  int get size => _sizeofUint32;
+
+  @override
+  List<E> read(BufferContext bc, int offset) =>
+      new _FbGenericList<E>(_elementReader, bc, bc.derefObject(offset));
+}
+
+/// Object that can read a value at a [BufferContext].
+abstract class Reader<T> {
+  const Reader();
+
+  /// The size of the value in bytes.
+  int get size;
+
+  /// Read the value at the given [offset] in [bc].
+  T read(BufferContext bc, int offset);
+
+  /// Read the value of the given [field] in the given [object].
+  T vTableGet(BufferContext object, int offset, int field, [T defaultValue]) {
+    int vTableSOffset = object._getInt32(offset);
+    int vTableOffset = offset - vTableSOffset;
+    int vTableSize = object._getUint16(vTableOffset);
+    int vTableFieldOffset = field;
+    if (vTableFieldOffset < vTableSize) {
+      int fieldOffsetInObject =
+          object._getUint16(vTableOffset + vTableFieldOffset);
+      if (fieldOffsetInObject != 0) {
+        return read(object, offset + fieldOffsetInObject);
+      }
+    }
+    return defaultValue;
+  }
+}
+
+/// The reader of string values.
+class StringReader extends Reader<String> {
+  const StringReader() : super();
+
+  @override
+  int get size => 4;
+
+  @override
+  String read(BufferContext bc, int offset) {
+    int strOffset = bc.derefObject(offset);
+    int length = bc._getUint32(strOffset);
+    Uint8List bytes = bc._asUint8LIst(strOffset + 4, length);
+    if (_isLatin(bytes)) {
+      return new String.fromCharCodes(bytes);
+    }
+    return utf8.decode(bytes);
+  }
+
+  static bool _isLatin(Uint8List bytes) {
+    int length = bytes.length;
+    for (int i = 0; i < length; i++) {
+      if (bytes[i] > 127) {
+        return false;
+      }
+    }
+    return true;
+  }
+}
+
+/// An abstract reader for structs.
+abstract class StructReader<T> extends Reader<T> {
+  const StructReader();
+
+  /// Return the object at `offset`.
+  T createObject(BufferContext bc, int offset);
+
+  T read(BufferContext bp, int offset) {
+    return createObject(bp, offset);
+  }
+}
+
+/// An abstract reader for tables.
+abstract class TableReader<T> extends Reader<T> {
+  const TableReader();
+
+  @override
+  int get size => 4;
+
+  /// Return the object at [offset].
+  T createObject(BufferContext bc, int offset);
+
+  @override
+  T read(BufferContext bp, int offset) {
+    int objectOffset = bp.derefObject(offset);
+    return createObject(bp, objectOffset);
+  }
+}
+
+/// Reader of lists of unsigned 32-bit integer values.
+///
+/// The returned unmodifiable lists lazily read values on access.
+class Uint32ListReader extends Reader<List<int>> {
+  const Uint32ListReader();
+
+  @override
+  int get size => _sizeofUint32;
+
+  @override
+  List<int> read(BufferContext bc, int offset) =>
+      new _FbUint32List(bc, bc.derefObject(offset));
+}
+
+/// The reader of unsigned 64-bit integers.
+///
+/// WARNING: May have compatibility issues with JavaScript
+class Uint64Reader extends Reader<int> {
+  const Uint64Reader() : super();
+
+  @override
+  int get size => _sizeofUint64;
+
+  @override
+  int read(BufferContext bc, int offset) => bc._getUint64(offset);
+}
+
+/// The reader of unsigned 32-bit integers.
+class Uint32Reader extends Reader<int> {
+  const Uint32Reader() : super();
+
+  @override
+  int get size => _sizeofUint32;
+
+  @override
+  int read(BufferContext bc, int offset) => bc._getUint32(offset);
+}
+
+/// Reader of lists of unsigned 32-bit integer values.
+///
+/// The returned unmodifiable lists lazily read values on access.
+class Uint16ListReader extends Reader<List<int>> {
+  const Uint16ListReader();
+
+  @override
+  int get size => _sizeofUint32;
+
+  @override
+  List<int> read(BufferContext bc, int offset) =>
+      new _FbUint16List(bc, bc.derefObject(offset));
+}
+
+/// The reader of unsigned 32-bit integers.
+class Uint16Reader extends Reader<int> {
+  const Uint16Reader() : super();
+
+  @override
+  int get size => _sizeofUint16;
+
+  @override
+  int read(BufferContext bc, int offset) => bc._getUint16(offset);
+}
+
+/// Reader of lists of unsigned 8-bit integer values.
+///
+/// The returned unmodifiable lists lazily read values on access.
+class Uint8ListReader extends Reader<List<int>> {
+  const Uint8ListReader();
+
+  @override
+  int get size => _sizeofUint32;
+
+  @override
+  List<int> read(BufferContext bc, int offset) =>
+      new _FbUint8List(bc, bc.derefObject(offset));
+}
+
+/// The reader of unsigned 8-bit integers.
+class Uint8Reader extends Reader<int> {
+  const Uint8Reader() : super();
+
+  @override
+  int get size => _sizeofUint8;
+
+  @override
+  int read(BufferContext bc, int offset) => bc._getUint8(offset);
+}
+
+/// The list backed by 64-bit values - Uint64 length and Float64.
+class _FbFloat64List extends _FbList<double> {
+  _FbFloat64List(BufferContext bc, int offset) : super(bc, offset);
+
+  @override
+  double operator [](int i) {
+    return bc._getFloat64(offset + 4 + 8 * i);
+  }
+}
+
+/// The list backed by 32-bit values - Float32.
+class _FbFloat32List extends _FbList<double> {
+  _FbFloat32List(BufferContext bc, int offset) : super(bc, offset);
+
+  @override
+  double operator [](int i) {
+    return bc._getFloat32(offset + 4 + 4 * i);
+  }
+}
+
+/// List backed by a generic object which may have any size.
+class _FbGenericList<E> extends _FbList<E> {
+  final Reader<E> elementReader;
+
+  List<E> _items;
+
+  _FbGenericList(this.elementReader, BufferContext bp, int offset)
+      : super(bp, offset);
+
+  @override
+  E operator [](int i) {
+    _items ??= new List<E>(length);
+    E item = _items[i];
+    if (item == null) {
+      item = elementReader.read(bc, offset + 4 + elementReader.size * i);
+      _items[i] = item;
+    }
+    return item;
+  }
+}
+
+/// The base class for immutable lists read from flat buffers.
+abstract class _FbList<E> extends Object with ListMixin<E> implements List<E> {
+  final BufferContext bc;
+  final int offset;
+  int _length;
+
+  _FbList(this.bc, this.offset);
+
+  @override
+  int get length {
+    _length ??= bc._getUint32(offset);
+    return _length;
+  }
+
+  @override
+  void set length(int i) =>
+      throw new StateError('Attempt to modify immutable list');
+
+  @override
+  void operator []=(int i, E e) =>
+      throw new StateError('Attempt to modify immutable list');
+}
+
+/// List backed by 32-bit unsigned integers.
+class _FbUint32List extends _FbList<int> {
+  _FbUint32List(BufferContext bc, int offset) : super(bc, offset);
+
+  @override
+  int operator [](int i) {
+    return bc._getUint32(offset + 4 + 4 * i);
+  }
+}
+
+/// List backed by 16-bit unsigned integers.
+class _FbUint16List extends _FbList<int> {
+  _FbUint16List(BufferContext bc, int offset) : super(bc, offset);
+
+  @override
+  int operator [](int i) {
+    return bc._getUint16(offset + 4 + 2 * i);
+  }
+}
+
+/// List backed by 8-bit unsigned integers.
+class _FbUint8List extends _FbList<int> {
+  _FbUint8List(BufferContext bc, int offset) : super(bc, offset);
+
+  @override
+  int operator [](int i) {
+    return bc._getUint8(offset + 4 + i);
+  }
+}
+
+/// List backed by 8-bit unsigned integers.
+class _FbBoolList extends _FbList<bool> {
+  _FbBoolList(BufferContext bc, int offset) : super(bc, offset);
+
+  @override
+  bool operator [](int i) {
+    return bc._getUint8(offset + 4 + i) == 1 ? true : false;
+  }
+}
+
+/// Class that describes the structure of a table.
+class _VTable {
+  static const int _metadataLength = 4;
+
+  final List<int> fieldTails = <int>[];
+  final List<int> fieldOffsets = <int>[];
+
+  /// The size of the table that uses this VTable.
+  int tableSize;
+
+  /// The tail of this VTable.  It is used to share the same VTable between
+  /// multiple tables of identical structure.
+  int tail;
+
+  int get _vTableSize => numOfUint16 * _sizeofUint16;
+
+  int get numOfUint16 => 1 + 1 + fieldTails.length;
+
+  void addField(int field, int offset) {
+    while (fieldTails.length <= field) {
+      fieldTails.add(null);
+    }
+    fieldTails[field] = offset;
+  }
+
+  bool _offsetsMatch(int vt2Start, ByteData buf) {
+    for (int i = 0; i < fieldOffsets.length; i++) {
+      if (fieldOffsets[i] !=
+          buf.getUint16(
+              vt2Start + _metadataLength + (2 * i), Endian.little)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /// Fill the [fieldOffsets] field.
+  void computeFieldOffsets(int tableTail) {
+    assert(fieldOffsets.isEmpty);
+    for (int fieldTail in fieldTails) {
+      int fieldOffset = fieldTail == null ? 0 : tableTail - fieldTail;
+      fieldOffsets.add(fieldOffset);
+    }
+  }
+
+  /// Outputs this VTable to [buf], which is is expected to be aligned to 16-bit
+  /// and have at least [numOfUint16] 16-bit words available.
+  void output(ByteData buf, int bufOffset) {
+    // VTable size.
+    buf.setUint16(bufOffset, numOfUint16 * 2, Endian.little);
+    bufOffset += 2;
+    // Table size.
+    buf.setUint16(bufOffset, tableSize, Endian.little);
+    bufOffset += 2;
+    // Field offsets.
+    for (int fieldOffset in fieldOffsets) {
+      buf.setUint16(bufOffset, fieldOffset, Endian.little);
+      bufOffset += 2;
+    }
+  }
+}
diff --git a/third_party/flatbuffers/dart/publish.sh b/third_party/flatbuffers/dart/publish.sh
new file mode 100755
index 0000000..167a4a3
--- /dev/null
+++ b/third_party/flatbuffers/dart/publish.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# 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.
+#
+# Note to pub consumers: this file is used to assist with publishing the
+# pub package from the flatbuffers repository and is not meant for general use.
+# As pub does not currently provide a way to exclude files, it is included here.
+
+command -v pub >/dev/null 2>&1 || { echo >&2 "Require `pub` but it's not installed.  Aborting."; exit 1; }
+
+cp ../samples/monster.fbs example/
+cp ../tests/monster_test.fbs test/
+pub publish
+
+rm example/monster.fbs
+rm test/monster_test.fbs
\ No newline at end of file
diff --git a/third_party/flatbuffers/dart/pubspec.yaml b/third_party/flatbuffers/dart/pubspec.yaml
new file mode 100644
index 0000000..4761ffc
--- /dev/null
+++ b/third_party/flatbuffers/dart/pubspec.yaml
@@ -0,0 +1,20 @@
+name: flat_buffers
+version: 1.11.0
+description: >
+  FlatBuffers reading and writing library for Dart.  Use the flatc compiler to
+  generate Dart classes for a FlatBuffers schema, and this library to assist with
+  reading and writing the binary format.
+
+  Based on original work by Konstantin Scheglov and Paul Berry of the Dart SDK team.
+authors:
+- Dan Field <dfield@gmail.com>
+- Konstantin Scheglov
+- Paul Berry
+homepage: https://github.com/google/flatbuffers
+documentation: https://google.github.io/flatbuffers/index.html
+dev_dependencies:
+  test: ^1.3.0
+  test_reflective_loader: ^0.1.4
+  path: ^1.5.1
+environment:
+  sdk: '>=2.0.0-dev.28.0 <3.0.0'
\ No newline at end of file
diff --git a/third_party/flatbuffers/dart/test/flat_buffers_test.dart b/third_party/flatbuffers/dart/test/flat_buffers_test.dart
new file mode 100644
index 0000000..f9c5e01
--- /dev/null
+++ b/third_party/flatbuffers/dart/test/flat_buffers_test.dart
@@ -0,0 +1,573 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:typed_data';
+import 'dart:io' as io;
+
+import 'package:path/path.dart' as path;
+
+import 'package:flat_buffers/flat_buffers.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import './monster_test_my_game.example_generated.dart' as example;
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(BuilderTest);
+    defineReflectiveTests(CheckOtherLangaugesData);
+  });
+}
+
+int indexToField(int index) {
+  return (1 + 1 + index) * 2;
+}
+
+@reflectiveTest
+class CheckOtherLangaugesData {
+  test_cppData() async {
+    List<int> data = await new io.File(path.join(
+      path.dirname(io.Platform.script.path),
+      'monsterdata_test.mon',
+    ))
+        .readAsBytes();
+    example.Monster mon = new example.Monster(data);
+    expect(mon.hp, 80);
+    expect(mon.mana, 150);
+    expect(mon.name, 'MyMonster');
+    expect(mon.pos.x, 1.0);
+    expect(mon.pos.y, 2.0);
+    expect(mon.pos.z, 3.0);
+    expect(mon.pos.test1, 3.0);
+    expect(mon.pos.test2.value, 2.0);
+    expect(mon.pos.test3.a, 5);
+    expect(mon.pos.test3.b, 6);
+    expect(mon.testType.value, example.AnyTypeId.Monster.value);
+    expect(mon.test is example.Monster, true);
+    final monster2 = mon.test as example.Monster;
+    expect(monster2.name, "Fred");
+
+    expect(mon.inventory.length, 5);
+    expect(mon.inventory.reduce((cur, next) => cur + next), 10);
+    expect(mon.test4.length, 2);
+    expect(
+        mon.test4[0].a + mon.test4[0].b + mon.test4[1].a + mon.test4[1].b, 100);
+    expect(mon.testarrayofstring.length, 2);
+    expect(mon.testarrayofstring[0], "test1");
+    expect(mon.testarrayofstring[1], "test2");
+
+    // this will fail if accessing any field fails.
+    expect(mon.toString(),
+        'Monster{pos: Vec3{x: 1.0, y: 2.0, z: 3.0, test1: 3.0, test2: Color{value: 2}, test3: Test{a: 5, b: 6}}, mana: 150, hp: 80, name: MyMonster, inventory: [0, 1, 2, 3, 4], color: Color{value: 8}, testType: AnyTypeId{value: 1}, test: Monster{pos: null, mana: 150, hp: 100, name: Fred, inventory: null, color: Color{value: 8}, testType: AnyTypeId{value: 0}, test: null, test4: null, testarrayofstring: null, testarrayoftables: null, enemy: null, testnestedflatbuffer: null, testempty: null, testbool: false, testhashs32Fnv1: 0, testhashu32Fnv1: 0, testhashs64Fnv1: 0, testhashu64Fnv1: 0, testhashs32Fnv1a: 0, testhashu32Fnv1a: 0, testhashs64Fnv1a: 0, testhashu64Fnv1a: 0, testarrayofbools: null, testf: 3.14159, testf2: 3.0, testf3: 0.0, testarrayofstring2: null, testarrayofsortedstruct: null, flex: null, test5: null, vectorOfLongs: null, vectorOfDoubles: null, parentNamespaceTest: null, vectorOfReferrables: null, singleWeakReference: 0, vectorOfWeakReferences: null, vectorOfStrongReferrables: null, coOwningReference: 0, vectorOfCoOwningReferences: null, nonOwningReference: 0, vectorOfNonOwningReferences: null}, test4: [Test{a: 10, b: 20}, Test{a: 30, b: 40}], testarrayofstring: [test1, test2], testarrayoftables: null, enemy: Monster{pos: null, mana: 150, hp: 100, name: Fred, inventory: null, color: Color{value: 8}, testType: AnyTypeId{value: 0}, test: null, test4: null, testarrayofstring: null, testarrayoftables: null, enemy: null, testnestedflatbuffer: null, testempty: null, testbool: false, testhashs32Fnv1: 0, testhashu32Fnv1: 0, testhashs64Fnv1: 0, testhashu64Fnv1: 0, testhashs32Fnv1a: 0, testhashu32Fnv1a: 0, testhashs64Fnv1a: 0, testhashu64Fnv1a: 0, testarrayofbools: null, testf: 3.14159, testf2: 3.0, testf3: 0.0, testarrayofstring2: null, testarrayofsortedstruct: null, flex: null, test5: null, vectorOfLongs: null, vectorOfDoubles: null, parentNamespaceTest: null, vectorOfReferrables: null, singleWeakReference: 0, vectorOfWeakReferences: null, vectorOfStrongReferrables: null, coOwningReference: 0, vectorOfCoOwningReferences: null, nonOwningReference: 0, vectorOfNonOwningReferences: null}, testnestedflatbuffer: null, testempty: null, testbool: false, testhashs32Fnv1: -579221183, testhashu32Fnv1: 3715746113, testhashs64Fnv1: 7930699090847568257, testhashu64Fnv1: 7930699090847568257, testhashs32Fnv1a: -1904106383, testhashu32Fnv1a: 2390860913, testhashs64Fnv1a: 4898026182817603057, testhashu64Fnv1a: 4898026182817603057, testarrayofbools: [true, false, true], testf: 3.14159, testf2: 3.0, testf3: 0.0, testarrayofstring2: null, testarrayofsortedstruct: null, flex: null, test5: [Test{a: 10, b: 20}, Test{a: 30, b: 40}], vectorOfLongs: [1, 100, 10000, 1000000, 100000000], vectorOfDoubles: [-1.7976931348623157e+308, 0.0, 1.7976931348623157e+308], parentNamespaceTest: null, vectorOfReferrables: null, singleWeakReference: 0, vectorOfWeakReferences: null, vectorOfStrongReferrables: null, coOwningReference: 0, vectorOfCoOwningReferences: null, nonOwningReference: 0, vectorOfNonOwningReferences: null}');
+  }
+}
+
+@reflectiveTest
+class BuilderTest {
+  void test_monsterBuilder() {
+    final fbBuilder = new Builder();
+    final str = fbBuilder.writeString('MyMonster');
+
+    fbBuilder.writeString('test1');
+    fbBuilder.writeString('test2');
+    final testArrayOfString = fbBuilder.endStructVector(2);
+
+    final fred = fbBuilder.writeString('Fred');
+
+    final List<int> treasure = [0, 1, 2, 3, 4];
+    final inventory = fbBuilder.writeListUint8(treasure);
+
+    final monBuilder = new example.MonsterBuilder(fbBuilder)
+      ..begin()
+      ..addNameOffset(fred);
+    final mon2 = monBuilder.finish();
+
+    final testBuilder = new example.TestBuilder(fbBuilder);
+    testBuilder.finish(10, 20);
+    testBuilder.finish(30, 40);
+    final test4 = fbBuilder.endStructVector(2);
+
+
+    monBuilder
+      ..begin()
+      ..addPos(
+        new example.Vec3Builder(fbBuilder).finish(
+          1.0,
+          2.0,
+          3.0,
+          3.0,
+          example.Color.Green,
+          () => testBuilder.finish(5, 6),
+        ),
+      )
+      ..addHp(80)
+      ..addNameOffset(str)
+      ..addInventoryOffset(inventory)
+      ..addTestType(example.AnyTypeId.Monster)
+      ..addTestOffset(mon2)
+      ..addTest4Offset(test4)
+      ..addTestarrayofstringOffset(testArrayOfString);
+    final mon = monBuilder.finish();
+    fbBuilder.finish(mon);
+  }
+
+  void test_error_addInt32_withoutStartTable() {
+    Builder builder = new Builder();
+    expect(() {
+      builder.addInt32(0, 0);
+    }, throwsStateError);
+  }
+
+  void test_error_addOffset_withoutStartTable() {
+    Builder builder = new Builder();
+    expect(() {
+      builder.addOffset(0, 0);
+    }, throwsStateError);
+  }
+
+  void test_error_endTable_withoutStartTable() {
+    Builder builder = new Builder();
+    expect(() {
+      builder.endTable();
+    }, throwsStateError);
+  }
+
+  void test_error_startTable_duringTable() {
+    Builder builder = new Builder();
+    builder.startTable();
+    expect(() {
+      builder.startTable();
+    }, throwsStateError);
+  }
+
+  void test_error_writeString_duringTable() {
+    Builder builder = new Builder();
+    builder.startTable();
+    expect(() {
+      builder.writeString('12345');
+    }, throwsStateError);
+  }
+
+  void test_file_identifier() {
+    Uint8List byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      builder.startTable();
+      int offset = builder.endTable();
+      byteList = builder.finish(offset, 'Az~ÿ');
+    }
+    // Convert byteList to a ByteData so that we can read data from it.
+    ByteData byteData = byteList.buffer.asByteData(byteList.offsetInBytes);
+    // First 4 bytes are an offset to the table data.
+    int tableDataLoc = byteData.getUint32(0, Endian.little);
+    // Next 4 bytes are the file identifier.
+    expect(byteData.getUint8(4), 65); // 'a'
+    expect(byteData.getUint8(5), 122); // 'z'
+    expect(byteData.getUint8(6), 126); // '~'
+    expect(byteData.getUint8(7), 255); // 'ÿ'
+    // First 4 bytes of the table data are a backwards offset to the vtable.
+    int vTableLoc = tableDataLoc -
+        byteData.getInt32(tableDataLoc, Endian.little);
+    // First 2 bytes of the vtable are the size of the vtable in bytes, which
+    // should be 4.
+    expect(byteData.getUint16(vTableLoc, Endian.little), 4);
+    // Next 2 bytes are the size of the object in bytes (including the vtable
+    // pointer), which should be 4.
+    expect(byteData.getUint16(vTableLoc + 2, Endian.little), 4);
+  }
+
+  void test_low() {
+    Builder builder = new Builder(initialSize: 0);
+    expect((builder..putUint8(1)).lowFinish(), [1]);
+    expect((builder..putUint32(2)).lowFinish(), [2, 0, 0, 0, 0, 0, 0, 1]);
+    expect((builder..putUint8(3)).lowFinish(),
+        [0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 1]);
+    expect((builder..putUint8(4)).lowFinish(),
+        [0, 0, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]);
+    expect((builder..putUint8(5)).lowFinish(),
+        [0, 5, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]);
+    expect((builder..putUint32(6)).lowFinish(),
+        [6, 0, 0, 0, 0, 5, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]);
+  }
+
+  void test_table_default() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      builder.startTable();
+      builder.addInt32(0, 10, 10);
+      builder.addInt32(1, 20, 10);
+      int offset = builder.endTable();
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferContext buffer = new BufferContext.fromBytes(byteList);
+    int objectOffset = buffer.derefObject(0);
+    // was not written, so uses the new default value
+    expect(
+        const Int32Reader()
+            .vTableGet(buffer, objectOffset, indexToField(0), 15),
+        15);
+    // has the written value
+    expect(
+        const Int32Reader()
+            .vTableGet(buffer, objectOffset, indexToField(1), 15),
+        20);
+  }
+
+  void test_table_format() {
+    Uint8List byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      builder.startTable();
+      builder.addInt32(0, 10);
+      builder.addInt32(1, 20);
+      builder.addInt32(2, 30);
+      byteList = builder.finish(builder.endTable());
+    }
+    // Convert byteList to a ByteData so that we can read data from it.
+    ByteData byteData = byteList.buffer.asByteData(byteList.offsetInBytes);
+    // First 4 bytes are an offset to the table data.
+    int tableDataLoc = byteData.getUint32(0, Endian.little);
+    // First 4 bytes of the table data are a backwards offset to the vtable.
+    int vTableLoc = tableDataLoc -
+        byteData.getInt32(tableDataLoc, Endian.little);
+    // First 2 bytes of the vtable are the size of the vtable in bytes, which
+    // should be 10.
+    expect(byteData.getUint16(vTableLoc, Endian.little), 10);
+    // Next 2 bytes are the size of the object in bytes (including the vtable
+    // pointer), which should be 16.
+    expect(byteData.getUint16(vTableLoc + 2, Endian.little), 16);
+    // Remaining 6 bytes are the offsets within the object where the ints are
+    // located.
+    for (int i = 0; i < 3; i++) {
+      int offset =
+          byteData.getUint16(vTableLoc + 4 + 2 * i, Endian.little);
+      expect(byteData.getInt32(tableDataLoc + offset, Endian.little),
+          10 + 10 * i);
+    }
+  }
+
+  void test_table_string() {
+    String latinString = 'test';
+    String unicodeString = 'Проба пера';
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      int latinStringOffset = builder.writeString(latinString);
+      int unicodeStringOffset = builder.writeString(unicodeString);
+      builder.startTable();
+      builder.addOffset(0, latinStringOffset);
+      builder.addOffset(1, unicodeStringOffset);
+      int offset = builder.endTable();
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    int objectOffset = buf.derefObject(0);
+    expect(const StringReader().vTableGet(buf, objectOffset, indexToField(0)),
+        latinString);
+    expect(const StringReader().vTableGet(buf, objectOffset, indexToField(1)),
+        unicodeString);
+  }
+
+  void test_table_types() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      int stringOffset = builder.writeString('12345');
+      builder.startTable();
+      builder.addBool(0, true);
+      builder.addInt8(1, 10);
+      builder.addInt32(2, 20);
+      builder.addOffset(3, stringOffset);
+      builder.addInt32(4, 40);
+      builder.addUint32(5, 0x9ABCDEF0);
+      builder.addUint8(6, 0x9A);
+      int offset = builder.endTable();
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    int objectOffset = buf.derefObject(0);
+    expect(
+        const BoolReader().vTableGet(buf, objectOffset, indexToField(0)), true);
+    expect(
+        const Int8Reader().vTableGet(buf, objectOffset, indexToField(1)), 10);
+    expect(
+        const Int32Reader().vTableGet(buf, objectOffset, indexToField(2)), 20);
+    expect(const StringReader().vTableGet(buf, objectOffset, indexToField(3)),
+        '12345');
+    expect(
+        const Int32Reader().vTableGet(buf, objectOffset, indexToField(4)), 40);
+    expect(const Uint32Reader().vTableGet(buf, objectOffset, indexToField(5)),
+        0x9ABCDEF0);
+    expect(const Uint8Reader().vTableGet(buf, objectOffset, indexToField(6)),
+        0x9A);
+  }
+
+  void test_writeList_of_Uint32() {
+    List<int> values = <int>[10, 100, 12345, 0x9abcdef0];
+    // write
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      int offset = builder.writeListUint32(values);
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    List<int> items = const Uint32ListReader().read(buf, 0);
+    expect(items, hasLength(4));
+    expect(items, orderedEquals(values));
+  }
+
+  void test_writeList_ofBool() {
+    void verifyListBooleans(int len, List<int> trueBits) {
+      // write
+      List<int> byteList;
+      {
+        Builder builder = new Builder(initialSize: 0);
+        List<bool> values = new List<bool>.filled(len, false);
+        for (int bit in trueBits) {
+          values[bit] = true;
+        }
+        int offset = builder.writeListBool(values);
+        byteList = builder.finish(offset);
+      }
+      // read and verify
+      BufferContext buf = new BufferContext.fromBytes(byteList);
+      List<bool> items = const BoolListReader().read(buf, 0);
+      expect(items, hasLength(len));
+      for (int i = 0; i < items.length; i++) {
+        expect(items[i], trueBits.contains(i), reason: 'bit $i of $len');
+      }
+    }
+
+    verifyListBooleans(0, <int>[]);
+    verifyListBooleans(1, <int>[]);
+    verifyListBooleans(1, <int>[0]);
+    verifyListBooleans(31, <int>[0, 1]);
+    verifyListBooleans(31, <int>[1, 2, 24, 25, 30]);
+    verifyListBooleans(31, <int>[0, 30]);
+    verifyListBooleans(32, <int>[1, 2, 24, 25, 31]);
+    verifyListBooleans(33, <int>[1, 2, 24, 25, 32]);
+    verifyListBooleans(33, <int>[1, 2, 24, 25, 31, 32]);
+    verifyListBooleans(63, <int>[]);
+    verifyListBooleans(63, <int>[0, 1, 2, 61, 62]);
+    verifyListBooleans(63, new List<int>.generate(63, (i) => i));
+    verifyListBooleans(64, <int>[]);
+    verifyListBooleans(64, <int>[0, 1, 2, 61, 62, 63]);
+    verifyListBooleans(64, <int>[1, 2, 62]);
+    verifyListBooleans(64, <int>[0, 1, 2, 63]);
+    verifyListBooleans(64, new List<int>.generate(64, (i) => i));
+    verifyListBooleans(100, <int>[0, 3, 30, 60, 90, 99]);
+  }
+
+  void test_writeList_ofInt32() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      int offset = builder.writeListInt32(<int>[1, 2, 3, 4, 5]);
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    List<int> items = const ListReader<int>(const Int32Reader()).read(buf, 0);
+    expect(items, hasLength(5));
+    expect(items, orderedEquals(<int>[1, 2, 3, 4, 5]));
+  }
+
+  void test_writeList_ofFloat64() {
+    List<double> values = <double>[-1.234567, 3.4E+9, -5.6E-13, 7.8, 12.13];
+    // write
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      int offset = builder.writeListFloat64(values);
+      byteList = builder.finish(offset);
+    }
+
+    // read and verify
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    List<double> items = const Float64ListReader().read(buf, 0);
+
+    expect(items, hasLength(values.length));
+    for (int i = 0; i < values.length; i++) {
+      expect(values[i], closeTo(items[i], .001));
+    }
+  }
+
+  void test_writeList_ofFloat32() {
+    List<double> values = [1.0, 2.23, -3.213, 7.8, 12.13];
+    // write
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      int offset = builder.writeListFloat32(values);
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    List<double> items = const Float32ListReader().read(buf, 0);
+    expect(items, hasLength(5));
+    for (int i = 0; i < values.length; i++) {
+      expect(values[i], closeTo(items[i], .001));
+    }
+  }
+
+  void test_writeList_ofObjects() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      // write the object #1
+      int object1;
+      {
+        builder.startTable();
+        builder.addInt32(0, 10);
+        builder.addInt32(1, 20);
+        object1 = builder.endTable();
+      }
+      // write the object #1
+      int object2;
+      {
+        builder.startTable();
+        builder.addInt32(0, 100);
+        builder.addInt32(1, 200);
+        object2 = builder.endTable();
+      }
+      // write the list
+      int offset = builder.writeList([object1, object2]);
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    List<TestPointImpl> items =
+        const ListReader<TestPointImpl>(const TestPointReader()).read(buf, 0);
+    expect(items, hasLength(2));
+    expect(items[0].x, 10);
+    expect(items[0].y, 20);
+    expect(items[1].x, 100);
+    expect(items[1].y, 200);
+  }
+
+  void test_writeList_ofStrings_asRoot() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      int str1 = builder.writeString('12345');
+      int str2 = builder.writeString('ABC');
+      int offset = builder.writeList([str1, str2]);
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    List<String> items =
+        const ListReader<String>(const StringReader()).read(buf, 0);
+    expect(items, hasLength(2));
+    expect(items, contains('12345'));
+    expect(items, contains('ABC'));
+  }
+
+  void test_writeList_ofStrings_inObject() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      int listOffset = builder.writeList(
+          [builder.writeString('12345'), builder.writeString('ABC')]);
+      builder.startTable();
+      builder.addOffset(0, listOffset);
+      int offset = builder.endTable();
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    StringListWrapperImpl reader = new StringListWrapperReader().read(buf, 0);
+    List<String> items = reader.items;
+    expect(items, hasLength(2));
+    expect(items, contains('12345'));
+    expect(items, contains('ABC'));
+  }
+
+  void test_writeList_ofUint32() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      int offset = builder.writeListUint32(<int>[1, 2, 0x9ABCDEF0]);
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    List<int> items = const Uint32ListReader().read(buf, 0);
+    expect(items, hasLength(3));
+    expect(items, orderedEquals(<int>[1, 2, 0x9ABCDEF0]));
+  }
+
+  void test_writeList_ofUint16() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      int offset = builder.writeListUint16(<int>[1, 2, 60000]);
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    List<int> items = const Uint16ListReader().read(buf, 0);
+    expect(items, hasLength(3));
+    expect(items, orderedEquals(<int>[1, 2, 60000]));
+  }
+
+  void test_writeList_ofUint8() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      int offset = builder.writeListUint8(<int>[1, 2, 3, 4, 0x9A]);
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    List<int> items = const Uint8ListReader().read(buf, 0);
+    expect(items, hasLength(5));
+    expect(items, orderedEquals(<int>[1, 2, 3, 4, 0x9A]));
+  }
+}
+
+class StringListWrapperImpl {
+  final BufferContext bp;
+  final int offset;
+
+  StringListWrapperImpl(this.bp, this.offset);
+
+  List<String> get items => const ListReader<String>(const StringReader())
+      .vTableGet(bp, offset, indexToField(0));
+}
+
+class StringListWrapperReader extends TableReader<StringListWrapperImpl> {
+  const StringListWrapperReader();
+
+  @override
+  StringListWrapperImpl createObject(BufferContext object, int offset) {
+    return new StringListWrapperImpl(object, offset);
+  }
+}
+
+class TestPointImpl {
+  final BufferContext bp;
+  final int offset;
+
+  TestPointImpl(this.bp, this.offset);
+
+  int get x => const Int32Reader().vTableGet(bp, offset, indexToField(0), 0);
+
+  int get y => const Int32Reader().vTableGet(bp, offset, indexToField(1), 0);
+}
+
+class TestPointReader extends TableReader<TestPointImpl> {
+  const TestPointReader();
+
+  @override
+  TestPointImpl createObject(BufferContext object, int offset) {
+    return new TestPointImpl(object, offset);
+  }
+}
diff --git a/third_party/flatbuffers/dart/test/monster_test_my_game.example2_generated.dart b/third_party/flatbuffers/dart/test/monster_test_my_game.example2_generated.dart
new file mode 100644
index 0000000..9a3ab66
--- /dev/null
+++ b/third_party/flatbuffers/dart/test/monster_test_my_game.example2_generated.dart
@@ -0,0 +1,62 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+// ignore_for_file: unused_import, unused_field, unused_local_variable
+
+library my_game.example2;
+
+import 'dart:typed_data' show Uint8List;
+import 'package:flat_buffers/flat_buffers.dart' as fb;
+
+import 'include_test1_my_game.example2_generated.dart';
+import 'include_test2_my_game.example2_generated.dart';
+import './monster_test_my_game_generated.dart' as my_game;
+import './monster_test_my_game.example_generated.dart' as my_game_example;
+
+class Monster {
+  Monster._(this._bc, this._bcOffset);
+  factory Monster(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<Monster> reader = const _MonsterReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+
+  @override
+  String toString() {
+    return 'Monster{}';
+  }
+}
+
+class _MonsterReader extends fb.TableReader<Monster> {
+  const _MonsterReader();
+
+  @override
+  Monster createObject(fb.BufferContext bc, int offset) => 
+    new Monster._(bc, offset);
+}
+
+class MonsterObjectBuilder extends fb.ObjectBuilder {
+
+  MonsterObjectBuilder();
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+
+    fbBuilder.startTable();
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
diff --git a/third_party/flatbuffers/dart/test/monster_test_my_game.example_generated.dart b/third_party/flatbuffers/dart/test/monster_test_my_game.example_generated.dart
new file mode 100644
index 0000000..49e2ec1
--- /dev/null
+++ b/third_party/flatbuffers/dart/test/monster_test_my_game.example_generated.dart
@@ -0,0 +1,1486 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+// ignore_for_file: unused_import, unused_field, unused_local_variable
+
+library my_game.example;
+
+import 'dart:typed_data' show Uint8List;
+import 'package:flat_buffers/flat_buffers.dart' as fb;
+
+import 'include_test1_my_game.example_generated.dart';
+import 'include_test2_my_game.example_generated.dart';
+import './monster_test_my_game_generated.dart' as my_game;
+import './monster_test_my_game.example2_generated.dart' as my_game_example2;
+
+class Color {
+  final int value;
+  const Color._(this.value);
+
+  factory Color.fromValue(int value) {
+    if (value == null) value = 0;
+    if (!values.containsKey(value)) {
+      throw new StateError('Invalid value $value for bit flag enum Color');
+    }
+    return values[value];
+  }
+
+  static bool containsValue(int value) => values.containsKey(value);
+
+  static const Color Red = const Color._(1);
+  static const Color Green = const Color._(2);
+  static const Color Blue = const Color._(8);
+  static get values => {1: Red,2: Green,8: Blue,};
+
+  static const fb.Reader<Color> reader = const _ColorReader();
+
+  @override
+  String toString() {
+    return 'Color{value: $value}';
+  }
+}
+
+class _ColorReader extends fb.Reader<Color> {
+  const _ColorReader();
+
+  @override
+  int get size => 1;
+
+  @override
+  Color read(fb.BufferContext bc, int offset) =>
+      new Color.fromValue(const fb.Int8Reader().read(bc, offset));
+}
+
+class AnyTypeId {
+  final int value;
+  const AnyTypeId._(this.value);
+
+  factory AnyTypeId.fromValue(int value) {
+    if (value == null) value = 0;
+    if (!values.containsKey(value)) {
+      throw new StateError('Invalid value $value for bit flag enum AnyTypeId');
+    }
+    return values[value];
+  }
+
+  static const int minValue = 0;
+  static const int maxValue = 3;
+  static bool containsValue(int value) => values.containsKey(value);
+
+  static const AnyTypeId NONE = const AnyTypeId._(0);
+  static const AnyTypeId Monster = const AnyTypeId._(1);
+  static const AnyTypeId TestSimpleTableWithEnum = const AnyTypeId._(2);
+  static const AnyTypeId MyGame_Example2_Monster = const AnyTypeId._(3);
+  static get values => {0: NONE,1: Monster,2: TestSimpleTableWithEnum,3: MyGame_Example2_Monster,};
+
+  static const fb.Reader<AnyTypeId> reader = const _AnyTypeIdReader();
+
+  @override
+  String toString() {
+    return 'AnyTypeId{value: $value}';
+  }
+}
+
+class _AnyTypeIdReader extends fb.Reader<AnyTypeId> {
+  const _AnyTypeIdReader();
+
+  @override
+  int get size => 1;
+
+  @override
+  AnyTypeId read(fb.BufferContext bc, int offset) =>
+      new AnyTypeId.fromValue(const fb.Uint8Reader().read(bc, offset));
+}
+
+class AnyUniqueAliasesTypeId {
+  final int value;
+  const AnyUniqueAliasesTypeId._(this.value);
+
+  factory AnyUniqueAliasesTypeId.fromValue(int value) {
+    if (value == null) value = 0;
+    if (!values.containsKey(value)) {
+      throw new StateError('Invalid value $value for bit flag enum AnyUniqueAliasesTypeId');
+    }
+    return values[value];
+  }
+
+  static const int minValue = 0;
+  static const int maxValue = 3;
+  static bool containsValue(int value) => values.containsKey(value);
+
+  static const AnyUniqueAliasesTypeId NONE = const AnyUniqueAliasesTypeId._(0);
+  static const AnyUniqueAliasesTypeId M = const AnyUniqueAliasesTypeId._(1);
+  static const AnyUniqueAliasesTypeId T = const AnyUniqueAliasesTypeId._(2);
+  static const AnyUniqueAliasesTypeId M2 = const AnyUniqueAliasesTypeId._(3);
+  static get values => {0: NONE,1: M,2: T,3: M2,};
+
+  static const fb.Reader<AnyUniqueAliasesTypeId> reader = const _AnyUniqueAliasesTypeIdReader();
+
+  @override
+  String toString() {
+    return 'AnyUniqueAliasesTypeId{value: $value}';
+  }
+}
+
+class _AnyUniqueAliasesTypeIdReader extends fb.Reader<AnyUniqueAliasesTypeId> {
+  const _AnyUniqueAliasesTypeIdReader();
+
+  @override
+  int get size => 1;
+
+  @override
+  AnyUniqueAliasesTypeId read(fb.BufferContext bc, int offset) =>
+      new AnyUniqueAliasesTypeId.fromValue(const fb.Uint8Reader().read(bc, offset));
+}
+
+class AnyAmbiguousAliasesTypeId {
+  final int value;
+  const AnyAmbiguousAliasesTypeId._(this.value);
+
+  factory AnyAmbiguousAliasesTypeId.fromValue(int value) {
+    if (value == null) value = 0;
+    if (!values.containsKey(value)) {
+      throw new StateError('Invalid value $value for bit flag enum AnyAmbiguousAliasesTypeId');
+    }
+    return values[value];
+  }
+
+  static const int minValue = 0;
+  static const int maxValue = 3;
+  static bool containsValue(int value) => values.containsKey(value);
+
+  static const AnyAmbiguousAliasesTypeId NONE = const AnyAmbiguousAliasesTypeId._(0);
+  static const AnyAmbiguousAliasesTypeId M1 = const AnyAmbiguousAliasesTypeId._(1);
+  static const AnyAmbiguousAliasesTypeId M2 = const AnyAmbiguousAliasesTypeId._(2);
+  static const AnyAmbiguousAliasesTypeId M3 = const AnyAmbiguousAliasesTypeId._(3);
+  static get values => {0: NONE,1: M1,2: M2,3: M3,};
+
+  static const fb.Reader<AnyAmbiguousAliasesTypeId> reader = const _AnyAmbiguousAliasesTypeIdReader();
+
+  @override
+  String toString() {
+    return 'AnyAmbiguousAliasesTypeId{value: $value}';
+  }
+}
+
+class _AnyAmbiguousAliasesTypeIdReader extends fb.Reader<AnyAmbiguousAliasesTypeId> {
+  const _AnyAmbiguousAliasesTypeIdReader();
+
+  @override
+  int get size => 1;
+
+  @override
+  AnyAmbiguousAliasesTypeId read(fb.BufferContext bc, int offset) =>
+      new AnyAmbiguousAliasesTypeId.fromValue(const fb.Uint8Reader().read(bc, offset));
+}
+
+class Test {
+  Test._(this._bc, this._bcOffset);
+
+  static const fb.Reader<Test> reader = const _TestReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  int get a => const fb.Int16Reader().read(_bc, _bcOffset + 0);
+  int get b => const fb.Int8Reader().read(_bc, _bcOffset + 2);
+
+  @override
+  String toString() {
+    return 'Test{a: $a, b: $b}';
+  }
+}
+
+class _TestReader extends fb.StructReader<Test> {
+  const _TestReader();
+
+  @override
+  int get size => 4;
+
+  @override
+  Test createObject(fb.BufferContext bc, int offset) => 
+    new Test._(bc, offset);
+}
+
+class TestBuilder {
+  TestBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  int finish(int a, int b) {
+    fbBuilder.pad(1);
+    fbBuilder.putInt8(b);
+    fbBuilder.putInt16(a);
+    return fbBuilder.offset;
+  }
+
+}
+
+class TestObjectBuilder extends fb.ObjectBuilder {
+  final int _a;
+  final int _b;
+
+  TestObjectBuilder({
+    int a,
+    int b,
+  })
+      : _a = a,
+        _b = b;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+
+    fbBuilder.pad(1);
+    fbBuilder.putInt8(_b);
+    fbBuilder.putInt16(_a);
+    return fbBuilder.offset;
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
+class TestSimpleTableWithEnum {
+  TestSimpleTableWithEnum._(this._bc, this._bcOffset);
+  factory TestSimpleTableWithEnum(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<TestSimpleTableWithEnum> reader = const _TestSimpleTableWithEnumReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  Color get color => new Color.fromValue(const fb.Int8Reader().vTableGet(_bc, _bcOffset, 4, 2));
+
+  @override
+  String toString() {
+    return 'TestSimpleTableWithEnum{color: $color}';
+  }
+}
+
+class _TestSimpleTableWithEnumReader extends fb.TableReader<TestSimpleTableWithEnum> {
+  const _TestSimpleTableWithEnumReader();
+
+  @override
+  TestSimpleTableWithEnum createObject(fb.BufferContext bc, int offset) => 
+    new TestSimpleTableWithEnum._(bc, offset);
+}
+
+class TestSimpleTableWithEnumBuilder {
+  TestSimpleTableWithEnumBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  void begin() {
+    fbBuilder.startTable();
+  }
+
+  int addColor(Color color) {
+    fbBuilder.addInt8(0, color?.value);
+    return fbBuilder.offset;
+  }
+
+  int finish() {
+    return fbBuilder.endTable();
+  }
+}
+
+class TestSimpleTableWithEnumObjectBuilder extends fb.ObjectBuilder {
+  final Color _color;
+
+  TestSimpleTableWithEnumObjectBuilder({
+    Color color,
+  })
+      : _color = color;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+
+    fbBuilder.startTable();
+    fbBuilder.addInt8(0, _color?.value);
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
+class Vec3 {
+  Vec3._(this._bc, this._bcOffset);
+
+  static const fb.Reader<Vec3> reader = const _Vec3Reader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  double get x => const fb.Float32Reader().read(_bc, _bcOffset + 0);
+  double get y => const fb.Float32Reader().read(_bc, _bcOffset + 4);
+  double get z => const fb.Float32Reader().read(_bc, _bcOffset + 8);
+  double get test1 => const fb.Float64Reader().read(_bc, _bcOffset + 16);
+  Color get test2 => new Color.fromValue(const fb.Int8Reader().read(_bc, _bcOffset + 24));
+  Test get test3 => Test.reader.read(_bc, _bcOffset + 26);
+
+  @override
+  String toString() {
+    return 'Vec3{x: $x, y: $y, z: $z, test1: $test1, test2: $test2, test3: $test3}';
+  }
+}
+
+class _Vec3Reader extends fb.StructReader<Vec3> {
+  const _Vec3Reader();
+
+  @override
+  int get size => 32;
+
+  @override
+  Vec3 createObject(fb.BufferContext bc, int offset) => 
+    new Vec3._(bc, offset);
+}
+
+class Vec3Builder {
+  Vec3Builder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  int finish(double x, double y, double z, double test1, Color test2, fb.StructBuilder test3) {
+    fbBuilder.pad(2);
+    test3();
+    fbBuilder.pad(1);
+    fbBuilder.putInt8(test2?.value);
+    fbBuilder.putFloat64(test1);
+    fbBuilder.pad(4);
+    fbBuilder.putFloat32(z);
+    fbBuilder.putFloat32(y);
+    fbBuilder.putFloat32(x);
+    return fbBuilder.offset;
+  }
+
+}
+
+class Vec3ObjectBuilder extends fb.ObjectBuilder {
+  final double _x;
+  final double _y;
+  final double _z;
+  final double _test1;
+  final Color _test2;
+  final TestObjectBuilder _test3;
+
+  Vec3ObjectBuilder({
+    double x,
+    double y,
+    double z,
+    double test1,
+    Color test2,
+    TestObjectBuilder test3,
+  })
+      : _x = x,
+        _y = y,
+        _z = z,
+        _test1 = test1,
+        _test2 = test2,
+        _test3 = test3;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+
+    fbBuilder.pad(2);
+    _test3.finish(fbBuilder);
+    fbBuilder.pad(1);
+    fbBuilder.putInt8(_test2?.value);
+    fbBuilder.putFloat64(_test1);
+    fbBuilder.pad(4);
+    fbBuilder.putFloat32(_z);
+    fbBuilder.putFloat32(_y);
+    fbBuilder.putFloat32(_x);
+    return fbBuilder.offset;
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
+class Ability {
+  Ability._(this._bc, this._bcOffset);
+
+  static const fb.Reader<Ability> reader = const _AbilityReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  int get id => const fb.Uint32Reader().read(_bc, _bcOffset + 0);
+  int get distance => const fb.Uint32Reader().read(_bc, _bcOffset + 4);
+
+  @override
+  String toString() {
+    return 'Ability{id: $id, distance: $distance}';
+  }
+}
+
+class _AbilityReader extends fb.StructReader<Ability> {
+  const _AbilityReader();
+
+  @override
+  int get size => 8;
+
+  @override
+  Ability createObject(fb.BufferContext bc, int offset) => 
+    new Ability._(bc, offset);
+}
+
+class AbilityBuilder {
+  AbilityBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  int finish(int id, int distance) {
+    fbBuilder.putUint32(distance);
+    fbBuilder.putUint32(id);
+    return fbBuilder.offset;
+  }
+
+}
+
+class AbilityObjectBuilder extends fb.ObjectBuilder {
+  final int _id;
+  final int _distance;
+
+  AbilityObjectBuilder({
+    int id,
+    int distance,
+  })
+      : _id = id,
+        _distance = distance;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+
+    fbBuilder.putUint32(_distance);
+    fbBuilder.putUint32(_id);
+    return fbBuilder.offset;
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
+class Stat {
+  Stat._(this._bc, this._bcOffset);
+  factory Stat(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<Stat> reader = const _StatReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  String get id => const fb.StringReader().vTableGet(_bc, _bcOffset, 4, null);
+  int get val => const fb.Int64Reader().vTableGet(_bc, _bcOffset, 6, 0);
+  int get count => const fb.Uint16Reader().vTableGet(_bc, _bcOffset, 8, 0);
+
+  @override
+  String toString() {
+    return 'Stat{id: $id, val: $val, count: $count}';
+  }
+}
+
+class _StatReader extends fb.TableReader<Stat> {
+  const _StatReader();
+
+  @override
+  Stat createObject(fb.BufferContext bc, int offset) => 
+    new Stat._(bc, offset);
+}
+
+class StatBuilder {
+  StatBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  void begin() {
+    fbBuilder.startTable();
+  }
+
+  int addIdOffset(int offset) {
+    fbBuilder.addOffset(0, offset);
+    return fbBuilder.offset;
+  }
+  int addVal(int val) {
+    fbBuilder.addInt64(1, val);
+    return fbBuilder.offset;
+  }
+  int addCount(int count) {
+    fbBuilder.addUint16(2, count);
+    return fbBuilder.offset;
+  }
+
+  int finish() {
+    return fbBuilder.endTable();
+  }
+}
+
+class StatObjectBuilder extends fb.ObjectBuilder {
+  final String _id;
+  final int _val;
+  final int _count;
+
+  StatObjectBuilder({
+    String id,
+    int val,
+    int count,
+  })
+      : _id = id,
+        _val = val,
+        _count = count;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+    final int idOffset = fbBuilder.writeString(_id);
+
+    fbBuilder.startTable();
+    if (idOffset != null) {
+      fbBuilder.addOffset(0, idOffset);
+    }
+    fbBuilder.addInt64(1, _val);
+    fbBuilder.addUint16(2, _count);
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
+class Referrable {
+  Referrable._(this._bc, this._bcOffset);
+  factory Referrable(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<Referrable> reader = const _ReferrableReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  int get id => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 4, 0);
+
+  @override
+  String toString() {
+    return 'Referrable{id: $id}';
+  }
+}
+
+class _ReferrableReader extends fb.TableReader<Referrable> {
+  const _ReferrableReader();
+
+  @override
+  Referrable createObject(fb.BufferContext bc, int offset) => 
+    new Referrable._(bc, offset);
+}
+
+class ReferrableBuilder {
+  ReferrableBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  void begin() {
+    fbBuilder.startTable();
+  }
+
+  int addId(int id) {
+    fbBuilder.addUint64(0, id);
+    return fbBuilder.offset;
+  }
+
+  int finish() {
+    return fbBuilder.endTable();
+  }
+}
+
+class ReferrableObjectBuilder extends fb.ObjectBuilder {
+  final int _id;
+
+  ReferrableObjectBuilder({
+    int id,
+  })
+      : _id = id;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+
+    fbBuilder.startTable();
+    fbBuilder.addUint64(0, _id);
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
+///  an example documentation comment: monster object
+class Monster {
+  Monster._(this._bc, this._bcOffset);
+  factory Monster(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<Monster> reader = const _MonsterReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  Vec3 get pos => Vec3.reader.vTableGet(_bc, _bcOffset, 4, null);
+  int get mana => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 6, 150);
+  int get hp => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 8, 100);
+  String get name => const fb.StringReader().vTableGet(_bc, _bcOffset, 10, null);
+  List<int> get inventory => const fb.ListReader<int>(const fb.Uint8Reader()).vTableGet(_bc, _bcOffset, 14, null);
+  Color get color => new Color.fromValue(const fb.Int8Reader().vTableGet(_bc, _bcOffset, 16, 8));
+  AnyTypeId get testType => new AnyTypeId.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 18, 0));
+  dynamic get test {
+    switch (testType?.value) {
+      case 1: return Monster.reader.vTableGet(_bc, _bcOffset, 20, null);
+      case 2: return TestSimpleTableWithEnum.reader.vTableGet(_bc, _bcOffset, 20, null);
+      case 3: return my_game_example2.Monster.reader.vTableGet(_bc, _bcOffset, 20, null);
+      default: return null;
+    }
+  }
+  List<Test> get test4 => const fb.ListReader<Test>(Test.reader).vTableGet(_bc, _bcOffset, 22, null);
+  List<String> get testarrayofstring => const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bc, _bcOffset, 24, null);
+///  an example documentation comment: this will end up in the generated code
+///  multiline too
+  List<Monster> get testarrayoftables => const fb.ListReader<Monster>(Monster.reader).vTableGet(_bc, _bcOffset, 26, null);
+  Monster get enemy => Monster.reader.vTableGet(_bc, _bcOffset, 28, null);
+  List<int> get testnestedflatbuffer => const fb.ListReader<int>(const fb.Uint8Reader()).vTableGet(_bc, _bcOffset, 30, null);
+  Stat get testempty => Stat.reader.vTableGet(_bc, _bcOffset, 32, null);
+  bool get testbool => const fb.BoolReader().vTableGet(_bc, _bcOffset, 34, false);
+  int get testhashs32Fnv1 => const fb.Int32Reader().vTableGet(_bc, _bcOffset, 36, 0);
+  int get testhashu32Fnv1 => const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 38, 0);
+  int get testhashs64Fnv1 => const fb.Int64Reader().vTableGet(_bc, _bcOffset, 40, 0);
+  int get testhashu64Fnv1 => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 42, 0);
+  int get testhashs32Fnv1a => const fb.Int32Reader().vTableGet(_bc, _bcOffset, 44, 0);
+  int get testhashu32Fnv1a => const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 46, 0);
+  int get testhashs64Fnv1a => const fb.Int64Reader().vTableGet(_bc, _bcOffset, 48, 0);
+  int get testhashu64Fnv1a => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 50, 0);
+  List<bool> get testarrayofbools => const fb.ListReader<bool>(const fb.BoolReader()).vTableGet(_bc, _bcOffset, 52, null);
+  double get testf => const fb.Float32Reader().vTableGet(_bc, _bcOffset, 54, 3.14159);
+  double get testf2 => const fb.Float32Reader().vTableGet(_bc, _bcOffset, 56, 3.0);
+  double get testf3 => const fb.Float32Reader().vTableGet(_bc, _bcOffset, 58, 0.0);
+  List<String> get testarrayofstring2 => const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bc, _bcOffset, 60, null);
+  List<Ability> get testarrayofsortedstruct => const fb.ListReader<Ability>(Ability.reader).vTableGet(_bc, _bcOffset, 62, null);
+  List<int> get flex => const fb.ListReader<int>(const fb.Uint8Reader()).vTableGet(_bc, _bcOffset, 64, null);
+  List<Test> get test5 => const fb.ListReader<Test>(Test.reader).vTableGet(_bc, _bcOffset, 66, null);
+  List<int> get vectorOfLongs => const fb.ListReader<int>(const fb.Int64Reader()).vTableGet(_bc, _bcOffset, 68, null);
+  List<double> get vectorOfDoubles => const fb.ListReader<double>(const fb.Float64Reader()).vTableGet(_bc, _bcOffset, 70, null);
+  my_game.InParentNamespace get parentNamespaceTest => my_game.InParentNamespace.reader.vTableGet(_bc, _bcOffset, 72, null);
+  List<Referrable> get vectorOfReferrables => const fb.ListReader<Referrable>(Referrable.reader).vTableGet(_bc, _bcOffset, 74, null);
+  int get singleWeakReference => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 76, 0);
+  List<int> get vectorOfWeakReferences => const fb.ListReader<int>(const fb.Uint64Reader()).vTableGet(_bc, _bcOffset, 78, null);
+  List<Referrable> get vectorOfStrongReferrables => const fb.ListReader<Referrable>(Referrable.reader).vTableGet(_bc, _bcOffset, 80, null);
+  int get coOwningReference => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 82, 0);
+  List<int> get vectorOfCoOwningReferences => const fb.ListReader<int>(const fb.Uint64Reader()).vTableGet(_bc, _bcOffset, 84, null);
+  int get nonOwningReference => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 86, 0);
+  List<int> get vectorOfNonOwningReferences => const fb.ListReader<int>(const fb.Uint64Reader()).vTableGet(_bc, _bcOffset, 88, null);
+  AnyUniqueAliasesTypeId get anyUniqueType => new AnyUniqueAliasesTypeId.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 90, 0));
+  dynamic get anyUnique {
+    switch (anyUniqueType?.value) {
+      case 1: return M.reader.vTableGet(_bc, _bcOffset, 92, null);
+      case 2: return T.reader.vTableGet(_bc, _bcOffset, 92, null);
+      case 3: return M2.reader.vTableGet(_bc, _bcOffset, 92, null);
+      default: return null;
+    }
+  }
+  AnyAmbiguousAliasesTypeId get anyAmbiguousType => new AnyAmbiguousAliasesTypeId.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 94, 0));
+  dynamic get anyAmbiguous {
+    switch (anyAmbiguousType?.value) {
+      case 1: return M1.reader.vTableGet(_bc, _bcOffset, 96, null);
+      case 2: return M2.reader.vTableGet(_bc, _bcOffset, 96, null);
+      case 3: return M3.reader.vTableGet(_bc, _bcOffset, 96, null);
+      default: return null;
+    }
+  }
+  List<Color> get vectorOfEnums => const fb.ListReader<Color>(Color.reader).vTableGet(_bc, _bcOffset, 98, null);
+
+  @override
+  String toString() {
+    return 'Monster{pos: $pos, mana: $mana, hp: $hp, name: $name, inventory: $inventory, color: $color, testType: $testType, test: $test, test4: $test4, testarrayofstring: $testarrayofstring, testarrayoftables: $testarrayoftables, enemy: $enemy, testnestedflatbuffer: $testnestedflatbuffer, testempty: $testempty, testbool: $testbool, testhashs32Fnv1: $testhashs32Fnv1, testhashu32Fnv1: $testhashu32Fnv1, testhashs64Fnv1: $testhashs64Fnv1, testhashu64Fnv1: $testhashu64Fnv1, testhashs32Fnv1a: $testhashs32Fnv1a, testhashu32Fnv1a: $testhashu32Fnv1a, testhashs64Fnv1a: $testhashs64Fnv1a, testhashu64Fnv1a: $testhashu64Fnv1a, testarrayofbools: $testarrayofbools, testf: $testf, testf2: $testf2, testf3: $testf3, testarrayofstring2: $testarrayofstring2, testarrayofsortedstruct: $testarrayofsortedstruct, flex: $flex, test5: $test5, vectorOfLongs: $vectorOfLongs, vectorOfDoubles: $vectorOfDoubles, parentNamespaceTest: $parentNamespaceTest, vectorOfReferrables: $vectorOfReferrables, singleWeakReference: $singleWeakReference, vectorOfWeakReferences: $vectorOfWeakReferences, vectorOfStrongReferrables: $vectorOfStrongReferrables, coOwningReference: $coOwningReference, vectorOfCoOwningReferences: $vectorOfCoOwningReferences, nonOwningReference: $nonOwningReference, vectorOfNonOwningReferences: $vectorOfNonOwningReferences, anyUniqueType: $anyUniqueType, anyUnique: $anyUnique, anyAmbiguousType: $anyAmbiguousType, anyAmbiguous: $anyAmbiguous, vectorOfEnums: $vectorOfEnums}';
+  }
+}
+
+class _MonsterReader extends fb.TableReader<Monster> {
+  const _MonsterReader();
+
+  @override
+  Monster createObject(fb.BufferContext bc, int offset) => 
+    new Monster._(bc, offset);
+}
+
+class MonsterBuilder {
+  MonsterBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  void begin() {
+    fbBuilder.startTable();
+  }
+
+  int addPos(int offset) {
+    fbBuilder.addStruct(0, offset);
+    return fbBuilder.offset;
+  }
+  int addMana(int mana) {
+    fbBuilder.addInt16(1, mana);
+    return fbBuilder.offset;
+  }
+  int addHp(int hp) {
+    fbBuilder.addInt16(2, hp);
+    return fbBuilder.offset;
+  }
+  int addNameOffset(int offset) {
+    fbBuilder.addOffset(3, offset);
+    return fbBuilder.offset;
+  }
+  int addInventoryOffset(int offset) {
+    fbBuilder.addOffset(5, offset);
+    return fbBuilder.offset;
+  }
+  int addColor(Color color) {
+    fbBuilder.addInt8(6, color?.value);
+    return fbBuilder.offset;
+  }
+  int addTestType(AnyTypeId testType) {
+    fbBuilder.addUint8(7, testType?.value);
+    return fbBuilder.offset;
+  }
+  int addTestOffset(int offset) {
+    fbBuilder.addOffset(8, offset);
+    return fbBuilder.offset;
+  }
+  int addTest4Offset(int offset) {
+    fbBuilder.addOffset(9, offset);
+    return fbBuilder.offset;
+  }
+  int addTestarrayofstringOffset(int offset) {
+    fbBuilder.addOffset(10, offset);
+    return fbBuilder.offset;
+  }
+  int addTestarrayoftablesOffset(int offset) {
+    fbBuilder.addOffset(11, offset);
+    return fbBuilder.offset;
+  }
+  int addEnemyOffset(int offset) {
+    fbBuilder.addOffset(12, offset);
+    return fbBuilder.offset;
+  }
+  int addTestnestedflatbufferOffset(int offset) {
+    fbBuilder.addOffset(13, offset);
+    return fbBuilder.offset;
+  }
+  int addTestemptyOffset(int offset) {
+    fbBuilder.addOffset(14, offset);
+    return fbBuilder.offset;
+  }
+  int addTestbool(bool testbool) {
+    fbBuilder.addBool(15, testbool);
+    return fbBuilder.offset;
+  }
+  int addTesthashs32Fnv1(int testhashs32Fnv1) {
+    fbBuilder.addInt32(16, testhashs32Fnv1);
+    return fbBuilder.offset;
+  }
+  int addTesthashu32Fnv1(int testhashu32Fnv1) {
+    fbBuilder.addUint32(17, testhashu32Fnv1);
+    return fbBuilder.offset;
+  }
+  int addTesthashs64Fnv1(int testhashs64Fnv1) {
+    fbBuilder.addInt64(18, testhashs64Fnv1);
+    return fbBuilder.offset;
+  }
+  int addTesthashu64Fnv1(int testhashu64Fnv1) {
+    fbBuilder.addUint64(19, testhashu64Fnv1);
+    return fbBuilder.offset;
+  }
+  int addTesthashs32Fnv1a(int testhashs32Fnv1a) {
+    fbBuilder.addInt32(20, testhashs32Fnv1a);
+    return fbBuilder.offset;
+  }
+  int addTesthashu32Fnv1a(int testhashu32Fnv1a) {
+    fbBuilder.addUint32(21, testhashu32Fnv1a);
+    return fbBuilder.offset;
+  }
+  int addTesthashs64Fnv1a(int testhashs64Fnv1a) {
+    fbBuilder.addInt64(22, testhashs64Fnv1a);
+    return fbBuilder.offset;
+  }
+  int addTesthashu64Fnv1a(int testhashu64Fnv1a) {
+    fbBuilder.addUint64(23, testhashu64Fnv1a);
+    return fbBuilder.offset;
+  }
+  int addTestarrayofboolsOffset(int offset) {
+    fbBuilder.addOffset(24, offset);
+    return fbBuilder.offset;
+  }
+  int addTestf(double testf) {
+    fbBuilder.addFloat32(25, testf);
+    return fbBuilder.offset;
+  }
+  int addTestf2(double testf2) {
+    fbBuilder.addFloat32(26, testf2);
+    return fbBuilder.offset;
+  }
+  int addTestf3(double testf3) {
+    fbBuilder.addFloat32(27, testf3);
+    return fbBuilder.offset;
+  }
+  int addTestarrayofstring2Offset(int offset) {
+    fbBuilder.addOffset(28, offset);
+    return fbBuilder.offset;
+  }
+  int addTestarrayofsortedstructOffset(int offset) {
+    fbBuilder.addOffset(29, offset);
+    return fbBuilder.offset;
+  }
+  int addFlexOffset(int offset) {
+    fbBuilder.addOffset(30, offset);
+    return fbBuilder.offset;
+  }
+  int addTest5Offset(int offset) {
+    fbBuilder.addOffset(31, offset);
+    return fbBuilder.offset;
+  }
+  int addVectorOfLongsOffset(int offset) {
+    fbBuilder.addOffset(32, offset);
+    return fbBuilder.offset;
+  }
+  int addVectorOfDoublesOffset(int offset) {
+    fbBuilder.addOffset(33, offset);
+    return fbBuilder.offset;
+  }
+  int addParentNamespaceTestOffset(int offset) {
+    fbBuilder.addOffset(34, offset);
+    return fbBuilder.offset;
+  }
+  int addVectorOfReferrablesOffset(int offset) {
+    fbBuilder.addOffset(35, offset);
+    return fbBuilder.offset;
+  }
+  int addSingleWeakReference(int singleWeakReference) {
+    fbBuilder.addUint64(36, singleWeakReference);
+    return fbBuilder.offset;
+  }
+  int addVectorOfWeakReferencesOffset(int offset) {
+    fbBuilder.addOffset(37, offset);
+    return fbBuilder.offset;
+  }
+  int addVectorOfStrongReferrablesOffset(int offset) {
+    fbBuilder.addOffset(38, offset);
+    return fbBuilder.offset;
+  }
+  int addCoOwningReference(int coOwningReference) {
+    fbBuilder.addUint64(39, coOwningReference);
+    return fbBuilder.offset;
+  }
+  int addVectorOfCoOwningReferencesOffset(int offset) {
+    fbBuilder.addOffset(40, offset);
+    return fbBuilder.offset;
+  }
+  int addNonOwningReference(int nonOwningReference) {
+    fbBuilder.addUint64(41, nonOwningReference);
+    return fbBuilder.offset;
+  }
+  int addVectorOfNonOwningReferencesOffset(int offset) {
+    fbBuilder.addOffset(42, offset);
+    return fbBuilder.offset;
+  }
+  int addAnyUniqueType(AnyUniqueAliasesTypeId anyUniqueType) {
+    fbBuilder.addUint8(43, anyUniqueType?.value);
+    return fbBuilder.offset;
+  }
+  int addAnyUniqueOffset(int offset) {
+    fbBuilder.addOffset(44, offset);
+    return fbBuilder.offset;
+  }
+  int addAnyAmbiguousType(AnyAmbiguousAliasesTypeId anyAmbiguousType) {
+    fbBuilder.addUint8(45, anyAmbiguousType?.value);
+    return fbBuilder.offset;
+  }
+  int addAnyAmbiguousOffset(int offset) {
+    fbBuilder.addOffset(46, offset);
+    return fbBuilder.offset;
+  }
+  int addVectorOfEnumsOffset(int offset) {
+    fbBuilder.addOffset(47, offset);
+    return fbBuilder.offset;
+  }
+
+  int finish() {
+    return fbBuilder.endTable();
+  }
+}
+
+class MonsterObjectBuilder extends fb.ObjectBuilder {
+  final Vec3ObjectBuilder _pos;
+  final int _mana;
+  final int _hp;
+  final String _name;
+  final List<int> _inventory;
+  final Color _color;
+  final AnyTypeId _testType;
+  final dynamic _test;
+  final List<TestObjectBuilder> _test4;
+  final List<String> _testarrayofstring;
+  final List<MonsterObjectBuilder> _testarrayoftables;
+  final MonsterObjectBuilder _enemy;
+  final List<int> _testnestedflatbuffer;
+  final StatObjectBuilder _testempty;
+  final bool _testbool;
+  final int _testhashs32Fnv1;
+  final int _testhashu32Fnv1;
+  final int _testhashs64Fnv1;
+  final int _testhashu64Fnv1;
+  final int _testhashs32Fnv1a;
+  final int _testhashu32Fnv1a;
+  final int _testhashs64Fnv1a;
+  final int _testhashu64Fnv1a;
+  final List<bool> _testarrayofbools;
+  final double _testf;
+  final double _testf2;
+  final double _testf3;
+  final List<String> _testarrayofstring2;
+  final List<AbilityObjectBuilder> _testarrayofsortedstruct;
+  final List<int> _flex;
+  final List<TestObjectBuilder> _test5;
+  final List<int> _vectorOfLongs;
+  final List<double> _vectorOfDoubles;
+  final my_game.InParentNamespaceObjectBuilder _parentNamespaceTest;
+  final List<ReferrableObjectBuilder> _vectorOfReferrables;
+  final int _singleWeakReference;
+  final List<int> _vectorOfWeakReferences;
+  final List<ReferrableObjectBuilder> _vectorOfStrongReferrables;
+  final int _coOwningReference;
+  final List<int> _vectorOfCoOwningReferences;
+  final int _nonOwningReference;
+  final List<int> _vectorOfNonOwningReferences;
+  final AnyUniqueAliasesTypeId _anyUniqueType;
+  final dynamic _anyUnique;
+  final AnyAmbiguousAliasesTypeId _anyAmbiguousType;
+  final dynamic _anyAmbiguous;
+  final List<Color> _vectorOfEnums;
+
+  MonsterObjectBuilder({
+    Vec3ObjectBuilder pos,
+    int mana,
+    int hp,
+    String name,
+    List<int> inventory,
+    Color color,
+    AnyTypeId testType,
+    dynamic test,
+    List<TestObjectBuilder> test4,
+    List<String> testarrayofstring,
+    List<MonsterObjectBuilder> testarrayoftables,
+    MonsterObjectBuilder enemy,
+    List<int> testnestedflatbuffer,
+    StatObjectBuilder testempty,
+    bool testbool,
+    int testhashs32Fnv1,
+    int testhashu32Fnv1,
+    int testhashs64Fnv1,
+    int testhashu64Fnv1,
+    int testhashs32Fnv1a,
+    int testhashu32Fnv1a,
+    int testhashs64Fnv1a,
+    int testhashu64Fnv1a,
+    List<bool> testarrayofbools,
+    double testf,
+    double testf2,
+    double testf3,
+    List<String> testarrayofstring2,
+    List<AbilityObjectBuilder> testarrayofsortedstruct,
+    List<int> flex,
+    List<TestObjectBuilder> test5,
+    List<int> vectorOfLongs,
+    List<double> vectorOfDoubles,
+    my_game.InParentNamespaceObjectBuilder parentNamespaceTest,
+    List<ReferrableObjectBuilder> vectorOfReferrables,
+    int singleWeakReference,
+    List<int> vectorOfWeakReferences,
+    List<ReferrableObjectBuilder> vectorOfStrongReferrables,
+    int coOwningReference,
+    List<int> vectorOfCoOwningReferences,
+    int nonOwningReference,
+    List<int> vectorOfNonOwningReferences,
+    AnyUniqueAliasesTypeId anyUniqueType,
+    dynamic anyUnique,
+    AnyAmbiguousAliasesTypeId anyAmbiguousType,
+    dynamic anyAmbiguous,
+    List<Color> vectorOfEnums,
+  })
+      : _pos = pos,
+        _mana = mana,
+        _hp = hp,
+        _name = name,
+        _inventory = inventory,
+        _color = color,
+        _testType = testType,
+        _test = test,
+        _test4 = test4,
+        _testarrayofstring = testarrayofstring,
+        _testarrayoftables = testarrayoftables,
+        _enemy = enemy,
+        _testnestedflatbuffer = testnestedflatbuffer,
+        _testempty = testempty,
+        _testbool = testbool,
+        _testhashs32Fnv1 = testhashs32Fnv1,
+        _testhashu32Fnv1 = testhashu32Fnv1,
+        _testhashs64Fnv1 = testhashs64Fnv1,
+        _testhashu64Fnv1 = testhashu64Fnv1,
+        _testhashs32Fnv1a = testhashs32Fnv1a,
+        _testhashu32Fnv1a = testhashu32Fnv1a,
+        _testhashs64Fnv1a = testhashs64Fnv1a,
+        _testhashu64Fnv1a = testhashu64Fnv1a,
+        _testarrayofbools = testarrayofbools,
+        _testf = testf,
+        _testf2 = testf2,
+        _testf3 = testf3,
+        _testarrayofstring2 = testarrayofstring2,
+        _testarrayofsortedstruct = testarrayofsortedstruct,
+        _flex = flex,
+        _test5 = test5,
+        _vectorOfLongs = vectorOfLongs,
+        _vectorOfDoubles = vectorOfDoubles,
+        _parentNamespaceTest = parentNamespaceTest,
+        _vectorOfReferrables = vectorOfReferrables,
+        _singleWeakReference = singleWeakReference,
+        _vectorOfWeakReferences = vectorOfWeakReferences,
+        _vectorOfStrongReferrables = vectorOfStrongReferrables,
+        _coOwningReference = coOwningReference,
+        _vectorOfCoOwningReferences = vectorOfCoOwningReferences,
+        _nonOwningReference = nonOwningReference,
+        _vectorOfNonOwningReferences = vectorOfNonOwningReferences,
+        _anyUniqueType = anyUniqueType,
+        _anyUnique = anyUnique,
+        _anyAmbiguousType = anyAmbiguousType,
+        _anyAmbiguous = anyAmbiguous,
+        _vectorOfEnums = vectorOfEnums;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+    final int nameOffset = fbBuilder.writeString(_name);
+    final int inventoryOffset = _inventory?.isNotEmpty == true
+        ? fbBuilder.writeListUint8(_inventory)
+        : null;
+    final int testOffset = _test?.getOrCreateOffset(fbBuilder);
+    final int test4Offset = _test4?.isNotEmpty == true
+        ? fbBuilder.writeListOfStructs(_test4)
+        : null;
+    final int testarrayofstringOffset = _testarrayofstring?.isNotEmpty == true
+        ? fbBuilder.writeList(_testarrayofstring.map((b) => fbBuilder.writeString(b)).toList())
+        : null;
+    final int testarrayoftablesOffset = _testarrayoftables?.isNotEmpty == true
+        ? fbBuilder.writeList(_testarrayoftables.map((b) => b.getOrCreateOffset(fbBuilder)).toList())
+        : null;
+    final int enemyOffset = _enemy?.getOrCreateOffset(fbBuilder);
+    final int testnestedflatbufferOffset = _testnestedflatbuffer?.isNotEmpty == true
+        ? fbBuilder.writeListUint8(_testnestedflatbuffer)
+        : null;
+    final int testemptyOffset = _testempty?.getOrCreateOffset(fbBuilder);
+    final int testarrayofboolsOffset = _testarrayofbools?.isNotEmpty == true
+        ? fbBuilder.writeListBool(_testarrayofbools)
+        : null;
+    final int testarrayofstring2Offset = _testarrayofstring2?.isNotEmpty == true
+        ? fbBuilder.writeList(_testarrayofstring2.map((b) => fbBuilder.writeString(b)).toList())
+        : null;
+    final int testarrayofsortedstructOffset = _testarrayofsortedstruct?.isNotEmpty == true
+        ? fbBuilder.writeListOfStructs(_testarrayofsortedstruct)
+        : null;
+    final int flexOffset = _flex?.isNotEmpty == true
+        ? fbBuilder.writeListUint8(_flex)
+        : null;
+    final int test5Offset = _test5?.isNotEmpty == true
+        ? fbBuilder.writeListOfStructs(_test5)
+        : null;
+    final int vectorOfLongsOffset = _vectorOfLongs?.isNotEmpty == true
+        ? fbBuilder.writeListInt64(_vectorOfLongs)
+        : null;
+    final int vectorOfDoublesOffset = _vectorOfDoubles?.isNotEmpty == true
+        ? fbBuilder.writeListFloat64(_vectorOfDoubles)
+        : null;
+    final int parentNamespaceTestOffset = _parentNamespaceTest?.getOrCreateOffset(fbBuilder);
+    final int vectorOfReferrablesOffset = _vectorOfReferrables?.isNotEmpty == true
+        ? fbBuilder.writeList(_vectorOfReferrables.map((b) => b.getOrCreateOffset(fbBuilder)).toList())
+        : null;
+    final int vectorOfWeakReferencesOffset = _vectorOfWeakReferences?.isNotEmpty == true
+        ? fbBuilder.writeListUint64(_vectorOfWeakReferences)
+        : null;
+    final int vectorOfStrongReferrablesOffset = _vectorOfStrongReferrables?.isNotEmpty == true
+        ? fbBuilder.writeList(_vectorOfStrongReferrables.map((b) => b.getOrCreateOffset(fbBuilder)).toList())
+        : null;
+    final int vectorOfCoOwningReferencesOffset = _vectorOfCoOwningReferences?.isNotEmpty == true
+        ? fbBuilder.writeListUint64(_vectorOfCoOwningReferences)
+        : null;
+    final int vectorOfNonOwningReferencesOffset = _vectorOfNonOwningReferences?.isNotEmpty == true
+        ? fbBuilder.writeListUint64(_vectorOfNonOwningReferences)
+        : null;
+    final int anyUniqueOffset = _anyUnique?.getOrCreateOffset(fbBuilder);
+    final int anyAmbiguousOffset = _anyAmbiguous?.getOrCreateOffset(fbBuilder);
+    final int vectorOfEnumsOffset = _vectorOfEnums?.isNotEmpty == true
+        ? fbBuilder.writeListInt8(_vectorOfEnums.map((f) => f.value))
+        : null;
+
+    fbBuilder.startTable();
+    if (_pos != null) {
+      fbBuilder.addStruct(0, _pos.finish(fbBuilder));
+    }
+    fbBuilder.addInt16(1, _mana);
+    fbBuilder.addInt16(2, _hp);
+    if (nameOffset != null) {
+      fbBuilder.addOffset(3, nameOffset);
+    }
+    if (inventoryOffset != null) {
+      fbBuilder.addOffset(5, inventoryOffset);
+    }
+    fbBuilder.addInt8(6, _color?.value);
+    fbBuilder.addUint8(7, _testType?.value);
+    if (testOffset != null) {
+      fbBuilder.addOffset(8, testOffset);
+    }
+    if (test4Offset != null) {
+      fbBuilder.addOffset(9, test4Offset);
+    }
+    if (testarrayofstringOffset != null) {
+      fbBuilder.addOffset(10, testarrayofstringOffset);
+    }
+    if (testarrayoftablesOffset != null) {
+      fbBuilder.addOffset(11, testarrayoftablesOffset);
+    }
+    if (enemyOffset != null) {
+      fbBuilder.addOffset(12, enemyOffset);
+    }
+    if (testnestedflatbufferOffset != null) {
+      fbBuilder.addOffset(13, testnestedflatbufferOffset);
+    }
+    if (testemptyOffset != null) {
+      fbBuilder.addOffset(14, testemptyOffset);
+    }
+    fbBuilder.addBool(15, _testbool);
+    fbBuilder.addInt32(16, _testhashs32Fnv1);
+    fbBuilder.addUint32(17, _testhashu32Fnv1);
+    fbBuilder.addInt64(18, _testhashs64Fnv1);
+    fbBuilder.addUint64(19, _testhashu64Fnv1);
+    fbBuilder.addInt32(20, _testhashs32Fnv1a);
+    fbBuilder.addUint32(21, _testhashu32Fnv1a);
+    fbBuilder.addInt64(22, _testhashs64Fnv1a);
+    fbBuilder.addUint64(23, _testhashu64Fnv1a);
+    if (testarrayofboolsOffset != null) {
+      fbBuilder.addOffset(24, testarrayofboolsOffset);
+    }
+    fbBuilder.addFloat32(25, _testf);
+    fbBuilder.addFloat32(26, _testf2);
+    fbBuilder.addFloat32(27, _testf3);
+    if (testarrayofstring2Offset != null) {
+      fbBuilder.addOffset(28, testarrayofstring2Offset);
+    }
+    if (testarrayofsortedstructOffset != null) {
+      fbBuilder.addOffset(29, testarrayofsortedstructOffset);
+    }
+    if (flexOffset != null) {
+      fbBuilder.addOffset(30, flexOffset);
+    }
+    if (test5Offset != null) {
+      fbBuilder.addOffset(31, test5Offset);
+    }
+    if (vectorOfLongsOffset != null) {
+      fbBuilder.addOffset(32, vectorOfLongsOffset);
+    }
+    if (vectorOfDoublesOffset != null) {
+      fbBuilder.addOffset(33, vectorOfDoublesOffset);
+    }
+    if (parentNamespaceTestOffset != null) {
+      fbBuilder.addOffset(34, parentNamespaceTestOffset);
+    }
+    if (vectorOfReferrablesOffset != null) {
+      fbBuilder.addOffset(35, vectorOfReferrablesOffset);
+    }
+    fbBuilder.addUint64(36, _singleWeakReference);
+    if (vectorOfWeakReferencesOffset != null) {
+      fbBuilder.addOffset(37, vectorOfWeakReferencesOffset);
+    }
+    if (vectorOfStrongReferrablesOffset != null) {
+      fbBuilder.addOffset(38, vectorOfStrongReferrablesOffset);
+    }
+    fbBuilder.addUint64(39, _coOwningReference);
+    if (vectorOfCoOwningReferencesOffset != null) {
+      fbBuilder.addOffset(40, vectorOfCoOwningReferencesOffset);
+    }
+    fbBuilder.addUint64(41, _nonOwningReference);
+    if (vectorOfNonOwningReferencesOffset != null) {
+      fbBuilder.addOffset(42, vectorOfNonOwningReferencesOffset);
+    }
+    fbBuilder.addUint8(43, _anyUniqueType?.value);
+    if (anyUniqueOffset != null) {
+      fbBuilder.addOffset(44, anyUniqueOffset);
+    }
+    fbBuilder.addUint8(45, _anyAmbiguousType?.value);
+    if (anyAmbiguousOffset != null) {
+      fbBuilder.addOffset(46, anyAmbiguousOffset);
+    }
+    if (vectorOfEnumsOffset != null) {
+      fbBuilder.addOffset(47, vectorOfEnumsOffset);
+    }
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
+class TypeAliases {
+  TypeAliases._(this._bc, this._bcOffset);
+  factory TypeAliases(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<TypeAliases> reader = const _TypeAliasesReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  int get i8 => const fb.Int8Reader().vTableGet(_bc, _bcOffset, 4, 0);
+  int get u8 => const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 6, 0);
+  int get i16 => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 8, 0);
+  int get u16 => const fb.Uint16Reader().vTableGet(_bc, _bcOffset, 10, 0);
+  int get i32 => const fb.Int32Reader().vTableGet(_bc, _bcOffset, 12, 0);
+  int get u32 => const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 14, 0);
+  int get i64 => const fb.Int64Reader().vTableGet(_bc, _bcOffset, 16, 0);
+  int get u64 => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 18, 0);
+  double get f32 => const fb.Float32Reader().vTableGet(_bc, _bcOffset, 20, 0.0);
+  double get f64 => const fb.Float64Reader().vTableGet(_bc, _bcOffset, 22, 0.0);
+  List<int> get v8 => const fb.ListReader<int>(const fb.Int8Reader()).vTableGet(_bc, _bcOffset, 24, null);
+  List<double> get vf64 => const fb.ListReader<double>(const fb.Float64Reader()).vTableGet(_bc, _bcOffset, 26, null);
+
+  @override
+  String toString() {
+    return 'TypeAliases{i8: $i8, u8: $u8, i16: $i16, u16: $u16, i32: $i32, u32: $u32, i64: $i64, u64: $u64, f32: $f32, f64: $f64, v8: $v8, vf64: $vf64}';
+  }
+}
+
+class _TypeAliasesReader extends fb.TableReader<TypeAliases> {
+  const _TypeAliasesReader();
+
+  @override
+  TypeAliases createObject(fb.BufferContext bc, int offset) => 
+    new TypeAliases._(bc, offset);
+}
+
+class TypeAliasesBuilder {
+  TypeAliasesBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  void begin() {
+    fbBuilder.startTable();
+  }
+
+  int addI8(int i8) {
+    fbBuilder.addInt8(0, i8);
+    return fbBuilder.offset;
+  }
+  int addU8(int u8) {
+    fbBuilder.addUint8(1, u8);
+    return fbBuilder.offset;
+  }
+  int addI16(int i16) {
+    fbBuilder.addInt16(2, i16);
+    return fbBuilder.offset;
+  }
+  int addU16(int u16) {
+    fbBuilder.addUint16(3, u16);
+    return fbBuilder.offset;
+  }
+  int addI32(int i32) {
+    fbBuilder.addInt32(4, i32);
+    return fbBuilder.offset;
+  }
+  int addU32(int u32) {
+    fbBuilder.addUint32(5, u32);
+    return fbBuilder.offset;
+  }
+  int addI64(int i64) {
+    fbBuilder.addInt64(6, i64);
+    return fbBuilder.offset;
+  }
+  int addU64(int u64) {
+    fbBuilder.addUint64(7, u64);
+    return fbBuilder.offset;
+  }
+  int addF32(double f32) {
+    fbBuilder.addFloat32(8, f32);
+    return fbBuilder.offset;
+  }
+  int addF64(double f64) {
+    fbBuilder.addFloat64(9, f64);
+    return fbBuilder.offset;
+  }
+  int addV8Offset(int offset) {
+    fbBuilder.addOffset(10, offset);
+    return fbBuilder.offset;
+  }
+  int addVf64Offset(int offset) {
+    fbBuilder.addOffset(11, offset);
+    return fbBuilder.offset;
+  }
+
+  int finish() {
+    return fbBuilder.endTable();
+  }
+}
+
+class TypeAliasesObjectBuilder extends fb.ObjectBuilder {
+  final int _i8;
+  final int _u8;
+  final int _i16;
+  final int _u16;
+  final int _i32;
+  final int _u32;
+  final int _i64;
+  final int _u64;
+  final double _f32;
+  final double _f64;
+  final List<int> _v8;
+  final List<double> _vf64;
+
+  TypeAliasesObjectBuilder({
+    int i8,
+    int u8,
+    int i16,
+    int u16,
+    int i32,
+    int u32,
+    int i64,
+    int u64,
+    double f32,
+    double f64,
+    List<int> v8,
+    List<double> vf64,
+  })
+      : _i8 = i8,
+        _u8 = u8,
+        _i16 = i16,
+        _u16 = u16,
+        _i32 = i32,
+        _u32 = u32,
+        _i64 = i64,
+        _u64 = u64,
+        _f32 = f32,
+        _f64 = f64,
+        _v8 = v8,
+        _vf64 = vf64;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+    final int v8Offset = _v8?.isNotEmpty == true
+        ? fbBuilder.writeListInt8(_v8)
+        : null;
+    final int vf64Offset = _vf64?.isNotEmpty == true
+        ? fbBuilder.writeListFloat64(_vf64)
+        : null;
+
+    fbBuilder.startTable();
+    fbBuilder.addInt8(0, _i8);
+    fbBuilder.addUint8(1, _u8);
+    fbBuilder.addInt16(2, _i16);
+    fbBuilder.addUint16(3, _u16);
+    fbBuilder.addInt32(4, _i32);
+    fbBuilder.addUint32(5, _u32);
+    fbBuilder.addInt64(6, _i64);
+    fbBuilder.addUint64(7, _u64);
+    fbBuilder.addFloat32(8, _f32);
+    fbBuilder.addFloat64(9, _f64);
+    if (v8Offset != null) {
+      fbBuilder.addOffset(10, v8Offset);
+    }
+    if (vf64Offset != null) {
+      fbBuilder.addOffset(11, vf64Offset);
+    }
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
diff --git a/third_party/flatbuffers/dart/test/monster_test_my_game_generated.dart b/third_party/flatbuffers/dart/test/monster_test_my_game_generated.dart
new file mode 100644
index 0000000..26bb73b
--- /dev/null
+++ b/third_party/flatbuffers/dart/test/monster_test_my_game_generated.dart
@@ -0,0 +1,62 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+// ignore_for_file: unused_import, unused_field, unused_local_variable
+
+library my_game;
+
+import 'dart:typed_data' show Uint8List;
+import 'package:flat_buffers/flat_buffers.dart' as fb;
+
+import 'include_test1_my_game_generated.dart';
+import 'include_test2_my_game_generated.dart';
+import './monster_test_my_game.example_generated.dart' as my_game_example;
+import './monster_test_my_game.example2_generated.dart' as my_game_example2;
+
+class InParentNamespace {
+  InParentNamespace._(this._bc, this._bcOffset);
+  factory InParentNamespace(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<InParentNamespace> reader = const _InParentNamespaceReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+
+  @override
+  String toString() {
+    return 'InParentNamespace{}';
+  }
+}
+
+class _InParentNamespaceReader extends fb.TableReader<InParentNamespace> {
+  const _InParentNamespaceReader();
+
+  @override
+  InParentNamespace createObject(fb.BufferContext bc, int offset) => 
+    new InParentNamespace._(bc, offset);
+}
+
+class InParentNamespaceObjectBuilder extends fb.ObjectBuilder {
+
+  InParentNamespaceObjectBuilder();
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+
+    fbBuilder.startTable();
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
diff --git a/third_party/flatbuffers/docs/footer.html b/third_party/flatbuffers/docs/footer.html
new file mode 100644
index 0000000..42bc5f2
--- /dev/null
+++ b/third_party/flatbuffers/docs/footer.html
@@ -0,0 +1,14 @@
+<!-- Google Analytics -->
+<script>
+  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+  ga('create', 'UA-49880327-7', 'auto');
+  ga('send', 'pageview');
+
+</script>
+
+</body>
+</html>
diff --git a/third_party/flatbuffers/docs/header.html b/third_party/flatbuffers/docs/header.html
new file mode 100644
index 0000000..0266e7c
--- /dev/null
+++ b/third_party/flatbuffers/docs/header.html
@@ -0,0 +1,62 @@
+<!-- HTML header for doxygen 1.8.6-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen $doxygenversion"/>
+<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
+<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
+<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="$relpath^jquery.js"></script>
+<script type="text/javascript" src="$relpath^dynsections.js"></script>
+$treeview
+$search
+$mathjax
+<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
+<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,400italic,500,500italic,700,700italic|Roboto+Mono:400,700" rel="stylesheet">
+$extrastylesheet
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+
+<!--BEGIN TITLEAREA-->
+<div id="titlearea" style="height: 110px;">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <!--BEGIN PROJECT_LOGO-->
+  <td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"/></td>
+  <!--END PROJECT_LOGO-->
+  <td id="commonprojectlogo">
+    <img alt="Logo" src="$relpath^fpl_logo_small.png"/>
+  </td>
+  <!--BEGIN PROJECT_NAME-->
+  <td style="padding-left: 0.5em;">
+   <div id="projectname">$projectname
+   <!--BEGIN PROJECT_NUMBER-->&#160;<span id="projectnumber">$projectnumber</span><!--END PROJECT_NUMBER-->
+   </div>
+   <div style="font-size:12px;">
+    An open source project by <a href="https://developers.google.com/games/#Tools">FPL</a>.
+   </div>
+   <!--BEGIN PROJECT_BRIEF--><div id="projectbrief">$projectbrief</div><!--END PROJECT_BRIEF-->
+  </td>
+  <!--END PROJECT_NAME-->
+  <!--BEGIN !PROJECT_NAME-->
+   <!--BEGIN PROJECT_BRIEF-->
+    <td style="padding-left: 0.5em;">
+    <div id="projectbrief">$projectbrief</div>
+    </td>
+   <!--END PROJECT_BRIEF-->
+  <!--END !PROJECT_NAME-->
+  <!--BEGIN DISABLE_INDEX-->
+   <!--BEGIN SEARCHENGINE-->
+   <td>$searchbox</td>
+   <!--END SEARCHENGINE-->
+  <!--END DISABLE_INDEX-->
+ </tr>
+ </tbody>
+</table>
+</div>
+<!--END TITLEAREA-->
+<!-- end header part -->
diff --git a/third_party/flatbuffers/docs/images/fpl_logo_small.png b/third_party/flatbuffers/docs/images/fpl_logo_small.png
new file mode 100644
index 0000000..2c728f3
--- /dev/null
+++ b/third_party/flatbuffers/docs/images/fpl_logo_small.png
Binary files differ
diff --git a/third_party/flatbuffers/docs/images/ftv2mnode.png b/third_party/flatbuffers/docs/images/ftv2mnode.png
new file mode 100644
index 0000000..3caf47d
--- /dev/null
+++ b/third_party/flatbuffers/docs/images/ftv2mnode.png
Binary files differ
diff --git a/third_party/flatbuffers/docs/images/ftv2pnode.png b/third_party/flatbuffers/docs/images/ftv2pnode.png
new file mode 100644
index 0000000..f1aaad3
--- /dev/null
+++ b/third_party/flatbuffers/docs/images/ftv2pnode.png
Binary files differ
diff --git a/third_party/flatbuffers/docs/source/Benchmarks.md b/third_party/flatbuffers/docs/source/Benchmarks.md
new file mode 100644
index 0000000..848f4e3
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/Benchmarks.md
@@ -0,0 +1,63 @@
+C++ Benchmarks    {#flatbuffers_benchmarks}
+==========
+
+Comparing against other serialization solutions, running on Windows 7
+64bit. We use the LITE runtime for Protocol Buffers (less code / lower
+overhead), Rapid JSON (one of the fastest C++ JSON parsers around),
+and pugixml, also one of the fastest XML parsers.
+
+We also compare against code that doesn't use a serialization library
+at all (the column "Raw structs"), which is what you get if you write
+hardcoded code that just writes structs. This is the fastest possible,
+but of course is not cross platform nor has any kind of forwards /
+backwards compatibility.
+
+We compare against Flatbuffers with the binary wire format (as
+intended), and also with JSON as the wire format with the optional JSON
+parser (which, using a schema, parses JSON into a binary buffer that can
+then be accessed as before).
+
+The benchmark object is a set of about 10 objects containing an array, 4
+strings, and a large variety of int/float scalar values of all sizes,
+meant to be representative of game data, e.g. a scene format.
+
+|                                                        | FlatBuffers (binary)  | Protocol Buffers LITE | Rapid JSON            | FlatBuffers (JSON)     | pugixml               | Raw structs           |
+|--------------------------------------------------------|-----------------------|-----------------------|-----------------------|------------------------| ----------------------| ----------------------|
+| Decode + Traverse + Dealloc (1 million times, seconds) | 0.08                  | 302                   | 583                   | 105                    | 196                   | 0.02                  |
+| Decode / Traverse / Dealloc (breakdown)                | 0 / 0.08 / 0          | 220 / 0.15 / 81       | 294 / 0.9 / 287       | 70 / 0.08 / 35         | 41 / 3.9 / 150        | 0 / 0.02 / 0          |
+| Encode (1 million times, seconds)                      | 3.2                   | 185                   | 650                   | 169                    | 273                   | 0.15                  |
+| Wire format size (normal / zlib, bytes)                | 344 / 220             | 228 / 174             | 1475 / 322            | 1029 / 298             | 1137 / 341            | 312 / 187             |
+| Memory needed to store decoded wire (bytes / blocks)   | 0 / 0                 | 760 / 20              | 65689 / 4             | 328 / 1                | 34194 / 3             | 0 / 0                 |
+| Transient memory allocated during decode (KB)          | 0                     | 1                     | 131                   | 4                      | 34                    | 0                     |
+| Generated source code size (KB)                        | 4                     | 61                    | 0                     | 4                      | 0                     | 0                     |
+| Field access in handwritten traversal code             | typed accessors       | typed accessors       | manual error checking | typed accessors        | manual error checking | typed but no safety   |
+| Library source code (KB)                               | 15                    | some subset of 3800   | 87                    | 43                     | 327                   | 0                     |
+
+### Some other serialization systems we compared against but did not benchmark (yet), in rough order of applicability:
+
+-   Cap'n'Proto promises to reduce Protocol Buffers much like FlatBuffers does,
+    though with a more complicated binary encoding and less flexibility (no
+    optional fields to allow deprecating fields or serializing with missing
+    fields for which defaults exist).
+    It currently also isn't fully cross-platform portable (lack of VS support).
+-   msgpack: has very minimal forwards/backwards compatibility support when used
+    with the typed C++ interface. Also lacks VS2010 support.
+-   Thrift: very similar to Protocol Buffers, but appears to be less efficient,
+    and have more dependencies.
+-   YAML: a superset of JSON and otherwise very similar. Used by e.g. Unity.
+-   C# comes with built-in serialization functionality, as used by Unity also.
+    Being tied to the language, and having no automatic versioning support
+    limits its applicability.
+-   Project Anarchy (the free mobile engine by Havok) comes with a serialization
+    system, that however does no automatic versioning (have to code around new
+    fields manually), is very much tied to the rest of the engine, and works
+    without a schema to generate code (tied to your C++ class definition).
+
+### Code for benchmarks
+
+Code for these benchmarks sits in `benchmarks/` in git branch `benchmarks`.
+It sits in its own branch because it has submodule dependencies that the main
+project doesn't need, and the code standards do not meet those of the main
+project. Please read `benchmarks/cpp/README.txt` before working with the code.
+
+<br>
diff --git a/third_party/flatbuffers/docs/source/Building.md b/third_party/flatbuffers/docs/source/Building.md
new file mode 100644
index 0000000..a896711
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/Building.md
@@ -0,0 +1,100 @@
+Building    {#flatbuffers_guide_building}
+========
+
+## Building with CMake
+
+The distribution comes with a `cmake` file that should allow
+you to build project/make files for any platform. For details on `cmake`, see
+<https://www.cmake.org>. In brief, depending on your platform, use one of
+e.g.:
+
+    cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release
+    cmake -G "Visual Studio 10" -DCMAKE_BUILD_TYPE=Release
+    cmake -G "Xcode" -DCMAKE_BUILD_TYPE=Release
+
+Then, build as normal for your platform. This should result in a `flatc`
+executable, essential for the next steps.
+Note that to use clang instead of gcc, you may need to set up your environment
+variables, e.g.
+`CC=/usr/bin/clang CXX=/usr/bin/clang++ cmake -G "Unix Makefiles"`.
+
+Optionally, run the `flattests` executable from the root `flatbuffers/`
+directory to ensure everything is working correctly on your system. If this
+fails, please contact us!
+
+Building should also produce two sample executables, `flatsamplebinary` and
+`flatsampletext`, see the corresponding `.cpp` files in the
+`flatbuffers/samples` directory.
+
+*Note that you MUST be in the root of the FlatBuffers distribution when you
+run 'flattests' or `flatsampletext`, or it will fail to load its files.*
+
+## Building for Android
+
+There is a `flatbuffers/android` directory that contains all you need to build
+the test executable on android (use the included `build_apk.sh` script, or use
+`ndk_build` / `adb` etc. as usual). Upon running, it will output to the log
+if tests succeeded or not.
+
+You may also run an android sample from inside the `flatbuffers/samples`, by
+running the `android_sample.sh` script. Optionally, you may go to the
+`flatbuffers/samples/android` folder and build the sample with the
+`build_apk.sh` script or `ndk_build` / `adb` etc.
+
+## Using FlatBuffers in your own projects
+
+For C++, there is usually no runtime to compile, as the code consists of a
+single header, `include/flatbuffers/flatbuffers.h`. You should add the
+`include` folder to your include paths. If you wish to be
+able to load schemas and/or parse text into binary buffers at runtime,
+you additionally need the other headers in `include/flatbuffers`. You must
+also compile/link `src/idl_parser.cpp` (and `src/idl_gen_text.cpp` if you
+also want to be able convert binary to text).
+
+To see how to include FlatBuffers in any of our supported languages, please
+view the [Tutorial](@ref flatbuffers_guide_tutorial) and select your appropriate
+language using the radio buttons.
+
+### Using in CMake-based projects
+If you want to use FlatBuffers in a project which already uses CMake, then a more
+robust and flexible approach is to build FlatBuffers as part of that project directly.
+This is done by making the FlatBuffers source code available to the main build
+and adding it using CMake's `add_subdirectory()` command. This has the
+significant advantage that the same compiler and linker settings are used
+between FlatBuffers and the rest of your project, so issues associated with using
+incompatible libraries (eg debug/release), etc. are avoided. This is
+particularly useful on Windows.
+
+Suppose you put FlatBuffers source code in directory `${FLATBUFFERS_SRC_DIR}`.
+To build it as part of your project, add following code to your `CMakeLists.txt` file:
+```cmake
+# Add FlatBuffers directly to our build. This defines the `flatbuffers` target.
+add_subdirectory(${FLATBUFFERS_SRC_DIR}
+                 ${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-build
+                 EXCLUDE_FROM_ALL)
+
+# Now simply link against flatbuffers as needed to your already declared target.
+# The flatbuffers target carry header search path automatically if CMake > 2.8.11.
+target_link_libraries(own_project_target PRIVATE flatbuffers)
+```
+When build your project the `flatbuffers` library will be compiled and linked 
+to a target as part of your project.
+
+#### Override default depth limit of nested objects
+To override [the depth limit of recursion](@ref flatbuffers_guide_use_cpp), 
+add this directive:
+```cmake
+set(FLATBUFFERS_MAX_PARSING_DEPTH 16)
+```
+to `CMakeLists.txt` file before `add_subdirectory(${FLATBUFFERS_SRC_DIR})` line.
+
+#### For Google Play apps
+
+For applications on Google Play that integrate this library, usage is tracked.
+This tracking is done automatically using the embedded version string
+(flatbuffer_version_string), and helps us continue to optimize it.
+Aside from consuming a few extra bytes in your application binary, it shouldn't
+affect your application at all. We use this information to let us know if
+FlatBuffers is useful and if we should continue to invest in it. Since this is
+open source, you are free to remove the version string but we would appreciate
+if you would leave it in.
diff --git a/third_party/flatbuffers/docs/source/CONTRIBUTING.md b/third_party/flatbuffers/docs/source/CONTRIBUTING.md
new file mode 120000
index 0000000..f939e75
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/CONTRIBUTING.md
@@ -0,0 +1 @@
+../../CONTRIBUTING.md
\ No newline at end of file
diff --git a/third_party/flatbuffers/docs/source/CUsage.md b/third_party/flatbuffers/docs/source/CUsage.md
new file mode 100644
index 0000000..9aafa6f
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/CUsage.md
@@ -0,0 +1,224 @@
+Use in C    {#flatbuffers_guide_use_c}
+==========
+
+The C language binding exists in a separate project named [FlatCC](https://github.com/dvidelabs/flatcc).
+
+The `flatcc` C schema compiler can generate code offline as well as
+online via a C library. It can also generate buffer verifiers and fast
+JSON parsers, printers.
+
+Great care has been taken to ensure compatibily with the main `flatc`
+project.
+
+## General Documention
+
+- [Tutorial](@ref flatbuffers_guide_tutorial) - select C as language
+  when scrolling down
+- [FlatCC Guide](https://github.com/dvidelabs/flatcc#flatcc-flatbuffers-in-c-for-c)
+- [The C Builder Interface](https://github.com/dvidelabs/flatcc/blob/master/doc/builder.md#the-builder-interface)
+- [The Monster Sample in C](https://github.com/dvidelabs/flatcc/blob/master/samples/monster/monster.c)
+- [GitHub](https://github.com/dvidelabs/flatcc)
+
+
+## Supported Platforms
+
+- Ubuntu (clang / gcc, ninja / gnu make)
+- OS-X (clang / gcc, ninja / gnu make)
+- Windows MSVC 2010, 2013, 2015
+
+CI builds recent versions of gcc, clang and MSVC on OS-X, Ubuntu, and
+Windows, and occasionally older compiler versions. See main project [Status](https://github.com/dvidelabs/flatcc#status).
+
+Other platforms may well work, including Centos, but are not tested
+regularly.
+
+The monster sample project was specifically written for C99 in order to
+follow the C++ version and for that reason it will not work with MSVC
+2010.
+
+## Modular Object Creation
+
+In the tutorial we used the call `Monster_create_as_root` to create the
+root buffer object since this is easier in simple use cases. Sometimes
+we need more modularity so we can reuse a function to create nested
+tables and root tables the same way. For this we need the
+`flatcc_builder_buffer_create_call`. It is best to keep `flatcc_builder`
+calls isolated at the top driver level, so we get:
+
+<div class="language-c">
+~~~{.c}
+  ns(Monster_ref_t) create_orc(flatcc_builder_t *B)
+  {
+    // ... same as in the tutorial.
+    return s(Monster_create(B, ...));
+  }
+
+  void create_monster_buffer()
+  {
+      uint8_t *buf;
+      size_t size;
+      flatcc_builder_t builder, *B;
+
+      // Initialize the builder object.
+      B = &builder;
+      flatcc_builder_init(B);
+      // Only use `buffer_create` without `create/start/end_as_root`.
+      flatcc_builder_buffer_create(create_orc(B));
+      // Allocate and copy buffer to user memory.
+      buf = flatcc_builder_finalize_buffer(B, &size);
+      // ... write the buffer to disk or network, or something.
+
+      free(buf);
+      flatcc_builder_clear(B);
+  }
+~~~
+</div>
+
+The same principle applies with `start/end` vs `start/end_as_root` in
+the top-down approach.
+
+
+## Top Down Example
+
+The tutorial uses a bottom up approach. In C it is also possible to use
+a top-down approach by starting and ending objects nested within each
+other. In the tutorial there is no deep nesting, so the difference is
+limited, but it shows the idea:
+
+<div class="language-c">
+<br>
+~~~{.c}
+  uint8_t treasure[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+  size_t treasure_count = c_vec_len(treasure);
+  ns(Weapon_ref_t) axe;
+
+  // NOTE: if we use end_as_root, we MUST also start as root.
+  ns(Monster_start_as_root(B));
+  ns(Monster_pos_create(B, 1.0f, 2.0f, 3.0f));
+  ns(Monster_hp_add(B, 300));
+  ns(Monster_mana_add(B, 150));
+  // We use create_str instead of add because we have no existing string reference.
+  ns(Monster_name_create_str(B, "Orc"));
+  // Again we use create because we no existing vector object, only a C-array.
+  ns(Monster_inventory_create(B, treasure, treasure_count));
+  ns(Monster_color_add(B, ns(Color_Red)));
+  if (1) {
+      ns(Monster_weapons_start(B));
+      ns(Monster_weapons_push_create(B, flatbuffers_string_create_str(B, "Sword"), 3));
+      // We reuse the axe object later. Note that we dereference a pointer
+      // because push always returns a short-term pointer to the stored element.
+      // We could also have created the axe object first and simply pushed it.
+      axe = *ns(Monster_weapons_push_create(B, flatbuffers_string_create_str(B, "Axe"), 5));
+      ns(Monster_weapons_end(B));
+  } else {
+      // We can have more control with the table elements added to a vector:
+      //
+      ns(Monster_weapons_start(B));
+      ns(Monster_weapons_push_start(B));
+      ns(Weapon_name_create_str(B, "Sword"));
+      ns(Weapon_damage_add(B, 3));
+      ns(Monster_weapons_push_end(B));
+      ns(Monster_weapons_push_start(B));
+      ns(Monster_weapons_push_start(B));
+      ns(Weapon_name_create_str(B, "Axe"));
+      ns(Weapon_damage_add(B, 5));
+      axe = *ns(Monster_weapons_push_end(B));
+      ns(Monster_weapons_end(B));
+  }
+  // Unions can get their type by using a type-specific add/create/start method.
+  ns(Monster_equipped_Weapon_add(B, axe));
+
+  ns(Monster_end_as_root(B));
+~~~
+</div>
+
+
+## Basic Reflection
+
+The C-API does support reading binary schema (.bfbs)
+files via code generated from the `reflection.fbs` schema, and an
+[example usage](https://github.com/dvidelabs/flatcc/tree/master/samples/reflection)
+shows how to use this. The reflection schema files are pre-generated
+in the [runtime distribution](https://github.com/dvidelabs/flatcc/tree/master/include/flatcc/reflection).
+
+
+## Mutations and Reflection
+
+The C-API does not support mutating reflection like C++ does, nor does
+the reader interface support mutating scalars (and it is generally
+unsafe to do so even after verification).
+
+The generated reader interface supports sorting vectors in-place after
+casting them to a mutating type because it is not practical to do so
+while building a buffer. This is covered in the builder documentation.  
+The reflection example makes use of this feature to look up objects by
+name.
+
+It is possible to build new buffers using complex objects from existing
+buffers as source. This can be very efficient due to direct copy
+semantics without endian conversion or temporary stack allocation.
+
+Scalars, structs and strings can be used as source, as well vectors of
+these.
+
+It is currently not possible to use an existing table or vector of table
+as source, but it would be possible to add support for this at some
+point.
+
+
+## Namespaces
+
+The `FLATBUFFERS_WRAP_NAMESPACE` approach used in the tutorial is convenient
+when each function has a very long namespace prefix. But it isn't always
+the best approach. If the namespace is absent, or simple and
+informative, we might as well use the prefix directly. The
+[reflection example](https://github.com/dvidelabs/flatcc/blob/master/samples/reflection/bfbs2json.c)
+mentioned above uses this approach.
+
+
+## Checking for Present Members
+
+Not all languages support testing if a field is present, but in C we can
+elaborate the reader section of the tutorial with tests for this. Recall
+that `mana` was set to the default value `150` and therefore shouldn't
+be present.
+
+<div class="language-c">
+~~~{.c}
+  int hp_present = ns(Monster_hp_is_present(monster)); // 1
+  int mana_present = ns(Monster_mana_is_present(monster)); // 0
+~~~
+</div>
+
+## Alternative ways to add a Union
+
+In the tutorial we used a single call to add a union.  Here we show
+different ways to accomplish the same thing. The last form is rarely
+used, but is the low-level way to do it. It can be used to group small
+values together in the table by adding type and data at different
+points in time.
+
+<div class="language-c">
+~~~{.c}
+   ns(Equipment_union_ref_t) equipped = ns(Equipment_as_Weapon(axe));
+   ns(Monster_equipped_add(B, equipped));
+   // or alternatively
+   ns(Monster_equipped_Weapon_add(B, axe);
+   // or alternatively
+   ns(Monster_equipped_add_type(B, ns(Equipment_Weapon));
+   ns(Monster_equipped_add_member(B, axe));
+~~~
+</div>
+
+## Why not integrate with the `flatc` tool?
+
+[It was considered how the C code generator could be integrated into the
+`flatc` tool](https://github.com/dvidelabs/flatcc/issues/1), but it
+would either require that the standalone C implementation of the schema
+compiler was dropped, or it would lead to excessive code duplication, or
+a complicated intermediate representation would have to be invented.
+Neither of these alternatives are very attractive, and it isn't a big
+deal to use the `flatcc` tool instead of `flatc` given that the
+FlatBuffers C runtime library needs to be made available regardless.
+
+
diff --git a/third_party/flatbuffers/docs/source/Compiler.md b/third_party/flatbuffers/docs/source/Compiler.md
new file mode 100644
index 0000000..7889abd
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/Compiler.md
@@ -0,0 +1,207 @@
+Using the schema compiler    {#flatbuffers_guide_using_schema_compiler}
+=========================
+
+Usage:
+
+    flatc [ GENERATOR OPTIONS ] [ -o PATH ] [ -I PATH ] FILES...
+          [ -- FILES...]
+
+The files are read and parsed in order, and can contain either schemas
+or data (see below). Data files are processed according to the definitions of
+the most recent schema specified.
+
+`--` indicates that the following files are binary files in
+FlatBuffer format conforming to the schema indicated before it.
+
+Depending on the flags passed, additional files may
+be generated for each file processed:
+
+For any schema input files, one or more generators can be specified:
+
+-   `--cpp`, `-c` : Generate a C++ header for all definitions in this file (as
+    `filename_generated.h`).
+
+-   `--java`, `-j` : Generate Java code.
+
+-   `--kotlin`, `-k` : Generate Kotlin code.
+
+-   `--csharp`, `-n` : Generate C# code.
+
+-   `--go`, `-g` : Generate Go code.
+
+-   `--python`, `-p`: Generate Python code.
+
+-   `--js`, `-s`: Generate JavaScript code.
+
+-   `--ts`: Generate TypeScript code.
+
+-   `--php`: Generate PHP code.
+
+-   `--grpc`: Generate RPC stub code for GRPC.
+
+-   `--dart`: Generate Dart code.
+
+-   `--lua`: Generate Lua code.
+
+-   `--lobster`: Generate Lobster code.
+
+-   `--rust`, `-r` : Generate Rust code.
+
+For any data input files:
+
+-   `--binary`, `-b` : If data is contained in this file, generate a
+    `filename.bin` containing the binary flatbuffer (or a different extension
+    if one is specified in the schema).
+
+-   `--json`, `-t` : If data is contained in this file, generate a
+    `filename.json` representing the data in the flatbuffer.
+
+Additional options:
+
+-   `-o PATH` : Output all generated files to PATH (either absolute, or
+    relative to the current directory). If omitted, PATH will be the
+    current directory. PATH should end in your systems path separator,
+    e.g. `/` or `\`.
+
+-   `-I PATH` : when encountering `include` statements, attempt to load the
+    files from this path. Paths will be tried in the order given, and if all
+    fail (or none are specified) it will try to load relative to the path of
+    the schema file being parsed.
+
+-   `-M` : Print make rules for generated files.
+
+-   `--strict-json` : Require & generate strict JSON (field names are enclosed
+    in quotes, no trailing commas in tables/vectors). By default, no quotes are
+    required/generated, and trailing commas are allowed.
+
+-   `--allow-non-utf8` : Pass non-UTF-8 input through parser and emit nonstandard
+    \x escapes in JSON. (Default is to raise parse error on non-UTF-8 input.)
+
+-  `--natural-utf8` : Output strings with UTF-8 as human-readable strings.
+     By default, UTF-8 characters are printed as \uXXXX escapes."
+
+-   `--defaults-json` : Output fields whose value is equal to the default value
+    when writing JSON text.
+
+-   `--no-prefix` : Don't prefix enum values in generated C++ by their enum
+    type.
+
+-   `--scoped-enums` : Use C++11 style scoped and strongly typed enums in
+    generated C++. This also implies `--no-prefix`.
+
+-   `--gen-includes` : (deprecated), this is the default behavior.
+                       If the original behavior is required (no include
+	                   statements) use `--no-includes.`
+
+-   `--no-includes` : Don't generate include statements for included schemas the
+    generated file depends on (C++).
+
+-   `--gen-mutable` : Generate additional non-const accessors for mutating
+    FlatBuffers in-place.
+
+-   `--gen-onefile` : Generate single output file for C# and Go.
+
+-   `--gen-name-strings` : Generate type name functions for C++.
+
+-   `--gen-object-api` : Generate an additional object-based API. This API is
+    more convenient for object construction and mutation than the base API,
+    at the cost of efficiency (object allocation). Recommended only to be used
+    if other options are insufficient.
+
+-   `--gen-compare`  :  Generate operator== for object-based API types.
+
+-   `--gen-nullable` : Add Clang _Nullable for C++ pointer. or @Nullable for Java.
+
+-   `--gen-generated` : Add @Generated annotation for Java.
+
+-   `--gen-all` : Generate not just code for the current schema files, but
+    for all files it includes as well. If the language uses a single file for
+    output (by default the case for C++ and JS), all code will end up in
+    this one file.
+
+-   `--cpp-include` : Adds an #include in generated file
+
+-   `--cpp-ptr-type T` : Set object API pointer type (default std::unique_ptr)
+
+-   `--cpp-str-type T` : Set object API string type (default std::string)
+    T::c_str(), T::length() and T::empty() must be supported.
+    The custom type also needs to be constructible from std::string (see the
+	--cpp-str-flex-ctor option to change this behavior).
+
+-   `--cpp-str-flex-ctor` : Don't construct custom string types by passing
+    std::string from Flatbuffers, but (char* + length). This allows efficient
+	construction of custom string types, including zero-copy construction.
+
+-   `--object-prefix` : Customise class prefix for C++ object-based API.
+
+-   `--object-suffix` : Customise class suffix for C++ object-based API.
+
+-   `--no-js-exports` : Removes Node.js style export lines (useful for JS)
+
+-   `--goog-js-export` :  Uses goog.exportsSymbol and goog.exportsProperty
+    instead of Node.js style exporting.  Needed for compatibility with the
+    Google closure compiler (useful for JS).
+
+-   `--es6-js-export` : Generates ECMAScript v6 style export definitions
+    instead of Node.js style exporting. Useful when integrating flatbuffers
+    with modern Javascript projects.
+
+-   `--go-namespace` : Generate the overrided namespace in Golang.
+
+-   `--go-import` : Generate the overrided import for flatbuffers in Golang.
+     (default is "github.com/google/flatbuffers/go").
+
+-   `--raw-binary` : Allow binaries without a file_indentifier to be read.
+    This may crash flatc given a mismatched schema.
+
+-   `--size-prefixed` : Input binaries are size prefixed buffers.
+
+-   `--proto`: Expect input files to be .proto files (protocol buffers).
+    Output the corresponding .fbs file.
+    Currently supports: `package`, `message`, `enum`, nested declarations,
+    `import` (use `-I` for paths), `extend`, `oneof`, `group`.
+    Does not support, but will skip without error: `option`, `service`,
+    `extensions`, and most everything else.
+
+-   `--oneof-union` : Translate .proto oneofs to flatbuffer unions.
+
+-   `--grpc` : Generate GRPC interfaces for the specified languages.
+
+-   `--schema`: Serialize schemas instead of JSON (use with -b). This will
+    output a binary version of the specified schema that itself corresponds
+    to the reflection/reflection.fbs schema. Loading this binary file is the
+    basis for reflection functionality.
+
+-   `--bfbs-comments`: Add doc comments to the binary schema files.
+
+-   `--conform FILE` : Specify a schema the following schemas should be
+    an evolution of. Gives errors if not. Useful to check if schema
+    modifications don't break schema evolution rules.
+
+-   `--conform-includes PATH` : Include path for the schema given with
+    `--conform PATH`.
+
+-   `--include-prefix PATH` : Prefix this path to any generated include
+    statements.
+
+-   `--keep-prefix` : Keep original prefix of schema include statement.
+
+-   `--no-fb-impor` : Don't include flatbuffers import statement for TypeScript.
+
+-   `--no-ts-reexpor` : Don't re-export imported dependencies for TypeScript.
+
+-   `--short-name` : Use short function names for JS and TypeScript.
+
+-   `--reflect-types` : Add minimal type reflection to code generation.
+
+-   `--reflect-names` : Add minimal type/name reflection.
+
+-   `--root-type T` : Select or override the default root_type.
+
+-   `--force-defaults` : Emit default values in binary output from JSON.
+
+-   `--force-empty` : When serializing from object API representation, force
+     strings and vectors to empty rather than null.
+
+NOTE: short-form options for generators are deprecated, use the long form
+whenever possible.
diff --git a/third_party/flatbuffers/docs/source/CppUsage.md b/third_party/flatbuffers/docs/source/CppUsage.md
new file mode 100644
index 0000000..7867f4b
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/CppUsage.md
@@ -0,0 +1,608 @@
+Use in C++    {#flatbuffers_guide_use_cpp}
+==========
+
+## Before you get started
+
+Before diving into the FlatBuffers usage in C++, it should be noted that
+the [Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide
+to general FlatBuffers usage in all of the supported languages (including C++).
+This page is designed to cover the nuances of FlatBuffers usage, specific to
+C++.
+
+#### Prerequisites
+
+This page assumes you have written a FlatBuffers schema and compiled it
+with the Schema Compiler. If you have not, please see
+[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler)
+and [Writing a schema](@ref flatbuffers_guide_writing_schema).
+
+Assuming you wrote a schema, say `mygame.fbs` (though the extension doesn't
+matter), you've generated a C++ header called `mygame_generated.h` using the
+compiler (e.g. `flatc -c mygame.fbs`), you can now start using this in
+your program by including the header. As noted, this header relies on
+`flatbuffers/flatbuffers.h`, which should be in your include path.
+
+## FlatBuffers C++ library code location
+
+The code for the FlatBuffers C++ library can be found at
+`flatbuffers/include/flatbuffers`. You can browse the library code on the
+[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/include/flatbuffers).
+
+## Testing the FlatBuffers C++ library
+
+The code to test the C++ library can be found at `flatbuffers/tests`.
+The test code itself is located in
+[test.cpp](https://github.com/google/flatbuffers/blob/master/tests/test.cpp).
+
+This test file is built alongside `flatc`. To review how to build the project,
+please read the [Building](@ref flatbuffers_guide_building) documentation.
+
+To run the tests, execute `flattests` from the root `flatbuffers/` directory.
+For example, on [Linux](https://en.wikipedia.org/wiki/Linux), you would simply
+run: `./flattests`.
+
+## Using the FlatBuffers C++ library
+
+*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
+example of how to use FlatBuffers in C++.*
+
+FlatBuffers supports both reading and writing FlatBuffers in C++.
+
+To use FlatBuffers in your code, first generate the C++ classes from your
+schema with the `--cpp` option to `flatc`. Then you can include both FlatBuffers
+and the generated code to read or write FlatBuffers.
+
+For example, here is how you would read a FlatBuffer binary file in C++:
+First, include the library and generated code. Then read the file into
+a `char *` array, which you pass to `GetMonster()`.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
+    #include "flatbuffers/flatbuffers.h"
+    #include "monster_test_generate.h"
+    #include <iostream> // C++ header file for printing
+    #include <fstream> // C++ header file for file access
+
+
+    std::ifstream infile;
+    infile.open("monsterdata_test.mon", std::ios::binary | std::ios::in);
+    infile.seekg(0,std::ios::end);
+    int length = infile.tellg();
+    infile.seekg(0,std::ios::beg);
+    char *data = new char[length];
+    infile.read(data, length);
+    infile.close();
+
+    auto monster = GetMonster(data);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`monster` is of type `Monster *`, and points to somewhere *inside* your
+buffer (root object pointers are not the same as `buffer_pointer` !).
+If you look in your generated header, you'll see it has
+convenient accessors for all fields, e.g. `hp()`, `mana()`, etc:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
+    std::cout << "hp : " << monster->hp() << std::endl;            // `80`
+    std::cout << "mana : " << monster->mana() << std::endl;        // default value of `150`
+    std::cout << "name : " << monster->name()->c_str() << std::endl;        // "MyMonster"
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+*Note: That we never stored a `mana` value, so it will return the default.*
+
+The following attributes are supported:
+
+-   `shared` (on a field): For string fields, this enables the usage of string
+    pooling (i.e. `CreateSharedString`) as default serialization behavior.
+
+    Specifically, `CreateXxxDirect` functions and `Pack` functions for object
+    based API (see below) will use `CreateSharedString` to create strings.
+
+## Object based API.  {#flatbuffers_cpp_object_based_api}
+
+FlatBuffers is all about memory efficiency, which is why its base API is written
+around using as little as possible of it. This does make the API clumsier
+(requiring pre-order construction of all data, and making mutation harder).
+
+For times when efficiency is less important a more convenient object based API
+can be used (through `--gen-object-api`) that is able to unpack & pack a
+FlatBuffer into objects and standard STL containers, allowing for convenient
+construction, access and mutation.
+
+To use:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
+    // Autogenerated class from table Monster.
+    MonsterT monsterobj;
+
+    // Deserialize from buffer into object.
+    UnPackTo(&monsterobj, flatbuffer);
+
+    // Update object directly like a C++ class instance.
+    cout << monsterobj->name;  // This is now a std::string!
+    monsterobj->name = "Bob";  // Change the name.
+
+    // Serialize into new flatbuffer.
+    FlatBufferBuilder fbb;
+    Pack(fbb, &monsterobj);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following attributes are specific to the object-based API code generation:
+
+-   `native_inline` (on a field): Because FlatBuffer tables and structs are
+    optionally present in a given buffer, they are best represented as pointers
+    (specifically std::unique_ptrs) in the native class since they can be null.
+    This attribute changes the member declaration to use the type directly
+    rather than wrapped in a unique_ptr.
+
+-   `native_default`: "value" (on a field): For members that are declared
+    "native_inline", the value specified with this attribute will be included
+    verbatim in the class constructor initializer list for this member.
+
+-   `native_custom_alloc`:"custom_allocator" (on a table or struct): When using the
+    object-based API all generated NativeTables that  are allocated when unpacking
+    your  flatbuffer will use "custom allocator". The allocator is also used by
+    any std::vector that appears in a table defined with `native_custom_alloc`.
+    This can be  used to provide allocation from a pool for example, for faster
+    unpacking when using the object-based API.
+
+    Minimal Example:
+
+    schema:
+
+    table mytable(native_custom_alloc:"custom_allocator") {
+      ...
+    }
+
+    with custom_allocator defined before flatbuffers.h is included, as:
+
+    template <typename T> struct custom_allocator : public std::allocator<T> {
+
+      typedef T *pointer;
+
+      template <class U>
+      struct rebind {
+        typedef custom_allocator<U> other;
+      };
+
+      pointer allocate(const std::size_t n) {
+        return std::allocator<T>::allocate(n);
+      }
+
+      void deallocate(T* ptr, std::size_t n) {
+        return std::allocator<T>::deallocate(ptr,n);
+      }
+
+      custom_allocator() throw() {}
+      template <class U>
+      custom_allocator(const custom_allocator<U>&) throw() {}
+    };
+
+-   `native_type`' "type" (on a struct): In some cases, a more optimal C++ data
+    type exists for a given struct.  For example, the following schema:
+
+      struct Vec2 {
+        x: float;
+        y: float;
+      }
+
+    generates the following Object-Based API class:
+
+      struct Vec2T : flatbuffers::NativeTable {
+        float x;
+        float y;
+      };
+
+    However, it can be useful to instead use a user-defined C++ type since it
+    can provide more functionality, eg.
+
+      struct vector2 {
+        float x = 0, y = 0;
+        vector2 operator+(vector2 rhs) const { ... }
+        vector2 operator-(vector2 rhs) const { ... }
+        float length() const { ... }
+        // etc.
+      };
+
+    The `native_type` attribute will replace the usage of the generated class
+    with the given type.  So, continuing with the example, the generated
+    code would use |vector2| in place of |Vec2T| for all generated code.
+
+    However, becuase the native_type is unknown to flatbuffers, the user must
+    provide the following functions to aide in the serialization process:
+
+      namespace flatbuffers {
+        FlatbufferStruct Pack(const native_type& obj);
+        native_type UnPack(const FlatbufferStruct& obj);
+      }
+
+Finally, the following top-level attribute
+
+-   `native_include`: "path" (at file level): Because the `native_type` attribute
+    can be used to introduce types that are unknown to flatbuffers, it may be
+    necessary to include "external" header files in the generated code.  This
+    attribute can be used to directly add an #include directive to the top of
+    the generated code that includes the specified path directly.
+
+-   `force_align`: this attribute may not be respected in the object API,
+    depending on the aligned of the allocator used with `new`.
+
+# External references.
+
+An additional feature of the object API is the ability to allow you to load
+multiple independent FlatBuffers, and have them refer to eachothers objects
+using hashes which are then represented as typed pointers in the object API.
+
+To make this work have a field in the objects you want to referred to which is
+using the string hashing feature (see `hash` attribute in the
+[schema](@ref flatbuffers_guide_writing_schema) documentation). Then you have
+a similar hash in the field referring to it, along with a `cpp_type`
+attribute specifying the C++ type this will refer to (this can be any C++
+type, and will get a `*` added).
+
+Then, in JSON or however you create these buffers, make sure they use the
+same string (or hash).
+
+When you call `UnPack` (or `Create`), you'll need a function that maps from
+hash to the object (see `resolver_function_t` for details).
+
+# Using different pointer types.
+
+By default the object tree is built out of `std::unique_ptr`, but you can
+influence this either globally (using the `--cpp-ptr-type` argument to
+`flatc`) or per field (using the `cpp_ptr_type` attribute) to by any smart
+pointer type (`my_ptr<T>`), or by specifying `naked` as the type to get `T *`
+pointers. Unlike the smart pointers, naked pointers do not manage memory for
+you, so you'll have to manage their lifecycles manually.  To reference the
+pointer type specified by the `--cpp-ptr-type` argument to `flatc` from a
+flatbuffer field set the `cpp_ptr_type` attribute to `default_ptr_type`.
+
+# Using different string type.
+
+By default the object tree is built out of `std::string`, but you can
+influence this either globally (using the `--cpp-str-type` argument to
+`flatc`) or per field using the `cpp_str_type` attribute.
+
+The type must support T::c_str(), T::length() and T::empty() as member functions.
+
+Further, the type must be constructible from std::string, as by default a
+std::string instance is constructed and then used to initialize the custom
+string type. This behavior impedes efficient and zero-copy construction of
+custom string types; the `--cpp-str-flex-ctor` argument to `flatc` or the
+per field attribute `cpp_str_flex_ctor` can be used to change this behavior,
+so that the custom string type is constructed by passing the pointer and
+length of the FlatBuffers String. The custom string class will require a
+constructor in the following format: custom_str_class(const char *, size_t).
+Please note that the character array is not guaranteed to be NULL terminated,
+you should always use the provided size to determine end of string.
+
+## Reflection (& Resizing)
+
+There is experimental support for reflection in FlatBuffers, allowing you to
+read and write data even if you don't know the exact format of a buffer, and
+even allows you to change sizes of strings and vectors in-place.
+
+The way this works is very elegant; there is actually a FlatBuffer schema that
+describes schemas (!) which you can find in `reflection/reflection.fbs`.
+The compiler, `flatc`, can write out any schemas it has just parsed as a binary
+FlatBuffer, corresponding to this meta-schema.
+
+Loading in one of these binary schemas at runtime allows you traverse any
+FlatBuffer data that corresponds to it without knowing the exact format. You
+can query what fields are present, and then read/write them after.
+
+For convenient field manipulation, you can include the header
+`flatbuffers/reflection.h` which includes both the generated code from the meta
+schema, as well as a lot of helper functions.
+
+And example of usage, for the time being, can be found in
+`test.cpp/ReflectionTest()`.
+
+## Mini Reflection
+
+A more limited form of reflection is available for direct inclusion in
+generated code, which doesn't any (binary) schema access at all. It was designed
+to keep the overhead of reflection as low as possible (on the order of 2-6
+bytes per field added to your executable), but doesn't contain all the
+information the (binary) schema contains.
+
+You add this information to your generated code by specifying `--reflect-types`
+(or instead `--reflect-names` if you also want field / enum names).
+
+You can now use this information, for example to print a FlatBuffer to text:
+
+    auto s = flatbuffers::FlatBufferToString(flatbuf, MonsterTypeTable());
+
+`MonsterTypeTable()` is declared in the generated code for each type. The
+string produced is very similar to the JSON produced by the `Parser` based
+text generator.
+
+You'll need `flatbuffers/minireflect.h` for this functionality. In there is also
+a convenient visitor/iterator so you can write your own output / functionality
+based on the mini reflection tables without having to know the FlatBuffers or
+reflection encoding.
+
+## Storing maps / dictionaries in a FlatBuffer
+
+FlatBuffers doesn't support maps natively, but there is support to
+emulate their behavior with vectors and binary search, which means you
+can have fast lookups directly from a FlatBuffer without having to unpack
+your data into a `std::map` or similar.
+
+To use it:
+-   Designate one of the fields in a table as they "key" field. You do this
+    by setting the `key` attribute on this field, e.g.
+    `name:string (key)`.
+    You may only have one key field, and it must be of string or scalar type.
+-   Write out tables of this type as usual, collect their offsets in an
+    array or vector.
+-   Instead of `CreateVector`, call `CreateVectorOfSortedTables`,
+    which will first sort all offsets such that the tables they refer to
+    are sorted by the key field, then serialize it.
+-   Now when you're accessing the FlatBuffer, you can use `Vector::LookupByKey`
+    instead of just `Vector::Get` to access elements of the vector, e.g.:
+    `myvector->LookupByKey("Fred")`, which returns a pointer to the
+    corresponding table type, or `nullptr` if not found.
+    `LookupByKey` performs a binary search, so should have a similar speed to
+    `std::map`, though may be faster because of better caching. `LookupByKey`
+    only works if the vector has been sorted, it will likely not find elements
+    if it hasn't been sorted.
+
+## Direct memory access
+
+As you can see from the above examples, all elements in a buffer are
+accessed through generated accessors. This is because everything is
+stored in little endian format on all platforms (the accessor
+performs a swap operation on big endian machines), and also because
+the layout of things is generally not known to the user.
+
+For structs, layout is deterministic and guaranteed to be the same
+across platforms (scalars are aligned to their
+own size, and structs themselves to their largest member), and you
+are allowed to access this memory directly by using `sizeof()` and
+`memcpy` on the pointer to a struct, or even an array of structs.
+
+To compute offsets to sub-elements of a struct, make sure they
+are a structs themselves, as then you can use the pointers to
+figure out the offset without having to hardcode it. This is
+handy for use of arrays of structs with calls like `glVertexAttribPointer`
+in OpenGL or similar APIs.
+
+It is important to note is that structs are still little endian on all
+machines, so only use tricks like this if you can guarantee you're not
+shipping on a big endian machine (an `assert(FLATBUFFERS_LITTLEENDIAN)`
+would be wise).
+
+## Access of untrusted buffers
+
+The generated accessor functions access fields over offsets, which is
+very quick. These offsets are not verified at run-time, so a malformed
+buffer could cause a program to crash by accessing random memory.
+
+When you're processing large amounts of data from a source you know (e.g.
+your own generated data on disk), this is acceptable, but when reading
+data from the network that can potentially have been modified by an
+attacker, this is undesirable.
+
+For this reason, you can optionally use a buffer verifier before you
+access the data. This verifier will check all offsets, all sizes of
+fields, and null termination of strings to ensure that when a buffer
+is accessed, all reads will end up inside the buffer.
+
+Each root type will have a verification function generated for it,
+e.g. for `Monster`, you can call:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
+	bool ok = VerifyMonsterBuffer(Verifier(buf, len));
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+if `ok` is true, the buffer is safe to read.
+
+Besides untrusted data, this function may be useful to call in debug
+mode, as extra insurance against data being corrupted somewhere along
+the way.
+
+While verifying a buffer isn't "free", it is typically faster than
+a full traversal (since any scalar data is not actually touched),
+and since it may cause the buffer to be brought into cache before
+reading, the actual overhead may be even lower than expected.
+
+In specialized cases where a denial of service attack is possible,
+the verifier has two additional constructor arguments that allow
+you to limit the nesting depth and total amount of tables the
+verifier may encounter before declaring the buffer malformed. The default is
+`Verifier(buf, len, 64 /* max depth */, 1000000, /* max tables */)` which
+should be sufficient for most uses.
+
+## Text & schema parsing
+
+Using binary buffers with the generated header provides a super low
+overhead use of FlatBuffer data. There are, however, times when you want
+to use text formats, for example because it interacts better with source
+control, or you want to give your users easy access to data.
+
+Another reason might be that you already have a lot of data in JSON
+format, or a tool that generates JSON, and if you can write a schema for
+it, this will provide you an easy way to use that data directly.
+
+(see the schema documentation for some specifics on the JSON format
+accepted).
+
+There are two ways to use text formats:
+
+#### Using the compiler as a conversion tool
+
+This is the preferred path, as it doesn't require you to add any new
+code to your program, and is maximally efficient since you can ship with
+binary data. The disadvantage is that it is an extra step for your
+users/developers to perform, though you might be able to automate it.
+
+    flatc -b myschema.fbs mydata.json
+
+This will generate the binary file `mydata_wire.bin` which can be loaded
+as before.
+
+#### Making your program capable of loading text directly
+
+This gives you maximum flexibility. You could even opt to support both,
+i.e. check for both files, and regenerate the binary from text when
+required, otherwise just load the binary.
+
+This option is currently only available for C++, or Java through JNI.
+
+As mentioned in the section "Building" above, this technique requires
+you to link a few more files into your program, and you'll want to include
+`flatbuffers/idl.h`.
+
+Load text (either a schema or json) into an in-memory buffer (there is a
+convenient `LoadFile()` utility function in `flatbuffers/util.h` if you
+wish). Construct a parser:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
+    flatbuffers::Parser parser;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Now you can parse any number of text files in sequence:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
+    parser.Parse(text_file.c_str());
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This works similarly to how the command-line compiler works: a sequence
+of files parsed by the same `Parser` object allow later files to
+reference definitions in earlier files. Typically this means you first
+load a schema file (which populates `Parser` with definitions), followed
+by one or more JSON files.
+
+As optional argument to `Parse`, you may specify a null-terminated list of
+include paths. If not specified, any include statements try to resolve from
+the current directory.
+
+If there were any parsing errors, `Parse` will return `false`, and
+`Parser::err` contains a human readable error string with a line number
+etc, which you should present to the creator of that file.
+
+After each JSON file, the `Parser::fbb` member variable is the
+`FlatBufferBuilder` that contains the binary buffer version of that
+file, that you can access as described above.
+
+`samples/sample_text.cpp` is a code sample showing the above operations.
+
+## Threading
+
+Reading a FlatBuffer does not touch any memory outside the original buffer,
+and is entirely read-only (all const), so is safe to access from multiple
+threads even without synchronisation primitives.
+
+Creating a FlatBuffer is not thread safe. All state related to building
+a FlatBuffer is contained in a FlatBufferBuilder instance, and no memory
+outside of it is touched. To make this thread safe, either do not
+share instances of FlatBufferBuilder between threads (recommended), or
+manually wrap it in synchronisation primites. There's no automatic way to
+accomplish this, by design, as we feel multithreaded construction
+of a single buffer will be rare, and synchronisation overhead would be costly.
+
+## Advanced union features
+
+The C++ implementation currently supports vectors of unions (i.e. you can
+declare a field as `[T]` where `T` is a union type instead of a table type). It
+also supports structs and strings in unions, besides tables.
+
+For an example of these features, see `tests/union_vector`, and
+`UnionVectorTest` in `test.cpp`.
+
+Since these features haven't been ported to other languages yet, if you
+choose to use them, you won't be able to use these buffers in other languages
+(`flatc` will refuse to compile a schema that uses these features).
+
+These features reduce the amount of "table wrapping" that was previously
+needed to use unions.
+
+To use scalars, simply wrap them in a struct.
+
+## Depth limit of nested objects and stack-overflow control
+The parser of Flatbuffers schema or json-files is kind of recursive parser.
+To avoid stack-overflow problem the parser has a built-in limiter of
+recursion depth. Number of nested declarations in a schema or number of
+nested json-objects is limited. By default, this depth limit set to `64`.
+It is possible to override this limit with `FLATBUFFERS_MAX_PARSING_DEPTH`
+definition. This definition can be helpful for testing purposes or embedded
+applications. For details see [build](@ref flatbuffers_guide_building) of
+CMake-based projects.
+
+## Dependence from C-locale {#flatbuffers_locale_cpp}
+The Flatbuffers [grammar](@ref flatbuffers grammar) uses ASCII
+character set for identifiers, alphanumeric literals, reserved words.
+
+Internal implementation of the Flatbuffers depends from functions which
+depend from C-locale: `strtod()` or `strtof()`, for example.
+The library expects the dot `.` symbol as the separator of an integer
+part from the fractional part of a float number.
+Another separator symbols (`,` for example) will break the compatibility
+and may lead to an error while parsing a Flatbuffers schema or a json file.
+
+The Standard C locale is a global resource, there is only one locale for
+the entire application. Some modern compilers and platforms have
+locale-independent or locale-narrow functions `strtof_l`, `strtod_l`,
+`strtoll_l`, `strtoull_l` to resolve this dependency.
+These functions use specified locale rather than the global or per-thread
+locale instead. They are part of POSIX-2008 but not part of the C/C++
+standard library, therefore, may be missing on some platforms.
+The Flatbuffers library try to detect these functions at configuration and
+compile time:
+- CMake `"CMakeLists.txt"`:
+  - Check existence of `strtol_l` and `strtod_l` in the `<stdlib.h>`.
+- Compile-time `"/include/base.h"`:
+  - `_MSC_VER >= 1900`: MSVC2012 or higher if build with MSVC.
+  - `_XOPEN_SOURCE>=700`: POSIX-2008 if build with GCC/Clang.
+
+After detection, the definition `FLATBUFFERS_LOCALE_INDEPENDENT` will be
+set to `0` or `1`.
+To override or stop this detection use CMake `-DFLATBUFFERS_LOCALE_INDEPENDENT={0|1}`
+or predefine `FLATBUFFERS_LOCALE_INDEPENDENT` symbol.
+
+To test the compatibility of the Flatbuffers library with
+a specific locale use the environment variable `FLATBUFFERS_TEST_LOCALE`:
+```sh
+>FLATBUFFERS_TEST_LOCALE="" ./flattests
+>FLATBUFFERS_TEST_LOCALE="ru_RU.CP1251" ./flattests
+```
+
+## Support of floating-point numbers
+The Flatbuffers library assumes that a C++ compiler and a CPU are 
+compatible with the `IEEE-754` floating-point standard.
+The schema and json parser may fail if `fast-math` or `/fp:fast` mode is active.
+
+### Support of hexadecimal and special floating-point numbers
+According to the [grammar](@ref flatbuffers_grammar) `fbs` and `json` files 
+may use hexadecimal and special (`NaN`, `Inf`) floating-point literals.
+The Flatbuffers uses `strtof` and `strtod` functions to parse floating-point
+literals. The Flatbuffers library has a code to detect a compiler compatibility 
+with the literals. If necessary conditions are met the preprocessor constant
+`FLATBUFFERS_HAS_NEW_STRTOD` will be set to `1`.
+The support of floating-point literals will be limited at compile time
+if `FLATBUFFERS_HAS_NEW_STRTOD` constant is less than `1`.
+In this case, schemas with hexadecimal or special literals cannot be used.
+
+### Comparison of floating-point NaN values
+The floating-point `NaN` (`not a number`) is special value which 
+representing an undefined or unrepresentable value.
+`NaN` may be explicitly assigned to variables, typically as a representation 
+for missing values or may be a result of a mathematical operation.
+The `IEEE-754` defines two kind of `NaNs`:
+- Quiet NaNs, or `qNaNs`.
+- Signaling NaNs, or `sNaNs`.
+
+According to the `IEEE-754`, a comparison with `NaN` always returns 
+an unordered result even when compared with itself. As a result, a whole 
+Flatbuffers object will be not equal to itself if has one or more `NaN`.
+Flatbuffers scalar fields that have the default value are not actually stored 
+in the serialized data but are generated in code (see [Writing a schema](@ref flatbuffers_guide_writing_schema)).
+Scalar fields with `NaN` defaults break this behavior.
+If a schema has a lot of `NaN` defaults the Flatbuffers can override 
+the unordered comparison by the ordered: `(NaN==NaN)->true`.
+This ordered comparison is enabled when compiling a program with the symbol
+`FLATBUFFERS_NAN_DEFAULTS` defined.
+Additional computations added by `FLATBUFFERS_NAN_DEFAULTS` are very cheap
+if GCC or Clang used. These compilers have a compile-time implementation 
+of `isnan` checking which MSVC does not.
+
+<br>
diff --git a/third_party/flatbuffers/docs/source/DartUsage.md b/third_party/flatbuffers/docs/source/DartUsage.md
new file mode 100644
index 0000000..6670cc5
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/DartUsage.md
@@ -0,0 +1,108 @@
+Use in Dart    {#flatbuffers_guide_use_dart}
+===========
+
+## Before you get started
+
+Before diving into the FlatBuffers usage in Dart, it should be noted that
+the [Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide
+to general FlatBuffers usage in all of the supported languages (including Dart).
+This page is designed to cover the nuances of FlatBuffers usage, specific to
+Dart.
+
+You should also have read the [Building](@ref flatbuffers_guide_building)
+documentation to build `flatc` and should be familiar with
+[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) and
+[Writing a schema](@ref flatbuffers_guide_writing_schema).
+
+## FlatBuffers Dart library code location
+
+The code for the FlatBuffers Dart library can be found at
+`flatbuffers/dart`. You can browse the library code on the [FlatBuffers
+GitHub page](https://github.com/google/flatbuffers/tree/master/dart).
+
+## Testing the FlatBuffers Dart library
+
+The code to test the Dart library can be found at `flatbuffers/tests`.
+The test code itself is located in [dart_test.dart](https://github.com/google/
+flatbuffers/blob/master/tests/dart_test.dart).
+
+To run the tests, use the [DartTest.sh](https://github.com/google/flatbuffers/
+blob/master/tests/DartTest.sh) shell script.
+
+*Note: The shell script requires the [Dart SDK](https://www.dartlang.org/tools/sdk)
+to be installed.*
+
+## Using the FlatBuffers Dart library
+
+*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
+example of how to use FlatBuffers in Dart.*
+
+FlatBuffers supports reading and writing binary FlatBuffers in Dart.
+
+To use FlatBuffers in your own code, first generate Dart classes from your
+schema with the `--dart` option to `flatc`. Then you can include both FlatBuffers
+and the generated code to read or write a FlatBuffer.
+
+For example, here is how you would read a FlatBuffer binary file in Dart: First,
+include the library and generated code. Then read a FlatBuffer binary file into
+a `List<int>`, which you pass to the factory constructor for `Monster`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.dart}
+import 'dart:io' as io;
+
+import 'package:flat_buffers/flat_buffers.dart' as fb;
+import './monster_my_game.sample_generated.dart' as myGame;
+
+List<int> data = await new io.File('monster.dat').readAsBytes();
+var monster = new myGame.Monster(data);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Now you can access values like this:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.dart}
+var hp = monster.hp;
+var pos = monster.pos;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+## Differences from the Dart SDK Front End flat_buffers
+
+The work in this repository is signfiicantly based on the implementation used
+internally by the Dart SDK in the front end/analyzer package. Several
+significant changes have been made.
+
+1. Support for packed boolean lists has been removed.  This is not standard
+   in other implementations and is not compatible with them.  Do note that,
+   like in the JavaScript implementation, __null values in boolean lists
+   will be treated as false__.  It is also still entirely possible to pack data
+   in a single scalar field, but that would have to be done on the application
+   side.
+2. The SDK implementation supports enums with regular Dart enums, which
+   works if enums are always indexed at 1; however, FlatBuffers does not
+   require that.  This implementation uses specialized enum-like classes to
+   ensure proper mapping from FlatBuffers to Dart and other platforms.
+3. The SDK implementation does not appear to support FlatBuffer structs or
+   vectors of structs - it treated everything as a built-in scalar or a table.
+   This implementation treats structs in a way that is compatible with other
+   non-Dart implementations, and properly handles vectors of structs.  Many of
+   the methods prefixed with 'low' have been prepurposed to support this.
+4. The SDK implementation treats int64 and uint64 as float64s. This
+   implementation does not.  This may cause problems with JavaScript
+   compatibility - however, it should be possible to use the JavaScript
+   implementation, or to do a customized implementation that treats all 64 bit
+   numbers as floats.  Supporting the Dart VM and Flutter was a more important
+   goal of this implementation.  Support for 16 bit integers was also added.
+5. The code generation in this offers an "ObjectBuilder", which generates code
+   very similar to the SDK classes that consume FlatBuffers, as well as Builder
+   classes, which produces code which more closely resembles the builders in 
+   other languages. The ObjectBuilder classes are easier to use, at the cost of
+   additional references allocated.
+
+## Text Parsing
+
+There currently is no support for parsing text (Schema's and JSON) directly
+from Dart, though you could use the C++ parser through Dart Native Extensions.
+Please see the C++ documentation for more on text parsing (note that this is
+not currently an option in Flutter - follow [this issue](https://github.com/flutter/flutter/issues/7053)
+for the latest).
+
+<br>
diff --git a/third_party/flatbuffers/docs/source/FlatBuffers.md b/third_party/flatbuffers/docs/source/FlatBuffers.md
new file mode 100644
index 0000000..dc77500
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/FlatBuffers.md
@@ -0,0 +1,180 @@
+FlatBuffers    {#flatbuffers_index}
+===========
+
+# Overview {#flatbuffers_overview}
+
+[FlatBuffers](@ref flatbuffers_overview) is an efficient cross platform
+serialization library for C++, C#, C, Go, Java, Kotlin, JavaScript, Lobster, Lua, TypeScript, PHP, Python, and Rust.
+It was originally created at Google for game development and other
+performance-critical applications.
+
+It is available as Open Source on [GitHub](http://github.com/google/flatbuffers)
+under the Apache license, v2 (see LICENSE.txt).
+
+## Why use FlatBuffers?
+
+-   **Access to serialized data without parsing/unpacking** - What sets
+    FlatBuffers apart is that it represents hierarchical data in a flat
+    binary buffer in such a way that it can still be accessed directly
+    without parsing/unpacking, while also still supporting data
+    structure evolution (forwards/backwards compatibility).
+
+-   **Memory efficiency and speed** - The only memory needed to access
+    your data is that of the buffer. It requires 0 additional allocations
+    (in C++, other languages may vary). FlatBuffers is also very
+    suitable for use with mmap (or streaming), requiring only part of the
+    buffer to be in memory. Access is close to the speed of raw
+    struct access with only one extra indirection (a kind of vtable) to
+    allow for format evolution and optional fields. It is aimed at
+    projects where spending time and space (many memory allocations) to
+    be able to access or construct serialized data is undesirable, such
+    as in games or any other performance sensitive applications. See the
+    [benchmarks](@ref flatbuffers_benchmarks) for details.
+
+-   **Flexible** - Optional fields means not only do you get great
+    forwards and backwards compatibility (increasingly important for
+    long-lived games: don't have to update all data with each new
+    version!). It also means you have a lot of choice in what data you
+    write and what data you don't, and how you design data structures.
+
+-   **Tiny code footprint** - Small amounts of generated code, and just
+    a single small header as the minimum dependency, which is very easy
+    to integrate. Again, see the benchmark section for details.
+
+-   **Strongly typed** - Errors happen at compile time rather than
+    manually having to write repetitive and error prone run-time checks.
+    Useful code can be generated for you.
+
+-   **Convenient to use** - Generated C++ code allows for terse access
+    & construction code. Then there's optional functionality for parsing
+    schemas and JSON-like text representations at runtime efficiently if
+    needed (faster and more memory efficient than other JSON
+    parsers).
+
+    Java, Kotlin and Go code supports object-reuse. C# has efficient struct based
+    accessors.
+
+-   **Cross platform code with no dependencies** - C++ code will work
+    with any recent gcc/clang and VS2010. Comes with build files for the tests &
+    samples (Android .mk files, and cmake for all other platforms).
+
+### Why not use Protocol Buffers, or .. ?
+
+Protocol Buffers is indeed relatively similar to FlatBuffers,
+with the primary difference being that FlatBuffers does not need a parsing/
+unpacking step to a secondary representation before you can
+access data, often coupled with per-object memory allocation. The code
+is an order of magnitude bigger, too. Protocol Buffers has neither optional
+text import/export nor schema language features like unions.
+
+### But all the cool kids use JSON!
+
+JSON is very readable (which is why we use it as our optional text
+format) and very convenient when used together with dynamically typed
+languages (such as JavaScript). When serializing data from statically
+typed languages, however, JSON not only has the obvious drawback of runtime
+inefficiency, but also forces you to write *more* code to access data
+(counterintuitively) due to its dynamic-typing serialization system.
+In this context, it is only a better choice for systems that have very
+little to no information ahead of time about what data needs to be stored.
+
+If you do need to store data that doesn't fit a schema, FlatBuffers also
+offers a schema-less (self-describing) version!
+
+Read more about the "why" of FlatBuffers in the
+[white paper](@ref flatbuffers_white_paper).
+
+### Who uses FlatBuffers?
+-   [Cocos2d-x](http://www.cocos2d-x.org/), the #1 open source mobile game
+    engine, uses it to serialize all their
+    [game data](http://www.cocos2d-x.org/reference/native-cpp/V3.5/d7/d2d/namespaceflatbuffers.html).
+-   [Facebook](http://facebook.com/) uses it for client-server communication in
+    their Android app. They have a nice
+    [article](https://code.facebook.com/posts/872547912839369/improving-facebook-s-performance-on-android-with-flatbuffers/)
+    explaining how it speeds up loading their posts.
+-   [Fun Propulsion Labs](https://developers.google.com/games/#Tools)
+    at Google uses it extensively in all their libraries and games.
+
+## Usage in brief
+
+This section is a quick rundown of how to use this system. Subsequent
+sections provide a more in-depth usage guide.
+
+-   Write a schema file that allows you to define the data structures
+    you may want to serialize. Fields can have a scalar type
+    (ints/floats of all sizes), or they can be a: string; array of any type;
+    reference to yet another object; or, a set of possible objects (unions).
+    Fields are optional and have defaults, so they don't need to be
+    present for every object instance.
+
+-   Use `flatc` (the FlatBuffer compiler) to generate a C++ header (or
+    Java/Kotlin/C#/Go/Python.. classes) with helper classes to access and construct
+    serialized data. This header (say `mydata_generated.h`) only depends on
+    `flatbuffers.h`, which defines the core functionality.
+
+-   Use the `FlatBufferBuilder` class to construct a flat binary buffer.
+    The generated functions allow you to add objects to this
+    buffer recursively, often as simply as making a single function call.
+
+-   Store or send your buffer somewhere!
+
+-   When reading it back, you can obtain the pointer to the root object
+    from the binary buffer, and from there traverse it conveniently
+    in-place with `object->field()`.
+
+## In-depth documentation
+
+-   How to [build the compiler](@ref flatbuffers_guide_building) and samples on
+    various platforms.
+-   How to [use the compiler](@ref flatbuffers_guide_using_schema_compiler).
+-   How to [write a schema](@ref flatbuffers_guide_writing_schema).
+-   How to [use the generated C++ code](@ref flatbuffers_guide_use_cpp) in your
+    own programs.
+-   How to [use the generated Java/C# code](@ref flatbuffers_guide_use_java_c-sharp)
+    in your own programs.
+-   How to [use the generated Kotlin code](@ref flatbuffers_guide_use_kotlin)
+        in your own programs.
+-   How to [use the generated Go code](@ref flatbuffers_guide_use_go) in your
+    own programs.
+-   How to [use the generated Lua code](@ref flatbuffers_guide_use_lua) in your
+    own programs.
+-   How to [use the generated JavaScript code](@ref flatbuffers_guide_use_javascript) in your
+    own programs.
+-   How to [use the generated TypeScript code](@ref flatbuffers_guide_use_typescript) in your
+    own programs.
+-   How to [use FlatBuffers in C with `flatcc`](@ref flatbuffers_guide_use_c) in your
+    own programs.
+-   How to [use the generated Lobster code](@ref flatbuffers_guide_use_lobster) in your
+    own programs.
+-   How to [use the generated Rust code](@ref flatbuffers_guide_use_rust) in your
+    own programs.
+-   [Support matrix](@ref flatbuffers_support) for platforms/languages/features.
+-   Some [benchmarks](@ref flatbuffers_benchmarks) showing the advantage of
+    using FlatBuffers.
+-   A [white paper](@ref flatbuffers_white_paper) explaining the "why" of
+    FlatBuffers.
+-   How to use the [schema-less](@ref flexbuffers) version of
+    FlatBuffers.
+-   A description of the [internals](@ref flatbuffers_internals) of FlatBuffers.
+-   A formal [grammar](@ref flatbuffers_grammar) of the schema language.
+
+## Online resources
+
+-   [GitHub repository](http://github.com/google/flatbuffers)
+-   [Landing page](http://google.github.io/flatbuffers)
+-   [FlatBuffers Google Group](https://groups.google.com/forum/#!forum/flatbuffers)
+-   [FlatBuffers Issues Tracker](http://github.com/google/flatbuffers/issues)
+-   Independent implementations & tools:
+    - [FlatCC](https://github.com/dvidelabs/flatcc) Alternative FlatBuffers
+      parser, code generator and runtime all in C.
+-   Videos:
+    - Colt's [DevByte](https://www.youtube.com/watch?v=iQTxMkSJ1dQ).
+    - GDC 2015 [Lightning Talk](https://www.youtube.com/watch?v=olmL1fUnQAQ).
+    - FlatBuffers for [Go](https://www.youtube.com/watch?v=-BPVId_lA5w).
+    - Evolution of FlatBuffers
+      [visualization](https://www.youtube.com/watch?v=a0QE0xS8rKM).
+-   Useful documentation created by others:
+    - [FlatBuffers in Go](https://rwinslow.com/tags/flatbuffers/)
+    - [FlatBuffers in Android](http://frogermcs.github.io/flatbuffers-in-android-introdution/)
+    - [Parsing JSON to FlatBuffers in Java](http://frogermcs.github.io/json-parsing-with-flatbuffers-in-android/)
+    - [FlatBuffers in Unity](http://exiin.com/blog/flatbuffers-for-unity-sample-code/)
diff --git a/third_party/flatbuffers/docs/source/FlexBuffers.md b/third_party/flatbuffers/docs/source/FlexBuffers.md
new file mode 100644
index 0000000..a089df3
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/FlexBuffers.md
@@ -0,0 +1,166 @@
+FlexBuffers    {#flexbuffers}
+==========
+
+FlatBuffers was designed around schemas, because when you want maximum
+performance and data consistency, strong typing is helpful.
+
+There are however times when you want to store data that doesn't fit a
+schema, because you can't know ahead of time what all needs to be stored.
+
+For this, FlatBuffers has a dedicated format, called FlexBuffers.
+This is a binary format that can be used in conjunction
+with FlatBuffers (by storing a part of a buffer in FlexBuffers
+format), or also as its own independent serialization format.
+
+While it loses the strong typing, you retain the most unique advantage
+FlatBuffers has over other serialization formats (schema-based or not):
+FlexBuffers can also be accessed without parsing / copying / object allocation.
+This is a huge win in efficiency / memory friendly-ness, and allows unique
+use cases such as mmap-ing large amounts of free-form data.
+
+FlexBuffers' design and implementation allows for a very compact encoding,
+combining automatic pooling of strings with automatic sizing of containers to
+their smallest possible representation (8/16/32/64 bits). Many values and
+offsets can be encoded in just 8 bits. While a schema-less representation is
+usually more bulky because of the need to be self-descriptive, FlexBuffers
+generates smaller binaries for many cases than regular FlatBuffers.
+
+FlexBuffers is still slower than regular FlatBuffers though, so we recommend to
+only use it if you need it.
+
+
+# Usage
+
+This is for C++, other languages may follow.
+
+Include the header `flexbuffers.h`, which in turn depends on `flatbuffers.h`
+and `util.h`.
+
+To create a buffer:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
+flexbuffers::Builder fbb;
+fbb.Int(13);
+fbb.Finish();
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You create any value, followed by `Finish`. Unlike FlatBuffers which requires
+the root value to be a table, here any value can be the root, including a lonely
+int value.
+
+You can now access the `std::vector<uint8_t>` that contains the encoded value
+as `fbb.GetBuffer()`. Write it, send it, or store it in a parent FlatBuffer. In
+this case, the buffer is just 3 bytes in size.
+
+To read this value back, you could just say:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
+auto root = flexbuffers::GetRoot(my_buffer);
+int64_t i = root.AsInt64();
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+FlexBuffers stores ints only as big as needed, so it doesn't differentiate
+between different sizes of ints. You can ask for the 64 bit version,
+regardless of what you put in. In fact, since you demand to read the root
+as an int, if you supply a buffer that actually contains a float, or a
+string with numbers in it, it will convert it for you on the fly as well,
+or return 0 if it can't. If instead you actually want to know what is inside
+the buffer before you access it, you can call `root.GetType()` or `root.IsInt()`
+etc.
+
+Here's a slightly more complex value you could write instead of `fbb.Int` above:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
+fbb.Map([&]() {
+  fbb.Vector("vec", [&]() {
+    fbb.Int(-100);
+    fbb.String("Fred");
+    fbb.IndirectFloat(4.0f);
+  });
+  fbb.UInt("foo", 100);
+});
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This stores the equivalent of the JSON value
+`{ vec: [ -100, "Fred", 4.0 ], foo: 100 }`. The root is a dictionary that has
+just two key-value pairs, with keys `vec` and `foo`. Unlike FlatBuffers, it
+actually has to store these keys in the buffer (which it does only once if
+you store multiple such objects, by pooling key values), but also unlike
+FlatBuffers it has no restriction on the keys (fields) that you use.
+
+The map constructor uses a C++11 Lambda to group its children, but you can
+also use more conventional start/end calls if you prefer.
+
+The first value in the map is a vector. You'll notice that unlike FlatBuffers,
+you can use mixed types. There is also a `TypedVector` variant that only
+allows a single type, and uses a bit less memory.
+
+`IndirectFloat` is an interesting feature that allows you to store values
+by offset rather than inline. Though that doesn't make any visible change
+to the user, the consequence is that large values (especially doubles or
+64 bit ints) that occur more than once can be shared. Another use case is
+inside of vectors, where the largest element makes up the size of all elements
+(e.g. a single double forces all elements to 64bit), so storing a lot of small
+integers together with a double is more efficient if the double is indirect.
+
+Accessing it:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
+auto map = flexbuffers::GetRoot(my_buffer).AsMap();
+map.size();  // 2
+auto vec = map["vec"].AsVector();
+vec.size();  // 3
+vec[0].AsInt64();  // -100;
+vec[1].AsString().c_str();  // "Fred";
+vec[1].AsInt64();  // 0 (Number parsing failed).
+vec[2].AsDouble();  // 4.0
+vec[2].AsString().IsTheEmptyString();  // true (Wrong Type).
+vec[2].AsString().c_str();  // "" (This still works though).
+vec[2].ToString().c_str();  // "4" (Or have it converted).
+map["foo"].AsUInt8();  // 100
+map["unknown"].IsNull();  // true
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+# Binary encoding
+
+A description of how FlexBuffers are encoded is in the
+[internals](@ref flatbuffers_internals) document.
+
+
+# Nesting inside a FlatBuffer
+
+You can mark a field as containing a FlexBuffer, e.g.
+
+    a:[ubyte] (flexbuffer);
+
+A special accessor will be generated that allows you to access the root value
+directly, e.g. `a_flexbuffer_root().AsInt64()`.
+
+
+# Efficiency tips
+
+* Vectors generally are a lot more efficient than maps, so prefer them over maps
+  when possible for small objects. Instead of a map with keys `x`, `y` and `z`,
+  use a vector. Better yet, use a typed vector. Or even better, use a fixed
+  size typed vector.
+* Maps are backwards compatible with vectors, and can be iterated as such.
+  You can iterate either just the values (`map.Values()`), or in parallel with
+  the keys vector (`map.Keys()`). If you intend
+  to access most or all elements, this is faster than looking up each element
+  by key, since that involves a binary search of the key vector.
+* When possible, don't mix values that require a big bit width (such as double)
+  in a large vector of smaller values, since all elements will take on this
+  width. Use `IndirectDouble` when this is a possibility. Note that
+  integers automatically use the smallest width possible, i.e. if you ask
+  to serialize an int64_t whose value is actually small, you will use less
+  bits. Doubles are represented as floats whenever possible losslessly, but
+  this is only possible for few values.
+  Since nested vectors/maps are stored over offsets, they typically don't
+  affect the vector width.
+* To store large arrays of byte data, use a blob. If you'd use a typed
+  vector, the bit width of the size field may make it use more space than
+  expected, and may not be compatible with `memcpy`.
+  Similarly, large arrays of (u)int16_t may be better off stored as a
+  binary blob if their size could exceed 64k elements.
+  Construction and use are otherwise similar to strings.
diff --git a/third_party/flatbuffers/docs/source/GoApi.md b/third_party/flatbuffers/docs/source/GoApi.md
new file mode 100644
index 0000000..98be2b6
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/GoApi.md
@@ -0,0 +1,26 @@
+Go API
+======
+
+\addtogroup flatbuffers_go_api
+
+<!-- Note: The `GoApi_generate.txt` code snippet was generated using `godoc` and
+     customized for use with this markdown file. To regenerate the file, use the
+     `godoc` tool (http://godoc.org) with the files in the `flatbuffers/go`
+     folder.
+
+     You may need to ensure that copies of the files exist in the `src/`
+     subfolder at the path set by the `$GOROOT` environment variable. You can
+     either move the files to `$GOROOT/src/flatbuffers` manually, if `$GOROOT`
+     is already set, otherwise you will need to manually set the `$GOROOT`
+     variable to a path and create `src/flatbuffers` subfolders at that path.
+     Then copy the flatbuffers files into `$GOROOT/src/flatbuffers`. (Some
+     versions of `godoc` include a `-path` flag. This could be used instead, if
+     available).
+
+     Once the files exist at the `$GOROOT/src/flatbuffers` location, you can
+     regenerate this doc using the following command:
+     `godoc flatbuffers > GoApi_generated.txt`.
+
+     After the documentation is generated, you will have to manually remove any
+     non-user facing documentation from this file. -->
+\snippet GoApi_generated.txt Go API
diff --git a/third_party/flatbuffers/docs/source/GoApi_generated.txt b/third_party/flatbuffers/docs/source/GoApi_generated.txt
new file mode 100644
index 0000000..3d4e0fc
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/GoApi_generated.txt
@@ -0,0 +1,125 @@
+// This file was generated using `godoc` and customized for use with the
+// API Reference documentation. To recreate this file, use the `godoc` tool
+// (http://godoc.org) with the files in the `flatbuffers/go` folder.
+//
+// Note: You may need to ensure that copies of the files exist in the
+// `src/` subfolder at the path set by the `$GOROOT` environment variable.
+// You can either move the files to `$GOROOT/src/flatbuffers` manually, if
+// `$GOROOT` is already set, otherwise you will need to manually set the
+// `$GOROOT` variable to a path and create `src/flatbuffers` subfolders at that
+// path. Then copy these files into `$GOROOT/src/flatbuffers`. (Some versions of
+// `godoc` include a `-path` flag. This could be used instead, if available).
+//
+// Once the files exist at the `$GOROOT/src/flatbuffers` location, you can
+// regenerate this doc using the following command:
+// `godoc flatbuffers > GoApi_generated.txt`.
+//
+// After the documentation is generated, you will have to manually remove any
+// non-user facing documentation from this file.
+
+/// [Go API]
+PACKAGE DOCUMENTATION
+
+package flatbuffers
+    Package flatbuffers provides facilities to read and write flatbuffers
+    objects.
+
+TYPES
+
+type Builder struct {
+    // `Bytes` gives raw access to the buffer. Most users will want to use
+    // FinishedBytes() instead.
+    Bytes []byte
+}
+    Builder is a state machine for creating FlatBuffer objects. Use a
+    Builder to construct object(s) starting from leaf nodes.
+
+    A Builder constructs byte buffers in a last-first manner for simplicity
+    and performance.
+
+FUNCTIONS
+
+func NewBuilder(initialSize int) *Builder
+    NewBuilder initializes a Builder of size `initial_size`. The internal
+    buffer is grown as needed.
+
+func (b *Builder) CreateByteString(s []byte) UOffsetT
+    CreateByteString writes a byte slice as a string (null-terminated).
+
+func (b *Builder) CreateByteVector(v []byte) UOffsetT
+    CreateByteVector writes a ubyte vector
+
+func (b *Builder) CreateString(s string) UOffsetT
+    CreateString writes a null-terminated string as a vector.
+
+func (b *Builder) EndVector(vectorNumElems int) UOffsetT
+    EndVector writes data necessary to finish vector construction.
+
+func (b *Builder) Finish(rootTable UOffsetT)
+    Finish finalizes a buffer, pointing to the given `rootTable`.
+
+func (b *Builder) FinishedBytes() []byte
+    FinishedBytes returns a pointer to the written data in the byte buffer.
+    Panics if the builder is not in a finished state (which is caused by
+    calling `Finish()`).
+
+func (b *Builder) Head() UOffsetT
+    Head gives the start of useful data in the underlying byte buffer. Note:
+    unlike other functions, this value is interpreted as from the left.
+
+func (b *Builder) PrependBool(x bool)
+    PrependBool prepends a bool to the Builder buffer. Aligns and checks for
+    space.
+
+func (b *Builder) PrependByte(x byte)
+    PrependByte prepends a byte to the Builder buffer. Aligns and checks for
+    space.
+
+func (b *Builder) PrependFloat32(x float32)
+    PrependFloat32 prepends a float32 to the Builder buffer. Aligns and
+    checks for space.
+
+func (b *Builder) PrependFloat64(x float64)
+    PrependFloat64 prepends a float64 to the Builder buffer. Aligns and
+    checks for space.
+
+func (b *Builder) PrependInt16(x int16)
+    PrependInt16 prepends a int16 to the Builder buffer. Aligns and checks
+    for space.
+
+func (b *Builder) PrependInt32(x int32)
+    PrependInt32 prepends a int32 to the Builder buffer. Aligns and checks
+    for space.
+
+func (b *Builder) PrependInt64(x int64)
+    PrependInt64 prepends a int64 to the Builder buffer. Aligns and checks
+    for space.
+
+func (b *Builder) PrependInt8(x int8)
+    PrependInt8 prepends a int8 to the Builder buffer. Aligns and checks for
+    space.
+
+func (b *Builder) PrependUOffsetT(off UOffsetT)
+    PrependUOffsetT prepends an UOffsetT, relative to where it will be
+    written.
+
+func (b *Builder) PrependUint16(x uint16)
+    PrependUint16 prepends a uint16 to the Builder buffer. Aligns and checks
+    for space.
+
+func (b *Builder) PrependUint32(x uint32)
+    PrependUint32 prepends a uint32 to the Builder buffer. Aligns and checks
+    for space.
+
+func (b *Builder) PrependUint64(x uint64)
+    PrependUint64 prepends a uint64 to the Builder buffer. Aligns and checks
+    for space.
+
+func (b *Builder) PrependUint8(x uint8)
+    PrependUint8 prepends a uint8 to the Builder buffer. Aligns and checks
+    for space.
+
+func (b *Builder) Reset()
+    Reset truncates the underlying Builder buffer, facilitating alloc-free
+    reuse of a Builder. It also resets bookkeeping data.
+/// [Go API]
diff --git a/third_party/flatbuffers/docs/source/GoUsage.md b/third_party/flatbuffers/docs/source/GoUsage.md
new file mode 100644
index 0000000..ab6ddbd
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/GoUsage.md
@@ -0,0 +1,99 @@
+Use in Go    {#flatbuffers_guide_use_go}
+=========
+
+## Before you get started
+
+Before diving into the FlatBuffers usage in Go, it should be noted that
+the [Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide
+to general FlatBuffers usage in all of the supported languages (including Go).
+This page is designed to cover the nuances of FlatBuffers usage, specific to
+Go.
+
+You should also have read the [Building](@ref flatbuffers_guide_building)
+documentation to build `flatc` and should be familiar with
+[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) and
+[Writing a schema](@ref flatbuffers_guide_writing_schema).
+
+## FlatBuffers Go library code location
+
+The code for the FlatBuffers Go library can be found at
+`flatbuffers/go`. You can browse the library code on the [FlatBuffers
+GitHub page](https://github.com/google/flatbuffers/tree/master/go).
+
+## Testing the FlatBuffers Go library
+
+The code to test the Go library can be found at `flatbuffers/tests`.
+The test code itself is located in [go_test.go](https://github.com/google/
+flatbuffers/blob/master/tests/go_test.go).
+
+To run the tests, use the [GoTest.sh](https://github.com/google/flatbuffers/
+blob/master/tests/GoTest.sh) shell script.
+
+*Note: The shell script requires [Go](https://golang.org/doc/install) to
+be installed.*
+
+## Using the FlatBuffers Go library
+
+*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
+example of how to use FlatBuffers in Go.*
+
+FlatBuffers supports reading and writing binary FlatBuffers in Go.
+
+To use FlatBuffers in your own code, first generate Go classes from your
+schema with the `--go` option to `flatc`. Then you can include both FlatBuffers
+and the generated code to read or write a FlatBuffer.
+
+For example, here is how you would read a FlatBuffer binary file in Go: First,
+include the library and generated code. Then read a FlatBuffer binary file into
+a `[]byte`, which you pass to the `GetRootAsMonster` function:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.go}
+    import (
+       example "MyGame/Example"
+       flatbuffers "github.com/google/flatbuffers/go"
+
+       io/ioutil
+    )
+
+    buf, err := ioutil.ReadFile("monster.dat")
+    // handle err
+    monster := example.GetRootAsMonster(buf, 0)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Now you can access values like this:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.go}
+    hp := monster.Hp()
+    pos := monster.Pos(nil)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+In some cases it's necessary to modify values in an existing FlatBuffer in place (without creating a copy). For this reason, scalar fields of a Flatbuffer table or struct can be mutated.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.go}
+    monster := example.GetRootAsMonster(buf, 0)
+
+    // Set table field.
+    if ok := monster.MutateHp(10); !ok {
+      panic("failed to mutate Hp")
+    }
+
+    // Set struct field.
+    monster.Pos().MutateZ(4)
+
+    // This mutation will fail because the mana field is not available in
+    // the buffer. It should be set when creating the buffer.
+    if ok := monster.MutateMana(20); !ok {
+      panic("failed to mutate Hp")
+    }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The term `mutate` is used instead of `set` to indicate that this is a special use case. All mutate functions return a boolean value which is false if the field we're trying to mutate is not available in the buffer.
+
+## Text Parsing
+
+There currently is no support for parsing text (Schema's and JSON) directly
+from Go, though you could use the C++ parser through cgo. Please see the
+C++ documentation for more on text parsing.
+
+<br>
diff --git a/third_party/flatbuffers/docs/source/Grammar.md b/third_party/flatbuffers/docs/source/Grammar.md
new file mode 100644
index 0000000..51cc5f0
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/Grammar.md
@@ -0,0 +1,74 @@
+Grammar of the schema language    {#flatbuffers_grammar}
+==============================
+
+schema = include*
+         ( namespace\_decl | type\_decl | enum\_decl | root\_decl |
+           file_extension_decl | file_identifier_decl |
+           attribute\_decl | rpc\_decl | object )*
+
+include = `include` string\_constant `;`
+
+namespace\_decl = `namespace` ident ( `.` ident )* `;`
+
+attribute\_decl = `attribute` ident | `"`ident`"` `;`
+
+type\_decl = ( `table` | `struct` ) ident metadata `{` field\_decl+ `}`
+
+enum\_decl = ( `enum` ident `:` type | `union` ident )  metadata `{`
+commasep( enumval\_decl ) `}`
+
+root\_decl = `root_type` ident `;`
+
+field\_decl = ident `:` type [ `=` scalar ] metadata `;`
+
+rpc\_decl = `rpc_service` ident `{` rpc\_method+ `}`
+
+rpc\_method = ident `(` ident `)` `:` ident metadata `;`
+
+type = `bool` | `byte` | `ubyte` | `short` | `ushort` | `int` | `uint` |
+`float` | `long` | `ulong` | `double` |
+`int8` | `uint8` | `int16` | `uint16` | `int32` | `uint32`| `int64` | `uint64` |
+`float32` | `float64` |
+`string` | `[` type `]` | ident
+
+enumval\_decl = ident [ `=` integer\_constant ]
+
+metadata = [ `(` commasep( ident [ `:` single\_value ] ) `)` ]
+
+scalar = integer\_constant | float\_constant
+
+object = { commasep( ident `:` value ) }
+
+single\_value = scalar | string\_constant
+
+value = single\_value | object | `[` commasep( value ) `]`
+
+commasep(x) = [ x ( `,` x )\* ]
+
+file_extension_decl = `file_extension` string\_constant `;`
+
+file_identifier_decl = `file_identifier` string\_constant `;`
+
+string\_constant = `\".*?\"`
+
+ident = `[a-zA-Z_][a-zA-Z0-9_]*`
+
+`[:digit:]` = `[0-9]`
+
+`[:xdigit:]` = `[0-9a-fA-F]`
+
+dec\_integer\_constant = `[-+]?[:digit:]+`
+
+hex\_integer\_constant = `[-+]?0[xX][:xdigit:]+`
+
+integer\_constant = dec\_integer\_constant | hex\_integer\_constant
+
+dec\_float\_constant = `[-+]?(([.][:digit:]+)|([:digit:]+[.][:digit:]*)|([:digit:]+))([eE][-+]?[:digit:]+)?`
+
+hex\_float\_constant = `[-+]?0[xX](([.][:xdigit:]+)|([:xdigit:]+[.][:xdigit:]*)|([:xdigit:]+))([pP][-+]?[:digit:]+)`
+
+special\_float\_constant = `[-+]?(nan|inf|infinity)`
+
+float\_constant = decimal\_float\_constant | hexadecimal\_float\_constant | special\_float\_constant
+
+boolean\_constant = `(true|false)` | (integer\_constant ? `true` : `false`)
diff --git a/third_party/flatbuffers/docs/source/Internals.md b/third_party/flatbuffers/docs/source/Internals.md
new file mode 100644
index 0000000..d2064ca
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/Internals.md
@@ -0,0 +1,455 @@
+FlatBuffer Internals    {#flatbuffers_internals}
+====================
+
+This section is entirely optional for the use of FlatBuffers. In normal
+usage, you should never need the information contained herein. If you're
+interested however, it should give you more of an appreciation of why
+FlatBuffers is both efficient and convenient.
+
+### Format components
+
+A FlatBuffer is a binary file and in-memory format consisting mostly of
+scalars of various sizes, all aligned to their own size. Each scalar is
+also always represented in little-endian format, as this corresponds to
+all commonly used CPUs today. FlatBuffers will also work on big-endian
+machines, but will be slightly slower because of additional
+byte-swap intrinsics.
+
+It is assumed that the following conditions are met, to ensure
+cross-platform interoperability:
+- The binary `IEEE-754` format is used for floating-point numbers.
+- The `two's complemented` representation is used for signed integers.
+- The endianness is the same for floating-point numbers as for integers.
+
+On purpose, the format leaves a lot of details about where exactly
+things live in memory undefined, e.g. fields in a table can have any
+order, and objects to some extent can be stored in many orders. This is
+because the format doesn't need this information to be efficient, and it
+leaves room for optimization and extension (for example, fields can be
+packed in a way that is most compact). Instead, the format is defined in
+terms of offsets and adjacency only. This may mean two different
+implementations may produce different binaries given the same input
+values, and this is perfectly valid.
+
+### Format identification
+
+The format also doesn't contain information for format identification
+and versioning, which is also by design. FlatBuffers is a statically typed
+system, meaning the user of a buffer needs to know what kind of buffer
+it is. FlatBuffers can of course be wrapped inside other containers
+where needed, or you can use its union feature to dynamically identify
+multiple possible sub-objects stored. Additionally, it can be used
+together with the schema parser if full reflective capabilities are
+desired.
+
+Versioning is something that is intrinsically part of the format (the
+optionality / extensibility of fields), so the format itself does not
+need a version number (it's a meta-format, in a sense). We're hoping
+that this format can accommodate all data needed. If format breaking
+changes are ever necessary, it would become a new kind of format rather
+than just a variation.
+
+### Offsets
+
+The most important and generic offset type (see `flatbuffers.h`) is
+`uoffset_t`, which is currently always a `uint32_t`, and is used to
+refer to all tables/unions/strings/vectors (these are never stored
+in-line). 32bit is
+intentional, since we want to keep the format binary compatible between
+32 and 64bit systems, and a 64bit offset would bloat the size for almost
+all uses. A version of this format with 64bit (or 16bit) offsets is easy to set
+when needed. Unsigned means they can only point in one direction, which
+typically is forward (towards a higher memory location). Any backwards
+offsets will be explicitly marked as such.
+
+The format starts with an `uoffset_t` to the root object in the buffer.
+
+We have two kinds of objects, structs and tables.
+
+### Structs
+
+These are the simplest, and as mentioned, intended for simple data that
+benefits from being extra efficient and doesn't need versioning /
+extensibility. They are always stored inline in their parent (a struct,
+table, or vector) for maximum compactness. Structs define a consistent
+memory layout where all components are aligned to their size, and
+structs aligned to their largest scalar member. This is done independent
+of the alignment rules of the underlying compiler to guarantee a cross
+platform compatible layout. This layout is then enforced in the generated
+code.
+
+### Tables
+
+Unlike structs, these are not stored in inline in their parent, but are
+referred to by offset.
+
+They start with an `soffset_t` to a vtable. This is a signed version of
+`uoffset_t`, since vtables may be stored anywhere relative to the object.
+This offset is substracted (not added) from the object start to arrive at
+the vtable start. This offset is followed by all the
+fields as aligned scalars (or offsets). Unlike structs, not all fields
+need to be present. There is no set order and layout.
+
+To be able to access fields regardless of these uncertainties, we go
+through a vtable of offsets. Vtables are shared between any objects that
+happen to have the same vtable values.
+
+The elements of a vtable are all of type `voffset_t`, which is
+a `uint16_t`. The first element is the size of the vtable in bytes,
+including the size element. The second one is the size of the object, in bytes
+(including the vtable offset). This size could be used for streaming, to know
+how many bytes to read to be able to access all *inline* fields of the object.
+The remaining elements are the N offsets, where N is the amount of fields
+declared in the schema when the code that constructed this buffer was
+compiled (thus, the size of the table is N + 2).
+
+All accessor functions in the generated code for tables contain the
+offset into this table as a constant. This offset is checked against the
+first field (the number of elements), to protect against newer code
+reading older data. If this offset is out of range, or the vtable entry
+is 0, that means the field is not present in this object, and the
+default value is return. Otherwise, the entry is used as offset to the
+field to be read.
+
+### Strings and Vectors
+
+Strings are simply a vector of bytes, and are always
+null-terminated. Vectors are stored as contiguous aligned scalar
+elements prefixed by a 32bit element count (not including any
+null termination). Neither is stored inline in their parent, but are referred to
+by offset.
+
+### Construction
+
+The current implementation constructs these buffers backwards (starting
+at the highest memory address of the buffer), since
+that significantly reduces the amount of bookkeeping and simplifies the
+construction API.
+
+### Code example
+
+Here's an example of the code that gets generated for the `samples/monster.fbs`.
+What follows is the entire file, broken up by comments:
+
+    // automatically generated, do not modify
+
+    #include "flatbuffers/flatbuffers.h"
+
+    namespace MyGame {
+    namespace Sample {
+
+Nested namespace support.
+
+    enum {
+      Color_Red = 0,
+      Color_Green = 1,
+      Color_Blue = 2,
+    };
+
+    inline const char **EnumNamesColor() {
+      static const char *names[] = { "Red", "Green", "Blue", nullptr };
+      return names;
+    }
+
+    inline const char *EnumNameColor(int e) { return EnumNamesColor()[e]; }
+
+Enums and convenient reverse lookup.
+
+    enum {
+      Any_NONE = 0,
+      Any_Monster = 1,
+    };
+
+    inline const char **EnumNamesAny() {
+      static const char *names[] = { "NONE", "Monster", nullptr };
+      return names;
+    }
+
+    inline const char *EnumNameAny(int e) { return EnumNamesAny()[e]; }
+
+Unions share a lot with enums.
+
+    struct Vec3;
+    struct Monster;
+
+Predeclare all data types since circular references between types are allowed
+(circular references between object are not, though).
+
+    FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Vec3 {
+     private:
+      float x_;
+      float y_;
+      float z_;
+
+     public:
+      Vec3(float x, float y, float z)
+        : x_(flatbuffers::EndianScalar(x)), y_(flatbuffers::EndianScalar(y)), z_(flatbuffers::EndianScalar(z)) {}
+
+      float x() const { return flatbuffers::EndianScalar(x_); }
+      float y() const { return flatbuffers::EndianScalar(y_); }
+      float z() const { return flatbuffers::EndianScalar(z_); }
+    };
+    FLATBUFFERS_STRUCT_END(Vec3, 12);
+
+These ugly macros do a couple of things: they turn off any padding the compiler
+might normally do, since we add padding manually (though none in this example),
+and they enforce alignment chosen by FlatBuffers. This ensures the layout of
+this struct will look the same regardless of compiler and platform. Note that
+the fields are private: this is because these store little endian scalars
+regardless of platform (since this is part of the serialized data).
+`EndianScalar` then converts back and forth, which is a no-op on all current
+mobile and desktop platforms, and a single machine instruction on the few
+remaining big endian platforms.
+
+    struct Monster : private flatbuffers::Table {
+      const Vec3 *pos() const { return GetStruct<const Vec3 *>(4); }
+      int16_t mana() const { return GetField<int16_t>(6, 150); }
+      int16_t hp() const { return GetField<int16_t>(8, 100); }
+      const flatbuffers::String *name() const { return GetPointer<const flatbuffers::String *>(10); }
+      const flatbuffers::Vector<uint8_t> *inventory() const { return GetPointer<const flatbuffers::Vector<uint8_t> *>(14); }
+      int8_t color() const { return GetField<int8_t>(16, 2); }
+    };
+
+Tables are a bit more complicated. A table accessor struct is used to point at
+the serialized data for a table, which always starts with an offset to its
+vtable. It derives from `Table`, which contains the `GetField` helper functions.
+GetField takes a vtable offset, and a default value. It will look in the vtable
+at that offset. If the offset is out of bounds (data from an older version) or
+the vtable entry is 0, the field is not present and the default is returned.
+Otherwise, it uses the entry as an offset into the table to locate the field.
+
+    struct MonsterBuilder {
+      flatbuffers::FlatBufferBuilder &fbb_;
+      flatbuffers::uoffset_t start_;
+      void add_pos(const Vec3 *pos) { fbb_.AddStruct(4, pos); }
+      void add_mana(int16_t mana) { fbb_.AddElement<int16_t>(6, mana, 150); }
+      void add_hp(int16_t hp) { fbb_.AddElement<int16_t>(8, hp, 100); }
+      void add_name(flatbuffers::Offset<flatbuffers::String> name) { fbb_.AddOffset(10, name); }
+      void add_inventory(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory) { fbb_.AddOffset(14, inventory); }
+      void add_color(int8_t color) { fbb_.AddElement<int8_t>(16, color, 2); }
+      MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
+      flatbuffers::Offset<Monster> Finish() { return flatbuffers::Offset<Monster>(fbb_.EndTable(start_, 7)); }
+    };
+
+`MonsterBuilder` is the base helper struct to construct a table using a
+`FlatBufferBuilder`. You can add the fields in any order, and the `Finish`
+call will ensure the correct vtable gets generated.
+
+    inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb,
+                                                      const Vec3 *pos, int16_t mana,
+                                                      int16_t hp,
+                                                      flatbuffers::Offset<flatbuffers::String> name,
+                                                      flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory,
+                                                      int8_t color) {
+      MonsterBuilder builder_(_fbb);
+      builder_.add_inventory(inventory);
+      builder_.add_name(name);
+      builder_.add_pos(pos);
+      builder_.add_hp(hp);
+      builder_.add_mana(mana);
+      builder_.add_color(color);
+      return builder_.Finish();
+    }
+
+`CreateMonster` is a convenience function that calls all functions in
+`MonsterBuilder` above for you. Note that if you pass values which are
+defaults as arguments, it will not actually construct that field, so
+you can probably use this function instead of the builder class in
+almost all cases.
+
+    inline const Monster *GetMonster(const void *buf) { return flatbuffers::GetRoot<Monster>(buf); }
+
+This function is only generated for the root table type, to be able to
+start traversing a FlatBuffer from a raw buffer pointer.
+
+    }; // namespace MyGame
+    }; // namespace Sample
+
+### Encoding example.
+
+Below is a sample encoding for the following JSON corresponding to the above
+schema:
+
+    { pos: { x: 1, y: 2, z: 3 }, name: "fred", hp: 50 }
+
+Resulting in this binary buffer:
+
+    // Start of the buffer:
+    uint32_t 20  // Offset to the root table.
+
+    // Start of the vtable. Not shared in this example, but could be:
+    uint16_t 16 // Size of table, starting from here.
+    uint16_t 22 // Size of object inline data.
+    uint16_t 4, 0, 20, 16, 0, 0  // Offsets to fields from start of (root) table, 0 for not present.
+
+    // Start of the root table:
+    int32_t 16     // Offset to vtable used (default negative direction)
+    float 1, 2, 3  // the Vec3 struct, inline.
+    uint32_t 8     // Offset to the name string.
+    int16_t 50     // hp field.
+    int16_t 0      // Padding for alignment.
+
+    // Start of name string:
+    uint32_t 4  // Length of string.
+    int8_t 'f', 'r', 'e', 'd', 0, 0, 0, 0  // Text + 0 termination + padding.
+
+Note that this not the only possible encoding, since the writer has some
+flexibility in which of the children of root object to write first (though in
+this case there's only one string), and what order to write the fields in.
+Different orders may also cause different alignments to happen.
+
+### Additional reading.
+
+The author of the C language implementation has made a similar
+[document](https://github.com/dvidelabs/flatcc/blob/master/doc/binary-format.md#flatbuffers-binary-format)
+that may further help clarify the format.
+
+# FlexBuffers
+
+The [schema-less](@ref flexbuffers) version of FlatBuffers have their
+own encoding, detailed here.
+
+It shares many properties mentioned above, in that all data is accessed
+over offsets, all scalars are aligned to their own size, and
+all data is always stored in little endian format.
+
+One difference is that FlexBuffers are built front to back, so children are
+stored before parents, and the root of the data starts at the last byte.
+
+Another difference is that scalar data is stored with a variable number of bits
+(8/16/32/64). The current width is always determined by the *parent*, i.e. if
+the scalar sits in a vector, the vector determines the bit width for all
+elements at once. Selecting the minimum bit width for a particular vector is
+something the encoder does automatically and thus is typically of no concern
+to the user, though being aware of this feature (and not sticking a double in
+the same vector as a bunch of byte sized elements) is helpful for efficiency.
+
+Unlike FlatBuffers there is only one kind of offset, and that is an unsigned
+integer indicating the number of bytes in a negative direction from the address
+of itself (where the offset is stored).
+
+### Vectors
+
+The representation of the vector is at the core of how FlexBuffers works (since
+maps are really just a combination of 2 vectors), so it is worth starting there.
+
+As mentioned, a vector is governed by a single bit width (supplied by its
+parent). This includes the size field. For example, a vector that stores the
+integer values `1, 2, 3` is encoded as follows:
+
+    uint8_t 3, 1, 2, 3, 4, 4, 4
+
+The first `3` is the size field, and is placed before the vector (an offset
+from the parent to this vector points to the first element, not the size
+field, so the size field is effectively at index -1).
+Since this is an untyped vector `SL_VECTOR`, it is followed by 3 type
+bytes (one per element of the vector), which are always following the vector,
+and are always a uint8_t even if the vector is made up of bigger scalars.
+
+### Types
+
+A type byte is made up of 2 components (see flexbuffers.h for exact values):
+
+* 2 lower bits representing the bit-width of the child (8, 16, 32, 64).
+  This is only used if the child is accessed over an offset, such as a child
+  vector. It is ignored for inline types.
+* 6 bits representing the actual type (see flexbuffers.h).
+
+Thus, in this example `4` means 8 bit child (value 0, unused, since the value is
+in-line), type `SL_INT` (value 1).
+
+### Typed Vectors
+
+These are like the Vectors above, but omit the type bytes. The type is instead
+determined by the vector type supplied by the parent. Typed vectors are only
+available for a subset of types for which these savings can be significant,
+namely inline signed/unsigned integers (`TYPE_VECTOR_INT` / `TYPE_VECTOR_UINT`),
+floats (`TYPE_VECTOR_FLOAT`), and keys (`TYPE_VECTOR_KEY`, see below).
+
+Additionally, for scalars, there are fixed length vectors of sizes 2 / 3 / 4
+that don't store the size (`TYPE_VECTOR_INT2` etc.), for an additional savings
+in space when storing common vector or color data.
+
+### Scalars
+
+FlexBuffers supports integers (`TYPE_INT` and `TYPE_UINT`) and floats
+(`TYPE_FLOAT`), available in the bit-widths mentioned above. They can be stored
+both inline and over an offset (`TYPE_INDIRECT_*`).
+
+The offset version is useful to encode costly 64bit (or even 32bit) quantities
+into vectors / maps of smaller sizes, and to share / repeat a value multiple
+times.
+
+### Booleans and Nulls
+
+Booleans (`TYPE_BOOL`) and nulls (`TYPE_NULL`) are encoded as inlined unsigned integers.
+
+### Blobs, Strings and Keys.
+
+A blob (`TYPE_BLOB`) is encoded similar to a vector, with one difference: the
+elements are always `uint8_t`. The parent bit width only determines the width of
+the size field, allowing blobs to be large without the elements being large.
+
+Strings (`TYPE_STRING`) are similar to blobs, except they have an additional 0
+termination byte for convenience, and they MUST be UTF-8 encoded (since an
+accessor in a language that does not support pointers to UTF-8 data may have to
+convert them to a native string type).
+
+A "Key" (`TYPE_KEY`) is similar to a string, but doesn't store the size
+field. They're so named because they are used with maps, which don't care
+for the size, and can thus be even more compact. Unlike strings, keys cannot
+contain bytes of value 0 as part of their data (size can only be determined by
+`strlen`), so while you can use them outside the context of maps if you so
+desire, you're usually better off with strings.
+
+### Maps
+
+A map (`TYPE_MAP`) is like an (untyped) vector, but with 2 prefixes before the
+size field:
+
+| index | field                                                        |
+| ----: | :----------------------------------------------------------- |
+| -3    | An offset to the keys vector (may be shared between tables). |
+| -2    | Byte width of the keys vector.                               |
+| -1    | Size (from here on it is compatible with `TYPE_VECTOR`)      |
+| 0     | Elements.                                                    |
+| Size  | Types.                                                       |
+
+Since a map is otherwise the same as a vector, it can be iterated like
+a vector (which is probably faster than lookup by key).
+
+The keys vector is a typed vector of keys. Both the keys and corresponding
+values *have* to be stored in sorted order (as determined by `strcmp`), such
+that lookups can be made using binary search.
+
+The reason the key vector is a seperate structure from the value vector is
+such that it can be shared between multiple value vectors, and also to
+allow it to be treated as its own individual vector in code.
+
+An example map { foo: 13, bar: 14 } would be encoded as:
+
+    0 : uint8_t 'b', 'a', 'r', 0
+    4 : uint8_t 'f', 'o', 'o', 0
+    8 : uint8_t 2      // key vector of size 2
+    // key vector offset points here
+    9 : uint8_t 9, 6   // offsets to bar_key and foo_key
+    11: uint8_t 2, 1   // offset to key vector, and its byte width
+    13: uint8_t 2      // value vector of size
+    // value vector offset points here
+    14: uint8_t 14, 13 // values
+    16: uint8_t 4, 4   // types
+
+### The root
+
+As mentioned, the root starts at the end of the buffer.
+The last uint8_t is the width in bytes of the root (normally the parent
+determines the width, but the root has no parent). The uint8_t before this is
+the type of the root, and the bytes before that are the root value (of the
+number of bytes specified by the last byte).
+
+So for example, the integer value `13` as root would be:
+
+    uint8_t 13, 4, 1    // Value, type, root byte width.
+
+
+<br>
diff --git a/third_party/flatbuffers/docs/source/JavaCsharpUsage.md b/third_party/flatbuffers/docs/source/JavaCsharpUsage.md
new file mode 100644
index 0000000..102ce37
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/JavaCsharpUsage.md
@@ -0,0 +1,172 @@
+Use in Java/C#    {#flatbuffers_guide_use_java_c-sharp}
+==============
+
+## Before you get started
+
+Before diving into the FlatBuffers usage in Java or C#, it should be noted that
+the [Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide to
+general FlatBuffers usage in all of the supported languages (including both Java
+and C#). This page is designed to cover the nuances of FlatBuffers usage,
+specific to Java and C#.
+
+You should also have read the [Building](@ref flatbuffers_guide_building)
+documentation to build `flatc` and should be familiar with
+[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) and
+[Writing a schema](@ref flatbuffers_guide_writing_schema).
+
+## FlatBuffers Java and C-sharp code location
+
+#### Java
+
+The code for the FlatBuffers Java library can be found at
+`flatbuffers/java/com/google/flatbuffers`. You can browse the library on the
+[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/
+java/com/google/flatbuffers).
+
+#### C-sharp
+
+The code for the FlatBuffers C# library can be found at
+`flatbuffers/net/FlatBuffers`. You can browse the library on the
+[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/net/
+FlatBuffers).
+
+## Testing the FlatBuffers Java and C-sharp libraries
+
+The code to test the libraries can be found at `flatbuffers/tests`.
+
+#### Java
+
+The test code for Java is located in [JavaTest.java](https://github.com/google
+/flatbuffers/blob/master/tests/JavaTest.java).
+
+To run the tests, use either [JavaTest.sh](https://github.com/google/
+flatbuffers/blob/master/tests/JavaTest.sh) or [JavaTest.bat](https://github.com/
+google/flatbuffers/blob/master/tests/JavaTest.bat), depending on your operating
+system.
+
+*Note: These scripts require that [Java](https://www.oracle.com/java/index.html)
+is installed.*
+
+#### C-sharp
+
+The test code for C# is located in the [FlatBuffers.Test](https://github.com/
+google/flatbuffers/tree/master/tests/FlatBuffers.Test) subfolder. To run the
+tests, open `FlatBuffers.Test.csproj` in [Visual Studio](
+https://www.visualstudio.com), and compile/run the project.
+
+Optionally, you can run this using [Mono](http://www.mono-project.com/) instead.
+Once you have installed `Mono`, you can run the tests from the command line
+by running the following commands from inside the `FlatBuffers.Test` folder:
+
+~~~{.sh}
+  mcs *.cs ../MyGame/Example/*.cs ../../net/FlatBuffers/*.cs
+  mono Assert.exe
+~~~
+
+## Using the FlatBuffers Java (and C#) library
+
+*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
+example of how to use FlatBuffers in Java or C#.*
+
+FlatBuffers supports reading and writing binary FlatBuffers in Java and C#.
+
+To use FlatBuffers in your own code, first generate Java classes from your
+schema with the `--java` option to `flatc`. (Or for C# with `--csharp`).
+Then you can include both FlatBuffers and the generated code to read
+or write a FlatBuffer.
+
+For example, here is how you would read a FlatBuffer binary file in Java:
+First, import the library and generated code. Then, you read a FlatBuffer binary
+file into a `byte[]`.  You then turn the `byte[]` into a `ByteBuffer`, which you
+pass to the `getRootAsMyRootType` function:
+
+*Note: The code here is written from the perspective of Java. Code for both
+languages is both generated and used in nearly the exact same way, with only
+minor differences. These differences are
+[explained in a section below](#differences_in_c-sharp).*
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java}
+    import MyGame.Example.*;
+    import com.google.flatbuffers.FlatBufferBuilder;
+
+    // This snippet ignores exceptions for brevity.
+    File file = new File("monsterdata_test.mon");
+    RandomAccessFile f = new RandomAccessFile(file, "r");
+    byte[] data = new byte[(int)f.length()];
+    f.readFully(data);
+    f.close();
+
+    ByteBuffer bb = ByteBuffer.wrap(data);
+    Monster monster = Monster.getRootAsMonster(bb);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Now you can access the data from the `Monster monster`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java}
+    short hp = monster.hp();
+    Vec3 pos = monster.pos();
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+<a name="differences_in_c-sharp">
+#### Differences in C-sharp
+</a>
+
+C# code works almost identically to Java, with only a few minor differences.
+You can see an example of C# code in
+`tests/FlatBuffers.Test/FlatBuffersExampleTests.cs` or
+`samples/SampleBinary.cs`.
+
+First of all, naming follows standard C# style with `PascalCasing` identifiers,
+e.g. `GetRootAsMyRootType`. Also, values (except vectors and unions) are
+available as properties instead of parameterless accessor methods as in Java.
+The performance-enhancing methods to which you can pass an already created
+object are prefixed with `Get`, e.g.:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs}
+    // property
+    var pos = monster.Pos;
+
+    // method filling a preconstructed object
+    var preconstructedPos = new Vec3();
+    monster.GetPos(preconstructedPos);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+## Storing dictionaries in a FlatBuffer
+
+FlatBuffers doesn't support dictionaries natively, but there is support to
+emulate their behavior with vectors and binary search, which means you
+can have fast lookups directly from a FlatBuffer without having to unpack
+your data into a `Dictionary` or similar.
+
+To use it:
+-   Designate one of the fields in a table as the "key" field. You do this
+    by setting the `key` attribute on this field, e.g.
+    `name:string (key)`.
+    You may only have one key field, and it must be of string or scalar type.
+-   Write out tables of this type as usual, collect their offsets in an
+    array.
+-   Instead of calling standard generated method,
+    e.g.: `Monster.createTestarrayoftablesVector`,
+    call `CreateSortedVectorOfMonster` in C# or
+    `createSortedVectorOfTables` (from the `FlatBufferBuilder` object) in Java,
+    which will first sort all offsets such that the tables they refer to
+    are sorted by the key field, then serialize it.
+-   Now when you're accessing the FlatBuffer, you can use
+    the `ByKey` accessor to access elements of the vector, e.g.:
+    `monster.testarrayoftablesByKey("Frodo")` in Java or
+    `monster.TestarrayoftablesByKey("Frodo")` in C#,
+    which returns an object of the corresponding table type,
+    or `null` if not found.
+    `ByKey` performs a binary search, so should have a similar
+    speed to `Dictionary`, though may be faster because of better caching.
+    `ByKey` only works if the vector has been sorted, it will
+    likely not find elements if it hasn't been sorted.
+
+## Text parsing
+
+There currently is no support for parsing text (Schema's and JSON) directly
+from Java or C#, though you could use the C++ parser through native call
+interfaces available to each language. Please see the
+C++ documentation for more on text parsing.
+
+<br>
diff --git a/third_party/flatbuffers/docs/source/JavaScriptUsage.md b/third_party/flatbuffers/docs/source/JavaScriptUsage.md
new file mode 100644
index 0000000..c321c95
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/JavaScriptUsage.md
@@ -0,0 +1,105 @@
+Use in JavaScript    {#flatbuffers_guide_use_javascript}
+=================
+
+## Before you get started
+
+Before diving into the FlatBuffers usage in JavaScript, it should be noted that
+the [Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide to
+general FlatBuffers usage in all of the supported languages
+(including JavaScript). This page is specifically designed to cover the nuances
+of FlatBuffers usage in JavaScript.
+
+You should also have read the [Building](@ref flatbuffers_guide_building)
+documentation to build `flatc` and should be familiar with
+[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) and
+[Writing a schema](@ref flatbuffers_guide_writing_schema).
+
+## FlatBuffers JavaScript library code location
+
+The code for the FlatBuffers JavaScript library can be found at
+`flatbuffers/js`. You can browse the library code on the [FlatBuffers
+GitHub page](https://github.com/google/flatbuffers/tree/master/js).
+
+## Testing the FlatBuffers JavaScript library
+
+The code to test the JavaScript library can be found at `flatbuffers/tests`.
+The test code itself is located in [JavaScriptTest.js](https://github.com/
+google/flatbuffers/blob/master/tests/JavaScriptTest.js).
+
+To run the tests, use the [JavaScriptTest.sh](https://github.com/google/
+flatbuffers/blob/master/tests/JavaScriptTest.sh) shell script.
+
+*Note: The JavaScript test file requires [Node.js](https://nodejs.org/en/).*
+
+## Using the FlatBuffers JavaScript libary
+
+*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
+example of how to use FlatBuffers in JavaScript.*
+
+FlatBuffers supports both reading and writing FlatBuffers in JavaScript.
+
+To use FlatBuffers in your own code, first generate JavaScript classes from your
+schema with the `--js` option to `flatc`. Then you can include both FlatBuffers
+and the generated code to read or write a FlatBuffer.
+
+For example, here is how you would read a FlatBuffer binary file in Javascript:
+First, include the library and generated code. Then read the file into an
+`Uint8Array`. Make a `flatbuffers.ByteBuffer` out of the `Uint8Array`, and pass
+the ByteBuffer to the `getRootAsMonster` function.
+
+*Note: Both JavaScript module loaders (e.g. Node.js) and browser-based
+HTML/JavaScript code segments are shown below in the following snippet:*
+
+~~~{.js}
+  // Note: These require functions are specific to JavaScript module loaders
+  //       (namely, Node.js). See below for a browser-based example.
+  var fs = require('fs');
+
+  var flatbuffers = require('../flatbuffers').flatbuffers;
+  var MyGame = require('./monster_generated').MyGame;
+
+  var data = new Uint8Array(fs.readFileSync('monster.dat'));
+  var buf = new flatbuffers.ByteBuffer(data);
+
+  var monster = MyGame.Example.Monster.getRootAsMonster(buf);
+
+  //--------------------------------------------------------------------------//
+
+  // Note: This code is specific to browser-based HTML/JavaScript. See above
+  //       for the code using JavaScript module loaders (e.g. Node.js).
+  <script src="../js/flatbuffers.js"></script>
+  <script src="monster_generated.js"></script>
+  <script>
+    function readFile() {
+      var reader = new FileReader(); // This example uses the HTML5 FileReader.
+      var file = document.getElementById(
+          'file_input').files[0]; // "monster.dat" from the HTML <input> field.
+
+      reader.onload = function() { // Executes after the file is read.
+        var data = new Uint8Array(reader.result);
+
+        var buf = new flatbuffers.ByteBuffer(data);
+
+        var monster = MyGame.Example.Monster.getRootAsMonster(buf);
+      }
+
+      reader.readAsArrayBuffer(file);
+    }
+  </script>
+
+  // Open the HTML file in a browser and select "monster.dat" from with the
+  // <input> field.
+  <input type="file" id="file_input" onchange="readFile();">
+~~~
+
+Now you can access values like this:
+
+~~~{.js}
+  var hp = monster.hp();
+  var pos = monster.pos();
+~~~
+
+## Text parsing FlatBuffers in JavaScript
+
+There currently is no support for parsing text (Schema's and JSON) directly
+from JavaScript.
diff --git a/third_party/flatbuffers/docs/source/KotlinUsage.md b/third_party/flatbuffers/docs/source/KotlinUsage.md
new file mode 100644
index 0000000..092fcd7
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/KotlinUsage.md
@@ -0,0 +1,84 @@
+Use in Kotlin    {#flatbuffers_guide_use_kotlin}
+==============
+
+## Before you get started
+
+Before diving into the FlatBuffers usage in Kotlin, it should be noted that
+the [Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide to
+general FlatBuffers usage in all of the supported languages (including K).
+
+This page is designed to cover the nuances of FlatBuffers usage, specific to Kotlin.
+
+You should also have read the [Building](@ref flatbuffers_guide_building)
+documentation to build `flatc` and should be familiar with
+[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) and
+[Writing a schema](@ref flatbuffers_guide_writing_schema).
+
+## Kotlin and FlatBuffers Java code location
+
+Code generated for Kotlin currently uses the flatbuffers java runtime library. That means that Kotlin generated code can only have Java virtual machine as target architecture (which includes Android). Kotlin Native and Kotlin.js are currently not supported.
+
+The code for the FlatBuffers Java library can be found at
+`flatbuffers/java/com/google/flatbuffers`. You can browse the library on the
+[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/
+java/com/google/flatbuffers).
+
+## Testing FlatBuffers Kotlin
+
+The test code for Java is located in [KotlinTest.java](https://github.com/google
+/flatbuffers/blob/master/tests/KotlinTest.kt).
+
+To run the tests, use  [KotlinTest.sh](https://github.com/google/
+flatbuffers/blob/master/tests/KotlinTest.sh) shell script.
+
+*Note: These scripts require that [Kotlin](https://kotlinlang.org/) is installed.*
+
+## Using the FlatBuffers Kotlin library
+
+*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
+example of how to use FlatBuffers in Kotlin.*
+
+FlatBuffers supports reading and writing binary FlatBuffers in Kotlin.
+
+To use FlatBuffers in your own code, first generate Java classes from your
+schema with the `--kotlin` option to `flatc`.
+Then you can include both FlatBuffers and the generated code to read
+or write a FlatBuffer.
+
+For example, here is how you would read a FlatBuffer binary file in Kotlin:
+First, import the library and generated code. Then, you read a FlatBuffer binary
+file into a `ByteArray`.  You then turn the `ByteArray` into a `ByteBuffer`, which you
+pass to the `getRootAsMyRootType` function:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.kt}
+    import MyGame.Example.*
+    import com.google.flatbuffers.FlatBufferBuilder
+
+    // This snippet ignores exceptions for brevity.
+    val data = RandomAccessFile(File("monsterdata_test.mon"), "r").use {
+        val temp = ByteArray(it.length().toInt())
+        it.readFully(temp)
+        temp
+    }
+
+    val bb = ByteBuffer.wrap(data)
+    val monster = Monster.getRootAsMonster(bb)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Now you can access the data from the `Monster monster`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.kt}
+    val hp = monster.hp
+    val pos = monster.pos!!;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+## Differences between Kotlin and Java code
+
+Kotlin generated code was designed to be as close as possible to the java counterpart, as for now, we only support kotlin on java virtual machine. So the differences in implementation and usage are basically the ones introduced by the Kotlin language itself. You can find more in-depth information [here](https://kotlinlang.org/docs/reference/comparison-to-java.html).
+
+The most obvious ones are:
+
+* Fields as accessed as Kotlin [properties](https://kotlinlang.org/docs/reference/properties.html)
+* Static methods are accessed in [companion object](https://kotlinlang.org/docs/reference/classes.html#companion-objects)
\ No newline at end of file
diff --git a/third_party/flatbuffers/docs/source/LobsterUsage.md b/third_party/flatbuffers/docs/source/LobsterUsage.md
new file mode 100644
index 0000000..9d69caf
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/LobsterUsage.md
@@ -0,0 +1,85 @@
+Use in Lobster    {#flatbuffers_guide_use_lobster}
+==============
+
+## Before you get started
+
+Before diving into the FlatBuffers usage in Lobster, it should be noted that the
+[Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide to general
+FlatBuffers usage in all of the supported languages (including Lobster). This
+page is designed to cover the nuances of FlatBuffers usage, specific to
+Lobster.
+
+You should also have read the [Building](@ref flatbuffers_guide_building)
+documentation to build `flatc` and should be familiar with
+[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) and
+[Writing a schema](@ref flatbuffers_guide_writing_schema).
+
+## FlatBuffers Lobster library code location
+
+The code for the FlatBuffers Lobster library can be found at
+`flatbuffers/lobster`. You can browse the library code on the
+[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/
+lobster).
+
+## Testing the FlatBuffers Lobster library
+
+The code to test the Lobster library can be found at `flatbuffers/tests`.
+The test code itself is located in [lobstertest.lobster](https://github.com/google/
+flatbuffers/blob/master/tests/lobstertest.lobster).
+
+To run the tests, run `lobster lobstertest.lobster`. To obtain Lobster itself,
+go to the [Lobster homepage](http://strlen.com/lobster) or
+[github](https://github.com/aardappel/lobster) to learn how to build it for your
+platform.
+
+## Using the FlatBuffers Lobster library
+
+*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
+example of how to use FlatBuffers in Lobster.*
+
+There is support for both reading and writing FlatBuffers in Lobster.
+
+To use FlatBuffers in your own code, first generate Lobster classes from your
+schema with the `--lobster` option to `flatc`. Then you can include both
+FlatBuffers and the generated code to read or write a FlatBuffer.
+
+For example, here is how you would read a FlatBuffer binary file in Lobster:
+First, import the library and the generated code. Then read a FlatBuffer binary
+file into a string, which you pass to the `GetRootAsMonster` function:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.lobster}
+    include "monster_generated.lobster"
+
+    let fb = read_file("monsterdata_test.mon")
+    assert fb
+    let monster = MyGame_Example_GetRootAsMonster(fb)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Now you can access values like this:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.lobster}
+    let hp = monster.hp
+    let pos = monster.pos
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As you can see, even though `hp` and `pos` are functions that access FlatBuffer
+data in-place in the string buffer, they appear as field accesses.
+
+## Speed
+
+Using FlatBuffers in Lobster should be relatively fast, as the implementation
+makes use of native support for writing binary values, and access of vtables.
+Both generated code and the runtime library are therefore small and fast.
+
+Actual speed will depend on wether you use Lobster as bytecode VM or compiled to
+C++.
+
+## Text Parsing
+
+Lobster has full support for parsing JSON into FlatBuffers, or generating
+JSON from FlatBuffers. See `samples/sample_test.lobster` for an example.
+
+This uses the C++ parser and generator underneath, so should be both fast and
+conformant.
+
+<br>
diff --git a/third_party/flatbuffers/docs/source/LuaUsage.md b/third_party/flatbuffers/docs/source/LuaUsage.md
new file mode 100644
index 0000000..75b1f3b
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/LuaUsage.md
@@ -0,0 +1,81 @@
+Use in Lua    {#flatbuffers_guide_use_lua}
+=============
+
+## Before you get started
+
+Before diving into the FlatBuffers usage in Lua, it should be noted that the
+[Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide to general
+FlatBuffers usage in all of the supported languages (including Lua). This
+page is designed to cover the nuances of FlatBuffers usage, specific to
+Lua.
+
+You should also have read the [Building](@ref flatbuffers_guide_building)
+documentation to build `flatc` and should be familiar with
+[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) and
+[Writing a schema](@ref flatbuffers_guide_writing_schema).
+
+## FlatBuffers Lua library code location
+
+The code for the FlatBuffers Lua library can be found at
+`flatbuffers/lua`. You can browse the library code on the
+[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/lua).
+
+## Testing the FlatBuffers Lua library
+
+The code to test the Lua library can be found at `flatbuffers/tests`.
+The test code itself is located in [luatest.lua](https://github.com/google/
+flatbuffers/blob/master/tests/luatest.lua).
+
+To run the tests, use the [LuaTest.sh](https://github.com/google/flatbuffers/
+blob/master/tests/LuaTest.sh) shell script.
+
+*Note: This script requires [Lua 5.3](https://www.lua.org/) to be
+installed.*
+
+## Using the FlatBuffers Lua library
+
+*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
+example of how to use FlatBuffers in Lua.*
+
+There is support for both reading and writing FlatBuffers in Lua.
+
+To use FlatBuffers in your own code, first generate Lua classes from your
+schema with the `--lua` option to `flatc`. Then you can include both
+FlatBuffers and the generated code to read or write a FlatBuffer.
+
+For example, here is how you would read a FlatBuffer binary file in Lua:
+First, require the module and the generated code. Then read a FlatBuffer binary
+file into a `string`, which you pass to the `GetRootAsMonster` function:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.lua}
+    -- require the library
+    local flatbuffers = require("flatbuffers")
+    
+    -- require the generated code
+    local monster = require("MyGame.Sample.Monster")
+
+    -- read the flatbuffer from a file into a string
+    local f = io.open('monster.dat', 'rb')
+    local buf = f:read('*a')
+    f:close()
+
+    -- parse the flatbuffer to get an instance to the root monster
+    local monster1 = monster.GetRootAsMonster(buf, 0)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Now you can access values like this:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.lua}
+    -- use the : notation to access member data
+    local hp = monster1:Hp()
+    local pos = monster1:Pos()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+## Text Parsing
+
+There currently is no support for parsing text (Schema's and JSON) directly
+from Lua, though you could use the C++ parser through SWIG or ctypes. Please
+see the C++ documentation for more on text parsing.
+
+<br>
diff --git a/third_party/flatbuffers/docs/source/PHPUsage.md b/third_party/flatbuffers/docs/source/PHPUsage.md
new file mode 100644
index 0000000..cdff449
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/PHPUsage.md
@@ -0,0 +1,89 @@
+Use in PHP    {#flatbuffers_guide_use_php}
+==========
+
+## Before you get started
+
+Before diving into the FlatBuffers usage in PHP, it should be noted that
+the [Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide to
+general FlatBuffers usage in all of the supported languages
+(including PHP). This page is specifically designed to cover the nuances of
+FlatBuffers usage in PHP.
+
+You should also have read the [Building](@ref flatbuffers_guide_building)
+documentation to build `flatc` and should be familiar with
+[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) and
+[Writing a schema](@ref flatbuffers_guide_writing_schema).
+
+## FlatBuffers PHP library code location
+
+The code for FlatBuffers PHP library can be found at `flatbuffers/php`. You
+can browse the library code on the [FlatBuffers
+GitHub page](https://github.com/google/flatbuffers/tree/master/php).
+
+## Testing the FlatBuffers JavaScript library
+
+The code to test the PHP library can be found at `flatbuffers/tests`.
+The test code itself is located in [phpTest.php](https://github.com/google/
+flatbuffers/blob/master/tests/phpTest.php).
+
+You can run the test with `php phpTest.php` from the command line.
+
+*Note: The PHP test file requires
+[PHP](http://php.net/manual/en/install.php) to be installed.*
+
+## Using theFlatBuffers PHP library
+
+*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
+example of how to use FlatBuffers in PHP.*
+
+FlatBuffers supports both reading and writing FlatBuffers in PHP.
+
+To use FlatBuffers in your own code, first generate PHP classes from your schema
+with the `--php` option to `flatc`. Then you can include both FlatBuffers and
+the generated code to read or write a FlatBuffer.
+
+For example, here is how you would read a FlatBuffer binary file in PHP:
+First, include the library and generated code (using the PSR `autoload`
+function). Then you can read a FlatBuffer binary file, which you
+pass the contents of to the `GetRootAsMonster` function:
+
+~~~{.php}
+  // It is recommended that your use PSR autoload when using FlatBuffers in PHP.
+  // Here is an example:
+  function __autoload($class_name) {
+    // The last segment of the class name matches the file name.
+    $class = substr($class_name, strrpos($class_name, "\\") + 1);
+    $root_dir = join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)))); // `flatbuffers` root.
+
+    // Contains the `*.php` files for the FlatBuffers library and the `flatc` generated files.
+    $paths = array(join(DIRECTORY_SEPARATOR, array($root_dir, "php")),
+                   join(DIRECTORY_SEPARATOR, array($root_dir, "tests", "MyGame", "Example")));
+    foreach ($paths as $path) {
+      $file = join(DIRECTORY_SEPARATOR, array($path, $class . ".php"));
+      if (file_exists($file)) {
+        require($file);
+        break;
+    }
+  }
+
+  // Read the contents of the FlatBuffer binary file.
+  $filename = "monster.dat";
+  $handle = fopen($filename, "rb");
+  $contents = $fread($handle, filesize($filename));
+  fclose($handle);
+
+  // Pass the contents to `GetRootAsMonster`.
+  $monster = \MyGame\Example\Monster::GetRootAsMonster($contents);
+~~~
+
+Now you can access values like this:
+
+~~~{.php}
+  $hp = $monster->GetHp();
+  $pos = $monster->GetPos();
+~~~
+
+## Text Parsing
+
+There currently is no support for parsing text (Schema's and JSON) directly
+from PHP.
diff --git a/third_party/flatbuffers/docs/source/PythonUsage.md b/third_party/flatbuffers/docs/source/PythonUsage.md
new file mode 100644
index 0000000..f338cda
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/PythonUsage.md
@@ -0,0 +1,100 @@
+Use in Python    {#flatbuffers_guide_use_python}
+=============
+
+## Before you get started
+
+Before diving into the FlatBuffers usage in Python, it should be noted that the
+[Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide to general
+FlatBuffers usage in all of the supported languages (including Python). This
+page is designed to cover the nuances of FlatBuffers usage, specific to
+Python.
+
+You should also have read the [Building](@ref flatbuffers_guide_building)
+documentation to build `flatc` and should be familiar with
+[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) and
+[Writing a schema](@ref flatbuffers_guide_writing_schema).
+
+## FlatBuffers Python library code location
+
+The code for the FlatBuffers Python library can be found at
+`flatbuffers/python/flatbuffers`. You can browse the library code on the
+[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/
+python).
+
+## Testing the FlatBuffers Python library
+
+The code to test the Python library can be found at `flatbuffers/tests`.
+The test code itself is located in [py_test.py](https://github.com/google/
+flatbuffers/blob/master/tests/py_test.py).
+
+To run the tests, use the [PythonTest.sh](https://github.com/google/flatbuffers/
+blob/master/tests/PythonTest.sh) shell script.
+
+*Note: This script requires [python](https://www.python.org/) to be
+installed.*
+
+## Using the FlatBuffers Python library
+
+*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
+example of how to use FlatBuffers in Python.*
+
+There is support for both reading and writing FlatBuffers in Python.
+
+To use FlatBuffers in your own code, first generate Python classes from your
+schema with the `--python` option to `flatc`. Then you can include both
+FlatBuffers and the generated code to read or write a FlatBuffer.
+
+For example, here is how you would read a FlatBuffer binary file in Python:
+First, import the library and the generated code. Then read a FlatBuffer binary
+file into a `bytearray`, which you pass to the `GetRootAsMonster` function:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.py}
+    import MyGame.Example as example
+    import flatbuffers
+
+    buf = open('monster.dat', 'rb').read()
+    buf = bytearray(buf)
+    monster = example.GetRootAsMonster(buf, 0)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Now you can access values like this:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.py}
+    hp = monster.Hp()
+    pos = monster.Pos()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+## Support for Numpy arrays
+
+The Flatbuffers python library also has support for accessing scalar
+vectors as numpy arrays. This can be orders of magnitude faster than
+iterating over the vector one element at a time, and is particularly
+useful when unpacking large nested flatbuffers. The generated code for
+a scalar vector will have a method `<vector name>AsNumpy()`. In the
+case of the Monster example, you could access the inventory vector
+like this:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.py}
+    inventory = monster.InventoryAsNumpy()
+    # inventory is a numpy array of type np.dtype('uint8')
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+instead of
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.py}
+    inventory = []
+    for i in range(monster.InventoryLength()):
+        inventory.append(int(monster.Inventory(i)))
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Numpy is not a requirement. If numpy is not installed on your system,
+then attempting to access one of the `*asNumpy()` methods will result
+in a `NumpyRequiredForThisFeature` exception.
+
+## Text Parsing
+
+There currently is no support for parsing text (Schema's and JSON) directly
+from Python, though you could use the C++ parser through SWIG or ctypes. Please
+see the C++ documentation for more on text parsing.
+
+<br>
diff --git a/third_party/flatbuffers/docs/source/README_TO_GENERATE_DOCS.md b/third_party/flatbuffers/docs/source/README_TO_GENERATE_DOCS.md
new file mode 100644
index 0000000..5df0b6a
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/README_TO_GENERATE_DOCS.md
@@ -0,0 +1,32 @@
+## Prerequisites
+
+To generate the docs for FlatBuffers from the source files, you
+will first need to install two programs.
+
+1. You will need to install `doxygen`. See
+   [Download Doxygen](http://www.stack.nl/~dimitri/doxygen/download.html).
+
+2. You will need to install `doxypypy` to format python comments appropriately.
+   Install it from [here](https://github.com/Feneric/doxypypy).
+
+*Note: You will need both `doxygen` and `doxypypy` to be in your
+[PATH](https://en.wikipedia.org/wiki/PATH_(variable)) environment variable.*
+
+After you have both of those files installed and in your path, you need to
+set up the `py_filter` to invoke `doxypypy` from `doxygen`.
+
+Follow the steps
+[here](https://github.com/Feneric/doxypypy#invoking-doxypypy-from-doxygen).
+
+## Generating Docs
+
+Run the following commands to generate the docs:
+
+`cd flatbuffers/docs/source`
+`doxygen`
+
+The output is placed in `flatbuffers/docs/html`.
+
+*Note: The Go API Reference code must be generated ahead of time. For
+instructions on how to regenerated this file, please read the comments
+in `GoApi.md`.*
diff --git a/third_party/flatbuffers/docs/source/RustUsage.md b/third_party/flatbuffers/docs/source/RustUsage.md
new file mode 100644
index 0000000..6819117
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/RustUsage.md
@@ -0,0 +1,174 @@
+Use in Rust    {#flatbuffers_guide_use_rust}
+==========
+
+## Before you get started
+
+Before diving into the FlatBuffers usage in Rust, it should be noted that
+the [Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide
+to general FlatBuffers usage in all of the supported languages (including Rust).
+This page is designed to cover the nuances of FlatBuffers usage, specific to
+Rust.
+
+#### Prerequisites
+
+This page assumes you have written a FlatBuffers schema and compiled it
+with the Schema Compiler. If you have not, please see
+[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler)
+and [Writing a schema](@ref flatbuffers_guide_writing_schema).
+
+Assuming you wrote a schema, say `mygame.fbs` (though the extension doesn't
+matter), you've generated a Rust file called `mygame_generated.rs` using the
+compiler (e.g. `flatc --rust mygame.fbs` or via helpers listed in "Useful
+tools created by others" section bellow), you can now start using this in
+your program by including the file. As noted, this header relies on the crate
+`flatbuffers`, which should be in your include `Cargo.toml`.
+
+## FlatBuffers Rust library code location
+
+The code for the FlatBuffers Rust library can be found at
+`flatbuffers/rust`. You can browse the library code on the
+[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/rust).
+
+## Testing the FlatBuffers Rust library
+
+The code to test the Rust library can be found at `flatbuffers/tests/rust_usage_test`.
+The test code itself is located in
+[integration_test.rs](https://github.com/google/flatbuffers/blob/master/tests/rust_usage_test/tests/integration_test.rs)
+
+This test file requires `flatc` to be present. To review how to build the project,
+please read the [Building](@ref flatbuffers_guide_building) documenation.
+
+To run the tests, execute `RustTest.sh` from the `flatbuffers/tests` directory.
+For example, on [Linux](https://en.wikipedia.org/wiki/Linux), you would simply
+run: `cd tests && ./RustTest.sh`.
+
+*Note: The shell script requires [Rust](https://www.rust-lang.org) to
+be installed.*
+
+## Using the FlatBuffers Rust library
+
+*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
+example of how to use FlatBuffers in Rust.*
+
+FlatBuffers supports both reading and writing FlatBuffers in Rust.
+
+To use FlatBuffers in your code, first generate the Rust modules from your
+schema with the `--rust` option to `flatc`. Then you can import both FlatBuffers
+and the generated code to read or write FlatBuffers.
+
+For example, here is how you would read a FlatBuffer binary file in Rust:
+First, include the library and generated code. Then read the file into
+a `u8` vector, which you pass, as a byte slice, to `get_root_as_monster()`.
+
+This full example program is available in the Rust test suite:
+[monster_example.rs](https://github.com/google/flatbuffers/blob/master/tests/rust_usage_test/bin/monster_example.rs)
+
+It can be run by `cd`ing to the `rust_usage_test` directory and executing: `cargo run monster_example`.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.rs}
+    extern crate flatbuffers;
+
+    #[allow(dead_code, unused_imports)]
+    #[path = "../../monster_test_generated.rs"]
+    mod monster_test_generated;
+    pub use monster_test_generated::my_game;
+
+    use std::io::Read;
+
+    fn main() {
+        let mut f = std::fs::File::open("../monsterdata_test.mon").unwrap();
+        let mut buf = Vec::new();
+        f.read_to_end(&mut buf).expect("file reading failed");
+
+        let monster = my_game::example::get_root_as_monster(&buf[..]);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`monster` is of type `Monster`, and points to somewhere *inside* your
+buffer (root object pointers are not the same as `buffer_pointer` !).
+If you look in your generated header, you'll see it has
+convenient accessors for all fields, e.g. `hp()`, `mana()`, etc:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.rs}
+        println!("{}", monster.hp());     // `80`
+        println!("{}", monster.mana());   // default value of `150`
+        println!("{:?}", monster.name()); // Some("MyMonster")
+    }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+*Note: That we never stored a `mana` value, so it will return the default.*
+
+## Direct memory access
+
+As you can see from the above examples, all elements in a buffer are
+accessed through generated accessors. This is because everything is
+stored in little endian format on all platforms (the accessor
+performs a swap operation on big endian machines), and also because
+the layout of things is generally not known to the user.
+
+For structs, layout is deterministic and guaranteed to be the same
+across platforms (scalars are aligned to their
+own size, and structs themselves to their largest member), and you
+are allowed to access this memory directly by using `safe_slice` and
+on the reference to a struct, or even an array of structs.
+
+To compute offsets to sub-elements of a struct, make sure they
+are structs themselves, as then you can use the pointers to
+figure out the offset without having to hardcode it. This is
+handy for use of arrays of structs with calls like `glVertexAttribPointer`
+in OpenGL or similar APIs.
+
+It is important to note is that structs are still little endian on all
+machines, so only use tricks like this if you can guarantee you're not
+shipping on a big endian machine (using an `#[cfg(target_endian = "little")]`
+attribute would be wise).
+
+The special function `safe_slice` is implemented on Vector objects that are
+represented in memory the same way as they are represented on the wire. This
+function is always available on vectors of struct, bool, u8, and i8. It is
+conditionally-compiled on little-endian systems for all the remaining scalar
+types.
+
+The FlatBufferBuilder function `create_vector_direct` is implemented for all
+types that are endian-safe to write with a `memcpy`. It is the write-equivalent
+of `safe_slice`.
+
+## Access of untrusted buffers
+
+The generated accessor functions access fields over offsets, which is
+very quick. These offsets are used to index into Rust slices, so they are
+bounds-checked by the Rust runtime. However, our Rust implementation may
+change: we may convert access functions to use direct pointer dereferencing, to
+improve lookup speed. As a result, users should not rely on the aforementioned
+bounds-checking behavior.
+
+When you're processing large amounts of data from a source you know (e.g.
+your own generated data on disk), this is acceptable, but when reading
+data from the network that can potentially have been modified by an
+attacker, this is undesirable.
+
+The C++ port provides a buffer verifier. At this time, Rust does not. Rust may
+provide a verifier in a future version. In the meantime, Rust users can access
+the buffer verifier generated by the C++ port through a foreign function
+interface (FFI).
+
+## Threading
+
+Reading a FlatBuffer does not touch any memory outside the original buffer,
+and is entirely read-only (all immutable), so is safe to access from multiple
+threads even without synchronisation primitives.
+
+Creating a FlatBuffer is not thread safe. All state related to building
+a FlatBuffer is contained in a FlatBufferBuilder instance, and no memory
+outside of it is touched. To make this thread safe, either do not
+share instances of FlatBufferBuilder between threads (recommended), or
+manually wrap it in synchronisation primitives. There's no automatic way to
+accomplish this, by design, as we feel multithreaded construction
+of a single buffer will be rare, and synchronisation overhead would be costly.
+
+## Useful tools created by others
+
+* [flatc-rust](https://github.com/frol/flatc-rust) - FlatBuffers compiler
+(flatc) as API for transparent `.fbs` to `.rs` code-generation via Cargo
+build scripts integration.
+
+<br>
diff --git a/third_party/flatbuffers/docs/source/Schemas.md b/third_party/flatbuffers/docs/source/Schemas.md
new file mode 100644
index 0000000..403aebb
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/Schemas.md
@@ -0,0 +1,629 @@
+Writing a schema    {#flatbuffers_guide_writing_schema}
+================
+
+The syntax of the schema language (aka IDL, [Interface Definition Language][])
+should look quite familiar to users of any of the C family of
+languages, and also to users of other IDLs. Let's look at an example
+first:
+
+    // example IDL file
+
+    namespace MyGame;
+
+    attribute "priority";
+
+    enum Color : byte { Red = 1, Green, Blue }
+
+    union Any { Monster, Weapon, Pickup }
+
+    struct Vec3 {
+      x:float;
+      y:float;
+      z:float;
+    }
+
+    table Monster {
+      pos:Vec3;
+      mana:short = 150;
+      hp:short = 100;
+      name:string;
+      friendly:bool = false (deprecated, priority: 1);
+      inventory:[ubyte];
+      color:Color = Blue;
+      test:Any;
+    }
+
+    root_type Monster;
+
+(`Weapon` & `Pickup` not defined as part of this example).
+
+### Tables
+
+Tables are the main way of defining objects in FlatBuffers, and consist
+of a name (here `Monster`) and a list of fields. Each field has a name,
+a type, and optionally a default value (if omitted, it defaults to `0` /
+`NULL`).
+
+Each field is optional: It does not have to appear in the wire
+representation, and you can choose to omit fields for each individual
+object. As a result, you have the flexibility to add fields without fear of
+bloating your data. This design is also FlatBuffer's mechanism for forward
+and backwards compatibility. Note that:
+
+-   You can add new fields in the schema ONLY at the end of a table
+    definition. Older data will still
+    read correctly, and give you the default value when read. Older code
+    will simply ignore the new field.
+    If you want to have flexibility to use any order for fields in your
+    schema, you can manually assign ids (much like Protocol Buffers),
+    see the `id` attribute below.
+
+-   You cannot delete fields you don't use anymore from the schema,
+    but you can simply
+    stop writing them into your data for almost the same effect.
+    Additionally you can mark them as `deprecated` as in the example
+    above, which will prevent the generation of accessors in the
+    generated C++, as a way to enforce the field not being used any more.
+    (careful: this may break code!).
+
+-   You may change field names and table names, if you're ok with your
+    code breaking until you've renamed them there too.
+
+See "Schema evolution examples" below for more on this
+topic.
+
+### Structs
+
+Similar to a table, only now none of the fields are optional (so no defaults
+either), and fields may not be added or be deprecated. Structs may only contain
+scalars or other structs. Use this for
+simple objects where you are very sure no changes will ever be made
+(as quite clear in the example `Vec3`). Structs use less memory than
+tables and are even faster to access (they are always stored in-line in their
+parent object, and use no virtual table).
+
+### Types
+
+Built-in scalar types are
+
+-   8 bit: `byte` (`int8`), `ubyte` (`uint8`), `bool`
+
+-   16 bit: `short` (`int16`), `ushort` (`uint16`)
+
+-   32 bit: `int` (`int32`), `uint` (`uint32`), `float` (`float32`)
+
+-   64 bit: `long` (`int64`), `ulong` (`uint64`), `double` (`float64`)
+
+The type names in parentheses are alias names such that for example
+`uint8` can be used in place of `ubyte`, and `int32` can be used in
+place of `int` without affecting code generation.
+
+Built-in non-scalar types:
+
+-   Vector of any other type (denoted with `[type]`). Nesting vectors
+    is not supported, instead you can wrap the inner vector in a table.
+
+-   `string`, which may only hold UTF-8 or 7-bit ASCII. For other text encodings
+    or general binary data use vectors (`[byte]` or `[ubyte]`) instead.
+
+-   References to other tables or structs, enums or unions (see
+    below).
+
+You can't change types of fields once they're used, with the exception
+of same-size data where a `reinterpret_cast` would give you a desirable result,
+e.g. you could change a `uint` to an `int` if no values in current data use the
+high bit yet.
+
+### Arrays
+
+Arrays are a convenience short-hand for a fixed-length collection of elements.
+Arrays can be used to replace the following schema:
+
+    struct Vec3 {
+        x:float;
+        y:float;
+        z:float;
+    }
+
+with the following schema:
+
+    struct Vec3 {
+        v:[float:3];
+    }
+
+Both representations are binary equivalent.
+
+Arrays are currently only supported in a `struct`.
+
+### (Default) Values
+
+Values are a sequence of digits. Values may be optionally followed by a decimal
+point (`.`) and more digits, for float constants, or optionally prefixed by
+a `-`. Floats may also be in scientific notation; optionally ending with an `e`
+or `E`, followed by a `+` or `-` and more digits.
+
+Only scalar values can have defaults, non-scalar (string/vector/table) fields
+default to `NULL` when not present.
+
+You generally do not want to change default values after they're initially
+defined. Fields that have the default value are not actually stored in the
+serialized data (see also Gotchas below) but are generated in code,
+so when you change the default, you'd
+now get a different value than from code generated from an older version of
+the schema. There are situations, however, where this may be
+desirable, especially if you can ensure a simultaneous rebuild of
+all code.
+
+### Enums
+
+Define a sequence of named constants, each with a given value, or
+increasing by one from the previous one. The default first value
+is `0`. As you can see in the enum declaration, you specify the underlying
+integral type of the enum with `:` (in this case `byte`), which then determines
+the type of any fields declared with this enum type.
+
+Only integer types are allowed, i.e. `byte`, `ubyte`, `short` `ushort`, `int`,
+`uint`, `long` and `ulong`.
+
+Typically, enum values should only ever be added, never removed (there is no
+deprecation for enums). This requires code to handle forwards compatibility
+itself, by handling unknown enum values.
+
+### Unions
+
+Unions share a lot of properties with enums, but instead of new names
+for constants, you use names of tables. You can then declare
+a union field, which can hold a reference to any of those types, and
+additionally a field with the suffix `_type` is generated that holds
+the corresponding enum value, allowing you to know which type to cast
+to at runtime.
+
+It's possible to give an alias name to a type union. This way a type can even be
+used to mean different things depending on the name used:
+
+    table PointPosition { x:uint; y:uint; }
+    table MarkerPosition {}
+    union Position {
+      Start:MarkerPosition,
+      Point:PointPosition,
+      Finish:MarkerPosition
+    }
+
+Unions contain a special `NONE` marker to denote that no value is stored so that
+name cannot be used as an alias.
+
+Unions are a good way to be able to send multiple message types as a FlatBuffer.
+Note that because a union field is really two fields, it must always be
+part of a table, it cannot be the root of a FlatBuffer by itself.
+
+If you have a need to distinguish between different FlatBuffers in a more
+open-ended way, for example for use as files, see the file identification
+feature below.
+
+There is an experimental support only in C++ for a vector of unions
+(and types). In the example IDL file above, use [Any] to add a
+vector of Any to Monster table.
+
+### Namespaces
+
+These will generate the corresponding namespace in C++ for all helper
+code, and packages in Java. You can use `.` to specify nested namespaces /
+packages.
+
+### Includes
+
+You can include other schemas files in your current one, e.g.:
+
+    include "mydefinitions.fbs";
+
+This makes it easier to refer to types defined elsewhere. `include`
+automatically ensures each file is parsed just once, even when referred to
+more than once.
+
+When using the `flatc` compiler to generate code for schema definitions,
+only definitions in the current file will be generated, not those from the
+included files (those you still generate separately).
+
+### Root type
+
+This declares what you consider to be the root table (or struct) of the
+serialized data. This is particularly important for parsing JSON data,
+which doesn't include object type information.
+
+### File identification and extension
+
+Typically, a FlatBuffer binary buffer is not self-describing, i.e. it
+needs you to know its schema to parse it correctly. But if you
+want to use a FlatBuffer as a file format, it would be convenient
+to be able to have a "magic number" in there, like most file formats
+have, to be able to do a sanity check to see if you're reading the
+kind of file you're expecting.
+
+Now, you can always prefix a FlatBuffer with your own file header,
+but FlatBuffers has a built-in way to add an identifier to a
+FlatBuffer that takes up minimal space, and keeps the buffer
+compatible with buffers that don't have such an identifier.
+
+You can specify in a schema, similar to `root_type`, that you intend
+for this type of FlatBuffer to be used as a file format:
+
+    file_identifier "MYFI";
+
+Identifiers must always be exactly 4 characters long. These 4 characters
+will end up as bytes at offsets 4-7 (inclusive) in the buffer.
+
+For any schema that has such an identifier, `flatc` will automatically
+add the identifier to any binaries it generates (with `-b`),
+and generated calls like `FinishMonsterBuffer` also add the identifier.
+If you have specified an identifier and wish to generate a buffer
+without one, you can always still do so by calling
+`FlatBufferBuilder::Finish` explicitly.
+
+After loading a buffer, you can use a call like
+`MonsterBufferHasIdentifier` to check if the identifier is present.
+
+Note that this is best for open-ended uses such as files. If you simply wanted
+to send one of a set of possible messages over a network for example, you'd
+be better off with a union.
+
+Additionally, by default `flatc` will output binary files as `.bin`.
+This declaration in the schema will change that to whatever you want:
+
+    file_extension "ext";
+
+### RPC interface declarations
+
+You can declare RPC calls in a schema, that define a set of functions
+that take a FlatBuffer as an argument (the request) and return a FlatBuffer
+as the response (both of which must be table types):
+
+    rpc_service MonsterStorage {
+      Store(Monster):StoreResponse;
+      Retrieve(MonsterId):Monster;
+    }
+
+What code this produces and how it is used depends on language and RPC system
+used, there is preliminary support for GRPC through the `--grpc` code generator,
+see `grpc/tests` for an example.
+
+### Comments & documentation
+
+May be written as in most C-based languages. Additionally, a triple
+comment (`///`) on a line by itself signals that a comment is documentation
+for whatever is declared on the line after it
+(table/struct/field/enum/union/element), and the comment is output
+in the corresponding C++ code. Multiple such lines per item are allowed.
+
+### Attributes
+
+Attributes may be attached to a declaration, behind a field, or after
+the name of a table/struct/enum/union. These may either have a value or
+not. Some attributes like `deprecated` are understood by the compiler;
+user defined ones need to be declared with the attribute declaration
+(like `priority` in the example above), and are
+available to query if you parse the schema at runtime.
+This is useful if you write your own code generators/editors etc., and
+you wish to add additional information specific to your tool (such as a
+help text).
+
+Current understood attributes:
+
+-   `id: n` (on a table field): manually set the field identifier to `n`.
+    If you use this attribute, you must use it on ALL fields of this table,
+    and the numbers must be a contiguous range from 0 onwards.
+    Additionally, since a union type effectively adds two fields, its
+    id must be that of the second field (the first field is the type
+    field and not explicitly declared in the schema).
+    For example, if the last field before the union field had id 6,
+    the union field should have id 8, and the unions type field will
+    implicitly be 7.
+    IDs allow the fields to be placed in any order in the schema.
+    When a new field is added to the schema it must use the next available ID.
+-   `deprecated` (on a field): do not generate accessors for this field
+    anymore, code should stop using this data. Old data may still contain this
+    field, but it won't be accessible anymore by newer code. Note that if you
+    deprecate a field that was previous required, old code may fail to validate
+    new data (when using the optional verifier).
+-   `required` (on a non-scalar table field): this field must always be set.
+    By default, all fields are optional, i.e. may be left out. This is
+    desirable, as it helps with forwards/backwards compatibility, and
+    flexibility of data structures. It is also a burden on the reading code,
+    since for non-scalar fields it requires you to check against NULL and
+    take appropriate action. By specifying this field, you force code that
+    constructs FlatBuffers to ensure this field is initialized, so the reading
+    code may access it directly, without checking for NULL. If the constructing
+    code does not initialize this field, they will get an assert, and also
+    the verifier will fail on buffers that have missing required fields. Note
+    that if you add this attribute to an existing field, this will only be
+    valid if existing data always contains this field / existing code always
+    writes this field.
+-   `force_align: size` (on a struct): force the alignment of this struct
+    to be something higher than what it is naturally aligned to. Causes
+    these structs to be aligned to that amount inside a buffer, IF that
+    buffer is allocated with that alignment (which is not necessarily
+    the case for buffers accessed directly inside a `FlatBufferBuilder`).
+    Note: currently not guaranteed to have an effect when used with
+    `--object-api`, since that may allocate objects at alignments less than
+    what you specify with `force_align`.
+-   `bit_flags` (on an unsigned enum): the values of this field indicate bits,
+    meaning that any unsigned value N specified in the schema will end up
+    representing 1<<N, or if you don't specify values at all, you'll get
+    the sequence 1, 2, 4, 8, ...
+-   `nested_flatbuffer: "table_name"` (on a field): this indicates that the field
+    (which must be a vector of ubyte) contains flatbuffer data, for which the
+    root type is given by `table_name`. The generated code will then produce
+    a convenient accessor for the nested FlatBuffer.
+-   `flexbuffer` (on a field): this indicates that the field
+    (which must be a vector of ubyte) contains flexbuffer data. The generated
+    code will then produce a convenient accessor for the FlexBuffer root.
+-   `key` (on a field): this field is meant to be used as a key when sorting
+    a vector of the type of table it sits in. Can be used for in-place
+    binary search.
+-   `hash` (on a field). This is an (un)signed 32/64 bit integer field, whose
+    value during JSON parsing is allowed to be a string, which will then be
+    stored as its hash. The value of attribute is the hashing algorithm to
+    use, one of `fnv1_32` `fnv1_64` `fnv1a_32` `fnv1a_64`.
+-   `original_order` (on a table): since elements in a table do not need
+    to be stored in any particular order, they are often optimized for
+    space by sorting them to size. This attribute stops that from happening.
+    There should generally not be any reason to use this flag.
+-   'native_*'.  Several attributes have been added to support the [C++ object
+    Based API](@ref flatbuffers_cpp_object_based_api).  All such attributes
+    are prefixed with the term "native_".
+
+
+## JSON Parsing
+
+The same parser that parses the schema declarations above is also able
+to parse JSON objects that conform to this schema. So, unlike other JSON
+parsers, this parser is strongly typed, and parses directly into a FlatBuffer
+(see the compiler documentation on how to do this from the command line, or
+the C++ documentation on how to do this at runtime).
+
+Besides needing a schema, there are a few other changes to how it parses
+JSON:
+
+-   It accepts field names with and without quotes, like many JSON parsers
+    already do. It outputs them without quotes as well, though can be made
+    to output them using the `strict_json` flag.
+-   If a field has an enum type, the parser will recognize symbolic enum
+    values (with or without quotes) instead of numbers, e.g.
+    `field: EnumVal`. If a field is of integral type, you can still use
+    symbolic names, but values need to be prefixed with their type and
+    need to be quoted, e.g. `field: "Enum.EnumVal"`. For enums
+    representing flags, you may place multiple inside a string
+    separated by spaces to OR them, e.g.
+    `field: "EnumVal1 EnumVal2"` or `field: "Enum.EnumVal1 Enum.EnumVal2"`.
+-   Similarly, for unions, these need to specified with two fields much like
+    you do when serializing from code. E.g. for a field `foo`, you must
+    add a field `foo_type: FooOne` right before the `foo` field, where
+    `FooOne` would be the table out of the union you want to use.
+-   A field that has the value `null` (e.g. `field: null`) is intended to
+    have the default value for that field (thus has the same effect as if
+    that field wasn't specified at all).
+-   It has some built in conversion functions, so you can write for example
+    `rad(180)` where ever you'd normally write `3.14159`.
+    Currently supports the following functions: `rad`, `deg`, `cos`, `sin`,
+    `tan`, `acos`, `asin`, `atan`.
+
+When parsing JSON, it recognizes the following escape codes in strings:
+
+-   `\n` - linefeed.
+-   `\t` - tab.
+-   `\r` - carriage return.
+-   `\b` - backspace.
+-   `\f` - form feed.
+-   `\"` - double quote.
+-   `\\` - backslash.
+-   `\/` - forward slash.
+-   `\uXXXX` - 16-bit unicode code point, converted to the equivalent UTF-8
+    representation.
+-   `\xXX` - 8-bit binary hexadecimal number XX. This is the only one that is
+     not in the JSON spec (see http://json.org/), but is needed to be able to
+     encode arbitrary binary in strings to text and back without losing
+     information (e.g. the byte 0xFF can't be represented in standard JSON).
+
+It also generates these escape codes back again when generating JSON from a
+binary representation.
+
+When parsing numbers, the parser is more flexible than JSON.
+A format of numeric literals is more close to the C/C++.
+According to the [grammar](@ref flatbuffers_grammar), it accepts the following
+numerical literals:
+
+-   An integer literal can have any number of leading zero `0` digits.
+    Unlike C/C++, the parser ignores a leading zero, not interpreting it as the
+    beginning of the octal number.
+    The numbers `[081, -00094]` are equal to `[81, -94]`  decimal integers.
+-   The parser accepts unsigned and signed hexadecimal integer numbers.
+    For example: `[0x123, +0x45, -0x67]` are equal to `[291, 69, -103]` decimals.
+-   The format of float-point numbers is fully compatible with C/C++ format.
+    If a modern C++ compiler is used the parser accepts hexadecimal and special
+    floating-point literals as well:
+    `[-1.0, 2., .3e0, 3.e4, 0x21.34p-5, -inf, nan]`.
+
+    The following conventions for floating-point numbers are used:
+    - The exponent suffix of hexadecimal floating-point number is mandatory.
+    - Parsed `NaN` converted to unsigned IEEE-754 `quiet-NaN` value.
+
+    Extended floating-point support was tested with:
+    - x64 Windows: `MSVC2015` and higher.
+    - x64 Linux: `LLVM 6.0`, `GCC 4.9` and higher.
+
+    For details, see [Use in C++](@ref flatbuffers_guide_use_cpp) section.
+
+-   For compatibility with a JSON lint tool all numeric literals of scalar
+    fields can be wrapped to quoted string:
+    `"1", "2.0", "0x48A", "0x0C.0Ep-1", "-inf", "true"`.
+
+## Guidelines
+
+### Efficiency
+
+FlatBuffers is all about efficiency, but to realize that efficiency you
+require an efficient schema. There are usually multiple choices on
+how to represent data that have vastly different size characteristics.
+
+It is very common nowadays to represent any kind of data as dictionaries
+(as in e.g. JSON), because of its flexibility and extensibility. While
+it is possible to emulate this in FlatBuffers (as a vector
+of tables with key and value(s)), this is a bad match for a strongly
+typed system like FlatBuffers, leading to relatively large binaries.
+FlatBuffer tables are more flexible than classes/structs in most systems,
+since having a large number of fields only few of which are actually
+used is still efficient. You should thus try to organize your data
+as much as possible such that you can use tables where you might be
+tempted to use a dictionary.
+
+Similarly, strings as values should only be used when they are
+truely open-ended. If you can, always use an enum instead.
+
+FlatBuffers doesn't have inheritance, so the way to represent a set
+of related data structures is a union. Unions do have a cost however,
+so an alternative to a union is to have a single table that has
+all the fields of all the data structures you are trying to
+represent, if they are relatively similar / share many fields.
+Again, this is efficient because optional fields are cheap.
+
+FlatBuffers supports the full range of integer sizes, so try to pick
+the smallest size needed, rather than defaulting to int/long.
+
+Remember that you can share data (refer to the same string/table
+within a buffer), so factoring out repeating data into its own
+data structure may be worth it.
+
+### Style guide
+
+Identifiers in a schema are meant to translate to many different programming
+languages, so using the style of your "main" language is generally a bad idea.
+
+For this reason, below is a suggested style guide to adhere to, to keep schemas
+consistent for interoperation regardless of the target language.
+
+Where possible, the code generators for specific languages will generate
+identifiers that adhere to the language style, based on the schema identifiers.
+
+- Table, struct, enum and rpc names (types): UpperCamelCase.
+- Table and struct field names: snake_case. This is translated to lowerCamelCase
+  automatically for some languages, e.g. Java.
+- Enum values: UpperCamelCase.
+- namespaces: UpperCamelCase.
+
+Formatting (this is less important, but still worth adhering to):
+
+- Opening brace: on the same line as the start of the declaration.
+- Spacing: Indent by 2 spaces. None around `:` for types, on both sides for `=`.
+
+For an example, see the schema at the top of this file.
+
+## Gotchas
+
+### Schemas and version control
+
+FlatBuffers relies on new field declarations being added at the end, and earlier
+declarations to not be removed, but be marked deprecated when needed. We think
+this is an improvement over the manual number assignment that happens in
+Protocol Buffers (and which is still an option using the `id` attribute
+mentioned above).
+
+One place where this is possibly problematic however is source control. If user
+A adds a field, generates new binary data with this new schema, then tries to
+commit both to source control after user B already committed a new field also,
+and just auto-merges the schema, the binary files are now invalid compared to
+the new schema.
+
+The solution of course is that you should not be generating binary data before
+your schema changes have been committed, ensuring consistency with the rest of
+the world. If this is not practical for you, use explicit field ids, which
+should always generate a merge conflict if two people try to allocate the same
+id.
+
+### Schema evolution examples
+
+Some examples to clarify what happens as you change a schema:
+
+If we have the following original schema:
+
+    table { a:int; b:int; }
+
+And we extend it:
+
+    table { a:int; b:int; c:int; }
+
+This is ok. Code compiled with the old schema reading data generated with the
+new one will simply ignore the presence of the new field. Code compiled with the
+new schema reading old data will get the default value for `c` (which is 0
+in this case, since it is not specified).
+
+    table { a:int (deprecated); b:int; }
+
+This is also ok. Code compiled with the old schema reading newer data will now
+always get the default value for `a` since it is not present. Code compiled
+with the new schema now cannot read nor write `a` anymore (any existing code
+that tries to do so will result in compile errors), but can still read
+old data (they will ignore the field).
+
+    table { c:int a:int; b:int; }
+
+This is NOT ok, as this makes the schemas incompatible. Old code reading newer
+data will interpret `c` as if it was `a`, and new code reading old data
+accessing `a` will instead receive `b`.
+
+    table { c:int (id: 2); a:int (id: 0); b:int (id: 1); }
+
+This is ok. If your intent was to order/group fields in a way that makes sense
+semantically, you can do so using explicit id assignment. Now we are compatible
+with the original schema, and the fields can be ordered in any way, as long as
+we keep the sequence of ids.
+
+    table { b:int; }
+
+NOT ok. We can only remove a field by deprecation, regardless of wether we use
+explicit ids or not.
+
+    table { a:uint; b:uint; }
+
+This is MAYBE ok, and only in the case where the type change is the same size,
+like here. If old data never contained any negative numbers, this will be
+safe to do.
+
+    table { a:int = 1; b:int = 2; }
+
+Generally NOT ok. Any older data written that had 0 values were not written to
+the buffer, and rely on the default value to be recreated. These will now have
+those values appear to `1` and `2` instead. There may be cases in which this
+is ok, but care must be taken.
+
+    table { aa:int; bb:int; }
+
+Occasionally ok. You've renamed fields, which will break all code (and JSON
+files!) that use this schema, but as long as the change is obvious, this is not
+incompatible with the actual binary buffers, since those only ever address
+fields by id/offset.
+<br>
+
+### Testing whether a field is present in a table
+
+Most serialization formats (e.g. JSON or Protocol Buffers) make it very
+explicit in the format whether a field is present in an object or not,
+allowing you to use this as "extra" information.
+
+In FlatBuffers, this also holds for everything except scalar values.
+
+FlatBuffers by default will not write fields that are equal to the default
+value (for scalars), sometimes resulting in a significant space savings.
+
+However, this also means testing whether a field is "present" is somewhat
+meaningless, since it does not tell you if the field was actually written by
+calling `add_field` style calls, unless you're only interested in this
+information for non-default values.
+
+Some `FlatBufferBuilder` implementations have an option called `force_defaults`
+that circumvents this behavior, and writes fields even if they are equal to
+the default. You can then use `IsFieldPresent` to query this.
+
+Another option that works in all languages is to wrap a scalar field in a
+struct. This way it will return null if it is not present. The cool thing
+is that structs don't take up any more space than the scalar they represent.
+
+   [Interface Definition Language]: https://en.wikipedia.org/wiki/Interface_description_language
diff --git a/third_party/flatbuffers/docs/source/Support.md b/third_party/flatbuffers/docs/source/Support.md
new file mode 100644
index 0000000..c8ac7f7
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/Support.md
@@ -0,0 +1,46 @@
+Platform / Language / Feature support    {#flatbuffers_support}
+=====================================
+
+FlatBuffers is actively being worked on, which means that certain platform /
+language / feature combinations may not be available yet.
+
+This page tries to track those issues, to make informed decisions easier.
+In general:
+
+  * Languages: language support beyond the ones created by the original
+    FlatBuffer authors typically depends on community contributions.
+  * Features: C++ was the first language supported, since our original
+    target was high performance game development. It thus has the richest
+    feature set, and is likely most robust. Other languages are catching up
+    however.
+  * Platforms: All language implementations are typically portable to most
+    platforms, unless where noted otherwise.
+
+NOTE: this table is a start, it needs to be extended.
+
+Feature                        | C++    | Java   | C#     | Go     | Python | JS        | TS        | C       | PHP | Dart    | Lobster | Rust
+------------------------------ | ------ | ------ | ------ | ------ | ------ | --------- | --------- | ------  | --- | ------- | ------- | ----
+Codegen for all basic features | Yes    | Yes    | Yes    | Yes    | Yes    | Yes       | Yes       | Yes     | WiP | Yes     | Yes     | Yes
+JSON parsing                   | Yes    | No     | No     | No     | No     | No        | No        | Yes     | No  | No      | Yes     | No
+Simple mutation                | Yes    | Yes    | Yes    | Yes    | No     | No        | No        | No      | No  | No      | No      | No
+Reflection                     | Yes    | No     | No     | No     | No     | No        | No        | Basic   | No  | No      | No      | No
+Buffer verifier                | Yes    | No     | No     | No     | No     | No        | No        | Yes     | No  | No      | No      | No
+Testing: basic                 | Yes    | Yes    | Yes    | Yes    | Yes    | Yes       | Yes       | Yes     | ?   | Yes     | Yes     | Yes
+Testing: fuzz                  | Yes    | No     | No     | Yes    | Yes    | No        | No        | No      | ?   | No      | No      | Yes
+Performance:                   | Superb | Great  | Great  | Great  | Ok     | ?         | ?         | Superb  | ?   | ?       | Great   | Superb
+Platform: Windows              | VS2010 | Yes    | Yes    | ?      | ?      | ?         | Yes       | VS2010  | ?   | Yes     | Yes     | Yes
+Platform: Linux                | GCC282 | Yes    | ?      | Yes    | Yes    | ?         | Yes       | Yes     | ?   | Yes     | Yes     | Yes
+Platform: OS X                 | Xcode4 | ?      | ?      | ?      | Yes    | ?         | Yes       | Yes     | ?   | Yes     | Yes     | Yes
+Platform: Android              | NDK10d | Yes    | ?      | ?      | ?      | ?         | ?         | ?       | ?   | Flutter | Yes     | ?
+Platform: iOS                  | ?      | ?      | ?      | ?      | ?      | ?         | ?         | ?       | ?   | Flutter | Yes     | ?
+Engine: Unity                  | ?      | ?      | Yes    | ?      | ?      | ?         | ?         | ?       | ?   | ?       | No      | ?
+Primary authors (github)       | aard*  | aard*  | ev*/js*| rw     | rw     | evanw/ev* | kr*       | mik*    | ch* | dnfield | aard*   | rw
+
+  * aard = aardappel (previously: gwvo)
+  * ev = evolutional
+  * js = jonsimantov
+  * mik = mikkelfj
+  * ch = chobie
+  * kr = krojew
+
+<br>
diff --git a/third_party/flatbuffers/docs/source/Tutorial.md b/third_party/flatbuffers/docs/source/Tutorial.md
new file mode 100644
index 0000000..e8d8519
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/Tutorial.md
@@ -0,0 +1,3219 @@
+Tutorial   {#flatbuffers_guide_tutorial}
+========
+
+## Overview
+
+This tutorial provides a basic example of how to work with
+[FlatBuffers](@ref flatbuffers_overview). We will step through a simple example
+application, which shows you how to:
+
+   - Write a FlatBuffer `schema` file.
+   - Use the `flatc` FlatBuffer compiler.
+   - Parse [JSON](http://json.org) files that conform to a schema into
+     FlatBuffer binary files.
+   - Use the generated files in many of the supported languages (such as C++,
+     Java, and more.)
+
+During this example, imagine that you are creating a game where the main
+character, the hero of the story, needs to slay some `orc`s. We will walk
+through each step necessary to create this monster type using FlatBuffers.
+
+Please select your desired language for our quest:
+\htmlonly
+<form>
+  <input type="radio" name="language" value="cpp" checked="checked">C++</input>
+  <input type="radio" name="language" value="java">Java</input>
+  <input type="radio" name="language" value="kotlin">Kotlin</input>
+  <input type="radio" name="language" value="csharp">C#</input>
+  <input type="radio" name="language" value="go">Go</input>
+  <input type="radio" name="language" value="python">Python</input>
+  <input type="radio" name="language" value="javascript">JavaScript</input>
+  <input type="radio" name="language" value="typescript">TypeScript</input>
+  <input type="radio" name="language" value="php">PHP</input>
+  <input type="radio" name="language" value="c">C</input>
+  <input type="radio" name="language" value="dart">Dart</input>
+  <input type="radio" name="language" value="lua">Lua</input>
+  <input type="radio" name="language" value="lobster">Lobster</input>
+  <input type="radio" name="language" value="rust">Rust</input>
+</form>
+\endhtmlonly
+
+\htmlonly
+<script>
+  /**
+   * Check if an HTML `class` attribute is in the language-specific format.
+   * @param {string} languageClass An HTML `class` attribute in the format
+   * 'language-{lang}', where {lang} is a programming language (e.g. 'cpp',
+   * 'java', 'go', etc.).
+   * @return {boolean} Returns `true` if `languageClass` was in the valid
+   * format, prefixed with 'language-'. Otherwise, it returns false.
+   */
+  function isProgrammingLanguageClassName(languageClass) {
+    if (languageClass && languageClass.substring(0, 9) == 'language-' &&
+        languageClass.length > 8) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  /**
+   * Given a language-specific HTML `class` attribute, extract the language.
+   * @param {string} languageClass The string name of an HTML `class` attribute,
+   * in the format `language-{lang}`, where {lang} is a programming language
+   * (e.g. 'cpp', 'java', 'go', etc.).
+   * @return {string} Returns a string containing only the {lang} portion of
+   * the class name. If the input was invalid, then it returns `null`.
+   */
+  function extractProgrammingLanguageFromLanguageClass(languageClass) {
+    if (isProgrammingLanguageClassName(languageClass)) {
+      return languageClass.substring(9);
+    } else {
+      return null;
+    }
+  }
+
+  /**
+   * Hide every code snippet, except for the language that is selected.
+   */
+  function displayChosenLanguage() {
+    var selection = $('input:checked').val();
+
+    var htmlElements = document.getElementsByTagName('*');
+    for (var i = 0; i < htmlElements.length; i++) {
+      if (isProgrammingLanguageClassName(htmlElements[i].className)) {
+        if (extractProgrammingLanguageFromLanguageClass(
+              htmlElements[i].className).toLowerCase() != selection) {
+          htmlElements[i].style.display = 'none';
+        } else {
+          htmlElements[i].style.display = 'initial';
+        }
+      }
+    }
+  }
+
+  $( document ).ready(displayChosenLanguage);
+
+  $('input[type=radio]').on("click", displayChosenLanguage);
+</script>
+\endhtmlonly
+
+## Where to Find the Example Code
+
+Samples demonstating the concepts in this example are located in the source code
+package, under the `samples` directory. You can browse the samples on GitHub
+[here](https://github.com/google/flatbuffers/tree/master/samples).
+
+<div class="language-c">
+*Note: The above does not apply to C, instead [look here](https://github.com/dvidelabs/flatcc/tree/master/samples).*
+</div>
+
+For your chosen language, please cross-reference with:
+
+<div class="language-cpp">
+[sample_binary.cpp](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.cpp)
+</div>
+<div class="language-java">
+[SampleBinary.java](https://github.com/google/flatbuffers/blob/master/samples/SampleBinary.java)
+</div>
+<div class="language-kotlin">
+[SampleBinary.kt](https://github.com/google/flatbuffers/blob/master/samples/SampleBinary.kt)
+</div>
+<div class="language-csharp">
+[SampleBinary.cs](https://github.com/google/flatbuffers/blob/master/samples/SampleBinary.cs)
+</div>
+<div class="language-go">
+[sample_binary.go](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.go)
+</div>
+<div class="language-python">
+[sample_binary.py](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.py)
+</div>
+<div class="language-javascript">
+[samplebinary.js](https://github.com/google/flatbuffers/blob/master/samples/samplebinary.js)
+</div>
+<div class="language-typescript">
+<em>none yet</em>
+</div>
+<div class="language-php">
+[SampleBinary.php](https://github.com/google/flatbuffers/blob/master/samples/SampleBinary.php)
+</div>
+<div class="language-c">
+[monster.c](https://github.com/dvidelabs/flatcc/blob/master/samples/monster/monster.c)
+</div>
+<div class="language-dart">
+[example.dart](https://github.com/google/flatbuffers/blob/master/dart/example/example.dart)
+</div>
+<div class="language-lua">
+[sample_binary.lua](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.lua)
+</div>
+<div class="language-lobster">
+[sample_binary.lobster](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.lobster)
+</div>
+<div class="language-rust">
+[sample_binary.rs](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.rs)
+</div>
+
+
+## Writing the Monsters' FlatBuffer Schema
+
+To start working with FlatBuffers, you first need to create a `schema` file,
+which defines the format for each data structure you wish to serialize. Here is
+the `schema` that defines the template for our monsters:
+
+~~~
+  // Example IDL file for our monster's schema.
+
+  namespace MyGame.Sample;
+
+  enum Color:byte { Red = 0, Green, Blue = 2 }
+
+  union Equipment { Weapon } // Optionally add more tables.
+
+  struct Vec3 {
+    x:float;
+    y:float;
+    z:float;
+  }
+
+  table Monster {
+    pos:Vec3; // Struct.
+    mana:short = 150;
+    hp:short = 100;
+    name:string;
+    friendly:bool = false (deprecated);
+    inventory:[ubyte];  // Vector of scalars.
+    color:Color = Blue; // Enum.
+    weapons:[Weapon];   // Vector of tables.
+    equipped:Equipment; // Union.
+    path:[Vec3];        // Vector of structs.
+  }
+
+  table Weapon {
+    name:string;
+    damage:short;
+  }
+
+  root_type Monster;
+~~~
+
+As you can see, the syntax for the `schema`
+[Interface Definition Language (IDL)](https://en.wikipedia.org/wiki/Interface_description_language)
+is similar to those of the C family of languages, and other IDL languages. Let's
+examine each part of this `schema` to determine what it does.
+
+The `schema` starts with a `namespace` declaration. This determines the
+corresponding package/namespace for the generated code. In our example, we have
+the `Sample` namespace inside of the `MyGame` namespace.
+
+Next, we have an `enum` definition. In this example, we have an `enum` of type
+`byte`, named `Color`. We have three values in this `enum`: `Red`, `Green`, and
+`Blue`. We specify `Red = 0` and `Blue = 2`, but we do not specify an explicit
+value for `Green`. Since the behavior of an `enum` is to increment if
+unspecified, `Green` will receive the implicit value of `1`.
+
+Following the `enum` is a `union`. The `union` in this example is not very
+useful, as it only contains the one `table` (named `Weapon`). If we had created
+multiple tables that we would want the `union` to be able to reference, we
+could add more elements to the `union Equipment`.
+
+After the `union` comes a `struct Vec3`, which represents a floating point
+vector with `3` dimensions. We use a `struct` here, over a `table`, because
+`struct`s are ideal for data structures that will not change, since they use
+less memory and have faster lookup.
+
+The `Monster` table is the main object in our FlatBuffer. This will be used as
+the template to store our `orc` monster. We specify some default values for
+fields, such as `mana:short = 150`. All unspecified fields will default to `0`
+or `NULL`. Another thing to note is the line
+`friendly:bool = false (deprecated);`. Since you cannot delete fields from a
+`table` (to support backwards compatability), you can set fields as
+`deprecated`, which will prevent the generation of accessors for this field in
+the generated code. Be careful when using `deprecated`, however, as it may break
+legacy code that used this accessor.
+
+The `Weapon` table is a sub-table used within our FlatBuffer. It is
+used twice: once within the `Monster` table and once within the `Equipment`
+enum. For our `Monster`, it is used to populate a `vector of tables` via the
+`weapons` field within our `Monster`. It is also the only table referenced by
+the `Equipment` union.
+
+The last part of the `schema` is the `root_type`. The root type declares what
+will be the root table for the serialized data. In our case, the root type is
+our `Monster` table.
+
+The scalar types can also use alias type names such as `int16` instead
+of `short` and `float32` instead of `float`. Thus we could also write
+the `Weapon` table as:
+
+  table Weapon {
+    name:string;
+    damage:int16;
+  }
+
+#### More Information About Schemas
+
+You can find a complete guide to writing `schema` files in the
+[Writing a schema](@ref flatbuffers_guide_writing_schema) section of the
+Programmer's Guide. You can also view the formal
+[Grammar of the schema language](@ref flatbuffers_grammar).
+
+## Compiling the Monsters' Schema
+
+After you have written the FlatBuffers schema, the next step is to compile it.
+
+If you have not already done so, please follow
+[these instructions](@ref flatbuffers_guide_building) to build `flatc`, the
+FlatBuffer compiler.
+
+Once `flatc` is built successfully, compile the schema for your language:
+
+<div class="language-c">
+*Note: If you're working in C, you need to use the separate project [FlatCC](https://github.com/dvidelabs/flatcc) which contains a schema compiler and runtime library in C for C.*
+<br>
+See [flatcc build instructions](https://github.com/dvidelabs/flatcc#building).
+<br>
+Please be aware of the difference between `flatc` and `flatcc` tools.
+<br>
+</div>
+
+<div class="language-cpp">
+~~~{.sh}
+  cd flatbuffers/samples
+  ./../flatc --cpp monster.fbs
+~~~
+</div>
+<div class="language-java">
+~~~{.sh}
+  cd flatbuffers/samples
+  ./../flatc --java monster.fbs
+~~~
+</div>
+<div class="language-kotlin">
+~~~{.sh}
+  cd flatbuffers/samples
+  ./../flatc --kotlin monster.fbs
+~~~
+</div>
+<div class="language-csharp">
+~~~{.sh}
+  cd flatbuffers/samples
+  ./../flatc --csharp monster.fbs
+~~~
+</div>
+<div class="language-go">
+~~~{.sh}
+  cd flatbuffers/samples
+  ./../flatc --go monster.fbs
+~~~
+</div>
+<div class="language-python">
+~~~{.sh}
+  cd flatbuffers/samples
+  ./../flatc --python monster.fbs
+~~~
+</div>
+<div class="language-javascript">
+~~~{.sh}
+  cd flatbuffers/samples
+  ./../flatc --js monster.fbs
+~~~
+</div>
+<div class="language-typescript">
+~~~{.sh}
+  cd flatbuffers/samples
+  ./../flatc --ts monster.fbs
+~~~
+</div>
+<div class="language-php">
+~~~{.sh}
+  cd flatbuffers/sample
+  ./../flatc --php monster.fbs
+~~~
+</div>
+<div class="language-c">
+~~~{.sh}
+  cd flatcc
+  mkdir -p build/tmp/samples/monster
+  bin/flatcc -a -o build/tmp/samples/monster samples/monster/monster.fbs
+  # or just
+  flatcc/samples/monster/build.sh
+~~~
+</div>
+<div class="language-dart">
+~~~{.sh}
+  cd flatbuffers/samples
+  ./../flatc --dart monster.fbs
+~~~
+</div>
+<div class="language-lua">
+~~~{.sh}
+  cd flatbuffers/samples
+  ./../flatc --lua monster.fbs
+~~~
+</div>
+<div class="language-lobster">
+~~~{.sh}
+  cd flatbuffers/samples
+  ./../flatc --lobster monster.fbs
+~~~
+</div>
+<div class="language-rust">
+~~~{.sh}
+  cd flatbuffers/samples
+  ./../flatc --rust monster.fbs
+~~~
+</div>
+
+For a more complete guide to using the `flatc` compiler, please read the
+[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler)
+section of the Programmer's Guide.
+
+## Reading and Writing Monster FlatBuffers
+
+Now that we have compiled the schema for our programming language, we can
+start creating some monsters and serializing/deserializing them from
+FlatBuffers.
+
+#### Creating and Writing Orc FlatBuffers
+
+The first step is to import/include the library, generated files, etc.
+
+<div class="language-cpp">
+~~~{.cpp}
+  #include "monster_generated.h" // This was generated by `flatc`.
+
+  using namespace MyGame::Sample; // Specified in the schema.
+~~~
+</div>
+<div class="language-java">
+~~~{.java}
+  import MyGame.Sample.*; //The `flatc` generated files. (Monster, Vec3, etc.)
+
+  import com.google.flatbuffers.FlatBufferBuilder;
+~~~
+</div>
+<div class="language-kotlin">
+~~~{.kotlin}
+  import MyGame.Sample.* //The `flatc` generated files. (Monster, Vec3, etc.)
+
+  import com.google.flatbuffers.FlatBufferBuilder
+~~~
+</div>
+<div class="language-csharp">
+~~~{.cs}
+  using FlatBuffers;
+  using MyGame.Sample; // The `flatc` generated files. (Monster, Vec3, etc.)
+~~~
+</div>
+<div class="language-go">
+~~~{.go}
+  import (
+          flatbuffers "github.com/google/flatbuffers/go"
+          sample "MyGame/Sample"
+  )
+~~~
+</div>
+<div class="language-python">
+~~~{.py}
+  import flatbuffers
+
+  # Generated by `flatc`.
+  import MyGame.Sample.Color
+  import MyGame.Sample.Equipment
+  import MyGame.Sample.Monster
+  import MyGame.Sample.Vec3
+  import MyGame.Sample.Weapon
+~~~
+</div>
+<div class="language-javascript">
+~~~{.js}
+  // The following code is for JavaScript module loaders (e.g. Node.js). See
+  // below for a browser-based HTML/JavaScript example of including the library.
+  var flatbuffers = require('/js/flatbuffers').flatbuffers;
+  var MyGame = require('./monster_generated').MyGame; // Generated by `flatc`.
+
+  //--------------------------------------------------------------------------//
+
+  // The following code is for browser-based HTML/JavaScript. Use the above code
+  // for JavaScript module loaders (e.g. Node.js).
+  <script src="../js/flatbuffers.js"></script>
+  <script src="monster_generated.js"></script> // Generated by `flatc`.
+~~~
+</div>
+<div class="language-typescript">
+  // note: import flatbuffers with your desired import method
+
+  import { MyGame } from './monster_generated';
+</div>
+<div class="language-php">
+~~~{.php}
+  // It is recommended that your use PSR autoload when using FlatBuffers in PHP.
+  // Here is an example from `SampleBinary.php`:
+  function __autoload($class_name) {
+    // The last segment of the class name matches the file name.
+    $class = substr($class_name, strrpos($class_name, "\\") + 1);
+    $root_dir = join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)))); // `flatbuffers` root.
+
+    // Contains the `*.php` files for the FlatBuffers library and the `flatc` generated files.
+    $paths = array(join(DIRECTORY_SEPARATOR, array($root_dir, "php")),
+                   join(DIRECTORY_SEPARATOR, array($root_dir, "samples", "MyGame", "Sample")));
+    foreach ($paths as $path) {
+      $file = join(DIRECTORY_SEPARATOR, array($path, $class . ".php"));
+      if (file_exists($file)) {
+        require($file);
+        break;
+      }
+    }
+  }
+~~~
+</div>
+<div class="language-c">
+~~~{.c}
+  #include "monster_builder.h" // Generated by `flatcc`.
+
+  // Convenient namespace macro to manage long namespace prefix.
+  #undef ns
+  #define ns(x) FLATBUFFERS_WRAP_NAMESPACE(MyGame_Sample, x) // Specified in the schema.
+
+  // A helper to simplify creating vectors from C-arrays.
+  #define c_vec_len(V) (sizeof(V)/sizeof((V)[0]))
+~~~
+</div>
+<div class="language-dart">
+~~~{.dart}
+  import 'package:flat_buffers/flat_buffers.dart' as fb;
+
+  // Generated by `flatc`.
+  import 'monster_my_game.sample_generated.dart' as myGame;
+~~~
+</div>
+<div class="language-lua">
+~~~{.lua}
+  -- require the flatbuffers module
+  local flatbuffers = require("flatbuffers")
+
+  -- require the generated files from `flatc`.
+  local color = require("MyGame.Sample.Color")
+  local equipment = require("MyGame.Sample.Equipment")
+  local monster = require("MyGame.Sample.Monster")
+  local vec3 = require("MyGame.Sample.Vec3")
+  local weapon = require("MyGame.Sample.Weapon")
+~~~
+</div>
+<div class="language-lobster">
+~~~{.lobster}
+  import from "../lobster/"  // Where to find flatbuffers.lobster
+  import monster_generated
+~~~
+</div>
+<div class="language-rust">
+~~~{.rs}
+  // import the flatbuffers runtime library
+  extern crate flatbuffers;
+
+  // import the generated code
+  #[allow(dead_code, unused_imports)]
+  #[path = "./monster_generated.rs"]
+  mod monster_generated;
+  pub use monster_generated::my_game::sample::{get_root_as_monster,
+                                               Color, Equipment,
+                                               Monster, MonsterArgs,
+                                               Vec3,
+                                               Weapon, WeaponArgs};
+~~~
+</div>
+
+Now we are ready to start building some buffers. In order to start, we need
+to create an instance of the `FlatBufferBuilder`, which will contain the buffer
+as it grows. You can pass an initial size of the buffer (here 1024 bytes),
+which will grow automatically if needed:
+
+<div class="language-cpp">
+~~~{.cpp}
+  // Create a `FlatBufferBuilder`, which will be used to create our
+  // monsters' FlatBuffers.
+  flatbuffers::FlatBufferBuilder builder(1024);
+~~~
+</div>
+<div class="language-java">
+~~~{.java}
+  // Create a `FlatBufferBuilder`, which will be used to create our
+  // monsters' FlatBuffers.
+  FlatBufferBuilder builder = new FlatBufferBuilder(1024);
+~~~
+</div>
+<div class="language-kotlin">
+~~~{.kt}
+  // Create a `FlatBufferBuilder`, which will be used to create our
+  // monsters' FlatBuffers.
+  val builder = FlatBufferBuilder(1024)
+~~~
+</div>
+<div class="language-csharp">
+~~~{.cs}
+  // Create a `FlatBufferBuilder`, which will be used to create our
+  // monsters' FlatBuffers.
+  var builder = new FlatBufferBuilder(1024);
+~~~
+</div>
+<div class="language-go">
+~~~{.go}
+  // Create a `FlatBufferBuilder`, which will be used to create our
+  // monsters' FlatBuffers.
+  builder := flatbuffers.NewBuilder(1024)
+~~~
+</div>
+<div class="language-python">
+~~~{.py}
+  # Create a `FlatBufferBuilder`, which will be used to create our
+  # monsters' FlatBuffers.
+  builder = flatbuffers.Builder(1024)
+~~~
+</div>
+<div class="language-javascript">
+~~~{.js}
+  // Create a `flatbuffer.Builder`, which will be used to create our
+  // monsters' FlatBuffers.
+  var builder = new flatbuffers.Builder(1024);
+~~~
+</div>
+<div class="language-typescript">
+~~~{.ts}
+  // Create a `flatbuffer.Builder`, which will be used to create our
+  // monsters' FlatBuffers.
+  let builder = new flatbuffers.Builder(1024);
+~~~
+</div>
+<div class="language-php">
+~~~{.php}
+  // Create a `FlatBufferBuilder`, which will be used to create our
+  // monsters' FlatBuffers.
+  $builder = new Google\FlatBuffers\FlatbufferBuilder(1024);
+~~~
+</div>
+<div class="language-c">
+~~~{.c}
+    flatcc_builder_t builder, *B;
+    B = &builder;
+    // Initialize the builder object.
+    flatcc_builder_init(B);
+~~~
+</div>
+<div class="language-dart">
+~~~{.dart}
+  // Create the fb.Builder object that will be used by our generated builders
+  // Note that if you are only planning to immediately get the byte array this builder would create,
+  // you can use the convenience method `toBytes()` on the generated builders.
+  // For example, you could do something like `new myGame.MonsterBuilder(...).toBytes()`
+  var builder = new fb.Builder(initialSize: 1024);
+~~~
+</div>
+<div class="language-lua">
+~~~{.lua}
+  -- get access to the builder, providing an array of size 1024
+  local builder = flatbuffers.Builder(1024)
+~~~
+</div>
+<div class="language-lobster">
+~~~{.lobster}
+  // get access to the builder
+  let builder = flatbuffers_builder {}
+~~~
+</div>
+<div class="language-rust">
+~~~{.rs}
+  // Build up a serialized buffer algorithmically.
+  // Initialize it with a capacity of 1024 bytes.
+  let mut builder = flatbuffers::FlatBufferBuilder::new_with_capacity(1024);
+~~~
+</div>
+
+After creating the `builder`, we can start serializing our data. Before we make
+our `orc` Monster, lets create some `Weapon`s: a `Sword` and an `Axe`.
+
+<div class="language-cpp">
+~~~{.cpp}
+  auto weapon_one_name = builder.CreateString("Sword");
+  short weapon_one_damage = 3;
+
+  auto weapon_two_name = builder.CreateString("Axe");
+  short weapon_two_damage = 5;
+
+  // Use the `CreateWeapon` shortcut to create Weapons with all the fields set.
+  auto sword = CreateWeapon(builder, weapon_one_name, weapon_one_damage);
+  auto axe = CreateWeapon(builder, weapon_two_name, weapon_two_damage);
+~~~
+</div>
+<div class="language-java">
+~~~{.java}
+  int weaponOneName = builder.createString("Sword")
+  short weaponOneDamage = 3;
+
+  int weaponTwoName = builder.createString("Axe");
+  short weaponTwoDamage = 5;
+
+  // Use the `createWeapon()` helper function to create the weapons, since we set every field.
+  int sword = Weapon.createWeapon(builder, weaponOneName, weaponOneDamage);
+  int axe = Weapon.createWeapon(builder, weaponTwoName, weaponTwoDamage);
+~~~
+</div>
+<div class="language-kotlin">
+~~~{.kt}
+  val weaponOneName = builder.createString("Sword")
+  val weaponOneDamage: Short = 3;
+
+  val weaponTwoName = builder.createString("Axe")
+  val weaponTwoDamage: Short = 5;
+
+  // Use the `createWeapon()` helper function to create the weapons, since we set every field.
+  val sword = Weapon.createWeapon(builder, weaponOneName, weaponOneDamage)
+  val axe = Weapon.createWeapon(builder, weaponTwoName, weaponTwoDamage)
+~~~
+</div>
+<div class="language-csharp">
+~~~{.cs}
+  var weaponOneName = builder.CreateString("Sword");
+  var weaponOneDamage = 3;
+
+  var weaponTwoName = builder.CreateString("Axe");
+  var weaponTwoDamage = 5;
+
+  // Use the `CreateWeapon()` helper function to create the weapons, since we set every field.
+  var sword = Weapon.CreateWeapon(builder, weaponOneName, (short)weaponOneDamage);
+  var axe = Weapon.CreateWeapon(builder, weaponTwoName, (short)weaponTwoDamage);
+~~~
+</div>
+<div class="language-go">
+~~~{.go}
+  weaponOne := builder.CreateString("Sword")
+  weaponTwo := builder.CreateString("Axe")
+
+  // Create the first `Weapon` ("Sword").
+  sample.WeaponStart(builder)
+  sample.WeaponAddName(builder, weaponOne)
+  sample.WeaponAddDamage(builder, 3)
+  sword := sample.WeaponEnd(builder)
+
+  // Create the second `Weapon` ("Axe").
+  sample.WeaponStart(builder)
+  sample.WeaponAddName(builder, weaponTwo)
+  sample.WeaponAddDamage(builder, 5)
+  axe := sample.WeaponEnd(builder)
+~~~
+</div>
+<div class="language-python">
+~~~{.py}
+  weapon_one = builder.CreateString('Sword')
+  weapon_two = builder.CreateString('Axe')
+
+  # Create the first `Weapon` ('Sword').
+  MyGame.Sample.Weapon.WeaponStart(builder)
+  MyGame.Sample.Weapon.WeaponAddName(builder, weapon_one)
+  MyGame.Sample.Weapon.WeaponAddDamage(builder, 3)
+  sword = MyGame.Sample.Weapon.WeaponEnd(builder)
+
+  # Create the second `Weapon` ('Axe').
+  MyGame.Sample.Weapon.WeaponStart(builder)
+  MyGame.Sample.Weapon.WeaponAddName(builder, weapon_two)
+  MyGame.Sample.Weapon.WeaponAddDamage(builder, 5)
+  axe = MyGame.Sample.Weapon.WeaponEnd(builder)
+~~~
+</div>
+<div class="language-javascript">
+~~~{.js}
+  var weaponOne = builder.createString('Sword');
+  var weaponTwo = builder.createString('Axe');
+
+  // Create the first `Weapon` ('Sword').
+  MyGame.Sample.Weapon.startWeapon(builder);
+  MyGame.Sample.Weapon.addName(builder, weaponOne);
+  MyGame.Sample.Weapon.addDamage(builder, 3);
+  var sword = MyGame.Sample.Weapon.endWeapon(builder);
+
+  // Create the second `Weapon` ('Axe').
+  MyGame.Sample.Weapon.startWeapon(builder);
+  MyGame.Sample.Weapon.addName(builder, weaponTwo);
+  MyGame.Sample.Weapon.addDamage(builder, 5);
+  var axe = MyGame.Sample.Weapon.endWeapon(builder);
+~~~
+</div>
+<div class="language-typescript">
+~~~{.js}
+  let weaponOne = builder.createString('Sword');
+  let weaponTwo = builder.createString('Axe');
+
+  // Create the first `Weapon` ('Sword').
+  MyGame.Sample.Weapon.startWeapon(builder);
+  MyGame.Sample.Weapon.addName(builder, weaponOne);
+  MyGame.Sample.Weapon.addDamage(builder, 3);
+  let sword = MyGame.Sample.Weapon.endWeapon(builder);
+
+  // Create the second `Weapon` ('Axe').
+  MyGame.Sample.Weapon.startWeapon(builder);
+  MyGame.Sample.Weapon.addName(builder, weaponTwo);
+  MyGame.Sample.Weapon.addDamage(builder, 5);
+  let axe = MyGame.Sample.Weapon.endWeapon(builder);
+~~~
+</div>
+<div class="language-php">
+~~~{.php}
+  // Create the `Weapon`s using the `createWeapon()` helper function.
+  $weapon_one_name = $builder->createString("Sword");
+  $sword = \MyGame\Sample\Weapon::CreateWeapon($builder, $weapon_one_name, 3);
+
+  $weapon_two_name = $builder->createString("Axe");
+  $axe = \MyGame\Sample\Weapon::CreateWeapon($builder, $weapon_two_name, 5);
+
+  // Create an array from the two `Weapon`s and pass it to the
+  // `CreateWeaponsVector()` method to create a FlatBuffer vector.
+  $weaps = array($sword, $axe);
+  $weapons = \MyGame\Sample\Monster::CreateWeaponsVector($builder, $weaps);
+~~~
+</div>
+<div class="language-c">
+~~~{.c}
+  flatbuffers_string_ref_t weapon_one_name = flatbuffers_string_create_str(B, "Sword");
+  uint16_t weapon_one_damage = 3;
+
+  flatbuffers_string_ref_t weapon_two_name = flatbuffers_string_create_str(B, "Axe");
+  uint16_t weapon_two_damage = 5;
+
+  ns(Weapon_ref_t) sword = ns(Weapon_create(B, weapon_one_name, weapon_one_damage));
+  ns(Weapon_ref_t) axe = ns(Weapon_create(B, weapon_two_name, weapon_two_damage));
+~~~
+</div>
+<div class="language-dart">
+~~~{.dart}
+  // The generated Builder classes work much like in other languages,
+  final int weaponOneName = builder.writeString("Sword");
+  final int weaponOneDamage = 3;
+
+  final int weaponTwoName = builder.writeString("Axe");
+  final int weaponTwoDamage = 5;
+
+  final swordBuilder = new myGame.WeaponBuilder(builder)
+    ..begin()
+    ..addNameOffset(weaponOneName)
+    ..addDamage(weaponOneDamage);
+  final int sword = swordBuilder.finish();
+
+  final axeBuilder = new myGame.WeaponBuilder(builder)
+    ..begin()
+    ..addNameOffset(weaponTwoName)
+    ..addDamage(weaponTwoDamage);
+  final int axe = axeBuilder.finish();
+
+
+
+  // The generated ObjectBuilder classes offer an easier to use alternative
+  // at the cost of requiring some additional reference allocations. If memory
+  // usage is critical, or if you'll be working with especially large messages
+  // or tables, you should prefer using the generated Builder classes.
+  // The following code would produce an identical buffer as above.
+  final String weaponOneName = "Sword";
+  final int weaponOneDamage = 3;
+
+  final String weaponTwoName = "Axe";
+  final int weaponTwoDamage = 5;
+
+  final myGame.WeaponBuilder sword = new myGame.WeaponObjectBuilder(
+    name: weaponOneName,
+    damage: weaponOneDamage,
+  );
+
+  final myGame.WeaponBuilder axe = new myGame.WeaponObjectBuilder(
+    name: weaponTwoName,
+    damage: weaponTwoDamage,
+  );
+~~~
+</div>
+<div class="language-lua">
+~~~{.lua}
+    local weaponOne = builder:CreateString("Sword")
+    local weaponTwo = builder:CreateString("Axe")
+
+    -- Create the first 'Weapon'
+    weapon.Start(builder)
+    weapon.AddName(builder, weaponOne)
+    weapon.AddDamage(builder, 3)
+    local sword = weapon.End(builder)
+
+    -- Create the second 'Weapon'
+    weapon.Start(builder)
+    weapon.AddName(builder, weaponTwo)
+    weapon.AddDamage(builder, 5)
+    local axe = weapon.End(builder)
+~~~
+</div>
+<div class="language-lobster">
+~~~{.lobster}
+  let weapon_names = [ "Sword", "Axe" ]
+  let weapon_damages = [ 3, 5 ]
+
+  let weapon_offsets = map(weapon_names) name, i:
+      let ns = builder.CreateString(name)
+      MyGame_Sample_WeaponBuilder { b }
+          .start()
+          .add_name(ns)
+          .add_damage(weapon_damages[i])
+          .end()
+~~~
+</div>
+<div class="language-rust">
+~~~{.rs}
+  // Serialize some weapons for the Monster: A 'sword' and an 'axe'.
+  let weapon_one_name = builder.create_string("Sword");
+  let weapon_two_name = builder.create_string("Axe");
+
+  // Use the `Weapon::create` shortcut to create Weapons with named field
+  // arguments.
+  let sword = Weapon::create(&mut builder, &WeaponArgs{
+      name: Some(weapon_one_name),
+      damage: 3,
+  });
+  let axe = Weapon::create(&mut builder, &WeaponArgs{
+      name: Some(weapon_two_name),
+      damage: 5,
+  });
+~~~
+</div>
+
+Now let's create our monster, the `orc`. For this `orc`, lets make him
+`red` with rage, positioned at `(1.0, 2.0, 3.0)`, and give him
+a large pool of hit points with `300`. We can give him a vector of weapons
+to choose from (our `Sword` and `Axe` from earlier). In this case, we will
+equip him with the `Axe`, since it is the most powerful of the two. Lastly,
+let's fill his inventory with some potential treasures that can be taken once he
+is defeated.
+
+Before we serialize a monster, we need to first serialize any objects that are
+contained there-in, i.e. we serialize the data tree using depth-first, pre-order
+traversal. This is generally easy to do on any tree structures.
+
+<div class="language-cpp">
+~~~{.cpp}
+  // Serialize a name for our monster, called "Orc".
+  auto name = builder.CreateString("Orc");
+
+  // Create a `vector` representing the inventory of the Orc. Each number
+  // could correspond to an item that can be claimed after he is slain.
+  unsigned char treasure[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+  auto inventory = builder.CreateVector(treasure, 10);
+~~~
+</div>
+<div class="language-java">
+~~~{.java}
+  // Serialize a name for our monster, called "Orc".
+  int name = builder.createString("Orc");
+
+  // Create a `vector` representing the inventory of the Orc. Each number
+  // could correspond to an item that can be claimed after he is slain.
+  byte[] treasure = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+  int inv = Monster.createInventoryVector(builder, treasure);
+~~~
+</div>
+<div class="language-kotlin">
+~~~{.kt}
+  // Serialize a name for our monster, called "Orc".
+  val name = builder.createString("Orc")
+
+  // Create a `vector` representing the inventory of the Orc. Each number
+  // could correspond to an item that can be claimed after he is slain.
+  val treasure = byteArrayOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
+  val inv = Monster.createInventoryVector(builder, treasure)
+~~~
+</div>
+<div class="language-csharp">
+~~~{.cs}
+  // Serialize a name for our monster, called "Orc".
+  var name = builder.CreateString("Orc");
+
+  // Create a `vector` representing the inventory of the Orc. Each number
+  // could correspond to an item that can be claimed after he is slain.
+  // Note: Since we prepend the bytes, this loop iterates in reverse order.
+  Monster.StartInventoryVector(builder, 10);
+  for (int i = 9; i >= 0; i--)
+  {
+    builder.AddByte((byte)i);
+  }
+  var inv = builder.EndVector();
+~~~
+</div>
+<div class="language-go">
+~~~{.go}
+  // Serialize a name for our monster, called "Orc".
+  name := builder.CreateString("Orc")
+
+  // Create a `vector` representing the inventory of the Orc. Each number
+  // could correspond to an item that can be claimed after he is slain.
+  // Note: Since we prepend the bytes, this loop iterates in reverse.
+  sample.MonsterStartInventoryVector(builder, 10)
+  for i := 9; i >= 0; i-- {
+          builder.PrependByte(byte(i))
+  }
+  inv := builder.EndVector(10)
+~~~
+</div>
+<div class="language-python">
+~~~{.py}
+  # Serialize a name for our monster, called "Orc".
+  name = builder.CreateString("Orc")
+
+  # Create a `vector` representing the inventory of the Orc. Each number
+  # could correspond to an item that can be claimed after he is slain.
+  # Note: Since we prepend the bytes, this loop iterates in reverse.
+  MyGame.Sample.Monster.MonsterStartInventoryVector(builder, 10)
+  for i in reversed(range(0, 10)):
+    builder.PrependByte(i)
+  inv = builder.EndVector(10)
+~~~
+</div>
+<div class="language-javascript">
+~~~{.js}
+  // Serialize a name for our monster, called 'Orc'.
+  var name = builder.createString('Orc');
+
+  // Create a `vector` representing the inventory of the Orc. Each number
+  // could correspond to an item that can be claimed after he is slain.
+  var treasure = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+  var inv = MyGame.Sample.Monster.createInventoryVector(builder, treasure);
+~~~
+</div>
+<div class="language-typescript">
+~~~{.js}
+  // Serialize a name for our monster, called 'Orc'.
+  let name = builder.createString('Orc');
+
+  // Create a `vector` representing the inventory of the Orc. Each number
+  // could correspond to an item that can be claimed after he is slain.
+  let treasure = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+  let inv = MyGame.Sample.Monster.createInventoryVector(builder, treasure);
+~~~
+</div>
+<div class="language-php">
+~~~{.php}
+  // Serialize a name for our monster, called "Orc".
+  $name = $builder->createString("Orc");
+
+  // Create a `vector` representing the inventory of the Orc. Each number
+  // could correspond to an item that can be claimed after he is slain.
+  $treasure = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+  $inv = \MyGame\Sample\Monster::CreateInventoryVector($builder, $treasure);
+~~~
+</div>
+<div class="language-c">
+~~~{.c}
+  // Serialize a name for our monster, called "Orc".
+  // The _str suffix indicates the source is an ascii-z string.
+  flatbuffers_string_ref_t name = flatbuffers_string_create_str(B, "Orc");
+
+  // Create a `vector` representing the inventory of the Orc. Each number
+  // could correspond to an item that can be claimed after he is slain.
+  uint8_t treasure[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+  flatbuffers_uint8_vec_ref_t inventory;
+  // `c_vec_len` is the convenience macro we defined earlier.
+  inventory = flatbuffers_uint8_vec_create(B, treasure, c_vec_len(treasure));
+~~~
+</div>
+<div class="language-dart">
+~~~{.dart}
+  // Serialize a name for our monster, called "Orc".
+  final int name = builder.writeString('Orc');
+
+  // Create a list representing the inventory of the Orc. Each number
+  // could correspond to an item that can be claimed after he is slain.
+  final List<int> treasure = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+  final inventory = builder.writeListUint8(treasure);
+
+  // The following code should be used instead if you intend to use the
+  // ObjectBuilder classes:
+  // Serialize a name for our monster, called "Orc".
+  final String name = 'Orc';
+
+  // Create a list representing the inventory of the Orc. Each number
+  // could correspond to an item that can be claimed after he is slain.
+  final List<int> treasure = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+~~~
+</div>
+<div class="language-lua">
+~~~{.py}
+    -- Serialize a name for our mosnter, called 'orc'
+    local name = builder:CreateString("Orc")
+
+    -- Create a `vector` representing the inventory of the Orc. Each number
+    -- could correspond to an item that can be claimed after he is slain.
+    -- Note: Since we prepend the bytes, this loop iterates in reverse.
+    monster.StartInventoryVector(builder, 10)
+    for i=10,1,-1 do
+        builder:PrependByte(i)
+    end
+    local inv = builder:EndVector(10)
+~~~
+</div>
+<div class="language-lobster">
+~~~{.lobster}
+  // Name of the monster.
+  let name = builder.CreateString("Orc")
+
+  // Inventory.
+  let inv = builder.MyGame_Sample_MonsterCreateInventoryVector(map(10): _)
+~~~
+</div>
+<div class="language-rust">
+~~~{.rs}
+  // Name of the Monster.
+  let name = builder.create_string("Orc");
+
+  // Inventory.
+  let inventory = builder.create_vector(&[0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
+~~~
+</div>
+
+We serialized two built-in data types (`string` and `vector`) and captured
+their return values. These values are offsets into the serialized data,
+indicating where they are stored, such that we can refer to them below when
+adding fields to our monster.
+
+*Note: To create a `vector` of nested objects (e.g. `table`s, `string`s, or
+other `vector`s), collect their offsets into a temporary data structure, and
+then create an additional `vector` containing their offsets.*
+
+If instead of creating a vector from an existing array you serialize elements
+individually one by one, take care to note that this happens in reverse order,
+as buffers are built back to front.
+
+For example, take a look at the two `Weapon`s that we created earlier (`Sword`
+and `Axe`). These are both FlatBuffer `table`s, whose offsets we now store in
+memory. Therefore we can create a FlatBuffer `vector` to contain these
+offsets.
+
+<div class="language-cpp">
+~~~{.cpp}
+  // Place the weapons into a `std::vector`, then convert that into a FlatBuffer `vector`.
+  std::vector<flatbuffers::Offset<Weapon>> weapons_vector;
+  weapons_vector.push_back(sword);
+  weapons_vector.push_back(axe);
+  auto weapons = builder.CreateVector(weapons_vector);
+~~~
+</div>
+<div class="language-java">
+~~~{.java}
+  // Place the two weapons into an array, and pass it to the `createWeaponsVector()` method to
+  // create a FlatBuffer vector.
+  int[] weaps = new int[2];
+  weaps[0] = sword;
+  weaps[1] = axe;
+
+  // Pass the `weaps` array into the `createWeaponsVector()` method to create a FlatBuffer vector.
+  int weapons = Monster.createWeaponsVector(builder, weaps);
+~~~
+</div>
+<div class="language-kotlin">
+~~~{.kt}
+  // Place the two weapons into an array, and pass it to the `createWeaponsVector()` method to
+  // create a FlatBuffer vector.
+  val weaps = intArrayOf(sword, axe)
+
+  // Pass the `weaps` array into the `createWeaponsVector()` method to create a FlatBuffer vector.
+  val weapons = Monster.createWeaponsVector(builder, weaps)
+~~~
+</div>
+<div class="language-csharp">
+~~~{.cs}
+  var weaps = new Offset<Weapon>[2];
+  weaps[0] = sword;
+  weaps[1] = axe;
+
+  // Pass the `weaps` array into the `CreateWeaponsVector()` method to create a FlatBuffer vector.
+  var weapons = Monster.CreateWeaponsVector(builder, weaps);
+~~~
+</div>
+<div class="language-go">
+~~~{.go}
+  // Create a FlatBuffer vector and prepend the weapons.
+  // Note: Since we prepend the data, prepend them in reverse order.
+  sample.MonsterStartWeaponsVector(builder, 2)
+  builder.PrependUOffsetT(axe)
+  builder.PrependUOffsetT(sword)
+  weapons := builder.EndVector(2)
+~~~
+</div>
+<div class="language-python">
+~~~{.py}
+  # Create a FlatBuffer vector and prepend the weapons.
+  # Note: Since we prepend the data, prepend them in reverse order.
+  MyGame.Sample.Monster.MonsterStartWeaponsVector(builder, 2)
+  builder.PrependUOffsetTRelative(axe)
+  builder.PrependUOffsetTRelative(sword)
+  weapons = builder.EndVector(2)
+~~~
+</div>
+<div class="language-javascript">
+~~~{.js}
+  // Create an array from the two `Weapon`s and pass it to the
+  // `createWeaponsVector()` method to create a FlatBuffer vector.
+  var weaps = [sword, axe];
+  var weapons = MyGame.Sample.Monster.createWeaponsVector(builder, weaps);
+~~~
+</div>
+<div class="language-typescript">
+~~~{.ts}
+  // Create an array from the two `Weapon`s and pass it to the
+  // `createWeaponsVector()` method to create a FlatBuffer vector.
+  let weaps = [sword, axe];
+  let weapons = MyGame.Sample.Monster.createWeaponsVector(builder, weaps);
+~~~
+</div>
+<div class="language-php">
+~~~{.php}
+  // Create an array from the two `Weapon`s and pass it to the
+  // `CreateWeaponsVector()` method to create a FlatBuffer vector.
+  $weaps = array($sword, $axe);
+  $weapons = \MyGame\Sample\Monster::CreateWeaponsVector($builder, $weaps);
+~~~
+</div>
+<div class="language-c">
+~~~{.c}
+  // We use the internal builder stack to implement a dynamic vector.
+  ns(Weapon_vec_start(B));
+  ns(Weapon_vec_push(B, sword));
+  ns(Weapon_vec_push(B, axe));
+  ns(Weapon_vec_ref_t) weapons = ns(Weapon_vec_end(B));
+~~~
+</div>
+<div class="language-dart">
+~~~{.dart}
+  // If using the Builder classes, serialize the `[sword,axe]`
+  final weapons = builder.writeList([sword, axe]);
+
+  // If using the ObjectBuilders, just create an array from the two `Weapon`s
+  final List<myGame.WeaponBuilder> weaps = [sword, axe];
+~~~
+</div>
+<div class="language-lua">
+~~~{.lua}
+    -- Create a FlatBuffer vector and prepend the weapons.
+    -- Note: Since we prepend the data, prepend them in reverse order.
+    monster.StartWeaponsVector(builder, 2)
+    builder:PrependUOffsetTRelative(axe)
+    builder:PrependUOffsetTRelative(sword)
+    local weapons = builder:EndVector(2)
+~~~
+</div>
+<div class="language-lobster">
+~~~{.lobster}
+  let weapons = builder.MyGame_Sample_MonsterCreateWeaponsVector(weapon_offsets)
+~~~
+</div>
+<div class="language-rust">
+~~~{.rs}
+  // Create a FlatBuffer `vector` that contains offsets to the sword and axe
+  // we created above.
+  let weapons = builder.create_vector(&[sword, axe]);
+~~~
+</div>
+
+<br>
+Note there's additional convenience overloads of `CreateVector`, allowing you
+to work with data that's not in a `std::vector`, or allowing you to generate
+elements by calling a lambda. For the common case of `std::vector<std::string>`
+there's also `CreateVectorOfStrings`.
+</div>
+
+Note that vectors of structs are serialized differently from tables, since
+structs are stored in-line in the vector. For example, to create a vector
+for the `path` field above:
+
+<div class="language-cpp">
+~~~{.cpp}
+  Vec3 points[] = { Vec3(1.0f, 2.0f, 3.0f), Vec3(4.0f, 5.0f, 6.0f) };
+  auto path = builder.CreateVectorOfStructs(points, 2);
+~~~
+</div>
+<div class="language-java">
+~~~{.java}
+  Monster.startPathVector(fbb, 2);
+  Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f);
+  Vec3.createVec3(builder, 4.0f, 5.0f, 6.0f);
+  int path = fbb.endVector();
+~~~
+</div>
+<div class="language-kotlin">
+~~~{.kt}
+  Monster.startPathVector(fbb, 2)
+  Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f)
+  Vec3.createVec3(builder, 4.0f, 5.0f, 6.0f)
+  val path = fbb.endVector()
+~~~
+</div>
+<div class="language-csharp">
+~~~{.cs}
+  Monster.StartPathVector(fbb, 2);
+  Vec3.CreateVec3(builder, 1.0f, 2.0f, 3.0f);
+  Vec3.CreateVec3(builder, 4.0f, 5.0f, 6.0f);
+  var path = fbb.EndVector();
+~~~
+</div>
+<div class="language-go">
+~~~{.go}
+  sample.MonsterStartPathVector(builder, 2)
+  sample.CreateVec3(builder, 1.0, 2.0, 3.0)
+  sample.CreateVec3(builder, 4.0, 5.0, 6.0)
+  path := builder.EndVector(2)
+~~~
+</div>
+<div class="language-python">
+~~~{.py}
+  MyGame.Sample.Monster.MonsterStartPathVector(builder, 2)
+  MyGame.Sample.Vec3.CreateVec3(builder, 1.0, 2.0, 3.0)
+  MyGame.Sample.Vec3.CreateVec3(builder, 4.0, 5.0, 6.0)
+  path = builder.EndVector(2)
+~~~
+</div>
+<div class="language-javascript">
+~~~{.js}
+  MyGame.Sample.Monster.startPathVector(builder, 2);
+  MyGame.Sample.Vec3.createVec3(builder, 1.0, 2.0, 3.0);
+  MyGame.Sample.Vec3.createVec3(builder, 4.0, 5.0, 6.0);
+  var path = builder.endVector();
+~~~
+</div>
+<div class="language-typescript">
+~~~{.ts}
+  MyGame.Sample.Monster.startPathVector(builder, 2);
+  MyGame.Sample.Vec3.createVec3(builder, 1.0, 2.0, 3.0);
+  MyGame.Sample.Vec3.createVec3(builder, 4.0, 5.0, 6.0);
+  let path = builder.endVector();
+~~~
+</div>
+<div class="language-php">
+~~~{.php}
+  \MyGame\Example\Monster::StartPathVector($builder, 2);
+  \MyGame\Sample\Vec3::CreateVec3($builder, 1.0, 2.0, 3.0);
+  \MyGame\Sample\Vec3::CreateVec3($builder, 1.0, 2.0, 3.0);
+  $path = $builder->endVector();
+~~~
+</div>
+<div class="language-c">
+~~~{.c}
+  // TBD
+~~~
+</div>
+<div class="language-dart">
+~~~{.dart}
+  // Using the Builder classes, you can write a list of structs like so:
+  // Note that the intended order should be reversed if order is important.
+  final vec3Builder = new myGame.Vec3Builder(builder);
+  vec3Builder.finish(4.0, 5.0, 6.0);
+  vec3Builder.finish(1.0, 2.0, 3.0);
+  final int path = builder.endStructVector(2); // the length of the vector
+
+  // Otherwise, using the ObjectBuilder classes:
+  // The dart implementation provides a simple interface for writing vectors
+  // of structs, in `writeListOfStructs`. This method takes
+  // `List<ObjectBuilder>` and is used by the generated builder classes.
+  final List<myGame.Vec3ObjectBuilder> path = [
+    new myGame.Vec3ObjectBuilder(x: 1.0, y: 2.0, z: 3.0),
+    new myGame.Vec3ObjectBuilder(x: 4.0, y: 5.0, z: 6.0)
+  ];
+~~~
+</div>
+<div class="language-lua">
+~~~{.lua}
+    -- Create a FlatBuffer vector and prepend the path locations.
+    -- Note: Since we prepend the data, prepend them in reverse order.
+    monster.StartPathVector(builder, 2)
+    vec3.CreateVec3(builder, 1.0, 2.0, 3.0)
+    vec3.CreateVec3(builder, 4.0, 5.0, 6.0)
+    local path = builder:EndVector(2)
+~~~
+</div>
+<div class="language-lobster">
+~~~{.lobster}
+  builder.MyGame_Sample_MonsterStartPathVector(2)
+  builder.MyGame_Sample_CreateVec3(1.0, 2.0, 3.0)
+  builder.MyGame_Sample_CreateVec3(4.0, 5.0, 6.0)
+  let path = builder.EndVector(2)
+~~~
+</div>
+<div class="language-rust">
+~~~{.rs}
+  // Create the path vector of Vec3 objects.
+  let x = Vec3::new(1.0, 2.0, 3.0);
+  let y = Vec3::new(4.0, 5.0, 6.0);
+  let path = builder.create_vector(&[x, y]);
+
+  // Note that, for convenience, it is also valid to create a vector of
+  // references to structs, like this:
+  // let path = builder.create_vector(&[&x, &y]);
+~~~
+</div>
+
+We have now serialized the non-scalar components of the orc, so we
+can serialize the monster itself:
+
+<div class="language-cpp">
+~~~{.cpp}
+  // Create the position struct
+  auto position = Vec3(1.0f, 2.0f, 3.0f);
+
+  // Set his hit points to 300 and his mana to 150.
+  int hp = 300;
+  int mana = 150;
+
+  // Finally, create the monster using the `CreateMonster` helper function
+  // to set all fields.
+  auto orc = CreateMonster(builder, &position, mana, hp, name, inventory,
+                          Color_Red, weapons, Equipment_Weapon, axe.Union(),
+                          path);
+~~~
+</div>
+<div class="language-java">
+~~~{.java}
+  // Create our monster using `startMonster()` and `endMonster()`.
+  Monster.startMonster(builder);
+  Monster.addPos(builder, Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f));
+  Monster.addName(builder, name);
+  Monster.addColor(builder, Color.Red);
+  Monster.addHp(builder, (short)300);
+  Monster.addInventory(builder, inv);
+  Monster.addWeapons(builder, weapons);
+  Monster.addEquippedType(builder, Equipment.Weapon);
+  Monster.addEquipped(builder, axe);
+  Monster.addPath(builder, path);
+  int orc = Monster.endMonster(builder);
+~~~
+</div>
+<div class="language-kotlin">
+~~~{.kt}
+  // Create our monster using `startMonster()` and `endMonster()`.
+  Monster.startMonster(builder)
+  Monster.addPos(builder, Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f))
+  Monster.addName(builder, name)
+  Monster.addColor(builder, Color.Red)
+  Monster.addHp(builder, 300.toShort())
+  Monster.addInventory(builder, inv)
+  Monster.addWeapons(builder, weapons)
+  Monster.addEquippedType(builder, Equipment.Weapon)
+  Monster.addEquipped(builder, axe)
+  Monster.addPath(builder, path)
+  val orc = Monster.endMonster(builder)
+~~~
+</div>
+<div class="language-csharp">
+~~~{.cs}
+  // Create our monster using `StartMonster()` and `EndMonster()`.
+  Monster.StartMonster(builder);
+  Monster.AddPos(builder, Vec3.CreateVec3(builder, 1.0f, 2.0f, 3.0f));
+  Monster.AddHp(builder, (short)300);
+  Monster.AddName(builder, name);
+  Monster.AddInventory(builder, inv);
+  Monster.AddColor(builder, Color.Red);
+  Monster.AddWeapons(builder, weapons);
+  Monster.AddEquippedType(builder, Equipment.Weapon);
+  Monster.AddEquipped(builder, axe.Value); // Axe
+  Monster.AddPath(builder, path);
+  var orc = Monster.EndMonster(builder);
+~~~
+</div>
+<div class="language-go">
+~~~{.go}
+  // Create our monster using `MonsterStart()` and `MonsterEnd()`.
+  sample.MonsterStart(builder)
+  sample.MonsterAddPos(builder, sample.CreateVec3(builder, 1.0, 2.0, 3.0))
+  sample.MonsterAddHp(builder, 300)
+  sample.MonsterAddName(builder, name)
+  sample.MonsterAddInventory(builder, inv)
+  sample.MonsterAddColor(builder, sample.ColorRed)
+  sample.MonsterAddWeapons(builder, weapons)
+  sample.MonsterAddEquippedType(builder, sample.EquipmentWeapon)
+  sample.MonsterAddEquipped(builder, axe)
+  sample.MonsterAddPath(builder, path)
+  orc := sample.MonsterEnd(builder)
+~~~
+</div>
+<div class="language-python">
+~~~{.py}
+  # Create our monster by using `MonsterStart()` and `MonsterEnd()`.
+  MyGame.Sample.Monster.MonsterStart(builder)
+  MyGame.Sample.Monster.MonsterAddPos(builder,
+                          MyGame.Sample.Vec3.CreateVec3(builder, 1.0, 2.0, 3.0))
+  MyGame.Sample.Monster.MonsterAddHp(builder, 300)
+  MyGame.Sample.Monster.MonsterAddName(builder, name)
+  MyGame.Sample.Monster.MonsterAddInventory(builder, inv)
+  MyGame.Sample.Monster.MonsterAddColor(builder,
+                                        MyGame.Sample.Color.Color().Red)
+  MyGame.Sample.Monster.MonsterAddWeapons(builder, weapons)
+  MyGame.Sample.Monster.MonsterAddEquippedType(
+      builder, MyGame.Sample.Equipment.Equipment().Weapon)
+  MyGame.Sample.Monster.MonsterAddEquipped(builder, axe)
+  MyGame.Sample.Monster.MonsterAddPath(builder, path)
+  orc = MyGame.Sample.Monster.MonsterEnd(builder)
+~~~
+</div>
+<div class="language-javascript">
+~~~{.js}
+  // Create our monster by using `startMonster()` and `endMonster()`.
+  MyGame.Sample.Monster.startMonster(builder);
+  MyGame.Sample.Monster.addPos(builder,
+                         MyGame.Sample.Vec3.createVec3(builder, 1.0, 2.0, 3.0));
+  MyGame.Sample.Monster.addHp(builder, 300);
+  MyGame.Sample.Monster.addColor(builder, MyGame.Sample.Color.Red)
+  MyGame.Sample.Monster.addName(builder, name);
+  MyGame.Sample.Monster.addInventory(builder, inv);
+  MyGame.Sample.Monster.addWeapons(builder, weapons);
+  MyGame.Sample.Monster.addEquippedType(builder, MyGame.Sample.Equipment.Weapon);
+  MyGame.Sample.Monster.addEquipped(builder, axe);
+  MyGame.Sample.Monster.addPath(builder, path);
+  var orc = MyGame.Sample.Monster.endMonster(builder);
+~~~
+</div>
+<div class="language-typescript">
+~~~{.ts}
+  // Create our monster by using `startMonster()` and `endMonster()`.
+  MyGame.Sample.Monster.startMonster(builder);
+  MyGame.Sample.Monster.addPos(builder,
+                         MyGame.Sample.Vec3.createVec3(builder, 1.0, 2.0, 3.0));
+  MyGame.Sample.Monster.addHp(builder, 300);
+  MyGame.Sample.Monster.addColor(builder, MyGame.Sample.Color.Red)
+  MyGame.Sample.Monster.addName(builder, name);
+  MyGame.Sample.Monster.addInventory(builder, inv);
+  MyGame.Sample.Monster.addWeapons(builder, weapons);
+  MyGame.Sample.Monster.addEquippedType(builder, MyGame.Sample.Equipment.Weapon);
+  MyGame.Sample.Monster.addEquipped(builder, axe);
+  MyGame.Sample.Monster.addPath(builder, path);
+  let orc = MyGame.Sample.Monster.endMonster(builder);
+~~~
+</div>
+<div class="language-php">
+~~~{.php}
+  // Create our monster by using `StartMonster()` and `EndMonster()`.
+  \MyGame\Sample\Monster::StartMonster($builder);
+  \MyGame\Sample\Monster::AddPos($builder,
+                      \MyGame\Sample\Vec3::CreateVec3($builder, 1.0, 2.0, 3.0));
+  \MyGame\Sample\Monster::AddHp($builder, 300);
+  \MyGame\Sample\Monster::AddName($builder, $name);
+  \MyGame\Sample\Monster::AddInventory($builder, $inv);
+  \MyGame\Sample\Monster::AddColor($builder, \MyGame\Sample\Color::Red);
+  \MyGame\Sample\Monster::AddWeapons($builder, $weapons);
+  \MyGame\Sample\Monster::AddEquippedType($builder, \MyGame\Sample\Equipment::Weapon);
+  \MyGame\Sample\Monster::AddEquipped($builder, $axe);
+  \MyGame\Sample\Monster::AddPath($builder, $path);
+  $orc = \MyGame\Sample\Monster::EndMonster($builder);
+~~~
+</div>
+<div class="language-c">
+~~~{.c}
+  // Set his hit points to 300 and his mana to 150.
+  uint16_t hp = 300;
+  uint16_t mana = 150;
+
+  // Define an equipment union. `create` calls in C has a single
+  // argument for unions where C++ has both a type and a data argument.
+  ns(Equipment_union_ref_t) equipped = ns(Equipment_as_Weapon(axe));
+  ns(Vec3_t) pos = { 1.0f, 2.0f, 3.0f };
+  ns(Monster_create_as_root(B, &pos, mana, hp, name, inventory, ns(Color_Red),
+          weapons, equipped, path));
+~~~
+</div>
+<div class="language-dart">
+~~~{.dart}
+  // Using the Builder API:
+  // Set his hit points to 300 and his mana to 150.
+  final int hp = 300;
+  final int mana = 150;
+
+  final monster = new myGame.MonsterBuilder(builder)
+    ..begin()
+    ..addNameOffset(name)
+    ..addInventoryOffset(inventory)
+    ..addWeaponsOffset(weapons)
+    ..addEquippedType(myGame.EquipmentTypeId.Weapon)
+    ..addEquippedOffset(axe)
+    ..addHp(hp)
+    ..addMana(mana)
+    ..addPos(vec3Builder.finish(1.0, 2.0, 3.0))
+    ..addPathOffset(path)
+    ..addColor(myGame.Color.Red);
+
+  final int orc = monster.finish();
+
+  // -Or- using the ObjectBuilder API:
+  // Set his hit points to 300 and his mana to 150.
+  final int hp = 300;
+  final int mana = 150;
+
+  // Note that these parameters are optional - it is not necessary to set
+  // all of them.
+  // Also note that it is not necessary to `finish` the builder helpers above
+  // - the generated code will automatically reuse offsets if the same object
+  // is used in more than one place (e.g. the axe appearing in `weapons` and
+  // `equipped`).
+  final myGame.MonsterBuilder orcBuilder = new myGame.MonsterBuilder(
+    name: name,
+    inventory: treasure,
+    weapons: weaps,
+    equippedType: myGame.EquipmentTypeId.Weapon,
+    equipped: axe,
+    path: path,
+    hp: hp,
+    mana: mana,
+    pos: new myGame.Vec3Builder(x: 1.0, y: 2.0, z: 3.0),
+    color: myGame.Color.Red,
+    path: [
+        new myGame.Vec3ObjectBuilder(x: 1.0, y: 2.0, z: 3.0),
+        new myGame.Vec3ObjectBuilder(x: 4.0, y: 5.0, z: 6.0)
+    ]);
+
+  final int orc = orcBuilder.finish(builder);
+~~~
+</div>
+<div class="language-lua">
+~~~{.lua}
+    -- Create our monster by using Start() andEnd()
+    monster.Start(builder)
+    monster.AddPos(builder, vec3.CreateVec3(builder, 1.0, 2.0, 3.0))
+    monster.AddHp(builder, 300)
+    monster.AddName(builder, name)
+    monster.AddInventory(builder, inv)
+    monster.AddColor(builder, color.Red)
+    monster.AddWeapons(builder, weapons)
+    monster.AddEquippedType(builder, equipment.Weapon)
+    monster.AddEquipped(builder, axe)
+    monster.AddPath(builder, path)
+    local orc = monster.End(builder)
+~~~
+</div>
+<div class="language-lobster">
+~~~{.lobster}
+  let orc = MyGame_Sample_MonsterBuilder { b }
+      .start()
+      .add_pos(b.MyGame_Sample_CreateVec3(1.0, 2.0, 3.0))
+      .add_hp(300)
+      .add_name(name)
+      .add_inventory(inv)
+      .add_color(MyGame_Sample_Color_Red)
+      .add_weapons(weapons)
+      .add_equipped_type(MyGame_Sample_Equipment_Weapon)
+      .add_equipped(weapon_offsets[1])
+      .add_path(path)
+      .end()
+~~~
+</div>
+<div class="language-rust">
+~~~{.rs}
+  // Create the monster using the `Monster::create` helper function. This
+  // function accepts a `MonsterArgs` struct, which supplies all of the data
+  // needed to build a `Monster`. To supply empty/default fields, just use the
+  // Rust built-in `Default::default()` function, as demonstrated below.
+  let orc = Monster::create(&mut builder, &MonsterArgs{
+      pos: Some(&Vec3::new(1.0f32, 2.0f32, 3.0f32)),
+      mana: 150,
+      hp: 80,
+      name: Some(name),
+      inventory: Some(inventory),
+      color: Color::Red,
+      weapons: Some(weapons),
+      equipped_type: Equipment::Weapon,
+      equipped: Some(axe.as_union_value()),
+      path: Some(path),
+      ..Default::default()
+  });
+~~~
+</div>
+
+Note how we create `Vec3` struct in-line in the table. Unlike tables, structs
+are simple combinations of scalars that are always stored inline, just like
+scalars themselves.
+
+**Important**: Unlike structs, you should not nest tables or other objects,
+which is why we created all the strings/vectors/tables that this monster refers
+to before `start`. If you try to create any of them between `start` and `end`,
+you will get an assert/exception/panic depending on your language.
+
+*Note: Since we are passing `150` as the `mana` field, which happens to be the
+default value, the field will not actually be written to the buffer, since the
+default value will be returned on query anyway. This is a nice space savings,
+especially if default values are common in your data. It also means that you do
+not need to be worried of adding a lot of fields that are only used in a small
+number of instances, as it will not bloat the buffer if unused.*
+
+<div class="language-cpp">
+<br>
+If you do not wish to set every field in a `table`, it may be more convenient to
+manually set each field of your monster, instead of calling `CreateMonster()`.
+The following snippet is functionally equivalent to the above code, but provides
+a bit more flexibility.
+<br>
+~~~{.cpp}
+  // You can use this code instead of `CreateMonster()`, to create our orc
+  // manually.
+  MonsterBuilder monster_builder(builder);
+  monster_builder.add_pos(&position);
+  monster_builder.add_hp(hp);
+  monster_builder.add_name(name);
+  monster_builder.add_inventory(inventory);
+  monster_builder.add_color(Color_Red);
+  monster_builder.add_weapons(weapons);
+  monster_builder.add_equipped_type(Equipment_Weapon);
+  monster_builder.add_equipped(axe.Union());
+  auto orc = monster_builder.Finish();
+~~~
+</div>
+<div class="language-c">
+If you do not wish to set every field in a `table`, it may be more convenient to
+manually set each field of your monster, instead of calling `create_monster_as_root()`.
+The following snippet is functionally equivalent to the above code, but provides
+a bit more flexibility.
+<br>
+~~~{.c}
+  // It is important to pair `start_as_root` with `end_as_root`.
+  ns(Monster_start_as_root(B));
+  ns(Monster_pos_create(B, 1.0f, 2.0f, 3.0f));
+  // or alternatively
+  //ns(Monster_pos_add(&pos);
+
+  ns(Monster_hp_add(B, hp));
+  // Notice that `Monser_name_add` adds a string reference unlike the
+  // add_str and add_strn variants.
+  ns(Monster_name_add(B, name));
+  ns(Monster_inventory_add(B, inventory));
+  ns(Monster_color_add(B, ns(Color_Red)));
+  ns(Monster_weapons_add(B, weapons));
+  ns(Monster_equipped_add(B, equipped));
+  // Complete the monster object and make it the buffer root object.
+  ns(Monster_end_as_root(B));
+~~~
+</div>
+
+Before finishing the serialization, let's take a quick look at FlatBuffer
+`union Equipped`. There are two parts to each FlatBuffer `union`. The first, is
+a hidden field `_type`, that is generated to hold the type of `table` referred
+to by the `union`. This allows you to know which type to cast to at runtime.
+Second, is the `union`'s data.
+
+In our example, the last two things we added to our `Monster` were the
+`Equipped Type` and the `Equipped` union itself.
+
+Here is a repetition these lines, to help highlight them more clearly:
+
+<div class="language-cpp">
+  ~~~{.cpp}
+    monster_builder.add_equipped_type(Equipment_Weapon); // Union type
+    monster_builder.add_equipped(axe); // Union data
+  ~~~
+</div>
+<div class="language-java">
+  ~~~{.java}
+    Monster.addEquippedType(builder, Equipment.Weapon); // Union type
+    Monster.addEquipped(axe); // Union data
+  ~~~
+</div>
+<div class="language-kotlin">
+  ~~~{.kt}
+    Monster.addEquippedType(builder, Equipment.Weapon) // Union type
+    Monster.addEquipped(axe) // Union data
+  ~~~
+</div>
+<div class="language-csharp">
+  ~~~{.cs}
+    Monster.AddEquippedType(builder, Equipment.Weapon); // Union type
+    Monster.AddEquipped(builder, axe.Value); // Union data
+  ~~~
+</div>
+<div class="language-go">
+  ~~~{.go}
+    sample.MonsterAddEquippedType(builder, sample.EquipmentWeapon) // Union type
+    sample.MonsterAddEquipped(builder, axe) // Union data
+  ~~~
+</div>
+<div class="language-python">
+  ~~~{.py}
+    MyGame.Sample.Monster.MonsterAddEquippedType(            # Union type
+        builder, MyGame.Sample.Equipment.Equipment().Weapon)
+    MyGame.Sample.Monster.MonsterAddEquipped(builder, axe)   # Union data
+  ~~~
+</div>
+<div class="language-javascript">
+  ~~~{.js}
+    MyGame.Sample.Monster.addEquippedType(builder, MyGame.Sample.Equipment.Weapon); // Union type
+    MyGame.Sample.Monster.addEquipped(builder, axe); // Union data
+  ~~~
+</div>
+<div class="language-typescript">
+  ~~~{.ts}
+    MyGame.Sample.Monster.addEquippedType(builder, MyGame.Sample.Equipment.Weapon); // Union type
+    MyGame.Sample.Monster.addEquipped(builder, axe); // Union data
+  ~~~
+</div>
+<div class="language-php">
+  ~~~{.php}
+    \MyGame\Sample\Monster::AddEquippedType($builder, \MyGame\Sample\Equipment::Weapon); // Union type
+    \MyGame\Sample\Monster::AddEquipped($builder, $axe); // Union data
+  ~~~
+</div>
+<div class="language-c">
+~~~{.c}
+  // Add union type and data simultaneously.
+  ns(Monster_equipped_Weapon_add(B, axe));
+~~~
+</div>
+<div class="language-dart">
+~~~{.dart}
+  // using the builder API:
+  ..addEquippedType(myGame.EquipmentTypeId.Weapon)
+  ..addEquippedOffset(axe)
+
+  // in the ObjectBuilder API:
+  equippedTypeId: myGame.EquipmentTypeId.Weapon,  // Union type
+  equipped: axe,                                  // Union data
+~~~
+</div>
+<div class="language-lua">
+~~~{.lua}
+    monster.AddEquippedType(builder, equipment.Weapon) -- Union type
+    monster.AddEquipped(builder, axe) -- Union data
+~~~
+</div>
+<div class="language-lobster">
+~~~{.lobster}
+    .add_equipped_type(MyGame_Sample_Equipment_Weapon)
+    .add_equipped(axe)
+~~~
+</div>
+<div class="language-rust">
+  ~~~{.rs}
+    // You need to call `as_union_value` to turn an object into a type that
+    // can be used as a union value.
+    monster_builder.add_equipped_type(Equipment::Weapon); // Union type
+    monster_builder.add_equipped(axe.as_union_value()); // Union data
+  ~~~
+</div>
+
+After you have created your buffer, you will have the offset to the root of the
+data in the `orc` variable, so you can finish the buffer by calling the
+appropriate `finish` method.
+
+
+<div class="language-cpp">
+~~~{.cpp}
+  // Call `Finish()` to instruct the builder that this monster is complete.
+  // Note: Regardless of how you created the `orc`, you still need to call
+  // `Finish()` on the `FlatBufferBuilder`.
+  builder.Finish(orc); // You could also call `FinishMonsterBuffer(builder,
+                       //                                          orc);`.
+~~~
+</div>
+<div class="language-java">
+~~~{.java}
+  // Call `finish()` to instruct the builder that this monster is complete.
+  builder.finish(orc); // You could also call `Monster.finishMonsterBuffer(builder, orc);`.
+~~~
+</div>
+<div class="language-kotlin">
+~~~{.kt}
+  // Call `finish()` to instruct the builder that this monster is complete.
+  builder.finish(orc) // You could also call `Monster.finishMonsterBuffer(builder, orc);`.
+~~~
+</div>
+<div class="language-csharp">
+~~~{.cs}
+  // Call `Finish()` to instruct the builder that this monster is complete.
+  builder.Finish(orc.Value); // You could also call `Monster.FinishMonsterBuffer(builder, orc);`.
+~~~
+</div>
+<div class="language-go">
+~~~{.go}
+  // Call `Finish()` to instruct the builder that this monster is complete.
+  builder.Finish(orc)
+~~~
+</div>
+<div class="language-python">
+~~~{.py}
+  # Call `Finish()` to instruct the builder that this monster is complete.
+  builder.Finish(orc)
+~~~
+</div>
+<div class="language-javascript">
+~~~{.js}
+  // Call `finish()` to instruct the builder that this monster is complete.
+  builder.finish(orc); // You could also call `MyGame.Sample.Monster.finishMonsterBuffer(builder,
+                       //                                                                 orc);`.
+~~~
+</div>
+<div class="language-typescript">
+~~~{.ts}
+  // Call `finish()` to instruct the builder that this monster is complete.
+  builder.finish(orc); // You could also call `MyGame.Sample.Monster.finishMonsterBuffer(builder,
+                       //                                                                 orc);`.
+~~~
+</div>
+<div class="language-php">
+~~~{.php}
+  // Call `finish()` to instruct the builder that this monster is complete.
+   $builder->finish($orc); // You may also call `\MyGame\Sample\Monster::FinishMonsterBuffer(
+                           //                        $builder, $orc);`.
+~~~
+</div>
+<div class="language-c">
+~~~{.c}
+  // Because we used `Monster_create_as_root`, we do not need a `finish` call in C`.
+~~~
+</div>
+<div class="language-dart">
+~~~{.dart}
+  // Call `finish()` to instruct the builder that this monster is complete.
+  // See the next code section, as in Dart `finish` will also return the byte array.
+~~~
+</div>
+<div class="language-lua">
+~~~{.lua}
+    -- Call 'Finish()' to instruct the builder that this monster is complete.
+    builder:Finish(orc)
+~~~
+</div>
+<div class="language-lobster">
+~~~{.lobster}
+  // Call `Finish()` to instruct the builder that this monster is complete.
+  builder.Finish(orc)
+~~~
+</div>
+<div class="language-rust">
+~~~{.rs}
+  // Call `finish()` to instruct the builder that this monster is complete.
+  builder.finish(orc, None);
+~~~
+</div>
+
+The buffer is now ready to be stored somewhere, sent over the network, be
+compressed, or whatever you'd like to do with it. You can access the buffer
+like so:
+
+<div class="language-cpp">
+~~~{.cpp}
+  // This must be called after `Finish()`.
+  uint8_t *buf = builder.GetBufferPointer();
+  int size = builder.GetSize(); // Returns the size of the buffer that
+                                // `GetBufferPointer()` points to.
+~~~
+</div>
+<div class="language-java">
+~~~{.java}
+  // This must be called after `finish()`.
+  java.nio.ByteBuffer buf = builder.dataBuffer();
+  // The data in this ByteBuffer does NOT start at 0, but at buf.position().
+  // The number of bytes is buf.remaining().
+
+  // Alternatively this copies the above data out of the ByteBuffer for you:
+  byte[] buf = builder.sizedByteArray();
+~~~
+</div>
+<div class="language-kotlin">
+~~~{.kt}
+  // This must be called after `finish()`.
+  val buf = builder.dataBuffer()
+  // The data in this ByteBuffer does NOT start at 0, but at buf.position().
+  // The number of bytes is buf.remaining().
+
+  // Alternatively this copies the above data out of the ByteBuffer for you:
+  val buf = builder.sizedByteArray()
+~~~
+</div>
+<div class="language-csharp">
+~~~{.cs}
+  // This must be called after `Finish()`.
+  var buf = builder.DataBuffer; // Of type `FlatBuffers.ByteBuffer`.
+  // The data in this ByteBuffer does NOT start at 0, but at buf.Position.
+  // The end of the data is marked by buf.Length, so the size is
+  // buf.Length - buf.Position.
+
+  // Alternatively this copies the above data out of the ByteBuffer for you:
+  byte[] buf = builder.SizedByteArray();
+~~~
+</div>
+<div class="language-go">
+~~~{.go}
+  // This must be called after `Finish()`.
+  buf := builder.FinishedBytes() // Of type `byte[]`.
+~~~
+</div>
+<div class="language-python">
+~~~{.py}
+  # This must be called after `Finish()`.
+  buf = builder.Output() // Of type `bytearray`.
+~~~
+</div>
+<div class="language-javascript">
+~~~{.js}
+  // This must be called after `finish()`.
+  var buf = builder.asUint8Array(); // Of type `Uint8Array`.
+~~~
+</div>
+<div class="language-typescript">
+~~~{.ts}
+  // This must be called after `finish()`.
+  let buf = builder.asUint8Array(); // Of type `Uint8Array`.
+~~~
+</div>
+<div class="language-php">
+~~~{.php}
+  // This must be called after `finish()`.
+  $buf = $builder->dataBuffer(); // Of type `Google\FlatBuffers\ByteBuffer`
+  // The data in this ByteBuffer does NOT start at 0, but at buf->getPosition().
+  // The end of the data is marked by buf->capacity(), so the size is
+  // buf->capacity() - buf->getPosition().
+~~~
+</div>
+<div class="language-c">
+~~~{.c}
+  uint8_t *buf;
+  size_t size;
+
+  // Allocate and extract a readable buffer from internal builder heap.
+  // The returned buffer must be deallocated using `free`.
+  // NOTE: Finalizing the buffer does NOT change the builder, it
+  // just creates a snapshot of the builder content.
+  buf = flatcc_builder_finalize_buffer(B, &size);
+  // use buf
+  free(buf);
+
+  // Optionally reset builder to reuse builder without deallocating
+  // internal stack and heap.
+  flatcc_builder_reset(B);
+  // build next buffer.
+  // ...
+
+  // Cleanup.
+  flatcc_builder_clear(B);
+~~~
+</div>
+<div class="language-dart">
+~~~{.dart}
+  final Uint8List buf = builder.finish(orc);
+~~~
+</div>
+<div class="language-lua">
+~~~{.lua}
+    -- Get the flatbuffer as a string containing the binary data
+    local bufAsString = builder:Output()
+~~~
+</div>
+<div class="language-lobster">
+~~~{.lobster}
+  // This must be called after `Finish()`.
+  let buf = builder.SizedCopy() // Of type `string`.
+~~~
+</div>
+<div class="language-rust">
+~~~{.rs}
+  // This must be called after `finish()`.
+  // `finished_data` returns a byte slice.
+  let buf = builder.finished_data(); // Of type `&[u8]`
+~~~
+</div>
+
+
+Now you can write the bytes to a file, send them over the network..
+**Make sure your file mode (or transfer protocol) is set to BINARY, not text.**
+If you transfer a FlatBuffer in text mode, the buffer will be corrupted,
+which will lead to hard to find problems when you read the buffer.
+
+#### Reading Orc FlatBuffers
+
+Now that we have successfully created an `Orc` FlatBuffer, the monster data can
+be saved, sent over a network, etc. Let's now adventure into the inverse, and
+access a FlatBuffer.
+
+This section requires the same import/include, namespace, etc. requirements as
+before:
+
+<div class="language-cpp">
+~~~{.cpp}
+  #include "monster_generated.h" // This was generated by `flatc`.
+
+  using namespace MyGame::Sample; // Specified in the schema.
+~~~
+</div>
+<div class="language-java">
+~~~{.java}
+  import MyGame.Sample.*; //The `flatc` generated files. (Monster, Vec3, etc.)
+
+  import com.google.flatbuffers.FlatBufferBuilder;
+~~~
+</div>
+<div class="language-kotlin">
+~~~{.kt}
+  import MyGame.Sample.* //The `flatc` generated files. (Monster, Vec3, etc.)
+
+  import com.google.flatbuffers.FlatBufferBuilder
+~~~
+</div>
+<div class="language-csharp">
+~~~{.cs}
+  using FlatBuffers;
+  using MyGame.Sample; // The `flatc` generated files. (Monster, Vec3, etc.)
+~~~
+</div>
+<div class="language-go">
+~~~{.go}
+  import (
+          flatbuffers "github.com/google/flatbuffers/go"
+          sample "MyGame/Sample"
+  )
+~~~
+</div>
+<div class="language-python">
+~~~{.py}
+  import flatbuffers
+
+  # Generated by `flatc`.
+  import MyGame.Sample.Any
+  import MyGame.Sample.Color
+  import MyGame.Sample.Monster
+  import MyGame.Sample.Vec3
+~~~
+</div>
+<div class="language-javascript">
+~~~{.js}
+  // The following code is for JavaScript module loaders (e.g. Node.js). See
+  // below for a browser-based HTML/JavaScript example of including the library.
+  var flatbuffers = require('/js/flatbuffers').flatbuffers;
+  var MyGame = require('./monster_generated').MyGame; // Generated by `flatc`.
+
+  //--------------------------------------------------------------------------//
+
+  // The following code is for browser-based HTML/JavaScript. Use the above code
+  // for JavaScript module loaders (e.g. Node.js).
+  <script src="../js/flatbuffers.js"></script>
+  <script src="monster_generated.js"></script> // Generated by `flatc`.
+~~~
+</div>
+<div class="language-typescript">
+~~~{.js}
+  // note: import flabuffers with your desired import method
+
+  import { MyGame } from './monster_generated';
+~~~
+</div>
+<div class="language-php">
+~~~{.php}
+  // It is recommended that your use PSR autoload when using FlatBuffers in PHP.
+  // Here is an example from `SampleBinary.php`:
+  function __autoload($class_name) {
+    // The last segment of the class name matches the file name.
+    $class = substr($class_name, strrpos($class_name, "\\") + 1);
+    $root_dir = join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)))); // `flatbuffers` root.
+
+    // Contains the `*.php` files for the FlatBuffers library and the `flatc` generated files.
+    $paths = array(join(DIRECTORY_SEPARATOR, array($root_dir, "php")),
+                   join(DIRECTORY_SEPARATOR, array($root_dir, "samples", "MyGame", "Sample")));
+    foreach ($paths as $path) {
+      $file = join(DIRECTORY_SEPARATOR, array($path, $class . ".php"));
+      if (file_exists($file)) {
+        require($file);
+        break;
+      }
+    }
+  }
+~~~
+</div>
+<div class="language-c">
+~~~{.c}
+  // Only needed if we don't have `#include "monster_builder.h"`.
+  #include "monster_reader.h"
+
+  #undef ns
+  #define ns(x) FLATBUFFERS_WRAP_NAMESPACE(MyGame_Sample, x) // Specified in the schema.
+~~~
+</div>
+<div class="language-dart">
+~~~{.dart}
+import 'package:flat_buffers/flat_buffers.dart' as fb;
+import './monster_my_game.sample_generated.dart' as myGame;
+~~~
+</div>
+<div class="language-lua">
+~~~{.lua}
+  -- require the flatbuffers module
+  local flatbuffers = require("flatbuffers")
+
+  -- require the generated files from `flatc`.
+  local color = require("MyGame.Sample.Color")
+  local equipment = require("MyGame.Sample.Equipment")
+  local monster = require("MyGame.Sample.Monster")
+  local vec3 = require("MyGame.Sample.Vec3")
+  local weapon = require("MyGame.Sample.Weapon")
+~~~
+</div>
+<div class="language-lobster">
+~~~{.lobster}
+  import from "../lobster/"  // Where to find flatbuffers.lobster
+  import monster_generated
+~~~
+</div>
+<div class="language-rust">
+~~~{.rs}
+  // import the flatbuffers runtime library
+  extern crate flatbuffers;
+
+  // import the generated code
+  #[allow(dead_code, unused_imports)]
+  #[path = "./monster_generated.rs"]
+  mod monster_generated;
+  pub use monster_generated::my_game::sample::{get_root_as_monster,
+                                               Color, Equipment,
+                                               Monster, MonsterArgs,
+                                               Vec3,
+                                               Weapon, WeaponArgs};
+~~~
+</div>
+
+Then, assuming you have a buffer of bytes received from disk,
+network, etc., you can create start accessing the buffer like so:
+
+**Again, make sure you read the bytes in BINARY mode, otherwise the code below
+won't work**
+
+<div class="language-cpp">
+~~~{.cpp}
+  uint8_t *buffer_pointer = /* the data you just read */;
+
+  // Get a pointer to the root object inside the buffer.
+  auto monster = GetMonster(buffer_pointer);
+
+  // `monster` is of type `Monster *`.
+  // Note: root object pointers are NOT the same as `buffer_pointer`.
+  // `GetMonster` is a convenience function that calls `GetRoot<Monster>`,
+  // the latter is also available for non-root types.
+~~~
+</div>
+<div class="language-java">
+~~~{.java}
+  byte[] bytes = /* the data you just read */
+  java.nio.ByteBuffer buf = java.nio.ByteBuffer.wrap(bytes);
+
+  // Get an accessor to the root object inside the buffer.
+  Monster monster = Monster.getRootAsMonster(buf);
+~~~
+</div>
+<div class="language-kotlin">
+~~~{.kt}
+  val bytes = /* the data you just read */
+  val buf = java.nio.ByteBuffer.wrap(bytes)
+
+  // Get an accessor to the root object inside the buffer.
+  Monster monster = Monster.getRootAsMonster(buf)
+~~~
+</div>
+<div class="language-csharp">
+~~~{.cs}
+  byte[] bytes = /* the data you just read */
+  var buf = new ByteBuffer(bytes);
+
+  // Get an accessor to the root object inside the buffer.
+  var monster = Monster.GetRootAsMonster(buf);
+~~~
+</div>
+<div class="language-go">
+~~~{.go}
+  var buf []byte = /* the data you just read */
+
+  // Get an accessor to the root object inside the buffer.
+  monster := sample.GetRootAsMonster(buf, 0)
+
+  // Note: We use `0` for the offset here, which is typical for most buffers
+  // you would read. If you wanted to read from `builder.Bytes` directly, you
+  // would need to pass in the offset of `builder.Head()`, as the builder
+  // constructs the buffer backwards, so may not start at offset 0.
+~~~
+</div>
+<div class="language-python">
+~~~{.py}
+  buf = /* the data you just read, in an object of type "bytearray" */
+
+  // Get an accessor to the root object inside the buffer.
+  monster = MyGame.Sample.Monster.Monster.GetRootAsMonster(buf, 0)
+
+  # Note: We use `0` for the offset here, which is typical for most buffers
+  # you would read.  If you wanted to read from the `builder.Bytes` directly,
+  # you would need to pass in the offset of `builder.Head()`, as the builder
+  # constructs the buffer backwards, so may not start at offset 0.
+~~~
+</div>
+<div class="language-javascript">
+~~~{.js}
+  var bytes = /* the data you just read, in an object of type "Uint8Array" */
+  var buf = new flatbuffers.ByteBuffer(bytes);
+
+  // Get an accessor to the root object inside the buffer.
+  var monster = MyGame.Sample.Monster.getRootAsMonster(buf);
+~~~
+</div>
+<div class="language-typescript">
+~~~{.ts}
+  let bytes = /* the data you just read, in an object of type "Uint8Array" */
+  let buf = new flatbuffers.ByteBuffer(bytes);
+
+  // Get an accessor to the root object inside the buffer.
+  let monster = MyGame.Sample.Monster.getRootAsMonster(buf);
+~~~
+</div>
+<div class="language-php">
+~~~{.php}
+  $bytes = /* the data you just read, in a string */
+  $buf = Google\FlatBuffers\ByteBuffer::wrap($bytes);
+
+  // Get an accessor to the root object inside the buffer.
+  $monster = \MyGame\Sample\Monster::GetRootAsMonster($buf);
+~~~
+</div>
+<div class="language-c">
+~~~{.c}
+  // Note that we use the `table_t` suffix when reading a table object
+  // as opposed to the `ref_t` suffix used during the construction of
+  // the buffer.
+  ns(Monster_table_t) monster = ns(Monster_as_root(buffer));
+
+  // Note: root object pointers are NOT the same as the `buffer` pointer.
+~~~
+</div>
+<div class="language-dart">
+~~~{.dart}
+List<int> data = ... // the data, e.g. from file or network
+// A generated factory constructor that will read the data.
+myGame.Monster monster = new myGame.Monster(data);
+~~~
+</div>
+<div class="language-lua">
+~~~{.lua}
+    local bufAsString =   -- The data you just read in
+
+    -- Convert the string representation into binary array Lua structure
+    local buf = flatbuffers.binaryArray.New(bufAsString)
+
+    -- Get an accessor to the root object insert the buffer
+    local mon = monster.GetRootAsMonster(buf, 0)
+~~~
+</div>
+<div class="language-lobster">
+~~~{.lobster}
+  buf = /* the data you just read, in a string */
+
+  // Get an accessor to the root object inside the buffer.
+  let monster = MyGame_Sample_GetRootAsMonster(buf)
+~~~
+</div>
+<div class="language-rust">
+~~~{.rs}
+  let buf = /* the data you just read, in a &[u8] */
+
+  // Get an accessor to the root object inside the buffer.
+  let monster = get_root_as_monster(buf);
+~~~
+</div>
+
+If you look in the generated files from the schema compiler, you will see it generated
+accessors for all non-`deprecated` fields. For example:
+
+<div class="language-cpp">
+~~~{.cpp}
+  auto hp = monster->hp();
+  auto mana = monster->mana();
+  auto name = monster->name()->c_str();
+~~~
+</div>
+<div class="language-java">
+~~~{.java}
+  short hp = monster.hp();
+  short mana = monster.mana();
+  String name = monster.name();
+~~~
+</div>
+<div class="language-kotlin">
+~~~{.kt}
+  val hp = monster.hp
+  val mana = monster.mana
+  val name = monster.name
+~~~
+</div>
+<div class="language-csharp">
+~~~{.cs}
+  // For C#, unlike most other languages support by FlatBuffers, most values (except for
+  // vectors and unions) are available as properties instead of accessor methods.
+  var hp = monster.Hp
+  var mana = monster.Mana
+  var name = monster.Name
+~~~
+</div>
+<div class="language-go">
+~~~{.go}
+  hp := monster.Hp()
+  mana := monster.Mana()
+  name := string(monster.Name()) // Note: `monster.Name()` returns a byte[].
+~~~
+</div>
+<div class="language-python">
+~~~{.py}
+  hp = monster.Hp()
+  mana = monster.Mana()
+  name = monster.Name()
+~~~
+</div>
+<div class="language-javascript">
+~~~{.js}
+  var hp = $monster.hp();
+  var mana = $monster.mana();
+  var name = $monster.name();
+~~~
+</div>
+<div class="language-typescript">
+~~~{.ts}
+  let hp = $monster.hp();
+  let mana = $monster.mana();
+  let name = $monster.name();
+~~~
+</div>
+<div class="language-php">
+~~~{.php}
+  $hp = $monster->getHp();
+  $mana = $monster->getMana();
+  $name = monster->getName();
+~~~
+</div>
+<div class="language-c">
+~~~{.c}
+  uint16_t hp = ns(Monster_hp(monster));
+  uint16_t mana = ns(Monster_mana(monster));
+  flatbuffers_string_t name = ns(Monster_name(monster));
+~~~
+</div>
+<div class="language-dart">
+~~~{.dart}
+  // For Dart, unlike other languages support by FlatBuffers, most values
+  // are available as properties instead of accessor methods.
+  var hp = monster.hp;
+  var mana = monster.mana;
+  var name = monster.name;
+~~~
+</div>
+<div class="language-lua">
+~~~{.lua}
+  local hp = mon:Hp()
+  local mana = mon:Mana()
+  local name = mon:Name()
+~~~
+</div>
+<div class="language-lobster">
+~~~{.lobster}
+  let hp = monster.hp
+  let mana = monster.mana
+  let name = monster.name
+~~~
+</div>
+<div class="language-rust">
+~~~{.rs}
+  // Get and test some scalar types from the FlatBuffer.
+  let hp = monster.hp();
+  let mana = monster.mana();
+  let name = monster.name();
+~~~
+</div>
+
+These should hold `300`, `150`, and `"Orc"` respectively.
+
+*Note: The default value `150` wasn't stored in `mana`, but we are still able to retrieve it.*
+
+To access sub-objects, in the case of our `pos`, which is a `Vec3`:
+
+<div class="language-cpp">
+~~~{.cpp}
+  auto pos = monster->pos();
+  auto x = pos->x();
+  auto y = pos->y();
+  auto z = pos->z();
+~~~
+</div>
+<div class="language-java">
+~~~{.java}
+  Vec3 pos = monster.pos();
+  float x = pos.x();
+  float y = pos.y();
+  float z = pos.z();
+~~~
+</div>
+<div class="language-kotlin">
+~~~{.kt}
+  val pos = monster.pos!!
+  val x = pos.x
+  val y = pos.y
+  val z = pos.z
+~~~
+</div>
+<div class="language-csharp">
+~~~{.cs}
+  var pos = monster.Pos.Value;
+  var x = pos.X;
+  var y = pos.Y;
+  var z = pos.Z;
+~~~
+</div>
+<div class="language-go">
+~~~{.go}
+  pos := monster.Pos(nil)
+  x := pos.X()
+  y := pos.Y()
+  z := pos.Z()
+
+  // Note: Whenever you access a new object, like in `Pos()`, a new temporary
+  // accessor object gets created. If your code is very performance sensitive,
+  // you can pass in a pointer to an existing `Vec3` instead of `nil`. This
+  // allows you to reuse it across many calls to reduce the amount of object
+  // allocation/garbage collection.
+~~~
+</div>
+<div class="language-python">
+~~~{.py}
+  pos = monster.Pos()
+  x = pos.X()
+  y = pos.Y()
+  z = pos.Z()
+~~~
+</div>
+<div class="language-javascript">
+~~~{.js}
+  var pos = monster.pos();
+  var x = pos.x();
+  var y = pos.y();
+  var z = pos.z();
+~~~
+</div>
+<div class="language-typescript">
+~~~{.ts}
+  let pos = monster.pos();
+  let x = pos.x();
+  let y = pos.y();
+  let z = pos.z();
+~~~
+</div>
+<div class="language-php">
+~~~{.php}
+  $pos = $monster->getPos();
+  $x = $pos->getX();
+  $y = $pos->getY();
+  $z = $pos->getZ();
+~~~
+</div>
+<div class="language-c">
+~~~{.c}
+  ns(Vec3_struct_t) pos = ns(Monster_pos(monster));
+  float x = ns(Vec3_x(pos));
+  float y = ns(Vec3_y(pos));
+  float z = ns(Vec3_z(pos));
+~~~
+</div>
+<div class="language-dart">
+~~~{.dart}
+  myGame.Vec3 pos = monster.pos;
+  double x = pos.x;
+  double y = pos.y;
+  double z = pos.z;
+~~~
+</div>
+<div class="language-lua">
+~~~{.lua}
+  local pos = mon:Pos()
+  local x = pos:X()
+  local y = pos:Y()
+  local z = pos:Z()
+~~~
+</div>
+<div class="language-lobster">
+~~~{.lobster}
+  let pos = monster.pos
+  let x = pos.x
+  let y = pos.y
+  let z = pos.z
+~~~
+</div>
+<div class="language-rust">
+~~~{.rs}
+  let pos = monster.pos().unwrap();
+  let x = pos.x();
+  let y = pos.y();
+  let z = pos.z();
+~~~
+</div>
+
+`x`, `y`, and `z` will contain `1.0`, `2.0`, and `3.0`, respectively.
+
+*Note: Had we not set `pos` during serialization, it would be a `NULL`-value.*
+
+Similarly, we can access elements of the inventory `vector` by indexing it. You
+can also iterate over the length of the array/vector representing the
+FlatBuffers `vector`.
+
+<div class="language-cpp">
+~~~{.cpp}
+  auto inv = monster->inventory(); // A pointer to a `flatbuffers::Vector<>`.
+  auto inv_len = inv->size();
+  auto third_item = inv->Get(2);
+~~~
+</div>
+<div class="language-java">
+~~~{.java}
+  int invLength = monster.inventoryLength();
+  byte thirdItem = monster.inventory(2);
+~~~
+</div>
+<div class="language-kotlin">
+~~~{.kotlin}
+  val invLength = monster.inventoryLength
+  val thirdItem = monster.inventory(2)!!
+~~~
+</div>
+<div class="language-csharp">
+~~~{.cs}
+  int invLength = monster.InventoryLength;
+  var thirdItem = monster.Inventory(2);
+~~~
+</div>
+<div class="language-go">
+~~~{.go}
+  invLength := monster.InventoryLength()
+  thirdItem := monster.Inventory(2)
+~~~
+</div>
+<div class="language-python">
+~~~{.py}
+  inv_len = monster.InventoryLength()
+  third_item = monster.Inventory(2)
+~~~
+</div>
+<div class="language-javascript">
+~~~{.js}
+  var invLength = monster.inventoryLength();
+  var thirdItem = monster.inventory(2);
+~~~
+</div>
+<div class="language-typescript">
+~~~{.ts}
+  let invLength = monster.inventoryLength();
+  let thirdItem = monster.inventory(2);
+~~~
+</div>
+<div class="language-php">
+~~~{.php}
+  $inv_len = $monster->getInventoryLength();
+  $third_item = $monster->getInventory(2);
+~~~
+</div>
+<div class="language-c">
+~~~{.c}
+    // If `inv` hasn't been set, it will be null. It is valid get
+    // the length of null which will be 0, useful for iteration.
+    flatbuffers_uint8_vec_t inv = ns(Monster_inventory(monster));
+    size_t inv_len = flatbuffers_uint8_vec_len(inv);
+~~~
+</div>
+<div class="language-dart">
+~~~{.dart}
+  int invLength = monster.inventory.length;
+  var thirdItem = monster.inventory[2];
+~~~
+</div>
+<div class="language-lua">
+~~~{.lua}
+  local invLength = mon:InventoryLength()
+  local thirdItem = mon:Inventory(3) -- Lua is 1-based
+~~~
+</div>
+<div class="language-lobster">
+~~~{.lobster}
+  let inv_len = monster.inventory_length
+  let third_item = monster.inventory(2)
+~~~
+</div>
+<div class="language-rust">
+~~~{.rs}
+  // Get a test an element from the `inventory` FlatBuffer's `vector`.
+  let inv = monster.inventory().unwrap();
+
+  // Note that this vector is returned as a slice, because direct access for
+  // this type, a `u8` vector, is safe on all platforms:
+  let third_item = inv[2];
+~~~
+</div>
+
+For `vector`s of `table`s, you can access the elements like any other vector,
+except your need to handle the result as a FlatBuffer `table`:
+
+<div class="language-cpp">
+~~~{.cpp}
+  auto weapons = monster->weapons(); // A pointer to a `flatbuffers::Vector<>`.
+  auto weapon_len = weapons->size();
+  auto second_weapon_name = weapons->Get(1)->name()->str();
+  auto second_weapon_damage = weapons->Get(1)->damage()
+~~~
+</div>
+<div class="language-java">
+~~~{.java}
+  int weaponsLength = monster.weaponsLength();
+  String secondWeaponName = monster.weapons(1).name();
+  short secondWeaponDamage = monster.weapons(1).damage();
+~~~
+</div>
+<div class="language-kotlin">
+~~~{.kt}
+  val weaponsLength = monster.weaponsLength
+  val secondWeaponName = monster.weapons(1)!!.name
+  val secondWeaponDamage = monster.weapons(1)!!.damage
+~~~
+</div>
+<div class="language-csharp">
+~~~{.cs}
+  int weaponsLength = monster.WeaponsLength;
+  var secondWeaponName = monster.Weapons(1).Name;
+  var secondWeaponDamage = monster.Weapons(1).Damage;
+~~~
+</div>
+<div class="language-go">
+~~~{.go}
+  weaponLength := monster.WeaponsLength()
+  weapon := new(sample.Weapon) // We need a `sample.Weapon` to pass into `monster.Weapons()`
+                               // to capture the output of the function.
+  if monster.Weapons(weapon, 1) {
+          secondWeaponName := weapon.Name()
+          secondWeaponDamage := weapon.Damage()
+  }
+~~~
+</div>
+<div class="language-python">
+~~~{.py}
+  weapons_length = monster.WeaponsLength()
+  second_weapon_name = monster.Weapons(1).Name()
+  second_weapon_damage = monster.Weapons(1).Damage()
+~~~
+</div>
+<div class="language-javascript">
+~~~{.js}
+  var weaponsLength = monster.weaponsLength();
+  var secondWeaponName = monster.weapons(1).name();
+  var secondWeaponDamage = monster.weapons(1).damage();
+~~~
+</div>
+<div class="language-typescript">
+~~~{.ts}
+  let weaponsLength = monster.weaponsLength();
+  let secondWeaponName = monster.weapons(1).name();
+  let secondWeaponDamage = monster.weapons(1).damage();
+~~~
+</div>
+<div class="language-php">
+~~~{.php}
+  $weapons_len = $monster->getWeaponsLength();
+  $second_weapon_name = $monster->getWeapons(1)->getName();
+  $second_weapon_damage = $monster->getWeapons(1)->getDamage();
+~~~
+</div>
+<div class="language-c">
+~~~{.c}
+  ns(Weapon_vec_t) weapons = ns(Monster_weapons(monster));
+  size_t weapons_len = ns(Weapon_vec_len(weapons));
+  // We can use `const char *` instead of `flatbuffers_string_t`.
+  const char *second_weapon_name = ns(Weapon_name(ns(Weapon_vec_at(weapons, 1))));
+  uint16_t second_weapon_damage =  ns(Weapon_damage(ns(Weapon_vec_at(weapons, 1))));
+~~~
+</div>
+<div class="language-dart">
+~~~{.dart}
+  int weaponsLength = monster.weapons.length;
+  var secondWeaponName = monster.weapons[1].name;
+  var secondWeaponDamage = monster.Weapons[1].damage;
+~~~
+</div>
+<div class="language-lua">
+~~~{.lua}
+  local weaponsLength = mon:WeaponsLength()
+  local secondWeaponName = mon:Weapon(2):Name()
+  local secondWeaponDamage = mon:Weapon(2):Damage()
+~~~
+</div>
+<div class="language-lobster">
+~~~{.lobster}
+  let weapons_length = monster.weapons_length
+  let second_weapon_name = monster.weapons(1).name
+  let second_weapon_damage = monster.weapons(1).damage
+~~~
+</div>
+<div class="language-rust">
+~~~{.rs}
+  // Get and test the `weapons` FlatBuffers's `vector`.
+  let weps = monster.weapons().unwrap();
+  let weps_len = weps.len();
+
+  let wep2 = weps.get(1);
+  let second_weapon_name = wep2.name();
+  let second_weapon_damage = wep2.damage();
+~~~
+</div>
+
+Last, we can access our `Equipped` FlatBuffer `union`. Just like when we created
+the `union`, we need to get both parts of the `union`: the type and the data.
+
+We can access the type to dynamically cast the data as needed (since the
+`union` only stores a FlatBuffer `table`).
+
+<div class="language-cpp">
+~~~{.cpp}
+  auto union_type = monster.equipped_type();
+
+  if (union_type == Equipment_Weapon) {
+    auto weapon = static_cast<const Weapon*>(monster->equipped()); // Requires `static_cast`
+                                                                   // to type `const Weapon*`.
+
+    auto weapon_name = weapon->name()->str(); // "Axe"
+    auto weapon_damage = weapon->damage();    // 5
+  }
+~~~
+</div>
+<div class="language-java">
+~~~{.java}
+  int unionType = monster.EquippedType();
+
+  if (unionType == Equipment.Weapon) {
+    Weapon weapon = (Weapon)monster.equipped(new Weapon()); // Requires explicit cast
+                                                            // to `Weapon`.
+
+    String weaponName = weapon.name();    // "Axe"
+    short weaponDamage = weapon.damage(); // 5
+  }
+~~~
+</div>
+<div class="language-kotlin">
+~~~{.kt}
+  val unionType = monster.EquippedType
+
+  if (unionType == Equipment.Weapon) {
+    val weapon = monster.equipped(Weapon()) as Weapon // Requires explicit cast
+                                                            // to `Weapon`.
+
+    val weaponName = weapon.name   // "Axe"
+    val weaponDamage = weapon.damage // 5
+  }
+~~~
+</div>
+<div class="language-csharp">
+~~~{.cs}
+  var unionType = monster.EquippedType;
+
+  if (unionType == Equipment.Weapon) {
+    var weapon = monster.Equipped<Weapon>().Value;
+
+    var weaponName = weapon.Name;     // "Axe"
+    var weaponDamage = weapon.Damage; // 5
+  }
+~~~
+</div>
+<div class="language-go">
+~~~{.go}
+  // We need a `flatbuffers.Table` to capture the output of the
+  // `monster.Equipped()` function.
+  unionTable := new(flatbuffers.Table)
+
+  if monster.Equipped(unionTable) {
+          unionType := monster.EquippedType()
+
+          if unionType == sample.EquipmentWeapon {
+                  // Create a `sample.Weapon` object that can be initialized with the contents
+                  // of the `flatbuffers.Table` (`unionTable`), which was populated by
+                  // `monster.Equipped()`.
+                  unionWeapon = new(sample.Weapon)
+                  unionWeapon.Init(unionTable.Bytes, unionTable.Pos)
+
+                  weaponName = unionWeapon.Name()
+                  weaponDamage = unionWeapon.Damage()
+          }
+  }
+~~~
+</div>
+<div class="language-python">
+~~~{.py}
+  union_type = monster.EquippedType()
+
+  if union_type == MyGame.Sample.Equipment.Equipment().Weapon:
+    # `monster.Equipped()` returns a `flatbuffers.Table`, which can be used to
+    # initialize a `MyGame.Sample.Weapon.Weapon()`.
+    union_weapon = MyGame.Sample.Weapon.Weapon()
+    union_weapon.Init(monster.Equipped().Bytes, monster.Equipped().Pos)
+
+    weapon_name = union_weapon.Name()     // 'Axe'
+    weapon_damage = union_weapon.Damage() // 5
+~~~
+</div>
+<div class="language-javascript">
+~~~{.js}
+  var unionType = monster.equippedType();
+
+  if (unionType == MyGame.Sample.Equipment.Weapon) {
+    var weapon_name = monster.equipped(new MyGame.Sample.Weapon()).name();     // 'Axe'
+    var weapon_damage = monster.equipped(new MyGame.Sample.Weapon()).damage(); // 5
+  }
+~~~
+</div>
+<div class="language-typescript">
+~~~{.ts}
+  let unionType = monster.equippedType();
+
+  if (unionType == MyGame.Sample.Equipment.Weapon) {
+    let weapon_name = monster.equipped(new MyGame.Sample.Weapon()).name();     // 'Axe'
+    let weapon_damage = monster.equipped(new MyGame.Sample.Weapon()).damage(); // 5
+  }
+~~~
+</div>
+<div class="language-php">
+~~~{.php}
+  $union_type = $monster->getEquippedType();
+
+  if ($union_type == \MyGame\Sample\Equipment::Weapon) {
+    $weapon_name = $monster->getEquipped(new \MyGame\Sample\Weapon())->getName();     // "Axe"
+    $weapon_damage = $monster->getEquipped(new \MyGame\Sample\Weapon())->getDamage(); // 5
+  }
+~~~
+</div>
+<div class="language-c">
+~~~{.c}
+  // Access union type field.
+  if (ns(Monster_equipped_type(monster)) == ns(Equipment_Weapon)) {
+      // Cast to appropriate type:
+      // C allows for silent void pointer assignment, so we need no explicit cast.
+      ns(Weapon_table_t) weapon = ns(Monster_equipped(monster));
+      const char *weapon_name = ns(Weapon_name(weapon)); // "Axe"
+      uint16_t weapon_damage = ns(Weapon_damage(weapon)); // 5
+  }
+~~~
+</div>
+<div class="language-dart">
+~~~{.dart}
+  var unionType = monster.equippedType.value;
+
+  if (unionType == myGame.EquipmentTypeId.Weapon.value) {
+    myGame.Weapon weapon = mon.equipped as myGame.Weapon;
+
+    var weaponName = weapon.name;     // "Axe"
+    var weaponDamage = weapon.damage; // 5
+  }
+~~~
+</div>
+<div class="language-lua">
+~~~{.lua}
+  local unionType = mon:EquippedType()
+
+  if unionType == equipment.Weapon then
+    local unionWeapon = weapon.New()
+    unionWeapon:Init(mon:Equipped().bytes, mon:Equipped().pos)
+
+    local weaponName = unionWeapon:Name()     -- 'Axe'
+    local weaponDamage = unionWeapon:Damage() -- 5
+  end
+~~~
+</div>
+<div class="language-lobster">
+~~~{.lobster}
+  union_type = monster.equipped_type
+
+  if union_type == MyGame_Sample_Equipment_Weapon:
+      // `monster.equipped_as_Weapon` returns a FlatBuffer handle much like normal table fields,
+      // but this is only valid to call if we already know it is the correct type.
+      let union_weapon = monster.equipped_as_Weapon
+
+      let weapon_name = union_weapon.name     // "Axe"
+      let weapon_damage = union_weapon.damage // 5
+~~~
+</div>
+<div class="language-rust">
+~~~{.rs}
+  // Get and test the `Equipment` union (`equipped` field).
+  // `equipped_as_weapon` returns a FlatBuffer handle much like normal table
+  // fields, but this will return `None` is the union is not actually of that
+  // type.
+  if monster.equipped_type() == Equipment::Weapon {
+    let equipped = monster.equipped_as_weapon().unwrap();
+    let weapon_name = equipped.name();
+    let weapon_damage = equipped.damage();
+~~~
+</div>
+
+## Mutating FlatBuffers
+
+As you saw above, typically once you have created a FlatBuffer, it is read-only
+from that moment on. There are, however, cases where you have just received a
+FlatBuffer, and you'd like to modify something about it before sending it on to
+another recipient. With the above functionality, you'd have to generate an
+entirely new FlatBuffer, while tracking what you modified in your own data
+structures. This is inconvenient.
+
+For this reason FlatBuffers can also be mutated in-place. While this is great
+for making small fixes to an existing buffer, you generally want to create
+buffers from scratch whenever possible, since it is much more efficient and the
+API is much more general purpose.
+
+To get non-const accessors, invoke `flatc` with `--gen-mutable`.
+
+Similar to how we read fields using the accessors above, we can now use the
+mutators like so:
+
+<div class="language-cpp">
+~~~{.cpp}
+  auto monster = GetMutableMonster(buffer_pointer);  // non-const
+  monster->mutate_hp(10);                      // Set the table `hp` field.
+  monster->mutable_pos()->mutate_z(4);         // Set struct field.
+  monster->mutable_inventory()->Mutate(0, 1);  // Set vector element.
+~~~
+</div>
+<div class="language-java">
+~~~{.java}
+  Monster monster = Monster.getRootAsMonster(buf);
+  monster.mutateHp(10);            // Set table field.
+  monster.pos().mutateZ(4);        // Set struct field.
+  monster.mutateInventory(0, 1);   // Set vector element.
+~~~
+</div>
+<div class="language-kotlin">
+~~~{.kt}
+  val monster = Monster.getRootAsMonster(buf)
+  monster.mutateHp(10)            // Set table field.
+  monster.pos!!.mutateZ(4)        // Set struct field.
+  monster.mutateInventory(0, 1)   // Set vector element.
+~~~
+</div>
+<div class="language-csharp">
+~~~{.cs}
+  var monster = Monster.GetRootAsMonster(buf);
+  monster.MutateHp(10);            // Set table field.
+  monster.Pos.MutateZ(4);          // Set struct field.
+  monster.MutateInventory(0, 1);   // Set vector element.
+~~~
+</div>
+<div class="language-go">
+~~~{.go}
+  <API for mutating FlatBuffers is not yet available in Go.>
+~~~
+</div>
+<div class="language-python">
+~~~{.py}
+  <API for mutating FlatBuffers is not yet available in Python.>
+~~~
+</div>
+<div class="language-javascript">
+~~~{.js}
+  <API for mutating FlatBuffers is not yet supported in JavaScript.>
+~~~
+</div>
+<div class="language-typescript">
+~~~{.ts}
+  <API for mutating FlatBuffers is not yet supported in TypeScript.>
+~~~
+</div>
+<div class="language-php">
+~~~{.php}
+  <API for mutating FlatBuffers is not yet supported in PHP.>
+~~~
+</div>
+<div class="language-c">
+~~~{.c}
+  <API for in-place mutating FlatBuffers will not be supported in C
+  (except in-place vector sorting is possible).>
+~~~
+</div>
+<div class="language-dart">
+~~~{.dart}
+  <API for mutating FlatBuffers not yet available in Dart.>
+~~~
+</div>
+<div class="language-lua">
+~~~{.lua}
+  <API for mutating FlatBuffers is not yet available in Lua.>
+~~~
+</div>
+<div class="language-lobster">
+~~~{.lobster}
+  <API for mutating FlatBuffers is not yet available in Lobster.>
+~~~
+</div>
+<div class="language-rust">
+~~~{.rs}
+  <API for mutating FlatBuffers is not yet available in Rust.>
+~~~
+</div>
+
+We use the somewhat verbose term `mutate` instead of `set` to indicate that this
+is a special use case, not to be confused with the default way of constructing
+FlatBuffer data.
+
+After the above mutations, you can send on the FlatBuffer to a new recipient
+without any further work!
+
+Note that any `mutate` functions on a table will return a boolean, which is
+`false` if the field we're trying to set is not present in the buffer. Fields
+that are not present if they weren't set, or even if they happen to be equal to
+the default value. For example, in the creation code above, the `mana`
+field is equal to `150`, which is the default value, so it was never stored in
+the buffer. Trying to call the corresponding `mutate` method for `mana` on such
+data will return `false`, and the value won't actually be modified!
+
+One way to solve this is to call `ForceDefaults` on a FlatBufferBuilder to
+force all fields you set to actually be written. This, of course, increases the
+size of the buffer somewhat, but this may be acceptable for a mutable buffer.
+
+If this is not sufficient, other ways of mutating FlatBuffers may be supported
+in your language through an object based API (`--gen-object-api`) or reflection.
+See the individual language documents for support.
+
+## Using `flatc` as a JSON Conversion Tool
+
+If you are working with C, C++, or Lobster, you can parse JSON at runtime.
+If your language does not support JSON at the moment, `flatc` may provide an
+alternative. Using `flatc` is often the preferred method, as it doesn't require you to
+add any new code to your program. It is also efficient, since you can ship with
+the binary data. The drawback is that it requires an extra step for your
+users/developers to perform (although it may be able to be automated
+as part of your compilation).
+
+#### JSON to binary representation
+
+Lets say you have a JSON file that describes your monster. In this example,
+we will use the file `flatbuffers/samples/monsterdata.json`.
+
+Here are the contents of the file:
+
+~~~{.json}
+{
+  pos: {
+    x: 1.0,
+    y: 2.0,
+    z: 3.0
+  },
+  hp: 300,
+  name: "Orc",
+  weapons: [
+    {
+      name: "axe",
+      damage: 100
+    },
+    {
+      name: "bow",
+      damage: 90
+    }
+  ],
+  equipped_type: "Weapon",
+  equipped: {
+    name: "bow",
+    damage: 90
+  }
+}
+~~~
+
+You can run this file through the `flatc` compiler with the `-b` flag and
+our `monster.fbs` schema to produce a FlatBuffer binary file.
+
+~~~{.sh}
+./../flatc -b monster.fbs monsterdata.json
+~~~
+
+The output of this will be a file `monsterdata.bin`, which will contain the
+FlatBuffer binary representation of the contents from our `.json` file.
+
+<div class="language-cpp">
+*Note: If you're working in C++, you can also parse JSON at runtime. See the
+[Use in C++](@ref flatbuffers_guide_use_cpp) section of the Programmer's
+Guide for more information.*
+</div>
+<div class="language-c">
+*Note: If you're working in C, the `flatcc --json` (not `flatc`)
+compiler will generate schema specific high performance json parsers and
+printers that you can compile and use at runtime. The `flatc` compiler (not
+`flatcc`) on the other hand, is still useful for general offline json to
+flatbuffer conversion from a given schema. There are no current plans
+for `flatcc` to support this.*
+</div>
+<div class="language-lobster">
+*Note: If you're working in Lobster, you can also parse JSON at runtime. See the
+[Use in Lobster](@ref flatbuffers_guide_use_lobster) section of the Programmer's
+Guide for more information.*
+</div>
+
+#### FlatBuffer binary to JSON
+
+Converting from a FlatBuffer binary representation to JSON is supported as well:
+~~~{.sh}
+./../flatc --json --raw-binary monster.fbs -- monsterdata.bin
+~~~
+This will convert `monsterdata.bin` back to its original JSON representation.
+You need to pass the corresponding FlatBuffers schema so that flatc knows how to
+interpret the binary buffer. Since `monster.fbs` does not specify an explicit
+`file_identifier` for binary buffers, `flatc` needs to be forced into reading
+the `.bin` file using the `--raw-binary` option.
+
+The FlatBuffer binary representation does not explicitly encode default values,
+therefore they are not present in the resulting JSON unless you specify
+`--defaults-json`.
+
+If you intend to process the JSON with other tools, you may consider switching
+on `--strict-json` so that identifiers are quoted properly.
+
+*Note: The resulting JSON file is not necessarily identical with the original JSON.
+If the binary representation contains floating point numbers, floats and doubles
+are rounded to 6 and 12 digits, respectively, in order to represent them as
+decimals in the JSON document. *
+
+## Advanced Features for Each Language
+
+Each language has a dedicated `Use in XXX` page in the Programmer's Guide
+to cover the nuances of FlatBuffers in that language.
+
+For your chosen language, see:
+
+<div class="language-cpp">
+[Use in C++](@ref flatbuffers_guide_use_cpp)
+</div>
+<div class="language-java">
+[Use in Java/C#](@ref flatbuffers_guide_use_java_c-sharp)
+</div>
+<div class="language-kotlin">
+[Use in Kotlin](@ref flatbuffers_guide_use_kotlin)
+</div>
+<div class="language-csharp">
+[Use in Java/C#](@ref flatbuffers_guide_use_java_c-sharp)
+</div>
+<div class="language-go">
+[Use in Go](@ref flatbuffers_guide_use_go)
+</div>
+<div class="language-python">
+[Use in Python](@ref flatbuffers_guide_use_python)
+</div>
+<div class="language-javascript">
+[Use in JavaScript](@ref flatbuffers_guide_use_javascript)
+</div>
+<div class="language-typescript">
+[Use in TypeScript](@ref flatbuffers_guide_use_typescript)
+</div>
+<div class="language-php">
+[Use in PHP](@ref flatbuffers_guide_use_php)
+</div>
+<div class="language-c">
+[Use in C](@ref flatbuffers_guide_use_c)
+</div>
+<div class="language-dart">
+[Use in Dart](@ref flatbuffers_guide_use_dart)
+</div>
+<div class="language-lua">
+[Use in Lua](@ref flatbuffers_guide_use_lua)
+</div>
+<div class="language-lobster">
+[Use in Lobster](@ref flatbuffers_guide_use_lobster)
+</div>
+<div class="language-rust">
+[Use in Rust](@ref flatbuffers_guide_use_rust)
+</div>
+
+<br>
diff --git a/third_party/flatbuffers/docs/source/TypeScriptUsage.md b/third_party/flatbuffers/docs/source/TypeScriptUsage.md
new file mode 100644
index 0000000..02aa239
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/TypeScriptUsage.md
@@ -0,0 +1,66 @@
+Use in TypeScript    {#flatbuffers_guide_use_typescript}
+=================
+
+## Before you get started
+
+Before diving into the FlatBuffers usage in TypeScript, it should be noted that
+the [Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide to
+general FlatBuffers usage in all of the supported languages
+(including TypeScript). This page is specifically designed to cover the nuances
+of FlatBuffers usage in TypeScript.
+
+You should also have read the [Building](@ref flatbuffers_guide_building)
+documentation to build `flatc` and should be familiar with
+[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) and
+[Writing a schema](@ref flatbuffers_guide_writing_schema).
+
+## FlatBuffers TypeScript library code location
+
+The code for the FlatBuffers TypeScript library can be found at
+`flatbuffers/js` with typings available at `@types/flatbuffers`.
+
+## Testing the FlatBuffers TypeScript library
+
+To run the tests, use the [TypeScriptTest.sh](https://github.com/google/
+flatbuffers/blob/master/tests/TypeScriptTest.sh) shell script.
+
+*Note: The TypeScript test file requires [Node.js](https://nodejs.org/en/).*
+
+## Using the FlatBuffers TypeScript libary
+
+*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
+example of how to use FlatBuffers in TypeScript.*
+
+FlatBuffers supports both reading and writing FlatBuffers in TypeScript.
+
+To use FlatBuffers in your own code, first generate TypeScript classes from your
+schema with the `--ts` option to `flatc`. Then you can include both FlatBuffers
+and the generated code to read or write a FlatBuffer.
+
+For example, here is how you would read a FlatBuffer binary file in TypeScript:
+First, include the library and generated code. Then read the file into an
+`Uint8Array`. Make a `flatbuffers.ByteBuffer` out of the `Uint8Array`, and pass
+the ByteBuffer to the `getRootAsMonster` function.
+
+~~~{.ts}
+  // note: import flatbuffers with your desired import method
+
+  import { MyGame } from './monster_generated';
+
+  let data = new Uint8Array(fs.readFileSync('monster.dat'));
+  let buf = new flatbuffers.ByteBuffer(data);
+
+  let monster = MyGame.Example.Monster.getRootAsMonster(buf);
+~~~
+
+Now you can access values like this:
+
+~~~{.ts}
+  let hp = monster.hp();
+  let pos = monster.pos();
+~~~
+
+## Text parsing FlatBuffers in TypeScript
+
+There currently is no support for parsing text (Schema's and JSON) directly
+from TypeScript.
diff --git a/third_party/flatbuffers/docs/source/WhitePaper.md b/third_party/flatbuffers/docs/source/WhitePaper.md
new file mode 100644
index 0000000..e504ada
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/WhitePaper.md
@@ -0,0 +1,128 @@
+FlatBuffers white paper    {#flatbuffers_white_paper}
+=======================
+
+This document tries to shed some light on to the "why" of FlatBuffers, a
+new serialization library.
+
+## Motivation
+
+Back in the good old days, performance was all about instructions and
+cycles. Nowadays, processing units have run so far ahead of the memory
+subsystem, that making an efficient application should start and finish
+with thinking about memory. How much you use of it. How you lay it out
+and access it. How you allocate it. When you copy it.
+
+Serialization is a pervasive activity in a lot programs, and a common
+source of memory inefficiency, with lots of temporary data structures
+needed to parse and represent data, and inefficient allocation patterns
+and locality.
+
+If it would be possible to do serialization with no temporary objects,
+no additional allocation, no copying, and good locality, this could be
+of great value. The reason serialization systems usually don't manage
+this is because it goes counter to forwards/backwards compatability, and
+platform specifics like endianness and alignment.
+
+FlatBuffers is what you get if you try anyway.
+
+In particular, FlatBuffers focus is on mobile hardware (where memory
+size and memory bandwidth is even more constrained than on desktop
+hardware), and applications that have the highest performance needs:
+games.
+
+## FlatBuffers
+
+*This is a summary of FlatBuffers functionality, with some rationale.
+A more detailed description can be found in the FlatBuffers
+documentation.*
+
+### Summary
+
+A FlatBuffer is a binary buffer containing nested objects (structs,
+tables, vectors,..) organized using offsets so that the data can be
+traversed in-place just like any pointer-based data structure. Unlike
+most in-memory data structures however, it uses strict rules of
+alignment and endianness (always little) to ensure these buffers are
+cross platform. Additionally, for objects that are tables, FlatBuffers
+provides forwards/backwards compatibility and general optionality of
+fields, to support most forms of format evolution.
+
+You define your object types in a schema, which can then be compiled to
+C++ or Java for low to zero overhead reading & writing.
+Optionally, JSON data can be dynamically parsed into buffers.
+
+### Tables
+
+Tables are the cornerstone of FlatBuffers, since format evolution is
+essential for most applications of serialization. Typically, dealing
+with format changes is something that can be done transparently during
+the parsing process of most serialization solutions out there.
+But a FlatBuffer isn't parsed before it is accessed.
+
+Tables get around this by using an extra indirection to access fields,
+through a *vtable*. Each table comes with a vtable (which may be shared
+between multiple tables with the same layout), and contains information
+where fields for this particular kind of instance of vtable are stored.
+The vtable may also indicate that the field is not present (because this
+FlatBuffer was written with an older version of the software, of simply
+because the information was not necessary for this instance, or deemed
+deprecated), in which case a default value is returned.
+
+Tables have a low overhead in memory (since vtables are small and
+shared) and in access cost (an extra indirection), but provide great
+flexibility. Tables may even cost less memory than the equivalent
+struct, since fields do not need to be stored when they are equal to
+their default.
+
+FlatBuffers additionally offers "naked" structs, which do not offer
+forwards/backwards compatibility, but can be even smaller (useful for
+very small objects that are unlikely to change, like e.g. a coordinate
+pair or a RGBA color).
+
+### Schemas
+
+While schemas reduce some generality (you can't just read any data
+without having its schema), they have a lot of upsides:
+
+-   Most information about the format can be factored into the generated
+    code, reducing memory needed to store data, and time to access it.
+
+-   The strong typing of the data definitions means less error
+    checking/handling at runtime (less can go wrong).
+
+-   A schema enables us to access a buffer without parsing.
+
+FlatBuffer schemas are fairly similar to those of the incumbent,
+Protocol Buffers, and generally should be readable to those familiar
+with the C family of languages. We chose to improve upon the features
+offered by .proto files in the following ways:
+
+-   Deprecation of fields instead of manual field id assignment.
+    Extending an object in a .proto means hunting for a free slot among
+    the numbers (preferring lower numbers since they have a more compact
+    representation). Besides being inconvenient, it also makes removing
+    fields problematic: you either have to keep them, not making it
+    obvious that this field shouldn't be read/written anymore, and still
+    generating accessors. Or you remove it, but now you risk that
+    there's still old data around that uses that field by the time
+    someone reuses that field id, with nasty consequences.
+
+-   Differentiating between tables and structs (see above). Effectively
+    all table fields are `optional`, and all struct fields are
+    `required`.
+
+-   Having a native vector type instead of `repeated`. This gives you a
+    length without having to collect all items, and in the case of
+    scalars provides for a more compact representation, and one that
+    guarantees adjacency.
+
+-   Having a native `union` type instead of using a series of `optional`
+    fields, all of which must be checked individually.
+
+-   Being able to define defaults for all scalars, instead of having to
+    deal with their optionality at each access.
+
+-   A parser that can deal with both schemas and data definitions (JSON
+    compatible) uniformly.
+
+<br>
diff --git a/third_party/flatbuffers/docs/source/doxyfile b/third_party/flatbuffers/docs/source/doxyfile
new file mode 100644
index 0000000..6ba3c10
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/doxyfile
@@ -0,0 +1,2371 @@
+# Doxyfile 1.8.5
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME           = "FlatBuffers"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER         =
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          =
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is included in
+# the documentation. The maximum height of the logo should not exceed 55 pixels
+# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo
+# to the output directory.
+
+PROJECT_LOGO           =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = ".."
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-
+# Traditional, Croatian, Czech, Danish, Dutch, English, Esperanto, Farsi,
+# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en,
+# Korean, Korean-en, Latvian, Norwegian, Macedonian, Persian, Polish,
+# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish,
+# Turkish, Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES        = NO
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH        =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH    =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF      = YES
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a
+# new page for each member. If set to NO, the documentation of a member will be
+# part of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE               = 2
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES                =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST              =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make
+# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
+# (default is Fortran), use: inc=Fortran f=C.
+#
+# Note For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING      =
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT       = YES
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by by putting a % sign in front of the word
+# or globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT       = NO  # Due to the multiple languages included in the API
+                             # reference for FlatBuffers, the Auto-links were
+                             # wrong more often than not.
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT   = NO
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC         = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES  = NO
+
+# This flag is only useful for Objective-C code. When set to YES local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO these classes will be included in the various overviews. This option has
+# no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES       = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO the members will appear in declaration order.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS        = YES
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the
+# todo list. This list is created by putting \todo commands in the
+# documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST      = NO
+
+# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the
+# test list. This list is created by putting \test commands in the
+# documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST      = NO
+
+# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST       = NO
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS       =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES the list
+# will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES        = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER    =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE            = doxygen_layout.xml
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. Do not use file names with spaces, bibtex cannot handle them. See
+# also \cite for info how to create references.
+
+CITE_BIB_FILES         =
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS               = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR      = NO
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO doxygen will only warn about wrong or incomplete parameter
+# documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE           =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces.
+# Note: If this tag is empty the current directory is searched.
+
+INPUT = "FlatBuffers.md" \
+        "Building.md" \
+        "Compiler.md" \
+        "Schemas.md" \
+        "CppUsage.md" \
+        "CUsage.md" \
+        "DartUsage.md" \
+        "GoUsage.md" \
+        "JavaCsharpUsage.md" \
+        "JavaScriptUsage.md" \
+        "TypeScriptUsage.md" \
+        "PHPUsage.md" \
+        "PythonUsage.md" \
+        "LuaUsage.md" \
+        "LobsterUsage.md" \
+        "RustUsage.md" \
+        "Support.md" \
+        "Benchmarks.md" \
+        "WhitePaper.md" \
+        "FlexBuffers.md" \
+        "Internals.md" \
+        "Grammar.md" \
+        "../../CONTRIBUTING.md" \
+        "Tutorial.md" \
+        "GoApi.md" \
+        "gRPC/CppUsage.md" \
+        "groups" \
+        "../../java/com/google/flatbuffers" \
+        "../../python/flatbuffers/builder.py" \
+        "../../js/flatbuffers.js" \
+        "../../php/FlatbufferBuilder.php" \
+        "../../net/FlatBuffers/FlatBufferBuilder.cs" \
+        "../../include/flatbuffers/flatbuffers.h" \
+        "../../go/builder.go"
+        "../../rust/flatbuffers/src/builder.rs"
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank the
+# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii,
+# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp,
+# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown,
+# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
+# *.qsf, *.as and *.js.
+
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cxx \
+                         *.cpp \
+                         *.c++ \
+                         *.java \
+                         *.ii \
+                         *.ixx \
+                         *.ipp \
+                         *.i++ \
+                         *.inl \
+                         *.idl \
+                         *.ddl \
+                         *.odl \
+                         *.h \
+                         *.hh \
+                         *.hxx \
+                         *.hpp \
+                         *.h++ \
+                         *.cs \
+                         *.d \
+                         *.php \
+                         *.php4 \
+                         *.php5 \
+                         *.phtml \
+                         *.inc \
+                         *.m \
+                         *.markdown \
+                         *.md \
+                         *.mm \
+                         *.dox \
+                         *.py \
+                         *.f90 \
+                         *.f \
+                         *.for \
+                         *.tcl \
+                         *.vhd \
+                         *.vhdl \
+                         *.ucf \
+                         *.qsf \
+                         *.as \
+                         *.js \
+                         *.go
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE                =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = *_test.py |
+                         __init__.py
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS        =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH           = "GoApi_generated.txt" "../../grpc/samples"
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS       = *.cpp *.h *.txt *.fbs
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE      = YES
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH             =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+
+INPUT_FILTER           =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS        = *.py=py_filter
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER ) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS =
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE = FlatBuffers.md
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS    = NO
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES, then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS        = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX     = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX          =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER            = ../header.html
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER            = ../footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET        =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user-
+# defined cascading style sheet that is included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefor more robust against future updates.
+# Doxygen will copy the style sheet file to the output directory. For an example
+# see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET  = style.css
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES       = "../images/fpl_logo_small.png" \
+                         "../images/ftv2mnode.png" \
+                         "../images/ftv2pnode.png"
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the stylesheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP         = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET        = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP      = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE               =
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler ( hhc.exe). If non-empty
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION           =
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated (
+# YES) or that it should be included in the master .chm file ( NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI           = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING     =
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated (
+# YES) or a normal table of contents ( NO) in the .chm file.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE               =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME   =
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS  =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS  =
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION           =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX          = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW      = YES
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH         = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using prerendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT         = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS     =
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE       =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE           = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavours of web server based searching depending on the
+# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
+# searching and an index file used by the script. When EXTERNAL_SEARCH is
+# enabled the indexing and searching needs to be provided by external tools. See
+# the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH    = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer ( doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH        = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer ( doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL       =
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE        = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID     =
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS  =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE             = a4
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. To get the times font for
+# instance you can specify
+# EXTRA_PACKAGES=times
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES         =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will
+# replace them by respectively the title of the page, the current date and time,
+# only the current date, the version number of doxygen, the project name (see
+# PROJECT_NAME), or the project number (see PROJECT_NUMBER).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER           =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER           =
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES      =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS         = YES
+
+# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE        = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES     = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE        = plain
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE    =
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE    =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a
+# validating XML parser to check the syntax of the XML files.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_SCHEMA             =
+
+# The XML_DTD tag can be used to specify a XML DTD, which can be used by a
+# validating XML parser to check the syntax of the XML files.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_DTD                =
+
+# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK       = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT         = docbook
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen
+# Definitions (see http://autogen.sf.net) file that captures the structure of
+# the code including all documentation. Note that this feature is still
+# experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING   = NO
+
+# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names
+# in the source code. If set to NO only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES the includes files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH           =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS  =
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED             =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED      =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all refrences to function-like macros that are alone on a line, have an
+# all uppercase name, and do not end with a semicolon. Such function macros are
+# typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have an unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES               =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE       =
+
+# If the ALLEXTERNALS tag is set to YES all external class will be listed in the
+# class index. If set to NO only the inherited external classes will be listed.
+# The default value is: NO.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in
+# the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS        = NO
+
+# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES         = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH            =
+
+# If set to YES, the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
+
+HAVE_DOT               = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS        = 0
+
+# When you want a differently looking font n the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH           =
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK               = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH          = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot.
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, jpg, gif and svg.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT       = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG        = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH               =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS           =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS           =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP            = YES
diff --git a/third_party/flatbuffers/docs/source/doxygen_layout.xml b/third_party/flatbuffers/docs/source/doxygen_layout.xml
new file mode 100644
index 0000000..a232507
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/doxygen_layout.xml
@@ -0,0 +1,248 @@
+<!-- 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.
+ -->
+<doxygenlayout version="1.0">
+  <navindex>
+    <tab type="mainpage" visible="no" title=""/>
+    <tab type="usergroup" url="" title="Programmer's Guide">
+      <tab type="user" url="@ref flatbuffers_guide_building"
+          title="Building"/>
+      <tab type="user" url="@ref flatbuffers_guide_tutorial" title="Tutorial"/>
+      <tab type="user" url="@ref flatbuffers_guide_using_schema_compiler"
+          title="Using the schema compiler"/>
+      <tab type="user" url="@ref flatbuffers_guide_writing_schema"
+          title="Writing a schema"/>
+      <tab type="user" url="@ref flatbuffers_guide_use_cpp"
+          title="Use in C++"/>
+      <tab type="user" url="@ref flatbuffers_guide_use_c"
+          title="Use in C"/>
+      <tab type="user" url="@ref flatbuffers_guide_use_go"
+          title="Use in Go"/>
+      <tab type="user" url="@ref flatbuffers_guide_use_java_c-sharp"
+          title="Use in Java/C#"/>
+      <tab type="user" url="@ref flatbuffers_guide_use_javascript"
+          title="Use in JavaScript"/>
+      <tab type="user" url="@ref flatbuffers_guide_use_typescript"
+          title="Use in TypeScript"/>
+      <tab type="user" url="@ref flatbuffers_guide_use_php"
+          title="Use in PHP"/>
+      <tab type="user" url="@ref flatbuffers_guide_use_python"
+          title="Use in Python"/>
+      <tab type="user" url="@ref flatbuffers_guide_use_dart"
+          title="Use in Dart"/>
+      <tab type="user" url="@ref flatbuffers_guide_use_lua"
+          title="Use in Lua"/>
+      <tab type="user" url="@ref flatbuffers_guide_use_lobster"
+          title="Use in Lobster"/>
+      <tab type="user" url="@ref flatbuffers_guide_use_rust"
+          title="Use in Rust"/>
+      <tab type="user" url="@ref flexbuffers"
+          title="Schema-less version"/>
+      <tab type="usergroup" url="" title="gRPC">
+        <tab type="user" url="@ref flatbuffers_grpc_guide_use_cpp"
+            title="Use in C++"/>
+      </tab>
+    </tab>
+    <tab type="user" url="@ref flatbuffers_support"
+        title="Platform / Language / Feature support"/>
+    <tab type="user" url="@ref flatbuffers_benchmarks"
+        title="Benchmarks"/>
+    <tab type="user" url="@ref flatbuffers_white_paper"
+        title="FlatBuffers white paper"/>
+    <tab type="user" url="@ref flatbuffers_internals"
+        title="FlatBuffers internals"/>
+    <tab type="user" url="@ref flatbuffers_grammar"
+        title="Grammar of the schema language"/>
+    <tab type="usergroup" url="" title="API Reference">
+      <tab type="modules" visible="yes" title="APIs" intro=""/>
+      <tab type="classes" visible="yes" title="">
+        <tab type="classlist" visible="yes" title="" intro=""/>
+        <tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
+        <tab type="hierarchy" visible="yes" title="" intro=""/>
+        <tab type="classmembers" visible="yes" title="" intro=""/>
+      </tab>
+    </tab>
+    <tab type="user" url="@ref contributing" title="Contributing"/>
+  </navindex>
+
+  <!-- Layout definition for a class page -->
+  <class>
+    <briefdescription visible="yes"/>
+    <includes visible="$SHOW_INCLUDE_FILES"/>
+    <inheritancegraph visible="$CLASS_GRAPH"/>
+    <collaborationgraph visible="$COLLABORATION_GRAPH"/>
+    <detaileddescription title=""/>
+    <memberdecl>
+      <nestedclasses visible="yes" title=""/>
+      <publictypes title=""/>
+      <services title=""/>
+      <interfaces title=""/>
+      <publicslots title=""/>
+      <signals title=""/>
+      <publicmethods title=""/>
+      <publicstaticmethods title=""/>
+      <publicattributes title=""/>
+      <publicstaticattributes title=""/>
+      <protectedtypes title=""/>
+      <protectedslots title=""/>
+      <protectedmethods title=""/>
+      <protectedstaticmethods title=""/>
+      <protectedattributes title=""/>
+      <protectedstaticattributes title=""/>
+      <packagetypes title=""/>
+      <packagemethods title=""/>
+      <packagestaticmethods title=""/>
+      <packageattributes title=""/>
+      <packagestaticattributes title=""/>
+      <properties title=""/>
+      <events title=""/>
+      <privatetypes title=""/>
+      <privateslots title=""/>
+      <privatemethods title=""/>
+      <privatestaticmethods title=""/>
+      <privateattributes title=""/>
+      <privatestaticattributes title=""/>
+      <friends title=""/>
+      <related title="" subtitle=""/>
+      <membergroups visible="yes"/>
+    </memberdecl>
+    <memberdef>
+      <inlineclasses title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <services title=""/>
+      <interfaces title=""/>
+      <constructors title=""/>
+      <functions title=""/>
+      <related title=""/>
+      <variables title=""/>
+      <properties title=""/>
+      <events title=""/>
+    </memberdef>
+    <allmemberslink visible="yes"/>
+    <usedfiles visible="$SHOW_USED_FILES"/>
+    <authorsection visible="yes"/>
+  </class>
+
+  <!-- Layout definition for a namespace page -->
+  <namespace>
+    <briefdescription visible="yes"/>
+    <memberdecl>
+      <nestednamespaces visible="yes" title=""/>
+      <constantgroups visible="yes" title=""/>
+      <classes visible="yes" title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <functions title=""/>
+      <variables title=""/>
+      <membergroups visible="yes"/>
+    </memberdecl>
+    <detaileddescription title=""/>
+    <memberdef>
+      <inlineclasses title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <functions title=""/>
+      <variables title=""/>
+    </memberdef>
+    <authorsection visible="yes"/>
+  </namespace>
+
+  <!-- Layout definition for a file page -->
+  <file>
+    <briefdescription visible="yes"/>
+    <includes visible="$SHOW_INCLUDE_FILES"/>
+    <includegraph visible="$INCLUDE_GRAPH"/>
+    <includedbygraph visible="$INCLUDED_BY_GRAPH"/>
+    <sourcelink visible="yes"/>
+    <detaileddescription title=""/>
+    <memberdecl>
+      <classes visible="yes" title=""/>
+      <namespaces visible="yes" title=""/>
+      <constantgroups visible="yes" title=""/>
+      <defines title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <functions title=""/>
+      <variables title=""/>
+      <membergroups visible="yes"/>
+    </memberdecl>
+    <memberdef>
+      <inlineclasses title=""/>
+      <defines title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <functions title=""/>
+      <variables title=""/>
+    </memberdef>
+    <authorsection/>
+  </file>
+
+  <!-- Layout definition for a group page -->
+  <group>
+    <briefdescription visible="yes"/>
+    <groupgraph visible="$GROUP_GRAPHS"/>
+    <detaileddescription title=""/>
+    <memberdecl>
+      <nestedgroups visible="yes" title=""/>
+      <dirs visible="yes" title=""/>
+      <files visible="yes" title=""/>
+      <namespaces visible="yes" title=""/>
+      <classes visible="yes" title=""/>
+      <defines title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <enumvalues title=""/>
+      <functions title=""/>
+      <variables title=""/>
+      <signals title=""/>
+      <publicslots title=""/>
+      <protectedslots title=""/>
+      <privateslots title=""/>
+      <events title=""/>
+      <properties title=""/>
+      <friends title=""/>
+      <membergroups visible="yes"/>
+    </memberdecl>
+    <memberdef>
+      <pagedocs/>
+      <inlineclasses title=""/>
+      <defines title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <enumvalues title=""/>
+      <functions title=""/>
+      <variables title=""/>
+      <signals title=""/>
+      <publicslots title=""/>
+      <protectedslots title=""/>
+      <privateslots title=""/>
+      <events title=""/>
+      <properties title=""/>
+      <friends title=""/>
+    </memberdef>
+    <authorsection visible="yes"/>
+  </group>
+
+  <!-- Layout definition for a directory page -->
+  <directory>
+    <briefdescription visible="yes"/>
+    <directorygraph visible="yes"/>
+    <memberdecl>
+      <dirs visible="yes"/>
+      <files visible="yes"/>
+    </memberdecl>
+    <detaileddescription title=""/>
+  </directory>
+</doxygenlayout>
diff --git a/third_party/flatbuffers/docs/source/gRPC/CppUsage.md b/third_party/flatbuffers/docs/source/gRPC/CppUsage.md
new file mode 100644
index 0000000..93dbb29
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/gRPC/CppUsage.md
@@ -0,0 +1,29 @@
+Use in C++    {#flatbuffers_grpc_guide_use_cpp}
+==========
+
+## Before you get started
+
+Before diving into the FlatBuffers gRPC usage in C++, you should already be
+familiar with the following:
+
+- FlatBuffers as a serialization format
+- [gRPC](http://www.grpc.io/docs/) usage
+
+## Using the FlatBuffers gRPC C++ library
+
+NOTE: The examples below are also in the `grpc/samples/greeter` directory.
+
+We will illustrate usage with the following schema:
+
+@include grpc/samples/greeter/greeter.fbs
+
+When we run `flatc`, we pass in the `--grpc` option and generage an additional
+`greeter.grpc.fb.h` and `greeter.grpc.fb.cc`.
+
+Example server code looks like this:
+
+@include grpc/samples/greeter/server.cpp
+
+Example client code looks like this:
+
+@include grpc/samples/greeter/client.cpp
diff --git a/third_party/flatbuffers/docs/source/groups b/third_party/flatbuffers/docs/source/groups
new file mode 100644
index 0000000..c3aea18
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/groups
@@ -0,0 +1,23 @@
+/// @defgroup flatbuffers_cpp_api C++ API
+/// @brief FlatBuffers API for C++
+
+/// @defgroup flatbuffers_csharp_api C# API
+/// @brief FlatBuffers API for C#
+
+/// @defgroup flatbuffers_go_api Go API
+/// @brief FlatBuffers API for Go
+
+/// @defgroup flatbuffers_java_api Java API
+/// @brief FlatBuffers API for Java
+
+/// @defgroup flatbuffers_javascript_api JavaScript API
+/// @brief FlatBuffers API for JavaScript
+
+/// @defgroup flatbuffers_typescript_api TypeScript API
+/// @brief FlatBuffers API for TypeScript
+
+/// @defgroup flatbuffers_php_api PHP API
+/// @brief FlatBuffers API for PHP
+
+/// @defgroup flatbuffers_python_api Python API
+/// @brief FlatBuffers API for Python
diff --git a/third_party/flatbuffers/docs/source/style.css b/third_party/flatbuffers/docs/source/style.css
new file mode 100644
index 0000000..6045a97
--- /dev/null
+++ b/third_party/flatbuffers/docs/source/style.css
@@ -0,0 +1,396 @@
+body,
+#projectname,
+table,
+div,
+p,
+dl,
+.title,
+.tabs,
+.tabs2,
+.tabs3,
+#nav-tree .label {
+  font-family: roboto, sans-serif;
+}
+
+#commonprojectlogo {
+  padding: 5px 0px 5px 15px;
+}
+
+#projectname {
+  color: #00bcd4;
+  font-size: 280%;
+  padding: 15px 0px;
+  font-weight: 300;
+}
+
+#titlearea {
+  border-bottom: 2px solid #e5e5e5;
+}
+
+.title {
+  color: #212121;
+  font: 300 34px/40px Roboto,sans-serif;
+}
+
+#nav-tree {
+  background-color: #fff;
+}
+
+#navrow1, #navrow2 {
+  border-bottom: 2px solid #e7e7e7;
+}
+
+.tabs, .tabs2, .tabs3 {
+  font-size: 14px;
+}
+
+.tabs,
+.tabs2,
+.tabs3,
+.tablist li,
+.tablist li.current a {
+  background-image: none;
+}
+
+.tablist {
+  list-style: none;
+}
+
+.tablist li, .tablist li p {
+  margin: 0;
+}
+
+.tablist li a,
+.tablist li.current a {
+  color: #757575;
+  text-shadow: none;
+}
+
+.tablist li.current a {
+  background: #00bcd4;
+  color: #fff;
+}
+
+.tablist a {
+  background-image: none;
+  border-right: 2px solid #e5e5e5;
+  font-weight: normal;
+}
+
+.tablist a:hover,
+.tablist li.current a:hover {
+  background-image: none;
+  text-decoration: underline;
+  text-shadow: none;
+}
+
+.tablist a:hover {
+  color: #00bcd4;
+}
+
+.tablist li.current a:hover {
+  color: #fff;
+}
+
+div.header {
+  background-color: #f7f7f7;
+  background-image: none;
+  border-bottom: none;
+}
+
+#MSearchBox {
+  border: 1px solid #ccc;
+  border-radius: 5px;
+  display: inline-block;
+  height: 20px;
+  right: 10px;
+}
+
+#MSearchBox .left,
+#MSearchBox .right,
+#MSearchField {
+  background: none;
+}
+
+a.SelectItem:hover {
+  background-color: #00bcd4;
+}
+
+#nav-tree {
+  background-image: none;
+}
+
+#nav-tree .selected {
+  background-image: none;
+  text-shadow: none;
+  background-color: #f7f7f7;
+}
+
+#nav-tree a {
+  color: #212121;
+}
+
+#nav-tree .selected a {
+  color: #0288d1;
+}
+
+#nav-tree .item:hover {
+  background-color: #f7f7f7;
+}
+
+#nav-tree .item:hover a {
+  color: #0288d1;
+}
+
+#nav-tree .label {
+  font-size: 13px;
+}
+
+#nav-sync {
+  display: none;
+}
+
+.ui-resizable-e {
+  background: #ebebeb;
+  border-left: 1px solid #ddd;
+  border-right: 1px solid #ddd;
+}
+
+.contents tr td .image {
+  margin-top: 24px;
+}
+
+.image {
+  text-align: left;
+  margin-bottom: 8px;
+}
+
+a:link,
+a:visited,
+.contents a:link,
+.contents a:visited,
+a.el {
+  color: #0288d1;
+  font-weight: normal;
+  text-decoration: none;
+}
+
+div.contents {
+  margin-right: 12px;
+}
+
+.directory tr, .directory tr.even {
+  background: #7cb342;
+  border-top: 1px solid #7cb342;
+}
+
+.directory td,
+.directory td.entry,
+.directory td.desc {
+  background: rgba(255,255,255,.95);
+  border-left: none;
+  color: #212121;
+  padding-top: 10px;
+  padding-bottom: 10px;
+  padding-left: 8px;
+  padding-right: 8px;
+}
+
+.directory tr#row_0_ {
+  border-top-color: #7cb342;
+}
+
+.directory tr#row_0_ td {
+  background: #7cb342;
+  color: #fff;
+  font-size: 18px;
+}
+
+.memSeparator {
+  border-bottom: none;
+}
+
+.memitem {
+  background: #7cb342;
+}
+
+.memproto, dl.reflist dt {
+  background: #7cb342;
+  background-image: none;
+  border: none;
+  box-shadow: none;
+  -webkit-box-shadow: none;
+  color: #fff;
+  text-shadow: none;
+}
+
+.memproto .memtemplate,
+.memproto a.el,
+.memproto .paramname {
+  color: #fff;
+}
+
+.memdoc, dl.reflist dd {
+  border: none;
+  background-color: rgba(255,255,255,.95);
+  background-image: none;
+  box-shadow: none;
+  -webkit-box-shadow: none;
+  -webkit-border-bottom-left-radius: 0;
+  -webkit-border-bottom-right-radius: 0;
+}
+
+.memitem, table.doxtable, table.memberdecls {
+  margin-bottom: 24px;
+}
+
+table.doxtable th {
+  background: #7cb342;
+}
+
+table.doxtable tr {
+  background: #7cb342;
+  border-top: 1px solid #7cb342;
+}
+
+table.doxtable td, table.doxtable th {
+  border: none;
+  padding: 10px 8px;
+}
+
+table.doxtable td {
+  background-color: rgba(255,255,255,.95);
+}
+
+.memberdecls {
+  background: #7cb342;
+  border-top: 1px solid #7cb342;
+}
+
+.memberdecls .heading h2 {
+  border-bottom: none;
+  color: #fff;
+  font-size: 110%;
+  font-weight: bold;
+  margin: 0 0 0 6px;
+}
+
+.memberdecls tr:not(.heading) td {
+  background-color: rgba(255,255,255,.95);
+}
+
+h1, h2, h2.groupheader, h3, h4, h5, h6 {
+  color: #212121;
+}
+
+h1 {
+  border-bottom: 1px solid #ebebeb;
+  font: 400 28px/32px Roboto,sans-serif;
+  letter-spacing: -.01em;
+  margin: 40px 0 20px;
+  padding-bottom: 3px;
+}
+
+h2, h2.groupheader {
+  border-bottom: 1px solid #ebebeb;
+  font: 400 23px/32px Roboto,sans-serif;
+  letter-spacing: -.01em;
+  margin: 40px 0 20px;
+  padding-bottom: 3px;
+}
+
+h3 {
+  font: 500 20px/32px Roboto,sans-serif;
+  margin: 32px 0 16px;
+}
+
+h4 {
+  font: 500 18px/32px Roboto,sans-serif;
+  margin: 32px 0 16px;
+}
+
+ol,
+ul {
+  margin: 0;
+  padding-left: 40px;
+}
+
+ol {
+  list-style: decimal outside;
+}
+
+ol ol {
+  list-style-type: lower-alpha;
+}
+
+ol ol ol {
+  list-style-type: lower-roman;
+}
+
+ul {
+  list-style: disc outside;
+}
+
+li,
+li p {
+  margin: 8px 0;
+  padding: 0;
+}
+
+div.summary
+{
+  float: none;
+  font-size: 8pt;
+  padding-left: 5px;
+  width: calc(100% - 10px);
+  text-align: left;
+  display: block;
+}
+
+div.ingroups {
+  margin-top: 8px;
+}
+
+div.fragment {
+  border: 1px solid #ddd;
+  color: #455a64;
+  font: 14px/20px Roboto Mono, monospace;
+  padding: 8px;
+}
+
+div.line {
+  line-height: 1.5;
+  font-size: inherit;
+}
+
+code, pre {
+  color: #455a64;
+  background: #f7f7f7;
+  font: 400 100% Roboto Mono,monospace;
+  padding: 1px 4px;
+}
+
+span.preprocessor, span.comment {
+  color: #0b8043;
+}
+
+span.keywordtype {
+  color: #0097a7;
+}
+
+.paramname {
+  color: #ef6c00;
+}
+
+.memTemplParams {
+  color: #ef6c00;
+}
+
+span.mlabel {
+  background: rgba(255,255,255,.25);
+  border: none;
+}
+
+blockquote {
+  border: 1px solid #ddd;
+}
diff --git a/third_party/flatbuffers/go/BUILD.bazel b/third_party/flatbuffers/go/BUILD.bazel
new file mode 100644
index 0000000..78bd8d8
--- /dev/null
+++ b/third_party/flatbuffers/go/BUILD.bazel
@@ -0,0 +1,23 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+alias(
+    name = "go_default_library",
+    actual = ":go",
+    visibility = ["//visibility:public"],
+)
+
+go_library(
+    name = "go",
+    srcs = [
+        "builder.go",
+        "doc.go",
+        "encode.go",
+        "grpc.go",
+        "lib.go",
+        "sizes.go",
+        "struct.go",
+        "table.go",
+    ],
+    importpath = "github.com/google/flatbuffers/go",
+    visibility = ["//visibility:public"],
+)
diff --git a/third_party/flatbuffers/go/builder.go b/third_party/flatbuffers/go/builder.go
new file mode 100644
index 0000000..8d75700
--- /dev/null
+++ b/third_party/flatbuffers/go/builder.go
@@ -0,0 +1,771 @@
+package flatbuffers
+
+// Builder is a state machine for creating FlatBuffer objects.
+// Use a Builder to construct object(s) starting from leaf nodes.
+//
+// A Builder constructs byte buffers in a last-first manner for simplicity and
+// performance.
+type Builder struct {
+	// `Bytes` gives raw access to the buffer. Most users will want to use
+	// FinishedBytes() instead.
+	Bytes []byte
+
+	minalign  int
+	vtable    []UOffsetT
+	objectEnd UOffsetT
+	vtables   []UOffsetT
+	head      UOffsetT
+	nested    bool
+	finished  bool
+}
+
+const fileIdentifierLength = 4
+
+// NewBuilder initializes a Builder of size `initial_size`.
+// The internal buffer is grown as needed.
+func NewBuilder(initialSize int) *Builder {
+	if initialSize <= 0 {
+		initialSize = 0
+	}
+
+	b := &Builder{}
+	b.Bytes = make([]byte, initialSize)
+	b.head = UOffsetT(initialSize)
+	b.minalign = 1
+	b.vtables = make([]UOffsetT, 0, 16) // sensible default capacity
+
+	return b
+}
+
+// Reset truncates the underlying Builder buffer, facilitating alloc-free
+// reuse of a Builder. It also resets bookkeeping data.
+func (b *Builder) Reset() {
+	if b.Bytes != nil {
+		b.Bytes = b.Bytes[:cap(b.Bytes)]
+	}
+
+	if b.vtables != nil {
+		b.vtables = b.vtables[:0]
+	}
+
+	if b.vtable != nil {
+		b.vtable = b.vtable[:0]
+	}
+
+	b.head = UOffsetT(len(b.Bytes))
+	b.minalign = 1
+	b.nested = false
+	b.finished = false
+}
+
+// FinishedBytes returns a pointer to the written data in the byte buffer.
+// Panics if the builder is not in a finished state (which is caused by calling
+// `Finish()`).
+func (b *Builder) FinishedBytes() []byte {
+	b.assertFinished()
+	return b.Bytes[b.Head():]
+}
+
+// StartObject initializes bookkeeping for writing a new object.
+func (b *Builder) StartObject(numfields int) {
+	b.assertNotNested()
+	b.nested = true
+
+	// use 32-bit offsets so that arithmetic doesn't overflow.
+	if cap(b.vtable) < numfields || b.vtable == nil {
+		b.vtable = make([]UOffsetT, numfields)
+	} else {
+		b.vtable = b.vtable[:numfields]
+		for i := 0; i < len(b.vtable); i++ {
+			b.vtable[i] = 0
+		}
+	}
+
+	b.objectEnd = b.Offset()
+}
+
+// WriteVtable serializes the vtable for the current object, if applicable.
+//
+// Before writing out the vtable, this checks pre-existing vtables for equality
+// to this one. If an equal vtable is found, point the object to the existing
+// vtable and return.
+//
+// Because vtable values are sensitive to alignment of object data, not all
+// logically-equal vtables will be deduplicated.
+//
+// A vtable has the following format:
+//   <VOffsetT: size of the vtable in bytes, including this value>
+//   <VOffsetT: size of the object in bytes, including the vtable offset>
+//   <VOffsetT: offset for a field> * N, where N is the number of fields in
+//	        the schema for this type. Includes deprecated fields.
+// Thus, a vtable is made of 2 + N elements, each SizeVOffsetT bytes wide.
+//
+// An object has the following format:
+//   <SOffsetT: offset to this object's vtable (may be negative)>
+//   <byte: data>+
+func (b *Builder) WriteVtable() (n UOffsetT) {
+	// Prepend a zero scalar to the object. Later in this function we'll
+	// write an offset here that points to the object's vtable:
+	b.PrependSOffsetT(0)
+
+	objectOffset := b.Offset()
+	existingVtable := UOffsetT(0)
+
+	// Trim vtable of trailing zeroes.
+	i := len(b.vtable) - 1
+	for ; i >= 0 && b.vtable[i] == 0; i-- {
+	}
+	b.vtable = b.vtable[:i+1]
+
+	// Search backwards through existing vtables, because similar vtables
+	// are likely to have been recently appended. See
+	// BenchmarkVtableDeduplication for a case in which this heuristic
+	// saves about 30% of the time used in writing objects with duplicate
+	// tables.
+	for i := len(b.vtables) - 1; i >= 0; i-- {
+		// Find the other vtable, which is associated with `i`:
+		vt2Offset := b.vtables[i]
+		vt2Start := len(b.Bytes) - int(vt2Offset)
+		vt2Len := GetVOffsetT(b.Bytes[vt2Start:])
+
+		metadata := VtableMetadataFields * SizeVOffsetT
+		vt2End := vt2Start + int(vt2Len)
+		vt2 := b.Bytes[vt2Start+metadata : vt2End]
+
+		// Compare the other vtable to the one under consideration.
+		// If they are equal, store the offset and break:
+		if vtableEqual(b.vtable, objectOffset, vt2) {
+			existingVtable = vt2Offset
+			break
+		}
+	}
+
+	if existingVtable == 0 {
+		// Did not find a vtable, so write this one to the buffer.
+
+		// Write out the current vtable in reverse , because
+		// serialization occurs in last-first order:
+		for i := len(b.vtable) - 1; i >= 0; i-- {
+			var off UOffsetT
+			if b.vtable[i] != 0 {
+				// Forward reference to field;
+				// use 32bit number to assert no overflow:
+				off = objectOffset - b.vtable[i]
+			}
+
+			b.PrependVOffsetT(VOffsetT(off))
+		}
+
+		// The two metadata fields are written last.
+
+		// First, store the object bytesize:
+		objectSize := objectOffset - b.objectEnd
+		b.PrependVOffsetT(VOffsetT(objectSize))
+
+		// Second, store the vtable bytesize:
+		vBytes := (len(b.vtable) + VtableMetadataFields) * SizeVOffsetT
+		b.PrependVOffsetT(VOffsetT(vBytes))
+
+		// Next, write the offset to the new vtable in the
+		// already-allocated SOffsetT at the beginning of this object:
+		objectStart := SOffsetT(len(b.Bytes)) - SOffsetT(objectOffset)
+		WriteSOffsetT(b.Bytes[objectStart:],
+			SOffsetT(b.Offset())-SOffsetT(objectOffset))
+
+		// Finally, store this vtable in memory for future
+		// deduplication:
+		b.vtables = append(b.vtables, b.Offset())
+	} else {
+		// Found a duplicate vtable.
+
+		objectStart := SOffsetT(len(b.Bytes)) - SOffsetT(objectOffset)
+		b.head = UOffsetT(objectStart)
+
+		// Write the offset to the found vtable in the
+		// already-allocated SOffsetT at the beginning of this object:
+		WriteSOffsetT(b.Bytes[b.head:],
+			SOffsetT(existingVtable)-SOffsetT(objectOffset))
+	}
+
+	b.vtable = b.vtable[:0]
+	return objectOffset
+}
+
+// EndObject writes data necessary to finish object construction.
+func (b *Builder) EndObject() UOffsetT {
+	b.assertNested()
+	n := b.WriteVtable()
+	b.nested = false
+	return n
+}
+
+// Doubles the size of the byteslice, and copies the old data towards the
+// end of the new byteslice (since we build the buffer backwards).
+func (b *Builder) growByteBuffer() {
+	if (int64(len(b.Bytes)) & int64(0xC0000000)) != 0 {
+		panic("cannot grow buffer beyond 2 gigabytes")
+	}
+	newLen := len(b.Bytes) * 2
+	if newLen == 0 {
+		newLen = 1
+	}
+
+	if cap(b.Bytes) >= newLen {
+		b.Bytes = b.Bytes[:newLen]
+	} else {
+		extension := make([]byte, newLen-len(b.Bytes))
+		b.Bytes = append(b.Bytes, extension...)
+	}
+
+	middle := newLen / 2
+	copy(b.Bytes[middle:], b.Bytes[:middle])
+}
+
+// Head gives the start of useful data in the underlying byte buffer.
+// Note: unlike other functions, this value is interpreted as from the left.
+func (b *Builder) Head() UOffsetT {
+	return b.head
+}
+
+// Offset relative to the end of the buffer.
+func (b *Builder) Offset() UOffsetT {
+	return UOffsetT(len(b.Bytes)) - b.head
+}
+
+// Pad places zeros at the current offset.
+func (b *Builder) Pad(n int) {
+	for i := 0; i < n; i++ {
+		b.PlaceByte(0)
+	}
+}
+
+// Prep prepares to write an element of `size` after `additional_bytes`
+// have been written, e.g. if you write a string, you need to align such
+// the int length field is aligned to SizeInt32, and the string data follows it
+// directly.
+// If all you need to do is align, `additionalBytes` will be 0.
+func (b *Builder) Prep(size, additionalBytes int) {
+	// Track the biggest thing we've ever aligned to.
+	if size > b.minalign {
+		b.minalign = size
+	}
+	// Find the amount of alignment needed such that `size` is properly
+	// aligned after `additionalBytes`:
+	alignSize := (^(len(b.Bytes) - int(b.Head()) + additionalBytes)) + 1
+	alignSize &= (size - 1)
+
+	// Reallocate the buffer if needed:
+	for int(b.head) <= alignSize+size+additionalBytes {
+		oldBufSize := len(b.Bytes)
+		b.growByteBuffer()
+		b.head += UOffsetT(len(b.Bytes) - oldBufSize)
+	}
+	b.Pad(alignSize)
+}
+
+// PrependSOffsetT prepends an SOffsetT, relative to where it will be written.
+func (b *Builder) PrependSOffsetT(off SOffsetT) {
+	b.Prep(SizeSOffsetT, 0) // Ensure alignment is already done.
+	if !(UOffsetT(off) <= b.Offset()) {
+		panic("unreachable: off <= b.Offset()")
+	}
+	off2 := SOffsetT(b.Offset()) - off + SOffsetT(SizeSOffsetT)
+	b.PlaceSOffsetT(off2)
+}
+
+// PrependUOffsetT prepends an UOffsetT, relative to where it will be written.
+func (b *Builder) PrependUOffsetT(off UOffsetT) {
+	b.Prep(SizeUOffsetT, 0) // Ensure alignment is already done.
+	if !(off <= b.Offset()) {
+		panic("unreachable: off <= b.Offset()")
+	}
+	off2 := b.Offset() - off + UOffsetT(SizeUOffsetT)
+	b.PlaceUOffsetT(off2)
+}
+
+// StartVector initializes bookkeeping for writing a new vector.
+//
+// A vector has the following format:
+//   <UOffsetT: number of elements in this vector>
+//   <T: data>+, where T is the type of elements of this vector.
+func (b *Builder) StartVector(elemSize, numElems, alignment int) UOffsetT {
+	b.assertNotNested()
+	b.nested = true
+	b.Prep(SizeUint32, elemSize*numElems)
+	b.Prep(alignment, elemSize*numElems) // Just in case alignment > int.
+	return b.Offset()
+}
+
+// EndVector writes data necessary to finish vector construction.
+func (b *Builder) EndVector(vectorNumElems int) UOffsetT {
+	b.assertNested()
+
+	// we already made space for this, so write without PrependUint32
+	b.PlaceUOffsetT(UOffsetT(vectorNumElems))
+
+	b.nested = false
+	return b.Offset()
+}
+
+// CreateString writes a null-terminated string as a vector.
+func (b *Builder) CreateString(s string) UOffsetT {
+	b.assertNotNested()
+	b.nested = true
+
+	b.Prep(int(SizeUOffsetT), (len(s)+1)*SizeByte)
+	b.PlaceByte(0)
+
+	l := UOffsetT(len(s))
+
+	b.head -= l
+	copy(b.Bytes[b.head:b.head+l], s)
+
+	return b.EndVector(len(s))
+}
+
+// CreateByteString writes a byte slice as a string (null-terminated).
+func (b *Builder) CreateByteString(s []byte) UOffsetT {
+	b.assertNotNested()
+	b.nested = true
+
+	b.Prep(int(SizeUOffsetT), (len(s)+1)*SizeByte)
+	b.PlaceByte(0)
+
+	l := UOffsetT(len(s))
+
+	b.head -= l
+	copy(b.Bytes[b.head:b.head+l], s)
+
+	return b.EndVector(len(s))
+}
+
+// CreateByteVector writes a ubyte vector
+func (b *Builder) CreateByteVector(v []byte) UOffsetT {
+	b.assertNotNested()
+	b.nested = true
+
+	b.Prep(int(SizeUOffsetT), len(v)*SizeByte)
+
+	l := UOffsetT(len(v))
+
+	b.head -= l
+	copy(b.Bytes[b.head:b.head+l], v)
+
+	return b.EndVector(len(v))
+}
+
+func (b *Builder) assertNested() {
+	// If you get this assert, you're in an object while trying to write
+	// data that belongs outside of an object.
+	// To fix this, write non-inline data (like vectors) before creating
+	// objects.
+	if !b.nested {
+		panic("Incorrect creation order: must be inside object.")
+	}
+}
+
+func (b *Builder) assertNotNested() {
+	// If you hit this, you're trying to construct a Table/Vector/String
+	// during the construction of its parent table (between the MyTableBuilder
+	// and builder.Finish()).
+	// Move the creation of these sub-objects to above the MyTableBuilder to
+	// not get this assert.
+	// Ignoring this assert may appear to work in simple cases, but the reason
+	// it is here is that storing objects in-line may cause vtable offsets
+	// to not fit anymore. It also leads to vtable duplication.
+	if b.nested {
+		panic("Incorrect creation order: object must not be nested.")
+	}
+}
+
+func (b *Builder) assertFinished() {
+	// If you get this assert, you're attempting to get access a buffer
+	// which hasn't been finished yet. Be sure to call builder.Finish()
+	// with your root table.
+	// If you really need to access an unfinished buffer, use the Bytes
+	// buffer directly.
+	if !b.finished {
+		panic("Incorrect use of FinishedBytes(): must call 'Finish' first.")
+	}
+}
+
+// PrependBoolSlot prepends a bool onto the object at vtable slot `o`.
+// If value `x` equals default `d`, then the slot will be set to zero and no
+// other data will be written.
+func (b *Builder) PrependBoolSlot(o int, x, d bool) {
+	val := byte(0)
+	if x {
+		val = 1
+	}
+	def := byte(0)
+	if d {
+		def = 1
+	}
+	b.PrependByteSlot(o, val, def)
+}
+
+// PrependByteSlot prepends a byte onto the object at vtable slot `o`.
+// If value `x` equals default `d`, then the slot will be set to zero and no
+// other data will be written.
+func (b *Builder) PrependByteSlot(o int, x, d byte) {
+	if x != d {
+		b.PrependByte(x)
+		b.Slot(o)
+	}
+}
+
+// PrependUint8Slot prepends a uint8 onto the object at vtable slot `o`.
+// If value `x` equals default `d`, then the slot will be set to zero and no
+// other data will be written.
+func (b *Builder) PrependUint8Slot(o int, x, d uint8) {
+	if x != d {
+		b.PrependUint8(x)
+		b.Slot(o)
+	}
+}
+
+// PrependUint16Slot prepends a uint16 onto the object at vtable slot `o`.
+// If value `x` equals default `d`, then the slot will be set to zero and no
+// other data will be written.
+func (b *Builder) PrependUint16Slot(o int, x, d uint16) {
+	if x != d {
+		b.PrependUint16(x)
+		b.Slot(o)
+	}
+}
+
+// PrependUint32Slot prepends a uint32 onto the object at vtable slot `o`.
+// If value `x` equals default `d`, then the slot will be set to zero and no
+// other data will be written.
+func (b *Builder) PrependUint32Slot(o int, x, d uint32) {
+	if x != d {
+		b.PrependUint32(x)
+		b.Slot(o)
+	}
+}
+
+// PrependUint64Slot prepends a uint64 onto the object at vtable slot `o`.
+// If value `x` equals default `d`, then the slot will be set to zero and no
+// other data will be written.
+func (b *Builder) PrependUint64Slot(o int, x, d uint64) {
+	if x != d {
+		b.PrependUint64(x)
+		b.Slot(o)
+	}
+}
+
+// PrependInt8Slot prepends a int8 onto the object at vtable slot `o`.
+// If value `x` equals default `d`, then the slot will be set to zero and no
+// other data will be written.
+func (b *Builder) PrependInt8Slot(o int, x, d int8) {
+	if x != d {
+		b.PrependInt8(x)
+		b.Slot(o)
+	}
+}
+
+// PrependInt16Slot prepends a int16 onto the object at vtable slot `o`.
+// If value `x` equals default `d`, then the slot will be set to zero and no
+// other data will be written.
+func (b *Builder) PrependInt16Slot(o int, x, d int16) {
+	if x != d {
+		b.PrependInt16(x)
+		b.Slot(o)
+	}
+}
+
+// PrependInt32Slot prepends a int32 onto the object at vtable slot `o`.
+// If value `x` equals default `d`, then the slot will be set to zero and no
+// other data will be written.
+func (b *Builder) PrependInt32Slot(o int, x, d int32) {
+	if x != d {
+		b.PrependInt32(x)
+		b.Slot(o)
+	}
+}
+
+// PrependInt64Slot prepends a int64 onto the object at vtable slot `o`.
+// If value `x` equals default `d`, then the slot will be set to zero and no
+// other data will be written.
+func (b *Builder) PrependInt64Slot(o int, x, d int64) {
+	if x != d {
+		b.PrependInt64(x)
+		b.Slot(o)
+	}
+}
+
+// PrependFloat32Slot prepends a float32 onto the object at vtable slot `o`.
+// If value `x` equals default `d`, then the slot will be set to zero and no
+// other data will be written.
+func (b *Builder) PrependFloat32Slot(o int, x, d float32) {
+	if x != d {
+		b.PrependFloat32(x)
+		b.Slot(o)
+	}
+}
+
+// PrependFloat64Slot prepends a float64 onto the object at vtable slot `o`.
+// If value `x` equals default `d`, then the slot will be set to zero and no
+// other data will be written.
+func (b *Builder) PrependFloat64Slot(o int, x, d float64) {
+	if x != d {
+		b.PrependFloat64(x)
+		b.Slot(o)
+	}
+}
+
+// PrependUOffsetTSlot prepends an UOffsetT onto the object at vtable slot `o`.
+// If value `x` equals default `d`, then the slot will be set to zero and no
+// other data will be written.
+func (b *Builder) PrependUOffsetTSlot(o int, x, d UOffsetT) {
+	if x != d {
+		b.PrependUOffsetT(x)
+		b.Slot(o)
+	}
+}
+
+// PrependStructSlot prepends a struct onto the object at vtable slot `o`.
+// Structs are stored inline, so nothing additional is being added.
+// In generated code, `d` is always 0.
+func (b *Builder) PrependStructSlot(voffset int, x, d UOffsetT) {
+	if x != d {
+		b.assertNested()
+		if x != b.Offset() {
+			panic("inline data write outside of object")
+		}
+		b.Slot(voffset)
+	}
+}
+
+// Slot sets the vtable key `voffset` to the current location in the buffer.
+func (b *Builder) Slot(slotnum int) {
+	b.vtable[slotnum] = UOffsetT(b.Offset())
+}
+
+// FinishWithFileIdentifier finalizes a buffer, pointing to the given `rootTable`.
+// as well as applys a file identifier
+func (b *Builder) FinishWithFileIdentifier(rootTable UOffsetT, fid []byte) {
+	if fid == nil || len(fid) != fileIdentifierLength {
+		panic("incorrect file identifier length")
+	}
+	// In order to add a file identifier to the flatbuffer message, we need
+	// to prepare an alignment and file identifier length
+	b.Prep(b.minalign, SizeInt32+fileIdentifierLength)
+	for i := fileIdentifierLength - 1; i >= 0; i-- {
+		// place the file identifier
+		b.PlaceByte(fid[i])
+	}
+	// finish
+	b.Finish(rootTable)
+}
+
+// Finish finalizes a buffer, pointing to the given `rootTable`.
+func (b *Builder) Finish(rootTable UOffsetT) {
+	b.assertNotNested()
+	b.Prep(b.minalign, SizeUOffsetT)
+	b.PrependUOffsetT(rootTable)
+	b.finished = true
+}
+
+// vtableEqual compares an unwritten vtable to a written vtable.
+func vtableEqual(a []UOffsetT, objectStart UOffsetT, b []byte) bool {
+	if len(a)*SizeVOffsetT != len(b) {
+		return false
+	}
+
+	for i := 0; i < len(a); i++ {
+		x := GetVOffsetT(b[i*SizeVOffsetT : (i+1)*SizeVOffsetT])
+
+		// Skip vtable entries that indicate a default value.
+		if x == 0 && a[i] == 0 {
+			continue
+		}
+
+		y := SOffsetT(objectStart) - SOffsetT(a[i])
+		if SOffsetT(x) != y {
+			return false
+		}
+	}
+	return true
+}
+
+// PrependBool prepends a bool to the Builder buffer.
+// Aligns and checks for space.
+func (b *Builder) PrependBool(x bool) {
+	b.Prep(SizeBool, 0)
+	b.PlaceBool(x)
+}
+
+// PrependUint8 prepends a uint8 to the Builder buffer.
+// Aligns and checks for space.
+func (b *Builder) PrependUint8(x uint8) {
+	b.Prep(SizeUint8, 0)
+	b.PlaceUint8(x)
+}
+
+// PrependUint16 prepends a uint16 to the Builder buffer.
+// Aligns and checks for space.
+func (b *Builder) PrependUint16(x uint16) {
+	b.Prep(SizeUint16, 0)
+	b.PlaceUint16(x)
+}
+
+// PrependUint32 prepends a uint32 to the Builder buffer.
+// Aligns and checks for space.
+func (b *Builder) PrependUint32(x uint32) {
+	b.Prep(SizeUint32, 0)
+	b.PlaceUint32(x)
+}
+
+// PrependUint64 prepends a uint64 to the Builder buffer.
+// Aligns and checks for space.
+func (b *Builder) PrependUint64(x uint64) {
+	b.Prep(SizeUint64, 0)
+	b.PlaceUint64(x)
+}
+
+// PrependInt8 prepends a int8 to the Builder buffer.
+// Aligns and checks for space.
+func (b *Builder) PrependInt8(x int8) {
+	b.Prep(SizeInt8, 0)
+	b.PlaceInt8(x)
+}
+
+// PrependInt16 prepends a int16 to the Builder buffer.
+// Aligns and checks for space.
+func (b *Builder) PrependInt16(x int16) {
+	b.Prep(SizeInt16, 0)
+	b.PlaceInt16(x)
+}
+
+// PrependInt32 prepends a int32 to the Builder buffer.
+// Aligns and checks for space.
+func (b *Builder) PrependInt32(x int32) {
+	b.Prep(SizeInt32, 0)
+	b.PlaceInt32(x)
+}
+
+// PrependInt64 prepends a int64 to the Builder buffer.
+// Aligns and checks for space.
+func (b *Builder) PrependInt64(x int64) {
+	b.Prep(SizeInt64, 0)
+	b.PlaceInt64(x)
+}
+
+// PrependFloat32 prepends a float32 to the Builder buffer.
+// Aligns and checks for space.
+func (b *Builder) PrependFloat32(x float32) {
+	b.Prep(SizeFloat32, 0)
+	b.PlaceFloat32(x)
+}
+
+// PrependFloat64 prepends a float64 to the Builder buffer.
+// Aligns and checks for space.
+func (b *Builder) PrependFloat64(x float64) {
+	b.Prep(SizeFloat64, 0)
+	b.PlaceFloat64(x)
+}
+
+// PrependByte prepends a byte to the Builder buffer.
+// Aligns and checks for space.
+func (b *Builder) PrependByte(x byte) {
+	b.Prep(SizeByte, 0)
+	b.PlaceByte(x)
+}
+
+// PrependVOffsetT prepends a VOffsetT to the Builder buffer.
+// Aligns and checks for space.
+func (b *Builder) PrependVOffsetT(x VOffsetT) {
+	b.Prep(SizeVOffsetT, 0)
+	b.PlaceVOffsetT(x)
+}
+
+// PlaceBool prepends a bool to the Builder, without checking for space.
+func (b *Builder) PlaceBool(x bool) {
+	b.head -= UOffsetT(SizeBool)
+	WriteBool(b.Bytes[b.head:], x)
+}
+
+// PlaceUint8 prepends a uint8 to the Builder, without checking for space.
+func (b *Builder) PlaceUint8(x uint8) {
+	b.head -= UOffsetT(SizeUint8)
+	WriteUint8(b.Bytes[b.head:], x)
+}
+
+// PlaceUint16 prepends a uint16 to the Builder, without checking for space.
+func (b *Builder) PlaceUint16(x uint16) {
+	b.head -= UOffsetT(SizeUint16)
+	WriteUint16(b.Bytes[b.head:], x)
+}
+
+// PlaceUint32 prepends a uint32 to the Builder, without checking for space.
+func (b *Builder) PlaceUint32(x uint32) {
+	b.head -= UOffsetT(SizeUint32)
+	WriteUint32(b.Bytes[b.head:], x)
+}
+
+// PlaceUint64 prepends a uint64 to the Builder, without checking for space.
+func (b *Builder) PlaceUint64(x uint64) {
+	b.head -= UOffsetT(SizeUint64)
+	WriteUint64(b.Bytes[b.head:], x)
+}
+
+// PlaceInt8 prepends a int8 to the Builder, without checking for space.
+func (b *Builder) PlaceInt8(x int8) {
+	b.head -= UOffsetT(SizeInt8)
+	WriteInt8(b.Bytes[b.head:], x)
+}
+
+// PlaceInt16 prepends a int16 to the Builder, without checking for space.
+func (b *Builder) PlaceInt16(x int16) {
+	b.head -= UOffsetT(SizeInt16)
+	WriteInt16(b.Bytes[b.head:], x)
+}
+
+// PlaceInt32 prepends a int32 to the Builder, without checking for space.
+func (b *Builder) PlaceInt32(x int32) {
+	b.head -= UOffsetT(SizeInt32)
+	WriteInt32(b.Bytes[b.head:], x)
+}
+
+// PlaceInt64 prepends a int64 to the Builder, without checking for space.
+func (b *Builder) PlaceInt64(x int64) {
+	b.head -= UOffsetT(SizeInt64)
+	WriteInt64(b.Bytes[b.head:], x)
+}
+
+// PlaceFloat32 prepends a float32 to the Builder, without checking for space.
+func (b *Builder) PlaceFloat32(x float32) {
+	b.head -= UOffsetT(SizeFloat32)
+	WriteFloat32(b.Bytes[b.head:], x)
+}
+
+// PlaceFloat64 prepends a float64 to the Builder, without checking for space.
+func (b *Builder) PlaceFloat64(x float64) {
+	b.head -= UOffsetT(SizeFloat64)
+	WriteFloat64(b.Bytes[b.head:], x)
+}
+
+// PlaceByte prepends a byte to the Builder, without checking for space.
+func (b *Builder) PlaceByte(x byte) {
+	b.head -= UOffsetT(SizeByte)
+	WriteByte(b.Bytes[b.head:], x)
+}
+
+// PlaceVOffsetT prepends a VOffsetT to the Builder, without checking for space.
+func (b *Builder) PlaceVOffsetT(x VOffsetT) {
+	b.head -= UOffsetT(SizeVOffsetT)
+	WriteVOffsetT(b.Bytes[b.head:], x)
+}
+
+// PlaceSOffsetT prepends a SOffsetT to the Builder, without checking for space.
+func (b *Builder) PlaceSOffsetT(x SOffsetT) {
+	b.head -= UOffsetT(SizeSOffsetT)
+	WriteSOffsetT(b.Bytes[b.head:], x)
+}
+
+// PlaceUOffsetT prepends a UOffsetT to the Builder, without checking for space.
+func (b *Builder) PlaceUOffsetT(x UOffsetT) {
+	b.head -= UOffsetT(SizeUOffsetT)
+	WriteUOffsetT(b.Bytes[b.head:], x)
+}
diff --git a/third_party/flatbuffers/go/doc.go b/third_party/flatbuffers/go/doc.go
new file mode 100644
index 0000000..694edc7
--- /dev/null
+++ b/third_party/flatbuffers/go/doc.go
@@ -0,0 +1,3 @@
+// Package flatbuffers provides facilities to read and write flatbuffers
+// objects.
+package flatbuffers
diff --git a/third_party/flatbuffers/go/encode.go b/third_party/flatbuffers/go/encode.go
new file mode 100644
index 0000000..72d4f3a
--- /dev/null
+++ b/third_party/flatbuffers/go/encode.go
@@ -0,0 +1,238 @@
+package flatbuffers
+
+import (
+	"math"
+)
+
+type (
+	// A SOffsetT stores a signed offset into arbitrary data.
+	SOffsetT int32
+	// A UOffsetT stores an unsigned offset into vector data.
+	UOffsetT uint32
+	// A VOffsetT stores an unsigned offset in a vtable.
+	VOffsetT uint16
+)
+
+const (
+	// VtableMetadataFields is the count of metadata fields in each vtable.
+	VtableMetadataFields = 2
+)
+
+// GetByte decodes a little-endian byte from a byte slice.
+func GetByte(buf []byte) byte {
+	return byte(GetUint8(buf))
+}
+
+// GetBool decodes a little-endian bool from a byte slice.
+func GetBool(buf []byte) bool {
+	return buf[0] == 1
+}
+
+// GetUint8 decodes a little-endian uint8 from a byte slice.
+func GetUint8(buf []byte) (n uint8) {
+	n = uint8(buf[0])
+	return
+}
+
+// GetUint16 decodes a little-endian uint16 from a byte slice.
+func GetUint16(buf []byte) (n uint16) {
+	_ = buf[1] // Force one bounds check. See: golang.org/issue/14808
+	n |= uint16(buf[0])
+	n |= uint16(buf[1]) << 8
+	return
+}
+
+// GetUint32 decodes a little-endian uint32 from a byte slice.
+func GetUint32(buf []byte) (n uint32) {
+	_ = buf[3] // Force one bounds check. See: golang.org/issue/14808
+	n |= uint32(buf[0])
+	n |= uint32(buf[1]) << 8
+	n |= uint32(buf[2]) << 16
+	n |= uint32(buf[3]) << 24
+	return
+}
+
+// GetUint64 decodes a little-endian uint64 from a byte slice.
+func GetUint64(buf []byte) (n uint64) {
+	_ = buf[7] // Force one bounds check. See: golang.org/issue/14808
+	n |= uint64(buf[0])
+	n |= uint64(buf[1]) << 8
+	n |= uint64(buf[2]) << 16
+	n |= uint64(buf[3]) << 24
+	n |= uint64(buf[4]) << 32
+	n |= uint64(buf[5]) << 40
+	n |= uint64(buf[6]) << 48
+	n |= uint64(buf[7]) << 56
+	return
+}
+
+// GetInt8 decodes a little-endian int8 from a byte slice.
+func GetInt8(buf []byte) (n int8) {
+	n = int8(buf[0])
+	return
+}
+
+// GetInt16 decodes a little-endian int16 from a byte slice.
+func GetInt16(buf []byte) (n int16) {
+	_ = buf[1] // Force one bounds check. See: golang.org/issue/14808
+	n |= int16(buf[0])
+	n |= int16(buf[1]) << 8
+	return
+}
+
+// GetInt32 decodes a little-endian int32 from a byte slice.
+func GetInt32(buf []byte) (n int32) {
+	_ = buf[3] // Force one bounds check. See: golang.org/issue/14808
+	n |= int32(buf[0])
+	n |= int32(buf[1]) << 8
+	n |= int32(buf[2]) << 16
+	n |= int32(buf[3]) << 24
+	return
+}
+
+// GetInt64 decodes a little-endian int64 from a byte slice.
+func GetInt64(buf []byte) (n int64) {
+	_ = buf[7] // Force one bounds check. See: golang.org/issue/14808
+	n |= int64(buf[0])
+	n |= int64(buf[1]) << 8
+	n |= int64(buf[2]) << 16
+	n |= int64(buf[3]) << 24
+	n |= int64(buf[4]) << 32
+	n |= int64(buf[5]) << 40
+	n |= int64(buf[6]) << 48
+	n |= int64(buf[7]) << 56
+	return
+}
+
+// GetFloat32 decodes a little-endian float32 from a byte slice.
+func GetFloat32(buf []byte) float32 {
+	x := GetUint32(buf)
+	return math.Float32frombits(x)
+}
+
+// GetFloat64 decodes a little-endian float64 from a byte slice.
+func GetFloat64(buf []byte) float64 {
+	x := GetUint64(buf)
+	return math.Float64frombits(x)
+}
+
+// GetUOffsetT decodes a little-endian UOffsetT from a byte slice.
+func GetUOffsetT(buf []byte) UOffsetT {
+	return UOffsetT(GetInt32(buf))
+}
+
+// GetSOffsetT decodes a little-endian SOffsetT from a byte slice.
+func GetSOffsetT(buf []byte) SOffsetT {
+	return SOffsetT(GetInt32(buf))
+}
+
+// GetVOffsetT decodes a little-endian VOffsetT from a byte slice.
+func GetVOffsetT(buf []byte) VOffsetT {
+	return VOffsetT(GetUint16(buf))
+}
+
+// WriteByte encodes a little-endian uint8 into a byte slice.
+func WriteByte(buf []byte, n byte) {
+	WriteUint8(buf, uint8(n))
+}
+
+// WriteBool encodes a little-endian bool into a byte slice.
+func WriteBool(buf []byte, b bool) {
+	buf[0] = 0
+	if b {
+		buf[0] = 1
+	}
+}
+
+// WriteUint8 encodes a little-endian uint8 into a byte slice.
+func WriteUint8(buf []byte, n uint8) {
+	buf[0] = byte(n)
+}
+
+// WriteUint16 encodes a little-endian uint16 into a byte slice.
+func WriteUint16(buf []byte, n uint16) {
+	_ = buf[1] // Force one bounds check. See: golang.org/issue/14808
+	buf[0] = byte(n)
+	buf[1] = byte(n >> 8)
+}
+
+// WriteUint32 encodes a little-endian uint32 into a byte slice.
+func WriteUint32(buf []byte, n uint32) {
+	_ = buf[3] // Force one bounds check. See: golang.org/issue/14808
+	buf[0] = byte(n)
+	buf[1] = byte(n >> 8)
+	buf[2] = byte(n >> 16)
+	buf[3] = byte(n >> 24)
+}
+
+// WriteUint64 encodes a little-endian uint64 into a byte slice.
+func WriteUint64(buf []byte, n uint64) {
+	_ = buf[7] // Force one bounds check. See: golang.org/issue/14808
+	buf[0] = byte(n)
+	buf[1] = byte(n >> 8)
+	buf[2] = byte(n >> 16)
+	buf[3] = byte(n >> 24)
+	buf[4] = byte(n >> 32)
+	buf[5] = byte(n >> 40)
+	buf[6] = byte(n >> 48)
+	buf[7] = byte(n >> 56)
+}
+
+// WriteInt8 encodes a little-endian int8 into a byte slice.
+func WriteInt8(buf []byte, n int8) {
+	buf[0] = byte(n)
+}
+
+// WriteInt16 encodes a little-endian int16 into a byte slice.
+func WriteInt16(buf []byte, n int16) {
+	_ = buf[1] // Force one bounds check. See: golang.org/issue/14808
+	buf[0] = byte(n)
+	buf[1] = byte(n >> 8)
+}
+
+// WriteInt32 encodes a little-endian int32 into a byte slice.
+func WriteInt32(buf []byte, n int32) {
+	_ = buf[3] // Force one bounds check. See: golang.org/issue/14808
+	buf[0] = byte(n)
+	buf[1] = byte(n >> 8)
+	buf[2] = byte(n >> 16)
+	buf[3] = byte(n >> 24)
+}
+
+// WriteInt64 encodes a little-endian int64 into a byte slice.
+func WriteInt64(buf []byte, n int64) {
+	_ = buf[7] // Force one bounds check. See: golang.org/issue/14808
+	buf[0] = byte(n)
+	buf[1] = byte(n >> 8)
+	buf[2] = byte(n >> 16)
+	buf[3] = byte(n >> 24)
+	buf[4] = byte(n >> 32)
+	buf[5] = byte(n >> 40)
+	buf[6] = byte(n >> 48)
+	buf[7] = byte(n >> 56)
+}
+
+// WriteFloat32 encodes a little-endian float32 into a byte slice.
+func WriteFloat32(buf []byte, n float32) {
+	WriteUint32(buf, math.Float32bits(n))
+}
+
+// WriteFloat64 encodes a little-endian float64 into a byte slice.
+func WriteFloat64(buf []byte, n float64) {
+	WriteUint64(buf, math.Float64bits(n))
+}
+
+// WriteVOffsetT encodes a little-endian VOffsetT into a byte slice.
+func WriteVOffsetT(buf []byte, n VOffsetT) {
+	WriteUint16(buf, uint16(n))
+}
+
+// WriteSOffsetT encodes a little-endian SOffsetT into a byte slice.
+func WriteSOffsetT(buf []byte, n SOffsetT) {
+	WriteInt32(buf, int32(n))
+}
+
+// WriteUOffsetT encodes a little-endian UOffsetT into a byte slice.
+func WriteUOffsetT(buf []byte, n UOffsetT) {
+	WriteUint32(buf, uint32(n))
+}
diff --git a/third_party/flatbuffers/go/grpc.go b/third_party/flatbuffers/go/grpc.go
new file mode 100644
index 0000000..e7dabd3
--- /dev/null
+++ b/third_party/flatbuffers/go/grpc.go
@@ -0,0 +1,23 @@
+package flatbuffers
+
+// Codec implements gRPC-go Codec which is used to encode and decode messages.
+var Codec = "flatbuffers"
+
+type FlatbuffersCodec struct{}
+
+func (FlatbuffersCodec) Marshal(v interface{}) ([]byte, error) {
+	return v.(*Builder).FinishedBytes(), nil
+}
+
+func (FlatbuffersCodec) Unmarshal(data []byte, v interface{}) error {
+	v.(flatbuffersInit).Init(data, GetUOffsetT(data))
+	return nil
+}
+
+func (FlatbuffersCodec) String() string {
+	return Codec
+}
+
+type flatbuffersInit interface {
+	Init(data []byte, i UOffsetT)
+}
diff --git a/third_party/flatbuffers/go/lib.go b/third_party/flatbuffers/go/lib.go
new file mode 100644
index 0000000..adfce52
--- /dev/null
+++ b/third_party/flatbuffers/go/lib.go
@@ -0,0 +1,13 @@
+package flatbuffers
+
+// FlatBuffer is the interface that represents a flatbuffer.
+type FlatBuffer interface {
+	Table() Table
+	Init(buf []byte, i UOffsetT)
+}
+
+// GetRootAs is a generic helper to initialize a FlatBuffer with the provided buffer bytes and its data offset.
+func GetRootAs(buf []byte, offset UOffsetT, fb FlatBuffer) {
+	n := GetUOffsetT(buf[offset:])
+	fb.Init(buf, n+offset)
+}
diff --git a/third_party/flatbuffers/go/sizes.go b/third_party/flatbuffers/go/sizes.go
new file mode 100644
index 0000000..ba22169
--- /dev/null
+++ b/third_party/flatbuffers/go/sizes.go
@@ -0,0 +1,55 @@
+package flatbuffers
+
+import (
+	"unsafe"
+)
+
+const (
+	// See http://golang.org/ref/spec#Numeric_types
+
+	// SizeUint8 is the byte size of a uint8.
+	SizeUint8 = 1
+	// SizeUint16 is the byte size of a uint16.
+	SizeUint16 = 2
+	// SizeUint32 is the byte size of a uint32.
+	SizeUint32 = 4
+	// SizeUint64 is the byte size of a uint64.
+	SizeUint64 = 8
+
+	// SizeInt8 is the byte size of a int8.
+	SizeInt8 = 1
+	// SizeInt16 is the byte size of a int16.
+	SizeInt16 = 2
+	// SizeInt32 is the byte size of a int32.
+	SizeInt32 = 4
+	// SizeInt64 is the byte size of a int64.
+	SizeInt64 = 8
+
+	// SizeFloat32 is the byte size of a float32.
+	SizeFloat32 = 4
+	// SizeFloat64 is the byte size of a float64.
+	SizeFloat64 = 8
+
+	// SizeByte is the byte size of a byte.
+	// The `byte` type is aliased (by Go definition) to uint8.
+	SizeByte = 1
+
+	// SizeBool is the byte size of a bool.
+	// The `bool` type is aliased (by flatbuffers convention) to uint8.
+	SizeBool = 1
+
+	// SizeSOffsetT is the byte size of an SOffsetT.
+	// The `SOffsetT` type is aliased (by flatbuffers convention) to int32.
+	SizeSOffsetT = 4
+	// SizeUOffsetT is the byte size of an UOffsetT.
+	// The `UOffsetT` type is aliased (by flatbuffers convention) to uint32.
+	SizeUOffsetT = 4
+	// SizeVOffsetT is the byte size of an VOffsetT.
+	// The `VOffsetT` type is aliased (by flatbuffers convention) to uint16.
+	SizeVOffsetT = 2
+)
+
+// byteSliceToString converts a []byte to string without a heap allocation.
+func byteSliceToString(b []byte) string {
+	return *(*string)(unsafe.Pointer(&b))
+}
diff --git a/third_party/flatbuffers/go/struct.go b/third_party/flatbuffers/go/struct.go
new file mode 100644
index 0000000..11258f7
--- /dev/null
+++ b/third_party/flatbuffers/go/struct.go
@@ -0,0 +1,8 @@
+package flatbuffers
+
+// Struct wraps a byte slice and provides read access to its data.
+//
+// Structs do not have a vtable.
+type Struct struct {
+	Table
+}
diff --git a/third_party/flatbuffers/go/table.go b/third_party/flatbuffers/go/table.go
new file mode 100644
index 0000000..b273146
--- /dev/null
+++ b/third_party/flatbuffers/go/table.go
@@ -0,0 +1,505 @@
+package flatbuffers
+
+// Table wraps a byte slice and provides read access to its data.
+//
+// The variable `Pos` indicates the root of the FlatBuffers object therein.
+type Table struct {
+	Bytes []byte
+	Pos   UOffsetT // Always < 1<<31.
+}
+
+// Offset provides access into the Table's vtable.
+//
+// Fields which are deprecated are ignored by checking against the vtable's length.
+func (t *Table) Offset(vtableOffset VOffsetT) VOffsetT {
+	vtable := UOffsetT(SOffsetT(t.Pos) - t.GetSOffsetT(t.Pos))
+	if vtableOffset < t.GetVOffsetT(vtable) {
+		return t.GetVOffsetT(vtable + UOffsetT(vtableOffset))
+	}
+	return 0
+}
+
+// Indirect retrieves the relative offset stored at `offset`.
+func (t *Table) Indirect(off UOffsetT) UOffsetT {
+	return off + GetUOffsetT(t.Bytes[off:])
+}
+
+// String gets a string from data stored inside the flatbuffer.
+func (t *Table) String(off UOffsetT) string {
+	b := t.ByteVector(off)
+	return byteSliceToString(b)
+}
+
+// ByteVector gets a byte slice from data stored inside the flatbuffer.
+func (t *Table) ByteVector(off UOffsetT) []byte {
+	off += GetUOffsetT(t.Bytes[off:])
+	start := off + UOffsetT(SizeUOffsetT)
+	length := GetUOffsetT(t.Bytes[off:])
+	return t.Bytes[start : start+length]
+}
+
+// VectorLen retrieves the length of the vector whose offset is stored at
+// "off" in this object.
+func (t *Table) VectorLen(off UOffsetT) int {
+	off += t.Pos
+	off += GetUOffsetT(t.Bytes[off:])
+	return int(GetUOffsetT(t.Bytes[off:]))
+}
+
+// Vector retrieves the start of data of the vector whose offset is stored
+// at "off" in this object.
+func (t *Table) Vector(off UOffsetT) UOffsetT {
+	off += t.Pos
+	x := off + GetUOffsetT(t.Bytes[off:])
+	// data starts after metadata containing the vector length
+	x += UOffsetT(SizeUOffsetT)
+	return x
+}
+
+// Union initializes any Table-derived type to point to the union at the given
+// offset.
+func (t *Table) Union(t2 *Table, off UOffsetT) {
+	off += t.Pos
+	t2.Pos = off + t.GetUOffsetT(off)
+	t2.Bytes = t.Bytes
+}
+
+// GetBool retrieves a bool at the given offset.
+func (t *Table) GetBool(off UOffsetT) bool {
+	return GetBool(t.Bytes[off:])
+}
+
+// GetByte retrieves a byte at the given offset.
+func (t *Table) GetByte(off UOffsetT) byte {
+	return GetByte(t.Bytes[off:])
+}
+
+// GetUint8 retrieves a uint8 at the given offset.
+func (t *Table) GetUint8(off UOffsetT) uint8 {
+	return GetUint8(t.Bytes[off:])
+}
+
+// GetUint16 retrieves a uint16 at the given offset.
+func (t *Table) GetUint16(off UOffsetT) uint16 {
+	return GetUint16(t.Bytes[off:])
+}
+
+// GetUint32 retrieves a uint32 at the given offset.
+func (t *Table) GetUint32(off UOffsetT) uint32 {
+	return GetUint32(t.Bytes[off:])
+}
+
+// GetUint64 retrieves a uint64 at the given offset.
+func (t *Table) GetUint64(off UOffsetT) uint64 {
+	return GetUint64(t.Bytes[off:])
+}
+
+// GetInt8 retrieves a int8 at the given offset.
+func (t *Table) GetInt8(off UOffsetT) int8 {
+	return GetInt8(t.Bytes[off:])
+}
+
+// GetInt16 retrieves a int16 at the given offset.
+func (t *Table) GetInt16(off UOffsetT) int16 {
+	return GetInt16(t.Bytes[off:])
+}
+
+// GetInt32 retrieves a int32 at the given offset.
+func (t *Table) GetInt32(off UOffsetT) int32 {
+	return GetInt32(t.Bytes[off:])
+}
+
+// GetInt64 retrieves a int64 at the given offset.
+func (t *Table) GetInt64(off UOffsetT) int64 {
+	return GetInt64(t.Bytes[off:])
+}
+
+// GetFloat32 retrieves a float32 at the given offset.
+func (t *Table) GetFloat32(off UOffsetT) float32 {
+	return GetFloat32(t.Bytes[off:])
+}
+
+// GetFloat64 retrieves a float64 at the given offset.
+func (t *Table) GetFloat64(off UOffsetT) float64 {
+	return GetFloat64(t.Bytes[off:])
+}
+
+// GetUOffsetT retrieves a UOffsetT at the given offset.
+func (t *Table) GetUOffsetT(off UOffsetT) UOffsetT {
+	return GetUOffsetT(t.Bytes[off:])
+}
+
+// GetVOffsetT retrieves a VOffsetT at the given offset.
+func (t *Table) GetVOffsetT(off UOffsetT) VOffsetT {
+	return GetVOffsetT(t.Bytes[off:])
+}
+
+// GetSOffsetT retrieves a SOffsetT at the given offset.
+func (t *Table) GetSOffsetT(off UOffsetT) SOffsetT {
+	return GetSOffsetT(t.Bytes[off:])
+}
+
+// GetBoolSlot retrieves the bool that the given vtable location
+// points to. If the vtable value is zero, the default value `d`
+// will be returned.
+func (t *Table) GetBoolSlot(slot VOffsetT, d bool) bool {
+	off := t.Offset(slot)
+	if off == 0 {
+		return d
+	}
+
+	return t.GetBool(t.Pos + UOffsetT(off))
+}
+
+// GetByteSlot retrieves the byte that the given vtable location
+// points to. If the vtable value is zero, the default value `d`
+// will be returned.
+func (t *Table) GetByteSlot(slot VOffsetT, d byte) byte {
+	off := t.Offset(slot)
+	if off == 0 {
+		return d
+	}
+
+	return t.GetByte(t.Pos + UOffsetT(off))
+}
+
+// GetInt8Slot retrieves the int8 that the given vtable location
+// points to. If the vtable value is zero, the default value `d`
+// will be returned.
+func (t *Table) GetInt8Slot(slot VOffsetT, d int8) int8 {
+	off := t.Offset(slot)
+	if off == 0 {
+		return d
+	}
+
+	return t.GetInt8(t.Pos + UOffsetT(off))
+}
+
+// GetUint8Slot retrieves the uint8 that the given vtable location
+// points to. If the vtable value is zero, the default value `d`
+// will be returned.
+func (t *Table) GetUint8Slot(slot VOffsetT, d uint8) uint8 {
+	off := t.Offset(slot)
+	if off == 0 {
+		return d
+	}
+
+	return t.GetUint8(t.Pos + UOffsetT(off))
+}
+
+// GetInt16Slot retrieves the int16 that the given vtable location
+// points to. If the vtable value is zero, the default value `d`
+// will be returned.
+func (t *Table) GetInt16Slot(slot VOffsetT, d int16) int16 {
+	off := t.Offset(slot)
+	if off == 0 {
+		return d
+	}
+
+	return t.GetInt16(t.Pos + UOffsetT(off))
+}
+
+// GetUint16Slot retrieves the uint16 that the given vtable location
+// points to. If the vtable value is zero, the default value `d`
+// will be returned.
+func (t *Table) GetUint16Slot(slot VOffsetT, d uint16) uint16 {
+	off := t.Offset(slot)
+	if off == 0 {
+		return d
+	}
+
+	return t.GetUint16(t.Pos + UOffsetT(off))
+}
+
+// GetInt32Slot retrieves the int32 that the given vtable location
+// points to. If the vtable value is zero, the default value `d`
+// will be returned.
+func (t *Table) GetInt32Slot(slot VOffsetT, d int32) int32 {
+	off := t.Offset(slot)
+	if off == 0 {
+		return d
+	}
+
+	return t.GetInt32(t.Pos + UOffsetT(off))
+}
+
+// GetUint32Slot retrieves the uint32 that the given vtable location
+// points to. If the vtable value is zero, the default value `d`
+// will be returned.
+func (t *Table) GetUint32Slot(slot VOffsetT, d uint32) uint32 {
+	off := t.Offset(slot)
+	if off == 0 {
+		return d
+	}
+
+	return t.GetUint32(t.Pos + UOffsetT(off))
+}
+
+// GetInt64Slot retrieves the int64 that the given vtable location
+// points to. If the vtable value is zero, the default value `d`
+// will be returned.
+func (t *Table) GetInt64Slot(slot VOffsetT, d int64) int64 {
+	off := t.Offset(slot)
+	if off == 0 {
+		return d
+	}
+
+	return t.GetInt64(t.Pos + UOffsetT(off))
+}
+
+// GetUint64Slot retrieves the uint64 that the given vtable location
+// points to. If the vtable value is zero, the default value `d`
+// will be returned.
+func (t *Table) GetUint64Slot(slot VOffsetT, d uint64) uint64 {
+	off := t.Offset(slot)
+	if off == 0 {
+		return d
+	}
+
+	return t.GetUint64(t.Pos + UOffsetT(off))
+}
+
+// GetFloat32Slot retrieves the float32 that the given vtable location
+// points to. If the vtable value is zero, the default value `d`
+// will be returned.
+func (t *Table) GetFloat32Slot(slot VOffsetT, d float32) float32 {
+	off := t.Offset(slot)
+	if off == 0 {
+		return d
+	}
+
+	return t.GetFloat32(t.Pos + UOffsetT(off))
+}
+
+// GetFloat64Slot retrieves the float64 that the given vtable location
+// points to. If the vtable value is zero, the default value `d`
+// will be returned.
+func (t *Table) GetFloat64Slot(slot VOffsetT, d float64) float64 {
+	off := t.Offset(slot)
+	if off == 0 {
+		return d
+	}
+
+	return t.GetFloat64(t.Pos + UOffsetT(off))
+}
+
+// GetVOffsetTSlot retrieves the VOffsetT that the given vtable location
+// points to. If the vtable value is zero, the default value `d`
+// will be returned.
+func (t *Table) GetVOffsetTSlot(slot VOffsetT, d VOffsetT) VOffsetT {
+	off := t.Offset(slot)
+	if off == 0 {
+		return d
+	}
+	return VOffsetT(off)
+}
+
+// MutateBool updates a bool at the given offset.
+func (t *Table) MutateBool(off UOffsetT, n bool) bool {
+	WriteBool(t.Bytes[off:], n)
+	return true
+}
+
+// MutateByte updates a Byte at the given offset.
+func (t *Table) MutateByte(off UOffsetT, n byte) bool {
+	WriteByte(t.Bytes[off:], n)
+	return true
+}
+
+// MutateUint8 updates a Uint8 at the given offset.
+func (t *Table) MutateUint8(off UOffsetT, n uint8) bool {
+	WriteUint8(t.Bytes[off:], n)
+	return true
+}
+
+// MutateUint16 updates a Uint16 at the given offset.
+func (t *Table) MutateUint16(off UOffsetT, n uint16) bool {
+	WriteUint16(t.Bytes[off:], n)
+	return true
+}
+
+// MutateUint32 updates a Uint32 at the given offset.
+func (t *Table) MutateUint32(off UOffsetT, n uint32) bool {
+	WriteUint32(t.Bytes[off:], n)
+	return true
+}
+
+// MutateUint64 updates a Uint64 at the given offset.
+func (t *Table) MutateUint64(off UOffsetT, n uint64) bool {
+	WriteUint64(t.Bytes[off:], n)
+	return true
+}
+
+// MutateInt8 updates a Int8 at the given offset.
+func (t *Table) MutateInt8(off UOffsetT, n int8) bool {
+	WriteInt8(t.Bytes[off:], n)
+	return true
+}
+
+// MutateInt16 updates a Int16 at the given offset.
+func (t *Table) MutateInt16(off UOffsetT, n int16) bool {
+	WriteInt16(t.Bytes[off:], n)
+	return true
+}
+
+// MutateInt32 updates a Int32 at the given offset.
+func (t *Table) MutateInt32(off UOffsetT, n int32) bool {
+	WriteInt32(t.Bytes[off:], n)
+	return true
+}
+
+// MutateInt64 updates a Int64 at the given offset.
+func (t *Table) MutateInt64(off UOffsetT, n int64) bool {
+	WriteInt64(t.Bytes[off:], n)
+	return true
+}
+
+// MutateFloat32 updates a Float32 at the given offset.
+func (t *Table) MutateFloat32(off UOffsetT, n float32) bool {
+	WriteFloat32(t.Bytes[off:], n)
+	return true
+}
+
+// MutateFloat64 updates a Float64 at the given offset.
+func (t *Table) MutateFloat64(off UOffsetT, n float64) bool {
+	WriteFloat64(t.Bytes[off:], n)
+	return true
+}
+
+// MutateUOffsetT updates a UOffsetT at the given offset.
+func (t *Table) MutateUOffsetT(off UOffsetT, n UOffsetT) bool {
+	WriteUOffsetT(t.Bytes[off:], n)
+	return true
+}
+
+// MutateVOffsetT updates a VOffsetT at the given offset.
+func (t *Table) MutateVOffsetT(off UOffsetT, n VOffsetT) bool {
+	WriteVOffsetT(t.Bytes[off:], n)
+	return true
+}
+
+// MutateSOffsetT updates a SOffsetT at the given offset.
+func (t *Table) MutateSOffsetT(off UOffsetT, n SOffsetT) bool {
+	WriteSOffsetT(t.Bytes[off:], n)
+	return true
+}
+
+// MutateBoolSlot updates the bool at given vtable location
+func (t *Table) MutateBoolSlot(slot VOffsetT, n bool) bool {
+	if off := t.Offset(slot); off != 0 {
+		t.MutateBool(t.Pos+UOffsetT(off), n)
+		return true
+	}
+
+	return false
+}
+
+// MutateByteSlot updates the byte at given vtable location
+func (t *Table) MutateByteSlot(slot VOffsetT, n byte) bool {
+	if off := t.Offset(slot); off != 0 {
+		t.MutateByte(t.Pos+UOffsetT(off), n)
+		return true
+	}
+
+	return false
+}
+
+// MutateInt8Slot updates the int8 at given vtable location
+func (t *Table) MutateInt8Slot(slot VOffsetT, n int8) bool {
+	if off := t.Offset(slot); off != 0 {
+		t.MutateInt8(t.Pos+UOffsetT(off), n)
+		return true
+	}
+
+	return false
+}
+
+// MutateUint8Slot updates the uint8 at given vtable location
+func (t *Table) MutateUint8Slot(slot VOffsetT, n uint8) bool {
+	if off := t.Offset(slot); off != 0 {
+		t.MutateUint8(t.Pos+UOffsetT(off), n)
+		return true
+	}
+
+	return false
+}
+
+// MutateInt16Slot updates the int16 at given vtable location
+func (t *Table) MutateInt16Slot(slot VOffsetT, n int16) bool {
+	if off := t.Offset(slot); off != 0 {
+		t.MutateInt16(t.Pos+UOffsetT(off), n)
+		return true
+	}
+
+	return false
+}
+
+// MutateUint16Slot updates the uint16 at given vtable location
+func (t *Table) MutateUint16Slot(slot VOffsetT, n uint16) bool {
+	if off := t.Offset(slot); off != 0 {
+		t.MutateUint16(t.Pos+UOffsetT(off), n)
+		return true
+	}
+
+	return false
+}
+
+// MutateInt32Slot updates the int32 at given vtable location
+func (t *Table) MutateInt32Slot(slot VOffsetT, n int32) bool {
+	if off := t.Offset(slot); off != 0 {
+		t.MutateInt32(t.Pos+UOffsetT(off), n)
+		return true
+	}
+
+	return false
+}
+
+// MutateUint32Slot updates the uint32 at given vtable location
+func (t *Table) MutateUint32Slot(slot VOffsetT, n uint32) bool {
+	if off := t.Offset(slot); off != 0 {
+		t.MutateUint32(t.Pos+UOffsetT(off), n)
+		return true
+	}
+
+	return false
+}
+
+// MutateInt64Slot updates the int64 at given vtable location
+func (t *Table) MutateInt64Slot(slot VOffsetT, n int64) bool {
+	if off := t.Offset(slot); off != 0 {
+		t.MutateInt64(t.Pos+UOffsetT(off), n)
+		return true
+	}
+
+	return false
+}
+
+// MutateUint64Slot updates the uint64 at given vtable location
+func (t *Table) MutateUint64Slot(slot VOffsetT, n uint64) bool {
+	if off := t.Offset(slot); off != 0 {
+		t.MutateUint64(t.Pos+UOffsetT(off), n)
+		return true
+	}
+
+	return false
+}
+
+// MutateFloat32Slot updates the float32 at given vtable location
+func (t *Table) MutateFloat32Slot(slot VOffsetT, n float32) bool {
+	if off := t.Offset(slot); off != 0 {
+		t.MutateFloat32(t.Pos+UOffsetT(off), n)
+		return true
+	}
+
+	return false
+}
+
+// MutateFloat64Slot updates the float64 at given vtable location
+func (t *Table) MutateFloat64Slot(slot VOffsetT, n float64) bool {
+	if off := t.Offset(slot); off != 0 {
+		t.MutateFloat64(t.Pos+UOffsetT(off), n)
+		return true
+	}
+
+	return false
+}
diff --git a/third_party/flatbuffers/grpc/README.md b/third_party/flatbuffers/grpc/README.md
new file mode 100644
index 0000000..544651d
--- /dev/null
+++ b/third_party/flatbuffers/grpc/README.md
@@ -0,0 +1,31 @@
+GRPC implementation and test
+============================
+
+NOTE: files in `src/` are shared with the GRPC project, and maintained there
+(any changes should be submitted to GRPC instead). These files are copied
+from GRPC, and work with both the Protobuf and FlatBuffers code generator.
+
+`tests/` contains a GRPC specific test, you need to have built and installed
+the GRPC libraries for this to compile. This test will build using the
+`FLATBUFFERS_BUILD_GRPCTEST` option to the main FlatBuffers CMake project.
+
+## Building Flatbuffers with gRPC
+
+### Linux
+
+1. Download, build and install gRPC. See [instructions](https://github.com/grpc/grpc/tree/master/src/cpp).
+    * Lets say your gRPC clone is at `/your/path/to/grpc_repo`.
+    * Install gRPC in a custom directory by running `make install prefix=/your/path/to/grpc_repo/install`.
+2. `export GRPC_INSTALL_PATH=/your/path/to/grpc_repo/install`
+3. `export PROTOBUF_DOWNLOAD_PATH=/your/path/to/grpc_repo/third_party/protobuf`
+4. `mkdir build ; cd build`
+5. `cmake -DFLATBUFFERS_BUILD_GRPCTEST=ON -DGRPC_INSTALL_PATH=${GRPC_INSTALL_PATH} -DPROTOBUF_DOWNLOAD_PATH=${PROTOBUF_DOWNLOAD_PATH} ..`
+6. `make`
+
+## Running FlatBuffer gRPC tests
+
+### Linux
+
+1. `ln -s ${GRPC_INSTALL_PATH}/lib/libgrpc++_unsecure.so.6 ${GRPC_INSTALL_PATH}/lib/libgrpc++_unsecure.so.1`
+2. `export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${GRPC_INSTALL_PATH}/lib`
+3. `make test ARGS=-V` 
diff --git a/third_party/flatbuffers/grpc/build_grpc.sh b/third_party/flatbuffers/grpc/build_grpc.sh
new file mode 100755
index 0000000..8fb9e1c
--- /dev/null
+++ b/third_party/flatbuffers/grpc/build_grpc.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+grpc_1_15_1_githash=1a60e6971f428323245a930031ad267bb3142ba4
+
+function build_grpc () {
+  git clone https://github.com/grpc/grpc.git google/grpc
+  cd google/grpc
+  git checkout ${grpc_1_15_1_githash} 
+  git submodule update --init
+  make
+  make install prefix=`pwd`/install
+  if [ ! -f ${GRPC_INSTALL_PATH}/lib/libgrpc++_unsecure.so.1 ]; then
+    ln -s ${GRPC_INSTALL_PATH}/lib/libgrpc++_unsecure.so.6 ${GRPC_INSTALL_PATH}/lib/libgrpc++_unsecure.so.1
+  fi
+  cd ../..
+}
+
+GRPC_INSTALL_PATH=`pwd`/google/grpc/install
+PROTOBUF_DOWNLOAD_PATH=`pwd`/google/grpc/third_party/protobuf
+
+build_grpc
diff --git a/third_party/flatbuffers/grpc/flatbuffers-java-grpc/pom.xml b/third_party/flatbuffers/grpc/flatbuffers-java-grpc/pom.xml
new file mode 100644
index 0000000..b5b88cb
--- /dev/null
+++ b/third_party/flatbuffers/grpc/flatbuffers-java-grpc/pom.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.google.flatbuffers</groupId>
+        <artifactId>flatbuffers-parent</artifactId>
+        <version>1.11.1</version>
+    </parent>
+    <artifactId>flatbuffers-java-grpc</artifactId>
+    <name>${project.artifactId}</name>
+    <packaging>bundle</packaging>
+    <description>
+        Utilities supporting generated code for GRPC
+    </description>
+    <developers>
+        <developer>
+            <name>Wouter van Oortmerssen</name>
+        </developer>
+        <developer>
+            <name>Yuri Finkelstein</name>
+            <url>https://github.com/yfinkelstein</url>
+        </developer>
+    </developers>
+    <properties>
+        <gRPC.version>1.11.1</gRPC.version>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>com.google.flatbuffers</groupId>
+            <artifactId>flatbuffers-java</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-core</artifactId>
+            <version>${gRPC.version}</version>
+        </dependency>
+  </dependencies>
+</project>
+
diff --git a/third_party/flatbuffers/grpc/flatbuffers-java-grpc/src/main/java/com/google/flatbuffers/grpc/FlatbuffersUtils.java b/third_party/flatbuffers/grpc/flatbuffers-java-grpc/src/main/java/com/google/flatbuffers/grpc/FlatbuffersUtils.java
new file mode 100644
index 0000000..768708b
--- /dev/null
+++ b/third_party/flatbuffers/grpc/flatbuffers-java-grpc/src/main/java/com/google/flatbuffers/grpc/FlatbuffersUtils.java
@@ -0,0 +1,117 @@
+/*
+ * 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.
+ */
+package com.google.flatbuffers.grpc;
+
+import com.google.flatbuffers.Table;
+import io.grpc.Drainable;
+import io.grpc.KnownLength;
+import io.grpc.MethodDescriptor;
+
+import javax.annotation.Nullable;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+
+public class FlatbuffersUtils {
+    abstract public static class FBExtactor  <T extends Table> {
+        T extract (InputStream stream) throws IOException {
+            if (stream instanceof KnownLength) {
+                int size = stream.available();
+                ByteBuffer buffer = ByteBuffer.allocate(size);
+                stream.read(buffer.array());
+                return extract(buffer);
+            } else
+                throw new RuntimeException("The class " + stream.getClass().getCanonicalName() + " does not extend from KnownLength ");
+        }
+
+        public abstract T extract(ByteBuffer buffer);
+
+    }
+
+    static class FBInputStream extends InputStream implements Drainable, KnownLength {
+        private final ByteBuffer buffer;
+        private final int size;
+        @Nullable private ByteArrayInputStream inputStream;
+
+        FBInputStream(ByteBuffer buffer) {
+            this.buffer = buffer;
+            this.size = buffer.remaining();
+        }
+
+        private void makeStreamIfNotAlready() {
+            if (inputStream == null)
+                inputStream = new ByteArrayInputStream(buffer.array(), buffer.position(), size);
+        }
+
+        @Override
+        public int drainTo(OutputStream target) throws IOException {
+            target.write(buffer.array(), buffer.position(), size);
+            return size;
+        }
+
+        @Override
+        public int read() throws IOException {
+            makeStreamIfNotAlready();
+            return inputStream.read();
+        }
+
+        @Override
+        public int read(byte[] b, int off, int len) throws IOException {
+            makeStreamIfNotAlready();
+            if (inputStream == null) {
+                if (len >= size) {
+                    System.arraycopy(buffer.array(), buffer.position(), b, off, size);
+                    return size;
+                } else {
+                    makeStreamIfNotAlready();
+                    return inputStream.read(b, off, len);
+                }
+            } else
+                return inputStream.read(b, off, len);
+        }
+
+        @Override
+        public int available() throws IOException {
+            return inputStream == null ? size : inputStream.available();
+        }
+
+    }
+
+    public static <T extends Table> MethodDescriptor.Marshaller<T> marshaller(final Class<T> clazz, final FBExtactor<T> extractor) {
+        return new MethodDescriptor.ReflectableMarshaller<T>() {
+            @Override
+            public Class<T> getMessageClass() {
+                return clazz;
+            }
+
+            @Override
+            public InputStream stream(T value) {
+                return new FBInputStream (value.getByteBuffer());
+            }
+
+            @Override
+            public T parse(InputStream stream) {
+                try {
+                    return extractor.extract(stream);
+                } catch (IOException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        };
+    }
+}
diff --git a/third_party/flatbuffers/grpc/pom.xml b/third_party/flatbuffers/grpc/pom.xml
new file mode 100644
index 0000000..a0fca79
--- /dev/null
+++ b/third_party/flatbuffers/grpc/pom.xml
@@ -0,0 +1,213 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>com.google.flatbuffers</groupId>
+    <artifactId>flatbuffers-parent</artifactId>
+    <packaging>pom</packaging>
+    <version>1.11.1</version>
+    <name>flatbuffers-parent</name>
+    <description>parent pom for flatbuffers java artifacts</description>
+    <properties>
+        <scm.url>https://github.com/google/flatbuffers</scm.url>
+        <scm.connection>scm:git:${scm.url}.git</scm.connection>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <licenses>
+        <license>
+            <name>The Apache Software License, Version 2.0</name>
+            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+            <distribution>repo</distribution>
+        </license>
+    </licenses>
+
+    <issueManagement>
+        <system>GitHub</system>
+        <url>https://github.com/google/flatbuffers/issues</url>
+    </issueManagement>
+
+    <developers>
+        <developer>
+            <name>Wouter van Oortmerssen</name>
+        </developer>
+    </developers>
+
+    <url>${scm.url}</url>
+
+    <scm>
+        <connection>${scm.connection}</connection>
+        <developerConnection>${scm.connection}</developerConnection>
+        <url>${scm.url}</url>
+        <tag>HEAD</tag>
+    </scm>
+
+    <distributionManagement>
+        <snapshotRepository>
+            <id>ossrh</id>
+            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+        </snapshotRepository>
+    </distributionManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.12</version>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
+    <build>
+        <extensions>
+            <extension>
+                <!--
+                    os-maven-plugin is a Maven extension/plugin that generates various useful platform-dependent
+                    project properties normalized from ${os.detected.name} and ${os.detected.arch}.
+                -->
+                <groupId>kr.motd.maven</groupId>
+                <artifactId>os-maven-plugin</artifactId>
+                <version>1.5.0.Final</version>
+            </extension>
+        </extensions>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <artifactId>maven-compiler-plugin</artifactId>
+                    <version>3.6.1</version>
+                </plugin>
+                <plugin>
+                    <artifactId>maven-jar-plugin</artifactId>
+                    <version>3.0.2</version>
+                </plugin>
+                <plugin>
+                    <artifactId>maven-source-plugin</artifactId>
+                    <version>3.0.1</version>
+                </plugin>
+                <plugin>
+                    <artifactId>maven-surefire-plugin</artifactId>
+                    <version>2.19.1</version>
+                </plugin>
+                <plugin>
+                    <artifactId>maven-javadoc-plugin</artifactId>
+                    <version>2.10.4</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.codehaus.mojo</groupId>
+                    <artifactId>build-helper-maven-plugin</artifactId>
+                    <version>1.12</version>
+                </plugin>
+                <plugin>
+                    <artifactId>maven-dependency-plugin</artifactId>
+                    <version>2.8</version>
+                </plugin>
+                <plugin>
+                    <artifactId>maven-deploy-plugin</artifactId>
+                    <version>2.7</version>
+                </plugin>
+                <plugin>
+                    <artifactId>maven-gpg-plugin</artifactId>
+                    <version>1.5</version>
+                </plugin>
+                <plugin>
+                    <artifactId>maven-release-plugin</artifactId>
+                    <version>2.5.3</version>
+                </plugin>
+
+                <plugin>
+                    <groupId>org.codehaus.mojo</groupId>
+                    <artifactId>exec-maven-plugin</artifactId>
+                    <version>1.5.0</version>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+
+        <plugins>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.6</source>
+                    <target>1.6</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <includes>
+                        <include>**/*Test.java</include>
+                    </includes>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-source-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>attach-sources</id>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>attach-javadocs</id>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <version>3.0.1</version>
+                <extensions>true</extensions>
+            </plugin>
+            <plugin>
+                <groupId>org.sonatype.plugins</groupId>
+                <artifactId>nexus-staging-maven-plugin</artifactId>
+                <version>1.6.7</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <serverId>ossrh</serverId>
+                    <nexusUrl>https://oss.sonatype.org/</nexusUrl>
+                    <autoReleaseAfterClose>true</autoReleaseAfterClose>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-gpg-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>sign-artifacts</id>
+                        <phase>verify</phase>
+                        <goals>
+                            <goal>sign</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <artifactId>maven-release-plugin</artifactId>
+                <configuration>
+                    <autoVersionSubmodules>true</autoVersionSubmodules>
+                    <useReleaseProfile>false</useReleaseProfile>
+                    <releaseProfiles>release</releaseProfiles>
+                    <goals>deploy</goals>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <modules>
+<!-- consider the benefits of publishing all maven artifacts in this project
+
+        <module>flatbuffers-compiler</module>
+        <module>flatbuffers-java</module>
+
+-->
+        <module>flatbuffers-java-grpc</module>
+    </modules>
+
+</project>
diff --git a/third_party/flatbuffers/grpc/samples/greeter/Makefile b/third_party/flatbuffers/grpc/samples/greeter/Makefile
new file mode 100644
index 0000000..3746705
--- /dev/null
+++ b/third_party/flatbuffers/grpc/samples/greeter/Makefile
@@ -0,0 +1,14 @@
+CXXFLAGS ?= -I../../../include
+LDFLAGS ?=
+
+.PHONY: all
+all: server client
+
+greeter_generated.h: greeter.fbs
+	flatc --grpc --cpp $<
+
+server: server.cpp greeter.grpc.fb.cc greeter_generated.h greeter.grpc.fb.h
+	g++ -std=c++11 -O2 $(CXXFLAGS) $(LDFLAGS) -lgpr -lgrpc -lgrpc++ server.cpp greeter.grpc.fb.cc -o $@
+
+client: client.cpp greeter.grpc.fb.cc greeter_generated.h greeter.grpc.fb.h
+	g++ -std=c++11 -O2 $(CXXFLAGS) $(LDFLAGS) -lgpr -lgrpc -lgrpc++ client.cpp greeter.grpc.fb.cc -o $@
diff --git a/third_party/flatbuffers/grpc/samples/greeter/client.cpp b/third_party/flatbuffers/grpc/samples/greeter/client.cpp
new file mode 100644
index 0000000..2e42f8f
--- /dev/null
+++ b/third_party/flatbuffers/grpc/samples/greeter/client.cpp
@@ -0,0 +1,85 @@
+#include "greeter.grpc.fb.h"
+#include "greeter_generated.h"
+
+#include <grpc++/grpc++.h>
+
+#include <iostream>
+#include <memory>
+#include <string>
+
+class GreeterClient {
+ public:
+  GreeterClient(std::shared_ptr<grpc::Channel> channel)
+    : stub_(Greeter::NewStub(channel)) {}
+
+  std::string SayHello(const std::string &name) {
+    flatbuffers::grpc::MessageBuilder mb;
+    auto name_offset = mb.CreateString(name);
+    auto request_offset = CreateHelloRequest(mb, name_offset);
+    mb.Finish(request_offset);
+    auto request_msg = mb.ReleaseMessage<HelloRequest>();
+
+    flatbuffers::grpc::Message<HelloReply> response_msg;
+
+    grpc::ClientContext context;
+
+    auto status = stub_->SayHello(&context, request_msg, &response_msg);
+    if (status.ok()) {
+      const HelloReply *response = response_msg.GetRoot();
+      return response->message()->str();
+    } else {
+      std::cerr << status.error_code() << ": " << status.error_message()
+                << std::endl;
+      return "RPC failed";
+    }
+  }
+
+  void SayManyHellos(const std::string &name, int num_greetings,
+                     std::function<void(const std::string &)> callback) {
+    flatbuffers::grpc::MessageBuilder mb;
+    auto name_offset = mb.CreateString(name);
+    auto request_offset =
+        CreateManyHellosRequest(mb, name_offset, num_greetings);
+    mb.Finish(request_offset);
+    auto request_msg = mb.ReleaseMessage<ManyHellosRequest>();
+
+    flatbuffers::grpc::Message<HelloReply> response_msg;
+
+    grpc::ClientContext context;
+
+    auto stream = stub_->SayManyHellos(&context, request_msg);
+    while (stream->Read(&response_msg)) {
+      const HelloReply *response = response_msg.GetRoot();
+      callback(response->message()->str());
+    }
+    auto status = stream->Finish();
+    if (!status.ok()) {
+      std::cerr << status.error_code() << ": " << status.error_message()
+                << std::endl;
+      callback("RPC failed");
+    }
+  }
+
+ private:
+  std::unique_ptr<Greeter::Stub> stub_;
+};
+
+int main(int argc, char **argv) {
+  std::string server_address("localhost:50051");
+
+  auto channel =
+      grpc::CreateChannel(server_address, grpc::InsecureChannelCredentials());
+  GreeterClient greeter(channel);
+
+  std::string name("world");
+
+  std::string message = greeter.SayHello(name);
+  std::cerr << "Greeter received: " << message << std::endl;
+
+  int num_greetings = 10;
+  greeter.SayManyHellos(name, num_greetings, [](const std::string &message) {
+    std::cerr << "Greeter received: " << message << std::endl;
+  });
+
+  return 0;
+}
diff --git a/third_party/flatbuffers/grpc/samples/greeter/greeter.fbs b/third_party/flatbuffers/grpc/samples/greeter/greeter.fbs
new file mode 100644
index 0000000..811303c
--- /dev/null
+++ b/third_party/flatbuffers/grpc/samples/greeter/greeter.fbs
@@ -0,0 +1,17 @@
+table HelloReply {
+  message:string;
+}
+
+table HelloRequest {
+  name:string;
+}
+
+table ManyHellosRequest {
+  name:string;
+  num_greetings:int;
+}
+
+rpc_service Greeter {
+  SayHello(HelloRequest):HelloReply;
+  SayManyHellos(ManyHellosRequest):HelloReply (streaming: "server");
+}
diff --git a/third_party/flatbuffers/grpc/samples/greeter/server.cpp b/third_party/flatbuffers/grpc/samples/greeter/server.cpp
new file mode 100644
index 0000000..82c97dc
--- /dev/null
+++ b/third_party/flatbuffers/grpc/samples/greeter/server.cpp
@@ -0,0 +1,80 @@
+#include "greeter.grpc.fb.h"
+#include "greeter_generated.h"
+
+#include <grpc++/grpc++.h>
+
+#include <iostream>
+#include <memory>
+#include <string>
+
+class GreeterServiceImpl final : public Greeter::Service {
+  virtual grpc::Status SayHello(
+      grpc::ServerContext *context,
+      const flatbuffers::grpc::Message<HelloRequest> *request_msg,
+      flatbuffers::grpc::Message<HelloReply> *response_msg) override {
+    // flatbuffers::grpc::MessageBuilder mb_;
+    // We call GetRoot to "parse" the message. Verification is already
+    // performed by default. See the notes below for more details.
+    const HelloRequest *request = request_msg->GetRoot();
+
+    // Fields are retrieved as usual with FlatBuffers
+    const std::string &name = request->name()->str();
+
+    // `flatbuffers::grpc::MessageBuilder` is a `FlatBufferBuilder` with a
+    // special allocator for efficient gRPC buffer transfer, but otherwise
+    // usage is the same as usual.
+    auto msg_offset = mb_.CreateString("Hello, " + name);
+    auto hello_offset = CreateHelloReply(mb_, msg_offset);
+    mb_.Finish(hello_offset);
+
+    // The `ReleaseMessage<T>()` function detaches the message from the
+    // builder, so we can transfer the resopnse to gRPC while simultaneously
+    // detaching that memory buffer from the builer.
+    *response_msg = mb_.ReleaseMessage<HelloReply>();
+    assert(response_msg->Verify());
+
+    // Return an OK status.
+    return grpc::Status::OK;
+  }
+
+  virtual grpc::Status SayManyHellos(
+      grpc::ServerContext *context,
+      const flatbuffers::grpc::Message<ManyHellosRequest> *request_msg,
+      grpc::ServerWriter<flatbuffers::grpc::Message<HelloReply>> *writer)
+      override {
+    // The streaming usage below is simply a combination of standard gRPC
+    // streaming with the FlatBuffers usage shown above.
+    const ManyHellosRequest *request = request_msg->GetRoot();
+    const std::string &name = request->name()->str();
+    int num_greetings = request->num_greetings();
+
+    for (int i = 0; i < num_greetings; i++) {
+      auto msg_offset = mb_.CreateString("Many hellos, " + name);
+      auto hello_offset = CreateHelloReply(mb_, msg_offset);
+      mb_.Finish(hello_offset);
+      writer->Write(mb_.ReleaseMessage<HelloReply>());
+    }
+
+    return grpc::Status::OK;
+  }
+
+  flatbuffers::grpc::MessageBuilder mb_;
+};
+
+void RunServer() {
+  std::string server_address("0.0.0.0:50051");
+  GreeterServiceImpl service;
+
+  grpc::ServerBuilder builder;
+  builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
+  builder.RegisterService(&service);
+  std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
+  std::cerr << "Server listening on " << server_address << std::endl;
+
+  server->Wait();
+}
+
+int main(int argc, const char *argv[]) {
+  RunServer();
+  return 0;
+}
diff --git a/third_party/flatbuffers/grpc/src/compiler/config.h b/third_party/flatbuffers/grpc/src/compiler/config.h
new file mode 100644
index 0000000..4adc594
--- /dev/null
+++ b/third_party/flatbuffers/grpc/src/compiler/config.h
@@ -0,0 +1,40 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef SRC_COMPILER_CONFIG_H
+#define SRC_COMPILER_CONFIG_H
+
+// This file is here only because schema_interface.h, which is copied from gRPC,
+// includes it. There is nothing for Flatbuffers to configure.
+
+#endif  // SRC_COMPILER_CONFIG_H
diff --git a/third_party/flatbuffers/grpc/src/compiler/cpp_generator.cc b/third_party/flatbuffers/grpc/src/compiler/cpp_generator.cc
new file mode 100644
index 0000000..6cfd22e
--- /dev/null
+++ b/third_party/flatbuffers/grpc/src/compiler/cpp_generator.cc
@@ -0,0 +1,1780 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <map>
+
+#include "src/compiler/cpp_generator.h"
+#include "flatbuffers/util.h"
+
+#include <sstream>
+
+namespace grpc_cpp_generator {
+namespace {
+
+grpc::string message_header_ext() { return "_generated.h"; }
+grpc::string service_header_ext() { return ".grpc.fb.h"; }
+
+template <class T>
+grpc::string as_string(T x) {
+  std::ostringstream out;
+  out << x;
+  return out.str();
+}
+
+inline bool ClientOnlyStreaming(const grpc_generator::Method *method) {
+  return method->ClientStreaming() && !method->ServerStreaming();
+}
+
+inline bool ServerOnlyStreaming(const grpc_generator::Method *method) {
+  return !method->ClientStreaming() && method->ServerStreaming();
+}
+
+grpc::string FilenameIdentifier(const grpc::string &filename) {
+  grpc::string result;
+  for (unsigned i = 0; i < filename.size(); i++) {
+    char c = filename[i];
+    if (isalnum(c)) {
+      result.push_back(c);
+    } else {
+      static char hex[] = "0123456789abcdef";
+      result.push_back('_');
+      result.push_back(hex[(c >> 4) & 0xf]);
+      result.push_back(hex[c & 0xf]);
+    }
+  }
+  return result;
+}
+}  // namespace
+
+template <class T, size_t N>
+T *array_end(T (&array)[N]) {
+  return array + N;
+}
+
+void PrintIncludes(grpc_generator::Printer *printer,
+                   const std::vector<grpc::string> &headers,
+                   const Parameters &params) {
+  std::map<grpc::string, grpc::string> vars;
+
+  vars["l"] = params.use_system_headers ? '<' : '"';
+  vars["r"] = params.use_system_headers ? '>' : '"';
+
+  auto &s = params.grpc_search_path;
+  if (!s.empty()) {
+    vars["l"] += s;
+    if (s[s.size() - 1] != '/') {
+      vars["l"] += '/';
+    }
+  }
+
+  for (auto i = headers.begin(); i != headers.end(); i++) {
+    vars["h"] = *i;
+    printer->Print(vars, "#include $l$$h$$r$\n");
+  }
+}
+
+grpc::string GetHeaderPrologue(grpc_generator::File *file,
+                               const Parameters & /*params*/) {
+  grpc::string output;
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    auto printer = file->CreatePrinter(&output);
+    std::map<grpc::string, grpc::string> vars;
+
+    vars["filename"] = file->filename();
+    vars["filename_identifier"] = FilenameIdentifier(file->filename());
+    vars["filename_base"] = file->filename_without_ext();
+    vars["message_header_ext"] = message_header_ext();
+
+    printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
+    printer->Print(vars,
+                   "// If you make any local change, they will be lost.\n");
+    printer->Print(vars, "// source: $filename$\n");
+    grpc::string leading_comments = file->GetLeadingComments("//");
+    if (!leading_comments.empty()) {
+      printer->Print(vars, "// Original file comments:\n");
+      printer->Print(leading_comments.c_str());
+    }
+    printer->Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n");
+    printer->Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n");
+    printer->Print(vars, "\n");
+    printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
+    printer->Print(vars, file->additional_headers().c_str());
+    printer->Print(vars, "\n");
+  }
+  return output;
+}
+
+grpc::string GetHeaderIncludes(grpc_generator::File *file,
+                               const Parameters &params) {
+  grpc::string output;
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    auto printer = file->CreatePrinter(&output);
+    std::map<grpc::string, grpc::string> vars;
+
+    static const char *headers_strs[] = {
+        "grpc++/impl/codegen/async_stream.h",
+        "grpc++/impl/codegen/async_unary_call.h",
+        "grpc++/impl/codegen/method_handler_impl.h",
+        "grpc++/impl/codegen/proto_utils.h",
+        "grpc++/impl/codegen/rpc_method.h",
+        "grpc++/impl/codegen/service_type.h",
+        "grpc++/impl/codegen/status.h",
+        "grpc++/impl/codegen/stub_options.h",
+        "grpc++/impl/codegen/sync_stream.h"};
+    std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
+    PrintIncludes(printer.get(), headers, params);
+    printer->Print(vars, "\n");
+    printer->Print(vars, "namespace grpc {\n");
+    printer->Print(vars, "class CompletionQueue;\n");
+    printer->Print(vars, "class Channel;\n");
+    printer->Print(vars, "class ServerCompletionQueue;\n");
+    printer->Print(vars, "class ServerContext;\n");
+    printer->Print(vars, "}  // namespace grpc\n\n");
+
+    if (!file->package().empty()) {
+      std::vector<grpc::string> parts = file->package_parts();
+
+      for (auto part = parts.begin(); part != parts.end(); part++) {
+        vars["part"] = *part;
+        printer->Print(vars, "namespace $part$ {\n");
+      }
+      printer->Print(vars, "\n");
+    }
+  }
+  return output;
+}
+
+void PrintHeaderClientMethodInterfaces(
+    grpc_generator::Printer *printer, const grpc_generator::Method *method,
+    std::map<grpc::string, grpc::string> *vars, bool is_public) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type_name();
+  (*vars)["Response"] = method->output_type_name();
+
+  struct {
+    grpc::string prefix;
+    grpc::string method_params;  // extra arguments to method
+    grpc::string raw_args;       // extra arguments to raw version of method
+  } async_prefixes[] = {{"Async", ", void* tag", ", tag"},
+                        {"PrepareAsync", "", ""}};
+
+  if (is_public) {
+    if (method->NoStreaming()) {
+      printer->Print(
+          *vars,
+          "virtual ::grpc::Status $Method$(::grpc::ClientContext* context, "
+          "const $Request$& request, $Response$* response) = 0;\n");
+      for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        printer->Print(
+            *vars,
+            "std::unique_ptr< "
+            "::grpc::ClientAsyncResponseReaderInterface< $Response$>> "
+            "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
+            "const $Request$& request, "
+            "::grpc::CompletionQueue* cq) {\n");
+        printer->Indent();
+        printer->Print(
+            *vars,
+            "return std::unique_ptr< "
+            "::grpc::ClientAsyncResponseReaderInterface< $Response$>>("
+            "$AsyncPrefix$$Method$Raw(context, request, cq));\n");
+        printer->Outdent();
+        printer->Print("}\n");
+      }
+    } else if (ClientOnlyStreaming(method)) {
+      printer->Print(
+          *vars,
+          "std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
+          " $Method$("
+          "::grpc::ClientContext* context, $Response$* response) {\n");
+      printer->Indent();
+      printer->Print(
+          *vars,
+          "return std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
+          "($Method$Raw(context, response));\n");
+      printer->Outdent();
+      printer->Print("}\n");
+      for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+        (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
+        printer->Print(
+            *vars,
+            "std::unique_ptr< ::grpc::ClientAsyncWriterInterface< $Request$>>"
+            " $AsyncPrefix$$Method$(::grpc::ClientContext* context, "
+            "$Response$* "
+            "response, "
+            "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
+        printer->Indent();
+        printer->Print(*vars,
+                       "return std::unique_ptr< "
+                       "::grpc::ClientAsyncWriterInterface< $Request$>>("
+                       "$AsyncPrefix$$Method$Raw(context, response, "
+                       "cq$AsyncRawArgs$));\n");
+        printer->Outdent();
+        printer->Print("}\n");
+      }
+    } else if (ServerOnlyStreaming(method)) {
+      printer->Print(
+          *vars,
+          "std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
+          " $Method$(::grpc::ClientContext* context, const $Request$& request)"
+          " {\n");
+      printer->Indent();
+      printer->Print(
+          *vars,
+          "return std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
+          "($Method$Raw(context, request));\n");
+      printer->Outdent();
+      printer->Print("}\n");
+      for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+        (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
+        printer->Print(
+            *vars,
+            "std::unique_ptr< ::grpc::ClientAsyncReaderInterface< $Response$>> "
+            "$AsyncPrefix$$Method$("
+            "::grpc::ClientContext* context, const $Request$& request, "
+            "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
+        printer->Indent();
+        printer->Print(
+            *vars,
+            "return std::unique_ptr< "
+            "::grpc::ClientAsyncReaderInterface< $Response$>>("
+            "$AsyncPrefix$$Method$Raw(context, request, cq$AsyncRawArgs$));\n");
+        printer->Outdent();
+        printer->Print("}\n");
+      }
+    } else if (method->BidiStreaming()) {
+      printer->Print(*vars,
+                     "std::unique_ptr< ::grpc::ClientReaderWriterInterface< "
+                     "$Request$, $Response$>> "
+                     "$Method$(::grpc::ClientContext* context) {\n");
+      printer->Indent();
+      printer->Print(
+          *vars,
+          "return std::unique_ptr< "
+          "::grpc::ClientReaderWriterInterface< $Request$, $Response$>>("
+          "$Method$Raw(context));\n");
+      printer->Outdent();
+      printer->Print("}\n");
+      for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+        (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
+        printer->Print(
+            *vars,
+            "std::unique_ptr< "
+            "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>> "
+            "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
+            "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
+        printer->Indent();
+        printer->Print(
+            *vars,
+            "return std::unique_ptr< "
+            "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>>("
+            "$AsyncPrefix$$Method$Raw(context, cq$AsyncRawArgs$));\n");
+        printer->Outdent();
+        printer->Print("}\n");
+      }
+    }
+  } else {
+    if (method->NoStreaming()) {
+      for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        printer->Print(
+            *vars,
+            "virtual ::grpc::ClientAsyncResponseReaderInterface< $Response$>* "
+            "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
+            "const $Request$& request, "
+            "::grpc::CompletionQueue* cq) = 0;\n");
+      }
+    } else if (ClientOnlyStreaming(method)) {
+      printer->Print(
+          *vars,
+          "virtual ::grpc::ClientWriterInterface< $Request$>*"
+          " $Method$Raw("
+          "::grpc::ClientContext* context, $Response$* response) = 0;\n");
+      for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+        printer->Print(
+            *vars,
+            "virtual ::grpc::ClientAsyncWriterInterface< $Request$>*"
+            " $AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
+            "$Response$* response, "
+            "::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n");
+      }
+    } else if (ServerOnlyStreaming(method)) {
+      printer->Print(
+          *vars,
+          "virtual ::grpc::ClientReaderInterface< $Response$>* "
+          "$Method$Raw("
+          "::grpc::ClientContext* context, const $Request$& request) = 0;\n");
+      for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+        printer->Print(
+            *vars,
+            "virtual ::grpc::ClientAsyncReaderInterface< $Response$>* "
+            "$AsyncPrefix$$Method$Raw("
+            "::grpc::ClientContext* context, const $Request$& request, "
+            "::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n");
+      }
+    } else if (method->BidiStreaming()) {
+      printer->Print(*vars,
+                     "virtual ::grpc::ClientReaderWriterInterface< $Request$, "
+                     "$Response$>* "
+                     "$Method$Raw(::grpc::ClientContext* context) = 0;\n");
+      for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+        printer->Print(
+            *vars,
+            "virtual ::grpc::ClientAsyncReaderWriterInterface< "
+            "$Request$, $Response$>* "
+            "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
+            "::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n");
+      }
+    }
+  }
+}
+
+void PrintHeaderClientMethod(grpc_generator::Printer *printer,
+                             const grpc_generator::Method *method,
+                             std::map<grpc::string, grpc::string> *vars,
+                             bool is_public) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type_name();
+  (*vars)["Response"] = method->output_type_name();
+  struct {
+    grpc::string prefix;
+    grpc::string method_params;  // extra arguments to method
+    grpc::string raw_args;       // extra arguments to raw version of method
+  } async_prefixes[] = {{"Async", ", void* tag", ", tag"},
+                        {"PrepareAsync", "", ""}};
+
+  if (is_public) {
+    if (method->NoStreaming()) {
+      printer->Print(
+          *vars,
+          "::grpc::Status $Method$(::grpc::ClientContext* context, "
+          "const $Request$& request, $Response$* response) override;\n");
+    for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        printer->Print(
+            *vars,
+            "std::unique_ptr< ::grpc::ClientAsyncResponseReader< $Response$>> "
+            "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
+            "const $Request$& request, "
+            "::grpc::CompletionQueue* cq) {\n");
+        printer->Indent();
+        printer->Print(*vars,
+                       "return std::unique_ptr< "
+                       "::grpc::ClientAsyncResponseReader< $Response$>>("
+                       "$AsyncPrefix$$Method$Raw(context, request, cq));\n");
+        printer->Outdent();
+        printer->Print("}\n");
+      }
+    } else if (ClientOnlyStreaming(method)) {
+      printer->Print(
+          *vars,
+          "std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
+          " $Method$("
+          "::grpc::ClientContext* context, $Response$* response) {\n");
+      printer->Indent();
+      printer->Print(*vars,
+                     "return std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
+                     "($Method$Raw(context, response));\n");
+      printer->Outdent();
+      printer->Print("}\n");
+      for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+        (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
+        printer->Print(*vars,
+                       "std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>"
+                       " $AsyncPrefix$$Method$(::grpc::ClientContext* context, "
+                       "$Response$* response, "
+                       "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
+        printer->Indent();
+        printer->Print(
+            *vars,
+            "return std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>("
+            "$AsyncPrefix$$Method$Raw(context, response, "
+            "cq$AsyncRawArgs$));\n");
+        printer->Outdent();
+        printer->Print("}\n");
+      }
+    } else if (ServerOnlyStreaming(method)) {
+      printer->Print(
+          *vars,
+          "std::unique_ptr< ::grpc::ClientReader< $Response$>>"
+          " $Method$(::grpc::ClientContext* context, const $Request$& request)"
+          " {\n");
+      printer->Indent();
+      printer->Print(
+          *vars,
+          "return std::unique_ptr< ::grpc::ClientReader< $Response$>>"
+          "($Method$Raw(context, request));\n");
+      printer->Outdent();
+      printer->Print("}\n");
+      for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+        (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
+        printer->Print(
+            *vars,
+            "std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>> "
+            "$AsyncPrefix$$Method$("
+            "::grpc::ClientContext* context, const $Request$& request, "
+            "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
+        printer->Indent();
+        printer->Print(
+            *vars,
+            "return std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>>("
+            "$AsyncPrefix$$Method$Raw(context, request, cq$AsyncRawArgs$));\n");
+        printer->Outdent();
+        printer->Print("}\n");
+      }
+    } else if (method->BidiStreaming()) {
+      printer->Print(
+          *vars,
+          "std::unique_ptr< ::grpc::ClientReaderWriter< $Request$, $Response$>>"
+          " $Method$(::grpc::ClientContext* context) {\n");
+      printer->Indent();
+      printer->Print(*vars,
+                     "return std::unique_ptr< "
+                     "::grpc::ClientReaderWriter< $Request$, $Response$>>("
+                     "$Method$Raw(context));\n");
+      printer->Outdent();
+      printer->Print("}\n");
+      for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+        (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
+        printer->Print(*vars,
+                       "std::unique_ptr<  ::grpc::ClientAsyncReaderWriter< "
+                       "$Request$, $Response$>> "
+                       "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
+                       "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
+        printer->Indent();
+        printer->Print(
+            *vars,
+            "return std::unique_ptr< "
+            "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>>("
+            "$AsyncPrefix$$Method$Raw(context, cq$AsyncRawArgs$));\n");
+        printer->Outdent();
+        printer->Print("}\n");
+      }
+    }
+  } else {
+    if (method->NoStreaming()) {
+      for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        printer->Print(
+            *vars,
+            "::grpc::ClientAsyncResponseReader< $Response$>* "
+            "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
+            "const $Request$& request, "
+            "::grpc::CompletionQueue* cq) override;\n");
+      }
+    } else if (ClientOnlyStreaming(method)) {
+      printer->Print(*vars,
+                     "::grpc::ClientWriter< $Request$>* $Method$Raw("
+                     "::grpc::ClientContext* context, $Response$* response) "
+                     "override;\n");
+    for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+        (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
+        printer->Print(
+            *vars,
+            "::grpc::ClientAsyncWriter< $Request$>* $AsyncPrefix$$Method$Raw("
+            "::grpc::ClientContext* context, $Response$* response, "
+            "::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n");
+      }
+    } else if (ServerOnlyStreaming(method)) {
+      printer->Print(*vars,
+                     "::grpc::ClientReader< $Response$>* $Method$Raw("
+                     "::grpc::ClientContext* context, const $Request$& request)"
+                     " override;\n");
+    for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+        (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
+        printer->Print(
+            *vars,
+            "::grpc::ClientAsyncReader< $Response$>* $AsyncPrefix$$Method$Raw("
+            "::grpc::ClientContext* context, const $Request$& request, "
+            "::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n");
+      }
+    } else if (method->BidiStreaming()) {
+      printer->Print(*vars,
+                     "::grpc::ClientReaderWriter< $Request$, $Response$>* "
+                     "$Method$Raw(::grpc::ClientContext* context) override;\n");
+      for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+        (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
+        printer->Print(
+            *vars,
+            "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
+            "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
+            "::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n");
+      }
+    }
+  }
+}
+
+void PrintHeaderClientMethodData(grpc_generator::Printer *printer,
+                                 const grpc_generator::Method *method,
+                                 std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Method"] = method->name();
+  printer->Print(*vars,
+                 "const ::grpc::internal::RpcMethod rpcmethod_$Method$_;\n");
+}
+
+void PrintHeaderServerMethodSync(grpc_generator::Printer *printer,
+                                 const grpc_generator::Method *method,
+                                 std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type_name();
+  (*vars)["Response"] = method->output_type_name();
+  printer->Print(method->GetLeadingComments("//").c_str());
+  if (method->NoStreaming()) {
+    printer->Print(*vars,
+                   "virtual ::grpc::Status $Method$("
+                   "::grpc::ServerContext* context, const $Request$* request, "
+                   "$Response$* response);\n");
+  } else if (ClientOnlyStreaming(method)) {
+    printer->Print(*vars,
+                   "virtual ::grpc::Status $Method$("
+                   "::grpc::ServerContext* context, "
+                   "::grpc::ServerReader< $Request$>* reader, "
+                   "$Response$* response);\n");
+  } else if (ServerOnlyStreaming(method)) {
+    printer->Print(*vars,
+                   "virtual ::grpc::Status $Method$("
+                   "::grpc::ServerContext* context, const $Request$* request, "
+                   "::grpc::ServerWriter< $Response$>* writer);\n");
+  } else if (method->BidiStreaming()) {
+    printer->Print(
+        *vars,
+        "virtual ::grpc::Status $Method$("
+        "::grpc::ServerContext* context, "
+        "::grpc::ServerReaderWriter< $Response$, $Request$>* stream);"
+        "\n");
+  }
+  printer->Print(method->GetTrailingComments("//").c_str());
+}
+
+void PrintHeaderServerMethodAsync(grpc_generator::Printer *printer,
+                                  const grpc_generator::Method *method,
+                                  std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type_name();
+  (*vars)["Response"] = method->output_type_name();
+  printer->Print(*vars, "template <class BaseClass>\n");
+  printer->Print(*vars,
+                 "class WithAsyncMethod_$Method$ : public BaseClass {\n");
+  printer->Print(
+      " private:\n"
+      "  void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
+  printer->Print(" public:\n");
+  printer->Indent();
+  printer->Print(*vars,
+                 "WithAsyncMethod_$Method$() {\n"
+                 "  ::grpc::Service::MarkMethodAsync($Idx$);\n"
+                 "}\n");
+  printer->Print(*vars,
+                 "~WithAsyncMethod_$Method$() override {\n"
+                 "  BaseClassMustBeDerivedFromService(this);\n"
+                 "}\n");
+  if (method->NoStreaming()) {
+    printer->Print(
+        *vars,
+        "// disable synchronous version of this method\n"
+        "::grpc::Status $Method$("
+        "::grpc::ServerContext* context, const $Request$* request, "
+        "$Response$* response) final override {\n"
+        "  abort();\n"
+        "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+        "}\n");
+    printer->Print(
+        *vars,
+        "void Request$Method$("
+        "::grpc::ServerContext* context, $Request$* request, "
+        "::grpc::ServerAsyncResponseWriter< $Response$>* response, "
+        "::grpc::CompletionQueue* new_call_cq, "
+        "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
+    printer->Print(*vars,
+                   "  ::grpc::Service::RequestAsyncUnary($Idx$, context, "
+                   "request, response, new_call_cq, notification_cq, tag);\n");
+    printer->Print("}\n");
+  } else if (ClientOnlyStreaming(method)) {
+    printer->Print(
+        *vars,
+        "// disable synchronous version of this method\n"
+        "::grpc::Status $Method$("
+        "::grpc::ServerContext* context, "
+        "::grpc::ServerReader< $Request$>* reader, "
+        "$Response$* response) final override {\n"
+        "  abort();\n"
+        "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+        "}\n");
+    printer->Print(
+        *vars,
+        "void Request$Method$("
+        "::grpc::ServerContext* context, "
+        "::grpc::ServerAsyncReader< $Response$, $Request$>* reader, "
+        "::grpc::CompletionQueue* new_call_cq, "
+        "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
+    printer->Print(*vars,
+                   "  ::grpc::Service::RequestAsyncClientStreaming($Idx$, "
+                   "context, reader, new_call_cq, notification_cq, tag);\n");
+    printer->Print("}\n");
+  } else if (ServerOnlyStreaming(method)) {
+    printer->Print(
+        *vars,
+        "// disable synchronous version of this method\n"
+        "::grpc::Status $Method$("
+        "::grpc::ServerContext* context, const $Request$* request, "
+        "::grpc::ServerWriter< $Response$>* writer) final override "
+        "{\n"
+        "  abort();\n"
+        "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+        "}\n");
+    printer->Print(
+        *vars,
+        "void Request$Method$("
+        "::grpc::ServerContext* context, $Request$* request, "
+        "::grpc::ServerAsyncWriter< $Response$>* writer, "
+        "::grpc::CompletionQueue* new_call_cq, "
+        "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
+    printer->Print(
+        *vars,
+        "  ::grpc::Service::RequestAsyncServerStreaming($Idx$, "
+        "context, request, writer, new_call_cq, notification_cq, tag);\n");
+    printer->Print("}\n");
+  } else if (method->BidiStreaming()) {
+    printer->Print(
+        *vars,
+        "// disable synchronous version of this method\n"
+        "::grpc::Status $Method$("
+        "::grpc::ServerContext* context, "
+        "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) "
+        "final override {\n"
+        "  abort();\n"
+        "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+        "}\n");
+    printer->Print(
+        *vars,
+        "void Request$Method$("
+        "::grpc::ServerContext* context, "
+        "::grpc::ServerAsyncReaderWriter< $Response$, $Request$>* stream, "
+        "::grpc::CompletionQueue* new_call_cq, "
+        "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
+    printer->Print(*vars,
+                   "  ::grpc::Service::RequestAsyncBidiStreaming($Idx$, "
+                   "context, stream, new_call_cq, notification_cq, tag);\n");
+    printer->Print("}\n");
+  }
+  printer->Outdent();
+  printer->Print(*vars, "};\n");
+}
+
+void PrintHeaderServerMethodStreamedUnary(
+    grpc_generator::Printer *printer, const grpc_generator::Method *method,
+    std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type_name();
+  (*vars)["Response"] = method->output_type_name();
+  if (method->NoStreaming()) {
+    printer->Print(*vars, "template <class BaseClass>\n");
+    printer->Print(*vars,
+                   "class WithStreamedUnaryMethod_$Method$ : "
+                   "public BaseClass {\n");
+    printer->Print(
+        " private:\n"
+        "  void BaseClassMustBeDerivedFromService(const Service *service) "
+        "{}\n");
+    printer->Print(" public:\n");
+    printer->Indent();
+    printer->Print(*vars,
+                   "WithStreamedUnaryMethod_$Method$() {\n"
+                   "  ::grpc::Service::MarkMethodStreamed($Idx$,\n"
+                   "    new ::grpc::internal::StreamedUnaryHandler< $Request$, "
+                   "$Response$>(std::bind"
+                   "(&WithStreamedUnaryMethod_$Method$<BaseClass>::"
+                   "Streamed$Method$, this, std::placeholders::_1, "
+                   "std::placeholders::_2)));\n"
+                   "}\n");
+    printer->Print(*vars,
+                   "~WithStreamedUnaryMethod_$Method$() override {\n"
+                   "  BaseClassMustBeDerivedFromService(this);\n"
+                   "}\n");
+    printer->Print(
+        *vars,
+        "// disable regular version of this method\n"
+        "::grpc::Status $Method$("
+        "::grpc::ServerContext* context, const $Request$* request, "
+        "$Response$* response) final override {\n"
+        "  abort();\n"
+        "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+        "}\n");
+    printer->Print(*vars,
+                   "// replace default version of method with streamed unary\n"
+                   "virtual ::grpc::Status Streamed$Method$("
+                   "::grpc::ServerContext* context, "
+                   "::grpc::ServerUnaryStreamer< "
+                   "$Request$,$Response$>* server_unary_streamer)"
+                   " = 0;\n");
+    printer->Outdent();
+    printer->Print(*vars, "};\n");
+  }
+}
+
+void PrintHeaderServerMethodSplitStreaming(
+    grpc_generator::Printer *printer, const grpc_generator::Method *method,
+    std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type_name();
+  (*vars)["Response"] = method->output_type_name();
+  if (ServerOnlyStreaming(method)) {
+    printer->Print(*vars, "template <class BaseClass>\n");
+    printer->Print(*vars,
+                   "class WithSplitStreamingMethod_$Method$ : "
+                   "public BaseClass {\n");
+    printer->Print(
+        " private:\n"
+        "  void BaseClassMustBeDerivedFromService(const Service *service) "
+        "{}\n");
+    printer->Print(" public:\n");
+    printer->Indent();
+    printer->Print(
+        *vars,
+        "WithSplitStreamingMethod_$Method$() {\n"
+        "  ::grpc::Service::MarkMethodStreamed($Idx$,\n"
+        "    new ::grpc::internal::SplitServerStreamingHandler< $Request$, "
+        "$Response$>(std::bind"
+        "(&WithSplitStreamingMethod_$Method$<BaseClass>::"
+        "Streamed$Method$, this, std::placeholders::_1, "
+        "std::placeholders::_2)));\n"
+        "}\n");
+    printer->Print(*vars,
+                   "~WithSplitStreamingMethod_$Method$() override {\n"
+                   "  BaseClassMustBeDerivedFromService(this);\n"
+                   "}\n");
+    printer->Print(
+        *vars,
+        "// disable regular version of this method\n"
+        "::grpc::Status $Method$("
+        "::grpc::ServerContext* context, const $Request$* request, "
+        "::grpc::ServerWriter< $Response$>* writer) final override "
+        "{\n"
+        "  abort();\n"
+        "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+        "}\n");
+    printer->Print(*vars,
+                   "// replace default version of method with split streamed\n"
+                   "virtual ::grpc::Status Streamed$Method$("
+                   "::grpc::ServerContext* context, "
+                   "::grpc::ServerSplitStreamer< "
+                   "$Request$,$Response$>* server_split_streamer)"
+                   " = 0;\n");
+    printer->Outdent();
+    printer->Print(*vars, "};\n");
+  }
+}
+
+void PrintHeaderServerMethodGeneric(
+    grpc_generator::Printer *printer, const grpc_generator::Method *method,
+    std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type_name();
+  (*vars)["Response"] = method->output_type_name();
+  printer->Print(*vars, "template <class BaseClass>\n");
+  printer->Print(*vars,
+                 "class WithGenericMethod_$Method$ : public BaseClass {\n");
+  printer->Print(
+      " private:\n"
+      "  void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
+  printer->Print(" public:\n");
+  printer->Indent();
+  printer->Print(*vars,
+                 "WithGenericMethod_$Method$() {\n"
+                 "  ::grpc::Service::MarkMethodGeneric($Idx$);\n"
+                 "}\n");
+  printer->Print(*vars,
+                 "~WithGenericMethod_$Method$() override {\n"
+                 "  BaseClassMustBeDerivedFromService(this);\n"
+                 "}\n");
+  if (method->NoStreaming()) {
+    printer->Print(
+        *vars,
+        "// disable synchronous version of this method\n"
+        "::grpc::Status $Method$("
+        "::grpc::ServerContext* context, const $Request$* request, "
+        "$Response$* response) final override {\n"
+        "  abort();\n"
+        "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+        "}\n");
+  } else if (ClientOnlyStreaming(method)) {
+    printer->Print(
+        *vars,
+        "// disable synchronous version of this method\n"
+        "::grpc::Status $Method$("
+        "::grpc::ServerContext* context, "
+        "::grpc::ServerReader< $Request$>* reader, "
+        "$Response$* response) final override {\n"
+        "  abort();\n"
+        "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+        "}\n");
+  } else if (ServerOnlyStreaming(method)) {
+    printer->Print(
+        *vars,
+        "// disable synchronous version of this method\n"
+        "::grpc::Status $Method$("
+        "::grpc::ServerContext* context, const $Request$* request, "
+        "::grpc::ServerWriter< $Response$>* writer) final override "
+        "{\n"
+        "  abort();\n"
+        "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+        "}\n");
+  } else if (method->BidiStreaming()) {
+    printer->Print(
+        *vars,
+        "// disable synchronous version of this method\n"
+        "::grpc::Status $Method$("
+        "::grpc::ServerContext* context, "
+        "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) "
+        "final override {\n"
+        "  abort();\n"
+        "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+        "}\n");
+  }
+  printer->Outdent();
+  printer->Print(*vars, "};\n");
+}
+
+void PrintHeaderService(grpc_generator::Printer *printer,
+                        const grpc_generator::Service *service,
+                        std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Service"] = service->name();
+
+  printer->Print(service->GetLeadingComments("//").c_str());
+  printer->Print(*vars,
+                 "class $Service$ final {\n"
+                 " public:\n");
+  printer->Indent();
+
+  // Service metadata
+  printer->Print(*vars,
+                 "static constexpr char const* service_full_name() {\n"
+                 "  return \"$Package$$Service$\";\n"
+                 "}\n");
+
+  // Client side
+  printer->Print(
+      "class StubInterface {\n"
+      " public:\n");
+  printer->Indent();
+  printer->Print("virtual ~StubInterface() {}\n");
+  for (int i = 0; i < service->method_count(); ++i) {
+    printer->Print(service->method(i)->GetLeadingComments("//").c_str());
+    PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), vars,
+                                      true);
+    printer->Print(service->method(i)->GetTrailingComments("//").c_str());
+  }
+  printer->Outdent();
+  printer->Print("private:\n");
+  printer->Indent();
+  for (int i = 0; i < service->method_count(); ++i) {
+    PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), vars,
+                                      false);
+  }
+  printer->Outdent();
+  printer->Print("};\n");
+  printer->Print(
+      "class Stub final : public StubInterface"
+      " {\n public:\n");
+  printer->Indent();
+  printer->Print(
+      "Stub(const std::shared_ptr< ::grpc::ChannelInterface>& "
+      "channel);\n");
+  for (int i = 0; i < service->method_count(); ++i) {
+    PrintHeaderClientMethod(printer, service->method(i).get(), vars, true);
+  }
+  printer->Outdent();
+  printer->Print("\n private:\n");
+  printer->Indent();
+  printer->Print("std::shared_ptr< ::grpc::ChannelInterface> channel_;\n");
+  for (int i = 0; i < service->method_count(); ++i) {
+    PrintHeaderClientMethod(printer, service->method(i).get(), vars, false);
+  }
+  for (int i = 0; i < service->method_count(); ++i) {
+    PrintHeaderClientMethodData(printer, service->method(i).get(), vars);
+  }
+  printer->Outdent();
+  printer->Print("};\n");
+  printer->Print(
+      "static std::unique_ptr<Stub> NewStub(const std::shared_ptr< "
+      "::grpc::ChannelInterface>& channel, "
+      "const ::grpc::StubOptions& options = ::grpc::StubOptions());\n");
+
+  printer->Print("\n");
+
+  // Server side - base
+  printer->Print(
+      "class Service : public ::grpc::Service {\n"
+      " public:\n");
+  printer->Indent();
+  printer->Print("Service();\n");
+  printer->Print("virtual ~Service();\n");
+  for (int i = 0; i < service->method_count(); ++i) {
+    PrintHeaderServerMethodSync(printer, service->method(i).get(), vars);
+  }
+  printer->Outdent();
+  printer->Print("};\n");
+
+  // Server side - Asynchronous
+  for (int i = 0; i < service->method_count(); ++i) {
+    (*vars)["Idx"] = as_string(i);
+    PrintHeaderServerMethodAsync(printer, service->method(i).get(), vars);
+  }
+
+  printer->Print("typedef ");
+
+  for (int i = 0; i < service->method_count(); ++i) {
+    (*vars)["method_name"] = service->method(i).get()->name();
+    printer->Print(*vars, "WithAsyncMethod_$method_name$<");
+  }
+  printer->Print("Service");
+  for (int i = 0; i < service->method_count(); ++i) {
+    printer->Print(" >");
+  }
+  printer->Print(" AsyncService;\n");
+
+  // Server side - Generic
+  for (int i = 0; i < service->method_count(); ++i) {
+    (*vars)["Idx"] = as_string(i);
+    PrintHeaderServerMethodGeneric(printer, service->method(i).get(), vars);
+  }
+
+  // Server side - Streamed Unary
+  for (int i = 0; i < service->method_count(); ++i) {
+    (*vars)["Idx"] = as_string(i);
+    PrintHeaderServerMethodStreamedUnary(printer, service->method(i).get(),
+                                         vars);
+  }
+
+  printer->Print("typedef ");
+  for (int i = 0; i < service->method_count(); ++i) {
+    (*vars)["method_name"] = service->method(i).get()->name();
+    if (service->method(i)->NoStreaming()) {
+      printer->Print(*vars, "WithStreamedUnaryMethod_$method_name$<");
+    }
+  }
+  printer->Print("Service");
+  for (int i = 0; i < service->method_count(); ++i) {
+    if (service->method(i)->NoStreaming()) {
+      printer->Print(" >");
+    }
+  }
+  printer->Print(" StreamedUnaryService;\n");
+
+  // Server side - controlled server-side streaming
+  for (int i = 0; i < service->method_count(); ++i) {
+    (*vars)["Idx"] = as_string(i);
+    PrintHeaderServerMethodSplitStreaming(printer, service->method(i).get(),
+                                          vars);
+  }
+
+  printer->Print("typedef ");
+  for (int i = 0; i < service->method_count(); ++i) {
+    (*vars)["method_name"] = service->method(i).get()->name();
+    auto method = service->method(i);
+    if (ServerOnlyStreaming(method.get())) {
+      printer->Print(*vars, "WithSplitStreamingMethod_$method_name$<");
+    }
+  }
+  printer->Print("Service");
+  for (int i = 0; i < service->method_count(); ++i) {
+    auto method = service->method(i);
+    if (ServerOnlyStreaming(method.get())) {
+      printer->Print(" >");
+    }
+  }
+  printer->Print(" SplitStreamedService;\n");
+
+  // Server side - typedef for controlled both unary and server-side streaming
+  printer->Print("typedef ");
+  for (int i = 0; i < service->method_count(); ++i) {
+    (*vars)["method_name"] = service->method(i).get()->name();
+    auto method = service->method(i);
+    if (ServerOnlyStreaming(method.get())) {
+      printer->Print(*vars, "WithSplitStreamingMethod_$method_name$<");
+    }
+    if (service->method(i)->NoStreaming()) {
+      printer->Print(*vars, "WithStreamedUnaryMethod_$method_name$<");
+    }
+  }
+  printer->Print("Service");
+  for (int i = 0; i < service->method_count(); ++i) {
+    auto method = service->method(i);
+    if (service->method(i)->NoStreaming() ||
+        ServerOnlyStreaming(method.get())) {
+      printer->Print(" >");
+    }
+  }
+  printer->Print(" StreamedService;\n");
+
+  printer->Outdent();
+  printer->Print("};\n");
+  printer->Print(service->GetTrailingComments("//").c_str());
+}
+
+grpc::string GetHeaderServices(grpc_generator::File *file,
+                               const Parameters &params) {
+  grpc::string output;
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    auto printer = file->CreatePrinter(&output);
+    std::map<grpc::string, grpc::string> vars;
+    // Package string is empty or ends with a dot. It is used to fully qualify
+    // method names.
+    vars["Package"] = file->package();
+    if (!file->package().empty()) {
+      vars["Package"].append(".");
+    }
+
+    if (!params.services_namespace.empty()) {
+      vars["services_namespace"] = params.services_namespace;
+      printer->Print(vars, "\nnamespace $services_namespace$ {\n\n");
+    }
+
+    for (int i = 0; i < file->service_count(); ++i) {
+      PrintHeaderService(printer.get(), file->service(i).get(), &vars);
+      printer->Print("\n");
+    }
+
+    if (!params.services_namespace.empty()) {
+      printer->Print(vars, "}  // namespace $services_namespace$\n\n");
+    }
+  }
+  return output;
+}
+
+grpc::string GetHeaderEpilogue(grpc_generator::File *file,
+                               const Parameters & /*params*/) {
+  grpc::string output;
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    auto printer = file->CreatePrinter(&output);
+    std::map<grpc::string, grpc::string> vars;
+
+    vars["filename"] = file->filename();
+    vars["filename_identifier"] = FilenameIdentifier(file->filename());
+
+    if (!file->package().empty()) {
+      std::vector<grpc::string> parts = file->package_parts();
+
+      for (auto part = parts.rbegin(); part != parts.rend(); part++) {
+        vars["part"] = *part;
+        printer->Print(vars, "}  // namespace $part$\n");
+      }
+      printer->Print(vars, "\n");
+    }
+
+    printer->Print(vars, "\n");
+    printer->Print(vars, "#endif  // GRPC_$filename_identifier$__INCLUDED\n");
+
+    printer->Print(file->GetTrailingComments("//").c_str());
+  }
+  return output;
+}
+
+grpc::string GetSourcePrologue(grpc_generator::File *file,
+                               const Parameters & /*params*/) {
+  grpc::string output;
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    auto printer = file->CreatePrinter(&output);
+    std::map<grpc::string, grpc::string> vars;
+
+    vars["filename"] = file->filename();
+    vars["filename_base"] = file->filename_without_ext();
+    vars["message_header_ext"] = message_header_ext();
+    vars["service_header_ext"] = service_header_ext();
+
+    printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
+    printer->Print(vars,
+                   "// If you make any local change, they will be lost.\n");
+    printer->Print(vars, "// source: $filename$\n\n");
+
+    printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
+    printer->Print(vars, "#include \"$filename_base$$service_header_ext$\"\n");
+    printer->Print(vars, "\n");
+  }
+  return output;
+}
+
+grpc::string GetSourceIncludes(grpc_generator::File *file,
+                               const Parameters &params) {
+  grpc::string output;
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    auto printer = file->CreatePrinter(&output);
+    std::map<grpc::string, grpc::string> vars;
+
+    static const char *headers_strs[] = {
+        "grpc++/impl/codegen/async_stream.h",
+        "grpc++/impl/codegen/async_unary_call.h",
+        "grpc++/impl/codegen/channel_interface.h",
+        "grpc++/impl/codegen/client_unary_call.h",
+        "grpc++/impl/codegen/method_handler_impl.h",
+        "grpc++/impl/codegen/rpc_service_method.h",
+        "grpc++/impl/codegen/service_type.h",
+        "grpc++/impl/codegen/sync_stream.h"};
+    std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
+    PrintIncludes(printer.get(), headers, params);
+
+    if (!file->package().empty()) {
+      std::vector<grpc::string> parts = file->package_parts();
+
+      for (auto part = parts.begin(); part != parts.end(); part++) {
+        vars["part"] = *part;
+        printer->Print(vars, "namespace $part$ {\n");
+      }
+    }
+
+    printer->Print(vars, "\n");
+  }
+  return output;
+}
+
+void PrintSourceClientMethod(grpc_generator::Printer *printer,
+                             const grpc_generator::Method *method,
+                             std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type_name();
+  (*vars)["Response"] = method->output_type_name();
+  struct {
+    grpc::string prefix;
+    grpc::string start;          // bool literal expressed as string
+    grpc::string method_params;  // extra arguments to method
+    grpc::string create_args;    // extra arguments to creator
+  } async_prefixes[] = {{"Async", "true", ", void* tag", ", tag"},
+                        {"PrepareAsync", "false", "", ", nullptr"}};
+  if (method->NoStreaming()) {
+    printer->Print(*vars,
+                   "::grpc::Status $ns$$Service$::Stub::$Method$("
+                   "::grpc::ClientContext* context, "
+                   "const $Request$& request, $Response$* response) {\n");
+    printer->Print(*vars,
+                   "  return ::grpc::internal::BlockingUnaryCall"
+                   "(channel_.get(), rpcmethod_$Method$_, "
+                   "context, request, response);\n}\n\n");
+    for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+      auto& async_prefix = async_prefixes[i];
+      (*vars)["AsyncPrefix"] = async_prefix.prefix;
+      (*vars)["AsyncStart"] = async_prefix.start;
+      printer->Print(*vars,
+                     "::grpc::ClientAsyncResponseReader< $Response$>* "
+                     "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw(::grpc::"
+                     "ClientContext* context, "
+                     "const $Request$& request, "
+                     "::grpc::CompletionQueue* cq) {\n");
+      printer->Print(
+          *vars,
+          "  return "
+          "::grpc::internal::ClientAsyncResponseReaderFactory< $Response$>"
+          "::Create(channel_.get(), cq, "
+          "rpcmethod_$Method$_, "
+          "context, request, $AsyncStart$);\n"
+          "}\n\n");
+    }
+  } else if (ClientOnlyStreaming(method)) {
+    printer->Print(*vars,
+                   "::grpc::ClientWriter< $Request$>* "
+                   "$ns$$Service$::Stub::$Method$Raw("
+                   "::grpc::ClientContext* context, $Response$* response) {\n");
+    printer->Print(
+        *vars,
+        "  return ::grpc::internal::ClientWriterFactory< $Request$>::Create("
+        "channel_.get(), "
+        "rpcmethod_$Method$_, "
+        "context, response);\n"
+        "}\n\n");
+    for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+      auto& async_prefix = async_prefixes[i];
+      (*vars)["AsyncPrefix"] = async_prefix.prefix;
+      (*vars)["AsyncStart"] = async_prefix.start;
+      (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+      (*vars)["AsyncCreateArgs"] = async_prefix.create_args;
+      printer->Print(*vars,
+                     "::grpc::ClientAsyncWriter< $Request$>* "
+                     "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw("
+                     "::grpc::ClientContext* context, $Response$* response, "
+                     "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
+      printer->Print(
+          *vars,
+          "  return ::grpc::internal::ClientAsyncWriterFactory< $Request$>"
+          "::Create(channel_.get(), cq, "
+          "rpcmethod_$Method$_, "
+          "context, response, $AsyncStart$$AsyncCreateArgs$);\n"
+          "}\n\n");
+    }
+  } else if (ServerOnlyStreaming(method)) {
+    printer->Print(
+        *vars,
+        "::grpc::ClientReader< $Response$>* "
+        "$ns$$Service$::Stub::$Method$Raw("
+        "::grpc::ClientContext* context, const $Request$& request) {\n");
+    printer->Print(
+        *vars,
+        "  return ::grpc::internal::ClientReaderFactory< $Response$>::Create("
+        "channel_.get(), "
+        "rpcmethod_$Method$_, "
+        "context, request);\n"
+        "}\n\n");
+    for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+      auto& async_prefix = async_prefixes[i];
+      (*vars)["AsyncPrefix"] = async_prefix.prefix;
+      (*vars)["AsyncStart"] = async_prefix.start;
+      (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+      (*vars)["AsyncCreateArgs"] = async_prefix.create_args;
+      printer->Print(
+          *vars,
+          "::grpc::ClientAsyncReader< $Response$>* "
+          "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw("
+          "::grpc::ClientContext* context, const $Request$& request, "
+          "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
+      printer->Print(
+          *vars,
+          "  return ::grpc::internal::ClientAsyncReaderFactory< $Response$>"
+          "::Create(channel_.get(), cq, "
+          "rpcmethod_$Method$_, "
+          "context, request, $AsyncStart$$AsyncCreateArgs$);\n"
+          "}\n\n");
+    }
+  } else if (method->BidiStreaming()) {
+    printer->Print(
+        *vars,
+        "::grpc::ClientReaderWriter< $Request$, $Response$>* "
+        "$ns$$Service$::Stub::$Method$Raw(::grpc::ClientContext* context) {\n");
+    printer->Print(*vars,
+                   "  return ::grpc::internal::ClientReaderWriterFactory< "
+                   "$Request$, $Response$>::Create("
+                   "channel_.get(), "
+                   "rpcmethod_$Method$_, "
+                   "context);\n"
+                   "}\n\n");
+    for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+      auto& async_prefix = async_prefixes[i];
+      (*vars)["AsyncPrefix"] = async_prefix.prefix;
+      (*vars)["AsyncStart"] = async_prefix.start;
+      (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+      (*vars)["AsyncCreateArgs"] = async_prefix.create_args;
+      printer->Print(*vars,
+                     "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
+                     "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw(::grpc::"
+                     "ClientContext* context, "
+                     "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
+      printer->Print(*vars,
+                     "  return "
+                     "::grpc::internal::ClientAsyncReaderWriterFactory< "
+                     "$Request$, $Response$>::Create("
+                     "channel_.get(), cq, "
+                     "rpcmethod_$Method$_, "
+                     "context, $AsyncStart$$AsyncCreateArgs$);\n"
+                     "}\n\n");
+    }
+  }
+}
+
+void PrintSourceServerMethod(grpc_generator::Printer *printer,
+                             const grpc_generator::Method *method,
+                             std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type_name();
+  (*vars)["Response"] = method->output_type_name();
+  if (method->NoStreaming()) {
+    printer->Print(*vars,
+                   "::grpc::Status $ns$$Service$::Service::$Method$("
+                   "::grpc::ServerContext* context, "
+                   "const $Request$* request, $Response$* response) {\n");
+    printer->Print("  (void) context;\n");
+    printer->Print("  (void) request;\n");
+    printer->Print("  (void) response;\n");
+    printer->Print(
+        "  return ::grpc::Status("
+        "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
+    printer->Print("}\n\n");
+  } else if (ClientOnlyStreaming(method)) {
+    printer->Print(*vars,
+                   "::grpc::Status $ns$$Service$::Service::$Method$("
+                   "::grpc::ServerContext* context, "
+                   "::grpc::ServerReader< $Request$>* reader, "
+                   "$Response$* response) {\n");
+    printer->Print("  (void) context;\n");
+    printer->Print("  (void) reader;\n");
+    printer->Print("  (void) response;\n");
+    printer->Print(
+        "  return ::grpc::Status("
+        "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
+    printer->Print("}\n\n");
+  } else if (ServerOnlyStreaming(method)) {
+    printer->Print(*vars,
+                   "::grpc::Status $ns$$Service$::Service::$Method$("
+                   "::grpc::ServerContext* context, "
+                   "const $Request$* request, "
+                   "::grpc::ServerWriter< $Response$>* writer) {\n");
+    printer->Print("  (void) context;\n");
+    printer->Print("  (void) request;\n");
+    printer->Print("  (void) writer;\n");
+    printer->Print(
+        "  return ::grpc::Status("
+        "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
+    printer->Print("}\n\n");
+  } else if (method->BidiStreaming()) {
+    printer->Print(*vars,
+                   "::grpc::Status $ns$$Service$::Service::$Method$("
+                   "::grpc::ServerContext* context, "
+                   "::grpc::ServerReaderWriter< $Response$, $Request$>* "
+                   "stream) {\n");
+    printer->Print("  (void) context;\n");
+    printer->Print("  (void) stream;\n");
+    printer->Print(
+        "  return ::grpc::Status("
+        "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
+    printer->Print("}\n\n");
+  }
+}
+
+void PrintSourceService(grpc_generator::Printer *printer,
+                        const grpc_generator::Service *service,
+                        std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Service"] = service->name();
+
+  if (service->method_count() > 0) {
+    printer->Print(*vars,
+                   "static const char* $prefix$$Service$_method_names[] = {\n");
+    for (int i = 0; i < service->method_count(); ++i) {
+      (*vars)["Method"] = service->method(i).get()->name();
+      printer->Print(*vars, "  \"/$Package$$Service$/$Method$\",\n");
+    }
+    printer->Print(*vars, "};\n\n");
+  }
+
+  printer->Print(*vars,
+                 "std::unique_ptr< $ns$$Service$::Stub> $ns$$Service$::NewStub("
+                 "const std::shared_ptr< ::grpc::ChannelInterface>& channel, "
+                 "const ::grpc::StubOptions& options) {\n"
+                 "  std::unique_ptr< $ns$$Service$::Stub> stub(new "
+                 "$ns$$Service$::Stub(channel));\n"
+                 "  return stub;\n"
+                 "}\n\n");
+  printer->Print(*vars,
+                 "$ns$$Service$::Stub::Stub(const std::shared_ptr< "
+                 "::grpc::ChannelInterface>& channel)\n");
+  printer->Indent();
+  printer->Print(": channel_(channel)");
+  for (int i = 0; i < service->method_count(); ++i) {
+    auto method = service->method(i);
+    (*vars)["Method"] = method->name();
+    (*vars)["Idx"] = as_string(i);
+    if (method->NoStreaming()) {
+      (*vars)["StreamingType"] = "NORMAL_RPC";
+      // NOTE: There is no reason to consider streamed-unary as a separate
+      // category here since this part is setting up the client-side stub
+      // and this appears as a NORMAL_RPC from the client-side.
+    } else if (ClientOnlyStreaming(method.get())) {
+      (*vars)["StreamingType"] = "CLIENT_STREAMING";
+    } else if (ServerOnlyStreaming(method.get())) {
+      (*vars)["StreamingType"] = "SERVER_STREAMING";
+    } else {
+      (*vars)["StreamingType"] = "BIDI_STREAMING";
+    }
+    printer->Print(*vars,
+                   ", rpcmethod_$Method$_("
+                   "$prefix$$Service$_method_names[$Idx$], "
+                   "::grpc::internal::RpcMethod::$StreamingType$, "
+                   "channel"
+                   ")\n");
+  }
+  printer->Print("{}\n\n");
+  printer->Outdent();
+
+  for (int i = 0; i < service->method_count(); ++i) {
+    (*vars)["Idx"] = as_string(i);
+    PrintSourceClientMethod(printer, service->method(i).get(), vars);
+  }
+
+  printer->Print(*vars, "$ns$$Service$::Service::Service() {\n");
+  printer->Indent();
+  for (int i = 0; i < service->method_count(); ++i) {
+    auto method = service->method(i);
+    (*vars)["Idx"] = as_string(i);
+    (*vars)["Method"] = method->name();
+    (*vars)["Request"] = method->input_type_name();
+    (*vars)["Response"] = method->output_type_name();
+    if (method->NoStreaming()) {
+      printer->Print(
+          *vars,
+          "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
+          "    $prefix$$Service$_method_names[$Idx$],\n"
+          "    ::grpc::internal::RpcMethod::NORMAL_RPC,\n"
+          "    new ::grpc::internal::RpcMethodHandler< $ns$$Service$::Service, "
+          "$Request$, "
+          "$Response$>(\n"
+          "        std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
+    } else if (ClientOnlyStreaming(method.get())) {
+      printer->Print(
+          *vars,
+          "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
+          "    $prefix$$Service$_method_names[$Idx$],\n"
+          "    ::grpc::internal::RpcMethod::CLIENT_STREAMING,\n"
+          "    new ::grpc::internal::ClientStreamingHandler< "
+          "$ns$$Service$::Service, $Request$, $Response$>(\n"
+          "        std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
+    } else if (ServerOnlyStreaming(method.get())) {
+      printer->Print(
+          *vars,
+          "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
+          "    $prefix$$Service$_method_names[$Idx$],\n"
+          "    ::grpc::internal::RpcMethod::SERVER_STREAMING,\n"
+          "    new ::grpc::internal::ServerStreamingHandler< "
+          "$ns$$Service$::Service, $Request$, $Response$>(\n"
+          "        std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
+    } else if (method->BidiStreaming()) {
+      printer->Print(
+          *vars,
+          "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
+          "    $prefix$$Service$_method_names[$Idx$],\n"
+          "    ::grpc::internal::RpcMethod::BIDI_STREAMING,\n"
+          "    new ::grpc::internal::BidiStreamingHandler< "
+          "$ns$$Service$::Service, $Request$, $Response$>(\n"
+          "        std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
+    }
+  }
+  printer->Outdent();
+  printer->Print(*vars, "}\n\n");
+  printer->Print(*vars,
+                 "$ns$$Service$::Service::~Service() {\n"
+                 "}\n\n");
+  for (int i = 0; i < service->method_count(); ++i) {
+    (*vars)["Idx"] = as_string(i);
+    PrintSourceServerMethod(printer, service->method(i).get(), vars);
+  }
+}
+
+grpc::string GetSourceServices(grpc_generator::File *file,
+                               const Parameters &params) {
+  grpc::string output;
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    auto printer = file->CreatePrinter(&output);
+    std::map<grpc::string, grpc::string> vars;
+    // Package string is empty or ends with a dot. It is used to fully qualify
+    // method names.
+    vars["Package"] = file->package();
+    if (!file->package().empty()) {
+      vars["Package"].append(".");
+    }
+    if (!params.services_namespace.empty()) {
+      vars["ns"] = params.services_namespace + "::";
+      vars["prefix"] = params.services_namespace;
+    } else {
+      vars["ns"] = "";
+      vars["prefix"] = "";
+    }
+
+    for (int i = 0; i < file->service_count(); ++i) {
+      PrintSourceService(printer.get(), file->service(i).get(), &vars);
+      printer->Print("\n");
+    }
+  }
+  return output;
+}
+
+grpc::string GetSourceEpilogue(grpc_generator::File *file,
+                               const Parameters & /*params*/) {
+  grpc::string temp;
+
+  if (!file->package().empty()) {
+    std::vector<grpc::string> parts = file->package_parts();
+
+    for (auto part = parts.begin(); part != parts.end(); part++) {
+      temp.append("}  // namespace ");
+      temp.append(*part);
+      temp.append("\n");
+    }
+    temp.append("\n");
+  }
+
+  return temp;
+}
+
+// TODO(mmukhi): Make sure we need parameters or not.
+grpc::string GetMockPrologue(grpc_generator::File *file,
+                             const Parameters & /*params*/) {
+  grpc::string output;
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    auto printer = file->CreatePrinter(&output);
+    std::map<grpc::string, grpc::string> vars;
+
+    vars["filename"] = file->filename();
+    vars["filename_base"] = file->filename_without_ext();
+    vars["message_header_ext"] = message_header_ext();
+    vars["service_header_ext"] = service_header_ext();
+
+    printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
+    printer->Print(vars,
+                   "// If you make any local change, they will be lost.\n");
+    printer->Print(vars, "// source: $filename$\n\n");
+
+    printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
+    printer->Print(vars, "#include \"$filename_base$$service_header_ext$\"\n");
+    printer->Print(vars, file->additional_headers().c_str());
+    printer->Print(vars, "\n");
+  }
+  return output;
+}
+
+// TODO(mmukhi): Add client-stream and completion-queue headers.
+grpc::string GetMockIncludes(grpc_generator::File *file,
+                             const Parameters &params) {
+  grpc::string output;
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    auto printer = file->CreatePrinter(&output);
+    std::map<grpc::string, grpc::string> vars;
+
+    static const char *headers_strs[] = {
+        "grpc++/impl/codegen/async_stream.h",
+        "grpc++/impl/codegen/sync_stream.h",
+        "gmock/gmock.h",
+    };
+    std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
+    PrintIncludes(printer.get(), headers, params);
+
+    if (!file->package().empty()) {
+      std::vector<grpc::string> parts = file->package_parts();
+
+      for (auto part = parts.begin(); part != parts.end(); part++) {
+        vars["part"] = *part;
+        printer->Print(vars, "namespace $part$ {\n");
+      }
+    }
+
+    printer->Print(vars, "\n");
+  }
+  return output;
+}
+
+void PrintMockClientMethods(grpc_generator::Printer *printer,
+                            const grpc_generator::Method *method,
+                            std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type_name();
+  (*vars)["Response"] = method->output_type_name();
+
+  struct {
+    grpc::string prefix;
+    grpc::string method_params;  // extra arguments to method
+    int extra_method_param_count;
+  } async_prefixes[] = {{"Async", ", void* tag", 1}, {"PrepareAsync", "", 0}};
+
+  if (method->NoStreaming()) {
+    printer->Print(
+        *vars,
+        "MOCK_METHOD3($Method$, ::grpc::Status(::grpc::ClientContext* context, "
+        "const $Request$& request, $Response$* response));\n");
+    for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+      auto& async_prefix = async_prefixes[i];
+      (*vars)["AsyncPrefix"] = async_prefix.prefix;
+      printer->Print(
+          *vars,
+          "MOCK_METHOD3($AsyncPrefix$$Method$Raw, "
+          "::grpc::ClientAsyncResponseReaderInterface< $Response$>*"
+          "(::grpc::ClientContext* context, const $Request$& request, "
+          "::grpc::CompletionQueue* cq));\n");
+    }
+  } else if (ClientOnlyStreaming(method)) {
+    printer->Print(
+        *vars,
+        "MOCK_METHOD2($Method$Raw, "
+        "::grpc::ClientWriterInterface< $Request$>*"
+        "(::grpc::ClientContext* context, $Response$* response));\n");
+    for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+      auto& async_prefix = async_prefixes[i];
+      (*vars)["AsyncPrefix"] = async_prefix.prefix;
+      (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+      (*vars)["MockArgs"] =
+        flatbuffers::NumToString(3 + async_prefix.extra_method_param_count);
+      printer->Print(*vars,
+                     "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
+                     "::grpc::ClientAsyncWriterInterface< $Request$>*"
+                     "(::grpc::ClientContext* context, $Response$* response, "
+                     "::grpc::CompletionQueue* cq$AsyncMethodParams$));\n");
+    }
+  } else if (ServerOnlyStreaming(method)) {
+    printer->Print(
+        *vars,
+        "MOCK_METHOD2($Method$Raw, "
+        "::grpc::ClientReaderInterface< $Response$>*"
+        "(::grpc::ClientContext* context, const $Request$& request));\n");
+    for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+      auto& async_prefix = async_prefixes[i];
+      (*vars)["AsyncPrefix"] = async_prefix.prefix;
+      (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+      (*vars)["MockArgs"] =
+          flatbuffers::NumToString(3 + async_prefix.extra_method_param_count);
+      printer->Print(
+          *vars,
+          "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
+          "::grpc::ClientAsyncReaderInterface< $Response$>*"
+          "(::grpc::ClientContext* context, const $Request$& request, "
+          "::grpc::CompletionQueue* cq$AsyncMethodParams$));\n");
+    }
+  } else if (method->BidiStreaming()) {
+    printer->Print(
+        *vars,
+        "MOCK_METHOD1($Method$Raw, "
+        "::grpc::ClientReaderWriterInterface< $Request$, $Response$>*"
+        "(::grpc::ClientContext* context));\n");
+    for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+      auto& async_prefix = async_prefixes[i];
+      (*vars)["AsyncPrefix"] = async_prefix.prefix;
+      (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+      (*vars)["MockArgs"] =
+          flatbuffers::NumToString(2 + async_prefix.extra_method_param_count);
+      printer->Print(
+          *vars,
+          "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
+          "::grpc::ClientAsyncReaderWriterInterface<$Request$, $Response$>*"
+          "(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq"
+          "$AsyncMethodParams$));\n");
+    }
+  }
+}
+
+void PrintMockService(grpc_generator::Printer *printer,
+                      const grpc_generator::Service *service,
+                      std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Service"] = service->name();
+
+  printer->Print(*vars,
+                 "class Mock$Service$Stub : public $Service$::StubInterface {\n"
+                 " public:\n");
+  printer->Indent();
+  for (int i = 0; i < service->method_count(); ++i) {
+    PrintMockClientMethods(printer, service->method(i).get(), vars);
+  }
+  printer->Outdent();
+  printer->Print("};\n");
+}
+
+grpc::string GetMockServices(grpc_generator::File *file,
+                             const Parameters &params) {
+  grpc::string output;
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    auto printer = file->CreatePrinter(&output);
+    std::map<grpc::string, grpc::string> vars;
+    // Package string is empty or ends with a dot. It is used to fully qualify
+    // method names.
+    vars["Package"] = file->package();
+    if (!file->package().empty()) {
+      vars["Package"].append(".");
+    }
+
+    if (!params.services_namespace.empty()) {
+      vars["services_namespace"] = params.services_namespace;
+      printer->Print(vars, "\nnamespace $services_namespace$ {\n\n");
+    }
+
+    for (int i = 0; i < file->service_count(); i++) {
+      PrintMockService(printer.get(), file->service(i).get(), &vars);
+      printer->Print("\n");
+    }
+
+    if (!params.services_namespace.empty()) {
+      printer->Print(vars, "} // namespace $services_namespace$\n\n");
+    }
+  }
+  return output;
+}
+
+grpc::string GetMockEpilogue(grpc_generator::File *file,
+                             const Parameters & /*params*/) {
+  grpc::string temp;
+
+  if (!file->package().empty()) {
+    std::vector<grpc::string> parts = file->package_parts();
+
+    for (auto part = parts.begin(); part != parts.end(); part++) {
+      temp.append("} // namespace ");
+      temp.append(*part);
+      temp.append("\n");
+    }
+    temp.append("\n");
+  }
+
+  return temp;
+}
+
+}  // namespace grpc_cpp_generator
diff --git a/third_party/flatbuffers/grpc/src/compiler/cpp_generator.h b/third_party/flatbuffers/grpc/src/compiler/cpp_generator.h
new file mode 100644
index 0000000..6119ebe
--- /dev/null
+++ b/third_party/flatbuffers/grpc/src/compiler/cpp_generator.h
@@ -0,0 +1,138 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H
+#define GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H
+
+// cpp_generator.h/.cc do not directly depend on GRPC/ProtoBuf, such that they
+// can be used to generate code for other serialization systems, such as
+// FlatBuffers.
+
+#include <memory>
+#include <vector>
+
+#include "src/compiler/config.h"
+#include "src/compiler/schema_interface.h"
+
+#ifndef GRPC_CUSTOM_STRING
+#include <string>
+#define GRPC_CUSTOM_STRING std::string
+#endif
+
+namespace grpc {
+
+typedef GRPC_CUSTOM_STRING string;
+
+}  // namespace grpc
+
+namespace grpc_cpp_generator {
+
+// Contains all the parameters that are parsed from the command line.
+struct Parameters {
+  // Puts the service into a namespace
+  grpc::string services_namespace;
+  // Use system includes (<>) or local includes ("")
+  bool use_system_headers;
+  // Prefix to any grpc include
+  grpc::string grpc_search_path;
+  // Generate GMOCK code to facilitate unit testing.
+  bool generate_mock_code;
+};
+
+// Return the prologue of the generated header file.
+grpc::string GetHeaderPrologue(grpc_generator::File *file,
+                               const Parameters &params);
+
+// Return the includes needed for generated header file.
+grpc::string GetHeaderIncludes(grpc_generator::File *file,
+                               const Parameters &params);
+
+// Return the includes needed for generated source file.
+grpc::string GetSourceIncludes(grpc_generator::File *file,
+                               const Parameters &params);
+
+// Return the epilogue of the generated header file.
+grpc::string GetHeaderEpilogue(grpc_generator::File *file,
+                               const Parameters &params);
+
+// Return the prologue of the generated source file.
+grpc::string GetSourcePrologue(grpc_generator::File *file,
+                               const Parameters &params);
+
+// Return the services for generated header file.
+grpc::string GetHeaderServices(grpc_generator::File *file,
+                               const Parameters &params);
+
+// Return the services for generated source file.
+grpc::string GetSourceServices(grpc_generator::File *file,
+                               const Parameters &params);
+
+// Return the epilogue of the generated source file.
+grpc::string GetSourceEpilogue(grpc_generator::File *file,
+                               const Parameters &params);
+
+// Return the prologue of the generated mock file.
+grpc::string GetMockPrologue(grpc_generator::File *file,
+                             const Parameters &params);
+
+// Return the includes needed for generated mock file.
+grpc::string GetMockIncludes(grpc_generator::File *file,
+                             const Parameters &params);
+
+// Return the services for generated mock file.
+grpc::string GetMockServices(grpc_generator::File *file,
+                             const Parameters &params);
+
+// Return the epilogue of generated mock file.
+grpc::string GetMockEpilogue(grpc_generator::File *file,
+                             const Parameters &params);
+
+// Return the prologue of the generated mock file.
+grpc::string GetMockPrologue(grpc_generator::File *file,
+                             const Parameters &params);
+
+// Return the includes needed for generated mock file.
+grpc::string GetMockIncludes(grpc_generator::File *file,
+                             const Parameters &params);
+
+// Return the services for generated mock file.
+grpc::string GetMockServices(grpc_generator::File *file,
+                             const Parameters &params);
+
+// Return the epilogue of generated mock file.
+grpc::string GetMockEpilogue(grpc_generator::File *file,
+                             const Parameters &params);
+
+}  // namespace grpc_cpp_generator
+
+#endif  // GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H
diff --git a/third_party/flatbuffers/grpc/src/compiler/go_generator.cc b/third_party/flatbuffers/grpc/src/compiler/go_generator.cc
new file mode 100644
index 0000000..604828d
--- /dev/null
+++ b/third_party/flatbuffers/grpc/src/compiler/go_generator.cc
@@ -0,0 +1,446 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation AN/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <map>
+#include <cctype>
+#include <sstream>
+
+#include "src/compiler/go_generator.h"
+
+template <class T>
+grpc::string as_string(T x) {
+	std::ostringstream out;
+	out << x;
+	return out.str();
+}
+
+inline bool ClientOnlyStreaming(const grpc_generator::Method *method) {
+  return method->ClientStreaming() && !method->ServerStreaming();
+}
+
+inline bool ServerOnlyStreaming(const grpc_generator::Method *method) {
+  return !method->ClientStreaming() && method->ServerStreaming();
+}
+
+namespace grpc_go_generator {
+
+// Returns string with first letter to lowerCase
+grpc::string unexportName(grpc::string s) {
+	if (s.empty())
+		return s;
+	s[0] = static_cast<char>(std::tolower(s[0]));
+	return s;
+}
+
+// Returns string with first letter to uppercase
+grpc::string exportName(grpc::string s) {
+	if (s.empty())
+		return s;
+	s[0] = static_cast<char>(std::toupper(s[0]));
+	return s;
+}
+
+// Generates imports for the service
+void GenerateImports(grpc_generator::File *file, grpc_generator::Printer *printer,
+                     std::map<grpc::string, grpc::string> vars) {
+	vars["filename"] = file->filename();
+	printer->Print("//Generated by gRPC Go plugin\n");
+	printer->Print("//If you make any local changes, they will be lost\n");
+	printer->Print(vars, "//source: $filename$\n\n");
+	printer->Print(vars, "package $Package$\n\n");
+	if (file->additional_headers() != "") {
+		printer->Print(file->additional_headers().c_str());
+		printer->Print("\n\n");
+	}
+	printer->Print("import (\n");
+	printer->Indent();
+	printer->Print(vars, "$context$ \"context\"\n");
+	printer->Print(vars, "$grpc$ \"google.golang.org/grpc\"\n");
+	printer->Outdent();
+	printer->Print(")\n\n");
+}
+
+// Generates Server method signature source
+void GenerateServerMethodSignature(const grpc_generator::Method *method, grpc_generator::Printer *printer,
+                                   std::map<grpc::string, grpc::string> vars) {
+	vars["Method"] = exportName(method->name());
+	vars["Request"] = method->get_input_type_name();
+	vars["Response"] = (vars["CustomMethodIO"] == "") ? method->get_output_type_name() : vars["CustomMethodIO"];
+	if (method->NoStreaming()) {
+		printer->Print(vars, "$Method$($context$.Context, *$Request$) (*$Response$, error)");
+	} else if (ServerOnlyStreaming(method)) {
+		printer->Print(vars, "$Method$(*$Request$, $Service$_$Method$Server) error");
+	} else {
+		printer->Print(vars, "$Method$($Service$_$Method$Server) error");
+	}
+}
+
+void GenerateServerMethod(const grpc_generator::Method *method, grpc_generator::Printer *printer,
+                          std::map<grpc::string, grpc::string> vars) {
+	vars["Method"] = exportName(method->name());
+	vars["Request"] = method->get_input_type_name();
+	vars["Response"] = (vars["CustomMethodIO"] == "") ? method->get_output_type_name() : vars["CustomMethodIO"];
+	vars["FullMethodName"] = "/" + vars["ServicePrefix"] + "." + vars["Service"] + "/" + vars["Method"];
+	vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
+	if (method->NoStreaming()) {
+		printer->Print(vars, "func $Handler$(srv interface{}, ctx $context$.Context,\n\tdec func(interface{}) error, interceptor $grpc$.UnaryServerInterceptor) (interface{}, error) {\n");
+		printer->Indent();
+		printer->Print(vars, "in := new($Request$)\n");
+		printer->Print("if err := dec(in); err != nil { return nil, err }\n");
+		printer->Print(vars, "if interceptor == nil { return srv.($Service$Server).$Method$(ctx, in) }\n");
+		printer->Print(vars, "info := &$grpc$.UnaryServerInfo{\n");
+		printer->Indent();
+		printer->Print("Server: srv,\n");
+		printer->Print(vars, "FullMethod: \"$FullMethodName$\",\n");
+		printer->Outdent();
+		printer->Print("}\n\n");
+		printer->Print(vars, "handler := func(ctx $context$.Context, req interface{}) (interface{}, error) {\n");
+		printer->Indent();
+		printer->Print(vars, "return srv.($Service$Server).$Method$(ctx, req.(* $Request$))\n");
+		printer->Outdent();
+		printer->Print("}\n");
+		printer->Print("return interceptor(ctx, in, info, handler)\n");
+		printer->Outdent();
+		printer->Print("}\n\n");
+		return;
+	}
+	vars["StreamType"] = vars["ServiceUnexported"] + vars["Method"] + "Server";
+	printer->Print(vars, "func $Handler$(srv interface{}, stream $grpc$.ServerStream) error {\n");
+	printer->Indent();
+	if (ServerOnlyStreaming(method)) {
+		printer->Print(vars, "m := new($Request$)\n");
+		printer->Print(vars, "if err := stream.RecvMsg(m); err != nil { return err }\n");
+		printer->Print(vars, "return srv.($Service$Server).$Method$(m, &$StreamType${stream})\n");
+	} else {
+		printer->Print(vars, "return srv.($Service$Server).$Method$(&$StreamType${stream})\n");
+	}
+	printer->Outdent();
+	printer->Print("}\n\n");
+
+	bool genSend = method->BidiStreaming() || ServerOnlyStreaming(method);
+	bool genRecv = method->BidiStreaming() || ClientOnlyStreaming(method);
+	bool genSendAndClose = ClientOnlyStreaming(method);
+
+	printer->Print(vars, "type $Service$_$Method$Server interface { \n");
+	printer->Indent();
+	if (genSend) {
+		printer->Print(vars, "Send(* $Response$) error\n");
+	}
+	if (genRecv) {
+		printer->Print(vars, "Recv() (* $Request$, error)\n");
+	}
+	if (genSendAndClose) {
+		printer->Print(vars, "SendAndClose(* $Response$) error\n");
+	}
+	printer->Print(vars, "$grpc$.ServerStream\n");
+	printer->Outdent();
+	printer->Print("}\n\n");
+
+	printer->Print(vars, "type $StreamType$ struct {\n");
+	printer->Indent();
+	printer->Print(vars, "$grpc$.ServerStream\n");
+	printer->Outdent();
+	printer->Print("}\n\n");
+
+	if (genSend) {
+		printer->Print(vars, "func (x *$StreamType$) Send(m *$Response$) error {\n");
+		printer->Indent();
+		printer->Print("return x.ServerStream.SendMsg(m)\n");
+		printer->Outdent();
+		printer->Print("}\n\n");
+	}
+	if (genRecv) {
+		printer->Print(vars, "func (x *$StreamType$) Recv() (*$Request$, error) {\n");
+		printer->Indent();
+		printer->Print(vars, "m := new($Request$)\n");
+		printer->Print("if err := x.ServerStream.RecvMsg(m); err != nil { return nil, err }\n");
+		printer->Print("return m, nil\n");
+		printer->Outdent();
+		printer->Print("}\n\n");
+	}
+	if (genSendAndClose) {
+		printer->Print(vars, "func (x *$StreamType$) SendAndClose(m *$Response$) error {\n");
+		printer->Indent();
+		printer->Print("return x.ServerStream.SendMsg(m)\n");
+		printer->Outdent();
+		printer->Print("}\n\n");
+	}
+
+}
+
+// Generates Client method signature source
+void GenerateClientMethodSignature(const grpc_generator::Method *method, grpc_generator::Printer *printer,
+                                   std::map<grpc::string, grpc::string> vars) {
+	vars["Method"] = exportName(method->name());
+	vars["Request"] = ", in *" + ((vars["CustomMethodIO"] == "") ? method->get_input_type_name() : vars["CustomMethodIO"]);
+	if (ClientOnlyStreaming(method) || method->BidiStreaming()) {
+		vars["Request"] = "";
+	}
+	vars["Response"] = "* " + method->get_output_type_name();
+	if (ClientOnlyStreaming(method) || method->BidiStreaming() || ServerOnlyStreaming(method)) {
+		vars["Response"] = vars["Service"] + "_" + vars["Method"] + "Client" ;
+	}
+	printer->Print(vars, "$Method$(ctx $context$.Context$Request$, \n\topts... $grpc$.CallOption) ($Response$, error)");
+}
+
+// Generates Client method source
+void GenerateClientMethod(const grpc_generator::Method *method, grpc_generator::Printer *printer,
+                          std::map<grpc::string, grpc::string> vars) {
+	printer->Print(vars, "func (c *$ServiceUnexported$Client) ");
+	GenerateClientMethodSignature(method, printer, vars);
+	printer->Print(" {\n");
+	printer->Indent();
+	vars["Method"] = exportName(method->name());
+	vars["Request"] = (vars["CustomMethodIO"] == "") ? method->get_input_type_name() : vars["CustomMethodIO"];
+	vars["Response"] = method->get_output_type_name();
+	vars["FullMethodName"] = "/" + vars["ServicePrefix"] + "." + vars["Service"] + "/" + vars["Method"];
+	if (method->NoStreaming()) {
+		printer->Print(vars, "out := new($Response$)\n");
+		printer->Print(vars, "err := $grpc$.Invoke(ctx, \"$FullMethodName$\", in, out, c.cc, opts...)\n");
+		printer->Print("if err != nil { return nil, err }\n");
+		printer->Print("return out, nil\n");
+		printer->Outdent();
+		printer->Print("}\n\n");
+		return;
+	}
+	vars["StreamType"] = vars["ServiceUnexported"] + vars["Method"] + "Client";
+	printer->Print(vars, "stream, err := $grpc$.NewClientStream(ctx, &$MethodDesc$, c.cc, \"$FullMethodName$\", opts...)\n");
+	printer->Print("if err != nil { return nil, err }\n");
+
+	printer->Print(vars, "x := &$StreamType${stream}\n");
+	if (ServerOnlyStreaming(method)) {
+		printer->Print("if err := x.ClientStream.SendMsg(in); err != nil { return nil, err }\n");
+		printer->Print("if err := x.ClientStream.CloseSend(); err != nil { return nil, err }\n");
+	}
+	printer->Print("return x,nil\n");
+	printer->Outdent();
+	printer->Print("}\n\n");
+
+	bool genSend = method->BidiStreaming() || ClientOnlyStreaming(method);
+	bool genRecv = method->BidiStreaming() || ServerOnlyStreaming(method);
+	bool genCloseAndRecv = ClientOnlyStreaming(method);
+
+	//Stream interface
+	printer->Print(vars, "type $Service$_$Method$Client interface {\n");
+	printer->Indent();
+	if (genSend) {
+		printer->Print(vars, "Send(*$Request$) error\n");
+	}
+	if (genRecv) {
+		printer->Print(vars, "Recv() (*$Response$, error)\n");
+	}
+	if (genCloseAndRecv) {
+		printer->Print(vars, "CloseAndRecv() (*$Response$, error)\n");
+	}
+	printer->Print(vars, "$grpc$.ClientStream\n");
+	printer->Outdent();
+	printer->Print("}\n\n");
+
+	//Stream Client
+	printer->Print(vars, "type $StreamType$ struct{\n");
+	printer->Indent();
+	printer->Print(vars, "$grpc$.ClientStream\n");
+	printer->Outdent();
+	printer->Print("}\n\n");
+
+	if (genSend) {
+		printer->Print(vars, "func (x *$StreamType$) Send(m *$Request$) error {\n");
+		printer->Indent();
+		printer->Print("return x.ClientStream.SendMsg(m)\n");
+		printer->Outdent();
+		printer->Print("}\n\n");
+	}
+
+	if (genRecv) {
+		printer->Print(vars, "func (x *$StreamType$) Recv() (*$Response$, error) {\n");
+		printer->Indent();
+		printer->Print(vars, "m := new($Response$)\n");
+		printer->Print("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }\n");
+		printer->Print("return m, nil\n");
+		printer->Outdent();
+		printer->Print("}\n\n");
+	}
+
+	if (genCloseAndRecv) {
+		printer->Print(vars, "func (x *$StreamType$) CloseAndRecv() (*$Response$, error) {\n");
+		printer->Indent();
+		printer->Print("if err := x.ClientStream.CloseSend(); err != nil { return nil, err }\n");
+		printer->Print(vars, "m := new ($Response$)\n");
+		printer->Print("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }\n");
+		printer->Print("return m, nil\n");
+		printer->Outdent();
+		printer->Print("}\n\n");
+	}
+}
+
+// Generates client API for the service
+void GenerateService(const grpc_generator::Service *service, grpc_generator::Printer* printer,
+                     std::map<grpc::string, grpc::string> vars) {
+	vars["Service"] = exportName(service->name());
+	// Client Interface
+	printer->Print(vars, "// Client API for $Service$ service\n");
+	printer->Print(vars, "type $Service$Client interface{\n");
+	printer->Indent();
+	for (int i = 0; i < service->method_count(); i++) {
+		GenerateClientMethodSignature(service->method(i).get(), printer, vars);
+		printer->Print("\n");
+	}
+	printer->Outdent();
+	printer->Print("}\n\n");
+
+	// Client structure
+	vars["ServiceUnexported"] = unexportName(vars["Service"]);
+	printer->Print(vars, "type $ServiceUnexported$Client struct {\n");
+	printer->Indent();
+	printer->Print(vars, "cc *$grpc$.ClientConn\n");
+	printer->Outdent();
+	printer->Print("}\n\n");
+
+	// NewClient
+	printer->Print(vars, "func New$Service$Client(cc *$grpc$.ClientConn) $Service$Client {\n");
+	printer->Indent();
+	printer->Print(vars, "return &$ServiceUnexported$Client{cc}");
+	printer->Outdent();
+	printer->Print("\n}\n\n");
+
+	int unary_methods = 0, streaming_methods = 0;
+	vars["ServiceDesc"] = "_" + vars["Service"] + "_serviceDesc";
+	for (int i = 0; i < service->method_count(); i++) {
+		auto method = service->method(i);
+		if (method->NoStreaming()) {
+			vars["MethodDesc"] = vars["ServiceDesc"] + ".Method[" + as_string(unary_methods) + "]";
+			unary_methods++;
+		} else {
+			vars["MethodDesc"] = vars["ServiceDesc"] + ".Streams[" + as_string(streaming_methods) + "]";
+			streaming_methods++;
+		}
+		GenerateClientMethod(method.get(), printer, vars);
+	}
+
+	//Server Interface
+	printer->Print(vars, "// Server API for $Service$ service\n");
+	printer->Print(vars, "type $Service$Server interface {\n");
+	printer->Indent();
+	for (int i = 0; i < service->method_count(); i++) {
+		GenerateServerMethodSignature(service->method(i).get(), printer, vars);
+		printer->Print("\n");
+	}
+	printer->Outdent();
+	printer->Print("}\n\n");
+
+	// Server registration.
+	printer->Print(vars, "func Register$Service$Server(s *$grpc$.Server, srv $Service$Server) {\n");
+	printer->Indent();
+	printer->Print(vars, "s.RegisterService(&$ServiceDesc$, srv)\n");
+	printer->Outdent();
+	printer->Print("}\n\n");
+
+	for (int i = 0; i < service->method_count(); i++) {
+		GenerateServerMethod(service->method(i).get(), printer, vars);
+		printer->Print("\n");
+	}
+
+
+	//Service Descriptor
+	printer->Print(vars, "var $ServiceDesc$ = $grpc$.ServiceDesc{\n");
+	printer->Indent();
+	printer->Print(vars, "ServiceName: \"$ServicePrefix$.$Service$\",\n");
+	printer->Print(vars, "HandlerType: (*$Service$Server)(nil),\n");
+	printer->Print(vars, "Methods: []$grpc$.MethodDesc{\n");
+	printer->Indent();
+	for (int i = 0; i < service->method_count(); i++) {
+		auto method = service->method(i);
+		vars["Method"] = method->name();
+		vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
+		if (method->NoStreaming()) {
+			printer->Print("{\n");
+			printer->Indent();
+			printer->Print(vars, "MethodName: \"$Method$\",\n");
+			printer->Print(vars, "Handler: $Handler$, \n");
+			printer->Outdent();
+			printer->Print("},\n");
+		}
+	}
+	printer->Outdent();
+	printer->Print("},\n");
+	printer->Print(vars, "Streams: []$grpc$.StreamDesc{\n");
+	printer->Indent();
+	for (int i = 0; i < service->method_count(); i++) {
+		auto method = service->method(i);
+		vars["Method"] = method->name();
+		vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
+		if (!method->NoStreaming()) {
+			printer->Print("{\n");
+			printer->Indent();
+			printer->Print(vars, "StreamName: \"$Method$\",\n");
+			printer->Print(vars, "Handler: $Handler$, \n");
+			if (ClientOnlyStreaming(method.get())) {
+				printer->Print("ClientStreams: true,\n");
+			} else if (ServerOnlyStreaming(method.get())) {
+				printer->Print("ServerStreams: true,\n");
+			} else {
+				printer->Print("ServerStreams: true,\n");
+				printer->Print("ClientStreams: true,\n");
+			}
+			printer->Outdent();
+			printer->Print("},\n");
+		}
+	}
+	printer->Outdent();
+	printer->Print("},\n");
+	printer->Outdent();
+	printer->Print("}\n\n");
+
+}
+
+
+// Returns source for the service
+grpc::string GenerateServiceSource(grpc_generator::File *file,
+                                   const grpc_generator::Service *service,
+                                   grpc_go_generator::Parameters *parameters) {
+	grpc::string out;
+	auto p = file->CreatePrinter(&out);
+	auto printer = p.get();
+	std::map<grpc::string, grpc::string> vars;
+	vars["Package"] = parameters->package_name;
+	vars["ServicePrefix"] = parameters->service_prefix;
+	vars["grpc"] = "grpc";
+	vars["context"] = "context";
+	GenerateImports(file, printer, vars);
+	if (parameters->custom_method_io_type != "") {
+		vars["CustomMethodIO"] = parameters->custom_method_io_type;
+	}
+	GenerateService(service, printer, vars);
+	return out;
+}
+}// Namespace grpc_go_generator
diff --git a/third_party/flatbuffers/grpc/src/compiler/go_generator.h b/third_party/flatbuffers/grpc/src/compiler/go_generator.h
new file mode 100644
index 0000000..baa94e0
--- /dev/null
+++ b/third_party/flatbuffers/grpc/src/compiler/go_generator.h
@@ -0,0 +1,64 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_INTERNAL_COMPILER_GO_GENERATOR_H
+#define GRPC_INTERNAL_COMPILER_GO_GENERATOR_H
+
+//go generator is used to generate GRPC code for serialization system, such as flatbuffers
+#include <memory>
+#include <vector>
+
+#include "src/compiler/schema_interface.h"
+
+namespace grpc_go_generator {
+
+struct Parameters {
+  //Defines the custom parameter types for methods
+  //eg: flatbuffers uses flatbuffers.Builder as input for the client and output for the server
+  grpc::string custom_method_io_type;
+
+  //Package name for the service
+  grpc::string package_name;
+
+  //Prefix for RPC Calls
+  grpc::string service_prefix;
+};
+
+// Return the source of the generated service file.
+grpc::string GenerateServiceSource(grpc_generator::File *file,
+                                   const grpc_generator::Service *service,
+                                   grpc_go_generator::Parameters *parameters);
+
+}
+
+#endif  // GRPC_INTERNAL_COMPILER_GO_GENERATOR_H
diff --git a/third_party/flatbuffers/grpc/src/compiler/java_generator.cc b/third_party/flatbuffers/grpc/src/compiler/java_generator.cc
new file mode 100644
index 0000000..661c9ee
--- /dev/null
+++ b/third_party/flatbuffers/grpc/src/compiler/java_generator.cc
@@ -0,0 +1,1135 @@
+/*
+ * 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 "java_generator.h"
+
+#include <algorithm>
+#include <iostream>
+#include <iterator>
+#include <map>
+#include <utility>
+#include <vector>
+
+// just to get flatbuffer_version_string()
+#include <flatbuffers/flatbuffers.h>
+#include <flatbuffers/util.h>
+#define to_string flatbuffers::NumToString
+
+// Stringify helpers used solely to cast GRPC_VERSION
+#ifndef STR
+#define STR(s) #s
+#endif
+
+#ifndef XSTR
+#define XSTR(s) STR(s)
+#endif
+
+
+typedef grpc_generator::Printer Printer;
+typedef std::map<grpc::string, grpc::string> VARS;
+typedef grpc_generator::Service ServiceDescriptor;
+typedef grpc_generator::CommentHolder
+    DescriptorType;  // base class of all 'descriptors'
+typedef grpc_generator::Method MethodDescriptor;
+
+namespace grpc_java_generator {
+typedef std::string string;
+// Generates imports for the service
+void GenerateImports(grpc_generator::File* file,
+                     grpc_generator::Printer* printer, VARS& vars) {
+  vars["filename"] = file->filename();
+  printer->Print(
+      vars,
+      "//Generated by flatc compiler (version $flatc_version$)\n");
+  printer->Print("//If you make any local changes, they will be lost\n");
+  printer->Print(vars, "//source: $filename$.fbs\n\n");
+  printer->Print(vars, "package $Package$;\n\n");
+  vars["Package"] = vars["Package"] + ".";
+  if (!file->additional_headers().empty()) {
+    printer->Print(file->additional_headers().c_str());
+    printer->Print("\n\n");
+  }
+}
+
+// Adjust a method name prefix identifier to follow the JavaBean spec:
+//   - decapitalize the first letter
+//   - remove embedded underscores & capitalize the following letter
+static string MixedLower(const string& word) {
+  string w;
+  w += static_cast<string::value_type>(tolower(word[0]));
+  bool after_underscore = false;
+  for (size_t i = 1; i < word.length(); ++i) {
+    if (word[i] == '_') {
+      after_underscore = true;
+    } else {
+      w += after_underscore ? static_cast<string::value_type>(toupper(word[i]))
+                            : word[i];
+      after_underscore = false;
+    }
+  }
+  return w;
+}
+
+// Converts to the identifier to the ALL_UPPER_CASE format.
+//   - An underscore is inserted where a lower case letter is followed by an
+//     upper case letter.
+//   - All letters are converted to upper case
+static string ToAllUpperCase(const string& word) {
+  string w;
+  for (size_t i = 0; i < word.length(); ++i) {
+    w += static_cast<string::value_type>(toupper(word[i]));
+    if ((i < word.length() - 1) && islower(word[i]) && isupper(word[i + 1])) {
+      w += '_';
+    }
+  }
+  return w;
+}
+
+static inline string LowerMethodName(const MethodDescriptor* method) {
+  return MixedLower(method->name());
+}
+
+static inline string MethodPropertiesFieldName(const MethodDescriptor* method) {
+  return "METHOD_" + ToAllUpperCase(method->name());
+}
+
+static inline string MethodPropertiesGetterName(
+    const MethodDescriptor* method) {
+  return MixedLower("get_" + method->name() + "_method");
+}
+
+static inline string MethodIdFieldName(const MethodDescriptor* method) {
+  return "METHODID_" + ToAllUpperCase(method->name());
+}
+
+static inline string JavaClassName(VARS& vars, const string& name) {
+  // string name = google::protobuf::compiler::java::ClassName(desc);
+  return vars["Package"] + name;
+}
+
+static inline string ServiceClassName(const string& service_name) {
+  return service_name + "Grpc";
+}
+
+// TODO(nmittler): Remove once protobuf includes javadoc methods in
+// distribution.
+template <typename ITR>
+static void GrpcSplitStringToIteratorUsing(const string& full,
+                                           const char* delim, ITR& result) {
+  // Optimize the common case where delim is a single character.
+  if (delim[0] != '\0' && delim[1] == '\0') {
+    char c = delim[0];
+    const char* p = full.data();
+    const char* end = p + full.size();
+    while (p != end) {
+      if (*p == c) {
+        ++p;
+      } else {
+        const char* start = p;
+        while (++p != end && *p != c)
+          ;
+        *result++ = string(start, p - start);
+      }
+    }
+    return;
+  }
+
+  string::size_type begin_index, end_index;
+  begin_index = full.find_first_not_of(delim);
+  while (begin_index != string::npos) {
+    end_index = full.find_first_of(delim, begin_index);
+    if (end_index == string::npos) {
+      *result++ = full.substr(begin_index);
+      return;
+    }
+    *result++ = full.substr(begin_index, (end_index - begin_index));
+    begin_index = full.find_first_not_of(delim, end_index);
+  }
+}
+
+static void GrpcSplitStringUsing(const string& full, const char* delim,
+                                 std::vector<string>* result) {
+  std::back_insert_iterator<std::vector<string>> it(*result);
+  GrpcSplitStringToIteratorUsing(full, delim, it);
+}
+
+static std::vector<string> GrpcSplit(const string& full, const char* delim) {
+  std::vector<string> result;
+  GrpcSplitStringUsing(full, delim, &result);
+  return result;
+}
+
+// TODO(nmittler): Remove once protobuf includes javadoc methods in
+// distribution.
+static string GrpcEscapeJavadoc(const string& input) {
+  string result;
+  result.reserve(input.size() * 2);
+
+  char prev = '*';
+
+  for (string::size_type i = 0; i < input.size(); i++) {
+    char c = input[i];
+    switch (c) {
+      case '*':
+        // Avoid "/*".
+        if (prev == '/') {
+          result.append("&#42;");
+        } else {
+          result.push_back(c);
+        }
+        break;
+      case '/':
+        // Avoid "*/".
+        if (prev == '*') {
+          result.append("&#47;");
+        } else {
+          result.push_back(c);
+        }
+        break;
+      case '@':
+        // '@' starts javadoc tags including the @deprecated tag, which will
+        // cause a compile-time error if inserted before a declaration that
+        // does not have a corresponding @Deprecated annotation.
+        result.append("&#64;");
+        break;
+      case '<':
+        // Avoid interpretation as HTML.
+        result.append("&lt;");
+        break;
+      case '>':
+        // Avoid interpretation as HTML.
+        result.append("&gt;");
+        break;
+      case '&':
+        // Avoid interpretation as HTML.
+        result.append("&amp;");
+        break;
+      case '\\':
+        // Java interprets Unicode escape sequences anywhere!
+        result.append("&#92;");
+        break;
+      default:
+        result.push_back(c);
+        break;
+    }
+
+    prev = c;
+  }
+
+  return result;
+}
+
+static std::vector<string> GrpcGetDocLines(const string& comments) {
+  if (!comments.empty()) {
+    // TODO(kenton):  Ideally we should parse the comment text as Markdown and
+    //   write it back as HTML, but this requires a Markdown parser.  For now
+    //   we just use <pre> to get fixed-width text formatting.
+
+    // If the comment itself contains block comment start or end markers,
+    // HTML-escape them so that they don't accidentally close the doc comment.
+    string escapedComments = GrpcEscapeJavadoc(comments);
+
+    std::vector<string> lines = GrpcSplit(escapedComments, "\n");
+    while (!lines.empty() && lines.back().empty()) {
+      lines.pop_back();
+    }
+    return lines;
+  }
+  return std::vector<string>();
+}
+
+static std::vector<string> GrpcGetDocLinesForDescriptor(
+    const DescriptorType* descriptor) {
+  return descriptor->GetAllComments();
+  // return GrpcGetDocLines(descriptor->GetLeadingComments("///"));
+}
+
+static void GrpcWriteDocCommentBody(Printer* printer, VARS& vars,
+                                    const std::vector<string>& lines,
+                                    bool surroundWithPreTag) {
+  if (!lines.empty()) {
+    if (surroundWithPreTag) {
+      printer->Print(" * <pre>\n");
+    }
+
+    for (size_t i = 0; i < lines.size(); i++) {
+      // Most lines should start with a space.  Watch out for lines that start
+      // with a /, since putting that right after the leading asterisk will
+      // close the comment.
+      vars["line"] = lines[i];
+      if (!lines[i].empty() && lines[i][0] == '/') {
+        printer->Print(vars, " * $line$\n");
+      } else {
+        printer->Print(vars, " *$line$\n");
+      }
+    }
+
+    if (surroundWithPreTag) {
+      printer->Print(" * </pre>\n");
+    }
+  }
+}
+
+static void GrpcWriteDocComment(Printer* printer, VARS& vars,
+                                const string& comments) {
+  printer->Print("/**\n");
+  std::vector<string> lines = GrpcGetDocLines(comments);
+  GrpcWriteDocCommentBody(printer, vars, lines, false);
+  printer->Print(" */\n");
+}
+
+static void GrpcWriteServiceDocComment(Printer* printer, VARS& vars,
+                                       const ServiceDescriptor* service) {
+  printer->Print("/**\n");
+  std::vector<string> lines = GrpcGetDocLinesForDescriptor(service);
+  GrpcWriteDocCommentBody(printer, vars, lines, true);
+  printer->Print(" */\n");
+}
+
+void GrpcWriteMethodDocComment(Printer* printer, VARS& vars,
+                               const MethodDescriptor* method) {
+  printer->Print("/**\n");
+  std::vector<string> lines = GrpcGetDocLinesForDescriptor(method);
+  GrpcWriteDocCommentBody(printer, vars, lines, true);
+  printer->Print(" */\n");
+}
+
+//outputs static singleton extractor for type stored in "extr_type" and "extr_type_name" vars
+static void PrintTypeExtractor(Printer* p, VARS& vars) {
+  p->Print(
+    vars,
+    "private static volatile FlatbuffersUtils.FBExtactor<$extr_type$> "
+    "extractorOf$extr_type_name$;\n"
+    "private static FlatbuffersUtils.FBExtactor<$extr_type$> "
+    "getExtractorOf$extr_type_name$() {\n"
+    "    if (extractorOf$extr_type_name$ != null) return "
+    "extractorOf$extr_type_name$;\n"
+    "    synchronized ($service_class_name$.class) {\n"
+    "        if (extractorOf$extr_type_name$ != null) return "
+    "extractorOf$extr_type_name$;\n"
+    "        extractorOf$extr_type_name$ = new "
+    "FlatbuffersUtils.FBExtactor<$extr_type$>() {\n"
+    "            public $extr_type$ extract (ByteBuffer buffer) {\n"
+    "                return "
+    "$extr_type$.getRootAs$extr_type_name$(buffer);\n"
+    "            }\n"
+    "        };\n"
+    "        return extractorOf$extr_type_name$;\n"
+    "    }\n"
+    "}\n\n");
+}
+static void PrintMethodFields(Printer* p, VARS& vars,
+                              const ServiceDescriptor* service) {
+  p->Print("// Static method descriptors that strictly reflect the proto.\n");
+  vars["service_name"] = service->name();
+
+  //set of names of rpc input- and output- types that were already encountered.
+  //this is needed to avoid duplicating type extractor since it's possible that
+  //the same type is used as an input or output type of more than a single RPC method
+  std::set<std::string> encounteredTypes;
+
+  for (int i = 0; i < service->method_count(); ++i) {
+    auto method = service->method(i);
+    vars["arg_in_id"] = to_string(2L * i); //trying to make msvc 10 happy
+    vars["arg_out_id"] = to_string(2L * i + 1);
+    vars["method_name"] = method->name();
+    vars["input_type_name"] = method->get_input_type_name();
+    vars["output_type_name"] = method->get_output_type_name();
+    vars["input_type"] = JavaClassName(vars, method->get_input_type_name());
+    vars["output_type"] = JavaClassName(vars, method->get_output_type_name());
+    vars["method_field_name"] = MethodPropertiesFieldName(method.get());
+    vars["method_new_field_name"] = MethodPropertiesGetterName(method.get());
+    vars["method_method_name"] = MethodPropertiesGetterName(method.get());
+    bool client_streaming = method->ClientStreaming() || method->BidiStreaming();
+    bool server_streaming = method->ServerStreaming() || method->BidiStreaming();
+    if (client_streaming) {
+      if (server_streaming) {
+        vars["method_type"] = "BIDI_STREAMING";
+      } else {
+        vars["method_type"] = "CLIENT_STREAMING";
+      }
+    } else {
+      if (server_streaming) {
+        vars["method_type"] = "SERVER_STREAMING";
+      } else {
+        vars["method_type"] = "UNARY";
+      }
+    }
+
+    p->Print(
+        vars,
+        "@$ExperimentalApi$(\"https://github.com/grpc/grpc-java/issues/"
+        "1901\")\n"
+        "@$Deprecated$ // Use {@link #$method_method_name$()} instead. \n"
+        "public static final $MethodDescriptor$<$input_type$,\n"
+        "    $output_type$> $method_field_name$ = $method_method_name$();\n"
+        "\n"
+        "private static volatile $MethodDescriptor$<$input_type$,\n"
+        "    $output_type$> $method_new_field_name$;\n"
+        "\n");
+
+    if (encounteredTypes.insert(vars["input_type_name"]).second) {
+      vars["extr_type"] = vars["input_type"];
+      vars["extr_type_name"] = vars["input_type_name"];
+      PrintTypeExtractor(p, vars);
+    }
+
+    if (encounteredTypes.insert(vars["output_type_name"]).second) {
+      vars["extr_type"] = vars["output_type"];
+      vars["extr_type_name"] = vars["output_type_name"];
+      PrintTypeExtractor(p, vars);
+    }
+
+    p->Print(
+      vars,
+      "@$ExperimentalApi$(\"https://github.com/grpc/grpc-java/issues/"
+      "1901\")\n"
+      "public static $MethodDescriptor$<$input_type$,\n"
+      "    $output_type$> $method_method_name$() {\n"
+      "  $MethodDescriptor$<$input_type$, $output_type$> "
+      "$method_new_field_name$;\n"
+      "  if (($method_new_field_name$ = "
+      "$service_class_name$.$method_new_field_name$) == null) {\n"
+      "    synchronized ($service_class_name$.class) {\n"
+      "      if (($method_new_field_name$ = "
+      "$service_class_name$.$method_new_field_name$) == null) {\n"
+      "        $service_class_name$.$method_new_field_name$ = "
+      "$method_new_field_name$ = \n"
+      "            $MethodDescriptor$.<$input_type$, "
+      "$output_type$>newBuilder()\n"
+      "            .setType($MethodType$.$method_type$)\n"
+      "            .setFullMethodName(generateFullMethodName(\n"
+      "                \"$Package$$service_name$\", \"$method_name$\"))\n"
+      "            .setSampledToLocalTracing(true)\n"
+      "            .setRequestMarshaller(FlatbuffersUtils.marshaller(\n"
+      "                $input_type$.class, "
+      "getExtractorOf$input_type_name$()))\n"
+      "            .setResponseMarshaller(FlatbuffersUtils.marshaller(\n"
+      "                $output_type$.class, "
+      "getExtractorOf$output_type_name$()))\n");
+
+    //            vars["proto_method_descriptor_supplier"] = service->name() +
+    //            "MethodDescriptorSupplier";
+    p->Print(vars, "                .setSchemaDescriptor(null)\n");
+    //"                .setSchemaDescriptor(new
+    //$proto_method_descriptor_supplier$(\"$method_name$\"))\n");
+
+    p->Print(vars, "                .build();\n");
+    p->Print(vars,
+             "        }\n"
+             "      }\n"
+             "   }\n"
+             "   return $method_new_field_name$;\n"
+             "}\n");
+
+    p->Print("\n");
+  }
+}
+enum StubType {
+  ASYNC_INTERFACE = 0,
+  BLOCKING_CLIENT_INTERFACE = 1,
+  FUTURE_CLIENT_INTERFACE = 2,
+  BLOCKING_SERVER_INTERFACE = 3,
+  ASYNC_CLIENT_IMPL = 4,
+  BLOCKING_CLIENT_IMPL = 5,
+  FUTURE_CLIENT_IMPL = 6,
+  ABSTRACT_CLASS = 7,
+};
+
+enum CallType { ASYNC_CALL = 0, BLOCKING_CALL = 1, FUTURE_CALL = 2 };
+
+static void PrintBindServiceMethodBody(Printer* p, VARS& vars,
+                                       const ServiceDescriptor* service);
+
+// Prints a client interface or implementation class, or a server interface.
+static void PrintStub(Printer* p, VARS& vars, const ServiceDescriptor* service,
+                      StubType type) {
+  const string service_name = service->name();
+  vars["service_name"] = service_name;
+  vars["abstract_name"] = service_name + "ImplBase";
+  string stub_name = service_name;
+  string client_name = service_name;
+  CallType call_type = ASYNC_CALL;
+  bool impl_base = false;
+  bool interface = false;
+  switch (type) {
+    case ABSTRACT_CLASS:
+      call_type = ASYNC_CALL;
+      impl_base = true;
+      break;
+    case ASYNC_CLIENT_IMPL:
+      call_type = ASYNC_CALL;
+      stub_name += "Stub";
+      break;
+    case BLOCKING_CLIENT_INTERFACE:
+      interface = true;
+      FLATBUFFERS_FALLTHROUGH(); // fall thru
+    case BLOCKING_CLIENT_IMPL:
+      call_type = BLOCKING_CALL;
+      stub_name += "BlockingStub";
+      client_name += "BlockingClient";
+      break;
+    case FUTURE_CLIENT_INTERFACE:
+      interface = true;
+      FLATBUFFERS_FALLTHROUGH(); // fall thru
+    case FUTURE_CLIENT_IMPL:
+      call_type = FUTURE_CALL;
+      stub_name += "FutureStub";
+      client_name += "FutureClient";
+      break;
+    case ASYNC_INTERFACE:
+      call_type = ASYNC_CALL;
+      interface = true;
+      break;
+    default:
+      GRPC_CODEGEN_FAIL << "Cannot determine class name for StubType: " << type;
+  }
+  vars["stub_name"] = stub_name;
+  vars["client_name"] = client_name;
+
+  // Class head
+  if (!interface) {
+    GrpcWriteServiceDocComment(p, vars, service);
+  }
+  if (impl_base) {
+    p->Print(vars,
+             "public static abstract class $abstract_name$ implements "
+             "$BindableService$ {\n");
+  } else {
+    p->Print(vars,
+             "public static final class $stub_name$ extends "
+             "$AbstractStub$<$stub_name$> {\n");
+  }
+  p->Indent();
+
+  // Constructor and build() method
+  if (!impl_base && !interface) {
+    p->Print(vars, "private $stub_name$($Channel$ channel) {\n");
+    p->Indent();
+    p->Print("super(channel);\n");
+    p->Outdent();
+    p->Print("}\n\n");
+    p->Print(vars,
+             "private $stub_name$($Channel$ channel,\n"
+             "    $CallOptions$ callOptions) {\n");
+    p->Indent();
+    p->Print("super(channel, callOptions);\n");
+    p->Outdent();
+    p->Print("}\n\n");
+    p->Print(vars,
+             "@$Override$\n"
+             "protected $stub_name$ build($Channel$ channel,\n"
+             "    $CallOptions$ callOptions) {\n");
+    p->Indent();
+    p->Print(vars, "return new $stub_name$(channel, callOptions);\n");
+    p->Outdent();
+    p->Print("}\n");
+  }
+
+  // RPC methods
+  for (int i = 0; i < service->method_count(); ++i) {
+    auto method = service->method(i);
+    vars["input_type"] = JavaClassName(vars, method->get_input_type_name());
+    vars["output_type"] = JavaClassName(vars, method->get_output_type_name());
+    vars["lower_method_name"] = LowerMethodName(&*method);
+    vars["method_method_name"] = MethodPropertiesGetterName(&*method);
+    bool client_streaming = method->ClientStreaming() || method->BidiStreaming();
+    bool server_streaming = method->ServerStreaming() || method->BidiStreaming();
+
+    if (call_type == BLOCKING_CALL && client_streaming) {
+      // Blocking client interface with client streaming is not available
+      continue;
+    }
+
+    if (call_type == FUTURE_CALL && (client_streaming || server_streaming)) {
+      // Future interface doesn't support streaming.
+      continue;
+    }
+
+    // Method signature
+    p->Print("\n");
+    // TODO(nmittler): Replace with WriteMethodDocComment once included by the
+    // protobuf distro.
+    if (!interface) {
+      GrpcWriteMethodDocComment(p, vars, &*method);
+    }
+    p->Print("public ");
+    switch (call_type) {
+      case BLOCKING_CALL:
+        GRPC_CODEGEN_CHECK(!client_streaming)
+            << "Blocking client interface with client streaming is unavailable";
+        if (server_streaming) {
+          // Server streaming
+          p->Print(vars,
+                   "$Iterator$<$output_type$> $lower_method_name$(\n"
+                   "    $input_type$ request)");
+        } else {
+          // Simple RPC
+          p->Print(vars,
+                   "$output_type$ $lower_method_name$($input_type$ request)");
+        }
+        break;
+      case ASYNC_CALL:
+        if (client_streaming) {
+          // Bidirectional streaming or client streaming
+          p->Print(vars,
+                   "$StreamObserver$<$input_type$> $lower_method_name$(\n"
+                   "    $StreamObserver$<$output_type$> responseObserver)");
+        } else {
+          // Server streaming or simple RPC
+          p->Print(vars,
+                   "void $lower_method_name$($input_type$ request,\n"
+                   "    $StreamObserver$<$output_type$> responseObserver)");
+        }
+        break;
+      case FUTURE_CALL:
+        GRPC_CODEGEN_CHECK(!client_streaming && !server_streaming)
+            << "Future interface doesn't support streaming. "
+            << "client_streaming=" << client_streaming << ", "
+            << "server_streaming=" << server_streaming;
+        p->Print(vars,
+                 "$ListenableFuture$<$output_type$> $lower_method_name$(\n"
+                 "    $input_type$ request)");
+        break;
+    }
+
+    if (interface) {
+      p->Print(";\n");
+      continue;
+    }
+    // Method body.
+    p->Print(" {\n");
+    p->Indent();
+    if (impl_base) {
+      switch (call_type) {
+          // NB: Skipping validation of service methods. If something is wrong,
+          // we wouldn't get to this point as compiler would return errors when
+          // generating service interface.
+        case ASYNC_CALL:
+          if (client_streaming) {
+            p->Print(vars,
+                     "return "
+                     "asyncUnimplementedStreamingCall($method_method_name$(), "
+                     "responseObserver);\n");
+          } else {
+            p->Print(vars,
+                     "asyncUnimplementedUnaryCall($method_method_name$(), "
+                     "responseObserver);\n");
+          }
+          break;
+        default:
+          break;
+      }
+    } else if (!interface) {
+      switch (call_type) {
+        case BLOCKING_CALL:
+          GRPC_CODEGEN_CHECK(!client_streaming)
+              << "Blocking client streaming interface is not available";
+          if (server_streaming) {
+            vars["calls_method"] = "blockingServerStreamingCall";
+            vars["params"] = "request";
+          } else {
+            vars["calls_method"] = "blockingUnaryCall";
+            vars["params"] = "request";
+          }
+          p->Print(vars,
+                   "return $calls_method$(\n"
+                   "    getChannel(), $method_method_name$(), "
+                   "getCallOptions(), $params$);\n");
+          break;
+        case ASYNC_CALL:
+          if (server_streaming) {
+            if (client_streaming) {
+              vars["calls_method"] = "asyncBidiStreamingCall";
+              vars["params"] = "responseObserver";
+            } else {
+              vars["calls_method"] = "asyncServerStreamingCall";
+              vars["params"] = "request, responseObserver";
+            }
+          } else {
+            if (client_streaming) {
+              vars["calls_method"] = "asyncClientStreamingCall";
+              vars["params"] = "responseObserver";
+            } else {
+              vars["calls_method"] = "asyncUnaryCall";
+              vars["params"] = "request, responseObserver";
+            }
+          }
+          vars["last_line_prefix"] = client_streaming ? "return " : "";
+          p->Print(vars,
+                   "$last_line_prefix$$calls_method$(\n"
+                   "    getChannel().newCall($method_method_name$(), "
+                   "getCallOptions()), $params$);\n");
+          break;
+        case FUTURE_CALL:
+          GRPC_CODEGEN_CHECK(!client_streaming && !server_streaming)
+              << "Future interface doesn't support streaming. "
+              << "client_streaming=" << client_streaming << ", "
+              << "server_streaming=" << server_streaming;
+          vars["calls_method"] = "futureUnaryCall";
+          p->Print(vars,
+                   "return $calls_method$(\n"
+                   "    getChannel().newCall($method_method_name$(), "
+                   "getCallOptions()), request);\n");
+          break;
+      }
+    }
+    p->Outdent();
+    p->Print("}\n");
+  }
+
+  if (impl_base) {
+    p->Print("\n");
+    p->Print(
+        vars,
+        "@$Override$ public final $ServerServiceDefinition$ bindService() {\n");
+    vars["instance"] = "this";
+    PrintBindServiceMethodBody(p, vars, service);
+    p->Print("}\n");
+  }
+
+  p->Outdent();
+  p->Print("}\n\n");
+}
+
+static bool CompareMethodClientStreaming(
+    const std::unique_ptr<const grpc_generator::Method>& method1,
+    const std::unique_ptr<const grpc_generator::Method>& method2) {
+  return method1->ClientStreaming() < method2->ClientStreaming();
+}
+
+// Place all method invocations into a single class to reduce memory footprint
+// on Android.
+static void PrintMethodHandlerClass(Printer* p, VARS& vars,
+                                    const ServiceDescriptor* service) {
+  // Sort method ids based on ClientStreaming() so switch tables are compact.
+  std::vector<std::unique_ptr<const grpc_generator::Method>> sorted_methods(
+      service->method_count());
+  for (int i = 0; i < service->method_count(); ++i) {
+    sorted_methods[i] = service->method(i);
+  }
+  stable_sort(sorted_methods.begin(), sorted_methods.end(),
+              CompareMethodClientStreaming);
+  for (size_t i = 0; i < sorted_methods.size(); i++) {
+    auto& method = sorted_methods[i];
+    vars["method_id"] = to_string(i);
+    vars["method_id_name"] = MethodIdFieldName(&*method);
+    p->Print(vars,
+             "private static final int $method_id_name$ = $method_id$;\n");
+  }
+  p->Print("\n");
+  vars["service_name"] = service->name() + "ImplBase";
+  p->Print(vars,
+           "private static final class MethodHandlers<Req, Resp> implements\n"
+           "    io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,\n"
+           "    io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>,\n"
+           "    io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>,\n"
+           "    io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> {\n"
+           "  private final $service_name$ serviceImpl;\n"
+           "  private final int methodId;\n"
+           "\n"
+           "  MethodHandlers($service_name$ serviceImpl, int methodId) {\n"
+           "    this.serviceImpl = serviceImpl;\n"
+           "    this.methodId = methodId;\n"
+           "  }\n\n");
+  p->Indent();
+  p->Print(vars,
+           "@$Override$\n"
+           "@java.lang.SuppressWarnings(\"unchecked\")\n"
+           "public void invoke(Req request, $StreamObserver$<Resp> "
+           "responseObserver) {\n"
+           "  switch (methodId) {\n");
+  p->Indent();
+  p->Indent();
+
+  for (int i = 0; i < service->method_count(); ++i) {
+    auto method = service->method(i);
+    if (method->ClientStreaming() || method->BidiStreaming()) {
+      continue;
+    }
+    vars["method_id_name"] = MethodIdFieldName(&*method);
+    vars["lower_method_name"] = LowerMethodName(&*method);
+    vars["input_type"] = JavaClassName(vars, method->get_input_type_name());
+    vars["output_type"] = JavaClassName(vars, method->get_output_type_name());
+    p->Print(vars,
+             "case $method_id_name$:\n"
+             "  serviceImpl.$lower_method_name$(($input_type$) request,\n"
+             "      ($StreamObserver$<$output_type$>) responseObserver);\n"
+             "  break;\n");
+  }
+  p->Print(
+      "default:\n"
+      "  throw new AssertionError();\n");
+
+  p->Outdent();
+  p->Outdent();
+  p->Print(
+      "  }\n"
+      "}\n\n");
+
+  p->Print(vars,
+           "@$Override$\n"
+           "@java.lang.SuppressWarnings(\"unchecked\")\n"
+           "public $StreamObserver$<Req> invoke(\n"
+           "    $StreamObserver$<Resp> responseObserver) {\n"
+           "  switch (methodId) {\n");
+  p->Indent();
+  p->Indent();
+
+  for (int i = 0; i < service->method_count(); ++i) {
+    auto method = service->method(i);
+    if (!(method->ClientStreaming() || method->BidiStreaming())) {
+      continue;
+    }
+    vars["method_id_name"] = MethodIdFieldName(&*method);
+    vars["lower_method_name"] = LowerMethodName(&*method);
+    vars["input_type"] = JavaClassName(vars, method->get_input_type_name());
+    vars["output_type"] = JavaClassName(vars, method->get_output_type_name());
+    p->Print(
+        vars,
+        "case $method_id_name$:\n"
+        "  return ($StreamObserver$<Req>) serviceImpl.$lower_method_name$(\n"
+        "      ($StreamObserver$<$output_type$>) responseObserver);\n");
+  }
+  p->Print(
+      "default:\n"
+      "  throw new AssertionError();\n");
+
+  p->Outdent();
+  p->Outdent();
+  p->Print(
+      "  }\n"
+      "}\n");
+
+  p->Outdent();
+  p->Print("}\n\n");
+}
+
+static void PrintGetServiceDescriptorMethod(Printer* p, VARS& vars,
+                                            const ServiceDescriptor* service) {
+  vars["service_name"] = service->name();
+  //        vars["proto_base_descriptor_supplier"] = service->name() +
+  //        "BaseDescriptorSupplier"; vars["proto_file_descriptor_supplier"] =
+  //        service->name() + "FileDescriptorSupplier";
+  //        vars["proto_method_descriptor_supplier"] = service->name() +
+  //        "MethodDescriptorSupplier"; vars["proto_class_name"] =
+  //        google::protobuf::compiler::java::ClassName(service->file());
+  //        p->Print(
+  //                 vars,
+  //                 "private static abstract class
+  //                 $proto_base_descriptor_supplier$\n" "    implements
+  //                 $ProtoFileDescriptorSupplier$,
+  //                 $ProtoServiceDescriptorSupplier$ {\n" "
+  //                 $proto_base_descriptor_supplier$() {}\n"
+  //                 "\n"
+  //                 "  @$Override$\n"
+  //                 "  public com.google.protobuf.Descriptors.FileDescriptor
+  //                 getFileDescriptor() {\n" "    return
+  //                 $proto_class_name$.getDescriptor();\n" "  }\n"
+  //                 "\n"
+  //                 "  @$Override$\n"
+  //                 "  public com.google.protobuf.Descriptors.ServiceDescriptor
+  //                 getServiceDescriptor() {\n" "    return
+  //                 getFileDescriptor().findServiceByName(\"$service_name$\");\n"
+  //                 "  }\n"
+  //                 "}\n"
+  //                 "\n"
+  //                 "private static final class
+  //                 $proto_file_descriptor_supplier$\n" "    extends
+  //                 $proto_base_descriptor_supplier$ {\n" "
+  //                 $proto_file_descriptor_supplier$() {}\n"
+  //                 "}\n"
+  //                 "\n"
+  //                 "private static final class
+  //                 $proto_method_descriptor_supplier$\n" "    extends
+  //                 $proto_base_descriptor_supplier$\n" "    implements
+  //                 $ProtoMethodDescriptorSupplier$ {\n" "  private final
+  //                 String methodName;\n"
+  //                 "\n"
+  //                 "  $proto_method_descriptor_supplier$(String methodName)
+  //                 {\n" "    this.methodName = methodName;\n" "  }\n"
+  //                 "\n"
+  //                 "  @$Override$\n"
+  //                 "  public com.google.protobuf.Descriptors.MethodDescriptor
+  //                 getMethodDescriptor() {\n" "    return
+  //                 getServiceDescriptor().findMethodByName(methodName);\n" "
+  //                 }\n"
+  //                 "}\n\n");
+
+  p->Print(
+      vars,
+      "private static volatile $ServiceDescriptor$ serviceDescriptor;\n\n");
+
+  p->Print(vars,
+           "public static $ServiceDescriptor$ getServiceDescriptor() {\n");
+  p->Indent();
+  p->Print(vars, "$ServiceDescriptor$ result = serviceDescriptor;\n");
+  p->Print("if (result == null) {\n");
+  p->Indent();
+  p->Print(vars, "synchronized ($service_class_name$.class) {\n");
+  p->Indent();
+  p->Print("result = serviceDescriptor;\n");
+  p->Print("if (result == null) {\n");
+  p->Indent();
+
+  p->Print(vars,
+           "serviceDescriptor = result = "
+           "$ServiceDescriptor$.newBuilder(SERVICE_NAME)");
+  p->Indent();
+  p->Indent();
+  p->Print(vars, "\n.setSchemaDescriptor(null)");
+  for (int i = 0; i < service->method_count(); ++i) {
+    auto method = service->method(i);
+    vars["method_method_name"] = MethodPropertiesGetterName(&*method);
+    p->Print(vars, "\n.addMethod($method_method_name$())");
+  }
+  p->Print("\n.build();\n");
+  p->Outdent();
+  p->Outdent();
+
+  p->Outdent();
+  p->Print("}\n");
+  p->Outdent();
+  p->Print("}\n");
+  p->Outdent();
+  p->Print("}\n");
+  p->Print("return result;\n");
+  p->Outdent();
+  p->Print("}\n");
+}
+
+static void PrintBindServiceMethodBody(Printer* p, VARS& vars,
+                                       const ServiceDescriptor* service) {
+  vars["service_name"] = service->name();
+  p->Indent();
+  p->Print(vars,
+           "return "
+           "$ServerServiceDefinition$.builder(getServiceDescriptor())\n");
+  p->Indent();
+  p->Indent();
+  for (int i = 0; i < service->method_count(); ++i) {
+    auto method = service->method(i);
+    vars["lower_method_name"] = LowerMethodName(&*method);
+    vars["method_method_name"] = MethodPropertiesGetterName(&*method);
+    vars["input_type"] = JavaClassName(vars, method->get_input_type_name());
+    vars["output_type"] = JavaClassName(vars, method->get_output_type_name());
+    vars["method_id_name"] = MethodIdFieldName(&*method);
+    bool client_streaming = method->ClientStreaming() || method->BidiStreaming();
+    bool server_streaming = method->ServerStreaming() || method->BidiStreaming();
+    if (client_streaming) {
+      if (server_streaming) {
+        vars["calls_method"] = "asyncBidiStreamingCall";
+      } else {
+        vars["calls_method"] = "asyncClientStreamingCall";
+      }
+    } else {
+      if (server_streaming) {
+        vars["calls_method"] = "asyncServerStreamingCall";
+      } else {
+        vars["calls_method"] = "asyncUnaryCall";
+      }
+    }
+    p->Print(vars, ".addMethod(\n");
+    p->Indent();
+    p->Print(vars,
+             "$method_method_name$(),\n"
+             "$calls_method$(\n");
+    p->Indent();
+    p->Print(vars,
+             "new MethodHandlers<\n"
+             "  $input_type$,\n"
+             "  $output_type$>(\n"
+             "    $instance$, $method_id_name$)))\n");
+    p->Outdent();
+    p->Outdent();
+  }
+  p->Print(".build();\n");
+  p->Outdent();
+  p->Outdent();
+  p->Outdent();
+}
+
+static void PrintService(Printer* p, VARS& vars,
+                         const ServiceDescriptor* service,
+                         bool disable_version) {
+  vars["service_name"] = service->name();
+  vars["service_class_name"] = ServiceClassName(service->name());
+  vars["grpc_version"] = "";
+#ifdef GRPC_VERSION
+  if (!disable_version) {
+    vars["grpc_version"] = " (version " XSTR(GRPC_VERSION) ")";
+  }
+#else
+  (void)disable_version;
+#endif
+  // TODO(nmittler): Replace with WriteServiceDocComment once included by
+  // protobuf distro.
+  GrpcWriteServiceDocComment(p, vars, service);
+  p->Print(vars,
+           "@$Generated$(\n"
+           "    value = \"by gRPC proto compiler$grpc_version$\",\n"
+           "    comments = \"Source: $file_name$.fbs\")\n"
+           "public final class $service_class_name$ {\n\n");
+  p->Indent();
+  p->Print(vars, "private $service_class_name$() {}\n\n");
+
+  p->Print(vars,
+           "public static final String SERVICE_NAME = "
+           "\"$Package$$service_name$\";\n\n");
+
+  PrintMethodFields(p, vars, service);
+
+  // TODO(nmittler): Replace with WriteDocComment once included by protobuf
+  // distro.
+  GrpcWriteDocComment(
+      p, vars,
+      " Creates a new async stub that supports all call types for the service");
+  p->Print(vars,
+           "public static $service_name$Stub newStub($Channel$ channel) {\n");
+  p->Indent();
+  p->Print(vars, "return new $service_name$Stub(channel);\n");
+  p->Outdent();
+  p->Print("}\n\n");
+
+  // TODO(nmittler): Replace with WriteDocComment once included by protobuf
+  // distro.
+  GrpcWriteDocComment(
+      p, vars,
+      " Creates a new blocking-style stub that supports unary and streaming "
+      "output calls on the service");
+  p->Print(vars,
+           "public static $service_name$BlockingStub newBlockingStub(\n"
+           "    $Channel$ channel) {\n");
+  p->Indent();
+  p->Print(vars, "return new $service_name$BlockingStub(channel);\n");
+  p->Outdent();
+  p->Print("}\n\n");
+
+  // TODO(nmittler): Replace with WriteDocComment once included by protobuf
+  // distro.
+  GrpcWriteDocComment(
+      p, vars,
+      " Creates a new ListenableFuture-style stub that supports unary calls "
+      "on the service");
+  p->Print(vars,
+           "public static $service_name$FutureStub newFutureStub(\n"
+           "    $Channel$ channel) {\n");
+  p->Indent();
+  p->Print(vars, "return new $service_name$FutureStub(channel);\n");
+  p->Outdent();
+  p->Print("}\n\n");
+
+  PrintStub(p, vars, service, ABSTRACT_CLASS);
+  PrintStub(p, vars, service, ASYNC_CLIENT_IMPL);
+  PrintStub(p, vars, service, BLOCKING_CLIENT_IMPL);
+  PrintStub(p, vars, service, FUTURE_CLIENT_IMPL);
+
+  PrintMethodHandlerClass(p, vars, service);
+  PrintGetServiceDescriptorMethod(p, vars, service);
+  p->Outdent();
+  p->Print("}\n");
+}
+
+void PrintStaticImports(Printer* p) {
+  p->Print(
+      "import java.nio.ByteBuffer;\n"
+      "import static "
+      "io.grpc.MethodDescriptor.generateFullMethodName;\n"
+      "import static "
+      "io.grpc.stub.ClientCalls.asyncBidiStreamingCall;\n"
+      "import static "
+      "io.grpc.stub.ClientCalls.asyncClientStreamingCall;\n"
+      "import static "
+      "io.grpc.stub.ClientCalls.asyncServerStreamingCall;\n"
+      "import static "
+      "io.grpc.stub.ClientCalls.asyncUnaryCall;\n"
+      "import static "
+      "io.grpc.stub.ClientCalls.blockingServerStreamingCall;\n"
+      "import static "
+      "io.grpc.stub.ClientCalls.blockingUnaryCall;\n"
+      "import static "
+      "io.grpc.stub.ClientCalls.futureUnaryCall;\n"
+      "import static "
+      "io.grpc.stub.ServerCalls.asyncBidiStreamingCall;\n"
+      "import static "
+      "io.grpc.stub.ServerCalls.asyncClientStreamingCall;\n"
+      "import static "
+      "io.grpc.stub.ServerCalls.asyncServerStreamingCall;\n"
+      "import static "
+      "io.grpc.stub.ServerCalls.asyncUnaryCall;\n"
+      "import static "
+      "io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;\n"
+      "import static "
+      "io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;\n\n");
+}
+
+void GenerateService(const grpc_generator::Service* service,
+                     grpc_generator::Printer* printer, VARS& vars,
+                     bool disable_version) {
+  // All non-generated classes must be referred by fully qualified names to
+  // avoid collision with generated classes.
+  vars["String"] = "java.lang.String";
+  vars["Deprecated"] = "java.lang.Deprecated";
+  vars["Override"] = "java.lang.Override";
+  vars["Channel"] = "io.grpc.Channel";
+  vars["CallOptions"] = "io.grpc.CallOptions";
+  vars["MethodType"] = "io.grpc.MethodDescriptor.MethodType";
+  vars["ServerMethodDefinition"] = "io.grpc.ServerMethodDefinition";
+  vars["BindableService"] = "io.grpc.BindableService";
+  vars["ServerServiceDefinition"] = "io.grpc.ServerServiceDefinition";
+  vars["ServiceDescriptor"] = "io.grpc.ServiceDescriptor";
+  vars["ProtoFileDescriptorSupplier"] =
+      "io.grpc.protobuf.ProtoFileDescriptorSupplier";
+  vars["ProtoServiceDescriptorSupplier"] =
+      "io.grpc.protobuf.ProtoServiceDescriptorSupplier";
+  vars["ProtoMethodDescriptorSupplier"] =
+      "io.grpc.protobuf.ProtoMethodDescriptorSupplier";
+  vars["AbstractStub"] = "io.grpc.stub.AbstractStub";
+  vars["MethodDescriptor"] = "io.grpc.MethodDescriptor";
+  vars["NanoUtils"] = "io.grpc.protobuf.nano.NanoUtils";
+  vars["StreamObserver"] = "io.grpc.stub.StreamObserver";
+  vars["Iterator"] = "java.util.Iterator";
+  vars["Generated"] = "javax.annotation.Generated";
+  vars["ListenableFuture"] =
+      "com.google.common.util.concurrent.ListenableFuture";
+  vars["ExperimentalApi"] = "io.grpc.ExperimentalApi";
+
+  PrintStaticImports(printer);
+
+  PrintService(printer, vars, service, disable_version);
+}
+
+grpc::string GenerateServiceSource(
+    grpc_generator::File* file, const grpc_generator::Service* service,
+    grpc_java_generator::Parameters* parameters) {
+  grpc::string out;
+  auto printer = file->CreatePrinter(&out);
+  VARS vars;
+  vars["flatc_version"] = grpc::string(
+      FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MAJOR) "." FLATBUFFERS_STRING(
+          FLATBUFFERS_VERSION_MINOR) "." FLATBUFFERS_STRING(FLATBUFFERS_VERSION_REVISION));
+
+  vars["file_name"] = file->filename();
+
+  if (!parameters->package_name.empty()) {
+    vars["Package"] = parameters->package_name;  // ServiceJavaPackage(service);
+  }
+  GenerateImports(file, &*printer, vars);
+  GenerateService(service, &*printer, vars, false);
+  return out;
+}
+
+}  // namespace grpc_java_generator
diff --git a/third_party/flatbuffers/grpc/src/compiler/java_generator.h b/third_party/flatbuffers/grpc/src/compiler/java_generator.h
new file mode 100644
index 0000000..b101fbf
--- /dev/null
+++ b/third_party/flatbuffers/grpc/src/compiler/java_generator.h
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+
+#ifndef NET_GRPC_COMPILER_JAVA_GENERATOR_H_
+#define NET_GRPC_COMPILER_JAVA_GENERATOR_H_
+
+#include <stdlib.h>  // for abort()
+#include <iostream>
+#include <map>
+#include <string>
+
+#include "src/compiler/schema_interface.h"
+
+class LogMessageVoidify {
+ public:
+  LogMessageVoidify() {}
+  // This has to be an operator with a precedence lower than << but
+  // higher than ?:
+  void operator&(std::ostream&) {}
+};
+
+class LogHelper {
+  std::ostream* os_;
+
+ public:
+  LogHelper(std::ostream* os) : os_(os) {}
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning( \
+    disable : 4722)  // the flow of control terminates in a destructor
+  // (needed to compile ~LogHelper where destructor emits abort intentionally -
+  // inherited from grpc/java code generator).
+#endif
+  ~LogHelper() {
+    *os_ << std::endl;
+    ::abort();
+  }
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+  std::ostream& get_os() const { return *os_; }
+};
+
+// Abort the program after logging the mesage if the given condition is not
+// true. Otherwise, do nothing.
+#define GRPC_CODEGEN_CHECK(x)                                            \
+  (x) ? (void)0                                                          \
+      : LogMessageVoidify() & LogHelper(&std::cerr).get_os()             \
+                                  << "CHECK FAILED: " << __FILE__ << ":" \
+                                  << __LINE__ << ": "
+
+// Abort the program after logging the mesage.
+#define GRPC_CODEGEN_FAIL GRPC_CODEGEN_CHECK(false)
+
+namespace grpc_java_generator {
+struct Parameters {
+  //        //Defines the custom parameter types for methods
+  //        //eg: flatbuffers uses flatbuffers.Builder as input for the client
+  //        and output for the server grpc::string custom_method_io_type;
+
+  // Package name for the service
+  grpc::string package_name;
+};
+
+// Return the source of the generated service file.
+grpc::string GenerateServiceSource(grpc_generator::File* file,
+                                   const grpc_generator::Service* service,
+                                   grpc_java_generator::Parameters* parameters);
+
+}  // namespace grpc_java_generator
+
+#endif  // NET_GRPC_COMPILER_JAVA_GENERATOR_H_
diff --git a/third_party/flatbuffers/grpc/src/compiler/schema_interface.h b/third_party/flatbuffers/grpc/src/compiler/schema_interface.h
new file mode 100644
index 0000000..2be2ed7
--- /dev/null
+++ b/third_party/flatbuffers/grpc/src/compiler/schema_interface.h
@@ -0,0 +1,126 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
+#define GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
+
+#include "src/compiler/config.h"
+
+#include <memory>
+#include <vector>
+
+#ifndef GRPC_CUSTOM_STRING
+#  include <string>
+#  define GRPC_CUSTOM_STRING std::string
+#endif
+
+namespace grpc {
+
+typedef GRPC_CUSTOM_STRING string;
+
+}  // namespace grpc
+
+namespace grpc_generator {
+
+// A common interface for objects having comments in the source.
+// Return formatted comments to be inserted in generated code.
+struct CommentHolder {
+  virtual ~CommentHolder() {}
+  virtual grpc::string GetLeadingComments(const grpc::string prefix) const = 0;
+  virtual grpc::string GetTrailingComments(const grpc::string prefix) const = 0;
+  virtual std::vector<grpc::string> GetAllComments() const = 0;
+};
+
+// An abstract interface representing a method.
+struct Method : public CommentHolder {
+  virtual ~Method() {}
+
+  virtual grpc::string name() const = 0;
+
+  virtual grpc::string input_type_name() const = 0;
+  virtual grpc::string output_type_name() const = 0;
+
+  virtual 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 = 0;
+  virtual 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 = 0;
+
+  virtual grpc::string get_input_type_name() const = 0;
+  virtual grpc::string get_output_type_name() const = 0;
+  virtual bool NoStreaming() const = 0;
+  virtual bool ClientStreaming() const = 0;
+  virtual bool ServerStreaming() const = 0;
+  virtual bool BidiStreaming() const = 0;
+};
+
+// An abstract interface representing a service.
+struct Service : public CommentHolder {
+  virtual ~Service() {}
+
+  virtual grpc::string name() const = 0;
+
+  virtual int method_count() const = 0;
+  virtual std::unique_ptr<const Method> method(int i) const = 0;
+};
+
+struct Printer {
+  virtual ~Printer() {}
+
+  virtual void Print(const std::map<grpc::string, grpc::string> &vars,
+                     const char *template_string) = 0;
+  virtual void Print(const char *string) = 0;
+  virtual void Indent() = 0;
+  virtual void Outdent() = 0;
+};
+
+// An interface that allows the source generated to be output using various
+// libraries/idls/serializers.
+struct File : public CommentHolder {
+  virtual ~File() {}
+
+  virtual grpc::string filename() const = 0;
+  virtual grpc::string filename_without_ext() const = 0;
+  virtual grpc::string package() const = 0;
+  virtual std::vector<grpc::string> package_parts() const = 0;
+  virtual grpc::string additional_headers() const = 0;
+
+  virtual int service_count() const = 0;
+  virtual std::unique_ptr<const Service> service(int i) const = 0;
+
+  virtual std::unique_ptr<Printer> CreatePrinter(grpc::string *str) const = 0;
+};
+}  // namespace grpc_generator
+
+#endif  // GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
diff --git a/third_party/flatbuffers/grpc/tests/GameFactory.java b/third_party/flatbuffers/grpc/tests/GameFactory.java
new file mode 100644
index 0000000..520ae39
--- /dev/null
+++ b/third_party/flatbuffers/grpc/tests/GameFactory.java
@@ -0,0 +1,42 @@
+import java.nio.ByteBuffer;
+import MyGame.Example.Monster;
+import MyGame.Example.Stat;
+import com.google.flatbuffers.FlatBufferBuilder;
+
+class GameFactory {
+  public static Monster createMonster(String monsterName, short nestedMonsterHp, short nestedMonsterMana) {
+    FlatBufferBuilder builder = new FlatBufferBuilder();
+
+    int name_offset = builder.createString(monsterName);
+    Monster.startMonster(builder);
+    Monster.addName(builder, name_offset);
+    Monster.addHp(builder, nestedMonsterHp);
+    Monster.addMana(builder, nestedMonsterMana);
+    int monster_offset = Monster.endMonster(builder);
+    Monster.finishMonsterBuffer(builder, monster_offset);
+
+    ByteBuffer buffer = builder.dataBuffer();
+    Monster monster = Monster.getRootAsMonster(buffer);
+    return monster;
+  }
+
+  public static Monster createMonsterFromStat(Stat stat, int seqNo) {
+    FlatBufferBuilder builder = new FlatBufferBuilder();
+    int name_offset = builder.createString(stat.id() + " No." + seqNo);
+    Monster.startMonster(builder);
+    Monster.addName(builder, name_offset);
+    int monster_offset = Monster.endMonster(builder);
+    Monster.finishMonsterBuffer(builder, monster_offset);
+    Monster monster = Monster.getRootAsMonster(builder.dataBuffer());
+    return monster;
+  }
+
+  public static Stat createStat(String greeting, long val, int count) { 
+    FlatBufferBuilder builder = new FlatBufferBuilder();
+    int statOffset = Stat.createStat(builder, builder.createString(greeting), val, count);
+    builder.finish(statOffset);
+    Stat stat = Stat.getRootAsStat(builder.dataBuffer());
+    return stat;
+  }
+
+}
diff --git a/third_party/flatbuffers/grpc/tests/JavaGrpcTest.java b/third_party/flatbuffers/grpc/tests/JavaGrpcTest.java
new file mode 100644
index 0000000..98a67b5
--- /dev/null
+++ b/third_party/flatbuffers/grpc/tests/JavaGrpcTest.java
@@ -0,0 +1,242 @@
+/*
+ * 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.
+ */
+
+import MyGame.Example.Monster;
+import MyGame.Example.MonsterStorageGrpc;
+import MyGame.Example.Stat;
+import com.google.flatbuffers.FlatBufferBuilder;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import io.grpc.Server;
+import io.grpc.ServerBuilder;
+import io.grpc.stub.StreamObserver;
+import org.junit.Assert;
+
+import java.io.IOException;
+import java.lang.InterruptedException;
+import java.nio.ByteBuffer;
+import java.util.Iterator;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.CountDownLatch;
+
+
+/**
+ * Demonstrates basic client-server interaction using grpc-java over netty.
+ */
+public class JavaGrpcTest {
+    static final String BIG_MONSTER_NAME = "Cyberdemon";
+    static final short nestedMonsterHp = 600;
+    static final short nestedMonsterMana = 1024;
+    static final int numStreamedMsgs = 10;
+    static final int timeoutMs = 3000;
+    static Server server;
+    static ManagedChannel channel;
+    static MonsterStorageGrpc.MonsterStorageBlockingStub blockingStub;
+    static MonsterStorageGrpc.MonsterStorageStub asyncStub;
+
+    static class MyService extends MonsterStorageGrpc.MonsterStorageImplBase {
+        @Override
+        public void store(Monster request, io.grpc.stub.StreamObserver<Stat> responseObserver) {
+            Assert.assertEquals(request.name(), BIG_MONSTER_NAME);
+            Assert.assertEquals(request.hp(), nestedMonsterHp);
+            Assert.assertEquals(request.mana(), nestedMonsterMana);
+            System.out.println("Received store request from " + request.name());
+            // Create a response from the incoming request name.
+            Stat stat = GameFactory.createStat("Hello " + request.name(), 100, 10);
+            responseObserver.onNext(stat);
+            responseObserver.onCompleted();
+        }
+
+        @Override
+        public void retrieve(Stat request, io.grpc.stub.StreamObserver<Monster> responseObserver) {
+            // Create 10 monsters for streaming response.
+            for (int i=0; i<numStreamedMsgs; i++) {
+                Monster monster = GameFactory.createMonsterFromStat(request, i);
+                responseObserver.onNext(monster);
+            }
+            responseObserver.onCompleted();
+        }
+
+        @Override
+        public StreamObserver<Monster> getMaxHitPoint(final StreamObserver<Stat> responseObserver) {
+          return computeMinMax(responseObserver, false);
+        }
+
+        @Override
+        public StreamObserver<Monster> getMinMaxHitPoints(final StreamObserver<Stat> responseObserver) {
+          return computeMinMax(responseObserver, true);
+        }
+
+        private StreamObserver<Monster> computeMinMax(final StreamObserver<Stat> responseObserver, final boolean includeMin) {
+          final AtomicInteger maxHp = new AtomicInteger(Integer.MIN_VALUE);
+          final AtomicReference<String> maxHpMonsterName = new AtomicReference<String>();
+          final AtomicInteger maxHpCount = new AtomicInteger();
+
+          final AtomicInteger minHp = new AtomicInteger(Integer.MAX_VALUE);
+          final AtomicReference<String> minHpMonsterName = new AtomicReference<String>();
+          final AtomicInteger minHpCount = new AtomicInteger();
+
+          return new StreamObserver<Monster>() {
+            public void onNext(Monster monster) {
+              if (monster.hp() > maxHp.get()) {
+                // Found a monster of higher hit points.
+                maxHp.set(monster.hp());
+                maxHpMonsterName.set(monster.name()); 
+                maxHpCount.set(1);
+              }
+              else if (monster.hp() == maxHp.get()) {
+                // Count how many times we saw a monster of current max hit points.
+                maxHpCount.getAndIncrement();
+              }
+
+              if (monster.hp() < minHp.get()) {
+                // Found a monster of a lower hit points.
+                minHp.set(monster.hp());
+                minHpMonsterName.set(monster.name());
+                minHpCount.set(1);
+              }
+              else if (monster.hp() == minHp.get()) {
+                // Count how many times we saw a monster of current min hit points.
+                minHpCount.getAndIncrement();
+              }
+            }
+            public void onCompleted() {
+              Stat maxHpStat = GameFactory.createStat(maxHpMonsterName.get(), maxHp.get(), maxHpCount.get());
+              // Send max hit points first.
+              responseObserver.onNext(maxHpStat);
+              if (includeMin) {
+                // Send min hit points.
+                Stat minHpStat = GameFactory.createStat(minHpMonsterName.get(), minHp.get(), minHpCount.get());
+                responseObserver.onNext(minHpStat);
+              }
+              responseObserver.onCompleted();
+            }
+            public void onError(Throwable t) {
+              // Not expected
+              Assert.fail();
+            };
+          };
+        }
+    }
+
+    @org.junit.BeforeClass
+    public static void startServer() throws IOException {
+        server = ServerBuilder.forPort(0).addService(new MyService()).build().start();
+        int port = server.getPort();
+        channel = ManagedChannelBuilder.forAddress("localhost", port)
+                // Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid
+                // needing certificates.
+                .usePlaintext(true)
+                .directExecutor()
+                .build();
+        blockingStub = MonsterStorageGrpc.newBlockingStub(channel);
+        asyncStub = MonsterStorageGrpc.newStub(channel);
+    }
+
+    @org.junit.Test
+    public void testUnary() throws IOException {
+        Monster monsterRequest = GameFactory.createMonster(BIG_MONSTER_NAME, nestedMonsterHp, nestedMonsterMana);
+        Stat stat = blockingStub.store(monsterRequest);
+        Assert.assertEquals(stat.id(), "Hello " + BIG_MONSTER_NAME);
+        System.out.println("Received stat response from service: " + stat.id());
+    }
+
+    @org.junit.Test
+    public void testServerStreaming() throws IOException {
+        Monster monsterRequest = GameFactory.createMonster(BIG_MONSTER_NAME, nestedMonsterHp, nestedMonsterMana);
+        Stat stat = blockingStub.store(monsterRequest);
+        Iterator<Monster> iterator = blockingStub.retrieve(stat);
+        int counter = 0;
+        while(iterator.hasNext()) {
+            Monster m = iterator.next();
+            System.out.println("Received monster " + m.name());
+            counter ++;
+        }
+        Assert.assertEquals(counter, numStreamedMsgs);
+        System.out.println("FlatBuffers GRPC client/server test: completed successfully");
+    }
+
+    @org.junit.Test
+    public void testClientStreaming() throws IOException, InterruptedException {
+      final AtomicReference<Stat> maxHitStat = new AtomicReference<Stat>();
+      final CountDownLatch streamAlive = new CountDownLatch(1);
+
+      StreamObserver<Stat> statObserver = new StreamObserver<Stat>() {
+        public void onCompleted() { 
+          streamAlive.countDown();
+        }
+        public void onError(Throwable ex) { }
+        public void onNext(Stat stat) {
+          maxHitStat.set(stat);
+        }
+      };
+      StreamObserver<Monster> monsterStream = asyncStub.getMaxHitPoint(statObserver);
+      short count = 10;
+      for (short i = 0;i < count; ++i) {
+        Monster monster = GameFactory.createMonster(BIG_MONSTER_NAME + i, (short) (nestedMonsterHp * i), nestedMonsterMana);
+        monsterStream.onNext(monster);
+      }
+      monsterStream.onCompleted();
+      // Wait a little bit for the server to send the stats of the monster with the max hit-points.
+      streamAlive.await(timeoutMs, TimeUnit.MILLISECONDS);
+      Assert.assertEquals(maxHitStat.get().id(), BIG_MONSTER_NAME + (count - 1));
+      Assert.assertEquals(maxHitStat.get().val(), nestedMonsterHp * (count - 1));
+      Assert.assertEquals(maxHitStat.get().count(), 1);
+    }
+
+    @org.junit.Test
+    public void testBiDiStreaming() throws IOException, InterruptedException {
+      final AtomicReference<Stat> maxHitStat = new AtomicReference<Stat>();
+      final AtomicReference<Stat> minHitStat = new AtomicReference<Stat>();
+      final CountDownLatch streamAlive = new CountDownLatch(1);
+
+      StreamObserver<Stat> statObserver = new StreamObserver<Stat>() {
+        public void onCompleted() {
+          streamAlive.countDown();
+        }
+        public void onError(Throwable ex) { }
+        public void onNext(Stat stat) {
+          // We expect the server to send the max stat first and then the min stat.
+          if (maxHitStat.get() == null) {
+            maxHitStat.set(stat);
+          }
+          else {
+            minHitStat.set(stat);
+          }
+        }
+      };
+      StreamObserver<Monster> monsterStream = asyncStub.getMinMaxHitPoints(statObserver);
+      short count = 10;
+      for (short i = 0;i < count; ++i) {
+        Monster monster = GameFactory.createMonster(BIG_MONSTER_NAME + i, (short) (nestedMonsterHp * i), nestedMonsterMana);
+        monsterStream.onNext(monster);
+      }
+      monsterStream.onCompleted();
+
+      // Wait a little bit for the server to send the stats of the monster with the max and min hit-points.
+      streamAlive.await(timeoutMs, TimeUnit.MILLISECONDS);
+
+      Assert.assertEquals(maxHitStat.get().id(), BIG_MONSTER_NAME + (count - 1));
+      Assert.assertEquals(maxHitStat.get().val(), nestedMonsterHp * (count - 1));
+      Assert.assertEquals(maxHitStat.get().count(), 1);
+
+      Assert.assertEquals(minHitStat.get().id(), BIG_MONSTER_NAME + 0);
+      Assert.assertEquals(minHitStat.get().val(), nestedMonsterHp * 0);
+      Assert.assertEquals(minHitStat.get().count(), 1);
+    }
+}
diff --git a/third_party/flatbuffers/grpc/tests/go_test.go b/third_party/flatbuffers/grpc/tests/go_test.go
new file mode 100644
index 0000000..288036b
--- /dev/null
+++ b/third_party/flatbuffers/grpc/tests/go_test.go
@@ -0,0 +1,93 @@
+package testing
+
+import (
+	"../../tests/MyGame/Example"
+
+	"context"
+	"net"
+	"testing"
+
+	"google.golang.org/grpc"
+)
+
+type server struct{}
+
+// test used to send and receive in grpc methods
+var test = "Flatbuffers"
+var addr = "0.0.0.0:50051"
+
+// gRPC server store method
+func (s *server) Store(context context.Context, in *Example.Monster) (*flatbuffers.Builder, error) {
+	b := flatbuffers.NewBuilder(0)
+	i := b.CreateString(test)
+	Example.StatStart(b)
+	Example.StatAddId(b, i)
+	b.Finish(Example.StatEnd(b))
+	return b, nil
+
+}
+
+// gRPC server retrieve method
+func (s *server) Retrieve(context context.Context, in *Example.Stat) (*flatbuffers.Builder, error) {
+	b := flatbuffers.NewBuilder(0)
+	i := b.CreateString(test)
+	Example.MonsterStart(b)
+	Example.MonsterAddName(b, i)
+	b.Finish(Example.MonsterEnd(b))
+	return b, nil
+}
+
+func StoreClient(c Example.MonsterStorageClient, t *testing.T) {
+	b := flatbuffers.NewBuilder(0)
+	i := b.CreateString(test)
+	Example.MonsterStart(b)
+	Example.MonsterAddName(b, i)
+	b.Finish(Example.MonsterEnd(b))
+	out, err := c.Store(context.Background(), b)
+	if err != nil {
+		t.Fatalf("Store client failed: %v", err)
+	}
+	if string(out.Id()) != test {
+		t.Errorf("StoreClient failed: expected=%s, got=%s\n", test, out.Id())
+		t.Fail()
+	}
+}
+
+func RetrieveClient(c Example.MonsterStorageClient, t *testing.T) {
+	b := flatbuffers.NewBuilder(0)
+	i := b.CreateString(test)
+	Example.StatStart(b)
+	Example.StatAddId(b, i)
+	b.Finish(Example.StatEnd(b))
+	out, err := c.Retrieve(context.Background(), b)
+	if err != nil {
+		t.Fatalf("Retrieve client failed: %v", err)
+	}
+	if string(out.Name()) != test {
+		t.Errorf("RetrieveClient failed: expected=%s, got=%s\n", test, out.Name())
+		t.Fail()
+	}
+}
+
+func TestGRPC(t *testing.T) {
+	lis, err := net.Listen("tcp", addr)
+	if err != nil {
+		t.Fatalf("Failed to listen: %v", err)
+	}
+	ser := grpc.NewServer(grpc.CustomCodec(flatbuffers.FlatbuffersCodec{}))
+	Example.RegisterMonsterStorageServer(ser, &server{})
+	go func() {
+		if err := ser.Serve(lis); err != nil {
+			t.Fatalf("Failed to serve: %v", err)
+			t.FailNow()
+		}
+	}()
+	conn, err := grpc.Dial(addr, grpc.WithInsecure(), grpc.WithCodec(flatbuffers.FlatbuffersCodec{}))
+	if err != nil {
+		t.Fatalf("Failed to connect: %v", err)
+	}
+	defer conn.Close()
+	client := Example.NewMonsterStorageClient(conn)
+	StoreClient(client, t)
+	RetrieveClient(client, t)
+}
diff --git a/third_party/flatbuffers/grpc/tests/grpctest.cpp b/third_party/flatbuffers/grpc/tests/grpctest.cpp
new file mode 100644
index 0000000..7e5c6e6
--- /dev/null
+++ b/third_party/flatbuffers/grpc/tests/grpctest.cpp
@@ -0,0 +1,196 @@
+/*
+ * 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 <thread>
+
+#include <grpc++/grpc++.h>
+
+#include "monster_test.grpc.fb.h"
+#include "monster_test_generated.h"
+#include "test_assert.h"
+
+using namespace MyGame::Example;
+using flatbuffers::grpc::MessageBuilder;
+using flatbuffers::FlatBufferBuilder;
+
+void message_builder_tests();
+
+// The callback implementation of our server, that derives from the generated
+// code. It implements all rpcs specified in the FlatBuffers schema.
+class ServiceImpl final : public MyGame::Example::MonsterStorage::Service {
+  virtual ::grpc::Status Store(
+      ::grpc::ServerContext *context,
+      const flatbuffers::grpc::Message<Monster> *request,
+      flatbuffers::grpc::Message<Stat> *response) override {
+    // Create a response from the incoming request name.
+    fbb_.Clear();
+    auto stat_offset = CreateStat(
+        fbb_, fbb_.CreateString("Hello, " + request->GetRoot()->name()->str()));
+    fbb_.Finish(stat_offset);
+    // Transfer ownership of the message to gRPC
+    *response = fbb_.ReleaseMessage<Stat>();
+    return grpc::Status::OK;
+  }
+  virtual ::grpc::Status Retrieve(
+      ::grpc::ServerContext *context,
+      const flatbuffers::grpc::Message<Stat> *request,
+      ::grpc::ServerWriter<flatbuffers::grpc::Message<Monster>> *writer)
+      override {
+    for (int i = 0; i < 5; i++) {
+      fbb_.Clear();
+      // Create 5 monsters for resposne.
+      auto monster_offset =
+          CreateMonster(fbb_, 0, 0, 0,
+                        fbb_.CreateString(request->GetRoot()->id()->str() +
+                                          " No." + std::to_string(i)));
+      fbb_.Finish(monster_offset);
+
+      flatbuffers::grpc::Message<Monster> monster =
+          fbb_.ReleaseMessage<Monster>();
+
+      // Send monster to client using streaming.
+      writer->Write(monster);
+    }
+    return grpc::Status::OK;
+  }
+
+ private:
+  flatbuffers::grpc::MessageBuilder fbb_;
+};
+
+// Track the server instance, so we can terminate it later.
+grpc::Server *server_instance = nullptr;
+// Mutex to protec this variable.
+std::mutex wait_for_server;
+std::condition_variable server_instance_cv;
+
+// This function implements the server thread.
+void RunServer() {
+  auto server_address = "0.0.0.0:50051";
+  // Callback interface we implemented above.
+  ServiceImpl service;
+  grpc::ServerBuilder builder;
+  builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
+  builder.RegisterService(&service);
+
+  // Start the server. Lock to change the variable we're changing.
+  wait_for_server.lock();
+  server_instance = builder.BuildAndStart().release();
+  wait_for_server.unlock();
+  server_instance_cv.notify_one();
+
+  std::cout << "Server listening on " << server_address << std::endl;
+  // This will block the thread and serve requests.
+  server_instance->Wait();
+}
+
+template <class Builder>
+void StoreRPC(MonsterStorage::Stub *stub) {
+  Builder fbb;
+  grpc::ClientContext context;
+  // Build a request with the name set.
+  auto monster_offset = CreateMonster(fbb, 0, 0, 0, fbb.CreateString("Fred"));
+  MessageBuilder mb(std::move(fbb));
+  mb.Finish(monster_offset);
+  auto request = mb.ReleaseMessage<Monster>();
+  flatbuffers::grpc::Message<Stat> response;
+
+  // The actual RPC.
+  auto status = stub->Store(&context, request, &response);
+
+  if (status.ok()) {
+    auto resp = response.GetRoot()->id();
+    std::cout << "RPC response: " << resp->str() << std::endl;
+  } else {
+    std::cout << "RPC failed" << std::endl;
+  }
+}
+
+template <class Builder>
+void RetrieveRPC(MonsterStorage::Stub *stub) {
+  Builder fbb;
+  grpc::ClientContext context;
+  fbb.Clear();
+  auto stat_offset = CreateStat(fbb, fbb.CreateString("Fred"));
+  fbb.Finish(stat_offset);
+  auto request = MessageBuilder(std::move(fbb)).ReleaseMessage<Stat>();
+
+  flatbuffers::grpc::Message<Monster> response;
+  auto stream = stub->Retrieve(&context, request);
+  while (stream->Read(&response)) {
+    auto resp = response.GetRoot()->name();
+    std::cout << "RPC Streaming response: " << resp->str() << std::endl;
+  }
+}
+
+int grpc_server_test() {
+  // Launch server.
+  std::thread server_thread(RunServer);
+
+  // wait for server to spin up.
+  std::unique_lock<std::mutex> lock(wait_for_server);
+  while (!server_instance) server_instance_cv.wait(lock);
+
+  // Now connect the client.
+  auto channel = grpc::CreateChannel("localhost:50051",
+                                     grpc::InsecureChannelCredentials());
+  auto stub = MyGame::Example::MonsterStorage::NewStub(channel);
+
+  StoreRPC<MessageBuilder>(stub.get());
+  StoreRPC<FlatBufferBuilder>(stub.get());
+
+  RetrieveRPC<MessageBuilder>(stub.get());
+  RetrieveRPC<FlatBufferBuilder>(stub.get());
+
+
+#if !FLATBUFFERS_GRPC_DISABLE_AUTO_VERIFICATION
+  {
+    // Test that an invalid request errors out correctly
+    grpc::ClientContext context;
+    flatbuffers::grpc::Message<Monster> request;  // simulate invalid message
+    flatbuffers::grpc::Message<Stat> response;
+    auto status = stub->Store(&context, request, &response);
+    // The rpc status should be INTERNAL to indicate a verification error. This
+    // matches the protobuf gRPC status code for an unparseable message.
+    assert(!status.ok());
+    assert(status.error_code() == ::grpc::StatusCode::INTERNAL);
+    assert(strcmp(status.error_message().c_str(),
+                  "Message verification failed") == 0);
+  }
+#endif
+
+  server_instance->Shutdown();
+
+  server_thread.join();
+
+  delete server_instance;
+
+  return 0;
+}
+
+int main(int /*argc*/, const char * /*argv*/ []) {
+  message_builder_tests();
+  grpc_server_test();
+
+  if (!testing_fails) {
+    TEST_OUTPUT_LINE("ALL TESTS PASSED");
+    return 0;
+  } else {
+    TEST_OUTPUT_LINE("%d FAILED TESTS", testing_fails);
+    return 1;
+  }
+}
+
diff --git a/third_party/flatbuffers/grpc/tests/java-grpc-test.sh b/third_party/flatbuffers/grpc/tests/java-grpc-test.sh
new file mode 100755
index 0000000..ec42960
--- /dev/null
+++ b/third_party/flatbuffers/grpc/tests/java-grpc-test.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+# NOTE: make sure `mvn install` in /gprc is executed before running this test
+mvn test
diff --git a/third_party/flatbuffers/grpc/tests/message_builder_test.cpp b/third_party/flatbuffers/grpc/tests/message_builder_test.cpp
new file mode 100644
index 0000000..36f5bc2
--- /dev/null
+++ b/third_party/flatbuffers/grpc/tests/message_builder_test.cpp
@@ -0,0 +1,340 @@
+#include "flatbuffers/grpc.h"
+#include "monster_test_generated.h"
+#include "test_assert.h"
+#include "test_builder.h"
+
+using MyGame::Example::Vec3;
+using MyGame::Example::CreateStat;
+using MyGame::Example::Any_NONE;
+
+bool verify(flatbuffers::grpc::Message<Monster> &msg, const std::string &expected_name, Color color) {
+  const Monster *monster = msg.GetRoot();
+  return (monster->name()->str() == expected_name) && (monster->color() == color);
+}
+
+bool release_n_verify(flatbuffers::grpc::MessageBuilder &mbb, const std::string &expected_name, Color color) {
+  flatbuffers::grpc::Message<Monster> msg = mbb.ReleaseMessage<Monster>();
+  const Monster *monster = msg.GetRoot();
+  return (monster->name()->str() == expected_name) && (monster->color() == color);
+}
+
+void builder_move_assign_after_releaseraw_test(flatbuffers::grpc::MessageBuilder dst) {
+  auto root_offset1 = populate1(dst);
+  dst.Finish(root_offset1);
+  size_t size, offset;
+  grpc_slice slice;
+  dst.ReleaseRaw(size, offset, slice);
+  flatbuffers::FlatBufferBuilder src;
+  auto root_offset2 = populate2(src);
+  src.Finish(root_offset2);
+  auto src_size = src.GetSize();
+  // Move into a released builder.
+  dst = std::move(src);
+  TEST_EQ(dst.GetSize(), src_size);
+  TEST_ASSERT(release_n_verify(dst, m2_name, m2_color));
+  TEST_EQ(src.GetSize(), 0);
+  grpc_slice_unref(slice);
+}
+
+template <class SrcBuilder>
+struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
+  static void builder_reusable_after_release_message_test(TestSelector selector) {
+    if (!selector.count(REUSABLE_AFTER_RELEASE_MESSAGE)) {
+      return;
+    }
+
+    flatbuffers::grpc::MessageBuilder mb;
+    std::vector<flatbuffers::grpc::Message<Monster>> buffers;
+    for (int i = 0; i < 5; ++i) {
+      auto root_offset1 = populate1(mb);
+      mb.Finish(root_offset1);
+      buffers.push_back(mb.ReleaseMessage<Monster>());
+      TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
+    }
+  }
+
+  static void builder_reusable_after_release_test(TestSelector selector) {
+    if (!selector.count(REUSABLE_AFTER_RELEASE)) {
+      return;
+    }
+
+    // FIXME: Populate-Release loop fails assert(GRPC_SLICE_IS_EMPTY(slice_)) in SliceAllocator::allocate
+    // in the second iteration.
+
+    flatbuffers::grpc::MessageBuilder mb;
+    std::vector<flatbuffers::DetachedBuffer> buffers;
+    for (int i = 0; i < 2; ++i) {
+      auto root_offset1 = populate1(mb);
+      mb.Finish(root_offset1);
+      buffers.push_back(mb.Release());
+      TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
+    }
+  }
+
+  static void builder_reusable_after_releaseraw_test(TestSelector selector) {
+    if (!selector.count(REUSABLE_AFTER_RELEASE_RAW)) {
+      return;
+    }
+
+    flatbuffers::grpc::MessageBuilder mb;
+    for (int i = 0; i < 5; ++i) {
+      auto root_offset1 = populate1(mb);
+      mb.Finish(root_offset1);
+      size_t size, offset;
+      grpc_slice slice;
+      const uint8_t *buf = mb.ReleaseRaw(size, offset, slice);
+      TEST_ASSERT_FUNC(verify(buf, offset, m1_name, m1_color));
+      grpc_slice_unref(slice);
+    }
+  }
+
+  static void builder_reusable_after_release_and_move_assign_test(TestSelector selector) {
+    if (!selector.count(REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN)) {
+      return;
+    }
+
+    // FIXME: Release-move_assign loop fails assert(p == GRPC_SLICE_START_PTR(slice_))
+    // in DetachedBuffer destructor after all the iterations
+
+    flatbuffers::grpc::MessageBuilder dst;
+    std::vector<flatbuffers::DetachedBuffer> buffers;
+
+    for (int i = 0; i < 2; ++i) {
+      auto root_offset1 = populate1(dst);
+      dst.Finish(root_offset1);
+      buffers.push_back(dst.Release());
+      TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
+
+      // bring dst back to life.
+      SrcBuilder src;
+      dst = std::move(src);
+      TEST_EQ_FUNC(dst.GetSize(), 0);
+      TEST_EQ_FUNC(src.GetSize(), 0);
+    }
+  }
+
+  static void builder_reusable_after_release_message_and_move_assign_test(TestSelector selector) {
+    if (!selector.count(REUSABLE_AFTER_RELEASE_MESSAGE_AND_MOVE_ASSIGN)) {
+      return;
+    }
+
+    flatbuffers::grpc::MessageBuilder dst;
+    std::vector<flatbuffers::grpc::Message<Monster>> buffers;
+
+    for (int i = 0; i < 5; ++i) {
+      auto root_offset1 = populate1(dst);
+      dst.Finish(root_offset1);
+      buffers.push_back(dst.ReleaseMessage<Monster>());
+      TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
+
+      // bring dst back to life.
+      SrcBuilder src;
+      dst = std::move(src);
+      TEST_EQ_FUNC(dst.GetSize(), 0);
+      TEST_EQ_FUNC(src.GetSize(), 0);
+    }
+  }
+
+  static void builder_reusable_after_releaseraw_and_move_assign_test(TestSelector selector) {
+    if (!selector.count(REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN)) {
+      return;
+    }
+
+    flatbuffers::grpc::MessageBuilder dst;
+    for (int i = 0; i < 5; ++i) {
+      auto root_offset1 = populate1(dst);
+      dst.Finish(root_offset1);
+      size_t size, offset;
+      grpc_slice slice = grpc_empty_slice();
+      const uint8_t *buf = dst.ReleaseRaw(size, offset, slice);
+      TEST_ASSERT_FUNC(verify(buf, offset, m1_name, m1_color));
+      grpc_slice_unref(slice);
+
+      SrcBuilder src;
+      dst = std::move(src);
+      TEST_EQ_FUNC(dst.GetSize(), 0);
+      TEST_EQ_FUNC(src.GetSize(), 0);
+    }
+  }
+
+  static void run_tests(TestSelector selector) {
+    builder_reusable_after_release_test(selector);
+    builder_reusable_after_release_message_test(selector);
+    builder_reusable_after_releaseraw_test(selector);
+    builder_reusable_after_release_and_move_assign_test(selector);
+    builder_reusable_after_releaseraw_and_move_assign_test(selector);
+    builder_reusable_after_release_message_and_move_assign_test(selector);
+  }
+};
+
+void slice_allocator_tests() {
+  // move-construct no-delete test
+  {
+    size_t size = 2048;
+    flatbuffers::grpc::SliceAllocator sa1;
+    uint8_t *buf = sa1.allocate(size);
+    TEST_ASSERT_FUNC(buf != 0);
+    buf[0] = 100;
+    buf[size-1] = 200;
+    flatbuffers::grpc::SliceAllocator sa2(std::move(sa1));
+    // buf should not be deleted after move-construct
+    TEST_EQ_FUNC(buf[0], 100);
+    TEST_EQ_FUNC(buf[size-1], 200);
+    // buf is freed here
+  }
+
+  // move-assign test
+  {
+    flatbuffers::grpc::SliceAllocator sa1, sa2;
+    uint8_t *buf = sa1.allocate(2048);
+    sa1 = std::move(sa2);
+    // sa1 deletes previously allocated memory in move-assign.
+    // So buf is no longer usable here.
+    TEST_ASSERT_FUNC(buf != 0);
+  }
+}
+
+/// This function does not populate exactly the first half of the table. But it could.
+void populate_first_half(MyGame::Example::MonsterBuilder &wrapper, flatbuffers::Offset<flatbuffers::String> name_offset) {
+  wrapper.add_name(name_offset);
+  wrapper.add_color(m1_color);
+}
+
+/// This function does not populate exactly the second half of the table. But it could.
+void populate_second_half(MyGame::Example::MonsterBuilder &wrapper) {
+  wrapper.add_hp(77);
+  wrapper.add_mana(88);
+  Vec3 vec3;
+  wrapper.add_pos(&vec3);
+}
+
+/// This function is a hack to update the FlatBufferBuilder reference (fbb_) in the MonsterBuilder object.
+/// This function will break if fbb_ is not the first member in MonsterBuilder. In that case, some offset must be added.
+/// This function is used exclusively for testing correctness of move operations between FlatBufferBuilders.
+/// If MonsterBuilder had a fbb_ pointer, this hack would be unnecessary. That involves a code-generator change though.
+void test_only_hack_update_fbb_reference(MyGame::Example::MonsterBuilder &monsterBuilder,
+                                         flatbuffers::grpc::MessageBuilder &mb) {
+  *reinterpret_cast<flatbuffers::FlatBufferBuilder **>(&monsterBuilder) = &mb;
+}
+
+/// This test validates correctness of move conversion of FlatBufferBuilder to a MessageBuilder DURING
+/// a table construction. Half of the table is constructed using FlatBufferBuilder and the other half
+/// of the table is constructed using a MessageBuilder.
+void builder_move_ctor_conversion_before_finish_half_n_half_table_test() {
+  for (size_t initial_size = 4 ; initial_size <= 2048; initial_size *= 2) {
+    flatbuffers::FlatBufferBuilder fbb(initial_size);
+    auto name_offset = fbb.CreateString(m1_name);
+    MyGame::Example::MonsterBuilder monsterBuilder(fbb);     // starts a table in FlatBufferBuilder
+    populate_first_half(monsterBuilder, name_offset);
+    flatbuffers::grpc::MessageBuilder mb(std::move(fbb));
+    test_only_hack_update_fbb_reference(monsterBuilder, mb); // hack
+    populate_second_half(monsterBuilder);
+    mb.Finish(monsterBuilder.Finish());                      // ends the table in MessageBuilder
+    TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
+    TEST_EQ_FUNC(fbb.GetSize(), 0);
+  }
+}
+
+/// This test populates a COMPLETE inner table before move conversion and later populates more members in the outer table.
+void builder_move_ctor_conversion_before_finish_test() {
+  for (size_t initial_size = 4 ; initial_size <= 2048; initial_size *= 2) {
+    flatbuffers::FlatBufferBuilder fbb(initial_size);
+    auto stat_offset = CreateStat(fbb, fbb.CreateString("SomeId"), 0, 0);
+    flatbuffers::grpc::MessageBuilder mb(std::move(fbb));
+    auto monster_offset = CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name), 0, m1_color, Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset);
+    mb.Finish(monster_offset);
+    TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
+    TEST_EQ_FUNC(fbb.GetSize(), 0);
+  }
+}
+
+/// This test validates correctness of move conversion of FlatBufferBuilder to a MessageBuilder DURING
+/// a table construction. Half of the table is constructed using FlatBufferBuilder and the other half
+/// of the table is constructed using a MessageBuilder.
+void builder_move_assign_conversion_before_finish_half_n_half_table_test() {
+  flatbuffers::FlatBufferBuilder fbb;
+  flatbuffers::grpc::MessageBuilder mb;
+
+  for (int i = 0;i < 5; ++i) {
+    flatbuffers::FlatBufferBuilder fbb;
+    auto name_offset = fbb.CreateString(m1_name);
+    MyGame::Example::MonsterBuilder monsterBuilder(fbb);     // starts a table in FlatBufferBuilder
+    populate_first_half(monsterBuilder, name_offset);
+    mb = std::move(fbb);
+    test_only_hack_update_fbb_reference(monsterBuilder, mb); // hack
+    populate_second_half(monsterBuilder);
+    mb.Finish(monsterBuilder.Finish());                      // ends the table in MessageBuilder
+    TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
+    TEST_EQ_FUNC(fbb.GetSize(), 0);
+  }
+}
+
+/// This test populates a COMPLETE inner table before move conversion and later populates more members in the outer table.
+void builder_move_assign_conversion_before_finish_test() {
+  flatbuffers::FlatBufferBuilder fbb;
+  flatbuffers::grpc::MessageBuilder mb;
+
+  for (int i = 0;i < 5; ++i) {
+    auto stat_offset = CreateStat(fbb, fbb.CreateString("SomeId"), 0, 0);
+    mb = std::move(fbb);
+    auto monster_offset = CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name), 0, m1_color, Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset);
+    mb.Finish(monster_offset);
+    TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
+    TEST_EQ_FUNC(fbb.GetSize(), 0);
+  }
+}
+
+/// This test populates data, finishes the buffer, and does move conversion after.
+void builder_move_ctor_conversion_after_finish_test() {
+  flatbuffers::FlatBufferBuilder fbb;
+  fbb.Finish(populate1(fbb));
+  flatbuffers::grpc::MessageBuilder mb(std::move(fbb));
+  TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
+  TEST_EQ_FUNC(fbb.GetSize(), 0);
+}
+
+/// This test populates data, finishes the buffer, and does move conversion after.
+void builder_move_assign_conversion_after_finish_test() {
+  flatbuffers::FlatBufferBuilder fbb;
+  flatbuffers::grpc::MessageBuilder mb;
+
+  for (int i = 0;i < 5; ++i) {
+    fbb.Finish(populate1(fbb));
+    mb = std::move(fbb);
+    TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
+    TEST_EQ_FUNC(fbb.GetSize(), 0);
+  }
+}
+
+void message_builder_tests() {
+  using flatbuffers::grpc::MessageBuilder;
+  using flatbuffers::FlatBufferBuilder;
+
+  slice_allocator_tests();
+
+#ifndef __APPLE__
+  builder_move_ctor_conversion_before_finish_half_n_half_table_test();
+  builder_move_assign_conversion_before_finish_half_n_half_table_test();
+#endif // __APPLE__
+  builder_move_ctor_conversion_before_finish_test();
+  builder_move_assign_conversion_before_finish_test();
+
+  builder_move_ctor_conversion_after_finish_test();
+  builder_move_assign_conversion_after_finish_test();
+
+  BuilderTests<MessageBuilder, MessageBuilder>::all_tests();
+  BuilderTests<MessageBuilder, FlatBufferBuilder>::all_tests();
+
+  BuilderReuseTestSelector tests[6] = {
+    //REUSABLE_AFTER_RELEASE,                 // Assertion failed: (GRPC_SLICE_IS_EMPTY(slice_))
+    //REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN, // Assertion failed: (p == GRPC_SLICE_START_PTR(slice_)
+
+    REUSABLE_AFTER_RELEASE_RAW,
+    REUSABLE_AFTER_RELEASE_MESSAGE,
+    REUSABLE_AFTER_RELEASE_MESSAGE_AND_MOVE_ASSIGN,
+    REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN
+  };
+
+  BuilderReuseTests<MessageBuilder, MessageBuilder>::run_tests(TestSelector(tests, tests+6));
+  BuilderReuseTests<MessageBuilder, FlatBufferBuilder>::run_tests(TestSelector(tests, tests+6));
+}
diff --git a/third_party/flatbuffers/grpc/tests/pom.xml b/third_party/flatbuffers/grpc/tests/pom.xml
new file mode 100644
index 0000000..addc9fa
--- /dev/null
+++ b/third_party/flatbuffers/grpc/tests/pom.xml
@@ -0,0 +1,73 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.google.flatbuffers</groupId>
+        <artifactId>flatbuffers-parent</artifactId>
+        <version>1.11.1</version>
+    </parent>
+    <artifactId>grpc-test</artifactId>
+    <description>Example/Test project demonstrating usage of flatbuffers with GRPC-Java instead of protobufs
+    </description>
+    <properties>
+        <gRPC.version>1.11.1</gRPC.version>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>com.google.flatbuffers</groupId>
+            <artifactId>flatbuffers-java</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.google.flatbuffers</groupId>
+            <artifactId>flatbuffers-java-grpc</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+            <version>${gRPC.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+            <version>${gRPC.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.12</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>add-source</id>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>add-test-source</goal>
+                        </goals>
+                        <configuration>
+                            <sources>
+                                <source>${project.basedir}</source>
+				<source>${project.basedir}/../../tests</source>
+                            </sources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+        <!--<testSourceDirectory>${project.basedir}</testSourceDirectory>-->
+    </build>
+</project>
+
diff --git a/third_party/flatbuffers/include/flatbuffers/base.h b/third_party/flatbuffers/include/flatbuffers/base.h
new file mode 100644
index 0000000..d98da13
--- /dev/null
+++ b/third_party/flatbuffers/include/flatbuffers/base.h
@@ -0,0 +1,392 @@
+#ifndef FLATBUFFERS_BASE_H_
+#define FLATBUFFERS_BASE_H_
+
+// clang-format off
+
+// If activate should be declared and included first.
+#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && \
+    defined(_MSC_VER) && defined(_DEBUG)
+  // The _CRTDBG_MAP_ALLOC inside <crtdbg.h> will replace
+  // calloc/free (etc) to its debug version using #define directives.
+  #define _CRTDBG_MAP_ALLOC
+  #include <stdlib.h>
+  #include <crtdbg.h>
+  // Replace operator new by trace-enabled version.
+  #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
+  #define new DEBUG_NEW
+#endif
+
+#if !defined(FLATBUFFERS_ASSERT)
+#include <assert.h>
+#define FLATBUFFERS_ASSERT assert
+#elif defined(FLATBUFFERS_ASSERT_INCLUDE)
+// Include file with forward declaration
+#include FLATBUFFERS_ASSERT_INCLUDE
+#endif
+
+#ifndef ARDUINO
+#include <cstdint>
+#endif
+
+#include <cstddef>
+#include <cstdlib>
+#include <cstring>
+
+#if defined(ARDUINO) && !defined(ARDUINOSTL_M_H)
+  #include <utility.h>
+#else
+  #include <utility>
+#endif
+
+#include <string>
+#include <type_traits>
+#include <vector>
+#include <set>
+#include <algorithm>
+#include <iterator>
+#include <memory>
+
+#ifdef _STLPORT_VERSION
+  #define FLATBUFFERS_CPP98_STL
+#endif
+#ifndef FLATBUFFERS_CPP98_STL
+  #include <functional>
+#endif
+
+#include "flatbuffers/stl_emulation.h"
+
+#if defined(__ICCARM__)
+#include <intrinsics.h>
+#endif
+
+// Note the __clang__ check is needed, because clang presents itself
+// as an older GNUC compiler (4.2).
+// Clang 3.3 and later implement all of the ISO C++ 2011 standard.
+// Clang 3.4 and later implement all of the ISO C++ 2014 standard.
+// http://clang.llvm.org/cxx_status.html
+
+// Note the MSVC value '__cplusplus' may be incorrect:
+// The '__cplusplus' predefined macro in the MSVC stuck at the value 199711L,
+// indicating (erroneously!) that the compiler conformed to the C++98 Standard.
+// This value should be correct starting from MSVC2017-15.7-Preview-3.
+// The '__cplusplus' will be valid only if MSVC2017-15.7-P3 and the `/Zc:__cplusplus` switch is set.
+// Workaround (for details see MSDN):
+// Use the _MSC_VER and _MSVC_LANG definition instead of the __cplusplus  for compatibility.
+// The _MSVC_LANG macro reports the Standard version regardless of the '/Zc:__cplusplus' switch.
+
+#if defined(__GNUC__) && !defined(__clang__)
+  #define FLATBUFFERS_GCC (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+#else
+  #define FLATBUFFERS_GCC 0
+#endif
+
+#if defined(__clang__)
+  #define FLATBUFFERS_CLANG (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
+#else
+  #define FLATBUFFERS_CLANG 0
+#endif
+
+/// @cond FLATBUFFERS_INTERNAL
+#if __cplusplus <= 199711L && \
+    (!defined(_MSC_VER) || _MSC_VER < 1600) && \
+    (!defined(__GNUC__) || \
+      (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40400))
+  #error A C++11 compatible compiler with support for the auto typing is \
+         required for FlatBuffers.
+  #error __cplusplus _MSC_VER __GNUC__  __GNUC_MINOR__  __GNUC_PATCHLEVEL__
+#endif
+
+#if !defined(__clang__) && \
+    defined(__GNUC__) && \
+    (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40600)
+  // Backwards compatability for g++ 4.4, and 4.5 which don't have the nullptr
+  // and constexpr keywords. Note the __clang__ check is needed, because clang
+  // presents itself as an older GNUC compiler.
+  #ifndef nullptr_t
+    const class nullptr_t {
+    public:
+      template<class T> inline operator T*() const { return 0; }
+    private:
+      void operator&() const;
+    } nullptr = {};
+  #endif
+  #ifndef constexpr
+    #define constexpr const
+  #endif
+#endif
+
+// The wire format uses a little endian encoding (since that's efficient for
+// the common platforms).
+#if defined(__s390x__)
+  #define FLATBUFFERS_LITTLEENDIAN 0
+#endif // __s390x__
+#if !defined(FLATBUFFERS_LITTLEENDIAN)
+  #if defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__)
+    #if (defined(__BIG_ENDIAN__) || \
+         (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
+      #define FLATBUFFERS_LITTLEENDIAN 0
+    #else
+      #define FLATBUFFERS_LITTLEENDIAN 1
+    #endif // __BIG_ENDIAN__
+  #elif defined(_MSC_VER)
+    #if defined(_M_PPC)
+      #define FLATBUFFERS_LITTLEENDIAN 0
+    #else
+      #define FLATBUFFERS_LITTLEENDIAN 1
+    #endif
+  #else
+    #error Unable to determine endianness, define FLATBUFFERS_LITTLEENDIAN.
+  #endif
+#endif // !defined(FLATBUFFERS_LITTLEENDIAN)
+
+#define FLATBUFFERS_VERSION_MAJOR 1
+#define FLATBUFFERS_VERSION_MINOR 11
+#define FLATBUFFERS_VERSION_REVISION 0
+#define FLATBUFFERS_STRING_EXPAND(X) #X
+#define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X)
+namespace flatbuffers {
+  // Returns version as string  "MAJOR.MINOR.REVISION".
+  const char* FLATBUFFERS_VERSION();
+}
+
+#if (!defined(_MSC_VER) || _MSC_VER > 1600) && \
+    (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 407)) || \
+    defined(__clang__)
+  #define FLATBUFFERS_FINAL_CLASS final
+  #define FLATBUFFERS_OVERRIDE override
+  #define FLATBUFFERS_VTABLE_UNDERLYING_TYPE : flatbuffers::voffset_t
+#else
+  #define FLATBUFFERS_FINAL_CLASS
+  #define FLATBUFFERS_OVERRIDE
+  #define FLATBUFFERS_VTABLE_UNDERLYING_TYPE
+#endif
+
+#if (!defined(_MSC_VER) || _MSC_VER >= 1900) && \
+    (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)) || \
+    (defined(__cpp_constexpr) && __cpp_constexpr >= 200704)
+  #define FLATBUFFERS_CONSTEXPR constexpr
+#else
+  #define FLATBUFFERS_CONSTEXPR const
+#endif
+
+#if (defined(__cplusplus) && __cplusplus >= 201402L) || \
+    (defined(__cpp_constexpr) && __cpp_constexpr >= 201304)
+  #define FLATBUFFERS_CONSTEXPR_CPP14 FLATBUFFERS_CONSTEXPR
+#else
+  #define FLATBUFFERS_CONSTEXPR_CPP14
+#endif
+
+#if (defined(__GXX_EXPERIMENTAL_CXX0X__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)) || \
+    (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 190023026)) || \
+    defined(__clang__)
+  #define FLATBUFFERS_NOEXCEPT noexcept
+#else
+  #define FLATBUFFERS_NOEXCEPT
+#endif
+
+// NOTE: the FLATBUFFERS_DELETE_FUNC macro may change the access mode to
+// private, so be sure to put it at the end or reset access mode explicitly.
+#if (!defined(_MSC_VER) || _MSC_FULL_VER >= 180020827) && \
+    (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 404)) || \
+    defined(__clang__)
+  #define FLATBUFFERS_DELETE_FUNC(func) func = delete;
+#else
+  #define FLATBUFFERS_DELETE_FUNC(func) private: func;
+#endif
+
+#ifndef FLATBUFFERS_HAS_STRING_VIEW
+  // Only provide flatbuffers::string_view if __has_include can be used
+  // to detect a header that provides an implementation
+  #if defined(__has_include)
+    // Check for std::string_view (in c++17)
+    #if __has_include(<string_view>) && (__cplusplus >= 201606 || _HAS_CXX17)
+      #include <string_view>
+      namespace flatbuffers {
+        typedef std::string_view string_view;
+      }
+      #define FLATBUFFERS_HAS_STRING_VIEW 1
+    // Check for std::experimental::string_view (in c++14, compiler-dependent)
+    #elif __has_include(<experimental/string_view>) && (__cplusplus >= 201411)
+      #include <experimental/string_view>
+      namespace flatbuffers {
+        typedef std::experimental::string_view string_view;
+      }
+      #define FLATBUFFERS_HAS_STRING_VIEW 1
+    #endif
+  #endif // __has_include
+#endif // !FLATBUFFERS_HAS_STRING_VIEW
+
+#ifndef FLATBUFFERS_HAS_NEW_STRTOD
+  // Modern (C++11) strtod and strtof functions are available for use.
+  // 1) nan/inf strings as argument of strtod;
+  // 2) hex-float  as argument of  strtod/strtof.
+  #if (defined(_MSC_VER) && _MSC_VER >= 1900) || \
+      (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)) || \
+      (defined(__clang__))
+    #define FLATBUFFERS_HAS_NEW_STRTOD 1
+  #endif
+#endif // !FLATBUFFERS_HAS_NEW_STRTOD
+
+#ifndef FLATBUFFERS_LOCALE_INDEPENDENT
+  // Enable locale independent functions {strtof_l, strtod_l,strtoll_l, strtoull_l}.
+  // They are part of the POSIX-2008 but not part of the C/C++ standard.
+  // GCC/Clang have definition (_XOPEN_SOURCE>=700) if POSIX-2008.
+  #if ((defined(_MSC_VER) && _MSC_VER >= 1800)            || \
+       (defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE>=700)))
+    #define FLATBUFFERS_LOCALE_INDEPENDENT 1
+  #else
+    #define FLATBUFFERS_LOCALE_INDEPENDENT 0
+  #endif
+#endif  // !FLATBUFFERS_LOCALE_INDEPENDENT
+
+// Suppress Undefined Behavior Sanitizer (recoverable only). Usage:
+// - __supress_ubsan__("undefined")
+// - __supress_ubsan__("signed-integer-overflow")
+#if defined(__clang__)
+  #define __supress_ubsan__(type) __attribute__((no_sanitize(type)))
+#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)
+  #define __supress_ubsan__(type) __attribute__((no_sanitize_undefined))
+#else
+  #define __supress_ubsan__(type)
+#endif
+
+// This is constexpr function used for checking compile-time constants.
+// Avoid `#pragma warning(disable: 4127) // C4127: expression is constant`.
+template<typename T> FLATBUFFERS_CONSTEXPR inline bool IsConstTrue(T t) {
+  return !!t;
+}
+
+// Enable C++ attribute [[]] if std:c++17 or higher.
+#if ((__cplusplus >= 201703L) \
+    || (defined(_MSVC_LANG) &&  (_MSVC_LANG >= 201703L)))
+  // All attributes unknown to an implementation are ignored without causing an error.
+  #define FLATBUFFERS_ATTRIBUTE(attr) [[attr]]
+
+  #define FLATBUFFERS_FALLTHROUGH() [[fallthrough]]
+#else
+  #define FLATBUFFERS_ATTRIBUTE(attr)
+
+  #if FLATBUFFERS_CLANG >= 30800
+    #define FLATBUFFERS_FALLTHROUGH() [[clang::fallthrough]]
+  #elif FLATBUFFERS_GCC >= 70300
+    #define FLATBUFFERS_FALLTHROUGH() [[gnu::fallthrough]]
+  #else
+    #define FLATBUFFERS_FALLTHROUGH()
+  #endif
+#endif
+
+/// @endcond
+
+/// @file
+namespace flatbuffers {
+
+/// @cond FLATBUFFERS_INTERNAL
+// Our default offset / size type, 32bit on purpose on 64bit systems.
+// Also, using a consistent offset type maintains compatibility of serialized
+// offset values between 32bit and 64bit systems.
+typedef uint32_t uoffset_t;
+
+// Signed offsets for references that can go in both directions.
+typedef int32_t soffset_t;
+
+// Offset/index used in v-tables, can be changed to uint8_t in
+// format forks to save a bit of space if desired.
+typedef uint16_t voffset_t;
+
+typedef uintmax_t largest_scalar_t;
+
+// In 32bits, this evaluates to 2GB - 1
+#define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(soffset_t) * 8 - 1)) - 1)
+
+// We support aligning the contents of buffers up to this size.
+#define FLATBUFFERS_MAX_ALIGNMENT 16
+
+#if defined(_MSC_VER)
+  #pragma warning(push)
+  #pragma warning(disable: 4127) // C4127: conditional expression is constant
+#endif
+
+template<typename T> T EndianSwap(T t) {
+  #if defined(_MSC_VER)
+    #define FLATBUFFERS_BYTESWAP16 _byteswap_ushort
+    #define FLATBUFFERS_BYTESWAP32 _byteswap_ulong
+    #define FLATBUFFERS_BYTESWAP64 _byteswap_uint64
+  #elif defined(__ICCARM__)
+    #define FLATBUFFERS_BYTESWAP16 __REV16
+    #define FLATBUFFERS_BYTESWAP32 __REV
+    #define FLATBUFFERS_BYTESWAP64(x) \
+       ((__REV(static_cast<uint32_t>(x >> 32U))) | (static_cast<uint64_t>(__REV(static_cast<uint32_t>(x)))) << 32U)
+  #else
+    #if defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ < 408 && !defined(__clang__)
+      // __builtin_bswap16 was missing prior to GCC 4.8.
+      #define FLATBUFFERS_BYTESWAP16(x) \
+        static_cast<uint16_t>(__builtin_bswap32(static_cast<uint32_t>(x) << 16))
+    #else
+      #define FLATBUFFERS_BYTESWAP16 __builtin_bswap16
+    #endif
+    #define FLATBUFFERS_BYTESWAP32 __builtin_bswap32
+    #define FLATBUFFERS_BYTESWAP64 __builtin_bswap64
+  #endif
+  if (sizeof(T) == 1) {   // Compile-time if-then's.
+    return t;
+  } else if (sizeof(T) == 2) {
+    union { T t; uint16_t i; } u;
+    u.t = t;
+    u.i = FLATBUFFERS_BYTESWAP16(u.i);
+    return u.t;
+  } else if (sizeof(T) == 4) {
+    union { T t; uint32_t i; } u;
+    u.t = t;
+    u.i = FLATBUFFERS_BYTESWAP32(u.i);
+    return u.t;
+  } else if (sizeof(T) == 8) {
+    union { T t; uint64_t i; } u;
+    u.t = t;
+    u.i = FLATBUFFERS_BYTESWAP64(u.i);
+    return u.t;
+  } else {
+    FLATBUFFERS_ASSERT(0);
+  }
+}
+
+#if defined(_MSC_VER)
+  #pragma warning(pop)
+#endif
+
+
+template<typename T> T EndianScalar(T t) {
+  #if FLATBUFFERS_LITTLEENDIAN
+    return t;
+  #else
+    return EndianSwap(t);
+  #endif
+}
+
+template<typename T>
+// UBSAN: C++ aliasing type rules, see std::bit_cast<> for details.
+__supress_ubsan__("alignment")
+T ReadScalar(const void *p) {
+  return EndianScalar(*reinterpret_cast<const T *>(p));
+}
+
+template<typename T>
+// UBSAN: C++ aliasing type rules, see std::bit_cast<> for details.
+__supress_ubsan__("alignment")
+void WriteScalar(void *p, T t) {
+  *reinterpret_cast<T *>(p) = EndianScalar(t);
+}
+
+template<typename T> struct Offset;
+template<typename T> __supress_ubsan__("alignment") void WriteScalar(void *p, Offset<T> t) {
+  *reinterpret_cast<uoffset_t *>(p) = EndianScalar(t.o);
+}
+
+// Computes how many bytes you'd have to pad to be able to write an
+// "scalar_size" scalar if the buffer had grown to "buf_size" (downwards in
+// memory).
+inline size_t PaddingBytes(size_t buf_size, size_t scalar_size) {
+  return ((~buf_size) + 1) & (scalar_size - 1);
+}
+
+}  // namespace flatbuffers
+#endif  // FLATBUFFERS_BASE_H_
diff --git a/third_party/flatbuffers/include/flatbuffers/code_generators.h b/third_party/flatbuffers/include/flatbuffers/code_generators.h
new file mode 100644
index 0000000..0bcec91
--- /dev/null
+++ b/third_party/flatbuffers/include/flatbuffers/code_generators.h
@@ -0,0 +1,223 @@
+/*
+ * 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.
+ */
+
+#ifndef FLATBUFFERS_CODE_GENERATORS_H_
+#define FLATBUFFERS_CODE_GENERATORS_H_
+
+#include <map>
+#include <sstream>
+#include "flatbuffers/idl.h"
+
+namespace flatbuffers {
+
+// Utility class to assist in generating code through use of text templates.
+//
+// Example code:
+//   CodeWriter code("\t");
+//   code.SetValue("NAME", "Foo");
+//   code += "void {{NAME}}() { printf("%s", "{{NAME}}"); }";
+//   code.SetValue("NAME", "Bar");
+//   code += "void {{NAME}}() { printf("%s", "{{NAME}}"); }";
+//   std::cout << code.ToString() << std::endl;
+//
+// Output:
+//  void Foo() { printf("%s", "Foo"); }
+//  void Bar() { printf("%s", "Bar"); }
+class CodeWriter {
+ public:
+  CodeWriter(std::string pad = std::string())
+      : pad_(pad), cur_ident_lvl_(0), ignore_ident_(false) {}
+
+  // Clears the current "written" code.
+  void Clear() {
+    stream_.str("");
+    stream_.clear();
+  }
+
+  // Associates a key with a value.  All subsequent calls to operator+=, where
+  // the specified key is contained in {{ and }} delimiters will be replaced by
+  // the given value.
+  void SetValue(const std::string &key, const std::string &value) {
+    value_map_[key] = value;
+  }
+
+  std::string GetValue(const std::string &key) const {
+    const auto it = value_map_.find(key);
+    return it == value_map_.end() ? "" : it->second;
+  }
+
+  // Appends the given text to the generated code as well as a newline
+  // character.  Any text within {{ and }} delimeters is replaced by values
+  // previously stored in the CodeWriter by calling SetValue above.  The newline
+  // will be suppressed if the text ends with the \\ character.
+  void operator+=(std::string text);
+
+  // Returns the current contents of the CodeWriter as a std::string.
+  std::string ToString() const { return stream_.str(); }
+
+  // Increase ident level for writing code
+  void IncrementIdentLevel() { cur_ident_lvl_++; }
+  // Decrease ident level for writing code
+  void DecrementIdentLevel() {
+    if (cur_ident_lvl_) cur_ident_lvl_--;
+  }
+
+ private:
+  std::map<std::string, std::string> value_map_;
+  std::stringstream stream_;
+  std::string pad_;
+  int cur_ident_lvl_;
+  bool ignore_ident_;
+
+  // Add ident padding (tab or space) based on ident level
+  void AppendIdent(std::stringstream &stream);
+};
+
+class BaseGenerator {
+ public:
+  virtual bool generate() = 0;
+
+  static std::string NamespaceDir(const Parser &parser, const std::string &path,
+                                  const Namespace &ns);
+
+ protected:
+  BaseGenerator(const Parser &parser, const std::string &path,
+                const std::string &file_name,
+                std::string qualifying_start,
+                std::string qualifying_separator)
+      : parser_(parser),
+        path_(path),
+        file_name_(file_name),
+        qualifying_start_(qualifying_start),
+        qualifying_separator_(qualifying_separator) {}
+  virtual ~BaseGenerator() {}
+
+  // No copy/assign.
+  BaseGenerator &operator=(const BaseGenerator &);
+  BaseGenerator(const BaseGenerator &);
+
+  std::string NamespaceDir(const Namespace &ns) const;
+
+  static const char *FlatBuffersGeneratedWarning();
+
+  static std::string FullNamespace(const char *separator, const Namespace &ns);
+
+  static std::string LastNamespacePart(const Namespace &ns);
+
+  // tracks the current namespace for early exit in WrapInNameSpace
+  // c++, java and csharp returns a different namespace from
+  // the following default (no early exit, always fully qualify),
+  // which works for js and php
+  virtual const Namespace *CurrentNameSpace() const { return nullptr; }
+
+  // Ensure that a type is prefixed with its namespace even within
+  // its own namespace to avoid conflict between generated method
+  // names and similarly named classes or structs
+  std::string WrapInNameSpace(const Namespace *ns,
+                              const std::string &name) const;
+
+  std::string WrapInNameSpace(const Definition &def) const;
+
+  std::string GetNameSpace(const Definition &def) const;
+
+  const Parser &parser_;
+  const std::string &path_;
+  const std::string &file_name_;
+  const std::string qualifying_start_;
+  const std::string qualifying_separator_;
+};
+
+struct CommentConfig {
+  const char *first_line;
+  const char *content_line_prefix;
+  const char *last_line;
+};
+
+extern void GenComment(const std::vector<std::string> &dc,
+                       std::string *code_ptr, const CommentConfig *config,
+                       const char *prefix = "");
+
+class FloatConstantGenerator {
+ public:
+  virtual ~FloatConstantGenerator() {}
+  std::string GenFloatConstant(const FieldDef &field) const;
+
+ private:
+  virtual std::string Value(double v, const std::string &src) const = 0;
+  virtual std::string Inf(double v) const = 0;
+  virtual std::string NaN(double v) const = 0;
+
+  virtual std::string Value(float v, const std::string &src) const = 0;
+  virtual std::string Inf(float v) const = 0;
+  virtual std::string NaN(float v) const = 0;
+
+  template<typename T>
+  std::string GenFloatConstantImpl(const FieldDef &field) const;
+};
+
+class SimpleFloatConstantGenerator : public FloatConstantGenerator {
+ public:
+  SimpleFloatConstantGenerator(const char *nan_number,
+                               const char *pos_inf_number,
+                               const char *neg_inf_number);
+
+ private:
+  std::string Value(double v,
+                    const std::string &src) const FLATBUFFERS_OVERRIDE;
+  std::string Inf(double v) const FLATBUFFERS_OVERRIDE;
+  std::string NaN(double v) const FLATBUFFERS_OVERRIDE;
+
+  std::string Value(float v, const std::string &src) const FLATBUFFERS_OVERRIDE;
+  std::string Inf(float v) const FLATBUFFERS_OVERRIDE;
+  std::string NaN(float v) const FLATBUFFERS_OVERRIDE;
+
+  const std::string nan_number_;
+  const std::string pos_inf_number_;
+  const std::string neg_inf_number_;
+};
+
+// C++, C#, Java like generator.
+class TypedFloatConstantGenerator : public FloatConstantGenerator {
+ public:
+  TypedFloatConstantGenerator(const char *double_prefix,
+                              const char *single_prefix, const char *nan_number,
+                              const char *pos_inf_number,
+                              const char *neg_inf_number = "");
+
+ private:
+  std::string Value(double v,
+                    const std::string &src) const FLATBUFFERS_OVERRIDE;
+  std::string Inf(double v) const FLATBUFFERS_OVERRIDE;
+
+  std::string NaN(double v) const FLATBUFFERS_OVERRIDE;
+
+  std::string Value(float v, const std::string &src) const FLATBUFFERS_OVERRIDE;
+  std::string Inf(float v) const FLATBUFFERS_OVERRIDE;
+  std::string NaN(float v) const FLATBUFFERS_OVERRIDE;
+
+  std::string MakeNaN(const std::string &prefix) const;
+  std::string MakeInf(bool neg, const std::string &prefix) const;
+
+  const std::string double_prefix_;
+  const std::string single_prefix_;
+  const std::string nan_number_;
+  const std::string pos_inf_number_;
+  const std::string neg_inf_number_;
+};
+
+}  // namespace flatbuffers
+
+#endif  // FLATBUFFERS_CODE_GENERATORS_H_
diff --git a/third_party/flatbuffers/include/flatbuffers/flatbuffers.h b/third_party/flatbuffers/include/flatbuffers/flatbuffers.h
new file mode 100644
index 0000000..1a250cd
--- /dev/null
+++ b/third_party/flatbuffers/include/flatbuffers/flatbuffers.h
@@ -0,0 +1,2703 @@
+/*
+ * 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.
+ */
+
+#ifndef FLATBUFFERS_H_
+#define FLATBUFFERS_H_
+
+#include "flatbuffers/base.h"
+
+#if defined(FLATBUFFERS_NAN_DEFAULTS)
+#include <cmath>
+#endif
+
+namespace flatbuffers {
+// Generic 'operator==' with conditional specialisations.
+// T e - new value of a scalar field.
+// T def - default of scalar (is known at compile-time).
+template<typename T> inline bool IsTheSameAs(T e, T def) { return e == def; }
+
+#if defined(FLATBUFFERS_NAN_DEFAULTS) && \
+    defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
+// Like `operator==(e, def)` with weak NaN if T=(float|double).
+template<typename T> inline bool IsFloatTheSameAs(T e, T def) {
+  return (e == def) || ((def != def) && (e != e));
+}
+template<> inline bool IsTheSameAs<float>(float e, float def) {
+  return IsFloatTheSameAs(e, def);
+}
+template<> inline bool IsTheSameAs<double>(double e, double def) {
+  return IsFloatTheSameAs(e, def);
+}
+#endif
+
+// Wrapper for uoffset_t to allow safe template specialization.
+// Value is allowed to be 0 to indicate a null object (see e.g. AddOffset).
+template<typename T> struct Offset {
+  uoffset_t o;
+  Offset() : o(0) {}
+  Offset(uoffset_t _o) : o(_o) {}
+  Offset<void> Union() const { return Offset<void>(o); }
+  bool IsNull() const { return !o; }
+};
+
+inline void EndianCheck() {
+  int endiantest = 1;
+  // If this fails, see FLATBUFFERS_LITTLEENDIAN above.
+  FLATBUFFERS_ASSERT(*reinterpret_cast<char *>(&endiantest) ==
+                     FLATBUFFERS_LITTLEENDIAN);
+  (void)endiantest;
+}
+
+template<typename T> FLATBUFFERS_CONSTEXPR size_t AlignOf() {
+  // clang-format off
+  #ifdef _MSC_VER
+    return __alignof(T);
+  #else
+    #ifndef alignof
+      return __alignof__(T);
+    #else
+      return alignof(T);
+    #endif
+  #endif
+  // clang-format on
+}
+
+// When we read serialized data from memory, in the case of most scalars,
+// we want to just read T, but in the case of Offset, we want to actually
+// perform the indirection and return a pointer.
+// The template specialization below does just that.
+// It is wrapped in a struct since function templates can't overload on the
+// return type like this.
+// The typedef is for the convenience of callers of this function
+// (avoiding the need for a trailing return decltype)
+template<typename T> struct IndirectHelper {
+  typedef T return_type;
+  typedef T mutable_return_type;
+  static const size_t element_stride = sizeof(T);
+  static return_type Read(const uint8_t *p, uoffset_t i) {
+    return EndianScalar((reinterpret_cast<const T *>(p))[i]);
+  }
+};
+template<typename T> struct IndirectHelper<Offset<T>> {
+  typedef const T *return_type;
+  typedef T *mutable_return_type;
+  static const size_t element_stride = sizeof(uoffset_t);
+  static return_type Read(const uint8_t *p, uoffset_t i) {
+    p += i * sizeof(uoffset_t);
+    return reinterpret_cast<return_type>(p + ReadScalar<uoffset_t>(p));
+  }
+};
+template<typename T> struct IndirectHelper<const T *> {
+  typedef const T *return_type;
+  typedef T *mutable_return_type;
+  static const size_t element_stride = sizeof(T);
+  static return_type Read(const uint8_t *p, uoffset_t i) {
+    return reinterpret_cast<const T *>(p + i * sizeof(T));
+  }
+};
+
+// An STL compatible iterator implementation for Vector below, effectively
+// calling Get() for every element.
+template<typename T, typename IT> struct VectorIterator {
+  typedef std::random_access_iterator_tag iterator_category;
+  typedef IT value_type;
+  typedef ptrdiff_t difference_type;
+  typedef IT *pointer;
+  typedef IT &reference;
+
+  VectorIterator(const uint8_t *data, uoffset_t i)
+      : data_(data + IndirectHelper<T>::element_stride * i) {}
+  VectorIterator(const VectorIterator &other) : data_(other.data_) {}
+  VectorIterator() : data_(nullptr) {}
+
+  VectorIterator &operator=(const VectorIterator &other) {
+    data_ = other.data_;
+    return *this;
+  }
+
+  // clang-format off
+  #if !defined(FLATBUFFERS_CPP98_STL)
+  VectorIterator &operator=(VectorIterator &&other) {
+    data_ = other.data_;
+    return *this;
+  }
+  #endif  // !defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+
+  bool operator==(const VectorIterator &other) const {
+    return data_ == other.data_;
+  }
+
+  bool operator<(const VectorIterator &other) const {
+    return data_ < other.data_;
+  }
+
+  bool operator!=(const VectorIterator &other) const {
+    return data_ != other.data_;
+  }
+
+  difference_type operator-(const VectorIterator &other) const {
+    return (data_ - other.data_) / IndirectHelper<T>::element_stride;
+  }
+
+  IT operator*() const { return IndirectHelper<T>::Read(data_, 0); }
+
+  IT operator->() const { return IndirectHelper<T>::Read(data_, 0); }
+
+  VectorIterator &operator++() {
+    data_ += IndirectHelper<T>::element_stride;
+    return *this;
+  }
+
+  VectorIterator operator++(int) {
+    VectorIterator temp(data_, 0);
+    data_ += IndirectHelper<T>::element_stride;
+    return temp;
+  }
+
+  VectorIterator operator+(const uoffset_t &offset) const {
+    return VectorIterator(data_ + offset * IndirectHelper<T>::element_stride,
+                          0);
+  }
+
+  VectorIterator &operator+=(const uoffset_t &offset) {
+    data_ += offset * IndirectHelper<T>::element_stride;
+    return *this;
+  }
+
+  VectorIterator &operator--() {
+    data_ -= IndirectHelper<T>::element_stride;
+    return *this;
+  }
+
+  VectorIterator operator--(int) {
+    VectorIterator temp(data_, 0);
+    data_ -= IndirectHelper<T>::element_stride;
+    return temp;
+  }
+
+  VectorIterator operator-(const uoffset_t &offset) const {
+    return VectorIterator(data_ - offset * IndirectHelper<T>::element_stride,
+                          0);
+  }
+
+  VectorIterator &operator-=(const uoffset_t &offset) {
+    data_ -= offset * IndirectHelper<T>::element_stride;
+    return *this;
+  }
+
+ private:
+  const uint8_t *data_;
+};
+
+template<typename Iterator> struct VectorReverseIterator :
+  public std::reverse_iterator<Iterator> {
+
+  explicit VectorReverseIterator(Iterator iter) :
+    std::reverse_iterator<Iterator>(iter) {}
+
+  typename Iterator::value_type operator*() const {
+    return *(std::reverse_iterator<Iterator>::current);
+  }
+
+  typename Iterator::value_type operator->() const {
+    return *(std::reverse_iterator<Iterator>::current);
+  }
+};
+
+struct String;
+
+// This is used as a helper type for accessing vectors.
+// Vector::data() assumes the vector elements start after the length field.
+template<typename T> class Vector {
+ public:
+  typedef VectorIterator<T, typename IndirectHelper<T>::mutable_return_type>
+      iterator;
+  typedef VectorIterator<T, typename IndirectHelper<T>::return_type>
+      const_iterator;
+  typedef VectorReverseIterator<iterator> reverse_iterator;
+  typedef VectorReverseIterator<const_iterator> const_reverse_iterator;
+
+  uoffset_t size() const { return EndianScalar(length_); }
+
+  // Deprecated: use size(). Here for backwards compatibility.
+  FLATBUFFERS_ATTRIBUTE(deprecated("use size() instead"))
+  uoffset_t Length() const { return size(); }
+
+  typedef typename IndirectHelper<T>::return_type return_type;
+  typedef typename IndirectHelper<T>::mutable_return_type mutable_return_type;
+
+  return_type Get(uoffset_t i) const {
+    FLATBUFFERS_ASSERT(i < size());
+    return IndirectHelper<T>::Read(Data(), i);
+  }
+
+  return_type operator[](uoffset_t i) const { return Get(i); }
+
+  // If this is a Vector of enums, T will be its storage type, not the enum
+  // type. This function makes it convenient to retrieve value with enum
+  // type E.
+  template<typename E> E GetEnum(uoffset_t i) const {
+    return static_cast<E>(Get(i));
+  }
+
+  // If this a vector of unions, this does the cast for you. There's no check
+  // to make sure this is the right type!
+  template<typename U> const U *GetAs(uoffset_t i) const {
+    return reinterpret_cast<const U *>(Get(i));
+  }
+
+  // If this a vector of unions, this does the cast for you. There's no check
+  // to make sure this is actually a string!
+  const String *GetAsString(uoffset_t i) const {
+    return reinterpret_cast<const String *>(Get(i));
+  }
+
+  const void *GetStructFromOffset(size_t o) const {
+    return reinterpret_cast<const void *>(Data() + o);
+  }
+
+  iterator begin() { return iterator(Data(), 0); }
+  const_iterator begin() const { return const_iterator(Data(), 0); }
+
+  iterator end() { return iterator(Data(), size()); }
+  const_iterator end() const { return const_iterator(Data(), size()); }
+
+  reverse_iterator rbegin() { return reverse_iterator(end() - 1); }
+  const_reverse_iterator rbegin() const { return const_reverse_iterator(end() - 1); }
+
+  reverse_iterator rend() { return reverse_iterator(begin() - 1); }
+  const_reverse_iterator rend() const { return const_reverse_iterator(begin() - 1); }
+
+  const_iterator cbegin() const { return begin(); }
+
+  const_iterator cend() const { return end(); }
+
+  const_reverse_iterator crbegin() const { return rbegin(); }
+
+  const_reverse_iterator crend() const { return rend(); }
+
+  // Change elements if you have a non-const pointer to this object.
+  // Scalars only. See reflection.h, and the documentation.
+  void Mutate(uoffset_t i, const T &val) {
+    FLATBUFFERS_ASSERT(i < size());
+    WriteScalar(data() + i, val);
+  }
+
+  // Change an element of a vector of tables (or strings).
+  // "val" points to the new table/string, as you can obtain from
+  // e.g. reflection::AddFlatBuffer().
+  void MutateOffset(uoffset_t i, const uint8_t *val) {
+    FLATBUFFERS_ASSERT(i < size());
+    static_assert(sizeof(T) == sizeof(uoffset_t), "Unrelated types");
+    WriteScalar(data() + i,
+                static_cast<uoffset_t>(val - (Data() + i * sizeof(uoffset_t))));
+  }
+
+  // Get a mutable pointer to tables/strings inside this vector.
+  mutable_return_type GetMutableObject(uoffset_t i) const {
+    FLATBUFFERS_ASSERT(i < size());
+    return const_cast<mutable_return_type>(IndirectHelper<T>::Read(Data(), i));
+  }
+
+  // The raw data in little endian format. Use with care.
+  const uint8_t *Data() const {
+    return reinterpret_cast<const uint8_t *>(&length_ + 1);
+  }
+
+  uint8_t *Data() { return reinterpret_cast<uint8_t *>(&length_ + 1); }
+
+  // Similarly, but typed, much like std::vector::data
+  const T *data() const { return reinterpret_cast<const T *>(Data()); }
+  T *data() { return reinterpret_cast<T *>(Data()); }
+
+  template<typename K> return_type LookupByKey(K key) const {
+    void *search_result = std::bsearch(
+        &key, Data(), size(), IndirectHelper<T>::element_stride, KeyCompare<K>);
+
+    if (!search_result) {
+      return nullptr;  // Key not found.
+    }
+
+    const uint8_t *element = reinterpret_cast<const uint8_t *>(search_result);
+
+    return IndirectHelper<T>::Read(element, 0);
+  }
+
+ protected:
+  // This class is only used to access pre-existing data. Don't ever
+  // try to construct these manually.
+  Vector();
+
+  uoffset_t length_;
+
+ private:
+  // This class is a pointer. Copying will therefore create an invalid object.
+  // Private and unimplemented copy constructor.
+  Vector(const Vector &);
+
+  template<typename K> static int KeyCompare(const void *ap, const void *bp) {
+    const K *key = reinterpret_cast<const K *>(ap);
+    const uint8_t *data = reinterpret_cast<const uint8_t *>(bp);
+    auto table = IndirectHelper<T>::Read(data, 0);
+
+    // std::bsearch compares with the operands transposed, so we negate the
+    // result here.
+    return -table->KeyCompareWithValue(*key);
+  }
+};
+
+// Represent a vector much like the template above, but in this case we
+// don't know what the element types are (used with reflection.h).
+class VectorOfAny {
+ public:
+  uoffset_t size() const { return EndianScalar(length_); }
+
+  const uint8_t *Data() const {
+    return reinterpret_cast<const uint8_t *>(&length_ + 1);
+  }
+  uint8_t *Data() { return reinterpret_cast<uint8_t *>(&length_ + 1); }
+
+ protected:
+  VectorOfAny();
+
+  uoffset_t length_;
+
+ private:
+  VectorOfAny(const VectorOfAny &);
+};
+
+#ifndef FLATBUFFERS_CPP98_STL
+template<typename T, typename U>
+Vector<Offset<T>> *VectorCast(Vector<Offset<U>> *ptr) {
+  static_assert(std::is_base_of<T, U>::value, "Unrelated types");
+  return reinterpret_cast<Vector<Offset<T>> *>(ptr);
+}
+
+template<typename T, typename U>
+const Vector<Offset<T>> *VectorCast(const Vector<Offset<U>> *ptr) {
+  static_assert(std::is_base_of<T, U>::value, "Unrelated types");
+  return reinterpret_cast<const Vector<Offset<T>> *>(ptr);
+}
+#endif
+
+// Convenient helper function to get the length of any vector, regardless
+// of whether it is null or not (the field is not set).
+template<typename T> static inline size_t VectorLength(const Vector<T> *v) {
+  return v ? v->size() : 0;
+}
+
+// This is used as a helper type for accessing arrays.
+template<typename T, uint16_t length> class Array {
+ public:
+  typedef VectorIterator<T, typename IndirectHelper<T>::return_type>
+      const_iterator;
+  typedef VectorReverseIterator<const_iterator> const_reverse_iterator;
+
+  typedef typename IndirectHelper<T>::return_type return_type;
+
+  FLATBUFFERS_CONSTEXPR uint16_t size() const { return length; }
+
+  return_type Get(uoffset_t i) const {
+    FLATBUFFERS_ASSERT(i < size());
+    return IndirectHelper<T>::Read(Data(), i);
+  }
+
+  return_type operator[](uoffset_t i) const { return Get(i); }
+
+  const_iterator begin() const { return const_iterator(Data(), 0); }
+  const_iterator end() const { return const_iterator(Data(), size()); }
+
+  const_reverse_iterator rbegin() const {
+    return const_reverse_iterator(end());
+  }
+  const_reverse_iterator rend() const { return const_reverse_iterator(end()); }
+
+  const_iterator cbegin() const { return begin(); }
+  const_iterator cend() const { return end(); }
+
+  const_reverse_iterator crbegin() const { return rbegin(); }
+  const_reverse_iterator crend() const { return rend(); }
+
+  // Change elements if you have a non-const pointer to this object.
+  void Mutate(uoffset_t i, const T &val) {
+    FLATBUFFERS_ASSERT(i < size());
+    WriteScalar(data() + i, val);
+  }
+
+  // Get a mutable pointer to elements inside this array.
+  // @note This method should be only used to mutate arrays of structs followed
+  //  by a @p Mutate operation. For primitive types use @p Mutate directly.
+  // @warning Assignments and reads to/from the dereferenced pointer are not
+  //  automatically converted to the correct endianness.
+  T *GetMutablePointer(uoffset_t i) const {
+    FLATBUFFERS_ASSERT(i < size());
+    return const_cast<T *>(&data()[i]);
+  }
+
+  // The raw data in little endian format. Use with care.
+  const uint8_t *Data() const { return data_; }
+
+  uint8_t *Data() { return data_; }
+
+  // Similarly, but typed, much like std::vector::data
+  const T *data() const { return reinterpret_cast<const T *>(Data()); }
+  T *data() { return reinterpret_cast<T *>(Data()); }
+
+ protected:
+  // This class is only used to access pre-existing data. Don't ever
+  // try to construct these manually.
+  // 'constexpr' allows us to use 'size()' at compile time.
+  // @note Must not use 'FLATBUFFERS_CONSTEXPR' here, as const is not allowed on
+  //  a constructor.
+#if defined(__cpp_constexpr)
+  constexpr Array();
+#else
+  Array();
+#endif
+
+  uint8_t data_[length * sizeof(T)];
+
+ private:
+  // This class is a pointer. Copying will therefore create an invalid object.
+  // Private and unimplemented copy constructor.
+  Array(const Array &);
+};
+
+// Lexicographically compare two strings (possibly containing nulls), and
+// return true if the first is less than the second.
+static inline bool StringLessThan(const char *a_data, uoffset_t a_size,
+                                  const char *b_data, uoffset_t b_size) {
+  const auto cmp = memcmp(a_data, b_data, (std::min)(a_size, b_size));
+  return cmp == 0 ? a_size < b_size : cmp < 0;
+}
+
+struct String : public Vector<char> {
+  const char *c_str() const { return reinterpret_cast<const char *>(Data()); }
+  std::string str() const { return std::string(c_str(), size()); }
+
+  // clang-format off
+  #ifdef FLATBUFFERS_HAS_STRING_VIEW
+  flatbuffers::string_view string_view() const {
+    return flatbuffers::string_view(c_str(), size());
+  }
+  #endif // FLATBUFFERS_HAS_STRING_VIEW
+  // clang-format on
+
+  bool operator<(const String &o) const {
+    return StringLessThan(this->data(), this->size(), o.data(), o.size());
+  }
+};
+
+// Convenience function to get std::string from a String returning an empty
+// string on null pointer.
+static inline std::string GetString(const String * str) {
+  return str ? str->str() : "";
+}
+
+// Convenience function to get char* from a String returning an empty string on
+// null pointer.
+static inline const char * GetCstring(const String * str) {
+  return str ? str->c_str() : "";
+}
+
+// Allocator interface. This is flatbuffers-specific and meant only for
+// `vector_downward` usage.
+class Allocator {
+ public:
+  virtual ~Allocator() {}
+
+  // Allocate `size` bytes of memory.
+  virtual uint8_t *allocate(size_t size) = 0;
+
+  // Deallocate `size` bytes of memory at `p` allocated by this allocator.
+  virtual void deallocate(uint8_t *p, size_t size) = 0;
+
+  // Reallocate `new_size` bytes of memory, replacing the old region of size
+  // `old_size` at `p`. In contrast to a normal realloc, this grows downwards,
+  // and is intended specifcally for `vector_downward` use.
+  // `in_use_back` and `in_use_front` indicate how much of `old_size` is
+  // actually in use at each end, and needs to be copied.
+  virtual uint8_t *reallocate_downward(uint8_t *old_p, size_t old_size,
+                                       size_t new_size, size_t in_use_back,
+                                       size_t in_use_front) {
+    FLATBUFFERS_ASSERT(new_size > old_size);  // vector_downward only grows
+    uint8_t *new_p = allocate(new_size);
+    memcpy_downward(old_p, old_size, new_p, new_size, in_use_back,
+                    in_use_front);
+    deallocate(old_p, old_size);
+    return new_p;
+  }
+
+ protected:
+  // Called by `reallocate_downward` to copy memory from `old_p` of `old_size`
+  // to `new_p` of `new_size`. Only memory of size `in_use_front` and
+  // `in_use_back` will be copied from the front and back of the old memory
+  // allocation.
+  void memcpy_downward(uint8_t *old_p, size_t old_size,
+                       uint8_t *new_p, size_t new_size,
+                       size_t in_use_back, size_t in_use_front) {
+    memcpy(new_p + new_size - in_use_back, old_p + old_size - in_use_back,
+           in_use_back);
+    memcpy(new_p, old_p, in_use_front);
+  }
+};
+
+// DefaultAllocator uses new/delete to allocate memory regions
+class DefaultAllocator : public Allocator {
+ public:
+  uint8_t *allocate(size_t size) FLATBUFFERS_OVERRIDE {
+    return new uint8_t[size];
+  }
+
+  void deallocate(uint8_t *p, size_t) FLATBUFFERS_OVERRIDE {
+    delete[] p;
+  }
+
+  static void dealloc(void *p, size_t) {
+    delete[] static_cast<uint8_t *>(p);
+  }
+};
+
+// These functions allow for a null allocator to mean use the default allocator,
+// as used by DetachedBuffer and vector_downward below.
+// This is to avoid having a statically or dynamically allocated default
+// allocator, or having to move it between the classes that may own it.
+inline uint8_t *Allocate(Allocator *allocator, size_t size) {
+  return allocator ? allocator->allocate(size)
+                   : DefaultAllocator().allocate(size);
+}
+
+inline void Deallocate(Allocator *allocator, uint8_t *p, size_t size) {
+  if (allocator) allocator->deallocate(p, size);
+  else DefaultAllocator().deallocate(p, size);
+}
+
+inline uint8_t *ReallocateDownward(Allocator *allocator, uint8_t *old_p,
+                                   size_t old_size, size_t new_size,
+                                   size_t in_use_back, size_t in_use_front) {
+  return allocator
+      ? allocator->reallocate_downward(old_p, old_size, new_size,
+                                       in_use_back, in_use_front)
+      : DefaultAllocator().reallocate_downward(old_p, old_size, new_size,
+                                               in_use_back, in_use_front);
+}
+
+// DetachedBuffer is a finished flatbuffer memory region, detached from its
+// builder. The original memory region and allocator are also stored so that
+// the DetachedBuffer can manage the memory lifetime.
+class DetachedBuffer {
+ public:
+  DetachedBuffer()
+      : allocator_(nullptr),
+        own_allocator_(false),
+        buf_(nullptr),
+        reserved_(0),
+        cur_(nullptr),
+        size_(0) {}
+
+  DetachedBuffer(Allocator *allocator, bool own_allocator, uint8_t *buf,
+                 size_t reserved, uint8_t *cur, size_t sz)
+      : allocator_(allocator),
+        own_allocator_(own_allocator),
+        buf_(buf),
+        reserved_(reserved),
+        cur_(cur),
+        size_(sz) {}
+
+  // clang-format off
+  #if !defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+  DetachedBuffer(DetachedBuffer &&other)
+      : allocator_(other.allocator_),
+        own_allocator_(other.own_allocator_),
+        buf_(other.buf_),
+        reserved_(other.reserved_),
+        cur_(other.cur_),
+        size_(other.size_) {
+    other.reset();
+  }
+  // clang-format off
+  #endif  // !defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+
+  // clang-format off
+  #if !defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+  DetachedBuffer &operator=(DetachedBuffer &&other) {
+    destroy();
+
+    allocator_ = other.allocator_;
+    own_allocator_ = other.own_allocator_;
+    buf_ = other.buf_;
+    reserved_ = other.reserved_;
+    cur_ = other.cur_;
+    size_ = other.size_;
+
+    other.reset();
+
+    return *this;
+  }
+  // clang-format off
+  #endif  // !defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+
+  ~DetachedBuffer() { destroy(); }
+
+  const uint8_t *data() const { return cur_; }
+
+  uint8_t *data() { return cur_; }
+
+  size_t size() const { return size_; }
+
+  // clang-format off
+  #if 0  // disabled for now due to the ordering of classes in this header
+  template <class T>
+  bool Verify() const {
+    Verifier verifier(data(), size());
+    return verifier.Verify<T>(nullptr);
+  }
+
+  template <class T>
+  const T* GetRoot() const {
+    return flatbuffers::GetRoot<T>(data());
+  }
+
+  template <class T>
+  T* GetRoot() {
+    return flatbuffers::GetRoot<T>(data());
+  }
+  #endif
+  // clang-format on
+
+  // clang-format off
+  #if !defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+  // These may change access mode, leave these at end of public section
+  FLATBUFFERS_DELETE_FUNC(DetachedBuffer(const DetachedBuffer &other))
+  FLATBUFFERS_DELETE_FUNC(
+      DetachedBuffer &operator=(const DetachedBuffer &other))
+  // clang-format off
+  #endif  // !defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+
+protected:
+  Allocator *allocator_;
+  bool own_allocator_;
+  uint8_t *buf_;
+  size_t reserved_;
+  uint8_t *cur_;
+  size_t size_;
+
+  inline void destroy() {
+    if (buf_) Deallocate(allocator_, buf_, reserved_);
+    if (own_allocator_ && allocator_) { delete allocator_; }
+    reset();
+  }
+
+  inline void reset() {
+    allocator_ = nullptr;
+    own_allocator_ = false;
+    buf_ = nullptr;
+    reserved_ = 0;
+    cur_ = nullptr;
+    size_ = 0;
+  }
+};
+
+// This is a minimal replication of std::vector<uint8_t> functionality,
+// except growing from higher to lower addresses. i.e push_back() inserts data
+// in the lowest address in the vector.
+// Since this vector leaves the lower part unused, we support a "scratch-pad"
+// that can be stored there for temporary data, to share the allocated space.
+// Essentially, this supports 2 std::vectors in a single buffer.
+class vector_downward {
+ public:
+  explicit vector_downward(size_t initial_size,
+                           Allocator *allocator,
+                           bool own_allocator,
+                           size_t buffer_minalign)
+      : allocator_(allocator),
+        own_allocator_(own_allocator),
+        initial_size_(initial_size),
+        buffer_minalign_(buffer_minalign),
+        reserved_(0),
+        buf_(nullptr),
+        cur_(nullptr),
+        scratch_(nullptr) {}
+
+  // clang-format off
+  #if !defined(FLATBUFFERS_CPP98_STL)
+  vector_downward(vector_downward &&other)
+  #else
+  vector_downward(vector_downward &other)
+  #endif  // defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+    : allocator_(other.allocator_),
+      own_allocator_(other.own_allocator_),
+      initial_size_(other.initial_size_),
+      buffer_minalign_(other.buffer_minalign_),
+      reserved_(other.reserved_),
+      buf_(other.buf_),
+      cur_(other.cur_),
+      scratch_(other.scratch_) {
+    // No change in other.allocator_
+    // No change in other.initial_size_
+    // No change in other.buffer_minalign_
+    other.own_allocator_ = false;
+    other.reserved_ = 0;
+    other.buf_ = nullptr;
+    other.cur_ = nullptr;
+    other.scratch_ = nullptr;
+  }
+
+  // clang-format off
+  #if !defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+  vector_downward &operator=(vector_downward &&other) {
+    // Move construct a temporary and swap idiom
+    vector_downward temp(std::move(other));
+    swap(temp);
+    return *this;
+  }
+  // clang-format off
+  #endif  // defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+
+  ~vector_downward() {
+    clear_buffer();
+    clear_allocator();
+  }
+
+  void reset() {
+    clear_buffer();
+    clear();
+  }
+
+  void clear() {
+    if (buf_) {
+      cur_ = buf_ + reserved_;
+    } else {
+      reserved_ = 0;
+      cur_ = nullptr;
+    }
+    clear_scratch();
+  }
+
+  void clear_scratch() {
+    scratch_ = buf_;
+  }
+
+  void clear_allocator() {
+    if (own_allocator_ && allocator_) { delete allocator_; }
+    allocator_ = nullptr;
+    own_allocator_ = false;
+  }
+
+  void clear_buffer() {
+    if (buf_) Deallocate(allocator_, buf_, reserved_);
+    buf_ = nullptr;
+  }
+
+  // Relinquish the pointer to the caller.
+  uint8_t *release_raw(size_t &allocated_bytes, size_t &offset) {
+    auto *buf = buf_;
+    allocated_bytes = reserved_;
+    offset = static_cast<size_t>(cur_ - buf_);
+
+    // release_raw only relinquishes the buffer ownership.
+    // Does not deallocate or reset the allocator. Destructor will do that.
+    buf_ = nullptr;
+    clear();
+    return buf;
+  }
+
+  // Relinquish the pointer to the caller.
+  DetachedBuffer release() {
+    // allocator ownership (if any) is transferred to DetachedBuffer.
+    DetachedBuffer fb(allocator_, own_allocator_, buf_, reserved_, cur_,
+                      size());
+    if (own_allocator_) {
+      allocator_ = nullptr;
+      own_allocator_ = false;
+    }
+    buf_ = nullptr;
+    clear();
+    return fb;
+  }
+
+  size_t ensure_space(size_t len) {
+    FLATBUFFERS_ASSERT(cur_ >= scratch_ && scratch_ >= buf_);
+    if (len > static_cast<size_t>(cur_ - scratch_)) { reallocate(len); }
+    // Beyond this, signed offsets may not have enough range:
+    // (FlatBuffers > 2GB not supported).
+    FLATBUFFERS_ASSERT(size() < FLATBUFFERS_MAX_BUFFER_SIZE);
+    return len;
+  }
+
+  inline uint8_t *make_space(size_t len) {
+    size_t space = ensure_space(len);
+    cur_ -= space;
+    return cur_;
+  }
+
+  // Returns nullptr if using the DefaultAllocator.
+  Allocator *get_custom_allocator() { return allocator_; }
+
+  uoffset_t size() const {
+    return static_cast<uoffset_t>(reserved_ - (cur_ - buf_));
+  }
+
+  uoffset_t scratch_size() const {
+    return static_cast<uoffset_t>(scratch_ - buf_);
+  }
+
+  size_t capacity() const { return reserved_; }
+
+  uint8_t *data() const {
+    FLATBUFFERS_ASSERT(cur_);
+    return cur_;
+  }
+
+  uint8_t *scratch_data() const {
+    FLATBUFFERS_ASSERT(buf_);
+    return buf_;
+  }
+
+  uint8_t *scratch_end() const {
+    FLATBUFFERS_ASSERT(scratch_);
+    return scratch_;
+  }
+
+  uint8_t *data_at(size_t offset) const { return buf_ + reserved_ - offset; }
+
+  void push(const uint8_t *bytes, size_t num) {
+    if (num > 0) { memcpy(make_space(num), bytes, num); }
+  }
+
+  // Specialized version of push() that avoids memcpy call for small data.
+  template<typename T> void push_small(const T &little_endian_t) {
+    make_space(sizeof(T));
+    *reinterpret_cast<T *>(cur_) = little_endian_t;
+  }
+
+  template<typename T> void scratch_push_small(const T &t) {
+    ensure_space(sizeof(T));
+    *reinterpret_cast<T *>(scratch_) = t;
+    scratch_ += sizeof(T);
+  }
+
+  // fill() is most frequently called with small byte counts (<= 4),
+  // which is why we're using loops rather than calling memset.
+  void fill(size_t zero_pad_bytes) {
+    make_space(zero_pad_bytes);
+    for (size_t i = 0; i < zero_pad_bytes; i++) cur_[i] = 0;
+  }
+
+  // Version for when we know the size is larger.
+  // Precondition: zero_pad_bytes > 0
+  void fill_big(size_t zero_pad_bytes) {
+    memset(make_space(zero_pad_bytes), 0, zero_pad_bytes);
+  }
+
+  void pop(size_t bytes_to_remove) { cur_ += bytes_to_remove; }
+  void scratch_pop(size_t bytes_to_remove) { scratch_ -= bytes_to_remove; }
+
+  void swap(vector_downward &other) {
+    using std::swap;
+    swap(allocator_, other.allocator_);
+    swap(own_allocator_, other.own_allocator_);
+    swap(initial_size_, other.initial_size_);
+    swap(buffer_minalign_, other.buffer_minalign_);
+    swap(reserved_, other.reserved_);
+    swap(buf_, other.buf_);
+    swap(cur_, other.cur_);
+    swap(scratch_, other.scratch_);
+  }
+
+  void swap_allocator(vector_downward &other) {
+    using std::swap;
+    swap(allocator_, other.allocator_);
+    swap(own_allocator_, other.own_allocator_);
+  }
+
+ private:
+  // You shouldn't really be copying instances of this class.
+  FLATBUFFERS_DELETE_FUNC(vector_downward(const vector_downward &))
+  FLATBUFFERS_DELETE_FUNC(vector_downward &operator=(const vector_downward &))
+
+  Allocator *allocator_;
+  bool own_allocator_;
+  size_t initial_size_;
+  size_t buffer_minalign_;
+  size_t reserved_;
+  uint8_t *buf_;
+  uint8_t *cur_;  // Points at location between empty (below) and used (above).
+  uint8_t *scratch_;  // Points to the end of the scratchpad in use.
+
+  void reallocate(size_t len) {
+    auto old_reserved = reserved_;
+    auto old_size = size();
+    auto old_scratch_size = scratch_size();
+    reserved_ += (std::max)(len,
+                            old_reserved ? old_reserved / 2 : initial_size_);
+    reserved_ = (reserved_ + buffer_minalign_ - 1) & ~(buffer_minalign_ - 1);
+    if (buf_) {
+      buf_ = ReallocateDownward(allocator_, buf_, old_reserved, reserved_,
+                                old_size, old_scratch_size);
+    } else {
+      buf_ = Allocate(allocator_, reserved_);
+    }
+    cur_ = buf_ + reserved_ - old_size;
+    scratch_ = buf_ + old_scratch_size;
+  }
+};
+
+// Converts a Field ID to a virtual table offset.
+inline voffset_t FieldIndexToOffset(voffset_t field_id) {
+  // Should correspond to what EndTable() below builds up.
+  const int fixed_fields = 2;  // Vtable size and Object Size.
+  return static_cast<voffset_t>((field_id + fixed_fields) * sizeof(voffset_t));
+}
+
+template<typename T, typename Alloc>
+const T *data(const std::vector<T, Alloc> &v) {
+  // Eventually the returned pointer gets passed down to memcpy, so
+  // we need it to be non-null to avoid undefined behavior.
+  static uint8_t t;
+  return v.empty() ? reinterpret_cast<const T*>(&t) : &v.front();
+}
+template<typename T, typename Alloc> T *data(std::vector<T, Alloc> &v) {
+  // Eventually the returned pointer gets passed down to memcpy, so
+  // we need it to be non-null to avoid undefined behavior.
+  static uint8_t t;
+  return v.empty() ? reinterpret_cast<T*>(&t) : &v.front();
+}
+
+/// @endcond
+
+/// @addtogroup flatbuffers_cpp_api
+/// @{
+/// @class FlatBufferBuilder
+/// @brief Helper class to hold data needed in creation of a FlatBuffer.
+/// To serialize data, you typically call one of the `Create*()` functions in
+/// the generated code, which in turn call a sequence of `StartTable`/
+/// `PushElement`/`AddElement`/`EndTable`, or the builtin `CreateString`/
+/// `CreateVector` functions. Do this is depth-first order to build up a tree to
+/// the root. `Finish()` wraps up the buffer ready for transport.
+class FlatBufferBuilder {
+ public:
+  /// @brief Default constructor for FlatBufferBuilder.
+  /// @param[in] initial_size The initial size of the buffer, in bytes. Defaults
+  /// to `1024`.
+  /// @param[in] allocator An `Allocator` to use. If null will use
+  /// `DefaultAllocator`.
+  /// @param[in] own_allocator Whether the builder/vector should own the
+  /// allocator. Defaults to / `false`.
+  /// @param[in] buffer_minalign Force the buffer to be aligned to the given
+  /// minimum alignment upon reallocation. Only needed if you intend to store
+  /// types with custom alignment AND you wish to read the buffer in-place
+  /// directly after creation.
+  explicit FlatBufferBuilder(size_t initial_size = 1024,
+                             Allocator *allocator = nullptr,
+                             bool own_allocator = false,
+                             size_t buffer_minalign =
+                                 AlignOf<largest_scalar_t>())
+      : buf_(initial_size, allocator, own_allocator, buffer_minalign),
+        num_field_loc(0),
+        max_voffset_(0),
+        nested(false),
+        finished(false),
+        minalign_(1),
+        force_defaults_(false),
+        dedup_vtables_(true),
+        string_pool(nullptr) {
+    EndianCheck();
+  }
+
+  // clang-format off
+  /// @brief Move constructor for FlatBufferBuilder.
+  #if !defined(FLATBUFFERS_CPP98_STL)
+  FlatBufferBuilder(FlatBufferBuilder &&other)
+  #else
+  FlatBufferBuilder(FlatBufferBuilder &other)
+  #endif  // #if !defined(FLATBUFFERS_CPP98_STL)
+    : buf_(1024, nullptr, false, AlignOf<largest_scalar_t>()),
+      num_field_loc(0),
+      max_voffset_(0),
+      nested(false),
+      finished(false),
+      minalign_(1),
+      force_defaults_(false),
+      dedup_vtables_(true),
+      string_pool(nullptr) {
+    EndianCheck();
+    // Default construct and swap idiom.
+    // Lack of delegating constructors in vs2010 makes it more verbose than needed.
+    Swap(other);
+  }
+  // clang-format on
+
+  // clang-format off
+  #if !defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+  /// @brief Move assignment operator for FlatBufferBuilder.
+  FlatBufferBuilder &operator=(FlatBufferBuilder &&other) {
+    // Move construct a temporary and swap idiom
+    FlatBufferBuilder temp(std::move(other));
+    Swap(temp);
+    return *this;
+  }
+  // clang-format off
+  #endif  // defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+
+  void Swap(FlatBufferBuilder &other) {
+    using std::swap;
+    buf_.swap(other.buf_);
+    swap(num_field_loc, other.num_field_loc);
+    swap(max_voffset_, other.max_voffset_);
+    swap(nested, other.nested);
+    swap(finished, other.finished);
+    swap(minalign_, other.minalign_);
+    swap(force_defaults_, other.force_defaults_);
+    swap(dedup_vtables_, other.dedup_vtables_);
+    swap(string_pool, other.string_pool);
+  }
+
+  ~FlatBufferBuilder() {
+    if (string_pool) delete string_pool;
+  }
+
+  void Reset() {
+    Clear();       // clear builder state
+    buf_.reset();  // deallocate buffer
+  }
+
+  /// @brief Reset all the state in this FlatBufferBuilder so it can be reused
+  /// to construct another buffer.
+  void Clear() {
+    ClearOffsets();
+    buf_.clear();
+    nested = false;
+    finished = false;
+    minalign_ = 1;
+    if (string_pool) string_pool->clear();
+  }
+
+  /// @brief The current size of the serialized buffer, counting from the end.
+  /// @return Returns an `uoffset_t` with the current size of the buffer.
+  uoffset_t GetSize() const { return buf_.size(); }
+
+  /// @brief Get the serialized buffer (after you call `Finish()`).
+  /// @return Returns an `uint8_t` pointer to the FlatBuffer data inside the
+  /// buffer.
+  uint8_t *GetBufferPointer() const {
+    Finished();
+    return buf_.data();
+  }
+
+  /// @brief Get a pointer to an unfinished buffer.
+  /// @return Returns a `uint8_t` pointer to the unfinished buffer.
+  uint8_t *GetCurrentBufferPointer() const { return buf_.data(); }
+
+  /// @brief Get the released pointer to the serialized buffer.
+  /// @warning Do NOT attempt to use this FlatBufferBuilder afterwards!
+  /// @return A `FlatBuffer` that owns the buffer and its allocator and
+  /// behaves similar to a `unique_ptr` with a deleter.
+  FLATBUFFERS_ATTRIBUTE(deprecated("use Release() instead")) DetachedBuffer
+  ReleaseBufferPointer() {
+    Finished();
+    return buf_.release();
+  }
+
+  /// @brief Get the released DetachedBuffer.
+  /// @return A `DetachedBuffer` that owns the buffer and its allocator.
+  DetachedBuffer Release() {
+    Finished();
+    return buf_.release();
+  }
+
+  /// @brief Get the released pointer to the serialized buffer.
+  /// @param The size of the memory block containing
+  /// the serialized `FlatBuffer`.
+  /// @param The offset from the released pointer where the finished
+  /// `FlatBuffer` starts.
+  /// @return A raw pointer to the start of the memory block containing
+  /// the serialized `FlatBuffer`.
+  /// @remark If the allocator is owned, it gets deleted when the destructor is called..
+  uint8_t *ReleaseRaw(size_t &size, size_t &offset) {
+    Finished();
+    return buf_.release_raw(size, offset);
+  }
+
+  /// @brief get the minimum alignment this buffer needs to be accessed
+  /// properly. This is only known once all elements have been written (after
+  /// you call Finish()). You can use this information if you need to embed
+  /// a FlatBuffer in some other buffer, such that you can later read it
+  /// without first having to copy it into its own buffer.
+  size_t GetBufferMinAlignment() {
+    Finished();
+    return minalign_;
+  }
+
+  /// @cond FLATBUFFERS_INTERNAL
+  void Finished() const {
+    // If you get this assert, you're attempting to get access a buffer
+    // which hasn't been finished yet. Be sure to call
+    // FlatBufferBuilder::Finish with your root table.
+    // If you really need to access an unfinished buffer, call
+    // GetCurrentBufferPointer instead.
+    FLATBUFFERS_ASSERT(finished);
+  }
+  /// @endcond
+
+  /// @brief In order to save space, fields that are set to their default value
+  /// don't get serialized into the buffer.
+  /// @param[in] bool fd When set to `true`, always serializes default values that are set.
+  /// Optional fields which are not set explicitly, will still not be serialized.
+  void ForceDefaults(bool fd) { force_defaults_ = fd; }
+
+  /// @brief By default vtables are deduped in order to save space.
+  /// @param[in] bool dedup When set to `true`, dedup vtables.
+  void DedupVtables(bool dedup) { dedup_vtables_ = dedup; }
+
+  /// @cond FLATBUFFERS_INTERNAL
+  void Pad(size_t num_bytes) { buf_.fill(num_bytes); }
+
+  void TrackMinAlign(size_t elem_size) {
+    if (elem_size > minalign_) minalign_ = elem_size;
+  }
+
+  void Align(size_t elem_size) {
+    TrackMinAlign(elem_size);
+    buf_.fill(PaddingBytes(buf_.size(), elem_size));
+  }
+
+  void PushFlatBuffer(const uint8_t *bytes, size_t size) {
+    PushBytes(bytes, size);
+    finished = true;
+  }
+
+  void PushBytes(const uint8_t *bytes, size_t size) { buf_.push(bytes, size); }
+
+  void PopBytes(size_t amount) { buf_.pop(amount); }
+
+  template<typename T> void AssertScalarT() {
+    // The code assumes power of 2 sizes and endian-swap-ability.
+    static_assert(flatbuffers::is_scalar<T>::value, "T must be a scalar type");
+  }
+
+  // Write a single aligned scalar to the buffer
+  template<typename T> uoffset_t PushElement(T element) {
+    AssertScalarT<T>();
+    T litle_endian_element = EndianScalar(element);
+    Align(sizeof(T));
+    buf_.push_small(litle_endian_element);
+    return GetSize();
+  }
+
+  template<typename T> uoffset_t PushElement(Offset<T> off) {
+    // Special case for offsets: see ReferTo below.
+    return PushElement(ReferTo(off.o));
+  }
+
+  // When writing fields, we track where they are, so we can create correct
+  // vtables later.
+  void TrackField(voffset_t field, uoffset_t off) {
+    FieldLoc fl = { off, field };
+    buf_.scratch_push_small(fl);
+    num_field_loc++;
+    max_voffset_ = (std::max)(max_voffset_, field);
+  }
+
+  // Like PushElement, but additionally tracks the field this represents.
+  template<typename T> void AddElement(voffset_t field, T e, T def) {
+    // We don't serialize values equal to the default.
+    if (IsTheSameAs(e, def) && !force_defaults_) return;
+    auto off = PushElement(e);
+    TrackField(field, off);
+  }
+
+  template<typename T> void AddOffset(voffset_t field, Offset<T> off) {
+    if (off.IsNull()) return;  // Don't store.
+    AddElement(field, ReferTo(off.o), static_cast<uoffset_t>(0));
+  }
+
+  template<typename T> void AddStruct(voffset_t field, const T *structptr) {
+    if (!structptr) return;  // Default, don't store.
+    Align(AlignOf<T>());
+    buf_.push_small(*structptr);
+    TrackField(field, GetSize());
+  }
+
+  void AddStructOffset(voffset_t field, uoffset_t off) {
+    TrackField(field, off);
+  }
+
+  // Offsets initially are relative to the end of the buffer (downwards).
+  // This function converts them to be relative to the current location
+  // in the buffer (when stored here), pointing upwards.
+  uoffset_t ReferTo(uoffset_t off) {
+    // Align to ensure GetSize() below is correct.
+    Align(sizeof(uoffset_t));
+    // Offset must refer to something already in buffer.
+    FLATBUFFERS_ASSERT(off && off <= GetSize());
+    return GetSize() - off + static_cast<uoffset_t>(sizeof(uoffset_t));
+  }
+
+  void NotNested() {
+    // If you hit this, you're trying to construct a Table/Vector/String
+    // during the construction of its parent table (between the MyTableBuilder
+    // and table.Finish().
+    // Move the creation of these sub-objects to above the MyTableBuilder to
+    // not get this assert.
+    // Ignoring this assert may appear to work in simple cases, but the reason
+    // it is here is that storing objects in-line may cause vtable offsets
+    // to not fit anymore. It also leads to vtable duplication.
+    FLATBUFFERS_ASSERT(!nested);
+    // If you hit this, fields were added outside the scope of a table.
+    FLATBUFFERS_ASSERT(!num_field_loc);
+  }
+
+  // From generated code (or from the parser), we call StartTable/EndTable
+  // with a sequence of AddElement calls in between.
+  uoffset_t StartTable() {
+    NotNested();
+    nested = true;
+    return GetSize();
+  }
+
+  // This finishes one serialized object by generating the vtable if it's a
+  // table, comparing it against existing vtables, and writing the
+  // resulting vtable offset.
+  uoffset_t EndTable(uoffset_t start) {
+    // If you get this assert, a corresponding StartTable wasn't called.
+    FLATBUFFERS_ASSERT(nested);
+    // Write the vtable offset, which is the start of any Table.
+    // We fill it's value later.
+    auto vtableoffsetloc = PushElement<soffset_t>(0);
+    // Write a vtable, which consists entirely of voffset_t elements.
+    // It starts with the number of offsets, followed by a type id, followed
+    // by the offsets themselves. In reverse:
+    // Include space for the last offset and ensure empty tables have a
+    // minimum size.
+    max_voffset_ =
+        (std::max)(static_cast<voffset_t>(max_voffset_ + sizeof(voffset_t)),
+                   FieldIndexToOffset(0));
+    buf_.fill_big(max_voffset_);
+    auto table_object_size = vtableoffsetloc - start;
+    // Vtable use 16bit offsets.
+    FLATBUFFERS_ASSERT(table_object_size < 0x10000);
+    WriteScalar<voffset_t>(buf_.data() + sizeof(voffset_t),
+                           static_cast<voffset_t>(table_object_size));
+    WriteScalar<voffset_t>(buf_.data(), max_voffset_);
+    // Write the offsets into the table
+    for (auto it = buf_.scratch_end() - num_field_loc * sizeof(FieldLoc);
+         it < buf_.scratch_end(); it += sizeof(FieldLoc)) {
+      auto field_location = reinterpret_cast<FieldLoc *>(it);
+      auto pos = static_cast<voffset_t>(vtableoffsetloc - field_location->off);
+      // If this asserts, it means you've set a field twice.
+      FLATBUFFERS_ASSERT(
+          !ReadScalar<voffset_t>(buf_.data() + field_location->id));
+      WriteScalar<voffset_t>(buf_.data() + field_location->id, pos);
+    }
+    ClearOffsets();
+    auto vt1 = reinterpret_cast<voffset_t *>(buf_.data());
+    auto vt1_size = ReadScalar<voffset_t>(vt1);
+    auto vt_use = GetSize();
+    // See if we already have generated a vtable with this exact same
+    // layout before. If so, make it point to the old one, remove this one.
+    if (dedup_vtables_) {
+      for (auto it = buf_.scratch_data(); it < buf_.scratch_end();
+           it += sizeof(uoffset_t)) {
+        auto vt_offset_ptr = reinterpret_cast<uoffset_t *>(it);
+        auto vt2 = reinterpret_cast<voffset_t *>(buf_.data_at(*vt_offset_ptr));
+        auto vt2_size = *vt2;
+        if (vt1_size != vt2_size || 0 != memcmp(vt2, vt1, vt1_size)) continue;
+        vt_use = *vt_offset_ptr;
+        buf_.pop(GetSize() - vtableoffsetloc);
+        break;
+      }
+    }
+    // If this is a new vtable, remember it.
+    if (vt_use == GetSize()) { buf_.scratch_push_small(vt_use); }
+    // Fill the vtable offset we created above.
+    // The offset points from the beginning of the object to where the
+    // vtable is stored.
+    // Offsets default direction is downward in memory for future format
+    // flexibility (storing all vtables at the start of the file).
+    WriteScalar(buf_.data_at(vtableoffsetloc),
+                static_cast<soffset_t>(vt_use) -
+                    static_cast<soffset_t>(vtableoffsetloc));
+
+    nested = false;
+    return vtableoffsetloc;
+  }
+
+  FLATBUFFERS_ATTRIBUTE(deprecated("call the version above instead"))
+  uoffset_t EndTable(uoffset_t start, voffset_t /*numfields*/) {
+    return EndTable(start);
+  }
+
+  // This checks a required field has been set in a given table that has
+  // just been constructed.
+  template<typename T> void Required(Offset<T> table, voffset_t field);
+
+  uoffset_t StartStruct(size_t alignment) {
+    Align(alignment);
+    return GetSize();
+  }
+
+  uoffset_t EndStruct() { return GetSize(); }
+
+  void ClearOffsets() {
+    buf_.scratch_pop(num_field_loc * sizeof(FieldLoc));
+    num_field_loc = 0;
+    max_voffset_ = 0;
+  }
+
+  // Aligns such that when "len" bytes are written, an object can be written
+  // after it with "alignment" without padding.
+  void PreAlign(size_t len, size_t alignment) {
+    TrackMinAlign(alignment);
+    buf_.fill(PaddingBytes(GetSize() + len, alignment));
+  }
+  template<typename T> void PreAlign(size_t len) {
+    AssertScalarT<T>();
+    PreAlign(len, sizeof(T));
+  }
+  /// @endcond
+
+  /// @brief Store a string in the buffer, which can contain any binary data.
+  /// @param[in] str A const char pointer to the data to be stored as a string.
+  /// @param[in] len The number of bytes that should be stored from `str`.
+  /// @return Returns the offset in the buffer where the string starts.
+  Offset<String> CreateString(const char *str, size_t len) {
+    NotNested();
+    PreAlign<uoffset_t>(len + 1);  // Always 0-terminated.
+    buf_.fill(1);
+    PushBytes(reinterpret_cast<const uint8_t *>(str), len);
+    PushElement(static_cast<uoffset_t>(len));
+    return Offset<String>(GetSize());
+  }
+
+  /// @brief Store a string in the buffer, which is null-terminated.
+  /// @param[in] str A const char pointer to a C-string to add to the buffer.
+  /// @return Returns the offset in the buffer where the string starts.
+  Offset<String> CreateString(const char *str) {
+    return CreateString(str, strlen(str));
+  }
+
+  /// @brief Store a string in the buffer, which is null-terminated.
+  /// @param[in] str A char pointer to a C-string to add to the buffer.
+  /// @return Returns the offset in the buffer where the string starts.
+  Offset<String> CreateString(char *str) {
+    return CreateString(str, strlen(str));
+  }
+
+  /// @brief Store a string in the buffer, which can contain any binary data.
+  /// @param[in] str A const reference to a std::string to store in the buffer.
+  /// @return Returns the offset in the buffer where the string starts.
+  Offset<String> CreateString(const std::string &str) {
+    return CreateString(str.c_str(), str.length());
+  }
+
+  // clang-format off
+  #ifdef FLATBUFFERS_HAS_STRING_VIEW
+  /// @brief Store a string in the buffer, which can contain any binary data.
+  /// @param[in] str A const string_view to copy in to the buffer.
+  /// @return Returns the offset in the buffer where the string starts.
+  Offset<String> CreateString(flatbuffers::string_view str) {
+    return CreateString(str.data(), str.size());
+  }
+  #endif // FLATBUFFERS_HAS_STRING_VIEW
+  // clang-format on
+
+  /// @brief Store a string in the buffer, which can contain any binary data.
+  /// @param[in] str A const pointer to a `String` struct to add to the buffer.
+  /// @return Returns the offset in the buffer where the string starts
+  Offset<String> CreateString(const String *str) {
+    return str ? CreateString(str->c_str(), str->size()) : 0;
+  }
+
+  /// @brief Store a string in the buffer, which can contain any binary data.
+  /// @param[in] str A const reference to a std::string like type with support
+  /// of T::c_str() and T::length() to store in the buffer.
+  /// @return Returns the offset in the buffer where the string starts.
+  template<typename T> Offset<String> CreateString(const T &str) {
+    return CreateString(str.c_str(), str.length());
+  }
+
+  /// @brief Store a string in the buffer, which can contain any binary data.
+  /// If a string with this exact contents has already been serialized before,
+  /// instead simply returns the offset of the existing string.
+  /// @param[in] str A const char pointer to the data to be stored as a string.
+  /// @param[in] len The number of bytes that should be stored from `str`.
+  /// @return Returns the offset in the buffer where the string starts.
+  Offset<String> CreateSharedString(const char *str, size_t len) {
+    if (!string_pool)
+      string_pool = new StringOffsetMap(StringOffsetCompare(buf_));
+    auto size_before_string = buf_.size();
+    // Must first serialize the string, since the set is all offsets into
+    // buffer.
+    auto off = CreateString(str, len);
+    auto it = string_pool->find(off);
+    // If it exists we reuse existing serialized data!
+    if (it != string_pool->end()) {
+      // We can remove the string we serialized.
+      buf_.pop(buf_.size() - size_before_string);
+      return *it;
+    }
+    // Record this string for future use.
+    string_pool->insert(off);
+    return off;
+  }
+
+  /// @brief Store a string in the buffer, which null-terminated.
+  /// If a string with this exact contents has already been serialized before,
+  /// instead simply returns the offset of the existing string.
+  /// @param[in] str A const char pointer to a C-string to add to the buffer.
+  /// @return Returns the offset in the buffer where the string starts.
+  Offset<String> CreateSharedString(const char *str) {
+    return CreateSharedString(str, strlen(str));
+  }
+
+  /// @brief Store a string in the buffer, which can contain any binary data.
+  /// If a string with this exact contents has already been serialized before,
+  /// instead simply returns the offset of the existing string.
+  /// @param[in] str A const reference to a std::string to store in the buffer.
+  /// @return Returns the offset in the buffer where the string starts.
+  Offset<String> CreateSharedString(const std::string &str) {
+    return CreateSharedString(str.c_str(), str.length());
+  }
+
+  /// @brief Store a string in the buffer, which can contain any binary data.
+  /// If a string with this exact contents has already been serialized before,
+  /// instead simply returns the offset of the existing string.
+  /// @param[in] str A const pointer to a `String` struct to add to the buffer.
+  /// @return Returns the offset in the buffer where the string starts
+  Offset<String> CreateSharedString(const String *str) {
+    return CreateSharedString(str->c_str(), str->size());
+  }
+
+  /// @cond FLATBUFFERS_INTERNAL
+  uoffset_t EndVector(size_t len) {
+    FLATBUFFERS_ASSERT(nested);  // Hit if no corresponding StartVector.
+    nested = false;
+    return PushElement(static_cast<uoffset_t>(len));
+  }
+
+  void StartVector(size_t len, size_t elemsize) {
+    NotNested();
+    nested = true;
+    PreAlign<uoffset_t>(len * elemsize);
+    PreAlign(len * elemsize, elemsize);  // Just in case elemsize > uoffset_t.
+  }
+
+  // Call this right before StartVector/CreateVector if you want to force the
+  // alignment to be something different than what the element size would
+  // normally dictate.
+  // This is useful when storing a nested_flatbuffer in a vector of bytes,
+  // or when storing SIMD floats, etc.
+  void ForceVectorAlignment(size_t len, size_t elemsize, size_t alignment) {
+    PreAlign(len * elemsize, alignment);
+  }
+
+  // Similar to ForceVectorAlignment but for String fields.
+  void ForceStringAlignment(size_t len, size_t alignment) {
+    PreAlign((len + 1) * sizeof(char), alignment);
+  }
+
+  /// @endcond
+
+  /// @brief Serialize an array into a FlatBuffer `vector`.
+  /// @tparam T The data type of the array elements.
+  /// @param[in] v A pointer to the array of type `T` to serialize into the
+  /// buffer as a `vector`.
+  /// @param[in] len The number of elements to serialize.
+  /// @return Returns a typed `Offset` into the serialized data indicating
+  /// where the vector is stored.
+  template<typename T> Offset<Vector<T>> CreateVector(const T *v, size_t len) {
+    // If this assert hits, you're specifying a template argument that is
+    // causing the wrong overload to be selected, remove it.
+    AssertScalarT<T>();
+    StartVector(len, sizeof(T));
+    // clang-format off
+    #if FLATBUFFERS_LITTLEENDIAN
+      PushBytes(reinterpret_cast<const uint8_t *>(v), len * sizeof(T));
+    #else
+      if (sizeof(T) == 1) {
+        PushBytes(reinterpret_cast<const uint8_t *>(v), len);
+      } else {
+        for (auto i = len; i > 0; ) {
+          PushElement(v[--i]);
+        }
+      }
+    #endif
+    // clang-format on
+    return Offset<Vector<T>>(EndVector(len));
+  }
+
+  template<typename T>
+  Offset<Vector<Offset<T>>> CreateVector(const Offset<T> *v, size_t len) {
+    StartVector(len, sizeof(Offset<T>));
+    for (auto i = len; i > 0;) { PushElement(v[--i]); }
+    return Offset<Vector<Offset<T>>>(EndVector(len));
+  }
+
+  /// @brief Serialize a `std::vector` into a FlatBuffer `vector`.
+  /// @tparam T The data type of the `std::vector` elements.
+  /// @param v A const reference to the `std::vector` to serialize into the
+  /// buffer as a `vector`.
+  /// @return Returns a typed `Offset` into the serialized data indicating
+  /// where the vector is stored.
+  template<typename T> Offset<Vector<T>> CreateVector(const std::vector<T> &v) {
+    return CreateVector(data(v), v.size());
+  }
+
+  // vector<bool> may be implemented using a bit-set, so we can't access it as
+  // an array. Instead, read elements manually.
+  // Background: https://isocpp.org/blog/2012/11/on-vectorbool
+  Offset<Vector<uint8_t>> CreateVector(const std::vector<bool> &v) {
+    StartVector(v.size(), sizeof(uint8_t));
+    for (auto i = v.size(); i > 0;) {
+      PushElement(static_cast<uint8_t>(v[--i]));
+    }
+    return Offset<Vector<uint8_t>>(EndVector(v.size()));
+  }
+
+  // clang-format off
+  #ifndef FLATBUFFERS_CPP98_STL
+  /// @brief Serialize values returned by a function into a FlatBuffer `vector`.
+  /// This is a convenience function that takes care of iteration for you.
+  /// @tparam T The data type of the `std::vector` elements.
+  /// @param f A function that takes the current iteration 0..vector_size-1 and
+  /// returns any type that you can construct a FlatBuffers vector out of.
+  /// @return Returns a typed `Offset` into the serialized data indicating
+  /// where the vector is stored.
+  template<typename T> Offset<Vector<T>> CreateVector(size_t vector_size,
+      const std::function<T (size_t i)> &f) {
+    std::vector<T> elems(vector_size);
+    for (size_t i = 0; i < vector_size; i++) elems[i] = f(i);
+    return CreateVector(elems);
+  }
+  #endif
+  // clang-format on
+
+  /// @brief Serialize values returned by a function into a FlatBuffer `vector`.
+  /// This is a convenience function that takes care of iteration for you.
+  /// @tparam T The data type of the `std::vector` elements.
+  /// @param f A function that takes the current iteration 0..vector_size-1,
+  /// and the state parameter returning any type that you can construct a
+  /// FlatBuffers vector out of.
+  /// @param state State passed to f.
+  /// @return Returns a typed `Offset` into the serialized data indicating
+  /// where the vector is stored.
+  template<typename T, typename F, typename S>
+  Offset<Vector<T>> CreateVector(size_t vector_size, F f, S *state) {
+    std::vector<T> elems(vector_size);
+    for (size_t i = 0; i < vector_size; i++) elems[i] = f(i, state);
+    return CreateVector(elems);
+  }
+
+  /// @brief Serialize a `std::vector<std::string>` into a FlatBuffer `vector`.
+  /// This is a convenience function for a common case.
+  /// @param v A const reference to the `std::vector` to serialize into the
+  /// buffer as a `vector`.
+  /// @return Returns a typed `Offset` into the serialized data indicating
+  /// where the vector is stored.
+  Offset<Vector<Offset<String>>> CreateVectorOfStrings(
+      const std::vector<std::string> &v) {
+    std::vector<Offset<String>> offsets(v.size());
+    for (size_t i = 0; i < v.size(); i++) offsets[i] = CreateString(v[i]);
+    return CreateVector(offsets);
+  }
+
+  /// @brief Serialize an array of structs into a FlatBuffer `vector`.
+  /// @tparam T The data type of the struct array elements.
+  /// @param[in] v A pointer to the array of type `T` to serialize into the
+  /// buffer as a `vector`.
+  /// @param[in] len The number of elements to serialize.
+  /// @return Returns a typed `Offset` into the serialized data indicating
+  /// where the vector is stored.
+  template<typename T>
+  Offset<Vector<const T *>> CreateVectorOfStructs(const T *v, size_t len) {
+    StartVector(len * sizeof(T) / AlignOf<T>(), AlignOf<T>());
+    PushBytes(reinterpret_cast<const uint8_t *>(v), sizeof(T) * len);
+    return Offset<Vector<const T *>>(EndVector(len));
+  }
+
+  /// @brief Serialize an array of native structs into a FlatBuffer `vector`.
+  /// @tparam T The data type of the struct array elements.
+  /// @tparam S The data type of the native struct array elements.
+  /// @param[in] v A pointer to the array of type `S` to serialize into the
+  /// buffer as a `vector`.
+  /// @param[in] len The number of elements to serialize.
+  /// @return Returns a typed `Offset` into the serialized data indicating
+  /// where the vector is stored.
+  template<typename T, typename S>
+  Offset<Vector<const T *>> CreateVectorOfNativeStructs(const S *v,
+                                                        size_t len) {
+    extern T Pack(const S &);
+    std::vector<T> vv(len);
+    std::transform(v, v + len, vv.begin(), Pack);
+    return CreateVectorOfStructs<T>(vv.data(), vv.size());
+  }
+
+  // clang-format off
+  #ifndef FLATBUFFERS_CPP98_STL
+  /// @brief Serialize an array of structs into a FlatBuffer `vector`.
+  /// @tparam T The data type of the struct array elements.
+  /// @param[in] f A function that takes the current iteration 0..vector_size-1
+  /// and a pointer to the struct that must be filled.
+  /// @return Returns a typed `Offset` into the serialized data indicating
+  /// where the vector is stored.
+  /// This is mostly useful when flatbuffers are generated with mutation
+  /// accessors.
+  template<typename T> Offset<Vector<const T *>> CreateVectorOfStructs(
+      size_t vector_size, const std::function<void(size_t i, T *)> &filler) {
+    T* structs = StartVectorOfStructs<T>(vector_size);
+    for (size_t i = 0; i < vector_size; i++) {
+      filler(i, structs);
+      structs++;
+    }
+    return EndVectorOfStructs<T>(vector_size);
+  }
+  #endif
+  // clang-format on
+
+  /// @brief Serialize an array of structs into a FlatBuffer `vector`.
+  /// @tparam T The data type of the struct array elements.
+  /// @param[in] f A function that takes the current iteration 0..vector_size-1,
+  /// a pointer to the struct that must be filled and the state argument.
+  /// @param[in] state Arbitrary state to pass to f.
+  /// @return Returns a typed `Offset` into the serialized data indicating
+  /// where the vector is stored.
+  /// This is mostly useful when flatbuffers are generated with mutation
+  /// accessors.
+  template<typename T, typename F, typename S>
+  Offset<Vector<const T *>> CreateVectorOfStructs(size_t vector_size, F f,
+                                                  S *state) {
+    T *structs = StartVectorOfStructs<T>(vector_size);
+    for (size_t i = 0; i < vector_size; i++) {
+      f(i, structs, state);
+      structs++;
+    }
+    return EndVectorOfStructs<T>(vector_size);
+  }
+
+  /// @brief Serialize a `std::vector` of structs into a FlatBuffer `vector`.
+  /// @tparam T The data type of the `std::vector` struct elements.
+  /// @param[in]] v A const reference to the `std::vector` of structs to
+  /// serialize into the buffer as a `vector`.
+  /// @return Returns a typed `Offset` into the serialized data indicating
+  /// where the vector is stored.
+  template<typename T, typename Alloc>
+  Offset<Vector<const T *>> CreateVectorOfStructs(
+      const std::vector<T, Alloc> &v) {
+    return CreateVectorOfStructs(data(v), v.size());
+  }
+
+  /// @brief Serialize a `std::vector` of native structs into a FlatBuffer
+  /// `vector`.
+  /// @tparam T The data type of the `std::vector` struct elements.
+  /// @tparam S The data type of the `std::vector` native struct elements.
+  /// @param[in]] v A const reference to the `std::vector` of structs to
+  /// serialize into the buffer as a `vector`.
+  /// @return Returns a typed `Offset` into the serialized data indicating
+  /// where the vector is stored.
+  template<typename T, typename S>
+  Offset<Vector<const T *>> CreateVectorOfNativeStructs(
+      const std::vector<S> &v) {
+    return CreateVectorOfNativeStructs<T, S>(data(v), v.size());
+  }
+
+  /// @cond FLATBUFFERS_INTERNAL
+  template<typename T> struct StructKeyComparator {
+    bool operator()(const T &a, const T &b) const {
+      return a.KeyCompareLessThan(&b);
+    }
+
+   private:
+    StructKeyComparator &operator=(const StructKeyComparator &);
+  };
+  /// @endcond
+
+  /// @brief Serialize a `std::vector` of structs into a FlatBuffer `vector`
+  /// in sorted order.
+  /// @tparam T The data type of the `std::vector` struct elements.
+  /// @param[in]] v A const reference to the `std::vector` of structs to
+  /// serialize into the buffer as a `vector`.
+  /// @return Returns a typed `Offset` into the serialized data indicating
+  /// where the vector is stored.
+  template<typename T>
+  Offset<Vector<const T *>> CreateVectorOfSortedStructs(std::vector<T> *v) {
+    return CreateVectorOfSortedStructs(data(*v), v->size());
+  }
+
+  /// @brief Serialize a `std::vector` of native structs into a FlatBuffer
+  /// `vector` in sorted order.
+  /// @tparam T The data type of the `std::vector` struct elements.
+  /// @tparam S The data type of the `std::vector` native struct elements.
+  /// @param[in]] v A const reference to the `std::vector` of structs to
+  /// serialize into the buffer as a `vector`.
+  /// @return Returns a typed `Offset` into the serialized data indicating
+  /// where the vector is stored.
+  template<typename T, typename S>
+  Offset<Vector<const T *>> CreateVectorOfSortedNativeStructs(
+      std::vector<S> *v) {
+    return CreateVectorOfSortedNativeStructs<T, S>(data(*v), v->size());
+  }
+
+  /// @brief Serialize an array of structs into a FlatBuffer `vector` in sorted
+  /// order.
+  /// @tparam T The data type of the struct array elements.
+  /// @param[in] v A pointer to the array of type `T` to serialize into the
+  /// buffer as a `vector`.
+  /// @param[in] len The number of elements to serialize.
+  /// @return Returns a typed `Offset` into the serialized data indicating
+  /// where the vector is stored.
+  template<typename T>
+  Offset<Vector<const T *>> CreateVectorOfSortedStructs(T *v, size_t len) {
+    std::sort(v, v + len, StructKeyComparator<T>());
+    return CreateVectorOfStructs(v, len);
+  }
+
+  /// @brief Serialize an array of native structs into a FlatBuffer `vector` in
+  /// sorted order.
+  /// @tparam T The data type of the struct array elements.
+  /// @tparam S The data type of the native struct array elements.
+  /// @param[in] v A pointer to the array of type `S` to serialize into the
+  /// buffer as a `vector`.
+  /// @param[in] len The number of elements to serialize.
+  /// @return Returns a typed `Offset` into the serialized data indicating
+  /// where the vector is stored.
+  template<typename T, typename S>
+  Offset<Vector<const T *>> CreateVectorOfSortedNativeStructs(S *v,
+                                                              size_t len) {
+    extern T Pack(const S &);
+    typedef T (*Pack_t)(const S &);
+    std::vector<T> vv(len);
+    std::transform(v, v + len, vv.begin(), static_cast<Pack_t&>(Pack));
+    return CreateVectorOfSortedStructs<T>(vv, len);
+  }
+
+  /// @cond FLATBUFFERS_INTERNAL
+  template<typename T> struct TableKeyComparator {
+    TableKeyComparator(vector_downward &buf) : buf_(buf) {}
+    bool operator()(const Offset<T> &a, const Offset<T> &b) const {
+      auto table_a = reinterpret_cast<T *>(buf_.data_at(a.o));
+      auto table_b = reinterpret_cast<T *>(buf_.data_at(b.o));
+      return table_a->KeyCompareLessThan(table_b);
+    }
+    vector_downward &buf_;
+
+   private:
+    TableKeyComparator &operator=(const TableKeyComparator &);
+  };
+  /// @endcond
+
+  /// @brief Serialize an array of `table` offsets as a `vector` in the buffer
+  /// in sorted order.
+  /// @tparam T The data type that the offset refers to.
+  /// @param[in] v An array of type `Offset<T>` that contains the `table`
+  /// offsets to store in the buffer in sorted order.
+  /// @param[in] len The number of elements to store in the `vector`.
+  /// @return Returns a typed `Offset` into the serialized data indicating
+  /// where the vector is stored.
+  template<typename T>
+  Offset<Vector<Offset<T>>> CreateVectorOfSortedTables(Offset<T> *v,
+                                                       size_t len) {
+    std::sort(v, v + len, TableKeyComparator<T>(buf_));
+    return CreateVector(v, len);
+  }
+
+  /// @brief Serialize an array of `table` offsets as a `vector` in the buffer
+  /// in sorted order.
+  /// @tparam T The data type that the offset refers to.
+  /// @param[in] v An array of type `Offset<T>` that contains the `table`
+  /// offsets to store in the buffer in sorted order.
+  /// @return Returns a typed `Offset` into the serialized data indicating
+  /// where the vector is stored.
+  template<typename T>
+  Offset<Vector<Offset<T>>> CreateVectorOfSortedTables(
+      std::vector<Offset<T>> *v) {
+    return CreateVectorOfSortedTables(data(*v), v->size());
+  }
+
+  /// @brief Specialized version of `CreateVector` for non-copying use cases.
+  /// Write the data any time later to the returned buffer pointer `buf`.
+  /// @param[in] len The number of elements to store in the `vector`.
+  /// @param[in] elemsize The size of each element in the `vector`.
+  /// @param[out] buf A pointer to a `uint8_t` pointer that can be
+  /// written to at a later time to serialize the data into a `vector`
+  /// in the buffer.
+  uoffset_t CreateUninitializedVector(size_t len, size_t elemsize,
+                                      uint8_t **buf) {
+    NotNested();
+    StartVector(len, elemsize);
+    buf_.make_space(len * elemsize);
+    auto vec_start = GetSize();
+    auto vec_end = EndVector(len);
+    *buf = buf_.data_at(vec_start);
+    return vec_end;
+  }
+
+  /// @brief Specialized version of `CreateVector` for non-copying use cases.
+  /// Write the data any time later to the returned buffer pointer `buf`.
+  /// @tparam T The data type of the data that will be stored in the buffer
+  /// as a `vector`.
+  /// @param[in] len The number of elements to store in the `vector`.
+  /// @param[out] buf A pointer to a pointer of type `T` that can be
+  /// written to at a later time to serialize the data into a `vector`
+  /// in the buffer.
+  template<typename T>
+  Offset<Vector<T>> CreateUninitializedVector(size_t len, T **buf) {
+    AssertScalarT<T>();
+    return CreateUninitializedVector(len, sizeof(T),
+                                     reinterpret_cast<uint8_t **>(buf));
+  }
+
+  template<typename T>
+  Offset<Vector<const T*>> CreateUninitializedVectorOfStructs(size_t len, T **buf) {
+    return CreateUninitializedVector(len, sizeof(T),
+                                     reinterpret_cast<uint8_t **>(buf));
+  }
+
+
+  // @brief Create a vector of scalar type T given as input a vector of scalar
+  // type U, useful with e.g. pre "enum class" enums, or any existing scalar
+  // data of the wrong type.
+  template<typename T, typename U>
+  Offset<Vector<T>> CreateVectorScalarCast(const U *v, size_t len) {
+    AssertScalarT<T>();
+    AssertScalarT<U>();
+    StartVector(len, sizeof(T));
+    for (auto i = len; i > 0;) { PushElement(static_cast<T>(v[--i])); }
+    return Offset<Vector<T>>(EndVector(len));
+  }
+
+  /// @brief Write a struct by itself, typically to be part of a union.
+  template<typename T> Offset<const T *> CreateStruct(const T &structobj) {
+    NotNested();
+    Align(AlignOf<T>());
+    buf_.push_small(structobj);
+    return Offset<const T *>(GetSize());
+  }
+
+  /// @brief The length of a FlatBuffer file header.
+  static const size_t kFileIdentifierLength = 4;
+
+  /// @brief Finish serializing a buffer by writing the root offset.
+  /// @param[in] file_identifier If a `file_identifier` is given, the buffer
+  /// will be prefixed with a standard FlatBuffers file header.
+  template<typename T>
+  void Finish(Offset<T> root, const char *file_identifier = nullptr) {
+    Finish(root.o, file_identifier, false);
+  }
+
+  /// @brief Finish a buffer with a 32 bit size field pre-fixed (size of the
+  /// buffer following the size field). These buffers are NOT compatible
+  /// with standard buffers created by Finish, i.e. you can't call GetRoot
+  /// on them, you have to use GetSizePrefixedRoot instead.
+  /// All >32 bit quantities in this buffer will be aligned when the whole
+  /// size pre-fixed buffer is aligned.
+  /// These kinds of buffers are useful for creating a stream of FlatBuffers.
+  template<typename T>
+  void FinishSizePrefixed(Offset<T> root,
+                          const char *file_identifier = nullptr) {
+    Finish(root.o, file_identifier, true);
+  }
+
+  void SwapBufAllocator(FlatBufferBuilder &other) {
+    buf_.swap_allocator(other.buf_);
+  }
+
+protected:
+
+  // You shouldn't really be copying instances of this class.
+  FlatBufferBuilder(const FlatBufferBuilder &);
+  FlatBufferBuilder &operator=(const FlatBufferBuilder &);
+
+  void Finish(uoffset_t root, const char *file_identifier, bool size_prefix) {
+    NotNested();
+    buf_.clear_scratch();
+    // This will cause the whole buffer to be aligned.
+    PreAlign((size_prefix ? sizeof(uoffset_t) : 0) + sizeof(uoffset_t) +
+                 (file_identifier ? kFileIdentifierLength : 0),
+             minalign_);
+    if (file_identifier) {
+      FLATBUFFERS_ASSERT(strlen(file_identifier) == kFileIdentifierLength);
+      PushBytes(reinterpret_cast<const uint8_t *>(file_identifier),
+                kFileIdentifierLength);
+    }
+    PushElement(ReferTo(root));  // Location of root.
+    if (size_prefix) { PushElement(GetSize()); }
+    finished = true;
+  }
+
+  struct FieldLoc {
+    uoffset_t off;
+    voffset_t id;
+  };
+
+  vector_downward buf_;
+
+  // Accumulating offsets of table members while it is being built.
+  // We store these in the scratch pad of buf_, after the vtable offsets.
+  uoffset_t num_field_loc;
+  // Track how much of the vtable is in use, so we can output the most compact
+  // possible vtable.
+  voffset_t max_voffset_;
+
+  // Ensure objects are not nested.
+  bool nested;
+
+  // Ensure the buffer is finished before it is being accessed.
+  bool finished;
+
+  size_t minalign_;
+
+  bool force_defaults_;  // Serialize values equal to their defaults anyway.
+
+  bool dedup_vtables_;
+
+  struct StringOffsetCompare {
+    StringOffsetCompare(const vector_downward &buf) : buf_(&buf) {}
+    bool operator()(const Offset<String> &a, const Offset<String> &b) const {
+      auto stra = reinterpret_cast<const String *>(buf_->data_at(a.o));
+      auto strb = reinterpret_cast<const String *>(buf_->data_at(b.o));
+      return StringLessThan(stra->data(), stra->size(),
+                            strb->data(), strb->size());
+    }
+    const vector_downward *buf_;
+  };
+
+  // For use with CreateSharedString. Instantiated on first use only.
+  typedef std::set<Offset<String>, StringOffsetCompare> StringOffsetMap;
+  StringOffsetMap *string_pool;
+
+ private:
+  // Allocates space for a vector of structures.
+  // Must be completed with EndVectorOfStructs().
+  template<typename T> T *StartVectorOfStructs(size_t vector_size) {
+    StartVector(vector_size * sizeof(T) / AlignOf<T>(), AlignOf<T>());
+    return reinterpret_cast<T *>(buf_.make_space(vector_size * sizeof(T)));
+  }
+
+  // End the vector of structues in the flatbuffers.
+  // Vector should have previously be started with StartVectorOfStructs().
+  template<typename T>
+  Offset<Vector<const T *>> EndVectorOfStructs(size_t vector_size) {
+    return Offset<Vector<const T *>>(EndVector(vector_size));
+  }
+};
+/// @}
+
+/// @cond FLATBUFFERS_INTERNAL
+// Helpers to get a typed pointer to the root object contained in the buffer.
+template<typename T> T *GetMutableRoot(void *buf) {
+  EndianCheck();
+  return reinterpret_cast<T *>(
+      reinterpret_cast<uint8_t *>(buf) +
+      EndianScalar(*reinterpret_cast<uoffset_t *>(buf)));
+}
+
+template<typename T> const T *GetRoot(const void *buf) {
+  return GetMutableRoot<T>(const_cast<void *>(buf));
+}
+
+template<typename T> const T *GetSizePrefixedRoot(const void *buf) {
+  return GetRoot<T>(reinterpret_cast<const uint8_t *>(buf) + sizeof(uoffset_t));
+}
+
+/// Helpers to get a typed pointer to objects that are currently being built.
+/// @warning Creating new objects will lead to reallocations and invalidates
+/// the pointer!
+template<typename T>
+T *GetMutableTemporaryPointer(FlatBufferBuilder &fbb, Offset<T> offset) {
+  return reinterpret_cast<T *>(fbb.GetCurrentBufferPointer() + fbb.GetSize() -
+                               offset.o);
+}
+
+template<typename T>
+const T *GetTemporaryPointer(FlatBufferBuilder &fbb, Offset<T> offset) {
+  return GetMutableTemporaryPointer<T>(fbb, offset);
+}
+
+/// @brief Get a pointer to the the file_identifier section of the buffer.
+/// @return Returns a const char pointer to the start of the file_identifier
+/// characters in the buffer.  The returned char * has length
+/// 'flatbuffers::FlatBufferBuilder::kFileIdentifierLength'.
+/// This function is UNDEFINED for FlatBuffers whose schema does not include
+/// a file_identifier (likely points at padding or the start of a the root
+/// vtable).
+inline const char *GetBufferIdentifier(const void *buf, bool size_prefixed = false) {
+  return reinterpret_cast<const char *>(buf) +
+         ((size_prefixed) ? 2 * sizeof(uoffset_t) : sizeof(uoffset_t));
+}
+
+// Helper to see if the identifier in a buffer has the expected value.
+inline bool BufferHasIdentifier(const void *buf, const char *identifier, bool size_prefixed = false) {
+  return strncmp(GetBufferIdentifier(buf, size_prefixed), identifier,
+                 FlatBufferBuilder::kFileIdentifierLength) == 0;
+}
+
+// Helper class to verify the integrity of a FlatBuffer
+class Verifier FLATBUFFERS_FINAL_CLASS {
+ public:
+  Verifier(const uint8_t *buf, size_t buf_len, uoffset_t _max_depth = 64,
+           uoffset_t _max_tables = 1000000, bool _check_alignment = true)
+      : buf_(buf),
+        size_(buf_len),
+        depth_(0),
+        max_depth_(_max_depth),
+        num_tables_(0),
+        max_tables_(_max_tables),
+        upper_bound_(0),
+        check_alignment_(_check_alignment)
+  {
+    FLATBUFFERS_ASSERT(size_ < FLATBUFFERS_MAX_BUFFER_SIZE);
+  }
+
+  // Central location where any verification failures register.
+  bool Check(bool ok) const {
+    // clang-format off
+    #ifdef FLATBUFFERS_DEBUG_VERIFICATION_FAILURE
+      FLATBUFFERS_ASSERT(ok);
+    #endif
+    #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
+      if (!ok)
+        upper_bound_ = 0;
+    #endif
+    // clang-format on
+    return ok;
+  }
+
+  // Verify any range within the buffer.
+  bool Verify(size_t elem, size_t elem_len) const {
+    // clang-format off
+    #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
+      auto upper_bound = elem + elem_len;
+      if (upper_bound_ < upper_bound)
+        upper_bound_ =  upper_bound;
+    #endif
+    // clang-format on
+    return Check(elem_len < size_ && elem <= size_ - elem_len);
+  }
+
+  template<typename T> bool VerifyAlignment(size_t elem) const {
+    return (elem & (sizeof(T) - 1)) == 0 || !check_alignment_;
+  }
+
+  // Verify a range indicated by sizeof(T).
+  template<typename T> bool Verify(size_t elem) const {
+    return VerifyAlignment<T>(elem) && Verify(elem, sizeof(T));
+  }
+
+  // Verify relative to a known-good base pointer.
+  bool Verify(const uint8_t *base, voffset_t elem_off, size_t elem_len) const {
+    return Verify(static_cast<size_t>(base - buf_) + elem_off, elem_len);
+  }
+
+  template<typename T> bool Verify(const uint8_t *base, voffset_t elem_off)
+      const {
+    return Verify(static_cast<size_t>(base - buf_) + elem_off, sizeof(T));
+  }
+
+  // Verify a pointer (may be NULL) of a table type.
+  template<typename T> bool VerifyTable(const T *table) {
+    return !table || table->Verify(*this);
+  }
+
+  // Verify a pointer (may be NULL) of any vector type.
+  template<typename T> bool VerifyVector(const Vector<T> *vec) const {
+    return !vec || VerifyVectorOrString(reinterpret_cast<const uint8_t *>(vec),
+                                        sizeof(T));
+  }
+
+  // Verify a pointer (may be NULL) of a vector to struct.
+  template<typename T> bool VerifyVector(const Vector<const T *> *vec) const {
+    return VerifyVector(reinterpret_cast<const Vector<T> *>(vec));
+  }
+
+  // Verify a pointer (may be NULL) to string.
+  bool VerifyString(const String *str) const {
+    size_t end;
+    return !str ||
+           (VerifyVectorOrString(reinterpret_cast<const uint8_t *>(str),
+                                 1, &end) &&
+            Verify(end, 1) &&      // Must have terminator
+            Check(buf_[end] == '\0'));  // Terminating byte must be 0.
+  }
+
+  // Common code between vectors and strings.
+  bool VerifyVectorOrString(const uint8_t *vec, size_t elem_size,
+                    size_t *end = nullptr) const {
+    auto veco = static_cast<size_t>(vec - buf_);
+    // Check we can read the size field.
+    if (!Verify<uoffset_t>(veco)) return false;
+    // Check the whole array. If this is a string, the byte past the array
+    // must be 0.
+    auto size = ReadScalar<uoffset_t>(vec);
+    auto max_elems = FLATBUFFERS_MAX_BUFFER_SIZE / elem_size;
+    if (!Check(size < max_elems))
+      return false;  // Protect against byte_size overflowing.
+    auto byte_size = sizeof(size) + elem_size * size;
+    if (end) *end = veco + byte_size;
+    return Verify(veco, byte_size);
+  }
+
+  // Special case for string contents, after the above has been called.
+  bool VerifyVectorOfStrings(const Vector<Offset<String>> *vec) const {
+    if (vec) {
+      for (uoffset_t i = 0; i < vec->size(); i++) {
+        if (!VerifyString(vec->Get(i))) return false;
+      }
+    }
+    return true;
+  }
+
+  // Special case for table contents, after the above has been called.
+  template<typename T> bool VerifyVectorOfTables(const Vector<Offset<T>> *vec) {
+    if (vec) {
+      for (uoffset_t i = 0; i < vec->size(); i++) {
+        if (!vec->Get(i)->Verify(*this)) return false;
+      }
+    }
+    return true;
+  }
+
+  bool VerifyTableStart(const uint8_t *table) {
+    // Check the vtable offset.
+    auto tableo = static_cast<size_t>(table - buf_);
+    if (!Verify<soffset_t>(tableo)) return false;
+    // This offset may be signed, but doing the substraction unsigned always
+    // gives the result we want.
+    auto vtableo = tableo - static_cast<size_t>(ReadScalar<soffset_t>(table));
+    // Check the vtable size field, then check vtable fits in its entirety.
+    return VerifyComplexity() && Verify<voffset_t>(vtableo) &&
+           VerifyAlignment<voffset_t>(ReadScalar<voffset_t>(buf_ + vtableo)) &&
+           Verify(vtableo, ReadScalar<voffset_t>(buf_ + vtableo));
+  }
+
+  template<typename T>
+  bool VerifyBufferFromStart(const char *identifier, size_t start) {
+    if (identifier &&
+        (size_ < 2 * sizeof(flatbuffers::uoffset_t) ||
+         !BufferHasIdentifier(buf_ + start, identifier))) {
+      return false;
+    }
+
+    // Call T::Verify, which must be in the generated code for this type.
+    auto o = VerifyOffset(start);
+    return o && reinterpret_cast<const T *>(buf_ + start + o)->Verify(*this)
+    // clang-format off
+    #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
+           && GetComputedSize()
+    #endif
+        ;
+    // clang-format on
+  }
+
+  // Verify this whole buffer, starting with root type T.
+  template<typename T> bool VerifyBuffer() { return VerifyBuffer<T>(nullptr); }
+
+  template<typename T> bool VerifyBuffer(const char *identifier) {
+    return VerifyBufferFromStart<T>(identifier, 0);
+  }
+
+  template<typename T> bool VerifySizePrefixedBuffer(const char *identifier) {
+    return Verify<uoffset_t>(0U) &&
+           ReadScalar<uoffset_t>(buf_) == size_ - sizeof(uoffset_t) &&
+           VerifyBufferFromStart<T>(identifier, sizeof(uoffset_t));
+  }
+
+  uoffset_t VerifyOffset(size_t start) const {
+    if (!Verify<uoffset_t>(start)) return 0;
+    auto o = ReadScalar<uoffset_t>(buf_ + start);
+    // May not point to itself.
+    if (!Check(o != 0)) return 0;
+    // Can't wrap around / buffers are max 2GB.
+    if (!Check(static_cast<soffset_t>(o) >= 0)) return 0;
+    // Must be inside the buffer to create a pointer from it (pointer outside
+    // buffer is UB).
+    if (!Verify(start + o, 1)) return 0;
+    return o;
+  }
+
+  uoffset_t VerifyOffset(const uint8_t *base, voffset_t start) const {
+    return VerifyOffset(static_cast<size_t>(base - buf_) + start);
+  }
+
+  // Called at the start of a table to increase counters measuring data
+  // structure depth and amount, and possibly bails out with false if
+  // limits set by the constructor have been hit. Needs to be balanced
+  // with EndTable().
+  bool VerifyComplexity() {
+    depth_++;
+    num_tables_++;
+    return Check(depth_ <= max_depth_ && num_tables_ <= max_tables_);
+  }
+
+  // Called at the end of a table to pop the depth count.
+  bool EndTable() {
+    depth_--;
+    return true;
+  }
+
+  // Returns the message size in bytes
+  size_t GetComputedSize() const {
+    // clang-format off
+    #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
+      uintptr_t size = upper_bound_;
+      // Align the size to uoffset_t
+      size = (size - 1 + sizeof(uoffset_t)) & ~(sizeof(uoffset_t) - 1);
+      return (size > size_) ?  0 : size;
+    #else
+      // Must turn on FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE for this to work.
+      (void)upper_bound_;
+      FLATBUFFERS_ASSERT(false);
+      return 0;
+    #endif
+    // clang-format on
+  }
+
+ private:
+  const uint8_t *buf_;
+  size_t size_;
+  uoffset_t depth_;
+  uoffset_t max_depth_;
+  uoffset_t num_tables_;
+  uoffset_t max_tables_;
+  mutable size_t upper_bound_;
+  bool check_alignment_;
+};
+
+// Convenient way to bundle a buffer and its length, to pass it around
+// typed by its root.
+// A BufferRef does not own its buffer.
+struct BufferRefBase {};  // for std::is_base_of
+template<typename T> struct BufferRef : BufferRefBase {
+  BufferRef() : buf(nullptr), len(0), must_free(false) {}
+  BufferRef(uint8_t *_buf, uoffset_t _len)
+      : buf(_buf), len(_len), must_free(false) {}
+
+  ~BufferRef() {
+    if (must_free) free(buf);
+  }
+
+  const T *GetRoot() const { return flatbuffers::GetRoot<T>(buf); }
+
+  bool Verify() {
+    Verifier verifier(buf, len);
+    return verifier.VerifyBuffer<T>(nullptr);
+  }
+
+  uint8_t *buf;
+  uoffset_t len;
+  bool must_free;
+};
+
+// "structs" are flat structures that do not have an offset table, thus
+// always have all members present and do not support forwards/backwards
+// compatible extensions.
+
+class Struct FLATBUFFERS_FINAL_CLASS {
+ public:
+  template<typename T> T GetField(uoffset_t o) const {
+    return ReadScalar<T>(&data_[o]);
+  }
+
+  template<typename T> T GetStruct(uoffset_t o) const {
+    return reinterpret_cast<T>(&data_[o]);
+  }
+
+  const uint8_t *GetAddressOf(uoffset_t o) const { return &data_[o]; }
+  uint8_t *GetAddressOf(uoffset_t o) { return &data_[o]; }
+
+ private:
+  uint8_t data_[1];
+};
+
+// "tables" use an offset table (possibly shared) that allows fields to be
+// omitted and added at will, but uses an extra indirection to read.
+class Table {
+ public:
+  const uint8_t *GetVTable() const {
+    return data_ - ReadScalar<soffset_t>(data_);
+  }
+
+  // This gets the field offset for any of the functions below it, or 0
+  // if the field was not present.
+  voffset_t GetOptionalFieldOffset(voffset_t field) const {
+    // The vtable offset is always at the start.
+    auto vtable = GetVTable();
+    // The first element is the size of the vtable (fields + type id + itself).
+    auto vtsize = ReadScalar<voffset_t>(vtable);
+    // If the field we're accessing is outside the vtable, we're reading older
+    // data, so it's the same as if the offset was 0 (not present).
+    return field < vtsize ? ReadScalar<voffset_t>(vtable + field) : 0;
+  }
+
+  template<typename T> T GetField(voffset_t field, T defaultval) const {
+    auto field_offset = GetOptionalFieldOffset(field);
+    return field_offset ? ReadScalar<T>(data_ + field_offset) : defaultval;
+  }
+
+  template<typename P> P GetPointer(voffset_t field) {
+    auto field_offset = GetOptionalFieldOffset(field);
+    auto p = data_ + field_offset;
+    return field_offset ? reinterpret_cast<P>(p + ReadScalar<uoffset_t>(p))
+                        : nullptr;
+  }
+  template<typename P> P GetPointer(voffset_t field) const {
+    return const_cast<Table *>(this)->GetPointer<P>(field);
+  }
+
+  template<typename P> P GetStruct(voffset_t field) const {
+    auto field_offset = GetOptionalFieldOffset(field);
+    auto p = const_cast<uint8_t *>(data_ + field_offset);
+    return field_offset ? reinterpret_cast<P>(p) : nullptr;
+  }
+
+  template<typename T> bool SetField(voffset_t field, T val, T def) {
+    auto field_offset = GetOptionalFieldOffset(field);
+    if (!field_offset) return IsTheSameAs(val, def);
+    WriteScalar(data_ + field_offset, val);
+    return true;
+  }
+
+  bool SetPointer(voffset_t field, const uint8_t *val) {
+    auto field_offset = GetOptionalFieldOffset(field);
+    if (!field_offset) return false;
+    WriteScalar(data_ + field_offset,
+                static_cast<uoffset_t>(val - (data_ + field_offset)));
+    return true;
+  }
+
+  uint8_t *GetAddressOf(voffset_t field) {
+    auto field_offset = GetOptionalFieldOffset(field);
+    return field_offset ? data_ + field_offset : nullptr;
+  }
+  const uint8_t *GetAddressOf(voffset_t field) const {
+    return const_cast<Table *>(this)->GetAddressOf(field);
+  }
+
+  bool CheckField(voffset_t field) const {
+    return GetOptionalFieldOffset(field) != 0;
+  }
+
+  // Verify the vtable of this table.
+  // Call this once per table, followed by VerifyField once per field.
+  bool VerifyTableStart(Verifier &verifier) const {
+    return verifier.VerifyTableStart(data_);
+  }
+
+  // Verify a particular field.
+  template<typename T>
+  bool VerifyField(const Verifier &verifier, voffset_t field) const {
+    // Calling GetOptionalFieldOffset should be safe now thanks to
+    // VerifyTable().
+    auto field_offset = GetOptionalFieldOffset(field);
+    // Check the actual field.
+    return !field_offset || verifier.Verify<T>(data_, field_offset);
+  }
+
+  // VerifyField for required fields.
+  template<typename T>
+  bool VerifyFieldRequired(const Verifier &verifier, voffset_t field) const {
+    auto field_offset = GetOptionalFieldOffset(field);
+    return verifier.Check(field_offset != 0) &&
+           verifier.Verify<T>(data_, field_offset);
+  }
+
+  // Versions for offsets.
+  bool VerifyOffset(const Verifier &verifier, voffset_t field) const {
+    auto field_offset = GetOptionalFieldOffset(field);
+    return !field_offset || verifier.VerifyOffset(data_, field_offset);
+  }
+
+  bool VerifyOffsetRequired(const Verifier &verifier, voffset_t field) const {
+    auto field_offset = GetOptionalFieldOffset(field);
+    return verifier.Check(field_offset != 0) &&
+           verifier.VerifyOffset(data_, field_offset);
+  }
+
+ private:
+  // private constructor & copy constructor: you obtain instances of this
+  // class by pointing to existing data only
+  Table();
+  Table(const Table &other);
+
+  uint8_t data_[1];
+};
+
+template<typename T> void FlatBufferBuilder::Required(Offset<T> table,
+                                                      voffset_t field) {
+  auto table_ptr = reinterpret_cast<const Table *>(buf_.data_at(table.o));
+  bool ok = table_ptr->GetOptionalFieldOffset(field) != 0;
+  // If this fails, the caller will show what field needs to be set.
+  FLATBUFFERS_ASSERT(ok);
+  (void)ok;
+}
+
+/// @brief This can compute the start of a FlatBuffer from a root pointer, i.e.
+/// it is the opposite transformation of GetRoot().
+/// This may be useful if you want to pass on a root and have the recipient
+/// delete the buffer afterwards.
+inline const uint8_t *GetBufferStartFromRootPointer(const void *root) {
+  auto table = reinterpret_cast<const Table *>(root);
+  auto vtable = table->GetVTable();
+  // Either the vtable is before the root or after the root.
+  auto start = (std::min)(vtable, reinterpret_cast<const uint8_t *>(root));
+  // Align to at least sizeof(uoffset_t).
+  start = reinterpret_cast<const uint8_t *>(reinterpret_cast<uintptr_t>(start) &
+                                            ~(sizeof(uoffset_t) - 1));
+  // Additionally, there may be a file_identifier in the buffer, and the root
+  // offset. The buffer may have been aligned to any size between
+  // sizeof(uoffset_t) and FLATBUFFERS_MAX_ALIGNMENT (see "force_align").
+  // Sadly, the exact alignment is only known when constructing the buffer,
+  // since it depends on the presence of values with said alignment properties.
+  // So instead, we simply look at the next uoffset_t values (root,
+  // file_identifier, and alignment padding) to see which points to the root.
+  // None of the other values can "impersonate" the root since they will either
+  // be 0 or four ASCII characters.
+  static_assert(FlatBufferBuilder::kFileIdentifierLength == sizeof(uoffset_t),
+                "file_identifier is assumed to be the same size as uoffset_t");
+  for (auto possible_roots = FLATBUFFERS_MAX_ALIGNMENT / sizeof(uoffset_t) + 1;
+       possible_roots; possible_roots--) {
+    start -= sizeof(uoffset_t);
+    if (ReadScalar<uoffset_t>(start) + start ==
+        reinterpret_cast<const uint8_t *>(root))
+      return start;
+  }
+  // We didn't find the root, either the "root" passed isn't really a root,
+  // or the buffer is corrupt.
+  // Assert, because calling this function with bad data may cause reads
+  // outside of buffer boundaries.
+  FLATBUFFERS_ASSERT(false);
+  return nullptr;
+}
+
+/// @brief This return the prefixed size of a FlatBuffer.
+inline uoffset_t GetPrefixedSize(const uint8_t* buf){ return ReadScalar<uoffset_t>(buf); }
+
+// Base class for native objects (FlatBuffer data de-serialized into native
+// C++ data structures).
+// Contains no functionality, purely documentative.
+struct NativeTable {};
+
+/// @brief Function types to be used with resolving hashes into objects and
+/// back again. The resolver gets a pointer to a field inside an object API
+/// object that is of the type specified in the schema using the attribute
+/// `cpp_type` (it is thus important whatever you write to this address
+/// matches that type). The value of this field is initially null, so you
+/// may choose to implement a delayed binding lookup using this function
+/// if you wish. The resolver does the opposite lookup, for when the object
+/// is being serialized again.
+typedef uint64_t hash_value_t;
+// clang-format off
+#ifdef FLATBUFFERS_CPP98_STL
+  typedef void (*resolver_function_t)(void **pointer_adr, hash_value_t hash);
+  typedef hash_value_t (*rehasher_function_t)(void *pointer);
+#else
+  typedef std::function<void (void **pointer_adr, hash_value_t hash)>
+          resolver_function_t;
+  typedef std::function<hash_value_t (void *pointer)> rehasher_function_t;
+#endif
+// clang-format on
+
+// Helper function to test if a field is present, using any of the field
+// enums in the generated code.
+// `table` must be a generated table type. Since this is a template parameter,
+// this is not typechecked to be a subclass of Table, so beware!
+// Note: this function will return false for fields equal to the default
+// value, since they're not stored in the buffer (unless force_defaults was
+// used).
+template<typename T>
+bool IsFieldPresent(const T *table, typename T::FlatBuffersVTableOffset field) {
+  // Cast, since Table is a private baseclass of any table types.
+  return reinterpret_cast<const Table *>(table)->CheckField(
+      static_cast<voffset_t>(field));
+}
+
+// Utility function for reverse lookups on the EnumNames*() functions
+// (in the generated C++ code)
+// names must be NULL terminated.
+inline int LookupEnum(const char **names, const char *name) {
+  for (const char **p = names; *p; p++)
+    if (!strcmp(*p, name)) return static_cast<int>(p - names);
+  return -1;
+}
+
+// These macros allow us to layout a struct with a guarantee that they'll end
+// up looking the same on different compilers and platforms.
+// It does this by disallowing the compiler to do any padding, and then
+// does padding itself by inserting extra padding fields that make every
+// element aligned to its own size.
+// Additionally, it manually sets the alignment of the struct as a whole,
+// which is typically its largest element, or a custom size set in the schema
+// by the force_align attribute.
+// These are used in the generated code only.
+
+// clang-format off
+#if defined(_MSC_VER)
+  #define FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(alignment) \
+    __pragma(pack(1)) \
+    struct __declspec(align(alignment))
+  #define FLATBUFFERS_STRUCT_END(name, size) \
+    __pragma(pack()) \
+    static_assert(sizeof(name) == size, "compiler breaks packing rules")
+#elif defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__)
+  #define FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(alignment) \
+    _Pragma("pack(1)") \
+    struct __attribute__((aligned(alignment)))
+  #define FLATBUFFERS_STRUCT_END(name, size) \
+    _Pragma("pack()") \
+    static_assert(sizeof(name) == size, "compiler breaks packing rules")
+#else
+  #error Unknown compiler, please define structure alignment macros
+#endif
+// clang-format on
+
+// Minimal reflection via code generation.
+// Besides full-fat reflection (see reflection.h) and parsing/printing by
+// loading schemas (see idl.h), we can also have code generation for mimimal
+// reflection data which allows pretty-printing and other uses without needing
+// a schema or a parser.
+// Generate code with --reflect-types (types only) or --reflect-names (names
+// also) to enable.
+// See minireflect.h for utilities using this functionality.
+
+// These types are organized slightly differently as the ones in idl.h.
+enum SequenceType { ST_TABLE, ST_STRUCT, ST_UNION, ST_ENUM };
+
+// Scalars have the same order as in idl.h
+// clang-format off
+#define FLATBUFFERS_GEN_ELEMENTARY_TYPES(ET) \
+  ET(ET_UTYPE) \
+  ET(ET_BOOL) \
+  ET(ET_CHAR) \
+  ET(ET_UCHAR) \
+  ET(ET_SHORT) \
+  ET(ET_USHORT) \
+  ET(ET_INT) \
+  ET(ET_UINT) \
+  ET(ET_LONG) \
+  ET(ET_ULONG) \
+  ET(ET_FLOAT) \
+  ET(ET_DOUBLE) \
+  ET(ET_STRING) \
+  ET(ET_SEQUENCE)  // See SequenceType.
+
+enum ElementaryType {
+  #define FLATBUFFERS_ET(E) E,
+    FLATBUFFERS_GEN_ELEMENTARY_TYPES(FLATBUFFERS_ET)
+  #undef FLATBUFFERS_ET
+};
+
+inline const char * const *ElementaryTypeNames() {
+  static const char * const names[] = {
+    #define FLATBUFFERS_ET(E) #E,
+      FLATBUFFERS_GEN_ELEMENTARY_TYPES(FLATBUFFERS_ET)
+    #undef FLATBUFFERS_ET
+  };
+  return names;
+}
+// clang-format on
+
+// Basic type info cost just 16bits per field!
+struct TypeCode {
+  uint16_t base_type : 4;  // ElementaryType
+  uint16_t is_vector : 1;
+  int16_t sequence_ref : 11;  // Index into type_refs below, or -1 for none.
+};
+
+static_assert(sizeof(TypeCode) == 2, "TypeCode");
+
+struct TypeTable;
+
+// Signature of the static method present in each type.
+typedef const TypeTable *(*TypeFunction)();
+
+struct TypeTable {
+  SequenceType st;
+  size_t num_elems;  // of type_codes, values, names (but not type_refs).
+  const TypeCode *type_codes;  // num_elems count
+  const TypeFunction *type_refs;  // less than num_elems entries (see TypeCode).
+  const int64_t *values;  // Only set for non-consecutive enum/union or structs.
+  const char * const *names;     // Only set if compiled with --reflect-names.
+};
+
+// String which identifies the current version of FlatBuffers.
+// flatbuffer_version_string is used by Google developers to identify which
+// applications uploaded to Google Play are using this library.  This allows
+// the development team at Google to determine the popularity of the library.
+// How it works: Applications that are uploaded to the Google Play Store are
+// scanned for this version string.  We track which applications are using it
+// to measure popularity.  You are free to remove it (of course) but we would
+// appreciate if you left it in.
+
+// Weak linkage is culled by VS & doesn't work on cygwin.
+// clang-format off
+#if !defined(_WIN32) && !defined(__CYGWIN__)
+
+extern volatile __attribute__((weak)) const char *flatbuffer_version_string;
+volatile __attribute__((weak)) const char *flatbuffer_version_string =
+  "FlatBuffers "
+  FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MAJOR) "."
+  FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MINOR) "."
+  FLATBUFFERS_STRING(FLATBUFFERS_VERSION_REVISION);
+
+#endif  // !defined(_WIN32) && !defined(__CYGWIN__)
+
+#define FLATBUFFERS_DEFINE_BITMASK_OPERATORS(E, T)\
+    inline E operator | (E lhs, E rhs){\
+        return E(T(lhs) | T(rhs));\
+    }\
+    inline E operator & (E lhs, E rhs){\
+        return E(T(lhs) & T(rhs));\
+    }\
+    inline E operator ^ (E lhs, E rhs){\
+        return E(T(lhs) ^ T(rhs));\
+    }\
+    inline E operator ~ (E lhs){\
+        return E(~T(lhs));\
+    }\
+    inline E operator |= (E &lhs, E rhs){\
+        lhs = lhs | rhs;\
+        return lhs;\
+    }\
+    inline E operator &= (E &lhs, E rhs){\
+        lhs = lhs & rhs;\
+        return lhs;\
+    }\
+    inline E operator ^= (E &lhs, E rhs){\
+        lhs = lhs ^ rhs;\
+        return lhs;\
+    }\
+    inline bool operator !(E rhs) \
+    {\
+        return !bool(T(rhs)); \
+    }
+/// @endcond
+}  // namespace flatbuffers
+
+// clang-format on
+
+#endif  // FLATBUFFERS_H_
diff --git a/third_party/flatbuffers/include/flatbuffers/flatc.h b/third_party/flatbuffers/include/flatbuffers/flatc.h
new file mode 100644
index 0000000..f2765d2
--- /dev/null
+++ b/third_party/flatbuffers/include/flatbuffers/flatc.h
@@ -0,0 +1,96 @@
+/*
+ * 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 <functional>
+#include <limits>
+#include <string>
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/util.h"
+
+#ifndef FLATC_H_
+#  define FLATC_H_
+
+namespace flatbuffers {
+
+class FlatCompiler {
+ public:
+  // Output generator for the various programming languages and formats we
+  // support.
+  struct Generator {
+    typedef bool (*GenerateFn)(const flatbuffers::Parser &parser,
+                               const std::string &path,
+                               const std::string &file_name);
+    typedef std::string (*MakeRuleFn)(const flatbuffers::Parser &parser,
+                                      const std::string &path,
+                                      const std::string &file_name);
+
+    GenerateFn generate;
+    const char *generator_opt_short;
+    const char *generator_opt_long;
+    const char *lang_name;
+    bool schema_only;
+    GenerateFn generateGRPC;
+    flatbuffers::IDLOptions::Language lang;
+    const char *generator_help;
+    MakeRuleFn make_rule;
+  };
+
+  typedef void (*WarnFn)(const FlatCompiler *flatc, const std::string &warn,
+                         bool show_exe_name);
+
+  typedef void (*ErrorFn)(const FlatCompiler *flatc, const std::string &err,
+                          bool usage, bool show_exe_name);
+
+  // Parameters required to initialize the FlatCompiler.
+  struct InitParams {
+    InitParams()
+        : generators(nullptr),
+          num_generators(0),
+          warn_fn(nullptr),
+          error_fn(nullptr) {}
+
+    const Generator *generators;
+    size_t num_generators;
+    WarnFn warn_fn;
+    ErrorFn error_fn;
+  };
+
+  explicit FlatCompiler(const InitParams &params) : params_(params) {}
+
+  int Compile(int argc, const char **argv);
+
+  std::string GetUsageString(const char *program_name) const;
+
+ private:
+  void ParseFile(flatbuffers::Parser &parser, const std::string &filename,
+                 const std::string &contents,
+                 std::vector<const char *> &include_directories) const;
+
+  void LoadBinarySchema(Parser &parser, const std::string &filename,
+                        const std::string &contents);
+
+  void Warn(const std::string &warn, bool show_exe_name = true) const;
+
+  void Error(const std::string &err, bool usage = true,
+             bool show_exe_name = true) const;
+
+  InitParams params_;
+};
+
+}  // namespace flatbuffers
+
+#endif  // FLATC_H_
diff --git a/third_party/flatbuffers/include/flatbuffers/flexbuffers.h b/third_party/flatbuffers/include/flatbuffers/flexbuffers.h
new file mode 100644
index 0000000..7cba5b7
--- /dev/null
+++ b/third_party/flatbuffers/include/flatbuffers/flexbuffers.h
@@ -0,0 +1,1538 @@
+/*
+ * 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.
+ */
+
+#ifndef FLATBUFFERS_FLEXBUFFERS_H_
+#define FLATBUFFERS_FLEXBUFFERS_H_
+
+#include <map>
+// Used to select STL variant.
+#include "flatbuffers/base.h"
+// We use the basic binary writing functions from the regular FlatBuffers.
+#include "flatbuffers/util.h"
+
+#ifdef _MSC_VER
+#  include <intrin.h>
+#endif
+
+#if defined(_MSC_VER)
+#  pragma warning(push)
+#  pragma warning(disable : 4127)  // C4127: conditional expression is constant
+#endif
+
+namespace flexbuffers {
+
+class Reference;
+class Map;
+
+// These are used in the lower 2 bits of a type field to determine the size of
+// the elements (and or size field) of the item pointed to (e.g. vector).
+enum BitWidth {
+  BIT_WIDTH_8 = 0,
+  BIT_WIDTH_16 = 1,
+  BIT_WIDTH_32 = 2,
+  BIT_WIDTH_64 = 3,
+};
+
+// These are used as the upper 6 bits of a type field to indicate the actual
+// type.
+enum Type {
+  FBT_NULL = 0,
+  FBT_INT = 1,
+  FBT_UINT = 2,
+  FBT_FLOAT = 3,
+  // Types above stored inline, types below store an offset.
+  FBT_KEY = 4,
+  FBT_STRING = 5,
+  FBT_INDIRECT_INT = 6,
+  FBT_INDIRECT_UINT = 7,
+  FBT_INDIRECT_FLOAT = 8,
+  FBT_MAP = 9,
+  FBT_VECTOR = 10,      // Untyped.
+  FBT_VECTOR_INT = 11,  // Typed any size (stores no type table).
+  FBT_VECTOR_UINT = 12,
+  FBT_VECTOR_FLOAT = 13,
+  FBT_VECTOR_KEY = 14,
+  FBT_VECTOR_STRING = 15,
+  FBT_VECTOR_INT2 = 16,  // Typed tuple (no type table, no size field).
+  FBT_VECTOR_UINT2 = 17,
+  FBT_VECTOR_FLOAT2 = 18,
+  FBT_VECTOR_INT3 = 19,  // Typed triple (no type table, no size field).
+  FBT_VECTOR_UINT3 = 20,
+  FBT_VECTOR_FLOAT3 = 21,
+  FBT_VECTOR_INT4 = 22,  // Typed quad (no type table, no size field).
+  FBT_VECTOR_UINT4 = 23,
+  FBT_VECTOR_FLOAT4 = 24,
+  FBT_BLOB = 25,
+  FBT_BOOL = 26,
+  FBT_VECTOR_BOOL =
+      36,  // To Allow the same type of conversion of type to vector type
+};
+
+inline bool IsInline(Type t) { return t <= FBT_FLOAT || t == FBT_BOOL; }
+
+inline bool IsTypedVectorElementType(Type t) {
+  return (t >= FBT_INT && t <= FBT_STRING) || t == FBT_BOOL;
+}
+
+inline bool IsTypedVector(Type t) {
+  return (t >= FBT_VECTOR_INT && t <= FBT_VECTOR_STRING) ||
+         t == FBT_VECTOR_BOOL;
+}
+
+inline bool IsFixedTypedVector(Type t) {
+  return t >= FBT_VECTOR_INT2 && t <= FBT_VECTOR_FLOAT4;
+}
+
+inline Type ToTypedVector(Type t, size_t fixed_len = 0) {
+  FLATBUFFERS_ASSERT(IsTypedVectorElementType(t));
+  switch (fixed_len) {
+    case 0: return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT);
+    case 2: return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT2);
+    case 3: return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT3);
+    case 4: return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT4);
+    default: FLATBUFFERS_ASSERT(0); return FBT_NULL;
+  }
+}
+
+inline Type ToTypedVectorElementType(Type t) {
+  FLATBUFFERS_ASSERT(IsTypedVector(t));
+  return static_cast<Type>(t - FBT_VECTOR_INT + FBT_INT);
+}
+
+inline Type ToFixedTypedVectorElementType(Type t, uint8_t *len) {
+  FLATBUFFERS_ASSERT(IsFixedTypedVector(t));
+  auto fixed_type = t - FBT_VECTOR_INT2;
+  *len = static_cast<uint8_t>(fixed_type / 3 +
+                              2);  // 3 types each, starting from length 2.
+  return static_cast<Type>(fixed_type % 3 + FBT_INT);
+}
+
+// TODO: implement proper support for 8/16bit floats, or decide not to
+// support them.
+typedef int16_t half;
+typedef int8_t quarter;
+
+// TODO: can we do this without conditionals using intrinsics or inline asm
+// on some platforms? Given branch prediction the method below should be
+// decently quick, but it is the most frequently executed function.
+// We could do an (unaligned) 64-bit read if we ifdef out the platforms for
+// which that doesn't work (or where we'd read into un-owned memory).
+template<typename R, typename T1, typename T2, typename T4, typename T8>
+R ReadSizedScalar(const uint8_t *data, uint8_t byte_width) {
+  return byte_width < 4
+             ? (byte_width < 2
+                    ? static_cast<R>(flatbuffers::ReadScalar<T1>(data))
+                    : static_cast<R>(flatbuffers::ReadScalar<T2>(data)))
+             : (byte_width < 8
+                    ? static_cast<R>(flatbuffers::ReadScalar<T4>(data))
+                    : static_cast<R>(flatbuffers::ReadScalar<T8>(data)));
+}
+
+inline int64_t ReadInt64(const uint8_t *data, uint8_t byte_width) {
+  return ReadSizedScalar<int64_t, int8_t, int16_t, int32_t, int64_t>(
+      data, byte_width);
+}
+
+inline uint64_t ReadUInt64(const uint8_t *data, uint8_t byte_width) {
+  // This is the "hottest" function (all offset lookups use this), so worth
+  // optimizing if possible.
+  // TODO: GCC apparently replaces memcpy by a rep movsb, but only if count is a
+  // constant, which here it isn't. Test if memcpy is still faster than
+  // the conditionals in ReadSizedScalar. Can also use inline asm.
+  // clang-format off
+  #if defined(_MSC_VER) && (defined(_M_X64) || defined _M_IX86)
+    uint64_t u = 0;
+    __movsb(reinterpret_cast<uint8_t *>(&u),
+            reinterpret_cast<const uint8_t *>(data), byte_width);
+    return flatbuffers::EndianScalar(u);
+  #else
+    return ReadSizedScalar<uint64_t, uint8_t, uint16_t, uint32_t, uint64_t>(
+             data, byte_width);
+  #endif
+  // clang-format on
+}
+
+inline double ReadDouble(const uint8_t *data, uint8_t byte_width) {
+  return ReadSizedScalar<double, quarter, half, float, double>(data,
+                                                               byte_width);
+}
+
+inline const uint8_t *Indirect(const uint8_t *offset, uint8_t byte_width) {
+  return offset - ReadUInt64(offset, byte_width);
+}
+
+template<typename T> const uint8_t *Indirect(const uint8_t *offset) {
+  return offset - flatbuffers::ReadScalar<T>(offset);
+}
+
+inline BitWidth WidthU(uint64_t u) {
+#define FLATBUFFERS_GET_FIELD_BIT_WIDTH(value, width)                   \
+  {                                                                     \
+    if (!((u) & ~((1ULL << (width)) - 1ULL))) return BIT_WIDTH_##width; \
+  }
+  FLATBUFFERS_GET_FIELD_BIT_WIDTH(u, 8);
+  FLATBUFFERS_GET_FIELD_BIT_WIDTH(u, 16);
+  FLATBUFFERS_GET_FIELD_BIT_WIDTH(u, 32);
+#undef FLATBUFFERS_GET_FIELD_BIT_WIDTH
+  return BIT_WIDTH_64;
+}
+
+inline BitWidth WidthI(int64_t i) {
+  auto u = static_cast<uint64_t>(i) << 1;
+  return WidthU(i >= 0 ? u : ~u);
+}
+
+inline BitWidth WidthF(double f) {
+  return static_cast<double>(static_cast<float>(f)) == f ? BIT_WIDTH_32
+                                                         : BIT_WIDTH_64;
+}
+
+// Base class of all types below.
+// Points into the data buffer and allows access to one type.
+class Object {
+ public:
+  Object(const uint8_t *data, uint8_t byte_width)
+      : data_(data), byte_width_(byte_width) {}
+
+ protected:
+  const uint8_t *data_;
+  uint8_t byte_width_;
+};
+
+// Stores size in `byte_width_` bytes before data_ pointer.
+class Sized : public Object {
+ public:
+  Sized(const uint8_t *data, uint8_t byte_width) : Object(data, byte_width) {}
+  size_t size() const {
+    return static_cast<size_t>(ReadUInt64(data_ - byte_width_, byte_width_));
+  }
+};
+
+class String : public Sized {
+ public:
+  String(const uint8_t *data, uint8_t byte_width) : Sized(data, byte_width) {}
+
+  size_t length() const { return size(); }
+  const char *c_str() const { return reinterpret_cast<const char *>(data_); }
+  std::string str() const { return std::string(c_str(), length()); }
+
+  static String EmptyString() {
+    static const uint8_t empty_string[] = { 0 /*len*/, 0 /*terminator*/ };
+    return String(empty_string + 1, 1);
+  }
+  bool IsTheEmptyString() const { return data_ == EmptyString().data_; }
+};
+
+class Blob : public Sized {
+ public:
+  Blob(const uint8_t *data_buf, uint8_t byte_width)
+      : Sized(data_buf, byte_width) {}
+
+  static Blob EmptyBlob() {
+    static const uint8_t empty_blob[] = { 0 /*len*/ };
+    return Blob(empty_blob + 1, 1);
+  }
+  bool IsTheEmptyBlob() const { return data_ == EmptyBlob().data_; }
+  const uint8_t *data() const { return data_; }
+};
+
+class Vector : public Sized {
+ public:
+  Vector(const uint8_t *data, uint8_t byte_width) : Sized(data, byte_width) {}
+
+  Reference operator[](size_t i) const;
+
+  static Vector EmptyVector() {
+    static const uint8_t empty_vector[] = { 0 /*len*/ };
+    return Vector(empty_vector + 1, 1);
+  }
+  bool IsTheEmptyVector() const { return data_ == EmptyVector().data_; }
+};
+
+class TypedVector : public Sized {
+ public:
+  TypedVector(const uint8_t *data, uint8_t byte_width, Type element_type)
+      : Sized(data, byte_width), type_(element_type) {}
+
+  Reference operator[](size_t i) const;
+
+  static TypedVector EmptyTypedVector() {
+    static const uint8_t empty_typed_vector[] = { 0 /*len*/ };
+    return TypedVector(empty_typed_vector + 1, 1, FBT_INT);
+  }
+  bool IsTheEmptyVector() const {
+    return data_ == TypedVector::EmptyTypedVector().data_;
+  }
+
+  Type ElementType() { return type_; }
+
+ private:
+  Type type_;
+
+  friend Map;
+};
+
+class FixedTypedVector : public Object {
+ public:
+  FixedTypedVector(const uint8_t *data, uint8_t byte_width, Type element_type,
+                   uint8_t len)
+      : Object(data, byte_width), type_(element_type), len_(len) {}
+
+  Reference operator[](size_t i) const;
+
+  static FixedTypedVector EmptyFixedTypedVector() {
+    static const uint8_t fixed_empty_vector[] = { 0 /* unused */ };
+    return FixedTypedVector(fixed_empty_vector, 1, FBT_INT, 0);
+  }
+  bool IsTheEmptyFixedTypedVector() const {
+    return data_ == FixedTypedVector::EmptyFixedTypedVector().data_;
+  }
+
+  Type ElementType() { return type_; }
+  uint8_t size() { return len_; }
+
+ private:
+  Type type_;
+  uint8_t len_;
+};
+
+class Map : public Vector {
+ public:
+  Map(const uint8_t *data, uint8_t byte_width) : Vector(data, byte_width) {}
+
+  Reference operator[](const char *key) const;
+  Reference operator[](const std::string &key) const;
+
+  Vector Values() const { return Vector(data_, byte_width_); }
+
+  TypedVector Keys() const {
+    const size_t num_prefixed_fields = 3;
+    auto keys_offset = data_ - byte_width_ * num_prefixed_fields;
+    return TypedVector(Indirect(keys_offset, byte_width_),
+                       static_cast<uint8_t>(
+                           ReadUInt64(keys_offset + byte_width_, byte_width_)),
+                       FBT_KEY);
+  }
+
+  static Map EmptyMap() {
+    static const uint8_t empty_map[] = {
+      0 /*keys_len*/, 0 /*keys_offset*/, 1 /*keys_width*/, 0 /*len*/
+    };
+    return Map(empty_map + 4, 1);
+  }
+
+  bool IsTheEmptyMap() const { return data_ == EmptyMap().data_; }
+};
+
+template<typename T>
+void AppendToString(std::string &s, T &&v, bool keys_quoted) {
+    s += "[ ";
+    for (size_t i = 0; i < v.size(); i++) {
+      if (i) s += ", ";
+      v[i].ToString(true, keys_quoted, s);
+    }
+    s += " ]";
+}
+
+class Reference {
+ public:
+  Reference(const uint8_t *data, uint8_t parent_width, uint8_t byte_width,
+            Type type)
+      : data_(data),
+        parent_width_(parent_width),
+        byte_width_(byte_width),
+        type_(type) {}
+
+  Reference(const uint8_t *data, uint8_t parent_width, uint8_t packed_type)
+      : data_(data), parent_width_(parent_width) {
+    byte_width_ = 1U << static_cast<BitWidth>(packed_type & 3);
+    type_ = static_cast<Type>(packed_type >> 2);
+  }
+
+  Type GetType() const { return type_; }
+
+  bool IsNull() const { return type_ == FBT_NULL; }
+  bool IsBool() const { return type_ == FBT_BOOL; }
+  bool IsInt() const { return type_ == FBT_INT || type_ == FBT_INDIRECT_INT; }
+  bool IsUInt() const {
+    return type_ == FBT_UINT || type_ == FBT_INDIRECT_UINT;
+  }
+  bool IsIntOrUint() const { return IsInt() || IsUInt(); }
+  bool IsFloat() const {
+    return type_ == FBT_FLOAT || type_ == FBT_INDIRECT_FLOAT;
+  }
+  bool IsNumeric() const { return IsIntOrUint() || IsFloat(); }
+  bool IsString() const { return type_ == FBT_STRING; }
+  bool IsKey() const { return type_ == FBT_KEY; }
+  bool IsVector() const { return type_ == FBT_VECTOR || type_ == FBT_MAP; }
+  bool IsTypedVector() const { return flexbuffers::IsTypedVector(type_); }
+  bool IsFixedTypedVector() const { return flexbuffers::IsFixedTypedVector(type_); }
+  bool IsAnyVector() const { return (IsTypedVector() || IsFixedTypedVector() || IsVector());}
+  bool IsMap() const { return type_ == FBT_MAP; }
+  bool IsBlob() const { return type_ == FBT_BLOB; }
+
+  bool AsBool() const {
+    return (type_ == FBT_BOOL ? ReadUInt64(data_, parent_width_)
+                               : AsUInt64()) != 0;
+  }
+
+  // Reads any type as a int64_t. Never fails, does most sensible conversion.
+  // Truncates floats, strings are attempted to be parsed for a number,
+  // vectors/maps return their size. Returns 0 if all else fails.
+  int64_t AsInt64() const {
+    if (type_ == FBT_INT) {
+      // A fast path for the common case.
+      return ReadInt64(data_, parent_width_);
+    } else
+      switch (type_) {
+        case FBT_INDIRECT_INT: return ReadInt64(Indirect(), byte_width_);
+        case FBT_UINT: return ReadUInt64(data_, parent_width_);
+        case FBT_INDIRECT_UINT: return ReadUInt64(Indirect(), byte_width_);
+        case FBT_FLOAT:
+          return static_cast<int64_t>(ReadDouble(data_, parent_width_));
+        case FBT_INDIRECT_FLOAT:
+          return static_cast<int64_t>(ReadDouble(Indirect(), byte_width_));
+        case FBT_NULL: return 0;
+        case FBT_STRING: return flatbuffers::StringToInt(AsString().c_str());
+        case FBT_VECTOR: return static_cast<int64_t>(AsVector().size());
+        case FBT_BOOL: return ReadInt64(data_, parent_width_);
+        default:
+          // Convert other things to int.
+          return 0;
+      }
+  }
+
+  // TODO: could specialize these to not use AsInt64() if that saves
+  // extension ops in generated code, and use a faster op than ReadInt64.
+  int32_t AsInt32() const { return static_cast<int32_t>(AsInt64()); }
+  int16_t AsInt16() const { return static_cast<int16_t>(AsInt64()); }
+  int8_t AsInt8() const { return static_cast<int8_t>(AsInt64()); }
+
+  uint64_t AsUInt64() const {
+    if (type_ == FBT_UINT) {
+      // A fast path for the common case.
+      return ReadUInt64(data_, parent_width_);
+    } else
+      switch (type_) {
+        case FBT_INDIRECT_UINT: return ReadUInt64(Indirect(), byte_width_);
+        case FBT_INT: return ReadInt64(data_, parent_width_);
+        case FBT_INDIRECT_INT: return ReadInt64(Indirect(), byte_width_);
+        case FBT_FLOAT:
+          return static_cast<uint64_t>(ReadDouble(data_, parent_width_));
+        case FBT_INDIRECT_FLOAT:
+          return static_cast<uint64_t>(ReadDouble(Indirect(), byte_width_));
+        case FBT_NULL: return 0;
+        case FBT_STRING: return flatbuffers::StringToUInt(AsString().c_str());
+        case FBT_VECTOR: return static_cast<uint64_t>(AsVector().size());
+        case FBT_BOOL: return ReadUInt64(data_, parent_width_);
+        default:
+          // Convert other things to uint.
+          return 0;
+      }
+  }
+
+  uint32_t AsUInt32() const { return static_cast<uint32_t>(AsUInt64()); }
+  uint16_t AsUInt16() const { return static_cast<uint16_t>(AsUInt64()); }
+  uint8_t AsUInt8() const { return static_cast<uint8_t>(AsUInt64()); }
+
+  double AsDouble() const {
+    if (type_ == FBT_FLOAT) {
+      // A fast path for the common case.
+      return ReadDouble(data_, parent_width_);
+    } else
+      switch (type_) {
+        case FBT_INDIRECT_FLOAT: return ReadDouble(Indirect(), byte_width_);
+        case FBT_INT:
+          return static_cast<double>(ReadInt64(data_, parent_width_));
+        case FBT_UINT:
+          return static_cast<double>(ReadUInt64(data_, parent_width_));
+        case FBT_INDIRECT_INT:
+          return static_cast<double>(ReadInt64(Indirect(), byte_width_));
+        case FBT_INDIRECT_UINT:
+          return static_cast<double>(ReadUInt64(Indirect(), byte_width_));
+        case FBT_NULL: return 0.0;
+        case FBT_STRING: return strtod(AsString().c_str(), nullptr);
+        case FBT_VECTOR: return static_cast<double>(AsVector().size());
+        case FBT_BOOL:
+          return static_cast<double>(ReadUInt64(data_, parent_width_));
+        default:
+          // Convert strings and other things to float.
+          return 0;
+      }
+  }
+
+  float AsFloat() const { return static_cast<float>(AsDouble()); }
+
+  const char *AsKey() const {
+    if (type_ == FBT_KEY) {
+      return reinterpret_cast<const char *>(Indirect());
+    } else {
+      return "";
+    }
+  }
+
+  // This function returns the empty string if you try to read a not-string.
+  String AsString() const {
+    if (type_ == FBT_STRING) {
+      return String(Indirect(), byte_width_);
+    } else {
+      return String::EmptyString();
+    }
+  }
+
+  // Unlike AsString(), this will convert any type to a std::string.
+  std::string ToString() const {
+    std::string s;
+    ToString(false, false, s);
+    return s;
+  }
+
+  // Convert any type to a JSON-like string. strings_quoted determines if
+  // string values at the top level receive "" quotes (inside other values
+  // they always do). keys_quoted determines if keys are quoted, at any level.
+  // TODO(wvo): add further options to have indentation/newlines.
+  void ToString(bool strings_quoted, bool keys_quoted, std::string &s) const {
+    if (type_ == FBT_STRING) {
+      String str(Indirect(), byte_width_);
+      if (strings_quoted) {
+        flatbuffers::EscapeString(str.c_str(), str.length(), &s, true, false);
+      } else {
+        s.append(str.c_str(), str.length());
+      }
+    } else if (IsKey()) {
+      auto str = AsKey();
+      if (keys_quoted) {
+        flatbuffers::EscapeString(str, strlen(str), &s, true, false);
+      } else {
+        s += str;
+      }
+    } else if (IsInt()) {
+      s += flatbuffers::NumToString(AsInt64());
+    } else if (IsUInt()) {
+      s += flatbuffers::NumToString(AsUInt64());
+    } else if (IsFloat()) {
+      s += flatbuffers::NumToString(AsDouble());
+    } else if (IsNull()) {
+      s += "null";
+    } else if (IsBool()) {
+      s += AsBool() ? "true" : "false";
+    } else if (IsMap()) {
+      s += "{ ";
+      auto m = AsMap();
+      auto keys = m.Keys();
+      auto vals = m.Values();
+      for (size_t i = 0; i < keys.size(); i++) {
+        keys[i].ToString(true, keys_quoted, s);
+        s += ": ";
+        vals[i].ToString(true, keys_quoted, s);
+        if (i < keys.size() - 1) s += ", ";
+      }
+      s += " }";
+    } else if (IsVector()) {
+      AppendToString<Vector>(s, AsVector(), keys_quoted);
+    } else if (IsTypedVector()) {
+      AppendToString<TypedVector>(s, AsTypedVector(), keys_quoted);
+    } else if (IsFixedTypedVector()) {
+      AppendToString<FixedTypedVector>(s, AsFixedTypedVector(), keys_quoted);
+    } else if (IsBlob()) {
+      auto blob = AsBlob();
+      flatbuffers::EscapeString(reinterpret_cast<const char*>(blob.data()), blob.size(), &s, true, false);
+    } else {
+      s += "(?)";
+    }
+  }
+
+  // This function returns the empty blob if you try to read a not-blob.
+  // Strings can be viewed as blobs too.
+  Blob AsBlob() const {
+    if (type_ == FBT_BLOB || type_ == FBT_STRING) {
+      return Blob(Indirect(), byte_width_);
+    } else {
+      return Blob::EmptyBlob();
+    }
+  }
+
+  // This function returns the empty vector if you try to read a not-vector.
+  // Maps can be viewed as vectors too.
+  Vector AsVector() const {
+    if (type_ == FBT_VECTOR || type_ == FBT_MAP) {
+      return Vector(Indirect(), byte_width_);
+    } else {
+      return Vector::EmptyVector();
+    }
+  }
+
+  TypedVector AsTypedVector() const {
+    if (IsTypedVector()) {
+      return TypedVector(Indirect(), byte_width_,
+                         ToTypedVectorElementType(type_));
+    } else {
+      return TypedVector::EmptyTypedVector();
+    }
+  }
+
+  FixedTypedVector AsFixedTypedVector() const {
+    if (IsFixedTypedVector()) {
+      uint8_t len = 0;
+      auto vtype = ToFixedTypedVectorElementType(type_, &len);
+      return FixedTypedVector(Indirect(), byte_width_, vtype, len);
+    } else {
+      return FixedTypedVector::EmptyFixedTypedVector();
+    }
+  }
+
+  Map AsMap() const {
+    if (type_ == FBT_MAP) {
+      return Map(Indirect(), byte_width_);
+    } else {
+      return Map::EmptyMap();
+    }
+  }
+
+  template<typename T> T As() const;
+
+  // Experimental: Mutation functions.
+  // These allow scalars in an already created buffer to be updated in-place.
+  // Since by default scalars are stored in the smallest possible space,
+  // the new value may not fit, in which case these functions return false.
+  // To avoid this, you can construct the values you intend to mutate using
+  // Builder::ForceMinimumBitWidth.
+  bool MutateInt(int64_t i) {
+    if (type_ == FBT_INT) {
+      return Mutate(data_, i, parent_width_, WidthI(i));
+    } else if (type_ == FBT_INDIRECT_INT) {
+      return Mutate(Indirect(), i, byte_width_, WidthI(i));
+    } else if (type_ == FBT_UINT) {
+      auto u = static_cast<uint64_t>(i);
+      return Mutate(data_, u, parent_width_, WidthU(u));
+    } else if (type_ == FBT_INDIRECT_UINT) {
+      auto u = static_cast<uint64_t>(i);
+      return Mutate(Indirect(), u, byte_width_, WidthU(u));
+    } else {
+      return false;
+    }
+  }
+
+  bool MutateBool(bool b) {
+    return type_ == FBT_BOOL && Mutate(data_, b, parent_width_, BIT_WIDTH_8);
+  }
+
+  bool MutateUInt(uint64_t u) {
+    if (type_ == FBT_UINT) {
+      return Mutate(data_, u, parent_width_, WidthU(u));
+    } else if (type_ == FBT_INDIRECT_UINT) {
+      return Mutate(Indirect(), u, byte_width_, WidthU(u));
+    } else if (type_ == FBT_INT) {
+      auto i = static_cast<int64_t>(u);
+      return Mutate(data_, i, parent_width_, WidthI(i));
+    } else if (type_ == FBT_INDIRECT_INT) {
+      auto i = static_cast<int64_t>(u);
+      return Mutate(Indirect(), i, byte_width_, WidthI(i));
+    } else {
+      return false;
+    }
+  }
+
+  bool MutateFloat(float f) {
+    if (type_ == FBT_FLOAT) {
+      return MutateF(data_, f, parent_width_, BIT_WIDTH_32);
+    } else if (type_ == FBT_INDIRECT_FLOAT) {
+      return MutateF(Indirect(), f, byte_width_, BIT_WIDTH_32);
+    } else {
+      return false;
+    }
+  }
+
+  bool MutateFloat(double d) {
+    if (type_ == FBT_FLOAT) {
+      return MutateF(data_, d, parent_width_, WidthF(d));
+    } else if (type_ == FBT_INDIRECT_FLOAT) {
+      return MutateF(Indirect(), d, byte_width_, WidthF(d));
+    } else {
+      return false;
+    }
+  }
+
+  bool MutateString(const char *str, size_t len) {
+    auto s = AsString();
+    if (s.IsTheEmptyString()) return false;
+    // This is very strict, could allow shorter strings, but that creates
+    // garbage.
+    if (s.length() != len) return false;
+    memcpy(const_cast<char *>(s.c_str()), str, len);
+    return true;
+  }
+  bool MutateString(const char *str) { return MutateString(str, strlen(str)); }
+  bool MutateString(const std::string &str) {
+    return MutateString(str.data(), str.length());
+  }
+
+ private:
+  const uint8_t *Indirect() const {
+    return flexbuffers::Indirect(data_, parent_width_);
+  }
+
+  template<typename T>
+  bool Mutate(const uint8_t *dest, T t, size_t byte_width,
+              BitWidth value_width) {
+    auto fits = static_cast<size_t>(static_cast<size_t>(1U) << value_width) <=
+                byte_width;
+    if (fits) {
+      t = flatbuffers::EndianScalar(t);
+      memcpy(const_cast<uint8_t *>(dest), &t, byte_width);
+    }
+    return fits;
+  }
+
+  template<typename T>
+  bool MutateF(const uint8_t *dest, T t, size_t byte_width,
+               BitWidth value_width) {
+    if (byte_width == sizeof(double))
+      return Mutate(dest, static_cast<double>(t), byte_width, value_width);
+    if (byte_width == sizeof(float))
+      return Mutate(dest, static_cast<float>(t), byte_width, value_width);
+    FLATBUFFERS_ASSERT(false);
+    return false;
+  }
+
+  const uint8_t *data_;
+  uint8_t parent_width_;
+  uint8_t byte_width_;
+  Type type_;
+};
+
+// Template specialization for As().
+template<> inline bool Reference::As<bool>() const { return AsBool(); }
+
+template<> inline int8_t Reference::As<int8_t>() const { return AsInt8(); }
+template<> inline int16_t Reference::As<int16_t>() const { return AsInt16(); }
+template<> inline int32_t Reference::As<int32_t>() const { return AsInt32(); }
+template<> inline int64_t Reference::As<int64_t>() const { return AsInt64(); }
+
+template<> inline uint8_t Reference::As<uint8_t>() const { return AsUInt8(); }
+template<> inline uint16_t Reference::As<uint16_t>() const { return AsUInt16(); }
+template<> inline uint32_t Reference::As<uint32_t>() const { return AsUInt32(); }
+template<> inline uint64_t Reference::As<uint64_t>() const { return AsUInt64(); }
+
+template<> inline double Reference::As<double>() const { return AsDouble(); }
+template<> inline float Reference::As<float>() const { return AsFloat(); }
+
+template<> inline String Reference::As<String>() const { return AsString(); }
+template<> inline std::string Reference::As<std::string>() const {
+  return AsString().str();
+}
+
+template<> inline Blob Reference::As<Blob>() const { return AsBlob(); }
+template<> inline Vector Reference::As<Vector>() const { return AsVector(); }
+template<> inline TypedVector Reference::As<TypedVector>() const {
+  return AsTypedVector();
+}
+template<> inline FixedTypedVector Reference::As<FixedTypedVector>() const {
+  return AsFixedTypedVector();
+}
+template<> inline Map Reference::As<Map>() const { return AsMap(); }
+
+inline uint8_t PackedType(BitWidth bit_width, Type type) {
+  return static_cast<uint8_t>(bit_width | (type << 2));
+}
+
+inline uint8_t NullPackedType() { return PackedType(BIT_WIDTH_8, FBT_NULL); }
+
+// Vector accessors.
+// Note: if you try to access outside of bounds, you get a Null value back
+// instead. Normally this would be an assert, but since this is "dynamically
+// typed" data, you may not want that (someone sends you a 2d vector and you
+// wanted 3d).
+// The Null converts seamlessly into a default value for any other type.
+// TODO(wvo): Could introduce an #ifdef that makes this into an assert?
+inline Reference Vector::operator[](size_t i) const {
+  auto len = size();
+  if (i >= len) return Reference(nullptr, 1, NullPackedType());
+  auto packed_type = (data_ + len * byte_width_)[i];
+  auto elem = data_ + i * byte_width_;
+  return Reference(elem, byte_width_, packed_type);
+}
+
+inline Reference TypedVector::operator[](size_t i) const {
+  auto len = size();
+  if (i >= len) return Reference(nullptr, 1, NullPackedType());
+  auto elem = data_ + i * byte_width_;
+  return Reference(elem, byte_width_, 1, type_);
+}
+
+inline Reference FixedTypedVector::operator[](size_t i) const {
+  if (i >= len_) return Reference(nullptr, 1, NullPackedType());
+  auto elem = data_ + i * byte_width_;
+  return Reference(elem, byte_width_, 1, type_);
+}
+
+template<typename T> int KeyCompare(const void *key, const void *elem) {
+  auto str_elem = reinterpret_cast<const char *>(
+      Indirect<T>(reinterpret_cast<const uint8_t *>(elem)));
+  auto skey = reinterpret_cast<const char *>(key);
+  return strcmp(skey, str_elem);
+}
+
+inline Reference Map::operator[](const char *key) const {
+  auto keys = Keys();
+  // We can't pass keys.byte_width_ to the comparison function, so we have
+  // to pick the right one ahead of time.
+  int (*comp)(const void *, const void *) = nullptr;
+  switch (keys.byte_width_) {
+    case 1: comp = KeyCompare<uint8_t>; break;
+    case 2: comp = KeyCompare<uint16_t>; break;
+    case 4: comp = KeyCompare<uint32_t>; break;
+    case 8: comp = KeyCompare<uint64_t>; break;
+  }
+  auto res = std::bsearch(key, keys.data_, keys.size(), keys.byte_width_, comp);
+  if (!res) return Reference(nullptr, 1, NullPackedType());
+  auto i = (reinterpret_cast<uint8_t *>(res) - keys.data_) / keys.byte_width_;
+  return (*static_cast<const Vector *>(this))[i];
+}
+
+inline Reference Map::operator[](const std::string &key) const {
+  return (*this)[key.c_str()];
+}
+
+inline Reference GetRoot(const uint8_t *buffer, size_t size) {
+  // See Finish() below for the serialization counterpart of this.
+  // The root starts at the end of the buffer, so we parse backwards from there.
+  auto end = buffer + size;
+  auto byte_width = *--end;
+  auto packed_type = *--end;
+  end -= byte_width;  // The root data item.
+  return Reference(end, byte_width, packed_type);
+}
+
+inline Reference GetRoot(const std::vector<uint8_t> &buffer) {
+  return GetRoot(flatbuffers::vector_data(buffer), buffer.size());
+}
+
+// Flags that configure how the Builder behaves.
+// The "Share" flags determine if the Builder automatically tries to pool
+// this type. Pooling can reduce the size of serialized data if there are
+// multiple maps of the same kind, at the expense of slightly slower
+// serialization (the cost of lookups) and more memory use (std::set).
+// By default this is on for keys, but off for strings.
+// Turn keys off if you have e.g. only one map.
+// Turn strings on if you expect many non-unique string values.
+// Additionally, sharing key vectors can save space if you have maps with
+// identical field populations.
+enum BuilderFlag {
+  BUILDER_FLAG_NONE = 0,
+  BUILDER_FLAG_SHARE_KEYS = 1,
+  BUILDER_FLAG_SHARE_STRINGS = 2,
+  BUILDER_FLAG_SHARE_KEYS_AND_STRINGS = 3,
+  BUILDER_FLAG_SHARE_KEY_VECTORS = 4,
+  BUILDER_FLAG_SHARE_ALL = 7,
+};
+
+class Builder FLATBUFFERS_FINAL_CLASS {
+ public:
+  Builder(size_t initial_size = 256,
+          BuilderFlag flags = BUILDER_FLAG_SHARE_KEYS)
+      : buf_(initial_size),
+        finished_(false),
+        flags_(flags),
+        force_min_bit_width_(BIT_WIDTH_8),
+        key_pool(KeyOffsetCompare(buf_)),
+        string_pool(StringOffsetCompare(buf_)) {
+    buf_.clear();
+  }
+
+  /// @brief Get the serialized buffer (after you call `Finish()`).
+  /// @return Returns a vector owned by this class.
+  const std::vector<uint8_t> &GetBuffer() const {
+    Finished();
+    return buf_;
+  }
+
+  // Size of the buffer. Does not include unfinished values.
+  size_t GetSize() const { return buf_.size(); }
+
+  // Reset all state so we can re-use the buffer.
+  void Clear() {
+    buf_.clear();
+    stack_.clear();
+    finished_ = false;
+    // flags_ remains as-is;
+    force_min_bit_width_ = BIT_WIDTH_8;
+    key_pool.clear();
+    string_pool.clear();
+  }
+
+  // All value constructing functions below have two versions: one that
+  // takes a key (for placement inside a map) and one that doesn't (for inside
+  // vectors and elsewhere).
+
+  void Null() { stack_.push_back(Value()); }
+  void Null(const char *key) {
+    Key(key);
+    Null();
+  }
+
+  void Int(int64_t i) { stack_.push_back(Value(i, FBT_INT, WidthI(i))); }
+  void Int(const char *key, int64_t i) {
+    Key(key);
+    Int(i);
+  }
+
+  void UInt(uint64_t u) { stack_.push_back(Value(u, FBT_UINT, WidthU(u))); }
+  void UInt(const char *key, uint64_t u) {
+    Key(key);
+    UInt(u);
+  }
+
+  void Float(float f) { stack_.push_back(Value(f)); }
+  void Float(const char *key, float f) {
+    Key(key);
+    Float(f);
+  }
+
+  void Double(double f) { stack_.push_back(Value(f)); }
+  void Double(const char *key, double d) {
+    Key(key);
+    Double(d);
+  }
+
+  void Bool(bool b) { stack_.push_back(Value(b)); }
+  void Bool(const char *key, bool b) {
+    Key(key);
+    Bool(b);
+  }
+
+  void IndirectInt(int64_t i) { PushIndirect(i, FBT_INDIRECT_INT, WidthI(i)); }
+  void IndirectInt(const char *key, int64_t i) {
+    Key(key);
+    IndirectInt(i);
+  }
+
+  void IndirectUInt(uint64_t u) {
+    PushIndirect(u, FBT_INDIRECT_UINT, WidthU(u));
+  }
+  void IndirectUInt(const char *key, uint64_t u) {
+    Key(key);
+    IndirectUInt(u);
+  }
+
+  void IndirectFloat(float f) {
+    PushIndirect(f, FBT_INDIRECT_FLOAT, BIT_WIDTH_32);
+  }
+  void IndirectFloat(const char *key, float f) {
+    Key(key);
+    IndirectFloat(f);
+  }
+
+  void IndirectDouble(double f) {
+    PushIndirect(f, FBT_INDIRECT_FLOAT, WidthF(f));
+  }
+  void IndirectDouble(const char *key, double d) {
+    Key(key);
+    IndirectDouble(d);
+  }
+
+  size_t Key(const char *str, size_t len) {
+    auto sloc = buf_.size();
+    WriteBytes(str, len + 1);
+    if (flags_ & BUILDER_FLAG_SHARE_KEYS) {
+      auto it = key_pool.find(sloc);
+      if (it != key_pool.end()) {
+        // Already in the buffer. Remove key we just serialized, and use
+        // existing offset instead.
+        buf_.resize(sloc);
+        sloc = *it;
+      } else {
+        key_pool.insert(sloc);
+      }
+    }
+    stack_.push_back(Value(static_cast<uint64_t>(sloc), FBT_KEY, BIT_WIDTH_8));
+    return sloc;
+  }
+
+  size_t Key(const char *str) { return Key(str, strlen(str)); }
+  size_t Key(const std::string &str) { return Key(str.c_str(), str.size()); }
+
+  size_t String(const char *str, size_t len) {
+    auto reset_to = buf_.size();
+    auto sloc = CreateBlob(str, len, 1, FBT_STRING);
+    if (flags_ & BUILDER_FLAG_SHARE_STRINGS) {
+      StringOffset so(sloc, len);
+      auto it = string_pool.find(so);
+      if (it != string_pool.end()) {
+        // Already in the buffer. Remove string we just serialized, and use
+        // existing offset instead.
+        buf_.resize(reset_to);
+        sloc = it->first;
+        stack_.back().u_ = sloc;
+      } else {
+        string_pool.insert(so);
+      }
+    }
+    return sloc;
+  }
+  size_t String(const char *str) { return String(str, strlen(str)); }
+  size_t String(const std::string &str) {
+    return String(str.c_str(), str.size());
+  }
+  void String(const flexbuffers::String &str) {
+    String(str.c_str(), str.length());
+  }
+
+  void String(const char *key, const char *str) {
+    Key(key);
+    String(str);
+  }
+  void String(const char *key, const std::string &str) {
+    Key(key);
+    String(str);
+  }
+  void String(const char *key, const flexbuffers::String &str) {
+    Key(key);
+    String(str);
+  }
+
+  size_t Blob(const void *data, size_t len) {
+    return CreateBlob(data, len, 0, FBT_BLOB);
+  }
+  size_t Blob(const std::vector<uint8_t> &v) {
+    return CreateBlob(flatbuffers::vector_data(v), v.size(), 0, FBT_BLOB);
+  }
+
+  // TODO(wvo): support all the FlexBuffer types (like flexbuffers::String),
+  // e.g. Vector etc. Also in overloaded versions.
+  // Also some FlatBuffers types?
+
+  size_t StartVector() { return stack_.size(); }
+  size_t StartVector(const char *key) {
+    Key(key);
+    return stack_.size();
+  }
+  size_t StartMap() { return stack_.size(); }
+  size_t StartMap(const char *key) {
+    Key(key);
+    return stack_.size();
+  }
+
+  // TODO(wvo): allow this to specify an aligment greater than the natural
+  // alignment.
+  size_t EndVector(size_t start, bool typed, bool fixed) {
+    auto vec = CreateVector(start, stack_.size() - start, 1, typed, fixed);
+    // Remove temp elements and return vector.
+    stack_.resize(start);
+    stack_.push_back(vec);
+    return static_cast<size_t>(vec.u_);
+  }
+
+  size_t EndMap(size_t start) {
+    // We should have interleaved keys and values on the stack.
+    // Make sure it is an even number:
+    auto len = stack_.size() - start;
+    FLATBUFFERS_ASSERT(!(len & 1));
+    len /= 2;
+    // Make sure keys are all strings:
+    for (auto key = start; key < stack_.size(); key += 2) {
+      FLATBUFFERS_ASSERT(stack_[key].type_ == FBT_KEY);
+    }
+    // Now sort values, so later we can do a binary seach lookup.
+    // We want to sort 2 array elements at a time.
+    struct TwoValue {
+      Value key;
+      Value val;
+    };
+    // TODO(wvo): strict aliasing?
+    // TODO(wvo): allow the caller to indicate the data is already sorted
+    // for maximum efficiency? With an assert to check sortedness to make sure
+    // we're not breaking binary search.
+    // Or, we can track if the map is sorted as keys are added which would be
+    // be quite cheap (cheaper than checking it here), so we can skip this
+    // step automatically when appliccable, and encourage people to write in
+    // sorted fashion.
+    // std::sort is typically already a lot faster on sorted data though.
+    auto dict =
+        reinterpret_cast<TwoValue *>(flatbuffers::vector_data(stack_) + start);
+    std::sort(dict, dict + len,
+              [&](const TwoValue &a, const TwoValue &b) -> bool {
+                auto as = reinterpret_cast<const char *>(
+                    flatbuffers::vector_data(buf_) + a.key.u_);
+                auto bs = reinterpret_cast<const char *>(
+                    flatbuffers::vector_data(buf_) + b.key.u_);
+                auto comp = strcmp(as, bs);
+                // If this assertion hits, you've added two keys with the same
+                // value to this map.
+                // TODO: Have to check for pointer equality, as some sort
+                // implementation apparently call this function with the same
+                // element?? Why?
+                FLATBUFFERS_ASSERT(comp || &a == &b);
+                return comp < 0;
+              });
+    // First create a vector out of all keys.
+    // TODO(wvo): if kBuilderFlagShareKeyVectors is true, see if we can share
+    // the first vector.
+    auto keys = CreateVector(start, len, 2, true, false);
+    auto vec = CreateVector(start + 1, len, 2, false, false, &keys);
+    // Remove temp elements and return map.
+    stack_.resize(start);
+    stack_.push_back(vec);
+    return static_cast<size_t>(vec.u_);
+  }
+
+  template<typename F> size_t Vector(F f) {
+    auto start = StartVector();
+    f();
+    return EndVector(start, false, false);
+  }
+  template<typename F, typename T> size_t Vector(F f, T &state) {
+    auto start = StartVector();
+    f(state);
+    return EndVector(start, false, false);
+  }
+  template<typename F> size_t Vector(const char *key, F f) {
+    auto start = StartVector(key);
+    f();
+    return EndVector(start, false, false);
+  }
+  template<typename F, typename T>
+  size_t Vector(const char *key, F f, T &state) {
+    auto start = StartVector(key);
+    f(state);
+    return EndVector(start, false, false);
+  }
+
+  template<typename T> void Vector(const T *elems, size_t len) {
+    if (flatbuffers::is_scalar<T>::value) {
+      // This path should be a lot quicker and use less space.
+      ScalarVector(elems, len, false);
+    } else {
+      auto start = StartVector();
+      for (size_t i = 0; i < len; i++) Add(elems[i]);
+      EndVector(start, false, false);
+    }
+  }
+  template<typename T>
+  void Vector(const char *key, const T *elems, size_t len) {
+    Key(key);
+    Vector(elems, len);
+  }
+  template<typename T> void Vector(const std::vector<T> &vec) {
+    Vector(flatbuffers::vector_data(vec), vec.size());
+  }
+
+  template<typename F> size_t TypedVector(F f) {
+    auto start = StartVector();
+    f();
+    return EndVector(start, true, false);
+  }
+  template<typename F, typename T> size_t TypedVector(F f, T &state) {
+    auto start = StartVector();
+    f(state);
+    return EndVector(start, true, false);
+  }
+  template<typename F> size_t TypedVector(const char *key, F f) {
+    auto start = StartVector(key);
+    f();
+    return EndVector(start, true, false);
+  }
+  template<typename F, typename T>
+  size_t TypedVector(const char *key, F f, T &state) {
+    auto start = StartVector(key);
+    f(state);
+    return EndVector(start, true, false);
+  }
+
+  template<typename T> size_t FixedTypedVector(const T *elems, size_t len) {
+    // We only support a few fixed vector lengths. Anything bigger use a
+    // regular typed vector.
+    FLATBUFFERS_ASSERT(len >= 2 && len <= 4);
+    // And only scalar values.
+    static_assert(flatbuffers::is_scalar<T>::value, "Unrelated types");
+    return ScalarVector(elems, len, true);
+  }
+
+  template<typename T>
+  size_t FixedTypedVector(const char *key, const T *elems, size_t len) {
+    Key(key);
+    return FixedTypedVector(elems, len);
+  }
+
+  template<typename F> size_t Map(F f) {
+    auto start = StartMap();
+    f();
+    return EndMap(start);
+  }
+  template<typename F, typename T> size_t Map(F f, T &state) {
+    auto start = StartMap();
+    f(state);
+    return EndMap(start);
+  }
+  template<typename F> size_t Map(const char *key, F f) {
+    auto start = StartMap(key);
+    f();
+    return EndMap(start);
+  }
+  template<typename F, typename T> size_t Map(const char *key, F f, T &state) {
+    auto start = StartMap(key);
+    f(state);
+    return EndMap(start);
+  }
+  template<typename T> void Map(const std::map<std::string, T> &map) {
+    auto start = StartMap();
+    for (auto it = map.begin(); it != map.end(); ++it)
+      Add(it->first.c_str(), it->second);
+    EndMap(start);
+  }
+
+  // Overloaded Add that tries to call the correct function above.
+  void Add(int8_t i) { Int(i); }
+  void Add(int16_t i) { Int(i); }
+  void Add(int32_t i) { Int(i); }
+  void Add(int64_t i) { Int(i); }
+  void Add(uint8_t u) { UInt(u); }
+  void Add(uint16_t u) { UInt(u); }
+  void Add(uint32_t u) { UInt(u); }
+  void Add(uint64_t u) { UInt(u); }
+  void Add(float f) { Float(f); }
+  void Add(double d) { Double(d); }
+  void Add(bool b) { Bool(b); }
+  void Add(const char *str) { String(str); }
+  void Add(const std::string &str) { String(str); }
+  void Add(const flexbuffers::String &str) { String(str); }
+
+  template<typename T> void Add(const std::vector<T> &vec) { Vector(vec); }
+
+  template<typename T> void Add(const char *key, const T &t) {
+    Key(key);
+    Add(t);
+  }
+
+  template<typename T> void Add(const std::map<std::string, T> &map) {
+    Map(map);
+  }
+
+  template<typename T> void operator+=(const T &t) { Add(t); }
+
+  // This function is useful in combination with the Mutate* functions above.
+  // It forces elements of vectors and maps to have a minimum size, such that
+  // they can later be updated without failing.
+  // Call with no arguments to reset.
+  void ForceMinimumBitWidth(BitWidth bw = BIT_WIDTH_8) {
+    force_min_bit_width_ = bw;
+  }
+
+  void Finish() {
+    // If you hit this assert, you likely have objects that were never included
+    // in a parent. You need to have exactly one root to finish a buffer.
+    // Check your Start/End calls are matched, and all objects are inside
+    // some other object.
+    FLATBUFFERS_ASSERT(stack_.size() == 1);
+
+    // Write root value.
+    auto byte_width = Align(stack_[0].ElemWidth(buf_.size(), 0));
+    WriteAny(stack_[0], byte_width);
+    // Write root type.
+    Write(stack_[0].StoredPackedType(), 1);
+    // Write root size. Normally determined by parent, but root has no parent :)
+    Write(byte_width, 1);
+
+    finished_ = true;
+  }
+
+ private:
+  void Finished() const {
+    // If you get this assert, you're attempting to get access a buffer
+    // which hasn't been finished yet. Be sure to call
+    // Builder::Finish with your root object.
+    FLATBUFFERS_ASSERT(finished_);
+  }
+
+  // Align to prepare for writing a scalar with a certain size.
+  uint8_t Align(BitWidth alignment) {
+    auto byte_width = 1U << alignment;
+    buf_.insert(buf_.end(), flatbuffers::PaddingBytes(buf_.size(), byte_width),
+                0);
+    return static_cast<uint8_t>(byte_width);
+  }
+
+  void WriteBytes(const void *val, size_t size) {
+    buf_.insert(buf_.end(), reinterpret_cast<const uint8_t *>(val),
+                reinterpret_cast<const uint8_t *>(val) + size);
+  }
+
+  template<typename T> void Write(T val, size_t byte_width) {
+    FLATBUFFERS_ASSERT(sizeof(T) >= byte_width);
+    val = flatbuffers::EndianScalar(val);
+    WriteBytes(&val, byte_width);
+  }
+
+  void WriteDouble(double f, uint8_t byte_width) {
+    switch (byte_width) {
+      case 8: Write(f, byte_width); break;
+      case 4: Write(static_cast<float>(f), byte_width); break;
+      // case 2: Write(static_cast<half>(f), byte_width); break;
+      // case 1: Write(static_cast<quarter>(f), byte_width); break;
+      default: FLATBUFFERS_ASSERT(0);
+    }
+  }
+
+  void WriteOffset(uint64_t o, uint8_t byte_width) {
+    auto reloff = buf_.size() - o;
+    FLATBUFFERS_ASSERT(byte_width == 8 || reloff < 1ULL << (byte_width * 8));
+    Write(reloff, byte_width);
+  }
+
+  template<typename T> void PushIndirect(T val, Type type, BitWidth bit_width) {
+    auto byte_width = Align(bit_width);
+    auto iloc = buf_.size();
+    Write(val, byte_width);
+    stack_.push_back(Value(static_cast<uint64_t>(iloc), type, bit_width));
+  }
+
+  static BitWidth WidthB(size_t byte_width) {
+    switch (byte_width) {
+      case 1: return BIT_WIDTH_8;
+      case 2: return BIT_WIDTH_16;
+      case 4: return BIT_WIDTH_32;
+      case 8: return BIT_WIDTH_64;
+      default: FLATBUFFERS_ASSERT(false); return BIT_WIDTH_64;
+    }
+  }
+
+  template<typename T> static Type GetScalarType() {
+    static_assert(flatbuffers::is_scalar<T>::value, "Unrelated types");
+    return flatbuffers::is_floating_point<T>::value
+               ? FBT_FLOAT
+               : flatbuffers::is_same<T, bool>::value
+                     ? FBT_BOOL
+                     : (flatbuffers::is_unsigned<T>::value ? FBT_UINT
+                                                           : FBT_INT);
+  }
+
+  struct Value {
+    union {
+      int64_t i_;
+      uint64_t u_;
+      double f_;
+    };
+
+    Type type_;
+
+    // For scalars: of itself, for vector: of its elements, for string: length.
+    BitWidth min_bit_width_;
+
+    Value() : i_(0), type_(FBT_NULL), min_bit_width_(BIT_WIDTH_8) {}
+
+    Value(bool b)
+        : u_(static_cast<uint64_t>(b)),
+          type_(FBT_BOOL),
+          min_bit_width_(BIT_WIDTH_8) {}
+
+    Value(int64_t i, Type t, BitWidth bw)
+        : i_(i), type_(t), min_bit_width_(bw) {}
+    Value(uint64_t u, Type t, BitWidth bw)
+        : u_(u), type_(t), min_bit_width_(bw) {}
+
+    Value(float f) : f_(f), type_(FBT_FLOAT), min_bit_width_(BIT_WIDTH_32) {}
+    Value(double f) : f_(f), type_(FBT_FLOAT), min_bit_width_(WidthF(f)) {}
+
+    uint8_t StoredPackedType(BitWidth parent_bit_width_ = BIT_WIDTH_8) const {
+      return PackedType(StoredWidth(parent_bit_width_), type_);
+    }
+
+    BitWidth ElemWidth(size_t buf_size, size_t elem_index) const {
+      if (IsInline(type_)) {
+        return min_bit_width_;
+      } else {
+        // We have an absolute offset, but want to store a relative offset
+        // elem_index elements beyond the current buffer end. Since whether
+        // the relative offset fits in a certain byte_width depends on
+        // the size of the elements before it (and their alignment), we have
+        // to test for each size in turn.
+        for (size_t byte_width = 1;
+             byte_width <= sizeof(flatbuffers::largest_scalar_t);
+             byte_width *= 2) {
+          // Where are we going to write this offset?
+          auto offset_loc = buf_size +
+                            flatbuffers::PaddingBytes(buf_size, byte_width) +
+                            elem_index * byte_width;
+          // Compute relative offset.
+          auto offset = offset_loc - u_;
+          // Does it fit?
+          auto bit_width = WidthU(offset);
+          if (static_cast<size_t>(static_cast<size_t>(1U) << bit_width) ==
+              byte_width)
+            return bit_width;
+        }
+        FLATBUFFERS_ASSERT(false);  // Must match one of the sizes above.
+        return BIT_WIDTH_64;
+      }
+    }
+
+    BitWidth StoredWidth(BitWidth parent_bit_width_ = BIT_WIDTH_8) const {
+      if (IsInline(type_)) {
+        return (std::max)(min_bit_width_, parent_bit_width_);
+      } else {
+        return min_bit_width_;
+      }
+    }
+  };
+
+  void WriteAny(const Value &val, uint8_t byte_width) {
+    switch (val.type_) {
+      case FBT_NULL:
+      case FBT_INT: Write(val.i_, byte_width); break;
+      case FBT_BOOL:
+      case FBT_UINT: Write(val.u_, byte_width); break;
+      case FBT_FLOAT: WriteDouble(val.f_, byte_width); break;
+      default: WriteOffset(val.u_, byte_width); break;
+    }
+  }
+
+  size_t CreateBlob(const void *data, size_t len, size_t trailing, Type type) {
+    auto bit_width = WidthU(len);
+    auto byte_width = Align(bit_width);
+    Write<uint64_t>(len, byte_width);
+    auto sloc = buf_.size();
+    WriteBytes(data, len + trailing);
+    stack_.push_back(Value(static_cast<uint64_t>(sloc), type, bit_width));
+    return sloc;
+  }
+
+  template<typename T>
+  size_t ScalarVector(const T *elems, size_t len, bool fixed) {
+    auto vector_type = GetScalarType<T>();
+    auto byte_width = sizeof(T);
+    auto bit_width = WidthB(byte_width);
+    // If you get this assert, you're trying to write a vector with a size
+    // field that is bigger than the scalars you're trying to write (e.g. a
+    // byte vector > 255 elements). For such types, write a "blob" instead.
+    // TODO: instead of asserting, could write vector with larger elements
+    // instead, though that would be wasteful.
+    FLATBUFFERS_ASSERT(WidthU(len) <= bit_width);
+    if (!fixed) Write<uint64_t>(len, byte_width);
+    auto vloc = buf_.size();
+    for (size_t i = 0; i < len; i++) Write(elems[i], byte_width);
+    stack_.push_back(Value(static_cast<uint64_t>(vloc),
+                           ToTypedVector(vector_type, fixed ? len : 0),
+                           bit_width));
+    return vloc;
+  }
+
+  Value CreateVector(size_t start, size_t vec_len, size_t step, bool typed,
+                     bool fixed, const Value *keys = nullptr) {
+    FLATBUFFERS_ASSERT(!fixed || typed); // typed=false, fixed=true combination is not supported.
+    // Figure out smallest bit width we can store this vector with.
+    auto bit_width = (std::max)(force_min_bit_width_, WidthU(vec_len));
+    auto prefix_elems = 1;
+    if (keys) {
+      // If this vector is part of a map, we will pre-fix an offset to the keys
+      // to this vector.
+      bit_width = (std::max)(bit_width, keys->ElemWidth(buf_.size(), 0));
+      prefix_elems += 2;
+    }
+    Type vector_type = FBT_KEY;
+    // Check bit widths and types for all elements.
+    for (size_t i = start; i < stack_.size(); i += step) {
+      auto elem_width = stack_[i].ElemWidth(buf_.size(), i + prefix_elems);
+      bit_width = (std::max)(bit_width, elem_width);
+      if (typed) {
+        if (i == start) {
+          vector_type = stack_[i].type_;
+        } else {
+          // If you get this assert, you are writing a typed vector with
+          // elements that are not all the same type.
+          FLATBUFFERS_ASSERT(vector_type == stack_[i].type_);
+        }
+      }
+    }
+    // If you get this assert, your fixed types are not one of:
+    // Int / UInt / Float / Key.
+    FLATBUFFERS_ASSERT(!fixed || IsTypedVectorElementType(vector_type));
+    auto byte_width = Align(bit_width);
+    // Write vector. First the keys width/offset if available, and size.
+    if (keys) {
+      WriteOffset(keys->u_, byte_width);
+      Write<uint64_t>(1ULL << keys->min_bit_width_, byte_width);
+    }
+    if (!fixed) Write<uint64_t>(vec_len, byte_width);
+    // Then the actual data.
+    auto vloc = buf_.size();
+    for (size_t i = start; i < stack_.size(); i += step) {
+      WriteAny(stack_[i], byte_width);
+    }
+    // Then the types.
+    if (!typed) {
+      for (size_t i = start; i < stack_.size(); i += step) {
+        buf_.push_back(stack_[i].StoredPackedType(bit_width));
+      }
+    }
+    return Value(static_cast<uint64_t>(vloc),
+                 keys ? FBT_MAP
+                      : (typed ? ToTypedVector(vector_type, fixed ? vec_len : 0)
+                               : FBT_VECTOR),
+                 bit_width);
+  }
+
+  // You shouldn't really be copying instances of this class.
+  Builder(const Builder &);
+  Builder &operator=(const Builder &);
+
+  std::vector<uint8_t> buf_;
+  std::vector<Value> stack_;
+
+  bool finished_;
+
+  BuilderFlag flags_;
+
+  BitWidth force_min_bit_width_;
+
+  struct KeyOffsetCompare {
+    explicit KeyOffsetCompare(const std::vector<uint8_t> &buf) : buf_(&buf) {}
+    bool operator()(size_t a, size_t b) const {
+      auto stra =
+          reinterpret_cast<const char *>(flatbuffers::vector_data(*buf_) + a);
+      auto strb =
+          reinterpret_cast<const char *>(flatbuffers::vector_data(*buf_) + b);
+      return strcmp(stra, strb) < 0;
+    }
+    const std::vector<uint8_t> *buf_;
+  };
+
+  typedef std::pair<size_t, size_t> StringOffset;
+  struct StringOffsetCompare {
+    explicit StringOffsetCompare(const std::vector<uint8_t> &buf) : buf_(&buf) {}
+    bool operator()(const StringOffset &a, const StringOffset &b) const {
+      auto stra = reinterpret_cast<const char *>(
+          flatbuffers::vector_data(*buf_) + a.first);
+      auto strb = reinterpret_cast<const char *>(
+          flatbuffers::vector_data(*buf_) + b.first);
+      return strncmp(stra, strb, (std::min)(a.second, b.second) + 1) < 0;
+    }
+    const std::vector<uint8_t> *buf_;
+  };
+
+  typedef std::set<size_t, KeyOffsetCompare> KeyOffsetMap;
+  typedef std::set<StringOffset, StringOffsetCompare> StringOffsetMap;
+
+  KeyOffsetMap key_pool;
+  StringOffsetMap string_pool;
+};
+
+}  // namespace flexbuffers
+
+#  if defined(_MSC_VER)
+#    pragma warning(pop)
+#  endif
+
+#endif  // FLATBUFFERS_FLEXBUFFERS_H_
diff --git a/third_party/flatbuffers/include/flatbuffers/grpc.h b/third_party/flatbuffers/include/flatbuffers/grpc.h
new file mode 100644
index 0000000..a75b67c
--- /dev/null
+++ b/third_party/flatbuffers/include/flatbuffers/grpc.h
@@ -0,0 +1,328 @@
+/*
+ * 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.
+ */
+
+#ifndef FLATBUFFERS_GRPC_H_
+#define FLATBUFFERS_GRPC_H_
+
+// Helper functionality to glue FlatBuffers and GRPC.
+
+#include "flatbuffers/flatbuffers.h"
+#include "grpc++/support/byte_buffer.h"
+#include "grpc/byte_buffer_reader.h"
+
+namespace flatbuffers {
+namespace grpc {
+
+// Message is a typed wrapper around a buffer that manages the underlying
+// `grpc_slice` and also provides flatbuffers-specific helpers such as `Verify`
+// and `GetRoot`. Since it is backed by a `grpc_slice`, the underlying buffer
+// is refcounted and ownership is be managed automatically.
+template<class T> class Message {
+ public:
+  Message() : slice_(grpc_empty_slice()) {}
+
+  Message(grpc_slice slice, bool add_ref)
+      : slice_(add_ref ? grpc_slice_ref(slice) : slice) {}
+
+  Message &operator=(const Message &other) = delete;
+
+  Message(Message &&other) : slice_(other.slice_) {
+    other.slice_ = grpc_empty_slice();
+  }
+
+  Message(const Message &other) = delete;
+
+  Message &operator=(Message &&other) {
+    grpc_slice_unref(slice_);
+    slice_ = other.slice_;
+    other.slice_ = grpc_empty_slice();
+    return *this;
+  }
+
+  ~Message() { grpc_slice_unref(slice_); }
+
+  const uint8_t *mutable_data() const { return GRPC_SLICE_START_PTR(slice_); }
+
+  const uint8_t *data() const { return GRPC_SLICE_START_PTR(slice_); }
+
+  size_t size() const { return GRPC_SLICE_LENGTH(slice_); }
+
+  bool Verify() const {
+    Verifier verifier(data(), size());
+    return verifier.VerifyBuffer<T>(nullptr);
+  }
+
+  T *GetMutableRoot() { return flatbuffers::GetMutableRoot<T>(mutable_data()); }
+
+  const T *GetRoot() const { return flatbuffers::GetRoot<T>(data()); }
+
+  // This is only intended for serializer use, or if you know what you're doing
+  const grpc_slice &BorrowSlice() const { return slice_; }
+
+ private:
+  grpc_slice slice_;
+};
+
+class MessageBuilder;
+
+// SliceAllocator is a gRPC-specific allocator that uses the `grpc_slice`
+// refcounted slices to manage memory ownership. This makes it easy and
+// efficient to transfer buffers to gRPC.
+class SliceAllocator : public Allocator {
+ public:
+  SliceAllocator() : slice_(grpc_empty_slice()) {}
+
+  SliceAllocator(const SliceAllocator &other) = delete;
+  SliceAllocator &operator=(const SliceAllocator &other) = delete;
+
+  SliceAllocator(SliceAllocator &&other)
+    : slice_(grpc_empty_slice()) {
+    // default-construct and swap idiom
+    swap(other);
+  }
+
+  SliceAllocator &operator=(SliceAllocator &&other) {
+    // move-construct and swap idiom
+    SliceAllocator temp(std::move(other));
+    swap(temp);
+    return *this;
+  }
+
+  void swap(SliceAllocator &other) {
+    using std::swap;
+    swap(slice_, other.slice_);
+  }
+
+  virtual ~SliceAllocator() { grpc_slice_unref(slice_); }
+
+  virtual uint8_t *allocate(size_t size) override {
+    FLATBUFFERS_ASSERT(GRPC_SLICE_IS_EMPTY(slice_));
+    slice_ = grpc_slice_malloc(size);
+    return GRPC_SLICE_START_PTR(slice_);
+  }
+
+  virtual void deallocate(uint8_t *p, size_t size) override {
+    FLATBUFFERS_ASSERT(p == GRPC_SLICE_START_PTR(slice_));
+    FLATBUFFERS_ASSERT(size == GRPC_SLICE_LENGTH(slice_));
+    grpc_slice_unref(slice_);
+    slice_ = grpc_empty_slice();
+  }
+
+  virtual uint8_t *reallocate_downward(uint8_t *old_p, size_t old_size,
+                                       size_t new_size, size_t in_use_back,
+                                       size_t in_use_front) override {
+    FLATBUFFERS_ASSERT(old_p == GRPC_SLICE_START_PTR(slice_));
+    FLATBUFFERS_ASSERT(old_size == GRPC_SLICE_LENGTH(slice_));
+    FLATBUFFERS_ASSERT(new_size > old_size);
+    grpc_slice old_slice = slice_;
+    grpc_slice new_slice = grpc_slice_malloc(new_size);
+    uint8_t *new_p = GRPC_SLICE_START_PTR(new_slice);
+    memcpy_downward(old_p, old_size, new_p, new_size, in_use_back,
+                    in_use_front);
+    slice_ = new_slice;
+    grpc_slice_unref(old_slice);
+    return new_p;
+  }
+
+ private:
+  grpc_slice &get_slice(uint8_t *p, size_t size) {
+    FLATBUFFERS_ASSERT(p == GRPC_SLICE_START_PTR(slice_));
+    FLATBUFFERS_ASSERT(size == GRPC_SLICE_LENGTH(slice_));
+    return slice_;
+  }
+
+  grpc_slice slice_;
+
+  friend class MessageBuilder;
+};
+
+// SliceAllocatorMember is a hack to ensure that the MessageBuilder's
+// slice_allocator_ member is constructed before the FlatBufferBuilder, since
+// the allocator is used in the FlatBufferBuilder ctor.
+namespace detail {
+struct SliceAllocatorMember {
+  SliceAllocator slice_allocator_;
+};
+}  // namespace detail
+
+// MessageBuilder is a gRPC-specific FlatBufferBuilder that uses SliceAllocator
+// to allocate gRPC buffers.
+class MessageBuilder : private detail::SliceAllocatorMember,
+                       public FlatBufferBuilder {
+ public:
+  explicit MessageBuilder(uoffset_t initial_size = 1024)
+    : FlatBufferBuilder(initial_size, &slice_allocator_, false) {}
+
+  MessageBuilder(const MessageBuilder &other) = delete;
+  MessageBuilder &operator=(const MessageBuilder &other) = delete;
+
+  MessageBuilder(MessageBuilder &&other)
+    : FlatBufferBuilder(1024, &slice_allocator_, false) {
+    // Default construct and swap idiom.
+    Swap(other);
+  }
+
+  /// Create a MessageBuilder from a FlatBufferBuilder.
+  explicit MessageBuilder(FlatBufferBuilder &&src, void (*dealloc)(void*, size_t) = &DefaultAllocator::dealloc)
+    : FlatBufferBuilder(1024, &slice_allocator_, false) {
+    src.Swap(*this);
+    src.SwapBufAllocator(*this);
+    if (buf_.capacity()) {
+      uint8_t *buf = buf_.scratch_data();       // pointer to memory
+      size_t capacity = buf_.capacity();        // size of memory
+      slice_allocator_.slice_ = grpc_slice_new_with_len(buf, capacity, dealloc);
+    }
+    else {
+      slice_allocator_.slice_ = grpc_empty_slice();
+    }
+  }
+
+  /// Move-assign a FlatBufferBuilder to a MessageBuilder.
+  /// Only FlatBufferBuilder with default allocator (basically, nullptr) is supported.
+  MessageBuilder &operator=(FlatBufferBuilder &&src) {
+    // Move construct a temporary and swap
+    MessageBuilder temp(std::move(src));
+    Swap(temp);
+    return *this;
+  }
+
+  MessageBuilder &operator=(MessageBuilder &&other) {
+    // Move construct a temporary and swap
+    MessageBuilder temp(std::move(other));
+    Swap(temp);
+    return *this;
+  }
+
+  void Swap(MessageBuilder &other) {
+    slice_allocator_.swap(other.slice_allocator_);
+    FlatBufferBuilder::Swap(other);
+    // After swapping the FlatBufferBuilder, we swap back the allocator, which restores
+    // the original allocator back in place. This is necessary because MessageBuilder's
+    // allocator is its own member (SliceAllocatorMember). The allocator passed to
+    // FlatBufferBuilder::vector_downward must point to this member.
+    buf_.swap_allocator(other.buf_);
+  }
+
+  // Releases the ownership of the buffer pointer.
+  // Returns the size, offset, and the original grpc_slice that
+  // allocated the buffer. Also see grpc_slice_unref().
+  uint8_t *ReleaseRaw(size_t &size, size_t &offset, grpc_slice &slice) {
+    uint8_t *buf = FlatBufferBuilder::ReleaseRaw(size, offset);
+    slice = slice_allocator_.slice_;
+    slice_allocator_.slice_ = grpc_empty_slice();
+    return buf;
+  }
+
+  ~MessageBuilder() {}
+
+  // GetMessage extracts the subslice of the buffer corresponding to the
+  // flatbuffers-encoded region and wraps it in a `Message<T>` to handle buffer
+  // ownership.
+  template<class T> Message<T> GetMessage() {
+    auto buf_data = buf_.scratch_data();       // pointer to memory
+    auto buf_size = buf_.capacity();  // size of memory
+    auto msg_data = buf_.data();      // pointer to msg
+    auto msg_size = buf_.size();      // size of msg
+    // Do some sanity checks on data/size
+    FLATBUFFERS_ASSERT(msg_data);
+    FLATBUFFERS_ASSERT(msg_size);
+    FLATBUFFERS_ASSERT(msg_data >= buf_data);
+    FLATBUFFERS_ASSERT(msg_data + msg_size <= buf_data + buf_size);
+    // Calculate offsets from the buffer start
+    auto begin = msg_data - buf_data;
+    auto end = begin + msg_size;
+    // Get the slice we are working with (no refcount change)
+    grpc_slice slice = slice_allocator_.get_slice(buf_data, buf_size);
+    // Extract a subslice of the existing slice (increment refcount)
+    grpc_slice subslice = grpc_slice_sub(slice, begin, end);
+    // Wrap the subslice in a `Message<T>`, but don't increment refcount
+    Message<T> msg(subslice, false);
+    return msg;
+  }
+
+  template<class T> Message<T> ReleaseMessage() {
+    Message<T> msg = GetMessage<T>();
+    Reset();
+    return msg;
+  }
+
+ private:
+  // SliceAllocator slice_allocator_;  // part of SliceAllocatorMember
+};
+
+}  // namespace grpc
+}  // namespace flatbuffers
+
+namespace grpc {
+
+template<class T> class SerializationTraits<flatbuffers::grpc::Message<T>> {
+ public:
+  static grpc::Status Serialize(const flatbuffers::grpc::Message<T> &msg,
+                                grpc_byte_buffer **buffer, bool *own_buffer) {
+    // We are passed in a `Message<T>`, which is a wrapper around a
+    // `grpc_slice`. We extract it here using `BorrowSlice()`. The const cast
+    // is necesary because the `grpc_raw_byte_buffer_create` func expects
+    // non-const slices in order to increment their refcounts.
+    grpc_slice *slice = const_cast<grpc_slice *>(&msg.BorrowSlice());
+    // Now use `grpc_raw_byte_buffer_create` to package the single slice into a
+    // `grpc_byte_buffer`, incrementing the refcount in the process.
+    *buffer = grpc_raw_byte_buffer_create(slice, 1);
+    *own_buffer = true;
+    return grpc::Status::OK;
+  }
+
+  // Deserialize by pulling the
+  static grpc::Status Deserialize(grpc_byte_buffer *buffer,
+                                  flatbuffers::grpc::Message<T> *msg) {
+    if (!buffer) {
+      return ::grpc::Status(::grpc::StatusCode::INTERNAL, "No payload");
+    }
+    // Check if this is a single uncompressed slice.
+    if ((buffer->type == GRPC_BB_RAW) &&
+        (buffer->data.raw.compression == GRPC_COMPRESS_NONE) &&
+        (buffer->data.raw.slice_buffer.count == 1)) {
+      // If it is, then we can reference the `grpc_slice` directly.
+      grpc_slice slice = buffer->data.raw.slice_buffer.slices[0];
+      // We wrap a `Message<T>` around the slice, incrementing the refcount.
+      *msg = flatbuffers::grpc::Message<T>(slice, true);
+    } else {
+      // Otherwise, we need to use `grpc_byte_buffer_reader_readall` to read
+      // `buffer` into a single contiguous `grpc_slice`. The gRPC reader gives
+      // us back a new slice with the refcount already incremented.
+      grpc_byte_buffer_reader reader;
+      grpc_byte_buffer_reader_init(&reader, buffer);
+      grpc_slice slice = grpc_byte_buffer_reader_readall(&reader);
+      grpc_byte_buffer_reader_destroy(&reader);
+      // We wrap a `Message<T>` around the slice, but dont increment refcount
+      *msg = flatbuffers::grpc::Message<T>(slice, false);
+    }
+    grpc_byte_buffer_destroy(buffer);
+#if FLATBUFFERS_GRPC_DISABLE_AUTO_VERIFICATION
+    return ::grpc::Status::OK;
+#else
+    if (msg->Verify()) {
+      return ::grpc::Status::OK;
+    } else {
+      return ::grpc::Status(::grpc::StatusCode::INTERNAL,
+                            "Message verification failed");
+    }
+#endif
+  }
+};
+
+}  // namespace grpc
+
+#endif  // FLATBUFFERS_GRPC_H_
diff --git a/third_party/flatbuffers/include/flatbuffers/hash.h b/third_party/flatbuffers/include/flatbuffers/hash.h
new file mode 100644
index 0000000..16536cb
--- /dev/null
+++ b/third_party/flatbuffers/include/flatbuffers/hash.h
@@ -0,0 +1,127 @@
+/*
+ * 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.
+ */
+
+#ifndef FLATBUFFERS_HASH_H_
+#define FLATBUFFERS_HASH_H_
+
+#include <cstdint>
+#include <cstring>
+
+#include "flatbuffers/flatbuffers.h"
+
+namespace flatbuffers {
+
+template<typename T> struct FnvTraits {
+  static const T kFnvPrime;
+  static const T kOffsetBasis;
+};
+
+template<> struct FnvTraits<uint32_t> {
+  static const uint32_t kFnvPrime = 0x01000193;
+  static const uint32_t kOffsetBasis = 0x811C9DC5;
+};
+
+template<> struct FnvTraits<uint64_t> {
+  static const uint64_t kFnvPrime = 0x00000100000001b3ULL;
+  static const uint64_t kOffsetBasis = 0xcbf29ce484222645ULL;
+};
+
+template<typename T> T HashFnv1(const char *input) {
+  T hash = FnvTraits<T>::kOffsetBasis;
+  for (const char *c = input; *c; ++c) {
+    hash *= FnvTraits<T>::kFnvPrime;
+    hash ^= static_cast<unsigned char>(*c);
+  }
+  return hash;
+}
+
+template<typename T> T HashFnv1a(const char *input) {
+  T hash = FnvTraits<T>::kOffsetBasis;
+  for (const char *c = input; *c; ++c) {
+    hash ^= static_cast<unsigned char>(*c);
+    hash *= FnvTraits<T>::kFnvPrime;
+  }
+  return hash;
+}
+
+template <> inline uint16_t HashFnv1<uint16_t>(const char *input) {
+  uint32_t hash = HashFnv1<uint32_t>(input);
+  return (hash >> 16) ^ (hash & 0xffff);
+}
+
+template <> inline uint16_t HashFnv1a<uint16_t>(const char *input) {
+  uint32_t hash = HashFnv1a<uint32_t>(input);
+  return (hash >> 16) ^ (hash & 0xffff);
+}
+
+template <typename T> struct NamedHashFunction {
+  const char *name;
+
+  typedef T (*HashFunction)(const char *);
+  HashFunction function;
+};
+
+const NamedHashFunction<uint16_t> kHashFunctions16[] = {
+  { "fnv1_16",  HashFnv1<uint16_t> },
+  { "fnv1a_16", HashFnv1a<uint16_t> },
+};
+
+const NamedHashFunction<uint32_t> kHashFunctions32[] = {
+  { "fnv1_32", HashFnv1<uint32_t> },
+  { "fnv1a_32", HashFnv1a<uint32_t> },
+};
+
+const NamedHashFunction<uint64_t> kHashFunctions64[] = {
+  { "fnv1_64", HashFnv1<uint64_t> },
+  { "fnv1a_64", HashFnv1a<uint64_t> },
+};
+
+inline NamedHashFunction<uint16_t>::HashFunction FindHashFunction16(
+    const char *name) {
+  std::size_t size = sizeof(kHashFunctions16) / sizeof(kHashFunctions16[0]);
+  for (std::size_t i = 0; i < size; ++i) {
+    if (std::strcmp(name, kHashFunctions16[i].name) == 0) {
+      return kHashFunctions16[i].function;
+    }
+  }
+  return nullptr;
+}
+
+inline NamedHashFunction<uint32_t>::HashFunction FindHashFunction32(
+    const char *name) {
+  std::size_t size = sizeof(kHashFunctions32) / sizeof(kHashFunctions32[0]);
+  for (std::size_t i = 0; i < size; ++i) {
+    if (std::strcmp(name, kHashFunctions32[i].name) == 0) {
+      return kHashFunctions32[i].function;
+    }
+  }
+  return nullptr;
+}
+
+inline NamedHashFunction<uint64_t>::HashFunction FindHashFunction64(
+    const char *name) {
+  std::size_t size = sizeof(kHashFunctions64) / sizeof(kHashFunctions64[0]);
+  for (std::size_t i = 0; i < size; ++i) {
+    if (std::strcmp(name, kHashFunctions64[i].name) == 0) {
+      return kHashFunctions64[i].function;
+    }
+  }
+  return nullptr;
+}
+
+}  // namespace flatbuffers
+
+#endif  // FLATBUFFERS_HASH_H_
diff --git a/third_party/flatbuffers/include/flatbuffers/idl.h b/third_party/flatbuffers/include/flatbuffers/idl.h
new file mode 100644
index 0000000..44e3566
--- /dev/null
+++ b/third_party/flatbuffers/include/flatbuffers/idl.h
@@ -0,0 +1,1093 @@
+/*
+ * 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.
+ */
+
+#ifndef FLATBUFFERS_IDL_H_
+#define FLATBUFFERS_IDL_H_
+
+#include <map>
+#include <memory>
+#include <stack>
+
+#include "flatbuffers/base.h"
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/flexbuffers.h"
+#include "flatbuffers/hash.h"
+#include "flatbuffers/reflection.h"
+
+#if !defined(FLATBUFFERS_CPP98_STL)
+#  include <functional>
+#endif  // !defined(FLATBUFFERS_CPP98_STL)
+
+// This file defines the data types representing a parsed IDL (Interface
+// Definition Language) / schema file.
+
+// Limits maximum depth of nested objects.
+// Prevents stack overflow while parse flatbuffers or json.
+#if !defined(FLATBUFFERS_MAX_PARSING_DEPTH)
+#  define FLATBUFFERS_MAX_PARSING_DEPTH 64
+#endif
+
+namespace flatbuffers {
+
+// The order of these matters for Is*() functions below.
+// Additionally, Parser::ParseType assumes bool..string is a contiguous range
+// of type tokens.
+// clang-format off
+#define FLATBUFFERS_GEN_TYPES_SCALAR(TD) \
+  TD(NONE,   "",       uint8_t,  byte,   byte,    byte,   uint8,   u8,   UByte) \
+  TD(UTYPE,  "",       uint8_t,  byte,   byte,    byte,   uint8,   u8,   UByte) /* begin scalar/int */ \
+  TD(BOOL,   "bool",   uint8_t,  boolean,bool,    bool,   bool,    bool, Boolean) \
+  TD(CHAR,   "byte",   int8_t,   byte,   int8,    sbyte,  int8,    i8,   Byte) \
+  TD(UCHAR,  "ubyte",  uint8_t,  byte,   byte,    byte,   uint8,   u8,   UByte) \
+  TD(SHORT,  "short",  int16_t,  short,  int16,   short,  int16,   i16,  Short) \
+  TD(USHORT, "ushort", uint16_t, short,  uint16,  ushort, uint16,  u16,  UShort) \
+  TD(INT,    "int",    int32_t,  int,    int32,   int,    int32,   i32,  Int) \
+  TD(UINT,   "uint",   uint32_t, int,    uint32,  uint,   uint32,  u32,  UInt) \
+  TD(LONG,   "long",   int64_t,  long,   int64,   long,   int64,   i64,  Long) \
+  TD(ULONG,  "ulong",  uint64_t, long,   uint64,  ulong,  uint64,  u64,  ULong) /* end int */ \
+  TD(FLOAT,  "float",  float,    float,  float32, float,  float32, f32,  Float) /* begin float */ \
+  TD(DOUBLE, "double", double,   double, float64, double, float64, f64,  Double) /* end float/scalar */
+#define FLATBUFFERS_GEN_TYPES_POINTER(TD) \
+  TD(STRING, "string", Offset<void>, int, int, StringOffset, int, unused, Int) \
+  TD(VECTOR, "",       Offset<void>, int, int, VectorOffset, int, unused, Int) \
+  TD(STRUCT, "",       Offset<void>, int, int, int,          int, unused, Int) \
+  TD(UNION,  "",       Offset<void>, int, int, int,          int, unused, Int)
+#define FLATBUFFERS_GEN_TYPE_ARRAY(TD) \
+  TD(ARRAY,  "",       int,          int, int, int,          int, unused, Int)
+// The fields are:
+// - enum
+// - FlatBuffers schema type.
+// - C++ type.
+// - Java type.
+// - Go type.
+// - C# / .Net type.
+// - Python type.
+// - Rust type.
+// - Kotlin type.
+
+// using these macros, we can now write code dealing with types just once, e.g.
+
+/*
+switch (type) {
+  #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
+                         RTYPE, KTYPE) \
+    case BASE_TYPE_ ## ENUM: \
+      // do something specific to CTYPE here
+    FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+  #undef FLATBUFFERS_TD
+}
+*/
+
+#define FLATBUFFERS_GEN_TYPES(TD) \
+        FLATBUFFERS_GEN_TYPES_SCALAR(TD) \
+        FLATBUFFERS_GEN_TYPES_POINTER(TD) \
+        FLATBUFFERS_GEN_TYPE_ARRAY(TD)
+
+// Create an enum for all the types above.
+#ifdef __GNUC__
+__extension__  // Stop GCC complaining about trailing comma with -Wpendantic.
+#endif
+enum BaseType {
+  #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
+                         RTYPE, KTYPE) \
+      BASE_TYPE_ ## ENUM,
+    FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+  #undef FLATBUFFERS_TD
+};
+
+#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
+                       RTYPE, KTYPE) \
+    static_assert(sizeof(CTYPE) <= sizeof(largest_scalar_t), \
+                  "define largest_scalar_t as " #CTYPE);
+  FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+#undef FLATBUFFERS_TD
+
+inline bool IsScalar (BaseType t) { return t >= BASE_TYPE_UTYPE &&
+                                           t <= BASE_TYPE_DOUBLE; }
+inline bool IsInteger(BaseType t) { return t >= BASE_TYPE_UTYPE &&
+                                           t <= BASE_TYPE_ULONG; }
+inline bool IsFloat  (BaseType t) { return t == BASE_TYPE_FLOAT ||
+                                           t == BASE_TYPE_DOUBLE; }
+inline bool IsLong   (BaseType t) { return t == BASE_TYPE_LONG ||
+                                           t == BASE_TYPE_ULONG; }
+inline bool IsBool   (BaseType t) { return t == BASE_TYPE_BOOL; }
+inline bool IsOneByte(BaseType t) { return t >= BASE_TYPE_UTYPE &&
+                                           t <= BASE_TYPE_UCHAR; }
+
+inline bool IsUnsigned(BaseType t) {
+  return (t == BASE_TYPE_UTYPE)  || (t == BASE_TYPE_UCHAR) ||
+         (t == BASE_TYPE_USHORT) || (t == BASE_TYPE_UINT)  ||
+         (t == BASE_TYPE_ULONG);
+}
+
+// clang-format on
+
+extern const char *const kTypeNames[];
+extern const char kTypeSizes[];
+
+inline size_t SizeOf(BaseType t) { return kTypeSizes[t]; }
+
+struct StructDef;
+struct EnumDef;
+class Parser;
+
+// Represents any type in the IDL, which is a combination of the BaseType
+// and additional information for vectors/structs_.
+struct Type {
+  explicit Type(BaseType _base_type = BASE_TYPE_NONE, StructDef *_sd = nullptr,
+                EnumDef *_ed = nullptr, uint16_t _fixed_length = 0)
+      : base_type(_base_type),
+        element(BASE_TYPE_NONE),
+        struct_def(_sd),
+        enum_def(_ed),
+        fixed_length(_fixed_length) {}
+
+  bool operator==(const Type &o) {
+    return base_type == o.base_type && element == o.element &&
+           struct_def == o.struct_def && enum_def == o.enum_def;
+  }
+
+  Type VectorType() const {
+    return Type(element, struct_def, enum_def, fixed_length);
+  }
+
+  Offset<reflection::Type> Serialize(FlatBufferBuilder *builder) const;
+
+  bool Deserialize(const Parser &parser, const reflection::Type *type);
+
+  BaseType base_type;
+  BaseType element;       // only set if t == BASE_TYPE_VECTOR
+  StructDef *struct_def;  // only set if t or element == BASE_TYPE_STRUCT
+  EnumDef *enum_def;      // set if t == BASE_TYPE_UNION / BASE_TYPE_UTYPE,
+                          // or for an integral type derived from an enum.
+  uint16_t fixed_length;  // only set if t == BASE_TYPE_ARRAY
+};
+
+// Represents a parsed scalar value, it's type, and field offset.
+struct Value {
+  Value()
+      : constant("0"),
+        offset(static_cast<voffset_t>(~(static_cast<voffset_t>(0U)))) {}
+  Type type;
+  std::string constant;
+  voffset_t offset;
+};
+
+// Helper class that retains the original order of a set of identifiers and
+// also provides quick lookup.
+template<typename T> class SymbolTable {
+ public:
+  ~SymbolTable() {
+    for (auto it = vec.begin(); it != vec.end(); ++it) { delete *it; }
+  }
+
+  bool Add(const std::string &name, T *e) {
+    vector_emplace_back(&vec, e);
+    auto it = dict.find(name);
+    if (it != dict.end()) return true;
+    dict[name] = e;
+    return false;
+  }
+
+  void Move(const std::string &oldname, const std::string &newname) {
+    auto it = dict.find(oldname);
+    if (it != dict.end()) {
+      auto obj = it->second;
+      dict.erase(it);
+      dict[newname] = obj;
+    } else {
+      FLATBUFFERS_ASSERT(false);
+    }
+  }
+
+  T *Lookup(const std::string &name) const {
+    auto it = dict.find(name);
+    return it == dict.end() ? nullptr : it->second;
+  }
+
+ public:
+  std::map<std::string, T *> dict;  // quick lookup
+  std::vector<T *> vec;             // Used to iterate in order of insertion
+};
+
+// A name space, as set in the schema.
+struct Namespace {
+  Namespace() : from_table(0) {}
+
+  // Given a (potentally unqualified) name, return the "fully qualified" name
+  // which has a full namespaced descriptor.
+  // With max_components you can request less than the number of components
+  // the current namespace has.
+  std::string GetFullyQualifiedName(const std::string &name,
+                                    size_t max_components = 1000) const;
+
+  std::vector<std::string> components;
+  size_t from_table;  // Part of the namespace corresponds to a message/table.
+};
+
+inline bool operator<(const Namespace &a, const Namespace &b) {
+  size_t min_size = std::min(a.components.size(), b.components.size());
+  for (size_t i = 0; i < min_size; ++i) {
+    if (a.components[i] != b.components[i])
+      return a.components[i] < b.components[i];
+  }
+  return a.components.size() < b.components.size();
+}
+
+// Base class for all definition types (fields, structs_, enums_).
+struct Definition {
+  Definition()
+      : generated(false),
+        defined_namespace(nullptr),
+        serialized_location(0),
+        index(-1),
+        refcount(1) {}
+
+  flatbuffers::Offset<
+      flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>>
+  SerializeAttributes(FlatBufferBuilder *builder, const Parser &parser) const;
+
+  bool DeserializeAttributes(Parser &parser,
+                             const Vector<Offset<reflection::KeyValue>> *attrs);
+
+  std::string name;
+  std::string file;
+  std::vector<std::string> doc_comment;
+  SymbolTable<Value> attributes;
+  bool generated;  // did we already output code for this definition?
+  Namespace *defined_namespace;  // Where it was defined.
+
+  // For use with Serialize()
+  uoffset_t serialized_location;
+  int index;  // Inside the vector it is stored.
+  int refcount;
+};
+
+struct FieldDef : public Definition {
+  FieldDef()
+      : deprecated(false),
+        required(false),
+        key(false),
+        shared(false),
+        native_inline(false),
+        flexbuffer(false),
+        nested_flatbuffer(NULL),
+        padding(0) {}
+
+  Offset<reflection::Field> Serialize(FlatBufferBuilder *builder, uint16_t id,
+                                      const Parser &parser) const;
+
+  bool Deserialize(Parser &parser, const reflection::Field *field);
+
+  Value value;
+  bool deprecated;  // Field is allowed to be present in old data, but can't be.
+                    // written in new data nor accessed in new code.
+  bool required;    // Field must always be present.
+  bool key;         // Field functions as a key for creating sorted vectors.
+  bool shared;  // Field will be using string pooling (i.e. CreateSharedString)
+                // as default serialization behavior if field is a string.
+  bool native_inline;  // Field will be defined inline (instead of as a pointer)
+                       // for native tables if field is a struct.
+  bool flexbuffer;     // This field contains FlexBuffer data.
+  StructDef *nested_flatbuffer;  // This field contains nested FlatBuffer data.
+  size_t padding;                // Bytes to always pad after this field.
+};
+
+struct StructDef : public Definition {
+  StructDef()
+      : fixed(false),
+        predecl(true),
+        sortbysize(true),
+        has_key(false),
+        minalign(1),
+        bytesize(0) {}
+
+  void PadLastField(size_t min_align) {
+    auto padding = PaddingBytes(bytesize, min_align);
+    bytesize += padding;
+    if (fields.vec.size()) fields.vec.back()->padding = padding;
+  }
+
+  Offset<reflection::Object> Serialize(FlatBufferBuilder *builder,
+                                       const Parser &parser) const;
+
+  bool Deserialize(Parser &parser, const reflection::Object *object);
+
+  SymbolTable<FieldDef> fields;
+
+  bool fixed;       // If it's struct, not a table.
+  bool predecl;     // If it's used before it was defined.
+  bool sortbysize;  // Whether fields come in the declaration or size order.
+  bool has_key;     // It has a key field.
+  size_t minalign;  // What the whole object needs to be aligned to.
+  size_t bytesize;  // Size if fixed.
+
+  flatbuffers::unique_ptr<std::string> original_location;
+};
+
+inline bool IsStruct(const Type &type) {
+  return type.base_type == BASE_TYPE_STRUCT && type.struct_def->fixed;
+}
+
+inline bool IsVector(const Type &type) {
+  return type.base_type == BASE_TYPE_VECTOR;
+}
+
+inline bool IsArray(const Type &type) {
+  return type.base_type == BASE_TYPE_ARRAY;
+}
+
+inline bool IsSeries(const Type &type) {
+  return IsVector(type) || IsArray(type);
+}
+
+inline bool IsEnum(const Type &type) {
+  return type.enum_def != nullptr && IsInteger(type.base_type);
+}
+
+inline size_t InlineSize(const Type &type) {
+  return IsStruct(type)
+             ? type.struct_def->bytesize
+             : (IsArray(type)
+                    ? InlineSize(type.VectorType()) * type.fixed_length
+                    : SizeOf(type.base_type));
+}
+
+inline size_t InlineAlignment(const Type &type) {
+  return IsStruct(type)
+             ? type.struct_def->minalign
+             : (SizeOf(IsArray(type) ? type.element : type.base_type));
+}
+
+struct EnumDef;
+struct EnumValBuilder;
+
+struct EnumVal {
+  Offset<reflection::EnumVal> Serialize(FlatBufferBuilder *builder, const Parser &parser) const;
+
+  bool Deserialize(const Parser &parser, const reflection::EnumVal *val);
+
+  uint64_t GetAsUInt64() const { return static_cast<uint64_t>(value); }
+  int64_t GetAsInt64() const { return value; }
+  bool IsZero() const { return 0 == value; }
+  bool IsNonZero() const { return !IsZero(); }
+
+  std::string name;
+  std::vector<std::string> doc_comment;
+  Type union_type;
+
+ private:
+  friend EnumDef;
+  friend EnumValBuilder;
+  friend bool operator==(const EnumVal &lhs, const EnumVal &rhs);
+
+  EnumVal(const std::string &_name, int64_t _val) : name(_name), value(_val) {}
+  EnumVal() : value(0) {}
+
+  int64_t value;
+};
+
+struct EnumDef : public Definition {
+  EnumDef() : is_union(false), uses_multiple_type_instances(false) {}
+
+  Offset<reflection::Enum> Serialize(FlatBufferBuilder *builder,
+                                     const Parser &parser) const;
+
+  bool Deserialize(Parser &parser, const reflection::Enum *values);
+
+  template<typename T> void ChangeEnumValue(EnumVal *ev, T new_val);
+  void SortByValue();
+  void RemoveDuplicates();
+
+  std::string AllFlags() const;
+  const EnumVal *MinValue() const;
+  const EnumVal *MaxValue() const;
+  // Returns the number of integer steps from v1 to v2.
+  uint64_t Distance(const EnumVal *v1, const EnumVal *v2) const;
+  // Returns the number of integer steps from Min to Max.
+  uint64_t Distance() const { return Distance(MinValue(), MaxValue()); }
+
+  EnumVal *ReverseLookup(int64_t enum_idx,
+                         bool skip_union_default = false) const;
+  EnumVal *FindByValue(const std::string &constant) const;
+
+  std::string ToString(const EnumVal &ev) const {
+    return IsUInt64() ? NumToString(ev.GetAsUInt64())
+                      : NumToString(ev.GetAsInt64());
+  }
+
+  size_t size() const { return vals.vec.size(); }
+
+  const std::vector<EnumVal *> &Vals() const {
+    FLATBUFFERS_ASSERT(false == vals.vec.empty());
+    return vals.vec;
+  }
+
+  const EnumVal *Lookup(const std::string &enum_name) const {
+    return vals.Lookup(enum_name);
+  }
+
+  bool is_union;
+  // Type is a union which uses type aliases where at least one type is
+  // available under two different names.
+  bool uses_multiple_type_instances;
+  Type underlying_type;
+
+ private:
+  bool IsUInt64() const {
+    return (BASE_TYPE_ULONG == underlying_type.base_type);
+  }
+
+  friend EnumValBuilder;
+  SymbolTable<EnumVal> vals;
+};
+
+inline bool operator==(const EnumVal &lhs, const EnumVal &rhs) {
+  return lhs.value == rhs.value;
+}
+inline bool operator!=(const EnumVal &lhs, const EnumVal &rhs) {
+  return !(lhs == rhs);
+}
+
+inline bool EqualByName(const Type &a, const Type &b) {
+  return a.base_type == b.base_type && a.element == b.element &&
+         (a.struct_def == b.struct_def ||
+          a.struct_def->name == b.struct_def->name) &&
+         (a.enum_def == b.enum_def || a.enum_def->name == b.enum_def->name);
+}
+
+struct RPCCall : public Definition {
+  Offset<reflection::RPCCall> Serialize(FlatBufferBuilder *builder, const Parser &parser) const;
+
+  bool Deserialize(Parser &parser, const reflection::RPCCall *call);
+
+  StructDef *request, *response;
+};
+
+struct ServiceDef : public Definition {
+  Offset<reflection::Service> Serialize(FlatBufferBuilder *builder, const Parser &parser) const;
+  bool Deserialize(Parser &parser, const reflection::Service *service);
+
+  SymbolTable<RPCCall> calls;
+};
+
+// Container of options that may apply to any of the source/text generators.
+struct IDLOptions {
+  bool strict_json;
+  bool skip_js_exports;
+  bool use_goog_js_export_format;
+  bool use_ES6_js_export_format;
+  bool output_default_scalars_in_json;
+  int indent_step;
+  bool output_enum_identifiers;
+  bool prefixed_enums;
+  bool scoped_enums;
+  bool include_dependence_headers;
+  bool mutable_buffer;
+  bool one_file;
+  bool proto_mode;
+  bool proto_oneof_union;
+  bool generate_all;
+  bool skip_unexpected_fields_in_json;
+  bool generate_name_strings;
+  bool generate_object_based_api;
+  bool gen_compare;
+  std::string cpp_object_api_pointer_type;
+  std::string cpp_object_api_string_type;
+  bool cpp_object_api_string_flexible_constructor;
+  bool gen_nullable;
+  bool gen_generated;
+  std::string object_prefix;
+  std::string object_suffix;
+  bool union_value_namespacing;
+  bool allow_non_utf8;
+  bool natural_utf8;
+  std::string include_prefix;
+  bool keep_include_path;
+  bool binary_schema_comments;
+  bool binary_schema_builtins;
+  bool skip_flatbuffers_import;
+  std::string go_import;
+  std::string go_namespace;
+  bool reexport_ts_modules;
+  bool js_ts_short_names;
+  bool protobuf_ascii_alike;
+  bool size_prefixed;
+  std::string root_type;
+  bool force_defaults;
+  std::vector<std::string> cpp_includes;
+
+  // Possible options for the more general generator below.
+  enum Language {
+    kJava = 1 << 0,
+    kCSharp = 1 << 1,
+    kGo = 1 << 2,
+    kCpp = 1 << 3,
+    kJs = 1 << 4,
+    kPython = 1 << 5,
+    kPhp = 1 << 6,
+    kJson = 1 << 7,
+    kBinary = 1 << 8,
+    kTs = 1 << 9,
+    kJsonSchema = 1 << 10,
+    kDart = 1 << 11,
+    kLua = 1 << 12,
+    kLobster = 1 << 13,
+    kRust = 1 << 14,
+    kKotlin = 1 << 15,
+    kMAX
+  };
+
+  Language lang;
+
+  enum MiniReflect { kNone, kTypes, kTypesAndNames };
+
+  MiniReflect mini_reflect;
+
+  // The corresponding language bit will be set if a language is included
+  // for code generation.
+  unsigned long lang_to_generate;
+
+  // If set (default behavior), empty string and vector fields will be set to
+  // nullptr to make the flatbuffer more compact.
+  bool set_empty_to_null;
+
+  IDLOptions()
+      : strict_json(false),
+        skip_js_exports(false),
+        use_goog_js_export_format(false),
+        use_ES6_js_export_format(false),
+        output_default_scalars_in_json(false),
+        indent_step(2),
+        output_enum_identifiers(true),
+        prefixed_enums(true),
+        scoped_enums(false),
+        include_dependence_headers(true),
+        mutable_buffer(false),
+        one_file(false),
+        proto_mode(false),
+        proto_oneof_union(false),
+        generate_all(false),
+        skip_unexpected_fields_in_json(false),
+        generate_name_strings(false),
+        generate_object_based_api(false),
+        gen_compare(false),
+        cpp_object_api_pointer_type("std::unique_ptr"),
+        cpp_object_api_string_flexible_constructor(false),
+        gen_nullable(false),
+        gen_generated(false),
+        object_suffix("T"),
+        union_value_namespacing(true),
+        allow_non_utf8(false),
+        natural_utf8(false),
+        keep_include_path(false),
+        binary_schema_comments(false),
+        binary_schema_builtins(false),
+        skip_flatbuffers_import(false),
+        reexport_ts_modules(true),
+        js_ts_short_names(false),
+        protobuf_ascii_alike(false),
+        size_prefixed(false),
+        force_defaults(false),
+        lang(IDLOptions::kJava),
+        mini_reflect(IDLOptions::kNone),
+        lang_to_generate(0),
+        set_empty_to_null(true) {}
+};
+
+// This encapsulates where the parser is in the current source file.
+struct ParserState {
+  ParserState()
+      : cursor_(nullptr),
+        line_start_(nullptr),
+        line_(0),
+        token_(-1),
+        attr_is_trivial_ascii_string_(true) {}
+
+ protected:
+  void ResetState(const char *source) {
+    cursor_ = source;
+    line_ = 0;
+    MarkNewLine();
+  }
+
+  void MarkNewLine() {
+    line_start_ = cursor_;
+    line_ += 1;
+  }
+
+  int64_t CursorPosition() const {
+    FLATBUFFERS_ASSERT(cursor_ && line_start_ && cursor_ >= line_start_);
+    return static_cast<int64_t>(cursor_ - line_start_);
+  }
+
+  const char *cursor_;
+  const char *line_start_;
+  int line_;  // the current line being parsed
+  int token_;
+
+  // Flag: text in attribute_ is true ASCII string without escape
+  // sequences. Only printable ASCII (without [\t\r\n]).
+  // Used for number-in-string (and base64 string in future).
+  bool attr_is_trivial_ascii_string_;
+  std::string attribute_;
+  std::vector<std::string> doc_comment_;
+};
+
+// A way to make error propagation less error prone by requiring values to be
+// checked.
+// Once you create a value of this type you must either:
+// - Call Check() on it.
+// - Copy or assign it to another value.
+// Failure to do so leads to an assert.
+// This guarantees that this as return value cannot be ignored.
+class CheckedError {
+ public:
+  explicit CheckedError(bool error)
+      : is_error_(error), has_been_checked_(false) {}
+
+  CheckedError &operator=(const CheckedError &other) {
+    is_error_ = other.is_error_;
+    has_been_checked_ = false;
+    other.has_been_checked_ = true;
+    return *this;
+  }
+
+  CheckedError(const CheckedError &other) {
+    *this = other;  // Use assignment operator.
+  }
+
+  ~CheckedError() { FLATBUFFERS_ASSERT(has_been_checked_); }
+
+  bool Check() {
+    has_been_checked_ = true;
+    return is_error_;
+  }
+
+ private:
+  bool is_error_;
+  mutable bool has_been_checked_;
+};
+
+// Additionally, in GCC we can get these errors statically, for additional
+// assurance:
+// clang-format off
+#ifdef __GNUC__
+#define FLATBUFFERS_CHECKED_ERROR CheckedError \
+          __attribute__((warn_unused_result))
+#else
+#define FLATBUFFERS_CHECKED_ERROR CheckedError
+#endif
+// clang-format on
+
+class Parser : public ParserState {
+ public:
+  explicit Parser(const IDLOptions &options = IDLOptions())
+      : current_namespace_(nullptr),
+        empty_namespace_(nullptr),
+        root_struct_def_(nullptr),
+        opts(options),
+        uses_flexbuffers_(false),
+        source_(nullptr),
+        anonymous_counter(0),
+        recurse_protection_counter(0) {
+    if (opts.force_defaults) {
+      builder_.ForceDefaults(true);
+    }
+    // Start out with the empty namespace being current.
+    empty_namespace_ = new Namespace();
+    namespaces_.push_back(empty_namespace_);
+    current_namespace_ = empty_namespace_;
+    known_attributes_["deprecated"] = true;
+    known_attributes_["required"] = true;
+    known_attributes_["key"] = true;
+    known_attributes_["shared"] = true;
+    known_attributes_["hash"] = true;
+    known_attributes_["id"] = true;
+    known_attributes_["force_align"] = true;
+    known_attributes_["bit_flags"] = true;
+    known_attributes_["original_order"] = true;
+    known_attributes_["nested_flatbuffer"] = true;
+    known_attributes_["csharp_partial"] = true;
+    known_attributes_["streaming"] = true;
+    known_attributes_["idempotent"] = true;
+    known_attributes_["cpp_type"] = true;
+    known_attributes_["cpp_ptr_type"] = true;
+    known_attributes_["cpp_ptr_type_get"] = true;
+    known_attributes_["cpp_str_type"] = true;
+    known_attributes_["cpp_str_flex_ctor"] = true;
+    known_attributes_["native_inline"] = true;
+    known_attributes_["native_custom_alloc"] = true;
+    known_attributes_["native_type"] = true;
+    known_attributes_["native_default"] = true;
+    known_attributes_["flexbuffer"] = true;
+    known_attributes_["private"] = true;
+  }
+
+  ~Parser() {
+    for (auto it = namespaces_.begin(); it != namespaces_.end(); ++it) {
+      delete *it;
+    }
+  }
+
+  // Parse the string containing either schema or JSON data, which will
+  // populate the SymbolTable's or the FlatBufferBuilder above.
+  // include_paths is used to resolve any include statements, and typically
+  // should at least include the project path (where you loaded source_ from).
+  // include_paths must be nullptr terminated if specified.
+  // If include_paths is nullptr, it will attempt to load from the current
+  // directory.
+  // If the source was loaded from a file and isn't an include file,
+  // supply its name in source_filename.
+  // All paths specified in this call must be in posix format, if you accept
+  // paths from user input, please call PosixPath on them first.
+  bool Parse(const char *_source, const char **include_paths = nullptr,
+             const char *source_filename = nullptr);
+
+  // Set the root type. May override the one set in the schema.
+  bool SetRootType(const char *name);
+
+  // Mark all definitions as already having code generated.
+  void MarkGenerated();
+
+  // Get the files recursively included by the given file. The returned
+  // container will have at least the given file.
+  std::set<std::string> GetIncludedFilesRecursive(
+      const std::string &file_name) const;
+
+  // Fills builder_ with a binary version of the schema parsed.
+  // See reflection/reflection.fbs
+  void Serialize();
+
+  // Deserialize a schema buffer
+  bool Deserialize(const uint8_t *buf, const size_t size);
+
+  // Fills internal structure as if the schema passed had been loaded by parsing
+  // with Parse except that included filenames will not be populated.
+  bool Deserialize(const reflection::Schema* schema);
+
+  Type* DeserializeType(const reflection::Type* type);
+
+  // Checks that the schema represented by this parser is a safe evolution
+  // of the schema provided. Returns non-empty error on any problems.
+  std::string ConformTo(const Parser &base);
+
+  // Similar to Parse(), but now only accepts JSON to be parsed into a
+  // FlexBuffer.
+  bool ParseFlexBuffer(const char *source, const char *source_filename,
+                       flexbuffers::Builder *builder);
+
+  StructDef *LookupStruct(const std::string &id) const;
+
+  std::string UnqualifiedName(const std::string &fullQualifiedName);
+
+  FLATBUFFERS_CHECKED_ERROR Error(const std::string &msg);
+
+ private:
+  void Message(const std::string &msg);
+  void Warning(const std::string &msg);
+  FLATBUFFERS_CHECKED_ERROR ParseHexNum(int nibbles, uint64_t *val);
+  FLATBUFFERS_CHECKED_ERROR Next();
+  FLATBUFFERS_CHECKED_ERROR SkipByteOrderMark();
+  bool Is(int t) const;
+  bool IsIdent(const char *id) const;
+  FLATBUFFERS_CHECKED_ERROR Expect(int t);
+  std::string TokenToStringId(int t) const;
+  EnumDef *LookupEnum(const std::string &id);
+  FLATBUFFERS_CHECKED_ERROR ParseNamespacing(std::string *id,
+                                             std::string *last);
+  FLATBUFFERS_CHECKED_ERROR ParseTypeIdent(Type &type);
+  FLATBUFFERS_CHECKED_ERROR ParseType(Type &type);
+  FLATBUFFERS_CHECKED_ERROR AddField(StructDef &struct_def,
+                                     const std::string &name, const Type &type,
+                                     FieldDef **dest);
+  FLATBUFFERS_CHECKED_ERROR ParseField(StructDef &struct_def);
+  FLATBUFFERS_CHECKED_ERROR ParseString(Value &val);
+  FLATBUFFERS_CHECKED_ERROR ParseComma();
+  FLATBUFFERS_CHECKED_ERROR ParseAnyValue(Value &val, FieldDef *field,
+                                          size_t parent_fieldn,
+                                          const StructDef *parent_struct_def,
+                                          uoffset_t count,
+                                          bool inside_vector = false);
+  template<typename F>
+  FLATBUFFERS_CHECKED_ERROR ParseTableDelimiters(size_t &fieldn,
+                                                 const StructDef *struct_def,
+                                                 F body);
+  FLATBUFFERS_CHECKED_ERROR ParseTable(const StructDef &struct_def,
+                                       std::string *value, uoffset_t *ovalue);
+  void SerializeStruct(const StructDef &struct_def, const Value &val);
+  void SerializeStruct(FlatBufferBuilder &builder, const StructDef &struct_def,
+                       const Value &val);
+  template<typename F>
+  FLATBUFFERS_CHECKED_ERROR ParseVectorDelimiters(uoffset_t &count, F body);
+  FLATBUFFERS_CHECKED_ERROR ParseVector(const Type &type, uoffset_t *ovalue,
+                                        FieldDef *field, size_t fieldn);
+  FLATBUFFERS_CHECKED_ERROR ParseArray(Value &array);
+  FLATBUFFERS_CHECKED_ERROR ParseNestedFlatbuffer(Value &val, FieldDef *field,
+                                                  size_t fieldn,
+                                                  const StructDef *parent_struct_def);
+  FLATBUFFERS_CHECKED_ERROR ParseMetaData(SymbolTable<Value> *attributes);
+  FLATBUFFERS_CHECKED_ERROR TryTypedValue(const std::string *name, int dtoken, bool check, Value &e,
+                                          BaseType req, bool *destmatch);
+  FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef* field);
+  FLATBUFFERS_CHECKED_ERROR TokenError();
+  FLATBUFFERS_CHECKED_ERROR ParseSingleValue(const std::string *name, Value &e, bool check_now);
+  FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(const Type &type, std::string *result);
+  StructDef *LookupCreateStruct(const std::string &name,
+                                bool create_if_new = true,
+                                bool definition = false);
+  FLATBUFFERS_CHECKED_ERROR ParseEnum(bool is_union, EnumDef **dest);
+  FLATBUFFERS_CHECKED_ERROR ParseNamespace();
+  FLATBUFFERS_CHECKED_ERROR StartStruct(const std::string &name,
+                                        StructDef **dest);
+  FLATBUFFERS_CHECKED_ERROR StartEnum(const std::string &name,
+                                      bool is_union,
+                                      EnumDef **dest);
+  FLATBUFFERS_CHECKED_ERROR ParseDecl();
+  FLATBUFFERS_CHECKED_ERROR ParseService();
+  FLATBUFFERS_CHECKED_ERROR ParseProtoFields(StructDef *struct_def,
+                                             bool isextend, bool inside_oneof);
+  FLATBUFFERS_CHECKED_ERROR ParseProtoOption();
+  FLATBUFFERS_CHECKED_ERROR ParseProtoKey();
+  FLATBUFFERS_CHECKED_ERROR ParseProtoDecl();
+  FLATBUFFERS_CHECKED_ERROR ParseProtoCurliesOrIdent();
+  FLATBUFFERS_CHECKED_ERROR ParseTypeFromProtoType(Type *type);
+  FLATBUFFERS_CHECKED_ERROR SkipAnyJsonValue();
+  FLATBUFFERS_CHECKED_ERROR ParseFlexBufferValue(flexbuffers::Builder *builder);
+  FLATBUFFERS_CHECKED_ERROR StartParseFile(const char *source,
+                                           const char *source_filename);
+  FLATBUFFERS_CHECKED_ERROR ParseRoot(const char *_source,
+                                    const char **include_paths,
+                                    const char *source_filename);
+  FLATBUFFERS_CHECKED_ERROR DoParse(const char *_source,
+                                           const char **include_paths,
+                                           const char *source_filename,
+                                           const char *include_filename);
+  FLATBUFFERS_CHECKED_ERROR CheckClash(std::vector<FieldDef*> &fields,
+                                       StructDef *struct_def,
+                                       const char *suffix,
+                                       BaseType baseType);
+
+  bool SupportsAdvancedUnionFeatures() const;
+  bool SupportsAdvancedArrayFeatures() const;
+  Namespace *UniqueNamespace(Namespace *ns);
+
+  FLATBUFFERS_CHECKED_ERROR RecurseError();
+  template<typename F> CheckedError Recurse(F f);
+
+ public:
+  SymbolTable<Type> types_;
+  SymbolTable<StructDef> structs_;
+  SymbolTable<EnumDef> enums_;
+  SymbolTable<ServiceDef> services_;
+  std::vector<Namespace *> namespaces_;
+  Namespace *current_namespace_;
+  Namespace *empty_namespace_;
+  std::string error_;         // User readable error_ if Parse() == false
+
+  FlatBufferBuilder builder_;  // any data contained in the file
+  StructDef *root_struct_def_;
+  std::string file_identifier_;
+  std::string file_extension_;
+
+  std::map<std::string, std::string> included_files_;
+  std::map<std::string, std::set<std::string>> files_included_per_file_;
+  std::vector<std::string> native_included_files_;
+
+  std::map<std::string, bool> known_attributes_;
+
+  IDLOptions opts;
+  bool uses_flexbuffers_;
+
+ private:
+  const char *source_;
+
+  std::string file_being_parsed_;
+
+  std::vector<std::pair<Value, FieldDef *>> field_stack_;
+
+  int anonymous_counter;
+  int recurse_protection_counter;
+};
+
+// Utility functions for multiple generators:
+
+extern std::string MakeCamel(const std::string &in, bool first = true);
+
+// Generate text (JSON) from a given FlatBuffer, and a given Parser
+// object that has been populated with the corresponding schema.
+// If ident_step is 0, no indentation will be generated. Additionally,
+// if it is less than 0, no linefeeds will be generated either.
+// See idl_gen_text.cpp.
+// strict_json adds "quotes" around field names if true.
+// If the flatbuffer cannot be encoded in JSON (e.g., it contains non-UTF-8
+// byte arrays in String values), returns false.
+extern bool GenerateTextFromTable(const Parser &parser,
+                                  const void *table,
+                                  const std::string &tablename,
+                                  std::string *text);
+extern bool GenerateText(const Parser &parser,
+                         const void *flatbuffer,
+                         std::string *text);
+extern bool GenerateTextFile(const Parser &parser,
+                             const std::string &path,
+                             const std::string &file_name);
+
+// Generate binary files from a given FlatBuffer, and a given Parser
+// object that has been populated with the corresponding schema.
+// See idl_gen_general.cpp.
+extern bool GenerateBinary(const Parser &parser,
+                           const std::string &path,
+                           const std::string &file_name);
+
+// Generate a C++ header from the definitions in the Parser object.
+// See idl_gen_cpp.
+extern bool GenerateCPP(const Parser &parser,
+                        const std::string &path,
+                        const std::string &file_name);
+
+extern bool GenerateDart(const Parser &parser,
+                         const std::string &path,
+                         const std::string &file_name);
+
+// Generate JavaScript or TypeScript code from the definitions in the Parser object.
+// See idl_gen_js.
+extern bool GenerateJSTS(const Parser &parser,
+                       const std::string &path,
+                       const std::string &file_name);
+
+// Generate Go files from the definitions in the Parser object.
+// See idl_gen_go.cpp.
+extern bool GenerateGo(const Parser &parser,
+                       const std::string &path,
+                       const std::string &file_name);
+
+// Generate Php code from the definitions in the Parser object.
+// See idl_gen_php.
+extern bool GeneratePhp(const Parser &parser,
+                        const std::string &path,
+                        const std::string &file_name);
+
+// Generate Python files from the definitions in the Parser object.
+// See idl_gen_python.cpp.
+extern bool GeneratePython(const Parser &parser,
+                           const std::string &path,
+                           const std::string &file_name);
+
+// Generate Lobster files from the definitions in the Parser object.
+// See idl_gen_lobster.cpp.
+extern bool GenerateLobster(const Parser &parser,
+                            const std::string &path,
+                            const std::string &file_name);
+
+// Generate Lua files from the definitions in the Parser object.
+// See idl_gen_lua.cpp.
+extern bool GenerateLua(const Parser &parser,
+                      const std::string &path,
+                      const std::string &file_name);
+
+// Generate Rust files from the definitions in the Parser object.
+// See idl_gen_rust.cpp.
+extern bool GenerateRust(const Parser &parser,
+                         const std::string &path,
+                         const std::string &file_name);
+
+// Generate Json schema file
+// See idl_gen_json_schema.cpp.
+extern bool GenerateJsonSchema(const Parser &parser,
+                           const std::string &path,
+                           const std::string &file_name);
+
+extern bool GenerateKotlin(const Parser &parser, const std::string &path,
+                           const std::string &file_name);
+
+// Generate Java/C#/.. files from the definitions in the Parser object.
+// See idl_gen_general.cpp.
+extern bool GenerateGeneral(const Parser &parser,
+                            const std::string &path,
+                            const std::string &file_name);
+
+// Generate a schema file from the internal representation, useful after
+// parsing a .proto schema.
+extern std::string GenerateFBS(const Parser &parser,
+                               const std::string &file_name);
+extern bool GenerateFBS(const Parser &parser,
+                        const std::string &path,
+                        const std::string &file_name);
+
+// Generate a make rule for the generated JavaScript or TypeScript code.
+// See idl_gen_js.cpp.
+extern std::string JSTSMakeRule(const Parser &parser,
+                              const std::string &path,
+                              const std::string &file_name);
+
+// Generate a make rule for the generated C++ header.
+// See idl_gen_cpp.cpp.
+extern std::string CPPMakeRule(const Parser &parser,
+                               const std::string &path,
+                               const std::string &file_name);
+
+// Generate a make rule for the generated Dart code
+// see idl_gen_dart.cpp
+extern std::string DartMakeRule(const Parser &parser,
+                                const std::string &path,
+                                const std::string &file_name);
+
+// Generate a make rule for the generated Rust code.
+// See idl_gen_rust.cpp.
+extern std::string RustMakeRule(const Parser &parser,
+                                const std::string &path,
+                                const std::string &file_name);
+
+// Generate a make rule for the generated Java/C#/... files.
+// See idl_gen_general.cpp.
+extern std::string GeneralMakeRule(const Parser &parser,
+                                   const std::string &path,
+                                   const std::string &file_name);
+
+// Generate a make rule for the generated text (JSON) files.
+// See idl_gen_text.cpp.
+extern std::string TextMakeRule(const Parser &parser,
+                                const std::string &path,
+                                const std::string &file_names);
+
+// Generate a make rule for the generated binary files.
+// See idl_gen_general.cpp.
+extern std::string BinaryMakeRule(const Parser &parser,
+                                  const std::string &path,
+                                  const std::string &file_name);
+
+// Generate GRPC Cpp interfaces.
+// See idl_gen_grpc.cpp.
+bool GenerateCppGRPC(const Parser &parser,
+                     const std::string &path,
+                     const std::string &file_name);
+
+// Generate GRPC Go interfaces.
+// See idl_gen_grpc.cpp.
+bool GenerateGoGRPC(const Parser &parser,
+                    const std::string &path,
+                    const std::string &file_name);
+
+// Generate GRPC Java classes.
+// See idl_gen_grpc.cpp
+bool GenerateJavaGRPC(const Parser &parser,
+                      const std::string &path,
+                      const std::string &file_name);
+
+}  // namespace flatbuffers
+
+#endif  // FLATBUFFERS_IDL_H_
diff --git a/third_party/flatbuffers/include/flatbuffers/minireflect.h b/third_party/flatbuffers/include/flatbuffers/minireflect.h
new file mode 100644
index 0000000..9d648ec
--- /dev/null
+++ b/third_party/flatbuffers/include/flatbuffers/minireflect.h
@@ -0,0 +1,407 @@
+/*
+ * 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.
+ */
+
+#ifndef FLATBUFFERS_MINIREFLECT_H_
+#define FLATBUFFERS_MINIREFLECT_H_
+
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/util.h"
+
+namespace flatbuffers {
+
+// Utilities that can be used with the "mini reflection" tables present
+// in generated code with --reflect-types (only types) or --reflect-names
+// (also names).
+// This allows basic reflection functionality such as pretty-printing
+// that does not require the use of the schema parser or loading of binary
+// schema files at runtime (reflection.h).
+
+// For any of the functions below that take `const TypeTable *`, you pass
+// `FooTypeTable()` if the type of the root is `Foo`.
+
+// First, a generic iterator that can be used by multiple algorithms.
+
+struct IterationVisitor {
+  // These mark the scope of a table or struct.
+  virtual void StartSequence() {}
+  virtual void EndSequence() {}
+  // Called for each field regardless of wether it is present or not.
+  // If not present, val == nullptr. set_idx is the index of all set fields.
+  virtual void Field(size_t /*field_idx*/, size_t /*set_idx*/,
+                     ElementaryType /*type*/, bool /*is_vector*/,
+                     const TypeTable * /*type_table*/, const char * /*name*/,
+                     const uint8_t * /*val*/) {}
+  // Called for a value that is actually present, after a field, or as part
+  // of a vector.
+  virtual void UType(uint8_t, const char *) {}
+  virtual void Bool(bool) {}
+  virtual void Char(int8_t, const char *) {}
+  virtual void UChar(uint8_t, const char *) {}
+  virtual void Short(int16_t, const char *) {}
+  virtual void UShort(uint16_t, const char *) {}
+  virtual void Int(int32_t, const char *) {}
+  virtual void UInt(uint32_t, const char *) {}
+  virtual void Long(int64_t) {}
+  virtual void ULong(uint64_t) {}
+  virtual void Float(float) {}
+  virtual void Double(double) {}
+  virtual void String(const String *) {}
+  virtual void Unknown(const uint8_t *) {}  // From a future version.
+  // These mark the scope of a vector.
+  virtual void StartVector() {}
+  virtual void EndVector() {}
+  virtual void Element(size_t /*i*/, ElementaryType /*type*/,
+                       const TypeTable * /*type_table*/,
+                       const uint8_t * /*val*/) {}
+  virtual ~IterationVisitor() {}
+};
+
+inline size_t InlineSize(ElementaryType type, const TypeTable *type_table) {
+  switch (type) {
+    case ET_UTYPE:
+    case ET_BOOL:
+    case ET_CHAR:
+    case ET_UCHAR: return 1;
+    case ET_SHORT:
+    case ET_USHORT: return 2;
+    case ET_INT:
+    case ET_UINT:
+    case ET_FLOAT:
+    case ET_STRING: return 4;
+    case ET_LONG:
+    case ET_ULONG:
+    case ET_DOUBLE: return 8;
+    case ET_SEQUENCE:
+      switch (type_table->st) {
+        case ST_TABLE:
+        case ST_UNION: return 4;
+        case ST_STRUCT: return static_cast<size_t>(type_table->values[type_table->num_elems]);
+        default: FLATBUFFERS_ASSERT(false); return 1;
+      }
+    default: FLATBUFFERS_ASSERT(false); return 1;
+  }
+}
+
+inline int64_t LookupEnum(int64_t enum_val, const int64_t *values,
+                          size_t num_values) {
+  if (!values) return enum_val;
+  for (size_t i = 0; i < num_values; i++) {
+    if (enum_val == values[i]) return static_cast<int64_t>(i);
+  }
+  return -1;  // Unknown enum value.
+}
+
+template<typename T> const char *EnumName(T tval, const TypeTable *type_table) {
+  if (!type_table || !type_table->names) return nullptr;
+  auto i = LookupEnum(static_cast<int64_t>(tval), type_table->values,
+                      type_table->num_elems);
+  if (i >= 0 && i < static_cast<int64_t>(type_table->num_elems)) {
+    return type_table->names[i];
+  }
+  return nullptr;
+}
+
+void IterateObject(const uint8_t *obj, const TypeTable *type_table,
+                   IterationVisitor *visitor);
+
+inline void IterateValue(ElementaryType type, const uint8_t *val,
+                         const TypeTable *type_table, const uint8_t *prev_val,
+                         soffset_t vector_index, IterationVisitor *visitor) {
+  switch (type) {
+    case ET_UTYPE: {
+      auto tval = ReadScalar<uint8_t>(val);
+      visitor->UType(tval, EnumName(tval, type_table));
+      break;
+    }
+    case ET_BOOL: {
+      visitor->Bool(ReadScalar<uint8_t>(val) != 0);
+      break;
+    }
+    case ET_CHAR: {
+      auto tval = ReadScalar<int8_t>(val);
+      visitor->Char(tval, EnumName(tval, type_table));
+      break;
+    }
+    case ET_UCHAR: {
+      auto tval = ReadScalar<uint8_t>(val);
+      visitor->UChar(tval, EnumName(tval, type_table));
+      break;
+    }
+    case ET_SHORT: {
+      auto tval = ReadScalar<int16_t>(val);
+      visitor->Short(tval, EnumName(tval, type_table));
+      break;
+    }
+    case ET_USHORT: {
+      auto tval = ReadScalar<uint16_t>(val);
+      visitor->UShort(tval, EnumName(tval, type_table));
+      break;
+    }
+    case ET_INT: {
+      auto tval = ReadScalar<int32_t>(val);
+      visitor->Int(tval, EnumName(tval, type_table));
+      break;
+    }
+    case ET_UINT: {
+      auto tval = ReadScalar<uint32_t>(val);
+      visitor->UInt(tval, EnumName(tval, type_table));
+      break;
+    }
+    case ET_LONG: {
+      visitor->Long(ReadScalar<int64_t>(val));
+      break;
+    }
+    case ET_ULONG: {
+      visitor->ULong(ReadScalar<uint64_t>(val));
+      break;
+    }
+    case ET_FLOAT: {
+      visitor->Float(ReadScalar<float>(val));
+      break;
+    }
+    case ET_DOUBLE: {
+      visitor->Double(ReadScalar<double>(val));
+      break;
+    }
+    case ET_STRING: {
+      val += ReadScalar<uoffset_t>(val);
+      visitor->String(reinterpret_cast<const String *>(val));
+      break;
+    }
+    case ET_SEQUENCE: {
+      switch (type_table->st) {
+        case ST_TABLE:
+          val += ReadScalar<uoffset_t>(val);
+          IterateObject(val, type_table, visitor);
+          break;
+        case ST_STRUCT: IterateObject(val, type_table, visitor); break;
+        case ST_UNION: {
+          val += ReadScalar<uoffset_t>(val);
+          FLATBUFFERS_ASSERT(prev_val);
+          auto union_type = *prev_val;  // Always a uint8_t.
+          if (vector_index >= 0) {
+            auto type_vec = reinterpret_cast<const Vector<uint8_t> *>(prev_val);
+            union_type = type_vec->Get(static_cast<uoffset_t>(vector_index));
+          }
+          auto type_code_idx =
+              LookupEnum(union_type, type_table->values, type_table->num_elems);
+          if (type_code_idx >= 0 &&
+              type_code_idx < static_cast<int32_t>(type_table->num_elems)) {
+            auto type_code = type_table->type_codes[type_code_idx];
+            switch (type_code.base_type) {
+              case ET_SEQUENCE: {
+                auto ref = type_table->type_refs[type_code.sequence_ref]();
+                IterateObject(val, ref, visitor);
+                break;
+              }
+              case ET_STRING:
+                visitor->String(reinterpret_cast<const String *>(val));
+                break;
+              default: visitor->Unknown(val);
+            }
+          } else {
+            visitor->Unknown(val);
+          }
+          break;
+        }
+        case ST_ENUM: FLATBUFFERS_ASSERT(false); break;
+      }
+      break;
+    }
+    default: {
+      visitor->Unknown(val);
+      break;
+    }
+  }
+}
+
+inline void IterateObject(const uint8_t *obj, const TypeTable *type_table,
+                          IterationVisitor *visitor) {
+  visitor->StartSequence();
+  const uint8_t *prev_val = nullptr;
+  size_t set_idx = 0;
+  for (size_t i = 0; i < type_table->num_elems; i++) {
+    auto type_code = type_table->type_codes[i];
+    auto type = static_cast<ElementaryType>(type_code.base_type);
+    auto is_vector = type_code.is_vector != 0;
+    auto ref_idx = type_code.sequence_ref;
+    const TypeTable *ref = nullptr;
+    if (ref_idx >= 0) { ref = type_table->type_refs[ref_idx](); }
+    auto name = type_table->names ? type_table->names[i] : nullptr;
+    const uint8_t *val = nullptr;
+    if (type_table->st == ST_TABLE) {
+      val = reinterpret_cast<const Table *>(obj)->GetAddressOf(
+          FieldIndexToOffset(static_cast<voffset_t>(i)));
+    } else {
+      val = obj + type_table->values[i];
+    }
+    visitor->Field(i, set_idx, type, is_vector, ref, name, val);
+    if (val) {
+      set_idx++;
+      if (is_vector) {
+        val += ReadScalar<uoffset_t>(val);
+        auto vec = reinterpret_cast<const Vector<uint8_t> *>(val);
+        visitor->StartVector();
+        auto elem_ptr = vec->Data();
+        for (size_t j = 0; j < vec->size(); j++) {
+          visitor->Element(j, type, ref, elem_ptr);
+          IterateValue(type, elem_ptr, ref, prev_val, static_cast<soffset_t>(j),
+                       visitor);
+          elem_ptr += InlineSize(type, ref);
+        }
+        visitor->EndVector();
+      } else {
+        IterateValue(type, val, ref, prev_val, -1, visitor);
+      }
+    }
+    prev_val = val;
+  }
+  visitor->EndSequence();
+}
+
+inline void IterateFlatBuffer(const uint8_t *buffer,
+                              const TypeTable *type_table,
+                              IterationVisitor *callback) {
+  IterateObject(GetRoot<uint8_t>(buffer), type_table, callback);
+}
+
+// Outputting a Flatbuffer to a string. Tries to conform as close to JSON /
+// the output generated by idl_gen_text.cpp.
+
+struct ToStringVisitor : public IterationVisitor {
+  std::string s;
+  std::string d;
+  bool q;
+  std::string in;
+  size_t indent_level;
+  bool vector_delimited;
+  ToStringVisitor(std::string delimiter, bool quotes, std::string indent,
+                  bool vdelimited = true)
+      : d(delimiter),
+        q(quotes),
+        in(indent),
+        indent_level(0),
+        vector_delimited(vdelimited) {}
+  ToStringVisitor(std::string delimiter)
+      : d(delimiter),
+        q(false),
+        in(""),
+        indent_level(0),
+        vector_delimited(true) {}
+
+  void append_indent() {
+    for (size_t i = 0; i < indent_level; i++) { s += in; }
+  }
+
+  void StartSequence() {
+    s += "{";
+    s += d;
+    indent_level++;
+  }
+  void EndSequence() {
+    s += d;
+    indent_level--;
+    append_indent();
+    s += "}";
+  }
+  void Field(size_t /*field_idx*/, size_t set_idx, ElementaryType /*type*/,
+             bool /*is_vector*/, const TypeTable * /*type_table*/,
+             const char *name, const uint8_t *val) {
+    if (!val) return;
+    if (set_idx) {
+      s += ",";
+      s += d;
+    }
+    append_indent();
+    if (name) {
+      if (q) s += "\"";
+      s += name;
+      if (q) s += "\"";
+      s += ": ";
+    }
+  }
+  template<typename T> void Named(T x, const char *name) {
+    if (name) {
+      if (q) s += "\"";
+      s += name;
+      if (q) s += "\"";
+    } else {
+      s += NumToString(x);
+    }
+  }
+  void UType(uint8_t x, const char *name) { Named(x, name); }
+  void Bool(bool x) { s += x ? "true" : "false"; }
+  void Char(int8_t x, const char *name) { Named(x, name); }
+  void UChar(uint8_t x, const char *name) { Named(x, name); }
+  void Short(int16_t x, const char *name) { Named(x, name); }
+  void UShort(uint16_t x, const char *name) { Named(x, name); }
+  void Int(int32_t x, const char *name) { Named(x, name); }
+  void UInt(uint32_t x, const char *name) { Named(x, name); }
+  void Long(int64_t x) { s += NumToString(x); }
+  void ULong(uint64_t x) { s += NumToString(x); }
+  void Float(float x) { s += NumToString(x); }
+  void Double(double x) { s += NumToString(x); }
+  void String(const struct String *str) {
+    EscapeString(str->c_str(), str->size(), &s, true, false);
+  }
+  void Unknown(const uint8_t *) { s += "(?)"; }
+  void StartVector() {
+    s += "[";
+    if (vector_delimited) {
+      s += d;
+      indent_level++;
+      append_indent();
+    } else {
+      s += " ";
+    }
+  }
+  void EndVector() {
+    if (vector_delimited) {
+      s += d;
+      indent_level--;
+      append_indent();
+    } else {
+      s += " ";
+    }
+    s += "]";
+  }
+  void Element(size_t i, ElementaryType /*type*/,
+               const TypeTable * /*type_table*/, const uint8_t * /*val*/) {
+    if (i) {
+      s += ",";
+      if (vector_delimited) {
+        s += d;
+        append_indent();
+      } else {
+        s += " ";
+      }
+    }
+  }
+};
+
+inline std::string FlatBufferToString(const uint8_t *buffer,
+                                      const TypeTable *type_table,
+                                      bool multi_line = false,
+                                      bool vector_delimited = true) {
+  ToStringVisitor tostring_visitor(multi_line ? "\n" : " ", false, "",
+                                   vector_delimited);
+  IterateFlatBuffer(buffer, type_table, &tostring_visitor);
+  return tostring_visitor.s;
+}
+
+}  // namespace flatbuffers
+
+#endif  // FLATBUFFERS_MINIREFLECT_H_
diff --git a/third_party/flatbuffers/include/flatbuffers/reflection.h b/third_party/flatbuffers/include/flatbuffers/reflection.h
new file mode 100644
index 0000000..580ae62
--- /dev/null
+++ b/third_party/flatbuffers/include/flatbuffers/reflection.h
@@ -0,0 +1,477 @@
+/*
+ * 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.
+ */
+
+#ifndef FLATBUFFERS_REFLECTION_H_
+#define FLATBUFFERS_REFLECTION_H_
+
+// This is somewhat of a circular dependency because flatc (and thus this
+// file) is needed to generate this header in the first place.
+// Should normally not be a problem since it can be generated by the
+// previous version of flatc whenever this code needs to change.
+// See reflection/generate_code.sh
+#include "flatbuffers/reflection_generated.h"
+
+// Helper functionality for reflection.
+
+namespace flatbuffers {
+
+// ------------------------- GETTERS -------------------------
+
+inline bool IsScalar(reflection::BaseType t) {
+  return t >= reflection::UType && t <= reflection::Double;
+}
+inline bool IsInteger(reflection::BaseType t) {
+  return t >= reflection::UType && t <= reflection::ULong;
+}
+inline bool IsFloat(reflection::BaseType t) {
+  return t == reflection::Float || t == reflection::Double;
+}
+inline bool IsLong(reflection::BaseType t) {
+  return t == reflection::Long || t == reflection::ULong;
+}
+
+// Size of a basic type, don't use with structs.
+inline size_t GetTypeSize(reflection::BaseType base_type) {
+  // This needs to correspond to the BaseType enum.
+  static size_t sizes[] = { 0, 1, 1, 1, 1, 2, 2, 4, 4, 8, 8, 4, 8, 4, 4, 4, 4 };
+  return sizes[base_type];
+}
+
+// Same as above, but now correctly returns the size of a struct if
+// the field (or vector element) is a struct.
+inline size_t GetTypeSizeInline(reflection::BaseType base_type, int type_index,
+                                const reflection::Schema &schema) {
+  if (base_type == reflection::Obj &&
+      schema.objects()->Get(type_index)->is_struct()) {
+    return schema.objects()->Get(type_index)->bytesize();
+  } else {
+    return GetTypeSize(base_type);
+  }
+}
+
+// Get the root, regardless of what type it is.
+inline Table *GetAnyRoot(uint8_t *flatbuf) {
+  return GetMutableRoot<Table>(flatbuf);
+}
+inline const Table *GetAnyRoot(const uint8_t *flatbuf) {
+  return GetRoot<Table>(flatbuf);
+}
+
+// Get a field's default, if you know it's an integer, and its exact type.
+template<typename T> T GetFieldDefaultI(const reflection::Field &field) {
+  FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type()));
+  return static_cast<T>(field.default_integer());
+}
+
+// Get a field's default, if you know it's floating point and its exact type.
+template<typename T> T GetFieldDefaultF(const reflection::Field &field) {
+  FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type()));
+  return static_cast<T>(field.default_real());
+}
+
+// Get a field, if you know it's an integer, and its exact type.
+template<typename T>
+T GetFieldI(const Table &table, const reflection::Field &field) {
+  FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type()));
+  return table.GetField<T>(field.offset(),
+                           static_cast<T>(field.default_integer()));
+}
+
+// Get a field, if you know it's floating point and its exact type.
+template<typename T>
+T GetFieldF(const Table &table, const reflection::Field &field) {
+  FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type()));
+  return table.GetField<T>(field.offset(),
+                           static_cast<T>(field.default_real()));
+}
+
+// Get a field, if you know it's a string.
+inline const String *GetFieldS(const Table &table,
+                               const reflection::Field &field) {
+  FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::String);
+  return table.GetPointer<const String *>(field.offset());
+}
+
+// Get a field, if you know it's a vector.
+template<typename T>
+Vector<T> *GetFieldV(const Table &table, const reflection::Field &field) {
+  FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Vector &&
+                     sizeof(T) == GetTypeSize(field.type()->element()));
+  return table.GetPointer<Vector<T> *>(field.offset());
+}
+
+// Get a field, if you know it's a vector, generically.
+// To actually access elements, use the return value together with
+// field.type()->element() in any of GetAnyVectorElemI below etc.
+inline VectorOfAny *GetFieldAnyV(const Table &table,
+                                 const reflection::Field &field) {
+  return table.GetPointer<VectorOfAny *>(field.offset());
+}
+
+// Get a field, if you know it's a table.
+inline Table *GetFieldT(const Table &table, const reflection::Field &field) {
+  FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj ||
+                     field.type()->base_type() == reflection::Union);
+  return table.GetPointer<Table *>(field.offset());
+}
+
+// Get a field, if you know it's a struct.
+inline const Struct *GetFieldStruct(const Table &table,
+                                    const reflection::Field &field) {
+  // TODO: This does NOT check if the field is a table or struct, but we'd need
+  // access to the schema to check the is_struct flag.
+  FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj);
+  return table.GetStruct<const Struct *>(field.offset());
+}
+
+// Get a structure's field, if you know it's a struct.
+inline const Struct *GetFieldStruct(const Struct &structure,
+                                    const reflection::Field &field) {
+  FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj);
+  return structure.GetStruct<const Struct *>(field.offset());
+}
+
+// Raw helper functions used below: get any value in memory as a 64bit int, a
+// double or a string.
+// All scalars get static_cast to an int64_t, strings use strtoull, every other
+// data type returns 0.
+int64_t GetAnyValueI(reflection::BaseType type, const uint8_t *data);
+// All scalars static cast to double, strings use strtod, every other data
+// type is 0.0.
+double GetAnyValueF(reflection::BaseType type, const uint8_t *data);
+// All scalars converted using stringstream, strings as-is, and all other
+// data types provide some level of debug-pretty-printing.
+std::string GetAnyValueS(reflection::BaseType type, const uint8_t *data,
+                         const reflection::Schema *schema, int type_index);
+
+// Get any table field as a 64bit int, regardless of what type it is.
+inline int64_t GetAnyFieldI(const Table &table,
+                            const reflection::Field &field) {
+  auto field_ptr = table.GetAddressOf(field.offset());
+  return field_ptr ? GetAnyValueI(field.type()->base_type(), field_ptr)
+                   : field.default_integer();
+}
+
+// Get any table field as a double, regardless of what type it is.
+inline double GetAnyFieldF(const Table &table, const reflection::Field &field) {
+  auto field_ptr = table.GetAddressOf(field.offset());
+  return field_ptr ? GetAnyValueF(field.type()->base_type(), field_ptr)
+                   : field.default_real();
+}
+
+// Get any table field as a string, regardless of what type it is.
+// You may pass nullptr for the schema if you don't care to have fields that
+// are of table type pretty-printed.
+inline std::string GetAnyFieldS(const Table &table,
+                                const reflection::Field &field,
+                                const reflection::Schema *schema) {
+  auto field_ptr = table.GetAddressOf(field.offset());
+  return field_ptr ? GetAnyValueS(field.type()->base_type(), field_ptr, schema,
+                                  field.type()->index())
+                   : "";
+}
+
+// Get any struct field as a 64bit int, regardless of what type it is.
+inline int64_t GetAnyFieldI(const Struct &st, const reflection::Field &field) {
+  return GetAnyValueI(field.type()->base_type(),
+                      st.GetAddressOf(field.offset()));
+}
+
+// Get any struct field as a double, regardless of what type it is.
+inline double GetAnyFieldF(const Struct &st, const reflection::Field &field) {
+  return GetAnyValueF(field.type()->base_type(),
+                      st.GetAddressOf(field.offset()));
+}
+
+// Get any struct field as a string, regardless of what type it is.
+inline std::string GetAnyFieldS(const Struct &st,
+                                const reflection::Field &field) {
+  return GetAnyValueS(field.type()->base_type(),
+                      st.GetAddressOf(field.offset()), nullptr, -1);
+}
+
+// Get any vector element as a 64bit int, regardless of what type it is.
+inline int64_t GetAnyVectorElemI(const VectorOfAny *vec,
+                                 reflection::BaseType elem_type, size_t i) {
+  return GetAnyValueI(elem_type, vec->Data() + GetTypeSize(elem_type) * i);
+}
+
+// Get any vector element as a double, regardless of what type it is.
+inline double GetAnyVectorElemF(const VectorOfAny *vec,
+                                reflection::BaseType elem_type, size_t i) {
+  return GetAnyValueF(elem_type, vec->Data() + GetTypeSize(elem_type) * i);
+}
+
+// Get any vector element as a string, regardless of what type it is.
+inline std::string GetAnyVectorElemS(const VectorOfAny *vec,
+                                     reflection::BaseType elem_type, size_t i) {
+  return GetAnyValueS(elem_type, vec->Data() + GetTypeSize(elem_type) * i,
+                      nullptr, -1);
+}
+
+// Get a vector element that's a table/string/vector from a generic vector.
+// Pass Table/String/VectorOfAny as template parameter.
+// Warning: does no typechecking.
+template<typename T>
+T *GetAnyVectorElemPointer(const VectorOfAny *vec, size_t i) {
+  auto elem_ptr = vec->Data() + sizeof(uoffset_t) * i;
+  return reinterpret_cast<T*>(elem_ptr + ReadScalar<uoffset_t>(elem_ptr));
+}
+
+// Get the inline-address of a vector element. Useful for Structs (pass Struct
+// as template arg), or being able to address a range of scalars in-line.
+// Get elem_size from GetTypeSizeInline().
+// Note: little-endian data on all platforms, use EndianScalar() instead of
+// raw pointer access with scalars).
+template<typename T>
+T *GetAnyVectorElemAddressOf(const VectorOfAny *vec, size_t i,
+                             size_t elem_size) {
+  return reinterpret_cast<T *>(vec->Data() + elem_size * i);
+}
+
+// Similarly, for elements of tables.
+template<typename T>
+T *GetAnyFieldAddressOf(const Table &table, const reflection::Field &field) {
+  return reinterpret_cast<T *>(table.GetAddressOf(field.offset()));
+}
+
+// Similarly, for elements of structs.
+template<typename T>
+T *GetAnyFieldAddressOf(const Struct &st, const reflection::Field &field) {
+  return reinterpret_cast<T *>(st.GetAddressOf(field.offset()));
+}
+
+// ------------------------- SETTERS -------------------------
+
+// Set any scalar field, if you know its exact type.
+template<typename T>
+bool SetField(Table *table, const reflection::Field &field, T val) {
+  reflection::BaseType type = field.type()->base_type();
+  if (!IsScalar(type)) { return false; }
+  FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(type));
+  T def;
+  if (IsInteger(type)) {
+    def = GetFieldDefaultI<T>(field);
+  } else {
+    FLATBUFFERS_ASSERT(IsFloat(type));
+    def = GetFieldDefaultF<T>(field);
+  }
+  return table->SetField(field.offset(), val, def);
+}
+
+// Raw helper functions used below: set any value in memory as a 64bit int, a
+// double or a string.
+// These work for all scalar values, but do nothing for other data types.
+// To set a string, see SetString below.
+void SetAnyValueI(reflection::BaseType type, uint8_t *data, int64_t val);
+void SetAnyValueF(reflection::BaseType type, uint8_t *data, double val);
+void SetAnyValueS(reflection::BaseType type, uint8_t *data, const char *val);
+
+// Set any table field as a 64bit int, regardless of type what it is.
+inline bool SetAnyFieldI(Table *table, const reflection::Field &field,
+                         int64_t val) {
+  auto field_ptr = table->GetAddressOf(field.offset());
+  if (!field_ptr) return val == GetFieldDefaultI<int64_t>(field);
+  SetAnyValueI(field.type()->base_type(), field_ptr, val);
+  return true;
+}
+
+// Set any table field as a double, regardless of what type it is.
+inline bool SetAnyFieldF(Table *table, const reflection::Field &field,
+                         double val) {
+  auto field_ptr = table->GetAddressOf(field.offset());
+  if (!field_ptr) return val == GetFieldDefaultF<double>(field);
+  SetAnyValueF(field.type()->base_type(), field_ptr, val);
+  return true;
+}
+
+// Set any table field as a string, regardless of what type it is.
+inline bool SetAnyFieldS(Table *table, const reflection::Field &field,
+                         const char *val) {
+  auto field_ptr = table->GetAddressOf(field.offset());
+  if (!field_ptr) return false;
+  SetAnyValueS(field.type()->base_type(), field_ptr, val);
+  return true;
+}
+
+// Set any struct field as a 64bit int, regardless of type what it is.
+inline void SetAnyFieldI(Struct *st, const reflection::Field &field,
+                         int64_t val) {
+  SetAnyValueI(field.type()->base_type(), st->GetAddressOf(field.offset()),
+               val);
+}
+
+// Set any struct field as a double, regardless of type what it is.
+inline void SetAnyFieldF(Struct *st, const reflection::Field &field,
+                         double val) {
+  SetAnyValueF(field.type()->base_type(), st->GetAddressOf(field.offset()),
+               val);
+}
+
+// Set any struct field as a string, regardless of type what it is.
+inline void SetAnyFieldS(Struct *st, const reflection::Field &field,
+                         const char *val) {
+  SetAnyValueS(field.type()->base_type(), st->GetAddressOf(field.offset()),
+               val);
+}
+
+// Set any vector element as a 64bit int, regardless of type what it is.
+inline void SetAnyVectorElemI(VectorOfAny *vec, reflection::BaseType elem_type,
+                              size_t i, int64_t val) {
+  SetAnyValueI(elem_type, vec->Data() + GetTypeSize(elem_type) * i, val);
+}
+
+// Set any vector element as a double, regardless of type what it is.
+inline void SetAnyVectorElemF(VectorOfAny *vec, reflection::BaseType elem_type,
+                              size_t i, double val) {
+  SetAnyValueF(elem_type, vec->Data() + GetTypeSize(elem_type) * i, val);
+}
+
+// Set any vector element as a string, regardless of type what it is.
+inline void SetAnyVectorElemS(VectorOfAny *vec, reflection::BaseType elem_type,
+                              size_t i, const char *val) {
+  SetAnyValueS(elem_type, vec->Data() + GetTypeSize(elem_type) * i, val);
+}
+
+// ------------------------- RESIZING SETTERS -------------------------
+
+// "smart" pointer for use with resizing vectors: turns a pointer inside
+// a vector into a relative offset, such that it is not affected by resizes.
+template<typename T, typename U> class pointer_inside_vector {
+ public:
+  pointer_inside_vector(T *ptr, std::vector<U> &vec)
+      : offset_(reinterpret_cast<uint8_t *>(ptr) -
+                reinterpret_cast<uint8_t *>(flatbuffers::vector_data(vec))),
+        vec_(vec) {}
+
+  T *operator*() const {
+    return reinterpret_cast<T *>(
+        reinterpret_cast<uint8_t *>(flatbuffers::vector_data(vec_)) + offset_);
+  }
+  T *operator->() const { return operator*(); }
+  void operator=(const pointer_inside_vector &piv);
+
+ private:
+  size_t offset_;
+  std::vector<U> &vec_;
+};
+
+// Helper to create the above easily without specifying template args.
+template<typename T, typename U>
+pointer_inside_vector<T, U> piv(T *ptr, std::vector<U> &vec) {
+  return pointer_inside_vector<T, U>(ptr, vec);
+}
+
+inline const char *UnionTypeFieldSuffix() { return "_type"; }
+
+// Helper to figure out the actual table type a union refers to.
+inline const reflection::Object &GetUnionType(
+    const reflection::Schema &schema, const reflection::Object &parent,
+    const reflection::Field &unionfield, const Table &table) {
+  auto enumdef = schema.enums()->Get(unionfield.type()->index());
+  // TODO: this is clumsy and slow, but no other way to find it?
+  auto type_field = parent.fields()->LookupByKey(
+      (unionfield.name()->str() + UnionTypeFieldSuffix()).c_str());
+  FLATBUFFERS_ASSERT(type_field);
+  auto union_type = GetFieldI<uint8_t>(table, *type_field);
+  auto enumval = enumdef->values()->LookupByKey(union_type);
+  return *enumval->object();
+}
+
+// Changes the contents of a string inside a FlatBuffer. FlatBuffer must
+// live inside a std::vector so we can resize the buffer if needed.
+// "str" must live inside "flatbuf" and may be invalidated after this call.
+// If your FlatBuffer's root table is not the schema's root table, you should
+// pass in your root_table type as well.
+void SetString(const reflection::Schema &schema, const std::string &val,
+               const String *str, std::vector<uint8_t> *flatbuf,
+               const reflection::Object *root_table = nullptr);
+
+// Resizes a flatbuffers::Vector inside a FlatBuffer. FlatBuffer must
+// live inside a std::vector so we can resize the buffer if needed.
+// "vec" must live inside "flatbuf" and may be invalidated after this call.
+// If your FlatBuffer's root table is not the schema's root table, you should
+// pass in your root_table type as well.
+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 = nullptr);
+
+template<typename T>
+void ResizeVector(const reflection::Schema &schema, uoffset_t newsize, T val,
+                  const Vector<T> *vec, std::vector<uint8_t> *flatbuf,
+                  const reflection::Object *root_table = nullptr) {
+  auto delta_elem = static_cast<int>(newsize) - static_cast<int>(vec->size());
+  auto newelems = ResizeAnyVector(
+      schema, newsize, reinterpret_cast<const VectorOfAny *>(vec), vec->size(),
+      static_cast<uoffset_t>(sizeof(T)), flatbuf, root_table);
+  // Set new elements to "val".
+  for (int i = 0; i < delta_elem; i++) {
+    auto loc = newelems + i * sizeof(T);
+    auto is_scalar = flatbuffers::is_scalar<T>::value;
+    if (is_scalar) {
+      WriteScalar(loc, val);
+    } else {  // struct
+      *reinterpret_cast<T *>(loc) = val;
+    }
+  }
+}
+
+// Adds any new data (in the form of a new FlatBuffer) to an existing
+// FlatBuffer. This can be used when any of the above methods are not
+// sufficient, in particular for adding new tables and new fields.
+// This is potentially slightly less efficient than a FlatBuffer constructed
+// in one piece, since the new FlatBuffer doesn't share any vtables with the
+// existing one.
+// The return value can now be set using Vector::MutateOffset or SetFieldT
+// below.
+const uint8_t *AddFlatBuffer(std::vector<uint8_t> &flatbuf,
+                             const uint8_t *newbuf, size_t newlen);
+
+inline bool SetFieldT(Table *table, const reflection::Field &field,
+                      const uint8_t *val) {
+  FLATBUFFERS_ASSERT(sizeof(uoffset_t) ==
+                     GetTypeSize(field.type()->base_type()));
+  return table->SetPointer(field.offset(), val);
+}
+
+// ------------------------- COPYING -------------------------
+
+// Generic copying of tables from a FlatBuffer into a FlatBuffer builder.
+// Can be used to do any kind of merging/selecting you may want to do out
+// of existing buffers. Also useful to reconstruct a whole buffer if the
+// above resizing functionality has introduced garbage in a buffer you want
+// to remove.
+// Note: this does not deal with DAGs correctly. If the table passed forms a
+// DAG, the copy will be a tree instead (with duplicates). Strings can be
+// shared however, by passing true for use_string_pooling.
+
+Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
+                                const reflection::Schema &schema,
+                                const reflection::Object &objectdef,
+                                const Table &table,
+                                bool use_string_pooling = false);
+
+// Verifies the provided flatbuffer using reflection.
+// root should point to the root type for this flatbuffer.
+// buf should point to the start of flatbuffer data.
+// length specifies the size of the flatbuffer data.
+bool Verify(const reflection::Schema &schema, const reflection::Object &root,
+            const uint8_t *buf, size_t length);
+
+}  // namespace flatbuffers
+
+#endif  // FLATBUFFERS_REFLECTION_H_
diff --git a/third_party/flatbuffers/include/flatbuffers/reflection_generated.h b/third_party/flatbuffers/include/flatbuffers/reflection_generated.h
new file mode 100644
index 0000000..0e73a0f
--- /dev/null
+++ b/third_party/flatbuffers/include/flatbuffers/reflection_generated.h
@@ -0,0 +1,1195 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_REFLECTION_REFLECTION_H_
+#define FLATBUFFERS_GENERATED_REFLECTION_REFLECTION_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+namespace reflection {
+
+struct Type;
+
+struct KeyValue;
+
+struct EnumVal;
+
+struct Enum;
+
+struct Field;
+
+struct Object;
+
+struct RPCCall;
+
+struct Service;
+
+struct Schema;
+
+enum BaseType {
+  None = 0,
+  UType = 1,
+  Bool = 2,
+  Byte = 3,
+  UByte = 4,
+  Short = 5,
+  UShort = 6,
+  Int = 7,
+  UInt = 8,
+  Long = 9,
+  ULong = 10,
+  Float = 11,
+  Double = 12,
+  String = 13,
+  Vector = 14,
+  Obj = 15,
+  Union = 16,
+  Array = 17
+};
+
+inline const BaseType (&EnumValuesBaseType())[18] {
+  static const BaseType values[] = {
+    None,
+    UType,
+    Bool,
+    Byte,
+    UByte,
+    Short,
+    UShort,
+    Int,
+    UInt,
+    Long,
+    ULong,
+    Float,
+    Double,
+    String,
+    Vector,
+    Obj,
+    Union,
+    Array
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesBaseType() {
+  static const char * const names[19] = {
+    "None",
+    "UType",
+    "Bool",
+    "Byte",
+    "UByte",
+    "Short",
+    "UShort",
+    "Int",
+    "UInt",
+    "Long",
+    "ULong",
+    "Float",
+    "Double",
+    "String",
+    "Vector",
+    "Obj",
+    "Union",
+    "Array",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameBaseType(BaseType e) {
+  if (e < None || e > Array) return "";
+  const size_t index = static_cast<size_t>(e);
+  return EnumNamesBaseType()[index];
+}
+
+struct Type FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_BASE_TYPE = 4,
+    VT_ELEMENT = 6,
+    VT_INDEX = 8,
+    VT_FIXED_LENGTH = 10
+  };
+  reflection::BaseType base_type() const {
+    return static_cast<reflection::BaseType>(GetField<int8_t>(VT_BASE_TYPE, 0));
+  }
+  reflection::BaseType element() const {
+    return static_cast<reflection::BaseType>(GetField<int8_t>(VT_ELEMENT, 0));
+  }
+  int32_t index() const {
+    return GetField<int32_t>(VT_INDEX, -1);
+  }
+  uint16_t fixed_length() const {
+    return GetField<uint16_t>(VT_FIXED_LENGTH, 0);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<int8_t>(verifier, VT_BASE_TYPE) &&
+           VerifyField<int8_t>(verifier, VT_ELEMENT) &&
+           VerifyField<int32_t>(verifier, VT_INDEX) &&
+           VerifyField<uint16_t>(verifier, VT_FIXED_LENGTH) &&
+           verifier.EndTable();
+  }
+};
+
+struct TypeBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_base_type(reflection::BaseType base_type) {
+    fbb_.AddElement<int8_t>(Type::VT_BASE_TYPE, static_cast<int8_t>(base_type), 0);
+  }
+  void add_element(reflection::BaseType element) {
+    fbb_.AddElement<int8_t>(Type::VT_ELEMENT, static_cast<int8_t>(element), 0);
+  }
+  void add_index(int32_t index) {
+    fbb_.AddElement<int32_t>(Type::VT_INDEX, index, -1);
+  }
+  void add_fixed_length(uint16_t fixed_length) {
+    fbb_.AddElement<uint16_t>(Type::VT_FIXED_LENGTH, fixed_length, 0);
+  }
+  explicit TypeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  TypeBuilder &operator=(const TypeBuilder &);
+  flatbuffers::Offset<Type> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Type>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Type> CreateType(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    reflection::BaseType base_type = reflection::None,
+    reflection::BaseType element = reflection::None,
+    int32_t index = -1,
+    uint16_t fixed_length = 0) {
+  TypeBuilder builder_(_fbb);
+  builder_.add_index(index);
+  builder_.add_fixed_length(fixed_length);
+  builder_.add_element(element);
+  builder_.add_base_type(base_type);
+  return builder_.Finish();
+}
+
+struct KeyValue FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_KEY = 4,
+    VT_VALUE = 6
+  };
+  const flatbuffers::String *key() const {
+    return GetPointer<const flatbuffers::String *>(VT_KEY);
+  }
+  bool KeyCompareLessThan(const KeyValue *o) const {
+    return *key() < *o->key();
+  }
+  int KeyCompareWithValue(const char *val) const {
+    return strcmp(key()->c_str(), val);
+  }
+  const flatbuffers::String *value() const {
+    return GetPointer<const flatbuffers::String *>(VT_VALUE);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffsetRequired(verifier, VT_KEY) &&
+           verifier.VerifyString(key()) &&
+           VerifyOffset(verifier, VT_VALUE) &&
+           verifier.VerifyString(value()) &&
+           verifier.EndTable();
+  }
+};
+
+struct KeyValueBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_key(flatbuffers::Offset<flatbuffers::String> key) {
+    fbb_.AddOffset(KeyValue::VT_KEY, key);
+  }
+  void add_value(flatbuffers::Offset<flatbuffers::String> value) {
+    fbb_.AddOffset(KeyValue::VT_VALUE, value);
+  }
+  explicit KeyValueBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  KeyValueBuilder &operator=(const KeyValueBuilder &);
+  flatbuffers::Offset<KeyValue> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<KeyValue>(end);
+    fbb_.Required(o, KeyValue::VT_KEY);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<KeyValue> CreateKeyValue(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<flatbuffers::String> key = 0,
+    flatbuffers::Offset<flatbuffers::String> value = 0) {
+  KeyValueBuilder builder_(_fbb);
+  builder_.add_value(value);
+  builder_.add_key(key);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<KeyValue> CreateKeyValueDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const char *key = nullptr,
+    const char *value = nullptr) {
+  auto key__ = key ? _fbb.CreateString(key) : 0;
+  auto value__ = value ? _fbb.CreateString(value) : 0;
+  return reflection::CreateKeyValue(
+      _fbb,
+      key__,
+      value__);
+}
+
+struct EnumVal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_NAME = 4,
+    VT_VALUE = 6,
+    VT_OBJECT = 8,
+    VT_UNION_TYPE = 10,
+    VT_DOCUMENTATION = 12
+  };
+  const flatbuffers::String *name() const {
+    return GetPointer<const flatbuffers::String *>(VT_NAME);
+  }
+  int64_t value() const {
+    return GetField<int64_t>(VT_VALUE, 0);
+  }
+  bool KeyCompareLessThan(const EnumVal *o) const {
+    return value() < o->value();
+  }
+  int KeyCompareWithValue(int64_t val) const {
+    return static_cast<int>(value() > val) - static_cast<int>(value() < val);
+  }
+  const reflection::Object *object() const {
+    return GetPointer<const reflection::Object *>(VT_OBJECT);
+  }
+  const reflection::Type *union_type() const {
+    return GetPointer<const reflection::Type *>(VT_UNION_TYPE);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffsetRequired(verifier, VT_NAME) &&
+           verifier.VerifyString(name()) &&
+           VerifyField<int64_t>(verifier, VT_VALUE) &&
+           VerifyOffset(verifier, VT_OBJECT) &&
+           verifier.VerifyTable(object()) &&
+           VerifyOffset(verifier, VT_UNION_TYPE) &&
+           verifier.VerifyTable(union_type()) &&
+           VerifyOffset(verifier, VT_DOCUMENTATION) &&
+           verifier.VerifyVector(documentation()) &&
+           verifier.VerifyVectorOfStrings(documentation()) &&
+           verifier.EndTable();
+  }
+};
+
+struct EnumValBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_name(flatbuffers::Offset<flatbuffers::String> name) {
+    fbb_.AddOffset(EnumVal::VT_NAME, name);
+  }
+  void add_value(int64_t value) {
+    fbb_.AddElement<int64_t>(EnumVal::VT_VALUE, value, 0);
+  }
+  void add_object(flatbuffers::Offset<reflection::Object> object) {
+    fbb_.AddOffset(EnumVal::VT_OBJECT, object);
+  }
+  void add_union_type(flatbuffers::Offset<reflection::Type> union_type) {
+    fbb_.AddOffset(EnumVal::VT_UNION_TYPE, union_type);
+  }
+  void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
+    fbb_.AddOffset(EnumVal::VT_DOCUMENTATION, documentation);
+  }
+  explicit EnumValBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  EnumValBuilder &operator=(const EnumValBuilder &);
+  flatbuffers::Offset<EnumVal> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<EnumVal>(end);
+    fbb_.Required(o, EnumVal::VT_NAME);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<EnumVal> CreateEnumVal(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<flatbuffers::String> name = 0,
+    int64_t value = 0,
+    flatbuffers::Offset<reflection::Object> object = 0,
+    flatbuffers::Offset<reflection::Type> union_type = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
+  EnumValBuilder builder_(_fbb);
+  builder_.add_value(value);
+  builder_.add_documentation(documentation);
+  builder_.add_union_type(union_type);
+  builder_.add_object(object);
+  builder_.add_name(name);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<EnumVal> CreateEnumValDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const char *name = nullptr,
+    int64_t value = 0,
+    flatbuffers::Offset<reflection::Object> object = 0,
+    flatbuffers::Offset<reflection::Type> union_type = 0,
+    const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
+  auto name__ = name ? _fbb.CreateString(name) : 0;
+  auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
+  return reflection::CreateEnumVal(
+      _fbb,
+      name__,
+      value,
+      object,
+      union_type,
+      documentation__);
+}
+
+struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_NAME = 4,
+    VT_VALUES = 6,
+    VT_IS_UNION = 8,
+    VT_UNDERLYING_TYPE = 10,
+    VT_ATTRIBUTES = 12,
+    VT_DOCUMENTATION = 14
+  };
+  const flatbuffers::String *name() const {
+    return GetPointer<const flatbuffers::String *>(VT_NAME);
+  }
+  bool KeyCompareLessThan(const Enum *o) const {
+    return *name() < *o->name();
+  }
+  int KeyCompareWithValue(const char *val) const {
+    return strcmp(name()->c_str(), val);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>> *values() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>> *>(VT_VALUES);
+  }
+  bool is_union() const {
+    return GetField<uint8_t>(VT_IS_UNION, 0) != 0;
+  }
+  const reflection::Type *underlying_type() const {
+    return GetPointer<const reflection::Type *>(VT_UNDERLYING_TYPE);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffsetRequired(verifier, VT_NAME) &&
+           verifier.VerifyString(name()) &&
+           VerifyOffsetRequired(verifier, VT_VALUES) &&
+           verifier.VerifyVector(values()) &&
+           verifier.VerifyVectorOfTables(values()) &&
+           VerifyField<uint8_t>(verifier, VT_IS_UNION) &&
+           VerifyOffsetRequired(verifier, VT_UNDERLYING_TYPE) &&
+           verifier.VerifyTable(underlying_type()) &&
+           VerifyOffset(verifier, VT_ATTRIBUTES) &&
+           verifier.VerifyVector(attributes()) &&
+           verifier.VerifyVectorOfTables(attributes()) &&
+           VerifyOffset(verifier, VT_DOCUMENTATION) &&
+           verifier.VerifyVector(documentation()) &&
+           verifier.VerifyVectorOfStrings(documentation()) &&
+           verifier.EndTable();
+  }
+};
+
+struct EnumBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_name(flatbuffers::Offset<flatbuffers::String> name) {
+    fbb_.AddOffset(Enum::VT_NAME, name);
+  }
+  void add_values(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>>> values) {
+    fbb_.AddOffset(Enum::VT_VALUES, values);
+  }
+  void add_is_union(bool is_union) {
+    fbb_.AddElement<uint8_t>(Enum::VT_IS_UNION, static_cast<uint8_t>(is_union), 0);
+  }
+  void add_underlying_type(flatbuffers::Offset<reflection::Type> underlying_type) {
+    fbb_.AddOffset(Enum::VT_UNDERLYING_TYPE, underlying_type);
+  }
+  void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
+    fbb_.AddOffset(Enum::VT_ATTRIBUTES, attributes);
+  }
+  void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
+    fbb_.AddOffset(Enum::VT_DOCUMENTATION, documentation);
+  }
+  explicit EnumBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  EnumBuilder &operator=(const EnumBuilder &);
+  flatbuffers::Offset<Enum> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Enum>(end);
+    fbb_.Required(o, Enum::VT_NAME);
+    fbb_.Required(o, Enum::VT_VALUES);
+    fbb_.Required(o, Enum::VT_UNDERLYING_TYPE);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Enum> CreateEnum(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<flatbuffers::String> name = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>>> values = 0,
+    bool is_union = false,
+    flatbuffers::Offset<reflection::Type> underlying_type = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
+  EnumBuilder builder_(_fbb);
+  builder_.add_documentation(documentation);
+  builder_.add_attributes(attributes);
+  builder_.add_underlying_type(underlying_type);
+  builder_.add_values(values);
+  builder_.add_name(name);
+  builder_.add_is_union(is_union);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Enum> CreateEnumDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const char *name = nullptr,
+    const std::vector<flatbuffers::Offset<reflection::EnumVal>> *values = nullptr,
+    bool is_union = false,
+    flatbuffers::Offset<reflection::Type> underlying_type = 0,
+    const std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
+    const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
+  auto name__ = name ? _fbb.CreateString(name) : 0;
+  auto values__ = values ? _fbb.CreateVector<flatbuffers::Offset<reflection::EnumVal>>(*values) : 0;
+  auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<reflection::KeyValue>>(*attributes) : 0;
+  auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
+  return reflection::CreateEnum(
+      _fbb,
+      name__,
+      values__,
+      is_union,
+      underlying_type,
+      attributes__,
+      documentation__);
+}
+
+struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_NAME = 4,
+    VT_TYPE = 6,
+    VT_ID = 8,
+    VT_OFFSET = 10,
+    VT_DEFAULT_INTEGER = 12,
+    VT_DEFAULT_REAL = 14,
+    VT_DEPRECATED = 16,
+    VT_REQUIRED = 18,
+    VT_KEY = 20,
+    VT_ATTRIBUTES = 22,
+    VT_DOCUMENTATION = 24
+  };
+  const flatbuffers::String *name() const {
+    return GetPointer<const flatbuffers::String *>(VT_NAME);
+  }
+  bool KeyCompareLessThan(const Field *o) const {
+    return *name() < *o->name();
+  }
+  int KeyCompareWithValue(const char *val) const {
+    return strcmp(name()->c_str(), val);
+  }
+  const reflection::Type *type() const {
+    return GetPointer<const reflection::Type *>(VT_TYPE);
+  }
+  uint16_t id() const {
+    return GetField<uint16_t>(VT_ID, 0);
+  }
+  uint16_t offset() const {
+    return GetField<uint16_t>(VT_OFFSET, 0);
+  }
+  int64_t default_integer() const {
+    return GetField<int64_t>(VT_DEFAULT_INTEGER, 0);
+  }
+  double default_real() const {
+    return GetField<double>(VT_DEFAULT_REAL, 0.0);
+  }
+  bool deprecated() const {
+    return GetField<uint8_t>(VT_DEPRECATED, 0) != 0;
+  }
+  bool required() const {
+    return GetField<uint8_t>(VT_REQUIRED, 0) != 0;
+  }
+  bool key() const {
+    return GetField<uint8_t>(VT_KEY, 0) != 0;
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffsetRequired(verifier, VT_NAME) &&
+           verifier.VerifyString(name()) &&
+           VerifyOffsetRequired(verifier, VT_TYPE) &&
+           verifier.VerifyTable(type()) &&
+           VerifyField<uint16_t>(verifier, VT_ID) &&
+           VerifyField<uint16_t>(verifier, VT_OFFSET) &&
+           VerifyField<int64_t>(verifier, VT_DEFAULT_INTEGER) &&
+           VerifyField<double>(verifier, VT_DEFAULT_REAL) &&
+           VerifyField<uint8_t>(verifier, VT_DEPRECATED) &&
+           VerifyField<uint8_t>(verifier, VT_REQUIRED) &&
+           VerifyField<uint8_t>(verifier, VT_KEY) &&
+           VerifyOffset(verifier, VT_ATTRIBUTES) &&
+           verifier.VerifyVector(attributes()) &&
+           verifier.VerifyVectorOfTables(attributes()) &&
+           VerifyOffset(verifier, VT_DOCUMENTATION) &&
+           verifier.VerifyVector(documentation()) &&
+           verifier.VerifyVectorOfStrings(documentation()) &&
+           verifier.EndTable();
+  }
+};
+
+struct FieldBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_name(flatbuffers::Offset<flatbuffers::String> name) {
+    fbb_.AddOffset(Field::VT_NAME, name);
+  }
+  void add_type(flatbuffers::Offset<reflection::Type> type) {
+    fbb_.AddOffset(Field::VT_TYPE, type);
+  }
+  void add_id(uint16_t id) {
+    fbb_.AddElement<uint16_t>(Field::VT_ID, id, 0);
+  }
+  void add_offset(uint16_t offset) {
+    fbb_.AddElement<uint16_t>(Field::VT_OFFSET, offset, 0);
+  }
+  void add_default_integer(int64_t default_integer) {
+    fbb_.AddElement<int64_t>(Field::VT_DEFAULT_INTEGER, default_integer, 0);
+  }
+  void add_default_real(double default_real) {
+    fbb_.AddElement<double>(Field::VT_DEFAULT_REAL, default_real, 0.0);
+  }
+  void add_deprecated(bool deprecated) {
+    fbb_.AddElement<uint8_t>(Field::VT_DEPRECATED, static_cast<uint8_t>(deprecated), 0);
+  }
+  void add_required(bool required) {
+    fbb_.AddElement<uint8_t>(Field::VT_REQUIRED, static_cast<uint8_t>(required), 0);
+  }
+  void add_key(bool key) {
+    fbb_.AddElement<uint8_t>(Field::VT_KEY, static_cast<uint8_t>(key), 0);
+  }
+  void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
+    fbb_.AddOffset(Field::VT_ATTRIBUTES, attributes);
+  }
+  void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
+    fbb_.AddOffset(Field::VT_DOCUMENTATION, documentation);
+  }
+  explicit FieldBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  FieldBuilder &operator=(const FieldBuilder &);
+  flatbuffers::Offset<Field> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Field>(end);
+    fbb_.Required(o, Field::VT_NAME);
+    fbb_.Required(o, Field::VT_TYPE);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Field> CreateField(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<flatbuffers::String> name = 0,
+    flatbuffers::Offset<reflection::Type> type = 0,
+    uint16_t id = 0,
+    uint16_t offset = 0,
+    int64_t default_integer = 0,
+    double default_real = 0.0,
+    bool deprecated = false,
+    bool required = false,
+    bool key = false,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
+  FieldBuilder builder_(_fbb);
+  builder_.add_default_real(default_real);
+  builder_.add_default_integer(default_integer);
+  builder_.add_documentation(documentation);
+  builder_.add_attributes(attributes);
+  builder_.add_type(type);
+  builder_.add_name(name);
+  builder_.add_offset(offset);
+  builder_.add_id(id);
+  builder_.add_key(key);
+  builder_.add_required(required);
+  builder_.add_deprecated(deprecated);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Field> CreateFieldDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const char *name = nullptr,
+    flatbuffers::Offset<reflection::Type> type = 0,
+    uint16_t id = 0,
+    uint16_t offset = 0,
+    int64_t default_integer = 0,
+    double default_real = 0.0,
+    bool deprecated = false,
+    bool required = false,
+    bool key = false,
+    const std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
+    const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
+  auto name__ = name ? _fbb.CreateString(name) : 0;
+  auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<reflection::KeyValue>>(*attributes) : 0;
+  auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
+  return reflection::CreateField(
+      _fbb,
+      name__,
+      type,
+      id,
+      offset,
+      default_integer,
+      default_real,
+      deprecated,
+      required,
+      key,
+      attributes__,
+      documentation__);
+}
+
+struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_NAME = 4,
+    VT_FIELDS = 6,
+    VT_IS_STRUCT = 8,
+    VT_MINALIGN = 10,
+    VT_BYTESIZE = 12,
+    VT_ATTRIBUTES = 14,
+    VT_DOCUMENTATION = 16
+  };
+  const flatbuffers::String *name() const {
+    return GetPointer<const flatbuffers::String *>(VT_NAME);
+  }
+  bool KeyCompareLessThan(const Object *o) const {
+    return *name() < *o->name();
+  }
+  int KeyCompareWithValue(const char *val) const {
+    return strcmp(name()->c_str(), val);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<reflection::Field>> *fields() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Field>> *>(VT_FIELDS);
+  }
+  bool is_struct() const {
+    return GetField<uint8_t>(VT_IS_STRUCT, 0) != 0;
+  }
+  int32_t minalign() const {
+    return GetField<int32_t>(VT_MINALIGN, 0);
+  }
+  int32_t bytesize() const {
+    return GetField<int32_t>(VT_BYTESIZE, 0);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffsetRequired(verifier, VT_NAME) &&
+           verifier.VerifyString(name()) &&
+           VerifyOffsetRequired(verifier, VT_FIELDS) &&
+           verifier.VerifyVector(fields()) &&
+           verifier.VerifyVectorOfTables(fields()) &&
+           VerifyField<uint8_t>(verifier, VT_IS_STRUCT) &&
+           VerifyField<int32_t>(verifier, VT_MINALIGN) &&
+           VerifyField<int32_t>(verifier, VT_BYTESIZE) &&
+           VerifyOffset(verifier, VT_ATTRIBUTES) &&
+           verifier.VerifyVector(attributes()) &&
+           verifier.VerifyVectorOfTables(attributes()) &&
+           VerifyOffset(verifier, VT_DOCUMENTATION) &&
+           verifier.VerifyVector(documentation()) &&
+           verifier.VerifyVectorOfStrings(documentation()) &&
+           verifier.EndTable();
+  }
+};
+
+struct ObjectBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_name(flatbuffers::Offset<flatbuffers::String> name) {
+    fbb_.AddOffset(Object::VT_NAME, name);
+  }
+  void add_fields(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Field>>> fields) {
+    fbb_.AddOffset(Object::VT_FIELDS, fields);
+  }
+  void add_is_struct(bool is_struct) {
+    fbb_.AddElement<uint8_t>(Object::VT_IS_STRUCT, static_cast<uint8_t>(is_struct), 0);
+  }
+  void add_minalign(int32_t minalign) {
+    fbb_.AddElement<int32_t>(Object::VT_MINALIGN, minalign, 0);
+  }
+  void add_bytesize(int32_t bytesize) {
+    fbb_.AddElement<int32_t>(Object::VT_BYTESIZE, bytesize, 0);
+  }
+  void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
+    fbb_.AddOffset(Object::VT_ATTRIBUTES, attributes);
+  }
+  void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
+    fbb_.AddOffset(Object::VT_DOCUMENTATION, documentation);
+  }
+  explicit ObjectBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  ObjectBuilder &operator=(const ObjectBuilder &);
+  flatbuffers::Offset<Object> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Object>(end);
+    fbb_.Required(o, Object::VT_NAME);
+    fbb_.Required(o, Object::VT_FIELDS);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Object> CreateObject(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<flatbuffers::String> name = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Field>>> fields = 0,
+    bool is_struct = false,
+    int32_t minalign = 0,
+    int32_t bytesize = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
+  ObjectBuilder builder_(_fbb);
+  builder_.add_documentation(documentation);
+  builder_.add_attributes(attributes);
+  builder_.add_bytesize(bytesize);
+  builder_.add_minalign(minalign);
+  builder_.add_fields(fields);
+  builder_.add_name(name);
+  builder_.add_is_struct(is_struct);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Object> CreateObjectDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const char *name = nullptr,
+    const std::vector<flatbuffers::Offset<reflection::Field>> *fields = nullptr,
+    bool is_struct = false,
+    int32_t minalign = 0,
+    int32_t bytesize = 0,
+    const std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
+    const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
+  auto name__ = name ? _fbb.CreateString(name) : 0;
+  auto fields__ = fields ? _fbb.CreateVector<flatbuffers::Offset<reflection::Field>>(*fields) : 0;
+  auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<reflection::KeyValue>>(*attributes) : 0;
+  auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
+  return reflection::CreateObject(
+      _fbb,
+      name__,
+      fields__,
+      is_struct,
+      minalign,
+      bytesize,
+      attributes__,
+      documentation__);
+}
+
+struct RPCCall FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_NAME = 4,
+    VT_REQUEST = 6,
+    VT_RESPONSE = 8,
+    VT_ATTRIBUTES = 10,
+    VT_DOCUMENTATION = 12
+  };
+  const flatbuffers::String *name() const {
+    return GetPointer<const flatbuffers::String *>(VT_NAME);
+  }
+  bool KeyCompareLessThan(const RPCCall *o) const {
+    return *name() < *o->name();
+  }
+  int KeyCompareWithValue(const char *val) const {
+    return strcmp(name()->c_str(), val);
+  }
+  const reflection::Object *request() const {
+    return GetPointer<const reflection::Object *>(VT_REQUEST);
+  }
+  const reflection::Object *response() const {
+    return GetPointer<const reflection::Object *>(VT_RESPONSE);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffsetRequired(verifier, VT_NAME) &&
+           verifier.VerifyString(name()) &&
+           VerifyOffsetRequired(verifier, VT_REQUEST) &&
+           verifier.VerifyTable(request()) &&
+           VerifyOffsetRequired(verifier, VT_RESPONSE) &&
+           verifier.VerifyTable(response()) &&
+           VerifyOffset(verifier, VT_ATTRIBUTES) &&
+           verifier.VerifyVector(attributes()) &&
+           verifier.VerifyVectorOfTables(attributes()) &&
+           VerifyOffset(verifier, VT_DOCUMENTATION) &&
+           verifier.VerifyVector(documentation()) &&
+           verifier.VerifyVectorOfStrings(documentation()) &&
+           verifier.EndTable();
+  }
+};
+
+struct RPCCallBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_name(flatbuffers::Offset<flatbuffers::String> name) {
+    fbb_.AddOffset(RPCCall::VT_NAME, name);
+  }
+  void add_request(flatbuffers::Offset<reflection::Object> request) {
+    fbb_.AddOffset(RPCCall::VT_REQUEST, request);
+  }
+  void add_response(flatbuffers::Offset<reflection::Object> response) {
+    fbb_.AddOffset(RPCCall::VT_RESPONSE, response);
+  }
+  void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
+    fbb_.AddOffset(RPCCall::VT_ATTRIBUTES, attributes);
+  }
+  void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
+    fbb_.AddOffset(RPCCall::VT_DOCUMENTATION, documentation);
+  }
+  explicit RPCCallBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  RPCCallBuilder &operator=(const RPCCallBuilder &);
+  flatbuffers::Offset<RPCCall> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<RPCCall>(end);
+    fbb_.Required(o, RPCCall::VT_NAME);
+    fbb_.Required(o, RPCCall::VT_REQUEST);
+    fbb_.Required(o, RPCCall::VT_RESPONSE);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<RPCCall> CreateRPCCall(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<flatbuffers::String> name = 0,
+    flatbuffers::Offset<reflection::Object> request = 0,
+    flatbuffers::Offset<reflection::Object> response = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
+  RPCCallBuilder builder_(_fbb);
+  builder_.add_documentation(documentation);
+  builder_.add_attributes(attributes);
+  builder_.add_response(response);
+  builder_.add_request(request);
+  builder_.add_name(name);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<RPCCall> CreateRPCCallDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const char *name = nullptr,
+    flatbuffers::Offset<reflection::Object> request = 0,
+    flatbuffers::Offset<reflection::Object> response = 0,
+    const std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
+    const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
+  auto name__ = name ? _fbb.CreateString(name) : 0;
+  auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<reflection::KeyValue>>(*attributes) : 0;
+  auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
+  return reflection::CreateRPCCall(
+      _fbb,
+      name__,
+      request,
+      response,
+      attributes__,
+      documentation__);
+}
+
+struct Service FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_NAME = 4,
+    VT_CALLS = 6,
+    VT_ATTRIBUTES = 8,
+    VT_DOCUMENTATION = 10
+  };
+  const flatbuffers::String *name() const {
+    return GetPointer<const flatbuffers::String *>(VT_NAME);
+  }
+  bool KeyCompareLessThan(const Service *o) const {
+    return *name() < *o->name();
+  }
+  int KeyCompareWithValue(const char *val) const {
+    return strcmp(name()->c_str(), val);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>> *calls() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>> *>(VT_CALLS);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffsetRequired(verifier, VT_NAME) &&
+           verifier.VerifyString(name()) &&
+           VerifyOffset(verifier, VT_CALLS) &&
+           verifier.VerifyVector(calls()) &&
+           verifier.VerifyVectorOfTables(calls()) &&
+           VerifyOffset(verifier, VT_ATTRIBUTES) &&
+           verifier.VerifyVector(attributes()) &&
+           verifier.VerifyVectorOfTables(attributes()) &&
+           VerifyOffset(verifier, VT_DOCUMENTATION) &&
+           verifier.VerifyVector(documentation()) &&
+           verifier.VerifyVectorOfStrings(documentation()) &&
+           verifier.EndTable();
+  }
+};
+
+struct ServiceBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_name(flatbuffers::Offset<flatbuffers::String> name) {
+    fbb_.AddOffset(Service::VT_NAME, name);
+  }
+  void add_calls(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>>> calls) {
+    fbb_.AddOffset(Service::VT_CALLS, calls);
+  }
+  void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
+    fbb_.AddOffset(Service::VT_ATTRIBUTES, attributes);
+  }
+  void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
+    fbb_.AddOffset(Service::VT_DOCUMENTATION, documentation);
+  }
+  explicit ServiceBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  ServiceBuilder &operator=(const ServiceBuilder &);
+  flatbuffers::Offset<Service> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Service>(end);
+    fbb_.Required(o, Service::VT_NAME);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Service> CreateService(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<flatbuffers::String> name = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>>> calls = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
+  ServiceBuilder builder_(_fbb);
+  builder_.add_documentation(documentation);
+  builder_.add_attributes(attributes);
+  builder_.add_calls(calls);
+  builder_.add_name(name);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Service> CreateServiceDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const char *name = nullptr,
+    const std::vector<flatbuffers::Offset<reflection::RPCCall>> *calls = nullptr,
+    const std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
+    const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
+  auto name__ = name ? _fbb.CreateString(name) : 0;
+  auto calls__ = calls ? _fbb.CreateVector<flatbuffers::Offset<reflection::RPCCall>>(*calls) : 0;
+  auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<reflection::KeyValue>>(*attributes) : 0;
+  auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
+  return reflection::CreateService(
+      _fbb,
+      name__,
+      calls__,
+      attributes__,
+      documentation__);
+}
+
+struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_OBJECTS = 4,
+    VT_ENUMS = 6,
+    VT_FILE_IDENT = 8,
+    VT_FILE_EXT = 10,
+    VT_ROOT_TABLE = 12,
+    VT_SERVICES = 14
+  };
+  const flatbuffers::Vector<flatbuffers::Offset<reflection::Object>> *objects() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Object>> *>(VT_OBJECTS);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>> *enums() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>> *>(VT_ENUMS);
+  }
+  const flatbuffers::String *file_ident() const {
+    return GetPointer<const flatbuffers::String *>(VT_FILE_IDENT);
+  }
+  const flatbuffers::String *file_ext() const {
+    return GetPointer<const flatbuffers::String *>(VT_FILE_EXT);
+  }
+  const reflection::Object *root_table() const {
+    return GetPointer<const reflection::Object *>(VT_ROOT_TABLE);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<reflection::Service>> *services() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Service>> *>(VT_SERVICES);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffsetRequired(verifier, VT_OBJECTS) &&
+           verifier.VerifyVector(objects()) &&
+           verifier.VerifyVectorOfTables(objects()) &&
+           VerifyOffsetRequired(verifier, VT_ENUMS) &&
+           verifier.VerifyVector(enums()) &&
+           verifier.VerifyVectorOfTables(enums()) &&
+           VerifyOffset(verifier, VT_FILE_IDENT) &&
+           verifier.VerifyString(file_ident()) &&
+           VerifyOffset(verifier, VT_FILE_EXT) &&
+           verifier.VerifyString(file_ext()) &&
+           VerifyOffset(verifier, VT_ROOT_TABLE) &&
+           verifier.VerifyTable(root_table()) &&
+           VerifyOffset(verifier, VT_SERVICES) &&
+           verifier.VerifyVector(services()) &&
+           verifier.VerifyVectorOfTables(services()) &&
+           verifier.EndTable();
+  }
+};
+
+struct SchemaBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_objects(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Object>>> objects) {
+    fbb_.AddOffset(Schema::VT_OBJECTS, objects);
+  }
+  void add_enums(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>>> enums) {
+    fbb_.AddOffset(Schema::VT_ENUMS, enums);
+  }
+  void add_file_ident(flatbuffers::Offset<flatbuffers::String> file_ident) {
+    fbb_.AddOffset(Schema::VT_FILE_IDENT, file_ident);
+  }
+  void add_file_ext(flatbuffers::Offset<flatbuffers::String> file_ext) {
+    fbb_.AddOffset(Schema::VT_FILE_EXT, file_ext);
+  }
+  void add_root_table(flatbuffers::Offset<reflection::Object> root_table) {
+    fbb_.AddOffset(Schema::VT_ROOT_TABLE, root_table);
+  }
+  void add_services(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Service>>> services) {
+    fbb_.AddOffset(Schema::VT_SERVICES, services);
+  }
+  explicit SchemaBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  SchemaBuilder &operator=(const SchemaBuilder &);
+  flatbuffers::Offset<Schema> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Schema>(end);
+    fbb_.Required(o, Schema::VT_OBJECTS);
+    fbb_.Required(o, Schema::VT_ENUMS);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Schema> CreateSchema(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Object>>> objects = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>>> enums = 0,
+    flatbuffers::Offset<flatbuffers::String> file_ident = 0,
+    flatbuffers::Offset<flatbuffers::String> file_ext = 0,
+    flatbuffers::Offset<reflection::Object> root_table = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Service>>> services = 0) {
+  SchemaBuilder builder_(_fbb);
+  builder_.add_services(services);
+  builder_.add_root_table(root_table);
+  builder_.add_file_ext(file_ext);
+  builder_.add_file_ident(file_ident);
+  builder_.add_enums(enums);
+  builder_.add_objects(objects);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Schema> CreateSchemaDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const std::vector<flatbuffers::Offset<reflection::Object>> *objects = nullptr,
+    const std::vector<flatbuffers::Offset<reflection::Enum>> *enums = nullptr,
+    const char *file_ident = nullptr,
+    const char *file_ext = nullptr,
+    flatbuffers::Offset<reflection::Object> root_table = 0,
+    const std::vector<flatbuffers::Offset<reflection::Service>> *services = nullptr) {
+  auto objects__ = objects ? _fbb.CreateVector<flatbuffers::Offset<reflection::Object>>(*objects) : 0;
+  auto enums__ = enums ? _fbb.CreateVector<flatbuffers::Offset<reflection::Enum>>(*enums) : 0;
+  auto file_ident__ = file_ident ? _fbb.CreateString(file_ident) : 0;
+  auto file_ext__ = file_ext ? _fbb.CreateString(file_ext) : 0;
+  auto services__ = services ? _fbb.CreateVector<flatbuffers::Offset<reflection::Service>>(*services) : 0;
+  return reflection::CreateSchema(
+      _fbb,
+      objects__,
+      enums__,
+      file_ident__,
+      file_ext__,
+      root_table,
+      services__);
+}
+
+inline const reflection::Schema *GetSchema(const void *buf) {
+  return flatbuffers::GetRoot<reflection::Schema>(buf);
+}
+
+inline const reflection::Schema *GetSizePrefixedSchema(const void *buf) {
+  return flatbuffers::GetSizePrefixedRoot<reflection::Schema>(buf);
+}
+
+inline const char *SchemaIdentifier() {
+  return "BFBS";
+}
+
+inline bool SchemaBufferHasIdentifier(const void *buf) {
+  return flatbuffers::BufferHasIdentifier(
+      buf, SchemaIdentifier());
+}
+
+inline bool VerifySchemaBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifyBuffer<reflection::Schema>(SchemaIdentifier());
+}
+
+inline bool VerifySizePrefixedSchemaBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifySizePrefixedBuffer<reflection::Schema>(SchemaIdentifier());
+}
+
+inline const char *SchemaExtension() {
+  return "bfbs";
+}
+
+inline void FinishSchemaBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<reflection::Schema> root) {
+  fbb.Finish(root, SchemaIdentifier());
+}
+
+inline void FinishSizePrefixedSchemaBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<reflection::Schema> root) {
+  fbb.FinishSizePrefixed(root, SchemaIdentifier());
+}
+
+}  // namespace reflection
+
+#endif  // FLATBUFFERS_GENERATED_REFLECTION_REFLECTION_H_
diff --git a/third_party/flatbuffers/include/flatbuffers/registry.h b/third_party/flatbuffers/include/flatbuffers/registry.h
new file mode 100644
index 0000000..9ea425b
--- /dev/null
+++ b/third_party/flatbuffers/include/flatbuffers/registry.h
@@ -0,0 +1,127 @@
+/*
+ * 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.
+ */
+
+#ifndef FLATBUFFERS_REGISTRY_H_
+#define FLATBUFFERS_REGISTRY_H_
+
+#include "flatbuffers/idl.h"
+
+namespace flatbuffers {
+
+// Convenience class to easily parse or generate text for arbitrary FlatBuffers.
+// Simply pre-populate it with all schema filenames that may be in use, and
+// This class will look them up using the file_identifier declared in the
+// schema.
+class Registry {
+ public:
+  // Call this for all schemas that may be in use. The identifier has
+  // a function in the generated code, e.g. MonsterIdentifier().
+  void Register(const char *file_identifier, const char *schema_path) {
+    Schema schema;
+    schema.path_ = schema_path;
+    schemas_[file_identifier] = schema;
+  }
+
+  // Generate text from an arbitrary FlatBuffer by looking up its
+  // file_identifier in the registry.
+  bool FlatBufferToText(const uint8_t *flatbuf, size_t len, std::string *dest) {
+    // Get the identifier out of the buffer.
+    // If the buffer is truncated, exit.
+    if (len < sizeof(uoffset_t) + FlatBufferBuilder::kFileIdentifierLength) {
+      lasterror_ = "buffer truncated";
+      return false;
+    }
+    std::string ident(
+        reinterpret_cast<const char *>(flatbuf) + sizeof(uoffset_t),
+        FlatBufferBuilder::kFileIdentifierLength);
+    // Load and parse the schema.
+    Parser parser;
+    if (!LoadSchema(ident, &parser)) return false;
+    // Now we're ready to generate text.
+    if (!GenerateText(parser, flatbuf, dest)) {
+      lasterror_ = "unable to generate text for FlatBuffer binary";
+      return false;
+    }
+    return true;
+  }
+
+  // Converts a binary buffer to text using one of the schemas in the registry,
+  // use the file_identifier to indicate which.
+  // If DetachedBuffer::data() is null then parsing failed.
+  DetachedBuffer TextToFlatBuffer(const char *text,
+                                  const char *file_identifier) {
+    // Load and parse the schema.
+    Parser parser;
+    if (!LoadSchema(file_identifier, &parser)) return DetachedBuffer();
+    // Parse the text.
+    if (!parser.Parse(text)) {
+      lasterror_ = parser.error_;
+      return DetachedBuffer();
+    }
+    // We have a valid FlatBuffer. Detach it from the builder and return.
+    return parser.builder_.Release();
+  }
+
+  // Modify any parsing / output options used by the other functions.
+  void SetOptions(const IDLOptions &opts) { opts_ = opts; }
+
+  // If schemas used contain include statements, call this function for every
+  // directory the parser should search them for.
+  void AddIncludeDirectory(const char *path) { include_paths_.push_back(path); }
+
+  // Returns a human readable error if any of the above functions fail.
+  const std::string &GetLastError() { return lasterror_; }
+
+ private:
+  bool LoadSchema(const std::string &ident, Parser *parser) {
+    // Find the schema, if not, exit.
+    auto it = schemas_.find(ident);
+    if (it == schemas_.end()) {
+      // Don't attach the identifier, since it may not be human readable.
+      lasterror_ = "identifier for this buffer not in the registry";
+      return false;
+    }
+    auto &schema = it->second;
+    // Load the schema from disk. If not, exit.
+    std::string schematext;
+    if (!LoadFile(schema.path_.c_str(), false, &schematext)) {
+      lasterror_ = "could not load schema: " + schema.path_;
+      return false;
+    }
+    // Parse schema.
+    parser->opts = opts_;
+    if (!parser->Parse(schematext.c_str(), vector_data(include_paths_),
+                       schema.path_.c_str())) {
+      lasterror_ = parser->error_;
+      return false;
+    }
+    return true;
+  }
+
+  struct Schema {
+    std::string path_;
+    // TODO(wvo) optionally cache schema file or parsed schema here.
+  };
+
+  std::string lasterror_;
+  IDLOptions opts_;
+  std::vector<const char *> include_paths_;
+  std::map<std::string, Schema> schemas_;
+};
+
+}  // namespace flatbuffers
+
+#endif  // FLATBUFFERS_REGISTRY_H_
diff --git a/third_party/flatbuffers/include/flatbuffers/stl_emulation.h b/third_party/flatbuffers/include/flatbuffers/stl_emulation.h
new file mode 100644
index 0000000..6f6e766
--- /dev/null
+++ b/third_party/flatbuffers/include/flatbuffers/stl_emulation.h
@@ -0,0 +1,275 @@
+/*
+ * 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.
+ */
+
+#ifndef FLATBUFFERS_STL_EMULATION_H_
+#define FLATBUFFERS_STL_EMULATION_H_
+
+// clang-format off
+
+#include <string>
+#include <type_traits>
+#include <vector>
+#include <memory>
+#include <limits>
+
+#if defined(_STLPORT_VERSION) && !defined(FLATBUFFERS_CPP98_STL)
+  #define FLATBUFFERS_CPP98_STL
+#endif  // defined(_STLPORT_VERSION) && !defined(FLATBUFFERS_CPP98_STL)
+
+#if defined(FLATBUFFERS_CPP98_STL)
+  #include <cctype>
+#endif  // defined(FLATBUFFERS_CPP98_STL)
+
+// Check if we can use template aliases
+// Not possible if Microsoft Compiler before 2012
+// Possible is the language feature __cpp_alias_templates is defined well
+// Or possible if the C++ std is C+11 or newer
+#if (defined(_MSC_VER) && _MSC_VER > 1700 /* MSVC2012 */) \
+    || (defined(__cpp_alias_templates) && __cpp_alias_templates >= 200704) \
+    || (defined(__cplusplus) && __cplusplus >= 201103L)
+  #define FLATBUFFERS_TEMPLATES_ALIASES
+#endif
+
+// This header provides backwards compatibility for C++98 STLs like stlport.
+namespace flatbuffers {
+
+// Retrieve ::back() from a string in a way that is compatible with pre C++11
+// STLs (e.g stlport).
+inline char& string_back(std::string &value) {
+  return value[value.length() - 1];
+}
+
+inline char string_back(const std::string &value) {
+  return value[value.length() - 1];
+}
+
+// Helper method that retrieves ::data() from a vector in a way that is
+// compatible with pre C++11 STLs (e.g stlport).
+template <typename T> inline T *vector_data(std::vector<T> &vector) {
+  // In some debug environments, operator[] does bounds checking, so &vector[0]
+  // can't be used.
+  return vector.empty() ? nullptr : &vector[0];
+}
+
+template <typename T> inline const T *vector_data(
+    const std::vector<T> &vector) {
+  return vector.empty() ? nullptr : &vector[0];
+}
+
+template <typename T, typename V>
+inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
+  #if defined(FLATBUFFERS_CPP98_STL)
+    vector->push_back(data);
+  #else
+    vector->emplace_back(std::forward<V>(data));
+  #endif  // defined(FLATBUFFERS_CPP98_STL)
+}
+
+#ifndef FLATBUFFERS_CPP98_STL
+  #if defined(FLATBUFFERS_TEMPLATES_ALIASES)
+    template <typename T>
+    using numeric_limits = std::numeric_limits<T>;
+  #else
+    template <typename T> class numeric_limits :
+      public std::numeric_limits<T> {};
+  #endif  // defined(FLATBUFFERS_TEMPLATES_ALIASES)
+#else
+  template <typename T> class numeric_limits :
+      public std::numeric_limits<T> {
+    public:
+      // Android NDK fix.
+      static T lowest() {
+        return std::numeric_limits<T>::min();
+      }
+  };
+
+  template <> class numeric_limits<float> : 
+      public std::numeric_limits<float> {
+    public:
+      static float lowest() { return -FLT_MAX; }
+  };
+
+  template <> class numeric_limits<double> : 
+      public std::numeric_limits<double> {
+    public:
+      static double lowest() { return -DBL_MAX; }
+  };
+
+  template <> class numeric_limits<unsigned long long> {
+   public:
+    static unsigned long long min() { return 0ULL; }
+    static unsigned long long max() { return ~0ULL; }
+    static unsigned long long lowest() {
+      return numeric_limits<unsigned long long>::min();
+    }
+  };
+
+  template <> class numeric_limits<long long> {
+   public:
+    static long long min() {
+      return static_cast<long long>(1ULL << ((sizeof(long long) << 3) - 1));
+    }
+    static long long max() {
+      return static_cast<long long>(
+          (1ULL << ((sizeof(long long) << 3) - 1)) - 1);
+    }
+    static long long lowest() {
+      return numeric_limits<long long>::min();
+    }
+  };
+#endif  // FLATBUFFERS_CPP98_STL
+
+#if defined(FLATBUFFERS_TEMPLATES_ALIASES)
+  #ifndef FLATBUFFERS_CPP98_STL
+    template <typename T> using is_scalar = std::is_scalar<T>;
+    template <typename T, typename U> using is_same = std::is_same<T,U>;
+    template <typename T> using is_floating_point = std::is_floating_point<T>;
+    template <typename T> using is_unsigned = std::is_unsigned<T>;
+    template <typename T> using make_unsigned = std::make_unsigned<T>;
+  #else
+    // Map C++ TR1 templates defined by stlport.
+    template <typename T> using is_scalar = std::tr1::is_scalar<T>;
+    template <typename T, typename U> using is_same = std::tr1::is_same<T,U>;
+    template <typename T> using is_floating_point =
+        std::tr1::is_floating_point<T>;
+    template <typename T> using is_unsigned = std::tr1::is_unsigned<T>;
+    // Android NDK doesn't have std::make_unsigned or std::tr1::make_unsigned.
+    template<typename T> struct make_unsigned {
+      static_assert(is_unsigned<T>::value, "Specialization not implemented!");
+      using type = T;
+    };
+    template<> struct make_unsigned<char> { using type = unsigned char; };
+    template<> struct make_unsigned<short> { using type = unsigned short; };
+    template<> struct make_unsigned<int> { using type = unsigned int; };
+    template<> struct make_unsigned<long> { using type = unsigned long; };
+    template<>
+    struct make_unsigned<long long> { using type = unsigned long long; };
+  #endif  // !FLATBUFFERS_CPP98_STL
+#else
+  // MSVC 2010 doesn't support C++11 aliases.
+  template <typename T> struct is_scalar : public std::is_scalar<T> {};
+  template <typename T, typename U> struct is_same : public std::is_same<T,U> {};
+  template <typename T> struct is_floating_point :
+        public std::is_floating_point<T> {};
+  template <typename T> struct is_unsigned : public std::is_unsigned<T> {};
+  template <typename T> struct make_unsigned : public std::make_unsigned<T> {};
+#endif  // defined(FLATBUFFERS_TEMPLATES_ALIASES)
+
+#ifndef FLATBUFFERS_CPP98_STL
+  #if defined(FLATBUFFERS_TEMPLATES_ALIASES)
+    template <class T> using unique_ptr = std::unique_ptr<T>;
+  #else
+    // MSVC 2010 doesn't support C++11 aliases.
+    // We're manually "aliasing" the class here as we want to bring unique_ptr
+    // into the flatbuffers namespace.  We have unique_ptr in the flatbuffers
+    // namespace we have a completely independent implemenation (see below)
+    // for C++98 STL implementations.
+    template <class T> class unique_ptr : public std::unique_ptr<T> {
+     public:
+      unique_ptr() {}
+      explicit unique_ptr(T* p) : std::unique_ptr<T>(p) {}
+      unique_ptr(std::unique_ptr<T>&& u) { *this = std::move(u); }
+      unique_ptr(unique_ptr&& u) { *this = std::move(u); }
+      unique_ptr& operator=(std::unique_ptr<T>&& u) {
+        std::unique_ptr<T>::reset(u.release());
+        return *this;
+      }
+      unique_ptr& operator=(unique_ptr&& u) {
+        std::unique_ptr<T>::reset(u.release());
+        return *this;
+      }
+      unique_ptr& operator=(T* p) {
+        return std::unique_ptr<T>::operator=(p);
+      }
+    };
+  #endif  // defined(FLATBUFFERS_TEMPLATES_ALIASES)
+#else
+  // Very limited implementation of unique_ptr.
+  // This is provided simply to allow the C++ code generated from the default
+  // settings to function in C++98 environments with no modifications.
+  template <class T> class unique_ptr {
+   public:
+    typedef T element_type;
+
+    unique_ptr() : ptr_(nullptr) {}
+    explicit unique_ptr(T* p) : ptr_(p) {}
+    unique_ptr(unique_ptr&& u) : ptr_(nullptr) { reset(u.release()); }
+    unique_ptr(const unique_ptr& u) : ptr_(nullptr) {
+      reset(const_cast<unique_ptr*>(&u)->release());
+    }
+    ~unique_ptr() { reset(); }
+
+    unique_ptr& operator=(const unique_ptr& u) {
+      reset(const_cast<unique_ptr*>(&u)->release());
+      return *this;
+    }
+
+    unique_ptr& operator=(unique_ptr&& u) {
+      reset(u.release());
+      return *this;
+    }
+
+    unique_ptr& operator=(T* p) {
+      reset(p);
+      return *this;
+    }
+
+    const T& operator*() const { return *ptr_; }
+    T* operator->() const { return ptr_; }
+    T* get() const noexcept { return ptr_; }
+    explicit operator bool() const { return ptr_ != nullptr; }
+
+    // modifiers
+    T* release() {
+      T* value = ptr_;
+      ptr_ = nullptr;
+      return value;
+    }
+
+    void reset(T* p = nullptr) {
+      T* value = ptr_;
+      ptr_ = p;
+      if (value) delete value;
+    }
+
+    void swap(unique_ptr& u) {
+      T* temp_ptr = ptr_;
+      ptr_ = u.ptr_;
+      u.ptr_ = temp_ptr;
+    }
+
+   private:
+    T* ptr_;
+  };
+
+  template <class T> bool operator==(const unique_ptr<T>& x,
+                                     const unique_ptr<T>& y) {
+    return x.get() == y.get();
+  }
+
+  template <class T, class D> bool operator==(const unique_ptr<T>& x,
+                                              const D* y) {
+    return static_cast<D*>(x.get()) == y;
+  }
+
+  template <class T> bool operator==(const unique_ptr<T>& x, intptr_t y) {
+    return reinterpret_cast<intptr_t>(x.get()) == y;
+  }
+#endif  // !FLATBUFFERS_CPP98_STL
+
+}  // namespace flatbuffers
+
+#endif  // FLATBUFFERS_STL_EMULATION_H_
diff --git a/third_party/flatbuffers/include/flatbuffers/util.h b/third_party/flatbuffers/include/flatbuffers/util.h
new file mode 100644
index 0000000..072fe9e
--- /dev/null
+++ b/third_party/flatbuffers/include/flatbuffers/util.h
@@ -0,0 +1,657 @@
+/*
+ * 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.
+ */
+
+#ifndef FLATBUFFERS_UTIL_H_
+#define FLATBUFFERS_UTIL_H_
+
+#include "flatbuffers/base.h"
+
+#include <errno.h>
+
+#ifndef FLATBUFFERS_PREFER_PRINTF
+#  include <sstream>
+#else  // FLATBUFFERS_PREFER_PRINTF
+#  include <float.h>
+#  include <stdio.h>
+#endif  // FLATBUFFERS_PREFER_PRINTF
+
+#include <iomanip>
+#include <string>
+
+namespace flatbuffers {
+
+// @locale-independent functions for ASCII characters set.
+
+// Fast checking that character lies in closed range: [a <= x <= b]
+// using one compare (conditional branch) operator.
+inline bool check_ascii_range(char x, char a, char b) {
+  FLATBUFFERS_ASSERT(a <= b);
+  // (Hacker's Delight): `a <= x <= b` <=> `(x-a) <={u} (b-a)`.
+  // The x, a, b will be promoted to int and subtracted without overflow.
+  return static_cast<unsigned int>(x - a) <= static_cast<unsigned int>(b - a);
+}
+
+// Case-insensitive isalpha
+inline bool is_alpha(char c) {
+  // ASCII only: alpha to upper case => reset bit 0x20 (~0x20 = 0xDF).
+  return check_ascii_range(c & 0xDF, 'a' & 0xDF, 'z' & 0xDF);
+}
+
+// Check (case-insensitive) that `c` is equal to alpha.
+inline bool is_alpha_char(char c, char alpha) {
+  FLATBUFFERS_ASSERT(is_alpha(alpha));
+  // ASCII only: alpha to upper case => reset bit 0x20 (~0x20 = 0xDF).
+  return ((c & 0xDF) == (alpha & 0xDF));
+}
+
+// https://en.cppreference.com/w/cpp/string/byte/isxdigit
+// isdigit and isxdigit are the only standard narrow character classification
+// functions that are not affected by the currently installed C locale. although
+// some implementations (e.g. Microsoft in 1252 codepage) may classify
+// additional single-byte characters as digits.
+inline bool is_digit(char c) { return check_ascii_range(c, '0', '9'); }
+
+inline bool is_xdigit(char c) {
+  // Replace by look-up table.
+  return is_digit(c) || check_ascii_range(c & 0xDF, 'a' & 0xDF, 'f' & 0xDF);
+}
+
+// Case-insensitive isalnum
+inline bool is_alnum(char c) { return is_alpha(c) || is_digit(c); }
+
+// @end-locale-independent functions for ASCII character set
+
+#ifdef FLATBUFFERS_PREFER_PRINTF
+template<typename T> size_t IntToDigitCount(T t) {
+  size_t digit_count = 0;
+  // Count the sign for negative numbers
+  if (t < 0) digit_count++;
+  // Count a single 0 left of the dot for fractional numbers
+  if (-1 < t && t < 1) digit_count++;
+  // Count digits until fractional part
+  T eps = std::numeric_limits<float>::epsilon();
+  while (t <= (-1 + eps) || (1 - eps) <= t) {
+    t /= 10;
+    digit_count++;
+  }
+  return digit_count;
+}
+
+template<typename T> size_t NumToStringWidth(T t, int precision = 0) {
+  size_t string_width = IntToDigitCount(t);
+  // Count the dot for floating point numbers
+  if (precision) string_width += (precision + 1);
+  return string_width;
+}
+
+template<typename T>
+std::string NumToStringImplWrapper(T t, const char *fmt, int precision = 0) {
+  size_t string_width = NumToStringWidth(t, precision);
+  std::string s(string_width, 0x00);
+  // Allow snprintf to use std::string trailing null to detect buffer overflow
+  snprintf(const_cast<char *>(s.data()), (s.size() + 1), fmt, string_width, t);
+  return s;
+}
+#endif  // FLATBUFFERS_PREFER_PRINTF
+
+// Convert an integer or floating point value to a string.
+// In contrast to std::stringstream, "char" values are
+// converted to a string of digits, and we don't use scientific notation.
+template<typename T> std::string NumToString(T t) {
+  // clang-format off
+
+  #ifndef FLATBUFFERS_PREFER_PRINTF
+    std::stringstream ss;
+    ss << t;
+    return ss.str();
+  #else // FLATBUFFERS_PREFER_PRINTF
+    auto v = static_cast<long long>(t);
+    return NumToStringImplWrapper(v, "%.*lld");
+  #endif // FLATBUFFERS_PREFER_PRINTF
+  // clang-format on
+}
+// Avoid char types used as character data.
+template<> inline std::string NumToString<signed char>(signed char t) {
+  return NumToString(static_cast<int>(t));
+}
+template<> inline std::string NumToString<unsigned char>(unsigned char t) {
+  return NumToString(static_cast<int>(t));
+}
+template<> inline std::string NumToString<char>(char t) {
+  return NumToString(static_cast<int>(t));
+}
+#if defined(FLATBUFFERS_CPP98_STL)
+template<> inline std::string NumToString<long long>(long long t) {
+  char buf[21];  // (log((1 << 63) - 1) / log(10)) + 2
+  snprintf(buf, sizeof(buf), "%lld", t);
+  return std::string(buf);
+}
+
+template<>
+inline std::string NumToString<unsigned long long>(unsigned long long t) {
+  char buf[22];  // (log((1 << 63) - 1) / log(10)) + 1
+  snprintf(buf, sizeof(buf), "%llu", t);
+  return std::string(buf);
+}
+#endif  // defined(FLATBUFFERS_CPP98_STL)
+
+// Special versions for floats/doubles.
+template<typename T> std::string FloatToString(T t, int precision) {
+  // clang-format off
+
+  #ifndef FLATBUFFERS_PREFER_PRINTF
+    // to_string() prints different numbers of digits for floats depending on
+    // platform and isn't available on Android, so we use stringstream
+    std::stringstream ss;
+    // Use std::fixed to suppress scientific notation.
+    ss << std::fixed;
+    // Default precision is 6, we want that to be higher for doubles.
+    ss << std::setprecision(precision);
+    ss << t;
+    auto s = ss.str();
+  #else // FLATBUFFERS_PREFER_PRINTF
+    auto v = static_cast<double>(t);
+    auto s = NumToStringImplWrapper(v, "%0.*f", precision);
+  #endif // FLATBUFFERS_PREFER_PRINTF
+  // clang-format on
+  // Sadly, std::fixed turns "1" into "1.00000", so here we undo that.
+  auto p = s.find_last_not_of('0');
+  if (p != std::string::npos) {
+    // Strip trailing zeroes. If it is a whole number, keep one zero.
+    s.resize(p + (s[p] == '.' ? 2 : 1));
+  }
+  return s;
+}
+
+template<> inline std::string NumToString<double>(double t) {
+  return FloatToString(t, 12);
+}
+template<> inline std::string NumToString<float>(float t) {
+  return FloatToString(t, 6);
+}
+
+// Convert an integer value to a hexadecimal string.
+// The returned string length is always xdigits long, prefixed by 0 digits.
+// For example, IntToStringHex(0x23, 8) returns the string "00000023".
+inline std::string IntToStringHex(int i, int xdigits) {
+  FLATBUFFERS_ASSERT(i >= 0);
+  // clang-format off
+
+  #ifndef FLATBUFFERS_PREFER_PRINTF
+    std::stringstream ss;
+    ss << std::setw(xdigits) << std::setfill('0') << std::hex << std::uppercase
+       << i;
+    return ss.str();
+  #else // FLATBUFFERS_PREFER_PRINTF
+    return NumToStringImplWrapper(i, "%.*X", xdigits);
+  #endif // FLATBUFFERS_PREFER_PRINTF
+  // clang-format on
+}
+
+// clang-format off
+// Use locale independent functions {strtod_l, strtof_l, strtoll_l, strtoull_l}.
+#if defined(FLATBUFFERS_LOCALE_INDEPENDENT) && (FLATBUFFERS_LOCALE_INDEPENDENT > 0)
+  class ClassicLocale {
+    #ifdef _MSC_VER
+      typedef _locale_t locale_type;
+    #else
+      typedef locale_t locale_type;  // POSIX.1-2008 locale_t type
+    #endif
+    ClassicLocale();
+    ~ClassicLocale();
+    locale_type locale_;
+    static ClassicLocale instance_;
+  public:
+    static locale_type Get() { return instance_.locale_; }
+  };
+
+  #ifdef _MSC_VER
+    #define __strtoull_impl(s, pe, b) _strtoui64_l(s, pe, b, ClassicLocale::Get())
+    #define __strtoll_impl(s, pe, b) _strtoi64_l(s, pe, b, ClassicLocale::Get())
+    #define __strtod_impl(s, pe) _strtod_l(s, pe, ClassicLocale::Get())
+    #define __strtof_impl(s, pe) _strtof_l(s, pe, ClassicLocale::Get())
+  #else
+    #define __strtoull_impl(s, pe, b) strtoull_l(s, pe, b, ClassicLocale::Get())
+    #define __strtoll_impl(s, pe, b) strtoll_l(s, pe, b, ClassicLocale::Get())
+    #define __strtod_impl(s, pe) strtod_l(s, pe, ClassicLocale::Get())
+    #define __strtof_impl(s, pe) strtof_l(s, pe, ClassicLocale::Get())
+  #endif
+#else
+  #define __strtod_impl(s, pe) strtod(s, pe)
+  #define __strtof_impl(s, pe) static_cast<float>(strtod(s, pe))
+  #ifdef _MSC_VER
+    #define __strtoull_impl(s, pe, b) _strtoui64(s, pe, b)
+    #define __strtoll_impl(s, pe, b) _strtoi64(s, pe, b)
+  #else
+    #define __strtoull_impl(s, pe, b) strtoull(s, pe, b)
+    #define __strtoll_impl(s, pe, b) strtoll(s, pe, b)
+  #endif
+#endif
+
+inline void strtoval_impl(int64_t *val, const char *str, char **endptr,
+                                 int base) {
+    *val = __strtoll_impl(str, endptr, base);
+}
+
+inline void strtoval_impl(uint64_t *val, const char *str, char **endptr,
+                                 int base) {
+  *val = __strtoull_impl(str, endptr, base);
+}
+
+inline void strtoval_impl(double *val, const char *str, char **endptr) {
+  *val = __strtod_impl(str, endptr);
+}
+
+// UBSAN: double to float is safe if numeric_limits<float>::is_iec559 is true.
+__supress_ubsan__("float-cast-overflow")
+inline void strtoval_impl(float *val, const char *str, char **endptr) {
+  *val = __strtof_impl(str, endptr);
+}
+#undef __strtoull_impl
+#undef __strtoll_impl
+#undef __strtod_impl
+#undef __strtof_impl
+// clang-format on
+
+// Adaptor for strtoull()/strtoll().
+// Flatbuffers accepts numbers with any count of leading zeros (-009 is -9),
+// while strtoll with base=0 interprets first leading zero as octal prefix.
+// In future, it is possible to add prefixed 0b0101.
+// 1) Checks errno code for overflow condition (out of range).
+// 2) If base <= 0, function try to detect base of number by prefix.
+//
+// Return value (like strtoull and strtoll, but reject partial result):
+// - If successful, an integer value corresponding to the str is returned.
+// - If full string conversion can't be performed, 0 is returned.
+// - If the converted value falls out of range of corresponding return type, a
+// range error occurs. In this case value MAX(T)/MIN(T) is returned.
+template<typename T>
+inline bool StringToIntegerImpl(T *val, const char *const str,
+                                const int base = 0,
+                                const bool check_errno = true) {
+  // T is int64_t or uint64_T
+  FLATBUFFERS_ASSERT(str);
+  if (base <= 0) {
+    auto s = str;
+    while (*s && !is_digit(*s)) s++;
+    if (s[0] == '0' && is_alpha_char(s[1], 'X'))
+      return StringToIntegerImpl(val, str, 16, check_errno);
+    // if a prefix not match, try base=10
+    return StringToIntegerImpl(val, str, 10, check_errno);
+  } else {
+    if (check_errno) errno = 0;  // clear thread-local errno
+    auto endptr = str;
+    strtoval_impl(val, str, const_cast<char **>(&endptr), base);
+    if ((*endptr != '\0') || (endptr == str)) {
+      *val = 0;      // erase partial result
+      return false;  // invalid string
+    }
+    // errno is out-of-range, return MAX/MIN
+    if (check_errno && errno) return false;
+    return true;
+  }
+}
+
+template<typename T>
+inline bool StringToFloatImpl(T *val, const char *const str) {
+  // Type T must be either float or double.
+  FLATBUFFERS_ASSERT(str && val);
+  auto end = str;
+  strtoval_impl(val, str, const_cast<char **>(&end));
+  auto done = (end != str) && (*end == '\0');
+  if (!done) *val = 0;  // erase partial result
+  return done;
+}
+
+// Convert a string to an instance of T.
+// Return value (matched with StringToInteger64Impl and strtod):
+// - If successful, a numeric value corresponding to the str is returned.
+// - If full string conversion can't be performed, 0 is returned.
+// - If the converted value falls out of range of corresponding return type, a
+// range error occurs. In this case value MAX(T)/MIN(T) is returned.
+template<typename T> inline bool StringToNumber(const char *s, T *val) {
+  FLATBUFFERS_ASSERT(s && val);
+  int64_t i64;
+  // The errno check isn't needed, will return MAX/MIN on overflow.
+  if (StringToIntegerImpl(&i64, s, 0, false)) {
+    const int64_t max = (flatbuffers::numeric_limits<T>::max)();
+    const int64_t min = flatbuffers::numeric_limits<T>::lowest();
+    if (i64 > max) {
+      *val = static_cast<T>(max);
+      return false;
+    }
+    if (i64 < min) {
+      // For unsigned types return max to distinguish from
+      // "no conversion can be performed" when 0 is returned.
+      *val = static_cast<T>(flatbuffers::is_unsigned<T>::value ? max : min);
+      return false;
+    }
+    *val = static_cast<T>(i64);
+    return true;
+  }
+  *val = 0;
+  return false;
+}
+
+template<> inline bool StringToNumber<int64_t>(const char *str, int64_t *val) {
+  return StringToIntegerImpl(val, str);
+}
+
+template<>
+inline bool StringToNumber<uint64_t>(const char *str, uint64_t *val) {
+  if (!StringToIntegerImpl(val, str)) return false;
+  // The strtoull accepts negative numbers:
+  // If the minus sign was part of the input sequence, the numeric value
+  // calculated from the sequence of digits is negated as if by unary minus
+  // in the result type, which applies unsigned integer wraparound rules.
+  // Fix this behaviour (except -0).
+  if (*val) {
+    auto s = str;
+    while (*s && !is_digit(*s)) s++;
+    s = (s > str) ? (s - 1) : s;  // step back to one symbol
+    if (*s == '-') {
+      // For unsigned types return the max to distinguish from
+      // "no conversion can be performed".
+      *val = (flatbuffers::numeric_limits<uint64_t>::max)();
+      return false;
+    }
+  }
+  return true;
+}
+
+template<> inline bool StringToNumber(const char *s, float *val) {
+  return StringToFloatImpl(val, s);
+}
+
+template<> inline bool StringToNumber(const char *s, double *val) {
+  return StringToFloatImpl(val, s);
+}
+
+inline int64_t StringToInt(const char *s, int base = 10) {
+  int64_t val;
+  return StringToIntegerImpl(&val, s, base) ? val : 0;
+}
+
+inline uint64_t StringToUInt(const char *s, int base = 10) {
+  uint64_t val;
+  return StringToIntegerImpl(&val, s, base) ? val : 0;
+}
+
+typedef bool (*LoadFileFunction)(const char *filename, bool binary,
+                                 std::string *dest);
+typedef bool (*FileExistsFunction)(const char *filename);
+
+LoadFileFunction SetLoadFileFunction(LoadFileFunction load_file_function);
+
+FileExistsFunction SetFileExistsFunction(
+    FileExistsFunction file_exists_function);
+
+// Check if file "name" exists.
+bool FileExists(const char *name);
+
+// Check if "name" exists and it is also a directory.
+bool DirExists(const char *name);
+
+// Load file "name" into "buf" returning true if successful
+// false otherwise.  If "binary" is false data is read
+// using ifstream's text mode, otherwise data is read with
+// no transcoding.
+bool LoadFile(const char *name, bool binary, std::string *buf);
+
+// Save data "buf" of length "len" bytes into a file
+// "name" returning true if successful, false otherwise.
+// If "binary" is false data is written using ifstream's
+// text mode, otherwise data is written with no
+// transcoding.
+bool SaveFile(const char *name, const char *buf, size_t len, bool binary);
+
+// Save data "buf" into file "name" returning true if
+// successful, false otherwise.  If "binary" is false
+// data is written using ifstream's text mode, otherwise
+// data is written with no transcoding.
+inline bool SaveFile(const char *name, const std::string &buf, bool binary) {
+  return SaveFile(name, buf.c_str(), buf.size(), binary);
+}
+
+// Functionality for minimalistic portable path handling.
+
+// The functions below behave correctly regardless of whether posix ('/') or
+// Windows ('/' or '\\') separators are used.
+
+// Any new separators inserted are always posix.
+FLATBUFFERS_CONSTEXPR char kPathSeparator = '/';
+
+// Returns the path with the extension, if any, removed.
+std::string StripExtension(const std::string &filepath);
+
+// Returns the extension, if any.
+std::string GetExtension(const std::string &filepath);
+
+// Return the last component of the path, after the last separator.
+std::string StripPath(const std::string &filepath);
+
+// Strip the last component of the path + separator.
+std::string StripFileName(const std::string &filepath);
+
+// Concatenates a path with a filename, regardless of wether the path
+// ends in a separator or not.
+std::string ConCatPathFileName(const std::string &path,
+                               const std::string &filename);
+
+// Replaces any '\\' separators with '/'
+std::string PosixPath(const char *path);
+
+// This function ensure a directory exists, by recursively
+// creating dirs for any parts of the path that don't exist yet.
+void EnsureDirExists(const std::string &filepath);
+
+// Obtains the absolute path from any other path.
+// Returns the input path if the absolute path couldn't be resolved.
+std::string AbsolutePath(const std::string &filepath);
+
+// To and from UTF-8 unicode conversion functions
+
+// Convert a unicode code point into a UTF-8 representation by appending it
+// to a string. Returns the number of bytes generated.
+inline int ToUTF8(uint32_t ucc, std::string *out) {
+  FLATBUFFERS_ASSERT(!(ucc & 0x80000000));  // Top bit can't be set.
+  // 6 possible encodings: http://en.wikipedia.org/wiki/UTF-8
+  for (int i = 0; i < 6; i++) {
+    // Max bits this encoding can represent.
+    uint32_t max_bits = 6 + i * 5 + static_cast<int>(!i);
+    if (ucc < (1u << max_bits)) {  // does it fit?
+      // Remaining bits not encoded in the first byte, store 6 bits each
+      uint32_t remain_bits = i * 6;
+      // Store first byte:
+      (*out) += static_cast<char>((0xFE << (max_bits - remain_bits)) |
+                                  (ucc >> remain_bits));
+      // Store remaining bytes:
+      for (int j = i - 1; j >= 0; j--) {
+        (*out) += static_cast<char>(((ucc >> (j * 6)) & 0x3F) | 0x80);
+      }
+      return i + 1;  // Return the number of bytes added.
+    }
+  }
+  FLATBUFFERS_ASSERT(0);  // Impossible to arrive here.
+  return -1;
+}
+
+// Converts whatever prefix of the incoming string corresponds to a valid
+// UTF-8 sequence into a unicode code. The incoming pointer will have been
+// advanced past all bytes parsed.
+// returns -1 upon corrupt UTF-8 encoding (ignore the incoming pointer in
+// this case).
+inline int FromUTF8(const char **in) {
+  int len = 0;
+  // Count leading 1 bits.
+  for (int mask = 0x80; mask >= 0x04; mask >>= 1) {
+    if (**in & mask) {
+      len++;
+    } else {
+      break;
+    }
+  }
+  if ((static_cast<unsigned char>(**in) << len) & 0x80)
+    return -1;  // Bit after leading 1's must be 0.
+  if (!len) return *(*in)++;
+  // UTF-8 encoded values with a length are between 2 and 4 bytes.
+  if (len < 2 || len > 4) { return -1; }
+  // Grab initial bits of the code.
+  int ucc = *(*in)++ & ((1 << (7 - len)) - 1);
+  for (int i = 0; i < len - 1; i++) {
+    if ((**in & 0xC0) != 0x80) return -1;  // Upper bits must 1 0.
+    ucc <<= 6;
+    ucc |= *(*in)++ & 0x3F;  // Grab 6 more bits of the code.
+  }
+  // UTF-8 cannot encode values between 0xD800 and 0xDFFF (reserved for
+  // UTF-16 surrogate pairs).
+  if (ucc >= 0xD800 && ucc <= 0xDFFF) { return -1; }
+  // UTF-8 must represent code points in their shortest possible encoding.
+  switch (len) {
+    case 2:
+      // Two bytes of UTF-8 can represent code points from U+0080 to U+07FF.
+      if (ucc < 0x0080 || ucc > 0x07FF) { return -1; }
+      break;
+    case 3:
+      // Three bytes of UTF-8 can represent code points from U+0800 to U+FFFF.
+      if (ucc < 0x0800 || ucc > 0xFFFF) { return -1; }
+      break;
+    case 4:
+      // Four bytes of UTF-8 can represent code points from U+10000 to U+10FFFF.
+      if (ucc < 0x10000 || ucc > 0x10FFFF) { return -1; }
+      break;
+  }
+  return ucc;
+}
+
+#ifndef FLATBUFFERS_PREFER_PRINTF
+// Wraps a string to a maximum length, inserting new lines where necessary. Any
+// existing whitespace will be collapsed down to a single space. A prefix or
+// suffix can be provided, which will be inserted before or after a wrapped
+// line, respectively.
+inline std::string WordWrap(const std::string in, size_t max_length,
+                            const std::string wrapped_line_prefix,
+                            const std::string wrapped_line_suffix) {
+  std::istringstream in_stream(in);
+  std::string wrapped, line, word;
+
+  in_stream >> word;
+  line = word;
+
+  while (in_stream >> word) {
+    if ((line.length() + 1 + word.length() + wrapped_line_suffix.length()) <
+        max_length) {
+      line += " " + word;
+    } else {
+      wrapped += line + wrapped_line_suffix + "\n";
+      line = wrapped_line_prefix + word;
+    }
+  }
+  wrapped += line;
+
+  return wrapped;
+}
+#endif  // !FLATBUFFERS_PREFER_PRINTF
+
+inline bool EscapeString(const char *s, size_t length, std::string *_text,
+                         bool allow_non_utf8, bool natural_utf8) {
+  std::string &text = *_text;
+  text += "\"";
+  for (uoffset_t i = 0; i < length; i++) {
+    char c = s[i];
+    switch (c) {
+      case '\n': text += "\\n"; break;
+      case '\t': text += "\\t"; break;
+      case '\r': text += "\\r"; break;
+      case '\b': text += "\\b"; break;
+      case '\f': text += "\\f"; break;
+      case '\"': text += "\\\""; break;
+      case '\\': text += "\\\\"; break;
+      default:
+        if (c >= ' ' && c <= '~') {
+          text += c;
+        } else {
+          // Not printable ASCII data. Let's see if it's valid UTF-8 first:
+          const char *utf8 = s + i;
+          int ucc = FromUTF8(&utf8);
+          if (ucc < 0) {
+            if (allow_non_utf8) {
+              text += "\\x";
+              text += IntToStringHex(static_cast<uint8_t>(c), 2);
+            } else {
+              // There are two cases here:
+              //
+              // 1) We reached here by parsing an IDL file. In that case,
+              // we previously checked for non-UTF-8, so we shouldn't reach
+              // here.
+              //
+              // 2) We reached here by someone calling GenerateText()
+              // on a previously-serialized flatbuffer. The data might have
+              // non-UTF-8 Strings, or might be corrupt.
+              //
+              // In both cases, we have to give up and inform the caller
+              // they have no JSON.
+              return false;
+            }
+          } else {
+            if (natural_utf8) {
+              // utf8 points to past all utf-8 bytes parsed
+              text.append(s + i, static_cast<size_t>(utf8 - s - i));
+            } else if (ucc <= 0xFFFF) {
+              // Parses as Unicode within JSON's \uXXXX range, so use that.
+              text += "\\u";
+              text += IntToStringHex(ucc, 4);
+            } else if (ucc <= 0x10FFFF) {
+              // Encode Unicode SMP values to a surrogate pair using two \u
+              // escapes.
+              uint32_t base = ucc - 0x10000;
+              auto high_surrogate = (base >> 10) + 0xD800;
+              auto low_surrogate = (base & 0x03FF) + 0xDC00;
+              text += "\\u";
+              text += IntToStringHex(high_surrogate, 4);
+              text += "\\u";
+              text += IntToStringHex(low_surrogate, 4);
+            }
+            // Skip past characters recognized.
+            i = static_cast<uoffset_t>(utf8 - s - 1);
+          }
+        }
+        break;
+    }
+  }
+  text += "\"";
+  return true;
+}
+
+// Remove paired quotes in a string: "text"|'text' -> text.
+std::string RemoveStringQuotes(const std::string &s);
+
+// Change th global C-locale to locale with name <locale_name>.
+// Returns an actual locale name in <_value>, useful if locale_name is "" or
+// null.
+bool SetGlobalTestLocale(const char *locale_name,
+                         std::string *_value = nullptr);
+
+// Read (or test) a value of environment variable.
+bool ReadEnvironmentVariable(const char *var_name,
+                             std::string *_value = nullptr);
+
+// MSVC specific: Send all assert reports to STDOUT to prevent CI hangs.
+void SetupDefaultCRTReportMode();
+
+}  // namespace flatbuffers
+
+#endif  // FLATBUFFERS_UTIL_H_
diff --git a/third_party/flatbuffers/java/com/google/flatbuffers/ByteBufferUtil.java b/third_party/flatbuffers/java/com/google/flatbuffers/ByteBufferUtil.java
new file mode 100644
index 0000000..624dc4e
--- /dev/null
+++ b/third_party/flatbuffers/java/com/google/flatbuffers/ByteBufferUtil.java
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+package com.google.flatbuffers;
+
+import static com.google.flatbuffers.Constants.*;
+
+import java.nio.ByteBuffer;
+
+/// @file
+/// @addtogroup flatbuffers_java_api
+/// @{
+
+/**
+ * Class that collects utility functions around `ByteBuffer`.
+ */
+public class ByteBufferUtil {
+
+	/**
+     * Extract the size prefix from a `ByteBuffer`.
+     * 
+     * @param bb a size-prefixed buffer
+     * @return the size prefix
+     */
+    public static int getSizePrefix(ByteBuffer bb) {
+        return bb.getInt(bb.position());
+    }
+
+	/**
+     * Create a duplicate of a size-prefixed `ByteBuffer` that has its position
+     * advanced just past the size prefix.
+     * 
+     * @param bb a size-prefixed buffer
+     * @return a new buffer on the same underlying data that has skipped the
+     *         size prefix
+     */
+    public static ByteBuffer removeSizePrefix(ByteBuffer bb) {
+        ByteBuffer s = bb.duplicate();
+        s.position(s.position() + SIZE_PREFIX_LENGTH);
+        return s;
+    }
+
+}
+
+/// @}
diff --git a/third_party/flatbuffers/java/com/google/flatbuffers/Constants.java b/third_party/flatbuffers/java/com/google/flatbuffers/Constants.java
new file mode 100644
index 0000000..e974a80
--- /dev/null
+++ b/third_party/flatbuffers/java/com/google/flatbuffers/Constants.java
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+package com.google.flatbuffers;
+
+/// @cond FLATBUFFERS_INTERNAL
+
+/**
+ * Class that holds shared constants
+ */
+public class Constants {
+    // Java doesn't seem to have these.
+    /** The number of bytes in an `byte`. */
+    static final int SIZEOF_BYTE = 1;
+    /** The number of bytes in a `short`. */
+    static final int SIZEOF_SHORT = 2;
+    /** The number of bytes in an `int`. */
+    static final int SIZEOF_INT = 4;
+    /** The number of bytes in an `float`. */
+    static final int SIZEOF_FLOAT = 4;
+    /** The number of bytes in an `long`. */
+    static final int SIZEOF_LONG = 8;
+    /** The number of bytes in an `double`. */
+    static final int SIZEOF_DOUBLE = 8;
+    /** The number of bytes in a file identifier. */
+    static final int FILE_IDENTIFIER_LENGTH = 4;
+    /** The number of bytes in a size prefix. */
+    public static final int SIZE_PREFIX_LENGTH = 4;
+    /** A version identifier to force a compile error if someone
+    accidentally tries to build generated code with a runtime of
+    two mismatched version. Versions need to always match, as
+    the runtime and generated code are modified in sync.
+    Changes to the Java implementation need to be sure to change
+    the version here and in the code generator on every possible
+    incompatible change */
+    public static void FLATBUFFERS_1_11_1() {}
+}
+
+/// @endcond
diff --git a/third_party/flatbuffers/java/com/google/flatbuffers/FlatBufferBuilder.java b/third_party/flatbuffers/java/com/google/flatbuffers/FlatBufferBuilder.java
new file mode 100644
index 0000000..f224610
--- /dev/null
+++ b/third_party/flatbuffers/java/com/google/flatbuffers/FlatBufferBuilder.java
@@ -0,0 +1,1012 @@
+/*
+ * 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.
+ */
+
+package com.google.flatbuffers;
+
+import static com.google.flatbuffers.Constants.*;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.*;
+import java.util.Arrays;
+
+/// @file
+/// @addtogroup flatbuffers_java_api
+/// @{
+
+/**
+ * Class that helps you build a FlatBuffer.  See the section
+ * "Use in Java/C#" in the main FlatBuffers documentation.
+ */
+public class FlatBufferBuilder {
+    /// @cond FLATBUFFERS_INTERNAL
+    ByteBuffer bb;                  // Where we construct the FlatBuffer.
+    int space;                      // Remaining space in the ByteBuffer.
+    int minalign = 1;               // Minimum alignment encountered so far.
+    int[] vtable = null;            // The vtable for the current table.
+    int vtable_in_use = 0;          // The amount of fields we're actually using.
+    boolean nested = false;         // Whether we are currently serializing a table.
+    boolean finished = false;       // Whether the buffer is finished.
+    int object_start;               // Starting offset of the current struct/table.
+    int[] vtables = new int[16];    // List of offsets of all vtables.
+    int num_vtables = 0;            // Number of entries in `vtables` in use.
+    int vector_num_elems = 0;       // For the current vector being built.
+    boolean force_defaults = false; // False omits default values from the serialized data.
+    ByteBufferFactory bb_factory;   // Factory for allocating the internal buffer
+    final Utf8 utf8;                // UTF-8 encoder to use
+    /// @endcond
+
+    /**
+     * Start with a buffer of size `initial_size`, then grow as required.
+     *
+     * @param initial_size The initial size of the internal buffer to use.
+     * @param bb_factory The factory to be used for allocating the internal buffer
+     */
+    public FlatBufferBuilder(int initial_size, ByteBufferFactory bb_factory) {
+        this(initial_size, bb_factory, null, Utf8.getDefault());
+    }
+
+    /**
+     * Start with a buffer of size `initial_size`, then grow as required.
+     *
+     * @param initial_size The initial size of the internal buffer to use.
+     * @param bb_factory The factory to be used for allocating the internal buffer
+     * @param existing_bb The byte buffer to reuse.
+     * @param utf8 The Utf8 codec
+     */
+    public FlatBufferBuilder(int initial_size, ByteBufferFactory bb_factory,
+                             ByteBuffer existing_bb, Utf8 utf8) {
+        if (initial_size <= 0) {
+          initial_size = 1;
+        }
+        space = initial_size;
+        this.bb_factory = bb_factory;
+        if (existing_bb != null) {
+          bb = existing_bb;
+          bb.clear();
+          bb.order(ByteOrder.LITTLE_ENDIAN);
+        } else {
+          bb = bb_factory.newByteBuffer(initial_size);
+        }
+        this.utf8 = utf8;
+    }
+
+   /**
+    * Start with a buffer of size `initial_size`, then grow as required.
+    *
+    * @param initial_size The initial size of the internal buffer to use.
+    */
+    public FlatBufferBuilder(int initial_size) {
+        this(initial_size, HeapByteBufferFactory.INSTANCE, null, Utf8.getDefault());
+    }
+
+    /**
+     * Start with a buffer of 1KiB, then grow as required.
+     */
+    public FlatBufferBuilder() {
+        this(1024);
+    }
+
+    /**
+     * Alternative constructor allowing reuse of {@link ByteBuffer}s.  The builder
+     * can still grow the buffer as necessary.  User classes should make sure
+     * to call {@link #dataBuffer()} to obtain the resulting encoded message.
+     *
+     * @param existing_bb The byte buffer to reuse.
+     * @param bb_factory The factory to be used for allocating a new internal buffer if
+     *                   the existing buffer needs to grow
+     */
+    public FlatBufferBuilder(ByteBuffer existing_bb, ByteBufferFactory bb_factory) {
+        this(existing_bb.capacity(), bb_factory, existing_bb, Utf8.getDefault());
+    }
+
+    /**
+     * Alternative constructor allowing reuse of {@link ByteBuffer}s.  The builder
+     * can still grow the buffer as necessary.  User classes should make sure
+     * to call {@link #dataBuffer()} to obtain the resulting encoded message.
+     *
+     * @param existing_bb The byte buffer to reuse.
+     */
+    public FlatBufferBuilder(ByteBuffer existing_bb) {
+        this(existing_bb, new HeapByteBufferFactory());
+    }
+
+    /**
+     * Alternative initializer that allows reusing this object on an existing
+     * `ByteBuffer`. This method resets the builder's internal state, but keeps
+     * objects that have been allocated for temporary storage.
+     *
+     * @param existing_bb The byte buffer to reuse.
+     * @param bb_factory The factory to be used for allocating a new internal buffer if
+     *                   the existing buffer needs to grow
+     * @return Returns `this`.
+     */
+    public FlatBufferBuilder init(ByteBuffer existing_bb, ByteBufferFactory bb_factory){
+        this.bb_factory = bb_factory;
+        bb = existing_bb;
+        bb.clear();
+        bb.order(ByteOrder.LITTLE_ENDIAN);
+        minalign = 1;
+        space = bb.capacity();
+        vtable_in_use = 0;
+        nested = false;
+        finished = false;
+        object_start = 0;
+        num_vtables = 0;
+        vector_num_elems = 0;
+        return this;
+    }
+
+    /**
+     * An interface that provides a user of the FlatBufferBuilder class the ability to specify
+     * the method in which the internal buffer gets allocated. This allows for alternatives
+     * to the default behavior, which is to allocate memory for a new byte-array
+     * backed `ByteBuffer` array inside the JVM.
+     *
+     * The FlatBufferBuilder class contains the HeapByteBufferFactory class to
+     * preserve the default behavior in the event that the user does not provide
+     * their own implementation of this interface.
+     */
+    public static abstract class ByteBufferFactory {
+        /**
+         * Create a `ByteBuffer` with a given capacity.
+         * The returned ByteBuf must have a ByteOrder.LITTLE_ENDIAN ByteOrder.
+         *
+         * @param capacity The size of the `ByteBuffer` to allocate.
+         * @return Returns the new `ByteBuffer` that was allocated.
+         */
+        public abstract ByteBuffer newByteBuffer(int capacity);
+
+        /**
+         * Release a ByteBuffer. Current {@link FlatBufferBuilder}
+         * released any reference to it, so it is safe to dispose the buffer
+         * or return it to a pool.
+         * It is not guaranteed that the buffer has been created
+         * with {@link #newByteBuffer(int) }.
+         *
+         * @param bb the buffer to release
+         */
+        public void releaseByteBuffer(ByteBuffer bb) {
+        }
+    }
+
+    /**
+     * An implementation of the ByteBufferFactory interface that is used when
+     * one is not provided by the user.
+     *
+     * Allocate memory for a new byte-array backed `ByteBuffer` array inside the JVM.
+     */
+    public static final class HeapByteBufferFactory extends ByteBufferFactory {
+
+        public static final HeapByteBufferFactory INSTANCE = new HeapByteBufferFactory();
+
+        @Override
+        public ByteBuffer newByteBuffer(int capacity) {
+            return ByteBuffer.allocate(capacity).order(ByteOrder.LITTLE_ENDIAN);
+        }
+    }
+
+    /**
+     * Reset the FlatBufferBuilder by purging all data that it holds.
+     */
+    public void clear(){
+        space = bb.capacity();
+        bb.clear();
+        minalign = 1;
+        while(vtable_in_use > 0) vtable[--vtable_in_use] = 0;
+        vtable_in_use = 0;
+        nested = false;
+        finished = false;
+        object_start = 0;
+        num_vtables = 0;
+        vector_num_elems = 0;
+    }
+
+    /**
+     * Doubles the size of the backing {@link ByteBuffer} and copies the old data towards the
+     * end of the new buffer (since we build the buffer backwards).
+     *
+     * @param bb The current buffer with the existing data.
+     * @param bb_factory The factory to be used for allocating the new internal buffer
+     * @return A new byte buffer with the old data copied copied to it.  The data is
+     * located at the end of the buffer.
+     */
+    static ByteBuffer growByteBuffer(ByteBuffer bb, ByteBufferFactory bb_factory) {
+        int old_buf_size = bb.capacity();
+        if ((old_buf_size & 0xC0000000) != 0)  // Ensure we don't grow beyond what fits in an int.
+            throw new AssertionError("FlatBuffers: cannot grow buffer beyond 2 gigabytes.");
+        int new_buf_size = old_buf_size == 0 ? 1 : old_buf_size << 1;
+        bb.position(0);
+        ByteBuffer nbb = bb_factory.newByteBuffer(new_buf_size);
+        nbb.position(new_buf_size - old_buf_size);
+        nbb.put(bb);
+        return nbb;
+    }
+
+   /**
+    * Offset relative to the end of the buffer.
+    *
+    * @return Offset relative to the end of the buffer.
+    */
+    public int offset() {
+        return bb.capacity() - space;
+    }
+
+   /**
+    * Add zero valued bytes to prepare a new entry to be added.
+    *
+    * @param byte_size Number of bytes to add.
+    */
+    public void pad(int byte_size) {
+        for (int i = 0; i < byte_size; i++) bb.put(--space, (byte)0);
+    }
+
+   /**
+    * Prepare to write an element of `size` after `additional_bytes`
+    * have been written, e.g. if you write a string, you need to align such
+    * the int length field is aligned to {@link com.google.flatbuffers.Constants#SIZEOF_INT}, and
+    * the string data follows it directly.  If all you need to do is alignment, `additional_bytes`
+    * will be 0.
+    *
+    * @param size This is the of the new element to write.
+    * @param additional_bytes The padding size.
+    */
+    public void prep(int size, int additional_bytes) {
+        // Track the biggest thing we've ever aligned to.
+        if (size > minalign) minalign = size;
+        // Find the amount of alignment needed such that `size` is properly
+        // aligned after `additional_bytes`
+        int align_size = ((~(bb.capacity() - space + additional_bytes)) + 1) & (size - 1);
+        // Reallocate the buffer if needed.
+        while (space < align_size + size + additional_bytes) {
+            int old_buf_size = bb.capacity();
+            ByteBuffer old = bb;
+            bb = growByteBuffer(old, bb_factory);
+            if (old != bb) {
+                bb_factory.releaseByteBuffer(old);
+            }
+            space += bb.capacity() - old_buf_size;
+        }
+        pad(align_size);
+    }
+
+    /**
+     * Add a `boolean` to the buffer, backwards from the current location. Doesn't align nor
+     * check for space.
+     *
+     * @param x A `boolean` to put into the buffer.
+     */
+    public void putBoolean(boolean x) { bb.put      (space -= Constants.SIZEOF_BYTE, (byte)(x ? 1 : 0)); }
+
+    /**
+     * Add a `byte` to the buffer, backwards from the current location. Doesn't align nor
+     * check for space.
+     *
+     * @param x A `byte` to put into the buffer.
+     */
+    public void putByte   (byte    x) { bb.put      (space -= Constants.SIZEOF_BYTE, x); }
+
+    /**
+     * Add a `short` to the buffer, backwards from the current location. Doesn't align nor
+     * check for space.
+     *
+     * @param x A `short` to put into the buffer.
+     */
+    public void putShort  (short   x) { bb.putShort (space -= Constants.SIZEOF_SHORT, x); }
+
+    /**
+     * Add an `int` to the buffer, backwards from the current location. Doesn't align nor
+     * check for space.
+     *
+     * @param x An `int` to put into the buffer.
+     */
+    public void putInt    (int     x) { bb.putInt   (space -= Constants.SIZEOF_INT, x); }
+
+    /**
+     * Add a `long` to the buffer, backwards from the current location. Doesn't align nor
+     * check for space.
+     *
+     * @param x A `long` to put into the buffer.
+     */
+    public void putLong   (long    x) { bb.putLong  (space -= Constants.SIZEOF_LONG, x); }
+
+    /**
+     * Add a `float` to the buffer, backwards from the current location. Doesn't align nor
+     * check for space.
+     *
+     * @param x A `float` to put into the buffer.
+     */
+    public void putFloat  (float   x) { bb.putFloat (space -= Constants.SIZEOF_FLOAT, x); }
+
+    /**
+     * Add a `double` to the buffer, backwards from the current location. Doesn't align nor
+     * check for space.
+     *
+     * @param x A `double` to put into the buffer.
+     */
+    public void putDouble (double  x) { bb.putDouble(space -= Constants.SIZEOF_DOUBLE, x); }
+    /// @endcond
+
+    /**
+     * Add a `boolean` to the buffer, properly aligned, and grows the buffer (if necessary).
+     *
+     * @param x A `boolean` to put into the buffer.
+     */
+    public void addBoolean(boolean x) { prep(Constants.SIZEOF_BYTE, 0); putBoolean(x); }
+
+    /**
+     * Add a `byte` to the buffer, properly aligned, and grows the buffer (if necessary).
+     *
+     * @param x A `byte` to put into the buffer.
+     */
+    public void addByte   (byte    x) { prep(Constants.SIZEOF_BYTE, 0); putByte   (x); }
+
+    /**
+     * Add a `short` to the buffer, properly aligned, and grows the buffer (if necessary).
+     *
+     * @param x A `short` to put into the buffer.
+     */
+    public void addShort  (short   x) { prep(Constants.SIZEOF_SHORT, 0); putShort  (x); }
+
+    /**
+     * Add an `int` to the buffer, properly aligned, and grows the buffer (if necessary).
+     *
+     * @param x An `int` to put into the buffer.
+     */
+    public void addInt    (int     x) { prep(Constants.SIZEOF_INT, 0); putInt    (x); }
+
+    /**
+     * Add a `long` to the buffer, properly aligned, and grows the buffer (if necessary).
+     *
+     * @param x A `long` to put into the buffer.
+     */
+    public void addLong   (long    x) { prep(Constants.SIZEOF_LONG, 0); putLong   (x); }
+
+    /**
+     * Add a `float` to the buffer, properly aligned, and grows the buffer (if necessary).
+     *
+     * @param x A `float` to put into the buffer.
+     */
+    public void addFloat  (float   x) { prep(Constants.SIZEOF_FLOAT, 0); putFloat  (x); }
+
+    /**
+     * Add a `double` to the buffer, properly aligned, and grows the buffer (if necessary).
+     *
+     * @param x A `double` to put into the buffer.
+     */
+    public void addDouble (double  x) { prep(Constants.SIZEOF_DOUBLE, 0); putDouble (x); }
+
+   /**
+    * Adds on offset, relative to where it will be written.
+    *
+    * @param off The offset to add.
+    */
+    public void addOffset(int off) {
+        prep(SIZEOF_INT, 0);  // Ensure alignment is already done.
+        assert off <= offset();
+        off = offset() - off + SIZEOF_INT;
+        putInt(off);
+    }
+
+   /// @cond FLATBUFFERS_INTERNAL
+   /**
+    * Start a new array/vector of objects.  Users usually will not call
+    * this directly.  The `FlatBuffers` compiler will create a start/end
+    * method for vector types in generated code.
+    * <p>
+    * The expected sequence of calls is:
+    * <ol>
+    * <li>Start the array using this method.</li>
+    * <li>Call {@link #addOffset(int)} `num_elems` number of times to set
+    * the offset of each element in the array.</li>
+    * <li>Call {@link #endVector()} to retrieve the offset of the array.</li>
+    * </ol>
+    * <p>
+    * For example, to create an array of strings, do:
+    * <pre>{@code
+    * // Need 10 strings
+    * FlatBufferBuilder builder = new FlatBufferBuilder(existingBuffer);
+    * int[] offsets = new int[10];
+    *
+    * for (int i = 0; i < 10; i++) {
+    *   offsets[i] = fbb.createString(" " + i);
+    * }
+    *
+    * // Have the strings in the buffer, but don't have a vector.
+    * // Add a vector that references the newly created strings:
+    * builder.startVector(4, offsets.length, 4);
+    *
+    * // Add each string to the newly created vector
+    * // The strings are added in reverse order since the buffer
+    * // is filled in back to front
+    * for (int i = offsets.length - 1; i >= 0; i--) {
+    *   builder.addOffset(offsets[i]);
+    * }
+    *
+    * // Finish off the vector
+    * int offsetOfTheVector = fbb.endVector();
+    * }</pre>
+    *
+    * @param elem_size The size of each element in the array.
+    * @param num_elems The number of elements in the array.
+    * @param alignment The alignment of the array.
+    */
+    public void startVector(int elem_size, int num_elems, int alignment) {
+        notNested();
+        vector_num_elems = num_elems;
+        prep(SIZEOF_INT, elem_size * num_elems);
+        prep(alignment, elem_size * num_elems); // Just in case alignment > int.
+        nested = true;
+    }
+
+   /**
+    * Finish off the creation of an array and all its elements.  The array
+    * must be created with {@link #startVector(int, int, int)}.
+    *
+    * @return The offset at which the newly created array starts.
+    * @see #startVector(int, int, int)
+    */
+    public int endVector() {
+        if (!nested)
+            throw new AssertionError("FlatBuffers: endVector called without startVector");
+        nested = false;
+        putInt(vector_num_elems);
+        return offset();
+    }
+    /// @endcond
+
+    /**
+     * Create a new array/vector and return a ByteBuffer to be filled later.
+     * Call {@link #endVector} after this method to get an offset to the beginning
+     * of vector.
+     *
+     * @param elem_size the size of each element in bytes.
+     * @param num_elems number of elements in the vector.
+     * @param alignment byte alignment.
+     * @return ByteBuffer with position and limit set to the space allocated for the array.
+     */
+    public ByteBuffer createUnintializedVector(int elem_size, int num_elems, int alignment) {
+        int length = elem_size * num_elems;
+        startVector(elem_size, num_elems, alignment);
+
+        bb.position(space -= length);
+
+        // Slice and limit the copy vector to point to the 'array'
+        ByteBuffer copy = bb.slice().order(ByteOrder.LITTLE_ENDIAN);
+        copy.limit(length);
+        return copy;
+    }
+
+   /**
+     * Create a vector of tables.
+     *
+     * @param offsets Offsets of the tables.
+     * @return Returns offset of the vector.
+     */
+    public int createVectorOfTables(int[] offsets) {
+        notNested();
+        startVector(Constants.SIZEOF_INT, offsets.length, Constants.SIZEOF_INT);
+        for(int i = offsets.length - 1; i >= 0; i--) addOffset(offsets[i]);
+        return endVector();
+    }
+
+    /**
+     * Create a vector of sorted by the key tables.
+     *
+     * @param obj Instance of the table subclass.
+     * @param offsets Offsets of the tables.
+     * @return Returns offset of the sorted vector.
+     */
+    public <T extends Table> int createSortedVectorOfTables(T obj, int[] offsets) {
+        obj.sortTables(offsets, bb);
+        return createVectorOfTables(offsets);
+    }
+
+   /**
+    * Encode the string `s` in the buffer using UTF-8.  If {@code s} is
+    * already a {@link CharBuffer}, this method is allocation free.
+    *
+    * @param s The string to encode.
+    * @return The offset in the buffer where the encoded string starts.
+    */
+    public int createString(CharSequence s) {
+        int length = utf8.encodedLength(s);
+        addByte((byte)0);
+        startVector(1, length, 1);
+        bb.position(space -= length);
+        utf8.encodeUtf8(s, bb);
+        return endVector();
+    }
+
+   /**
+    * Create a string in the buffer from an already encoded UTF-8 string in a ByteBuffer.
+    *
+    * @param s An already encoded UTF-8 string as a `ByteBuffer`.
+    * @return The offset in the buffer where the encoded string starts.
+    */
+    public int createString(ByteBuffer s) {
+        int length = s.remaining();
+        addByte((byte)0);
+        startVector(1, length, 1);
+        bb.position(space -= length);
+        bb.put(s);
+        return endVector();
+    }
+
+    /**
+     * Create a byte array in the buffer.
+     *
+     * @param arr A source array with data
+     * @return The offset in the buffer where the encoded array starts.
+     */
+    public int createByteVector(byte[] arr) {
+        int length = arr.length;
+        startVector(1, length, 1);
+        bb.position(space -= length);
+        bb.put(arr);
+        return endVector();
+    }
+
+   /// @cond FLATBUFFERS_INTERNAL
+   /**
+    * Should not be accessing the final buffer before it is finished.
+    */
+    public void finished() {
+        if (!finished)
+            throw new AssertionError(
+                "FlatBuffers: you can only access the serialized buffer after it has been" +
+                " finished by FlatBufferBuilder.finish().");
+    }
+
+   /**
+    * Should not be creating any other object, string or vector
+    * while an object is being constructed.
+    */
+    public void notNested() {
+        if (nested)
+            throw new AssertionError("FlatBuffers: object serialization must not be nested.");
+    }
+
+   /**
+    * Structures are always stored inline, they need to be created right
+    * where they're used.  You'll get this assertion failure if you
+    * created it elsewhere.
+    *
+    * @param obj The offset of the created object.
+    */
+    public void Nested(int obj) {
+        if (obj != offset())
+            throw new AssertionError("FlatBuffers: struct must be serialized inline.");
+    }
+
+   /**
+    * Start encoding a new object in the buffer.  Users will not usually need to
+    * call this directly. The `FlatBuffers` compiler will generate helper methods
+    * that call this method internally.
+    * <p>
+    * For example, using the "Monster" code found on the "landing page". An
+    * object of type `Monster` can be created using the following code:
+    *
+    * <pre>{@code
+    * int testArrayOfString = Monster.createTestarrayofstringVector(fbb, new int[] {
+    *   fbb.createString("test1"),
+    *   fbb.createString("test2")
+    * });
+    *
+    * Monster.startMonster(fbb);
+    * Monster.addPos(fbb, Vec3.createVec3(fbb, 1.0f, 2.0f, 3.0f, 3.0,
+    *   Color.Green, (short)5, (byte)6));
+    * Monster.addHp(fbb, (short)80);
+    * Monster.addName(fbb, str);
+    * Monster.addInventory(fbb, inv);
+    * Monster.addTestType(fbb, (byte)Any.Monster);
+    * Monster.addTest(fbb, mon2);
+    * Monster.addTest4(fbb, test4);
+    * Monster.addTestarrayofstring(fbb, testArrayOfString);
+    * int mon = Monster.endMonster(fbb);
+    * }</pre>
+    * <p>
+    * Here:
+    * <ul>
+    * <li>The call to `Monster#startMonster(FlatBufferBuilder)` will call this
+    * method with the right number of fields set.</li>
+    * <li>`Monster#endMonster(FlatBufferBuilder)` will ensure {@link #endObject()} is called.</li>
+    * </ul>
+    * <p>
+    * It's not recommended to call this method directly.  If it's called manually, you must ensure
+    * to audit all calls to it whenever fields are added or removed from your schema.  This is
+    * automatically done by the code generated by the `FlatBuffers` compiler.
+    *
+    * @param numfields The number of fields found in this object.
+    */
+    public void startTable(int numfields) {
+        notNested();
+        if (vtable == null || vtable.length < numfields) vtable = new int[numfields];
+        vtable_in_use = numfields;
+        Arrays.fill(vtable, 0, vtable_in_use, 0);
+        nested = true;
+        object_start = offset();
+    }
+
+    /**
+     * Add a `boolean` to a table at `o` into its vtable, with value `x` and default `d`.
+     *
+     * @param o The index into the vtable.
+     * @param x A `boolean` to put into the buffer, depending on how defaults are handled. If
+     * `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the
+     * default value, it can be skipped.
+     * @param d A `boolean` default value to compare against when `force_defaults` is `false`.
+     */
+    public void addBoolean(int o, boolean x, boolean d) { if(force_defaults || x != d) { addBoolean(x); slot(o); } }
+
+    /**
+     * Add a `byte` to a table at `o` into its vtable, with value `x` and default `d`.
+     *
+     * @param o The index into the vtable.
+     * @param x A `byte` to put into the buffer, depending on how defaults are handled. If
+     * `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the
+     * default value, it can be skipped.
+     * @param d A `byte` default value to compare against when `force_defaults` is `false`.
+     */
+    public void addByte   (int o, byte    x, int     d) { if(force_defaults || x != d) { addByte   (x); slot(o); } }
+
+    /**
+     * Add a `short` to a table at `o` into its vtable, with value `x` and default `d`.
+     *
+     * @param o The index into the vtable.
+     * @param x A `short` to put into the buffer, depending on how defaults are handled. If
+     * `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the
+     * default value, it can be skipped.
+     * @param d A `short` default value to compare against when `force_defaults` is `false`.
+     */
+    public void addShort  (int o, short   x, int     d) { if(force_defaults || x != d) { addShort  (x); slot(o); } }
+
+    /**
+     * Add an `int` to a table at `o` into its vtable, with value `x` and default `d`.
+     *
+     * @param o The index into the vtable.
+     * @param x An `int` to put into the buffer, depending on how defaults are handled. If
+     * `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the
+     * default value, it can be skipped.
+     * @param d An `int` default value to compare against when `force_defaults` is `false`.
+     */
+    public void addInt    (int o, int     x, int     d) { if(force_defaults || x != d) { addInt    (x); slot(o); } }
+
+    /**
+     * Add a `long` to a table at `o` into its vtable, with value `x` and default `d`.
+     *
+     * @param o The index into the vtable.
+     * @param x A `long` to put into the buffer, depending on how defaults are handled. If
+     * `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the
+     * default value, it can be skipped.
+     * @param d A `long` default value to compare against when `force_defaults` is `false`.
+     */
+    public void addLong   (int o, long    x, long    d) { if(force_defaults || x != d) { addLong   (x); slot(o); } }
+
+    /**
+     * Add a `float` to a table at `o` into its vtable, with value `x` and default `d`.
+     *
+     * @param o The index into the vtable.
+     * @param x A `float` to put into the buffer, depending on how defaults are handled. If
+     * `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the
+     * default value, it can be skipped.
+     * @param d A `float` default value to compare against when `force_defaults` is `false`.
+     */
+    public void addFloat  (int o, float   x, double  d) { if(force_defaults || x != d) { addFloat  (x); slot(o); } }
+
+    /**
+     * Add a `double` to a table at `o` into its vtable, with value `x` and default `d`.
+     *
+     * @param o The index into the vtable.
+     * @param x A `double` to put into the buffer, depending on how defaults are handled. If
+     * `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the
+     * default value, it can be skipped.
+     * @param d A `double` default value to compare against when `force_defaults` is `false`.
+     */
+    public void addDouble (int o, double  x, double  d) { if(force_defaults || x != d) { addDouble (x); slot(o); } }
+
+    /**
+     * Add an `offset` to a table at `o` into its vtable, with value `x` and default `d`.
+     *
+     * @param o The index into the vtable.
+     * @param x An `offset` to put into the buffer, depending on how defaults are handled. If
+     * `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the
+     * default value, it can be skipped.
+     * @param d An `offset` default value to compare against when `force_defaults` is `false`.
+     */
+    public void addOffset (int o, int     x, int     d) { if(force_defaults || x != d) { addOffset (x); slot(o); } }
+
+    /**
+     * Add a struct to the table. Structs are stored inline, so nothing additional is being added.
+     *
+     * @param voffset The index into the vtable.
+     * @param x The offset of the created struct.
+     * @param d The default value is always `0`.
+     */
+    public void addStruct(int voffset, int x, int d) {
+        if(x != d) {
+            Nested(x);
+            slot(voffset);
+        }
+    }
+
+    /**
+     * Set the current vtable at `voffset` to the current location in the buffer.
+     *
+     * @param voffset The index into the vtable to store the offset relative to the end of the
+     * buffer.
+     */
+    public void slot(int voffset) {
+        vtable[voffset] = offset();
+    }
+
+   /**
+    * Finish off writing the object that is under construction.
+    *
+    * @return The offset to the object inside {@link #dataBuffer()}.
+    * @see #startTable(int)
+    */
+    public int endTable() {
+        if (vtable == null || !nested)
+            throw new AssertionError("FlatBuffers: endTable called without startTable");
+        addInt(0);
+        int vtableloc = offset();
+        // Write out the current vtable.
+        int i = vtable_in_use - 1;
+        // Trim trailing zeroes.
+        for (; i >= 0 && vtable[i] == 0; i--) {}
+        int trimmed_size = i + 1;
+        for (; i >= 0 ; i--) {
+            // Offset relative to the start of the table.
+            short off = (short)(vtable[i] != 0 ? vtableloc - vtable[i] : 0);
+            addShort(off);
+        }
+
+        final int standard_fields = 2; // The fields below:
+        addShort((short)(vtableloc - object_start));
+        addShort((short)((trimmed_size + standard_fields) * SIZEOF_SHORT));
+
+        // Search for an existing vtable that matches the current one.
+        int existing_vtable = 0;
+        outer_loop:
+        for (i = 0; i < num_vtables; i++) {
+            int vt1 = bb.capacity() - vtables[i];
+            int vt2 = space;
+            short len = bb.getShort(vt1);
+            if (len == bb.getShort(vt2)) {
+                for (int j = SIZEOF_SHORT; j < len; j += SIZEOF_SHORT) {
+                    if (bb.getShort(vt1 + j) != bb.getShort(vt2 + j)) {
+                        continue outer_loop;
+                    }
+                }
+                existing_vtable = vtables[i];
+                break outer_loop;
+            }
+        }
+
+        if (existing_vtable != 0) {
+            // Found a match:
+            // Remove the current vtable.
+            space = bb.capacity() - vtableloc;
+            // Point table to existing vtable.
+            bb.putInt(space, existing_vtable - vtableloc);
+        } else {
+            // No match:
+            // Add the location of the current vtable to the list of vtables.
+            if (num_vtables == vtables.length) vtables = Arrays.copyOf(vtables, num_vtables * 2);
+            vtables[num_vtables++] = offset();
+            // Point table to current vtable.
+            bb.putInt(bb.capacity() - vtableloc, offset() - vtableloc);
+        }
+
+        nested = false;
+        return vtableloc;
+    }
+
+    /**
+     * Checks that a required field has been set in a given table that has
+     * just been constructed.
+     *
+     * @param table The offset to the start of the table from the `ByteBuffer` capacity.
+     * @param field The offset to the field in the vtable.
+     */
+    public void required(int table, int field) {
+        int table_start = bb.capacity() - table;
+        int vtable_start = table_start - bb.getInt(table_start);
+        boolean ok = bb.getShort(vtable_start + field) != 0;
+        // If this fails, the caller will show what field needs to be set.
+        if (!ok)
+            throw new AssertionError("FlatBuffers: field " + field + " must be set");
+    }
+    /// @endcond
+
+    /**
+     * Finalize a buffer, pointing to the given `root_table`.
+     *
+     * @param root_table An offset to be added to the buffer.
+     * @param size_prefix Whether to prefix the size to the buffer.
+     */
+    protected void finish(int root_table, boolean size_prefix) {
+        prep(minalign, SIZEOF_INT + (size_prefix ? SIZEOF_INT : 0));
+        addOffset(root_table);
+        if (size_prefix) {
+            addInt(bb.capacity() - space);
+        }
+        bb.position(space);
+        finished = true;
+    }
+
+    /**
+     * Finalize a buffer, pointing to the given `root_table`.
+     *
+     * @param root_table An offset to be added to the buffer.
+     */
+    public void finish(int root_table) {
+        finish(root_table, false);
+    }
+
+    /**
+     * Finalize a buffer, pointing to the given `root_table`, with the size prefixed.
+     *
+     * @param root_table An offset to be added to the buffer.
+     */
+    public void finishSizePrefixed(int root_table) {
+        finish(root_table, true);
+    }
+
+    /**
+     * Finalize a buffer, pointing to the given `root_table`.
+     *
+     * @param root_table An offset to be added to the buffer.
+     * @param file_identifier A FlatBuffer file identifier to be added to the buffer before
+     * `root_table`.
+     * @param size_prefix Whether to prefix the size to the buffer.
+     */
+    protected void finish(int root_table, String file_identifier, boolean size_prefix) {
+        prep(minalign, SIZEOF_INT + FILE_IDENTIFIER_LENGTH + (size_prefix ? SIZEOF_INT : 0));
+        if (file_identifier.length() != FILE_IDENTIFIER_LENGTH)
+            throw new AssertionError("FlatBuffers: file identifier must be length " +
+                                     FILE_IDENTIFIER_LENGTH);
+        for (int i = FILE_IDENTIFIER_LENGTH - 1; i >= 0; i--) {
+            addByte((byte)file_identifier.charAt(i));
+        }
+        finish(root_table, size_prefix);
+    }
+
+    /**
+     * Finalize a buffer, pointing to the given `root_table`.
+     *
+     * @param root_table An offset to be added to the buffer.
+     * @param file_identifier A FlatBuffer file identifier to be added to the buffer before
+     * `root_table`.
+     */
+    public void finish(int root_table, String file_identifier) {
+        finish(root_table, file_identifier, false);
+    }
+
+    /**
+     * Finalize a buffer, pointing to the given `root_table`, with the size prefixed.
+     *
+     * @param root_table An offset to be added to the buffer.
+     * @param file_identifier A FlatBuffer file identifier to be added to the buffer before
+     * `root_table`.
+     */
+    public void finishSizePrefixed(int root_table, String file_identifier) {
+        finish(root_table, file_identifier, true);
+    }
+
+    /**
+     * In order to save space, fields that are set to their default value
+     * don't get serialized into the buffer. Forcing defaults provides a
+     * way to manually disable this optimization.
+     *
+     * @param forceDefaults When set to `true`, always serializes default values.
+     * @return Returns `this`.
+     */
+    public FlatBufferBuilder forceDefaults(boolean forceDefaults){
+        this.force_defaults = forceDefaults;
+        return this;
+    }
+
+    /**
+     * Get the ByteBuffer representing the FlatBuffer. Only call this after you've
+     * called `finish()`. The actual data starts at the ByteBuffer's current position,
+     * not necessarily at `0`.
+     *
+     * @return The {@link ByteBuffer} representing the FlatBuffer
+     */
+    public ByteBuffer dataBuffer() {
+        finished();
+        return bb;
+    }
+
+   /**
+    * The FlatBuffer data doesn't start at offset 0 in the {@link ByteBuffer}, but
+    * now the {@code ByteBuffer}'s position is set to that location upon {@link #finish(int)}.
+    *
+    * @return The {@link ByteBuffer#position() position} the data starts in {@link #dataBuffer()}
+    * @deprecated This method should not be needed anymore, but is left
+    * here for the moment to document this API change. It will be removed in the future.
+    */
+    @Deprecated
+    private int dataStart() {
+        finished();
+        return space;
+    }
+
+   /**
+    * A utility function to copy and return the ByteBuffer data from `start` to
+    * `start` + `length` as a `byte[]`.
+    *
+    * @param start Start copying at this offset.
+    * @param length How many bytes to copy.
+    * @return A range copy of the {@link #dataBuffer() data buffer}.
+    * @throws IndexOutOfBoundsException If the range of bytes is ouf of bound.
+    */
+    public byte[] sizedByteArray(int start, int length){
+        finished();
+        byte[] array = new byte[length];
+        bb.position(start);
+        bb.get(array);
+        return array;
+    }
+
+   /**
+    * A utility function to copy and return the ByteBuffer data as a `byte[]`.
+    *
+    * @return A full copy of the {@link #dataBuffer() data buffer}.
+    */
+    public byte[] sizedByteArray() {
+        return sizedByteArray(space, bb.capacity() - space);
+    }
+
+    /**
+     * A utility function to return an InputStream to the ByteBuffer data
+     *
+     * @return An InputStream that starts at the beginning of the ByteBuffer data
+     *         and can read to the end of it.
+     */
+    public InputStream sizedInputStream() {
+        finished();
+        ByteBuffer duplicate = bb.duplicate();
+        duplicate.position(space);
+        duplicate.limit(bb.capacity());
+        return new ByteBufferBackedInputStream(duplicate);
+    }
+
+    /**
+     * A class that allows a user to create an InputStream from a ByteBuffer.
+     */
+    static class ByteBufferBackedInputStream extends InputStream {
+
+        ByteBuffer buf;
+
+        public ByteBufferBackedInputStream(ByteBuffer buf) {
+            this.buf = buf;
+        }
+
+        public int read() throws IOException {
+            try {
+                return buf.get() & 0xFF;
+            } catch(BufferUnderflowException e) {
+                return -1;
+            }
+        }
+    }
+
+}
+
+/// @}
diff --git a/third_party/flatbuffers/java/com/google/flatbuffers/Struct.java b/third_party/flatbuffers/java/com/google/flatbuffers/Struct.java
new file mode 100644
index 0000000..c92164f
--- /dev/null
+++ b/third_party/flatbuffers/java/com/google/flatbuffers/Struct.java
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+package com.google.flatbuffers;
+
+import java.nio.ByteBuffer;
+
+/// @cond FLATBUFFERS_INTERNAL
+
+/**
+ * All structs in the generated code derive from this class, and add their own accessors.
+ */
+public class Struct {
+  /** Used to hold the position of the `bb` buffer. */
+  protected int bb_pos;
+  /** The underlying ByteBuffer to hold the data of the Struct. */
+  protected ByteBuffer bb;
+
+  /**
+   * Re-init the internal state with an external buffer {@code ByteBuffer} and an offset within.
+   *
+   * This method exists primarily to allow recycling Table instances without risking memory leaks
+   * due to {@code ByteBuffer} references.
+   */
+  protected void __reset(int _i, ByteBuffer _bb) { 
+    bb = _bb;
+    if (bb != null) {
+      bb_pos = _i;
+    } else {
+      bb_pos = 0;
+    }
+  }
+
+  /**
+   * Resets internal state with a null {@code ByteBuffer} and a zero position.
+   *
+   * This method exists primarily to allow recycling Struct instances without risking memory leaks
+   * due to {@code ByteBuffer} references. The instance will be unusable until it is assigned
+   * again to a {@code ByteBuffer}.
+   *
+   * @param struct the instance to reset to initial state
+   */
+  public void __reset() {
+    __reset(0, null);
+  }
+}
+
+/// @endcond
diff --git a/third_party/flatbuffers/java/com/google/flatbuffers/Table.java b/third_party/flatbuffers/java/com/google/flatbuffers/Table.java
new file mode 100644
index 0000000..ff069f2
--- /dev/null
+++ b/third_party/flatbuffers/java/com/google/flatbuffers/Table.java
@@ -0,0 +1,297 @@
+/*
+ * 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.
+ */
+
+package com.google.flatbuffers;
+
+import static com.google.flatbuffers.Constants.*;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+
+/// @cond FLATBUFFERS_INTERNAL
+
+/**
+ * All tables in the generated code derive from this class, and add their own accessors.
+ */
+public class Table {
+  public final static ThreadLocal<Charset> UTF8_CHARSET = new ThreadLocal<Charset>() {
+    @Override
+    protected Charset initialValue() {
+      return Charset.forName("UTF-8");
+    }
+  };
+  /** Used to hold the position of the `bb` buffer. */
+  protected int bb_pos;
+  /** The underlying ByteBuffer to hold the data of the Table. */
+  protected ByteBuffer bb;
+  /** Used to hold the vtable position. */
+  private int vtable_start;
+  /** Used to hold the vtable size. */
+  private int vtable_size;
+  Utf8 utf8 = Utf8.getDefault();
+
+  /**
+   * Get the underlying ByteBuffer.
+   *
+   * @return Returns the Table's ByteBuffer.
+   */
+  public ByteBuffer getByteBuffer() { return bb; }
+
+  /**
+   * Look up a field in the vtable.
+   *
+   * @param vtable_offset An `int` offset to the vtable in the Table's ByteBuffer.
+   * @return Returns an offset into the object, or `0` if the field is not present.
+   */
+  protected int __offset(int vtable_offset) {
+    return vtable_offset < vtable_size ? bb.getShort(vtable_start + vtable_offset) : 0;
+  }
+
+  protected static int __offset(int vtable_offset, int offset, ByteBuffer bb) {
+    int vtable = bb.capacity() - offset;
+    return bb.getShort(vtable + vtable_offset - bb.getInt(vtable)) + vtable;
+  }
+
+  /**
+   * Retrieve a relative offset.
+   *
+   * @param offset An `int` index into the Table's ByteBuffer containing the relative offset.
+   * @return Returns the relative offset stored at `offset`.
+   */
+  protected int __indirect(int offset) {
+    return offset + bb.getInt(offset);
+  }
+
+  protected static int __indirect(int offset, ByteBuffer bb) {
+    return offset + bb.getInt(offset);
+  }
+
+  /**
+   * Create a Java `String` from UTF-8 data stored inside the FlatBuffer.
+   *
+   * This allocates a new string and converts to wide chars upon each access,
+   * which is not very efficient. Instead, each FlatBuffer string also comes with an
+   * accessor based on __vector_as_bytebuffer below, which is much more efficient,
+   * assuming your Java program can handle UTF-8 data directly.
+   *
+   * @param offset An `int` index into the Table's ByteBuffer.
+   * @return Returns a `String` from the data stored inside the FlatBuffer at `offset`.
+   */
+  protected String __string(int offset) {
+    offset += bb.getInt(offset);
+    int length = bb.getInt(offset);
+    return utf8.decodeUtf8(bb, offset + SIZEOF_INT, length);
+  }
+
+  /**
+   * Get the length of a vector.
+   *
+   * @param offset An `int` index into the Table's ByteBuffer.
+   * @return Returns the length of the vector whose offset is stored at `offset`.
+   */
+  protected int __vector_len(int offset) {
+    offset += bb_pos;
+    offset += bb.getInt(offset);
+    return bb.getInt(offset);
+  }
+
+  /**
+   * Get the start data of a vector.
+   *
+   * @param offset An `int` index into the Table's ByteBuffer.
+   * @return Returns the start of the vector data whose offset is stored at `offset`.
+   */
+  protected int __vector(int offset) {
+    offset += bb_pos;
+    return offset + bb.getInt(offset) + SIZEOF_INT;  // data starts after the length
+  }
+
+  /**
+   * Get a whole vector as a ByteBuffer.
+   *
+   * This is efficient, since it only allocates a new {@link ByteBuffer} object,
+   * but does not actually copy the data, it still refers to the same bytes
+   * as the original ByteBuffer. Also useful with nested FlatBuffers, etc.
+   *
+   * @param vector_offset The position of the vector in the byte buffer
+   * @param elem_size The size of each element in the array
+   * @return The {@link ByteBuffer} for the array
+   */
+  protected ByteBuffer __vector_as_bytebuffer(int vector_offset, int elem_size) {
+    int o = __offset(vector_offset);
+    if (o == 0) return null;
+    ByteBuffer bb = this.bb.duplicate().order(ByteOrder.LITTLE_ENDIAN);
+    int vectorstart = __vector(o);
+    bb.position(vectorstart);
+    bb.limit(vectorstart + __vector_len(o) * elem_size);
+    return bb;
+  }
+
+  /**
+   * Initialize vector as a ByteBuffer.
+   *
+   * This is more efficient than using duplicate, since it doesn't copy the data
+   * nor allocattes a new {@link ByteBuffer}, creating no garbage to be collected.
+   *
+   * @param bb The {@link ByteBuffer} for the array
+   * @param vector_offset The position of the vector in the byte buffer
+   * @param elem_size The size of each element in the array
+   * @return The {@link ByteBuffer} for the array
+   */
+  protected ByteBuffer __vector_in_bytebuffer(ByteBuffer bb, int vector_offset, int elem_size) {
+    int o = this.__offset(vector_offset);
+    if (o == 0) return null;
+    int vectorstart = __vector(o);
+    bb.rewind();
+    bb.limit(vectorstart + __vector_len(o) * elem_size);
+    bb.position(vectorstart);
+    return bb;
+  }
+
+  /**
+   * Initialize any Table-derived type to point to the union at the given `offset`.
+   *
+   * @param t A `Table`-derived type that should point to the union at `offset`.
+   * @param offset An `int` index into the Table's ByteBuffer.
+   * @return Returns the Table that points to the union at `offset`.
+   */
+  protected Table __union(Table t, int offset) {
+    offset += bb_pos;
+    t.bb_pos = offset + bb.getInt(offset);
+    t.bb = bb;
+    t.vtable_start = t.bb_pos - bb.getInt(t.bb_pos);
+    t.vtable_size = bb.getShort(t.vtable_start);
+    return t;
+  }
+
+  /**
+   * Check if a {@link ByteBuffer} contains a file identifier.
+   *
+   * @param bb A {@code ByteBuffer} to check if it contains the identifier
+   * `ident`.
+   * @param ident A `String` identifier of the FlatBuffer file.
+   * @return True if the buffer contains the file identifier
+   */
+  protected static boolean __has_identifier(ByteBuffer bb, String ident) {
+    if (ident.length() != FILE_IDENTIFIER_LENGTH)
+        throw new AssertionError("FlatBuffers: file identifier must be length " +
+                                 FILE_IDENTIFIER_LENGTH);
+    for (int i = 0; i < FILE_IDENTIFIER_LENGTH; i++) {
+      if (ident.charAt(i) != (char)bb.get(bb.position() + SIZEOF_INT + i)) return false;
+    }
+    return true;
+  }
+
+  /**
+   * Sort tables by the key.
+   *
+   * @param offsets An 'int' indexes of the tables into the bb.
+   * @param bb A {@code ByteBuffer} to get the tables.
+   */
+  protected void sortTables(int[] offsets, final ByteBuffer bb) {
+    Integer[] off = new Integer[offsets.length];
+    for (int i = 0; i < offsets.length; i++) off[i] = offsets[i];
+    java.util.Arrays.sort(off, new java.util.Comparator<Integer>() {
+      public int compare(Integer o1, Integer o2) {
+        return keysCompare(o1, o2, bb);
+      }
+    });
+    for (int i = 0; i < offsets.length; i++) offsets[i] = off[i];
+  }
+
+  /**
+   * Compare two tables by the key.
+   *
+   * @param o1 An 'Integer' index of the first key into the bb.
+   * @param o2 An 'Integer' index of the second key into the bb.
+   * @param bb A {@code ByteBuffer} to get the keys.
+   */
+  protected int keysCompare(Integer o1, Integer o2, ByteBuffer bb) { return 0; }
+
+  /**
+   * Compare two strings in the buffer.
+   *
+   * @param offset_1 An 'int' index of the first string into the bb.
+   * @param offset_2 An 'int' index of the second string into the bb.
+   * @param bb A {@code ByteBuffer} to get the strings.
+   */
+  protected static int compareStrings(int offset_1, int offset_2, ByteBuffer bb) {
+    offset_1 += bb.getInt(offset_1);
+    offset_2 += bb.getInt(offset_2);
+    int len_1 = bb.getInt(offset_1);
+    int len_2 = bb.getInt(offset_2);
+    int startPos_1 = offset_1 + SIZEOF_INT;
+    int startPos_2 = offset_2 + SIZEOF_INT;
+    int len = Math.min(len_1, len_2);
+    for(int i = 0; i < len; i++) {
+      if (bb.get(i + startPos_1) != bb.get(i + startPos_2))
+        return bb.get(i + startPos_1) - bb.get(i + startPos_2);
+    }
+    return len_1 - len_2;
+  }
+
+  /**
+   * Compare string from the buffer with the 'String' object.
+   *
+   * @param offset_1 An 'int' index of the first string into the bb.
+   * @param key Second string as a byte array.
+   * @param bb A {@code ByteBuffer} to get the first string.
+   */
+  protected static int compareStrings(int offset_1, byte[] key, ByteBuffer bb) {
+    offset_1 += bb.getInt(offset_1);
+    int len_1 = bb.getInt(offset_1);
+    int len_2 = key.length;
+    int startPos_1 = offset_1 + Constants.SIZEOF_INT;
+    int len = Math.min(len_1, len_2);
+    for (int i = 0; i < len; i++) {
+      if (bb.get(i + startPos_1) != key[i])
+        return bb.get(i + startPos_1) - key[i];
+    }
+    return len_1 - len_2;
+  }
+
+  /**
+   * Re-init the internal state with an external buffer {@code ByteBuffer} and an offset within.
+   *
+   * This method exists primarily to allow recycling Table instances without risking memory leaks
+   * due to {@code ByteBuffer} references.
+   */
+  protected void __reset(int _i, ByteBuffer _bb) { 
+    bb = _bb;
+    if (bb != null) {
+      bb_pos = _i;
+      vtable_start = bb_pos - bb.getInt(bb_pos);
+      vtable_size = bb.getShort(vtable_start);
+    } else {
+      bb_pos = 0;
+      vtable_start = 0;
+      vtable_size = 0;
+    }
+  }
+
+  /**
+   * Resets the internal state with a null {@code ByteBuffer} and a zero position.
+   *
+   * This method exists primarily to allow recycling Table instances without risking memory leaks
+   * due to {@code ByteBuffer} references. The instance will be unusable until it is assigned
+   * again to a {@code ByteBuffer}.
+   */
+  public void __reset() {
+    __reset(0, null);
+  }
+}
+
+/// @endcond
diff --git a/third_party/flatbuffers/java/com/google/flatbuffers/Utf8.java b/third_party/flatbuffers/java/com/google/flatbuffers/Utf8.java
new file mode 100644
index 0000000..efb6811
--- /dev/null
+++ b/third_party/flatbuffers/java/com/google/flatbuffers/Utf8.java
@@ -0,0 +1,193 @@
+/*
+ * 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.
+ */
+
+package com.google.flatbuffers;
+
+import java.nio.ByteBuffer;
+
+import static java.lang.Character.MIN_HIGH_SURROGATE;
+import static java.lang.Character.MIN_LOW_SURROGATE;
+import static java.lang.Character.MIN_SUPPLEMENTARY_CODE_POINT;
+
+public abstract class Utf8 {
+
+  /**
+   * Returns the number of bytes in the UTF-8-encoded form of {@code sequence}. For a string,
+   * this method is equivalent to {@code string.getBytes(UTF_8).length}, but is more efficient in
+   * both time and space.
+   *
+   * @throws IllegalArgumentException if {@code sequence} contains ill-formed UTF-16 (unpaired
+   *     surrogates)
+   */
+  public abstract int encodedLength(CharSequence sequence);
+
+  /**
+   * Encodes the given characters to the target {@link ByteBuffer} using UTF-8 encoding.
+   *
+   * <p>Selects an optimal algorithm based on the type of {@link ByteBuffer} (i.e. heap or direct)
+   * and the capabilities of the platform.
+   *
+   * @param in the source string to be encoded
+   * @param out the target buffer to receive the encoded string.
+   */
+  public abstract void encodeUtf8(CharSequence in, ByteBuffer out);
+
+  /**
+   * Decodes the given UTF-8 portion of the {@link ByteBuffer} into a {@link String}.
+   *
+   * @throws IllegalArgumentException if the input is not valid UTF-8.
+   */
+  public abstract String decodeUtf8(ByteBuffer buffer, int offset, int length);
+
+  private static Utf8 DEFAULT;
+
+  /**
+   * Get the default UTF-8 processor.
+   * @return the default processor
+   */
+  public static Utf8 getDefault() {
+    if (DEFAULT == null) {
+      DEFAULT = new Utf8Safe();
+    }
+    return DEFAULT;
+  }
+
+  /**
+   * Set the default instance of the UTF-8 processor.
+   * @param instance the new instance to use
+   */
+  public static void setDefault(Utf8 instance) {
+    DEFAULT = instance;
+  }
+
+  /**
+   * Utility methods for decoding bytes into {@link String}. Callers are responsible for extracting
+   * bytes (possibly using Unsafe methods), and checking remaining bytes. All other UTF-8 validity
+   * checks and codepoint conversion happen in this class.
+   */
+  static class DecodeUtil {
+
+    /**
+     * Returns whether this is a single-byte codepoint (i.e., ASCII) with the form '0XXXXXXX'.
+     */
+    static boolean isOneByte(byte b) {
+      return b >= 0;
+    }
+
+    /**
+     * Returns whether this is a two-byte codepoint with the form '10XXXXXX'.
+     */
+    static boolean isTwoBytes(byte b) {
+      return b < (byte) 0xE0;
+    }
+
+    /**
+     * Returns whether this is a three-byte codepoint with the form '110XXXXX'.
+     */
+    static boolean isThreeBytes(byte b) {
+      return b < (byte) 0xF0;
+    }
+
+    static void handleOneByte(byte byte1, char[] resultArr, int resultPos) {
+      resultArr[resultPos] = (char) byte1;
+    }
+
+    static void handleTwoBytes(
+        byte byte1, byte byte2, char[] resultArr, int resultPos)
+        throws IllegalArgumentException {
+      // Simultaneously checks for illegal trailing-byte in leading position (<= '11000000') and
+      // overlong 2-byte, '11000001'.
+      if (byte1 < (byte) 0xC2) {
+        throw new IllegalArgumentException("Invalid UTF-8: Illegal leading byte in 2 bytes utf");
+      }
+      if (isNotTrailingByte(byte2)) {
+        throw new IllegalArgumentException("Invalid UTF-8: Illegal trailing byte in 2 bytes utf");
+      }
+      resultArr[resultPos] = (char) (((byte1 & 0x1F) << 6) | trailingByteValue(byte2));
+    }
+
+    static void handleThreeBytes(
+        byte byte1, byte byte2, byte byte3, char[] resultArr, int resultPos)
+        throws IllegalArgumentException {
+      if (isNotTrailingByte(byte2)
+              // overlong? 5 most significant bits must not all be zero
+              || (byte1 == (byte) 0xE0 && byte2 < (byte) 0xA0)
+              // check for illegal surrogate codepoints
+              || (byte1 == (byte) 0xED && byte2 >= (byte) 0xA0)
+              || isNotTrailingByte(byte3)) {
+        throw new IllegalArgumentException("Invalid UTF-8");
+      }
+      resultArr[resultPos] = (char)
+                                 (((byte1 & 0x0F) << 12) | (trailingByteValue(byte2) << 6) | trailingByteValue(byte3));
+    }
+
+    static void handleFourBytes(
+        byte byte1, byte byte2, byte byte3, byte byte4, char[] resultArr, int resultPos)
+        throws IllegalArgumentException{
+      if (isNotTrailingByte(byte2)
+              // Check that 1 <= plane <= 16.  Tricky optimized form of:
+              //   valid 4-byte leading byte?
+              // if (byte1 > (byte) 0xF4 ||
+              //   overlong? 4 most significant bits must not all be zero
+              //     byte1 == (byte) 0xF0 && byte2 < (byte) 0x90 ||
+              //   codepoint larger than the highest code point (U+10FFFF)?
+              //     byte1 == (byte) 0xF4 && byte2 > (byte) 0x8F)
+              || (((byte1 << 28) + (byte2 - (byte) 0x90)) >> 30) != 0
+              || isNotTrailingByte(byte3)
+              || isNotTrailingByte(byte4)) {
+        throw new IllegalArgumentException("Invalid UTF-8");
+      }
+      int codepoint = ((byte1 & 0x07) << 18)
+                          | (trailingByteValue(byte2) << 12)
+                          | (trailingByteValue(byte3) << 6)
+                          | trailingByteValue(byte4);
+      resultArr[resultPos] = DecodeUtil.highSurrogate(codepoint);
+      resultArr[resultPos + 1] = DecodeUtil.lowSurrogate(codepoint);
+    }
+
+    /**
+     * Returns whether the byte is not a valid continuation of the form '10XXXXXX'.
+     */
+    private static boolean isNotTrailingByte(byte b) {
+      return b > (byte) 0xBF;
+    }
+
+    /**
+     * Returns the actual value of the trailing byte (removes the prefix '10') for composition.
+     */
+    private static int trailingByteValue(byte b) {
+      return b & 0x3F;
+    }
+
+    private static char highSurrogate(int codePoint) {
+      return (char) ((MIN_HIGH_SURROGATE - (MIN_SUPPLEMENTARY_CODE_POINT >>> 10))
+                         + (codePoint >>> 10));
+    }
+
+    private static char lowSurrogate(int codePoint) {
+      return (char) (MIN_LOW_SURROGATE + (codePoint & 0x3ff));
+    }
+  }
+
+  // These UTF-8 handling methods are copied from Guava's Utf8Unsafe class with a modification to throw
+  // a protocol buffer local exception. This exception is then caught in CodedOutputStream so it can
+  // fallback to more lenient behavior.
+  static class UnpairedSurrogateException extends IllegalArgumentException {
+    UnpairedSurrogateException(int index, int length) {
+      super("Unpaired surrogate at index " + index + " of " + length);
+    }
+  }
+}
diff --git a/third_party/flatbuffers/java/com/google/flatbuffers/Utf8Old.java b/third_party/flatbuffers/java/com/google/flatbuffers/Utf8Old.java
new file mode 100644
index 0000000..3dac714
--- /dev/null
+++ b/third_party/flatbuffers/java/com/google/flatbuffers/Utf8Old.java
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ */
+
+package com.google.flatbuffers;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CoderResult;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * This class implements the Utf8 API using the Java Utf8 encoder. Use
+ * Utf8.setDefault(new Utf8Old()); to use it.
+ */
+public class Utf8Old extends Utf8 {
+
+  private static class Cache {
+    final CharsetEncoder encoder;
+    final CharsetDecoder decoder;
+    CharSequence lastInput = null;
+    ByteBuffer lastOutput = null;
+
+    Cache() {
+      encoder = StandardCharsets.UTF_8.newEncoder();
+      decoder = StandardCharsets.UTF_8.newDecoder();
+    }
+  }
+
+  private static final ThreadLocal<Cache> CACHE =
+      ThreadLocal.withInitial(() -> new Cache());
+
+  // Play some games so that the old encoder doesn't pay twice for computing
+  // the length of the encoded string.
+
+  @Override
+  public int encodedLength(CharSequence in) {
+    final Cache cache = CACHE.get();
+    int estimated = (int) (in.length() * cache.encoder.maxBytesPerChar());
+    if (cache.lastOutput == null || cache.lastOutput.capacity() < estimated) {
+      cache.lastOutput = ByteBuffer.allocate(Math.max(128, estimated));
+    }
+    cache.lastOutput.clear();
+    cache.lastInput = in;
+    CharBuffer wrap = (in instanceof CharBuffer) ?
+                          (CharBuffer) in : CharBuffer.wrap(in);
+    CoderResult result = cache.encoder.encode(wrap, cache.lastOutput, true);
+    if (result.isError()) {
+      try {
+        result.throwException();
+      } catch (CharacterCodingException e) {
+        throw new IllegalArgumentException("bad character encoding", e);
+      }
+    }
+    cache.lastOutput.flip();
+    return cache.lastOutput.remaining();
+  }
+
+  @Override
+  public void encodeUtf8(CharSequence in, ByteBuffer out) {
+    final Cache cache = CACHE.get();
+    if (cache.lastInput != in) {
+      // Update the lastOutput to match our input, although flatbuffer should
+      // never take this branch.
+      encodedLength(in);
+    }
+    out.put(cache.lastOutput);
+  }
+
+  @Override
+  public String decodeUtf8(ByteBuffer buffer, int offset, int length) {
+    CharsetDecoder decoder = CACHE.get().decoder;
+    decoder.reset();
+    buffer = buffer.duplicate();
+    buffer.position(offset);
+    buffer.limit(offset + length);
+    try {
+      CharBuffer result = decoder.decode(buffer);
+      return result.toString();
+    } catch (CharacterCodingException e) {
+      throw new IllegalArgumentException("Bad encoding", e);
+    }
+  }
+}
diff --git a/third_party/flatbuffers/java/com/google/flatbuffers/Utf8Safe.java b/third_party/flatbuffers/java/com/google/flatbuffers/Utf8Safe.java
new file mode 100644
index 0000000..06ea420
--- /dev/null
+++ b/third_party/flatbuffers/java/com/google/flatbuffers/Utf8Safe.java
@@ -0,0 +1,451 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.flatbuffers;
+
+import java.nio.ByteBuffer;
+import static java.lang.Character.MAX_SURROGATE;
+import static java.lang.Character.MIN_SUPPLEMENTARY_CODE_POINT;
+import static java.lang.Character.MIN_SURROGATE;
+import static java.lang.Character.isSurrogatePair;
+import static java.lang.Character.toCodePoint;
+
+/**
+ * A set of low-level, high-performance static utility methods related
+ * to the UTF-8 character encoding.  This class has no dependencies
+ * outside of the core JDK libraries.
+ *
+ * <p>There are several variants of UTF-8.  The one implemented by
+ * this class is the restricted definition of UTF-8 introduced in
+ * Unicode 3.1, which mandates the rejection of "overlong" byte
+ * sequences as well as rejection of 3-byte surrogate codepoint byte
+ * sequences.  Note that the UTF-8 decoder included in Oracle's JDK
+ * has been modified to also reject "overlong" byte sequences, but (as
+ * of 2011) still accepts 3-byte surrogate codepoint byte sequences.
+ *
+ * <p>The byte sequences considered valid by this class are exactly
+ * those that can be roundtrip converted to Strings and back to bytes
+ * using the UTF-8 charset, without loss: <pre> {@code
+ * Arrays.equals(bytes, new String(bytes, Internal.UTF_8).getBytes(Internal.UTF_8))
+ * }</pre>
+ *
+ * <p>See the Unicode Standard,</br>
+ * Table 3-6. <em>UTF-8 Bit Distribution</em>,</br>
+ * Table 3-7. <em>Well Formed UTF-8 Byte Sequences</em>.
+ */
+final public class Utf8Safe extends Utf8 {
+
+  /**
+   * Returns the number of bytes in the UTF-8-encoded form of {@code sequence}. For a string,
+   * this method is equivalent to {@code string.getBytes(UTF_8).length}, but is more efficient in
+   * both time and space.
+   *
+   * @throws IllegalArgumentException if {@code sequence} contains ill-formed UTF-16 (unpaired
+   *     surrogates)
+   */
+  private static int computeEncodedLength(CharSequence sequence) {
+    // Warning to maintainers: this implementation is highly optimized.
+    int utf16Length = sequence.length();
+    int utf8Length = utf16Length;
+    int i = 0;
+
+    // This loop optimizes for pure ASCII.
+    while (i < utf16Length && sequence.charAt(i) < 0x80) {
+      i++;
+    }
+
+    // This loop optimizes for chars less than 0x800.
+    for (; i < utf16Length; i++) {
+      char c = sequence.charAt(i);
+      if (c < 0x800) {
+        utf8Length += ((0x7f - c) >>> 31);  // branch free!
+      } else {
+        utf8Length += encodedLengthGeneral(sequence, i);
+        break;
+      }
+    }
+
+    if (utf8Length < utf16Length) {
+      // Necessary and sufficient condition for overflow because of maximum 3x expansion
+      throw new IllegalArgumentException("UTF-8 length does not fit in int: "
+                                             + (utf8Length + (1L << 32)));
+    }
+    return utf8Length;
+  }
+
+  private static int encodedLengthGeneral(CharSequence sequence, int start) {
+    int utf16Length = sequence.length();
+    int utf8Length = 0;
+    for (int i = start; i < utf16Length; i++) {
+      char c = sequence.charAt(i);
+      if (c < 0x800) {
+        utf8Length += (0x7f - c) >>> 31; // branch free!
+      } else {
+        utf8Length += 2;
+        // jdk7+: if (Character.isSurrogate(c)) {
+        if (Character.MIN_SURROGATE <= c && c <= Character.MAX_SURROGATE) {
+          // Check that we have a well-formed surrogate pair.
+          int cp = Character.codePointAt(sequence, i);
+          if (cp < MIN_SUPPLEMENTARY_CODE_POINT) {
+            throw new Utf8Safe.UnpairedSurrogateException(i, utf16Length);
+          }
+          i++;
+        }
+      }
+    }
+    return utf8Length;
+  }
+
+  private static String decodeUtf8Array(byte[] bytes, int index, int size) {
+    // Bitwise OR combines the sign bits so any negative value fails the check.
+    if ((index | size | bytes.length - index - size) < 0) {
+      throw new ArrayIndexOutOfBoundsException(
+          String.format("buffer length=%d, index=%d, size=%d", bytes.length, index, size));
+    }
+
+    int offset = index;
+    final int limit = offset + size;
+
+    // The longest possible resulting String is the same as the number of input bytes, when it is
+    // all ASCII. For other cases, this over-allocates and we will truncate in the end.
+    char[] resultArr = new char[size];
+    int resultPos = 0;
+
+    // Optimize for 100% ASCII (Hotspot loves small simple top-level loops like this).
+    // This simple loop stops when we encounter a byte >= 0x80 (i.e. non-ASCII).
+    while (offset < limit) {
+      byte b = bytes[offset];
+      if (!DecodeUtil.isOneByte(b)) {
+        break;
+      }
+      offset++;
+      DecodeUtil.handleOneByte(b, resultArr, resultPos++);
+    }
+
+    while (offset < limit) {
+      byte byte1 = bytes[offset++];
+      if (DecodeUtil.isOneByte(byte1)) {
+        DecodeUtil.handleOneByte(byte1, resultArr, resultPos++);
+        // It's common for there to be multiple ASCII characters in a run mixed in, so add an
+        // extra optimized loop to take care of these runs.
+        while (offset < limit) {
+          byte b = bytes[offset];
+          if (!DecodeUtil.isOneByte(b)) {
+            break;
+          }
+          offset++;
+          DecodeUtil.handleOneByte(b, resultArr, resultPos++);
+        }
+      } else if (DecodeUtil.isTwoBytes(byte1)) {
+        if (offset >= limit) {
+          throw new IllegalArgumentException("Invalid UTF-8");
+        }
+        DecodeUtil.handleTwoBytes(byte1, /* byte2 */ bytes[offset++], resultArr, resultPos++);
+      } else if (DecodeUtil.isThreeBytes(byte1)) {
+        if (offset >= limit - 1) {
+          throw new IllegalArgumentException("Invalid UTF-8");
+        }
+        DecodeUtil.handleThreeBytes(
+            byte1,
+            /* byte2 */ bytes[offset++],
+            /* byte3 */ bytes[offset++],
+            resultArr,
+            resultPos++);
+      } else {
+        if (offset >= limit - 2) {
+          throw new IllegalArgumentException("Invalid UTF-8");
+        }
+        DecodeUtil.handleFourBytes(
+            byte1,
+            /* byte2 */ bytes[offset++],
+            /* byte3 */ bytes[offset++],
+            /* byte4 */ bytes[offset++],
+            resultArr,
+            resultPos++);
+        // 4-byte case requires two chars.
+        resultPos++;
+      }
+    }
+
+    return new String(resultArr, 0, resultPos);
+  }
+
+  private static String decodeUtf8Buffer(ByteBuffer buffer, int offset,
+                                         int length) {
+    // Bitwise OR combines the sign bits so any negative value fails the check.
+    if ((offset | length | buffer.limit() - offset - length) < 0) {
+      throw new ArrayIndexOutOfBoundsException(
+          String.format("buffer limit=%d, index=%d, limit=%d", buffer.limit(),
+              offset, length));
+    }
+
+    final int limit = offset + length;
+
+    // The longest possible resulting String is the same as the number of input bytes, when it is
+    // all ASCII. For other cases, this over-allocates and we will truncate in the end.
+    char[] resultArr = new char[length];
+    int resultPos = 0;
+
+    // Optimize for 100% ASCII (Hotspot loves small simple top-level loops like this).
+    // This simple loop stops when we encounter a byte >= 0x80 (i.e. non-ASCII).
+    while (offset < limit) {
+      byte b = buffer.get(offset);
+      if (!DecodeUtil.isOneByte(b)) {
+        break;
+      }
+      offset++;
+      DecodeUtil.handleOneByte(b, resultArr, resultPos++);
+    }
+
+    while (offset < limit) {
+      byte byte1 = buffer.get(offset++);
+      if (DecodeUtil.isOneByte(byte1)) {
+        DecodeUtil.handleOneByte(byte1, resultArr, resultPos++);
+        // It's common for there to be multiple ASCII characters in a run mixed in, so add an
+        // extra optimized loop to take care of these runs.
+        while (offset < limit) {
+          byte b = buffer.get(offset);
+          if (!DecodeUtil.isOneByte(b)) {
+            break;
+          }
+          offset++;
+          DecodeUtil.handleOneByte(b, resultArr, resultPos++);
+        }
+      } else if (DecodeUtil.isTwoBytes(byte1)) {
+        if (offset >= limit) {
+          throw new IllegalArgumentException("Invalid UTF-8");
+        }
+        DecodeUtil.handleTwoBytes(
+            byte1, /* byte2 */ buffer.get(offset++), resultArr, resultPos++);
+      } else if (DecodeUtil.isThreeBytes(byte1)) {
+        if (offset >= limit - 1) {
+          throw new IllegalArgumentException("Invalid UTF-8");
+        }
+        DecodeUtil.handleThreeBytes(
+            byte1,
+            /* byte2 */ buffer.get(offset++),
+            /* byte3 */ buffer.get(offset++),
+            resultArr,
+            resultPos++);
+      } else {
+        if (offset >= limit - 2) {
+          throw new IllegalArgumentException("Invalid UTF-8");
+        }
+        DecodeUtil.handleFourBytes(
+            byte1,
+            /* byte2 */ buffer.get(offset++),
+            /* byte3 */ buffer.get(offset++),
+            /* byte4 */ buffer.get(offset++),
+            resultArr,
+            resultPos++);
+        // 4-byte case requires two chars.
+        resultPos++;
+      }
+    }
+
+    return new String(resultArr, 0, resultPos);
+  }
+
+  @Override
+  public int encodedLength(CharSequence in) {
+    return computeEncodedLength(in);
+  }
+
+  /**
+   * Decodes the given UTF-8 portion of the {@link ByteBuffer} into a {@link String}.
+   *
+   * @throws IllegalArgumentException if the input is not valid UTF-8.
+   */
+  @Override
+  public String decodeUtf8(ByteBuffer buffer, int offset, int length)
+      throws IllegalArgumentException {
+    if (buffer.hasArray()) {
+      return decodeUtf8Array(buffer.array(), buffer.arrayOffset() + offset, length);
+    } else {
+      return decodeUtf8Buffer(buffer, offset, length);
+    }
+  }
+
+
+  private static void encodeUtf8Buffer(CharSequence in, ByteBuffer out) {
+    final int inLength = in.length();
+    int outIx = out.position();
+    int inIx = 0;
+
+    // Since ByteBuffer.putXXX() already checks boundaries for us, no need to explicitly check
+    // access. Assume the buffer is big enough and let it handle the out of bounds exception
+    // if it occurs.
+    try {
+      // Designed to take advantage of
+      // https://wikis.oracle.com/display/HotSpotInternals/RangeCheckElimination
+      for (char c; inIx < inLength && (c = in.charAt(inIx)) < 0x80; ++inIx) {
+        out.put(outIx + inIx, (byte) c);
+      }
+      if (inIx == inLength) {
+        // Successfully encoded the entire string.
+        out.position(outIx + inIx);
+        return;
+      }
+
+      outIx += inIx;
+      for (char c; inIx < inLength; ++inIx, ++outIx) {
+        c = in.charAt(inIx);
+        if (c < 0x80) {
+          // One byte (0xxx xxxx)
+          out.put(outIx, (byte) c);
+        } else if (c < 0x800) {
+          // Two bytes (110x xxxx 10xx xxxx)
+
+          // Benchmarks show put performs better than putShort here (for HotSpot).
+          out.put(outIx++, (byte) (0xC0 | (c >>> 6)));
+          out.put(outIx, (byte) (0x80 | (0x3F & c)));
+        } else if (c < MIN_SURROGATE || MAX_SURROGATE < c) {
+          // Three bytes (1110 xxxx 10xx xxxx 10xx xxxx)
+          // Maximum single-char code point is 0xFFFF, 16 bits.
+
+          // Benchmarks show put performs better than putShort here (for HotSpot).
+          out.put(outIx++, (byte) (0xE0 | (c >>> 12)));
+          out.put(outIx++, (byte) (0x80 | (0x3F & (c >>> 6))));
+          out.put(outIx, (byte) (0x80 | (0x3F & c)));
+        } else {
+          // Four bytes (1111 xxxx 10xx xxxx 10xx xxxx 10xx xxxx)
+
+          // Minimum code point represented by a surrogate pair is 0x10000, 17 bits, four UTF-8
+          // bytes
+          final char low;
+          if (inIx + 1 == inLength || !isSurrogatePair(c, (low = in.charAt(++inIx)))) {
+            throw new UnpairedSurrogateException(inIx, inLength);
+          }
+          // TODO(nathanmittler): Consider using putInt() to improve performance.
+          int codePoint = toCodePoint(c, low);
+          out.put(outIx++, (byte) ((0xF << 4) | (codePoint >>> 18)));
+          out.put(outIx++, (byte) (0x80 | (0x3F & (codePoint >>> 12))));
+          out.put(outIx++, (byte) (0x80 | (0x3F & (codePoint >>> 6))));
+          out.put(outIx, (byte) (0x80 | (0x3F & codePoint)));
+        }
+      }
+
+      // Successfully encoded the entire string.
+      out.position(outIx);
+    } catch (IndexOutOfBoundsException e) {
+      // TODO(nathanmittler): Consider making the API throw IndexOutOfBoundsException instead.
+
+      // If we failed in the outer ASCII loop, outIx will not have been updated. In this case,
+      // use inIx to determine the bad write index.
+      int badWriteIndex = out.position() + Math.max(inIx, outIx - out.position() + 1);
+      throw new ArrayIndexOutOfBoundsException(
+          "Failed writing " + in.charAt(inIx) + " at index " + badWriteIndex);
+    }
+  }
+
+  private static int encodeUtf8Array(CharSequence in, byte[] out,
+                                     int offset, int length) {
+    int utf16Length = in.length();
+    int j = offset;
+    int i = 0;
+    int limit = offset + length;
+    // Designed to take advantage of
+    // https://wikis.oracle.com/display/HotSpotInternals/RangeCheckElimination
+    for (char c; i < utf16Length && i + j < limit && (c = in.charAt(i)) < 0x80; i++) {
+      out[j + i] = (byte) c;
+    }
+    if (i == utf16Length) {
+      return j + utf16Length;
+    }
+    j += i;
+    for (char c; i < utf16Length; i++) {
+      c = in.charAt(i);
+      if (c < 0x80 && j < limit) {
+        out[j++] = (byte) c;
+      } else if (c < 0x800 && j <= limit - 2) { // 11 bits, two UTF-8 bytes
+        out[j++] = (byte) ((0xF << 6) | (c >>> 6));
+        out[j++] = (byte) (0x80 | (0x3F & c));
+      } else if ((c < Character.MIN_SURROGATE || Character.MAX_SURROGATE < c) && j <= limit - 3) {
+        // Maximum single-char code point is 0xFFFF, 16 bits, three UTF-8 bytes
+        out[j++] = (byte) ((0xF << 5) | (c >>> 12));
+        out[j++] = (byte) (0x80 | (0x3F & (c >>> 6)));
+        out[j++] = (byte) (0x80 | (0x3F & c));
+      } else if (j <= limit - 4) {
+        // Minimum code point represented by a surrogate pair is 0x10000, 17 bits,
+        // four UTF-8 bytes
+        final char low;
+        if (i + 1 == in.length()
+                || !Character.isSurrogatePair(c, (low = in.charAt(++i)))) {
+          throw new UnpairedSurrogateException((i - 1), utf16Length);
+        }
+        int codePoint = Character.toCodePoint(c, low);
+        out[j++] = (byte) ((0xF << 4) | (codePoint >>> 18));
+        out[j++] = (byte) (0x80 | (0x3F & (codePoint >>> 12)));
+        out[j++] = (byte) (0x80 | (0x3F & (codePoint >>> 6)));
+        out[j++] = (byte) (0x80 | (0x3F & codePoint));
+      } else {
+        // If we are surrogates and we're not a surrogate pair, always throw an
+        // UnpairedSurrogateException instead of an ArrayOutOfBoundsException.
+        if ((Character.MIN_SURROGATE <= c && c <= Character.MAX_SURROGATE)
+                && (i + 1 == in.length()
+                        || !Character.isSurrogatePair(c, in.charAt(i + 1)))) {
+          throw new UnpairedSurrogateException(i, utf16Length);
+        }
+        throw new ArrayIndexOutOfBoundsException("Failed writing " + c + " at index " + j);
+      }
+    }
+    return j;
+  }
+
+  /**
+   * Encodes the given characters to the target {@link ByteBuffer} using UTF-8 encoding.
+   *
+   * <p>Selects an optimal algorithm based on the type of {@link ByteBuffer} (i.e. heap or direct)
+   * and the capabilities of the platform.
+   *
+   * @param in the source string to be encoded
+   * @param out the target buffer to receive the encoded string.
+   */
+  @Override
+  public void encodeUtf8(CharSequence in, ByteBuffer out) {
+    if (out.hasArray()) {
+      int start = out.arrayOffset();
+      int end = encodeUtf8Array(in, out.array(), start + out.position(),
+          out.remaining());
+      out.position(end - start);
+    } else {
+      encodeUtf8Buffer(in, out);
+    }
+  }
+
+  // These UTF-8 handling methods are copied from Guava's Utf8Unsafe class with
+  // a modification to throw a local exception. This exception can be caught
+  // to fallback to more lenient behavior.
+  static class UnpairedSurrogateException extends IllegalArgumentException {
+    UnpairedSurrogateException(int index, int length) {
+      super("Unpaired surrogate at index " + index + " of " + length);
+    }
+  }
+}
diff --git a/third_party/flatbuffers/js/flatbuffers.js b/third_party/flatbuffers/js/flatbuffers.js
new file mode 100644
index 0000000..461cd7a
--- /dev/null
+++ b/third_party/flatbuffers/js/flatbuffers.js
@@ -0,0 +1,1259 @@
+/// @file
+/// @addtogroup flatbuffers_javascript_api
+/// @{
+/// @cond FLATBUFFERS_INTERNAL
+
+/**
+ * @fileoverview
+ *
+ * Need to suppress 'global this' error so the Node.js export line doesn't cause
+ * closure compile to error out.
+ * @suppress {globalThis}
+ */
+
+/**
+ * @const
+ * @namespace
+ */
+var flatbuffers = {};
+
+/**
+ * @typedef {number}
+ */
+flatbuffers.Offset;
+
+/**
+ * @typedef {{
+ *   bb: flatbuffers.ByteBuffer,
+ *   bb_pos: number
+ * }}
+ */
+flatbuffers.Table;
+
+/**
+ * @type {number}
+ * @const
+ */
+flatbuffers.SIZEOF_SHORT = 2;
+
+/**
+ * @type {number}
+ * @const
+ */
+flatbuffers.SIZEOF_INT = 4;
+
+/**
+ * @type {number}
+ * @const
+ */
+flatbuffers.FILE_IDENTIFIER_LENGTH = 4;
+
+/**
+ * @type {number}
+ * @const
+ */
+flatbuffers.SIZE_PREFIX_LENGTH = 4;
+
+/**
+ * @enum {number}
+ */
+flatbuffers.Encoding = {
+  UTF8_BYTES: 1,
+  UTF16_STRING: 2
+};
+
+/**
+ * @type {Int32Array}
+ * @const
+ */
+flatbuffers.int32 = new Int32Array(2);
+
+/**
+ * @type {Float32Array}
+ * @const
+ */
+flatbuffers.float32 = new Float32Array(flatbuffers.int32.buffer);
+
+/**
+ * @type {Float64Array}
+ * @const
+ */
+flatbuffers.float64 = new Float64Array(flatbuffers.int32.buffer);
+
+/**
+ * @type {boolean}
+ * @const
+ */
+flatbuffers.isLittleEndian = new Uint16Array(new Uint8Array([1, 0]).buffer)[0] === 1;
+
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * @constructor
+ * @param {number} low
+ * @param {number} high
+ */
+flatbuffers.Long = function(low, high) {
+  /**
+   * @type {number}
+   * @const
+   */
+  this.low = low | 0;
+
+  /**
+   * @type {number}
+   * @const
+   */
+  this.high = high | 0;
+};
+
+/**
+ * @param {number} low
+ * @param {number} high
+ * @returns {flatbuffers.Long}
+ */
+flatbuffers.Long.create = function(low, high) {
+  // Special-case zero to avoid GC overhead for default values
+  return low == 0 && high == 0 ? flatbuffers.Long.ZERO : new flatbuffers.Long(low, high);
+};
+
+/**
+ * @returns {number}
+ */
+flatbuffers.Long.prototype.toFloat64 = function() {
+  return (this.low >>> 0) + this.high * 0x100000000;
+};
+
+/**
+ * @param {flatbuffers.Long} other
+ * @returns {boolean}
+ */
+flatbuffers.Long.prototype.equals = function(other) {
+  return this.low == other.low && this.high == other.high;
+};
+
+/**
+ * @type {flatbuffers.Long}
+ * @const
+ */
+flatbuffers.Long.ZERO = new flatbuffers.Long(0, 0);
+
+/// @endcond
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Create a FlatBufferBuilder.
+ *
+ * @constructor
+ * @param {number=} opt_initial_size
+ */
+flatbuffers.Builder = function(opt_initial_size) {
+  if (!opt_initial_size) {
+    var initial_size = 1024;
+  } else {
+    var initial_size = opt_initial_size;
+  }
+
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   * @private
+   */
+  this.bb = flatbuffers.ByteBuffer.allocate(initial_size);
+
+  /**
+   * Remaining space in the ByteBuffer.
+   *
+   * @type {number}
+   * @private
+   */
+  this.space = initial_size;
+
+  /**
+   * Minimum alignment encountered so far.
+   *
+   * @type {number}
+   * @private
+   */
+  this.minalign = 1;
+
+  /**
+   * The vtable for the current table.
+   *
+   * @type {Array.<number>}
+   * @private
+   */
+  this.vtable = null;
+
+  /**
+   * The amount of fields we're actually using.
+   *
+   * @type {number}
+   * @private
+   */
+  this.vtable_in_use = 0;
+
+  /**
+   * Whether we are currently serializing a table.
+   *
+   * @type {boolean}
+   * @private
+   */
+  this.isNested = false;
+
+  /**
+   * Starting offset of the current struct/table.
+   *
+   * @type {number}
+   * @private
+   */
+  this.object_start = 0;
+
+  /**
+   * List of offsets of all vtables.
+   *
+   * @type {Array.<number>}
+   * @private
+   */
+  this.vtables = [];
+
+  /**
+   * For the current vector being built.
+   *
+   * @type {number}
+   * @private
+   */
+  this.vector_num_elems = 0;
+
+  /**
+   * False omits default values from the serialized data
+   *
+   * @type {boolean}
+   * @private
+   */
+  this.force_defaults = false;
+};
+
+flatbuffers.Builder.prototype.clear = function() {
+  this.bb.clear();
+  this.space = this.bb.capacity();
+  this.minalign = 1;
+  this.vtable = null;
+  this.vtable_in_use = 0;
+  this.isNested = false;
+  this.object_start = 0;
+  this.vtables = [];
+  this.vector_num_elems = 0;
+  this.force_defaults = false;
+};
+
+/**
+ * In order to save space, fields that are set to their default value
+ * don't get serialized into the buffer. Forcing defaults provides a
+ * way to manually disable this optimization.
+ *
+ * @param {boolean} forceDefaults true always serializes default values
+ */
+flatbuffers.Builder.prototype.forceDefaults = function(forceDefaults) {
+  this.force_defaults = forceDefaults;
+};
+
+/**
+ * Get the ByteBuffer representing the FlatBuffer. Only call this after you've
+ * called finish(). The actual data starts at the ByteBuffer's current position,
+ * not necessarily at 0.
+ *
+ * @returns {flatbuffers.ByteBuffer}
+ */
+flatbuffers.Builder.prototype.dataBuffer = function() {
+  return this.bb;
+};
+
+/**
+ * Get the bytes representing the FlatBuffer. Only call this after you've
+ * called finish().
+ *
+ * @returns {Uint8Array}
+ */
+flatbuffers.Builder.prototype.asUint8Array = function() {
+  return this.bb.bytes().subarray(this.bb.position(), this.bb.position() + this.offset());
+};
+
+/// @cond FLATBUFFERS_INTERNAL
+/**
+ * Prepare to write an element of `size` after `additional_bytes` have been
+ * written, e.g. if you write a string, you need to align such the int length
+ * field is aligned to 4 bytes, and the string data follows it directly. If all
+ * you need to do is alignment, `additional_bytes` will be 0.
+ *
+ * @param {number} size This is the of the new element to write
+ * @param {number} additional_bytes The padding size
+ */
+flatbuffers.Builder.prototype.prep = function(size, additional_bytes) {
+  // Track the biggest thing we've ever aligned to.
+  if (size > this.minalign) {
+    this.minalign = size;
+  }
+
+  // Find the amount of alignment needed such that `size` is properly
+  // aligned after `additional_bytes`
+  var align_size = ((~(this.bb.capacity() - this.space + additional_bytes)) + 1) & (size - 1);
+
+  // Reallocate the buffer if needed.
+  while (this.space < align_size + size + additional_bytes) {
+    var old_buf_size = this.bb.capacity();
+    this.bb = flatbuffers.Builder.growByteBuffer(this.bb);
+    this.space += this.bb.capacity() - old_buf_size;
+  }
+
+  this.pad(align_size);
+};
+
+/**
+ * @param {number} byte_size
+ */
+flatbuffers.Builder.prototype.pad = function(byte_size) {
+  for (var i = 0; i < byte_size; i++) {
+    this.bb.writeInt8(--this.space, 0);
+  }
+};
+
+/**
+ * @param {number} value
+ */
+flatbuffers.Builder.prototype.writeInt8 = function(value) {
+  this.bb.writeInt8(this.space -= 1, value);
+};
+
+/**
+ * @param {number} value
+ */
+flatbuffers.Builder.prototype.writeInt16 = function(value) {
+  this.bb.writeInt16(this.space -= 2, value);
+};
+
+/**
+ * @param {number} value
+ */
+flatbuffers.Builder.prototype.writeInt32 = function(value) {
+  this.bb.writeInt32(this.space -= 4, value);
+};
+
+/**
+ * @param {flatbuffers.Long} value
+ */
+flatbuffers.Builder.prototype.writeInt64 = function(value) {
+  this.bb.writeInt64(this.space -= 8, value);
+};
+
+/**
+ * @param {number} value
+ */
+flatbuffers.Builder.prototype.writeFloat32 = function(value) {
+  this.bb.writeFloat32(this.space -= 4, value);
+};
+
+/**
+ * @param {number} value
+ */
+flatbuffers.Builder.prototype.writeFloat64 = function(value) {
+  this.bb.writeFloat64(this.space -= 8, value);
+};
+/// @endcond
+
+/**
+ * Add an `int8` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param {number} value The `int8` to add the the buffer.
+ */
+flatbuffers.Builder.prototype.addInt8 = function(value) {
+  this.prep(1, 0);
+  this.writeInt8(value);
+};
+
+/**
+ * Add an `int16` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param {number} value The `int16` to add the the buffer.
+ */
+flatbuffers.Builder.prototype.addInt16 = function(value) {
+  this.prep(2, 0);
+  this.writeInt16(value);
+};
+
+/**
+ * Add an `int32` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param {number} value The `int32` to add the the buffer.
+ */
+flatbuffers.Builder.prototype.addInt32 = function(value) {
+  this.prep(4, 0);
+  this.writeInt32(value);
+};
+
+/**
+ * Add an `int64` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param {flatbuffers.Long} value The `int64` to add the the buffer.
+ */
+flatbuffers.Builder.prototype.addInt64 = function(value) {
+  this.prep(8, 0);
+  this.writeInt64(value);
+};
+
+/**
+ * Add a `float32` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param {number} value The `float32` to add the the buffer.
+ */
+flatbuffers.Builder.prototype.addFloat32 = function(value) {
+  this.prep(4, 0);
+  this.writeFloat32(value);
+};
+
+/**
+ * Add a `float64` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param {number} value The `float64` to add the the buffer.
+ */
+flatbuffers.Builder.prototype.addFloat64 = function(value) {
+  this.prep(8, 0);
+  this.writeFloat64(value);
+};
+
+/// @cond FLATBUFFERS_INTERNAL
+/**
+ * @param {number} voffset
+ * @param {number} value
+ * @param {number} defaultValue
+ */
+flatbuffers.Builder.prototype.addFieldInt8 = function(voffset, value, defaultValue) {
+  if (this.force_defaults || value != defaultValue) {
+    this.addInt8(value);
+    this.slot(voffset);
+  }
+};
+
+/**
+ * @param {number} voffset
+ * @param {number} value
+ * @param {number} defaultValue
+ */
+flatbuffers.Builder.prototype.addFieldInt16 = function(voffset, value, defaultValue) {
+  if (this.force_defaults || value != defaultValue) {
+    this.addInt16(value);
+    this.slot(voffset);
+  }
+};
+
+/**
+ * @param {number} voffset
+ * @param {number} value
+ * @param {number} defaultValue
+ */
+flatbuffers.Builder.prototype.addFieldInt32 = function(voffset, value, defaultValue) {
+  if (this.force_defaults || value != defaultValue) {
+    this.addInt32(value);
+    this.slot(voffset);
+  }
+};
+
+/**
+ * @param {number} voffset
+ * @param {flatbuffers.Long} value
+ * @param {flatbuffers.Long} defaultValue
+ */
+flatbuffers.Builder.prototype.addFieldInt64 = function(voffset, value, defaultValue) {
+  if (this.force_defaults || !value.equals(defaultValue)) {
+    this.addInt64(value);
+    this.slot(voffset);
+  }
+};
+
+/**
+ * @param {number} voffset
+ * @param {number} value
+ * @param {number} defaultValue
+ */
+flatbuffers.Builder.prototype.addFieldFloat32 = function(voffset, value, defaultValue) {
+  if (this.force_defaults || value != defaultValue) {
+    this.addFloat32(value);
+    this.slot(voffset);
+  }
+};
+
+/**
+ * @param {number} voffset
+ * @param {number} value
+ * @param {number} defaultValue
+ */
+flatbuffers.Builder.prototype.addFieldFloat64 = function(voffset, value, defaultValue) {
+  if (this.force_defaults || value != defaultValue) {
+    this.addFloat64(value);
+    this.slot(voffset);
+  }
+};
+
+/**
+ * @param {number} voffset
+ * @param {flatbuffers.Offset} value
+ * @param {flatbuffers.Offset} defaultValue
+ */
+flatbuffers.Builder.prototype.addFieldOffset = function(voffset, value, defaultValue) {
+  if (this.force_defaults || value != defaultValue) {
+    this.addOffset(value);
+    this.slot(voffset);
+  }
+};
+
+/**
+ * Structs are stored inline, so nothing additional is being added. `d` is always 0.
+ *
+ * @param {number} voffset
+ * @param {flatbuffers.Offset} value
+ * @param {flatbuffers.Offset} defaultValue
+ */
+flatbuffers.Builder.prototype.addFieldStruct = function(voffset, value, defaultValue) {
+  if (value != defaultValue) {
+    this.nested(value);
+    this.slot(voffset);
+  }
+};
+
+/**
+ * Structures are always stored inline, they need to be created right
+ * where they're used.  You'll get this assertion failure if you
+ * created it elsewhere.
+ *
+ * @param {flatbuffers.Offset} obj The offset of the created object
+ */
+flatbuffers.Builder.prototype.nested = function(obj) {
+  if (obj != this.offset()) {
+    throw new Error('FlatBuffers: struct must be serialized inline.');
+  }
+};
+
+/**
+ * Should not be creating any other object, string or vector
+ * while an object is being constructed
+ */
+flatbuffers.Builder.prototype.notNested = function() {
+  if (this.isNested) {
+    throw new Error('FlatBuffers: object serialization must not be nested.');
+  }
+};
+
+/**
+ * Set the current vtable at `voffset` to the current location in the buffer.
+ *
+ * @param {number} voffset
+ */
+flatbuffers.Builder.prototype.slot = function(voffset) {
+  this.vtable[voffset] = this.offset();
+};
+
+/**
+ * @returns {flatbuffers.Offset} Offset relative to the end of the buffer.
+ */
+flatbuffers.Builder.prototype.offset = function() {
+  return this.bb.capacity() - this.space;
+};
+
+/**
+ * Doubles the size of the backing ByteBuffer and copies the old data towards
+ * the end of the new buffer (since we build the buffer backwards).
+ *
+ * @param {flatbuffers.ByteBuffer} bb The current buffer with the existing data
+ * @returns {flatbuffers.ByteBuffer} A new byte buffer with the old data copied
+ * to it. The data is located at the end of the buffer.
+ *
+ * uint8Array.set() formally takes {Array<number>|ArrayBufferView}, so to pass
+ * it a uint8Array we need to suppress the type check:
+ * @suppress {checkTypes}
+ */
+flatbuffers.Builder.growByteBuffer = function(bb) {
+  var old_buf_size = bb.capacity();
+
+  // Ensure we don't grow beyond what fits in an int.
+  if (old_buf_size & 0xC0000000) {
+    throw new Error('FlatBuffers: cannot grow buffer beyond 2 gigabytes.');
+  }
+
+  var new_buf_size = old_buf_size << 1;
+  var nbb = flatbuffers.ByteBuffer.allocate(new_buf_size);
+  nbb.setPosition(new_buf_size - old_buf_size);
+  nbb.bytes().set(bb.bytes(), new_buf_size - old_buf_size);
+  return nbb;
+};
+/// @endcond
+
+/**
+ * Adds on offset, relative to where it will be written.
+ *
+ * @param {flatbuffers.Offset} offset The offset to add.
+ */
+flatbuffers.Builder.prototype.addOffset = function(offset) {
+  this.prep(flatbuffers.SIZEOF_INT, 0); // Ensure alignment is already done.
+  this.writeInt32(this.offset() - offset + flatbuffers.SIZEOF_INT);
+};
+
+/// @cond FLATBUFFERS_INTERNAL
+/**
+ * Start encoding a new object in the buffer.  Users will not usually need to
+ * call this directly. The FlatBuffers compiler will generate helper methods
+ * that call this method internally.
+ *
+ * @param {number} numfields
+ */
+flatbuffers.Builder.prototype.startObject = function(numfields) {
+  this.notNested();
+  if (this.vtable == null) {
+    this.vtable = [];
+  }
+  this.vtable_in_use = numfields;
+  for (var i = 0; i < numfields; i++) {
+    this.vtable[i] = 0; // This will push additional elements as needed
+  }
+  this.isNested = true;
+  this.object_start = this.offset();
+};
+
+/**
+ * Finish off writing the object that is under construction.
+ *
+ * @returns {flatbuffers.Offset} The offset to the object inside `dataBuffer`
+ */
+flatbuffers.Builder.prototype.endObject = function() {
+  if (this.vtable == null || !this.isNested) {
+    throw new Error('FlatBuffers: endObject called without startObject');
+  }
+
+  this.addInt32(0);
+  var vtableloc = this.offset();
+
+  // Trim trailing zeroes.
+  var i = this.vtable_in_use - 1;
+  for (; i >= 0 && this.vtable[i] == 0; i--) {}
+  var trimmed_size = i + 1;
+
+  // Write out the current vtable.
+  for (; i >= 0; i--) {
+    // Offset relative to the start of the table.
+    this.addInt16(this.vtable[i] != 0 ? vtableloc - this.vtable[i] : 0);
+  }
+
+  var standard_fields = 2; // The fields below:
+  this.addInt16(vtableloc - this.object_start);
+  var len = (trimmed_size + standard_fields) * flatbuffers.SIZEOF_SHORT;
+  this.addInt16(len);
+
+  // Search for an existing vtable that matches the current one.
+  var existing_vtable = 0;
+  var vt1 = this.space;
+outer_loop:
+  for (i = 0; i < this.vtables.length; i++) {
+    var vt2 = this.bb.capacity() - this.vtables[i];
+    if (len == this.bb.readInt16(vt2)) {
+      for (var j = flatbuffers.SIZEOF_SHORT; j < len; j += flatbuffers.SIZEOF_SHORT) {
+        if (this.bb.readInt16(vt1 + j) != this.bb.readInt16(vt2 + j)) {
+          continue outer_loop;
+        }
+      }
+      existing_vtable = this.vtables[i];
+      break;
+    }
+  }
+
+  if (existing_vtable) {
+    // Found a match:
+    // Remove the current vtable.
+    this.space = this.bb.capacity() - vtableloc;
+
+    // Point table to existing vtable.
+    this.bb.writeInt32(this.space, existing_vtable - vtableloc);
+  } else {
+    // No match:
+    // Add the location of the current vtable to the list of vtables.
+    this.vtables.push(this.offset());
+
+    // Point table to current vtable.
+    this.bb.writeInt32(this.bb.capacity() - vtableloc, this.offset() - vtableloc);
+  }
+
+  this.isNested = false;
+  return vtableloc;
+};
+/// @endcond
+
+/**
+ * Finalize a buffer, poiting to the given `root_table`.
+ *
+ * @param {flatbuffers.Offset} root_table
+ * @param {string=} opt_file_identifier
+ * @param {boolean=} opt_size_prefix
+ */
+flatbuffers.Builder.prototype.finish = function(root_table, opt_file_identifier, opt_size_prefix) {
+  var size_prefix = opt_size_prefix ? flatbuffers.SIZE_PREFIX_LENGTH : 0;
+  if (opt_file_identifier) {
+    var file_identifier = opt_file_identifier;
+    this.prep(this.minalign, flatbuffers.SIZEOF_INT +
+      flatbuffers.FILE_IDENTIFIER_LENGTH + size_prefix);
+    if (file_identifier.length != flatbuffers.FILE_IDENTIFIER_LENGTH) {
+      throw new Error('FlatBuffers: file identifier must be length ' +
+        flatbuffers.FILE_IDENTIFIER_LENGTH);
+    }
+    for (var i = flatbuffers.FILE_IDENTIFIER_LENGTH - 1; i >= 0; i--) {
+      this.writeInt8(file_identifier.charCodeAt(i));
+    }
+  }
+  this.prep(this.minalign, flatbuffers.SIZEOF_INT + size_prefix);
+  this.addOffset(root_table);
+  if (size_prefix) {
+    this.addInt32(this.bb.capacity() - this.space);
+  }
+  this.bb.setPosition(this.space);
+};
+
+/**
+ * Finalize a size prefixed buffer, pointing to the given `root_table`.
+ *
+ * @param {flatbuffers.Offset} root_table
+ * @param {string=} opt_file_identifier
+ */
+flatbuffers.Builder.prototype.finishSizePrefixed = function (root_table, opt_file_identifier) {
+  this.finish(root_table, opt_file_identifier, true);
+};
+
+/// @cond FLATBUFFERS_INTERNAL
+/**
+ * This checks a required field has been set in a given table that has
+ * just been constructed.
+ *
+ * @param {flatbuffers.Offset} table
+ * @param {number} field
+ */
+flatbuffers.Builder.prototype.requiredField = function(table, field) {
+  var table_start = this.bb.capacity() - table;
+  var vtable_start = table_start - this.bb.readInt32(table_start);
+  var ok = this.bb.readInt16(vtable_start + field) != 0;
+
+  // If this fails, the caller will show what field needs to be set.
+  if (!ok) {
+    throw new Error('FlatBuffers: field ' + field + ' must be set');
+  }
+};
+
+/**
+ * Start a new array/vector of objects.  Users usually will not call
+ * this directly. The FlatBuffers compiler will create a start/end
+ * method for vector types in generated code.
+ *
+ * @param {number} elem_size The size of each element in the array
+ * @param {number} num_elems The number of elements in the array
+ * @param {number} alignment The alignment of the array
+ */
+flatbuffers.Builder.prototype.startVector = function(elem_size, num_elems, alignment) {
+  this.notNested();
+  this.vector_num_elems = num_elems;
+  this.prep(flatbuffers.SIZEOF_INT, elem_size * num_elems);
+  this.prep(alignment, elem_size * num_elems); // Just in case alignment > int.
+};
+
+/**
+ * Finish off the creation of an array and all its elements. The array must be
+ * created with `startVector`.
+ *
+ * @returns {flatbuffers.Offset} The offset at which the newly created array
+ * starts.
+ */
+flatbuffers.Builder.prototype.endVector = function() {
+  this.writeInt32(this.vector_num_elems);
+  return this.offset();
+};
+/// @endcond
+
+/**
+ * Encode the string `s` in the buffer using UTF-8. If a Uint8Array is passed
+ * instead of a string, it is assumed to contain valid UTF-8 encoded data.
+ *
+ * @param {string|Uint8Array} s The string to encode
+ * @return {flatbuffers.Offset} The offset in the buffer where the encoded string starts
+ */
+flatbuffers.Builder.prototype.createString = function(s) {
+  if (s instanceof Uint8Array) {
+    var utf8 = s;
+  } else {
+    var utf8 = [];
+    var i = 0;
+
+    while (i < s.length) {
+      var codePoint;
+
+      // Decode UTF-16
+      var a = s.charCodeAt(i++);
+      if (a < 0xD800 || a >= 0xDC00) {
+        codePoint = a;
+      } else {
+        var b = s.charCodeAt(i++);
+        codePoint = (a << 10) + b + (0x10000 - (0xD800 << 10) - 0xDC00);
+      }
+
+      // Encode UTF-8
+      if (codePoint < 0x80) {
+        utf8.push(codePoint);
+      } else {
+        if (codePoint < 0x800) {
+          utf8.push(((codePoint >> 6) & 0x1F) | 0xC0);
+        } else {
+          if (codePoint < 0x10000) {
+            utf8.push(((codePoint >> 12) & 0x0F) | 0xE0);
+          } else {
+            utf8.push(
+              ((codePoint >> 18) & 0x07) | 0xF0,
+              ((codePoint >> 12) & 0x3F) | 0x80);
+          }
+          utf8.push(((codePoint >> 6) & 0x3F) | 0x80);
+        }
+        utf8.push((codePoint & 0x3F) | 0x80);
+      }
+    }
+  }
+
+  this.addInt8(0);
+  this.startVector(1, utf8.length, 1);
+  this.bb.setPosition(this.space -= utf8.length);
+  for (var i = 0, offset = this.space, bytes = this.bb.bytes(); i < utf8.length; i++) {
+    bytes[offset++] = utf8[i];
+  }
+  return this.endVector();
+};
+
+/**
+ * A helper function to avoid generated code depending on this file directly.
+ *
+ * @param {number} low
+ * @param {number} high
+ * @returns {flatbuffers.Long}
+ */
+flatbuffers.Builder.prototype.createLong = function(low, high) {
+  return flatbuffers.Long.create(low, high);
+};
+////////////////////////////////////////////////////////////////////////////////
+/// @cond FLATBUFFERS_INTERNAL
+/**
+ * Create a new ByteBuffer with a given array of bytes (`Uint8Array`).
+ *
+ * @constructor
+ * @param {Uint8Array} bytes
+ */
+flatbuffers.ByteBuffer = function(bytes) {
+  /**
+   * @type {Uint8Array}
+   * @private
+   */
+  this.bytes_ = bytes;
+
+  /**
+   * @type {number}
+   * @private
+   */
+  this.position_ = 0;
+};
+
+/**
+ * Create and allocate a new ByteBuffer with a given size.
+ *
+ * @param {number} byte_size
+ * @returns {flatbuffers.ByteBuffer}
+ */
+flatbuffers.ByteBuffer.allocate = function(byte_size) {
+  return new flatbuffers.ByteBuffer(new Uint8Array(byte_size));
+};
+
+flatbuffers.ByteBuffer.prototype.clear = function() {
+  this.position_ = 0;
+};
+
+/**
+ * Get the underlying `Uint8Array`.
+ *
+ * @returns {Uint8Array}
+ */
+flatbuffers.ByteBuffer.prototype.bytes = function() {
+  return this.bytes_;
+};
+
+/**
+ * Get the buffer's position.
+ *
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.position = function() {
+  return this.position_;
+};
+
+/**
+ * Set the buffer's position.
+ *
+ * @param {number} position
+ */
+flatbuffers.ByteBuffer.prototype.setPosition = function(position) {
+  this.position_ = position;
+};
+
+/**
+ * Get the buffer's capacity.
+ *
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.capacity = function() {
+  return this.bytes_.length;
+};
+
+/**
+ * @param {number} offset
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.readInt8 = function(offset) {
+  return this.readUint8(offset) << 24 >> 24;
+};
+
+/**
+ * @param {number} offset
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.readUint8 = function(offset) {
+  return this.bytes_[offset];
+};
+
+/**
+ * @param {number} offset
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.readInt16 = function(offset) {
+  return this.readUint16(offset) << 16 >> 16;
+};
+
+/**
+ * @param {number} offset
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.readUint16 = function(offset) {
+  return this.bytes_[offset] | this.bytes_[offset + 1] << 8;
+};
+
+/**
+ * @param {number} offset
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.readInt32 = function(offset) {
+  return this.bytes_[offset] | this.bytes_[offset + 1] << 8 | this.bytes_[offset + 2] << 16 | this.bytes_[offset + 3] << 24;
+};
+
+/**
+ * @param {number} offset
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.readUint32 = function(offset) {
+  return this.readInt32(offset) >>> 0;
+};
+
+/**
+ * @param {number} offset
+ * @returns {flatbuffers.Long}
+ */
+flatbuffers.ByteBuffer.prototype.readInt64 = function(offset) {
+  return new flatbuffers.Long(this.readInt32(offset), this.readInt32(offset + 4));
+};
+
+/**
+ * @param {number} offset
+ * @returns {flatbuffers.Long}
+ */
+flatbuffers.ByteBuffer.prototype.readUint64 = function(offset) {
+  return new flatbuffers.Long(this.readUint32(offset), this.readUint32(offset + 4));
+};
+
+/**
+ * @param {number} offset
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.readFloat32 = function(offset) {
+  flatbuffers.int32[0] = this.readInt32(offset);
+  return flatbuffers.float32[0];
+};
+
+/**
+ * @param {number} offset
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.readFloat64 = function(offset) {
+  flatbuffers.int32[flatbuffers.isLittleEndian ? 0 : 1] = this.readInt32(offset);
+  flatbuffers.int32[flatbuffers.isLittleEndian ? 1 : 0] = this.readInt32(offset + 4);
+  return flatbuffers.float64[0];
+};
+
+/**
+ * @param {number} offset
+ * @param {number|boolean} value
+ */
+flatbuffers.ByteBuffer.prototype.writeInt8 = function(offset, value) {
+  this.bytes_[offset] = /** @type {number} */(value);
+};
+
+/**
+ * @param {number} offset
+ * @param {number} value
+ */
+flatbuffers.ByteBuffer.prototype.writeUint8 = function(offset, value) {
+  this.bytes_[offset] = value;
+};
+
+/**
+ * @param {number} offset
+ * @param {number} value
+ */
+flatbuffers.ByteBuffer.prototype.writeInt16 = function(offset, value) {
+  this.bytes_[offset] = value;
+  this.bytes_[offset + 1] = value >> 8;
+};
+
+/**
+ * @param {number} offset
+ * @param {number} value
+ */
+flatbuffers.ByteBuffer.prototype.writeUint16 = function(offset, value) {
+    this.bytes_[offset] = value;
+    this.bytes_[offset + 1] = value >> 8;
+};
+
+/**
+ * @param {number} offset
+ * @param {number} value
+ */
+flatbuffers.ByteBuffer.prototype.writeInt32 = function(offset, value) {
+  this.bytes_[offset] = value;
+  this.bytes_[offset + 1] = value >> 8;
+  this.bytes_[offset + 2] = value >> 16;
+  this.bytes_[offset + 3] = value >> 24;
+};
+
+/**
+ * @param {number} offset
+ * @param {number} value
+ */
+flatbuffers.ByteBuffer.prototype.writeUint32 = function(offset, value) {
+    this.bytes_[offset] = value;
+    this.bytes_[offset + 1] = value >> 8;
+    this.bytes_[offset + 2] = value >> 16;
+    this.bytes_[offset + 3] = value >> 24;
+};
+
+/**
+ * @param {number} offset
+ * @param {flatbuffers.Long} value
+ */
+flatbuffers.ByteBuffer.prototype.writeInt64 = function(offset, value) {
+  this.writeInt32(offset, value.low);
+  this.writeInt32(offset + 4, value.high);
+};
+
+/**
+ * @param {number} offset
+ * @param {flatbuffers.Long} value
+ */
+flatbuffers.ByteBuffer.prototype.writeUint64 = function(offset, value) {
+    this.writeUint32(offset, value.low);
+    this.writeUint32(offset + 4, value.high);
+};
+
+/**
+ * @param {number} offset
+ * @param {number} value
+ */
+flatbuffers.ByteBuffer.prototype.writeFloat32 = function(offset, value) {
+  flatbuffers.float32[0] = value;
+  this.writeInt32(offset, flatbuffers.int32[0]);
+};
+
+/**
+ * @param {number} offset
+ * @param {number} value
+ */
+flatbuffers.ByteBuffer.prototype.writeFloat64 = function(offset, value) {
+  flatbuffers.float64[0] = value;
+  this.writeInt32(offset, flatbuffers.int32[flatbuffers.isLittleEndian ? 0 : 1]);
+  this.writeInt32(offset + 4, flatbuffers.int32[flatbuffers.isLittleEndian ? 1 : 0]);
+};
+
+/**
+ * Return the file identifier.   Behavior is undefined for FlatBuffers whose
+ * schema does not include a file_identifier (likely points at padding or the
+ * start of a the root vtable).
+ * @returns {string}
+ */
+flatbuffers.ByteBuffer.prototype.getBufferIdentifier = function() {
+  if (this.bytes_.length < this.position_ + flatbuffers.SIZEOF_INT +
+      flatbuffers.FILE_IDENTIFIER_LENGTH) {
+    throw new Error(
+        'FlatBuffers: ByteBuffer is too short to contain an identifier.');
+  }
+  var result = "";
+  for (var i = 0; i < flatbuffers.FILE_IDENTIFIER_LENGTH; i++) {
+    result += String.fromCharCode(
+        this.readInt8(this.position_ + flatbuffers.SIZEOF_INT + i));
+  }
+  return result;
+};
+
+/**
+ * Look up a field in the vtable, return an offset into the object, or 0 if the
+ * field is not present.
+ *
+ * @param {number} bb_pos
+ * @param {number} vtable_offset
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.__offset = function(bb_pos, vtable_offset) {
+  var vtable = bb_pos - this.readInt32(bb_pos);
+  return vtable_offset < this.readInt16(vtable) ? this.readInt16(vtable + vtable_offset) : 0;
+};
+
+/**
+ * Initialize any Table-derived type to point to the union at the given offset.
+ *
+ * @param {flatbuffers.Table} t
+ * @param {number} offset
+ * @returns {flatbuffers.Table}
+ */
+flatbuffers.ByteBuffer.prototype.__union = function(t, offset) {
+  t.bb_pos = offset + this.readInt32(offset);
+  t.bb = this;
+  return t;
+};
+
+/**
+ * Create a JavaScript string from UTF-8 data stored inside the FlatBuffer.
+ * This allocates a new string and converts to wide chars upon each access.
+ *
+ * To avoid the conversion to UTF-16, pass flatbuffers.Encoding.UTF8_BYTES as
+ * the "optionalEncoding" argument. This is useful for avoiding conversion to
+ * and from UTF-16 when the data will just be packaged back up in another
+ * FlatBuffer later on.
+ *
+ * @param {number} offset
+ * @param {flatbuffers.Encoding=} opt_encoding Defaults to UTF16_STRING
+ * @returns {string|Uint8Array}
+ */
+flatbuffers.ByteBuffer.prototype.__string = function(offset, opt_encoding) {
+  offset += this.readInt32(offset);
+
+  var length = this.readInt32(offset);
+  var result = '';
+  var i = 0;
+
+  offset += flatbuffers.SIZEOF_INT;
+
+  if (opt_encoding === flatbuffers.Encoding.UTF8_BYTES) {
+    return this.bytes_.subarray(offset, offset + length);
+  }
+
+  while (i < length) {
+    var codePoint;
+
+    // Decode UTF-8
+    var a = this.readUint8(offset + i++);
+    if (a < 0xC0) {
+      codePoint = a;
+    } else {
+      var b = this.readUint8(offset + i++);
+      if (a < 0xE0) {
+        codePoint =
+          ((a & 0x1F) << 6) |
+          (b & 0x3F);
+      } else {
+        var c = this.readUint8(offset + i++);
+        if (a < 0xF0) {
+          codePoint =
+            ((a & 0x0F) << 12) |
+            ((b & 0x3F) << 6) |
+            (c & 0x3F);
+        } else {
+          var d = this.readUint8(offset + i++);
+          codePoint =
+            ((a & 0x07) << 18) |
+            ((b & 0x3F) << 12) |
+            ((c & 0x3F) << 6) |
+            (d & 0x3F);
+        }
+      }
+    }
+
+    // Encode UTF-16
+    if (codePoint < 0x10000) {
+      result += String.fromCharCode(codePoint);
+    } else {
+      codePoint -= 0x10000;
+      result += String.fromCharCode(
+        (codePoint >> 10) + 0xD800,
+        (codePoint & ((1 << 10) - 1)) + 0xDC00);
+    }
+  }
+
+  return result;
+};
+
+/**
+ * Retrieve the relative offset stored at "offset"
+ * @param {number} offset
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.__indirect = function(offset) {
+  return offset + this.readInt32(offset);
+};
+
+/**
+ * Get the start of data of a vector whose offset is stored at "offset" in this object.
+ *
+ * @param {number} offset
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.__vector = function(offset) {
+  return offset + this.readInt32(offset) + flatbuffers.SIZEOF_INT; // data starts after the length
+};
+
+/**
+ * Get the length of a vector whose offset is stored at "offset" in this object.
+ *
+ * @param {number} offset
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.__vector_len = function(offset) {
+  return this.readInt32(offset + this.readInt32(offset));
+};
+
+/**
+ * @param {string} ident
+ * @returns {boolean}
+ */
+flatbuffers.ByteBuffer.prototype.__has_identifier = function(ident) {
+  if (ident.length != flatbuffers.FILE_IDENTIFIER_LENGTH) {
+    throw new Error('FlatBuffers: file identifier must be length ' +
+                    flatbuffers.FILE_IDENTIFIER_LENGTH);
+  }
+  for (var i = 0; i < flatbuffers.FILE_IDENTIFIER_LENGTH; i++) {
+    if (ident.charCodeAt(i) != this.readInt8(this.position_ + flatbuffers.SIZEOF_INT + i)) {
+      return false;
+    }
+  }
+  return true;
+};
+
+/**
+ * A helper function to avoid generated code depending on this file directly.
+ *
+ * @param {number} low
+ * @param {number} high
+ * @returns {flatbuffers.Long}
+ */
+flatbuffers.ByteBuffer.prototype.createLong = function(low, high) {
+  return flatbuffers.Long.create(low, high);
+};
+
+// Exports for Node.js and RequireJS
+this.flatbuffers = flatbuffers;
+
+/// @endcond
+/// @}
diff --git a/third_party/flatbuffers/lobster/flatbuffers.lobster b/third_party/flatbuffers/lobster/flatbuffers.lobster
new file mode 100644
index 0000000..0f1c15d
--- /dev/null
+++ b/third_party/flatbuffers/lobster/flatbuffers.lobster
@@ -0,0 +1,284 @@
+// 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.
+
+import std
+
+namespace flatbuffers
+
+class handle:
+    buf_:string
+    pos_:int
+
+// More strongly typed than a naked int, at no cost.
+struct offset:
+    o:int
+
+enum sizeof:
+    sz_8 = 1
+    sz_16 = 2
+    sz_32 = 4
+    sz_64 = 8
+    sz_voffset = 2
+    sz_uoffset = 4
+    sz_soffset = 4
+    sz_metadata_fields = 2
+
+class builder:
+    buf = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    current_vtable:[int] = []
+    head = 0
+    minalign = 1
+    object_end = 0
+    vtables:[int] = []
+    nested = false
+    finished = false
+
+    // Optionally call this right after creating the builder for a larger initial buffer.
+    def Initial(initial_size:int):
+        buf = "\x00".repeat_string(initial_size)
+
+    def Start():
+        // Get the start of useful data in the underlying byte buffer.
+        return buf.length - head
+
+    def Offset():
+        // Offset relative to the end of the buffer.
+        return offset { head }
+
+    // Returns a copy of the part of the buffer containing only the finished FlatBuffer
+    def SizedCopy():
+        assert finished
+        return buf.substring(Start(), -1)
+
+    def StartNesting():
+        assert not nested
+        nested = true
+
+    def EndNesting():
+        assert nested
+        nested = false
+
+    def StartObject(numfields):
+        StartNesting()
+        current_vtable = map(numfields): 0
+        object_end = head
+        minalign = 1
+
+    def EndObject():
+        EndNesting()
+        // Prepend a zero scalar to the object. Later in this function we'll
+        // write an offset here that points to the object's vtable:
+        PrependInt32(0)
+        let object_offset = head
+        // Write out new vtable speculatively.
+        let vtable_size = (current_vtable.length + sz_metadata_fields) * sz_voffset
+        while current_vtable.length:
+            let o = current_vtable.pop()
+            PrependVOffsetT(if o: object_offset - o else: 0)
+        // The two metadata fields are written last.
+        // First, store the object bytesize:
+        PrependVOffsetT(object_offset - object_end)
+        // Second, store the vtable bytesize:
+        PrependVOffsetT(vtable_size)
+        // Search backwards through existing vtables, because similar vtables
+        // are likely to have been recently appended. See
+        // BenchmarkVtableDeduplication for a case in which this heuristic
+        // saves about 30% of the time used in writing objects with duplicate
+        // tables.
+        def find_existing_table():
+            reverse(vtables) vt2_offset:
+                // Find the other vtable:
+                let vt2_start = buf.length - vt2_offset
+                let vt2_len = buf.read_int16_le(vt2_start)
+                // Compare the other vtable to the one under consideration.
+                // If they are equal, return the offset:
+                if vtable_size == vt2_len and
+                    not compare_substring(buf, Start(), buf, vt2_start, vtable_size):
+                        return vt2_offset
+            return 0
+        let existing_vtable = find_existing_table()
+        if existing_vtable:
+            // Found a duplicate vtable, remove the one we wrote.
+            head = object_offset
+            // Write the offset to the found vtable in the
+            // already-allocated offset at the beginning of this object:
+            buf.write_int32_le(Start(), existing_vtable - object_offset)
+        else:
+            // Did not find a vtable, so keep the one we wrote.
+            // Next, write the offset to the new vtable in the
+            // already-allocated offset at the beginning of this object:
+            buf.write_int32_le(buf.length - object_offset, head - object_offset)
+            // Finally, store this vtable in memory for future
+            // deduplication:
+            vtables.push(head)
+        return offset { object_offset }
+
+    def Pad(n):
+        for(n):
+            buf, head = buf.write_int8_le_back(head, 0)
+
+    def Prep(size, additional_bytes):
+        // Track the biggest thing we've ever aligned to.
+        if size > minalign:
+            minalign = size
+        // Find the amount of alignment needed such that `size` is properly
+        // aligned after `additionalBytes`:
+        let align_size = ((~(head + additional_bytes)) + 1) & (size - 1)
+        Pad(align_size)
+
+    def PrependUOffsetTRelative(off:offset):
+        // Prepends an unsigned offset into vector data, relative to where it will be written.
+        Prep(sz_uoffset, 0)
+        assert off.o <= head
+        PlaceUOffsetT(head - off.o + sz_uoffset)
+
+    def StartVector(elem_size, num_elems, alignment):
+        // Initializes bookkeeping for writing a new vector.
+        StartNesting()
+        Prep(sz_32, elem_size * num_elems)
+        Prep(alignment, elem_size * num_elems)  // In case alignment > int.
+        return Offset()
+
+    def EndVector(vector_num_elems):
+        EndNesting()
+        // we already made space for this, so write without PrependUint32
+        PlaceUOffsetT(vector_num_elems)
+        return Offset()
+
+    def CreateString(s:string):
+        // writes a null-terminated byte string.
+        StartNesting()
+        Prep(sz_32, s.length + 1)
+        buf, head = buf.write_substring_back(head, s, true)
+        return EndVector(s.length)
+
+    def CreateByteVector(s:string):
+        // writes a non-null-terminated byte string.
+        StartNesting()
+        Prep(sz_32, s.length)
+        buf, head = buf.write_substring_back(head, s, false)
+        return EndVector(s.length)
+
+    def Slot(slotnum):
+        assert nested
+        while current_vtable.length <= slotnum: current_vtable.push(0)
+        current_vtable[slotnum] = head
+
+    def __Finish(root_table:offset, size_prefix:int):
+        // Finish finalizes a buffer, pointing to the given root_table
+        assert not finished
+        assert not nested
+        var prep_size = sz_32
+        if size_prefix:
+            prep_size += sz_32
+        Prep(minalign, prep_size)
+        PrependUOffsetTRelative(root_table)
+        if size_prefix:
+            PrependInt32(head)
+        finished = true
+        return Start()
+
+    def Finish(root_table:offset):
+        return __Finish(root_table, false)
+
+    def FinishSizePrefixed(root_table:offset):
+        return __Finish(root_table, true)
+
+    def PrependBool(x):
+        buf, head = buf.write_int8_le_back(head, x)
+
+    def PrependByte(x):
+        buf, head = buf.write_int8_le_back(head, x)
+
+    def PrependUint8(x):
+        buf, head = buf.write_int8_le_back(head, x)
+
+    def PrependUint16(x):
+        Prep(sz_16, 0)
+        buf, head = buf.write_int16_le_back(head, x)
+
+    def PrependUint32(x):
+        Prep(sz_32, 0)
+        buf, head = buf.write_int32_le_back(head, x)
+
+    def PrependUint64(x):
+        Prep(sz_64, 0)
+        buf, head = buf.write_int64_le_back(head, x)
+
+    def PrependInt8(x):
+        buf, head = buf.write_int8_le_back(head, x)
+
+    def PrependInt16(x):
+        Prep(sz_16, 0)
+        buf, head = buf.write_int16_le_back(head, x)
+
+    def PrependInt32(x):
+        Prep(sz_32, 0)
+        buf, head = buf.write_int32_le_back(head, x)
+
+    def PrependInt64(x):
+        Prep(sz_64, 0)
+        buf, head = buf.write_int64_le_back(head, x)
+
+    def PrependFloat32(x):
+        Prep(sz_32, 0)
+        buf, head = buf.write_float32_le_back(head, x)
+
+    def PrependFloat64(x):
+        Prep(sz_64, 0)
+        buf, head = buf.write_float64_le_back(head, x)
+
+    def PrependVOffsetT(x):
+        Prep(sz_voffset, 0)
+        buf, head = buf.write_int16_le_back(head, x)
+
+    def PlaceVOffsetT(x):
+        buf, head = buf.write_int16_le_back(head, x)
+
+    def PlaceSOffsetT(x):
+        buf, head = buf.write_int32_le_back(head, x)
+
+    def PlaceUOffsetT(x):
+        buf, head = buf.write_int32_le_back(head, x)
+
+    def PrependSlot(o:int, x, d, f):
+        if x != d:
+            f(x)
+            Slot(o)
+
+    def PrependBoolSlot(o, x, d): PrependSlot(o, x, d): PrependBool(_)
+    def PrependByteSlot(o, x, d): PrependSlot(o, x, d): PrependByte(_)
+    def PrependUint8Slot(o, x, d): PrependSlot(o, x, d): PrependUint8(_)
+    def PrependUint16Slot(o, x, d): PrependSlot(o, x, d): PrependUint16(_)
+    def PrependUint32Slot(o, x, d): PrependSlot(o, x, d): PrependUint32(_)
+    def PrependUint64Slot(o, x, d): PrependSlot(o, x, d): PrependUint64(_)
+    def PrependInt8Slot(o, x, d): PrependSlot(o, x, d): PrependInt8(_)
+    def PrependInt16Slot(o, x, d): PrependSlot(o, x, d): PrependInt16(_)
+    def PrependInt32Slot(o, x, d): PrependSlot(o, x, d): PrependInt32(_)
+    def PrependInt64Slot(o, x, d): PrependSlot(o, x, d): PrependInt64(_)
+    def PrependFloat32Slot(o, x, d): PrependSlot(o, x, d): PrependFloat32(_)
+    def PrependFloat64Slot(o, x, d): PrependSlot(o, x, d): PrependFloat64(_)
+
+    def PrependUOffsetTRelativeSlot(o:int, x:offset):
+        if x.o:
+            PrependUOffsetTRelative(x)
+            Slot(o)
+
+    def PrependStructSlot(v:int, x:offset):
+        if x.o:
+            // Structs are always stored inline, so need to be created right
+            // where they are used. You'll get this error if you created it
+            // elsewhere.
+            assert x.o == head
+            Slot(v)
diff --git a/third_party/flatbuffers/lua/flatbuffers.lua b/third_party/flatbuffers/lua/flatbuffers.lua
new file mode 100644
index 0000000..1c85c4e
--- /dev/null
+++ b/third_party/flatbuffers/lua/flatbuffers.lua
@@ -0,0 +1,8 @@
+local m = {}
+
+m.Builder = require("flatbuffers.builder").New
+m.N = require("flatbuffers.numTypes")
+m.view = require("flatbuffers.view")
+m.binaryArray = require("flatbuffers.binaryarray")
+
+return m
\ No newline at end of file
diff --git a/third_party/flatbuffers/lua/flatbuffers/binaryarray.lua b/third_party/flatbuffers/lua/flatbuffers/binaryarray.lua
new file mode 100644
index 0000000..bf728cd
--- /dev/null
+++ b/third_party/flatbuffers/lua/flatbuffers/binaryarray.lua
@@ -0,0 +1,123 @@
+local m = {} -- the module table
+
+local mt = {} -- the module metatable
+
+-- given a binary array, set a metamethod to return its length
+-- (e.g., #binaryArray, calls this)
+function mt:__len()
+    return self.size
+end
+
+-- Create a new binary array of an initial size
+function m.New(sizeOrString)
+    -- the array storage itself
+    local o = {}
+    
+    if type(sizeOrString) == "string" then
+        o.str = sizeOrString
+        o.size = #sizeOrString
+    elseif type(sizeOrString) == "number" then
+        o.data = {}
+        o.size = sizeOrString
+    else
+        error("Expect a integer size value or string to construct a binary array")
+    end
+    -- set the inheritance
+    setmetatable(o, {__index = mt, __len = mt.__len})
+    return o
+end
+
+-- Get a slice of the binary array from start to end position
+function mt:Slice(startPos, endPos)
+    startPos = startPos or 0
+    endPos = endPos or self.size
+    local d = self.data
+    if d then
+        -- if the self.data is defined, we are building the buffer
+        -- in a Lua table
+        
+        -- new table to store the slice components
+        local b = {}
+        
+        -- starting with the startPos, put all
+        -- values into the new table to be concat later
+        -- updated the startPos based on the size of the
+        -- value
+        while startPos < endPos do
+            local v = d[startPos] or '/0'
+            table.insert(b, v)
+            startPos = startPos + #v
+        end
+
+        -- combine the table of strings into one string
+        -- this is faster than doing a bunch of concats by themselves
+        return table.concat(b)
+    else
+        -- n.b start/endPos are 0-based incoming, so need to convert
+        --     correctly. in python a slice includes start -> end - 1
+        return self.str:sub(startPos+1, endPos)
+    end
+end
+
+-- Grow the binary array to a new size, placing the exisiting data
+-- at then end of the new array
+function mt:Grow(newsize)
+    -- the new table to store the data
+    local newT = {}
+    
+    -- the offset to be applied to existing entries
+    local offset = newsize - self.size
+    
+    -- loop over all the current entries and
+    -- add them to the new table at the correct
+    -- offset location
+    local d = self.data
+    for i,data in pairs(d) do
+        newT[i + offset] = data
+    end
+    
+    -- update this storage with the new table and size
+    self.data = newT
+    self.size = newsize
+end
+
+-- memorization for padding strings
+local pads = {}
+
+-- pad the binary with n \0 bytes at the starting position
+function mt:Pad(n, startPos)
+    -- use memorization to avoid creating a bunch of strings
+    -- all the time
+    local s = pads[n]
+    if not s then
+        s = string.rep('\0', n)
+        pads[n] = s
+    end
+    
+    -- store the padding string at the start position in the
+    -- Lua table
+    self.data[startPos] = s
+end
+
+-- Sets the binary array value at the specified position
+function mt:Set(value, position)
+    self.data[position] = value
+end
+
+-- locals for slightly faster access
+local sunpack = string.unpack
+local spack = string.pack
+
+-- Pack the data into a binary representation
+function m.Pack(fmt, ...)
+    return spack(fmt, ...)
+end
+
+-- Unpack the data from a binary representation in
+-- a Lua value
+function m.Unpack(fmt, s, pos)
+    return sunpack(fmt, s.str, pos + 1)
+end
+
+-- Return the binary array module
+return m
\ No newline at end of file
diff --git a/third_party/flatbuffers/lua/flatbuffers/builder.lua b/third_party/flatbuffers/lua/flatbuffers/builder.lua
new file mode 100644
index 0000000..2fb2220
--- /dev/null
+++ b/third_party/flatbuffers/lua/flatbuffers/builder.lua
@@ -0,0 +1,369 @@
+local N = require("flatbuffers.numTypes")
+local ba = require("flatbuffers.binaryarray")
+local compat = require("flatbuffers.compat")
+
+local m = {}
+
+local mt = {}
+
+-- get locals for faster access
+local VOffsetT  = N.VOffsetT
+local UOffsetT  = N.UOffsetT
+local SOffsetT  = N.SOffsetT
+local Bool      = N.Bool
+local Uint8     = N.Uint8
+local Uint16    = N.Uint16
+local Uint32    = N.Uint32
+local Uint64    = N.Uint64
+local Int8      = N.Int8
+local Int16     = N.Int16
+local Int32     = N.Int32
+local Int64     = N.Int64
+local Float32   = N.Float32
+local Float64   = N.Float64
+
+local MAX_BUFFER_SIZE = 0x80000000 -- 2 GB
+local VtableMetadataFields = 2
+
+local getAlignSize = compat.GetAlignSize
+
+local function vtableEqual(a, objectStart, b)
+    UOffsetT:EnforceNumber(objectStart)
+    if (#a * VOffsetT.bytewidth) ~= #b then
+        return false
+    end
+
+    for i, elem in ipairs(a) do
+        local x = string.unpack(VOffsetT.packFmt, b, 1 + (i - 1) * VOffsetT.bytewidth)
+        if x ~= 0 or elem ~= 0 then
+            local y = objectStart - elem
+            if x ~= y then
+                return false
+            end
+        end
+    end
+    return true
+end
+
+function m.New(initialSize)
+    assert(0 <= initialSize and initialSize < MAX_BUFFER_SIZE)
+    local o =
+    {
+        finished = false,
+        bytes = ba.New(initialSize),
+        nested = false,
+        head = initialSize,
+        minalign = 1,
+        vtables = {}
+    }
+    setmetatable(o, {__index = mt})
+    return o
+end
+
+function mt:Output(full)
+    assert(self.finished, "Builder Not Finished")
+    if full then
+        return self.bytes:Slice()
+    else
+        return self.bytes:Slice(self.head)
+    end
+end
+
+function mt:StartObject(numFields)
+    assert(not self.nested)
+
+    local vtable = {}
+
+    for _=1,numFields do
+        table.insert(vtable, 0)
+    end
+
+    self.currentVTable = vtable
+    self.objectEnd = self:Offset()
+    self.nested = true
+end
+
+function mt:WriteVtable()
+    self:PrependSOffsetTRelative(0)
+    local objectOffset = self:Offset()
+
+    local exisitingVTable
+    local i = #self.vtables
+    while i >= 1 do
+        if self.vtables[i] == 0 then
+            table.remove(self.vtables,i)
+        end
+        i = i - 1
+    end
+
+    i = #self.vtables
+    while i >= 1 do
+
+        local vt2Offset = self.vtables[i]
+        local vt2Start = #self.bytes - vt2Offset
+        local vt2lenstr = self.bytes:Slice(vt2Start, vt2Start+1)
+        local vt2Len = string.unpack(VOffsetT.packFmt, vt2lenstr, 1)
+
+        local metadata = VtableMetadataFields * VOffsetT.bytewidth
+        local vt2End = vt2Start + vt2Len
+        local vt2 = self.bytes:Slice(vt2Start+metadata,vt2End)
+
+        if vtableEqual(self.currentVTable, objectOffset, vt2) then
+            exisitingVTable = vt2Offset
+            break
+        end
+
+        i = i - 1
+    end
+
+    if not exisitingVTable then
+        i = #self.currentVTable
+        while i >= 1 do
+            local off = 0
+            local a = self.currentVTable[i]
+            if a and a ~= 0 then
+                off = objectOffset - a
+            end
+            self:PrependVOffsetT(off)
+
+            i = i - 1
+        end
+
+        local objectSize = objectOffset - self.objectEnd
+        self:PrependVOffsetT(objectSize)
+
+        local vBytes = #self.currentVTable + VtableMetadataFields
+        vBytes = vBytes * VOffsetT.bytewidth
+        self:PrependVOffsetT(vBytes)
+
+        local objectStart = #self.bytes - objectOffset
+        self.bytes:Set(SOffsetT:Pack(self:Offset() - objectOffset),objectStart)
+
+        table.insert(self.vtables, self:Offset())
+    else
+        local objectStart = #self.bytes - objectOffset
+        self.head = objectStart
+        self.bytes:Set(SOffsetT:Pack(exisitingVTable - objectOffset),self.head)
+    end
+
+    self.currentVTable = nil
+    return objectOffset
+end
+
+function mt:EndObject()
+    assert(self.nested)
+    self.nested = false
+    return self:WriteVtable()
+end
+
+local function growByteBuffer(self, desiredSize)
+    local s = #self.bytes
+    assert(s < MAX_BUFFER_SIZE, "Flat Buffers cannot grow buffer beyond 2 gigabytes")
+    local newsize = s
+    repeat
+        newsize = math.min(newsize * 2, MAX_BUFFER_SIZE)
+        if newsize == 0 then newsize = 1 end
+    until newsize > desiredSize
+
+    self.bytes:Grow(newsize)
+end
+
+function mt:Head()
+    return self.head
+end
+
+function mt:Offset()
+   return #self.bytes - self.head
+end
+
+function mt:Pad(n)
+    if n > 0 then
+        -- pads are 8-bit, so skip the bytewidth lookup
+        local h = self.head - n  -- UInt8
+        self.head = h
+        self.bytes:Pad(n, h)
+    end
+end
+
+function mt:Prep(size, additionalBytes)
+    if size > self.minalign then
+        self.minalign = size
+    end
+
+    local h = self.head
+
+    local k = #self.bytes - h + additionalBytes
+    local alignsize = ((~k) + 1) & (size - 1) -- getAlignSize(k, size)
+
+    local desiredSize = alignsize + size + additionalBytes
+
+    while self.head < desiredSize do
+        local oldBufSize = #self.bytes
+        growByteBuffer(self, desiredSize)
+        local updatedHead = self.head + #self.bytes - oldBufSize
+        self.head = updatedHead
+    end
+
+    self:Pad(alignsize)
+end
+
+function mt:PrependSOffsetTRelative(off)
+    self:Prep(SOffsetT.bytewidth, 0)
+    assert(off <= self:Offset(), "Offset arithmetic error")
+    local off2 = self:Offset() - off + SOffsetT.bytewidth
+    self:Place(off2, SOffsetT)
+end
+
+function mt:PrependUOffsetTRelative(off)
+    self:Prep(UOffsetT.bytewidth, 0)
+    local soffset = self:Offset()
+    if off <= soffset then
+        local off2 = soffset - off + UOffsetT.bytewidth
+        self:Place(off2, UOffsetT)
+    else
+        error("Offset arithmetic error")
+    end
+end
+
+function mt:StartVector(elemSize, numElements, alignment)
+    assert(not self.nested)
+    self.nested = true
+    self:Prep(Uint32.bytewidth, elemSize * numElements)
+    self:Prep(alignment, elemSize * numElements)
+    return self:Offset()
+end
+
+function mt:EndVector(vectorNumElements)
+    assert(self.nested)
+    self.nested = false
+    self:Place(vectorNumElements, UOffsetT)
+    return self:Offset()
+end
+
+function mt:CreateString(s)
+    assert(not self.nested)
+    self.nested = true
+
+    assert(type(s) == "string")
+
+    self:Prep(UOffsetT.bytewidth, (#s + 1)*Uint8.bytewidth)
+    self:Place(0, Uint8)
+
+    local l = #s
+    self.head = self.head - l
+
+    self.bytes:Set(s, self.head, self.head + l)
+
+    return self:EndVector(#s)
+end
+
+function mt:CreateByteVector(x)
+    assert(not self.nested)
+    self.nested = true
+    self:Prep(UOffsetT.bytewidth, #x*Uint8.bytewidth)
+
+    local l = #x
+    self.head = self.head - l
+
+    self.bytes:Set(x, self.head, self.head + l)
+
+    return self:EndVector(#x)
+end
+
+function mt:Slot(slotnum)
+    assert(self.nested)
+    -- n.b. slot number is 0-based
+    self.currentVTable[slotnum + 1] = self:Offset()
+end
+
+local function finish(self, rootTable, sizePrefix)
+    UOffsetT:EnforceNumber(rootTable)
+    local prepSize = UOffsetT.bytewidth
+    if sizePrefix then
+        prepSize = prepSize + Int32.bytewidth
+    end
+
+    self:Prep(self.minalign, prepSize)
+    self:PrependUOffsetTRelative(rootTable)
+    if sizePrefix then
+        local size = #self.bytes - self.head
+        Int32:EnforceNumber(size)
+        self:PrependInt32(size)
+    end
+    self.finished = true
+    return self.head
+end
+
+function mt:Finish(rootTable)
+    return finish(self, rootTable, false)
+end
+
+function mt:FinishSizePrefixed(rootTable)
+    return finish(self, rootTable, true)
+end
+
+function mt:Prepend(flags, off)
+    self:Prep(flags.bytewidth, 0)
+    self:Place(off, flags)
+end
+
+function mt:PrependSlot(flags, o, x, d)
+    flags:EnforceNumber(x)
+    flags:EnforceNumber(d)
+    if x ~= d then
+        self:Prepend(flags, x)
+        self:Slot(o)
+    end
+end
+
+function mt:PrependBoolSlot(...)    self:PrependSlot(Bool, ...) end
+function mt:PrependByteSlot(...)    self:PrependSlot(Uint8, ...) end
+function mt:PrependUint8Slot(...)   self:PrependSlot(Uint8, ...) end
+function mt:PrependUint16Slot(...)  self:PrependSlot(Uint16, ...) end
+function mt:PrependUint32Slot(...)  self:PrependSlot(Uint32, ...) end
+function mt:PrependUint64Slot(...)  self:PrependSlot(Uint64, ...) end
+function mt:PrependInt8Slot(...)    self:PrependSlot(Int8, ...) end
+function mt:PrependInt16Slot(...)   self:PrependSlot(Int16, ...) end
+function mt:PrependInt32Slot(...)   self:PrependSlot(Int32, ...) end
+function mt:PrependInt64Slot(...)   self:PrependSlot(Int64, ...) end
+function mt:PrependFloat32Slot(...) self:PrependSlot(Float32, ...) end
+function mt:PrependFloat64Slot(...) self:PrependSlot(Float64, ...) end
+
+function mt:PrependUOffsetTRelativeSlot(o,x,d)
+    if x~=d then
+        self:PrependUOffsetTRelative(x)
+        self:Slot(o)
+    end
+end
+
+function mt:PrependStructSlot(v,x,d)
+    UOffsetT:EnforceNumber(d)
+    if x~=d then
+        UOffsetT:EnforceNumber(x)
+        assert(x == self:Offset(), "Tried to write a Struct at an Offset that is different from the current Offset of the Builder.")
+        self:Slot(v)
+    end
+end
+
+function mt:PrependBool(x)      self:Prepend(Bool, x) end
+function mt:PrependByte(x)      self:Prepend(Uint8, x) end
+function mt:PrependUint8(x)     self:Prepend(Uint8, x) end
+function mt:PrependUint16(x)    self:Prepend(Uint16, x) end
+function mt:PrependUint32(x)    self:Prepend(Uint32, x) end
+function mt:PrependUint64(x)    self:Prepend(Uint64, x) end
+function mt:PrependInt8(x)      self:Prepend(Int8, x) end
+function mt:PrependInt16(x)     self:Prepend(Int16, x) end
+function mt:PrependInt32(x)     self:Prepend(Int32, x) end
+function mt:PrependInt64(x)     self:Prepend(Int64, x) end
+function mt:PrependFloat32(x)   self:Prepend(Float32, x) end
+function mt:PrependFloat64(x)   self:Prepend(Float64, x) end
+function mt:PrependVOffsetT(x)  self:Prepend(VOffsetT, x) end
+
+function mt:Place(x, flags)
+    local d = flags:EnforceNumberAndPack(x)
+    local h = self.head - flags.bytewidth
+    self.head = h
+    self.bytes:Set(d, h)
+end
+
+return m
diff --git a/third_party/flatbuffers/lua/flatbuffers/compat.lua b/third_party/flatbuffers/lua/flatbuffers/compat.lua
new file mode 100644
index 0000000..89c992b
--- /dev/null
+++ b/third_party/flatbuffers/lua/flatbuffers/compat.lua
@@ -0,0 +1,17 @@
+local m = {}
+
+local getAlignSize
+if _VERSION == "Lua 5.3" then
+    getAlignSize = function(k, size)
+            return ((~k) + 1) & (size - 1)
+        end    
+else
+    getAlignSize = function(self, size, additionalBytes)        
+        local alignsize = bit32.bnot(#self.bytes-self:Head() + additionalBytes) + 1
+        return bit32.band(alignsize,(size - 1))
+    end
+end
+    
+m.GetAlignSize = getAlignSize
+
+return m
\ No newline at end of file
diff --git a/third_party/flatbuffers/lua/flatbuffers/numTypes.lua b/third_party/flatbuffers/lua/flatbuffers/numTypes.lua
new file mode 100644
index 0000000..8fec21c
--- /dev/null
+++ b/third_party/flatbuffers/lua/flatbuffers/numTypes.lua
@@ -0,0 +1,204 @@
+local m = {}
+
+local ba = require("flatbuffers.binaryarray")
+
+local bpack = ba.Pack
+local bunpack = ba.Unpack
+
+local type_mt =  {}
+
+function type_mt:Pack(value)
+    return bpack(self.packFmt, value)
+end
+
+function type_mt:Unpack(buf, pos)    
+    return bunpack(self.packFmt, buf, pos)
+end
+
+function type_mt:ValidNumber(n)
+    if not self.min_value and not self.max_value then return true end
+    return self.min_value <= n and n <= self.max_value
+end
+
+function type_mt:EnforceNumber(n)
+    -- duplicate code since the overhead of function calls 
+    -- for such a popular method is time consuming
+    if not self.min_value and not self.max_value then 
+        return 
+    end
+    
+    if self.min_value <= n and n <= self.max_value then 
+        return
+    end    
+    
+    error("Number is not in the valid range") 
+end
+
+function type_mt:EnforceNumberAndPack(n)
+    return bpack(self.packFmt, n)    
+end
+
+function type_mt:ConvertType(n, otherType)
+    assert(self.bytewidth == otherType.bytewidth, "Cannot convert between types of different widths")
+    if self == otherType then
+        return n
+    end
+    return otherType:Unpack(self:Pack(n))
+end
+
+local bool_mt =
+{
+    bytewidth = 1,
+    min_value = false,
+    max_value = true,
+    lua_type = type(true),
+    name = "bool",
+    packFmt = "<I1",
+    Pack = function(self, value) return value and "1" or "0" end,
+    Unpack = function(self, buf, pos) return buf[pos] == "1" end,
+    ValidNumber = function(self, n) return true end, -- anything is a valid boolean in Lua
+    EnforceNumber = function(self, n) end, -- anything is a valid boolean in Lua
+    EnforceNumberAndPack = function(self, n) return self:Pack(value) end,
+}
+
+local uint8_mt = 
+{
+    bytewidth = 1,
+    min_value = 0,
+    max_value = 2^8-1,
+    lua_type = type(1),
+    name = "uint8",
+    packFmt = "<I1"
+}
+
+local uint16_mt = 
+{
+    bytewidth = 2,
+    min_value = 0,
+    max_value = 2^16-1,
+    lua_type = type(1),
+    name = "uint16",
+    packFmt = "<I2"
+}
+
+local uint32_mt = 
+{
+    bytewidth = 4,
+    min_value = 0,
+    max_value = 2^32-1,
+    lua_type = type(1),
+    name = "uint32",
+    packFmt = "<I4"
+}
+
+local uint64_mt = 
+{
+    bytewidth = 8,
+    min_value = 0,
+    max_value = 2^64-1,
+    lua_type = type(1),
+    name = "uint64",
+    packFmt = "<I8"
+}
+
+local int8_mt = 
+{
+    bytewidth = 1,
+    min_value = -2^7,
+    max_value = 2^7-1,
+    lua_type = type(1),
+    name = "int8",
+    packFmt = "<i1"
+}
+
+local int16_mt = 
+{
+    bytewidth = 2,
+    min_value = -2^15,
+    max_value = 2^15-1,
+    lua_type = type(1),
+    name = "int16",
+    packFmt = "<i2"
+}
+
+local int32_mt = 
+{
+    bytewidth = 4,
+    min_value = -2^31,
+    max_value = 2^31-1,
+    lua_type = type(1),
+    name = "int32",
+    packFmt = "<i4"
+}
+
+local int64_mt = 
+{
+    bytewidth = 8,
+    min_value = -2^63,
+    max_value = 2^63-1,
+    lua_type = type(1),
+    name = "int64",
+    packFmt = "<i8"
+}
+
+local float32_mt = 
+{
+    bytewidth = 4,
+    min_value = nil,
+    max_value = nil,
+    lua_type = type(1.0),
+    name = "float32",
+    packFmt = "<f"
+}
+
+local float64_mt = 
+{
+    bytewidth = 8,
+    min_value = nil,
+    max_value = nil,
+    lua_type = type(1.0),
+    name = "float64",
+    packFmt = "<d"
+}
+
+-- register the base class
+setmetatable(bool_mt, {__index = type_mt})
+setmetatable(uint8_mt, {__index = type_mt})
+setmetatable(uint16_mt, {__index = type_mt})
+setmetatable(uint32_mt, {__index = type_mt})
+setmetatable(uint64_mt, {__index = type_mt})
+setmetatable(int8_mt, {__index = type_mt})
+setmetatable(int16_mt, {__index = type_mt})
+setmetatable(int32_mt, {__index = type_mt})
+setmetatable(int64_mt, {__index = type_mt})
+setmetatable(float32_mt, {__index = type_mt})
+setmetatable(float64_mt, {__index = type_mt})
+
+
+m.Uint8     = uint8_mt
+m.Uint16    = uint16_mt
+m.Uint32    = uint32_mt
+m.Uint64    = uint64_mt
+m.Int8      = int8_mt
+m.Int16     = int16_mt
+m.Int32     = int32_mt
+m.Int64     = int64_mt
+m.Float32   = float32_mt
+m.Float64   = float64_mt
+
+m.UOffsetT  = uint32_mt
+m.VOffsetT  = uint16_mt
+m.SOffsetT  = int32_mt
+
+local GenerateTypes = function(listOfTypes)
+    for _,t in pairs(listOfTypes) do
+        t.Pack = function(self, value) return bpack(self.packFmt, value) end
+        t.Unpack = function(self, buf, pos) return bunpack(self.packFmt, buf, pos) end
+    end
+end
+
+GenerateTypes(m)
+
+-- explicitly execute after GenerateTypes call, as we don't want to define a Pack/Unpack function for it.
+m.Bool      = bool_mt
+return m
diff --git a/third_party/flatbuffers/lua/flatbuffers/view.lua b/third_party/flatbuffers/lua/flatbuffers/view.lua
new file mode 100644
index 0000000..da0f8bf
--- /dev/null
+++ b/third_party/flatbuffers/lua/flatbuffers/view.lua
@@ -0,0 +1,97 @@
+local m = {}
+local mt = {}
+
+local mt_name = "flatbuffers.view.mt"
+
+local N = require("flatbuffers.numTypes")
+local binaryarray = require("flatbuffers.binaryarray")
+
+function m.New(buf, pos)
+    N.UOffsetT:EnforceNumber(pos)
+    
+    -- need to convert from a string buffer into
+    -- a binary array
+
+    local o = {
+        bytes = type(buf) == "string" and binaryarray.New(buf) or buf,
+        pos = pos
+    }
+    setmetatable(o, {__index = mt, __metatable = mt_name})
+    return o
+end
+
+function mt:Offset(vtableOffset)
+    local vtable = self.pos - self:Get(N.SOffsetT, self.pos)
+    local vtableEnd = self:Get(N.VOffsetT, vtable)
+    if vtableOffset < vtableEnd then
+        return self:Get(N.VOffsetT, vtable + vtableOffset)
+    end
+    return 0
+end
+
+function mt:Indirect(off)
+    N.UOffsetT:EnforceNumber(off)
+    return off + N.UOffsetT:Unpack(self.bytes, off)
+end
+
+function mt:String(off)
+    N.UOffsetT:EnforceNumber(off)
+    off = off + N.UOffsetT:Unpack(self.bytes, off)
+    local start = off + N.UOffsetT.bytewidth
+    local length = N.UOffsetT:Unpack(self.bytes, off)
+    return self.bytes:Slice(start, start+length)
+end
+
+function mt:VectorLen(off)
+    N.UOffsetT:EnforceNumber(off)
+    off = off + self.pos
+    off = off + N.UOffsetT:Unpack(self.bytes, off)
+    return N.UOffsetT:Unpack(self.bytes, off)
+end
+
+function mt:Vector(off)
+    N.UOffsetT:EnforceNumber(off)
+    
+    off = off + self.pos
+    local x = off + self:Get(N.UOffsetT, off)
+    x = x + N.UOffsetT.bytewidth
+    return x
+end
+
+function mt:Union(t2, off)
+    assert(getmetatable(t2) == mt_name)
+    N.UOffsetT:EnforceNumber(off)
+    
+    off = off + self.pos
+    t2.pos = off + self:Get(N.UOffsetT, off)
+    t2.bytes = self.bytes
+end
+
+function mt:Get(flags, off)
+    N.UOffsetT:EnforceNumber(off)
+    return flags:Unpack(self.bytes, off)
+end
+
+function mt:GetSlot(slot, d, validatorFlags)
+    N.VOffsetT:EnforceNumber(slot)
+    if validatorFlags then
+        validatorFlags:EnforceNumber(d)
+    end
+    local off = self:Offset(slot)
+    if off == 0 then
+        return d
+    end
+    return self:Get(validatorFlags, self.pos + off)
+end
+
+function mt:GetVOffsetTSlot(slot, d)
+    N.VOffsetT:EnforceNumber(slot)
+    N.VOffsetT:EnforceNumber(d)
+    local off = self:Offset(slot)
+    if off == 0 then
+        return d
+    end
+    return off
+end
+
+return m
\ No newline at end of file
diff --git a/third_party/flatbuffers/net/FlatBuffers/ByteBuffer.cs b/third_party/flatbuffers/net/FlatBuffers/ByteBuffer.cs
new file mode 100644
index 0000000..5e212dd
--- /dev/null
+++ b/third_party/flatbuffers/net/FlatBuffers/ByteBuffer.cs
@@ -0,0 +1,891 @@
+/*
+ * 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.
+ */
+
+// There are 3 #defines that have an impact on performance / features of this ByteBuffer implementation
+//
+//      UNSAFE_BYTEBUFFER 
+//          This will use unsafe code to manipulate the underlying byte array. This
+//          can yield a reasonable performance increase.
+//
+//      BYTEBUFFER_NO_BOUNDS_CHECK
+//          This will disable the bounds check asserts to the byte array. This can
+//          yield a small performance gain in normal code..
+//
+//      ENABLE_SPAN_T
+//          This will enable reading and writing blocks of memory with a Span<T> instead if just
+//          T[].  You can also enable writing directly to shared memory or other types of memory
+//          by providing a custom implementation of ByteBufferAllocator.
+//          ENABLE_SPAN_T also requires UNSAFE_BYTEBUFFER to be defined
+//
+// Using UNSAFE_BYTEBUFFER and BYTEBUFFER_NO_BOUNDS_CHECK together can yield a
+// performance gain of ~15% for some operations, however doing so is potentially 
+// dangerous. Do so at your own risk!
+//
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Text;
+
+#if ENABLE_SPAN_T
+using System.Buffers.Binary;
+#endif
+
+#if ENABLE_SPAN_T && !UNSAFE_BYTEBUFFER
+#error ENABLE_SPAN_T requires UNSAFE_BYTEBUFFER to also be defined
+#endif
+
+namespace FlatBuffers
+{
+    public abstract class ByteBufferAllocator
+    {
+#if ENABLE_SPAN_T
+        public abstract Span<byte> Span { get; }
+        public abstract ReadOnlySpan<byte> ReadOnlySpan { get; }
+        public abstract Memory<byte> Memory { get; }
+        public abstract ReadOnlyMemory<byte> ReadOnlyMemory { get; }
+
+#else
+        public byte[] Buffer
+        {
+            get;
+            protected set;
+        }
+#endif
+
+        public int Length
+        {
+            get;
+            protected set;
+        }
+
+        public abstract void GrowFront(int newSize);
+    }
+
+    public sealed class ByteArrayAllocator : ByteBufferAllocator
+    {
+        private byte[] _buffer;
+
+        public ByteArrayAllocator(byte[] buffer)
+        {
+            _buffer = buffer;
+            InitBuffer();
+        }
+
+        public override void GrowFront(int newSize)
+        {
+            if ((Length & 0xC0000000) != 0)
+                throw new Exception(
+                    "ByteBuffer: cannot grow buffer beyond 2 gigabytes.");
+
+            if (newSize < Length)
+                throw new Exception("ByteBuffer: cannot truncate buffer.");
+
+            byte[] newBuffer = new byte[newSize];
+            System.Buffer.BlockCopy(_buffer, 0, newBuffer, newSize - Length, Length);
+            _buffer = newBuffer;
+            InitBuffer();
+        }
+
+#if ENABLE_SPAN_T
+        public override Span<byte> Span => _buffer;
+        public override ReadOnlySpan<byte> ReadOnlySpan => _buffer;
+        public override Memory<byte> Memory => _buffer;
+        public override ReadOnlyMemory<byte> ReadOnlyMemory => _buffer;
+#endif
+
+        private void InitBuffer()
+        {
+            Length = _buffer.Length;
+#if !ENABLE_SPAN_T
+            Buffer = _buffer;
+#endif
+        }
+    }
+
+    /// <summary>
+    /// Class to mimic Java's ByteBuffer which is used heavily in Flatbuffers.
+    /// </summary>
+    public class ByteBuffer
+    {
+        private ByteBufferAllocator _buffer;
+        private int _pos;  // Must track start of the buffer.
+
+        public ByteBuffer(ByteBufferAllocator allocator, int position)
+        {
+            _buffer = allocator;
+            _pos = position;
+        }
+
+        public ByteBuffer(int size) : this(new byte[size]) { }
+
+        public ByteBuffer(byte[] buffer) : this(buffer, 0) { }
+
+        public ByteBuffer(byte[] buffer, int pos)
+        {
+            _buffer = new ByteArrayAllocator(buffer);
+            _pos = pos;
+        }
+
+        public int Position
+        {
+            get { return _pos; }
+            set { _pos = value; }
+        }
+
+        public int Length { get { return _buffer.Length; } }
+
+        public void Reset()
+        {
+            _pos = 0;
+        }
+
+        // Create a new ByteBuffer on the same underlying data.
+        // The new ByteBuffer's position will be same as this buffer's.
+        public ByteBuffer Duplicate()
+        {
+            return new ByteBuffer(_buffer, Position);
+        }
+
+        // Increases the size of the ByteBuffer, and copies the old data towards
+        // the end of the new buffer.
+        public void GrowFront(int newSize)
+        {
+            _buffer.GrowFront(newSize);
+        }
+
+        public byte[] ToArray(int pos, int len)
+        {
+            return ToArray<byte>(pos, len);
+        }
+
+        /// <summary>
+        /// A lookup of type sizes. Used instead of Marshal.SizeOf() which has additional
+        /// overhead, but also is compatible with generic functions for simplified code.
+        /// </summary>
+        private static Dictionary<Type, int> genericSizes = new Dictionary<Type, int>()
+        {
+            { typeof(bool),     sizeof(bool) },
+            { typeof(float),    sizeof(float) },
+            { typeof(double),   sizeof(double) },
+            { typeof(sbyte),    sizeof(sbyte) },
+            { typeof(byte),     sizeof(byte) },
+            { typeof(short),    sizeof(short) },
+            { typeof(ushort),   sizeof(ushort) },
+            { typeof(int),      sizeof(int) },
+            { typeof(uint),     sizeof(uint) },
+            { typeof(ulong),    sizeof(ulong) },
+            { typeof(long),     sizeof(long) },
+        };
+
+        /// <summary>
+        /// Get the wire-size (in bytes) of a type supported by flatbuffers.
+        /// </summary>
+        /// <param name="t">The type to get the wire size of</param>
+        /// <returns></returns>
+        public static int SizeOf<T>()
+        {
+            return genericSizes[typeof(T)];
+        }
+
+        /// <summary>
+        /// Checks if the Type provided is supported as scalar value
+        /// </summary>
+        /// <typeparam name="T">The Type to check</typeparam>
+        /// <returns>True if the type is a scalar type that is supported, falsed otherwise</returns>
+        public static bool IsSupportedType<T>()
+        {
+            return genericSizes.ContainsKey(typeof(T));
+        }
+
+        /// <summary>
+        /// Get the wire-size (in bytes) of an typed array
+        /// </summary>
+        /// <typeparam name="T">The type of the array</typeparam>
+        /// <param name="x">The array to get the size of</param>
+        /// <returns>The number of bytes the array takes on wire</returns>
+        public static int ArraySize<T>(T[] x)
+        {
+            return SizeOf<T>() * x.Length;
+        }
+
+#if ENABLE_SPAN_T
+        public static int ArraySize<T>(Span<T> x)
+        {
+            return SizeOf<T>() * x.Length;
+        }
+#endif
+
+        // Get a portion of the buffer casted into an array of type T, given
+        // the buffer position and length.
+#if ENABLE_SPAN_T
+        public T[] ToArray<T>(int pos, int len)
+            where T : struct
+        {
+            AssertOffsetAndLength(pos, len);
+            return MemoryMarshal.Cast<byte, T>(_buffer.ReadOnlySpan.Slice(pos)).Slice(0, len).ToArray();
+        }
+#else
+        public T[] ToArray<T>(int pos, int len)
+            where T : struct
+        {
+            AssertOffsetAndLength(pos, len);
+            T[] arr = new T[len];
+            Buffer.BlockCopy(_buffer.Buffer, pos, arr, 0, ArraySize(arr));
+            return arr;
+        }
+#endif
+
+        public byte[] ToSizedArray()
+        {
+            return ToArray<byte>(Position, Length - Position);
+        }
+
+        public byte[] ToFullArray()
+        {
+            return ToArray<byte>(0, Length);
+        }
+
+#if ENABLE_SPAN_T
+        public ReadOnlyMemory<byte> ToReadOnlyMemory(int pos, int len)
+        {
+            return _buffer.ReadOnlyMemory.Slice(pos, len);
+        }
+
+        public Memory<byte> ToMemory(int pos, int len)
+        {
+            return _buffer.Memory.Slice(pos, len);
+        }
+
+        public Span<byte> ToSpan(int pos, int len)
+        {
+            return _buffer.Span.Slice(pos, len);
+        }
+#else
+        public ArraySegment<byte> ToArraySegment(int pos, int len)
+        {
+            return new ArraySegment<byte>(_buffer.Buffer, pos, len);
+        }
+
+        public MemoryStream ToMemoryStream(int pos, int len)
+        {
+            return new MemoryStream(_buffer.Buffer, pos, len);
+        }
+#endif
+
+#if !UNSAFE_BYTEBUFFER
+        // Pre-allocated helper arrays for convertion.
+        private float[] floathelper = new[] { 0.0f };
+        private int[] inthelper = new[] { 0 };
+        private double[] doublehelper = new[] { 0.0 };
+        private ulong[] ulonghelper = new[] { 0UL };
+#endif // !UNSAFE_BYTEBUFFER
+
+        // Helper functions for the unsafe version.
+        static public ushort ReverseBytes(ushort input)
+        {
+            return (ushort)(((input & 0x00FFU) << 8) |
+                            ((input & 0xFF00U) >> 8));
+        }
+        static public uint ReverseBytes(uint input)
+        {
+            return ((input & 0x000000FFU) << 24) |
+                   ((input & 0x0000FF00U) <<  8) |
+                   ((input & 0x00FF0000U) >>  8) |
+                   ((input & 0xFF000000U) >> 24);
+        }
+        static public ulong ReverseBytes(ulong input)
+        {
+            return (((input & 0x00000000000000FFUL) << 56) |
+                    ((input & 0x000000000000FF00UL) << 40) |
+                    ((input & 0x0000000000FF0000UL) << 24) |
+                    ((input & 0x00000000FF000000UL) <<  8) |
+                    ((input & 0x000000FF00000000UL) >>  8) |
+                    ((input & 0x0000FF0000000000UL) >> 24) |
+                    ((input & 0x00FF000000000000UL) >> 40) |
+                    ((input & 0xFF00000000000000UL) >> 56));
+        }
+
+#if !UNSAFE_BYTEBUFFER
+        // Helper functions for the safe (but slower) version.
+        protected void WriteLittleEndian(int offset, int count, ulong data)
+        {
+            if (BitConverter.IsLittleEndian)
+            {
+                for (int i = 0; i < count; i++)
+                {
+                    _buffer.Buffer[offset + i] = (byte)(data >> i * 8);
+                }
+            }
+            else
+            {
+                for (int i = 0; i < count; i++)
+                {
+                    _buffer.Buffer[offset + count - 1 - i] = (byte)(data >> i * 8);
+                }
+            }
+        }
+
+        protected ulong ReadLittleEndian(int offset, int count)
+        {
+            AssertOffsetAndLength(offset, count);
+            ulong r = 0;
+            if (BitConverter.IsLittleEndian)
+            {
+                for (int i = 0; i < count; i++)
+                {
+                    r |= (ulong)_buffer.Buffer[offset + i] << i * 8;
+                }
+            }
+            else
+            {
+                for (int i = 0; i < count; i++)
+                {
+                    r |= (ulong)_buffer.Buffer[offset + count - 1 - i] << i * 8;
+                }
+            }
+            return r;
+        }
+#endif // !UNSAFE_BYTEBUFFER
+
+        private void AssertOffsetAndLength(int offset, int length)
+        {
+#if !BYTEBUFFER_NO_BOUNDS_CHECK
+            if (offset < 0 ||
+                offset > _buffer.Length - length)
+                throw new ArgumentOutOfRangeException();
+#endif
+        }
+
+#if ENABLE_SPAN_T
+
+        public void PutSbyte(int offset, sbyte value)
+        {
+            AssertOffsetAndLength(offset, sizeof(sbyte));
+            _buffer.Span[offset] = (byte)value;
+        }
+
+        public void PutByte(int offset, byte value)
+        {
+            AssertOffsetAndLength(offset, sizeof(byte));
+            _buffer.Span[offset] = value;
+        }
+
+        public void PutByte(int offset, byte value, int count)
+        {
+            AssertOffsetAndLength(offset, sizeof(byte) * count);
+            Span<byte> span = _buffer.Span.Slice(offset, count);
+            for (var i = 0; i < span.Length; ++i)
+                span[i] = value;
+        }
+#else
+        public void PutSbyte(int offset, sbyte value)
+        {
+            AssertOffsetAndLength(offset, sizeof(sbyte));
+            _buffer.Buffer[offset] = (byte)value;
+        }
+
+        public void PutByte(int offset, byte value)
+        {
+            AssertOffsetAndLength(offset, sizeof(byte));
+            _buffer.Buffer[offset] = value;
+        }
+
+        public void PutByte(int offset, byte value, int count)
+        {
+            AssertOffsetAndLength(offset, sizeof(byte) * count);
+            for (var i = 0; i < count; ++i)
+                _buffer.Buffer[offset + i] = value;
+        }
+#endif
+
+        // this method exists in order to conform with Java ByteBuffer standards
+        public void Put(int offset, byte value)
+        {
+            PutByte(offset, value);
+        }
+
+#if ENABLE_SPAN_T
+        public unsafe void PutStringUTF8(int offset, string value)
+        {
+            AssertOffsetAndLength(offset, value.Length);
+            fixed (char* s = value)
+            {
+                fixed (byte* buffer = &MemoryMarshal.GetReference(_buffer.Span))
+                {
+                    Encoding.UTF8.GetBytes(s, value.Length, buffer + offset, Length - offset);
+                }
+            }
+        }
+#else
+        public void PutStringUTF8(int offset, string value)
+        {
+            AssertOffsetAndLength(offset, value.Length);
+            Encoding.UTF8.GetBytes(value, 0, value.Length,
+                _buffer.Buffer, offset);
+        }
+#endif
+
+#if UNSAFE_BYTEBUFFER
+        // Unsafe but more efficient versions of Put*.
+        public void PutShort(int offset, short value)
+        {
+            PutUshort(offset, (ushort)value);
+        }
+
+        public unsafe void PutUshort(int offset, ushort value)
+        {
+            AssertOffsetAndLength(offset, sizeof(ushort));
+#if ENABLE_SPAN_T
+            Span<byte> span = _buffer.Span.Slice(offset);
+            BinaryPrimitives.WriteUInt16LittleEndian(span, value);
+#else
+            fixed (byte* ptr = _buffer.Buffer)
+            {
+                *(ushort*)(ptr + offset) = BitConverter.IsLittleEndian
+                    ? value
+                    : ReverseBytes(value);
+            }
+#endif
+        }
+
+        public void PutInt(int offset, int value)
+        {
+            PutUint(offset, (uint)value);
+        }
+
+        public unsafe void PutUint(int offset, uint value)
+        {
+            AssertOffsetAndLength(offset, sizeof(uint));
+#if ENABLE_SPAN_T
+            Span<byte> span = _buffer.Span.Slice(offset);
+            BinaryPrimitives.WriteUInt32LittleEndian(span, value);
+#else
+            fixed (byte* ptr = _buffer.Buffer)
+            {
+                *(uint*)(ptr + offset) = BitConverter.IsLittleEndian
+                    ? value
+                    : ReverseBytes(value);
+            }
+#endif
+        }
+
+        public unsafe void PutLong(int offset, long value)
+        {
+            PutUlong(offset, (ulong)value);
+        }
+
+        public unsafe void PutUlong(int offset, ulong value)
+        {
+            AssertOffsetAndLength(offset, sizeof(ulong));
+#if ENABLE_SPAN_T
+            Span<byte> span = _buffer.Span.Slice(offset);
+            BinaryPrimitives.WriteUInt64LittleEndian(span, value);
+#else
+            fixed (byte* ptr = _buffer.Buffer)
+            {
+                *(ulong*)(ptr + offset) = BitConverter.IsLittleEndian
+                    ? value
+                    : ReverseBytes(value);
+            }
+#endif
+        }
+
+        public unsafe void PutFloat(int offset, float value)
+        {
+            AssertOffsetAndLength(offset, sizeof(float));
+#if ENABLE_SPAN_T
+            fixed (byte* ptr = &MemoryMarshal.GetReference(_buffer.Span))
+#else
+            fixed (byte* ptr = _buffer.Buffer)
+#endif
+            {
+                if (BitConverter.IsLittleEndian)
+                {
+                    *(float*)(ptr + offset) = value;
+                }
+                else
+                {
+                    *(uint*)(ptr + offset) = ReverseBytes(*(uint*)(&value));
+                }
+            }
+        }
+
+        public unsafe void PutDouble(int offset, double value)
+        {
+            AssertOffsetAndLength(offset, sizeof(double));
+#if ENABLE_SPAN_T
+            fixed (byte* ptr = &MemoryMarshal.GetReference(_buffer.Span))
+#else
+            fixed (byte* ptr = _buffer.Buffer)
+#endif
+            {
+                if (BitConverter.IsLittleEndian)
+                {
+                    *(double*)(ptr + offset) = value;
+                }
+                else
+                {
+                    *(ulong*)(ptr + offset) = ReverseBytes(*(ulong*)(&value));
+                }
+            }
+        }
+#else // !UNSAFE_BYTEBUFFER
+        // Slower versions of Put* for when unsafe code is not allowed.
+        public void PutShort(int offset, short value)
+        {
+            AssertOffsetAndLength(offset, sizeof(short));
+            WriteLittleEndian(offset, sizeof(short), (ulong)value);
+        }
+
+        public void PutUshort(int offset, ushort value)
+        {
+            AssertOffsetAndLength(offset, sizeof(ushort));
+            WriteLittleEndian(offset, sizeof(ushort), (ulong)value);
+        }
+
+        public void PutInt(int offset, int value)
+        {
+            AssertOffsetAndLength(offset, sizeof(int));
+            WriteLittleEndian(offset, sizeof(int), (ulong)value);
+        }
+
+        public void PutUint(int offset, uint value)
+        {
+            AssertOffsetAndLength(offset, sizeof(uint));
+            WriteLittleEndian(offset, sizeof(uint), (ulong)value);
+        }
+
+        public void PutLong(int offset, long value)
+        {
+            AssertOffsetAndLength(offset, sizeof(long));
+            WriteLittleEndian(offset, sizeof(long), (ulong)value);
+        }
+
+        public void PutUlong(int offset, ulong value)
+        {
+            AssertOffsetAndLength(offset, sizeof(ulong));
+            WriteLittleEndian(offset, sizeof(ulong), value);
+        }
+
+        public void PutFloat(int offset, float value)
+        {
+            AssertOffsetAndLength(offset, sizeof(float));
+            floathelper[0] = value;
+            Buffer.BlockCopy(floathelper, 0, inthelper, 0, sizeof(float));
+            WriteLittleEndian(offset, sizeof(float), (ulong)inthelper[0]);
+        }
+
+        public void PutDouble(int offset, double value)
+        {
+            AssertOffsetAndLength(offset, sizeof(double));
+            doublehelper[0] = value;
+            Buffer.BlockCopy(doublehelper, 0, ulonghelper, 0, sizeof(double));
+            WriteLittleEndian(offset, sizeof(double), ulonghelper[0]);
+        }
+
+#endif // UNSAFE_BYTEBUFFER
+
+#if ENABLE_SPAN_T
+        public sbyte GetSbyte(int index)
+        {
+            AssertOffsetAndLength(index, sizeof(sbyte));
+            return (sbyte)_buffer.ReadOnlySpan[index];
+        }
+
+        public byte Get(int index)
+        {
+            AssertOffsetAndLength(index, sizeof(byte));
+            return _buffer.ReadOnlySpan[index];
+        }
+#else
+        public sbyte GetSbyte(int index)
+        {
+            AssertOffsetAndLength(index, sizeof(sbyte));
+            return (sbyte)_buffer.Buffer[index];
+        }
+
+        public byte Get(int index)
+        {
+            AssertOffsetAndLength(index, sizeof(byte));
+            return _buffer.Buffer[index];
+        }
+#endif
+
+#if ENABLE_SPAN_T
+        public unsafe string GetStringUTF8(int startPos, int len)
+        {
+            fixed (byte* buffer = &MemoryMarshal.GetReference(_buffer.ReadOnlySpan.Slice(startPos)))
+            {
+                return Encoding.UTF8.GetString(buffer, len);
+            }
+        }
+#else
+        public string GetStringUTF8(int startPos, int len)
+        {
+            return Encoding.UTF8.GetString(_buffer.Buffer, startPos, len);
+        }
+#endif
+
+#if UNSAFE_BYTEBUFFER
+        // Unsafe but more efficient versions of Get*.
+        public short GetShort(int offset)
+        {
+            return (short)GetUshort(offset);
+        }
+
+        public unsafe ushort GetUshort(int offset)
+        {
+            AssertOffsetAndLength(offset, sizeof(ushort));
+#if ENABLE_SPAN_T
+            ReadOnlySpan<byte> span = _buffer.ReadOnlySpan.Slice(offset);
+            return BinaryPrimitives.ReadUInt16LittleEndian(span);
+#else
+            fixed (byte* ptr = _buffer.Buffer)
+            {
+                return BitConverter.IsLittleEndian
+                    ? *(ushort*)(ptr + offset)
+                    : ReverseBytes(*(ushort*)(ptr + offset));
+            }
+#endif
+        }
+
+        public int GetInt(int offset)
+        {
+            return (int)GetUint(offset);
+        }
+
+        public unsafe uint GetUint(int offset)
+        {
+            AssertOffsetAndLength(offset, sizeof(uint));
+#if ENABLE_SPAN_T
+            ReadOnlySpan<byte> span = _buffer.ReadOnlySpan.Slice(offset);
+            return BinaryPrimitives.ReadUInt32LittleEndian(span);
+#else
+            fixed (byte* ptr = _buffer.Buffer)
+            {
+                return BitConverter.IsLittleEndian
+                    ? *(uint*)(ptr + offset)
+                    : ReverseBytes(*(uint*)(ptr + offset));
+            }
+#endif
+        }
+
+        public long GetLong(int offset)
+        {
+            return (long)GetUlong(offset);
+        }
+
+        public unsafe ulong GetUlong(int offset)
+        {
+            AssertOffsetAndLength(offset, sizeof(ulong));
+#if ENABLE_SPAN_T
+            ReadOnlySpan<byte> span = _buffer.ReadOnlySpan.Slice(offset);
+            return BinaryPrimitives.ReadUInt64LittleEndian(span);
+#else            
+            fixed (byte* ptr = _buffer.Buffer)
+            {
+                return BitConverter.IsLittleEndian
+                    ? *(ulong*)(ptr + offset)
+                    : ReverseBytes(*(ulong*)(ptr + offset));
+            }
+#endif
+        }
+
+        public unsafe float GetFloat(int offset)
+        {
+            AssertOffsetAndLength(offset, sizeof(float));
+#if ENABLE_SPAN_T
+            fixed (byte* ptr = &MemoryMarshal.GetReference(_buffer.ReadOnlySpan))
+#else
+            fixed (byte* ptr = _buffer.Buffer)
+#endif
+            {
+                if (BitConverter.IsLittleEndian)
+                {
+                    return *(float*)(ptr + offset);
+                }
+                else
+                {
+                    uint uvalue = ReverseBytes(*(uint*)(ptr + offset));
+                    return *(float*)(&uvalue);
+                }
+            }
+        }
+
+        public unsafe double GetDouble(int offset)
+        {
+            AssertOffsetAndLength(offset, sizeof(double));
+#if ENABLE_SPAN_T
+            fixed (byte* ptr = &MemoryMarshal.GetReference(_buffer.ReadOnlySpan))
+#else
+            fixed (byte* ptr = _buffer.Buffer)
+#endif
+            {
+                if (BitConverter.IsLittleEndian)
+                {
+                    return *(double*)(ptr + offset);
+                }
+                else
+                {
+                    ulong uvalue = ReverseBytes(*(ulong*)(ptr + offset));
+                    return *(double*)(&uvalue);
+                }
+            }
+        }
+#else // !UNSAFE_BYTEBUFFER
+        // Slower versions of Get* for when unsafe code is not allowed.
+        public short GetShort(int index)
+        {
+            return (short)ReadLittleEndian(index, sizeof(short));
+        }
+
+        public ushort GetUshort(int index)
+        {
+            return (ushort)ReadLittleEndian(index, sizeof(ushort));
+        }
+
+        public int GetInt(int index)
+        {
+            return (int)ReadLittleEndian(index, sizeof(int));
+        }
+
+        public uint GetUint(int index)
+        {
+            return (uint)ReadLittleEndian(index, sizeof(uint));
+        }
+
+        public long GetLong(int index)
+        {
+            return (long)ReadLittleEndian(index, sizeof(long));
+        }
+
+        public ulong GetUlong(int index)
+        {
+            return ReadLittleEndian(index, sizeof(ulong));
+        }
+
+        public float GetFloat(int index)
+        {
+            int i = (int)ReadLittleEndian(index, sizeof(float));
+            inthelper[0] = i;
+            Buffer.BlockCopy(inthelper, 0, floathelper, 0, sizeof(float));
+            return floathelper[0];
+        }
+
+        public double GetDouble(int index)
+        {
+            ulong i = ReadLittleEndian(index, sizeof(double));
+            // There's Int64BitsToDouble but it uses unsafe code internally.
+            ulonghelper[0] = i;
+            Buffer.BlockCopy(ulonghelper, 0, doublehelper, 0, sizeof(double));
+            return doublehelper[0];
+        }
+#endif // UNSAFE_BYTEBUFFER
+
+        /// <summary>
+        /// Copies an array of type T into this buffer, ending at the given
+        /// offset into this buffer. The starting offset is calculated based on the length
+        /// of the array and is the value returned.
+        /// </summary>
+        /// <typeparam name="T">The type of the input data (must be a struct)</typeparam>
+        /// <param name="offset">The offset into this buffer where the copy will end</param>
+        /// <param name="x">The array to copy data from</param>
+        /// <returns>The 'start' location of this buffer now, after the copy completed</returns>
+        public int Put<T>(int offset, T[] x)
+            where T : struct
+        {
+            if (x == null)
+            {
+                throw new ArgumentNullException("Cannot put a null array");
+            }
+
+            if (x.Length == 0)
+            {
+                throw new ArgumentException("Cannot put an empty array");
+            }
+
+            if (!IsSupportedType<T>())
+            {
+                throw new ArgumentException("Cannot put an array of type "
+                    + typeof(T) + " into this buffer");
+            }
+
+            if (BitConverter.IsLittleEndian)
+            {
+                int numBytes = ByteBuffer.ArraySize(x);
+                offset -= numBytes;
+                AssertOffsetAndLength(offset, numBytes);
+                // if we are LE, just do a block copy
+#if ENABLE_SPAN_T
+                MemoryMarshal.Cast<T, byte>(x).CopyTo(_buffer.Span.Slice(offset, numBytes));
+#else
+                Buffer.BlockCopy(x, 0, _buffer.Buffer, offset, numBytes);
+#endif
+            }
+            else
+            {
+                throw new NotImplementedException("Big Endian Support not implemented yet " +
+                    "for putting typed arrays");
+                // if we are BE, we have to swap each element by itself
+                //for(int i = x.Length - 1; i >= 0; i--)
+                //{
+                //  todo: low priority, but need to genericize the Put<T>() functions
+                //}
+            }
+            return offset;
+        }
+
+#if ENABLE_SPAN_T
+        public int Put<T>(int offset, Span<T> x)
+            where T : struct
+        {
+            if (x.Length == 0)
+            {
+                throw new ArgumentException("Cannot put an empty array");
+            }
+
+            if (!IsSupportedType<T>())
+            {
+                throw new ArgumentException("Cannot put an array of type "
+                    + typeof(T) + " into this buffer");
+            }
+
+            if (BitConverter.IsLittleEndian)
+            {
+                int numBytes = ByteBuffer.ArraySize(x);
+                offset -= numBytes;
+                AssertOffsetAndLength(offset, numBytes);
+                // if we are LE, just do a block copy
+                MemoryMarshal.Cast<T, byte>(x).CopyTo(_buffer.Span.Slice(offset, numBytes));
+            }
+            else
+            {
+                throw new NotImplementedException("Big Endian Support not implemented yet " +
+                    "for putting typed arrays");
+                // if we are BE, we have to swap each element by itself
+                //for(int i = x.Length - 1; i >= 0; i--)
+                //{
+                //  todo: low priority, but need to genericize the Put<T>() functions
+                //}
+            }
+            return offset;
+        }
+#endif
+    }
+}
diff --git a/third_party/flatbuffers/net/FlatBuffers/ByteBufferUtil.cs b/third_party/flatbuffers/net/FlatBuffers/ByteBufferUtil.cs
new file mode 100644
index 0000000..66e8266
--- /dev/null
+++ b/third_party/flatbuffers/net/FlatBuffers/ByteBufferUtil.cs
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+using System;
+
+namespace FlatBuffers
+{
+	/// <summary>
+	/// Class that collects utility functions around `ByteBuffer`.
+	/// </summary>
+	public class ByteBufferUtil
+	{
+		// Extract the size prefix from a `ByteBuffer`.
+		public static int GetSizePrefix(ByteBuffer bb) {
+			return bb.GetInt(bb.Position);
+		}
+
+		// Create a duplicate of a size-prefixed `ByteBuffer` that has its position
+		// advanced just past the size prefix.
+		public static ByteBuffer RemoveSizePrefix(ByteBuffer bb) {
+			ByteBuffer s = bb.Duplicate();
+			s.Position += FlatBufferConstants.SizePrefixLength;
+			return s;
+		}
+	}
+}
diff --git a/third_party/flatbuffers/net/FlatBuffers/FlatBufferBuilder.cs b/third_party/flatbuffers/net/FlatBuffers/FlatBufferBuilder.cs
new file mode 100644
index 0000000..27c16b3
--- /dev/null
+++ b/third_party/flatbuffers/net/FlatBuffers/FlatBufferBuilder.cs
@@ -0,0 +1,842 @@
+/*
+ * 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.
+ */
+
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+/// @file
+/// @addtogroup flatbuffers_csharp_api
+/// @{
+
+namespace FlatBuffers
+{
+    /// <summary>
+    /// Responsible for building up and accessing a FlatBuffer formatted byte
+    /// array (via ByteBuffer).
+    /// </summary>
+    public class FlatBufferBuilder
+    {
+        private int _space;
+        private ByteBuffer _bb;
+        private int _minAlign = 1;
+
+        // The vtable for the current table (if _vtableSize >= 0)
+        private int[] _vtable = new int[16];
+        // The size of the vtable. -1 indicates no vtable
+        private int _vtableSize = -1;
+        // Starting offset of the current struct/table.
+        private int _objectStart;
+        // List of offsets of all vtables.
+        private int[] _vtables = new int[16];
+        // Number of entries in `vtables` in use.
+        private int _numVtables = 0;
+        // For the current vector being built.
+        private int _vectorNumElems = 0;
+
+        // For CreateSharedString
+        private Dictionary<string, StringOffset> _sharedStringMap = null;
+
+        /// <summary>
+        /// Create a FlatBufferBuilder with a given initial size.
+        /// </summary>
+        /// <param name="initialSize">
+        /// The initial size to use for the internal buffer.
+        /// </param>
+        public FlatBufferBuilder(int initialSize)
+        {
+            if (initialSize <= 0)
+                throw new ArgumentOutOfRangeException("initialSize",
+                    initialSize, "Must be greater than zero");
+            _space = initialSize;
+            _bb = new ByteBuffer(initialSize);
+        }
+
+        /// <summary>
+        /// Create a FlatBufferBuilder backed by the pased in ByteBuffer
+        /// </summary>
+        /// <param name="buffer">The ByteBuffer to write to</param>
+        public FlatBufferBuilder(ByteBuffer buffer)
+        {
+            _bb = buffer;
+            _space = buffer.Length;
+            buffer.Reset();
+        }
+
+        /// <summary>
+        /// Reset the FlatBufferBuilder by purging all data that it holds.
+        /// </summary>
+        public void Clear()
+        {
+            _space = _bb.Length;
+            _bb.Reset();
+            _minAlign = 1;
+            while (_vtableSize > 0) _vtable[--_vtableSize] = 0;
+            _vtableSize = -1;
+            _objectStart = 0;
+            _numVtables = 0;
+            _vectorNumElems = 0;
+        }
+
+        /// <summary>
+        /// Gets and sets a Boolean to disable the optimization when serializing
+        /// default values to a Table.
+        ///
+        /// In order to save space, fields that are set to their default value
+        /// don't get serialized into the buffer.
+        /// </summary>
+        public bool ForceDefaults { get; set; }
+
+        /// @cond FLATBUFFERS_INTERNAL
+
+        public int Offset { get { return _bb.Length - _space; } }
+
+        public void Pad(int size)
+        {
+             _bb.PutByte(_space -= size, 0, size);
+        }
+
+        // Doubles the size of the ByteBuffer, and copies the old data towards
+        // the end of the new buffer (since we build the buffer backwards).
+        void GrowBuffer()
+        {
+            _bb.GrowFront(_bb.Length << 1);
+        }
+
+        // Prepare to write an element of `size` after `additional_bytes`
+        // have been written, e.g. if you write a string, you need to align
+        // such the int length field is aligned to SIZEOF_INT, and the string
+        // data follows it directly.
+        // If all you need to do is align, `additional_bytes` will be 0.
+        public void Prep(int size, int additionalBytes)
+        {
+            // Track the biggest thing we've ever aligned to.
+            if (size > _minAlign)
+                _minAlign = size;
+            // Find the amount of alignment needed such that `size` is properly
+            // aligned after `additional_bytes`
+            var alignSize =
+                ((~((int)_bb.Length - _space + additionalBytes)) + 1) &
+                (size - 1);
+            // Reallocate the buffer if needed.
+            while (_space < alignSize + size + additionalBytes)
+            {
+                var oldBufSize = (int)_bb.Length;
+                GrowBuffer();
+                _space += (int)_bb.Length - oldBufSize;
+
+            }
+            if (alignSize > 0)
+                Pad(alignSize);
+        }
+
+        public void PutBool(bool x)
+        {
+          _bb.PutByte(_space -= sizeof(byte), (byte)(x ? 1 : 0));
+        }
+
+        public void PutSbyte(sbyte x)
+        {
+          _bb.PutSbyte(_space -= sizeof(sbyte), x);
+        }
+
+        public void PutByte(byte x)
+        {
+            _bb.PutByte(_space -= sizeof(byte), x);
+        }
+
+        public void PutShort(short x)
+        {
+            _bb.PutShort(_space -= sizeof(short), x);
+        }
+
+        public void PutUshort(ushort x)
+        {
+          _bb.PutUshort(_space -= sizeof(ushort), x);
+        }
+
+        public void PutInt(int x)
+        {
+            _bb.PutInt(_space -= sizeof(int), x);
+        }
+
+        public void PutUint(uint x)
+        {
+          _bb.PutUint(_space -= sizeof(uint), x);
+        }
+
+        public void PutLong(long x)
+        {
+            _bb.PutLong(_space -= sizeof(long), x);
+        }
+
+        public void PutUlong(ulong x)
+        {
+          _bb.PutUlong(_space -= sizeof(ulong), x);
+        }
+
+        public void PutFloat(float x)
+        {
+            _bb.PutFloat(_space -= sizeof(float), x);
+        }
+
+        /// <summary>
+        /// Puts an array of type T into this builder at the
+        /// current offset
+        /// </summary>
+        /// <typeparam name="T">The type of the input data </typeparam>
+        /// <param name="x">The array to copy data from</param>
+        public void Put<T>(T[] x)
+            where T : struct
+        {
+            _space = _bb.Put(_space, x);
+        }
+
+#if ENABLE_SPAN_T
+        /// <summary>
+        /// Puts a span of type T into this builder at the
+        /// current offset
+        /// </summary>
+        /// <typeparam name="T">The type of the input data </typeparam>
+        /// <param name="x">The span to copy data from</param>
+        public void Put<T>(Span<T> x)
+            where T : struct
+        {
+            _space = _bb.Put(_space, x);
+        }
+#endif
+
+        public void PutDouble(double x)
+        {
+            _bb.PutDouble(_space -= sizeof(double), x);
+        }
+        /// @endcond
+
+        /// <summary>
+        /// Add a `bool` to the buffer (aligns the data and grows if necessary).
+        /// </summary>
+        /// <param name="x">The `bool` to add to the buffer.</param>
+        public void AddBool(bool x) { Prep(sizeof(byte), 0); PutBool(x); }
+
+        /// <summary>
+        /// Add a `sbyte` to the buffer (aligns the data and grows if necessary).
+        /// </summary>
+        /// <param name="x">The `sbyte` to add to the buffer.</param>
+        public void AddSbyte(sbyte x) { Prep(sizeof(sbyte), 0); PutSbyte(x); }
+
+        /// <summary>
+        /// Add a `byte` to the buffer (aligns the data and grows if necessary).
+        /// </summary>
+        /// <param name="x">The `byte` to add to the buffer.</param>
+        public void AddByte(byte x) { Prep(sizeof(byte), 0); PutByte(x); }
+
+        /// <summary>
+        /// Add a `short` to the buffer (aligns the data and grows if necessary).
+        /// </summary>
+        /// <param name="x">The `short` to add to the buffer.</param>
+        public void AddShort(short x) { Prep(sizeof(short), 0); PutShort(x); }
+
+        /// <summary>
+        /// Add an `ushort` to the buffer (aligns the data and grows if necessary).
+        /// </summary>
+        /// <param name="x">The `ushort` to add to the buffer.</param>
+        public void AddUshort(ushort x) { Prep(sizeof(ushort), 0); PutUshort(x); }
+
+        /// <summary>
+        /// Add an `int` to the buffer (aligns the data and grows if necessary).
+        /// </summary>
+        /// <param name="x">The `int` to add to the buffer.</param>
+        public void AddInt(int x) { Prep(sizeof(int), 0); PutInt(x); }
+
+        /// <summary>
+        /// Add an `uint` to the buffer (aligns the data and grows if necessary).
+        /// </summary>
+        /// <param name="x">The `uint` to add to the buffer.</param>
+        public void AddUint(uint x) { Prep(sizeof(uint), 0); PutUint(x); }
+
+        /// <summary>
+        /// Add a `long` to the buffer (aligns the data and grows if necessary).
+        /// </summary>
+        /// <param name="x">The `long` to add to the buffer.</param>
+        public void AddLong(long x) { Prep(sizeof(long), 0); PutLong(x); }
+
+        /// <summary>
+        /// Add an `ulong` to the buffer (aligns the data and grows if necessary).
+        /// </summary>
+        /// <param name="x">The `ulong` to add to the buffer.</param>
+        public void AddUlong(ulong x) { Prep(sizeof(ulong), 0); PutUlong(x); }
+
+        /// <summary>
+        /// Add a `float` to the buffer (aligns the data and grows if necessary).
+        /// </summary>
+        /// <param name="x">The `float` to add to the buffer.</param>
+        public void AddFloat(float x) { Prep(sizeof(float), 0); PutFloat(x); }
+
+        /// <summary>
+        /// Add an array of type T to the buffer (aligns the data and grows if necessary).
+        /// </summary>
+        /// <typeparam name="T">The type of the input data</typeparam>
+        /// <param name="x">The array to copy data from</param>
+        public void Add<T>(T[] x)
+            where T : struct
+        {
+            if (x == null)
+            {
+                throw new ArgumentNullException("Cannot add a null array");
+            }
+
+            if( x.Length == 0)
+            {
+                // don't do anything if the array is empty
+                return;
+            }
+
+            if(!ByteBuffer.IsSupportedType<T>())
+            {
+                throw new ArgumentException("Cannot add this Type array to the builder");
+            }
+
+            int size = ByteBuffer.SizeOf<T>();
+            // Need to prep on size (for data alignment) and then we pass the
+            // rest of the length (minus 1) as additional bytes
+            Prep(size, size * (x.Length - 1));
+            Put(x);
+        }
+
+#if ENABLE_SPAN_T
+        /// <summary>
+        /// Add a span of type T to the buffer (aligns the data and grows if necessary).
+        /// </summary>
+        /// <typeparam name="T">The type of the input data</typeparam>
+        /// <param name="x">The span to copy data from</param>
+        public void Add<T>(Span<T> x)
+            where T : struct
+        {
+            if (!ByteBuffer.IsSupportedType<T>())
+            {
+                throw new ArgumentException("Cannot add this Type array to the builder");
+            }
+
+            int size = ByteBuffer.SizeOf<T>();
+            // Need to prep on size (for data alignment) and then we pass the
+            // rest of the length (minus 1) as additional bytes
+            Prep(size, size * (x.Length - 1));
+            Put(x);
+        }
+#endif
+
+        /// <summary>
+        /// Add a `double` to the buffer (aligns the data and grows if necessary).
+        /// </summary>
+        /// <param name="x">The `double` to add to the buffer.</param>
+        public void AddDouble(double x) { Prep(sizeof(double), 0);
+                                          PutDouble(x); }
+
+        /// <summary>
+        /// Adds an offset, relative to where it will be written.
+        /// </summary>
+        /// <param name="off">The offset to add to the buffer.</param>
+        public void AddOffset(int off)
+        {
+            Prep(sizeof(int), 0);  // Ensure alignment is already done.
+            if (off > Offset)
+                throw new ArgumentException();
+
+            off = Offset - off + sizeof(int);
+            PutInt(off);
+        }
+
+        /// @cond FLATBUFFERS_INTERNAL
+        public void StartVector(int elemSize, int count, int alignment)
+        {
+            NotNested();
+            _vectorNumElems = count;
+            Prep(sizeof(int), elemSize * count);
+            Prep(alignment, elemSize * count); // Just in case alignment > int.
+        }
+        /// @endcond
+
+        /// <summary>
+        /// Writes data necessary to finish a vector construction.
+        /// </summary>
+        public VectorOffset EndVector()
+        {
+            PutInt(_vectorNumElems);
+            return new VectorOffset(Offset);
+        }
+
+        /// <summary>
+        /// Creates a vector of tables.
+        /// </summary>
+        /// <param name="offsets">Offsets of the tables.</param>
+        public VectorOffset CreateVectorOfTables<T>(Offset<T>[] offsets) where T : struct
+        {
+            NotNested();
+            StartVector(sizeof(int), offsets.Length, sizeof(int));
+            for (int i = offsets.Length - 1; i >= 0; i--) AddOffset(offsets[i].Value);
+            return EndVector();
+        }
+
+        /// @cond FLATBUFFERS_INTENRAL
+        public void Nested(int obj)
+        {
+            // Structs are always stored inline, so need to be created right
+            // where they are used. You'll get this assert if you created it
+            // elsewhere.
+            if (obj != Offset)
+                throw new Exception(
+                    "FlatBuffers: struct must be serialized inline.");
+        }
+
+        public void NotNested()
+        {
+            // You should not be creating any other objects or strings/vectors
+            // while an object is being constructed
+            if (_vtableSize >= 0)
+                throw new Exception(
+                    "FlatBuffers: object serialization must not be nested.");
+        }
+
+        public void StartTable(int numfields)
+        {
+            if (numfields < 0)
+                throw new ArgumentOutOfRangeException("Flatbuffers: invalid numfields");
+
+            NotNested();
+
+            if (_vtable.Length < numfields)
+                _vtable = new int[numfields];
+
+            _vtableSize = numfields;
+            _objectStart = Offset;
+        }
+
+
+        // Set the current vtable at `voffset` to the current location in the
+        // buffer.
+        public void Slot(int voffset)
+        {
+            if (voffset >= _vtableSize)
+                throw new IndexOutOfRangeException("Flatbuffers: invalid voffset");
+
+            _vtable[voffset] = Offset;
+        }
+
+        /// <summary>
+        /// Adds a Boolean to the Table at index `o` in its vtable using the value `x` and default `d`
+        /// </summary>
+        /// <param name="o">The index into the vtable</param>
+        /// <param name="x">The value to put into the buffer. If the value is equal to the default
+        /// and <see cref="ForceDefaults"/> is false, the value will be skipped.</param>
+        /// <param name="d">The default value to compare the value against</param>
+        public void AddBool(int o, bool x, bool d) { if (ForceDefaults || x != d) { AddBool(x); Slot(o); } }
+
+        /// <summary>
+        /// Adds a SByte to the Table at index `o` in its vtable using the value `x` and default `d`
+        /// </summary>
+        /// <param name="o">The index into the vtable</param>
+        /// <param name="x">The value to put into the buffer. If the value is equal to the default
+        /// and <see cref="ForceDefaults"/> is false, the value will be skipped.</param>
+        /// <param name="d">The default value to compare the value against</param>
+        public void AddSbyte(int o, sbyte x, sbyte d) { if (ForceDefaults || x != d) { AddSbyte(x); Slot(o); } }
+
+        /// <summary>
+        /// Adds a Byte to the Table at index `o` in its vtable using the value `x` and default `d`
+        /// </summary>
+        /// <param name="o">The index into the vtable</param>
+        /// <param name="x">The value to put into the buffer. If the value is equal to the default
+        /// and <see cref="ForceDefaults"/> is false, the value will be skipped.</param>
+        /// <param name="d">The default value to compare the value against</param>
+        public void AddByte(int o, byte x, byte d) { if (ForceDefaults || x != d) { AddByte(x); Slot(o); } }
+
+        /// <summary>
+        /// Adds a Int16 to the Table at index `o` in its vtable using the value `x` and default `d`
+        /// </summary>
+        /// <param name="o">The index into the vtable</param>
+        /// <param name="x">The value to put into the buffer. If the value is equal to the default
+        /// and <see cref="ForceDefaults"/> is false, the value will be skipped.</param>
+        /// <param name="d">The default value to compare the value against</param>
+        public void AddShort(int o, short x, int d) { if (ForceDefaults || x != d) { AddShort(x); Slot(o); } }
+
+        /// <summary>
+        /// Adds a UInt16 to the Table at index `o` in its vtable using the value `x` and default `d`
+        /// </summary>
+        /// <param name="o">The index into the vtable</param>
+        /// <param name="x">The value to put into the buffer. If the value is equal to the default
+        /// and <see cref="ForceDefaults"/> is false, the value will be skipped.</param>
+        /// <param name="d">The default value to compare the value against</param>
+        public void AddUshort(int o, ushort x, ushort d) { if (ForceDefaults || x != d) { AddUshort(x); Slot(o); } }
+
+        /// <summary>
+        /// Adds an Int32 to the Table at index `o` in its vtable using the value `x` and default `d`
+        /// </summary>
+        /// <param name="o">The index into the vtable</param>
+        /// <param name="x">The value to put into the buffer. If the value is equal to the default
+        /// and <see cref="ForceDefaults"/> is false, the value will be skipped.</param>
+        /// <param name="d">The default value to compare the value against</param>
+        public void AddInt(int o, int x, int d) { if (ForceDefaults || x != d) { AddInt(x); Slot(o); } }
+
+        /// <summary>
+        /// Adds a UInt32 to the Table at index `o` in its vtable using the value `x` and default `d`
+        /// </summary>
+        /// <param name="o">The index into the vtable</param>
+        /// <param name="x">The value to put into the buffer. If the value is equal to the default
+        /// and <see cref="ForceDefaults"/> is false, the value will be skipped.</param>
+        /// <param name="d">The default value to compare the value against</param>
+        public void AddUint(int o, uint x, uint d) { if (ForceDefaults || x != d) { AddUint(x); Slot(o); } }
+
+        /// <summary>
+        /// Adds an Int64 to the Table at index `o` in its vtable using the value `x` and default `d`
+        /// </summary>
+        /// <param name="o">The index into the vtable</param>
+        /// <param name="x">The value to put into the buffer. If the value is equal to the default
+        /// and <see cref="ForceDefaults"/> is false, the value will be skipped.</param>
+        /// <param name="d">The default value to compare the value against</param>
+        public void AddLong(int o, long x, long d) { if (ForceDefaults || x != d) { AddLong(x); Slot(o); } }
+
+        /// <summary>
+        /// Adds a UInt64 to the Table at index `o` in its vtable using the value `x` and default `d`
+        /// </summary>
+        /// <param name="o">The index into the vtable</param>
+        /// <param name="x">The value to put into the buffer. If the value is equal to the default
+        /// and <see cref="ForceDefaults"/> is false, the value will be skipped.</param>
+        /// <param name="d">The default value to compare the value against</param>
+        public void AddUlong(int o, ulong x, ulong d) { if (ForceDefaults || x != d) { AddUlong(x); Slot(o); } }
+
+        /// <summary>
+        /// Adds a Single to the Table at index `o` in its vtable using the value `x` and default `d`
+        /// </summary>
+        /// <param name="o">The index into the vtable</param>
+        /// <param name="x">The value to put into the buffer. If the value is equal to the default
+        /// and <see cref="ForceDefaults"/> is false, the value will be skipped.</param>
+        /// <param name="d">The default value to compare the value against</param>
+        public void AddFloat(int o, float x, double d) { if (ForceDefaults || x != d) { AddFloat(x); Slot(o); } }
+
+        /// <summary>
+        /// Adds a Double to the Table at index `o` in its vtable using the value `x` and default `d`
+        /// </summary>
+        /// <param name="o">The index into the vtable</param>
+        /// <param name="x">The value to put into the buffer. If the value is equal to the default
+        /// and <see cref="ForceDefaults"/> is false, the value will be skipped.</param>
+        /// <param name="d">The default value to compare the value against</param>
+        public void AddDouble(int o, double x, double d) { if (ForceDefaults || x != d) { AddDouble(x); Slot(o); } }
+
+        /// <summary>
+        /// Adds a buffer offset to the Table at index `o` in its vtable using the value `x` and default `d`
+        /// </summary>
+        /// <param name="o">The index into the vtable</param>
+        /// <param name="x">The value to put into the buffer. If the value is equal to the default
+        /// the value will be skipped.</param>
+        /// <param name="d">The default value to compare the value against</param>
+        public void AddOffset(int o, int x, int d) { if (x != d) { AddOffset(x); Slot(o); } }
+        /// @endcond
+
+        /// <summary>
+        /// Encode the string `s` in the buffer using UTF-8.
+        /// </summary>
+        /// <param name="s">The string to encode.</param>
+        /// <returns>
+        /// The offset in the buffer where the encoded string starts.
+        /// </returns>
+        public StringOffset CreateString(string s)
+        {
+            NotNested();
+            AddByte(0);
+            var utf8StringLen = Encoding.UTF8.GetByteCount(s);
+            StartVector(1, utf8StringLen, 1);
+            _bb.PutStringUTF8(_space -= utf8StringLen, s);
+            return new StringOffset(EndVector().Value);
+        }
+
+
+#if ENABLE_SPAN_T
+        /// <summary>
+        /// Creates a string in the buffer from a Span containing
+        /// a UTF8 string.
+        /// </summary>
+        /// <param name="chars">the UTF8 string to add to the buffer</param>
+        /// <returns>
+        /// The offset in the buffer where the encoded string starts.
+        /// </returns>
+        public StringOffset CreateUTF8String(Span<byte> chars)
+        {
+            NotNested();
+            AddByte(0);
+            var utf8StringLen = chars.Length;
+            StartVector(1, utf8StringLen, 1);
+            _space = _bb.Put(_space, chars);
+            return new StringOffset(EndVector().Value);
+        }
+#endif
+
+        /// <summary>
+        /// Store a string in the buffer, which can contain any binary data.
+        /// If a string with this exact contents has already been serialized before,
+        /// instead simply returns the offset of the existing string.
+        /// </summary>
+        /// <param name="s">The string to encode.</param>
+        /// <returns>
+        /// The offset in the buffer where the encoded string starts.
+        /// </returns>
+        public StringOffset CreateSharedString(string s)
+        {
+            if (_sharedStringMap == null)
+            {
+                _sharedStringMap = new Dictionary<string, StringOffset>();
+            }
+
+            if (_sharedStringMap.ContainsKey(s))
+            {
+                return _sharedStringMap[s];
+            }
+
+            var stringOffset = CreateString(s);
+            _sharedStringMap.Add(s, stringOffset);
+            return stringOffset;
+        }
+
+        /// @cond FLATBUFFERS_INTERNAL
+        // Structs are stored inline, so nothing additional is being added.
+        // `d` is always 0.
+        public void AddStruct(int voffset, int x, int d)
+        {
+            if (x != d)
+            {
+                Nested(x);
+                Slot(voffset);
+            }
+        }
+
+        public int EndTable()
+        {
+            if (_vtableSize < 0)
+                throw new InvalidOperationException(
+                  "Flatbuffers: calling EndTable without a StartTable");
+
+            AddInt((int)0);
+            var vtableloc = Offset;
+            // Write out the current vtable.
+            int i = _vtableSize - 1;
+            // Trim trailing zeroes.
+            for (; i >= 0 && _vtable[i] == 0; i--) {}
+            int trimmedSize = i + 1;
+            for (; i >= 0 ; i--) {
+                // Offset relative to the start of the table.
+                short off = (short)(_vtable[i] != 0
+                                        ? vtableloc - _vtable[i]
+                                        : 0);
+                AddShort(off);
+
+                // clear out written entry
+                _vtable[i] = 0;
+            }
+
+            const int standardFields = 2; // The fields below:
+            AddShort((short)(vtableloc - _objectStart));
+            AddShort((short)((trimmedSize + standardFields) *
+                             sizeof(short)));
+
+            // Search for an existing vtable that matches the current one.
+            int existingVtable = 0;
+            for (i = 0; i < _numVtables; i++) {
+                int vt1 = _bb.Length - _vtables[i];
+                int vt2 = _space;
+                short len = _bb.GetShort(vt1);
+                if (len == _bb.GetShort(vt2)) {
+                    for (int j = sizeof(short); j < len; j += sizeof(short)) {
+                        if (_bb.GetShort(vt1 + j) != _bb.GetShort(vt2 + j)) {
+                            goto endLoop;
+                        }
+                    }
+                    existingVtable = _vtables[i];
+                    break;
+                }
+
+                endLoop: { }
+            }
+
+            if (existingVtable != 0) {
+                // Found a match:
+                // Remove the current vtable.
+                _space = _bb.Length - vtableloc;
+                // Point table to existing vtable.
+                _bb.PutInt(_space, existingVtable - vtableloc);
+            } else {
+                // No match:
+                // Add the location of the current vtable to the list of
+                // vtables.
+                if (_numVtables == _vtables.Length)
+                {
+                    // Arrays.CopyOf(vtables num_vtables * 2);
+                    var newvtables = new int[ _numVtables * 2];
+                    Array.Copy(_vtables, newvtables, _vtables.Length);
+
+                    _vtables = newvtables;
+                };
+                _vtables[_numVtables++] = Offset;
+                // Point table to current vtable.
+                _bb.PutInt(_bb.Length - vtableloc, Offset - vtableloc);
+            }
+
+            _vtableSize = -1;
+            return vtableloc;
+        }
+
+        // This checks a required field has been set in a given table that has
+        // just been constructed.
+        public void Required(int table, int field)
+        {
+          int table_start = _bb.Length - table;
+          int vtable_start = table_start - _bb.GetInt(table_start);
+          bool ok = _bb.GetShort(vtable_start + field) != 0;
+          // If this fails, the caller will show what field needs to be set.
+          if (!ok)
+            throw new InvalidOperationException("FlatBuffers: field " + field +
+                                                " must be set");
+        }
+        /// @endcond
+
+        /// <summary>
+        /// Finalize a buffer, pointing to the given `root_table`.
+        /// </summary>
+        /// <param name="rootTable">
+        /// An offset to be added to the buffer.
+        /// </param>
+        /// <param name="sizePrefix">
+        /// Whether to prefix the size to the buffer.
+        /// </param>
+        protected void Finish(int rootTable, bool sizePrefix)
+        {
+            Prep(_minAlign, sizeof(int) + (sizePrefix ? sizeof(int) : 0));
+            AddOffset(rootTable);
+            if (sizePrefix) {
+                AddInt(_bb.Length - _space);
+            }
+            _bb.Position = _space;
+        }
+
+        /// <summary>
+        /// Finalize a buffer, pointing to the given `root_table`.
+        /// </summary>
+        /// <param name="rootTable">
+        /// An offset to be added to the buffer.
+        /// </param>
+        public void Finish(int rootTable)
+        {
+            Finish(rootTable, false);
+        }
+
+        /// <summary>
+        /// Finalize a buffer, pointing to the given `root_table`, with the size prefixed.
+        /// </summary>
+        /// <param name="rootTable">
+        /// An offset to be added to the buffer.
+        /// </param>
+        public void FinishSizePrefixed(int rootTable)
+        {
+            Finish(rootTable, true);
+        }
+
+        /// <summary>
+        /// Get the ByteBuffer representing the FlatBuffer.
+        /// </summary>
+        /// <remarks>
+        /// This is typically only called after you call `Finish()`.
+        /// The actual data starts at the ByteBuffer's current position,
+        /// not necessarily at `0`.
+        /// </remarks>
+        /// <returns>
+        /// Returns the ByteBuffer for this FlatBuffer.
+        /// </returns>
+        public ByteBuffer DataBuffer { get { return _bb; } }
+
+        /// <summary>
+        /// A utility function to copy and return the ByteBuffer data as a
+        /// `byte[]`.
+        /// </summary>
+        /// <returns>
+        /// A full copy of the FlatBuffer data.
+        /// </returns>
+        public byte[] SizedByteArray()
+        {
+            return _bb.ToSizedArray();
+        }
+
+        /// <summary>
+        /// Finalize a buffer, pointing to the given `rootTable`.
+        /// </summary>
+        /// <param name="rootTable">
+        /// An offset to be added to the buffer.
+        /// </param>
+        /// <param name="fileIdentifier">
+        /// A FlatBuffer file identifier to be added to the buffer before
+        /// `root_table`.
+        /// </param>
+        /// <param name="sizePrefix">
+        /// Whether to prefix the size to the buffer.
+        /// </param>
+        protected void Finish(int rootTable, string fileIdentifier, bool sizePrefix)
+        {
+            Prep(_minAlign, sizeof(int) + (sizePrefix ? sizeof(int) : 0) +
+                            FlatBufferConstants.FileIdentifierLength);
+            if (fileIdentifier.Length !=
+                FlatBufferConstants.FileIdentifierLength)
+                throw new ArgumentException(
+                    "FlatBuffers: file identifier must be length " +
+                    FlatBufferConstants.FileIdentifierLength,
+                    "fileIdentifier");
+            for (int i = FlatBufferConstants.FileIdentifierLength - 1; i >= 0;
+                 i--)
+            {
+               AddByte((byte)fileIdentifier[i]);
+            }
+            Finish(rootTable, sizePrefix);
+        }
+
+        /// <summary>
+        /// Finalize a buffer, pointing to the given `rootTable`.
+        /// </summary>
+        /// <param name="rootTable">
+        /// An offset to be added to the buffer.
+        /// </param>
+        /// <param name="fileIdentifier">
+        /// A FlatBuffer file identifier to be added to the buffer before
+        /// `root_table`.
+        /// </param>
+        public void Finish(int rootTable, string fileIdentifier)
+        {
+            Finish(rootTable, fileIdentifier, false);
+        }
+
+        /// <summary>
+        /// Finalize a buffer, pointing to the given `rootTable`, with the size prefixed.
+        /// </summary>
+        /// <param name="rootTable">
+        /// An offset to be added to the buffer.
+        /// </param>
+        /// <param name="fileIdentifier">
+        /// A FlatBuffer file identifier to be added to the buffer before
+        /// `root_table`.
+        /// </param>
+        public void FinishSizePrefixed(int rootTable, string fileIdentifier)
+        {
+            Finish(rootTable, fileIdentifier, true);
+        }
+    }
+}
+
+/// @}
diff --git a/third_party/flatbuffers/net/FlatBuffers/FlatBufferConstants.cs b/third_party/flatbuffers/net/FlatBuffers/FlatBufferConstants.cs
new file mode 100644
index 0000000..730d7ef
--- /dev/null
+++ b/third_party/flatbuffers/net/FlatBuffers/FlatBufferConstants.cs
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace FlatBuffers
+{
+    public static class FlatBufferConstants
+    {
+        public const int FileIdentifierLength = 4;
+        public const int SizePrefixLength = 4;
+        /** A version identifier to force a compile error if someone
+        accidentally tries to build generated code with a runtime of
+        two mismatched version. Versions need to always match, as
+        the runtime and generated code are modified in sync.
+        Changes to the C# implementation need to be sure to change
+        the version here and in the code generator on every possible
+        incompatible change */
+        public static void FLATBUFFERS_1_11_1() {}
+    }
+}
diff --git a/third_party/flatbuffers/net/FlatBuffers/FlatBuffers.Core.csproj b/third_party/flatbuffers/net/FlatBuffers/FlatBuffers.Core.csproj
new file mode 100644
index 0000000..4285dd7
--- /dev/null
+++ b/third_party/flatbuffers/net/FlatBuffers/FlatBuffers.Core.csproj
@@ -0,0 +1,19 @@
+﻿<Project Sdk="Microsoft.NET.Sdk">
+
+    <PropertyGroup>
+        <TargetFramework>netstandard2.0</TargetFramework>
+    </PropertyGroup>
+
+    <ItemGroup>
+      <Compile Remove="Properties\**" />
+    </ItemGroup>
+
+    <ItemGroup>
+      <EmbeddedResource Remove="Properties\**" />
+    </ItemGroup>
+
+    <ItemGroup>
+      <None Remove="Properties\**" />
+    </ItemGroup>
+
+</Project>
diff --git a/third_party/flatbuffers/net/FlatBuffers/FlatBuffers.csproj b/third_party/flatbuffers/net/FlatBuffers/FlatBuffers.csproj
new file mode 100644
index 0000000..a029094
--- /dev/null
+++ b/third_party/flatbuffers/net/FlatBuffers/FlatBuffers.csproj
@@ -0,0 +1,54 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{28C00774-1E73-4A75-AD8F-844CD21A064D}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>FlatBuffers</RootNamespace>
+    <AssemblyName>FlatBuffers</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ByteBuffer.cs" />
+    <Compile Include="FlatBufferBuilder.cs" />
+    <Compile Include="FlatBufferConstants.cs" />
+    <Compile Include="IFlatbufferObject.cs" />
+    <Compile Include="Offset.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Struct.cs" />
+    <Compile Include="Table.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/third_party/flatbuffers/net/FlatBuffers/IFlatbufferObject.cs b/third_party/flatbuffers/net/FlatBuffers/IFlatbufferObject.cs
new file mode 100644
index 0000000..6a15aba
--- /dev/null
+++ b/third_party/flatbuffers/net/FlatBuffers/IFlatbufferObject.cs
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+namespace FlatBuffers
+{
+    /// <summary>
+    /// This is the base for both structs and tables.
+    /// </summary>
+    public interface IFlatbufferObject
+    {
+        void __init(int _i, ByteBuffer _bb);
+
+        ByteBuffer ByteBuffer { get; }
+    }
+}
diff --git a/third_party/flatbuffers/net/FlatBuffers/Offset.cs b/third_party/flatbuffers/net/FlatBuffers/Offset.cs
new file mode 100644
index 0000000..2b17cec
--- /dev/null
+++ b/third_party/flatbuffers/net/FlatBuffers/Offset.cs
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+namespace FlatBuffers
+{
+    /// <summary>
+    /// Offset class for typesafe assignments.
+    /// </summary>
+    public struct Offset<T> where T : struct
+    {
+        public int Value;
+        public Offset(int value)
+        {
+            Value = value;
+        }
+    }
+
+    public struct StringOffset
+    {
+        public int Value;
+        public StringOffset(int value)
+        {
+            Value = value;
+        }
+    }
+
+    public struct VectorOffset
+    {
+        public int Value;
+        public VectorOffset(int value)
+        {
+            Value = value;
+        }
+    }
+}
diff --git a/third_party/flatbuffers/net/FlatBuffers/Properties/AssemblyInfo.cs b/third_party/flatbuffers/net/FlatBuffers/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..1edfac4
--- /dev/null
+++ b/third_party/flatbuffers/net/FlatBuffers/Properties/AssemblyInfo.cs
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("FlatBuffers")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("FlatBuffers")]
+[assembly: AssemblyCopyright("Copyright (c) 2015 Google Inc")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components.  If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("91c32e64-ef20-47df-9c9f-cec9207bc6df")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/third_party/flatbuffers/net/FlatBuffers/Struct.cs b/third_party/flatbuffers/net/FlatBuffers/Struct.cs
new file mode 100644
index 0000000..4f7fac9
--- /dev/null
+++ b/third_party/flatbuffers/net/FlatBuffers/Struct.cs
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+namespace FlatBuffers
+{
+    /// <summary>
+    /// All structs in the generated code derive from this class, and add their own accessors.
+    /// </summary>
+    public struct Struct
+    {
+        public int bb_pos { get; private set; }
+        public ByteBuffer bb { get; private set; }
+
+        // Re-init the internal state with an external buffer {@code ByteBuffer} and an offset within.
+        public Struct(int _i, ByteBuffer _bb)
+        {
+            bb = _bb;
+            bb_pos = _i;
+        }
+    }
+}
diff --git a/third_party/flatbuffers/net/FlatBuffers/Table.cs b/third_party/flatbuffers/net/FlatBuffers/Table.cs
new file mode 100644
index 0000000..e10ba95
--- /dev/null
+++ b/third_party/flatbuffers/net/FlatBuffers/Table.cs
@@ -0,0 +1,202 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Text;
+
+namespace FlatBuffers
+{
+    /// <summary>
+    /// All tables in the generated code derive from this struct, and add their own accessors.
+    /// </summary>
+    public struct Table
+    {
+        public int bb_pos { get; private set; }
+        public ByteBuffer bb { get; private set; }
+
+        public ByteBuffer ByteBuffer { get { return bb; } }
+
+        // Re-init the internal state with an external buffer {@code ByteBuffer} and an offset within.
+        public Table(int _i, ByteBuffer _bb)
+        {
+            bb = _bb;
+            bb_pos = _i;
+        }
+
+        // Look up a field in the vtable, return an offset into the object, or 0 if the field is not
+        // present.
+        public int __offset(int vtableOffset)
+        {
+            int vtable = bb_pos - bb.GetInt(bb_pos);
+            return vtableOffset < bb.GetShort(vtable) ? (int)bb.GetShort(vtable + vtableOffset) : 0;
+        }
+
+        public static int __offset(int vtableOffset, int offset, ByteBuffer bb)
+        {
+            int vtable = bb.Length - offset;
+            return (int)bb.GetShort(vtable + vtableOffset - bb.GetInt(vtable)) + vtable;
+        }
+
+        // Retrieve the relative offset stored at "offset"
+        public int __indirect(int offset)
+        {
+            return offset + bb.GetInt(offset);
+        }
+
+        public static int __indirect(int offset, ByteBuffer bb)
+        {
+            return offset + bb.GetInt(offset);
+        }
+
+        // Create a .NET String from UTF-8 data stored inside the flatbuffer.
+        public string __string(int offset)
+        {
+            offset += bb.GetInt(offset);
+            var len = bb.GetInt(offset);
+            var startPos = offset + sizeof(int);
+            return bb.GetStringUTF8(startPos, len);
+        }
+
+        // Get the length of a vector whose offset is stored at "offset" in this object.
+        public int __vector_len(int offset)
+        {
+            offset += bb_pos;
+            offset += bb.GetInt(offset);
+            return bb.GetInt(offset);
+        }
+
+        // Get the start of data of a vector whose offset is stored at "offset" in this object.
+        public int __vector(int offset)
+        {
+            offset += bb_pos;
+            return offset + bb.GetInt(offset) + sizeof(int);  // data starts after the length
+        }
+
+#if ENABLE_SPAN_T
+        // Get the data of a vector whoses offset is stored at "offset" in this object as an
+        // Spant&lt;byte&gt;. If the vector is not present in the ByteBuffer,
+        // then an empty span will be returned.
+        public Span<byte> __vector_as_span(int offset)
+        {
+            var o = this.__offset(offset);
+            if (0 == o)
+            {
+                return new Span<byte>();
+            }
+
+            var pos = this.__vector(o);
+            var len = this.__vector_len(o);
+            return bb.ToSpan(pos, len);
+        }
+#else
+        // Get the data of a vector whoses offset is stored at "offset" in this object as an
+        // ArraySegment&lt;byte&gt;. If the vector is not present in the ByteBuffer,
+        // then a null value will be returned.
+        public ArraySegment<byte>? __vector_as_arraysegment(int offset)
+        {
+            var o = this.__offset(offset);
+            if (0 == o)
+            {
+                return null;
+            }
+
+            var pos = this.__vector(o);
+            var len = this.__vector_len(o);
+            return bb.ToArraySegment(pos, len);
+        }
+#endif
+
+        // Get the data of a vector whoses offset is stored at "offset" in this object as an
+        // T[]. If the vector is not present in the ByteBuffer, then a null value will be
+        // returned.
+        public T[] __vector_as_array<T>(int offset)
+            where T : struct
+        {
+            if(!BitConverter.IsLittleEndian)
+            {
+                throw new NotSupportedException("Getting typed arrays on a Big Endian " +
+                    "system is not support");
+            }
+
+            var o = this.__offset(offset);
+            if (0 == o)
+            {
+                return null;
+            }
+
+            var pos = this.__vector(o);
+            var len = this.__vector_len(o);
+            return bb.ToArray<T>(pos, len);
+        }
+
+        // Initialize any Table-derived type to point to the union at the given offset.
+        public T __union<T>(int offset) where T : struct, IFlatbufferObject
+        {
+            offset += bb_pos;
+            T t = new T();
+            t.__init(offset + bb.GetInt(offset), bb);
+            return t;
+        }
+
+        public static bool __has_identifier(ByteBuffer bb, string ident)
+        {
+            if (ident.Length != FlatBufferConstants.FileIdentifierLength)
+                throw new ArgumentException("FlatBuffers: file identifier must be length " + FlatBufferConstants.FileIdentifierLength, "ident");
+
+            for (var i = 0; i < FlatBufferConstants.FileIdentifierLength; i++)
+            {
+                if (ident[i] != (char)bb.Get(bb.Position + sizeof(int) + i)) return false;
+            }
+
+            return true;
+        }
+
+        // Compare strings in the ByteBuffer.
+        public static int CompareStrings(int offset_1, int offset_2, ByteBuffer bb)
+        {
+            offset_1 += bb.GetInt(offset_1);
+            offset_2 += bb.GetInt(offset_2);
+            var len_1 = bb.GetInt(offset_1);
+            var len_2 = bb.GetInt(offset_2);
+            var startPos_1 = offset_1 + sizeof(int);
+            var startPos_2 = offset_2 + sizeof(int);
+            var len = Math.Min(len_1, len_2);
+            for(int i = 0; i < len; i++) {
+                byte b1 = bb.Get(i + startPos_1);
+                byte b2 = bb.Get(i + startPos_2);
+                if (b1 != b2)
+                    return b1 - b2;
+            }
+            return len_1 - len_2;
+        }
+
+        // Compare string from the ByteBuffer with the string object
+        public static int CompareStrings(int offset_1, byte[] key, ByteBuffer bb)
+        {
+            offset_1 += bb.GetInt(offset_1);
+            var len_1 = bb.GetInt(offset_1);
+            var len_2 = key.Length;
+            var startPos_1 = offset_1 + sizeof(int);
+            var len = Math.Min(len_1, len_2);
+            for (int i = 0; i < len; i++) {
+                byte b = bb.Get(i + startPos_1);
+                if (b != key[i])
+                    return b - key[i];
+            }
+            return len_1 - len_2;
+        }
+    }
+}
diff --git a/third_party/flatbuffers/package.json b/third_party/flatbuffers/package.json
new file mode 100644
index 0000000..f95e754
--- /dev/null
+++ b/third_party/flatbuffers/package.json
@@ -0,0 +1,34 @@
+{
+  "name": "flatbuffers",
+  "version": "1.11.0",
+  "description": "Memory Efficient Serialization Library",
+  "files": [
+    "js/flatbuffers.js",
+    "js/flatbuffers.mjs"
+  ],
+  "main": "js/flatbuffers",
+  "module": "js/flatbuffers.mjs",
+  "directories": {
+    "doc": "docs",
+    "test": "tests"
+  },
+  "scripts": {
+    "test": "tests/JavaScriptTest.sh",
+    "append-esm-export": "sed \"s/this.flatbuffers = flatbuffers;/export { flatbuffers };/\" js/flatbuffers.js > js/flatbuffers.mjs",
+    "prepublishOnly": "npm run append-esm-export"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/google/flatbuffers.git"
+  },
+  "keywords": [
+    "flatbuffers"
+  ],
+  "author": "The FlatBuffers project",
+  "license": "SEE LICENSE IN LICENSE.txt",
+  "bugs": {
+    "url": "https://github.com/google/flatbuffers/issues"
+  },
+  "homepage": "https://google.github.io/flatbuffers/",
+  "dependencies": {}
+}
diff --git a/third_party/flatbuffers/php/ByteBuffer.php b/third_party/flatbuffers/php/ByteBuffer.php
new file mode 100644
index 0000000..9929a7d
--- /dev/null
+++ b/third_party/flatbuffers/php/ByteBuffer.php
@@ -0,0 +1,493 @@
+<?php
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * 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.
+ */
+
+namespace Google\FlatBuffers;
+
+class ByteBuffer
+{
+    /**
+     * @var string $_buffer;
+     */
+    public $_buffer;
+
+    /**
+     * @var int $_pos;
+     */
+    private $_pos;
+
+    /**
+     * @var bool $_is_little_endian
+     */
+    private static $_is_little_endian = null;
+
+    public static function wrap($bytes)
+    {
+        $bb = new ByteBuffer(0);
+        $bb->_buffer = $bytes;
+
+        return $bb;
+    }
+
+    /**
+     * @param $size
+     */
+    public function __construct($size)
+    {
+        $this->_buffer = str_repeat("\0", $size);
+    }
+
+    /**
+     * @return int
+     */
+    public function capacity()
+    {
+        return strlen($this->_buffer);
+    }
+
+    /**
+     * @return int
+     */
+    public function getPosition()
+    {
+        return $this->_pos;
+    }
+
+    /**
+     * @param $pos
+     */
+    public function setPosition($pos)
+    {
+        $this->_pos = $pos;
+    }
+
+    /**
+     *
+     */
+    public function reset()
+    {
+        $this->_pos = 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function length()
+    {
+        return strlen($this->_buffer);
+    }
+
+    /**
+     * @return string
+     */
+    public function data()
+    {
+        return substr($this->_buffer, $this->_pos);
+    }
+
+    /**
+     * @return bool
+     */
+    public static function isLittleEndian()
+    {
+        if (ByteBuffer::$_is_little_endian === null) {
+            ByteBuffer::$_is_little_endian = unpack('S', "\x01\x00")[1] === 1;
+        }
+
+        return ByteBuffer::$_is_little_endian;
+    }
+
+    /**
+     * write little endian value to the buffer.
+     *
+     * @param $offset
+     * @param $count byte length
+     * @param $data actual values
+     */
+    public function writeLittleEndian($offset, $count, $data)
+    {
+        if (ByteBuffer::isLittleEndian()) {
+            for ($i = 0; $i < $count; $i++) {
+                $this->_buffer[$offset + $i] = chr($data >> $i * 8);
+            }
+        } else {
+            for ($i = 0; $i < $count; $i++) {
+                $this->_buffer[$offset + $count - 1 - $i] = chr($data >> $i * 8);
+            }
+        }
+    }
+
+    /**
+     * read little endian value from the buffer
+     *
+     * @param $offset
+     * @param $count acutal size
+     * @return int
+     */
+    public function readLittleEndian($offset, $count, $force_bigendian = false)
+    {
+        $this->assertOffsetAndLength($offset, $count);
+        $r = 0;
+
+        if (ByteBuffer::isLittleEndian() && $force_bigendian == false) {
+            for ($i = 0; $i < $count; $i++) {
+                $r |= ord($this->_buffer[$offset + $i]) << $i * 8;
+            }
+        } else {
+            for ($i = 0; $i < $count; $i++) {
+                $r |= ord($this->_buffer[$offset + $count -1 - $i]) << $i * 8;
+            }
+        }
+
+        return $r;
+    }
+
+    /**
+     * @param $offset
+     * @param $length
+     */
+    public function assertOffsetAndLength($offset, $length)
+    {
+        if ($offset < 0 ||
+            $offset >= strlen($this->_buffer) ||
+            $offset + $length > strlen($this->_buffer)) {
+            throw new \OutOfRangeException(sprintf("offset: %d, length: %d, buffer; %d", $offset, $length, strlen($this->_buffer)));
+        }
+    }
+
+    /**
+     * @param $offset
+     * @param $value
+     * @return mixed
+     */
+    public function putSbyte($offset, $value)
+    {
+        self::validateValue(-128, 127, $value, "sbyte");
+
+        $length = strlen($value);
+        $this->assertOffsetAndLength($offset, $length);
+        return $this->_buffer[$offset] = $value;
+    }
+
+    /**
+     * @param $offset
+     * @param $value
+     * @return mixed
+     */
+    public function putByte($offset, $value)
+    {
+        self::validateValue(0, 255, $value, "byte");
+
+        $length = strlen($value);
+        $this->assertOffsetAndLength($offset, $length);
+        return $this->_buffer[$offset] = $value;
+    }
+
+    /**
+     * @param $offset
+     * @param $value
+     */
+    public function put($offset, $value)
+    {
+        $length = strlen($value);
+        $this->assertOffsetAndLength($offset, $length);
+        for ($i = 0; $i < $length; $i++) {
+            $this->_buffer[$offset + $i] = $value[$i];
+        }
+    }
+
+    /**
+     * @param $offset
+     * @param $value
+     */
+    public function putShort($offset, $value)
+    {
+        self::validateValue(-32768, 32767, $value, "short");
+
+        $this->assertOffsetAndLength($offset, 2);
+        $this->writeLittleEndian($offset, 2, $value);
+    }
+
+    /**
+     * @param $offset
+     * @param $value
+     */
+    public function putUshort($offset, $value)
+    {
+        self::validateValue(0, 65535, $value, "short");
+
+        $this->assertOffsetAndLength($offset, 2);
+        $this->writeLittleEndian($offset, 2, $value);
+    }
+
+    /**
+     * @param $offset
+     * @param $value
+     */
+    public function putInt($offset, $value)
+    {
+        // 2147483647 = (1 << 31) -1 = Maximum signed 32-bit int
+        // -2147483648 = -1 << 31 = Minimum signed 32-bit int
+        self::validateValue(-2147483648, 2147483647, $value, "int");
+
+        $this->assertOffsetAndLength($offset, 4);
+        $this->writeLittleEndian($offset, 4, $value);
+    }
+
+    /**
+     * @param $offset
+     * @param $value
+     */
+    public function putUint($offset, $value)
+    {
+        // NOTE: We can't put big integer value. this is PHP limitation.
+        // 4294967295 = (1 << 32) -1 = Maximum unsigned 32-bin int
+        self::validateValue(0, 4294967295, $value, "uint",  " php has big numbers limitation. check your PHP_INT_MAX");
+
+        $this->assertOffsetAndLength($offset, 4);
+        $this->writeLittleEndian($offset, 4, $value);
+    }
+
+    /**
+     * @param $offset
+     * @param $value
+     */
+    public function putLong($offset, $value)
+    {
+        // NOTE: We can't put big integer value. this is PHP limitation.
+        self::validateValue(~PHP_INT_MAX, PHP_INT_MAX, $value, "long",  " php has big numbers limitation. check your PHP_INT_MAX");
+
+        $this->assertOffsetAndLength($offset, 8);
+        $this->writeLittleEndian($offset, 8, $value);
+    }
+
+    /**
+     * @param $offset
+     * @param $value
+     */
+    public function putUlong($offset, $value)
+    {
+        // NOTE: We can't put big integer value. this is PHP limitation.
+        self::validateValue(0, PHP_INT_MAX, $value, "long", " php has big numbers limitation. check your PHP_INT_MAX");
+
+        $this->assertOffsetAndLength($offset, 8);
+        $this->writeLittleEndian($offset, 8, $value);
+    }
+
+    /**
+     * @param $offset
+     * @param $value
+     */
+    public function putFloat($offset, $value)
+    {
+        $this->assertOffsetAndLength($offset, 4);
+
+        $floathelper = pack("f", $value);
+        $v = unpack("V", $floathelper);
+        $this->writeLittleEndian($offset, 4, $v[1]);
+    }
+
+    /**
+     * @param $offset
+     * @param $value
+     */
+    public function putDouble($offset, $value)
+    {
+        $this->assertOffsetAndLength($offset, 8);
+
+        $floathelper = pack("d", $value);
+        $v = unpack("V*", $floathelper);
+
+        $this->writeLittleEndian($offset, 4, $v[1]);
+        $this->writeLittleEndian($offset + 4, 4, $v[2]);
+    }
+
+    /**
+     * @param $index
+     * @return mixed
+     */
+    public function getByte($index)
+    {
+        return ord($this->_buffer[$index]);
+    }
+
+    /**
+     * @param $index
+     * @return mixed
+     */
+    public function getSbyte($index)
+    {
+        $v = unpack("c", $this->_buffer[$index]);
+        return $v[1];
+    }
+
+    /**
+     * @param $buffer
+     */
+    public function getX(&$buffer)
+    {
+        for ($i = $this->_pos, $j = 0; $j < strlen($buffer); $i++, $j++) {
+            $buffer[$j] = $this->_buffer[$i];
+        }
+    }
+
+    /**
+     * @param $index
+     * @return mixed
+     */
+    public function get($index)
+    {
+        $this->assertOffsetAndLength($index, 1);
+        return $this->_buffer[$index];
+    }
+
+
+    /**
+     * @param $index
+     * @return mixed
+     */
+    public function getBool($index)
+    {
+        return (bool)ord($this->_buffer[$index]);
+    }
+
+    /**
+     * @param $index
+     * @return int
+     */
+    public function getShort($index)
+    {
+        $result = $this->readLittleEndian($index, 2);
+
+        $sign = $index + (ByteBuffer::isLittleEndian() ? 1 : 0);
+        $issigned = isset($this->_buffer[$sign]) && ord($this->_buffer[$sign]) & 0x80;
+
+        // 65536 = 1 << 16 = Maximum unsigned 16-bit int
+        return $issigned ? $result - 65536 : $result;
+    }
+
+    /**
+     * @param $index
+     * @return int
+     */
+    public function getUShort($index)
+    {
+        return $this->readLittleEndian($index, 2);
+    }
+
+    /**
+     * @param $index
+     * @return int
+     */
+    public function getInt($index)
+    {
+        $result = $this->readLittleEndian($index, 4);
+
+        $sign = $index + (ByteBuffer::isLittleEndian() ? 3 : 0);
+        $issigned = isset($this->_buffer[$sign]) && ord($this->_buffer[$sign]) & 0x80;
+
+        if (PHP_INT_SIZE > 4) {
+            // 4294967296 = 1 << 32 = Maximum unsigned 32-bit int
+            return $issigned ? $result - 4294967296 : $result;
+        } else {
+            // 32bit / Windows treated number as signed integer.
+            return $result;
+        }
+    }
+
+    /**
+     * @param $index
+     * @return int
+     */
+    public function getUint($index)
+    {
+        return $this->readLittleEndian($index, 4);
+    }
+
+    /**
+     * @param $index
+     * @return int
+     */
+    public function getLong($index)
+    {
+        return $this->readLittleEndian($index, 8);
+    }
+
+    /**
+     * @param $index
+     * @return int
+     */
+    public function getUlong($index)
+    {
+        return $this->readLittleEndian($index, 8);
+    }
+
+    /**
+     * @param $index
+     * @return mixed
+     */
+    public function getFloat($index)
+    {
+        $i = $this->readLittleEndian($index, 4);
+
+        return self::convertHelper(self::__FLOAT, $i);
+    }
+
+    /**
+     * @param $index
+     * @return float
+     */
+    public function getDouble($index)
+    {
+        $i = $this->readLittleEndian($index, 4);
+        $i2 = $this->readLittleEndian($index + 4, 4);
+
+        return self::convertHelper(self::__DOUBLE, $i, $i2);
+    }
+
+    const __SHORT = 1;
+    const __INT = 2;
+    const __LONG = 3;
+    const __FLOAT = 4;
+    const __DOUBLE = 5;
+    private static function convertHelper($type, $value, $value2 = null) {
+        // readLittleEndian construct unsigned integer value from bytes. we have to encode this value to
+        // correct bytes, and decode as expected types with `unpack` function.
+        // then it returns correct type value.
+        // see also: http://php.net/manual/en/function.pack.php
+
+        switch ($type) {
+            case self::__FLOAT:
+                $inthelper = pack("V", $value);
+                $v = unpack("f", $inthelper);
+                return $v[1];
+                break;
+            case self::__DOUBLE:
+                $inthelper = pack("VV", $value, $value2);
+                $v = unpack("d", $inthelper);
+                return $v[1];
+                break;
+            default:
+                throw new \Exception(sprintf("unexpected type %d specified", $type));
+        }
+    }
+
+    private static function validateValue($min, $max, $value, $type, $additional_notes = "") {
+        if(!($min <= $value && $value <= $max)) {
+            throw new \InvalidArgumentException(sprintf("bad number %s for type %s.%s", $value, $type, $additional_notes));
+        }
+    }
+}
diff --git a/third_party/flatbuffers/php/Constants.php b/third_party/flatbuffers/php/Constants.php
new file mode 100644
index 0000000..ef3730d
--- /dev/null
+++ b/third_party/flatbuffers/php/Constants.php
@@ -0,0 +1,25 @@
+<?php
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * 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.
+ */
+
+namespace Google\FlatBuffers;
+
+class Constants
+{
+    const SIZEOF_SHORT = 2;
+    const SIZEOF_INT = 4;
+    const FILE_IDENTIFIER_LENGTH = 4;
+}
diff --git a/third_party/flatbuffers/php/FlatbufferBuilder.php b/third_party/flatbuffers/php/FlatbufferBuilder.php
new file mode 100644
index 0000000..4fbc2bc
--- /dev/null
+++ b/third_party/flatbuffers/php/FlatbufferBuilder.php
@@ -0,0 +1,977 @@
+<?php
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * 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.
+ */
+
+/// @file
+/// @addtogroup flatbuffers_php_api
+/// @{
+
+namespace Google\FlatBuffers;
+
+final class FlatbufferBuilder
+{
+    /**
+     * Internal ByteBuffer for the FlatBuffer data.
+     * @var ByteBuffer $bb
+     */
+    public $bb;
+
+    /// @cond FLATBUFFERS_INTERNAL
+    /**
+     * @var int $space
+     */
+    protected $space;
+
+    /**
+     * @var int $minalign
+     */
+    protected $minalign = 1;
+
+    /**
+     * @var array $vtable
+     */
+    protected $vtable;
+
+    /**
+     * @var int $vtable_in_use
+     */
+    protected $vtable_in_use = 0;
+
+    /**
+     * @var bool $nested
+     */
+    protected $nested = false;
+
+    /**
+     * @var int $object_start
+     */
+    protected $object_start;
+
+    /**
+     * @var array $vtables
+     */
+    protected $vtables = array();
+
+    /**
+     * @var int $num_vtables
+     */
+    protected $num_vtables = 0;
+
+    /**
+     * @var int $vector_num_elems
+     */
+    protected $vector_num_elems = 0;
+
+    /**
+     * @var bool $force_defaults
+     */
+    protected $force_defaults = false;
+    /// @endcond
+
+    /**
+     * Create a FlatBufferBuilder with a given initial size.
+     *
+     * @param $initial_size initial byte buffer size.
+     */
+    public function __construct($initial_size)
+    {
+        if ($initial_size <= 0) {
+            $initial_size = 1;
+        }
+        $this->space = $initial_size;
+        $this->bb = $this->newByteBuffer($initial_size);
+    }
+
+    /// @cond FLATBUFFERS_INTERNAL
+    /**
+     * create new bytebuffer
+     *
+     * @param $size
+     * @return ByteBuffer
+     */
+    private function newByteBuffer($size)
+    {
+        return new ByteBuffer($size);
+    }
+
+    /**
+     * Returns the current ByteBuffer offset.
+     *
+     * @return int
+     */
+    public function offset()
+    {
+        return $this->bb->capacity() - $this->space;
+    }
+
+    /**
+     * padding buffer
+     *
+     * @param $byte_size
+     */
+    public function pad($byte_size)
+    {
+        for ($i = 0; $i < $byte_size; $i++) {
+            $this->bb->putByte(--$this->space, "\0");
+        }
+    }
+
+    /**
+     * prepare bytebuffer
+     *
+     * @param $size
+     * @param $additional_bytes
+     * @throws \Exception
+     */
+    public function prep($size, $additional_bytes)
+    {
+        if ($size > $this->minalign) {
+            $this->minalign = $size;
+        }
+
+        $align_size = ((~($this->bb->capacity() - $this->space + $additional_bytes)) + 1) & ($size - 1);
+        while ($this->space < $align_size + $size  + $additional_bytes) {
+            $old_buf_size = $this->bb->capacity();
+            $this->bb = $this->growByteBuffer($this->bb);
+            $this->space += $this->bb->capacity() - $old_buf_size;
+        }
+
+        $this->pad($align_size);
+    }
+
+    /**
+     * @param ByteBuffer $bb
+     * @return ByteBuffer
+     * @throws \Exception
+     */
+    private static function growByteBuffer(ByteBuffer $bb)
+    {
+        $old_buf_size = $bb->capacity();
+        if (($old_buf_size & 0xC0000000) != 0) {
+            throw new \Exception("FlatBuffers: cannot grow buffer beyond 2 gigabytes");
+        }
+        $new_buf_size = $old_buf_size << 1;
+
+        $bb->setPosition(0);
+        $nbb = new ByteBuffer($new_buf_size);
+
+        $nbb->setPosition($new_buf_size - $old_buf_size);
+
+        // TODO(chobie): is this little bit faster?
+        //$nbb->_buffer = substr_replace($nbb->_buffer, $bb->_buffer, $new_buf_size - $old_buf_size, strlen($bb->_buffer));
+        for ($i = $new_buf_size - $old_buf_size, $j = 0; $j < strlen($bb->_buffer); $i++, $j++) {
+            $nbb->_buffer[$i] = $bb->_buffer[$j];
+        }
+
+        return $nbb;
+    }
+
+    /**
+     * @param $x
+     */
+    public function putBool($x)
+    {
+        $this->bb->put($this->space -= 1, chr((int)(bool)($x)));
+    }
+
+    /**
+     * @param $x
+     */
+    public function putByte($x)
+    {
+        $this->bb->put($this->space -= 1, chr($x));
+    }
+
+    /**
+     * @param $x
+     */
+    public function putSbyte($x)
+    {
+        $this->bb->put($this->space -= 1, chr($x));
+    }
+
+    /**
+     * @param $x
+     */
+    public function putShort($x)
+    {
+        $this->bb->putShort($this->space -= 2, $x);
+    }
+
+    /**
+     * @param $x
+     */
+    public function putUshort($x)
+    {
+        $this->bb->putUshort($this->space -= 2, $x);
+    }
+
+    /**
+     * @param $x
+     */
+    public function putInt($x)
+    {
+        $this->bb->putInt($this->space -= 4, $x);
+    }
+
+    /**
+     * @param $x
+     */
+    public function putUint($x)
+    {
+        if ($x > PHP_INT_MAX) {
+            throw new \InvalidArgumentException("your platform can't handle uint correctly. use 64bit machine.");
+        }
+
+        $this->bb->putUint($this->space -= 4, $x);
+    }
+
+    /**
+     * @param $x
+     */
+    public function putLong($x)
+    {
+        if ($x > PHP_INT_MAX) {
+            throw new \InvalidArgumentException("Your platform can't handle long correctly. Use a 64bit machine.");
+        }
+
+        $this->bb->putLong($this->space -= 8, $x);
+    }
+
+    /**
+     * @param $x
+     */
+    public function putUlong($x)
+    {
+        if ($x > PHP_INT_MAX) {
+            throw new \InvalidArgumentException("Your platform can't handle ulong correctly. This is a php limitation. Please wait for the extension release.");
+        }
+
+        $this->bb->putUlong($this->space -= 8, $x);
+    }
+
+    /**
+     * @param $x
+     */
+    public function putFloat($x)
+    {
+        $this->bb->putFloat($this->space -= 4, $x);
+    }
+
+    /**
+     * @param $x
+     */
+    public function putDouble($x)
+    {
+        $this->bb->putDouble($this->space -= 8, $x);
+    }
+
+    /**
+     * @param $off
+     */
+    public function putOffset($off)
+    {
+        $new_off = $this->offset() - $off + Constants::SIZEOF_INT;
+        $this->putInt($new_off);
+    }
+    /// @endcond
+
+    /**
+     * Add a `bool` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param $x The `bool` to add to the buffer.
+     */
+    public function addBool($x)
+    {
+        $this->prep(1, 0);
+        $this->putBool($x);
+    }
+
+    /**
+     * Add a `byte` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param $x The `byte` to add to the buffer.
+     */
+    public function addByte($x)
+    {
+        $this->prep(1, 0);
+        $this->putByte($x);
+    }
+
+    /**
+     * Add a `signed byte` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param $x The `signed byte` to add to the buffer.
+     */
+    public function addSbyte($x)
+    {
+        $this->prep(1, 0);
+        $this->putSbyte($x);
+    }
+
+    /**
+     * Add a `short` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param $x The `short` to add to the buffer.
+     */
+    public function addShort($x)
+    {
+        $this->prep(2, 0);
+        $this->putShort($x);
+    }
+
+    /**
+     * Add an `unsigned short` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param $x The `unsigned short` to add to the buffer.
+     */
+    public function addUshort($x)
+    {
+        $this->prep(2, 0);
+        $this->putUshort($x);
+    }
+
+    /**
+     * Add an `int` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param $x The `int` to add to the buffer.
+     */
+    public function addInt($x)
+    {
+        $this->prep(4, 0);
+        $this->putInt($x);
+    }
+
+    /**
+     * Add an `unsigned int` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param $x The `unsigned int` to add to the buffer.
+     */
+    public function addUint($x)
+    {
+        $this->prep(4, 0);
+        $this->putUint($x);
+    }
+
+    /**
+     * Add a `long` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param $x The `long` to add to the buffer.
+     */
+    public function addLong($x)
+    {
+        $this->prep(8, 0);
+        $this->putLong($x);
+    }
+
+    /**
+     * Add an `unsigned long` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param $x The `unsigned long` to add to the buffer.
+     */
+    public function addUlong($x)
+    {
+        $this->prep(8, 0);
+        $this->putUlong($x);
+    }
+
+    /**
+     * Add a `float` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param $x The `float` to add to the buffer.
+     */
+    public function addFloat($x)
+    {
+        $this->prep(4, 0);
+        $this->putFloat($x);
+    }
+
+    /**
+     * Add a `double` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param $x The `double` to add to the buffer.
+     */
+    public function addDouble($x)
+    {
+        $this->prep(8, 0);
+        $this->putDouble($x);
+    }
+
+    /// @cond FLATBUFFERS_INTERNAL
+    /**
+     * @param $o
+     * @param $x
+     * @param $d
+     */
+    public function addBoolX($o, $x, $d)
+    {
+        if ($this->force_defaults || $x != $d) {
+            $this->addBool($x);
+            $this->slot($o);
+        }
+    }
+
+    /**
+     * @param $o
+     * @param $x
+     * @param $d
+     */
+    public function addByteX($o, $x, $d)
+    {
+        if ($this->force_defaults || $x != $d) {
+            $this->addByte($x);
+            $this->slot($o);
+        }
+    }
+
+    /**
+     * @param $o
+     * @param $x
+     * @param $d
+     */
+    public function addSbyteX($o, $x, $d)
+    {
+        if ($this->force_defaults || $x != $d) {
+            $this->addSbyte($x);
+            $this->slot($o);
+        }
+    }
+
+    /**
+     * @param $o
+     * @param $x
+     * @param $d
+     */
+    public function addShortX($o, $x, $d)
+    {
+        if ($this->force_defaults || $x != $d) {
+            $this->addShort($x);
+            $this->slot($o);
+        }
+    }
+
+    /**
+     * @param $o
+     * @param $x
+     * @param $d
+     */
+    public function addUshortX($o, $x, $d)
+    {
+        if ($this->force_defaults || $x != $d) {
+            $this->addUshort($x);
+            $this->slot($o);
+        }
+    }
+
+    /**
+     * @param $o
+     * @param $x
+     * @param $d
+     */
+    public function addIntX($o, $x, $d)
+    {
+        if ($this->force_defaults || $x != $d) {
+            $this->addInt($x);
+            $this->slot($o);
+        }
+    }
+
+    /**
+     * @param $o
+     * @param $x
+     * @param $d
+     */
+    public function addUintX($o, $x, $d)
+    {
+        if ($this->force_defaults || $x != $d) {
+            $this->addUint($x);
+            $this->slot($o);
+        }
+    }
+
+    /**
+     * @param $o
+     * @param $x
+     * @param $d
+     */
+    public function addLongX($o, $x, $d)
+    {
+        if ($this->force_defaults || $x != $d) {
+            $this->addLong($x);
+            $this->slot($o);
+        }
+    }
+
+    /**
+     * @param $o
+     * @param $x
+     * @param $d
+     */
+    public function addUlongX($o, $x, $d)
+    {
+        if ($this->force_defaults || $x != $d) {
+            $this->addUlong($x);
+            $this->slot($o);
+        }
+    }
+
+
+    /**
+     * @param $o
+     * @param $x
+     * @param $d
+     */
+    public function addFloatX($o, $x, $d)
+    {
+        if ($this->force_defaults || $x != $d) {
+            $this->addFloat($x);
+            $this->slot($o);
+        }
+    }
+
+    /**
+     * @param $o
+     * @param $x
+     * @param $d
+     */
+    public function addDoubleX($o, $x, $d)
+    {
+        if ($this->force_defaults || $x != $d) {
+            $this->addDouble($x);
+            $this->slot($o);
+        }
+    }
+
+    /**
+     * @param $o
+     * @param $x
+     * @param $d
+     * @throws \Exception
+     */
+    public function addOffsetX($o, $x, $d)
+    {
+        if ($this->force_defaults || $x != $d) {
+            $this->addOffset($x);
+            $this->slot($o);
+        }
+    }
+    /// @endcond
+
+    /**
+     * Adds on offset, relative to where it will be written.
+     * @param $off The offset to add to the buffer.
+     * @throws \Exception Throws an exception if `$off` is greater than the underlying ByteBuffer's
+     * offest.
+     */
+    public function addOffset($off)
+    {
+        $this->prep(Constants::SIZEOF_INT, 0); // Ensure alignment is already done
+        if ($off > $this->offset()) {
+            throw new \Exception("");
+        }
+        $this->putOffset($off);
+    }
+
+    /// @cond FLATBUFFERS_INTERNAL
+    /**
+     * @param $elem_size
+     * @param $num_elems
+     * @param $alignment
+     * @throws \Exception
+     */
+    public function startVector($elem_size, $num_elems, $alignment)
+    {
+        $this->notNested();
+        $this->vector_num_elems = $num_elems;
+        $this->prep(Constants::SIZEOF_INT, $elem_size * $num_elems);
+        $this->prep($alignment, $elem_size * $num_elems); // Just in case alignemnt > int;
+    }
+
+    /**
+     * @return int
+     */
+    public function endVector()
+    {
+        $this->putUint($this->vector_num_elems);
+        return $this->offset();
+    }
+
+    protected function is_utf8($bytes)
+    {
+        if (function_exists('mb_detect_encoding')) {
+            return (bool) mb_detect_encoding($bytes, 'UTF-8', true);
+        }
+
+        $len = strlen($bytes);
+        if ($len < 1) {
+            /* NOTE: always return 1 when passed string is null */
+            return true;
+        }
+
+        for ($j = 0, $i = 0; $i < $len; $i++) {
+            // check ACII
+            if ($bytes[$j] == "\x09" ||
+                $bytes[$j] == "\x0A" ||
+                $bytes[$j] == "\x0D" ||
+                ($bytes[$j] >= "\x20" && $bytes[$j] <= "\x7E")) {
+                $j++;
+                continue;
+            }
+
+            /* non-overlong 2-byte */
+            if ((($i+1) <= $len) &&
+                ($bytes[$j] >= "\xC2" && $bytes[$j] <= "\xDF" &&
+                    ($bytes[$j+1] >= "\x80" && $bytes[$j+1] <= "\xBF"))) {
+                $j += 2;
+                $i++;
+                continue;
+            }
+
+            /* excluding overlongs */
+            if ((($i + 2) <= $len) &&
+                $bytes[$j] == "\xE0" &&
+                ($bytes[$j+1] >= "\xA0" && $bytes[$j+1] <= "\xBF" &&
+                    ($bytes[$j+2] >= "\x80" && $bytes[$j+2] <= "\xBF"))) {
+                $bytes += 3;
+                $i +=2;
+                continue;
+            }
+
+            /* straight 3-byte */
+            if ((($i+2) <= $len) &&
+                (($bytes[$j] >= "\xE1" && $bytes[$j] <= "\xEC") ||
+                    $bytes[$j] == "\xEE" ||
+                    $bytes[$j] = "\xEF") &&
+                ($bytes[$j+1] >= "\x80" && $bytes[$j+1] <= "\xBF") &&
+                ($bytes[$j+2] >= "\x80" && $bytes[$j+2] <= "\xBF")) {
+                $j += 3;
+                $i += 2;
+                continue;
+            }
+
+            /* excluding surrogates */
+            if ((($i+2) <= $len) &&
+                $bytes[$j] == "\xED" &&
+                ($bytes[$j+1] >= "\x80" && $bytes[$j+1] <= "\x9f" &&
+                    ($bytes[$j+2] >= "\x80" && $bytes[$j+2] <= "\xBF"))) {
+                $j += 3;
+                $i += 2;
+                continue;
+            }
+
+            /* planes 1-3 */
+            if ((($i + 3) <= $len) &&
+                $bytes[$j] == "\xF0" &&
+                ($bytes[$j+1] >= "\x90" && $bytes[$j+1] <= "\xBF") &&
+                ($bytes[$j+2] >= "\x80" && $bytes[$j+2] <= "\xBF") &&
+                ($bytes[$j+3] >= "\x80" && $bytes[$j+3] <= "\xBF")) {
+                $j += 4;
+                $i += 3;
+                continue;
+            }
+
+
+            /* planes 4-15 */
+            if ((($i+3) <= $len) &&
+                $bytes[$j] >= "\xF1" && $bytes[$j] <= "\xF3" &&
+                $bytes[$j+1] >= "\x80" && $bytes[$j+1] <= "\xBF" &&
+                $bytes[$j+2] >= "\x80" && $bytes[$j+2] <= "\xBF" &&
+                $bytes[$j+3] >= "\x80" && $bytes[$j+3] <= "\xBF"
+            ) {
+                $j += 4;
+                $i += 3;
+                continue;
+            }
+
+            /* plane 16 */
+            if ((($i+3) <= $len) &&
+                $bytes[$j] == "\xF4" &&
+                ($bytes[$j+1] >= "\x80" && $bytes[$j+1] <= "\x8F") &&
+                ($bytes[$j+2] >= "\x80" && $bytes[$j+2] <= "\xBF") &&
+                ($bytes[$j+3] >= "\x80" && $bytes[$j+3] <= "\xBF")
+            ) {
+                $bytes += 4;
+                $i += 3;
+                continue;
+            }
+
+
+            return false;
+        }
+
+        return true;
+    }
+    /// @endcond
+
+    /**
+     * Encode the string `$s` in the buffer using UTF-8.
+     * @param string $s The string to encode.
+     * @return int The offset in the buffer where the encoded string starts.
+     * @throws InvalidArgumentException Thrown if the input string `$s` is not
+     *     UTF-8.
+     */
+    public function createString($s)
+    {
+        if (!$this->is_utf8($s)) {
+            throw new \InvalidArgumentException("string must be utf-8 encoded value.");
+        }
+
+        $this->notNested();
+        $this->addByte(0); // null terminated
+        $this->startVector(1, strlen($s), 1);
+        $this->space -= strlen($s);
+        for ($i =  $this->space, $j = 0 ; $j < strlen($s) ; $i++, $j++) {
+            $this->bb->_buffer[$i] = $s[$j];
+        }
+        return $this->endVector();
+    }
+
+    /// @cond FLATBUFFERS_INTERNAL
+    /**
+     * @throws \Exception
+     */
+    public function notNested()
+    {
+        if ($this->nested) {
+            throw new \Exception("FlatBuffers; object serialization must not be nested");
+        }
+    }
+
+    /**
+     * @param $obj
+     * @throws \Exception
+     */
+    public function nested($obj)
+    {
+        if ($obj != $this->offset()) {
+            throw new \Exception("FlatBuffers: struct must be serialized inline");
+        }
+    }
+
+    /**
+     * @param $numfields
+     * @throws \Exception
+     */
+    public function startObject($numfields)
+    {
+        $this->notNested();
+        if ($this->vtable == null || count($this->vtable) < $numfields) {
+            $this->vtable = array();
+        }
+
+        $this->vtable_in_use = $numfields;
+        for ($i = 0; $i < $numfields; $i++) {
+            $this->vtable[$i] = 0;
+        }
+
+        $this->nested = true;
+        $this->object_start = $this->offset();
+    }
+
+    /**
+     * @param $voffset
+     * @param $x
+     * @param $d
+     * @throws \Exception
+     */
+    public function addStructX($voffset, $x, $d)
+    {
+        if ($x != $d) {
+            $this->nested($x);
+            $this->slot($voffset);
+        }
+    }
+
+    /**
+     * @param $voffset
+     * @param $x
+     * @param $d
+     * @throws \Exception
+     */
+    public function addStruct($voffset, $x, $d)
+    {
+        if ($x != $d) {
+            $this->nested($x);
+            $this->slot($voffset);
+        }
+    }
+
+    /**
+     * @param $voffset
+     */
+    public function slot($voffset)
+    {
+        $this->vtable[$voffset] = $this->offset();
+    }
+
+    /**
+     * @return int
+     * @throws \Exception
+     */
+    public function endObject()
+    {
+        if ($this->vtable == null || !$this->nested) {
+            throw new \Exception("FlatBuffers: endObject called without startObject");
+        }
+
+        $this->addInt(0);
+        $vtableloc = $this->offset();
+
+        $i = $this->vtable_in_use -1;
+        // Trim trailing zeroes.
+        for (; $i >= 0 && $this->vtable[$i] == 0; $i--) {}
+        $trimmed_size = $i + 1;
+        for (; $i >= 0; $i--) {
+            $off = ($this->vtable[$i] != 0) ? $vtableloc - $this->vtable[$i] : 0;
+            $this->addShort($off);
+        }
+
+        $standard_fields = 2; // the fields below
+        $this->addShort($vtableloc - $this->object_start);
+        $this->addShort(($trimmed_size + $standard_fields) * Constants::SIZEOF_SHORT);
+
+        // search for an existing vtable that matches the current one.
+        $existing_vtable = 0;
+
+        for ($i = 0; $i < $this->num_vtables; $i++) {
+            $vt1 = $this->bb->capacity() - $this->vtables[$i];
+            $vt2 = $this->space;
+
+            $len = $this->bb->getShort($vt1);
+
+            if ($len == $this->bb->getShort($vt2)) {
+                for ($j = Constants::SIZEOF_SHORT; $j < $len; $j += Constants::SIZEOF_SHORT) {
+                    if ($this->bb->getShort($vt1 + $j) != $this->bb->getShort($vt2 + $j)) {
+                        continue 2;
+                    }
+                }
+                $existing_vtable = $this->vtables[$i];
+                break;
+            }
+        }
+
+        if ($existing_vtable != 0) {
+            // Found a match:
+            // Remove the current vtable
+            $this->space = $this->bb->capacity() - $vtableloc;
+            $this->bb->putInt($this->space, $existing_vtable - $vtableloc);
+        } else {
+            // No Match:
+            // Add the location of the current vtable to the list of vtables
+            if ($this->num_vtables == count($this->vtables)) {
+                $vtables = $this->vtables;
+                $this->vtables = array();
+                // copy of
+                for ($i = 0; $i < count($vtables) * 2; $i++) {
+                    $this->vtables[$i] = ($i < count($vtables)) ? $vtables[$i] : 0;
+                }
+            }
+            $this->vtables[$this->num_vtables++] = $this->offset();
+            $this->bb->putInt($this->bb->capacity() - $vtableloc, $this->offset() - $vtableloc);
+        }
+
+        $this->nested = false;
+        $this->vtable = null;
+        return $vtableloc;
+    }
+
+    /**
+     * @param $table
+     * @param $field
+     * @throws \Exception
+     */
+    public function required($table, $field)
+    {
+        $table_start = $this->bb->capacity() - $table;
+        $vtable_start = $table_start - $this->bb->getInt($table_start);
+        $ok = $this->bb->getShort($vtable_start + $field) != 0;
+
+        if (!$ok) {
+            throw new \Exception("FlatBuffers: field "  . $field  .  " must be set");
+        }
+    }
+    /// @endcond
+
+    /**
+     * Finalize a buffer, pointing to the given `$root_table`.
+     * @param $root_table An offest to be added to the buffer.
+     * @param $file_identifier A FlatBuffer file identifier to be added to the
+     *     buffer before `$root_table`. This defaults to `null`.
+     * @throws InvalidArgumentException Thrown if an invalid `$identifier` is
+     *     given, where its length is not equal to
+     *    `Constants::FILE_IDENTIFIER_LENGTH`.
+     */
+    public function finish($root_table, $identifier = null)
+    {
+        if ($identifier == null) {
+            $this->prep($this->minalign, Constants::SIZEOF_INT);
+            $this->addOffset($root_table);
+            $this->bb->setPosition($this->space);
+        } else {
+            $this->prep($this->minalign, Constants::SIZEOF_INT + Constants::FILE_IDENTIFIER_LENGTH);
+            if (strlen($identifier) != Constants::FILE_IDENTIFIER_LENGTH) {
+                throw new \InvalidArgumentException(
+                    sprintf("FlatBuffers: file identifier must be length %d",
+                        Constants::FILE_IDENTIFIER_LENGTH));
+            }
+
+            for ($i = Constants::FILE_IDENTIFIER_LENGTH - 1; $i >= 0;
+                  $i--) {
+                $this->addByte(ord($identifier[$i]));
+            }
+            $this->finish($root_table);
+        }
+    }
+
+    /**
+     * In order to save space, fields that are set to their default value don't
+     * get serialized into the buffer.
+     * @param bool $forceDefaults When set to `true`, always serializes default
+     *     values.
+     */
+    public function forceDefaults($forceDefaults)
+    {
+        $this->force_defaults = $forceDefaults;
+    }
+
+    /**
+     * Get the ByteBuffer representing the FlatBuffer.
+     * @return ByteBuffer The ByteBuffer containing the FlatBuffer data.
+     */
+    public function dataBuffer()
+    {
+        return $this->bb;
+    }
+
+    /// @cond FLATBUFFERS_INTERNAL
+    /**
+     * @return int
+     */
+    public function dataStart()
+    {
+        return $this->space;
+    }
+    /// @endcond
+
+    /**
+     * Utility function to copy and return the FlatBuffer data from the
+     * underlying ByteBuffer.
+     * @return string A string (representing a byte[]) that contains a copy
+     * of the FlatBuffer data.
+     */
+    public function sizedByteArray()
+    {
+        $start = $this->space;
+        $length = $this->bb->capacity() - $this->space;
+
+        $result = str_repeat("\0", $length);
+        $this->bb->setPosition($start);
+        $this->bb->getX($result);
+
+        return $result;
+    }
+}
+
+/// @}
diff --git a/third_party/flatbuffers/php/Struct.php b/third_party/flatbuffers/php/Struct.php
new file mode 100644
index 0000000..cd7652e
--- /dev/null
+++ b/third_party/flatbuffers/php/Struct.php
@@ -0,0 +1,41 @@
+<?php
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * 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.
+ */
+
+namespace Google\FlatBuffers;
+
+abstract class Struct
+{
+    /**
+     * @var int $bb_pos
+     */
+    protected $bb_pos;
+
+    /**
+     * @var ByteBuffer $bb
+     */
+    protected $bb;
+
+    public function setByteBufferPos($pos)
+    {
+        $this->bb_pos = $pos;
+    }
+
+    public function setByteBuffer($bb)
+    {
+        $this->bb = $bb;
+    }
+}
diff --git a/third_party/flatbuffers/php/Table.php b/third_party/flatbuffers/php/Table.php
new file mode 100644
index 0000000..bf6fe21
--- /dev/null
+++ b/third_party/flatbuffers/php/Table.php
@@ -0,0 +1,145 @@
+<?php
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * 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.
+ */
+
+namespace Google\FlatBuffers;
+
+abstract class Table
+{
+    /**
+     * @var int $bb_pos
+     */
+    protected $bb_pos;
+    /**
+     * @var ByteBuffer $bb
+     */
+    protected $bb;
+
+    public function __construct()
+    {
+    }
+
+    public function setByteBufferPos($pos)
+    {
+        $this->bb_pos = $pos;
+    }
+
+    public function setByteBuffer($bb)
+    {
+        $this->bb = $bb;
+    }
+
+    /**
+     * returns actual vtable offset
+     *
+     * @param $vtable_offset
+     * @return int offset > 0 means exist value. 0 means not exist
+     */
+    protected function __offset($vtable_offset)
+    {
+        $vtable = $this->bb_pos - $this->bb->getInt($this->bb_pos);
+        return $vtable_offset < $this->bb->getShort($vtable) ? $this->bb->getShort($vtable + $vtable_offset) : 0;
+    }
+
+    /**
+     * @param $offset
+     * @return mixed
+     */
+    protected function __indirect($offset)
+    {
+        return $offset + $this->bb->getInt($offset);
+    }
+
+    /**
+     * fetch utf8 encoded string.
+     *
+     * @param $offset
+     * @return string
+     */
+    protected function __string($offset)
+    {
+        $offset += $this->bb->getInt($offset);
+        $len = $this->bb->getInt($offset);
+        $startPos = $offset + Constants::SIZEOF_INT;
+        return substr($this->bb->_buffer, $startPos, $len);
+    }
+
+    /**
+     * @param $offset
+     * @return int
+     */
+    protected function __vector_len($offset)
+    {
+        $offset += $this->bb_pos;
+        $offset += $this->bb->getInt($offset);
+        return $this->bb->getInt($offset);
+    }
+
+    /**
+     * @param $offset
+     * @return int
+     */
+    protected function __vector($offset)
+    {
+        $offset += $this->bb_pos;
+        // data starts after the length
+        return $offset + $this->bb->getInt($offset) + Constants::SIZEOF_INT;
+    }
+
+    protected function __vector_as_bytes($vector_offset, $elem_size=1)
+    {
+        $o = $this->__offset($vector_offset);
+        if ($o == 0) {
+            return null;
+        }
+
+        return substr($this->bb->_buffer, $this->__vector($o), $this->__vector_len($o) * $elem_size);
+    }
+
+    /**
+     * @param Table $table
+     * @param int $offset
+     * @return Table
+     */
+    protected function __union($table, $offset)
+    {
+        $offset += $this->bb_pos;
+        $table->setByteBufferPos($offset + $this->bb->getInt($offset));
+        $table->setByteBuffer($this->bb);
+        return $table;
+    }
+
+    /**
+     * @param ByteBuffer $bb
+     * @param string $ident
+     * @return bool
+     * @throws \ArgumentException
+     */
+    protected static function __has_identifier($bb, $ident)
+    {
+        if (strlen($ident) != Constants::FILE_IDENTIFIER_LENGTH) {
+            throw new \ArgumentException("FlatBuffers: file identifier must be length "  . Constants::FILE_IDENTIFIER_LENGTH);
+        }
+
+        for ($i = 0; $i < 4; $i++) {
+            if ($ident[$i] != $bb->get($bb->getPosition() + Constants::SIZEOF_INT + $i)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+}
diff --git a/third_party/flatbuffers/pom.xml b/third_party/flatbuffers/pom.xml
new file mode 100644
index 0000000..cb410cc
--- /dev/null
+++ b/third_party/flatbuffers/pom.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.google.flatbuffers</groupId>
+  <artifactId>flatbuffers-java</artifactId>
+  <version>1.11.1</version>
+  <packaging>bundle</packaging>
+  <name>FlatBuffers Java API</name>
+  <description>
+    Memory Efficient Serialization Library
+  </description>
+  <developers>
+    <developer>
+      <name>Wouter van Oortmerssen</name>
+    </developer>
+  </developers>
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+  <url>https://github.com/google/flatbuffers</url>
+  <licenses>
+    <license>
+      <name>Apache License V2.0</name>
+      <url>https://raw.githubusercontent.com/google/flatbuffers/master/LICENSE.txt</url>
+      <distribution>repo</distribution>
+    </license>
+  </licenses>
+  <scm>
+    <url>https://github.com/google/flatbuffers</url>
+    <connection>
+      scm:git:https://github.com/google/flatbuffers.git
+    </connection>
+    <tag>HEAD</tag>
+  </scm>
+  <dependencies>
+  </dependencies>
+  <distributionManagement>
+    <snapshotRepository>
+      <id>ossrh</id>
+      <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+    </snapshotRepository>
+  </distributionManagement>
+  <build>
+    <sourceDirectory>java</sourceDirectory>
+    <plugins>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <source>1.8</source>
+          <target>1.8</target>
+        </configuration>
+        <version>3.2</version>
+      </plugin>
+      <plugin>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <includes>
+            <include>**/*Test.java</include>
+          </includes>
+        </configuration>
+        <version>2.18.1</version>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-source-plugin</artifactId>
+        <version>2.3</version>
+        <executions>
+          <execution>
+            <id>attach-sources</id>
+            <goals>
+              <goal>jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-javadoc-plugin</artifactId>
+        <version>2.9.1</version>
+        <configuration>
+          <additionalparam>-Xdoclint:none</additionalparam>
+          <additionalOptions>-Xdoclint:none</additionalOptions>
+        </configuration>
+        <executions>
+          <execution>
+            <id>attach-javadocs</id>
+            <goals>
+              <goal>jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <version>3.0.1</version>
+        <extensions>true</extensions>
+      </plugin>
+      <plugin>
+        <groupId>org.sonatype.plugins</groupId>
+        <artifactId>nexus-staging-maven-plugin</artifactId>
+        <version>1.6.7</version>
+        <extensions>true</extensions>
+        <configuration>
+          <serverId>ossrh</serverId>
+          <nexusUrl>https://oss.sonatype.org/</nexusUrl>
+          <autoReleaseAfterClose>true</autoReleaseAfterClose>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-gpg-plugin</artifactId>
+        <version>1.5</version>
+        <executions>
+          <execution>
+            <id>sign-artifacts</id>
+            <phase>verify</phase>
+            <goals>
+              <goal>sign</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-release-plugin</artifactId>
+        <version>2.5.3</version>
+        <configuration>
+          <autoVersionSubmodules>true</autoVersionSubmodules>
+          <useReleaseProfile>false</useReleaseProfile>
+          <releaseProfiles>release</releaseProfiles>
+          <goals>deploy</goals>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
+
diff --git a/third_party/flatbuffers/python/.gitignore b/third_party/flatbuffers/python/.gitignore
new file mode 100644
index 0000000..a771946
--- /dev/null
+++ b/third_party/flatbuffers/python/.gitignore
@@ -0,0 +1,2 @@
+/dist/
+/*.egg-info/
diff --git a/third_party/flatbuffers/python/__init__.py b/third_party/flatbuffers/python/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/flatbuffers/python/__init__.py
diff --git a/third_party/flatbuffers/python/flatbuffers/__init__.py b/third_party/flatbuffers/python/flatbuffers/__init__.py
new file mode 100644
index 0000000..d14872a
--- /dev/null
+++ b/third_party/flatbuffers/python/flatbuffers/__init__.py
@@ -0,0 +1,17 @@
+# 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.
+
+from .builder import Builder
+from .table import Table
+from .compat import range_func as compat_range
diff --git a/third_party/flatbuffers/python/flatbuffers/builder.py b/third_party/flatbuffers/python/flatbuffers/builder.py
new file mode 100644
index 0000000..d04ee85
--- /dev/null
+++ b/third_party/flatbuffers/python/flatbuffers/builder.py
@@ -0,0 +1,755 @@
+# 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.
+
+from . import number_types as N
+from .number_types import (UOffsetTFlags, SOffsetTFlags, VOffsetTFlags)
+
+from . import encode
+from . import packer
+
+from . import compat
+from .compat import range_func
+from .compat import memoryview_type
+from .compat import import_numpy, NumpyRequiredForThisFeature
+
+np = import_numpy()
+## @file
+## @addtogroup flatbuffers_python_api
+## @{
+
+## @cond FLATBUFFERS_INTERNAL
+class OffsetArithmeticError(RuntimeError):
+    """
+    Error caused by an Offset arithmetic error. Probably caused by bad
+    writing of fields. This is considered an unreachable situation in
+    normal circumstances.
+    """
+    pass
+
+
+class IsNotNestedError(RuntimeError):
+    """
+    Error caused by using a Builder to write Object data when not inside
+    an Object.
+    """
+    pass
+
+
+class IsNestedError(RuntimeError):
+    """
+    Error caused by using a Builder to begin an Object when an Object is
+    already being built.
+    """
+    pass
+
+
+class StructIsNotInlineError(RuntimeError):
+    """
+    Error caused by using a Builder to write a Struct at a location that
+    is not the current Offset.
+    """
+    pass
+
+
+class BuilderSizeError(RuntimeError):
+    """
+    Error caused by causing a Builder to exceed the hardcoded limit of 2
+    gigabytes.
+    """
+    pass
+
+class BuilderNotFinishedError(RuntimeError):
+    """
+    Error caused by not calling `Finish` before calling `Output`.
+    """
+    pass
+
+
+# VtableMetadataFields is the count of metadata fields in each vtable.
+VtableMetadataFields = 2
+## @endcond
+
+class Builder(object):
+    """ A Builder is used to construct one or more FlatBuffers.
+
+    Typically, Builder objects will be used from code generated by the `flatc`
+    compiler.
+
+    A Builder constructs byte buffers in a last-first manner for simplicity and
+    performance during reading.
+
+    Internally, a Builder is a state machine for creating FlatBuffer objects.
+
+    It holds the following internal state:
+        - Bytes: an array of bytes.
+        - current_vtable: a list of integers.
+        - vtables: a hash of vtable entries.
+
+    Attributes:
+      Bytes: The internal `bytearray` for the Builder.
+      finished: A boolean determining if the Builder has been finalized.
+    """
+
+    ## @cond FLATBUFFERS_INTENRAL
+    __slots__ = ("Bytes", "current_vtable", "head", "minalign", "objectEnd",
+                 "vtables", "nested", "finished")
+
+    """Maximum buffer size constant, in bytes.
+
+    Builder will never allow it's buffer grow over this size.
+    Currently equals 2Gb.
+    """
+    MAX_BUFFER_SIZE = 2**31
+    ## @endcond
+
+    def __init__(self, initialSize):
+        """Initializes a Builder of size `initial_size`.
+
+        The internal buffer is grown as needed.
+        """
+
+        if not (0 <= initialSize <= Builder.MAX_BUFFER_SIZE):
+            msg = "flatbuffers: Cannot create Builder larger than 2 gigabytes."
+            raise BuilderSizeError(msg)
+
+        self.Bytes = bytearray(initialSize)
+        ## @cond FLATBUFFERS_INTERNAL
+        self.current_vtable = None
+        self.head = UOffsetTFlags.py_type(initialSize)
+        self.minalign = 1
+        self.objectEnd = None
+        self.vtables = {}
+        self.nested = False
+        ## @endcond
+        self.finished = False
+
+
+    def Output(self):
+        """Return the portion of the buffer that has been used for writing data.
+
+        This is the typical way to access the FlatBuffer data inside the
+        builder. If you try to access `Builder.Bytes` directly, you would need
+        to manually index it with `Head()`, since the buffer is constructed
+        backwards.
+
+        It raises BuilderNotFinishedError if the buffer has not been finished
+        with `Finish`.
+        """
+
+        if not self.finished:
+            raise BuilderNotFinishedError()
+
+        return self.Bytes[self.Head():]
+
+    ## @cond FLATBUFFERS_INTERNAL
+    def StartObject(self, numfields):
+        """StartObject initializes bookkeeping for writing a new object."""
+
+        self.assertNotNested()
+
+        # use 32-bit offsets so that arithmetic doesn't overflow.
+        self.current_vtable = [0 for _ in range_func(numfields)]
+        self.objectEnd = self.Offset()
+        self.nested = True
+
+    def WriteVtable(self):
+        """
+        WriteVtable serializes the vtable for the current object, if needed.
+
+        Before writing out the vtable, this checks pre-existing vtables for
+        equality to this one. If an equal vtable is found, point the object to
+        the existing vtable and return.
+
+        Because vtable values are sensitive to alignment of object data, not
+        all logically-equal vtables will be deduplicated.
+
+        A vtable has the following format:
+          <VOffsetT: size of the vtable in bytes, including this value>
+          <VOffsetT: size of the object in bytes, including the vtable offset>
+          <VOffsetT: offset for a field> * N, where N is the number of fields
+                     in the schema for this type. Includes deprecated fields.
+        Thus, a vtable is made of 2 + N elements, each VOffsetT bytes wide.
+
+        An object has the following format:
+          <SOffsetT: offset to this object's vtable (may be negative)>
+          <byte: data>+
+        """
+
+        # Prepend a zero scalar to the object. Later in this function we'll
+        # write an offset here that points to the object's vtable:
+        self.PrependSOffsetTRelative(0)
+
+        objectOffset = self.Offset()
+
+        vtKey = []
+        trim = True
+        for elem in reversed(self.current_vtable):
+            if elem == 0:
+                if trim:
+                    continue
+            else:
+                elem = objectOffset - elem
+                trim = False
+
+            vtKey.append(elem)
+
+        vtKey = tuple(vtKey)
+        vt2Offset = self.vtables.get(vtKey)
+        if vt2Offset is None:
+            # Did not find a vtable, so write this one to the buffer.
+
+            # Write out the current vtable in reverse , because
+            # serialization occurs in last-first order:
+            i = len(self.current_vtable) - 1
+            trailing = 0
+            trim = True
+            while i >= 0:
+                off = 0
+                elem = self.current_vtable[i]
+                i -= 1
+
+                if elem == 0:
+                    if trim:
+                        trailing += 1
+                        continue
+                else:
+                    # Forward reference to field;
+                    # use 32bit number to ensure no overflow:
+                    off = objectOffset - elem
+                    trim = False
+
+                self.PrependVOffsetT(off)
+
+            # The two metadata fields are written last.
+
+            # First, store the object bytesize:
+            objectSize = UOffsetTFlags.py_type(objectOffset - self.objectEnd)
+            self.PrependVOffsetT(VOffsetTFlags.py_type(objectSize))
+
+            # Second, store the vtable bytesize:
+            vBytes = len(self.current_vtable) - trailing + VtableMetadataFields
+            vBytes *= N.VOffsetTFlags.bytewidth
+            self.PrependVOffsetT(VOffsetTFlags.py_type(vBytes))
+
+            # Next, write the offset to the new vtable in the
+            # already-allocated SOffsetT at the beginning of this object:
+            objectStart = SOffsetTFlags.py_type(len(self.Bytes) - objectOffset)
+            encode.Write(packer.soffset, self.Bytes, objectStart,
+                         SOffsetTFlags.py_type(self.Offset() - objectOffset))
+
+            # Finally, store this vtable in memory for future
+            # deduplication:
+            self.vtables[vtKey] = self.Offset()
+        else:
+            # Found a duplicate vtable.
+            objectStart = SOffsetTFlags.py_type(len(self.Bytes) - objectOffset)
+            self.head = UOffsetTFlags.py_type(objectStart)
+
+            # Write the offset to the found vtable in the
+            # already-allocated SOffsetT at the beginning of this object:
+            encode.Write(packer.soffset, self.Bytes, self.Head(),
+                         SOffsetTFlags.py_type(vt2Offset - objectOffset))
+
+        self.current_vtable = None
+        return objectOffset
+
+    def EndObject(self):
+        """EndObject writes data necessary to finish object construction."""
+        self.assertNested()
+        self.nested = False
+        return self.WriteVtable()
+
+    def growByteBuffer(self):
+        """Doubles the size of the byteslice, and copies the old data towards
+           the end of the new buffer (since we build the buffer backwards)."""
+        if len(self.Bytes) == Builder.MAX_BUFFER_SIZE:
+            msg = "flatbuffers: cannot grow buffer beyond 2 gigabytes"
+            raise BuilderSizeError(msg)
+
+        newSize = min(len(self.Bytes) * 2, Builder.MAX_BUFFER_SIZE)
+        if newSize == 0:
+            newSize = 1
+        bytes2 = bytearray(newSize)
+        bytes2[newSize-len(self.Bytes):] = self.Bytes
+        self.Bytes = bytes2
+    ## @endcond
+
+    def Head(self):
+        """Get the start of useful data in the underlying byte buffer.
+
+        Note: unlike other functions, this value is interpreted as from the
+        left.
+        """
+        ## @cond FLATBUFFERS_INTERNAL
+        return self.head
+        ## @endcond
+
+    ## @cond FLATBUFFERS_INTERNAL
+    def Offset(self):
+        """Offset relative to the end of the buffer."""
+        return UOffsetTFlags.py_type(len(self.Bytes) - self.Head())
+
+    def Pad(self, n):
+        """Pad places zeros at the current offset."""
+        for i in range_func(n):
+            self.Place(0, N.Uint8Flags)
+
+    def Prep(self, size, additionalBytes):
+        """
+        Prep prepares to write an element of `size` after `additional_bytes`
+        have been written, e.g. if you write a string, you need to align
+        such the int length field is aligned to SizeInt32, and the string
+        data follows it directly.
+        If all you need to do is align, `additionalBytes` will be 0.
+        """
+
+        # Track the biggest thing we've ever aligned to.
+        if size > self.minalign:
+            self.minalign = size
+
+        # Find the amount of alignment needed such that `size` is properly
+        # aligned after `additionalBytes`:
+        alignSize = (~(len(self.Bytes) - self.Head() + additionalBytes)) + 1
+        alignSize &= (size - 1)
+
+        # Reallocate the buffer if needed:
+        while self.Head() < alignSize+size+additionalBytes:
+            oldBufSize = len(self.Bytes)
+            self.growByteBuffer()
+            updated_head = self.head + len(self.Bytes) - oldBufSize
+            self.head = UOffsetTFlags.py_type(updated_head)
+        self.Pad(alignSize)
+
+    def PrependSOffsetTRelative(self, off):
+        """
+        PrependSOffsetTRelative prepends an SOffsetT, relative to where it
+        will be written.
+        """
+
+        # Ensure alignment is already done:
+        self.Prep(N.SOffsetTFlags.bytewidth, 0)
+        if not (off <= self.Offset()):
+            msg = "flatbuffers: Offset arithmetic error."
+            raise OffsetArithmeticError(msg)
+        off2 = self.Offset() - off + N.SOffsetTFlags.bytewidth
+        self.PlaceSOffsetT(off2)
+    ## @endcond
+
+    def PrependUOffsetTRelative(self, off):
+        """Prepends an unsigned offset into vector data, relative to where it
+        will be written.
+        """
+
+        # Ensure alignment is already done:
+        self.Prep(N.UOffsetTFlags.bytewidth, 0)
+        if not (off <= self.Offset()):
+            msg = "flatbuffers: Offset arithmetic error."
+            raise OffsetArithmeticError(msg)
+        off2 = self.Offset() - off + N.UOffsetTFlags.bytewidth
+        self.PlaceUOffsetT(off2)
+
+    ## @cond FLATBUFFERS_INTERNAL
+    def StartVector(self, elemSize, numElems, alignment):
+        """
+        StartVector initializes bookkeeping for writing a new vector.
+
+        A vector has the following format:
+          - <UOffsetT: number of elements in this vector>
+          - <T: data>+, where T is the type of elements of this vector.
+        """
+
+        self.assertNotNested()
+        self.nested = True
+        self.Prep(N.Uint32Flags.bytewidth, elemSize*numElems)
+        self.Prep(alignment, elemSize*numElems)  # In case alignment > int.
+        return self.Offset()
+    ## @endcond
+
+    def EndVector(self, vectorNumElems):
+        """EndVector writes data necessary to finish vector construction."""
+
+        self.assertNested()
+        ## @cond FLATBUFFERS_INTERNAL
+        self.nested = False
+        ## @endcond
+        # we already made space for this, so write without PrependUint32
+        self.PlaceUOffsetT(vectorNumElems)
+        return self.Offset()
+
+    def CreateString(self, s, encoding='utf-8', errors='strict'):
+        """CreateString writes a null-terminated byte string as a vector."""
+
+        self.assertNotNested()
+        ## @cond FLATBUFFERS_INTERNAL
+        self.nested = True
+        ## @endcond
+
+        if isinstance(s, compat.string_types):
+            x = s.encode(encoding, errors)
+        elif isinstance(s, compat.binary_types):
+            x = s
+        else:
+            raise TypeError("non-string passed to CreateString")
+
+        self.Prep(N.UOffsetTFlags.bytewidth, (len(x)+1)*N.Uint8Flags.bytewidth)
+        self.Place(0, N.Uint8Flags)
+
+        l = UOffsetTFlags.py_type(len(s))
+        ## @cond FLATBUFFERS_INTERNAL
+        self.head = UOffsetTFlags.py_type(self.Head() - l)
+        ## @endcond
+        self.Bytes[self.Head():self.Head()+l] = x
+
+        return self.EndVector(len(x))
+
+    def CreateByteVector(self, x):
+        """CreateString writes a byte vector."""
+
+        self.assertNotNested()
+        ## @cond FLATBUFFERS_INTERNAL
+        self.nested = True
+        ## @endcond
+
+        if not isinstance(x, compat.binary_types):
+            raise TypeError("non-byte vector passed to CreateByteVector")
+
+        self.Prep(N.UOffsetTFlags.bytewidth, len(x)*N.Uint8Flags.bytewidth)
+
+        l = UOffsetTFlags.py_type(len(x))
+        ## @cond FLATBUFFERS_INTERNAL
+        self.head = UOffsetTFlags.py_type(self.Head() - l)
+        ## @endcond
+        self.Bytes[self.Head():self.Head()+l] = x
+
+        return self.EndVector(len(x))
+
+    def CreateNumpyVector(self, x):
+        """CreateNumpyVector writes a numpy array into the buffer."""
+
+        if np is None:
+            # Numpy is required for this feature
+            raise NumpyRequiredForThisFeature("Numpy was not found.")
+
+        if not isinstance(x, np.ndarray):
+            raise TypeError("non-numpy-ndarray passed to CreateNumpyVector")
+
+        if x.dtype.kind not in ['b', 'i', 'u', 'f']:
+            raise TypeError("numpy-ndarray holds elements of unsupported datatype")
+
+        if x.ndim > 1:
+            raise TypeError("multidimensional-ndarray passed to CreateNumpyVector")
+
+        self.StartVector(x.itemsize, x.size, x.dtype.alignment)
+
+        # Ensure little endian byte ordering
+        if x.dtype.str[0] == "<":
+            x_lend = x
+        else:
+            x_lend = x.byteswap(inplace=False)
+
+        # Calculate total length
+        l = UOffsetTFlags.py_type(x_lend.itemsize * x_lend.size)
+        ## @cond FLATBUFFERS_INTERNAL
+        self.head = UOffsetTFlags.py_type(self.Head() - l)
+        ## @endcond
+
+        # tobytes ensures c_contiguous ordering
+        self.Bytes[self.Head():self.Head()+l] = x_lend.tobytes(order='C')
+        
+        return self.EndVector(x.size)
+
+    ## @cond FLATBUFFERS_INTERNAL
+    def assertNested(self):
+        """
+        Check that we are in the process of building an object.
+        """
+
+        if not self.nested:
+            raise IsNotNestedError()
+
+    def assertNotNested(self):
+        """
+        Check that no other objects are being built while making this
+        object. If not, raise an exception.
+        """
+
+        if self.nested:
+            raise IsNestedError()
+
+    def assertStructIsInline(self, obj):
+        """
+        Structs are always stored inline, so need to be created right
+        where they are used. You'll get this error if you created it
+        elsewhere.
+        """
+
+        N.enforce_number(obj, N.UOffsetTFlags)
+        if obj != self.Offset():
+            msg = ("flatbuffers: Tried to write a Struct at an Offset that "
+                   "is different from the current Offset of the Builder.")
+            raise StructIsNotInlineError(msg)
+
+    def Slot(self, slotnum):
+        """
+        Slot sets the vtable key `voffset` to the current location in the
+        buffer.
+
+        """
+        self.assertNested()
+        self.current_vtable[slotnum] = self.Offset()
+    ## @endcond
+
+    def __Finish(self, rootTable, sizePrefix, file_identifier=None):
+        """Finish finalizes a buffer, pointing to the given `rootTable`."""
+        N.enforce_number(rootTable, N.UOffsetTFlags)
+
+        if file_identifier is not None:
+            self.Prep(N.UOffsetTFlags.bytewidth, N.Uint8Flags.bytewidth*4)
+            
+            # Convert bytes object file_identifier to an array of 4 8-bit integers,
+            # and use big-endian to enforce size compliance.
+            # https://docs.python.org/2/library/struct.html#format-characters
+            file_identifier = N.struct.unpack(">BBBB", file_identifier)
+            for i in range(encode.FILE_IDENTIFIER_LENGTH-1, -1, -1):
+                # Place the bytes of the file_identifer in reverse order:
+                self.Place(file_identifier[i], N.Uint8Flags)   
+                
+        self.PrependUOffsetTRelative(rootTable)
+        if sizePrefix:
+            size = len(self.Bytes) - self.Head()
+            N.enforce_number(size, N.Int32Flags)
+            self.PrependInt32(size)
+        self.finished = True
+        return self.Head()
+
+    def Finish(self, rootTable, file_identifier=None):
+        """Finish finalizes a buffer, pointing to the given `rootTable`."""
+        return self.__Finish(rootTable, False, file_identifier=file_identifier)
+
+    def FinishSizePrefixed(self, rootTable, file_identifier=None):
+        """
+        Finish finalizes a buffer, pointing to the given `rootTable`,
+        with the size prefixed.
+        """
+        return self.__Finish(rootTable, True, file_identifier=file_identifier)
+
+    ## @cond FLATBUFFERS_INTERNAL
+    def Prepend(self, flags, off):
+        self.Prep(flags.bytewidth, 0)
+        self.Place(off, flags)
+
+    def PrependSlot(self, flags, o, x, d):
+        N.enforce_number(x, flags)
+        N.enforce_number(d, flags)
+        if x != d:
+            self.Prepend(flags, x)
+            self.Slot(o)
+
+    def PrependBoolSlot(self, *args): self.PrependSlot(N.BoolFlags, *args)
+
+    def PrependByteSlot(self, *args): self.PrependSlot(N.Uint8Flags, *args)
+
+    def PrependUint8Slot(self, *args): self.PrependSlot(N.Uint8Flags, *args)
+
+    def PrependUint16Slot(self, *args): self.PrependSlot(N.Uint16Flags, *args)
+
+    def PrependUint32Slot(self, *args): self.PrependSlot(N.Uint32Flags, *args)
+
+    def PrependUint64Slot(self, *args): self.PrependSlot(N.Uint64Flags, *args)
+
+    def PrependInt8Slot(self, *args): self.PrependSlot(N.Int8Flags, *args)
+
+    def PrependInt16Slot(self, *args): self.PrependSlot(N.Int16Flags, *args)
+
+    def PrependInt32Slot(self, *args): self.PrependSlot(N.Int32Flags, *args)
+
+    def PrependInt64Slot(self, *args): self.PrependSlot(N.Int64Flags, *args)
+
+    def PrependFloat32Slot(self, *args): self.PrependSlot(N.Float32Flags,
+                                                          *args)
+
+    def PrependFloat64Slot(self, *args): self.PrependSlot(N.Float64Flags,
+                                                          *args)
+
+    def PrependUOffsetTRelativeSlot(self, o, x, d):
+        """
+        PrependUOffsetTRelativeSlot prepends an UOffsetT onto the object at
+        vtable slot `o`. If value `x` equals default `d`, then the slot will
+        be set to zero and no other data will be written.
+        """
+
+        if x != d:
+            self.PrependUOffsetTRelative(x)
+            self.Slot(o)
+
+    def PrependStructSlot(self, v, x, d):
+        """
+        PrependStructSlot prepends a struct onto the object at vtable slot `o`.
+        Structs are stored inline, so nothing additional is being added.
+        In generated code, `d` is always 0.
+        """
+
+        N.enforce_number(d, N.UOffsetTFlags)
+        if x != d:
+            self.assertStructIsInline(x)
+            self.Slot(v)
+
+    ## @endcond
+
+    def PrependBool(self, x):
+        """Prepend a `bool` to the Builder buffer.
+
+        Note: aligns and checks for space.
+        """
+        self.Prepend(N.BoolFlags, x)
+
+    def PrependByte(self, x):
+        """Prepend a `byte` to the Builder buffer.
+
+        Note: aligns and checks for space.
+        """
+        self.Prepend(N.Uint8Flags, x)
+
+    def PrependUint8(self, x):
+        """Prepend an `uint8` to the Builder buffer.
+
+        Note: aligns and checks for space.
+        """
+        self.Prepend(N.Uint8Flags, x)
+
+    def PrependUint16(self, x):
+        """Prepend an `uint16` to the Builder buffer.
+
+        Note: aligns and checks for space.
+        """
+        self.Prepend(N.Uint16Flags, x)
+
+    def PrependUint32(self, x):
+        """Prepend an `uint32` to the Builder buffer.
+
+        Note: aligns and checks for space.
+        """
+        self.Prepend(N.Uint32Flags, x)
+
+    def PrependUint64(self, x):
+        """Prepend an `uint64` to the Builder buffer.
+
+        Note: aligns and checks for space.
+        """
+        self.Prepend(N.Uint64Flags, x)
+
+    def PrependInt8(self, x):
+        """Prepend an `int8` to the Builder buffer.
+
+        Note: aligns and checks for space.
+        """
+        self.Prepend(N.Int8Flags, x)
+
+    def PrependInt16(self, x):
+        """Prepend an `int16` to the Builder buffer.
+
+        Note: aligns and checks for space.
+        """
+        self.Prepend(N.Int16Flags, x)
+
+    def PrependInt32(self, x):
+        """Prepend an `int32` to the Builder buffer.
+
+        Note: aligns and checks for space.
+        """
+        self.Prepend(N.Int32Flags, x)
+
+    def PrependInt64(self, x):
+        """Prepend an `int64` to the Builder buffer.
+
+        Note: aligns and checks for space.
+        """
+        self.Prepend(N.Int64Flags, x)
+
+    def PrependFloat32(self, x):
+        """Prepend a `float32` to the Builder buffer.
+
+        Note: aligns and checks for space.
+        """
+        self.Prepend(N.Float32Flags, x)
+
+    def PrependFloat64(self, x):
+        """Prepend a `float64` to the Builder buffer.
+
+        Note: aligns and checks for space.
+        """
+        self.Prepend(N.Float64Flags, x)
+
+##############################################################
+
+    ## @cond FLATBUFFERS_INTERNAL
+    def PrependVOffsetT(self, x): self.Prepend(N.VOffsetTFlags, x)
+
+    def Place(self, x, flags):
+        """
+        Place prepends a value specified by `flags` to the Builder,
+        without checking for available space.
+        """
+
+        N.enforce_number(x, flags)
+        self.head = self.head - flags.bytewidth
+        encode.Write(flags.packer_type, self.Bytes, self.Head(), x)
+
+    def PlaceVOffsetT(self, x):
+        """PlaceVOffsetT prepends a VOffsetT to the Builder, without checking
+        for space.
+        """
+        N.enforce_number(x, N.VOffsetTFlags)
+        self.head = self.head - N.VOffsetTFlags.bytewidth
+        encode.Write(packer.voffset, self.Bytes, self.Head(), x)
+
+    def PlaceSOffsetT(self, x):
+        """PlaceSOffsetT prepends a SOffsetT to the Builder, without checking
+        for space.
+        """
+        N.enforce_number(x, N.SOffsetTFlags)
+        self.head = self.head - N.SOffsetTFlags.bytewidth
+        encode.Write(packer.soffset, self.Bytes, self.Head(), x)
+
+    def PlaceUOffsetT(self, x):
+        """PlaceUOffsetT prepends a UOffsetT to the Builder, without checking
+        for space.
+        """
+        N.enforce_number(x, N.UOffsetTFlags)
+        self.head = self.head - N.UOffsetTFlags.bytewidth
+        encode.Write(packer.uoffset, self.Bytes, self.Head(), x)
+    ## @endcond
+
+## @cond FLATBUFFERS_INTERNAL
+def vtableEqual(a, objectStart, b):
+    """vtableEqual compares an unwritten vtable to a written vtable."""
+
+    N.enforce_number(objectStart, N.UOffsetTFlags)
+
+    if len(a) * N.VOffsetTFlags.bytewidth != len(b):
+        return False
+
+    for i, elem in enumerate(a):
+        x = encode.Get(packer.voffset, b, i * N.VOffsetTFlags.bytewidth)
+
+        # Skip vtable entries that indicate a default value.
+        if x == 0 and elem == 0:
+            pass
+        else:
+            y = objectStart - elem
+            if x != y:
+                return False
+    return True
+## @endcond
+## @}
diff --git a/third_party/flatbuffers/python/flatbuffers/compat.py b/third_party/flatbuffers/python/flatbuffers/compat.py
new file mode 100644
index 0000000..2fc9cca
--- /dev/null
+++ b/third_party/flatbuffers/python/flatbuffers/compat.py
@@ -0,0 +1,81 @@
+# 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.
+
+""" A tiny version of `six` to help with backwards compability. Also includes
+ compatibility helpers for numpy. """
+
+import sys
+import imp
+
+PY2 = sys.version_info[0] == 2
+PY26 = sys.version_info[0:2] == (2, 6)
+PY27 = sys.version_info[0:2] == (2, 7)
+PY275 = sys.version_info[0:3] >= (2, 7, 5)
+PY3 = sys.version_info[0] == 3
+PY34 = sys.version_info[0:2] >= (3, 4)
+
+if PY3:
+    string_types = (str,)
+    binary_types = (bytes,bytearray)
+    range_func = range
+    memoryview_type = memoryview
+    struct_bool_decl = "?"
+else:
+    string_types = (unicode,)
+    if PY26 or PY27:
+        binary_types = (str,bytearray)
+    else:
+        binary_types = (str,)
+    range_func = xrange
+    if PY26 or (PY27 and not PY275):
+        memoryview_type = buffer
+        struct_bool_decl = "<b"
+    else:
+        memoryview_type = memoryview
+        struct_bool_decl = "?"
+
+# Helper functions to facilitate making numpy optional instead of required
+
+def import_numpy():
+    """
+    Returns the numpy module if it exists on the system,
+    otherwise returns None.
+    """
+    try:
+        imp.find_module('numpy')
+        numpy_exists = True
+    except ImportError:
+        numpy_exists = False
+
+    if numpy_exists:
+        # We do this outside of try/except block in case numpy exists
+        # but is not installed correctly. We do not want to catch an
+        # incorrect installation which would manifest as an
+        # ImportError.
+        import numpy as np
+    else:
+        np = None
+
+    return np
+
+
+class NumpyRequiredForThisFeature(RuntimeError):
+    """
+    Error raised when user tries to use a feature that
+    requires numpy without having numpy installed.
+    """
+    pass
+
+
+# NOTE: Future Jython support may require code here (look at `six`).
diff --git a/third_party/flatbuffers/python/flatbuffers/encode.py b/third_party/flatbuffers/python/flatbuffers/encode.py
new file mode 100644
index 0000000..c4f1a59
--- /dev/null
+++ b/third_party/flatbuffers/python/flatbuffers/encode.py
@@ -0,0 +1,42 @@
+# 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.
+
+from . import number_types as N
+from . import packer
+from .compat import memoryview_type
+from .compat import import_numpy, NumpyRequiredForThisFeature
+
+np = import_numpy()
+
+FILE_IDENTIFIER_LENGTH=4
+
+def Get(packer_type, buf, head):
+    """ Get decodes a value at buf[head] using `packer_type`. """
+    return packer_type.unpack_from(memoryview_type(buf), head)[0]
+
+
+def GetVectorAsNumpy(numpy_type, buf, count, offset):
+    """ GetVecAsNumpy decodes values starting at buf[head] as
+    `numpy_type`, where `numpy_type` is a numpy dtype. """
+    if np is not None:
+        # TODO: could set .flags.writeable = False to make users jump through
+        #       hoops before modifying...
+        return np.frombuffer(buf, dtype=numpy_type, count=count, offset=offset)
+    else:
+        raise NumpyRequiredForThisFeature('Numpy was not found.')
+
+
+def Write(packer_type, buf, head, n):
+    """ Write encodes `n` at buf[head] using `packer_type`. """
+    packer_type.pack_into(buf, head, n)
diff --git a/third_party/flatbuffers/python/flatbuffers/number_types.py b/third_party/flatbuffers/python/flatbuffers/number_types.py
new file mode 100644
index 0000000..47942ff
--- /dev/null
+++ b/third_party/flatbuffers/python/flatbuffers/number_types.py
@@ -0,0 +1,181 @@
+# 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.
+
+import collections
+import struct
+
+from . import packer
+from .compat import import_numpy, NumpyRequiredForThisFeature
+
+np = import_numpy()
+
+# For reference, see:
+# https://docs.python.org/2/library/ctypes.html#ctypes-fundamental-data-types-2
+
+# These classes could be collections.namedtuple instances, but those are new
+# in 2.6 and we want to work towards 2.5 compatability.
+
+class BoolFlags(object):
+    bytewidth = 1
+    min_val = False
+    max_val = True
+    py_type = bool
+    name = "bool"
+    packer_type = packer.boolean
+
+
+class Uint8Flags(object):
+    bytewidth = 1
+    min_val = 0
+    max_val = (2**8) - 1
+    py_type = int
+    name = "uint8"
+    packer_type = packer.uint8
+
+
+class Uint16Flags(object):
+    bytewidth = 2
+    min_val = 0
+    max_val = (2**16) - 1
+    py_type = int
+    name = "uint16"
+    packer_type = packer.uint16
+
+
+class Uint32Flags(object):
+    bytewidth = 4
+    min_val = 0
+    max_val = (2**32) - 1
+    py_type = int
+    name = "uint32"
+    packer_type = packer.uint32
+
+
+class Uint64Flags(object):
+    bytewidth = 8
+    min_val = 0
+    max_val = (2**64) - 1
+    py_type = int
+    name = "uint64"
+    packer_type = packer.uint64
+
+
+class Int8Flags(object):
+    bytewidth = 1
+    min_val = -(2**7)
+    max_val = (2**7) - 1
+    py_type = int
+    name = "int8"
+    packer_type = packer.int8
+
+
+class Int16Flags(object):
+    bytewidth = 2
+    min_val = -(2**15)
+    max_val = (2**15) - 1
+    py_type = int
+    name = "int16"
+    packer_type = packer.int16
+
+
+class Int32Flags(object):
+    bytewidth = 4
+    min_val = -(2**31)
+    max_val = (2**31) - 1
+    py_type = int
+    name = "int32"
+    packer_type = packer.int32
+
+
+class Int64Flags(object):
+    bytewidth = 8
+    min_val = -(2**63)
+    max_val = (2**63) - 1
+    py_type = int
+    name = "int64"
+    packer_type = packer.int64
+
+
+class Float32Flags(object):
+    bytewidth = 4
+    min_val = None
+    max_val = None
+    py_type = float
+    name = "float32"
+    packer_type = packer.float32
+
+
+class Float64Flags(object):
+    bytewidth = 8
+    min_val = None
+    max_val = None
+    py_type = float
+    name = "float64"
+    packer_type = packer.float64
+
+
+class SOffsetTFlags(Int32Flags):
+    pass
+
+
+class UOffsetTFlags(Uint32Flags):
+    pass
+
+
+class VOffsetTFlags(Uint16Flags):
+    pass
+
+
+def valid_number(n, flags):
+    if flags.min_val is None and flags.max_val is None:
+        return True
+    return flags.min_val <= n <= flags.max_val
+
+
+def enforce_number(n, flags):
+    if flags.min_val is None and flags.max_val is None:
+        return
+    if not flags.min_val <= n <= flags.max_val:
+        raise TypeError("bad number %s for type %s" % (str(n), flags.name))
+
+
+def float32_to_uint32(n):
+    packed = struct.pack("<1f", n)
+    (converted,) = struct.unpack("<1L", packed)
+    return converted
+
+
+def uint32_to_float32(n):
+    packed = struct.pack("<1L", n)
+    (unpacked,) = struct.unpack("<1f", packed)
+    return unpacked
+
+
+def float64_to_uint64(n):
+    packed = struct.pack("<1d", n)
+    (converted,) = struct.unpack("<1Q", packed)
+    return converted
+
+
+def uint64_to_float64(n):
+    packed = struct.pack("<1Q", n)
+    (unpacked,) = struct.unpack("<1d", packed)
+    return unpacked
+
+
+def to_numpy_type(number_type):
+    if np is not None:
+        return np.dtype(number_type.name).newbyteorder('<')
+    else:
+        raise NumpyRequiredForThisFeature('Numpy was not found.')
diff --git a/third_party/flatbuffers/python/flatbuffers/packer.py b/third_party/flatbuffers/python/flatbuffers/packer.py
new file mode 100644
index 0000000..20ee9f1
--- /dev/null
+++ b/third_party/flatbuffers/python/flatbuffers/packer.py
@@ -0,0 +1,42 @@
+# 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.
+
+"""
+Provide pre-compiled struct packers for encoding and decoding.
+
+See: https://docs.python.org/2/library/struct.html#format-characters
+"""
+
+import struct
+from . import compat
+
+
+boolean = struct.Struct(compat.struct_bool_decl)
+
+uint8 = struct.Struct("<B")
+uint16 = struct.Struct("<H")
+uint32 = struct.Struct("<I")
+uint64 = struct.Struct("<Q")
+
+int8 = struct.Struct("<b")
+int16 = struct.Struct("<h")
+int32 = struct.Struct("<i")
+int64 = struct.Struct("<q")
+
+float32 = struct.Struct("<f")
+float64 = struct.Struct("<d")
+
+uoffset = uint32
+soffset = int32
+voffset = uint16
diff --git a/third_party/flatbuffers/python/flatbuffers/table.py b/third_party/flatbuffers/python/flatbuffers/table.py
new file mode 100644
index 0000000..adc76ca
--- /dev/null
+++ b/third_party/flatbuffers/python/flatbuffers/table.py
@@ -0,0 +1,129 @@
+# 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.
+
+from . import encode
+from . import number_types as N
+
+
+class Table(object):
+    """Table wraps a byte slice and provides read access to its data.
+
+    The variable `Pos` indicates the root of the FlatBuffers object therein."""
+
+    __slots__ = ("Bytes", "Pos")
+
+    def __init__(self, buf, pos):
+        N.enforce_number(pos, N.UOffsetTFlags)
+
+        self.Bytes = buf
+        self.Pos = pos
+
+    def Offset(self, vtableOffset):
+        """Offset provides access into the Table's vtable.
+
+        Deprecated fields are ignored by checking the vtable's length."""
+
+        vtable = self.Pos - self.Get(N.SOffsetTFlags, self.Pos)
+        vtableEnd = self.Get(N.VOffsetTFlags, vtable)
+        if vtableOffset < vtableEnd:
+            return self.Get(N.VOffsetTFlags, vtable + vtableOffset)
+        return 0
+
+    def Indirect(self, off):
+        """Indirect retrieves the relative offset stored at `offset`."""
+        N.enforce_number(off, N.UOffsetTFlags)
+        return off + encode.Get(N.UOffsetTFlags.packer_type, self.Bytes, off)
+
+    def String(self, off):
+        """String gets a string from data stored inside the flatbuffer."""
+        N.enforce_number(off, N.UOffsetTFlags)
+        off += encode.Get(N.UOffsetTFlags.packer_type, self.Bytes, off)
+        start = off + N.UOffsetTFlags.bytewidth
+        length = encode.Get(N.UOffsetTFlags.packer_type, self.Bytes, off)
+        return bytes(self.Bytes[start:start+length])
+
+    def VectorLen(self, off):
+        """VectorLen retrieves the length of the vector whose offset is stored
+           at "off" in this object."""
+        N.enforce_number(off, N.UOffsetTFlags)
+
+        off += self.Pos
+        off += encode.Get(N.UOffsetTFlags.packer_type, self.Bytes, off)
+        ret = encode.Get(N.UOffsetTFlags.packer_type, self.Bytes, off)
+        return ret
+
+    def Vector(self, off):
+        """Vector retrieves the start of data of the vector whose offset is
+           stored at "off" in this object."""
+        N.enforce_number(off, N.UOffsetTFlags)
+
+        off += self.Pos
+        x = off + self.Get(N.UOffsetTFlags, off)
+        # data starts after metadata containing the vector length
+        x += N.UOffsetTFlags.bytewidth
+        return x
+
+    def Union(self, t2, off):
+        """Union initializes any Table-derived type to point to the union at
+           the given offset."""
+        assert type(t2) is Table
+        N.enforce_number(off, N.UOffsetTFlags)
+
+        off += self.Pos
+        t2.Pos = off + self.Get(N.UOffsetTFlags, off)
+        t2.Bytes = self.Bytes
+
+    def Get(self, flags, off):
+        """
+        Get retrieves a value of the type specified by `flags`  at the
+        given offset.
+        """
+        N.enforce_number(off, N.UOffsetTFlags)
+        return flags.py_type(encode.Get(flags.packer_type, self.Bytes, off))
+
+    def GetSlot(self, slot, d, validator_flags):
+        N.enforce_number(slot, N.VOffsetTFlags)
+        if validator_flags is not None:
+            N.enforce_number(d, validator_flags)
+        off = self.Offset(slot)
+        if off == 0:
+            return d
+        return self.Get(validator_flags, self.Pos + off)
+
+    def GetVectorAsNumpy(self, flags, off):
+        """
+        GetVectorAsNumpy returns the vector that starts at `Vector(off)`
+        as a numpy array with the type specified by `flags`. The array is
+        a `view` into Bytes, so modifying the returned array will
+        modify Bytes in place.
+        """
+        offset = self.Vector(off)
+        length = self.VectorLen(off) # TODO: length accounts for bytewidth, right?
+        numpy_dtype = N.to_numpy_type(flags)
+        return encode.GetVectorAsNumpy(numpy_dtype, self.Bytes, length, offset)
+
+    def GetVOffsetTSlot(self, slot, d):
+        """
+        GetVOffsetTSlot retrieves the VOffsetT that the given vtable location
+        points to. If the vtable value is zero, the default value `d`
+        will be returned.
+        """
+
+        N.enforce_number(slot, N.VOffsetTFlags)
+        N.enforce_number(d, N.VOffsetTFlags)
+
+        off = self.Offset(slot)
+        if off == 0:
+                return d
+        return off
diff --git a/third_party/flatbuffers/python/flatbuffers/util.py b/third_party/flatbuffers/python/flatbuffers/util.py
new file mode 100644
index 0000000..a5a7838
--- /dev/null
+++ b/third_party/flatbuffers/python/flatbuffers/util.py
@@ -0,0 +1,43 @@
+# 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.
+
+from . import encode
+from . import number_types
+from . import packer
+
+def GetSizePrefix(buf, offset):
+	"""Extract the size prefix from a buffer."""
+	return encode.Get(packer.int32, buf, offset)
+
+def GetBufferIdentifier(buf, offset, size_prefixed=False):
+        """Extract the file_identifier from a buffer"""
+        if size_prefixed:
+            # increase offset by size of UOffsetTFlags
+            offset += number_types.UOffsetTFlags.bytewidth
+        # increase offset by size of root table pointer
+        offset += number_types.UOffsetTFlags.bytewidth
+        # end of FILE_IDENTIFIER
+        end = offset + encode.FILE_IDENTIFIER_LENGTH
+        return buf[offset:end]
+
+def BufferHasIdentifier(buf, offset, file_identifier, size_prefixed=False):
+        got = GetBufferIdentifier(buf, offset, size_prefixed=size_prefixed)
+        return got == file_identifier
+
+def RemoveSizePrefix(buf, offset):
+	"""
+	Create a slice of a size-prefixed buffer that has
+	its position advanced just past the size prefix.
+	"""
+	return buf, offset + number_types.Int32Flags.bytewidth
diff --git a/third_party/flatbuffers/python/setup.cfg b/third_party/flatbuffers/python/setup.cfg
new file mode 100644
index 0000000..3c6e79c
--- /dev/null
+++ b/third_party/flatbuffers/python/setup.cfg
@@ -0,0 +1,2 @@
+[bdist_wheel]
+universal=1
diff --git a/third_party/flatbuffers/python/setup.py b/third_party/flatbuffers/python/setup.py
new file mode 100644
index 0000000..b3fc566
--- /dev/null
+++ b/third_party/flatbuffers/python/setup.py
@@ -0,0 +1,71 @@
+# 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.
+
+import os
+from datetime import datetime
+from setuptools import setup
+
+
+def version():
+    version = os.getenv('VERSION', None)
+    if version:
+        # Most git tags are prefixed with 'v' (example: v1.2.3) this is
+        # never desirable for artifact repositories, so we strip the
+        # leading 'v' if it's present.
+        return version[1:] if version.startswith('v') else version
+    else:
+        # Default version is an ISO8601 compiliant datetime. PyPI doesn't allow
+        # the colon ':' character in its versions, and time is required to allow
+        # for multiple publications to master in one day. This datetime string
+        # uses the "basic" ISO8601 format for both its date and time components
+        # to avoid issues with the colon character (ISO requires that date and
+        # time components of a date-time string must be uniformly basic or
+        # extended, which is why the date component does not have dashes.
+        #
+        # Publications using datetime versions should only be made from master
+        # to represent the HEAD moving forward.
+        version = datetime.utcnow().strftime('%Y%m%d%H%M%S')
+        print("VERSION environment variable not set, using datetime instead: {}"
+              .format(version))
+
+    return version
+
+setup(
+    name='flatbuffers',
+    version=version(),
+    license='Apache 2.0',
+    author='FlatBuffers Contributors',
+    author_email='me@rwinslow.com',
+    url='https://google.github.io/flatbuffers/',
+    long_description=('Python runtime library for use with the '
+                      '`Flatbuffers <https://google.github.io/flatbuffers/>`_ '
+                      'serialization format.'),
+    packages=['flatbuffers'],
+    include_package_data=True,
+    requires=[],
+    description='The FlatBuffers serialization format for Python',
+    classifiers=[
+        'Intended Audience :: Developers',
+        'License :: OSI Approved :: Apache Software License',
+        'Operating System :: OS Independent',
+        'Programming Language :: Python',
+        'Programming Language :: Python :: 2',
+        'Programming Language :: Python :: 3',
+        'Topic :: Software Development :: Libraries :: Python Modules',
+    ],
+    project_urls={
+        'Documentation': 'https://google.github.io/flatbuffers/',
+        'Source': 'https://github.com/google/flatbuffers',
+    },
+)
\ No newline at end of file
diff --git a/third_party/flatbuffers/readme.md b/third_party/flatbuffers/readme.md
new file mode 100644
index 0000000..3d5467e
--- /dev/null
+++ b/third_party/flatbuffers/readme.md
@@ -0,0 +1,54 @@
+![logo](http://google.github.io/flatbuffers/fpl_logo_small.png) FlatBuffers
+===========
+
+[![Join the chat at https://gitter.im/google/flatbuffers](https://badges.gitter.im/google/flatbuffers.svg)](https://gitter.im/google/flatbuffers?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+[![Build Status](https://travis-ci.org/google/flatbuffers.svg?branch=master)](https://travis-ci.org/google/flatbuffers) [![Build status](https://ci.appveyor.com/api/projects/status/yg5idd2fnusv1n10?svg=true)](https://ci.appveyor.com/project/gwvo/flatbuffers)
+
+**FlatBuffers** is a cross platform serialization library architected for
+maximum memory efficiency. It allows you to directly access serialized data without parsing/unpacking it first, while still having great forwards/backwards compatibility.
+
+**Go to our [landing page][] to browse our documentation.**
+
+## Supported operating systems
+* Windows
+* MacOS X
+* Linux
+* Android
+* And any others with a recent C++ compiler.
+
+## Supported programming languages
+* C++
+* C#
+* C
+* Dart
+* Go
+* Java
+* JavaScript
+* Lobster
+* Lua
+* PHP
+* Python
+* Rust
+* TypeScript
+
+*and more in progress...*
+
+## Contribution
+* [FlatBuffers Google Group][] to discuss FlatBuffers with other developers and users.
+* [FlatBuffers Issues Tracker][] to submit an issue.
+* [stackoverflow.com][] with [`flatbuffers` tag][] for any questions regarding FlatBuffers.
+
+*To contribute to this project,* see [CONTRIBUTING][].
+
+## Licensing
+*Flatbuffers* is licensed under the Apache License, Version 2.0. See [LICENSE][] for the full license text.
+
+<br>
+
+   [CONTRIBUTING]: http://github.com/google/flatbuffers/blob/master/CONTRIBUTING.md
+   [`flatbuffers` tag]: https://stackoverflow.com/questions/tagged/flatbuffers
+   [FlatBuffers Google Group]: https://groups.google.com/forum/#!forum/flatbuffers
+   [FlatBuffers Issues Tracker]: http://github.com/google/flatbuffers/issues
+   [stackoverflow.com]: http://stackoverflow.com/search?q=flatbuffers
+   [landing page]: https://google.github.io/flatbuffers
+   [LICENSE]: https://github.com/google/flatbuffers/blob/master/LICENSE.txt
diff --git a/third_party/flatbuffers/reflection/generate_code.bat b/third_party/flatbuffers/reflection/generate_code.bat
new file mode 100644
index 0000000..e299325
--- /dev/null
+++ b/third_party/flatbuffers/reflection/generate_code.bat
@@ -0,0 +1,18 @@
+:: 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.
+
+set buildtype=Release
+if "%1"=="-b" set buildtype=%2
+
+..\%buildtype%\flatc.exe --cpp --no-prefix -o ../include/flatbuffers reflection.fbs || exit /b 1
diff --git a/third_party/flatbuffers/reflection/generate_code.sh b/third_party/flatbuffers/reflection/generate_code.sh
new file mode 100755
index 0000000..f186b73
--- /dev/null
+++ b/third_party/flatbuffers/reflection/generate_code.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+#
+# 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.
+set -e
+
+../flatc -c --no-prefix -o ../include/flatbuffers reflection.fbs
diff --git a/third_party/flatbuffers/reflection/reflection.fbs b/third_party/flatbuffers/reflection/reflection.fbs
new file mode 100644
index 0000000..8fed025
--- /dev/null
+++ b/third_party/flatbuffers/reflection/reflection.fbs
@@ -0,0 +1,113 @@
+// This schema defines objects that represent a parsed schema, like
+// the binary version of a .fbs file.
+// This could be used to operate on unknown FlatBuffers at runtime.
+// It can even ... represent itself (!)
+
+namespace reflection;
+
+// These must correspond to the enum in idl.h.
+enum BaseType : byte {
+    None,
+    UType,
+    Bool,
+    Byte,
+    UByte,
+    Short,
+    UShort,
+    Int,
+    UInt,
+    Long,
+    ULong,
+    Float,
+    Double,
+    String,
+    Vector,
+    Obj,     // Used for tables & structs.
+    Union,
+    Array
+}
+
+table Type {
+    base_type:BaseType;
+    element:BaseType = None;  // Only if base_type == Vector 
+                              // or base_type == Array.
+    index:int = -1;  // If base_type == Object, index into "objects" below.
+                     // If base_type == Union, UnionType, or integral derived
+                     // from an enum, index into "enums" below.
+    fixed_length:uint16 = 0;  // Only if base_type == Array.
+}
+
+table KeyValue {
+    key:string (required, key);
+    value:string;
+}
+
+table EnumVal {
+    name:string (required);
+    value:long (key);
+    object:Object;  // Will be deprecated in favor of union_type in the future.
+    union_type:Type;
+    documentation:[string];
+}
+
+table Enum {
+    name:string (required, key);
+    values:[EnumVal] (required);  // In order of their values.
+    is_union:bool = false;
+    underlying_type:Type (required);
+    attributes:[KeyValue];
+    documentation:[string];
+}
+
+table Field {
+    name:string (required, key);
+    type:Type (required);
+    id:ushort;
+    offset:ushort;  // Offset into the vtable for tables, or into the struct.
+    default_integer:long = 0;
+    default_real:double = 0.0;
+    deprecated:bool = false;
+    required:bool = false;
+    key:bool = false;
+    attributes:[KeyValue];
+    documentation:[string];
+}
+
+table Object {  // Used for both tables and structs.
+    name:string (required, key);
+    fields:[Field] (required);  // Sorted.
+    is_struct:bool = false;
+    minalign:int;
+    bytesize:int;  // For structs.
+    attributes:[KeyValue];
+    documentation:[string];
+}
+
+table RPCCall {
+    name:string (required, key);
+    request:Object (required);      // must be a table (not a struct)
+    response:Object (required);     // must be a table (not a struct)
+    attributes:[KeyValue];
+    documentation:[string];
+}
+
+table Service {
+    name:string (required, key);
+    calls:[RPCCall];
+    attributes:[KeyValue];
+    documentation:[string];
+}
+
+table Schema {
+    objects:[Object] (required);    // Sorted.
+    enums:[Enum] (required);        // Sorted.
+    file_ident:string;
+    file_ext:string;
+    root_table:Object;
+    services:[Service];             // Sorted.
+}
+
+root_type Schema;
+
+file_identifier "BFBS";
+file_extension "bfbs";
diff --git a/third_party/flatbuffers/rust/flatbuffers/Cargo.toml b/third_party/flatbuffers/rust/flatbuffers/Cargo.toml
new file mode 100644
index 0000000..32d9b1b
--- /dev/null
+++ b/third_party/flatbuffers/rust/flatbuffers/Cargo.toml
@@ -0,0 +1,13 @@
+[package]
+name = "flatbuffers"
+version = "0.6.0"
+authors = ["Robert Winslow <hello@rwinslow.com>", "FlatBuffers Maintainers"]
+license = "Apache-2.0"
+description = "Official FlatBuffers Rust runtime library."
+homepage = "https://google.github.io/flatbuffers/"
+repository = "https://github.com/google/flatbuffers"
+keywords = ["flatbuffers", "serialization", "zero-copy"]
+categories = ["encoding", "data-structures", "memory-management"]
+
+[dependencies]
+smallvec = "0.6"
diff --git a/third_party/flatbuffers/rust/flatbuffers/src/builder.rs b/third_party/flatbuffers/rust/flatbuffers/src/builder.rs
new file mode 100644
index 0000000..36d6c6a
--- /dev/null
+++ b/third_party/flatbuffers/rust/flatbuffers/src/builder.rs
@@ -0,0 +1,701 @@
+/*
+ * 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.
+ */
+
+extern crate smallvec;
+
+use std::cmp::max;
+use std::marker::PhantomData;
+use std::ptr::write_bytes;
+use std::slice::from_raw_parts;
+
+use endian_scalar::{emplace_scalar, read_scalar_at};
+use primitives::*;
+use push::{Push, PushAlignment};
+use table::Table;
+use vector::{SafeSliceAccess, Vector};
+use vtable::{field_index_to_field_offset, VTable};
+use vtable_writer::VTableWriter;
+
+pub const N_SMALLVEC_STRING_VECTOR_CAPACITY: usize = 16;
+
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+struct FieldLoc {
+    off: UOffsetT,
+    id: VOffsetT,
+}
+
+/// FlatBufferBuilder builds a FlatBuffer through manipulating its internal
+/// state. It has an owned `Vec<u8>` that grows as needed (up to the hardcoded
+/// limit of 2GiB, which is set by the FlatBuffers format).
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct FlatBufferBuilder<'fbb> {
+    owned_buf: Vec<u8>,
+    head: usize,
+
+    field_locs: Vec<FieldLoc>,
+    written_vtable_revpos: Vec<UOffsetT>,
+
+    nested: bool,
+    finished: bool,
+
+    min_align: usize,
+
+    _phantom: PhantomData<&'fbb ()>,
+}
+
+impl<'fbb> FlatBufferBuilder<'fbb> {
+    /// Create a FlatBufferBuilder that is ready for writing.
+    pub fn new() -> Self {
+        Self::new_with_capacity(0)
+    }
+
+    /// Create a FlatBufferBuilder that is ready for writing, with a
+    /// ready-to-use capacity of the provided size.
+    ///
+    /// The maximum valid value is `FLATBUFFERS_MAX_BUFFER_SIZE`.
+    pub fn new_with_capacity(size: usize) -> Self {
+        // we need to check the size here because we create the backing buffer
+        // directly, bypassing the typical way of using grow_owned_buf:
+        assert!(
+            size <= FLATBUFFERS_MAX_BUFFER_SIZE,
+            "cannot initialize buffer bigger than 2 gigabytes"
+        );
+
+        FlatBufferBuilder {
+            owned_buf: vec![0u8; size],
+            head: size,
+
+            field_locs: Vec::new(),
+            written_vtable_revpos: Vec::new(),
+
+            nested: false,
+            finished: false,
+
+            min_align: 0,
+
+            _phantom: PhantomData,
+        }
+    }
+
+    /// Reset the FlatBufferBuilder internal state. Use this method after a
+    /// call to a `finish` function in order to re-use a FlatBufferBuilder.
+    ///
+    /// This function is the only way to reset the `finished` state and start
+    /// again.
+    ///
+    /// If you are using a FlatBufferBuilder repeatedly, make sure to use this
+    /// function, because it re-uses the FlatBufferBuilder's existing
+    /// heap-allocated `Vec<u8>` internal buffer. This offers significant speed
+    /// improvements as compared to creating a new FlatBufferBuilder for every
+    /// new object.
+    pub fn reset(&mut self) {
+        // memset only the part of the buffer that could be dirty:
+        {
+            let to_clear = self.owned_buf.len() - self.head;
+            let ptr = (&mut self.owned_buf[self.head..]).as_mut_ptr();
+            unsafe {
+                write_bytes(ptr, 0, to_clear);
+            }
+        }
+
+        self.head = self.owned_buf.len();
+        self.written_vtable_revpos.clear();
+
+        self.nested = false;
+        self.finished = false;
+
+        self.min_align = 0;
+    }
+
+    /// Destroy the FlatBufferBuilder, returning its internal byte vector
+    /// and the index into it that represents the start of valid data.
+    pub fn collapse(self) -> (Vec<u8>, usize) {
+        (self.owned_buf, self.head)
+    }
+
+    /// Push a Push'able value onto the front of the in-progress data.
+    ///
+    /// This function uses traits to provide a unified API for writing
+    /// scalars, tables, vectors, and WIPOffsets.
+    #[inline]
+    pub fn push<P: Push>(&mut self, x: P) -> WIPOffset<P::Output> {
+        let sz = P::size();
+        self.align(sz, P::alignment());
+        self.make_space(sz);
+        {
+            let (dst, rest) = (&mut self.owned_buf[self.head..]).split_at_mut(sz);
+            x.push(dst, rest);
+        }
+        WIPOffset::new(self.used_space() as UOffsetT)
+    }
+
+    /// Push a Push'able value onto the front of the in-progress data, and
+    /// store a reference to it in the in-progress vtable. If the value matches
+    /// the default, then this is a no-op.
+    #[inline]
+    pub fn push_slot<X: Push + PartialEq>(&mut self, slotoff: VOffsetT, x: X, default: X) {
+        self.assert_nested("push_slot");
+        if x == default {
+            return;
+        }
+        self.push_slot_always(slotoff, x);
+    }
+
+    /// Push a Push'able value onto the front of the in-progress data, and
+    /// store a reference to it in the in-progress vtable.
+    #[inline]
+    pub fn push_slot_always<X: Push>(&mut self, slotoff: VOffsetT, x: X) {
+        self.assert_nested("push_slot_always");
+        let off = self.push(x);
+        self.track_field(slotoff, off.value());
+    }
+
+    /// Retrieve the number of vtables that have been serialized into the
+    /// FlatBuffer. This is primarily used to check vtable deduplication.
+    #[inline]
+    pub fn num_written_vtables(&self) -> usize {
+        self.written_vtable_revpos.len()
+    }
+
+    /// Start a Table write.
+    ///
+    /// Asserts that the builder is not in a nested state.
+    ///
+    /// Users probably want to use `push_slot` to add values after calling this.
+    #[inline]
+    pub fn start_table(&mut self) -> WIPOffset<TableUnfinishedWIPOffset> {
+        self.assert_not_nested(
+            "start_table can not be called when a table or vector is under construction",
+        );
+        self.nested = true;
+
+        WIPOffset::new(self.used_space() as UOffsetT)
+    }
+
+    /// End a Table write.
+    ///
+    /// Asserts that the builder is in a nested state.
+    #[inline]
+    pub fn end_table(
+        &mut self,
+        off: WIPOffset<TableUnfinishedWIPOffset>,
+    ) -> WIPOffset<TableFinishedWIPOffset> {
+        self.assert_nested("end_table");
+
+        let o = self.write_vtable(off);
+
+        self.nested = false;
+        self.field_locs.clear();
+
+        WIPOffset::new(o.value())
+    }
+
+    /// Start a Vector write.
+    ///
+    /// Asserts that the builder is not in a nested state.
+    ///
+    /// Most users will prefer to call `create_vector`.
+    /// Speed optimizing users who choose to create vectors manually using this
+    /// function will want to use `push` to add values.
+    #[inline]
+    pub fn start_vector<T: Push>(&mut self, num_items: usize) {
+        self.assert_not_nested(
+            "start_vector can not be called when a table or vector is under construction",
+        );
+        self.nested = true;
+        self.align(num_items * T::size(), T::alignment().max_of(SIZE_UOFFSET));
+    }
+
+    /// End a Vector write.
+    ///
+    /// Note that the `num_elems` parameter is the number of written items, not
+    /// the byte count.
+    ///
+    /// Asserts that the builder is in a nested state.
+    #[inline]
+    pub fn end_vector<T: Push>(&mut self, num_elems: usize) -> WIPOffset<Vector<'fbb, T>> {
+        self.assert_nested("end_vector");
+        self.nested = false;
+        let o = self.push::<UOffsetT>(num_elems as UOffsetT);
+        WIPOffset::new(o.value())
+    }
+
+    /// Create a utf8 string.
+    ///
+    /// The wire format represents this as a zero-terminated byte vector.
+    #[inline]
+    pub fn create_string<'a: 'b, 'b>(&'a mut self, s: &'b str) -> WIPOffset<&'fbb str> {
+        self.assert_not_nested(
+            "create_string can not be called when a table or vector is under construction",
+        );
+        WIPOffset::new(self.create_byte_string(s.as_bytes()).value())
+    }
+
+    /// Create a zero-terminated byte vector.
+    #[inline]
+    pub fn create_byte_string(&mut self, data: &[u8]) -> WIPOffset<&'fbb [u8]> {
+        self.assert_not_nested(
+            "create_byte_string can not be called when a table or vector is under construction",
+        );
+        self.align(data.len() + 1, PushAlignment::new(SIZE_UOFFSET));
+        self.push(0u8);
+        self.push_bytes_unprefixed(data);
+        self.push(data.len() as UOffsetT);
+        WIPOffset::new(self.used_space() as UOffsetT)
+    }
+
+    /// Create a vector by memcpy'ing. This is much faster than calling
+    /// `create_vector`, but the underlying type must be represented as
+    /// little-endian on the host machine. This property is encoded in the
+    /// type system through the SafeSliceAccess trait. The following types are
+    /// always safe, on any platform: bool, u8, i8, and any
+    /// FlatBuffers-generated struct.
+    #[inline]
+    pub fn create_vector_direct<'a: 'b, 'b, T: SafeSliceAccess + Push + Sized + 'b>(
+        &'a mut self,
+        items: &'b [T],
+    ) -> WIPOffset<Vector<'fbb, T>> {
+        self.assert_not_nested(
+            "create_vector_direct can not be called when a table or vector is under construction",
+        );
+        let elem_size = T::size();
+        self.align(items.len() * elem_size, T::alignment().max_of(SIZE_UOFFSET));
+
+        let bytes = {
+            let ptr = items.as_ptr() as *const T as *const u8;
+            unsafe { from_raw_parts(ptr, items.len() * elem_size) }
+        };
+        self.push_bytes_unprefixed(bytes);
+        self.push(items.len() as UOffsetT);
+
+        WIPOffset::new(self.used_space() as UOffsetT)
+    }
+
+    /// Create a vector of strings.
+    ///
+    /// Speed-sensitive users may wish to reduce memory usage by creating the
+    /// vector manually: use `start_vector`, `push`, and `end_vector`.
+    #[inline]
+    pub fn create_vector_of_strings<'a, 'b>(
+        &'a mut self,
+        xs: &'b [&'b str],
+    ) -> WIPOffset<Vector<'fbb, ForwardsUOffset<&'fbb str>>> {
+        self.assert_not_nested("create_vector_of_strings can not be called when a table or vector is under construction");
+        // internally, smallvec can be a stack-allocated or heap-allocated vector:
+        // if xs.len() > N_SMALLVEC_STRING_VECTOR_CAPACITY then it will overflow to the heap.
+        let mut offsets: smallvec::SmallVec<[WIPOffset<&str>; N_SMALLVEC_STRING_VECTOR_CAPACITY]> =
+            smallvec::SmallVec::with_capacity(xs.len());
+        unsafe {
+            offsets.set_len(xs.len());
+        }
+
+        // note that this happens in reverse, because the buffer is built back-to-front:
+        for (i, &s) in xs.iter().enumerate().rev() {
+            let o = self.create_string(s);
+            offsets[i] = o;
+        }
+        self.create_vector(&offsets[..])
+    }
+
+    /// Create a vector of Push-able objects.
+    ///
+    /// Speed-sensitive users may wish to reduce memory usage by creating the
+    /// vector manually: use `start_vector`, `push`, and `end_vector`.
+    #[inline]
+    pub fn create_vector<'a: 'b, 'b, T: Push + Copy + 'b>(
+        &'a mut self,
+        items: &'b [T],
+    ) -> WIPOffset<Vector<'fbb, T::Output>> {
+        let elem_size = T::size();
+        self.align(items.len() * elem_size, T::alignment().max_of(SIZE_UOFFSET));
+        for i in (0..items.len()).rev() {
+            self.push(items[i]);
+        }
+        WIPOffset::new(self.push::<UOffsetT>(items.len() as UOffsetT).value())
+    }
+
+    /// Get the byte slice for the data that has been written, regardless of
+    /// whether it has been finished.
+    #[inline]
+    pub fn unfinished_data(&self) -> &[u8] {
+        &self.owned_buf[self.head..]
+    }
+    /// Get the byte slice for the data that has been written after a call to
+    /// one of the `finish` functions.
+    #[inline]
+    pub fn finished_data(&self) -> &[u8] {
+        self.assert_finished("finished_bytes cannot be called when the buffer is not yet finished");
+        &self.owned_buf[self.head..]
+    }
+    /// Assert that a field is present in the just-finished Table.
+    ///
+    /// This is somewhat low-level and is mostly used by the generated code.
+    #[inline]
+    pub fn required(
+        &self,
+        tab_revloc: WIPOffset<TableFinishedWIPOffset>,
+        slot_byte_loc: VOffsetT,
+        assert_msg_name: &'static str,
+    ) {
+        let idx = self.used_space() - tab_revloc.value() as usize;
+        let tab = Table::new(&self.owned_buf[self.head..], idx);
+        let o = tab.vtable().get(slot_byte_loc) as usize;
+        assert!(o != 0, "missing required field {}", assert_msg_name);
+    }
+
+    /// Finalize the FlatBuffer by: aligning it, pushing an optional file
+    /// identifier on to it, pushing a size prefix on to it, and marking the
+    /// internal state of the FlatBufferBuilder as `finished`. Afterwards,
+    /// users can call `finished_data` to get the resulting data.
+    #[inline]
+    pub fn finish_size_prefixed<T>(&mut self, root: WIPOffset<T>, file_identifier: Option<&str>) {
+        self.finish_with_opts(root, file_identifier, true);
+    }
+
+    /// Finalize the FlatBuffer by: aligning it, pushing an optional file
+    /// identifier on to it, and marking the internal state of the
+    /// FlatBufferBuilder as `finished`. Afterwards, users can call
+    /// `finished_data` to get the resulting data.
+    #[inline]
+    pub fn finish<T>(&mut self, root: WIPOffset<T>, file_identifier: Option<&str>) {
+        self.finish_with_opts(root, file_identifier, false);
+    }
+
+    /// Finalize the FlatBuffer by: aligning it and marking the internal state
+    /// of the FlatBufferBuilder as `finished`. Afterwards, users can call
+    /// `finished_data` to get the resulting data.
+    #[inline]
+    pub fn finish_minimal<T>(&mut self, root: WIPOffset<T>) {
+        self.finish_with_opts(root, None, false);
+    }
+
+    #[inline]
+    fn used_space(&self) -> usize {
+        self.owned_buf.len() - self.head as usize
+    }
+
+    #[inline]
+    fn track_field(&mut self, slot_off: VOffsetT, off: UOffsetT) {
+        let fl = FieldLoc {
+            id: slot_off,
+            off: off,
+        };
+        self.field_locs.push(fl);
+    }
+
+    /// Write the VTable, if it is new.
+    fn write_vtable(
+        &mut self,
+        table_tail_revloc: WIPOffset<TableUnfinishedWIPOffset>,
+    ) -> WIPOffset<VTableWIPOffset> {
+        self.assert_nested("write_vtable");
+
+        // Write the vtable offset, which is the start of any Table.
+        // We fill its value later.
+        let object_revloc_to_vtable: WIPOffset<VTableWIPOffset> =
+            WIPOffset::new(self.push::<UOffsetT>(0xF0F0F0F0 as UOffsetT).value());
+
+        // Layout of the data this function will create when a new vtable is
+        // needed.
+        // --------------------------------------------------------------------
+        // vtable starts here
+        // | x, x -- vtable len (bytes) [u16]
+        // | x, x -- object inline len (bytes) [u16]
+        // | x, x -- zero, or num bytes from start of object to field #0   [u16]
+        // | ...
+        // | x, x -- zero, or num bytes from start of object to field #n-1 [u16]
+        // vtable ends here
+        // table starts here
+        // | x, x, x, x -- offset (negative direction) to the vtable [i32]
+        // |               aka "vtableoffset"
+        // | -- table inline data begins here, we don't touch it --
+        // table ends here -- aka "table_start"
+        // --------------------------------------------------------------------
+        //
+        // Layout of the data this function will create when we re-use an
+        // existing vtable.
+        //
+        // We always serialize this particular vtable, then compare it to the
+        // other vtables we know about to see if there is a duplicate. If there
+        // is, then we erase the serialized vtable we just made.
+        // We serialize it first so that we are able to do byte-by-byte
+        // comparisons with already-serialized vtables. This 1) saves
+        // bookkeeping space (we only keep revlocs to existing vtables), 2)
+        // allows us to convert to little-endian once, then do
+        // fast memcmp comparisons, and 3) by ensuring we are comparing real
+        // serialized vtables, we can be more assured that we are doing the
+        // comparisons correctly.
+        //
+        // --------------------------------------------------------------------
+        // table starts here
+        // | x, x, x, x -- offset (negative direction) to an existing vtable [i32]
+        // |               aka "vtableoffset"
+        // | -- table inline data begins here, we don't touch it --
+        // table starts here: aka "table_start"
+        // --------------------------------------------------------------------
+
+        // fill the WIP vtable with zeros:
+        let vtable_byte_len = get_vtable_byte_len(&self.field_locs);
+        self.make_space(vtable_byte_len);
+
+        // compute the length of the table (not vtable!) in bytes:
+        let table_object_size = object_revloc_to_vtable.value() - table_tail_revloc.value();
+        debug_assert!(table_object_size < 0x10000); // vTable use 16bit offsets.
+
+        // Write the VTable (we may delete it afterwards, if it is a duplicate):
+        let vt_start_pos = self.head;
+        let vt_end_pos = self.head + vtable_byte_len;
+        {
+            // write the vtable header:
+            let vtfw = &mut VTableWriter::init(&mut self.owned_buf[vt_start_pos..vt_end_pos]);
+            vtfw.write_vtable_byte_length(vtable_byte_len as VOffsetT);
+            vtfw.write_object_inline_size(table_object_size as VOffsetT);
+
+            // serialize every FieldLoc to the vtable:
+            for &fl in self.field_locs.iter() {
+                let pos: VOffsetT = (object_revloc_to_vtable.value() - fl.off) as VOffsetT;
+                debug_assert_eq!(
+                    vtfw.get_field_offset(fl.id),
+                    0,
+                    "tried to write a vtable field multiple times"
+                );
+                vtfw.write_field_offset(fl.id, pos);
+            }
+        }
+        let dup_vt_use = {
+            let this_vt = VTable::init(&self.owned_buf[..], self.head);
+            self.find_duplicate_stored_vtable_revloc(this_vt)
+        };
+
+        let vt_use = match dup_vt_use {
+            Some(n) => {
+                VTableWriter::init(&mut self.owned_buf[vt_start_pos..vt_end_pos]).clear();
+                self.head += vtable_byte_len;
+                n
+            }
+            None => {
+                let new_vt_use = self.used_space() as UOffsetT;
+                self.written_vtable_revpos.push(new_vt_use);
+                new_vt_use
+            }
+        };
+
+        {
+            let n = self.head + self.used_space() - object_revloc_to_vtable.value() as usize;
+            let saw = read_scalar_at::<UOffsetT>(&self.owned_buf, n);
+            debug_assert_eq!(saw, 0xF0F0F0F0);
+            emplace_scalar::<SOffsetT>(
+                &mut self.owned_buf[n..n + SIZE_SOFFSET],
+                vt_use as SOffsetT - object_revloc_to_vtable.value() as SOffsetT,
+            );
+        }
+
+        self.field_locs.clear();
+
+        object_revloc_to_vtable
+    }
+
+    #[inline]
+    fn find_duplicate_stored_vtable_revloc(&self, needle: VTable) -> Option<UOffsetT> {
+        for &revloc in self.written_vtable_revpos.iter().rev() {
+            let o = VTable::init(
+                &self.owned_buf[..],
+                self.head + self.used_space() - revloc as usize,
+            );
+            if needle == o {
+                return Some(revloc);
+            }
+        }
+        None
+    }
+
+    // Only call this when you know it is safe to double the size of the buffer.
+    #[inline]
+    fn grow_owned_buf(&mut self) {
+        let old_len = self.owned_buf.len();
+        let new_len = max(1, old_len * 2);
+
+        let starting_active_size = self.used_space();
+
+        let diff = new_len - old_len;
+        self.owned_buf.resize(new_len, 0);
+        self.head += diff;
+
+        let ending_active_size = self.used_space();
+        debug_assert_eq!(starting_active_size, ending_active_size);
+
+        if new_len == 1 {
+            return;
+        }
+
+        // calculate the midpoint, and safely copy the old end data to the new
+        // end position:
+        let middle = new_len / 2;
+        {
+            let (left, right) = &mut self.owned_buf[..].split_at_mut(middle);
+            right.copy_from_slice(left);
+        }
+        // finally, zero out the old end data.
+        {
+            let ptr = (&mut self.owned_buf[..middle]).as_mut_ptr();
+            unsafe {
+                write_bytes(ptr, 0, middle);
+            }
+        }
+    }
+
+    // with or without a size prefix changes how we load the data, so finish*
+    // functions are split along those lines.
+    fn finish_with_opts<T>(
+        &mut self,
+        root: WIPOffset<T>,
+        file_identifier: Option<&str>,
+        size_prefixed: bool,
+    ) {
+        self.assert_not_finished("buffer cannot be finished when it is already finished");
+        self.assert_not_nested(
+            "buffer cannot be finished when a table or vector is under construction",
+        );
+        self.written_vtable_revpos.clear();
+
+        let to_align = {
+            // for the root offset:
+            let a = SIZE_UOFFSET;
+            // for the size prefix:
+            let b = if size_prefixed { SIZE_UOFFSET } else { 0 };
+            // for the file identifier (a string that is not zero-terminated):
+            let c = if file_identifier.is_some() {
+                FILE_IDENTIFIER_LENGTH
+            } else {
+                0
+            };
+            a + b + c
+        };
+
+        {
+            let ma = PushAlignment::new(self.min_align);
+            self.align(to_align, ma);
+        }
+
+        if let Some(ident) = file_identifier {
+            debug_assert_eq!(ident.len(), FILE_IDENTIFIER_LENGTH);
+            self.push_bytes_unprefixed(ident.as_bytes());
+        }
+
+        self.push(root);
+
+        if size_prefixed {
+            let sz = self.used_space() as UOffsetT;
+            self.push::<UOffsetT>(sz);
+        }
+        self.finished = true;
+    }
+
+    #[inline]
+    fn align(&mut self, len: usize, alignment: PushAlignment) {
+        self.track_min_align(alignment.value());
+        let s = self.used_space() as usize;
+        self.make_space(padding_bytes(s + len, alignment.value()));
+    }
+
+    #[inline]
+    fn track_min_align(&mut self, alignment: usize) {
+        self.min_align = max(self.min_align, alignment);
+    }
+
+    #[inline]
+    fn push_bytes_unprefixed(&mut self, x: &[u8]) -> UOffsetT {
+        let n = self.make_space(x.len());
+        &mut self.owned_buf[n..n + x.len()].copy_from_slice(x);
+
+        n as UOffsetT
+    }
+
+    #[inline]
+    fn make_space(&mut self, want: usize) -> usize {
+        self.ensure_capacity(want);
+        self.head -= want;
+        self.head
+    }
+
+    #[inline]
+    fn ensure_capacity(&mut self, want: usize) -> usize {
+        if self.unused_ready_space() >= want {
+            return want;
+        }
+        assert!(
+            want <= FLATBUFFERS_MAX_BUFFER_SIZE,
+            "cannot grow buffer beyond 2 gigabytes"
+        );
+
+        while self.unused_ready_space() < want {
+            self.grow_owned_buf();
+        }
+        want
+    }
+    #[inline]
+    fn unused_ready_space(&self) -> usize {
+        self.head
+    }
+    #[inline]
+    fn assert_nested(&self, fn_name: &'static str) {
+        // we don't assert that self.field_locs.len() >0 because the vtable
+        // could be empty (e.g. for empty tables, or for all-default values).
+        debug_assert!(
+            self.nested,
+            format!(
+                "incorrect FlatBufferBuilder usage: {} must be called while in a nested state",
+                fn_name
+            )
+        );
+    }
+    #[inline]
+    fn assert_not_nested(&self, msg: &'static str) {
+        debug_assert!(!self.nested, msg);
+    }
+    #[inline]
+    fn assert_finished(&self, msg: &'static str) {
+        debug_assert!(self.finished, msg);
+    }
+    #[inline]
+    fn assert_not_finished(&self, msg: &'static str) {
+        debug_assert!(!self.finished, msg);
+    }
+}
+
+/// Compute the length of the vtable needed to represent the provided FieldLocs.
+/// If there are no FieldLocs, then provide the minimum number of bytes
+/// required: enough to write the VTable header.
+#[inline]
+fn get_vtable_byte_len(field_locs: &[FieldLoc]) -> usize {
+    let max_voffset = field_locs.iter().map(|fl| fl.id).max();
+    match max_voffset {
+        None => field_index_to_field_offset(0) as usize,
+        Some(mv) => mv as usize + SIZE_VOFFSET,
+    }
+}
+
+#[inline]
+fn padding_bytes(buf_size: usize, scalar_size: usize) -> usize {
+    // ((!buf_size) + 1) & (scalar_size - 1)
+    (!buf_size).wrapping_add(1) & (scalar_size.wrapping_sub(1))
+}
+
+impl<'fbb> Default for FlatBufferBuilder<'fbb> {
+    fn default() -> Self {
+        Self::new_with_capacity(0)
+    }
+}
diff --git a/third_party/flatbuffers/rust/flatbuffers/src/endian_scalar.rs b/third_party/flatbuffers/rust/flatbuffers/src/endian_scalar.rs
new file mode 100644
index 0000000..df0b384
--- /dev/null
+++ b/third_party/flatbuffers/rust/flatbuffers/src/endian_scalar.rs
@@ -0,0 +1,179 @@
+/*
+ * 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.
+ */
+
+use std::mem::size_of;
+
+/// Trait for values that must be stored in little-endian byte order, but
+/// might be represented in memory as big-endian. Every type that implements
+/// EndianScalar is a valid FlatBuffers scalar value.
+///
+/// The Rust stdlib does not provide a trait to represent scalars, so this trait
+/// serves that purpose, too.
+///
+/// Note that we do not use the num-traits crate for this, because it provides
+/// "too much". For example, num-traits provides i128 support, but that is an
+/// invalid FlatBuffers type.
+pub trait EndianScalar: Sized + PartialEq + Copy + Clone {
+    fn to_little_endian(self) -> Self;
+    fn from_little_endian(self) -> Self;
+}
+
+/// Macro for implementing a no-op endian conversion. This is used for types
+/// that are one byte wide.
+macro_rules! impl_endian_scalar_noop {
+    ($ty:ident) => {
+        impl EndianScalar for $ty {
+            #[inline]
+            fn to_little_endian(self) -> Self {
+                self
+            }
+            #[inline]
+            fn from_little_endian(self) -> Self {
+                self
+            }
+        }
+    };
+}
+
+/// Macro for implementing an endian conversion using the stdlib `to_le` and
+/// `from_le` functions. This is used for integer types. It is not used for
+/// floats, because the `to_le` and `from_le` are not implemented for them in
+/// the stdlib.
+macro_rules! impl_endian_scalar_stdlib_le_conversion {
+    ($ty:ident) => {
+        impl EndianScalar for $ty {
+            #[inline]
+            fn to_little_endian(self) -> Self {
+                Self::to_le(self)
+            }
+            #[inline]
+            fn from_little_endian(self) -> Self {
+                Self::from_le(self)
+            }
+        }
+    };
+}
+
+impl_endian_scalar_noop!(bool);
+impl_endian_scalar_noop!(u8);
+impl_endian_scalar_noop!(i8);
+
+impl_endian_scalar_stdlib_le_conversion!(u16);
+impl_endian_scalar_stdlib_le_conversion!(u32);
+impl_endian_scalar_stdlib_le_conversion!(u64);
+impl_endian_scalar_stdlib_le_conversion!(i16);
+impl_endian_scalar_stdlib_le_conversion!(i32);
+impl_endian_scalar_stdlib_le_conversion!(i64);
+
+impl EndianScalar for f32 {
+    /// Convert f32 from host endian-ness to little-endian.
+    #[inline]
+    fn to_little_endian(self) -> Self {
+        #[cfg(target_endian = "little")]
+        {
+            self
+        }
+        #[cfg(not(target_endian = "little"))]
+        {
+            byte_swap_f32(self)
+        }
+    }
+    /// Convert f32 from little-endian to host endian-ness.
+    #[inline]
+    fn from_little_endian(self) -> Self {
+        #[cfg(target_endian = "little")]
+        {
+            self
+        }
+        #[cfg(not(target_endian = "little"))]
+        {
+            byte_swap_f32(self)
+        }
+    }
+}
+
+impl EndianScalar for f64 {
+    /// Convert f64 from host endian-ness to little-endian.
+    #[inline]
+    fn to_little_endian(self) -> Self {
+        #[cfg(target_endian = "little")]
+        {
+            self
+        }
+        #[cfg(not(target_endian = "little"))]
+        {
+            byte_swap_f64(self)
+        }
+    }
+    /// Convert f64 from little-endian to host endian-ness.
+    #[inline]
+    fn from_little_endian(self) -> Self {
+        #[cfg(target_endian = "little")]
+        {
+            self
+        }
+        #[cfg(not(target_endian = "little"))]
+        {
+            byte_swap_f64(self)
+        }
+    }
+}
+
+/// Swaps the bytes of an f32.
+#[allow(dead_code)]
+#[inline]
+pub fn byte_swap_f32(x: f32) -> f32 {
+    f32::from_bits(x.to_bits().swap_bytes())
+}
+
+/// Swaps the bytes of an f64.
+#[allow(dead_code)]
+#[inline]
+pub fn byte_swap_f64(x: f64) -> f64 {
+    f64::from_bits(x.to_bits().swap_bytes())
+}
+
+/// Place an EndianScalar into the provided mutable byte slice. Performs
+/// endian conversion, if necessary.
+#[inline]
+pub fn emplace_scalar<T: EndianScalar>(s: &mut [u8], x: T) {
+    let sz = size_of::<T>();
+    let mut_ptr = (&mut s[..sz]).as_mut_ptr() as *mut T;
+    let val = x.to_little_endian();
+    unsafe {
+        *mut_ptr = val;
+    }
+}
+
+/// Read an EndianScalar from the provided byte slice at the specified location.
+/// Performs endian conversion, if necessary.
+#[inline]
+pub fn read_scalar_at<T: EndianScalar>(s: &[u8], loc: usize) -> T {
+    let buf = &s[loc..loc + size_of::<T>()];
+    read_scalar(buf)
+}
+
+/// Read an EndianScalar from the provided byte slice. Performs endian
+/// conversion, if necessary.
+#[inline]
+pub fn read_scalar<T: EndianScalar>(s: &[u8]) -> T {
+    let sz = size_of::<T>();
+
+    let p = (&s[..sz]).as_ptr() as *const T;
+    let x = unsafe { *p };
+
+    x.from_little_endian()
+}
diff --git a/third_party/flatbuffers/rust/flatbuffers/src/follow.rs b/third_party/flatbuffers/rust/flatbuffers/src/follow.rs
new file mode 100644
index 0000000..4d3eff7
--- /dev/null
+++ b/third_party/flatbuffers/rust/flatbuffers/src/follow.rs
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+use std::marker::PhantomData;
+
+/// Follow is a trait that allows us to access FlatBuffers in a declarative,
+/// type safe, and fast way. They compile down to almost no code (after
+/// optimizations). Conceptually, Follow lifts the offset-based access
+/// patterns of FlatBuffers data into the type system. This trait is used
+/// pervasively at read time, to access tables, vtables, vectors, strings, and
+/// all other data. At this time, Follow is not utilized much on the write
+/// path.
+///
+/// Writing a new Follow implementation primarily involves deciding whether
+/// you want to return data (of the type Self::Inner) or do you want to
+/// continue traversing the FlatBuffer.
+pub trait Follow<'a> {
+    type Inner;
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner;
+}
+
+/// Execute a follow as a top-level function.
+#[allow(dead_code)]
+#[inline]
+pub fn lifted_follow<'a, T: Follow<'a>>(buf: &'a [u8], loc: usize) -> T::Inner {
+    T::follow(buf, loc)
+}
+
+/// FollowStart wraps a Follow impl in a struct type. This can make certain
+/// programming patterns more ergonomic.
+#[derive(Debug)]
+pub struct FollowStart<T>(PhantomData<T>);
+impl<'a, T: Follow<'a> + 'a> FollowStart<T> {
+    #[inline]
+    pub fn new() -> Self {
+        Self { 0: PhantomData }
+    }
+    #[inline]
+    pub fn self_follow(&'a self, buf: &'a [u8], loc: usize) -> T::Inner {
+        T::follow(buf, loc)
+    }
+}
+impl<'a, T: Follow<'a>> Follow<'a> for FollowStart<T> {
+    type Inner = T::Inner;
+    #[inline]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        T::follow(buf, loc)
+    }
+}
diff --git a/third_party/flatbuffers/rust/flatbuffers/src/lib.rs b/third_party/flatbuffers/rust/flatbuffers/src/lib.rs
new file mode 100644
index 0000000..ef54132
--- /dev/null
+++ b/third_party/flatbuffers/rust/flatbuffers/src/lib.rs
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+//! # FlatBuffers
+//!
+//! A library for memory-efficient serialization of data.
+//!
+//! This crate provides runtime support for the FlatBuffers format in the Rust programming language.
+//! To use this crate, first generate code with the `flatc` compiler, as described here: https://google.github.io/flatbuffers/
+//! Then, include that code into your project.
+//! Finally, add this crate to your `Cargo.toml`.
+//!
+//! At this time, Rust support is experimental, and APIs may change between minor versions.
+//!
+//! At this time, to generate Rust code, you will need the latest `master` version of `flatc`, available from here: https://github.com/google/flatbuffers
+//! (On OSX, you can install FlatBuffers from `HEAD` with the Homebrew package manager.)
+
+mod builder;
+mod endian_scalar;
+mod follow;
+mod primitives;
+mod push;
+mod table;
+mod vector;
+mod vtable;
+mod vtable_writer;
+
+pub use builder::FlatBufferBuilder;
+pub use endian_scalar::{
+    byte_swap_f32, byte_swap_f64, emplace_scalar, read_scalar, read_scalar_at, EndianScalar,
+};
+pub use follow::{Follow, FollowStart};
+pub use primitives::*;
+pub use push::Push;
+pub use table::{buffer_has_identifier, get_root, get_size_prefixed_root, Table};
+pub use vector::{follow_cast_ref, SafeSliceAccess, Vector};
+pub use vtable::field_index_to_field_offset;
+
+// TODO(rw): Unify `create_vector` and `create_vector_direct` by using
+//           `Into<Vector<...>>`.
+// TODO(rw): Split fill ops in builder into fill_small, fill_big like in C++.
diff --git a/third_party/flatbuffers/rust/flatbuffers/src/primitives.rs b/third_party/flatbuffers/rust/flatbuffers/src/primitives.rs
new file mode 100644
index 0000000..cfd4140
--- /dev/null
+++ b/third_party/flatbuffers/rust/flatbuffers/src/primitives.rs
@@ -0,0 +1,298 @@
+/*
+ * 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.
+ */
+
+use std::marker::PhantomData;
+use std::mem::size_of;
+use std::ops::Deref;
+
+use endian_scalar::{emplace_scalar, read_scalar, read_scalar_at};
+use follow::Follow;
+use push::Push;
+
+pub const FLATBUFFERS_MAX_BUFFER_SIZE: usize = (1u64 << 31) as usize;
+
+pub const FILE_IDENTIFIER_LENGTH: usize = 4;
+
+pub const VTABLE_METADATA_FIELDS: usize = 2;
+
+pub const SIZE_U8: usize = size_of::<u8>();
+pub const SIZE_I8: usize = size_of::<i8>();
+
+pub const SIZE_U16: usize = size_of::<u16>();
+pub const SIZE_I16: usize = size_of::<i16>();
+
+pub const SIZE_U32: usize = size_of::<u32>();
+pub const SIZE_I32: usize = size_of::<i32>();
+
+pub const SIZE_U64: usize = size_of::<u64>();
+pub const SIZE_I64: usize = size_of::<i64>();
+
+pub const SIZE_F32: usize = size_of::<f32>();
+pub const SIZE_F64: usize = size_of::<f64>();
+
+pub const SIZE_SOFFSET: usize = SIZE_I32;
+pub const SIZE_UOFFSET: usize = SIZE_U32;
+pub const SIZE_VOFFSET: usize = SIZE_I16;
+
+pub const SIZE_SIZEPREFIX: usize = SIZE_UOFFSET;
+
+/// SOffsetT is an i32 that is used by tables to reference their vtables.
+pub type SOffsetT = i32;
+
+/// UOffsetT is a u32 that is used by pervasively to represent both pointers
+/// and lengths of vectors.
+pub type UOffsetT = u32;
+
+/// VOffsetT is a i32 that is used by vtables to store field data.
+pub type VOffsetT = i16;
+
+/// TableFinishedWIPOffset marks a WIPOffset as being for a finished table.
+pub struct TableFinishedWIPOffset {}
+
+/// TableUnfinishedWIPOffset marks a WIPOffset as being for an unfinished table.
+pub struct TableUnfinishedWIPOffset {}
+
+/// UnionWIPOffset marks a WIPOffset as being for a union value.
+pub struct UnionWIPOffset {}
+
+/// VTableWIPOffset marks a WIPOffset as being for a vtable.
+pub struct VTableWIPOffset {}
+
+/// WIPOffset contains an UOffsetT with a special meaning: it is the location of
+/// data relative to the *end* of an in-progress FlatBuffer. The
+/// FlatBufferBuilder uses this to track the location of objects in an absolute
+/// way. The impl of Push converts a WIPOffset into a ForwardsUOffset.
+#[derive(Debug)]
+pub struct WIPOffset<T>(UOffsetT, PhantomData<T>);
+
+// TODO(rw): why do we need to reimplement (with a default impl) Copy to
+//           avoid ownership errors?
+impl<T> Copy for WIPOffset<T> {}
+impl<T> Clone for WIPOffset<T> {
+    #[inline]
+    fn clone(&self) -> WIPOffset<T> {
+        WIPOffset::new(self.0.clone())
+    }
+}
+impl<T> PartialEq for WIPOffset<T> {
+    fn eq(&self, o: &WIPOffset<T>) -> bool {
+        self.value() == o.value()
+    }
+}
+
+impl<T> Deref for WIPOffset<T> {
+    type Target = UOffsetT;
+    #[inline]
+    fn deref(&self) -> &UOffsetT {
+        &self.0
+    }
+}
+impl<'a, T: 'a> WIPOffset<T> {
+    /// Create a new WIPOffset.
+    #[inline]
+    pub fn new(o: UOffsetT) -> WIPOffset<T> {
+        WIPOffset {
+            0: o,
+            1: PhantomData,
+        }
+    }
+
+    /// Return a wrapped value that brings its meaning as a union WIPOffset
+    /// into the type system.
+    #[inline(always)]
+    pub fn as_union_value(&self) -> WIPOffset<UnionWIPOffset> {
+        WIPOffset::new(self.0)
+    }
+    /// Get the underlying value.
+    #[inline(always)]
+    pub fn value(&self) -> UOffsetT {
+        self.0
+    }
+}
+
+impl<T> Push for WIPOffset<T> {
+    type Output = ForwardsUOffset<T>;
+
+    #[inline(always)]
+    fn push(&self, dst: &mut [u8], rest: &[u8]) {
+        let n = (SIZE_UOFFSET + rest.len() - self.value() as usize) as UOffsetT;
+        emplace_scalar::<UOffsetT>(dst, n);
+    }
+}
+
+impl<T> Push for ForwardsUOffset<T> {
+    type Output = Self;
+
+    #[inline(always)]
+    fn push(&self, dst: &mut [u8], rest: &[u8]) {
+        self.value().push(dst, rest);
+    }
+}
+
+/// ForwardsUOffset is used by Follow to traverse a FlatBuffer: the pointer
+/// is incremented by the value contained in this type.
+#[derive(Debug)]
+pub struct ForwardsUOffset<T>(UOffsetT, PhantomData<T>);
+impl<T> ForwardsUOffset<T> {
+    #[inline(always)]
+    pub fn value(&self) -> UOffsetT {
+        self.0
+    }
+}
+
+impl<'a, T: Follow<'a>> Follow<'a> for ForwardsUOffset<T> {
+    type Inner = T::Inner;
+    #[inline(always)]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        let slice = &buf[loc..loc + SIZE_UOFFSET];
+        let off = read_scalar::<u32>(slice) as usize;
+        T::follow(buf, loc + off)
+    }
+}
+
+/// ForwardsVOffset is used by Follow to traverse a FlatBuffer: the pointer
+/// is incremented by the value contained in this type.
+#[derive(Debug)]
+pub struct ForwardsVOffset<T>(VOffsetT, PhantomData<T>);
+impl<T> ForwardsVOffset<T> {
+    #[inline(always)]
+    pub fn value(&self) -> VOffsetT {
+        self.0
+    }
+}
+
+impl<'a, T: Follow<'a>> Follow<'a> for ForwardsVOffset<T> {
+    type Inner = T::Inner;
+    #[inline(always)]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        let slice = &buf[loc..loc + SIZE_VOFFSET];
+        let off = read_scalar::<VOffsetT>(slice) as usize;
+        T::follow(buf, loc + off)
+    }
+}
+
+impl<T> Push for ForwardsVOffset<T> {
+    type Output = Self;
+
+    #[inline]
+    fn push(&self, dst: &mut [u8], rest: &[u8]) {
+        self.value().push(dst, rest);
+    }
+}
+
+/// ForwardsSOffset is used by Follow to traverse a FlatBuffer: the pointer
+/// is incremented by the *negative* of the value contained in this type.
+#[derive(Debug)]
+pub struct BackwardsSOffset<T>(SOffsetT, PhantomData<T>);
+impl<T> BackwardsSOffset<T> {
+    #[inline(always)]
+    pub fn value(&self) -> SOffsetT {
+        self.0
+    }
+}
+
+impl<'a, T: Follow<'a>> Follow<'a> for BackwardsSOffset<T> {
+    type Inner = T::Inner;
+    #[inline(always)]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        let slice = &buf[loc..loc + SIZE_SOFFSET];
+        let off = read_scalar::<SOffsetT>(slice);
+        T::follow(buf, (loc as SOffsetT - off) as usize)
+    }
+}
+
+impl<T> Push for BackwardsSOffset<T> {
+    type Output = Self;
+
+    #[inline]
+    fn push(&self, dst: &mut [u8], rest: &[u8]) {
+        self.value().push(dst, rest);
+    }
+}
+
+/// SkipSizePrefix is used by Follow to traverse a FlatBuffer: the pointer is
+/// incremented by a fixed constant in order to skip over the size prefix value.
+pub struct SkipSizePrefix<T>(PhantomData<T>);
+impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipSizePrefix<T> {
+    type Inner = T::Inner;
+    #[inline(always)]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        T::follow(buf, loc + SIZE_SIZEPREFIX)
+    }
+}
+
+/// SkipRootOffset is used by Follow to traverse a FlatBuffer: the pointer is
+/// incremented by a fixed constant in order to skip over the root offset value.
+pub struct SkipRootOffset<T>(PhantomData<T>);
+impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipRootOffset<T> {
+    type Inner = T::Inner;
+    #[inline(always)]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        T::follow(buf, loc + SIZE_UOFFSET)
+    }
+}
+
+/// FileIdentifier is used by Follow to traverse a FlatBuffer: the pointer is
+/// dereferenced into a byte slice, whose bytes are the file identifer value.
+pub struct FileIdentifier;
+impl<'a> Follow<'a> for FileIdentifier {
+    type Inner = &'a [u8];
+    #[inline(always)]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        &buf[loc..loc + FILE_IDENTIFIER_LENGTH]
+    }
+}
+
+/// SkipFileIdentifier is used by Follow to traverse a FlatBuffer: the pointer
+/// is incremented by a fixed constant in order to skip over the file
+/// identifier value.
+pub struct SkipFileIdentifier<T>(PhantomData<T>);
+impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipFileIdentifier<T> {
+    type Inner = T::Inner;
+    #[inline(always)]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        T::follow(buf, loc + FILE_IDENTIFIER_LENGTH)
+    }
+}
+
+/// Follow trait impls for primitive types.
+///
+/// Ideally, these would be implemented as a single impl using trait bounds on
+/// EndianScalar, but implementing Follow that way causes a conflict with
+/// other impls.
+macro_rules! impl_follow_for_endian_scalar {
+    ($ty:ident) => {
+        impl<'a> Follow<'a> for $ty {
+            type Inner = $ty;
+            #[inline(always)]
+            fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+                read_scalar_at::<$ty>(buf, loc)
+            }
+        }
+    };
+}
+
+impl_follow_for_endian_scalar!(bool);
+impl_follow_for_endian_scalar!(u8);
+impl_follow_for_endian_scalar!(u16);
+impl_follow_for_endian_scalar!(u32);
+impl_follow_for_endian_scalar!(u64);
+impl_follow_for_endian_scalar!(i8);
+impl_follow_for_endian_scalar!(i16);
+impl_follow_for_endian_scalar!(i32);
+impl_follow_for_endian_scalar!(i64);
+impl_follow_for_endian_scalar!(f32);
+impl_follow_for_endian_scalar!(f64);
diff --git a/third_party/flatbuffers/rust/flatbuffers/src/push.rs b/third_party/flatbuffers/rust/flatbuffers/src/push.rs
new file mode 100644
index 0000000..1863058
--- /dev/null
+++ b/third_party/flatbuffers/rust/flatbuffers/src/push.rs
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+use std::cmp::max;
+use std::mem::{align_of, size_of};
+
+use endian_scalar::emplace_scalar;
+
+/// Trait to abstract over functionality needed to write values (either owned
+/// or referenced). Used in FlatBufferBuilder and implemented for generated
+/// types.
+pub trait Push: Sized {
+    type Output;
+    fn push(&self, dst: &mut [u8], _rest: &[u8]);
+    #[inline]
+    fn size() -> usize {
+        size_of::<Self::Output>()
+    }
+    #[inline]
+    fn alignment() -> PushAlignment {
+        PushAlignment::new(align_of::<Self::Output>())
+    }
+}
+
+/// Ensure Push alignment calculations are typesafe (because this helps reduce
+/// implementation issues when using FlatBufferBuilder::align).
+pub struct PushAlignment(usize);
+impl PushAlignment {
+    #[inline]
+    pub fn new(x: usize) -> Self {
+        PushAlignment { 0: x }
+    }
+    #[inline]
+    pub fn value(&self) -> usize {
+        self.0
+    }
+    #[inline]
+    pub fn max_of(&self, o: usize) -> Self {
+        PushAlignment::new(max(self.0, o))
+    }
+}
+
+/// Macro to implement Push for EndianScalar types.
+macro_rules! impl_push_for_endian_scalar {
+    ($ty:ident) => {
+        impl Push for $ty {
+            type Output = $ty;
+
+            #[inline]
+            fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+                emplace_scalar::<$ty>(dst, *self);
+            }
+        }
+    };
+}
+
+impl_push_for_endian_scalar!(bool);
+impl_push_for_endian_scalar!(u8);
+impl_push_for_endian_scalar!(i8);
+impl_push_for_endian_scalar!(u16);
+impl_push_for_endian_scalar!(i16);
+impl_push_for_endian_scalar!(u32);
+impl_push_for_endian_scalar!(i32);
+impl_push_for_endian_scalar!(u64);
+impl_push_for_endian_scalar!(i64);
+impl_push_for_endian_scalar!(f32);
+impl_push_for_endian_scalar!(f64);
diff --git a/third_party/flatbuffers/rust/flatbuffers/src/table.rs b/third_party/flatbuffers/rust/flatbuffers/src/table.rs
new file mode 100644
index 0000000..7b1c4a5
--- /dev/null
+++ b/third_party/flatbuffers/rust/flatbuffers/src/table.rs
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+use follow::Follow;
+use primitives::*;
+use vtable::VTable;
+
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub struct Table<'a> {
+    pub buf: &'a [u8],
+    pub loc: usize,
+}
+
+impl<'a> Table<'a> {
+    #[inline]
+    pub fn new(buf: &'a [u8], loc: usize) -> Self {
+        Table { buf: buf, loc: loc }
+    }
+    #[inline]
+    pub fn vtable(&self) -> VTable<'a> {
+        <BackwardsSOffset<VTable<'a>>>::follow(self.buf, self.loc)
+    }
+    #[inline]
+    pub fn get<T: Follow<'a> + 'a>(
+        &self,
+        slot_byte_loc: VOffsetT,
+        default: Option<T::Inner>,
+    ) -> Option<T::Inner> {
+        let o = self.vtable().get(slot_byte_loc) as usize;
+        if o == 0 {
+            return default;
+        }
+        Some(<T>::follow(self.buf, self.loc + o))
+    }
+}
+
+impl<'a> Follow<'a> for Table<'a> {
+    type Inner = Table<'a>;
+    #[inline]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        Table { buf: buf, loc: loc }
+    }
+}
+
+#[inline]
+pub fn get_root<'a, T: Follow<'a> + 'a>(data: &'a [u8]) -> T::Inner {
+    <ForwardsUOffset<T>>::follow(data, 0)
+}
+#[inline]
+pub fn get_size_prefixed_root<'a, T: Follow<'a> + 'a>(data: &'a [u8]) -> T::Inner {
+    <SkipSizePrefix<ForwardsUOffset<T>>>::follow(data, 0)
+}
+#[inline]
+pub fn buffer_has_identifier(data: &[u8], ident: &str, size_prefixed: bool) -> bool {
+    assert_eq!(ident.len(), FILE_IDENTIFIER_LENGTH);
+
+    let got = if size_prefixed {
+        <SkipSizePrefix<SkipRootOffset<FileIdentifier>>>::follow(data, 0)
+    } else {
+        <SkipRootOffset<FileIdentifier>>::follow(data, 0)
+    };
+
+    ident.as_bytes() == got
+}
diff --git a/third_party/flatbuffers/rust/flatbuffers/src/vector.rs b/third_party/flatbuffers/rust/flatbuffers/src/vector.rs
new file mode 100644
index 0000000..66653eb
--- /dev/null
+++ b/third_party/flatbuffers/rust/flatbuffers/src/vector.rs
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+
+use std::marker::PhantomData;
+use std::mem::size_of;
+use std::slice::from_raw_parts;
+use std::str::from_utf8_unchecked;
+
+#[cfg(target_endian = "little")]
+use endian_scalar::EndianScalar;
+use endian_scalar::{read_scalar, read_scalar_at};
+use follow::Follow;
+use primitives::*;
+
+#[derive(Debug)]
+pub struct Vector<'a, T: 'a>(&'a [u8], usize, PhantomData<T>);
+
+impl<'a, T: 'a> Vector<'a, T> {
+    #[inline(always)]
+    pub fn new(buf: &'a [u8], loc: usize) -> Self {
+        Vector {
+            0: buf,
+            1: loc,
+            2: PhantomData,
+        }
+    }
+
+    #[inline(always)]
+    pub fn len(&self) -> usize {
+        read_scalar::<UOffsetT>(&self.0[self.1 as usize..]) as usize
+    }
+}
+
+impl<'a, T: Follow<'a> + 'a> Vector<'a, T> {
+    #[inline(always)]
+    pub fn get(&self, idx: usize) -> T::Inner {
+        debug_assert!(idx < read_scalar::<u32>(&self.0[self.1 as usize..]) as usize);
+        let sz = size_of::<T>();
+        debug_assert!(sz > 0);
+        T::follow(self.0, self.1 as usize + SIZE_UOFFSET + sz * idx)
+    }
+}
+
+pub trait SafeSliceAccess {}
+impl<'a, T: SafeSliceAccess + 'a> Vector<'a, T> {
+    pub fn safe_slice(self) -> &'a [T] {
+        let buf = self.0;
+        let loc = self.1;
+        let sz = size_of::<T>();
+        debug_assert!(sz > 0);
+        let len = read_scalar_at::<UOffsetT>(&buf, loc) as usize;
+        let data_buf = &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len * sz];
+        let ptr = data_buf.as_ptr() as *const T;
+        let s: &'a [T] = unsafe { from_raw_parts(ptr, len) };
+        s
+    }
+}
+
+impl SafeSliceAccess for u8 {}
+impl SafeSliceAccess for i8 {}
+impl SafeSliceAccess for bool {}
+
+#[cfg(target_endian = "little")]
+mod le_safe_slice_impls {
+    impl super::SafeSliceAccess for u16 {}
+    impl super::SafeSliceAccess for u32 {}
+    impl super::SafeSliceAccess for u64 {}
+
+    impl super::SafeSliceAccess for i16 {}
+    impl super::SafeSliceAccess for i32 {}
+    impl super::SafeSliceAccess for i64 {}
+
+    impl super::SafeSliceAccess for f32 {}
+    impl super::SafeSliceAccess for f64 {}
+}
+
+#[cfg(target_endian = "little")]
+pub use self::le_safe_slice_impls::*;
+
+pub fn follow_cast_ref<'a, T: Sized + 'a>(buf: &'a [u8], loc: usize) -> &'a T {
+    let sz = size_of::<T>();
+    let buf = &buf[loc..loc + sz];
+    let ptr = buf.as_ptr() as *const T;
+    unsafe { &*ptr }
+}
+
+impl<'a> Follow<'a> for &'a str {
+    type Inner = &'a str;
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        let len = read_scalar_at::<UOffsetT>(&buf, loc) as usize;
+        let slice = &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len];
+        let s = unsafe { from_utf8_unchecked(slice) };
+        s
+    }
+}
+
+#[cfg(target_endian = "little")]
+fn follow_slice_helper<T>(buf: &[u8], loc: usize) -> &[T] {
+    let sz = size_of::<T>();
+    debug_assert!(sz > 0);
+    let len = read_scalar_at::<UOffsetT>(&buf, loc) as usize;
+    let data_buf = &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len * sz];
+    let ptr = data_buf.as_ptr() as *const T;
+    let s: &[T] = unsafe { from_raw_parts(ptr, len) };
+    s
+}
+
+/// Implement direct slice access if the host is little-endian.
+#[cfg(target_endian = "little")]
+impl<'a, T: EndianScalar> Follow<'a> for &'a [T] {
+    type Inner = &'a [T];
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        follow_slice_helper::<T>(buf, loc)
+    }
+}
+
+/// Implement Follow for all possible Vectors that have Follow-able elements.
+impl<'a, T: Follow<'a> + 'a> Follow<'a> for Vector<'a, T> {
+    type Inner = Vector<'a, T>;
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        Vector::new(buf, loc)
+    }
+}
diff --git a/third_party/flatbuffers/rust/flatbuffers/src/vtable.rs b/third_party/flatbuffers/rust/flatbuffers/src/vtable.rs
new file mode 100644
index 0000000..5808670
--- /dev/null
+++ b/third_party/flatbuffers/rust/flatbuffers/src/vtable.rs
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+use endian_scalar::read_scalar_at;
+use follow::Follow;
+use primitives::*;
+
+/// VTable encapsulates read-only usage of a vtable. It is only to be used
+/// by generated code.
+#[derive(Debug)]
+pub struct VTable<'a> {
+    buf: &'a [u8],
+    loc: usize,
+}
+
+impl<'a> PartialEq for VTable<'a> {
+    fn eq(&self, other: &VTable) -> bool {
+        self.as_bytes().eq(other.as_bytes())
+    }
+}
+
+impl<'a> VTable<'a> {
+    pub fn init(buf: &'a [u8], loc: usize) -> Self {
+        VTable { buf: buf, loc: loc }
+    }
+    pub fn num_fields(&self) -> usize {
+        (self.num_bytes() / SIZE_VOFFSET) - 2
+    }
+    pub fn num_bytes(&self) -> usize {
+        read_scalar_at::<VOffsetT>(self.buf, self.loc) as usize
+    }
+    pub fn object_inline_num_bytes(&self) -> usize {
+        let n = read_scalar_at::<VOffsetT>(self.buf, self.loc + SIZE_VOFFSET);
+        n as usize
+    }
+    pub fn get_field(&self, idx: usize) -> VOffsetT {
+        // TODO(rw): distinguish between None and 0?
+        if idx > self.num_fields() {
+            return 0;
+        }
+        read_scalar_at::<VOffsetT>(
+            self.buf,
+            self.loc + SIZE_VOFFSET + SIZE_VOFFSET + SIZE_VOFFSET * idx,
+        )
+    }
+    pub fn get(&self, byte_loc: VOffsetT) -> VOffsetT {
+        // TODO(rw): distinguish between None and 0?
+        if byte_loc as usize >= self.num_bytes() {
+            return 0;
+        }
+        read_scalar_at::<VOffsetT>(self.buf, self.loc + byte_loc as usize)
+    }
+    pub fn as_bytes(&self) -> &[u8] {
+        let len = self.num_bytes();
+        &self.buf[self.loc..self.loc + len]
+    }
+}
+
+#[allow(dead_code)]
+pub fn field_index_to_field_offset(field_id: VOffsetT) -> VOffsetT {
+    // Should correspond to what end_table() below builds up.
+    let fixed_fields = 2; // Vtable size and Object Size.
+    ((field_id + fixed_fields) * (SIZE_VOFFSET as VOffsetT)) as VOffsetT
+}
+
+#[allow(dead_code)]
+pub fn field_offset_to_field_index(field_o: VOffsetT) -> VOffsetT {
+    debug_assert!(field_o >= 2);
+    let fixed_fields = 2; // VTable size and Object Size.
+    (field_o / (SIZE_VOFFSET as VOffsetT)) - fixed_fields
+}
+
+impl<'a> Follow<'a> for VTable<'a> {
+    type Inner = VTable<'a>;
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        VTable::init(buf, loc)
+    }
+}
diff --git a/third_party/flatbuffers/rust/flatbuffers/src/vtable_writer.rs b/third_party/flatbuffers/rust/flatbuffers/src/vtable_writer.rs
new file mode 100644
index 0000000..d1e87dd
--- /dev/null
+++ b/third_party/flatbuffers/rust/flatbuffers/src/vtable_writer.rs
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+use std::ptr::write_bytes;
+
+use endian_scalar::{emplace_scalar, read_scalar_at};
+use primitives::*;
+
+/// VTableWriter compartmentalizes actions needed to create a vtable.
+#[derive(Debug)]
+pub struct VTableWriter<'a> {
+    buf: &'a mut [u8],
+}
+
+impl<'a> VTableWriter<'a> {
+    #[inline(always)]
+    pub fn init(buf: &'a mut [u8]) -> Self {
+        VTableWriter { buf: buf }
+    }
+
+    /// Writes the vtable length (in bytes) into the vtable.
+    ///
+    /// Note that callers already need to have computed this to initialize
+    /// a VTableWriter.
+    ///
+    /// In debug mode, asserts that the length of the underlying data is equal
+    /// to the provided value.
+    #[inline(always)]
+    pub fn write_vtable_byte_length(&mut self, n: VOffsetT) {
+        emplace_scalar::<VOffsetT>(&mut self.buf[..SIZE_VOFFSET], n);
+        debug_assert_eq!(n as usize, self.buf.len());
+    }
+
+    /// Writes an object length (in bytes) into the vtable.
+    #[inline(always)]
+    pub fn write_object_inline_size(&mut self, n: VOffsetT) {
+        emplace_scalar::<VOffsetT>(&mut self.buf[SIZE_VOFFSET..2 * SIZE_VOFFSET], n);
+    }
+
+    /// Gets an object field offset from the vtable. Only used for debugging.
+    ///
+    /// Note that this expects field offsets (which are like pointers), not
+    /// field ids (which are like array indices).
+    #[inline(always)]
+    pub fn get_field_offset(&self, vtable_offset: VOffsetT) -> VOffsetT {
+        let idx = vtable_offset as usize;
+        read_scalar_at::<VOffsetT>(&self.buf, idx)
+    }
+
+    /// Writes an object field offset into the vtable.
+    ///
+    /// Note that this expects field offsets (which are like pointers), not
+    /// field ids (which are like array indices).
+    #[inline(always)]
+    pub fn write_field_offset(&mut self, vtable_offset: VOffsetT, object_data_offset: VOffsetT) {
+        let idx = vtable_offset as usize;
+        emplace_scalar::<VOffsetT>(&mut self.buf[idx..idx + SIZE_VOFFSET], object_data_offset);
+    }
+
+    /// Clears all data in this VTableWriter. Used to cleanly undo a
+    /// vtable write.
+    #[inline(always)]
+    pub fn clear(&mut self) {
+        // This is the closest thing to memset in Rust right now.
+        let len = self.buf.len();
+        let p = self.buf.as_mut_ptr() as *mut u8;
+        unsafe {
+            write_bytes(p, 0, len);
+        }
+    }
+}
diff --git a/third_party/flatbuffers/samples/SampleBinary.cs b/third_party/flatbuffers/samples/SampleBinary.cs
new file mode 100644
index 0000000..d07caf7
--- /dev/null
+++ b/third_party/flatbuffers/samples/SampleBinary.cs
@@ -0,0 +1,134 @@
+/*
+ * 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.
+ */
+
+// To run, use the `csharp_sample.sh` script.
+
+using System;
+using FlatBuffers;
+using MyGame.Sample;
+
+class SampleBinary
+{
+  // Example how to use FlatBuffers to create and read binary buffers.
+  static void Main()
+  {
+    var builder = new FlatBufferBuilder(1);
+
+    // Create some weapons for our Monster ('Sword' and 'Axe').
+    var weapon1Name = builder.CreateString("Sword");
+    var weapon1Damage = 3;
+    var weapon2Name = builder.CreateString("Axe");
+    var weapon2Damage = 5;
+
+    // Use the `CreateWeapon()` helper function to create the weapons, since we set every field.
+    var weaps = new Offset<Weapon>[2];
+    weaps[0] = Weapon.CreateWeapon(builder, weapon1Name, (short)weapon1Damage);
+    weaps[1] = Weapon.CreateWeapon(builder, weapon2Name, (short)weapon2Damage);
+
+    // Serialize the FlatBuffer data.
+    var name = builder.CreateString("Orc");
+    var treasure =  new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+    var inv = Monster.CreateInventoryVector(builder, treasure);
+    var weapons = Monster.CreateWeaponsVector(builder, weaps);
+    var pos = Vec3.CreateVec3(builder, 1.0f, 2.0f, 3.0f);
+
+    Monster.StartMonster(builder);
+    Monster.AddPos(builder, pos);
+    Monster.AddHp(builder, (short)300);
+    Monster.AddName(builder, name);
+    Monster.AddInventory(builder, inv);
+    Monster.AddColor(builder, Color.Red);
+    Monster.AddWeapons(builder, weapons);
+    Monster.AddEquippedType(builder, Equipment.Weapon);
+    Monster.AddEquipped(builder, weaps[1].Value);
+    var orc = Monster.EndMonster(builder);
+
+    builder.Finish(orc.Value); // You could also call `Monster.FinishMonsterBuffer(builder, orc);`.
+
+    // We now have a FlatBuffer that we could store on disk or send over a network.
+
+    // ...Code to store to disk or send over a network goes here...
+
+    // Instead, we are going to access it right away, as if we just received it.
+
+    var buf = builder.DataBuffer;
+
+    // Get access to the root:
+    var monster = Monster.GetRootAsMonster(buf);
+
+    // For C#, unlike other languages, most values (except for vectors and unions) are available as
+    // properties instead of accessor methods.
+
+    // Note: We did not set the `Mana` field explicitly, so we get back the default value.
+    Assert(monster.Mana == 150, "monster.Mana", Convert.ToString(monster.Mana),
+           Convert.ToString(150));
+    Assert(monster.Hp == 300, "monster.Hp", Convert.ToString(monster.Hp), Convert.ToString(30));
+    Assert(monster.Name.Equals("Orc", StringComparison.Ordinal), "monster.Name", monster.Name,
+           "Orc");
+    Assert(monster.Color == Color.Red, "monster.Color", Convert.ToString(monster.Color),
+           Convert.ToString(Color.Red));
+
+    var vec = monster.Pos.Value;
+    Assert(vec.X == 1.0f, "vec.X",
+           Convert.ToString(vec.X), Convert.ToString(1.0f));
+    Assert(vec.Y == 2.0f, "vec.Y",
+           Convert.ToString(vec.Y), Convert.ToString(2.0f));
+    Assert(vec.Z == 3.0f, "vec.Z",
+           Convert.ToString(vec.Z), Convert.ToString(3.0f));
+
+    // Get and test the `Inventory` FlatBuffer `vector`.
+    for (int i = 0; i < monster.InventoryLength; i++)
+    {
+      Assert(monster.Inventory(i) == i, "monster.Inventory",
+             Convert.ToString(monster.Inventory(i)), Convert.ToString(i));
+    }
+
+    // Get and test the `Weapons` FlatBuffer `vector` of `table`s.
+    var expectedWeaponNames = new string[] {"Sword", "Axe"};
+    var expectedWeaponDamages = new short[] {3, 5};
+    for (int i = 0; i < monster.WeaponsLength; i++)
+    {
+      Assert(monster.Weapons(i).Value.Name.Equals(expectedWeaponNames[i], StringComparison.Ordinal),
+             "monster.Weapons", monster.Weapons(i).Value.Name, expectedWeaponNames[i]);
+      Assert(monster.Weapons(i).Value.Damage == expectedWeaponDamages[i], "monster.GetWeapons",
+             Convert.ToString(monster.Weapons(i).Value.Damage),
+             Convert.ToString(expectedWeaponDamages[i]));
+    }
+
+    // Get and test the `Equipped` FlatBuffer `union`.
+    Assert(monster.EquippedType == Equipment.Weapon, "monster.EquippedType",
+           Convert.ToString(monster.EquippedType), Convert.ToString(Equipment.Weapon));
+    var equipped = monster.Equipped<Weapon>().Value;
+    Assert(equipped.Name.Equals("Axe", StringComparison.Ordinal), "equipped.Name", equipped.Name,
+           "Axe");
+    Assert(equipped.Damage == 5, "equipped.Damage", Convert.ToString(equipped.Damage),
+           Convert.ToString(5));
+
+    Console.WriteLine("The FlatBuffer was successfully created and verified!");
+  }
+
+  // A helper function to handle assertions.
+  static void Assert(bool assertPassed, string codeExecuted, string actualValue,
+                     string expectedValue)
+  {
+    if (assertPassed == false)
+    {
+      Console.WriteLine("Assert failed! " + codeExecuted + " (" + actualValue +
+          ") was not equal to " + expectedValue + ".");
+      System.Environment.Exit(1);
+    }
+  }
+}
diff --git a/third_party/flatbuffers/samples/SampleBinary.java b/third_party/flatbuffers/samples/SampleBinary.java
new file mode 100644
index 0000000..555194f
--- /dev/null
+++ b/third_party/flatbuffers/samples/SampleBinary.java
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+// Run this file with the `java_sample.sh` script.
+
+import MyGame.Sample.Color;
+import MyGame.Sample.Equipment;
+import MyGame.Sample.Monster;
+import MyGame.Sample.Vec3;
+import MyGame.Sample.Weapon;
+
+import com.google.flatbuffers.FlatBufferBuilder;
+
+import java.nio.ByteBuffer;
+
+class SampleBinary {
+  // Example how to use FlatBuffers to create and read binary buffers.
+  public static void main(String[] args) {
+    FlatBufferBuilder builder = new FlatBufferBuilder(0);
+
+    // Create some weapons for our Monster ('Sword' and 'Axe').
+    int weaponOneName = builder.createString("Sword");
+    short weaponOneDamage = 3;
+    int weaponTwoName = builder.createString("Axe");
+    short weaponTwoDamage = 5;
+
+    // Use the `createWeapon()` helper function to create the weapons, since we set every field.
+    int[] weaps = new int[2];
+    weaps[0] = Weapon.createWeapon(builder, weaponOneName, weaponOneDamage);
+    weaps[1] = Weapon.createWeapon(builder, weaponTwoName, weaponTwoDamage);
+
+    // Serialize the FlatBuffer data.
+    int name = builder.createString("Orc");
+    byte[] treasure = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+    int inv = Monster.createInventoryVector(builder, treasure);
+    int weapons = Monster.createWeaponsVector(builder, weaps);
+    int pos = Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f);
+
+    Monster.startMonster(builder);
+    Monster.addPos(builder, pos);
+    Monster.addName(builder, name);
+    Monster.addColor(builder, Color.Red);
+    Monster.addHp(builder, (short)300);
+    Monster.addInventory(builder, inv);
+    Monster.addWeapons(builder, weapons);
+    Monster.addEquippedType(builder, Equipment.Weapon);
+    Monster.addEquipped(builder, weaps[1]);
+    int orc = Monster.endMonster(builder);
+
+    builder.finish(orc); // You could also call `Monster.finishMonsterBuffer(builder, orc);`.
+
+    // We now have a FlatBuffer that can be stored on disk or sent over a network.
+
+    // ...Code to store to disk or send over a network goes here...
+
+    // Instead, we are going to access it right away, as if we just received it.
+
+    ByteBuffer buf = builder.dataBuffer();
+
+    // Get access to the root:
+    Monster monster = Monster.getRootAsMonster(buf);
+
+    // Note: We did not set the `mana` field explicitly, so we get back the default value.
+    assert monster.mana() == (short)150;
+    assert monster.hp() == (short)300;
+    assert monster.name().equals("Orc");
+    assert monster.color() == Color.Red;
+    assert monster.pos().x() == 1.0f;
+    assert monster.pos().y() == 2.0f;
+    assert monster.pos().z() == 3.0f;
+
+    // Get and test the `inventory` FlatBuffer `vector`.
+    for (int i = 0; i < monster.inventoryLength(); i++) {
+      assert monster.inventory(i) == (byte)i;
+    }
+
+    // Get and test the `weapons` FlatBuffer `vector` of `table`s.
+    String[] expectedWeaponNames = {"Sword", "Axe"};
+    int[] expectedWeaponDamages = {3, 5};
+    for (int i = 0; i < monster.weaponsLength(); i++) {
+      assert monster.weapons(i).name().equals(expectedWeaponNames[i]);
+      assert monster.weapons(i).damage() == expectedWeaponDamages[i];
+    }
+
+    // Get and test the `equipped` FlatBuffer `union`.
+    assert monster.equippedType() == Equipment.Weapon;
+    Weapon equipped = (Weapon)monster.equipped(new Weapon());
+    assert equipped.name().equals("Axe");
+    assert equipped.damage() == 5;
+
+    System.out.println("The FlatBuffer was successfully created and verified!");
+  }
+}
diff --git a/third_party/flatbuffers/samples/SampleBinary.kt b/third_party/flatbuffers/samples/SampleBinary.kt
new file mode 100644
index 0000000..2974f36
--- /dev/null
+++ b/third_party/flatbuffers/samples/SampleBinary.kt
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+
+// Run this file with the `java_sample.sh` script.
+
+import MyGame.Sample.Color
+import MyGame.Sample.Equipment
+import MyGame.Sample.Monster
+import MyGame.Sample.Vec3
+import MyGame.Sample.Weapon
+
+import com.google.flatbuffers.FlatBufferBuilder
+
+class SampleBinary {
+
+  companion object {
+    // Example how to use FlatBuffers to create and read binary buffers.
+    @JvmStatic
+    fun main(args: Array<String>) {
+        val builder = FlatBufferBuilder(0)
+
+        // Create some weapons for our Monster ('Sword' and 'Axe').
+        val weaponOneName = builder.createString("Sword")
+        val weaponOneDamage: Short = 3
+        val weaponTwoName = builder.createString("Axe")
+        val weaponTwoDamage: Short = 5
+
+        // Use the `createWeapon()` helper function to create the weapons, since we set every field.
+        val weaps = IntArray(2)
+        weaps[0] = Weapon.createWeapon(builder, weaponOneName, weaponOneDamage)
+        weaps[1] = Weapon.createWeapon(builder, weaponTwoName, weaponTwoDamage)
+
+        // Serialize the FlatBuffer data.
+        val name = builder.createString("Orc")
+        val treasure = byteArrayOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
+        val inv = Monster.createInventoryVector(builder, treasure)
+        val weapons = Monster.createWeaponsVector(builder, weaps)
+        val pos = Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f)
+
+        Monster.startMonster(builder)
+        Monster.addPos(builder, pos)
+        Monster.addName(builder, name)
+        Monster.addColor(builder, Color.Red)
+        Monster.addHp(builder, 300.toShort())
+        Monster.addInventory(builder, inv)
+        Monster.addWeapons(builder, weapons)
+        Monster.addEquippedType(builder, Equipment.Weapon)
+        Monster.addEquipped(builder, weaps[1])
+        val orc = Monster.endMonster(builder)
+
+        builder.finish(orc) // You could also call `Monster.finishMonsterBuffer(builder, orc);`.
+
+        // We now have a FlatBuffer that can be stored on disk or sent over a network.
+
+        // ...Code to store to disk or send over a network goes here...
+
+        // Instead, we are going to access it right away, as if we just received it.
+
+        val buf = builder.dataBuffer()
+
+        // Get access to the root:
+        val monster = Monster.getRootAsMonster(buf)
+
+        // Note: We did not set the `mana` field explicitly, so we get back the default value.
+        assert(monster.mana == 150.toShort())
+        assert(monster.hp == 300.toShort())
+        assert(monster.name.equals("Orc"))
+        assert(monster.color == Color.Red)
+        assert(monster.pos!!.x == 1.0f)
+        assert(monster.pos!!.y == 2.0f)
+        assert(monster.pos!!.z == 3.0f)
+
+        // Get and test the `inventory` FlatBuffer `vector`.
+        for (i in 0 until monster.inventoryLength) {
+            assert(monster.inventory(i) == i.toByte().toInt())
+        }
+
+        // Get and test the `weapons` FlatBuffer `vector` of `table`s.
+        val expectedWeaponNames = arrayOf("Sword", "Axe")
+        val expectedWeaponDamages = intArrayOf(3, 5)
+        for (i in 0 until monster.weaponsLength) {
+            assert(monster.weapons(i)!!.name.equals(expectedWeaponNames[i]))
+            assert(monster.weapons(i)!!.damage.toInt() == expectedWeaponDamages[i])
+        }
+
+        // Get and test the `equipped` FlatBuffer `union`.
+        assert(monster.equippedType == Equipment.Weapon)
+        val equipped = monster.equipped(Weapon()) as Weapon?
+        assert(equipped!!.name.equals("Axe"))
+        assert(equipped.damage == 5.toShort())
+
+        println("The FlatBuffer was successfully created and verified!")
+    }
+  }
+}
diff --git a/third_party/flatbuffers/samples/SampleBinary.php b/third_party/flatbuffers/samples/SampleBinary.php
new file mode 100644
index 0000000..d28ffa3
--- /dev/null
+++ b/third_party/flatbuffers/samples/SampleBinary.php
@@ -0,0 +1,115 @@
+<?php
+/*
+ * 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.
+ */
+
+// To run, use the `php_sample.sh` script.
+
+// It is recommended that you use PSR autoload when using FlatBuffers.
+function __autoload($class_name) {
+  $class = substr($class_name, strrpos($class_name, "\\") + 1);
+  $root_dir = join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)))); // `flatbuffers` root.
+  $paths = array(join(DIRECTORY_SEPARATOR, array($root_dir, "php")),
+                 join(DIRECTORY_SEPARATOR, array($root_dir, "samples", "MyGame", "Sample")));
+  foreach ($paths as $path) {
+    $file = join(DIRECTORY_SEPARATOR, array($path, $class . ".php"));
+    if (file_exists($file)) {
+      require($file);
+      break;
+    }
+  }
+}
+
+// Example how to use FlatBuffers to create and read binary buffers.
+function main() {
+  $builder = new Google\FlatBuffers\FlatbufferBuilder(0);
+
+  // Create some weapons for our Monster using the `createWeapon()` helper function.
+  $weapon_one = $builder->createString("Sword");
+  $sword = \MyGame\Sample\Weapon::CreateWeapon($builder, $weapon_one, 3);
+  $weapon_two = $builder->createString("Axe");
+  $axe = \MyGame\Sample\Weapon::CreateWeapon($builder, $weapon_two, 5);
+
+  // Serialize the FlatBuffer data.
+  $name = $builder->createString("Orc");
+
+  $treasure = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+  $inv = \MyGame\Sample\Monster::CreateInventoryVector($builder, $treasure);
+
+  $weaps = array($sword, $axe);
+  $weapons = \MyGame\Sample\Monster::CreateWeaponsVector($builder, $weaps);
+
+  $pos = \MyGame\Sample\Vec3::CreateVec3($builder, 1.0, 2.0, 3.0);
+
+  \MyGame\Sample\Monster::StartMonster($builder);
+  \MyGame\Sample\Monster::AddPos($builder, $pos);
+  \MyGame\Sample\Monster::AddHp($builder, 300);
+  \MyGame\Sample\Monster::AddName($builder, $name);
+  \MyGame\Sample\Monster::AddInventory($builder, $inv);
+  \MyGame\Sample\Monster::AddColor($builder, \MyGame\Sample\Color::Red);
+  \MyGame\Sample\Monster::AddWeapons($builder, $weapons);
+  \MyGame\Sample\Monster::AddEquippedType($builder, \MyGame\Sample\Equipment::Weapon);
+  \MyGame\Sample\Monster::AddEquipped($builder, $weaps[1]);
+  $orc = \MyGame\Sample\Monster::EndMonster($builder);
+
+  $builder->finish($orc); // You may also call `\MyGame\Sample\Monster::FinishMonsterBuffer($builder, $orc);`.
+
+  // We now have a FlatBuffer that can be stored on disk or sent over a network.
+
+  // ...Code to store to disk or send over a network goes here...
+
+  // Instead, we are going to access it right away, as if we just received it.
+
+  $buf = $builder->dataBuffer();
+
+  // Get access to the root:
+  $monster = \MyGame\Sample\Monster::GetRootAsMonster($buf);
+
+  $success = true; // Tracks if an assert occurred.
+
+  // Note: We did not set the `mana` field explicitly, so we get back the default value.
+  $success &= assert($monster->getMana() == 150);
+  $success &= assert($monster->getHp() == 300);
+  $success &= assert($monster->getName() == "Orc");
+  $success &= assert($monster->getColor() == \MyGame\Sample\Color::Red);
+  $success &= assert($monster->getPos()->getX() == 1.0);
+  $success &= assert($monster->getPos()->getY() == 2.0);
+  $success &= assert($monster->getPos()->getZ() == 3.0);
+
+  // Get and test the `inventory` FlatBuffer `vector`.
+  for ($i = 0; $i < $monster->getInventoryLength(); $i++) {
+    $success &= assert($monster->getInventory($i) == $i);
+  }
+
+  // Get and test the `weapons` FlatBuffer `vector` of `table`s.
+  $expected_weapon_names = array("Sword", "Axe");
+  $expected_weapon_damages = array(3, 5);
+  for ($i = 0; $i < $monster->getWeaponsLength(); $i++) {
+    $success &= assert($monster->getWeapons($i)->getName() == $expected_weapon_names[$i]);
+    $success &= assert($monster->getWeapons($i)->getDamage() == $expected_weapon_damages[$i]);
+  }
+
+  // Get and test the `equipped` FlatBuffer `union`.
+  $success &= assert($monster->getEquippedType() == \MyGame\Sample\Equipment::Weapon);
+  $success &= assert($monster->getEquipped(new \MyGame\Sample\Weapon())->getName() == "Axe");
+  $success &= assert($monster->getEquipped(new \MyGame\Sample\Weapon())->getDamage() == 5);
+
+  if ($success) {
+    print("The FlatBuffer was successfully created and verified!\n");
+  }
+}
+
+main();
+?>
diff --git a/third_party/flatbuffers/samples/android/AndroidManifest.xml b/third_party/flatbuffers/samples/android/AndroidManifest.xml
new file mode 100644
index 0000000..352e0fa
--- /dev/null
+++ b/third_party/flatbuffers/samples/android/AndroidManifest.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2015 Google, Inc.
+
+     This software is provided 'as-is', without any express or implied
+     warranty.  In no event will the authors be held liable for any damages
+     arising from the use of this software.
+     Permission is granted to anyone to use this software for any purpose,
+     including commercial applications, and to alter it and redistribute it
+     freely, subject to the following restrictions:
+     1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+     2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+     3. This notice may not be removed or altered from any source distribution.
+ -->
+<!-- BEGIN_INCLUDE(manifest) -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.samples.FlatBufferSample">
+
+    <uses-feature android:glEsVersion="0x00020000"></uses-feature>
+
+    <!-- This .apk has no Java code itself, so set hasCode to false. -->
+    <application android:label="@string/app_name"
+                 android:hasCode="false"
+                 android:allowBackup="false">
+        <!-- Our activity is the built-in NativeActivity framework class.
+             This will take care of integrating with our NDK code. -->
+        <activity android:name="android.app.NativeActivity"
+                android:label="@string/app_name"
+                android:configChanges="orientation|keyboardHidden"
+                android:screenOrientation="landscape">
+            <!-- Tell NativeActivity the name of or .so -->
+            <meta-data android:name="android.app.lib_name"
+                    android:value="FlatBufferSample" />
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
+<!-- END_INCLUDE(manifest) -->
diff --git a/third_party/flatbuffers/samples/android/build.gradle b/third_party/flatbuffers/samples/android/build.gradle
new file mode 100644
index 0000000..81c1af0
--- /dev/null
+++ b/third_party/flatbuffers/samples/android/build.gradle
@@ -0,0 +1,108 @@
+// Copyright (c) 2017 Google, Inc.
+//
+// This software is provided 'as-is', without any express or implied
+// warranty.  In no event will the authors be held liable for any damages
+// arising from the use of this software.
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would be
+// appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+// misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+
+buildscript {
+  repositories {
+    jcenter()
+  }
+  dependencies {
+    classpath 'com.android.tools.build:gradle:2.3.0'
+  }
+}
+
+allprojects {
+  repositories {
+    jcenter()
+  }
+}
+
+apply plugin: 'com.android.application'
+
+android {
+  compileSdkVersion 25
+  buildToolsVersion '25.0.2'
+
+  sourceSets {
+    main {
+      manifest.srcFile 'AndroidManifest.xml'
+      res.srcDirs = ['res']
+    }
+  }
+
+  externalNativeBuild {
+    ndkBuild {
+      path "jni/Android.mk"
+    }
+  }
+
+  defaultConfig {
+    applicationId 'com.samples.FlatBufferSample'
+    // This is the platform API where NativeActivity was introduced.
+    minSdkVersion 9
+    targetSdkVersion 25
+    versionCode 1
+    versionName "1.0"
+
+    buildTypes {
+      release {
+        minifyEnabled false
+      }
+    }
+
+    externalNativeBuild {
+      ndkBuild {
+        targets "FlatBufferSample"
+        arguments "-j" + Runtime.getRuntime().availableProcessors()
+        abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
+      }
+    }
+  }
+
+  lintOptions {
+    abortOnError false
+  }
+
+  // Build with each STL variant.
+  productFlavors {
+    stlport {
+      applicationIdSuffix ".stlport"
+      versionNameSuffix "-stlport"
+      externalNativeBuild {
+        ndkBuild {
+          arguments "APP_STL=stlport_static"
+        }
+      }
+    }
+    gnustl {
+      applicationIdSuffix ".gnustl"
+      versionNameSuffix "-gnustl"
+      externalNativeBuild {
+        ndkBuild {
+          arguments "APP_STL=gnustl_static"
+        }
+      }
+    }
+    libcpp {
+      applicationIdSuffix ".libcpp"
+      versionNameSuffix "-libcpp"
+      externalNativeBuild {
+        ndkBuild {
+          arguments "APP_STL=c++_static"
+        }
+      }
+    }
+  }
+}
diff --git a/third_party/flatbuffers/samples/android/gradle/wrapper/gradle-wrapper.jar b/third_party/flatbuffers/samples/android/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..b4163b8
--- /dev/null
+++ b/third_party/flatbuffers/samples/android/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/third_party/flatbuffers/samples/android/gradle/wrapper/gradle-wrapper.properties b/third_party/flatbuffers/samples/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..1e1168c
--- /dev/null
+++ b/third_party/flatbuffers/samples/android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Mon Jun 19 11:54:59 PDT 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.0-all.zip
diff --git a/third_party/flatbuffers/samples/android/gradlew b/third_party/flatbuffers/samples/android/gradlew
new file mode 100755
index 0000000..cccdd3d
--- /dev/null
+++ b/third_party/flatbuffers/samples/android/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+    echo "$*"
+}
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Escape application args
+save () {
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+    echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+  cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/third_party/flatbuffers/samples/android/gradlew.bat b/third_party/flatbuffers/samples/android/gradlew.bat
new file mode 100644
index 0000000..f955316
--- /dev/null
+++ b/third_party/flatbuffers/samples/android/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/third_party/flatbuffers/samples/android/jni/Android.mk b/third_party/flatbuffers/samples/android/jni/Android.mk
new file mode 100644
index 0000000..917c2f9
--- /dev/null
+++ b/third_party/flatbuffers/samples/android/jni/Android.mk
@@ -0,0 +1,56 @@
+# Copyright (c) 2013 Google, Inc.
+#
+# This software is provided 'as-is', without any express or implied
+# warranty.  In no event will the authors be held liable for any damages
+# arising from the use of this software.
+# Permission is granted to anyone to use this software for any purpose,
+# including commercial applications, and to alter it and redistribute it
+# freely, subject to the following restrictions:
+# 1. The origin of this software must not be misrepresented; you must not
+# claim that you wrote the original software. If you use this software
+# in a product, an acknowledgment in the product documentation would be
+# appreciated but is not required.
+# 2. Altered source versions must be plainly marked as such, and must not be
+# misrepresented as being the original software.
+# 3. This notice may not be removed or altered from any source distribution.
+
+LOCAL_PATH := $(call my-dir)
+FLATBUFFERS_ROOT_DIR := $(LOCAL_PATH)/../../..
+
+# FlatBuffers test
+include $(CLEAR_VARS)
+
+# Include the FlatBuffer utility function to generate header files from schemas.
+include $(FLATBUFFERS_ROOT_DIR)/android/jni/include.mk
+
+LOCAL_MODULE := FlatBufferSample
+
+# Set up some useful variables to identify schema and output directories and
+# schema files.
+ANDROID_SAMPLE_GENERATED_OUTPUT_DIR := $(LOCAL_PATH)/gen/include
+ANDROID_SAMPLE_SCHEMA_DIR := $(LOCAL_PATH)/schemas
+ANDROID_SAMPLE_SCHEMA_FILES := $(ANDROID_SAMPLE_SCHEMA_DIR)/animal.fbs
+
+LOCAL_C_INCLUDES := $(ANDROID_SAMPLE_GENERATED_OUTPUT_DIR)
+
+$(info $(LOCAL_C_INCLUDES))
+
+LOCAL_SRC_FILES := main.cpp
+
+LOCAL_CPPFLAGS := -std=c++11 -fexceptions -Wall -Wno-literal-suffix
+LOCAL_LDLIBS := -llog -landroid -latomic
+LOCAL_ARM_MODE := arm
+LOCAL_STATIC_LIBRARIES := android_native_app_glue flatbuffers
+
+ifeq (,$(ANDROID_SAMPLE_RUN_ONCE))
+ANDROID_SAMPLE_RUN_ONCE := 1
+$(call flatbuffers_header_build_rules,$(ANDROID_SAMPLE_SCHEMA_FILES),$(ANDROID_SAMPLE_SCHEMA_DIR),$(ANDROID_SAMPLE_GENERATED_OUTPUT_DIR),,$(LOCAL_SRC_FILES))
+endif
+
+include $(BUILD_SHARED_LIBRARY)
+
+# Path to Flatbuffers root directory.
+$(call import-add-path,$(FLATBUFFERS_ROOT_DIR)/..)
+
+$(call import-module,flatbuffers/android/jni)
+$(call import-module,android/native_app_glue)
diff --git a/third_party/flatbuffers/samples/android/jni/Application.mk b/third_party/flatbuffers/samples/android/jni/Application.mk
new file mode 100644
index 0000000..ca9e800
--- /dev/null
+++ b/third_party/flatbuffers/samples/android/jni/Application.mk
@@ -0,0 +1,20 @@
+# Copyright (c) 2014 Google, Inc.
+#
+# This software is provided 'as-is', without any express or implied
+# warranty.  In no event will the authors be held liable for any damages
+# arising from the use of this software.
+# Permission is granted to anyone to use this software for any purpose,
+# including commercial applications, and to alter it and redistribute it
+# freely, subject to the following restrictions:
+# 1. The origin of this software must not be misrepresented; you must not
+# claim that you wrote the original software. If you use this software
+# in a product, an acknowledgment in the product documentation would be
+# appreciated but is not required.
+# 2. Altered source versions must be plainly marked as such, and must not be
+# misrepresented as being the original software.
+# 3. This notice may not be removed or altered from any source distribution.
+APP_PLATFORM := android-9
+APP_PROJECT_PATH := $(call my-dir)/..
+APP_STL ?= stlport_static
+APP_ABI := armeabi-v7a
+APP_CPPFLAGS += -std=c++11
diff --git a/third_party/flatbuffers/samples/android/jni/main.cpp b/third_party/flatbuffers/samples/android/jni/main.cpp
new file mode 100644
index 0000000..8758027
--- /dev/null
+++ b/third_party/flatbuffers/samples/android/jni/main.cpp
@@ -0,0 +1,43 @@
+// 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 <android/log.h>
+
+#include "android_native_app_glue.h"
+#include "animal_generated.h" // Includes "flatbuffers/flatbuffers.h".
+
+void android_main(android_app *app) {
+  app_dummy();
+
+  flatbuffers::FlatBufferBuilder builder;
+  auto name = builder.CreateString("Dog");
+  auto sound = builder.CreateString("Bark");
+  auto animal_buffer = sample::CreateAnimal(builder, name, sound);
+  builder.Finish(animal_buffer);
+
+  // We now have a FlatBuffer that can be stored on disk or sent over a network.
+
+  // ...Code to store on disk or send over a network goes here...
+
+  // Instead, we're going to access it immediately, as if we just recieved this.
+
+  auto animal = sample::GetAnimal(builder.GetBufferPointer());
+
+  assert(animal->name()->str() == "Dog");
+  assert(animal->sound()->str() == "Bark");
+  (void)animal; // To silence "Unused Variable" warnings.
+
+  __android_log_print(ANDROID_LOG_INFO, "FlatBufferSample",
+      "FlatBuffer successfully created and verified.");
+}
diff --git a/third_party/flatbuffers/samples/android/jni/schemas/animal.fbs b/third_party/flatbuffers/samples/android/jni/schemas/animal.fbs
new file mode 100644
index 0000000..d1bd38d
--- /dev/null
+++ b/third_party/flatbuffers/samples/android/jni/schemas/animal.fbs
@@ -0,0 +1,22 @@
+// 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.
+
+namespace sample;
+
+table Animal {
+  name:string;
+  sound:string;
+}
+
+root_type Animal;
diff --git a/third_party/flatbuffers/samples/android/res/values/strings.xml b/third_party/flatbuffers/samples/android/res/values/strings.xml
new file mode 100644
index 0000000..57ddaf4
--- /dev/null
+++ b/third_party/flatbuffers/samples/android/res/values/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2015 Google, Inc.
+
+     This software is provided 'as-is', without any express or implied
+     warranty.  In no event will the authors be held liable for any damages
+     arising from the use of this software.
+     Permission is granted to anyone to use this software for any purpose,
+     including commercial applications, and to alter it and redistribute it
+     freely, subject to the following restrictions:
+     1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+     2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+     3. This notice may not be removed or altered from any source distribution.
+ -->
+<resources>
+    <string name="app_name">FlatBufferSample</string>
+</resources>
diff --git a/third_party/flatbuffers/samples/android_sample.sh b/third_party/flatbuffers/samples/android_sample.sh
new file mode 100755
index 0000000..53633ac
--- /dev/null
+++ b/third_party/flatbuffers/samples/android_sample.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+#
+# 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.
+#
+# Note: This script requires the Android NDK and Android SDK to be installed.
+#       It also requires an Android device to be connected for installing and
+#       running the applicaton.
+
+sampledir=$(readlink -fn `dirname $0`)
+currentdir=$(readlink -fn `pwd`)
+
+if [[ "$sampledir" != "$currentdir" ]]; then
+  echo Error: This script must be run from inside the $sampledir directory.
+  echo You executed it from the $currentdir directory.
+  exit 1
+fi
+
+# Execute `build_apk.sh` to build and run the android app.
+cd android
+./gradlew build
+
+
+
diff --git a/third_party/flatbuffers/samples/csharp_sample.sh b/third_party/flatbuffers/samples/csharp_sample.sh
new file mode 100755
index 0000000..ea472ed
--- /dev/null
+++ b/third_party/flatbuffers/samples/csharp_sample.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+#
+# 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.
+#
+# Note: This script runs on Mac and Linux. It requires `mono` to be installed
+# and `flatc` to be built (using `cmake` in the root directory).
+
+sampledir=$(cd $(dirname $BASH_SOURCE) && pwd)
+rootidr=$(cd $sampledir/.. && pwd)
+currentdir=$(pwd)
+
+if [[ "$sampledir" != "$currentdir" ]]; then
+  echo Error: This script must be run from inside the $sampledir directory.
+  echo You executed it from the $currentdir directory.
+  exit 1
+fi
+
+# Run `flatc`. Note: This requires you to compile using `cmake` from the
+# root `/flatbuffers` directory.
+if [ -e ../flatc ]; then
+  ../flatc --csharp --gen-mutable monster.fbs
+elif [ -e ../Debug/flatc ]; then
+  ../Debug/flatc --csharp --gen-mutable monster.fbs
+else
+  echo 'flatc' could not be found. Make sure to build FlatBuffers from the \
+       $rootdir directory.
+  exit 1
+fi
+
+echo Compiling and running the C# sample.
+
+# Compile and execute the sample.
+mcs SampleBinary.cs MyGame/Sample/*.cs ../net/FlatBuffers/*.cs
+mono SampleBinary.exe
+
+# Cleanup temporary files.
+rm SampleBinary.exe
+rm -rf MyGame/
diff --git a/third_party/flatbuffers/samples/dart_sample.sh b/third_party/flatbuffers/samples/dart_sample.sh
new file mode 100755
index 0000000..5616066
--- /dev/null
+++ b/third_party/flatbuffers/samples/dart_sample.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+#
+# Copyright 2018 Dan Field. 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.
+#
+# Note: This script runs on Mac and Linux. It requires `Node.js` to be installed
+# and `flatc` to be built (using `cmake` in the root directory).
+
+sampledir=$(cd $(dirname $BASH_SOURCE) && pwd)
+rootdir=$(cd $sampledir/.. && pwd)
+currentdir=$(pwd)
+
+if [[ "$sampledir" != "$currentdir" ]]; then
+  echo Error: This script must be run from inside the $sampledir directory.
+  echo You executed it from the $currentdir directory.
+  exit 1
+fi
+
+cd ../dart/example
+
+# Run `flatc`. Note: This requires you to compile using `cmake` from the
+# root `/flatbuffers` directory.
+if [ -e ../../flatc ]; then
+  ../../flatc --dart ../../samples/monster.fbs
+elif [ -e ../../Debug/flatc ]; then
+  ../../Debug/flatc --dart ../../samples/monster.fbs
+else
+  echo 'flatc' could not be found. Make sure to build FlatBuffers from the \
+       $rootdir directory.
+  exit 1
+fi
+
+echo Running the Dart sample.
+
+# Execute the sample.
+dart example.dart
+
+# Cleanup temporary files.
+git checkout monster_my_game.sample_generated.dart
+
+cd ../../samples
diff --git a/third_party/flatbuffers/samples/go_sample.sh b/third_party/flatbuffers/samples/go_sample.sh
new file mode 100755
index 0000000..13a96c1
--- /dev/null
+++ b/third_party/flatbuffers/samples/go_sample.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+#
+# 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.
+#
+# Note: This script runs on Mac and Linux. It requires `go` to be installed
+# and 'flatc' to be built (using `cmake` in the root directory).
+
+sampledir=$(cd $(dirname $BASH_SOURCE) && pwd)
+rootdir=$(cd $sampledir/.. && pwd)
+currentdir=$(pwd)
+
+if [[ "$sampledir" != "$currentdir" ]]; then
+  echo Error: This script must be run from inside the $sampledir directory.
+  echo You executed it from the $currentdir directory.
+  exit 1
+fi
+
+# Run `flatc`. Note: This requires you to compile using `cmake` from the
+# root `/flatbuffers` directory.
+if [ -e ../flatc ]; then
+  ../flatc --go monster.fbs
+elif [ -e ../Debug/flatc ]; then
+  ../Debug/flatc --go monster.fbs
+else
+  echo 'flatc' could not be found. Make sure to build FlatBuffers from the \
+       $rootdir directory.
+ exit 1
+fi
+
+echo Compiling and running the Go sample.
+
+# Go requires a particular layout of files in order to link the necessary
+# packages. Copy these files to the respective directores to compile the
+# sample.
+mkdir -p ${sampledir}/go_gen/src/MyGame/Sample
+mkdir -p ${sampledir}/go_gen/src/github.com/google/flatbuffers/go
+cp MyGame/Sample/*.go ${sampledir}/go_gen/src/MyGame/Sample/
+cp ${sampledir}/../go/* ${sampledir}/go_gen/src/github.com/google/flatbuffers/go
+
+# Export the `GOPATH`, so that `go` will know which directories to search for
+# the libraries.
+export GOPATH=${sampledir}/go_gen/
+
+# Compile and execute the sample.
+go build -o go_sample sample_binary.go
+./go_sample
+
+# Clean up the temporary files.
+rm -rf MyGame/
+rm -rf ${sampledir}/go_gen/
+rm go_sample
diff --git a/third_party/flatbuffers/samples/java_sample.sh b/third_party/flatbuffers/samples/java_sample.sh
new file mode 100755
index 0000000..bd1315f
--- /dev/null
+++ b/third_party/flatbuffers/samples/java_sample.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+#
+# 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.
+#
+# Note: This script runs on Mac and Linux. It requires `java` to be installed
+# and `flatc` to be built (using `cmake` in the root directory).
+
+sampledir=$(cd $(dirname $BASH_SOURCE) && pwd)
+rootdir=$(cd $sampledir/.. && pwd)
+currentdir=$(pwd)
+
+if [[ "$sampledir" != "$currentdir" ]]; then
+  echo Error: This script must be run from inside the $sampledir directory.
+  echo You executed it from the $currentdir directory.
+  exit 1
+fi
+
+# Run `flatc`. Note: This requires you to compile using `cmake` from the
+# root `/flatbuffers` directory.
+if [ -e ../flatc ]; then
+  ../flatc --java --gen-mutable monster.fbs
+elif [ -e ../Debug/flatc ]; then
+  ../Debug/flatc --java --gen-mutable monster.fbs
+else
+  echo 'flatc' could not be found. Make sure to build FlatBuffers from the \
+       $rootdir directory.
+  exit 1
+fi
+
+echo Compiling and running the Java sample.
+
+# Compile and execute the sample.
+javac -classpath ${sampledir}/../java:${sampledir} SampleBinary.java
+java -classpath ${sampledir}/../java:${sampledir} SampleBinary
+
+# Cleanup temporary files.
+rm -rf MyGame/
+rm ${sampledir}/../java/com/google/flatbuffers/*.class
+rm *.class
diff --git a/third_party/flatbuffers/samples/javascript_sample.sh b/third_party/flatbuffers/samples/javascript_sample.sh
new file mode 100755
index 0000000..4bbc478
--- /dev/null
+++ b/third_party/flatbuffers/samples/javascript_sample.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+#
+# 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.
+#
+# Note: This script runs on Mac and Linux. It requires `Node.js` to be installed
+# and `flatc` to be built (using `cmake` in the root directory).
+
+sampledir=$(cd $(dirname $BASH_SOURCE) && pwd)
+rootdir=$(cd $sampledir/.. && pwd)
+currentdir=$(pwd)
+
+if [[ "$sampledir" != "$currentdir" ]]; then
+  echo Error: This script must be run from inside the $sampledir directory.
+  echo You executed it from the $currentdir directory.
+  exit 1
+fi
+
+# Run `flatc`. Note: This requires you to compile using `cmake` from the
+# root `/flatbuffers` directory.
+if [ -e ../flatc ]; then
+  ../flatc --js monster.fbs
+elif [ -e ../Debug/flatc ]; then
+  ../Debug/flatc --js monster.fbs
+else
+  echo 'flatc' could not be found. Make sure to build FlatBuffers from the \
+       $rootdir directory.
+  exit 1
+fi
+
+echo Running the JavaScript sample.
+
+# Execute the sample.
+node samplebinary.js
+
+# Cleanup temporary files.
+rm monster_generated.js
diff --git a/third_party/flatbuffers/samples/kotlin_sample.sh b/third_party/flatbuffers/samples/kotlin_sample.sh
new file mode 100755
index 0000000..30ca00a
--- /dev/null
+++ b/third_party/flatbuffers/samples/kotlin_sample.sh
@@ -0,0 +1,60 @@
+#!/bin/bash
+#
+# 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.
+#
+# Note: This script runs on Mac and Linux. It requires `kotlin` to be installed
+# and `flatc` to be built (using `cmake` in the root directory).
+
+sampledir=$(cd $(dirname $BASH_SOURCE) && pwd)
+rootdir=$(cd $sampledir/.. && pwd)
+currentdir=$(pwd)
+
+if [[ "$sampledir" != "$currentdir" ]]; then
+  echo Error: This script must be run from inside the $sampledir directory.
+  echo You executed it from the $currentdir directory.
+  exit 1
+fi
+
+# Run `flatc`. Note: This requires you to compile using `cmake` from the
+# root `/flatbuffers` directory.
+if [ -e ../flatc ]; then
+  echo "compiling now"
+  ../flatc --kotlin --gen-mutable monster.fbs
+elif [ -e ../Debug/flatc ]; then
+  ../Debug/flatc --kotlin --gen-mutable monster.fbs
+else
+  echo 'flatc' could not be found. Make sure to build FlatBuffers from the \
+       $rootdir directory.
+  exit 1
+fi
+
+echo Compiling and running the Kotlin sample
+
+all_kt_files=`find $sampledir -name "*.kt" -print`
+# Run test
+mkdir -v "${sampledir}/kotlin"
+echo Compiling Java Runtime
+javac ${rootdir}/java/com/google/flatbuffers/*.java -d ${sampledir}/kotlin
+echo Compiling Kotlin source
+kotlinc -classpath ${sampledir}/../java:${sampledir}/kotlin $all_kt_files SampleBinary.kt -include-runtime -d ${sampledir}/kotlin
+# Make jar
+echo Making jar
+jar cvf ${sampledir}/kotlin/kotlin_sample.jar -C ${sampledir}/kotlin . > /dev/null
+echo Running test
+kotlin -cp ${sampledir}/kotlin/kotlin_sample.jar SampleBinary
+
+# Cleanup temporary files.
+# rm -rf MyGame/
+# rm -rf ${sampledir}/kotlin
diff --git a/third_party/flatbuffers/samples/lua/MyGame/Sample/Color.lua b/third_party/flatbuffers/samples/lua/MyGame/Sample/Color.lua
new file mode 100644
index 0000000..8bf62e1
--- /dev/null
+++ b/third_party/flatbuffers/samples/lua/MyGame/Sample/Color.lua
@@ -0,0 +1,11 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Sample
+
+local Color = {
+    Red = 0,
+    Green = 1,
+    Blue = 2,
+}
+
+return Color -- return the module
\ No newline at end of file
diff --git a/third_party/flatbuffers/samples/lua/MyGame/Sample/Equipment.lua b/third_party/flatbuffers/samples/lua/MyGame/Sample/Equipment.lua
new file mode 100644
index 0000000..0a20b36
--- /dev/null
+++ b/third_party/flatbuffers/samples/lua/MyGame/Sample/Equipment.lua
@@ -0,0 +1,10 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Sample
+
+local Equipment = {
+    NONE = 0,
+    Weapon = 1,
+}
+
+return Equipment -- return the module
\ No newline at end of file
diff --git a/third_party/flatbuffers/samples/lua/MyGame/Sample/Monster.lua b/third_party/flatbuffers/samples/lua/MyGame/Sample/Monster.lua
new file mode 100644
index 0000000..b55c27e
--- /dev/null
+++ b/third_party/flatbuffers/samples/lua/MyGame/Sample/Monster.lua
@@ -0,0 +1,122 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Sample
+
+local flatbuffers = require('flatbuffers')
+
+local Monster = {} -- the module
+local Monster_mt = {} -- the class metatable
+
+function Monster.New()
+    local o = {}
+    setmetatable(o, {__index = Monster_mt})
+    return o
+end
+function Monster.GetRootAsMonster(buf, offset)
+    local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)
+    local o = Monster.New()
+    o:Init(buf, n + offset)
+    return o
+end
+function Monster_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function Monster_mt:Pos()
+    local o = self.view:Offset(4)
+    if o ~= 0 then
+        local x = o + self.view.pos
+        local obj = require('MyGame.Sample.Vec3').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function Monster_mt:Mana()
+    local o = self.view:Offset(6)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int16, o + self.view.pos)
+    end
+    return 150
+end
+function Monster_mt:Hp()
+    local o = self.view:Offset(8)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int16, o + self.view.pos)
+    end
+    return 100
+end
+function Monster_mt:Name()
+    local o = self.view:Offset(10)
+    if o ~= 0 then
+        return self.view:String(o + self.view.pos)
+    end
+end
+function Monster_mt:Inventory(j)
+    local o = self.view:Offset(14)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:Get(flatbuffers.N.Uint8, a + ((j-1) * 1))
+    end
+    return 0
+end
+function Monster_mt:InventoryLength()
+    local o = self.view:Offset(14)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:Color()
+    local o = self.view:Offset(16)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int8, o + self.view.pos)
+    end
+    return 2
+end
+function Monster_mt:Weapons(j)
+    local o = self.view:Offset(18)
+    if o ~= 0 then
+        local x = self.view:Vector(o)
+        x = x + ((j-1) * 4)
+        x = self.view:Indirect(x)
+        local obj = require('MyGame.Sample.Weapon').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function Monster_mt:WeaponsLength()
+    local o = self.view:Offset(18)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:EquippedType()
+    local o = self.view:Offset(20)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint8, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:Equipped()
+    local o = self.view:Offset(22)
+    if o ~= 0 then
+        local obj = flatbuffers.view.New(require('flatbuffers.binaryarray').New(0), 0)
+        self.view:Union(obj, o)
+        return obj
+    end
+end
+function Monster.Start(builder) builder:StartObject(10) end
+function Monster.AddPos(builder, pos) builder:PrependStructSlot(0, pos, 0) end
+function Monster.AddMana(builder, mana) builder:PrependInt16Slot(1, mana, 150) end
+function Monster.AddHp(builder, hp) builder:PrependInt16Slot(2, hp, 100) end
+function Monster.AddName(builder, name) builder:PrependUOffsetTRelativeSlot(3, name, 0) end
+function Monster.AddInventory(builder, inventory) builder:PrependUOffsetTRelativeSlot(5, inventory, 0) end
+function Monster.StartInventoryVector(builder, numElems) return builder:StartVector(1, numElems, 1) end
+function Monster.AddColor(builder, color) builder:PrependInt8Slot(6, color, 2) end
+function Monster.AddWeapons(builder, weapons) builder:PrependUOffsetTRelativeSlot(7, weapons, 0) end
+function Monster.StartWeaponsVector(builder, numElems) return builder:StartVector(4, numElems, 4) end
+function Monster.AddEquippedType(builder, equippedType) builder:PrependUint8Slot(8, equippedType, 0) end
+function Monster.AddEquipped(builder, equipped) builder:PrependUOffsetTRelativeSlot(9, equipped, 0) end
+function Monster.End(builder) return builder:EndObject() end
+
+return Monster -- return the module
\ No newline at end of file
diff --git a/third_party/flatbuffers/samples/lua/MyGame/Sample/Vec3.lua b/third_party/flatbuffers/samples/lua/MyGame/Sample/Vec3.lua
new file mode 100644
index 0000000..d42b055
--- /dev/null
+++ b/third_party/flatbuffers/samples/lua/MyGame/Sample/Vec3.lua
@@ -0,0 +1,35 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Sample
+
+local flatbuffers = require('flatbuffers')
+
+local Vec3 = {} -- the module
+local Vec3_mt = {} -- the class metatable
+
+function Vec3.New()
+    local o = {}
+    setmetatable(o, {__index = Vec3_mt})
+    return o
+end
+function Vec3_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function Vec3_mt:X()
+    return self.view:Get(flatbuffers.N.Float32, self.view.pos + 0)
+end
+function Vec3_mt:Y()
+    return self.view:Get(flatbuffers.N.Float32, self.view.pos + 4)
+end
+function Vec3_mt:Z()
+    return self.view:Get(flatbuffers.N.Float32, self.view.pos + 8)
+end
+function Vec3.CreateVec3(builder, x, y, z)
+    builder:Prep(4, 12)
+    builder:PrependFloat32(z)
+    builder:PrependFloat32(y)
+    builder:PrependFloat32(x)
+    return builder:Offset()
+end
+
+return Vec3 -- return the module
\ No newline at end of file
diff --git a/third_party/flatbuffers/samples/lua/MyGame/Sample/Weapon.lua b/third_party/flatbuffers/samples/lua/MyGame/Sample/Weapon.lua
new file mode 100644
index 0000000..60442b9
--- /dev/null
+++ b/third_party/flatbuffers/samples/lua/MyGame/Sample/Weapon.lua
@@ -0,0 +1,42 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Sample
+
+local flatbuffers = require('flatbuffers')
+
+local Weapon = {} -- the module
+local Weapon_mt = {} -- the class metatable
+
+function Weapon.New()
+    local o = {}
+    setmetatable(o, {__index = Weapon_mt})
+    return o
+end
+function Weapon.GetRootAsWeapon(buf, offset)
+    local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)
+    local o = Weapon.New()
+    o:Init(buf, n + offset)
+    return o
+end
+function Weapon_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function Weapon_mt:Name()
+    local o = self.view:Offset(4)
+    if o ~= 0 then
+        return self.view:String(o + self.view.pos)
+    end
+end
+function Weapon_mt:Damage()
+    local o = self.view:Offset(6)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int16, o + self.view.pos)
+    end
+    return 0
+end
+function Weapon.Start(builder) builder:StartObject(2) end
+function Weapon.AddName(builder, name) builder:PrependUOffsetTRelativeSlot(0, name, 0) end
+function Weapon.AddDamage(builder, damage) builder:PrependInt16Slot(1, damage, 0) end
+function Weapon.End(builder) return builder:EndObject() end
+
+return Weapon -- return the module
\ No newline at end of file
diff --git a/third_party/flatbuffers/samples/monster.bfbs b/third_party/flatbuffers/samples/monster.bfbs
new file mode 100644
index 0000000..061a17b
--- /dev/null
+++ b/third_party/flatbuffers/samples/monster.bfbs
Binary files differ
diff --git a/third_party/flatbuffers/samples/monster.fbs b/third_party/flatbuffers/samples/monster.fbs
new file mode 100644
index 0000000..af22451
--- /dev/null
+++ b/third_party/flatbuffers/samples/monster.fbs
@@ -0,0 +1,33 @@
+// Example IDL file for our monster's schema.
+
+namespace MyGame.Sample;
+
+enum Color:byte { Red = 0, Green, Blue = 2 }
+
+union Equipment { Weapon } // Optionally add more tables.
+
+struct Vec3 {
+  x:float;
+  y:float;
+  z:float;
+}
+
+table Monster {
+  pos:Vec3;
+  mana:short = 150;
+  hp:short = 100;
+  name:string;
+  friendly:bool = false (deprecated);
+  inventory:[ubyte];
+  color:Color = Blue;
+  weapons:[Weapon];
+  equipped:Equipment;
+  path:[Vec3];
+}
+
+table Weapon {
+  name:string;
+  damage:short;
+}
+
+root_type Monster;
diff --git a/third_party/flatbuffers/samples/monster_generated.h b/third_party/flatbuffers/samples/monster_generated.h
new file mode 100644
index 0000000..30115da
--- /dev/null
+++ b/third_party/flatbuffers/samples/monster_generated.h
@@ -0,0 +1,877 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_MONSTER_MYGAME_SAMPLE_H_
+#define FLATBUFFERS_GENERATED_MONSTER_MYGAME_SAMPLE_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+namespace MyGame {
+namespace Sample {
+
+struct Vec3;
+
+struct Monster;
+struct MonsterT;
+
+struct Weapon;
+struct WeaponT;
+
+bool operator==(const Vec3 &lhs, const Vec3 &rhs);
+bool operator!=(const Vec3 &lhs, const Vec3 &rhs);
+bool operator==(const MonsterT &lhs, const MonsterT &rhs);
+bool operator!=(const MonsterT &lhs, const MonsterT &rhs);
+bool operator==(const WeaponT &lhs, const WeaponT &rhs);
+bool operator!=(const WeaponT &lhs, const WeaponT &rhs);
+
+inline const flatbuffers::TypeTable *Vec3TypeTable();
+
+inline const flatbuffers::TypeTable *MonsterTypeTable();
+
+inline const flatbuffers::TypeTable *WeaponTypeTable();
+
+enum Color {
+  Color_Red = 0,
+  Color_Green = 1,
+  Color_Blue = 2,
+  Color_MIN = Color_Red,
+  Color_MAX = Color_Blue
+};
+
+inline const Color (&EnumValuesColor())[3] {
+  static const Color values[] = {
+    Color_Red,
+    Color_Green,
+    Color_Blue
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesColor() {
+  static const char * const names[4] = {
+    "Red",
+    "Green",
+    "Blue",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameColor(Color e) {
+  if (e < Color_Red || e > Color_Blue) return "";
+  const size_t index = static_cast<size_t>(e);
+  return EnumNamesColor()[index];
+}
+
+enum Equipment {
+  Equipment_NONE = 0,
+  Equipment_Weapon = 1,
+  Equipment_MIN = Equipment_NONE,
+  Equipment_MAX = Equipment_Weapon
+};
+
+inline const Equipment (&EnumValuesEquipment())[2] {
+  static const Equipment values[] = {
+    Equipment_NONE,
+    Equipment_Weapon
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesEquipment() {
+  static const char * const names[3] = {
+    "NONE",
+    "Weapon",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameEquipment(Equipment e) {
+  if (e < Equipment_NONE || e > Equipment_Weapon) return "";
+  const size_t index = static_cast<size_t>(e);
+  return EnumNamesEquipment()[index];
+}
+
+template<typename T> struct EquipmentTraits {
+  static const Equipment enum_value = Equipment_NONE;
+};
+
+template<> struct EquipmentTraits<MyGame::Sample::Weapon> {
+  static const Equipment enum_value = Equipment_Weapon;
+};
+
+struct EquipmentUnion {
+  Equipment type;
+  void *value;
+
+  EquipmentUnion() : type(Equipment_NONE), value(nullptr) {}
+  EquipmentUnion(EquipmentUnion&& u) FLATBUFFERS_NOEXCEPT :
+    type(Equipment_NONE), value(nullptr)
+    { std::swap(type, u.type); std::swap(value, u.value); }
+  EquipmentUnion(const EquipmentUnion &) FLATBUFFERS_NOEXCEPT;
+  EquipmentUnion &operator=(const EquipmentUnion &u) FLATBUFFERS_NOEXCEPT
+    { EquipmentUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; }
+  EquipmentUnion &operator=(EquipmentUnion &&u) FLATBUFFERS_NOEXCEPT
+    { std::swap(type, u.type); std::swap(value, u.value); return *this; }
+  ~EquipmentUnion() { Reset(); }
+
+  void Reset();
+
+#ifndef FLATBUFFERS_CPP98_STL
+  template <typename T>
+  void Set(T&& val) {
+    using RT = typename std::remove_reference<T>::type;
+    Reset();
+    type = EquipmentTraits<typename RT::TableType>::enum_value;
+    if (type != Equipment_NONE) {
+      value = new RT(std::forward<T>(val));
+    }
+  }
+#endif  // FLATBUFFERS_CPP98_STL
+
+  static void *UnPack(const void *obj, Equipment type, const flatbuffers::resolver_function_t *resolver);
+  flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const;
+
+  MyGame::Sample::WeaponT *AsWeapon() {
+    return type == Equipment_Weapon ?
+      reinterpret_cast<MyGame::Sample::WeaponT *>(value) : nullptr;
+  }
+  const MyGame::Sample::WeaponT *AsWeapon() const {
+    return type == Equipment_Weapon ?
+      reinterpret_cast<const MyGame::Sample::WeaponT *>(value) : nullptr;
+  }
+};
+
+
+inline bool operator==(const EquipmentUnion &lhs, const EquipmentUnion &rhs) {
+  if (lhs.type != rhs.type) return false;
+  switch (lhs.type) {
+    case Equipment_NONE: {
+      return true;
+    }
+    case Equipment_Weapon: {
+      return *(reinterpret_cast<const MyGame::Sample::WeaponT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Sample::WeaponT *>(rhs.value));
+    }
+    default: {
+      return false;
+    }
+  }
+}
+
+inline bool operator!=(const EquipmentUnion &lhs, const EquipmentUnion &rhs) {
+    return !(lhs == rhs);
+}
+
+bool VerifyEquipment(flatbuffers::Verifier &verifier, const void *obj, Equipment type);
+bool VerifyEquipmentVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Vec3 FLATBUFFERS_FINAL_CLASS {
+ private:
+  float x_;
+  float y_;
+  float z_;
+
+ public:
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return Vec3TypeTable();
+  }
+  Vec3() {
+    memset(static_cast<void *>(this), 0, sizeof(Vec3));
+  }
+  Vec3(float _x, float _y, float _z)
+      : x_(flatbuffers::EndianScalar(_x)),
+        y_(flatbuffers::EndianScalar(_y)),
+        z_(flatbuffers::EndianScalar(_z)) {
+  }
+  float x() const {
+    return flatbuffers::EndianScalar(x_);
+  }
+  void mutate_x(float _x) {
+    flatbuffers::WriteScalar(&x_, _x);
+  }
+  float y() const {
+    return flatbuffers::EndianScalar(y_);
+  }
+  void mutate_y(float _y) {
+    flatbuffers::WriteScalar(&y_, _y);
+  }
+  float z() const {
+    return flatbuffers::EndianScalar(z_);
+  }
+  void mutate_z(float _z) {
+    flatbuffers::WriteScalar(&z_, _z);
+  }
+};
+FLATBUFFERS_STRUCT_END(Vec3, 12);
+
+inline bool operator==(const Vec3 &lhs, const Vec3 &rhs) {
+  return
+      (lhs.x() == rhs.x()) &&
+      (lhs.y() == rhs.y()) &&
+      (lhs.z() == rhs.z());
+}
+
+inline bool operator!=(const Vec3 &lhs, const Vec3 &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct MonsterT : public flatbuffers::NativeTable {
+  typedef Monster TableType;
+  flatbuffers::unique_ptr<MyGame::Sample::Vec3> pos;
+  int16_t mana;
+  int16_t hp;
+  std::string name;
+  std::vector<uint8_t> inventory;
+  MyGame::Sample::Color color;
+  std::vector<flatbuffers::unique_ptr<MyGame::Sample::WeaponT>> weapons;
+  EquipmentUnion equipped;
+  std::vector<MyGame::Sample::Vec3> path;
+  MonsterT()
+      : mana(150),
+        hp(100),
+        color(MyGame::Sample::Color_Blue) {
+  }
+};
+
+inline bool operator==(const MonsterT &lhs, const MonsterT &rhs) {
+  return
+      (lhs.pos == rhs.pos) &&
+      (lhs.mana == rhs.mana) &&
+      (lhs.hp == rhs.hp) &&
+      (lhs.name == rhs.name) &&
+      (lhs.inventory == rhs.inventory) &&
+      (lhs.color == rhs.color) &&
+      (lhs.weapons == rhs.weapons) &&
+      (lhs.equipped == rhs.equipped) &&
+      (lhs.path == rhs.path);
+}
+
+inline bool operator!=(const MonsterT &lhs, const MonsterT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef MonsterT NativeTableType;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return MonsterTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_POS = 4,
+    VT_MANA = 6,
+    VT_HP = 8,
+    VT_NAME = 10,
+    VT_INVENTORY = 14,
+    VT_COLOR = 16,
+    VT_WEAPONS = 18,
+    VT_EQUIPPED_TYPE = 20,
+    VT_EQUIPPED = 22,
+    VT_PATH = 24
+  };
+  const MyGame::Sample::Vec3 *pos() const {
+    return GetStruct<const MyGame::Sample::Vec3 *>(VT_POS);
+  }
+  MyGame::Sample::Vec3 *mutable_pos() {
+    return GetStruct<MyGame::Sample::Vec3 *>(VT_POS);
+  }
+  int16_t mana() const {
+    return GetField<int16_t>(VT_MANA, 150);
+  }
+  bool mutate_mana(int16_t _mana) {
+    return SetField<int16_t>(VT_MANA, _mana, 150);
+  }
+  int16_t hp() const {
+    return GetField<int16_t>(VT_HP, 100);
+  }
+  bool mutate_hp(int16_t _hp) {
+    return SetField<int16_t>(VT_HP, _hp, 100);
+  }
+  const flatbuffers::String *name() const {
+    return GetPointer<const flatbuffers::String *>(VT_NAME);
+  }
+  flatbuffers::String *mutable_name() {
+    return GetPointer<flatbuffers::String *>(VT_NAME);
+  }
+  const flatbuffers::Vector<uint8_t> *inventory() const {
+    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_INVENTORY);
+  }
+  flatbuffers::Vector<uint8_t> *mutable_inventory() {
+    return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_INVENTORY);
+  }
+  MyGame::Sample::Color color() const {
+    return static_cast<MyGame::Sample::Color>(GetField<int8_t>(VT_COLOR, 2));
+  }
+  bool mutate_color(MyGame::Sample::Color _color) {
+    return SetField<int8_t>(VT_COLOR, static_cast<int8_t>(_color), 2);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<MyGame::Sample::Weapon>> *weapons() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<MyGame::Sample::Weapon>> *>(VT_WEAPONS);
+  }
+  flatbuffers::Vector<flatbuffers::Offset<MyGame::Sample::Weapon>> *mutable_weapons() {
+    return GetPointer<flatbuffers::Vector<flatbuffers::Offset<MyGame::Sample::Weapon>> *>(VT_WEAPONS);
+  }
+  MyGame::Sample::Equipment equipped_type() const {
+    return static_cast<MyGame::Sample::Equipment>(GetField<uint8_t>(VT_EQUIPPED_TYPE, 0));
+  }
+  bool mutate_equipped_type(MyGame::Sample::Equipment _equipped_type) {
+    return SetField<uint8_t>(VT_EQUIPPED_TYPE, static_cast<uint8_t>(_equipped_type), 0);
+  }
+  const void *equipped() const {
+    return GetPointer<const void *>(VT_EQUIPPED);
+  }
+  template<typename T> const T *equipped_as() const;
+  const MyGame::Sample::Weapon *equipped_as_Weapon() const {
+    return equipped_type() == MyGame::Sample::Equipment_Weapon ? static_cast<const MyGame::Sample::Weapon *>(equipped()) : nullptr;
+  }
+  void *mutable_equipped() {
+    return GetPointer<void *>(VT_EQUIPPED);
+  }
+  const flatbuffers::Vector<const MyGame::Sample::Vec3 *> *path() const {
+    return GetPointer<const flatbuffers::Vector<const MyGame::Sample::Vec3 *> *>(VT_PATH);
+  }
+  flatbuffers::Vector<const MyGame::Sample::Vec3 *> *mutable_path() {
+    return GetPointer<flatbuffers::Vector<const MyGame::Sample::Vec3 *> *>(VT_PATH);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<MyGame::Sample::Vec3>(verifier, VT_POS) &&
+           VerifyField<int16_t>(verifier, VT_MANA) &&
+           VerifyField<int16_t>(verifier, VT_HP) &&
+           VerifyOffset(verifier, VT_NAME) &&
+           verifier.VerifyString(name()) &&
+           VerifyOffset(verifier, VT_INVENTORY) &&
+           verifier.VerifyVector(inventory()) &&
+           VerifyField<int8_t>(verifier, VT_COLOR) &&
+           VerifyOffset(verifier, VT_WEAPONS) &&
+           verifier.VerifyVector(weapons()) &&
+           verifier.VerifyVectorOfTables(weapons()) &&
+           VerifyField<uint8_t>(verifier, VT_EQUIPPED_TYPE) &&
+           VerifyOffset(verifier, VT_EQUIPPED) &&
+           VerifyEquipment(verifier, equipped(), equipped_type()) &&
+           VerifyOffset(verifier, VT_PATH) &&
+           verifier.VerifyVector(path()) &&
+           verifier.EndTable();
+  }
+  MonsterT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<Monster> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+template<> inline const MyGame::Sample::Weapon *Monster::equipped_as<MyGame::Sample::Weapon>() const {
+  return equipped_as_Weapon();
+}
+
+struct MonsterBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_pos(const MyGame::Sample::Vec3 *pos) {
+    fbb_.AddStruct(Monster::VT_POS, pos);
+  }
+  void add_mana(int16_t mana) {
+    fbb_.AddElement<int16_t>(Monster::VT_MANA, mana, 150);
+  }
+  void add_hp(int16_t hp) {
+    fbb_.AddElement<int16_t>(Monster::VT_HP, hp, 100);
+  }
+  void add_name(flatbuffers::Offset<flatbuffers::String> name) {
+    fbb_.AddOffset(Monster::VT_NAME, name);
+  }
+  void add_inventory(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory) {
+    fbb_.AddOffset(Monster::VT_INVENTORY, inventory);
+  }
+  void add_color(MyGame::Sample::Color color) {
+    fbb_.AddElement<int8_t>(Monster::VT_COLOR, static_cast<int8_t>(color), 2);
+  }
+  void add_weapons(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Sample::Weapon>>> weapons) {
+    fbb_.AddOffset(Monster::VT_WEAPONS, weapons);
+  }
+  void add_equipped_type(MyGame::Sample::Equipment equipped_type) {
+    fbb_.AddElement<uint8_t>(Monster::VT_EQUIPPED_TYPE, static_cast<uint8_t>(equipped_type), 0);
+  }
+  void add_equipped(flatbuffers::Offset<void> equipped) {
+    fbb_.AddOffset(Monster::VT_EQUIPPED, equipped);
+  }
+  void add_path(flatbuffers::Offset<flatbuffers::Vector<const MyGame::Sample::Vec3 *>> path) {
+    fbb_.AddOffset(Monster::VT_PATH, path);
+  }
+  explicit MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  MonsterBuilder &operator=(const MonsterBuilder &);
+  flatbuffers::Offset<Monster> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Monster>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Monster> CreateMonster(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const MyGame::Sample::Vec3 *pos = 0,
+    int16_t mana = 150,
+    int16_t hp = 100,
+    flatbuffers::Offset<flatbuffers::String> name = 0,
+    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory = 0,
+    MyGame::Sample::Color color = MyGame::Sample::Color_Blue,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Sample::Weapon>>> weapons = 0,
+    MyGame::Sample::Equipment equipped_type = MyGame::Sample::Equipment_NONE,
+    flatbuffers::Offset<void> equipped = 0,
+    flatbuffers::Offset<flatbuffers::Vector<const MyGame::Sample::Vec3 *>> path = 0) {
+  MonsterBuilder builder_(_fbb);
+  builder_.add_path(path);
+  builder_.add_equipped(equipped);
+  builder_.add_weapons(weapons);
+  builder_.add_inventory(inventory);
+  builder_.add_name(name);
+  builder_.add_pos(pos);
+  builder_.add_hp(hp);
+  builder_.add_mana(mana);
+  builder_.add_equipped_type(equipped_type);
+  builder_.add_color(color);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Monster> CreateMonsterDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const MyGame::Sample::Vec3 *pos = 0,
+    int16_t mana = 150,
+    int16_t hp = 100,
+    const char *name = nullptr,
+    const std::vector<uint8_t> *inventory = nullptr,
+    MyGame::Sample::Color color = MyGame::Sample::Color_Blue,
+    const std::vector<flatbuffers::Offset<MyGame::Sample::Weapon>> *weapons = nullptr,
+    MyGame::Sample::Equipment equipped_type = MyGame::Sample::Equipment_NONE,
+    flatbuffers::Offset<void> equipped = 0,
+    const std::vector<MyGame::Sample::Vec3> *path = nullptr) {
+  auto name__ = name ? _fbb.CreateString(name) : 0;
+  auto inventory__ = inventory ? _fbb.CreateVector<uint8_t>(*inventory) : 0;
+  auto weapons__ = weapons ? _fbb.CreateVector<flatbuffers::Offset<MyGame::Sample::Weapon>>(*weapons) : 0;
+  auto path__ = path ? _fbb.CreateVectorOfStructs<MyGame::Sample::Vec3>(*path) : 0;
+  return MyGame::Sample::CreateMonster(
+      _fbb,
+      pos,
+      mana,
+      hp,
+      name__,
+      inventory__,
+      color,
+      weapons__,
+      equipped_type,
+      equipped,
+      path__);
+}
+
+flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+struct WeaponT : public flatbuffers::NativeTable {
+  typedef Weapon TableType;
+  std::string name;
+  int16_t damage;
+  WeaponT()
+      : damage(0) {
+  }
+};
+
+inline bool operator==(const WeaponT &lhs, const WeaponT &rhs) {
+  return
+      (lhs.name == rhs.name) &&
+      (lhs.damage == rhs.damage);
+}
+
+inline bool operator!=(const WeaponT &lhs, const WeaponT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct Weapon FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef WeaponT NativeTableType;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return WeaponTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_NAME = 4,
+    VT_DAMAGE = 6
+  };
+  const flatbuffers::String *name() const {
+    return GetPointer<const flatbuffers::String *>(VT_NAME);
+  }
+  flatbuffers::String *mutable_name() {
+    return GetPointer<flatbuffers::String *>(VT_NAME);
+  }
+  int16_t damage() const {
+    return GetField<int16_t>(VT_DAMAGE, 0);
+  }
+  bool mutate_damage(int16_t _damage) {
+    return SetField<int16_t>(VT_DAMAGE, _damage, 0);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffset(verifier, VT_NAME) &&
+           verifier.VerifyString(name()) &&
+           VerifyField<int16_t>(verifier, VT_DAMAGE) &&
+           verifier.EndTable();
+  }
+  WeaponT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(WeaponT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<Weapon> Pack(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct WeaponBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_name(flatbuffers::Offset<flatbuffers::String> name) {
+    fbb_.AddOffset(Weapon::VT_NAME, name);
+  }
+  void add_damage(int16_t damage) {
+    fbb_.AddElement<int16_t>(Weapon::VT_DAMAGE, damage, 0);
+  }
+  explicit WeaponBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  WeaponBuilder &operator=(const WeaponBuilder &);
+  flatbuffers::Offset<Weapon> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Weapon>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Weapon> CreateWeapon(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<flatbuffers::String> name = 0,
+    int16_t damage = 0) {
+  WeaponBuilder builder_(_fbb);
+  builder_.add_name(name);
+  builder_.add_damage(damage);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Weapon> CreateWeaponDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const char *name = nullptr,
+    int16_t damage = 0) {
+  auto name__ = name ? _fbb.CreateString(name) : 0;
+  return MyGame::Sample::CreateWeapon(
+      _fbb,
+      name__,
+      damage);
+}
+
+flatbuffers::Offset<Weapon> CreateWeapon(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = new MonsterT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+inline void Monster::UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = pos(); if (_e) _o->pos = flatbuffers::unique_ptr<MyGame::Sample::Vec3>(new MyGame::Sample::Vec3(*_e)); };
+  { auto _e = mana(); _o->mana = _e; };
+  { auto _e = hp(); _o->hp = _e; };
+  { auto _e = name(); if (_e) _o->name = _e->str(); };
+  { auto _e = inventory(); if (_e) { _o->inventory.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->inventory[_i] = _e->Get(_i); } } };
+  { auto _e = color(); _o->color = _e; };
+  { auto _e = weapons(); if (_e) { _o->weapons.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->weapons[_i] = flatbuffers::unique_ptr<MyGame::Sample::WeaponT>(_e->Get(_i)->UnPack(_resolver)); } } };
+  { auto _e = equipped_type(); _o->equipped.type = _e; };
+  { auto _e = equipped(); if (_e) _o->equipped.value = EquipmentUnion::UnPack(_e, equipped_type(), _resolver); };
+  { auto _e = path(); if (_e) { _o->path.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->path[_i] = *_e->Get(_i); } } };
+}
+
+inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateMonster(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const MonsterT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _pos = _o->pos ? _o->pos.get() : 0;
+  auto _mana = _o->mana;
+  auto _hp = _o->hp;
+  auto _name = _o->name.empty() ? 0 : _fbb.CreateString(_o->name);
+  auto _inventory = _o->inventory.size() ? _fbb.CreateVector(_o->inventory) : 0;
+  auto _color = _o->color;
+  auto _weapons = _o->weapons.size() ? _fbb.CreateVector<flatbuffers::Offset<MyGame::Sample::Weapon>> (_o->weapons.size(), [](size_t i, _VectorArgs *__va) { return CreateWeapon(*__va->__fbb, __va->__o->weapons[i].get(), __va->__rehasher); }, &_va ) : 0;
+  auto _equipped_type = _o->equipped.type;
+  auto _equipped = _o->equipped.Pack(_fbb);
+  auto _path = _o->path.size() ? _fbb.CreateVectorOfStructs(_o->path) : 0;
+  return MyGame::Sample::CreateMonster(
+      _fbb,
+      _pos,
+      _mana,
+      _hp,
+      _name,
+      _inventory,
+      _color,
+      _weapons,
+      _equipped_type,
+      _equipped,
+      _path);
+}
+
+inline WeaponT *Weapon::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = new WeaponT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+inline void Weapon::UnPackTo(WeaponT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = name(); if (_e) _o->name = _e->str(); };
+  { auto _e = damage(); _o->damage = _e; };
+}
+
+inline flatbuffers::Offset<Weapon> Weapon::Pack(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateWeapon(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<Weapon> CreateWeapon(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const WeaponT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _name = _o->name.empty() ? 0 : _fbb.CreateString(_o->name);
+  auto _damage = _o->damage;
+  return MyGame::Sample::CreateWeapon(
+      _fbb,
+      _name,
+      _damage);
+}
+
+inline bool VerifyEquipment(flatbuffers::Verifier &verifier, const void *obj, Equipment type) {
+  switch (type) {
+    case Equipment_NONE: {
+      return true;
+    }
+    case Equipment_Weapon: {
+      auto ptr = reinterpret_cast<const MyGame::Sample::Weapon *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    default: return false;
+  }
+}
+
+inline bool VerifyEquipmentVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
+  if (!values || !types) return !values && !types;
+  if (values->size() != types->size()) return false;
+  for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+    if (!VerifyEquipment(
+        verifier,  values->Get(i), types->GetEnum<Equipment>(i))) {
+      return false;
+    }
+  }
+  return true;
+}
+
+inline void *EquipmentUnion::UnPack(const void *obj, Equipment type, const flatbuffers::resolver_function_t *resolver) {
+  switch (type) {
+    case Equipment_Weapon: {
+      auto ptr = reinterpret_cast<const MyGame::Sample::Weapon *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    default: return nullptr;
+  }
+}
+
+inline flatbuffers::Offset<void> EquipmentUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const {
+  switch (type) {
+    case Equipment_Weapon: {
+      auto ptr = reinterpret_cast<const MyGame::Sample::WeaponT *>(value);
+      return CreateWeapon(_fbb, ptr, _rehasher).Union();
+    }
+    default: return 0;
+  }
+}
+
+inline EquipmentUnion::EquipmentUnion(const EquipmentUnion &u) FLATBUFFERS_NOEXCEPT : type(u.type), value(nullptr) {
+  switch (type) {
+    case Equipment_Weapon: {
+      value = new MyGame::Sample::WeaponT(*reinterpret_cast<MyGame::Sample::WeaponT *>(u.value));
+      break;
+    }
+    default:
+      break;
+  }
+}
+
+inline void EquipmentUnion::Reset() {
+  switch (type) {
+    case Equipment_Weapon: {
+      auto ptr = reinterpret_cast<MyGame::Sample::WeaponT *>(value);
+      delete ptr;
+      break;
+    }
+    default: break;
+  }
+  value = nullptr;
+  type = Equipment_NONE;
+}
+
+inline const flatbuffers::TypeTable *ColorTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_CHAR, 0, 0 },
+    { flatbuffers::ET_CHAR, 0, 0 },
+    { flatbuffers::ET_CHAR, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Sample::ColorTypeTable
+  };
+  static const char * const names[] = {
+    "Red",
+    "Green",
+    "Blue"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_ENUM, 3, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *EquipmentTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 0, -1 },
+    { flatbuffers::ET_SEQUENCE, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Sample::WeaponTypeTable
+  };
+  static const char * const names[] = {
+    "NONE",
+    "Weapon"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_UNION, 2, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *Vec3TypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 }
+  };
+  static const int64_t values[] = { 0, 4, 8, 12 };
+  static const char * const names[] = {
+    "x",
+    "y",
+    "z"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_STRUCT, 3, type_codes, nullptr, values, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *MonsterTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 0, 0 },
+    { flatbuffers::ET_SHORT, 0, -1 },
+    { flatbuffers::ET_SHORT, 0, -1 },
+    { flatbuffers::ET_STRING, 0, -1 },
+    { flatbuffers::ET_BOOL, 0, -1 },
+    { flatbuffers::ET_UCHAR, 1, -1 },
+    { flatbuffers::ET_CHAR, 0, 1 },
+    { flatbuffers::ET_SEQUENCE, 1, 2 },
+    { flatbuffers::ET_UTYPE, 0, 3 },
+    { flatbuffers::ET_SEQUENCE, 0, 3 },
+    { flatbuffers::ET_SEQUENCE, 1, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Sample::Vec3TypeTable,
+    MyGame::Sample::ColorTypeTable,
+    MyGame::Sample::WeaponTypeTable,
+    MyGame::Sample::EquipmentTypeTable
+  };
+  static const char * const names[] = {
+    "pos",
+    "mana",
+    "hp",
+    "name",
+    "friendly",
+    "inventory",
+    "color",
+    "weapons",
+    "equipped_type",
+    "equipped",
+    "path"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 11, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *WeaponTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_STRING, 0, -1 },
+    { flatbuffers::ET_SHORT, 0, -1 }
+  };
+  static const char * const names[] = {
+    "name",
+    "damage"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 2, type_codes, nullptr, nullptr, names
+  };
+  return &tt;
+}
+
+inline const MyGame::Sample::Monster *GetMonster(const void *buf) {
+  return flatbuffers::GetRoot<MyGame::Sample::Monster>(buf);
+}
+
+inline const MyGame::Sample::Monster *GetSizePrefixedMonster(const void *buf) {
+  return flatbuffers::GetSizePrefixedRoot<MyGame::Sample::Monster>(buf);
+}
+
+inline Monster *GetMutableMonster(void *buf) {
+  return flatbuffers::GetMutableRoot<Monster>(buf);
+}
+
+inline bool VerifyMonsterBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifyBuffer<MyGame::Sample::Monster>(nullptr);
+}
+
+inline bool VerifySizePrefixedMonsterBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifySizePrefixedBuffer<MyGame::Sample::Monster>(nullptr);
+}
+
+inline void FinishMonsterBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<MyGame::Sample::Monster> root) {
+  fbb.Finish(root);
+}
+
+inline void FinishSizePrefixedMonsterBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<MyGame::Sample::Monster> root) {
+  fbb.FinishSizePrefixed(root);
+}
+
+inline flatbuffers::unique_ptr<MyGame::Sample::MonsterT> UnPackMonster(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return flatbuffers::unique_ptr<MyGame::Sample::MonsterT>(GetMonster(buf)->UnPack(res));
+}
+
+inline flatbuffers::unique_ptr<MyGame::Sample::MonsterT> UnPackSizePrefixedMonster(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return flatbuffers::unique_ptr<MyGame::Sample::MonsterT>(GetSizePrefixedMonster(buf)->UnPack(res));
+}
+
+}  // namespace Sample
+}  // namespace MyGame
+
+#endif  // FLATBUFFERS_GENERATED_MONSTER_MYGAME_SAMPLE_H_
diff --git a/third_party/flatbuffers/samples/monster_generated.lobster b/third_party/flatbuffers/samples/monster_generated.lobster
new file mode 100644
index 0000000..702cdd4
--- /dev/null
+++ b/third_party/flatbuffers/samples/monster_generated.lobster
@@ -0,0 +1,143 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+import flatbuffers
+
+namespace MyGame_Sample
+
+enum Color:
+    Color_Red = 0
+    Color_Green = 1
+    Color_Blue = 2
+
+enum Equipment:
+    Equipment_NONE = 0
+    Equipment_Weapon = 1
+
+class Vec3
+
+class Monster
+
+class Weapon
+
+class Vec3 : flatbuffers_handle
+    def x():
+        return buf_.read_float32_le(pos_ + 0)
+    def y():
+        return buf_.read_float32_le(pos_ + 4)
+    def z():
+        return buf_.read_float32_le(pos_ + 8)
+
+def CreateVec3(b_:flatbuffers_builder, x:float, y:float, z:float):
+    b_.Prep(4, 12)
+    b_.PrependFloat32(z)
+    b_.PrependFloat32(y)
+    b_.PrependFloat32(x)
+    return b_.Offset()
+
+class Monster : flatbuffers_handle
+    def pos():
+        let o = buf_.flatbuffers_field_struct(pos_, 4)
+        return if o: MyGame_Sample_Vec3 { buf_, o } else: nil
+    def mana():
+        return buf_.flatbuffers_field_int16(pos_, 6, 150)
+    def hp():
+        return buf_.flatbuffers_field_int16(pos_, 8, 100)
+    def name():
+        return buf_.flatbuffers_field_string(pos_, 10)
+    def inventory(i:int):
+        return buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 14) + i * 1)
+    def inventory_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 14)
+    def color():
+        return Color(buf_.flatbuffers_field_int8(pos_, 16, 2))
+    def weapons(i:int):
+        return MyGame_Sample_Weapon { buf_, buf_.flatbuffers_indirect(buf_.flatbuffers_field_vector(pos_, 18) + i * 4) }
+    def weapons_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 18)
+    def equipped_type():
+        return Equipment(buf_.flatbuffers_field_int8(pos_, 20, 0))
+    def equipped_as_Weapon():
+        return MyGame_Sample_Weapon { buf_, buf_.flatbuffers_field_table(pos_, 22) }
+    def path(i:int):
+        return MyGame_Sample_Vec3 { buf_, buf_.flatbuffers_field_vector(pos_, 24) + i * 12 }
+    def path_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 24)
+
+def GetRootAsMonster(buf:string): return Monster { buf, buf.flatbuffers_indirect(0) }
+
+struct MonsterBuilder:
+    b_:flatbuffers_builder
+    def start():
+        b_.StartObject(11)
+        return this
+    def add_pos(pos:flatbuffers_offset):
+        b_.PrependStructSlot(0, pos)
+        return this
+    def add_mana(mana:int):
+        b_.PrependInt16Slot(1, mana, 150)
+        return this
+    def add_hp(hp:int):
+        b_.PrependInt16Slot(2, hp, 100)
+        return this
+    def add_name(name:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(3, name)
+        return this
+    def add_inventory(inventory:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(5, inventory)
+        return this
+    def add_color(color:Color):
+        b_.PrependInt8Slot(6, color, 2)
+        return this
+    def add_weapons(weapons:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(7, weapons)
+        return this
+    def add_equipped_type(equipped_type:Equipment):
+        b_.PrependUint8Slot(8, equipped_type, 0)
+        return this
+    def add_equipped(equipped:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(9, equipped)
+        return this
+    def add_path(path:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(10, path)
+        return this
+    def end():
+        return b_.EndObject()
+
+def MonsterStartInventoryVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(1, n_, 1)
+def MonsterCreateInventoryVector(b_:flatbuffers_builder, v_:[int]):
+    b_.StartVector(1, v_.length, 1)
+    reverse(v_) e_: b_.PrependUint8(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartWeaponsVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(4, n_, 4)
+def MonsterCreateWeaponsVector(b_:flatbuffers_builder, v_:[flatbuffers_offset]):
+    b_.StartVector(4, v_.length, 4)
+    reverse(v_) e_: b_.PrependUOffsetTRelative(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartPathVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(12, n_, 4)
+
+class Weapon : flatbuffers_handle
+    def name():
+        return buf_.flatbuffers_field_string(pos_, 4)
+    def damage():
+        return buf_.flatbuffers_field_int16(pos_, 6, 0)
+
+def GetRootAsWeapon(buf:string): return Weapon { buf, buf.flatbuffers_indirect(0) }
+
+struct WeaponBuilder:
+    b_:flatbuffers_builder
+    def start():
+        b_.StartObject(2)
+        return this
+    def add_name(name:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(0, name)
+        return this
+    def add_damage(damage:int):
+        b_.PrependInt16Slot(1, damage, 0)
+        return this
+    def end():
+        return b_.EndObject()
+
diff --git a/third_party/flatbuffers/samples/monster_generated.rs b/third_party/flatbuffers/samples/monster_generated.rs
new file mode 100644
index 0000000..9ec573c
--- /dev/null
+++ b/third_party/flatbuffers/samples/monster_generated.rs
@@ -0,0 +1,507 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+pub mod my_game {
+  #![allow(dead_code)]
+  #![allow(unused_imports)]
+
+  use std::mem;
+  use std::marker::PhantomData;
+  use std::cmp::Ordering;
+
+  extern crate flatbuffers;
+  use self::flatbuffers::EndianScalar;
+pub mod sample {
+  #![allow(dead_code)]
+  #![allow(unused_imports)]
+
+  use std::mem;
+  use std::marker::PhantomData;
+  use std::cmp::Ordering;
+
+  extern crate flatbuffers;
+  use self::flatbuffers::EndianScalar;
+
+#[allow(non_camel_case_types)]
+#[repr(i8)]
+#[derive(Clone, Copy, PartialEq, Debug)]
+pub enum Color {
+  Red = 0,
+  Green = 1,
+  Blue = 2
+}
+
+const ENUM_MIN_COLOR: i8 = 0;
+const ENUM_MAX_COLOR: i8 = 2;
+
+impl<'a> flatbuffers::Follow<'a> for Color {
+  type Inner = Self;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    flatbuffers::read_scalar_at::<Self>(buf, loc)
+  }
+}
+
+impl flatbuffers::EndianScalar for Color {
+  #[inline]
+  fn to_little_endian(self) -> Self {
+    let n = i8::to_le(self as i8);
+    let p = &n as *const i8 as *const Color;
+    unsafe { *p }
+  }
+  #[inline]
+  fn from_little_endian(self) -> Self {
+    let n = i8::from_le(self as i8);
+    let p = &n as *const i8 as *const Color;
+    unsafe { *p }
+  }
+}
+
+impl flatbuffers::Push for Color {
+    type Output = Color;
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        flatbuffers::emplace_scalar::<Color>(dst, *self);
+    }
+}
+
+#[allow(non_camel_case_types)]
+const ENUM_VALUES_COLOR:[Color; 3] = [
+  Color::Red,
+  Color::Green,
+  Color::Blue
+];
+
+#[allow(non_camel_case_types)]
+const ENUM_NAMES_COLOR:[&'static str; 3] = [
+    "Red",
+    "Green",
+    "Blue"
+];
+
+pub fn enum_name_color(e: Color) -> &'static str {
+  let index: usize = e as usize;
+  ENUM_NAMES_COLOR[index]
+}
+
+#[allow(non_camel_case_types)]
+#[repr(u8)]
+#[derive(Clone, Copy, PartialEq, Debug)]
+pub enum Equipment {
+  NONE = 0,
+  Weapon = 1
+}
+
+const ENUM_MIN_EQUIPMENT: u8 = 0;
+const ENUM_MAX_EQUIPMENT: u8 = 1;
+
+impl<'a> flatbuffers::Follow<'a> for Equipment {
+  type Inner = Self;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    flatbuffers::read_scalar_at::<Self>(buf, loc)
+  }
+}
+
+impl flatbuffers::EndianScalar for Equipment {
+  #[inline]
+  fn to_little_endian(self) -> Self {
+    let n = u8::to_le(self as u8);
+    let p = &n as *const u8 as *const Equipment;
+    unsafe { *p }
+  }
+  #[inline]
+  fn from_little_endian(self) -> Self {
+    let n = u8::from_le(self as u8);
+    let p = &n as *const u8 as *const Equipment;
+    unsafe { *p }
+  }
+}
+
+impl flatbuffers::Push for Equipment {
+    type Output = Equipment;
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        flatbuffers::emplace_scalar::<Equipment>(dst, *self);
+    }
+}
+
+#[allow(non_camel_case_types)]
+const ENUM_VALUES_EQUIPMENT:[Equipment; 2] = [
+  Equipment::NONE,
+  Equipment::Weapon
+];
+
+#[allow(non_camel_case_types)]
+const ENUM_NAMES_EQUIPMENT:[&'static str; 2] = [
+    "NONE",
+    "Weapon"
+];
+
+pub fn enum_name_equipment(e: Equipment) -> &'static str {
+  let index: usize = e as usize;
+  ENUM_NAMES_EQUIPMENT[index]
+}
+
+pub struct EquipmentUnionTableOffset {}
+// struct Vec3, aligned to 4
+#[repr(C, align(4))]
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub struct Vec3 {
+  x_: f32,
+  y_: f32,
+  z_: f32,
+} // pub struct Vec3
+impl flatbuffers::SafeSliceAccess for Vec3 {}
+impl<'a> flatbuffers::Follow<'a> for Vec3 {
+  type Inner = &'a Vec3;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    <&'a Vec3>::follow(buf, loc)
+    //flatbuffers::follow_cast_ref::<Vec3>(buf, loc)
+  }
+}
+impl<'a> flatbuffers::Follow<'a> for &'a Vec3 {
+  type Inner = &'a Vec3;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    flatbuffers::follow_cast_ref::<Vec3>(buf, loc)
+  }
+}
+impl<'b> flatbuffers::Push for Vec3 {
+    type Output = Vec3;
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        let src = unsafe {
+            ::std::slice::from_raw_parts(self as *const Vec3 as *const u8, Self::size())
+        };
+        dst.copy_from_slice(src);
+    }
+}
+impl<'b> flatbuffers::Push for &'b Vec3 {
+    type Output = Vec3;
+
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        let src = unsafe {
+            ::std::slice::from_raw_parts(*self as *const Vec3 as *const u8, Self::size())
+        };
+        dst.copy_from_slice(src);
+    }
+}
+
+
+impl Vec3 {
+  pub fn new<'a>(_x: f32, _y: f32, _z: f32) -> Self {
+    Vec3 {
+      x_: _x.to_little_endian(),
+      y_: _y.to_little_endian(),
+      z_: _z.to_little_endian(),
+
+    }
+  }
+  pub fn x<'a>(&'a self) -> f32 {
+    self.x_.from_little_endian()
+  }
+  pub fn y<'a>(&'a self) -> f32 {
+    self.y_.from_little_endian()
+  }
+  pub fn z<'a>(&'a self) -> f32 {
+    self.z_.from_little_endian()
+  }
+}
+
+pub enum MonsterOffset {}
+#[derive(Copy, Clone, Debug, PartialEq)]
+
+pub struct Monster<'a> {
+  pub _tab: flatbuffers::Table<'a>,
+}
+
+impl<'a> flatbuffers::Follow<'a> for Monster<'a> {
+    type Inner = Monster<'a>;
+    #[inline]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        Self {
+            _tab: flatbuffers::Table { buf: buf, loc: loc },
+        }
+    }
+}
+
+impl<'a> Monster<'a> {
+    #[inline]
+    pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
+        Monster {
+            _tab: table,
+        }
+    }
+    #[allow(unused_mut)]
+    pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
+        _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
+        args: &'args MonsterArgs<'args>) -> flatbuffers::WIPOffset<Monster<'bldr>> {
+      let mut builder = MonsterBuilder::new(_fbb);
+      if let Some(x) = args.equipped { builder.add_equipped(x); }
+      if let Some(x) = args.weapons { builder.add_weapons(x); }
+      if let Some(x) = args.inventory { builder.add_inventory(x); }
+      if let Some(x) = args.name { builder.add_name(x); }
+      if let Some(x) = args.pos { builder.add_pos(x); }
+      builder.add_hp(args.hp);
+      builder.add_mana(args.mana);
+      builder.add_equipped_type(args.equipped_type);
+      builder.add_color(args.color);
+      builder.finish()
+    }
+
+    pub const VT_POS: flatbuffers::VOffsetT = 4;
+    pub const VT_MANA: flatbuffers::VOffsetT = 6;
+    pub const VT_HP: flatbuffers::VOffsetT = 8;
+    pub const VT_NAME: flatbuffers::VOffsetT = 10;
+    pub const VT_INVENTORY: flatbuffers::VOffsetT = 14;
+    pub const VT_COLOR: flatbuffers::VOffsetT = 16;
+    pub const VT_WEAPONS: flatbuffers::VOffsetT = 18;
+    pub const VT_EQUIPPED_TYPE: flatbuffers::VOffsetT = 20;
+    pub const VT_EQUIPPED: flatbuffers::VOffsetT = 22;
+
+  #[inline]
+  pub fn pos(&'a self) -> Option<&'a Vec3> {
+    self._tab.get::<Vec3>(Monster::VT_POS, None)
+  }
+  #[inline]
+  pub fn mana(&'a self) -> i16 {
+    self._tab.get::<i16>(Monster::VT_MANA, Some(150)).unwrap()
+  }
+  #[inline]
+  pub fn hp(&'a self) -> i16 {
+    self._tab.get::<i16>(Monster::VT_HP, Some(100)).unwrap()
+  }
+  #[inline]
+  pub fn name(&'a self) -> Option<&'a str> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(Monster::VT_NAME, None)
+  }
+  #[inline]
+  pub fn inventory(&'a self) -> Option<&'a [u8]> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, u8>>>(Monster::VT_INVENTORY, None).map(|v| v.safe_slice())
+  }
+  #[inline]
+  pub fn color(&'a self) -> Color {
+    self._tab.get::<Color>(Monster::VT_COLOR, Some(Color::Blue)).unwrap()
+  }
+  #[inline]
+  pub fn weapons(&'a self) -> Option<flatbuffers::Vector<flatbuffers::ForwardsUOffset<Weapon<'a>>>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<flatbuffers::ForwardsUOffset<Weapon<'a>>>>>(Monster::VT_WEAPONS, None)
+  }
+  #[inline]
+  pub fn equipped_type(&'a self) -> Equipment {
+    self._tab.get::<Equipment>(Monster::VT_EQUIPPED_TYPE, Some(Equipment::NONE)).unwrap()
+  }
+  #[inline]
+  pub fn equipped(&'a self) -> Option<flatbuffers::Table<'a>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Table<'a>>>(Monster::VT_EQUIPPED, None)
+  }
+  #[inline]
+  #[allow(non_snake_case)]
+  pub fn equipped_as_weapon(&'a self) -> Option<Weapon> {
+    if self.equipped_type() == Equipment::Weapon {
+      self.equipped().map(|u| Weapon::init_from_table(u))
+    } else {
+      None
+    }
+  }
+
+}
+
+pub struct MonsterArgs<'a> {
+    pub pos: Option<&'a  Vec3>,
+    pub mana: i16,
+    pub hp: i16,
+    pub name: Option<flatbuffers::WIPOffset<&'a  str>>,
+    pub inventory: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a ,  u8>>>,
+    pub color: Color,
+    pub weapons: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a , flatbuffers::ForwardsUOffset<Weapon<'a >>>>>,
+    pub equipped_type: Equipment,
+    pub equipped: Option<flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>>,
+}
+impl<'a> Default for MonsterArgs<'a> {
+    #[inline]
+    fn default() -> Self {
+        MonsterArgs {
+            pos: None,
+            mana: 150,
+            hp: 100,
+            name: None,
+            inventory: None,
+            color: Color::Blue,
+            weapons: None,
+            equipped_type: Equipment::NONE,
+            equipped: None,
+        }
+    }
+}
+pub struct MonsterBuilder<'a: 'b, 'b> {
+  fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+  start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
+}
+impl<'a: 'b, 'b> MonsterBuilder<'a, 'b> {
+  #[inline]
+  pub fn add_pos(&mut self, pos: &'b  Vec3) {
+    self.fbb_.push_slot_always::<&Vec3>(Monster::VT_POS, pos);
+  }
+  #[inline]
+  pub fn add_mana(&mut self, mana: i16) {
+    self.fbb_.push_slot::<i16>(Monster::VT_MANA, mana, 150);
+  }
+  #[inline]
+  pub fn add_hp(&mut self, hp: i16) {
+    self.fbb_.push_slot::<i16>(Monster::VT_HP, hp, 100);
+  }
+  #[inline]
+  pub fn add_name(&mut self, name: flatbuffers::WIPOffset<&'b  str>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_NAME, name);
+  }
+  #[inline]
+  pub fn add_inventory(&mut self, inventory: flatbuffers::WIPOffset<flatbuffers::Vector<'b , u8>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_INVENTORY, inventory);
+  }
+  #[inline]
+  pub fn add_color(&mut self, color: Color) {
+    self.fbb_.push_slot::<Color>(Monster::VT_COLOR, color, Color::Blue);
+  }
+  #[inline]
+  pub fn add_weapons(&mut self, weapons: flatbuffers::WIPOffset<flatbuffers::Vector<'b , flatbuffers::ForwardsUOffset<Weapon<'b >>>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_WEAPONS, weapons);
+  }
+  #[inline]
+  pub fn add_equipped_type(&mut self, equipped_type: Equipment) {
+    self.fbb_.push_slot::<Equipment>(Monster::VT_EQUIPPED_TYPE, equipped_type, Equipment::NONE);
+  }
+  #[inline]
+  pub fn add_equipped(&mut self, equipped: flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_EQUIPPED, equipped);
+  }
+  #[inline]
+  pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> MonsterBuilder<'a, 'b> {
+    let start = _fbb.start_table();
+    MonsterBuilder {
+      fbb_: _fbb,
+      start_: start,
+    }
+  }
+  #[inline]
+  pub fn finish(self) -> flatbuffers::WIPOffset<Monster<'a>> {
+    let o = self.fbb_.end_table(self.start_);
+    flatbuffers::WIPOffset::new(o.value())
+  }
+}
+
+pub enum WeaponOffset {}
+#[derive(Copy, Clone, Debug, PartialEq)]
+
+pub struct Weapon<'a> {
+  pub _tab: flatbuffers::Table<'a>,
+}
+
+impl<'a> flatbuffers::Follow<'a> for Weapon<'a> {
+    type Inner = Weapon<'a>;
+    #[inline]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        Self {
+            _tab: flatbuffers::Table { buf: buf, loc: loc },
+        }
+    }
+}
+
+impl<'a> Weapon<'a> {
+    #[inline]
+    pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
+        Weapon {
+            _tab: table,
+        }
+    }
+    #[allow(unused_mut)]
+    pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
+        _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
+        args: &'args WeaponArgs<'args>) -> flatbuffers::WIPOffset<Weapon<'bldr>> {
+      let mut builder = WeaponBuilder::new(_fbb);
+      if let Some(x) = args.name { builder.add_name(x); }
+      builder.add_damage(args.damage);
+      builder.finish()
+    }
+
+    pub const VT_NAME: flatbuffers::VOffsetT = 4;
+    pub const VT_DAMAGE: flatbuffers::VOffsetT = 6;
+
+  #[inline]
+  pub fn name(&'a self) -> Option<&'a str> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(Weapon::VT_NAME, None)
+  }
+  #[inline]
+  pub fn damage(&'a self) -> i16 {
+    self._tab.get::<i16>(Weapon::VT_DAMAGE, Some(0)).unwrap()
+  }
+}
+
+pub struct WeaponArgs<'a> {
+    pub name: Option<flatbuffers::WIPOffset<&'a  str>>,
+    pub damage: i16,
+}
+impl<'a> Default for WeaponArgs<'a> {
+    #[inline]
+    fn default() -> Self {
+        WeaponArgs {
+            name: None,
+            damage: 0,
+        }
+    }
+}
+pub struct WeaponBuilder<'a: 'b, 'b> {
+  fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+  start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
+}
+impl<'a: 'b, 'b> WeaponBuilder<'a, 'b> {
+  #[inline]
+  pub fn add_name(&mut self, name: flatbuffers::WIPOffset<&'b  str>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Weapon::VT_NAME, name);
+  }
+  #[inline]
+  pub fn add_damage(&mut self, damage: i16) {
+    self.fbb_.push_slot::<i16>(Weapon::VT_DAMAGE, damage, 0);
+  }
+  #[inline]
+  pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> WeaponBuilder<'a, 'b> {
+    let start = _fbb.start_table();
+    WeaponBuilder {
+      fbb_: _fbb,
+      start_: start,
+    }
+  }
+  #[inline]
+  pub fn finish(self) -> flatbuffers::WIPOffset<Weapon<'a>> {
+    let o = self.fbb_.end_table(self.start_);
+    flatbuffers::WIPOffset::new(o.value())
+  }
+}
+
+#[inline]
+pub fn get_root_as_monster<'a>(buf: &'a [u8]) -> Monster<'a> {
+  flatbuffers::get_root::<Monster<'a>>(buf)
+}
+
+#[inline]
+pub fn get_size_prefixed_root_as_monster<'a>(buf: &'a [u8]) -> Monster<'a> {
+  flatbuffers::get_size_prefixed_root::<Monster<'a>>(buf)
+}
+
+#[inline]
+pub fn finish_monster_buffer<'a, 'b>(
+    fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+    root: flatbuffers::WIPOffset<Monster<'a>>) {
+  fbb.finish(root, None);
+}
+
+#[inline]
+pub fn finish_size_prefixed_monster_buffer<'a, 'b>(fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, root: flatbuffers::WIPOffset<Monster<'a>>) {
+  fbb.finish_size_prefixed(root, None);
+}
+}  // pub mod Sample
+}  // pub mod MyGame
+
diff --git a/third_party/flatbuffers/samples/monsterdata.json b/third_party/flatbuffers/samples/monsterdata.json
new file mode 100644
index 0000000..fa60b35
--- /dev/null
+++ b/third_party/flatbuffers/samples/monsterdata.json
@@ -0,0 +1,24 @@
+{
+  pos: {
+    x: 1.0,
+    y: 2.0,
+    z: 3.0
+  },
+  hp: 300,
+  name: "Orc",
+  weapons: [
+    {
+      name: "axe",
+      damage: 100
+    },
+    {
+      name: "bow",
+      damage: 90
+    }
+  ],
+  equipped_type: "Weapon",
+  equipped: {
+    name: "bow",
+    damage: 90
+  }
+}
diff --git a/third_party/flatbuffers/samples/php_sample.sh b/third_party/flatbuffers/samples/php_sample.sh
new file mode 100755
index 0000000..c23edc3
--- /dev/null
+++ b/third_party/flatbuffers/samples/php_sample.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+#
+# 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.
+#
+# Note: This script runs on Mac and Linux. It requires `php` to be installed
+# and `flatc` to be built (using `cmake` in the root directory).
+
+sampledir=$(cd $(dirname $BASH_SOURCE) && pwd)
+rootdir=$(cd $sampledir/.. && pwd)
+currentdir=$(pwd)
+
+if [[ "$sampledir" != "$currentdir" ]]; then
+  echo Error: This script must be run from inside the $sampledir directory.
+  echo You executed it from the $currentdir directory.
+  exit 1
+fi
+
+# Run `flatc`. Note: This requires you to compile using `cmake` from the
+# root `/flatbuffers` directory.
+if [ -e ../flatc ]; then
+  ../flatc --php monster.fbs
+elif [ -e ../Debug/flatc ]; then
+  ../Debug/flatc --php monster.fbs
+else
+  echo 'flatc' could not be found. Make sure to build FlatBuffers from the \
+        $rootdir directory.
+  exit 1
+fi
+
+echo Running the PHP sample.
+
+# Execute the sample.
+php SampleBinary.php
+
+# Clean up temporary files.
+rm -rf MyGame/
diff --git a/third_party/flatbuffers/samples/python_sample.sh b/third_party/flatbuffers/samples/python_sample.sh
new file mode 100755
index 0000000..ca5de2b
--- /dev/null
+++ b/third_party/flatbuffers/samples/python_sample.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+#
+# 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.
+#
+# Note: This script runs on Mac and Linux. It requires `python` to be installed
+# and `flatc` to be built (using `cmake` in the root directory).
+
+sampledir=$(cd $(dirname $BASH_SOURCE) && pwd)
+rootdir=$(cd $sampledir/.. && pwd)
+currentdir=$(pwd)
+
+if [[ "$sampledir" != "$currentdir" ]]; then
+  echo Error: This script must be run from inside the $sampledir directory.
+  echo You executed it from the $currentdir directory.
+  exit 1
+fi
+
+# Run `flatc`. Note: This requires you to compile using `cmake` from the
+# root `/flatbuffers` directory.
+if [ -e ../flatc ]; then
+  ../flatc --python monster.fbs
+elif [ -e ../Debug/flatc ]; then
+  ../Debug/flatc --python monster.fbs
+else
+  echo 'flatc' could not be found. Make sure to build FlatBuffers from the \
+       $rootdir directory.
+  exit 1
+fi
+
+echo Running the Python sample.
+
+# Execute the sample.
+python sample_binary.py
+
+# Clean up the temporary files.
+rm -rf MyGame
diff --git a/third_party/flatbuffers/samples/sample_bfbs.cpp b/third_party/flatbuffers/samples/sample_bfbs.cpp
new file mode 100644
index 0000000..9512e24
--- /dev/null
+++ b/third_party/flatbuffers/samples/sample_bfbs.cpp
@@ -0,0 +1,78 @@
+/*
+ * 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/idl.h"
+#include "flatbuffers/util.h"
+
+#include "monster_test_generated.h"
+#include "monster_generated.h" // Already includes "flatbuffers/flatbuffers.h".
+
+using namespace MyGame::Sample;
+
+// This is an example of parsing text straight into a buffer and then
+// generating flatbuffer (JSON) text from the buffer.
+int main(int /*argc*/, const char * /*argv*/[]) {
+  // load FlatBuffer schema (.fbs) and JSON from disk
+  std::string schema_file;
+  std::string json_file;
+  std::string bfbs_file;
+  bool ok =
+      flatbuffers::LoadFile("tests/monster_test.fbs", false, &schema_file) &&
+      flatbuffers::LoadFile("tests/monsterdata_test.golden", false, &json_file) &&
+      flatbuffers::LoadFile("tests/monster_test.bfbs", true, &bfbs_file);
+  if (!ok) {
+    printf("couldn't load files!\n");
+    return 1;
+  }
+
+  const char *include_directories[] = { "samples", "tests",
+                                        "tests/include_test", nullptr };
+  // parse fbs schema
+  flatbuffers::Parser parser1;
+  ok = parser1.Parse(schema_file.c_str(), include_directories);
+  assert(ok);
+
+  // inizialize parser by deserializing bfbs schema
+  flatbuffers::Parser parser2;
+  ok = parser2.Deserialize((uint8_t *)bfbs_file.c_str(), bfbs_file.length());
+  assert(ok);
+
+  // parse json in parser from fbs and bfbs
+  ok = parser1.Parse(json_file.c_str(), include_directories);
+  assert(ok);
+  ok = parser2.Parse(json_file.c_str(), include_directories);
+  assert(ok);
+
+  // to ensure it is correct, we now generate text back from the binary,
+  // and compare the two:
+  std::string jsongen1;
+  if (!GenerateText(parser1, parser1.builder_.GetBufferPointer(), &jsongen1)) {
+    printf("Couldn't serialize parsed data to JSON!\n");
+    return 1;
+  }
+
+  std::string jsongen2;
+  if (!GenerateText(parser2, parser2.builder_.GetBufferPointer(), &jsongen2)) {
+    printf("Couldn't serialize parsed data to JSON!\n");
+    return 1;
+  }
+
+  if (jsongen1 != jsongen2) {
+    printf("%s----------------\n%s", jsongen1.c_str(), jsongen2.c_str());
+  }
+
+  printf("The FlatBuffer has been parsed from JSON successfully.\n");
+}
diff --git a/third_party/flatbuffers/samples/sample_binary.cpp b/third_party/flatbuffers/samples/sample_binary.cpp
new file mode 100644
index 0000000..46f08bb
--- /dev/null
+++ b/third_party/flatbuffers/samples/sample_binary.cpp
@@ -0,0 +1,104 @@
+/*
+ * 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 "monster_generated.h"  // Already includes "flatbuffers/flatbuffers.h".
+
+using namespace MyGame::Sample;
+
+// Example how to use FlatBuffers to create and read binary buffers.
+
+int main(int /*argc*/, const char * /*argv*/ []) {
+  // Build up a serialized buffer algorithmically:
+  flatbuffers::FlatBufferBuilder builder;
+
+  // First, lets serialize some weapons for the Monster: A 'sword' and an 'axe'.
+  auto weapon_one_name = builder.CreateString("Sword");
+  short weapon_one_damage = 3;
+
+  auto weapon_two_name = builder.CreateString("Axe");
+  short weapon_two_damage = 5;
+
+  // Use the `CreateWeapon` shortcut to create Weapons with all fields set.
+  auto sword = CreateWeapon(builder, weapon_one_name, weapon_one_damage);
+  auto axe = CreateWeapon(builder, weapon_two_name, weapon_two_damage);
+
+  // Create a FlatBuffer's `vector` from the `std::vector`.
+  std::vector<flatbuffers::Offset<Weapon>> weapons_vector;
+  weapons_vector.push_back(sword);
+  weapons_vector.push_back(axe);
+  auto weapons = builder.CreateVector(weapons_vector);
+
+  // Second, serialize the rest of the objects needed by the Monster.
+  auto position = Vec3(1.0f, 2.0f, 3.0f);
+
+  auto name = builder.CreateString("MyMonster");
+
+  unsigned char inv_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+  auto inventory = builder.CreateVector(inv_data, 10);
+
+  // Shortcut for creating monster with all fields set:
+  auto orc = CreateMonster(builder, &position, 150, 80, name, inventory,
+                           Color_Red, weapons, Equipment_Weapon, axe.Union());
+
+  builder.Finish(orc);  // Serialize the root of the object.
+
+  // We now have a FlatBuffer we can store on disk or send over a network.
+
+  // ** file/network code goes here :) **
+  // access builder.GetBufferPointer() for builder.GetSize() bytes
+
+  // Instead, we're going to access it right away (as if we just received it).
+
+  // Get access to the root:
+  auto monster = GetMonster(builder.GetBufferPointer());
+
+  // Get and test some scalar types from the FlatBuffer.
+  assert(monster->hp() == 80);
+  assert(monster->mana() == 150);  // default
+  assert(monster->name()->str() == "MyMonster");
+
+  // Get and test a field of the FlatBuffer's `struct`.
+  auto pos = monster->pos();
+  assert(pos);
+  assert(pos->z() == 3.0f);
+  (void)pos;
+
+  // Get a test an element from the `inventory` FlatBuffer's `vector`.
+  auto inv = monster->inventory();
+  assert(inv);
+  assert(inv->Get(9) == 9);
+  (void)inv;
+
+  // Get and test the `weapons` FlatBuffers's `vector`.
+  std::string expected_weapon_names[] = { "Sword", "Axe" };
+  short expected_weapon_damages[] = { 3, 5 };
+  auto weps = monster->weapons();
+  for (unsigned int i = 0; i < weps->size(); i++) {
+    assert(weps->Get(i)->name()->str() == expected_weapon_names[i]);
+    assert(weps->Get(i)->damage() == expected_weapon_damages[i]);
+  }
+  (void)expected_weapon_names;
+  (void)expected_weapon_damages;
+
+  // Get and test the `Equipment` union (`equipped` field).
+  assert(monster->equipped_type() == Equipment_Weapon);
+  auto equipped = static_cast<const Weapon *>(monster->equipped());
+  assert(equipped->name()->str() == "Axe");
+  assert(equipped->damage() == 5);
+  (void)equipped;
+
+  printf("The FlatBuffer was successfully created and verified!\n");
+}
diff --git a/third_party/flatbuffers/samples/sample_binary.go b/third_party/flatbuffers/samples/sample_binary.go
new file mode 100644
index 0000000..e04650b
--- /dev/null
+++ b/third_party/flatbuffers/samples/sample_binary.go
@@ -0,0 +1,165 @@
+/*
+ * 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.
+ */
+
+// To run, use the `go_sample.sh` script.
+
+package main
+
+import (
+	sample "MyGame/Sample"
+	"fmt"
+	flatbuffers "github.com/google/flatbuffers/go"
+	"strconv"
+)
+
+// Example how to use Flatbuffers to create and read binary buffers.
+func main() {
+	builder := flatbuffers.NewBuilder(0)
+
+	// Create some weapons for our Monster ("Sword" and "Axe").
+	weaponOne := builder.CreateString("Sword")
+	weaponTwo := builder.CreateString("Axe")
+
+	sample.WeaponStart(builder)
+	sample.WeaponAddName(builder, weaponOne)
+	sample.WeaponAddDamage(builder, 3)
+	sword := sample.WeaponEnd(builder)
+
+	sample.WeaponStart(builder)
+	sample.WeaponAddName(builder, weaponTwo)
+	sample.WeaponAddDamage(builder, 5)
+	axe := sample.WeaponEnd(builder)
+
+	// Serialize the FlatBuffer data.
+	name := builder.CreateString("Orc")
+
+	sample.MonsterStartInventoryVector(builder, 10)
+	// Note: Since we prepend the bytes, this loop iterates in reverse.
+	for i := 9; i >= 0; i-- {
+		builder.PrependByte(byte(i))
+	}
+	inv := builder.EndVector(10)
+
+	sample.MonsterStartWeaponsVector(builder, 2)
+	// Note: Since we prepend the weapons, prepend in reverse order.
+	builder.PrependUOffsetT(axe)
+	builder.PrependUOffsetT(sword)
+	weapons := builder.EndVector(2)
+
+	pos := sample.CreateVec3(builder, 1.0, 2.0, 3.0)
+
+	sample.MonsterStart(builder)
+	sample.MonsterAddPos(builder, pos)
+	sample.MonsterAddHp(builder, 300)
+	sample.MonsterAddName(builder, name)
+	sample.MonsterAddInventory(builder, inv)
+	sample.MonsterAddColor(builder, sample.ColorRed)
+	sample.MonsterAddWeapons(builder, weapons)
+	sample.MonsterAddEquippedType(builder, sample.EquipmentWeapon)
+	sample.MonsterAddEquipped(builder, axe)
+	orc := sample.MonsterEnd(builder)
+
+	builder.Finish(orc)
+
+	// We now have a FlatBuffer that we could store on disk or send over a network.
+
+	// ...Saving to file or sending over a network code goes here...
+
+	// Instead, we are going to access this buffer right away (as if we just received it).
+
+	buf := builder.FinishedBytes()
+
+	// Note: We use `0` for the offset here, since we got the data using the
+	// `builder.FinishedBytes()` method. This simulates the data you would store/receive in your
+	// FlatBuffer. If you wanted to read from the `builder.Bytes` directly, you would need to
+	// pass in the offset of `builder.Head()`, as the builder actually constructs the buffer
+	// backwards.
+	monster := sample.GetRootAsMonster(buf, 0)
+
+	// Note: We did not set the `mana` field explicitly, so we get the
+	// default value.
+	assert(monster.Mana() == 150, "`monster.Mana()`", strconv.Itoa(int(monster.Mana())), "150")
+	assert(monster.Hp() == 300, "`monster.Hp()`", strconv.Itoa(int(monster.Hp())), "300")
+	assert(string(monster.Name()) == "Orc", "`string(monster.Name())`", string(monster.Name()),
+		"\"Orc\"")
+	assert(monster.Color() == sample.ColorRed, "`monster.Color()`",
+		strconv.Itoa(int(monster.Color())), strconv.Itoa(int(sample.ColorRed)))
+
+	// Note: Whenever you access a new object, like in `Pos()`, a new temporary accessor object
+	// gets created. If your code is very performance sensitive, you can pass in a pointer to an
+	// existing `Vec3` instead of `nil`. This allows you to reuse it across many calls to reduce
+	// the amount of object allocation/garbage collection.
+	assert(monster.Pos(nil).X() == 1.0, "`monster.Pos(nil).X()`",
+		strconv.FormatFloat(float64(monster.Pos(nil).X()), 'f', 1, 32), "1.0")
+	assert(monster.Pos(nil).Y() == 2.0, "`monster.Pos(nil).Y()`",
+		strconv.FormatFloat(float64(monster.Pos(nil).Y()), 'f', 1, 32), "2.0")
+	assert(monster.Pos(nil).Z() == 3.0, "`monster.Pos(nil).Z()`",
+		strconv.FormatFloat(float64(monster.Pos(nil).Z()), 'f', 1, 32), "3.0")
+
+	// For vectors, like `Inventory`, they have a method suffixed with 'Length' that can be used
+	// to query the length of the vector. You can index the vector by passing an index value
+	// into the accessor.
+	for i := 0; i < monster.InventoryLength(); i++ {
+		assert(monster.Inventory(i) == byte(i), "`monster.Inventory(i)`",
+			strconv.Itoa(int(monster.Inventory(i))), strconv.Itoa(int(byte(i))))
+	}
+
+	expectedWeaponNames := []string{"Sword", "Axe"}
+	expectedWeaponDamages := []int{3, 5}
+	weapon := new(sample.Weapon) // We need a `sample.Weapon` to pass into `monster.Weapons()`
+	// to capture the output of that function.
+	for i := 0; i < monster.WeaponsLength(); i++ {
+		if monster.Weapons(weapon, i) {
+			assert(string(weapon.Name()) == expectedWeaponNames[i], "`weapon.Name()`",
+				string(weapon.Name()), expectedWeaponNames[i])
+			assert(int(weapon.Damage()) == expectedWeaponDamages[i],
+				"`weapon.Damage()`", strconv.Itoa(int(weapon.Damage())),
+				strconv.Itoa(expectedWeaponDamages[i]))
+		}
+	}
+
+	// For FlatBuffer `union`s, you can get the type of the union, as well as the union
+	// data itself.
+	assert(monster.EquippedType() == sample.EquipmentWeapon, "`monster.EquippedType()`",
+		strconv.Itoa(int(monster.EquippedType())), strconv.Itoa(int(sample.EquipmentWeapon)))
+
+	unionTable := new(flatbuffers.Table)
+	if monster.Equipped(unionTable) {
+		// An example of how you can appropriately convert the table depending on the
+		// FlatBuffer `union` type. You could add `else if` and `else` clauses to handle
+		// other FlatBuffer `union` types for this field. (Similarly, this could be
+		// done in a switch statement.)
+		if monster.EquippedType() == sample.EquipmentWeapon {
+			unionWeapon := new(sample.Weapon)
+			unionWeapon.Init(unionTable.Bytes, unionTable.Pos)
+
+			assert(string(unionWeapon.Name()) == "Axe", "`unionWeapon.Name()`",
+				string(unionWeapon.Name()), "Axe")
+			assert(int(unionWeapon.Damage()) == 5, "`unionWeapon.Damage()`",
+				strconv.Itoa(int(unionWeapon.Damage())), strconv.Itoa(5))
+		}
+	}
+
+	fmt.Printf("The FlatBuffer was successfully created and verified!\n")
+}
+
+// A helper function to print out if an assertion failed.
+func assert(assertPassed bool, codeExecuted string, actualValue string, expectedValue string) {
+	if assertPassed == false {
+		panic("Assert failed! " + codeExecuted + " (" + actualValue +
+			") was not equal to " + expectedValue + ".")
+	}
+}
diff --git a/third_party/flatbuffers/samples/sample_binary.lobster b/third_party/flatbuffers/samples/sample_binary.lobster
new file mode 100644
index 0000000..cd7adab
--- /dev/null
+++ b/third_party/flatbuffers/samples/sample_binary.lobster
@@ -0,0 +1,100 @@
+// 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.
+
+import from "../lobster/"
+import monster_generated
+
+// Example of how to use FlatBuffers to create and read binary buffers.
+
+// Create a builder.
+let b = flatbuffers_builder {}
+
+// Create some weapons for our monster.
+let weapon_names = [ "Sword", "Axe" ]
+let weapon_damages = [ 3, 5 ]
+
+let weapon_offsets = map(weapon_names) name, i:
+    let ns = b.CreateString(name)
+    MyGame_Sample_WeaponBuilder { b }
+        .start()
+        .add_name(ns)
+        .add_damage(weapon_damages[i])
+        .end()
+
+let weapons = b.MyGame_Sample_MonsterCreateWeaponsVector(weapon_offsets)
+
+// Name of the monster.
+let name = b.CreateString("Orc")
+
+// Inventory.
+let inv = b.MyGame_Sample_MonsterCreateInventoryVector(map(10): _)
+
+// Now pack it all together in our root monster object.
+let orc = MyGame_Sample_MonsterBuilder { b }
+    .start()
+    .add_pos(b.MyGame_Sample_CreateVec3(1.0, 2.0, 3.0))
+    .add_hp(300)
+    .add_name(name)
+    .add_inventory(inv)
+    .add_color(MyGame_Sample_Color_Red)
+    .add_weapons(weapons)
+    .add_equipped_type(MyGame_Sample_Equipment_Weapon)
+    .add_equipped(weapon_offsets[1])
+    .end()
+
+// Finish the buffer!
+b.Finish(orc)
+
+// We now have a FlatBuffer that we could store on disk or send over a network.
+
+let buf = b.SizedCopy()
+
+// ...Saving to file or sending over a network code goes here...
+
+// Instead, we are going to access this buffer right away (as if we just
+// received it).
+
+// Get the root object accessor.
+let monster = MyGame_Sample_GetRootAsMonster(buf)
+
+// Note: We did not set the `mana` field explicitly, so we get a default value.
+assert monster.mana == 150
+assert monster.hp == 300
+assert monster.name == "Orc"
+assert monster.color == MyGame_Sample_Color_Red
+let pos = monster.pos
+assert pos
+assert pos.x == 1.0
+assert pos.y == 2.0
+assert pos.z == 3.0
+
+// Get and test the `inventory` FlatBuffer vector.
+for(monster.inventory_length) e, i:
+  assert monster.inventory(i) == e
+
+// Get and test the `weapons` FlatBuffer vector of tables.
+for(monster.weapons_length) i:
+  assert monster.weapons(i).name == weapon_names[i]
+  assert monster.weapons(i).damage == weapon_damages[i]
+
+// Get and test the `equipped` FlatBuffer union.
+assert monster.equipped_type() == MyGame_Sample_Equipment_Weapon
+
+// Now that we know the union value is a weapon, we can safely call as_Weapon:
+let union_weapon = monster.equipped_as_Weapon
+
+assert union_weapon.name == "Axe"
+assert union_weapon.damage == 5
+
+print "The FlatBuffer was successfully created and verified!"
diff --git a/third_party/flatbuffers/samples/sample_binary.lua b/third_party/flatbuffers/samples/sample_binary.lua
new file mode 100644
index 0000000..da96539
--- /dev/null
+++ b/third_party/flatbuffers/samples/sample_binary.lua
@@ -0,0 +1,107 @@
+-- need to update the Lua path to point to the local flatbuffers implementation
+package.path = string.format("../lua/?.lua;%s",package.path)
+package.path = string.format("./lua/?.lua;%s",package.path)
+
+-- require the library
+local flatbuffers = require("flatbuffers")
+
+local binaryArray = flatbuffers.binaryArray-- for hex dump utility
+
+-- require the files generated from the schema
+local weapon = require("MyGame.Sample.Weapon")
+local monster = require("MyGame.Sample.Monster")
+local vec3 = require("MyGame.Sample.Vec3")
+local color = require("MyGame.Sample.Color")
+local equipment = require("MyGame.Sample.Equipment")
+
+-- get access to the builder, providing an array of size 1024
+local builder = flatbuffers.Builder(1024)
+
+local weaponOne = builder:CreateString("Sword")
+local weaponTwo = builder:CreateString("Axe")
+
+-- Create the first 'Weapon'
+weapon.Start(builder)
+weapon.AddName(builder, weaponOne)
+weapon.AddDamage(builder, 3)
+local sword = weapon.End(builder)
+
+-- Create the second 'Weapon'
+weapon.Start(builder)
+weapon.AddName(builder, weaponTwo)
+weapon.AddDamage(builder, 5)
+local axe = weapon.End(builder)
+
+-- Serialize a name for our mosnter, called 'orc'
+local name = builder:CreateString("Orc")
+
+-- Create a `vector` representing the inventory of the Orc. Each number
+-- could correspond to an item that can be claimed after he is slain.
+-- Note: Since we prepend the bytes, this loop iterates in reverse.
+monster.StartInventoryVector(builder, 10)
+for i=10,1,-1 do
+    builder:PrependByte(i)
+end
+local inv = builder:EndVector(10)
+
+-- Create a FlatBuffer vector and prepend the weapons.
+-- Note: Since we prepend the data, prepend them in reverse order.
+monster.StartWeaponsVector(builder, 2)
+builder:PrependUOffsetTRelative(axe)
+builder:PrependUOffsetTRelative(sword)
+local weapons = builder:EndVector(2)
+
+-- Create our monster by using Start() andEnd()
+monster.Start(builder)
+monster.AddPos(builder, vec3.CreateVec3(builder, 1.0, 2.0, 3.0))
+monster.AddHp(builder, 300)
+monster.AddName(builder, name)
+monster.AddInventory(builder, inv)
+monster.AddColor(builder, color.Red)
+monster.AddWeapons(builder, weapons)
+monster.AddEquippedType(builder, equipment.Weapon)
+monster.AddEquipped(builder, axe)
+local orc = monster.End(builder)
+
+-- Call 'Finish()' to instruct the builder that this monster is complete.
+builder:Finish(orc)
+
+-- Get the flatbuffer as a string containing the binary data
+local bufAsString = builder:Output()
+
+-- Convert the string representation into binary array Lua structure
+local buf = flatbuffers.binaryArray.New(bufAsString)
+
+-- Get an accessor to the root object insert the buffer
+local mon = monster.GetRootAsMonster(buf, 0)
+
+assert(mon:Mana() == 150)
+assert(mon:Hp() == 300)
+assert(mon:Name() == "Orc")
+assert(mon:Color() == color.Red)
+assert(mon:Pos():X() == 1.0)
+assert(mon:Pos():Y() == 2.0)
+assert(mon:Pos():Z() == 3.0)
+
+for i=1,mon:InventoryLength() do
+    assert(mon:Inventory(i) == i)
+end
+
+local expected = { 
+    {w = 'Sword', d = 3}, 
+    {w = 'Axe', d = 5}
+}
+
+for i=1,mon:WeaponsLength() do
+   assert(mon:Weapons(i):Name() == expected[i].w)
+   assert(mon:Weapons(i):Damage() == expected[i].d)
+end
+
+assert(mon:EquippedType() == equipment.Weapon)
+
+local unionWeapon = weapon.New()
+unionWeapon:Init(mon:Equipped().bytes,mon:Equipped().pos)
+assert(unionWeapon:Name() == "Axe")
+assert(unionWeapon:Damage() == 5)
+
+print("The Lua FlatBuffer example was successfully created and verified!")
\ No newline at end of file
diff --git a/third_party/flatbuffers/samples/sample_binary.py b/third_party/flatbuffers/samples/sample_binary.py
new file mode 100644
index 0000000..96711fb
--- /dev/null
+++ b/third_party/flatbuffers/samples/sample_binary.py
@@ -0,0 +1,137 @@
+#!/usr/bin/python
+# 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.
+
+# To run this file, use `python_sample.sh`.
+
+# Append paths to the `flatbuffers` and `MyGame` modules. This is necessary
+# to facilitate executing this script in the `samples` folder, and to root
+# folder (where it gets placed when using `cmake`).
+import os
+import sys
+sys.path.append(os.path.join(os.path.dirname(__file__), '../python'))
+
+import flatbuffers
+import MyGame.Sample.Color
+import MyGame.Sample.Equipment
+import MyGame.Sample.Monster
+import MyGame.Sample.Vec3
+import MyGame.Sample.Weapon
+
+# Example of how to use FlatBuffers to create and read binary buffers.
+
+def main():
+  builder = flatbuffers.Builder(0)
+
+  # Create some weapons for our Monster ('Sword' and 'Axe').
+  weapon_one = builder.CreateString('Sword')
+  weapon_two = builder.CreateString('Axe')
+
+  MyGame.Sample.Weapon.WeaponStart(builder)
+  MyGame.Sample.Weapon.WeaponAddName(builder, weapon_one)
+  MyGame.Sample.Weapon.WeaponAddDamage(builder, 3)
+  sword = MyGame.Sample.Weapon.WeaponEnd(builder)
+
+  MyGame.Sample.Weapon.WeaponStart(builder)
+  MyGame.Sample.Weapon.WeaponAddName(builder, weapon_two)
+  MyGame.Sample.Weapon.WeaponAddDamage(builder, 5)
+  axe = MyGame.Sample.Weapon.WeaponEnd(builder)
+
+  # Serialize the FlatBuffer data.
+  name = builder.CreateString('Orc')
+
+  MyGame.Sample.Monster.MonsterStartInventoryVector(builder, 10)
+  # Note: Since we prepend the bytes, this loop iterates in reverse order.
+  for i in reversed(range(0, 10)):
+    builder.PrependByte(i)
+  inv = builder.EndVector(10)
+
+  MyGame.Sample.Monster.MonsterStartWeaponsVector(builder, 2)
+  # Note: Since we prepend the data, prepend the weapons in reverse order.
+  builder.PrependUOffsetTRelative(axe)
+  builder.PrependUOffsetTRelative(sword)
+  weapons = builder.EndVector(2)
+
+  pos = MyGame.Sample.Vec3.CreateVec3(builder, 1.0, 2.0, 3.0)
+
+  MyGame.Sample.Monster.MonsterStart(builder)
+  MyGame.Sample.Monster.MonsterAddPos(builder, pos)
+  MyGame.Sample.Monster.MonsterAddHp(builder, 300)
+  MyGame.Sample.Monster.MonsterAddName(builder, name)
+  MyGame.Sample.Monster.MonsterAddInventory(builder, inv)
+  MyGame.Sample.Monster.MonsterAddColor(builder,
+                                        MyGame.Sample.Color.Color().Red)
+  MyGame.Sample.Monster.MonsterAddWeapons(builder, weapons)
+  MyGame.Sample.Monster.MonsterAddEquippedType(
+      builder, MyGame.Sample.Equipment.Equipment().Weapon)
+  MyGame.Sample.Monster.MonsterAddEquipped(builder, axe)
+  orc = MyGame.Sample.Monster.MonsterEnd(builder)
+
+  builder.Finish(orc)
+
+  # We now have a FlatBuffer that we could store on disk or send over a network.
+
+  # ...Saving to file or sending over a network code goes here...
+
+  # Instead, we are going to access this buffer right away (as if we just
+  # received it).
+
+  buf = builder.Output()
+
+  # Note: We use `0` for the offset here, since we got the data using the
+  # `builder.Output()` method. This simulates the data you would store/receive
+  # in your FlatBuffer. If you wanted to read from the `builder.Bytes` directly,
+  # you would need to pass in the offset of `builder.Head()`, as the builder
+  # actually constructs the buffer backwards.
+  monster = MyGame.Sample.Monster.Monster.GetRootAsMonster(buf, 0)
+
+  # Note: We did not set the `Mana` field explicitly, so we get a default value.
+  assert monster.Mana() == 150
+  assert monster.Hp() == 300
+  assert monster.Name() == 'Orc'
+  assert monster.Color() == MyGame.Sample.Color.Color().Red
+  assert monster.Pos().X() == 1.0
+  assert monster.Pos().Y() == 2.0
+  assert monster.Pos().Z() == 3.0
+
+  # Get and test the `inventory` FlatBuffer `vector`.
+  for i in xrange(monster.InventoryLength()):
+    assert monster.Inventory(i) == i
+
+  # Get and test the `weapons` FlatBuffer `vector` of `table`s.
+  expected_weapon_names = ['Sword', 'Axe']
+  expected_weapon_damages = [3, 5]
+  for i in xrange(monster.WeaponsLength()):
+    assert monster.Weapons(i).Name() == expected_weapon_names[i]
+    assert monster.Weapons(i).Damage() == expected_weapon_damages[i]
+
+  # Get and test the `equipped` FlatBuffer `union`.
+  assert monster.EquippedType() == MyGame.Sample.Equipment.Equipment().Weapon
+
+  # An example of how you can appropriately convert the table depending on the
+  # FlatBuffer `union` type. You could add `elif` and `else` clauses to handle
+  # the other FlatBuffer `union` types for this field.
+  if monster.EquippedType() == MyGame.Sample.Equipment.Equipment().Weapon:
+    # `monster.Equipped()` returns a `flatbuffers.Table`, which can be used
+    # to initialize a `MyGame.Sample.Weapon.Weapon()`, in this case.
+    union_weapon = MyGame.Sample.Weapon.Weapon()
+    union_weapon.Init(monster.Equipped().Bytes, monster.Equipped().Pos)
+
+    assert union_weapon.Name() == "Axe"
+    assert union_weapon.Damage() == 5
+
+  print 'The FlatBuffer was successfully created and verified!'
+
+if __name__ == '__main__':
+  main()
diff --git a/third_party/flatbuffers/samples/sample_binary.rs b/third_party/flatbuffers/samples/sample_binary.rs
new file mode 100644
index 0000000..7a4c2ae
--- /dev/null
+++ b/third_party/flatbuffers/samples/sample_binary.rs
@@ -0,0 +1,155 @@
+/*
+ * 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.
+ */
+
+// import the flatbuffers runtime library
+extern crate flatbuffers;
+
+// import the generated code
+#[path = "./monster_generated.rs"]
+mod monster_generated;
+pub use monster_generated::my_game::sample::{get_root_as_monster,
+                                             Color, Equipment,
+                                             Monster, MonsterArgs,
+                                             Vec3,
+                                             Weapon, WeaponArgs};
+
+
+// Example how to use FlatBuffers to create and read binary buffers.
+
+fn main() {
+  // Build up a serialized buffer algorithmically.
+  // Initialize it with a capacity of 1024 bytes.
+  let mut builder = flatbuffers::FlatBufferBuilder::new_with_capacity(1024);
+
+  // Serialize some weapons for the Monster: A 'sword' and an 'axe'.
+  let weapon_one_name = builder.create_string("Sword");
+  let weapon_two_name = builder.create_string("Axe");
+
+  // Use the `Weapon::create` shortcut to create Weapons with named field
+  // arguments.
+  let sword = Weapon::create(&mut builder, &WeaponArgs{
+      name: Some(weapon_one_name),
+      damage: 3,
+  });
+  let axe = Weapon::create(&mut builder, &WeaponArgs{
+      name: Some(weapon_two_name),
+      damage: 5,
+  });
+
+  // Name of the Monster.
+  let name = builder.create_string("Orc");
+
+  // Inventory.
+  let inventory = builder.create_vector(&[0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
+
+  // Create a FlatBuffer `vector` that contains offsets to the sword and axe
+  // we created above.
+  let weapons = builder.create_vector(&[sword, axe]);
+
+  // Create the path vector of Vec3 objects:
+  //let x = Vec3::new(1.0, 2.0, 3.0);
+  //let y = Vec3::new(4.0, 5.0, 6.0);
+  //let path = builder.create_vector(&[x, y]);
+
+  // Note that, for convenience, it is also valid to create a vector of
+  // references to structs, like this:
+  // let path = builder.create_vector(&[&x, &y]);
+
+  // Create the monster using the `Monster::create` helper function. This
+  // function accepts a `MonsterArgs` struct, which supplies all of the data
+  // needed to build a `Monster`. To supply empty/default fields, just use the
+  // Rust built-in `Default::default()` function, as demononstrated below.
+  let orc = Monster::create(&mut builder, &MonsterArgs{
+      pos: Some(&Vec3::new(1.0f32, 2.0f32, 3.0f32)),
+      mana: 150,
+      hp: 80,
+      name: Some(name),
+      inventory: Some(inventory),
+      color: Color::Red,
+      weapons: Some(weapons),
+      equipped_type: Equipment::Weapon,
+      equipped: Some(axe.as_union_value()),
+      //path: Some(path),
+      ..Default::default()
+  });
+
+  // Serialize the root of the object, without providing a file identifier.
+  builder.finish(orc, None);
+
+  // We now have a FlatBuffer we can store on disk or send over a network.
+
+  // ** file/network code goes here :) **
+
+  // Instead, we're going to access it right away (as if we just received it).
+  // This must be called after `finish()`.
+  let buf = builder.finished_data(); // Of type `&[u8]`
+
+  // Get access to the root:
+  let monster = get_root_as_monster(buf);
+
+  // Get and test some scalar types from the FlatBuffer.
+  let hp = monster.hp();
+  let mana = monster.mana();
+  let name = monster.name();
+
+  assert_eq!(hp, 80);
+  assert_eq!(mana, 150);  // default
+  assert_eq!(name, Some("Orc"));
+
+  // Get and test a field of the FlatBuffer's `struct`.
+  assert!(monster.pos().is_some());
+  let pos = monster.pos().unwrap();
+  let x = pos.x();
+  let y = pos.y();
+  let z = pos.z();
+  assert_eq!(x, 1.0f32);
+  assert_eq!(y, 2.0f32);
+  assert_eq!(z, 3.0f32);
+
+  // Get an element from the `inventory` FlatBuffer's `vector`.
+  assert!(monster.inventory().is_some());
+  let inv = monster.inventory().unwrap();
+
+  // Note that this vector is returned as a slice, because direct access for
+  // this type, a u8 vector, is safe on all platforms:
+  let third_item = inv[2];
+  assert_eq!(third_item, 2);
+
+  // Get and test the `weapons` FlatBuffers's `vector`.
+  assert!(monster.weapons().is_some());
+  let weps = monster.weapons().unwrap();
+  //let weps_len = weps.len();
+  let wep2 = weps.get(1);
+  let second_weapon_name = wep2.name();
+  let second_weapon_damage = wep2.damage();
+  assert_eq!(second_weapon_name, Some("Axe"));
+  assert_eq!(second_weapon_damage, 5);
+
+  // Get and test the `Equipment` union (`equipped` field).
+  assert_eq!(monster.equipped_type(), Equipment::Weapon);
+  let equipped = monster.equipped_as_weapon().unwrap();
+  let weapon_name = equipped.name();
+  let weapon_damage = equipped.damage();
+  assert_eq!(weapon_name, Some("Axe"));
+  assert_eq!(weapon_damage, 5);
+
+  // Get and test the `path` FlatBuffers's `vector`.
+  //assert_eq!(monster.path().unwrap().len(), 2);
+  //assert_eq!(monster.path().unwrap()[0].x(), 1.0);
+  //assert_eq!(monster.path().unwrap()[1].x(), 4.0);
+
+  println!("The FlatBuffer was successfully created and accessed!");
+}
diff --git a/third_party/flatbuffers/samples/sample_text.cpp b/third_party/flatbuffers/samples/sample_text.cpp
new file mode 100644
index 0000000..aca0189
--- /dev/null
+++ b/third_party/flatbuffers/samples/sample_text.cpp
@@ -0,0 +1,59 @@
+/*
+ * 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/idl.h"
+#include "flatbuffers/util.h"
+
+#include "monster_generated.h"  // Already includes "flatbuffers/flatbuffers.h".
+
+using namespace MyGame::Sample;
+
+// This is an example of parsing text straight into a buffer and then
+// generating flatbuffer (JSON) text from the buffer.
+int main(int /*argc*/, const char * /*argv*/ []) {
+  // load FlatBuffer schema (.fbs) and JSON from disk
+  std::string schemafile;
+  std::string jsonfile;
+  bool ok = flatbuffers::LoadFile("samples/monster.fbs", false, &schemafile) &&
+            flatbuffers::LoadFile("samples/monsterdata.json", false, &jsonfile);
+  if (!ok) {
+    printf("couldn't load files!\n");
+    return 1;
+  }
+
+  // parse schema first, so we can use it to parse the data after
+  flatbuffers::Parser parser;
+  const char *include_directories[] = { "samples", nullptr };
+  ok = parser.Parse(schemafile.c_str(), include_directories) &&
+       parser.Parse(jsonfile.c_str(), include_directories);
+  assert(ok);
+
+  // here, parser.builder_ contains a binary buffer that is the parsed data.
+
+  // to ensure it is correct, we now generate text back from the binary,
+  // and compare the two:
+  std::string jsongen;
+  if (!GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen)) {
+    printf("Couldn't serialize parsed data to JSON!\n");
+    return 1;
+  }
+
+  if (jsongen != jsonfile) {
+    printf("%s----------------\n%s", jsongen.c_str(), jsonfile.c_str());
+  }
+
+  printf("The FlatBuffer has been parsed from JSON successfully.\n");
+}
diff --git a/third_party/flatbuffers/samples/sample_text.lobster b/third_party/flatbuffers/samples/sample_text.lobster
new file mode 100644
index 0000000..26b3eaf
--- /dev/null
+++ b/third_party/flatbuffers/samples/sample_text.lobster
@@ -0,0 +1,43 @@
+// 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.
+
+import from "../lobster/"
+import monster_generated
+
+// Example how to interop with JSON.
+
+// Test loading some JSON, converting it to a binary FlatBuffer and back again.
+
+// First read the schema and JSON data.
+let schema = read_file("monster.fbs", true)
+let json = read_file("monsterdata.json", true)
+assert schema and json
+
+// Parse JSON  to binary:
+let fb, err1 = flatbuffers_json_to_binary(schema, json, [])
+assert not err1
+
+// Access one field in it, just to check:
+let monster = MyGame_Sample_GetRootAsMonster(fb)
+assert monster.name == "Orc"
+
+// Convert binary back to JSON:
+let json2, err2 = flatbuffers_binary_to_json(schema, fb, [])
+assert not err2
+
+// The generated JSON should be exactly equal to the original!
+assert json == json2
+
+// Print what we've been converting for good measure:
+print json
diff --git a/third_party/flatbuffers/samples/samplebinary.js b/third_party/flatbuffers/samples/samplebinary.js
new file mode 100644
index 0000000..9c8c908
--- /dev/null
+++ b/third_party/flatbuffers/samples/samplebinary.js
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+// To run, use the `javascript_sample.sh` script.
+
+var assert = require('assert');
+var flatbuffers = require('../js/flatbuffers').flatbuffers;
+var MyGame = require('./monster_generated').MyGame;
+
+// Example how to use FlatBuffers to create and read binary buffers.
+function main() {
+  var builder = new flatbuffers.Builder(0);
+
+  // Create some weapons for our Monster ('Sword' and 'Axe').
+  var weaponOne = builder.createString('Sword');
+  var weaponTwo = builder.createString('Axe');
+
+  MyGame.Sample.Weapon.startWeapon(builder);
+  MyGame.Sample.Weapon.addName(builder, weaponOne);
+  MyGame.Sample.Weapon.addDamage(builder, 3);
+  var sword = MyGame.Sample.Weapon.endWeapon(builder);
+
+  MyGame.Sample.Weapon.startWeapon(builder);
+  MyGame.Sample.Weapon.addName(builder, weaponTwo);
+  MyGame.Sample.Weapon.addDamage(builder, 5);
+  var axe = MyGame.Sample.Weapon.endWeapon(builder);
+
+  // Serialize the FlatBuffer data.
+  var name = builder.createString('Orc');
+
+  var treasure = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+  var inv = MyGame.Sample.Monster.createInventoryVector(builder, treasure);
+
+  var weaps = [sword, axe];
+  var weapons = MyGame.Sample.Monster.createWeaponsVector(builder, weaps);
+
+  var pos = MyGame.Sample.Vec3.createVec3(builder, 1.0, 2.0, 3.0);
+
+  MyGame.Sample.Monster.startMonster(builder);
+  MyGame.Sample.Monster.addPos(builder, pos);
+  MyGame.Sample.Monster.addHp(builder, 300);
+  MyGame.Sample.Monster.addColor(builder, MyGame.Sample.Color.Red)
+  MyGame.Sample.Monster.addName(builder, name);
+  MyGame.Sample.Monster.addInventory(builder, inv);
+  MyGame.Sample.Monster.addWeapons(builder, weapons);
+  MyGame.Sample.Monster.addEquippedType(builder, MyGame.Sample.Equipment.Weapon);
+  MyGame.Sample.Monster.addEquipped(builder, weaps[1]);
+  var orc = MyGame.Sample.Monster.endMonster(builder);
+
+  builder.finish(orc); // You may also call 'MyGame.Example.Monster.finishMonsterBuffer(builder, orc);'.
+
+  // We now have a FlatBuffer that can be stored on disk or sent over a network.
+
+  // ...Code to store to disk or send over a network goes here...
+
+  // Instead, we are going to access it right away, as if we just received it.
+
+  var buf = builder.dataBuffer();
+
+  // Get access to the root:
+  var monster = MyGame.Sample.Monster.getRootAsMonster(buf);
+
+  // Note: We did not set the `mana` field explicitly, so we get back the default value.
+  assert.equal(monster.mana(), 150);
+  assert.equal(monster.hp(), 300);
+  assert.equal(monster.name(), 'Orc');
+  assert.equal(monster.color(), MyGame.Sample.Color.Red);
+  assert.equal(monster.pos().x(), 1.0);
+  assert.equal(monster.pos().y(), 2.0);
+  assert.equal(monster.pos().z(), 3.0);
+
+  // Get and test the `inventory` FlatBuffer `vector`.
+  for (var i = 0; i < monster.inventoryLength(); i++) {
+    assert.equal(monster.inventory(i), i);
+  }
+
+  // Get and test the `weapons` FlatBuffer `vector` of `table`s.
+  var expectedWeaponNames = ['Sword', 'Axe'];
+  var expectedWeaponDamages = [3, 5];
+  for (var i = 0; i < monster.weaponsLength(); i++) {
+    assert.equal(monster.weapons(i).name(), expectedWeaponNames[i]);
+    assert.equal(monster.weapons(i).damage(), expectedWeaponDamages[i]);
+  }
+
+  // Get and test the `equipped` FlatBuffer `union`.
+  assert.equal(monster.equippedType(), MyGame.Sample.Equipment.Weapon);
+  assert.equal(monster.equipped(new MyGame.Sample.Weapon()).name(), 'Axe');
+  assert.equal(monster.equipped(new MyGame.Sample.Weapon()).damage(), 5);
+
+  console.log('The FlatBuffer was successfully created and verified!');
+}
+
+main();
diff --git a/third_party/flatbuffers/snap/snapcraft.yaml b/third_party/flatbuffers/snap/snapcraft.yaml
new file mode 100644
index 0000000..1713896
--- /dev/null
+++ b/third_party/flatbuffers/snap/snapcraft.yaml
@@ -0,0 +1,37 @@
+name: flatbuffers
+base: core18
+version: latest
+version-script: git describe --always | sed -e 's/-/+git/;y/-/./' | tail -c +2
+summary: FlatBuffers compiler
+description: |
+  FlatBuffers compiler
+
+  NOTE: This snap also ships the necessary header files required to compile
+  projects using flatbuffers, however, for the compilation to work, you have
+  to manually add the following path in your project's configuration:
+
+  /snap/flatbuffers/current/include
+
+  If you need to use flatbuffers headers from a location other than the above
+  path, it is recommended to not use this snap as that could cause a mismatch.
+
+grade: stable
+confinement: strict
+
+parts:
+  flatc:
+    plugin: cmake
+    source: .
+    configflags:
+      - -GUnix Makefiles
+      - -DCMAKE_BUILD_TYPE=Release
+    build-packages:
+      - g++
+      # used to set version number
+      - git
+
+apps:
+  flatc:
+    command: flatc
+    plugs:
+      - home
diff --git a/third_party/flatbuffers/src/clang-format.sh b/third_party/flatbuffers/src/clang-format.sh
new file mode 100644
index 0000000..fbce6b9
--- /dev/null
+++ b/third_party/flatbuffers/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/third_party/flatbuffers/src/code_generators.cpp b/third_party/flatbuffers/src/code_generators.cpp
new file mode 100644
index 0000000..52ca305
--- /dev/null
+++ b/third_party/flatbuffers/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/third_party/flatbuffers/src/flatc.cpp b/third_party/flatbuffers/src/flatc.cpp
new file mode 100644
index 0000000..e1236bd
--- /dev/null
+++ b/third_party/flatbuffers/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/third_party/flatbuffers/src/flatc_main.cpp b/third_party/flatbuffers/src/flatc_main.cpp
new file mode 100644
index 0000000..72bb4a2
--- /dev/null
+++ b/third_party/flatbuffers/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/third_party/flatbuffers/src/flathash.cpp b/third_party/flatbuffers/src/flathash.cpp
new file mode 100644
index 0000000..bc3d2df
--- /dev/null
+++ b/third_party/flatbuffers/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/third_party/flatbuffers/src/idl_gen_cpp.cpp b/third_party/flatbuffers/src/idl_gen_cpp.cpp
new file mode 100644
index 0000000..b667ea4
--- /dev/null
+++ b/third_party/flatbuffers/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/third_party/flatbuffers/src/idl_gen_dart.cpp b/third_party/flatbuffers/src/idl_gen_dart.cpp
new file mode 100644
index 0000000..2346a85
--- /dev/null
+++ b/third_party/flatbuffers/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/third_party/flatbuffers/src/idl_gen_fbs.cpp b/third_party/flatbuffers/src/idl_gen_fbs.cpp
new file mode 100644
index 0000000..e5f3723
--- /dev/null
+++ b/third_party/flatbuffers/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/third_party/flatbuffers/src/idl_gen_general.cpp b/third_party/flatbuffers/src/idl_gen_general.cpp
new file mode 100644
index 0000000..8dca792
--- /dev/null
+++ b/third_party/flatbuffers/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/third_party/flatbuffers/src/idl_gen_go.cpp b/third_party/flatbuffers/src/idl_gen_go.cpp
new file mode 100644
index 0000000..5e62b61
--- /dev/null
+++ b/third_party/flatbuffers/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/third_party/flatbuffers/src/idl_gen_grpc.cpp b/third_party/flatbuffers/src/idl_gen_grpc.cpp
new file mode 100644
index 0000000..1d5e8e5
--- /dev/null
+++ b/third_party/flatbuffers/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/third_party/flatbuffers/src/idl_gen_js_ts.cpp b/third_party/flatbuffers/src/idl_gen_js_ts.cpp
new file mode 100644
index 0000000..9c89c1a
--- /dev/null
+++ b/third_party/flatbuffers/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/third_party/flatbuffers/src/idl_gen_json_schema.cpp b/third_party/flatbuffers/src/idl_gen_json_schema.cpp
new file mode 100644
index 0000000..27e2cd4
--- /dev/null
+++ b/third_party/flatbuffers/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/third_party/flatbuffers/src/idl_gen_kotlin.cpp b/third_party/flatbuffers/src/idl_gen_kotlin.cpp
new file mode 100644
index 0000000..3ced7b3
--- /dev/null
+++ b/third_party/flatbuffers/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/third_party/flatbuffers/src/idl_gen_lobster.cpp b/third_party/flatbuffers/src/idl_gen_lobster.cpp
new file mode 100644
index 0000000..ef9e474
--- /dev/null
+++ b/third_party/flatbuffers/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/third_party/flatbuffers/src/idl_gen_lua.cpp b/third_party/flatbuffers/src/idl_gen_lua.cpp
new file mode 100644
index 0000000..10df231
--- /dev/null
+++ b/third_party/flatbuffers/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/third_party/flatbuffers/src/idl_gen_php.cpp b/third_party/flatbuffers/src/idl_gen_php.cpp
new file mode 100644
index 0000000..9d81415
--- /dev/null
+++ b/third_party/flatbuffers/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/third_party/flatbuffers/src/idl_gen_python.cpp b/third_party/flatbuffers/src/idl_gen_python.cpp
new file mode 100644
index 0000000..c8db359
--- /dev/null
+++ b/third_party/flatbuffers/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/third_party/flatbuffers/src/idl_gen_rust.cpp b/third_party/flatbuffers/src/idl_gen_rust.cpp
new file mode 100644
index 0000000..936ac83
--- /dev/null
+++ b/third_party/flatbuffers/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/third_party/flatbuffers/src/idl_gen_text.cpp b/third_party/flatbuffers/src/idl_gen_text.cpp
new file mode 100644
index 0000000..9825dce
--- /dev/null
+++ b/third_party/flatbuffers/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/third_party/flatbuffers/src/idl_parser.cpp b/third_party/flatbuffers/src/idl_parser.cpp
new file mode 100644
index 0000000..31b315c
--- /dev/null
+++ b/third_party/flatbuffers/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/third_party/flatbuffers/src/reflection.cpp b/third_party/flatbuffers/src/reflection.cpp
new file mode 100644
index 0000000..89ce783
--- /dev/null
+++ b/third_party/flatbuffers/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/third_party/flatbuffers/src/util.cpp b/third_party/flatbuffers/src/util.cpp
new file mode 100644
index 0000000..5483cee
--- /dev/null
+++ b/third_party/flatbuffers/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
diff --git a/third_party/flatbuffers/tests/DartTest.sh b/third_party/flatbuffers/tests/DartTest.sh
new file mode 100755
index 0000000..6ce72cc
--- /dev/null
+++ b/third_party/flatbuffers/tests/DartTest.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+#
+# 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.
+
+pushd "$(dirname $0)" >/dev/null
+
+command -v pub >/dev/null 2>&1 || { echo >&2 "Dart tests require `pub` but it's not installed.  Aborting."; exit 1; }
+command -v dart >/dev/null 2>&1 || { echo >&2 "Dart tests require dart to be in path but it's not installed.  Aborting."; exit 1; }
+# output required files to the dart folder so that pub will be able to 
+# distribute them and more people can more easily run the dart tests
+../flatc --dart -I include_test -o ../dart/test monster_test.fbs 
+cp monsterdata_test.mon ../dart/test
+
+cd ../dart
+
+# update packages
+pub get
+# Execute the sample.
+dart test/flat_buffers_test.dart
+
+# cleanup
+rm ../dart/test/monsterdata_test.mon
diff --git a/third_party/flatbuffers/tests/FlatBuffers.Benchmarks/FlatBufferBuilderBenchmark.cs b/third_party/flatbuffers/tests/FlatBuffers.Benchmarks/FlatBufferBuilderBenchmark.cs
new file mode 100644
index 0000000..1df5ac3
--- /dev/null
+++ b/third_party/flatbuffers/tests/FlatBuffers.Benchmarks/FlatBufferBuilderBenchmark.cs
@@ -0,0 +1,101 @@
+﻿/*
+ * 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.
+ */
+
+using BenchmarkDotNet.Attributes;
+using MyGame.Example;
+
+namespace FlatBuffers.Benchmarks
+{
+    //[EtwProfiler] - needs elevated privileges
+    [MemoryDiagnoser]
+    public class FlatBufferBuilderBenchmark
+    {
+        private const int NumberOfRows = 10_000;
+
+        [Benchmark]
+        public void BuildNestedMonster()
+        {
+            const string nestedMonsterName = "NestedMonsterName";
+            const short nestedMonsterHp = 600;
+            const short nestedMonsterMana = 1024;
+
+            for (int i = 0; i < NumberOfRows; i++)
+            {
+                // Create nested buffer as a Monster type
+                var fbb1 = new FlatBufferBuilder(16);
+                var str1 = fbb1.CreateString(nestedMonsterName);
+                Monster.StartMonster(fbb1);
+                Monster.AddName(fbb1, str1);
+                Monster.AddHp(fbb1, nestedMonsterHp);
+                Monster.AddMana(fbb1, nestedMonsterMana);
+                var monster1 = Monster.EndMonster(fbb1);
+                Monster.FinishMonsterBuffer(fbb1, monster1);
+                var fbb1Bytes = fbb1.SizedByteArray();
+                fbb1 = null;
+
+                // Create a Monster which has the first buffer as a nested buffer
+                var fbb2 = new FlatBufferBuilder(16);
+                var str2 = fbb2.CreateString("My Monster");
+                var nestedBuffer = Monster.CreateTestnestedflatbufferVector(fbb2, fbb1Bytes);
+                Monster.StartMonster(fbb2);
+                Monster.AddName(fbb2, str2);
+                Monster.AddHp(fbb2, 50);
+                Monster.AddMana(fbb2, 32);
+                Monster.AddTestnestedflatbuffer(fbb2, nestedBuffer);
+                var monster = Monster.EndMonster(fbb2);
+                Monster.FinishMonsterBuffer(fbb2, monster);
+            }
+        }
+
+        [Benchmark]
+        public void BuildMonster()
+        {
+            for (int i = 0; i < NumberOfRows; i++)
+            {
+                var builder = new FlatBufferBuilder(16);
+                var str1 = builder.CreateString("MonsterName");
+                Monster.StartMonster(builder);
+                Monster.AddName(builder, str1);
+                Monster.AddHp(builder, 600);
+                Monster.AddMana(builder, 1024);
+                Monster.AddColor(builder, Color.Blue);
+                Monster.AddTestbool(builder, true);
+                Monster.AddTestf(builder, 0.3f);
+                Monster.AddTestf2(builder, 0.2f);
+                Monster.AddTestf3(builder, 0.1f);
+
+                var monster1 = Monster.EndMonster(builder);
+                Monster.FinishMonsterBuffer(builder, monster1);
+            }
+        }
+
+        [Benchmark]
+        public void TestTables()
+        {
+            FlatBufferBuilder builder = new FlatBufferBuilder(1024 * 1024 * 32);
+            for (int x = 0; x < 500000; ++x)
+            {
+                var offset = builder.CreateString("T");
+                builder.StartObject(4);
+                builder.AddDouble(3.2);
+                builder.AddDouble(4.2);
+                builder.AddDouble(5.2);
+                builder.AddOffset(offset.Value);
+                builder.EndObject();
+            }
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/FlatBuffers.Benchmarks/FlatBuffers.Benchmarks.csproj b/third_party/flatbuffers/tests/FlatBuffers.Benchmarks/FlatBuffers.Benchmarks.csproj
new file mode 100644
index 0000000..b900384
--- /dev/null
+++ b/third_party/flatbuffers/tests/FlatBuffers.Benchmarks/FlatBuffers.Benchmarks.csproj
@@ -0,0 +1,21 @@
+﻿<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>netcoreapp2.1</TargetFramework>
+    <LangVersion>latest</LangVersion>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <DefineConstants>$(DefineConstants);UNSAFE_BYTEBUFFER;BYTEBUFFER_NO_BOUNDS_CHECK;ENABLE_SPAN_T</DefineConstants>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="BenchmarkDotNet" Version="0.11.3" />
+    <PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" Version="0.11.3" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Compile Include="..\..\net\FlatBuffers\*.cs" Link="FlatBuffers\%(FileName).cs" />
+    <Compile Include="..\MyGame\**\*.cs" Link="MyGame\Example\%(FileName).cs" />
+  </ItemGroup>
+
+</Project>
diff --git a/third_party/flatbuffers/tests/FlatBuffers.Benchmarks/Program.cs b/third_party/flatbuffers/tests/FlatBuffers.Benchmarks/Program.cs
new file mode 100644
index 0000000..9e63b4b
--- /dev/null
+++ b/third_party/flatbuffers/tests/FlatBuffers.Benchmarks/Program.cs
@@ -0,0 +1,30 @@
+﻿/*
+ * 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.
+ */
+
+using BenchmarkDotNet.Running;
+
+namespace FlatBuffers.Benchmarks
+{
+    public static class Program
+    {
+        public static void Main(string[] args)
+        {
+            BenchmarkSwitcher
+                .FromAssembly(typeof(Program).Assembly)
+                .Run(args);
+        }
+    }
+}
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/FlatBuffers.Test/Assert.cs b/third_party/flatbuffers/tests/FlatBuffers.Test/Assert.cs
new file mode 100644
index 0000000..488c338
--- /dev/null
+++ b/third_party/flatbuffers/tests/FlatBuffers.Test/Assert.cs
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace FlatBuffers.Test
+{
+
+    public class AssertFailedException : Exception
+    {
+        private readonly object _expected;
+        private readonly object _actual;
+
+        public AssertFailedException(object expected, object actual)
+        {
+            _expected = expected;
+            _actual = actual;
+        }
+
+        public override string Message
+        {
+            get { return string.Format("Expected {0} but saw {1}", _expected, _actual); }
+        }
+    }
+
+    public class AssertArrayFailedException : Exception
+    {
+        private readonly int _index;
+        private readonly object _expected;
+        private readonly object _actual;
+
+        public AssertArrayFailedException(int index, object expected, object actual)
+        {
+            _index = index;
+            _expected = expected;
+            _actual = actual;
+        }
+
+        public override string Message
+        {
+            get { return string.Format("Expected {0} at index {1} but saw {2}", _expected, _index, _actual); }
+        }
+    }
+
+    public class AssertUnexpectedThrowException : Exception
+    {
+        private readonly object _expected;
+
+        public AssertUnexpectedThrowException(object expected)
+        {
+            _expected = expected;
+        }
+
+        public override string Message
+        {
+            get { return string.Format("Expected exception of type {0}", _expected); }
+        }
+    }
+
+    public static class Assert
+    {
+        public static void AreEqual<T>(T expected, T actual)
+        {
+            if (!expected.Equals(actual))
+            {
+                throw new AssertFailedException(expected, actual);
+            }
+        }
+
+        public static void ArrayEqual<T>(T[] expected, T[] actual)
+        {
+            if (expected.Length != actual.Length)
+            {
+                throw new AssertFailedException(expected, actual);
+            }
+
+            for(var i = 0; i < expected.Length; ++i)
+            {
+                if (!expected[i].Equals(actual[i]))
+                {
+                    throw new AssertArrayFailedException(i, expected, actual);
+                }
+            }
+        }
+
+        public static void IsTrue(bool value)
+        {
+            if (!value)
+            {
+                throw new AssertFailedException(true, value);
+            }
+        }
+
+        public static void IsFalse(bool value)
+        {
+            if (value)
+            {
+                throw new AssertFailedException(false, value);
+            }
+        }
+
+        public static void Throws<T>(Action action) where T : Exception
+        {
+            var caught = false;
+            try
+            {
+                action();
+            }
+            catch (T)
+            {
+                caught = true;
+            }
+
+            if (!caught)
+            {
+                throw new AssertUnexpectedThrowException(typeof (T));
+            }
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/FlatBuffers.Test/ByteBufferTests.cs b/third_party/flatbuffers/tests/FlatBuffers.Test/ByteBufferTests.cs
new file mode 100644
index 0000000..1c33a2f
--- /dev/null
+++ b/third_party/flatbuffers/tests/FlatBuffers.Test/ByteBufferTests.cs
@@ -0,0 +1,612 @@
+/*
+ * 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.
+ */
+
+using System;
+
+namespace FlatBuffers.Test
+{
+    [FlatBuffersTestClass]
+    public class ByteBufferTests
+    {
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_Length_MatchesBufferLength()
+        {
+            var buffer = new byte[1000];
+            var uut = new ByteBuffer(buffer);
+            Assert.AreEqual(buffer.Length, uut.Length);
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutBytePopulatesBufferAtZeroOffset()
+        {
+            var buffer = new byte[1];
+            var uut = new ByteBuffer(buffer);
+            uut.PutByte(0, (byte)99);
+
+            Assert.AreEqual((byte)99, buffer[0]);
+        }
+
+#if !BYTEBUFFER_NO_BOUNDS_CHECK
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutByteCannotPutAtOffsetPastLength()
+        {
+            var uut = new ByteBuffer(1);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutByte(1, 99));
+        }
+#endif
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutShortPopulatesBufferCorrectly()
+        {
+            var buffer = new byte[2];
+            var uut = new ByteBuffer(buffer);
+            uut.PutShort(0, (short)1);
+
+            // Ensure Endianness was written correctly
+            Assert.AreEqual((byte)1, buffer[0]);
+            Assert.AreEqual((byte)0, buffer[1]);
+        }
+
+#if !BYTEBUFFER_NO_BOUNDS_CHECK
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutShortCannotPutAtOffsetPastLength()
+        {
+            var uut = new ByteBuffer(2);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutShort(2, 99));
+        }
+#endif
+
+#if !BYTEBUFFER_NO_BOUNDS_CHECK
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutShortChecksLength()
+        {
+            var uut = new ByteBuffer(1);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutShort(0, 99));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutShortChecksLengthAndOffset()
+        {
+            var uut = new ByteBuffer(2);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutShort(1, 99));
+        }
+#endif
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutIntPopulatesBufferCorrectly()
+        {
+            var buffer = new byte[4];
+            var uut = new ByteBuffer(buffer);
+            uut.PutInt(0, 0x0A0B0C0D);
+
+            // Ensure Endianness was written correctly
+            Assert.AreEqual(0x0D, buffer[0]);
+            Assert.AreEqual(0x0C, buffer[1]);
+            Assert.AreEqual(0x0B, buffer[2]);
+            Assert.AreEqual(0x0A, buffer[3]);
+        }
+
+#if !BYTEBUFFER_NO_BOUNDS_CHECK
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutIntCannotPutAtOffsetPastLength()
+        {
+            var uut = new ByteBuffer(4);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutInt(2, 0x0A0B0C0D));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutIntChecksLength()
+        {
+            var uut = new ByteBuffer(1);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutInt(0, 0x0A0B0C0D));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutIntChecksLengthAndOffset()
+        {
+            var uut = new ByteBuffer(4);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutInt(2, 0x0A0B0C0D));
+        }
+#endif
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutLongPopulatesBufferCorrectly()
+        {
+            var buffer = new byte[8];
+            var uut = new ByteBuffer(buffer);
+            uut.PutLong(0, 0x010203040A0B0C0D);
+
+            // Ensure Endianness was written correctly
+            Assert.AreEqual(0x0D, buffer[0]);
+            Assert.AreEqual(0x0C, buffer[1]);
+            Assert.AreEqual(0x0B, buffer[2]);
+            Assert.AreEqual(0x0A, buffer[3]);
+            Assert.AreEqual(0x04, buffer[4]);
+            Assert.AreEqual(0x03, buffer[5]);
+            Assert.AreEqual(0x02, buffer[6]);
+            Assert.AreEqual(0x01, buffer[7]);
+        }
+
+#if !BYTEBUFFER_NO_BOUNDS_CHECK
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutLongCannotPutAtOffsetPastLength()
+        {
+            var uut = new ByteBuffer(8);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutLong(2, 0x010203040A0B0C0D));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutLongChecksLength()
+        {
+            var uut = new ByteBuffer(1);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutLong(0, 0x010203040A0B0C0D));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_PutLongChecksLengthAndOffset()
+        {
+            var uut = new ByteBuffer(8);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutLong(2, 0x010203040A0B0C0D));
+        }
+#endif
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_GetByteReturnsCorrectData()
+        {
+            var buffer = new byte[1];
+            buffer[0] = 99;
+            var uut = new ByteBuffer(buffer);
+            Assert.AreEqual((byte)99, uut.Get(0));
+        }
+
+#if !BYTEBUFFER_NO_BOUNDS_CHECK
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_GetByteChecksOffset()
+        {
+            var uut = new ByteBuffer(1);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.Get(1));
+        }
+#endif
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_GetShortReturnsCorrectData()
+        {
+            var buffer = new byte[2];
+            buffer[0] = 1;
+            buffer[1] = 0;
+            var uut = new ByteBuffer(buffer);
+            Assert.AreEqual(1, uut.GetShort(0));
+        }
+
+#if !BYTEBUFFER_NO_BOUNDS_CHECK
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_GetShortChecksOffset()
+        {
+            var uut = new ByteBuffer(2);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetShort(2));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_GetShortChecksLength()
+        {
+            var uut = new ByteBuffer(2);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetShort(1));
+        }
+#endif
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_GetIntReturnsCorrectData()
+        {
+            var buffer = new byte[4];
+            buffer[0] = 0x0D;
+            buffer[1] = 0x0C;
+            buffer[2] = 0x0B;
+            buffer[3] = 0x0A;
+            var uut = new ByteBuffer(buffer);
+            Assert.AreEqual(0x0A0B0C0D, uut.GetInt(0));
+        }
+
+#if !BYTEBUFFER_NO_BOUNDS_CHECK
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_GetIntChecksOffset()
+        {
+            var uut = new ByteBuffer(4);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetInt(4));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_GetIntChecksLength()
+        {
+            var uut = new ByteBuffer(2);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetInt(0));
+        }
+#endif
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_GetLongReturnsCorrectData()
+        {
+            var buffer = new byte[8];
+            buffer[0] = 0x0D;
+            buffer[1] = 0x0C;
+            buffer[2] = 0x0B;
+            buffer[3] = 0x0A;
+            buffer[4] = 0x04;
+            buffer[5] = 0x03;
+            buffer[6] = 0x02;
+            buffer[7] = 0x01;
+            var uut = new ByteBuffer(buffer);
+            Assert.AreEqual(0x010203040A0B0C0D, uut.GetLong(0));
+        }
+
+#if !BYTEBUFFER_NO_BOUNDS_CHECK
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_GetLongChecksOffset()
+        {
+            var uut = new ByteBuffer(8);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetLong(8));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_GetLongChecksLength()
+        {
+            var uut = new ByteBuffer(7);
+            Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetLong(0));
+        }
+#endif
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_ReverseBytesUshort()
+        {
+            const ushort original = (ushort)0x1234U;
+            var reverse = ByteBuffer.ReverseBytes(original);
+            Assert.AreEqual(0x3412U, reverse);
+
+            var rereverse = ByteBuffer.ReverseBytes(reverse);
+            Assert.AreEqual(original, rereverse);
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_ReverseBytesUint()
+        {
+            const uint original = 0x12345678;
+            var reverse = ByteBuffer.ReverseBytes(original);
+            Assert.AreEqual(0x78563412U, reverse);
+
+            var rereverse = ByteBuffer.ReverseBytes(reverse);
+            Assert.AreEqual(original, rereverse);
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_ReverseBytesUlong()
+        {
+            const ulong original = 0x1234567890ABCDEFUL;
+            var reverse = ByteBuffer.ReverseBytes(original);
+            Assert.AreEqual(0xEFCDAB9078563412UL, reverse);
+
+            var rereverse = ByteBuffer.ReverseBytes(reverse);
+            Assert.AreEqual(original, rereverse);
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_ToFullArray_MatchesBuffer()
+        {
+            var buffer = new byte[4];
+            buffer[0] = 0x0D;
+            buffer[1] = 0x0C;
+            buffer[2] = 0x0B;
+            buffer[3] = 0x0A;
+            var uut = new ByteBuffer(buffer);
+            Assert.ArrayEqual(buffer, uut.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_ToSizedArray_MatchesBuffer()
+        {
+            var buffer = new byte[4];
+            buffer[0] = 0x0D;
+            buffer[1] = 0x0C;
+            buffer[2] = 0x0B;
+            buffer[3] = 0x0A;
+            var uut = new ByteBuffer(buffer);
+            Assert.ArrayEqual(buffer, uut.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_Duplicate_MatchesBuffer()
+        {
+            var buffer = new byte[4];
+            buffer[0] = 0x0D;
+            buffer[1] = 0x0C;
+            buffer[2] = 0x0B;
+            buffer[3] = 0x0A;
+            var uut = new ByteBuffer(buffer);
+            Assert.AreEqual(0x0A0B0C0D, uut.GetInt(0));
+
+            // Advance by two bytes
+            uut.Position = 2; uut = uut.Duplicate();
+            Assert.AreEqual(0x0A0B, uut.GetShort(2));
+
+            // Advance by one more byte
+            uut.Position = 1; uut = uut.Duplicate();
+            Assert.AreEqual(0x0A, uut.Get(3));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_To_Array_Float()
+        {
+            const int len = 9;
+
+            // Construct the data array
+            var fData = new float[len];
+            fData[0] = 1.0079F;
+            fData[1] = 4.0026F;
+            fData[2] = 6.941F;
+            fData[3] = 9.0122F;
+            fData[4] = 10.811F;
+            fData[5] = 12.0107F;
+            fData[6] = 14.0067F;
+            fData[7] = 15.9994F;
+            fData[8] = 18.9984F;
+
+            // Tranfer it to a byte array
+            var buffer = new byte[sizeof(float) * fData.Length];
+            Buffer.BlockCopy(fData, 0, buffer, 0, buffer.Length);
+
+            // Create the Byte Buffer from byte array
+            var uut = new ByteBuffer(buffer);
+
+            // Get the full array back out and ensure they are equivalent
+            var bbArray = uut.ToArray<float>(0, len);
+            Assert.ArrayEqual(fData, bbArray);
+
+            // Get a portion of the full array back out and ensure the
+            // subrange agrees
+            var bbArray2 = uut.ToArray<float>(4, len - 1);
+            Assert.AreEqual(bbArray2.Length, len - 1);
+            for (int i = 1; i < len - 1; i++)
+            {
+                Assert.AreEqual(fData[i], bbArray2[i - 1]);
+            }
+
+            // Get a sub portion of the full array back out and ensure the
+            // subrange agrees
+            var bbArray3 = uut.ToArray<float>(8, len - 4);
+            Assert.AreEqual(bbArray3.Length, len - 4);
+            for (int i = 2; i < len - 4; i++)
+            {
+                Assert.AreEqual(fData[i], bbArray3[i - 2]);
+            }
+        }
+
+        public void ByteBuffer_Put_Array_Helper<T>(T[] data, int typeSize)
+            where T : struct
+        {
+            // Create the Byte Buffer
+            var uut = new ByteBuffer(1024);
+
+            // Put the data into the buffer and make sure the offset is
+            // calculated correctly
+            int nOffset = uut.Put(1024, data);
+            Assert.AreEqual(1024 - typeSize * data.Length, nOffset);
+
+            // Get the full array back out and ensure they are equivalent
+            var bbArray = uut.ToArray<T>(nOffset, data.Length);
+            Assert.ArrayEqual(data, bbArray);
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_Put_Array_Float()
+        {
+            const int len = 9;
+
+            // Construct the data array
+            var data = new float[len];
+            data[0] = 1.0079F;
+            data[1] = 4.0026F;
+            data[2] = 6.941F;
+            data[3] = 9.0122F;
+            data[4] = 10.811F;
+            data[5] = 12.0107F;
+            data[6] = 14.0067F;
+            data[7] = 15.9994F;
+            data[8] = 18.9984F;
+
+            ByteBuffer_Put_Array_Helper(data, sizeof(float));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_Put_Array_Double()
+        {
+            const int len = 9;
+
+            // Construct the data array
+            var data = new double[len];
+            data[0] = 1.0079;
+            data[1] = 4.0026;
+            data[2] = 6.941;
+            data[3] = 9.0122;
+            data[4] = 10.811;
+            data[5] = 12.0107;
+            data[6] = 14.0067;
+            data[7] = 15.9994;
+            data[8] = 18.9984;
+
+            ByteBuffer_Put_Array_Helper(data, sizeof(double));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_Put_Array_Int()
+        {
+            const int len = 9;
+
+            // Construct the data array
+            var data = new int[len];
+            data[0] = 1;
+            data[1] = 4;
+            data[2] = 6;
+            data[3] = 9;
+            data[4] = 10;
+            data[5] = 12;
+            data[6] = 14;
+            data[7] = 15;
+            data[8] = 18;
+
+            ByteBuffer_Put_Array_Helper(data, sizeof(int));
+        }
+
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_Put_Array_UInt()
+        {
+            const int len = 9;
+
+            // Construct the data array
+            var data = new uint[len];
+            data[0] = 1;
+            data[1] = 4;
+            data[2] = 6;
+            data[3] = 9;
+            data[4] = 10;
+            data[5] = 12;
+            data[6] = 14;
+            data[7] = 15;
+            data[8] = 18;
+
+            ByteBuffer_Put_Array_Helper(data, sizeof(uint));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_Put_Array_Bool()
+        {
+            const int len = 9;
+
+            // Construct the data array
+            var data = new bool[len];
+            data[0] = true;
+            data[1] = true;
+            data[2] = false;
+            data[3] = true;
+            data[4] = false;
+            data[5] = true;
+            data[6] = true;
+            data[7] = true;
+            data[8] = false;
+
+            ByteBuffer_Put_Array_Helper(data, sizeof(bool));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_Put_Array_Long()
+        {
+            const int len = 9;
+
+            // Construct the data array
+            var data = new long[len];
+            data[0] = 1;
+            data[1] = 4;
+            data[2] = 6;
+            data[3] = 9;
+            data[4] = 10;
+            data[5] = 12;
+            data[6] = 14;
+            data[7] = 15;
+            data[8] = 18;
+
+            ByteBuffer_Put_Array_Helper(data, sizeof(long));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_Put_Array_Byte()
+        {
+            const int len = 9;
+
+            // Construct the data array
+            var data = new byte[len];
+            data[0] = 1;
+            data[1] = 4;
+            data[2] = 6;
+            data[3] = 9;
+            data[4] = 10;
+            data[5] = 12;
+            data[6] = 14;
+            data[7] = 15;
+            data[8] = 18;
+
+            ByteBuffer_Put_Array_Helper(data, sizeof(byte));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_Put_Array_SByte()
+        {
+            const int len = 9;
+
+            // Construct the data array
+            var data = new sbyte[len];
+            data[0] = 1;
+            data[1] = 4;
+            data[2] = 6;
+            data[3] = 9;
+            data[4] = 10;
+            data[5] = 12;
+            data[6] = 14;
+            data[7] = 15;
+            data[8] = 18;
+
+            ByteBuffer_Put_Array_Helper(data, sizeof(sbyte));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_Put_Array_Null_Throws()
+        {
+            // Create the Byte Buffer
+            var uut = new ByteBuffer(1024);
+
+            // create a null array and try to put it into the buffer
+            float[] data = null;
+            Assert.Throws<ArgumentNullException>(() => uut.Put(1024, data));
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_Put_Array_Empty_Throws()
+        {
+            // Create the Byte Buffer
+            var uut = new ByteBuffer(1024);
+
+            // create an array of length == 0, and try to put it into the buffer
+            float[] data = new float[0];
+            Assert.Throws<ArgumentException>(() => uut.Put(1024, data));
+        }
+
+        private struct dummyStruct
+        {
+            int a;
+            float b;
+        }
+
+        [FlatBuffersTestMethod]
+        public void ByteBuffer_Put_Array_IncorrectType_Throws()
+        {
+            // Create the Byte Buffer
+            var uut = new ByteBuffer(1024);
+
+            // Create an array of dummy structures that shouldn't be
+            // able to be put into the buffer
+            var data = new dummyStruct[10];
+            Assert.Throws<ArgumentException>(() => uut.Put(1024, data));
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/FlatBuffers.Test/FlatBufferBuilderTests.cs b/third_party/flatbuffers/tests/FlatBuffers.Test/FlatBufferBuilderTests.cs
new file mode 100644
index 0000000..d2f49f7
--- /dev/null
+++ b/third_party/flatbuffers/tests/FlatBuffers.Test/FlatBufferBuilderTests.cs
@@ -0,0 +1,354 @@
+/*
+ * 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.
+ */
+
+using System;
+
+namespace FlatBuffers.Test
+{
+    [FlatBuffersTestClass]
+    public class FlatBufferBuilderTests
+    {
+        private FlatBufferBuilder CreateBuffer(bool forceDefaults = true)
+        {
+            var fbb = new FlatBufferBuilder(16) {ForceDefaults = forceDefaults};
+            fbb.StartTable(1);
+            return fbb;
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WithForceDefaults_WhenAddBool_AndDefaultValue_OffsetIncreasesBySize()
+        {
+            var fbb = CreateBuffer();
+            var storedOffset = fbb.Offset;
+            fbb.AddBool(0, false, false);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(sizeof(bool), endOffset-storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WithForceDefaults_WhenAddSByte_AndDefaultValue_OffsetIncreasesBySize()
+        {
+            var fbb = CreateBuffer();
+            var storedOffset = fbb.Offset;
+            fbb.AddSbyte(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(sizeof(sbyte), endOffset - storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WithForceDefaults_WhenAddByte_AndDefaultValue_OffsetIncreasesBySize()
+        {
+            var fbb = CreateBuffer();
+            var storedOffset = fbb.Offset;
+            fbb.AddByte(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(sizeof(byte), endOffset - storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WithForceDefaults_WhenAddShort_AndDefaultValue_OffsetIncreasesBySize()
+        {
+            var fbb = CreateBuffer();
+            var storedOffset = fbb.Offset;
+            fbb.AddShort(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(sizeof(short), endOffset - storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WithForceDefaults_WhenAddUShort_AndDefaultValue_OffsetIncreasesBySize()
+        {
+            var fbb = CreateBuffer();
+            var storedOffset = fbb.Offset;
+            fbb.AddUshort(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(sizeof(ushort), endOffset - storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WithForceDefaults_WhenAddInt_AndDefaultValue_OffsetIncreasesBySize()
+        {
+            var fbb = CreateBuffer();
+            var storedOffset = fbb.Offset;
+            fbb.AddInt(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(sizeof(int), endOffset - storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WithForceDefaults_WhenAddUInt_AndDefaultValue_OffsetIncreasesBySize()
+        {
+            var fbb = CreateBuffer();
+            var storedOffset = fbb.Offset;
+            fbb.AddUint(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(sizeof(uint), endOffset - storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WithForceDefaults_WhenAddLong_AndDefaultValue_OffsetIncreasesBySize()
+        {
+            var fbb = CreateBuffer();
+            var storedOffset = fbb.Offset;
+            fbb.AddLong(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(sizeof(long), endOffset - storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WithForceDefaults_WhenAddULong_AndDefaultValue_OffsetIncreasesBySize()
+        {
+            var fbb = CreateBuffer();
+            var storedOffset = fbb.Offset;
+            fbb.AddUlong(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(sizeof(ulong), endOffset - storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WithForceDefaults_WhenAddFloat_AndDefaultValue_OffsetIncreasesBySize()
+        {
+            var fbb = CreateBuffer();
+            var storedOffset = fbb.Offset;
+            fbb.AddFloat(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(sizeof(float), endOffset - storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WithForceDefaults_WhenAddDouble_AndDefaultValue_OffsetIncreasesBySize()
+        {
+            var fbb = CreateBuffer();
+            var storedOffset = fbb.Offset;
+            fbb.AddDouble(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(sizeof(double), endOffset - storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WhenAddBool_AndDefaultValue_OffsetIsUnchanged()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+            fbb.AddBool(0, false, false);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WhenAddSByte_AndDefaultValue_OffsetIsUnchanged()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+            fbb.AddSbyte(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WhenAddByte_AndDefaultValue_OffsetIsUnchanged()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+            fbb.AddByte(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WhenAddShort_AndDefaultValue_OffsetIsUnchanged()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+            fbb.AddShort(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WhenAddUShort_AndDefaultValue_OffsetIsUnchanged()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+            fbb.AddUshort(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WhenAddInt_AndDefaultValue_OffsetIsUnchanged()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+            fbb.AddInt(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WhenAddUInt_AndDefaultValue_OffsetIsUnchanged()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+            fbb.AddUint(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WhenAddLong_AndDefaultValue_OffsetIsUnchanged()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+            fbb.AddLong(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WhenAddULong_AndDefaultValue_OffsetIsUnchanged()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+            fbb.AddUlong(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WhenAddFloat_AndDefaultValue_OffsetIsUnchanged()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+            fbb.AddFloat(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_WhenAddDouble_AndDefaultValue_OffsetIsUnchanged()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+            fbb.AddDouble(0, 0, 0);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_Add_Array_Float()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+
+            const int len = 9;
+
+            // Construct the data array
+            var data = new float[len];
+            data[0] = 1.0079F;
+            data[1] = 4.0026F;
+            data[2] = 6.941F;
+            data[3] = 9.0122F;
+            data[4] = 10.811F;
+            data[5] = 12.0107F;
+            data[6] = 14.0067F;
+            data[7] = 15.9994F;
+            data[8] = 18.9984F;
+
+            fbb.Add(data);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset + sizeof(float) * data.Length);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_Add_Array_Bool()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+
+            const int len = 9;
+
+            // Construct the data array
+            var data = new bool[len];
+            data[0] = true;
+            data[1] = true;
+            data[2] = false;
+            data[3] = true;
+            data[4] = false;
+            data[5] = true;
+            data[6] = true;
+            data[7] = true;
+            data[8] = false;
+
+            fbb.Add(data);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset + sizeof(bool) * data.Length);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_Add_Array_Double()
+        {
+            var fbb = CreateBuffer(false);
+            var storedOffset = fbb.Offset;
+
+            const int len = 9;
+
+            // Construct the data array
+            var data = new double[len];
+            data[0] = 1.0079;
+            data[1] = 4.0026;
+            data[2] = 6.941;
+            data[3] = 9.0122;
+            data[4] = 10.811;
+            data[5] = 12.0107;
+            data[6] = 14.0067;
+            data[7] = 15.9994;
+            data[8] = 18.9984;
+
+            fbb.Add(data);
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset + sizeof(double) * data.Length);
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_Add_Array_Null_Throws()
+        {
+            var fbb = CreateBuffer(false);
+
+            // Construct the data array
+            float[] data = null;
+
+            Assert.Throws<ArgumentNullException>(() => fbb.Add(data));
+        }
+
+        [FlatBuffersTestMethod]
+        public void FlatBufferBuilder_Add_Array_Empty_Noop()
+        {
+            var fbb = CreateBuffer(false);
+
+            var storedOffset = fbb.Offset;
+
+            // Construct an empty data array
+            float[] data = new float[0];
+            fbb.Add(data);
+
+            // Make sure the offset didn't change since nothing
+            // was really added
+            var endOffset = fbb.Offset;
+            Assert.AreEqual(endOffset, storedOffset);
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/FlatBuffers.Test/FlatBuffers.Test.csproj b/third_party/flatbuffers/tests/FlatBuffers.Test/FlatBuffers.Test.csproj
new file mode 100644
index 0000000..d698d20
--- /dev/null
+++ b/third_party/flatbuffers/tests/FlatBuffers.Test/FlatBuffers.Test.csproj
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{9DB0B5E7-757E-4BD1-A5F6-279390331254}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>FlatBuffers.Test</RootNamespace>
+    <AssemblyName>FlatBuffers.Test</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup>
+    <StartupObject />
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(UnsafeByteBuffer)' == 'true'">
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <DefineConstants>$(DefineConstants);UNSAFE_BYTEBUFFER</DefineConstants>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="..\..\net\FlatBuffers\ByteBuffer.cs">
+      <Link>FlatBuffers\ByteBuffer.cs</Link>
+    </Compile>
+    <Compile Include="..\..\net\FlatBuffers\ByteBufferUtil.cs">
+      <Link>FlatBuffers\ByteBufferUtil.cs</Link>
+    </Compile>
+    <Compile Include="..\..\net\FlatBuffers\IFlatbufferObject.cs">
+      <Link>FlatBuffers\IFlatbufferObject.cs</Link>
+    </Compile>
+    <Compile Include="..\..\net\FlatBuffers\Offset.cs">
+      <Link>FlatBuffers\Offset.cs</Link>
+    </Compile>
+    <Compile Include="..\..\net\FlatBuffers\FlatBufferBuilder.cs">
+      <Link>FlatBuffers\FlatBufferBuilder.cs</Link>
+    </Compile>
+    <Compile Include="..\..\net\FlatBuffers\FlatBufferConstants.cs">
+      <Link>FlatBuffers\FlatBufferConstants.cs</Link>
+    </Compile>
+    <Compile Include="..\..\net\FlatBuffers\Struct.cs">
+      <Link>FlatBuffers\Struct.cs</Link>
+    </Compile>
+    <Compile Include="..\..\net\FlatBuffers\Table.cs">
+      <Link>FlatBuffers\Table.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\Any.cs">
+      <Link>MyGame\Example\Any.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\AnyAmbiguousAliases.cs">
+      <Link>MyGame\Example\AnyAmbiguousAliases.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\AnyUniqueAliases.cs">
+      <Link>MyGame\Example\AnyUniqueAliases.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\Color.cs">
+      <Link>MyGame\Example\Color.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\Monster.cs">
+      <Link>MyGame\Example\Monster.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\Referrable.cs">
+      <Link>MyGame\Example\Referrable.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\Stat.cs">
+      <Link>MyGame\Example\Stat.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\Test.cs">
+      <Link>MyGame\Example\Test.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\TestSimpleTableWithEnum.cs">
+      <Link>MyGame\Example\TestSimpleTableWithEnum.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\Vec3.cs">
+      <Link>MyGame\Example\Vec3.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\Ability.cs">
+      <Link>MyGame\Example\Ability.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\ArrayTable.cs">
+      <Link>MyGame\Example\ArrayTable.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\ArrayStruct.cs">
+      <Link>MyGame\Example\ArrayStruct.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\NestedStruct.cs">
+      <Link>MyGame\Example\NestedStruct.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\Example\TestEnum.cs">
+      <Link>MyGame\Example\TestEnum.cs</Link>
+    </Compile>
+    <Compile Include="..\MyGame\InParentNamespace.cs">
+      <Link>MyGame\InParentNamespace.cs</Link>
+    </Compile>
+    <Compile Include="..\namespace_test\NamespaceA\NamespaceB\EnumInNestedNS.cs">
+      <Link>NamespaceA\NamespaceB\EnumInNestedNS.cs</Link>
+    </Compile>
+    <Compile Include="..\namespace_test\NamespaceA\NamespaceB\StructInNestedNS.cs">
+      <Link>NamespaceA\NamespaceB\StructInNestedNS.cs</Link>
+    </Compile>
+    <Compile Include="..\namespace_test\NamespaceA\NamespaceB\TableInNestedNS.cs">
+      <Link>NamespaceA\NamespaceB\TableInNestedNS.cs</Link>
+    </Compile>
+    <Compile Include="..\namespace_test\NamespaceA\TableInFirstNS.cs">
+      <Link>NamespaceA\TableInFirstNS.cs</Link>
+    </Compile>
+    <Compile Include="Assert.cs" />
+    <Compile Include="ByteBufferTests.cs" />
+    <Compile Include="FlatBufferBuilderTests.cs" />
+    <Compile Include="FlatBuffersFuzzTests.cs" />
+    <Compile Include="FlatBuffersTestClassAttribute.cs" />
+    <Compile Include="FlatBuffersTestMethodAttribute.cs" />
+    <Compile Include="FuzzTestData.cs" />
+    <Compile Include="Lcg.cs" />
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="FlatBuffersExampleTests.cs" />
+    <Compile Include="TestTable.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="..\monsterdata_test.mon">
+      <Link>Resources\monsterdata_test.mon</Link>
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
diff --git a/third_party/flatbuffers/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs b/third_party/flatbuffers/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs
new file mode 100644
index 0000000..b09119c
--- /dev/null
+++ b/third_party/flatbuffers/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs
@@ -0,0 +1,387 @@
+﻿/*
+ * 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.
+ */
+
+using System.IO;
+using System.Text;
+using MyGame.Example;
+
+namespace FlatBuffers.Test
+{
+    [FlatBuffersTestClass]
+    public class FlatBuffersExampleTests
+    {
+        public void RunTests()
+        {
+            CanCreateNewFlatBufferFromScratch();
+            CanReadCppGeneratedWireFile();
+            TestEnums();
+        }
+
+        [FlatBuffersTestMethod]
+        public void CanCreateNewFlatBufferFromScratch()
+        {
+            CanCreateNewFlatBufferFromScratch(true);
+            CanCreateNewFlatBufferFromScratch(false);
+        }
+
+        private void CanCreateNewFlatBufferFromScratch(bool sizePrefix)
+        {
+            // Second, let's create a FlatBuffer from scratch in C#, and test it also.
+            // We use an initial size of 1 to exercise the reallocation algorithm,
+            // normally a size larger than the typical FlatBuffer you generate would be
+            // better for performance.
+            var fbb = new FlatBufferBuilder(1);
+
+            StringOffset[] names = { fbb.CreateString("Frodo"), fbb.CreateString("Barney"), fbb.CreateString("Wilma") };
+            Offset<Monster>[] off = new Offset<Monster>[3];
+            Monster.StartMonster(fbb);
+            Monster.AddName(fbb, names[0]);
+            off[0] = Monster.EndMonster(fbb);
+            Monster.StartMonster(fbb);
+            Monster.AddName(fbb, names[1]);
+            off[1] = Monster.EndMonster(fbb);
+            Monster.StartMonster(fbb);
+            Monster.AddName(fbb, names[2]);
+            off[2] = Monster.EndMonster(fbb);
+            var sortMons = Monster.CreateSortedVectorOfMonster(fbb, off);
+
+            // We set up the same values as monsterdata.json:
+
+            var str = fbb.CreateString("MyMonster");
+            var test1 = fbb.CreateString("test1");
+            var test2 = fbb.CreateString("test2");
+
+
+            Monster.StartInventoryVector(fbb, 5);
+            for (int i = 4; i >= 0; i--)
+            {
+                fbb.AddByte((byte)i);
+            }
+            var inv = fbb.EndVector();
+
+            var fred = fbb.CreateString("Fred");
+            Monster.StartMonster(fbb);
+            Monster.AddName(fbb, fred);
+            var mon2 = Monster.EndMonster(fbb);
+
+            Monster.StartTest4Vector(fbb, 2);
+            MyGame.Example.Test.CreateTest(fbb, (short)10, (sbyte)20);
+            MyGame.Example.Test.CreateTest(fbb, (short)30, (sbyte)40);
+            var test4 = fbb.EndVector();
+
+            Monster.StartTestarrayofstringVector(fbb, 2);
+            fbb.AddOffset(test2.Value);
+            fbb.AddOffset(test1.Value);
+            var testArrayOfString = fbb.EndVector();
+
+            Monster.StartMonster(fbb);
+            Monster.AddPos(fbb, Vec3.CreateVec3(fbb, 1.0f, 2.0f, 3.0f, 3.0,
+                                                     Color.Green, (short)5, (sbyte)6));
+            Monster.AddHp(fbb, (short)80);
+            Monster.AddName(fbb, str);
+            Monster.AddInventory(fbb, inv);
+            Monster.AddTestType(fbb, Any.Monster);
+            Monster.AddTest(fbb, mon2.Value);
+            Monster.AddTest4(fbb, test4);
+            Monster.AddTestarrayofstring(fbb, testArrayOfString);
+            Monster.AddTestbool(fbb, true);
+            Monster.AddTestarrayoftables(fbb, sortMons);
+            var mon = Monster.EndMonster(fbb);
+
+            if (sizePrefix)
+            {
+                Monster.FinishSizePrefixedMonsterBuffer(fbb, mon);
+            }
+            else
+            {
+                Monster.FinishMonsterBuffer(fbb, mon);
+            }
+
+            // Dump to output directory so we can inspect later, if needed
+#if ENABLE_SPAN_T
+            var data = fbb.DataBuffer.ToSizedArray();
+            string filename = @"Resources/monsterdata_cstest" + (sizePrefix ? "_sp" : "") + ".mon";
+            File.WriteAllBytes(filename, data);
+#else
+            using (var ms = fbb.DataBuffer.ToMemoryStream(fbb.DataBuffer.Position, fbb.Offset))
+            {
+                var data = ms.ToArray();
+                string filename = @"Resources/monsterdata_cstest" + (sizePrefix ? "_sp" : "") + ".mon";
+                File.WriteAllBytes(filename, data);
+            }
+#endif
+
+            // Remove the size prefix if necessary for further testing
+            ByteBuffer dataBuffer = fbb.DataBuffer;
+            if (sizePrefix)
+            {
+                Assert.AreEqual(ByteBufferUtil.GetSizePrefix(dataBuffer) + FlatBufferConstants.SizePrefixLength,
+                                dataBuffer.Length - dataBuffer.Position);
+                dataBuffer = ByteBufferUtil.RemoveSizePrefix(dataBuffer);
+            }
+
+            // Now assert the buffer
+            TestBuffer(dataBuffer);
+
+            //Attempt to mutate Monster fields and check whether the buffer has been mutated properly
+            // revert to original values after testing
+            Monster monster = Monster.GetRootAsMonster(dataBuffer);
+            
+
+            // mana is optional and does not exist in the buffer so the mutation should fail
+            // the mana field should retain its default value
+            Assert.AreEqual(monster.MutateMana((short)10), false);
+            Assert.AreEqual(monster.Mana, (short)150);
+
+            // Accessing a vector of sorted by the key tables
+            Assert.AreEqual(monster.Testarrayoftables(0).Value.Name, "Barney");
+            Assert.AreEqual(monster.Testarrayoftables(1).Value.Name, "Frodo");
+            Assert.AreEqual(monster.Testarrayoftables(2).Value.Name, "Wilma");
+
+            // Example of searching for a table by the key
+            Assert.IsTrue(monster.TestarrayoftablesByKey("Frodo") != null);
+            Assert.IsTrue(monster.TestarrayoftablesByKey("Barney") != null);
+            Assert.IsTrue(monster.TestarrayoftablesByKey("Wilma") != null);
+
+            // testType is an existing field and mutating it should succeed
+            Assert.AreEqual(monster.TestType, Any.Monster);
+            Assert.AreEqual(monster.MutateTestType(Any.NONE), true);
+            Assert.AreEqual(monster.TestType, Any.NONE);
+            Assert.AreEqual(monster.MutateTestType(Any.Monster), true);
+            Assert.AreEqual(monster.TestType, Any.Monster);
+
+            //mutate the inventory vector
+            Assert.AreEqual(monster.MutateInventory(0, 1), true);
+            Assert.AreEqual(monster.MutateInventory(1, 2), true);
+            Assert.AreEqual(monster.MutateInventory(2, 3), true);
+            Assert.AreEqual(monster.MutateInventory(3, 4), true);
+            Assert.AreEqual(monster.MutateInventory(4, 5), true);
+
+            for (int i = 0; i < monster.InventoryLength; i++)
+            {
+                Assert.AreEqual(monster.Inventory(i), i + 1);
+            }
+
+            //reverse mutation
+            Assert.AreEqual(monster.MutateInventory(0, 0), true);
+            Assert.AreEqual(monster.MutateInventory(1, 1), true);
+            Assert.AreEqual(monster.MutateInventory(2, 2), true);
+            Assert.AreEqual(monster.MutateInventory(3, 3), true);
+            Assert.AreEqual(monster.MutateInventory(4, 4), true);
+
+            // get a struct field and edit one of its fields
+            Vec3 pos = (Vec3)monster.Pos;
+            Assert.AreEqual(pos.X, 1.0f);
+            pos.MutateX(55.0f);
+            Assert.AreEqual(pos.X, 55.0f);
+            pos.MutateX(1.0f);
+            Assert.AreEqual(pos.X, 1.0f);
+
+            TestBuffer(dataBuffer);
+        }
+
+        private void TestBuffer(ByteBuffer bb)
+        {
+            Monster monster = Monster.GetRootAsMonster(bb);
+
+            Assert.AreEqual(80, monster.Hp);
+            Assert.AreEqual(150, monster.Mana);
+            Assert.AreEqual("MyMonster", monster.Name);
+
+            var pos = monster.Pos.Value;
+            Assert.AreEqual(1.0f, pos.X);
+            Assert.AreEqual(2.0f, pos.Y);
+            Assert.AreEqual(3.0f, pos.Z);
+
+            Assert.AreEqual(3.0f, pos.Test1);
+            Assert.AreEqual(Color.Green, pos.Test2);
+            var t = (MyGame.Example.Test)pos.Test3;
+            Assert.AreEqual((short)5, t.A);
+            Assert.AreEqual((sbyte)6, t.B);
+
+            Assert.AreEqual(Any.Monster, monster.TestType);
+
+            var monster2 = monster.Test<Monster>().Value;
+            Assert.AreEqual("Fred", monster2.Name);
+
+
+            Assert.AreEqual(5, monster.InventoryLength);
+            var invsum = 0;
+            for (var i = 0; i < monster.InventoryLength; i++)
+            {
+                invsum += monster.Inventory(i);
+            }
+            Assert.AreEqual(10, invsum);
+
+            // Get the inventory as an array and subtract the
+            // sum to get it back to 0
+            var inventoryArray = monster.GetInventoryArray();
+            Assert.AreEqual(5, inventoryArray.Length);
+            foreach(var inv in inventoryArray)
+            {
+                invsum -= inv;
+            }
+            Assert.AreEqual(0, invsum);
+
+            var test0 = monster.Test4(0).Value;
+            var test1 = monster.Test4(1).Value;
+            Assert.AreEqual(2, monster.Test4Length);
+
+            Assert.AreEqual(100, test0.A + test0.B + test1.A + test1.B);
+
+            Assert.AreEqual(2, monster.TestarrayofstringLength);
+            Assert.AreEqual("test1", monster.Testarrayofstring(0));
+            Assert.AreEqual("test2", monster.Testarrayofstring(1));
+
+            Assert.AreEqual(true, monster.Testbool);
+
+#if ENABLE_SPAN_T
+            var nameBytes = monster.GetNameBytes();
+            Assert.AreEqual("MyMonster", Encoding.UTF8.GetString(nameBytes.ToArray(), 0, nameBytes.Length));
+
+            if (0 == monster.TestarrayofboolsLength)
+            {
+                Assert.IsFalse(monster.GetTestarrayofboolsBytes().Length != 0);
+            }
+            else
+            {
+                Assert.IsTrue(monster.GetTestarrayofboolsBytes().Length != 0);
+            }
+#else
+            var nameBytes = monster.GetNameBytes().Value;
+            Assert.AreEqual("MyMonster", Encoding.UTF8.GetString(nameBytes.Array, nameBytes.Offset, nameBytes.Count));
+
+            if (0 == monster.TestarrayofboolsLength)
+            {
+                Assert.IsFalse(monster.GetTestarrayofboolsBytes().HasValue);
+            }
+            else
+            {
+                Assert.IsTrue(monster.GetTestarrayofboolsBytes().HasValue);
+            }
+#endif
+        }
+
+        [FlatBuffersTestMethod]
+        public void CanReadCppGeneratedWireFile()
+        {
+            var data = File.ReadAllBytes(@"Resources/monsterdata_test.mon");
+            var bb = new ByteBuffer(data);
+            TestBuffer(bb);
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestEnums()
+        {
+            Assert.AreEqual("Red", Color.Red.ToString());
+            Assert.AreEqual("Blue", Color.Blue.ToString());
+            Assert.AreEqual("NONE", Any.NONE.ToString());
+            Assert.AreEqual("Monster", Any.Monster.ToString());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestNestedFlatBuffer()
+        {
+            const string nestedMonsterName = "NestedMonsterName";
+            const short nestedMonsterHp = 600;
+            const short nestedMonsterMana = 1024;
+            // Create nested buffer as a Monster type
+            var fbb1 = new FlatBufferBuilder(16);
+            var str1 = fbb1.CreateString(nestedMonsterName);
+            Monster.StartMonster(fbb1);
+            Monster.AddName(fbb1, str1);
+            Monster.AddHp(fbb1, nestedMonsterHp);
+            Monster.AddMana(fbb1, nestedMonsterMana);
+            var monster1 = Monster.EndMonster(fbb1);
+            Monster.FinishMonsterBuffer(fbb1, monster1);
+            var fbb1Bytes = fbb1.SizedByteArray();
+            fbb1 = null;
+
+            // Create a Monster which has the first buffer as a nested buffer
+            var fbb2 = new FlatBufferBuilder(16);
+            var str2 = fbb2.CreateString("My Monster");
+            var nestedBuffer = Monster.CreateTestnestedflatbufferVector(fbb2, fbb1Bytes);
+            Monster.StartMonster(fbb2);
+            Monster.AddName(fbb2, str2);
+            Monster.AddHp(fbb2, 50);
+            Monster.AddMana(fbb2, 32);
+            Monster.AddTestnestedflatbuffer(fbb2, nestedBuffer);
+            var monster = Monster.EndMonster(fbb2);
+            Monster.FinishMonsterBuffer(fbb2, monster);
+
+            // Now test the data extracted from the nested buffer
+            var mons = Monster.GetRootAsMonster(fbb2.DataBuffer);
+            var nestedMonster = mons.GetTestnestedflatbufferAsMonster().Value;
+
+            Assert.AreEqual(nestedMonsterMana, nestedMonster.Mana);
+            Assert.AreEqual(nestedMonsterHp, nestedMonster.Hp);
+            Assert.AreEqual(nestedMonsterName, nestedMonster.Name);
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestFixedLenghtArrays()
+        {
+            FlatBufferBuilder builder = new FlatBufferBuilder(100);
+
+            float   a;
+            int[]   b = new int[15];
+            sbyte   c;
+            int[,]  d_a = new int[2, 2];
+            TestEnum[]  d_b = new TestEnum[2];
+            TestEnum[,] d_c = new TestEnum[2, 2];
+
+            a = 0.5f;
+            for (int i = 0; i < 15; i++) b[i] = i;
+            c = 1;
+            d_a[0, 0] = 1;
+            d_a[0, 1] = 2;
+            d_a[1, 0] = 3;
+            d_a[1, 1] = 4;
+            d_b[0] = TestEnum.B;
+            d_b[1] = TestEnum.C;
+            d_c[0, 0] = TestEnum.A;
+            d_c[0, 1] = TestEnum.B;
+            d_c[1, 0] = TestEnum.C;
+            d_c[1, 1] = TestEnum.B;
+
+            Offset<ArrayStruct> arrayOffset = ArrayStruct.CreateArrayStruct(
+                builder, a, b, c, d_a, d_b, d_c);
+
+            // Create a table with the ArrayStruct.
+            ArrayTable.StartArrayTable(builder);
+            ArrayTable.AddA(builder, arrayOffset);
+            Offset<ArrayTable> tableOffset = ArrayTable.EndArrayTable(builder);
+
+            ArrayTable.FinishArrayTableBuffer(builder, tableOffset);
+
+            ArrayTable table = ArrayTable.GetRootAsArrayTable(builder.DataBuffer);
+
+            Assert.AreEqual(table.A?.A, 0.5f);
+            for (int i = 0; i < 15; i++) Assert.AreEqual(table.A?.B(i), i);
+            Assert.AreEqual(table.A?.C, (sbyte)1);
+            Assert.AreEqual(table.A?.D(0).A(0), 1);
+            Assert.AreEqual(table.A?.D(0).A(1), 2);
+            Assert.AreEqual(table.A?.D(1).A(0), 3);
+            Assert.AreEqual(table.A?.D(1).A(1), 4);
+            Assert.AreEqual(table.A?.D(0).B, TestEnum.B);
+            Assert.AreEqual(table.A?.D(1).B, TestEnum.C);
+            Assert.AreEqual(table.A?.D(0).C(0), TestEnum.A);
+            Assert.AreEqual(table.A?.D(0).C(1), TestEnum.B);
+            Assert.AreEqual(table.A?.D(1).C(0), TestEnum.C);
+            Assert.AreEqual(table.A?.D(1).C(1), TestEnum.B);
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/FlatBuffers.Test/FlatBuffersFuzzTests.cs b/third_party/flatbuffers/tests/FlatBuffers.Test/FlatBuffersFuzzTests.cs
new file mode 100644
index 0000000..b6c60ea
--- /dev/null
+++ b/third_party/flatbuffers/tests/FlatBuffers.Test/FlatBuffersFuzzTests.cs
@@ -0,0 +1,811 @@
+/*
+ * 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.
+ */
+
+using System;
+
+namespace FlatBuffers.Test
+{
+    [FlatBuffersTestClass]
+    public class FlatBuffersFuzzTests
+    {
+        private readonly Lcg _lcg = new Lcg();
+
+        [FlatBuffersTestMethod]
+        public void TestObjects()
+        {
+            CheckObjects(11, 100);
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestNumbers()
+        {
+            var builder = new FlatBufferBuilder(1);
+            Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
+            builder.AddBool(true);
+            Assert.ArrayEqual(new byte[] { 1 }, builder.DataBuffer.ToFullArray());
+            builder.AddSbyte(-127);
+            Assert.ArrayEqual(new byte[] { 129, 1 }, builder.DataBuffer.ToFullArray());
+            builder.AddByte(255);
+            Assert.ArrayEqual(new byte[] { 0, 255, 129, 1 }, builder.DataBuffer.ToFullArray()); // First pad
+            builder.AddShort(-32222);
+            Assert.ArrayEqual(new byte[] { 0, 0, 0x22, 0x82, 0, 255, 129, 1 }, builder.DataBuffer.ToFullArray()); // Second pad
+            builder.AddUshort(0xFEEE);
+            Assert.ArrayEqual(new byte[] { 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1 }, builder.DataBuffer.ToFullArray()); // no pad
+            builder.AddInt(-53687092);
+            Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1 }, builder.DataBuffer.ToFullArray()); // third pad
+            builder.AddUint(0x98765432);
+            Assert.ArrayEqual(new byte[] { 0x32, 0x54, 0x76, 0x98, 204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1 }, builder.DataBuffer.ToFullArray()); // no pad
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestNumbers64()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.AddUlong(0x1122334455667788);
+            Assert.ArrayEqual(new byte[] { 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }, builder.DataBuffer.ToFullArray());
+
+            builder = new FlatBufferBuilder(1);
+            builder.AddLong(0x1122334455667788);
+            Assert.ArrayEqual(new byte[] { 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }, builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVector_1xUInt8()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartVector(sizeof(byte), 1, 1);
+            Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }, builder.DataBuffer.ToFullArray());
+            builder.AddByte(1);
+            Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 1, 0, 0, 0 }, builder.DataBuffer.ToFullArray());
+            builder.EndVector();
+            Assert.ArrayEqual(new byte[] { 1, 0, 0, 0, 1, 0, 0, 0 }, builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVector_2xUint8()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartVector(sizeof(byte), 2, 1);
+            Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }, builder.DataBuffer.ToFullArray());
+            builder.AddByte(1);
+            Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 0, 1, 0, 0 }, builder.DataBuffer.ToFullArray());
+            builder.AddByte(2);
+            Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 2, 1, 0, 0 }, builder.DataBuffer.ToFullArray());
+            builder.EndVector();
+            Assert.ArrayEqual(new byte[] { 2, 0, 0, 0, 2, 1, 0, 0 }, builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVector_1xUInt16()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartVector(sizeof(ushort), 1, 1);
+            Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }, builder.DataBuffer.ToFullArray());
+            builder.AddUshort(1);
+            Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 1, 0, 0, 0 }, builder.DataBuffer.ToFullArray());
+            builder.EndVector();
+            Assert.ArrayEqual(new byte[] { 1, 0, 0, 0, 1, 0, 0, 0 }, builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVector_2xUInt16()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartVector(sizeof(ushort), 2, 1);
+            Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }, builder.DataBuffer.ToFullArray());
+            builder.AddUshort(0xABCD);
+            Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 0, 0, 0xCD, 0xAB }, builder.DataBuffer.ToFullArray());
+            builder.AddUshort(0xDCBA);
+            Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 0xBA, 0xDC, 0xCD, 0xAB }, builder.DataBuffer.ToFullArray());
+            builder.EndVector();
+            Assert.ArrayEqual(new byte[] { 2, 0, 0, 0, 0xBA, 0xDC, 0xCD, 0xAB }, builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestCreateAsciiString()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.CreateString("foo");
+            Assert.ArrayEqual(new byte[] { 3, 0, 0, 0, (byte)'f', (byte)'o', (byte)'o', 0 }, builder.DataBuffer.ToFullArray());
+
+            builder.CreateString("moop");
+            Assert.ArrayEqual(new byte[]
+            {
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,  // Padding to 32 bytes
+                4, 0, 0, 0,
+                (byte)'m', (byte)'o', (byte)'o', (byte)'p',
+                0, 0, 0, 0, // zero terminator with 3 byte pad
+                3, 0, 0, 0,
+                (byte)'f', (byte)'o', (byte)'o', 0
+            }, builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestCreateSharedAsciiString()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.CreateSharedString("foo");
+            Assert.ArrayEqual(new byte[] { 3, 0, 0, 0, (byte)'f', (byte)'o', (byte)'o', 0 }, builder.DataBuffer.ToFullArray());
+
+            builder.CreateSharedString("foo");
+            Assert.ArrayEqual(new byte[] { 3, 0, 0, 0, (byte)'f', (byte)'o', (byte)'o', 0 }, builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestCreateArbitarytring()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.CreateString("\x01\x02\x03");
+            Assert.ArrayEqual(new byte[]
+            {
+                3, 0, 0, 0,
+                0x01, 0x02, 0x03, 0
+            }, builder.DataBuffer.ToFullArray()); // No padding
+            builder.CreateString("\x04\x05\x06\x07");
+            Assert.ArrayEqual(new byte[]
+            {
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,  // Padding to 32 bytes
+                4, 0, 0, 0,
+                0x04, 0x05, 0x06, 0x07,
+                0, 0, 0, 0, // zero terminator with 3 byte pad
+                3, 0, 0, 0,
+                0x01, 0x02, 0x03, 0
+            }, builder.DataBuffer.ToFullArray()); // No padding
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestEmptyVTable()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartTable(0);
+            Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
+            builder.EndTable();
+            Assert.ArrayEqual(new byte[]
+            {
+                4, 0, 4, 0,
+                4, 0, 0, 0
+            },
+                builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVTableWithOneBool()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartTable(1);
+            Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
+            builder.AddBool(0, true, false);
+            builder.EndTable();
+            Assert.ArrayEqual(new byte[]
+            {
+                0, 0, // padding to 16 bytes
+                6, 0, // vtable bytes
+                8, 0, // object length inc vtable offset
+                7, 0, // start of bool value
+                6, 0, 0, 0, // int32 offset for start of vtable
+                0, 0, 0, // padding
+                1, // value 0
+            },
+                builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVTableWithOneBool_DefaultValue()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartTable(1);
+            Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
+            builder.AddBool(0, false, false);
+            builder.EndTable();
+            Assert.ArrayEqual(new byte[]
+            {
+                // No padding.
+                4, 0, // vtable bytes
+                4, 0, // end of object from here
+                // entry 0 is not stored (trimmed end of vtable)
+                4, 0, 0, 0, // int32 offset for start of vtable
+            },
+                builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVTableWithOneInt16()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartTable(1);
+            Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
+            builder.AddShort(0, 0x789A, 0);
+            builder.EndTable();
+            Assert.ArrayEqual(new byte[]
+            {
+                0, 0, // padding to 16 bytes
+                6, 0, // vtable bytes
+                8, 0, // object length inc vtable offset
+                6, 0, // start of int16 value
+                6, 0, 0, 0, // int32 offset for start of vtable
+                0, 0, // padding
+                0x9A, 0x78, //value 0
+            },
+                builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVTableWithTwoInt16()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartTable(2);
+            Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
+            builder.AddShort(0, 0x3456, 0);
+            builder.AddShort(1, 0x789A, 0);
+            builder.EndTable();
+            Assert.ArrayEqual(new byte[]
+            {
+                8, 0, // vtable bytes
+                8, 0, // object length inc vtable offset
+                6, 0, // start of int16 value 0
+                4, 0, // start of int16 value 1
+                8, 0, 0, 0, // int32 offset for start of vtable
+                0x9A, 0x78, // value 1
+                0x56, 0x34, // value 0
+            },
+                builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVTableWithInt16AndBool()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartTable(2);
+            Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
+            builder.AddShort(0, 0x3456, 0);
+            builder.AddBool(1, true, false);
+            builder.EndTable();
+            Assert.ArrayEqual(new byte[]
+            {
+                8, 0, // vtable bytes
+                8, 0, // object length inc vtable offset
+                6, 0, // start of int16 value 0
+                5, 0, // start of bool value 1
+                8, 0, 0, 0, // int32 offset for start of vtable
+                0, 1, // padding + value 1
+                0x56, 0x34, // value 0
+            },
+                builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVTableWithEmptyVector()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartVector(sizeof(byte), 0, 1);
+            var vecEnd = builder.EndVector();
+
+            builder.StartTable(1);
+
+            builder.AddOffset(0, vecEnd.Value, 0);
+            builder.EndTable();
+            Assert.ArrayEqual(new byte[]
+            {
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0,       // Padding to 32 bytes
+                6, 0, // vtable bytes
+                8, 0, // object length inc vtable offset
+                4, 0, // start of vector offset value 0
+                6, 0, 0, 0, // int32 offset for start of vtable
+                4, 0, 0, 0,
+                0, 0, 0, 0,
+            },
+                builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVTableWithEmptyVectorAndScalars()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartVector(sizeof(byte), 0, 1);
+            var vecEnd = builder.EndVector();
+
+            builder.StartTable(2);
+            builder.AddShort(0, 55, 0);
+            builder.AddOffset(1, vecEnd.Value, 0);
+            builder.EndTable();
+            Assert.ArrayEqual(new byte[]
+            {
+                0, 0, 0, 0,
+                0, 0, 0, 0, // Padding to 32 bytes
+                8, 0, // vtable bytes
+                12, 0, // object length inc vtable offset
+                10, 0,     // offset to int16 value 0
+                4, 0, // start of vector offset value 1
+                8, 0, 0, 0, // int32 offset for start of vtable
+                8, 0, 0, 0, // value 1
+                0, 0, 55, 0, // value 0
+                0, 0, 0, 0, // length of vector (not in sctruc)
+            },
+                builder.DataBuffer.ToFullArray());
+        }
+
+
+        [FlatBuffersTestMethod]
+        public void TestVTableWith_1xInt16_and_Vector_or_2xInt16()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartVector(sizeof(short), 2, 1);
+            builder.AddShort(0x1234);
+            builder.AddShort(0x5678);
+            var vecEnd = builder.EndVector();
+
+            builder.StartTable(2);
+            builder.AddOffset(1, vecEnd.Value, 0);
+            builder.AddShort(0, 55, 0);
+            builder.EndTable();
+            Assert.ArrayEqual(new byte[]
+            {
+                0, 0, 0, 0, // Padding to 32 bytes
+                8, 0, // vtable bytes
+                12, 0, // object length
+                6, 0,     // start of value 0 from end of vtable
+                8, 0,     // start of value 1 from end of buffer
+                8, 0, 0, 0, // int32 offset for start of vtable
+                0, 0, 55, 0,    // padding + value 0
+                4, 0, 0, 0, // position of vector from here
+                2, 0, 0, 0, // length of vector
+                0x78, 0x56,       // vector value 0
+                0x34, 0x12,       // vector value 1
+            },
+                builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVTableWithAStruct_of_int8_int16_int32()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartTable(1);
+            builder.Prep(4+4+4, 0);
+            builder.AddSbyte(55);
+            builder.Pad(3);
+            builder.AddShort(0x1234);
+            builder.Pad(2);
+            builder.AddInt(0x12345678);
+            var structStart = builder.Offset;
+            builder.AddStruct(0, structStart, 0);
+            builder.EndTable();
+            Assert.ArrayEqual(new byte[]
+            {
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, // Padding to 32 bytes
+                6, 0, // vtable bytes
+                16, 0, // object length
+                4, 0,     // start of struct from here
+                6, 0, 0, 0, // int32 offset for start of vtable
+                0x78, 0x56, 0x34, 0x12,  // struct value 2
+                0x00, 0x00, 0x34, 0x12, // struct value 1
+                0x00, 0x00, 0x00, 55, // struct value 0
+            },
+                builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVTableWithAVectorOf_2xStructOf_2xInt8()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartVector(sizeof(byte)*2, 2, 1);
+            builder.AddByte(33);
+            builder.AddByte(44);
+            builder.AddByte(55);
+            builder.AddByte(66);
+            var vecEnd = builder.EndVector();
+
+            builder.StartTable(1);
+            builder.AddOffset(0, vecEnd.Value, 0);
+            builder.EndTable();
+
+            Assert.ArrayEqual(new byte[]
+            {
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, // Padding to 32 bytes
+                6, 0, // vtable bytes
+                8, 0, // object length
+                4, 0,     // offset of vector offset
+                6, 0, 0, 0, // int32 offset for start of vtable
+                4, 0, 0, 0, // Vector start offset
+                2, 0, 0, 0, // Vector len
+                66, // vector 1, 1
+                55, // vector 1, 0
+                44, // vector 0, 1
+                33, // vector 0, 0
+            },
+                builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestVTableWithSomeElements()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartTable(2);
+            builder.AddByte(0, 33, 0);
+            builder.AddShort(1, 66, 0);
+            var off = builder.EndTable();
+            builder.Finish(off);
+
+            byte[] padded = new byte[]
+            {
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0, //Padding to 32 bytes
+                12, 0, 0, 0,     // root of table, pointing to vtable offset
+                8, 0, // vtable bytes
+                8, 0, // object length
+                7, 0, // start of value 0
+                4, 0, // start of value 1
+                8, 0, 0, 0, // int32 offset for start of vtable
+                66, 0, // value 1
+                0, 33, // value 0
+
+            };
+            Assert.ArrayEqual(padded, builder.DataBuffer.ToFullArray());
+
+            // no padding in sized array
+            byte[] unpadded = new byte[padded.Length - 12];
+            Buffer.BlockCopy(padded, 12, unpadded, 0, unpadded.Length);
+            Assert.ArrayEqual(unpadded, builder.DataBuffer.ToSizedArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestTwoFinishTable()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartTable(2);
+            builder.AddByte(0, 33, 0);
+            builder.AddByte(1, 44, 0);
+            var off0 = builder.EndTable();
+            builder.Finish(off0);
+
+            builder.StartTable(3);
+            builder.AddByte(0, 55, 0);
+            builder.AddByte(1, 66, 0);
+            builder.AddByte(2, 77, 0);
+            var off1 = builder.EndTable();
+            builder.Finish(off1);
+
+            Assert.ArrayEqual(new byte[]
+            {
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,       // padding to 64 bytes
+                16, 0, 0, 0,     // root of table, pointing to vtable offset (obj1)
+                0, 0, // padding
+
+                10, 0, // vtable bytes
+                8, 0, // object length
+                7, 0, // start of value 0
+                6, 0, // start of value 1
+                5, 0, // start of value 2
+                10, 0, 0, 0, // int32 offset for start of vtable
+                0, // pad
+                77, // values 2, 1, 0
+                66,
+                55,
+
+                12, 0, 0, 0,     // root of table, pointing to vtable offset (obj0)
+                8, 0, // vtable bytes
+                8, 0, // object length
+                7, 0, // start of value 0
+                6, 0, // start of value 1
+                8, 0, 0, 0, // int32 offset for start of vtable
+                0, 0, // pad
+                44, // value 1, 0
+                33,
+            },
+                builder.DataBuffer.ToFullArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestBunchOfBools()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartTable(8);
+            for (var i = 0; i < 8; i++)
+            {
+                builder.AddBool(i, true, false);
+            }
+            var off = builder.EndTable();
+            builder.Finish(off);
+
+            byte[] padded = new byte[]
+            {
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,       // padding to 64 bytes
+
+                24, 0, 0, 0,     // root of table, pointing to vtable offset (obj0)
+                20, 0, // vtable bytes
+                12, 0, // object length
+                11, 0, // start of value 0
+                10, 0, // start of value 1
+                9, 0, // start of value 2
+                8, 0, // start of value 3
+                7, 0, // start of value 4
+                6, 0, // start of value 5
+                5, 0, // start of value 6
+                4, 0, // start of value 7
+
+                20, 0, 0, 0, // int32 offset for start of vtable
+
+                1, 1, 1, 1,  // values
+                1, 1, 1, 1,
+
+            };
+            Assert.ArrayEqual(padded, builder.DataBuffer.ToFullArray());
+
+            // no padding in sized array
+            byte[] unpadded = new byte[padded.Length - 28];
+            Buffer.BlockCopy(padded, 28, unpadded, 0, unpadded.Length);
+            Assert.ArrayEqual(unpadded, builder.DataBuffer.ToSizedArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestBunchOfBoolsSizePrefixed()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartTable(8);
+            for (var i = 0; i < 8; i++)
+            {
+                builder.AddBool(i, true, false);
+            }
+            var off = builder.EndTable();
+            builder.FinishSizePrefixed(off);
+
+            byte[] padded = new byte[]
+            {
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,
+                0, 0, 0, 0,      // padding to 64 bytes
+
+                36, 0, 0, 0,     // size prefix
+                24, 0, 0, 0,     // root of table, pointing to vtable offset (obj0)
+                20, 0, // vtable bytes
+                12, 0, // object length
+                11, 0, // start of value 0
+                10, 0, // start of value 1
+                9, 0, // start of value 2
+                8, 0, // start of value 3
+                7, 0, // start of value 4
+                6, 0, // start of value 5
+                5, 0, // start of value 6
+                4, 0, // start of value 7
+
+                20, 0, 0, 0, // int32 offset for start of vtable
+
+                1, 1, 1, 1,  // values
+                1, 1, 1, 1,
+
+            };
+            Assert.ArrayEqual(padded, builder.DataBuffer.ToFullArray());
+
+            // no padding in sized array
+            byte[] unpadded = new byte[padded.Length - 24];
+            Buffer.BlockCopy(padded, 24, unpadded, 0, unpadded.Length);
+            Assert.ArrayEqual(unpadded, builder.DataBuffer.ToSizedArray());
+        }
+
+        [FlatBuffersTestMethod]
+        public void TestWithFloat()
+        {
+            var builder = new FlatBufferBuilder(1);
+            builder.StartTable(1);
+            builder.AddFloat(0, 1, 0);
+            builder.EndTable();
+
+
+            Assert.ArrayEqual(new byte[]
+            {
+                0, 0,
+                6, 0, // vtable bytes
+                8, 0, // object length
+                4, 0, // start of value 0
+                6, 0, 0, 0, // int32 offset for start of vtable
+                0, 0, 128, 63,  // value
+
+            },
+                builder.DataBuffer.ToFullArray());
+        }
+
+        private void CheckObjects(int fieldCount, int objectCount)
+        {
+            _lcg.Reset();
+
+            const int testValuesMax = 11;
+
+            var builder = new FlatBufferBuilder(1);
+
+            var objects = new int[objectCount];
+
+            for (var i = 0; i < objectCount; ++i)
+            {
+                builder.StartTable(fieldCount);
+
+                for (var j = 0; j < fieldCount; ++j)
+                {
+                    var fieldType = _lcg.Next()%testValuesMax;
+
+                    switch (fieldType)
+                    {
+                        case 0:
+                        {
+                            builder.AddBool(j, FuzzTestData.BoolValue, false);
+                            break;
+                        }
+                        case 1:
+                        {
+                            builder.AddSbyte(j, FuzzTestData.Int8Value, 0);
+                            break;
+                        }
+                        case 2:
+                        {
+                            builder.AddByte(j, FuzzTestData.UInt8Value, 0);
+                            break;
+                        }
+                        case 3:
+                        {
+                            builder.AddShort(j, FuzzTestData.Int16Value, 0);
+                            break;
+                        }
+                        case 4:
+                        {
+                            builder.AddUshort(j, FuzzTestData.UInt16Value, 0);
+                            break;
+                        }
+                        case 5:
+                        {
+                            builder.AddInt(j, FuzzTestData.Int32Value, 0);
+                            break;
+                        }
+                        case 6:
+                        {
+                            builder.AddUint(j, FuzzTestData.UInt32Value, 0);
+                            break;
+                        }
+                        case 7:
+                        {
+                            builder.AddLong(j, FuzzTestData.Int64Value, 0);
+                            break;
+                        }
+                        case 8:
+                        {
+                            builder.AddUlong(j, FuzzTestData.UInt64Value, 0);
+                            break;
+                        }
+                        case 9:
+                        {
+                            builder.AddFloat(j, FuzzTestData.Float32Value, 0);
+                            break;
+                        }
+                        case 10:
+                        {
+                            builder.AddDouble(j, FuzzTestData.Float64Value, 0);
+                            break;
+                        }
+                        default:
+                            throw new Exception("Unreachable");
+                    }
+
+                }
+
+                var offset = builder.EndTable();
+
+                // Store the object offset
+                objects[i] = offset;
+            }
+
+            _lcg.Reset();
+
+            // Test all objects are readable and return expected values...
+            for (var i = 0; i < objectCount; ++i)
+            {
+                var table = new TestTable(builder.DataBuffer, builder.DataBuffer.Length - objects[i]);
+
+                for (var j = 0; j < fieldCount; ++j)
+                {
+                    var fieldType = _lcg.Next() % testValuesMax;
+                    var fc = 2 + j; // 2 == VtableMetadataFields
+                    var f = fc * 2;
+
+                    switch (fieldType)
+                    {
+                        case 0:
+                        {
+                            Assert.AreEqual(FuzzTestData.BoolValue, table.GetSlot(f, false));
+                            break;
+                        }
+                        case 1:
+                        {
+                            Assert.AreEqual(FuzzTestData.Int8Value, table.GetSlot(f, (sbyte)0));
+                            break;
+                        }
+                        case 2:
+                        {
+                            Assert.AreEqual(FuzzTestData.UInt8Value, table.GetSlot(f, (byte)0));
+                            break;
+                        }
+                        case 3:
+                        {
+                            Assert.AreEqual(FuzzTestData.Int16Value, table.GetSlot(f, (short)0));
+                            break;
+                        }
+                        case 4:
+                        {
+                            Assert.AreEqual(FuzzTestData.UInt16Value, table.GetSlot(f, (ushort)0));
+                            break;
+                        }
+                        case 5:
+                        {
+                            Assert.AreEqual(FuzzTestData.Int32Value, table.GetSlot(f, (int)0));
+                            break;
+                        }
+                        case 6:
+                        {
+                            Assert.AreEqual(FuzzTestData.UInt32Value, table.GetSlot(f, (uint)0));
+                            break;
+                        }
+                        case 7:
+                        {
+                            Assert.AreEqual(FuzzTestData.Int64Value, table.GetSlot(f, (long)0));
+                            break;
+                        }
+                        case 8:
+                        {
+                            Assert.AreEqual(FuzzTestData.UInt64Value, table.GetSlot(f, (ulong)0));
+                            break;
+                        }
+                        case 9:
+                        {
+                            Assert.AreEqual(FuzzTestData.Float32Value, table.GetSlot(f, (float)0));
+                            break;
+                        }
+                        case 10:
+                        {
+                            Assert.AreEqual(FuzzTestData.Float64Value, table.GetSlot(f, (double)0));
+                            break;
+                        }
+                        default:
+                            throw new Exception("Unreachable");
+                    }
+
+                }
+
+            }
+
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/FlatBuffers.Test/FlatBuffersTestClassAttribute.cs b/third_party/flatbuffers/tests/FlatBuffers.Test/FlatBuffersTestClassAttribute.cs
new file mode 100644
index 0000000..f31e38b
--- /dev/null
+++ b/third_party/flatbuffers/tests/FlatBuffers.Test/FlatBuffersTestClassAttribute.cs
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace FlatBuffers.Test
+{
+    [AttributeUsage(AttributeTargets.Class)]
+    public class FlatBuffersTestClassAttribute : Attribute
+    {
+    }
+}
diff --git a/third_party/flatbuffers/tests/FlatBuffers.Test/FlatBuffersTestMethodAttribute.cs b/third_party/flatbuffers/tests/FlatBuffers.Test/FlatBuffersTestMethodAttribute.cs
new file mode 100644
index 0000000..989dae5
--- /dev/null
+++ b/third_party/flatbuffers/tests/FlatBuffers.Test/FlatBuffersTestMethodAttribute.cs
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+ using System;
+
+namespace FlatBuffers.Test
+{
+    [AttributeUsage(AttributeTargets.Method)]
+    public class FlatBuffersTestMethodAttribute : Attribute
+    {
+    }
+}
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/FlatBuffers.Test/FuzzTestData.cs b/third_party/flatbuffers/tests/FlatBuffers.Test/FuzzTestData.cs
new file mode 100644
index 0000000..119e44e
--- /dev/null
+++ b/third_party/flatbuffers/tests/FlatBuffers.Test/FuzzTestData.cs
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+using System;
+
+namespace FlatBuffers.Test
+{
+    internal static class FuzzTestData
+    {
+        private static readonly byte[] _overflowInt32 = new byte[] {0x83, 0x33, 0x33, 0x33};
+        private static readonly byte[] _overflowInt64 = new byte[] { 0x84, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 };
+
+        public static readonly bool BoolValue = true;
+        public static readonly  sbyte Int8Value = -127;        // 0x81
+        public static readonly  byte UInt8Value = 255;         // 0xFF
+        public static readonly  short Int16Value = -32222;     // 0x8222;
+        public static readonly  ushort UInt16Value = 65262;      // 0xFEEE
+        public static readonly int Int32Value = BitConverter.ToInt32(_overflowInt32, 0);
+        public static readonly uint UInt32Value = 0xFDDDDDDD;
+        public static readonly long Int64Value = BitConverter.ToInt64(_overflowInt64, 0);
+        public static readonly ulong UInt64Value = 0xFCCCCCCCCCCCCCCC;
+        public static readonly float Float32Value = 3.14159f;
+        public static readonly double Float64Value = 3.14159265359;
+    }
+}
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/FlatBuffers.Test/Lcg.cs b/third_party/flatbuffers/tests/FlatBuffers.Test/Lcg.cs
new file mode 100644
index 0000000..c329ed8
--- /dev/null
+++ b/third_party/flatbuffers/tests/FlatBuffers.Test/Lcg.cs
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+namespace FlatBuffers.Test
+{
+    /// <summary>
+    /// Lcg Pseudo RNG
+    /// </summary>
+    internal sealed class Lcg
+    {
+        private const uint InitialValue = 10000;
+        private uint _state;
+
+        public Lcg()
+        {
+            _state = InitialValue;
+        }
+
+        public uint Next()
+        {
+            return (_state = 69069 * _state + 362437);
+        }
+
+        public void Reset()
+        {
+            _state = InitialValue;
+        }
+    }
+}
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/FlatBuffers.Test/NetTest.sh b/third_party/flatbuffers/tests/FlatBuffers.Test/NetTest.sh
new file mode 100644
index 0000000..3822b49
--- /dev/null
+++ b/third_party/flatbuffers/tests/FlatBuffers.Test/NetTest.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# Testing C# on Linux using Mono.
+
+mcs -debug -out:./fbnettest.exe \
+  ../../net/FlatBuffers/*.cs ../MyGame/Example/*.cs ../MyGame/*.cs ../union_vector/*.cs \
+  FlatBuffersTestClassAttribute.cs FlatBuffersTestMethodAttribute.cs Assert.cs FlatBuffersExampleTests.cs Program.cs ByteBufferTests.cs FlatBufferBuilderTests.cs FlatBuffersFuzzTests.cs FuzzTestData.cs Lcg.cs TestTable.cs
+mono --debug ./fbnettest.exe
+rm fbnettest.exe
+rm Resources/monsterdata_cstest.mon
+rm Resources/monsterdata_cstest_sp.mon
+
+# Repeat with unsafe versions
+
+mcs -debug -out:./fbnettest.exe \
+  -unsafe -d:UNSAFE_BYTEBUFFER \
+  ../../net/FlatBuffers/*.cs ../MyGame/Example/*.cs ../MyGame/*.cs ../union_vector/*.cs\
+  FlatBuffersTestClassAttribute.cs FlatBuffersTestMethodAttribute.cs Assert.cs FlatBuffersExampleTests.cs Program.cs ByteBufferTests.cs FlatBufferBuilderTests.cs FlatBuffersFuzzTests.cs FuzzTestData.cs Lcg.cs TestTable.cs
+mono --debug ./fbnettest.exe
+rm fbnettest.exe
+rm Resources/monsterdata_cstest.mon
+rm Resources/monsterdata_cstest_sp.mon
+
diff --git a/third_party/flatbuffers/tests/FlatBuffers.Test/Program.cs b/third_party/flatbuffers/tests/FlatBuffers.Test/Program.cs
new file mode 100644
index 0000000..f8cec4e
--- /dev/null
+++ b/third_party/flatbuffers/tests/FlatBuffers.Test/Program.cs
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+
+namespace FlatBuffers.Test
+{
+    static class Program
+    {
+        public static int Main(string[] args)
+        {
+            var testResults = new List<bool>();
+
+            var testClasses = Assembly.GetExecutingAssembly().GetExportedTypes()
+                .Where(t => t.IsClass && t.GetCustomAttributes(typeof (FlatBuffersTestClassAttribute), false).Length > 0);
+
+            foreach (var testClass in testClasses)
+            {
+                var methods = testClass.GetMethods(BindingFlags.Public |
+                                                         BindingFlags.Instance)
+                          .Where(m => m.GetCustomAttributes(typeof(FlatBuffersTestMethodAttribute), false).Length > 0);
+
+                var inst = Activator.CreateInstance(testClass);
+
+                foreach (var method in methods)
+                {
+                    try
+                    {
+                        method.Invoke(inst, new object[] { });
+                        testResults.Add(true);
+                    }
+                    catch (Exception ex)
+                    {
+                        Console.WriteLine("{0}: FAILED when invoking {1} with error {2}",
+                            testClass.Name ,method.Name, ex.GetBaseException());
+                        testResults.Add(false);
+                    }
+                }
+            }
+
+            var failedCount = testResults.Count(i => i == false);
+
+            Console.WriteLine("{0} tests run, {1} failed", testResults.Count, failedCount);
+
+            if (failedCount > 0)
+            {
+                return -1;
+            }
+            return 0;
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/FlatBuffers.Test/Properties/AssemblyInfo.cs b/third_party/flatbuffers/tests/FlatBuffers.Test/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..2e33f08
--- /dev/null
+++ b/third_party/flatbuffers/tests/FlatBuffers.Test/Properties/AssemblyInfo.cs
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("FlatBuffers.Test")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("FlatBuffers.Test")]
+[assembly: AssemblyCopyright("Copyright (c) 2014  Google Inc")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components.  If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("a1d58a51-3e74-4ae9-aac7-5a399c9eed1a")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/third_party/flatbuffers/tests/FlatBuffers.Test/Resources/monsterdata_test.mon b/third_party/flatbuffers/tests/FlatBuffers.Test/Resources/monsterdata_test.mon
new file mode 100644
index 0000000..3f83972
--- /dev/null
+++ b/third_party/flatbuffers/tests/FlatBuffers.Test/Resources/monsterdata_test.mon
Binary files differ
diff --git a/third_party/flatbuffers/tests/FlatBuffers.Test/TestTable.cs b/third_party/flatbuffers/tests/FlatBuffers.Test/TestTable.cs
new file mode 100644
index 0000000..4f663f0
--- /dev/null
+++ b/third_party/flatbuffers/tests/FlatBuffers.Test/TestTable.cs
@@ -0,0 +1,152 @@
+/*
+ * 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.
+ */
+
+namespace FlatBuffers.Test
+{
+    /// <summary>
+    /// A test Table object that gives easy access to the slot data
+    /// </summary>
+    internal struct TestTable
+    {
+        Table t;
+
+        public TestTable(ByteBuffer bb, int pos)
+        {
+          t = new Table(pos, bb);
+        }
+
+        public bool GetSlot(int slot, bool def)
+        {
+            var off = t.__offset(slot);
+
+            if (off == 0)
+            {
+                return def;
+            }
+            return t.bb.GetSbyte(t.bb_pos + off) != 0;
+        }
+
+        public sbyte GetSlot(int slot, sbyte def)
+        {
+            var off = t.__offset(slot);
+
+            if (off == 0)
+            {
+                return def;
+            }
+            return t.bb.GetSbyte(t.bb_pos + off);
+        }
+
+        public byte GetSlot(int slot, byte def)
+        {
+            var off = t.__offset(slot);
+
+            if (off == 0)
+            {
+                return def;
+            }
+            return t.bb.Get(t.bb_pos + off);
+        }
+
+        public short GetSlot(int slot, short def)
+        {
+            var off = t.__offset(slot);
+
+            if (off == 0)
+            {
+                return def;
+            }
+            return t.bb.GetShort(t.bb_pos + off);
+        }
+
+        public ushort GetSlot(int slot, ushort def)
+        {
+            var off = t.__offset(slot);
+
+            if (off == 0)
+            {
+                return def;
+            }
+            return t.bb.GetUshort(t.bb_pos + off);
+        }
+
+        public int GetSlot(int slot, int def)
+        {
+            var off = t.__offset(slot);
+
+            if (off == 0)
+            {
+                return def;
+            }
+            return t.bb.GetInt(t.bb_pos + off);
+        }
+
+        public uint GetSlot(int slot, uint def)
+        {
+            var off = t.__offset(slot);
+
+            if (off == 0)
+            {
+                return def;
+            }
+            return t.bb.GetUint(t.bb_pos + off);
+        }
+
+        public long GetSlot(int slot, long def)
+        {
+            var off = t.__offset(slot);
+
+            if (off == 0)
+            {
+                return def;
+            }
+            return t.bb.GetLong(t.bb_pos + off);
+        }
+
+        public ulong GetSlot(int slot, ulong def)
+        {
+            var off = t.__offset(slot);
+
+            if (off == 0)
+            {
+                return def;
+            }
+            return t.bb.GetUlong(t.bb_pos + off);
+        }
+
+        public float GetSlot(int slot, float def)
+        {
+            var off = t.__offset(slot);
+
+            if (off == 0)
+            {
+                return def;
+            }
+            return t.bb.GetFloat(t.bb_pos + off);
+        }
+
+        public double GetSlot(int slot, double def)
+        {
+            var off = t.__offset(slot);
+
+            if (off == 0)
+            {
+                return def;
+            }
+            return t.bb.GetDouble(t.bb_pos + off);
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/GoTest.sh b/third_party/flatbuffers/tests/GoTest.sh
new file mode 100755
index 0000000..e69f0d8
--- /dev/null
+++ b/third_party/flatbuffers/tests/GoTest.sh
@@ -0,0 +1,75 @@
+#!/bin/bash -eu
+#
+# 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.
+
+pushd "$(dirname $0)" >/dev/null
+test_dir="$(pwd)"
+go_path=${test_dir}/go_gen
+go_src=${go_path}/src
+
+# Emit Go code for the example schema in the test dir:
+../flatc -g -I include_test monster_test.fbs
+
+# Go requires a particular layout of files in order to link multiple packages.
+# Copy flatbuffer Go files to their own package directories to compile the
+# test binary:
+mkdir -p ${go_src}/MyGame/Example
+mkdir -p ${go_src}/MyGame/Example2
+mkdir -p ${go_src}/github.com/google/flatbuffers/go
+mkdir -p ${go_src}/flatbuffers_test
+
+cp -a MyGame/*.go ./go_gen/src/MyGame/
+cp -a MyGame/Example/*.go ./go_gen/src/MyGame/Example/
+cp -a MyGame/Example2/*.go ./go_gen/src/MyGame/Example2/
+# do not compile the gRPC generated files, which are not tested by go_test.go
+# below, but have their own test.
+rm ./go_gen/src/MyGame/Example/*_grpc.go
+cp -a ../go/* ./go_gen/src/github.com/google/flatbuffers/go
+cp -a ./go_test.go ./go_gen/src/flatbuffers_test/
+
+# Run tests with necessary flags.
+# Developers may wish to see more detail by appending the verbosity flag
+# -test.v to arguments for this command, as in:
+#   go -test -test.v ...
+# Developers may also wish to run benchmarks, which may be achieved with the
+# flag -test.bench and the wildcard regexp ".":
+#   go -test -test.bench=. ...
+GOPATH=${go_path} go test flatbuffers_test \
+                     --test.coverpkg=github.com/google/flatbuffers/go \
+                     --cpp_data=${test_dir}/monsterdata_test.mon \
+                     --out_data=${test_dir}/monsterdata_go_wire.mon \
+                     --test.bench=. \
+                     --test.benchtime=3s \
+                     --fuzz=true \
+                     --fuzz_fields=4 \
+                     --fuzz_objects=10000
+
+GO_TEST_RESULT=$?
+rm -rf ${go_path}/{pkg,src}
+if [[ $GO_TEST_RESULT  == 0 ]]; then
+    echo "OK: Go tests passed."
+else
+    echo "KO: Go tests failed."
+    exit 1
+fi
+
+NOT_FMT_FILES=$(gofmt -l MyGame)
+if [[ ${NOT_FMT_FILES} != "" ]]; then
+    echo "These files are not well gofmt'ed:"
+    echo
+    echo "${NOT_FMT_FILES}"
+    # enable this when enums are properly formated
+    # exit 1
+fi
diff --git a/third_party/flatbuffers/tests/JavaScriptTest.js b/third_party/flatbuffers/tests/JavaScriptTest.js
new file mode 100644
index 0000000..7116daa
--- /dev/null
+++ b/third_party/flatbuffers/tests/JavaScriptTest.js
@@ -0,0 +1,369 @@
+// Run this using JavaScriptTest.sh
+var assert = require('assert');
+var fs = require('fs');
+
+var flatbuffers = require('../js/flatbuffers').flatbuffers;
+var MyGame = require(process.argv[2]).MyGame;
+
+function main() {
+
+  // First, let's test reading a FlatBuffer generated by C++ code:
+  // This file was generated from monsterdata_test.json
+  var data = new Uint8Array(fs.readFileSync('monsterdata_test.mon'));
+
+  // Now test it:
+
+  var bb = new flatbuffers.ByteBuffer(data);
+  testBuffer(bb);
+
+  // Second, let's create a FlatBuffer from scratch in JavaScript, and test it also.
+  // We use an initial size of 1 to exercise the reallocation algorithm,
+  // normally a size larger than the typical FlatBuffer you generate would be
+  // better for performance.
+  var fbb = new flatbuffers.Builder(1);
+  createMonster(fbb);
+  serializeAndTest(fbb);
+
+  // clear the builder, repeat tests
+  var clearIterations = 100;
+  var startingCapacity = fbb.bb.capacity();
+  for (var i = 0; i < clearIterations; i++) {
+    fbb.clear();
+    createMonster(fbb);
+    serializeAndTest(fbb);
+  }
+  // the capacity of our buffer shouldn't increase with the same size payload
+  assert.strictEqual(fbb.bb.capacity(), startingCapacity);
+
+  test64bit();
+  testUnicode();
+  fuzzTest1();
+
+  console.log('FlatBuffers test: completed successfully');
+}
+
+function createMonster(fbb) {
+  // We set up the same values as monsterdata.json:
+
+  var str = fbb.createString('MyMonster');
+
+  var inv = MyGame.Example.Monster.createInventoryVector(fbb, [0, 1, 2, 3, 4]);
+
+  var fred = fbb.createString('Fred');
+  MyGame.Example.Monster.startMonster(fbb);
+  MyGame.Example.Monster.addName(fbb, fred);
+  var mon2 = MyGame.Example.Monster.endMonster(fbb);
+
+  MyGame.Example.Monster.startTest4Vector(fbb, 2);
+  MyGame.Example.Test.createTest(fbb, 10, 20);
+  MyGame.Example.Test.createTest(fbb, 30, 40);
+  var test4 = fbb.endVector();
+
+  var testArrayOfString = MyGame.Example.Monster.createTestarrayofstringVector(fbb, [
+    fbb.createString('test1'),
+    fbb.createString('test2')
+  ]);
+
+  MyGame.Example.Monster.startMonster(fbb);
+  MyGame.Example.Monster.addPos(fbb, MyGame.Example.Vec3.createVec3(fbb, 1, 2, 3, 3, MyGame.Example.Color.Green, 5, 6));
+  MyGame.Example.Monster.addHp(fbb, 80);
+  MyGame.Example.Monster.addName(fbb, str);
+  MyGame.Example.Monster.addInventory(fbb, inv);
+  MyGame.Example.Monster.addTestType(fbb, MyGame.Example.Any.Monster);
+  MyGame.Example.Monster.addTest(fbb, mon2);
+  MyGame.Example.Monster.addTest4(fbb, test4);
+  MyGame.Example.Monster.addTestarrayofstring(fbb, testArrayOfString);
+  MyGame.Example.Monster.addTestbool(fbb, true);
+  var mon = MyGame.Example.Monster.endMonster(fbb);
+
+  MyGame.Example.Monster.finishMonsterBuffer(fbb, mon);
+}
+
+function serializeAndTest(fbb) {
+  // Write the result to a file for debugging purposes:
+  // Note that the binaries are not necessarily identical, since the JSON
+  // parser may serialize in a slightly different order than the above
+  // JavaScript code. They are functionally equivalent though.
+
+  fs.writeFileSync('monsterdata_javascript_wire.mon', new Buffer(fbb.asUint8Array()));
+
+  // Tests mutation first.  This will verify that we did not trample any other
+  // part of the byte buffer.
+  testMutation(fbb.dataBuffer());
+
+  testBuffer(fbb.dataBuffer());
+}
+
+function testMutation(bb) {
+  var monster = MyGame.Example.Monster.getRootAsMonster(bb);
+
+  monster.mutate_hp(120);
+  assert.strictEqual(monster.hp(), 120);
+
+  monster.mutate_hp(80);
+  assert.strictEqual(monster.hp(), 80);
+
+  var manaRes = monster.mutate_mana(10);
+  assert.strictEqual(manaRes, false);  // Field was NOT present, because default value.
+
+  // TODO: There is not the availability to mutate structs or vectors.
+}
+
+function testBuffer(bb) {
+  assert.ok(MyGame.Example.Monster.bufferHasIdentifier(bb));
+
+  var monster = MyGame.Example.Monster.getRootAsMonster(bb);
+
+  assert.strictEqual(monster.hp(), 80);
+  assert.strictEqual(monster.mana(), 150); // default
+
+  assert.strictEqual(monster.name(), 'MyMonster');
+
+  var pos = monster.pos();
+  assert.strictEqual(pos.x(), 1);
+  assert.strictEqual(pos.y(), 2);
+  assert.strictEqual(pos.z(), 3);
+  assert.strictEqual(pos.test1(), 3);
+  assert.strictEqual(pos.test2(), MyGame.Example.Color.Green);
+  var t = pos.test3();
+  assert.strictEqual(t.a(), 5);
+  assert.strictEqual(t.b(), 6);
+
+  assert.strictEqual(monster.testType(), MyGame.Example.Any.Monster);
+  var monster2 = new MyGame.Example.Monster();
+  assert.strictEqual(monster.test(monster2) != null, true);
+  assert.strictEqual(monster2.name(), 'Fred');
+
+  assert.strictEqual(monster.inventoryLength(), 5);
+  var invsum = 0;
+  for (var i = 0; i < monster.inventoryLength(); i++) {
+    invsum += monster.inventory(i);
+  }
+  assert.strictEqual(invsum, 10);
+
+  var invsum2 = 0;
+  var invArr = monster.inventoryArray();
+  for (var i = 0; i < invArr.length; i++) {
+    invsum2 += invArr[i];
+  }
+  assert.strictEqual(invsum2, 10);
+
+  var test_0 = monster.test4(0);
+  var test_1 = monster.test4(1);
+  assert.strictEqual(monster.test4Length(), 2);
+  assert.strictEqual(test_0.a() + test_0.b() + test_1.a() + test_1.b(), 100);
+
+  assert.strictEqual(monster.testarrayofstringLength(), 2);
+  assert.strictEqual(monster.testarrayofstring(0), 'test1');
+  assert.strictEqual(monster.testarrayofstring(1), 'test2');
+
+  assert.strictEqual(monster.testbool(), true);
+}
+
+function test64bit() {
+  var fbb = new flatbuffers.Builder();
+  var required = fbb.createString('required');
+
+  MyGame.Example.Stat.startStat(fbb);
+  var stat2 = MyGame.Example.Stat.endStat(fbb);
+
+  MyGame.Example.Monster.startMonster(fbb);
+  MyGame.Example.Monster.addName(fbb, required);
+  MyGame.Example.Monster.addTestempty(fbb, stat2);
+  var mon2 = MyGame.Example.Monster.endMonster(fbb);
+
+  MyGame.Example.Stat.startStat(fbb);
+  // 2541551405100253985 = 0x87654321(low part) + 0x23456789 * 0x100000000(high part);
+  MyGame.Example.Stat.addVal(fbb, new flatbuffers.Long(0x87654321, 0x23456789));    // the low part is Uint32
+  var stat = MyGame.Example.Stat.endStat(fbb);
+
+  MyGame.Example.Monster.startMonster(fbb);
+  MyGame.Example.Monster.addName(fbb, required);
+  MyGame.Example.Monster.addEnemy(fbb, mon2);
+  MyGame.Example.Monster.addTestempty(fbb, stat);
+  var mon = MyGame.Example.Monster.endMonster(fbb);
+
+  MyGame.Example.Monster.finishMonsterBuffer(fbb, mon);
+  var bytes = fbb.asUint8Array();
+
+  ////////////////////////////////////////////////////////////////
+
+  var bb = new flatbuffers.ByteBuffer(bytes);
+  assert.ok(MyGame.Example.Monster.bufferHasIdentifier(bb));
+  var mon = MyGame.Example.Monster.getRootAsMonster(bb);
+
+  var stat = mon.testempty();
+  assert.strictEqual(stat != null, true);
+  assert.strictEqual(stat.val() != null, true);
+  assert.strictEqual(stat.val().toFloat64(), 2541551405100253985);
+
+  var mon2 = mon.enemy();
+  assert.strictEqual(mon2 != null, true);
+  stat = mon2.testempty();
+  assert.strictEqual(stat != null, true);
+  assert.strictEqual(stat.val() != null, true);
+  assert.strictEqual(stat.val().low, 0); // default value
+  assert.strictEqual(stat.val().high, 0);
+}
+
+function testUnicode() {
+  var correct = fs.readFileSync('unicode_test.mon');
+  var json = JSON.parse(fs.readFileSync('unicode_test.json', 'utf8'));
+
+  // Test reading
+  function testReadingUnicode(bb) {
+    var monster = MyGame.Example.Monster.getRootAsMonster(bb);
+    assert.strictEqual(monster.name(), json.name);
+    assert.deepEqual(new Buffer(monster.name(flatbuffers.Encoding.UTF8_BYTES)), new Buffer(json.name));
+    assert.strictEqual(monster.testarrayoftablesLength(), json.testarrayoftables.length);
+    json.testarrayoftables.forEach(function(table, i) {
+      var value = monster.testarrayoftables(i);
+      assert.strictEqual(value.name(), table.name);
+      assert.deepEqual(new Buffer(value.name(flatbuffers.Encoding.UTF8_BYTES)), new Buffer(table.name));
+    });
+    assert.strictEqual(monster.testarrayofstringLength(), json.testarrayofstring.length);
+    json.testarrayofstring.forEach(function(string, i) {
+      assert.strictEqual(monster.testarrayofstring(i), string);
+      assert.deepEqual(new Buffer(monster.testarrayofstring(i, flatbuffers.Encoding.UTF8_BYTES)), new Buffer(string));
+    });
+  }
+  testReadingUnicode(new flatbuffers.ByteBuffer(new Uint8Array(correct)));
+
+  // Test writing
+  var fbb = new flatbuffers.Builder();
+  var name = fbb.createString(json.name);
+  var testarrayoftablesOffsets = json.testarrayoftables.map(function(table) {
+    var name = fbb.createString(new Uint8Array(new Buffer(table.name)));
+    MyGame.Example.Monster.startMonster(fbb);
+    MyGame.Example.Monster.addName(fbb, name);
+    return MyGame.Example.Monster.endMonster(fbb);
+  });
+  var testarrayoftablesOffset = MyGame.Example.Monster.createTestarrayoftablesVector(fbb,
+    testarrayoftablesOffsets);
+  var testarrayofstringOffset = MyGame.Example.Monster.createTestarrayofstringVector(fbb,
+    json.testarrayofstring.map(function(string) { return fbb.createString(string); }));
+  MyGame.Example.Monster.startMonster(fbb);
+  MyGame.Example.Monster.addTestarrayofstring(fbb, testarrayofstringOffset);
+  MyGame.Example.Monster.addTestarrayoftables(fbb, testarrayoftablesOffset);
+  MyGame.Example.Monster.addName(fbb, name);
+  MyGame.Example.Monster.finishSizePrefixedMonsterBuffer(fbb, MyGame.Example.Monster.endMonster(fbb));
+  var bb = new flatbuffers.ByteBuffer(fbb.asUint8Array())
+  bb.setPosition(4);
+  testReadingUnicode(bb);
+}
+
+var __imul = Math.imul ? Math.imul : function(a, b) {
+  var ah = a >> 16 & 65535;
+  var bh = b >> 16 & 65535;
+  var al = a & 65535;
+  var bl = b & 65535;
+  return al * bl + (ah * bl + al * bh << 16) | 0;
+};
+
+// Include simple random number generator to ensure results will be the
+// same cross platform.
+// http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator
+var lcg_seed = 48271;
+
+function lcg_rand() {
+  return lcg_seed = (__imul(lcg_seed, 279470273) >>> 0) % 4294967291;
+}
+
+function lcg_reset() {
+  lcg_seed = 48271;
+}
+
+// Converts a Field ID to a virtual table offset.
+function fieldIndexToOffset(field_id) {
+  // Should correspond to what EndTable() below builds up.
+  var fixed_fields = 2;  // Vtable size and Object Size.
+  return (field_id + fixed_fields) * 2;
+}
+
+// Low level stress/fuzz test: serialize/deserialize a variety of
+// different kinds of data in different combinations
+function fuzzTest1() {
+
+  // Values we're testing against: chosen to ensure no bits get chopped
+  // off anywhere, and also be different from eachother.
+  var bool_val   = true;
+  var char_val   = -127;  // 0x81
+  var uchar_val  = 0xFF;
+  var short_val  = -32222; // 0x8222;
+  var ushort_val = 0xFEEE;
+  var int_val    = 0x83333333 | 0;
+  var uint_val   = 0xFDDDDDDD;
+  var long_val   = new flatbuffers.Long(0x44444444, 0x84444444);
+  var ulong_val  = new flatbuffers.Long(0xCCCCCCCC, 0xFCCCCCCC);
+  var float_val  = new Float32Array([3.14159])[0];
+  var double_val = 3.14159265359;
+
+  var test_values_max = 11;
+  var fields_per_object = 4;
+  var num_fuzz_objects = 10000;  // The higher, the more thorough :)
+
+  var builder = new flatbuffers.Builder();
+
+  lcg_reset();  // Keep it deterministic.
+
+  var objects = [];
+
+  // Generate num_fuzz_objects random objects each consisting of
+  // fields_per_object fields, each of a random type.
+  for (var i = 0; i < num_fuzz_objects; i++) {
+    builder.startObject(fields_per_object);
+    for (var f = 0; f < fields_per_object; f++) {
+      var choice = lcg_rand() % test_values_max;
+      switch (choice) {
+        case 0:  builder.addFieldInt8(f, bool_val,   0); break;
+        case 1:  builder.addFieldInt8(f, char_val,   0); break;
+        case 2:  builder.addFieldInt8(f, uchar_val,  0); break;
+        case 3:  builder.addFieldInt16(f, short_val,  0); break;
+        case 4:  builder.addFieldInt16(f, ushort_val, 0); break;
+        case 5:  builder.addFieldInt32(f, int_val,    0); break;
+        case 6:  builder.addFieldInt32(f, uint_val,   0); break;
+        case 7:  builder.addFieldInt64(f, long_val,   flatbuffers.Long.ZERO); break;
+        case 8:  builder.addFieldInt64(f, ulong_val,  flatbuffers.Long.ZERO); break;
+        case 9:  builder.addFieldFloat32(f, float_val,  0); break;
+        case 10: builder.addFieldFloat64(f, double_val, 0); break;
+      }
+    }
+    objects.push(builder.endObject());
+  }
+  builder.prep(8, 0);  // Align whole buffer.
+
+  lcg_reset();  // Reset.
+
+  builder.finish(objects[objects.length - 1]);
+  var bytes = new Uint8Array(builder.asUint8Array());
+  var view = new DataView(bytes.buffer);
+
+  // Test that all objects we generated are readable and return the
+  // expected values. We generate random objects in the same order
+  // so this is deterministic.
+  for (var i = 0; i < num_fuzz_objects; i++) {
+    var offset = bytes.length - objects[i];
+    for (var f = 0; f < fields_per_object; f++) {
+      var choice = lcg_rand() % test_values_max;
+      var vtable_offset = fieldIndexToOffset(f);
+      var vtable = offset - view.getInt32(offset, true);
+      assert.ok(vtable_offset < view.getInt16(vtable, true));
+      var field_offset = offset + view.getInt16(vtable + vtable_offset, true);
+      switch (choice) {
+        case 0:  assert.strictEqual(!!view.getInt8(field_offset), bool_val); break;
+        case 1:  assert.strictEqual(view.getInt8(field_offset), char_val); break;
+        case 2:  assert.strictEqual(view.getUint8(field_offset), uchar_val); break;
+        case 3:  assert.strictEqual(view.getInt16(field_offset, true), short_val); break;
+        case 4:  assert.strictEqual(view.getUint16(field_offset, true), ushort_val); break;
+        case 5:  assert.strictEqual(view.getInt32(field_offset, true), int_val); break;
+        case 6:  assert.strictEqual(view.getUint32(field_offset, true), uint_val); break;
+        case 7:  assert.strictEqual(view.getInt32(field_offset, true), long_val.low); assert.strictEqual(view.getInt32(field_offset + 4, true), long_val.high); break;
+        case 8:  assert.strictEqual(view.getInt32(field_offset, true), ulong_val.low); assert.strictEqual(view.getInt32(field_offset + 4, true), ulong_val.high); break;
+        case 9:  assert.strictEqual(view.getFloat32(field_offset, true), float_val); break;
+        case 10: assert.strictEqual(view.getFloat64(field_offset, true), double_val); break;
+      }
+    }
+  }
+}
+
+main();
diff --git a/third_party/flatbuffers/tests/JavaScriptTest.sh b/third_party/flatbuffers/tests/JavaScriptTest.sh
new file mode 100755
index 0000000..c0286a0
--- /dev/null
+++ b/third_party/flatbuffers/tests/JavaScriptTest.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+#
+# 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.
+
+pushd "$(dirname $0)" >/dev/null
+../flatc -b -I include_test monster_test.fbs unicode_test.json
+node JavaScriptTest ./monster_test_generated
diff --git a/third_party/flatbuffers/tests/JavaScriptUnionVectorTest.js b/third_party/flatbuffers/tests/JavaScriptUnionVectorTest.js
new file mode 100644
index 0000000..d79669f
--- /dev/null
+++ b/third_party/flatbuffers/tests/JavaScriptUnionVectorTest.js
@@ -0,0 +1,57 @@
+var assert = require('assert');
+
+var flatbuffers = require('../js/flatbuffers').flatbuffers;
+var Test = require(process.argv[2]);
+
+function main() {
+  var fbb = new flatbuffers.Builder();
+
+  var charTypes = [
+    Test.Character.Belle,
+    Test.Character.MuLan,
+    Test.Character.BookFan,
+  ];
+
+  Test.Attacker.startAttacker(fbb);
+  Test.Attacker.addSwordAttackDamage(fbb, 5);
+  var attackerOffset = Test.Attacker.endAttacker(fbb);
+
+  var charTypesOffset = Test.Movie.createCharactersTypeVector(fbb, charTypes);
+  var charsOffset = Test.Movie.createCharactersVector(
+    fbb,
+    [
+      Test.BookReader.createBookReader(fbb, 7),
+      attackerOffset,
+      Test.BookReader.createBookReader(fbb, 2),
+    ]
+  );
+
+  Test.Movie.startMovie(fbb);
+  Test.Movie.addCharactersType(fbb, charTypesOffset);
+  Test.Movie.addCharacters(fbb, charsOffset);
+  Test.Movie.finishMovieBuffer(fbb, Test.Movie.endMovie(fbb));
+
+  var buf = new flatbuffers.ByteBuffer(fbb.asUint8Array());
+
+  var movie = Test.Movie.getRootAsMovie(buf);
+
+  assert.strictEqual(movie.charactersTypeLength(), charTypes.length);
+  assert.strictEqual(movie.charactersLength(), movie.charactersTypeLength());
+
+  for (var i = 0; i < charTypes.length; ++i) {
+    assert.strictEqual(movie.charactersType(i), charTypes[i]);
+  }
+
+  var bookReader7 = movie.characters(0, new Test.BookReader());
+  assert.strictEqual(bookReader7.booksRead(), 7);
+
+  var attacker = movie.characters(1, new Test.Attacker());
+  assert.strictEqual(attacker.swordAttackDamage(), 5);
+
+  var bookReader2 = movie.characters(2, new Test.BookReader());
+  assert.strictEqual(bookReader2.booksRead(), 2);
+
+  console.log('FlatBuffers union vector test: completed successfully');
+}
+
+main();
diff --git a/third_party/flatbuffers/tests/JavaTest.bat b/third_party/flatbuffers/tests/JavaTest.bat
new file mode 100644
index 0000000..921815a
--- /dev/null
+++ b/third_party/flatbuffers/tests/JavaTest.bat
@@ -0,0 +1,21 @@
+@echo off
+rem Copyright 2014 Google Inc. All rights reserved.
+rem
+rem Licensed under the Apache License, Version 2.0 (the "License");
+rem you may not use this file except in compliance with the License.
+rem You may obtain a copy of the License at
+rem
+rem     http://www.apache.org/licenses/LICENSE-2.0
+rem
+rem Unless required by applicable law or agreed to in writing, software
+rem distributed under the License is distributed on an "AS IS" BASIS,
+rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+rem See the License for the specific language governing permissions and
+rem limitations under the License.
+
+rem Compile then run the Java test.
+
+set batch_file_dir=%~d0%~p0
+
+javac -g -classpath %batch_file_dir%\..\java;%batch_file_dir%;%batch_file_dir%\namespace_test;%batch_file_dir%\union_vector JavaTest.java
+java -classpath %batch_file_dir%\..\java;%batch_file_dir%;%batch_file_dir%\namespace_test;%batch_file_dir%\union_vector JavaTest
diff --git a/third_party/flatbuffers/tests/JavaTest.java b/third_party/flatbuffers/tests/JavaTest.java
new file mode 100644
index 0000000..6505767
--- /dev/null
+++ b/third_party/flatbuffers/tests/JavaTest.java
@@ -0,0 +1,517 @@
+/*
+ * 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.
+ */
+
+import java.io.*;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.FileChannel;
+import MyGame.Example.*;
+import NamespaceA.*;
+import NamespaceA.NamespaceB.*;
+import com.google.flatbuffers.ByteBufferUtil;
+import static com.google.flatbuffers.Constants.*;
+import com.google.flatbuffers.FlatBufferBuilder;
+import MyGame.MonsterExtra;
+
+class JavaTest {
+    public static void main(String[] args) {
+
+        // First, let's test reading a FlatBuffer generated by C++ code:
+        // This file was generated from monsterdata_test.json
+
+        byte[] data = null;
+        File file = new File("monsterdata_test.mon");
+        RandomAccessFile f = null;
+        try {
+            f = new RandomAccessFile(file, "r");
+            data = new byte[(int)f.length()];
+            f.readFully(data);
+            f.close();
+        } catch(java.io.IOException e) {
+            System.out.println("FlatBuffers test: couldn't read file");
+            return;
+        }
+
+        // Now test it:
+
+        ByteBuffer bb = ByteBuffer.wrap(data);
+        TestBuffer(bb);
+
+        // Second, let's create a FlatBuffer from scratch in Java, and test it also.
+        // We use an initial size of 1 to exercise the reallocation algorithm,
+        // normally a size larger than the typical FlatBuffer you generate would be
+        // better for performance.
+        FlatBufferBuilder fbb = new FlatBufferBuilder(1);
+
+        TestBuilderBasics(fbb, true);
+        TestBuilderBasics(fbb, false);
+
+        TestExtendedBuffer(fbb.dataBuffer().asReadOnlyBuffer());
+
+        TestNamespaceNesting();
+
+        TestNestedFlatBuffer();
+
+        TestCreateByteVector();
+
+        TestCreateUninitializedVector();
+
+        TestByteBufferFactory();
+
+        TestSizedInputStream();
+
+        TestVectorOfUnions();
+
+        TestFixedLengthArrays();
+
+        System.out.println("FlatBuffers test: completed successfully");
+    }
+
+    static void TestEnums() {
+      TestEq(Color.name(Color.Red), "Red");
+      TestEq(Color.name(Color.Blue), "Blue");
+      TestEq(Any.name(Any.NONE), "NONE");
+      TestEq(Any.name(Any.Monster), "Monster");
+    }
+
+    static void TestBuffer(ByteBuffer bb) {
+        TestEq(Monster.MonsterBufferHasIdentifier(bb), true);
+
+        Monster monster = Monster.getRootAsMonster(bb);
+
+        TestEq(monster.hp(), (short)80);
+        TestEq(monster.mana(), (short)150);  // default
+
+        TestEq(monster.name(), "MyMonster");
+        // monster.friendly() // can't access, deprecated
+
+        Vec3 pos = monster.pos();
+        TestEq(pos.x(), 1.0f);
+        TestEq(pos.y(), 2.0f);
+        TestEq(pos.z(), 3.0f);
+        TestEq(pos.test1(), 3.0);
+        // issue: int != byte
+        TestEq(pos.test2(), (int) Color.Green);
+        Test t = pos.test3();
+        TestEq(t.a(), (short)5);
+        TestEq(t.b(), (byte)6);
+
+        TestEq(monster.testType(), (byte)Any.Monster);
+        Monster monster2 = new Monster();
+        TestEq(monster.test(monster2) != null, true);
+        TestEq(monster2.name(), "Fred");
+
+        TestEq(monster.inventoryLength(), 5);
+        int invsum = 0;
+        for (int i = 0; i < monster.inventoryLength(); i++)
+            invsum += monster.inventory(i);
+        TestEq(invsum, 10);
+
+        // Alternative way of accessing a vector:
+        ByteBuffer ibb = monster.inventoryAsByteBuffer();
+        invsum = 0;
+        while (ibb.position() < ibb.limit())
+            invsum += ibb.get();
+        TestEq(invsum, 10);
+
+        Test test_0 = monster.test4(0);
+        Test test_1 = monster.test4(1);
+        TestEq(monster.test4Length(), 2);
+        TestEq(test_0.a() + test_0.b() + test_1.a() + test_1.b(), 100);
+
+        TestEq(monster.testarrayofstringLength(), 2);
+        TestEq(monster.testarrayofstring(0),"test1");
+        TestEq(monster.testarrayofstring(1),"test2");
+
+        TestEq(monster.testbool(), true);
+    }
+
+    // this method checks additional fields not present in the binary buffer read from file
+    // these new tests are performed on top of the regular tests
+    static void TestExtendedBuffer(ByteBuffer bb) {
+        TestBuffer(bb);
+
+        Monster monster = Monster.getRootAsMonster(bb);
+
+        TestEq(monster.testhashu32Fnv1(), Integer.MAX_VALUE + 1L);
+    }
+
+    static void TestNamespaceNesting() {
+        // reference / manipulate these to verify compilation
+        FlatBufferBuilder fbb = new FlatBufferBuilder(1);
+
+        TableInNestedNS.startTableInNestedNS(fbb);
+        TableInNestedNS.addFoo(fbb, 1234);
+        int nestedTableOff = TableInNestedNS.endTableInNestedNS(fbb);
+
+        TableInFirstNS.startTableInFirstNS(fbb);
+        TableInFirstNS.addFooTable(fbb, nestedTableOff);
+        int off = TableInFirstNS.endTableInFirstNS(fbb);
+    }
+
+    static void TestNestedFlatBuffer() {
+        final String nestedMonsterName = "NestedMonsterName";
+        final short nestedMonsterHp = 600;
+        final short nestedMonsterMana = 1024;
+
+        FlatBufferBuilder fbb1 = new FlatBufferBuilder(16);
+        int str1 = fbb1.createString(nestedMonsterName);
+        Monster.startMonster(fbb1);
+        Monster.addName(fbb1, str1);
+        Monster.addHp(fbb1, nestedMonsterHp);
+        Monster.addMana(fbb1, nestedMonsterMana);
+        int monster1 = Monster.endMonster(fbb1);
+        Monster.finishMonsterBuffer(fbb1, monster1);
+        byte[] fbb1Bytes = fbb1.sizedByteArray();
+        fbb1 = null;
+
+        FlatBufferBuilder fbb2 = new FlatBufferBuilder(16);
+        int str2 = fbb2.createString("My Monster");
+        int nestedBuffer = Monster.createTestnestedflatbufferVector(fbb2, fbb1Bytes);
+        Monster.startMonster(fbb2);
+        Monster.addName(fbb2, str2);
+        Monster.addHp(fbb2, (short)50);
+        Monster.addMana(fbb2, (short)32);
+        Monster.addTestnestedflatbuffer(fbb2, nestedBuffer);
+        int monster = Monster.endMonster(fbb2);
+        Monster.finishMonsterBuffer(fbb2, monster);
+
+        // Now test the data extracted from the nested buffer
+        Monster mons = Monster.getRootAsMonster(fbb2.dataBuffer());
+        Monster nestedMonster = mons.testnestedflatbufferAsMonster();
+
+        TestEq(nestedMonsterMana, nestedMonster.mana());
+        TestEq(nestedMonsterHp, nestedMonster.hp());
+        TestEq(nestedMonsterName, nestedMonster.name());
+    }
+
+    static void TestCreateByteVector() {
+        FlatBufferBuilder fbb = new FlatBufferBuilder(16);
+        int str = fbb.createString("MyMonster");
+        byte[] inventory = new byte[] { 0, 1, 2, 3, 4 };
+        int vec = fbb.createByteVector(inventory);
+        Monster.startMonster(fbb);
+        Monster.addInventory(fbb, vec);
+        Monster.addName(fbb, str);
+        int monster1 = Monster.endMonster(fbb);
+        Monster.finishMonsterBuffer(fbb, monster1);
+        Monster monsterObject = Monster.getRootAsMonster(fbb.dataBuffer());
+
+        TestEq(monsterObject.inventory(1), (int)inventory[1]);
+        TestEq(monsterObject.inventoryLength(), inventory.length);
+        TestEq(ByteBuffer.wrap(inventory), monsterObject.inventoryAsByteBuffer());
+    }
+
+    static void TestCreateUninitializedVector() {
+        FlatBufferBuilder fbb = new FlatBufferBuilder(16);
+        int str = fbb.createString("MyMonster");
+        byte[] inventory = new byte[] { 0, 1, 2, 3, 4 };
+        ByteBuffer bb = fbb.createUnintializedVector(1, inventory.length, 1);
+        for (byte i:inventory) {
+            bb.put(i);
+        }
+        int vec = fbb.endVector();
+        Monster.startMonster(fbb);
+        Monster.addInventory(fbb, vec);
+        Monster.addName(fbb, str);
+        int monster1 = Monster.endMonster(fbb);
+        Monster.finishMonsterBuffer(fbb, monster1);
+        Monster monsterObject = Monster.getRootAsMonster(fbb.dataBuffer());
+
+        TestEq(monsterObject.inventory(1), (int)inventory[1]);
+        TestEq(monsterObject.inventoryLength(), inventory.length);
+        TestEq(ByteBuffer.wrap(inventory), monsterObject.inventoryAsByteBuffer());
+    }
+
+    static void TestByteBufferFactory() {
+        final class MappedByteBufferFactory extends FlatBufferBuilder.ByteBufferFactory {
+            @Override
+            public ByteBuffer newByteBuffer(int capacity) {
+                ByteBuffer bb;
+                try {
+                    bb =  new RandomAccessFile("javatest.bin", "rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, capacity).order(ByteOrder.LITTLE_ENDIAN);
+                } catch(Throwable e) {
+                    System.out.println("FlatBuffers test: couldn't map ByteBuffer to a file");
+                    bb = null;
+                }
+                return bb;
+            }
+        }
+
+        FlatBufferBuilder fbb = new FlatBufferBuilder(1, new MappedByteBufferFactory());
+
+        TestBuilderBasics(fbb, false);
+    }
+
+    static void TestSizedInputStream() {
+        // Test on default FlatBufferBuilder that uses HeapByteBuffer
+        FlatBufferBuilder fbb = new FlatBufferBuilder(1);
+
+        TestBuilderBasics(fbb, false);
+
+        InputStream in = fbb.sizedInputStream();
+        byte[] array = fbb.sizedByteArray();
+        int count = 0;
+        int currentVal = 0;
+
+        while (currentVal != -1 && count < array.length) {
+            try {
+                currentVal = in.read();
+            } catch(java.io.IOException e) {
+                System.out.println("FlatBuffers test: couldn't read from InputStream");
+                return;
+            }
+            TestEq((byte)currentVal, array[count]);
+            count++;
+        }
+        TestEq(count, array.length);
+    }
+
+    static void TestBuilderBasics(FlatBufferBuilder fbb, boolean sizePrefix) {
+        int[] names = {fbb.createString("Frodo"), fbb.createString("Barney"), fbb.createString("Wilma")};
+        int[] off = new int[3];
+        Monster.startMonster(fbb);
+        Monster.addName(fbb, names[0]);
+        off[0] = Monster.endMonster(fbb);
+        Monster.startMonster(fbb);
+        Monster.addName(fbb, names[1]);
+        off[1] = Monster.endMonster(fbb);
+        Monster.startMonster(fbb);
+        Monster.addName(fbb, names[2]);
+        off[2] = Monster.endMonster(fbb);
+        int sortMons = fbb.createSortedVectorOfTables(new Monster(), off);
+
+        // We set up the same values as monsterdata.json:
+
+        int str = fbb.createString("MyMonster");
+
+        int inv = Monster.createInventoryVector(fbb, new byte[] { 0, 1, 2, 3, 4 });
+
+        int fred = fbb.createString("Fred");
+        Monster.startMonster(fbb);
+        Monster.addName(fbb, fred);
+        int mon2 = Monster.endMonster(fbb);
+
+        Monster.startTest4Vector(fbb, 2);
+        Test.createTest(fbb, (short)10, (byte)20);
+        Test.createTest(fbb, (short)30, (byte)40);
+        int test4 = fbb.endVector();
+
+        int testArrayOfString = Monster.createTestarrayofstringVector(fbb, new int[] {
+                fbb.createString("test1"),
+                fbb.createString("test2")
+        });
+
+        Monster.startMonster(fbb);
+        Monster.addPos(fbb, Vec3.createVec3(fbb, 1.0f, 2.0f, 3.0f, 3.0,
+                Color.Green, (short)5, (byte)6));
+        Monster.addHp(fbb, (short)80);
+        Monster.addName(fbb, str);
+        Monster.addInventory(fbb, inv);
+        Monster.addTestType(fbb, (byte)Any.Monster);
+        Monster.addTest(fbb, mon2);
+        Monster.addTest4(fbb, test4);
+        Monster.addTestarrayofstring(fbb, testArrayOfString);
+        Monster.addTestbool(fbb, true);
+        Monster.addTesthashu32Fnv1(fbb, Integer.MAX_VALUE + 1L);
+        Monster.addTestarrayoftables(fbb, sortMons);
+        int mon = Monster.endMonster(fbb);
+
+        if (sizePrefix) {
+            Monster.finishSizePrefixedMonsterBuffer(fbb, mon);
+        } else {
+            Monster.finishMonsterBuffer(fbb, mon);
+        }
+
+        // Write the result to a file for debugging purposes:
+        // Note that the binaries are not necessarily identical, since the JSON
+        // parser may serialize in a slightly different order than the above
+        // Java code. They are functionally equivalent though.
+
+        try {
+            String filename = "monsterdata_java_wire" + (sizePrefix ? "_sp" : "") + ".mon";
+            FileChannel fc = new FileOutputStream(filename).getChannel();
+            fc.write(fbb.dataBuffer().duplicate());
+            fc.close();
+        } catch(java.io.IOException e) {
+            System.out.println("FlatBuffers test: couldn't write file");
+            return;
+        }
+
+        // Test it:
+        ByteBuffer dataBuffer = fbb.dataBuffer();
+        if (sizePrefix) {
+            TestEq(ByteBufferUtil.getSizePrefix(dataBuffer) + SIZE_PREFIX_LENGTH,
+                   dataBuffer.remaining());
+            dataBuffer = ByteBufferUtil.removeSizePrefix(dataBuffer);
+        }
+        TestExtendedBuffer(dataBuffer);
+
+        // Make sure it also works with read only ByteBuffers. This is slower,
+        // since creating strings incurs an additional copy
+        // (see Table.__string).
+        TestExtendedBuffer(dataBuffer.asReadOnlyBuffer());
+
+        TestEnums();
+
+        //Attempt to mutate Monster fields and check whether the buffer has been mutated properly
+        // revert to original values after testing
+        Monster monster = Monster.getRootAsMonster(dataBuffer);
+
+        // mana is optional and does not exist in the buffer so the mutation should fail
+        // the mana field should retain its default value
+        TestEq(monster.mutateMana((short)10), false);
+        TestEq(monster.mana(), (short)150);
+
+        // Accessing a vector of sorted by the key tables
+        TestEq(monster.testarrayoftables(0).name(), "Barney");
+        TestEq(monster.testarrayoftables(1).name(), "Frodo");
+        TestEq(monster.testarrayoftables(2).name(), "Wilma");
+
+        // Example of searching for a table by the key
+        TestEq(monster.testarrayoftablesByKey("Frodo").name(), "Frodo");
+        TestEq(monster.testarrayoftablesByKey("Barney").name(), "Barney");
+        TestEq(monster.testarrayoftablesByKey("Wilma").name(), "Wilma");
+
+        // testType is an existing field and mutating it should succeed
+        TestEq(monster.testType(), (byte)Any.Monster);
+        TestEq(monster.mutateTestType(Any.NONE), true);
+        TestEq(monster.testType(), (byte)Any.NONE);
+        TestEq(monster.mutateTestType(Any.Monster), true);
+        TestEq(monster.testType(), (byte)Any.Monster);
+
+        //mutate the inventory vector
+        TestEq(monster.mutateInventory(0, 1), true);
+        TestEq(monster.mutateInventory(1, 2), true);
+        TestEq(monster.mutateInventory(2, 3), true);
+        TestEq(monster.mutateInventory(3, 4), true);
+        TestEq(monster.mutateInventory(4, 5), true);
+
+        for (int i = 0; i < monster.inventoryLength(); i++) {
+            TestEq(monster.inventory(i), i + 1);
+        }
+
+        //reverse mutation
+        TestEq(monster.mutateInventory(0, 0), true);
+        TestEq(monster.mutateInventory(1, 1), true);
+        TestEq(monster.mutateInventory(2, 2), true);
+        TestEq(monster.mutateInventory(3, 3), true);
+        TestEq(monster.mutateInventory(4, 4), true);
+
+        // get a struct field and edit one of its fields
+        Vec3 pos = monster.pos();
+        TestEq(pos.x(), 1.0f);
+        pos.mutateX(55.0f);
+        TestEq(pos.x(), 55.0f);
+        pos.mutateX(1.0f);
+        TestEq(pos.x(), 1.0f);
+    }
+
+    static void TestVectorOfUnions() {
+        final FlatBufferBuilder fbb = new FlatBufferBuilder();
+
+        final int swordAttackDamage = 1;
+
+        final int[] characterVector = new int[] {
+            Attacker.createAttacker(fbb, swordAttackDamage),
+        };
+
+        final byte[] characterTypeVector = new byte[]{
+            Character.MuLan,
+        };
+
+        Movie.finishMovieBuffer(
+            fbb,
+            Movie.createMovie(
+                fbb,
+                (byte)0,
+                (byte)0,
+                Movie.createCharactersTypeVector(fbb, characterTypeVector),
+                Movie.createCharactersVector(fbb, characterVector)
+            )
+        );
+
+        final Movie movie = Movie.getRootAsMovie(fbb.dataBuffer());
+
+        TestEq(movie.charactersTypeLength(), characterTypeVector.length);
+        TestEq(movie.charactersLength(), characterVector.length);
+
+        TestEq(movie.charactersType(0), characterTypeVector[0]);
+
+        TestEq(((Attacker)movie.characters(new Attacker(), 0)).swordAttackDamage(), swordAttackDamage);
+    }
+
+    static void TestFixedLengthArrays() {
+        FlatBufferBuilder builder = new FlatBufferBuilder(0);
+
+        float       a;
+        int[]       b = new int[15];
+        byte        c;
+        int[][]     d_a = new int[2][2];
+        byte[]      d_b = new byte[2];
+        byte[][]    d_c = new byte[2][2];
+
+        a = 0.5f;
+        for (int i = 0; i < 15; i++) b[i] = i;
+        c = 1;
+        d_a[0][0] = 1;
+        d_a[0][1] = 2;
+        d_a[1][0] = 3;
+        d_a[1][1] = 4;
+        d_b[0] = TestEnum.B;
+        d_b[1] = TestEnum.C;
+        d_c[0][0] = TestEnum.A;
+        d_c[0][1] = TestEnum.B;
+        d_c[1][0] = TestEnum.C;
+        d_c[1][1] = TestEnum.B;
+
+        int arrayOffset = ArrayStruct.createArrayStruct(builder,
+            a, b, c, d_a, d_b, d_c);
+
+        // Create a table with the ArrayStruct.
+        ArrayTable.startArrayTable(builder);
+        ArrayTable.addA(builder, arrayOffset);
+        int tableOffset = ArrayTable.endArrayTable(builder);
+
+        ArrayTable.finishArrayTableBuffer(builder, tableOffset);
+
+        ArrayTable table = ArrayTable.getRootAsArrayTable(builder.dataBuffer());
+        NestedStruct nested = new NestedStruct();
+
+        TestEq(table.a().a(), 0.5f);
+        for (int i = 0; i < 15; i++) TestEq(table.a().b(i), i);
+        TestEq(table.a().c(), (byte)1);
+        TestEq(table.a().d(nested, 0).a(0), 1);
+        TestEq(table.a().d(nested, 0).a(1), 2);
+        TestEq(table.a().d(nested, 1).a(0), 3);
+        TestEq(table.a().d(nested, 1).a(1), 4);
+        TestEq(table.a().d(nested, 0).b(), TestEnum.B);
+        TestEq(table.a().d(nested, 1).b(), TestEnum.C);
+        TestEq(table.a().d(nested, 0).c(0), TestEnum.A);
+        TestEq(table.a().d(nested, 0).c(1), TestEnum.B);
+        TestEq(table.a().d(nested, 1).c(0), TestEnum.C);
+        TestEq(table.a().d(nested, 1).c(1), TestEnum.B);
+    }
+
+    static <T> void TestEq(T a, T b) {
+        if (!a.equals(b)) {
+            System.out.println("" + a.getClass().getName() + " " + b.getClass().getName());
+            System.out.println("FlatBuffers test FAILED: \'" + a + "\' != \'" + b + "\'");
+            assert false;
+            System.exit(1);
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/JavaTest.sh b/third_party/flatbuffers/tests/JavaTest.sh
new file mode 100755
index 0000000..58d8442
--- /dev/null
+++ b/third_party/flatbuffers/tests/JavaTest.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+#
+# 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.
+
+set -o errexit
+
+echo Compile then run the Java test.
+
+java -version
+
+testdir="$(readlink -fn "$(dirname "$0")")"
+
+targetdir="${testdir}/target"
+
+if [[ -e "${targetdir}" ]]; then
+    echo "cleaning target"
+    rm -rf "${targetdir}"
+fi
+
+mkdir -v "${targetdir}"
+
+if ! find "${testdir}/../java" -type f -name "*.class" -delete; then
+    echo "failed to clean .class files from java directory" >&2
+    exit 1
+fi
+
+javac -d "${targetdir}" -classpath "${testdir}/../java:${testdir}:${testdir}/namespace_test:${testdir}/union_vector" "${testdir}/JavaTest.java"
+
+(cd "${testdir}" && java -classpath "${targetdir}" JavaTest )
+
+rm -rf "${targetdir}"
diff --git a/third_party/flatbuffers/tests/KotlinTest.kt b/third_party/flatbuffers/tests/KotlinTest.kt
new file mode 100644
index 0000000..07f0465
--- /dev/null
+++ b/third_party/flatbuffers/tests/KotlinTest.kt
@@ -0,0 +1,460 @@
+/*
+ * 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.
+ */
+
+import MyGame.Example.*
+import com.google.flatbuffers.ByteBufferUtil
+import com.google.flatbuffers.FlatBufferBuilder
+import NamespaceA.*
+import NamespaceA.NamespaceB.*
+import NamespaceA.NamespaceB.TableInNestedNS
+import java.io.File
+import java.io.FileOutputStream
+import java.io.InputStream
+import java.io.RandomAccessFile
+import java.nio.ByteBuffer
+import java.nio.ByteOrder
+import java.nio.channels.FileChannel
+
+import com.google.flatbuffers.Constants.SIZE_PREFIX_LENGTH
+
+@kotlin.ExperimentalUnsignedTypes
+class KotlinTest {
+
+  companion object {
+    @JvmStatic
+    fun main(args: Array<String>) {
+
+        // First, let's test reading a FlatBuffer generated by C++ code:
+        // This file was generated from monsterdata_test.json
+
+        val data = RandomAccessFile(File("monsterdata_test.mon"), "r").use {
+            val temp = ByteArray(it.length().toInt())
+            it.readFully(temp)
+            temp
+        }
+
+        // Now test it:
+
+        val bb = ByteBuffer.wrap(data)
+        TestBuffer(bb)
+
+        // Second, let's create a FlatBuffer from scratch in Java, and test it also.
+        // We use an initial size of 1 to exercise the reallocation algorithm,
+        // normally a size larger than the typical FlatBuffer you generate would be
+        // better for performance.
+        val fbb = FlatBufferBuilder(1)
+
+        TestBuilderBasics(fbb, true)
+        TestBuilderBasics(fbb, false)
+
+        TestExtendedBuffer(fbb.dataBuffer().asReadOnlyBuffer())
+
+        TestNamespaceNesting()
+
+        TestNestedFlatBuffer()
+
+        TestCreateByteVector()
+
+        TestCreateUninitializedVector()
+
+        TestByteBufferFactory()
+
+        TestSizedInputStream()
+
+        TestVectorOfUnions()
+
+        println("FlatBuffers test: completed successfully")
+    }
+
+    fun TestEnums() {
+        assert(Color.name(Color.Red.toInt()) == "Red")
+        assert(Color.name(Color.Blue.toInt()) == "Blue")
+        assert(Any_.name(Any_.NONE.toInt()) == "NONE")
+        assert(Any_.name(Any_.Monster.toInt()) == "Monster")
+    }
+
+    fun TestBuffer(bb: ByteBuffer) {
+        assert(Monster.MonsterBufferHasIdentifier(bb) == true)
+
+        val monster = Monster.getRootAsMonster(bb)
+
+        assert(monster.hp == 80.toShort())
+        assert(monster.mana == 150.toShort())  // default
+
+        assert(monster.name == "MyMonster")
+        // monster.friendly() // can't access, deprecated
+
+        val pos = monster.pos!!
+        assert(pos.x == 1.0f)
+        assert(pos.y == 2.0f)
+        assert(pos.z == 3.0f)
+        assert(pos.test1 == 3.0)
+        // issue: int != byte
+        assert(pos.test2 == Color.Green)
+        val t = pos.test3!!
+        assert(t.a == 5.toShort())
+        assert(t.b == 6.toByte())
+
+        assert(monster.testType == Any_.Monster)
+        val monster2 = Monster()
+        assert(monster.test(monster2) != null == true)
+        assert(monster2.name == "Fred")
+
+        assert(monster.inventoryLength == 5)
+        var invsum = 0u
+        for (i in 0 until monster.inventoryLength)
+            invsum += monster.inventory(i)
+        assert(invsum == 10u)
+
+        // Alternative way of accessing a vector:
+        val ibb = monster.inventoryAsByteBuffer
+        invsum = 0u
+        while (ibb.position() < ibb.limit())
+            invsum += ibb.get().toUInt()
+        assert(invsum == 10u)
+
+
+        val test_0 = monster.test4(0)!!
+        val test_1 = monster.test4(1)!!
+        assert(monster.test4Length == 2)
+        assert(test_0.a + test_0.b + test_1.a + test_1.b == 100)
+
+        assert(monster.testarrayofstringLength == 2)
+        assert(monster.testarrayofstring(0) == "test1")
+        assert(monster.testarrayofstring(1) == "test2")
+
+        assert(monster.testbool == true)
+    }
+
+    // this method checks additional fields not present in the binary buffer read from file
+    // these new tests are performed on top of the regular tests
+    fun TestExtendedBuffer(bb: ByteBuffer) {
+        TestBuffer(bb)
+
+        val monster = Monster.getRootAsMonster(bb)
+
+        assert(monster.testhashu32Fnv1 == (1u + Integer.MAX_VALUE.toUInt()))
+    }
+
+    fun TestNamespaceNesting() {
+        // reference / manipulate these to verify compilation
+        val fbb = FlatBufferBuilder(1)
+
+        TableInNestedNS.startTableInNestedNS(fbb)
+        TableInNestedNS.addFoo(fbb, 1234)
+        val nestedTableOff = TableInNestedNS.endTableInNestedNS(fbb)
+
+        TableInFirstNS.startTableInFirstNS(fbb)
+        TableInFirstNS.addFooTable(fbb, nestedTableOff)
+    }
+
+    fun TestNestedFlatBuffer() {
+        val nestedMonsterName = "NestedMonsterName"
+        val nestedMonsterHp: Short = 600
+        val nestedMonsterMana: Short = 1024
+
+        var fbb1: FlatBufferBuilder? = FlatBufferBuilder(16)
+        val str1 = fbb1!!.createString(nestedMonsterName)
+        Monster.startMonster(fbb1)
+        Monster.addName(fbb1, str1)
+        Monster.addHp(fbb1, nestedMonsterHp)
+        Monster.addMana(fbb1, nestedMonsterMana)
+        val monster1 = Monster.endMonster(fbb1)
+        Monster.finishMonsterBuffer(fbb1, monster1)
+        val fbb1Bytes = fbb1.sizedByteArray()
+        
+        val fbb2 = FlatBufferBuilder(16)
+        val str2 = fbb2.createString("My Monster")
+        val nestedBuffer = Monster.createTestnestedflatbufferVector(fbb2, fbb1Bytes.asUByteArray())
+        Monster.startMonster(fbb2)
+        Monster.addName(fbb2, str2)
+        Monster.addHp(fbb2, 50.toShort())
+        Monster.addMana(fbb2, 32.toShort())
+        Monster.addTestnestedflatbuffer(fbb2, nestedBuffer)
+        val monster = Monster.endMonster(fbb2)
+        Monster.finishMonsterBuffer(fbb2, monster)
+
+        // Now test the data extracted from the nested buffer
+        val mons = Monster.getRootAsMonster(fbb2.dataBuffer())
+        val nestedMonster = mons.testnestedflatbufferAsMonster!!
+
+        assert(nestedMonsterMana == nestedMonster.mana)
+        assert(nestedMonsterHp == nestedMonster.hp)
+        assert(nestedMonsterName == nestedMonster.name)
+    }
+
+    fun TestCreateByteVector() {
+        val fbb = FlatBufferBuilder(16)
+        val str = fbb.createString("MyMonster")
+        val inventory = byteArrayOf(0, 1, 2, 3, 4)
+        val vec = fbb.createByteVector(inventory)
+        Monster.startMonster(fbb)
+        Monster.addInventory(fbb, vec)
+        Monster.addName(fbb, str)
+        val monster1 = Monster.endMonster(fbb)
+        Monster.finishMonsterBuffer(fbb, monster1)
+        val monsterObject = Monster.getRootAsMonster(fbb.dataBuffer())
+
+        assert(monsterObject.inventory(1) == inventory[1].toUByte())
+        assert(monsterObject.inventoryLength == inventory.size)
+        assert(ByteBuffer.wrap(inventory) == monsterObject.inventoryAsByteBuffer)
+    }
+
+    fun TestCreateUninitializedVector() {
+        val fbb = FlatBufferBuilder(16)
+        val str = fbb.createString("MyMonster")
+        val inventory = byteArrayOf(0, 1, 2, 3, 4)
+        val bb = fbb.createUnintializedVector(1, inventory.size, 1)
+        for (i in inventory) {
+            bb.put(i)
+        }
+        val vec = fbb.endVector()
+        Monster.startMonster(fbb)
+        Monster.addInventory(fbb, vec)
+        Monster.addName(fbb, str)
+        val monster1 = Monster.endMonster(fbb)
+        Monster.finishMonsterBuffer(fbb, monster1)
+        val monsterObject = Monster.getRootAsMonster(fbb.dataBuffer())
+
+        assert(monsterObject.inventory(1) == inventory[1].toUByte())
+        assert(monsterObject.inventoryLength == inventory.size)
+        assert(ByteBuffer.wrap(inventory) == monsterObject.inventoryAsByteBuffer)
+    }
+
+    fun TestByteBufferFactory() {
+        class MappedByteBufferFactory : FlatBufferBuilder.ByteBufferFactory() {
+            override fun newByteBuffer(capacity: Int): ByteBuffer? {
+                var bb: ByteBuffer?
+                try {
+                    bb = RandomAccessFile("javatest.bin", "rw").channel.map(
+                        FileChannel.MapMode.READ_WRITE,
+                        0,
+                        capacity.toLong()
+                    ).order(ByteOrder.LITTLE_ENDIAN)
+                } catch (e: Throwable) {
+                    println("FlatBuffers test: couldn't map ByteBuffer to a file")
+                    bb = null
+                }
+
+                return bb
+            }
+        }
+
+        val fbb = FlatBufferBuilder(1, MappedByteBufferFactory())
+
+        TestBuilderBasics(fbb, false)
+    }
+
+    fun TestSizedInputStream() {
+        // Test on default FlatBufferBuilder that uses HeapByteBuffer
+        val fbb = FlatBufferBuilder(1)
+
+        TestBuilderBasics(fbb, false)
+
+        val `in` = fbb.sizedInputStream()
+        val array = fbb.sizedByteArray()
+        var count = 0
+        var currentVal = 0
+
+        while (currentVal != -1 && count < array.size) {
+            try {
+                currentVal = `in`.read()
+            } catch (e: java.io.IOException) {
+                println("FlatBuffers test: couldn't read from InputStream")
+                return
+            }
+
+            assert(currentVal.toByte() == array[count])
+            count++
+        }
+        assert(count == array.size)
+    }
+
+    fun TestBuilderBasics(fbb: FlatBufferBuilder, sizePrefix: Boolean) {
+        val names = intArrayOf(fbb.createString("Frodo"), fbb.createString("Barney"), fbb.createString("Wilma"))
+        val off = IntArray(3)
+        Monster.startMonster(fbb)
+        Monster.addName(fbb, names[0])
+        off[0] = Monster.endMonster(fbb)
+        Monster.startMonster(fbb)
+        Monster.addName(fbb, names[1])
+        off[1] = Monster.endMonster(fbb)
+        Monster.startMonster(fbb)
+        Monster.addName(fbb, names[2])
+        off[2] = Monster.endMonster(fbb)
+        val sortMons = fbb.createSortedVectorOfTables(Monster(), off)
+
+        // We set up the same values as monsterdata.json:
+
+        val str = fbb.createString("MyMonster")
+
+        val inv = Monster.createInventoryVector(fbb, byteArrayOf(0, 1, 2, 3, 4).asUByteArray())
+
+        val fred = fbb.createString("Fred")
+        Monster.startMonster(fbb)
+        Monster.addName(fbb, fred)
+        val mon2 = Monster.endMonster(fbb)
+
+        Monster.startTest4Vector(fbb, 2)
+        Test.createTest(fbb, 10.toShort(), 20.toByte())
+        Test.createTest(fbb, 30.toShort(), 40.toByte())
+        val test4 = fbb.endVector()
+
+        val testArrayOfString =
+            Monster.createTestarrayofstringVector(fbb, intArrayOf(fbb.createString("test1"), fbb.createString("test2")))
+
+        Monster.startMonster(fbb)
+        Monster.addPos(
+            fbb, Vec3.createVec3(
+                fbb, 1.0f, 2.0f, 3.0f, 3.0,
+                Color.Green, 5.toShort(), 6.toByte()
+            )
+        )
+        Monster.addHp(fbb, 80.toShort())
+        Monster.addName(fbb, str)
+        Monster.addInventory(fbb, inv)
+        Monster.addTestType(fbb, Any_.Monster)
+        Monster.addTest(fbb, mon2)
+        Monster.addTest4(fbb, test4)
+        Monster.addTestarrayofstring(fbb, testArrayOfString)
+        Monster.addTestbool(fbb, true)
+        Monster.addTesthashu32Fnv1(fbb, UInt.MAX_VALUE + 1u)
+        Monster.addTestarrayoftables(fbb, sortMons)
+        val mon = Monster.endMonster(fbb)
+
+        if (sizePrefix) {
+            Monster.finishSizePrefixedMonsterBuffer(fbb, mon)
+        } else {
+            Monster.finishMonsterBuffer(fbb, mon)
+        }
+
+        // Write the result to a file for debugging purposes:
+        // Note that the binaries are not necessarily identical, since the JSON
+        // parser may serialize in a slightly different order than the above
+        // Java code. They are functionally equivalent though.
+
+        try {
+            val filename = "monsterdata_java_wire" + (if (sizePrefix) "_sp" else "") + ".mon"
+            val fc = FileOutputStream(filename).channel
+            fc.write(fbb.dataBuffer().duplicate())
+            fc.close()
+        } catch (e: java.io.IOException) {
+            println("FlatBuffers test: couldn't write file")
+            return
+        }
+
+        // Test it:
+        var dataBuffer = fbb.dataBuffer()
+        if (sizePrefix) {
+            assert(
+                ByteBufferUtil.getSizePrefix(dataBuffer) + SIZE_PREFIX_LENGTH ==
+                dataBuffer.remaining()
+            )
+            dataBuffer = ByteBufferUtil.removeSizePrefix(dataBuffer)
+        }
+        TestExtendedBuffer(dataBuffer)
+
+        // Make sure it also works with read only ByteBuffers. This is slower,
+        // since creating strings incurs an additional copy
+        // (see Table.__string).
+        TestExtendedBuffer(dataBuffer.asReadOnlyBuffer())
+
+        TestEnums()
+
+        //Attempt to mutate Monster fields and check whether the buffer has been mutated properly
+        // revert to original values after testing
+        val monster = Monster.getRootAsMonster(dataBuffer)
+
+        // mana is optional and does not exist in the buffer so the mutation should fail
+        // the mana field should retain its default value
+        assert(monster.mutateMana(10.toShort()) == false)
+        assert(monster.mana == 150.toShort())
+
+        // Accessing a vector of sorted by the key tables
+        assert(monster.testarrayoftables(0)!!.name == "Barney")
+        assert(monster.testarrayoftables(1)!!.name == "Frodo")
+        assert(monster.testarrayoftables(2)!!.name == "Wilma")
+
+        // Example of searching for a table by the key
+        assert(monster.testarrayoftablesByKey("Frodo")!!.name == "Frodo")
+        assert(monster.testarrayoftablesByKey("Barney")!!.name == "Barney")
+        assert(monster.testarrayoftablesByKey("Wilma")!!.name == "Wilma")
+
+        // testType is an existing field and mutating it should succeed
+        assert(monster.testType == Any_.Monster)
+        assert(monster.mutateTestType(Any_.NONE) == true)
+        assert(monster.testType == Any_.NONE)
+        assert(monster.mutateTestType(Any_.Monster) == true)
+        assert(monster.testType == Any_.Monster)
+
+        //mutate the inventory vector
+        assert(monster.mutateInventory(0, 1u) == true)
+        assert(monster.mutateInventory(1, 2u) == true)
+        assert(monster.mutateInventory(2, 3u) == true)
+        assert(monster.mutateInventory(3, 4u) == true)
+        assert(monster.mutateInventory(4, 5u) == true)
+
+        for (i in 0 until monster.inventoryLength) {
+            assert(monster.inventory(i) == (i.toUByte() + 1u).toUByte())
+        }
+
+        //reverse mutation
+        assert(monster.mutateInventory(0, 0u) == true)
+        assert(monster.mutateInventory(1, 1u) == true)
+        assert(monster.mutateInventory(2, 2u) == true)
+        assert(monster.mutateInventory(3, 3u) == true)
+        assert(monster.mutateInventory(4, 4u) == true)
+
+        // get a struct field and edit one of its fields
+        val pos = monster.pos!!
+        assert(pos.x == 1.0f)
+        pos.mutateX(55.0f)
+        assert(pos.x == 55.0f)
+        pos.mutateX(1.0f)
+        assert(pos.x == 1.0f)
+    }
+
+    fun TestVectorOfUnions() {
+        val fbb = FlatBufferBuilder()
+
+        val swordAttackDamage = 1
+
+        val characterVector = intArrayOf(Attacker.createAttacker(fbb, swordAttackDamage))
+
+        val characterTypeVector = ubyteArrayOf(Character_.MuLan)
+
+        Movie.finishMovieBuffer(
+            fbb,
+            Movie.createMovie(
+                fbb,
+                0u,
+                0,
+                Movie.createCharactersTypeVector(fbb, characterTypeVector),
+                Movie.createCharactersVector(fbb, characterVector)
+            )
+        )
+
+        val movie = Movie.getRootAsMovie(fbb.dataBuffer())
+
+        assert(movie.charactersTypeLength == characterTypeVector.size)
+        assert(movie.charactersLength == characterVector.size)
+
+        assert(movie.charactersType(0) == characterTypeVector[0])
+
+        assert((movie.characters(Attacker(), 0) as Attacker).swordAttackDamage == swordAttackDamage)
+    }
+}
+  }
diff --git a/third_party/flatbuffers/tests/KotlinTest.sh b/third_party/flatbuffers/tests/KotlinTest.sh
new file mode 100755
index 0000000..709e68c
--- /dev/null
+++ b/third_party/flatbuffers/tests/KotlinTest.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+# 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.
+
+echo Compile then run the Kotlin test.
+
+testdir=$(dirname $0)
+targetdir="${testdir}/kotlin"
+
+if [[ -e "${targetdir}" ]]; then
+    echo "cleaning target"
+    rm -rf "${targetdir}"
+fi
+
+mkdir -v "${targetdir}"
+
+if ! find "${testdir}/../java" -type f -name "*.class" -delete; then
+    echo "failed to clean .class files from java directory" >&2
+    exit 1
+fi
+
+all_kt_files=`find . -name "*.kt" -print`
+
+# Compile java FlatBuffer library 
+javac ${testdir}/../java/com/google/flatbuffers/*.java -d $targetdir
+# Compile Kotlin files
+kotlinc $all_kt_files -classpath $targetdir -include-runtime -d $targetdir
+# Make jar
+jar cvf ${testdir}/kotlin_test.jar -C $targetdir . > /dev/null
+# Run test
+kotlin -cp ${testdir}/kotlin_test.jar KotlinTest
+# clean up
+rm -rf $targetdir
+rm ${testdir}/kotlin_test.jar
diff --git a/third_party/flatbuffers/tests/LuaTest.bat b/third_party/flatbuffers/tests/LuaTest.bat
new file mode 100644
index 0000000..2bbf1d0
--- /dev/null
+++ b/third_party/flatbuffers/tests/LuaTest.bat
@@ -0,0 +1,6 @@
+set buildtype=Release
+if "%1"=="-b" set buildtype=%2
+
+..\%buildtype%\flatc.exe --lua -I include_test monster_test.fbs
+
+lua53.exe luatest.lua
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/LuaTest.sh b/third_party/flatbuffers/tests/LuaTest.sh
new file mode 100755
index 0000000..eb70e8a
--- /dev/null
+++ b/third_party/flatbuffers/tests/LuaTest.sh
@@ -0,0 +1,22 @@
+#!/bin/bash -eu
+#
+# Copyright 2019 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.
+
+pushd "$(dirname $0)" >/dev/null
+test_dir="$(pwd)"
+
+${test_dir}/../flatc --lua -I include_test monster_test.fbs
+
+lua5.3 luatest.lua
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Ability.cs b/third_party/flatbuffers/tests/MyGame/Example/Ability.cs
new file mode 100644
index 0000000..8315985
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Ability.cs
@@ -0,0 +1,32 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct Ability : IFlatbufferObject
+{
+  private Struct __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
+  public Ability __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public uint Id { get { return __p.bb.GetUint(__p.bb_pos + 0); } }
+  public void MutateId(uint id) { __p.bb.PutUint(__p.bb_pos + 0, id); }
+  public uint Distance { get { return __p.bb.GetUint(__p.bb_pos + 4); } }
+  public void MutateDistance(uint distance) { __p.bb.PutUint(__p.bb_pos + 4, distance); }
+
+  public static Offset<MyGame.Example.Ability> CreateAbility(FlatBufferBuilder builder, uint Id, uint Distance) {
+    builder.Prep(4, 8);
+    builder.PutUint(Distance);
+    builder.PutUint(Id);
+    return new Offset<MyGame.Example.Ability>(builder.Offset);
+  }
+};
+
+
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Ability.go b/third_party/flatbuffers/tests/MyGame/Example/Ability.go
new file mode 100644
index 0000000..a56b445
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Ability.go
@@ -0,0 +1,41 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package Example
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+
+type Ability struct {
+	_tab flatbuffers.Struct
+}
+
+func (rcv *Ability) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *Ability) Table() flatbuffers.Table {
+	return rcv._tab.Table
+}
+
+func (rcv *Ability) Id() uint32 {
+	return rcv._tab.GetUint32(rcv._tab.Pos + flatbuffers.UOffsetT(0))
+}
+func (rcv *Ability) MutateId(n uint32) bool {
+	return rcv._tab.MutateUint32(rcv._tab.Pos+flatbuffers.UOffsetT(0), n)
+}
+
+func (rcv *Ability) Distance() uint32 {
+	return rcv._tab.GetUint32(rcv._tab.Pos + flatbuffers.UOffsetT(4))
+}
+func (rcv *Ability) MutateDistance(n uint32) bool {
+	return rcv._tab.MutateUint32(rcv._tab.Pos+flatbuffers.UOffsetT(4), n)
+}
+
+func CreateAbility(builder *flatbuffers.Builder, id uint32, distance uint32) flatbuffers.UOffsetT {
+	builder.Prep(4, 8)
+	builder.PrependUint32(distance)
+	builder.PrependUint32(id)
+	return builder.Offset()
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Ability.java b/third_party/flatbuffers/tests/MyGame/Example/Ability.java
new file mode 100644
index 0000000..1a8ef03
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Ability.java
@@ -0,0 +1,27 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class Ability extends Struct {
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public Ability __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public long id() { return (long)bb.getInt(bb_pos + 0) & 0xFFFFFFFFL; }
+  public void mutateId(long id) { bb.putInt(bb_pos + 0, (int)id); }
+  public long distance() { return (long)bb.getInt(bb_pos + 4) & 0xFFFFFFFFL; }
+  public void mutateDistance(long distance) { bb.putInt(bb_pos + 4, (int)distance); }
+
+  public static int createAbility(FlatBufferBuilder builder, long id, long distance) {
+    builder.prep(4, 8);
+    builder.putInt((int)distance);
+    builder.putInt((int)id);
+    return builder.offset();
+  }
+}
+
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Ability.kt b/third_party/flatbuffers/tests/MyGame/Example/Ability.kt
new file mode 100644
index 0000000..1b644d6
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Ability.kt
@@ -0,0 +1,32 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Ability : Struct() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : Ability {
+        __init(_i, _bb)
+        return this
+    }
+    val id : UInt get() = bb.getInt(bb_pos + 0).toUInt()
+    fun mutateId(id: UInt) : ByteBuffer = bb.putInt(bb_pos + 0, id.toInt())
+    val distance : UInt get() = bb.getInt(bb_pos + 4).toUInt()
+    fun mutateDistance(distance: UInt) : ByteBuffer = bb.putInt(bb_pos + 4, distance.toInt())
+    companion object {
+        fun createAbility(builder: FlatBufferBuilder, id: UInt, distance: UInt) : Int {
+            builder.prep(4, 8)
+            builder.putInt(distance.toInt())
+            builder.putInt(id.toInt())
+            return builder.offset()
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Ability.lua b/third_party/flatbuffers/tests/MyGame/Example/Ability.lua
new file mode 100644
index 0000000..7fb664a
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Ability.lua
@@ -0,0 +1,31 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Example
+
+local flatbuffers = require('flatbuffers')
+
+local Ability = {} -- the module
+local Ability_mt = {} -- the class metatable
+
+function Ability.New()
+    local o = {}
+    setmetatable(o, {__index = Ability_mt})
+    return o
+end
+function Ability_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function Ability_mt:Id()
+    return self.view:Get(flatbuffers.N.Uint32, self.view.pos + 0)
+end
+function Ability_mt:Distance()
+    return self.view:Get(flatbuffers.N.Uint32, self.view.pos + 4)
+end
+function Ability.CreateAbility(builder, id, distance)
+    builder:Prep(4, 8)
+    builder:PrependUint32(distance)
+    builder:PrependUint32(id)
+    return builder:Offset()
+end
+
+return Ability -- return the module
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Ability.php b/third_party/flatbuffers/tests/MyGame/Example/Ability.php
new file mode 100644
index 0000000..c09eca3
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Ability.php
@@ -0,0 +1,52 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame\Example;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class Ability extends Struct
+{
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return Ability
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @return uint
+     */
+    public function GetId()
+    {
+        return $this->bb->getUint($this->bb_pos + 0);
+    }
+
+    /**
+     * @return uint
+     */
+    public function GetDistance()
+    {
+        return $this->bb->getUint($this->bb_pos + 4);
+    }
+
+
+    /**
+     * @return int offset
+     */
+    public static function createAbility(FlatBufferBuilder $builder, $id, $distance)
+    {
+        $builder->prep(4, 8);
+        $builder->putUint($distance);
+        $builder->putUint($id);
+        return $builder->offset();
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Ability.py b/third_party/flatbuffers/tests/MyGame/Example/Ability.py
new file mode 100644
index 0000000..3c4776e
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Ability.py
@@ -0,0 +1,23 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+import flatbuffers
+
+class Ability(object):
+    __slots__ = ['_tab']
+
+    # Ability
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # Ability
+    def Id(self): return self._tab.Get(flatbuffers.number_types.Uint32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(0))
+    # Ability
+    def Distance(self): return self._tab.Get(flatbuffers.number_types.Uint32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(4))
+
+def CreateAbility(builder, id, distance):
+    builder.Prep(4, 8)
+    builder.PrependUint32(distance)
+    builder.PrependUint32(id)
+    return builder.Offset()
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Any.cs b/third_party/flatbuffers/tests/MyGame/Example/Any.cs
new file mode 100644
index 0000000..f95c6bc
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Any.cs
@@ -0,0 +1,17 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+public enum Any : byte
+{
+  NONE = 0,
+  Monster = 1,
+  TestSimpleTableWithEnum = 2,
+  MyGame_Example2_Monster = 3,
+};
+
+
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Any.go b/third_party/flatbuffers/tests/MyGame/Example/Any.go
new file mode 100644
index 0000000..8d9067e
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Any.go
@@ -0,0 +1,35 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package Example
+
+import "strconv"
+
+type Any byte
+
+const (
+	AnyNONE                    Any = 0
+	AnyMonster                 Any = 1
+	AnyTestSimpleTableWithEnum Any = 2
+	AnyMyGame_Example2_Monster Any = 3
+)
+
+var EnumNamesAny = map[Any]string{
+	AnyNONE:                    "NONE",
+	AnyMonster:                 "Monster",
+	AnyTestSimpleTableWithEnum: "TestSimpleTableWithEnum",
+	AnyMyGame_Example2_Monster: "MyGame_Example2_Monster",
+}
+
+var EnumValuesAny = map[string]Any{
+	"NONE":                    AnyNONE,
+	"Monster":                 AnyMonster,
+	"TestSimpleTableWithEnum": AnyTestSimpleTableWithEnum,
+	"MyGame_Example2_Monster": AnyMyGame_Example2_Monster,
+}
+
+func (v Any) String() string {
+	if s, ok := EnumNamesAny[v]; ok {
+		return s
+	}
+	return "Any(" + strconv.FormatInt(int64(v), 10) + ")"
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Any.java b/third_party/flatbuffers/tests/MyGame/Example/Any.java
new file mode 100644
index 0000000..6e4fb76
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Any.java
@@ -0,0 +1,16 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+public final class Any {
+  private Any() { }
+  public static final byte NONE = 0;
+  public static final byte Monster = 1;
+  public static final byte TestSimpleTableWithEnum = 2;
+  public static final byte MyGame_Example2_Monster = 3;
+
+  public static final String[] names = { "NONE", "Monster", "TestSimpleTableWithEnum", "MyGame_Example2_Monster", };
+
+  public static String name(int e) { return names[e]; }
+}
+
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Any.kt b/third_party/flatbuffers/tests/MyGame/Example/Any.kt
new file mode 100644
index 0000000..f1a4dfe
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Any.kt
@@ -0,0 +1,16 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Any_ private constructor() {
+    companion object {
+        const val NONE: UByte = 0u
+        const val Monster: UByte = 1u
+        const val TestSimpleTableWithEnum: UByte = 2u
+        const val MyGameExample2Monster: UByte = 3u
+        val names : Array<String> = arrayOf("NONE", "Monster", "TestSimpleTableWithEnum", "MyGame_Example2_Monster")
+        fun name(e: Int) : String = names[e]
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Any.lua b/third_party/flatbuffers/tests/MyGame/Example/Any.lua
new file mode 100644
index 0000000..03225ba
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Any.lua
@@ -0,0 +1,12 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Example
+
+local Any = {
+    NONE = 0,
+    Monster = 1,
+    TestSimpleTableWithEnum = 2,
+    MyGame_Example2_Monster = 3,
+}
+
+return Any -- return the module
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Any.php b/third_party/flatbuffers/tests/MyGame/Example/Any.php
new file mode 100644
index 0000000..929caaf
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Any.php
@@ -0,0 +1,27 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame\Example;
+
+class Any
+{
+    const NONE = 0;
+    const Monster = 1;
+    const TestSimpleTableWithEnum = 2;
+    const MyGame_Example2_Monster = 3;
+
+    private static $names = array(
+        Any::NONE=>"NONE",
+        Any::Monster=>"Monster",
+        Any::TestSimpleTableWithEnum=>"TestSimpleTableWithEnum",
+        Any::MyGame_Example2_Monster=>"MyGame_Example2_Monster",
+    );
+
+    public static function Name($e)
+    {
+        if (!isset(self::$names[$e])) {
+            throw new \Exception();
+        }
+        return self::$names[$e];
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Any.py b/third_party/flatbuffers/tests/MyGame/Example/Any.py
new file mode 100644
index 0000000..f1b8d51
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Any.py
@@ -0,0 +1,10 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+class Any(object):
+    NONE = 0
+    Monster = 1
+    TestSimpleTableWithEnum = 2
+    MyGame_Example2_Monster = 3
+
diff --git a/third_party/flatbuffers/tests/MyGame/Example/AnyAmbiguousAliases.cs b/third_party/flatbuffers/tests/MyGame/Example/AnyAmbiguousAliases.cs
new file mode 100644
index 0000000..c727b88
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/AnyAmbiguousAliases.cs
@@ -0,0 +1,17 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+public enum AnyAmbiguousAliases : byte
+{
+  NONE = 0,
+  M1 = 1,
+  M2 = 2,
+  M3 = 3,
+};
+
+
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/AnyAmbiguousAliases.go b/third_party/flatbuffers/tests/MyGame/Example/AnyAmbiguousAliases.go
new file mode 100644
index 0000000..b9c3793
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/AnyAmbiguousAliases.go
@@ -0,0 +1,35 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package Example
+
+import "strconv"
+
+type AnyAmbiguousAliases byte
+
+const (
+	AnyAmbiguousAliasesNONE AnyAmbiguousAliases = 0
+	AnyAmbiguousAliasesM1   AnyAmbiguousAliases = 1
+	AnyAmbiguousAliasesM2   AnyAmbiguousAliases = 2
+	AnyAmbiguousAliasesM3   AnyAmbiguousAliases = 3
+)
+
+var EnumNamesAnyAmbiguousAliases = map[AnyAmbiguousAliases]string{
+	AnyAmbiguousAliasesNONE: "NONE",
+	AnyAmbiguousAliasesM1:   "M1",
+	AnyAmbiguousAliasesM2:   "M2",
+	AnyAmbiguousAliasesM3:   "M3",
+}
+
+var EnumValuesAnyAmbiguousAliases = map[string]AnyAmbiguousAliases{
+	"NONE": AnyAmbiguousAliasesNONE,
+	"M1":   AnyAmbiguousAliasesM1,
+	"M2":   AnyAmbiguousAliasesM2,
+	"M3":   AnyAmbiguousAliasesM3,
+}
+
+func (v AnyAmbiguousAliases) String() string {
+	if s, ok := EnumNamesAnyAmbiguousAliases[v]; ok {
+		return s
+	}
+	return "AnyAmbiguousAliases(" + strconv.FormatInt(int64(v), 10) + ")"
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/AnyAmbiguousAliases.java b/third_party/flatbuffers/tests/MyGame/Example/AnyAmbiguousAliases.java
new file mode 100644
index 0000000..b8a6870
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/AnyAmbiguousAliases.java
@@ -0,0 +1,16 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+public final class AnyAmbiguousAliases {
+  private AnyAmbiguousAliases() { }
+  public static final byte NONE = 0;
+  public static final byte M1 = 1;
+  public static final byte M2 = 2;
+  public static final byte M3 = 3;
+
+  public static final String[] names = { "NONE", "M1", "M2", "M3", };
+
+  public static String name(int e) { return names[e]; }
+}
+
diff --git a/third_party/flatbuffers/tests/MyGame/Example/AnyAmbiguousAliases.kt b/third_party/flatbuffers/tests/MyGame/Example/AnyAmbiguousAliases.kt
new file mode 100644
index 0000000..cee13c5
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/AnyAmbiguousAliases.kt
@@ -0,0 +1,16 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class AnyAmbiguousAliases private constructor() {
+    companion object {
+        const val NONE: UByte = 0u
+        const val M1: UByte = 1u
+        const val M2: UByte = 2u
+        const val M3: UByte = 3u
+        val names : Array<String> = arrayOf("NONE", "M1", "M2", "M3")
+        fun name(e: Int) : String = names[e]
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/AnyAmbiguousAliases.lua b/third_party/flatbuffers/tests/MyGame/Example/AnyAmbiguousAliases.lua
new file mode 100644
index 0000000..dbe474b
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/AnyAmbiguousAliases.lua
@@ -0,0 +1,12 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Example
+
+local AnyAmbiguousAliases = {
+    NONE = 0,
+    M1 = 1,
+    M2 = 2,
+    M3 = 3,
+}
+
+return AnyAmbiguousAliases -- return the module
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/MyGame/Example/AnyAmbiguousAliases.php b/third_party/flatbuffers/tests/MyGame/Example/AnyAmbiguousAliases.php
new file mode 100644
index 0000000..13d318a
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/AnyAmbiguousAliases.php
@@ -0,0 +1,27 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame\Example;
+
+class AnyAmbiguousAliases
+{
+    const NONE = 0;
+    const M1 = 1;
+    const M2 = 2;
+    const M3 = 3;
+
+    private static $names = array(
+        AnyAmbiguousAliases::NONE=>"NONE",
+        AnyAmbiguousAliases::M1=>"M1",
+        AnyAmbiguousAliases::M2=>"M2",
+        AnyAmbiguousAliases::M3=>"M3",
+    );
+
+    public static function Name($e)
+    {
+        if (!isset(self::$names[$e])) {
+            throw new \Exception();
+        }
+        return self::$names[$e];
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/AnyAmbiguousAliases.py b/third_party/flatbuffers/tests/MyGame/Example/AnyAmbiguousAliases.py
new file mode 100644
index 0000000..de6e9d0
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/AnyAmbiguousAliases.py
@@ -0,0 +1,10 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+class AnyAmbiguousAliases(object):
+    NONE = 0
+    M1 = 1
+    M2 = 2
+    M3 = 3
+
diff --git a/third_party/flatbuffers/tests/MyGame/Example/AnyUniqueAliases.cs b/third_party/flatbuffers/tests/MyGame/Example/AnyUniqueAliases.cs
new file mode 100644
index 0000000..42a3e0b
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/AnyUniqueAliases.cs
@@ -0,0 +1,17 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+public enum AnyUniqueAliases : byte
+{
+  NONE = 0,
+  M = 1,
+  TS = 2,
+  M2 = 3,
+};
+
+
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/AnyUniqueAliases.go b/third_party/flatbuffers/tests/MyGame/Example/AnyUniqueAliases.go
new file mode 100644
index 0000000..23d8649
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/AnyUniqueAliases.go
@@ -0,0 +1,35 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package Example
+
+import "strconv"
+
+type AnyUniqueAliases byte
+
+const (
+	AnyUniqueAliasesNONE AnyUniqueAliases = 0
+	AnyUniqueAliasesM    AnyUniqueAliases = 1
+	AnyUniqueAliasesTS   AnyUniqueAliases = 2
+	AnyUniqueAliasesM2   AnyUniqueAliases = 3
+)
+
+var EnumNamesAnyUniqueAliases = map[AnyUniqueAliases]string{
+	AnyUniqueAliasesNONE: "NONE",
+	AnyUniqueAliasesM:    "M",
+	AnyUniqueAliasesTS:   "TS",
+	AnyUniqueAliasesM2:   "M2",
+}
+
+var EnumValuesAnyUniqueAliases = map[string]AnyUniqueAliases{
+	"NONE": AnyUniqueAliasesNONE,
+	"M":    AnyUniqueAliasesM,
+	"TS":   AnyUniqueAliasesTS,
+	"M2":   AnyUniqueAliasesM2,
+}
+
+func (v AnyUniqueAliases) String() string {
+	if s, ok := EnumNamesAnyUniqueAliases[v]; ok {
+		return s
+	}
+	return "AnyUniqueAliases(" + strconv.FormatInt(int64(v), 10) + ")"
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/AnyUniqueAliases.java b/third_party/flatbuffers/tests/MyGame/Example/AnyUniqueAliases.java
new file mode 100644
index 0000000..1f32945
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/AnyUniqueAliases.java
@@ -0,0 +1,16 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+public final class AnyUniqueAliases {
+  private AnyUniqueAliases() { }
+  public static final byte NONE = 0;
+  public static final byte M = 1;
+  public static final byte TS = 2;
+  public static final byte M2 = 3;
+
+  public static final String[] names = { "NONE", "M", "TS", "M2", };
+
+  public static String name(int e) { return names[e]; }
+}
+
diff --git a/third_party/flatbuffers/tests/MyGame/Example/AnyUniqueAliases.kt b/third_party/flatbuffers/tests/MyGame/Example/AnyUniqueAliases.kt
new file mode 100644
index 0000000..1902d5d
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/AnyUniqueAliases.kt
@@ -0,0 +1,16 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class AnyUniqueAliases private constructor() {
+    companion object {
+        const val NONE: UByte = 0u
+        const val M: UByte = 1u
+        const val TS: UByte = 2u
+        const val M2: UByte = 3u
+        val names : Array<String> = arrayOf("NONE", "M", "TS", "M2")
+        fun name(e: Int) : String = names[e]
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/AnyUniqueAliases.lua b/third_party/flatbuffers/tests/MyGame/Example/AnyUniqueAliases.lua
new file mode 100644
index 0000000..9bfeb80
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/AnyUniqueAliases.lua
@@ -0,0 +1,12 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Example
+
+local AnyUniqueAliases = {
+    NONE = 0,
+    M = 1,
+    TS = 2,
+    M2 = 3,
+}
+
+return AnyUniqueAliases -- return the module
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/MyGame/Example/AnyUniqueAliases.php b/third_party/flatbuffers/tests/MyGame/Example/AnyUniqueAliases.php
new file mode 100644
index 0000000..830d8b5
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/AnyUniqueAliases.php
@@ -0,0 +1,27 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame\Example;
+
+class AnyUniqueAliases
+{
+    const NONE = 0;
+    const M = 1;
+    const TS = 2;
+    const M2 = 3;
+
+    private static $names = array(
+        AnyUniqueAliases::NONE=>"NONE",
+        AnyUniqueAliases::M=>"M",
+        AnyUniqueAliases::TS=>"TS",
+        AnyUniqueAliases::M2=>"M2",
+    );
+
+    public static function Name($e)
+    {
+        if (!isset(self::$names[$e])) {
+            throw new \Exception();
+        }
+        return self::$names[$e];
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/AnyUniqueAliases.py b/third_party/flatbuffers/tests/MyGame/Example/AnyUniqueAliases.py
new file mode 100644
index 0000000..a6da355
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/AnyUniqueAliases.py
@@ -0,0 +1,10 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+class AnyUniqueAliases(object):
+    NONE = 0
+    M = 1
+    TS = 2
+    M2 = 3
+
diff --git a/third_party/flatbuffers/tests/MyGame/Example/ArrayStruct.cs b/third_party/flatbuffers/tests/MyGame/Example/ArrayStruct.cs
new file mode 100644
index 0000000..28815e7
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/ArrayStruct.cs
@@ -0,0 +1,50 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct ArrayStruct : IFlatbufferObject
+{
+  private Struct __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
+  public ArrayStruct __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public float A { get { return __p.bb.GetFloat(__p.bb_pos + 0); } }
+  public void MutateA(float a) { __p.bb.PutFloat(__p.bb_pos + 0, a); }
+  public int B(int j) { return __p.bb.GetInt(__p.bb_pos + 4 + j * 4); }
+  public void MutateB(int j, int b) { __p.bb.PutInt(__p.bb_pos + 4 + j * 4, b); }
+  public sbyte C { get { return __p.bb.GetSbyte(__p.bb_pos + 64); } }
+  public void MutateC(sbyte c) { __p.bb.PutSbyte(__p.bb_pos + 64, c); }
+  public MyGame.Example.NestedStruct D(int j) { return (new MyGame.Example.NestedStruct()).__assign(__p.bb_pos + 68 + j * 12, __p.bb); }
+
+  public static Offset<MyGame.Example.ArrayStruct> CreateArrayStruct(FlatBufferBuilder builder, float A, int[] B, sbyte C, int[,] d_A, MyGame.Example.TestEnum[] d_B, MyGame.Example.TestEnum[,] d_C) {
+    builder.Prep(4, 92);
+    for (int _idx0 = 2; _idx0 > 0; _idx0--) {
+      builder.Prep(4, 12);
+      builder.Pad(1);
+      for (int _idx1 = 2; _idx1 > 0; _idx1--) {
+        builder.PutSbyte((sbyte)d_C[_idx0-1,_idx1-1]);
+      }
+      builder.PutSbyte((sbyte)d_B[_idx0-1]);
+      for (int _idx1 = 2; _idx1 > 0; _idx1--) {
+        builder.PutInt(d_A[_idx0-1,_idx1-1]);
+      }
+    }
+    builder.Pad(3);
+    builder.PutSbyte(C);
+    for (int _idx0 = 15; _idx0 > 0; _idx0--) {
+      builder.PutInt(B[_idx0-1]);
+    }
+    builder.PutFloat(A);
+    return new Offset<MyGame.Example.ArrayStruct>(builder.Offset);
+  }
+};
+
+
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/ArrayStruct.java b/third_party/flatbuffers/tests/MyGame/Example/ArrayStruct.java
new file mode 100644
index 0000000..0098c55
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/ArrayStruct.java
@@ -0,0 +1,45 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class ArrayStruct extends Struct {
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public ArrayStruct __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public float a() { return bb.getFloat(bb_pos + 0); }
+  public void mutateA(float a) { bb.putFloat(bb_pos + 0, a); }
+  public int b(int j) { return bb.getInt(bb_pos + 4 + j * 4); }
+  public void mutateB(int j, int b) { bb.putInt(bb_pos + 4 + j * 4, b); }
+  public byte c() { return bb.get(bb_pos + 64); }
+  public void mutateC(byte c) { bb.put(bb_pos + 64, c); }
+  public MyGame.Example.NestedStruct d(MyGame.Example.NestedStruct obj, int j) { return obj.__assign(bb_pos + 68 + j * 12, bb); }
+
+  public static int createArrayStruct(FlatBufferBuilder builder, float a, int[] b, byte c, int[][] d_a, byte[] d_b, byte[][] d_c) {
+    builder.prep(4, 92);
+    for (int _idx0 = 2; _idx0 > 0; _idx0--) {
+      builder.prep(4, 12);
+      builder.pad(1);
+      for (int _idx1 = 2; _idx1 > 0; _idx1--) {
+        builder.putByte(d_c[_idx0-1][_idx1-1]);
+      }
+      builder.putByte(d_b[_idx0-1]);
+      for (int _idx1 = 2; _idx1 > 0; _idx1--) {
+        builder.putInt(d_a[_idx0-1][_idx1-1]);
+      }
+    }
+    builder.pad(3);
+    builder.putByte(c);
+    for (int _idx0 = 15; _idx0 > 0; _idx0--) {
+      builder.putInt(b[_idx0-1]);
+    }
+    builder.putFloat(a);
+    return builder.offset();
+  }
+}
+
diff --git a/third_party/flatbuffers/tests/MyGame/Example/ArrayStruct.py b/third_party/flatbuffers/tests/MyGame/Example/ArrayStruct.py
new file mode 100644
index 0000000..79dda31
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/ArrayStruct.py
@@ -0,0 +1,41 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+import flatbuffers
+
+class ArrayStruct(object):
+    __slots__ = ['_tab']
+
+    # ArrayStruct
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # ArrayStruct
+    def A(self): return self._tab.Get(flatbuffers.number_types.Float32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(0))
+    # ArrayStruct
+    def B(self): return [self._tab.Get(flatbuffers.number_types.Int32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(4 + i * 4)) for i in range(15)]
+    # ArrayStruct
+    def C(self): return self._tab.Get(flatbuffers.number_types.Int8Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(64))
+    # ArrayStruct
+    def D(self, obj, i):
+        obj.Init(self._tab.Bytes, self._tab.Pos + 68 + i * 12)
+        return obj
+
+
+def CreateArrayStruct(builder, a, b, c, d_a, d_b, d_c):
+    builder.Prep(4, 92)
+    for _idx0 in range(2 , 0, -1):
+        builder.Prep(4, 12)
+        builder.Pad(1)
+        for _idx1 in range(2 , 0, -1):
+            builder.PrependInt8(d_c[_idx0-1][_idx1-1])
+        builder.PrependInt8(d_b[_idx0-1])
+        for _idx1 in range(2 , 0, -1):
+            builder.PrependInt32(d_a[_idx0-1][_idx1-1])
+    builder.Pad(3)
+    builder.PrependInt8(c)
+    for _idx0 in range(15 , 0, -1):
+        builder.PrependInt32(b[_idx0-1])
+    builder.PrependFloat32(a)
+    return builder.Offset()
diff --git a/third_party/flatbuffers/tests/MyGame/Example/ArrayTable.cs b/third_party/flatbuffers/tests/MyGame/Example/ArrayTable.cs
new file mode 100644
index 0000000..e303211
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/ArrayTable.cs
@@ -0,0 +1,35 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct ArrayTable : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static ArrayTable GetRootAsArrayTable(ByteBuffer _bb) { return GetRootAsArrayTable(_bb, new ArrayTable()); }
+  public static ArrayTable GetRootAsArrayTable(ByteBuffer _bb, ArrayTable obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public static bool ArrayTableBufferHasIdentifier(ByteBuffer _bb) { return Table.__has_identifier(_bb, "ARRT"); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public ArrayTable __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public MyGame.Example.ArrayStruct? A { get { int o = __p.__offset(4); return o != 0 ? (MyGame.Example.ArrayStruct?)(new MyGame.Example.ArrayStruct()).__assign(o + __p.bb_pos, __p.bb) : null; } }
+
+  public static void StartArrayTable(FlatBufferBuilder builder) { builder.StartTable(1); }
+  public static void AddA(FlatBufferBuilder builder, Offset<MyGame.Example.ArrayStruct> aOffset) { builder.AddStruct(0, aOffset.Value, 0); }
+  public static Offset<MyGame.Example.ArrayTable> EndArrayTable(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<MyGame.Example.ArrayTable>(o);
+  }
+  public static void FinishArrayTableBuffer(FlatBufferBuilder builder, Offset<MyGame.Example.ArrayTable> offset) { builder.Finish(offset.Value, "ARRT"); }
+  public static void FinishSizePrefixedArrayTableBuffer(FlatBufferBuilder builder, Offset<MyGame.Example.ArrayTable> offset) { builder.FinishSizePrefixed(offset.Value, "ARRT"); }
+};
+
+
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/ArrayTable.java b/third_party/flatbuffers/tests/MyGame/Example/ArrayTable.java
new file mode 100644
index 0000000..74ce86a
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/ArrayTable.java
@@ -0,0 +1,31 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class ArrayTable extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static ArrayTable getRootAsArrayTable(ByteBuffer _bb) { return getRootAsArrayTable(_bb, new ArrayTable()); }
+  public static ArrayTable getRootAsArrayTable(ByteBuffer _bb, ArrayTable obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public static boolean ArrayTableBufferHasIdentifier(ByteBuffer _bb) { return __has_identifier(_bb, "ARRT"); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public ArrayTable __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public MyGame.Example.ArrayStruct a() { return a(new MyGame.Example.ArrayStruct()); }
+  public MyGame.Example.ArrayStruct a(MyGame.Example.ArrayStruct obj) { int o = __offset(4); return o != 0 ? obj.__assign(o + bb_pos, bb) : null; }
+
+  public static void startArrayTable(FlatBufferBuilder builder) { builder.startTable(1); }
+  public static void addA(FlatBufferBuilder builder, int aOffset) { builder.addStruct(0, aOffset, 0); }
+  public static int endArrayTable(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+  public static void finishArrayTableBuffer(FlatBufferBuilder builder, int offset) { builder.finish(offset, "ARRT"); }
+  public static void finishSizePrefixedArrayTableBuffer(FlatBufferBuilder builder, int offset) { builder.finishSizePrefixed(offset, "ARRT"); }
+}
+
diff --git a/third_party/flatbuffers/tests/MyGame/Example/ArrayTable.py b/third_party/flatbuffers/tests/MyGame/Example/ArrayTable.py
new file mode 100644
index 0000000..6d583f9
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/ArrayTable.py
@@ -0,0 +1,38 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+import flatbuffers
+
+class ArrayTable(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAsArrayTable(cls, buf, offset):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = ArrayTable()
+        x.Init(buf, n + offset)
+        return x
+
+    @classmethod
+    def ArrayTableBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
+        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x41\x52\x52\x54", size_prefixed=size_prefixed)
+
+    # ArrayTable
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # ArrayTable
+    def A(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        if o != 0:
+            x = o + self._tab.Pos
+            from .ArrayStruct import ArrayStruct
+            obj = ArrayStruct()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+def ArrayTableStart(builder): builder.StartObject(1)
+def ArrayTableAddA(builder, a): builder.PrependStructSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(a), 0)
+def ArrayTableEnd(builder): return builder.EndObject()
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Color.cs b/third_party/flatbuffers/tests/MyGame/Example/Color.cs
new file mode 100644
index 0000000..5981cf8
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Color.cs
@@ -0,0 +1,21 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+/// Composite components of Monster color.
+[System.FlagsAttribute]
+public enum Color : byte
+{
+  Red = 1,
+  /// \brief color Green
+  /// Green is bit_flag with value (1u << 1)
+  Green = 2,
+  /// \brief color Blue (1u << 3)
+  Blue = 8,
+};
+
+
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Color.go b/third_party/flatbuffers/tests/MyGame/Example/Color.go
new file mode 100644
index 0000000..9570ae4
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Color.go
@@ -0,0 +1,36 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package Example
+
+import "strconv"
+
+/// Composite components of Monster color.
+type Color byte
+
+const (
+	ColorRed   Color = 1
+	/// \brief color Green
+	/// Green is bit_flag with value (1u << 1)
+	ColorGreen Color = 2
+	/// \brief color Blue (1u << 3)
+	ColorBlue  Color = 8
+)
+
+var EnumNamesColor = map[Color]string{
+	ColorRed:   "Red",
+	ColorGreen: "Green",
+	ColorBlue:  "Blue",
+}
+
+var EnumValuesColor = map[string]Color{
+	"Red":   ColorRed,
+	"Green": ColorGreen,
+	"Blue":  ColorBlue,
+}
+
+func (v Color) String() string {
+	if s, ok := EnumNamesColor[v]; ok {
+		return s
+	}
+	return "Color(" + strconv.FormatInt(int64(v), 10) + ")"
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Color.java b/third_party/flatbuffers/tests/MyGame/Example/Color.java
new file mode 100644
index 0000000..0563c0a
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Color.java
@@ -0,0 +1,25 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+/**
+ * Composite components of Monster color.
+ */
+public final class Color {
+  private Color() { }
+  public static final byte Red = 1;
+  /**
+   * \brief color Green
+   * Green is bit_flag with value (1u << 1)
+   */
+  public static final byte Green = 2;
+  /**
+   * \brief color Blue (1u << 3)
+   */
+  public static final byte Blue = 8;
+
+  public static final String[] names = { "Red", "Green", "", "", "", "", "", "Blue", };
+
+  public static String name(int e) { return names[e - Red]; }
+}
+
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Color.kt b/third_party/flatbuffers/tests/MyGame/Example/Color.kt
new file mode 100644
index 0000000..4c27ba3
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Color.kt
@@ -0,0 +1,25 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+/**
+ * Composite components of Monster color.
+ */
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Color private constructor() {
+    companion object {
+        const val Red: UByte = 1u
+        /**
+         * \brief color Green
+         * Green is bit_flag with value (1u << 1)
+         */
+        const val Green: UByte = 2u
+        /**
+         * \brief color Blue (1u << 3)
+         */
+        const val Blue: UByte = 8u
+        val names : Array<String> = arrayOf("Red", "Green", "", "", "", "", "", "Blue")
+        fun name(e: Int) : String = names[e - Red.toInt()]
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Color.lua b/third_party/flatbuffers/tests/MyGame/Example/Color.lua
new file mode 100644
index 0000000..d4d2cbc
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Color.lua
@@ -0,0 +1,15 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Example
+
+-- Composite components of Monster color.
+local Color = {
+    Red = 1,
+    -- \brief color Green
+    -- Green is bit_flag with value (1u << 1)
+    Green = 2,
+    -- \brief color Blue (1u << 3)
+    Blue = 8,
+}
+
+return Color -- return the module
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Color.php b/third_party/flatbuffers/tests/MyGame/Example/Color.php
new file mode 100644
index 0000000..8c32922
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Color.php
@@ -0,0 +1,29 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame\Example;
+
+/// Composite components of Monster color.
+class Color
+{
+    const Red = 1;
+    /// \brief color Green
+    /// Green is bit_flag with value (1u << 1)
+    const Green = 2;
+    /// \brief color Blue (1u << 3)
+    const Blue = 8;
+
+    private static $names = array(
+        Color::Red=>"Red",
+        Color::Green=>"Green",
+        Color::Blue=>"Blue",
+    );
+
+    public static function Name($e)
+    {
+        if (!isset(self::$names[$e])) {
+            throw new \Exception();
+        }
+        return self::$names[$e];
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Color.py b/third_party/flatbuffers/tests/MyGame/Example/Color.py
new file mode 100644
index 0000000..55aa821
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Color.py
@@ -0,0 +1,13 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+# Composite components of Monster color.
+class Color(object):
+    Red = 1
+    # \brief color Green
+    # Green is bit_flag with value (1u << 1)
+    Green = 2
+    # \brief color Blue (1u << 3)
+    Blue = 8
+
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Monster.cs b/third_party/flatbuffers/tests/MyGame/Example/Monster.cs
new file mode 100644
index 0000000..5dc669e
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Monster.cs
@@ -0,0 +1,324 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+using global::System;
+using global::FlatBuffers;
+
+/// an example documentation comment: monster object
+public struct Monster : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static Monster GetRootAsMonster(ByteBuffer _bb) { return GetRootAsMonster(_bb, new Monster()); }
+  public static Monster GetRootAsMonster(ByteBuffer _bb, Monster obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public static bool MonsterBufferHasIdentifier(ByteBuffer _bb) { return Table.__has_identifier(_bb, "MONS"); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public Monster __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public MyGame.Example.Vec3? Pos { get { int o = __p.__offset(4); return o != 0 ? (MyGame.Example.Vec3?)(new MyGame.Example.Vec3()).__assign(o + __p.bb_pos, __p.bb) : null; } }
+  public short Mana { get { int o = __p.__offset(6); return o != 0 ? __p.bb.GetShort(o + __p.bb_pos) : (short)150; } }
+  public bool MutateMana(short mana) { int o = __p.__offset(6); if (o != 0) { __p.bb.PutShort(o + __p.bb_pos, mana); return true; } else { return false; } }
+  public short Hp { get { int o = __p.__offset(8); return o != 0 ? __p.bb.GetShort(o + __p.bb_pos) : (short)100; } }
+  public bool MutateHp(short hp) { int o = __p.__offset(8); if (o != 0) { __p.bb.PutShort(o + __p.bb_pos, hp); return true; } else { return false; } }
+  public string Name { get { int o = __p.__offset(10); return o != 0 ? __p.__string(o + __p.bb_pos) : null; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetNameBytes() { return __p.__vector_as_span(10); }
+#else
+  public ArraySegment<byte>? GetNameBytes() { return __p.__vector_as_arraysegment(10); }
+#endif
+  public byte[] GetNameArray() { return __p.__vector_as_array<byte>(10); }
+  public byte Inventory(int j) { int o = __p.__offset(14); return o != 0 ? __p.bb.Get(__p.__vector(o) + j * 1) : (byte)0; }
+  public int InventoryLength { get { int o = __p.__offset(14); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetInventoryBytes() { return __p.__vector_as_span(14); }
+#else
+  public ArraySegment<byte>? GetInventoryBytes() { return __p.__vector_as_arraysegment(14); }
+#endif
+  public byte[] GetInventoryArray() { return __p.__vector_as_array<byte>(14); }
+  public bool MutateInventory(int j, byte inventory) { int o = __p.__offset(14); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, inventory); return true; } else { return false; } }
+  public MyGame.Example.Color Color { get { int o = __p.__offset(16); return o != 0 ? (MyGame.Example.Color)__p.bb.Get(o + __p.bb_pos) : MyGame.Example.Color.Blue; } }
+  public bool MutateColor(MyGame.Example.Color color) { int o = __p.__offset(16); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)color); return true; } else { return false; } }
+  public MyGame.Example.Any TestType { get { int o = __p.__offset(18); return o != 0 ? (MyGame.Example.Any)__p.bb.Get(o + __p.bb_pos) : MyGame.Example.Any.NONE; } }
+  public bool MutateTestType(MyGame.Example.Any test_type) { int o = __p.__offset(18); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)test_type); return true; } else { return false; } }
+  public TTable? Test<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(20); return o != 0 ? (TTable?)__p.__union<TTable>(o) : null; }
+  public MyGame.Example.Test? Test4(int j) { int o = __p.__offset(22); return o != 0 ? (MyGame.Example.Test?)(new MyGame.Example.Test()).__assign(__p.__vector(o) + j * 4, __p.bb) : null; }
+  public int Test4Length { get { int o = __p.__offset(22); return o != 0 ? __p.__vector_len(o) : 0; } }
+  public string Testarrayofstring(int j) { int o = __p.__offset(24); return o != 0 ? __p.__string(__p.__vector(o) + j * 4) : null; }
+  public int TestarrayofstringLength { get { int o = __p.__offset(24); return o != 0 ? __p.__vector_len(o) : 0; } }
+  /// an example documentation comment: this will end up in the generated code
+  /// multiline too
+  public MyGame.Example.Monster? Testarrayoftables(int j) { int o = __p.__offset(26); return o != 0 ? (MyGame.Example.Monster?)(new MyGame.Example.Monster()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
+  public int TestarrayoftablesLength { get { int o = __p.__offset(26); return o != 0 ? __p.__vector_len(o) : 0; } }
+  public MyGame.Example.Monster? TestarrayoftablesByKey(string key) { int o = __p.__offset(26); return o != 0 ? MyGame.Example.Monster.__lookup_by_key(__p.__vector(o), key, __p.bb) : null; }
+  public MyGame.Example.Monster? Enemy { get { int o = __p.__offset(28); return o != 0 ? (MyGame.Example.Monster?)(new MyGame.Example.Monster()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
+  public byte Testnestedflatbuffer(int j) { int o = __p.__offset(30); return o != 0 ? __p.bb.Get(__p.__vector(o) + j * 1) : (byte)0; }
+  public int TestnestedflatbufferLength { get { int o = __p.__offset(30); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetTestnestedflatbufferBytes() { return __p.__vector_as_span(30); }
+#else
+  public ArraySegment<byte>? GetTestnestedflatbufferBytes() { return __p.__vector_as_arraysegment(30); }
+#endif
+  public byte[] GetTestnestedflatbufferArray() { return __p.__vector_as_array<byte>(30); }
+  public MyGame.Example.Monster? GetTestnestedflatbufferAsMonster() { int o = __p.__offset(30); return o != 0 ? (MyGame.Example.Monster?)(new MyGame.Example.Monster()).__assign(__p.__indirect(__p.__vector(o)), __p.bb) : null; }
+  public bool MutateTestnestedflatbuffer(int j, byte testnestedflatbuffer) { int o = __p.__offset(30); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, testnestedflatbuffer); return true; } else { return false; } }
+  public MyGame.Example.Stat? Testempty { get { int o = __p.__offset(32); return o != 0 ? (MyGame.Example.Stat?)(new MyGame.Example.Stat()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
+  public bool Testbool { get { int o = __p.__offset(34); return o != 0 ? 0!=__p.bb.Get(o + __p.bb_pos) : (bool)false; } }
+  public bool MutateTestbool(bool testbool) { int o = __p.__offset(34); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)(testbool ? 1 : 0)); return true; } else { return false; } }
+  public int Testhashs32Fnv1 { get { int o = __p.__offset(36); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } }
+  public bool MutateTesthashs32Fnv1(int testhashs32_fnv1) { int o = __p.__offset(36); if (o != 0) { __p.bb.PutInt(o + __p.bb_pos, testhashs32_fnv1); return true; } else { return false; } }
+  public uint Testhashu32Fnv1 { get { int o = __p.__offset(38); return o != 0 ? __p.bb.GetUint(o + __p.bb_pos) : (uint)0; } }
+  public bool MutateTesthashu32Fnv1(uint testhashu32_fnv1) { int o = __p.__offset(38); if (o != 0) { __p.bb.PutUint(o + __p.bb_pos, testhashu32_fnv1); return true; } else { return false; } }
+  public long Testhashs64Fnv1 { get { int o = __p.__offset(40); return o != 0 ? __p.bb.GetLong(o + __p.bb_pos) : (long)0; } }
+  public bool MutateTesthashs64Fnv1(long testhashs64_fnv1) { int o = __p.__offset(40); if (o != 0) { __p.bb.PutLong(o + __p.bb_pos, testhashs64_fnv1); return true; } else { return false; } }
+  public ulong Testhashu64Fnv1 { get { int o = __p.__offset(42); return o != 0 ? __p.bb.GetUlong(o + __p.bb_pos) : (ulong)0; } }
+  public bool MutateTesthashu64Fnv1(ulong testhashu64_fnv1) { int o = __p.__offset(42); if (o != 0) { __p.bb.PutUlong(o + __p.bb_pos, testhashu64_fnv1); return true; } else { return false; } }
+  public int Testhashs32Fnv1a { get { int o = __p.__offset(44); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } }
+  public bool MutateTesthashs32Fnv1a(int testhashs32_fnv1a) { int o = __p.__offset(44); if (o != 0) { __p.bb.PutInt(o + __p.bb_pos, testhashs32_fnv1a); return true; } else { return false; } }
+  public uint Testhashu32Fnv1a { get { int o = __p.__offset(46); return o != 0 ? __p.bb.GetUint(o + __p.bb_pos) : (uint)0; } }
+  public bool MutateTesthashu32Fnv1a(uint testhashu32_fnv1a) { int o = __p.__offset(46); if (o != 0) { __p.bb.PutUint(o + __p.bb_pos, testhashu32_fnv1a); return true; } else { return false; } }
+  public long Testhashs64Fnv1a { get { int o = __p.__offset(48); return o != 0 ? __p.bb.GetLong(o + __p.bb_pos) : (long)0; } }
+  public bool MutateTesthashs64Fnv1a(long testhashs64_fnv1a) { int o = __p.__offset(48); if (o != 0) { __p.bb.PutLong(o + __p.bb_pos, testhashs64_fnv1a); return true; } else { return false; } }
+  public ulong Testhashu64Fnv1a { get { int o = __p.__offset(50); return o != 0 ? __p.bb.GetUlong(o + __p.bb_pos) : (ulong)0; } }
+  public bool MutateTesthashu64Fnv1a(ulong testhashu64_fnv1a) { int o = __p.__offset(50); if (o != 0) { __p.bb.PutUlong(o + __p.bb_pos, testhashu64_fnv1a); return true; } else { return false; } }
+  public bool Testarrayofbools(int j) { int o = __p.__offset(52); return o != 0 ? 0!=__p.bb.Get(__p.__vector(o) + j * 1) : false; }
+  public int TestarrayofboolsLength { get { int o = __p.__offset(52); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetTestarrayofboolsBytes() { return __p.__vector_as_span(52); }
+#else
+  public ArraySegment<byte>? GetTestarrayofboolsBytes() { return __p.__vector_as_arraysegment(52); }
+#endif
+  public bool[] GetTestarrayofboolsArray() { return __p.__vector_as_array<bool>(52); }
+  public bool MutateTestarrayofbools(int j, bool testarrayofbools) { int o = __p.__offset(52); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, (byte)(testarrayofbools ? 1 : 0)); return true; } else { return false; } }
+  public float Testf { get { int o = __p.__offset(54); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)3.14159f; } }
+  public bool MutateTestf(float testf) { int o = __p.__offset(54); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, testf); return true; } else { return false; } }
+  public float Testf2 { get { int o = __p.__offset(56); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)3.0f; } }
+  public bool MutateTestf2(float testf2) { int o = __p.__offset(56); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, testf2); return true; } else { return false; } }
+  public float Testf3 { get { int o = __p.__offset(58); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)0.0f; } }
+  public bool MutateTestf3(float testf3) { int o = __p.__offset(58); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, testf3); return true; } else { return false; } }
+  public string Testarrayofstring2(int j) { int o = __p.__offset(60); return o != 0 ? __p.__string(__p.__vector(o) + j * 4) : null; }
+  public int Testarrayofstring2Length { get { int o = __p.__offset(60); return o != 0 ? __p.__vector_len(o) : 0; } }
+  public MyGame.Example.Ability? Testarrayofsortedstruct(int j) { int o = __p.__offset(62); return o != 0 ? (MyGame.Example.Ability?)(new MyGame.Example.Ability()).__assign(__p.__vector(o) + j * 8, __p.bb) : null; }
+  public int TestarrayofsortedstructLength { get { int o = __p.__offset(62); return o != 0 ? __p.__vector_len(o) : 0; } }
+  public byte Flex(int j) { int o = __p.__offset(64); return o != 0 ? __p.bb.Get(__p.__vector(o) + j * 1) : (byte)0; }
+  public int FlexLength { get { int o = __p.__offset(64); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetFlexBytes() { return __p.__vector_as_span(64); }
+#else
+  public ArraySegment<byte>? GetFlexBytes() { return __p.__vector_as_arraysegment(64); }
+#endif
+  public byte[] GetFlexArray() { return __p.__vector_as_array<byte>(64); }
+  public bool MutateFlex(int j, byte flex) { int o = __p.__offset(64); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, flex); return true; } else { return false; } }
+  public MyGame.Example.Test? Test5(int j) { int o = __p.__offset(66); return o != 0 ? (MyGame.Example.Test?)(new MyGame.Example.Test()).__assign(__p.__vector(o) + j * 4, __p.bb) : null; }
+  public int Test5Length { get { int o = __p.__offset(66); return o != 0 ? __p.__vector_len(o) : 0; } }
+  public long VectorOfLongs(int j) { int o = __p.__offset(68); return o != 0 ? __p.bb.GetLong(__p.__vector(o) + j * 8) : (long)0; }
+  public int VectorOfLongsLength { get { int o = __p.__offset(68); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetVectorOfLongsBytes() { return __p.__vector_as_span(68); }
+#else
+  public ArraySegment<byte>? GetVectorOfLongsBytes() { return __p.__vector_as_arraysegment(68); }
+#endif
+  public long[] GetVectorOfLongsArray() { return __p.__vector_as_array<long>(68); }
+  public bool MutateVectorOfLongs(int j, long vector_of_longs) { int o = __p.__offset(68); if (o != 0) { __p.bb.PutLong(__p.__vector(o) + j * 8, vector_of_longs); return true; } else { return false; } }
+  public double VectorOfDoubles(int j) { int o = __p.__offset(70); return o != 0 ? __p.bb.GetDouble(__p.__vector(o) + j * 8) : (double)0; }
+  public int VectorOfDoublesLength { get { int o = __p.__offset(70); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetVectorOfDoublesBytes() { return __p.__vector_as_span(70); }
+#else
+  public ArraySegment<byte>? GetVectorOfDoublesBytes() { return __p.__vector_as_arraysegment(70); }
+#endif
+  public double[] GetVectorOfDoublesArray() { return __p.__vector_as_array<double>(70); }
+  public bool MutateVectorOfDoubles(int j, double vector_of_doubles) { int o = __p.__offset(70); if (o != 0) { __p.bb.PutDouble(__p.__vector(o) + j * 8, vector_of_doubles); return true; } else { return false; } }
+  public MyGame.InParentNamespace? ParentNamespaceTest { get { int o = __p.__offset(72); return o != 0 ? (MyGame.InParentNamespace?)(new MyGame.InParentNamespace()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
+  public MyGame.Example.Referrable? VectorOfReferrables(int j) { int o = __p.__offset(74); return o != 0 ? (MyGame.Example.Referrable?)(new MyGame.Example.Referrable()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
+  public int VectorOfReferrablesLength { get { int o = __p.__offset(74); return o != 0 ? __p.__vector_len(o) : 0; } }
+  public MyGame.Example.Referrable? VectorOfReferrablesByKey(ulong key) { int o = __p.__offset(74); return o != 0 ? MyGame.Example.Referrable.__lookup_by_key(__p.__vector(o), key, __p.bb) : null; }
+  public ulong SingleWeakReference { get { int o = __p.__offset(76); return o != 0 ? __p.bb.GetUlong(o + __p.bb_pos) : (ulong)0; } }
+  public bool MutateSingleWeakReference(ulong single_weak_reference) { int o = __p.__offset(76); if (o != 0) { __p.bb.PutUlong(o + __p.bb_pos, single_weak_reference); return true; } else { return false; } }
+  public ulong VectorOfWeakReferences(int j) { int o = __p.__offset(78); return o != 0 ? __p.bb.GetUlong(__p.__vector(o) + j * 8) : (ulong)0; }
+  public int VectorOfWeakReferencesLength { get { int o = __p.__offset(78); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetVectorOfWeakReferencesBytes() { return __p.__vector_as_span(78); }
+#else
+  public ArraySegment<byte>? GetVectorOfWeakReferencesBytes() { return __p.__vector_as_arraysegment(78); }
+#endif
+  public ulong[] GetVectorOfWeakReferencesArray() { return __p.__vector_as_array<ulong>(78); }
+  public bool MutateVectorOfWeakReferences(int j, ulong vector_of_weak_references) { int o = __p.__offset(78); if (o != 0) { __p.bb.PutUlong(__p.__vector(o) + j * 8, vector_of_weak_references); return true; } else { return false; } }
+  public MyGame.Example.Referrable? VectorOfStrongReferrables(int j) { int o = __p.__offset(80); return o != 0 ? (MyGame.Example.Referrable?)(new MyGame.Example.Referrable()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
+  public int VectorOfStrongReferrablesLength { get { int o = __p.__offset(80); return o != 0 ? __p.__vector_len(o) : 0; } }
+  public MyGame.Example.Referrable? VectorOfStrongReferrablesByKey(ulong key) { int o = __p.__offset(80); return o != 0 ? MyGame.Example.Referrable.__lookup_by_key(__p.__vector(o), key, __p.bb) : null; }
+  public ulong CoOwningReference { get { int o = __p.__offset(82); return o != 0 ? __p.bb.GetUlong(o + __p.bb_pos) : (ulong)0; } }
+  public bool MutateCoOwningReference(ulong co_owning_reference) { int o = __p.__offset(82); if (o != 0) { __p.bb.PutUlong(o + __p.bb_pos, co_owning_reference); return true; } else { return false; } }
+  public ulong VectorOfCoOwningReferences(int j) { int o = __p.__offset(84); return o != 0 ? __p.bb.GetUlong(__p.__vector(o) + j * 8) : (ulong)0; }
+  public int VectorOfCoOwningReferencesLength { get { int o = __p.__offset(84); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetVectorOfCoOwningReferencesBytes() { return __p.__vector_as_span(84); }
+#else
+  public ArraySegment<byte>? GetVectorOfCoOwningReferencesBytes() { return __p.__vector_as_arraysegment(84); }
+#endif
+  public ulong[] GetVectorOfCoOwningReferencesArray() { return __p.__vector_as_array<ulong>(84); }
+  public bool MutateVectorOfCoOwningReferences(int j, ulong vector_of_co_owning_references) { int o = __p.__offset(84); if (o != 0) { __p.bb.PutUlong(__p.__vector(o) + j * 8, vector_of_co_owning_references); return true; } else { return false; } }
+  public ulong NonOwningReference { get { int o = __p.__offset(86); return o != 0 ? __p.bb.GetUlong(o + __p.bb_pos) : (ulong)0; } }
+  public bool MutateNonOwningReference(ulong non_owning_reference) { int o = __p.__offset(86); if (o != 0) { __p.bb.PutUlong(o + __p.bb_pos, non_owning_reference); return true; } else { return false; } }
+  public ulong VectorOfNonOwningReferences(int j) { int o = __p.__offset(88); return o != 0 ? __p.bb.GetUlong(__p.__vector(o) + j * 8) : (ulong)0; }
+  public int VectorOfNonOwningReferencesLength { get { int o = __p.__offset(88); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetVectorOfNonOwningReferencesBytes() { return __p.__vector_as_span(88); }
+#else
+  public ArraySegment<byte>? GetVectorOfNonOwningReferencesBytes() { return __p.__vector_as_arraysegment(88); }
+#endif
+  public ulong[] GetVectorOfNonOwningReferencesArray() { return __p.__vector_as_array<ulong>(88); }
+  public bool MutateVectorOfNonOwningReferences(int j, ulong vector_of_non_owning_references) { int o = __p.__offset(88); if (o != 0) { __p.bb.PutUlong(__p.__vector(o) + j * 8, vector_of_non_owning_references); return true; } else { return false; } }
+  public MyGame.Example.AnyUniqueAliases AnyUniqueType { get { int o = __p.__offset(90); return o != 0 ? (MyGame.Example.AnyUniqueAliases)__p.bb.Get(o + __p.bb_pos) : MyGame.Example.AnyUniqueAliases.NONE; } }
+  public bool MutateAnyUniqueType(MyGame.Example.AnyUniqueAliases any_unique_type) { int o = __p.__offset(90); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)any_unique_type); return true; } else { return false; } }
+  public TTable? AnyUnique<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(92); return o != 0 ? (TTable?)__p.__union<TTable>(o) : null; }
+  public MyGame.Example.AnyAmbiguousAliases AnyAmbiguousType { get { int o = __p.__offset(94); return o != 0 ? (MyGame.Example.AnyAmbiguousAliases)__p.bb.Get(o + __p.bb_pos) : MyGame.Example.AnyAmbiguousAliases.NONE; } }
+  public bool MutateAnyAmbiguousType(MyGame.Example.AnyAmbiguousAliases any_ambiguous_type) { int o = __p.__offset(94); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)any_ambiguous_type); return true; } else { return false; } }
+  public TTable? AnyAmbiguous<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(96); return o != 0 ? (TTable?)__p.__union<TTable>(o) : null; }
+  public MyGame.Example.Color VectorOfEnums(int j) { int o = __p.__offset(98); return o != 0 ? (MyGame.Example.Color)__p.bb.Get(__p.__vector(o) + j * 1) : (MyGame.Example.Color)0; }
+  public int VectorOfEnumsLength { get { int o = __p.__offset(98); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetVectorOfEnumsBytes() { return __p.__vector_as_span(98); }
+#else
+  public ArraySegment<byte>? GetVectorOfEnumsBytes() { return __p.__vector_as_arraysegment(98); }
+#endif
+  public MyGame.Example.Color[] GetVectorOfEnumsArray() { return __p.__vector_as_array<MyGame.Example.Color>(98); }
+  public bool MutateVectorOfEnums(int j, MyGame.Example.Color vector_of_enums) { int o = __p.__offset(98); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, (byte)vector_of_enums); return true; } else { return false; } }
+
+  public static void StartMonster(FlatBufferBuilder builder) { builder.StartTable(48); }
+  public static void AddPos(FlatBufferBuilder builder, Offset<MyGame.Example.Vec3> posOffset) { builder.AddStruct(0, posOffset.Value, 0); }
+  public static void AddMana(FlatBufferBuilder builder, short mana) { builder.AddShort(1, mana, 150); }
+  public static void AddHp(FlatBufferBuilder builder, short hp) { builder.AddShort(2, hp, 100); }
+  public static void AddName(FlatBufferBuilder builder, StringOffset nameOffset) { builder.AddOffset(3, nameOffset.Value, 0); }
+  public static void AddInventory(FlatBufferBuilder builder, VectorOffset inventoryOffset) { builder.AddOffset(5, inventoryOffset.Value, 0); }
+  public static VectorOffset CreateInventoryVector(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddByte(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateInventoryVectorBlock(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); }
+  public static void StartInventoryVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
+  public static void AddColor(FlatBufferBuilder builder, MyGame.Example.Color color) { builder.AddByte(6, (byte)color, 8); }
+  public static void AddTestType(FlatBufferBuilder builder, MyGame.Example.Any testType) { builder.AddByte(7, (byte)testType, 0); }
+  public static void AddTest(FlatBufferBuilder builder, int testOffset) { builder.AddOffset(8, testOffset, 0); }
+  public static void AddTest4(FlatBufferBuilder builder, VectorOffset test4Offset) { builder.AddOffset(9, test4Offset.Value, 0); }
+  public static void StartTest4Vector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 2); }
+  public static void AddTestarrayofstring(FlatBufferBuilder builder, VectorOffset testarrayofstringOffset) { builder.AddOffset(10, testarrayofstringOffset.Value, 0); }
+  public static VectorOffset CreateTestarrayofstringVector(FlatBufferBuilder builder, StringOffset[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
+  public static VectorOffset CreateTestarrayofstringVectorBlock(FlatBufferBuilder builder, StringOffset[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
+  public static void StartTestarrayofstringVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
+  public static void AddTestarrayoftables(FlatBufferBuilder builder, VectorOffset testarrayoftablesOffset) { builder.AddOffset(11, testarrayoftablesOffset.Value, 0); }
+  public static VectorOffset CreateTestarrayoftablesVector(FlatBufferBuilder builder, Offset<MyGame.Example.Monster>[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
+  public static VectorOffset CreateTestarrayoftablesVectorBlock(FlatBufferBuilder builder, Offset<MyGame.Example.Monster>[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
+  public static void StartTestarrayoftablesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
+  public static void AddEnemy(FlatBufferBuilder builder, Offset<MyGame.Example.Monster> enemyOffset) { builder.AddOffset(12, enemyOffset.Value, 0); }
+  public static void AddTestnestedflatbuffer(FlatBufferBuilder builder, VectorOffset testnestedflatbufferOffset) { builder.AddOffset(13, testnestedflatbufferOffset.Value, 0); }
+  public static VectorOffset CreateTestnestedflatbufferVector(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddByte(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateTestnestedflatbufferVectorBlock(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); }
+  public static void StartTestnestedflatbufferVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
+  public static void AddTestempty(FlatBufferBuilder builder, Offset<MyGame.Example.Stat> testemptyOffset) { builder.AddOffset(14, testemptyOffset.Value, 0); }
+  public static void AddTestbool(FlatBufferBuilder builder, bool testbool) { builder.AddBool(15, testbool, false); }
+  public static void AddTesthashs32Fnv1(FlatBufferBuilder builder, int testhashs32Fnv1) { builder.AddInt(16, testhashs32Fnv1, 0); }
+  public static void AddTesthashu32Fnv1(FlatBufferBuilder builder, uint testhashu32Fnv1) { builder.AddUint(17, testhashu32Fnv1, 0); }
+  public static void AddTesthashs64Fnv1(FlatBufferBuilder builder, long testhashs64Fnv1) { builder.AddLong(18, testhashs64Fnv1, 0); }
+  public static void AddTesthashu64Fnv1(FlatBufferBuilder builder, ulong testhashu64Fnv1) { builder.AddUlong(19, testhashu64Fnv1, 0); }
+  public static void AddTesthashs32Fnv1a(FlatBufferBuilder builder, int testhashs32Fnv1a) { builder.AddInt(20, testhashs32Fnv1a, 0); }
+  public static void AddTesthashu32Fnv1a(FlatBufferBuilder builder, uint testhashu32Fnv1a) { builder.AddUint(21, testhashu32Fnv1a, 0); }
+  public static void AddTesthashs64Fnv1a(FlatBufferBuilder builder, long testhashs64Fnv1a) { builder.AddLong(22, testhashs64Fnv1a, 0); }
+  public static void AddTesthashu64Fnv1a(FlatBufferBuilder builder, ulong testhashu64Fnv1a) { builder.AddUlong(23, testhashu64Fnv1a, 0); }
+  public static void AddTestarrayofbools(FlatBufferBuilder builder, VectorOffset testarrayofboolsOffset) { builder.AddOffset(24, testarrayofboolsOffset.Value, 0); }
+  public static VectorOffset CreateTestarrayofboolsVector(FlatBufferBuilder builder, bool[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddBool(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateTestarrayofboolsVectorBlock(FlatBufferBuilder builder, bool[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); }
+  public static void StartTestarrayofboolsVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
+  public static void AddTestf(FlatBufferBuilder builder, float testf) { builder.AddFloat(25, testf, 3.14159f); }
+  public static void AddTestf2(FlatBufferBuilder builder, float testf2) { builder.AddFloat(26, testf2, 3.0f); }
+  public static void AddTestf3(FlatBufferBuilder builder, float testf3) { builder.AddFloat(27, testf3, 0.0f); }
+  public static void AddTestarrayofstring2(FlatBufferBuilder builder, VectorOffset testarrayofstring2Offset) { builder.AddOffset(28, testarrayofstring2Offset.Value, 0); }
+  public static VectorOffset CreateTestarrayofstring2Vector(FlatBufferBuilder builder, StringOffset[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
+  public static VectorOffset CreateTestarrayofstring2VectorBlock(FlatBufferBuilder builder, StringOffset[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
+  public static void StartTestarrayofstring2Vector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
+  public static void AddTestarrayofsortedstruct(FlatBufferBuilder builder, VectorOffset testarrayofsortedstructOffset) { builder.AddOffset(29, testarrayofsortedstructOffset.Value, 0); }
+  public static void StartTestarrayofsortedstructVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 4); }
+  public static void AddFlex(FlatBufferBuilder builder, VectorOffset flexOffset) { builder.AddOffset(30, flexOffset.Value, 0); }
+  public static VectorOffset CreateFlexVector(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddByte(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateFlexVectorBlock(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); }
+  public static void StartFlexVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
+  public static void AddTest5(FlatBufferBuilder builder, VectorOffset test5Offset) { builder.AddOffset(31, test5Offset.Value, 0); }
+  public static void StartTest5Vector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 2); }
+  public static void AddVectorOfLongs(FlatBufferBuilder builder, VectorOffset vectorOfLongsOffset) { builder.AddOffset(32, vectorOfLongsOffset.Value, 0); }
+  public static VectorOffset CreateVectorOfLongsVector(FlatBufferBuilder builder, long[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddLong(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateVectorOfLongsVectorBlock(FlatBufferBuilder builder, long[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
+  public static void StartVectorOfLongsVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
+  public static void AddVectorOfDoubles(FlatBufferBuilder builder, VectorOffset vectorOfDoublesOffset) { builder.AddOffset(33, vectorOfDoublesOffset.Value, 0); }
+  public static VectorOffset CreateVectorOfDoublesVector(FlatBufferBuilder builder, double[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddDouble(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateVectorOfDoublesVectorBlock(FlatBufferBuilder builder, double[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
+  public static void StartVectorOfDoublesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
+  public static void AddParentNamespaceTest(FlatBufferBuilder builder, Offset<MyGame.InParentNamespace> parentNamespaceTestOffset) { builder.AddOffset(34, parentNamespaceTestOffset.Value, 0); }
+  public static void AddVectorOfReferrables(FlatBufferBuilder builder, VectorOffset vectorOfReferrablesOffset) { builder.AddOffset(35, vectorOfReferrablesOffset.Value, 0); }
+  public static VectorOffset CreateVectorOfReferrablesVector(FlatBufferBuilder builder, Offset<MyGame.Example.Referrable>[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
+  public static VectorOffset CreateVectorOfReferrablesVectorBlock(FlatBufferBuilder builder, Offset<MyGame.Example.Referrable>[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
+  public static void StartVectorOfReferrablesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
+  public static void AddSingleWeakReference(FlatBufferBuilder builder, ulong singleWeakReference) { builder.AddUlong(36, singleWeakReference, 0); }
+  public static void AddVectorOfWeakReferences(FlatBufferBuilder builder, VectorOffset vectorOfWeakReferencesOffset) { builder.AddOffset(37, vectorOfWeakReferencesOffset.Value, 0); }
+  public static VectorOffset CreateVectorOfWeakReferencesVector(FlatBufferBuilder builder, ulong[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddUlong(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateVectorOfWeakReferencesVectorBlock(FlatBufferBuilder builder, ulong[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
+  public static void StartVectorOfWeakReferencesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
+  public static void AddVectorOfStrongReferrables(FlatBufferBuilder builder, VectorOffset vectorOfStrongReferrablesOffset) { builder.AddOffset(38, vectorOfStrongReferrablesOffset.Value, 0); }
+  public static VectorOffset CreateVectorOfStrongReferrablesVector(FlatBufferBuilder builder, Offset<MyGame.Example.Referrable>[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
+  public static VectorOffset CreateVectorOfStrongReferrablesVectorBlock(FlatBufferBuilder builder, Offset<MyGame.Example.Referrable>[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
+  public static void StartVectorOfStrongReferrablesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
+  public static void AddCoOwningReference(FlatBufferBuilder builder, ulong coOwningReference) { builder.AddUlong(39, coOwningReference, 0); }
+  public static void AddVectorOfCoOwningReferences(FlatBufferBuilder builder, VectorOffset vectorOfCoOwningReferencesOffset) { builder.AddOffset(40, vectorOfCoOwningReferencesOffset.Value, 0); }
+  public static VectorOffset CreateVectorOfCoOwningReferencesVector(FlatBufferBuilder builder, ulong[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddUlong(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateVectorOfCoOwningReferencesVectorBlock(FlatBufferBuilder builder, ulong[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
+  public static void StartVectorOfCoOwningReferencesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
+  public static void AddNonOwningReference(FlatBufferBuilder builder, ulong nonOwningReference) { builder.AddUlong(41, nonOwningReference, 0); }
+  public static void AddVectorOfNonOwningReferences(FlatBufferBuilder builder, VectorOffset vectorOfNonOwningReferencesOffset) { builder.AddOffset(42, vectorOfNonOwningReferencesOffset.Value, 0); }
+  public static VectorOffset CreateVectorOfNonOwningReferencesVector(FlatBufferBuilder builder, ulong[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddUlong(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateVectorOfNonOwningReferencesVectorBlock(FlatBufferBuilder builder, ulong[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
+  public static void StartVectorOfNonOwningReferencesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
+  public static void AddAnyUniqueType(FlatBufferBuilder builder, MyGame.Example.AnyUniqueAliases anyUniqueType) { builder.AddByte(43, (byte)anyUniqueType, 0); }
+  public static void AddAnyUnique(FlatBufferBuilder builder, int anyUniqueOffset) { builder.AddOffset(44, anyUniqueOffset, 0); }
+  public static void AddAnyAmbiguousType(FlatBufferBuilder builder, MyGame.Example.AnyAmbiguousAliases anyAmbiguousType) { builder.AddByte(45, (byte)anyAmbiguousType, 0); }
+  public static void AddAnyAmbiguous(FlatBufferBuilder builder, int anyAmbiguousOffset) { builder.AddOffset(46, anyAmbiguousOffset, 0); }
+  public static void AddVectorOfEnums(FlatBufferBuilder builder, VectorOffset vectorOfEnumsOffset) { builder.AddOffset(47, vectorOfEnumsOffset.Value, 0); }
+  public static VectorOffset CreateVectorOfEnumsVector(FlatBufferBuilder builder, MyGame.Example.Color[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddByte((byte)data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateVectorOfEnumsVectorBlock(FlatBufferBuilder builder, MyGame.Example.Color[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); }
+  public static void StartVectorOfEnumsVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
+  public static Offset<MyGame.Example.Monster> EndMonster(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    builder.Required(o, 10);  // name
+    return new Offset<MyGame.Example.Monster>(o);
+  }
+  public static void FinishMonsterBuffer(FlatBufferBuilder builder, Offset<MyGame.Example.Monster> offset) { builder.Finish(offset.Value, "MONS"); }
+  public static void FinishSizePrefixedMonsterBuffer(FlatBufferBuilder builder, Offset<MyGame.Example.Monster> offset) { builder.FinishSizePrefixed(offset.Value, "MONS"); }
+
+  public static VectorOffset CreateSortedVectorOfMonster(FlatBufferBuilder builder, Offset<Monster>[] offsets) {
+    Array.Sort(offsets, (Offset<Monster> o1, Offset<Monster> o2) => Table.CompareStrings(Table.__offset(10, o1.Value, builder.DataBuffer), Table.__offset(10, o2.Value, builder.DataBuffer), builder.DataBuffer));
+    return builder.CreateVectorOfTables(offsets);
+  }
+
+  public static Monster? __lookup_by_key(int vectorLocation, string key, ByteBuffer bb) {
+    byte[] byteKey = System.Text.Encoding.UTF8.GetBytes(key);
+    int span = bb.GetInt(vectorLocation - 4);
+    int start = 0;
+    while (span != 0) {
+      int middle = span / 2;
+      int tableOffset = Table.__indirect(vectorLocation + 4 * (start + middle), bb);
+      int comp = Table.CompareStrings(Table.__offset(10, bb.Length - tableOffset, bb), byteKey, bb);
+      if (comp > 0) {
+        span = middle;
+      } else if (comp < 0) {
+        middle++;
+        start += middle;
+        span -= middle;
+      } else {
+        return new Monster().__assign(tableOffset, bb);
+      }
+    }
+    return null;
+  }
+};
+
+
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Monster.go b/third_party/flatbuffers/tests/MyGame/Example/Monster.go
new file mode 100644
index 0000000..dabb596
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Monster.go
@@ -0,0 +1,1018 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package Example
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+
+	MyGame "MyGame"
+)
+
+/// an example documentation comment: monster object
+type Monster struct {
+	_tab flatbuffers.Table
+}
+
+func GetRootAsMonster(buf []byte, offset flatbuffers.UOffsetT) *Monster {
+	n := flatbuffers.GetUOffsetT(buf[offset:])
+	x := &Monster{}
+	x.Init(buf, n+offset)
+	return x
+}
+
+func (rcv *Monster) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *Monster) Table() flatbuffers.Table {
+	return rcv._tab
+}
+
+func (rcv *Monster) Pos(obj *Vec3) *Vec3 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+	if o != 0 {
+		x := o + rcv._tab.Pos
+		if obj == nil {
+			obj = new(Vec3)
+		}
+		obj.Init(rcv._tab.Bytes, x)
+		return obj
+	}
+	return nil
+}
+
+func (rcv *Monster) Mana() int16 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
+	if o != 0 {
+		return rcv._tab.GetInt16(o + rcv._tab.Pos)
+	}
+	return 150
+}
+
+func (rcv *Monster) MutateMana(n int16) bool {
+	return rcv._tab.MutateInt16Slot(6, n)
+}
+
+func (rcv *Monster) Hp() int16 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
+	if o != 0 {
+		return rcv._tab.GetInt16(o + rcv._tab.Pos)
+	}
+	return 100
+}
+
+func (rcv *Monster) MutateHp(n int16) bool {
+	return rcv._tab.MutateInt16Slot(8, n)
+}
+
+func (rcv *Monster) Name() []byte {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(10))
+	if o != 0 {
+		return rcv._tab.ByteVector(o + rcv._tab.Pos)
+	}
+	return nil
+}
+
+func (rcv *Monster) Inventory(j int) byte {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(14))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.GetByte(a + flatbuffers.UOffsetT(j*1))
+	}
+	return 0
+}
+
+func (rcv *Monster) InventoryLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(14))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) InventoryBytes() []byte {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(14))
+	if o != 0 {
+		return rcv._tab.ByteVector(o + rcv._tab.Pos)
+	}
+	return nil
+}
+
+func (rcv *Monster) MutateInventory(j int, n byte) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(14))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.MutateByte(a+flatbuffers.UOffsetT(j*1), n)
+	}
+	return false
+}
+
+func (rcv *Monster) Color() Color {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(16))
+	if o != 0 {
+		return Color(rcv._tab.GetByte(o + rcv._tab.Pos))
+	}
+	return 8
+}
+
+func (rcv *Monster) MutateColor(n Color) bool {
+	return rcv._tab.MutateByteSlot(16, byte(n))
+}
+
+func (rcv *Monster) TestType() Any {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(18))
+	if o != 0 {
+		return Any(rcv._tab.GetByte(o + rcv._tab.Pos))
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateTestType(n Any) bool {
+	return rcv._tab.MutateByteSlot(18, byte(n))
+}
+
+func (rcv *Monster) Test(obj *flatbuffers.Table) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(20))
+	if o != 0 {
+		rcv._tab.Union(obj, o)
+		return true
+	}
+	return false
+}
+
+func (rcv *Monster) Test4(obj *Test, j int) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(22))
+	if o != 0 {
+		x := rcv._tab.Vector(o)
+		x += flatbuffers.UOffsetT(j) * 4
+		obj.Init(rcv._tab.Bytes, x)
+		return true
+	}
+	return false
+}
+
+func (rcv *Monster) Test4Length() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(22))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) Testarrayofstring(j int) []byte {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(24))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.ByteVector(a + flatbuffers.UOffsetT(j*4))
+	}
+	return nil
+}
+
+func (rcv *Monster) TestarrayofstringLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(24))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+/// an example documentation comment: this will end up in the generated code
+/// multiline too
+func (rcv *Monster) Testarrayoftables(obj *Monster, j int) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(26))
+	if o != 0 {
+		x := rcv._tab.Vector(o)
+		x += flatbuffers.UOffsetT(j) * 4
+		x = rcv._tab.Indirect(x)
+		obj.Init(rcv._tab.Bytes, x)
+		return true
+	}
+	return false
+}
+
+func (rcv *Monster) TestarrayoftablesLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(26))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+/// an example documentation comment: this will end up in the generated code
+/// multiline too
+func (rcv *Monster) Enemy(obj *Monster) *Monster {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(28))
+	if o != 0 {
+		x := rcv._tab.Indirect(o + rcv._tab.Pos)
+		if obj == nil {
+			obj = new(Monster)
+		}
+		obj.Init(rcv._tab.Bytes, x)
+		return obj
+	}
+	return nil
+}
+
+func (rcv *Monster) Testnestedflatbuffer(j int) byte {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(30))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.GetByte(a + flatbuffers.UOffsetT(j*1))
+	}
+	return 0
+}
+
+func (rcv *Monster) TestnestedflatbufferLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(30))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) TestnestedflatbufferBytes() []byte {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(30))
+	if o != 0 {
+		return rcv._tab.ByteVector(o + rcv._tab.Pos)
+	}
+	return nil
+}
+
+func (rcv *Monster) MutateTestnestedflatbuffer(j int, n byte) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(30))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.MutateByte(a+flatbuffers.UOffsetT(j*1), n)
+	}
+	return false
+}
+
+func (rcv *Monster) Testempty(obj *Stat) *Stat {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(32))
+	if o != 0 {
+		x := rcv._tab.Indirect(o + rcv._tab.Pos)
+		if obj == nil {
+			obj = new(Stat)
+		}
+		obj.Init(rcv._tab.Bytes, x)
+		return obj
+	}
+	return nil
+}
+
+func (rcv *Monster) Testbool() bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(34))
+	if o != 0 {
+		return rcv._tab.GetBool(o + rcv._tab.Pos)
+	}
+	return false
+}
+
+func (rcv *Monster) MutateTestbool(n bool) bool {
+	return rcv._tab.MutateBoolSlot(34, n)
+}
+
+func (rcv *Monster) Testhashs32Fnv1() int32 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(36))
+	if o != 0 {
+		return rcv._tab.GetInt32(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateTesthashs32Fnv1(n int32) bool {
+	return rcv._tab.MutateInt32Slot(36, n)
+}
+
+func (rcv *Monster) Testhashu32Fnv1() uint32 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(38))
+	if o != 0 {
+		return rcv._tab.GetUint32(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateTesthashu32Fnv1(n uint32) bool {
+	return rcv._tab.MutateUint32Slot(38, n)
+}
+
+func (rcv *Monster) Testhashs64Fnv1() int64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(40))
+	if o != 0 {
+		return rcv._tab.GetInt64(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateTesthashs64Fnv1(n int64) bool {
+	return rcv._tab.MutateInt64Slot(40, n)
+}
+
+func (rcv *Monster) Testhashu64Fnv1() uint64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(42))
+	if o != 0 {
+		return rcv._tab.GetUint64(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateTesthashu64Fnv1(n uint64) bool {
+	return rcv._tab.MutateUint64Slot(42, n)
+}
+
+func (rcv *Monster) Testhashs32Fnv1a() int32 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(44))
+	if o != 0 {
+		return rcv._tab.GetInt32(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateTesthashs32Fnv1a(n int32) bool {
+	return rcv._tab.MutateInt32Slot(44, n)
+}
+
+func (rcv *Monster) Testhashu32Fnv1a() uint32 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(46))
+	if o != 0 {
+		return rcv._tab.GetUint32(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateTesthashu32Fnv1a(n uint32) bool {
+	return rcv._tab.MutateUint32Slot(46, n)
+}
+
+func (rcv *Monster) Testhashs64Fnv1a() int64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(48))
+	if o != 0 {
+		return rcv._tab.GetInt64(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateTesthashs64Fnv1a(n int64) bool {
+	return rcv._tab.MutateInt64Slot(48, n)
+}
+
+func (rcv *Monster) Testhashu64Fnv1a() uint64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(50))
+	if o != 0 {
+		return rcv._tab.GetUint64(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateTesthashu64Fnv1a(n uint64) bool {
+	return rcv._tab.MutateUint64Slot(50, n)
+}
+
+func (rcv *Monster) Testarrayofbools(j int) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(52))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.GetBool(a + flatbuffers.UOffsetT(j*1))
+	}
+	return false
+}
+
+func (rcv *Monster) TestarrayofboolsLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(52))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateTestarrayofbools(j int, n bool) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(52))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.MutateBool(a+flatbuffers.UOffsetT(j*1), n)
+	}
+	return false
+}
+
+func (rcv *Monster) Testf() float32 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(54))
+	if o != 0 {
+		return rcv._tab.GetFloat32(o + rcv._tab.Pos)
+	}
+	return 3.14159
+}
+
+func (rcv *Monster) MutateTestf(n float32) bool {
+	return rcv._tab.MutateFloat32Slot(54, n)
+}
+
+func (rcv *Monster) Testf2() float32 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(56))
+	if o != 0 {
+		return rcv._tab.GetFloat32(o + rcv._tab.Pos)
+	}
+	return 3.0
+}
+
+func (rcv *Monster) MutateTestf2(n float32) bool {
+	return rcv._tab.MutateFloat32Slot(56, n)
+}
+
+func (rcv *Monster) Testf3() float32 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(58))
+	if o != 0 {
+		return rcv._tab.GetFloat32(o + rcv._tab.Pos)
+	}
+	return 0.0
+}
+
+func (rcv *Monster) MutateTestf3(n float32) bool {
+	return rcv._tab.MutateFloat32Slot(58, n)
+}
+
+func (rcv *Monster) Testarrayofstring2(j int) []byte {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(60))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.ByteVector(a + flatbuffers.UOffsetT(j*4))
+	}
+	return nil
+}
+
+func (rcv *Monster) Testarrayofstring2Length() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(60))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) Testarrayofsortedstruct(obj *Ability, j int) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(62))
+	if o != 0 {
+		x := rcv._tab.Vector(o)
+		x += flatbuffers.UOffsetT(j) * 8
+		obj.Init(rcv._tab.Bytes, x)
+		return true
+	}
+	return false
+}
+
+func (rcv *Monster) TestarrayofsortedstructLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(62))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) Flex(j int) byte {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(64))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.GetByte(a + flatbuffers.UOffsetT(j*1))
+	}
+	return 0
+}
+
+func (rcv *Monster) FlexLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(64))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) FlexBytes() []byte {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(64))
+	if o != 0 {
+		return rcv._tab.ByteVector(o + rcv._tab.Pos)
+	}
+	return nil
+}
+
+func (rcv *Monster) MutateFlex(j int, n byte) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(64))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.MutateByte(a+flatbuffers.UOffsetT(j*1), n)
+	}
+	return false
+}
+
+func (rcv *Monster) Test5(obj *Test, j int) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(66))
+	if o != 0 {
+		x := rcv._tab.Vector(o)
+		x += flatbuffers.UOffsetT(j) * 4
+		obj.Init(rcv._tab.Bytes, x)
+		return true
+	}
+	return false
+}
+
+func (rcv *Monster) Test5Length() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(66))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) VectorOfLongs(j int) int64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(68))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.GetInt64(a + flatbuffers.UOffsetT(j*8))
+	}
+	return 0
+}
+
+func (rcv *Monster) VectorOfLongsLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(68))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateVectorOfLongs(j int, n int64) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(68))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.MutateInt64(a+flatbuffers.UOffsetT(j*8), n)
+	}
+	return false
+}
+
+func (rcv *Monster) VectorOfDoubles(j int) float64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(70))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.GetFloat64(a + flatbuffers.UOffsetT(j*8))
+	}
+	return 0
+}
+
+func (rcv *Monster) VectorOfDoublesLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(70))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateVectorOfDoubles(j int, n float64) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(70))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.MutateFloat64(a+flatbuffers.UOffsetT(j*8), n)
+	}
+	return false
+}
+
+func (rcv *Monster) ParentNamespaceTest(obj *MyGame.InParentNamespace) *MyGame.InParentNamespace {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(72))
+	if o != 0 {
+		x := rcv._tab.Indirect(o + rcv._tab.Pos)
+		if obj == nil {
+			obj = new(MyGame.InParentNamespace)
+		}
+		obj.Init(rcv._tab.Bytes, x)
+		return obj
+	}
+	return nil
+}
+
+func (rcv *Monster) VectorOfReferrables(obj *Referrable, j int) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(74))
+	if o != 0 {
+		x := rcv._tab.Vector(o)
+		x += flatbuffers.UOffsetT(j) * 4
+		x = rcv._tab.Indirect(x)
+		obj.Init(rcv._tab.Bytes, x)
+		return true
+	}
+	return false
+}
+
+func (rcv *Monster) VectorOfReferrablesLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(74))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) SingleWeakReference() uint64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(76))
+	if o != 0 {
+		return rcv._tab.GetUint64(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateSingleWeakReference(n uint64) bool {
+	return rcv._tab.MutateUint64Slot(76, n)
+}
+
+func (rcv *Monster) VectorOfWeakReferences(j int) uint64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(78))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.GetUint64(a + flatbuffers.UOffsetT(j*8))
+	}
+	return 0
+}
+
+func (rcv *Monster) VectorOfWeakReferencesLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(78))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateVectorOfWeakReferences(j int, n uint64) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(78))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.MutateUint64(a+flatbuffers.UOffsetT(j*8), n)
+	}
+	return false
+}
+
+func (rcv *Monster) VectorOfStrongReferrables(obj *Referrable, j int) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(80))
+	if o != 0 {
+		x := rcv._tab.Vector(o)
+		x += flatbuffers.UOffsetT(j) * 4
+		x = rcv._tab.Indirect(x)
+		obj.Init(rcv._tab.Bytes, x)
+		return true
+	}
+	return false
+}
+
+func (rcv *Monster) VectorOfStrongReferrablesLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(80))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) CoOwningReference() uint64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(82))
+	if o != 0 {
+		return rcv._tab.GetUint64(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateCoOwningReference(n uint64) bool {
+	return rcv._tab.MutateUint64Slot(82, n)
+}
+
+func (rcv *Monster) VectorOfCoOwningReferences(j int) uint64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(84))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.GetUint64(a + flatbuffers.UOffsetT(j*8))
+	}
+	return 0
+}
+
+func (rcv *Monster) VectorOfCoOwningReferencesLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(84))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateVectorOfCoOwningReferences(j int, n uint64) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(84))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.MutateUint64(a+flatbuffers.UOffsetT(j*8), n)
+	}
+	return false
+}
+
+func (rcv *Monster) NonOwningReference() uint64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(86))
+	if o != 0 {
+		return rcv._tab.GetUint64(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateNonOwningReference(n uint64) bool {
+	return rcv._tab.MutateUint64Slot(86, n)
+}
+
+func (rcv *Monster) VectorOfNonOwningReferences(j int) uint64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(88))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.GetUint64(a + flatbuffers.UOffsetT(j*8))
+	}
+	return 0
+}
+
+func (rcv *Monster) VectorOfNonOwningReferencesLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(88))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateVectorOfNonOwningReferences(j int, n uint64) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(88))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.MutateUint64(a+flatbuffers.UOffsetT(j*8), n)
+	}
+	return false
+}
+
+func (rcv *Monster) AnyUniqueType() AnyUniqueAliases {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(90))
+	if o != 0 {
+		return AnyUniqueAliases(rcv._tab.GetByte(o + rcv._tab.Pos))
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateAnyUniqueType(n AnyUniqueAliases) bool {
+	return rcv._tab.MutateByteSlot(90, byte(n))
+}
+
+func (rcv *Monster) AnyUnique(obj *flatbuffers.Table) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(92))
+	if o != 0 {
+		rcv._tab.Union(obj, o)
+		return true
+	}
+	return false
+}
+
+func (rcv *Monster) AnyAmbiguousType() AnyAmbiguousAliases {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(94))
+	if o != 0 {
+		return AnyAmbiguousAliases(rcv._tab.GetByte(o + rcv._tab.Pos))
+	}
+	return 0
+}
+
+func (rcv *Monster) MutateAnyAmbiguousType(n AnyAmbiguousAliases) bool {
+	return rcv._tab.MutateByteSlot(94, byte(n))
+}
+
+func (rcv *Monster) AnyAmbiguous(obj *flatbuffers.Table) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(96))
+	if o != 0 {
+		rcv._tab.Union(obj, o)
+		return true
+	}
+	return false
+}
+
+func (rcv *Monster) VectorOfEnums(j int) Color {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(98))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return Color(rcv._tab.GetByte(a + flatbuffers.UOffsetT(j*1)))
+	}
+	return 0
+}
+
+func (rcv *Monster) VectorOfEnumsLength() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(98))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *Monster) VectorOfEnumsBytes() []byte {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(98))
+	if o != 0 {
+		return rcv._tab.ByteVector(o + rcv._tab.Pos)
+	}
+	return nil
+}
+
+func (rcv *Monster) MutateVectorOfEnums(j int, n Color) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(98))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.MutateByte(a+flatbuffers.UOffsetT(j*1), byte(n))
+	}
+	return false
+}
+
+func MonsterStart(builder *flatbuffers.Builder) {
+	builder.StartObject(48)
+}
+func MonsterAddPos(builder *flatbuffers.Builder, pos flatbuffers.UOffsetT) {
+	builder.PrependStructSlot(0, flatbuffers.UOffsetT(pos), 0)
+}
+func MonsterAddMana(builder *flatbuffers.Builder, mana int16) {
+	builder.PrependInt16Slot(1, mana, 150)
+}
+func MonsterAddHp(builder *flatbuffers.Builder, hp int16) {
+	builder.PrependInt16Slot(2, hp, 100)
+}
+func MonsterAddName(builder *flatbuffers.Builder, name flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(3, flatbuffers.UOffsetT(name), 0)
+}
+func MonsterAddInventory(builder *flatbuffers.Builder, inventory flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(5, flatbuffers.UOffsetT(inventory), 0)
+}
+func MonsterStartInventoryVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(1, numElems, 1)
+}
+func MonsterAddColor(builder *flatbuffers.Builder, color Color) {
+	builder.PrependByteSlot(6, byte(color), 8)
+}
+func MonsterAddTestType(builder *flatbuffers.Builder, testType Any) {
+	builder.PrependByteSlot(7, byte(testType), 0)
+}
+func MonsterAddTest(builder *flatbuffers.Builder, test flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(8, flatbuffers.UOffsetT(test), 0)
+}
+func MonsterAddTest4(builder *flatbuffers.Builder, test4 flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(9, flatbuffers.UOffsetT(test4), 0)
+}
+func MonsterStartTest4Vector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(4, numElems, 2)
+}
+func MonsterAddTestarrayofstring(builder *flatbuffers.Builder, testarrayofstring flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(10, flatbuffers.UOffsetT(testarrayofstring), 0)
+}
+func MonsterStartTestarrayofstringVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(4, numElems, 4)
+}
+func MonsterAddTestarrayoftables(builder *flatbuffers.Builder, testarrayoftables flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(11, flatbuffers.UOffsetT(testarrayoftables), 0)
+}
+func MonsterStartTestarrayoftablesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(4, numElems, 4)
+}
+func MonsterAddEnemy(builder *flatbuffers.Builder, enemy flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(12, flatbuffers.UOffsetT(enemy), 0)
+}
+func MonsterAddTestnestedflatbuffer(builder *flatbuffers.Builder, testnestedflatbuffer flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(13, flatbuffers.UOffsetT(testnestedflatbuffer), 0)
+}
+func MonsterStartTestnestedflatbufferVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(1, numElems, 1)
+}
+func MonsterAddTestempty(builder *flatbuffers.Builder, testempty flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(14, flatbuffers.UOffsetT(testempty), 0)
+}
+func MonsterAddTestbool(builder *flatbuffers.Builder, testbool bool) {
+	builder.PrependBoolSlot(15, testbool, false)
+}
+func MonsterAddTesthashs32Fnv1(builder *flatbuffers.Builder, testhashs32Fnv1 int32) {
+	builder.PrependInt32Slot(16, testhashs32Fnv1, 0)
+}
+func MonsterAddTesthashu32Fnv1(builder *flatbuffers.Builder, testhashu32Fnv1 uint32) {
+	builder.PrependUint32Slot(17, testhashu32Fnv1, 0)
+}
+func MonsterAddTesthashs64Fnv1(builder *flatbuffers.Builder, testhashs64Fnv1 int64) {
+	builder.PrependInt64Slot(18, testhashs64Fnv1, 0)
+}
+func MonsterAddTesthashu64Fnv1(builder *flatbuffers.Builder, testhashu64Fnv1 uint64) {
+	builder.PrependUint64Slot(19, testhashu64Fnv1, 0)
+}
+func MonsterAddTesthashs32Fnv1a(builder *flatbuffers.Builder, testhashs32Fnv1a int32) {
+	builder.PrependInt32Slot(20, testhashs32Fnv1a, 0)
+}
+func MonsterAddTesthashu32Fnv1a(builder *flatbuffers.Builder, testhashu32Fnv1a uint32) {
+	builder.PrependUint32Slot(21, testhashu32Fnv1a, 0)
+}
+func MonsterAddTesthashs64Fnv1a(builder *flatbuffers.Builder, testhashs64Fnv1a int64) {
+	builder.PrependInt64Slot(22, testhashs64Fnv1a, 0)
+}
+func MonsterAddTesthashu64Fnv1a(builder *flatbuffers.Builder, testhashu64Fnv1a uint64) {
+	builder.PrependUint64Slot(23, testhashu64Fnv1a, 0)
+}
+func MonsterAddTestarrayofbools(builder *flatbuffers.Builder, testarrayofbools flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(24, flatbuffers.UOffsetT(testarrayofbools), 0)
+}
+func MonsterStartTestarrayofboolsVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(1, numElems, 1)
+}
+func MonsterAddTestf(builder *flatbuffers.Builder, testf float32) {
+	builder.PrependFloat32Slot(25, testf, 3.14159)
+}
+func MonsterAddTestf2(builder *flatbuffers.Builder, testf2 float32) {
+	builder.PrependFloat32Slot(26, testf2, 3.0)
+}
+func MonsterAddTestf3(builder *flatbuffers.Builder, testf3 float32) {
+	builder.PrependFloat32Slot(27, testf3, 0.0)
+}
+func MonsterAddTestarrayofstring2(builder *flatbuffers.Builder, testarrayofstring2 flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(28, flatbuffers.UOffsetT(testarrayofstring2), 0)
+}
+func MonsterStartTestarrayofstring2Vector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(4, numElems, 4)
+}
+func MonsterAddTestarrayofsortedstruct(builder *flatbuffers.Builder, testarrayofsortedstruct flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(29, flatbuffers.UOffsetT(testarrayofsortedstruct), 0)
+}
+func MonsterStartTestarrayofsortedstructVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(8, numElems, 4)
+}
+func MonsterAddFlex(builder *flatbuffers.Builder, flex flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(30, flatbuffers.UOffsetT(flex), 0)
+}
+func MonsterStartFlexVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(1, numElems, 1)
+}
+func MonsterAddTest5(builder *flatbuffers.Builder, test5 flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(31, flatbuffers.UOffsetT(test5), 0)
+}
+func MonsterStartTest5Vector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(4, numElems, 2)
+}
+func MonsterAddVectorOfLongs(builder *flatbuffers.Builder, vectorOfLongs flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(32, flatbuffers.UOffsetT(vectorOfLongs), 0)
+}
+func MonsterStartVectorOfLongsVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(8, numElems, 8)
+}
+func MonsterAddVectorOfDoubles(builder *flatbuffers.Builder, vectorOfDoubles flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(33, flatbuffers.UOffsetT(vectorOfDoubles), 0)
+}
+func MonsterStartVectorOfDoublesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(8, numElems, 8)
+}
+func MonsterAddParentNamespaceTest(builder *flatbuffers.Builder, parentNamespaceTest flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(34, flatbuffers.UOffsetT(parentNamespaceTest), 0)
+}
+func MonsterAddVectorOfReferrables(builder *flatbuffers.Builder, vectorOfReferrables flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(35, flatbuffers.UOffsetT(vectorOfReferrables), 0)
+}
+func MonsterStartVectorOfReferrablesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(4, numElems, 4)
+}
+func MonsterAddSingleWeakReference(builder *flatbuffers.Builder, singleWeakReference uint64) {
+	builder.PrependUint64Slot(36, singleWeakReference, 0)
+}
+func MonsterAddVectorOfWeakReferences(builder *flatbuffers.Builder, vectorOfWeakReferences flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(37, flatbuffers.UOffsetT(vectorOfWeakReferences), 0)
+}
+func MonsterStartVectorOfWeakReferencesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(8, numElems, 8)
+}
+func MonsterAddVectorOfStrongReferrables(builder *flatbuffers.Builder, vectorOfStrongReferrables flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(38, flatbuffers.UOffsetT(vectorOfStrongReferrables), 0)
+}
+func MonsterStartVectorOfStrongReferrablesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(4, numElems, 4)
+}
+func MonsterAddCoOwningReference(builder *flatbuffers.Builder, coOwningReference uint64) {
+	builder.PrependUint64Slot(39, coOwningReference, 0)
+}
+func MonsterAddVectorOfCoOwningReferences(builder *flatbuffers.Builder, vectorOfCoOwningReferences flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(40, flatbuffers.UOffsetT(vectorOfCoOwningReferences), 0)
+}
+func MonsterStartVectorOfCoOwningReferencesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(8, numElems, 8)
+}
+func MonsterAddNonOwningReference(builder *flatbuffers.Builder, nonOwningReference uint64) {
+	builder.PrependUint64Slot(41, nonOwningReference, 0)
+}
+func MonsterAddVectorOfNonOwningReferences(builder *flatbuffers.Builder, vectorOfNonOwningReferences flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(42, flatbuffers.UOffsetT(vectorOfNonOwningReferences), 0)
+}
+func MonsterStartVectorOfNonOwningReferencesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(8, numElems, 8)
+}
+func MonsterAddAnyUniqueType(builder *flatbuffers.Builder, anyUniqueType AnyUniqueAliases) {
+	builder.PrependByteSlot(43, byte(anyUniqueType), 0)
+}
+func MonsterAddAnyUnique(builder *flatbuffers.Builder, anyUnique flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(44, flatbuffers.UOffsetT(anyUnique), 0)
+}
+func MonsterAddAnyAmbiguousType(builder *flatbuffers.Builder, anyAmbiguousType AnyAmbiguousAliases) {
+	builder.PrependByteSlot(45, byte(anyAmbiguousType), 0)
+}
+func MonsterAddAnyAmbiguous(builder *flatbuffers.Builder, anyAmbiguous flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(46, flatbuffers.UOffsetT(anyAmbiguous), 0)
+}
+func MonsterAddVectorOfEnums(builder *flatbuffers.Builder, vectorOfEnums flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(47, flatbuffers.UOffsetT(vectorOfEnums), 0)
+}
+func MonsterStartVectorOfEnumsVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(1, numElems, 1)
+}
+func MonsterEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+	return builder.EndObject()
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Monster.java b/third_party/flatbuffers/tests/MyGame/Example/Monster.java
new file mode 100644
index 0000000..34d7983
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Monster.java
@@ -0,0 +1,276 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+/**
+ * an example documentation comment: monster object
+ */
+public final class Monster extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static Monster getRootAsMonster(ByteBuffer _bb) { return getRootAsMonster(_bb, new Monster()); }
+  public static Monster getRootAsMonster(ByteBuffer _bb, Monster obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public static boolean MonsterBufferHasIdentifier(ByteBuffer _bb) { return __has_identifier(_bb, "MONS"); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public Monster __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public MyGame.Example.Vec3 pos() { return pos(new MyGame.Example.Vec3()); }
+  public MyGame.Example.Vec3 pos(MyGame.Example.Vec3 obj) { int o = __offset(4); return o != 0 ? obj.__assign(o + bb_pos, bb) : null; }
+  public short mana() { int o = __offset(6); return o != 0 ? bb.getShort(o + bb_pos) : 150; }
+  public boolean mutateMana(short mana) { int o = __offset(6); if (o != 0) { bb.putShort(o + bb_pos, mana); return true; } else { return false; } }
+  public short hp() { int o = __offset(8); return o != 0 ? bb.getShort(o + bb_pos) : 100; }
+  public boolean mutateHp(short hp) { int o = __offset(8); if (o != 0) { bb.putShort(o + bb_pos, hp); return true; } else { return false; } }
+  public String name() { int o = __offset(10); return o != 0 ? __string(o + bb_pos) : null; }
+  public ByteBuffer nameAsByteBuffer() { return __vector_as_bytebuffer(10, 1); }
+  public ByteBuffer nameInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 10, 1); }
+  public int inventory(int j) { int o = __offset(14); return o != 0 ? bb.get(__vector(o) + j * 1) & 0xFF : 0; }
+  public int inventoryLength() { int o = __offset(14); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer inventoryAsByteBuffer() { return __vector_as_bytebuffer(14, 1); }
+  public ByteBuffer inventoryInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 14, 1); }
+  public boolean mutateInventory(int j, int inventory) { int o = __offset(14); if (o != 0) { bb.put(__vector(o) + j * 1, (byte)inventory); return true; } else { return false; } }
+  public int color() { int o = __offset(16); return o != 0 ? bb.get(o + bb_pos) & 0xFF : 8; }
+  public boolean mutateColor(int color) { int o = __offset(16); if (o != 0) { bb.put(o + bb_pos, (byte)color); return true; } else { return false; } }
+  public byte testType() { int o = __offset(18); return o != 0 ? bb.get(o + bb_pos) : 0; }
+  public boolean mutateTestType(byte test_type) { int o = __offset(18); if (o != 0) { bb.put(o + bb_pos, test_type); return true; } else { return false; } }
+  public Table test(Table obj) { int o = __offset(20); return o != 0 ? __union(obj, o) : null; }
+  public MyGame.Example.Test test4(int j) { return test4(new MyGame.Example.Test(), j); }
+  public MyGame.Example.Test test4(MyGame.Example.Test obj, int j) { int o = __offset(22); return o != 0 ? obj.__assign(__vector(o) + j * 4, bb) : null; }
+  public int test4Length() { int o = __offset(22); return o != 0 ? __vector_len(o) : 0; }
+  public String testarrayofstring(int j) { int o = __offset(24); return o != 0 ? __string(__vector(o) + j * 4) : null; }
+  public int testarrayofstringLength() { int o = __offset(24); return o != 0 ? __vector_len(o) : 0; }
+  /**
+   * an example documentation comment: this will end up in the generated code
+   * multiline too
+   */
+  public MyGame.Example.Monster testarrayoftables(int j) { return testarrayoftables(new MyGame.Example.Monster(), j); }
+  public MyGame.Example.Monster testarrayoftables(MyGame.Example.Monster obj, int j) { int o = __offset(26); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; }
+  public int testarrayoftablesLength() { int o = __offset(26); return o != 0 ? __vector_len(o) : 0; }
+  public MyGame.Example.Monster testarrayoftablesByKey(String key) { int o = __offset(26); return o != 0 ? MyGame.Example.Monster.__lookup_by_key(null, __vector(o), key, bb) : null; }
+  public MyGame.Example.Monster testarrayoftablesByKey(MyGame.Example.Monster obj, String key) { int o = __offset(26); return o != 0 ? MyGame.Example.Monster.__lookup_by_key(obj, __vector(o), key, bb) : null; }
+  public MyGame.Example.Monster enemy() { return enemy(new MyGame.Example.Monster()); }
+  public MyGame.Example.Monster enemy(MyGame.Example.Monster obj) { int o = __offset(28); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
+  public int testnestedflatbuffer(int j) { int o = __offset(30); return o != 0 ? bb.get(__vector(o) + j * 1) & 0xFF : 0; }
+  public int testnestedflatbufferLength() { int o = __offset(30); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer testnestedflatbufferAsByteBuffer() { return __vector_as_bytebuffer(30, 1); }
+  public ByteBuffer testnestedflatbufferInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 30, 1); }
+  public MyGame.Example.Monster testnestedflatbufferAsMonster() { return testnestedflatbufferAsMonster(new MyGame.Example.Monster()); }
+  public MyGame.Example.Monster testnestedflatbufferAsMonster(MyGame.Example.Monster obj) { int o = __offset(30); return o != 0 ? obj.__assign(__indirect(__vector(o)), bb) : null; }
+  public boolean mutateTestnestedflatbuffer(int j, int testnestedflatbuffer) { int o = __offset(30); if (o != 0) { bb.put(__vector(o) + j * 1, (byte)testnestedflatbuffer); return true; } else { return false; } }
+  public MyGame.Example.Stat testempty() { return testempty(new MyGame.Example.Stat()); }
+  public MyGame.Example.Stat testempty(MyGame.Example.Stat obj) { int o = __offset(32); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
+  public boolean testbool() { int o = __offset(34); return o != 0 ? 0!=bb.get(o + bb_pos) : false; }
+  public boolean mutateTestbool(boolean testbool) { int o = __offset(34); if (o != 0) { bb.put(o + bb_pos, (byte)(testbool ? 1 : 0)); return true; } else { return false; } }
+  public int testhashs32Fnv1() { int o = __offset(36); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
+  public boolean mutateTesthashs32Fnv1(int testhashs32_fnv1) { int o = __offset(36); if (o != 0) { bb.putInt(o + bb_pos, testhashs32_fnv1); return true; } else { return false; } }
+  public long testhashu32Fnv1() { int o = __offset(38); return o != 0 ? (long)bb.getInt(o + bb_pos) & 0xFFFFFFFFL : 0L; }
+  public boolean mutateTesthashu32Fnv1(long testhashu32_fnv1) { int o = __offset(38); if (o != 0) { bb.putInt(o + bb_pos, (int)testhashu32_fnv1); return true; } else { return false; } }
+  public long testhashs64Fnv1() { int o = __offset(40); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
+  public boolean mutateTesthashs64Fnv1(long testhashs64_fnv1) { int o = __offset(40); if (o != 0) { bb.putLong(o + bb_pos, testhashs64_fnv1); return true; } else { return false; } }
+  public long testhashu64Fnv1() { int o = __offset(42); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
+  public boolean mutateTesthashu64Fnv1(long testhashu64_fnv1) { int o = __offset(42); if (o != 0) { bb.putLong(o + bb_pos, testhashu64_fnv1); return true; } else { return false; } }
+  public int testhashs32Fnv1a() { int o = __offset(44); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
+  public boolean mutateTesthashs32Fnv1a(int testhashs32_fnv1a) { int o = __offset(44); if (o != 0) { bb.putInt(o + bb_pos, testhashs32_fnv1a); return true; } else { return false; } }
+  public long testhashu32Fnv1a() { int o = __offset(46); return o != 0 ? (long)bb.getInt(o + bb_pos) & 0xFFFFFFFFL : 0L; }
+  public boolean mutateTesthashu32Fnv1a(long testhashu32_fnv1a) { int o = __offset(46); if (o != 0) { bb.putInt(o + bb_pos, (int)testhashu32_fnv1a); return true; } else { return false; } }
+  public long testhashs64Fnv1a() { int o = __offset(48); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
+  public boolean mutateTesthashs64Fnv1a(long testhashs64_fnv1a) { int o = __offset(48); if (o != 0) { bb.putLong(o + bb_pos, testhashs64_fnv1a); return true; } else { return false; } }
+  public long testhashu64Fnv1a() { int o = __offset(50); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
+  public boolean mutateTesthashu64Fnv1a(long testhashu64_fnv1a) { int o = __offset(50); if (o != 0) { bb.putLong(o + bb_pos, testhashu64_fnv1a); return true; } else { return false; } }
+  public boolean testarrayofbools(int j) { int o = __offset(52); return o != 0 ? 0!=bb.get(__vector(o) + j * 1) : false; }
+  public int testarrayofboolsLength() { int o = __offset(52); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer testarrayofboolsAsByteBuffer() { return __vector_as_bytebuffer(52, 1); }
+  public ByteBuffer testarrayofboolsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 52, 1); }
+  public boolean mutateTestarrayofbools(int j, boolean testarrayofbools) { int o = __offset(52); if (o != 0) { bb.put(__vector(o) + j * 1, (byte)(testarrayofbools ? 1 : 0)); return true; } else { return false; } }
+  public float testf() { int o = __offset(54); return o != 0 ? bb.getFloat(o + bb_pos) : 3.14159f; }
+  public boolean mutateTestf(float testf) { int o = __offset(54); if (o != 0) { bb.putFloat(o + bb_pos, testf); return true; } else { return false; } }
+  public float testf2() { int o = __offset(56); return o != 0 ? bb.getFloat(o + bb_pos) : 3.0f; }
+  public boolean mutateTestf2(float testf2) { int o = __offset(56); if (o != 0) { bb.putFloat(o + bb_pos, testf2); return true; } else { return false; } }
+  public float testf3() { int o = __offset(58); return o != 0 ? bb.getFloat(o + bb_pos) : 0.0f; }
+  public boolean mutateTestf3(float testf3) { int o = __offset(58); if (o != 0) { bb.putFloat(o + bb_pos, testf3); return true; } else { return false; } }
+  public String testarrayofstring2(int j) { int o = __offset(60); return o != 0 ? __string(__vector(o) + j * 4) : null; }
+  public int testarrayofstring2Length() { int o = __offset(60); return o != 0 ? __vector_len(o) : 0; }
+  public MyGame.Example.Ability testarrayofsortedstruct(int j) { return testarrayofsortedstruct(new MyGame.Example.Ability(), j); }
+  public MyGame.Example.Ability testarrayofsortedstruct(MyGame.Example.Ability obj, int j) { int o = __offset(62); return o != 0 ? obj.__assign(__vector(o) + j * 8, bb) : null; }
+  public int testarrayofsortedstructLength() { int o = __offset(62); return o != 0 ? __vector_len(o) : 0; }
+  public int flex(int j) { int o = __offset(64); return o != 0 ? bb.get(__vector(o) + j * 1) & 0xFF : 0; }
+  public int flexLength() { int o = __offset(64); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer flexAsByteBuffer() { return __vector_as_bytebuffer(64, 1); }
+  public ByteBuffer flexInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 64, 1); }
+  public boolean mutateFlex(int j, int flex) { int o = __offset(64); if (o != 0) { bb.put(__vector(o) + j * 1, (byte)flex); return true; } else { return false; } }
+  public MyGame.Example.Test test5(int j) { return test5(new MyGame.Example.Test(), j); }
+  public MyGame.Example.Test test5(MyGame.Example.Test obj, int j) { int o = __offset(66); return o != 0 ? obj.__assign(__vector(o) + j * 4, bb) : null; }
+  public int test5Length() { int o = __offset(66); return o != 0 ? __vector_len(o) : 0; }
+  public long vectorOfLongs(int j) { int o = __offset(68); return o != 0 ? bb.getLong(__vector(o) + j * 8) : 0; }
+  public int vectorOfLongsLength() { int o = __offset(68); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer vectorOfLongsAsByteBuffer() { return __vector_as_bytebuffer(68, 8); }
+  public ByteBuffer vectorOfLongsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 68, 8); }
+  public boolean mutateVectorOfLongs(int j, long vector_of_longs) { int o = __offset(68); if (o != 0) { bb.putLong(__vector(o) + j * 8, vector_of_longs); return true; } else { return false; } }
+  public double vectorOfDoubles(int j) { int o = __offset(70); return o != 0 ? bb.getDouble(__vector(o) + j * 8) : 0; }
+  public int vectorOfDoublesLength() { int o = __offset(70); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer vectorOfDoublesAsByteBuffer() { return __vector_as_bytebuffer(70, 8); }
+  public ByteBuffer vectorOfDoublesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 70, 8); }
+  public boolean mutateVectorOfDoubles(int j, double vector_of_doubles) { int o = __offset(70); if (o != 0) { bb.putDouble(__vector(o) + j * 8, vector_of_doubles); return true; } else { return false; } }
+  public MyGame.InParentNamespace parentNamespaceTest() { return parentNamespaceTest(new MyGame.InParentNamespace()); }
+  public MyGame.InParentNamespace parentNamespaceTest(MyGame.InParentNamespace obj) { int o = __offset(72); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
+  public MyGame.Example.Referrable vectorOfReferrables(int j) { return vectorOfReferrables(new MyGame.Example.Referrable(), j); }
+  public MyGame.Example.Referrable vectorOfReferrables(MyGame.Example.Referrable obj, int j) { int o = __offset(74); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; }
+  public int vectorOfReferrablesLength() { int o = __offset(74); return o != 0 ? __vector_len(o) : 0; }
+  public MyGame.Example.Referrable vectorOfReferrablesByKey(long key) { int o = __offset(74); return o != 0 ? MyGame.Example.Referrable.__lookup_by_key(null, __vector(o), key, bb) : null; }
+  public MyGame.Example.Referrable vectorOfReferrablesByKey(MyGame.Example.Referrable obj, long key) { int o = __offset(74); return o != 0 ? MyGame.Example.Referrable.__lookup_by_key(obj, __vector(o), key, bb) : null; }
+  public long singleWeakReference() { int o = __offset(76); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
+  public boolean mutateSingleWeakReference(long single_weak_reference) { int o = __offset(76); if (o != 0) { bb.putLong(o + bb_pos, single_weak_reference); return true; } else { return false; } }
+  public long vectorOfWeakReferences(int j) { int o = __offset(78); return o != 0 ? bb.getLong(__vector(o) + j * 8) : 0; }
+  public int vectorOfWeakReferencesLength() { int o = __offset(78); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer vectorOfWeakReferencesAsByteBuffer() { return __vector_as_bytebuffer(78, 8); }
+  public ByteBuffer vectorOfWeakReferencesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 78, 8); }
+  public boolean mutateVectorOfWeakReferences(int j, long vector_of_weak_references) { int o = __offset(78); if (o != 0) { bb.putLong(__vector(o) + j * 8, vector_of_weak_references); return true; } else { return false; } }
+  public MyGame.Example.Referrable vectorOfStrongReferrables(int j) { return vectorOfStrongReferrables(new MyGame.Example.Referrable(), j); }
+  public MyGame.Example.Referrable vectorOfStrongReferrables(MyGame.Example.Referrable obj, int j) { int o = __offset(80); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; }
+  public int vectorOfStrongReferrablesLength() { int o = __offset(80); return o != 0 ? __vector_len(o) : 0; }
+  public MyGame.Example.Referrable vectorOfStrongReferrablesByKey(long key) { int o = __offset(80); return o != 0 ? MyGame.Example.Referrable.__lookup_by_key(null, __vector(o), key, bb) : null; }
+  public MyGame.Example.Referrable vectorOfStrongReferrablesByKey(MyGame.Example.Referrable obj, long key) { int o = __offset(80); return o != 0 ? MyGame.Example.Referrable.__lookup_by_key(obj, __vector(o), key, bb) : null; }
+  public long coOwningReference() { int o = __offset(82); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
+  public boolean mutateCoOwningReference(long co_owning_reference) { int o = __offset(82); if (o != 0) { bb.putLong(o + bb_pos, co_owning_reference); return true; } else { return false; } }
+  public long vectorOfCoOwningReferences(int j) { int o = __offset(84); return o != 0 ? bb.getLong(__vector(o) + j * 8) : 0; }
+  public int vectorOfCoOwningReferencesLength() { int o = __offset(84); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer vectorOfCoOwningReferencesAsByteBuffer() { return __vector_as_bytebuffer(84, 8); }
+  public ByteBuffer vectorOfCoOwningReferencesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 84, 8); }
+  public boolean mutateVectorOfCoOwningReferences(int j, long vector_of_co_owning_references) { int o = __offset(84); if (o != 0) { bb.putLong(__vector(o) + j * 8, vector_of_co_owning_references); return true; } else { return false; } }
+  public long nonOwningReference() { int o = __offset(86); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
+  public boolean mutateNonOwningReference(long non_owning_reference) { int o = __offset(86); if (o != 0) { bb.putLong(o + bb_pos, non_owning_reference); return true; } else { return false; } }
+  public long vectorOfNonOwningReferences(int j) { int o = __offset(88); return o != 0 ? bb.getLong(__vector(o) + j * 8) : 0; }
+  public int vectorOfNonOwningReferencesLength() { int o = __offset(88); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer vectorOfNonOwningReferencesAsByteBuffer() { return __vector_as_bytebuffer(88, 8); }
+  public ByteBuffer vectorOfNonOwningReferencesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 88, 8); }
+  public boolean mutateVectorOfNonOwningReferences(int j, long vector_of_non_owning_references) { int o = __offset(88); if (o != 0) { bb.putLong(__vector(o) + j * 8, vector_of_non_owning_references); return true; } else { return false; } }
+  public byte anyUniqueType() { int o = __offset(90); return o != 0 ? bb.get(o + bb_pos) : 0; }
+  public boolean mutateAnyUniqueType(byte any_unique_type) { int o = __offset(90); if (o != 0) { bb.put(o + bb_pos, any_unique_type); return true; } else { return false; } }
+  public Table anyUnique(Table obj) { int o = __offset(92); return o != 0 ? __union(obj, o) : null; }
+  public byte anyAmbiguousType() { int o = __offset(94); return o != 0 ? bb.get(o + bb_pos) : 0; }
+  public boolean mutateAnyAmbiguousType(byte any_ambiguous_type) { int o = __offset(94); if (o != 0) { bb.put(o + bb_pos, any_ambiguous_type); return true; } else { return false; } }
+  public Table anyAmbiguous(Table obj) { int o = __offset(96); return o != 0 ? __union(obj, o) : null; }
+  public int vectorOfEnums(int j) { int o = __offset(98); return o != 0 ? bb.get(__vector(o) + j * 1) & 0xFF : 0; }
+  public int vectorOfEnumsLength() { int o = __offset(98); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer vectorOfEnumsAsByteBuffer() { return __vector_as_bytebuffer(98, 1); }
+  public ByteBuffer vectorOfEnumsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 98, 1); }
+  public boolean mutateVectorOfEnums(int j, int vector_of_enums) { int o = __offset(98); if (o != 0) { bb.put(__vector(o) + j * 1, (byte)vector_of_enums); return true; } else { return false; } }
+
+  public static void startMonster(FlatBufferBuilder builder) { builder.startTable(48); }
+  public static void addPos(FlatBufferBuilder builder, int posOffset) { builder.addStruct(0, posOffset, 0); }
+  public static void addMana(FlatBufferBuilder builder, short mana) { builder.addShort(1, mana, 150); }
+  public static void addHp(FlatBufferBuilder builder, short hp) { builder.addShort(2, hp, 100); }
+  public static void addName(FlatBufferBuilder builder, int nameOffset) { builder.addOffset(3, nameOffset, 0); }
+  public static void addInventory(FlatBufferBuilder builder, int inventoryOffset) { builder.addOffset(5, inventoryOffset, 0); }
+  public static int createInventoryVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); }
+  public static void startInventoryVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
+  public static void addColor(FlatBufferBuilder builder, int color) { builder.addByte(6, (byte)color, (byte)8); }
+  public static void addTestType(FlatBufferBuilder builder, byte testType) { builder.addByte(7, testType, 0); }
+  public static void addTest(FlatBufferBuilder builder, int testOffset) { builder.addOffset(8, testOffset, 0); }
+  public static void addTest4(FlatBufferBuilder builder, int test4Offset) { builder.addOffset(9, test4Offset, 0); }
+  public static void startTest4Vector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 2); }
+  public static void addTestarrayofstring(FlatBufferBuilder builder, int testarrayofstringOffset) { builder.addOffset(10, testarrayofstringOffset, 0); }
+  public static int createTestarrayofstringVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
+  public static void startTestarrayofstringVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
+  public static void addTestarrayoftables(FlatBufferBuilder builder, int testarrayoftablesOffset) { builder.addOffset(11, testarrayoftablesOffset, 0); }
+  public static int createTestarrayoftablesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
+  public static void startTestarrayoftablesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
+  public static void addEnemy(FlatBufferBuilder builder, int enemyOffset) { builder.addOffset(12, enemyOffset, 0); }
+  public static void addTestnestedflatbuffer(FlatBufferBuilder builder, int testnestedflatbufferOffset) { builder.addOffset(13, testnestedflatbufferOffset, 0); }
+  public static int createTestnestedflatbufferVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); }
+  public static void startTestnestedflatbufferVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
+  public static void addTestempty(FlatBufferBuilder builder, int testemptyOffset) { builder.addOffset(14, testemptyOffset, 0); }
+  public static void addTestbool(FlatBufferBuilder builder, boolean testbool) { builder.addBoolean(15, testbool, false); }
+  public static void addTesthashs32Fnv1(FlatBufferBuilder builder, int testhashs32Fnv1) { builder.addInt(16, testhashs32Fnv1, 0); }
+  public static void addTesthashu32Fnv1(FlatBufferBuilder builder, long testhashu32Fnv1) { builder.addInt(17, (int)testhashu32Fnv1, (int)0L); }
+  public static void addTesthashs64Fnv1(FlatBufferBuilder builder, long testhashs64Fnv1) { builder.addLong(18, testhashs64Fnv1, 0L); }
+  public static void addTesthashu64Fnv1(FlatBufferBuilder builder, long testhashu64Fnv1) { builder.addLong(19, testhashu64Fnv1, 0L); }
+  public static void addTesthashs32Fnv1a(FlatBufferBuilder builder, int testhashs32Fnv1a) { builder.addInt(20, testhashs32Fnv1a, 0); }
+  public static void addTesthashu32Fnv1a(FlatBufferBuilder builder, long testhashu32Fnv1a) { builder.addInt(21, (int)testhashu32Fnv1a, (int)0L); }
+  public static void addTesthashs64Fnv1a(FlatBufferBuilder builder, long testhashs64Fnv1a) { builder.addLong(22, testhashs64Fnv1a, 0L); }
+  public static void addTesthashu64Fnv1a(FlatBufferBuilder builder, long testhashu64Fnv1a) { builder.addLong(23, testhashu64Fnv1a, 0L); }
+  public static void addTestarrayofbools(FlatBufferBuilder builder, int testarrayofboolsOffset) { builder.addOffset(24, testarrayofboolsOffset, 0); }
+  public static int createTestarrayofboolsVector(FlatBufferBuilder builder, boolean[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addBoolean(data[i]); return builder.endVector(); }
+  public static void startTestarrayofboolsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
+  public static void addTestf(FlatBufferBuilder builder, float testf) { builder.addFloat(25, testf, 3.14159f); }
+  public static void addTestf2(FlatBufferBuilder builder, float testf2) { builder.addFloat(26, testf2, 3.0f); }
+  public static void addTestf3(FlatBufferBuilder builder, float testf3) { builder.addFloat(27, testf3, 0.0f); }
+  public static void addTestarrayofstring2(FlatBufferBuilder builder, int testarrayofstring2Offset) { builder.addOffset(28, testarrayofstring2Offset, 0); }
+  public static int createTestarrayofstring2Vector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
+  public static void startTestarrayofstring2Vector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
+  public static void addTestarrayofsortedstruct(FlatBufferBuilder builder, int testarrayofsortedstructOffset) { builder.addOffset(29, testarrayofsortedstructOffset, 0); }
+  public static void startTestarrayofsortedstructVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 4); }
+  public static void addFlex(FlatBufferBuilder builder, int flexOffset) { builder.addOffset(30, flexOffset, 0); }
+  public static int createFlexVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); }
+  public static void startFlexVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
+  public static void addTest5(FlatBufferBuilder builder, int test5Offset) { builder.addOffset(31, test5Offset, 0); }
+  public static void startTest5Vector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 2); }
+  public static void addVectorOfLongs(FlatBufferBuilder builder, int vectorOfLongsOffset) { builder.addOffset(32, vectorOfLongsOffset, 0); }
+  public static int createVectorOfLongsVector(FlatBufferBuilder builder, long[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addLong(data[i]); return builder.endVector(); }
+  public static void startVectorOfLongsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); }
+  public static void addVectorOfDoubles(FlatBufferBuilder builder, int vectorOfDoublesOffset) { builder.addOffset(33, vectorOfDoublesOffset, 0); }
+  public static int createVectorOfDoublesVector(FlatBufferBuilder builder, double[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addDouble(data[i]); return builder.endVector(); }
+  public static void startVectorOfDoublesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); }
+  public static void addParentNamespaceTest(FlatBufferBuilder builder, int parentNamespaceTestOffset) { builder.addOffset(34, parentNamespaceTestOffset, 0); }
+  public static void addVectorOfReferrables(FlatBufferBuilder builder, int vectorOfReferrablesOffset) { builder.addOffset(35, vectorOfReferrablesOffset, 0); }
+  public static int createVectorOfReferrablesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
+  public static void startVectorOfReferrablesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
+  public static void addSingleWeakReference(FlatBufferBuilder builder, long singleWeakReference) { builder.addLong(36, singleWeakReference, 0L); }
+  public static void addVectorOfWeakReferences(FlatBufferBuilder builder, int vectorOfWeakReferencesOffset) { builder.addOffset(37, vectorOfWeakReferencesOffset, 0); }
+  public static int createVectorOfWeakReferencesVector(FlatBufferBuilder builder, long[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addLong(data[i]); return builder.endVector(); }
+  public static void startVectorOfWeakReferencesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); }
+  public static void addVectorOfStrongReferrables(FlatBufferBuilder builder, int vectorOfStrongReferrablesOffset) { builder.addOffset(38, vectorOfStrongReferrablesOffset, 0); }
+  public static int createVectorOfStrongReferrablesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
+  public static void startVectorOfStrongReferrablesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
+  public static void addCoOwningReference(FlatBufferBuilder builder, long coOwningReference) { builder.addLong(39, coOwningReference, 0L); }
+  public static void addVectorOfCoOwningReferences(FlatBufferBuilder builder, int vectorOfCoOwningReferencesOffset) { builder.addOffset(40, vectorOfCoOwningReferencesOffset, 0); }
+  public static int createVectorOfCoOwningReferencesVector(FlatBufferBuilder builder, long[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addLong(data[i]); return builder.endVector(); }
+  public static void startVectorOfCoOwningReferencesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); }
+  public static void addNonOwningReference(FlatBufferBuilder builder, long nonOwningReference) { builder.addLong(41, nonOwningReference, 0L); }
+  public static void addVectorOfNonOwningReferences(FlatBufferBuilder builder, int vectorOfNonOwningReferencesOffset) { builder.addOffset(42, vectorOfNonOwningReferencesOffset, 0); }
+  public static int createVectorOfNonOwningReferencesVector(FlatBufferBuilder builder, long[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addLong(data[i]); return builder.endVector(); }
+  public static void startVectorOfNonOwningReferencesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); }
+  public static void addAnyUniqueType(FlatBufferBuilder builder, byte anyUniqueType) { builder.addByte(43, anyUniqueType, 0); }
+  public static void addAnyUnique(FlatBufferBuilder builder, int anyUniqueOffset) { builder.addOffset(44, anyUniqueOffset, 0); }
+  public static void addAnyAmbiguousType(FlatBufferBuilder builder, byte anyAmbiguousType) { builder.addByte(45, anyAmbiguousType, 0); }
+  public static void addAnyAmbiguous(FlatBufferBuilder builder, int anyAmbiguousOffset) { builder.addOffset(46, anyAmbiguousOffset, 0); }
+  public static void addVectorOfEnums(FlatBufferBuilder builder, int vectorOfEnumsOffset) { builder.addOffset(47, vectorOfEnumsOffset, 0); }
+  public static int createVectorOfEnumsVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); }
+  public static void startVectorOfEnumsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
+  public static int endMonster(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    builder.required(o, 10);  // name
+    return o;
+  }
+  public static void finishMonsterBuffer(FlatBufferBuilder builder, int offset) { builder.finish(offset, "MONS"); }
+  public static void finishSizePrefixedMonsterBuffer(FlatBufferBuilder builder, int offset) { builder.finishSizePrefixed(offset, "MONS"); }
+
+  @Override
+  protected int keysCompare(Integer o1, Integer o2, ByteBuffer _bb) { return compareStrings(__offset(10, o1, _bb), __offset(10, o2, _bb), _bb); }
+
+  public static Monster __lookup_by_key(Monster obj, int vectorLocation, String key, ByteBuffer bb) {
+    byte[] byteKey = key.getBytes(Table.UTF8_CHARSET.get());
+    int span = bb.getInt(vectorLocation - 4);
+    int start = 0;
+    while (span != 0) {
+      int middle = span / 2;
+      int tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb);
+      int comp = compareStrings(__offset(10, bb.capacity() - tableOffset, bb), byteKey, bb);
+      if (comp > 0) {
+        span = middle;
+      } else if (comp < 0) {
+        middle++;
+        start += middle;
+        span -= middle;
+      } else {
+        return (obj == null ? new Monster() : obj).__assign(tableOffset, bb);
+      }
+    }
+    return null;
+  }
+}
+
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Monster.kt b/third_party/flatbuffers/tests/MyGame/Example/Monster.kt
new file mode 100644
index 0000000..71d72b8
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Monster.kt
@@ -0,0 +1,974 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+/**
+ * an example documentation comment: monster object
+ */
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Monster : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : Monster {
+        __init(_i, _bb)
+        return this
+    }
+    val pos : MyGame.Example.Vec3? get() = pos(MyGame.Example.Vec3())
+    fun pos(obj: MyGame.Example.Vec3) : MyGame.Example.Vec3? {
+        val o = __offset(4)
+        return if (o != 0) {
+            obj.__assign(o + bb_pos, bb)
+        } else {
+            null
+        }
+    }
+    val mana : Short
+        get() {
+            val o = __offset(6)
+            return if(o != 0) bb.getShort(o + bb_pos) else 150
+        }
+    fun mutateMana(mana: Short) : Boolean {
+        val o = __offset(6)
+        return if (o != 0) {
+            bb.putShort(o + bb_pos, mana)
+            true
+        } else {
+            false
+        }
+    }
+    val hp : Short
+        get() {
+            val o = __offset(8)
+            return if(o != 0) bb.getShort(o + bb_pos) else 100
+        }
+    fun mutateHp(hp: Short) : Boolean {
+        val o = __offset(8)
+        return if (o != 0) {
+            bb.putShort(o + bb_pos, hp)
+            true
+        } else {
+            false
+        }
+    }
+    val name : String?
+        get() {
+            val o = __offset(10)
+            return if (o != 0) __string(o + bb_pos) else null
+        }
+    val nameAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(10, 1)
+    fun nameInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 10, 1)
+    fun inventory(j: Int) : UByte {
+        val o = __offset(14)
+        return if (o != 0) {
+            bb.get(__vector(o) + j * 1).toUByte()
+        } else {
+            0u
+        }
+    }
+    val inventoryLength : Int
+        get() {
+            val o = __offset(14); return if (o != 0) __vector_len(o) else 0
+        }
+    val inventoryAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(14, 1)
+    fun inventoryInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 14, 1)
+    fun mutateInventory(j: Int, inventory: UByte) : Boolean {
+        val o = __offset(14)
+        return if (o != 0) {
+            bb.put(__vector(o) + j * 1, inventory.toByte())
+            true
+        } else {
+            false
+        }
+    }
+    val color : UByte
+        get() {
+            val o = __offset(16)
+            return if(o != 0) bb.get(o + bb_pos).toUByte() else 8u
+        }
+    fun mutateColor(color: UByte) : Boolean {
+        val o = __offset(16)
+        return if (o != 0) {
+            bb.put(o + bb_pos, color.toByte())
+            true
+        } else {
+            false
+        }
+    }
+    val testType : UByte
+        get() {
+            val o = __offset(18)
+            return if(o != 0) bb.get(o + bb_pos).toUByte() else 0u
+        }
+    fun mutateTestType(testType: UByte) : Boolean {
+        val o = __offset(18)
+        return if (o != 0) {
+            bb.put(o + bb_pos, testType.toByte())
+            true
+        } else {
+            false
+        }
+    }
+    fun test(obj: Table) : Table? {
+        val o = __offset(20); return if (o != 0) __union(obj, o) else null
+    }
+    fun test4(j: Int) : MyGame.Example.Test? = test4(MyGame.Example.Test(), j)
+    fun test4(obj: MyGame.Example.Test, j: Int) : MyGame.Example.Test? {
+        val o = __offset(22)
+        return if (o != 0) {
+            obj.__assign(__vector(o) + j * 4, bb)
+        } else {
+            null
+        }
+    }
+    val test4Length : Int
+        get() {
+            val o = __offset(22); return if (o != 0) __vector_len(o) else 0
+        }
+    fun testarrayofstring(j: Int) : String? {
+        val o = __offset(24)
+        return if (o != 0) {
+            __string(__vector(o) + j * 4)
+        } else {
+            null
+        }
+    }
+    val testarrayofstringLength : Int
+        get() {
+            val o = __offset(24); return if (o != 0) __vector_len(o) else 0
+        }
+    /**
+     * an example documentation comment: this will end up in the generated code
+     * multiline too
+     */
+    fun testarrayoftables(j: Int) : MyGame.Example.Monster? = testarrayoftables(MyGame.Example.Monster(), j)
+    fun testarrayoftables(obj: MyGame.Example.Monster, j: Int) : MyGame.Example.Monster? {
+        val o = __offset(26)
+        return if (o != 0) {
+            obj.__assign(__indirect(__vector(o) + j * 4), bb)
+        } else {
+            null
+        }
+    }
+    val testarrayoftablesLength : Int
+        get() {
+            val o = __offset(26); return if (o != 0) __vector_len(o) else 0
+        }
+    fun testarrayoftablesByKey(key: String) : MyGame.Example.Monster? {
+        val o = __offset(26)
+        return if (o != 0) {
+            MyGame.Example.Monster.__lookup_by_key(null, __vector(o), key, bb)
+        } else {
+            null
+        }
+    }
+    fun testarrayoftablesByKey(obj: MyGame.Example.Monster, key: String) : MyGame.Example.Monster? {
+        val o = __offset(26)
+        return if (o != 0) {
+            MyGame.Example.Monster.__lookup_by_key(obj, __vector(o), key, bb)
+        } else {
+            null
+        }
+    }
+    val enemy : MyGame.Example.Monster? get() = enemy(MyGame.Example.Monster())
+    fun enemy(obj: MyGame.Example.Monster) : MyGame.Example.Monster? {
+        val o = __offset(28)
+        return if (o != 0) {
+            obj.__assign(__indirect(o + bb_pos), bb)
+        } else {
+            null
+        }
+    }
+    fun testnestedflatbuffer(j: Int) : UByte {
+        val o = __offset(30)
+        return if (o != 0) {
+            bb.get(__vector(o) + j * 1).toUByte()
+        } else {
+            0u
+        }
+    }
+    val testnestedflatbufferLength : Int
+        get() {
+            val o = __offset(30); return if (o != 0) __vector_len(o) else 0
+        }
+    val testnestedflatbufferAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(30, 1)
+    fun testnestedflatbufferInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 30, 1)
+    val testnestedflatbufferAsMonster : MyGame.Example.Monster? get() = testnestedflatbufferAsMonster(MyGame.Example.Monster())
+    fun testnestedflatbufferAsMonster(obj: MyGame.Example.Monster) : MyGame.Example.Monster? {
+        val o = __offset(30)
+        return if (o != 0) {
+            obj.__assign(__indirect(__vector(o)), bb)
+        } else {
+            null
+        }
+    }
+    fun mutateTestnestedflatbuffer(j: Int, testnestedflatbuffer: UByte) : Boolean {
+        val o = __offset(30)
+        return if (o != 0) {
+            bb.put(__vector(o) + j * 1, testnestedflatbuffer.toByte())
+            true
+        } else {
+            false
+        }
+    }
+    val testempty : MyGame.Example.Stat? get() = testempty(MyGame.Example.Stat())
+    fun testempty(obj: MyGame.Example.Stat) : MyGame.Example.Stat? {
+        val o = __offset(32)
+        return if (o != 0) {
+            obj.__assign(__indirect(o + bb_pos), bb)
+        } else {
+            null
+        }
+    }
+    val testbool : Boolean
+        get() {
+            val o = __offset(34)
+            return if(o != 0) 0.toByte() != bb.get(o + bb_pos) else false
+        }
+    fun mutateTestbool(testbool: Boolean) : Boolean {
+        val o = __offset(34)
+        return if (o != 0) {
+            bb.put(o + bb_pos, (if(testbool) 1 else 0).toByte())
+            true
+        } else {
+            false
+        }
+    }
+    val testhashs32Fnv1 : Int
+        get() {
+            val o = __offset(36)
+            return if(o != 0) bb.getInt(o + bb_pos) else 0
+        }
+    fun mutateTesthashs32Fnv1(testhashs32Fnv1: Int) : Boolean {
+        val o = __offset(36)
+        return if (o != 0) {
+            bb.putInt(o + bb_pos, testhashs32Fnv1)
+            true
+        } else {
+            false
+        }
+    }
+    val testhashu32Fnv1 : UInt
+        get() {
+            val o = __offset(38)
+            return if(o != 0) bb.getInt(o + bb_pos).toUInt() else 0u
+        }
+    fun mutateTesthashu32Fnv1(testhashu32Fnv1: UInt) : Boolean {
+        val o = __offset(38)
+        return if (o != 0) {
+            bb.putInt(o + bb_pos, testhashu32Fnv1.toInt())
+            true
+        } else {
+            false
+        }
+    }
+    val testhashs64Fnv1 : Long
+        get() {
+            val o = __offset(40)
+            return if(o != 0) bb.getLong(o + bb_pos) else 0L
+        }
+    fun mutateTesthashs64Fnv1(testhashs64Fnv1: Long) : Boolean {
+        val o = __offset(40)
+        return if (o != 0) {
+            bb.putLong(o + bb_pos, testhashs64Fnv1)
+            true
+        } else {
+            false
+        }
+    }
+    val testhashu64Fnv1 : ULong
+        get() {
+            val o = __offset(42)
+            return if(o != 0) bb.getLong(o + bb_pos).toULong() else 0UL
+        }
+    fun mutateTesthashu64Fnv1(testhashu64Fnv1: ULong) : Boolean {
+        val o = __offset(42)
+        return if (o != 0) {
+            bb.putLong(o + bb_pos, testhashu64Fnv1.toLong())
+            true
+        } else {
+            false
+        }
+    }
+    val testhashs32Fnv1a : Int
+        get() {
+            val o = __offset(44)
+            return if(o != 0) bb.getInt(o + bb_pos) else 0
+        }
+    fun mutateTesthashs32Fnv1a(testhashs32Fnv1a: Int) : Boolean {
+        val o = __offset(44)
+        return if (o != 0) {
+            bb.putInt(o + bb_pos, testhashs32Fnv1a)
+            true
+        } else {
+            false
+        }
+    }
+    val testhashu32Fnv1a : UInt
+        get() {
+            val o = __offset(46)
+            return if(o != 0) bb.getInt(o + bb_pos).toUInt() else 0u
+        }
+    fun mutateTesthashu32Fnv1a(testhashu32Fnv1a: UInt) : Boolean {
+        val o = __offset(46)
+        return if (o != 0) {
+            bb.putInt(o + bb_pos, testhashu32Fnv1a.toInt())
+            true
+        } else {
+            false
+        }
+    }
+    val testhashs64Fnv1a : Long
+        get() {
+            val o = __offset(48)
+            return if(o != 0) bb.getLong(o + bb_pos) else 0L
+        }
+    fun mutateTesthashs64Fnv1a(testhashs64Fnv1a: Long) : Boolean {
+        val o = __offset(48)
+        return if (o != 0) {
+            bb.putLong(o + bb_pos, testhashs64Fnv1a)
+            true
+        } else {
+            false
+        }
+    }
+    val testhashu64Fnv1a : ULong
+        get() {
+            val o = __offset(50)
+            return if(o != 0) bb.getLong(o + bb_pos).toULong() else 0UL
+        }
+    fun mutateTesthashu64Fnv1a(testhashu64Fnv1a: ULong) : Boolean {
+        val o = __offset(50)
+        return if (o != 0) {
+            bb.putLong(o + bb_pos, testhashu64Fnv1a.toLong())
+            true
+        } else {
+            false
+        }
+    }
+    fun testarrayofbools(j: Int) : Boolean {
+        val o = __offset(52)
+        return if (o != 0) {
+            0.toByte() != bb.get(__vector(o) + j * 1)
+        } else {
+            false
+        }
+    }
+    val testarrayofboolsLength : Int
+        get() {
+            val o = __offset(52); return if (o != 0) __vector_len(o) else 0
+        }
+    val testarrayofboolsAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(52, 1)
+    fun testarrayofboolsInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 52, 1)
+    fun mutateTestarrayofbools(j: Int, testarrayofbools: Boolean) : Boolean {
+        val o = __offset(52)
+        return if (o != 0) {
+            bb.put(__vector(o) + j * 1, (if(testarrayofbools) 1 else 0).toByte())
+            true
+        } else {
+            false
+        }
+    }
+    val testf : Float
+        get() {
+            val o = __offset(54)
+            return if(o != 0) bb.getFloat(o + bb_pos) else 3.14159f
+        }
+    fun mutateTestf(testf: Float) : Boolean {
+        val o = __offset(54)
+        return if (o != 0) {
+            bb.putFloat(o + bb_pos, testf)
+            true
+        } else {
+            false
+        }
+    }
+    val testf2 : Float
+        get() {
+            val o = __offset(56)
+            return if(o != 0) bb.getFloat(o + bb_pos) else 3.0f
+        }
+    fun mutateTestf2(testf2: Float) : Boolean {
+        val o = __offset(56)
+        return if (o != 0) {
+            bb.putFloat(o + bb_pos, testf2)
+            true
+        } else {
+            false
+        }
+    }
+    val testf3 : Float
+        get() {
+            val o = __offset(58)
+            return if(o != 0) bb.getFloat(o + bb_pos) else 0.0f
+        }
+    fun mutateTestf3(testf3: Float) : Boolean {
+        val o = __offset(58)
+        return if (o != 0) {
+            bb.putFloat(o + bb_pos, testf3)
+            true
+        } else {
+            false
+        }
+    }
+    fun testarrayofstring2(j: Int) : String? {
+        val o = __offset(60)
+        return if (o != 0) {
+            __string(__vector(o) + j * 4)
+        } else {
+            null
+        }
+    }
+    val testarrayofstring2Length : Int
+        get() {
+            val o = __offset(60); return if (o != 0) __vector_len(o) else 0
+        }
+    fun testarrayofsortedstruct(j: Int) : MyGame.Example.Ability? = testarrayofsortedstruct(MyGame.Example.Ability(), j)
+    fun testarrayofsortedstruct(obj: MyGame.Example.Ability, j: Int) : MyGame.Example.Ability? {
+        val o = __offset(62)
+        return if (o != 0) {
+            obj.__assign(__vector(o) + j * 8, bb)
+        } else {
+            null
+        }
+    }
+    val testarrayofsortedstructLength : Int
+        get() {
+            val o = __offset(62); return if (o != 0) __vector_len(o) else 0
+        }
+    fun flex(j: Int) : UByte {
+        val o = __offset(64)
+        return if (o != 0) {
+            bb.get(__vector(o) + j * 1).toUByte()
+        } else {
+            0u
+        }
+    }
+    val flexLength : Int
+        get() {
+            val o = __offset(64); return if (o != 0) __vector_len(o) else 0
+        }
+    val flexAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(64, 1)
+    fun flexInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 64, 1)
+    fun mutateFlex(j: Int, flex: UByte) : Boolean {
+        val o = __offset(64)
+        return if (o != 0) {
+            bb.put(__vector(o) + j * 1, flex.toByte())
+            true
+        } else {
+            false
+        }
+    }
+    fun test5(j: Int) : MyGame.Example.Test? = test5(MyGame.Example.Test(), j)
+    fun test5(obj: MyGame.Example.Test, j: Int) : MyGame.Example.Test? {
+        val o = __offset(66)
+        return if (o != 0) {
+            obj.__assign(__vector(o) + j * 4, bb)
+        } else {
+            null
+        }
+    }
+    val test5Length : Int
+        get() {
+            val o = __offset(66); return if (o != 0) __vector_len(o) else 0
+        }
+    fun vectorOfLongs(j: Int) : Long {
+        val o = __offset(68)
+        return if (o != 0) {
+            bb.getLong(__vector(o) + j * 8)
+        } else {
+            0
+        }
+    }
+    val vectorOfLongsLength : Int
+        get() {
+            val o = __offset(68); return if (o != 0) __vector_len(o) else 0
+        }
+    val vectorOfLongsAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(68, 8)
+    fun vectorOfLongsInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 68, 8)
+    fun mutateVectorOfLongs(j: Int, vectorOfLongs: Long) : Boolean {
+        val o = __offset(68)
+        return if (o != 0) {
+            bb.putLong(__vector(o) + j * 8, vectorOfLongs)
+            true
+        } else {
+            false
+        }
+    }
+    fun vectorOfDoubles(j: Int) : Double {
+        val o = __offset(70)
+        return if (o != 0) {
+            bb.getDouble(__vector(o) + j * 8)
+        } else {
+            0.0
+        }
+    }
+    val vectorOfDoublesLength : Int
+        get() {
+            val o = __offset(70); return if (o != 0) __vector_len(o) else 0
+        }
+    val vectorOfDoublesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(70, 8)
+    fun vectorOfDoublesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 70, 8)
+    fun mutateVectorOfDoubles(j: Int, vectorOfDoubles: Double) : Boolean {
+        val o = __offset(70)
+        return if (o != 0) {
+            bb.putDouble(__vector(o) + j * 8, vectorOfDoubles)
+            true
+        } else {
+            false
+        }
+    }
+    val parentNamespaceTest : MyGame.InParentNamespace? get() = parentNamespaceTest(MyGame.InParentNamespace())
+    fun parentNamespaceTest(obj: MyGame.InParentNamespace) : MyGame.InParentNamespace? {
+        val o = __offset(72)
+        return if (o != 0) {
+            obj.__assign(__indirect(o + bb_pos), bb)
+        } else {
+            null
+        }
+    }
+    fun vectorOfReferrables(j: Int) : MyGame.Example.Referrable? = vectorOfReferrables(MyGame.Example.Referrable(), j)
+    fun vectorOfReferrables(obj: MyGame.Example.Referrable, j: Int) : MyGame.Example.Referrable? {
+        val o = __offset(74)
+        return if (o != 0) {
+            obj.__assign(__indirect(__vector(o) + j * 4), bb)
+        } else {
+            null
+        }
+    }
+    val vectorOfReferrablesLength : Int
+        get() {
+            val o = __offset(74); return if (o != 0) __vector_len(o) else 0
+        }
+    fun vectorOfReferrablesByKey(key: ULong) : MyGame.Example.Referrable? {
+        val o = __offset(74)
+        return if (o != 0) {
+            MyGame.Example.Referrable.__lookup_by_key(null, __vector(o), key, bb)
+        } else {
+            null
+        }
+    }
+    fun vectorOfReferrablesByKey(obj: MyGame.Example.Referrable, key: ULong) : MyGame.Example.Referrable? {
+        val o = __offset(74)
+        return if (o != 0) {
+            MyGame.Example.Referrable.__lookup_by_key(obj, __vector(o), key, bb)
+        } else {
+            null
+        }
+    }
+    val singleWeakReference : ULong
+        get() {
+            val o = __offset(76)
+            return if(o != 0) bb.getLong(o + bb_pos).toULong() else 0UL
+        }
+    fun mutateSingleWeakReference(singleWeakReference: ULong) : Boolean {
+        val o = __offset(76)
+        return if (o != 0) {
+            bb.putLong(o + bb_pos, singleWeakReference.toLong())
+            true
+        } else {
+            false
+        }
+    }
+    fun vectorOfWeakReferences(j: Int) : ULong {
+        val o = __offset(78)
+        return if (o != 0) {
+            bb.getLong(__vector(o) + j * 8).toULong()
+        } else {
+            0uL
+        }
+    }
+    val vectorOfWeakReferencesLength : Int
+        get() {
+            val o = __offset(78); return if (o != 0) __vector_len(o) else 0
+        }
+    val vectorOfWeakReferencesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(78, 8)
+    fun vectorOfWeakReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 78, 8)
+    fun mutateVectorOfWeakReferences(j: Int, vectorOfWeakReferences: ULong) : Boolean {
+        val o = __offset(78)
+        return if (o != 0) {
+            bb.putLong(__vector(o) + j * 8, vectorOfWeakReferences.toLong())
+            true
+        } else {
+            false
+        }
+    }
+    fun vectorOfStrongReferrables(j: Int) : MyGame.Example.Referrable? = vectorOfStrongReferrables(MyGame.Example.Referrable(), j)
+    fun vectorOfStrongReferrables(obj: MyGame.Example.Referrable, j: Int) : MyGame.Example.Referrable? {
+        val o = __offset(80)
+        return if (o != 0) {
+            obj.__assign(__indirect(__vector(o) + j * 4), bb)
+        } else {
+            null
+        }
+    }
+    val vectorOfStrongReferrablesLength : Int
+        get() {
+            val o = __offset(80); return if (o != 0) __vector_len(o) else 0
+        }
+    fun vectorOfStrongReferrablesByKey(key: ULong) : MyGame.Example.Referrable? {
+        val o = __offset(80)
+        return if (o != 0) {
+            MyGame.Example.Referrable.__lookup_by_key(null, __vector(o), key, bb)
+        } else {
+            null
+        }
+    }
+    fun vectorOfStrongReferrablesByKey(obj: MyGame.Example.Referrable, key: ULong) : MyGame.Example.Referrable? {
+        val o = __offset(80)
+        return if (o != 0) {
+            MyGame.Example.Referrable.__lookup_by_key(obj, __vector(o), key, bb)
+        } else {
+            null
+        }
+    }
+    val coOwningReference : ULong
+        get() {
+            val o = __offset(82)
+            return if(o != 0) bb.getLong(o + bb_pos).toULong() else 0UL
+        }
+    fun mutateCoOwningReference(coOwningReference: ULong) : Boolean {
+        val o = __offset(82)
+        return if (o != 0) {
+            bb.putLong(o + bb_pos, coOwningReference.toLong())
+            true
+        } else {
+            false
+        }
+    }
+    fun vectorOfCoOwningReferences(j: Int) : ULong {
+        val o = __offset(84)
+        return if (o != 0) {
+            bb.getLong(__vector(o) + j * 8).toULong()
+        } else {
+            0uL
+        }
+    }
+    val vectorOfCoOwningReferencesLength : Int
+        get() {
+            val o = __offset(84); return if (o != 0) __vector_len(o) else 0
+        }
+    val vectorOfCoOwningReferencesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(84, 8)
+    fun vectorOfCoOwningReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 84, 8)
+    fun mutateVectorOfCoOwningReferences(j: Int, vectorOfCoOwningReferences: ULong) : Boolean {
+        val o = __offset(84)
+        return if (o != 0) {
+            bb.putLong(__vector(o) + j * 8, vectorOfCoOwningReferences.toLong())
+            true
+        } else {
+            false
+        }
+    }
+    val nonOwningReference : ULong
+        get() {
+            val o = __offset(86)
+            return if(o != 0) bb.getLong(o + bb_pos).toULong() else 0UL
+        }
+    fun mutateNonOwningReference(nonOwningReference: ULong) : Boolean {
+        val o = __offset(86)
+        return if (o != 0) {
+            bb.putLong(o + bb_pos, nonOwningReference.toLong())
+            true
+        } else {
+            false
+        }
+    }
+    fun vectorOfNonOwningReferences(j: Int) : ULong {
+        val o = __offset(88)
+        return if (o != 0) {
+            bb.getLong(__vector(o) + j * 8).toULong()
+        } else {
+            0uL
+        }
+    }
+    val vectorOfNonOwningReferencesLength : Int
+        get() {
+            val o = __offset(88); return if (o != 0) __vector_len(o) else 0
+        }
+    val vectorOfNonOwningReferencesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(88, 8)
+    fun vectorOfNonOwningReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 88, 8)
+    fun mutateVectorOfNonOwningReferences(j: Int, vectorOfNonOwningReferences: ULong) : Boolean {
+        val o = __offset(88)
+        return if (o != 0) {
+            bb.putLong(__vector(o) + j * 8, vectorOfNonOwningReferences.toLong())
+            true
+        } else {
+            false
+        }
+    }
+    val anyUniqueType : UByte
+        get() {
+            val o = __offset(90)
+            return if(o != 0) bb.get(o + bb_pos).toUByte() else 0u
+        }
+    fun mutateAnyUniqueType(anyUniqueType: UByte) : Boolean {
+        val o = __offset(90)
+        return if (o != 0) {
+            bb.put(o + bb_pos, anyUniqueType.toByte())
+            true
+        } else {
+            false
+        }
+    }
+    fun anyUnique(obj: Table) : Table? {
+        val o = __offset(92); return if (o != 0) __union(obj, o) else null
+    }
+    val anyAmbiguousType : UByte
+        get() {
+            val o = __offset(94)
+            return if(o != 0) bb.get(o + bb_pos).toUByte() else 0u
+        }
+    fun mutateAnyAmbiguousType(anyAmbiguousType: UByte) : Boolean {
+        val o = __offset(94)
+        return if (o != 0) {
+            bb.put(o + bb_pos, anyAmbiguousType.toByte())
+            true
+        } else {
+            false
+        }
+    }
+    fun anyAmbiguous(obj: Table) : Table? {
+        val o = __offset(96); return if (o != 0) __union(obj, o) else null
+    }
+    fun vectorOfEnums(j: Int) : UByte {
+        val o = __offset(98)
+        return if (o != 0) {
+            bb.get(__vector(o) + j * 1).toUByte()
+        } else {
+            0u
+        }
+    }
+    val vectorOfEnumsLength : Int
+        get() {
+            val o = __offset(98); return if (o != 0) __vector_len(o) else 0
+        }
+    val vectorOfEnumsAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(98, 1)
+    fun vectorOfEnumsInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 98, 1)
+    fun mutateVectorOfEnums(j: Int, vectorOfEnums: UByte) : Boolean {
+        val o = __offset(98)
+        return if (o != 0) {
+            bb.put(__vector(o) + j * 1, vectorOfEnums.toByte())
+            true
+        } else {
+            false
+        }
+    }
+    override fun keysCompare(o1: Int, o2: Int, _bb: ByteBuffer) : Int {
+         return compareStrings(__offset(10, o1, _bb), __offset(10, o2, _bb), _bb)
+    }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsMonster(_bb: ByteBuffer): Monster = getRootAsMonster(_bb, Monster())
+        fun getRootAsMonster(_bb: ByteBuffer, obj: Monster): Monster {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun MonsterBufferHasIdentifier(_bb: ByteBuffer) : Boolean = __has_identifier(_bb, "MONS")
+        fun startMonster(builder: FlatBufferBuilder) = builder.startTable(48)
+        fun addPos(builder: FlatBufferBuilder, pos: Int) = builder.addStruct(0, pos, 0)
+        fun addMana(builder: FlatBufferBuilder, mana: Short) = builder.addShort(1, mana, 150)
+        fun addHp(builder: FlatBufferBuilder, hp: Short) = builder.addShort(2, hp, 100)
+        fun addName(builder: FlatBufferBuilder, name: Int) = builder.addOffset(3, name, 0)
+        fun addInventory(builder: FlatBufferBuilder, inventory: Int) = builder.addOffset(5, inventory, 0)
+        fun createInventoryVector(builder: FlatBufferBuilder, data: UByteArray) : Int {
+            builder.startVector(1, data.size, 1)
+            for (i in data.size - 1 downTo 0) {
+                builder.addByte(data[i].toByte())
+            }
+            return builder.endVector()
+        }
+        fun startInventoryVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(1, numElems, 1)
+        fun addColor(builder: FlatBufferBuilder, color: UByte) = builder.addByte(6, color.toByte(), 8)
+        fun addTestType(builder: FlatBufferBuilder, testType: UByte) = builder.addByte(7, testType.toByte(), 0)
+        fun addTest(builder: FlatBufferBuilder, test: Int) = builder.addOffset(8, test, 0)
+        fun addTest4(builder: FlatBufferBuilder, test4: Int) = builder.addOffset(9, test4, 0)
+        fun startTest4Vector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 2)
+        fun addTestarrayofstring(builder: FlatBufferBuilder, testarrayofstring: Int) = builder.addOffset(10, testarrayofstring, 0)
+        fun createTestarrayofstringVector(builder: FlatBufferBuilder, data: IntArray) : Int {
+            builder.startVector(4, data.size, 4)
+            for (i in data.size - 1 downTo 0) {
+                builder.addOffset(data[i])
+            }
+            return builder.endVector()
+        }
+        fun startTestarrayofstringVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 4)
+        fun addTestarrayoftables(builder: FlatBufferBuilder, testarrayoftables: Int) = builder.addOffset(11, testarrayoftables, 0)
+        fun createTestarrayoftablesVector(builder: FlatBufferBuilder, data: IntArray) : Int {
+            builder.startVector(4, data.size, 4)
+            for (i in data.size - 1 downTo 0) {
+                builder.addOffset(data[i])
+            }
+            return builder.endVector()
+        }
+        fun startTestarrayoftablesVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 4)
+        fun addEnemy(builder: FlatBufferBuilder, enemy: Int) = builder.addOffset(12, enemy, 0)
+        fun addTestnestedflatbuffer(builder: FlatBufferBuilder, testnestedflatbuffer: Int) = builder.addOffset(13, testnestedflatbuffer, 0)
+        fun createTestnestedflatbufferVector(builder: FlatBufferBuilder, data: UByteArray) : Int {
+            builder.startVector(1, data.size, 1)
+            for (i in data.size - 1 downTo 0) {
+                builder.addByte(data[i].toByte())
+            }
+            return builder.endVector()
+        }
+        fun startTestnestedflatbufferVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(1, numElems, 1)
+        fun addTestempty(builder: FlatBufferBuilder, testempty: Int) = builder.addOffset(14, testempty, 0)
+        fun addTestbool(builder: FlatBufferBuilder, testbool: Boolean) = builder.addBoolean(15, testbool, false)
+        fun addTesthashs32Fnv1(builder: FlatBufferBuilder, testhashs32Fnv1: Int) = builder.addInt(16, testhashs32Fnv1, 0)
+        fun addTesthashu32Fnv1(builder: FlatBufferBuilder, testhashu32Fnv1: UInt) = builder.addInt(17, testhashu32Fnv1.toInt(), 0)
+        fun addTesthashs64Fnv1(builder: FlatBufferBuilder, testhashs64Fnv1: Long) = builder.addLong(18, testhashs64Fnv1, 0L)
+        fun addTesthashu64Fnv1(builder: FlatBufferBuilder, testhashu64Fnv1: ULong) = builder.addLong(19, testhashu64Fnv1.toLong(), 0)
+        fun addTesthashs32Fnv1a(builder: FlatBufferBuilder, testhashs32Fnv1a: Int) = builder.addInt(20, testhashs32Fnv1a, 0)
+        fun addTesthashu32Fnv1a(builder: FlatBufferBuilder, testhashu32Fnv1a: UInt) = builder.addInt(21, testhashu32Fnv1a.toInt(), 0)
+        fun addTesthashs64Fnv1a(builder: FlatBufferBuilder, testhashs64Fnv1a: Long) = builder.addLong(22, testhashs64Fnv1a, 0L)
+        fun addTesthashu64Fnv1a(builder: FlatBufferBuilder, testhashu64Fnv1a: ULong) = builder.addLong(23, testhashu64Fnv1a.toLong(), 0)
+        fun addTestarrayofbools(builder: FlatBufferBuilder, testarrayofbools: Int) = builder.addOffset(24, testarrayofbools, 0)
+        fun createTestarrayofboolsVector(builder: FlatBufferBuilder, data: BooleanArray) : Int {
+            builder.startVector(1, data.size, 1)
+            for (i in data.size - 1 downTo 0) {
+                builder.addBoolean(data[i])
+            }
+            return builder.endVector()
+        }
+        fun startTestarrayofboolsVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(1, numElems, 1)
+        fun addTestf(builder: FlatBufferBuilder, testf: Float) = builder.addFloat(25, testf, 3.14159)
+        fun addTestf2(builder: FlatBufferBuilder, testf2: Float) = builder.addFloat(26, testf2, 3.0)
+        fun addTestf3(builder: FlatBufferBuilder, testf3: Float) = builder.addFloat(27, testf3, 0.0)
+        fun addTestarrayofstring2(builder: FlatBufferBuilder, testarrayofstring2: Int) = builder.addOffset(28, testarrayofstring2, 0)
+        fun createTestarrayofstring2Vector(builder: FlatBufferBuilder, data: IntArray) : Int {
+            builder.startVector(4, data.size, 4)
+            for (i in data.size - 1 downTo 0) {
+                builder.addOffset(data[i])
+            }
+            return builder.endVector()
+        }
+        fun startTestarrayofstring2Vector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 4)
+        fun addTestarrayofsortedstruct(builder: FlatBufferBuilder, testarrayofsortedstruct: Int) = builder.addOffset(29, testarrayofsortedstruct, 0)
+        fun startTestarrayofsortedstructVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(8, numElems, 4)
+        fun addFlex(builder: FlatBufferBuilder, flex: Int) = builder.addOffset(30, flex, 0)
+        fun createFlexVector(builder: FlatBufferBuilder, data: UByteArray) : Int {
+            builder.startVector(1, data.size, 1)
+            for (i in data.size - 1 downTo 0) {
+                builder.addByte(data[i].toByte())
+            }
+            return builder.endVector()
+        }
+        fun startFlexVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(1, numElems, 1)
+        fun addTest5(builder: FlatBufferBuilder, test5: Int) = builder.addOffset(31, test5, 0)
+        fun startTest5Vector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 2)
+        fun addVectorOfLongs(builder: FlatBufferBuilder, vectorOfLongs: Int) = builder.addOffset(32, vectorOfLongs, 0)
+        fun createVectorOfLongsVector(builder: FlatBufferBuilder, data: LongArray) : Int {
+            builder.startVector(8, data.size, 8)
+            for (i in data.size - 1 downTo 0) {
+                builder.addLong(data[i])
+            }
+            return builder.endVector()
+        }
+        fun startVectorOfLongsVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(8, numElems, 8)
+        fun addVectorOfDoubles(builder: FlatBufferBuilder, vectorOfDoubles: Int) = builder.addOffset(33, vectorOfDoubles, 0)
+        fun createVectorOfDoublesVector(builder: FlatBufferBuilder, data: DoubleArray) : Int {
+            builder.startVector(8, data.size, 8)
+            for (i in data.size - 1 downTo 0) {
+                builder.addDouble(data[i])
+            }
+            return builder.endVector()
+        }
+        fun startVectorOfDoublesVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(8, numElems, 8)
+        fun addParentNamespaceTest(builder: FlatBufferBuilder, parentNamespaceTest: Int) = builder.addOffset(34, parentNamespaceTest, 0)
+        fun addVectorOfReferrables(builder: FlatBufferBuilder, vectorOfReferrables: Int) = builder.addOffset(35, vectorOfReferrables, 0)
+        fun createVectorOfReferrablesVector(builder: FlatBufferBuilder, data: IntArray) : Int {
+            builder.startVector(4, data.size, 4)
+            for (i in data.size - 1 downTo 0) {
+                builder.addOffset(data[i])
+            }
+            return builder.endVector()
+        }
+        fun startVectorOfReferrablesVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 4)
+        fun addSingleWeakReference(builder: FlatBufferBuilder, singleWeakReference: ULong) = builder.addLong(36, singleWeakReference.toLong(), 0)
+        fun addVectorOfWeakReferences(builder: FlatBufferBuilder, vectorOfWeakReferences: Int) = builder.addOffset(37, vectorOfWeakReferences, 0)
+        fun createVectorOfWeakReferencesVector(builder: FlatBufferBuilder, data: ULongArray) : Int {
+            builder.startVector(8, data.size, 8)
+            for (i in data.size - 1 downTo 0) {
+                builder.addLong(data[i].toLong())
+            }
+            return builder.endVector()
+        }
+        fun startVectorOfWeakReferencesVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(8, numElems, 8)
+        fun addVectorOfStrongReferrables(builder: FlatBufferBuilder, vectorOfStrongReferrables: Int) = builder.addOffset(38, vectorOfStrongReferrables, 0)
+        fun createVectorOfStrongReferrablesVector(builder: FlatBufferBuilder, data: IntArray) : Int {
+            builder.startVector(4, data.size, 4)
+            for (i in data.size - 1 downTo 0) {
+                builder.addOffset(data[i])
+            }
+            return builder.endVector()
+        }
+        fun startVectorOfStrongReferrablesVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 4)
+        fun addCoOwningReference(builder: FlatBufferBuilder, coOwningReference: ULong) = builder.addLong(39, coOwningReference.toLong(), 0)
+        fun addVectorOfCoOwningReferences(builder: FlatBufferBuilder, vectorOfCoOwningReferences: Int) = builder.addOffset(40, vectorOfCoOwningReferences, 0)
+        fun createVectorOfCoOwningReferencesVector(builder: FlatBufferBuilder, data: ULongArray) : Int {
+            builder.startVector(8, data.size, 8)
+            for (i in data.size - 1 downTo 0) {
+                builder.addLong(data[i].toLong())
+            }
+            return builder.endVector()
+        }
+        fun startVectorOfCoOwningReferencesVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(8, numElems, 8)
+        fun addNonOwningReference(builder: FlatBufferBuilder, nonOwningReference: ULong) = builder.addLong(41, nonOwningReference.toLong(), 0)
+        fun addVectorOfNonOwningReferences(builder: FlatBufferBuilder, vectorOfNonOwningReferences: Int) = builder.addOffset(42, vectorOfNonOwningReferences, 0)
+        fun createVectorOfNonOwningReferencesVector(builder: FlatBufferBuilder, data: ULongArray) : Int {
+            builder.startVector(8, data.size, 8)
+            for (i in data.size - 1 downTo 0) {
+                builder.addLong(data[i].toLong())
+            }
+            return builder.endVector()
+        }
+        fun startVectorOfNonOwningReferencesVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(8, numElems, 8)
+        fun addAnyUniqueType(builder: FlatBufferBuilder, anyUniqueType: UByte) = builder.addByte(43, anyUniqueType.toByte(), 0)
+        fun addAnyUnique(builder: FlatBufferBuilder, anyUnique: Int) = builder.addOffset(44, anyUnique, 0)
+        fun addAnyAmbiguousType(builder: FlatBufferBuilder, anyAmbiguousType: UByte) = builder.addByte(45, anyAmbiguousType.toByte(), 0)
+        fun addAnyAmbiguous(builder: FlatBufferBuilder, anyAmbiguous: Int) = builder.addOffset(46, anyAmbiguous, 0)
+        fun addVectorOfEnums(builder: FlatBufferBuilder, vectorOfEnums: Int) = builder.addOffset(47, vectorOfEnums, 0)
+        fun createVectorOfEnumsVector(builder: FlatBufferBuilder, data: UByteArray) : Int {
+            builder.startVector(1, data.size, 1)
+            for (i in data.size - 1 downTo 0) {
+                builder.addByte(data[i].toByte())
+            }
+            return builder.endVector()
+        }
+        fun startVectorOfEnumsVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(1, numElems, 1)
+        fun endMonster(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+                builder.required(o, 10)
+            return o
+        }
+        fun finishMonsterBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finish(offset, "MONS")
+        fun finishSizePrefixedMonsterBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finishSizePrefixed(offset, "MONS")
+        fun __lookup_by_key(obj: Monster?, vectorLocation: Int, key: String, bb: ByteBuffer) : Monster? {
+            val byteKey = key.toByteArray(Table.UTF8_CHARSET.get()!!)
+            var span = bb.getInt(vectorLocation - 4)
+            var start = 0
+            while (span != 0) {
+                var middle = span / 2
+                val tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb)
+                val comp = compareStrings(__offset(10, bb.capacity() - tableOffset, bb), byteKey, bb)
+                when {
+                    comp > 0 -> span = middle
+                    comp < 0 -> {
+                        middle++
+                        start += middle
+                        span -= middle
+                    }
+                    else -> {
+                        return (obj ?: Monster()).__assign(tableOffset, bb)
+                    }
+                }
+            }
+            return null
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Monster.lua b/third_party/flatbuffers/tests/MyGame/Example/Monster.lua
new file mode 100644
index 0000000..130c903
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Monster.lua
@@ -0,0 +1,593 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Example
+
+local flatbuffers = require('flatbuffers')
+
+-- an example documentation comment: monster object
+local Monster = {} -- the module
+local Monster_mt = {} -- the class metatable
+
+function Monster.New()
+    local o = {}
+    setmetatable(o, {__index = Monster_mt})
+    return o
+end
+function Monster.GetRootAsMonster(buf, offset)
+    local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)
+    local o = Monster.New()
+    o:Init(buf, n + offset)
+    return o
+end
+function Monster_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function Monster_mt:Pos()
+    local o = self.view:Offset(4)
+    if o ~= 0 then
+        local x = o + self.view.pos
+        local obj = require('MyGame.Example.Vec3').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function Monster_mt:Mana()
+    local o = self.view:Offset(6)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int16, o + self.view.pos)
+    end
+    return 150
+end
+function Monster_mt:Hp()
+    local o = self.view:Offset(8)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int16, o + self.view.pos)
+    end
+    return 100
+end
+function Monster_mt:Name()
+    local o = self.view:Offset(10)
+    if o ~= 0 then
+        return self.view:String(o + self.view.pos)
+    end
+end
+function Monster_mt:Inventory(j)
+    local o = self.view:Offset(14)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:Get(flatbuffers.N.Uint8, a + ((j-1) * 1))
+    end
+    return 0
+end
+function Monster_mt:InventoryLength()
+    local o = self.view:Offset(14)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:Color()
+    local o = self.view:Offset(16)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint8, o + self.view.pos)
+    end
+    return 8
+end
+function Monster_mt:TestType()
+    local o = self.view:Offset(18)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint8, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:Test()
+    local o = self.view:Offset(20)
+    if o ~= 0 then
+        local obj = flatbuffers.view.New(require('flatbuffers.binaryarray').New(0), 0)
+        self.view:Union(obj, o)
+        return obj
+    end
+end
+function Monster_mt:Test4(j)
+    local o = self.view:Offset(22)
+    if o ~= 0 then
+        local x = self.view:Vector(o)
+        x = x + ((j-1) * 4)
+        local obj = require('MyGame.Example.Test').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function Monster_mt:Test4Length()
+    local o = self.view:Offset(22)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:Testarrayofstring(j)
+    local o = self.view:Offset(24)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:String(a + ((j-1) * 4))
+    end
+    return ''
+end
+function Monster_mt:TestarrayofstringLength()
+    local o = self.view:Offset(24)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+-- an example documentation comment: this will end up in the generated code
+-- multiline too
+function Monster_mt:Testarrayoftables(j)
+    local o = self.view:Offset(26)
+    if o ~= 0 then
+        local x = self.view:Vector(o)
+        x = x + ((j-1) * 4)
+        x = self.view:Indirect(x)
+        local obj = require('MyGame.Example.Monster').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function Monster_mt:TestarrayoftablesLength()
+    local o = self.view:Offset(26)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:Enemy()
+    local o = self.view:Offset(28)
+    if o ~= 0 then
+        local x = self.view:Indirect(o + self.view.pos)
+        local obj = require('MyGame.Example.Monster').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function Monster_mt:Testnestedflatbuffer(j)
+    local o = self.view:Offset(30)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:Get(flatbuffers.N.Uint8, a + ((j-1) * 1))
+    end
+    return 0
+end
+function Monster_mt:TestnestedflatbufferLength()
+    local o = self.view:Offset(30)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:Testempty()
+    local o = self.view:Offset(32)
+    if o ~= 0 then
+        local x = self.view:Indirect(o + self.view.pos)
+        local obj = require('MyGame.Example.Stat').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function Monster_mt:Testbool()
+    local o = self.view:Offset(34)
+    if o ~= 0 then
+        return (self.view:Get(flatbuffers.N.Bool, o + self.view.pos) ~= 0)
+    end
+    return false
+end
+function Monster_mt:Testhashs32Fnv1()
+    local o = self.view:Offset(36)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int32, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:Testhashu32Fnv1()
+    local o = self.view:Offset(38)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint32, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:Testhashs64Fnv1()
+    local o = self.view:Offset(40)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int64, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:Testhashu64Fnv1()
+    local o = self.view:Offset(42)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint64, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:Testhashs32Fnv1a()
+    local o = self.view:Offset(44)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int32, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:Testhashu32Fnv1a()
+    local o = self.view:Offset(46)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint32, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:Testhashs64Fnv1a()
+    local o = self.view:Offset(48)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int64, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:Testhashu64Fnv1a()
+    local o = self.view:Offset(50)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint64, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:Testarrayofbools(j)
+    local o = self.view:Offset(52)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:Get(flatbuffers.N.Bool, a + ((j-1) * 1))
+    end
+    return 0
+end
+function Monster_mt:TestarrayofboolsLength()
+    local o = self.view:Offset(52)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:Testf()
+    local o = self.view:Offset(54)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Float32, o + self.view.pos)
+    end
+    return 3.14159
+end
+function Monster_mt:Testf2()
+    local o = self.view:Offset(56)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Float32, o + self.view.pos)
+    end
+    return 3.0
+end
+function Monster_mt:Testf3()
+    local o = self.view:Offset(58)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Float32, o + self.view.pos)
+    end
+    return 0.0
+end
+function Monster_mt:Testarrayofstring2(j)
+    local o = self.view:Offset(60)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:String(a + ((j-1) * 4))
+    end
+    return ''
+end
+function Monster_mt:Testarrayofstring2Length()
+    local o = self.view:Offset(60)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:Testarrayofsortedstruct(j)
+    local o = self.view:Offset(62)
+    if o ~= 0 then
+        local x = self.view:Vector(o)
+        x = x + ((j-1) * 8)
+        local obj = require('MyGame.Example.Ability').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function Monster_mt:TestarrayofsortedstructLength()
+    local o = self.view:Offset(62)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:Flex(j)
+    local o = self.view:Offset(64)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:Get(flatbuffers.N.Uint8, a + ((j-1) * 1))
+    end
+    return 0
+end
+function Monster_mt:FlexLength()
+    local o = self.view:Offset(64)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:Test5(j)
+    local o = self.view:Offset(66)
+    if o ~= 0 then
+        local x = self.view:Vector(o)
+        x = x + ((j-1) * 4)
+        local obj = require('MyGame.Example.Test').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function Monster_mt:Test5Length()
+    local o = self.view:Offset(66)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:VectorOfLongs(j)
+    local o = self.view:Offset(68)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:Get(flatbuffers.N.Int64, a + ((j-1) * 8))
+    end
+    return 0
+end
+function Monster_mt:VectorOfLongsLength()
+    local o = self.view:Offset(68)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:VectorOfDoubles(j)
+    local o = self.view:Offset(70)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:Get(flatbuffers.N.Float64, a + ((j-1) * 8))
+    end
+    return 0
+end
+function Monster_mt:VectorOfDoublesLength()
+    local o = self.view:Offset(70)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:ParentNamespaceTest()
+    local o = self.view:Offset(72)
+    if o ~= 0 then
+        local x = self.view:Indirect(o + self.view.pos)
+        local obj = require('MyGame.InParentNamespace').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function Monster_mt:VectorOfReferrables(j)
+    local o = self.view:Offset(74)
+    if o ~= 0 then
+        local x = self.view:Vector(o)
+        x = x + ((j-1) * 4)
+        x = self.view:Indirect(x)
+        local obj = require('MyGame.Example.Referrable').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function Monster_mt:VectorOfReferrablesLength()
+    local o = self.view:Offset(74)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:SingleWeakReference()
+    local o = self.view:Offset(76)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint64, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:VectorOfWeakReferences(j)
+    local o = self.view:Offset(78)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:Get(flatbuffers.N.Uint64, a + ((j-1) * 8))
+    end
+    return 0
+end
+function Monster_mt:VectorOfWeakReferencesLength()
+    local o = self.view:Offset(78)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:VectorOfStrongReferrables(j)
+    local o = self.view:Offset(80)
+    if o ~= 0 then
+        local x = self.view:Vector(o)
+        x = x + ((j-1) * 4)
+        x = self.view:Indirect(x)
+        local obj = require('MyGame.Example.Referrable').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function Monster_mt:VectorOfStrongReferrablesLength()
+    local o = self.view:Offset(80)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:CoOwningReference()
+    local o = self.view:Offset(82)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint64, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:VectorOfCoOwningReferences(j)
+    local o = self.view:Offset(84)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:Get(flatbuffers.N.Uint64, a + ((j-1) * 8))
+    end
+    return 0
+end
+function Monster_mt:VectorOfCoOwningReferencesLength()
+    local o = self.view:Offset(84)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:NonOwningReference()
+    local o = self.view:Offset(86)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint64, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:VectorOfNonOwningReferences(j)
+    local o = self.view:Offset(88)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:Get(flatbuffers.N.Uint64, a + ((j-1) * 8))
+    end
+    return 0
+end
+function Monster_mt:VectorOfNonOwningReferencesLength()
+    local o = self.view:Offset(88)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster_mt:AnyUniqueType()
+    local o = self.view:Offset(90)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint8, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:AnyUnique()
+    local o = self.view:Offset(92)
+    if o ~= 0 then
+        local obj = flatbuffers.view.New(require('flatbuffers.binaryarray').New(0), 0)
+        self.view:Union(obj, o)
+        return obj
+    end
+end
+function Monster_mt:AnyAmbiguousType()
+    local o = self.view:Offset(94)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint8, o + self.view.pos)
+    end
+    return 0
+end
+function Monster_mt:AnyAmbiguous()
+    local o = self.view:Offset(96)
+    if o ~= 0 then
+        local obj = flatbuffers.view.New(require('flatbuffers.binaryarray').New(0), 0)
+        self.view:Union(obj, o)
+        return obj
+    end
+end
+function Monster_mt:VectorOfEnums(j)
+    local o = self.view:Offset(98)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:Get(flatbuffers.N.Uint8, a + ((j-1) * 1))
+    end
+    return 0
+end
+function Monster_mt:VectorOfEnumsLength()
+    local o = self.view:Offset(98)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function Monster.Start(builder) builder:StartObject(48) end
+function Monster.AddPos(builder, pos) builder:PrependStructSlot(0, pos, 0) end
+function Monster.AddMana(builder, mana) builder:PrependInt16Slot(1, mana, 150) end
+function Monster.AddHp(builder, hp) builder:PrependInt16Slot(2, hp, 100) end
+function Monster.AddName(builder, name) builder:PrependUOffsetTRelativeSlot(3, name, 0) end
+function Monster.AddInventory(builder, inventory) builder:PrependUOffsetTRelativeSlot(5, inventory, 0) end
+function Monster.StartInventoryVector(builder, numElems) return builder:StartVector(1, numElems, 1) end
+function Monster.AddColor(builder, color) builder:PrependUint8Slot(6, color, 8) end
+function Monster.AddTestType(builder, testType) builder:PrependUint8Slot(7, testType, 0) end
+function Monster.AddTest(builder, test) builder:PrependUOffsetTRelativeSlot(8, test, 0) end
+function Monster.AddTest4(builder, test4) builder:PrependUOffsetTRelativeSlot(9, test4, 0) end
+function Monster.StartTest4Vector(builder, numElems) return builder:StartVector(4, numElems, 2) end
+function Monster.AddTestarrayofstring(builder, testarrayofstring) builder:PrependUOffsetTRelativeSlot(10, testarrayofstring, 0) end
+function Monster.StartTestarrayofstringVector(builder, numElems) return builder:StartVector(4, numElems, 4) end
+function Monster.AddTestarrayoftables(builder, testarrayoftables) builder:PrependUOffsetTRelativeSlot(11, testarrayoftables, 0) end
+function Monster.StartTestarrayoftablesVector(builder, numElems) return builder:StartVector(4, numElems, 4) end
+function Monster.AddEnemy(builder, enemy) builder:PrependUOffsetTRelativeSlot(12, enemy, 0) end
+function Monster.AddTestnestedflatbuffer(builder, testnestedflatbuffer) builder:PrependUOffsetTRelativeSlot(13, testnestedflatbuffer, 0) end
+function Monster.StartTestnestedflatbufferVector(builder, numElems) return builder:StartVector(1, numElems, 1) end
+function Monster.AddTestempty(builder, testempty) builder:PrependUOffsetTRelativeSlot(14, testempty, 0) end
+function Monster.AddTestbool(builder, testbool) builder:PrependBoolSlot(15, testbool, 0) end
+function Monster.AddTesthashs32Fnv1(builder, testhashs32Fnv1) builder:PrependInt32Slot(16, testhashs32Fnv1, 0) end
+function Monster.AddTesthashu32Fnv1(builder, testhashu32Fnv1) builder:PrependUint32Slot(17, testhashu32Fnv1, 0) end
+function Monster.AddTesthashs64Fnv1(builder, testhashs64Fnv1) builder:PrependInt64Slot(18, testhashs64Fnv1, 0) end
+function Monster.AddTesthashu64Fnv1(builder, testhashu64Fnv1) builder:PrependUint64Slot(19, testhashu64Fnv1, 0) end
+function Monster.AddTesthashs32Fnv1a(builder, testhashs32Fnv1a) builder:PrependInt32Slot(20, testhashs32Fnv1a, 0) end
+function Monster.AddTesthashu32Fnv1a(builder, testhashu32Fnv1a) builder:PrependUint32Slot(21, testhashu32Fnv1a, 0) end
+function Monster.AddTesthashs64Fnv1a(builder, testhashs64Fnv1a) builder:PrependInt64Slot(22, testhashs64Fnv1a, 0) end
+function Monster.AddTesthashu64Fnv1a(builder, testhashu64Fnv1a) builder:PrependUint64Slot(23, testhashu64Fnv1a, 0) end
+function Monster.AddTestarrayofbools(builder, testarrayofbools) builder:PrependUOffsetTRelativeSlot(24, testarrayofbools, 0) end
+function Monster.StartTestarrayofboolsVector(builder, numElems) return builder:StartVector(1, numElems, 1) end
+function Monster.AddTestf(builder, testf) builder:PrependFloat32Slot(25, testf, 3.14159) end
+function Monster.AddTestf2(builder, testf2) builder:PrependFloat32Slot(26, testf2, 3.0) end
+function Monster.AddTestf3(builder, testf3) builder:PrependFloat32Slot(27, testf3, 0.0) end
+function Monster.AddTestarrayofstring2(builder, testarrayofstring2) builder:PrependUOffsetTRelativeSlot(28, testarrayofstring2, 0) end
+function Monster.StartTestarrayofstring2Vector(builder, numElems) return builder:StartVector(4, numElems, 4) end
+function Monster.AddTestarrayofsortedstruct(builder, testarrayofsortedstruct) builder:PrependUOffsetTRelativeSlot(29, testarrayofsortedstruct, 0) end
+function Monster.StartTestarrayofsortedstructVector(builder, numElems) return builder:StartVector(8, numElems, 4) end
+function Monster.AddFlex(builder, flex) builder:PrependUOffsetTRelativeSlot(30, flex, 0) end
+function Monster.StartFlexVector(builder, numElems) return builder:StartVector(1, numElems, 1) end
+function Monster.AddTest5(builder, test5) builder:PrependUOffsetTRelativeSlot(31, test5, 0) end
+function Monster.StartTest5Vector(builder, numElems) return builder:StartVector(4, numElems, 2) end
+function Monster.AddVectorOfLongs(builder, vectorOfLongs) builder:PrependUOffsetTRelativeSlot(32, vectorOfLongs, 0) end
+function Monster.StartVectorOfLongsVector(builder, numElems) return builder:StartVector(8, numElems, 8) end
+function Monster.AddVectorOfDoubles(builder, vectorOfDoubles) builder:PrependUOffsetTRelativeSlot(33, vectorOfDoubles, 0) end
+function Monster.StartVectorOfDoublesVector(builder, numElems) return builder:StartVector(8, numElems, 8) end
+function Monster.AddParentNamespaceTest(builder, parentNamespaceTest) builder:PrependUOffsetTRelativeSlot(34, parentNamespaceTest, 0) end
+function Monster.AddVectorOfReferrables(builder, vectorOfReferrables) builder:PrependUOffsetTRelativeSlot(35, vectorOfReferrables, 0) end
+function Monster.StartVectorOfReferrablesVector(builder, numElems) return builder:StartVector(4, numElems, 4) end
+function Monster.AddSingleWeakReference(builder, singleWeakReference) builder:PrependUint64Slot(36, singleWeakReference, 0) end
+function Monster.AddVectorOfWeakReferences(builder, vectorOfWeakReferences) builder:PrependUOffsetTRelativeSlot(37, vectorOfWeakReferences, 0) end
+function Monster.StartVectorOfWeakReferencesVector(builder, numElems) return builder:StartVector(8, numElems, 8) end
+function Monster.AddVectorOfStrongReferrables(builder, vectorOfStrongReferrables) builder:PrependUOffsetTRelativeSlot(38, vectorOfStrongReferrables, 0) end
+function Monster.StartVectorOfStrongReferrablesVector(builder, numElems) return builder:StartVector(4, numElems, 4) end
+function Monster.AddCoOwningReference(builder, coOwningReference) builder:PrependUint64Slot(39, coOwningReference, 0) end
+function Monster.AddVectorOfCoOwningReferences(builder, vectorOfCoOwningReferences) builder:PrependUOffsetTRelativeSlot(40, vectorOfCoOwningReferences, 0) end
+function Monster.StartVectorOfCoOwningReferencesVector(builder, numElems) return builder:StartVector(8, numElems, 8) end
+function Monster.AddNonOwningReference(builder, nonOwningReference) builder:PrependUint64Slot(41, nonOwningReference, 0) end
+function Monster.AddVectorOfNonOwningReferences(builder, vectorOfNonOwningReferences) builder:PrependUOffsetTRelativeSlot(42, vectorOfNonOwningReferences, 0) end
+function Monster.StartVectorOfNonOwningReferencesVector(builder, numElems) return builder:StartVector(8, numElems, 8) end
+function Monster.AddAnyUniqueType(builder, anyUniqueType) builder:PrependUint8Slot(43, anyUniqueType, 0) end
+function Monster.AddAnyUnique(builder, anyUnique) builder:PrependUOffsetTRelativeSlot(44, anyUnique, 0) end
+function Monster.AddAnyAmbiguousType(builder, anyAmbiguousType) builder:PrependUint8Slot(45, anyAmbiguousType, 0) end
+function Monster.AddAnyAmbiguous(builder, anyAmbiguous) builder:PrependUOffsetTRelativeSlot(46, anyAmbiguous, 0) end
+function Monster.AddVectorOfEnums(builder, vectorOfEnums) builder:PrependUOffsetTRelativeSlot(47, vectorOfEnums, 0) end
+function Monster.StartVectorOfEnumsVector(builder, numElems) return builder:StartVector(1, numElems, 1) end
+function Monster.End(builder) return builder:EndObject() end
+
+return Monster -- return the module
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Monster.php b/third_party/flatbuffers/tests/MyGame/Example/Monster.php
new file mode 100644
index 0000000..7d6de87b
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Monster.php
@@ -0,0 +1,1647 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame\Example;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+/// an example documentation comment: monster object
+class Monster extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return Monster
+     */
+    public static function getRootAsMonster(ByteBuffer $bb)
+    {
+        $obj = new Monster();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    public static function MonsterIdentifier()
+    {
+        return "MONS";
+    }
+
+    public static function MonsterBufferHasIdentifier(ByteBuffer $buf)
+    {
+        return self::__has_identifier($buf, self::MonsterIdentifier());
+    }
+
+    public static function MonsterExtension()
+    {
+        return "mon";
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return Monster
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    public function getPos()
+    {
+        $obj = new Vec3();
+        $o = $this->__offset(4);
+        return $o != 0 ? $obj->init($o + $this->bb_pos, $this->bb) : 0;
+    }
+
+    /**
+     * @return short
+     */
+    public function getMana()
+    {
+        $o = $this->__offset(6);
+        return $o != 0 ? $this->bb->getShort($o + $this->bb_pos) : 150;
+    }
+
+    /**
+     * @return short
+     */
+    public function getHp()
+    {
+        $o = $this->__offset(8);
+        return $o != 0 ? $this->bb->getShort($o + $this->bb_pos) : 100;
+    }
+
+    public function getName()
+    {
+        $o = $this->__offset(10);
+        return $o != 0 ? $this->__string($o + $this->bb_pos) : null;
+    }
+
+    /**
+     * @param int offset
+     * @return byte
+     */
+    public function getInventory($j)
+    {
+        $o = $this->__offset(14);
+        return $o != 0 ? $this->bb->getByte($this->__vector($o) + $j * 1) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getInventoryLength()
+    {
+        $o = $this->__offset(14);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @return string
+     */
+    public function getInventoryBytes()
+    {
+        return $this->__vector_as_bytes(14);
+    }
+
+    /**
+     * @return byte
+     */
+    public function getColor()
+    {
+        $o = $this->__offset(16);
+        return $o != 0 ? $this->bb->getByte($o + $this->bb_pos) : \MyGame\Example\Color::Blue;
+    }
+
+    /**
+     * @return byte
+     */
+    public function getTestType()
+    {
+        $o = $this->__offset(18);
+        return $o != 0 ? $this->bb->getByte($o + $this->bb_pos) : \MyGame\Example\Any::NONE;
+    }
+
+    /**
+     * @returnint
+     */
+    public function getTest($obj)
+    {
+        $o = $this->__offset(20);
+        return $o != 0 ? $this->__union($obj, $o) : null;
+    }
+
+    /**
+     * @returnVectorOffset
+     */
+    public function getTest4($j)
+    {
+        $o = $this->__offset(22);
+        $obj = new Test();
+        return $o != 0 ? $obj->init($this->__vector($o) + $j *4, $this->bb) : null;
+    }
+
+    /**
+     * @return int
+     */
+    public function getTest4Length()
+    {
+        $o = $this->__offset(22);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @param int offset
+     * @return string
+     */
+    public function getTestarrayofstring($j)
+    {
+        $o = $this->__offset(24);
+        return $o != 0 ? $this->__string($this->__vector($o) + $j * 4) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getTestarrayofstringLength()
+    {
+        $o = $this->__offset(24);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /// an example documentation comment: this will end up in the generated code
+    /// multiline too
+    /**
+     * @returnVectorOffset
+     */
+    public function getTestarrayoftables($j)
+    {
+        $o = $this->__offset(26);
+        $obj = new Monster();
+        return $o != 0 ? $obj->init($this->__indirect($this->__vector($o) + $j * 4), $this->bb) : null;
+    }
+
+    /**
+     * @return int
+     */
+    public function getTestarrayoftablesLength()
+    {
+        $o = $this->__offset(26);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    public function getEnemy()
+    {
+        $obj = new Monster();
+        $o = $this->__offset(28);
+        return $o != 0 ? $obj->init($this->__indirect($o + $this->bb_pos), $this->bb) : 0;
+    }
+
+    /**
+     * @param int offset
+     * @return byte
+     */
+    public function getTestnestedflatbuffer($j)
+    {
+        $o = $this->__offset(30);
+        return $o != 0 ? $this->bb->getByte($this->__vector($o) + $j * 1) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getTestnestedflatbufferLength()
+    {
+        $o = $this->__offset(30);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @return string
+     */
+    public function getTestnestedflatbufferBytes()
+    {
+        return $this->__vector_as_bytes(30);
+    }
+
+    public function getTestempty()
+    {
+        $obj = new Stat();
+        $o = $this->__offset(32);
+        return $o != 0 ? $obj->init($this->__indirect($o + $this->bb_pos), $this->bb) : 0;
+    }
+
+    /**
+     * @return bool
+     */
+    public function getTestbool()
+    {
+        $o = $this->__offset(34);
+        return $o != 0 ? $this->bb->getBool($o + $this->bb_pos) : false;
+    }
+
+    /**
+     * @return int
+     */
+    public function getTesthashs32Fnv1()
+    {
+        $o = $this->__offset(36);
+        return $o != 0 ? $this->bb->getInt($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return uint
+     */
+    public function getTesthashu32Fnv1()
+    {
+        $o = $this->__offset(38);
+        return $o != 0 ? $this->bb->getUint($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return long
+     */
+    public function getTesthashs64Fnv1()
+    {
+        $o = $this->__offset(40);
+        return $o != 0 ? $this->bb->getLong($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return ulong
+     */
+    public function getTesthashu64Fnv1()
+    {
+        $o = $this->__offset(42);
+        return $o != 0 ? $this->bb->getUlong($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getTesthashs32Fnv1a()
+    {
+        $o = $this->__offset(44);
+        return $o != 0 ? $this->bb->getInt($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return uint
+     */
+    public function getTesthashu32Fnv1a()
+    {
+        $o = $this->__offset(46);
+        return $o != 0 ? $this->bb->getUint($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return long
+     */
+    public function getTesthashs64Fnv1a()
+    {
+        $o = $this->__offset(48);
+        return $o != 0 ? $this->bb->getLong($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return ulong
+     */
+    public function getTesthashu64Fnv1a()
+    {
+        $o = $this->__offset(50);
+        return $o != 0 ? $this->bb->getUlong($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @param int offset
+     * @return bool
+     */
+    public function getTestarrayofbools($j)
+    {
+        $o = $this->__offset(52);
+        return $o != 0 ? $this->bb->getBool($this->__vector($o) + $j * 1) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getTestarrayofboolsLength()
+    {
+        $o = $this->__offset(52);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @return float
+     */
+    public function getTestf()
+    {
+        $o = $this->__offset(54);
+        return $o != 0 ? $this->bb->getFloat($o + $this->bb_pos) : 3.14159;
+    }
+
+    /**
+     * @return float
+     */
+    public function getTestf2()
+    {
+        $o = $this->__offset(56);
+        return $o != 0 ? $this->bb->getFloat($o + $this->bb_pos) : 3.0;
+    }
+
+    /**
+     * @return float
+     */
+    public function getTestf3()
+    {
+        $o = $this->__offset(58);
+        return $o != 0 ? $this->bb->getFloat($o + $this->bb_pos) : 0.0;
+    }
+
+    /**
+     * @param int offset
+     * @return string
+     */
+    public function getTestarrayofstring2($j)
+    {
+        $o = $this->__offset(60);
+        return $o != 0 ? $this->__string($this->__vector($o) + $j * 4) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getTestarrayofstring2Length()
+    {
+        $o = $this->__offset(60);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @returnVectorOffset
+     */
+    public function getTestarrayofsortedstruct($j)
+    {
+        $o = $this->__offset(62);
+        $obj = new Ability();
+        return $o != 0 ? $obj->init($this->__vector($o) + $j *8, $this->bb) : null;
+    }
+
+    /**
+     * @return int
+     */
+    public function getTestarrayofsortedstructLength()
+    {
+        $o = $this->__offset(62);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @param int offset
+     * @return byte
+     */
+    public function getFlex($j)
+    {
+        $o = $this->__offset(64);
+        return $o != 0 ? $this->bb->getByte($this->__vector($o) + $j * 1) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getFlexLength()
+    {
+        $o = $this->__offset(64);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @return string
+     */
+    public function getFlexBytes()
+    {
+        return $this->__vector_as_bytes(64);
+    }
+
+    /**
+     * @returnVectorOffset
+     */
+    public function getTest5($j)
+    {
+        $o = $this->__offset(66);
+        $obj = new Test();
+        return $o != 0 ? $obj->init($this->__vector($o) + $j *4, $this->bb) : null;
+    }
+
+    /**
+     * @return int
+     */
+    public function getTest5Length()
+    {
+        $o = $this->__offset(66);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @param int offset
+     * @return long
+     */
+    public function getVectorOfLongs($j)
+    {
+        $o = $this->__offset(68);
+        return $o != 0 ? $this->bb->getLong($this->__vector($o) + $j * 8) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getVectorOfLongsLength()
+    {
+        $o = $this->__offset(68);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @param int offset
+     * @return double
+     */
+    public function getVectorOfDoubles($j)
+    {
+        $o = $this->__offset(70);
+        return $o != 0 ? $this->bb->getDouble($this->__vector($o) + $j * 8) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getVectorOfDoublesLength()
+    {
+        $o = $this->__offset(70);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    public function getParentNamespaceTest()
+    {
+        $obj = new InParentNamespace();
+        $o = $this->__offset(72);
+        return $o != 0 ? $obj->init($this->__indirect($o + $this->bb_pos), $this->bb) : 0;
+    }
+
+    /**
+     * @returnVectorOffset
+     */
+    public function getVectorOfReferrables($j)
+    {
+        $o = $this->__offset(74);
+        $obj = new Referrable();
+        return $o != 0 ? $obj->init($this->__indirect($this->__vector($o) + $j * 4), $this->bb) : null;
+    }
+
+    /**
+     * @return int
+     */
+    public function getVectorOfReferrablesLength()
+    {
+        $o = $this->__offset(74);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @return ulong
+     */
+    public function getSingleWeakReference()
+    {
+        $o = $this->__offset(76);
+        return $o != 0 ? $this->bb->getUlong($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @param int offset
+     * @return ulong
+     */
+    public function getVectorOfWeakReferences($j)
+    {
+        $o = $this->__offset(78);
+        return $o != 0 ? $this->bb->getUlong($this->__vector($o) + $j * 8) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getVectorOfWeakReferencesLength()
+    {
+        $o = $this->__offset(78);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @returnVectorOffset
+     */
+    public function getVectorOfStrongReferrables($j)
+    {
+        $o = $this->__offset(80);
+        $obj = new Referrable();
+        return $o != 0 ? $obj->init($this->__indirect($this->__vector($o) + $j * 4), $this->bb) : null;
+    }
+
+    /**
+     * @return int
+     */
+    public function getVectorOfStrongReferrablesLength()
+    {
+        $o = $this->__offset(80);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @return ulong
+     */
+    public function getCoOwningReference()
+    {
+        $o = $this->__offset(82);
+        return $o != 0 ? $this->bb->getUlong($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @param int offset
+     * @return ulong
+     */
+    public function getVectorOfCoOwningReferences($j)
+    {
+        $o = $this->__offset(84);
+        return $o != 0 ? $this->bb->getUlong($this->__vector($o) + $j * 8) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getVectorOfCoOwningReferencesLength()
+    {
+        $o = $this->__offset(84);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @return ulong
+     */
+    public function getNonOwningReference()
+    {
+        $o = $this->__offset(86);
+        return $o != 0 ? $this->bb->getUlong($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @param int offset
+     * @return ulong
+     */
+    public function getVectorOfNonOwningReferences($j)
+    {
+        $o = $this->__offset(88);
+        return $o != 0 ? $this->bb->getUlong($this->__vector($o) + $j * 8) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getVectorOfNonOwningReferencesLength()
+    {
+        $o = $this->__offset(88);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @return byte
+     */
+    public function getAnyUniqueType()
+    {
+        $o = $this->__offset(90);
+        return $o != 0 ? $this->bb->getByte($o + $this->bb_pos) : \MyGame\Example\AnyUniqueAliases::NONE;
+    }
+
+    /**
+     * @returnint
+     */
+    public function getAnyUnique($obj)
+    {
+        $o = $this->__offset(92);
+        return $o != 0 ? $this->__union($obj, $o) : null;
+    }
+
+    /**
+     * @return byte
+     */
+    public function getAnyAmbiguousType()
+    {
+        $o = $this->__offset(94);
+        return $o != 0 ? $this->bb->getByte($o + $this->bb_pos) : \MyGame\Example\AnyAmbiguousAliases::NONE;
+    }
+
+    /**
+     * @returnint
+     */
+    public function getAnyAmbiguous($obj)
+    {
+        $o = $this->__offset(96);
+        return $o != 0 ? $this->__union($obj, $o) : null;
+    }
+
+    /**
+     * @param int offset
+     * @return byte
+     */
+    public function getVectorOfEnums($j)
+    {
+        $o = $this->__offset(98);
+        return $o != 0 ? $this->bb->getByte($this->__vector($o) + $j * 1) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getVectorOfEnumsLength()
+    {
+        $o = $this->__offset(98);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @return string
+     */
+    public function getVectorOfEnumsBytes()
+    {
+        return $this->__vector_as_bytes(98);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startMonster(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(48);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return Monster
+     */
+    public static function createMonster(FlatBufferBuilder $builder, $pos, $mana, $hp, $name, $inventory, $color, $test_type, $test, $test4, $testarrayofstring, $testarrayoftables, $enemy, $testnestedflatbuffer, $testempty, $testbool, $testhashs32_fnv1, $testhashu32_fnv1, $testhashs64_fnv1, $testhashu64_fnv1, $testhashs32_fnv1a, $testhashu32_fnv1a, $testhashs64_fnv1a, $testhashu64_fnv1a, $testarrayofbools, $testf, $testf2, $testf3, $testarrayofstring2, $testarrayofsortedstruct, $flex, $test5, $vector_of_longs, $vector_of_doubles, $parent_namespace_test, $vector_of_referrables, $single_weak_reference, $vector_of_weak_references, $vector_of_strong_referrables, $co_owning_reference, $vector_of_co_owning_references, $non_owning_reference, $vector_of_non_owning_references, $any_unique_type, $any_unique, $any_ambiguous_type, $any_ambiguous, $vector_of_enums)
+    {
+        $builder->startObject(48);
+        self::addPos($builder, $pos);
+        self::addMana($builder, $mana);
+        self::addHp($builder, $hp);
+        self::addName($builder, $name);
+        self::addInventory($builder, $inventory);
+        self::addColor($builder, $color);
+        self::addTestType($builder, $test_type);
+        self::addTest($builder, $test);
+        self::addTest4($builder, $test4);
+        self::addTestarrayofstring($builder, $testarrayofstring);
+        self::addTestarrayoftables($builder, $testarrayoftables);
+        self::addEnemy($builder, $enemy);
+        self::addTestnestedflatbuffer($builder, $testnestedflatbuffer);
+        self::addTestempty($builder, $testempty);
+        self::addTestbool($builder, $testbool);
+        self::addTesthashs32Fnv1($builder, $testhashs32_fnv1);
+        self::addTesthashu32Fnv1($builder, $testhashu32_fnv1);
+        self::addTesthashs64Fnv1($builder, $testhashs64_fnv1);
+        self::addTesthashu64Fnv1($builder, $testhashu64_fnv1);
+        self::addTesthashs32Fnv1a($builder, $testhashs32_fnv1a);
+        self::addTesthashu32Fnv1a($builder, $testhashu32_fnv1a);
+        self::addTesthashs64Fnv1a($builder, $testhashs64_fnv1a);
+        self::addTesthashu64Fnv1a($builder, $testhashu64_fnv1a);
+        self::addTestarrayofbools($builder, $testarrayofbools);
+        self::addTestf($builder, $testf);
+        self::addTestf2($builder, $testf2);
+        self::addTestf3($builder, $testf3);
+        self::addTestarrayofstring2($builder, $testarrayofstring2);
+        self::addTestarrayofsortedstruct($builder, $testarrayofsortedstruct);
+        self::addFlex($builder, $flex);
+        self::addTest5($builder, $test5);
+        self::addVectorOfLongs($builder, $vector_of_longs);
+        self::addVectorOfDoubles($builder, $vector_of_doubles);
+        self::addParentNamespaceTest($builder, $parent_namespace_test);
+        self::addVectorOfReferrables($builder, $vector_of_referrables);
+        self::addSingleWeakReference($builder, $single_weak_reference);
+        self::addVectorOfWeakReferences($builder, $vector_of_weak_references);
+        self::addVectorOfStrongReferrables($builder, $vector_of_strong_referrables);
+        self::addCoOwningReference($builder, $co_owning_reference);
+        self::addVectorOfCoOwningReferences($builder, $vector_of_co_owning_references);
+        self::addNonOwningReference($builder, $non_owning_reference);
+        self::addVectorOfNonOwningReferences($builder, $vector_of_non_owning_references);
+        self::addAnyUniqueType($builder, $any_unique_type);
+        self::addAnyUnique($builder, $any_unique);
+        self::addAnyAmbiguousType($builder, $any_ambiguous_type);
+        self::addAnyAmbiguous($builder, $any_ambiguous);
+        self::addVectorOfEnums($builder, $vector_of_enums);
+        $o = $builder->endObject();
+        $builder->required($o, 10);  // name
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addPos(FlatBufferBuilder $builder, $pos)
+    {
+        $builder->addStructX(0, $pos, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param short
+     * @return void
+     */
+    public static function addMana(FlatBufferBuilder $builder, $mana)
+    {
+        $builder->addShortX(1, $mana, 150);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param short
+     * @return void
+     */
+    public static function addHp(FlatBufferBuilder $builder, $hp)
+    {
+        $builder->addShortX(2, $hp, 100);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param StringOffset
+     * @return void
+     */
+    public static function addName(FlatBufferBuilder $builder, $name)
+    {
+        $builder->addOffsetX(3, $name, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addInventory(FlatBufferBuilder $builder, $inventory)
+    {
+        $builder->addOffsetX(5, $inventory, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createInventoryVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(1, count($data), 1);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putByte($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startInventoryVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(1, $numElems, 1);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param byte
+     * @return void
+     */
+    public static function addColor(FlatBufferBuilder $builder, $color)
+    {
+        $builder->addByteX(6, $color, 8);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param byte
+     * @return void
+     */
+    public static function addTestType(FlatBufferBuilder $builder, $testType)
+    {
+        $builder->addByteX(7, $testType, 0);
+    }
+
+    public static function addTest(FlatBufferBuilder $builder, $offset)
+    {
+        $builder->addOffsetX(8, $offset, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addTest4(FlatBufferBuilder $builder, $test4)
+    {
+        $builder->addOffsetX(9, $test4, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createTest4Vector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(4, count($data), 2);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putOffset($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startTest4Vector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(4, $numElems, 2);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addTestarrayofstring(FlatBufferBuilder $builder, $testarrayofstring)
+    {
+        $builder->addOffsetX(10, $testarrayofstring, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createTestarrayofstringVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(4, count($data), 4);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putOffset($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startTestarrayofstringVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(4, $numElems, 4);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addTestarrayoftables(FlatBufferBuilder $builder, $testarrayoftables)
+    {
+        $builder->addOffsetX(11, $testarrayoftables, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createTestarrayoftablesVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(4, count($data), 4);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putOffset($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startTestarrayoftablesVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(4, $numElems, 4);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addEnemy(FlatBufferBuilder $builder, $enemy)
+    {
+        $builder->addOffsetX(12, $enemy, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addTestnestedflatbuffer(FlatBufferBuilder $builder, $testnestedflatbuffer)
+    {
+        $builder->addOffsetX(13, $testnestedflatbuffer, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createTestnestedflatbufferVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(1, count($data), 1);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putByte($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startTestnestedflatbufferVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(1, $numElems, 1);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addTestempty(FlatBufferBuilder $builder, $testempty)
+    {
+        $builder->addOffsetX(14, $testempty, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param bool
+     * @return void
+     */
+    public static function addTestbool(FlatBufferBuilder $builder, $testbool)
+    {
+        $builder->addBoolX(15, $testbool, false);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addTesthashs32Fnv1(FlatBufferBuilder $builder, $testhashs32Fnv1)
+    {
+        $builder->addIntX(16, $testhashs32Fnv1, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param uint
+     * @return void
+     */
+    public static function addTesthashu32Fnv1(FlatBufferBuilder $builder, $testhashu32Fnv1)
+    {
+        $builder->addUintX(17, $testhashu32Fnv1, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param long
+     * @return void
+     */
+    public static function addTesthashs64Fnv1(FlatBufferBuilder $builder, $testhashs64Fnv1)
+    {
+        $builder->addLongX(18, $testhashs64Fnv1, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param ulong
+     * @return void
+     */
+    public static function addTesthashu64Fnv1(FlatBufferBuilder $builder, $testhashu64Fnv1)
+    {
+        $builder->addUlongX(19, $testhashu64Fnv1, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addTesthashs32Fnv1a(FlatBufferBuilder $builder, $testhashs32Fnv1a)
+    {
+        $builder->addIntX(20, $testhashs32Fnv1a, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param uint
+     * @return void
+     */
+    public static function addTesthashu32Fnv1a(FlatBufferBuilder $builder, $testhashu32Fnv1a)
+    {
+        $builder->addUintX(21, $testhashu32Fnv1a, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param long
+     * @return void
+     */
+    public static function addTesthashs64Fnv1a(FlatBufferBuilder $builder, $testhashs64Fnv1a)
+    {
+        $builder->addLongX(22, $testhashs64Fnv1a, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param ulong
+     * @return void
+     */
+    public static function addTesthashu64Fnv1a(FlatBufferBuilder $builder, $testhashu64Fnv1a)
+    {
+        $builder->addUlongX(23, $testhashu64Fnv1a, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addTestarrayofbools(FlatBufferBuilder $builder, $testarrayofbools)
+    {
+        $builder->addOffsetX(24, $testarrayofbools, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createTestarrayofboolsVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(1, count($data), 1);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putBool($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startTestarrayofboolsVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(1, $numElems, 1);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param float
+     * @return void
+     */
+    public static function addTestf(FlatBufferBuilder $builder, $testf)
+    {
+        $builder->addFloatX(25, $testf, 3.14159);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param float
+     * @return void
+     */
+    public static function addTestf2(FlatBufferBuilder $builder, $testf2)
+    {
+        $builder->addFloatX(26, $testf2, 3.0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param float
+     * @return void
+     */
+    public static function addTestf3(FlatBufferBuilder $builder, $testf3)
+    {
+        $builder->addFloatX(27, $testf3, 0.0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addTestarrayofstring2(FlatBufferBuilder $builder, $testarrayofstring2)
+    {
+        $builder->addOffsetX(28, $testarrayofstring2, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createTestarrayofstring2Vector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(4, count($data), 4);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putOffset($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startTestarrayofstring2Vector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(4, $numElems, 4);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addTestarrayofsortedstruct(FlatBufferBuilder $builder, $testarrayofsortedstruct)
+    {
+        $builder->addOffsetX(29, $testarrayofsortedstruct, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createTestarrayofsortedstructVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(8, count($data), 4);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putOffset($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startTestarrayofsortedstructVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(8, $numElems, 4);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addFlex(FlatBufferBuilder $builder, $flex)
+    {
+        $builder->addOffsetX(30, $flex, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createFlexVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(1, count($data), 1);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putByte($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startFlexVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(1, $numElems, 1);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addTest5(FlatBufferBuilder $builder, $test5)
+    {
+        $builder->addOffsetX(31, $test5, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createTest5Vector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(4, count($data), 2);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putOffset($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startTest5Vector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(4, $numElems, 2);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addVectorOfLongs(FlatBufferBuilder $builder, $vectorOfLongs)
+    {
+        $builder->addOffsetX(32, $vectorOfLongs, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createVectorOfLongsVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(8, count($data), 8);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putLong($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startVectorOfLongsVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(8, $numElems, 8);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addVectorOfDoubles(FlatBufferBuilder $builder, $vectorOfDoubles)
+    {
+        $builder->addOffsetX(33, $vectorOfDoubles, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createVectorOfDoublesVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(8, count($data), 8);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putDouble($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startVectorOfDoublesVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(8, $numElems, 8);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addParentNamespaceTest(FlatBufferBuilder $builder, $parentNamespaceTest)
+    {
+        $builder->addOffsetX(34, $parentNamespaceTest, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addVectorOfReferrables(FlatBufferBuilder $builder, $vectorOfReferrables)
+    {
+        $builder->addOffsetX(35, $vectorOfReferrables, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createVectorOfReferrablesVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(4, count($data), 4);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putOffset($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startVectorOfReferrablesVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(4, $numElems, 4);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param ulong
+     * @return void
+     */
+    public static function addSingleWeakReference(FlatBufferBuilder $builder, $singleWeakReference)
+    {
+        $builder->addUlongX(36, $singleWeakReference, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addVectorOfWeakReferences(FlatBufferBuilder $builder, $vectorOfWeakReferences)
+    {
+        $builder->addOffsetX(37, $vectorOfWeakReferences, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createVectorOfWeakReferencesVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(8, count($data), 8);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putUlong($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startVectorOfWeakReferencesVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(8, $numElems, 8);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addVectorOfStrongReferrables(FlatBufferBuilder $builder, $vectorOfStrongReferrables)
+    {
+        $builder->addOffsetX(38, $vectorOfStrongReferrables, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createVectorOfStrongReferrablesVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(4, count($data), 4);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putOffset($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startVectorOfStrongReferrablesVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(4, $numElems, 4);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param ulong
+     * @return void
+     */
+    public static function addCoOwningReference(FlatBufferBuilder $builder, $coOwningReference)
+    {
+        $builder->addUlongX(39, $coOwningReference, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addVectorOfCoOwningReferences(FlatBufferBuilder $builder, $vectorOfCoOwningReferences)
+    {
+        $builder->addOffsetX(40, $vectorOfCoOwningReferences, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createVectorOfCoOwningReferencesVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(8, count($data), 8);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putUlong($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startVectorOfCoOwningReferencesVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(8, $numElems, 8);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param ulong
+     * @return void
+     */
+    public static function addNonOwningReference(FlatBufferBuilder $builder, $nonOwningReference)
+    {
+        $builder->addUlongX(41, $nonOwningReference, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addVectorOfNonOwningReferences(FlatBufferBuilder $builder, $vectorOfNonOwningReferences)
+    {
+        $builder->addOffsetX(42, $vectorOfNonOwningReferences, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createVectorOfNonOwningReferencesVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(8, count($data), 8);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putUlong($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startVectorOfNonOwningReferencesVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(8, $numElems, 8);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param byte
+     * @return void
+     */
+    public static function addAnyUniqueType(FlatBufferBuilder $builder, $anyUniqueType)
+    {
+        $builder->addByteX(43, $anyUniqueType, 0);
+    }
+
+    public static function addAnyUnique(FlatBufferBuilder $builder, $offset)
+    {
+        $builder->addOffsetX(44, $offset, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param byte
+     * @return void
+     */
+    public static function addAnyAmbiguousType(FlatBufferBuilder $builder, $anyAmbiguousType)
+    {
+        $builder->addByteX(45, $anyAmbiguousType, 0);
+    }
+
+    public static function addAnyAmbiguous(FlatBufferBuilder $builder, $offset)
+    {
+        $builder->addOffsetX(46, $offset, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addVectorOfEnums(FlatBufferBuilder $builder, $vectorOfEnums)
+    {
+        $builder->addOffsetX(47, $vectorOfEnums, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createVectorOfEnumsVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(1, count($data), 1);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putByte($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startVectorOfEnumsVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(1, $numElems, 1);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endMonster(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        $builder->required($o, 10);  // name
+        return $o;
+    }
+
+    public static function finishMonsterBuffer(FlatBufferBuilder $builder, $offset)
+    {
+        $builder->finish($offset, "MONS");
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Monster.py b/third_party/flatbuffers/tests/MyGame/Example/Monster.py
new file mode 100644
index 0000000..5baf64d
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Monster.py
@@ -0,0 +1,689 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+import flatbuffers
+
+# an example documentation comment: monster object
+class Monster(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAsMonster(cls, buf, offset):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = Monster()
+        x.Init(buf, n + offset)
+        return x
+
+    @classmethod
+    def MonsterBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
+        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)
+
+    # Monster
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # Monster
+    def Pos(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        if o != 0:
+            x = o + self._tab.Pos
+            from .Vec3 import Vec3
+            obj = Vec3()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+    # Monster
+    def Mana(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int16Flags, o + self._tab.Pos)
+        return 150
+
+    # Monster
+    def Hp(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int16Flags, o + self._tab.Pos)
+        return 100
+
+    # Monster
+    def Name(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
+        if o != 0:
+            return self._tab.String(o + self._tab.Pos)
+        return None
+
+    # Monster
+    def Inventory(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
+        return 0
+
+    # Monster
+    def InventoryAsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
+        return 0
+
+    # Monster
+    def InventoryLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def Color(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
+        return 8
+
+    # Monster
+    def TestType(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def Test(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
+        if o != 0:
+            from flatbuffers.table import Table
+            obj = Table(bytearray(), 0)
+            self._tab.Union(obj, o)
+            return obj
+        return None
+
+    # Monster
+    def Test4(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
+        if o != 0:
+            x = self._tab.Vector(o)
+            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
+            from .Test import Test
+            obj = Test()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+    # Monster
+    def Test4Length(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def Testarrayofstring(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.String(a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
+        return ""
+
+    # Monster
+    def TestarrayofstringLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # an example documentation comment: this will end up in the generated code
+    # multiline too
+    # Monster
+    def Testarrayoftables(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
+        if o != 0:
+            x = self._tab.Vector(o)
+            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
+            x = self._tab.Indirect(x)
+            from .Monster import Monster
+            obj = Monster()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+    # Monster
+    def TestarrayoftablesLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def Enemy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(28))
+        if o != 0:
+            x = self._tab.Indirect(o + self._tab.Pos)
+            from .Monster import Monster
+            obj = Monster()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+    # Monster
+    def Testnestedflatbuffer(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(30))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
+        return 0
+
+    # Monster
+    def TestnestedflatbufferAsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(30))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
+        return 0
+
+    # Monster
+    def TestnestedflatbufferLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(30))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def Testempty(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(32))
+        if o != 0:
+            x = self._tab.Indirect(o + self._tab.Pos)
+            from .Stat import Stat
+            obj = Stat()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+    # Monster
+    def Testbool(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(34))
+        if o != 0:
+            return bool(self._tab.Get(flatbuffers.number_types.BoolFlags, o + self._tab.Pos))
+        return False
+
+    # Monster
+    def Testhashs32Fnv1(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(36))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def Testhashu32Fnv1(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(38))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint32Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def Testhashs64Fnv1(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(40))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int64Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def Testhashu64Fnv1(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(42))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def Testhashs32Fnv1a(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(44))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def Testhashu32Fnv1a(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(46))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint32Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def Testhashs64Fnv1a(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(48))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int64Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def Testhashu64Fnv1a(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(50))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def Testarrayofbools(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(52))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.BoolFlags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
+        return 0
+
+    # Monster
+    def TestarrayofboolsAsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(52))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.BoolFlags, o)
+        return 0
+
+    # Monster
+    def TestarrayofboolsLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(52))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def Testf(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(54))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
+        return 3.14159
+
+    # Monster
+    def Testf2(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(56))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
+        return 3.0
+
+    # Monster
+    def Testf3(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(58))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
+        return 0.0
+
+    # Monster
+    def Testarrayofstring2(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(60))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.String(a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
+        return ""
+
+    # Monster
+    def Testarrayofstring2Length(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(60))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def Testarrayofsortedstruct(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(62))
+        if o != 0:
+            x = self._tab.Vector(o)
+            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 8
+            from .Ability import Ability
+            obj = Ability()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+    # Monster
+    def TestarrayofsortedstructLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(62))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def Flex(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(64))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
+        return 0
+
+    # Monster
+    def FlexAsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(64))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
+        return 0
+
+    # Monster
+    def FlexLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(64))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def Test5(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(66))
+        if o != 0:
+            x = self._tab.Vector(o)
+            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
+            from .Test import Test
+            obj = Test()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+    # Monster
+    def Test5Length(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(66))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def VectorOfLongs(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(68))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.Int64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
+        return 0
+
+    # Monster
+    def VectorOfLongsAsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(68))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Int64Flags, o)
+        return 0
+
+    # Monster
+    def VectorOfLongsLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(68))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def VectorOfDoubles(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(70))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.Float64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
+        return 0
+
+    # Monster
+    def VectorOfDoublesAsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(70))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Float64Flags, o)
+        return 0
+
+    # Monster
+    def VectorOfDoublesLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(70))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def ParentNamespaceTest(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(72))
+        if o != 0:
+            x = self._tab.Indirect(o + self._tab.Pos)
+            from .InParentNamespace import InParentNamespace
+            obj = InParentNamespace()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+    # Monster
+    def VectorOfReferrables(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(74))
+        if o != 0:
+            x = self._tab.Vector(o)
+            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
+            x = self._tab.Indirect(x)
+            from .Referrable import Referrable
+            obj = Referrable()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+    # Monster
+    def VectorOfReferrablesLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(74))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def SingleWeakReference(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(76))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def VectorOfWeakReferences(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(78))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.Uint64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
+        return 0
+
+    # Monster
+    def VectorOfWeakReferencesAsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(78))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint64Flags, o)
+        return 0
+
+    # Monster
+    def VectorOfWeakReferencesLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(78))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def VectorOfStrongReferrables(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(80))
+        if o != 0:
+            x = self._tab.Vector(o)
+            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
+            x = self._tab.Indirect(x)
+            from .Referrable import Referrable
+            obj = Referrable()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+    # Monster
+    def VectorOfStrongReferrablesLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(80))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def CoOwningReference(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(82))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def VectorOfCoOwningReferences(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(84))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.Uint64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
+        return 0
+
+    # Monster
+    def VectorOfCoOwningReferencesAsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(84))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint64Flags, o)
+        return 0
+
+    # Monster
+    def VectorOfCoOwningReferencesLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(84))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def NonOwningReference(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(86))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def VectorOfNonOwningReferences(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(88))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.Uint64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
+        return 0
+
+    # Monster
+    def VectorOfNonOwningReferencesAsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(88))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint64Flags, o)
+        return 0
+
+    # Monster
+    def VectorOfNonOwningReferencesLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(88))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # Monster
+    def AnyUniqueType(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(90))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def AnyUnique(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(92))
+        if o != 0:
+            from flatbuffers.table import Table
+            obj = Table(bytearray(), 0)
+            self._tab.Union(obj, o)
+            return obj
+        return None
+
+    # Monster
+    def AnyAmbiguousType(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(94))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
+        return 0
+
+    # Monster
+    def AnyAmbiguous(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(96))
+        if o != 0:
+            from flatbuffers.table import Table
+            obj = Table(bytearray(), 0)
+            self._tab.Union(obj, o)
+            return obj
+        return None
+
+    # Monster
+    def VectorOfEnums(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(98))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
+        return 0
+
+    # Monster
+    def VectorOfEnumsAsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(98))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
+        return 0
+
+    # Monster
+    def VectorOfEnumsLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(98))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+def MonsterStart(builder): builder.StartObject(48)
+def MonsterAddPos(builder, pos): builder.PrependStructSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(pos), 0)
+def MonsterAddMana(builder, mana): builder.PrependInt16Slot(1, mana, 150)
+def MonsterAddHp(builder, hp): builder.PrependInt16Slot(2, hp, 100)
+def MonsterAddName(builder, name): builder.PrependUOffsetTRelativeSlot(3, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0)
+def MonsterAddInventory(builder, inventory): builder.PrependUOffsetTRelativeSlot(5, flatbuffers.number_types.UOffsetTFlags.py_type(inventory), 0)
+def MonsterStartInventoryVector(builder, numElems): return builder.StartVector(1, numElems, 1)
+def MonsterAddColor(builder, color): builder.PrependUint8Slot(6, color, 8)
+def MonsterAddTestType(builder, testType): builder.PrependUint8Slot(7, testType, 0)
+def MonsterAddTest(builder, test): builder.PrependUOffsetTRelativeSlot(8, flatbuffers.number_types.UOffsetTFlags.py_type(test), 0)
+def MonsterAddTest4(builder, test4): builder.PrependUOffsetTRelativeSlot(9, flatbuffers.number_types.UOffsetTFlags.py_type(test4), 0)
+def MonsterStartTest4Vector(builder, numElems): return builder.StartVector(4, numElems, 2)
+def MonsterAddTestarrayofstring(builder, testarrayofstring): builder.PrependUOffsetTRelativeSlot(10, flatbuffers.number_types.UOffsetTFlags.py_type(testarrayofstring), 0)
+def MonsterStartTestarrayofstringVector(builder, numElems): return builder.StartVector(4, numElems, 4)
+def MonsterAddTestarrayoftables(builder, testarrayoftables): builder.PrependUOffsetTRelativeSlot(11, flatbuffers.number_types.UOffsetTFlags.py_type(testarrayoftables), 0)
+def MonsterStartTestarrayoftablesVector(builder, numElems): return builder.StartVector(4, numElems, 4)
+def MonsterAddEnemy(builder, enemy): builder.PrependUOffsetTRelativeSlot(12, flatbuffers.number_types.UOffsetTFlags.py_type(enemy), 0)
+def MonsterAddTestnestedflatbuffer(builder, testnestedflatbuffer): builder.PrependUOffsetTRelativeSlot(13, flatbuffers.number_types.UOffsetTFlags.py_type(testnestedflatbuffer), 0)
+def MonsterStartTestnestedflatbufferVector(builder, numElems): return builder.StartVector(1, numElems, 1)
+def MonsterAddTestempty(builder, testempty): builder.PrependUOffsetTRelativeSlot(14, flatbuffers.number_types.UOffsetTFlags.py_type(testempty), 0)
+def MonsterAddTestbool(builder, testbool): builder.PrependBoolSlot(15, testbool, 0)
+def MonsterAddTesthashs32Fnv1(builder, testhashs32Fnv1): builder.PrependInt32Slot(16, testhashs32Fnv1, 0)
+def MonsterAddTesthashu32Fnv1(builder, testhashu32Fnv1): builder.PrependUint32Slot(17, testhashu32Fnv1, 0)
+def MonsterAddTesthashs64Fnv1(builder, testhashs64Fnv1): builder.PrependInt64Slot(18, testhashs64Fnv1, 0)
+def MonsterAddTesthashu64Fnv1(builder, testhashu64Fnv1): builder.PrependUint64Slot(19, testhashu64Fnv1, 0)
+def MonsterAddTesthashs32Fnv1a(builder, testhashs32Fnv1a): builder.PrependInt32Slot(20, testhashs32Fnv1a, 0)
+def MonsterAddTesthashu32Fnv1a(builder, testhashu32Fnv1a): builder.PrependUint32Slot(21, testhashu32Fnv1a, 0)
+def MonsterAddTesthashs64Fnv1a(builder, testhashs64Fnv1a): builder.PrependInt64Slot(22, testhashs64Fnv1a, 0)
+def MonsterAddTesthashu64Fnv1a(builder, testhashu64Fnv1a): builder.PrependUint64Slot(23, testhashu64Fnv1a, 0)
+def MonsterAddTestarrayofbools(builder, testarrayofbools): builder.PrependUOffsetTRelativeSlot(24, flatbuffers.number_types.UOffsetTFlags.py_type(testarrayofbools), 0)
+def MonsterStartTestarrayofboolsVector(builder, numElems): return builder.StartVector(1, numElems, 1)
+def MonsterAddTestf(builder, testf): builder.PrependFloat32Slot(25, testf, 3.14159)
+def MonsterAddTestf2(builder, testf2): builder.PrependFloat32Slot(26, testf2, 3.0)
+def MonsterAddTestf3(builder, testf3): builder.PrependFloat32Slot(27, testf3, 0.0)
+def MonsterAddTestarrayofstring2(builder, testarrayofstring2): builder.PrependUOffsetTRelativeSlot(28, flatbuffers.number_types.UOffsetTFlags.py_type(testarrayofstring2), 0)
+def MonsterStartTestarrayofstring2Vector(builder, numElems): return builder.StartVector(4, numElems, 4)
+def MonsterAddTestarrayofsortedstruct(builder, testarrayofsortedstruct): builder.PrependUOffsetTRelativeSlot(29, flatbuffers.number_types.UOffsetTFlags.py_type(testarrayofsortedstruct), 0)
+def MonsterStartTestarrayofsortedstructVector(builder, numElems): return builder.StartVector(8, numElems, 4)
+def MonsterAddFlex(builder, flex): builder.PrependUOffsetTRelativeSlot(30, flatbuffers.number_types.UOffsetTFlags.py_type(flex), 0)
+def MonsterStartFlexVector(builder, numElems): return builder.StartVector(1, numElems, 1)
+def MonsterAddTest5(builder, test5): builder.PrependUOffsetTRelativeSlot(31, flatbuffers.number_types.UOffsetTFlags.py_type(test5), 0)
+def MonsterStartTest5Vector(builder, numElems): return builder.StartVector(4, numElems, 2)
+def MonsterAddVectorOfLongs(builder, vectorOfLongs): builder.PrependUOffsetTRelativeSlot(32, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfLongs), 0)
+def MonsterStartVectorOfLongsVector(builder, numElems): return builder.StartVector(8, numElems, 8)
+def MonsterAddVectorOfDoubles(builder, vectorOfDoubles): builder.PrependUOffsetTRelativeSlot(33, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfDoubles), 0)
+def MonsterStartVectorOfDoublesVector(builder, numElems): return builder.StartVector(8, numElems, 8)
+def MonsterAddParentNamespaceTest(builder, parentNamespaceTest): builder.PrependUOffsetTRelativeSlot(34, flatbuffers.number_types.UOffsetTFlags.py_type(parentNamespaceTest), 0)
+def MonsterAddVectorOfReferrables(builder, vectorOfReferrables): builder.PrependUOffsetTRelativeSlot(35, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfReferrables), 0)
+def MonsterStartVectorOfReferrablesVector(builder, numElems): return builder.StartVector(4, numElems, 4)
+def MonsterAddSingleWeakReference(builder, singleWeakReference): builder.PrependUint64Slot(36, singleWeakReference, 0)
+def MonsterAddVectorOfWeakReferences(builder, vectorOfWeakReferences): builder.PrependUOffsetTRelativeSlot(37, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfWeakReferences), 0)
+def MonsterStartVectorOfWeakReferencesVector(builder, numElems): return builder.StartVector(8, numElems, 8)
+def MonsterAddVectorOfStrongReferrables(builder, vectorOfStrongReferrables): builder.PrependUOffsetTRelativeSlot(38, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfStrongReferrables), 0)
+def MonsterStartVectorOfStrongReferrablesVector(builder, numElems): return builder.StartVector(4, numElems, 4)
+def MonsterAddCoOwningReference(builder, coOwningReference): builder.PrependUint64Slot(39, coOwningReference, 0)
+def MonsterAddVectorOfCoOwningReferences(builder, vectorOfCoOwningReferences): builder.PrependUOffsetTRelativeSlot(40, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfCoOwningReferences), 0)
+def MonsterStartVectorOfCoOwningReferencesVector(builder, numElems): return builder.StartVector(8, numElems, 8)
+def MonsterAddNonOwningReference(builder, nonOwningReference): builder.PrependUint64Slot(41, nonOwningReference, 0)
+def MonsterAddVectorOfNonOwningReferences(builder, vectorOfNonOwningReferences): builder.PrependUOffsetTRelativeSlot(42, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfNonOwningReferences), 0)
+def MonsterStartVectorOfNonOwningReferencesVector(builder, numElems): return builder.StartVector(8, numElems, 8)
+def MonsterAddAnyUniqueType(builder, anyUniqueType): builder.PrependUint8Slot(43, anyUniqueType, 0)
+def MonsterAddAnyUnique(builder, anyUnique): builder.PrependUOffsetTRelativeSlot(44, flatbuffers.number_types.UOffsetTFlags.py_type(anyUnique), 0)
+def MonsterAddAnyAmbiguousType(builder, anyAmbiguousType): builder.PrependUint8Slot(45, anyAmbiguousType, 0)
+def MonsterAddAnyAmbiguous(builder, anyAmbiguous): builder.PrependUOffsetTRelativeSlot(46, flatbuffers.number_types.UOffsetTFlags.py_type(anyAmbiguous), 0)
+def MonsterAddVectorOfEnums(builder, vectorOfEnums): builder.PrependUOffsetTRelativeSlot(47, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfEnums), 0)
+def MonsterStartVectorOfEnumsVector(builder, numElems): return builder.StartVector(1, numElems, 1)
+def MonsterEnd(builder): return builder.EndObject()
diff --git a/third_party/flatbuffers/tests/MyGame/Example/MonsterStorageGrpc.java b/third_party/flatbuffers/tests/MyGame/Example/MonsterStorageGrpc.java
new file mode 100644
index 0000000..b9f070f
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/MonsterStorageGrpc.java
@@ -0,0 +1,470 @@
+//Generated by flatc compiler (version 1.11.0)
+//If you make any local changes, they will be lost
+//source: monster_test.fbs
+
+package MyGame.Example;
+
+import com.google.flatbuffers.grpc.FlatbuffersUtils;
+
+import java.nio.ByteBuffer;
+import static io.grpc.MethodDescriptor.generateFullMethodName;
+import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall;
+import static io.grpc.stub.ClientCalls.asyncClientStreamingCall;
+import static io.grpc.stub.ClientCalls.asyncServerStreamingCall;
+import static io.grpc.stub.ClientCalls.asyncUnaryCall;
+import static io.grpc.stub.ClientCalls.blockingServerStreamingCall;
+import static io.grpc.stub.ClientCalls.blockingUnaryCall;
+import static io.grpc.stub.ClientCalls.futureUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;
+
+/**
+ */
+@javax.annotation.Generated(
+    value = "by gRPC proto compiler",
+    comments = "Source: monster_test.fbs")
+public final class MonsterStorageGrpc {
+
+  private MonsterStorageGrpc() {}
+  
+  public static final String SERVICE_NAME = "MyGame.Example.MonsterStorage";
+  
+  // Static method descriptors that strictly reflect the proto.
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  @java.lang.Deprecated // Use {@link #getStoreMethod()} instead. 
+  public static final io.grpc.MethodDescriptor<MyGame.Example.Monster,
+      MyGame.Example.Stat> METHOD_STORE = getStoreMethod();
+  
+  private static volatile io.grpc.MethodDescriptor<MyGame.Example.Monster,
+      MyGame.Example.Stat> getStoreMethod;
+  
+  private static volatile FlatbuffersUtils.FBExtactor<MyGame.Example.Monster> extractorOfMonster;
+  private static FlatbuffersUtils.FBExtactor<MyGame.Example.Monster> getExtractorOfMonster() {
+      if (extractorOfMonster != null) return extractorOfMonster;
+      synchronized (MonsterStorageGrpc.class) {
+          if (extractorOfMonster != null) return extractorOfMonster;
+          extractorOfMonster = new FlatbuffersUtils.FBExtactor<MyGame.Example.Monster>() {
+              public MyGame.Example.Monster extract (ByteBuffer buffer) {
+                  return MyGame.Example.Monster.getRootAsMonster(buffer);
+              }
+          };
+          return extractorOfMonster;
+      }
+  }
+  
+  private static volatile FlatbuffersUtils.FBExtactor<MyGame.Example.Stat> extractorOfStat;
+  private static FlatbuffersUtils.FBExtactor<MyGame.Example.Stat> getExtractorOfStat() {
+      if (extractorOfStat != null) return extractorOfStat;
+      synchronized (MonsterStorageGrpc.class) {
+          if (extractorOfStat != null) return extractorOfStat;
+          extractorOfStat = new FlatbuffersUtils.FBExtactor<MyGame.Example.Stat>() {
+              public MyGame.Example.Stat extract (ByteBuffer buffer) {
+                  return MyGame.Example.Stat.getRootAsStat(buffer);
+              }
+          };
+          return extractorOfStat;
+      }
+  }
+  
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  public static io.grpc.MethodDescriptor<MyGame.Example.Monster,
+      MyGame.Example.Stat> getStoreMethod() {
+    io.grpc.MethodDescriptor<MyGame.Example.Monster, MyGame.Example.Stat> getStoreMethod;
+    if ((getStoreMethod = MonsterStorageGrpc.getStoreMethod) == null) {
+      synchronized (MonsterStorageGrpc.class) {
+        if ((getStoreMethod = MonsterStorageGrpc.getStoreMethod) == null) {
+          MonsterStorageGrpc.getStoreMethod = getStoreMethod = 
+              io.grpc.MethodDescriptor.<MyGame.Example.Monster, MyGame.Example.Stat>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(
+                  "MyGame.Example.MonsterStorage", "Store"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(FlatbuffersUtils.marshaller(
+                  MyGame.Example.Monster.class, getExtractorOfMonster()))
+              .setResponseMarshaller(FlatbuffersUtils.marshaller(
+                  MyGame.Example.Stat.class, getExtractorOfStat()))
+                  .setSchemaDescriptor(null)
+                  .build();
+          }
+        }
+     }
+     return getStoreMethod;
+  }
+  
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  @java.lang.Deprecated // Use {@link #getRetrieveMethod()} instead. 
+  public static final io.grpc.MethodDescriptor<MyGame.Example.Stat,
+      MyGame.Example.Monster> METHOD_RETRIEVE = getRetrieveMethod();
+  
+  private static volatile io.grpc.MethodDescriptor<MyGame.Example.Stat,
+      MyGame.Example.Monster> getRetrieveMethod;
+  
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  public static io.grpc.MethodDescriptor<MyGame.Example.Stat,
+      MyGame.Example.Monster> getRetrieveMethod() {
+    io.grpc.MethodDescriptor<MyGame.Example.Stat, MyGame.Example.Monster> getRetrieveMethod;
+    if ((getRetrieveMethod = MonsterStorageGrpc.getRetrieveMethod) == null) {
+      synchronized (MonsterStorageGrpc.class) {
+        if ((getRetrieveMethod = MonsterStorageGrpc.getRetrieveMethod) == null) {
+          MonsterStorageGrpc.getRetrieveMethod = getRetrieveMethod = 
+              io.grpc.MethodDescriptor.<MyGame.Example.Stat, MyGame.Example.Monster>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING)
+              .setFullMethodName(generateFullMethodName(
+                  "MyGame.Example.MonsterStorage", "Retrieve"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(FlatbuffersUtils.marshaller(
+                  MyGame.Example.Stat.class, getExtractorOfStat()))
+              .setResponseMarshaller(FlatbuffersUtils.marshaller(
+                  MyGame.Example.Monster.class, getExtractorOfMonster()))
+                  .setSchemaDescriptor(null)
+                  .build();
+          }
+        }
+     }
+     return getRetrieveMethod;
+  }
+  
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  @java.lang.Deprecated // Use {@link #getGetMaxHitPointMethod()} instead. 
+  public static final io.grpc.MethodDescriptor<MyGame.Example.Monster,
+      MyGame.Example.Stat> METHOD_GET_MAX_HIT_POINT = getGetMaxHitPointMethod();
+  
+  private static volatile io.grpc.MethodDescriptor<MyGame.Example.Monster,
+      MyGame.Example.Stat> getGetMaxHitPointMethod;
+  
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  public static io.grpc.MethodDescriptor<MyGame.Example.Monster,
+      MyGame.Example.Stat> getGetMaxHitPointMethod() {
+    io.grpc.MethodDescriptor<MyGame.Example.Monster, MyGame.Example.Stat> getGetMaxHitPointMethod;
+    if ((getGetMaxHitPointMethod = MonsterStorageGrpc.getGetMaxHitPointMethod) == null) {
+      synchronized (MonsterStorageGrpc.class) {
+        if ((getGetMaxHitPointMethod = MonsterStorageGrpc.getGetMaxHitPointMethod) == null) {
+          MonsterStorageGrpc.getGetMaxHitPointMethod = getGetMaxHitPointMethod = 
+              io.grpc.MethodDescriptor.<MyGame.Example.Monster, MyGame.Example.Stat>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.CLIENT_STREAMING)
+              .setFullMethodName(generateFullMethodName(
+                  "MyGame.Example.MonsterStorage", "GetMaxHitPoint"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(FlatbuffersUtils.marshaller(
+                  MyGame.Example.Monster.class, getExtractorOfMonster()))
+              .setResponseMarshaller(FlatbuffersUtils.marshaller(
+                  MyGame.Example.Stat.class, getExtractorOfStat()))
+                  .setSchemaDescriptor(null)
+                  .build();
+          }
+        }
+     }
+     return getGetMaxHitPointMethod;
+  }
+  
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  @java.lang.Deprecated // Use {@link #getGetMinMaxHitPointsMethod()} instead. 
+  public static final io.grpc.MethodDescriptor<MyGame.Example.Monster,
+      MyGame.Example.Stat> METHOD_GET_MIN_MAX_HIT_POINTS = getGetMinMaxHitPointsMethod();
+  
+  private static volatile io.grpc.MethodDescriptor<MyGame.Example.Monster,
+      MyGame.Example.Stat> getGetMinMaxHitPointsMethod;
+  
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  public static io.grpc.MethodDescriptor<MyGame.Example.Monster,
+      MyGame.Example.Stat> getGetMinMaxHitPointsMethod() {
+    io.grpc.MethodDescriptor<MyGame.Example.Monster, MyGame.Example.Stat> getGetMinMaxHitPointsMethod;
+    if ((getGetMinMaxHitPointsMethod = MonsterStorageGrpc.getGetMinMaxHitPointsMethod) == null) {
+      synchronized (MonsterStorageGrpc.class) {
+        if ((getGetMinMaxHitPointsMethod = MonsterStorageGrpc.getGetMinMaxHitPointsMethod) == null) {
+          MonsterStorageGrpc.getGetMinMaxHitPointsMethod = getGetMinMaxHitPointsMethod = 
+              io.grpc.MethodDescriptor.<MyGame.Example.Monster, MyGame.Example.Stat>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.BIDI_STREAMING)
+              .setFullMethodName(generateFullMethodName(
+                  "MyGame.Example.MonsterStorage", "GetMinMaxHitPoints"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(FlatbuffersUtils.marshaller(
+                  MyGame.Example.Monster.class, getExtractorOfMonster()))
+              .setResponseMarshaller(FlatbuffersUtils.marshaller(
+                  MyGame.Example.Stat.class, getExtractorOfStat()))
+                  .setSchemaDescriptor(null)
+                  .build();
+          }
+        }
+     }
+     return getGetMinMaxHitPointsMethod;
+  }
+  
+  /**
+   * Creates a new async stub that supports all call types for the service
+   */
+  public static MonsterStorageStub newStub(io.grpc.Channel channel) {
+    return new MonsterStorageStub(channel);
+  }
+  
+  /**
+   * Creates a new blocking-style stub that supports unary and streaming output calls on the service
+   */
+  public static MonsterStorageBlockingStub newBlockingStub(
+      io.grpc.Channel channel) {
+    return new MonsterStorageBlockingStub(channel);
+  }
+  
+  /**
+   * Creates a new ListenableFuture-style stub that supports unary calls on the service
+   */
+  public static MonsterStorageFutureStub newFutureStub(
+      io.grpc.Channel channel) {
+    return new MonsterStorageFutureStub(channel);
+  }
+  
+  /**
+   */
+  public static abstract class MonsterStorageImplBase implements io.grpc.BindableService {
+    
+    /**
+     */
+    public     void store(MyGame.Example.Monster request,
+        io.grpc.stub.StreamObserver<MyGame.Example.Stat> responseObserver)     {
+      asyncUnimplementedUnaryCall(getStoreMethod(), responseObserver);
+    }
+    
+    /**
+     */
+    public     void retrieve(MyGame.Example.Stat request,
+        io.grpc.stub.StreamObserver<MyGame.Example.Monster> responseObserver)     {
+      asyncUnimplementedUnaryCall(getRetrieveMethod(), responseObserver);
+    }
+    
+    /**
+     */
+    public     io.grpc.stub.StreamObserver<MyGame.Example.Monster> getMaxHitPoint(
+        io.grpc.stub.StreamObserver<MyGame.Example.Stat> responseObserver)     {
+      return asyncUnimplementedStreamingCall(getGetMaxHitPointMethod(), responseObserver);
+    }
+    
+    /**
+     */
+    public     io.grpc.stub.StreamObserver<MyGame.Example.Monster> getMinMaxHitPoints(
+        io.grpc.stub.StreamObserver<MyGame.Example.Stat> responseObserver)     {
+      return asyncUnimplementedStreamingCall(getGetMinMaxHitPointsMethod(), responseObserver);
+    }
+    
+    @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() {
+      return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
+          .addMethod(
+            getStoreMethod(),
+            asyncUnaryCall(
+              new MethodHandlers<
+                MyGame.Example.Monster,
+                MyGame.Example.Stat>(
+                  this, METHODID_STORE)))
+          .addMethod(
+            getRetrieveMethod(),
+            asyncServerStreamingCall(
+              new MethodHandlers<
+                MyGame.Example.Stat,
+                MyGame.Example.Monster>(
+                  this, METHODID_RETRIEVE)))
+          .addMethod(
+            getGetMaxHitPointMethod(),
+            asyncClientStreamingCall(
+              new MethodHandlers<
+                MyGame.Example.Monster,
+                MyGame.Example.Stat>(
+                  this, METHODID_GET_MAX_HIT_POINT)))
+          .addMethod(
+            getGetMinMaxHitPointsMethod(),
+            asyncBidiStreamingCall(
+              new MethodHandlers<
+                MyGame.Example.Monster,
+                MyGame.Example.Stat>(
+                  this, METHODID_GET_MIN_MAX_HIT_POINTS)))
+          .build();
+    }
+  }
+  
+  /**
+   */
+  public static final class MonsterStorageStub extends io.grpc.stub.AbstractStub<MonsterStorageStub> {
+    private MonsterStorageStub(io.grpc.Channel channel) {
+      super(channel);
+    }
+    
+    private MonsterStorageStub(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+    
+    @java.lang.Override
+    protected MonsterStorageStub build(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      return new MonsterStorageStub(channel, callOptions);
+    }
+    
+    /**
+     */
+    public     void store(MyGame.Example.Monster request,
+        io.grpc.stub.StreamObserver<MyGame.Example.Stat> responseObserver)     {
+      asyncUnaryCall(
+          getChannel().newCall(getStoreMethod(), getCallOptions()), request, responseObserver);
+    }
+    
+    /**
+     */
+    public     void retrieve(MyGame.Example.Stat request,
+        io.grpc.stub.StreamObserver<MyGame.Example.Monster> responseObserver)     {
+      asyncServerStreamingCall(
+          getChannel().newCall(getRetrieveMethod(), getCallOptions()), request, responseObserver);
+    }
+    
+    /**
+     */
+    public     io.grpc.stub.StreamObserver<MyGame.Example.Monster> getMaxHitPoint(
+        io.grpc.stub.StreamObserver<MyGame.Example.Stat> responseObserver)     {
+      return asyncClientStreamingCall(
+          getChannel().newCall(getGetMaxHitPointMethod(), getCallOptions()), responseObserver);
+    }
+    
+    /**
+     */
+    public     io.grpc.stub.StreamObserver<MyGame.Example.Monster> getMinMaxHitPoints(
+        io.grpc.stub.StreamObserver<MyGame.Example.Stat> responseObserver)     {
+      return asyncBidiStreamingCall(
+          getChannel().newCall(getGetMinMaxHitPointsMethod(), getCallOptions()), responseObserver);
+    }
+  }
+  
+  /**
+   */
+  public static final class MonsterStorageBlockingStub extends io.grpc.stub.AbstractStub<MonsterStorageBlockingStub> {
+    private MonsterStorageBlockingStub(io.grpc.Channel channel) {
+      super(channel);
+    }
+    
+    private MonsterStorageBlockingStub(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+    
+    @java.lang.Override
+    protected MonsterStorageBlockingStub build(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      return new MonsterStorageBlockingStub(channel, callOptions);
+    }
+    
+    /**
+     */
+    public     MyGame.Example.Stat store(MyGame.Example.Monster request)     {
+      return blockingUnaryCall(
+          getChannel(), getStoreMethod(), getCallOptions(), request);
+    }
+    
+    /**
+     */
+    public     java.util.Iterator<MyGame.Example.Monster> retrieve(
+        MyGame.Example.Stat request)     {
+      return blockingServerStreamingCall(
+          getChannel(), getRetrieveMethod(), getCallOptions(), request);
+    }
+  }
+  
+  /**
+   */
+  public static final class MonsterStorageFutureStub extends io.grpc.stub.AbstractStub<MonsterStorageFutureStub> {
+    private MonsterStorageFutureStub(io.grpc.Channel channel) {
+      super(channel);
+    }
+    
+    private MonsterStorageFutureStub(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+    
+    @java.lang.Override
+    protected MonsterStorageFutureStub build(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      return new MonsterStorageFutureStub(channel, callOptions);
+    }
+    
+    /**
+     */
+    public     com.google.common.util.concurrent.ListenableFuture<MyGame.Example.Stat> store(
+        MyGame.Example.Monster request)     {
+      return futureUnaryCall(
+          getChannel().newCall(getStoreMethod(), getCallOptions()), request);
+    }
+  }
+  
+  private static final int METHODID_STORE = 0;
+  private static final int METHODID_RETRIEVE = 1;
+  private static final int METHODID_GET_MIN_MAX_HIT_POINTS = 2;
+  private static final int METHODID_GET_MAX_HIT_POINT = 3;
+  
+  private static final class MethodHandlers<Req, Resp> implements
+      io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> {
+    private final MonsterStorageImplBase serviceImpl;
+    private final int methodId;
+  
+    MethodHandlers(MonsterStorageImplBase serviceImpl, int methodId) {
+      this.serviceImpl = serviceImpl;
+      this.methodId = methodId;
+    }
+  
+    @java.lang.Override
+    @java.lang.SuppressWarnings("unchecked")
+    public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) {
+      switch (methodId) {
+        case METHODID_STORE:
+          serviceImpl.store((MyGame.Example.Monster) request,
+              (io.grpc.stub.StreamObserver<MyGame.Example.Stat>) responseObserver);
+          break;
+        case METHODID_RETRIEVE:
+          serviceImpl.retrieve((MyGame.Example.Stat) request,
+              (io.grpc.stub.StreamObserver<MyGame.Example.Monster>) responseObserver);
+          break;
+        default:
+          throw new AssertionError();
+      }
+    }
+    
+    @java.lang.Override
+    @java.lang.SuppressWarnings("unchecked")
+    public io.grpc.stub.StreamObserver<Req> invoke(
+        io.grpc.stub.StreamObserver<Resp> responseObserver) {
+      switch (methodId) {
+        case METHODID_GET_MAX_HIT_POINT:
+          return (io.grpc.stub.StreamObserver<Req>) serviceImpl.getMaxHitPoint(
+              (io.grpc.stub.StreamObserver<MyGame.Example.Stat>) responseObserver);
+        case METHODID_GET_MIN_MAX_HIT_POINTS:
+          return (io.grpc.stub.StreamObserver<Req>) serviceImpl.getMinMaxHitPoints(
+              (io.grpc.stub.StreamObserver<MyGame.Example.Stat>) responseObserver);
+        default:
+          throw new AssertionError();
+      }
+    }
+  }
+  
+  private static volatile io.grpc.ServiceDescriptor serviceDescriptor;
+  
+  public static io.grpc.ServiceDescriptor getServiceDescriptor() {
+    io.grpc.ServiceDescriptor result = serviceDescriptor;
+    if (result == null) {
+      synchronized (MonsterStorageGrpc.class) {
+        result = serviceDescriptor;
+        if (result == null) {
+          serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)              
+              .setSchemaDescriptor(null)              
+              .addMethod(getStoreMethod())              
+              .addMethod(getRetrieveMethod())              
+              .addMethod(getGetMaxHitPointMethod())              
+              .addMethod(getGetMinMaxHitPointsMethod())              
+              .build();
+        }
+      }
+    }
+    return result;
+  }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/MonsterStorage_grpc.go b/third_party/flatbuffers/tests/MyGame/Example/MonsterStorage_grpc.go
new file mode 100644
index 0000000..deeec29
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/MonsterStorage_grpc.go
@@ -0,0 +1,251 @@
+//Generated by gRPC Go plugin
+//If you make any local changes, they will be lost
+//source: monster_test
+
+package Example
+
+import "github.com/google/flatbuffers/go"
+
+import (
+  context "context"
+  grpc "google.golang.org/grpc"
+)
+
+// Client API for MonsterStorage service
+type MonsterStorageClient interface{
+  Store(ctx context.Context, in *flatbuffers.Builder, 
+  	opts... grpc.CallOption) (* Stat, error)  
+  Retrieve(ctx context.Context, in *flatbuffers.Builder, 
+  	opts... grpc.CallOption) (MonsterStorage_RetrieveClient, error)  
+  GetMaxHitPoint(ctx context.Context, 
+  	opts... grpc.CallOption) (MonsterStorage_GetMaxHitPointClient, error)  
+  GetMinMaxHitPoints(ctx context.Context, 
+  	opts... grpc.CallOption) (MonsterStorage_GetMinMaxHitPointsClient, error)  
+}
+
+type monsterStorageClient struct {
+  cc *grpc.ClientConn
+}
+
+func NewMonsterStorageClient(cc *grpc.ClientConn) MonsterStorageClient {
+  return &monsterStorageClient{cc}
+}
+
+func (c *monsterStorageClient) Store(ctx context.Context, in *flatbuffers.Builder, 
+	opts... grpc.CallOption) (* Stat, error) {
+  out := new(Stat)
+  err := grpc.Invoke(ctx, "/MyGame.Example.MonsterStorage/Store", in, out, c.cc, opts...)
+  if err != nil { return nil, err }
+  return out, nil
+}
+
+func (c *monsterStorageClient) Retrieve(ctx context.Context, in *flatbuffers.Builder, 
+	opts... grpc.CallOption) (MonsterStorage_RetrieveClient, error) {
+  stream, err := grpc.NewClientStream(ctx, &_MonsterStorage_serviceDesc.Streams[0], c.cc, "/MyGame.Example.MonsterStorage/Retrieve", opts...)
+  if err != nil { return nil, err }
+  x := &monsterStorageRetrieveClient{stream}
+  if err := x.ClientStream.SendMsg(in); err != nil { return nil, err }
+  if err := x.ClientStream.CloseSend(); err != nil { return nil, err }
+  return x,nil
+}
+
+type MonsterStorage_RetrieveClient interface {
+  Recv() (*Monster, error)
+  grpc.ClientStream
+}
+
+type monsterStorageRetrieveClient struct{
+  grpc.ClientStream
+}
+
+func (x *monsterStorageRetrieveClient) Recv() (*Monster, error) {
+  m := new(Monster)
+  if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }
+  return m, nil
+}
+
+func (c *monsterStorageClient) GetMaxHitPoint(ctx context.Context, 
+	opts... grpc.CallOption) (MonsterStorage_GetMaxHitPointClient, error) {
+  stream, err := grpc.NewClientStream(ctx, &_MonsterStorage_serviceDesc.Streams[1], c.cc, "/MyGame.Example.MonsterStorage/GetMaxHitPoint", opts...)
+  if err != nil { return nil, err }
+  x := &monsterStorageGetMaxHitPointClient{stream}
+  return x,nil
+}
+
+type MonsterStorage_GetMaxHitPointClient interface {
+  Send(*flatbuffers.Builder) error
+  CloseAndRecv() (*Stat, error)
+  grpc.ClientStream
+}
+
+type monsterStorageGetMaxHitPointClient struct{
+  grpc.ClientStream
+}
+
+func (x *monsterStorageGetMaxHitPointClient) Send(m *flatbuffers.Builder) error {
+  return x.ClientStream.SendMsg(m)
+}
+
+func (x *monsterStorageGetMaxHitPointClient) CloseAndRecv() (*Stat, error) {
+  if err := x.ClientStream.CloseSend(); err != nil { return nil, err }
+  m := new (Stat)
+  if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }
+  return m, nil
+}
+
+func (c *monsterStorageClient) GetMinMaxHitPoints(ctx context.Context, 
+	opts... grpc.CallOption) (MonsterStorage_GetMinMaxHitPointsClient, error) {
+  stream, err := grpc.NewClientStream(ctx, &_MonsterStorage_serviceDesc.Streams[2], c.cc, "/MyGame.Example.MonsterStorage/GetMinMaxHitPoints", opts...)
+  if err != nil { return nil, err }
+  x := &monsterStorageGetMinMaxHitPointsClient{stream}
+  return x,nil
+}
+
+type MonsterStorage_GetMinMaxHitPointsClient interface {
+  Send(*flatbuffers.Builder) error
+  Recv() (*Stat, error)
+  grpc.ClientStream
+}
+
+type monsterStorageGetMinMaxHitPointsClient struct{
+  grpc.ClientStream
+}
+
+func (x *monsterStorageGetMinMaxHitPointsClient) Send(m *flatbuffers.Builder) error {
+  return x.ClientStream.SendMsg(m)
+}
+
+func (x *monsterStorageGetMinMaxHitPointsClient) Recv() (*Stat, error) {
+  m := new(Stat)
+  if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }
+  return m, nil
+}
+
+// Server API for MonsterStorage service
+type MonsterStorageServer interface {
+  Store(context.Context, *Monster) (*flatbuffers.Builder, error)  
+  Retrieve(*Stat, MonsterStorage_RetrieveServer) error  
+  GetMaxHitPoint(MonsterStorage_GetMaxHitPointServer) error  
+  GetMinMaxHitPoints(MonsterStorage_GetMinMaxHitPointsServer) error  
+}
+
+func RegisterMonsterStorageServer(s *grpc.Server, srv MonsterStorageServer) {
+  s.RegisterService(&_MonsterStorage_serviceDesc, srv)
+}
+
+func _MonsterStorage_Store_Handler(srv interface{}, ctx context.Context,
+	dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+  in := new(Monster)
+  if err := dec(in); err != nil { return nil, err }
+  if interceptor == nil { return srv.(MonsterStorageServer).Store(ctx, in) }
+  info := &grpc.UnaryServerInfo{
+    Server: srv,
+    FullMethod: "/MyGame.Example.MonsterStorage/Store",
+  }
+  
+  handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+    return srv.(MonsterStorageServer).Store(ctx, req.(* Monster))
+  }
+  return interceptor(ctx, in, info, handler)
+}
+
+
+func _MonsterStorage_Retrieve_Handler(srv interface{}, stream grpc.ServerStream) error {
+  m := new(Stat)
+  if err := stream.RecvMsg(m); err != nil { return err }
+  return srv.(MonsterStorageServer).Retrieve(m, &monsterStorageRetrieveServer{stream})
+}
+
+type MonsterStorage_RetrieveServer interface { 
+  Send(* flatbuffers.Builder) error
+  grpc.ServerStream
+}
+
+type monsterStorageRetrieveServer struct {
+  grpc.ServerStream
+}
+
+func (x *monsterStorageRetrieveServer) Send(m *flatbuffers.Builder) error {
+  return x.ServerStream.SendMsg(m)
+}
+
+
+func _MonsterStorage_GetMaxHitPoint_Handler(srv interface{}, stream grpc.ServerStream) error {
+  return srv.(MonsterStorageServer).GetMaxHitPoint(&monsterStorageGetMaxHitPointServer{stream})
+}
+
+type MonsterStorage_GetMaxHitPointServer interface { 
+  Recv() (* Monster, error)
+  SendAndClose(* flatbuffers.Builder) error
+  grpc.ServerStream
+}
+
+type monsterStorageGetMaxHitPointServer struct {
+  grpc.ServerStream
+}
+
+func (x *monsterStorageGetMaxHitPointServer) Recv() (*Monster, error) {
+  m := new(Monster)
+  if err := x.ServerStream.RecvMsg(m); err != nil { return nil, err }
+  return m, nil
+}
+
+func (x *monsterStorageGetMaxHitPointServer) SendAndClose(m *flatbuffers.Builder) error {
+  return x.ServerStream.SendMsg(m)
+}
+
+
+func _MonsterStorage_GetMinMaxHitPoints_Handler(srv interface{}, stream grpc.ServerStream) error {
+  return srv.(MonsterStorageServer).GetMinMaxHitPoints(&monsterStorageGetMinMaxHitPointsServer{stream})
+}
+
+type MonsterStorage_GetMinMaxHitPointsServer interface { 
+  Send(* flatbuffers.Builder) error
+  Recv() (* Monster, error)
+  grpc.ServerStream
+}
+
+type monsterStorageGetMinMaxHitPointsServer struct {
+  grpc.ServerStream
+}
+
+func (x *monsterStorageGetMinMaxHitPointsServer) Send(m *flatbuffers.Builder) error {
+  return x.ServerStream.SendMsg(m)
+}
+
+func (x *monsterStorageGetMinMaxHitPointsServer) Recv() (*Monster, error) {
+  m := new(Monster)
+  if err := x.ServerStream.RecvMsg(m); err != nil { return nil, err }
+  return m, nil
+}
+
+
+var _MonsterStorage_serviceDesc = grpc.ServiceDesc{
+  ServiceName: "MyGame.Example.MonsterStorage",
+  HandlerType: (*MonsterStorageServer)(nil),
+  Methods: []grpc.MethodDesc{
+    {
+      MethodName: "Store",
+      Handler: _MonsterStorage_Store_Handler, 
+    },
+  },
+  Streams: []grpc.StreamDesc{
+    {
+      StreamName: "Retrieve",
+      Handler: _MonsterStorage_Retrieve_Handler, 
+      ServerStreams: true,
+    },
+    {
+      StreamName: "GetMaxHitPoint",
+      Handler: _MonsterStorage_GetMaxHitPoint_Handler, 
+      ClientStreams: true,
+    },
+    {
+      StreamName: "GetMinMaxHitPoints",
+      Handler: _MonsterStorage_GetMinMaxHitPoints_Handler, 
+      ServerStreams: true,
+      ClientStreams: true,
+    },
+  },
+}
+
diff --git a/third_party/flatbuffers/tests/MyGame/Example/NestedStruct.cs b/third_party/flatbuffers/tests/MyGame/Example/NestedStruct.cs
new file mode 100644
index 0000000..3f1f2f0
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/NestedStruct.cs
@@ -0,0 +1,40 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct NestedStruct : IFlatbufferObject
+{
+  private Struct __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
+  public NestedStruct __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public int A(int j) { return __p.bb.GetInt(__p.bb_pos + 0 + j * 4); }
+  public void MutateA(int j, int a) { __p.bb.PutInt(__p.bb_pos + 0 + j * 4, a); }
+  public MyGame.Example.TestEnum B { get { return (MyGame.Example.TestEnum)__p.bb.GetSbyte(__p.bb_pos + 8); } }
+  public void MutateB(MyGame.Example.TestEnum b) { __p.bb.PutSbyte(__p.bb_pos + 8, (sbyte)b); }
+  public MyGame.Example.TestEnum C(int j) { return (MyGame.Example.TestEnum)__p.bb.GetSbyte(__p.bb_pos + 9 + j * 1); }
+  public void MutateC(int j, MyGame.Example.TestEnum c) { __p.bb.PutSbyte(__p.bb_pos + 9 + j * 1, (sbyte)c); }
+
+  public static Offset<MyGame.Example.NestedStruct> CreateNestedStruct(FlatBufferBuilder builder, int[] A, MyGame.Example.TestEnum B, MyGame.Example.TestEnum[] C) {
+    builder.Prep(4, 12);
+    builder.Pad(1);
+    for (int _idx0 = 2; _idx0 > 0; _idx0--) {
+      builder.PutSbyte((sbyte)C[_idx0-1]);
+    }
+    builder.PutSbyte((sbyte)B);
+    for (int _idx0 = 2; _idx0 > 0; _idx0--) {
+      builder.PutInt(A[_idx0-1]);
+    }
+    return new Offset<MyGame.Example.NestedStruct>(builder.Offset);
+  }
+};
+
+
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/NestedStruct.java b/third_party/flatbuffers/tests/MyGame/Example/NestedStruct.java
new file mode 100644
index 0000000..3c8a8f6
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/NestedStruct.java
@@ -0,0 +1,35 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class NestedStruct extends Struct {
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public NestedStruct __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public int a(int j) { return bb.getInt(bb_pos + 0 + j * 4); }
+  public void mutateA(int j, int a) { bb.putInt(bb_pos + 0 + j * 4, a); }
+  public byte b() { return bb.get(bb_pos + 8); }
+  public void mutateB(byte b) { bb.put(bb_pos + 8, b); }
+  public byte c(int j) { return bb.get(bb_pos + 9 + j * 1); }
+  public void mutateC(int j, byte c) { bb.put(bb_pos + 9 + j * 1, c); }
+
+  public static int createNestedStruct(FlatBufferBuilder builder, int[] a, byte b, byte[] c) {
+    builder.prep(4, 12);
+    builder.pad(1);
+    for (int _idx0 = 2; _idx0 > 0; _idx0--) {
+      builder.putByte(c[_idx0-1]);
+    }
+    builder.putByte(b);
+    for (int _idx0 = 2; _idx0 > 0; _idx0--) {
+      builder.putInt(a[_idx0-1]);
+    }
+    return builder.offset();
+  }
+}
+
diff --git a/third_party/flatbuffers/tests/MyGame/Example/NestedStruct.py b/third_party/flatbuffers/tests/MyGame/Example/NestedStruct.py
new file mode 100644
index 0000000..aa742f4
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/NestedStruct.py
@@ -0,0 +1,29 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+import flatbuffers
+
+class NestedStruct(object):
+    __slots__ = ['_tab']
+
+    # NestedStruct
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # NestedStruct
+    def A(self): return [self._tab.Get(flatbuffers.number_types.Int32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(0 + i * 4)) for i in range(2)]
+    # NestedStruct
+    def B(self): return self._tab.Get(flatbuffers.number_types.Int8Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(8))
+    # NestedStruct
+    def C(self): return [self._tab.Get(flatbuffers.number_types.Int8Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(9 + i * 1)) for i in range(2)]
+
+def CreateNestedStruct(builder, a, b, c):
+    builder.Prep(4, 12)
+    builder.Pad(1)
+    for _idx0 in range(2 , 0, -1):
+        builder.PrependInt8(c[_idx0-1])
+    builder.PrependInt8(b)
+    for _idx0 in range(2 , 0, -1):
+        builder.PrependInt32(a[_idx0-1])
+    return builder.Offset()
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Referrable.cs b/third_party/flatbuffers/tests/MyGame/Example/Referrable.cs
new file mode 100644
index 0000000..5a79f91
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Referrable.cs
@@ -0,0 +1,65 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct Referrable : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static Referrable GetRootAsReferrable(ByteBuffer _bb) { return GetRootAsReferrable(_bb, new Referrable()); }
+  public static Referrable GetRootAsReferrable(ByteBuffer _bb, Referrable obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public Referrable __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public ulong Id { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetUlong(o + __p.bb_pos) : (ulong)0; } }
+  public bool MutateId(ulong id) { int o = __p.__offset(4); if (o != 0) { __p.bb.PutUlong(o + __p.bb_pos, id); return true; } else { return false; } }
+
+  public static Offset<MyGame.Example.Referrable> CreateReferrable(FlatBufferBuilder builder,
+      ulong id = 0) {
+    builder.StartTable(1);
+    Referrable.AddId(builder, id);
+    return Referrable.EndReferrable(builder);
+  }
+
+  public static void StartReferrable(FlatBufferBuilder builder) { builder.StartTable(1); }
+  public static void AddId(FlatBufferBuilder builder, ulong id) { builder.AddUlong(0, id, 0); }
+  public static Offset<MyGame.Example.Referrable> EndReferrable(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<MyGame.Example.Referrable>(o);
+  }
+
+  public static VectorOffset CreateSortedVectorOfReferrable(FlatBufferBuilder builder, Offset<Referrable>[] offsets) {
+    Array.Sort(offsets, (Offset<Referrable> o1, Offset<Referrable> o2) => builder.DataBuffer.GetUlong(Table.__offset(4, o1.Value, builder.DataBuffer)).CompareTo(builder.DataBuffer.GetUlong(Table.__offset(4, o2.Value, builder.DataBuffer))));
+    return builder.CreateVectorOfTables(offsets);
+  }
+
+  public static Referrable? __lookup_by_key(int vectorLocation, ulong key, ByteBuffer bb) {
+    int span = bb.GetInt(vectorLocation - 4);
+    int start = 0;
+    while (span != 0) {
+      int middle = span / 2;
+      int tableOffset = Table.__indirect(vectorLocation + 4 * (start + middle), bb);
+      int comp = bb.GetUlong(Table.__offset(4, bb.Length - tableOffset, bb)).CompareTo(key);
+      if (comp > 0) {
+        span = middle;
+      } else if (comp < 0) {
+        middle++;
+        start += middle;
+        span -= middle;
+      } else {
+        return new Referrable().__assign(tableOffset, bb);
+      }
+    }
+    return null;
+  }
+};
+
+
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Referrable.go b/third_party/flatbuffers/tests/MyGame/Example/Referrable.go
new file mode 100644
index 0000000..0fb06fb
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Referrable.go
@@ -0,0 +1,49 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package Example
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+
+type Referrable struct {
+	_tab flatbuffers.Table
+}
+
+func GetRootAsReferrable(buf []byte, offset flatbuffers.UOffsetT) *Referrable {
+	n := flatbuffers.GetUOffsetT(buf[offset:])
+	x := &Referrable{}
+	x.Init(buf, n+offset)
+	return x
+}
+
+func (rcv *Referrable) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *Referrable) Table() flatbuffers.Table {
+	return rcv._tab
+}
+
+func (rcv *Referrable) Id() uint64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+	if o != 0 {
+		return rcv._tab.GetUint64(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Referrable) MutateId(n uint64) bool {
+	return rcv._tab.MutateUint64Slot(4, n)
+}
+
+func ReferrableStart(builder *flatbuffers.Builder) {
+	builder.StartObject(1)
+}
+func ReferrableAddId(builder *flatbuffers.Builder, id uint64) {
+	builder.PrependUint64Slot(0, id, 0)
+}
+func ReferrableEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+	return builder.EndObject()
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Referrable.java b/third_party/flatbuffers/tests/MyGame/Example/Referrable.java
new file mode 100644
index 0000000..f154857
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Referrable.java
@@ -0,0 +1,63 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class Referrable extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static Referrable getRootAsReferrable(ByteBuffer _bb) { return getRootAsReferrable(_bb, new Referrable()); }
+  public static Referrable getRootAsReferrable(ByteBuffer _bb, Referrable obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public Referrable __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public long id() { int o = __offset(4); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
+  public boolean mutateId(long id) { int o = __offset(4); if (o != 0) { bb.putLong(o + bb_pos, id); return true; } else { return false; } }
+
+  public static int createReferrable(FlatBufferBuilder builder,
+      long id) {
+    builder.startTable(1);
+    Referrable.addId(builder, id);
+    return Referrable.endReferrable(builder);
+  }
+
+  public static void startReferrable(FlatBufferBuilder builder) { builder.startTable(1); }
+  public static void addId(FlatBufferBuilder builder, long id) { builder.addLong(0, id, 0L); }
+  public static int endReferrable(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+
+  @Override
+  protected int keysCompare(Integer o1, Integer o2, ByteBuffer _bb) {
+    long val_1 = _bb.getLong(__offset(4, o1, _bb));
+    long val_2 = _bb.getLong(__offset(4, o2, _bb));
+    return val_1 > val_2 ? 1 : val_1 < val_2 ? -1 : 0;
+  }
+
+  public static Referrable __lookup_by_key(Referrable obj, int vectorLocation, long key, ByteBuffer bb) {
+    int span = bb.getInt(vectorLocation - 4);
+    int start = 0;
+    while (span != 0) {
+      int middle = span / 2;
+      int tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb);
+      long val = bb.getLong(__offset(4, bb.capacity() - tableOffset, bb));
+      int comp = val > key ? 1 : val < key ? -1 : 0;
+      if (comp > 0) {
+        span = middle;
+      } else if (comp < 0) {
+        middle++;
+        start += middle;
+        span -= middle;
+      } else {
+        return (obj == null ? new Referrable() : obj).__assign(tableOffset, bb);
+      }
+    }
+    return null;
+  }
+}
+
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Referrable.kt b/third_party/flatbuffers/tests/MyGame/Example/Referrable.kt
new file mode 100644
index 0000000..55ff1d8
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Referrable.kt
@@ -0,0 +1,80 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Referrable : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : Referrable {
+        __init(_i, _bb)
+        return this
+    }
+    val id : ULong
+        get() {
+            val o = __offset(4)
+            return if(o != 0) bb.getLong(o + bb_pos).toULong() else 0UL
+        }
+    fun mutateId(id: ULong) : Boolean {
+        val o = __offset(4)
+        return if (o != 0) {
+            bb.putLong(o + bb_pos, id.toLong())
+            true
+        } else {
+            false
+        }
+    }
+    override fun keysCompare(o1: Int, o2: Int, _bb: ByteBuffer) : Int {
+        val val_1 = _bb.getLong(__offset(4, o1, _bb))
+        val val_2 = _bb.getLong(__offset(4, o2, _bb))
+        return (val_1 - val_2).sign
+    }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsReferrable(_bb: ByteBuffer): Referrable = getRootAsReferrable(_bb, Referrable())
+        fun getRootAsReferrable(_bb: ByteBuffer, obj: Referrable): Referrable {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun createReferrable(builder: FlatBufferBuilder, id: ULong) : Int {
+            builder.startTable(1)
+            addId(builder, id)
+            return endReferrable(builder)
+        }
+        fun startReferrable(builder: FlatBufferBuilder) = builder.startTable(1)
+        fun addId(builder: FlatBufferBuilder, id: ULong) = builder.addLong(0, id.toLong(), 0)
+        fun endReferrable(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+            return o
+        }
+        fun __lookup_by_key(obj: Referrable?, vectorLocation: Int, key: ULong, bb: ByteBuffer) : Referrable? {
+            var span = bb.getInt(vectorLocation - 4)
+            var start = 0
+            while (span != 0) {
+                var middle = span / 2
+                val tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb)
+                val value = bb.getLong(__offset(4, bb.capacity() - tableOffset, bb)).toULong()
+                val comp = value.compareTo(key)
+                when {
+                    comp > 0 -> span = middle
+                    comp < 0 -> {
+                        middle++
+                        start += middle
+                        span -= middle
+                    }
+                    else -> {
+                        return (obj ?: Referrable()).__assign(tableOffset, bb)
+                    }
+                }
+            }
+            return null
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Referrable.lua b/third_party/flatbuffers/tests/MyGame/Example/Referrable.lua
new file mode 100644
index 0000000..9b0f5a1
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Referrable.lua
@@ -0,0 +1,35 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Example
+
+local flatbuffers = require('flatbuffers')
+
+local Referrable = {} -- the module
+local Referrable_mt = {} -- the class metatable
+
+function Referrable.New()
+    local o = {}
+    setmetatable(o, {__index = Referrable_mt})
+    return o
+end
+function Referrable.GetRootAsReferrable(buf, offset)
+    local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)
+    local o = Referrable.New()
+    o:Init(buf, n + offset)
+    return o
+end
+function Referrable_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function Referrable_mt:Id()
+    local o = self.view:Offset(4)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint64, o + self.view.pos)
+    end
+    return 0
+end
+function Referrable.Start(builder) builder:StartObject(1) end
+function Referrable.AddId(builder, id) builder:PrependUint64Slot(0, id, 0) end
+function Referrable.End(builder) return builder:EndObject() end
+
+return Referrable -- return the module
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Referrable.php b/third_party/flatbuffers/tests/MyGame/Example/Referrable.php
new file mode 100644
index 0000000..5844011
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Referrable.php
@@ -0,0 +1,99 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame\Example;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class Referrable extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return Referrable
+     */
+    public static function getRootAsReferrable(ByteBuffer $bb)
+    {
+        $obj = new Referrable();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    public static function ReferrableIdentifier()
+    {
+        return "MONS";
+    }
+
+    public static function ReferrableBufferHasIdentifier(ByteBuffer $buf)
+    {
+        return self::__has_identifier($buf, self::ReferrableIdentifier());
+    }
+
+    public static function ReferrableExtension()
+    {
+        return "mon";
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return Referrable
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @return ulong
+     */
+    public function getId()
+    {
+        $o = $this->__offset(4);
+        return $o != 0 ? $this->bb->getUlong($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startReferrable(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(1);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return Referrable
+     */
+    public static function createReferrable(FlatBufferBuilder $builder, $id)
+    {
+        $builder->startObject(1);
+        self::addId($builder, $id);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param ulong
+     * @return void
+     */
+    public static function addId(FlatBufferBuilder $builder, $id)
+    {
+        $builder->addUlongX(0, $id, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endReferrable(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Referrable.py b/third_party/flatbuffers/tests/MyGame/Example/Referrable.py
new file mode 100644
index 0000000..eaec09b
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Referrable.py
@@ -0,0 +1,34 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+import flatbuffers
+
+class Referrable(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAsReferrable(cls, buf, offset):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = Referrable()
+        x.Init(buf, n + offset)
+        return x
+
+    @classmethod
+    def ReferrableBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
+        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)
+
+    # Referrable
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # Referrable
+    def Id(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
+        return 0
+
+def ReferrableStart(builder): builder.StartObject(1)
+def ReferrableAddId(builder, id): builder.PrependUint64Slot(0, id, 0)
+def ReferrableEnd(builder): return builder.EndObject()
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Stat.cs b/third_party/flatbuffers/tests/MyGame/Example/Stat.cs
new file mode 100644
index 0000000..bcd1004
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Stat.cs
@@ -0,0 +1,55 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct Stat : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static Stat GetRootAsStat(ByteBuffer _bb) { return GetRootAsStat(_bb, new Stat()); }
+  public static Stat GetRootAsStat(ByteBuffer _bb, Stat obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public Stat __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public string Id { get { int o = __p.__offset(4); return o != 0 ? __p.__string(o + __p.bb_pos) : null; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetIdBytes() { return __p.__vector_as_span(4); }
+#else
+  public ArraySegment<byte>? GetIdBytes() { return __p.__vector_as_arraysegment(4); }
+#endif
+  public byte[] GetIdArray() { return __p.__vector_as_array<byte>(4); }
+  public long Val { get { int o = __p.__offset(6); return o != 0 ? __p.bb.GetLong(o + __p.bb_pos) : (long)0; } }
+  public bool MutateVal(long val) { int o = __p.__offset(6); if (o != 0) { __p.bb.PutLong(o + __p.bb_pos, val); return true; } else { return false; } }
+  public ushort Count { get { int o = __p.__offset(8); return o != 0 ? __p.bb.GetUshort(o + __p.bb_pos) : (ushort)0; } }
+  public bool MutateCount(ushort count) { int o = __p.__offset(8); if (o != 0) { __p.bb.PutUshort(o + __p.bb_pos, count); return true; } else { return false; } }
+
+  public static Offset<MyGame.Example.Stat> CreateStat(FlatBufferBuilder builder,
+      StringOffset idOffset = default(StringOffset),
+      long val = 0,
+      ushort count = 0) {
+    builder.StartTable(3);
+    Stat.AddVal(builder, val);
+    Stat.AddId(builder, idOffset);
+    Stat.AddCount(builder, count);
+    return Stat.EndStat(builder);
+  }
+
+  public static void StartStat(FlatBufferBuilder builder) { builder.StartTable(3); }
+  public static void AddId(FlatBufferBuilder builder, StringOffset idOffset) { builder.AddOffset(0, idOffset.Value, 0); }
+  public static void AddVal(FlatBufferBuilder builder, long val) { builder.AddLong(1, val, 0); }
+  public static void AddCount(FlatBufferBuilder builder, ushort count) { builder.AddUshort(2, count, 0); }
+  public static Offset<MyGame.Example.Stat> EndStat(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<MyGame.Example.Stat>(o);
+  }
+};
+
+
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Stat.go b/third_party/flatbuffers/tests/MyGame/Example/Stat.go
new file mode 100644
index 0000000..401712f
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Stat.go
@@ -0,0 +1,75 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package Example
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+
+type Stat struct {
+	_tab flatbuffers.Table
+}
+
+func GetRootAsStat(buf []byte, offset flatbuffers.UOffsetT) *Stat {
+	n := flatbuffers.GetUOffsetT(buf[offset:])
+	x := &Stat{}
+	x.Init(buf, n+offset)
+	return x
+}
+
+func (rcv *Stat) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *Stat) Table() flatbuffers.Table {
+	return rcv._tab
+}
+
+func (rcv *Stat) Id() []byte {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+	if o != 0 {
+		return rcv._tab.ByteVector(o + rcv._tab.Pos)
+	}
+	return nil
+}
+
+func (rcv *Stat) Val() int64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
+	if o != 0 {
+		return rcv._tab.GetInt64(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Stat) MutateVal(n int64) bool {
+	return rcv._tab.MutateInt64Slot(6, n)
+}
+
+func (rcv *Stat) Count() uint16 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
+	if o != 0 {
+		return rcv._tab.GetUint16(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *Stat) MutateCount(n uint16) bool {
+	return rcv._tab.MutateUint16Slot(8, n)
+}
+
+func StatStart(builder *flatbuffers.Builder) {
+	builder.StartObject(3)
+}
+func StatAddId(builder *flatbuffers.Builder, id flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(id), 0)
+}
+func StatAddVal(builder *flatbuffers.Builder, val int64) {
+	builder.PrependInt64Slot(1, val, 0)
+}
+func StatAddCount(builder *flatbuffers.Builder, count uint16) {
+	builder.PrependUint16Slot(2, count, 0)
+}
+func StatEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+	return builder.EndObject()
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Stat.java b/third_party/flatbuffers/tests/MyGame/Example/Stat.java
new file mode 100644
index 0000000..58d34f3
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Stat.java
@@ -0,0 +1,46 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class Stat extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static Stat getRootAsStat(ByteBuffer _bb) { return getRootAsStat(_bb, new Stat()); }
+  public static Stat getRootAsStat(ByteBuffer _bb, Stat obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public Stat __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public String id() { int o = __offset(4); return o != 0 ? __string(o + bb_pos) : null; }
+  public ByteBuffer idAsByteBuffer() { return __vector_as_bytebuffer(4, 1); }
+  public ByteBuffer idInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 4, 1); }
+  public long val() { int o = __offset(6); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
+  public boolean mutateVal(long val) { int o = __offset(6); if (o != 0) { bb.putLong(o + bb_pos, val); return true; } else { return false; } }
+  public int count() { int o = __offset(8); return o != 0 ? bb.getShort(o + bb_pos) & 0xFFFF : 0; }
+  public boolean mutateCount(int count) { int o = __offset(8); if (o != 0) { bb.putShort(o + bb_pos, (short)count); return true; } else { return false; } }
+
+  public static int createStat(FlatBufferBuilder builder,
+      int idOffset,
+      long val,
+      int count) {
+    builder.startTable(3);
+    Stat.addVal(builder, val);
+    Stat.addId(builder, idOffset);
+    Stat.addCount(builder, count);
+    return Stat.endStat(builder);
+  }
+
+  public static void startStat(FlatBufferBuilder builder) { builder.startTable(3); }
+  public static void addId(FlatBufferBuilder builder, int idOffset) { builder.addOffset(0, idOffset, 0); }
+  public static void addVal(FlatBufferBuilder builder, long val) { builder.addLong(1, val, 0L); }
+  public static void addCount(FlatBufferBuilder builder, int count) { builder.addShort(2, (short)count, (short)0); }
+  public static int endStat(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+}
+
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Stat.kt b/third_party/flatbuffers/tests/MyGame/Example/Stat.kt
new file mode 100644
index 0000000..26b293c
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Stat.kt
@@ -0,0 +1,78 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Stat : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : Stat {
+        __init(_i, _bb)
+        return this
+    }
+    val id : String?
+        get() {
+            val o = __offset(4)
+            return if (o != 0) __string(o + bb_pos) else null
+        }
+    val idAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(4, 1)
+    fun idInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 4, 1)
+    val val_ : Long
+        get() {
+            val o = __offset(6)
+            return if(o != 0) bb.getLong(o + bb_pos) else 0L
+        }
+    fun mutateVal_(val_: Long) : Boolean {
+        val o = __offset(6)
+        return if (o != 0) {
+            bb.putLong(o + bb_pos, val_)
+            true
+        } else {
+            false
+        }
+    }
+    val count : UShort
+        get() {
+            val o = __offset(8)
+            return if(o != 0) bb.getShort(o + bb_pos).toUShort() else 0u
+        }
+    fun mutateCount(count: UShort) : Boolean {
+        val o = __offset(8)
+        return if (o != 0) {
+            bb.putShort(o + bb_pos, count.toShort())
+            true
+        } else {
+            false
+        }
+    }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsStat(_bb: ByteBuffer): Stat = getRootAsStat(_bb, Stat())
+        fun getRootAsStat(_bb: ByteBuffer, obj: Stat): Stat {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun createStat(builder: FlatBufferBuilder, idOffset: Int, val_: Long, count: UShort) : Int {
+            builder.startTable(3)
+            addVal_(builder, val_)
+            addId(builder, idOffset)
+            addCount(builder, count)
+            return endStat(builder)
+        }
+        fun startStat(builder: FlatBufferBuilder) = builder.startTable(3)
+        fun addId(builder: FlatBufferBuilder, id: Int) = builder.addOffset(0, id, 0)
+        fun addVal_(builder: FlatBufferBuilder, val_: Long) = builder.addLong(1, val_, 0L)
+        fun addCount(builder: FlatBufferBuilder, count: UShort) = builder.addShort(2, count.toShort(), 0)
+        fun endStat(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+            return o
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Stat.lua b/third_party/flatbuffers/tests/MyGame/Example/Stat.lua
new file mode 100644
index 0000000..6999184
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Stat.lua
@@ -0,0 +1,50 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Example
+
+local flatbuffers = require('flatbuffers')
+
+local Stat = {} -- the module
+local Stat_mt = {} -- the class metatable
+
+function Stat.New()
+    local o = {}
+    setmetatable(o, {__index = Stat_mt})
+    return o
+end
+function Stat.GetRootAsStat(buf, offset)
+    local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)
+    local o = Stat.New()
+    o:Init(buf, n + offset)
+    return o
+end
+function Stat_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function Stat_mt:Id()
+    local o = self.view:Offset(4)
+    if o ~= 0 then
+        return self.view:String(o + self.view.pos)
+    end
+end
+function Stat_mt:Val()
+    local o = self.view:Offset(6)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int64, o + self.view.pos)
+    end
+    return 0
+end
+function Stat_mt:Count()
+    local o = self.view:Offset(8)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint16, o + self.view.pos)
+    end
+    return 0
+end
+function Stat.Start(builder) builder:StartObject(3) end
+function Stat.AddId(builder, id) builder:PrependUOffsetTRelativeSlot(0, id, 0) end
+function Stat.AddVal(builder, val) builder:PrependInt64Slot(1, val, 0) end
+function Stat.AddCount(builder, count) builder:PrependUint16Slot(2, count, 0) end
+function Stat.End(builder) return builder:EndObject() end
+
+return Stat -- return the module
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Stat.php b/third_party/flatbuffers/tests/MyGame/Example/Stat.php
new file mode 100644
index 0000000..6ef7034
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Stat.php
@@ -0,0 +1,136 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame\Example;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class Stat extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return Stat
+     */
+    public static function getRootAsStat(ByteBuffer $bb)
+    {
+        $obj = new Stat();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    public static function StatIdentifier()
+    {
+        return "MONS";
+    }
+
+    public static function StatBufferHasIdentifier(ByteBuffer $buf)
+    {
+        return self::__has_identifier($buf, self::StatIdentifier());
+    }
+
+    public static function StatExtension()
+    {
+        return "mon";
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return Stat
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    public function getId()
+    {
+        $o = $this->__offset(4);
+        return $o != 0 ? $this->__string($o + $this->bb_pos) : null;
+    }
+
+    /**
+     * @return long
+     */
+    public function getVal()
+    {
+        $o = $this->__offset(6);
+        return $o != 0 ? $this->bb->getLong($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return ushort
+     */
+    public function getCount()
+    {
+        $o = $this->__offset(8);
+        return $o != 0 ? $this->bb->getUshort($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startStat(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(3);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return Stat
+     */
+    public static function createStat(FlatBufferBuilder $builder, $id, $val, $count)
+    {
+        $builder->startObject(3);
+        self::addId($builder, $id);
+        self::addVal($builder, $val);
+        self::addCount($builder, $count);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param StringOffset
+     * @return void
+     */
+    public static function addId(FlatBufferBuilder $builder, $id)
+    {
+        $builder->addOffsetX(0, $id, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param long
+     * @return void
+     */
+    public static function addVal(FlatBufferBuilder $builder, $val)
+    {
+        $builder->addLongX(1, $val, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param ushort
+     * @return void
+     */
+    public static function addCount(FlatBufferBuilder $builder, $count)
+    {
+        $builder->addUshortX(2, $count, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endStat(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Stat.py b/third_party/flatbuffers/tests/MyGame/Example/Stat.py
new file mode 100644
index 0000000..0fbd2a7
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Stat.py
@@ -0,0 +1,50 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+import flatbuffers
+
+class Stat(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAsStat(cls, buf, offset):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = Stat()
+        x.Init(buf, n + offset)
+        return x
+
+    @classmethod
+    def StatBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
+        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)
+
+    # Stat
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # Stat
+    def Id(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        if o != 0:
+            return self._tab.String(o + self._tab.Pos)
+        return None
+
+    # Stat
+    def Val(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int64Flags, o + self._tab.Pos)
+        return 0
+
+    # Stat
+    def Count(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint16Flags, o + self._tab.Pos)
+        return 0
+
+def StatStart(builder): builder.StartObject(3)
+def StatAddId(builder, id): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(id), 0)
+def StatAddVal(builder, val): builder.PrependInt64Slot(1, val, 0)
+def StatAddCount(builder, count): builder.PrependUint16Slot(2, count, 0)
+def StatEnd(builder): return builder.EndObject()
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Test.cs b/third_party/flatbuffers/tests/MyGame/Example/Test.cs
new file mode 100644
index 0000000..cd91454
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Test.cs
@@ -0,0 +1,33 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct Test : IFlatbufferObject
+{
+  private Struct __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
+  public Test __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public short A { get { return __p.bb.GetShort(__p.bb_pos + 0); } }
+  public void MutateA(short a) { __p.bb.PutShort(__p.bb_pos + 0, a); }
+  public sbyte B { get { return __p.bb.GetSbyte(__p.bb_pos + 2); } }
+  public void MutateB(sbyte b) { __p.bb.PutSbyte(__p.bb_pos + 2, b); }
+
+  public static Offset<MyGame.Example.Test> CreateTest(FlatBufferBuilder builder, short A, sbyte B) {
+    builder.Prep(2, 4);
+    builder.Pad(1);
+    builder.PutSbyte(B);
+    builder.PutShort(A);
+    return new Offset<MyGame.Example.Test>(builder.Offset);
+  }
+};
+
+
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Test.go b/third_party/flatbuffers/tests/MyGame/Example/Test.go
new file mode 100644
index 0000000..53f53fd
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Test.go
@@ -0,0 +1,42 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package Example
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+
+type Test struct {
+	_tab flatbuffers.Struct
+}
+
+func (rcv *Test) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *Test) Table() flatbuffers.Table {
+	return rcv._tab.Table
+}
+
+func (rcv *Test) A() int16 {
+	return rcv._tab.GetInt16(rcv._tab.Pos + flatbuffers.UOffsetT(0))
+}
+func (rcv *Test) MutateA(n int16) bool {
+	return rcv._tab.MutateInt16(rcv._tab.Pos+flatbuffers.UOffsetT(0), n)
+}
+
+func (rcv *Test) B() int8 {
+	return rcv._tab.GetInt8(rcv._tab.Pos + flatbuffers.UOffsetT(2))
+}
+func (rcv *Test) MutateB(n int8) bool {
+	return rcv._tab.MutateInt8(rcv._tab.Pos+flatbuffers.UOffsetT(2), n)
+}
+
+func CreateTest(builder *flatbuffers.Builder, a int16, b int8) flatbuffers.UOffsetT {
+	builder.Prep(2, 4)
+	builder.Pad(1)
+	builder.PrependInt8(b)
+	builder.PrependInt16(a)
+	return builder.Offset()
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Test.java b/third_party/flatbuffers/tests/MyGame/Example/Test.java
new file mode 100644
index 0000000..83fdeb0
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Test.java
@@ -0,0 +1,28 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class Test extends Struct {
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public Test __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public short a() { return bb.getShort(bb_pos + 0); }
+  public void mutateA(short a) { bb.putShort(bb_pos + 0, a); }
+  public byte b() { return bb.get(bb_pos + 2); }
+  public void mutateB(byte b) { bb.put(bb_pos + 2, b); }
+
+  public static int createTest(FlatBufferBuilder builder, short a, byte b) {
+    builder.prep(2, 4);
+    builder.pad(1);
+    builder.putByte(b);
+    builder.putShort(a);
+    return builder.offset();
+  }
+}
+
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Test.kt b/third_party/flatbuffers/tests/MyGame/Example/Test.kt
new file mode 100644
index 0000000..f2ceed6
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Test.kt
@@ -0,0 +1,33 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Test : Struct() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : Test {
+        __init(_i, _bb)
+        return this
+    }
+    val a : Short get() = bb.getShort(bb_pos + 0)
+    fun mutateA(a: Short) : ByteBuffer = bb.putShort(bb_pos + 0, a)
+    val b : Byte get() = bb.get(bb_pos + 2)
+    fun mutateB(b: Byte) : ByteBuffer = bb.put(bb_pos + 2, b)
+    companion object {
+        fun createTest(builder: FlatBufferBuilder, a: Short, b: Byte) : Int {
+            builder.prep(2, 4)
+            builder.pad(1)
+            builder.putByte(b)
+            builder.putShort(a)
+            return builder.offset()
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Test.lua b/third_party/flatbuffers/tests/MyGame/Example/Test.lua
new file mode 100644
index 0000000..154067b
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Test.lua
@@ -0,0 +1,32 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Example
+
+local flatbuffers = require('flatbuffers')
+
+local Test = {} -- the module
+local Test_mt = {} -- the class metatable
+
+function Test.New()
+    local o = {}
+    setmetatable(o, {__index = Test_mt})
+    return o
+end
+function Test_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function Test_mt:A()
+    return self.view:Get(flatbuffers.N.Int16, self.view.pos + 0)
+end
+function Test_mt:B()
+    return self.view:Get(flatbuffers.N.Int8, self.view.pos + 2)
+end
+function Test.CreateTest(builder, a, b)
+    builder:Prep(2, 4)
+    builder:Pad(1)
+    builder:PrependInt8(b)
+    builder:PrependInt16(a)
+    return builder:Offset()
+end
+
+return Test -- return the module
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Test.php b/third_party/flatbuffers/tests/MyGame/Example/Test.php
new file mode 100644
index 0000000..13cced0
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Test.php
@@ -0,0 +1,53 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame\Example;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class Test extends Struct
+{
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return Test
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @return short
+     */
+    public function GetA()
+    {
+        return $this->bb->getShort($this->bb_pos + 0);
+    }
+
+    /**
+     * @return sbyte
+     */
+    public function GetB()
+    {
+        return $this->bb->getSbyte($this->bb_pos + 2);
+    }
+
+
+    /**
+     * @return int offset
+     */
+    public static function createTest(FlatBufferBuilder $builder, $a, $b)
+    {
+        $builder->prep(2, 4);
+        $builder->pad(1);
+        $builder->putSbyte($b);
+        $builder->putShort($a);
+        return $builder->offset();
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Test.py b/third_party/flatbuffers/tests/MyGame/Example/Test.py
new file mode 100644
index 0000000..3b2fd45
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Test.py
@@ -0,0 +1,24 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+import flatbuffers
+
+class Test(object):
+    __slots__ = ['_tab']
+
+    # Test
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # Test
+    def A(self): return self._tab.Get(flatbuffers.number_types.Int16Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(0))
+    # Test
+    def B(self): return self._tab.Get(flatbuffers.number_types.Int8Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(2))
+
+def CreateTest(builder, a, b):
+    builder.Prep(2, 4)
+    builder.Pad(1)
+    builder.PrependInt8(b)
+    builder.PrependInt16(a)
+    return builder.Offset()
diff --git a/third_party/flatbuffers/tests/MyGame/Example/TestEnum.cs b/third_party/flatbuffers/tests/MyGame/Example/TestEnum.cs
new file mode 100644
index 0000000..22e83b3
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/TestEnum.cs
@@ -0,0 +1,16 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+public enum TestEnum : sbyte
+{
+  A = 0,
+  B = 1,
+  C = 2,
+};
+
+
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/TestEnum.java b/third_party/flatbuffers/tests/MyGame/Example/TestEnum.java
new file mode 100644
index 0000000..411bf8e
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/TestEnum.java
@@ -0,0 +1,15 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+public final class TestEnum {
+  private TestEnum() { }
+  public static final byte A = 0;
+  public static final byte B = 1;
+  public static final byte C = 2;
+
+  public static final String[] names = { "A", "B", "C", };
+
+  public static String name(int e) { return names[e]; }
+}
+
diff --git a/third_party/flatbuffers/tests/MyGame/Example/TestEnum.kt b/third_party/flatbuffers/tests/MyGame/Example/TestEnum.kt
new file mode 100644
index 0000000..ca4d7f8
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/TestEnum.kt
@@ -0,0 +1,14 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+@Suppress("unused")
+class TestEnum private constructor() {
+    companion object {
+        const val A: Byte = 0
+        const val B: Byte = 1
+        const val C: Byte = 2
+        val names : Array<String> = arrayOf("A", "B", "C")
+        fun name(e: Int) : String = names[e]
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/TestEnum.py b/third_party/flatbuffers/tests/MyGame/Example/TestEnum.py
new file mode 100644
index 0000000..d49f10a
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/TestEnum.py
@@ -0,0 +1,9 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+class TestEnum(object):
+    A = 0
+    B = 1
+    C = 2
+
diff --git a/third_party/flatbuffers/tests/MyGame/Example/TestSimpleTableWithEnum.cs b/third_party/flatbuffers/tests/MyGame/Example/TestSimpleTableWithEnum.cs
new file mode 100644
index 0000000..f9ac42e
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/TestSimpleTableWithEnum.cs
@@ -0,0 +1,40 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+using global::System;
+using global::FlatBuffers;
+
+internal partial struct TestSimpleTableWithEnum : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static TestSimpleTableWithEnum GetRootAsTestSimpleTableWithEnum(ByteBuffer _bb) { return GetRootAsTestSimpleTableWithEnum(_bb, new TestSimpleTableWithEnum()); }
+  public static TestSimpleTableWithEnum GetRootAsTestSimpleTableWithEnum(ByteBuffer _bb, TestSimpleTableWithEnum obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public TestSimpleTableWithEnum __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public MyGame.Example.Color Color { get { int o = __p.__offset(4); return o != 0 ? (MyGame.Example.Color)__p.bb.Get(o + __p.bb_pos) : MyGame.Example.Color.Green; } }
+  public bool MutateColor(MyGame.Example.Color color) { int o = __p.__offset(4); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)color); return true; } else { return false; } }
+
+  public static Offset<MyGame.Example.TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(FlatBufferBuilder builder,
+      MyGame.Example.Color color = MyGame.Example.Color.Green) {
+    builder.StartTable(1);
+    TestSimpleTableWithEnum.AddColor(builder, color);
+    return TestSimpleTableWithEnum.EndTestSimpleTableWithEnum(builder);
+  }
+
+  public static void StartTestSimpleTableWithEnum(FlatBufferBuilder builder) { builder.StartTable(1); }
+  public static void AddColor(FlatBufferBuilder builder, MyGame.Example.Color color) { builder.AddByte(0, (byte)color, 2); }
+  public static Offset<MyGame.Example.TestSimpleTableWithEnum> EndTestSimpleTableWithEnum(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<MyGame.Example.TestSimpleTableWithEnum>(o);
+  }
+};
+
+
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/TestSimpleTableWithEnum.go b/third_party/flatbuffers/tests/MyGame/Example/TestSimpleTableWithEnum.go
new file mode 100644
index 0000000..35a6c7c
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/TestSimpleTableWithEnum.go
@@ -0,0 +1,49 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package Example
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+
+type TestSimpleTableWithEnum struct {
+	_tab flatbuffers.Table
+}
+
+func GetRootAsTestSimpleTableWithEnum(buf []byte, offset flatbuffers.UOffsetT) *TestSimpleTableWithEnum {
+	n := flatbuffers.GetUOffsetT(buf[offset:])
+	x := &TestSimpleTableWithEnum{}
+	x.Init(buf, n+offset)
+	return x
+}
+
+func (rcv *TestSimpleTableWithEnum) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *TestSimpleTableWithEnum) Table() flatbuffers.Table {
+	return rcv._tab
+}
+
+func (rcv *TestSimpleTableWithEnum) Color() Color {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+	if o != 0 {
+		return Color(rcv._tab.GetByte(o + rcv._tab.Pos))
+	}
+	return 2
+}
+
+func (rcv *TestSimpleTableWithEnum) MutateColor(n Color) bool {
+	return rcv._tab.MutateByteSlot(4, byte(n))
+}
+
+func TestSimpleTableWithEnumStart(builder *flatbuffers.Builder) {
+	builder.StartObject(1)
+}
+func TestSimpleTableWithEnumAddColor(builder *flatbuffers.Builder, color Color) {
+	builder.PrependByteSlot(0, byte(color), 2)
+}
+func TestSimpleTableWithEnumEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+	return builder.EndObject()
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/TestSimpleTableWithEnum.java b/third_party/flatbuffers/tests/MyGame/Example/TestSimpleTableWithEnum.java
new file mode 100644
index 0000000..c9f1c63
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/TestSimpleTableWithEnum.java
@@ -0,0 +1,35 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+final class TestSimpleTableWithEnum extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static TestSimpleTableWithEnum getRootAsTestSimpleTableWithEnum(ByteBuffer _bb) { return getRootAsTestSimpleTableWithEnum(_bb, new TestSimpleTableWithEnum()); }
+  public static TestSimpleTableWithEnum getRootAsTestSimpleTableWithEnum(ByteBuffer _bb, TestSimpleTableWithEnum obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public TestSimpleTableWithEnum __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public int color() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) & 0xFF : 2; }
+  public boolean mutateColor(int color) { int o = __offset(4); if (o != 0) { bb.put(o + bb_pos, (byte)color); return true; } else { return false; } }
+
+  public static int createTestSimpleTableWithEnum(FlatBufferBuilder builder,
+      int color) {
+    builder.startTable(1);
+    TestSimpleTableWithEnum.addColor(builder, color);
+    return TestSimpleTableWithEnum.endTestSimpleTableWithEnum(builder);
+  }
+
+  public static void startTestSimpleTableWithEnum(FlatBufferBuilder builder) { builder.startTable(1); }
+  public static void addColor(FlatBufferBuilder builder, int color) { builder.addByte(0, (byte)color, (byte)2); }
+  public static int endTestSimpleTableWithEnum(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+}
+
diff --git a/third_party/flatbuffers/tests/MyGame/Example/TestSimpleTableWithEnum.kt b/third_party/flatbuffers/tests/MyGame/Example/TestSimpleTableWithEnum.kt
new file mode 100644
index 0000000..68c6abf
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/TestSimpleTableWithEnum.kt
@@ -0,0 +1,53 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class TestSimpleTableWithEnum : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : TestSimpleTableWithEnum {
+        __init(_i, _bb)
+        return this
+    }
+    val color : UByte
+        get() {
+            val o = __offset(4)
+            return if(o != 0) bb.get(o + bb_pos).toUByte() else 2u
+        }
+    fun mutateColor(color: UByte) : Boolean {
+        val o = __offset(4)
+        return if (o != 0) {
+            bb.put(o + bb_pos, color.toByte())
+            true
+        } else {
+            false
+        }
+    }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsTestSimpleTableWithEnum(_bb: ByteBuffer): TestSimpleTableWithEnum = getRootAsTestSimpleTableWithEnum(_bb, TestSimpleTableWithEnum())
+        fun getRootAsTestSimpleTableWithEnum(_bb: ByteBuffer, obj: TestSimpleTableWithEnum): TestSimpleTableWithEnum {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun createTestSimpleTableWithEnum(builder: FlatBufferBuilder, color: UByte) : Int {
+            builder.startTable(1)
+            addColor(builder, color)
+            return endTestSimpleTableWithEnum(builder)
+        }
+        fun startTestSimpleTableWithEnum(builder: FlatBufferBuilder) = builder.startTable(1)
+        fun addColor(builder: FlatBufferBuilder, color: UByte) = builder.addByte(0, color.toByte(), 2)
+        fun endTestSimpleTableWithEnum(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+            return o
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/TestSimpleTableWithEnum.lua b/third_party/flatbuffers/tests/MyGame/Example/TestSimpleTableWithEnum.lua
new file mode 100644
index 0000000..32c8251
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/TestSimpleTableWithEnum.lua
@@ -0,0 +1,35 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Example
+
+local flatbuffers = require('flatbuffers')
+
+local TestSimpleTableWithEnum = {} -- the module
+local TestSimpleTableWithEnum_mt = {} -- the class metatable
+
+function TestSimpleTableWithEnum.New()
+    local o = {}
+    setmetatable(o, {__index = TestSimpleTableWithEnum_mt})
+    return o
+end
+function TestSimpleTableWithEnum.GetRootAsTestSimpleTableWithEnum(buf, offset)
+    local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)
+    local o = TestSimpleTableWithEnum.New()
+    o:Init(buf, n + offset)
+    return o
+end
+function TestSimpleTableWithEnum_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function TestSimpleTableWithEnum_mt:Color()
+    local o = self.view:Offset(4)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint8, o + self.view.pos)
+    end
+    return 2
+end
+function TestSimpleTableWithEnum.Start(builder) builder:StartObject(1) end
+function TestSimpleTableWithEnum.AddColor(builder, color) builder:PrependUint8Slot(0, color, 2) end
+function TestSimpleTableWithEnum.End(builder) return builder:EndObject() end
+
+return TestSimpleTableWithEnum -- return the module
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/MyGame/Example/TestSimpleTableWithEnum.php b/third_party/flatbuffers/tests/MyGame/Example/TestSimpleTableWithEnum.php
new file mode 100644
index 0000000..6429f8d
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/TestSimpleTableWithEnum.php
@@ -0,0 +1,99 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame\Example;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class TestSimpleTableWithEnum extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return TestSimpleTableWithEnum
+     */
+    public static function getRootAsTestSimpleTableWithEnum(ByteBuffer $bb)
+    {
+        $obj = new TestSimpleTableWithEnum();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    public static function TestSimpleTableWithEnumIdentifier()
+    {
+        return "MONS";
+    }
+
+    public static function TestSimpleTableWithEnumBufferHasIdentifier(ByteBuffer $buf)
+    {
+        return self::__has_identifier($buf, self::TestSimpleTableWithEnumIdentifier());
+    }
+
+    public static function TestSimpleTableWithEnumExtension()
+    {
+        return "mon";
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return TestSimpleTableWithEnum
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @return byte
+     */
+    public function getColor()
+    {
+        $o = $this->__offset(4);
+        return $o != 0 ? $this->bb->getByte($o + $this->bb_pos) : \MyGame\Example\Color::Green;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startTestSimpleTableWithEnum(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(1);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return TestSimpleTableWithEnum
+     */
+    public static function createTestSimpleTableWithEnum(FlatBufferBuilder $builder, $color)
+    {
+        $builder->startObject(1);
+        self::addColor($builder, $color);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param byte
+     * @return void
+     */
+    public static function addColor(FlatBufferBuilder $builder, $color)
+    {
+        $builder->addByteX(0, $color, 2);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endTestSimpleTableWithEnum(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/TestSimpleTableWithEnum.py b/third_party/flatbuffers/tests/MyGame/Example/TestSimpleTableWithEnum.py
new file mode 100644
index 0000000..cb9c631
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/TestSimpleTableWithEnum.py
@@ -0,0 +1,34 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+import flatbuffers
+
+class TestSimpleTableWithEnum(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAsTestSimpleTableWithEnum(cls, buf, offset):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = TestSimpleTableWithEnum()
+        x.Init(buf, n + offset)
+        return x
+
+    @classmethod
+    def TestSimpleTableWithEnumBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
+        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)
+
+    # TestSimpleTableWithEnum
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # TestSimpleTableWithEnum
+    def Color(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
+        return 2
+
+def TestSimpleTableWithEnumStart(builder): builder.StartObject(1)
+def TestSimpleTableWithEnumAddColor(builder, color): builder.PrependUint8Slot(0, color, 2)
+def TestSimpleTableWithEnumEnd(builder): return builder.EndObject()
diff --git a/third_party/flatbuffers/tests/MyGame/Example/TypeAliases.cs b/third_party/flatbuffers/tests/MyGame/Example/TypeAliases.cs
new file mode 100644
index 0000000..a7b54d5
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/TypeAliases.cs
@@ -0,0 +1,115 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct TypeAliases : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static TypeAliases GetRootAsTypeAliases(ByteBuffer _bb) { return GetRootAsTypeAliases(_bb, new TypeAliases()); }
+  public static TypeAliases GetRootAsTypeAliases(ByteBuffer _bb, TypeAliases obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public TypeAliases __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public sbyte I8 { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetSbyte(o + __p.bb_pos) : (sbyte)0; } }
+  public bool MutateI8(sbyte i8) { int o = __p.__offset(4); if (o != 0) { __p.bb.PutSbyte(o + __p.bb_pos, i8); return true; } else { return false; } }
+  public byte U8 { get { int o = __p.__offset(6); return o != 0 ? __p.bb.Get(o + __p.bb_pos) : (byte)0; } }
+  public bool MutateU8(byte u8) { int o = __p.__offset(6); if (o != 0) { __p.bb.Put(o + __p.bb_pos, u8); return true; } else { return false; } }
+  public short I16 { get { int o = __p.__offset(8); return o != 0 ? __p.bb.GetShort(o + __p.bb_pos) : (short)0; } }
+  public bool MutateI16(short i16) { int o = __p.__offset(8); if (o != 0) { __p.bb.PutShort(o + __p.bb_pos, i16); return true; } else { return false; } }
+  public ushort U16 { get { int o = __p.__offset(10); return o != 0 ? __p.bb.GetUshort(o + __p.bb_pos) : (ushort)0; } }
+  public bool MutateU16(ushort u16) { int o = __p.__offset(10); if (o != 0) { __p.bb.PutUshort(o + __p.bb_pos, u16); return true; } else { return false; } }
+  public int I32 { get { int o = __p.__offset(12); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } }
+  public bool MutateI32(int i32) { int o = __p.__offset(12); if (o != 0) { __p.bb.PutInt(o + __p.bb_pos, i32); return true; } else { return false; } }
+  public uint U32 { get { int o = __p.__offset(14); return o != 0 ? __p.bb.GetUint(o + __p.bb_pos) : (uint)0; } }
+  public bool MutateU32(uint u32) { int o = __p.__offset(14); if (o != 0) { __p.bb.PutUint(o + __p.bb_pos, u32); return true; } else { return false; } }
+  public long I64 { get { int o = __p.__offset(16); return o != 0 ? __p.bb.GetLong(o + __p.bb_pos) : (long)0; } }
+  public bool MutateI64(long i64) { int o = __p.__offset(16); if (o != 0) { __p.bb.PutLong(o + __p.bb_pos, i64); return true; } else { return false; } }
+  public ulong U64 { get { int o = __p.__offset(18); return o != 0 ? __p.bb.GetUlong(o + __p.bb_pos) : (ulong)0; } }
+  public bool MutateU64(ulong u64) { int o = __p.__offset(18); if (o != 0) { __p.bb.PutUlong(o + __p.bb_pos, u64); return true; } else { return false; } }
+  public float F32 { get { int o = __p.__offset(20); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)0.0f; } }
+  public bool MutateF32(float f32) { int o = __p.__offset(20); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, f32); return true; } else { return false; } }
+  public double F64 { get { int o = __p.__offset(22); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)0.0; } }
+  public bool MutateF64(double f64) { int o = __p.__offset(22); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, f64); return true; } else { return false; } }
+  public sbyte V8(int j) { int o = __p.__offset(24); return o != 0 ? __p.bb.GetSbyte(__p.__vector(o) + j * 1) : (sbyte)0; }
+  public int V8Length { get { int o = __p.__offset(24); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetV8Bytes() { return __p.__vector_as_span(24); }
+#else
+  public ArraySegment<byte>? GetV8Bytes() { return __p.__vector_as_arraysegment(24); }
+#endif
+  public sbyte[] GetV8Array() { return __p.__vector_as_array<sbyte>(24); }
+  public bool MutateV8(int j, sbyte v8) { int o = __p.__offset(24); if (o != 0) { __p.bb.PutSbyte(__p.__vector(o) + j * 1, v8); return true; } else { return false; } }
+  public double Vf64(int j) { int o = __p.__offset(26); return o != 0 ? __p.bb.GetDouble(__p.__vector(o) + j * 8) : (double)0; }
+  public int Vf64Length { get { int o = __p.__offset(26); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetVf64Bytes() { return __p.__vector_as_span(26); }
+#else
+  public ArraySegment<byte>? GetVf64Bytes() { return __p.__vector_as_arraysegment(26); }
+#endif
+  public double[] GetVf64Array() { return __p.__vector_as_array<double>(26); }
+  public bool MutateVf64(int j, double vf64) { int o = __p.__offset(26); if (o != 0) { __p.bb.PutDouble(__p.__vector(o) + j * 8, vf64); return true; } else { return false; } }
+
+  public static Offset<MyGame.Example.TypeAliases> CreateTypeAliases(FlatBufferBuilder builder,
+      sbyte i8 = 0,
+      byte u8 = 0,
+      short i16 = 0,
+      ushort u16 = 0,
+      int i32 = 0,
+      uint u32 = 0,
+      long i64 = 0,
+      ulong u64 = 0,
+      float f32 = 0.0f,
+      double f64 = 0.0,
+      VectorOffset v8Offset = default(VectorOffset),
+      VectorOffset vf64Offset = default(VectorOffset)) {
+    builder.StartTable(12);
+    TypeAliases.AddF64(builder, f64);
+    TypeAliases.AddU64(builder, u64);
+    TypeAliases.AddI64(builder, i64);
+    TypeAliases.AddVf64(builder, vf64Offset);
+    TypeAliases.AddV8(builder, v8Offset);
+    TypeAliases.AddF32(builder, f32);
+    TypeAliases.AddU32(builder, u32);
+    TypeAliases.AddI32(builder, i32);
+    TypeAliases.AddU16(builder, u16);
+    TypeAliases.AddI16(builder, i16);
+    TypeAliases.AddU8(builder, u8);
+    TypeAliases.AddI8(builder, i8);
+    return TypeAliases.EndTypeAliases(builder);
+  }
+
+  public static void StartTypeAliases(FlatBufferBuilder builder) { builder.StartTable(12); }
+  public static void AddI8(FlatBufferBuilder builder, sbyte i8) { builder.AddSbyte(0, i8, 0); }
+  public static void AddU8(FlatBufferBuilder builder, byte u8) { builder.AddByte(1, u8, 0); }
+  public static void AddI16(FlatBufferBuilder builder, short i16) { builder.AddShort(2, i16, 0); }
+  public static void AddU16(FlatBufferBuilder builder, ushort u16) { builder.AddUshort(3, u16, 0); }
+  public static void AddI32(FlatBufferBuilder builder, int i32) { builder.AddInt(4, i32, 0); }
+  public static void AddU32(FlatBufferBuilder builder, uint u32) { builder.AddUint(5, u32, 0); }
+  public static void AddI64(FlatBufferBuilder builder, long i64) { builder.AddLong(6, i64, 0); }
+  public static void AddU64(FlatBufferBuilder builder, ulong u64) { builder.AddUlong(7, u64, 0); }
+  public static void AddF32(FlatBufferBuilder builder, float f32) { builder.AddFloat(8, f32, 0.0f); }
+  public static void AddF64(FlatBufferBuilder builder, double f64) { builder.AddDouble(9, f64, 0.0); }
+  public static void AddV8(FlatBufferBuilder builder, VectorOffset v8Offset) { builder.AddOffset(10, v8Offset.Value, 0); }
+  public static VectorOffset CreateV8Vector(FlatBufferBuilder builder, sbyte[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddSbyte(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateV8VectorBlock(FlatBufferBuilder builder, sbyte[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); }
+  public static void StartV8Vector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
+  public static void AddVf64(FlatBufferBuilder builder, VectorOffset vf64Offset) { builder.AddOffset(11, vf64Offset.Value, 0); }
+  public static VectorOffset CreateVf64Vector(FlatBufferBuilder builder, double[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddDouble(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateVf64VectorBlock(FlatBufferBuilder builder, double[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
+  public static void StartVf64Vector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
+  public static Offset<MyGame.Example.TypeAliases> EndTypeAliases(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<MyGame.Example.TypeAliases>(o);
+  }
+};
+
+
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/TypeAliases.go b/third_party/flatbuffers/tests/MyGame/Example/TypeAliases.go
new file mode 100644
index 0000000..d017b5b
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/TypeAliases.go
@@ -0,0 +1,248 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package Example
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+
+type TypeAliases struct {
+	_tab flatbuffers.Table
+}
+
+func GetRootAsTypeAliases(buf []byte, offset flatbuffers.UOffsetT) *TypeAliases {
+	n := flatbuffers.GetUOffsetT(buf[offset:])
+	x := &TypeAliases{}
+	x.Init(buf, n+offset)
+	return x
+}
+
+func (rcv *TypeAliases) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *TypeAliases) Table() flatbuffers.Table {
+	return rcv._tab
+}
+
+func (rcv *TypeAliases) I8() int8 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+	if o != 0 {
+		return rcv._tab.GetInt8(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *TypeAliases) MutateI8(n int8) bool {
+	return rcv._tab.MutateInt8Slot(4, n)
+}
+
+func (rcv *TypeAliases) U8() byte {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
+	if o != 0 {
+		return rcv._tab.GetByte(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *TypeAliases) MutateU8(n byte) bool {
+	return rcv._tab.MutateByteSlot(6, n)
+}
+
+func (rcv *TypeAliases) I16() int16 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
+	if o != 0 {
+		return rcv._tab.GetInt16(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *TypeAliases) MutateI16(n int16) bool {
+	return rcv._tab.MutateInt16Slot(8, n)
+}
+
+func (rcv *TypeAliases) U16() uint16 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(10))
+	if o != 0 {
+		return rcv._tab.GetUint16(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *TypeAliases) MutateU16(n uint16) bool {
+	return rcv._tab.MutateUint16Slot(10, n)
+}
+
+func (rcv *TypeAliases) I32() int32 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(12))
+	if o != 0 {
+		return rcv._tab.GetInt32(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *TypeAliases) MutateI32(n int32) bool {
+	return rcv._tab.MutateInt32Slot(12, n)
+}
+
+func (rcv *TypeAliases) U32() uint32 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(14))
+	if o != 0 {
+		return rcv._tab.GetUint32(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *TypeAliases) MutateU32(n uint32) bool {
+	return rcv._tab.MutateUint32Slot(14, n)
+}
+
+func (rcv *TypeAliases) I64() int64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(16))
+	if o != 0 {
+		return rcv._tab.GetInt64(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *TypeAliases) MutateI64(n int64) bool {
+	return rcv._tab.MutateInt64Slot(16, n)
+}
+
+func (rcv *TypeAliases) U64() uint64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(18))
+	if o != 0 {
+		return rcv._tab.GetUint64(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *TypeAliases) MutateU64(n uint64) bool {
+	return rcv._tab.MutateUint64Slot(18, n)
+}
+
+func (rcv *TypeAliases) F32() float32 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(20))
+	if o != 0 {
+		return rcv._tab.GetFloat32(o + rcv._tab.Pos)
+	}
+	return 0.0
+}
+
+func (rcv *TypeAliases) MutateF32(n float32) bool {
+	return rcv._tab.MutateFloat32Slot(20, n)
+}
+
+func (rcv *TypeAliases) F64() float64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(22))
+	if o != 0 {
+		return rcv._tab.GetFloat64(o + rcv._tab.Pos)
+	}
+	return 0.0
+}
+
+func (rcv *TypeAliases) MutateF64(n float64) bool {
+	return rcv._tab.MutateFloat64Slot(22, n)
+}
+
+func (rcv *TypeAliases) V8(j int) int8 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(24))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.GetInt8(a + flatbuffers.UOffsetT(j*1))
+	}
+	return 0
+}
+
+func (rcv *TypeAliases) V8Length() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(24))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *TypeAliases) MutateV8(j int, n int8) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(24))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.MutateInt8(a+flatbuffers.UOffsetT(j*1), n)
+	}
+	return false
+}
+
+func (rcv *TypeAliases) Vf64(j int) float64 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(26))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.GetFloat64(a + flatbuffers.UOffsetT(j*8))
+	}
+	return 0
+}
+
+func (rcv *TypeAliases) Vf64Length() int {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(26))
+	if o != 0 {
+		return rcv._tab.VectorLen(o)
+	}
+	return 0
+}
+
+func (rcv *TypeAliases) MutateVf64(j int, n float64) bool {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(26))
+	if o != 0 {
+		a := rcv._tab.Vector(o)
+		return rcv._tab.MutateFloat64(a+flatbuffers.UOffsetT(j*8), n)
+	}
+	return false
+}
+
+func TypeAliasesStart(builder *flatbuffers.Builder) {
+	builder.StartObject(12)
+}
+func TypeAliasesAddI8(builder *flatbuffers.Builder, i8 int8) {
+	builder.PrependInt8Slot(0, i8, 0)
+}
+func TypeAliasesAddU8(builder *flatbuffers.Builder, u8 byte) {
+	builder.PrependByteSlot(1, u8, 0)
+}
+func TypeAliasesAddI16(builder *flatbuffers.Builder, i16 int16) {
+	builder.PrependInt16Slot(2, i16, 0)
+}
+func TypeAliasesAddU16(builder *flatbuffers.Builder, u16 uint16) {
+	builder.PrependUint16Slot(3, u16, 0)
+}
+func TypeAliasesAddI32(builder *flatbuffers.Builder, i32 int32) {
+	builder.PrependInt32Slot(4, i32, 0)
+}
+func TypeAliasesAddU32(builder *flatbuffers.Builder, u32 uint32) {
+	builder.PrependUint32Slot(5, u32, 0)
+}
+func TypeAliasesAddI64(builder *flatbuffers.Builder, i64 int64) {
+	builder.PrependInt64Slot(6, i64, 0)
+}
+func TypeAliasesAddU64(builder *flatbuffers.Builder, u64 uint64) {
+	builder.PrependUint64Slot(7, u64, 0)
+}
+func TypeAliasesAddF32(builder *flatbuffers.Builder, f32 float32) {
+	builder.PrependFloat32Slot(8, f32, 0.0)
+}
+func TypeAliasesAddF64(builder *flatbuffers.Builder, f64 float64) {
+	builder.PrependFloat64Slot(9, f64, 0.0)
+}
+func TypeAliasesAddV8(builder *flatbuffers.Builder, v8 flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(10, flatbuffers.UOffsetT(v8), 0)
+}
+func TypeAliasesStartV8Vector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(1, numElems, 1)
+}
+func TypeAliasesAddVf64(builder *flatbuffers.Builder, vf64 flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(11, flatbuffers.UOffsetT(vf64), 0)
+}
+func TypeAliasesStartVf64Vector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
+	return builder.StartVector(8, numElems, 8)
+}
+func TypeAliasesEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+	return builder.EndObject()
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/TypeAliases.java b/third_party/flatbuffers/tests/MyGame/Example/TypeAliases.java
new file mode 100644
index 0000000..dde6acb
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/TypeAliases.java
@@ -0,0 +1,100 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class TypeAliases extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static TypeAliases getRootAsTypeAliases(ByteBuffer _bb) { return getRootAsTypeAliases(_bb, new TypeAliases()); }
+  public static TypeAliases getRootAsTypeAliases(ByteBuffer _bb, TypeAliases obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public TypeAliases __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public byte i8() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 0; }
+  public boolean mutateI8(byte i8) { int o = __offset(4); if (o != 0) { bb.put(o + bb_pos, i8); return true; } else { return false; } }
+  public int u8() { int o = __offset(6); return o != 0 ? bb.get(o + bb_pos) & 0xFF : 0; }
+  public boolean mutateU8(int u8) { int o = __offset(6); if (o != 0) { bb.put(o + bb_pos, (byte)u8); return true; } else { return false; } }
+  public short i16() { int o = __offset(8); return o != 0 ? bb.getShort(o + bb_pos) : 0; }
+  public boolean mutateI16(short i16) { int o = __offset(8); if (o != 0) { bb.putShort(o + bb_pos, i16); return true; } else { return false; } }
+  public int u16() { int o = __offset(10); return o != 0 ? bb.getShort(o + bb_pos) & 0xFFFF : 0; }
+  public boolean mutateU16(int u16) { int o = __offset(10); if (o != 0) { bb.putShort(o + bb_pos, (short)u16); return true; } else { return false; } }
+  public int i32() { int o = __offset(12); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
+  public boolean mutateI32(int i32) { int o = __offset(12); if (o != 0) { bb.putInt(o + bb_pos, i32); return true; } else { return false; } }
+  public long u32() { int o = __offset(14); return o != 0 ? (long)bb.getInt(o + bb_pos) & 0xFFFFFFFFL : 0L; }
+  public boolean mutateU32(long u32) { int o = __offset(14); if (o != 0) { bb.putInt(o + bb_pos, (int)u32); return true; } else { return false; } }
+  public long i64() { int o = __offset(16); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
+  public boolean mutateI64(long i64) { int o = __offset(16); if (o != 0) { bb.putLong(o + bb_pos, i64); return true; } else { return false; } }
+  public long u64() { int o = __offset(18); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
+  public boolean mutateU64(long u64) { int o = __offset(18); if (o != 0) { bb.putLong(o + bb_pos, u64); return true; } else { return false; } }
+  public float f32() { int o = __offset(20); return o != 0 ? bb.getFloat(o + bb_pos) : 0.0f; }
+  public boolean mutateF32(float f32) { int o = __offset(20); if (o != 0) { bb.putFloat(o + bb_pos, f32); return true; } else { return false; } }
+  public double f64() { int o = __offset(22); return o != 0 ? bb.getDouble(o + bb_pos) : 0.0; }
+  public boolean mutateF64(double f64) { int o = __offset(22); if (o != 0) { bb.putDouble(o + bb_pos, f64); return true; } else { return false; } }
+  public byte v8(int j) { int o = __offset(24); return o != 0 ? bb.get(__vector(o) + j * 1) : 0; }
+  public int v8Length() { int o = __offset(24); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer v8AsByteBuffer() { return __vector_as_bytebuffer(24, 1); }
+  public ByteBuffer v8InByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 24, 1); }
+  public boolean mutateV8(int j, byte v8) { int o = __offset(24); if (o != 0) { bb.put(__vector(o) + j * 1, v8); return true; } else { return false; } }
+  public double vf64(int j) { int o = __offset(26); return o != 0 ? bb.getDouble(__vector(o) + j * 8) : 0; }
+  public int vf64Length() { int o = __offset(26); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer vf64AsByteBuffer() { return __vector_as_bytebuffer(26, 8); }
+  public ByteBuffer vf64InByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 26, 8); }
+  public boolean mutateVf64(int j, double vf64) { int o = __offset(26); if (o != 0) { bb.putDouble(__vector(o) + j * 8, vf64); return true; } else { return false; } }
+
+  public static int createTypeAliases(FlatBufferBuilder builder,
+      byte i8,
+      int u8,
+      short i16,
+      int u16,
+      int i32,
+      long u32,
+      long i64,
+      long u64,
+      float f32,
+      double f64,
+      int v8Offset,
+      int vf64Offset) {
+    builder.startTable(12);
+    TypeAliases.addF64(builder, f64);
+    TypeAliases.addU64(builder, u64);
+    TypeAliases.addI64(builder, i64);
+    TypeAliases.addVf64(builder, vf64Offset);
+    TypeAliases.addV8(builder, v8Offset);
+    TypeAliases.addF32(builder, f32);
+    TypeAliases.addU32(builder, u32);
+    TypeAliases.addI32(builder, i32);
+    TypeAliases.addU16(builder, u16);
+    TypeAliases.addI16(builder, i16);
+    TypeAliases.addU8(builder, u8);
+    TypeAliases.addI8(builder, i8);
+    return TypeAliases.endTypeAliases(builder);
+  }
+
+  public static void startTypeAliases(FlatBufferBuilder builder) { builder.startTable(12); }
+  public static void addI8(FlatBufferBuilder builder, byte i8) { builder.addByte(0, i8, 0); }
+  public static void addU8(FlatBufferBuilder builder, int u8) { builder.addByte(1, (byte)u8, (byte)0); }
+  public static void addI16(FlatBufferBuilder builder, short i16) { builder.addShort(2, i16, 0); }
+  public static void addU16(FlatBufferBuilder builder, int u16) { builder.addShort(3, (short)u16, (short)0); }
+  public static void addI32(FlatBufferBuilder builder, int i32) { builder.addInt(4, i32, 0); }
+  public static void addU32(FlatBufferBuilder builder, long u32) { builder.addInt(5, (int)u32, (int)0L); }
+  public static void addI64(FlatBufferBuilder builder, long i64) { builder.addLong(6, i64, 0L); }
+  public static void addU64(FlatBufferBuilder builder, long u64) { builder.addLong(7, u64, 0L); }
+  public static void addF32(FlatBufferBuilder builder, float f32) { builder.addFloat(8, f32, 0.0f); }
+  public static void addF64(FlatBufferBuilder builder, double f64) { builder.addDouble(9, f64, 0.0); }
+  public static void addV8(FlatBufferBuilder builder, int v8Offset) { builder.addOffset(10, v8Offset, 0); }
+  public static int createV8Vector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); }
+  public static void startV8Vector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
+  public static void addVf64(FlatBufferBuilder builder, int vf64Offset) { builder.addOffset(11, vf64Offset, 0); }
+  public static int createVf64Vector(FlatBufferBuilder builder, double[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addDouble(data[i]); return builder.endVector(); }
+  public static void startVf64Vector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); }
+  public static int endTypeAliases(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+}
+
diff --git a/third_party/flatbuffers/tests/MyGame/Example/TypeAliases.kt b/third_party/flatbuffers/tests/MyGame/Example/TypeAliases.kt
new file mode 100644
index 0000000..d1e8816
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/TypeAliases.kt
@@ -0,0 +1,263 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class TypeAliases : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : TypeAliases {
+        __init(_i, _bb)
+        return this
+    }
+    val i8 : Byte
+        get() {
+            val o = __offset(4)
+            return if(o != 0) bb.get(o + bb_pos) else 0
+        }
+    fun mutateI8(i8: Byte) : Boolean {
+        val o = __offset(4)
+        return if (o != 0) {
+            bb.put(o + bb_pos, i8)
+            true
+        } else {
+            false
+        }
+    }
+    val u8 : UByte
+        get() {
+            val o = __offset(6)
+            return if(o != 0) bb.get(o + bb_pos).toUByte() else 0u
+        }
+    fun mutateU8(u8: UByte) : Boolean {
+        val o = __offset(6)
+        return if (o != 0) {
+            bb.put(o + bb_pos, u8.toByte())
+            true
+        } else {
+            false
+        }
+    }
+    val i16 : Short
+        get() {
+            val o = __offset(8)
+            return if(o != 0) bb.getShort(o + bb_pos) else 0
+        }
+    fun mutateI16(i16: Short) : Boolean {
+        val o = __offset(8)
+        return if (o != 0) {
+            bb.putShort(o + bb_pos, i16)
+            true
+        } else {
+            false
+        }
+    }
+    val u16 : UShort
+        get() {
+            val o = __offset(10)
+            return if(o != 0) bb.getShort(o + bb_pos).toUShort() else 0u
+        }
+    fun mutateU16(u16: UShort) : Boolean {
+        val o = __offset(10)
+        return if (o != 0) {
+            bb.putShort(o + bb_pos, u16.toShort())
+            true
+        } else {
+            false
+        }
+    }
+    val i32 : Int
+        get() {
+            val o = __offset(12)
+            return if(o != 0) bb.getInt(o + bb_pos) else 0
+        }
+    fun mutateI32(i32: Int) : Boolean {
+        val o = __offset(12)
+        return if (o != 0) {
+            bb.putInt(o + bb_pos, i32)
+            true
+        } else {
+            false
+        }
+    }
+    val u32 : UInt
+        get() {
+            val o = __offset(14)
+            return if(o != 0) bb.getInt(o + bb_pos).toUInt() else 0u
+        }
+    fun mutateU32(u32: UInt) : Boolean {
+        val o = __offset(14)
+        return if (o != 0) {
+            bb.putInt(o + bb_pos, u32.toInt())
+            true
+        } else {
+            false
+        }
+    }
+    val i64 : Long
+        get() {
+            val o = __offset(16)
+            return if(o != 0) bb.getLong(o + bb_pos) else 0L
+        }
+    fun mutateI64(i64: Long) : Boolean {
+        val o = __offset(16)
+        return if (o != 0) {
+            bb.putLong(o + bb_pos, i64)
+            true
+        } else {
+            false
+        }
+    }
+    val u64 : ULong
+        get() {
+            val o = __offset(18)
+            return if(o != 0) bb.getLong(o + bb_pos).toULong() else 0UL
+        }
+    fun mutateU64(u64: ULong) : Boolean {
+        val o = __offset(18)
+        return if (o != 0) {
+            bb.putLong(o + bb_pos, u64.toLong())
+            true
+        } else {
+            false
+        }
+    }
+    val f32 : Float
+        get() {
+            val o = __offset(20)
+            return if(o != 0) bb.getFloat(o + bb_pos) else 0.0f
+        }
+    fun mutateF32(f32: Float) : Boolean {
+        val o = __offset(20)
+        return if (o != 0) {
+            bb.putFloat(o + bb_pos, f32)
+            true
+        } else {
+            false
+        }
+    }
+    val f64 : Double
+        get() {
+            val o = __offset(22)
+            return if(o != 0) bb.getDouble(o + bb_pos) else 0.0
+        }
+    fun mutateF64(f64: Double) : Boolean {
+        val o = __offset(22)
+        return if (o != 0) {
+            bb.putDouble(o + bb_pos, f64)
+            true
+        } else {
+            false
+        }
+    }
+    fun v8(j: Int) : Byte {
+        val o = __offset(24)
+        return if (o != 0) {
+            bb.get(__vector(o) + j * 1)
+        } else {
+            0
+        }
+    }
+    val v8Length : Int
+        get() {
+            val o = __offset(24); return if (o != 0) __vector_len(o) else 0
+        }
+    val v8AsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(24, 1)
+    fun v8InByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 24, 1)
+    fun mutateV8(j: Int, v8: Byte) : Boolean {
+        val o = __offset(24)
+        return if (o != 0) {
+            bb.put(__vector(o) + j * 1, v8)
+            true
+        } else {
+            false
+        }
+    }
+    fun vf64(j: Int) : Double {
+        val o = __offset(26)
+        return if (o != 0) {
+            bb.getDouble(__vector(o) + j * 8)
+        } else {
+            0.0
+        }
+    }
+    val vf64Length : Int
+        get() {
+            val o = __offset(26); return if (o != 0) __vector_len(o) else 0
+        }
+    val vf64AsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(26, 8)
+    fun vf64InByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 26, 8)
+    fun mutateVf64(j: Int, vf64: Double) : Boolean {
+        val o = __offset(26)
+        return if (o != 0) {
+            bb.putDouble(__vector(o) + j * 8, vf64)
+            true
+        } else {
+            false
+        }
+    }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsTypeAliases(_bb: ByteBuffer): TypeAliases = getRootAsTypeAliases(_bb, TypeAliases())
+        fun getRootAsTypeAliases(_bb: ByteBuffer, obj: TypeAliases): TypeAliases {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun createTypeAliases(builder: FlatBufferBuilder, i8: Byte, u8: UByte, i16: Short, u16: UShort, i32: Int, u32: UInt, i64: Long, u64: ULong, f32: Float, f64: Double, v8Offset: Int, vf64Offset: Int) : Int {
+            builder.startTable(12)
+            addF64(builder, f64)
+            addU64(builder, u64)
+            addI64(builder, i64)
+            addVf64(builder, vf64Offset)
+            addV8(builder, v8Offset)
+            addF32(builder, f32)
+            addU32(builder, u32)
+            addI32(builder, i32)
+            addU16(builder, u16)
+            addI16(builder, i16)
+            addU8(builder, u8)
+            addI8(builder, i8)
+            return endTypeAliases(builder)
+        }
+        fun startTypeAliases(builder: FlatBufferBuilder) = builder.startTable(12)
+        fun addI8(builder: FlatBufferBuilder, i8: Byte) = builder.addByte(0, i8, 0)
+        fun addU8(builder: FlatBufferBuilder, u8: UByte) = builder.addByte(1, u8.toByte(), 0)
+        fun addI16(builder: FlatBufferBuilder, i16: Short) = builder.addShort(2, i16, 0)
+        fun addU16(builder: FlatBufferBuilder, u16: UShort) = builder.addShort(3, u16.toShort(), 0)
+        fun addI32(builder: FlatBufferBuilder, i32: Int) = builder.addInt(4, i32, 0)
+        fun addU32(builder: FlatBufferBuilder, u32: UInt) = builder.addInt(5, u32.toInt(), 0)
+        fun addI64(builder: FlatBufferBuilder, i64: Long) = builder.addLong(6, i64, 0L)
+        fun addU64(builder: FlatBufferBuilder, u64: ULong) = builder.addLong(7, u64.toLong(), 0)
+        fun addF32(builder: FlatBufferBuilder, f32: Float) = builder.addFloat(8, f32, 0.0)
+        fun addF64(builder: FlatBufferBuilder, f64: Double) = builder.addDouble(9, f64, 0.0)
+        fun addV8(builder: FlatBufferBuilder, v8: Int) = builder.addOffset(10, v8, 0)
+        fun createV8Vector(builder: FlatBufferBuilder, data: ByteArray) : Int {
+            builder.startVector(1, data.size, 1)
+            for (i in data.size - 1 downTo 0) {
+                builder.addByte(data[i])
+            }
+            return builder.endVector()
+        }
+        fun startV8Vector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(1, numElems, 1)
+        fun addVf64(builder: FlatBufferBuilder, vf64: Int) = builder.addOffset(11, vf64, 0)
+        fun createVf64Vector(builder: FlatBufferBuilder, data: DoubleArray) : Int {
+            builder.startVector(8, data.size, 8)
+            for (i in data.size - 1 downTo 0) {
+                builder.addDouble(data[i])
+            }
+            return builder.endVector()
+        }
+        fun startVf64Vector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(8, numElems, 8)
+        fun endTypeAliases(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+            return o
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/TypeAliases.lua b/third_party/flatbuffers/tests/MyGame/Example/TypeAliases.lua
new file mode 100644
index 0000000..90f569c
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/TypeAliases.lua
@@ -0,0 +1,141 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Example
+
+local flatbuffers = require('flatbuffers')
+
+local TypeAliases = {} -- the module
+local TypeAliases_mt = {} -- the class metatable
+
+function TypeAliases.New()
+    local o = {}
+    setmetatable(o, {__index = TypeAliases_mt})
+    return o
+end
+function TypeAliases.GetRootAsTypeAliases(buf, offset)
+    local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)
+    local o = TypeAliases.New()
+    o:Init(buf, n + offset)
+    return o
+end
+function TypeAliases_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function TypeAliases_mt:I8()
+    local o = self.view:Offset(4)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int8, o + self.view.pos)
+    end
+    return 0
+end
+function TypeAliases_mt:U8()
+    local o = self.view:Offset(6)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint8, o + self.view.pos)
+    end
+    return 0
+end
+function TypeAliases_mt:I16()
+    local o = self.view:Offset(8)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int16, o + self.view.pos)
+    end
+    return 0
+end
+function TypeAliases_mt:U16()
+    local o = self.view:Offset(10)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint16, o + self.view.pos)
+    end
+    return 0
+end
+function TypeAliases_mt:I32()
+    local o = self.view:Offset(12)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int32, o + self.view.pos)
+    end
+    return 0
+end
+function TypeAliases_mt:U32()
+    local o = self.view:Offset(14)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint32, o + self.view.pos)
+    end
+    return 0
+end
+function TypeAliases_mt:I64()
+    local o = self.view:Offset(16)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int64, o + self.view.pos)
+    end
+    return 0
+end
+function TypeAliases_mt:U64()
+    local o = self.view:Offset(18)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Uint64, o + self.view.pos)
+    end
+    return 0
+end
+function TypeAliases_mt:F32()
+    local o = self.view:Offset(20)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Float32, o + self.view.pos)
+    end
+    return 0.0
+end
+function TypeAliases_mt:F64()
+    local o = self.view:Offset(22)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Float64, o + self.view.pos)
+    end
+    return 0.0
+end
+function TypeAliases_mt:V8(j)
+    local o = self.view:Offset(24)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:Get(flatbuffers.N.Int8, a + ((j-1) * 1))
+    end
+    return 0
+end
+function TypeAliases_mt:V8Length()
+    local o = self.view:Offset(24)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function TypeAliases_mt:Vf64(j)
+    local o = self.view:Offset(26)
+    if o ~= 0 then
+        local a = self.view:Vector(o)
+        return self.view:Get(flatbuffers.N.Float64, a + ((j-1) * 8))
+    end
+    return 0
+end
+function TypeAliases_mt:Vf64Length()
+    local o = self.view:Offset(26)
+    if o ~= 0 then
+        return self.view:VectorLen(o)
+    end
+    return 0
+end
+function TypeAliases.Start(builder) builder:StartObject(12) end
+function TypeAliases.AddI8(builder, i8) builder:PrependInt8Slot(0, i8, 0) end
+function TypeAliases.AddU8(builder, u8) builder:PrependUint8Slot(1, u8, 0) end
+function TypeAliases.AddI16(builder, i16) builder:PrependInt16Slot(2, i16, 0) end
+function TypeAliases.AddU16(builder, u16) builder:PrependUint16Slot(3, u16, 0) end
+function TypeAliases.AddI32(builder, i32) builder:PrependInt32Slot(4, i32, 0) end
+function TypeAliases.AddU32(builder, u32) builder:PrependUint32Slot(5, u32, 0) end
+function TypeAliases.AddI64(builder, i64) builder:PrependInt64Slot(6, i64, 0) end
+function TypeAliases.AddU64(builder, u64) builder:PrependUint64Slot(7, u64, 0) end
+function TypeAliases.AddF32(builder, f32) builder:PrependFloat32Slot(8, f32, 0.0) end
+function TypeAliases.AddF64(builder, f64) builder:PrependFloat64Slot(9, f64, 0.0) end
+function TypeAliases.AddV8(builder, v8) builder:PrependUOffsetTRelativeSlot(10, v8, 0) end
+function TypeAliases.StartV8Vector(builder, numElems) return builder:StartVector(1, numElems, 1) end
+function TypeAliases.AddVf64(builder, vf64) builder:PrependUOffsetTRelativeSlot(11, vf64, 0) end
+function TypeAliases.StartVf64Vector(builder, numElems) return builder:StartVector(8, numElems, 8) end
+function TypeAliases.End(builder) return builder:EndObject() end
+
+return TypeAliases -- return the module
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/MyGame/Example/TypeAliases.php b/third_party/flatbuffers/tests/MyGame/Example/TypeAliases.php
new file mode 100644
index 0000000..7629897
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/TypeAliases.php
@@ -0,0 +1,387 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame\Example;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class TypeAliases extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return TypeAliases
+     */
+    public static function getRootAsTypeAliases(ByteBuffer $bb)
+    {
+        $obj = new TypeAliases();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    public static function TypeAliasesIdentifier()
+    {
+        return "MONS";
+    }
+
+    public static function TypeAliasesBufferHasIdentifier(ByteBuffer $buf)
+    {
+        return self::__has_identifier($buf, self::TypeAliasesIdentifier());
+    }
+
+    public static function TypeAliasesExtension()
+    {
+        return "mon";
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return TypeAliases
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @return sbyte
+     */
+    public function getI8()
+    {
+        $o = $this->__offset(4);
+        return $o != 0 ? $this->bb->getSbyte($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return byte
+     */
+    public function getU8()
+    {
+        $o = $this->__offset(6);
+        return $o != 0 ? $this->bb->getByte($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return short
+     */
+    public function getI16()
+    {
+        $o = $this->__offset(8);
+        return $o != 0 ? $this->bb->getShort($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return ushort
+     */
+    public function getU16()
+    {
+        $o = $this->__offset(10);
+        return $o != 0 ? $this->bb->getUshort($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getI32()
+    {
+        $o = $this->__offset(12);
+        return $o != 0 ? $this->bb->getInt($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return uint
+     */
+    public function getU32()
+    {
+        $o = $this->__offset(14);
+        return $o != 0 ? $this->bb->getUint($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return long
+     */
+    public function getI64()
+    {
+        $o = $this->__offset(16);
+        return $o != 0 ? $this->bb->getLong($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return ulong
+     */
+    public function getU64()
+    {
+        $o = $this->__offset(18);
+        return $o != 0 ? $this->bb->getUlong($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @return float
+     */
+    public function getF32()
+    {
+        $o = $this->__offset(20);
+        return $o != 0 ? $this->bb->getFloat($o + $this->bb_pos) : 0.0;
+    }
+
+    /**
+     * @return double
+     */
+    public function getF64()
+    {
+        $o = $this->__offset(22);
+        return $o != 0 ? $this->bb->getDouble($o + $this->bb_pos) : 0.0;
+    }
+
+    /**
+     * @param int offset
+     * @return sbyte
+     */
+    public function getV8($j)
+    {
+        $o = $this->__offset(24);
+        return $o != 0 ? $this->bb->getSbyte($this->__vector($o) + $j * 1) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getV8Length()
+    {
+        $o = $this->__offset(24);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @param int offset
+     * @return double
+     */
+    public function getVf64($j)
+    {
+        $o = $this->__offset(26);
+        return $o != 0 ? $this->bb->getDouble($this->__vector($o) + $j * 8) : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getVf64Length()
+    {
+        $o = $this->__offset(26);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startTypeAliases(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(12);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return TypeAliases
+     */
+    public static function createTypeAliases(FlatBufferBuilder $builder, $i8, $u8, $i16, $u16, $i32, $u32, $i64, $u64, $f32, $f64, $v8, $vf64)
+    {
+        $builder->startObject(12);
+        self::addI8($builder, $i8);
+        self::addU8($builder, $u8);
+        self::addI16($builder, $i16);
+        self::addU16($builder, $u16);
+        self::addI32($builder, $i32);
+        self::addU32($builder, $u32);
+        self::addI64($builder, $i64);
+        self::addU64($builder, $u64);
+        self::addF32($builder, $f32);
+        self::addF64($builder, $f64);
+        self::addV8($builder, $v8);
+        self::addVf64($builder, $vf64);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param sbyte
+     * @return void
+     */
+    public static function addI8(FlatBufferBuilder $builder, $i8)
+    {
+        $builder->addSbyteX(0, $i8, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param byte
+     * @return void
+     */
+    public static function addU8(FlatBufferBuilder $builder, $u8)
+    {
+        $builder->addByteX(1, $u8, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param short
+     * @return void
+     */
+    public static function addI16(FlatBufferBuilder $builder, $i16)
+    {
+        $builder->addShortX(2, $i16, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param ushort
+     * @return void
+     */
+    public static function addU16(FlatBufferBuilder $builder, $u16)
+    {
+        $builder->addUshortX(3, $u16, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addI32(FlatBufferBuilder $builder, $i32)
+    {
+        $builder->addIntX(4, $i32, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param uint
+     * @return void
+     */
+    public static function addU32(FlatBufferBuilder $builder, $u32)
+    {
+        $builder->addUintX(5, $u32, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param long
+     * @return void
+     */
+    public static function addI64(FlatBufferBuilder $builder, $i64)
+    {
+        $builder->addLongX(6, $i64, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param ulong
+     * @return void
+     */
+    public static function addU64(FlatBufferBuilder $builder, $u64)
+    {
+        $builder->addUlongX(7, $u64, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param float
+     * @return void
+     */
+    public static function addF32(FlatBufferBuilder $builder, $f32)
+    {
+        $builder->addFloatX(8, $f32, 0.0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param double
+     * @return void
+     */
+    public static function addF64(FlatBufferBuilder $builder, $f64)
+    {
+        $builder->addDoubleX(9, $f64, 0.0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addV8(FlatBufferBuilder $builder, $v8)
+    {
+        $builder->addOffsetX(10, $v8, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createV8Vector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(1, count($data), 1);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putSbyte($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startV8Vector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(1, $numElems, 1);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addVf64(FlatBufferBuilder $builder, $vf64)
+    {
+        $builder->addOffsetX(11, $vf64, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createVf64Vector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(8, count($data), 8);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putDouble($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startVf64Vector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(8, $numElems, 8);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endTypeAliases(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/TypeAliases.py b/third_party/flatbuffers/tests/MyGame/Example/TypeAliases.py
new file mode 100644
index 0000000..81e9b06
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/TypeAliases.py
@@ -0,0 +1,154 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+import flatbuffers
+
+class TypeAliases(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAsTypeAliases(cls, buf, offset):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = TypeAliases()
+        x.Init(buf, n + offset)
+        return x
+
+    @classmethod
+    def TypeAliasesBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
+        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)
+
+    # TypeAliases
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # TypeAliases
+    def I8(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int8Flags, o + self._tab.Pos)
+        return 0
+
+    # TypeAliases
+    def U8(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
+        return 0
+
+    # TypeAliases
+    def I16(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int16Flags, o + self._tab.Pos)
+        return 0
+
+    # TypeAliases
+    def U16(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint16Flags, o + self._tab.Pos)
+        return 0
+
+    # TypeAliases
+    def I32(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
+        return 0
+
+    # TypeAliases
+    def U32(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint32Flags, o + self._tab.Pos)
+        return 0
+
+    # TypeAliases
+    def I64(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int64Flags, o + self._tab.Pos)
+        return 0
+
+    # TypeAliases
+    def U64(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
+        return 0
+
+    # TypeAliases
+    def F32(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
+        return 0.0
+
+    # TypeAliases
+    def F64(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
+        return 0.0
+
+    # TypeAliases
+    def V8(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.Int8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
+        return 0
+
+    # TypeAliases
+    def V8AsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Int8Flags, o)
+        return 0
+
+    # TypeAliases
+    def V8Length(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # TypeAliases
+    def Vf64(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.Float64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
+        return 0
+
+    # TypeAliases
+    def Vf64AsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Float64Flags, o)
+        return 0
+
+    # TypeAliases
+    def Vf64Length(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+def TypeAliasesStart(builder): builder.StartObject(12)
+def TypeAliasesAddI8(builder, i8): builder.PrependInt8Slot(0, i8, 0)
+def TypeAliasesAddU8(builder, u8): builder.PrependUint8Slot(1, u8, 0)
+def TypeAliasesAddI16(builder, i16): builder.PrependInt16Slot(2, i16, 0)
+def TypeAliasesAddU16(builder, u16): builder.PrependUint16Slot(3, u16, 0)
+def TypeAliasesAddI32(builder, i32): builder.PrependInt32Slot(4, i32, 0)
+def TypeAliasesAddU32(builder, u32): builder.PrependUint32Slot(5, u32, 0)
+def TypeAliasesAddI64(builder, i64): builder.PrependInt64Slot(6, i64, 0)
+def TypeAliasesAddU64(builder, u64): builder.PrependUint64Slot(7, u64, 0)
+def TypeAliasesAddF32(builder, f32): builder.PrependFloat32Slot(8, f32, 0.0)
+def TypeAliasesAddF64(builder, f64): builder.PrependFloat64Slot(9, f64, 0.0)
+def TypeAliasesAddV8(builder, v8): builder.PrependUOffsetTRelativeSlot(10, flatbuffers.number_types.UOffsetTFlags.py_type(v8), 0)
+def TypeAliasesStartV8Vector(builder, numElems): return builder.StartVector(1, numElems, 1)
+def TypeAliasesAddVf64(builder, vf64): builder.PrependUOffsetTRelativeSlot(11, flatbuffers.number_types.UOffsetTFlags.py_type(vf64), 0)
+def TypeAliasesStartVf64Vector(builder, numElems): return builder.StartVector(8, numElems, 8)
+def TypeAliasesEnd(builder): return builder.EndObject()
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Vec3.cs b/third_party/flatbuffers/tests/MyGame/Example/Vec3.cs
new file mode 100644
index 0000000..1dbb315
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Vec3.cs
@@ -0,0 +1,49 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct Vec3 : IFlatbufferObject
+{
+  private Struct __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
+  public Vec3 __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public float X { get { return __p.bb.GetFloat(__p.bb_pos + 0); } }
+  public void MutateX(float x) { __p.bb.PutFloat(__p.bb_pos + 0, x); }
+  public float Y { get { return __p.bb.GetFloat(__p.bb_pos + 4); } }
+  public void MutateY(float y) { __p.bb.PutFloat(__p.bb_pos + 4, y); }
+  public float Z { get { return __p.bb.GetFloat(__p.bb_pos + 8); } }
+  public void MutateZ(float z) { __p.bb.PutFloat(__p.bb_pos + 8, z); }
+  public double Test1 { get { return __p.bb.GetDouble(__p.bb_pos + 16); } }
+  public void MutateTest1(double test1) { __p.bb.PutDouble(__p.bb_pos + 16, test1); }
+  public MyGame.Example.Color Test2 { get { return (MyGame.Example.Color)__p.bb.Get(__p.bb_pos + 24); } }
+  public void MutateTest2(MyGame.Example.Color test2) { __p.bb.Put(__p.bb_pos + 24, (byte)test2); }
+  public MyGame.Example.Test Test3 { get { return (new MyGame.Example.Test()).__assign(__p.bb_pos + 26, __p.bb); } }
+
+  public static Offset<MyGame.Example.Vec3> CreateVec3(FlatBufferBuilder builder, float X, float Y, float Z, double Test1, MyGame.Example.Color Test2, short test3_A, sbyte test3_B) {
+    builder.Prep(8, 32);
+    builder.Pad(2);
+    builder.Prep(2, 4);
+    builder.Pad(1);
+    builder.PutSbyte(test3_B);
+    builder.PutShort(test3_A);
+    builder.Pad(1);
+    builder.PutByte((byte)Test2);
+    builder.PutDouble(Test1);
+    builder.Pad(4);
+    builder.PutFloat(Z);
+    builder.PutFloat(Y);
+    builder.PutFloat(X);
+    return new Offset<MyGame.Example.Vec3>(builder.Offset);
+  }
+};
+
+
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Vec3.go b/third_party/flatbuffers/tests/MyGame/Example/Vec3.go
new file mode 100644
index 0000000..9131afd
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Vec3.go
@@ -0,0 +1,80 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package Example
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+
+type Vec3 struct {
+	_tab flatbuffers.Struct
+}
+
+func (rcv *Vec3) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *Vec3) Table() flatbuffers.Table {
+	return rcv._tab.Table
+}
+
+func (rcv *Vec3) X() float32 {
+	return rcv._tab.GetFloat32(rcv._tab.Pos + flatbuffers.UOffsetT(0))
+}
+func (rcv *Vec3) MutateX(n float32) bool {
+	return rcv._tab.MutateFloat32(rcv._tab.Pos+flatbuffers.UOffsetT(0), n)
+}
+
+func (rcv *Vec3) Y() float32 {
+	return rcv._tab.GetFloat32(rcv._tab.Pos + flatbuffers.UOffsetT(4))
+}
+func (rcv *Vec3) MutateY(n float32) bool {
+	return rcv._tab.MutateFloat32(rcv._tab.Pos+flatbuffers.UOffsetT(4), n)
+}
+
+func (rcv *Vec3) Z() float32 {
+	return rcv._tab.GetFloat32(rcv._tab.Pos + flatbuffers.UOffsetT(8))
+}
+func (rcv *Vec3) MutateZ(n float32) bool {
+	return rcv._tab.MutateFloat32(rcv._tab.Pos+flatbuffers.UOffsetT(8), n)
+}
+
+func (rcv *Vec3) Test1() float64 {
+	return rcv._tab.GetFloat64(rcv._tab.Pos + flatbuffers.UOffsetT(16))
+}
+func (rcv *Vec3) MutateTest1(n float64) bool {
+	return rcv._tab.MutateFloat64(rcv._tab.Pos+flatbuffers.UOffsetT(16), n)
+}
+
+func (rcv *Vec3) Test2() Color {
+	return Color(rcv._tab.GetByte(rcv._tab.Pos + flatbuffers.UOffsetT(24)))
+}
+func (rcv *Vec3) MutateTest2(n Color) bool {
+	return rcv._tab.MutateByte(rcv._tab.Pos+flatbuffers.UOffsetT(24), byte(n))
+}
+
+func (rcv *Vec3) Test3(obj *Test) *Test {
+	if obj == nil {
+		obj = new(Test)
+	}
+	obj.Init(rcv._tab.Bytes, rcv._tab.Pos+26)
+	return obj
+}
+
+func CreateVec3(builder *flatbuffers.Builder, x float32, y float32, z float32, test1 float64, test2 Color, test3_a int16, test3_b int8) flatbuffers.UOffsetT {
+	builder.Prep(8, 32)
+	builder.Pad(2)
+	builder.Prep(2, 4)
+	builder.Pad(1)
+	builder.PrependInt8(test3_b)
+	builder.PrependInt16(test3_a)
+	builder.Pad(1)
+	builder.PrependByte(byte(test2))
+	builder.PrependFloat64(test1)
+	builder.Pad(4)
+	builder.PrependFloat32(z)
+	builder.PrependFloat32(y)
+	builder.PrependFloat32(x)
+	return builder.Offset()
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Vec3.java b/third_party/flatbuffers/tests/MyGame/Example/Vec3.java
new file mode 100644
index 0000000..0b67c74
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Vec3.java
@@ -0,0 +1,45 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class Vec3 extends Struct {
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public Vec3 __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public float x() { return bb.getFloat(bb_pos + 0); }
+  public void mutateX(float x) { bb.putFloat(bb_pos + 0, x); }
+  public float y() { return bb.getFloat(bb_pos + 4); }
+  public void mutateY(float y) { bb.putFloat(bb_pos + 4, y); }
+  public float z() { return bb.getFloat(bb_pos + 8); }
+  public void mutateZ(float z) { bb.putFloat(bb_pos + 8, z); }
+  public double test1() { return bb.getDouble(bb_pos + 16); }
+  public void mutateTest1(double test1) { bb.putDouble(bb_pos + 16, test1); }
+  public int test2() { return bb.get(bb_pos + 24) & 0xFF; }
+  public void mutateTest2(int test2) { bb.put(bb_pos + 24, (byte)test2); }
+  public MyGame.Example.Test test3() { return test3(new MyGame.Example.Test()); }
+  public MyGame.Example.Test test3(MyGame.Example.Test obj) { return obj.__assign(bb_pos + 26, bb); }
+
+  public static int createVec3(FlatBufferBuilder builder, float x, float y, float z, double test1, int test2, short test3_a, byte test3_b) {
+    builder.prep(8, 32);
+    builder.pad(2);
+    builder.prep(2, 4);
+    builder.pad(1);
+    builder.putByte(test3_b);
+    builder.putShort(test3_a);
+    builder.pad(1);
+    builder.putByte((byte)test2);
+    builder.putDouble(test1);
+    builder.pad(4);
+    builder.putFloat(z);
+    builder.putFloat(y);
+    builder.putFloat(x);
+    return builder.offset();
+  }
+}
+
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Vec3.kt b/third_party/flatbuffers/tests/MyGame/Example/Vec3.kt
new file mode 100644
index 0000000..90f1b4a
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Vec3.kt
@@ -0,0 +1,50 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Vec3 : Struct() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : Vec3 {
+        __init(_i, _bb)
+        return this
+    }
+    val x : Float get() = bb.getFloat(bb_pos + 0)
+    fun mutateX(x: Float) : ByteBuffer = bb.putFloat(bb_pos + 0, x)
+    val y : Float get() = bb.getFloat(bb_pos + 4)
+    fun mutateY(y: Float) : ByteBuffer = bb.putFloat(bb_pos + 4, y)
+    val z : Float get() = bb.getFloat(bb_pos + 8)
+    fun mutateZ(z: Float) : ByteBuffer = bb.putFloat(bb_pos + 8, z)
+    val test1 : Double get() = bb.getDouble(bb_pos + 16)
+    fun mutateTest1(test1: Double) : ByteBuffer = bb.putDouble(bb_pos + 16, test1)
+    val test2 : UByte get() = bb.get(bb_pos + 24).toUByte()
+    fun mutateTest2(test2: UByte) : ByteBuffer = bb.put(bb_pos + 24, test2.toByte())
+    val test3 : MyGame.Example.Test? get() = test3(MyGame.Example.Test())
+    fun test3(obj: MyGame.Example.Test) : MyGame.Example.Test? = obj.__assign(bb_pos + 26, bb)
+    companion object {
+        fun createVec3(builder: FlatBufferBuilder, x: Float, y: Float, z: Float, test1: Double, test2: UByte, test3_a: Short, test3_b: Byte) : Int {
+            builder.prep(8, 32)
+            builder.pad(2)
+            builder.prep(2, 4)
+            builder.pad(1)
+            builder.putByte(test3_b)
+            builder.putShort(test3_a)
+            builder.pad(1)
+            builder.putByte(test2.toByte())
+            builder.putDouble(test1)
+            builder.pad(4)
+            builder.putFloat(z)
+            builder.putFloat(y)
+            builder.putFloat(x)
+            return builder.offset()
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Vec3.lua b/third_party/flatbuffers/tests/MyGame/Example/Vec3.lua
new file mode 100644
index 0000000..24d4cc1
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Vec3.lua
@@ -0,0 +1,54 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Example
+
+local flatbuffers = require('flatbuffers')
+
+local Vec3 = {} -- the module
+local Vec3_mt = {} -- the class metatable
+
+function Vec3.New()
+    local o = {}
+    setmetatable(o, {__index = Vec3_mt})
+    return o
+end
+function Vec3_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function Vec3_mt:X()
+    return self.view:Get(flatbuffers.N.Float32, self.view.pos + 0)
+end
+function Vec3_mt:Y()
+    return self.view:Get(flatbuffers.N.Float32, self.view.pos + 4)
+end
+function Vec3_mt:Z()
+    return self.view:Get(flatbuffers.N.Float32, self.view.pos + 8)
+end
+function Vec3_mt:Test1()
+    return self.view:Get(flatbuffers.N.Float64, self.view.pos + 16)
+end
+function Vec3_mt:Test2()
+    return self.view:Get(flatbuffers.N.Uint8, self.view.pos + 24)
+end
+function Vec3_mt:Test3(obj)
+    obj:Init(self.view.bytes, self.view.pos + 26)
+    return obj
+end
+function Vec3.CreateVec3(builder, x, y, z, test1, test2, test3_a, test3_b)
+    builder:Prep(8, 32)
+    builder:Pad(2)
+    builder:Prep(2, 4)
+    builder:Pad(1)
+    builder:PrependInt8(test3_b)
+    builder:PrependInt16(test3_a)
+    builder:Pad(1)
+    builder:PrependUint8(test2)
+    builder:PrependFloat64(test1)
+    builder:Pad(4)
+    builder:PrependFloat32(z)
+    builder:PrependFloat32(y)
+    builder:PrependFloat32(x)
+    return builder:Offset()
+end
+
+return Vec3 -- return the module
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Vec3.php b/third_party/flatbuffers/tests/MyGame/Example/Vec3.php
new file mode 100644
index 0000000..4d149e6
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Vec3.php
@@ -0,0 +1,96 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame\Example;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class Vec3 extends Struct
+{
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return Vec3
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @return float
+     */
+    public function GetX()
+    {
+        return $this->bb->getFloat($this->bb_pos + 0);
+    }
+
+    /**
+     * @return float
+     */
+    public function GetY()
+    {
+        return $this->bb->getFloat($this->bb_pos + 4);
+    }
+
+    /**
+     * @return float
+     */
+    public function GetZ()
+    {
+        return $this->bb->getFloat($this->bb_pos + 8);
+    }
+
+    /**
+     * @return double
+     */
+    public function GetTest1()
+    {
+        return $this->bb->getDouble($this->bb_pos + 16);
+    }
+
+    /**
+     * @return byte
+     */
+    public function GetTest2()
+    {
+        return $this->bb->getByte($this->bb_pos + 24);
+    }
+
+    /**
+     * @return Test
+     */
+    public function getTest3()
+    {
+        $obj = new Test();
+        $obj->init($this->bb_pos + 26, $this->bb);
+        return $obj;
+    }
+
+
+    /**
+     * @return int offset
+     */
+    public static function createVec3(FlatBufferBuilder $builder, $x, $y, $z, $test1, $test2, $test3_a, $test3_b)
+    {
+        $builder->prep(8, 32);
+        $builder->pad(2);
+        $builder->prep(2, 4);
+        $builder->pad(1);
+        $builder->putSbyte($test3_b);
+        $builder->putShort($test3_a);
+        $builder->pad(1);
+        $builder->putByte($test2);
+        $builder->putDouble($test1);
+        $builder->pad(4);
+        $builder->putFloat($z);
+        $builder->putFloat($y);
+        $builder->putFloat($x);
+        return $builder->offset();
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example/Vec3.py b/third_party/flatbuffers/tests/MyGame/Example/Vec3.py
new file mode 100644
index 0000000..1f32390
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/Vec3.py
@@ -0,0 +1,44 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+import flatbuffers
+
+class Vec3(object):
+    __slots__ = ['_tab']
+
+    # Vec3
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # Vec3
+    def X(self): return self._tab.Get(flatbuffers.number_types.Float32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(0))
+    # Vec3
+    def Y(self): return self._tab.Get(flatbuffers.number_types.Float32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(4))
+    # Vec3
+    def Z(self): return self._tab.Get(flatbuffers.number_types.Float32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(8))
+    # Vec3
+    def Test1(self): return self._tab.Get(flatbuffers.number_types.Float64Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(16))
+    # Vec3
+    def Test2(self): return self._tab.Get(flatbuffers.number_types.Uint8Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(24))
+    # Vec3
+    def Test3(self, obj):
+        obj.Init(self._tab.Bytes, self._tab.Pos + 26)
+        return obj
+
+
+def CreateVec3(builder, x, y, z, test1, test2, test3_a, test3_b):
+    builder.Prep(8, 32)
+    builder.Pad(2)
+    builder.Prep(2, 4)
+    builder.Pad(1)
+    builder.PrependInt8(test3_b)
+    builder.PrependInt16(test3_a)
+    builder.Pad(1)
+    builder.PrependUint8(test2)
+    builder.PrependFloat64(test1)
+    builder.Pad(4)
+    builder.PrependFloat32(z)
+    builder.PrependFloat32(y)
+    builder.PrependFloat32(x)
+    return builder.Offset()
diff --git a/third_party/flatbuffers/tests/MyGame/Example/__init__.py b/third_party/flatbuffers/tests/MyGame/Example/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example/__init__.py
diff --git a/third_party/flatbuffers/tests/MyGame/Example2/Monster.cs b/third_party/flatbuffers/tests/MyGame/Example2/Monster.cs
new file mode 100644
index 0000000..a6e9dce
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example2/Monster.cs
@@ -0,0 +1,30 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example2
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct Monster : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static Monster GetRootAsMonster(ByteBuffer _bb) { return GetRootAsMonster(_bb, new Monster()); }
+  public static Monster GetRootAsMonster(ByteBuffer _bb, Monster obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public Monster __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+
+  public static void StartMonster(FlatBufferBuilder builder) { builder.StartTable(0); }
+  public static Offset<MyGame.Example2.Monster> EndMonster(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<MyGame.Example2.Monster>(o);
+  }
+};
+
+
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example2/Monster.go b/third_party/flatbuffers/tests/MyGame/Example2/Monster.go
new file mode 100644
index 0000000..d0fae94
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example2/Monster.go
@@ -0,0 +1,34 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package Example2
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+
+type Monster struct {
+	_tab flatbuffers.Table
+}
+
+func GetRootAsMonster(buf []byte, offset flatbuffers.UOffsetT) *Monster {
+	n := flatbuffers.GetUOffsetT(buf[offset:])
+	x := &Monster{}
+	x.Init(buf, n+offset)
+	return x
+}
+
+func (rcv *Monster) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *Monster) Table() flatbuffers.Table {
+	return rcv._tab
+}
+
+func MonsterStart(builder *flatbuffers.Builder) {
+	builder.StartObject(0)
+}
+func MonsterEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+	return builder.EndObject()
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example2/Monster.java b/third_party/flatbuffers/tests/MyGame/Example2/Monster.java
new file mode 100644
index 0000000..7e0cae1
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example2/Monster.java
@@ -0,0 +1,25 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example2;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class Monster extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static Monster getRootAsMonster(ByteBuffer _bb) { return getRootAsMonster(_bb, new Monster()); }
+  public static Monster getRootAsMonster(ByteBuffer _bb, Monster obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public Monster __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+
+  public static void startMonster(FlatBufferBuilder builder) { builder.startTable(0); }
+  public static int endMonster(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+}
+
diff --git a/third_party/flatbuffers/tests/MyGame/Example2/Monster.kt b/third_party/flatbuffers/tests/MyGame/Example2/Monster.kt
new file mode 100644
index 0000000..de587ba
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example2/Monster.kt
@@ -0,0 +1,33 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example2
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Monster : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : Monster {
+        __init(_i, _bb)
+        return this
+    }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsMonster(_bb: ByteBuffer): Monster = getRootAsMonster(_bb, Monster())
+        fun getRootAsMonster(_bb: ByteBuffer, obj: Monster): Monster {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun startMonster(builder: FlatBufferBuilder) = builder.startTable(0)
+        fun endMonster(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+            return o
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example2/Monster.lua b/third_party/flatbuffers/tests/MyGame/Example2/Monster.lua
new file mode 100644
index 0000000..347b5db
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example2/Monster.lua
@@ -0,0 +1,27 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Example2
+
+local flatbuffers = require('flatbuffers')
+
+local Monster = {} -- the module
+local Monster_mt = {} -- the class metatable
+
+function Monster.New()
+    local o = {}
+    setmetatable(o, {__index = Monster_mt})
+    return o
+end
+function Monster.GetRootAsMonster(buf, offset)
+    local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)
+    local o = Monster.New()
+    o:Init(buf, n + offset)
+    return o
+end
+function Monster_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function Monster.Start(builder) builder:StartObject(0) end
+function Monster.End(builder) return builder:EndObject() end
+
+return Monster -- return the module
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/MyGame/Example2/Monster.php b/third_party/flatbuffers/tests/MyGame/Example2/Monster.php
new file mode 100644
index 0000000..b00f150
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example2/Monster.php
@@ -0,0 +1,79 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame\Example2;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class Monster extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return Monster
+     */
+    public static function getRootAsMonster(ByteBuffer $bb)
+    {
+        $obj = new Monster();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    public static function MonsterIdentifier()
+    {
+        return "MONS";
+    }
+
+    public static function MonsterBufferHasIdentifier(ByteBuffer $buf)
+    {
+        return self::__has_identifier($buf, self::MonsterIdentifier());
+    }
+
+    public static function MonsterExtension()
+    {
+        return "mon";
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return Monster
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startMonster(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return Monster
+     */
+    public static function createMonster(FlatBufferBuilder $builder, )
+    {
+        $builder->startObject(0);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endMonster(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/Example2/Monster.py b/third_party/flatbuffers/tests/MyGame/Example2/Monster.py
new file mode 100644
index 0000000..44cc906
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example2/Monster.py
@@ -0,0 +1,26 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example2
+
+import flatbuffers
+
+class Monster(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAsMonster(cls, buf, offset):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = Monster()
+        x.Init(buf, n + offset)
+        return x
+
+    @classmethod
+    def MonsterBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
+        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)
+
+    # Monster
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+def MonsterStart(builder): builder.StartObject(0)
+def MonsterEnd(builder): return builder.EndObject()
diff --git a/third_party/flatbuffers/tests/MyGame/Example2/__init__.py b/third_party/flatbuffers/tests/MyGame/Example2/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/Example2/__init__.py
diff --git a/third_party/flatbuffers/tests/MyGame/InParentNamespace.cs b/third_party/flatbuffers/tests/MyGame/InParentNamespace.cs
new file mode 100644
index 0000000..869c400
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/InParentNamespace.cs
@@ -0,0 +1,30 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct InParentNamespace : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static InParentNamespace GetRootAsInParentNamespace(ByteBuffer _bb) { return GetRootAsInParentNamespace(_bb, new InParentNamespace()); }
+  public static InParentNamespace GetRootAsInParentNamespace(ByteBuffer _bb, InParentNamespace obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public InParentNamespace __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+
+  public static void StartInParentNamespace(FlatBufferBuilder builder) { builder.StartTable(0); }
+  public static Offset<MyGame.InParentNamespace> EndInParentNamespace(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<MyGame.InParentNamespace>(o);
+  }
+};
+
+
+}
diff --git a/third_party/flatbuffers/tests/MyGame/InParentNamespace.go b/third_party/flatbuffers/tests/MyGame/InParentNamespace.go
new file mode 100644
index 0000000..fc6ce32
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/InParentNamespace.go
@@ -0,0 +1,34 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package MyGame
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+
+type InParentNamespace struct {
+	_tab flatbuffers.Table
+}
+
+func GetRootAsInParentNamespace(buf []byte, offset flatbuffers.UOffsetT) *InParentNamespace {
+	n := flatbuffers.GetUOffsetT(buf[offset:])
+	x := &InParentNamespace{}
+	x.Init(buf, n+offset)
+	return x
+}
+
+func (rcv *InParentNamespace) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *InParentNamespace) Table() flatbuffers.Table {
+	return rcv._tab
+}
+
+func InParentNamespaceStart(builder *flatbuffers.Builder) {
+	builder.StartObject(0)
+}
+func InParentNamespaceEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+	return builder.EndObject()
+}
diff --git a/third_party/flatbuffers/tests/MyGame/InParentNamespace.java b/third_party/flatbuffers/tests/MyGame/InParentNamespace.java
new file mode 100644
index 0000000..fd10bc3
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/InParentNamespace.java
@@ -0,0 +1,25 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class InParentNamespace extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static InParentNamespace getRootAsInParentNamespace(ByteBuffer _bb) { return getRootAsInParentNamespace(_bb, new InParentNamespace()); }
+  public static InParentNamespace getRootAsInParentNamespace(ByteBuffer _bb, InParentNamespace obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public InParentNamespace __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+
+  public static void startInParentNamespace(FlatBufferBuilder builder) { builder.startTable(0); }
+  public static int endInParentNamespace(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+}
+
diff --git a/third_party/flatbuffers/tests/MyGame/InParentNamespace.kt b/third_party/flatbuffers/tests/MyGame/InParentNamespace.kt
new file mode 100644
index 0000000..76779fc
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/InParentNamespace.kt
@@ -0,0 +1,33 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class InParentNamespace : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : InParentNamespace {
+        __init(_i, _bb)
+        return this
+    }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsInParentNamespace(_bb: ByteBuffer): InParentNamespace = getRootAsInParentNamespace(_bb, InParentNamespace())
+        fun getRootAsInParentNamespace(_bb: ByteBuffer, obj: InParentNamespace): InParentNamespace {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun startInParentNamespace(builder: FlatBufferBuilder) = builder.startTable(0)
+        fun endInParentNamespace(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+            return o
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/InParentNamespace.lua b/third_party/flatbuffers/tests/MyGame/InParentNamespace.lua
new file mode 100644
index 0000000..b3fa0c8
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/InParentNamespace.lua
@@ -0,0 +1,27 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: MyGame
+
+local flatbuffers = require('flatbuffers')
+
+local InParentNamespace = {} -- the module
+local InParentNamespace_mt = {} -- the class metatable
+
+function InParentNamespace.New()
+    local o = {}
+    setmetatable(o, {__index = InParentNamespace_mt})
+    return o
+end
+function InParentNamespace.GetRootAsInParentNamespace(buf, offset)
+    local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)
+    local o = InParentNamespace.New()
+    o:Init(buf, n + offset)
+    return o
+end
+function InParentNamespace_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function InParentNamespace.Start(builder) builder:StartObject(0) end
+function InParentNamespace.End(builder) return builder:EndObject() end
+
+return InParentNamespace -- return the module
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/MyGame/InParentNamespace.php b/third_party/flatbuffers/tests/MyGame/InParentNamespace.php
new file mode 100644
index 0000000..e13a4f3
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/InParentNamespace.php
@@ -0,0 +1,79 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class InParentNamespace extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return InParentNamespace
+     */
+    public static function getRootAsInParentNamespace(ByteBuffer $bb)
+    {
+        $obj = new InParentNamespace();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    public static function InParentNamespaceIdentifier()
+    {
+        return "MONS";
+    }
+
+    public static function InParentNamespaceBufferHasIdentifier(ByteBuffer $buf)
+    {
+        return self::__has_identifier($buf, self::InParentNamespaceIdentifier());
+    }
+
+    public static function InParentNamespaceExtension()
+    {
+        return "mon";
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return InParentNamespace
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startInParentNamespace(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return InParentNamespace
+     */
+    public static function createInParentNamespace(FlatBufferBuilder $builder, )
+    {
+        $builder->startObject(0);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endInParentNamespace(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/InParentNamespace.py b/third_party/flatbuffers/tests/MyGame/InParentNamespace.py
new file mode 100644
index 0000000..3bfcca7
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/InParentNamespace.py
@@ -0,0 +1,26 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: MyGame
+
+import flatbuffers
+
+class InParentNamespace(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAsInParentNamespace(cls, buf, offset):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = InParentNamespace()
+        x.Init(buf, n + offset)
+        return x
+
+    @classmethod
+    def InParentNamespaceBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
+        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)
+
+    # InParentNamespace
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+def InParentNamespaceStart(builder): builder.StartObject(0)
+def InParentNamespaceEnd(builder): return builder.EndObject()
diff --git a/third_party/flatbuffers/tests/MyGame/MonsterExtra.cs b/third_party/flatbuffers/tests/MyGame/MonsterExtra.cs
new file mode 100644
index 0000000..5706390
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/MonsterExtra.cs
@@ -0,0 +1,108 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct MonsterExtra : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static MonsterExtra GetRootAsMonsterExtra(ByteBuffer _bb) { return GetRootAsMonsterExtra(_bb, new MonsterExtra()); }
+  public static MonsterExtra GetRootAsMonsterExtra(ByteBuffer _bb, MonsterExtra obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public static bool MonsterExtraBufferHasIdentifier(ByteBuffer _bb) { return Table.__has_identifier(_bb, "MONE"); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public MonsterExtra __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public double D0 { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)Double.NaN; } }
+  public bool MutateD0(double d0) { int o = __p.__offset(4); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, d0); return true; } else { return false; } }
+  public double D1 { get { int o = __p.__offset(6); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)Double.NaN; } }
+  public bool MutateD1(double d1) { int o = __p.__offset(6); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, d1); return true; } else { return false; } }
+  public double D2 { get { int o = __p.__offset(8); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)Double.PositiveInfinity; } }
+  public bool MutateD2(double d2) { int o = __p.__offset(8); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, d2); return true; } else { return false; } }
+  public double D3 { get { int o = __p.__offset(10); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)Double.NegativeInfinity; } }
+  public bool MutateD3(double d3) { int o = __p.__offset(10); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, d3); return true; } else { return false; } }
+  public float F0 { get { int o = __p.__offset(12); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.NaN; } }
+  public bool MutateF0(float f0) { int o = __p.__offset(12); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, f0); return true; } else { return false; } }
+  public float F1 { get { int o = __p.__offset(14); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.NaN; } }
+  public bool MutateF1(float f1) { int o = __p.__offset(14); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, f1); return true; } else { return false; } }
+  public float F2 { get { int o = __p.__offset(16); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.PositiveInfinity; } }
+  public bool MutateF2(float f2) { int o = __p.__offset(16); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, f2); return true; } else { return false; } }
+  public float F3 { get { int o = __p.__offset(18); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.NegativeInfinity; } }
+  public bool MutateF3(float f3) { int o = __p.__offset(18); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, f3); return true; } else { return false; } }
+  public double Dvec(int j) { int o = __p.__offset(20); return o != 0 ? __p.bb.GetDouble(__p.__vector(o) + j * 8) : (double)0; }
+  public int DvecLength { get { int o = __p.__offset(20); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetDvecBytes() { return __p.__vector_as_span(20); }
+#else
+  public ArraySegment<byte>? GetDvecBytes() { return __p.__vector_as_arraysegment(20); }
+#endif
+  public double[] GetDvecArray() { return __p.__vector_as_array<double>(20); }
+  public bool MutateDvec(int j, double dvec) { int o = __p.__offset(20); if (o != 0) { __p.bb.PutDouble(__p.__vector(o) + j * 8, dvec); return true; } else { return false; } }
+  public float Fvec(int j) { int o = __p.__offset(22); return o != 0 ? __p.bb.GetFloat(__p.__vector(o) + j * 4) : (float)0; }
+  public int FvecLength { get { int o = __p.__offset(22); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetFvecBytes() { return __p.__vector_as_span(22); }
+#else
+  public ArraySegment<byte>? GetFvecBytes() { return __p.__vector_as_arraysegment(22); }
+#endif
+  public float[] GetFvecArray() { return __p.__vector_as_array<float>(22); }
+  public bool MutateFvec(int j, float fvec) { int o = __p.__offset(22); if (o != 0) { __p.bb.PutFloat(__p.__vector(o) + j * 4, fvec); return true; } else { return false; } }
+
+  public static Offset<MyGame.MonsterExtra> CreateMonsterExtra(FlatBufferBuilder builder,
+      double d0 = Double.NaN,
+      double d1 = Double.NaN,
+      double d2 = Double.PositiveInfinity,
+      double d3 = Double.NegativeInfinity,
+      float f0 = Single.NaN,
+      float f1 = Single.NaN,
+      float f2 = Single.PositiveInfinity,
+      float f3 = Single.NegativeInfinity,
+      VectorOffset dvecOffset = default(VectorOffset),
+      VectorOffset fvecOffset = default(VectorOffset)) {
+    builder.StartTable(10);
+    MonsterExtra.AddD3(builder, d3);
+    MonsterExtra.AddD2(builder, d2);
+    MonsterExtra.AddD1(builder, d1);
+    MonsterExtra.AddD0(builder, d0);
+    MonsterExtra.AddFvec(builder, fvecOffset);
+    MonsterExtra.AddDvec(builder, dvecOffset);
+    MonsterExtra.AddF3(builder, f3);
+    MonsterExtra.AddF2(builder, f2);
+    MonsterExtra.AddF1(builder, f1);
+    MonsterExtra.AddF0(builder, f0);
+    return MonsterExtra.EndMonsterExtra(builder);
+  }
+
+  public static void StartMonsterExtra(FlatBufferBuilder builder) { builder.StartTable(10); }
+  public static void AddD0(FlatBufferBuilder builder, double d0) { builder.AddDouble(0, d0, Double.NaN); }
+  public static void AddD1(FlatBufferBuilder builder, double d1) { builder.AddDouble(1, d1, Double.NaN); }
+  public static void AddD2(FlatBufferBuilder builder, double d2) { builder.AddDouble(2, d2, Double.PositiveInfinity); }
+  public static void AddD3(FlatBufferBuilder builder, double d3) { builder.AddDouble(3, d3, Double.NegativeInfinity); }
+  public static void AddF0(FlatBufferBuilder builder, float f0) { builder.AddFloat(4, f0, Single.NaN); }
+  public static void AddF1(FlatBufferBuilder builder, float f1) { builder.AddFloat(5, f1, Single.NaN); }
+  public static void AddF2(FlatBufferBuilder builder, float f2) { builder.AddFloat(6, f2, Single.PositiveInfinity); }
+  public static void AddF3(FlatBufferBuilder builder, float f3) { builder.AddFloat(7, f3, Single.NegativeInfinity); }
+  public static void AddDvec(FlatBufferBuilder builder, VectorOffset dvecOffset) { builder.AddOffset(8, dvecOffset.Value, 0); }
+  public static VectorOffset CreateDvecVector(FlatBufferBuilder builder, double[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddDouble(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateDvecVectorBlock(FlatBufferBuilder builder, double[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
+  public static void StartDvecVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
+  public static void AddFvec(FlatBufferBuilder builder, VectorOffset fvecOffset) { builder.AddOffset(9, fvecOffset.Value, 0); }
+  public static VectorOffset CreateFvecVector(FlatBufferBuilder builder, float[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddFloat(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateFvecVectorBlock(FlatBufferBuilder builder, float[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
+  public static void StartFvecVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
+  public static Offset<MyGame.MonsterExtra> EndMonsterExtra(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<MyGame.MonsterExtra>(o);
+  }
+  public static void FinishMonsterExtraBuffer(FlatBufferBuilder builder, Offset<MyGame.MonsterExtra> offset) { builder.Finish(offset.Value, "MONE"); }
+  public static void FinishSizePrefixedMonsterExtraBuffer(FlatBufferBuilder builder, Offset<MyGame.MonsterExtra> offset) { builder.FinishSizePrefixed(offset.Value, "MONE"); }
+};
+
+
+}
diff --git a/third_party/flatbuffers/tests/MyGame/MonsterExtra.java b/third_party/flatbuffers/tests/MyGame/MonsterExtra.java
new file mode 100644
index 0000000..3022596
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/MonsterExtra.java
@@ -0,0 +1,93 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class MonsterExtra extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static MonsterExtra getRootAsMonsterExtra(ByteBuffer _bb) { return getRootAsMonsterExtra(_bb, new MonsterExtra()); }
+  public static MonsterExtra getRootAsMonsterExtra(ByteBuffer _bb, MonsterExtra obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public static boolean MonsterExtraBufferHasIdentifier(ByteBuffer _bb) { return __has_identifier(_bb, "MONE"); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public MonsterExtra __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public double d0() { int o = __offset(4); return o != 0 ? bb.getDouble(o + bb_pos) : Double.NaN; }
+  public boolean mutateD0(double d0) { int o = __offset(4); if (o != 0) { bb.putDouble(o + bb_pos, d0); return true; } else { return false; } }
+  public double d1() { int o = __offset(6); return o != 0 ? bb.getDouble(o + bb_pos) : Double.NaN; }
+  public boolean mutateD1(double d1) { int o = __offset(6); if (o != 0) { bb.putDouble(o + bb_pos, d1); return true; } else { return false; } }
+  public double d2() { int o = __offset(8); return o != 0 ? bb.getDouble(o + bb_pos) : Double.POSITIVE_INFINITY; }
+  public boolean mutateD2(double d2) { int o = __offset(8); if (o != 0) { bb.putDouble(o + bb_pos, d2); return true; } else { return false; } }
+  public double d3() { int o = __offset(10); return o != 0 ? bb.getDouble(o + bb_pos) : Double.NEGATIVE_INFINITY; }
+  public boolean mutateD3(double d3) { int o = __offset(10); if (o != 0) { bb.putDouble(o + bb_pos, d3); return true; } else { return false; } }
+  public float f0() { int o = __offset(12); return o != 0 ? bb.getFloat(o + bb_pos) : Float.NaN; }
+  public boolean mutateF0(float f0) { int o = __offset(12); if (o != 0) { bb.putFloat(o + bb_pos, f0); return true; } else { return false; } }
+  public float f1() { int o = __offset(14); return o != 0 ? bb.getFloat(o + bb_pos) : Float.NaN; }
+  public boolean mutateF1(float f1) { int o = __offset(14); if (o != 0) { bb.putFloat(o + bb_pos, f1); return true; } else { return false; } }
+  public float f2() { int o = __offset(16); return o != 0 ? bb.getFloat(o + bb_pos) : Float.POSITIVE_INFINITY; }
+  public boolean mutateF2(float f2) { int o = __offset(16); if (o != 0) { bb.putFloat(o + bb_pos, f2); return true; } else { return false; } }
+  public float f3() { int o = __offset(18); return o != 0 ? bb.getFloat(o + bb_pos) : Float.NEGATIVE_INFINITY; }
+  public boolean mutateF3(float f3) { int o = __offset(18); if (o != 0) { bb.putFloat(o + bb_pos, f3); return true; } else { return false; } }
+  public double dvec(int j) { int o = __offset(20); return o != 0 ? bb.getDouble(__vector(o) + j * 8) : 0; }
+  public int dvecLength() { int o = __offset(20); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer dvecAsByteBuffer() { return __vector_as_bytebuffer(20, 8); }
+  public ByteBuffer dvecInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 20, 8); }
+  public boolean mutateDvec(int j, double dvec) { int o = __offset(20); if (o != 0) { bb.putDouble(__vector(o) + j * 8, dvec); return true; } else { return false; } }
+  public float fvec(int j) { int o = __offset(22); return o != 0 ? bb.getFloat(__vector(o) + j * 4) : 0; }
+  public int fvecLength() { int o = __offset(22); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer fvecAsByteBuffer() { return __vector_as_bytebuffer(22, 4); }
+  public ByteBuffer fvecInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 22, 4); }
+  public boolean mutateFvec(int j, float fvec) { int o = __offset(22); if (o != 0) { bb.putFloat(__vector(o) + j * 4, fvec); return true; } else { return false; } }
+
+  public static int createMonsterExtra(FlatBufferBuilder builder,
+      double d0,
+      double d1,
+      double d2,
+      double d3,
+      float f0,
+      float f1,
+      float f2,
+      float f3,
+      int dvecOffset,
+      int fvecOffset) {
+    builder.startTable(10);
+    MonsterExtra.addD3(builder, d3);
+    MonsterExtra.addD2(builder, d2);
+    MonsterExtra.addD1(builder, d1);
+    MonsterExtra.addD0(builder, d0);
+    MonsterExtra.addFvec(builder, fvecOffset);
+    MonsterExtra.addDvec(builder, dvecOffset);
+    MonsterExtra.addF3(builder, f3);
+    MonsterExtra.addF2(builder, f2);
+    MonsterExtra.addF1(builder, f1);
+    MonsterExtra.addF0(builder, f0);
+    return MonsterExtra.endMonsterExtra(builder);
+  }
+
+  public static void startMonsterExtra(FlatBufferBuilder builder) { builder.startTable(10); }
+  public static void addD0(FlatBufferBuilder builder, double d0) { builder.addDouble(0, d0, Double.NaN); }
+  public static void addD1(FlatBufferBuilder builder, double d1) { builder.addDouble(1, d1, Double.NaN); }
+  public static void addD2(FlatBufferBuilder builder, double d2) { builder.addDouble(2, d2, Double.POSITIVE_INFINITY); }
+  public static void addD3(FlatBufferBuilder builder, double d3) { builder.addDouble(3, d3, Double.NEGATIVE_INFINITY); }
+  public static void addF0(FlatBufferBuilder builder, float f0) { builder.addFloat(4, f0, Float.NaN); }
+  public static void addF1(FlatBufferBuilder builder, float f1) { builder.addFloat(5, f1, Float.NaN); }
+  public static void addF2(FlatBufferBuilder builder, float f2) { builder.addFloat(6, f2, Float.POSITIVE_INFINITY); }
+  public static void addF3(FlatBufferBuilder builder, float f3) { builder.addFloat(7, f3, Float.NEGATIVE_INFINITY); }
+  public static void addDvec(FlatBufferBuilder builder, int dvecOffset) { builder.addOffset(8, dvecOffset, 0); }
+  public static int createDvecVector(FlatBufferBuilder builder, double[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addDouble(data[i]); return builder.endVector(); }
+  public static void startDvecVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); }
+  public static void addFvec(FlatBufferBuilder builder, int fvecOffset) { builder.addOffset(9, fvecOffset, 0); }
+  public static int createFvecVector(FlatBufferBuilder builder, float[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addFloat(data[i]); return builder.endVector(); }
+  public static void startFvecVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
+  public static int endMonsterExtra(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+  public static void finishMonsterExtraBuffer(FlatBufferBuilder builder, int offset) { builder.finish(offset, "MONE"); }
+  public static void finishSizePrefixedMonsterExtraBuffer(FlatBufferBuilder builder, int offset) { builder.finishSizePrefixed(offset, "MONE"); }
+}
+
diff --git a/third_party/flatbuffers/tests/MyGame/MonsterExtra.kt b/third_party/flatbuffers/tests/MyGame/MonsterExtra.kt
new file mode 100644
index 0000000..96ea731
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/MonsterExtra.kt
@@ -0,0 +1,234 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class MonsterExtra : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : MonsterExtra {
+        __init(_i, _bb)
+        return this
+    }
+    val d0 : Double
+        get() {
+            val o = __offset(4)
+            return if(o != 0) bb.getDouble(o + bb_pos) else Double.NaN
+        }
+    fun mutateD0(d0: Double) : Boolean {
+        val o = __offset(4)
+        return if (o != 0) {
+            bb.putDouble(o + bb_pos, d0)
+            true
+        } else {
+            false
+        }
+    }
+    val d1 : Double
+        get() {
+            val o = __offset(6)
+            return if(o != 0) bb.getDouble(o + bb_pos) else Double.NaN
+        }
+    fun mutateD1(d1: Double) : Boolean {
+        val o = __offset(6)
+        return if (o != 0) {
+            bb.putDouble(o + bb_pos, d1)
+            true
+        } else {
+            false
+        }
+    }
+    val d2 : Double
+        get() {
+            val o = __offset(8)
+            return if(o != 0) bb.getDouble(o + bb_pos) else Double.POSITIVE_INFINITY
+        }
+    fun mutateD2(d2: Double) : Boolean {
+        val o = __offset(8)
+        return if (o != 0) {
+            bb.putDouble(o + bb_pos, d2)
+            true
+        } else {
+            false
+        }
+    }
+    val d3 : Double
+        get() {
+            val o = __offset(10)
+            return if(o != 0) bb.getDouble(o + bb_pos) else Double.NEGATIVE_INFINITY
+        }
+    fun mutateD3(d3: Double) : Boolean {
+        val o = __offset(10)
+        return if (o != 0) {
+            bb.putDouble(o + bb_pos, d3)
+            true
+        } else {
+            false
+        }
+    }
+    val f0 : Float
+        get() {
+            val o = __offset(12)
+            return if(o != 0) bb.getFloat(o + bb_pos) else Float.NaN
+        }
+    fun mutateF0(f0: Float) : Boolean {
+        val o = __offset(12)
+        return if (o != 0) {
+            bb.putFloat(o + bb_pos, f0)
+            true
+        } else {
+            false
+        }
+    }
+    val f1 : Float
+        get() {
+            val o = __offset(14)
+            return if(o != 0) bb.getFloat(o + bb_pos) else Float.NaN
+        }
+    fun mutateF1(f1: Float) : Boolean {
+        val o = __offset(14)
+        return if (o != 0) {
+            bb.putFloat(o + bb_pos, f1)
+            true
+        } else {
+            false
+        }
+    }
+    val f2 : Float
+        get() {
+            val o = __offset(16)
+            return if(o != 0) bb.getFloat(o + bb_pos) else Float.POSITIVE_INFINITY
+        }
+    fun mutateF2(f2: Float) : Boolean {
+        val o = __offset(16)
+        return if (o != 0) {
+            bb.putFloat(o + bb_pos, f2)
+            true
+        } else {
+            false
+        }
+    }
+    val f3 : Float
+        get() {
+            val o = __offset(18)
+            return if(o != 0) bb.getFloat(o + bb_pos) else Float.NEGATIVE_INFINITY
+        }
+    fun mutateF3(f3: Float) : Boolean {
+        val o = __offset(18)
+        return if (o != 0) {
+            bb.putFloat(o + bb_pos, f3)
+            true
+        } else {
+            false
+        }
+    }
+    fun dvec(j: Int) : Double {
+        val o = __offset(20)
+        return if (o != 0) {
+            bb.getDouble(__vector(o) + j * 8)
+        } else {
+            0.0
+        }
+    }
+    val dvecLength : Int
+        get() {
+            val o = __offset(20); return if (o != 0) __vector_len(o) else 0
+        }
+    val dvecAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(20, 8)
+    fun dvecInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 20, 8)
+    fun mutateDvec(j: Int, dvec: Double) : Boolean {
+        val o = __offset(20)
+        return if (o != 0) {
+            bb.putDouble(__vector(o) + j * 8, dvec)
+            true
+        } else {
+            false
+        }
+    }
+    fun fvec(j: Int) : Float {
+        val o = __offset(22)
+        return if (o != 0) {
+            bb.getFloat(__vector(o) + j * 4)
+        } else {
+            0.0f
+        }
+    }
+    val fvecLength : Int
+        get() {
+            val o = __offset(22); return if (o != 0) __vector_len(o) else 0
+        }
+    val fvecAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(22, 4)
+    fun fvecInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 22, 4)
+    fun mutateFvec(j: Int, fvec: Float) : Boolean {
+        val o = __offset(22)
+        return if (o != 0) {
+            bb.putFloat(__vector(o) + j * 4, fvec)
+            true
+        } else {
+            false
+        }
+    }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsMonsterExtra(_bb: ByteBuffer): MonsterExtra = getRootAsMonsterExtra(_bb, MonsterExtra())
+        fun getRootAsMonsterExtra(_bb: ByteBuffer, obj: MonsterExtra): MonsterExtra {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun MonsterExtraBufferHasIdentifier(_bb: ByteBuffer) : Boolean = __has_identifier(_bb, "MONE")
+        fun createMonsterExtra(builder: FlatBufferBuilder, d0: Double, d1: Double, d2: Double, d3: Double, f0: Float, f1: Float, f2: Float, f3: Float, dvecOffset: Int, fvecOffset: Int) : Int {
+            builder.startTable(10)
+            addD3(builder, d3)
+            addD2(builder, d2)
+            addD1(builder, d1)
+            addD0(builder, d0)
+            addFvec(builder, fvecOffset)
+            addDvec(builder, dvecOffset)
+            addF3(builder, f3)
+            addF2(builder, f2)
+            addF1(builder, f1)
+            addF0(builder, f0)
+            return endMonsterExtra(builder)
+        }
+        fun startMonsterExtra(builder: FlatBufferBuilder) = builder.startTable(10)
+        fun addD0(builder: FlatBufferBuilder, d0: Double) = builder.addDouble(0, d0, Double.NaN)
+        fun addD1(builder: FlatBufferBuilder, d1: Double) = builder.addDouble(1, d1, Double.NaN)
+        fun addD2(builder: FlatBufferBuilder, d2: Double) = builder.addDouble(2, d2, Double.POSITIVE_INFINITY)
+        fun addD3(builder: FlatBufferBuilder, d3: Double) = builder.addDouble(3, d3, Double.NEGATIVE_INFINITY)
+        fun addF0(builder: FlatBufferBuilder, f0: Float) = builder.addFloat(4, f0, Double.NaN)
+        fun addF1(builder: FlatBufferBuilder, f1: Float) = builder.addFloat(5, f1, Double.NaN)
+        fun addF2(builder: FlatBufferBuilder, f2: Float) = builder.addFloat(6, f2, Double.POSITIVE_INFINITY)
+        fun addF3(builder: FlatBufferBuilder, f3: Float) = builder.addFloat(7, f3, Double.NEGATIVE_INFINITY)
+        fun addDvec(builder: FlatBufferBuilder, dvec: Int) = builder.addOffset(8, dvec, 0)
+        fun createDvecVector(builder: FlatBufferBuilder, data: DoubleArray) : Int {
+            builder.startVector(8, data.size, 8)
+            for (i in data.size - 1 downTo 0) {
+                builder.addDouble(data[i])
+            }
+            return builder.endVector()
+        }
+        fun startDvecVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(8, numElems, 8)
+        fun addFvec(builder: FlatBufferBuilder, fvec: Int) = builder.addOffset(9, fvec, 0)
+        fun createFvecVector(builder: FlatBufferBuilder, data: FloatArray) : Int {
+            builder.startVector(4, data.size, 4)
+            for (i in data.size - 1 downTo 0) {
+                builder.addFloat(data[i])
+            }
+            return builder.endVector()
+        }
+        fun startFvecVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 4)
+        fun endMonsterExtra(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+            return o
+        }
+        fun finishMonsterExtraBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finish(offset, "MONE")
+        fun finishSizePrefixedMonsterExtraBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finishSizePrefixed(offset, "MONE")
+    }
+}
diff --git a/third_party/flatbuffers/tests/MyGame/MonsterExtra.py b/third_party/flatbuffers/tests/MyGame/MonsterExtra.py
new file mode 100644
index 0000000..1f7dcb2
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/MonsterExtra.py
@@ -0,0 +1,138 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: MyGame
+
+import flatbuffers
+
+class MonsterExtra(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAsMonsterExtra(cls, buf, offset):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = MonsterExtra()
+        x.Init(buf, n + offset)
+        return x
+
+    @classmethod
+    def MonsterExtraBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
+        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x45", size_prefixed=size_prefixed)
+
+    # MonsterExtra
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # MonsterExtra
+    def D0(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
+        return float('nan')
+
+    # MonsterExtra
+    def D1(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
+        return float('nan')
+
+    # MonsterExtra
+    def D2(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
+        return float('inf')
+
+    # MonsterExtra
+    def D3(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
+        return float('-inf')
+
+    # MonsterExtra
+    def F0(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
+        return float('nan')
+
+    # MonsterExtra
+    def F1(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
+        return float('nan')
+
+    # MonsterExtra
+    def F2(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
+        return float('inf')
+
+    # MonsterExtra
+    def F3(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
+        return float('-inf')
+
+    # MonsterExtra
+    def Dvec(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.Float64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
+        return 0
+
+    # MonsterExtra
+    def DvecAsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Float64Flags, o)
+        return 0
+
+    # MonsterExtra
+    def DvecLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # MonsterExtra
+    def Fvec(self, j):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
+        if o != 0:
+            a = self._tab.Vector(o)
+            return self._tab.Get(flatbuffers.number_types.Float32Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
+        return 0
+
+    # MonsterExtra
+    def FvecAsNumpy(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
+        if o != 0:
+            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Float32Flags, o)
+        return 0
+
+    # MonsterExtra
+    def FvecLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+def MonsterExtraStart(builder): builder.StartObject(10)
+def MonsterExtraAddD0(builder, d0): builder.PrependFloat64Slot(0, d0, float('nan'))
+def MonsterExtraAddD1(builder, d1): builder.PrependFloat64Slot(1, d1, float('nan'))
+def MonsterExtraAddD2(builder, d2): builder.PrependFloat64Slot(2, d2, float('inf'))
+def MonsterExtraAddD3(builder, d3): builder.PrependFloat64Slot(3, d3, float('-inf'))
+def MonsterExtraAddF0(builder, f0): builder.PrependFloat32Slot(4, f0, float('nan'))
+def MonsterExtraAddF1(builder, f1): builder.PrependFloat32Slot(5, f1, float('nan'))
+def MonsterExtraAddF2(builder, f2): builder.PrependFloat32Slot(6, f2, float('inf'))
+def MonsterExtraAddF3(builder, f3): builder.PrependFloat32Slot(7, f3, float('-inf'))
+def MonsterExtraAddDvec(builder, dvec): builder.PrependUOffsetTRelativeSlot(8, flatbuffers.number_types.UOffsetTFlags.py_type(dvec), 0)
+def MonsterExtraStartDvecVector(builder, numElems): return builder.StartVector(8, numElems, 8)
+def MonsterExtraAddFvec(builder, fvec): builder.PrependUOffsetTRelativeSlot(9, flatbuffers.number_types.UOffsetTFlags.py_type(fvec), 0)
+def MonsterExtraStartFvecVector(builder, numElems): return builder.StartVector(4, numElems, 4)
+def MonsterExtraEnd(builder): return builder.EndObject()
diff --git a/third_party/flatbuffers/tests/MyGame/__init__.py b/third_party/flatbuffers/tests/MyGame/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/flatbuffers/tests/MyGame/__init__.py
diff --git a/third_party/flatbuffers/tests/PythonTest.sh b/third_party/flatbuffers/tests/PythonTest.sh
new file mode 100755
index 0000000..e4dbe8d
--- /dev/null
+++ b/third_party/flatbuffers/tests/PythonTest.sh
@@ -0,0 +1,79 @@
+#!/bin/bash -eu
+#
+# 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.
+
+pushd "$(dirname $0)" >/dev/null
+test_dir="$(pwd)"
+gen_code_path=${test_dir}
+runtime_library_dir=${test_dir}/../python
+
+# Emit Python code for the example schema in the test dir:
+${test_dir}/../flatc -p -o ${gen_code_path} -I include_test monster_test.fbs
+
+# Syntax: run_tests <interpreter> <benchmark vtable dedupes>
+#                   <benchmark read count> <benchmark build count>
+interpreters_tested=()
+function run_tests() {
+  if $(which ${1} >/dev/null); then
+    echo "Testing with interpreter: ${1}"
+    PYTHONDONTWRITEBYTECODE=1 \
+    JYTHONDONTWRITEBYTECODE=1 \
+    PYTHONPATH=${runtime_library_dir}:${gen_code_path} \
+    JYTHONPATH=${runtime_library_dir}:${gen_code_path} \
+    COMPARE_GENERATED_TO_GO=0 \
+    COMPARE_GENERATED_TO_JAVA=0 \
+    $1 py_test.py $2 $3 $4
+    interpreters_tested+=(${1})
+    echo
+  fi
+}
+
+# Run test suite with these interpreters. The arguments are benchmark counts.
+run_tests python2.6 100 100 100
+run_tests python2.7 100 100 100
+run_tests python3 100 100 100
+run_tests pypy 100 100 100
+
+# NOTE: We'd like to support python2.5 in the future.
+
+# NOTE: Jython 2.7.0 fails due to a bug in the stdlib `struct` library:
+#       http://bugs.jython.org/issue2188
+
+if [ ${#interpreters_tested[@]} -eq 0 ]; then
+  echo "No Python interpeters found on this system, could not run tests."
+  exit 1
+fi
+
+# Run test suite with default python intereter.
+# (If the Python program `coverage` is available, it will be run, too.
+#  Install `coverage` with `pip install coverage`.)
+if $(which coverage >/dev/null); then
+  echo 'Found coverage utility, running coverage with default Python:'
+
+  PYTHONDONTWRITEBYTECODE=1 \
+  PYTHONPATH=${runtime_library_dir}:${gen_code_path} \
+  coverage run --source=flatbuffers,MyGame py_test.py 0 0 0 > /dev/null
+
+  echo
+  cov_result=`coverage report --omit="*flatbuffers/vendor*,*py_test*" \
+              | tail -n 1 | awk ' { print $4 } '`
+  echo "Code coverage: ${cov_result}"
+else
+  echo -n "Did not find coverage utility for default Python, skipping. "
+  echo "Install with 'pip install coverage'."
+fi
+
+echo
+echo "OK: all tests passed for ${#interpreters_tested[@]} interpreters: ${interpreters_tested[@]}."
diff --git a/third_party/flatbuffers/tests/RustTest.bat b/third_party/flatbuffers/tests/RustTest.bat
new file mode 100644
index 0000000..ba9cfd2
--- /dev/null
+++ b/third_party/flatbuffers/tests/RustTest.bat
@@ -0,0 +1,23 @@
+@echo off
+rem Copyright 2018 Google Inc. All rights reserved.
+rem
+rem Licensed under the Apache License, Version 2.0 (the "License");
+rem you may not use this file except in compliance with the License.
+rem You may obtain a copy of the License at
+rem
+rem     http://www.apache.org/licenses/LICENSE-2.0
+rem
+rem Unless required by applicable law or agreed to in writing, software
+rem distributed under the License is distributed on an "AS IS" BASIS,
+rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+rem See the License for the specific language governing permissions and
+rem limitations under the License.
+
+rem Compile then run the Rust test.
+
+rem TODO(rw): how do we make this script abort the calling script in appveyor?
+
+cd rust_usage_test
+cargo test -- --quiet || exit /b 1
+cargo run --bin=alloc_check || exit /b 1
+cd ..
diff --git a/third_party/flatbuffers/tests/RustTest.sh b/third_party/flatbuffers/tests/RustTest.sh
new file mode 100755
index 0000000..0a3974b
--- /dev/null
+++ b/third_party/flatbuffers/tests/RustTest.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+set -e
+#
+# 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.
+
+if [[ "$1" == "mips-unknown-linux-gnu" ]]; then
+    TARGET_FLAG="--target mips-unknown-linux-gnu"
+    export CARGO_TARGET_MIPS_UNKNOWN_LINUX_GNU_LINKER=mips-linux-gnu-gcc
+    export CARGO_TARGET_MIPS_UNKNOWN_LINUX_GNU_RUNNER="qemu-mips -L /usr/mips-linux-gnu"
+fi
+
+cd ./rust_usage_test
+cargo test $TARGET_FLAG -- --quiet
+TEST_RESULT=$?
+if [[ $TEST_RESULT  == 0 ]]; then
+    echo "OK: Rust tests passed."
+else
+    echo "KO: Rust tests failed."
+    exit 1
+fi
+
+cargo run $TARGET_FLAG --bin=alloc_check
+TEST_RESULT=$?
+if [[ $TEST_RESULT  == 0 ]]; then
+    echo "OK: Rust heap alloc test passed."
+else
+    echo "KO: Rust heap alloc test failed."
+    exit 1
+fi
+
+cargo bench $TARGET_FLAG
diff --git a/third_party/flatbuffers/tests/TestAll.sh b/third_party/flatbuffers/tests/TestAll.sh
new file mode 100644
index 0000000..0fc0acd
--- /dev/null
+++ b/third_party/flatbuffers/tests/TestAll.sh
@@ -0,0 +1,63 @@
+echo "************************ Java:"
+
+sh JavaTest.sh
+
+echo "************************ Kotlin:"
+
+sh KotlinTest.sh
+
+echo "************************ Go:"
+
+sh GoTest.sh
+
+echo "************************ Python:"
+
+sh PythonTest.sh
+
+echo "************************ JavaScript:"
+
+sh JavaScriptTest.sh
+# FIXME does not exist:
+# sh JavaScriptUnionVectorTest.sh
+
+echo "************************ TypeScript:"
+
+sh TypeScriptTest.sh
+
+echo "************************ C++:"
+
+cd ..
+./flattests
+cd tests
+
+echo "************************ C#:"
+
+cd FlatBuffers.Test
+sh NetTest.sh
+cd ..
+
+echo "************************ PHP:"
+
+php phpTest.php
+sh phpUnionVectorTest.sh
+
+echo "************************ Dart:"
+
+sh DartTest.sh
+
+echo "************************ Rust:"
+
+sh RustTest.sh
+
+echo "************************ Lobster:"
+
+# TODO: test if available.
+# lobster lobstertest.lobster
+
+echo "************************ C:"
+
+echo "(in a different repo)"
+
+echo "************************ Swift:"
+
+echo "(in a different repo)"
diff --git a/third_party/flatbuffers/tests/TypeScriptTest.sh b/third_party/flatbuffers/tests/TypeScriptTest.sh
new file mode 100755
index 0000000..fa650a4
--- /dev/null
+++ b/third_party/flatbuffers/tests/TypeScriptTest.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+#
+# 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.
+
+pushd "$(dirname $0)" >/dev/null
+
+npm install @types/flatbuffers
+
+../flatc --ts --no-fb-import --gen-mutable -o ts -I include_test monster_test.fbs
+../flatc -b -I include_test monster_test.fbs unicode_test.json
+tsc --strict --noUnusedParameters --noUnusedLocals --noImplicitReturns --strictNullChecks ts/monster_test_generated.ts
+node JavaScriptTest ./ts/monster_test_generated
+
+../flatc --ts --js --no-fb-import -o ts union_vector/union_vector.fbs
+
+# test JS version first, then transpile and rerun for TS
+node JavaScriptUnionVectorTest ./ts/union_vector_generated
+tsc --strict --noUnusedParameters --noUnusedLocals --noImplicitReturns --strictNullChecks ts/union_vector_generated.ts
+node JavaScriptUnionVectorTest ./ts/union_vector_generated
+
+npm uninstall @types/flatbuffers
diff --git a/third_party/flatbuffers/tests/arrays_test.bfbs b/third_party/flatbuffers/tests/arrays_test.bfbs
new file mode 100644
index 0000000..2a89968
--- /dev/null
+++ b/third_party/flatbuffers/tests/arrays_test.bfbs
Binary files differ
diff --git a/third_party/flatbuffers/tests/arrays_test.fbs b/third_party/flatbuffers/tests/arrays_test.fbs
new file mode 100644
index 0000000..40bce66
--- /dev/null
+++ b/third_party/flatbuffers/tests/arrays_test.fbs
@@ -0,0 +1,24 @@
+namespace MyGame.Example;
+
+enum TestEnum : byte { A, B, C }
+
+struct NestedStruct{
+  a:[int:2];
+  b:TestEnum;
+  c:[TestEnum:2];
+}
+
+struct ArrayStruct{
+  a:float;
+  b:[int:0xF];
+  c:byte;
+  d:[NestedStruct:2];
+}
+
+table ArrayTable{
+  a:ArrayStruct;
+}
+
+root_type ArrayTable;
+file_identifier "ARRT";
+file_extension "mon";
diff --git a/third_party/flatbuffers/tests/arrays_test.golden b/third_party/flatbuffers/tests/arrays_test.golden
new file mode 100644
index 0000000..c032688
--- /dev/null
+++ b/third_party/flatbuffers/tests/arrays_test.golden
@@ -0,0 +1,19 @@
+{
+  a : {
+    a: 12.34,
+    b: [1,2,3,4,5,6,7,8,9,0xA,0xB,0xC,0xD,0xE,0xF],
+    c: -127,
+    d: [
+      {
+        a : [-1,2],
+        b : A,
+        c : [C, B]
+      },
+      {
+        a : [3,-4],
+        b : B,
+        c : [B, A]
+      }
+    ]
+  }
+}
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/arrays_test.schema.json b/third_party/flatbuffers/tests/arrays_test.schema.json
new file mode 100644
index 0000000..6803a1a
--- /dev/null
+++ b/third_party/flatbuffers/tests/arrays_test.schema.json
@@ -0,0 +1,60 @@
+{
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "definitions": {
+    "MyGame_Example_TestEnum" : {
+      "type" : "string",
+      "enum": ["A", "B", "C"]
+    },
+    "MyGame_Example_NestedStruct" : {
+      "type" : "object",
+      "properties" : {
+        "a" : {
+                "type" : "array", "items" : { "type" : "number" },
+                "minItems": 2,
+                "maxItems": 2
+              },
+        "b" : {
+                "$ref" : "#/definitions/MyGame_Example_TestEnum"
+              },
+        "c" : {
+                "$ref" : "#/definitions/MyGame_Example_TestEnum",
+                "minItems": 2,
+                "maxItems": 2
+              }
+      },
+      "additionalProperties" : false
+    },
+    "MyGame_Example_ArrayStruct" : {
+      "type" : "object",
+      "properties" : {
+        "a" : {
+                "type" : "number"
+              },
+        "b" : {
+                "type" : "array", "items" : { "type" : "number" },
+                "minItems": 15,
+                "maxItems": 15
+              },
+        "c" : {
+                "type" : "number"
+              },
+        "d" : {
+                "type" : "array", "items" : { "$ref" : "#/definitions/MyGame_Example_NestedStruct" },
+                "minItems": 2,
+                "maxItems": 2
+              }
+      },
+      "additionalProperties" : false
+    },
+    "MyGame_Example_ArrayTable" : {
+      "type" : "object",
+      "properties" : {
+        "a" : {
+                "$ref" : "#/definitions/MyGame_Example_ArrayStruct"
+              }
+      },
+      "additionalProperties" : false
+    }
+  },
+  "$ref" : "#/definitions/MyGame_Example_ArrayTable"
+}
diff --git a/third_party/flatbuffers/tests/arrays_test_generated.h b/third_party/flatbuffers/tests/arrays_test_generated.h
new file mode 100644
index 0000000..9875785
--- /dev/null
+++ b/third_party/flatbuffers/tests/arrays_test_generated.h
@@ -0,0 +1,419 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_ARRAYSTEST_MYGAME_EXAMPLE_H_
+#define FLATBUFFERS_GENERATED_ARRAYSTEST_MYGAME_EXAMPLE_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+namespace MyGame {
+namespace Example {
+
+struct NestedStruct;
+
+struct ArrayStruct;
+
+struct ArrayTable;
+struct ArrayTableT;
+
+bool operator==(const NestedStruct &lhs, const NestedStruct &rhs);
+bool operator!=(const NestedStruct &lhs, const NestedStruct &rhs);
+bool operator==(const ArrayStruct &lhs, const ArrayStruct &rhs);
+bool operator!=(const ArrayStruct &lhs, const ArrayStruct &rhs);
+bool operator==(const ArrayTableT &lhs, const ArrayTableT &rhs);
+bool operator!=(const ArrayTableT &lhs, const ArrayTableT &rhs);
+
+inline const flatbuffers::TypeTable *NestedStructTypeTable();
+
+inline const flatbuffers::TypeTable *ArrayStructTypeTable();
+
+inline const flatbuffers::TypeTable *ArrayTableTypeTable();
+
+enum class TestEnum : int8_t {
+  A = 0,
+  B = 1,
+  C = 2,
+  MIN = A,
+  MAX = C
+};
+
+inline const TestEnum (&EnumValuesTestEnum())[3] {
+  static const TestEnum values[] = {
+    TestEnum::A,
+    TestEnum::B,
+    TestEnum::C
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesTestEnum() {
+  static const char * const names[4] = {
+    "A",
+    "B",
+    "C",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameTestEnum(TestEnum e) {
+  if (e < TestEnum::A || e > TestEnum::C) return "";
+  const size_t index = static_cast<size_t>(e);
+  return EnumNamesTestEnum()[index];
+}
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) NestedStruct FLATBUFFERS_FINAL_CLASS {
+ private:
+  int32_t a_[2];
+  int8_t b_;
+  int8_t c_[2];
+  int8_t padding0__;
+
+ public:
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return NestedStructTypeTable();
+  }
+  NestedStruct() {
+    memset(static_cast<void *>(this), 0, sizeof(NestedStruct));
+  }
+  NestedStruct(MyGame::Example::TestEnum _b)
+      : b_(flatbuffers::EndianScalar(static_cast<int8_t>(_b))) {
+    std::memset(a_, 0, sizeof(a_));
+    std::memset(c_, 0, sizeof(c_));
+    (void)padding0__;
+  }
+  const flatbuffers::Array<int32_t, 2> *a() const {
+    return reinterpret_cast<const flatbuffers::Array<int32_t, 2> *>(a_);
+  }
+  flatbuffers::Array<int32_t, 2> *mutable_a() {
+    return reinterpret_cast<flatbuffers::Array<int32_t, 2> *>(a_);
+  }
+  MyGame::Example::TestEnum b() const {
+    return static_cast<MyGame::Example::TestEnum>(flatbuffers::EndianScalar(b_));
+  }
+  void mutate_b(MyGame::Example::TestEnum _b) {
+    flatbuffers::WriteScalar(&b_, static_cast<int8_t>(_b));
+  }
+  const flatbuffers::Array<MyGame::Example::TestEnum, 2> *c() const {
+    return reinterpret_cast<const flatbuffers::Array<MyGame::Example::TestEnum, 2> *>(c_);
+  }
+  flatbuffers::Array<MyGame::Example::TestEnum, 2> *mutable_c() {
+    return reinterpret_cast<flatbuffers::Array<MyGame::Example::TestEnum, 2> *>(c_);
+  }
+};
+FLATBUFFERS_STRUCT_END(NestedStruct, 12);
+
+inline bool operator==(const NestedStruct &lhs, const NestedStruct &rhs) {
+  return
+      (lhs.a() == rhs.a()) &&
+      (lhs.b() == rhs.b()) &&
+      (lhs.c() == rhs.c());
+}
+
+inline bool operator!=(const NestedStruct &lhs, const NestedStruct &rhs) {
+    return !(lhs == rhs);
+}
+
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) ArrayStruct FLATBUFFERS_FINAL_CLASS {
+ private:
+  float a_;
+  int32_t b_[15];
+  int8_t c_;
+  int8_t padding0__;  int16_t padding1__;
+  MyGame::Example::NestedStruct d_[2];
+
+ public:
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return ArrayStructTypeTable();
+  }
+  ArrayStruct() {
+    memset(static_cast<void *>(this), 0, sizeof(ArrayStruct));
+  }
+  ArrayStruct(float _a, int8_t _c)
+      : a_(flatbuffers::EndianScalar(_a)),
+        c_(flatbuffers::EndianScalar(_c)),
+        padding0__(0),
+        padding1__(0) {
+    std::memset(b_, 0, sizeof(b_));
+    (void)padding0__;    (void)padding1__;
+    std::memset(d_, 0, sizeof(d_));
+  }
+  float a() const {
+    return flatbuffers::EndianScalar(a_);
+  }
+  void mutate_a(float _a) {
+    flatbuffers::WriteScalar(&a_, _a);
+  }
+  const flatbuffers::Array<int32_t, 15> *b() const {
+    return reinterpret_cast<const flatbuffers::Array<int32_t, 15> *>(b_);
+  }
+  flatbuffers::Array<int32_t, 15> *mutable_b() {
+    return reinterpret_cast<flatbuffers::Array<int32_t, 15> *>(b_);
+  }
+  int8_t c() const {
+    return flatbuffers::EndianScalar(c_);
+  }
+  void mutate_c(int8_t _c) {
+    flatbuffers::WriteScalar(&c_, _c);
+  }
+  const flatbuffers::Array<MyGame::Example::NestedStruct, 2> *d() const {
+    return reinterpret_cast<const flatbuffers::Array<MyGame::Example::NestedStruct, 2> *>(d_);
+  }
+  flatbuffers::Array<MyGame::Example::NestedStruct, 2> *mutable_d() {
+    return reinterpret_cast<flatbuffers::Array<MyGame::Example::NestedStruct, 2> *>(d_);
+  }
+};
+FLATBUFFERS_STRUCT_END(ArrayStruct, 92);
+
+inline bool operator==(const ArrayStruct &lhs, const ArrayStruct &rhs) {
+  return
+      (lhs.a() == rhs.a()) &&
+      (lhs.b() == rhs.b()) &&
+      (lhs.c() == rhs.c()) &&
+      (lhs.d() == rhs.d());
+}
+
+inline bool operator!=(const ArrayStruct &lhs, const ArrayStruct &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct ArrayTableT : public flatbuffers::NativeTable {
+  typedef ArrayTable TableType;
+  flatbuffers::unique_ptr<MyGame::Example::ArrayStruct> a;
+  ArrayTableT() {
+  }
+};
+
+inline bool operator==(const ArrayTableT &lhs, const ArrayTableT &rhs) {
+  return
+      (lhs.a == rhs.a);
+}
+
+inline bool operator!=(const ArrayTableT &lhs, const ArrayTableT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct ArrayTable FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef ArrayTableT NativeTableType;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return ArrayTableTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_A = 4
+  };
+  const MyGame::Example::ArrayStruct *a() const {
+    return GetStruct<const MyGame::Example::ArrayStruct *>(VT_A);
+  }
+  MyGame::Example::ArrayStruct *mutable_a() {
+    return GetStruct<MyGame::Example::ArrayStruct *>(VT_A);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<MyGame::Example::ArrayStruct>(verifier, VT_A) &&
+           verifier.EndTable();
+  }
+  ArrayTableT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(ArrayTableT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<ArrayTable> Pack(flatbuffers::FlatBufferBuilder &_fbb, const ArrayTableT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct ArrayTableBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_a(const MyGame::Example::ArrayStruct *a) {
+    fbb_.AddStruct(ArrayTable::VT_A, a);
+  }
+  explicit ArrayTableBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  ArrayTableBuilder &operator=(const ArrayTableBuilder &);
+  flatbuffers::Offset<ArrayTable> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<ArrayTable>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<ArrayTable> CreateArrayTable(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const MyGame::Example::ArrayStruct *a = 0) {
+  ArrayTableBuilder builder_(_fbb);
+  builder_.add_a(a);
+  return builder_.Finish();
+}
+
+flatbuffers::Offset<ArrayTable> CreateArrayTable(flatbuffers::FlatBufferBuilder &_fbb, const ArrayTableT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+inline ArrayTableT *ArrayTable::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = new ArrayTableT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+inline void ArrayTable::UnPackTo(ArrayTableT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = a(); if (_e) _o->a = flatbuffers::unique_ptr<MyGame::Example::ArrayStruct>(new MyGame::Example::ArrayStruct(*_e)); };
+}
+
+inline flatbuffers::Offset<ArrayTable> ArrayTable::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ArrayTableT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateArrayTable(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<ArrayTable> CreateArrayTable(flatbuffers::FlatBufferBuilder &_fbb, const ArrayTableT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ArrayTableT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _a = _o->a ? _o->a.get() : 0;
+  return MyGame::Example::CreateArrayTable(
+      _fbb,
+      _a);
+}
+
+inline const flatbuffers::TypeTable *TestEnumTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_CHAR, 0, 0 },
+    { flatbuffers::ET_CHAR, 0, 0 },
+    { flatbuffers::ET_CHAR, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::TestEnumTypeTable
+  };
+  static const char * const names[] = {
+    "A",
+    "B",
+    "C"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_ENUM, 3, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *NestedStructTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 0, -1 },
+    { flatbuffers::ET_CHAR, 0, 0 },
+    { flatbuffers::ET_SEQUENCE, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::TestEnumTypeTable
+  };
+  static const int64_t values[] = { 0, 8, 9, 12 };
+  static const char * const names[] = {
+    "a",
+    "b",
+    "c"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_STRUCT, 3, type_codes, type_refs, values, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *ArrayStructTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_SEQUENCE, 0, -1 },
+    { flatbuffers::ET_CHAR, 0, -1 },
+    { flatbuffers::ET_SEQUENCE, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::NestedStructTypeTable
+  };
+  static const int64_t values[] = { 0, 4, 64, 68, 92 };
+  static const char * const names[] = {
+    "a",
+    "b",
+    "c",
+    "d"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_STRUCT, 4, type_codes, type_refs, values, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *ArrayTableTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::ArrayStructTypeTable
+  };
+  static const char * const names[] = {
+    "a"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 1, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+inline const MyGame::Example::ArrayTable *GetArrayTable(const void *buf) {
+  return flatbuffers::GetRoot<MyGame::Example::ArrayTable>(buf);
+}
+
+inline const MyGame::Example::ArrayTable *GetSizePrefixedArrayTable(const void *buf) {
+  return flatbuffers::GetSizePrefixedRoot<MyGame::Example::ArrayTable>(buf);
+}
+
+inline ArrayTable *GetMutableArrayTable(void *buf) {
+  return flatbuffers::GetMutableRoot<ArrayTable>(buf);
+}
+
+inline const char *ArrayTableIdentifier() {
+  return "ARRT";
+}
+
+inline bool ArrayTableBufferHasIdentifier(const void *buf) {
+  return flatbuffers::BufferHasIdentifier(
+      buf, ArrayTableIdentifier());
+}
+
+inline bool VerifyArrayTableBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifyBuffer<MyGame::Example::ArrayTable>(ArrayTableIdentifier());
+}
+
+inline bool VerifySizePrefixedArrayTableBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifySizePrefixedBuffer<MyGame::Example::ArrayTable>(ArrayTableIdentifier());
+}
+
+inline const char *ArrayTableExtension() {
+  return "mon";
+}
+
+inline void FinishArrayTableBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<MyGame::Example::ArrayTable> root) {
+  fbb.Finish(root, ArrayTableIdentifier());
+}
+
+inline void FinishSizePrefixedArrayTableBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<MyGame::Example::ArrayTable> root) {
+  fbb.FinishSizePrefixed(root, ArrayTableIdentifier());
+}
+
+inline flatbuffers::unique_ptr<MyGame::Example::ArrayTableT> UnPackArrayTable(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return flatbuffers::unique_ptr<MyGame::Example::ArrayTableT>(GetArrayTable(buf)->UnPack(res));
+}
+
+inline flatbuffers::unique_ptr<MyGame::Example::ArrayTableT> UnPackSizePrefixedArrayTable(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return flatbuffers::unique_ptr<MyGame::Example::ArrayTableT>(GetSizePrefixedArrayTable(buf)->UnPack(res));
+}
+
+}  // namespace Example
+}  // namespace MyGame
+
+#endif  // FLATBUFFERS_GENERATED_ARRAYSTEST_MYGAME_EXAMPLE_H_
diff --git a/third_party/flatbuffers/tests/docker/Dockerfile.testing.build_flatc_debian_stretch b/third_party/flatbuffers/tests/docker/Dockerfile.testing.build_flatc_debian_stretch
new file mode 100644
index 0000000..197a555
--- /dev/null
+++ b/third_party/flatbuffers/tests/docker/Dockerfile.testing.build_flatc_debian_stretch
@@ -0,0 +1,9 @@
+FROM debian:9.6-slim as base
+RUN apt -qq update >/dev/null
+RUN apt -qq install -y cmake make build-essential >/dev/null
+FROM base
+WORKDIR /code
+ADD . .
+RUN cmake -G "Unix Makefiles"
+RUN make flatc
+RUN ls flatc
diff --git a/third_party/flatbuffers/tests/docker/TODO.Dockerfile.testing.php.hhvm_2019_01_16 b/third_party/flatbuffers/tests/docker/TODO.Dockerfile.testing.php.hhvm_2019_01_16
new file mode 100644
index 0000000..e5023fa
--- /dev/null
+++ b/third_party/flatbuffers/tests/docker/TODO.Dockerfile.testing.php.hhvm_2019_01_16
@@ -0,0 +1,18 @@
+# This does not pass tests due to the following error:
+#
+# Fatal error: Uncaught exception 'InvalidArgumentException' with message 'Google\FlatBuffers\ByteBuffer::getX() expects parameter 1 by reference, but the call was not annotated with '&'. in /code/php/FlatbufferBuilder.php:971
+# Stack trace:
+# #0 /code/tests/phpTest.php(277): Google\FlatBuffers\FlatbufferBuilder->sizedByteArray()
+# #1 /code/tests/phpTest.php(79): fuzzTest1()
+# #2 /code/tests/phpTest.php(86): main()
+# #3 {main}
+#   thrown in in /code/php/FlatbufferBuilder.php:971
+FROM hhvm/hhvm:2019.01.16 as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN hhvm --version
+RUN hhvm phpTest.php
+RUN ../flatc --php -o php union_vector/union_vector.fbs
+RUN hhvm phpUnionVectorTest.php
diff --git a/third_party/flatbuffers/tests/docker/TODO.Dockerfile.testing.python.cpython_with_conda b/third_party/flatbuffers/tests/docker/TODO.Dockerfile.testing.python.cpython_with_conda
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/flatbuffers/tests/docker/TODO.Dockerfile.testing.python.cpython_with_conda
diff --git a/third_party/flatbuffers/tests/docker/TODO.Dockerfile.testing.python.cpython_with_numpy b/third_party/flatbuffers/tests/docker/TODO.Dockerfile.testing.python.cpython_with_numpy
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/flatbuffers/tests/docker/TODO.Dockerfile.testing.python.cpython_with_numpy
diff --git a/third_party/flatbuffers/tests/docker/TODO.Dockerfile.testing.python.pypy_6_0_0_py2 b/third_party/flatbuffers/tests/docker/TODO.Dockerfile.testing.python.pypy_6_0_0_py2
new file mode 100644
index 0000000..849b92e
--- /dev/null
+++ b/third_party/flatbuffers/tests/docker/TODO.Dockerfile.testing.python.pypy_6_0_0_py2
@@ -0,0 +1,7 @@
+FROM pypy:2-6.0.0-slim as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN pypy --version
+RUN ./PythonTest.sh
diff --git a/third_party/flatbuffers/tests/docker/TODO.Dockerfile.testing.python.pypy_6_0_0_py3 b/third_party/flatbuffers/tests/docker/TODO.Dockerfile.testing.python.pypy_6_0_0_py3
new file mode 100644
index 0000000..2df6b2a
--- /dev/null
+++ b/third_party/flatbuffers/tests/docker/TODO.Dockerfile.testing.python.pypy_6_0_0_py3
@@ -0,0 +1,7 @@
+FROM pypy:3-6.0.0-slim as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN pypy --version
+RUN ./PythonTest.sh
diff --git a/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.csharp.mono_5_18 b/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.csharp.mono_5_18
new file mode 100644
index 0000000..e6ba550
--- /dev/null
+++ b/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.csharp.mono_5_18
@@ -0,0 +1,8 @@
+FROM mono:5.18 as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN mono --version
+WORKDIR /code/tests/FlatBuffers.Test
+RUN sh NetTest.sh
diff --git a/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.golang.1_11 b/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.golang.1_11
new file mode 100644
index 0000000..81707ea
--- /dev/null
+++ b/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.golang.1_11
@@ -0,0 +1,7 @@
+FROM golang:1.11-stretch as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN go version
+RUN ./GoTest.sh
diff --git a/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.java.openjdk_10_0_2 b/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.java.openjdk_10_0_2
new file mode 100644
index 0000000..82c3add
--- /dev/null
+++ b/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.java.openjdk_10_0_2
@@ -0,0 +1,7 @@
+FROM openjdk:10.0.2-jdk-slim-sid as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN java -version
+RUN ./JavaTest.sh
diff --git a/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.java.openjdk_11_0_1 b/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.java.openjdk_11_0_1
new file mode 100644
index 0000000..ac1c3cc
--- /dev/null
+++ b/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.java.openjdk_11_0_1
@@ -0,0 +1,7 @@
+FROM openjdk:11.0.1-jdk-slim-sid as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN java -version
+RUN ./JavaTest.sh
diff --git a/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.node.10_13_0 b/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.node.10_13_0
new file mode 100644
index 0000000..b821105
--- /dev/null
+++ b/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.node.10_13_0
@@ -0,0 +1,8 @@
+FROM node:10.13.0-stretch as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN node --version
+RUN ../flatc -b -I include_test monster_test.fbs unicode_test.json
+RUN node JavaScriptTest ./monster_test_generated
diff --git a/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.node.11_2_0 b/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.node.11_2_0
new file mode 100644
index 0000000..f6b48e6
--- /dev/null
+++ b/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.node.11_2_0
@@ -0,0 +1,8 @@
+FROM node:11.2.0-stretch as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN node --version
+RUN ../flatc -b -I include_test monster_test.fbs unicode_test.json
+RUN node JavaScriptTest ./monster_test_generated
diff --git a/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.php.zend_7_3 b/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.php.zend_7_3
new file mode 100644
index 0000000..6cdf43c
--- /dev/null
+++ b/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.php.zend_7_3
@@ -0,0 +1,8 @@
+FROM php:7.3-cli-stretch as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN php --version
+RUN php phpTest.php
+RUN sh phpUnionVectorTest.sh
diff --git a/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.python.cpython_2_7_15 b/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.python.cpython_2_7_15
new file mode 100644
index 0000000..e68303e
--- /dev/null
+++ b/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.python.cpython_2_7_15
@@ -0,0 +1,8 @@
+FROM python:2.7.15-slim-stretch as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN python --version
+RUN pip install coverage
+RUN ./PythonTest.sh
diff --git a/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.python.cpython_3_7_1 b/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.python.cpython_3_7_1
new file mode 100644
index 0000000..7c2f15c
--- /dev/null
+++ b/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.python.cpython_3_7_1
@@ -0,0 +1,8 @@
+FROM python:3.7.1-slim-stretch as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN python --version
+RUN pip install coverage
+RUN ./PythonTest.sh
diff --git a/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.rust.1_30_1 b/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.rust.1_30_1
new file mode 100644
index 0000000..4d1755c
--- /dev/null
+++ b/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.rust.1_30_1
@@ -0,0 +1,7 @@
+FROM rust:1.30.1-slim-stretch as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN rustc --version
+RUN ./RustTest.sh
diff --git a/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.rust.big_endian.1_30_1 b/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.rust.big_endian.1_30_1
new file mode 100644
index 0000000..f2e93f4
--- /dev/null
+++ b/third_party/flatbuffers/tests/docker/languages/Dockerfile.testing.rust.big_endian.1_30_1
@@ -0,0 +1,15 @@
+FROM rust:1.30.1-slim-stretch as base
+RUN apt -qq update -y && apt -qq install -y \
+    gcc-mips-linux-gnu \
+    libexpat1 \
+    libmagic1 \
+    libmpdec2 \
+    libreadline7 \
+    qemu-user
+RUN rustup target add mips-unknown-linux-gnu
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN rustc --version
+RUN ./RustTest.sh mips-unknown-linux-gnu
diff --git a/third_party/flatbuffers/tests/fuzzer/CMakeLists.txt b/third_party/flatbuffers/tests/fuzzer/CMakeLists.txt
new file mode 100644
index 0000000..7df5df2
--- /dev/null
+++ b/third_party/flatbuffers/tests/fuzzer/CMakeLists.txt
@@ -0,0 +1,91 @@
+cmake_minimum_required(VERSION 3.9)
+
+set(CMAKE_VERBOSE_MAKEFILE ON)
+
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+
+project(FlatBuffersFuzzerTests)
+
+set(CMAKE_CXX_FLAGS
+  "${CMAKE_CXX_FLAGS} -std=c++14 -Wall -pedantic -Werror -Wextra -Wno-unused-parameter -fsigned-char")
+
+set(CMAKE_CXX_FLAGS
+  "${CMAKE_CXX_FLAGS} -g -fsigned-char -fno-omit-frame-pointer")
+
+# Typical slowdown introduced by MemorySanitizer (memory) is 3x.
+# '-fsanitize=address' not allowed with '-fsanitize=memory'
+if(YES)
+  set(CMAKE_CXX_FLAGS
+    "${CMAKE_CXX_FLAGS} -fsanitize=fuzzer,address,undefined")
+else()
+  set(CMAKE_CXX_FLAGS
+    "${CMAKE_CXX_FLAGS} -fsanitize=fuzzer,memory,undefined -fsanitize-memory-track-origins=2")
+endif()
+
+set(CMAKE_CXX_FLAGS
+  "${CMAKE_CXX_FLAGS} -fsanitize-coverage=edge,trace-cmp")
+
+# enable link-time optimisation
+# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto")
+
+# https://llvm.org/docs/Passes.html
+# save IR to see call graph
+# make one bitcode file:> llvm-link *.bc -o out.bc
+# print call-graph:> opt out.bc -analyze -print-callgraph &> callgraph.txt
+# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -save-temps -flto")
+
+set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=lld")
+
+set(FLATBUFFERS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../")
+
+set(FlatBuffers_Library_SRCS
+  ${FLATBUFFERS_DIR}/include/flatbuffers/code_generators.h
+  ${FLATBUFFERS_DIR}/include/flatbuffers/base.h
+  ${FLATBUFFERS_DIR}/include/flatbuffers/flatbuffers.h
+  ${FLATBUFFERS_DIR}/include/flatbuffers/hash.h
+  ${FLATBUFFERS_DIR}/include/flatbuffers/idl.h
+  ${FLATBUFFERS_DIR}/include/flatbuffers/util.h
+  ${FLATBUFFERS_DIR}/include/flatbuffers/reflection.h
+  ${FLATBUFFERS_DIR}/include/flatbuffers/reflection_generated.h
+  ${FLATBUFFERS_DIR}/include/flatbuffers/stl_emulation.h
+  ${FLATBUFFERS_DIR}/include/flatbuffers/flexbuffers.h
+  ${FLATBUFFERS_DIR}/include/flatbuffers/registry.h
+  ${FLATBUFFERS_DIR}/include/flatbuffers/minireflect.h
+  ${FLATBUFFERS_DIR}/src/code_generators.cpp
+  ${FLATBUFFERS_DIR}/src/idl_parser.cpp
+  ${FLATBUFFERS_DIR}/src/idl_gen_text.cpp
+  ${FLATBUFFERS_DIR}/src/reflection.cpp
+  ${FLATBUFFERS_DIR}/src/util.cpp
+  ${FLATBUFFERS_DIR}/tests/test_assert.cpp
+)
+
+include_directories(${FLATBUFFERS_DIR}/include)
+include_directories(${FLATBUFFERS_DIR}/tests)
+add_library(flatbuffers STATIC ${FlatBuffers_Library_SRCS})
+
+# FLATBUFFERS_ASSERT should assert in Release as well.
+# Redefine FLATBUFFERS_ASSERT macro definition.
+# Declare as PUBLIC to cover asserts in all included header files.
+target_compile_definitions(flatbuffers PUBLIC
+   FLATBUFFERS_ASSERT=fuzzer_assert_impl)
+target_compile_definitions(flatbuffers PUBLIC
+   FLATBUFFERS_ASSERT_INCLUDE="${CMAKE_CURRENT_SOURCE_DIR}/fuzzer_assert.h")
+
+if(NOT DEFINED FLATBUFFERS_MAX_PARSING_DEPTH)
+  # Force checking of RecursionError in the test
+  set(FLATBUFFERS_MAX_PARSING_DEPTH 8)
+endif()
+message(STATUS "FLATBUFFERS_MAX_PARSING_DEPTH: ${FLATBUFFERS_MAX_PARSING_DEPTH}")
+target_compile_definitions(flatbuffers PRIVATE FLATBUFFERS_MAX_PARSING_DEPTH=8)
+
+# Setup fuzzer tests.
+
+add_executable(scalar_fuzzer flatbuffers_scalar_fuzzer.cc)
+target_link_libraries(scalar_fuzzer PRIVATE flatbuffers)
+
+add_executable(parser_fuzzer flatbuffers_parser_fuzzer.cc)
+target_link_libraries(parser_fuzzer PRIVATE flatbuffers)
+
+add_executable(verifier_fuzzer flatbuffers_verifier_fuzzer.cc)
+target_link_libraries(verifier_fuzzer PRIVATE flatbuffers)
diff --git a/third_party/flatbuffers/tests/fuzzer/flatbuffers_parser_fuzzer.cc b/third_party/flatbuffers/tests/fuzzer/flatbuffers_parser_fuzzer.cc
new file mode 100644
index 0000000..87dd2d2
--- /dev/null
+++ b/third_party/flatbuffers/tests/fuzzer/flatbuffers_parser_fuzzer.cc
@@ -0,0 +1,67 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+#include <clocale>
+#include <string>
+
+#include "flatbuffers/idl.h"
+#include "test_init.h"
+
+static constexpr uint8_t flags_strict_json = 0x01;
+static constexpr uint8_t flags_skip_unexpected_fields_in_json = 0x02;
+static constexpr uint8_t flags_allow_non_utf8 = 0x04;
+// static constexpr uint8_t flags_flag_3 = 0x08;
+// static constexpr uint8_t flags_flag_4 = 0x10;
+// static constexpr uint8_t flags_flag_5 = 0x20;
+// static constexpr uint8_t flags_flag_6 = 0x40;
+// static constexpr uint8_t flags_flag_7 = 0x80;
+
+// Utility for test run.
+OneTimeTestInit OneTimeTestInit::one_time_init_;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  // Reserve one byte for Parser flags and one byte for repetition counter.
+  if (size < 3) return 0;
+  const uint8_t flags = data[0];
+  // normalize to ascii alphabet
+  const int extra_rep_number = data[1] >= '0' ? (data[1] - '0') : 0;
+  data += 2;
+  size -= 2;  // bypass
+
+  const std::string original(reinterpret_cast<const char *>(data), size);
+  auto input = std::string(original.c_str());  // until '\0'
+  if (input.empty()) return 0;
+
+  flatbuffers::IDLOptions opts;
+  opts.strict_json = (flags & flags_strict_json);
+  opts.skip_unexpected_fields_in_json =
+      (flags & flags_skip_unexpected_fields_in_json);
+  opts.allow_non_utf8 = (flags & flags_allow_non_utf8);
+
+  flatbuffers::Parser parser(opts);
+
+  // Guarantee 0-termination in the input.
+  auto parse_input = input.c_str();
+
+  // The fuzzer can adjust the number repetition if a side-effects have found.
+  // Each test should pass at least two times to ensure that the parser doesn't
+  // have any hidden-states or locale-depended effects.
+  for (auto cnt = 0; cnt < (extra_rep_number + 2); cnt++) {
+    // Each even run (0,2,4..) will test locale independed code.
+    auto use_locale = !!OneTimeTestInit::test_locale() && (0 == (cnt % 2));
+    // Set new locale.
+    if (use_locale) {
+      FLATBUFFERS_ASSERT(setlocale(LC_ALL, OneTimeTestInit::test_locale()));
+    }
+
+    // Check Parser.
+    parser.Parse(parse_input);
+
+    // Restore locale.
+    if (use_locale) { FLATBUFFERS_ASSERT(setlocale(LC_ALL, "C")); }
+  }
+
+  return 0;
+}
diff --git a/third_party/flatbuffers/tests/fuzzer/flatbuffers_scalar_fuzzer.cc b/third_party/flatbuffers/tests/fuzzer/flatbuffers_scalar_fuzzer.cc
new file mode 100644
index 0000000..074a488
--- /dev/null
+++ b/third_party/flatbuffers/tests/fuzzer/flatbuffers_scalar_fuzzer.cc
@@ -0,0 +1,351 @@
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <algorithm>
+#include <clocale>
+#include <memory>
+#include <regex>
+#include <string>
+
+#include "flatbuffers/idl.h"
+#include "test_init.h"
+
+static constexpr uint8_t flags_scalar_type = 0x0F;  // type of scalar value
+static constexpr uint8_t flags_quotes_kind = 0x10;  // quote " or '
+// reserved for future: json {named} or [unnamed]
+// static constexpr uint8_t flags_json_bracer = 0x20;
+
+// Find all 'subj' sub-strings and replace first character of sub-string.
+// BreakSequence("testest","tes", 'X') -> "XesXest".
+// BreakSequence("xxx","xx", 'Y') -> "YYx".
+static void BreakSequence(std::string &s, const char *subj, char repl) {
+  size_t pos = 0;
+  while (pos = s.find(subj, pos), pos != std::string::npos) {
+    s.at(pos) = repl;
+    pos++;
+  }
+}
+
+// Remove all leading and trailing symbols matched with pattern set.
+// StripString("xy{xy}y", "xy") -> "{xy}"
+static std::string StripString(const std::string &s, const char *pattern,
+                               size_t *pos = nullptr) {
+  if (pos) *pos = 0;
+  // leading
+  auto first = s.find_first_not_of(pattern);
+  if (std::string::npos == first) return "";
+  if (pos) *pos = first;
+  // trailing
+  auto last = s.find_last_not_of(pattern);
+  assert(last < s.length());
+  assert(first <= last);
+  return s.substr(first, last - first + 1);
+}
+
+class RegexMatcher {
+ protected:
+  virtual bool MatchNumber(const std::string &input) const = 0;
+
+ public:
+  virtual ~RegexMatcher() = default;
+
+  struct MatchResult {
+    size_t pos{ 0 };
+    size_t len{ 0 };
+    bool res{ false };
+    bool quoted{ false };
+  };
+
+  MatchResult Match(const std::string &input) const {
+    MatchResult r;
+    // strip leading and trailing "spaces" accepted by flatbuffer
+    auto test = StripString(input, "\t\r\n ", &r.pos);
+    r.len = test.size();
+    // check quotes
+    if (test.size() >= 2) {
+      auto fch = test.front();
+      auto lch = test.back();
+      r.quoted = (fch == lch) && (fch == '\'' || fch == '\"');
+      if (r.quoted) {
+        // remove quotes for regex test
+        test = test.substr(1, test.size() - 2);
+      }
+    }
+    // Fast check:
+    if (test.empty()) return r;
+    // A string with a valid scalar shouldn't have non-ascii or non-printable
+    // symbols.
+    for (auto c : test) {
+      if ((c < ' ') || (c > '~')) return r;
+    }
+    // Check with regex
+    r.res = MatchNumber(test);
+    return r;
+  }
+
+  bool MatchRegexList(const std::string &input,
+                      const std::vector<std::regex> &re_list) const {
+    auto str = StripString(input, " ");
+    if (str.empty()) return false;
+    for (auto &re : re_list) {
+      std::smatch match;
+      if (std::regex_match(str, match, re)) return true;
+    }
+    return false;
+  }
+};
+
+class IntegerRegex : public RegexMatcher {
+ protected:
+  bool MatchNumber(const std::string &input) const override {
+    static const std::vector<std::regex> re_list = {
+      std::regex{ R"(^[-+]?[0-9]+$)", std::regex_constants::optimize },
+
+      std::regex{
+          R"(^[-+]?0[xX][0-9a-fA-F]+$)", std::regex_constants::optimize }
+    };
+    return MatchRegexList(input, re_list);
+  }
+
+ public:
+  IntegerRegex() = default;
+  virtual ~IntegerRegex() = default;
+};
+
+class UIntegerRegex : public RegexMatcher {
+ protected:
+  bool MatchNumber(const std::string &input) const override {
+    static const std::vector<std::regex> re_list = {
+      std::regex{ R"(^[+]?[0-9]+$)", std::regex_constants::optimize },
+      std::regex{
+          R"(^[+]?0[xX][0-9a-fA-F]+$)", std::regex_constants::optimize },
+      // accept -0 number
+      std::regex{ R"(^[-](?:0[xX])?0+$)", std::regex_constants::optimize }
+    };
+    return MatchRegexList(input, re_list);
+  }
+
+ public:
+  UIntegerRegex() = default;
+  virtual ~UIntegerRegex() = default;
+};
+
+class BooleanRegex : public IntegerRegex {
+ protected:
+  bool MatchNumber(const std::string &input) const override {
+    if (input == "true" || input == "false") return true;
+    return IntegerRegex::MatchNumber(input);
+  }
+
+ public:
+  BooleanRegex() = default;
+  virtual ~BooleanRegex() = default;
+};
+
+class FloatRegex : public RegexMatcher {
+ protected:
+  bool MatchNumber(const std::string &input) const override {
+    static const std::vector<std::regex> re_list = {
+      // hex-float
+      std::regex{
+          R"(^[-+]?0[xX](?:(?:[.][0-9a-fA-F]+)|(?:[0-9a-fA-F]+[.][0-9a-fA-F]*)|(?:[0-9a-fA-F]+))[pP][-+]?[0-9]+$)",
+          std::regex_constants::optimize },
+      // dec-float
+      std::regex{
+          R"(^[-+]?(?:(?:[.][0-9]+)|(?:[0-9]+[.][0-9]*)|(?:[0-9]+))(?:[eE][-+]?[0-9]+)?$)",
+          std::regex_constants::optimize },
+
+      std::regex{ R"(^[-+]?(?:nan|inf|infinity)$)",
+                  std::regex_constants::optimize | std::regex_constants::icase }
+    };
+    return MatchRegexList(input, re_list);
+  }
+
+ public:
+  FloatRegex() = default;
+  virtual ~FloatRegex() = default;
+};
+
+class ScalarReferenceResult {
+ private:
+  ScalarReferenceResult(const char *_type, RegexMatcher::MatchResult _matched)
+      : type(_type), matched(_matched) {}
+
+ public:
+  // Decode scalar type and check if the input string satisfies the scalar type.
+  static ScalarReferenceResult Check(uint8_t code, const std::string &input) {
+    switch (code) {
+      case 0x0: return { "double", FloatRegex().Match(input) };
+      case 0x1: return { "float", FloatRegex().Match(input) };
+      case 0x2: return { "int8", IntegerRegex().Match(input) };
+      case 0x3: return { "int16", IntegerRegex().Match(input) };
+      case 0x4: return { "int32", IntegerRegex().Match(input) };
+      case 0x5: return { "int64", IntegerRegex().Match(input) };
+      case 0x6: return { "uint8", UIntegerRegex().Match(input) };
+      case 0x7: return { "uint16", UIntegerRegex().Match(input) };
+      case 0x8: return { "uint32", UIntegerRegex().Match(input) };
+      case 0x9: return { "uint64", UIntegerRegex().Match(input) };
+      case 0xA: return { "bool", BooleanRegex().Match(input) };
+      default: return { "float", FloatRegex().Match(input) };
+    };
+  }
+
+  const char *type;
+  const RegexMatcher::MatchResult matched;
+};
+
+bool Parse(flatbuffers::Parser &parser, const std::string &json,
+           std::string *_text) {
+  auto done = parser.Parse(json.c_str());
+  if (done) {
+    TEST_EQ(GenerateText(parser, parser.builder_.GetBufferPointer(), _text),
+            true);
+  } else {
+    *_text = parser.error_;
+  }
+  return done;
+}
+
+// Utility for test run.
+OneTimeTestInit OneTimeTestInit::one_time_init_;
+
+// llvm std::regex have problem with stack overflow, limit maximum length.
+// ./scalar_fuzzer -max_len=3000
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  // Reserve one byte for Parser flags and one byte for repetition counter.
+  if (size < 3) return 0;
+  const uint8_t flags = data[0];
+  // normalize to ascii alphabet
+  const int extra_rep_number = data[1] >= '0' ? (data[1] - '0') : 0;
+  data += 2;
+  size -= 2;  // bypass
+
+  // Guarantee 0-termination.
+  const std::string original(reinterpret_cast<const char *>(data), size);
+  auto input = std::string(original.c_str());  // until '\0'
+  if (input.empty()) return 0;
+
+  // Break comments in json to avoid complexity with regex matcher.
+  // The string " 12345 /* text */" will be accepted if insert it to string
+  // expression: "table X { Y: " + " 12345 /* text */" + "; }.
+  // But strings like this will complicate regex matcher.
+  // We reject this by transform "/* text */ 12345" to "@* text */ 12345".
+  BreakSequence(input, "//", '@');  // "//" -> "@/"
+  BreakSequence(input, "/*", '@');  // "/*" -> "@*"
+  // Break all known scalar functions (todo: add them to regex?):
+  for (auto f : { "deg", "rad", "sin", "cos", "tan", "asin", "acos", "atan" }) {
+    BreakSequence(input, f, '_');  // ident -> ident
+  }
+
+  // Extract type of scalar from 'flags' and check if the input string satisfies
+  // the scalar type.
+  const auto ref_res =
+      ScalarReferenceResult::Check(flags & flags_scalar_type, input);
+  auto &recheck = ref_res.matched;
+
+  // Create parser
+  flatbuffers::IDLOptions opts;
+  opts.force_defaults = true;
+  opts.output_default_scalars_in_json = true;
+  opts.indent_step = -1;
+  opts.strict_json = true;
+
+  flatbuffers::Parser parser(opts);
+  auto schema =
+      "table X { Y: " + std::string(ref_res.type) + "; } root_type X;";
+  TEST_EQ_FUNC(parser.Parse(schema.c_str()), true);
+
+  // The fuzzer can adjust the number repetition if a side-effects have found.
+  // Each test should pass at least two times to ensure that the parser doesn't
+  // have any hidden-states or locale-depended effects.
+  for (auto cnt = 0; cnt < (extra_rep_number + 2); cnt++) {
+    // Each even run (0,2,4..) will test locale independed code.
+    auto use_locale = !!OneTimeTestInit::test_locale() && (0 == (cnt % 2));
+    // Set new locale.
+    if (use_locale) {
+      FLATBUFFERS_ASSERT(setlocale(LC_ALL, OneTimeTestInit::test_locale()));
+    }
+
+    // Parse original input as-is.
+    auto orig_scalar = "{ \"Y\" : " + input + " }";
+    std::string orig_back;
+    auto orig_done = Parse(parser, orig_scalar, &orig_back);
+
+    if (recheck.res != orig_done) {
+      // look for "does not fit" or "doesn't fit" or "out of range"
+      auto not_fit =
+          (true == recheck.res)
+              ? ((orig_back.find("does not fit") != std::string::npos) ||
+                 (orig_back.find("out of range") != std::string::npos))
+              : false;
+
+      if (false == not_fit) {
+        TEST_OUTPUT_LINE("Stage 1 failed: Parser(%d) != Regex(%d)", orig_done,
+                         recheck.res);
+        TEST_EQ_STR(orig_back.c_str(),
+                    input.substr(recheck.pos, recheck.len).c_str());
+        TEST_EQ_FUNC(orig_done, recheck.res);
+      }
+    }
+
+    // Try to make quoted string and test it.
+    std::string qouted_input;
+    if (true == recheck.quoted) {
+      // we can't simply remove quotes, they may be nested "'12'".
+      // Original string "\'12\'" converted to "'12'".
+      // The string can be an invalid string by JSON rules, but after quotes
+      // removed can transform to valid.
+      assert(recheck.len >= 2);
+    } else {
+      const auto quote = (flags & flags_quotes_kind) ? '\"' : '\'';
+      qouted_input = input;  // copy
+      qouted_input.insert(recheck.pos + recheck.len, 1, quote);
+      qouted_input.insert(recheck.pos, 1, quote);
+    }
+
+    // Test quoted version of the string
+    if (!qouted_input.empty()) {
+      auto fix_scalar = "{ \"Y\" : " + qouted_input + " }";
+      std::string fix_back;
+      auto fix_done = Parse(parser, fix_scalar, &fix_back);
+
+      if (orig_done != fix_done) {
+        TEST_OUTPUT_LINE("Stage 2 failed: Parser(%d) != Regex(%d)", fix_done,
+                         orig_done);
+        TEST_EQ_STR(fix_back.c_str(), orig_back.c_str());
+      }
+      if (orig_done) { TEST_EQ_STR(fix_back.c_str(), orig_back.c_str()); }
+      TEST_EQ_FUNC(fix_done, orig_done);
+    }
+
+    // Create new parser and test default value
+    if (true == orig_done) {
+      flatbuffers::Parser def_parser(opts);  // re-use options
+      auto def_schema = "table X { Y: " + std::string(ref_res.type) + " = " +
+                        input + "; } root_type X;" +
+                        "{}";  // <- with empty json {}!
+
+      auto def_done = def_parser.Parse(def_schema.c_str());
+      if (false == def_done) {
+        TEST_OUTPUT_LINE("Stage 3.1 failed with _error = %s",
+                         def_parser.error_.c_str());
+        FLATBUFFERS_ASSERT(false);
+      }
+      // Compare with print.
+      std::string ref_string, def_string;
+      FLATBUFFERS_ASSERT(GenerateText(
+          parser, parser.builder_.GetBufferPointer(), &ref_string));
+      FLATBUFFERS_ASSERT(GenerateText(
+          def_parser, def_parser.builder_.GetBufferPointer(), &def_string));
+      if (ref_string != def_string) {
+        TEST_OUTPUT_LINE("Stage 3.2 failed: '%s' != '%s'", def_string.c_str(),
+                         ref_string.c_str());
+        FLATBUFFERS_ASSERT(false);
+      }
+    }
+
+    // Restore locale.
+    if (use_locale) { FLATBUFFERS_ASSERT(setlocale(LC_ALL, "C")); }
+  }
+  return 0;
+}
diff --git a/third_party/flatbuffers/tests/fuzzer/flatbuffers_verifier_fuzzer.cc b/third_party/flatbuffers/tests/fuzzer/flatbuffers_verifier_fuzzer.cc
new file mode 100644
index 0000000..d7d453c
--- /dev/null
+++ b/third_party/flatbuffers/tests/fuzzer/flatbuffers_verifier_fuzzer.cc
@@ -0,0 +1,14 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+#include <string>
+
+#include "monster_test_generated.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  flatbuffers::Verifier verifier(data, size);
+  MyGame::Example::VerifyMonsterBuffer(verifier);
+  return 0;
+}
diff --git a/third_party/flatbuffers/tests/fuzzer/fuzzer_assert.h b/third_party/flatbuffers/tests/fuzzer/fuzzer_assert.h
new file mode 100644
index 0000000..afdcf78
--- /dev/null
+++ b/third_party/flatbuffers/tests/fuzzer/fuzzer_assert.h
@@ -0,0 +1,9 @@
+#ifndef FUZZER_ASSERT_IMPL_H_
+#define FUZZER_ASSERT_IMPL_H_
+
+// Declare Debug/Release independed assert macro.
+#define fuzzer_assert_impl(x) (!!(x) ? static_cast<void>(0) : __builtin_trap())
+
+extern "C" void __builtin_trap(void);
+
+#endif // !FUZZER_ASSERT_IMPL_H_
diff --git a/third_party/flatbuffers/tests/fuzzer/readme.md b/third_party/flatbuffers/tests/fuzzer/readme.md
new file mode 100644
index 0000000..c5e147b
--- /dev/null
+++ b/third_party/flatbuffers/tests/fuzzer/readme.md
@@ -0,0 +1,55 @@
+# Test Flatbuffers library with help of libFuzzer
+Test suite of Flatbuffers library has fuzzer section with tests are based on libFuzzer library.
+
+> LibFuzzer is in-process, coverage-guided, evolutionary fuzzing engine.
+LibFuzzer is linked with the library under test, and feeds fuzzed inputs to the library via a specific fuzzing entrypoint (aka “target function”);
+the fuzzer then tracks which areas of the code are reached, and generates mutations on the corpus of input data in order to maximize the code coverage.
+The code coverage information for libFuzzer is provided by LLVM’s SanitizerCoverage instrumentation.
+
+For details about **libFuzzer** see: https://llvm.org/docs/LibFuzzer.html
+
+To build and run these tests LLVM compiler (with clang frontend) and CMake should be installed before.
+
+The fuzzer section include three tests:
+- `verifier_fuzzer` checks stability of deserialization engine for `Monster` schema;
+- `parser_fuzzer` checks stability of schema and json parser under various inputs;
+- `scalar_parser` focused on validation of the parser while parse numeric scalars in schema and/or json files;
+
+## Run tests with a specific locale
+The grammar of the Flatbuffers library is based on printable-ASCII characters.
+By design, the Flatbuffers library should be independent of the global or thread locales used by an end-user application.
+Set environment variable `FLATBUFFERS_TEST_LOCALE` to run a fuzzer with a specific C-locale:
+```sh
+>FLATBUFFERS_TEST_LOCALE="" ./scalar_parser
+>FLATBUFFERS_TEST_LOCALE="ru_RU.CP1251" ./parser_fuzzer
+```
+
+## Run fuzzer
+These are examples of running a fuzzer.
+Flags may vary and depend on a version of the libFuzzer library.
+For details, run a fuzzer with `-help` flag: `./parser_fuzzer -help=1`
+
+`./verifier_fuzzer -reduce_depth=1 -use_value_profile=1 -shrink=1 ../.corpus_verifier/`
+
+`./parser_fuzzer -reduce_depth=1 -use_value_profile=1 -shrink=1 ../.corpus_parser/`
+
+`./scalar_fuzzer -reduce_depth=1 -use_value_profile=1 -shrink=1 -max_len=3000 ../.corpus_parser/ ../.seed_parser/`
+
+Flag `-only_ascii=1` is useful for fast number-compatibility checking while run `scalar_fuzzer`:  
+`./scalar_fuzzer -only_ascii=1 -reduce_depth=1 -use_value_profile=1 -shrink=1 -max_len=3000 -timeout=10 -rss_limit_mb=2048 -jobs=2 ../.corpus_parser/ ../.seed_parser/`
+
+Run with a specific C-locale:  
+`FLATBUFFERS_TEST_LOCALE="ru_RU.CP1251" ./scalar_fuzzer -reduce_depth=1 -use_value_profile=1 -shrink=1 -max_len=3000 -timeout=10 -rss_limit_mb=2048 ../.corpus_parser/ ../.seed_parser/`
+
+## Merge (minimize) corpus
+The **libFuzzer** allow to filter (minimize) corpus with help of `-merge` flag:
+> -merge
+    If set to 1, any corpus inputs from the 2nd, 3rd etc. corpus directories that trigger new code coverage will be merged into the first corpus directory.
+    Defaults to 0. This flag can be used to minimize a corpus.
+
+Merge several seeds to one (a new collected corpus to the seed collection, for example):
+`./scalar_fuzzer -merge=1 ../.seed_parser/ ../.corpus_parser/`
+
+## Know limitations
+- LLVM 7.0 std::regex library has problem with stack overflow, maximum length of input for `scalar_fuzzer` run should be limited to 3000.
+  Example: `./scalar_fuzzer -max_len=3000`
diff --git a/third_party/flatbuffers/tests/fuzzer/test_init.h b/third_party/flatbuffers/tests/fuzzer/test_init.h
new file mode 100644
index 0000000..3d8d07c
--- /dev/null
+++ b/third_party/flatbuffers/tests/fuzzer/test_init.h
@@ -0,0 +1,56 @@
+
+#ifndef FUZZER_TEST_INIT_H_
+#define FUZZER_TEST_INIT_H_
+
+#include "fuzzer_assert.h"
+#include "test_assert.h"
+
+static_assert(__has_feature(memory_sanitizer) ||
+                  __has_feature(address_sanitizer),
+              "sanitizer disabled");
+
+// Utility for test run.
+struct OneTimeTestInit {
+  // Declare trap for the Flatbuffers test engine.
+  // This hook terminate program both in Debug and Release.
+  static bool TestFailListener(const char *expval, const char *val,
+                               const char *exp, const char *file, int line,
+                               const char *func = 0) {
+    (void)expval;
+    (void)val;
+    (void)exp;
+    (void)file;
+    (void)line;
+    (void)func;
+    // FLATBUFFERS_ASSERT redefined to be fully independent of the Flatbuffers
+    // library implementation (see test_assert.h for details).
+    fuzzer_assert_impl(false);  // terminate
+    return false;
+  }
+
+  OneTimeTestInit() : has_locale_(false) {
+    // Fuzzer test should be independent of the test engine implementation.
+    // This hook will terminate test if TEST_EQ/TEST_ASSERT asserted.
+    InitTestEngine(OneTimeTestInit::TestFailListener);
+
+    // Read a locale for the test.
+    if (flatbuffers::ReadEnvironmentVariable("FLATBUFFERS_TEST_LOCALE",
+                                             &test_locale_)) {
+      TEST_OUTPUT_LINE("The environment variable FLATBUFFERS_TEST_LOCALE=%s",
+                       test_locale_.c_str());
+      test_locale_ = flatbuffers::RemoveStringQuotes(test_locale_);
+      has_locale_ = true;
+    }
+  }
+
+  static const char *test_locale() {
+    return one_time_init_.has_locale_ ? nullptr
+                                      : one_time_init_.test_locale_.c_str();
+  }
+
+  bool has_locale_;
+  std::string test_locale_;
+  static OneTimeTestInit one_time_init_;
+};
+
+#endif  // !FUZZER_TEST_INIT_H_
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/generate_code.bat b/third_party/flatbuffers/tests/generate_code.bat
new file mode 100644
index 0000000..59033b8
--- /dev/null
+++ b/third_party/flatbuffers/tests/generate_code.bat
@@ -0,0 +1,46 @@
+:: 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.
+
+set buildtype=Release
+if "%1"=="-b" set buildtype=%2
+
+..\%buildtype%\flatc.exe --cpp --java --csharp --dart --go --binary --lobster --lua --python --js --ts --php --rust --grpc --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --cpp-ptr-type flatbuffers::unique_ptr  --no-fb-import -I include_test monster_test.fbs monsterdata_test.json || goto FAIL
+..\%buildtype%\flatc.exe --cpp --java --csharp --dart --go --binary --lobster --lua --python --js --ts --php --rust --gen-mutable --reflect-names --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr  -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs || goto FAIL
+..\%buildtype%\flatc.exe --cpp --java --csharp --js --ts --php --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr -o union_vector ./union_vector/union_vector.fbs || goto FAIL
+..\%buildtype%\flatc.exe -b --schema --bfbs-comments --bfbs-builtins -I include_test monster_test.fbs || goto FAIL
+..\%buildtype%\flatc.exe -b --schema --bfbs-comments --bfbs-builtins -I include_test arrays_test.fbs || goto FAIL
+..\%buildtype%\flatc.exe --jsonschema --schema -I include_test monster_test.fbs || goto FAIL
+..\%buildtype%\flatc.exe --cpp --java --csharp --python --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --scoped-enums --jsonschema --cpp-ptr-type flatbuffers::unique_ptr arrays_test.fbs || goto FAIL
+..\%buildtype%\flatc.exe --cpp --gen-mutable --gen-object-api --reflect-names --cpp-ptr-type flatbuffers::unique_ptr native_type_test.fbs || goto FAIL
+
+IF NOT "%MONSTER_EXTRA%"=="skip" (
+  @echo Generate MosterExtra
+  ..\%buildtype%\flatc.exe --cpp --java --csharp --python --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes monster_extra.fbs monsterdata_extra.json || goto FAIL
+) else (
+  @echo monster_extra.fbs skipped (the strtod function from MSVC2013 or older doesn't support NaN/Inf arguments)
+)
+
+cd ../samples
+..\%buildtype%\flatc.exe --cpp --lobster --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr monster.fbs || goto FAIL
+..\%buildtype%\flatc.exe -b --schema --bfbs-comments --bfbs-builtins monster.fbs || goto FAIL
+cd ../reflection
+call generate_code.bat %1 %2 || goto FAIL
+
+set EXITCODE=0
+goto SUCCESS
+:FAIL
+set EXITCODE=1
+:SUCCESS
+cd ../tests
+EXIT /B %EXITCODE%
diff --git a/third_party/flatbuffers/tests/generate_code.sh b/third_party/flatbuffers/tests/generate_code.sh
new file mode 100755
index 0000000..d086c2f
--- /dev/null
+++ b/third_party/flatbuffers/tests/generate_code.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+#
+# 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.
+set -e
+
+../flatc --cpp --java --kotlin  --csharp --dart --go --binary --lobster --lua --python --js --ts --php --rust --grpc --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --cpp-ptr-type flatbuffers::unique_ptr  --no-fb-import -I include_test monster_test.fbs monsterdata_test.json
+../flatc --cpp --java --kotlin --csharp --dart --go --binary --lobster --lua --python --js --ts --php --rust --gen-mutable --reflect-names --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr  -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs
+../flatc --cpp --java --kotlin --csharp --js --ts --php --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr -o union_vector ./union_vector/union_vector.fbs
+../flatc -b --schema --bfbs-comments --bfbs-builtins -I include_test monster_test.fbs
+../flatc -b --schema --bfbs-comments --bfbs-builtins -I include_test arrays_test.fbs
+../flatc --jsonschema --schema -I include_test monster_test.fbs
+../flatc --cpp --java --kotlin --csharp --python --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes monster_extra.fbs monsterdata_extra.json
+../flatc --cpp --java --csharp --python --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --scoped-enums --jsonschema --cpp-ptr-type flatbuffers::unique_ptr arrays_test.fbs
+cd ../samples
+../flatc --cpp --kotlin --lobster --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr monster.fbs
+../flatc -b --schema --bfbs-comments --bfbs-builtins monster.fbs
+cd ../reflection
+./generate_code.sh
diff --git a/third_party/flatbuffers/tests/go_test.go b/third_party/flatbuffers/tests/go_test.go
new file mode 100644
index 0000000..4784705
--- /dev/null
+++ b/third_party/flatbuffers/tests/go_test.go
@@ -0,0 +1,1889 @@
+/*
+ * 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.
+ */
+
+package main
+
+import (
+	mygame "MyGame"          // refers to generated code
+	example "MyGame/Example" // refers to generated code
+
+	"bytes"
+	"flag"
+	"fmt"
+	"io/ioutil"
+	"os"
+	"reflect"
+	"sort"
+	"testing"
+
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+
+var (
+	cppData, javaData, outData string
+	fuzz                       bool
+	fuzzFields, fuzzObjects    int
+)
+
+func init() {
+	flag.StringVar(&cppData, "cpp_data", "",
+		"location of monsterdata_test.mon to verify against (required)")
+	flag.StringVar(&javaData, "java_data", "",
+		"location of monsterdata_java_wire.mon to verify against (optional)")
+	flag.StringVar(&outData, "out_data", "",
+		"location to write generated Go data")
+	flag.BoolVar(&fuzz, "fuzz", false, "perform fuzzing")
+	flag.IntVar(&fuzzFields, "fuzz_fields", 4, "fields per fuzzer object")
+	flag.IntVar(&fuzzObjects, "fuzz_objects", 10000,
+		"number of fuzzer objects (higher is slower and more thorough")
+	flag.Parse()
+
+	if cppData == "" {
+		fmt.Fprintf(os.Stderr, "cpp_data argument is required\n")
+		os.Exit(1)
+	}
+}
+
+// Store specific byte patterns in these variables for the fuzzer. These
+// values are taken verbatim from the C++ function FuzzTest1.
+var (
+	overflowingInt32Val = flatbuffers.GetInt32([]byte{0x83, 0x33, 0x33, 0x33})
+	overflowingInt64Val = flatbuffers.GetInt64([]byte{0x84, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44})
+)
+
+// TestAll runs all checks, failing if any errors occur.
+func TestAll(t *testing.T) {
+	// Verify that the Go FlatBuffers runtime library generates the
+	// expected bytes (does not use any schema):
+	CheckByteLayout(t.Fatalf)
+	CheckMutateMethods(t.Fatalf)
+
+	// Verify that panics are raised during exceptional conditions:
+	CheckNotInObjectError(t.Fatalf)
+	CheckStringIsNestedError(t.Fatalf)
+	CheckByteStringIsNestedError(t.Fatalf)
+	CheckStructIsNotInlineError(t.Fatalf)
+	CheckFinishedBytesError(t.Fatalf)
+
+	// Verify that GetRootAs works for non-root tables
+	CheckGetRootAsForNonRootTable(t.Fatalf)
+	CheckTableAccessors(t.Fatalf)
+
+	// Verify that using the generated Go code builds a buffer without
+	// returning errors:
+	generated, off := CheckGeneratedBuild(t.Fatalf)
+
+	// Verify that the buffer generated by Go code is readable by the
+	// generated Go code:
+	CheckReadBuffer(generated, off, t.Fatalf)
+	CheckMutateBuffer(generated, off, t.Fatalf)
+
+	// Verify that the buffer generated by C++ code is readable by the
+	// generated Go code:
+	monsterDataCpp, err := ioutil.ReadFile(cppData)
+	if err != nil {
+		t.Fatal(err)
+	}
+	CheckReadBuffer(monsterDataCpp, 0, t.Fatalf)
+	CheckMutateBuffer(monsterDataCpp, 0, t.Fatalf)
+
+	// Verify that vtables are deduplicated when written:
+	CheckVtableDeduplication(t.Fatalf)
+
+	// Verify the enum names
+	CheckEnumNames(t.Fatalf)
+
+	// Verify enum String methods
+	CheckEnumString(t.Fatalf)
+
+	// Verify the enum values maps
+	CheckEnumValues(t.Fatalf)
+
+	// Verify that the Go code used in FlatBuffers documentation passes
+	// some sanity checks:
+	CheckDocExample(generated, off, t.Fatalf)
+
+	// Check Builder.CreateByteVector
+	CheckCreateByteVector(t.Fatalf)
+
+	// Check a parent namespace import
+	CheckParentNamespace(t.Fatalf)
+
+	// If the filename of the FlatBuffers file generated by the Java test
+	// is given, check that Go code can read it, and that Go code
+	// generates an identical buffer when used to create the example data:
+	if javaData != "" {
+		monsterDataJava, err := ioutil.ReadFile(javaData)
+		if err != nil {
+			t.Fatal(err)
+		}
+		CheckReadBuffer(monsterDataJava, 0, t.Fatalf)
+		CheckByteEquality(generated[off:], monsterDataJava, t.Fatalf)
+	}
+
+	// Verify that various fuzzing scenarios produce a valid FlatBuffer.
+	if fuzz {
+		checkFuzz(fuzzFields, fuzzObjects, t.Fatalf)
+	}
+
+	// Write the generated buffer out to a file:
+	err = ioutil.WriteFile(outData, generated[off:], os.FileMode(0644))
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+// CheckReadBuffer checks that the given buffer is evaluated correctly
+// as the example Monster.
+func CheckReadBuffer(buf []byte, offset flatbuffers.UOffsetT, fail func(string, ...interface{})) {
+	// try the two ways of generating a monster
+	monster1 := example.GetRootAsMonster(buf, offset)
+	monster2 := &example.Monster{}
+	flatbuffers.GetRootAs(buf, offset, monster2)
+	for _, monster := range []*example.Monster{monster1, monster2} {
+		if got := monster.Hp(); 80 != got {
+			fail(FailString("hp", 80, got))
+		}
+
+		// default
+		if got := monster.Mana(); 150 != got {
+			fail(FailString("mana", 150, got))
+		}
+
+		if got := monster.Name(); !bytes.Equal([]byte("MyMonster"), got) {
+			fail(FailString("name", "MyMonster", got))
+		}
+
+		if got := monster.Color(); example.ColorBlue != got {
+			fail(FailString("color", example.ColorBlue, got))
+		}
+
+		if got := monster.Testbool(); true != got {
+			fail(FailString("testbool", true, got))
+		}
+
+		// initialize a Vec3 from Pos()
+		vec := new(example.Vec3)
+		vec = monster.Pos(vec)
+		if vec == nil {
+			fail("vec3 initialization failed")
+		}
+
+		// check that new allocs equal given ones:
+		vec2 := monster.Pos(nil)
+		if !reflect.DeepEqual(vec, vec2) {
+			fail("fresh allocation failed")
+		}
+
+		// verify the properties of the Vec3
+		if got := vec.X(); float32(1.0) != got {
+			fail(FailString("Pos.X", float32(1.0), got))
+		}
+
+		if got := vec.Y(); float32(2.0) != got {
+			fail(FailString("Pos.Y", float32(2.0), got))
+		}
+
+		if got := vec.Z(); float32(3.0) != got {
+			fail(FailString("Pos.Z", float32(3.0), got))
+		}
+
+		if got := vec.Test1(); float64(3.0) != got {
+			fail(FailString("Pos.Test1", float64(3.0), got))
+		}
+
+		if got := vec.Test2(); example.ColorGreen != got {
+			fail(FailString("Pos.Test2", example.ColorGreen, got))
+		}
+
+		// initialize a Test from Test3(...)
+		t := new(example.Test)
+		t = vec.Test3(t)
+		if t == nil {
+			fail("vec.Test3(&t) failed")
+		}
+
+		// check that new allocs equal given ones:
+		t2 := vec.Test3(nil)
+		if !reflect.DeepEqual(t, t2) {
+			fail("fresh allocation failed")
+		}
+
+		// verify the properties of the Test
+		if got := t.A(); int16(5) != got {
+			fail(FailString("t.A()", int16(5), got))
+		}
+
+		if got := t.B(); int8(6) != got {
+			fail(FailString("t.B()", int8(6), got))
+		}
+
+		if got := monster.TestType(); example.AnyMonster != got {
+			fail(FailString("monster.TestType()", example.AnyMonster, got))
+		}
+
+		// initialize a Table from a union field Test(...)
+		var table2 flatbuffers.Table
+		if ok := monster.Test(&table2); !ok {
+			fail("monster.Test(&monster2) failed")
+		}
+
+		// initialize a Monster from the Table from the union
+		var monster2 example.Monster
+		monster2.Init(table2.Bytes, table2.Pos)
+
+		if got := monster2.Name(); !bytes.Equal([]byte("Fred"), got) {
+			fail(FailString("monster2.Name()", "Fred", got))
+		}
+
+		inventorySlice := monster.InventoryBytes()
+		if len(inventorySlice) != monster.InventoryLength() {
+			fail(FailString("len(monster.InventoryBytes) != monster.InventoryLength", len(inventorySlice), monster.InventoryLength()))
+		}
+
+		if got := monster.InventoryLength(); 5 != got {
+			fail(FailString("monster.InventoryLength", 5, got))
+		}
+
+		invsum := 0
+		l := monster.InventoryLength()
+		for i := 0; i < l; i++ {
+			v := monster.Inventory(i)
+			if v != inventorySlice[i] {
+				fail(FailString("monster inventory slice[i] != Inventory(i)", v, inventorySlice[i]))
+			}
+			invsum += int(v)
+		}
+		if invsum != 10 {
+			fail(FailString("monster inventory sum", 10, invsum))
+		}
+
+		if got := monster.Test4Length(); 2 != got {
+			fail(FailString("monster.Test4Length()", 2, got))
+		}
+
+		var test0 example.Test
+		ok := monster.Test4(&test0, 0)
+		if !ok {
+			fail(FailString("monster.Test4(&test0, 0)", true, ok))
+		}
+
+		var test1 example.Test
+		ok = monster.Test4(&test1, 1)
+		if !ok {
+			fail(FailString("monster.Test4(&test1, 1)", true, ok))
+		}
+
+		// the position of test0 and test1 are swapped in monsterdata_java_wire
+		// and monsterdata_test_wire, so ignore ordering
+		v0 := test0.A()
+		v1 := test0.B()
+		v2 := test1.A()
+		v3 := test1.B()
+		sum := int(v0) + int(v1) + int(v2) + int(v3)
+
+		if 100 != sum {
+			fail(FailString("test0 and test1 sum", 100, sum))
+		}
+
+		if got := monster.TestarrayofstringLength(); 2 != got {
+			fail(FailString("Testarrayofstring length", 2, got))
+		}
+
+		if got := monster.Testarrayofstring(0); !bytes.Equal([]byte("test1"), got) {
+			fail(FailString("Testarrayofstring(0)", "test1", got))
+		}
+
+		if got := monster.Testarrayofstring(1); !bytes.Equal([]byte("test2"), got) {
+			fail(FailString("Testarrayofstring(1)", "test2", got))
+		}
+	}
+}
+
+// CheckMutateBuffer checks that the given buffer can be mutated correctly
+// as the example Monster. Only available scalar values are mutated.
+func CheckMutateBuffer(org []byte, offset flatbuffers.UOffsetT, fail func(string, ...interface{})) {
+	// make a copy to mutate
+	buf := make([]byte, len(org))
+	copy(buf, org)
+
+	// load monster data from the buffer
+	monster := example.GetRootAsMonster(buf, offset)
+
+	// test case struct
+	type testcase struct {
+		field  string
+		testfn func() bool
+	}
+
+	testForOriginalValues := []testcase{
+		testcase{"Hp", func() bool { return monster.Hp() == 80 }},
+		testcase{"Mana", func() bool { return monster.Mana() == 150 }},
+		testcase{"Testbool", func() bool { return monster.Testbool() == true }},
+		testcase{"Pos.X'", func() bool { return monster.Pos(nil).X() == float32(1.0) }},
+		testcase{"Pos.Y'", func() bool { return monster.Pos(nil).Y() == float32(2.0) }},
+		testcase{"Pos.Z'", func() bool { return monster.Pos(nil).Z() == float32(3.0) }},
+		testcase{"Pos.Test1'", func() bool { return monster.Pos(nil).Test1() == float64(3.0) }},
+		testcase{"Pos.Test2'", func() bool { return monster.Pos(nil).Test2() == example.ColorGreen }},
+		testcase{"Pos.Test3.A", func() bool { return monster.Pos(nil).Test3(nil).A() == int16(5) }},
+		testcase{"Pos.Test3.B", func() bool { return monster.Pos(nil).Test3(nil).B() == int8(6) }},
+		testcase{"Inventory[2]", func() bool { return monster.Inventory(2) == byte(2) }},
+	}
+
+	testMutability := []testcase{
+		testcase{"Hp", func() bool { return monster.MutateHp(70) }},
+		testcase{"Mana", func() bool { return !monster.MutateMana(140) }},
+		testcase{"Testbool", func() bool { return monster.MutateTestbool(false) }},
+		testcase{"Pos.X", func() bool { return monster.Pos(nil).MutateX(10.0) }},
+		testcase{"Pos.Y", func() bool { return monster.Pos(nil).MutateY(20.0) }},
+		testcase{"Pos.Z", func() bool { return monster.Pos(nil).MutateZ(30.0) }},
+		testcase{"Pos.Test1", func() bool { return monster.Pos(nil).MutateTest1(30.0) }},
+		testcase{"Pos.Test2", func() bool { return monster.Pos(nil).MutateTest2(example.ColorBlue) }},
+		testcase{"Pos.Test3.A", func() bool { return monster.Pos(nil).Test3(nil).MutateA(50) }},
+		testcase{"Pos.Test3.B", func() bool { return monster.Pos(nil).Test3(nil).MutateB(60) }},
+		testcase{"Inventory[2]", func() bool { return monster.MutateInventory(2, 200) }},
+	}
+
+	testForMutatedValues := []testcase{
+		testcase{"Hp", func() bool { return monster.Hp() == 70 }},
+		testcase{"Mana", func() bool { return monster.Mana() == 150 }},
+		testcase{"Testbool", func() bool { return monster.Testbool() == false }},
+		testcase{"Pos.X'", func() bool { return monster.Pos(nil).X() == float32(10.0) }},
+		testcase{"Pos.Y'", func() bool { return monster.Pos(nil).Y() == float32(20.0) }},
+		testcase{"Pos.Z'", func() bool { return monster.Pos(nil).Z() == float32(30.0) }},
+		testcase{"Pos.Test1'", func() bool { return monster.Pos(nil).Test1() == float64(30.0) }},
+		testcase{"Pos.Test2'", func() bool { return monster.Pos(nil).Test2() == example.ColorBlue }},
+		testcase{"Pos.Test3.A", func() bool { return monster.Pos(nil).Test3(nil).A() == int16(50) }},
+		testcase{"Pos.Test3.B", func() bool { return monster.Pos(nil).Test3(nil).B() == int8(60) }},
+		testcase{"Inventory[2]", func() bool { return monster.Inventory(2) == byte(200) }},
+	}
+
+	testInvalidEnumValues := []testcase{
+		testcase{"Pos.Test2", func() bool { return monster.Pos(nil).MutateTest2(example.Color(20)) }},
+		testcase{"Pos.Test2", func() bool { return monster.Pos(nil).Test2() == example.Color(20) }},
+	}
+
+	// make sure original values are okay
+	for _, t := range testForOriginalValues {
+		if !t.testfn() {
+			fail("field '" + t.field + "' doesn't have the expected original value")
+		}
+	}
+
+	// try to mutate fields and check mutability
+	for _, t := range testMutability {
+		if !t.testfn() {
+			fail(FailString("field '"+t.field+"' failed mutability test", true, false))
+		}
+	}
+
+	// test whether values have changed
+	for _, t := range testForMutatedValues {
+		if !t.testfn() {
+			fail("field '" + t.field + "' doesn't have the expected mutated value")
+		}
+	}
+
+	// make sure the buffer has changed
+	if reflect.DeepEqual(buf, org) {
+		fail("mutate buffer failed")
+	}
+
+	// To make sure the buffer has changed accordingly
+	// Read data from the buffer and verify all fields
+	monster = example.GetRootAsMonster(buf, offset)
+	for _, t := range testForMutatedValues {
+		if !t.testfn() {
+			fail("field '" + t.field + "' doesn't have the expected mutated value")
+		}
+	}
+
+	// a couple extra tests for "invalid" enum values, which don't correspond to
+	// anything in the schema, but are allowed
+	for _, t := range testInvalidEnumValues {
+		if !t.testfn() {
+			fail("field '" + t.field + "' doesn't work with an invalid enum value")
+		}
+	}
+
+	// reverting all fields to original values should
+	// re-create the original buffer. Mutate all fields
+	// back to their original values and compare buffers.
+	// This test is done to make sure mutations do not do
+	// any unnecessary changes to the buffer.
+	monster = example.GetRootAsMonster(buf, offset)
+	monster.MutateHp(80)
+	monster.MutateTestbool(true)
+	monster.Pos(nil).MutateX(1.0)
+	monster.Pos(nil).MutateY(2.0)
+	monster.Pos(nil).MutateZ(3.0)
+	monster.Pos(nil).MutateTest1(3.0)
+	monster.Pos(nil).MutateTest2(example.ColorGreen)
+	monster.Pos(nil).Test3(nil).MutateA(5)
+	monster.Pos(nil).Test3(nil).MutateB(6)
+	monster.MutateInventory(2, 2)
+
+	for _, t := range testForOriginalValues {
+		if !t.testfn() {
+			fail("field '" + t.field + "' doesn't have the expected original value")
+		}
+	}
+
+	// buffer should have original values
+	if !reflect.DeepEqual(buf, org) {
+		fail("revert changes failed")
+	}
+}
+
+// Low level stress/fuzz test: serialize/deserialize a variety of
+// different kinds of data in different combinations
+func checkFuzz(fuzzFields, fuzzObjects int, fail func(string, ...interface{})) {
+
+	// Values we're testing against: chosen to ensure no bits get chopped
+	// off anywhere, and also be different from eachother.
+	boolVal := true
+	int8Val := int8(-127) // 0x81
+	uint8Val := uint8(0xFF)
+	int16Val := int16(-32222) // 0x8222
+	uint16Val := uint16(0xFEEE)
+	int32Val := int32(overflowingInt32Val)
+	uint32Val := uint32(0xFDDDDDDD)
+	int64Val := int64(overflowingInt64Val)
+	uint64Val := uint64(0xFCCCCCCCCCCCCCCC)
+	float32Val := float32(3.14159)
+	float64Val := float64(3.14159265359)
+
+	testValuesMax := 11 // hardcoded to the number of scalar types
+
+	builder := flatbuffers.NewBuilder(0)
+	l := NewLCG()
+
+	objects := make([]flatbuffers.UOffsetT, fuzzObjects)
+
+	// Generate fuzzObjects random objects each consisting of
+	// fuzzFields fields, each of a random type.
+	for i := 0; i < fuzzObjects; i++ {
+		builder.StartObject(fuzzFields)
+
+		for f := 0; f < fuzzFields; f++ {
+			choice := l.Next() % uint32(testValuesMax)
+			switch choice {
+			case 0:
+				builder.PrependBoolSlot(int(f), boolVal, false)
+			case 1:
+				builder.PrependInt8Slot(int(f), int8Val, 0)
+			case 2:
+				builder.PrependUint8Slot(int(f), uint8Val, 0)
+			case 3:
+				builder.PrependInt16Slot(int(f), int16Val, 0)
+			case 4:
+				builder.PrependUint16Slot(int(f), uint16Val, 0)
+			case 5:
+				builder.PrependInt32Slot(int(f), int32Val, 0)
+			case 6:
+				builder.PrependUint32Slot(int(f), uint32Val, 0)
+			case 7:
+				builder.PrependInt64Slot(int(f), int64Val, 0)
+			case 8:
+				builder.PrependUint64Slot(int(f), uint64Val, 0)
+			case 9:
+				builder.PrependFloat32Slot(int(f), float32Val, 0)
+			case 10:
+				builder.PrependFloat64Slot(int(f), float64Val, 0)
+			}
+		}
+
+		off := builder.EndObject()
+
+		// store the offset from the end of the builder buffer,
+		// since it will keep growing:
+		objects[i] = off
+	}
+
+	// Do some bookkeeping to generate stats on fuzzes:
+	stats := map[string]int{}
+	check := func(desc string, want, got interface{}) {
+		stats[desc]++
+		if want != got {
+			fail("%s want %v got %v", desc, want, got)
+		}
+	}
+
+	l = NewLCG() // Reset.
+
+	// Test that all objects we generated are readable and return the
+	// expected values. We generate random objects in the same order
+	// so this is deterministic.
+	for i := 0; i < fuzzObjects; i++ {
+
+		table := &flatbuffers.Table{
+			Bytes: builder.Bytes,
+			Pos:   flatbuffers.UOffsetT(len(builder.Bytes)) - objects[i],
+		}
+
+		for j := 0; j < fuzzFields; j++ {
+			f := flatbuffers.VOffsetT((flatbuffers.VtableMetadataFields + j) * flatbuffers.SizeVOffsetT)
+			choice := l.Next() % uint32(testValuesMax)
+
+			switch choice {
+			case 0:
+				check("bool", boolVal, table.GetBoolSlot(f, false))
+			case 1:
+				check("int8", int8Val, table.GetInt8Slot(f, 0))
+			case 2:
+				check("uint8", uint8Val, table.GetUint8Slot(f, 0))
+			case 3:
+				check("int16", int16Val, table.GetInt16Slot(f, 0))
+			case 4:
+				check("uint16", uint16Val, table.GetUint16Slot(f, 0))
+			case 5:
+				check("int32", int32Val, table.GetInt32Slot(f, 0))
+			case 6:
+				check("uint32", uint32Val, table.GetUint32Slot(f, 0))
+			case 7:
+				check("int64", int64Val, table.GetInt64Slot(f, 0))
+			case 8:
+				check("uint64", uint64Val, table.GetUint64Slot(f, 0))
+			case 9:
+				check("float32", float32Val, table.GetFloat32Slot(f, 0))
+			case 10:
+				check("float64", float64Val, table.GetFloat64Slot(f, 0))
+			}
+		}
+	}
+
+	// If enough checks were made, verify that all scalar types were used:
+	if fuzzFields*fuzzObjects >= testValuesMax {
+		if len(stats) != testValuesMax {
+			fail("fuzzing failed to test all scalar types")
+		}
+	}
+
+	// Print some counts, if needed:
+	if testing.Verbose() {
+		if fuzzFields == 0 || fuzzObjects == 0 {
+			fmt.Printf("fuzz\tfields: %d\tobjects: %d\t[none]\t%d\n",
+				fuzzFields, fuzzObjects, 0)
+		} else {
+			keys := make([]string, 0, len(stats))
+			for k := range stats {
+				keys = append(keys, k)
+			}
+			sort.Strings(keys)
+			for _, k := range keys {
+				fmt.Printf("fuzz\tfields: %d\tobjects: %d\t%s\t%d\n",
+					fuzzFields, fuzzObjects, k, stats[k])
+			}
+		}
+	}
+
+	return
+}
+
+// FailString makes a message for when expectations differ from reality.
+func FailString(name string, want, got interface{}) string {
+	return fmt.Sprintf("bad %s: want %#v got %#v", name, want, got)
+}
+
+// CheckByteLayout verifies the bytes of a Builder in various scenarios.
+func CheckByteLayout(fail func(string, ...interface{})) {
+	var b *flatbuffers.Builder
+
+	var i int
+	check := func(want []byte) {
+		i++
+		got := b.Bytes[b.Head():]
+		if !bytes.Equal(want, got) {
+			fail("case %d: want\n%v\nbut got\n%v\n", i, want, got)
+		}
+	}
+
+	// test 1: numbers
+
+	b = flatbuffers.NewBuilder(0)
+	check([]byte{})
+	b.PrependBool(true)
+	check([]byte{1})
+	b.PrependInt8(-127)
+	check([]byte{129, 1})
+	b.PrependUint8(255)
+	check([]byte{255, 129, 1})
+	b.PrependInt16(-32222)
+	check([]byte{0x22, 0x82, 0, 255, 129, 1}) // first pad
+	b.PrependUint16(0xFEEE)
+	check([]byte{0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1}) // no pad this time
+	b.PrependInt32(-53687092)
+	check([]byte{204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1})
+	b.PrependUint32(0x98765432)
+	check([]byte{0x32, 0x54, 0x76, 0x98, 204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1})
+
+	// test 1b: numbers 2
+
+	b = flatbuffers.NewBuilder(0)
+	b.PrependUint64(0x1122334455667788)
+	check([]byte{0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11})
+
+	// test 2: 1xbyte vector
+
+	b = flatbuffers.NewBuilder(0)
+	check([]byte{})
+	b.StartVector(flatbuffers.SizeByte, 1, 1)
+	check([]byte{0, 0, 0}) // align to 4bytes
+	b.PrependByte(1)
+	check([]byte{1, 0, 0, 0})
+	b.EndVector(1)
+	check([]byte{1, 0, 0, 0, 1, 0, 0, 0}) // padding
+
+	// test 3: 2xbyte vector
+
+	b = flatbuffers.NewBuilder(0)
+	b.StartVector(flatbuffers.SizeByte, 2, 1)
+	check([]byte{0, 0}) // align to 4bytes
+	b.PrependByte(1)
+	check([]byte{1, 0, 0})
+	b.PrependByte(2)
+	check([]byte{2, 1, 0, 0})
+	b.EndVector(2)
+	check([]byte{2, 0, 0, 0, 2, 1, 0, 0}) // padding
+
+	// test 3b: 11xbyte vector matches builder size
+
+	b = flatbuffers.NewBuilder(12)
+	b.StartVector(flatbuffers.SizeByte, 8, 1)
+	start := []byte{}
+	check(start)
+	for i := 1; i < 12; i++ {
+		b.PrependByte(byte(i))
+		start = append([]byte{byte(i)}, start...)
+		check(start)
+	}
+	b.EndVector(8)
+	check(append([]byte{8, 0, 0, 0}, start...))
+
+	// test 4: 1xuint16 vector
+
+	b = flatbuffers.NewBuilder(0)
+	b.StartVector(flatbuffers.SizeUint16, 1, 1)
+	check([]byte{0, 0}) // align to 4bytes
+	b.PrependUint16(1)
+	check([]byte{1, 0, 0, 0})
+	b.EndVector(1)
+	check([]byte{1, 0, 0, 0, 1, 0, 0, 0}) // padding
+
+	// test 5: 2xuint16 vector
+
+	b = flatbuffers.NewBuilder(0)
+	b.StartVector(flatbuffers.SizeUint16, 2, 1)
+	check([]byte{}) // align to 4bytes
+	b.PrependUint16(0xABCD)
+	check([]byte{0xCD, 0xAB})
+	b.PrependUint16(0xDCBA)
+	check([]byte{0xBA, 0xDC, 0xCD, 0xAB})
+	b.EndVector(2)
+	check([]byte{2, 0, 0, 0, 0xBA, 0xDC, 0xCD, 0xAB})
+
+	// test 6: CreateString
+
+	b = flatbuffers.NewBuilder(0)
+	b.CreateString("foo")
+	check([]byte{3, 0, 0, 0, 'f', 'o', 'o', 0}) // 0-terminated, no pad
+	b.CreateString("moop")
+	check([]byte{4, 0, 0, 0, 'm', 'o', 'o', 'p', 0, 0, 0, 0, // 0-terminated, 3-byte pad
+		3, 0, 0, 0, 'f', 'o', 'o', 0})
+
+	// test 6b: CreateString unicode
+
+	b = flatbuffers.NewBuilder(0)
+	// These characters are chinese from blog.golang.org/strings
+	// We use escape codes here so that editors without unicode support
+	// aren't bothered:
+	uni_str := "\u65e5\u672c\u8a9e"
+	b.CreateString(uni_str)
+	check([]byte{9, 0, 0, 0, 230, 151, 165, 230, 156, 172, 232, 170, 158, 0, //  null-terminated, 2-byte pad
+		0, 0})
+
+	// test 6c: CreateByteString
+
+	b = flatbuffers.NewBuilder(0)
+	b.CreateByteString([]byte("foo"))
+	check([]byte{3, 0, 0, 0, 'f', 'o', 'o', 0}) // 0-terminated, no pad
+	b.CreateByteString([]byte("moop"))
+	check([]byte{4, 0, 0, 0, 'm', 'o', 'o', 'p', 0, 0, 0, 0, // 0-terminated, 3-byte pad
+		3, 0, 0, 0, 'f', 'o', 'o', 0})
+
+	// test 7: empty vtable
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(0)
+	check([]byte{})
+	b.EndObject()
+	check([]byte{4, 0, 4, 0, 4, 0, 0, 0})
+
+	// test 8: vtable with one true bool
+	b = flatbuffers.NewBuilder(0)
+	check([]byte{})
+	b.StartObject(1)
+	check([]byte{})
+	b.PrependBoolSlot(0, true, false)
+	b.EndObject()
+	check([]byte{
+		6, 0, // vtable bytes
+		8, 0, // length of object including vtable offset
+		7, 0, // start of bool value
+		6, 0, 0, 0, // offset for start of vtable (int32)
+		0, 0, 0, // padded to 4 bytes
+		1, // bool value
+	})
+
+	// test 9: vtable with one default bool
+	b = flatbuffers.NewBuilder(0)
+	check([]byte{})
+	b.StartObject(1)
+	check([]byte{})
+	b.PrependBoolSlot(0, false, false)
+	b.EndObject()
+	check([]byte{
+		4, 0, // vtable bytes
+		4, 0, // end of object from here
+		// entry 1 is zero and not stored.
+		4, 0, 0, 0, // offset for start of vtable (int32)
+	})
+
+	// test 10: vtable with one int16
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(1)
+	b.PrependInt16Slot(0, 0x789A, 0)
+	b.EndObject()
+	check([]byte{
+		6, 0, // vtable bytes
+		8, 0, // end of object from here
+		6, 0, // offset to value
+		6, 0, 0, 0, // offset for start of vtable (int32)
+		0, 0, // padding to 4 bytes
+		0x9A, 0x78,
+	})
+
+	// test 11: vtable with two int16
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(2)
+	b.PrependInt16Slot(0, 0x3456, 0)
+	b.PrependInt16Slot(1, 0x789A, 0)
+	b.EndObject()
+	check([]byte{
+		8, 0, // vtable bytes
+		8, 0, // end of object from here
+		6, 0, // offset to value 0
+		4, 0, // offset to value 1
+		8, 0, 0, 0, // offset for start of vtable (int32)
+		0x9A, 0x78, // value 1
+		0x56, 0x34, // value 0
+	})
+
+	// test 12: vtable with int16 and bool
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(2)
+	b.PrependInt16Slot(0, 0x3456, 0)
+	b.PrependBoolSlot(1, true, false)
+	b.EndObject()
+	check([]byte{
+		8, 0, // vtable bytes
+		8, 0, // end of object from here
+		6, 0, // offset to value 0
+		5, 0, // offset to value 1
+		8, 0, 0, 0, // offset for start of vtable (int32)
+		0,          // padding
+		1,          // value 1
+		0x56, 0x34, // value 0
+	})
+
+	// test 12: vtable with empty vector
+	b = flatbuffers.NewBuilder(0)
+	b.StartVector(flatbuffers.SizeByte, 0, 1)
+	vecend := b.EndVector(0)
+	b.StartObject(1)
+	b.PrependUOffsetTSlot(0, vecend, 0)
+	b.EndObject()
+	check([]byte{
+		6, 0, // vtable bytes
+		8, 0,
+		4, 0, // offset to vector offset
+		6, 0, 0, 0, // offset for start of vtable (int32)
+		4, 0, 0, 0,
+		0, 0, 0, 0, // length of vector (not in struct)
+	})
+
+	// test 12b: vtable with empty vector of byte and some scalars
+	b = flatbuffers.NewBuilder(0)
+	b.StartVector(flatbuffers.SizeByte, 0, 1)
+	vecend = b.EndVector(0)
+	b.StartObject(2)
+	b.PrependInt16Slot(0, 55, 0)
+	b.PrependUOffsetTSlot(1, vecend, 0)
+	b.EndObject()
+	check([]byte{
+		8, 0, // vtable bytes
+		12, 0,
+		10, 0, // offset to value 0
+		4, 0, // offset to vector offset
+		8, 0, 0, 0, // vtable loc
+		8, 0, 0, 0, // value 1
+		0, 0, 55, 0, // value 0
+
+		0, 0, 0, 0, // length of vector (not in struct)
+	})
+
+	// test 13: vtable with 1 int16 and 2-vector of int16
+	b = flatbuffers.NewBuilder(0)
+	b.StartVector(flatbuffers.SizeInt16, 2, 1)
+	b.PrependInt16(0x1234)
+	b.PrependInt16(0x5678)
+	vecend = b.EndVector(2)
+	b.StartObject(2)
+	b.PrependUOffsetTSlot(1, vecend, 0)
+	b.PrependInt16Slot(0, 55, 0)
+	b.EndObject()
+	check([]byte{
+		8, 0, // vtable bytes
+		12, 0, // length of object
+		6, 0, // start of value 0 from end of vtable
+		8, 0, // start of value 1 from end of buffer
+		8, 0, 0, 0, // offset for start of vtable (int32)
+		0, 0, // padding
+		55, 0, // value 0
+		4, 0, 0, 0, // vector position from here
+		2, 0, 0, 0, // length of vector (uint32)
+		0x78, 0x56, // vector value 1
+		0x34, 0x12, // vector value 0
+	})
+
+	// test 14: vtable with 1 struct of 1 int8, 1 int16, 1 int32
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(1)
+	b.Prep(4+4+4, 0)
+	b.PrependInt8(55)
+	b.Pad(3)
+	b.PrependInt16(0x1234)
+	b.Pad(2)
+	b.PrependInt32(0x12345678)
+	structStart := b.Offset()
+	b.PrependStructSlot(0, structStart, 0)
+	b.EndObject()
+	check([]byte{
+		6, 0, // vtable bytes
+		16, 0, // end of object from here
+		4, 0, // start of struct from here
+		6, 0, 0, 0, // offset for start of vtable (int32)
+		0x78, 0x56, 0x34, 0x12, // value 2
+		0, 0, // padding
+		0x34, 0x12, // value 1
+		0, 0, 0, // padding
+		55, // value 0
+	})
+
+	// test 15: vtable with 1 vector of 2 struct of 2 int8
+	b = flatbuffers.NewBuilder(0)
+	b.StartVector(flatbuffers.SizeInt8*2, 2, 1)
+	b.PrependInt8(33)
+	b.PrependInt8(44)
+	b.PrependInt8(55)
+	b.PrependInt8(66)
+	vecend = b.EndVector(2)
+	b.StartObject(1)
+	b.PrependUOffsetTSlot(0, vecend, 0)
+	b.EndObject()
+	check([]byte{
+		6, 0, // vtable bytes
+		8, 0,
+		4, 0, // offset of vector offset
+		6, 0, 0, 0, // offset for start of vtable (int32)
+		4, 0, 0, 0, // vector start offset
+
+		2, 0, 0, 0, // vector length
+		66, // vector value 1,1
+		55, // vector value 1,0
+		44, // vector value 0,1
+		33, // vector value 0,0
+	})
+
+	// test 16: table with some elements
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(2)
+	b.PrependInt8Slot(0, 33, 0)
+	b.PrependInt16Slot(1, 66, 0)
+	off := b.EndObject()
+	b.Finish(off)
+
+	check([]byte{
+		12, 0, 0, 0, // root of table: points to vtable offset
+
+		8, 0, // vtable bytes
+		8, 0, // end of object from here
+		7, 0, // start of value 0
+		4, 0, // start of value 1
+
+		8, 0, 0, 0, // offset for start of vtable (int32)
+
+		66, 0, // value 1
+		0,  // padding
+		33, // value 0
+	})
+
+	// test 17: one unfinished table and one finished table
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(2)
+	b.PrependInt8Slot(0, 33, 0)
+	b.PrependInt8Slot(1, 44, 0)
+	off = b.EndObject()
+	b.Finish(off)
+
+	b.StartObject(3)
+	b.PrependInt8Slot(0, 55, 0)
+	b.PrependInt8Slot(1, 66, 0)
+	b.PrependInt8Slot(2, 77, 0)
+	off = b.EndObject()
+	b.Finish(off)
+
+	check([]byte{
+		16, 0, 0, 0, // root of table: points to object
+		0, 0, // padding
+
+		10, 0, // vtable bytes
+		8, 0, // size of object
+		7, 0, // start of value 0
+		6, 0, // start of value 1
+		5, 0, // start of value 2
+		10, 0, 0, 0, // offset for start of vtable (int32)
+		0,  // padding
+		77, // value 2
+		66, // value 1
+		55, // value 0
+
+		12, 0, 0, 0, // root of table: points to object
+
+		8, 0, // vtable bytes
+		8, 0, // size of object
+		7, 0, // start of value 0
+		6, 0, // start of value 1
+		8, 0, 0, 0, // offset for start of vtable (int32)
+		0, 0, // padding
+		44, // value 1
+		33, // value 0
+	})
+
+	// test 18: a bunch of bools
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(8)
+	b.PrependBoolSlot(0, true, false)
+	b.PrependBoolSlot(1, true, false)
+	b.PrependBoolSlot(2, true, false)
+	b.PrependBoolSlot(3, true, false)
+	b.PrependBoolSlot(4, true, false)
+	b.PrependBoolSlot(5, true, false)
+	b.PrependBoolSlot(6, true, false)
+	b.PrependBoolSlot(7, true, false)
+	off = b.EndObject()
+	b.Finish(off)
+
+	check([]byte{
+		24, 0, 0, 0, // root of table: points to vtable offset
+
+		20, 0, // vtable bytes
+		12, 0, // size of object
+		11, 0, // start of value 0
+		10, 0, // start of value 1
+		9, 0, // start of value 2
+		8, 0, // start of value 3
+		7, 0, // start of value 4
+		6, 0, // start of value 5
+		5, 0, // start of value 6
+		4, 0, // start of value 7
+		20, 0, 0, 0, // vtable offset
+
+		1, // value 7
+		1, // value 6
+		1, // value 5
+		1, // value 4
+		1, // value 3
+		1, // value 2
+		1, // value 1
+		1, // value 0
+	})
+
+	// test 19: three bools
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(3)
+	b.PrependBoolSlot(0, true, false)
+	b.PrependBoolSlot(1, true, false)
+	b.PrependBoolSlot(2, true, false)
+	off = b.EndObject()
+	b.Finish(off)
+
+	check([]byte{
+		16, 0, 0, 0, // root of table: points to vtable offset
+
+		0, 0, // padding
+
+		10, 0, // vtable bytes
+		8, 0, // size of object
+		7, 0, // start of value 0
+		6, 0, // start of value 1
+		5, 0, // start of value 2
+		10, 0, 0, 0, // vtable offset from here
+
+		0, // padding
+		1, // value 2
+		1, // value 1
+		1, // value 0
+	})
+
+	// test 20: some floats
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(1)
+	b.PrependFloat32Slot(0, 1.0, 0.0)
+	off = b.EndObject()
+
+	check([]byte{
+		6, 0, // vtable bytes
+		8, 0, // size of object
+		4, 0, // start of value 0
+		6, 0, 0, 0, // vtable offset
+
+		0, 0, 128, 63, // value 0
+	})
+}
+
+// CheckManualBuild builds a Monster manually.
+func CheckManualBuild(fail func(string, ...interface{})) ([]byte, flatbuffers.UOffsetT) {
+	b := flatbuffers.NewBuilder(0)
+	str := b.CreateString("MyMonster")
+
+	b.StartVector(1, 5, 1)
+	b.PrependByte(4)
+	b.PrependByte(3)
+	b.PrependByte(2)
+	b.PrependByte(1)
+	b.PrependByte(0)
+	inv := b.EndVector(5)
+
+	b.StartObject(13)
+	b.PrependInt16Slot(2, 20, 100)
+	mon2 := b.EndObject()
+
+	// Test4Vector
+	b.StartVector(4, 2, 1)
+
+	// Test 0
+	b.Prep(2, 4)
+	b.Pad(1)
+	b.PlaceInt8(20)
+	b.PlaceInt16(10)
+
+	// Test 1
+	b.Prep(2, 4)
+	b.Pad(1)
+	b.PlaceInt8(40)
+	b.PlaceInt16(30)
+
+	// end testvector
+	test4 := b.EndVector(2)
+
+	b.StartObject(13)
+
+	// a vec3
+	b.Prep(16, 32)
+	b.Pad(2)
+	b.Prep(2, 4)
+	b.Pad(1)
+	b.PlaceByte(6)
+	b.PlaceInt16(5)
+	b.Pad(1)
+	b.PlaceByte(4)
+	b.PlaceFloat64(3.0)
+	b.Pad(4)
+	b.PlaceFloat32(3.0)
+	b.PlaceFloat32(2.0)
+	b.PlaceFloat32(1.0)
+	vec3Loc := b.Offset()
+	// end vec3
+
+	b.PrependStructSlot(0, vec3Loc, 0) // vec3. noop
+	b.PrependInt16Slot(2, 80, 100)     // hp
+	b.PrependUOffsetTSlot(3, str, 0)
+	b.PrependUOffsetTSlot(5, inv, 0) // inventory
+	b.PrependByteSlot(7, 1, 0)
+	b.PrependUOffsetTSlot(8, mon2, 0)
+	b.PrependUOffsetTSlot(9, test4, 0)
+	mon := b.EndObject()
+
+	b.Finish(mon)
+
+	return b.Bytes, b.Head()
+}
+
+func CheckGetRootAsForNonRootTable(fail func(string, ...interface{})) {
+	b := flatbuffers.NewBuilder(0)
+	str := b.CreateString("MyStat")
+	example.StatStart(b)
+	example.StatAddId(b, str)
+	example.StatAddVal(b, 12345678)
+	example.StatAddCount(b, 12345)
+	stat_end := example.StatEnd(b)
+	b.Finish(stat_end)
+
+	stat := example.GetRootAsStat(b.Bytes, b.Head())
+
+	if got := stat.Id(); !bytes.Equal([]byte("MyStat"), got) {
+		fail(FailString("stat.Id()", "MyStat", got))
+	}
+
+	if got := stat.Val(); 12345678 != got {
+		fail(FailString("stat.Val()", 12345678, got))
+	}
+
+	if got := stat.Count(); 12345 != got {
+		fail(FailString("stat.Count()", 12345, got))
+	}
+}
+
+// CheckGeneratedBuild uses generated code to build the example Monster.
+func CheckGeneratedBuild(fail func(string, ...interface{})) ([]byte, flatbuffers.UOffsetT) {
+	b := flatbuffers.NewBuilder(0)
+	str := b.CreateString("MyMonster")
+	test1 := b.CreateString("test1")
+	test2 := b.CreateString("test2")
+	fred := b.CreateString("Fred")
+
+	example.MonsterStartInventoryVector(b, 5)
+	b.PrependByte(4)
+	b.PrependByte(3)
+	b.PrependByte(2)
+	b.PrependByte(1)
+	b.PrependByte(0)
+	inv := b.EndVector(5)
+
+	example.MonsterStart(b)
+	example.MonsterAddName(b, fred)
+	mon2 := example.MonsterEnd(b)
+
+	example.MonsterStartTest4Vector(b, 2)
+	example.CreateTest(b, 10, 20)
+	example.CreateTest(b, 30, 40)
+	test4 := b.EndVector(2)
+
+	example.MonsterStartTestarrayofstringVector(b, 2)
+	b.PrependUOffsetT(test2)
+	b.PrependUOffsetT(test1)
+	testArrayOfString := b.EndVector(2)
+
+	example.MonsterStart(b)
+
+	pos := example.CreateVec3(b, 1.0, 2.0, 3.0, 3.0, example.ColorGreen, 5, 6)
+	example.MonsterAddPos(b, pos)
+
+	example.MonsterAddHp(b, 80)
+	example.MonsterAddName(b, str)
+	example.MonsterAddTestbool(b, true)
+	example.MonsterAddInventory(b, inv)
+	example.MonsterAddTestType(b, 1)
+	example.MonsterAddTest(b, mon2)
+	example.MonsterAddTest4(b, test4)
+	example.MonsterAddTestarrayofstring(b, testArrayOfString)
+	mon := example.MonsterEnd(b)
+
+	b.Finish(mon)
+
+	return b.Bytes, b.Head()
+}
+
+// CheckTableAccessors checks that the table accessors work as expected.
+func CheckTableAccessors(fail func(string, ...interface{})) {
+	// test struct accessor
+	b := flatbuffers.NewBuilder(0)
+	pos := example.CreateVec3(b, 1.0, 2.0, 3.0, 3.0, 4, 5, 6)
+	b.Finish(pos)
+	vec3Bytes := b.FinishedBytes()
+	vec3 := &example.Vec3{}
+	flatbuffers.GetRootAs(vec3Bytes, 0, vec3)
+
+	if bytes.Compare(vec3Bytes, vec3.Table().Bytes) != 0 {
+		fail("invalid vec3 table")
+	}
+
+	// test table accessor
+	b = flatbuffers.NewBuilder(0)
+	str := b.CreateString("MyStat")
+	example.StatStart(b)
+	example.StatAddId(b, str)
+	example.StatAddVal(b, 12345678)
+	example.StatAddCount(b, 12345)
+	pos = example.StatEnd(b)
+	b.Finish(pos)
+	statBytes := b.FinishedBytes()
+	stat := &example.Stat{}
+	flatbuffers.GetRootAs(statBytes, 0, stat)
+
+	if bytes.Compare(statBytes, stat.Table().Bytes) != 0 {
+		fail("invalid stat table")
+	}
+}
+
+// CheckVtableDeduplication verifies that vtables are deduplicated.
+func CheckVtableDeduplication(fail func(string, ...interface{})) {
+	b := flatbuffers.NewBuilder(0)
+
+	b.StartObject(4)
+	b.PrependByteSlot(0, 0, 0)
+	b.PrependByteSlot(1, 11, 0)
+	b.PrependByteSlot(2, 22, 0)
+	b.PrependInt16Slot(3, 33, 0)
+	obj0 := b.EndObject()
+
+	b.StartObject(4)
+	b.PrependByteSlot(0, 0, 0)
+	b.PrependByteSlot(1, 44, 0)
+	b.PrependByteSlot(2, 55, 0)
+	b.PrependInt16Slot(3, 66, 0)
+	obj1 := b.EndObject()
+
+	b.StartObject(4)
+	b.PrependByteSlot(0, 0, 0)
+	b.PrependByteSlot(1, 77, 0)
+	b.PrependByteSlot(2, 88, 0)
+	b.PrependInt16Slot(3, 99, 0)
+	obj2 := b.EndObject()
+
+	got := b.Bytes[b.Head():]
+
+	want := []byte{
+		240, 255, 255, 255, // == -12. offset to dedupped vtable.
+		99, 0,
+		88,
+		77,
+		248, 255, 255, 255, // == -8. offset to dedupped vtable.
+		66, 0,
+		55,
+		44,
+		12, 0,
+		8, 0,
+		0, 0,
+		7, 0,
+		6, 0,
+		4, 0,
+		12, 0, 0, 0,
+		33, 0,
+		22,
+		11,
+	}
+
+	if !bytes.Equal(want, got) {
+		fail("testVtableDeduplication want:\n%d %v\nbut got:\n%d %v\n",
+			len(want), want, len(got), got)
+	}
+
+	table0 := &flatbuffers.Table{Bytes: b.Bytes, Pos: flatbuffers.UOffsetT(len(b.Bytes)) - obj0}
+	table1 := &flatbuffers.Table{Bytes: b.Bytes, Pos: flatbuffers.UOffsetT(len(b.Bytes)) - obj1}
+	table2 := &flatbuffers.Table{Bytes: b.Bytes, Pos: flatbuffers.UOffsetT(len(b.Bytes)) - obj2}
+
+	testTable := func(tab *flatbuffers.Table, a flatbuffers.VOffsetT, b, c, d byte) {
+		// vtable size
+		if got := tab.GetVOffsetTSlot(0, 0); 12 != got {
+			fail("failed 0, 0: %d", got)
+		}
+		// object size
+		if got := tab.GetVOffsetTSlot(2, 0); 8 != got {
+			fail("failed 2, 0: %d", got)
+		}
+		// default value
+		if got := tab.GetVOffsetTSlot(4, 0); a != got {
+			fail("failed 4, 0: %d", got)
+		}
+		if got := tab.GetByteSlot(6, 0); b != got {
+			fail("failed 6, 0: %d", got)
+		}
+		if val := tab.GetByteSlot(8, 0); c != val {
+			fail("failed 8, 0: %d", got)
+		}
+		if got := tab.GetByteSlot(10, 0); d != got {
+			fail("failed 10, 0: %d", got)
+		}
+	}
+
+	testTable(table0, 0, 11, 22, 33)
+	testTable(table1, 0, 44, 55, 66)
+	testTable(table2, 0, 77, 88, 99)
+}
+
+// CheckNotInObjectError verifies that `EndObject` fails if not inside an
+// object.
+func CheckNotInObjectError(fail func(string, ...interface{})) {
+	b := flatbuffers.NewBuilder(0)
+
+	defer func() {
+		r := recover()
+		if r == nil {
+			fail("expected panic in CheckNotInObjectError")
+		}
+	}()
+	b.EndObject()
+}
+
+// CheckStringIsNestedError verifies that a string can not be created inside
+// another object.
+func CheckStringIsNestedError(fail func(string, ...interface{})) {
+	b := flatbuffers.NewBuilder(0)
+	b.StartObject(0)
+	defer func() {
+		r := recover()
+		if r == nil {
+			fail("expected panic in CheckStringIsNestedError")
+		}
+	}()
+	b.CreateString("foo")
+}
+
+// CheckByteStringIsNestedError verifies that a bytestring can not be created
+// inside another object.
+func CheckByteStringIsNestedError(fail func(string, ...interface{})) {
+	b := flatbuffers.NewBuilder(0)
+	b.StartObject(0)
+	defer func() {
+		r := recover()
+		if r == nil {
+			fail("expected panic in CheckByteStringIsNestedError")
+		}
+	}()
+	b.CreateByteString([]byte("foo"))
+}
+
+// CheckStructIsNotInlineError verifies that writing a struct in a location
+// away from where it is used will cause a panic.
+func CheckStructIsNotInlineError(fail func(string, ...interface{})) {
+	b := flatbuffers.NewBuilder(0)
+	b.StartObject(0)
+	defer func() {
+		r := recover()
+		if r == nil {
+			fail("expected panic in CheckStructIsNotInlineError")
+		}
+	}()
+	b.PrependStructSlot(0, 1, 0)
+}
+
+// CheckFinishedBytesError verifies that `FinishedBytes` panics if the table
+// is not finished.
+func CheckFinishedBytesError(fail func(string, ...interface{})) {
+	b := flatbuffers.NewBuilder(0)
+
+	defer func() {
+		r := recover()
+		if r == nil {
+			fail("expected panic in CheckFinishedBytesError")
+		}
+	}()
+	b.FinishedBytes()
+}
+
+// CheckEnumNames checks that the generated enum names are correct.
+func CheckEnumNames(fail func(string, ...interface{})) {
+	{
+		want := map[example.Any]string{
+			example.AnyNONE:                    "NONE",
+			example.AnyMonster:                 "Monster",
+			example.AnyTestSimpleTableWithEnum: "TestSimpleTableWithEnum",
+			example.AnyMyGame_Example2_Monster: "MyGame_Example2_Monster",
+		}
+		got := example.EnumNamesAny
+		if !reflect.DeepEqual(got, want) {
+			fail("enum name is not equal")
+		}
+	}
+	{
+		want := map[example.Color]string{
+			example.ColorRed:   "Red",
+			example.ColorGreen: "Green",
+			example.ColorBlue:  "Blue",
+		}
+		got := example.EnumNamesColor
+		if !reflect.DeepEqual(got, want) {
+			fail("enum name is not equal")
+		}
+	}
+}
+
+// CheckEnumString checks the String method on generated enum types.
+func CheckEnumString(fail func(string, ...interface{})) {
+	if got := example.AnyMonster.String(); got != "Monster" {
+		fail("Monster.String: %q != %q", got, "Monster")
+	}
+	if got := fmt.Sprintf("color: %s", example.ColorGreen); got != "color: Green" {
+		fail("color.String: %q != %q", got, "color: Green")
+	}
+}
+
+// CheckEnumValues checks that the generated enum values maps are correct.
+func CheckEnumValues(fail func(string, ...interface{})) {
+	{
+		want := map[string]example.Any{
+			"NONE":                    example.AnyNONE,
+			"Monster":                 example.AnyMonster,
+			"TestSimpleTableWithEnum": example.AnyTestSimpleTableWithEnum,
+			"MyGame_Example2_Monster": example.AnyMyGame_Example2_Monster,
+		}
+		got := example.EnumValuesAny
+		if !reflect.DeepEqual(got, want) {
+			fail("enum name is not equal")
+		}
+	}
+	{
+		want := map[string]example.Color{
+			"Red":   example.ColorRed,
+			"Green": example.ColorGreen,
+			"Blue":  example.ColorBlue,
+		}
+		got := example.EnumValuesColor
+		if !reflect.DeepEqual(got, want) {
+			fail("enum name is not equal")
+		}
+	}
+}
+
+// CheckDocExample checks that the code given in FlatBuffers documentation
+// is syntactically correct.
+func CheckDocExample(buf []byte, off flatbuffers.UOffsetT, fail func(string, ...interface{})) {
+	monster := example.GetRootAsMonster(buf, off)
+	_ = monster.Hp()
+	_ = monster.Pos(nil)
+	for i := 0; i < monster.InventoryLength(); i++ {
+		_ = monster.Inventory(i) // do something here
+	}
+
+	builder := flatbuffers.NewBuilder(0)
+
+	example.MonsterStartInventoryVector(builder, 5)
+	for i := 4; i >= 0; i-- {
+		builder.PrependByte(byte(i))
+	}
+	inv := builder.EndVector(5)
+
+	str := builder.CreateString("MyMonster")
+	example.MonsterStart(builder)
+	example.MonsterAddPos(builder, example.CreateVec3(builder, 1.0, 2.0, 3.0, 3.0, example.Color(4), 5, 6))
+	example.MonsterAddHp(builder, 80)
+	example.MonsterAddName(builder, str)
+	example.MonsterAddInventory(builder, inv)
+	example.MonsterAddTestType(builder, 1)
+	example.MonsterAddColor(builder, example.ColorRed)
+	// example.MonsterAddTest(builder, mon2)
+	// example.MonsterAddTest4(builder, test4s)
+	_ = example.MonsterEnd(builder)
+}
+
+func CheckCreateByteVector(fail func(string, ...interface{})) {
+	raw := [30]byte{}
+	for i := 0; i < len(raw); i++ {
+		raw[i] = byte(i)
+	}
+
+	for size := 0; size < len(raw); size++ {
+		b1 := flatbuffers.NewBuilder(0)
+		b2 := flatbuffers.NewBuilder(0)
+		b1.StartVector(1, size, 1)
+		for i := size - 1; i >= 0; i-- {
+			b1.PrependByte(raw[i])
+		}
+		b1.EndVector(size)
+		b2.CreateByteVector(raw[:size])
+		CheckByteEquality(b1.Bytes, b2.Bytes, fail)
+	}
+}
+
+func CheckParentNamespace(fail func(string, ...interface{})) {
+	var empty, nonempty []byte
+
+	// create monster with an empty parent namespace field
+	{
+		builder := flatbuffers.NewBuilder(0)
+
+		example.MonsterStart(builder)
+		m := example.MonsterEnd(builder)
+		builder.Finish(m)
+
+		empty = make([]byte, len(builder.FinishedBytes()))
+		copy(empty, builder.FinishedBytes())
+	}
+
+	// create monster with a non-empty parent namespace field
+	{
+		builder := flatbuffers.NewBuilder(0)
+		mygame.InParentNamespaceStart(builder)
+		pn := mygame.InParentNamespaceEnd(builder)
+
+		example.MonsterStart(builder)
+		example.MonsterAddParentNamespaceTest(builder, pn)
+		m := example.MonsterEnd(builder)
+
+		builder.Finish(m)
+
+		nonempty = make([]byte, len(builder.FinishedBytes()))
+		copy(nonempty, builder.FinishedBytes())
+	}
+
+	// read monster with empty parent namespace field
+	{
+		m := example.GetRootAsMonster(empty, 0)
+		if m.ParentNamespaceTest(nil) != nil {
+			fail("expected nil ParentNamespaceTest for empty field")
+		}
+	}
+
+	// read monster with non-empty parent namespace field
+	{
+		m := example.GetRootAsMonster(nonempty, 0)
+		if m.ParentNamespaceTest(nil) == nil {
+			fail("expected non-nil ParentNamespaceTest for non-empty field")
+		}
+	}
+}
+
+// Include simple random number generator to ensure results will be the
+// same cross platform.
+// http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator
+type LCG uint32
+
+const InitialLCGSeed = 48271
+
+func NewLCG() *LCG {
+	n := uint32(InitialLCGSeed)
+	l := LCG(n)
+	return &l
+}
+
+func (lcg *LCG) Reset() {
+	*lcg = InitialLCGSeed
+}
+
+func (lcg *LCG) Next() uint32 {
+	n := uint32((uint64(*lcg) * uint64(279470273)) % uint64(4294967291))
+	*lcg = LCG(n)
+	return n
+}
+
+// CheckByteEquality verifies that two byte buffers are the same.
+func CheckByteEquality(a, b []byte, fail func(string, ...interface{})) {
+	if !bytes.Equal(a, b) {
+		fail("objects are not byte-wise equal")
+	}
+}
+
+// CheckMutateMethods checks all mutate methods one by one
+func CheckMutateMethods(fail func(string, ...interface{})) {
+	b := flatbuffers.NewBuilder(0)
+	b.StartObject(15)
+	b.PrependBoolSlot(0, true, false)
+	b.PrependByteSlot(1, 1, 0)
+	b.PrependUint8Slot(2, 2, 0)
+	b.PrependUint16Slot(3, 3, 0)
+	b.PrependUint32Slot(4, 4, 0)
+	b.PrependUint64Slot(5, 5, 0)
+	b.PrependInt8Slot(6, 6, 0)
+	b.PrependInt16Slot(7, 7, 0)
+	b.PrependInt32Slot(8, 8, 0)
+	b.PrependInt64Slot(9, 9, 0)
+	b.PrependFloat32Slot(10, 10, 0)
+	b.PrependFloat64Slot(11, 11, 0)
+
+	b.PrependUOffsetTSlot(12, 12, 0)
+	uoVal := b.Offset() - 12
+
+	b.PrependVOffsetT(13)
+	b.Slot(13)
+
+	b.PrependSOffsetT(14)
+	b.Slot(14)
+	soVal := flatbuffers.SOffsetT(b.Offset() - 14)
+
+	offset := b.EndObject()
+
+	t := &flatbuffers.Table{
+		Bytes: b.Bytes,
+		Pos:   flatbuffers.UOffsetT(len(b.Bytes)) - offset,
+	}
+
+	calcVOffsetT := func(slot int) (vtableOffset flatbuffers.VOffsetT) {
+		return flatbuffers.VOffsetT((flatbuffers.VtableMetadataFields + slot) * flatbuffers.SizeVOffsetT)
+	}
+	calcUOffsetT := func(vtableOffset flatbuffers.VOffsetT) (valueOffset flatbuffers.UOffsetT) {
+		return t.Pos + flatbuffers.UOffsetT(t.Offset(vtableOffset))
+	}
+
+	type testcase struct {
+		field  string
+		testfn func() bool
+	}
+
+	testForOriginalValues := []testcase{
+		testcase{"BoolSlot", func() bool { return t.GetBoolSlot(calcVOffsetT(0), true) == true }},
+		testcase{"ByteSlot", func() bool { return t.GetByteSlot(calcVOffsetT(1), 1) == 1 }},
+		testcase{"Uint8Slot", func() bool { return t.GetUint8Slot(calcVOffsetT(2), 2) == 2 }},
+		testcase{"Uint16Slot", func() bool { return t.GetUint16Slot(calcVOffsetT(3), 3) == 3 }},
+		testcase{"Uint32Slot", func() bool { return t.GetUint32Slot(calcVOffsetT(4), 4) == 4 }},
+		testcase{"Uint64Slot", func() bool { return t.GetUint64Slot(calcVOffsetT(5), 5) == 5 }},
+		testcase{"Int8Slot", func() bool { return t.GetInt8Slot(calcVOffsetT(6), 6) == 6 }},
+		testcase{"Int16Slot", func() bool { return t.GetInt16Slot(calcVOffsetT(7), 7) == 7 }},
+		testcase{"Int32Slot", func() bool { return t.GetInt32Slot(calcVOffsetT(8), 8) == 8 }},
+		testcase{"Int64Slot", func() bool { return t.GetInt64Slot(calcVOffsetT(9), 9) == 9 }},
+		testcase{"Float32Slot", func() bool { return t.GetFloat32Slot(calcVOffsetT(10), 10) == 10 }},
+		testcase{"Float64Slot", func() bool { return t.GetFloat64Slot(calcVOffsetT(11), 11) == 11 }},
+		testcase{"UOffsetTSlot", func() bool { return t.GetUOffsetT(calcUOffsetT(calcVOffsetT(12))) == uoVal }},
+		testcase{"VOffsetTSlot", func() bool { return t.GetVOffsetT(calcUOffsetT(calcVOffsetT(13))) == 13 }},
+		testcase{"SOffsetTSlot", func() bool { return t.GetSOffsetT(calcUOffsetT(calcVOffsetT(14))) == soVal }},
+	}
+
+	testMutability := []testcase{
+		testcase{"BoolSlot", func() bool { return t.MutateBoolSlot(calcVOffsetT(0), false) }},
+		testcase{"ByteSlot", func() bool { return t.MutateByteSlot(calcVOffsetT(1), 2) }},
+		testcase{"Uint8Slot", func() bool { return t.MutateUint8Slot(calcVOffsetT(2), 4) }},
+		testcase{"Uint16Slot", func() bool { return t.MutateUint16Slot(calcVOffsetT(3), 6) }},
+		testcase{"Uint32Slot", func() bool { return t.MutateUint32Slot(calcVOffsetT(4), 8) }},
+		testcase{"Uint64Slot", func() bool { return t.MutateUint64Slot(calcVOffsetT(5), 10) }},
+		testcase{"Int8Slot", func() bool { return t.MutateInt8Slot(calcVOffsetT(6), 12) }},
+		testcase{"Int16Slot", func() bool { return t.MutateInt16Slot(calcVOffsetT(7), 14) }},
+		testcase{"Int32Slot", func() bool { return t.MutateInt32Slot(calcVOffsetT(8), 16) }},
+		testcase{"Int64Slot", func() bool { return t.MutateInt64Slot(calcVOffsetT(9), 18) }},
+		testcase{"Float32Slot", func() bool { return t.MutateFloat32Slot(calcVOffsetT(10), 20) }},
+		testcase{"Float64Slot", func() bool { return t.MutateFloat64Slot(calcVOffsetT(11), 22) }},
+		testcase{"UOffsetTSlot", func() bool { return t.MutateUOffsetT(calcUOffsetT(calcVOffsetT(12)), 24) }},
+		testcase{"VOffsetTSlot", func() bool { return t.MutateVOffsetT(calcUOffsetT(calcVOffsetT(13)), 26) }},
+		testcase{"SOffsetTSlot", func() bool { return t.MutateSOffsetT(calcUOffsetT(calcVOffsetT(14)), 28) }},
+	}
+
+	testMutabilityWithoutSlot := []testcase{
+		testcase{"BoolSlot", func() bool { return t.MutateBoolSlot(calcVOffsetT(16), false) }},
+		testcase{"ByteSlot", func() bool { return t.MutateByteSlot(calcVOffsetT(16), 2) }},
+		testcase{"Uint8Slot", func() bool { return t.MutateUint8Slot(calcVOffsetT(16), 2) }},
+		testcase{"Uint16Slot", func() bool { return t.MutateUint16Slot(calcVOffsetT(16), 2) }},
+		testcase{"Uint32Slot", func() bool { return t.MutateUint32Slot(calcVOffsetT(16), 2) }},
+		testcase{"Uint64Slot", func() bool { return t.MutateUint64Slot(calcVOffsetT(16), 2) }},
+		testcase{"Int8Slot", func() bool { return t.MutateInt8Slot(calcVOffsetT(16), 2) }},
+		testcase{"Int16Slot", func() bool { return t.MutateInt16Slot(calcVOffsetT(16), 2) }},
+		testcase{"Int32Slot", func() bool { return t.MutateInt32Slot(calcVOffsetT(16), 2) }},
+		testcase{"Int64Slot", func() bool { return t.MutateInt64Slot(calcVOffsetT(16), 2) }},
+		testcase{"Float32Slot", func() bool { return t.MutateFloat32Slot(calcVOffsetT(16), 2) }},
+		testcase{"Float64Slot", func() bool { return t.MutateFloat64Slot(calcVOffsetT(16), 2) }},
+	}
+
+	testForMutatedValues := []testcase{
+		testcase{"BoolSlot", func() bool { return t.GetBoolSlot(calcVOffsetT(0), true) == false }},
+		testcase{"ByteSlot", func() bool { return t.GetByteSlot(calcVOffsetT(1), 1) == 2 }},
+		testcase{"Uint8Slot", func() bool { return t.GetUint8Slot(calcVOffsetT(2), 1) == 4 }},
+		testcase{"Uint16Slot", func() bool { return t.GetUint16Slot(calcVOffsetT(3), 1) == 6 }},
+		testcase{"Uint32Slot", func() bool { return t.GetUint32Slot(calcVOffsetT(4), 1) == 8 }},
+		testcase{"Uint64Slot", func() bool { return t.GetUint64Slot(calcVOffsetT(5), 1) == 10 }},
+		testcase{"Int8Slot", func() bool { return t.GetInt8Slot(calcVOffsetT(6), 1) == 12 }},
+		testcase{"Int16Slot", func() bool { return t.GetInt16Slot(calcVOffsetT(7), 1) == 14 }},
+		testcase{"Int32Slot", func() bool { return t.GetInt32Slot(calcVOffsetT(8), 1) == 16 }},
+		testcase{"Int64Slot", func() bool { return t.GetInt64Slot(calcVOffsetT(9), 1) == 18 }},
+		testcase{"Float32Slot", func() bool { return t.GetFloat32Slot(calcVOffsetT(10), 1) == 20 }},
+		testcase{"Float64Slot", func() bool { return t.GetFloat64Slot(calcVOffsetT(11), 1) == 22 }},
+		testcase{"UOffsetTSlot", func() bool { return t.GetUOffsetT(calcUOffsetT(calcVOffsetT(12))) == 24 }},
+		testcase{"VOffsetTSlot", func() bool { return t.GetVOffsetT(calcUOffsetT(calcVOffsetT(13))) == 26 }},
+		testcase{"SOffsetTSlot", func() bool { return t.GetSOffsetT(calcUOffsetT(calcVOffsetT(14))) == 28 }},
+	}
+
+	// make sure original values are okay
+	for _, t := range testForOriginalValues {
+		if !t.testfn() {
+			fail(t.field + "' field doesn't have the expected original value")
+		}
+	}
+
+	// try to mutate fields and check mutability
+	for _, t := range testMutability {
+		if !t.testfn() {
+			fail(FailString(t.field+"' field failed mutability test", "passed", "failed"))
+		}
+	}
+
+	// try to mutate fields and check mutability
+	// these have wrong slots so should fail
+	for _, t := range testMutabilityWithoutSlot {
+		if t.testfn() {
+			fail(FailString(t.field+"' field failed no slot mutability test", "failed", "passed"))
+		}
+	}
+
+	// test whether values have changed
+	for _, t := range testForMutatedValues {
+		if !t.testfn() {
+			fail(t.field + "' field doesn't have the expected mutated value")
+		}
+	}
+}
+
+// BenchmarkVtableDeduplication measures the speed of vtable deduplication
+// by creating prePop vtables, then populating b.N objects with a
+// different single vtable.
+//
+// When b.N is large (as in long benchmarks), memory usage may be high.
+func BenchmarkVtableDeduplication(b *testing.B) {
+	prePop := 10
+	builder := flatbuffers.NewBuilder(0)
+
+	// pre-populate some vtables:
+	for i := 0; i < prePop; i++ {
+		builder.StartObject(i)
+		for j := 0; j < i; j++ {
+			builder.PrependInt16Slot(j, int16(j), 0)
+		}
+		builder.EndObject()
+	}
+
+	// benchmark deduplication of a new vtable:
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		lim := prePop
+
+		builder.StartObject(lim)
+		for j := 0; j < lim; j++ {
+			builder.PrependInt16Slot(j, int16(j), 0)
+		}
+		builder.EndObject()
+	}
+}
+
+// BenchmarkParseGold measures the speed of parsing the 'gold' data
+// used throughout this test suite.
+func BenchmarkParseGold(b *testing.B) {
+	buf, offset := CheckGeneratedBuild(b.Fatalf)
+	monster := example.GetRootAsMonster(buf, offset)
+
+	// use these to prevent allocations:
+	reuse_pos := example.Vec3{}
+	reuse_test3 := example.Test{}
+	reuse_table2 := flatbuffers.Table{}
+	reuse_monster2 := example.Monster{}
+	reuse_test4_0 := example.Test{}
+	reuse_test4_1 := example.Test{}
+
+	b.SetBytes(int64(len(buf[offset:])))
+	b.ReportAllocs()
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		monster.Hp()
+		monster.Mana()
+		name := monster.Name()
+		_ = name[0]
+		_ = name[len(name)-1]
+
+		monster.Pos(&reuse_pos)
+		reuse_pos.X()
+		reuse_pos.Y()
+		reuse_pos.Z()
+		reuse_pos.Test1()
+		reuse_pos.Test2()
+		reuse_pos.Test3(&reuse_test3)
+		reuse_test3.A()
+		reuse_test3.B()
+		monster.TestType()
+		monster.Test(&reuse_table2)
+		reuse_monster2.Init(reuse_table2.Bytes, reuse_table2.Pos)
+		name2 := reuse_monster2.Name()
+		_ = name2[0]
+		_ = name2[len(name2)-1]
+		monster.InventoryLength()
+		l := monster.InventoryLength()
+		for i := 0; i < l; i++ {
+			monster.Inventory(i)
+		}
+		monster.Test4Length()
+		monster.Test4(&reuse_test4_0, 0)
+		monster.Test4(&reuse_test4_1, 1)
+
+		reuse_test4_0.A()
+		reuse_test4_0.B()
+		reuse_test4_1.A()
+		reuse_test4_1.B()
+
+		monster.TestarrayofstringLength()
+		str0 := monster.Testarrayofstring(0)
+		_ = str0[0]
+		_ = str0[len(str0)-1]
+		str1 := monster.Testarrayofstring(1)
+		_ = str1[0]
+		_ = str1[len(str1)-1]
+	}
+}
+
+// BenchmarkBuildGold uses generated code to build the example Monster.
+func BenchmarkBuildGold(b *testing.B) {
+	buf, offset := CheckGeneratedBuild(b.Fatalf)
+	bytes_length := int64(len(buf[offset:]))
+
+	reuse_str := "MyMonster"
+	reuse_test1 := "test1"
+	reuse_test2 := "test2"
+	reuse_fred := "Fred"
+
+	b.SetBytes(bytes_length)
+	bldr := flatbuffers.NewBuilder(0)
+	b.ResetTimer()
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		bldr.Reset()
+
+		str := bldr.CreateString(reuse_str)
+		test1 := bldr.CreateString(reuse_test1)
+		test2 := bldr.CreateString(reuse_test2)
+		fred := bldr.CreateString(reuse_fred)
+
+		example.MonsterStartInventoryVector(bldr, 5)
+		bldr.PrependByte(4)
+		bldr.PrependByte(3)
+		bldr.PrependByte(2)
+		bldr.PrependByte(1)
+		bldr.PrependByte(0)
+		inv := bldr.EndVector(5)
+
+		example.MonsterStart(bldr)
+		example.MonsterAddName(bldr, fred)
+		mon2 := example.MonsterEnd(bldr)
+
+		example.MonsterStartTest4Vector(bldr, 2)
+		example.CreateTest(bldr, 10, 20)
+		example.CreateTest(bldr, 30, 40)
+		test4 := bldr.EndVector(2)
+
+		example.MonsterStartTestarrayofstringVector(bldr, 2)
+		bldr.PrependUOffsetT(test2)
+		bldr.PrependUOffsetT(test1)
+		testArrayOfString := bldr.EndVector(2)
+
+		example.MonsterStart(bldr)
+
+		pos := example.CreateVec3(bldr, 1.0, 2.0, 3.0, 3.0, example.ColorGreen, 5, 6)
+		example.MonsterAddPos(bldr, pos)
+
+		example.MonsterAddHp(bldr, 80)
+		example.MonsterAddName(bldr, str)
+		example.MonsterAddInventory(bldr, inv)
+		example.MonsterAddTestType(bldr, 1)
+		example.MonsterAddTest(bldr, mon2)
+		example.MonsterAddTest4(bldr, test4)
+		example.MonsterAddTestarrayofstring(bldr, testArrayOfString)
+		mon := example.MonsterEnd(bldr)
+
+		bldr.Finish(mon)
+	}
+}
diff --git a/third_party/flatbuffers/tests/include_test/include_test1.fbs b/third_party/flatbuffers/tests/include_test/include_test1.fbs
new file mode 100644
index 0000000..804856a
--- /dev/null
+++ b/third_party/flatbuffers/tests/include_test/include_test1.fbs
@@ -0,0 +1,7 @@
+include "sub/include_test2.fbs";
+include "sub/include_test2.fbs";  // should be skipped
+include "include_test1.fbs";  // should be skipped
+
+table TableA {
+  b:MyGame.OtherNameSpace.TableB;
+}
diff --git a/third_party/flatbuffers/tests/include_test/sub/include_test2.fbs b/third_party/flatbuffers/tests/include_test/sub/include_test2.fbs
new file mode 100644
index 0000000..7225735
--- /dev/null
+++ b/third_party/flatbuffers/tests/include_test/sub/include_test2.fbs
@@ -0,0 +1,12 @@
+include "include_test1.fbs";
+include "sub/include_test2.fbs";    // should be skipped
+
+namespace MyGame.OtherNameSpace;
+
+enum FromInclude:long { IncludeVal }
+
+struct Unused { a:int; }
+
+table TableB {
+  a:TableA;
+}
diff --git a/third_party/flatbuffers/tests/javatest.bin b/third_party/flatbuffers/tests/javatest.bin
new file mode 100644
index 0000000..804dbba
--- /dev/null
+++ b/third_party/flatbuffers/tests/javatest.bin
Binary files differ
diff --git a/third_party/flatbuffers/tests/lobstertest.lobster b/third_party/flatbuffers/tests/lobstertest.lobster
new file mode 100644
index 0000000..7ea9b38
--- /dev/null
+++ b/third_party/flatbuffers/tests/lobstertest.lobster
@@ -0,0 +1,137 @@
+// 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.
+
+import from "../lobster/"
+import monster_test_generated
+
+def check_read_buffer(buf):
+    // CheckReadBuffer checks that the given buffer is evaluated correctly as the example Monster.
+    let monster = MyGame_Example_GetRootAsMonster(buf)
+
+    assert monster.hp == 80
+    assert monster.mana == 150
+    assert monster.name == "MyMonster"
+
+    let vec = monster.pos
+    assert vec
+    assert vec.x == 1.0
+    assert vec.y == 2.0
+    assert vec.z == 3.0
+    assert vec.test1 == 3.0
+    assert vec.test2 == 2
+
+    let t = vec.test3
+    assert t
+    assert t.a == 5
+    assert t.b == 6
+
+    assert monster.test_type == MyGame_Example_Any_Monster
+    assert monster.test_as_Monster.name == "Fred"
+
+    assert monster.inventory_length == 5
+    assert sum(map(monster.inventory_length) i: monster.inventory(i)) == 10
+
+    for(5) i:
+        assert monster.vector_of_longs(i) == pow(10, i * 2)
+
+    assert equal([-1.7976931348623157e+308, 0, 1.7976931348623157e+308],
+                 (map(monster.vector_of_doubles_length) i: monster.vector_of_doubles(i)))
+
+    assert monster.test4_length == 2
+    let test0 = monster.test4(0)
+    let test1 = monster.test4(1)
+    assert test0.a + test0.b + test1.a + test1.b == 100
+
+    assert monster.testarrayofstring_length == 2
+    assert monster.testarrayofstring(0) == "test1"
+    assert monster.testarrayofstring(1) == "test2"
+
+    assert monster.testarrayoftables_length == 0
+    assert monster.testnestedflatbuffer_length == 0
+    assert not monster.testempty()
+
+def make_monster_from_generated_code():
+    // Use generated code to build the example Monster.
+    let b = flatbuffers_builder {}
+
+    let name = b.CreateString("MyMonster")
+    let fred = b.CreateString("Fred")
+
+    let inv = b.MyGame_Example_MonsterCreateInventoryVector([ 0, 1, 2, 3, 4 ])
+
+    let mon2 = MyGame_Example_MonsterBuilder { b }
+        .start()
+        .add_name(fred)
+        .end()
+
+    b.MyGame_Example_MonsterStartTest4Vector(2)
+    b.MyGame_Example_CreateTest(10, 20)
+    b.MyGame_Example_CreateTest(30, 40)
+    let test4 = b.EndVector(2)
+
+    let test_array_of_string = b.MyGame_Example_MonsterCreateTestarrayofstringVector(
+                                   [ b.CreateString("test1"), b.CreateString("test2") ])
+
+    let vector_of_longs = b.MyGame_Example_MonsterCreateVectorOfLongsVector(
+                              [ 1, 100, 10000, 1000000, 100000000 ])
+
+    let vector_of_doubles = b.MyGame_Example_MonsterCreateVectorOfDoublesVector(
+                                [ -1.7976931348623157e+308, 0, 1.7976931348623157e+308 ])
+
+    let mon = MyGame_Example_MonsterBuilder { b }
+        .start()
+        .add_pos(b.MyGame_Example_CreateVec3(1.0, 2.0, 3.0, 3.0,
+                 MyGame_Example_Color_Green, 5, 6))
+        .add_hp(80)
+        .add_name(name)
+        .add_inventory(inv)
+        .add_test_type(MyGame_Example_Any_Monster)
+        .add_test(mon2)
+        .add_test4(test4)
+        .add_testarrayofstring(test_array_of_string)
+        .add_vector_of_longs(vector_of_longs)
+        .add_vector_of_doubles(vector_of_doubles)
+        .end()
+
+    b.Finish(mon)
+
+    return b.SizedCopy()
+
+// Verify that the canonical flatbuffer file (produced by the C++ implementation)
+// is readable by the generated Lobster code.
+let fb2 = read_file("monsterdata_test.mon")
+assert fb2
+check_read_buffer(fb2)
+
+// Verify that using the generated Lobster code builds a buffer without
+// returning errors, and is interpreted correctly.
+let fb1 = make_monster_from_generated_code()
+check_read_buffer(fb1)
+// Write the result to file for no good reason.
+write_file("monsterdata_lobster_wire.mon", fb1)
+
+// Test converting the buffer to JSON and parsing the JSON back again.
+let schema = read_file("monster_test.fbs")
+assert schema
+let includedirs = [ "include_test" ]
+// Convert binary to JSON:
+let json, err1 = flatbuffers_binary_to_json(schema, fb1, includedirs)
+assert not err1
+// Parse JSON back to binary:
+let fb3, err2 = flatbuffers_json_to_binary(schema, json, includedirs)
+assert not err2
+// Check the resulting binary again (full roundtrip test):
+check_read_buffer(fb3)
+
+print "Lobster test succesful!"
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/luatest.lua b/third_party/flatbuffers/tests/luatest.lua
new file mode 100644
index 0000000..c85a4ec
--- /dev/null
+++ b/third_party/flatbuffers/tests/luatest.lua
@@ -0,0 +1,296 @@
+package.path = string.format("../lua/?.lua;./?.lua;%s",package.path)
+
+local function checkReadBuffer(buf, offset, sizePrefix)
+    offset = offset or 0
+    
+    if type(buf) == "string" then
+        buf = flatbuffers.binaryArray.New(buf)
+    end
+    
+    if sizePrefix then               
+        local size = flatbuffers.N.Int32:Unpack(buf, offset)
+        assert(size == #buf - offset - 4)
+        offset = offset + flatbuffers.N.Int32.bytewidth
+    end    
+    
+    local mon = monster.GetRootAsMonster(buf, offset)
+    assert(mon:Hp() == 80, "Monster Hp is not 80")
+    assert(mon:Mana() == 150, "Monster Mana is not 150")
+    assert(mon:Name() == "MyMonster", "Monster Name is not MyMonster")
+    
+    local vec = assert(mon:Pos(), "Monster Position is nil")
+    assert(vec:X() == 1.0)
+    assert(vec:Y() == 2.0)
+    assert(vec:Z() == 3.0)
+    assert(vec:Test1() == 3.0)
+    assert(vec:Test2() == 2)
+    
+    local t = require("MyGame.Example.Test").New()
+    t = assert(vec:Test3(t))
+    
+    assert(t:A() == 5)
+    assert(t:B() == 6)
+    
+    local ut = require("MyGame.Example.Any")
+    assert(mon:TestType() == ut.Monster)
+    
+    local table2 = mon:Test()
+    assert(getmetatable(table2) == "flatbuffers.view.mt")
+    
+    local mon2 = monster.New()
+    mon2:Init(table2.bytes, table2.pos)
+    
+    assert(mon2:Name() == "Fred")
+    
+    assert(mon:InventoryLength() == 5)
+    local invsum = 0
+    for i=1,mon:InventoryLength() do
+        local v = mon:Inventory(i)
+        invsum = invsum + v
+    end
+    assert(invsum == 10)
+    
+    for i=1,5 do
+        assert(mon:VectorOfLongs(i) == 10^((i-1)*2))
+    end
+    
+    local dbls = { -1.7976931348623157e+308, 0, 1.7976931348623157e+308}
+    for i=1,mon:VectorOfDoublesLength() do
+        assert(mon:VectorOfDoubles(i) == dbls[i])
+    end
+    
+    assert(mon:Test4Length() == 2)
+    
+    local test0 = mon:Test4(1)
+    local test1 = mon:Test4(2)
+    
+    local v0 = test0:A()
+    local v1 = test0:B()
+    local v2 = test1:A()
+    local v3 = test1:B()
+    
+    local sumtest12 = v0 + v1 + v2 + v3
+    assert(sumtest12 == 100)
+    
+    assert(mon:TestarrayofstringLength() == 2)
+    assert(mon:Testarrayofstring(1) == "test1")
+    assert(mon:Testarrayofstring(2) == "test2")
+    
+    assert(mon:TestarrayoftablesLength() == 0)
+    assert(mon:TestnestedflatbufferLength() == 0)
+    assert(mon:Testempty() == nil)
+end
+
+local function generateMonster(sizePrefix)
+    local b = flatbuffers.Builder(0)
+    local str = b:CreateString("MyMonster")
+    local test1 = b:CreateString("test1")
+    local test2 = b:CreateString("test2")
+    local fred = b:CreateString("Fred")
+    
+    monster.StartInventoryVector(b, 5)
+    b:PrependByte(4)
+    b:PrependByte(3)
+    b:PrependByte(2)
+    b:PrependByte(1)
+    b:PrependByte(0)
+    local inv = b:EndVector(5)
+    
+    monster.Start(b)
+    monster.AddName(b, fred)
+    local mon2 = monster.End(b)
+    
+    monster.StartTest4Vector(b, 2)
+    test.CreateTest(b, 10, 20)
+    test.CreateTest(b, 30, 40)
+    local test4 = b:EndVector(2)
+    
+    monster.StartTestarrayofstringVector(b, 2)
+    b:PrependUOffsetTRelative(test2)
+    b:PrependUOffsetTRelative(test1)
+    local testArrayOfString = b:EndVector(2)
+    
+    monster.StartVectorOfLongsVector(b, 5)
+    b:PrependInt64(100000000)
+    b:PrependInt64(1000000)
+    b:PrependInt64(10000)
+    b:PrependInt64(100)
+    b:PrependInt64(1)
+    local vectorOfLongs = b:EndVector(5)
+    
+    monster.StartVectorOfDoublesVector(b, 3)
+    b:PrependFloat64(1.7976931348623157e+308)
+    b:PrependFloat64(0)
+    b:PrependFloat64(-1.7976931348623157e+308)
+    local vectorOfDoubles = b:EndVector(3)
+    
+    monster.Start(b)
+    local pos = vec3.CreateVec3(b, 1.0, 2.0, 3.0, 3.0, 2, 5, 6)
+    monster.AddPos(b, pos)
+    
+    monster.AddHp(b, 80)
+    monster.AddName(b, str)
+    monster.AddInventory(b, inv)
+    monster.AddTestType(b, 1)
+    monster.AddTest(b, mon2)
+    monster.AddTest4(b, test4)
+    monster.AddTestbool(b, true)
+    monster.AddTestbool(b, false)
+    monster.AddTestbool(b, null)
+    monster.AddTestbool(b,"true")
+    monster.AddTestarrayofstring(b, testArrayOfString)
+    monster.AddVectorOfLongs(b, vectorOfLongs)
+    monster.AddVectorOfDoubles(b, vectorOfDoubles)
+    local mon = monster.End(b)
+    
+    if sizePrefix then
+        b:FinishSizePrefixed(mon)
+    else
+        b:Finish(mon)
+    end
+    return b:Output(true), b:Head()
+end
+
+local function sizePrefix(sizePrefix)
+    local buf,offset = generateMonster(sizePrefix)
+    checkReadBuffer(buf, offset, sizePrefix)
+end
+
+local function testCanonicalData()
+    local f = assert(io.open('monsterdata_test.mon', 'rb'))
+    local wireData = f:read("*a")
+    f:close()    
+    checkReadBuffer(wireData)  
+end    
+    
+local function benchmarkMakeMonster(count)
+    local length = #(generateMonster())
+    
+    --require("flatbuffers.profiler")
+    --profiler = newProfiler("call")
+    --profiler:start()
+    
+    local s = os.clock()
+    for i=1,count do
+        generateMonster()
+    end
+    local e = os.clock()    
+    
+    --profiler:stop()
+
+    --local outfile = io.open( "profile.txt", "w+" )
+    --profiler:report( outfile, true)
+    --outfile:close()
+    
+    
+    local dur = (e - s)
+    local rate = count / (dur * 1000)
+    local data = (length * count) / (1024 * 1024)
+    local dataRate = data / dur
+    
+    print(string.format('built %d %d-byte flatbuffers in %.2fsec: %.2f/msec, %.2fMB/sec',
+        count, length, dur, rate, dataRate))
+end
+
+local function benchmarkReadBuffer(count)
+    local f = assert(io.open('monsterdata_test.mon', 'rb'))
+    local buf = f:read("*a")
+    f:close()    
+        
+    local s = os.clock()
+    for i=1,count do
+        checkReadBuffer(buf)
+    end
+    local e = os.clock()
+        
+    local dur = (e - s)
+    local rate = count / (dur * 1000)
+    local data = (#buf * count) / (1024 * 1024)
+    local dataRate = data / dur
+    
+    print(string.format('traversed %d %d-byte flatbuffers in %.2fsec: %.2f/msec, %.2fMB/sec',
+        count, #buf, dur, rate, dataRate))
+end
+    
+local tests = 
+{ 
+    {   
+        f = sizePrefix, 
+        d = "Test size prefix",
+        args = {{true}, {false}}
+    },
+    {   
+        f = testCanonicalData, 
+        d = "Tests Canonical flatbuffer file included in repo"       
+    },
+    {
+        f = benchmarkMakeMonster,
+        d = "Benchmark making monsters",
+        args = {
+            {100}, 
+            {1000},
+            {10000},
+        }
+    },   
+    {
+        f = benchmarkReadBuffer,
+        d = "Benchmark reading monsters",
+        args = {
+            {100}, 
+            {1000},
+            {10000},
+            -- uncomment following to run 1 million to compare. 
+            -- Took ~141 seconds on my machine
+            --{1000000}, 
+        }
+    }, 
+}
+
+local result, err = xpcall(function()
+    flatbuffers = assert(require("flatbuffers"))
+    monster = assert(require("MyGame.Example.Monster"))  
+    test = assert(require("MyGame.Example.Test"))
+    vec3 = assert(require("MyGame.Example.Vec3"))
+    
+    local function buildArgList(tbl)
+        local s = ""
+        for _,item in ipairs(tbl) do
+            s = s .. tostring(item) .. ","          
+        end
+        return s:sub(1,-2)
+    end
+    
+    local testsPassed, testsFailed = 0,0
+    for _,test in ipairs(tests) do
+        local allargs = test.args or {{}}
+        for _,args in ipairs(allargs) do
+            local results, err = xpcall(test.f,debug.traceback, table.unpack(args))        
+            if results then
+                testsPassed = testsPassed + 1
+            else
+                testsFailed = testsFailed + 1
+                print(string.format(" Test [%s](%s) failed: \n\t%s", 
+                        test.d or "", 
+                        buildArgList(args),
+                        err)) 
+            end
+        end
+    end
+    
+    local totalTests = testsPassed + testsFailed
+    print(string.format("# of test passed: %d / %d (%.2f%%)",
+        testsPassed, 
+        totalTests, 
+        totalTests ~= 0 
+            and 100 * (testsPassed / totalTests) 
+            or 0)
+        )
+    
+    return 0
+end, debug.traceback)
+
+if not result then
+    print("Unable to run tests due to test framework error: ",err)
+end
+
+os.exit(result or -1)
diff --git a/third_party/flatbuffers/tests/monster_extra.fbs b/third_party/flatbuffers/tests/monster_extra.fbs
new file mode 100644
index 0000000..d0fc7fe
--- /dev/null
+++ b/third_party/flatbuffers/tests/monster_extra.fbs
@@ -0,0 +1,21 @@
+namespace MyGame;
+
+// Not all programming languages support this extra table.
+table MonsterExtra {
+  // Float-point values with NaN and Inf defaults.
+  d0:double = nan;
+  d1:double = -nan; // parser must ignore sign of NaN
+  d2:double = +inf;
+  d3:double = -inf;
+  f0:float = -nan; // parser must ignore sign of NaN
+  f1:float = +nan;
+  f2:float = +inf;
+  f3:float = -inf;
+  dvec : [double];
+  fvec : [float];
+}
+
+root_type MonsterExtra;
+
+file_identifier "MONE";
+file_extension "mon";
diff --git a/third_party/flatbuffers/tests/monster_extra_generated.h b/third_party/flatbuffers/tests/monster_extra_generated.h
new file mode 100644
index 0000000..d7ff900
--- /dev/null
+++ b/third_party/flatbuffers/tests/monster_extra_generated.h
@@ -0,0 +1,406 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_MONSTEREXTRA_MYGAME_H_
+#define FLATBUFFERS_GENERATED_MONSTEREXTRA_MYGAME_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+namespace MyGame {
+
+struct MonsterExtra;
+struct MonsterExtraT;
+
+bool operator==(const MonsterExtraT &lhs, const MonsterExtraT &rhs);
+bool operator!=(const MonsterExtraT &lhs, const MonsterExtraT &rhs);
+
+inline const flatbuffers::TypeTable *MonsterExtraTypeTable();
+
+struct MonsterExtraT : public flatbuffers::NativeTable {
+  typedef MonsterExtra TableType;
+  double d0;
+  double d1;
+  double d2;
+  double d3;
+  float f0;
+  float f1;
+  float f2;
+  float f3;
+  std::vector<double> dvec;
+  std::vector<float> fvec;
+  MonsterExtraT()
+      : d0(std::numeric_limits<double>::quiet_NaN()),
+        d1(std::numeric_limits<double>::quiet_NaN()),
+        d2(std::numeric_limits<double>::infinity()),
+        d3(-std::numeric_limits<double>::infinity()),
+        f0(std::numeric_limits<float>::quiet_NaN()),
+        f1(std::numeric_limits<float>::quiet_NaN()),
+        f2(std::numeric_limits<float>::infinity()),
+        f3(-std::numeric_limits<float>::infinity()) {
+  }
+};
+
+inline bool operator==(const MonsterExtraT &lhs, const MonsterExtraT &rhs) {
+  return
+      (lhs.d0 == rhs.d0) &&
+      (lhs.d1 == rhs.d1) &&
+      (lhs.d2 == rhs.d2) &&
+      (lhs.d3 == rhs.d3) &&
+      (lhs.f0 == rhs.f0) &&
+      (lhs.f1 == rhs.f1) &&
+      (lhs.f2 == rhs.f2) &&
+      (lhs.f3 == rhs.f3) &&
+      (lhs.dvec == rhs.dvec) &&
+      (lhs.fvec == rhs.fvec);
+}
+
+inline bool operator!=(const MonsterExtraT &lhs, const MonsterExtraT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct MonsterExtra FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef MonsterExtraT NativeTableType;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return MonsterExtraTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_D0 = 4,
+    VT_D1 = 6,
+    VT_D2 = 8,
+    VT_D3 = 10,
+    VT_F0 = 12,
+    VT_F1 = 14,
+    VT_F2 = 16,
+    VT_F3 = 18,
+    VT_DVEC = 20,
+    VT_FVEC = 22
+  };
+  double d0() const {
+    return GetField<double>(VT_D0, std::numeric_limits<double>::quiet_NaN());
+  }
+  bool mutate_d0(double _d0) {
+    return SetField<double>(VT_D0, _d0, std::numeric_limits<double>::quiet_NaN());
+  }
+  double d1() const {
+    return GetField<double>(VT_D1, std::numeric_limits<double>::quiet_NaN());
+  }
+  bool mutate_d1(double _d1) {
+    return SetField<double>(VT_D1, _d1, std::numeric_limits<double>::quiet_NaN());
+  }
+  double d2() const {
+    return GetField<double>(VT_D2, std::numeric_limits<double>::infinity());
+  }
+  bool mutate_d2(double _d2) {
+    return SetField<double>(VT_D2, _d2, std::numeric_limits<double>::infinity());
+  }
+  double d3() const {
+    return GetField<double>(VT_D3, -std::numeric_limits<double>::infinity());
+  }
+  bool mutate_d3(double _d3) {
+    return SetField<double>(VT_D3, _d3, -std::numeric_limits<double>::infinity());
+  }
+  float f0() const {
+    return GetField<float>(VT_F0, std::numeric_limits<float>::quiet_NaN());
+  }
+  bool mutate_f0(float _f0) {
+    return SetField<float>(VT_F0, _f0, std::numeric_limits<float>::quiet_NaN());
+  }
+  float f1() const {
+    return GetField<float>(VT_F1, std::numeric_limits<float>::quiet_NaN());
+  }
+  bool mutate_f1(float _f1) {
+    return SetField<float>(VT_F1, _f1, std::numeric_limits<float>::quiet_NaN());
+  }
+  float f2() const {
+    return GetField<float>(VT_F2, std::numeric_limits<float>::infinity());
+  }
+  bool mutate_f2(float _f2) {
+    return SetField<float>(VT_F2, _f2, std::numeric_limits<float>::infinity());
+  }
+  float f3() const {
+    return GetField<float>(VT_F3, -std::numeric_limits<float>::infinity());
+  }
+  bool mutate_f3(float _f3) {
+    return SetField<float>(VT_F3, _f3, -std::numeric_limits<float>::infinity());
+  }
+  const flatbuffers::Vector<double> *dvec() const {
+    return GetPointer<const flatbuffers::Vector<double> *>(VT_DVEC);
+  }
+  flatbuffers::Vector<double> *mutable_dvec() {
+    return GetPointer<flatbuffers::Vector<double> *>(VT_DVEC);
+  }
+  const flatbuffers::Vector<float> *fvec() const {
+    return GetPointer<const flatbuffers::Vector<float> *>(VT_FVEC);
+  }
+  flatbuffers::Vector<float> *mutable_fvec() {
+    return GetPointer<flatbuffers::Vector<float> *>(VT_FVEC);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<double>(verifier, VT_D0) &&
+           VerifyField<double>(verifier, VT_D1) &&
+           VerifyField<double>(verifier, VT_D2) &&
+           VerifyField<double>(verifier, VT_D3) &&
+           VerifyField<float>(verifier, VT_F0) &&
+           VerifyField<float>(verifier, VT_F1) &&
+           VerifyField<float>(verifier, VT_F2) &&
+           VerifyField<float>(verifier, VT_F3) &&
+           VerifyOffset(verifier, VT_DVEC) &&
+           verifier.VerifyVector(dvec()) &&
+           VerifyOffset(verifier, VT_FVEC) &&
+           verifier.VerifyVector(fvec()) &&
+           verifier.EndTable();
+  }
+  MonsterExtraT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(MonsterExtraT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<MonsterExtra> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterExtraT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct MonsterExtraBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_d0(double d0) {
+    fbb_.AddElement<double>(MonsterExtra::VT_D0, d0, std::numeric_limits<double>::quiet_NaN());
+  }
+  void add_d1(double d1) {
+    fbb_.AddElement<double>(MonsterExtra::VT_D1, d1, std::numeric_limits<double>::quiet_NaN());
+  }
+  void add_d2(double d2) {
+    fbb_.AddElement<double>(MonsterExtra::VT_D2, d2, std::numeric_limits<double>::infinity());
+  }
+  void add_d3(double d3) {
+    fbb_.AddElement<double>(MonsterExtra::VT_D3, d3, -std::numeric_limits<double>::infinity());
+  }
+  void add_f0(float f0) {
+    fbb_.AddElement<float>(MonsterExtra::VT_F0, f0, std::numeric_limits<float>::quiet_NaN());
+  }
+  void add_f1(float f1) {
+    fbb_.AddElement<float>(MonsterExtra::VT_F1, f1, std::numeric_limits<float>::quiet_NaN());
+  }
+  void add_f2(float f2) {
+    fbb_.AddElement<float>(MonsterExtra::VT_F2, f2, std::numeric_limits<float>::infinity());
+  }
+  void add_f3(float f3) {
+    fbb_.AddElement<float>(MonsterExtra::VT_F3, f3, -std::numeric_limits<float>::infinity());
+  }
+  void add_dvec(flatbuffers::Offset<flatbuffers::Vector<double>> dvec) {
+    fbb_.AddOffset(MonsterExtra::VT_DVEC, dvec);
+  }
+  void add_fvec(flatbuffers::Offset<flatbuffers::Vector<float>> fvec) {
+    fbb_.AddOffset(MonsterExtra::VT_FVEC, fvec);
+  }
+  explicit MonsterExtraBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  MonsterExtraBuilder &operator=(const MonsterExtraBuilder &);
+  flatbuffers::Offset<MonsterExtra> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<MonsterExtra>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<MonsterExtra> CreateMonsterExtra(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    double d0 = std::numeric_limits<double>::quiet_NaN(),
+    double d1 = std::numeric_limits<double>::quiet_NaN(),
+    double d2 = std::numeric_limits<double>::infinity(),
+    double d3 = -std::numeric_limits<double>::infinity(),
+    float f0 = std::numeric_limits<float>::quiet_NaN(),
+    float f1 = std::numeric_limits<float>::quiet_NaN(),
+    float f2 = std::numeric_limits<float>::infinity(),
+    float f3 = -std::numeric_limits<float>::infinity(),
+    flatbuffers::Offset<flatbuffers::Vector<double>> dvec = 0,
+    flatbuffers::Offset<flatbuffers::Vector<float>> fvec = 0) {
+  MonsterExtraBuilder builder_(_fbb);
+  builder_.add_d3(d3);
+  builder_.add_d2(d2);
+  builder_.add_d1(d1);
+  builder_.add_d0(d0);
+  builder_.add_fvec(fvec);
+  builder_.add_dvec(dvec);
+  builder_.add_f3(f3);
+  builder_.add_f2(f2);
+  builder_.add_f1(f1);
+  builder_.add_f0(f0);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<MonsterExtra> CreateMonsterExtraDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    double d0 = std::numeric_limits<double>::quiet_NaN(),
+    double d1 = std::numeric_limits<double>::quiet_NaN(),
+    double d2 = std::numeric_limits<double>::infinity(),
+    double d3 = -std::numeric_limits<double>::infinity(),
+    float f0 = std::numeric_limits<float>::quiet_NaN(),
+    float f1 = std::numeric_limits<float>::quiet_NaN(),
+    float f2 = std::numeric_limits<float>::infinity(),
+    float f3 = -std::numeric_limits<float>::infinity(),
+    const std::vector<double> *dvec = nullptr,
+    const std::vector<float> *fvec = nullptr) {
+  auto dvec__ = dvec ? _fbb.CreateVector<double>(*dvec) : 0;
+  auto fvec__ = fvec ? _fbb.CreateVector<float>(*fvec) : 0;
+  return MyGame::CreateMonsterExtra(
+      _fbb,
+      d0,
+      d1,
+      d2,
+      d3,
+      f0,
+      f1,
+      f2,
+      f3,
+      dvec__,
+      fvec__);
+}
+
+flatbuffers::Offset<MonsterExtra> CreateMonsterExtra(flatbuffers::FlatBufferBuilder &_fbb, const MonsterExtraT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+inline MonsterExtraT *MonsterExtra::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = new MonsterExtraT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+inline void MonsterExtra::UnPackTo(MonsterExtraT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = d0(); _o->d0 = _e; };
+  { auto _e = d1(); _o->d1 = _e; };
+  { auto _e = d2(); _o->d2 = _e; };
+  { auto _e = d3(); _o->d3 = _e; };
+  { auto _e = f0(); _o->f0 = _e; };
+  { auto _e = f1(); _o->f1 = _e; };
+  { auto _e = f2(); _o->f2 = _e; };
+  { auto _e = f3(); _o->f3 = _e; };
+  { auto _e = dvec(); if (_e) { _o->dvec.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->dvec[_i] = _e->Get(_i); } } };
+  { auto _e = fvec(); if (_e) { _o->fvec.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->fvec[_i] = _e->Get(_i); } } };
+}
+
+inline flatbuffers::Offset<MonsterExtra> MonsterExtra::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterExtraT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateMonsterExtra(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<MonsterExtra> CreateMonsterExtra(flatbuffers::FlatBufferBuilder &_fbb, const MonsterExtraT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const MonsterExtraT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _d0 = _o->d0;
+  auto _d1 = _o->d1;
+  auto _d2 = _o->d2;
+  auto _d3 = _o->d3;
+  auto _f0 = _o->f0;
+  auto _f1 = _o->f1;
+  auto _f2 = _o->f2;
+  auto _f3 = _o->f3;
+  auto _dvec = _o->dvec.size() ? _fbb.CreateVector(_o->dvec) : 0;
+  auto _fvec = _o->fvec.size() ? _fbb.CreateVector(_o->fvec) : 0;
+  return MyGame::CreateMonsterExtra(
+      _fbb,
+      _d0,
+      _d1,
+      _d2,
+      _d3,
+      _f0,
+      _f1,
+      _f2,
+      _f3,
+      _dvec,
+      _fvec);
+}
+
+inline const flatbuffers::TypeTable *MonsterExtraTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_DOUBLE, 0, -1 },
+    { flatbuffers::ET_DOUBLE, 0, -1 },
+    { flatbuffers::ET_DOUBLE, 0, -1 },
+    { flatbuffers::ET_DOUBLE, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_DOUBLE, 1, -1 },
+    { flatbuffers::ET_FLOAT, 1, -1 }
+  };
+  static const char * const names[] = {
+    "d0",
+    "d1",
+    "d2",
+    "d3",
+    "f0",
+    "f1",
+    "f2",
+    "f3",
+    "dvec",
+    "fvec"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 10, type_codes, nullptr, nullptr, names
+  };
+  return &tt;
+}
+
+inline const MyGame::MonsterExtra *GetMonsterExtra(const void *buf) {
+  return flatbuffers::GetRoot<MyGame::MonsterExtra>(buf);
+}
+
+inline const MyGame::MonsterExtra *GetSizePrefixedMonsterExtra(const void *buf) {
+  return flatbuffers::GetSizePrefixedRoot<MyGame::MonsterExtra>(buf);
+}
+
+inline MonsterExtra *GetMutableMonsterExtra(void *buf) {
+  return flatbuffers::GetMutableRoot<MonsterExtra>(buf);
+}
+
+inline const char *MonsterExtraIdentifier() {
+  return "MONE";
+}
+
+inline bool MonsterExtraBufferHasIdentifier(const void *buf) {
+  return flatbuffers::BufferHasIdentifier(
+      buf, MonsterExtraIdentifier());
+}
+
+inline bool VerifyMonsterExtraBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifyBuffer<MyGame::MonsterExtra>(MonsterExtraIdentifier());
+}
+
+inline bool VerifySizePrefixedMonsterExtraBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifySizePrefixedBuffer<MyGame::MonsterExtra>(MonsterExtraIdentifier());
+}
+
+inline const char *MonsterExtraExtension() {
+  return "mon";
+}
+
+inline void FinishMonsterExtraBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<MyGame::MonsterExtra> root) {
+  fbb.Finish(root, MonsterExtraIdentifier());
+}
+
+inline void FinishSizePrefixedMonsterExtraBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<MyGame::MonsterExtra> root) {
+  fbb.FinishSizePrefixed(root, MonsterExtraIdentifier());
+}
+
+inline std::unique_ptr<MyGame::MonsterExtraT> UnPackMonsterExtra(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return std::unique_ptr<MyGame::MonsterExtraT>(GetMonsterExtra(buf)->UnPack(res));
+}
+
+inline std::unique_ptr<MyGame::MonsterExtraT> UnPackSizePrefixedMonsterExtra(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return std::unique_ptr<MyGame::MonsterExtraT>(GetSizePrefixedMonsterExtra(buf)->UnPack(res));
+}
+
+}  // namespace MyGame
+
+#endif  // FLATBUFFERS_GENERATED_MONSTEREXTRA_MYGAME_H_
diff --git a/third_party/flatbuffers/tests/monster_test.bfbs b/third_party/flatbuffers/tests/monster_test.bfbs
new file mode 100644
index 0000000..02d618d
--- /dev/null
+++ b/third_party/flatbuffers/tests/monster_test.bfbs
Binary files differ
diff --git a/third_party/flatbuffers/tests/monster_test.fbs b/third_party/flatbuffers/tests/monster_test.fbs
new file mode 100644
index 0000000..d791094
--- /dev/null
+++ b/third_party/flatbuffers/tests/monster_test.fbs
@@ -0,0 +1,138 @@
+// test schema file
+
+include "include_test1.fbs";
+
+namespace MyGame;
+
+table InParentNamespace {}
+
+namespace MyGame.Example2;
+
+table Monster {}  // Test having same name as below, but in different namespace.
+
+namespace MyGame.Example;
+
+attribute "priority";
+
+/// Composite components of Monster color.
+enum Color:ubyte (bit_flags) { 
+  Red = 0, // color Red = (1u << 0)
+  /// \brief color Green
+  /// Green is bit_flag with value (1u << 1)
+  Green, 
+  /// \brief color Blue (1u << 3)
+  Blue = 3, 
+}
+
+union Any { Monster, TestSimpleTableWithEnum, MyGame.Example2.Monster }
+
+union AnyUniqueAliases { M: Monster, TS: TestSimpleTableWithEnum, M2: MyGame.Example2.Monster }
+union AnyAmbiguousAliases { M1: Monster, M2: Monster, M3: Monster }
+
+struct Test { a:short; b:byte; }
+
+table TestSimpleTableWithEnum (csharp_partial, private) {
+  color: Color = Green;
+}
+
+struct Vec3 (force_align: 8) {
+  x:float;
+  y:float;
+  z:float;
+  test1:double;
+  test2:Color;
+  test3:Test;
+}
+
+struct Ability {
+  id:uint(key);
+  distance:uint;
+}
+
+table Stat {
+  id:string;
+  val:long;
+  count:ushort;
+}
+
+table Referrable {
+  id:ulong(key, hash:"fnv1a_64");
+}
+
+/// an example documentation comment: monster object
+table Monster {
+  pos:Vec3 (id: 0);
+  hp:short = 100 (id: 2);
+  mana:short = 150 (id: 1);
+  name:string (id: 3, required, key);
+  color:Color = Blue (id: 6);
+  inventory:[ubyte] (id: 5);
+  friendly:bool = false (deprecated, priority: 1, id: 4);
+  /// an example documentation comment: this will end up in the generated code
+  /// multiline too
+  testarrayoftables:[Monster] (id: 11);
+  testarrayofstring:[string] (id: 10);
+  testarrayofstring2:[string] (id: 28);
+  testarrayofbools:[bool] (id: 24);
+  testarrayofsortedstruct:[Ability] (id: 29);
+  enemy:MyGame.Example.Monster (id:12);  // Test referring by full namespace.
+  test:Any (id: 8);
+  test4:[Test] (id: 9);
+  test5:[Test] (id: 31);
+  testnestedflatbuffer:[ubyte] (id:13, nested_flatbuffer: "Monster");
+  testempty:Stat (id:14);
+  testbool:bool (id:15);
+  testhashs32_fnv1:int (id:16, hash:"fnv1_32");
+  testhashu32_fnv1:uint (id:17, hash:"fnv1_32");
+  testhashs64_fnv1:long (id:18, hash:"fnv1_64");
+  testhashu64_fnv1:ulong (id:19, hash:"fnv1_64");
+  testhashs32_fnv1a:int (id:20, hash:"fnv1a_32");
+  testhashu32_fnv1a:uint (id:21, hash:"fnv1a_32", cpp_type:"Stat");
+  testhashs64_fnv1a:long (id:22, hash:"fnv1a_64");
+  testhashu64_fnv1a:ulong (id:23, hash:"fnv1a_64");
+  testf:float = 3.14159 (id:25);
+  testf2:float = 3 (id:26);
+  testf3:float (id:27);
+  flex:[ubyte] (id:30, flexbuffer);
+  vector_of_longs:[long] (id:32);
+  vector_of_doubles:[double] (id:33);
+  parent_namespace_test:InParentNamespace (id:34);
+  vector_of_referrables:[Referrable](id:35);
+  single_weak_reference:ulong(id:36, hash:"fnv1a_64", cpp_type:"ReferrableT");
+  vector_of_weak_references:[ulong](id:37, hash:"fnv1a_64", cpp_type:"ReferrableT");
+  vector_of_strong_referrables:[Referrable](id:38, cpp_ptr_type:"default_ptr_type");                 //was shared_ptr
+  co_owning_reference:ulong(id:39, hash:"fnv1a_64", cpp_type:"ReferrableT", cpp_ptr_type:"naked");  //was shared_ptr as well
+  vector_of_co_owning_references:[ulong](id:40, hash:"fnv1a_64", cpp_type:"ReferrableT", cpp_ptr_type:"default_ptr_type", cpp_ptr_type_get:".get()");  //was shared_ptr
+  non_owning_reference:ulong(id:41, hash:"fnv1a_64", cpp_type:"ReferrableT", cpp_ptr_type:"naked", cpp_ptr_type_get:"");                              //was weak_ptr
+  vector_of_non_owning_references:[ulong](id:42, hash:"fnv1a_64", cpp_type:"ReferrableT", cpp_ptr_type:"naked", cpp_ptr_type_get:"");                 //was weak_ptr
+  any_unique:AnyUniqueAliases(id:44);
+  any_ambiguous:AnyAmbiguousAliases (id:46);
+  vector_of_enums:[Color] (id:47);
+}
+
+table TypeAliases {
+    i8:int8;
+    u8:uint8;
+    i16:int16;
+    u16:uint16;
+    i32:int32;
+    u32:uint32;
+    i64:int64;
+    u64:uint64;
+    f32:float32;
+    f64:float64;
+    v8:[int8];
+    vf64:[float64];
+}
+
+rpc_service MonsterStorage {
+  Store(Monster):Stat (streaming: "none");
+  Retrieve(Stat):Monster (streaming: "server", idempotent);
+  GetMaxHitPoint(Monster):Stat (streaming: "client");
+  GetMinMaxHitPoints(Monster):Stat (streaming: "bidi");
+}
+
+root_type Monster;
+
+file_identifier "MONS";
+file_extension "mon";
diff --git a/third_party/flatbuffers/tests/monster_test.grpc.fb.cc b/third_party/flatbuffers/tests/monster_test.grpc.fb.cc
new file mode 100644
index 0000000..f83e604
--- /dev/null
+++ b/third_party/flatbuffers/tests/monster_test.grpc.fb.cc
@@ -0,0 +1,142 @@
+// Generated by the gRPC C++ plugin.
+// If you make any local change, they will be lost.
+// source: monster_test
+
+#include "monster_test_generated.h"
+#include "monster_test.grpc.fb.h"
+
+#include <grpc++/impl/codegen/async_stream.h>
+#include <grpc++/impl/codegen/async_unary_call.h>
+#include <grpc++/impl/codegen/channel_interface.h>
+#include <grpc++/impl/codegen/client_unary_call.h>
+#include <grpc++/impl/codegen/method_handler_impl.h>
+#include <grpc++/impl/codegen/rpc_service_method.h>
+#include <grpc++/impl/codegen/service_type.h>
+#include <grpc++/impl/codegen/sync_stream.h>
+namespace MyGame {
+namespace Example {
+
+static const char* MonsterStorage_method_names[] = {
+  "/MyGame.Example.MonsterStorage/Store",
+  "/MyGame.Example.MonsterStorage/Retrieve",
+  "/MyGame.Example.MonsterStorage/GetMaxHitPoint",
+  "/MyGame.Example.MonsterStorage/GetMinMaxHitPoints",
+};
+
+std::unique_ptr< MonsterStorage::Stub> MonsterStorage::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) {
+  std::unique_ptr< MonsterStorage::Stub> stub(new MonsterStorage::Stub(channel));
+  return stub;
+}
+
+MonsterStorage::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel)
+  : channel_(channel)  , rpcmethod_Store_(MonsterStorage_method_names[0], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+  , rpcmethod_Retrieve_(MonsterStorage_method_names[1], ::grpc::internal::RpcMethod::SERVER_STREAMING, channel)
+  , rpcmethod_GetMaxHitPoint_(MonsterStorage_method_names[2], ::grpc::internal::RpcMethod::CLIENT_STREAMING, channel)
+  , rpcmethod_GetMinMaxHitPoints_(MonsterStorage_method_names[3], ::grpc::internal::RpcMethod::BIDI_STREAMING, channel)
+  {}
+  
+::grpc::Status MonsterStorage::Stub::Store(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Monster>& request, flatbuffers::grpc::Message<Stat>* response) {
+  return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_Store_, context, request, response);
+}
+
+::grpc::ClientAsyncResponseReader< flatbuffers::grpc::Message<Stat>>* MonsterStorage::Stub::AsyncStoreRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Monster>& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc::internal::ClientAsyncResponseReaderFactory< flatbuffers::grpc::Message<Stat>>::Create(channel_.get(), cq, rpcmethod_Store_, context, request, true);
+}
+
+::grpc::ClientAsyncResponseReader< flatbuffers::grpc::Message<Stat>>* MonsterStorage::Stub::PrepareAsyncStoreRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Monster>& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc::internal::ClientAsyncResponseReaderFactory< flatbuffers::grpc::Message<Stat>>::Create(channel_.get(), cq, rpcmethod_Store_, context, request, false);
+}
+
+::grpc::ClientReader< flatbuffers::grpc::Message<Monster>>* MonsterStorage::Stub::RetrieveRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request) {
+  return ::grpc::internal::ClientReaderFactory< flatbuffers::grpc::Message<Monster>>::Create(channel_.get(), rpcmethod_Retrieve_, context, request);
+}
+
+::grpc::ClientAsyncReader< flatbuffers::grpc::Message<Monster>>* MonsterStorage::Stub::AsyncRetrieveRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request, ::grpc::CompletionQueue* cq, void* tag) {
+  return ::grpc::internal::ClientAsyncReaderFactory< flatbuffers::grpc::Message<Monster>>::Create(channel_.get(), cq, rpcmethod_Retrieve_, context, request, true, tag);
+}
+
+::grpc::ClientAsyncReader< flatbuffers::grpc::Message<Monster>>* MonsterStorage::Stub::PrepareAsyncRetrieveRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc::internal::ClientAsyncReaderFactory< flatbuffers::grpc::Message<Monster>>::Create(channel_.get(), cq, rpcmethod_Retrieve_, context, request, false, nullptr);
+}
+
+::grpc::ClientWriter< flatbuffers::grpc::Message<Monster>>* MonsterStorage::Stub::GetMaxHitPointRaw(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response) {
+  return ::grpc::internal::ClientWriterFactory< flatbuffers::grpc::Message<Monster>>::Create(channel_.get(), rpcmethod_GetMaxHitPoint_, context, response);
+}
+
+::grpc::ClientAsyncWriter< flatbuffers::grpc::Message<Monster>>* MonsterStorage::Stub::AsyncGetMaxHitPointRaw(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response, ::grpc::CompletionQueue* cq, void* tag) {
+  return ::grpc::internal::ClientAsyncWriterFactory< flatbuffers::grpc::Message<Monster>>::Create(channel_.get(), cq, rpcmethod_GetMaxHitPoint_, context, response, true, tag);
+}
+
+::grpc::ClientAsyncWriter< flatbuffers::grpc::Message<Monster>>* MonsterStorage::Stub::PrepareAsyncGetMaxHitPointRaw(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response, ::grpc::CompletionQueue* cq) {
+  return ::grpc::internal::ClientAsyncWriterFactory< flatbuffers::grpc::Message<Monster>>::Create(channel_.get(), cq, rpcmethod_GetMaxHitPoint_, context, response, false, nullptr);
+}
+
+::grpc::ClientReaderWriter< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>* MonsterStorage::Stub::GetMinMaxHitPointsRaw(::grpc::ClientContext* context) {
+  return ::grpc::internal::ClientReaderWriterFactory< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>::Create(channel_.get(), rpcmethod_GetMinMaxHitPoints_, context);
+}
+
+::grpc::ClientAsyncReaderWriter< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>* MonsterStorage::Stub::AsyncGetMinMaxHitPointsRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) {
+  return ::grpc::internal::ClientAsyncReaderWriterFactory< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>::Create(channel_.get(), cq, rpcmethod_GetMinMaxHitPoints_, context, true, tag);
+}
+
+::grpc::ClientAsyncReaderWriter< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>* MonsterStorage::Stub::PrepareAsyncGetMinMaxHitPointsRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) {
+  return ::grpc::internal::ClientAsyncReaderWriterFactory< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>::Create(channel_.get(), cq, rpcmethod_GetMinMaxHitPoints_, context, false, nullptr);
+}
+
+MonsterStorage::Service::Service() {
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      MonsterStorage_method_names[0],
+      ::grpc::internal::RpcMethod::NORMAL_RPC,
+      new ::grpc::internal::RpcMethodHandler< MonsterStorage::Service, flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>(
+          std::mem_fn(&MonsterStorage::Service::Store), this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      MonsterStorage_method_names[1],
+      ::grpc::internal::RpcMethod::SERVER_STREAMING,
+      new ::grpc::internal::ServerStreamingHandler< MonsterStorage::Service, flatbuffers::grpc::Message<Stat>, flatbuffers::grpc::Message<Monster>>(
+          std::mem_fn(&MonsterStorage::Service::Retrieve), this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      MonsterStorage_method_names[2],
+      ::grpc::internal::RpcMethod::CLIENT_STREAMING,
+      new ::grpc::internal::ClientStreamingHandler< MonsterStorage::Service, flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>(
+          std::mem_fn(&MonsterStorage::Service::GetMaxHitPoint), this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      MonsterStorage_method_names[3],
+      ::grpc::internal::RpcMethod::BIDI_STREAMING,
+      new ::grpc::internal::BidiStreamingHandler< MonsterStorage::Service, flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>(
+          std::mem_fn(&MonsterStorage::Service::GetMinMaxHitPoints), this)));
+}
+
+MonsterStorage::Service::~Service() {
+}
+
+::grpc::Status MonsterStorage::Service::Store(::grpc::ServerContext* context, const flatbuffers::grpc::Message<Monster>* request, flatbuffers::grpc::Message<Stat>* response) {
+  (void) context;
+  (void) request;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status MonsterStorage::Service::Retrieve(::grpc::ServerContext* context, const flatbuffers::grpc::Message<Stat>* request, ::grpc::ServerWriter< flatbuffers::grpc::Message<Monster>>* writer) {
+  (void) context;
+  (void) request;
+  (void) writer;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status MonsterStorage::Service::GetMaxHitPoint(::grpc::ServerContext* context, ::grpc::ServerReader< flatbuffers::grpc::Message<Monster>>* reader, flatbuffers::grpc::Message<Stat>* response) {
+  (void) context;
+  (void) reader;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status MonsterStorage::Service::GetMinMaxHitPoints(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< flatbuffers::grpc::Message<Stat>, flatbuffers::grpc::Message<Monster>>* stream) {
+  (void) context;
+  (void) stream;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+
+}  // namespace MyGame
+}  // namespace Example
+
diff --git a/third_party/flatbuffers/tests/monster_test.grpc.fb.h b/third_party/flatbuffers/tests/monster_test.grpc.fb.h
new file mode 100644
index 0000000..72402ec
--- /dev/null
+++ b/third_party/flatbuffers/tests/monster_test.grpc.fb.h
@@ -0,0 +1,350 @@
+// Generated by the gRPC C++ plugin.
+// If you make any local change, they will be lost.
+// source: monster_test
+#ifndef GRPC_monster_5ftest__INCLUDED
+#define GRPC_monster_5ftest__INCLUDED
+
+#include "monster_test_generated.h"
+#include "flatbuffers/grpc.h"
+
+#include <grpc++/impl/codegen/async_stream.h>
+#include <grpc++/impl/codegen/async_unary_call.h>
+#include <grpc++/impl/codegen/method_handler_impl.h>
+#include <grpc++/impl/codegen/proto_utils.h>
+#include <grpc++/impl/codegen/rpc_method.h>
+#include <grpc++/impl/codegen/service_type.h>
+#include <grpc++/impl/codegen/status.h>
+#include <grpc++/impl/codegen/stub_options.h>
+#include <grpc++/impl/codegen/sync_stream.h>
+
+namespace grpc {
+class CompletionQueue;
+class Channel;
+class ServerCompletionQueue;
+class ServerContext;
+}  // namespace grpc
+
+namespace MyGame {
+namespace Example {
+
+class MonsterStorage final {
+ public:
+  static constexpr char const* service_full_name() {
+    return "MyGame.Example.MonsterStorage";
+  }
+  class StubInterface {
+   public:
+    virtual ~StubInterface() {}
+    virtual ::grpc::Status Store(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Monster>& request, flatbuffers::grpc::Message<Stat>* response) = 0;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< flatbuffers::grpc::Message<Stat>>> AsyncStore(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Monster>& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< flatbuffers::grpc::Message<Stat>>>(AsyncStoreRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< flatbuffers::grpc::Message<Stat>>> PrepareAsyncStore(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Monster>& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< flatbuffers::grpc::Message<Stat>>>(PrepareAsyncStoreRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientReaderInterface< flatbuffers::grpc::Message<Monster>>> Retrieve(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request) {
+      return std::unique_ptr< ::grpc::ClientReaderInterface< flatbuffers::grpc::Message<Monster>>>(RetrieveRaw(context, request));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReaderInterface< flatbuffers::grpc::Message<Monster>>> AsyncRetrieve(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< flatbuffers::grpc::Message<Monster>>>(AsyncRetrieveRaw(context, request, cq, tag));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReaderInterface< flatbuffers::grpc::Message<Monster>>> PrepareAsyncRetrieve(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< flatbuffers::grpc::Message<Monster>>>(PrepareAsyncRetrieveRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientWriterInterface< flatbuffers::grpc::Message<Monster>>> GetMaxHitPoint(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response) {
+      return std::unique_ptr< ::grpc::ClientWriterInterface< flatbuffers::grpc::Message<Monster>>>(GetMaxHitPointRaw(context, response));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncWriterInterface< flatbuffers::grpc::Message<Monster>>> AsyncGetMaxHitPoint(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncWriterInterface< flatbuffers::grpc::Message<Monster>>>(AsyncGetMaxHitPointRaw(context, response, cq, tag));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncWriterInterface< flatbuffers::grpc::Message<Monster>>> PrepareAsyncGetMaxHitPoint(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncWriterInterface< flatbuffers::grpc::Message<Monster>>>(PrepareAsyncGetMaxHitPointRaw(context, response, cq));
+    }
+    std::unique_ptr< ::grpc::ClientReaderWriterInterface< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>> GetMinMaxHitPoints(::grpc::ClientContext* context) {
+      return std::unique_ptr< ::grpc::ClientReaderWriterInterface< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>>(GetMinMaxHitPointsRaw(context));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>> AsyncGetMinMaxHitPoints(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>>(AsyncGetMinMaxHitPointsRaw(context, cq, tag));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>> PrepareAsyncGetMinMaxHitPoints(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>>(PrepareAsyncGetMinMaxHitPointsRaw(context, cq));
+    }
+  private:
+    virtual ::grpc::ClientAsyncResponseReaderInterface< flatbuffers::grpc::Message<Stat>>* AsyncStoreRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Monster>& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< flatbuffers::grpc::Message<Stat>>* PrepareAsyncStoreRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Monster>& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientReaderInterface< flatbuffers::grpc::Message<Monster>>* RetrieveRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request) = 0;
+    virtual ::grpc::ClientAsyncReaderInterface< flatbuffers::grpc::Message<Monster>>* AsyncRetrieveRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request, ::grpc::CompletionQueue* cq, void* tag) = 0;
+    virtual ::grpc::ClientAsyncReaderInterface< flatbuffers::grpc::Message<Monster>>* PrepareAsyncRetrieveRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientWriterInterface< flatbuffers::grpc::Message<Monster>>* GetMaxHitPointRaw(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response) = 0;
+    virtual ::grpc::ClientAsyncWriterInterface< flatbuffers::grpc::Message<Monster>>* AsyncGetMaxHitPointRaw(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response, ::grpc::CompletionQueue* cq, void* tag) = 0;
+    virtual ::grpc::ClientAsyncWriterInterface< flatbuffers::grpc::Message<Monster>>* PrepareAsyncGetMaxHitPointRaw(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientReaderWriterInterface< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>* GetMinMaxHitPointsRaw(::grpc::ClientContext* context) = 0;
+    virtual ::grpc::ClientAsyncReaderWriterInterface< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>* AsyncGetMinMaxHitPointsRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) = 0;
+    virtual ::grpc::ClientAsyncReaderWriterInterface< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>* PrepareAsyncGetMinMaxHitPointsRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) = 0;
+  };
+  class Stub final : public StubInterface {
+   public:
+    Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel);
+    ::grpc::Status Store(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Monster>& request, flatbuffers::grpc::Message<Stat>* response) override;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< flatbuffers::grpc::Message<Stat>>> AsyncStore(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Monster>& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< flatbuffers::grpc::Message<Stat>>>(AsyncStoreRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< flatbuffers::grpc::Message<Stat>>> PrepareAsyncStore(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Monster>& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< flatbuffers::grpc::Message<Stat>>>(PrepareAsyncStoreRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientReader< flatbuffers::grpc::Message<Monster>>> Retrieve(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request) {
+      return std::unique_ptr< ::grpc::ClientReader< flatbuffers::grpc::Message<Monster>>>(RetrieveRaw(context, request));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReader< flatbuffers::grpc::Message<Monster>>> AsyncRetrieve(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReader< flatbuffers::grpc::Message<Monster>>>(AsyncRetrieveRaw(context, request, cq, tag));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReader< flatbuffers::grpc::Message<Monster>>> PrepareAsyncRetrieve(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncReader< flatbuffers::grpc::Message<Monster>>>(PrepareAsyncRetrieveRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientWriter< flatbuffers::grpc::Message<Monster>>> GetMaxHitPoint(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response) {
+      return std::unique_ptr< ::grpc::ClientWriter< flatbuffers::grpc::Message<Monster>>>(GetMaxHitPointRaw(context, response));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncWriter< flatbuffers::grpc::Message<Monster>>> AsyncGetMaxHitPoint(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncWriter< flatbuffers::grpc::Message<Monster>>>(AsyncGetMaxHitPointRaw(context, response, cq, tag));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncWriter< flatbuffers::grpc::Message<Monster>>> PrepareAsyncGetMaxHitPoint(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncWriter< flatbuffers::grpc::Message<Monster>>>(PrepareAsyncGetMaxHitPointRaw(context, response, cq));
+    }
+    std::unique_ptr< ::grpc::ClientReaderWriter< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>> GetMinMaxHitPoints(::grpc::ClientContext* context) {
+      return std::unique_ptr< ::grpc::ClientReaderWriter< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>>(GetMinMaxHitPointsRaw(context));
+    }
+    std::unique_ptr<  ::grpc::ClientAsyncReaderWriter< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>> AsyncGetMinMaxHitPoints(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderWriter< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>>(AsyncGetMinMaxHitPointsRaw(context, cq, tag));
+    }
+    std::unique_ptr<  ::grpc::ClientAsyncReaderWriter< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>> PrepareAsyncGetMinMaxHitPoints(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderWriter< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>>(PrepareAsyncGetMinMaxHitPointsRaw(context, cq));
+    }
+  
+   private:
+    std::shared_ptr< ::grpc::ChannelInterface> channel_;
+    ::grpc::ClientAsyncResponseReader< flatbuffers::grpc::Message<Stat>>* AsyncStoreRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Monster>& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< flatbuffers::grpc::Message<Stat>>* PrepareAsyncStoreRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Monster>& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientReader< flatbuffers::grpc::Message<Monster>>* RetrieveRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request) override;
+    ::grpc::ClientAsyncReader< flatbuffers::grpc::Message<Monster>>* AsyncRetrieveRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request, ::grpc::CompletionQueue* cq, void* tag) override;
+    ::grpc::ClientAsyncReader< flatbuffers::grpc::Message<Monster>>* PrepareAsyncRetrieveRaw(::grpc::ClientContext* context, const flatbuffers::grpc::Message<Stat>& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientWriter< flatbuffers::grpc::Message<Monster>>* GetMaxHitPointRaw(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response) override;
+    ::grpc::ClientAsyncWriter< flatbuffers::grpc::Message<Monster>>* AsyncGetMaxHitPointRaw(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response, ::grpc::CompletionQueue* cq, void* tag) override;
+    ::grpc::ClientAsyncWriter< flatbuffers::grpc::Message<Monster>>* PrepareAsyncGetMaxHitPointRaw(::grpc::ClientContext* context, flatbuffers::grpc::Message<Stat>* response, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientReaderWriter< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>* GetMinMaxHitPointsRaw(::grpc::ClientContext* context) override;
+    ::grpc::ClientAsyncReaderWriter< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>* AsyncGetMinMaxHitPointsRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) override;
+    ::grpc::ClientAsyncReaderWriter< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>* PrepareAsyncGetMinMaxHitPointsRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) override;
+    const ::grpc::internal::RpcMethod rpcmethod_Store_;
+    const ::grpc::internal::RpcMethod rpcmethod_Retrieve_;
+    const ::grpc::internal::RpcMethod rpcmethod_GetMaxHitPoint_;
+    const ::grpc::internal::RpcMethod rpcmethod_GetMinMaxHitPoints_;
+  };
+  static std::unique_ptr<Stub> NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions());
+  
+  class Service : public ::grpc::Service {
+   public:
+    Service();
+    virtual ~Service();
+    virtual ::grpc::Status Store(::grpc::ServerContext* context, const flatbuffers::grpc::Message<Monster>* request, flatbuffers::grpc::Message<Stat>* response);
+    virtual ::grpc::Status Retrieve(::grpc::ServerContext* context, const flatbuffers::grpc::Message<Stat>* request, ::grpc::ServerWriter< flatbuffers::grpc::Message<Monster>>* writer);
+    virtual ::grpc::Status GetMaxHitPoint(::grpc::ServerContext* context, ::grpc::ServerReader< flatbuffers::grpc::Message<Monster>>* reader, flatbuffers::grpc::Message<Stat>* response);
+    virtual ::grpc::Status GetMinMaxHitPoints(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< flatbuffers::grpc::Message<Stat>, flatbuffers::grpc::Message<Monster>>* stream);
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_Store : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithAsyncMethod_Store() {
+      ::grpc::Service::MarkMethodAsync(0);
+    }
+    ~WithAsyncMethod_Store() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status Store(::grpc::ServerContext* context, const flatbuffers::grpc::Message<Monster>* request, flatbuffers::grpc::Message<Stat>* response) final override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestStore(::grpc::ServerContext* context, flatbuffers::grpc::Message<Monster>* request, ::grpc::ServerAsyncResponseWriter< flatbuffers::grpc::Message<Stat>>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_Retrieve : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithAsyncMethod_Retrieve() {
+      ::grpc::Service::MarkMethodAsync(1);
+    }
+    ~WithAsyncMethod_Retrieve() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status Retrieve(::grpc::ServerContext* context, const flatbuffers::grpc::Message<Stat>* request, ::grpc::ServerWriter< flatbuffers::grpc::Message<Monster>>* writer) final override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestRetrieve(::grpc::ServerContext* context, flatbuffers::grpc::Message<Stat>* request, ::grpc::ServerAsyncWriter< flatbuffers::grpc::Message<Monster>>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncServerStreaming(1, context, request, writer, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_GetMaxHitPoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithAsyncMethod_GetMaxHitPoint() {
+      ::grpc::Service::MarkMethodAsync(2);
+    }
+    ~WithAsyncMethod_GetMaxHitPoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetMaxHitPoint(::grpc::ServerContext* context, ::grpc::ServerReader< flatbuffers::grpc::Message<Monster>>* reader, flatbuffers::grpc::Message<Stat>* response) final override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetMaxHitPoint(::grpc::ServerContext* context, ::grpc::ServerAsyncReader< flatbuffers::grpc::Message<Stat>, flatbuffers::grpc::Message<Monster>>* reader, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncClientStreaming(2, context, reader, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_GetMinMaxHitPoints : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithAsyncMethod_GetMinMaxHitPoints() {
+      ::grpc::Service::MarkMethodAsync(3);
+    }
+    ~WithAsyncMethod_GetMinMaxHitPoints() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetMinMaxHitPoints(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< flatbuffers::grpc::Message<Stat>, flatbuffers::grpc::Message<Monster>>* stream) final override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetMinMaxHitPoints(::grpc::ServerContext* context, ::grpc::ServerAsyncReaderWriter< flatbuffers::grpc::Message<Stat>, flatbuffers::grpc::Message<Monster>>* stream, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncBidiStreaming(3, context, stream, new_call_cq, notification_cq, tag);
+    }
+  };
+  typedef   WithAsyncMethod_Store<  WithAsyncMethod_Retrieve<  WithAsyncMethod_GetMaxHitPoint<  WithAsyncMethod_GetMinMaxHitPoints<  Service   >   >   >   >   AsyncService;
+  template <class BaseClass>
+  class WithGenericMethod_Store : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithGenericMethod_Store() {
+      ::grpc::Service::MarkMethodGeneric(0);
+    }
+    ~WithGenericMethod_Store() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status Store(::grpc::ServerContext* context, const flatbuffers::grpc::Message<Monster>* request, flatbuffers::grpc::Message<Stat>* response) final override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_Retrieve : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithGenericMethod_Retrieve() {
+      ::grpc::Service::MarkMethodGeneric(1);
+    }
+    ~WithGenericMethod_Retrieve() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status Retrieve(::grpc::ServerContext* context, const flatbuffers::grpc::Message<Stat>* request, ::grpc::ServerWriter< flatbuffers::grpc::Message<Monster>>* writer) final override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_GetMaxHitPoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithGenericMethod_GetMaxHitPoint() {
+      ::grpc::Service::MarkMethodGeneric(2);
+    }
+    ~WithGenericMethod_GetMaxHitPoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetMaxHitPoint(::grpc::ServerContext* context, ::grpc::ServerReader< flatbuffers::grpc::Message<Monster>>* reader, flatbuffers::grpc::Message<Stat>* response) final override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_GetMinMaxHitPoints : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithGenericMethod_GetMinMaxHitPoints() {
+      ::grpc::Service::MarkMethodGeneric(3);
+    }
+    ~WithGenericMethod_GetMinMaxHitPoints() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetMinMaxHitPoints(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< flatbuffers::grpc::Message<Stat>, flatbuffers::grpc::Message<Monster>>* stream) final override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_Store : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithStreamedUnaryMethod_Store() {
+      ::grpc::Service::MarkMethodStreamed(0,
+        new ::grpc::internal::StreamedUnaryHandler< flatbuffers::grpc::Message<Monster>, flatbuffers::grpc::Message<Stat>>(std::bind(&WithStreamedUnaryMethod_Store<BaseClass>::StreamedStore, this, std::placeholders::_1, std::placeholders::_2)));
+    }
+    ~WithStreamedUnaryMethod_Store() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status Store(::grpc::ServerContext* context, const flatbuffers::grpc::Message<Monster>* request, flatbuffers::grpc::Message<Stat>* response) final override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status StreamedStore(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< flatbuffers::grpc::Message<Monster>,flatbuffers::grpc::Message<Stat>>* server_unary_streamer) = 0;
+  };
+  typedef   WithStreamedUnaryMethod_Store<  Service   >   StreamedUnaryService;
+  template <class BaseClass>
+  class WithSplitStreamingMethod_Retrieve : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithSplitStreamingMethod_Retrieve() {
+      ::grpc::Service::MarkMethodStreamed(1,
+        new ::grpc::internal::SplitServerStreamingHandler< flatbuffers::grpc::Message<Stat>, flatbuffers::grpc::Message<Monster>>(std::bind(&WithSplitStreamingMethod_Retrieve<BaseClass>::StreamedRetrieve, this, std::placeholders::_1, std::placeholders::_2)));
+    }
+    ~WithSplitStreamingMethod_Retrieve() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status Retrieve(::grpc::ServerContext* context, const flatbuffers::grpc::Message<Stat>* request, ::grpc::ServerWriter< flatbuffers::grpc::Message<Monster>>* writer) final override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with split streamed
+    virtual ::grpc::Status StreamedRetrieve(::grpc::ServerContext* context, ::grpc::ServerSplitStreamer< flatbuffers::grpc::Message<Stat>,flatbuffers::grpc::Message<Monster>>* server_split_streamer) = 0;
+  };
+  typedef   WithSplitStreamingMethod_Retrieve<  Service   >   SplitStreamedService;
+  typedef   WithStreamedUnaryMethod_Store<  WithSplitStreamingMethod_Retrieve<  Service   >   >   StreamedService;
+};
+
+}  // namespace Example
+}  // namespace MyGame
+
+
+#endif  // GRPC_monster_5ftest__INCLUDED
diff --git a/third_party/flatbuffers/tests/monster_test.schema.json b/third_party/flatbuffers/tests/monster_test.schema.json
new file mode 100644
index 0000000..7fb7500
--- /dev/null
+++ b/third_party/flatbuffers/tests/monster_test.schema.json
@@ -0,0 +1,340 @@
+{
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "definitions": {
+    "MyGame_OtherNameSpace_FromInclude" : {
+      "type" : "string",
+      "enum": ["IncludeVal"]
+    },
+    "MyGame_Example_Color" : {
+      "type" : "string",
+      "enum": ["Red", "Green", "Blue"]
+    },
+    "MyGame_Example_Any" : {
+      "type" : "string",
+      "enum": ["NONE", "Monster", "TestSimpleTableWithEnum", "MyGame_Example2_Monster"]
+    },
+    "MyGame_Example_AnyUniqueAliases" : {
+      "type" : "string",
+      "enum": ["NONE", "M", "TS", "M2"]
+    },
+    "MyGame_Example_AnyAmbiguousAliases" : {
+      "type" : "string",
+      "enum": ["NONE", "M1", "M2", "M3"]
+    },
+    "MyGame_OtherNameSpace_Unused" : {
+      "type" : "object",
+      "properties" : {
+        "a" : {
+                "type" : "number"
+              }
+      },
+      "additionalProperties" : false
+    },
+    "MyGame_OtherNameSpace_TableB" : {
+      "type" : "object",
+      "properties" : {
+        "a" : {
+                "$ref" : "#/definitions/TableA"
+              }
+      },
+      "additionalProperties" : false
+    },
+    "TableA" : {
+      "type" : "object",
+      "properties" : {
+        "b" : {
+                "$ref" : "#/definitions/MyGame_OtherNameSpace_TableB"
+              }
+      },
+      "additionalProperties" : false
+    },
+    "MyGame_InParentNamespace" : {
+      "type" : "object",
+      "properties" : {
+      },
+      "additionalProperties" : false
+    },
+    "MyGame_Example2_Monster" : {
+      "type" : "object",
+      "properties" : {
+      },
+      "additionalProperties" : false
+    },
+    "MyGame_Example_Test" : {
+      "type" : "object",
+      "properties" : {
+        "a" : {
+                "type" : "number"
+              },
+        "b" : {
+                "type" : "number"
+              }
+      },
+      "additionalProperties" : false
+    },
+    "MyGame_Example_TestSimpleTableWithEnum" : {
+      "type" : "object",
+      "properties" : {
+        "color" : {
+                "$ref" : "#/definitions/MyGame_Example_Color"
+              }
+      },
+      "additionalProperties" : false
+    },
+    "MyGame_Example_Vec3" : {
+      "type" : "object",
+      "properties" : {
+        "x" : {
+                "type" : "number"
+              },
+        "y" : {
+                "type" : "number"
+              },
+        "z" : {
+                "type" : "number"
+              },
+        "test1" : {
+                "type" : "number"
+              },
+        "test2" : {
+                "$ref" : "#/definitions/MyGame_Example_Color"
+              },
+        "test3" : {
+                "$ref" : "#/definitions/MyGame_Example_Test"
+              }
+      },
+      "additionalProperties" : false
+    },
+    "MyGame_Example_Ability" : {
+      "type" : "object",
+      "properties" : {
+        "id" : {
+                "type" : "number"
+              },
+        "distance" : {
+                "type" : "number"
+              }
+      },
+      "additionalProperties" : false
+    },
+    "MyGame_Example_Stat" : {
+      "type" : "object",
+      "properties" : {
+        "id" : {
+                "type" : "string"
+              },
+        "val" : {
+                "type" : "number"
+              },
+        "count" : {
+                "type" : "number"
+              }
+      },
+      "additionalProperties" : false
+    },
+    "MyGame_Example_Referrable" : {
+      "type" : "object",
+      "properties" : {
+        "id" : {
+                "type" : "number"
+              }
+      },
+      "additionalProperties" : false
+    },
+    "MyGame_Example_Monster" : {
+      "type" : "object",
+      "description" : " an example documentation comment: monster object",
+      "properties" : {
+        "pos" : {
+                "$ref" : "#/definitions/MyGame_Example_Vec3"
+              },
+        "mana" : {
+                "type" : "number"
+              },
+        "hp" : {
+                "type" : "number"
+              },
+        "name" : {
+                "type" : "string"
+              },
+        "friendly" : {
+                "type" : "boolean"
+              },
+        "inventory" : {
+                "type" : "array", "items" : { "type" : "number" }
+              },
+        "color" : {
+                "$ref" : "#/definitions/MyGame_Example_Color"
+              },
+        "test_type" : {
+                "$ref" : "#/definitions/MyGame_Example_Any"
+              },
+        "test" : {
+                "anyOf": [{ "$ref" : "#/definitions/MyGame_Example_Monster" },{ "$ref" : "#/definitions/MyGame_Example_TestSimpleTableWithEnum" },{ "$ref" : "#/definitions/MyGame_Example2_Monster" }]
+              },
+        "test4" : {
+                "type" : "array", "items" : { "$ref" : "#/definitions/MyGame_Example_Test" }
+              },
+        "testarrayofstring" : {
+                "type" : "array", "items" : { "type" : "string" }
+              },
+        "testarrayoftables" : {
+                "type" : "array", "items" : { "$ref" : "#/definitions/MyGame_Example_Monster" }
+              },
+        "enemy" : {
+                "$ref" : "#/definitions/MyGame_Example_Monster"
+              },
+        "testnestedflatbuffer" : {
+                "type" : "array", "items" : { "type" : "number" }
+              },
+        "testempty" : {
+                "$ref" : "#/definitions/MyGame_Example_Stat"
+              },
+        "testbool" : {
+                "type" : "boolean"
+              },
+        "testhashs32_fnv1" : {
+                "type" : "number"
+              },
+        "testhashu32_fnv1" : {
+                "type" : "number"
+              },
+        "testhashs64_fnv1" : {
+                "type" : "number"
+              },
+        "testhashu64_fnv1" : {
+                "type" : "number"
+              },
+        "testhashs32_fnv1a" : {
+                "type" : "number"
+              },
+        "testhashu32_fnv1a" : {
+                "type" : "number"
+              },
+        "testhashs64_fnv1a" : {
+                "type" : "number"
+              },
+        "testhashu64_fnv1a" : {
+                "type" : "number"
+              },
+        "testarrayofbools" : {
+                "type" : "array", "items" : { "type" : "boolean" }
+              },
+        "testf" : {
+                "type" : "number"
+              },
+        "testf2" : {
+                "type" : "number"
+              },
+        "testf3" : {
+                "type" : "number"
+              },
+        "testarrayofstring2" : {
+                "type" : "array", "items" : { "type" : "string" }
+              },
+        "testarrayofsortedstruct" : {
+                "type" : "array", "items" : { "$ref" : "#/definitions/MyGame_Example_Ability" }
+              },
+        "flex" : {
+                "type" : "array", "items" : { "type" : "number" }
+              },
+        "test5" : {
+                "type" : "array", "items" : { "$ref" : "#/definitions/MyGame_Example_Test" }
+              },
+        "vector_of_longs" : {
+                "type" : "array", "items" : { "type" : "number" }
+              },
+        "vector_of_doubles" : {
+                "type" : "array", "items" : { "type" : "number" }
+              },
+        "parent_namespace_test" : {
+                "$ref" : "#/definitions/MyGame_InParentNamespace"
+              },
+        "vector_of_referrables" : {
+                "type" : "array", "items" : { "$ref" : "#/definitions/MyGame_Example_Referrable" }
+              },
+        "single_weak_reference" : {
+                "type" : "number"
+              },
+        "vector_of_weak_references" : {
+                "type" : "array", "items" : { "type" : "number" }
+              },
+        "vector_of_strong_referrables" : {
+                "type" : "array", "items" : { "$ref" : "#/definitions/MyGame_Example_Referrable" }
+              },
+        "co_owning_reference" : {
+                "type" : "number"
+              },
+        "vector_of_co_owning_references" : {
+                "type" : "array", "items" : { "type" : "number" }
+              },
+        "non_owning_reference" : {
+                "type" : "number"
+              },
+        "vector_of_non_owning_references" : {
+                "type" : "array", "items" : { "type" : "number" }
+              },
+        "any_unique_type" : {
+                "$ref" : "#/definitions/MyGame_Example_AnyUniqueAliases"
+              },
+        "any_unique" : {
+                "anyOf": [{ "$ref" : "#/definitions/MyGame_Example_Monster" },{ "$ref" : "#/definitions/MyGame_Example_TestSimpleTableWithEnum" },{ "$ref" : "#/definitions/MyGame_Example2_Monster" }]
+              },
+        "any_ambiguous_type" : {
+                "$ref" : "#/definitions/MyGame_Example_AnyAmbiguousAliases"
+              },
+        "any_ambiguous" : {
+                "anyOf": [{ "$ref" : "#/definitions/MyGame_Example_Monster" },{ "$ref" : "#/definitions/MyGame_Example_Monster" },{ "$ref" : "#/definitions/MyGame_Example_Monster" }]
+              },
+        "vector_of_enums" : {
+                "$ref" : "#/definitions/MyGame_Example_Color"
+              }
+      },
+      "required" : ["name"],
+      "additionalProperties" : false
+    },
+    "MyGame_Example_TypeAliases" : {
+      "type" : "object",
+      "properties" : {
+        "i8" : {
+                "type" : "number"
+              },
+        "u8" : {
+                "type" : "number"
+              },
+        "i16" : {
+                "type" : "number"
+              },
+        "u16" : {
+                "type" : "number"
+              },
+        "i32" : {
+                "type" : "number"
+              },
+        "u32" : {
+                "type" : "number"
+              },
+        "i64" : {
+                "type" : "number"
+              },
+        "u64" : {
+                "type" : "number"
+              },
+        "f32" : {
+                "type" : "number"
+              },
+        "f64" : {
+                "type" : "number"
+              },
+        "v8" : {
+                "type" : "array", "items" : { "type" : "number" }
+              },
+        "vf64" : {
+                "type" : "array", "items" : { "type" : "number" }
+              }
+      },
+      "additionalProperties" : false
+    }
+  },
+  "$ref" : "#/definitions/MyGame_Example_Monster"
+}
diff --git a/third_party/flatbuffers/tests/monster_test_generated.h b/third_party/flatbuffers/tests/monster_test_generated.h
new file mode 100644
index 0000000..4016ce9
--- /dev/null
+++ b/third_party/flatbuffers/tests/monster_test_generated.h
@@ -0,0 +1,3499 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_MONSTERTEST_MYGAME_EXAMPLE_H_
+#define FLATBUFFERS_GENERATED_MONSTERTEST_MYGAME_EXAMPLE_H_
+
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/flexbuffers.h"
+
+namespace MyGame {
+
+struct InParentNamespace;
+struct InParentNamespaceT;
+
+namespace Example2 {
+
+struct Monster;
+struct MonsterT;
+
+}  // namespace Example2
+
+namespace Example {
+
+struct Test;
+
+struct TestSimpleTableWithEnum;
+struct TestSimpleTableWithEnumT;
+
+struct Vec3;
+
+struct Ability;
+
+struct Stat;
+struct StatT;
+
+struct Referrable;
+struct ReferrableT;
+
+struct Monster;
+struct MonsterT;
+
+struct TypeAliases;
+struct TypeAliasesT;
+
+}  // namespace Example
+
+bool operator==(const InParentNamespaceT &lhs, const InParentNamespaceT &rhs);
+bool operator!=(const InParentNamespaceT &lhs, const InParentNamespaceT &rhs);
+namespace Example2 {
+
+bool operator==(const MonsterT &lhs, const MonsterT &rhs);
+bool operator!=(const MonsterT &lhs, const MonsterT &rhs);
+}  // namespace Example2
+
+namespace Example {
+
+bool operator==(const Test &lhs, const Test &rhs);
+bool operator!=(const Test &lhs, const Test &rhs);
+bool operator==(const TestSimpleTableWithEnumT &lhs, const TestSimpleTableWithEnumT &rhs);
+bool operator!=(const TestSimpleTableWithEnumT &lhs, const TestSimpleTableWithEnumT &rhs);
+bool operator==(const Vec3 &lhs, const Vec3 &rhs);
+bool operator!=(const Vec3 &lhs, const Vec3 &rhs);
+bool operator==(const Ability &lhs, const Ability &rhs);
+bool operator!=(const Ability &lhs, const Ability &rhs);
+bool operator==(const StatT &lhs, const StatT &rhs);
+bool operator!=(const StatT &lhs, const StatT &rhs);
+bool operator==(const ReferrableT &lhs, const ReferrableT &rhs);
+bool operator!=(const ReferrableT &lhs, const ReferrableT &rhs);
+bool operator==(const MonsterT &lhs, const MonsterT &rhs);
+bool operator!=(const MonsterT &lhs, const MonsterT &rhs);
+bool operator==(const TypeAliasesT &lhs, const TypeAliasesT &rhs);
+bool operator!=(const TypeAliasesT &lhs, const TypeAliasesT &rhs);
+
+}  // namespace Example
+
+inline const flatbuffers::TypeTable *InParentNamespaceTypeTable();
+
+namespace Example2 {
+
+inline const flatbuffers::TypeTable *MonsterTypeTable();
+
+}  // namespace Example2
+
+namespace Example {
+
+inline const flatbuffers::TypeTable *TestTypeTable();
+
+inline const flatbuffers::TypeTable *TestSimpleTableWithEnumTypeTable();
+
+inline const flatbuffers::TypeTable *Vec3TypeTable();
+
+inline const flatbuffers::TypeTable *AbilityTypeTable();
+
+inline const flatbuffers::TypeTable *StatTypeTable();
+
+inline const flatbuffers::TypeTable *ReferrableTypeTable();
+
+inline const flatbuffers::TypeTable *MonsterTypeTable();
+
+inline const flatbuffers::TypeTable *TypeAliasesTypeTable();
+
+/// Composite components of Monster color.
+enum Color {
+  Color_Red = 1,
+  /// \brief color Green
+  /// Green is bit_flag with value (1u << 1)
+  Color_Green = 2,
+  /// \brief color Blue (1u << 3)
+  Color_Blue = 8,
+  Color_NONE = 0,
+  Color_ANY = 11
+};
+
+inline const Color (&EnumValuesColor())[3] {
+  static const Color values[] = {
+    Color_Red,
+    Color_Green,
+    Color_Blue
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesColor() {
+  static const char * const names[9] = {
+    "Red",
+    "Green",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "Blue",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameColor(Color e) {
+  if (e < Color_Red || e > Color_Blue) return "";
+  const size_t index = static_cast<size_t>(e) - static_cast<size_t>(Color_Red);
+  return EnumNamesColor()[index];
+}
+
+enum Any {
+  Any_NONE = 0,
+  Any_Monster = 1,
+  Any_TestSimpleTableWithEnum = 2,
+  Any_MyGame_Example2_Monster = 3,
+  Any_MIN = Any_NONE,
+  Any_MAX = Any_MyGame_Example2_Monster
+};
+
+inline const Any (&EnumValuesAny())[4] {
+  static const Any values[] = {
+    Any_NONE,
+    Any_Monster,
+    Any_TestSimpleTableWithEnum,
+    Any_MyGame_Example2_Monster
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesAny() {
+  static const char * const names[5] = {
+    "NONE",
+    "Monster",
+    "TestSimpleTableWithEnum",
+    "MyGame_Example2_Monster",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameAny(Any e) {
+  if (e < Any_NONE || e > Any_MyGame_Example2_Monster) return "";
+  const size_t index = static_cast<size_t>(e);
+  return EnumNamesAny()[index];
+}
+
+template<typename T> struct AnyTraits {
+  static const Any enum_value = Any_NONE;
+};
+
+template<> struct AnyTraits<MyGame::Example::Monster> {
+  static const Any enum_value = Any_Monster;
+};
+
+template<> struct AnyTraits<MyGame::Example::TestSimpleTableWithEnum> {
+  static const Any enum_value = Any_TestSimpleTableWithEnum;
+};
+
+template<> struct AnyTraits<MyGame::Example2::Monster> {
+  static const Any enum_value = Any_MyGame_Example2_Monster;
+};
+
+struct AnyUnion {
+  Any type;
+  void *value;
+
+  AnyUnion() : type(Any_NONE), value(nullptr) {}
+  AnyUnion(AnyUnion&& u) FLATBUFFERS_NOEXCEPT :
+    type(Any_NONE), value(nullptr)
+    { std::swap(type, u.type); std::swap(value, u.value); }
+  AnyUnion(const AnyUnion &) FLATBUFFERS_NOEXCEPT;
+  AnyUnion &operator=(const AnyUnion &u) FLATBUFFERS_NOEXCEPT
+    { AnyUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; }
+  AnyUnion &operator=(AnyUnion &&u) FLATBUFFERS_NOEXCEPT
+    { std::swap(type, u.type); std::swap(value, u.value); return *this; }
+  ~AnyUnion() { Reset(); }
+
+  void Reset();
+
+#ifndef FLATBUFFERS_CPP98_STL
+  template <typename T>
+  void Set(T&& val) {
+    using RT = typename std::remove_reference<T>::type;
+    Reset();
+    type = AnyTraits<typename RT::TableType>::enum_value;
+    if (type != Any_NONE) {
+      value = new RT(std::forward<T>(val));
+    }
+  }
+#endif  // FLATBUFFERS_CPP98_STL
+
+  static void *UnPack(const void *obj, Any type, const flatbuffers::resolver_function_t *resolver);
+  flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const;
+
+  MyGame::Example::MonsterT *AsMonster() {
+    return type == Any_Monster ?
+      reinterpret_cast<MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+  const MyGame::Example::MonsterT *AsMonster() const {
+    return type == Any_Monster ?
+      reinterpret_cast<const MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+  MyGame::Example::TestSimpleTableWithEnumT *AsTestSimpleTableWithEnum() {
+    return type == Any_TestSimpleTableWithEnum ?
+      reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(value) : nullptr;
+  }
+  const MyGame::Example::TestSimpleTableWithEnumT *AsTestSimpleTableWithEnum() const {
+    return type == Any_TestSimpleTableWithEnum ?
+      reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(value) : nullptr;
+  }
+  MyGame::Example2::MonsterT *AsMyGame_Example2_Monster() {
+    return type == Any_MyGame_Example2_Monster ?
+      reinterpret_cast<MyGame::Example2::MonsterT *>(value) : nullptr;
+  }
+  const MyGame::Example2::MonsterT *AsMyGame_Example2_Monster() const {
+    return type == Any_MyGame_Example2_Monster ?
+      reinterpret_cast<const MyGame::Example2::MonsterT *>(value) : nullptr;
+  }
+};
+
+
+inline bool operator==(const AnyUnion &lhs, const AnyUnion &rhs) {
+  if (lhs.type != rhs.type) return false;
+  switch (lhs.type) {
+    case Any_NONE: {
+      return true;
+    }
+    case Any_Monster: {
+      return *(reinterpret_cast<const MyGame::Example::MonsterT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Example::MonsterT *>(rhs.value));
+    }
+    case Any_TestSimpleTableWithEnum: {
+      return *(reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(rhs.value));
+    }
+    case Any_MyGame_Example2_Monster: {
+      return *(reinterpret_cast<const MyGame::Example2::MonsterT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Example2::MonsterT *>(rhs.value));
+    }
+    default: {
+      return false;
+    }
+  }
+}
+
+inline bool operator!=(const AnyUnion &lhs, const AnyUnion &rhs) {
+    return !(lhs == rhs);
+}
+
+bool VerifyAny(flatbuffers::Verifier &verifier, const void *obj, Any type);
+bool VerifyAnyVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);
+
+enum AnyUniqueAliases {
+  AnyUniqueAliases_NONE = 0,
+  AnyUniqueAliases_M = 1,
+  AnyUniqueAliases_TS = 2,
+  AnyUniqueAliases_M2 = 3,
+  AnyUniqueAliases_MIN = AnyUniqueAliases_NONE,
+  AnyUniqueAliases_MAX = AnyUniqueAliases_M2
+};
+
+inline const AnyUniqueAliases (&EnumValuesAnyUniqueAliases())[4] {
+  static const AnyUniqueAliases values[] = {
+    AnyUniqueAliases_NONE,
+    AnyUniqueAliases_M,
+    AnyUniqueAliases_TS,
+    AnyUniqueAliases_M2
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesAnyUniqueAliases() {
+  static const char * const names[5] = {
+    "NONE",
+    "M",
+    "TS",
+    "M2",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameAnyUniqueAliases(AnyUniqueAliases e) {
+  if (e < AnyUniqueAliases_NONE || e > AnyUniqueAliases_M2) return "";
+  const size_t index = static_cast<size_t>(e);
+  return EnumNamesAnyUniqueAliases()[index];
+}
+
+template<typename T> struct AnyUniqueAliasesTraits {
+  static const AnyUniqueAliases enum_value = AnyUniqueAliases_NONE;
+};
+
+template<> struct AnyUniqueAliasesTraits<MyGame::Example::Monster> {
+  static const AnyUniqueAliases enum_value = AnyUniqueAliases_M;
+};
+
+template<> struct AnyUniqueAliasesTraits<MyGame::Example::TestSimpleTableWithEnum> {
+  static const AnyUniqueAliases enum_value = AnyUniqueAliases_TS;
+};
+
+template<> struct AnyUniqueAliasesTraits<MyGame::Example2::Monster> {
+  static const AnyUniqueAliases enum_value = AnyUniqueAliases_M2;
+};
+
+struct AnyUniqueAliasesUnion {
+  AnyUniqueAliases type;
+  void *value;
+
+  AnyUniqueAliasesUnion() : type(AnyUniqueAliases_NONE), value(nullptr) {}
+  AnyUniqueAliasesUnion(AnyUniqueAliasesUnion&& u) FLATBUFFERS_NOEXCEPT :
+    type(AnyUniqueAliases_NONE), value(nullptr)
+    { std::swap(type, u.type); std::swap(value, u.value); }
+  AnyUniqueAliasesUnion(const AnyUniqueAliasesUnion &) FLATBUFFERS_NOEXCEPT;
+  AnyUniqueAliasesUnion &operator=(const AnyUniqueAliasesUnion &u) FLATBUFFERS_NOEXCEPT
+    { AnyUniqueAliasesUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; }
+  AnyUniqueAliasesUnion &operator=(AnyUniqueAliasesUnion &&u) FLATBUFFERS_NOEXCEPT
+    { std::swap(type, u.type); std::swap(value, u.value); return *this; }
+  ~AnyUniqueAliasesUnion() { Reset(); }
+
+  void Reset();
+
+#ifndef FLATBUFFERS_CPP98_STL
+  template <typename T>
+  void Set(T&& val) {
+    using RT = typename std::remove_reference<T>::type;
+    Reset();
+    type = AnyUniqueAliasesTraits<typename RT::TableType>::enum_value;
+    if (type != AnyUniqueAliases_NONE) {
+      value = new RT(std::forward<T>(val));
+    }
+  }
+#endif  // FLATBUFFERS_CPP98_STL
+
+  static void *UnPack(const void *obj, AnyUniqueAliases type, const flatbuffers::resolver_function_t *resolver);
+  flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const;
+
+  MyGame::Example::MonsterT *AsM() {
+    return type == AnyUniqueAliases_M ?
+      reinterpret_cast<MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+  const MyGame::Example::MonsterT *AsM() const {
+    return type == AnyUniqueAliases_M ?
+      reinterpret_cast<const MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+  MyGame::Example::TestSimpleTableWithEnumT *AsTS() {
+    return type == AnyUniqueAliases_TS ?
+      reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(value) : nullptr;
+  }
+  const MyGame::Example::TestSimpleTableWithEnumT *AsTS() const {
+    return type == AnyUniqueAliases_TS ?
+      reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(value) : nullptr;
+  }
+  MyGame::Example2::MonsterT *AsM2() {
+    return type == AnyUniqueAliases_M2 ?
+      reinterpret_cast<MyGame::Example2::MonsterT *>(value) : nullptr;
+  }
+  const MyGame::Example2::MonsterT *AsM2() const {
+    return type == AnyUniqueAliases_M2 ?
+      reinterpret_cast<const MyGame::Example2::MonsterT *>(value) : nullptr;
+  }
+};
+
+
+inline bool operator==(const AnyUniqueAliasesUnion &lhs, const AnyUniqueAliasesUnion &rhs) {
+  if (lhs.type != rhs.type) return false;
+  switch (lhs.type) {
+    case AnyUniqueAliases_NONE: {
+      return true;
+    }
+    case AnyUniqueAliases_M: {
+      return *(reinterpret_cast<const MyGame::Example::MonsterT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Example::MonsterT *>(rhs.value));
+    }
+    case AnyUniqueAliases_TS: {
+      return *(reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(rhs.value));
+    }
+    case AnyUniqueAliases_M2: {
+      return *(reinterpret_cast<const MyGame::Example2::MonsterT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Example2::MonsterT *>(rhs.value));
+    }
+    default: {
+      return false;
+    }
+  }
+}
+
+inline bool operator!=(const AnyUniqueAliasesUnion &lhs, const AnyUniqueAliasesUnion &rhs) {
+    return !(lhs == rhs);
+}
+
+bool VerifyAnyUniqueAliases(flatbuffers::Verifier &verifier, const void *obj, AnyUniqueAliases type);
+bool VerifyAnyUniqueAliasesVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);
+
+enum AnyAmbiguousAliases {
+  AnyAmbiguousAliases_NONE = 0,
+  AnyAmbiguousAliases_M1 = 1,
+  AnyAmbiguousAliases_M2 = 2,
+  AnyAmbiguousAliases_M3 = 3,
+  AnyAmbiguousAliases_MIN = AnyAmbiguousAliases_NONE,
+  AnyAmbiguousAliases_MAX = AnyAmbiguousAliases_M3
+};
+
+inline const AnyAmbiguousAliases (&EnumValuesAnyAmbiguousAliases())[4] {
+  static const AnyAmbiguousAliases values[] = {
+    AnyAmbiguousAliases_NONE,
+    AnyAmbiguousAliases_M1,
+    AnyAmbiguousAliases_M2,
+    AnyAmbiguousAliases_M3
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesAnyAmbiguousAliases() {
+  static const char * const names[5] = {
+    "NONE",
+    "M1",
+    "M2",
+    "M3",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameAnyAmbiguousAliases(AnyAmbiguousAliases e) {
+  if (e < AnyAmbiguousAliases_NONE || e > AnyAmbiguousAliases_M3) return "";
+  const size_t index = static_cast<size_t>(e);
+  return EnumNamesAnyAmbiguousAliases()[index];
+}
+
+struct AnyAmbiguousAliasesUnion {
+  AnyAmbiguousAliases type;
+  void *value;
+
+  AnyAmbiguousAliasesUnion() : type(AnyAmbiguousAliases_NONE), value(nullptr) {}
+  AnyAmbiguousAliasesUnion(AnyAmbiguousAliasesUnion&& u) FLATBUFFERS_NOEXCEPT :
+    type(AnyAmbiguousAliases_NONE), value(nullptr)
+    { std::swap(type, u.type); std::swap(value, u.value); }
+  AnyAmbiguousAliasesUnion(const AnyAmbiguousAliasesUnion &) FLATBUFFERS_NOEXCEPT;
+  AnyAmbiguousAliasesUnion &operator=(const AnyAmbiguousAliasesUnion &u) FLATBUFFERS_NOEXCEPT
+    { AnyAmbiguousAliasesUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; }
+  AnyAmbiguousAliasesUnion &operator=(AnyAmbiguousAliasesUnion &&u) FLATBUFFERS_NOEXCEPT
+    { std::swap(type, u.type); std::swap(value, u.value); return *this; }
+  ~AnyAmbiguousAliasesUnion() { Reset(); }
+
+  void Reset();
+
+  static void *UnPack(const void *obj, AnyAmbiguousAliases type, const flatbuffers::resolver_function_t *resolver);
+  flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const;
+
+  MyGame::Example::MonsterT *AsM1() {
+    return type == AnyAmbiguousAliases_M1 ?
+      reinterpret_cast<MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+  const MyGame::Example::MonsterT *AsM1() const {
+    return type == AnyAmbiguousAliases_M1 ?
+      reinterpret_cast<const MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+  MyGame::Example::MonsterT *AsM2() {
+    return type == AnyAmbiguousAliases_M2 ?
+      reinterpret_cast<MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+  const MyGame::Example::MonsterT *AsM2() const {
+    return type == AnyAmbiguousAliases_M2 ?
+      reinterpret_cast<const MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+  MyGame::Example::MonsterT *AsM3() {
+    return type == AnyAmbiguousAliases_M3 ?
+      reinterpret_cast<MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+  const MyGame::Example::MonsterT *AsM3() const {
+    return type == AnyAmbiguousAliases_M3 ?
+      reinterpret_cast<const MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+};
+
+
+inline bool operator==(const AnyAmbiguousAliasesUnion &lhs, const AnyAmbiguousAliasesUnion &rhs) {
+  if (lhs.type != rhs.type) return false;
+  switch (lhs.type) {
+    case AnyAmbiguousAliases_NONE: {
+      return true;
+    }
+    case AnyAmbiguousAliases_M1: {
+      return *(reinterpret_cast<const MyGame::Example::MonsterT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Example::MonsterT *>(rhs.value));
+    }
+    case AnyAmbiguousAliases_M2: {
+      return *(reinterpret_cast<const MyGame::Example::MonsterT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Example::MonsterT *>(rhs.value));
+    }
+    case AnyAmbiguousAliases_M3: {
+      return *(reinterpret_cast<const MyGame::Example::MonsterT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Example::MonsterT *>(rhs.value));
+    }
+    default: {
+      return false;
+    }
+  }
+}
+
+inline bool operator!=(const AnyAmbiguousAliasesUnion &lhs, const AnyAmbiguousAliasesUnion &rhs) {
+    return !(lhs == rhs);
+}
+
+bool VerifyAnyAmbiguousAliases(flatbuffers::Verifier &verifier, const void *obj, AnyAmbiguousAliases type);
+bool VerifyAnyAmbiguousAliasesVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(2) Test FLATBUFFERS_FINAL_CLASS {
+ private:
+  int16_t a_;
+  int8_t b_;
+  int8_t padding0__;
+
+ public:
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return TestTypeTable();
+  }
+  Test() {
+    memset(static_cast<void *>(this), 0, sizeof(Test));
+  }
+  Test(int16_t _a, int8_t _b)
+      : a_(flatbuffers::EndianScalar(_a)),
+        b_(flatbuffers::EndianScalar(_b)),
+        padding0__(0) {
+    (void)padding0__;
+  }
+  int16_t a() const {
+    return flatbuffers::EndianScalar(a_);
+  }
+  void mutate_a(int16_t _a) {
+    flatbuffers::WriteScalar(&a_, _a);
+  }
+  int8_t b() const {
+    return flatbuffers::EndianScalar(b_);
+  }
+  void mutate_b(int8_t _b) {
+    flatbuffers::WriteScalar(&b_, _b);
+  }
+};
+FLATBUFFERS_STRUCT_END(Test, 4);
+
+inline bool operator==(const Test &lhs, const Test &rhs) {
+  return
+      (lhs.a() == rhs.a()) &&
+      (lhs.b() == rhs.b());
+}
+
+inline bool operator!=(const Test &lhs, const Test &rhs) {
+    return !(lhs == rhs);
+}
+
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Vec3 FLATBUFFERS_FINAL_CLASS {
+ private:
+  float x_;
+  float y_;
+  float z_;
+  int32_t padding0__;
+  double test1_;
+  uint8_t test2_;
+  int8_t padding1__;
+  MyGame::Example::Test test3_;
+  int16_t padding2__;
+
+ public:
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return Vec3TypeTable();
+  }
+  Vec3() {
+    memset(static_cast<void *>(this), 0, sizeof(Vec3));
+  }
+  Vec3(float _x, float _y, float _z, double _test1, MyGame::Example::Color _test2, const MyGame::Example::Test &_test3)
+      : x_(flatbuffers::EndianScalar(_x)),
+        y_(flatbuffers::EndianScalar(_y)),
+        z_(flatbuffers::EndianScalar(_z)),
+        padding0__(0),
+        test1_(flatbuffers::EndianScalar(_test1)),
+        test2_(flatbuffers::EndianScalar(static_cast<uint8_t>(_test2))),
+        padding1__(0),
+        test3_(_test3),
+        padding2__(0) {
+    (void)padding0__;
+    (void)padding1__;
+    (void)padding2__;
+  }
+  float x() const {
+    return flatbuffers::EndianScalar(x_);
+  }
+  void mutate_x(float _x) {
+    flatbuffers::WriteScalar(&x_, _x);
+  }
+  float y() const {
+    return flatbuffers::EndianScalar(y_);
+  }
+  void mutate_y(float _y) {
+    flatbuffers::WriteScalar(&y_, _y);
+  }
+  float z() const {
+    return flatbuffers::EndianScalar(z_);
+  }
+  void mutate_z(float _z) {
+    flatbuffers::WriteScalar(&z_, _z);
+  }
+  double test1() const {
+    return flatbuffers::EndianScalar(test1_);
+  }
+  void mutate_test1(double _test1) {
+    flatbuffers::WriteScalar(&test1_, _test1);
+  }
+  MyGame::Example::Color test2() const {
+    return static_cast<MyGame::Example::Color>(flatbuffers::EndianScalar(test2_));
+  }
+  void mutate_test2(MyGame::Example::Color _test2) {
+    flatbuffers::WriteScalar(&test2_, static_cast<uint8_t>(_test2));
+  }
+  const MyGame::Example::Test &test3() const {
+    return test3_;
+  }
+  MyGame::Example::Test &mutable_test3() {
+    return test3_;
+  }
+};
+FLATBUFFERS_STRUCT_END(Vec3, 32);
+
+inline bool operator==(const Vec3 &lhs, const Vec3 &rhs) {
+  return
+      (lhs.x() == rhs.x()) &&
+      (lhs.y() == rhs.y()) &&
+      (lhs.z() == rhs.z()) &&
+      (lhs.test1() == rhs.test1()) &&
+      (lhs.test2() == rhs.test2()) &&
+      (lhs.test3() == rhs.test3());
+}
+
+inline bool operator!=(const Vec3 &lhs, const Vec3 &rhs) {
+    return !(lhs == rhs);
+}
+
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Ability FLATBUFFERS_FINAL_CLASS {
+ private:
+  uint32_t id_;
+  uint32_t distance_;
+
+ public:
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return AbilityTypeTable();
+  }
+  Ability() {
+    memset(static_cast<void *>(this), 0, sizeof(Ability));
+  }
+  Ability(uint32_t _id, uint32_t _distance)
+      : id_(flatbuffers::EndianScalar(_id)),
+        distance_(flatbuffers::EndianScalar(_distance)) {
+  }
+  uint32_t id() const {
+    return flatbuffers::EndianScalar(id_);
+  }
+  void mutate_id(uint32_t _id) {
+    flatbuffers::WriteScalar(&id_, _id);
+  }
+  bool KeyCompareLessThan(const Ability *o) const {
+    return id() < o->id();
+  }
+  int KeyCompareWithValue(uint32_t val) const {
+    return static_cast<int>(id() > val) - static_cast<int>(id() < val);
+  }
+  uint32_t distance() const {
+    return flatbuffers::EndianScalar(distance_);
+  }
+  void mutate_distance(uint32_t _distance) {
+    flatbuffers::WriteScalar(&distance_, _distance);
+  }
+};
+FLATBUFFERS_STRUCT_END(Ability, 8);
+
+inline bool operator==(const Ability &lhs, const Ability &rhs) {
+  return
+      (lhs.id() == rhs.id()) &&
+      (lhs.distance() == rhs.distance());
+}
+
+inline bool operator!=(const Ability &lhs, const Ability &rhs) {
+    return !(lhs == rhs);
+}
+
+
+}  // namespace Example
+
+struct InParentNamespaceT : public flatbuffers::NativeTable {
+  typedef InParentNamespace TableType;
+  InParentNamespaceT() {
+  }
+};
+
+inline bool operator==(const InParentNamespaceT &, const InParentNamespaceT &) {
+  return true;
+}
+
+inline bool operator!=(const InParentNamespaceT &lhs, const InParentNamespaceT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct InParentNamespace FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef InParentNamespaceT NativeTableType;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return InParentNamespaceTypeTable();
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           verifier.EndTable();
+  }
+  InParentNamespaceT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(InParentNamespaceT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<InParentNamespace> Pack(flatbuffers::FlatBufferBuilder &_fbb, const InParentNamespaceT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct InParentNamespaceBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  explicit InParentNamespaceBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  InParentNamespaceBuilder &operator=(const InParentNamespaceBuilder &);
+  flatbuffers::Offset<InParentNamespace> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<InParentNamespace>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<InParentNamespace> CreateInParentNamespace(
+    flatbuffers::FlatBufferBuilder &_fbb) {
+  InParentNamespaceBuilder builder_(_fbb);
+  return builder_.Finish();
+}
+
+flatbuffers::Offset<InParentNamespace> CreateInParentNamespace(flatbuffers::FlatBufferBuilder &_fbb, const InParentNamespaceT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+namespace Example2 {
+
+struct MonsterT : public flatbuffers::NativeTable {
+  typedef Monster TableType;
+  MonsterT() {
+  }
+};
+
+inline bool operator==(const MonsterT &, const MonsterT &) {
+  return true;
+}
+
+inline bool operator!=(const MonsterT &lhs, const MonsterT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef MonsterT NativeTableType;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return MonsterTypeTable();
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           verifier.EndTable();
+  }
+  MonsterT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<Monster> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct MonsterBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  explicit MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  MonsterBuilder &operator=(const MonsterBuilder &);
+  flatbuffers::Offset<Monster> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Monster>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Monster> CreateMonster(
+    flatbuffers::FlatBufferBuilder &_fbb) {
+  MonsterBuilder builder_(_fbb);
+  return builder_.Finish();
+}
+
+flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+}  // namespace Example2
+
+namespace Example {
+
+struct TestSimpleTableWithEnumT : public flatbuffers::NativeTable {
+  typedef TestSimpleTableWithEnum TableType;
+  MyGame::Example::Color color;
+  TestSimpleTableWithEnumT()
+      : color(MyGame::Example::Color_Green) {
+  }
+};
+
+inline bool operator==(const TestSimpleTableWithEnumT &lhs, const TestSimpleTableWithEnumT &rhs) {
+  return
+      (lhs.color == rhs.color);
+}
+
+inline bool operator!=(const TestSimpleTableWithEnumT &lhs, const TestSimpleTableWithEnumT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct TestSimpleTableWithEnum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef TestSimpleTableWithEnumT NativeTableType;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return TestSimpleTableWithEnumTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_COLOR = 4
+  };
+  MyGame::Example::Color color() const {
+    return static_cast<MyGame::Example::Color>(GetField<uint8_t>(VT_COLOR, 2));
+  }
+  bool mutate_color(MyGame::Example::Color _color) {
+    return SetField<uint8_t>(VT_COLOR, static_cast<uint8_t>(_color), 2);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<uint8_t>(verifier, VT_COLOR) &&
+           verifier.EndTable();
+  }
+  TestSimpleTableWithEnumT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(TestSimpleTableWithEnumT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<TestSimpleTableWithEnum> Pack(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct TestSimpleTableWithEnumBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_color(MyGame::Example::Color color) {
+    fbb_.AddElement<uint8_t>(TestSimpleTableWithEnum::VT_COLOR, static_cast<uint8_t>(color), 2);
+  }
+  explicit TestSimpleTableWithEnumBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  TestSimpleTableWithEnumBuilder &operator=(const TestSimpleTableWithEnumBuilder &);
+  flatbuffers::Offset<TestSimpleTableWithEnum> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<TestSimpleTableWithEnum>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    MyGame::Example::Color color = MyGame::Example::Color_Green) {
+  TestSimpleTableWithEnumBuilder builder_(_fbb);
+  builder_.add_color(color);
+  return builder_.Finish();
+}
+
+flatbuffers::Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+struct StatT : public flatbuffers::NativeTable {
+  typedef Stat TableType;
+  std::string id;
+  int64_t val;
+  uint16_t count;
+  StatT()
+      : val(0),
+        count(0) {
+  }
+};
+
+inline bool operator==(const StatT &lhs, const StatT &rhs) {
+  return
+      (lhs.id == rhs.id) &&
+      (lhs.val == rhs.val) &&
+      (lhs.count == rhs.count);
+}
+
+inline bool operator!=(const StatT &lhs, const StatT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct Stat FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef StatT NativeTableType;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return StatTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_ID = 4,
+    VT_VAL = 6,
+    VT_COUNT = 8
+  };
+  const flatbuffers::String *id() const {
+    return GetPointer<const flatbuffers::String *>(VT_ID);
+  }
+  flatbuffers::String *mutable_id() {
+    return GetPointer<flatbuffers::String *>(VT_ID);
+  }
+  int64_t val() const {
+    return GetField<int64_t>(VT_VAL, 0);
+  }
+  bool mutate_val(int64_t _val) {
+    return SetField<int64_t>(VT_VAL, _val, 0);
+  }
+  uint16_t count() const {
+    return GetField<uint16_t>(VT_COUNT, 0);
+  }
+  bool mutate_count(uint16_t _count) {
+    return SetField<uint16_t>(VT_COUNT, _count, 0);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffset(verifier, VT_ID) &&
+           verifier.VerifyString(id()) &&
+           VerifyField<int64_t>(verifier, VT_VAL) &&
+           VerifyField<uint16_t>(verifier, VT_COUNT) &&
+           verifier.EndTable();
+  }
+  StatT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(StatT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<Stat> Pack(flatbuffers::FlatBufferBuilder &_fbb, const StatT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct StatBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_id(flatbuffers::Offset<flatbuffers::String> id) {
+    fbb_.AddOffset(Stat::VT_ID, id);
+  }
+  void add_val(int64_t val) {
+    fbb_.AddElement<int64_t>(Stat::VT_VAL, val, 0);
+  }
+  void add_count(uint16_t count) {
+    fbb_.AddElement<uint16_t>(Stat::VT_COUNT, count, 0);
+  }
+  explicit StatBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  StatBuilder &operator=(const StatBuilder &);
+  flatbuffers::Offset<Stat> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Stat>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Stat> CreateStat(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<flatbuffers::String> id = 0,
+    int64_t val = 0,
+    uint16_t count = 0) {
+  StatBuilder builder_(_fbb);
+  builder_.add_val(val);
+  builder_.add_id(id);
+  builder_.add_count(count);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Stat> CreateStatDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const char *id = nullptr,
+    int64_t val = 0,
+    uint16_t count = 0) {
+  auto id__ = id ? _fbb.CreateString(id) : 0;
+  return MyGame::Example::CreateStat(
+      _fbb,
+      id__,
+      val,
+      count);
+}
+
+flatbuffers::Offset<Stat> CreateStat(flatbuffers::FlatBufferBuilder &_fbb, const StatT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+struct ReferrableT : public flatbuffers::NativeTable {
+  typedef Referrable TableType;
+  uint64_t id;
+  ReferrableT()
+      : id(0) {
+  }
+};
+
+inline bool operator==(const ReferrableT &lhs, const ReferrableT &rhs) {
+  return
+      (lhs.id == rhs.id);
+}
+
+inline bool operator!=(const ReferrableT &lhs, const ReferrableT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct Referrable FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef ReferrableT NativeTableType;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return ReferrableTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_ID = 4
+  };
+  uint64_t id() const {
+    return GetField<uint64_t>(VT_ID, 0);
+  }
+  bool mutate_id(uint64_t _id) {
+    return SetField<uint64_t>(VT_ID, _id, 0);
+  }
+  bool KeyCompareLessThan(const Referrable *o) const {
+    return id() < o->id();
+  }
+  int KeyCompareWithValue(uint64_t val) const {
+    return static_cast<int>(id() > val) - static_cast<int>(id() < val);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<uint64_t>(verifier, VT_ID) &&
+           verifier.EndTable();
+  }
+  ReferrableT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(ReferrableT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<Referrable> Pack(flatbuffers::FlatBufferBuilder &_fbb, const ReferrableT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct ReferrableBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_id(uint64_t id) {
+    fbb_.AddElement<uint64_t>(Referrable::VT_ID, id, 0);
+  }
+  explicit ReferrableBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  ReferrableBuilder &operator=(const ReferrableBuilder &);
+  flatbuffers::Offset<Referrable> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Referrable>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Referrable> CreateReferrable(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    uint64_t id = 0) {
+  ReferrableBuilder builder_(_fbb);
+  builder_.add_id(id);
+  return builder_.Finish();
+}
+
+flatbuffers::Offset<Referrable> CreateReferrable(flatbuffers::FlatBufferBuilder &_fbb, const ReferrableT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+struct MonsterT : public flatbuffers::NativeTable {
+  typedef Monster TableType;
+  flatbuffers::unique_ptr<MyGame::Example::Vec3> pos;
+  int16_t mana;
+  int16_t hp;
+  std::string name;
+  std::vector<uint8_t> inventory;
+  MyGame::Example::Color color;
+  AnyUnion test;
+  std::vector<MyGame::Example::Test> test4;
+  std::vector<std::string> testarrayofstring;
+  std::vector<flatbuffers::unique_ptr<MyGame::Example::MonsterT>> testarrayoftables;
+  flatbuffers::unique_ptr<MyGame::Example::MonsterT> enemy;
+  std::vector<uint8_t> testnestedflatbuffer;
+  flatbuffers::unique_ptr<MyGame::Example::StatT> testempty;
+  bool testbool;
+  int32_t testhashs32_fnv1;
+  uint32_t testhashu32_fnv1;
+  int64_t testhashs64_fnv1;
+  uint64_t testhashu64_fnv1;
+  int32_t testhashs32_fnv1a;
+  Stat *testhashu32_fnv1a;
+  int64_t testhashs64_fnv1a;
+  uint64_t testhashu64_fnv1a;
+  std::vector<bool> testarrayofbools;
+  float testf;
+  float testf2;
+  float testf3;
+  std::vector<std::string> testarrayofstring2;
+  std::vector<MyGame::Example::Ability> testarrayofsortedstruct;
+  std::vector<uint8_t> flex;
+  std::vector<MyGame::Example::Test> test5;
+  std::vector<int64_t> vector_of_longs;
+  std::vector<double> vector_of_doubles;
+  flatbuffers::unique_ptr<MyGame::InParentNamespaceT> parent_namespace_test;
+  std::vector<flatbuffers::unique_ptr<MyGame::Example::ReferrableT>> vector_of_referrables;
+  ReferrableT *single_weak_reference;
+  std::vector<ReferrableT *> vector_of_weak_references;
+  std::vector<flatbuffers::unique_ptr<MyGame::Example::ReferrableT>> vector_of_strong_referrables;
+  ReferrableT *co_owning_reference;
+  std::vector<flatbuffers::unique_ptr<ReferrableT>> vector_of_co_owning_references;
+  ReferrableT *non_owning_reference;
+  std::vector<ReferrableT *> vector_of_non_owning_references;
+  AnyUniqueAliasesUnion any_unique;
+  AnyAmbiguousAliasesUnion any_ambiguous;
+  std::vector<MyGame::Example::Color> vector_of_enums;
+  MonsterT()
+      : mana(150),
+        hp(100),
+        color(MyGame::Example::Color_Blue),
+        testbool(false),
+        testhashs32_fnv1(0),
+        testhashu32_fnv1(0),
+        testhashs64_fnv1(0),
+        testhashu64_fnv1(0),
+        testhashs32_fnv1a(0),
+        testhashu32_fnv1a(nullptr),
+        testhashs64_fnv1a(0),
+        testhashu64_fnv1a(0),
+        testf(3.14159f),
+        testf2(3.0f),
+        testf3(0.0f),
+        single_weak_reference(nullptr),
+        co_owning_reference(nullptr),
+        non_owning_reference(nullptr) {
+  }
+};
+
+inline bool operator==(const MonsterT &lhs, const MonsterT &rhs) {
+  return
+      (lhs.pos == rhs.pos) &&
+      (lhs.mana == rhs.mana) &&
+      (lhs.hp == rhs.hp) &&
+      (lhs.name == rhs.name) &&
+      (lhs.inventory == rhs.inventory) &&
+      (lhs.color == rhs.color) &&
+      (lhs.test == rhs.test) &&
+      (lhs.test4 == rhs.test4) &&
+      (lhs.testarrayofstring == rhs.testarrayofstring) &&
+      (lhs.testarrayoftables == rhs.testarrayoftables) &&
+      (lhs.enemy == rhs.enemy) &&
+      (lhs.testnestedflatbuffer == rhs.testnestedflatbuffer) &&
+      (lhs.testempty == rhs.testempty) &&
+      (lhs.testbool == rhs.testbool) &&
+      (lhs.testhashs32_fnv1 == rhs.testhashs32_fnv1) &&
+      (lhs.testhashu32_fnv1 == rhs.testhashu32_fnv1) &&
+      (lhs.testhashs64_fnv1 == rhs.testhashs64_fnv1) &&
+      (lhs.testhashu64_fnv1 == rhs.testhashu64_fnv1) &&
+      (lhs.testhashs32_fnv1a == rhs.testhashs32_fnv1a) &&
+      (lhs.testhashu32_fnv1a == rhs.testhashu32_fnv1a) &&
+      (lhs.testhashs64_fnv1a == rhs.testhashs64_fnv1a) &&
+      (lhs.testhashu64_fnv1a == rhs.testhashu64_fnv1a) &&
+      (lhs.testarrayofbools == rhs.testarrayofbools) &&
+      (lhs.testf == rhs.testf) &&
+      (lhs.testf2 == rhs.testf2) &&
+      (lhs.testf3 == rhs.testf3) &&
+      (lhs.testarrayofstring2 == rhs.testarrayofstring2) &&
+      (lhs.testarrayofsortedstruct == rhs.testarrayofsortedstruct) &&
+      (lhs.flex == rhs.flex) &&
+      (lhs.test5 == rhs.test5) &&
+      (lhs.vector_of_longs == rhs.vector_of_longs) &&
+      (lhs.vector_of_doubles == rhs.vector_of_doubles) &&
+      (lhs.parent_namespace_test == rhs.parent_namespace_test) &&
+      (lhs.vector_of_referrables == rhs.vector_of_referrables) &&
+      (lhs.single_weak_reference == rhs.single_weak_reference) &&
+      (lhs.vector_of_weak_references == rhs.vector_of_weak_references) &&
+      (lhs.vector_of_strong_referrables == rhs.vector_of_strong_referrables) &&
+      (lhs.co_owning_reference == rhs.co_owning_reference) &&
+      (lhs.vector_of_co_owning_references == rhs.vector_of_co_owning_references) &&
+      (lhs.non_owning_reference == rhs.non_owning_reference) &&
+      (lhs.vector_of_non_owning_references == rhs.vector_of_non_owning_references) &&
+      (lhs.any_unique == rhs.any_unique) &&
+      (lhs.any_ambiguous == rhs.any_ambiguous) &&
+      (lhs.vector_of_enums == rhs.vector_of_enums);
+}
+
+inline bool operator!=(const MonsterT &lhs, const MonsterT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+/// an example documentation comment: monster object
+struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef MonsterT NativeTableType;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return MonsterTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_POS = 4,
+    VT_MANA = 6,
+    VT_HP = 8,
+    VT_NAME = 10,
+    VT_INVENTORY = 14,
+    VT_COLOR = 16,
+    VT_TEST_TYPE = 18,
+    VT_TEST = 20,
+    VT_TEST4 = 22,
+    VT_TESTARRAYOFSTRING = 24,
+    VT_TESTARRAYOFTABLES = 26,
+    VT_ENEMY = 28,
+    VT_TESTNESTEDFLATBUFFER = 30,
+    VT_TESTEMPTY = 32,
+    VT_TESTBOOL = 34,
+    VT_TESTHASHS32_FNV1 = 36,
+    VT_TESTHASHU32_FNV1 = 38,
+    VT_TESTHASHS64_FNV1 = 40,
+    VT_TESTHASHU64_FNV1 = 42,
+    VT_TESTHASHS32_FNV1A = 44,
+    VT_TESTHASHU32_FNV1A = 46,
+    VT_TESTHASHS64_FNV1A = 48,
+    VT_TESTHASHU64_FNV1A = 50,
+    VT_TESTARRAYOFBOOLS = 52,
+    VT_TESTF = 54,
+    VT_TESTF2 = 56,
+    VT_TESTF3 = 58,
+    VT_TESTARRAYOFSTRING2 = 60,
+    VT_TESTARRAYOFSORTEDSTRUCT = 62,
+    VT_FLEX = 64,
+    VT_TEST5 = 66,
+    VT_VECTOR_OF_LONGS = 68,
+    VT_VECTOR_OF_DOUBLES = 70,
+    VT_PARENT_NAMESPACE_TEST = 72,
+    VT_VECTOR_OF_REFERRABLES = 74,
+    VT_SINGLE_WEAK_REFERENCE = 76,
+    VT_VECTOR_OF_WEAK_REFERENCES = 78,
+    VT_VECTOR_OF_STRONG_REFERRABLES = 80,
+    VT_CO_OWNING_REFERENCE = 82,
+    VT_VECTOR_OF_CO_OWNING_REFERENCES = 84,
+    VT_NON_OWNING_REFERENCE = 86,
+    VT_VECTOR_OF_NON_OWNING_REFERENCES = 88,
+    VT_ANY_UNIQUE_TYPE = 90,
+    VT_ANY_UNIQUE = 92,
+    VT_ANY_AMBIGUOUS_TYPE = 94,
+    VT_ANY_AMBIGUOUS = 96,
+    VT_VECTOR_OF_ENUMS = 98
+  };
+  const MyGame::Example::Vec3 *pos() const {
+    return GetStruct<const MyGame::Example::Vec3 *>(VT_POS);
+  }
+  MyGame::Example::Vec3 *mutable_pos() {
+    return GetStruct<MyGame::Example::Vec3 *>(VT_POS);
+  }
+  int16_t mana() const {
+    return GetField<int16_t>(VT_MANA, 150);
+  }
+  bool mutate_mana(int16_t _mana) {
+    return SetField<int16_t>(VT_MANA, _mana, 150);
+  }
+  int16_t hp() const {
+    return GetField<int16_t>(VT_HP, 100);
+  }
+  bool mutate_hp(int16_t _hp) {
+    return SetField<int16_t>(VT_HP, _hp, 100);
+  }
+  const flatbuffers::String *name() const {
+    return GetPointer<const flatbuffers::String *>(VT_NAME);
+  }
+  flatbuffers::String *mutable_name() {
+    return GetPointer<flatbuffers::String *>(VT_NAME);
+  }
+  bool KeyCompareLessThan(const Monster *o) const {
+    return *name() < *o->name();
+  }
+  int KeyCompareWithValue(const char *val) const {
+    return strcmp(name()->c_str(), val);
+  }
+  const flatbuffers::Vector<uint8_t> *inventory() const {
+    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_INVENTORY);
+  }
+  flatbuffers::Vector<uint8_t> *mutable_inventory() {
+    return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_INVENTORY);
+  }
+  MyGame::Example::Color color() const {
+    return static_cast<MyGame::Example::Color>(GetField<uint8_t>(VT_COLOR, 8));
+  }
+  bool mutate_color(MyGame::Example::Color _color) {
+    return SetField<uint8_t>(VT_COLOR, static_cast<uint8_t>(_color), 8);
+  }
+  MyGame::Example::Any test_type() const {
+    return static_cast<MyGame::Example::Any>(GetField<uint8_t>(VT_TEST_TYPE, 0));
+  }
+  bool mutate_test_type(MyGame::Example::Any _test_type) {
+    return SetField<uint8_t>(VT_TEST_TYPE, static_cast<uint8_t>(_test_type), 0);
+  }
+  const void *test() const {
+    return GetPointer<const void *>(VT_TEST);
+  }
+  template<typename T> const T *test_as() const;
+  const MyGame::Example::Monster *test_as_Monster() const {
+    return test_type() == MyGame::Example::Any_Monster ? static_cast<const MyGame::Example::Monster *>(test()) : nullptr;
+  }
+  const MyGame::Example::TestSimpleTableWithEnum *test_as_TestSimpleTableWithEnum() const {
+    return test_type() == MyGame::Example::Any_TestSimpleTableWithEnum ? static_cast<const MyGame::Example::TestSimpleTableWithEnum *>(test()) : nullptr;
+  }
+  const MyGame::Example2::Monster *test_as_MyGame_Example2_Monster() const {
+    return test_type() == MyGame::Example::Any_MyGame_Example2_Monster ? static_cast<const MyGame::Example2::Monster *>(test()) : nullptr;
+  }
+  void *mutable_test() {
+    return GetPointer<void *>(VT_TEST);
+  }
+  const flatbuffers::Vector<const MyGame::Example::Test *> *test4() const {
+    return GetPointer<const flatbuffers::Vector<const MyGame::Example::Test *> *>(VT_TEST4);
+  }
+  flatbuffers::Vector<const MyGame::Example::Test *> *mutable_test4() {
+    return GetPointer<flatbuffers::Vector<const MyGame::Example::Test *> *>(VT_TEST4);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *testarrayofstring() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_TESTARRAYOFSTRING);
+  }
+  flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *mutable_testarrayofstring() {
+    return GetPointer<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_TESTARRAYOFSTRING);
+  }
+  /// an example documentation comment: this will end up in the generated code
+  /// multiline too
+  const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>> *testarrayoftables() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>> *>(VT_TESTARRAYOFTABLES);
+  }
+  flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>> *mutable_testarrayoftables() {
+    return GetPointer<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>> *>(VT_TESTARRAYOFTABLES);
+  }
+  const MyGame::Example::Monster *enemy() const {
+    return GetPointer<const MyGame::Example::Monster *>(VT_ENEMY);
+  }
+  MyGame::Example::Monster *mutable_enemy() {
+    return GetPointer<MyGame::Example::Monster *>(VT_ENEMY);
+  }
+  const flatbuffers::Vector<uint8_t> *testnestedflatbuffer() const {
+    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_TESTNESTEDFLATBUFFER);
+  }
+  flatbuffers::Vector<uint8_t> *mutable_testnestedflatbuffer() {
+    return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_TESTNESTEDFLATBUFFER);
+  }
+  const MyGame::Example::Monster *testnestedflatbuffer_nested_root() const {
+    return flatbuffers::GetRoot<MyGame::Example::Monster>(testnestedflatbuffer()->Data());
+  }
+  const MyGame::Example::Stat *testempty() const {
+    return GetPointer<const MyGame::Example::Stat *>(VT_TESTEMPTY);
+  }
+  MyGame::Example::Stat *mutable_testempty() {
+    return GetPointer<MyGame::Example::Stat *>(VT_TESTEMPTY);
+  }
+  bool testbool() const {
+    return GetField<uint8_t>(VT_TESTBOOL, 0) != 0;
+  }
+  bool mutate_testbool(bool _testbool) {
+    return SetField<uint8_t>(VT_TESTBOOL, static_cast<uint8_t>(_testbool), 0);
+  }
+  int32_t testhashs32_fnv1() const {
+    return GetField<int32_t>(VT_TESTHASHS32_FNV1, 0);
+  }
+  bool mutate_testhashs32_fnv1(int32_t _testhashs32_fnv1) {
+    return SetField<int32_t>(VT_TESTHASHS32_FNV1, _testhashs32_fnv1, 0);
+  }
+  uint32_t testhashu32_fnv1() const {
+    return GetField<uint32_t>(VT_TESTHASHU32_FNV1, 0);
+  }
+  bool mutate_testhashu32_fnv1(uint32_t _testhashu32_fnv1) {
+    return SetField<uint32_t>(VT_TESTHASHU32_FNV1, _testhashu32_fnv1, 0);
+  }
+  int64_t testhashs64_fnv1() const {
+    return GetField<int64_t>(VT_TESTHASHS64_FNV1, 0);
+  }
+  bool mutate_testhashs64_fnv1(int64_t _testhashs64_fnv1) {
+    return SetField<int64_t>(VT_TESTHASHS64_FNV1, _testhashs64_fnv1, 0);
+  }
+  uint64_t testhashu64_fnv1() const {
+    return GetField<uint64_t>(VT_TESTHASHU64_FNV1, 0);
+  }
+  bool mutate_testhashu64_fnv1(uint64_t _testhashu64_fnv1) {
+    return SetField<uint64_t>(VT_TESTHASHU64_FNV1, _testhashu64_fnv1, 0);
+  }
+  int32_t testhashs32_fnv1a() const {
+    return GetField<int32_t>(VT_TESTHASHS32_FNV1A, 0);
+  }
+  bool mutate_testhashs32_fnv1a(int32_t _testhashs32_fnv1a) {
+    return SetField<int32_t>(VT_TESTHASHS32_FNV1A, _testhashs32_fnv1a, 0);
+  }
+  uint32_t testhashu32_fnv1a() const {
+    return GetField<uint32_t>(VT_TESTHASHU32_FNV1A, 0);
+  }
+  bool mutate_testhashu32_fnv1a(uint32_t _testhashu32_fnv1a) {
+    return SetField<uint32_t>(VT_TESTHASHU32_FNV1A, _testhashu32_fnv1a, 0);
+  }
+  int64_t testhashs64_fnv1a() const {
+    return GetField<int64_t>(VT_TESTHASHS64_FNV1A, 0);
+  }
+  bool mutate_testhashs64_fnv1a(int64_t _testhashs64_fnv1a) {
+    return SetField<int64_t>(VT_TESTHASHS64_FNV1A, _testhashs64_fnv1a, 0);
+  }
+  uint64_t testhashu64_fnv1a() const {
+    return GetField<uint64_t>(VT_TESTHASHU64_FNV1A, 0);
+  }
+  bool mutate_testhashu64_fnv1a(uint64_t _testhashu64_fnv1a) {
+    return SetField<uint64_t>(VT_TESTHASHU64_FNV1A, _testhashu64_fnv1a, 0);
+  }
+  const flatbuffers::Vector<uint8_t> *testarrayofbools() const {
+    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_TESTARRAYOFBOOLS);
+  }
+  flatbuffers::Vector<uint8_t> *mutable_testarrayofbools() {
+    return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_TESTARRAYOFBOOLS);
+  }
+  float testf() const {
+    return GetField<float>(VT_TESTF, 3.14159f);
+  }
+  bool mutate_testf(float _testf) {
+    return SetField<float>(VT_TESTF, _testf, 3.14159f);
+  }
+  float testf2() const {
+    return GetField<float>(VT_TESTF2, 3.0f);
+  }
+  bool mutate_testf2(float _testf2) {
+    return SetField<float>(VT_TESTF2, _testf2, 3.0f);
+  }
+  float testf3() const {
+    return GetField<float>(VT_TESTF3, 0.0f);
+  }
+  bool mutate_testf3(float _testf3) {
+    return SetField<float>(VT_TESTF3, _testf3, 0.0f);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *testarrayofstring2() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_TESTARRAYOFSTRING2);
+  }
+  flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *mutable_testarrayofstring2() {
+    return GetPointer<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_TESTARRAYOFSTRING2);
+  }
+  const flatbuffers::Vector<const MyGame::Example::Ability *> *testarrayofsortedstruct() const {
+    return GetPointer<const flatbuffers::Vector<const MyGame::Example::Ability *> *>(VT_TESTARRAYOFSORTEDSTRUCT);
+  }
+  flatbuffers::Vector<const MyGame::Example::Ability *> *mutable_testarrayofsortedstruct() {
+    return GetPointer<flatbuffers::Vector<const MyGame::Example::Ability *> *>(VT_TESTARRAYOFSORTEDSTRUCT);
+  }
+  const flatbuffers::Vector<uint8_t> *flex() const {
+    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_FLEX);
+  }
+  flatbuffers::Vector<uint8_t> *mutable_flex() {
+    return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_FLEX);
+  }
+  flexbuffers::Reference flex_flexbuffer_root() const {
+    return flexbuffers::GetRoot(flex()->Data(), flex()->size());
+  }
+  const flatbuffers::Vector<const MyGame::Example::Test *> *test5() const {
+    return GetPointer<const flatbuffers::Vector<const MyGame::Example::Test *> *>(VT_TEST5);
+  }
+  flatbuffers::Vector<const MyGame::Example::Test *> *mutable_test5() {
+    return GetPointer<flatbuffers::Vector<const MyGame::Example::Test *> *>(VT_TEST5);
+  }
+  const flatbuffers::Vector<int64_t> *vector_of_longs() const {
+    return GetPointer<const flatbuffers::Vector<int64_t> *>(VT_VECTOR_OF_LONGS);
+  }
+  flatbuffers::Vector<int64_t> *mutable_vector_of_longs() {
+    return GetPointer<flatbuffers::Vector<int64_t> *>(VT_VECTOR_OF_LONGS);
+  }
+  const flatbuffers::Vector<double> *vector_of_doubles() const {
+    return GetPointer<const flatbuffers::Vector<double> *>(VT_VECTOR_OF_DOUBLES);
+  }
+  flatbuffers::Vector<double> *mutable_vector_of_doubles() {
+    return GetPointer<flatbuffers::Vector<double> *>(VT_VECTOR_OF_DOUBLES);
+  }
+  const MyGame::InParentNamespace *parent_namespace_test() const {
+    return GetPointer<const MyGame::InParentNamespace *>(VT_PARENT_NAMESPACE_TEST);
+  }
+  MyGame::InParentNamespace *mutable_parent_namespace_test() {
+    return GetPointer<MyGame::InParentNamespace *>(VT_PARENT_NAMESPACE_TEST);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *vector_of_referrables() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *>(VT_VECTOR_OF_REFERRABLES);
+  }
+  flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *mutable_vector_of_referrables() {
+    return GetPointer<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *>(VT_VECTOR_OF_REFERRABLES);
+  }
+  uint64_t single_weak_reference() const {
+    return GetField<uint64_t>(VT_SINGLE_WEAK_REFERENCE, 0);
+  }
+  bool mutate_single_weak_reference(uint64_t _single_weak_reference) {
+    return SetField<uint64_t>(VT_SINGLE_WEAK_REFERENCE, _single_weak_reference, 0);
+  }
+  const flatbuffers::Vector<uint64_t> *vector_of_weak_references() const {
+    return GetPointer<const flatbuffers::Vector<uint64_t> *>(VT_VECTOR_OF_WEAK_REFERENCES);
+  }
+  flatbuffers::Vector<uint64_t> *mutable_vector_of_weak_references() {
+    return GetPointer<flatbuffers::Vector<uint64_t> *>(VT_VECTOR_OF_WEAK_REFERENCES);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *vector_of_strong_referrables() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *>(VT_VECTOR_OF_STRONG_REFERRABLES);
+  }
+  flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *mutable_vector_of_strong_referrables() {
+    return GetPointer<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *>(VT_VECTOR_OF_STRONG_REFERRABLES);
+  }
+  uint64_t co_owning_reference() const {
+    return GetField<uint64_t>(VT_CO_OWNING_REFERENCE, 0);
+  }
+  bool mutate_co_owning_reference(uint64_t _co_owning_reference) {
+    return SetField<uint64_t>(VT_CO_OWNING_REFERENCE, _co_owning_reference, 0);
+  }
+  const flatbuffers::Vector<uint64_t> *vector_of_co_owning_references() const {
+    return GetPointer<const flatbuffers::Vector<uint64_t> *>(VT_VECTOR_OF_CO_OWNING_REFERENCES);
+  }
+  flatbuffers::Vector<uint64_t> *mutable_vector_of_co_owning_references() {
+    return GetPointer<flatbuffers::Vector<uint64_t> *>(VT_VECTOR_OF_CO_OWNING_REFERENCES);
+  }
+  uint64_t non_owning_reference() const {
+    return GetField<uint64_t>(VT_NON_OWNING_REFERENCE, 0);
+  }
+  bool mutate_non_owning_reference(uint64_t _non_owning_reference) {
+    return SetField<uint64_t>(VT_NON_OWNING_REFERENCE, _non_owning_reference, 0);
+  }
+  const flatbuffers::Vector<uint64_t> *vector_of_non_owning_references() const {
+    return GetPointer<const flatbuffers::Vector<uint64_t> *>(VT_VECTOR_OF_NON_OWNING_REFERENCES);
+  }
+  flatbuffers::Vector<uint64_t> *mutable_vector_of_non_owning_references() {
+    return GetPointer<flatbuffers::Vector<uint64_t> *>(VT_VECTOR_OF_NON_OWNING_REFERENCES);
+  }
+  MyGame::Example::AnyUniqueAliases any_unique_type() const {
+    return static_cast<MyGame::Example::AnyUniqueAliases>(GetField<uint8_t>(VT_ANY_UNIQUE_TYPE, 0));
+  }
+  bool mutate_any_unique_type(MyGame::Example::AnyUniqueAliases _any_unique_type) {
+    return SetField<uint8_t>(VT_ANY_UNIQUE_TYPE, static_cast<uint8_t>(_any_unique_type), 0);
+  }
+  const void *any_unique() const {
+    return GetPointer<const void *>(VT_ANY_UNIQUE);
+  }
+  template<typename T> const T *any_unique_as() const;
+  const MyGame::Example::Monster *any_unique_as_M() const {
+    return any_unique_type() == MyGame::Example::AnyUniqueAliases_M ? static_cast<const MyGame::Example::Monster *>(any_unique()) : nullptr;
+  }
+  const MyGame::Example::TestSimpleTableWithEnum *any_unique_as_TS() const {
+    return any_unique_type() == MyGame::Example::AnyUniqueAliases_TS ? static_cast<const MyGame::Example::TestSimpleTableWithEnum *>(any_unique()) : nullptr;
+  }
+  const MyGame::Example2::Monster *any_unique_as_M2() const {
+    return any_unique_type() == MyGame::Example::AnyUniqueAliases_M2 ? static_cast<const MyGame::Example2::Monster *>(any_unique()) : nullptr;
+  }
+  void *mutable_any_unique() {
+    return GetPointer<void *>(VT_ANY_UNIQUE);
+  }
+  MyGame::Example::AnyAmbiguousAliases any_ambiguous_type() const {
+    return static_cast<MyGame::Example::AnyAmbiguousAliases>(GetField<uint8_t>(VT_ANY_AMBIGUOUS_TYPE, 0));
+  }
+  bool mutate_any_ambiguous_type(MyGame::Example::AnyAmbiguousAliases _any_ambiguous_type) {
+    return SetField<uint8_t>(VT_ANY_AMBIGUOUS_TYPE, static_cast<uint8_t>(_any_ambiguous_type), 0);
+  }
+  const void *any_ambiguous() const {
+    return GetPointer<const void *>(VT_ANY_AMBIGUOUS);
+  }
+  const MyGame::Example::Monster *any_ambiguous_as_M1() const {
+    return any_ambiguous_type() == MyGame::Example::AnyAmbiguousAliases_M1 ? static_cast<const MyGame::Example::Monster *>(any_ambiguous()) : nullptr;
+  }
+  const MyGame::Example::Monster *any_ambiguous_as_M2() const {
+    return any_ambiguous_type() == MyGame::Example::AnyAmbiguousAliases_M2 ? static_cast<const MyGame::Example::Monster *>(any_ambiguous()) : nullptr;
+  }
+  const MyGame::Example::Monster *any_ambiguous_as_M3() const {
+    return any_ambiguous_type() == MyGame::Example::AnyAmbiguousAliases_M3 ? static_cast<const MyGame::Example::Monster *>(any_ambiguous()) : nullptr;
+  }
+  void *mutable_any_ambiguous() {
+    return GetPointer<void *>(VT_ANY_AMBIGUOUS);
+  }
+  const flatbuffers::Vector<uint8_t> *vector_of_enums() const {
+    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_VECTOR_OF_ENUMS);
+  }
+  flatbuffers::Vector<uint8_t> *mutable_vector_of_enums() {
+    return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_VECTOR_OF_ENUMS);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<MyGame::Example::Vec3>(verifier, VT_POS) &&
+           VerifyField<int16_t>(verifier, VT_MANA) &&
+           VerifyField<int16_t>(verifier, VT_HP) &&
+           VerifyOffsetRequired(verifier, VT_NAME) &&
+           verifier.VerifyString(name()) &&
+           VerifyOffset(verifier, VT_INVENTORY) &&
+           verifier.VerifyVector(inventory()) &&
+           VerifyField<uint8_t>(verifier, VT_COLOR) &&
+           VerifyField<uint8_t>(verifier, VT_TEST_TYPE) &&
+           VerifyOffset(verifier, VT_TEST) &&
+           VerifyAny(verifier, test(), test_type()) &&
+           VerifyOffset(verifier, VT_TEST4) &&
+           verifier.VerifyVector(test4()) &&
+           VerifyOffset(verifier, VT_TESTARRAYOFSTRING) &&
+           verifier.VerifyVector(testarrayofstring()) &&
+           verifier.VerifyVectorOfStrings(testarrayofstring()) &&
+           VerifyOffset(verifier, VT_TESTARRAYOFTABLES) &&
+           verifier.VerifyVector(testarrayoftables()) &&
+           verifier.VerifyVectorOfTables(testarrayoftables()) &&
+           VerifyOffset(verifier, VT_ENEMY) &&
+           verifier.VerifyTable(enemy()) &&
+           VerifyOffset(verifier, VT_TESTNESTEDFLATBUFFER) &&
+           verifier.VerifyVector(testnestedflatbuffer()) &&
+           VerifyOffset(verifier, VT_TESTEMPTY) &&
+           verifier.VerifyTable(testempty()) &&
+           VerifyField<uint8_t>(verifier, VT_TESTBOOL) &&
+           VerifyField<int32_t>(verifier, VT_TESTHASHS32_FNV1) &&
+           VerifyField<uint32_t>(verifier, VT_TESTHASHU32_FNV1) &&
+           VerifyField<int64_t>(verifier, VT_TESTHASHS64_FNV1) &&
+           VerifyField<uint64_t>(verifier, VT_TESTHASHU64_FNV1) &&
+           VerifyField<int32_t>(verifier, VT_TESTHASHS32_FNV1A) &&
+           VerifyField<uint32_t>(verifier, VT_TESTHASHU32_FNV1A) &&
+           VerifyField<int64_t>(verifier, VT_TESTHASHS64_FNV1A) &&
+           VerifyField<uint64_t>(verifier, VT_TESTHASHU64_FNV1A) &&
+           VerifyOffset(verifier, VT_TESTARRAYOFBOOLS) &&
+           verifier.VerifyVector(testarrayofbools()) &&
+           VerifyField<float>(verifier, VT_TESTF) &&
+           VerifyField<float>(verifier, VT_TESTF2) &&
+           VerifyField<float>(verifier, VT_TESTF3) &&
+           VerifyOffset(verifier, VT_TESTARRAYOFSTRING2) &&
+           verifier.VerifyVector(testarrayofstring2()) &&
+           verifier.VerifyVectorOfStrings(testarrayofstring2()) &&
+           VerifyOffset(verifier, VT_TESTARRAYOFSORTEDSTRUCT) &&
+           verifier.VerifyVector(testarrayofsortedstruct()) &&
+           VerifyOffset(verifier, VT_FLEX) &&
+           verifier.VerifyVector(flex()) &&
+           VerifyOffset(verifier, VT_TEST5) &&
+           verifier.VerifyVector(test5()) &&
+           VerifyOffset(verifier, VT_VECTOR_OF_LONGS) &&
+           verifier.VerifyVector(vector_of_longs()) &&
+           VerifyOffset(verifier, VT_VECTOR_OF_DOUBLES) &&
+           verifier.VerifyVector(vector_of_doubles()) &&
+           VerifyOffset(verifier, VT_PARENT_NAMESPACE_TEST) &&
+           verifier.VerifyTable(parent_namespace_test()) &&
+           VerifyOffset(verifier, VT_VECTOR_OF_REFERRABLES) &&
+           verifier.VerifyVector(vector_of_referrables()) &&
+           verifier.VerifyVectorOfTables(vector_of_referrables()) &&
+           VerifyField<uint64_t>(verifier, VT_SINGLE_WEAK_REFERENCE) &&
+           VerifyOffset(verifier, VT_VECTOR_OF_WEAK_REFERENCES) &&
+           verifier.VerifyVector(vector_of_weak_references()) &&
+           VerifyOffset(verifier, VT_VECTOR_OF_STRONG_REFERRABLES) &&
+           verifier.VerifyVector(vector_of_strong_referrables()) &&
+           verifier.VerifyVectorOfTables(vector_of_strong_referrables()) &&
+           VerifyField<uint64_t>(verifier, VT_CO_OWNING_REFERENCE) &&
+           VerifyOffset(verifier, VT_VECTOR_OF_CO_OWNING_REFERENCES) &&
+           verifier.VerifyVector(vector_of_co_owning_references()) &&
+           VerifyField<uint64_t>(verifier, VT_NON_OWNING_REFERENCE) &&
+           VerifyOffset(verifier, VT_VECTOR_OF_NON_OWNING_REFERENCES) &&
+           verifier.VerifyVector(vector_of_non_owning_references()) &&
+           VerifyField<uint8_t>(verifier, VT_ANY_UNIQUE_TYPE) &&
+           VerifyOffset(verifier, VT_ANY_UNIQUE) &&
+           VerifyAnyUniqueAliases(verifier, any_unique(), any_unique_type()) &&
+           VerifyField<uint8_t>(verifier, VT_ANY_AMBIGUOUS_TYPE) &&
+           VerifyOffset(verifier, VT_ANY_AMBIGUOUS) &&
+           VerifyAnyAmbiguousAliases(verifier, any_ambiguous(), any_ambiguous_type()) &&
+           VerifyOffset(verifier, VT_VECTOR_OF_ENUMS) &&
+           verifier.VerifyVector(vector_of_enums()) &&
+           verifier.EndTable();
+  }
+  MonsterT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<Monster> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+template<> inline const MyGame::Example::Monster *Monster::test_as<MyGame::Example::Monster>() const {
+  return test_as_Monster();
+}
+
+template<> inline const MyGame::Example::TestSimpleTableWithEnum *Monster::test_as<MyGame::Example::TestSimpleTableWithEnum>() const {
+  return test_as_TestSimpleTableWithEnum();
+}
+
+template<> inline const MyGame::Example2::Monster *Monster::test_as<MyGame::Example2::Monster>() const {
+  return test_as_MyGame_Example2_Monster();
+}
+
+template<> inline const MyGame::Example::Monster *Monster::any_unique_as<MyGame::Example::Monster>() const {
+  return any_unique_as_M();
+}
+
+template<> inline const MyGame::Example::TestSimpleTableWithEnum *Monster::any_unique_as<MyGame::Example::TestSimpleTableWithEnum>() const {
+  return any_unique_as_TS();
+}
+
+template<> inline const MyGame::Example2::Monster *Monster::any_unique_as<MyGame::Example2::Monster>() const {
+  return any_unique_as_M2();
+}
+
+struct MonsterBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_pos(const MyGame::Example::Vec3 *pos) {
+    fbb_.AddStruct(Monster::VT_POS, pos);
+  }
+  void add_mana(int16_t mana) {
+    fbb_.AddElement<int16_t>(Monster::VT_MANA, mana, 150);
+  }
+  void add_hp(int16_t hp) {
+    fbb_.AddElement<int16_t>(Monster::VT_HP, hp, 100);
+  }
+  void add_name(flatbuffers::Offset<flatbuffers::String> name) {
+    fbb_.AddOffset(Monster::VT_NAME, name);
+  }
+  void add_inventory(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory) {
+    fbb_.AddOffset(Monster::VT_INVENTORY, inventory);
+  }
+  void add_color(MyGame::Example::Color color) {
+    fbb_.AddElement<uint8_t>(Monster::VT_COLOR, static_cast<uint8_t>(color), 8);
+  }
+  void add_test_type(MyGame::Example::Any test_type) {
+    fbb_.AddElement<uint8_t>(Monster::VT_TEST_TYPE, static_cast<uint8_t>(test_type), 0);
+  }
+  void add_test(flatbuffers::Offset<void> test) {
+    fbb_.AddOffset(Monster::VT_TEST, test);
+  }
+  void add_test4(flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Test *>> test4) {
+    fbb_.AddOffset(Monster::VT_TEST4, test4);
+  }
+  void add_testarrayofstring(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> testarrayofstring) {
+    fbb_.AddOffset(Monster::VT_TESTARRAYOFSTRING, testarrayofstring);
+  }
+  void add_testarrayoftables(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>>> testarrayoftables) {
+    fbb_.AddOffset(Monster::VT_TESTARRAYOFTABLES, testarrayoftables);
+  }
+  void add_enemy(flatbuffers::Offset<MyGame::Example::Monster> enemy) {
+    fbb_.AddOffset(Monster::VT_ENEMY, enemy);
+  }
+  void add_testnestedflatbuffer(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> testnestedflatbuffer) {
+    fbb_.AddOffset(Monster::VT_TESTNESTEDFLATBUFFER, testnestedflatbuffer);
+  }
+  void add_testempty(flatbuffers::Offset<MyGame::Example::Stat> testempty) {
+    fbb_.AddOffset(Monster::VT_TESTEMPTY, testempty);
+  }
+  void add_testbool(bool testbool) {
+    fbb_.AddElement<uint8_t>(Monster::VT_TESTBOOL, static_cast<uint8_t>(testbool), 0);
+  }
+  void add_testhashs32_fnv1(int32_t testhashs32_fnv1) {
+    fbb_.AddElement<int32_t>(Monster::VT_TESTHASHS32_FNV1, testhashs32_fnv1, 0);
+  }
+  void add_testhashu32_fnv1(uint32_t testhashu32_fnv1) {
+    fbb_.AddElement<uint32_t>(Monster::VT_TESTHASHU32_FNV1, testhashu32_fnv1, 0);
+  }
+  void add_testhashs64_fnv1(int64_t testhashs64_fnv1) {
+    fbb_.AddElement<int64_t>(Monster::VT_TESTHASHS64_FNV1, testhashs64_fnv1, 0);
+  }
+  void add_testhashu64_fnv1(uint64_t testhashu64_fnv1) {
+    fbb_.AddElement<uint64_t>(Monster::VT_TESTHASHU64_FNV1, testhashu64_fnv1, 0);
+  }
+  void add_testhashs32_fnv1a(int32_t testhashs32_fnv1a) {
+    fbb_.AddElement<int32_t>(Monster::VT_TESTHASHS32_FNV1A, testhashs32_fnv1a, 0);
+  }
+  void add_testhashu32_fnv1a(uint32_t testhashu32_fnv1a) {
+    fbb_.AddElement<uint32_t>(Monster::VT_TESTHASHU32_FNV1A, testhashu32_fnv1a, 0);
+  }
+  void add_testhashs64_fnv1a(int64_t testhashs64_fnv1a) {
+    fbb_.AddElement<int64_t>(Monster::VT_TESTHASHS64_FNV1A, testhashs64_fnv1a, 0);
+  }
+  void add_testhashu64_fnv1a(uint64_t testhashu64_fnv1a) {
+    fbb_.AddElement<uint64_t>(Monster::VT_TESTHASHU64_FNV1A, testhashu64_fnv1a, 0);
+  }
+  void add_testarrayofbools(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> testarrayofbools) {
+    fbb_.AddOffset(Monster::VT_TESTARRAYOFBOOLS, testarrayofbools);
+  }
+  void add_testf(float testf) {
+    fbb_.AddElement<float>(Monster::VT_TESTF, testf, 3.14159f);
+  }
+  void add_testf2(float testf2) {
+    fbb_.AddElement<float>(Monster::VT_TESTF2, testf2, 3.0f);
+  }
+  void add_testf3(float testf3) {
+    fbb_.AddElement<float>(Monster::VT_TESTF3, testf3, 0.0f);
+  }
+  void add_testarrayofstring2(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> testarrayofstring2) {
+    fbb_.AddOffset(Monster::VT_TESTARRAYOFSTRING2, testarrayofstring2);
+  }
+  void add_testarrayofsortedstruct(flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Ability *>> testarrayofsortedstruct) {
+    fbb_.AddOffset(Monster::VT_TESTARRAYOFSORTEDSTRUCT, testarrayofsortedstruct);
+  }
+  void add_flex(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> flex) {
+    fbb_.AddOffset(Monster::VT_FLEX, flex);
+  }
+  void add_test5(flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Test *>> test5) {
+    fbb_.AddOffset(Monster::VT_TEST5, test5);
+  }
+  void add_vector_of_longs(flatbuffers::Offset<flatbuffers::Vector<int64_t>> vector_of_longs) {
+    fbb_.AddOffset(Monster::VT_VECTOR_OF_LONGS, vector_of_longs);
+  }
+  void add_vector_of_doubles(flatbuffers::Offset<flatbuffers::Vector<double>> vector_of_doubles) {
+    fbb_.AddOffset(Monster::VT_VECTOR_OF_DOUBLES, vector_of_doubles);
+  }
+  void add_parent_namespace_test(flatbuffers::Offset<MyGame::InParentNamespace> parent_namespace_test) {
+    fbb_.AddOffset(Monster::VT_PARENT_NAMESPACE_TEST, parent_namespace_test);
+  }
+  void add_vector_of_referrables(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>>> vector_of_referrables) {
+    fbb_.AddOffset(Monster::VT_VECTOR_OF_REFERRABLES, vector_of_referrables);
+  }
+  void add_single_weak_reference(uint64_t single_weak_reference) {
+    fbb_.AddElement<uint64_t>(Monster::VT_SINGLE_WEAK_REFERENCE, single_weak_reference, 0);
+  }
+  void add_vector_of_weak_references(flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_weak_references) {
+    fbb_.AddOffset(Monster::VT_VECTOR_OF_WEAK_REFERENCES, vector_of_weak_references);
+  }
+  void add_vector_of_strong_referrables(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>>> vector_of_strong_referrables) {
+    fbb_.AddOffset(Monster::VT_VECTOR_OF_STRONG_REFERRABLES, vector_of_strong_referrables);
+  }
+  void add_co_owning_reference(uint64_t co_owning_reference) {
+    fbb_.AddElement<uint64_t>(Monster::VT_CO_OWNING_REFERENCE, co_owning_reference, 0);
+  }
+  void add_vector_of_co_owning_references(flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_co_owning_references) {
+    fbb_.AddOffset(Monster::VT_VECTOR_OF_CO_OWNING_REFERENCES, vector_of_co_owning_references);
+  }
+  void add_non_owning_reference(uint64_t non_owning_reference) {
+    fbb_.AddElement<uint64_t>(Monster::VT_NON_OWNING_REFERENCE, non_owning_reference, 0);
+  }
+  void add_vector_of_non_owning_references(flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_non_owning_references) {
+    fbb_.AddOffset(Monster::VT_VECTOR_OF_NON_OWNING_REFERENCES, vector_of_non_owning_references);
+  }
+  void add_any_unique_type(MyGame::Example::AnyUniqueAliases any_unique_type) {
+    fbb_.AddElement<uint8_t>(Monster::VT_ANY_UNIQUE_TYPE, static_cast<uint8_t>(any_unique_type), 0);
+  }
+  void add_any_unique(flatbuffers::Offset<void> any_unique) {
+    fbb_.AddOffset(Monster::VT_ANY_UNIQUE, any_unique);
+  }
+  void add_any_ambiguous_type(MyGame::Example::AnyAmbiguousAliases any_ambiguous_type) {
+    fbb_.AddElement<uint8_t>(Monster::VT_ANY_AMBIGUOUS_TYPE, static_cast<uint8_t>(any_ambiguous_type), 0);
+  }
+  void add_any_ambiguous(flatbuffers::Offset<void> any_ambiguous) {
+    fbb_.AddOffset(Monster::VT_ANY_AMBIGUOUS, any_ambiguous);
+  }
+  void add_vector_of_enums(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> vector_of_enums) {
+    fbb_.AddOffset(Monster::VT_VECTOR_OF_ENUMS, vector_of_enums);
+  }
+  explicit MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  MonsterBuilder &operator=(const MonsterBuilder &);
+  flatbuffers::Offset<Monster> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Monster>(end);
+    fbb_.Required(o, Monster::VT_NAME);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Monster> CreateMonster(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const MyGame::Example::Vec3 *pos = 0,
+    int16_t mana = 150,
+    int16_t hp = 100,
+    flatbuffers::Offset<flatbuffers::String> name = 0,
+    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory = 0,
+    MyGame::Example::Color color = MyGame::Example::Color_Blue,
+    MyGame::Example::Any test_type = MyGame::Example::Any_NONE,
+    flatbuffers::Offset<void> test = 0,
+    flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Test *>> test4 = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> testarrayofstring = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>>> testarrayoftables = 0,
+    flatbuffers::Offset<MyGame::Example::Monster> enemy = 0,
+    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> testnestedflatbuffer = 0,
+    flatbuffers::Offset<MyGame::Example::Stat> testempty = 0,
+    bool testbool = false,
+    int32_t testhashs32_fnv1 = 0,
+    uint32_t testhashu32_fnv1 = 0,
+    int64_t testhashs64_fnv1 = 0,
+    uint64_t testhashu64_fnv1 = 0,
+    int32_t testhashs32_fnv1a = 0,
+    uint32_t testhashu32_fnv1a = 0,
+    int64_t testhashs64_fnv1a = 0,
+    uint64_t testhashu64_fnv1a = 0,
+    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> testarrayofbools = 0,
+    float testf = 3.14159f,
+    float testf2 = 3.0f,
+    float testf3 = 0.0f,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> testarrayofstring2 = 0,
+    flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Ability *>> testarrayofsortedstruct = 0,
+    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> flex = 0,
+    flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Test *>> test5 = 0,
+    flatbuffers::Offset<flatbuffers::Vector<int64_t>> vector_of_longs = 0,
+    flatbuffers::Offset<flatbuffers::Vector<double>> vector_of_doubles = 0,
+    flatbuffers::Offset<MyGame::InParentNamespace> parent_namespace_test = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>>> vector_of_referrables = 0,
+    uint64_t single_weak_reference = 0,
+    flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_weak_references = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>>> vector_of_strong_referrables = 0,
+    uint64_t co_owning_reference = 0,
+    flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_co_owning_references = 0,
+    uint64_t non_owning_reference = 0,
+    flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_non_owning_references = 0,
+    MyGame::Example::AnyUniqueAliases any_unique_type = MyGame::Example::AnyUniqueAliases_NONE,
+    flatbuffers::Offset<void> any_unique = 0,
+    MyGame::Example::AnyAmbiguousAliases any_ambiguous_type = MyGame::Example::AnyAmbiguousAliases_NONE,
+    flatbuffers::Offset<void> any_ambiguous = 0,
+    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> vector_of_enums = 0) {
+  MonsterBuilder builder_(_fbb);
+  builder_.add_non_owning_reference(non_owning_reference);
+  builder_.add_co_owning_reference(co_owning_reference);
+  builder_.add_single_weak_reference(single_weak_reference);
+  builder_.add_testhashu64_fnv1a(testhashu64_fnv1a);
+  builder_.add_testhashs64_fnv1a(testhashs64_fnv1a);
+  builder_.add_testhashu64_fnv1(testhashu64_fnv1);
+  builder_.add_testhashs64_fnv1(testhashs64_fnv1);
+  builder_.add_vector_of_enums(vector_of_enums);
+  builder_.add_any_ambiguous(any_ambiguous);
+  builder_.add_any_unique(any_unique);
+  builder_.add_vector_of_non_owning_references(vector_of_non_owning_references);
+  builder_.add_vector_of_co_owning_references(vector_of_co_owning_references);
+  builder_.add_vector_of_strong_referrables(vector_of_strong_referrables);
+  builder_.add_vector_of_weak_references(vector_of_weak_references);
+  builder_.add_vector_of_referrables(vector_of_referrables);
+  builder_.add_parent_namespace_test(parent_namespace_test);
+  builder_.add_vector_of_doubles(vector_of_doubles);
+  builder_.add_vector_of_longs(vector_of_longs);
+  builder_.add_test5(test5);
+  builder_.add_flex(flex);
+  builder_.add_testarrayofsortedstruct(testarrayofsortedstruct);
+  builder_.add_testarrayofstring2(testarrayofstring2);
+  builder_.add_testf3(testf3);
+  builder_.add_testf2(testf2);
+  builder_.add_testf(testf);
+  builder_.add_testarrayofbools(testarrayofbools);
+  builder_.add_testhashu32_fnv1a(testhashu32_fnv1a);
+  builder_.add_testhashs32_fnv1a(testhashs32_fnv1a);
+  builder_.add_testhashu32_fnv1(testhashu32_fnv1);
+  builder_.add_testhashs32_fnv1(testhashs32_fnv1);
+  builder_.add_testempty(testempty);
+  builder_.add_testnestedflatbuffer(testnestedflatbuffer);
+  builder_.add_enemy(enemy);
+  builder_.add_testarrayoftables(testarrayoftables);
+  builder_.add_testarrayofstring(testarrayofstring);
+  builder_.add_test4(test4);
+  builder_.add_test(test);
+  builder_.add_inventory(inventory);
+  builder_.add_name(name);
+  builder_.add_pos(pos);
+  builder_.add_hp(hp);
+  builder_.add_mana(mana);
+  builder_.add_any_ambiguous_type(any_ambiguous_type);
+  builder_.add_any_unique_type(any_unique_type);
+  builder_.add_testbool(testbool);
+  builder_.add_test_type(test_type);
+  builder_.add_color(color);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Monster> CreateMonsterDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const MyGame::Example::Vec3 *pos = 0,
+    int16_t mana = 150,
+    int16_t hp = 100,
+    const char *name = nullptr,
+    const std::vector<uint8_t> *inventory = nullptr,
+    MyGame::Example::Color color = MyGame::Example::Color_Blue,
+    MyGame::Example::Any test_type = MyGame::Example::Any_NONE,
+    flatbuffers::Offset<void> test = 0,
+    const std::vector<MyGame::Example::Test> *test4 = nullptr,
+    const std::vector<flatbuffers::Offset<flatbuffers::String>> *testarrayofstring = nullptr,
+    const std::vector<flatbuffers::Offset<MyGame::Example::Monster>> *testarrayoftables = nullptr,
+    flatbuffers::Offset<MyGame::Example::Monster> enemy = 0,
+    const std::vector<uint8_t> *testnestedflatbuffer = nullptr,
+    flatbuffers::Offset<MyGame::Example::Stat> testempty = 0,
+    bool testbool = false,
+    int32_t testhashs32_fnv1 = 0,
+    uint32_t testhashu32_fnv1 = 0,
+    int64_t testhashs64_fnv1 = 0,
+    uint64_t testhashu64_fnv1 = 0,
+    int32_t testhashs32_fnv1a = 0,
+    uint32_t testhashu32_fnv1a = 0,
+    int64_t testhashs64_fnv1a = 0,
+    uint64_t testhashu64_fnv1a = 0,
+    const std::vector<uint8_t> *testarrayofbools = nullptr,
+    float testf = 3.14159f,
+    float testf2 = 3.0f,
+    float testf3 = 0.0f,
+    const std::vector<flatbuffers::Offset<flatbuffers::String>> *testarrayofstring2 = nullptr,
+    const std::vector<MyGame::Example::Ability> *testarrayofsortedstruct = nullptr,
+    const std::vector<uint8_t> *flex = nullptr,
+    const std::vector<MyGame::Example::Test> *test5 = nullptr,
+    const std::vector<int64_t> *vector_of_longs = nullptr,
+    const std::vector<double> *vector_of_doubles = nullptr,
+    flatbuffers::Offset<MyGame::InParentNamespace> parent_namespace_test = 0,
+    const std::vector<flatbuffers::Offset<MyGame::Example::Referrable>> *vector_of_referrables = nullptr,
+    uint64_t single_weak_reference = 0,
+    const std::vector<uint64_t> *vector_of_weak_references = nullptr,
+    const std::vector<flatbuffers::Offset<MyGame::Example::Referrable>> *vector_of_strong_referrables = nullptr,
+    uint64_t co_owning_reference = 0,
+    const std::vector<uint64_t> *vector_of_co_owning_references = nullptr,
+    uint64_t non_owning_reference = 0,
+    const std::vector<uint64_t> *vector_of_non_owning_references = nullptr,
+    MyGame::Example::AnyUniqueAliases any_unique_type = MyGame::Example::AnyUniqueAliases_NONE,
+    flatbuffers::Offset<void> any_unique = 0,
+    MyGame::Example::AnyAmbiguousAliases any_ambiguous_type = MyGame::Example::AnyAmbiguousAliases_NONE,
+    flatbuffers::Offset<void> any_ambiguous = 0,
+    const std::vector<uint8_t> *vector_of_enums = nullptr) {
+  auto name__ = name ? _fbb.CreateString(name) : 0;
+  auto inventory__ = inventory ? _fbb.CreateVector<uint8_t>(*inventory) : 0;
+  auto test4__ = test4 ? _fbb.CreateVectorOfStructs<MyGame::Example::Test>(*test4) : 0;
+  auto testarrayofstring__ = testarrayofstring ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*testarrayofstring) : 0;
+  auto testarrayoftables__ = testarrayoftables ? _fbb.CreateVector<flatbuffers::Offset<MyGame::Example::Monster>>(*testarrayoftables) : 0;
+  auto testnestedflatbuffer__ = testnestedflatbuffer ? _fbb.CreateVector<uint8_t>(*testnestedflatbuffer) : 0;
+  auto testarrayofbools__ = testarrayofbools ? _fbb.CreateVector<uint8_t>(*testarrayofbools) : 0;
+  auto testarrayofstring2__ = testarrayofstring2 ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*testarrayofstring2) : 0;
+  auto testarrayofsortedstruct__ = testarrayofsortedstruct ? _fbb.CreateVectorOfStructs<MyGame::Example::Ability>(*testarrayofsortedstruct) : 0;
+  auto flex__ = flex ? _fbb.CreateVector<uint8_t>(*flex) : 0;
+  auto test5__ = test5 ? _fbb.CreateVectorOfStructs<MyGame::Example::Test>(*test5) : 0;
+  auto vector_of_longs__ = vector_of_longs ? _fbb.CreateVector<int64_t>(*vector_of_longs) : 0;
+  auto vector_of_doubles__ = vector_of_doubles ? _fbb.CreateVector<double>(*vector_of_doubles) : 0;
+  auto vector_of_referrables__ = vector_of_referrables ? _fbb.CreateVector<flatbuffers::Offset<MyGame::Example::Referrable>>(*vector_of_referrables) : 0;
+  auto vector_of_weak_references__ = vector_of_weak_references ? _fbb.CreateVector<uint64_t>(*vector_of_weak_references) : 0;
+  auto vector_of_strong_referrables__ = vector_of_strong_referrables ? _fbb.CreateVector<flatbuffers::Offset<MyGame::Example::Referrable>>(*vector_of_strong_referrables) : 0;
+  auto vector_of_co_owning_references__ = vector_of_co_owning_references ? _fbb.CreateVector<uint64_t>(*vector_of_co_owning_references) : 0;
+  auto vector_of_non_owning_references__ = vector_of_non_owning_references ? _fbb.CreateVector<uint64_t>(*vector_of_non_owning_references) : 0;
+  auto vector_of_enums__ = vector_of_enums ? _fbb.CreateVector<uint8_t>(*vector_of_enums) : 0;
+  return MyGame::Example::CreateMonster(
+      _fbb,
+      pos,
+      mana,
+      hp,
+      name__,
+      inventory__,
+      color,
+      test_type,
+      test,
+      test4__,
+      testarrayofstring__,
+      testarrayoftables__,
+      enemy,
+      testnestedflatbuffer__,
+      testempty,
+      testbool,
+      testhashs32_fnv1,
+      testhashu32_fnv1,
+      testhashs64_fnv1,
+      testhashu64_fnv1,
+      testhashs32_fnv1a,
+      testhashu32_fnv1a,
+      testhashs64_fnv1a,
+      testhashu64_fnv1a,
+      testarrayofbools__,
+      testf,
+      testf2,
+      testf3,
+      testarrayofstring2__,
+      testarrayofsortedstruct__,
+      flex__,
+      test5__,
+      vector_of_longs__,
+      vector_of_doubles__,
+      parent_namespace_test,
+      vector_of_referrables__,
+      single_weak_reference,
+      vector_of_weak_references__,
+      vector_of_strong_referrables__,
+      co_owning_reference,
+      vector_of_co_owning_references__,
+      non_owning_reference,
+      vector_of_non_owning_references__,
+      any_unique_type,
+      any_unique,
+      any_ambiguous_type,
+      any_ambiguous,
+      vector_of_enums__);
+}
+
+flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+struct TypeAliasesT : public flatbuffers::NativeTable {
+  typedef TypeAliases TableType;
+  int8_t i8;
+  uint8_t u8;
+  int16_t i16;
+  uint16_t u16;
+  int32_t i32;
+  uint32_t u32;
+  int64_t i64;
+  uint64_t u64;
+  float f32;
+  double f64;
+  std::vector<int8_t> v8;
+  std::vector<double> vf64;
+  TypeAliasesT()
+      : i8(0),
+        u8(0),
+        i16(0),
+        u16(0),
+        i32(0),
+        u32(0),
+        i64(0),
+        u64(0),
+        f32(0.0f),
+        f64(0.0) {
+  }
+};
+
+inline bool operator==(const TypeAliasesT &lhs, const TypeAliasesT &rhs) {
+  return
+      (lhs.i8 == rhs.i8) &&
+      (lhs.u8 == rhs.u8) &&
+      (lhs.i16 == rhs.i16) &&
+      (lhs.u16 == rhs.u16) &&
+      (lhs.i32 == rhs.i32) &&
+      (lhs.u32 == rhs.u32) &&
+      (lhs.i64 == rhs.i64) &&
+      (lhs.u64 == rhs.u64) &&
+      (lhs.f32 == rhs.f32) &&
+      (lhs.f64 == rhs.f64) &&
+      (lhs.v8 == rhs.v8) &&
+      (lhs.vf64 == rhs.vf64);
+}
+
+inline bool operator!=(const TypeAliasesT &lhs, const TypeAliasesT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct TypeAliases FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef TypeAliasesT NativeTableType;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return TypeAliasesTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_I8 = 4,
+    VT_U8 = 6,
+    VT_I16 = 8,
+    VT_U16 = 10,
+    VT_I32 = 12,
+    VT_U32 = 14,
+    VT_I64 = 16,
+    VT_U64 = 18,
+    VT_F32 = 20,
+    VT_F64 = 22,
+    VT_V8 = 24,
+    VT_VF64 = 26
+  };
+  int8_t i8() const {
+    return GetField<int8_t>(VT_I8, 0);
+  }
+  bool mutate_i8(int8_t _i8) {
+    return SetField<int8_t>(VT_I8, _i8, 0);
+  }
+  uint8_t u8() const {
+    return GetField<uint8_t>(VT_U8, 0);
+  }
+  bool mutate_u8(uint8_t _u8) {
+    return SetField<uint8_t>(VT_U8, _u8, 0);
+  }
+  int16_t i16() const {
+    return GetField<int16_t>(VT_I16, 0);
+  }
+  bool mutate_i16(int16_t _i16) {
+    return SetField<int16_t>(VT_I16, _i16, 0);
+  }
+  uint16_t u16() const {
+    return GetField<uint16_t>(VT_U16, 0);
+  }
+  bool mutate_u16(uint16_t _u16) {
+    return SetField<uint16_t>(VT_U16, _u16, 0);
+  }
+  int32_t i32() const {
+    return GetField<int32_t>(VT_I32, 0);
+  }
+  bool mutate_i32(int32_t _i32) {
+    return SetField<int32_t>(VT_I32, _i32, 0);
+  }
+  uint32_t u32() const {
+    return GetField<uint32_t>(VT_U32, 0);
+  }
+  bool mutate_u32(uint32_t _u32) {
+    return SetField<uint32_t>(VT_U32, _u32, 0);
+  }
+  int64_t i64() const {
+    return GetField<int64_t>(VT_I64, 0);
+  }
+  bool mutate_i64(int64_t _i64) {
+    return SetField<int64_t>(VT_I64, _i64, 0);
+  }
+  uint64_t u64() const {
+    return GetField<uint64_t>(VT_U64, 0);
+  }
+  bool mutate_u64(uint64_t _u64) {
+    return SetField<uint64_t>(VT_U64, _u64, 0);
+  }
+  float f32() const {
+    return GetField<float>(VT_F32, 0.0f);
+  }
+  bool mutate_f32(float _f32) {
+    return SetField<float>(VT_F32, _f32, 0.0f);
+  }
+  double f64() const {
+    return GetField<double>(VT_F64, 0.0);
+  }
+  bool mutate_f64(double _f64) {
+    return SetField<double>(VT_F64, _f64, 0.0);
+  }
+  const flatbuffers::Vector<int8_t> *v8() const {
+    return GetPointer<const flatbuffers::Vector<int8_t> *>(VT_V8);
+  }
+  flatbuffers::Vector<int8_t> *mutable_v8() {
+    return GetPointer<flatbuffers::Vector<int8_t> *>(VT_V8);
+  }
+  const flatbuffers::Vector<double> *vf64() const {
+    return GetPointer<const flatbuffers::Vector<double> *>(VT_VF64);
+  }
+  flatbuffers::Vector<double> *mutable_vf64() {
+    return GetPointer<flatbuffers::Vector<double> *>(VT_VF64);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<int8_t>(verifier, VT_I8) &&
+           VerifyField<uint8_t>(verifier, VT_U8) &&
+           VerifyField<int16_t>(verifier, VT_I16) &&
+           VerifyField<uint16_t>(verifier, VT_U16) &&
+           VerifyField<int32_t>(verifier, VT_I32) &&
+           VerifyField<uint32_t>(verifier, VT_U32) &&
+           VerifyField<int64_t>(verifier, VT_I64) &&
+           VerifyField<uint64_t>(verifier, VT_U64) &&
+           VerifyField<float>(verifier, VT_F32) &&
+           VerifyField<double>(verifier, VT_F64) &&
+           VerifyOffset(verifier, VT_V8) &&
+           verifier.VerifyVector(v8()) &&
+           VerifyOffset(verifier, VT_VF64) &&
+           verifier.VerifyVector(vf64()) &&
+           verifier.EndTable();
+  }
+  TypeAliasesT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(TypeAliasesT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<TypeAliases> Pack(flatbuffers::FlatBufferBuilder &_fbb, const TypeAliasesT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct TypeAliasesBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_i8(int8_t i8) {
+    fbb_.AddElement<int8_t>(TypeAliases::VT_I8, i8, 0);
+  }
+  void add_u8(uint8_t u8) {
+    fbb_.AddElement<uint8_t>(TypeAliases::VT_U8, u8, 0);
+  }
+  void add_i16(int16_t i16) {
+    fbb_.AddElement<int16_t>(TypeAliases::VT_I16, i16, 0);
+  }
+  void add_u16(uint16_t u16) {
+    fbb_.AddElement<uint16_t>(TypeAliases::VT_U16, u16, 0);
+  }
+  void add_i32(int32_t i32) {
+    fbb_.AddElement<int32_t>(TypeAliases::VT_I32, i32, 0);
+  }
+  void add_u32(uint32_t u32) {
+    fbb_.AddElement<uint32_t>(TypeAliases::VT_U32, u32, 0);
+  }
+  void add_i64(int64_t i64) {
+    fbb_.AddElement<int64_t>(TypeAliases::VT_I64, i64, 0);
+  }
+  void add_u64(uint64_t u64) {
+    fbb_.AddElement<uint64_t>(TypeAliases::VT_U64, u64, 0);
+  }
+  void add_f32(float f32) {
+    fbb_.AddElement<float>(TypeAliases::VT_F32, f32, 0.0f);
+  }
+  void add_f64(double f64) {
+    fbb_.AddElement<double>(TypeAliases::VT_F64, f64, 0.0);
+  }
+  void add_v8(flatbuffers::Offset<flatbuffers::Vector<int8_t>> v8) {
+    fbb_.AddOffset(TypeAliases::VT_V8, v8);
+  }
+  void add_vf64(flatbuffers::Offset<flatbuffers::Vector<double>> vf64) {
+    fbb_.AddOffset(TypeAliases::VT_VF64, vf64);
+  }
+  explicit TypeAliasesBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  TypeAliasesBuilder &operator=(const TypeAliasesBuilder &);
+  flatbuffers::Offset<TypeAliases> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<TypeAliases>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<TypeAliases> CreateTypeAliases(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    int8_t i8 = 0,
+    uint8_t u8 = 0,
+    int16_t i16 = 0,
+    uint16_t u16 = 0,
+    int32_t i32 = 0,
+    uint32_t u32 = 0,
+    int64_t i64 = 0,
+    uint64_t u64 = 0,
+    float f32 = 0.0f,
+    double f64 = 0.0,
+    flatbuffers::Offset<flatbuffers::Vector<int8_t>> v8 = 0,
+    flatbuffers::Offset<flatbuffers::Vector<double>> vf64 = 0) {
+  TypeAliasesBuilder builder_(_fbb);
+  builder_.add_f64(f64);
+  builder_.add_u64(u64);
+  builder_.add_i64(i64);
+  builder_.add_vf64(vf64);
+  builder_.add_v8(v8);
+  builder_.add_f32(f32);
+  builder_.add_u32(u32);
+  builder_.add_i32(i32);
+  builder_.add_u16(u16);
+  builder_.add_i16(i16);
+  builder_.add_u8(u8);
+  builder_.add_i8(i8);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<TypeAliases> CreateTypeAliasesDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    int8_t i8 = 0,
+    uint8_t u8 = 0,
+    int16_t i16 = 0,
+    uint16_t u16 = 0,
+    int32_t i32 = 0,
+    uint32_t u32 = 0,
+    int64_t i64 = 0,
+    uint64_t u64 = 0,
+    float f32 = 0.0f,
+    double f64 = 0.0,
+    const std::vector<int8_t> *v8 = nullptr,
+    const std::vector<double> *vf64 = nullptr) {
+  auto v8__ = v8 ? _fbb.CreateVector<int8_t>(*v8) : 0;
+  auto vf64__ = vf64 ? _fbb.CreateVector<double>(*vf64) : 0;
+  return MyGame::Example::CreateTypeAliases(
+      _fbb,
+      i8,
+      u8,
+      i16,
+      u16,
+      i32,
+      u32,
+      i64,
+      u64,
+      f32,
+      f64,
+      v8__,
+      vf64__);
+}
+
+flatbuffers::Offset<TypeAliases> CreateTypeAliases(flatbuffers::FlatBufferBuilder &_fbb, const TypeAliasesT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+}  // namespace Example
+
+inline InParentNamespaceT *InParentNamespace::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = new InParentNamespaceT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+inline void InParentNamespace::UnPackTo(InParentNamespaceT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+}
+
+inline flatbuffers::Offset<InParentNamespace> InParentNamespace::Pack(flatbuffers::FlatBufferBuilder &_fbb, const InParentNamespaceT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateInParentNamespace(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<InParentNamespace> CreateInParentNamespace(flatbuffers::FlatBufferBuilder &_fbb, const InParentNamespaceT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const InParentNamespaceT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  return MyGame::CreateInParentNamespace(
+      _fbb);
+}
+
+namespace Example2 {
+
+inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = new MonsterT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+inline void Monster::UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+}
+
+inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateMonster(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const MonsterT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  return MyGame::Example2::CreateMonster(
+      _fbb);
+}
+
+}  // namespace Example2
+
+namespace Example {
+
+inline TestSimpleTableWithEnumT *TestSimpleTableWithEnum::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = new TestSimpleTableWithEnumT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+inline void TestSimpleTableWithEnum::UnPackTo(TestSimpleTableWithEnumT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = color(); _o->color = _e; };
+}
+
+inline flatbuffers::Offset<TestSimpleTableWithEnum> TestSimpleTableWithEnum::Pack(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateTestSimpleTableWithEnum(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const TestSimpleTableWithEnumT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _color = _o->color;
+  return MyGame::Example::CreateTestSimpleTableWithEnum(
+      _fbb,
+      _color);
+}
+
+inline StatT *Stat::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = new StatT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+inline void Stat::UnPackTo(StatT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = id(); if (_e) _o->id = _e->str(); };
+  { auto _e = val(); _o->val = _e; };
+  { auto _e = count(); _o->count = _e; };
+}
+
+inline flatbuffers::Offset<Stat> Stat::Pack(flatbuffers::FlatBufferBuilder &_fbb, const StatT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateStat(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<Stat> CreateStat(flatbuffers::FlatBufferBuilder &_fbb, const StatT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const StatT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _id = _o->id.empty() ? 0 : _fbb.CreateString(_o->id);
+  auto _val = _o->val;
+  auto _count = _o->count;
+  return MyGame::Example::CreateStat(
+      _fbb,
+      _id,
+      _val,
+      _count);
+}
+
+inline ReferrableT *Referrable::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = new ReferrableT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+inline void Referrable::UnPackTo(ReferrableT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = id(); _o->id = _e; };
+}
+
+inline flatbuffers::Offset<Referrable> Referrable::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ReferrableT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateReferrable(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<Referrable> CreateReferrable(flatbuffers::FlatBufferBuilder &_fbb, const ReferrableT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ReferrableT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _id = _o->id;
+  return MyGame::Example::CreateReferrable(
+      _fbb,
+      _id);
+}
+
+inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = new MonsterT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+inline void Monster::UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = pos(); if (_e) _o->pos = flatbuffers::unique_ptr<MyGame::Example::Vec3>(new MyGame::Example::Vec3(*_e)); };
+  { auto _e = mana(); _o->mana = _e; };
+  { auto _e = hp(); _o->hp = _e; };
+  { auto _e = name(); if (_e) _o->name = _e->str(); };
+  { auto _e = inventory(); if (_e) { _o->inventory.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->inventory[_i] = _e->Get(_i); } } };
+  { auto _e = color(); _o->color = _e; };
+  { auto _e = test_type(); _o->test.type = _e; };
+  { auto _e = test(); if (_e) _o->test.value = AnyUnion::UnPack(_e, test_type(), _resolver); };
+  { auto _e = test4(); if (_e) { _o->test4.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->test4[_i] = *_e->Get(_i); } } };
+  { auto _e = testarrayofstring(); if (_e) { _o->testarrayofstring.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofstring[_i] = _e->Get(_i)->str(); } } };
+  { auto _e = testarrayoftables(); if (_e) { _o->testarrayoftables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayoftables[_i] = flatbuffers::unique_ptr<MyGame::Example::MonsterT>(_e->Get(_i)->UnPack(_resolver)); } } };
+  { auto _e = enemy(); if (_e) _o->enemy = flatbuffers::unique_ptr<MyGame::Example::MonsterT>(_e->UnPack(_resolver)); };
+  { auto _e = testnestedflatbuffer(); if (_e) { _o->testnestedflatbuffer.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testnestedflatbuffer[_i] = _e->Get(_i); } } };
+  { auto _e = testempty(); if (_e) _o->testempty = flatbuffers::unique_ptr<MyGame::Example::StatT>(_e->UnPack(_resolver)); };
+  { auto _e = testbool(); _o->testbool = _e; };
+  { auto _e = testhashs32_fnv1(); _o->testhashs32_fnv1 = _e; };
+  { auto _e = testhashu32_fnv1(); _o->testhashu32_fnv1 = _e; };
+  { auto _e = testhashs64_fnv1(); _o->testhashs64_fnv1 = _e; };
+  { auto _e = testhashu64_fnv1(); _o->testhashu64_fnv1 = _e; };
+  { auto _e = testhashs32_fnv1a(); _o->testhashs32_fnv1a = _e; };
+  { auto _e = testhashu32_fnv1a(); //scalar resolver, naked 
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->testhashu32_fnv1a), static_cast<flatbuffers::hash_value_t>(_e)); else _o->testhashu32_fnv1a = nullptr; };
+  { auto _e = testhashs64_fnv1a(); _o->testhashs64_fnv1a = _e; };
+  { auto _e = testhashu64_fnv1a(); _o->testhashu64_fnv1a = _e; };
+  { auto _e = testarrayofbools(); if (_e) { _o->testarrayofbools.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofbools[_i] = _e->Get(_i) != 0; } } };
+  { auto _e = testf(); _o->testf = _e; };
+  { auto _e = testf2(); _o->testf2 = _e; };
+  { auto _e = testf3(); _o->testf3 = _e; };
+  { auto _e = testarrayofstring2(); if (_e) { _o->testarrayofstring2.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofstring2[_i] = _e->Get(_i)->str(); } } };
+  { auto _e = testarrayofsortedstruct(); if (_e) { _o->testarrayofsortedstruct.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofsortedstruct[_i] = *_e->Get(_i); } } };
+  { auto _e = flex(); if (_e) { _o->flex.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->flex[_i] = _e->Get(_i); } } };
+  { auto _e = test5(); if (_e) { _o->test5.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->test5[_i] = *_e->Get(_i); } } };
+  { auto _e = vector_of_longs(); if (_e) { _o->vector_of_longs.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_longs[_i] = _e->Get(_i); } } };
+  { auto _e = vector_of_doubles(); if (_e) { _o->vector_of_doubles.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_doubles[_i] = _e->Get(_i); } } };
+  { auto _e = parent_namespace_test(); if (_e) _o->parent_namespace_test = flatbuffers::unique_ptr<MyGame::InParentNamespaceT>(_e->UnPack(_resolver)); };
+  { auto _e = vector_of_referrables(); if (_e) { _o->vector_of_referrables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_referrables[_i] = flatbuffers::unique_ptr<MyGame::Example::ReferrableT>(_e->Get(_i)->UnPack(_resolver)); } } };
+  { auto _e = single_weak_reference(); //scalar resolver, naked 
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->single_weak_reference), static_cast<flatbuffers::hash_value_t>(_e)); else _o->single_weak_reference = nullptr; };
+  { auto _e = vector_of_weak_references(); if (_e) { _o->vector_of_weak_references.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { //vector resolver, naked
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->vector_of_weak_references[_i]), static_cast<flatbuffers::hash_value_t>(_e->Get(_i))); else _o->vector_of_weak_references[_i] = nullptr; } } };
+  { auto _e = vector_of_strong_referrables(); if (_e) { _o->vector_of_strong_referrables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_strong_referrables[_i] = flatbuffers::unique_ptr<MyGame::Example::ReferrableT>(_e->Get(_i)->UnPack(_resolver)); } } };
+  { auto _e = co_owning_reference(); //scalar resolver, naked 
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->co_owning_reference), static_cast<flatbuffers::hash_value_t>(_e)); else _o->co_owning_reference = nullptr; };
+  { auto _e = vector_of_co_owning_references(); if (_e) { _o->vector_of_co_owning_references.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { //vector resolver, default_ptr_type
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->vector_of_co_owning_references[_i]), static_cast<flatbuffers::hash_value_t>(_e->Get(_i)));/* else do nothing */; } } };
+  { auto _e = non_owning_reference(); //scalar resolver, naked 
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->non_owning_reference), static_cast<flatbuffers::hash_value_t>(_e)); else _o->non_owning_reference = nullptr; };
+  { auto _e = vector_of_non_owning_references(); if (_e) { _o->vector_of_non_owning_references.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { //vector resolver, naked
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->vector_of_non_owning_references[_i]), static_cast<flatbuffers::hash_value_t>(_e->Get(_i))); else _o->vector_of_non_owning_references[_i] = nullptr; } } };
+  { auto _e = any_unique_type(); _o->any_unique.type = _e; };
+  { auto _e = any_unique(); if (_e) _o->any_unique.value = AnyUniqueAliasesUnion::UnPack(_e, any_unique_type(), _resolver); };
+  { auto _e = any_ambiguous_type(); _o->any_ambiguous.type = _e; };
+  { auto _e = any_ambiguous(); if (_e) _o->any_ambiguous.value = AnyAmbiguousAliasesUnion::UnPack(_e, any_ambiguous_type(), _resolver); };
+  { auto _e = vector_of_enums(); if (_e) { _o->vector_of_enums.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_enums[_i] = static_cast<MyGame::Example::Color>(_e->Get(_i)); } } };
+}
+
+inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateMonster(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const MonsterT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _pos = _o->pos ? _o->pos.get() : 0;
+  auto _mana = _o->mana;
+  auto _hp = _o->hp;
+  auto _name = _fbb.CreateString(_o->name);
+  auto _inventory = _o->inventory.size() ? _fbb.CreateVector(_o->inventory) : 0;
+  auto _color = _o->color;
+  auto _test_type = _o->test.type;
+  auto _test = _o->test.Pack(_fbb);
+  auto _test4 = _o->test4.size() ? _fbb.CreateVectorOfStructs(_o->test4) : 0;
+  auto _testarrayofstring = _o->testarrayofstring.size() ? _fbb.CreateVectorOfStrings(_o->testarrayofstring) : 0;
+  auto _testarrayoftables = _o->testarrayoftables.size() ? _fbb.CreateVector<flatbuffers::Offset<MyGame::Example::Monster>> (_o->testarrayoftables.size(), [](size_t i, _VectorArgs *__va) { return CreateMonster(*__va->__fbb, __va->__o->testarrayoftables[i].get(), __va->__rehasher); }, &_va ) : 0;
+  auto _enemy = _o->enemy ? CreateMonster(_fbb, _o->enemy.get(), _rehasher) : 0;
+  auto _testnestedflatbuffer = _o->testnestedflatbuffer.size() ? _fbb.CreateVector(_o->testnestedflatbuffer) : 0;
+  auto _testempty = _o->testempty ? CreateStat(_fbb, _o->testempty.get(), _rehasher) : 0;
+  auto _testbool = _o->testbool;
+  auto _testhashs32_fnv1 = _o->testhashs32_fnv1;
+  auto _testhashu32_fnv1 = _o->testhashu32_fnv1;
+  auto _testhashs64_fnv1 = _o->testhashs64_fnv1;
+  auto _testhashu64_fnv1 = _o->testhashu64_fnv1;
+  auto _testhashs32_fnv1a = _o->testhashs32_fnv1a;
+  auto _testhashu32_fnv1a = _rehasher ? static_cast<uint32_t>((*_rehasher)(_o->testhashu32_fnv1a)) : 0;
+  auto _testhashs64_fnv1a = _o->testhashs64_fnv1a;
+  auto _testhashu64_fnv1a = _o->testhashu64_fnv1a;
+  auto _testarrayofbools = _o->testarrayofbools.size() ? _fbb.CreateVector(_o->testarrayofbools) : 0;
+  auto _testf = _o->testf;
+  auto _testf2 = _o->testf2;
+  auto _testf3 = _o->testf3;
+  auto _testarrayofstring2 = _o->testarrayofstring2.size() ? _fbb.CreateVectorOfStrings(_o->testarrayofstring2) : 0;
+  auto _testarrayofsortedstruct = _o->testarrayofsortedstruct.size() ? _fbb.CreateVectorOfStructs(_o->testarrayofsortedstruct) : 0;
+  auto _flex = _o->flex.size() ? _fbb.CreateVector(_o->flex) : 0;
+  auto _test5 = _o->test5.size() ? _fbb.CreateVectorOfStructs(_o->test5) : 0;
+  auto _vector_of_longs = _o->vector_of_longs.size() ? _fbb.CreateVector(_o->vector_of_longs) : 0;
+  auto _vector_of_doubles = _o->vector_of_doubles.size() ? _fbb.CreateVector(_o->vector_of_doubles) : 0;
+  auto _parent_namespace_test = _o->parent_namespace_test ? CreateInParentNamespace(_fbb, _o->parent_namespace_test.get(), _rehasher) : 0;
+  auto _vector_of_referrables = _o->vector_of_referrables.size() ? _fbb.CreateVector<flatbuffers::Offset<MyGame::Example::Referrable>> (_o->vector_of_referrables.size(), [](size_t i, _VectorArgs *__va) { return CreateReferrable(*__va->__fbb, __va->__o->vector_of_referrables[i].get(), __va->__rehasher); }, &_va ) : 0;
+  auto _single_weak_reference = _rehasher ? static_cast<uint64_t>((*_rehasher)(_o->single_weak_reference)) : 0;
+  auto _vector_of_weak_references = _o->vector_of_weak_references.size() ? _fbb.CreateVector<uint64_t>(_o->vector_of_weak_references.size(), [](size_t i, _VectorArgs *__va) { return __va->__rehasher ? static_cast<uint64_t>((*__va->__rehasher)(__va->__o->vector_of_weak_references[i])) : 0; }, &_va ) : 0;
+  auto _vector_of_strong_referrables = _o->vector_of_strong_referrables.size() ? _fbb.CreateVector<flatbuffers::Offset<MyGame::Example::Referrable>> (_o->vector_of_strong_referrables.size(), [](size_t i, _VectorArgs *__va) { return CreateReferrable(*__va->__fbb, __va->__o->vector_of_strong_referrables[i].get(), __va->__rehasher); }, &_va ) : 0;
+  auto _co_owning_reference = _rehasher ? static_cast<uint64_t>((*_rehasher)(_o->co_owning_reference)) : 0;
+  auto _vector_of_co_owning_references = _o->vector_of_co_owning_references.size() ? _fbb.CreateVector<uint64_t>(_o->vector_of_co_owning_references.size(), [](size_t i, _VectorArgs *__va) { return __va->__rehasher ? static_cast<uint64_t>((*__va->__rehasher)(__va->__o->vector_of_co_owning_references[i].get())) : 0; }, &_va ) : 0;
+  auto _non_owning_reference = _rehasher ? static_cast<uint64_t>((*_rehasher)(_o->non_owning_reference)) : 0;
+  auto _vector_of_non_owning_references = _o->vector_of_non_owning_references.size() ? _fbb.CreateVector<uint64_t>(_o->vector_of_non_owning_references.size(), [](size_t i, _VectorArgs *__va) { return __va->__rehasher ? static_cast<uint64_t>((*__va->__rehasher)(__va->__o->vector_of_non_owning_references[i])) : 0; }, &_va ) : 0;
+  auto _any_unique_type = _o->any_unique.type;
+  auto _any_unique = _o->any_unique.Pack(_fbb);
+  auto _any_ambiguous_type = _o->any_ambiguous.type;
+  auto _any_ambiguous = _o->any_ambiguous.Pack(_fbb);
+  auto _vector_of_enums = _o->vector_of_enums.size() ? _fbb.CreateVectorScalarCast<uint8_t>(flatbuffers::data(_o->vector_of_enums), _o->vector_of_enums.size()) : 0;
+  return MyGame::Example::CreateMonster(
+      _fbb,
+      _pos,
+      _mana,
+      _hp,
+      _name,
+      _inventory,
+      _color,
+      _test_type,
+      _test,
+      _test4,
+      _testarrayofstring,
+      _testarrayoftables,
+      _enemy,
+      _testnestedflatbuffer,
+      _testempty,
+      _testbool,
+      _testhashs32_fnv1,
+      _testhashu32_fnv1,
+      _testhashs64_fnv1,
+      _testhashu64_fnv1,
+      _testhashs32_fnv1a,
+      _testhashu32_fnv1a,
+      _testhashs64_fnv1a,
+      _testhashu64_fnv1a,
+      _testarrayofbools,
+      _testf,
+      _testf2,
+      _testf3,
+      _testarrayofstring2,
+      _testarrayofsortedstruct,
+      _flex,
+      _test5,
+      _vector_of_longs,
+      _vector_of_doubles,
+      _parent_namespace_test,
+      _vector_of_referrables,
+      _single_weak_reference,
+      _vector_of_weak_references,
+      _vector_of_strong_referrables,
+      _co_owning_reference,
+      _vector_of_co_owning_references,
+      _non_owning_reference,
+      _vector_of_non_owning_references,
+      _any_unique_type,
+      _any_unique,
+      _any_ambiguous_type,
+      _any_ambiguous,
+      _vector_of_enums);
+}
+
+inline TypeAliasesT *TypeAliases::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = new TypeAliasesT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+inline void TypeAliases::UnPackTo(TypeAliasesT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = i8(); _o->i8 = _e; };
+  { auto _e = u8(); _o->u8 = _e; };
+  { auto _e = i16(); _o->i16 = _e; };
+  { auto _e = u16(); _o->u16 = _e; };
+  { auto _e = i32(); _o->i32 = _e; };
+  { auto _e = u32(); _o->u32 = _e; };
+  { auto _e = i64(); _o->i64 = _e; };
+  { auto _e = u64(); _o->u64 = _e; };
+  { auto _e = f32(); _o->f32 = _e; };
+  { auto _e = f64(); _o->f64 = _e; };
+  { auto _e = v8(); if (_e) { _o->v8.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->v8[_i] = _e->Get(_i); } } };
+  { auto _e = vf64(); if (_e) { _o->vf64.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vf64[_i] = _e->Get(_i); } } };
+}
+
+inline flatbuffers::Offset<TypeAliases> TypeAliases::Pack(flatbuffers::FlatBufferBuilder &_fbb, const TypeAliasesT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateTypeAliases(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<TypeAliases> CreateTypeAliases(flatbuffers::FlatBufferBuilder &_fbb, const TypeAliasesT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const TypeAliasesT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _i8 = _o->i8;
+  auto _u8 = _o->u8;
+  auto _i16 = _o->i16;
+  auto _u16 = _o->u16;
+  auto _i32 = _o->i32;
+  auto _u32 = _o->u32;
+  auto _i64 = _o->i64;
+  auto _u64 = _o->u64;
+  auto _f32 = _o->f32;
+  auto _f64 = _o->f64;
+  auto _v8 = _o->v8.size() ? _fbb.CreateVector(_o->v8) : 0;
+  auto _vf64 = _o->vf64.size() ? _fbb.CreateVector(_o->vf64) : 0;
+  return MyGame::Example::CreateTypeAliases(
+      _fbb,
+      _i8,
+      _u8,
+      _i16,
+      _u16,
+      _i32,
+      _u32,
+      _i64,
+      _u64,
+      _f32,
+      _f64,
+      _v8,
+      _vf64);
+}
+
+inline bool VerifyAny(flatbuffers::Verifier &verifier, const void *obj, Any type) {
+  switch (type) {
+    case Any_NONE: {
+      return true;
+    }
+    case Any_Monster: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    case Any_TestSimpleTableWithEnum: {
+      auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnum *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    case Any_MyGame_Example2_Monster: {
+      auto ptr = reinterpret_cast<const MyGame::Example2::Monster *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    default: return false;
+  }
+}
+
+inline bool VerifyAnyVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
+  if (!values || !types) return !values && !types;
+  if (values->size() != types->size()) return false;
+  for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+    if (!VerifyAny(
+        verifier,  values->Get(i), types->GetEnum<Any>(i))) {
+      return false;
+    }
+  }
+  return true;
+}
+
+inline void *AnyUnion::UnPack(const void *obj, Any type, const flatbuffers::resolver_function_t *resolver) {
+  switch (type) {
+    case Any_Monster: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    case Any_TestSimpleTableWithEnum: {
+      auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnum *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    case Any_MyGame_Example2_Monster: {
+      auto ptr = reinterpret_cast<const MyGame::Example2::Monster *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    default: return nullptr;
+  }
+}
+
+inline flatbuffers::Offset<void> AnyUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const {
+  switch (type) {
+    case Any_Monster: {
+      auto ptr = reinterpret_cast<const MyGame::Example::MonsterT *>(value);
+      return CreateMonster(_fbb, ptr, _rehasher).Union();
+    }
+    case Any_TestSimpleTableWithEnum: {
+      auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(value);
+      return CreateTestSimpleTableWithEnum(_fbb, ptr, _rehasher).Union();
+    }
+    case Any_MyGame_Example2_Monster: {
+      auto ptr = reinterpret_cast<const MyGame::Example2::MonsterT *>(value);
+      return CreateMonster(_fbb, ptr, _rehasher).Union();
+    }
+    default: return 0;
+  }
+}
+
+inline AnyUnion::AnyUnion(const AnyUnion &u) FLATBUFFERS_NOEXCEPT : type(u.type), value(nullptr) {
+  switch (type) {
+    case Any_Monster: {
+      FLATBUFFERS_ASSERT(false);  // MyGame::Example::MonsterT not copyable.
+      break;
+    }
+    case Any_TestSimpleTableWithEnum: {
+      value = new MyGame::Example::TestSimpleTableWithEnumT(*reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(u.value));
+      break;
+    }
+    case Any_MyGame_Example2_Monster: {
+      value = new MyGame::Example2::MonsterT(*reinterpret_cast<MyGame::Example2::MonsterT *>(u.value));
+      break;
+    }
+    default:
+      break;
+  }
+}
+
+inline void AnyUnion::Reset() {
+  switch (type) {
+    case Any_Monster: {
+      auto ptr = reinterpret_cast<MyGame::Example::MonsterT *>(value);
+      delete ptr;
+      break;
+    }
+    case Any_TestSimpleTableWithEnum: {
+      auto ptr = reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(value);
+      delete ptr;
+      break;
+    }
+    case Any_MyGame_Example2_Monster: {
+      auto ptr = reinterpret_cast<MyGame::Example2::MonsterT *>(value);
+      delete ptr;
+      break;
+    }
+    default: break;
+  }
+  value = nullptr;
+  type = Any_NONE;
+}
+
+inline bool VerifyAnyUniqueAliases(flatbuffers::Verifier &verifier, const void *obj, AnyUniqueAliases type) {
+  switch (type) {
+    case AnyUniqueAliases_NONE: {
+      return true;
+    }
+    case AnyUniqueAliases_M: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    case AnyUniqueAliases_TS: {
+      auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnum *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    case AnyUniqueAliases_M2: {
+      auto ptr = reinterpret_cast<const MyGame::Example2::Monster *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    default: return false;
+  }
+}
+
+inline bool VerifyAnyUniqueAliasesVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
+  if (!values || !types) return !values && !types;
+  if (values->size() != types->size()) return false;
+  for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+    if (!VerifyAnyUniqueAliases(
+        verifier,  values->Get(i), types->GetEnum<AnyUniqueAliases>(i))) {
+      return false;
+    }
+  }
+  return true;
+}
+
+inline void *AnyUniqueAliasesUnion::UnPack(const void *obj, AnyUniqueAliases type, const flatbuffers::resolver_function_t *resolver) {
+  switch (type) {
+    case AnyUniqueAliases_M: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    case AnyUniqueAliases_TS: {
+      auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnum *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    case AnyUniqueAliases_M2: {
+      auto ptr = reinterpret_cast<const MyGame::Example2::Monster *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    default: return nullptr;
+  }
+}
+
+inline flatbuffers::Offset<void> AnyUniqueAliasesUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const {
+  switch (type) {
+    case AnyUniqueAliases_M: {
+      auto ptr = reinterpret_cast<const MyGame::Example::MonsterT *>(value);
+      return CreateMonster(_fbb, ptr, _rehasher).Union();
+    }
+    case AnyUniqueAliases_TS: {
+      auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(value);
+      return CreateTestSimpleTableWithEnum(_fbb, ptr, _rehasher).Union();
+    }
+    case AnyUniqueAliases_M2: {
+      auto ptr = reinterpret_cast<const MyGame::Example2::MonsterT *>(value);
+      return CreateMonster(_fbb, ptr, _rehasher).Union();
+    }
+    default: return 0;
+  }
+}
+
+inline AnyUniqueAliasesUnion::AnyUniqueAliasesUnion(const AnyUniqueAliasesUnion &u) FLATBUFFERS_NOEXCEPT : type(u.type), value(nullptr) {
+  switch (type) {
+    case AnyUniqueAliases_M: {
+      FLATBUFFERS_ASSERT(false);  // MyGame::Example::MonsterT not copyable.
+      break;
+    }
+    case AnyUniqueAliases_TS: {
+      value = new MyGame::Example::TestSimpleTableWithEnumT(*reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(u.value));
+      break;
+    }
+    case AnyUniqueAliases_M2: {
+      value = new MyGame::Example2::MonsterT(*reinterpret_cast<MyGame::Example2::MonsterT *>(u.value));
+      break;
+    }
+    default:
+      break;
+  }
+}
+
+inline void AnyUniqueAliasesUnion::Reset() {
+  switch (type) {
+    case AnyUniqueAliases_M: {
+      auto ptr = reinterpret_cast<MyGame::Example::MonsterT *>(value);
+      delete ptr;
+      break;
+    }
+    case AnyUniqueAliases_TS: {
+      auto ptr = reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(value);
+      delete ptr;
+      break;
+    }
+    case AnyUniqueAliases_M2: {
+      auto ptr = reinterpret_cast<MyGame::Example2::MonsterT *>(value);
+      delete ptr;
+      break;
+    }
+    default: break;
+  }
+  value = nullptr;
+  type = AnyUniqueAliases_NONE;
+}
+
+inline bool VerifyAnyAmbiguousAliases(flatbuffers::Verifier &verifier, const void *obj, AnyAmbiguousAliases type) {
+  switch (type) {
+    case AnyAmbiguousAliases_NONE: {
+      return true;
+    }
+    case AnyAmbiguousAliases_M1: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    case AnyAmbiguousAliases_M2: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    case AnyAmbiguousAliases_M3: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    default: return false;
+  }
+}
+
+inline bool VerifyAnyAmbiguousAliasesVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
+  if (!values || !types) return !values && !types;
+  if (values->size() != types->size()) return false;
+  for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+    if (!VerifyAnyAmbiguousAliases(
+        verifier,  values->Get(i), types->GetEnum<AnyAmbiguousAliases>(i))) {
+      return false;
+    }
+  }
+  return true;
+}
+
+inline void *AnyAmbiguousAliasesUnion::UnPack(const void *obj, AnyAmbiguousAliases type, const flatbuffers::resolver_function_t *resolver) {
+  switch (type) {
+    case AnyAmbiguousAliases_M1: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    case AnyAmbiguousAliases_M2: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    case AnyAmbiguousAliases_M3: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    default: return nullptr;
+  }
+}
+
+inline flatbuffers::Offset<void> AnyAmbiguousAliasesUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const {
+  switch (type) {
+    case AnyAmbiguousAliases_M1: {
+      auto ptr = reinterpret_cast<const MyGame::Example::MonsterT *>(value);
+      return CreateMonster(_fbb, ptr, _rehasher).Union();
+    }
+    case AnyAmbiguousAliases_M2: {
+      auto ptr = reinterpret_cast<const MyGame::Example::MonsterT *>(value);
+      return CreateMonster(_fbb, ptr, _rehasher).Union();
+    }
+    case AnyAmbiguousAliases_M3: {
+      auto ptr = reinterpret_cast<const MyGame::Example::MonsterT *>(value);
+      return CreateMonster(_fbb, ptr, _rehasher).Union();
+    }
+    default: return 0;
+  }
+}
+
+inline AnyAmbiguousAliasesUnion::AnyAmbiguousAliasesUnion(const AnyAmbiguousAliasesUnion &u) FLATBUFFERS_NOEXCEPT : type(u.type), value(nullptr) {
+  switch (type) {
+    case AnyAmbiguousAliases_M1: {
+      FLATBUFFERS_ASSERT(false);  // MyGame::Example::MonsterT not copyable.
+      break;
+    }
+    case AnyAmbiguousAliases_M2: {
+      FLATBUFFERS_ASSERT(false);  // MyGame::Example::MonsterT not copyable.
+      break;
+    }
+    case AnyAmbiguousAliases_M3: {
+      FLATBUFFERS_ASSERT(false);  // MyGame::Example::MonsterT not copyable.
+      break;
+    }
+    default:
+      break;
+  }
+}
+
+inline void AnyAmbiguousAliasesUnion::Reset() {
+  switch (type) {
+    case AnyAmbiguousAliases_M1: {
+      auto ptr = reinterpret_cast<MyGame::Example::MonsterT *>(value);
+      delete ptr;
+      break;
+    }
+    case AnyAmbiguousAliases_M2: {
+      auto ptr = reinterpret_cast<MyGame::Example::MonsterT *>(value);
+      delete ptr;
+      break;
+    }
+    case AnyAmbiguousAliases_M3: {
+      auto ptr = reinterpret_cast<MyGame::Example::MonsterT *>(value);
+      delete ptr;
+      break;
+    }
+    default: break;
+  }
+  value = nullptr;
+  type = AnyAmbiguousAliases_NONE;
+}
+
+inline const flatbuffers::TypeTable *ColorTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_UCHAR, 0, 0 },
+    { flatbuffers::ET_UCHAR, 0, 0 },
+    { flatbuffers::ET_UCHAR, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::ColorTypeTable
+  };
+  static const int64_t values[] = { 1, 2, 8 };
+  static const char * const names[] = {
+    "Red",
+    "Green",
+    "Blue"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_ENUM, 3, type_codes, type_refs, values, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *AnyTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 0, -1 },
+    { flatbuffers::ET_SEQUENCE, 0, 0 },
+    { flatbuffers::ET_SEQUENCE, 0, 1 },
+    { flatbuffers::ET_SEQUENCE, 0, 2 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::MonsterTypeTable,
+    MyGame::Example::TestSimpleTableWithEnumTypeTable,
+    MyGame::Example2::MonsterTypeTable
+  };
+  static const char * const names[] = {
+    "NONE",
+    "Monster",
+    "TestSimpleTableWithEnum",
+    "MyGame_Example2_Monster"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_UNION, 4, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *AnyUniqueAliasesTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 0, -1 },
+    { flatbuffers::ET_SEQUENCE, 0, 0 },
+    { flatbuffers::ET_SEQUENCE, 0, 1 },
+    { flatbuffers::ET_SEQUENCE, 0, 2 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::MonsterTypeTable,
+    MyGame::Example::TestSimpleTableWithEnumTypeTable,
+    MyGame::Example2::MonsterTypeTable
+  };
+  static const char * const names[] = {
+    "NONE",
+    "M",
+    "TS",
+    "M2"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_UNION, 4, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *AnyAmbiguousAliasesTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 0, -1 },
+    { flatbuffers::ET_SEQUENCE, 0, 0 },
+    { flatbuffers::ET_SEQUENCE, 0, 0 },
+    { flatbuffers::ET_SEQUENCE, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::MonsterTypeTable
+  };
+  static const char * const names[] = {
+    "NONE",
+    "M1",
+    "M2",
+    "M3"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_UNION, 4, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+}  // namespace Example
+
+inline const flatbuffers::TypeTable *InParentNamespaceTypeTable() {
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 0, nullptr, nullptr, nullptr, nullptr
+  };
+  return &tt;
+}
+
+namespace Example2 {
+
+inline const flatbuffers::TypeTable *MonsterTypeTable() {
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 0, nullptr, nullptr, nullptr, nullptr
+  };
+  return &tt;
+}
+
+}  // namespace Example2
+
+namespace Example {
+
+inline const flatbuffers::TypeTable *TestTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SHORT, 0, -1 },
+    { flatbuffers::ET_CHAR, 0, -1 }
+  };
+  static const int64_t values[] = { 0, 2, 4 };
+  static const char * const names[] = {
+    "a",
+    "b"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_STRUCT, 2, type_codes, nullptr, values, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *TestSimpleTableWithEnumTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_UCHAR, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::ColorTypeTable
+  };
+  static const char * const names[] = {
+    "color"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 1, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *Vec3TypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_DOUBLE, 0, -1 },
+    { flatbuffers::ET_UCHAR, 0, 0 },
+    { flatbuffers::ET_SEQUENCE, 0, 1 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::ColorTypeTable,
+    MyGame::Example::TestTypeTable
+  };
+  static const int64_t values[] = { 0, 4, 8, 16, 24, 26, 32 };
+  static const char * const names[] = {
+    "x",
+    "y",
+    "z",
+    "test1",
+    "test2",
+    "test3"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_STRUCT, 6, type_codes, type_refs, values, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *AbilityTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_UINT, 0, -1 },
+    { flatbuffers::ET_UINT, 0, -1 }
+  };
+  static const int64_t values[] = { 0, 4, 8 };
+  static const char * const names[] = {
+    "id",
+    "distance"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_STRUCT, 2, type_codes, nullptr, values, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *StatTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_STRING, 0, -1 },
+    { flatbuffers::ET_LONG, 0, -1 },
+    { flatbuffers::ET_USHORT, 0, -1 }
+  };
+  static const char * const names[] = {
+    "id",
+    "val",
+    "count"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 3, type_codes, nullptr, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *ReferrableTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_ULONG, 0, -1 }
+  };
+  static const char * const names[] = {
+    "id"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 1, type_codes, nullptr, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *MonsterTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 0, 0 },
+    { flatbuffers::ET_SHORT, 0, -1 },
+    { flatbuffers::ET_SHORT, 0, -1 },
+    { flatbuffers::ET_STRING, 0, -1 },
+    { flatbuffers::ET_BOOL, 0, -1 },
+    { flatbuffers::ET_UCHAR, 1, -1 },
+    { flatbuffers::ET_UCHAR, 0, 1 },
+    { flatbuffers::ET_UTYPE, 0, 2 },
+    { flatbuffers::ET_SEQUENCE, 0, 2 },
+    { flatbuffers::ET_SEQUENCE, 1, 3 },
+    { flatbuffers::ET_STRING, 1, -1 },
+    { flatbuffers::ET_SEQUENCE, 1, 4 },
+    { flatbuffers::ET_SEQUENCE, 0, 4 },
+    { flatbuffers::ET_UCHAR, 1, -1 },
+    { flatbuffers::ET_SEQUENCE, 0, 5 },
+    { flatbuffers::ET_BOOL, 0, -1 },
+    { flatbuffers::ET_INT, 0, -1 },
+    { flatbuffers::ET_UINT, 0, -1 },
+    { flatbuffers::ET_LONG, 0, -1 },
+    { flatbuffers::ET_ULONG, 0, -1 },
+    { flatbuffers::ET_INT, 0, -1 },
+    { flatbuffers::ET_UINT, 0, -1 },
+    { flatbuffers::ET_LONG, 0, -1 },
+    { flatbuffers::ET_ULONG, 0, -1 },
+    { flatbuffers::ET_BOOL, 1, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_STRING, 1, -1 },
+    { flatbuffers::ET_SEQUENCE, 1, 6 },
+    { flatbuffers::ET_UCHAR, 1, -1 },
+    { flatbuffers::ET_SEQUENCE, 1, 3 },
+    { flatbuffers::ET_LONG, 1, -1 },
+    { flatbuffers::ET_DOUBLE, 1, -1 },
+    { flatbuffers::ET_SEQUENCE, 0, 7 },
+    { flatbuffers::ET_SEQUENCE, 1, 8 },
+    { flatbuffers::ET_ULONG, 0, -1 },
+    { flatbuffers::ET_ULONG, 1, -1 },
+    { flatbuffers::ET_SEQUENCE, 1, 8 },
+    { flatbuffers::ET_ULONG, 0, -1 },
+    { flatbuffers::ET_ULONG, 1, -1 },
+    { flatbuffers::ET_ULONG, 0, -1 },
+    { flatbuffers::ET_ULONG, 1, -1 },
+    { flatbuffers::ET_UTYPE, 0, 9 },
+    { flatbuffers::ET_SEQUENCE, 0, 9 },
+    { flatbuffers::ET_UTYPE, 0, 10 },
+    { flatbuffers::ET_SEQUENCE, 0, 10 },
+    { flatbuffers::ET_UCHAR, 1, 1 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::Vec3TypeTable,
+    MyGame::Example::ColorTypeTable,
+    MyGame::Example::AnyTypeTable,
+    MyGame::Example::TestTypeTable,
+    MyGame::Example::MonsterTypeTable,
+    MyGame::Example::StatTypeTable,
+    MyGame::Example::AbilityTypeTable,
+    MyGame::InParentNamespaceTypeTable,
+    MyGame::Example::ReferrableTypeTable,
+    MyGame::Example::AnyUniqueAliasesTypeTable,
+    MyGame::Example::AnyAmbiguousAliasesTypeTable
+  };
+  static const char * const names[] = {
+    "pos",
+    "mana",
+    "hp",
+    "name",
+    "friendly",
+    "inventory",
+    "color",
+    "test_type",
+    "test",
+    "test4",
+    "testarrayofstring",
+    "testarrayoftables",
+    "enemy",
+    "testnestedflatbuffer",
+    "testempty",
+    "testbool",
+    "testhashs32_fnv1",
+    "testhashu32_fnv1",
+    "testhashs64_fnv1",
+    "testhashu64_fnv1",
+    "testhashs32_fnv1a",
+    "testhashu32_fnv1a",
+    "testhashs64_fnv1a",
+    "testhashu64_fnv1a",
+    "testarrayofbools",
+    "testf",
+    "testf2",
+    "testf3",
+    "testarrayofstring2",
+    "testarrayofsortedstruct",
+    "flex",
+    "test5",
+    "vector_of_longs",
+    "vector_of_doubles",
+    "parent_namespace_test",
+    "vector_of_referrables",
+    "single_weak_reference",
+    "vector_of_weak_references",
+    "vector_of_strong_referrables",
+    "co_owning_reference",
+    "vector_of_co_owning_references",
+    "non_owning_reference",
+    "vector_of_non_owning_references",
+    "any_unique_type",
+    "any_unique",
+    "any_ambiguous_type",
+    "any_ambiguous",
+    "vector_of_enums"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 48, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *TypeAliasesTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_CHAR, 0, -1 },
+    { flatbuffers::ET_UCHAR, 0, -1 },
+    { flatbuffers::ET_SHORT, 0, -1 },
+    { flatbuffers::ET_USHORT, 0, -1 },
+    { flatbuffers::ET_INT, 0, -1 },
+    { flatbuffers::ET_UINT, 0, -1 },
+    { flatbuffers::ET_LONG, 0, -1 },
+    { flatbuffers::ET_ULONG, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_DOUBLE, 0, -1 },
+    { flatbuffers::ET_CHAR, 1, -1 },
+    { flatbuffers::ET_DOUBLE, 1, -1 }
+  };
+  static const char * const names[] = {
+    "i8",
+    "u8",
+    "i16",
+    "u16",
+    "i32",
+    "u32",
+    "i64",
+    "u64",
+    "f32",
+    "f64",
+    "v8",
+    "vf64"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 12, type_codes, nullptr, nullptr, names
+  };
+  return &tt;
+}
+
+inline const MyGame::Example::Monster *GetMonster(const void *buf) {
+  return flatbuffers::GetRoot<MyGame::Example::Monster>(buf);
+}
+
+inline const MyGame::Example::Monster *GetSizePrefixedMonster(const void *buf) {
+  return flatbuffers::GetSizePrefixedRoot<MyGame::Example::Monster>(buf);
+}
+
+inline Monster *GetMutableMonster(void *buf) {
+  return flatbuffers::GetMutableRoot<Monster>(buf);
+}
+
+inline const char *MonsterIdentifier() {
+  return "MONS";
+}
+
+inline bool MonsterBufferHasIdentifier(const void *buf) {
+  return flatbuffers::BufferHasIdentifier(
+      buf, MonsterIdentifier());
+}
+
+inline bool VerifyMonsterBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifyBuffer<MyGame::Example::Monster>(MonsterIdentifier());
+}
+
+inline bool VerifySizePrefixedMonsterBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifySizePrefixedBuffer<MyGame::Example::Monster>(MonsterIdentifier());
+}
+
+inline const char *MonsterExtension() {
+  return "mon";
+}
+
+inline void FinishMonsterBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<MyGame::Example::Monster> root) {
+  fbb.Finish(root, MonsterIdentifier());
+}
+
+inline void FinishSizePrefixedMonsterBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<MyGame::Example::Monster> root) {
+  fbb.FinishSizePrefixed(root, MonsterIdentifier());
+}
+
+inline flatbuffers::unique_ptr<MyGame::Example::MonsterT> UnPackMonster(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return flatbuffers::unique_ptr<MyGame::Example::MonsterT>(GetMonster(buf)->UnPack(res));
+}
+
+inline flatbuffers::unique_ptr<MyGame::Example::MonsterT> UnPackSizePrefixedMonster(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return flatbuffers::unique_ptr<MyGame::Example::MonsterT>(GetSizePrefixedMonster(buf)->UnPack(res));
+}
+
+}  // namespace Example
+}  // namespace MyGame
+
+#endif  // FLATBUFFERS_GENERATED_MONSTERTEST_MYGAME_EXAMPLE_H_
diff --git a/third_party/flatbuffers/tests/monster_test_generated.js b/third_party/flatbuffers/tests/monster_test_generated.js
new file mode 100644
index 0000000..2a68288
--- /dev/null
+++ b/third_party/flatbuffers/tests/monster_test_generated.js
@@ -0,0 +1,3299 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+/**
+ * @const
+ * @namespace
+ */
+var MyGame = MyGame || {};
+
+/**
+ * @const
+ * @namespace
+ */
+MyGame.Example = MyGame.Example || {};
+
+/**
+ * @const
+ * @namespace
+ */
+MyGame.Example2 = MyGame.Example2 || {};
+
+/**
+ * @const
+ * @namespace
+ */
+MyGame.OtherNameSpace = MyGame.OtherNameSpace || {};
+
+/**
+ * Composite components of Monster color.
+ *
+ * @enum {number}
+ */
+MyGame.Example.Color = {
+  Red: 1,
+
+  /**
+   * \brief color Green
+   * Green is bit_flag with value (1u << 1)
+   */
+  Green: 2,
+
+  /**
+   * \brief color Blue (1u << 3)
+   */
+  Blue: 8
+};
+
+/**
+ * Composite components of Monster color.
+ *
+ * @enum {string}
+ */
+MyGame.Example.ColorName = {
+  1: 'Red',
+
+  /**
+   * \brief color Green
+   * Green is bit_flag with value (1u << 1)
+   */
+  2: 'Green',
+
+  /**
+   * \brief color Blue (1u << 3)
+   */
+  8: 'Blue'
+};
+
+/**
+ * @enum {number}
+ */
+MyGame.Example.Any = {
+  NONE: 0,
+  Monster: 1,
+  TestSimpleTableWithEnum: 2,
+  MyGame_Example2_Monster: 3
+};
+
+/**
+ * @enum {string}
+ */
+MyGame.Example.AnyName = {
+  0: 'NONE',
+  1: 'Monster',
+  2: 'TestSimpleTableWithEnum',
+  3: 'MyGame_Example2_Monster'
+};
+
+/**
+ * @enum {number}
+ */
+MyGame.Example.AnyUniqueAliases = {
+  NONE: 0,
+  M: 1,
+  TS: 2,
+  M2: 3
+};
+
+/**
+ * @enum {string}
+ */
+MyGame.Example.AnyUniqueAliasesName = {
+  0: 'NONE',
+  1: 'M',
+  2: 'TS',
+  3: 'M2'
+};
+
+/**
+ * @enum {number}
+ */
+MyGame.Example.AnyAmbiguousAliases = {
+  NONE: 0,
+  M1: 1,
+  M2: 2,
+  M3: 3
+};
+
+/**
+ * @enum {string}
+ */
+MyGame.Example.AnyAmbiguousAliasesName = {
+  0: 'NONE',
+  1: 'M1',
+  2: 'M2',
+  3: 'M3'
+};
+
+/**
+ * @constructor
+ */
+MyGame.InParentNamespace = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {MyGame.InParentNamespace}
+ */
+MyGame.InParentNamespace.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.InParentNamespace=} obj
+ * @returns {MyGame.InParentNamespace}
+ */
+MyGame.InParentNamespace.getRootAsInParentNamespace = function(bb, obj) {
+  return (obj || new MyGame.InParentNamespace).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.InParentNamespace=} obj
+ * @returns {MyGame.InParentNamespace}
+ */
+MyGame.InParentNamespace.getSizePrefixedRootAsInParentNamespace = function(bb, obj) {
+  return (obj || new MyGame.InParentNamespace).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ */
+MyGame.InParentNamespace.startInParentNamespace = function(builder) {
+  builder.startObject(0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.InParentNamespace.endInParentNamespace = function(builder) {
+  var offset = builder.endObject();
+  return offset;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.InParentNamespace.createInParentNamespace = function(builder) {
+  MyGame.InParentNamespace.startInParentNamespace(builder);
+  return MyGame.InParentNamespace.endInParentNamespace(builder);
+}
+
+/**
+ * @constructor
+ */
+MyGame.Example2.Monster = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {MyGame.Example2.Monster}
+ */
+MyGame.Example2.Monster.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example2.Monster=} obj
+ * @returns {MyGame.Example2.Monster}
+ */
+MyGame.Example2.Monster.getRootAsMonster = function(bb, obj) {
+  return (obj || new MyGame.Example2.Monster).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example2.Monster=} obj
+ * @returns {MyGame.Example2.Monster}
+ */
+MyGame.Example2.Monster.getSizePrefixedRootAsMonster = function(bb, obj) {
+  return (obj || new MyGame.Example2.Monster).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ */
+MyGame.Example2.Monster.startMonster = function(builder) {
+  builder.startObject(0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example2.Monster.endMonster = function(builder) {
+  var offset = builder.endObject();
+  return offset;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example2.Monster.createMonster = function(builder) {
+  MyGame.Example2.Monster.startMonster(builder);
+  return MyGame.Example2.Monster.endMonster(builder);
+}
+
+/**
+ * @constructor
+ */
+MyGame.Example.Test = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {MyGame.Example.Test}
+ */
+MyGame.Example.Test.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Test.prototype.a = function() {
+  return this.bb.readInt16(this.bb_pos);
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Test.prototype.mutate_a = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 0);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt16(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Test.prototype.b = function() {
+  return this.bb.readInt8(this.bb_pos + 2);
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Test.prototype.mutate_b = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 2);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} a
+ * @param {number} b
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Test.createTest = function(builder, a, b) {
+  builder.prep(2, 4);
+  builder.pad(1);
+  builder.writeInt8(b);
+  builder.writeInt16(a);
+  return builder.offset();
+};
+
+/**
+ * @constructor
+ */
+MyGame.Example.TestSimpleTableWithEnum = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {MyGame.Example.TestSimpleTableWithEnum}
+ */
+MyGame.Example.TestSimpleTableWithEnum.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example.TestSimpleTableWithEnum=} obj
+ * @returns {MyGame.Example.TestSimpleTableWithEnum}
+ */
+MyGame.Example.TestSimpleTableWithEnum.getRootAsTestSimpleTableWithEnum = function(bb, obj) {
+  return (obj || new MyGame.Example.TestSimpleTableWithEnum).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example.TestSimpleTableWithEnum=} obj
+ * @returns {MyGame.Example.TestSimpleTableWithEnum}
+ */
+MyGame.Example.TestSimpleTableWithEnum.getSizePrefixedRootAsTestSimpleTableWithEnum = function(bb, obj) {
+  return (obj || new MyGame.Example.TestSimpleTableWithEnum).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @returns {MyGame.Example.Color}
+ */
+MyGame.Example.TestSimpleTableWithEnum.prototype.color = function() {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+  return offset ? /** @type {MyGame.Example.Color} */ (this.bb.readUint8(this.bb_pos + offset)) : MyGame.Example.Color.Green;
+};
+
+/**
+ * @param {MyGame.Example.Color} value
+ * @returns {boolean}
+ */
+MyGame.Example.TestSimpleTableWithEnum.prototype.mutate_color = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ */
+MyGame.Example.TestSimpleTableWithEnum.startTestSimpleTableWithEnum = function(builder) {
+  builder.startObject(1);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {MyGame.Example.Color} color
+ */
+MyGame.Example.TestSimpleTableWithEnum.addColor = function(builder, color) {
+  builder.addFieldInt8(0, color, MyGame.Example.Color.Green);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.TestSimpleTableWithEnum.endTestSimpleTableWithEnum = function(builder) {
+  var offset = builder.endObject();
+  return offset;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {MyGame.Example.Color} color
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.TestSimpleTableWithEnum.createTestSimpleTableWithEnum = function(builder, color) {
+  MyGame.Example.TestSimpleTableWithEnum.startTestSimpleTableWithEnum(builder);
+  MyGame.Example.TestSimpleTableWithEnum.addColor(builder, color);
+  return MyGame.Example.TestSimpleTableWithEnum.endTestSimpleTableWithEnum(builder);
+}
+
+/**
+ * @constructor
+ */
+MyGame.Example.Vec3 = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {MyGame.Example.Vec3}
+ */
+MyGame.Example.Vec3.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Vec3.prototype.x = function() {
+  return this.bb.readFloat32(this.bb_pos);
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Vec3.prototype.mutate_x = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 0);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Vec3.prototype.y = function() {
+  return this.bb.readFloat32(this.bb_pos + 4);
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Vec3.prototype.mutate_y = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Vec3.prototype.z = function() {
+  return this.bb.readFloat32(this.bb_pos + 8);
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Vec3.prototype.mutate_z = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 8);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Vec3.prototype.test1 = function() {
+  return this.bb.readFloat64(this.bb_pos + 16);
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Vec3.prototype.mutate_test1 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 16);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeFloat64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {MyGame.Example.Color}
+ */
+MyGame.Example.Vec3.prototype.test2 = function() {
+  return /** @type {MyGame.Example.Color} */ (this.bb.readUint8(this.bb_pos + 24));
+};
+
+/**
+ * @param {MyGame.Example.Color} value
+ * @returns {boolean}
+ */
+MyGame.Example.Vec3.prototype.mutate_test2 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 24);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {MyGame.Example.Test=} obj
+ * @returns {MyGame.Example.Test|null}
+ */
+MyGame.Example.Vec3.prototype.test3 = function(obj) {
+  return (obj || new MyGame.Example.Test).__init(this.bb_pos + 26, this.bb);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} x
+ * @param {number} y
+ * @param {number} z
+ * @param {number} test1
+ * @param {MyGame.Example.Color} test2
+ * @param {number} test3_a
+ * @param {number} test3_b
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Vec3.createVec3 = function(builder, x, y, z, test1, test2, test3_a, test3_b) {
+  builder.prep(8, 32);
+  builder.pad(2);
+  builder.prep(2, 4);
+  builder.pad(1);
+  builder.writeInt8(test3_b);
+  builder.writeInt16(test3_a);
+  builder.pad(1);
+  builder.writeInt8(test2);
+  builder.writeFloat64(test1);
+  builder.pad(4);
+  builder.writeFloat32(z);
+  builder.writeFloat32(y);
+  builder.writeFloat32(x);
+  return builder.offset();
+};
+
+/**
+ * @constructor
+ */
+MyGame.Example.Ability = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {MyGame.Example.Ability}
+ */
+MyGame.Example.Ability.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Ability.prototype.id = function() {
+  return this.bb.readUint32(this.bb_pos);
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Ability.prototype.mutate_id = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 0);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Ability.prototype.distance = function() {
+  return this.bb.readUint32(this.bb_pos + 4);
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Ability.prototype.mutate_distance = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} id
+ * @param {number} distance
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Ability.createAbility = function(builder, id, distance) {
+  builder.prep(4, 8);
+  builder.writeInt32(distance);
+  builder.writeInt32(id);
+  return builder.offset();
+};
+
+/**
+ * @constructor
+ */
+MyGame.Example.Stat = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {MyGame.Example.Stat}
+ */
+MyGame.Example.Stat.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example.Stat=} obj
+ * @returns {MyGame.Example.Stat}
+ */
+MyGame.Example.Stat.getRootAsStat = function(bb, obj) {
+  return (obj || new MyGame.Example.Stat).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example.Stat=} obj
+ * @returns {MyGame.Example.Stat}
+ */
+MyGame.Example.Stat.getSizePrefixedRootAsStat = function(bb, obj) {
+  return (obj || new MyGame.Example.Stat).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.Encoding=} optionalEncoding
+ * @returns {string|Uint8Array|null}
+ */
+MyGame.Example.Stat.prototype.id = function(optionalEncoding) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+  return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
+};
+
+/**
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.Stat.prototype.val = function() {
+  var offset = this.bb.__offset(this.bb_pos, 6);
+  return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @param {flatbuffers.Long} value
+ * @returns {boolean}
+ */
+MyGame.Example.Stat.prototype.mutate_val = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 6);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Stat.prototype.count = function() {
+  var offset = this.bb.__offset(this.bb_pos, 8);
+  return offset ? this.bb.readUint16(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Stat.prototype.mutate_count = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 8);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint16(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ */
+MyGame.Example.Stat.startStat = function(builder) {
+  builder.startObject(3);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} idOffset
+ */
+MyGame.Example.Stat.addId = function(builder, idOffset) {
+  builder.addFieldOffset(0, idOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Long} val
+ */
+MyGame.Example.Stat.addVal = function(builder, val) {
+  builder.addFieldInt64(1, val, builder.createLong(0, 0));
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} count
+ */
+MyGame.Example.Stat.addCount = function(builder, count) {
+  builder.addFieldInt16(2, count, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Stat.endStat = function(builder) {
+  var offset = builder.endObject();
+  return offset;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} idOffset
+ * @param {flatbuffers.Long} val
+ * @param {number} count
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Stat.createStat = function(builder, idOffset, val, count) {
+  MyGame.Example.Stat.startStat(builder);
+  MyGame.Example.Stat.addId(builder, idOffset);
+  MyGame.Example.Stat.addVal(builder, val);
+  MyGame.Example.Stat.addCount(builder, count);
+  return MyGame.Example.Stat.endStat(builder);
+}
+
+/**
+ * @constructor
+ */
+MyGame.Example.Referrable = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {MyGame.Example.Referrable}
+ */
+MyGame.Example.Referrable.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example.Referrable=} obj
+ * @returns {MyGame.Example.Referrable}
+ */
+MyGame.Example.Referrable.getRootAsReferrable = function(bb, obj) {
+  return (obj || new MyGame.Example.Referrable).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example.Referrable=} obj
+ * @returns {MyGame.Example.Referrable}
+ */
+MyGame.Example.Referrable.getSizePrefixedRootAsReferrable = function(bb, obj) {
+  return (obj || new MyGame.Example.Referrable).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.Referrable.prototype.id = function() {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+  return offset ? this.bb.readUint64(this.bb_pos + offset) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @param {flatbuffers.Long} value
+ * @returns {boolean}
+ */
+MyGame.Example.Referrable.prototype.mutate_id = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ */
+MyGame.Example.Referrable.startReferrable = function(builder) {
+  builder.startObject(1);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Long} id
+ */
+MyGame.Example.Referrable.addId = function(builder, id) {
+  builder.addFieldInt64(0, id, builder.createLong(0, 0));
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Referrable.endReferrable = function(builder) {
+  var offset = builder.endObject();
+  return offset;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Long} id
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Referrable.createReferrable = function(builder, id) {
+  MyGame.Example.Referrable.startReferrable(builder);
+  MyGame.Example.Referrable.addId(builder, id);
+  return MyGame.Example.Referrable.endReferrable(builder);
+}
+
+/**
+ * an example documentation comment: monster object
+ *
+ * @constructor
+ */
+MyGame.Example.Monster = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {MyGame.Example.Monster}
+ */
+MyGame.Example.Monster.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example.Monster=} obj
+ * @returns {MyGame.Example.Monster}
+ */
+MyGame.Example.Monster.getRootAsMonster = function(bb, obj) {
+  return (obj || new MyGame.Example.Monster).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example.Monster=} obj
+ * @returns {MyGame.Example.Monster}
+ */
+MyGame.Example.Monster.getSizePrefixedRootAsMonster = function(bb, obj) {
+  return (obj || new MyGame.Example.Monster).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.bufferHasIdentifier = function(bb) {
+  return bb.__has_identifier('MONS');
+};
+
+/**
+ * @param {MyGame.Example.Vec3=} obj
+ * @returns {MyGame.Example.Vec3|null}
+ */
+MyGame.Example.Monster.prototype.pos = function(obj) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+  return offset ? (obj || new MyGame.Example.Vec3).__init(this.bb_pos + offset, this.bb) : null;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.mana = function() {
+  var offset = this.bb.__offset(this.bb_pos, 6);
+  return offset ? this.bb.readInt16(this.bb_pos + offset) : 150;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_mana = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 6);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt16(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.hp = function() {
+  var offset = this.bb.__offset(this.bb_pos, 8);
+  return offset ? this.bb.readInt16(this.bb_pos + offset) : 100;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_hp = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 8);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt16(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Encoding=} optionalEncoding
+ * @returns {string|Uint8Array|null}
+ */
+MyGame.Example.Monster.prototype.name = function(optionalEncoding) {
+  var offset = this.bb.__offset(this.bb_pos, 10);
+  return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
+};
+
+/**
+ * @param {number} index
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.inventory = function(index) {
+  var offset = this.bb.__offset(this.bb_pos, 14);
+  return offset ? this.bb.readUint8(this.bb.__vector(this.bb_pos + offset) + index) : 0;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.inventoryLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 14);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns {Uint8Array}
+ */
+MyGame.Example.Monster.prototype.inventoryArray = function() {
+  var offset = this.bb.__offset(this.bb_pos, 14);
+  return offset ? new Uint8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @returns {MyGame.Example.Color}
+ */
+MyGame.Example.Monster.prototype.color = function() {
+  var offset = this.bb.__offset(this.bb_pos, 16);
+  return offset ? /** @type {MyGame.Example.Color} */ (this.bb.readUint8(this.bb_pos + offset)) : MyGame.Example.Color.Blue;
+};
+
+/**
+ * @param {MyGame.Example.Color} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_color = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 16);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {MyGame.Example.Any}
+ */
+MyGame.Example.Monster.prototype.testType = function() {
+  var offset = this.bb.__offset(this.bb_pos, 18);
+  return offset ? /** @type {MyGame.Example.Any} */ (this.bb.readUint8(this.bb_pos + offset)) : MyGame.Example.Any.NONE;
+};
+
+/**
+ * @param {MyGame.Example.Any} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_test_type = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 18);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Table} obj
+ * @returns {?flatbuffers.Table}
+ */
+MyGame.Example.Monster.prototype.test = function(obj) {
+  var offset = this.bb.__offset(this.bb_pos, 20);
+  return offset ? this.bb.__union(obj, this.bb_pos + offset) : null;
+};
+
+/**
+ * @param {number} index
+ * @param {MyGame.Example.Test=} obj
+ * @returns {MyGame.Example.Test}
+ */
+MyGame.Example.Monster.prototype.test4 = function(index, obj) {
+  var offset = this.bb.__offset(this.bb_pos, 22);
+  return offset ? (obj || new MyGame.Example.Test).__init(this.bb.__vector(this.bb_pos + offset) + index * 4, this.bb) : null;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.test4Length = function() {
+  var offset = this.bb.__offset(this.bb_pos, 22);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} index
+ * @param {flatbuffers.Encoding=} optionalEncoding
+ * @returns {string|Uint8Array}
+ */
+MyGame.Example.Monster.prototype.testarrayofstring = function(index, optionalEncoding) {
+  var offset = this.bb.__offset(this.bb_pos, 24);
+  return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testarrayofstringLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 24);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * an example documentation comment: this will end up in the generated code
+ * multiline too
+ *
+ * @param {number} index
+ * @param {MyGame.Example.Monster=} obj
+ * @returns {MyGame.Example.Monster}
+ */
+MyGame.Example.Monster.prototype.testarrayoftables = function(index, obj) {
+  var offset = this.bb.__offset(this.bb_pos, 26);
+  return offset ? (obj || new MyGame.Example.Monster).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testarrayoftablesLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 26);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {MyGame.Example.Monster=} obj
+ * @returns {MyGame.Example.Monster|null}
+ */
+MyGame.Example.Monster.prototype.enemy = function(obj) {
+  var offset = this.bb.__offset(this.bb_pos, 28);
+  return offset ? (obj || new MyGame.Example.Monster).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
+};
+
+/**
+ * @param {number} index
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testnestedflatbuffer = function(index) {
+  var offset = this.bb.__offset(this.bb_pos, 30);
+  return offset ? this.bb.readUint8(this.bb.__vector(this.bb_pos + offset) + index) : 0;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testnestedflatbufferLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 30);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns {Uint8Array}
+ */
+MyGame.Example.Monster.prototype.testnestedflatbufferArray = function() {
+  var offset = this.bb.__offset(this.bb_pos, 30);
+  return offset ? new Uint8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param {MyGame.Example.Stat=} obj
+ * @returns {MyGame.Example.Stat|null}
+ */
+MyGame.Example.Monster.prototype.testempty = function(obj) {
+  var offset = this.bb.__offset(this.bb_pos, 32);
+  return offset ? (obj || new MyGame.Example.Stat).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
+};
+
+/**
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.testbool = function() {
+  var offset = this.bb.__offset(this.bb_pos, 34);
+  return offset ? !!this.bb.readInt8(this.bb_pos + offset) : false;
+};
+
+/**
+ * @param {boolean} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_testbool = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 34);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testhashs32Fnv1 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 36);
+  return offset ? this.bb.readInt32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_testhashs32_fnv1 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 36);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testhashu32Fnv1 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 38);
+  return offset ? this.bb.readUint32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_testhashu32_fnv1 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 38);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.Monster.prototype.testhashs64Fnv1 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 40);
+  return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @param {flatbuffers.Long} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_testhashs64_fnv1 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 40);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.Monster.prototype.testhashu64Fnv1 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 42);
+  return offset ? this.bb.readUint64(this.bb_pos + offset) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @param {flatbuffers.Long} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_testhashu64_fnv1 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 42);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testhashs32Fnv1a = function() {
+  var offset = this.bb.__offset(this.bb_pos, 44);
+  return offset ? this.bb.readInt32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_testhashs32_fnv1a = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 44);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testhashu32Fnv1a = function() {
+  var offset = this.bb.__offset(this.bb_pos, 46);
+  return offset ? this.bb.readUint32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_testhashu32_fnv1a = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 46);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.Monster.prototype.testhashs64Fnv1a = function() {
+  var offset = this.bb.__offset(this.bb_pos, 48);
+  return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @param {flatbuffers.Long} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_testhashs64_fnv1a = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 48);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.Monster.prototype.testhashu64Fnv1a = function() {
+  var offset = this.bb.__offset(this.bb_pos, 50);
+  return offset ? this.bb.readUint64(this.bb_pos + offset) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @param {flatbuffers.Long} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_testhashu64_fnv1a = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 50);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {number} index
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.testarrayofbools = function(index) {
+  var offset = this.bb.__offset(this.bb_pos, 52);
+  return offset ? !!this.bb.readInt8(this.bb.__vector(this.bb_pos + offset) + index) : false;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testarrayofboolsLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 52);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns {Int8Array}
+ */
+MyGame.Example.Monster.prototype.testarrayofboolsArray = function() {
+  var offset = this.bb.__offset(this.bb_pos, 52);
+  return offset ? new Int8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testf = function() {
+  var offset = this.bb.__offset(this.bb_pos, 54);
+  return offset ? this.bb.readFloat32(this.bb_pos + offset) : 3.14159;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_testf = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 54);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testf2 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 56);
+  return offset ? this.bb.readFloat32(this.bb_pos + offset) : 3.0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_testf2 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 56);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testf3 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 58);
+  return offset ? this.bb.readFloat32(this.bb_pos + offset) : 0.0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_testf3 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 58);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {number} index
+ * @param {flatbuffers.Encoding=} optionalEncoding
+ * @returns {string|Uint8Array}
+ */
+MyGame.Example.Monster.prototype.testarrayofstring2 = function(index, optionalEncoding) {
+  var offset = this.bb.__offset(this.bb_pos, 60);
+  return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testarrayofstring2Length = function() {
+  var offset = this.bb.__offset(this.bb_pos, 60);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} index
+ * @param {MyGame.Example.Ability=} obj
+ * @returns {MyGame.Example.Ability}
+ */
+MyGame.Example.Monster.prototype.testarrayofsortedstruct = function(index, obj) {
+  var offset = this.bb.__offset(this.bb_pos, 62);
+  return offset ? (obj || new MyGame.Example.Ability).__init(this.bb.__vector(this.bb_pos + offset) + index * 8, this.bb) : null;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.testarrayofsortedstructLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 62);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} index
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.flex = function(index) {
+  var offset = this.bb.__offset(this.bb_pos, 64);
+  return offset ? this.bb.readUint8(this.bb.__vector(this.bb_pos + offset) + index) : 0;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.flexLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 64);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns {Uint8Array}
+ */
+MyGame.Example.Monster.prototype.flexArray = function() {
+  var offset = this.bb.__offset(this.bb_pos, 64);
+  return offset ? new Uint8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param {number} index
+ * @param {MyGame.Example.Test=} obj
+ * @returns {MyGame.Example.Test}
+ */
+MyGame.Example.Monster.prototype.test5 = function(index, obj) {
+  var offset = this.bb.__offset(this.bb_pos, 66);
+  return offset ? (obj || new MyGame.Example.Test).__init(this.bb.__vector(this.bb_pos + offset) + index * 4, this.bb) : null;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.test5Length = function() {
+  var offset = this.bb.__offset(this.bb_pos, 66);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} index
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.Monster.prototype.vectorOfLongs = function(index) {
+  var offset = this.bb.__offset(this.bb_pos, 68);
+  return offset ? this.bb.readInt64(this.bb.__vector(this.bb_pos + offset) + index * 8) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.vectorOfLongsLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 68);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} index
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.vectorOfDoubles = function(index) {
+  var offset = this.bb.__offset(this.bb_pos, 70);
+  return offset ? this.bb.readFloat64(this.bb.__vector(this.bb_pos + offset) + index * 8) : 0;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.vectorOfDoublesLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 70);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns {Float64Array}
+ */
+MyGame.Example.Monster.prototype.vectorOfDoublesArray = function() {
+  var offset = this.bb.__offset(this.bb_pos, 70);
+  return offset ? new Float64Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param {MyGame.InParentNamespace=} obj
+ * @returns {MyGame.InParentNamespace|null}
+ */
+MyGame.Example.Monster.prototype.parentNamespaceTest = function(obj) {
+  var offset = this.bb.__offset(this.bb_pos, 72);
+  return offset ? (obj || new MyGame.InParentNamespace).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
+};
+
+/**
+ * @param {number} index
+ * @param {MyGame.Example.Referrable=} obj
+ * @returns {MyGame.Example.Referrable}
+ */
+MyGame.Example.Monster.prototype.vectorOfReferrables = function(index, obj) {
+  var offset = this.bb.__offset(this.bb_pos, 74);
+  return offset ? (obj || new MyGame.Example.Referrable).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.vectorOfReferrablesLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 74);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.Monster.prototype.singleWeakReference = function() {
+  var offset = this.bb.__offset(this.bb_pos, 76);
+  return offset ? this.bb.readUint64(this.bb_pos + offset) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @param {flatbuffers.Long} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_single_weak_reference = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 76);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {number} index
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.Monster.prototype.vectorOfWeakReferences = function(index) {
+  var offset = this.bb.__offset(this.bb_pos, 78);
+  return offset ? this.bb.readUint64(this.bb.__vector(this.bb_pos + offset) + index * 8) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.vectorOfWeakReferencesLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 78);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} index
+ * @param {MyGame.Example.Referrable=} obj
+ * @returns {MyGame.Example.Referrable}
+ */
+MyGame.Example.Monster.prototype.vectorOfStrongReferrables = function(index, obj) {
+  var offset = this.bb.__offset(this.bb_pos, 80);
+  return offset ? (obj || new MyGame.Example.Referrable).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.vectorOfStrongReferrablesLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 80);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.Monster.prototype.coOwningReference = function() {
+  var offset = this.bb.__offset(this.bb_pos, 82);
+  return offset ? this.bb.readUint64(this.bb_pos + offset) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @param {flatbuffers.Long} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_co_owning_reference = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 82);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {number} index
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.Monster.prototype.vectorOfCoOwningReferences = function(index) {
+  var offset = this.bb.__offset(this.bb_pos, 84);
+  return offset ? this.bb.readUint64(this.bb.__vector(this.bb_pos + offset) + index * 8) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.vectorOfCoOwningReferencesLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 84);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.Monster.prototype.nonOwningReference = function() {
+  var offset = this.bb.__offset(this.bb_pos, 86);
+  return offset ? this.bb.readUint64(this.bb_pos + offset) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @param {flatbuffers.Long} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_non_owning_reference = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 86);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {number} index
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.Monster.prototype.vectorOfNonOwningReferences = function(index) {
+  var offset = this.bb.__offset(this.bb_pos, 88);
+  return offset ? this.bb.readUint64(this.bb.__vector(this.bb_pos + offset) + index * 8) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.vectorOfNonOwningReferencesLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 88);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns {MyGame.Example.AnyUniqueAliases}
+ */
+MyGame.Example.Monster.prototype.anyUniqueType = function() {
+  var offset = this.bb.__offset(this.bb_pos, 90);
+  return offset ? /** @type {MyGame.Example.AnyUniqueAliases} */ (this.bb.readUint8(this.bb_pos + offset)) : MyGame.Example.AnyUniqueAliases.NONE;
+};
+
+/**
+ * @param {MyGame.Example.AnyUniqueAliases} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_any_unique_type = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 90);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Table} obj
+ * @returns {?flatbuffers.Table}
+ */
+MyGame.Example.Monster.prototype.anyUnique = function(obj) {
+  var offset = this.bb.__offset(this.bb_pos, 92);
+  return offset ? this.bb.__union(obj, this.bb_pos + offset) : null;
+};
+
+/**
+ * @returns {MyGame.Example.AnyAmbiguousAliases}
+ */
+MyGame.Example.Monster.prototype.anyAmbiguousType = function() {
+  var offset = this.bb.__offset(this.bb_pos, 94);
+  return offset ? /** @type {MyGame.Example.AnyAmbiguousAliases} */ (this.bb.readUint8(this.bb_pos + offset)) : MyGame.Example.AnyAmbiguousAliases.NONE;
+};
+
+/**
+ * @param {MyGame.Example.AnyAmbiguousAliases} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_any_ambiguous_type = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 94);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Table} obj
+ * @returns {?flatbuffers.Table}
+ */
+MyGame.Example.Monster.prototype.anyAmbiguous = function(obj) {
+  var offset = this.bb.__offset(this.bb_pos, 96);
+  return offset ? this.bb.__union(obj, this.bb_pos + offset) : null;
+};
+
+/**
+ * @param {number} index
+ * @returns {MyGame.Example.Color}
+ */
+MyGame.Example.Monster.prototype.vectorOfEnums = function(index) {
+  var offset = this.bb.__offset(this.bb_pos, 98);
+  return offset ? /** @type {MyGame.Example.Color} */ (this.bb.readUint8(this.bb.__vector(this.bb_pos + offset) + index)) : /** @type {MyGame.Example.Color} */ (0);
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.Monster.prototype.vectorOfEnumsLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 98);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns {Uint8Array}
+ */
+MyGame.Example.Monster.prototype.vectorOfEnumsArray = function() {
+  var offset = this.bb.__offset(this.bb_pos, 98);
+  return offset ? new Uint8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ */
+MyGame.Example.Monster.startMonster = function(builder) {
+  builder.startObject(48);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} posOffset
+ */
+MyGame.Example.Monster.addPos = function(builder, posOffset) {
+  builder.addFieldStruct(0, posOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} mana
+ */
+MyGame.Example.Monster.addMana = function(builder, mana) {
+  builder.addFieldInt16(1, mana, 150);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} hp
+ */
+MyGame.Example.Monster.addHp = function(builder, hp) {
+  builder.addFieldInt16(2, hp, 100);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} nameOffset
+ */
+MyGame.Example.Monster.addName = function(builder, nameOffset) {
+  builder.addFieldOffset(3, nameOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} inventoryOffset
+ */
+MyGame.Example.Monster.addInventory = function(builder, inventoryOffset) {
+  builder.addFieldOffset(5, inventoryOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<number>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createInventoryVector = function(builder, data) {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startInventoryVector = function(builder, numElems) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {MyGame.Example.Color} color
+ */
+MyGame.Example.Monster.addColor = function(builder, color) {
+  builder.addFieldInt8(6, color, MyGame.Example.Color.Blue);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {MyGame.Example.Any} testType
+ */
+MyGame.Example.Monster.addTestType = function(builder, testType) {
+  builder.addFieldInt8(7, testType, MyGame.Example.Any.NONE);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} testOffset
+ */
+MyGame.Example.Monster.addTest = function(builder, testOffset) {
+  builder.addFieldOffset(8, testOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} test4Offset
+ */
+MyGame.Example.Monster.addTest4 = function(builder, test4Offset) {
+  builder.addFieldOffset(9, test4Offset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startTest4Vector = function(builder, numElems) {
+  builder.startVector(4, numElems, 2);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} testarrayofstringOffset
+ */
+MyGame.Example.Monster.addTestarrayofstring = function(builder, testarrayofstringOffset) {
+  builder.addFieldOffset(10, testarrayofstringOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<flatbuffers.Offset>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createTestarrayofstringVector = function(builder, data) {
+  builder.startVector(4, data.length, 4);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addOffset(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startTestarrayofstringVector = function(builder, numElems) {
+  builder.startVector(4, numElems, 4);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} testarrayoftablesOffset
+ */
+MyGame.Example.Monster.addTestarrayoftables = function(builder, testarrayoftablesOffset) {
+  builder.addFieldOffset(11, testarrayoftablesOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<flatbuffers.Offset>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createTestarrayoftablesVector = function(builder, data) {
+  builder.startVector(4, data.length, 4);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addOffset(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startTestarrayoftablesVector = function(builder, numElems) {
+  builder.startVector(4, numElems, 4);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} enemyOffset
+ */
+MyGame.Example.Monster.addEnemy = function(builder, enemyOffset) {
+  builder.addFieldOffset(12, enemyOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} testnestedflatbufferOffset
+ */
+MyGame.Example.Monster.addTestnestedflatbuffer = function(builder, testnestedflatbufferOffset) {
+  builder.addFieldOffset(13, testnestedflatbufferOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<number>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createTestnestedflatbufferVector = function(builder, data) {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startTestnestedflatbufferVector = function(builder, numElems) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} testemptyOffset
+ */
+MyGame.Example.Monster.addTestempty = function(builder, testemptyOffset) {
+  builder.addFieldOffset(14, testemptyOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {boolean} testbool
+ */
+MyGame.Example.Monster.addTestbool = function(builder, testbool) {
+  builder.addFieldInt8(15, +testbool, +false);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} testhashs32Fnv1
+ */
+MyGame.Example.Monster.addTesthashs32Fnv1 = function(builder, testhashs32Fnv1) {
+  builder.addFieldInt32(16, testhashs32Fnv1, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} testhashu32Fnv1
+ */
+MyGame.Example.Monster.addTesthashu32Fnv1 = function(builder, testhashu32Fnv1) {
+  builder.addFieldInt32(17, testhashu32Fnv1, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Long} testhashs64Fnv1
+ */
+MyGame.Example.Monster.addTesthashs64Fnv1 = function(builder, testhashs64Fnv1) {
+  builder.addFieldInt64(18, testhashs64Fnv1, builder.createLong(0, 0));
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Long} testhashu64Fnv1
+ */
+MyGame.Example.Monster.addTesthashu64Fnv1 = function(builder, testhashu64Fnv1) {
+  builder.addFieldInt64(19, testhashu64Fnv1, builder.createLong(0, 0));
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} testhashs32Fnv1a
+ */
+MyGame.Example.Monster.addTesthashs32Fnv1a = function(builder, testhashs32Fnv1a) {
+  builder.addFieldInt32(20, testhashs32Fnv1a, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} testhashu32Fnv1a
+ */
+MyGame.Example.Monster.addTesthashu32Fnv1a = function(builder, testhashu32Fnv1a) {
+  builder.addFieldInt32(21, testhashu32Fnv1a, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Long} testhashs64Fnv1a
+ */
+MyGame.Example.Monster.addTesthashs64Fnv1a = function(builder, testhashs64Fnv1a) {
+  builder.addFieldInt64(22, testhashs64Fnv1a, builder.createLong(0, 0));
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Long} testhashu64Fnv1a
+ */
+MyGame.Example.Monster.addTesthashu64Fnv1a = function(builder, testhashu64Fnv1a) {
+  builder.addFieldInt64(23, testhashu64Fnv1a, builder.createLong(0, 0));
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} testarrayofboolsOffset
+ */
+MyGame.Example.Monster.addTestarrayofbools = function(builder, testarrayofboolsOffset) {
+  builder.addFieldOffset(24, testarrayofboolsOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<boolean>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createTestarrayofboolsVector = function(builder, data) {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(+data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startTestarrayofboolsVector = function(builder, numElems) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} testf
+ */
+MyGame.Example.Monster.addTestf = function(builder, testf) {
+  builder.addFieldFloat32(25, testf, 3.14159);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} testf2
+ */
+MyGame.Example.Monster.addTestf2 = function(builder, testf2) {
+  builder.addFieldFloat32(26, testf2, 3.0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} testf3
+ */
+MyGame.Example.Monster.addTestf3 = function(builder, testf3) {
+  builder.addFieldFloat32(27, testf3, 0.0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} testarrayofstring2Offset
+ */
+MyGame.Example.Monster.addTestarrayofstring2 = function(builder, testarrayofstring2Offset) {
+  builder.addFieldOffset(28, testarrayofstring2Offset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<flatbuffers.Offset>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createTestarrayofstring2Vector = function(builder, data) {
+  builder.startVector(4, data.length, 4);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addOffset(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startTestarrayofstring2Vector = function(builder, numElems) {
+  builder.startVector(4, numElems, 4);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} testarrayofsortedstructOffset
+ */
+MyGame.Example.Monster.addTestarrayofsortedstruct = function(builder, testarrayofsortedstructOffset) {
+  builder.addFieldOffset(29, testarrayofsortedstructOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startTestarrayofsortedstructVector = function(builder, numElems) {
+  builder.startVector(8, numElems, 4);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} flexOffset
+ */
+MyGame.Example.Monster.addFlex = function(builder, flexOffset) {
+  builder.addFieldOffset(30, flexOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<number>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createFlexVector = function(builder, data) {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startFlexVector = function(builder, numElems) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} test5Offset
+ */
+MyGame.Example.Monster.addTest5 = function(builder, test5Offset) {
+  builder.addFieldOffset(31, test5Offset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startTest5Vector = function(builder, numElems) {
+  builder.startVector(4, numElems, 2);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} vectorOfLongsOffset
+ */
+MyGame.Example.Monster.addVectorOfLongs = function(builder, vectorOfLongsOffset) {
+  builder.addFieldOffset(32, vectorOfLongsOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<flatbuffers.Long>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createVectorOfLongsVector = function(builder, data) {
+  builder.startVector(8, data.length, 8);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt64(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startVectorOfLongsVector = function(builder, numElems) {
+  builder.startVector(8, numElems, 8);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} vectorOfDoublesOffset
+ */
+MyGame.Example.Monster.addVectorOfDoubles = function(builder, vectorOfDoublesOffset) {
+  builder.addFieldOffset(33, vectorOfDoublesOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<number>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createVectorOfDoublesVector = function(builder, data) {
+  builder.startVector(8, data.length, 8);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addFloat64(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startVectorOfDoublesVector = function(builder, numElems) {
+  builder.startVector(8, numElems, 8);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} parentNamespaceTestOffset
+ */
+MyGame.Example.Monster.addParentNamespaceTest = function(builder, parentNamespaceTestOffset) {
+  builder.addFieldOffset(34, parentNamespaceTestOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} vectorOfReferrablesOffset
+ */
+MyGame.Example.Monster.addVectorOfReferrables = function(builder, vectorOfReferrablesOffset) {
+  builder.addFieldOffset(35, vectorOfReferrablesOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<flatbuffers.Offset>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createVectorOfReferrablesVector = function(builder, data) {
+  builder.startVector(4, data.length, 4);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addOffset(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startVectorOfReferrablesVector = function(builder, numElems) {
+  builder.startVector(4, numElems, 4);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Long} singleWeakReference
+ */
+MyGame.Example.Monster.addSingleWeakReference = function(builder, singleWeakReference) {
+  builder.addFieldInt64(36, singleWeakReference, builder.createLong(0, 0));
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} vectorOfWeakReferencesOffset
+ */
+MyGame.Example.Monster.addVectorOfWeakReferences = function(builder, vectorOfWeakReferencesOffset) {
+  builder.addFieldOffset(37, vectorOfWeakReferencesOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<flatbuffers.Long>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createVectorOfWeakReferencesVector = function(builder, data) {
+  builder.startVector(8, data.length, 8);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt64(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startVectorOfWeakReferencesVector = function(builder, numElems) {
+  builder.startVector(8, numElems, 8);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} vectorOfStrongReferrablesOffset
+ */
+MyGame.Example.Monster.addVectorOfStrongReferrables = function(builder, vectorOfStrongReferrablesOffset) {
+  builder.addFieldOffset(38, vectorOfStrongReferrablesOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<flatbuffers.Offset>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createVectorOfStrongReferrablesVector = function(builder, data) {
+  builder.startVector(4, data.length, 4);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addOffset(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startVectorOfStrongReferrablesVector = function(builder, numElems) {
+  builder.startVector(4, numElems, 4);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Long} coOwningReference
+ */
+MyGame.Example.Monster.addCoOwningReference = function(builder, coOwningReference) {
+  builder.addFieldInt64(39, coOwningReference, builder.createLong(0, 0));
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} vectorOfCoOwningReferencesOffset
+ */
+MyGame.Example.Monster.addVectorOfCoOwningReferences = function(builder, vectorOfCoOwningReferencesOffset) {
+  builder.addFieldOffset(40, vectorOfCoOwningReferencesOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<flatbuffers.Long>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createVectorOfCoOwningReferencesVector = function(builder, data) {
+  builder.startVector(8, data.length, 8);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt64(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startVectorOfCoOwningReferencesVector = function(builder, numElems) {
+  builder.startVector(8, numElems, 8);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Long} nonOwningReference
+ */
+MyGame.Example.Monster.addNonOwningReference = function(builder, nonOwningReference) {
+  builder.addFieldInt64(41, nonOwningReference, builder.createLong(0, 0));
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} vectorOfNonOwningReferencesOffset
+ */
+MyGame.Example.Monster.addVectorOfNonOwningReferences = function(builder, vectorOfNonOwningReferencesOffset) {
+  builder.addFieldOffset(42, vectorOfNonOwningReferencesOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<flatbuffers.Long>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createVectorOfNonOwningReferencesVector = function(builder, data) {
+  builder.startVector(8, data.length, 8);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt64(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startVectorOfNonOwningReferencesVector = function(builder, numElems) {
+  builder.startVector(8, numElems, 8);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {MyGame.Example.AnyUniqueAliases} anyUniqueType
+ */
+MyGame.Example.Monster.addAnyUniqueType = function(builder, anyUniqueType) {
+  builder.addFieldInt8(43, anyUniqueType, MyGame.Example.AnyUniqueAliases.NONE);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} anyUniqueOffset
+ */
+MyGame.Example.Monster.addAnyUnique = function(builder, anyUniqueOffset) {
+  builder.addFieldOffset(44, anyUniqueOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {MyGame.Example.AnyAmbiguousAliases} anyAmbiguousType
+ */
+MyGame.Example.Monster.addAnyAmbiguousType = function(builder, anyAmbiguousType) {
+  builder.addFieldInt8(45, anyAmbiguousType, MyGame.Example.AnyAmbiguousAliases.NONE);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} anyAmbiguousOffset
+ */
+MyGame.Example.Monster.addAnyAmbiguous = function(builder, anyAmbiguousOffset) {
+  builder.addFieldOffset(46, anyAmbiguousOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} vectorOfEnumsOffset
+ */
+MyGame.Example.Monster.addVectorOfEnums = function(builder, vectorOfEnumsOffset) {
+  builder.addFieldOffset(47, vectorOfEnumsOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<MyGame.Example.Color>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createVectorOfEnumsVector = function(builder, data) {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.Monster.startVectorOfEnumsVector = function(builder, numElems) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.endMonster = function(builder) {
+  var offset = builder.endObject();
+  builder.requiredField(offset, 10); // name
+  return offset;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} offset
+ */
+MyGame.Example.Monster.finishMonsterBuffer = function(builder, offset) {
+  builder.finish(offset, 'MONS');
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} offset
+ */
+MyGame.Example.Monster.finishSizePrefixedMonsterBuffer = function(builder, offset) {
+  builder.finish(offset, 'MONS', true);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} posOffset
+ * @param {number} mana
+ * @param {number} hp
+ * @param {flatbuffers.Offset} nameOffset
+ * @param {flatbuffers.Offset} inventoryOffset
+ * @param {MyGame.Example.Color} color
+ * @param {MyGame.Example.Any} testType
+ * @param {flatbuffers.Offset} testOffset
+ * @param {flatbuffers.Offset} test4Offset
+ * @param {flatbuffers.Offset} testarrayofstringOffset
+ * @param {flatbuffers.Offset} testarrayoftablesOffset
+ * @param {flatbuffers.Offset} enemyOffset
+ * @param {flatbuffers.Offset} testnestedflatbufferOffset
+ * @param {flatbuffers.Offset} testemptyOffset
+ * @param {boolean} testbool
+ * @param {number} testhashs32Fnv1
+ * @param {number} testhashu32Fnv1
+ * @param {flatbuffers.Long} testhashs64Fnv1
+ * @param {flatbuffers.Long} testhashu64Fnv1
+ * @param {number} testhashs32Fnv1a
+ * @param {number} testhashu32Fnv1a
+ * @param {flatbuffers.Long} testhashs64Fnv1a
+ * @param {flatbuffers.Long} testhashu64Fnv1a
+ * @param {flatbuffers.Offset} testarrayofboolsOffset
+ * @param {number} testf
+ * @param {number} testf2
+ * @param {number} testf3
+ * @param {flatbuffers.Offset} testarrayofstring2Offset
+ * @param {flatbuffers.Offset} testarrayofsortedstructOffset
+ * @param {flatbuffers.Offset} flexOffset
+ * @param {flatbuffers.Offset} test5Offset
+ * @param {flatbuffers.Offset} vectorOfLongsOffset
+ * @param {flatbuffers.Offset} vectorOfDoublesOffset
+ * @param {flatbuffers.Offset} parentNamespaceTestOffset
+ * @param {flatbuffers.Offset} vectorOfReferrablesOffset
+ * @param {flatbuffers.Long} singleWeakReference
+ * @param {flatbuffers.Offset} vectorOfWeakReferencesOffset
+ * @param {flatbuffers.Offset} vectorOfStrongReferrablesOffset
+ * @param {flatbuffers.Long} coOwningReference
+ * @param {flatbuffers.Offset} vectorOfCoOwningReferencesOffset
+ * @param {flatbuffers.Long} nonOwningReference
+ * @param {flatbuffers.Offset} vectorOfNonOwningReferencesOffset
+ * @param {MyGame.Example.AnyUniqueAliases} anyUniqueType
+ * @param {flatbuffers.Offset} anyUniqueOffset
+ * @param {MyGame.Example.AnyAmbiguousAliases} anyAmbiguousType
+ * @param {flatbuffers.Offset} anyAmbiguousOffset
+ * @param {flatbuffers.Offset} vectorOfEnumsOffset
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.Monster.createMonster = function(builder, posOffset, mana, hp, nameOffset, inventoryOffset, color, testType, testOffset, test4Offset, testarrayofstringOffset, testarrayoftablesOffset, enemyOffset, testnestedflatbufferOffset, testemptyOffset, testbool, testhashs32Fnv1, testhashu32Fnv1, testhashs64Fnv1, testhashu64Fnv1, testhashs32Fnv1a, testhashu32Fnv1a, testhashs64Fnv1a, testhashu64Fnv1a, testarrayofboolsOffset, testf, testf2, testf3, testarrayofstring2Offset, testarrayofsortedstructOffset, flexOffset, test5Offset, vectorOfLongsOffset, vectorOfDoublesOffset, parentNamespaceTestOffset, vectorOfReferrablesOffset, singleWeakReference, vectorOfWeakReferencesOffset, vectorOfStrongReferrablesOffset, coOwningReference, vectorOfCoOwningReferencesOffset, nonOwningReference, vectorOfNonOwningReferencesOffset, anyUniqueType, anyUniqueOffset, anyAmbiguousType, anyAmbiguousOffset, vectorOfEnumsOffset) {
+  MyGame.Example.Monster.startMonster(builder);
+  MyGame.Example.Monster.addPos(builder, posOffset);
+  MyGame.Example.Monster.addMana(builder, mana);
+  MyGame.Example.Monster.addHp(builder, hp);
+  MyGame.Example.Monster.addName(builder, nameOffset);
+  MyGame.Example.Monster.addInventory(builder, inventoryOffset);
+  MyGame.Example.Monster.addColor(builder, color);
+  MyGame.Example.Monster.addTestType(builder, testType);
+  MyGame.Example.Monster.addTest(builder, testOffset);
+  MyGame.Example.Monster.addTest4(builder, test4Offset);
+  MyGame.Example.Monster.addTestarrayofstring(builder, testarrayofstringOffset);
+  MyGame.Example.Monster.addTestarrayoftables(builder, testarrayoftablesOffset);
+  MyGame.Example.Monster.addEnemy(builder, enemyOffset);
+  MyGame.Example.Monster.addTestnestedflatbuffer(builder, testnestedflatbufferOffset);
+  MyGame.Example.Monster.addTestempty(builder, testemptyOffset);
+  MyGame.Example.Monster.addTestbool(builder, testbool);
+  MyGame.Example.Monster.addTesthashs32Fnv1(builder, testhashs32Fnv1);
+  MyGame.Example.Monster.addTesthashu32Fnv1(builder, testhashu32Fnv1);
+  MyGame.Example.Monster.addTesthashs64Fnv1(builder, testhashs64Fnv1);
+  MyGame.Example.Monster.addTesthashu64Fnv1(builder, testhashu64Fnv1);
+  MyGame.Example.Monster.addTesthashs32Fnv1a(builder, testhashs32Fnv1a);
+  MyGame.Example.Monster.addTesthashu32Fnv1a(builder, testhashu32Fnv1a);
+  MyGame.Example.Monster.addTesthashs64Fnv1a(builder, testhashs64Fnv1a);
+  MyGame.Example.Monster.addTesthashu64Fnv1a(builder, testhashu64Fnv1a);
+  MyGame.Example.Monster.addTestarrayofbools(builder, testarrayofboolsOffset);
+  MyGame.Example.Monster.addTestf(builder, testf);
+  MyGame.Example.Monster.addTestf2(builder, testf2);
+  MyGame.Example.Monster.addTestf3(builder, testf3);
+  MyGame.Example.Monster.addTestarrayofstring2(builder, testarrayofstring2Offset);
+  MyGame.Example.Monster.addTestarrayofsortedstruct(builder, testarrayofsortedstructOffset);
+  MyGame.Example.Monster.addFlex(builder, flexOffset);
+  MyGame.Example.Monster.addTest5(builder, test5Offset);
+  MyGame.Example.Monster.addVectorOfLongs(builder, vectorOfLongsOffset);
+  MyGame.Example.Monster.addVectorOfDoubles(builder, vectorOfDoublesOffset);
+  MyGame.Example.Monster.addParentNamespaceTest(builder, parentNamespaceTestOffset);
+  MyGame.Example.Monster.addVectorOfReferrables(builder, vectorOfReferrablesOffset);
+  MyGame.Example.Monster.addSingleWeakReference(builder, singleWeakReference);
+  MyGame.Example.Monster.addVectorOfWeakReferences(builder, vectorOfWeakReferencesOffset);
+  MyGame.Example.Monster.addVectorOfStrongReferrables(builder, vectorOfStrongReferrablesOffset);
+  MyGame.Example.Monster.addCoOwningReference(builder, coOwningReference);
+  MyGame.Example.Monster.addVectorOfCoOwningReferences(builder, vectorOfCoOwningReferencesOffset);
+  MyGame.Example.Monster.addNonOwningReference(builder, nonOwningReference);
+  MyGame.Example.Monster.addVectorOfNonOwningReferences(builder, vectorOfNonOwningReferencesOffset);
+  MyGame.Example.Monster.addAnyUniqueType(builder, anyUniqueType);
+  MyGame.Example.Monster.addAnyUnique(builder, anyUniqueOffset);
+  MyGame.Example.Monster.addAnyAmbiguousType(builder, anyAmbiguousType);
+  MyGame.Example.Monster.addAnyAmbiguous(builder, anyAmbiguousOffset);
+  MyGame.Example.Monster.addVectorOfEnums(builder, vectorOfEnumsOffset);
+  return MyGame.Example.Monster.endMonster(builder);
+}
+
+/**
+ * @constructor
+ */
+MyGame.Example.TypeAliases = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {MyGame.Example.TypeAliases}
+ */
+MyGame.Example.TypeAliases.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example.TypeAliases=} obj
+ * @returns {MyGame.Example.TypeAliases}
+ */
+MyGame.Example.TypeAliases.getRootAsTypeAliases = function(bb, obj) {
+  return (obj || new MyGame.Example.TypeAliases).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example.TypeAliases=} obj
+ * @returns {MyGame.Example.TypeAliases}
+ */
+MyGame.Example.TypeAliases.getSizePrefixedRootAsTypeAliases = function(bb, obj) {
+  return (obj || new MyGame.Example.TypeAliases).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.TypeAliases.prototype.i8 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+  return offset ? this.bb.readInt8(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.TypeAliases.prototype.mutate_i8 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.TypeAliases.prototype.u8 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 6);
+  return offset ? this.bb.readUint8(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.TypeAliases.prototype.mutate_u8 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 6);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.TypeAliases.prototype.i16 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 8);
+  return offset ? this.bb.readInt16(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.TypeAliases.prototype.mutate_i16 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 8);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt16(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.TypeAliases.prototype.u16 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 10);
+  return offset ? this.bb.readUint16(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.TypeAliases.prototype.mutate_u16 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 10);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint16(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.TypeAliases.prototype.i32 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 12);
+  return offset ? this.bb.readInt32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.TypeAliases.prototype.mutate_i32 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 12);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.TypeAliases.prototype.u32 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 14);
+  return offset ? this.bb.readUint32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.TypeAliases.prototype.mutate_u32 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 14);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.TypeAliases.prototype.i64 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 16);
+  return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @param {flatbuffers.Long} value
+ * @returns {boolean}
+ */
+MyGame.Example.TypeAliases.prototype.mutate_i64 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 16);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {flatbuffers.Long}
+ */
+MyGame.Example.TypeAliases.prototype.u64 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 18);
+  return offset ? this.bb.readUint64(this.bb_pos + offset) : this.bb.createLong(0, 0);
+};
+
+/**
+ * @param {flatbuffers.Long} value
+ * @returns {boolean}
+ */
+MyGame.Example.TypeAliases.prototype.mutate_u64 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 18);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.TypeAliases.prototype.f32 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 20);
+  return offset ? this.bb.readFloat32(this.bb_pos + offset) : 0.0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.TypeAliases.prototype.mutate_f32 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 20);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.TypeAliases.prototype.f64 = function() {
+  var offset = this.bb.__offset(this.bb_pos, 22);
+  return offset ? this.bb.readFloat64(this.bb_pos + offset) : 0.0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+MyGame.Example.TypeAliases.prototype.mutate_f64 = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 22);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeFloat64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {number} index
+ * @returns {number}
+ */
+MyGame.Example.TypeAliases.prototype.v8 = function(index) {
+  var offset = this.bb.__offset(this.bb_pos, 24);
+  return offset ? this.bb.readInt8(this.bb.__vector(this.bb_pos + offset) + index) : 0;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.TypeAliases.prototype.v8Length = function() {
+  var offset = this.bb.__offset(this.bb_pos, 24);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns {Int8Array}
+ */
+MyGame.Example.TypeAliases.prototype.v8Array = function() {
+  var offset = this.bb.__offset(this.bb_pos, 24);
+  return offset ? new Int8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param {number} index
+ * @returns {number}
+ */
+MyGame.Example.TypeAliases.prototype.vf64 = function(index) {
+  var offset = this.bb.__offset(this.bb_pos, 26);
+  return offset ? this.bb.readFloat64(this.bb.__vector(this.bb_pos + offset) + index * 8) : 0;
+};
+
+/**
+ * @returns {number}
+ */
+MyGame.Example.TypeAliases.prototype.vf64Length = function() {
+  var offset = this.bb.__offset(this.bb_pos, 26);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns {Float64Array}
+ */
+MyGame.Example.TypeAliases.prototype.vf64Array = function() {
+  var offset = this.bb.__offset(this.bb_pos, 26);
+  return offset ? new Float64Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ */
+MyGame.Example.TypeAliases.startTypeAliases = function(builder) {
+  builder.startObject(12);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} i8
+ */
+MyGame.Example.TypeAliases.addI8 = function(builder, i8) {
+  builder.addFieldInt8(0, i8, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} u8
+ */
+MyGame.Example.TypeAliases.addU8 = function(builder, u8) {
+  builder.addFieldInt8(1, u8, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} i16
+ */
+MyGame.Example.TypeAliases.addI16 = function(builder, i16) {
+  builder.addFieldInt16(2, i16, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} u16
+ */
+MyGame.Example.TypeAliases.addU16 = function(builder, u16) {
+  builder.addFieldInt16(3, u16, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} i32
+ */
+MyGame.Example.TypeAliases.addI32 = function(builder, i32) {
+  builder.addFieldInt32(4, i32, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} u32
+ */
+MyGame.Example.TypeAliases.addU32 = function(builder, u32) {
+  builder.addFieldInt32(5, u32, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Long} i64
+ */
+MyGame.Example.TypeAliases.addI64 = function(builder, i64) {
+  builder.addFieldInt64(6, i64, builder.createLong(0, 0));
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Long} u64
+ */
+MyGame.Example.TypeAliases.addU64 = function(builder, u64) {
+  builder.addFieldInt64(7, u64, builder.createLong(0, 0));
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} f32
+ */
+MyGame.Example.TypeAliases.addF32 = function(builder, f32) {
+  builder.addFieldFloat32(8, f32, 0.0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} f64
+ */
+MyGame.Example.TypeAliases.addF64 = function(builder, f64) {
+  builder.addFieldFloat64(9, f64, 0.0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} v8Offset
+ */
+MyGame.Example.TypeAliases.addV8 = function(builder, v8Offset) {
+  builder.addFieldOffset(10, v8Offset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<number>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.TypeAliases.createV8Vector = function(builder, data) {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.TypeAliases.startV8Vector = function(builder, numElems) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} vf64Offset
+ */
+MyGame.Example.TypeAliases.addVf64 = function(builder, vf64Offset) {
+  builder.addFieldOffset(11, vf64Offset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<number>} data
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.TypeAliases.createVf64Vector = function(builder, data) {
+  builder.startVector(8, data.length, 8);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addFloat64(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+MyGame.Example.TypeAliases.startVf64Vector = function(builder, numElems) {
+  builder.startVector(8, numElems, 8);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.TypeAliases.endTypeAliases = function(builder) {
+  var offset = builder.endObject();
+  return offset;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} i8
+ * @param {number} u8
+ * @param {number} i16
+ * @param {number} u16
+ * @param {number} i32
+ * @param {number} u32
+ * @param {flatbuffers.Long} i64
+ * @param {flatbuffers.Long} u64
+ * @param {number} f32
+ * @param {number} f64
+ * @param {flatbuffers.Offset} v8Offset
+ * @param {flatbuffers.Offset} vf64Offset
+ * @returns {flatbuffers.Offset}
+ */
+MyGame.Example.TypeAliases.createTypeAliases = function(builder, i8, u8, i16, u16, i32, u32, i64, u64, f32, f64, v8Offset, vf64Offset) {
+  MyGame.Example.TypeAliases.startTypeAliases(builder);
+  MyGame.Example.TypeAliases.addI8(builder, i8);
+  MyGame.Example.TypeAliases.addU8(builder, u8);
+  MyGame.Example.TypeAliases.addI16(builder, i16);
+  MyGame.Example.TypeAliases.addU16(builder, u16);
+  MyGame.Example.TypeAliases.addI32(builder, i32);
+  MyGame.Example.TypeAliases.addU32(builder, u32);
+  MyGame.Example.TypeAliases.addI64(builder, i64);
+  MyGame.Example.TypeAliases.addU64(builder, u64);
+  MyGame.Example.TypeAliases.addF32(builder, f32);
+  MyGame.Example.TypeAliases.addF64(builder, f64);
+  MyGame.Example.TypeAliases.addV8(builder, v8Offset);
+  MyGame.Example.TypeAliases.addVf64(builder, vf64Offset);
+  return MyGame.Example.TypeAliases.endTypeAliases(builder);
+}
+
+// Exports for Node.js and RequireJS
+this.MyGame = MyGame;
diff --git a/third_party/flatbuffers/tests/monster_test_generated.lobster b/third_party/flatbuffers/tests/monster_test_generated.lobster
new file mode 100644
index 0000000..05e9cbe
--- /dev/null
+++ b/third_party/flatbuffers/tests/monster_test_generated.lobster
@@ -0,0 +1,710 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+import flatbuffers
+
+namespace MyGame_Example
+
+/// Composite components of Monster color.
+enum Color:
+    Color_Red = 1
+    /// \brief color Green
+    /// Green is bit_flag with value (1u << 1)
+    Color_Green = 2
+    /// \brief color Blue (1u << 3)
+    Color_Blue = 8
+
+enum Any:
+    Any_NONE = 0
+    Any_Monster = 1
+    Any_TestSimpleTableWithEnum = 2
+    Any_MyGame_Example2_Monster = 3
+
+enum AnyUniqueAliases:
+    AnyUniqueAliases_NONE = 0
+    AnyUniqueAliases_M = 1
+    AnyUniqueAliases_TS = 2
+    AnyUniqueAliases_M2 = 3
+
+enum AnyAmbiguousAliases:
+    AnyAmbiguousAliases_NONE = 0
+    AnyAmbiguousAliases_M1 = 1
+    AnyAmbiguousAliases_M2 = 2
+    AnyAmbiguousAliases_M3 = 3
+
+namespace MyGame
+
+class InParentNamespace
+
+namespace MyGame_Example2
+
+class Monster
+
+namespace MyGame_Example
+
+class Test
+
+class TestSimpleTableWithEnum
+
+class Vec3
+
+class Ability
+
+class Stat
+
+class Referrable
+
+class Monster
+
+class TypeAliases
+
+namespace MyGame
+
+class InParentNamespace : flatbuffers_handle
+
+def GetRootAsInParentNamespace(buf:string): return InParentNamespace { buf, buf.flatbuffers_indirect(0) }
+
+struct InParentNamespaceBuilder:
+    b_:flatbuffers_builder
+    def start():
+        b_.StartObject(0)
+        return this
+    def end():
+        return b_.EndObject()
+
+namespace MyGame_Example2
+
+class Monster : flatbuffers_handle
+
+def GetRootAsMonster(buf:string): return Monster { buf, buf.flatbuffers_indirect(0) }
+
+struct MonsterBuilder:
+    b_:flatbuffers_builder
+    def start():
+        b_.StartObject(0)
+        return this
+    def end():
+        return b_.EndObject()
+
+namespace MyGame_Example
+
+class Test : flatbuffers_handle
+    def a():
+        return buf_.read_int16_le(pos_ + 0)
+    def b():
+        return buf_.read_int8_le(pos_ + 2)
+
+def CreateTest(b_:flatbuffers_builder, a:int, b:int):
+    b_.Prep(2, 4)
+    b_.Pad(1)
+    b_.PrependInt8(b)
+    b_.PrependInt16(a)
+    return b_.Offset()
+
+class TestSimpleTableWithEnum : flatbuffers_handle
+    def color():
+        return Color(buf_.flatbuffers_field_int8(pos_, 4, 2))
+
+def GetRootAsTestSimpleTableWithEnum(buf:string): return TestSimpleTableWithEnum { buf, buf.flatbuffers_indirect(0) }
+
+struct TestSimpleTableWithEnumBuilder:
+    b_:flatbuffers_builder
+    def start():
+        b_.StartObject(1)
+        return this
+    def add_color(color:Color):
+        b_.PrependUint8Slot(0, color, 2)
+        return this
+    def end():
+        return b_.EndObject()
+
+class Vec3 : flatbuffers_handle
+    def x():
+        return buf_.read_float32_le(pos_ + 0)
+    def y():
+        return buf_.read_float32_le(pos_ + 4)
+    def z():
+        return buf_.read_float32_le(pos_ + 8)
+    def test1():
+        return buf_.read_float64_le(pos_ + 16)
+    def test2():
+        return Color(buf_.read_int8_le(pos_ + 24))
+    def test3():
+        return MyGame_Example_Test{ buf_, pos_ + 26 }
+
+def CreateVec3(b_:flatbuffers_builder, x:float, y:float, z:float, test1:float, test2:Color, test3_a:int, test3_b:int):
+    b_.Prep(8, 32)
+    b_.Pad(2)
+    b_.Prep(2, 4)
+    b_.Pad(1)
+    b_.PrependInt8(test3_b)
+    b_.PrependInt16(test3_a)
+    b_.Pad(1)
+    b_.PrependUint8(test2)
+    b_.PrependFloat64(test1)
+    b_.Pad(4)
+    b_.PrependFloat32(z)
+    b_.PrependFloat32(y)
+    b_.PrependFloat32(x)
+    return b_.Offset()
+
+class Ability : flatbuffers_handle
+    def id():
+        return buf_.read_int32_le(pos_ + 0)
+    def distance():
+        return buf_.read_int32_le(pos_ + 4)
+
+def CreateAbility(b_:flatbuffers_builder, id:int, distance:int):
+    b_.Prep(4, 8)
+    b_.PrependUint32(distance)
+    b_.PrependUint32(id)
+    return b_.Offset()
+
+class Stat : flatbuffers_handle
+    def id():
+        return buf_.flatbuffers_field_string(pos_, 4)
+    def val():
+        return buf_.flatbuffers_field_int64(pos_, 6, 0)
+    def count():
+        return buf_.flatbuffers_field_int16(pos_, 8, 0)
+
+def GetRootAsStat(buf:string): return Stat { buf, buf.flatbuffers_indirect(0) }
+
+struct StatBuilder:
+    b_:flatbuffers_builder
+    def start():
+        b_.StartObject(3)
+        return this
+    def add_id(id:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(0, id)
+        return this
+    def add_val(val:int):
+        b_.PrependInt64Slot(1, val, 0)
+        return this
+    def add_count(count:int):
+        b_.PrependUint16Slot(2, count, 0)
+        return this
+    def end():
+        return b_.EndObject()
+
+class Referrable : flatbuffers_handle
+    def id():
+        return buf_.flatbuffers_field_int64(pos_, 4, 0)
+
+def GetRootAsReferrable(buf:string): return Referrable { buf, buf.flatbuffers_indirect(0) }
+
+struct ReferrableBuilder:
+    b_:flatbuffers_builder
+    def start():
+        b_.StartObject(1)
+        return this
+    def add_id(id:int):
+        b_.PrependUint64Slot(0, id, 0)
+        return this
+    def end():
+        return b_.EndObject()
+
+/// an example documentation comment: monster object
+class Monster : flatbuffers_handle
+    def pos():
+        let o = buf_.flatbuffers_field_struct(pos_, 4)
+        return if o: MyGame_Example_Vec3 { buf_, o } else: nil
+    def mana():
+        return buf_.flatbuffers_field_int16(pos_, 6, 150)
+    def hp():
+        return buf_.flatbuffers_field_int16(pos_, 8, 100)
+    def name():
+        return buf_.flatbuffers_field_string(pos_, 10)
+    def inventory(i:int):
+        return buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 14) + i * 1)
+    def inventory_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 14)
+    def color():
+        return Color(buf_.flatbuffers_field_int8(pos_, 16, 8))
+    def test_type():
+        return Any(buf_.flatbuffers_field_int8(pos_, 18, 0))
+    def test_as_Monster():
+        return MyGame_Example_Monster { buf_, buf_.flatbuffers_field_table(pos_, 20) }
+    def test_as_TestSimpleTableWithEnum():
+        return MyGame_Example_TestSimpleTableWithEnum { buf_, buf_.flatbuffers_field_table(pos_, 20) }
+    def test_as_MyGame_Example2_Monster():
+        return MyGame_Example2_Monster { buf_, buf_.flatbuffers_field_table(pos_, 20) }
+    def test4(i:int):
+        return MyGame_Example_Test { buf_, buf_.flatbuffers_field_vector(pos_, 22) + i * 4 }
+    def test4_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 22)
+    def testarrayofstring(i:int):
+        return buf_.flatbuffers_string(buf_.flatbuffers_field_vector(pos_, 24) + i * 4)
+    def testarrayofstring_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 24)
+    /// an example documentation comment: this will end up in the generated code
+    /// multiline too
+    def testarrayoftables(i:int):
+        return MyGame_Example_Monster { buf_, buf_.flatbuffers_indirect(buf_.flatbuffers_field_vector(pos_, 26) + i * 4) }
+    def testarrayoftables_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 26)
+    def enemy():
+        let o = buf_.flatbuffers_field_table(pos_, 28)
+        return if o: MyGame_Example_Monster { buf_, o } else: nil
+    def testnestedflatbuffer(i:int):
+        return buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 30) + i * 1)
+    def testnestedflatbuffer_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 30)
+    def testempty():
+        let o = buf_.flatbuffers_field_table(pos_, 32)
+        return if o: MyGame_Example_Stat { buf_, o } else: nil
+    def testbool():
+        return buf_.flatbuffers_field_int8(pos_, 34, 0)
+    def testhashs32_fnv1():
+        return buf_.flatbuffers_field_int32(pos_, 36, 0)
+    def testhashu32_fnv1():
+        return buf_.flatbuffers_field_int32(pos_, 38, 0)
+    def testhashs64_fnv1():
+        return buf_.flatbuffers_field_int64(pos_, 40, 0)
+    def testhashu64_fnv1():
+        return buf_.flatbuffers_field_int64(pos_, 42, 0)
+    def testhashs32_fnv1a():
+        return buf_.flatbuffers_field_int32(pos_, 44, 0)
+    def testhashu32_fnv1a():
+        return buf_.flatbuffers_field_int32(pos_, 46, 0)
+    def testhashs64_fnv1a():
+        return buf_.flatbuffers_field_int64(pos_, 48, 0)
+    def testhashu64_fnv1a():
+        return buf_.flatbuffers_field_int64(pos_, 50, 0)
+    def testarrayofbools(i:int):
+        return buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 52) + i * 1)
+    def testarrayofbools_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 52)
+    def testf():
+        return buf_.flatbuffers_field_float32(pos_, 54, 3.14159)
+    def testf2():
+        return buf_.flatbuffers_field_float32(pos_, 56, 3.0)
+    def testf3():
+        return buf_.flatbuffers_field_float32(pos_, 58, 0.0)
+    def testarrayofstring2(i:int):
+        return buf_.flatbuffers_string(buf_.flatbuffers_field_vector(pos_, 60) + i * 4)
+    def testarrayofstring2_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 60)
+    def testarrayofsortedstruct(i:int):
+        return MyGame_Example_Ability { buf_, buf_.flatbuffers_field_vector(pos_, 62) + i * 8 }
+    def testarrayofsortedstruct_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 62)
+    def flex(i:int):
+        return buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 64) + i * 1)
+    def flex_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 64)
+    def test5(i:int):
+        return MyGame_Example_Test { buf_, buf_.flatbuffers_field_vector(pos_, 66) + i * 4 }
+    def test5_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 66)
+    def vector_of_longs(i:int):
+        return buf_.read_int64_le(buf_.flatbuffers_field_vector(pos_, 68) + i * 8)
+    def vector_of_longs_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 68)
+    def vector_of_doubles(i:int):
+        return buf_.read_float64_le(buf_.flatbuffers_field_vector(pos_, 70) + i * 8)
+    def vector_of_doubles_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 70)
+    def parent_namespace_test():
+        let o = buf_.flatbuffers_field_table(pos_, 72)
+        return if o: MyGame_InParentNamespace { buf_, o } else: nil
+    def vector_of_referrables(i:int):
+        return MyGame_Example_Referrable { buf_, buf_.flatbuffers_indirect(buf_.flatbuffers_field_vector(pos_, 74) + i * 4) }
+    def vector_of_referrables_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 74)
+    def single_weak_reference():
+        return buf_.flatbuffers_field_int64(pos_, 76, 0)
+    def vector_of_weak_references(i:int):
+        return buf_.read_int64_le(buf_.flatbuffers_field_vector(pos_, 78) + i * 8)
+    def vector_of_weak_references_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 78)
+    def vector_of_strong_referrables(i:int):
+        return MyGame_Example_Referrable { buf_, buf_.flatbuffers_indirect(buf_.flatbuffers_field_vector(pos_, 80) + i * 4) }
+    def vector_of_strong_referrables_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 80)
+    def co_owning_reference():
+        return buf_.flatbuffers_field_int64(pos_, 82, 0)
+    def vector_of_co_owning_references(i:int):
+        return buf_.read_int64_le(buf_.flatbuffers_field_vector(pos_, 84) + i * 8)
+    def vector_of_co_owning_references_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 84)
+    def non_owning_reference():
+        return buf_.flatbuffers_field_int64(pos_, 86, 0)
+    def vector_of_non_owning_references(i:int):
+        return buf_.read_int64_le(buf_.flatbuffers_field_vector(pos_, 88) + i * 8)
+    def vector_of_non_owning_references_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 88)
+    def any_unique_type():
+        return AnyUniqueAliases(buf_.flatbuffers_field_int8(pos_, 90, 0))
+    def any_unique_as_M():
+        return MyGame_Example_Monster { buf_, buf_.flatbuffers_field_table(pos_, 92) }
+    def any_unique_as_TS():
+        return MyGame_Example_TestSimpleTableWithEnum { buf_, buf_.flatbuffers_field_table(pos_, 92) }
+    def any_unique_as_M2():
+        return MyGame_Example2_Monster { buf_, buf_.flatbuffers_field_table(pos_, 92) }
+    def any_ambiguous_type():
+        return AnyAmbiguousAliases(buf_.flatbuffers_field_int8(pos_, 94, 0))
+    def any_ambiguous_as_M1():
+        return MyGame_Example_Monster { buf_, buf_.flatbuffers_field_table(pos_, 96) }
+    def any_ambiguous_as_M2():
+        return MyGame_Example_Monster { buf_, buf_.flatbuffers_field_table(pos_, 96) }
+    def any_ambiguous_as_M3():
+        return MyGame_Example_Monster { buf_, buf_.flatbuffers_field_table(pos_, 96) }
+    def vector_of_enums(i:int):
+        return buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 98) + i * 1)
+    def vector_of_enums_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 98)
+
+def GetRootAsMonster(buf:string): return Monster { buf, buf.flatbuffers_indirect(0) }
+
+struct MonsterBuilder:
+    b_:flatbuffers_builder
+    def start():
+        b_.StartObject(48)
+        return this
+    def add_pos(pos:flatbuffers_offset):
+        b_.PrependStructSlot(0, pos)
+        return this
+    def add_mana(mana:int):
+        b_.PrependInt16Slot(1, mana, 150)
+        return this
+    def add_hp(hp:int):
+        b_.PrependInt16Slot(2, hp, 100)
+        return this
+    def add_name(name:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(3, name)
+        return this
+    def add_inventory(inventory:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(5, inventory)
+        return this
+    def add_color(color:Color):
+        b_.PrependUint8Slot(6, color, 8)
+        return this
+    def add_test_type(test_type:Any):
+        b_.PrependUint8Slot(7, test_type, 0)
+        return this
+    def add_test(test:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(8, test)
+        return this
+    def add_test4(test4:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(9, test4)
+        return this
+    def add_testarrayofstring(testarrayofstring:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(10, testarrayofstring)
+        return this
+    def add_testarrayoftables(testarrayoftables:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(11, testarrayoftables)
+        return this
+    def add_enemy(enemy:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(12, enemy)
+        return this
+    def add_testnestedflatbuffer(testnestedflatbuffer:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(13, testnestedflatbuffer)
+        return this
+    def add_testempty(testempty:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(14, testempty)
+        return this
+    def add_testbool(testbool:int):
+        b_.PrependBoolSlot(15, testbool, 0)
+        return this
+    def add_testhashs32_fnv1(testhashs32_fnv1:int):
+        b_.PrependInt32Slot(16, testhashs32_fnv1, 0)
+        return this
+    def add_testhashu32_fnv1(testhashu32_fnv1:int):
+        b_.PrependUint32Slot(17, testhashu32_fnv1, 0)
+        return this
+    def add_testhashs64_fnv1(testhashs64_fnv1:int):
+        b_.PrependInt64Slot(18, testhashs64_fnv1, 0)
+        return this
+    def add_testhashu64_fnv1(testhashu64_fnv1:int):
+        b_.PrependUint64Slot(19, testhashu64_fnv1, 0)
+        return this
+    def add_testhashs32_fnv1a(testhashs32_fnv1a:int):
+        b_.PrependInt32Slot(20, testhashs32_fnv1a, 0)
+        return this
+    def add_testhashu32_fnv1a(testhashu32_fnv1a:int):
+        b_.PrependUint32Slot(21, testhashu32_fnv1a, 0)
+        return this
+    def add_testhashs64_fnv1a(testhashs64_fnv1a:int):
+        b_.PrependInt64Slot(22, testhashs64_fnv1a, 0)
+        return this
+    def add_testhashu64_fnv1a(testhashu64_fnv1a:int):
+        b_.PrependUint64Slot(23, testhashu64_fnv1a, 0)
+        return this
+    def add_testarrayofbools(testarrayofbools:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(24, testarrayofbools)
+        return this
+    def add_testf(testf:float):
+        b_.PrependFloat32Slot(25, testf, 3.14159)
+        return this
+    def add_testf2(testf2:float):
+        b_.PrependFloat32Slot(26, testf2, 3.0)
+        return this
+    def add_testf3(testf3:float):
+        b_.PrependFloat32Slot(27, testf3, 0.0)
+        return this
+    def add_testarrayofstring2(testarrayofstring2:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(28, testarrayofstring2)
+        return this
+    def add_testarrayofsortedstruct(testarrayofsortedstruct:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(29, testarrayofsortedstruct)
+        return this
+    def add_flex(flex:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(30, flex)
+        return this
+    def add_test5(test5:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(31, test5)
+        return this
+    def add_vector_of_longs(vector_of_longs:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(32, vector_of_longs)
+        return this
+    def add_vector_of_doubles(vector_of_doubles:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(33, vector_of_doubles)
+        return this
+    def add_parent_namespace_test(parent_namespace_test:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(34, parent_namespace_test)
+        return this
+    def add_vector_of_referrables(vector_of_referrables:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(35, vector_of_referrables)
+        return this
+    def add_single_weak_reference(single_weak_reference:int):
+        b_.PrependUint64Slot(36, single_weak_reference, 0)
+        return this
+    def add_vector_of_weak_references(vector_of_weak_references:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(37, vector_of_weak_references)
+        return this
+    def add_vector_of_strong_referrables(vector_of_strong_referrables:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(38, vector_of_strong_referrables)
+        return this
+    def add_co_owning_reference(co_owning_reference:int):
+        b_.PrependUint64Slot(39, co_owning_reference, 0)
+        return this
+    def add_vector_of_co_owning_references(vector_of_co_owning_references:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(40, vector_of_co_owning_references)
+        return this
+    def add_non_owning_reference(non_owning_reference:int):
+        b_.PrependUint64Slot(41, non_owning_reference, 0)
+        return this
+    def add_vector_of_non_owning_references(vector_of_non_owning_references:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(42, vector_of_non_owning_references)
+        return this
+    def add_any_unique_type(any_unique_type:AnyUniqueAliases):
+        b_.PrependUint8Slot(43, any_unique_type, 0)
+        return this
+    def add_any_unique(any_unique:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(44, any_unique)
+        return this
+    def add_any_ambiguous_type(any_ambiguous_type:AnyAmbiguousAliases):
+        b_.PrependUint8Slot(45, any_ambiguous_type, 0)
+        return this
+    def add_any_ambiguous(any_ambiguous:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(46, any_ambiguous)
+        return this
+    def add_vector_of_enums(vector_of_enums:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(47, vector_of_enums)
+        return this
+    def end():
+        return b_.EndObject()
+
+def MonsterStartInventoryVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(1, n_, 1)
+def MonsterCreateInventoryVector(b_:flatbuffers_builder, v_:[int]):
+    b_.StartVector(1, v_.length, 1)
+    reverse(v_) e_: b_.PrependUint8(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartTest4Vector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(4, n_, 2)
+
+def MonsterStartTestarrayofstringVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(4, n_, 4)
+def MonsterCreateTestarrayofstringVector(b_:flatbuffers_builder, v_:[flatbuffers_offset]):
+    b_.StartVector(4, v_.length, 4)
+    reverse(v_) e_: b_.PrependUOffsetTRelative(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartTestarrayoftablesVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(4, n_, 4)
+def MonsterCreateTestarrayoftablesVector(b_:flatbuffers_builder, v_:[flatbuffers_offset]):
+    b_.StartVector(4, v_.length, 4)
+    reverse(v_) e_: b_.PrependUOffsetTRelative(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartTestnestedflatbufferVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(1, n_, 1)
+def MonsterCreateTestnestedflatbufferVector(b_:flatbuffers_builder, v_:[int]):
+    b_.StartVector(1, v_.length, 1)
+    reverse(v_) e_: b_.PrependUint8(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartTestarrayofboolsVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(1, n_, 1)
+def MonsterCreateTestarrayofboolsVector(b_:flatbuffers_builder, v_:[int]):
+    b_.StartVector(1, v_.length, 1)
+    reverse(v_) e_: b_.PrependBool(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartTestarrayofstring2Vector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(4, n_, 4)
+def MonsterCreateTestarrayofstring2Vector(b_:flatbuffers_builder, v_:[flatbuffers_offset]):
+    b_.StartVector(4, v_.length, 4)
+    reverse(v_) e_: b_.PrependUOffsetTRelative(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartTestarrayofsortedstructVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(8, n_, 4)
+
+def MonsterStartFlexVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(1, n_, 1)
+def MonsterCreateFlexVector(b_:flatbuffers_builder, v_:[int]):
+    b_.StartVector(1, v_.length, 1)
+    reverse(v_) e_: b_.PrependUint8(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartTest5Vector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(4, n_, 2)
+
+def MonsterStartVectorOfLongsVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(8, n_, 8)
+def MonsterCreateVectorOfLongsVector(b_:flatbuffers_builder, v_:[int]):
+    b_.StartVector(8, v_.length, 8)
+    reverse(v_) e_: b_.PrependInt64(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartVectorOfDoublesVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(8, n_, 8)
+def MonsterCreateVectorOfDoublesVector(b_:flatbuffers_builder, v_:[float]):
+    b_.StartVector(8, v_.length, 8)
+    reverse(v_) e_: b_.PrependFloat64(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartVectorOfReferrablesVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(4, n_, 4)
+def MonsterCreateVectorOfReferrablesVector(b_:flatbuffers_builder, v_:[flatbuffers_offset]):
+    b_.StartVector(4, v_.length, 4)
+    reverse(v_) e_: b_.PrependUOffsetTRelative(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartVectorOfWeakReferencesVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(8, n_, 8)
+def MonsterCreateVectorOfWeakReferencesVector(b_:flatbuffers_builder, v_:[int]):
+    b_.StartVector(8, v_.length, 8)
+    reverse(v_) e_: b_.PrependUint64(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartVectorOfStrongReferrablesVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(4, n_, 4)
+def MonsterCreateVectorOfStrongReferrablesVector(b_:flatbuffers_builder, v_:[flatbuffers_offset]):
+    b_.StartVector(4, v_.length, 4)
+    reverse(v_) e_: b_.PrependUOffsetTRelative(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartVectorOfCoOwningReferencesVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(8, n_, 8)
+def MonsterCreateVectorOfCoOwningReferencesVector(b_:flatbuffers_builder, v_:[int]):
+    b_.StartVector(8, v_.length, 8)
+    reverse(v_) e_: b_.PrependUint64(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartVectorOfNonOwningReferencesVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(8, n_, 8)
+def MonsterCreateVectorOfNonOwningReferencesVector(b_:flatbuffers_builder, v_:[int]):
+    b_.StartVector(8, v_.length, 8)
+    reverse(v_) e_: b_.PrependUint64(e_)
+    return b_.EndVector(v_.length)
+
+def MonsterStartVectorOfEnumsVector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(1, n_, 1)
+def MonsterCreateVectorOfEnumsVector(b_:flatbuffers_builder, v_:[Color]):
+    b_.StartVector(1, v_.length, 1)
+    reverse(v_) e_: b_.PrependUint8(e_)
+    return b_.EndVector(v_.length)
+
+class TypeAliases : flatbuffers_handle
+    def i8():
+        return buf_.flatbuffers_field_int8(pos_, 4, 0)
+    def u8():
+        return buf_.flatbuffers_field_int8(pos_, 6, 0)
+    def i16():
+        return buf_.flatbuffers_field_int16(pos_, 8, 0)
+    def u16():
+        return buf_.flatbuffers_field_int16(pos_, 10, 0)
+    def i32():
+        return buf_.flatbuffers_field_int32(pos_, 12, 0)
+    def u32():
+        return buf_.flatbuffers_field_int32(pos_, 14, 0)
+    def i64():
+        return buf_.flatbuffers_field_int64(pos_, 16, 0)
+    def u64():
+        return buf_.flatbuffers_field_int64(pos_, 18, 0)
+    def f32():
+        return buf_.flatbuffers_field_float32(pos_, 20, 0.0)
+    def f64():
+        return buf_.flatbuffers_field_float64(pos_, 22, 0.0)
+    def v8(i:int):
+        return buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 24) + i * 1)
+    def v8_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 24)
+    def vf64(i:int):
+        return buf_.read_float64_le(buf_.flatbuffers_field_vector(pos_, 26) + i * 8)
+    def vf64_length():
+        return buf_.flatbuffers_field_vector_len(pos_, 26)
+
+def GetRootAsTypeAliases(buf:string): return TypeAliases { buf, buf.flatbuffers_indirect(0) }
+
+struct TypeAliasesBuilder:
+    b_:flatbuffers_builder
+    def start():
+        b_.StartObject(12)
+        return this
+    def add_i8(i8:int):
+        b_.PrependInt8Slot(0, i8, 0)
+        return this
+    def add_u8(u8:int):
+        b_.PrependUint8Slot(1, u8, 0)
+        return this
+    def add_i16(i16:int):
+        b_.PrependInt16Slot(2, i16, 0)
+        return this
+    def add_u16(u16:int):
+        b_.PrependUint16Slot(3, u16, 0)
+        return this
+    def add_i32(i32:int):
+        b_.PrependInt32Slot(4, i32, 0)
+        return this
+    def add_u32(u32:int):
+        b_.PrependUint32Slot(5, u32, 0)
+        return this
+    def add_i64(i64:int):
+        b_.PrependInt64Slot(6, i64, 0)
+        return this
+    def add_u64(u64:int):
+        b_.PrependUint64Slot(7, u64, 0)
+        return this
+    def add_f32(f32:float):
+        b_.PrependFloat32Slot(8, f32, 0.0)
+        return this
+    def add_f64(f64:float):
+        b_.PrependFloat64Slot(9, f64, 0.0)
+        return this
+    def add_v8(v8:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(10, v8)
+        return this
+    def add_vf64(vf64:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(11, vf64)
+        return this
+    def end():
+        return b_.EndObject()
+
+def TypeAliasesStartV8Vector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(1, n_, 1)
+def TypeAliasesCreateV8Vector(b_:flatbuffers_builder, v_:[int]):
+    b_.StartVector(1, v_.length, 1)
+    reverse(v_) e_: b_.PrependInt8(e_)
+    return b_.EndVector(v_.length)
+
+def TypeAliasesStartVf64Vector(b_:flatbuffers_builder, n_:int):
+    b_.StartVector(8, n_, 8)
+def TypeAliasesCreateVf64Vector(b_:flatbuffers_builder, v_:[float]):
+    b_.StartVector(8, v_.length, 8)
+    reverse(v_) e_: b_.PrependFloat64(e_)
+    return b_.EndVector(v_.length)
+
diff --git a/third_party/flatbuffers/tests/monster_test_generated.rs b/third_party/flatbuffers/tests/monster_test_generated.rs
new file mode 100644
index 0000000..59bbf37
--- /dev/null
+++ b/third_party/flatbuffers/tests/monster_test_generated.rs
@@ -0,0 +1,1908 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+
+use std::mem;
+use std::cmp::Ordering;
+
+extern crate flatbuffers;
+use self::flatbuffers::EndianScalar;
+
+#[allow(unused_imports, dead_code)]
+pub mod my_game {
+
+  use std::mem;
+  use std::cmp::Ordering;
+
+  extern crate flatbuffers;
+  use self::flatbuffers::EndianScalar;
+
+pub enum InParentNamespaceOffset {}
+#[derive(Copy, Clone, Debug, PartialEq)]
+
+pub struct InParentNamespace<'a> {
+  pub _tab: flatbuffers::Table<'a>,
+}
+
+impl<'a> flatbuffers::Follow<'a> for InParentNamespace<'a> {
+    type Inner = InParentNamespace<'a>;
+    #[inline]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        Self {
+            _tab: flatbuffers::Table { buf: buf, loc: loc },
+        }
+    }
+}
+
+impl<'a> InParentNamespace<'a> {
+    #[inline]
+    pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
+        InParentNamespace {
+            _tab: table,
+        }
+    }
+    #[allow(unused_mut)]
+    pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
+        _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
+        _args: &'args InParentNamespaceArgs) -> flatbuffers::WIPOffset<InParentNamespace<'bldr>> {
+      let mut builder = InParentNamespaceBuilder::new(_fbb);
+      builder.finish()
+    }
+
+}
+
+pub struct InParentNamespaceArgs {
+}
+impl<'a> Default for InParentNamespaceArgs {
+    #[inline]
+    fn default() -> Self {
+        InParentNamespaceArgs {
+        }
+    }
+}
+pub struct InParentNamespaceBuilder<'a: 'b, 'b> {
+  fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+  start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
+}
+impl<'a: 'b, 'b> InParentNamespaceBuilder<'a, 'b> {
+  #[inline]
+  pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> InParentNamespaceBuilder<'a, 'b> {
+    let start = _fbb.start_table();
+    InParentNamespaceBuilder {
+      fbb_: _fbb,
+      start_: start,
+    }
+  }
+  #[inline]
+  pub fn finish(self) -> flatbuffers::WIPOffset<InParentNamespace<'a>> {
+    let o = self.fbb_.end_table(self.start_);
+    flatbuffers::WIPOffset::new(o.value())
+  }
+}
+
+#[allow(unused_imports, dead_code)]
+pub mod example_2 {
+
+  use std::mem;
+  use std::cmp::Ordering;
+
+  extern crate flatbuffers;
+  use self::flatbuffers::EndianScalar;
+
+pub enum MonsterOffset {}
+#[derive(Copy, Clone, Debug, PartialEq)]
+
+pub struct Monster<'a> {
+  pub _tab: flatbuffers::Table<'a>,
+}
+
+impl<'a> flatbuffers::Follow<'a> for Monster<'a> {
+    type Inner = Monster<'a>;
+    #[inline]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        Self {
+            _tab: flatbuffers::Table { buf: buf, loc: loc },
+        }
+    }
+}
+
+impl<'a> Monster<'a> {
+    #[inline]
+    pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
+        Monster {
+            _tab: table,
+        }
+    }
+    #[allow(unused_mut)]
+    pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
+        _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
+        _args: &'args MonsterArgs) -> flatbuffers::WIPOffset<Monster<'bldr>> {
+      let mut builder = MonsterBuilder::new(_fbb);
+      builder.finish()
+    }
+
+}
+
+pub struct MonsterArgs {
+}
+impl<'a> Default for MonsterArgs {
+    #[inline]
+    fn default() -> Self {
+        MonsterArgs {
+        }
+    }
+}
+pub struct MonsterBuilder<'a: 'b, 'b> {
+  fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+  start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
+}
+impl<'a: 'b, 'b> MonsterBuilder<'a, 'b> {
+  #[inline]
+  pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> MonsterBuilder<'a, 'b> {
+    let start = _fbb.start_table();
+    MonsterBuilder {
+      fbb_: _fbb,
+      start_: start,
+    }
+  }
+  #[inline]
+  pub fn finish(self) -> flatbuffers::WIPOffset<Monster<'a>> {
+    let o = self.fbb_.end_table(self.start_);
+    flatbuffers::WIPOffset::new(o.value())
+  }
+}
+
+}  // pub mod Example2
+
+#[allow(unused_imports, dead_code)]
+pub mod example {
+
+  use std::mem;
+  use std::cmp::Ordering;
+
+  extern crate flatbuffers;
+  use self::flatbuffers::EndianScalar;
+
+/// Composite components of Monster color.
+#[allow(non_camel_case_types)]
+#[repr(u8)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+pub enum Color {
+  Red = 1,
+  /// \brief color Green
+  /// Green is bit_flag with value (1u << 1)
+  Green = 2,
+  /// \brief color Blue (1u << 3)
+  Blue = 8,
+
+}
+
+const ENUM_MIN_COLOR: u8 = 1;
+const ENUM_MAX_COLOR: u8 = 8;
+
+impl<'a> flatbuffers::Follow<'a> for Color {
+  type Inner = Self;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    flatbuffers::read_scalar_at::<Self>(buf, loc)
+  }
+}
+
+impl flatbuffers::EndianScalar for Color {
+  #[inline]
+  fn to_little_endian(self) -> Self {
+    let n = u8::to_le(self as u8);
+    let p = &n as *const u8 as *const Color;
+    unsafe { *p }
+  }
+  #[inline]
+  fn from_little_endian(self) -> Self {
+    let n = u8::from_le(self as u8);
+    let p = &n as *const u8 as *const Color;
+    unsafe { *p }
+  }
+}
+
+impl flatbuffers::Push for Color {
+    type Output = Color;
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        flatbuffers::emplace_scalar::<Color>(dst, *self);
+    }
+}
+
+#[allow(non_camel_case_types)]
+const ENUM_VALUES_COLOR:[Color; 3] = [
+  Color::Red,
+  Color::Green,
+  Color::Blue
+];
+
+#[allow(non_camel_case_types)]
+const ENUM_NAMES_COLOR:[&'static str; 8] = [
+    "Red",
+    "Green",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "Blue"
+];
+
+pub fn enum_name_color(e: Color) -> &'static str {
+  let index = e as u8 - Color::Red as u8;
+  ENUM_NAMES_COLOR[index as usize]
+}
+
+#[allow(non_camel_case_types)]
+#[repr(u8)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+pub enum Any {
+  NONE = 0,
+  Monster = 1,
+  TestSimpleTableWithEnum = 2,
+  MyGame_Example2_Monster = 3,
+
+}
+
+const ENUM_MIN_ANY: u8 = 0;
+const ENUM_MAX_ANY: u8 = 3;
+
+impl<'a> flatbuffers::Follow<'a> for Any {
+  type Inner = Self;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    flatbuffers::read_scalar_at::<Self>(buf, loc)
+  }
+}
+
+impl flatbuffers::EndianScalar for Any {
+  #[inline]
+  fn to_little_endian(self) -> Self {
+    let n = u8::to_le(self as u8);
+    let p = &n as *const u8 as *const Any;
+    unsafe { *p }
+  }
+  #[inline]
+  fn from_little_endian(self) -> Self {
+    let n = u8::from_le(self as u8);
+    let p = &n as *const u8 as *const Any;
+    unsafe { *p }
+  }
+}
+
+impl flatbuffers::Push for Any {
+    type Output = Any;
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        flatbuffers::emplace_scalar::<Any>(dst, *self);
+    }
+}
+
+#[allow(non_camel_case_types)]
+const ENUM_VALUES_ANY:[Any; 4] = [
+  Any::NONE,
+  Any::Monster,
+  Any::TestSimpleTableWithEnum,
+  Any::MyGame_Example2_Monster
+];
+
+#[allow(non_camel_case_types)]
+const ENUM_NAMES_ANY:[&'static str; 4] = [
+    "NONE",
+    "Monster",
+    "TestSimpleTableWithEnum",
+    "MyGame_Example2_Monster"
+];
+
+pub fn enum_name_any(e: Any) -> &'static str {
+  let index = e as u8;
+  ENUM_NAMES_ANY[index as usize]
+}
+
+pub struct AnyUnionTableOffset {}
+#[allow(non_camel_case_types)]
+#[repr(u8)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+pub enum AnyUniqueAliases {
+  NONE = 0,
+  M = 1,
+  TS = 2,
+  M2 = 3,
+
+}
+
+const ENUM_MIN_ANY_UNIQUE_ALIASES: u8 = 0;
+const ENUM_MAX_ANY_UNIQUE_ALIASES: u8 = 3;
+
+impl<'a> flatbuffers::Follow<'a> for AnyUniqueAliases {
+  type Inner = Self;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    flatbuffers::read_scalar_at::<Self>(buf, loc)
+  }
+}
+
+impl flatbuffers::EndianScalar for AnyUniqueAliases {
+  #[inline]
+  fn to_little_endian(self) -> Self {
+    let n = u8::to_le(self as u8);
+    let p = &n as *const u8 as *const AnyUniqueAliases;
+    unsafe { *p }
+  }
+  #[inline]
+  fn from_little_endian(self) -> Self {
+    let n = u8::from_le(self as u8);
+    let p = &n as *const u8 as *const AnyUniqueAliases;
+    unsafe { *p }
+  }
+}
+
+impl flatbuffers::Push for AnyUniqueAliases {
+    type Output = AnyUniqueAliases;
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        flatbuffers::emplace_scalar::<AnyUniqueAliases>(dst, *self);
+    }
+}
+
+#[allow(non_camel_case_types)]
+const ENUM_VALUES_ANY_UNIQUE_ALIASES:[AnyUniqueAliases; 4] = [
+  AnyUniqueAliases::NONE,
+  AnyUniqueAliases::M,
+  AnyUniqueAliases::TS,
+  AnyUniqueAliases::M2
+];
+
+#[allow(non_camel_case_types)]
+const ENUM_NAMES_ANY_UNIQUE_ALIASES:[&'static str; 4] = [
+    "NONE",
+    "M",
+    "TS",
+    "M2"
+];
+
+pub fn enum_name_any_unique_aliases(e: AnyUniqueAliases) -> &'static str {
+  let index = e as u8;
+  ENUM_NAMES_ANY_UNIQUE_ALIASES[index as usize]
+}
+
+pub struct AnyUniqueAliasesUnionTableOffset {}
+#[allow(non_camel_case_types)]
+#[repr(u8)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+pub enum AnyAmbiguousAliases {
+  NONE = 0,
+  M1 = 1,
+  M2 = 2,
+  M3 = 3,
+
+}
+
+const ENUM_MIN_ANY_AMBIGUOUS_ALIASES: u8 = 0;
+const ENUM_MAX_ANY_AMBIGUOUS_ALIASES: u8 = 3;
+
+impl<'a> flatbuffers::Follow<'a> for AnyAmbiguousAliases {
+  type Inner = Self;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    flatbuffers::read_scalar_at::<Self>(buf, loc)
+  }
+}
+
+impl flatbuffers::EndianScalar for AnyAmbiguousAliases {
+  #[inline]
+  fn to_little_endian(self) -> Self {
+    let n = u8::to_le(self as u8);
+    let p = &n as *const u8 as *const AnyAmbiguousAliases;
+    unsafe { *p }
+  }
+  #[inline]
+  fn from_little_endian(self) -> Self {
+    let n = u8::from_le(self as u8);
+    let p = &n as *const u8 as *const AnyAmbiguousAliases;
+    unsafe { *p }
+  }
+}
+
+impl flatbuffers::Push for AnyAmbiguousAliases {
+    type Output = AnyAmbiguousAliases;
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        flatbuffers::emplace_scalar::<AnyAmbiguousAliases>(dst, *self);
+    }
+}
+
+#[allow(non_camel_case_types)]
+const ENUM_VALUES_ANY_AMBIGUOUS_ALIASES:[AnyAmbiguousAliases; 4] = [
+  AnyAmbiguousAliases::NONE,
+  AnyAmbiguousAliases::M1,
+  AnyAmbiguousAliases::M2,
+  AnyAmbiguousAliases::M3
+];
+
+#[allow(non_camel_case_types)]
+const ENUM_NAMES_ANY_AMBIGUOUS_ALIASES:[&'static str; 4] = [
+    "NONE",
+    "M1",
+    "M2",
+    "M3"
+];
+
+pub fn enum_name_any_ambiguous_aliases(e: AnyAmbiguousAliases) -> &'static str {
+  let index = e as u8;
+  ENUM_NAMES_ANY_AMBIGUOUS_ALIASES[index as usize]
+}
+
+pub struct AnyAmbiguousAliasesUnionTableOffset {}
+// struct Test, aligned to 2
+#[repr(C, align(2))]
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub struct Test {
+  a_: i16,
+  b_: i8,
+  padding0__: u8,
+} // pub struct Test
+impl flatbuffers::SafeSliceAccess for Test {}
+impl<'a> flatbuffers::Follow<'a> for Test {
+  type Inner = &'a Test;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    <&'a Test>::follow(buf, loc)
+  }
+}
+impl<'a> flatbuffers::Follow<'a> for &'a Test {
+  type Inner = &'a Test;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    flatbuffers::follow_cast_ref::<Test>(buf, loc)
+  }
+}
+impl<'b> flatbuffers::Push for Test {
+    type Output = Test;
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        let src = unsafe {
+            ::std::slice::from_raw_parts(self as *const Test as *const u8, Self::size())
+        };
+        dst.copy_from_slice(src);
+    }
+}
+impl<'b> flatbuffers::Push for &'b Test {
+    type Output = Test;
+
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        let src = unsafe {
+            ::std::slice::from_raw_parts(*self as *const Test as *const u8, Self::size())
+        };
+        dst.copy_from_slice(src);
+    }
+}
+
+
+impl Test {
+  pub fn new<'a>(_a: i16, _b: i8) -> Self {
+    Test {
+      a_: _a.to_little_endian(),
+      b_: _b.to_little_endian(),
+
+      padding0__: 0,
+    }
+  }
+  pub fn a<'a>(&'a self) -> i16 {
+    self.a_.from_little_endian()
+  }
+  pub fn b<'a>(&'a self) -> i8 {
+    self.b_.from_little_endian()
+  }
+}
+
+// struct Vec3, aligned to 8
+#[repr(C, align(8))]
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub struct Vec3 {
+  x_: f32,
+  y_: f32,
+  z_: f32,
+  padding0__: u32,
+  test1_: f64,
+  test2_: Color,
+  padding1__: u8,
+  test3_: Test,
+  padding2__: u16,
+} // pub struct Vec3
+impl flatbuffers::SafeSliceAccess for Vec3 {}
+impl<'a> flatbuffers::Follow<'a> for Vec3 {
+  type Inner = &'a Vec3;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    <&'a Vec3>::follow(buf, loc)
+  }
+}
+impl<'a> flatbuffers::Follow<'a> for &'a Vec3 {
+  type Inner = &'a Vec3;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    flatbuffers::follow_cast_ref::<Vec3>(buf, loc)
+  }
+}
+impl<'b> flatbuffers::Push for Vec3 {
+    type Output = Vec3;
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        let src = unsafe {
+            ::std::slice::from_raw_parts(self as *const Vec3 as *const u8, Self::size())
+        };
+        dst.copy_from_slice(src);
+    }
+}
+impl<'b> flatbuffers::Push for &'b Vec3 {
+    type Output = Vec3;
+
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        let src = unsafe {
+            ::std::slice::from_raw_parts(*self as *const Vec3 as *const u8, Self::size())
+        };
+        dst.copy_from_slice(src);
+    }
+}
+
+
+impl Vec3 {
+  pub fn new<'a>(_x: f32, _y: f32, _z: f32, _test1: f64, _test2: Color, _test3: &'a Test) -> Self {
+    Vec3 {
+      x_: _x.to_little_endian(),
+      y_: _y.to_little_endian(),
+      z_: _z.to_little_endian(),
+      test1_: _test1.to_little_endian(),
+      test2_: _test2.to_little_endian(),
+      test3_: *_test3,
+
+      padding0__: 0,
+      padding1__: 0,
+      padding2__: 0,
+    }
+  }
+  pub fn x<'a>(&'a self) -> f32 {
+    self.x_.from_little_endian()
+  }
+  pub fn y<'a>(&'a self) -> f32 {
+    self.y_.from_little_endian()
+  }
+  pub fn z<'a>(&'a self) -> f32 {
+    self.z_.from_little_endian()
+  }
+  pub fn test1<'a>(&'a self) -> f64 {
+    self.test1_.from_little_endian()
+  }
+  pub fn test2<'a>(&'a self) -> Color {
+    self.test2_.from_little_endian()
+  }
+  pub fn test3<'a>(&'a self) -> &'a Test {
+    &self.test3_
+  }
+}
+
+// struct Ability, aligned to 4
+#[repr(C, align(4))]
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub struct Ability {
+  id_: u32,
+  distance_: u32,
+} // pub struct Ability
+impl flatbuffers::SafeSliceAccess for Ability {}
+impl<'a> flatbuffers::Follow<'a> for Ability {
+  type Inner = &'a Ability;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    <&'a Ability>::follow(buf, loc)
+  }
+}
+impl<'a> flatbuffers::Follow<'a> for &'a Ability {
+  type Inner = &'a Ability;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    flatbuffers::follow_cast_ref::<Ability>(buf, loc)
+  }
+}
+impl<'b> flatbuffers::Push for Ability {
+    type Output = Ability;
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        let src = unsafe {
+            ::std::slice::from_raw_parts(self as *const Ability as *const u8, Self::size())
+        };
+        dst.copy_from_slice(src);
+    }
+}
+impl<'b> flatbuffers::Push for &'b Ability {
+    type Output = Ability;
+
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        let src = unsafe {
+            ::std::slice::from_raw_parts(*self as *const Ability as *const u8, Self::size())
+        };
+        dst.copy_from_slice(src);
+    }
+}
+
+
+impl Ability {
+  pub fn new<'a>(_id: u32, _distance: u32) -> Self {
+    Ability {
+      id_: _id.to_little_endian(),
+      distance_: _distance.to_little_endian(),
+
+    }
+  }
+  pub fn id<'a>(&'a self) -> u32 {
+    self.id_.from_little_endian()
+  }
+  #[inline]
+  pub fn key_compare_less_than(&self, o: &Ability) ->  bool {
+    self.id() < o.id()
+  }
+
+  #[inline]
+  pub fn key_compare_with_value(&self, val: u32) ->  ::std::cmp::Ordering {
+    let key = self.id();
+    key.cmp(&val)
+  }
+  pub fn distance<'a>(&'a self) -> u32 {
+    self.distance_.from_little_endian()
+  }
+}
+
+pub enum TestSimpleTableWithEnumOffset {}
+#[derive(Copy, Clone, Debug, PartialEq)]
+
+pub struct TestSimpleTableWithEnum<'a> {
+  pub _tab: flatbuffers::Table<'a>,
+}
+
+impl<'a> flatbuffers::Follow<'a> for TestSimpleTableWithEnum<'a> {
+    type Inner = TestSimpleTableWithEnum<'a>;
+    #[inline]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        Self {
+            _tab: flatbuffers::Table { buf: buf, loc: loc },
+        }
+    }
+}
+
+impl<'a> TestSimpleTableWithEnum<'a> {
+    #[inline]
+    pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
+        TestSimpleTableWithEnum {
+            _tab: table,
+        }
+    }
+    #[allow(unused_mut)]
+    pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
+        _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
+        args: &'args TestSimpleTableWithEnumArgs) -> flatbuffers::WIPOffset<TestSimpleTableWithEnum<'bldr>> {
+      let mut builder = TestSimpleTableWithEnumBuilder::new(_fbb);
+      builder.add_color(args.color);
+      builder.finish()
+    }
+
+    pub const VT_COLOR: flatbuffers::VOffsetT = 4;
+
+  #[inline]
+  pub fn color(&self) -> Color {
+    self._tab.get::<Color>(TestSimpleTableWithEnum::VT_COLOR, Some(Color::Green)).unwrap()
+  }
+}
+
+pub struct TestSimpleTableWithEnumArgs {
+    pub color: Color,
+}
+impl<'a> Default for TestSimpleTableWithEnumArgs {
+    #[inline]
+    fn default() -> Self {
+        TestSimpleTableWithEnumArgs {
+            color: Color::Green,
+        }
+    }
+}
+pub struct TestSimpleTableWithEnumBuilder<'a: 'b, 'b> {
+  fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+  start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
+}
+impl<'a: 'b, 'b> TestSimpleTableWithEnumBuilder<'a, 'b> {
+  #[inline]
+  pub fn add_color(&mut self, color: Color) {
+    self.fbb_.push_slot::<Color>(TestSimpleTableWithEnum::VT_COLOR, color, Color::Green);
+  }
+  #[inline]
+  pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> TestSimpleTableWithEnumBuilder<'a, 'b> {
+    let start = _fbb.start_table();
+    TestSimpleTableWithEnumBuilder {
+      fbb_: _fbb,
+      start_: start,
+    }
+  }
+  #[inline]
+  pub fn finish(self) -> flatbuffers::WIPOffset<TestSimpleTableWithEnum<'a>> {
+    let o = self.fbb_.end_table(self.start_);
+    flatbuffers::WIPOffset::new(o.value())
+  }
+}
+
+pub enum StatOffset {}
+#[derive(Copy, Clone, Debug, PartialEq)]
+
+pub struct Stat<'a> {
+  pub _tab: flatbuffers::Table<'a>,
+}
+
+impl<'a> flatbuffers::Follow<'a> for Stat<'a> {
+    type Inner = Stat<'a>;
+    #[inline]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        Self {
+            _tab: flatbuffers::Table { buf: buf, loc: loc },
+        }
+    }
+}
+
+impl<'a> Stat<'a> {
+    #[inline]
+    pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
+        Stat {
+            _tab: table,
+        }
+    }
+    #[allow(unused_mut)]
+    pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
+        _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
+        args: &'args StatArgs<'args>) -> flatbuffers::WIPOffset<Stat<'bldr>> {
+      let mut builder = StatBuilder::new(_fbb);
+      builder.add_val(args.val);
+      if let Some(x) = args.id { builder.add_id(x); }
+      builder.add_count(args.count);
+      builder.finish()
+    }
+
+    pub const VT_ID: flatbuffers::VOffsetT = 4;
+    pub const VT_VAL: flatbuffers::VOffsetT = 6;
+    pub const VT_COUNT: flatbuffers::VOffsetT = 8;
+
+  #[inline]
+  pub fn id(&self) -> Option<&'a str> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(Stat::VT_ID, None)
+  }
+  #[inline]
+  pub fn val(&self) -> i64 {
+    self._tab.get::<i64>(Stat::VT_VAL, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn count(&self) -> u16 {
+    self._tab.get::<u16>(Stat::VT_COUNT, Some(0)).unwrap()
+  }
+}
+
+pub struct StatArgs<'a> {
+    pub id: Option<flatbuffers::WIPOffset<&'a  str>>,
+    pub val: i64,
+    pub count: u16,
+}
+impl<'a> Default for StatArgs<'a> {
+    #[inline]
+    fn default() -> Self {
+        StatArgs {
+            id: None,
+            val: 0,
+            count: 0,
+        }
+    }
+}
+pub struct StatBuilder<'a: 'b, 'b> {
+  fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+  start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
+}
+impl<'a: 'b, 'b> StatBuilder<'a, 'b> {
+  #[inline]
+  pub fn add_id(&mut self, id: flatbuffers::WIPOffset<&'b  str>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Stat::VT_ID, id);
+  }
+  #[inline]
+  pub fn add_val(&mut self, val: i64) {
+    self.fbb_.push_slot::<i64>(Stat::VT_VAL, val, 0);
+  }
+  #[inline]
+  pub fn add_count(&mut self, count: u16) {
+    self.fbb_.push_slot::<u16>(Stat::VT_COUNT, count, 0);
+  }
+  #[inline]
+  pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> StatBuilder<'a, 'b> {
+    let start = _fbb.start_table();
+    StatBuilder {
+      fbb_: _fbb,
+      start_: start,
+    }
+  }
+  #[inline]
+  pub fn finish(self) -> flatbuffers::WIPOffset<Stat<'a>> {
+    let o = self.fbb_.end_table(self.start_);
+    flatbuffers::WIPOffset::new(o.value())
+  }
+}
+
+pub enum ReferrableOffset {}
+#[derive(Copy, Clone, Debug, PartialEq)]
+
+pub struct Referrable<'a> {
+  pub _tab: flatbuffers::Table<'a>,
+}
+
+impl<'a> flatbuffers::Follow<'a> for Referrable<'a> {
+    type Inner = Referrable<'a>;
+    #[inline]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        Self {
+            _tab: flatbuffers::Table { buf: buf, loc: loc },
+        }
+    }
+}
+
+impl<'a> Referrable<'a> {
+    #[inline]
+    pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
+        Referrable {
+            _tab: table,
+        }
+    }
+    #[allow(unused_mut)]
+    pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
+        _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
+        args: &'args ReferrableArgs) -> flatbuffers::WIPOffset<Referrable<'bldr>> {
+      let mut builder = ReferrableBuilder::new(_fbb);
+      builder.add_id(args.id);
+      builder.finish()
+    }
+
+    pub const VT_ID: flatbuffers::VOffsetT = 4;
+
+  #[inline]
+  pub fn id(&self) -> u64 {
+    self._tab.get::<u64>(Referrable::VT_ID, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn key_compare_less_than(&self, o: &Referrable) ->  bool {
+    self.id() < o.id()
+  }
+
+  #[inline]
+  pub fn key_compare_with_value(&self, val: u64) ->  ::std::cmp::Ordering {
+    let key = self.id();
+    key.cmp(&val)
+  }
+}
+
+pub struct ReferrableArgs {
+    pub id: u64,
+}
+impl<'a> Default for ReferrableArgs {
+    #[inline]
+    fn default() -> Self {
+        ReferrableArgs {
+            id: 0,
+        }
+    }
+}
+pub struct ReferrableBuilder<'a: 'b, 'b> {
+  fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+  start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
+}
+impl<'a: 'b, 'b> ReferrableBuilder<'a, 'b> {
+  #[inline]
+  pub fn add_id(&mut self, id: u64) {
+    self.fbb_.push_slot::<u64>(Referrable::VT_ID, id, 0);
+  }
+  #[inline]
+  pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> ReferrableBuilder<'a, 'b> {
+    let start = _fbb.start_table();
+    ReferrableBuilder {
+      fbb_: _fbb,
+      start_: start,
+    }
+  }
+  #[inline]
+  pub fn finish(self) -> flatbuffers::WIPOffset<Referrable<'a>> {
+    let o = self.fbb_.end_table(self.start_);
+    flatbuffers::WIPOffset::new(o.value())
+  }
+}
+
+pub enum MonsterOffset {}
+#[derive(Copy, Clone, Debug, PartialEq)]
+
+/// an example documentation comment: monster object
+pub struct Monster<'a> {
+  pub _tab: flatbuffers::Table<'a>,
+}
+
+impl<'a> flatbuffers::Follow<'a> for Monster<'a> {
+    type Inner = Monster<'a>;
+    #[inline]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        Self {
+            _tab: flatbuffers::Table { buf: buf, loc: loc },
+        }
+    }
+}
+
+impl<'a> Monster<'a> {
+    #[inline]
+    pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
+        Monster {
+            _tab: table,
+        }
+    }
+    #[allow(unused_mut)]
+    pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
+        _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
+        args: &'args MonsterArgs<'args>) -> flatbuffers::WIPOffset<Monster<'bldr>> {
+      let mut builder = MonsterBuilder::new(_fbb);
+      builder.add_non_owning_reference(args.non_owning_reference);
+      builder.add_co_owning_reference(args.co_owning_reference);
+      builder.add_single_weak_reference(args.single_weak_reference);
+      builder.add_testhashu64_fnv1a(args.testhashu64_fnv1a);
+      builder.add_testhashs64_fnv1a(args.testhashs64_fnv1a);
+      builder.add_testhashu64_fnv1(args.testhashu64_fnv1);
+      builder.add_testhashs64_fnv1(args.testhashs64_fnv1);
+      if let Some(x) = args.vector_of_enums { builder.add_vector_of_enums(x); }
+      if let Some(x) = args.any_ambiguous { builder.add_any_ambiguous(x); }
+      if let Some(x) = args.any_unique { builder.add_any_unique(x); }
+      if let Some(x) = args.vector_of_non_owning_references { builder.add_vector_of_non_owning_references(x); }
+      if let Some(x) = args.vector_of_co_owning_references { builder.add_vector_of_co_owning_references(x); }
+      if let Some(x) = args.vector_of_strong_referrables { builder.add_vector_of_strong_referrables(x); }
+      if let Some(x) = args.vector_of_weak_references { builder.add_vector_of_weak_references(x); }
+      if let Some(x) = args.vector_of_referrables { builder.add_vector_of_referrables(x); }
+      if let Some(x) = args.parent_namespace_test { builder.add_parent_namespace_test(x); }
+      if let Some(x) = args.vector_of_doubles { builder.add_vector_of_doubles(x); }
+      if let Some(x) = args.vector_of_longs { builder.add_vector_of_longs(x); }
+      if let Some(x) = args.test5 { builder.add_test5(x); }
+      if let Some(x) = args.flex { builder.add_flex(x); }
+      if let Some(x) = args.testarrayofsortedstruct { builder.add_testarrayofsortedstruct(x); }
+      if let Some(x) = args.testarrayofstring2 { builder.add_testarrayofstring2(x); }
+      builder.add_testf3(args.testf3);
+      builder.add_testf2(args.testf2);
+      builder.add_testf(args.testf);
+      if let Some(x) = args.testarrayofbools { builder.add_testarrayofbools(x); }
+      builder.add_testhashu32_fnv1a(args.testhashu32_fnv1a);
+      builder.add_testhashs32_fnv1a(args.testhashs32_fnv1a);
+      builder.add_testhashu32_fnv1(args.testhashu32_fnv1);
+      builder.add_testhashs32_fnv1(args.testhashs32_fnv1);
+      if let Some(x) = args.testempty { builder.add_testempty(x); }
+      if let Some(x) = args.testnestedflatbuffer { builder.add_testnestedflatbuffer(x); }
+      if let Some(x) = args.enemy { builder.add_enemy(x); }
+      if let Some(x) = args.testarrayoftables { builder.add_testarrayoftables(x); }
+      if let Some(x) = args.testarrayofstring { builder.add_testarrayofstring(x); }
+      if let Some(x) = args.test4 { builder.add_test4(x); }
+      if let Some(x) = args.test { builder.add_test(x); }
+      if let Some(x) = args.inventory { builder.add_inventory(x); }
+      if let Some(x) = args.name { builder.add_name(x); }
+      if let Some(x) = args.pos { builder.add_pos(x); }
+      builder.add_hp(args.hp);
+      builder.add_mana(args.mana);
+      builder.add_any_ambiguous_type(args.any_ambiguous_type);
+      builder.add_any_unique_type(args.any_unique_type);
+      builder.add_testbool(args.testbool);
+      builder.add_test_type(args.test_type);
+      builder.add_color(args.color);
+      builder.finish()
+    }
+
+    pub const VT_POS: flatbuffers::VOffsetT = 4;
+    pub const VT_MANA: flatbuffers::VOffsetT = 6;
+    pub const VT_HP: flatbuffers::VOffsetT = 8;
+    pub const VT_NAME: flatbuffers::VOffsetT = 10;
+    pub const VT_INVENTORY: flatbuffers::VOffsetT = 14;
+    pub const VT_COLOR: flatbuffers::VOffsetT = 16;
+    pub const VT_TEST_TYPE: flatbuffers::VOffsetT = 18;
+    pub const VT_TEST: flatbuffers::VOffsetT = 20;
+    pub const VT_TEST4: flatbuffers::VOffsetT = 22;
+    pub const VT_TESTARRAYOFSTRING: flatbuffers::VOffsetT = 24;
+    pub const VT_TESTARRAYOFTABLES: flatbuffers::VOffsetT = 26;
+    pub const VT_ENEMY: flatbuffers::VOffsetT = 28;
+    pub const VT_TESTNESTEDFLATBUFFER: flatbuffers::VOffsetT = 30;
+    pub const VT_TESTEMPTY: flatbuffers::VOffsetT = 32;
+    pub const VT_TESTBOOL: flatbuffers::VOffsetT = 34;
+    pub const VT_TESTHASHS32_FNV1: flatbuffers::VOffsetT = 36;
+    pub const VT_TESTHASHU32_FNV1: flatbuffers::VOffsetT = 38;
+    pub const VT_TESTHASHS64_FNV1: flatbuffers::VOffsetT = 40;
+    pub const VT_TESTHASHU64_FNV1: flatbuffers::VOffsetT = 42;
+    pub const VT_TESTHASHS32_FNV1A: flatbuffers::VOffsetT = 44;
+    pub const VT_TESTHASHU32_FNV1A: flatbuffers::VOffsetT = 46;
+    pub const VT_TESTHASHS64_FNV1A: flatbuffers::VOffsetT = 48;
+    pub const VT_TESTHASHU64_FNV1A: flatbuffers::VOffsetT = 50;
+    pub const VT_TESTARRAYOFBOOLS: flatbuffers::VOffsetT = 52;
+    pub const VT_TESTF: flatbuffers::VOffsetT = 54;
+    pub const VT_TESTF2: flatbuffers::VOffsetT = 56;
+    pub const VT_TESTF3: flatbuffers::VOffsetT = 58;
+    pub const VT_TESTARRAYOFSTRING2: flatbuffers::VOffsetT = 60;
+    pub const VT_TESTARRAYOFSORTEDSTRUCT: flatbuffers::VOffsetT = 62;
+    pub const VT_FLEX: flatbuffers::VOffsetT = 64;
+    pub const VT_TEST5: flatbuffers::VOffsetT = 66;
+    pub const VT_VECTOR_OF_LONGS: flatbuffers::VOffsetT = 68;
+    pub const VT_VECTOR_OF_DOUBLES: flatbuffers::VOffsetT = 70;
+    pub const VT_PARENT_NAMESPACE_TEST: flatbuffers::VOffsetT = 72;
+    pub const VT_VECTOR_OF_REFERRABLES: flatbuffers::VOffsetT = 74;
+    pub const VT_SINGLE_WEAK_REFERENCE: flatbuffers::VOffsetT = 76;
+    pub const VT_VECTOR_OF_WEAK_REFERENCES: flatbuffers::VOffsetT = 78;
+    pub const VT_VECTOR_OF_STRONG_REFERRABLES: flatbuffers::VOffsetT = 80;
+    pub const VT_CO_OWNING_REFERENCE: flatbuffers::VOffsetT = 82;
+    pub const VT_VECTOR_OF_CO_OWNING_REFERENCES: flatbuffers::VOffsetT = 84;
+    pub const VT_NON_OWNING_REFERENCE: flatbuffers::VOffsetT = 86;
+    pub const VT_VECTOR_OF_NON_OWNING_REFERENCES: flatbuffers::VOffsetT = 88;
+    pub const VT_ANY_UNIQUE_TYPE: flatbuffers::VOffsetT = 90;
+    pub const VT_ANY_UNIQUE: flatbuffers::VOffsetT = 92;
+    pub const VT_ANY_AMBIGUOUS_TYPE: flatbuffers::VOffsetT = 94;
+    pub const VT_ANY_AMBIGUOUS: flatbuffers::VOffsetT = 96;
+    pub const VT_VECTOR_OF_ENUMS: flatbuffers::VOffsetT = 98;
+
+  #[inline]
+  pub fn pos(&self) -> Option<&'a Vec3> {
+    self._tab.get::<Vec3>(Monster::VT_POS, None)
+  }
+  #[inline]
+  pub fn mana(&self) -> i16 {
+    self._tab.get::<i16>(Monster::VT_MANA, Some(150)).unwrap()
+  }
+  #[inline]
+  pub fn hp(&self) -> i16 {
+    self._tab.get::<i16>(Monster::VT_HP, Some(100)).unwrap()
+  }
+  #[inline]
+  pub fn name(&self) -> &'a str {
+    self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(Monster::VT_NAME, None).unwrap()
+  }
+  #[inline]
+  pub fn key_compare_less_than(&self, o: &Monster) ->  bool {
+    self.name() < o.name()
+  }
+
+  #[inline]
+  pub fn key_compare_with_value(&self, val: & str) ->  ::std::cmp::Ordering {
+    let key = self.name();
+    key.cmp(&val)
+  }
+  #[inline]
+  pub fn inventory(&self) -> Option<&'a [u8]> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, u8>>>(Monster::VT_INVENTORY, None).map(|v| v.safe_slice())
+  }
+  #[inline]
+  pub fn color(&self) -> Color {
+    self._tab.get::<Color>(Monster::VT_COLOR, Some(Color::Blue)).unwrap()
+  }
+  #[inline]
+  pub fn test_type(&self) -> Any {
+    self._tab.get::<Any>(Monster::VT_TEST_TYPE, Some(Any::NONE)).unwrap()
+  }
+  #[inline]
+  pub fn test(&self) -> Option<flatbuffers::Table<'a>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Table<'a>>>(Monster::VT_TEST, None)
+  }
+  #[inline]
+  pub fn test4(&self) -> Option<&'a [Test]> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<Test>>>(Monster::VT_TEST4, None).map(|v| v.safe_slice() )
+  }
+  #[inline]
+  pub fn testarrayofstring(&self) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<&'a str>>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<flatbuffers::ForwardsUOffset<&'a str>>>>(Monster::VT_TESTARRAYOFSTRING, None)
+  }
+  /// an example documentation comment: this will end up in the generated code
+  /// multiline too
+  #[inline]
+  pub fn testarrayoftables(&self) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Monster<'a>>>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<flatbuffers::ForwardsUOffset<Monster<'a>>>>>(Monster::VT_TESTARRAYOFTABLES, None)
+  }
+  #[inline]
+  pub fn enemy(&self) -> Option<Monster<'a>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<Monster<'a>>>(Monster::VT_ENEMY, None)
+  }
+  #[inline]
+  pub fn testnestedflatbuffer(&self) -> Option<&'a [u8]> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, u8>>>(Monster::VT_TESTNESTEDFLATBUFFER, None).map(|v| v.safe_slice())
+  }
+  pub fn testnestedflatbuffer_nested_flatbuffer(&'a self) ->  Option<Monster<'a>> {
+     match self.testnestedflatbuffer() {
+         None => { None }
+         Some(data) => {
+             use self::flatbuffers::Follow;
+             Some(<flatbuffers::ForwardsUOffset<Monster<'a>>>::follow(data, 0))
+         },
+     }
+  }
+  #[inline]
+  pub fn testempty(&self) -> Option<Stat<'a>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<Stat<'a>>>(Monster::VT_TESTEMPTY, None)
+  }
+  #[inline]
+  pub fn testbool(&self) -> bool {
+    self._tab.get::<bool>(Monster::VT_TESTBOOL, Some(false)).unwrap()
+  }
+  #[inline]
+  pub fn testhashs32_fnv1(&self) -> i32 {
+    self._tab.get::<i32>(Monster::VT_TESTHASHS32_FNV1, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn testhashu32_fnv1(&self) -> u32 {
+    self._tab.get::<u32>(Monster::VT_TESTHASHU32_FNV1, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn testhashs64_fnv1(&self) -> i64 {
+    self._tab.get::<i64>(Monster::VT_TESTHASHS64_FNV1, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn testhashu64_fnv1(&self) -> u64 {
+    self._tab.get::<u64>(Monster::VT_TESTHASHU64_FNV1, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn testhashs32_fnv1a(&self) -> i32 {
+    self._tab.get::<i32>(Monster::VT_TESTHASHS32_FNV1A, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn testhashu32_fnv1a(&self) -> u32 {
+    self._tab.get::<u32>(Monster::VT_TESTHASHU32_FNV1A, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn testhashs64_fnv1a(&self) -> i64 {
+    self._tab.get::<i64>(Monster::VT_TESTHASHS64_FNV1A, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn testhashu64_fnv1a(&self) -> u64 {
+    self._tab.get::<u64>(Monster::VT_TESTHASHU64_FNV1A, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn testarrayofbools(&self) -> Option<&'a [bool]> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, bool>>>(Monster::VT_TESTARRAYOFBOOLS, None).map(|v| v.safe_slice())
+  }
+  #[inline]
+  pub fn testf(&self) -> f32 {
+    self._tab.get::<f32>(Monster::VT_TESTF, Some(3.14159)).unwrap()
+  }
+  #[inline]
+  pub fn testf2(&self) -> f32 {
+    self._tab.get::<f32>(Monster::VT_TESTF2, Some(3.0)).unwrap()
+  }
+  #[inline]
+  pub fn testf3(&self) -> f32 {
+    self._tab.get::<f32>(Monster::VT_TESTF3, Some(0.0)).unwrap()
+  }
+  #[inline]
+  pub fn testarrayofstring2(&self) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<&'a str>>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<flatbuffers::ForwardsUOffset<&'a str>>>>(Monster::VT_TESTARRAYOFSTRING2, None)
+  }
+  #[inline]
+  pub fn testarrayofsortedstruct(&self) -> Option<&'a [Ability]> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<Ability>>>(Monster::VT_TESTARRAYOFSORTEDSTRUCT, None).map(|v| v.safe_slice() )
+  }
+  #[inline]
+  pub fn flex(&self) -> Option<&'a [u8]> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, u8>>>(Monster::VT_FLEX, None).map(|v| v.safe_slice())
+  }
+  #[inline]
+  pub fn test5(&self) -> Option<&'a [Test]> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<Test>>>(Monster::VT_TEST5, None).map(|v| v.safe_slice() )
+  }
+  #[inline]
+  pub fn vector_of_longs(&self) -> Option<flatbuffers::Vector<'a, i64>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, i64>>>(Monster::VT_VECTOR_OF_LONGS, None)
+  }
+  #[inline]
+  pub fn vector_of_doubles(&self) -> Option<flatbuffers::Vector<'a, f64>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, f64>>>(Monster::VT_VECTOR_OF_DOUBLES, None)
+  }
+  #[inline]
+  pub fn parent_namespace_test(&self) -> Option<super::InParentNamespace<'a>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<super::InParentNamespace<'a>>>(Monster::VT_PARENT_NAMESPACE_TEST, None)
+  }
+  #[inline]
+  pub fn vector_of_referrables(&self) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Referrable<'a>>>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<flatbuffers::ForwardsUOffset<Referrable<'a>>>>>(Monster::VT_VECTOR_OF_REFERRABLES, None)
+  }
+  #[inline]
+  pub fn single_weak_reference(&self) -> u64 {
+    self._tab.get::<u64>(Monster::VT_SINGLE_WEAK_REFERENCE, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn vector_of_weak_references(&self) -> Option<flatbuffers::Vector<'a, u64>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, u64>>>(Monster::VT_VECTOR_OF_WEAK_REFERENCES, None)
+  }
+  #[inline]
+  pub fn vector_of_strong_referrables(&self) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Referrable<'a>>>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<flatbuffers::ForwardsUOffset<Referrable<'a>>>>>(Monster::VT_VECTOR_OF_STRONG_REFERRABLES, None)
+  }
+  #[inline]
+  pub fn co_owning_reference(&self) -> u64 {
+    self._tab.get::<u64>(Monster::VT_CO_OWNING_REFERENCE, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn vector_of_co_owning_references(&self) -> Option<flatbuffers::Vector<'a, u64>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, u64>>>(Monster::VT_VECTOR_OF_CO_OWNING_REFERENCES, None)
+  }
+  #[inline]
+  pub fn non_owning_reference(&self) -> u64 {
+    self._tab.get::<u64>(Monster::VT_NON_OWNING_REFERENCE, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn vector_of_non_owning_references(&self) -> Option<flatbuffers::Vector<'a, u64>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, u64>>>(Monster::VT_VECTOR_OF_NON_OWNING_REFERENCES, None)
+  }
+  #[inline]
+  pub fn any_unique_type(&self) -> AnyUniqueAliases {
+    self._tab.get::<AnyUniqueAliases>(Monster::VT_ANY_UNIQUE_TYPE, Some(AnyUniqueAliases::NONE)).unwrap()
+  }
+  #[inline]
+  pub fn any_unique(&self) -> Option<flatbuffers::Table<'a>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Table<'a>>>(Monster::VT_ANY_UNIQUE, None)
+  }
+  #[inline]
+  pub fn any_ambiguous_type(&self) -> AnyAmbiguousAliases {
+    self._tab.get::<AnyAmbiguousAliases>(Monster::VT_ANY_AMBIGUOUS_TYPE, Some(AnyAmbiguousAliases::NONE)).unwrap()
+  }
+  #[inline]
+  pub fn any_ambiguous(&self) -> Option<flatbuffers::Table<'a>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Table<'a>>>(Monster::VT_ANY_AMBIGUOUS, None)
+  }
+  #[inline]
+  pub fn vector_of_enums(&self) -> Option<flatbuffers::Vector<'a, Color>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, Color>>>(Monster::VT_VECTOR_OF_ENUMS, None)
+  }
+  #[inline]
+  #[allow(non_snake_case)]
+  pub fn test_as_monster(&self) -> Option<Monster<'a>> {
+    if self.test_type() == Any::Monster {
+      self.test().map(|u| Monster::init_from_table(u))
+    } else {
+      None
+    }
+  }
+
+  #[inline]
+  #[allow(non_snake_case)]
+  pub fn test_as_test_simple_table_with_enum(&self) -> Option<TestSimpleTableWithEnum<'a>> {
+    if self.test_type() == Any::TestSimpleTableWithEnum {
+      self.test().map(|u| TestSimpleTableWithEnum::init_from_table(u))
+    } else {
+      None
+    }
+  }
+
+  #[inline]
+  #[allow(non_snake_case)]
+  pub fn test_as_my_game_example_2_monster(&self) -> Option<super::example_2::Monster<'a>> {
+    if self.test_type() == Any::MyGame_Example2_Monster {
+      self.test().map(|u| super::example_2::Monster::init_from_table(u))
+    } else {
+      None
+    }
+  }
+
+  #[inline]
+  #[allow(non_snake_case)]
+  pub fn any_unique_as_m(&self) -> Option<Monster<'a>> {
+    if self.any_unique_type() == AnyUniqueAliases::M {
+      self.any_unique().map(|u| Monster::init_from_table(u))
+    } else {
+      None
+    }
+  }
+
+  #[inline]
+  #[allow(non_snake_case)]
+  pub fn any_unique_as_ts(&self) -> Option<TestSimpleTableWithEnum<'a>> {
+    if self.any_unique_type() == AnyUniqueAliases::TS {
+      self.any_unique().map(|u| TestSimpleTableWithEnum::init_from_table(u))
+    } else {
+      None
+    }
+  }
+
+  #[inline]
+  #[allow(non_snake_case)]
+  pub fn any_unique_as_m2(&self) -> Option<super::example_2::Monster<'a>> {
+    if self.any_unique_type() == AnyUniqueAliases::M2 {
+      self.any_unique().map(|u| super::example_2::Monster::init_from_table(u))
+    } else {
+      None
+    }
+  }
+
+  #[inline]
+  #[allow(non_snake_case)]
+  pub fn any_ambiguous_as_m1(&self) -> Option<Monster<'a>> {
+    if self.any_ambiguous_type() == AnyAmbiguousAliases::M1 {
+      self.any_ambiguous().map(|u| Monster::init_from_table(u))
+    } else {
+      None
+    }
+  }
+
+  #[inline]
+  #[allow(non_snake_case)]
+  pub fn any_ambiguous_as_m2(&self) -> Option<Monster<'a>> {
+    if self.any_ambiguous_type() == AnyAmbiguousAliases::M2 {
+      self.any_ambiguous().map(|u| Monster::init_from_table(u))
+    } else {
+      None
+    }
+  }
+
+  #[inline]
+  #[allow(non_snake_case)]
+  pub fn any_ambiguous_as_m3(&self) -> Option<Monster<'a>> {
+    if self.any_ambiguous_type() == AnyAmbiguousAliases::M3 {
+      self.any_ambiguous().map(|u| Monster::init_from_table(u))
+    } else {
+      None
+    }
+  }
+
+}
+
+pub struct MonsterArgs<'a> {
+    pub pos: Option<&'a  Vec3>,
+    pub mana: i16,
+    pub hp: i16,
+    pub name: Option<flatbuffers::WIPOffset<&'a  str>>,
+    pub inventory: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a ,  u8>>>,
+    pub color: Color,
+    pub test_type: Any,
+    pub test: Option<flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>>,
+    pub test4: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a , Test>>>,
+    pub testarrayofstring: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a , flatbuffers::ForwardsUOffset<&'a  str>>>>,
+    pub testarrayoftables: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a , flatbuffers::ForwardsUOffset<Monster<'a >>>>>,
+    pub enemy: Option<flatbuffers::WIPOffset<Monster<'a >>>,
+    pub testnestedflatbuffer: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a ,  u8>>>,
+    pub testempty: Option<flatbuffers::WIPOffset<Stat<'a >>>,
+    pub testbool: bool,
+    pub testhashs32_fnv1: i32,
+    pub testhashu32_fnv1: u32,
+    pub testhashs64_fnv1: i64,
+    pub testhashu64_fnv1: u64,
+    pub testhashs32_fnv1a: i32,
+    pub testhashu32_fnv1a: u32,
+    pub testhashs64_fnv1a: i64,
+    pub testhashu64_fnv1a: u64,
+    pub testarrayofbools: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a , bool>>>,
+    pub testf: f32,
+    pub testf2: f32,
+    pub testf3: f32,
+    pub testarrayofstring2: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a , flatbuffers::ForwardsUOffset<&'a  str>>>>,
+    pub testarrayofsortedstruct: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a , Ability>>>,
+    pub flex: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a ,  u8>>>,
+    pub test5: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a , Test>>>,
+    pub vector_of_longs: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a ,  i64>>>,
+    pub vector_of_doubles: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a ,  f64>>>,
+    pub parent_namespace_test: Option<flatbuffers::WIPOffset<super::InParentNamespace<'a >>>,
+    pub vector_of_referrables: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a , flatbuffers::ForwardsUOffset<Referrable<'a >>>>>,
+    pub single_weak_reference: u64,
+    pub vector_of_weak_references: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a ,  u64>>>,
+    pub vector_of_strong_referrables: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a , flatbuffers::ForwardsUOffset<Referrable<'a >>>>>,
+    pub co_owning_reference: u64,
+    pub vector_of_co_owning_references: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a ,  u64>>>,
+    pub non_owning_reference: u64,
+    pub vector_of_non_owning_references: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a ,  u64>>>,
+    pub any_unique_type: AnyUniqueAliases,
+    pub any_unique: Option<flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>>,
+    pub any_ambiguous_type: AnyAmbiguousAliases,
+    pub any_ambiguous: Option<flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>>,
+    pub vector_of_enums: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a , Color>>>,
+}
+impl<'a> Default for MonsterArgs<'a> {
+    #[inline]
+    fn default() -> Self {
+        MonsterArgs {
+            pos: None,
+            mana: 150,
+            hp: 100,
+            name: None, // required field
+            inventory: None,
+            color: Color::Blue,
+            test_type: Any::NONE,
+            test: None,
+            test4: None,
+            testarrayofstring: None,
+            testarrayoftables: None,
+            enemy: None,
+            testnestedflatbuffer: None,
+            testempty: None,
+            testbool: false,
+            testhashs32_fnv1: 0,
+            testhashu32_fnv1: 0,
+            testhashs64_fnv1: 0,
+            testhashu64_fnv1: 0,
+            testhashs32_fnv1a: 0,
+            testhashu32_fnv1a: 0,
+            testhashs64_fnv1a: 0,
+            testhashu64_fnv1a: 0,
+            testarrayofbools: None,
+            testf: 3.14159,
+            testf2: 3.0,
+            testf3: 0.0,
+            testarrayofstring2: None,
+            testarrayofsortedstruct: None,
+            flex: None,
+            test5: None,
+            vector_of_longs: None,
+            vector_of_doubles: None,
+            parent_namespace_test: None,
+            vector_of_referrables: None,
+            single_weak_reference: 0,
+            vector_of_weak_references: None,
+            vector_of_strong_referrables: None,
+            co_owning_reference: 0,
+            vector_of_co_owning_references: None,
+            non_owning_reference: 0,
+            vector_of_non_owning_references: None,
+            any_unique_type: AnyUniqueAliases::NONE,
+            any_unique: None,
+            any_ambiguous_type: AnyAmbiguousAliases::NONE,
+            any_ambiguous: None,
+            vector_of_enums: None,
+        }
+    }
+}
+pub struct MonsterBuilder<'a: 'b, 'b> {
+  fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+  start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
+}
+impl<'a: 'b, 'b> MonsterBuilder<'a, 'b> {
+  #[inline]
+  pub fn add_pos(&mut self, pos: &'b  Vec3) {
+    self.fbb_.push_slot_always::<&Vec3>(Monster::VT_POS, pos);
+  }
+  #[inline]
+  pub fn add_mana(&mut self, mana: i16) {
+    self.fbb_.push_slot::<i16>(Monster::VT_MANA, mana, 150);
+  }
+  #[inline]
+  pub fn add_hp(&mut self, hp: i16) {
+    self.fbb_.push_slot::<i16>(Monster::VT_HP, hp, 100);
+  }
+  #[inline]
+  pub fn add_name(&mut self, name: flatbuffers::WIPOffset<&'b  str>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_NAME, name);
+  }
+  #[inline]
+  pub fn add_inventory(&mut self, inventory: flatbuffers::WIPOffset<flatbuffers::Vector<'b , u8>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_INVENTORY, inventory);
+  }
+  #[inline]
+  pub fn add_color(&mut self, color: Color) {
+    self.fbb_.push_slot::<Color>(Monster::VT_COLOR, color, Color::Blue);
+  }
+  #[inline]
+  pub fn add_test_type(&mut self, test_type: Any) {
+    self.fbb_.push_slot::<Any>(Monster::VT_TEST_TYPE, test_type, Any::NONE);
+  }
+  #[inline]
+  pub fn add_test(&mut self, test: flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_TEST, test);
+  }
+  #[inline]
+  pub fn add_test4(&mut self, test4: flatbuffers::WIPOffset<flatbuffers::Vector<'b , Test>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_TEST4, test4);
+  }
+  #[inline]
+  pub fn add_testarrayofstring(&mut self, testarrayofstring: flatbuffers::WIPOffset<flatbuffers::Vector<'b , flatbuffers::ForwardsUOffset<&'b  str>>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_TESTARRAYOFSTRING, testarrayofstring);
+  }
+  #[inline]
+  pub fn add_testarrayoftables(&mut self, testarrayoftables: flatbuffers::WIPOffset<flatbuffers::Vector<'b , flatbuffers::ForwardsUOffset<Monster<'b >>>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_TESTARRAYOFTABLES, testarrayoftables);
+  }
+  #[inline]
+  pub fn add_enemy(&mut self, enemy: flatbuffers::WIPOffset<Monster<'b >>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<Monster>>(Monster::VT_ENEMY, enemy);
+  }
+  #[inline]
+  pub fn add_testnestedflatbuffer(&mut self, testnestedflatbuffer: flatbuffers::WIPOffset<flatbuffers::Vector<'b , u8>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_TESTNESTEDFLATBUFFER, testnestedflatbuffer);
+  }
+  #[inline]
+  pub fn add_testempty(&mut self, testempty: flatbuffers::WIPOffset<Stat<'b >>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<Stat>>(Monster::VT_TESTEMPTY, testempty);
+  }
+  #[inline]
+  pub fn add_testbool(&mut self, testbool: bool) {
+    self.fbb_.push_slot::<bool>(Monster::VT_TESTBOOL, testbool, false);
+  }
+  #[inline]
+  pub fn add_testhashs32_fnv1(&mut self, testhashs32_fnv1: i32) {
+    self.fbb_.push_slot::<i32>(Monster::VT_TESTHASHS32_FNV1, testhashs32_fnv1, 0);
+  }
+  #[inline]
+  pub fn add_testhashu32_fnv1(&mut self, testhashu32_fnv1: u32) {
+    self.fbb_.push_slot::<u32>(Monster::VT_TESTHASHU32_FNV1, testhashu32_fnv1, 0);
+  }
+  #[inline]
+  pub fn add_testhashs64_fnv1(&mut self, testhashs64_fnv1: i64) {
+    self.fbb_.push_slot::<i64>(Monster::VT_TESTHASHS64_FNV1, testhashs64_fnv1, 0);
+  }
+  #[inline]
+  pub fn add_testhashu64_fnv1(&mut self, testhashu64_fnv1: u64) {
+    self.fbb_.push_slot::<u64>(Monster::VT_TESTHASHU64_FNV1, testhashu64_fnv1, 0);
+  }
+  #[inline]
+  pub fn add_testhashs32_fnv1a(&mut self, testhashs32_fnv1a: i32) {
+    self.fbb_.push_slot::<i32>(Monster::VT_TESTHASHS32_FNV1A, testhashs32_fnv1a, 0);
+  }
+  #[inline]
+  pub fn add_testhashu32_fnv1a(&mut self, testhashu32_fnv1a: u32) {
+    self.fbb_.push_slot::<u32>(Monster::VT_TESTHASHU32_FNV1A, testhashu32_fnv1a, 0);
+  }
+  #[inline]
+  pub fn add_testhashs64_fnv1a(&mut self, testhashs64_fnv1a: i64) {
+    self.fbb_.push_slot::<i64>(Monster::VT_TESTHASHS64_FNV1A, testhashs64_fnv1a, 0);
+  }
+  #[inline]
+  pub fn add_testhashu64_fnv1a(&mut self, testhashu64_fnv1a: u64) {
+    self.fbb_.push_slot::<u64>(Monster::VT_TESTHASHU64_FNV1A, testhashu64_fnv1a, 0);
+  }
+  #[inline]
+  pub fn add_testarrayofbools(&mut self, testarrayofbools: flatbuffers::WIPOffset<flatbuffers::Vector<'b , bool>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_TESTARRAYOFBOOLS, testarrayofbools);
+  }
+  #[inline]
+  pub fn add_testf(&mut self, testf: f32) {
+    self.fbb_.push_slot::<f32>(Monster::VT_TESTF, testf, 3.14159);
+  }
+  #[inline]
+  pub fn add_testf2(&mut self, testf2: f32) {
+    self.fbb_.push_slot::<f32>(Monster::VT_TESTF2, testf2, 3.0);
+  }
+  #[inline]
+  pub fn add_testf3(&mut self, testf3: f32) {
+    self.fbb_.push_slot::<f32>(Monster::VT_TESTF3, testf3, 0.0);
+  }
+  #[inline]
+  pub fn add_testarrayofstring2(&mut self, testarrayofstring2: flatbuffers::WIPOffset<flatbuffers::Vector<'b , flatbuffers::ForwardsUOffset<&'b  str>>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_TESTARRAYOFSTRING2, testarrayofstring2);
+  }
+  #[inline]
+  pub fn add_testarrayofsortedstruct(&mut self, testarrayofsortedstruct: flatbuffers::WIPOffset<flatbuffers::Vector<'b , Ability>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_TESTARRAYOFSORTEDSTRUCT, testarrayofsortedstruct);
+  }
+  #[inline]
+  pub fn add_flex(&mut self, flex: flatbuffers::WIPOffset<flatbuffers::Vector<'b , u8>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_FLEX, flex);
+  }
+  #[inline]
+  pub fn add_test5(&mut self, test5: flatbuffers::WIPOffset<flatbuffers::Vector<'b , Test>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_TEST5, test5);
+  }
+  #[inline]
+  pub fn add_vector_of_longs(&mut self, vector_of_longs: flatbuffers::WIPOffset<flatbuffers::Vector<'b , i64>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_VECTOR_OF_LONGS, vector_of_longs);
+  }
+  #[inline]
+  pub fn add_vector_of_doubles(&mut self, vector_of_doubles: flatbuffers::WIPOffset<flatbuffers::Vector<'b , f64>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_VECTOR_OF_DOUBLES, vector_of_doubles);
+  }
+  #[inline]
+  pub fn add_parent_namespace_test(&mut self, parent_namespace_test: flatbuffers::WIPOffset<super::InParentNamespace<'b >>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<super::InParentNamespace>>(Monster::VT_PARENT_NAMESPACE_TEST, parent_namespace_test);
+  }
+  #[inline]
+  pub fn add_vector_of_referrables(&mut self, vector_of_referrables: flatbuffers::WIPOffset<flatbuffers::Vector<'b , flatbuffers::ForwardsUOffset<Referrable<'b >>>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_VECTOR_OF_REFERRABLES, vector_of_referrables);
+  }
+  #[inline]
+  pub fn add_single_weak_reference(&mut self, single_weak_reference: u64) {
+    self.fbb_.push_slot::<u64>(Monster::VT_SINGLE_WEAK_REFERENCE, single_weak_reference, 0);
+  }
+  #[inline]
+  pub fn add_vector_of_weak_references(&mut self, vector_of_weak_references: flatbuffers::WIPOffset<flatbuffers::Vector<'b , u64>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_VECTOR_OF_WEAK_REFERENCES, vector_of_weak_references);
+  }
+  #[inline]
+  pub fn add_vector_of_strong_referrables(&mut self, vector_of_strong_referrables: flatbuffers::WIPOffset<flatbuffers::Vector<'b , flatbuffers::ForwardsUOffset<Referrable<'b >>>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_VECTOR_OF_STRONG_REFERRABLES, vector_of_strong_referrables);
+  }
+  #[inline]
+  pub fn add_co_owning_reference(&mut self, co_owning_reference: u64) {
+    self.fbb_.push_slot::<u64>(Monster::VT_CO_OWNING_REFERENCE, co_owning_reference, 0);
+  }
+  #[inline]
+  pub fn add_vector_of_co_owning_references(&mut self, vector_of_co_owning_references: flatbuffers::WIPOffset<flatbuffers::Vector<'b , u64>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_VECTOR_OF_CO_OWNING_REFERENCES, vector_of_co_owning_references);
+  }
+  #[inline]
+  pub fn add_non_owning_reference(&mut self, non_owning_reference: u64) {
+    self.fbb_.push_slot::<u64>(Monster::VT_NON_OWNING_REFERENCE, non_owning_reference, 0);
+  }
+  #[inline]
+  pub fn add_vector_of_non_owning_references(&mut self, vector_of_non_owning_references: flatbuffers::WIPOffset<flatbuffers::Vector<'b , u64>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_VECTOR_OF_NON_OWNING_REFERENCES, vector_of_non_owning_references);
+  }
+  #[inline]
+  pub fn add_any_unique_type(&mut self, any_unique_type: AnyUniqueAliases) {
+    self.fbb_.push_slot::<AnyUniqueAliases>(Monster::VT_ANY_UNIQUE_TYPE, any_unique_type, AnyUniqueAliases::NONE);
+  }
+  #[inline]
+  pub fn add_any_unique(&mut self, any_unique: flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_ANY_UNIQUE, any_unique);
+  }
+  #[inline]
+  pub fn add_any_ambiguous_type(&mut self, any_ambiguous_type: AnyAmbiguousAliases) {
+    self.fbb_.push_slot::<AnyAmbiguousAliases>(Monster::VT_ANY_AMBIGUOUS_TYPE, any_ambiguous_type, AnyAmbiguousAliases::NONE);
+  }
+  #[inline]
+  pub fn add_any_ambiguous(&mut self, any_ambiguous: flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_ANY_AMBIGUOUS, any_ambiguous);
+  }
+  #[inline]
+  pub fn add_vector_of_enums(&mut self, vector_of_enums: flatbuffers::WIPOffset<flatbuffers::Vector<'b , Color>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_VECTOR_OF_ENUMS, vector_of_enums);
+  }
+  #[inline]
+  pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> MonsterBuilder<'a, 'b> {
+    let start = _fbb.start_table();
+    MonsterBuilder {
+      fbb_: _fbb,
+      start_: start,
+    }
+  }
+  #[inline]
+  pub fn finish(self) -> flatbuffers::WIPOffset<Monster<'a>> {
+    let o = self.fbb_.end_table(self.start_);
+    self.fbb_.required(o, Monster::VT_NAME,"name");
+    flatbuffers::WIPOffset::new(o.value())
+  }
+}
+
+pub enum TypeAliasesOffset {}
+#[derive(Copy, Clone, Debug, PartialEq)]
+
+pub struct TypeAliases<'a> {
+  pub _tab: flatbuffers::Table<'a>,
+}
+
+impl<'a> flatbuffers::Follow<'a> for TypeAliases<'a> {
+    type Inner = TypeAliases<'a>;
+    #[inline]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        Self {
+            _tab: flatbuffers::Table { buf: buf, loc: loc },
+        }
+    }
+}
+
+impl<'a> TypeAliases<'a> {
+    #[inline]
+    pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
+        TypeAliases {
+            _tab: table,
+        }
+    }
+    #[allow(unused_mut)]
+    pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
+        _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
+        args: &'args TypeAliasesArgs<'args>) -> flatbuffers::WIPOffset<TypeAliases<'bldr>> {
+      let mut builder = TypeAliasesBuilder::new(_fbb);
+      builder.add_f64_(args.f64_);
+      builder.add_u64_(args.u64_);
+      builder.add_i64_(args.i64_);
+      if let Some(x) = args.vf64 { builder.add_vf64(x); }
+      if let Some(x) = args.v8 { builder.add_v8(x); }
+      builder.add_f32_(args.f32_);
+      builder.add_u32_(args.u32_);
+      builder.add_i32_(args.i32_);
+      builder.add_u16_(args.u16_);
+      builder.add_i16_(args.i16_);
+      builder.add_u8_(args.u8_);
+      builder.add_i8_(args.i8_);
+      builder.finish()
+    }
+
+    pub const VT_I8_: flatbuffers::VOffsetT = 4;
+    pub const VT_U8_: flatbuffers::VOffsetT = 6;
+    pub const VT_I16_: flatbuffers::VOffsetT = 8;
+    pub const VT_U16_: flatbuffers::VOffsetT = 10;
+    pub const VT_I32_: flatbuffers::VOffsetT = 12;
+    pub const VT_U32_: flatbuffers::VOffsetT = 14;
+    pub const VT_I64_: flatbuffers::VOffsetT = 16;
+    pub const VT_U64_: flatbuffers::VOffsetT = 18;
+    pub const VT_F32_: flatbuffers::VOffsetT = 20;
+    pub const VT_F64_: flatbuffers::VOffsetT = 22;
+    pub const VT_V8: flatbuffers::VOffsetT = 24;
+    pub const VT_VF64: flatbuffers::VOffsetT = 26;
+
+  #[inline]
+  pub fn i8_(&self) -> i8 {
+    self._tab.get::<i8>(TypeAliases::VT_I8_, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn u8_(&self) -> u8 {
+    self._tab.get::<u8>(TypeAliases::VT_U8_, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn i16_(&self) -> i16 {
+    self._tab.get::<i16>(TypeAliases::VT_I16_, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn u16_(&self) -> u16 {
+    self._tab.get::<u16>(TypeAliases::VT_U16_, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn i32_(&self) -> i32 {
+    self._tab.get::<i32>(TypeAliases::VT_I32_, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn u32_(&self) -> u32 {
+    self._tab.get::<u32>(TypeAliases::VT_U32_, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn i64_(&self) -> i64 {
+    self._tab.get::<i64>(TypeAliases::VT_I64_, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn u64_(&self) -> u64 {
+    self._tab.get::<u64>(TypeAliases::VT_U64_, Some(0)).unwrap()
+  }
+  #[inline]
+  pub fn f32_(&self) -> f32 {
+    self._tab.get::<f32>(TypeAliases::VT_F32_, Some(0.0)).unwrap()
+  }
+  #[inline]
+  pub fn f64_(&self) -> f64 {
+    self._tab.get::<f64>(TypeAliases::VT_F64_, Some(0.0)).unwrap()
+  }
+  #[inline]
+  pub fn v8(&self) -> Option<&'a [i8]> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, i8>>>(TypeAliases::VT_V8, None).map(|v| v.safe_slice())
+  }
+  #[inline]
+  pub fn vf64(&self) -> Option<flatbuffers::Vector<'a, f64>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, f64>>>(TypeAliases::VT_VF64, None)
+  }
+}
+
+pub struct TypeAliasesArgs<'a> {
+    pub i8_: i8,
+    pub u8_: u8,
+    pub i16_: i16,
+    pub u16_: u16,
+    pub i32_: i32,
+    pub u32_: u32,
+    pub i64_: i64,
+    pub u64_: u64,
+    pub f32_: f32,
+    pub f64_: f64,
+    pub v8: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a ,  i8>>>,
+    pub vf64: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a ,  f64>>>,
+}
+impl<'a> Default for TypeAliasesArgs<'a> {
+    #[inline]
+    fn default() -> Self {
+        TypeAliasesArgs {
+            i8_: 0,
+            u8_: 0,
+            i16_: 0,
+            u16_: 0,
+            i32_: 0,
+            u32_: 0,
+            i64_: 0,
+            u64_: 0,
+            f32_: 0.0,
+            f64_: 0.0,
+            v8: None,
+            vf64: None,
+        }
+    }
+}
+pub struct TypeAliasesBuilder<'a: 'b, 'b> {
+  fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+  start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
+}
+impl<'a: 'b, 'b> TypeAliasesBuilder<'a, 'b> {
+  #[inline]
+  pub fn add_i8_(&mut self, i8_: i8) {
+    self.fbb_.push_slot::<i8>(TypeAliases::VT_I8_, i8_, 0);
+  }
+  #[inline]
+  pub fn add_u8_(&mut self, u8_: u8) {
+    self.fbb_.push_slot::<u8>(TypeAliases::VT_U8_, u8_, 0);
+  }
+  #[inline]
+  pub fn add_i16_(&mut self, i16_: i16) {
+    self.fbb_.push_slot::<i16>(TypeAliases::VT_I16_, i16_, 0);
+  }
+  #[inline]
+  pub fn add_u16_(&mut self, u16_: u16) {
+    self.fbb_.push_slot::<u16>(TypeAliases::VT_U16_, u16_, 0);
+  }
+  #[inline]
+  pub fn add_i32_(&mut self, i32_: i32) {
+    self.fbb_.push_slot::<i32>(TypeAliases::VT_I32_, i32_, 0);
+  }
+  #[inline]
+  pub fn add_u32_(&mut self, u32_: u32) {
+    self.fbb_.push_slot::<u32>(TypeAliases::VT_U32_, u32_, 0);
+  }
+  #[inline]
+  pub fn add_i64_(&mut self, i64_: i64) {
+    self.fbb_.push_slot::<i64>(TypeAliases::VT_I64_, i64_, 0);
+  }
+  #[inline]
+  pub fn add_u64_(&mut self, u64_: u64) {
+    self.fbb_.push_slot::<u64>(TypeAliases::VT_U64_, u64_, 0);
+  }
+  #[inline]
+  pub fn add_f32_(&mut self, f32_: f32) {
+    self.fbb_.push_slot::<f32>(TypeAliases::VT_F32_, f32_, 0.0);
+  }
+  #[inline]
+  pub fn add_f64_(&mut self, f64_: f64) {
+    self.fbb_.push_slot::<f64>(TypeAliases::VT_F64_, f64_, 0.0);
+  }
+  #[inline]
+  pub fn add_v8(&mut self, v8: flatbuffers::WIPOffset<flatbuffers::Vector<'b , i8>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(TypeAliases::VT_V8, v8);
+  }
+  #[inline]
+  pub fn add_vf64(&mut self, vf64: flatbuffers::WIPOffset<flatbuffers::Vector<'b , f64>>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(TypeAliases::VT_VF64, vf64);
+  }
+  #[inline]
+  pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> TypeAliasesBuilder<'a, 'b> {
+    let start = _fbb.start_table();
+    TypeAliasesBuilder {
+      fbb_: _fbb,
+      start_: start,
+    }
+  }
+  #[inline]
+  pub fn finish(self) -> flatbuffers::WIPOffset<TypeAliases<'a>> {
+    let o = self.fbb_.end_table(self.start_);
+    flatbuffers::WIPOffset::new(o.value())
+  }
+}
+
+#[inline]
+pub fn get_root_as_monster<'a>(buf: &'a [u8]) -> Monster<'a> {
+  flatbuffers::get_root::<Monster<'a>>(buf)
+}
+
+#[inline]
+pub fn get_size_prefixed_root_as_monster<'a>(buf: &'a [u8]) -> Monster<'a> {
+  flatbuffers::get_size_prefixed_root::<Monster<'a>>(buf)
+}
+
+pub const MONSTER_IDENTIFIER: &'static str = "MONS";
+
+#[inline]
+pub fn monster_buffer_has_identifier(buf: &[u8]) -> bool {
+  return flatbuffers::buffer_has_identifier(buf, MONSTER_IDENTIFIER, false);
+}
+
+#[inline]
+pub fn monster_size_prefixed_buffer_has_identifier(buf: &[u8]) -> bool {
+  return flatbuffers::buffer_has_identifier(buf, MONSTER_IDENTIFIER, true);
+}
+
+pub const MONSTER_EXTENSION: &'static str = "mon";
+
+#[inline]
+pub fn finish_monster_buffer<'a, 'b>(
+    fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+    root: flatbuffers::WIPOffset<Monster<'a>>) {
+  fbb.finish(root, Some(MONSTER_IDENTIFIER));
+}
+
+#[inline]
+pub fn finish_size_prefixed_monster_buffer<'a, 'b>(fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, root: flatbuffers::WIPOffset<Monster<'a>>) {
+  fbb.finish_size_prefixed(root, Some(MONSTER_IDENTIFIER));
+}
+}  // pub mod Example
+}  // pub mod MyGame
+
diff --git a/third_party/flatbuffers/tests/monster_test_generated.ts b/third_party/flatbuffers/tests/monster_test_generated.ts
new file mode 100644
index 0000000..5f51589
--- /dev/null
+++ b/third_party/flatbuffers/tests/monster_test_generated.ts
@@ -0,0 +1,3086 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+/**
+ * Composite components of Monster color.
+ *
+ * @enum {number}
+ */
+export namespace MyGame.Example{
+export enum Color{
+  Red= 1,
+
+  /**
+   * \brief color Green
+   * Green is bit_flag with value (1u << 1)
+   */
+  Green= 2,
+
+  /**
+   * \brief color Blue (1u << 3)
+   */
+  Blue= 8
+}};
+
+/**
+ * @enum {number}
+ */
+export namespace MyGame.Example{
+export enum Any{
+  NONE= 0,
+  Monster= 1,
+  TestSimpleTableWithEnum= 2,
+  MyGame_Example2_Monster= 3
+}};
+
+/**
+ * @enum {number}
+ */
+export namespace MyGame.Example{
+export enum AnyUniqueAliases{
+  NONE= 0,
+  M= 1,
+  TS= 2,
+  M2= 3
+}};
+
+/**
+ * @enum {number}
+ */
+export namespace MyGame.Example{
+export enum AnyAmbiguousAliases{
+  NONE= 0,
+  M1= 1,
+  M2= 2,
+  M3= 3
+}};
+
+/**
+ * @constructor
+ */
+export namespace MyGame{
+export class InParentNamespace {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns InParentNamespace
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):InParentNamespace {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param InParentNamespace= obj
+ * @returns InParentNamespace
+ */
+static getRootAsInParentNamespace(bb:flatbuffers.ByteBuffer, obj?:InParentNamespace):InParentNamespace {
+  return (obj || new InParentNamespace).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param InParentNamespace= obj
+ * @returns InParentNamespace
+ */
+static getSizePrefixedRootAsInParentNamespace(bb:flatbuffers.ByteBuffer, obj?:InParentNamespace):InParentNamespace {
+  return (obj || new InParentNamespace).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ */
+static startInParentNamespace(builder:flatbuffers.Builder) {
+  builder.startObject(0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @returns flatbuffers.Offset
+ */
+static endInParentNamespace(builder:flatbuffers.Builder):flatbuffers.Offset {
+  var offset = builder.endObject();
+  return offset;
+};
+
+static createInParentNamespace(builder:flatbuffers.Builder):flatbuffers.Offset {
+  InParentNamespace.startInParentNamespace(builder);
+  return InParentNamespace.endInParentNamespace(builder);
+}
+}
+}
+/**
+ * @constructor
+ */
+export namespace MyGame.Example2{
+export class Monster {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns Monster
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):Monster {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Monster= obj
+ * @returns Monster
+ */
+static getRootAsMonster(bb:flatbuffers.ByteBuffer, obj?:Monster):Monster {
+  return (obj || new Monster).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Monster= obj
+ * @returns Monster
+ */
+static getSizePrefixedRootAsMonster(bb:flatbuffers.ByteBuffer, obj?:Monster):Monster {
+  return (obj || new Monster).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ */
+static startMonster(builder:flatbuffers.Builder) {
+  builder.startObject(0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @returns flatbuffers.Offset
+ */
+static endMonster(builder:flatbuffers.Builder):flatbuffers.Offset {
+  var offset = builder.endObject();
+  return offset;
+};
+
+static createMonster(builder:flatbuffers.Builder):flatbuffers.Offset {
+  Monster.startMonster(builder);
+  return Monster.endMonster(builder);
+}
+}
+}
+/**
+ * @constructor
+ */
+export namespace MyGame.Example{
+export class Test {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns Test
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):Test {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @returns number
+ */
+a():number {
+  return this.bb!.readInt16(this.bb_pos);
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_a(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 0);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt16(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+b():number {
+  return this.bb!.readInt8(this.bb_pos + 2);
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_b(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 2);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number a
+ * @param number b
+ * @returns flatbuffers.Offset
+ */
+static createTest(builder:flatbuffers.Builder, a: number, b: number):flatbuffers.Offset {
+  builder.prep(2, 4);
+  builder.pad(1);
+  builder.writeInt8(b);
+  builder.writeInt16(a);
+  return builder.offset();
+};
+
+}
+}
+/**
+ * @constructor
+ */
+export namespace MyGame.Example{
+export class TestSimpleTableWithEnum {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns TestSimpleTableWithEnum
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):TestSimpleTableWithEnum {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param TestSimpleTableWithEnum= obj
+ * @returns TestSimpleTableWithEnum
+ */
+static getRootAsTestSimpleTableWithEnum(bb:flatbuffers.ByteBuffer, obj?:TestSimpleTableWithEnum):TestSimpleTableWithEnum {
+  return (obj || new TestSimpleTableWithEnum).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param TestSimpleTableWithEnum= obj
+ * @returns TestSimpleTableWithEnum
+ */
+static getSizePrefixedRootAsTestSimpleTableWithEnum(bb:flatbuffers.ByteBuffer, obj?:TestSimpleTableWithEnum):TestSimpleTableWithEnum {
+  return (obj || new TestSimpleTableWithEnum).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @returns MyGame.Example.Color
+ */
+color():MyGame.Example.Color {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+  return offset ? /**  */ (this.bb!.readUint8(this.bb_pos + offset)) : MyGame.Example.Color.Green;
+};
+
+/**
+ * @param MyGame.Example.Color value
+ * @returns boolean
+ */
+mutate_color(value:MyGame.Example.Color):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ */
+static startTestSimpleTableWithEnum(builder:flatbuffers.Builder) {
+  builder.startObject(1);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param MyGame.Example.Color color
+ */
+static addColor(builder:flatbuffers.Builder, color:MyGame.Example.Color) {
+  builder.addFieldInt8(0, color, MyGame.Example.Color.Green);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @returns flatbuffers.Offset
+ */
+static endTestSimpleTableWithEnum(builder:flatbuffers.Builder):flatbuffers.Offset {
+  var offset = builder.endObject();
+  return offset;
+};
+
+static createTestSimpleTableWithEnum(builder:flatbuffers.Builder, color:MyGame.Example.Color):flatbuffers.Offset {
+  TestSimpleTableWithEnum.startTestSimpleTableWithEnum(builder);
+  TestSimpleTableWithEnum.addColor(builder, color);
+  return TestSimpleTableWithEnum.endTestSimpleTableWithEnum(builder);
+}
+}
+}
+/**
+ * @constructor
+ */
+export namespace MyGame.Example{
+export class Vec3 {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns Vec3
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):Vec3 {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @returns number
+ */
+x():number {
+  return this.bb!.readFloat32(this.bb_pos);
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_x(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 0);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+y():number {
+  return this.bb!.readFloat32(this.bb_pos + 4);
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_y(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+z():number {
+  return this.bb!.readFloat32(this.bb_pos + 8);
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_z(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 8);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+test1():number {
+  return this.bb!.readFloat64(this.bb_pos + 16);
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_test1(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 16);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeFloat64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns MyGame.Example.Color
+ */
+test2():MyGame.Example.Color {
+  return /**  */ (this.bb!.readUint8(this.bb_pos + 24));
+};
+
+/**
+ * @param MyGame.Example.Color value
+ * @returns boolean
+ */
+mutate_test2(value:MyGame.Example.Color):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 24);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param MyGame.Example.Test= obj
+ * @returns MyGame.Example.Test|null
+ */
+test3(obj?:MyGame.Example.Test):MyGame.Example.Test|null {
+  return (obj || new MyGame.Example.Test).__init(this.bb_pos + 26, this.bb!);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number x
+ * @param number y
+ * @param number z
+ * @param number test1
+ * @param MyGame.Example.Color test2
+ * @param number test3_a
+ * @param number test3_b
+ * @returns flatbuffers.Offset
+ */
+static createVec3(builder:flatbuffers.Builder, x: number, y: number, z: number, test1: number, test2: MyGame.Example.Color, test3_a: number, test3_b: number):flatbuffers.Offset {
+  builder.prep(8, 32);
+  builder.pad(2);
+  builder.prep(2, 4);
+  builder.pad(1);
+  builder.writeInt8(test3_b);
+  builder.writeInt16(test3_a);
+  builder.pad(1);
+  builder.writeInt8(test2);
+  builder.writeFloat64(test1);
+  builder.pad(4);
+  builder.writeFloat32(z);
+  builder.writeFloat32(y);
+  builder.writeFloat32(x);
+  return builder.offset();
+};
+
+}
+}
+/**
+ * @constructor
+ */
+export namespace MyGame.Example{
+export class Ability {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns Ability
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):Ability {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @returns number
+ */
+id():number {
+  return this.bb!.readUint32(this.bb_pos);
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_id(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 0);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+distance():number {
+  return this.bb!.readUint32(this.bb_pos + 4);
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_distance(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number id
+ * @param number distance
+ * @returns flatbuffers.Offset
+ */
+static createAbility(builder:flatbuffers.Builder, id: number, distance: number):flatbuffers.Offset {
+  builder.prep(4, 8);
+  builder.writeInt32(distance);
+  builder.writeInt32(id);
+  return builder.offset();
+};
+
+}
+}
+/**
+ * @constructor
+ */
+export namespace MyGame.Example{
+export class Stat {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns Stat
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):Stat {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Stat= obj
+ * @returns Stat
+ */
+static getRootAsStat(bb:flatbuffers.ByteBuffer, obj?:Stat):Stat {
+  return (obj || new Stat).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Stat= obj
+ * @returns Stat
+ */
+static getSizePrefixedRootAsStat(bb:flatbuffers.ByteBuffer, obj?:Stat):Stat {
+  return (obj || new Stat).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.Encoding= optionalEncoding
+ * @returns string|Uint8Array|null
+ */
+id():string|null
+id(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
+id(optionalEncoding?:any):string|Uint8Array|null {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+  return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
+};
+
+/**
+ * @returns flatbuffers.Long
+ */
+val():flatbuffers.Long {
+  var offset = this.bb!.__offset(this.bb_pos, 6);
+  return offset ? this.bb!.readInt64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @param flatbuffers.Long value
+ * @returns boolean
+ */
+mutate_val(value:flatbuffers.Long):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 6);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+count():number {
+  var offset = this.bb!.__offset(this.bb_pos, 8);
+  return offset ? this.bb!.readUint16(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_count(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 8);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint16(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ */
+static startStat(builder:flatbuffers.Builder) {
+  builder.startObject(3);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset idOffset
+ */
+static addId(builder:flatbuffers.Builder, idOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(0, idOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Long val
+ */
+static addVal(builder:flatbuffers.Builder, val:flatbuffers.Long) {
+  builder.addFieldInt64(1, val, builder.createLong(0, 0));
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number count
+ */
+static addCount(builder:flatbuffers.Builder, count:number) {
+  builder.addFieldInt16(2, count, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @returns flatbuffers.Offset
+ */
+static endStat(builder:flatbuffers.Builder):flatbuffers.Offset {
+  var offset = builder.endObject();
+  return offset;
+};
+
+static createStat(builder:flatbuffers.Builder, idOffset:flatbuffers.Offset, val:flatbuffers.Long, count:number):flatbuffers.Offset {
+  Stat.startStat(builder);
+  Stat.addId(builder, idOffset);
+  Stat.addVal(builder, val);
+  Stat.addCount(builder, count);
+  return Stat.endStat(builder);
+}
+}
+}
+/**
+ * @constructor
+ */
+export namespace MyGame.Example{
+export class Referrable {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns Referrable
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):Referrable {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Referrable= obj
+ * @returns Referrable
+ */
+static getRootAsReferrable(bb:flatbuffers.ByteBuffer, obj?:Referrable):Referrable {
+  return (obj || new Referrable).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Referrable= obj
+ * @returns Referrable
+ */
+static getSizePrefixedRootAsReferrable(bb:flatbuffers.ByteBuffer, obj?:Referrable):Referrable {
+  return (obj || new Referrable).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @returns flatbuffers.Long
+ */
+id():flatbuffers.Long {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+  return offset ? this.bb!.readUint64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @param flatbuffers.Long value
+ * @returns boolean
+ */
+mutate_id(value:flatbuffers.Long):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ */
+static startReferrable(builder:flatbuffers.Builder) {
+  builder.startObject(1);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Long id
+ */
+static addId(builder:flatbuffers.Builder, id:flatbuffers.Long) {
+  builder.addFieldInt64(0, id, builder.createLong(0, 0));
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @returns flatbuffers.Offset
+ */
+static endReferrable(builder:flatbuffers.Builder):flatbuffers.Offset {
+  var offset = builder.endObject();
+  return offset;
+};
+
+static createReferrable(builder:flatbuffers.Builder, id:flatbuffers.Long):flatbuffers.Offset {
+  Referrable.startReferrable(builder);
+  Referrable.addId(builder, id);
+  return Referrable.endReferrable(builder);
+}
+}
+}
+/**
+ * an example documentation comment: monster object
+ *
+ * @constructor
+ */
+export namespace MyGame.Example{
+export class Monster {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns Monster
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):Monster {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Monster= obj
+ * @returns Monster
+ */
+static getRootAsMonster(bb:flatbuffers.ByteBuffer, obj?:Monster):Monster {
+  return (obj || new Monster).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Monster= obj
+ * @returns Monster
+ */
+static getSizePrefixedRootAsMonster(bb:flatbuffers.ByteBuffer, obj?:Monster):Monster {
+  return (obj || new Monster).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @returns boolean
+ */
+static bufferHasIdentifier(bb:flatbuffers.ByteBuffer):boolean {
+  return bb.__has_identifier('MONS');
+};
+
+/**
+ * @param MyGame.Example.Vec3= obj
+ * @returns MyGame.Example.Vec3|null
+ */
+pos(obj?:MyGame.Example.Vec3):MyGame.Example.Vec3|null {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+  return offset ? (obj || new MyGame.Example.Vec3).__init(this.bb_pos + offset, this.bb!) : null;
+};
+
+/**
+ * @returns number
+ */
+mana():number {
+  var offset = this.bb!.__offset(this.bb_pos, 6);
+  return offset ? this.bb!.readInt16(this.bb_pos + offset) : 150;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_mana(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 6);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt16(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+hp():number {
+  var offset = this.bb!.__offset(this.bb_pos, 8);
+  return offset ? this.bb!.readInt16(this.bb_pos + offset) : 100;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_hp(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 8);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt16(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Encoding= optionalEncoding
+ * @returns string|Uint8Array|null
+ */
+name():string|null
+name(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
+name(optionalEncoding?:any):string|Uint8Array|null {
+  var offset = this.bb!.__offset(this.bb_pos, 10);
+  return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
+};
+
+/**
+ * @param number index
+ * @returns number
+ */
+inventory(index: number):number|null {
+  var offset = this.bb!.__offset(this.bb_pos, 14);
+  return offset ? this.bb!.readUint8(this.bb!.__vector(this.bb_pos + offset) + index) : 0;
+};
+
+/**
+ * @returns number
+ */
+inventoryLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 14);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns Uint8Array
+ */
+inventoryArray():Uint8Array|null {
+  var offset = this.bb!.__offset(this.bb_pos, 14);
+  return offset ? new Uint8Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @returns MyGame.Example.Color
+ */
+color():MyGame.Example.Color {
+  var offset = this.bb!.__offset(this.bb_pos, 16);
+  return offset ? /**  */ (this.bb!.readUint8(this.bb_pos + offset)) : MyGame.Example.Color.Blue;
+};
+
+/**
+ * @param MyGame.Example.Color value
+ * @returns boolean
+ */
+mutate_color(value:MyGame.Example.Color):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 16);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns MyGame.Example.Any
+ */
+testType():MyGame.Example.Any {
+  var offset = this.bb!.__offset(this.bb_pos, 18);
+  return offset ? /**  */ (this.bb!.readUint8(this.bb_pos + offset)) : MyGame.Example.Any.NONE;
+};
+
+/**
+ * @param MyGame.Example.Any value
+ * @returns boolean
+ */
+mutate_test_type(value:MyGame.Example.Any):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 18);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Table obj
+ * @returns ?flatbuffers.Table
+ */
+test<T extends flatbuffers.Table>(obj:T):T|null {
+  var offset = this.bb!.__offset(this.bb_pos, 20);
+  return offset ? this.bb!.__union(obj, this.bb_pos + offset) : null;
+};
+
+/**
+ * @param number index
+ * @param MyGame.Example.Test= obj
+ * @returns MyGame.Example.Test
+ */
+test4(index: number, obj?:MyGame.Example.Test):MyGame.Example.Test|null {
+  var offset = this.bb!.__offset(this.bb_pos, 22);
+  return offset ? (obj || new MyGame.Example.Test).__init(this.bb!.__vector(this.bb_pos + offset) + index * 4, this.bb!) : null;
+};
+
+/**
+ * @returns number
+ */
+test4Length():number {
+  var offset = this.bb!.__offset(this.bb_pos, 22);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number index
+ * @param flatbuffers.Encoding= optionalEncoding
+ * @returns string|Uint8Array
+ */
+testarrayofstring(index: number):string
+testarrayofstring(index: number,optionalEncoding:flatbuffers.Encoding):string|Uint8Array
+testarrayofstring(index: number,optionalEncoding?:any):string|Uint8Array|null {
+  var offset = this.bb!.__offset(this.bb_pos, 24);
+  return offset ? this.bb!.__string(this.bb!.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null;
+};
+
+/**
+ * @returns number
+ */
+testarrayofstringLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 24);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * an example documentation comment: this will end up in the generated code
+ * multiline too
+ *
+ * @param number index
+ * @param MyGame.Example.Monster= obj
+ * @returns MyGame.Example.Monster
+ */
+testarrayoftables(index: number, obj?:MyGame.Example.Monster):MyGame.Example.Monster|null {
+  var offset = this.bb!.__offset(this.bb_pos, 26);
+  return offset ? (obj || new MyGame.Example.Monster).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
+};
+
+/**
+ * @returns number
+ */
+testarrayoftablesLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 26);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param MyGame.Example.Monster= obj
+ * @returns MyGame.Example.Monster|null
+ */
+enemy(obj?:MyGame.Example.Monster):MyGame.Example.Monster|null {
+  var offset = this.bb!.__offset(this.bb_pos, 28);
+  return offset ? (obj || new MyGame.Example.Monster).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
+};
+
+/**
+ * @param number index
+ * @returns number
+ */
+testnestedflatbuffer(index: number):number|null {
+  var offset = this.bb!.__offset(this.bb_pos, 30);
+  return offset ? this.bb!.readUint8(this.bb!.__vector(this.bb_pos + offset) + index) : 0;
+};
+
+/**
+ * @returns number
+ */
+testnestedflatbufferLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 30);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns Uint8Array
+ */
+testnestedflatbufferArray():Uint8Array|null {
+  var offset = this.bb!.__offset(this.bb_pos, 30);
+  return offset ? new Uint8Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param MyGame.Example.Stat= obj
+ * @returns MyGame.Example.Stat|null
+ */
+testempty(obj?:MyGame.Example.Stat):MyGame.Example.Stat|null {
+  var offset = this.bb!.__offset(this.bb_pos, 32);
+  return offset ? (obj || new MyGame.Example.Stat).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
+};
+
+/**
+ * @returns boolean
+ */
+testbool():boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 34);
+  return offset ? !!this.bb!.readInt8(this.bb_pos + offset) : false;
+};
+
+/**
+ * @param boolean value
+ * @returns boolean
+ */
+mutate_testbool(value:boolean):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 34);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt8(this.bb_pos + offset, +value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+testhashs32Fnv1():number {
+  var offset = this.bb!.__offset(this.bb_pos, 36);
+  return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_testhashs32_fnv1(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 36);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+testhashu32Fnv1():number {
+  var offset = this.bb!.__offset(this.bb_pos, 38);
+  return offset ? this.bb!.readUint32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_testhashu32_fnv1(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 38);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns flatbuffers.Long
+ */
+testhashs64Fnv1():flatbuffers.Long {
+  var offset = this.bb!.__offset(this.bb_pos, 40);
+  return offset ? this.bb!.readInt64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @param flatbuffers.Long value
+ * @returns boolean
+ */
+mutate_testhashs64_fnv1(value:flatbuffers.Long):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 40);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns flatbuffers.Long
+ */
+testhashu64Fnv1():flatbuffers.Long {
+  var offset = this.bb!.__offset(this.bb_pos, 42);
+  return offset ? this.bb!.readUint64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @param flatbuffers.Long value
+ * @returns boolean
+ */
+mutate_testhashu64_fnv1(value:flatbuffers.Long):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 42);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+testhashs32Fnv1a():number {
+  var offset = this.bb!.__offset(this.bb_pos, 44);
+  return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_testhashs32_fnv1a(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 44);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+testhashu32Fnv1a():number {
+  var offset = this.bb!.__offset(this.bb_pos, 46);
+  return offset ? this.bb!.readUint32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_testhashu32_fnv1a(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 46);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns flatbuffers.Long
+ */
+testhashs64Fnv1a():flatbuffers.Long {
+  var offset = this.bb!.__offset(this.bb_pos, 48);
+  return offset ? this.bb!.readInt64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @param flatbuffers.Long value
+ * @returns boolean
+ */
+mutate_testhashs64_fnv1a(value:flatbuffers.Long):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 48);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns flatbuffers.Long
+ */
+testhashu64Fnv1a():flatbuffers.Long {
+  var offset = this.bb!.__offset(this.bb_pos, 50);
+  return offset ? this.bb!.readUint64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @param flatbuffers.Long value
+ * @returns boolean
+ */
+mutate_testhashu64_fnv1a(value:flatbuffers.Long):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 50);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param number index
+ * @returns boolean
+ */
+testarrayofbools(index: number):boolean|null {
+  var offset = this.bb!.__offset(this.bb_pos, 52);
+  return offset ? !!this.bb!.readInt8(this.bb!.__vector(this.bb_pos + offset) + index) : false;
+};
+
+/**
+ * @returns number
+ */
+testarrayofboolsLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 52);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns Int8Array
+ */
+testarrayofboolsArray():Int8Array|null {
+  var offset = this.bb!.__offset(this.bb_pos, 52);
+  return offset ? new Int8Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @returns number
+ */
+testf():number {
+  var offset = this.bb!.__offset(this.bb_pos, 54);
+  return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 3.14159;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_testf(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 54);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+testf2():number {
+  var offset = this.bb!.__offset(this.bb_pos, 56);
+  return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 3.0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_testf2(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 56);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+testf3():number {
+  var offset = this.bb!.__offset(this.bb_pos, 58);
+  return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_testf3(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 58);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param number index
+ * @param flatbuffers.Encoding= optionalEncoding
+ * @returns string|Uint8Array
+ */
+testarrayofstring2(index: number):string
+testarrayofstring2(index: number,optionalEncoding:flatbuffers.Encoding):string|Uint8Array
+testarrayofstring2(index: number,optionalEncoding?:any):string|Uint8Array|null {
+  var offset = this.bb!.__offset(this.bb_pos, 60);
+  return offset ? this.bb!.__string(this.bb!.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null;
+};
+
+/**
+ * @returns number
+ */
+testarrayofstring2Length():number {
+  var offset = this.bb!.__offset(this.bb_pos, 60);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number index
+ * @param MyGame.Example.Ability= obj
+ * @returns MyGame.Example.Ability
+ */
+testarrayofsortedstruct(index: number, obj?:MyGame.Example.Ability):MyGame.Example.Ability|null {
+  var offset = this.bb!.__offset(this.bb_pos, 62);
+  return offset ? (obj || new MyGame.Example.Ability).__init(this.bb!.__vector(this.bb_pos + offset) + index * 8, this.bb!) : null;
+};
+
+/**
+ * @returns number
+ */
+testarrayofsortedstructLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 62);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number index
+ * @returns number
+ */
+flex(index: number):number|null {
+  var offset = this.bb!.__offset(this.bb_pos, 64);
+  return offset ? this.bb!.readUint8(this.bb!.__vector(this.bb_pos + offset) + index) : 0;
+};
+
+/**
+ * @returns number
+ */
+flexLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 64);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns Uint8Array
+ */
+flexArray():Uint8Array|null {
+  var offset = this.bb!.__offset(this.bb_pos, 64);
+  return offset ? new Uint8Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param number index
+ * @param MyGame.Example.Test= obj
+ * @returns MyGame.Example.Test
+ */
+test5(index: number, obj?:MyGame.Example.Test):MyGame.Example.Test|null {
+  var offset = this.bb!.__offset(this.bb_pos, 66);
+  return offset ? (obj || new MyGame.Example.Test).__init(this.bb!.__vector(this.bb_pos + offset) + index * 4, this.bb!) : null;
+};
+
+/**
+ * @returns number
+ */
+test5Length():number {
+  var offset = this.bb!.__offset(this.bb_pos, 66);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number index
+ * @returns flatbuffers.Long
+ */
+vectorOfLongs(index: number):flatbuffers.Long|null {
+  var offset = this.bb!.__offset(this.bb_pos, 68);
+  return offset ? this.bb!.readInt64(this.bb!.__vector(this.bb_pos + offset) + index * 8) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @returns number
+ */
+vectorOfLongsLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 68);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number index
+ * @returns number
+ */
+vectorOfDoubles(index: number):number|null {
+  var offset = this.bb!.__offset(this.bb_pos, 70);
+  return offset ? this.bb!.readFloat64(this.bb!.__vector(this.bb_pos + offset) + index * 8) : 0;
+};
+
+/**
+ * @returns number
+ */
+vectorOfDoublesLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 70);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns Float64Array
+ */
+vectorOfDoublesArray():Float64Array|null {
+  var offset = this.bb!.__offset(this.bb_pos, 70);
+  return offset ? new Float64Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param MyGame.InParentNamespace= obj
+ * @returns MyGame.InParentNamespace|null
+ */
+parentNamespaceTest(obj?:MyGame.InParentNamespace):MyGame.InParentNamespace|null {
+  var offset = this.bb!.__offset(this.bb_pos, 72);
+  return offset ? (obj || new MyGame.InParentNamespace).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
+};
+
+/**
+ * @param number index
+ * @param MyGame.Example.Referrable= obj
+ * @returns MyGame.Example.Referrable
+ */
+vectorOfReferrables(index: number, obj?:MyGame.Example.Referrable):MyGame.Example.Referrable|null {
+  var offset = this.bb!.__offset(this.bb_pos, 74);
+  return offset ? (obj || new MyGame.Example.Referrable).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
+};
+
+/**
+ * @returns number
+ */
+vectorOfReferrablesLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 74);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns flatbuffers.Long
+ */
+singleWeakReference():flatbuffers.Long {
+  var offset = this.bb!.__offset(this.bb_pos, 76);
+  return offset ? this.bb!.readUint64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @param flatbuffers.Long value
+ * @returns boolean
+ */
+mutate_single_weak_reference(value:flatbuffers.Long):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 76);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param number index
+ * @returns flatbuffers.Long
+ */
+vectorOfWeakReferences(index: number):flatbuffers.Long|null {
+  var offset = this.bb!.__offset(this.bb_pos, 78);
+  return offset ? this.bb!.readUint64(this.bb!.__vector(this.bb_pos + offset) + index * 8) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @returns number
+ */
+vectorOfWeakReferencesLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 78);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number index
+ * @param MyGame.Example.Referrable= obj
+ * @returns MyGame.Example.Referrable
+ */
+vectorOfStrongReferrables(index: number, obj?:MyGame.Example.Referrable):MyGame.Example.Referrable|null {
+  var offset = this.bb!.__offset(this.bb_pos, 80);
+  return offset ? (obj || new MyGame.Example.Referrable).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
+};
+
+/**
+ * @returns number
+ */
+vectorOfStrongReferrablesLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 80);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns flatbuffers.Long
+ */
+coOwningReference():flatbuffers.Long {
+  var offset = this.bb!.__offset(this.bb_pos, 82);
+  return offset ? this.bb!.readUint64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @param flatbuffers.Long value
+ * @returns boolean
+ */
+mutate_co_owning_reference(value:flatbuffers.Long):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 82);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param number index
+ * @returns flatbuffers.Long
+ */
+vectorOfCoOwningReferences(index: number):flatbuffers.Long|null {
+  var offset = this.bb!.__offset(this.bb_pos, 84);
+  return offset ? this.bb!.readUint64(this.bb!.__vector(this.bb_pos + offset) + index * 8) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @returns number
+ */
+vectorOfCoOwningReferencesLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 84);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns flatbuffers.Long
+ */
+nonOwningReference():flatbuffers.Long {
+  var offset = this.bb!.__offset(this.bb_pos, 86);
+  return offset ? this.bb!.readUint64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @param flatbuffers.Long value
+ * @returns boolean
+ */
+mutate_non_owning_reference(value:flatbuffers.Long):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 86);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param number index
+ * @returns flatbuffers.Long
+ */
+vectorOfNonOwningReferences(index: number):flatbuffers.Long|null {
+  var offset = this.bb!.__offset(this.bb_pos, 88);
+  return offset ? this.bb!.readUint64(this.bb!.__vector(this.bb_pos + offset) + index * 8) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @returns number
+ */
+vectorOfNonOwningReferencesLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 88);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns MyGame.Example.AnyUniqueAliases
+ */
+anyUniqueType():MyGame.Example.AnyUniqueAliases {
+  var offset = this.bb!.__offset(this.bb_pos, 90);
+  return offset ? /**  */ (this.bb!.readUint8(this.bb_pos + offset)) : MyGame.Example.AnyUniqueAliases.NONE;
+};
+
+/**
+ * @param MyGame.Example.AnyUniqueAliases value
+ * @returns boolean
+ */
+mutate_any_unique_type(value:MyGame.Example.AnyUniqueAliases):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 90);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Table obj
+ * @returns ?flatbuffers.Table
+ */
+anyUnique<T extends flatbuffers.Table>(obj:T):T|null {
+  var offset = this.bb!.__offset(this.bb_pos, 92);
+  return offset ? this.bb!.__union(obj, this.bb_pos + offset) : null;
+};
+
+/**
+ * @returns MyGame.Example.AnyAmbiguousAliases
+ */
+anyAmbiguousType():MyGame.Example.AnyAmbiguousAliases {
+  var offset = this.bb!.__offset(this.bb_pos, 94);
+  return offset ? /**  */ (this.bb!.readUint8(this.bb_pos + offset)) : MyGame.Example.AnyAmbiguousAliases.NONE;
+};
+
+/**
+ * @param MyGame.Example.AnyAmbiguousAliases value
+ * @returns boolean
+ */
+mutate_any_ambiguous_type(value:MyGame.Example.AnyAmbiguousAliases):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 94);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Table obj
+ * @returns ?flatbuffers.Table
+ */
+anyAmbiguous<T extends flatbuffers.Table>(obj:T):T|null {
+  var offset = this.bb!.__offset(this.bb_pos, 96);
+  return offset ? this.bb!.__union(obj, this.bb_pos + offset) : null;
+};
+
+/**
+ * @param number index
+ * @returns MyGame.Example.Color
+ */
+vectorOfEnums(index: number):MyGame.Example.Color|null {
+  var offset = this.bb!.__offset(this.bb_pos, 98);
+  return offset ? /**  */ (this.bb!.readUint8(this.bb!.__vector(this.bb_pos + offset) + index)) : /**  */ (0);
+};
+
+/**
+ * @returns number
+ */
+vectorOfEnumsLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 98);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns Uint8Array
+ */
+vectorOfEnumsArray():Uint8Array|null {
+  var offset = this.bb!.__offset(this.bb_pos, 98);
+  return offset ? new Uint8Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ */
+static startMonster(builder:flatbuffers.Builder) {
+  builder.startObject(48);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset posOffset
+ */
+static addPos(builder:flatbuffers.Builder, posOffset:flatbuffers.Offset) {
+  builder.addFieldStruct(0, posOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number mana
+ */
+static addMana(builder:flatbuffers.Builder, mana:number) {
+  builder.addFieldInt16(1, mana, 150);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number hp
+ */
+static addHp(builder:flatbuffers.Builder, hp:number) {
+  builder.addFieldInt16(2, hp, 100);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset nameOffset
+ */
+static addName(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(3, nameOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset inventoryOffset
+ */
+static addInventory(builder:flatbuffers.Builder, inventoryOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(5, inventoryOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<number> data
+ * @returns flatbuffers.Offset
+ */
+static createInventoryVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startInventoryVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param MyGame.Example.Color color
+ */
+static addColor(builder:flatbuffers.Builder, color:MyGame.Example.Color) {
+  builder.addFieldInt8(6, color, MyGame.Example.Color.Blue);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param MyGame.Example.Any testType
+ */
+static addTestType(builder:flatbuffers.Builder, testType:MyGame.Example.Any) {
+  builder.addFieldInt8(7, testType, MyGame.Example.Any.NONE);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset testOffset
+ */
+static addTest(builder:flatbuffers.Builder, testOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(8, testOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset test4Offset
+ */
+static addTest4(builder:flatbuffers.Builder, test4Offset:flatbuffers.Offset) {
+  builder.addFieldOffset(9, test4Offset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startTest4Vector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(4, numElems, 2);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset testarrayofstringOffset
+ */
+static addTestarrayofstring(builder:flatbuffers.Builder, testarrayofstringOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(10, testarrayofstringOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<flatbuffers.Offset> data
+ * @returns flatbuffers.Offset
+ */
+static createTestarrayofstringVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
+  builder.startVector(4, data.length, 4);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addOffset(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startTestarrayofstringVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(4, numElems, 4);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset testarrayoftablesOffset
+ */
+static addTestarrayoftables(builder:flatbuffers.Builder, testarrayoftablesOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(11, testarrayoftablesOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<flatbuffers.Offset> data
+ * @returns flatbuffers.Offset
+ */
+static createTestarrayoftablesVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
+  builder.startVector(4, data.length, 4);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addOffset(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startTestarrayoftablesVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(4, numElems, 4);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset enemyOffset
+ */
+static addEnemy(builder:flatbuffers.Builder, enemyOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(12, enemyOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset testnestedflatbufferOffset
+ */
+static addTestnestedflatbuffer(builder:flatbuffers.Builder, testnestedflatbufferOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(13, testnestedflatbufferOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<number> data
+ * @returns flatbuffers.Offset
+ */
+static createTestnestedflatbufferVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startTestnestedflatbufferVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset testemptyOffset
+ */
+static addTestempty(builder:flatbuffers.Builder, testemptyOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(14, testemptyOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param boolean testbool
+ */
+static addTestbool(builder:flatbuffers.Builder, testbool:boolean) {
+  builder.addFieldInt8(15, +testbool, +false);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number testhashs32Fnv1
+ */
+static addTesthashs32Fnv1(builder:flatbuffers.Builder, testhashs32Fnv1:number) {
+  builder.addFieldInt32(16, testhashs32Fnv1, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number testhashu32Fnv1
+ */
+static addTesthashu32Fnv1(builder:flatbuffers.Builder, testhashu32Fnv1:number) {
+  builder.addFieldInt32(17, testhashu32Fnv1, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Long testhashs64Fnv1
+ */
+static addTesthashs64Fnv1(builder:flatbuffers.Builder, testhashs64Fnv1:flatbuffers.Long) {
+  builder.addFieldInt64(18, testhashs64Fnv1, builder.createLong(0, 0));
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Long testhashu64Fnv1
+ */
+static addTesthashu64Fnv1(builder:flatbuffers.Builder, testhashu64Fnv1:flatbuffers.Long) {
+  builder.addFieldInt64(19, testhashu64Fnv1, builder.createLong(0, 0));
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number testhashs32Fnv1a
+ */
+static addTesthashs32Fnv1a(builder:flatbuffers.Builder, testhashs32Fnv1a:number) {
+  builder.addFieldInt32(20, testhashs32Fnv1a, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number testhashu32Fnv1a
+ */
+static addTesthashu32Fnv1a(builder:flatbuffers.Builder, testhashu32Fnv1a:number) {
+  builder.addFieldInt32(21, testhashu32Fnv1a, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Long testhashs64Fnv1a
+ */
+static addTesthashs64Fnv1a(builder:flatbuffers.Builder, testhashs64Fnv1a:flatbuffers.Long) {
+  builder.addFieldInt64(22, testhashs64Fnv1a, builder.createLong(0, 0));
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Long testhashu64Fnv1a
+ */
+static addTesthashu64Fnv1a(builder:flatbuffers.Builder, testhashu64Fnv1a:flatbuffers.Long) {
+  builder.addFieldInt64(23, testhashu64Fnv1a, builder.createLong(0, 0));
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset testarrayofboolsOffset
+ */
+static addTestarrayofbools(builder:flatbuffers.Builder, testarrayofboolsOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(24, testarrayofboolsOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<boolean> data
+ * @returns flatbuffers.Offset
+ */
+static createTestarrayofboolsVector(builder:flatbuffers.Builder, data:boolean[]):flatbuffers.Offset {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(+data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startTestarrayofboolsVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number testf
+ */
+static addTestf(builder:flatbuffers.Builder, testf:number) {
+  builder.addFieldFloat32(25, testf, 3.14159);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number testf2
+ */
+static addTestf2(builder:flatbuffers.Builder, testf2:number) {
+  builder.addFieldFloat32(26, testf2, 3.0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number testf3
+ */
+static addTestf3(builder:flatbuffers.Builder, testf3:number) {
+  builder.addFieldFloat32(27, testf3, 0.0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset testarrayofstring2Offset
+ */
+static addTestarrayofstring2(builder:flatbuffers.Builder, testarrayofstring2Offset:flatbuffers.Offset) {
+  builder.addFieldOffset(28, testarrayofstring2Offset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<flatbuffers.Offset> data
+ * @returns flatbuffers.Offset
+ */
+static createTestarrayofstring2Vector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
+  builder.startVector(4, data.length, 4);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addOffset(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startTestarrayofstring2Vector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(4, numElems, 4);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset testarrayofsortedstructOffset
+ */
+static addTestarrayofsortedstruct(builder:flatbuffers.Builder, testarrayofsortedstructOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(29, testarrayofsortedstructOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startTestarrayofsortedstructVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(8, numElems, 4);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset flexOffset
+ */
+static addFlex(builder:flatbuffers.Builder, flexOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(30, flexOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<number> data
+ * @returns flatbuffers.Offset
+ */
+static createFlexVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startFlexVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset test5Offset
+ */
+static addTest5(builder:flatbuffers.Builder, test5Offset:flatbuffers.Offset) {
+  builder.addFieldOffset(31, test5Offset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startTest5Vector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(4, numElems, 2);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset vectorOfLongsOffset
+ */
+static addVectorOfLongs(builder:flatbuffers.Builder, vectorOfLongsOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(32, vectorOfLongsOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<flatbuffers.Long> data
+ * @returns flatbuffers.Offset
+ */
+static createVectorOfLongsVector(builder:flatbuffers.Builder, data:flatbuffers.Long[]):flatbuffers.Offset {
+  builder.startVector(8, data.length, 8);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt64(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startVectorOfLongsVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(8, numElems, 8);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset vectorOfDoublesOffset
+ */
+static addVectorOfDoubles(builder:flatbuffers.Builder, vectorOfDoublesOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(33, vectorOfDoublesOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<number> data
+ * @returns flatbuffers.Offset
+ */
+static createVectorOfDoublesVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset {
+  builder.startVector(8, data.length, 8);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addFloat64(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startVectorOfDoublesVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(8, numElems, 8);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset parentNamespaceTestOffset
+ */
+static addParentNamespaceTest(builder:flatbuffers.Builder, parentNamespaceTestOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(34, parentNamespaceTestOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset vectorOfReferrablesOffset
+ */
+static addVectorOfReferrables(builder:flatbuffers.Builder, vectorOfReferrablesOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(35, vectorOfReferrablesOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<flatbuffers.Offset> data
+ * @returns flatbuffers.Offset
+ */
+static createVectorOfReferrablesVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
+  builder.startVector(4, data.length, 4);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addOffset(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startVectorOfReferrablesVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(4, numElems, 4);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Long singleWeakReference
+ */
+static addSingleWeakReference(builder:flatbuffers.Builder, singleWeakReference:flatbuffers.Long) {
+  builder.addFieldInt64(36, singleWeakReference, builder.createLong(0, 0));
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset vectorOfWeakReferencesOffset
+ */
+static addVectorOfWeakReferences(builder:flatbuffers.Builder, vectorOfWeakReferencesOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(37, vectorOfWeakReferencesOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<flatbuffers.Long> data
+ * @returns flatbuffers.Offset
+ */
+static createVectorOfWeakReferencesVector(builder:flatbuffers.Builder, data:flatbuffers.Long[]):flatbuffers.Offset {
+  builder.startVector(8, data.length, 8);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt64(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startVectorOfWeakReferencesVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(8, numElems, 8);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset vectorOfStrongReferrablesOffset
+ */
+static addVectorOfStrongReferrables(builder:flatbuffers.Builder, vectorOfStrongReferrablesOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(38, vectorOfStrongReferrablesOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<flatbuffers.Offset> data
+ * @returns flatbuffers.Offset
+ */
+static createVectorOfStrongReferrablesVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
+  builder.startVector(4, data.length, 4);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addOffset(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startVectorOfStrongReferrablesVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(4, numElems, 4);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Long coOwningReference
+ */
+static addCoOwningReference(builder:flatbuffers.Builder, coOwningReference:flatbuffers.Long) {
+  builder.addFieldInt64(39, coOwningReference, builder.createLong(0, 0));
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset vectorOfCoOwningReferencesOffset
+ */
+static addVectorOfCoOwningReferences(builder:flatbuffers.Builder, vectorOfCoOwningReferencesOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(40, vectorOfCoOwningReferencesOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<flatbuffers.Long> data
+ * @returns flatbuffers.Offset
+ */
+static createVectorOfCoOwningReferencesVector(builder:flatbuffers.Builder, data:flatbuffers.Long[]):flatbuffers.Offset {
+  builder.startVector(8, data.length, 8);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt64(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startVectorOfCoOwningReferencesVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(8, numElems, 8);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Long nonOwningReference
+ */
+static addNonOwningReference(builder:flatbuffers.Builder, nonOwningReference:flatbuffers.Long) {
+  builder.addFieldInt64(41, nonOwningReference, builder.createLong(0, 0));
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset vectorOfNonOwningReferencesOffset
+ */
+static addVectorOfNonOwningReferences(builder:flatbuffers.Builder, vectorOfNonOwningReferencesOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(42, vectorOfNonOwningReferencesOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<flatbuffers.Long> data
+ * @returns flatbuffers.Offset
+ */
+static createVectorOfNonOwningReferencesVector(builder:flatbuffers.Builder, data:flatbuffers.Long[]):flatbuffers.Offset {
+  builder.startVector(8, data.length, 8);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt64(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startVectorOfNonOwningReferencesVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(8, numElems, 8);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param MyGame.Example.AnyUniqueAliases anyUniqueType
+ */
+static addAnyUniqueType(builder:flatbuffers.Builder, anyUniqueType:MyGame.Example.AnyUniqueAliases) {
+  builder.addFieldInt8(43, anyUniqueType, MyGame.Example.AnyUniqueAliases.NONE);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset anyUniqueOffset
+ */
+static addAnyUnique(builder:flatbuffers.Builder, anyUniqueOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(44, anyUniqueOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param MyGame.Example.AnyAmbiguousAliases anyAmbiguousType
+ */
+static addAnyAmbiguousType(builder:flatbuffers.Builder, anyAmbiguousType:MyGame.Example.AnyAmbiguousAliases) {
+  builder.addFieldInt8(45, anyAmbiguousType, MyGame.Example.AnyAmbiguousAliases.NONE);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset anyAmbiguousOffset
+ */
+static addAnyAmbiguous(builder:flatbuffers.Builder, anyAmbiguousOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(46, anyAmbiguousOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset vectorOfEnumsOffset
+ */
+static addVectorOfEnums(builder:flatbuffers.Builder, vectorOfEnumsOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(47, vectorOfEnumsOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<MyGame.Example.Color> data
+ * @returns flatbuffers.Offset
+ */
+static createVectorOfEnumsVector(builder:flatbuffers.Builder, data:MyGame.Example.Color[]):flatbuffers.Offset {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startVectorOfEnumsVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @returns flatbuffers.Offset
+ */
+static endMonster(builder:flatbuffers.Builder):flatbuffers.Offset {
+  var offset = builder.endObject();
+  builder.requiredField(offset, 10); // name
+  return offset;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset offset
+ */
+static finishMonsterBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {
+  builder.finish(offset, 'MONS');
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset offset
+ */
+static finishSizePrefixedMonsterBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {
+  builder.finish(offset, 'MONS', true);
+};
+
+static createMonster(builder:flatbuffers.Builder, posOffset:flatbuffers.Offset, mana:number, hp:number, nameOffset:flatbuffers.Offset, inventoryOffset:flatbuffers.Offset, color:MyGame.Example.Color, testType:MyGame.Example.Any, testOffset:flatbuffers.Offset, test4Offset:flatbuffers.Offset, testarrayofstringOffset:flatbuffers.Offset, testarrayoftablesOffset:flatbuffers.Offset, enemyOffset:flatbuffers.Offset, testnestedflatbufferOffset:flatbuffers.Offset, testemptyOffset:flatbuffers.Offset, testbool:boolean, testhashs32Fnv1:number, testhashu32Fnv1:number, testhashs64Fnv1:flatbuffers.Long, testhashu64Fnv1:flatbuffers.Long, testhashs32Fnv1a:number, testhashu32Fnv1a:number, testhashs64Fnv1a:flatbuffers.Long, testhashu64Fnv1a:flatbuffers.Long, testarrayofboolsOffset:flatbuffers.Offset, testf:number, testf2:number, testf3:number, testarrayofstring2Offset:flatbuffers.Offset, testarrayofsortedstructOffset:flatbuffers.Offset, flexOffset:flatbuffers.Offset, test5Offset:flatbuffers.Offset, vectorOfLongsOffset:flatbuffers.Offset, vectorOfDoublesOffset:flatbuffers.Offset, parentNamespaceTestOffset:flatbuffers.Offset, vectorOfReferrablesOffset:flatbuffers.Offset, singleWeakReference:flatbuffers.Long, vectorOfWeakReferencesOffset:flatbuffers.Offset, vectorOfStrongReferrablesOffset:flatbuffers.Offset, coOwningReference:flatbuffers.Long, vectorOfCoOwningReferencesOffset:flatbuffers.Offset, nonOwningReference:flatbuffers.Long, vectorOfNonOwningReferencesOffset:flatbuffers.Offset, anyUniqueType:MyGame.Example.AnyUniqueAliases, anyUniqueOffset:flatbuffers.Offset, anyAmbiguousType:MyGame.Example.AnyAmbiguousAliases, anyAmbiguousOffset:flatbuffers.Offset, vectorOfEnumsOffset:flatbuffers.Offset):flatbuffers.Offset {
+  Monster.startMonster(builder);
+  Monster.addPos(builder, posOffset);
+  Monster.addMana(builder, mana);
+  Monster.addHp(builder, hp);
+  Monster.addName(builder, nameOffset);
+  Monster.addInventory(builder, inventoryOffset);
+  Monster.addColor(builder, color);
+  Monster.addTestType(builder, testType);
+  Monster.addTest(builder, testOffset);
+  Monster.addTest4(builder, test4Offset);
+  Monster.addTestarrayofstring(builder, testarrayofstringOffset);
+  Monster.addTestarrayoftables(builder, testarrayoftablesOffset);
+  Monster.addEnemy(builder, enemyOffset);
+  Monster.addTestnestedflatbuffer(builder, testnestedflatbufferOffset);
+  Monster.addTestempty(builder, testemptyOffset);
+  Monster.addTestbool(builder, testbool);
+  Monster.addTesthashs32Fnv1(builder, testhashs32Fnv1);
+  Monster.addTesthashu32Fnv1(builder, testhashu32Fnv1);
+  Monster.addTesthashs64Fnv1(builder, testhashs64Fnv1);
+  Monster.addTesthashu64Fnv1(builder, testhashu64Fnv1);
+  Monster.addTesthashs32Fnv1a(builder, testhashs32Fnv1a);
+  Monster.addTesthashu32Fnv1a(builder, testhashu32Fnv1a);
+  Monster.addTesthashs64Fnv1a(builder, testhashs64Fnv1a);
+  Monster.addTesthashu64Fnv1a(builder, testhashu64Fnv1a);
+  Monster.addTestarrayofbools(builder, testarrayofboolsOffset);
+  Monster.addTestf(builder, testf);
+  Monster.addTestf2(builder, testf2);
+  Monster.addTestf3(builder, testf3);
+  Monster.addTestarrayofstring2(builder, testarrayofstring2Offset);
+  Monster.addTestarrayofsortedstruct(builder, testarrayofsortedstructOffset);
+  Monster.addFlex(builder, flexOffset);
+  Monster.addTest5(builder, test5Offset);
+  Monster.addVectorOfLongs(builder, vectorOfLongsOffset);
+  Monster.addVectorOfDoubles(builder, vectorOfDoublesOffset);
+  Monster.addParentNamespaceTest(builder, parentNamespaceTestOffset);
+  Monster.addVectorOfReferrables(builder, vectorOfReferrablesOffset);
+  Monster.addSingleWeakReference(builder, singleWeakReference);
+  Monster.addVectorOfWeakReferences(builder, vectorOfWeakReferencesOffset);
+  Monster.addVectorOfStrongReferrables(builder, vectorOfStrongReferrablesOffset);
+  Monster.addCoOwningReference(builder, coOwningReference);
+  Monster.addVectorOfCoOwningReferences(builder, vectorOfCoOwningReferencesOffset);
+  Monster.addNonOwningReference(builder, nonOwningReference);
+  Monster.addVectorOfNonOwningReferences(builder, vectorOfNonOwningReferencesOffset);
+  Monster.addAnyUniqueType(builder, anyUniqueType);
+  Monster.addAnyUnique(builder, anyUniqueOffset);
+  Monster.addAnyAmbiguousType(builder, anyAmbiguousType);
+  Monster.addAnyAmbiguous(builder, anyAmbiguousOffset);
+  Monster.addVectorOfEnums(builder, vectorOfEnumsOffset);
+  return Monster.endMonster(builder);
+}
+}
+}
+/**
+ * @constructor
+ */
+export namespace MyGame.Example{
+export class TypeAliases {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns TypeAliases
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):TypeAliases {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param TypeAliases= obj
+ * @returns TypeAliases
+ */
+static getRootAsTypeAliases(bb:flatbuffers.ByteBuffer, obj?:TypeAliases):TypeAliases {
+  return (obj || new TypeAliases).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param TypeAliases= obj
+ * @returns TypeAliases
+ */
+static getSizePrefixedRootAsTypeAliases(bb:flatbuffers.ByteBuffer, obj?:TypeAliases):TypeAliases {
+  return (obj || new TypeAliases).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @returns number
+ */
+i8():number {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+  return offset ? this.bb!.readInt8(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_i8(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+u8():number {
+  var offset = this.bb!.__offset(this.bb_pos, 6);
+  return offset ? this.bb!.readUint8(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_u8(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 6);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+i16():number {
+  var offset = this.bb!.__offset(this.bb_pos, 8);
+  return offset ? this.bb!.readInt16(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_i16(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 8);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt16(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+u16():number {
+  var offset = this.bb!.__offset(this.bb_pos, 10);
+  return offset ? this.bb!.readUint16(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_u16(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 10);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint16(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+i32():number {
+  var offset = this.bb!.__offset(this.bb_pos, 12);
+  return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_i32(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 12);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+u32():number {
+  var offset = this.bb!.__offset(this.bb_pos, 14);
+  return offset ? this.bb!.readUint32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_u32(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 14);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns flatbuffers.Long
+ */
+i64():flatbuffers.Long {
+  var offset = this.bb!.__offset(this.bb_pos, 16);
+  return offset ? this.bb!.readInt64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @param flatbuffers.Long value
+ * @returns boolean
+ */
+mutate_i64(value:flatbuffers.Long):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 16);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns flatbuffers.Long
+ */
+u64():flatbuffers.Long {
+  var offset = this.bb!.__offset(this.bb_pos, 18);
+  return offset ? this.bb!.readUint64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
+};
+
+/**
+ * @param flatbuffers.Long value
+ * @returns boolean
+ */
+mutate_u64(value:flatbuffers.Long):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 18);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+f32():number {
+  var offset = this.bb!.__offset(this.bb_pos, 20);
+  return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_f32(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 20);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeFloat32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+f64():number {
+  var offset = this.bb!.__offset(this.bb_pos, 22);
+  return offset ? this.bb!.readFloat64(this.bb_pos + offset) : 0.0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_f64(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 22);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeFloat64(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param number index
+ * @returns number
+ */
+v8(index: number):number|null {
+  var offset = this.bb!.__offset(this.bb_pos, 24);
+  return offset ? this.bb!.readInt8(this.bb!.__vector(this.bb_pos + offset) + index) : 0;
+};
+
+/**
+ * @returns number
+ */
+v8Length():number {
+  var offset = this.bb!.__offset(this.bb_pos, 24);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns Int8Array
+ */
+v8Array():Int8Array|null {
+  var offset = this.bb!.__offset(this.bb_pos, 24);
+  return offset ? new Int8Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param number index
+ * @returns number
+ */
+vf64(index: number):number|null {
+  var offset = this.bb!.__offset(this.bb_pos, 26);
+  return offset ? this.bb!.readFloat64(this.bb!.__vector(this.bb_pos + offset) + index * 8) : 0;
+};
+
+/**
+ * @returns number
+ */
+vf64Length():number {
+  var offset = this.bb!.__offset(this.bb_pos, 26);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns Float64Array
+ */
+vf64Array():Float64Array|null {
+  var offset = this.bb!.__offset(this.bb_pos, 26);
+  return offset ? new Float64Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ */
+static startTypeAliases(builder:flatbuffers.Builder) {
+  builder.startObject(12);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number i8
+ */
+static addI8(builder:flatbuffers.Builder, i8:number) {
+  builder.addFieldInt8(0, i8, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number u8
+ */
+static addU8(builder:flatbuffers.Builder, u8:number) {
+  builder.addFieldInt8(1, u8, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number i16
+ */
+static addI16(builder:flatbuffers.Builder, i16:number) {
+  builder.addFieldInt16(2, i16, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number u16
+ */
+static addU16(builder:flatbuffers.Builder, u16:number) {
+  builder.addFieldInt16(3, u16, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number i32
+ */
+static addI32(builder:flatbuffers.Builder, i32:number) {
+  builder.addFieldInt32(4, i32, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number u32
+ */
+static addU32(builder:flatbuffers.Builder, u32:number) {
+  builder.addFieldInt32(5, u32, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Long i64
+ */
+static addI64(builder:flatbuffers.Builder, i64:flatbuffers.Long) {
+  builder.addFieldInt64(6, i64, builder.createLong(0, 0));
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Long u64
+ */
+static addU64(builder:flatbuffers.Builder, u64:flatbuffers.Long) {
+  builder.addFieldInt64(7, u64, builder.createLong(0, 0));
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number f32
+ */
+static addF32(builder:flatbuffers.Builder, f32:number) {
+  builder.addFieldFloat32(8, f32, 0.0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number f64
+ */
+static addF64(builder:flatbuffers.Builder, f64:number) {
+  builder.addFieldFloat64(9, f64, 0.0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset v8Offset
+ */
+static addV8(builder:flatbuffers.Builder, v8Offset:flatbuffers.Offset) {
+  builder.addFieldOffset(10, v8Offset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<number> data
+ * @returns flatbuffers.Offset
+ */
+static createV8Vector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startV8Vector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset vf64Offset
+ */
+static addVf64(builder:flatbuffers.Builder, vf64Offset:flatbuffers.Offset) {
+  builder.addFieldOffset(11, vf64Offset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<number> data
+ * @returns flatbuffers.Offset
+ */
+static createVf64Vector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset {
+  builder.startVector(8, data.length, 8);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addFloat64(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startVf64Vector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(8, numElems, 8);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @returns flatbuffers.Offset
+ */
+static endTypeAliases(builder:flatbuffers.Builder):flatbuffers.Offset {
+  var offset = builder.endObject();
+  return offset;
+};
+
+static createTypeAliases(builder:flatbuffers.Builder, i8:number, u8:number, i16:number, u16:number, i32:number, u32:number, i64:flatbuffers.Long, u64:flatbuffers.Long, f32:number, f64:number, v8Offset:flatbuffers.Offset, vf64Offset:flatbuffers.Offset):flatbuffers.Offset {
+  TypeAliases.startTypeAliases(builder);
+  TypeAliases.addI8(builder, i8);
+  TypeAliases.addU8(builder, u8);
+  TypeAliases.addI16(builder, i16);
+  TypeAliases.addU16(builder, u16);
+  TypeAliases.addI32(builder, i32);
+  TypeAliases.addU32(builder, u32);
+  TypeAliases.addI64(builder, i64);
+  TypeAliases.addU64(builder, u64);
+  TypeAliases.addF32(builder, f32);
+  TypeAliases.addF64(builder, f64);
+  TypeAliases.addV8(builder, v8Offset);
+  TypeAliases.addVf64(builder, vf64Offset);
+  return TypeAliases.endTypeAliases(builder);
+}
+}
+}
diff --git a/third_party/flatbuffers/tests/monster_test_my_game.example2_generated.dart b/third_party/flatbuffers/tests/monster_test_my_game.example2_generated.dart
new file mode 100644
index 0000000..eed14bc
--- /dev/null
+++ b/third_party/flatbuffers/tests/monster_test_my_game.example2_generated.dart
@@ -0,0 +1,60 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+// ignore_for_file: unused_import, unused_field, unused_local_variable
+
+library my_game.example2;
+
+import 'dart:typed_data' show Uint8List;
+import 'package:flat_buffers/flat_buffers.dart' as fb;
+
+import './monster_test_my_game_generated.dart' as my_game;
+import './monster_test_my_game.example_generated.dart' as my_game_example;
+
+class Monster {
+  Monster._(this._bc, this._bcOffset);
+  factory Monster(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<Monster> reader = const _MonsterReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+
+  @override
+  String toString() {
+    return 'Monster{}';
+  }
+}
+
+class _MonsterReader extends fb.TableReader<Monster> {
+  const _MonsterReader();
+
+  @override
+  Monster createObject(fb.BufferContext bc, int offset) => 
+    new Monster._(bc, offset);
+}
+
+class MonsterObjectBuilder extends fb.ObjectBuilder {
+
+  MonsterObjectBuilder();
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+
+    fbBuilder.startTable();
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
diff --git a/third_party/flatbuffers/tests/monster_test_my_game.example_generated.dart b/third_party/flatbuffers/tests/monster_test_my_game.example_generated.dart
new file mode 100644
index 0000000..13b7f4a
--- /dev/null
+++ b/third_party/flatbuffers/tests/monster_test_my_game.example_generated.dart
@@ -0,0 +1,1490 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+// ignore_for_file: unused_import, unused_field, unused_local_variable
+
+library my_game.example;
+
+import 'dart:typed_data' show Uint8List;
+import 'package:flat_buffers/flat_buffers.dart' as fb;
+
+import './monster_test_my_game_generated.dart' as my_game;
+import './monster_test_my_game.example2_generated.dart' as my_game_example2;
+
+///  Composite components of Monster color.
+class Color {
+  final int value;
+  const Color._(this.value);
+
+  factory Color.fromValue(int value) {
+    if (value == null) value = 0;
+    if (!values.containsKey(value)) {
+      throw new StateError('Invalid value $value for bit flag enum Color');
+    }
+    return values[value];
+  }
+
+  static bool containsValue(int value) => values.containsKey(value);
+
+  static const Color Red = const Color._(1);
+
+  ///  \brief color Green
+  ///  Green is bit_flag with value (1u << 1)
+  static const Color Green = const Color._(2);
+
+  ///  \brief color Blue (1u << 3)
+  static const Color Blue = const Color._(8);
+  static get values => {1: Red,2: Green,8: Blue,};
+
+  static const fb.Reader<Color> reader = const _ColorReader();
+
+  @override
+  String toString() {
+    return 'Color{value: $value}';
+  }
+}
+
+class _ColorReader extends fb.Reader<Color> {
+  const _ColorReader();
+
+  @override
+  int get size => 1;
+
+  @override
+  Color read(fb.BufferContext bc, int offset) =>
+      new Color.fromValue(const fb.Uint8Reader().read(bc, offset));
+}
+
+class AnyTypeId {
+  final int value;
+  const AnyTypeId._(this.value);
+
+  factory AnyTypeId.fromValue(int value) {
+    if (value == null) value = 0;
+    if (!values.containsKey(value)) {
+      throw new StateError('Invalid value $value for bit flag enum AnyTypeId');
+    }
+    return values[value];
+  }
+
+  static const int minValue = 0;
+  static const int maxValue = 3;
+  static bool containsValue(int value) => values.containsKey(value);
+
+  static const AnyTypeId NONE = const AnyTypeId._(0);
+  static const AnyTypeId Monster = const AnyTypeId._(1);
+  static const AnyTypeId TestSimpleTableWithEnum = const AnyTypeId._(2);
+  static const AnyTypeId MyGame_Example2_Monster = const AnyTypeId._(3);
+  static get values => {0: NONE,1: Monster,2: TestSimpleTableWithEnum,3: MyGame_Example2_Monster,};
+
+  static const fb.Reader<AnyTypeId> reader = const _AnyTypeIdReader();
+
+  @override
+  String toString() {
+    return 'AnyTypeId{value: $value}';
+  }
+}
+
+class _AnyTypeIdReader extends fb.Reader<AnyTypeId> {
+  const _AnyTypeIdReader();
+
+  @override
+  int get size => 1;
+
+  @override
+  AnyTypeId read(fb.BufferContext bc, int offset) =>
+      new AnyTypeId.fromValue(const fb.Uint8Reader().read(bc, offset));
+}
+
+class AnyUniqueAliasesTypeId {
+  final int value;
+  const AnyUniqueAliasesTypeId._(this.value);
+
+  factory AnyUniqueAliasesTypeId.fromValue(int value) {
+    if (value == null) value = 0;
+    if (!values.containsKey(value)) {
+      throw new StateError('Invalid value $value for bit flag enum AnyUniqueAliasesTypeId');
+    }
+    return values[value];
+  }
+
+  static const int minValue = 0;
+  static const int maxValue = 3;
+  static bool containsValue(int value) => values.containsKey(value);
+
+  static const AnyUniqueAliasesTypeId NONE = const AnyUniqueAliasesTypeId._(0);
+  static const AnyUniqueAliasesTypeId M = const AnyUniqueAliasesTypeId._(1);
+  static const AnyUniqueAliasesTypeId TS = const AnyUniqueAliasesTypeId._(2);
+  static const AnyUniqueAliasesTypeId M2 = const AnyUniqueAliasesTypeId._(3);
+  static get values => {0: NONE,1: M,2: TS,3: M2,};
+
+  static const fb.Reader<AnyUniqueAliasesTypeId> reader = const _AnyUniqueAliasesTypeIdReader();
+
+  @override
+  String toString() {
+    return 'AnyUniqueAliasesTypeId{value: $value}';
+  }
+}
+
+class _AnyUniqueAliasesTypeIdReader extends fb.Reader<AnyUniqueAliasesTypeId> {
+  const _AnyUniqueAliasesTypeIdReader();
+
+  @override
+  int get size => 1;
+
+  @override
+  AnyUniqueAliasesTypeId read(fb.BufferContext bc, int offset) =>
+      new AnyUniqueAliasesTypeId.fromValue(const fb.Uint8Reader().read(bc, offset));
+}
+
+class AnyAmbiguousAliasesTypeId {
+  final int value;
+  const AnyAmbiguousAliasesTypeId._(this.value);
+
+  factory AnyAmbiguousAliasesTypeId.fromValue(int value) {
+    if (value == null) value = 0;
+    if (!values.containsKey(value)) {
+      throw new StateError('Invalid value $value for bit flag enum AnyAmbiguousAliasesTypeId');
+    }
+    return values[value];
+  }
+
+  static const int minValue = 0;
+  static const int maxValue = 3;
+  static bool containsValue(int value) => values.containsKey(value);
+
+  static const AnyAmbiguousAliasesTypeId NONE = const AnyAmbiguousAliasesTypeId._(0);
+  static const AnyAmbiguousAliasesTypeId M1 = const AnyAmbiguousAliasesTypeId._(1);
+  static const AnyAmbiguousAliasesTypeId M2 = const AnyAmbiguousAliasesTypeId._(2);
+  static const AnyAmbiguousAliasesTypeId M3 = const AnyAmbiguousAliasesTypeId._(3);
+  static get values => {0: NONE,1: M1,2: M2,3: M3,};
+
+  static const fb.Reader<AnyAmbiguousAliasesTypeId> reader = const _AnyAmbiguousAliasesTypeIdReader();
+
+  @override
+  String toString() {
+    return 'AnyAmbiguousAliasesTypeId{value: $value}';
+  }
+}
+
+class _AnyAmbiguousAliasesTypeIdReader extends fb.Reader<AnyAmbiguousAliasesTypeId> {
+  const _AnyAmbiguousAliasesTypeIdReader();
+
+  @override
+  int get size => 1;
+
+  @override
+  AnyAmbiguousAliasesTypeId read(fb.BufferContext bc, int offset) =>
+      new AnyAmbiguousAliasesTypeId.fromValue(const fb.Uint8Reader().read(bc, offset));
+}
+
+class Test {
+  Test._(this._bc, this._bcOffset);
+
+  static const fb.Reader<Test> reader = const _TestReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  int get a => const fb.Int16Reader().read(_bc, _bcOffset + 0);
+  int get b => const fb.Int8Reader().read(_bc, _bcOffset + 2);
+
+  @override
+  String toString() {
+    return 'Test{a: $a, b: $b}';
+  }
+}
+
+class _TestReader extends fb.StructReader<Test> {
+  const _TestReader();
+
+  @override
+  int get size => 4;
+
+  @override
+  Test createObject(fb.BufferContext bc, int offset) => 
+    new Test._(bc, offset);
+}
+
+class TestBuilder {
+  TestBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  int finish(int a, int b) {
+    fbBuilder.pad(1);
+    fbBuilder.putInt8(b);
+    fbBuilder.putInt16(a);
+    return fbBuilder.offset;
+  }
+
+}
+
+class TestObjectBuilder extends fb.ObjectBuilder {
+  final int _a;
+  final int _b;
+
+  TestObjectBuilder({
+    int a,
+    int b,
+  })
+      : _a = a,
+        _b = b;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+
+    fbBuilder.pad(1);
+    fbBuilder.putInt8(_b);
+    fbBuilder.putInt16(_a);
+    return fbBuilder.offset;
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
+class TestSimpleTableWithEnum {
+  TestSimpleTableWithEnum._(this._bc, this._bcOffset);
+  factory TestSimpleTableWithEnum(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<TestSimpleTableWithEnum> reader = const _TestSimpleTableWithEnumReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  Color get color => new Color.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 4, 2));
+
+  @override
+  String toString() {
+    return 'TestSimpleTableWithEnum{color: $color}';
+  }
+}
+
+class _TestSimpleTableWithEnumReader extends fb.TableReader<TestSimpleTableWithEnum> {
+  const _TestSimpleTableWithEnumReader();
+
+  @override
+  TestSimpleTableWithEnum createObject(fb.BufferContext bc, int offset) => 
+    new TestSimpleTableWithEnum._(bc, offset);
+}
+
+class TestSimpleTableWithEnumBuilder {
+  TestSimpleTableWithEnumBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  void begin() {
+    fbBuilder.startTable();
+  }
+
+  int addColor(Color color) {
+    fbBuilder.addUint8(0, color?.value);
+    return fbBuilder.offset;
+  }
+
+  int finish() {
+    return fbBuilder.endTable();
+  }
+}
+
+class TestSimpleTableWithEnumObjectBuilder extends fb.ObjectBuilder {
+  final Color _color;
+
+  TestSimpleTableWithEnumObjectBuilder({
+    Color color,
+  })
+      : _color = color;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+
+    fbBuilder.startTable();
+    fbBuilder.addUint8(0, _color?.value);
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
+class Vec3 {
+  Vec3._(this._bc, this._bcOffset);
+
+  static const fb.Reader<Vec3> reader = const _Vec3Reader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  double get x => const fb.Float32Reader().read(_bc, _bcOffset + 0);
+  double get y => const fb.Float32Reader().read(_bc, _bcOffset + 4);
+  double get z => const fb.Float32Reader().read(_bc, _bcOffset + 8);
+  double get test1 => const fb.Float64Reader().read(_bc, _bcOffset + 16);
+  Color get test2 => new Color.fromValue(const fb.Uint8Reader().read(_bc, _bcOffset + 24));
+  Test get test3 => Test.reader.read(_bc, _bcOffset + 26);
+
+  @override
+  String toString() {
+    return 'Vec3{x: $x, y: $y, z: $z, test1: $test1, test2: $test2, test3: $test3}';
+  }
+}
+
+class _Vec3Reader extends fb.StructReader<Vec3> {
+  const _Vec3Reader();
+
+  @override
+  int get size => 32;
+
+  @override
+  Vec3 createObject(fb.BufferContext bc, int offset) => 
+    new Vec3._(bc, offset);
+}
+
+class Vec3Builder {
+  Vec3Builder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  int finish(double x, double y, double z, double test1, Color test2, fb.StructBuilder test3) {
+    fbBuilder.pad(2);
+    test3();
+    fbBuilder.pad(1);
+    fbBuilder.putUint8(test2?.value);
+    fbBuilder.putFloat64(test1);
+    fbBuilder.pad(4);
+    fbBuilder.putFloat32(z);
+    fbBuilder.putFloat32(y);
+    fbBuilder.putFloat32(x);
+    return fbBuilder.offset;
+  }
+
+}
+
+class Vec3ObjectBuilder extends fb.ObjectBuilder {
+  final double _x;
+  final double _y;
+  final double _z;
+  final double _test1;
+  final Color _test2;
+  final TestObjectBuilder _test3;
+
+  Vec3ObjectBuilder({
+    double x,
+    double y,
+    double z,
+    double test1,
+    Color test2,
+    TestObjectBuilder test3,
+  })
+      : _x = x,
+        _y = y,
+        _z = z,
+        _test1 = test1,
+        _test2 = test2,
+        _test3 = test3;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+
+    fbBuilder.pad(2);
+    _test3.finish(fbBuilder);
+    fbBuilder.pad(1);
+    fbBuilder.putUint8(_test2?.value);
+    fbBuilder.putFloat64(_test1);
+    fbBuilder.pad(4);
+    fbBuilder.putFloat32(_z);
+    fbBuilder.putFloat32(_y);
+    fbBuilder.putFloat32(_x);
+    return fbBuilder.offset;
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
+class Ability {
+  Ability._(this._bc, this._bcOffset);
+
+  static const fb.Reader<Ability> reader = const _AbilityReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  int get id => const fb.Uint32Reader().read(_bc, _bcOffset + 0);
+  int get distance => const fb.Uint32Reader().read(_bc, _bcOffset + 4);
+
+  @override
+  String toString() {
+    return 'Ability{id: $id, distance: $distance}';
+  }
+}
+
+class _AbilityReader extends fb.StructReader<Ability> {
+  const _AbilityReader();
+
+  @override
+  int get size => 8;
+
+  @override
+  Ability createObject(fb.BufferContext bc, int offset) => 
+    new Ability._(bc, offset);
+}
+
+class AbilityBuilder {
+  AbilityBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  int finish(int id, int distance) {
+    fbBuilder.putUint32(distance);
+    fbBuilder.putUint32(id);
+    return fbBuilder.offset;
+  }
+
+}
+
+class AbilityObjectBuilder extends fb.ObjectBuilder {
+  final int _id;
+  final int _distance;
+
+  AbilityObjectBuilder({
+    int id,
+    int distance,
+  })
+      : _id = id,
+        _distance = distance;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+
+    fbBuilder.putUint32(_distance);
+    fbBuilder.putUint32(_id);
+    return fbBuilder.offset;
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
+class Stat {
+  Stat._(this._bc, this._bcOffset);
+  factory Stat(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<Stat> reader = const _StatReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  String get id => const fb.StringReader().vTableGet(_bc, _bcOffset, 4, null);
+  int get val => const fb.Int64Reader().vTableGet(_bc, _bcOffset, 6, 0);
+  int get count => const fb.Uint16Reader().vTableGet(_bc, _bcOffset, 8, 0);
+
+  @override
+  String toString() {
+    return 'Stat{id: $id, val: $val, count: $count}';
+  }
+}
+
+class _StatReader extends fb.TableReader<Stat> {
+  const _StatReader();
+
+  @override
+  Stat createObject(fb.BufferContext bc, int offset) => 
+    new Stat._(bc, offset);
+}
+
+class StatBuilder {
+  StatBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  void begin() {
+    fbBuilder.startTable();
+  }
+
+  int addIdOffset(int offset) {
+    fbBuilder.addOffset(0, offset);
+    return fbBuilder.offset;
+  }
+  int addVal(int val) {
+    fbBuilder.addInt64(1, val);
+    return fbBuilder.offset;
+  }
+  int addCount(int count) {
+    fbBuilder.addUint16(2, count);
+    return fbBuilder.offset;
+  }
+
+  int finish() {
+    return fbBuilder.endTable();
+  }
+}
+
+class StatObjectBuilder extends fb.ObjectBuilder {
+  final String _id;
+  final int _val;
+  final int _count;
+
+  StatObjectBuilder({
+    String id,
+    int val,
+    int count,
+  })
+      : _id = id,
+        _val = val,
+        _count = count;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+    final int idOffset = fbBuilder.writeString(_id);
+
+    fbBuilder.startTable();
+    if (idOffset != null) {
+      fbBuilder.addOffset(0, idOffset);
+    }
+    fbBuilder.addInt64(1, _val);
+    fbBuilder.addUint16(2, _count);
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
+class Referrable {
+  Referrable._(this._bc, this._bcOffset);
+  factory Referrable(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<Referrable> reader = const _ReferrableReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  int get id => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 4, 0);
+
+  @override
+  String toString() {
+    return 'Referrable{id: $id}';
+  }
+}
+
+class _ReferrableReader extends fb.TableReader<Referrable> {
+  const _ReferrableReader();
+
+  @override
+  Referrable createObject(fb.BufferContext bc, int offset) => 
+    new Referrable._(bc, offset);
+}
+
+class ReferrableBuilder {
+  ReferrableBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  void begin() {
+    fbBuilder.startTable();
+  }
+
+  int addId(int id) {
+    fbBuilder.addUint64(0, id);
+    return fbBuilder.offset;
+  }
+
+  int finish() {
+    return fbBuilder.endTable();
+  }
+}
+
+class ReferrableObjectBuilder extends fb.ObjectBuilder {
+  final int _id;
+
+  ReferrableObjectBuilder({
+    int id,
+  })
+      : _id = id;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+
+    fbBuilder.startTable();
+    fbBuilder.addUint64(0, _id);
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
+///  an example documentation comment: monster object
+class Monster {
+  Monster._(this._bc, this._bcOffset);
+  factory Monster(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<Monster> reader = const _MonsterReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  Vec3 get pos => Vec3.reader.vTableGet(_bc, _bcOffset, 4, null);
+  int get mana => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 6, 150);
+  int get hp => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 8, 100);
+  String get name => const fb.StringReader().vTableGet(_bc, _bcOffset, 10, null);
+  List<int> get inventory => const fb.ListReader<int>(const fb.Uint8Reader()).vTableGet(_bc, _bcOffset, 14, null);
+  Color get color => new Color.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 16, 8));
+  AnyTypeId get testType => new AnyTypeId.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 18, 0));
+  dynamic get test {
+    switch (testType?.value) {
+      case 1: return Monster.reader.vTableGet(_bc, _bcOffset, 20, null);
+      case 2: return TestSimpleTableWithEnum.reader.vTableGet(_bc, _bcOffset, 20, null);
+      case 3: return my_game_example2.Monster.reader.vTableGet(_bc, _bcOffset, 20, null);
+      default: return null;
+    }
+  }
+  List<Test> get test4 => const fb.ListReader<Test>(Test.reader).vTableGet(_bc, _bcOffset, 22, null);
+  List<String> get testarrayofstring => const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bc, _bcOffset, 24, null);
+  ///  an example documentation comment: this will end up in the generated code
+  ///  multiline too
+  List<Monster> get testarrayoftables => const fb.ListReader<Monster>(Monster.reader).vTableGet(_bc, _bcOffset, 26, null);
+  Monster get enemy => Monster.reader.vTableGet(_bc, _bcOffset, 28, null);
+  List<int> get testnestedflatbuffer => const fb.ListReader<int>(const fb.Uint8Reader()).vTableGet(_bc, _bcOffset, 30, null);
+  Stat get testempty => Stat.reader.vTableGet(_bc, _bcOffset, 32, null);
+  bool get testbool => const fb.BoolReader().vTableGet(_bc, _bcOffset, 34, false);
+  int get testhashs32Fnv1 => const fb.Int32Reader().vTableGet(_bc, _bcOffset, 36, 0);
+  int get testhashu32Fnv1 => const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 38, 0);
+  int get testhashs64Fnv1 => const fb.Int64Reader().vTableGet(_bc, _bcOffset, 40, 0);
+  int get testhashu64Fnv1 => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 42, 0);
+  int get testhashs32Fnv1a => const fb.Int32Reader().vTableGet(_bc, _bcOffset, 44, 0);
+  int get testhashu32Fnv1a => const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 46, 0);
+  int get testhashs64Fnv1a => const fb.Int64Reader().vTableGet(_bc, _bcOffset, 48, 0);
+  int get testhashu64Fnv1a => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 50, 0);
+  List<bool> get testarrayofbools => const fb.ListReader<bool>(const fb.BoolReader()).vTableGet(_bc, _bcOffset, 52, null);
+  double get testf => const fb.Float32Reader().vTableGet(_bc, _bcOffset, 54, 3.14159);
+  double get testf2 => const fb.Float32Reader().vTableGet(_bc, _bcOffset, 56, 3.0);
+  double get testf3 => const fb.Float32Reader().vTableGet(_bc, _bcOffset, 58, 0.0);
+  List<String> get testarrayofstring2 => const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bc, _bcOffset, 60, null);
+  List<Ability> get testarrayofsortedstruct => const fb.ListReader<Ability>(Ability.reader).vTableGet(_bc, _bcOffset, 62, null);
+  List<int> get flex => const fb.ListReader<int>(const fb.Uint8Reader()).vTableGet(_bc, _bcOffset, 64, null);
+  List<Test> get test5 => const fb.ListReader<Test>(Test.reader).vTableGet(_bc, _bcOffset, 66, null);
+  List<int> get vectorOfLongs => const fb.ListReader<int>(const fb.Int64Reader()).vTableGet(_bc, _bcOffset, 68, null);
+  List<double> get vectorOfDoubles => const fb.ListReader<double>(const fb.Float64Reader()).vTableGet(_bc, _bcOffset, 70, null);
+  my_game.InParentNamespace get parentNamespaceTest => my_game.InParentNamespace.reader.vTableGet(_bc, _bcOffset, 72, null);
+  List<Referrable> get vectorOfReferrables => const fb.ListReader<Referrable>(Referrable.reader).vTableGet(_bc, _bcOffset, 74, null);
+  int get singleWeakReference => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 76, 0);
+  List<int> get vectorOfWeakReferences => const fb.ListReader<int>(const fb.Uint64Reader()).vTableGet(_bc, _bcOffset, 78, null);
+  List<Referrable> get vectorOfStrongReferrables => const fb.ListReader<Referrable>(Referrable.reader).vTableGet(_bc, _bcOffset, 80, null);
+  int get coOwningReference => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 82, 0);
+  List<int> get vectorOfCoOwningReferences => const fb.ListReader<int>(const fb.Uint64Reader()).vTableGet(_bc, _bcOffset, 84, null);
+  int get nonOwningReference => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 86, 0);
+  List<int> get vectorOfNonOwningReferences => const fb.ListReader<int>(const fb.Uint64Reader()).vTableGet(_bc, _bcOffset, 88, null);
+  AnyUniqueAliasesTypeId get anyUniqueType => new AnyUniqueAliasesTypeId.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 90, 0));
+  dynamic get anyUnique {
+    switch (anyUniqueType?.value) {
+      case 1: return M.reader.vTableGet(_bc, _bcOffset, 92, null);
+      case 2: return TS.reader.vTableGet(_bc, _bcOffset, 92, null);
+      case 3: return M2.reader.vTableGet(_bc, _bcOffset, 92, null);
+      default: return null;
+    }
+  }
+  AnyAmbiguousAliasesTypeId get anyAmbiguousType => new AnyAmbiguousAliasesTypeId.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 94, 0));
+  dynamic get anyAmbiguous {
+    switch (anyAmbiguousType?.value) {
+      case 1: return M1.reader.vTableGet(_bc, _bcOffset, 96, null);
+      case 2: return M2.reader.vTableGet(_bc, _bcOffset, 96, null);
+      case 3: return M3.reader.vTableGet(_bc, _bcOffset, 96, null);
+      default: return null;
+    }
+  }
+  List<Color> get vectorOfEnums => const fb.ListReader<Color>(Color.reader).vTableGet(_bc, _bcOffset, 98, null);
+
+  @override
+  String toString() {
+    return 'Monster{pos: $pos, mana: $mana, hp: $hp, name: $name, inventory: $inventory, color: $color, testType: $testType, test: $test, test4: $test4, testarrayofstring: $testarrayofstring, testarrayoftables: $testarrayoftables, enemy: $enemy, testnestedflatbuffer: $testnestedflatbuffer, testempty: $testempty, testbool: $testbool, testhashs32Fnv1: $testhashs32Fnv1, testhashu32Fnv1: $testhashu32Fnv1, testhashs64Fnv1: $testhashs64Fnv1, testhashu64Fnv1: $testhashu64Fnv1, testhashs32Fnv1a: $testhashs32Fnv1a, testhashu32Fnv1a: $testhashu32Fnv1a, testhashs64Fnv1a: $testhashs64Fnv1a, testhashu64Fnv1a: $testhashu64Fnv1a, testarrayofbools: $testarrayofbools, testf: $testf, testf2: $testf2, testf3: $testf3, testarrayofstring2: $testarrayofstring2, testarrayofsortedstruct: $testarrayofsortedstruct, flex: $flex, test5: $test5, vectorOfLongs: $vectorOfLongs, vectorOfDoubles: $vectorOfDoubles, parentNamespaceTest: $parentNamespaceTest, vectorOfReferrables: $vectorOfReferrables, singleWeakReference: $singleWeakReference, vectorOfWeakReferences: $vectorOfWeakReferences, vectorOfStrongReferrables: $vectorOfStrongReferrables, coOwningReference: $coOwningReference, vectorOfCoOwningReferences: $vectorOfCoOwningReferences, nonOwningReference: $nonOwningReference, vectorOfNonOwningReferences: $vectorOfNonOwningReferences, anyUniqueType: $anyUniqueType, anyUnique: $anyUnique, anyAmbiguousType: $anyAmbiguousType, anyAmbiguous: $anyAmbiguous, vectorOfEnums: $vectorOfEnums}';
+  }
+}
+
+class _MonsterReader extends fb.TableReader<Monster> {
+  const _MonsterReader();
+
+  @override
+  Monster createObject(fb.BufferContext bc, int offset) => 
+    new Monster._(bc, offset);
+}
+
+class MonsterBuilder {
+  MonsterBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  void begin() {
+    fbBuilder.startTable();
+  }
+
+  int addPos(int offset) {
+    fbBuilder.addStruct(0, offset);
+    return fbBuilder.offset;
+  }
+  int addMana(int mana) {
+    fbBuilder.addInt16(1, mana);
+    return fbBuilder.offset;
+  }
+  int addHp(int hp) {
+    fbBuilder.addInt16(2, hp);
+    return fbBuilder.offset;
+  }
+  int addNameOffset(int offset) {
+    fbBuilder.addOffset(3, offset);
+    return fbBuilder.offset;
+  }
+  int addInventoryOffset(int offset) {
+    fbBuilder.addOffset(5, offset);
+    return fbBuilder.offset;
+  }
+  int addColor(Color color) {
+    fbBuilder.addUint8(6, color?.value);
+    return fbBuilder.offset;
+  }
+  int addTestType(AnyTypeId testType) {
+    fbBuilder.addUint8(7, testType?.value);
+    return fbBuilder.offset;
+  }
+  int addTestOffset(int offset) {
+    fbBuilder.addOffset(8, offset);
+    return fbBuilder.offset;
+  }
+  int addTest4Offset(int offset) {
+    fbBuilder.addOffset(9, offset);
+    return fbBuilder.offset;
+  }
+  int addTestarrayofstringOffset(int offset) {
+    fbBuilder.addOffset(10, offset);
+    return fbBuilder.offset;
+  }
+  int addTestarrayoftablesOffset(int offset) {
+    fbBuilder.addOffset(11, offset);
+    return fbBuilder.offset;
+  }
+  int addEnemyOffset(int offset) {
+    fbBuilder.addOffset(12, offset);
+    return fbBuilder.offset;
+  }
+  int addTestnestedflatbufferOffset(int offset) {
+    fbBuilder.addOffset(13, offset);
+    return fbBuilder.offset;
+  }
+  int addTestemptyOffset(int offset) {
+    fbBuilder.addOffset(14, offset);
+    return fbBuilder.offset;
+  }
+  int addTestbool(bool testbool) {
+    fbBuilder.addBool(15, testbool);
+    return fbBuilder.offset;
+  }
+  int addTesthashs32Fnv1(int testhashs32Fnv1) {
+    fbBuilder.addInt32(16, testhashs32Fnv1);
+    return fbBuilder.offset;
+  }
+  int addTesthashu32Fnv1(int testhashu32Fnv1) {
+    fbBuilder.addUint32(17, testhashu32Fnv1);
+    return fbBuilder.offset;
+  }
+  int addTesthashs64Fnv1(int testhashs64Fnv1) {
+    fbBuilder.addInt64(18, testhashs64Fnv1);
+    return fbBuilder.offset;
+  }
+  int addTesthashu64Fnv1(int testhashu64Fnv1) {
+    fbBuilder.addUint64(19, testhashu64Fnv1);
+    return fbBuilder.offset;
+  }
+  int addTesthashs32Fnv1a(int testhashs32Fnv1a) {
+    fbBuilder.addInt32(20, testhashs32Fnv1a);
+    return fbBuilder.offset;
+  }
+  int addTesthashu32Fnv1a(int testhashu32Fnv1a) {
+    fbBuilder.addUint32(21, testhashu32Fnv1a);
+    return fbBuilder.offset;
+  }
+  int addTesthashs64Fnv1a(int testhashs64Fnv1a) {
+    fbBuilder.addInt64(22, testhashs64Fnv1a);
+    return fbBuilder.offset;
+  }
+  int addTesthashu64Fnv1a(int testhashu64Fnv1a) {
+    fbBuilder.addUint64(23, testhashu64Fnv1a);
+    return fbBuilder.offset;
+  }
+  int addTestarrayofboolsOffset(int offset) {
+    fbBuilder.addOffset(24, offset);
+    return fbBuilder.offset;
+  }
+  int addTestf(double testf) {
+    fbBuilder.addFloat32(25, testf);
+    return fbBuilder.offset;
+  }
+  int addTestf2(double testf2) {
+    fbBuilder.addFloat32(26, testf2);
+    return fbBuilder.offset;
+  }
+  int addTestf3(double testf3) {
+    fbBuilder.addFloat32(27, testf3);
+    return fbBuilder.offset;
+  }
+  int addTestarrayofstring2Offset(int offset) {
+    fbBuilder.addOffset(28, offset);
+    return fbBuilder.offset;
+  }
+  int addTestarrayofsortedstructOffset(int offset) {
+    fbBuilder.addOffset(29, offset);
+    return fbBuilder.offset;
+  }
+  int addFlexOffset(int offset) {
+    fbBuilder.addOffset(30, offset);
+    return fbBuilder.offset;
+  }
+  int addTest5Offset(int offset) {
+    fbBuilder.addOffset(31, offset);
+    return fbBuilder.offset;
+  }
+  int addVectorOfLongsOffset(int offset) {
+    fbBuilder.addOffset(32, offset);
+    return fbBuilder.offset;
+  }
+  int addVectorOfDoublesOffset(int offset) {
+    fbBuilder.addOffset(33, offset);
+    return fbBuilder.offset;
+  }
+  int addParentNamespaceTestOffset(int offset) {
+    fbBuilder.addOffset(34, offset);
+    return fbBuilder.offset;
+  }
+  int addVectorOfReferrablesOffset(int offset) {
+    fbBuilder.addOffset(35, offset);
+    return fbBuilder.offset;
+  }
+  int addSingleWeakReference(int singleWeakReference) {
+    fbBuilder.addUint64(36, singleWeakReference);
+    return fbBuilder.offset;
+  }
+  int addVectorOfWeakReferencesOffset(int offset) {
+    fbBuilder.addOffset(37, offset);
+    return fbBuilder.offset;
+  }
+  int addVectorOfStrongReferrablesOffset(int offset) {
+    fbBuilder.addOffset(38, offset);
+    return fbBuilder.offset;
+  }
+  int addCoOwningReference(int coOwningReference) {
+    fbBuilder.addUint64(39, coOwningReference);
+    return fbBuilder.offset;
+  }
+  int addVectorOfCoOwningReferencesOffset(int offset) {
+    fbBuilder.addOffset(40, offset);
+    return fbBuilder.offset;
+  }
+  int addNonOwningReference(int nonOwningReference) {
+    fbBuilder.addUint64(41, nonOwningReference);
+    return fbBuilder.offset;
+  }
+  int addVectorOfNonOwningReferencesOffset(int offset) {
+    fbBuilder.addOffset(42, offset);
+    return fbBuilder.offset;
+  }
+  int addAnyUniqueType(AnyUniqueAliasesTypeId anyUniqueType) {
+    fbBuilder.addUint8(43, anyUniqueType?.value);
+    return fbBuilder.offset;
+  }
+  int addAnyUniqueOffset(int offset) {
+    fbBuilder.addOffset(44, offset);
+    return fbBuilder.offset;
+  }
+  int addAnyAmbiguousType(AnyAmbiguousAliasesTypeId anyAmbiguousType) {
+    fbBuilder.addUint8(45, anyAmbiguousType?.value);
+    return fbBuilder.offset;
+  }
+  int addAnyAmbiguousOffset(int offset) {
+    fbBuilder.addOffset(46, offset);
+    return fbBuilder.offset;
+  }
+  int addVectorOfEnumsOffset(int offset) {
+    fbBuilder.addOffset(47, offset);
+    return fbBuilder.offset;
+  }
+
+  int finish() {
+    return fbBuilder.endTable();
+  }
+}
+
+class MonsterObjectBuilder extends fb.ObjectBuilder {
+  final Vec3ObjectBuilder _pos;
+  final int _mana;
+  final int _hp;
+  final String _name;
+  final List<int> _inventory;
+  final Color _color;
+  final AnyTypeId _testType;
+  final dynamic _test;
+  final List<TestObjectBuilder> _test4;
+  final List<String> _testarrayofstring;
+  final List<MonsterObjectBuilder> _testarrayoftables;
+  final MonsterObjectBuilder _enemy;
+  final List<int> _testnestedflatbuffer;
+  final StatObjectBuilder _testempty;
+  final bool _testbool;
+  final int _testhashs32Fnv1;
+  final int _testhashu32Fnv1;
+  final int _testhashs64Fnv1;
+  final int _testhashu64Fnv1;
+  final int _testhashs32Fnv1a;
+  final int _testhashu32Fnv1a;
+  final int _testhashs64Fnv1a;
+  final int _testhashu64Fnv1a;
+  final List<bool> _testarrayofbools;
+  final double _testf;
+  final double _testf2;
+  final double _testf3;
+  final List<String> _testarrayofstring2;
+  final List<AbilityObjectBuilder> _testarrayofsortedstruct;
+  final List<int> _flex;
+  final List<TestObjectBuilder> _test5;
+  final List<int> _vectorOfLongs;
+  final List<double> _vectorOfDoubles;
+  final my_game.InParentNamespaceObjectBuilder _parentNamespaceTest;
+  final List<ReferrableObjectBuilder> _vectorOfReferrables;
+  final int _singleWeakReference;
+  final List<int> _vectorOfWeakReferences;
+  final List<ReferrableObjectBuilder> _vectorOfStrongReferrables;
+  final int _coOwningReference;
+  final List<int> _vectorOfCoOwningReferences;
+  final int _nonOwningReference;
+  final List<int> _vectorOfNonOwningReferences;
+  final AnyUniqueAliasesTypeId _anyUniqueType;
+  final dynamic _anyUnique;
+  final AnyAmbiguousAliasesTypeId _anyAmbiguousType;
+  final dynamic _anyAmbiguous;
+  final List<Color> _vectorOfEnums;
+
+  MonsterObjectBuilder({
+    Vec3ObjectBuilder pos,
+    int mana,
+    int hp,
+    String name,
+    List<int> inventory,
+    Color color,
+    AnyTypeId testType,
+    dynamic test,
+    List<TestObjectBuilder> test4,
+    List<String> testarrayofstring,
+    List<MonsterObjectBuilder> testarrayoftables,
+    MonsterObjectBuilder enemy,
+    List<int> testnestedflatbuffer,
+    StatObjectBuilder testempty,
+    bool testbool,
+    int testhashs32Fnv1,
+    int testhashu32Fnv1,
+    int testhashs64Fnv1,
+    int testhashu64Fnv1,
+    int testhashs32Fnv1a,
+    int testhashu32Fnv1a,
+    int testhashs64Fnv1a,
+    int testhashu64Fnv1a,
+    List<bool> testarrayofbools,
+    double testf,
+    double testf2,
+    double testf3,
+    List<String> testarrayofstring2,
+    List<AbilityObjectBuilder> testarrayofsortedstruct,
+    List<int> flex,
+    List<TestObjectBuilder> test5,
+    List<int> vectorOfLongs,
+    List<double> vectorOfDoubles,
+    my_game.InParentNamespaceObjectBuilder parentNamespaceTest,
+    List<ReferrableObjectBuilder> vectorOfReferrables,
+    int singleWeakReference,
+    List<int> vectorOfWeakReferences,
+    List<ReferrableObjectBuilder> vectorOfStrongReferrables,
+    int coOwningReference,
+    List<int> vectorOfCoOwningReferences,
+    int nonOwningReference,
+    List<int> vectorOfNonOwningReferences,
+    AnyUniqueAliasesTypeId anyUniqueType,
+    dynamic anyUnique,
+    AnyAmbiguousAliasesTypeId anyAmbiguousType,
+    dynamic anyAmbiguous,
+    List<Color> vectorOfEnums,
+  })
+      : _pos = pos,
+        _mana = mana,
+        _hp = hp,
+        _name = name,
+        _inventory = inventory,
+        _color = color,
+        _testType = testType,
+        _test = test,
+        _test4 = test4,
+        _testarrayofstring = testarrayofstring,
+        _testarrayoftables = testarrayoftables,
+        _enemy = enemy,
+        _testnestedflatbuffer = testnestedflatbuffer,
+        _testempty = testempty,
+        _testbool = testbool,
+        _testhashs32Fnv1 = testhashs32Fnv1,
+        _testhashu32Fnv1 = testhashu32Fnv1,
+        _testhashs64Fnv1 = testhashs64Fnv1,
+        _testhashu64Fnv1 = testhashu64Fnv1,
+        _testhashs32Fnv1a = testhashs32Fnv1a,
+        _testhashu32Fnv1a = testhashu32Fnv1a,
+        _testhashs64Fnv1a = testhashs64Fnv1a,
+        _testhashu64Fnv1a = testhashu64Fnv1a,
+        _testarrayofbools = testarrayofbools,
+        _testf = testf,
+        _testf2 = testf2,
+        _testf3 = testf3,
+        _testarrayofstring2 = testarrayofstring2,
+        _testarrayofsortedstruct = testarrayofsortedstruct,
+        _flex = flex,
+        _test5 = test5,
+        _vectorOfLongs = vectorOfLongs,
+        _vectorOfDoubles = vectorOfDoubles,
+        _parentNamespaceTest = parentNamespaceTest,
+        _vectorOfReferrables = vectorOfReferrables,
+        _singleWeakReference = singleWeakReference,
+        _vectorOfWeakReferences = vectorOfWeakReferences,
+        _vectorOfStrongReferrables = vectorOfStrongReferrables,
+        _coOwningReference = coOwningReference,
+        _vectorOfCoOwningReferences = vectorOfCoOwningReferences,
+        _nonOwningReference = nonOwningReference,
+        _vectorOfNonOwningReferences = vectorOfNonOwningReferences,
+        _anyUniqueType = anyUniqueType,
+        _anyUnique = anyUnique,
+        _anyAmbiguousType = anyAmbiguousType,
+        _anyAmbiguous = anyAmbiguous,
+        _vectorOfEnums = vectorOfEnums;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+    final int nameOffset = fbBuilder.writeString(_name);
+    final int inventoryOffset = _inventory?.isNotEmpty == true
+        ? fbBuilder.writeListUint8(_inventory)
+        : null;
+    final int testOffset = _test?.getOrCreateOffset(fbBuilder);
+    final int test4Offset = _test4?.isNotEmpty == true
+        ? fbBuilder.writeListOfStructs(_test4)
+        : null;
+    final int testarrayofstringOffset = _testarrayofstring?.isNotEmpty == true
+        ? fbBuilder.writeList(_testarrayofstring.map((b) => fbBuilder.writeString(b)).toList())
+        : null;
+    final int testarrayoftablesOffset = _testarrayoftables?.isNotEmpty == true
+        ? fbBuilder.writeList(_testarrayoftables.map((b) => b.getOrCreateOffset(fbBuilder)).toList())
+        : null;
+    final int enemyOffset = _enemy?.getOrCreateOffset(fbBuilder);
+    final int testnestedflatbufferOffset = _testnestedflatbuffer?.isNotEmpty == true
+        ? fbBuilder.writeListUint8(_testnestedflatbuffer)
+        : null;
+    final int testemptyOffset = _testempty?.getOrCreateOffset(fbBuilder);
+    final int testarrayofboolsOffset = _testarrayofbools?.isNotEmpty == true
+        ? fbBuilder.writeListBool(_testarrayofbools)
+        : null;
+    final int testarrayofstring2Offset = _testarrayofstring2?.isNotEmpty == true
+        ? fbBuilder.writeList(_testarrayofstring2.map((b) => fbBuilder.writeString(b)).toList())
+        : null;
+    final int testarrayofsortedstructOffset = _testarrayofsortedstruct?.isNotEmpty == true
+        ? fbBuilder.writeListOfStructs(_testarrayofsortedstruct)
+        : null;
+    final int flexOffset = _flex?.isNotEmpty == true
+        ? fbBuilder.writeListUint8(_flex)
+        : null;
+    final int test5Offset = _test5?.isNotEmpty == true
+        ? fbBuilder.writeListOfStructs(_test5)
+        : null;
+    final int vectorOfLongsOffset = _vectorOfLongs?.isNotEmpty == true
+        ? fbBuilder.writeListInt64(_vectorOfLongs)
+        : null;
+    final int vectorOfDoublesOffset = _vectorOfDoubles?.isNotEmpty == true
+        ? fbBuilder.writeListFloat64(_vectorOfDoubles)
+        : null;
+    final int parentNamespaceTestOffset = _parentNamespaceTest?.getOrCreateOffset(fbBuilder);
+    final int vectorOfReferrablesOffset = _vectorOfReferrables?.isNotEmpty == true
+        ? fbBuilder.writeList(_vectorOfReferrables.map((b) => b.getOrCreateOffset(fbBuilder)).toList())
+        : null;
+    final int vectorOfWeakReferencesOffset = _vectorOfWeakReferences?.isNotEmpty == true
+        ? fbBuilder.writeListUint64(_vectorOfWeakReferences)
+        : null;
+    final int vectorOfStrongReferrablesOffset = _vectorOfStrongReferrables?.isNotEmpty == true
+        ? fbBuilder.writeList(_vectorOfStrongReferrables.map((b) => b.getOrCreateOffset(fbBuilder)).toList())
+        : null;
+    final int vectorOfCoOwningReferencesOffset = _vectorOfCoOwningReferences?.isNotEmpty == true
+        ? fbBuilder.writeListUint64(_vectorOfCoOwningReferences)
+        : null;
+    final int vectorOfNonOwningReferencesOffset = _vectorOfNonOwningReferences?.isNotEmpty == true
+        ? fbBuilder.writeListUint64(_vectorOfNonOwningReferences)
+        : null;
+    final int anyUniqueOffset = _anyUnique?.getOrCreateOffset(fbBuilder);
+    final int anyAmbiguousOffset = _anyAmbiguous?.getOrCreateOffset(fbBuilder);
+    final int vectorOfEnumsOffset = _vectorOfEnums?.isNotEmpty == true
+        ? fbBuilder.writeListUint8(_vectorOfEnums.map((f) => f.value))
+        : null;
+
+    fbBuilder.startTable();
+    if (_pos != null) {
+      fbBuilder.addStruct(0, _pos.finish(fbBuilder));
+    }
+    fbBuilder.addInt16(1, _mana);
+    fbBuilder.addInt16(2, _hp);
+    if (nameOffset != null) {
+      fbBuilder.addOffset(3, nameOffset);
+    }
+    if (inventoryOffset != null) {
+      fbBuilder.addOffset(5, inventoryOffset);
+    }
+    fbBuilder.addUint8(6, _color?.value);
+    fbBuilder.addUint8(7, _testType?.value);
+    if (testOffset != null) {
+      fbBuilder.addOffset(8, testOffset);
+    }
+    if (test4Offset != null) {
+      fbBuilder.addOffset(9, test4Offset);
+    }
+    if (testarrayofstringOffset != null) {
+      fbBuilder.addOffset(10, testarrayofstringOffset);
+    }
+    if (testarrayoftablesOffset != null) {
+      fbBuilder.addOffset(11, testarrayoftablesOffset);
+    }
+    if (enemyOffset != null) {
+      fbBuilder.addOffset(12, enemyOffset);
+    }
+    if (testnestedflatbufferOffset != null) {
+      fbBuilder.addOffset(13, testnestedflatbufferOffset);
+    }
+    if (testemptyOffset != null) {
+      fbBuilder.addOffset(14, testemptyOffset);
+    }
+    fbBuilder.addBool(15, _testbool);
+    fbBuilder.addInt32(16, _testhashs32Fnv1);
+    fbBuilder.addUint32(17, _testhashu32Fnv1);
+    fbBuilder.addInt64(18, _testhashs64Fnv1);
+    fbBuilder.addUint64(19, _testhashu64Fnv1);
+    fbBuilder.addInt32(20, _testhashs32Fnv1a);
+    fbBuilder.addUint32(21, _testhashu32Fnv1a);
+    fbBuilder.addInt64(22, _testhashs64Fnv1a);
+    fbBuilder.addUint64(23, _testhashu64Fnv1a);
+    if (testarrayofboolsOffset != null) {
+      fbBuilder.addOffset(24, testarrayofboolsOffset);
+    }
+    fbBuilder.addFloat32(25, _testf);
+    fbBuilder.addFloat32(26, _testf2);
+    fbBuilder.addFloat32(27, _testf3);
+    if (testarrayofstring2Offset != null) {
+      fbBuilder.addOffset(28, testarrayofstring2Offset);
+    }
+    if (testarrayofsortedstructOffset != null) {
+      fbBuilder.addOffset(29, testarrayofsortedstructOffset);
+    }
+    if (flexOffset != null) {
+      fbBuilder.addOffset(30, flexOffset);
+    }
+    if (test5Offset != null) {
+      fbBuilder.addOffset(31, test5Offset);
+    }
+    if (vectorOfLongsOffset != null) {
+      fbBuilder.addOffset(32, vectorOfLongsOffset);
+    }
+    if (vectorOfDoublesOffset != null) {
+      fbBuilder.addOffset(33, vectorOfDoublesOffset);
+    }
+    if (parentNamespaceTestOffset != null) {
+      fbBuilder.addOffset(34, parentNamespaceTestOffset);
+    }
+    if (vectorOfReferrablesOffset != null) {
+      fbBuilder.addOffset(35, vectorOfReferrablesOffset);
+    }
+    fbBuilder.addUint64(36, _singleWeakReference);
+    if (vectorOfWeakReferencesOffset != null) {
+      fbBuilder.addOffset(37, vectorOfWeakReferencesOffset);
+    }
+    if (vectorOfStrongReferrablesOffset != null) {
+      fbBuilder.addOffset(38, vectorOfStrongReferrablesOffset);
+    }
+    fbBuilder.addUint64(39, _coOwningReference);
+    if (vectorOfCoOwningReferencesOffset != null) {
+      fbBuilder.addOffset(40, vectorOfCoOwningReferencesOffset);
+    }
+    fbBuilder.addUint64(41, _nonOwningReference);
+    if (vectorOfNonOwningReferencesOffset != null) {
+      fbBuilder.addOffset(42, vectorOfNonOwningReferencesOffset);
+    }
+    fbBuilder.addUint8(43, _anyUniqueType?.value);
+    if (anyUniqueOffset != null) {
+      fbBuilder.addOffset(44, anyUniqueOffset);
+    }
+    fbBuilder.addUint8(45, _anyAmbiguousType?.value);
+    if (anyAmbiguousOffset != null) {
+      fbBuilder.addOffset(46, anyAmbiguousOffset);
+    }
+    if (vectorOfEnumsOffset != null) {
+      fbBuilder.addOffset(47, vectorOfEnumsOffset);
+    }
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
+class TypeAliases {
+  TypeAliases._(this._bc, this._bcOffset);
+  factory TypeAliases(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<TypeAliases> reader = const _TypeAliasesReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  int get i8 => const fb.Int8Reader().vTableGet(_bc, _bcOffset, 4, 0);
+  int get u8 => const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 6, 0);
+  int get i16 => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 8, 0);
+  int get u16 => const fb.Uint16Reader().vTableGet(_bc, _bcOffset, 10, 0);
+  int get i32 => const fb.Int32Reader().vTableGet(_bc, _bcOffset, 12, 0);
+  int get u32 => const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 14, 0);
+  int get i64 => const fb.Int64Reader().vTableGet(_bc, _bcOffset, 16, 0);
+  int get u64 => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 18, 0);
+  double get f32 => const fb.Float32Reader().vTableGet(_bc, _bcOffset, 20, 0.0);
+  double get f64 => const fb.Float64Reader().vTableGet(_bc, _bcOffset, 22, 0.0);
+  List<int> get v8 => const fb.ListReader<int>(const fb.Int8Reader()).vTableGet(_bc, _bcOffset, 24, null);
+  List<double> get vf64 => const fb.ListReader<double>(const fb.Float64Reader()).vTableGet(_bc, _bcOffset, 26, null);
+
+  @override
+  String toString() {
+    return 'TypeAliases{i8: $i8, u8: $u8, i16: $i16, u16: $u16, i32: $i32, u32: $u32, i64: $i64, u64: $u64, f32: $f32, f64: $f64, v8: $v8, vf64: $vf64}';
+  }
+}
+
+class _TypeAliasesReader extends fb.TableReader<TypeAliases> {
+  const _TypeAliasesReader();
+
+  @override
+  TypeAliases createObject(fb.BufferContext bc, int offset) => 
+    new TypeAliases._(bc, offset);
+}
+
+class TypeAliasesBuilder {
+  TypeAliasesBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  void begin() {
+    fbBuilder.startTable();
+  }
+
+  int addI8(int i8) {
+    fbBuilder.addInt8(0, i8);
+    return fbBuilder.offset;
+  }
+  int addU8(int u8) {
+    fbBuilder.addUint8(1, u8);
+    return fbBuilder.offset;
+  }
+  int addI16(int i16) {
+    fbBuilder.addInt16(2, i16);
+    return fbBuilder.offset;
+  }
+  int addU16(int u16) {
+    fbBuilder.addUint16(3, u16);
+    return fbBuilder.offset;
+  }
+  int addI32(int i32) {
+    fbBuilder.addInt32(4, i32);
+    return fbBuilder.offset;
+  }
+  int addU32(int u32) {
+    fbBuilder.addUint32(5, u32);
+    return fbBuilder.offset;
+  }
+  int addI64(int i64) {
+    fbBuilder.addInt64(6, i64);
+    return fbBuilder.offset;
+  }
+  int addU64(int u64) {
+    fbBuilder.addUint64(7, u64);
+    return fbBuilder.offset;
+  }
+  int addF32(double f32) {
+    fbBuilder.addFloat32(8, f32);
+    return fbBuilder.offset;
+  }
+  int addF64(double f64) {
+    fbBuilder.addFloat64(9, f64);
+    return fbBuilder.offset;
+  }
+  int addV8Offset(int offset) {
+    fbBuilder.addOffset(10, offset);
+    return fbBuilder.offset;
+  }
+  int addVf64Offset(int offset) {
+    fbBuilder.addOffset(11, offset);
+    return fbBuilder.offset;
+  }
+
+  int finish() {
+    return fbBuilder.endTable();
+  }
+}
+
+class TypeAliasesObjectBuilder extends fb.ObjectBuilder {
+  final int _i8;
+  final int _u8;
+  final int _i16;
+  final int _u16;
+  final int _i32;
+  final int _u32;
+  final int _i64;
+  final int _u64;
+  final double _f32;
+  final double _f64;
+  final List<int> _v8;
+  final List<double> _vf64;
+
+  TypeAliasesObjectBuilder({
+    int i8,
+    int u8,
+    int i16,
+    int u16,
+    int i32,
+    int u32,
+    int i64,
+    int u64,
+    double f32,
+    double f64,
+    List<int> v8,
+    List<double> vf64,
+  })
+      : _i8 = i8,
+        _u8 = u8,
+        _i16 = i16,
+        _u16 = u16,
+        _i32 = i32,
+        _u32 = u32,
+        _i64 = i64,
+        _u64 = u64,
+        _f32 = f32,
+        _f64 = f64,
+        _v8 = v8,
+        _vf64 = vf64;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+    final int v8Offset = _v8?.isNotEmpty == true
+        ? fbBuilder.writeListInt8(_v8)
+        : null;
+    final int vf64Offset = _vf64?.isNotEmpty == true
+        ? fbBuilder.writeListFloat64(_vf64)
+        : null;
+
+    fbBuilder.startTable();
+    fbBuilder.addInt8(0, _i8);
+    fbBuilder.addUint8(1, _u8);
+    fbBuilder.addInt16(2, _i16);
+    fbBuilder.addUint16(3, _u16);
+    fbBuilder.addInt32(4, _i32);
+    fbBuilder.addUint32(5, _u32);
+    fbBuilder.addInt64(6, _i64);
+    fbBuilder.addUint64(7, _u64);
+    fbBuilder.addFloat32(8, _f32);
+    fbBuilder.addFloat64(9, _f64);
+    if (v8Offset != null) {
+      fbBuilder.addOffset(10, v8Offset);
+    }
+    if (vf64Offset != null) {
+      fbBuilder.addOffset(11, vf64Offset);
+    }
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
diff --git a/third_party/flatbuffers/tests/monster_test_my_game_generated.dart b/third_party/flatbuffers/tests/monster_test_my_game_generated.dart
new file mode 100644
index 0000000..abd538c
--- /dev/null
+++ b/third_party/flatbuffers/tests/monster_test_my_game_generated.dart
@@ -0,0 +1,60 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+// ignore_for_file: unused_import, unused_field, unused_local_variable
+
+library my_game;
+
+import 'dart:typed_data' show Uint8List;
+import 'package:flat_buffers/flat_buffers.dart' as fb;
+
+import './monster_test_my_game.example_generated.dart' as my_game_example;
+import './monster_test_my_game.example2_generated.dart' as my_game_example2;
+
+class InParentNamespace {
+  InParentNamespace._(this._bc, this._bcOffset);
+  factory InParentNamespace(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<InParentNamespace> reader = const _InParentNamespaceReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+
+  @override
+  String toString() {
+    return 'InParentNamespace{}';
+  }
+}
+
+class _InParentNamespaceReader extends fb.TableReader<InParentNamespace> {
+  const _InParentNamespaceReader();
+
+  @override
+  InParentNamespace createObject(fb.BufferContext bc, int offset) => 
+    new InParentNamespace._(bc, offset);
+}
+
+class InParentNamespaceObjectBuilder extends fb.ObjectBuilder {
+
+  InParentNamespaceObjectBuilder();
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+
+    fbBuilder.startTable();
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
diff --git a/third_party/flatbuffers/tests/monsterdata_extra.json b/third_party/flatbuffers/tests/monsterdata_extra.json
new file mode 100644
index 0000000..53045cd
--- /dev/null
+++ b/third_party/flatbuffers/tests/monsterdata_extra.json
@@ -0,0 +1,15 @@
+{
+  // Initialize with non-default values.
+  d0 : -nan, // match with default
+  d1 : +inf,
+  d2 : -inf,
+  d3:   nan,
+  f0 : +nan, // match with default
+  f1 : -nan, // match with default
+  f2 : +inf, // match with default
+  f3 : -inf, // match with default
+  // Values should have exact binary representation 
+  // to avoid rounding effects in tests.
+  dvec : [2.0, +inf, -inf, nan,],
+  fvec : [1.0, -inf, +inf, nan],
+}
diff --git a/third_party/flatbuffers/tests/monsterdata_python_wire.mon b/third_party/flatbuffers/tests/monsterdata_python_wire.mon
new file mode 100644
index 0000000..2fb956d
--- /dev/null
+++ b/third_party/flatbuffers/tests/monsterdata_python_wire.mon
Binary files differ
diff --git a/third_party/flatbuffers/tests/monsterdata_test.golden b/third_party/flatbuffers/tests/monsterdata_test.golden
new file mode 100644
index 0000000..4bead97
--- /dev/null
+++ b/third_party/flatbuffers/tests/monsterdata_test.golden
@@ -0,0 +1,82 @@
+{
+  pos: {
+    x: 1.0,
+    y: 2.0,
+    z: 3.0,
+    test1: 3.14159265359,
+    test2: "Green",
+    test3: {
+      a: 10,
+      b: 20
+    }
+  },
+  hp: 80,
+  name: "MyMonster",
+  inventory: [
+    0,
+    1,
+    2,
+    3,
+    4,
+    5,
+    6,
+    7,
+    8,
+    9
+  ],
+  test_type: "Monster",
+  test: {
+    name: "Fred"
+  },
+  test4: [
+    {
+      a: 10,
+      b: 20
+    },
+    {
+      a: 30,
+      b: 40
+    }
+  ],
+  testarrayofstring: [
+    "bob",
+    "fred",
+    "bob",
+    "fred"
+  ],
+  testarrayoftables: [
+    {
+      hp: 1000,
+      name: "Barney"
+    },
+    {
+      name: "Fred"
+    },
+    {
+      name: "Wilma"
+    }
+  ],
+  testnestedflatbuffer: {
+    name: "NestedMonster"
+  },
+  testbool: true,
+  testhashs32_fnv1: -579221183,
+  testhashu32_fnv1: 3715746113,
+  testhashs64_fnv1: 7930699090847568257,
+  testhashu64_fnv1: 7930699090847568257,
+  testhashs32_fnv1a: -1904106383,
+  testhashu32_fnv1a: 2390860913,
+  testhashs64_fnv1a: 4898026182817603057,
+  testhashu64_fnv1a: 4898026182817603057,
+  flex: 1234,
+  test5: [
+    {
+      a: 10,
+      b: 20
+    },
+    {
+      a: 30,
+      b: 40
+    }
+  ]
+}
diff --git a/third_party/flatbuffers/tests/monsterdata_test.json b/third_party/flatbuffers/tests/monsterdata_test.json
new file mode 100644
index 0000000..d3028b5
--- /dev/null
+++ b/third_party/flatbuffers/tests/monsterdata_test.json
@@ -0,0 +1,78 @@
+{
+  pos: {
+    x: 1,
+    y: "2",
+    z: 3,
+    test1: 3,
+    test2: Green,
+    test3: {
+      a: 5,
+      b: 6
+    }
+  },
+  hp: 80,
+  name: "MyMonster",
+  inventory: [
+    0,
+    1,
+    2,
+    3,
+    4
+  ],
+  vector_of_longs: [
+      1,
+      100,
+      10000,
+      1000000,
+      100000000
+  ],
+  vector_of_doubles: [
+      -1.7976931348623157e+308,
+      0,
+      1.7976931348623157e+308
+  ],
+  test_type: Monster,
+  test: {
+    name: "Fred",
+    pos: null
+  },
+  test4: [
+    {
+      a: 10,
+      b: 20
+    },
+    {
+      b: "40",
+      a: 30
+    }
+  ],
+  test5: [
+    {
+      a: 10,
+      b: 20
+    },
+    {
+      b: "40",
+      a: 30
+    }
+  ],
+  testarrayofstring: [
+    "test1",
+    "test2"
+  ],
+  enemy: {
+    name: "Fred"
+  },
+  testarrayofbools:[
+    true, false, true
+  ],
+  testbool: true,
+  testhashs32_fnv1: "This string is being hashed!",
+  testhashu32_fnv1: "This string is being hashed!",
+  testhashs64_fnv1: "This string is being hashed!",
+  testhashu64_fnv1: "This string is being hashed!",
+  testhashs32_fnv1a: "This string is being hashed!",
+  testhashu32_fnv1a: "This string is being hashed!",
+  testhashs64_fnv1a: "This string is being hashed!",
+  testhashu64_fnv1a: "This string is being hashed!",
+}
diff --git a/third_party/flatbuffers/tests/monsterdata_test.mon b/third_party/flatbuffers/tests/monsterdata_test.mon
new file mode 100644
index 0000000..ba6cf27
--- /dev/null
+++ b/third_party/flatbuffers/tests/monsterdata_test.mon
Binary files differ
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.cs b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.cs
new file mode 100644
index 0000000..ff44023
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.cs
@@ -0,0 +1,16 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace NamespaceA.NamespaceB
+{
+
+public enum EnumInNestedNS : sbyte
+{
+  A = 0,
+  B = 1,
+  C = 2,
+};
+
+
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.go b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.go
new file mode 100644
index 0000000..6cec5ff
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.go
@@ -0,0 +1,32 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package NamespaceB
+
+import "strconv"
+
+type EnumInNestedNS int8
+
+const (
+	EnumInNestedNSA EnumInNestedNS = 0
+	EnumInNestedNSB EnumInNestedNS = 1
+	EnumInNestedNSC EnumInNestedNS = 2
+)
+
+var EnumNamesEnumInNestedNS = map[EnumInNestedNS]string{
+	EnumInNestedNSA: "A",
+	EnumInNestedNSB: "B",
+	EnumInNestedNSC: "C",
+}
+
+var EnumValuesEnumInNestedNS = map[string]EnumInNestedNS{
+	"A": EnumInNestedNSA,
+	"B": EnumInNestedNSB,
+	"C": EnumInNestedNSC,
+}
+
+func (v EnumInNestedNS) String() string {
+	if s, ok := EnumNamesEnumInNestedNS[v]; ok {
+		return s
+	}
+	return "EnumInNestedNS(" + strconv.FormatInt(int64(v), 10) + ")"
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.java b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.java
new file mode 100644
index 0000000..e23cecc
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.java
@@ -0,0 +1,15 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceA.NamespaceB;
+
+public final class EnumInNestedNS {
+  private EnumInNestedNS() { }
+  public static final byte A = 0;
+  public static final byte B = 1;
+  public static final byte C = 2;
+
+  public static final String[] names = { "A", "B", "C", };
+
+  public static String name(int e) { return names[e]; }
+}
+
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.kt b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.kt
new file mode 100644
index 0000000..0ede58c
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.kt
@@ -0,0 +1,15 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceA.NamespaceB
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class EnumInNestedNS private constructor() {
+    companion object {
+        const val A: Byte = 0
+        const val B: Byte = 1
+        const val C: Byte = 2
+        val names : Array<String> = arrayOf("A", "B", "C")
+        fun name(e: Int) : String = names[e]
+    }
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.lua b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.lua
new file mode 100644
index 0000000..60b1fb1
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.lua
@@ -0,0 +1,11 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: NamespaceB
+
+local EnumInNestedNS = {
+    A = 0,
+    B = 1,
+    C = 2,
+}
+
+return EnumInNestedNS -- return the module
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.php b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.php
new file mode 100644
index 0000000..bcb22b7
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.php
@@ -0,0 +1,25 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace NamespaceA\NamespaceB;
+
+class EnumInNestedNS
+{
+    const A = 0;
+    const B = 1;
+    const C = 2;
+
+    private static $names = array(
+        EnumInNestedNS::A=>"A",
+        EnumInNestedNS::B=>"B",
+        EnumInNestedNS::C=>"C",
+    );
+
+    public static function Name($e)
+    {
+        if (!isset(self::$names[$e])) {
+            throw new \Exception();
+        }
+        return self::$names[$e];
+    }
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.py b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.py
new file mode 100644
index 0000000..cb8218f
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.py
@@ -0,0 +1,9 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: NamespaceB
+
+class EnumInNestedNS(object):
+    A = 0
+    B = 1
+    C = 2
+
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.cs b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.cs
new file mode 100644
index 0000000..9aba8db
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.cs
@@ -0,0 +1,32 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace NamespaceA.NamespaceB
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct StructInNestedNS : IFlatbufferObject
+{
+  private Struct __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
+  public StructInNestedNS __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public int A { get { return __p.bb.GetInt(__p.bb_pos + 0); } }
+  public void MutateA(int a) { __p.bb.PutInt(__p.bb_pos + 0, a); }
+  public int B { get { return __p.bb.GetInt(__p.bb_pos + 4); } }
+  public void MutateB(int b) { __p.bb.PutInt(__p.bb_pos + 4, b); }
+
+  public static Offset<NamespaceA.NamespaceB.StructInNestedNS> CreateStructInNestedNS(FlatBufferBuilder builder, int A, int B) {
+    builder.Prep(4, 8);
+    builder.PutInt(B);
+    builder.PutInt(A);
+    return new Offset<NamespaceA.NamespaceB.StructInNestedNS>(builder.Offset);
+  }
+};
+
+
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.go b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.go
new file mode 100644
index 0000000..e985fbf
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.go
@@ -0,0 +1,41 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package NamespaceB
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+
+type StructInNestedNS struct {
+	_tab flatbuffers.Struct
+}
+
+func (rcv *StructInNestedNS) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *StructInNestedNS) Table() flatbuffers.Table {
+	return rcv._tab.Table
+}
+
+func (rcv *StructInNestedNS) A() int32 {
+	return rcv._tab.GetInt32(rcv._tab.Pos + flatbuffers.UOffsetT(0))
+}
+func (rcv *StructInNestedNS) MutateA(n int32) bool {
+	return rcv._tab.MutateInt32(rcv._tab.Pos+flatbuffers.UOffsetT(0), n)
+}
+
+func (rcv *StructInNestedNS) B() int32 {
+	return rcv._tab.GetInt32(rcv._tab.Pos + flatbuffers.UOffsetT(4))
+}
+func (rcv *StructInNestedNS) MutateB(n int32) bool {
+	return rcv._tab.MutateInt32(rcv._tab.Pos+flatbuffers.UOffsetT(4), n)
+}
+
+func CreateStructInNestedNS(builder *flatbuffers.Builder, a int32, b int32) flatbuffers.UOffsetT {
+	builder.Prep(4, 8)
+	builder.PrependInt32(b)
+	builder.PrependInt32(a)
+	return builder.Offset()
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.java b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.java
new file mode 100644
index 0000000..284f89a
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.java
@@ -0,0 +1,27 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceA.NamespaceB;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class StructInNestedNS extends Struct {
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public StructInNestedNS __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public int a() { return bb.getInt(bb_pos + 0); }
+  public void mutateA(int a) { bb.putInt(bb_pos + 0, a); }
+  public int b() { return bb.getInt(bb_pos + 4); }
+  public void mutateB(int b) { bb.putInt(bb_pos + 4, b); }
+
+  public static int createStructInNestedNS(FlatBufferBuilder builder, int a, int b) {
+    builder.prep(4, 8);
+    builder.putInt(b);
+    builder.putInt(a);
+    return builder.offset();
+  }
+}
+
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.kt b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.kt
new file mode 100644
index 0000000..0273bb1
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.kt
@@ -0,0 +1,32 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceA.NamespaceB
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class StructInNestedNS : Struct() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : StructInNestedNS {
+        __init(_i, _bb)
+        return this
+    }
+    val a : Int get() = bb.getInt(bb_pos + 0)
+    fun mutateA(a: Int) : ByteBuffer = bb.putInt(bb_pos + 0, a)
+    val b : Int get() = bb.getInt(bb_pos + 4)
+    fun mutateB(b: Int) : ByteBuffer = bb.putInt(bb_pos + 4, b)
+    companion object {
+        fun createStructInNestedNS(builder: FlatBufferBuilder, a: Int, b: Int) : Int {
+            builder.prep(4, 8)
+            builder.putInt(b)
+            builder.putInt(a)
+            return builder.offset()
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.lua b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.lua
new file mode 100644
index 0000000..9ca7541
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.lua
@@ -0,0 +1,31 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: NamespaceB
+
+local flatbuffers = require('flatbuffers')
+
+local StructInNestedNS = {} -- the module
+local StructInNestedNS_mt = {} -- the class metatable
+
+function StructInNestedNS.New()
+    local o = {}
+    setmetatable(o, {__index = StructInNestedNS_mt})
+    return o
+end
+function StructInNestedNS_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function StructInNestedNS_mt:A()
+    return self.view:Get(flatbuffers.N.Int32, self.view.pos + 0)
+end
+function StructInNestedNS_mt:B()
+    return self.view:Get(flatbuffers.N.Int32, self.view.pos + 4)
+end
+function StructInNestedNS.CreateStructInNestedNS(builder, a, b)
+    builder:Prep(4, 8)
+    builder:PrependInt32(b)
+    builder:PrependInt32(a)
+    return builder:Offset()
+end
+
+return StructInNestedNS -- return the module
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.php b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.php
new file mode 100644
index 0000000..d305484
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.php
@@ -0,0 +1,52 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace NamespaceA\NamespaceB;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class StructInNestedNS extends Struct
+{
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return StructInNestedNS
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @return int
+     */
+    public function GetA()
+    {
+        return $this->bb->getInt($this->bb_pos + 0);
+    }
+
+    /**
+     * @return int
+     */
+    public function GetB()
+    {
+        return $this->bb->getInt($this->bb_pos + 4);
+    }
+
+
+    /**
+     * @return int offset
+     */
+    public static function createStructInNestedNS(FlatBufferBuilder $builder, $a, $b)
+    {
+        $builder->prep(4, 8);
+        $builder->putInt($b);
+        $builder->putInt($a);
+        return $builder->offset();
+    }
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.py b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.py
new file mode 100644
index 0000000..59cceaa
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.py
@@ -0,0 +1,23 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: NamespaceB
+
+import flatbuffers
+
+class StructInNestedNS(object):
+    __slots__ = ['_tab']
+
+    # StructInNestedNS
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # StructInNestedNS
+    def A(self): return self._tab.Get(flatbuffers.number_types.Int32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(0))
+    # StructInNestedNS
+    def B(self): return self._tab.Get(flatbuffers.number_types.Int32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(4))
+
+def CreateStructInNestedNS(builder, a, b):
+    builder.Prep(4, 8)
+    builder.PrependInt32(b)
+    builder.PrependInt32(a)
+    return builder.Offset()
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.cs b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.cs
new file mode 100644
index 0000000..f8ea32b
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.cs
@@ -0,0 +1,40 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace NamespaceA.NamespaceB
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct TableInNestedNS : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static TableInNestedNS GetRootAsTableInNestedNS(ByteBuffer _bb) { return GetRootAsTableInNestedNS(_bb, new TableInNestedNS()); }
+  public static TableInNestedNS GetRootAsTableInNestedNS(ByteBuffer _bb, TableInNestedNS obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public TableInNestedNS __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public int Foo { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } }
+  public bool MutateFoo(int foo) { int o = __p.__offset(4); if (o != 0) { __p.bb.PutInt(o + __p.bb_pos, foo); return true; } else { return false; } }
+
+  public static Offset<NamespaceA.NamespaceB.TableInNestedNS> CreateTableInNestedNS(FlatBufferBuilder builder,
+      int foo = 0) {
+    builder.StartTable(1);
+    TableInNestedNS.AddFoo(builder, foo);
+    return TableInNestedNS.EndTableInNestedNS(builder);
+  }
+
+  public static void StartTableInNestedNS(FlatBufferBuilder builder) { builder.StartTable(1); }
+  public static void AddFoo(FlatBufferBuilder builder, int foo) { builder.AddInt(0, foo, 0); }
+  public static Offset<NamespaceA.NamespaceB.TableInNestedNS> EndTableInNestedNS(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<NamespaceA.NamespaceB.TableInNestedNS>(o);
+  }
+};
+
+
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.go b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.go
new file mode 100644
index 0000000..75f7a55
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.go
@@ -0,0 +1,49 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package NamespaceB
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+
+type TableInNestedNS struct {
+	_tab flatbuffers.Table
+}
+
+func GetRootAsTableInNestedNS(buf []byte, offset flatbuffers.UOffsetT) *TableInNestedNS {
+	n := flatbuffers.GetUOffsetT(buf[offset:])
+	x := &TableInNestedNS{}
+	x.Init(buf, n+offset)
+	return x
+}
+
+func (rcv *TableInNestedNS) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *TableInNestedNS) Table() flatbuffers.Table {
+	return rcv._tab
+}
+
+func (rcv *TableInNestedNS) Foo() int32 {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+	if o != 0 {
+		return rcv._tab.GetInt32(o + rcv._tab.Pos)
+	}
+	return 0
+}
+
+func (rcv *TableInNestedNS) MutateFoo(n int32) bool {
+	return rcv._tab.MutateInt32Slot(4, n)
+}
+
+func TableInNestedNSStart(builder *flatbuffers.Builder) {
+	builder.StartObject(1)
+}
+func TableInNestedNSAddFoo(builder *flatbuffers.Builder, foo int32) {
+	builder.PrependInt32Slot(0, foo, 0)
+}
+func TableInNestedNSEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+	return builder.EndObject()
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.java b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.java
new file mode 100644
index 0000000..af1449b
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.java
@@ -0,0 +1,35 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceA.NamespaceB;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class TableInNestedNS extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static TableInNestedNS getRootAsTableInNestedNS(ByteBuffer _bb) { return getRootAsTableInNestedNS(_bb, new TableInNestedNS()); }
+  public static TableInNestedNS getRootAsTableInNestedNS(ByteBuffer _bb, TableInNestedNS obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public TableInNestedNS __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public int foo() { int o = __offset(4); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
+  public boolean mutateFoo(int foo) { int o = __offset(4); if (o != 0) { bb.putInt(o + bb_pos, foo); return true; } else { return false; } }
+
+  public static int createTableInNestedNS(FlatBufferBuilder builder,
+      int foo) {
+    builder.startTable(1);
+    TableInNestedNS.addFoo(builder, foo);
+    return TableInNestedNS.endTableInNestedNS(builder);
+  }
+
+  public static void startTableInNestedNS(FlatBufferBuilder builder) { builder.startTable(1); }
+  public static void addFoo(FlatBufferBuilder builder, int foo) { builder.addInt(0, foo, 0); }
+  public static int endTableInNestedNS(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+}
+
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.kt b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.kt
new file mode 100644
index 0000000..59ebdc9
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.kt
@@ -0,0 +1,53 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceA.NamespaceB
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class TableInNestedNS : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : TableInNestedNS {
+        __init(_i, _bb)
+        return this
+    }
+    val foo : Int
+        get() {
+            val o = __offset(4)
+            return if(o != 0) bb.getInt(o + bb_pos) else 0
+        }
+    fun mutateFoo(foo: Int) : Boolean {
+        val o = __offset(4)
+        return if (o != 0) {
+            bb.putInt(o + bb_pos, foo)
+            true
+        } else {
+            false
+        }
+    }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsTableInNestedNS(_bb: ByteBuffer): TableInNestedNS = getRootAsTableInNestedNS(_bb, TableInNestedNS())
+        fun getRootAsTableInNestedNS(_bb: ByteBuffer, obj: TableInNestedNS): TableInNestedNS {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun createTableInNestedNS(builder: FlatBufferBuilder, foo: Int) : Int {
+            builder.startTable(1)
+            addFoo(builder, foo)
+            return endTableInNestedNS(builder)
+        }
+        fun startTableInNestedNS(builder: FlatBufferBuilder) = builder.startTable(1)
+        fun addFoo(builder: FlatBufferBuilder, foo: Int) = builder.addInt(0, foo, 0)
+        fun endTableInNestedNS(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+            return o
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.lua b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.lua
new file mode 100644
index 0000000..dd45e58
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.lua
@@ -0,0 +1,35 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: NamespaceB
+
+local flatbuffers = require('flatbuffers')
+
+local TableInNestedNS = {} -- the module
+local TableInNestedNS_mt = {} -- the class metatable
+
+function TableInNestedNS.New()
+    local o = {}
+    setmetatable(o, {__index = TableInNestedNS_mt})
+    return o
+end
+function TableInNestedNS.GetRootAsTableInNestedNS(buf, offset)
+    local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)
+    local o = TableInNestedNS.New()
+    o:Init(buf, n + offset)
+    return o
+end
+function TableInNestedNS_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function TableInNestedNS_mt:Foo()
+    local o = self.view:Offset(4)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int32, o + self.view.pos)
+    end
+    return 0
+end
+function TableInNestedNS.Start(builder) builder:StartObject(1) end
+function TableInNestedNS.AddFoo(builder, foo) builder:PrependInt32Slot(0, foo, 0) end
+function TableInNestedNS.End(builder) return builder:EndObject() end
+
+return TableInNestedNS -- return the module
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.php b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.php
new file mode 100644
index 0000000..d16379d
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.php
@@ -0,0 +1,84 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace NamespaceA\NamespaceB;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class TableInNestedNS extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return TableInNestedNS
+     */
+    public static function getRootAsTableInNestedNS(ByteBuffer $bb)
+    {
+        $obj = new TableInNestedNS();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return TableInNestedNS
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @return int
+     */
+    public function getFoo()
+    {
+        $o = $this->__offset(4);
+        return $o != 0 ? $this->bb->getInt($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startTableInNestedNS(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(1);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return TableInNestedNS
+     */
+    public static function createTableInNestedNS(FlatBufferBuilder $builder, $foo)
+    {
+        $builder->startObject(1);
+        self::addFoo($builder, $foo);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addFoo(FlatBufferBuilder $builder, $foo)
+    {
+        $builder->addIntX(0, $foo, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endTableInNestedNS(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.py b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.py
new file mode 100644
index 0000000..d6d1674
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.py
@@ -0,0 +1,30 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: NamespaceB
+
+import flatbuffers
+
+class TableInNestedNS(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAsTableInNestedNS(cls, buf, offset):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = TableInNestedNS()
+        x.Init(buf, n + offset)
+        return x
+
+    # TableInNestedNS
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # TableInNestedNS
+    def Foo(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
+        return 0
+
+def TableInNestedNSStart(builder): builder.StartObject(1)
+def TableInNestedNSAddFoo(builder, foo): builder.PrependInt32Slot(0, foo, 0)
+def TableInNestedNSEnd(builder): return builder.EndObject()
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/__init__.py b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/NamespaceB/__init__.py
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/SecondTableInA.cs b/third_party/flatbuffers/tests/namespace_test/NamespaceA/SecondTableInA.cs
new file mode 100644
index 0000000..7e08de8
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/SecondTableInA.cs
@@ -0,0 +1,39 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace NamespaceA
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct SecondTableInA : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static SecondTableInA GetRootAsSecondTableInA(ByteBuffer _bb) { return GetRootAsSecondTableInA(_bb, new SecondTableInA()); }
+  public static SecondTableInA GetRootAsSecondTableInA(ByteBuffer _bb, SecondTableInA obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public SecondTableInA __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public NamespaceC.TableInC? ReferToC { get { int o = __p.__offset(4); return o != 0 ? (NamespaceC.TableInC?)(new NamespaceC.TableInC()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
+
+  public static Offset<NamespaceA.SecondTableInA> CreateSecondTableInA(FlatBufferBuilder builder,
+      Offset<NamespaceC.TableInC> refer_to_cOffset = default(Offset<NamespaceC.TableInC>)) {
+    builder.StartTable(1);
+    SecondTableInA.AddReferToC(builder, refer_to_cOffset);
+    return SecondTableInA.EndSecondTableInA(builder);
+  }
+
+  public static void StartSecondTableInA(FlatBufferBuilder builder) { builder.StartTable(1); }
+  public static void AddReferToC(FlatBufferBuilder builder, Offset<NamespaceC.TableInC> referToCOffset) { builder.AddOffset(0, referToCOffset.Value, 0); }
+  public static Offset<NamespaceA.SecondTableInA> EndSecondTableInA(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<NamespaceA.SecondTableInA>(o);
+  }
+};
+
+
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/SecondTableInA.go b/third_party/flatbuffers/tests/namespace_test/NamespaceA/SecondTableInA.go
new file mode 100644
index 0000000..6dd1eef
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/SecondTableInA.go
@@ -0,0 +1,52 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package NamespaceA
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+
+	NamespaceC "NamespaceC"
+)
+
+type SecondTableInA struct {
+	_tab flatbuffers.Table
+}
+
+func GetRootAsSecondTableInA(buf []byte, offset flatbuffers.UOffsetT) *SecondTableInA {
+	n := flatbuffers.GetUOffsetT(buf[offset:])
+	x := &SecondTableInA{}
+	x.Init(buf, n+offset)
+	return x
+}
+
+func (rcv *SecondTableInA) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *SecondTableInA) Table() flatbuffers.Table {
+	return rcv._tab
+}
+
+func (rcv *SecondTableInA) ReferToC(obj *NamespaceC.TableInC) *NamespaceC.TableInC {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+	if o != 0 {
+		x := rcv._tab.Indirect(o + rcv._tab.Pos)
+		if obj == nil {
+			obj = new(NamespaceC.TableInC)
+		}
+		obj.Init(rcv._tab.Bytes, x)
+		return obj
+	}
+	return nil
+}
+
+func SecondTableInAStart(builder *flatbuffers.Builder) {
+	builder.StartObject(1)
+}
+func SecondTableInAAddReferToC(builder *flatbuffers.Builder, referToC flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(referToC), 0)
+}
+func SecondTableInAEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+	return builder.EndObject()
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/SecondTableInA.java b/third_party/flatbuffers/tests/namespace_test/NamespaceA/SecondTableInA.java
new file mode 100644
index 0000000..a655199
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/SecondTableInA.java
@@ -0,0 +1,35 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceA;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class SecondTableInA extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static SecondTableInA getRootAsSecondTableInA(ByteBuffer _bb) { return getRootAsSecondTableInA(_bb, new SecondTableInA()); }
+  public static SecondTableInA getRootAsSecondTableInA(ByteBuffer _bb, SecondTableInA obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public SecondTableInA __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public NamespaceC.TableInC referToC() { return referToC(new NamespaceC.TableInC()); }
+  public NamespaceC.TableInC referToC(NamespaceC.TableInC obj) { int o = __offset(4); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
+
+  public static int createSecondTableInA(FlatBufferBuilder builder,
+      int refer_to_cOffset) {
+    builder.startTable(1);
+    SecondTableInA.addReferToC(builder, refer_to_cOffset);
+    return SecondTableInA.endSecondTableInA(builder);
+  }
+
+  public static void startSecondTableInA(FlatBufferBuilder builder) { builder.startTable(1); }
+  public static void addReferToC(FlatBufferBuilder builder, int referToCOffset) { builder.addOffset(0, referToCOffset, 0); }
+  public static int endSecondTableInA(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+}
+
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/SecondTableInA.kt b/third_party/flatbuffers/tests/namespace_test/NamespaceA/SecondTableInA.kt
new file mode 100644
index 0000000..8261443
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/SecondTableInA.kt
@@ -0,0 +1,48 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceA
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class SecondTableInA : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : SecondTableInA {
+        __init(_i, _bb)
+        return this
+    }
+    val referToC : NamespaceC.TableInC? get() = referToC(NamespaceC.TableInC())
+    fun referToC(obj: NamespaceC.TableInC) : NamespaceC.TableInC? {
+        val o = __offset(4)
+        return if (o != 0) {
+            obj.__assign(__indirect(o + bb_pos), bb)
+        } else {
+            null
+        }
+    }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsSecondTableInA(_bb: ByteBuffer): SecondTableInA = getRootAsSecondTableInA(_bb, SecondTableInA())
+        fun getRootAsSecondTableInA(_bb: ByteBuffer, obj: SecondTableInA): SecondTableInA {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun createSecondTableInA(builder: FlatBufferBuilder, referToCOffset: Int) : Int {
+            builder.startTable(1)
+            addReferToC(builder, referToCOffset)
+            return endSecondTableInA(builder)
+        }
+        fun startSecondTableInA(builder: FlatBufferBuilder) = builder.startTable(1)
+        fun addReferToC(builder: FlatBufferBuilder, referToC: Int) = builder.addOffset(0, referToC, 0)
+        fun endSecondTableInA(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+            return o
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/SecondTableInA.lua b/third_party/flatbuffers/tests/namespace_test/NamespaceA/SecondTableInA.lua
new file mode 100644
index 0000000..9a60e4b
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/SecondTableInA.lua
@@ -0,0 +1,37 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: NamespaceA
+
+local flatbuffers = require('flatbuffers')
+
+local SecondTableInA = {} -- the module
+local SecondTableInA_mt = {} -- the class metatable
+
+function SecondTableInA.New()
+    local o = {}
+    setmetatable(o, {__index = SecondTableInA_mt})
+    return o
+end
+function SecondTableInA.GetRootAsSecondTableInA(buf, offset)
+    local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)
+    local o = SecondTableInA.New()
+    o:Init(buf, n + offset)
+    return o
+end
+function SecondTableInA_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function SecondTableInA_mt:ReferToC()
+    local o = self.view:Offset(4)
+    if o ~= 0 then
+        local x = self.view:Indirect(o + self.view.pos)
+        local obj = require('NamespaceC.TableInC').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function SecondTableInA.Start(builder) builder:StartObject(1) end
+function SecondTableInA.AddReferToC(builder, referToC) builder:PrependUOffsetTRelativeSlot(0, referToC, 0) end
+function SecondTableInA.End(builder) return builder:EndObject() end
+
+return SecondTableInA -- return the module
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/SecondTableInA.php b/third_party/flatbuffers/tests/namespace_test/NamespaceA/SecondTableInA.php
new file mode 100644
index 0000000..c9bc65c
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/SecondTableInA.php
@@ -0,0 +1,82 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace NamespaceA;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class SecondTableInA extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return SecondTableInA
+     */
+    public static function getRootAsSecondTableInA(ByteBuffer $bb)
+    {
+        $obj = new SecondTableInA();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return SecondTableInA
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    public function getReferToC()
+    {
+        $obj = new TableInC();
+        $o = $this->__offset(4);
+        return $o != 0 ? $obj->init($this->__indirect($o + $this->bb_pos), $this->bb) : 0;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startSecondTableInA(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(1);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return SecondTableInA
+     */
+    public static function createSecondTableInA(FlatBufferBuilder $builder, $refer_to_c)
+    {
+        $builder->startObject(1);
+        self::addReferToC($builder, $refer_to_c);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addReferToC(FlatBufferBuilder $builder, $referToC)
+    {
+        $builder->addOffsetX(0, $referToC, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endSecondTableInA(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/SecondTableInA.py b/third_party/flatbuffers/tests/namespace_test/NamespaceA/SecondTableInA.py
new file mode 100644
index 0000000..20dac3e
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/SecondTableInA.py
@@ -0,0 +1,34 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: NamespaceA
+
+import flatbuffers
+
+class SecondTableInA(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAsSecondTableInA(cls, buf, offset):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = SecondTableInA()
+        x.Init(buf, n + offset)
+        return x
+
+    # SecondTableInA
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # SecondTableInA
+    def ReferToC(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        if o != 0:
+            x = self._tab.Indirect(o + self._tab.Pos)
+            from .TableInC import TableInC
+            obj = TableInC()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+def SecondTableInAStart(builder): builder.StartObject(1)
+def SecondTableInAAddReferToC(builder, referToC): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(referToC), 0)
+def SecondTableInAEnd(builder): return builder.EndObject()
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInC.cs b/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInC.cs
new file mode 100644
index 0000000..98f4e13
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInC.cs
@@ -0,0 +1,38 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace NamespaceA
+{
+
+using System;
+using FlatBuffers;
+
+public sealed class TableInC : Table {
+  public static TableInC GetRootAsTableInC(ByteBuffer _bb) { return GetRootAsTableInC(_bb, new TableInC()); }
+  public static TableInC GetRootAsTableInC(ByteBuffer _bb, TableInC obj) { return (obj.__init(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public TableInC __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
+
+  public NamespaceA.TableInFirstNS ReferToA1 { get { return GetReferToA1(new NamespaceA.TableInFirstNS()); } }
+  public NamespaceA.TableInFirstNS GetReferToA1(NamespaceA.TableInFirstNS obj) { int o = __offset(4); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }
+  public SecondTableInA ReferToA2 { get { return GetReferToA2(new SecondTableInA()); } }
+  public SecondTableInA GetReferToA2(SecondTableInA obj) { int o = __offset(6); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }
+
+  public static Offset<NamespaceC.TableInC> CreateTableInC(FlatBufferBuilder builder,
+      Offset<NamespaceA.TableInFirstNS> refer_to_a1Offset = default(Offset<NamespaceA.TableInFirstNS>),
+      Offset<SecondTableInA> refer_to_a2Offset = default(Offset<SecondTableInA>)) {
+    builder.StartObject(2);
+    TableInC.AddReferToA2(builder, refer_to_a2Offset);
+    TableInC.AddReferToA1(builder, refer_to_a1Offset);
+    return TableInC.EndTableInC(builder);
+  }
+
+  public static void StartTableInC(FlatBufferBuilder builder) { builder.StartObject(2); }
+  public static void AddReferToA1(FlatBufferBuilder builder, Offset<NamespaceA.TableInFirstNS> referToA1Offset) { builder.AddOffset(0, referToA1Offset.Value, 0); }
+  public static void AddReferToA2(FlatBufferBuilder builder, Offset<SecondTableInA> referToA2Offset) { builder.AddOffset(1, referToA2Offset.Value, 0); }
+  public static Offset<NamespaceC.TableInC> EndTableInC(FlatBufferBuilder builder) {
+    int o = builder.EndObject();
+    return new Offset<NamespaceC.TableInC>(o);
+  }
+};
+
+
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInC.go b/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInC.go
new file mode 100644
index 0000000..6f3d3f2
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInC.go
@@ -0,0 +1,46 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceA
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+type TableInC struct {
+	_tab flatbuffers.Table
+}
+
+func (rcv *TableInC) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *TableInC) ReferToA1(obj *TableInFirstNS) *TableInFirstNS {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+	if o != 0 {
+		x := rcv._tab.Indirect(o + rcv._tab.Pos)
+		if obj == nil {
+			obj = new(TableInFirstNS)
+		}
+		obj.Init(rcv._tab.Bytes, x)
+		return obj
+	}
+	return nil
+}
+
+func (rcv *TableInC) ReferToA2(obj *SecondTableInA) *SecondTableInA {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
+	if o != 0 {
+		x := rcv._tab.Indirect(o + rcv._tab.Pos)
+		if obj == nil {
+			obj = new(SecondTableInA)
+		}
+		obj.Init(rcv._tab.Bytes, x)
+		return obj
+	}
+	return nil
+}
+
+func TableInCStart(builder *flatbuffers.Builder) { builder.StartObject(2) }
+func TableInCAddReferToA1(builder *flatbuffers.Builder, referToA1 flatbuffers.UOffsetT) { builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(referToA1), 0) }
+func TableInCAddReferToA2(builder *flatbuffers.Builder, referToA2 flatbuffers.UOffsetT) { builder.PrependUOffsetTSlot(1, flatbuffers.UOffsetT(referToA2), 0) }
+func TableInCEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT { return builder.EndObject() }
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInC.php b/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInC.php
new file mode 100644
index 0000000..49705f8
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInC.php
@@ -0,0 +1,100 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace NamespaceA;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class TableInC extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return TableInC
+     */
+    public static function getRootAsTableInC(ByteBuffer $bb)
+    {
+        $obj = new TableInC();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return TableInC
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    public function getReferToA1()
+    {
+        $obj = new TableInFirstNS();
+        $o = $this->__offset(4);
+        return $o != 0 ? $obj->init($this->__indirect($o + $this->bb_pos), $this->bb) : 0;
+    }
+
+    public function getReferToA2()
+    {
+        $obj = new SecondTableInA();
+        $o = $this->__offset(6);
+        return $o != 0 ? $obj->init($this->__indirect($o + $this->bb_pos), $this->bb) : 0;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startTableInC(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(2);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return TableInC
+     */
+    public static function createTableInC(FlatBufferBuilder $builder, $refer_to_a1, $refer_to_a2)
+    {
+        $builder->startObject(2);
+        self::addReferToA1($builder, $refer_to_a1);
+        self::addReferToA2($builder, $refer_to_a2);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addReferToA1(FlatBufferBuilder $builder, $referToA1)
+    {
+        $builder->addOffsetX(0, $referToA1, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addReferToA2(FlatBufferBuilder $builder, $referToA2)
+    {
+        $builder->addOffsetX(1, $referToA2, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endTableInC(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInC.py b/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInC.py
new file mode 100644
index 0000000..4afea1a
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInC.py
@@ -0,0 +1,39 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: NamespaceA
+
+import flatbuffers
+
+class TableInC(object):
+    __slots__ = ['_tab']
+
+    # TableInC
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # TableInC
+    def ReferToA1(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        if o != 0:
+            x = self._tab.Indirect(o + self._tab.Pos)
+            from .TableInFirstNS import TableInFirstNS
+            obj = TableInFirstNS()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+    # TableInC
+    def ReferToA2(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
+        if o != 0:
+            x = self._tab.Indirect(o + self._tab.Pos)
+            from .SecondTableInA import SecondTableInA
+            obj = SecondTableInA()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+def TableInCStart(builder): builder.StartObject(2)
+def TableInCAddReferToA1(builder, referToA1): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(referToA1), 0)
+def TableInCAddReferToA2(builder, referToA2): builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(referToA2), 0)
+def TableInCEnd(builder): return builder.EndObject()
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInFirstNS.cs b/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInFirstNS.cs
new file mode 100644
index 0000000..d0d8ed0
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInFirstNS.cs
@@ -0,0 +1,37 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace NamespaceA
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct TableInFirstNS : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static TableInFirstNS GetRootAsTableInFirstNS(ByteBuffer _bb) { return GetRootAsTableInFirstNS(_bb, new TableInFirstNS()); }
+  public static TableInFirstNS GetRootAsTableInFirstNS(ByteBuffer _bb, TableInFirstNS obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public TableInFirstNS __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public NamespaceA.NamespaceB.TableInNestedNS? FooTable { get { int o = __p.__offset(4); return o != 0 ? (NamespaceA.NamespaceB.TableInNestedNS?)(new NamespaceA.NamespaceB.TableInNestedNS()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
+  public NamespaceA.NamespaceB.EnumInNestedNS FooEnum { get { int o = __p.__offset(6); return o != 0 ? (NamespaceA.NamespaceB.EnumInNestedNS)__p.bb.GetSbyte(o + __p.bb_pos) : NamespaceA.NamespaceB.EnumInNestedNS.A; } }
+  public bool MutateFooEnum(NamespaceA.NamespaceB.EnumInNestedNS foo_enum) { int o = __p.__offset(6); if (o != 0) { __p.bb.PutSbyte(o + __p.bb_pos, (sbyte)foo_enum); return true; } else { return false; } }
+  public NamespaceA.NamespaceB.StructInNestedNS? FooStruct { get { int o = __p.__offset(8); return o != 0 ? (NamespaceA.NamespaceB.StructInNestedNS?)(new NamespaceA.NamespaceB.StructInNestedNS()).__assign(o + __p.bb_pos, __p.bb) : null; } }
+
+  public static void StartTableInFirstNS(FlatBufferBuilder builder) { builder.StartTable(3); }
+  public static void AddFooTable(FlatBufferBuilder builder, Offset<NamespaceA.NamespaceB.TableInNestedNS> fooTableOffset) { builder.AddOffset(0, fooTableOffset.Value, 0); }
+  public static void AddFooEnum(FlatBufferBuilder builder, NamespaceA.NamespaceB.EnumInNestedNS fooEnum) { builder.AddSbyte(1, (sbyte)fooEnum, 0); }
+  public static void AddFooStruct(FlatBufferBuilder builder, Offset<NamespaceA.NamespaceB.StructInNestedNS> fooStructOffset) { builder.AddStruct(2, fooStructOffset.Value, 0); }
+  public static Offset<NamespaceA.TableInFirstNS> EndTableInFirstNS(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<NamespaceA.TableInFirstNS>(o);
+  }
+};
+
+
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInFirstNS.go b/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInFirstNS.go
new file mode 100644
index 0000000..bbcbdc6
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInFirstNS.go
@@ -0,0 +1,83 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package NamespaceA
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+
+	NamespaceA__NamespaceB "NamespaceA/NamespaceB"
+)
+
+type TableInFirstNS struct {
+	_tab flatbuffers.Table
+}
+
+func GetRootAsTableInFirstNS(buf []byte, offset flatbuffers.UOffsetT) *TableInFirstNS {
+	n := flatbuffers.GetUOffsetT(buf[offset:])
+	x := &TableInFirstNS{}
+	x.Init(buf, n+offset)
+	return x
+}
+
+func (rcv *TableInFirstNS) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *TableInFirstNS) Table() flatbuffers.Table {
+	return rcv._tab
+}
+
+func (rcv *TableInFirstNS) FooTable(obj *NamespaceA__NamespaceB.TableInNestedNS) *NamespaceA__NamespaceB.TableInNestedNS {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+	if o != 0 {
+		x := rcv._tab.Indirect(o + rcv._tab.Pos)
+		if obj == nil {
+			obj = new(NamespaceA__NamespaceB.TableInNestedNS)
+		}
+		obj.Init(rcv._tab.Bytes, x)
+		return obj
+	}
+	return nil
+}
+
+func (rcv *TableInFirstNS) FooEnum() NamespaceA__NamespaceB.EnumInNestedNS {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
+	if o != 0 {
+		return NamespaceA__NamespaceB.EnumInNestedNS(rcv._tab.GetInt8(o + rcv._tab.Pos))
+	}
+	return 0
+}
+
+func (rcv *TableInFirstNS) MutateFooEnum(n NamespaceA__NamespaceB.EnumInNestedNS) bool {
+	return rcv._tab.MutateInt8Slot(6, int8(n))
+}
+
+func (rcv *TableInFirstNS) FooStruct(obj *NamespaceA__NamespaceB.StructInNestedNS) *NamespaceA__NamespaceB.StructInNestedNS {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
+	if o != 0 {
+		x := o + rcv._tab.Pos
+		if obj == nil {
+			obj = new(NamespaceA__NamespaceB.StructInNestedNS)
+		}
+		obj.Init(rcv._tab.Bytes, x)
+		return obj
+	}
+	return nil
+}
+
+func TableInFirstNSStart(builder *flatbuffers.Builder) {
+	builder.StartObject(3)
+}
+func TableInFirstNSAddFooTable(builder *flatbuffers.Builder, fooTable flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(fooTable), 0)
+}
+func TableInFirstNSAddFooEnum(builder *flatbuffers.Builder, fooEnum NamespaceA__NamespaceB.EnumInNestedNS) {
+	builder.PrependInt8Slot(1, int8(fooEnum), 0)
+}
+func TableInFirstNSAddFooStruct(builder *flatbuffers.Builder, fooStruct flatbuffers.UOffsetT) {
+	builder.PrependStructSlot(2, flatbuffers.UOffsetT(fooStruct), 0)
+}
+func TableInFirstNSEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+	return builder.EndObject()
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInFirstNS.java b/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInFirstNS.java
new file mode 100644
index 0000000..e097381
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInFirstNS.java
@@ -0,0 +1,34 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceA;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class TableInFirstNS extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static TableInFirstNS getRootAsTableInFirstNS(ByteBuffer _bb) { return getRootAsTableInFirstNS(_bb, new TableInFirstNS()); }
+  public static TableInFirstNS getRootAsTableInFirstNS(ByteBuffer _bb, TableInFirstNS obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public TableInFirstNS __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public NamespaceA.NamespaceB.TableInNestedNS fooTable() { return fooTable(new NamespaceA.NamespaceB.TableInNestedNS()); }
+  public NamespaceA.NamespaceB.TableInNestedNS fooTable(NamespaceA.NamespaceB.TableInNestedNS obj) { int o = __offset(4); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
+  public byte fooEnum() { int o = __offset(6); return o != 0 ? bb.get(o + bb_pos) : 0; }
+  public boolean mutateFooEnum(byte foo_enum) { int o = __offset(6); if (o != 0) { bb.put(o + bb_pos, foo_enum); return true; } else { return false; } }
+  public NamespaceA.NamespaceB.StructInNestedNS fooStruct() { return fooStruct(new NamespaceA.NamespaceB.StructInNestedNS()); }
+  public NamespaceA.NamespaceB.StructInNestedNS fooStruct(NamespaceA.NamespaceB.StructInNestedNS obj) { int o = __offset(8); return o != 0 ? obj.__assign(o + bb_pos, bb) : null; }
+
+  public static void startTableInFirstNS(FlatBufferBuilder builder) { builder.startTable(3); }
+  public static void addFooTable(FlatBufferBuilder builder, int fooTableOffset) { builder.addOffset(0, fooTableOffset, 0); }
+  public static void addFooEnum(FlatBufferBuilder builder, byte fooEnum) { builder.addByte(1, fooEnum, 0); }
+  public static void addFooStruct(FlatBufferBuilder builder, int fooStructOffset) { builder.addStruct(2, fooStructOffset, 0); }
+  public static int endTableInFirstNS(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+}
+
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInFirstNS.kt b/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInFirstNS.kt
new file mode 100644
index 0000000..1ba0afc
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInFirstNS.kt
@@ -0,0 +1,68 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceA
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class TableInFirstNS : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : TableInFirstNS {
+        __init(_i, _bb)
+        return this
+    }
+    val fooTable : NamespaceA.NamespaceB.TableInNestedNS? get() = fooTable(NamespaceA.NamespaceB.TableInNestedNS())
+    fun fooTable(obj: NamespaceA.NamespaceB.TableInNestedNS) : NamespaceA.NamespaceB.TableInNestedNS? {
+        val o = __offset(4)
+        return if (o != 0) {
+            obj.__assign(__indirect(o + bb_pos), bb)
+        } else {
+            null
+        }
+    }
+    val fooEnum : Byte
+        get() {
+            val o = __offset(6)
+            return if(o != 0) bb.get(o + bb_pos) else 0
+        }
+    fun mutateFooEnum(fooEnum: Byte) : Boolean {
+        val o = __offset(6)
+        return if (o != 0) {
+            bb.put(o + bb_pos, fooEnum)
+            true
+        } else {
+            false
+        }
+    }
+    val fooStruct : NamespaceA.NamespaceB.StructInNestedNS? get() = fooStruct(NamespaceA.NamespaceB.StructInNestedNS())
+    fun fooStruct(obj: NamespaceA.NamespaceB.StructInNestedNS) : NamespaceA.NamespaceB.StructInNestedNS? {
+        val o = __offset(8)
+        return if (o != 0) {
+            obj.__assign(o + bb_pos, bb)
+        } else {
+            null
+        }
+    }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsTableInFirstNS(_bb: ByteBuffer): TableInFirstNS = getRootAsTableInFirstNS(_bb, TableInFirstNS())
+        fun getRootAsTableInFirstNS(_bb: ByteBuffer, obj: TableInFirstNS): TableInFirstNS {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun startTableInFirstNS(builder: FlatBufferBuilder) = builder.startTable(3)
+        fun addFooTable(builder: FlatBufferBuilder, fooTable: Int) = builder.addOffset(0, fooTable, 0)
+        fun addFooEnum(builder: FlatBufferBuilder, fooEnum: Byte) = builder.addByte(1, fooEnum, 0)
+        fun addFooStruct(builder: FlatBufferBuilder, fooStruct: Int) = builder.addStruct(2, fooStruct, 0)
+        fun endTableInFirstNS(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+            return o
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInFirstNS.lua b/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInFirstNS.lua
new file mode 100644
index 0000000..f70f2c7
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInFirstNS.lua
@@ -0,0 +1,55 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: NamespaceA
+
+local flatbuffers = require('flatbuffers')
+
+local TableInFirstNS = {} -- the module
+local TableInFirstNS_mt = {} -- the class metatable
+
+function TableInFirstNS.New()
+    local o = {}
+    setmetatable(o, {__index = TableInFirstNS_mt})
+    return o
+end
+function TableInFirstNS.GetRootAsTableInFirstNS(buf, offset)
+    local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)
+    local o = TableInFirstNS.New()
+    o:Init(buf, n + offset)
+    return o
+end
+function TableInFirstNS_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function TableInFirstNS_mt:FooTable()
+    local o = self.view:Offset(4)
+    if o ~= 0 then
+        local x = self.view:Indirect(o + self.view.pos)
+        local obj = require('NamespaceA.NamespaceB.TableInNestedNS').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function TableInFirstNS_mt:FooEnum()
+    local o = self.view:Offset(6)
+    if o ~= 0 then
+        return self.view:Get(flatbuffers.N.Int8, o + self.view.pos)
+    end
+    return 0
+end
+function TableInFirstNS_mt:FooStruct()
+    local o = self.view:Offset(8)
+    if o ~= 0 then
+        local x = o + self.view.pos
+        local obj = require('NamespaceA.NamespaceB.StructInNestedNS').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function TableInFirstNS.Start(builder) builder:StartObject(3) end
+function TableInFirstNS.AddFooTable(builder, fooTable) builder:PrependUOffsetTRelativeSlot(0, fooTable, 0) end
+function TableInFirstNS.AddFooEnum(builder, fooEnum) builder:PrependInt8Slot(1, fooEnum, 0) end
+function TableInFirstNS.AddFooStruct(builder, fooStruct) builder:PrependStructSlot(2, fooStruct, 0) end
+function TableInFirstNS.End(builder) return builder:EndObject() end
+
+return TableInFirstNS -- return the module
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInFirstNS.php b/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInFirstNS.php
new file mode 100644
index 0000000..9fb29c3
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInFirstNS.php
@@ -0,0 +1,120 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace NamespaceA;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class TableInFirstNS extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return TableInFirstNS
+     */
+    public static function getRootAsTableInFirstNS(ByteBuffer $bb)
+    {
+        $obj = new TableInFirstNS();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return TableInFirstNS
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    public function getFooTable()
+    {
+        $obj = new TableInNestedNS();
+        $o = $this->__offset(4);
+        return $o != 0 ? $obj->init($this->__indirect($o + $this->bb_pos), $this->bb) : 0;
+    }
+
+    /**
+     * @return sbyte
+     */
+    public function getFooEnum()
+    {
+        $o = $this->__offset(6);
+        return $o != 0 ? $this->bb->getSbyte($o + $this->bb_pos) : \NamespaceA\NamespaceB\EnumInNestedNS::A;
+    }
+
+    public function getFooStruct()
+    {
+        $obj = new StructInNestedNS();
+        $o = $this->__offset(8);
+        return $o != 0 ? $obj->init($o + $this->bb_pos, $this->bb) : 0;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startTableInFirstNS(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(3);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return TableInFirstNS
+     */
+    public static function createTableInFirstNS(FlatBufferBuilder $builder, $foo_table, $foo_enum, $foo_struct)
+    {
+        $builder->startObject(3);
+        self::addFooTable($builder, $foo_table);
+        self::addFooEnum($builder, $foo_enum);
+        self::addFooStruct($builder, $foo_struct);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addFooTable(FlatBufferBuilder $builder, $fooTable)
+    {
+        $builder->addOffsetX(0, $fooTable, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param sbyte
+     * @return void
+     */
+    public static function addFooEnum(FlatBufferBuilder $builder, $fooEnum)
+    {
+        $builder->addSbyteX(1, $fooEnum, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addFooStruct(FlatBufferBuilder $builder, $fooStruct)
+    {
+        $builder->addStructX(2, $fooStruct, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endTableInFirstNS(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInFirstNS.py b/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInFirstNS.py
new file mode 100644
index 0000000..40cbeba
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/TableInFirstNS.py
@@ -0,0 +1,54 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: NamespaceA
+
+import flatbuffers
+
+class TableInFirstNS(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAsTableInFirstNS(cls, buf, offset):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = TableInFirstNS()
+        x.Init(buf, n + offset)
+        return x
+
+    # TableInFirstNS
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # TableInFirstNS
+    def FooTable(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        if o != 0:
+            x = self._tab.Indirect(o + self._tab.Pos)
+            from .TableInNestedNS import TableInNestedNS
+            obj = TableInNestedNS()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+    # TableInFirstNS
+    def FooEnum(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int8Flags, o + self._tab.Pos)
+        return 0
+
+    # TableInFirstNS
+    def FooStruct(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
+        if o != 0:
+            x = o + self._tab.Pos
+            from .StructInNestedNS import StructInNestedNS
+            obj = StructInNestedNS()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+def TableInFirstNSStart(builder): builder.StartObject(3)
+def TableInFirstNSAddFooTable(builder, fooTable): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(fooTable), 0)
+def TableInFirstNSAddFooEnum(builder, fooEnum): builder.PrependInt8Slot(1, fooEnum, 0)
+def TableInFirstNSAddFooStruct(builder, fooStruct): builder.PrependStructSlot(2, flatbuffers.number_types.UOffsetTFlags.py_type(fooStruct), 0)
+def TableInFirstNSEnd(builder): return builder.EndObject()
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceA/__init__.py b/third_party/flatbuffers/tests/namespace_test/NamespaceA/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceA/__init__.py
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceC/TableInC.cs b/third_party/flatbuffers/tests/namespace_test/NamespaceC/TableInC.cs
new file mode 100644
index 0000000..74b85a4
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceC/TableInC.cs
@@ -0,0 +1,43 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace NamespaceC
+{
+
+using global::System;
+using global::FlatBuffers;
+
+public struct TableInC : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static TableInC GetRootAsTableInC(ByteBuffer _bb) { return GetRootAsTableInC(_bb, new TableInC()); }
+  public static TableInC GetRootAsTableInC(ByteBuffer _bb, TableInC obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public TableInC __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public NamespaceA.TableInFirstNS? ReferToA1 { get { int o = __p.__offset(4); return o != 0 ? (NamespaceA.TableInFirstNS?)(new NamespaceA.TableInFirstNS()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
+  public NamespaceA.SecondTableInA? ReferToA2 { get { int o = __p.__offset(6); return o != 0 ? (NamespaceA.SecondTableInA?)(new NamespaceA.SecondTableInA()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
+
+  public static Offset<NamespaceC.TableInC> CreateTableInC(FlatBufferBuilder builder,
+      Offset<NamespaceA.TableInFirstNS> refer_to_a1Offset = default(Offset<NamespaceA.TableInFirstNS>),
+      Offset<NamespaceA.SecondTableInA> refer_to_a2Offset = default(Offset<NamespaceA.SecondTableInA>)) {
+    builder.StartTable(2);
+    TableInC.AddReferToA2(builder, refer_to_a2Offset);
+    TableInC.AddReferToA1(builder, refer_to_a1Offset);
+    return TableInC.EndTableInC(builder);
+  }
+
+  public static void StartTableInC(FlatBufferBuilder builder) { builder.StartTable(2); }
+  public static void AddReferToA1(FlatBufferBuilder builder, Offset<NamespaceA.TableInFirstNS> referToA1Offset) { builder.AddOffset(0, referToA1Offset.Value, 0); }
+  public static void AddReferToA2(FlatBufferBuilder builder, Offset<NamespaceA.SecondTableInA> referToA2Offset) { builder.AddOffset(1, referToA2Offset.Value, 0); }
+  public static Offset<NamespaceC.TableInC> EndTableInC(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<NamespaceC.TableInC>(o);
+  }
+};
+
+
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceC/TableInC.go b/third_party/flatbuffers/tests/namespace_test/NamespaceC/TableInC.go
new file mode 100644
index 0000000..59b3e48
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceC/TableInC.go
@@ -0,0 +1,68 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package NamespaceC
+
+import (
+	flatbuffers "github.com/google/flatbuffers/go"
+
+	NamespaceA "NamespaceA"
+)
+
+type TableInC struct {
+	_tab flatbuffers.Table
+}
+
+func GetRootAsTableInC(buf []byte, offset flatbuffers.UOffsetT) *TableInC {
+	n := flatbuffers.GetUOffsetT(buf[offset:])
+	x := &TableInC{}
+	x.Init(buf, n+offset)
+	return x
+}
+
+func (rcv *TableInC) Init(buf []byte, i flatbuffers.UOffsetT) {
+	rcv._tab.Bytes = buf
+	rcv._tab.Pos = i
+}
+
+func (rcv *TableInC) Table() flatbuffers.Table {
+	return rcv._tab
+}
+
+func (rcv *TableInC) ReferToA1(obj *NamespaceA.TableInFirstNS) *NamespaceA.TableInFirstNS {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
+	if o != 0 {
+		x := rcv._tab.Indirect(o + rcv._tab.Pos)
+		if obj == nil {
+			obj = new(NamespaceA.TableInFirstNS)
+		}
+		obj.Init(rcv._tab.Bytes, x)
+		return obj
+	}
+	return nil
+}
+
+func (rcv *TableInC) ReferToA2(obj *NamespaceA.SecondTableInA) *NamespaceA.SecondTableInA {
+	o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
+	if o != 0 {
+		x := rcv._tab.Indirect(o + rcv._tab.Pos)
+		if obj == nil {
+			obj = new(NamespaceA.SecondTableInA)
+		}
+		obj.Init(rcv._tab.Bytes, x)
+		return obj
+	}
+	return nil
+}
+
+func TableInCStart(builder *flatbuffers.Builder) {
+	builder.StartObject(2)
+}
+func TableInCAddReferToA1(builder *flatbuffers.Builder, referToA1 flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(referToA1), 0)
+}
+func TableInCAddReferToA2(builder *flatbuffers.Builder, referToA2 flatbuffers.UOffsetT) {
+	builder.PrependUOffsetTSlot(1, flatbuffers.UOffsetT(referToA2), 0)
+}
+func TableInCEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+	return builder.EndObject()
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceC/TableInC.java b/third_party/flatbuffers/tests/namespace_test/NamespaceC/TableInC.java
new file mode 100644
index 0000000..2d9e4bf
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceC/TableInC.java
@@ -0,0 +1,40 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceC;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class TableInC extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static TableInC getRootAsTableInC(ByteBuffer _bb) { return getRootAsTableInC(_bb, new TableInC()); }
+  public static TableInC getRootAsTableInC(ByteBuffer _bb, TableInC obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public TableInC __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public NamespaceA.TableInFirstNS referToA1() { return referToA1(new NamespaceA.TableInFirstNS()); }
+  public NamespaceA.TableInFirstNS referToA1(NamespaceA.TableInFirstNS obj) { int o = __offset(4); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
+  public NamespaceA.SecondTableInA referToA2() { return referToA2(new NamespaceA.SecondTableInA()); }
+  public NamespaceA.SecondTableInA referToA2(NamespaceA.SecondTableInA obj) { int o = __offset(6); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
+
+  public static int createTableInC(FlatBufferBuilder builder,
+      int refer_to_a1Offset,
+      int refer_to_a2Offset) {
+    builder.startTable(2);
+    TableInC.addReferToA2(builder, refer_to_a2Offset);
+    TableInC.addReferToA1(builder, refer_to_a1Offset);
+    return TableInC.endTableInC(builder);
+  }
+
+  public static void startTableInC(FlatBufferBuilder builder) { builder.startTable(2); }
+  public static void addReferToA1(FlatBufferBuilder builder, int referToA1Offset) { builder.addOffset(0, referToA1Offset, 0); }
+  public static void addReferToA2(FlatBufferBuilder builder, int referToA2Offset) { builder.addOffset(1, referToA2Offset, 0); }
+  public static int endTableInC(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+}
+
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceC/TableInC.kt b/third_party/flatbuffers/tests/namespace_test/NamespaceC/TableInC.kt
new file mode 100644
index 0000000..e468642
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceC/TableInC.kt
@@ -0,0 +1,59 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceC
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class TableInC : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : TableInC {
+        __init(_i, _bb)
+        return this
+    }
+    val referToA1 : NamespaceA.TableInFirstNS? get() = referToA1(NamespaceA.TableInFirstNS())
+    fun referToA1(obj: NamespaceA.TableInFirstNS) : NamespaceA.TableInFirstNS? {
+        val o = __offset(4)
+        return if (o != 0) {
+            obj.__assign(__indirect(o + bb_pos), bb)
+        } else {
+            null
+        }
+    }
+    val referToA2 : NamespaceA.SecondTableInA? get() = referToA2(NamespaceA.SecondTableInA())
+    fun referToA2(obj: NamespaceA.SecondTableInA) : NamespaceA.SecondTableInA? {
+        val o = __offset(6)
+        return if (o != 0) {
+            obj.__assign(__indirect(o + bb_pos), bb)
+        } else {
+            null
+        }
+    }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsTableInC(_bb: ByteBuffer): TableInC = getRootAsTableInC(_bb, TableInC())
+        fun getRootAsTableInC(_bb: ByteBuffer, obj: TableInC): TableInC {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun createTableInC(builder: FlatBufferBuilder, referToA1Offset: Int, referToA2Offset: Int) : Int {
+            builder.startTable(2)
+            addReferToA2(builder, referToA2Offset)
+            addReferToA1(builder, referToA1Offset)
+            return endTableInC(builder)
+        }
+        fun startTableInC(builder: FlatBufferBuilder) = builder.startTable(2)
+        fun addReferToA1(builder: FlatBufferBuilder, referToA1: Int) = builder.addOffset(0, referToA1, 0)
+        fun addReferToA2(builder: FlatBufferBuilder, referToA2: Int) = builder.addOffset(1, referToA2, 0)
+        fun endTableInC(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+            return o
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceC/TableInC.lua b/third_party/flatbuffers/tests/namespace_test/NamespaceC/TableInC.lua
new file mode 100644
index 0000000..bb4fef0
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceC/TableInC.lua
@@ -0,0 +1,47 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: NamespaceC
+
+local flatbuffers = require('flatbuffers')
+
+local TableInC = {} -- the module
+local TableInC_mt = {} -- the class metatable
+
+function TableInC.New()
+    local o = {}
+    setmetatable(o, {__index = TableInC_mt})
+    return o
+end
+function TableInC.GetRootAsTableInC(buf, offset)
+    local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)
+    local o = TableInC.New()
+    o:Init(buf, n + offset)
+    return o
+end
+function TableInC_mt:Init(buf, pos)
+    self.view = flatbuffers.view.New(buf, pos)
+end
+function TableInC_mt:ReferToA1()
+    local o = self.view:Offset(4)
+    if o ~= 0 then
+        local x = self.view:Indirect(o + self.view.pos)
+        local obj = require('NamespaceA.TableInFirstNS').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function TableInC_mt:ReferToA2()
+    local o = self.view:Offset(6)
+    if o ~= 0 then
+        local x = self.view:Indirect(o + self.view.pos)
+        local obj = require('NamespaceA.SecondTableInA').New()
+        obj:Init(self.view.bytes, x)
+        return obj
+    end
+end
+function TableInC.Start(builder) builder:StartObject(2) end
+function TableInC.AddReferToA1(builder, referToA1) builder:PrependUOffsetTRelativeSlot(0, referToA1, 0) end
+function TableInC.AddReferToA2(builder, referToA2) builder:PrependUOffsetTRelativeSlot(1, referToA2, 0) end
+function TableInC.End(builder) return builder:EndObject() end
+
+return TableInC -- return the module
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceC/TableInC.php b/third_party/flatbuffers/tests/namespace_test/NamespaceC/TableInC.php
new file mode 100644
index 0000000..116aea1
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceC/TableInC.php
@@ -0,0 +1,100 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace NamespaceC;
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class TableInC extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return TableInC
+     */
+    public static function getRootAsTableInC(ByteBuffer $bb)
+    {
+        $obj = new TableInC();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return TableInC
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    public function getReferToA1()
+    {
+        $obj = new TableInFirstNS();
+        $o = $this->__offset(4);
+        return $o != 0 ? $obj->init($this->__indirect($o + $this->bb_pos), $this->bb) : 0;
+    }
+
+    public function getReferToA2()
+    {
+        $obj = new SecondTableInA();
+        $o = $this->__offset(6);
+        return $o != 0 ? $obj->init($this->__indirect($o + $this->bb_pos), $this->bb) : 0;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startTableInC(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(2);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return TableInC
+     */
+    public static function createTableInC(FlatBufferBuilder $builder, $refer_to_a1, $refer_to_a2)
+    {
+        $builder->startObject(2);
+        self::addReferToA1($builder, $refer_to_a1);
+        self::addReferToA2($builder, $refer_to_a2);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addReferToA1(FlatBufferBuilder $builder, $referToA1)
+    {
+        $builder->addOffsetX(0, $referToA1, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addReferToA2(FlatBufferBuilder $builder, $referToA2)
+    {
+        $builder->addOffsetX(1, $referToA2, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endTableInC(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceC/TableInC.py b/third_party/flatbuffers/tests/namespace_test/NamespaceC/TableInC.py
new file mode 100644
index 0000000..90b8736
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceC/TableInC.py
@@ -0,0 +1,46 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: NamespaceC
+
+import flatbuffers
+
+class TableInC(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAsTableInC(cls, buf, offset):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = TableInC()
+        x.Init(buf, n + offset)
+        return x
+
+    # TableInC
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # TableInC
+    def ReferToA1(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        if o != 0:
+            x = self._tab.Indirect(o + self._tab.Pos)
+            from .TableInFirstNS import TableInFirstNS
+            obj = TableInFirstNS()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+    # TableInC
+    def ReferToA2(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
+        if o != 0:
+            x = self._tab.Indirect(o + self._tab.Pos)
+            from .SecondTableInA import SecondTableInA
+            obj = SecondTableInA()
+            obj.Init(self._tab.Bytes, x)
+            return obj
+        return None
+
+def TableInCStart(builder): builder.StartObject(2)
+def TableInCAddReferToA1(builder, referToA1): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(referToA1), 0)
+def TableInCAddReferToA2(builder, referToA2): builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(referToA2), 0)
+def TableInCEnd(builder): return builder.EndObject()
diff --git a/third_party/flatbuffers/tests/namespace_test/NamespaceC/__init__.py b/third_party/flatbuffers/tests/namespace_test/NamespaceC/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/NamespaceC/__init__.py
diff --git a/third_party/flatbuffers/tests/namespace_test/namespace_test1.fbs b/third_party/flatbuffers/tests/namespace_test/namespace_test1.fbs
new file mode 100644
index 0000000..49449bf
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/namespace_test1.fbs
@@ -0,0 +1,17 @@
+namespace NamespaceA.NamespaceB;
+
+table TableInNestedNS
+{
+    foo:int;
+}
+
+enum EnumInNestedNS:byte
+{
+	A, B, C
+}
+
+struct StructInNestedNS
+{
+    a:int;
+	b:int;
+}
\ No newline at end of file
diff --git a/third_party/flatbuffers/tests/namespace_test/namespace_test1_generated.h b/third_party/flatbuffers/tests/namespace_test/namespace_test1_generated.h
new file mode 100644
index 0000000..daaf7ae
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/namespace_test1_generated.h
@@ -0,0 +1,182 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_NAMESPACETEST1_NAMESPACEA_NAMESPACEB_H_
+#define FLATBUFFERS_GENERATED_NAMESPACETEST1_NAMESPACEA_NAMESPACEB_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+namespace NamespaceA {
+namespace NamespaceB {
+
+struct TableInNestedNS;
+
+struct StructInNestedNS;
+
+inline const flatbuffers::TypeTable *TableInNestedNSTypeTable();
+
+inline const flatbuffers::TypeTable *StructInNestedNSTypeTable();
+
+enum EnumInNestedNS {
+  EnumInNestedNS_A = 0,
+  EnumInNestedNS_B = 1,
+  EnumInNestedNS_C = 2,
+  EnumInNestedNS_MIN = EnumInNestedNS_A,
+  EnumInNestedNS_MAX = EnumInNestedNS_C
+};
+
+inline const EnumInNestedNS (&EnumValuesEnumInNestedNS())[3] {
+  static const EnumInNestedNS values[] = {
+    EnumInNestedNS_A,
+    EnumInNestedNS_B,
+    EnumInNestedNS_C
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesEnumInNestedNS() {
+  static const char * const names[4] = {
+    "A",
+    "B",
+    "C",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameEnumInNestedNS(EnumInNestedNS e) {
+  if (e < EnumInNestedNS_A || e > EnumInNestedNS_C) return "";
+  const size_t index = static_cast<size_t>(e);
+  return EnumNamesEnumInNestedNS()[index];
+}
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) StructInNestedNS FLATBUFFERS_FINAL_CLASS {
+ private:
+  int32_t a_;
+  int32_t b_;
+
+ public:
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return StructInNestedNSTypeTable();
+  }
+  StructInNestedNS() {
+    memset(static_cast<void *>(this), 0, sizeof(StructInNestedNS));
+  }
+  StructInNestedNS(int32_t _a, int32_t _b)
+      : a_(flatbuffers::EndianScalar(_a)),
+        b_(flatbuffers::EndianScalar(_b)) {
+  }
+  int32_t a() const {
+    return flatbuffers::EndianScalar(a_);
+  }
+  void mutate_a(int32_t _a) {
+    flatbuffers::WriteScalar(&a_, _a);
+  }
+  int32_t b() const {
+    return flatbuffers::EndianScalar(b_);
+  }
+  void mutate_b(int32_t _b) {
+    flatbuffers::WriteScalar(&b_, _b);
+  }
+};
+FLATBUFFERS_STRUCT_END(StructInNestedNS, 8);
+
+struct TableInNestedNS FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return TableInNestedNSTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_FOO = 4
+  };
+  int32_t foo() const {
+    return GetField<int32_t>(VT_FOO, 0);
+  }
+  bool mutate_foo(int32_t _foo) {
+    return SetField<int32_t>(VT_FOO, _foo, 0);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<int32_t>(verifier, VT_FOO) &&
+           verifier.EndTable();
+  }
+};
+
+struct TableInNestedNSBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_foo(int32_t foo) {
+    fbb_.AddElement<int32_t>(TableInNestedNS::VT_FOO, foo, 0);
+  }
+  explicit TableInNestedNSBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  TableInNestedNSBuilder &operator=(const TableInNestedNSBuilder &);
+  flatbuffers::Offset<TableInNestedNS> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<TableInNestedNS>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<TableInNestedNS> CreateTableInNestedNS(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    int32_t foo = 0) {
+  TableInNestedNSBuilder builder_(_fbb);
+  builder_.add_foo(foo);
+  return builder_.Finish();
+}
+
+inline const flatbuffers::TypeTable *EnumInNestedNSTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_CHAR, 0, 0 },
+    { flatbuffers::ET_CHAR, 0, 0 },
+    { flatbuffers::ET_CHAR, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    NamespaceA::NamespaceB::EnumInNestedNSTypeTable
+  };
+  static const char * const names[] = {
+    "A",
+    "B",
+    "C"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_ENUM, 3, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *TableInNestedNSTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_INT, 0, -1 }
+  };
+  static const char * const names[] = {
+    "foo"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 1, type_codes, nullptr, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *StructInNestedNSTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_INT, 0, -1 },
+    { flatbuffers::ET_INT, 0, -1 }
+  };
+  static const int64_t values[] = { 0, 4, 8 };
+  static const char * const names[] = {
+    "a",
+    "b"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_STRUCT, 2, type_codes, nullptr, values, names
+  };
+  return &tt;
+}
+
+}  // namespace NamespaceB
+}  // namespace NamespaceA
+
+#endif  // FLATBUFFERS_GENERATED_NAMESPACETEST1_NAMESPACEA_NAMESPACEB_H_
diff --git a/third_party/flatbuffers/tests/namespace_test/namespace_test1_generated.js b/third_party/flatbuffers/tests/namespace_test/namespace_test1_generated.js
new file mode 100644
index 0000000..bd018d6
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/namespace_test1_generated.js
@@ -0,0 +1,219 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+/**
+ * @const
+ * @namespace
+ */
+var NamespaceA = NamespaceA || {};
+
+/**
+ * @const
+ * @namespace
+ */
+NamespaceA.NamespaceB = NamespaceA.NamespaceB || {};
+
+/**
+ * @enum {number}
+ */
+NamespaceA.NamespaceB.EnumInNestedNS = {
+  A: 0,
+  B: 1,
+  C: 2
+};
+
+/**
+ * @enum {string}
+ */
+NamespaceA.NamespaceB.EnumInNestedNSName = {
+  0: 'A',
+  1: 'B',
+  2: 'C'
+};
+
+/**
+ * @constructor
+ */
+NamespaceA.NamespaceB.TableInNestedNS = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {NamespaceA.NamespaceB.TableInNestedNS}
+ */
+NamespaceA.NamespaceB.TableInNestedNS.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {NamespaceA.NamespaceB.TableInNestedNS=} obj
+ * @returns {NamespaceA.NamespaceB.TableInNestedNS}
+ */
+NamespaceA.NamespaceB.TableInNestedNS.getRootAsTableInNestedNS = function(bb, obj) {
+  return (obj || new NamespaceA.NamespaceB.TableInNestedNS).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {NamespaceA.NamespaceB.TableInNestedNS=} obj
+ * @returns {NamespaceA.NamespaceB.TableInNestedNS}
+ */
+NamespaceA.NamespaceB.TableInNestedNS.getSizePrefixedRootAsTableInNestedNS = function(bb, obj) {
+  return (obj || new NamespaceA.NamespaceB.TableInNestedNS).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @returns {number}
+ */
+NamespaceA.NamespaceB.TableInNestedNS.prototype.foo = function() {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+  return offset ? this.bb.readInt32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+NamespaceA.NamespaceB.TableInNestedNS.prototype.mutate_foo = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ */
+NamespaceA.NamespaceB.TableInNestedNS.startTableInNestedNS = function(builder) {
+  builder.startObject(1);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} foo
+ */
+NamespaceA.NamespaceB.TableInNestedNS.addFoo = function(builder, foo) {
+  builder.addFieldInt32(0, foo, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+NamespaceA.NamespaceB.TableInNestedNS.endTableInNestedNS = function(builder) {
+  var offset = builder.endObject();
+  return offset;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} foo
+ * @returns {flatbuffers.Offset}
+ */
+NamespaceA.NamespaceB.TableInNestedNS.createTableInNestedNS = function(builder, foo) {
+  NamespaceA.NamespaceB.TableInNestedNS.startTableInNestedNS(builder);
+  NamespaceA.NamespaceB.TableInNestedNS.addFoo(builder, foo);
+  return NamespaceA.NamespaceB.TableInNestedNS.endTableInNestedNS(builder);
+}
+
+/**
+ * @constructor
+ */
+NamespaceA.NamespaceB.StructInNestedNS = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {NamespaceA.NamespaceB.StructInNestedNS}
+ */
+NamespaceA.NamespaceB.StructInNestedNS.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @returns {number}
+ */
+NamespaceA.NamespaceB.StructInNestedNS.prototype.a = function() {
+  return this.bb.readInt32(this.bb_pos);
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+NamespaceA.NamespaceB.StructInNestedNS.prototype.mutate_a = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 0);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns {number}
+ */
+NamespaceA.NamespaceB.StructInNestedNS.prototype.b = function() {
+  return this.bb.readInt32(this.bb_pos + 4);
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+NamespaceA.NamespaceB.StructInNestedNS.prototype.mutate_b = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} a
+ * @param {number} b
+ * @returns {flatbuffers.Offset}
+ */
+NamespaceA.NamespaceB.StructInNestedNS.createStructInNestedNS = function(builder, a, b) {
+  builder.prep(4, 8);
+  builder.writeInt32(b);
+  builder.writeInt32(a);
+  return builder.offset();
+};
+
+// Exports for Node.js and RequireJS
+this.NamespaceA = NamespaceA;
diff --git a/third_party/flatbuffers/tests/namespace_test/namespace_test1_generated.lobster b/third_party/flatbuffers/tests/namespace_test/namespace_test1_generated.lobster
new file mode 100644
index 0000000..6503005
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/namespace_test1_generated.lobster
@@ -0,0 +1,43 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+import flatbuffers
+
+namespace NamespaceA_NamespaceB
+
+enum EnumInNestedNS:
+    EnumInNestedNS_A = 0
+    EnumInNestedNS_B = 1
+    EnumInNestedNS_C = 2
+
+class TableInNestedNS
+
+class StructInNestedNS
+
+class TableInNestedNS : flatbuffers_handle
+    def foo():
+        return buf_.flatbuffers_field_int32(pos_, 4, 0)
+
+def GetRootAsTableInNestedNS(buf:string): return TableInNestedNS { buf, buf.flatbuffers_indirect(0) }
+
+struct TableInNestedNSBuilder:
+    b_:flatbuffers_builder
+    def start():
+        b_.StartObject(1)
+        return this
+    def add_foo(foo:int):
+        b_.PrependInt32Slot(0, foo, 0)
+        return this
+    def end():
+        return b_.EndObject()
+
+class StructInNestedNS : flatbuffers_handle
+    def a():
+        return buf_.read_int32_le(pos_ + 0)
+    def b():
+        return buf_.read_int32_le(pos_ + 4)
+
+def CreateStructInNestedNS(b_:flatbuffers_builder, a:int, b:int):
+    b_.Prep(4, 8)
+    b_.PrependInt32(b)
+    b_.PrependInt32(a)
+    return b_.Offset()
+
diff --git a/third_party/flatbuffers/tests/namespace_test/namespace_test1_generated.rs b/third_party/flatbuffers/tests/namespace_test/namespace_test1_generated.rs
new file mode 100644
index 0000000..ab30299
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/namespace_test1_generated.rs
@@ -0,0 +1,230 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+
+use std::mem;
+use std::cmp::Ordering;
+
+extern crate flatbuffers;
+use self::flatbuffers::EndianScalar;
+
+#[allow(unused_imports, dead_code)]
+pub mod namespace_a {
+
+  use std::mem;
+  use std::cmp::Ordering;
+
+  extern crate flatbuffers;
+  use self::flatbuffers::EndianScalar;
+#[allow(unused_imports, dead_code)]
+pub mod namespace_b {
+
+  use std::mem;
+  use std::cmp::Ordering;
+
+  extern crate flatbuffers;
+  use self::flatbuffers::EndianScalar;
+
+#[allow(non_camel_case_types)]
+#[repr(i8)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+pub enum EnumInNestedNS {
+  A = 0,
+  B = 1,
+  C = 2,
+
+}
+
+const ENUM_MIN_ENUM_IN_NESTED_NS: i8 = 0;
+const ENUM_MAX_ENUM_IN_NESTED_NS: i8 = 2;
+
+impl<'a> flatbuffers::Follow<'a> for EnumInNestedNS {
+  type Inner = Self;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    flatbuffers::read_scalar_at::<Self>(buf, loc)
+  }
+}
+
+impl flatbuffers::EndianScalar for EnumInNestedNS {
+  #[inline]
+  fn to_little_endian(self) -> Self {
+    let n = i8::to_le(self as i8);
+    let p = &n as *const i8 as *const EnumInNestedNS;
+    unsafe { *p }
+  }
+  #[inline]
+  fn from_little_endian(self) -> Self {
+    let n = i8::from_le(self as i8);
+    let p = &n as *const i8 as *const EnumInNestedNS;
+    unsafe { *p }
+  }
+}
+
+impl flatbuffers::Push for EnumInNestedNS {
+    type Output = EnumInNestedNS;
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        flatbuffers::emplace_scalar::<EnumInNestedNS>(dst, *self);
+    }
+}
+
+#[allow(non_camel_case_types)]
+const ENUM_VALUES_ENUM_IN_NESTED_NS:[EnumInNestedNS; 3] = [
+  EnumInNestedNS::A,
+  EnumInNestedNS::B,
+  EnumInNestedNS::C
+];
+
+#[allow(non_camel_case_types)]
+const ENUM_NAMES_ENUM_IN_NESTED_NS:[&'static str; 3] = [
+    "A",
+    "B",
+    "C"
+];
+
+pub fn enum_name_enum_in_nested_ns(e: EnumInNestedNS) -> &'static str {
+  let index = e as i8;
+  ENUM_NAMES_ENUM_IN_NESTED_NS[index as usize]
+}
+
+// struct StructInNestedNS, aligned to 4
+#[repr(C, align(4))]
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub struct StructInNestedNS {
+  a_: i32,
+  b_: i32,
+} // pub struct StructInNestedNS
+impl flatbuffers::SafeSliceAccess for StructInNestedNS {}
+impl<'a> flatbuffers::Follow<'a> for StructInNestedNS {
+  type Inner = &'a StructInNestedNS;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    <&'a StructInNestedNS>::follow(buf, loc)
+  }
+}
+impl<'a> flatbuffers::Follow<'a> for &'a StructInNestedNS {
+  type Inner = &'a StructInNestedNS;
+  #[inline]
+  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    flatbuffers::follow_cast_ref::<StructInNestedNS>(buf, loc)
+  }
+}
+impl<'b> flatbuffers::Push for StructInNestedNS {
+    type Output = StructInNestedNS;
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        let src = unsafe {
+            ::std::slice::from_raw_parts(self as *const StructInNestedNS as *const u8, Self::size())
+        };
+        dst.copy_from_slice(src);
+    }
+}
+impl<'b> flatbuffers::Push for &'b StructInNestedNS {
+    type Output = StructInNestedNS;
+
+    #[inline]
+    fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+        let src = unsafe {
+            ::std::slice::from_raw_parts(*self as *const StructInNestedNS as *const u8, Self::size())
+        };
+        dst.copy_from_slice(src);
+    }
+}
+
+
+impl StructInNestedNS {
+  pub fn new<'a>(_a: i32, _b: i32) -> Self {
+    StructInNestedNS {
+      a_: _a.to_little_endian(),
+      b_: _b.to_little_endian(),
+
+    }
+  }
+  pub fn a<'a>(&'a self) -> i32 {
+    self.a_.from_little_endian()
+  }
+  pub fn b<'a>(&'a self) -> i32 {
+    self.b_.from_little_endian()
+  }
+}
+
+pub enum TableInNestedNSOffset {}
+#[derive(Copy, Clone, Debug, PartialEq)]
+
+pub struct TableInNestedNS<'a> {
+  pub _tab: flatbuffers::Table<'a>,
+}
+
+impl<'a> flatbuffers::Follow<'a> for TableInNestedNS<'a> {
+    type Inner = TableInNestedNS<'a>;
+    #[inline]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        Self {
+            _tab: flatbuffers::Table { buf: buf, loc: loc },
+        }
+    }
+}
+
+impl<'a> TableInNestedNS<'a> {
+    #[inline]
+    pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
+        TableInNestedNS {
+            _tab: table,
+        }
+    }
+    #[allow(unused_mut)]
+    pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
+        _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
+        args: &'args TableInNestedNSArgs) -> flatbuffers::WIPOffset<TableInNestedNS<'bldr>> {
+      let mut builder = TableInNestedNSBuilder::new(_fbb);
+      builder.add_foo(args.foo);
+      builder.finish()
+    }
+
+    pub const VT_FOO: flatbuffers::VOffsetT = 4;
+
+  #[inline]
+  pub fn foo(&self) -> i32 {
+    self._tab.get::<i32>(TableInNestedNS::VT_FOO, Some(0)).unwrap()
+  }
+}
+
+pub struct TableInNestedNSArgs {
+    pub foo: i32,
+}
+impl<'a> Default for TableInNestedNSArgs {
+    #[inline]
+    fn default() -> Self {
+        TableInNestedNSArgs {
+            foo: 0,
+        }
+    }
+}
+pub struct TableInNestedNSBuilder<'a: 'b, 'b> {
+  fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+  start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
+}
+impl<'a: 'b, 'b> TableInNestedNSBuilder<'a, 'b> {
+  #[inline]
+  pub fn add_foo(&mut self, foo: i32) {
+    self.fbb_.push_slot::<i32>(TableInNestedNS::VT_FOO, foo, 0);
+  }
+  #[inline]
+  pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> TableInNestedNSBuilder<'a, 'b> {
+    let start = _fbb.start_table();
+    TableInNestedNSBuilder {
+      fbb_: _fbb,
+      start_: start,
+    }
+  }
+  #[inline]
+  pub fn finish(self) -> flatbuffers::WIPOffset<TableInNestedNS<'a>> {
+    let o = self.fbb_.end_table(self.start_);
+    flatbuffers::WIPOffset::new(o.value())
+  }
+}
+
+}  // pub mod NamespaceB
+}  // pub mod NamespaceA
+
diff --git a/third_party/flatbuffers/tests/namespace_test/namespace_test1_generated.ts b/third_party/flatbuffers/tests/namespace_test/namespace_test1_generated.ts
new file mode 100644
index 0000000..615c7ce
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/namespace_test1_generated.ts
@@ -0,0 +1,181 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+/**
+ * @enum {number}
+ */
+export namespace NamespaceA.NamespaceB{
+export enum EnumInNestedNS{
+  A= 0,
+  B= 1,
+  C= 2
+}};
+
+/**
+ * @constructor
+ */
+export namespace NamespaceA.NamespaceB{
+export class TableInNestedNS {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns TableInNestedNS
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):TableInNestedNS {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param TableInNestedNS= obj
+ * @returns TableInNestedNS
+ */
+static getRootAsTableInNestedNS(bb:flatbuffers.ByteBuffer, obj?:TableInNestedNS):TableInNestedNS {
+  return (obj || new TableInNestedNS).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param TableInNestedNS= obj
+ * @returns TableInNestedNS
+ */
+static getSizePrefixedRootAsTableInNestedNS(bb:flatbuffers.ByteBuffer, obj?:TableInNestedNS):TableInNestedNS {
+  return (obj || new TableInNestedNS).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @returns number
+ */
+foo():number {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+  return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_foo(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ */
+static startTableInNestedNS(builder:flatbuffers.Builder) {
+  builder.startObject(1);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number foo
+ */
+static addFoo(builder:flatbuffers.Builder, foo:number) {
+  builder.addFieldInt32(0, foo, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @returns flatbuffers.Offset
+ */
+static endTableInNestedNS(builder:flatbuffers.Builder):flatbuffers.Offset {
+  var offset = builder.endObject();
+  return offset;
+};
+
+static createTableInNestedNS(builder:flatbuffers.Builder, foo:number):flatbuffers.Offset {
+  TableInNestedNS.startTableInNestedNS(builder);
+  TableInNestedNS.addFoo(builder, foo);
+  return TableInNestedNS.endTableInNestedNS(builder);
+}
+}
+}
+/**
+ * @constructor
+ */
+export namespace NamespaceA.NamespaceB{
+export class StructInNestedNS {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns StructInNestedNS
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):StructInNestedNS {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @returns number
+ */
+a():number {
+  return this.bb!.readInt32(this.bb_pos);
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_a(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 0);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @returns number
+ */
+b():number {
+  return this.bb!.readInt32(this.bb_pos + 4);
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_b(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number a
+ * @param number b
+ * @returns flatbuffers.Offset
+ */
+static createStructInNestedNS(builder:flatbuffers.Builder, a: number, b: number):flatbuffers.Offset {
+  builder.prep(4, 8);
+  builder.writeInt32(b);
+  builder.writeInt32(a);
+  return builder.offset();
+};
+
+}
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/namespace_test1_namespace_a.namespace_b_generated.dart b/third_party/flatbuffers/tests/namespace_test/namespace_test1_namespace_a.namespace_b_generated.dart
new file mode 100644
index 0000000..f999e44
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/namespace_test1_namespace_a.namespace_b_generated.dart
@@ -0,0 +1,198 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+// ignore_for_file: unused_import, unused_field, unused_local_variable
+
+library namespace_a.namespace_b;
+
+import 'dart:typed_data' show Uint8List;
+import 'package:flat_buffers/flat_buffers.dart' as fb;
+
+
+class EnumInNestedNS {
+  final int value;
+  const EnumInNestedNS._(this.value);
+
+  factory EnumInNestedNS.fromValue(int value) {
+    if (value == null) value = 0;
+    if (!values.containsKey(value)) {
+      throw new StateError('Invalid value $value for bit flag enum EnumInNestedNS');
+    }
+    return values[value];
+  }
+
+  static const int minValue = 0;
+  static const int maxValue = 2;
+  static bool containsValue(int value) => values.containsKey(value);
+
+  static const EnumInNestedNS A = const EnumInNestedNS._(0);
+  static const EnumInNestedNS B = const EnumInNestedNS._(1);
+  static const EnumInNestedNS C = const EnumInNestedNS._(2);
+  static get values => {0: A,1: B,2: C,};
+
+  static const fb.Reader<EnumInNestedNS> reader = const _EnumInNestedNSReader();
+
+  @override
+  String toString() {
+    return 'EnumInNestedNS{value: $value}';
+  }
+}
+
+class _EnumInNestedNSReader extends fb.Reader<EnumInNestedNS> {
+  const _EnumInNestedNSReader();
+
+  @override
+  int get size => 1;
+
+  @override
+  EnumInNestedNS read(fb.BufferContext bc, int offset) =>
+      new EnumInNestedNS.fromValue(const fb.Int8Reader().read(bc, offset));
+}
+
+class TableInNestedNS {
+  TableInNestedNS._(this._bc, this._bcOffset);
+  factory TableInNestedNS(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<TableInNestedNS> reader = const _TableInNestedNSReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  int get foo => const fb.Int32Reader().vTableGet(_bc, _bcOffset, 4, 0);
+
+  @override
+  String toString() {
+    return 'TableInNestedNS{foo: $foo}';
+  }
+}
+
+class _TableInNestedNSReader extends fb.TableReader<TableInNestedNS> {
+  const _TableInNestedNSReader();
+
+  @override
+  TableInNestedNS createObject(fb.BufferContext bc, int offset) => 
+    new TableInNestedNS._(bc, offset);
+}
+
+class TableInNestedNSBuilder {
+  TableInNestedNSBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  void begin() {
+    fbBuilder.startTable();
+  }
+
+  int addFoo(int foo) {
+    fbBuilder.addInt32(0, foo);
+    return fbBuilder.offset;
+  }
+
+  int finish() {
+    return fbBuilder.endTable();
+  }
+}
+
+class TableInNestedNSObjectBuilder extends fb.ObjectBuilder {
+  final int _foo;
+
+  TableInNestedNSObjectBuilder({
+    int foo,
+  })
+      : _foo = foo;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+
+    fbBuilder.startTable();
+    fbBuilder.addInt32(0, _foo);
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
+class StructInNestedNS {
+  StructInNestedNS._(this._bc, this._bcOffset);
+
+  static const fb.Reader<StructInNestedNS> reader = const _StructInNestedNSReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  int get a => const fb.Int32Reader().read(_bc, _bcOffset + 0);
+  int get b => const fb.Int32Reader().read(_bc, _bcOffset + 4);
+
+  @override
+  String toString() {
+    return 'StructInNestedNS{a: $a, b: $b}';
+  }
+}
+
+class _StructInNestedNSReader extends fb.StructReader<StructInNestedNS> {
+  const _StructInNestedNSReader();
+
+  @override
+  int get size => 8;
+
+  @override
+  StructInNestedNS createObject(fb.BufferContext bc, int offset) => 
+    new StructInNestedNS._(bc, offset);
+}
+
+class StructInNestedNSBuilder {
+  StructInNestedNSBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  int finish(int a, int b) {
+    fbBuilder.putInt32(b);
+    fbBuilder.putInt32(a);
+    return fbBuilder.offset;
+  }
+
+}
+
+class StructInNestedNSObjectBuilder extends fb.ObjectBuilder {
+  final int _a;
+  final int _b;
+
+  StructInNestedNSObjectBuilder({
+    int a,
+    int b,
+  })
+      : _a = a,
+        _b = b;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+
+    fbBuilder.putInt32(_b);
+    fbBuilder.putInt32(_a);
+    return fbBuilder.offset;
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/namespace_test2.fbs b/third_party/flatbuffers/tests/namespace_test/namespace_test2.fbs
new file mode 100644
index 0000000..11d7dea
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/namespace_test2.fbs
@@ -0,0 +1,24 @@
+include "namespace_test1.fbs";
+
+namespace NamespaceA;
+
+table TableInFirstNS
+{
+    foo_table:NamespaceB.TableInNestedNS;
+	foo_enum:NamespaceB.EnumInNestedNS;
+	foo_struct:NamespaceB.StructInNestedNS;
+}
+
+// Test switching namespaces inside a file.
+namespace NamespaceC;
+
+table TableInC {
+    refer_to_a1:NamespaceA.TableInFirstNS;
+    refer_to_a2:NamespaceA.SecondTableInA;
+}
+
+namespace NamespaceA;
+
+table SecondTableInA {
+    refer_to_c:NamespaceC.TableInC;
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/namespace_test2_generated.h b/third_party/flatbuffers/tests/namespace_test/namespace_test2_generated.h
new file mode 100644
index 0000000..135100a
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/namespace_test2_generated.h
@@ -0,0 +1,305 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_NAMESPACETEST2_NAMESPACEA_H_
+#define FLATBUFFERS_GENERATED_NAMESPACETEST2_NAMESPACEA_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+#include "namespace_test1_generated.h"
+
+namespace NamespaceA {
+
+struct TableInFirstNS;
+
+}  // namespace NamespaceA
+
+namespace NamespaceC {
+
+struct TableInC;
+
+}  // namespace NamespaceC
+
+namespace NamespaceA {
+
+struct SecondTableInA;
+
+inline const flatbuffers::TypeTable *TableInFirstNSTypeTable();
+
+}  // namespace NamespaceA
+
+namespace NamespaceC {
+
+inline const flatbuffers::TypeTable *TableInCTypeTable();
+
+}  // namespace NamespaceC
+
+namespace NamespaceA {
+
+inline const flatbuffers::TypeTable *SecondTableInATypeTable();
+
+struct TableInFirstNS FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return TableInFirstNSTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_FOO_TABLE = 4,
+    VT_FOO_ENUM = 6,
+    VT_FOO_STRUCT = 8
+  };
+  const NamespaceA::NamespaceB::TableInNestedNS *foo_table() const {
+    return GetPointer<const NamespaceA::NamespaceB::TableInNestedNS *>(VT_FOO_TABLE);
+  }
+  NamespaceA::NamespaceB::TableInNestedNS *mutable_foo_table() {
+    return GetPointer<NamespaceA::NamespaceB::TableInNestedNS *>(VT_FOO_TABLE);
+  }
+  NamespaceA::NamespaceB::EnumInNestedNS foo_enum() const {
+    return static_cast<NamespaceA::NamespaceB::EnumInNestedNS>(GetField<int8_t>(VT_FOO_ENUM, 0));
+  }
+  bool mutate_foo_enum(NamespaceA::NamespaceB::EnumInNestedNS _foo_enum) {
+    return SetField<int8_t>(VT_FOO_ENUM, static_cast<int8_t>(_foo_enum), 0);
+  }
+  const NamespaceA::NamespaceB::StructInNestedNS *foo_struct() const {
+    return GetStruct<const NamespaceA::NamespaceB::StructInNestedNS *>(VT_FOO_STRUCT);
+  }
+  NamespaceA::NamespaceB::StructInNestedNS *mutable_foo_struct() {
+    return GetStruct<NamespaceA::NamespaceB::StructInNestedNS *>(VT_FOO_STRUCT);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffset(verifier, VT_FOO_TABLE) &&
+           verifier.VerifyTable(foo_table()) &&
+           VerifyField<int8_t>(verifier, VT_FOO_ENUM) &&
+           VerifyField<NamespaceA::NamespaceB::StructInNestedNS>(verifier, VT_FOO_STRUCT) &&
+           verifier.EndTable();
+  }
+};
+
+struct TableInFirstNSBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_foo_table(flatbuffers::Offset<NamespaceA::NamespaceB::TableInNestedNS> foo_table) {
+    fbb_.AddOffset(TableInFirstNS::VT_FOO_TABLE, foo_table);
+  }
+  void add_foo_enum(NamespaceA::NamespaceB::EnumInNestedNS foo_enum) {
+    fbb_.AddElement<int8_t>(TableInFirstNS::VT_FOO_ENUM, static_cast<int8_t>(foo_enum), 0);
+  }
+  void add_foo_struct(const NamespaceA::NamespaceB::StructInNestedNS *foo_struct) {
+    fbb_.AddStruct(TableInFirstNS::VT_FOO_STRUCT, foo_struct);
+  }
+  explicit TableInFirstNSBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  TableInFirstNSBuilder &operator=(const TableInFirstNSBuilder &);
+  flatbuffers::Offset<TableInFirstNS> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<TableInFirstNS>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<TableInFirstNS> CreateTableInFirstNS(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<NamespaceA::NamespaceB::TableInNestedNS> foo_table = 0,
+    NamespaceA::NamespaceB::EnumInNestedNS foo_enum = NamespaceA::NamespaceB::EnumInNestedNS_A,
+    const NamespaceA::NamespaceB::StructInNestedNS *foo_struct = 0) {
+  TableInFirstNSBuilder builder_(_fbb);
+  builder_.add_foo_struct(foo_struct);
+  builder_.add_foo_table(foo_table);
+  builder_.add_foo_enum(foo_enum);
+  return builder_.Finish();
+}
+
+}  // namespace NamespaceA
+
+namespace NamespaceC {
+
+struct TableInC FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return TableInCTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_REFER_TO_A1 = 4,
+    VT_REFER_TO_A2 = 6
+  };
+  const NamespaceA::TableInFirstNS *refer_to_a1() const {
+    return GetPointer<const NamespaceA::TableInFirstNS *>(VT_REFER_TO_A1);
+  }
+  NamespaceA::TableInFirstNS *mutable_refer_to_a1() {
+    return GetPointer<NamespaceA::TableInFirstNS *>(VT_REFER_TO_A1);
+  }
+  const NamespaceA::SecondTableInA *refer_to_a2() const {
+    return GetPointer<const NamespaceA::SecondTableInA *>(VT_REFER_TO_A2);
+  }
+  NamespaceA::SecondTableInA *mutable_refer_to_a2() {
+    return GetPointer<NamespaceA::SecondTableInA *>(VT_REFER_TO_A2);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffset(verifier, VT_REFER_TO_A1) &&
+           verifier.VerifyTable(refer_to_a1()) &&
+           VerifyOffset(verifier, VT_REFER_TO_A2) &&
+           verifier.VerifyTable(refer_to_a2()) &&
+           verifier.EndTable();
+  }
+};
+
+struct TableInCBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_refer_to_a1(flatbuffers::Offset<NamespaceA::TableInFirstNS> refer_to_a1) {
+    fbb_.AddOffset(TableInC::VT_REFER_TO_A1, refer_to_a1);
+  }
+  void add_refer_to_a2(flatbuffers::Offset<NamespaceA::SecondTableInA> refer_to_a2) {
+    fbb_.AddOffset(TableInC::VT_REFER_TO_A2, refer_to_a2);
+  }
+  explicit TableInCBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  TableInCBuilder &operator=(const TableInCBuilder &);
+  flatbuffers::Offset<TableInC> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<TableInC>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<TableInC> CreateTableInC(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<NamespaceA::TableInFirstNS> refer_to_a1 = 0,
+    flatbuffers::Offset<NamespaceA::SecondTableInA> refer_to_a2 = 0) {
+  TableInCBuilder builder_(_fbb);
+  builder_.add_refer_to_a2(refer_to_a2);
+  builder_.add_refer_to_a1(refer_to_a1);
+  return builder_.Finish();
+}
+
+}  // namespace NamespaceC
+
+namespace NamespaceA {
+
+struct SecondTableInA FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return SecondTableInATypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_REFER_TO_C = 4
+  };
+  const NamespaceC::TableInC *refer_to_c() const {
+    return GetPointer<const NamespaceC::TableInC *>(VT_REFER_TO_C);
+  }
+  NamespaceC::TableInC *mutable_refer_to_c() {
+    return GetPointer<NamespaceC::TableInC *>(VT_REFER_TO_C);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffset(verifier, VT_REFER_TO_C) &&
+           verifier.VerifyTable(refer_to_c()) &&
+           verifier.EndTable();
+  }
+};
+
+struct SecondTableInABuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_refer_to_c(flatbuffers::Offset<NamespaceC::TableInC> refer_to_c) {
+    fbb_.AddOffset(SecondTableInA::VT_REFER_TO_C, refer_to_c);
+  }
+  explicit SecondTableInABuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  SecondTableInABuilder &operator=(const SecondTableInABuilder &);
+  flatbuffers::Offset<SecondTableInA> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<SecondTableInA>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<SecondTableInA> CreateSecondTableInA(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<NamespaceC::TableInC> refer_to_c = 0) {
+  SecondTableInABuilder builder_(_fbb);
+  builder_.add_refer_to_c(refer_to_c);
+  return builder_.Finish();
+}
+
+}  // namespace NamespaceA
+
+namespace NamespaceC {
+
+}  // namespace NamespaceC
+
+namespace NamespaceA {
+
+inline const flatbuffers::TypeTable *TableInFirstNSTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 0, 0 },
+    { flatbuffers::ET_CHAR, 0, 1 },
+    { flatbuffers::ET_SEQUENCE, 0, 2 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    NamespaceA::NamespaceB::TableInNestedNSTypeTable,
+    NamespaceA::NamespaceB::EnumInNestedNSTypeTable,
+    NamespaceA::NamespaceB::StructInNestedNSTypeTable
+  };
+  static const char * const names[] = {
+    "foo_table",
+    "foo_enum",
+    "foo_struct"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 3, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+}  // namespace NamespaceA
+
+namespace NamespaceC {
+
+inline const flatbuffers::TypeTable *TableInCTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 0, 0 },
+    { flatbuffers::ET_SEQUENCE, 0, 1 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    NamespaceA::TableInFirstNSTypeTable,
+    NamespaceA::SecondTableInATypeTable
+  };
+  static const char * const names[] = {
+    "refer_to_a1",
+    "refer_to_a2"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 2, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+}  // namespace NamespaceC
+
+namespace NamespaceA {
+
+inline const flatbuffers::TypeTable *SecondTableInATypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    NamespaceC::TableInCTypeTable
+  };
+  static const char * const names[] = {
+    "refer_to_c"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 1, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+}  // namespace NamespaceA
+
+#endif  // FLATBUFFERS_GENERATED_NAMESPACETEST2_NAMESPACEA_H_
diff --git a/third_party/flatbuffers/tests/namespace_test/namespace_test2_generated.js b/third_party/flatbuffers/tests/namespace_test/namespace_test2_generated.js
new file mode 100644
index 0000000..f54cda7
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/namespace_test2_generated.js
@@ -0,0 +1,358 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+/**
+ * @const
+ * @namespace
+ */
+var NamespaceA = NamespaceA || {};
+
+/**
+ * @const
+ * @namespace
+ */
+NamespaceA.NamespaceB = NamespaceA.NamespaceB || {};
+
+/**
+ * @const
+ * @namespace
+ */
+var NamespaceC = NamespaceC || {};
+
+/**
+ * @constructor
+ */
+NamespaceA.TableInFirstNS = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {NamespaceA.TableInFirstNS}
+ */
+NamespaceA.TableInFirstNS.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {NamespaceA.TableInFirstNS=} obj
+ * @returns {NamespaceA.TableInFirstNS}
+ */
+NamespaceA.TableInFirstNS.getRootAsTableInFirstNS = function(bb, obj) {
+  return (obj || new NamespaceA.TableInFirstNS).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {NamespaceA.TableInFirstNS=} obj
+ * @returns {NamespaceA.TableInFirstNS}
+ */
+NamespaceA.TableInFirstNS.getSizePrefixedRootAsTableInFirstNS = function(bb, obj) {
+  return (obj || new NamespaceA.TableInFirstNS).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {NamespaceA.NamespaceB.TableInNestedNS=} obj
+ * @returns {NamespaceA.NamespaceB.TableInNestedNS|null}
+ */
+NamespaceA.TableInFirstNS.prototype.fooTable = function(obj) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+  return offset ? (obj || new NamespaceA.NamespaceB.TableInNestedNS).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
+};
+
+/**
+ * @returns {NamespaceA.NamespaceB.EnumInNestedNS}
+ */
+NamespaceA.TableInFirstNS.prototype.fooEnum = function() {
+  var offset = this.bb.__offset(this.bb_pos, 6);
+  return offset ? /** @type {NamespaceA.NamespaceB.EnumInNestedNS} */ (this.bb.readInt8(this.bb_pos + offset)) : NamespaceA.NamespaceB.EnumInNestedNS.A;
+};
+
+/**
+ * @param {NamespaceA.NamespaceB.EnumInNestedNS} value
+ * @returns {boolean}
+ */
+NamespaceA.TableInFirstNS.prototype.mutate_foo_enum = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 6);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {NamespaceA.NamespaceB.StructInNestedNS=} obj
+ * @returns {NamespaceA.NamespaceB.StructInNestedNS|null}
+ */
+NamespaceA.TableInFirstNS.prototype.fooStruct = function(obj) {
+  var offset = this.bb.__offset(this.bb_pos, 8);
+  return offset ? (obj || new NamespaceA.NamespaceB.StructInNestedNS).__init(this.bb_pos + offset, this.bb) : null;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ */
+NamespaceA.TableInFirstNS.startTableInFirstNS = function(builder) {
+  builder.startObject(3);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} fooTableOffset
+ */
+NamespaceA.TableInFirstNS.addFooTable = function(builder, fooTableOffset) {
+  builder.addFieldOffset(0, fooTableOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {NamespaceA.NamespaceB.EnumInNestedNS} fooEnum
+ */
+NamespaceA.TableInFirstNS.addFooEnum = function(builder, fooEnum) {
+  builder.addFieldInt8(1, fooEnum, NamespaceA.NamespaceB.EnumInNestedNS.A);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} fooStructOffset
+ */
+NamespaceA.TableInFirstNS.addFooStruct = function(builder, fooStructOffset) {
+  builder.addFieldStruct(2, fooStructOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+NamespaceA.TableInFirstNS.endTableInFirstNS = function(builder) {
+  var offset = builder.endObject();
+  return offset;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} fooTableOffset
+ * @param {NS8755221360535654258.NamespaceA.NamespaceB.EnumInNestedNS} fooEnum
+ * @param {flatbuffers.Offset} fooStructOffset
+ * @returns {flatbuffers.Offset}
+ */
+NamespaceA.TableInFirstNS.createTableInFirstNS = function(builder, fooTableOffset, fooEnum, fooStructOffset) {
+  NamespaceA.TableInFirstNS.startTableInFirstNS(builder);
+  NamespaceA.TableInFirstNS.addFooTable(builder, fooTableOffset);
+  NamespaceA.TableInFirstNS.addFooEnum(builder, fooEnum);
+  NamespaceA.TableInFirstNS.addFooStruct(builder, fooStructOffset);
+  return NamespaceA.TableInFirstNS.endTableInFirstNS(builder);
+}
+
+/**
+ * @constructor
+ */
+NamespaceC.TableInC = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {NamespaceC.TableInC}
+ */
+NamespaceC.TableInC.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {NamespaceC.TableInC=} obj
+ * @returns {NamespaceC.TableInC}
+ */
+NamespaceC.TableInC.getRootAsTableInC = function(bb, obj) {
+  return (obj || new NamespaceC.TableInC).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {NamespaceC.TableInC=} obj
+ * @returns {NamespaceC.TableInC}
+ */
+NamespaceC.TableInC.getSizePrefixedRootAsTableInC = function(bb, obj) {
+  return (obj || new NamespaceC.TableInC).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {NamespaceA.TableInFirstNS=} obj
+ * @returns {NamespaceA.TableInFirstNS|null}
+ */
+NamespaceC.TableInC.prototype.referToA1 = function(obj) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+  return offset ? (obj || new NamespaceA.TableInFirstNS).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
+};
+
+/**
+ * @param {NamespaceA.SecondTableInA=} obj
+ * @returns {NamespaceA.SecondTableInA|null}
+ */
+NamespaceC.TableInC.prototype.referToA2 = function(obj) {
+  var offset = this.bb.__offset(this.bb_pos, 6);
+  return offset ? (obj || new NamespaceA.SecondTableInA).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ */
+NamespaceC.TableInC.startTableInC = function(builder) {
+  builder.startObject(2);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} referToA1Offset
+ */
+NamespaceC.TableInC.addReferToA1 = function(builder, referToA1Offset) {
+  builder.addFieldOffset(0, referToA1Offset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} referToA2Offset
+ */
+NamespaceC.TableInC.addReferToA2 = function(builder, referToA2Offset) {
+  builder.addFieldOffset(1, referToA2Offset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+NamespaceC.TableInC.endTableInC = function(builder) {
+  var offset = builder.endObject();
+  return offset;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} referToA1Offset
+ * @param {flatbuffers.Offset} referToA2Offset
+ * @returns {flatbuffers.Offset}
+ */
+NamespaceC.TableInC.createTableInC = function(builder, referToA1Offset, referToA2Offset) {
+  NamespaceC.TableInC.startTableInC(builder);
+  NamespaceC.TableInC.addReferToA1(builder, referToA1Offset);
+  NamespaceC.TableInC.addReferToA2(builder, referToA2Offset);
+  return NamespaceC.TableInC.endTableInC(builder);
+}
+
+/**
+ * @constructor
+ */
+NamespaceA.SecondTableInA = function() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+};
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {NamespaceA.SecondTableInA}
+ */
+NamespaceA.SecondTableInA.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {NamespaceA.SecondTableInA=} obj
+ * @returns {NamespaceA.SecondTableInA}
+ */
+NamespaceA.SecondTableInA.getRootAsSecondTableInA = function(bb, obj) {
+  return (obj || new NamespaceA.SecondTableInA).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {NamespaceA.SecondTableInA=} obj
+ * @returns {NamespaceA.SecondTableInA}
+ */
+NamespaceA.SecondTableInA.getSizePrefixedRootAsSecondTableInA = function(bb, obj) {
+  return (obj || new NamespaceA.SecondTableInA).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {NamespaceC.TableInC=} obj
+ * @returns {NamespaceC.TableInC|null}
+ */
+NamespaceA.SecondTableInA.prototype.referToC = function(obj) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+  return offset ? (obj || new NamespaceC.TableInC).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ */
+NamespaceA.SecondTableInA.startSecondTableInA = function(builder) {
+  builder.startObject(1);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} referToCOffset
+ */
+NamespaceA.SecondTableInA.addReferToC = function(builder, referToCOffset) {
+  builder.addFieldOffset(0, referToCOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+NamespaceA.SecondTableInA.endSecondTableInA = function(builder) {
+  var offset = builder.endObject();
+  return offset;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} referToCOffset
+ * @returns {flatbuffers.Offset}
+ */
+NamespaceA.SecondTableInA.createSecondTableInA = function(builder, referToCOffset) {
+  NamespaceA.SecondTableInA.startSecondTableInA(builder);
+  NamespaceA.SecondTableInA.addReferToC(builder, referToCOffset);
+  return NamespaceA.SecondTableInA.endSecondTableInA(builder);
+}
+
+// Exports for Node.js and RequireJS
+this.NamespaceA = NamespaceA;
+this.NamespaceC = NamespaceC;
diff --git a/third_party/flatbuffers/tests/namespace_test/namespace_test2_generated.lobster b/third_party/flatbuffers/tests/namespace_test/namespace_test2_generated.lobster
new file mode 100644
index 0000000..4383e68
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/namespace_test2_generated.lobster
@@ -0,0 +1,90 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+import flatbuffers
+
+namespace NamespaceA
+
+class TableInFirstNS
+
+namespace NamespaceC
+
+class TableInC
+
+namespace NamespaceA
+
+class SecondTableInA
+
+class TableInFirstNS : flatbuffers_handle
+    def foo_table():
+        let o = buf_.flatbuffers_field_table(pos_, 4)
+        return if o: NamespaceA_NamespaceB_TableInNestedNS { buf_, o } else: nil
+    def foo_enum():
+        return EnumInNestedNS(buf_.flatbuffers_field_int8(pos_, 6, 0))
+    def foo_struct():
+        let o = buf_.flatbuffers_field_struct(pos_, 8)
+        return if o: NamespaceA_NamespaceB_StructInNestedNS { buf_, o } else: nil
+
+def GetRootAsTableInFirstNS(buf:string): return TableInFirstNS { buf, buf.flatbuffers_indirect(0) }
+
+struct TableInFirstNSBuilder:
+    b_:flatbuffers_builder
+    def start():
+        b_.StartObject(3)
+        return this
+    def add_foo_table(foo_table:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(0, foo_table)
+        return this
+    def add_foo_enum(foo_enum:EnumInNestedNS):
+        b_.PrependInt8Slot(1, foo_enum, 0)
+        return this
+    def add_foo_struct(foo_struct:flatbuffers_offset):
+        b_.PrependStructSlot(2, foo_struct)
+        return this
+    def end():
+        return b_.EndObject()
+
+namespace NamespaceC
+
+class TableInC : flatbuffers_handle
+    def refer_to_a1():
+        let o = buf_.flatbuffers_field_table(pos_, 4)
+        return if o: NamespaceA_TableInFirstNS { buf_, o } else: nil
+    def refer_to_a2():
+        let o = buf_.flatbuffers_field_table(pos_, 6)
+        return if o: NamespaceA_SecondTableInA { buf_, o } else: nil
+
+def GetRootAsTableInC(buf:string): return TableInC { buf, buf.flatbuffers_indirect(0) }
+
+struct TableInCBuilder:
+    b_:flatbuffers_builder
+    def start():
+        b_.StartObject(2)
+        return this
+    def add_refer_to_a1(refer_to_a1:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(0, refer_to_a1)
+        return this
+    def add_refer_to_a2(refer_to_a2:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(1, refer_to_a2)
+        return this
+    def end():
+        return b_.EndObject()
+
+namespace NamespaceA
+
+class SecondTableInA : flatbuffers_handle
+    def refer_to_c():
+        let o = buf_.flatbuffers_field_table(pos_, 4)
+        return if o: NamespaceC_TableInC { buf_, o } else: nil
+
+def GetRootAsSecondTableInA(buf:string): return SecondTableInA { buf, buf.flatbuffers_indirect(0) }
+
+struct SecondTableInABuilder:
+    b_:flatbuffers_builder
+    def start():
+        b_.StartObject(1)
+        return this
+    def add_refer_to_c(refer_to_c:flatbuffers_offset):
+        b_.PrependUOffsetTRelativeSlot(0, refer_to_c)
+        return this
+    def end():
+        return b_.EndObject()
+
diff --git a/third_party/flatbuffers/tests/namespace_test/namespace_test2_generated.rs b/third_party/flatbuffers/tests/namespace_test/namespace_test2_generated.rs
new file mode 100644
index 0000000..3c04c0f
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/namespace_test2_generated.rs
@@ -0,0 +1,296 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+
+use std::mem;
+use std::cmp::Ordering;
+
+extern crate flatbuffers;
+use self::flatbuffers::EndianScalar;
+
+#[allow(unused_imports, dead_code)]
+pub mod namespace_a {
+
+  use std::mem;
+  use std::cmp::Ordering;
+
+  extern crate flatbuffers;
+  use self::flatbuffers::EndianScalar;
+
+pub enum TableInFirstNSOffset {}
+#[derive(Copy, Clone, Debug, PartialEq)]
+
+pub struct TableInFirstNS<'a> {
+  pub _tab: flatbuffers::Table<'a>,
+}
+
+impl<'a> flatbuffers::Follow<'a> for TableInFirstNS<'a> {
+    type Inner = TableInFirstNS<'a>;
+    #[inline]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        Self {
+            _tab: flatbuffers::Table { buf: buf, loc: loc },
+        }
+    }
+}
+
+impl<'a> TableInFirstNS<'a> {
+    #[inline]
+    pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
+        TableInFirstNS {
+            _tab: table,
+        }
+    }
+    #[allow(unused_mut)]
+    pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
+        _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
+        args: &'args TableInFirstNSArgs<'args>) -> flatbuffers::WIPOffset<TableInFirstNS<'bldr>> {
+      let mut builder = TableInFirstNSBuilder::new(_fbb);
+      if let Some(x) = args.foo_struct { builder.add_foo_struct(x); }
+      if let Some(x) = args.foo_table { builder.add_foo_table(x); }
+      builder.add_foo_enum(args.foo_enum);
+      builder.finish()
+    }
+
+    pub const VT_FOO_TABLE: flatbuffers::VOffsetT = 4;
+    pub const VT_FOO_ENUM: flatbuffers::VOffsetT = 6;
+    pub const VT_FOO_STRUCT: flatbuffers::VOffsetT = 8;
+
+  #[inline]
+  pub fn foo_table(&self) -> Option<namespace_b::TableInNestedNS<'a>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<namespace_b::TableInNestedNS<'a>>>(TableInFirstNS::VT_FOO_TABLE, None)
+  }
+  #[inline]
+  pub fn foo_enum(&self) -> namespace_b::EnumInNestedNS {
+    self._tab.get::<namespace_b::EnumInNestedNS>(TableInFirstNS::VT_FOO_ENUM, Some(namespace_b::EnumInNestedNS::A)).unwrap()
+  }
+  #[inline]
+  pub fn foo_struct(&self) -> Option<&'a namespace_b::StructInNestedNS> {
+    self._tab.get::<namespace_b::StructInNestedNS>(TableInFirstNS::VT_FOO_STRUCT, None)
+  }
+}
+
+pub struct TableInFirstNSArgs<'a> {
+    pub foo_table: Option<flatbuffers::WIPOffset<namespace_b::TableInNestedNS<'a >>>,
+    pub foo_enum: namespace_b::EnumInNestedNS,
+    pub foo_struct: Option<&'a  namespace_b::StructInNestedNS>,
+}
+impl<'a> Default for TableInFirstNSArgs<'a> {
+    #[inline]
+    fn default() -> Self {
+        TableInFirstNSArgs {
+            foo_table: None,
+            foo_enum: namespace_b::EnumInNestedNS::A,
+            foo_struct: None,
+        }
+    }
+}
+pub struct TableInFirstNSBuilder<'a: 'b, 'b> {
+  fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+  start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
+}
+impl<'a: 'b, 'b> TableInFirstNSBuilder<'a, 'b> {
+  #[inline]
+  pub fn add_foo_table(&mut self, foo_table: flatbuffers::WIPOffset<namespace_b::TableInNestedNS<'b >>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<namespace_b::TableInNestedNS>>(TableInFirstNS::VT_FOO_TABLE, foo_table);
+  }
+  #[inline]
+  pub fn add_foo_enum(&mut self, foo_enum: namespace_b::EnumInNestedNS) {
+    self.fbb_.push_slot::<namespace_b::EnumInNestedNS>(TableInFirstNS::VT_FOO_ENUM, foo_enum, namespace_b::EnumInNestedNS::A);
+  }
+  #[inline]
+  pub fn add_foo_struct(&mut self, foo_struct: &'b  namespace_b::StructInNestedNS) {
+    self.fbb_.push_slot_always::<&namespace_b::StructInNestedNS>(TableInFirstNS::VT_FOO_STRUCT, foo_struct);
+  }
+  #[inline]
+  pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> TableInFirstNSBuilder<'a, 'b> {
+    let start = _fbb.start_table();
+    TableInFirstNSBuilder {
+      fbb_: _fbb,
+      start_: start,
+    }
+  }
+  #[inline]
+  pub fn finish(self) -> flatbuffers::WIPOffset<TableInFirstNS<'a>> {
+    let o = self.fbb_.end_table(self.start_);
+    flatbuffers::WIPOffset::new(o.value())
+  }
+}
+
+pub enum SecondTableInAOffset {}
+#[derive(Copy, Clone, Debug, PartialEq)]
+
+pub struct SecondTableInA<'a> {
+  pub _tab: flatbuffers::Table<'a>,
+}
+
+impl<'a> flatbuffers::Follow<'a> for SecondTableInA<'a> {
+    type Inner = SecondTableInA<'a>;
+    #[inline]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        Self {
+            _tab: flatbuffers::Table { buf: buf, loc: loc },
+        }
+    }
+}
+
+impl<'a> SecondTableInA<'a> {
+    #[inline]
+    pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
+        SecondTableInA {
+            _tab: table,
+        }
+    }
+    #[allow(unused_mut)]
+    pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
+        _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
+        args: &'args SecondTableInAArgs<'args>) -> flatbuffers::WIPOffset<SecondTableInA<'bldr>> {
+      let mut builder = SecondTableInABuilder::new(_fbb);
+      if let Some(x) = args.refer_to_c { builder.add_refer_to_c(x); }
+      builder.finish()
+    }
+
+    pub const VT_REFER_TO_C: flatbuffers::VOffsetT = 4;
+
+  #[inline]
+  pub fn refer_to_c(&self) -> Option<super::namespace_c::TableInC<'a>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<super::namespace_c::TableInC<'a>>>(SecondTableInA::VT_REFER_TO_C, None)
+  }
+}
+
+pub struct SecondTableInAArgs<'a> {
+    pub refer_to_c: Option<flatbuffers::WIPOffset<super::namespace_c::TableInC<'a >>>,
+}
+impl<'a> Default for SecondTableInAArgs<'a> {
+    #[inline]
+    fn default() -> Self {
+        SecondTableInAArgs {
+            refer_to_c: None,
+        }
+    }
+}
+pub struct SecondTableInABuilder<'a: 'b, 'b> {
+  fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+  start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
+}
+impl<'a: 'b, 'b> SecondTableInABuilder<'a, 'b> {
+  #[inline]
+  pub fn add_refer_to_c(&mut self, refer_to_c: flatbuffers::WIPOffset<super::namespace_c::TableInC<'b >>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<super::namespace_c::TableInC>>(SecondTableInA::VT_REFER_TO_C, refer_to_c);
+  }
+  #[inline]
+  pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> SecondTableInABuilder<'a, 'b> {
+    let start = _fbb.start_table();
+    SecondTableInABuilder {
+      fbb_: _fbb,
+      start_: start,
+    }
+  }
+  #[inline]
+  pub fn finish(self) -> flatbuffers::WIPOffset<SecondTableInA<'a>> {
+    let o = self.fbb_.end_table(self.start_);
+    flatbuffers::WIPOffset::new(o.value())
+  }
+}
+
+}  // pub mod NamespaceA
+
+#[allow(unused_imports, dead_code)]
+pub mod namespace_c {
+
+  use std::mem;
+  use std::cmp::Ordering;
+
+  extern crate flatbuffers;
+  use self::flatbuffers::EndianScalar;
+
+pub enum TableInCOffset {}
+#[derive(Copy, Clone, Debug, PartialEq)]
+
+pub struct TableInC<'a> {
+  pub _tab: flatbuffers::Table<'a>,
+}
+
+impl<'a> flatbuffers::Follow<'a> for TableInC<'a> {
+    type Inner = TableInC<'a>;
+    #[inline]
+    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        Self {
+            _tab: flatbuffers::Table { buf: buf, loc: loc },
+        }
+    }
+}
+
+impl<'a> TableInC<'a> {
+    #[inline]
+    pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
+        TableInC {
+            _tab: table,
+        }
+    }
+    #[allow(unused_mut)]
+    pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
+        _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
+        args: &'args TableInCArgs<'args>) -> flatbuffers::WIPOffset<TableInC<'bldr>> {
+      let mut builder = TableInCBuilder::new(_fbb);
+      if let Some(x) = args.refer_to_a2 { builder.add_refer_to_a2(x); }
+      if let Some(x) = args.refer_to_a1 { builder.add_refer_to_a1(x); }
+      builder.finish()
+    }
+
+    pub const VT_REFER_TO_A1: flatbuffers::VOffsetT = 4;
+    pub const VT_REFER_TO_A2: flatbuffers::VOffsetT = 6;
+
+  #[inline]
+  pub fn refer_to_a1(&self) -> Option<super::namespace_a::TableInFirstNS<'a>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<super::namespace_a::TableInFirstNS<'a>>>(TableInC::VT_REFER_TO_A1, None)
+  }
+  #[inline]
+  pub fn refer_to_a2(&self) -> Option<super::namespace_a::SecondTableInA<'a>> {
+    self._tab.get::<flatbuffers::ForwardsUOffset<super::namespace_a::SecondTableInA<'a>>>(TableInC::VT_REFER_TO_A2, None)
+  }
+}
+
+pub struct TableInCArgs<'a> {
+    pub refer_to_a1: Option<flatbuffers::WIPOffset<super::namespace_a::TableInFirstNS<'a >>>,
+    pub refer_to_a2: Option<flatbuffers::WIPOffset<super::namespace_a::SecondTableInA<'a >>>,
+}
+impl<'a> Default for TableInCArgs<'a> {
+    #[inline]
+    fn default() -> Self {
+        TableInCArgs {
+            refer_to_a1: None,
+            refer_to_a2: None,
+        }
+    }
+}
+pub struct TableInCBuilder<'a: 'b, 'b> {
+  fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+  start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
+}
+impl<'a: 'b, 'b> TableInCBuilder<'a, 'b> {
+  #[inline]
+  pub fn add_refer_to_a1(&mut self, refer_to_a1: flatbuffers::WIPOffset<super::namespace_a::TableInFirstNS<'b >>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<super::namespace_a::TableInFirstNS>>(TableInC::VT_REFER_TO_A1, refer_to_a1);
+  }
+  #[inline]
+  pub fn add_refer_to_a2(&mut self, refer_to_a2: flatbuffers::WIPOffset<super::namespace_a::SecondTableInA<'b >>) {
+    self.fbb_.push_slot_always::<flatbuffers::WIPOffset<super::namespace_a::SecondTableInA>>(TableInC::VT_REFER_TO_A2, refer_to_a2);
+  }
+  #[inline]
+  pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> TableInCBuilder<'a, 'b> {
+    let start = _fbb.start_table();
+    TableInCBuilder {
+      fbb_: _fbb,
+      start_: start,
+    }
+  }
+  #[inline]
+  pub fn finish(self) -> flatbuffers::WIPOffset<TableInC<'a>> {
+    let o = self.fbb_.end_table(self.start_);
+    flatbuffers::WIPOffset::new(o.value())
+  }
+}
+
+}  // pub mod NamespaceC
+
diff --git a/third_party/flatbuffers/tests/namespace_test/namespace_test2_generated.ts b/third_party/flatbuffers/tests/namespace_test/namespace_test2_generated.ts
new file mode 100644
index 0000000..7bd0543
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/namespace_test2_generated.ts
@@ -0,0 +1,302 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+import * as NS8755221360535654258 from "./namespace_test1_generated";
+/**
+ * @constructor
+ */
+export namespace NamespaceA{
+export class TableInFirstNS {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns TableInFirstNS
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):TableInFirstNS {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param TableInFirstNS= obj
+ * @returns TableInFirstNS
+ */
+static getRootAsTableInFirstNS(bb:flatbuffers.ByteBuffer, obj?:TableInFirstNS):TableInFirstNS {
+  return (obj || new TableInFirstNS).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param TableInFirstNS= obj
+ * @returns TableInFirstNS
+ */
+static getSizePrefixedRootAsTableInFirstNS(bb:flatbuffers.ByteBuffer, obj?:TableInFirstNS):TableInFirstNS {
+  return (obj || new TableInFirstNS).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param NamespaceA.NamespaceB.TableInNestedNS= obj
+ * @returns NamespaceA.NamespaceB.TableInNestedNS|null
+ */
+fooTable(obj?:NS8755221360535654258.NamespaceA.NamespaceB.TableInNestedNS):NS8755221360535654258.NamespaceA.NamespaceB.TableInNestedNS|null {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+  return offset ? (obj || new NS8755221360535654258.NamespaceA.NamespaceB.TableInNestedNS).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
+};
+
+/**
+ * @returns NamespaceA.NamespaceB.EnumInNestedNS
+ */
+fooEnum():NS8755221360535654258.NamespaceA.NamespaceB.EnumInNestedNS {
+  var offset = this.bb!.__offset(this.bb_pos, 6);
+  return offset ? /**  */ (this.bb!.readInt8(this.bb_pos + offset)) : NS8755221360535654258.NamespaceA.NamespaceB.EnumInNestedNS.A;
+};
+
+/**
+ * @param NamespaceA.NamespaceB.EnumInNestedNS value
+ * @returns boolean
+ */
+mutate_foo_enum(value:NS8755221360535654258.NamespaceA.NamespaceB.EnumInNestedNS):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 6);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param NamespaceA.NamespaceB.StructInNestedNS= obj
+ * @returns NamespaceA.NamespaceB.StructInNestedNS|null
+ */
+fooStruct(obj?:NS8755221360535654258.NamespaceA.NamespaceB.StructInNestedNS):NS8755221360535654258.NamespaceA.NamespaceB.StructInNestedNS|null {
+  var offset = this.bb!.__offset(this.bb_pos, 8);
+  return offset ? (obj || new NS8755221360535654258.NamespaceA.NamespaceB.StructInNestedNS).__init(this.bb_pos + offset, this.bb!) : null;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ */
+static startTableInFirstNS(builder:flatbuffers.Builder) {
+  builder.startObject(3);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset fooTableOffset
+ */
+static addFooTable(builder:flatbuffers.Builder, fooTableOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(0, fooTableOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param NamespaceA.NamespaceB.EnumInNestedNS fooEnum
+ */
+static addFooEnum(builder:flatbuffers.Builder, fooEnum:NS8755221360535654258.NamespaceA.NamespaceB.EnumInNestedNS) {
+  builder.addFieldInt8(1, fooEnum, NS8755221360535654258.NamespaceA.NamespaceB.EnumInNestedNS.A);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset fooStructOffset
+ */
+static addFooStruct(builder:flatbuffers.Builder, fooStructOffset:flatbuffers.Offset) {
+  builder.addFieldStruct(2, fooStructOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @returns flatbuffers.Offset
+ */
+static endTableInFirstNS(builder:flatbuffers.Builder):flatbuffers.Offset {
+  var offset = builder.endObject();
+  return offset;
+};
+
+static createTableInFirstNS(builder:flatbuffers.Builder, fooTableOffset:flatbuffers.Offset, fooEnum:NS8755221360535654258.NamespaceA.NamespaceB.EnumInNestedNS, fooStructOffset:flatbuffers.Offset):flatbuffers.Offset {
+  TableInFirstNS.startTableInFirstNS(builder);
+  TableInFirstNS.addFooTable(builder, fooTableOffset);
+  TableInFirstNS.addFooEnum(builder, fooEnum);
+  TableInFirstNS.addFooStruct(builder, fooStructOffset);
+  return TableInFirstNS.endTableInFirstNS(builder);
+}
+}
+}
+/**
+ * @constructor
+ */
+export namespace NamespaceC{
+export class TableInC {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns TableInC
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):TableInC {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param TableInC= obj
+ * @returns TableInC
+ */
+static getRootAsTableInC(bb:flatbuffers.ByteBuffer, obj?:TableInC):TableInC {
+  return (obj || new TableInC).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param TableInC= obj
+ * @returns TableInC
+ */
+static getSizePrefixedRootAsTableInC(bb:flatbuffers.ByteBuffer, obj?:TableInC):TableInC {
+  return (obj || new TableInC).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param NamespaceA.TableInFirstNS= obj
+ * @returns NamespaceA.TableInFirstNS|null
+ */
+referToA1(obj?:NamespaceA.TableInFirstNS):NamespaceA.TableInFirstNS|null {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+  return offset ? (obj || new NamespaceA.TableInFirstNS).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
+};
+
+/**
+ * @param NamespaceA.SecondTableInA= obj
+ * @returns NamespaceA.SecondTableInA|null
+ */
+referToA2(obj?:NamespaceA.SecondTableInA):NamespaceA.SecondTableInA|null {
+  var offset = this.bb!.__offset(this.bb_pos, 6);
+  return offset ? (obj || new NamespaceA.SecondTableInA).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ */
+static startTableInC(builder:flatbuffers.Builder) {
+  builder.startObject(2);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset referToA1Offset
+ */
+static addReferToA1(builder:flatbuffers.Builder, referToA1Offset:flatbuffers.Offset) {
+  builder.addFieldOffset(0, referToA1Offset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset referToA2Offset
+ */
+static addReferToA2(builder:flatbuffers.Builder, referToA2Offset:flatbuffers.Offset) {
+  builder.addFieldOffset(1, referToA2Offset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @returns flatbuffers.Offset
+ */
+static endTableInC(builder:flatbuffers.Builder):flatbuffers.Offset {
+  var offset = builder.endObject();
+  return offset;
+};
+
+static createTableInC(builder:flatbuffers.Builder, referToA1Offset:flatbuffers.Offset, referToA2Offset:flatbuffers.Offset):flatbuffers.Offset {
+  TableInC.startTableInC(builder);
+  TableInC.addReferToA1(builder, referToA1Offset);
+  TableInC.addReferToA2(builder, referToA2Offset);
+  return TableInC.endTableInC(builder);
+}
+}
+}
+/**
+ * @constructor
+ */
+export namespace NamespaceA{
+export class SecondTableInA {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns SecondTableInA
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):SecondTableInA {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param SecondTableInA= obj
+ * @returns SecondTableInA
+ */
+static getRootAsSecondTableInA(bb:flatbuffers.ByteBuffer, obj?:SecondTableInA):SecondTableInA {
+  return (obj || new SecondTableInA).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param SecondTableInA= obj
+ * @returns SecondTableInA
+ */
+static getSizePrefixedRootAsSecondTableInA(bb:flatbuffers.ByteBuffer, obj?:SecondTableInA):SecondTableInA {
+  return (obj || new SecondTableInA).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param NamespaceC.TableInC= obj
+ * @returns NamespaceC.TableInC|null
+ */
+referToC(obj?:NamespaceC.TableInC):NamespaceC.TableInC|null {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+  return offset ? (obj || new NamespaceC.TableInC).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ */
+static startSecondTableInA(builder:flatbuffers.Builder) {
+  builder.startObject(1);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset referToCOffset
+ */
+static addReferToC(builder:flatbuffers.Builder, referToCOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(0, referToCOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @returns flatbuffers.Offset
+ */
+static endSecondTableInA(builder:flatbuffers.Builder):flatbuffers.Offset {
+  var offset = builder.endObject();
+  return offset;
+};
+
+static createSecondTableInA(builder:flatbuffers.Builder, referToCOffset:flatbuffers.Offset):flatbuffers.Offset {
+  SecondTableInA.startSecondTableInA(builder);
+  SecondTableInA.addReferToC(builder, referToCOffset);
+  return SecondTableInA.endSecondTableInA(builder);
+}
+}
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/namespace_test2_namespace_a_generated.dart b/third_party/flatbuffers/tests/namespace_test/namespace_test2_namespace_a_generated.dart
new file mode 100644
index 0000000..d5108eb
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/namespace_test2_namespace_a_generated.dart
@@ -0,0 +1,189 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+// ignore_for_file: unused_import, unused_field, unused_local_variable
+
+library namespace_a;
+
+import 'dart:typed_data' show Uint8List;
+import 'package:flat_buffers/flat_buffers.dart' as fb;
+
+import 'namespace_test1_namespace_a_generated.dart';
+import './namespace_test2_namespace_c_generated.dart' as namespace_c;
+
+class TableInFirstNS {
+  TableInFirstNS._(this._bc, this._bcOffset);
+  factory TableInFirstNS(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<TableInFirstNS> reader = const _TableInFirstNSReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  namespace_a_namespace_b.TableInNestedNS get fooTable => namespace_a_namespace_b.TableInNestedNS.reader.vTableGet(_bc, _bcOffset, 4, null);
+  EnumInNestedNS get fooEnum => new EnumInNestedNS.fromValue(const fb.Int8Reader().vTableGet(_bc, _bcOffset, 6, 0));
+  namespace_a_namespace_b.StructInNestedNS get fooStruct => namespace_a_namespace_b.StructInNestedNS.reader.vTableGet(_bc, _bcOffset, 8, null);
+
+  @override
+  String toString() {
+    return 'TableInFirstNS{fooTable: $fooTable, fooEnum: $fooEnum, fooStruct: $fooStruct}';
+  }
+}
+
+class _TableInFirstNSReader extends fb.TableReader<TableInFirstNS> {
+  const _TableInFirstNSReader();
+
+  @override
+  TableInFirstNS createObject(fb.BufferContext bc, int offset) => 
+    new TableInFirstNS._(bc, offset);
+}
+
+class TableInFirstNSBuilder {
+  TableInFirstNSBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  void begin() {
+    fbBuilder.startTable();
+  }
+
+  int addFooTableOffset(int offset) {
+    fbBuilder.addOffset(0, offset);
+    return fbBuilder.offset;
+  }
+  int addFooEnum(EnumInNestedNS fooEnum) {
+    fbBuilder.addInt8(1, fooEnum?.value);
+    return fbBuilder.offset;
+  }
+  int addFooStruct(int offset) {
+    fbBuilder.addStruct(2, offset);
+    return fbBuilder.offset;
+  }
+
+  int finish() {
+    return fbBuilder.endTable();
+  }
+}
+
+class TableInFirstNSObjectBuilder extends fb.ObjectBuilder {
+  final namespace_a_namespace_b.TableInNestedNSObjectBuilder _fooTable;
+  final EnumInNestedNS _fooEnum;
+  final namespace_a_namespace_b.StructInNestedNSObjectBuilder _fooStruct;
+
+  TableInFirstNSObjectBuilder({
+    namespace_a_namespace_b.TableInNestedNSObjectBuilder fooTable,
+    EnumInNestedNS fooEnum,
+    namespace_a_namespace_b.StructInNestedNSObjectBuilder fooStruct,
+  })
+      : _fooTable = fooTable,
+        _fooEnum = fooEnum,
+        _fooStruct = fooStruct;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+    final int fooTableOffset = _fooTable?.getOrCreateOffset(fbBuilder);
+
+    fbBuilder.startTable();
+    if (fooTableOffset != null) {
+      fbBuilder.addOffset(0, fooTableOffset);
+    }
+    fbBuilder.addInt8(1, _fooEnum?.value);
+    if (_fooStruct != null) {
+      fbBuilder.addStruct(2, _fooStruct.finish(fbBuilder));
+    }
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
+class SecondTableInA {
+  SecondTableInA._(this._bc, this._bcOffset);
+  factory SecondTableInA(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<SecondTableInA> reader = const _SecondTableInAReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  namespace_c.TableInC get referToC => namespace_c.TableInC.reader.vTableGet(_bc, _bcOffset, 4, null);
+
+  @override
+  String toString() {
+    return 'SecondTableInA{referToC: $referToC}';
+  }
+}
+
+class _SecondTableInAReader extends fb.TableReader<SecondTableInA> {
+  const _SecondTableInAReader();
+
+  @override
+  SecondTableInA createObject(fb.BufferContext bc, int offset) => 
+    new SecondTableInA._(bc, offset);
+}
+
+class SecondTableInABuilder {
+  SecondTableInABuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  void begin() {
+    fbBuilder.startTable();
+  }
+
+  int addReferToCOffset(int offset) {
+    fbBuilder.addOffset(0, offset);
+    return fbBuilder.offset;
+  }
+
+  int finish() {
+    return fbBuilder.endTable();
+  }
+}
+
+class SecondTableInAObjectBuilder extends fb.ObjectBuilder {
+  final namespace_c.TableInCObjectBuilder _referToC;
+
+  SecondTableInAObjectBuilder({
+    namespace_c.TableInCObjectBuilder referToC,
+  })
+      : _referToC = referToC;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+    final int referToCOffset = _referToC?.getOrCreateOffset(fbBuilder);
+
+    fbBuilder.startTable();
+    if (referToCOffset != null) {
+      fbBuilder.addOffset(0, referToCOffset);
+    }
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
diff --git a/third_party/flatbuffers/tests/namespace_test/namespace_test2_namespace_c_generated.dart b/third_party/flatbuffers/tests/namespace_test/namespace_test2_namespace_c_generated.dart
new file mode 100644
index 0000000..7214feb
--- /dev/null
+++ b/third_party/flatbuffers/tests/namespace_test/namespace_test2_namespace_c_generated.dart
@@ -0,0 +1,102 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+// ignore_for_file: unused_import, unused_field, unused_local_variable
+
+library namespace_c;
+
+import 'dart:typed_data' show Uint8List;
+import 'package:flat_buffers/flat_buffers.dart' as fb;
+
+import 'namespace_test1_namespace_c_generated.dart';
+import './namespace_test2_namespace_a_generated.dart' as namespace_a;
+
+class TableInC {
+  TableInC._(this._bc, this._bcOffset);
+  factory TableInC(List<int> bytes) {
+    fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+    return reader.read(rootRef, 0);
+  }
+
+  static const fb.Reader<TableInC> reader = const _TableInCReader();
+
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  namespace_a.TableInFirstNS get referToA1 => namespace_a.TableInFirstNS.reader.vTableGet(_bc, _bcOffset, 4, null);
+  namespace_a.SecondTableInA get referToA2 => namespace_a.SecondTableInA.reader.vTableGet(_bc, _bcOffset, 6, null);
+
+  @override
+  String toString() {
+    return 'TableInC{referToA1: $referToA1, referToA2: $referToA2}';
+  }
+}
+
+class _TableInCReader extends fb.TableReader<TableInC> {
+  const _TableInCReader();
+
+  @override
+  TableInC createObject(fb.BufferContext bc, int offset) => 
+    new TableInC._(bc, offset);
+}
+
+class TableInCBuilder {
+  TableInCBuilder(this.fbBuilder) {
+    assert(fbBuilder != null);
+  }
+
+  final fb.Builder fbBuilder;
+
+  void begin() {
+    fbBuilder.startTable();
+  }
+
+  int addReferToA1Offset(int offset) {
+    fbBuilder.addOffset(0, offset);
+    return fbBuilder.offset;
+  }
+  int addReferToA2Offset(int offset) {
+    fbBuilder.addOffset(1, offset);
+    return fbBuilder.offset;
+  }
+
+  int finish() {
+    return fbBuilder.endTable();
+  }
+}
+
+class TableInCObjectBuilder extends fb.ObjectBuilder {
+  final namespace_a.TableInFirstNSObjectBuilder _referToA1;
+  final namespace_a.SecondTableInAObjectBuilder _referToA2;
+
+  TableInCObjectBuilder({
+    namespace_a.TableInFirstNSObjectBuilder referToA1,
+    namespace_a.SecondTableInAObjectBuilder referToA2,
+  })
+      : _referToA1 = referToA1,
+        _referToA2 = referToA2;
+
+  /// Finish building, and store into the [fbBuilder].
+  @override
+  int finish(
+    fb.Builder fbBuilder) {
+    assert(fbBuilder != null);
+    final int referToA1Offset = _referToA1?.getOrCreateOffset(fbBuilder);
+    final int referToA2Offset = _referToA2?.getOrCreateOffset(fbBuilder);
+
+    fbBuilder.startTable();
+    if (referToA1Offset != null) {
+      fbBuilder.addOffset(0, referToA1Offset);
+    }
+    if (referToA2Offset != null) {
+      fbBuilder.addOffset(1, referToA2Offset);
+    }
+    return fbBuilder.endTable();
+  }
+
+  /// Convenience method to serialize to byte list.
+  @override
+  Uint8List toBytes([String fileIdentifier]) {
+    fb.Builder fbBuilder = new fb.Builder();
+    int offset = finish(fbBuilder);
+    return fbBuilder.finish(offset, fileIdentifier);
+  }
+}
diff --git a/third_party/flatbuffers/tests/native_type_test.fbs b/third_party/flatbuffers/tests/native_type_test.fbs
new file mode 100644
index 0000000..de80bdf
--- /dev/null
+++ b/third_party/flatbuffers/tests/native_type_test.fbs
@@ -0,0 +1,15 @@
+native_include "native_type_test_impl.h";
+
+namespace Geometry;
+
+struct Vector3D (native_type:"Native::Vector3D") {
+  x:float;
+  y:float;
+  z:float;
+}
+
+table ApplicationData {
+  vectors:[Vector3D];
+}
+
+root_type ApplicationData;
diff --git a/third_party/flatbuffers/tests/native_type_test_generated.h b/third_party/flatbuffers/tests/native_type_test_generated.h
new file mode 100644
index 0000000..9ba7c61
--- /dev/null
+++ b/third_party/flatbuffers/tests/native_type_test_generated.h
@@ -0,0 +1,238 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_NATIVETYPETEST_GEOMETRY_H_
+#define FLATBUFFERS_GENERATED_NATIVETYPETEST_GEOMETRY_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+#include "native_type_test_impl.h"
+
+namespace Geometry {
+
+struct Vector3D;
+
+struct ApplicationData;
+struct ApplicationDataT;
+
+inline const flatbuffers::TypeTable *Vector3DTypeTable();
+
+inline const flatbuffers::TypeTable *ApplicationDataTypeTable();
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Vector3D FLATBUFFERS_FINAL_CLASS {
+ private:
+  float x_;
+  float y_;
+  float z_;
+
+ public:
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return Vector3DTypeTable();
+  }
+  Vector3D() {
+    memset(static_cast<void *>(this), 0, sizeof(Vector3D));
+  }
+  Vector3D(float _x, float _y, float _z)
+      : x_(flatbuffers::EndianScalar(_x)),
+        y_(flatbuffers::EndianScalar(_y)),
+        z_(flatbuffers::EndianScalar(_z)) {
+  }
+  float x() const {
+    return flatbuffers::EndianScalar(x_);
+  }
+  void mutate_x(float _x) {
+    flatbuffers::WriteScalar(&x_, _x);
+  }
+  float y() const {
+    return flatbuffers::EndianScalar(y_);
+  }
+  void mutate_y(float _y) {
+    flatbuffers::WriteScalar(&y_, _y);
+  }
+  float z() const {
+    return flatbuffers::EndianScalar(z_);
+  }
+  void mutate_z(float _z) {
+    flatbuffers::WriteScalar(&z_, _z);
+  }
+};
+FLATBUFFERS_STRUCT_END(Vector3D, 12);
+
+struct ApplicationDataT : public flatbuffers::NativeTable {
+  typedef ApplicationData TableType;
+  std::vector<Native::Vector3D> vectors;
+  ApplicationDataT() {
+  }
+};
+
+struct ApplicationData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef ApplicationDataT NativeTableType;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return ApplicationDataTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_VECTORS = 4
+  };
+  const flatbuffers::Vector<const Geometry::Vector3D *> *vectors() const {
+    return GetPointer<const flatbuffers::Vector<const Geometry::Vector3D *> *>(VT_VECTORS);
+  }
+  flatbuffers::Vector<const Geometry::Vector3D *> *mutable_vectors() {
+    return GetPointer<flatbuffers::Vector<const Geometry::Vector3D *> *>(VT_VECTORS);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffset(verifier, VT_VECTORS) &&
+           verifier.VerifyVector(vectors()) &&
+           verifier.EndTable();
+  }
+  ApplicationDataT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(ApplicationDataT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<ApplicationData> Pack(flatbuffers::FlatBufferBuilder &_fbb, const ApplicationDataT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct ApplicationDataBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_vectors(flatbuffers::Offset<flatbuffers::Vector<const Geometry::Vector3D *>> vectors) {
+    fbb_.AddOffset(ApplicationData::VT_VECTORS, vectors);
+  }
+  explicit ApplicationDataBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  ApplicationDataBuilder &operator=(const ApplicationDataBuilder &);
+  flatbuffers::Offset<ApplicationData> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<ApplicationData>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<ApplicationData> CreateApplicationData(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<flatbuffers::Vector<const Geometry::Vector3D *>> vectors = 0) {
+  ApplicationDataBuilder builder_(_fbb);
+  builder_.add_vectors(vectors);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<ApplicationData> CreateApplicationDataDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const std::vector<Geometry::Vector3D> *vectors = nullptr) {
+  auto vectors__ = vectors ? _fbb.CreateVectorOfStructs<Geometry::Vector3D>(*vectors) : 0;
+  return Geometry::CreateApplicationData(
+      _fbb,
+      vectors__);
+}
+
+flatbuffers::Offset<ApplicationData> CreateApplicationData(flatbuffers::FlatBufferBuilder &_fbb, const ApplicationDataT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+inline ApplicationDataT *ApplicationData::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = new ApplicationDataT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+inline void ApplicationData::UnPackTo(ApplicationDataT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = vectors(); if (_e) { _o->vectors.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vectors[_i] = flatbuffers::UnPack(*_e->Get(_i)); } } };
+}
+
+inline flatbuffers::Offset<ApplicationData> ApplicationData::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ApplicationDataT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateApplicationData(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<ApplicationData> CreateApplicationData(flatbuffers::FlatBufferBuilder &_fbb, const ApplicationDataT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ApplicationDataT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _vectors = _o->vectors.size() ? _fbb.CreateVectorOfNativeStructs<Geometry::Vector3D>(_o->vectors) : 0;
+  return Geometry::CreateApplicationData(
+      _fbb,
+      _vectors);
+}
+
+inline const flatbuffers::TypeTable *Vector3DTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 }
+  };
+  static const int64_t values[] = { 0, 4, 8, 12 };
+  static const char * const names[] = {
+    "x",
+    "y",
+    "z"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_STRUCT, 3, type_codes, nullptr, values, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *ApplicationDataTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 1, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    Geometry::Vector3DTypeTable
+  };
+  static const char * const names[] = {
+    "vectors"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 1, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+inline const Geometry::ApplicationData *GetApplicationData(const void *buf) {
+  return flatbuffers::GetRoot<Geometry::ApplicationData>(buf);
+}
+
+inline const Geometry::ApplicationData *GetSizePrefixedApplicationData(const void *buf) {
+  return flatbuffers::GetSizePrefixedRoot<Geometry::ApplicationData>(buf);
+}
+
+inline ApplicationData *GetMutableApplicationData(void *buf) {
+  return flatbuffers::GetMutableRoot<ApplicationData>(buf);
+}
+
+inline bool VerifyApplicationDataBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifyBuffer<Geometry::ApplicationData>(nullptr);
+}
+
+inline bool VerifySizePrefixedApplicationDataBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifySizePrefixedBuffer<Geometry::ApplicationData>(nullptr);
+}
+
+inline void FinishApplicationDataBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<Geometry::ApplicationData> root) {
+  fbb.Finish(root);
+}
+
+inline void FinishSizePrefixedApplicationDataBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<Geometry::ApplicationData> root) {
+  fbb.FinishSizePrefixed(root);
+}
+
+inline flatbuffers::unique_ptr<Geometry::ApplicationDataT> UnPackApplicationData(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return flatbuffers::unique_ptr<Geometry::ApplicationDataT>(GetApplicationData(buf)->UnPack(res));
+}
+
+inline flatbuffers::unique_ptr<Geometry::ApplicationDataT> UnPackSizePrefixedApplicationData(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return flatbuffers::unique_ptr<Geometry::ApplicationDataT>(GetSizePrefixedApplicationData(buf)->UnPack(res));
+}
+
+}  // namespace Geometry
+
+#endif  // FLATBUFFERS_GENERATED_NATIVETYPETEST_GEOMETRY_H_
diff --git a/third_party/flatbuffers/tests/native_type_test_impl.cpp b/third_party/flatbuffers/tests/native_type_test_impl.cpp
new file mode 100644
index 0000000..04ddb96
--- /dev/null
+++ b/third_party/flatbuffers/tests/native_type_test_impl.cpp
@@ -0,0 +1,13 @@
+#include "native_type_test_impl.h"
+#include "native_type_test_generated.h"
+
+namespace flatbuffers {
+  Geometry::Vector3D Pack(const Native::Vector3D &obj) {
+    return Geometry::Vector3D(obj.x, obj.y, obj.z);
+  }
+
+  const Native::Vector3D UnPack(const Geometry::Vector3D &obj) {
+    return Native::Vector3D(obj.x(), obj.y(), obj.z());
+  }
+}
+
diff --git a/third_party/flatbuffers/tests/native_type_test_impl.h b/third_party/flatbuffers/tests/native_type_test_impl.h
new file mode 100644
index 0000000..2473ad3
--- /dev/null
+++ b/third_party/flatbuffers/tests/native_type_test_impl.h
@@ -0,0 +1,24 @@
+#ifndef NATIVE_TYPE_TEST_IMPL_H
+#define NATIVE_TYPE_TEST_IMPL_H
+
+namespace Native {
+  struct Vector3D {
+    float x;
+    float y;
+    float z;
+
+    Vector3D() { x = 0; y = 0; z = 0; };
+    Vector3D(float _x, float _y, float _z) { this->x = _x; this->y = _y; this->z = _z; }
+  };
+}
+
+namespace Geometry { 
+  struct Vector3D;
+}
+
+namespace flatbuffers {
+  Geometry::Vector3D Pack(const Native::Vector3D &obj);
+  const Native::Vector3D UnPack(const Geometry::Vector3D &obj);
+}
+
+#endif // VECTOR3D_PACK_H
diff --git a/third_party/flatbuffers/tests/phpTest.php b/third_party/flatbuffers/tests/phpTest.php
new file mode 100644
index 0000000..c1447c2
--- /dev/null
+++ b/third_party/flatbuffers/tests/phpTest.php
@@ -0,0 +1,632 @@
+<?php
+// manual load for testing. please use PSR style autoloader when you use flatbuffers.
+require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "Constants.php"));
+require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "ByteBuffer.php"));
+require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "FlatbufferBuilder.php"));
+require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "Table.php"));
+require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "Struct.php"));
+foreach (glob(join(DIRECTORY_SEPARATOR, array(dirname(__FILE__), "MyGame", "Example", "*.php"))) as $file) {
+    require $file;
+}
+
+function main()
+{
+    /// Begin Test
+    $assert = new Assert();
+
+    // First, let's test reading a FlatBuffer generated by C++ code:
+    // This file was generated from monsterdata_test.json
+
+    // Now test it:
+    $data = file_get_contents('monsterdata_test.mon');
+    $bb = Google\FlatBuffers\ByteBuffer::wrap($data);
+    test_buffer($assert, $bb);
+
+    // Second, let's create a FlatBuffer from scratch in JavaScript, and test it also.
+    // We use an initial size of 1 to exercise the reallocation algorithm,
+    // normally a size larger than the typical FlatBuffer you generate would be
+    // better for performance.
+    $fbb = new Google\FlatBuffers\FlatBufferBuilder(1);
+
+    // We set up the same values as monsterdata.json:
+    $str = $fbb->createString("MyMonster");
+    $name = $fbb->createString('Fred');
+    \MyGame\Example\Monster::startMonster($fbb);
+    \MyGame\Example\Monster::addName($fbb, $name);
+    $enemy = \MyGame\Example\Monster::endMonster($fbb);
+
+    $inv = \MyGame\Example\Monster::CreateInventoryVector($fbb, array(0, 1, 2, 3, 4));
+
+    $fred = $fbb->createString('Fred');
+    \MyGame\Example\Monster::StartMonster($fbb);
+    \MyGame\Example\Monster::AddName($fbb, $fred);
+    $mon2 = \MyGame\Example\Monster::EndMonster($fbb);
+
+    \MyGame\Example\Monster::StartTest4Vector($fbb, 2);
+    \MyGame\Example\Test::CreateTest($fbb, 10, 20);
+    \MyGame\Example\Test::CreateTest($fbb, 30, 40);
+    $test4 = $fbb->endVector();
+
+    $testArrayOfString = \MyGame\Example\Monster::CreateTestarrayofstringVector($fbb, array(
+        $fbb->createString('test1'),
+        $fbb->createString('test2')
+    ));
+
+    \MyGame\Example\Monster::StartMonster($fbb);
+    \MyGame\Example\Monster::AddPos($fbb, \MyGame\Example\Vec3::CreateVec3($fbb,
+        1.0, 2.0, 3.0, //float
+        3.0, // double
+        \MyGame\Example\Color::Green,
+        5, //short
+        6));
+    \MyGame\Example\Monster::AddHp($fbb, 80);
+    \MyGame\Example\Monster::AddName($fbb, $str);
+    \MyGame\Example\Monster::AddInventory($fbb, $inv);
+    \MyGame\Example\Monster::AddTestType($fbb, \MyGame\Example\Any::Monster);
+    \MyGame\Example\Monster::AddTest($fbb, $mon2);
+    \MyGame\Example\Monster::AddTest4($fbb, $test4);
+    \MyGame\Example\Monster::AddTestarrayofstring($fbb, $testArrayOfString);
+    \MyGame\Example\Monster::AddEnemy($fbb, $enemy);
+    \MyGame\Example\Monster::AddTestbool($fbb, true);
+    $mon = \MyGame\Example\Monster::EndMonster($fbb);
+
+    \MyGame\Example\Monster::FinishMonsterBuffer($fbb, $mon);
+
+    // Test it:
+    test_buffer($assert, $fbb->dataBuffer());
+
+    testByteBuffer($assert);
+    fuzzTest1($assert);
+//    testUnicode($assert);
+
+    echo 'FlatBuffers php test: completed successfully' . PHP_EOL;
+}
+
+try {
+    main();
+    exit(0);
+} catch(Exception $e) {
+    printf("Fatal error: Uncaught exception '%s' with message '%s. in %s:%d\n", get_class($e), $e->getMessage(), $e->getFile(), $e->getLine());
+    printf("Stack trace:\n");
+    echo $e->getTraceAsString() . PHP_EOL;
+    printf("  thrown in in %s:%d\n", $e->getFile(), $e->getLine());
+
+    die(-1);
+}
+
+function test_buffer(Assert $assert, Google\FlatBuffers\ByteBuffer $bb) {
+
+    $assert->ok(MyGame\Example\Monster::MonsterBufferHasIdentifier($bb));
+    $monster = \MyGame\Example\Monster::GetRootAsMonster($bb);
+
+    $assert->strictEqual($monster->GetHp(), 80);
+    $assert->strictEqual($monster->GetMana(), 150); // default
+
+    $assert->strictEqual($monster->GetName(), 'MyMonster');
+
+    $pos = $monster->GetPos();
+    $assert->strictEqual($pos->GetX(), 1.0);
+    $assert->strictEqual($pos->GetY(), 2.0);
+    $assert->strictEqual($pos->GetZ(), 3.0);
+
+    $assert->Equal($pos->GetTest1(), 3.0);
+    $assert->strictEqual($pos->GetTest2(), \MyGame\Example\Color::Green);
+
+    $t = $pos->GetTest3();
+    $assert->strictEqual($t->GetA(), 5);
+    $assert->strictEqual($t->GetB(), 6);
+    $assert->strictEqual($monster->GetTestType(), \MyGame\Example\Any::Monster);
+
+    $monster2 = new \MyGame\Example\Monster();
+    $assert->strictEqual($monster->GetTest($monster2) != null, true);
+    $assert->strictEqual($monster2->GetName(), 'Fred');
+
+    $assert->strictEqual($monster->GetInventoryLength(), 5);
+    $invsum = 0;
+    for ($i = 0; $i < $monster->GetInventoryLength(); $i++) {
+        $invsum += $monster->GetInventory($i);
+    }
+    $assert->strictEqual($invsum, 10);
+
+    $assert->strictEqual(bin2hex($monster->GetInventoryBytes()), "0001020304");
+
+    $test_0 = $monster->GetTest4(0);
+    $test_1 = $monster->GetTest4(1);
+    $assert->strictEqual($monster->GetTest4Length(), 2);
+    $assert->strictEqual($test_0->GetA() + $test_0->GetB() + $test_1->GetA() + $test_1->GetB(), 100);
+
+    $assert->strictEqual($monster->GetTestarrayofstringLength(), 2);
+    $assert->strictEqual($monster->GetTestarrayofstring(0), 'test1');
+    $assert->strictEqual($monster->GetTestarrayofstring(1), 'test2');
+
+    $fred = $monster->getEnemy();
+    $assert->Equal('Fred', $fred->getName());
+
+    $assert->strictEqual($monster->GetTestbool(), true);
+}
+
+//function testUnicode(Assert $assert) {
+//    // missing unicode_test.mon, implemented later
+//    $correct = file_get_contents('unicode_test.mon');
+//    $json = json_decode(file_get_contents('unicode_test.json'));
+//
+//    // Test reading
+//    $bb = flatbuffers\ByteBuffer::Wrap($correct);
+//    $monster = \MyGame\Example\Monster::GetRootAsMonster($bb);
+//    $assert->strictEqual($monster->GetName(), $json["name"]);
+//
+//    //$assert->deepEqual(new Buffer(monster.name(flatbuffers.Encoding.UTF8_BYTES)), new Buffer(json.name));
+//    //assert.strictEqual(monster.testarrayoftablesLength(), json.testarrayoftables.length);
+//    foreach ($json["testarrayoftables"]as $i => $table) {
+//        $value = $monster->GetTestArrayOfTables($i);
+//        $assert->strictEqual($value->GetName(), $table["name"]);
+//        //assert.deepEqual(new Buffer(value.name(flatbuffers.Encoding.UTF8_BYTES)), new Buffer(table.name));
+//    }
+//    $assert->strictEqual($monster->GetTestarrayofstringLength(), $json["testarrayofstring"]["length"]);
+//    foreach ($json["testarrayofstring"] as $i => $string) {
+//        $assert->strictEqual($monster->GetTestarrayofstring($i), $string);
+//        //assert.deepEqual(new Buffer(monster.testarrayofstring(i, flatbuffers.Encoding.UTF8_BYTES)), new Buffer(string));
+//    }
+//
+//    // Test writing
+//    $fbb = new FlatBuffers\FlatBufferBuilder(1);
+//    $name = $fbb->CreateString($json["name"]);
+//    $testarrayoftablesOffsets = array_map(function($table) use($fbb) {
+//        $name = $fbb->CreateString($table["name"]);
+//        \MyGame\Example\Monster::StartMonster($fbb);
+//        \MyGame\Example\Monster::AddName($fbb, $name);
+//        return \MyGame\Example\Monster::EndMonster($fbb);
+//    }, $json["testarrayoftables"]);
+//    $testarrayoftablesOffset = \MyGame\Example\Monster::CreateTestarrayoftablesVector($fbb,
+//            $testarrayoftablesOffsets);
+////    $testarrayofstringOffset = \MyGame\Example\Monster::CreateTestarrayofstringVector($fbb,
+////            $json["testarrayofstring"].map(function(string) { return fbb.createString(string); }));
+//
+//    \MyGame\Example\Monster::startMonster($fbb);
+//    \MyGame\Example\Monster::addTestarrayofstring($fbb, $testarrayoftablesOffset);
+//    \MyGame\Example\Monster::addTestarrayoftables($fbb, $testarrayoftablesOffset);
+//    \MyGame\Example\Monster::addName($fbb, $name);
+//    \MyGame\Example\Monster::finishMonsterBuffer($fbb, \MyGame\Example\Monster::endMonster($fbb));
+//    //;assert.deepEqual(new Buffer(fbb.asUint8Array()), correct);
+//}
+
+// Low level stress/fuzz test: serialize/deserialize a variety of
+// different kinds of data in different combinations
+function fuzzTest1(Assert $assert)
+{
+
+    // Values we're testing against: chosen to ensure no bits get chopped
+    // off anywhere, and also be different from eachother.
+    $bool_val = true;
+    $char_val = -127; // 0x81
+    $uchar_val = 0xFF;
+    $short_val = -32222; // 0x8222;
+    $ushort_val = 0xFEEE;
+    $int_val = 0x7fffffff | 0;
+    // for now
+    $uint_val = 1;
+    $long_val = 2;
+    $ulong_val = 3;
+
+//    var uint_val   = 0xFDDDDDDD;
+//    var long_val   = new flatbuffers.Long(0x44444444, 0x84444444);
+//    var ulong_val  = new flatbuffers.Long(0xCCCCCCCC, 0xFCCCCCCC);
+
+    $float_val = 3.14159;
+    $double_val = 3.14159265359;
+
+    $test_values_max = 11;
+    $fields_per_object = 4;
+    // current implementation is not good at encoding.
+    $num_fuzz_objects = 1000;
+    $builder = new Google\FlatBuffers\FlatBufferBuilder(1);
+
+    // can't use same implementation due to PHP_INTMAX overflow issue.
+    // we use mt_rand function to reproduce fuzzy test.
+    mt_srand(48271);
+    $objects = array();
+    // Generate num_fuzz_objects random objects each consisting of
+    // fields_per_object fields, each of a random type.
+    for ($i = 0; $i < $num_fuzz_objects; $i++) {
+        $builder->startObject($fields_per_object);
+        for ($f = 0; $f < $fields_per_object; $f++) {
+            $choice = mt_rand() % $test_values_max;
+            switch ($choice) {
+                case 0:
+                    $builder->addBoolX($f, $bool_val, 0);
+                    break;
+                case 1:
+                    $builder->addByteX($f, $char_val, 0);
+                    break;
+                case 2:
+                    $builder->addSbyteX($f, $uchar_val, 0);
+                    break;
+                case 3:
+                    $builder->addShortX($f, $short_val, 0);
+                    break;
+                case 4:
+                    $builder->addUshortX($f, $ushort_val, 0);
+                    break;
+                case 5:
+                    $builder->addIntX($f, $int_val, 0);
+                    break;
+                case 6:
+                    $builder->addUintX($f, $uint_val, 0);
+                    break;
+                case 7:
+                    $builder->addLongX($f, $long_val, 0);
+                    break;
+                case 8:
+                    $builder->addUlongX($f, $ulong_val, 0);
+                    break;
+                case 9:
+                    $builder->addFloatX($f, $float_val, 0);
+                    break;
+                case 10:
+                    $builder->addDoubleX($f, $double_val, 0);
+                    break;
+            }
+        }
+        $objects[] = $builder->endObject();
+    }
+    $builder->prep(8, 0); // Align whole buffer.
+
+    mt_srand(48271); // Reset
+    $builder->finish($objects[count($objects) - 1]);
+
+    $view = Google\FlatBuffers\ByteBuffer::wrap($builder->sizedByteArray());
+    for ($i = 0; $i < $num_fuzz_objects; $i++) {
+        $offset = $view->capacity() - $objects[$i];
+        for ($f = 0; $f < $fields_per_object; $f++) {
+            $choice = mt_rand() % $test_values_max;
+            $vtable_offset = fieldIndexToOffset($f);
+            $vtable = $offset - $view->getInt($offset);
+            $assert->ok($vtable_offset < $view->getShort($vtable));
+            $field_offset = $offset + $view->getShort($vtable + $vtable_offset);
+            switch ($choice) {
+                case 0:
+                    $assert->strictEqual(!!$view->getBool($field_offset), $bool_val);
+                    break;
+                case 1:
+                    $assert->strictEqual($view->getSbyte($field_offset), $char_val);
+                    break;
+                case 2:
+                    $assert->strictEqual($view->getByte($field_offset), $uchar_val);
+                    break;
+                case 3:
+                    $assert->strictEqual($view->getShort($field_offset), $short_val);
+                    break;
+                case 4:
+                    $assert->strictEqual($view->getUShort($field_offset), $ushort_val);
+                    break;
+                case 5:
+                    $assert->strictEqual($view->getInt($field_offset), $int_val);
+                    break;
+                case 6:
+                    $assert->strictEqual($view->getUint($field_offset), $uint_val);
+                    break;
+                case 7:
+                    if (PHP_INT_SIZE <= 4) break;
+                    $assert->strictEqual($view->getLong($field_offset), $long_val);
+                    break;
+                case 8:
+                    if (PHP_INT_SIZE <= 4) break;
+                    $assert->strictEqual($view->getUlong($field_offset), $ulong_val);
+                    break;
+                case 9:
+                    $assert->strictEqual(floor($view->getFloat($field_offset)), floor($float_val));
+                    break;
+                case 10:
+                    $assert->strictEqual($view->getDouble($field_offset), $double_val);
+                    break;
+            }
+        }
+    }
+}
+
+function fieldIndexToOffset($field_id) {
+    // Should correspond to what EndTable() below builds up.
+    $fixed_fields = 2;  // Vtable size and Object Size.
+    return ($field_id + $fixed_fields) * 2;
+}
+
+function testByteBuffer(Assert $assert) {
+
+    //Test: ByteBuffer_Length_MatchesBufferLength
+    $buffer = str_repeat("\0", 100);
+    $uut  = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Equal($uut->capacity(), strlen($buffer));
+
+    //Test: ByteBuffer_PutBytePopulatesBufferAtZeroOffset
+    $buffer = "\0";
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $uut->putByte(0, "\x63"); // 99
+    $assert->Equal("\x63", $uut->_buffer[0]); // don't share buffer as php user might confuse reference.
+
+    //Test: ByteBuffer_PutByteCannotPutAtOffsetPastLength
+    $buffer = "\0";
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->putByte(1, "\x63"); // 99
+    });
+
+    //Test: ByteBuffer_PutShortPopulatesBufferCorrectly
+    $buffer = str_repeat("\0", 2);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $uut->putShort(0, 1);
+
+    // Ensure Endiannes was written correctly
+    $assert->Equal(chr(0x01), $uut->_buffer[0]);
+    $assert->Equal(chr(0x00), $uut->_buffer[1]);
+
+    $buffer = str_repeat("\0", 2);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $uut->putShort(0, -32768);
+
+    // Ensure Endiannes was written correctly
+    $assert->Equal(chr(0x00), $uut->_buffer[0]);
+    $assert->Equal(chr(0x80), $uut->_buffer[1]);
+
+    //Test: ByteBuffer_PutShortCannotPutAtOffsetPastLength
+    $buffer = "\0";
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->putShort(2, "\x63"); // 99
+    });
+
+    //Test: ByteBuffer_PutShortChecksLength
+    $buffer = "\0";
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->putShort(0, "\x63"); // 99
+    });
+
+    //Test: ByteBuffer_PutShortChecksLengthAndOffset
+    $buffer = str_repeat("\0", 2);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->putShort(1, "\x63"); // 99
+    });
+
+    //Test: ByteBuffer_PutIntPopulatesBufferCorrectly
+    $buffer = str_repeat("\0", 4);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $uut->putInt(0, 0x0A0B0C0D);
+    $assert->Equal(chr(0x0D), $uut->_buffer[0]);
+    $assert->Equal(chr(0x0C), $uut->_buffer[1]);
+    $assert->Equal(chr(0x0B), $uut->_buffer[2]);
+    $assert->Equal(chr(0x0A), $uut->_buffer[3]);
+
+    $buffer = str_repeat("\0", 4);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $uut->putInt(0, -2147483648);
+    $assert->Equal(chr(0x00), $uut->_buffer[0]);
+    $assert->Equal(chr(0x00), $uut->_buffer[1]);
+    $assert->Equal(chr(0x00), $uut->_buffer[2]);
+    $assert->Equal(chr(0x80), $uut->_buffer[3]);
+
+    //Test: ByteBuffer_PutIntCannotPutAtOffsetPastLength
+    $buffer = str_repeat("\0", 4);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->putInt(2, 0x0A0B0C0D);
+    });
+
+    //Test: ByteBuffer_PutIntChecksLength
+    $buffer = str_repeat("\0", 1);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->putInt(0, 0x0A0B0C0D);
+    });
+
+    //Test: ByteBuffer_PutIntChecksLengthAndOffset
+    $buffer = str_repeat("\0", 4);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->putInt(2, 0x0A0B0C0D);
+    });
+
+    if (PHP_INT_SIZE > 4) {
+        //Test: ByteBuffer_PutLongPopulatesBufferCorrectly
+        $buffer = str_repeat("\0", 8);
+        $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+        $uut->putLong(0, 0x010203040A0B0C0D);
+        $assert->Equal(chr(0x0D), $uut->_buffer[0]);
+        $assert->Equal(chr(0x0C), $uut->_buffer[1]);
+        $assert->Equal(chr(0x0B), $uut->_buffer[2]);
+        $assert->Equal(chr(0x0A), $uut->_buffer[3]);
+        $assert->Equal(chr(0x04), $uut->_buffer[4]);
+        $assert->Equal(chr(0x03), $uut->_buffer[5]);
+        $assert->Equal(chr(0x02), $uut->_buffer[6]);
+        $assert->Equal(chr(0x01), $uut->_buffer[7]);
+
+        //Test: ByteBuffer_PutLongCannotPutAtOffsetPastLength
+        $buffer = str_repeat("\0", 8);
+        $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+        $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+            $uut->putLong(2, 0x010203040A0B0C0D);
+        });
+
+        //Test: ByteBuffer_PutLongCannotPutAtOffsetPastLength
+        $buffer = str_repeat("\0", 1);
+        $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+        $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+            $uut->putLong(0, 0x010203040A0B0C0D);
+        });
+
+
+        //Test: ByteBuffer_PutLongChecksLengthAndOffset
+        $buffer = str_repeat("\0", 8);
+        $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+        $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+            $uut->putLong(2, 0x010203040A0B0C0D);
+        });
+    }
+
+    //Test: ByteBuffer_GetByteReturnsCorrectData
+    $buffer = str_repeat("\0", 1);
+    $buffer[0] = "\x63";
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Equal("\x63", $uut->get(0));
+
+    //Test: ByteBuffer_GetByteChecksOffset
+    $buffer = str_repeat("\0", 1);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->get(1);
+    });
+
+    //Test: ByteBuffer_GetShortReturnsCorrectData
+    $buffer = str_repeat("\0", 2);
+    $buffer[0] = chr(0x01);
+    $buffer[1] = chr(0x00);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Equal(1, $uut->getShort(0));
+
+    //Test: ByteBuffer_GetShortReturnsCorrectData (signed value)
+    $buffer = str_repeat("\0", 2);
+    $buffer[0] = chr(0x00);
+    $buffer[1] = chr(0x80);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Equal(-32768, $uut->getShort(0));
+
+    //Test: ByteBuffer_GetShortChecksOffset
+    $buffer = str_repeat("\0", 2);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->getShort(2);
+    });
+
+    //Test: ByteBuffer_GetShortChecksLength
+    $buffer = str_repeat("\0", 2);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->getShort(1);
+    });
+
+    //Test: ByteBuffer_GetIntReturnsCorrectData
+    $buffer = str_repeat("\0", 4);
+    $buffer[0] = chr(0x0D);
+    $buffer[1] = chr(0x0C);
+    $buffer[2] = chr(0x0B);
+    $buffer[3] = chr(0x0A);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Equal(0x0A0B0C0D, $uut->getInt(0));
+
+    $buffer = str_repeat("\0", 4);
+    $buffer[0] = chr(0x00);
+    $buffer[1] = chr(0x00);
+    $buffer[2] = chr(0x00);
+    $buffer[3] = chr(0x80);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Equal(-2147483648, $uut->getInt(0));
+
+    //Test: ByteBuffer_GetIntChecksOffset
+    $buffer = str_repeat("\0", 4);
+
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->getInt(4);
+    });
+
+    //Test: ByteBuffer_GetIntChecksLength
+    $buffer = str_repeat("\0", 2);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->getInt(0);
+    });
+
+    if (PHP_INT_SIZE > 4) {
+        //Test: ByteBuffer_GetLongReturnsCorrectData
+        $buffer = str_repeat("\0", 8);
+        $buffer[0] = chr(0x0D);
+        $buffer[1] = chr(0x0C);
+        $buffer[2] = chr(0x0B);
+        $buffer[3] = chr(0x0A);
+        $buffer[4] = chr(0x04);
+        $buffer[5] = chr(0x03);
+        $buffer[6] = chr(0x02);
+        $buffer[7] = chr(0x01);
+        $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+        $assert->Equal(0x010203040A0B0C0D, $uut->getLong(0));
+
+        //Test: Signed Long
+        $buffer = str_repeat("\0", 8);
+        $buffer[0] = chr(0x00);
+        $buffer[1] = chr(0x00);
+        $buffer[2] = chr(0x00);
+        $buffer[3] = chr(0x00);
+        $buffer[4] = chr(0x00);
+        $buffer[5] = chr(0x00);
+        $buffer[6] = chr(0x00);
+        $buffer[7] = chr(0x80);
+        $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+        $assert->Equal(-1 << 63, $uut->getLong(0));
+    }
+
+    //Test: ByteBuffer_GetLongChecksOffset
+    $buffer = str_repeat("\0", 8);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->getLong(8);
+    });
+
+    //Test: ByteBuffer_GetLongChecksLength
+    $buffer = str_repeat("\0", 7);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
+        $uut->getLong(0);
+    });
+
+    //Test: big endian
+    $buffer = str_repeat("\0", 2);
+    // 0xFF 0x00
+    // Little Endian: 255
+    // Big Endian: 65280
+    $buffer[0] = chr(0xff);
+    $buffer[1] = chr(0x00);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Equal(65280, $uut->readLittleEndian(0, 2, true));
+
+    $buffer = str_repeat("\0", 4);
+    $buffer[0] = chr(0x0D);
+    $buffer[1] = chr(0x0C);
+    $buffer[2] = chr(0x0B);
+    $buffer[3] = chr(0x0A);
+    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
+    $assert->Equal(0x0D0C0B0A, $uut->readLittleEndian(0, 4, true));
+
+}
+
+class Assert {
+    public function ok($result, $message = "") {
+        if (!$result){
+            throw new Exception(!empty($message) ? $message : "{$result} is not true.");
+        }
+    }
+
+    public function Equal($result, $expected, $message = "") {
+        if ($result != $expected) {
+            throw new Exception(!empty($message) ? $message : "given the result {$result} is not equals as {$expected}");
+        }
+    }
+
+
+    public function strictEqual($result, $expected, $message = "") {
+        if ($result !== $expected) {
+            throw new Exception(!empty($message) ? $message : "given the result {$result} is not strict equals as {$expected}");
+        }
+    }
+
+    public function Throws($class, Callable $callback) {
+        try {
+            $callback();
+
+            throw new \Exception("passed statement don't throw an exception.");
+        } catch (\Exception $e) {
+            if (get_class($e) != get_class($class)) {
+                throw new Exception("passed statement doesn't throw " . get_class($class) . ". throwws " . get_class($e));
+            }
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/phpUnionVectorTest.php b/third_party/flatbuffers/tests/phpUnionVectorTest.php
new file mode 100644
index 0000000..4b5e258
--- /dev/null
+++ b/third_party/flatbuffers/tests/phpUnionVectorTest.php
@@ -0,0 +1,109 @@
+<?php
+
+require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "Constants.php"));
+require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "ByteBuffer.php"));
+require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "FlatbufferBuilder.php"));
+require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "Table.php"));
+require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "Struct.php"));
+
+require join(DIRECTORY_SEPARATOR, array(dirname(__FILE__), "php", 'Attacker.php'));
+require join(DIRECTORY_SEPARATOR, array(dirname(__FILE__), "php", 'BookReader.php'));
+require join(DIRECTORY_SEPARATOR, array(dirname(__FILE__), "php", 'Character.php'));
+require join(DIRECTORY_SEPARATOR, array(dirname(__FILE__), "php", 'Movie.php'));
+
+class Assert {
+    public function ok($result, $message = "") {
+        if (!$result){
+            throw new Exception(!empty($message) ? $message : "{$result} is not true.");
+        }
+    }
+
+    public function Equal($result, $expected, $message = "") {
+        if ($result != $expected) {
+            throw new Exception(!empty($message) ? $message : "given the result {$result} is not equals as {$expected}");
+        }
+    }
+
+
+    public function strictEqual($result, $expected, $message = "") {
+        if ($result !== $expected) {
+            throw new Exception(!empty($message) ? $message : "given the result {$result} is not strict equals as {$expected}");
+        }
+    }
+
+    public function Throws($class, Callable $callback) {
+        try {
+            $callback();
+
+            throw new \Exception("passed statement don't throw an exception.");
+        } catch (\Exception $e) {
+            if (get_class($e) != get_class($class)) {
+                throw new Exception("passed statement doesn't throw " . get_class($class) . ". throwws " . get_class($e));
+            }
+        }
+    }
+}
+
+function main()
+{
+    $assert = new Assert();
+
+    $fbb = new Google\FlatBuffers\FlatBufferBuilder(1);
+
+    $charTypes = [
+        Character::Belle,
+        Character::MuLan,
+        Character::BookFan,
+    ];
+
+    Attacker::startAttacker($fbb);
+    Attacker::addSwordAttackDamage($fbb, 5);
+    $attackerOffset = Attacker::endAttacker($fbb);
+
+    $charTypesOffset = Movie::createCharactersTypeVector($fbb, $charTypes);
+    $charsOffset = Movie::createCharactersVector(
+        $fbb,
+        [
+            BookReader::createBookReader($fbb, 7),
+            $attackerOffset,
+            BookReader::createBookReader($fbb, 2),
+        ]
+    );
+
+    Movie::startMovie($fbb);
+    Movie::addCharactersType($fbb, $charTypesOffset);
+    Movie::addCharacters($fbb, $charsOffset);
+    Movie::finishMovieBuffer($fbb, Movie::endMovie($fbb));
+
+    $buf = Google\FlatBuffers\ByteBuffer::wrap($fbb->dataBuffer()->data());
+
+    $movie = Movie::getRootAsMovie($buf);
+
+    $assert->strictEqual($movie->getCharactersTypeLength(), count($charTypes));
+    $assert->strictEqual($movie->getCharactersLength(), $movie->getCharactersTypeLength());
+
+    for ($i = 0; $i < count($charTypes); ++$i) {
+        $assert->strictEqual($movie->getCharactersType($i), $charTypes[$i]);
+    }
+
+    $bookReader7 = $movie->getCharacters(0, new BookReader());
+    $assert->strictEqual($bookReader7->getBooksRead(), 7);
+
+    $attacker = $movie->getCharacters(1, new Attacker());
+    $assert->strictEqual($attacker->getSwordAttackDamage(), 5);
+
+    $bookReader2 = $movie->getCharacters(2, new BookReader());
+    $assert->strictEqual($bookReader2->getBooksRead(), 2);
+}
+
+try {
+    main();
+    exit(0);
+} catch(Exception $e) {
+    printf("Fatal error: Uncaught exception '%s' with message '%s. in %s:%d\n", get_class($e), $e->getMessage(), $e->getFile(), $e->getLine());
+    printf("Stack trace:\n");
+    echo $e->getTraceAsString() . PHP_EOL;
+    printf("  thrown in in %s:%d\n", $e->getFile(), $e->getLine());
+
+    die(-1);
+}
diff --git a/third_party/flatbuffers/tests/phpUnionVectorTest.sh b/third_party/flatbuffers/tests/phpUnionVectorTest.sh
new file mode 100755
index 0000000..a6c3f26
--- /dev/null
+++ b/third_party/flatbuffers/tests/phpUnionVectorTest.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+set -e
+
+../flatc --php -o php union_vector/union_vector.fbs
+php phpUnionVectorTest.php
+
+echo 'PHP union vector test passed'
diff --git a/third_party/flatbuffers/tests/prototest/imported.proto b/third_party/flatbuffers/tests/prototest/imported.proto
new file mode 100644
index 0000000..5b43e4b
--- /dev/null
+++ b/third_party/flatbuffers/tests/prototest/imported.proto
@@ -0,0 +1,5 @@
+package proto.test;
+
+message ImportedMessage {
+    optional int32 a = 26;
+}
diff --git a/third_party/flatbuffers/tests/prototest/test.golden b/third_party/flatbuffers/tests/prototest/test.golden
new file mode 100644
index 0000000..cf861b9
--- /dev/null
+++ b/third_party/flatbuffers/tests/prototest/test.golden
@@ -0,0 +1,59 @@
+// Generated from test.proto
+
+namespace proto.test;
+
+/// Enum doc comment.
+enum ProtoEnum : int {
+  NUL = 0,
+  FOO = 1,
+  /// Enum 2nd value doc comment misaligned.
+  BAR = 5,
+}
+
+table ImportedMessage {
+  a:int;
+}
+
+/// 2nd table doc comment with
+/// many lines.
+table ProtoMessage {
+  c:int = 16;
+  d:long;
+  p:uint;
+  e:ulong;
+  /// doc comment for f.
+  f:int = -1;
+  g:long;
+  h:uint;
+  q:ulong;
+  i:int;
+  j:long;
+  /// doc comment for k.
+  k:bool;
+  /// doc comment for l on 2
+  /// lines
+  l:string (required);
+  m:[ubyte];
+  n:proto.test.ProtoMessage_.OtherMessage;
+  o:[string];
+  z:proto.test.ImportedMessage;
+  /// doc comment for r.
+  r:proto.test.ProtoMessage_.Anonymous0;
+}
+
+namespace proto.test.ProtoMessage_;
+
+table OtherMessage {
+  a:double;
+  /// doc comment for b.
+  b:float = 3.14149;
+}
+
+table Anonymous0 {
+  /// doc comment for s.
+  s:proto.test.ImportedMessage;
+  /// doc comment for t on 2
+  /// lines.
+  t:proto.test.ProtoMessage_.OtherMessage;
+}
+
diff --git a/third_party/flatbuffers/tests/prototest/test.proto b/third_party/flatbuffers/tests/prototest/test.proto
new file mode 100644
index 0000000..45ce6c0
--- /dev/null
+++ b/third_party/flatbuffers/tests/prototest/test.proto
@@ -0,0 +1,59 @@
+// Sample .proto file that we can translate to the corresponding .fbs.
+
+option some_option = is_ignored;
+import "imported.proto";
+
+package proto.test;
+
+/// Enum doc comment.
+enum ProtoEnum {
+  option allow_alias = true;
+  NUL = 0;
+  FOO = 1;
+  /// Enum 2nd value doc comment misaligned.
+  BAR = 5;
+  // Aliases
+  FOO_A1 = 1;
+  BAR_A1 = 5;
+  FOO_A2 = 1;
+}
+
+/// 2nd table doc comment with
+/// many lines.
+message ProtoMessage {
+  // Ignored non-doc comment.
+  // A nested message declaration, will be moved to top level in .fbs
+  message OtherMessage {
+    optional double a = 26;
+    /// doc comment for b.
+    optional float b = 32 [default = 3.14149];
+  }
+  optional int32 c = 12 [default = 16];
+  optional int64 d = 1 [default = 0];
+  optional uint32 p = 1;
+  optional uint64 e = 2;
+  /// doc comment for f.
+  optional sint32 f = 3 [default = -1];
+  optional sint64 g = 4;
+  optional fixed32 h = 5;
+  optional fixed64 q = 6;
+  optional sfixed32 i = 7;
+  optional sfixed64 j = 8;
+  /// doc comment for k.
+  optional bool k = 9;
+  /// doc comment for l on 2
+  /// lines
+  required string l = 10;
+  optional bytes m = 11;
+  optional OtherMessage n = 12;
+  repeated string o = 14;
+  optional ImportedMessage z = 16;
+  /// doc comment for r.
+  oneof r {
+    /// doc comment for s.
+    ImportedMessage s = 17;
+    /// doc comment for t on 2
+    /// lines.
+    OtherMessage t = 18;
+  }
+}
diff --git a/third_party/flatbuffers/tests/prototest/test_union.golden b/third_party/flatbuffers/tests/prototest/test_union.golden
new file mode 100644
index 0000000..18270eb
--- /dev/null
+++ b/third_party/flatbuffers/tests/prototest/test_union.golden
@@ -0,0 +1,63 @@
+// Generated from test.proto
+
+namespace proto.test;
+
+/// Enum doc comment.
+enum ProtoEnum : int {
+  NUL = 0,
+  FOO = 1,
+  /// Enum 2nd value doc comment misaligned.
+  BAR = 5,
+}
+
+namespace proto.test.ProtoMessage_;
+
+union RUnion {
+  /// doc comment for s.
+  proto.test.ImportedMessage,
+  /// doc comment for t on 2
+  /// lines.
+  proto.test.ProtoMessage_.OtherMessage,
+}
+
+namespace proto.test;
+
+table ImportedMessage {
+  a:int;
+}
+
+/// 2nd table doc comment with
+/// many lines.
+table ProtoMessage {
+  c:int = 16;
+  d:long;
+  p:uint;
+  e:ulong;
+  /// doc comment for f.
+  f:int = -1;
+  g:long;
+  h:uint;
+  q:ulong;
+  i:int;
+  j:long;
+  /// doc comment for k.
+  k:bool;
+  /// doc comment for l on 2
+  /// lines
+  l:string (required);
+  m:[ubyte];
+  n:proto.test.ProtoMessage_.OtherMessage;
+  o:[string];
+  z:proto.test.ImportedMessage;
+  /// doc comment for r.
+  r:proto.test.ProtoMessage_.RUnion;
+}
+
+namespace proto.test.ProtoMessage_;
+
+table OtherMessage {
+  a:double;
+  /// doc comment for b.
+  b:float = 3.14149;
+}
+
diff --git a/third_party/flatbuffers/tests/py_test.py b/third_party/flatbuffers/tests/py_test.py
new file mode 100644
index 0000000..b152270
--- /dev/null
+++ b/third_party/flatbuffers/tests/py_test.py
@@ -0,0 +1,1817 @@
+# coding=utf-8
+# 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.
+
+import os.path
+import sys
+import imp
+PY_VERSION = sys.version_info[:2]
+
+import ctypes
+from collections import defaultdict
+import math
+import random
+import timeit
+import unittest
+
+from flatbuffers import compat
+from flatbuffers import util
+from flatbuffers.compat import range_func as compat_range
+from flatbuffers.compat import NumpyRequiredForThisFeature
+
+import flatbuffers
+from flatbuffers import number_types as N
+
+import MyGame  # refers to generated code
+import MyGame.Example  # refers to generated code
+import MyGame.Example.Any  # refers to generated code
+import MyGame.Example.Color  # refers to generated code
+import MyGame.Example.Monster  # refers to generated code
+import MyGame.Example.Test  # refers to generated code
+import MyGame.Example.Stat  # refers to generated code
+import MyGame.Example.Vec3  # refers to generated code
+import MyGame.MonsterExtra  # refers to generated code
+import MyGame.Example.ArrayTable  # refers to generated code
+import MyGame.Example.ArrayStruct  # refers to generated code
+import MyGame.Example.NestedStruct  # refers to generated code
+import MyGame.Example.TestEnum  # refers to generated code
+
+def assertRaises(test_case, fn, exception_class):
+    ''' Backwards-compatible assertion for exceptions raised. '''
+
+    exc = None
+    try:
+        fn()
+    except Exception as e:
+        exc = e
+    test_case.assertTrue(exc is not None)
+    test_case.assertTrue(isinstance(exc, exception_class))
+
+
+class TestWireFormat(unittest.TestCase):
+    def test_wire_format(self):
+        # Verify that using the generated Python code builds a buffer without
+        # returning errors, and is interpreted correctly, for size prefixed
+        # representation and regular:
+        for sizePrefix in [True, False]:
+            for file_identifier in [None, b"MONS"]:
+                gen_buf, gen_off = make_monster_from_generated_code(sizePrefix=sizePrefix, file_identifier=file_identifier)
+                CheckReadBuffer(gen_buf, gen_off, sizePrefix=sizePrefix, file_identifier=file_identifier)
+
+        # Verify that the canonical flatbuffer file is readable by the
+        # generated Python code. Note that context managers are not part of
+        # Python 2.5, so we use the simpler open/close methods here:
+        f = open('monsterdata_test.mon', 'rb')
+        canonicalWireData = f.read()
+        f.close()
+        CheckReadBuffer(bytearray(canonicalWireData), 0, file_identifier=b'MONS')
+
+        # Write the generated buffer out to a file:
+        f = open('monsterdata_python_wire.mon', 'wb')
+        f.write(gen_buf[gen_off:])
+        f.close()
+
+
+def CheckReadBuffer(buf, offset, sizePrefix=False, file_identifier=None):
+    ''' CheckReadBuffer checks that the given buffer is evaluated correctly
+        as the example Monster. '''
+
+    def asserter(stmt):
+        ''' An assertion helper that is separated from TestCase classes. '''
+        if not stmt:
+            raise AssertionError('CheckReadBuffer case failed')
+    if file_identifier:
+        # test prior to removal of size_prefix
+        asserter(util.GetBufferIdentifier(buf, offset, size_prefixed=sizePrefix) == file_identifier)
+        asserter(util.BufferHasIdentifier(buf, offset, file_identifier=file_identifier, size_prefixed=sizePrefix))
+    if sizePrefix:
+        size = util.GetSizePrefix(buf, offset)
+        asserter(size == len(buf[offset:])-4)
+        buf, offset = util.RemoveSizePrefix(buf, offset)
+    if file_identifier:
+        asserter(MyGame.Example.Monster.Monster.MonsterBufferHasIdentifier(buf, offset))
+    else:
+        asserter(not MyGame.Example.Monster.Monster.MonsterBufferHasIdentifier(buf, offset))
+    monster = MyGame.Example.Monster.Monster.GetRootAsMonster(buf, offset)
+
+    asserter(monster.Hp() == 80)
+    asserter(monster.Mana() == 150)
+    asserter(monster.Name() == b'MyMonster')
+
+    # initialize a Vec3 from Pos()
+    vec = monster.Pos()
+    asserter(vec is not None)
+
+    # verify the properties of the Vec3
+    asserter(vec.X() == 1.0)
+    asserter(vec.Y() == 2.0)
+    asserter(vec.Z() == 3.0)
+    asserter(vec.Test1() == 3.0)
+    asserter(vec.Test2() == 2)
+
+    # initialize a Test from Test3(...)
+    t = MyGame.Example.Test.Test()
+    t = vec.Test3(t)
+    asserter(t is not None)
+
+    # verify the properties of the Test
+    asserter(t.A() == 5)
+    asserter(t.B() == 6)
+
+    # verify that the enum code matches the enum declaration:
+    union_type = MyGame.Example.Any.Any
+    asserter(monster.TestType() == union_type.Monster)
+
+    # initialize a Table from a union field Test(...)
+    table2 = monster.Test()
+    asserter(type(table2) is flatbuffers.table.Table)
+
+    # initialize a Monster from the Table from the union
+    monster2 = MyGame.Example.Monster.Monster()
+    monster2.Init(table2.Bytes, table2.Pos)
+
+    asserter(monster2.Name() == b"Fred")
+
+    # iterate through the first monster's inventory:
+    asserter(monster.InventoryLength() == 5)
+
+    invsum = 0
+    for i in compat_range(monster.InventoryLength()):
+        v = monster.Inventory(i)
+        invsum += int(v)
+    asserter(invsum == 10)
+
+    for i in range(5):
+        asserter(monster.VectorOfLongs(i) == 10 ** (i * 2))
+
+    asserter(([-1.7976931348623157e+308, 0, 1.7976931348623157e+308]
+              == [monster.VectorOfDoubles(i)
+                  for i in range(monster.VectorOfDoublesLength())]))
+
+    try:
+        imp.find_module('numpy')
+        # if numpy exists, then we should be able to get the
+        # vector as a numpy array
+        import numpy as np
+
+        asserter(monster.InventoryAsNumpy().sum() == 10)
+        asserter(monster.InventoryAsNumpy().dtype == np.dtype('uint8'))
+
+        VectorOfLongs = monster.VectorOfLongsAsNumpy()
+        asserter(VectorOfLongs.dtype == np.dtype('int64'))
+        for i in range(5):
+            asserter(VectorOfLongs[i] == 10 ** (i * 2))
+
+        VectorOfDoubles = monster.VectorOfDoublesAsNumpy()
+        asserter(VectorOfDoubles.dtype == np.dtype('float64'))
+        asserter(VectorOfDoubles[0] == np.finfo('float64').min)
+        asserter(VectorOfDoubles[1] == 0.0)
+        asserter(VectorOfDoubles[2] == np.finfo('float64').max)
+
+    except ImportError:
+        # If numpy does not exist, trying to get vector as numpy
+        # array should raise NumpyRequiredForThisFeature. The way
+        # assertRaises has been implemented prevents us from
+        # asserting this error is raised outside of a test case.
+        pass
+
+    asserter(monster.Test4Length() == 2)
+
+    # create a 'Test' object and populate it:
+    test0 = monster.Test4(0)
+    asserter(type(test0) is MyGame.Example.Test.Test)
+
+    test1 = monster.Test4(1)
+    asserter(type(test1) is MyGame.Example.Test.Test)
+
+    # the position of test0 and test1 are swapped in monsterdata_java_wire
+    # and monsterdata_test_wire, so ignore ordering
+    v0 = test0.A()
+    v1 = test0.B()
+    v2 = test1.A()
+    v3 = test1.B()
+    sumtest12 = int(v0) + int(v1) + int(v2) + int(v3)
+
+    asserter(sumtest12 == 100)
+
+    asserter(monster.TestarrayofstringLength() == 2)
+    asserter(monster.Testarrayofstring(0) == b"test1")
+    asserter(monster.Testarrayofstring(1) == b"test2")
+
+    asserter(monster.TestarrayoftablesLength() == 0)
+    asserter(monster.TestnestedflatbufferLength() == 0)
+    asserter(monster.Testempty() is None)
+
+
+class TestFuzz(unittest.TestCase):
+    ''' Low level stress/fuzz test: serialize/deserialize a variety of
+        different kinds of data in different combinations '''
+
+    binary_type = compat.binary_types[0] # this will always exist
+    ofInt32Bytes = binary_type([0x83, 0x33, 0x33, 0x33])
+    ofInt64Bytes = binary_type([0x84, 0x44, 0x44, 0x44,
+                                0x44, 0x44, 0x44, 0x44])
+    overflowingInt32Val = flatbuffers.encode.Get(flatbuffers.packer.int32,
+                                                 ofInt32Bytes, 0)
+    overflowingInt64Val = flatbuffers.encode.Get(flatbuffers.packer.int64,
+                                                 ofInt64Bytes, 0)
+
+    # Values we're testing against: chosen to ensure no bits get chopped
+    # off anywhere, and also be different from eachother.
+    boolVal = True
+    int8Val = N.Int8Flags.py_type(-127) # 0x81
+    uint8Val = N.Uint8Flags.py_type(0xFF)
+    int16Val = N.Int16Flags.py_type(-32222) # 0x8222
+    uint16Val = N.Uint16Flags.py_type(0xFEEE)
+    int32Val = N.Int32Flags.py_type(overflowingInt32Val)
+    uint32Val = N.Uint32Flags.py_type(0xFDDDDDDD)
+    int64Val = N.Int64Flags.py_type(overflowingInt64Val)
+    uint64Val = N.Uint64Flags.py_type(0xFCCCCCCCCCCCCCCC)
+    # Python uses doubles, so force it here
+    float32Val = N.Float32Flags.py_type(ctypes.c_float(3.14159).value)
+    float64Val = N.Float64Flags.py_type(3.14159265359)
+
+    def test_fuzz(self):
+        return self.check_once(11, 100)
+
+    def check_once(self, fuzzFields, fuzzObjects):
+        testValuesMax = 11 # hardcoded to the number of scalar types
+
+        builder = flatbuffers.Builder(0)
+        l = LCG()
+
+        objects = [0 for _ in compat_range(fuzzObjects)]
+
+        # Generate fuzzObjects random objects each consisting of
+        # fuzzFields fields, each of a random type.
+        for i in compat_range(fuzzObjects):
+            builder.StartObject(fuzzFields)
+
+            for j in compat_range(fuzzFields):
+                choice = int(l.Next()) % testValuesMax
+                if choice == 0:
+                    builder.PrependBoolSlot(int(j), self.boolVal, False)
+                elif choice == 1:
+                    builder.PrependInt8Slot(int(j), self.int8Val, 0)
+                elif choice == 2:
+                    builder.PrependUint8Slot(int(j), self.uint8Val, 0)
+                elif choice == 3:
+                    builder.PrependInt16Slot(int(j), self.int16Val, 0)
+                elif choice == 4:
+                    builder.PrependUint16Slot(int(j), self.uint16Val, 0)
+                elif choice == 5:
+                    builder.PrependInt32Slot(int(j), self.int32Val, 0)
+                elif choice == 6:
+                    builder.PrependUint32Slot(int(j), self.uint32Val, 0)
+                elif choice == 7:
+                    builder.PrependInt64Slot(int(j), self.int64Val, 0)
+                elif choice == 8:
+                    builder.PrependUint64Slot(int(j), self.uint64Val, 0)
+                elif choice == 9:
+                    builder.PrependFloat32Slot(int(j), self.float32Val, 0)
+                elif choice == 10:
+                    builder.PrependFloat64Slot(int(j), self.float64Val, 0)
+                else:
+                    raise RuntimeError('unreachable')
+
+            off = builder.EndObject()
+
+            # store the offset from the end of the builder buffer,
+            # since it will keep growing:
+            objects[i] = off
+
+        # Do some bookkeeping to generate stats on fuzzes:
+        stats = defaultdict(int)
+        def check(table, desc, want, got):
+            stats[desc] += 1
+            self.assertEqual(want, got, "%s != %s, %s" % (want, got, desc))
+
+        l = LCG()  # Reset.
+
+        # Test that all objects we generated are readable and return the
+        # expected values. We generate random objects in the same order
+        # so this is deterministic.
+        for i in compat_range(fuzzObjects):
+
+            table = flatbuffers.table.Table(builder.Bytes,
+                                            len(builder.Bytes) - objects[i])
+
+            for j in compat_range(fuzzFields):
+                field_count = flatbuffers.builder.VtableMetadataFields + j
+                f = N.VOffsetTFlags.py_type(field_count *
+                                            N.VOffsetTFlags.bytewidth)
+                choice = int(l.Next()) % testValuesMax
+
+                if choice == 0:
+                    check(table, "bool", self.boolVal,
+                          table.GetSlot(f, False, N.BoolFlags))
+                elif choice == 1:
+                    check(table, "int8", self.int8Val,
+                          table.GetSlot(f, 0, N.Int8Flags))
+                elif choice == 2:
+                    check(table, "uint8", self.uint8Val,
+                          table.GetSlot(f, 0, N.Uint8Flags))
+                elif choice == 3:
+                    check(table, "int16", self.int16Val,
+                          table.GetSlot(f, 0, N.Int16Flags))
+                elif choice == 4:
+                    check(table, "uint16", self.uint16Val,
+                          table.GetSlot(f, 0, N.Uint16Flags))
+                elif choice == 5:
+                    check(table, "int32", self.int32Val,
+                          table.GetSlot(f, 0, N.Int32Flags))
+                elif choice == 6:
+                    check(table, "uint32", self.uint32Val,
+                          table.GetSlot(f, 0, N.Uint32Flags))
+                elif choice == 7:
+                    check(table, "int64", self.int64Val,
+                          table.GetSlot(f, 0, N.Int64Flags))
+                elif choice == 8:
+                    check(table, "uint64", self.uint64Val,
+                          table.GetSlot(f, 0, N.Uint64Flags))
+                elif choice == 9:
+                    check(table, "float32", self.float32Val,
+                          table.GetSlot(f, 0, N.Float32Flags))
+                elif choice == 10:
+                    check(table, "float64", self.float64Val,
+                          table.GetSlot(f, 0, N.Float64Flags))
+                else:
+                    raise RuntimeError('unreachable')
+
+        # If enough checks were made, verify that all scalar types were used:
+        self.assertEqual(testValuesMax, len(stats),
+                "fuzzing failed to test all scalar types: %s" % stats)
+
+
+class TestByteLayout(unittest.TestCase):
+    ''' TestByteLayout checks the bytes of a Builder in various scenarios. '''
+
+    def assertBuilderEquals(self, builder, want_chars_or_ints):
+        def integerize(x):
+            if isinstance(x, compat.string_types):
+                return ord(x)
+            return x
+
+        want_ints = list(map(integerize, want_chars_or_ints))
+        want = bytearray(want_ints)
+        got = builder.Bytes[builder.Head():] # use the buffer directly
+        self.assertEqual(want, got)
+
+    def test_numbers(self):
+        b = flatbuffers.Builder(0)
+        self.assertBuilderEquals(b, [])
+        b.PrependBool(True)
+        self.assertBuilderEquals(b, [1])
+        b.PrependInt8(-127)
+        self.assertBuilderEquals(b, [129, 1])
+        b.PrependUint8(255)
+        self.assertBuilderEquals(b, [255, 129, 1])
+        b.PrependInt16(-32222)
+        self.assertBuilderEquals(b, [0x22, 0x82, 0, 255, 129, 1]) # first pad
+        b.PrependUint16(0xFEEE)
+        # no pad this time:
+        self.assertBuilderEquals(b, [0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1])
+        b.PrependInt32(-53687092)
+        self.assertBuilderEquals(b, [204, 204, 204, 252, 0xEE, 0xFE,
+                                     0x22, 0x82, 0, 255, 129, 1])
+        b.PrependUint32(0x98765432)
+        self.assertBuilderEquals(b, [0x32, 0x54, 0x76, 0x98,
+                                     204, 204, 204, 252,
+                                     0xEE, 0xFE, 0x22, 0x82,
+                                     0, 255, 129, 1])
+
+    def test_numbers64(self):
+        b = flatbuffers.Builder(0)
+        b.PrependUint64(0x1122334455667788)
+        self.assertBuilderEquals(b, [0x88, 0x77, 0x66, 0x55,
+                                     0x44, 0x33, 0x22, 0x11])
+
+        b = flatbuffers.Builder(0)
+        b.PrependInt64(0x1122334455667788)
+        self.assertBuilderEquals(b, [0x88, 0x77, 0x66, 0x55,
+                                     0x44, 0x33, 0x22, 0x11])
+
+    def test_1xbyte_vector(self):
+        b = flatbuffers.Builder(0)
+        self.assertBuilderEquals(b, [])
+        b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 1, 1)
+        self.assertBuilderEquals(b, [0, 0, 0]) # align to 4bytes
+        b.PrependByte(1)
+        self.assertBuilderEquals(b, [1, 0, 0, 0])
+        b.EndVector(1)
+        self.assertBuilderEquals(b, [1, 0, 0, 0, 1, 0, 0, 0]) # padding
+
+    def test_2xbyte_vector(self):
+        b = flatbuffers.Builder(0)
+        b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 2, 1)
+        self.assertBuilderEquals(b, [0, 0]) # align to 4bytes
+        b.PrependByte(1)
+        self.assertBuilderEquals(b, [1, 0, 0])
+        b.PrependByte(2)
+        self.assertBuilderEquals(b, [2, 1, 0, 0])
+        b.EndVector(2)
+        self.assertBuilderEquals(b, [2, 0, 0, 0, 2, 1, 0, 0]) # padding
+
+    def test_1xuint16_vector(self):
+        b = flatbuffers.Builder(0)
+        b.StartVector(flatbuffers.number_types.Uint16Flags.bytewidth, 1, 1)
+        self.assertBuilderEquals(b, [0, 0]) # align to 4bytes
+        b.PrependUint16(1)
+        self.assertBuilderEquals(b, [1, 0, 0, 0])
+        b.EndVector(1)
+        self.assertBuilderEquals(b, [1, 0, 0, 0, 1, 0, 0, 0]) # padding
+
+    def test_2xuint16_vector(self):
+        b = flatbuffers.Builder(0)
+        b.StartVector(flatbuffers.number_types.Uint16Flags.bytewidth, 2, 1)
+        self.assertBuilderEquals(b, []) # align to 4bytes
+        b.PrependUint16(0xABCD)
+        self.assertBuilderEquals(b, [0xCD, 0xAB])
+        b.PrependUint16(0xDCBA)
+        self.assertBuilderEquals(b, [0xBA, 0xDC, 0xCD, 0xAB])
+        b.EndVector(2)
+        self.assertBuilderEquals(b, [2, 0, 0, 0, 0xBA, 0xDC, 0xCD, 0xAB])
+
+    def test_create_ascii_string(self):
+        b = flatbuffers.Builder(0)
+        b.CreateString(u"foo", encoding='ascii')
+
+        # 0-terminated, no pad:
+        self.assertBuilderEquals(b, [3, 0, 0, 0, 'f', 'o', 'o', 0])
+        b.CreateString(u"moop", encoding='ascii')
+        # 0-terminated, 3-byte pad:
+        self.assertBuilderEquals(b, [4, 0, 0, 0, 'm', 'o', 'o', 'p',
+                                     0, 0, 0, 0,
+                                     3, 0, 0, 0, 'f', 'o', 'o', 0])
+
+    def test_create_utf8_string(self):
+        b = flatbuffers.Builder(0)
+        b.CreateString(u"Цлїςσδε")
+        self.assertBuilderEquals(b, "\x0e\x00\x00\x00\xd0\xa6\xd0\xbb\xd1\x97" \
+            "\xcf\x82\xcf\x83\xce\xb4\xce\xb5\x00\x00")
+
+        b.CreateString(u"ﾌﾑｱﾑｶﾓｹﾓ")
+        self.assertBuilderEquals(b, "\x18\x00\x00\x00\xef\xbe\x8c\xef\xbe\x91" \
+            "\xef\xbd\xb1\xef\xbe\x91\xef\xbd\xb6\xef\xbe\x93\xef\xbd\xb9\xef" \
+            "\xbe\x93\x00\x00\x00\x00\x0e\x00\x00\x00\xd0\xa6\xd0\xbb\xd1\x97" \
+            "\xcf\x82\xcf\x83\xce\xb4\xce\xb5\x00\x00")
+
+    def test_create_arbitrary_string(self):
+        b = flatbuffers.Builder(0)
+        s = "\x01\x02\x03"
+        b.CreateString(s) # Default encoding is utf-8.
+        # 0-terminated, no pad:
+        self.assertBuilderEquals(b, [3, 0, 0, 0, 1, 2, 3, 0])
+        s2 = "\x04\x05\x06\x07"
+        b.CreateString(s2) # Default encoding is utf-8.
+        # 0-terminated, 3-byte pad:
+        self.assertBuilderEquals(b, [4, 0, 0, 0, 4, 5, 6, 7, 0, 0, 0, 0,
+                                     3, 0, 0, 0, 1, 2, 3, 0])
+
+    def test_create_byte_vector(self):
+        b = flatbuffers.Builder(0)
+        b.CreateByteVector(b"")
+        # 0-byte pad:
+        self.assertBuilderEquals(b, [0, 0, 0, 0])
+
+        b = flatbuffers.Builder(0)
+        b.CreateByteVector(b"\x01\x02\x03")
+        # 1-byte pad:
+        self.assertBuilderEquals(b, [3, 0, 0, 0, 1, 2, 3, 0])
+
+    def test_create_numpy_vector_int8(self):
+        try:
+            imp.find_module('numpy')
+            # if numpy exists, then we should be able to get the
+            # vector as a numpy array
+            import numpy as np
+
+            # Systems endian:
+            b = flatbuffers.Builder(0)
+            x = np.array([1, 2, -3], dtype=np.int8)
+            b.CreateNumpyVector(x)
+            self.assertBuilderEquals(b, [
+                3, 0, 0, 0,  # vector length
+                1, 2, 256 - 3, 0   # vector value + padding
+            ])
+
+            # Reverse endian:
+            b = flatbuffers.Builder(0)
+            x_other_endian = x.byteswap().newbyteorder()
+            b.CreateNumpyVector(x_other_endian)
+            self.assertBuilderEquals(b, [
+                3, 0, 0, 0,  # vector length
+                1, 2, 256 - 3, 0   # vector value + padding
+            ])
+        except ImportError:
+            b = flatbuffers.Builder(0)
+            x = 0
+            assertRaises(
+                self,
+                lambda: b.CreateNumpyVector(x),
+                NumpyRequiredForThisFeature)
+
+    def test_create_numpy_vector_uint16(self):
+        try:
+            imp.find_module('numpy')
+            # if numpy exists, then we should be able to get the
+            # vector as a numpy array
+            import numpy as np
+
+            # Systems endian:
+            b = flatbuffers.Builder(0)
+            x = np.array([1, 2, 312], dtype=np.uint16)
+            b.CreateNumpyVector(x)
+            self.assertBuilderEquals(b, [
+                3, 0, 0, 0,     # vector length
+                1, 0,           # 1
+                2, 0,           # 2
+                312 - 256, 1,   # 312
+                0, 0            # padding
+            ])
+
+            # Reverse endian:
+            b = flatbuffers.Builder(0)
+            x_other_endian = x.byteswap().newbyteorder()
+            b.CreateNumpyVector(x_other_endian)
+            self.assertBuilderEquals(b, [
+                3, 0, 0, 0,     # vector length
+                1, 0,           # 1
+                2, 0,           # 2
+                312 - 256, 1,   # 312
+                0, 0            # padding
+            ])
+        except ImportError:
+            b = flatbuffers.Builder(0)
+            x = 0
+            assertRaises(
+                self,
+                lambda: b.CreateNumpyVector(x),
+                NumpyRequiredForThisFeature)
+
+    def test_create_numpy_vector_int64(self):
+        try:
+            imp.find_module('numpy')
+            # if numpy exists, then we should be able to get the
+            # vector as a numpy array
+            import numpy as np
+
+            # Systems endian:
+            b = flatbuffers.Builder(0)
+            x = np.array([1, 2, -12], dtype=np.int64)
+            b.CreateNumpyVector(x)
+            self.assertBuilderEquals(b, [
+                3, 0, 0, 0,                     # vector length
+                1, 0, 0, 0, 0, 0, 0, 0,         # 1
+                2, 0, 0, 0, 0, 0, 0, 0,         # 2
+                256 - 12, 255, 255, 255, 255, 255, 255, 255   # -12
+            ])
+
+            # Reverse endian:
+            b = flatbuffers.Builder(0)
+            x_other_endian = x.byteswap().newbyteorder()
+            b.CreateNumpyVector(x_other_endian)
+            self.assertBuilderEquals(b, [
+                3, 0, 0, 0,                     # vector length
+                1, 0, 0, 0, 0, 0, 0, 0,         # 1
+                2, 0, 0, 0, 0, 0, 0, 0,         # 2
+                256 - 12, 255, 255, 255, 255, 255, 255, 255   # -12
+            ])
+
+        except ImportError:
+            b = flatbuffers.Builder(0)
+            x = 0
+            assertRaises(
+                self,
+                lambda: b.CreateNumpyVector(x),
+                NumpyRequiredForThisFeature)
+
+    def test_create_numpy_vector_float32(self):
+        try:
+            imp.find_module('numpy')
+            # if numpy exists, then we should be able to get the
+            # vector as a numpy array
+            import numpy as np
+
+            # Systems endian:
+            b = flatbuffers.Builder(0)
+            x = np.array([1, 2, -12], dtype=np.float32)
+            b.CreateNumpyVector(x)
+            self.assertBuilderEquals(b, [
+                3, 0, 0, 0,                     # vector length
+                0, 0, 128, 63,                  # 1
+                0, 0, 0, 64,                    # 2
+                0, 0, 64, 193                   # -12
+            ])
+
+            # Reverse endian:
+            b = flatbuffers.Builder(0)
+            x_other_endian = x.byteswap().newbyteorder()
+            b.CreateNumpyVector(x_other_endian)
+            self.assertBuilderEquals(b, [
+                3, 0, 0, 0,                     # vector length
+                0, 0, 128, 63,                  # 1
+                0, 0, 0, 64,                    # 2
+                0, 0, 64, 193                   # -12
+            ])
+
+        except ImportError:
+            b = flatbuffers.Builder(0)
+            x = 0
+            assertRaises(
+                self,
+                lambda: b.CreateNumpyVector(x),
+                NumpyRequiredForThisFeature)
+
+    def test_create_numpy_vector_float64(self):
+        try:
+            imp.find_module('numpy')
+            # if numpy exists, then we should be able to get the
+            # vector as a numpy array
+            import numpy as np
+
+            # Systems endian:
+            b = flatbuffers.Builder(0)
+            x = np.array([1, 2, -12], dtype=np.float64)
+            b.CreateNumpyVector(x)
+            self.assertBuilderEquals(b, [
+                3, 0, 0, 0,                     # vector length
+                0, 0, 0, 0, 0, 0, 240, 63,                  # 1
+                0, 0, 0, 0, 0, 0, 0, 64,                    # 2
+                0, 0, 0, 0, 0, 0, 40, 192                   # -12
+            ])
+
+            # Reverse endian:
+            b = flatbuffers.Builder(0)
+            x_other_endian = x.byteswap().newbyteorder()
+            b.CreateNumpyVector(x_other_endian)
+            self.assertBuilderEquals(b, [
+                3, 0, 0, 0,                     # vector length
+                0, 0, 0, 0, 0, 0, 240, 63,                  # 1
+                0, 0, 0, 0, 0, 0, 0, 64,                    # 2
+                0, 0, 0, 0, 0, 0, 40, 192                   # -12
+            ])
+
+        except ImportError:
+            b = flatbuffers.Builder(0)
+            x = 0
+            assertRaises(
+                self,
+                lambda: b.CreateNumpyVector(x),
+                NumpyRequiredForThisFeature)
+
+    def test_create_numpy_vector_bool(self):
+        try:
+            imp.find_module('numpy')
+            # if numpy exists, then we should be able to get the
+            # vector as a numpy array
+            import numpy as np
+
+            # Systems endian:
+            b = flatbuffers.Builder(0)
+            x = np.array([True, False, True], dtype=np.bool)
+            b.CreateNumpyVector(x)
+            self.assertBuilderEquals(b, [
+                3, 0, 0, 0, # vector length
+                1, 0, 1, 0  # vector values + padding
+            ])
+
+            # Reverse endian:
+            b = flatbuffers.Builder(0)
+            x_other_endian = x.byteswap().newbyteorder()
+            b.CreateNumpyVector(x_other_endian)
+            self.assertBuilderEquals(b, [
+                3, 0, 0, 0, # vector length
+                1, 0, 1, 0  # vector values + padding
+            ])
+
+        except ImportError:
+            b = flatbuffers.Builder(0)
+            x = 0
+            assertRaises(
+                self,
+                lambda: b.CreateNumpyVector(x),
+                NumpyRequiredForThisFeature)
+
+    def test_create_numpy_vector_reject_strings(self):
+        try:
+            imp.find_module('numpy')
+            # if numpy exists, then we should be able to get the
+            # vector as a numpy array
+            import numpy as np
+
+            # Create String array
+            b = flatbuffers.Builder(0)
+            x = np.array(["hello", "fb", "testing"])
+            assertRaises(
+                self,
+                lambda: b.CreateNumpyVector(x),
+                TypeError)
+
+        except ImportError:
+            b = flatbuffers.Builder(0)
+            x = 0
+            assertRaises(
+                self,
+                lambda: b.CreateNumpyVector(x),
+                NumpyRequiredForThisFeature)
+
+    def test_create_numpy_vector_reject_object(self):
+        try:
+            imp.find_module('numpy')
+            # if numpy exists, then we should be able to get the
+            # vector as a numpy array
+            import numpy as np
+
+            # Create String array
+            b = flatbuffers.Builder(0)
+            x = np.array([{"m": 0}, {"as": -2.1, 'c': 'c'}])
+            assertRaises(
+                self,
+                lambda: b.CreateNumpyVector(x),
+                TypeError)
+
+        except ImportError:
+            b = flatbuffers.Builder(0)
+            x = 0
+            assertRaises(
+                self,
+                lambda: b.CreateNumpyVector(x),
+                NumpyRequiredForThisFeature)
+
+    def test_empty_vtable(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(0)
+        self.assertBuilderEquals(b, [])
+        b.EndObject()
+        self.assertBuilderEquals(b, [4, 0, 4, 0, 4, 0, 0, 0])
+
+    def test_vtable_with_one_true_bool(self):
+        b = flatbuffers.Builder(0)
+        self.assertBuilderEquals(b, [])
+        b.StartObject(1)
+        self.assertBuilderEquals(b, [])
+        b.PrependBoolSlot(0, True, False)
+        b.EndObject()
+        self.assertBuilderEquals(b, [
+            6, 0,  # vtable bytes
+            8, 0,  # length of object including vtable offset
+            7, 0,  # start of bool value
+            6, 0, 0, 0,  # offset for start of vtable (int32)
+            0, 0, 0,  # padded to 4 bytes
+            1,  # bool value
+        ])
+
+    def test_vtable_with_one_default_bool(self):
+        b = flatbuffers.Builder(0)
+        self.assertBuilderEquals(b, [])
+        b.StartObject(1)
+        self.assertBuilderEquals(b, [])
+        b.PrependBoolSlot(0, False, False)
+        b.EndObject()
+        self.assertBuilderEquals(b, [
+            4, 0,  # vtable bytes
+            4, 0,  # end of object from here
+            # entry 1 is zero and not stored
+            4, 0, 0, 0,  # offset for start of vtable (int32)
+        ])
+
+    def test_vtable_with_one_int16(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(1)
+        b.PrependInt16Slot(0, 0x789A, 0)
+        b.EndObject()
+        self.assertBuilderEquals(b, [
+            6, 0,  # vtable bytes
+            8, 0,  # end of object from here
+            6, 0,  # offset to value
+            6, 0, 0, 0,  # offset for start of vtable (int32)
+            0, 0,  # padding to 4 bytes
+            0x9A, 0x78,
+        ])
+
+    def test_vtable_with_two_int16(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(2)
+        b.PrependInt16Slot(0, 0x3456, 0)
+        b.PrependInt16Slot(1, 0x789A, 0)
+        b.EndObject()
+        self.assertBuilderEquals(b, [
+            8, 0,  # vtable bytes
+            8, 0,  # end of object from here
+            6, 0,  # offset to value 0
+            4, 0,  # offset to value 1
+            8, 0, 0, 0,  # offset for start of vtable (int32)
+            0x9A, 0x78,  # value 1
+            0x56, 0x34,  # value 0
+        ])
+
+    def test_vtable_with_int16_and_bool(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(2)
+        b.PrependInt16Slot(0, 0x3456, 0)
+        b.PrependBoolSlot(1, True, False)
+        b.EndObject()
+        self.assertBuilderEquals(b, [
+            8, 0,  # vtable bytes
+            8, 0,  # end of object from here
+            6, 0,  # offset to value 0
+            5, 0,  # offset to value 1
+            8, 0, 0, 0,  # offset for start of vtable (int32)
+            0,          # padding
+            1,          # value 1
+            0x56, 0x34,  # value 0
+        ])
+
+    def test_vtable_with_empty_vector(self):
+        b = flatbuffers.Builder(0)
+        b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 0, 1)
+        vecend = b.EndVector(0)
+        b.StartObject(1)
+        b.PrependUOffsetTRelativeSlot(0, vecend, 0)
+        b.EndObject()
+        self.assertBuilderEquals(b, [
+            6, 0,  # vtable bytes
+            8, 0,
+            4, 0,  # offset to vector offset
+            6, 0, 0, 0,  # offset for start of vtable (int32)
+            4, 0, 0, 0,
+            0, 0, 0, 0,  # length of vector (not in struct)
+        ])
+
+    def test_vtable_with_empty_vector_of_byte_and_some_scalars(self):
+        b = flatbuffers.Builder(0)
+        b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 0, 1)
+        vecend = b.EndVector(0)
+        b.StartObject(2)
+        b.PrependInt16Slot(0, 55, 0)
+        b.PrependUOffsetTRelativeSlot(1, vecend, 0)
+        b.EndObject()
+        self.assertBuilderEquals(b, [
+            8, 0,  # vtable bytes
+            12, 0,
+            10, 0,  # offset to value 0
+            4, 0,  # offset to vector offset
+            8, 0, 0, 0,  # vtable loc
+            8, 0, 0, 0,  # value 1
+            0, 0, 55, 0,  # value 0
+
+            0, 0, 0, 0,  # length of vector (not in struct)
+        ])
+
+    def test_vtable_with_1_int16_and_2vector_of_int16(self):
+        b = flatbuffers.Builder(0)
+        b.StartVector(flatbuffers.number_types.Int16Flags.bytewidth, 2, 1)
+        b.PrependInt16(0x1234)
+        b.PrependInt16(0x5678)
+        vecend = b.EndVector(2)
+        b.StartObject(2)
+        b.PrependUOffsetTRelativeSlot(1, vecend, 0)
+        b.PrependInt16Slot(0, 55, 0)
+        b.EndObject()
+        self.assertBuilderEquals(b, [
+            8, 0,  # vtable bytes
+            12, 0,  # length of object
+            6, 0,  # start of value 0 from end of vtable
+            8, 0,  # start of value 1 from end of buffer
+            8, 0, 0, 0,  # offset for start of vtable (int32)
+            0, 0,  # padding
+            55, 0,  # value 0
+            4, 0, 0, 0,  # vector position from here
+            2, 0, 0, 0,  # length of vector (uint32)
+            0x78, 0x56,  # vector value 1
+            0x34, 0x12,  # vector value 0
+        ])
+
+    def test_vtable_with_1_struct_of_1_int8__1_int16__1_int32(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(1)
+        b.Prep(4+4+4, 0)
+        b.PrependInt8(55)
+        b.Pad(3)
+        b.PrependInt16(0x1234)
+        b.Pad(2)
+        b.PrependInt32(0x12345678)
+        structStart = b.Offset()
+        b.PrependStructSlot(0, structStart, 0)
+        b.EndObject()
+        self.assertBuilderEquals(b, [
+            6, 0,  # vtable bytes
+            16, 0,  # end of object from here
+            4, 0,  # start of struct from here
+            6, 0, 0, 0,  # offset for start of vtable (int32)
+            0x78, 0x56, 0x34, 0x12,  # value 2
+            0, 0,  # padding
+            0x34, 0x12,  # value 1
+            0, 0, 0,  # padding
+            55,  # value 0
+        ])
+
+    def test_vtable_with_1_vector_of_2_struct_of_2_int8(self):
+        b = flatbuffers.Builder(0)
+        b.StartVector(flatbuffers.number_types.Int8Flags.bytewidth*2, 2, 1)
+        b.PrependInt8(33)
+        b.PrependInt8(44)
+        b.PrependInt8(55)
+        b.PrependInt8(66)
+        vecend = b.EndVector(2)
+        b.StartObject(1)
+        b.PrependUOffsetTRelativeSlot(0, vecend, 0)
+        b.EndObject()
+        self.assertBuilderEquals(b, [
+            6, 0,  # vtable bytes
+            8, 0,
+            4, 0,  # offset of vector offset
+            6, 0, 0, 0,  # offset for start of vtable (int32)
+            4, 0, 0, 0,  # vector start offset
+
+            2, 0, 0, 0,  # vector length
+            66,  # vector value 1,1
+            55,  # vector value 1,0
+            44,  # vector value 0,1
+            33,  # vector value 0,0
+        ])
+
+    def test_table_with_some_elements(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(2)
+        b.PrependInt8Slot(0, 33, 0)
+        b.PrependInt16Slot(1, 66, 0)
+        off = b.EndObject()
+        b.Finish(off)
+
+        self.assertBuilderEquals(b, [
+            12, 0, 0, 0,  # root of table: points to vtable offset
+
+            8, 0,  # vtable bytes
+            8, 0,  # end of object from here
+            7, 0,  # start of value 0
+            4, 0,  # start of value 1
+
+            8, 0, 0, 0,  # offset for start of vtable (int32)
+
+            66, 0,  # value 1
+            0,  # padding
+            33,  # value 0
+        ])
+
+    def test__one_unfinished_table_and_one_finished_table(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(2)
+        b.PrependInt8Slot(0, 33, 0)
+        b.PrependInt8Slot(1, 44, 0)
+        off = b.EndObject()
+        b.Finish(off)
+
+        b.StartObject(3)
+        b.PrependInt8Slot(0, 55, 0)
+        b.PrependInt8Slot(1, 66, 0)
+        b.PrependInt8Slot(2, 77, 0)
+        off = b.EndObject()
+        b.Finish(off)
+
+        self.assertBuilderEquals(b, [
+            16, 0, 0, 0,  # root of table: points to object
+            0, 0,  # padding
+
+            10, 0,  # vtable bytes
+            8, 0,  # size of object
+            7, 0,  # start of value 0
+            6, 0,  # start of value 1
+            5, 0,  # start of value 2
+            10, 0, 0, 0,  # offset for start of vtable (int32)
+            0,  # padding
+            77,  # value 2
+            66,  # value 1
+            55,  # value 0
+
+            12, 0, 0, 0,  # root of table: points to object
+
+            8, 0,  # vtable bytes
+            8, 0,  # size of object
+            7, 0,  # start of value 0
+            6, 0,  # start of value 1
+            8, 0, 0, 0,  # offset for start of vtable (int32)
+            0, 0,  # padding
+            44,  # value 1
+            33,  # value 0
+        ])
+
+    def test_a_bunch_of_bools(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(8)
+        b.PrependBoolSlot(0, True, False)
+        b.PrependBoolSlot(1, True, False)
+        b.PrependBoolSlot(2, True, False)
+        b.PrependBoolSlot(3, True, False)
+        b.PrependBoolSlot(4, True, False)
+        b.PrependBoolSlot(5, True, False)
+        b.PrependBoolSlot(6, True, False)
+        b.PrependBoolSlot(7, True, False)
+        off = b.EndObject()
+        b.Finish(off)
+
+        self.assertBuilderEquals(b, [
+            24, 0, 0, 0,  # root of table: points to vtable offset
+
+            20, 0,  # vtable bytes
+            12, 0,  # size of object
+            11, 0,  # start of value 0
+            10, 0,  # start of value 1
+            9, 0,  # start of value 2
+            8, 0,  # start of value 3
+            7, 0,  # start of value 4
+            6, 0,  # start of value 5
+            5, 0,  # start of value 6
+            4, 0,  # start of value 7
+            20, 0, 0, 0,  # vtable offset
+
+            1,  # value 7
+            1,  # value 6
+            1,  # value 5
+            1,  # value 4
+            1,  # value 3
+            1,  # value 2
+            1,  # value 1
+            1,  # value 0
+        ])
+
+    def test_three_bools(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(3)
+        b.PrependBoolSlot(0, True, False)
+        b.PrependBoolSlot(1, True, False)
+        b.PrependBoolSlot(2, True, False)
+        off = b.EndObject()
+        b.Finish(off)
+
+        self.assertBuilderEquals(b, [
+            16, 0, 0, 0,  # root of table: points to vtable offset
+
+            0, 0,  # padding
+
+            10, 0,  # vtable bytes
+            8, 0,  # size of object
+            7, 0,  # start of value 0
+            6, 0,  # start of value 1
+            5, 0,  # start of value 2
+            10, 0, 0, 0,  # vtable offset from here
+
+            0,  # padding
+            1,  # value 2
+            1,  # value 1
+            1,  # value 0
+        ])
+
+    def test_some_floats(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(1)
+        b.PrependFloat32Slot(0, 1.0, 0.0)
+        off = b.EndObject()
+
+        self.assertBuilderEquals(b, [
+            6, 0,  # vtable bytes
+            8, 0,  # size of object
+            4, 0,  # start of value 0
+            6, 0, 0, 0,  # vtable offset
+
+            0, 0, 128, 63,  # value 0
+        ])
+
+
+def make_monster_from_generated_code(sizePrefix = False, file_identifier=None):
+    ''' Use generated code to build the example Monster. '''
+
+    b = flatbuffers.Builder(0)
+    string = b.CreateString("MyMonster")
+    test1 = b.CreateString("test1")
+    test2 = b.CreateString("test2")
+    fred = b.CreateString("Fred")
+
+    MyGame.Example.Monster.MonsterStartInventoryVector(b, 5)
+    b.PrependByte(4)
+    b.PrependByte(3)
+    b.PrependByte(2)
+    b.PrependByte(1)
+    b.PrependByte(0)
+    inv = b.EndVector(5)
+
+    MyGame.Example.Monster.MonsterStart(b)
+    MyGame.Example.Monster.MonsterAddName(b, fred)
+    mon2 = MyGame.Example.Monster.MonsterEnd(b)
+
+    MyGame.Example.Monster.MonsterStartTest4Vector(b, 2)
+    MyGame.Example.Test.CreateTest(b, 10, 20)
+    MyGame.Example.Test.CreateTest(b, 30, 40)
+    test4 = b.EndVector(2)
+
+    MyGame.Example.Monster.MonsterStartTestarrayofstringVector(b, 2)
+    b.PrependUOffsetTRelative(test2)
+    b.PrependUOffsetTRelative(test1)
+    testArrayOfString = b.EndVector(2)
+
+    MyGame.Example.Monster.MonsterStartVectorOfLongsVector(b, 5)
+    b.PrependInt64(100000000)
+    b.PrependInt64(1000000)
+    b.PrependInt64(10000)
+    b.PrependInt64(100)
+    b.PrependInt64(1)
+    VectorOfLongs = b.EndVector(5)
+
+    MyGame.Example.Monster.MonsterStartVectorOfDoublesVector(b, 3)
+    b.PrependFloat64(1.7976931348623157e+308)
+    b.PrependFloat64(0)
+    b.PrependFloat64(-1.7976931348623157e+308)
+    VectorOfDoubles = b.EndVector(3)
+
+    MyGame.Example.Monster.MonsterStart(b)
+
+    pos = MyGame.Example.Vec3.CreateVec3(b, 1.0, 2.0, 3.0, 3.0, 2, 5, 6)
+    MyGame.Example.Monster.MonsterAddPos(b, pos)
+
+    MyGame.Example.Monster.MonsterAddHp(b, 80)
+    MyGame.Example.Monster.MonsterAddName(b, string)
+    MyGame.Example.Monster.MonsterAddInventory(b, inv)
+    MyGame.Example.Monster.MonsterAddTestType(b, 1)
+    MyGame.Example.Monster.MonsterAddTest(b, mon2)
+    MyGame.Example.Monster.MonsterAddTest4(b, test4)
+    MyGame.Example.Monster.MonsterAddTestarrayofstring(b, testArrayOfString)
+    MyGame.Example.Monster.MonsterAddVectorOfLongs(b, VectorOfLongs)
+    MyGame.Example.Monster.MonsterAddVectorOfDoubles(b, VectorOfDoubles)
+    mon = MyGame.Example.Monster.MonsterEnd(b)
+
+    if sizePrefix:
+        b.FinishSizePrefixed(mon, file_identifier)
+    else:
+        b.Finish(mon, file_identifier)
+
+    return b.Bytes, b.Head()
+
+
+class TestAllCodePathsOfExampleSchema(unittest.TestCase):
+    def setUp(self, *args, **kwargs):
+        super(TestAllCodePathsOfExampleSchema, self).setUp(*args, **kwargs)
+
+        b = flatbuffers.Builder(0)
+        MyGame.Example.Monster.MonsterStart(b)
+        gen_mon = MyGame.Example.Monster.MonsterEnd(b)
+        b.Finish(gen_mon)
+
+        self.mon = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+                                                                   b.Head())
+
+    def test_default_monster_pos(self):
+        self.assertTrue(self.mon.Pos() is None)
+
+    def test_nondefault_monster_mana(self):
+        b = flatbuffers.Builder(0)
+        MyGame.Example.Monster.MonsterStart(b)
+        MyGame.Example.Monster.MonsterAddMana(b, 50)
+        mon = MyGame.Example.Monster.MonsterEnd(b)
+        b.Finish(mon)
+
+        got_mon = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+                                                                  b.Head())
+        self.assertEqual(50, got_mon.Mana())
+
+    def test_default_monster_hp(self):
+        self.assertEqual(100, self.mon.Hp())
+
+    def test_default_monster_name(self):
+        self.assertEqual(None, self.mon.Name())
+
+    def test_default_monster_inventory_item(self):
+        self.assertEqual(0, self.mon.Inventory(0))
+
+    def test_default_monster_inventory_length(self):
+        self.assertEqual(0, self.mon.InventoryLength())
+
+    def test_default_monster_color(self):
+        self.assertEqual(MyGame.Example.Color.Color.Blue, self.mon.Color())
+
+    def test_nondefault_monster_color(self):
+        b = flatbuffers.Builder(0)
+        color = MyGame.Example.Color.Color.Red
+        MyGame.Example.Monster.MonsterStart(b)
+        MyGame.Example.Monster.MonsterAddColor(b, color)
+        mon = MyGame.Example.Monster.MonsterEnd(b)
+        b.Finish(mon)
+
+        mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+                                                               b.Head())
+        self.assertEqual(MyGame.Example.Color.Color.Red, mon2.Color())
+
+    def test_default_monster_testtype(self):
+        self.assertEqual(0, self.mon.TestType())
+
+    def test_default_monster_test_field(self):
+        self.assertEqual(None, self.mon.Test())
+
+    def test_default_monster_test4_item(self):
+        self.assertEqual(None, self.mon.Test4(0))
+
+    def test_default_monster_test4_length(self):
+        self.assertEqual(0, self.mon.Test4Length())
+
+    def test_default_monster_testarrayofstring(self):
+        self.assertEqual("", self.mon.Testarrayofstring(0))
+
+    def test_default_monster_testarrayofstring_length(self):
+        self.assertEqual(0, self.mon.TestarrayofstringLength())
+
+    def test_default_monster_testarrayoftables(self):
+        self.assertEqual(None, self.mon.Testarrayoftables(0))
+
+    def test_nondefault_monster_testarrayoftables(self):
+        b = flatbuffers.Builder(0)
+
+        # make a child Monster within a vector of Monsters:
+        MyGame.Example.Monster.MonsterStart(b)
+        MyGame.Example.Monster.MonsterAddHp(b, 99)
+        sub_monster = MyGame.Example.Monster.MonsterEnd(b)
+
+        # build the vector:
+        MyGame.Example.Monster.MonsterStartTestarrayoftablesVector(b, 1)
+        b.PrependUOffsetTRelative(sub_monster)
+        vec = b.EndVector(1)
+
+        # make the parent monster and include the vector of Monster:
+        MyGame.Example.Monster.MonsterStart(b)
+        MyGame.Example.Monster.MonsterAddTestarrayoftables(b, vec)
+        mon = MyGame.Example.Monster.MonsterEnd(b)
+        b.Finish(mon)
+
+        # inspect the resulting data:
+        mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Output(), 0)
+        self.assertEqual(99, mon2.Testarrayoftables(0).Hp())
+        self.assertEqual(1, mon2.TestarrayoftablesLength())
+
+    def test_default_monster_testarrayoftables_length(self):
+        self.assertEqual(0, self.mon.TestarrayoftablesLength())
+
+    def test_nondefault_monster_enemy(self):
+        b = flatbuffers.Builder(0)
+
+        # make an Enemy object:
+        MyGame.Example.Monster.MonsterStart(b)
+        MyGame.Example.Monster.MonsterAddHp(b, 88)
+        enemy = MyGame.Example.Monster.MonsterEnd(b)
+        b.Finish(enemy)
+
+        # make the parent monster and include the vector of Monster:
+        MyGame.Example.Monster.MonsterStart(b)
+        MyGame.Example.Monster.MonsterAddEnemy(b, enemy)
+        mon = MyGame.Example.Monster.MonsterEnd(b)
+        b.Finish(mon)
+
+        # inspect the resulting data:
+        mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+                                                               b.Head())
+        self.assertEqual(88, mon2.Enemy().Hp())
+
+    def test_default_monster_testnestedflatbuffer(self):
+        self.assertEqual(0, self.mon.Testnestedflatbuffer(0))
+
+    def test_default_monster_testnestedflatbuffer_length(self):
+        self.assertEqual(0, self.mon.TestnestedflatbufferLength())
+
+    def test_nondefault_monster_testnestedflatbuffer(self):
+        b = flatbuffers.Builder(0)
+
+        MyGame.Example.Monster.MonsterStartTestnestedflatbufferVector(b, 3)
+        b.PrependByte(4)
+        b.PrependByte(2)
+        b.PrependByte(0)
+        sub_buf = b.EndVector(3)
+
+        # make the parent monster and include the vector of Monster:
+        MyGame.Example.Monster.MonsterStart(b)
+        MyGame.Example.Monster.MonsterAddTestnestedflatbuffer(b, sub_buf)
+        mon = MyGame.Example.Monster.MonsterEnd(b)
+        b.Finish(mon)
+
+        # inspect the resulting data:
+        mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+                                                               b.Head())
+        self.assertEqual(3, mon2.TestnestedflatbufferLength())
+        self.assertEqual(0, mon2.Testnestedflatbuffer(0))
+        self.assertEqual(2, mon2.Testnestedflatbuffer(1))
+        self.assertEqual(4, mon2.Testnestedflatbuffer(2))
+        try:
+            imp.find_module('numpy')
+            # if numpy exists, then we should be able to get the
+            # vector as a numpy array
+            self.assertEqual([0, 2, 4], mon2.TestnestedflatbufferAsNumpy().tolist())
+        except ImportError:
+            assertRaises(self,
+                         lambda: mon2.TestnestedflatbufferAsNumpy(),
+                         NumpyRequiredForThisFeature)
+
+    def test_nondefault_monster_testempty(self):
+        b = flatbuffers.Builder(0)
+
+        # make a Stat object:
+        MyGame.Example.Stat.StatStart(b)
+        MyGame.Example.Stat.StatAddVal(b, 123)
+        my_stat = MyGame.Example.Stat.StatEnd(b)
+        b.Finish(my_stat)
+
+        # include the stat object in a monster:
+        MyGame.Example.Monster.MonsterStart(b)
+        MyGame.Example.Monster.MonsterAddTestempty(b, my_stat)
+        mon = MyGame.Example.Monster.MonsterEnd(b)
+        b.Finish(mon)
+
+        # inspect the resulting data:
+        mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+                                                               b.Head())
+        self.assertEqual(123, mon2.Testempty().Val())
+
+    def test_default_monster_testbool(self):
+        self.assertFalse(self.mon.Testbool())
+
+    def test_nondefault_monster_testbool(self):
+        b = flatbuffers.Builder(0)
+        MyGame.Example.Monster.MonsterStart(b)
+        MyGame.Example.Monster.MonsterAddTestbool(b, True)
+        mon = MyGame.Example.Monster.MonsterEnd(b)
+        b.Finish(mon)
+
+        # inspect the resulting data:
+        mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+                                                               b.Head())
+        self.assertTrue(mon2.Testbool())
+
+    def test_default_monster_testhashes(self):
+        self.assertEqual(0, self.mon.Testhashs32Fnv1())
+        self.assertEqual(0, self.mon.Testhashu32Fnv1())
+        self.assertEqual(0, self.mon.Testhashs64Fnv1())
+        self.assertEqual(0, self.mon.Testhashu64Fnv1())
+        self.assertEqual(0, self.mon.Testhashs32Fnv1a())
+        self.assertEqual(0, self.mon.Testhashu32Fnv1a())
+        self.assertEqual(0, self.mon.Testhashs64Fnv1a())
+        self.assertEqual(0, self.mon.Testhashu64Fnv1a())
+
+    def test_nondefault_monster_testhashes(self):
+        b = flatbuffers.Builder(0)
+        MyGame.Example.Monster.MonsterStart(b)
+        MyGame.Example.Monster.MonsterAddTesthashs32Fnv1(b, 1)
+        MyGame.Example.Monster.MonsterAddTesthashu32Fnv1(b, 2)
+        MyGame.Example.Monster.MonsterAddTesthashs64Fnv1(b, 3)
+        MyGame.Example.Monster.MonsterAddTesthashu64Fnv1(b, 4)
+        MyGame.Example.Monster.MonsterAddTesthashs32Fnv1a(b, 5)
+        MyGame.Example.Monster.MonsterAddTesthashu32Fnv1a(b, 6)
+        MyGame.Example.Monster.MonsterAddTesthashs64Fnv1a(b, 7)
+        MyGame.Example.Monster.MonsterAddTesthashu64Fnv1a(b, 8)
+        mon = MyGame.Example.Monster.MonsterEnd(b)
+        b.Finish(mon)
+
+        # inspect the resulting data:
+        mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+                                                               b.Head())
+        self.assertEqual(1, mon2.Testhashs32Fnv1())
+        self.assertEqual(2, mon2.Testhashu32Fnv1())
+        self.assertEqual(3, mon2.Testhashs64Fnv1())
+        self.assertEqual(4, mon2.Testhashu64Fnv1())
+        self.assertEqual(5, mon2.Testhashs32Fnv1a())
+        self.assertEqual(6, mon2.Testhashu32Fnv1a())
+        self.assertEqual(7, mon2.Testhashs64Fnv1a())
+        self.assertEqual(8, mon2.Testhashu64Fnv1a())
+
+    def test_getrootas_for_nonroot_table(self):
+        b = flatbuffers.Builder(0)
+        string = b.CreateString("MyStat")
+
+        MyGame.Example.Stat.StatStart(b)
+        MyGame.Example.Stat.StatAddId(b, string)
+        MyGame.Example.Stat.StatAddVal(b, 12345678)
+        MyGame.Example.Stat.StatAddCount(b, 12345)
+        stat = MyGame.Example.Stat.StatEnd(b)
+        b.Finish(stat)
+
+        stat2 = MyGame.Example.Stat.Stat.GetRootAsStat(b.Bytes, b.Head())
+
+        self.assertEqual(b"MyStat", stat2.Id())
+        self.assertEqual(12345678, stat2.Val())
+        self.assertEqual(12345, stat2.Count())
+
+
+class TestAllCodePathsOfMonsterExtraSchema(unittest.TestCase):
+    def setUp(self, *args, **kwargs):
+        super(TestAllCodePathsOfMonsterExtraSchema, self).setUp(*args, **kwargs)
+
+        b = flatbuffers.Builder(0)
+        MyGame.MonsterExtra.MonsterExtraStart(b)
+        gen_mon = MyGame.MonsterExtra.MonsterExtraEnd(b)
+        b.Finish(gen_mon)
+
+        self.mon = MyGame.MonsterExtra.MonsterExtra.GetRootAsMonsterExtra(b.Bytes, b.Head())
+
+    def test_default_nan_inf(self):
+        self.assertTrue(math.isnan(self.mon.F1()))
+        self.assertEqual(self.mon.F2(), float("inf"))
+        self.assertEqual(self.mon.F3(), float("-inf"))
+
+        self.assertTrue(math.isnan(self.mon.D1()))
+        self.assertEqual(self.mon.D2(), float("inf"))
+        self.assertEqual(self.mon.D3(), float("-inf"))
+
+
+class TestVtableDeduplication(unittest.TestCase):
+    ''' TestVtableDeduplication verifies that vtables are deduplicated. '''
+
+    def test_vtable_deduplication(self):
+        b = flatbuffers.Builder(0)
+
+        b.StartObject(4)
+        b.PrependByteSlot(0, 0, 0)
+        b.PrependByteSlot(1, 11, 0)
+        b.PrependByteSlot(2, 22, 0)
+        b.PrependInt16Slot(3, 33, 0)
+        obj0 = b.EndObject()
+
+        b.StartObject(4)
+        b.PrependByteSlot(0, 0, 0)
+        b.PrependByteSlot(1, 44, 0)
+        b.PrependByteSlot(2, 55, 0)
+        b.PrependInt16Slot(3, 66, 0)
+        obj1 = b.EndObject()
+
+        b.StartObject(4)
+        b.PrependByteSlot(0, 0, 0)
+        b.PrependByteSlot(1, 77, 0)
+        b.PrependByteSlot(2, 88, 0)
+        b.PrependInt16Slot(3, 99, 0)
+        obj2 = b.EndObject()
+
+        got = b.Bytes[b.Head():]
+
+        want = bytearray([
+            240, 255, 255, 255,  # == -12. offset to dedupped vtable.
+            99, 0,
+            88,
+            77,
+            248, 255, 255, 255,  # == -8. offset to dedupped vtable.
+            66, 0,
+            55,
+            44,
+            12, 0,
+            8, 0,
+            0, 0,
+            7, 0,
+            6, 0,
+            4, 0,
+            12, 0, 0, 0,
+            33, 0,
+            22,
+            11,
+        ])
+
+        self.assertEqual((len(want), want), (len(got), got))
+
+        table0 = flatbuffers.table.Table(b.Bytes, len(b.Bytes) - obj0)
+        table1 = flatbuffers.table.Table(b.Bytes, len(b.Bytes) - obj1)
+        table2 = flatbuffers.table.Table(b.Bytes, len(b.Bytes) - obj2)
+
+        def _checkTable(tab, voffsett_value, b, c, d):
+            # vtable size
+            got = tab.GetVOffsetTSlot(0, 0)
+            self.assertEqual(12, got, 'case 0, 0')
+
+            # object size
+            got = tab.GetVOffsetTSlot(2, 0)
+            self.assertEqual(8, got, 'case 2, 0')
+
+            # default value
+            got = tab.GetVOffsetTSlot(4, 0)
+            self.assertEqual(voffsett_value, got, 'case 4, 0')
+
+            got = tab.GetSlot(6, 0, N.Uint8Flags)
+            self.assertEqual(b, got, 'case 6, 0')
+
+            val = tab.GetSlot(8, 0, N.Uint8Flags)
+            self.assertEqual(c, val, 'failed 8, 0')
+
+            got = tab.GetSlot(10, 0, N.Uint8Flags)
+            self.assertEqual(d, got, 'failed 10, 0')
+
+        _checkTable(table0, 0, 11, 22, 33)
+        _checkTable(table1, 0, 44, 55, 66)
+        _checkTable(table2, 0, 77, 88, 99)
+
+
+class TestExceptions(unittest.TestCase):
+    def test_object_is_nested_error(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(0)
+        assertRaises(self, lambda: b.StartObject(0),
+                     flatbuffers.builder.IsNestedError)
+
+    def test_object_is_not_nested_error(self):
+        b = flatbuffers.Builder(0)
+        assertRaises(self, lambda: b.EndObject(),
+                     flatbuffers.builder.IsNotNestedError)
+
+    def test_struct_is_not_inline_error(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(0)
+        assertRaises(self, lambda: b.PrependStructSlot(0, 1, 0),
+                     flatbuffers.builder.StructIsNotInlineError)
+
+    def test_unreachable_error(self):
+        b = flatbuffers.Builder(0)
+        assertRaises(self, lambda: b.PrependUOffsetTRelative(1),
+                     flatbuffers.builder.OffsetArithmeticError)
+
+    def test_create_string_is_nested_error(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(0)
+        s = 'test1'
+        assertRaises(self, lambda: b.CreateString(s),
+                     flatbuffers.builder.IsNestedError)
+
+    def test_create_byte_vector_is_nested_error(self):
+        b = flatbuffers.Builder(0)
+        b.StartObject(0)
+        s = b'test1'
+        assertRaises(self, lambda: b.CreateByteVector(s),
+                     flatbuffers.builder.IsNestedError)
+
+    def test_finished_bytes_error(self):
+        b = flatbuffers.Builder(0)
+        assertRaises(self, lambda: b.Output(),
+                     flatbuffers.builder.BuilderNotFinishedError)
+
+
+class TestFixedLengthArrays(unittest.TestCase):
+    def test_fixed_length_array(self):
+        builder = flatbuffers.Builder(0)
+
+        a = 0.5
+        b = range(0, 15)
+        c = 1
+        d_a = [[1, 2], [3, 4]]
+        d_b = [MyGame.Example.TestEnum.TestEnum.B, \
+                MyGame.Example.TestEnum.TestEnum.C]
+        d_c = [[MyGame.Example.TestEnum.TestEnum.A, \
+                MyGame.Example.TestEnum.TestEnum.B], \
+                [MyGame.Example.TestEnum.TestEnum.C, \
+                 MyGame.Example.TestEnum.TestEnum.B]]
+
+        arrayOffset = MyGame.Example.ArrayStruct.CreateArrayStruct(builder, \
+            a, b, c, d_a, d_b, d_c)
+
+        # Create a table with the ArrayStruct.
+        MyGame.Example.ArrayTable.ArrayTableStart(builder)
+        MyGame.Example.ArrayTable.ArrayTableAddA(builder, arrayOffset)
+        tableOffset = MyGame.Example.ArrayTable.ArrayTableEnd(builder)
+
+        builder.Finish(tableOffset)
+
+        buf = builder.Output()
+
+        table = MyGame.Example.ArrayTable.ArrayTable.GetRootAsArrayTable(buf, 0)
+
+        # Verify structure.
+        nested = MyGame.Example.NestedStruct.NestedStruct()
+        self.assertEqual(table.A().A(), 0.5)
+        self.assertEqual(table.A().B(), \
+            [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
+        self.assertEqual(table.A().C(), 1)
+        self.assertEqual(table.A().D(nested, 0).A(), [1, 2])
+        self.assertEqual(table.A().D(nested, 1).A(), [3, 4])
+        self.assertEqual(table.A().D(nested, 0).B(), \
+            MyGame.Example.TestEnum.TestEnum.B)
+        self.assertEqual(table.A().D(nested, 1).B(), \
+            MyGame.Example.TestEnum.TestEnum.C)
+        self.assertEqual(table.A().D(nested, 0).C(), \
+            [MyGame.Example.TestEnum.TestEnum.A, \
+             MyGame.Example.TestEnum.TestEnum.B])
+        self.assertEqual(table.A().D(nested, 1).C(), \
+            [MyGame.Example.TestEnum.TestEnum.C, \
+             MyGame.Example.TestEnum.TestEnum.B])
+
+
+def CheckAgainstGoldDataGo():
+    try:
+        gen_buf, gen_off = make_monster_from_generated_code()
+        fn = 'monsterdata_go_wire.mon'
+        if not os.path.exists(fn):
+            print('Go-generated data does not exist, failed.')
+            return False
+
+        # would like to use a context manager here, but it's less
+        # backwards-compatible:
+        f = open(fn, 'rb')
+        go_wire_data = f.read()
+        f.close()
+
+        CheckReadBuffer(bytearray(go_wire_data), 0)
+        if not bytearray(gen_buf[gen_off:]) == bytearray(go_wire_data):
+            raise AssertionError('CheckAgainstGoldDataGo failed')
+    except:
+        print('Failed to test against Go-generated test data.')
+        return False
+
+    print('Can read Go-generated test data, and Python generates bytewise identical data.')
+    return True
+
+
+def CheckAgainstGoldDataJava():
+    try:
+        gen_buf, gen_off = make_monster_from_generated_code()
+        fn = 'monsterdata_java_wire.mon'
+        if not os.path.exists(fn):
+            print('Java-generated data does not exist, failed.')
+            return False
+        f = open(fn, 'rb')
+        java_wire_data = f.read()
+        f.close()
+
+        CheckReadBuffer(bytearray(java_wire_data), 0)
+    except:
+        print('Failed to read Java-generated test data.')
+        return False
+
+    print('Can read Java-generated test data.')
+    return True
+
+
+class LCG(object):
+    ''' Include simple random number generator to ensure results will be the
+        same cross platform.
+        http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator '''
+
+    __slots__ = ['n']
+
+    InitialLCGSeed = 48271
+
+    def __init__(self):
+        self.n = self.InitialLCGSeed
+
+    def Reset(self):
+        self.n = self.InitialLCGSeed
+
+    def Next(self):
+        self.n = ((self.n * 279470273) % 4294967291) & 0xFFFFFFFF
+        return self.n
+
+
+def BenchmarkVtableDeduplication(count):
+    '''
+    BenchmarkVtableDeduplication measures the speed of vtable deduplication
+    by creating `prePop` vtables, then populating `count` objects with a
+    different single vtable.
+
+    When count is large (as in long benchmarks), memory usage may be high.
+    '''
+
+    for prePop in (1, 10, 100, 1000):
+        builder = flatbuffers.Builder(0)
+        n = 1 + int(math.log(prePop, 1.5))
+
+        # generate some layouts:
+        layouts = set()
+        r = list(compat_range(n))
+        while len(layouts) < prePop:
+            layouts.add(tuple(sorted(random.sample(r, int(max(1, n / 2))))))
+
+        layouts = list(layouts)
+
+        # pre-populate vtables:
+        for layout in layouts:
+            builder.StartObject(n)
+            for j in layout:
+                builder.PrependInt16Slot(j, j, 0)
+            builder.EndObject()
+
+        # benchmark deduplication of a new vtable:
+        def f():
+            layout = random.choice(layouts)
+            builder.StartObject(n)
+            for j in layout:
+                builder.PrependInt16Slot(j, j, 0)
+            builder.EndObject()
+
+        duration = timeit.timeit(stmt=f, number=count)
+        rate = float(count) / duration
+        print(('vtable deduplication rate (n=%d, vtables=%d): %.2f sec' % (
+            prePop,
+            len(builder.vtables),
+            rate))
+        )
+
+
+def BenchmarkCheckReadBuffer(count, buf, off):
+    '''
+    BenchmarkCheckReadBuffer measures the speed of flatbuffer reading
+    by re-using the CheckReadBuffer function with the gold data.
+    '''
+
+    def f():
+        CheckReadBuffer(buf, off)
+
+    duration = timeit.timeit(stmt=f, number=count)
+    rate = float(count) / duration
+    data = float(len(buf) * count) / float(1024 * 1024)
+    data_rate = data / float(duration)
+
+    print(('traversed %d %d-byte flatbuffers in %.2fsec: %.2f/sec, %.2fMB/sec')
+          % (count, len(buf), duration, rate, data_rate))
+
+
+def BenchmarkMakeMonsterFromGeneratedCode(count, length):
+    '''
+    BenchmarkMakeMonsterFromGeneratedCode measures the speed of flatbuffer
+    creation by re-using the make_monster_from_generated_code function for
+    generating gold data examples.
+    '''
+
+    duration = timeit.timeit(stmt=make_monster_from_generated_code,
+                             number=count)
+    rate = float(count) / duration
+    data = float(length * count) / float(1024 * 1024)
+    data_rate = data / float(duration)
+
+    print(('built %d %d-byte flatbuffers in %.2fsec: %.2f/sec, %.2fMB/sec' % \
+           (count, length, duration, rate, data_rate)))
+
+
+def backward_compatible_run_tests(**kwargs):
+    if PY_VERSION < (2, 6):
+        sys.stderr.write("Python version less than 2.6 are not supported")
+        sys.stderr.flush()
+        return False
+
+    # python2.6 has a reduced-functionality unittest.main function:
+    if PY_VERSION == (2, 6):
+        try:
+            unittest.main(**kwargs)
+        except SystemExit as e:
+            if not e.code == 0:
+                return False
+        return True
+
+    # python2.7 and above let us not exit once unittest.main is run:
+    kwargs['exit'] = False
+    kwargs['verbosity'] = 0
+    ret = unittest.main(**kwargs)
+    if ret.result.errors or ret.result.failures:
+        return False
+
+    return True
+
+def main():
+    import os
+    import sys
+    if not len(sys.argv) == 4:
+       sys.stderr.write('Usage: %s <benchmark vtable count>'
+                        '<benchmark read count> <benchmark build count>\n'
+                        % sys.argv[0])
+       sys.stderr.write('       Provide COMPARE_GENERATED_TO_GO=1   to check'
+                        'for bytewise comparison to Go data.\n')
+       sys.stderr.write('       Provide COMPARE_GENERATED_TO_JAVA=1 to check'
+                        'for bytewise comparison to Java data.\n')
+       sys.stderr.flush()
+       sys.exit(1)
+
+    kwargs = dict(argv=sys.argv[:-3])
+
+    # run tests, and run some language comparison checks if needed:
+    success = backward_compatible_run_tests(**kwargs)
+    if success and os.environ.get('COMPARE_GENERATED_TO_GO', 0) == "1":
+        success = success and CheckAgainstGoldDataGo()
+    if success and os.environ.get('COMPARE_GENERATED_TO_JAVA', 0) == "1":
+        success = success and CheckAgainstGoldDataJava()
+
+    if not success:
+        sys.stderr.write('Tests failed, skipping benchmarks.\n')
+        sys.stderr.flush()
+        sys.exit(1)
+
+    # run benchmarks (if 0, they will be a noop):
+    bench_vtable = int(sys.argv[1])
+    bench_traverse = int(sys.argv[2])
+    bench_build = int(sys.argv[3])
+    if bench_vtable:
+        BenchmarkVtableDeduplication(bench_vtable)
+    if bench_traverse:
+        buf, off = make_monster_from_generated_code()
+        BenchmarkCheckReadBuffer(bench_traverse, buf, off)
+    if bench_build:
+        buf, off = make_monster_from_generated_code()
+        BenchmarkMakeMonsterFromGeneratedCode(bench_build, len(buf))
+
+if __name__ == '__main__':
+    main()
diff --git a/third_party/flatbuffers/tests/rust_usage_test/Cargo.toml b/third_party/flatbuffers/tests/rust_usage_test/Cargo.toml
new file mode 100644
index 0000000..490d6d2
--- /dev/null
+++ b/third_party/flatbuffers/tests/rust_usage_test/Cargo.toml
@@ -0,0 +1,26 @@
+[package]
+name = "rust_usage_test"
+version = "0.1.0"
+authors = ["Robert Winslow <hello@rwinslow.com>", "FlatBuffers Maintainers"]
+
+[dependencies]
+flatbuffers = { path = "../../rust/flatbuffers" }
+
+[[bin]]
+name = "monster_example"
+path = "bin/monster_example.rs"
+
+[[bin]]
+name = "alloc_check"
+path = "bin/alloc_check.rs"
+
+
+[dev-dependencies]
+quickcheck = "0.6"
+# TODO(rw): look into moving to criterion.rs
+bencher = "0.1.5"
+
+[[bench]]
+# setup for bencher
+name = "flatbuffers_benchmarks"
+harness = false
diff --git a/third_party/flatbuffers/tests/rust_usage_test/benches/flatbuffers_benchmarks.rs b/third_party/flatbuffers/tests/rust_usage_test/benches/flatbuffers_benchmarks.rs
new file mode 100644
index 0000000..2c6be1f
--- /dev/null
+++ b/third_party/flatbuffers/tests/rust_usage_test/benches/flatbuffers_benchmarks.rs
@@ -0,0 +1,219 @@
+/*
+ * 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.
+ */
+
+#[macro_use]
+extern crate bencher;
+use bencher::Bencher;
+
+extern crate flatbuffers;
+
+#[allow(dead_code, unused_imports)]
+#[path = "../../monster_test_generated.rs"]
+mod monster_test_generated;
+pub use monster_test_generated::my_game;
+
+fn traverse_canonical_buffer(bench: &mut Bencher) {
+    let owned_data = {
+        let mut builder = &mut flatbuffers::FlatBufferBuilder::new();
+        create_serialized_example_with_generated_code(&mut builder, true);
+        builder.finished_data().to_vec()
+    };
+    let data = &owned_data[..];
+    let n = data.len() as u64;
+    bench.iter(|| {
+        traverse_serialized_example_with_generated_code(data);
+    });
+    bench.bytes = n;
+}
+
+fn create_canonical_buffer_then_reset(bench: &mut Bencher) {
+    let mut builder = &mut flatbuffers::FlatBufferBuilder::new();
+    // warmup
+    create_serialized_example_with_generated_code(&mut builder, true);
+    let n = builder.finished_data().len() as u64;
+    builder.reset();
+
+    bench.iter(|| {
+        let _ = create_serialized_example_with_generated_code(&mut builder, true);
+        builder.reset();
+    });
+
+    bench.bytes = n;
+}
+
+#[inline(always)]
+fn create_serialized_example_with_generated_code(builder: &mut flatbuffers::FlatBufferBuilder, finish: bool) -> usize{
+    let s0 = builder.create_string("test1");
+    let s1 = builder.create_string("test2");
+    let t0_name = builder.create_string("Barney");
+    let t1_name = builder.create_string("Fred");
+    let t2_name = builder.create_string("Wilma");
+    let t0 = my_game::example::Monster::create(builder, &my_game::example::MonsterArgs{
+        hp: 1000,
+        name: Some(t0_name),
+        ..Default::default()
+    });
+    let t1 = my_game::example::Monster::create(builder, &my_game::example::MonsterArgs{
+        name: Some(t1_name),
+        ..Default::default()
+    });
+    let t2 = my_game::example::Monster::create(builder, &my_game::example::MonsterArgs{
+        name: Some(t2_name),
+        ..Default::default()
+    });
+    let mon = {
+        let name = builder.create_string("MyMonster");
+        let fred_name = builder.create_string("Fred");
+        let inventory = builder.create_vector_direct(&[0u8, 1, 2, 3, 4]);
+        let test4 = builder.create_vector_direct(&[my_game::example::Test::new(10, 20),
+                                                   my_game::example::Test::new(30, 40)]);
+        let pos = my_game::example::Vec3::new(1.0, 2.0, 3.0, 3.0, my_game::example::Color::Green, &my_game::example::Test::new(5i16, 6i8));
+        let args = my_game::example::MonsterArgs{
+            hp: 80,
+            mana: 150,
+            name: Some(name),
+            pos: Some(&pos),
+            test_type: my_game::example::Any::Monster,
+            test: Some(my_game::example::Monster::create(builder, &my_game::example::MonsterArgs{
+                name: Some(fred_name),
+                ..Default::default()
+            }).as_union_value()),
+            inventory: Some(inventory),
+            test4: Some(test4),
+            testarrayofstring: Some(builder.create_vector(&[s0, s1])),
+            testarrayoftables: Some(builder.create_vector(&[t0, t1, t2])),
+            ..Default::default()
+        };
+        my_game::example::Monster::create(builder, &args)
+    };
+    if finish {
+        my_game::example::finish_monster_buffer(builder, mon);
+    }
+
+    builder.finished_data().len()
+
+    // make it do some work
+    // if builder.finished_data().len() == 0 { panic!("bad benchmark"); }
+}
+
+#[inline(always)]
+fn blackbox<T>(t: T) -> T {
+    // encapsulate this in case we need to turn it into a noop
+    bencher::black_box(t)
+}
+
+#[inline(always)]
+fn traverse_serialized_example_with_generated_code(bytes: &[u8]) {
+    let m = my_game::example::get_root_as_monster(bytes);
+    blackbox(m.hp());
+    blackbox(m.mana());
+    blackbox(m.name());
+    let pos = m.pos().unwrap();
+    blackbox(pos.x());
+    blackbox(pos.y());
+    blackbox(pos.z());
+    blackbox(pos.test1());
+    blackbox(pos.test2());
+    let pos_test3 = pos.test3();
+    blackbox(pos_test3.a());
+    blackbox(pos_test3.b());
+    blackbox(m.test_type());
+    let table2 = m.test().unwrap();
+    let monster2 = my_game::example::Monster::init_from_table(table2);
+    blackbox(monster2.name());
+    blackbox(m.inventory());
+    blackbox(m.test4());
+    let testarrayoftables = m.testarrayoftables().unwrap();
+    blackbox(testarrayoftables.get(0).hp());
+    blackbox(testarrayoftables.get(0).name());
+    blackbox(testarrayoftables.get(1).name());
+    blackbox(testarrayoftables.get(2).name());
+    let testarrayofstring = m.testarrayofstring().unwrap();
+    blackbox(testarrayofstring.get(0));
+    blackbox(testarrayofstring.get(1));
+}
+
+fn create_string_10(bench: &mut Bencher) {
+    let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1<<20);
+    let mut i = 0;
+    bench.iter(|| {
+        builder.create_string("foobarbaz"); // zero-terminated -> 10 bytes
+        i += 1;
+        if i == 10000 {
+            builder.reset();
+            i = 0;
+        }
+    });
+
+    bench.bytes = 10;
+}
+
+fn create_string_100(bench: &mut Bencher) {
+    let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1<<20);
+    let s_owned = (0..99).map(|_| "x").collect::<String>();
+    let s: &str = &s_owned;
+
+    let mut i = 0;
+    bench.iter(|| {
+        builder.create_string(s); // zero-terminated -> 100 bytes
+        i += 1;
+        if i == 1000 {
+            builder.reset();
+            i = 0;
+        }
+    });
+
+    bench.bytes = s.len() as u64;
+}
+
+fn create_byte_vector_100_naive(bench: &mut Bencher) {
+    let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1<<20);
+    let v_owned = (0u8..100).map(|i| i).collect::<Vec<u8>>();
+    let v: &[u8] = &v_owned;
+
+    let mut i = 0;
+    bench.iter(|| {
+        builder.create_vector(v); // zero-terminated -> 100 bytes
+        i += 1;
+        if i == 10000 {
+            builder.reset();
+            i = 0;
+        }
+    });
+
+    bench.bytes = v.len() as u64;
+}
+
+fn create_byte_vector_100_optimal(bench: &mut Bencher) {
+    let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1<<20);
+    let v_owned = (0u8..100).map(|i| i).collect::<Vec<u8>>();
+    let v: &[u8] = &v_owned;
+
+    let mut i = 0;
+    bench.iter(|| {
+        builder.create_vector_direct(v);
+        i += 1;
+        if i == 10000 {
+            builder.reset();
+            i = 0;
+        }
+    });
+
+    bench.bytes = v.len() as u64;
+}
+
+benchmark_group!(benches, create_byte_vector_100_naive, create_byte_vector_100_optimal, traverse_canonical_buffer, create_canonical_buffer_then_reset, create_string_10, create_string_100);
+benchmark_main!(benches);
diff --git a/third_party/flatbuffers/tests/rust_usage_test/bin/alloc_check.rs b/third_party/flatbuffers/tests/rust_usage_test/bin/alloc_check.rs
new file mode 100644
index 0000000..ae1039c
--- /dev/null
+++ b/third_party/flatbuffers/tests/rust_usage_test/bin/alloc_check.rs
@@ -0,0 +1,143 @@
+// define a passthrough allocator that tracks alloc calls.
+// (note that we can't drop this in to the usual test suite, because it's a big
+// global variable).
+use std::alloc::{GlobalAlloc, Layout, System};
+
+static mut N_ALLOCS: usize = 0;
+
+struct TrackingAllocator;
+
+impl TrackingAllocator {
+    fn n_allocs(&self) -> usize {
+        unsafe { N_ALLOCS }
+    }
+}
+unsafe impl GlobalAlloc for TrackingAllocator {
+    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+        N_ALLOCS += 1;
+        System.alloc(layout)
+    }
+    unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
+        System.dealloc(ptr, layout)
+    }
+}
+
+// use the tracking allocator:
+#[global_allocator]
+static A: TrackingAllocator = TrackingAllocator;
+
+// import the flatbuffers generated code:
+extern crate flatbuffers;
+#[allow(dead_code, unused_imports)]
+#[path = "../../monster_test_generated.rs"]
+mod monster_test_generated;
+pub use monster_test_generated::my_game;
+
+// verbatim from the test suite:
+fn create_serialized_example_with_generated_code(builder: &mut flatbuffers::FlatBufferBuilder) {
+    let mon = {
+        let _ = builder.create_vector_of_strings(&["these", "unused", "strings", "check", "the", "create_vector_of_strings", "function"]);
+
+        let s0 = builder.create_string("test1");
+        let s1 = builder.create_string("test2");
+        let fred_name = builder.create_string("Fred");
+
+        // can't inline creation of this Vec3 because we refer to it by reference, so it must live
+        // long enough to be used by MonsterArgs.
+        let pos = my_game::example::Vec3::new(1.0, 2.0, 3.0, 3.0, my_game::example::Color::Green, &my_game::example::Test::new(5i16, 6i8));
+
+        let args = my_game::example::MonsterArgs{
+            hp: 80,
+            mana: 150,
+            name: Some(builder.create_string("MyMonster")),
+            pos: Some(&pos),
+            test_type: my_game::example::Any::Monster,
+            test: Some(my_game::example::Monster::create(builder, &my_game::example::MonsterArgs{
+                name: Some(fred_name),
+                ..Default::default()
+            }).as_union_value()),
+            inventory: Some(builder.create_vector_direct(&[0u8, 1, 2, 3, 4][..])),
+            test4: Some(builder.create_vector_direct(&[my_game::example::Test::new(10, 20),
+            my_game::example::Test::new(30, 40)])),
+            testarrayofstring: Some(builder.create_vector(&[s0, s1])),
+            ..Default::default()
+        };
+        my_game::example::Monster::create(builder, &args)
+    };
+    my_game::example::finish_monster_buffer(builder, mon);
+}
+
+fn main() {
+    // test the allocation tracking:
+    {
+        let before = A.n_allocs();
+        let _x: Vec<u8> = vec![0u8; 1];
+        let after = A.n_allocs();
+        assert_eq!(before + 1, after);
+    }
+
+    let builder = &mut flatbuffers::FlatBufferBuilder::new();
+    {
+        // warm up the builder (it can make small allocs internally, such as for storing vtables):
+        create_serialized_example_with_generated_code(builder);
+    }
+
+    // reset the builder, clearing its heap-allocated memory:
+    builder.reset();
+
+    {
+        let before = A.n_allocs();
+        create_serialized_example_with_generated_code(builder);
+        let after = A.n_allocs();
+        assert_eq!(before, after, "KO: Heap allocs occurred in Rust write path");
+    }
+
+    let buf = builder.finished_data();
+
+    // use the allocation tracking on the read path:
+    {
+        let before = A.n_allocs();
+
+        // do many reads, forcing them to execute by using assert_eq:
+        {
+            let m = my_game::example::get_root_as_monster(buf);
+            assert_eq!(80, m.hp());
+            assert_eq!(150, m.mana());
+            assert_eq!("MyMonster", m.name());
+
+            let pos = m.pos().unwrap();
+            assert_eq!(pos.x(), 1.0f32);
+            assert_eq!(pos.y(), 2.0f32);
+            assert_eq!(pos.z(), 3.0f32);
+            assert_eq!(pos.test1(), 3.0f64);
+            assert_eq!(pos.test2(), my_game::example::Color::Green);
+            let pos_test3 = pos.test3();
+            assert_eq!(pos_test3.a(), 5i16);
+            assert_eq!(pos_test3.b(), 6i8);
+            assert_eq!(m.test_type(), my_game::example::Any::Monster);
+            let table2 = m.test().unwrap();
+            let m2 = my_game::example::Monster::init_from_table(table2);
+
+            assert_eq!(m2.name(), "Fred");
+
+            let inv = m.inventory().unwrap();
+            assert_eq!(inv.len(), 5);
+            assert_eq!(inv.iter().sum::<u8>(), 10u8);
+
+            let test4 = m.test4().unwrap();
+            assert_eq!(test4.len(), 2);
+            assert_eq!(test4[0].a() as i32 + test4[0].b() as i32 +
+                       test4[1].a() as i32 + test4[1].b() as i32, 100);
+
+            let testarrayofstring = m.testarrayofstring().unwrap();
+            assert_eq!(testarrayofstring.len(), 2);
+            assert_eq!(testarrayofstring.get(0), "test1");
+            assert_eq!(testarrayofstring.get(1), "test2");
+        }
+
+        // assert that no allocs occurred:
+        let after = A.n_allocs();
+        assert_eq!(before, after, "KO: Heap allocs occurred in Rust read path");
+    }
+    println!("Rust: Heap alloc checks completed successfully");
+}
diff --git a/third_party/flatbuffers/tests/rust_usage_test/bin/monster_example.rs b/third_party/flatbuffers/tests/rust_usage_test/bin/monster_example.rs
new file mode 100644
index 0000000..3c9a0a0
--- /dev/null
+++ b/third_party/flatbuffers/tests/rust_usage_test/bin/monster_example.rs
@@ -0,0 +1,19 @@
+extern crate flatbuffers;
+
+#[allow(dead_code, unused_imports)]
+#[path = "../../monster_test_generated.rs"]
+mod monster_test_generated;
+pub use monster_test_generated::my_game;
+
+use std::io::Read;
+
+fn main() {
+    let mut f = std::fs::File::open("../monsterdata_test.mon").unwrap();
+    let mut buf = Vec::new();
+    f.read_to_end(&mut buf).expect("file reading failed");
+
+    let monster = my_game::example::get_root_as_monster(&buf[..]);
+    println!("{}", monster.hp());     // `80`
+    println!("{}", monster.mana());   // default value of `150`
+    println!("{:?}", monster.name()); // Some("MyMonster")
+}
diff --git a/third_party/flatbuffers/tests/rust_usage_test/tests/integration_test.rs b/third_party/flatbuffers/tests/rust_usage_test/tests/integration_test.rs
new file mode 100644
index 0000000..0dace96
--- /dev/null
+++ b/third_party/flatbuffers/tests/rust_usage_test/tests/integration_test.rs
@@ -0,0 +1,2716 @@
+/*
+ *
+ * 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.
+ */
+
+extern crate quickcheck;
+
+extern crate flatbuffers;
+
+#[allow(dead_code, unused_imports)]
+#[path = "../../monster_test_generated.rs"]
+mod monster_test_generated;
+pub use monster_test_generated::my_game;
+
+// Include simple random number generator to ensure results will be the
+// same across platforms.
+// http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator
+struct LCG(u64);
+impl LCG {
+    fn new() -> Self {
+        LCG { 0: 48271 }
+    }
+    fn next(&mut self) -> u64 {
+        let old = self.0;
+        self.0 = (self.0 * 279470273u64) % 4294967291u64;
+        old
+    }
+    fn reset(&mut self) {
+        self.0 = 48271
+    }
+}
+
+// test helper macro to return an error if two expressions are not equal
+macro_rules! check_eq {
+    ($field_call:expr, $want:expr) => (
+        if $field_call == $want {
+            Ok(())
+        } else {
+            Err(stringify!($field_call))
+        }
+    )
+}
+
+#[test]
+fn macro_check_eq() {
+    assert!(check_eq!(1, 1).is_ok());
+    assert!(check_eq!(1, 2).is_err());
+}
+
+// test helper macro to return an error if two expressions are equal
+macro_rules! check_is_some {
+    ($field_call:expr) => (
+        if $field_call.is_some() {
+            Ok(())
+        } else {
+            Err(stringify!($field_call))
+        }
+    )
+}
+
+#[test]
+fn macro_check_is_some() {
+    let some: Option<usize> = Some(0);
+    let none: Option<usize> = None;
+    assert!(check_is_some!(some).is_ok());
+    assert!(check_is_some!(none).is_err());
+}
+
+
+fn create_serialized_example_with_generated_code(builder: &mut flatbuffers::FlatBufferBuilder) {
+    let mon = {
+        let s0 = builder.create_string("test1");
+        let s1 = builder.create_string("test2");
+        let fred_name = builder.create_string("Fred");
+
+        // can't inline creation of this Vec3 because we refer to it by reference, so it must live
+        // long enough to be used by MonsterArgs.
+        let pos = my_game::example::Vec3::new(1.0, 2.0, 3.0, 3.0, my_game::example::Color::Green, &my_game::example::Test::new(5i16, 6i8));
+
+        let args = my_game::example::MonsterArgs{
+            hp: 80,
+            mana: 150,
+            name: Some(builder.create_string("MyMonster")),
+            pos: Some(&pos),
+            test_type: my_game::example::Any::Monster,
+            test: Some(my_game::example::Monster::create(builder, &my_game::example::MonsterArgs{
+                name: Some(fred_name),
+                ..Default::default()
+            }).as_union_value()),
+            inventory: Some(builder.create_vector_direct(&[0u8, 1, 2, 3, 4][..])),
+            test4: Some(builder.create_vector_direct(&[my_game::example::Test::new(10, 20),
+                                                       my_game::example::Test::new(30, 40)])),
+            testarrayofstring: Some(builder.create_vector(&[s0, s1])),
+            ..Default::default()
+        };
+        my_game::example::Monster::create(builder, &args)
+    };
+    my_game::example::finish_monster_buffer(builder, mon);
+}
+
+fn create_serialized_example_with_library_code(builder: &mut flatbuffers::FlatBufferBuilder) {
+    let nested_union_mon = {
+        let name = builder.create_string("Fred");
+        let table_start = builder.start_table();
+        builder.push_slot_always(my_game::example::Monster::VT_NAME, name);
+        builder.end_table(table_start)
+    };
+    let pos = my_game::example::Vec3::new(1.0, 2.0, 3.0, 3.0, my_game::example::Color::Green, &my_game::example::Test::new(5i16, 6i8));
+    let inv = builder.create_vector(&[0u8, 1, 2, 3, 4]);
+
+    let test4 = builder.create_vector(&[my_game::example::Test::new(10, 20),
+                                        my_game::example::Test::new(30, 40)][..]);
+
+    let name = builder.create_string("MyMonster");
+    let testarrayofstring = builder.create_vector_of_strings(&["test1", "test2"][..]);
+
+    // begin building
+
+    let table_start = builder.start_table();
+    builder.push_slot(my_game::example::Monster::VT_HP, 80i16, 100);
+    builder.push_slot_always(my_game::example::Monster::VT_NAME, name);
+    builder.push_slot_always(my_game::example::Monster::VT_POS, &pos);
+    builder.push_slot(my_game::example::Monster::VT_TEST_TYPE, my_game::example::Any::Monster, my_game::example::Any::NONE);
+    builder.push_slot_always(my_game::example::Monster::VT_TEST, nested_union_mon);
+    builder.push_slot_always(my_game::example::Monster::VT_INVENTORY, inv);
+    builder.push_slot_always(my_game::example::Monster::VT_TEST4, test4);
+    builder.push_slot_always(my_game::example::Monster::VT_TESTARRAYOFSTRING, testarrayofstring);
+    let root = builder.end_table(table_start);
+    builder.finish(root, Some(my_game::example::MONSTER_IDENTIFIER));
+}
+
+fn serialized_example_is_accessible_and_correct(bytes: &[u8], identifier_required: bool, size_prefixed: bool) -> Result<(), &'static str> {
+
+    if identifier_required {
+        let correct = if size_prefixed {
+            my_game::example::monster_size_prefixed_buffer_has_identifier(bytes)
+        } else {
+            my_game::example::monster_buffer_has_identifier(bytes)
+        };
+        check_eq!(correct, true)?;
+    }
+
+    let m = if size_prefixed {
+        my_game::example::get_size_prefixed_root_as_monster(bytes)
+    } else {
+        my_game::example::get_root_as_monster(bytes)
+    };
+
+    check_eq!(m.hp(), 80)?;
+    check_eq!(m.mana(), 150)?;
+    check_eq!(m.name(), "MyMonster")?;
+
+    let pos = m.pos().unwrap();
+    check_eq!(pos.x(), 1.0f32)?;
+    check_eq!(pos.y(), 2.0f32)?;
+    check_eq!(pos.z(), 3.0f32)?;
+    check_eq!(pos.test1(), 3.0f64)?;
+    check_eq!(pos.test2(), my_game::example::Color::Green)?;
+
+    let pos_test3 = pos.test3();
+    check_eq!(pos_test3.a(), 5i16)?;
+    check_eq!(pos_test3.b(), 6i8)?;
+
+    check_eq!(m.test_type(), my_game::example::Any::Monster)?;
+    check_is_some!(m.test())?;
+    let table2 = m.test().unwrap();
+    let monster2 = my_game::example::Monster::init_from_table(table2);
+
+    check_eq!(monster2.name(), "Fred")?;
+
+    check_is_some!(m.inventory())?;
+    let inv = m.inventory().unwrap();
+    check_eq!(inv.len(), 5)?;
+    check_eq!(inv.iter().sum::<u8>(), 10u8)?;
+
+    check_is_some!(m.test4())?;
+    let test4 = m.test4().unwrap();
+    check_eq!(test4.len(), 2)?;
+    check_eq!(test4[0].a() as i32 + test4[0].b() as i32 +
+              test4[1].a() as i32 + test4[1].b() as i32, 100)?;
+
+    check_is_some!(m.testarrayofstring())?;
+    let testarrayofstring = m.testarrayofstring().unwrap();
+    check_eq!(testarrayofstring.len(), 2)?;
+    check_eq!(testarrayofstring.get(0), "test1")?;
+    check_eq!(testarrayofstring.get(1), "test2")?;
+
+    Ok(())
+}
+
+// Disabled due to Windows CI limitations.
+// #[test]
+// fn builder_initializes_with_maximum_buffer_size() {
+//     flatbuffers::FlatBufferBuilder::new_with_capacity(flatbuffers::FLATBUFFERS_MAX_BUFFER_SIZE);
+// }
+
+#[should_panic]
+#[test]
+fn builder_abort_with_greater_than_maximum_buffer_size() {
+    flatbuffers::FlatBufferBuilder::new_with_capacity(flatbuffers::FLATBUFFERS_MAX_BUFFER_SIZE+1);
+}
+
+#[test]
+fn builder_collapses_into_vec() {
+    let mut b = flatbuffers::FlatBufferBuilder::new();
+    create_serialized_example_with_generated_code(&mut b);
+    let (backing_buf, head) = b.collapse();
+    serialized_example_is_accessible_and_correct(&backing_buf[head..], true, false).unwrap();
+}
+
+#[cfg(test)]
+mod generated_constants {
+    extern crate flatbuffers;
+    use super::my_game;
+
+    #[test]
+    fn monster_identifier() {
+        assert_eq!("MONS", my_game::example::MONSTER_IDENTIFIER);
+    }
+
+    #[test]
+    fn monster_file_extension() {
+        assert_eq!("mon", my_game::example::MONSTER_EXTENSION);
+    }
+}
+
+#[cfg(test)]
+mod lifetime_correctness {
+    extern crate flatbuffers;
+
+    use std::mem;
+
+    use super::my_game;
+    use super::load_file;
+
+    #[test]
+    fn table_get_field_from_static_buffer_1() {
+        let buf = load_file("../monsterdata_test.mon").expect("missing monsterdata_test.mon");
+        // create 'static slice
+        let slice: &[u8] = &buf;
+        let slice: &'static [u8] = unsafe { mem::transmute(slice) };
+        // make sure values retrieved from the 'static buffer are themselves 'static
+        let monster: my_game::example::Monster<'static> = my_game::example::get_root_as_monster(slice);
+        // this line should compile:
+        let name: Option<&'static str> = monster._tab.get::<flatbuffers::ForwardsUOffset<&str>>(my_game::example::Monster::VT_NAME, None);
+        assert_eq!(name, Some("MyMonster"));
+    }
+
+    #[test]
+    fn table_get_field_from_static_buffer_2() {
+        static DATA: [u8; 4] = [0, 0, 0, 0]; // some binary data
+        let table: flatbuffers::Table<'static> = flatbuffers::Table::new(&DATA, 0);
+        // this line should compile:
+        table.get::<&'static str>(0, None);
+    }
+
+    #[test]
+    fn table_object_self_lifetime_in_closure() {
+        // This test is designed to ensure that lifetimes for temporary intermediate tables aren't inflated beyond where the need to be.
+        let buf = load_file("../monsterdata_test.mon").expect("missing monsterdata_test.mon");
+        let monster = my_game::example::get_root_as_monster(&buf);
+        let enemy: Option<my_game::example::Monster> = monster.enemy();
+        // This line won't compile if "self" is required to live for the lifetime of buf above as the borrow disappears at the end of the closure.
+        let enemy_of_my_enemy = enemy.map(|e| {
+            // enemy (the Option) is consumed, and the enum's value is taken as a temporary (e) at the start of the closure
+            let name = e.name();
+            // ... the temporary dies here, so for this to compile name's lifetime must not be tied to the temporary
+            name
+            // If this test fails the error would be "`e` dropped here while still borrowed"
+        });
+        assert_eq!(enemy_of_my_enemy, Some("Fred"));
+    }
+}
+
+#[cfg(test)]
+mod roundtrip_generated_code {
+    extern crate flatbuffers;
+
+    use super::my_game;
+
+    fn build_mon<'a, 'b>(builder: &'a mut flatbuffers::FlatBufferBuilder, args: &'b my_game::example::MonsterArgs) -> my_game::example::Monster<'a> {
+        let mon = my_game::example::Monster::create(builder, &args);
+        my_game::example::finish_monster_buffer(builder, mon);
+        my_game::example::get_root_as_monster(builder.finished_data())
+    }
+
+    #[test]
+    fn scalar_store() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{hp: 123, name: Some(name), ..Default::default()});
+        assert_eq!(m.hp(), 123);
+    }
+    #[test]
+    fn scalar_default() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), ..Default::default()});
+        assert_eq!(m.hp(), 100);
+    }
+    #[test]
+    fn string_store() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let name = b.create_string("foobar");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), ..Default::default()});
+        assert_eq!(m.name(), "foobar");
+    }
+    #[test]
+    fn struct_store() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{
+            name: Some(name),
+            pos: Some(&my_game::example::Vec3::new(1.0, 2.0, 3.0, 4.0,
+                                                   my_game::example::Color::Green,
+                                                   &my_game::example::Test::new(98, 99))),
+            ..Default::default()
+        });
+        assert_eq!(m.pos(), Some(&my_game::example::Vec3::new(1.0, 2.0, 3.0, 4.0,
+                                                              my_game::example::Color::Green,
+                                                              &my_game::example::Test::new(98, 99))));
+    }
+    #[test]
+    fn struct_default() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), ..Default::default()});
+        assert_eq!(m.pos(), None);
+    }
+    #[test]
+    fn enum_store() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), color: my_game::example::Color::Red, ..Default::default()});
+        assert_eq!(m.color(), my_game::example::Color::Red);
+    }
+    #[test]
+    fn enum_default() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), ..Default::default()});
+        assert_eq!(m.color(), my_game::example::Color::Blue);
+    }
+    #[test]
+    fn union_store() {
+        let b = &mut flatbuffers::FlatBufferBuilder::new();
+        {
+            let name_inner = b.create_string("foo");
+            let name_outer = b.create_string("bar");
+
+            let inner = my_game::example::Monster::create(b, &my_game::example::MonsterArgs{
+                name: Some(name_inner),
+                ..Default::default()
+            });
+            let outer = my_game::example::Monster::create(b, &my_game::example::MonsterArgs{
+                name: Some(name_outer),
+                test_type: my_game::example::Any::Monster,
+                test: Some(inner.as_union_value()),
+                ..Default::default()
+            });
+            my_game::example::finish_monster_buffer(b, outer);
+        }
+
+        let mon = my_game::example::get_root_as_monster(b.finished_data());
+        assert_eq!(mon.name(), "bar");
+        assert_eq!(mon.test_type(), my_game::example::Any::Monster);
+        assert_eq!(my_game::example::Monster::init_from_table(mon.test().unwrap()).name(),
+                   "foo");
+        assert_eq!(mon.test_as_monster().unwrap().name(), "foo");
+        assert_eq!(mon.test_as_test_simple_table_with_enum(), None);
+        assert_eq!(mon.test_as_my_game_example_2_monster(), None);
+    }
+    #[test]
+    fn union_default() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), ..Default::default()});
+        assert_eq!(m.test_type(), my_game::example::Any::NONE);
+        assert_eq!(m.test(), None);
+    }
+    #[test]
+    fn table_full_namespace_store() {
+        let b = &mut flatbuffers::FlatBufferBuilder::new();
+        {
+            let name_inner = b.create_string("foo");
+            let name_outer = b.create_string("bar");
+
+            let inner = my_game::example::Monster::create(b, &my_game::example::MonsterArgs{
+                name: Some(name_inner),
+                ..Default::default()
+            });
+            let outer = my_game::example::Monster::create(b, &my_game::example::MonsterArgs{
+                name: Some(name_outer),
+                enemy: Some(inner),
+                ..Default::default()
+            });
+            my_game::example::finish_monster_buffer(b, outer);
+        }
+
+        let mon = my_game::example::get_root_as_monster(b.finished_data());
+        assert_eq!(mon.name(), "bar");
+        assert_eq!(mon.enemy().unwrap().name(), "foo");
+    }
+    #[test]
+    fn table_full_namespace_default() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), ..Default::default()});
+        assert_eq!(m.enemy(), None);
+    }
+    #[test]
+    fn table_store() {
+        let b = &mut flatbuffers::FlatBufferBuilder::new();
+        {
+            let id_inner = b.create_string("foo");
+            let name_outer = b.create_string("bar");
+
+            let inner = my_game::example::Stat::create(b, &my_game::example::StatArgs{
+                id: Some(id_inner),
+                ..Default::default()
+            });
+            let outer = my_game::example::Monster::create(b, &my_game::example::MonsterArgs{
+                name: Some(name_outer),
+                testempty: Some(inner),
+                ..Default::default()
+            });
+            my_game::example::finish_monster_buffer(b, outer);
+        }
+
+        let mon = my_game::example::get_root_as_monster(b.finished_data());
+        assert_eq!(mon.name(), "bar");
+        assert_eq!(mon.testempty().unwrap().id(), Some("foo"));
+    }
+    #[test]
+    fn table_default() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), ..Default::default()});
+        assert_eq!(m.testempty(), None);
+    }
+    #[test]
+    fn nested_flatbuffer_store() {
+        let b0 = {
+            let mut b0 = flatbuffers::FlatBufferBuilder::new();
+            let args = my_game::example::MonsterArgs{
+                hp: 123,
+                name: Some(b0.create_string("foobar")),
+                ..Default::default()
+            };
+            let mon = my_game::example::Monster::create(&mut b0, &args);
+            my_game::example::finish_monster_buffer(&mut b0, mon);
+            b0
+        };
+
+        let b1 = {
+            let mut b1 = flatbuffers::FlatBufferBuilder::new();
+            let args = my_game::example::MonsterArgs{
+                testnestedflatbuffer: Some(b1.create_vector(b0.finished_data())),
+                name: Some(b1.create_string("foo")),
+                ..Default::default()
+            };
+            let mon = my_game::example::Monster::create(&mut b1, &args);
+            my_game::example::finish_monster_buffer(&mut b1, mon);
+            b1
+        };
+
+        let m = my_game::example::get_root_as_monster(b1.finished_data());
+
+        assert!(m.testnestedflatbuffer().is_some());
+        assert_eq!(m.testnestedflatbuffer().unwrap(), b0.finished_data());
+
+        let m2_a = my_game::example::get_root_as_monster(m.testnestedflatbuffer().unwrap());
+        assert_eq!(m2_a.hp(), 123);
+        assert_eq!(m2_a.name(), "foobar");
+
+        assert!(m.testnestedflatbuffer_nested_flatbuffer().is_some());
+        let m2_b = m.testnestedflatbuffer_nested_flatbuffer().unwrap();
+
+        assert_eq!(m2_b.hp(), 123);
+        assert_eq!(m2_b.name(), "foobar");
+    }
+    #[test]
+    fn nested_flatbuffer_default() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), ..Default::default()});
+        assert!(m.testnestedflatbuffer().is_none());
+    }
+    #[test]
+    fn vector_of_string_store_helper_build() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let v = b.create_vector_of_strings(&["foobar", "baz"]);
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{
+            name: Some(name),
+            testarrayofstring: Some(v), ..Default::default()});
+        assert_eq!(m.testarrayofstring().unwrap().len(), 2);
+        assert_eq!(m.testarrayofstring().unwrap().get(0), "foobar");
+        assert_eq!(m.testarrayofstring().unwrap().get(1), "baz");
+    }
+    #[test]
+    fn vector_of_string_store_manual_build() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let s0 = b.create_string("foobar");
+        let s1 = b.create_string("baz");
+        let v = b.create_vector(&[s0, s1]);
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{
+            name: Some(name),
+            testarrayofstring: Some(v), ..Default::default()});
+        assert_eq!(m.testarrayofstring().unwrap().len(), 2);
+        assert_eq!(m.testarrayofstring().unwrap().get(0), "foobar");
+        assert_eq!(m.testarrayofstring().unwrap().get(1), "baz");
+    }
+    #[test]
+    fn vector_of_ubyte_store() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let v = b.create_vector(&[123u8, 234u8][..]);
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{
+            name: Some(name),
+            inventory: Some(v), ..Default::default()});
+        assert_eq!(m.inventory().unwrap(), &[123, 234][..]);
+    }
+    #[test]
+    fn vector_of_bool_store() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let v = b.create_vector(&[false, true, false, true][..]);
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{
+            name: Some(name),
+            testarrayofbools: Some(v), ..Default::default()});
+        assert_eq!(m.testarrayofbools().unwrap(), &[false, true, false, true][..]);
+    }
+    #[test]
+    fn vector_of_f64_store() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let v = b.create_vector(&[3.14159265359f64][..]);
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{
+            name: Some(name),
+            vector_of_doubles: Some(v), ..Default::default()});
+        assert_eq!(m.vector_of_doubles().unwrap().len(), 1);
+        assert_eq!(m.vector_of_doubles().unwrap().get(0), 3.14159265359f64);
+    }
+    #[test]
+    fn vector_of_struct_store() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let v = b.create_vector(&[my_game::example::Test::new(127, -128), my_game::example::Test::new(3, 123)][..]);
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{
+            name: Some(name),
+            test4: Some(v), ..Default::default()});
+        assert_eq!(m.test4().unwrap(), &[my_game::example::Test::new(127, -128), my_game::example::Test::new(3, 123)][..]);
+    }
+    #[test]
+    fn vector_of_struct_store_with_type_inference() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let v = b.create_vector(&[my_game::example::Test::new(127, -128),
+                                  my_game::example::Test::new(3, 123),
+                                  my_game::example::Test::new(100, 101)]);
+        let name = b.create_string("foo");
+        let m = build_mon(&mut b, &my_game::example::MonsterArgs{
+            name: Some(name),
+            test4: Some(v), ..Default::default()});
+        assert_eq!(m.test4().unwrap(), &[my_game::example::Test::new(127, -128), my_game::example::Test::new(3, 123), my_game::example::Test::new(100, 101)][..]);
+    }
+    // TODO(rw) this passes, but I don't want to change the monster test schema right now
+    // #[test]
+    // fn vector_of_enum_store() {
+    //     let mut b = flatbuffers::FlatBufferBuilder::new();
+    //     let v = b.create_vector::<my_game::example::Color>(&[my_game::example::Color::Red, my_game::example::Color::Green][..]);
+    //     let name = b.create_string("foo");
+    //     let m = build_mon(&mut b, &my_game::example::MonsterArgs{
+    //         name: Some(name),
+    //         vector_of_enum: Some(v), ..Default::default()});
+    //     assert_eq!(m.vector_of_enum().unwrap().len(), 2);
+    //     assert_eq!(m.vector_of_enum().unwrap().get(0), my_game::example::Color::Red);
+    //     assert_eq!(m.vector_of_enum().unwrap().get(1), my_game::example::Color::Green);
+    // }
+    #[test]
+    fn vector_of_table_store() {
+        let b = &mut flatbuffers::FlatBufferBuilder::new();
+        let t0 = {
+            let name = b.create_string("foo");
+            let args = my_game::example::MonsterArgs{hp: 55, name: Some(name), ..Default::default()};
+            my_game::example::Monster::create(b, &args)
+        };
+        let t1 = {
+            let name = b.create_string("bar");
+            let args = my_game::example::MonsterArgs{name: Some(name), ..Default::default()};
+            my_game::example::Monster::create(b, &args)
+        };
+        let v = b.create_vector(&[t0, t1][..]);
+        let name = b.create_string("foo");
+        let m = build_mon(b, &my_game::example::MonsterArgs{
+            name: Some(name),
+            testarrayoftables: Some(v), ..Default::default()});
+        assert_eq!(m.testarrayoftables().unwrap().len(), 2);
+        assert_eq!(m.testarrayoftables().unwrap().get(0).hp(), 55);
+        assert_eq!(m.testarrayoftables().unwrap().get(0).name(), "foo");
+        assert_eq!(m.testarrayoftables().unwrap().get(1).hp(), 100);
+        assert_eq!(m.testarrayoftables().unwrap().get(1).name(), "bar");
+    }
+}
+
+#[cfg(test)]
+mod generated_code_alignment_and_padding {
+    extern crate flatbuffers;
+    use super::my_game;
+
+    #[test]
+    fn enum_color_is_1_byte() {
+        assert_eq!(1, ::std::mem::size_of::<my_game::example::Color>());
+    }
+
+    #[test]
+    fn enum_color_is_aligned_to_1() {
+        assert_eq!(1, ::std::mem::align_of::<my_game::example::Color>());
+    }
+
+    #[test]
+    fn union_any_is_1_byte() {
+        assert_eq!(1, ::std::mem::size_of::<my_game::example::Any>());
+    }
+
+    #[test]
+    fn union_any_is_aligned_to_1() {
+        assert_eq!(1, ::std::mem::align_of::<my_game::example::Any>());
+    }
+
+    #[test]
+    fn struct_test_is_4_bytes() {
+        assert_eq!(4, ::std::mem::size_of::<my_game::example::Test>());
+    }
+
+    #[test]
+    fn struct_test_is_aligned_to_2() {
+        assert_eq!(2, ::std::mem::align_of::<my_game::example::Test>());
+    }
+
+    #[test]
+    fn struct_vec3_is_32_bytes() {
+        assert_eq!(32, ::std::mem::size_of::<my_game::example::Vec3>());
+    }
+
+    #[test]
+    fn struct_vec3_is_aligned_to_8() {
+        assert_eq!(8, ::std::mem::align_of::<my_game::example::Vec3>());
+    }
+
+    #[test]
+    fn struct_vec3_is_written_with_correct_alignment_in_table() {
+        let b = &mut flatbuffers::FlatBufferBuilder::new();
+        {
+            let name = b.create_string("foo");
+            let mon = my_game::example::Monster::create(b, &my_game::example::MonsterArgs{
+                name: Some(name),
+                pos: Some(&my_game::example::Vec3::new(1.0, 2.0, 3.0, 4.0,
+                                                       my_game::example::Color::Green,
+                                                       &my_game::example::Test::new(98, 99))),
+                                                       ..Default::default()});
+            my_game::example::finish_monster_buffer(b, mon);
+        }
+        let buf = b.finished_data();
+        let mon = my_game::example::get_root_as_monster(buf);
+        let vec3 = mon.pos().unwrap();
+
+        let start_ptr = buf.as_ptr() as usize;
+        let vec3_ptr = vec3 as *const my_game::example::Vec3 as usize;
+
+        assert!(vec3_ptr > start_ptr);
+        let aln = ::std::mem::align_of::<my_game::example::Vec3>();
+        assert_eq!((vec3_ptr - start_ptr) % aln, 0);
+    }
+
+    #[test]
+    fn struct_ability_is_8_bytes() {
+        assert_eq!(8, ::std::mem::size_of::<my_game::example::Ability>());
+    }
+
+    #[test]
+    fn struct_ability_is_aligned_to_4() {
+        assert_eq!(4, ::std::mem::align_of::<my_game::example::Ability>());
+    }
+
+    #[test]
+    fn struct_ability_is_written_with_correct_alignment_in_table_vector() {
+        let b = &mut flatbuffers::FlatBufferBuilder::new();
+        {
+            let name = b.create_string("foo");
+            let v = b.create_vector(&[my_game::example::Ability::new(1, 2),
+                                      my_game::example::Ability::new(3, 4),
+                                      my_game::example::Ability::new(5, 6)]);
+            let mon = my_game::example::Monster::create(b, &my_game::example::MonsterArgs{
+                name: Some(name),
+                testarrayofsortedstruct: Some(v),
+                ..Default::default()});
+            my_game::example::finish_monster_buffer(b, mon);
+        }
+        let buf = b.finished_data();
+        let mon = my_game::example::get_root_as_monster(buf);
+        let abilities = mon.testarrayofsortedstruct().unwrap();
+
+        let start_ptr = buf.as_ptr() as usize;
+        for a in abilities.iter() {
+            let a_ptr = a as *const my_game::example::Ability as usize;
+            assert!(a_ptr > start_ptr);
+            let aln = ::std::mem::align_of::<my_game::example::Ability>();
+            assert_eq!((a_ptr - start_ptr) % aln, 0);
+        }
+    }
+}
+
+#[cfg(test)]
+mod roundtrip_byteswap {
+    extern crate quickcheck;
+    extern crate flatbuffers;
+
+    const N: u64 = 10000;
+
+    fn palindrome_32(x: f32) -> bool {
+        x == f32::from_bits(x.to_bits().swap_bytes())
+    }
+    fn palindrome_64(x: f64) -> bool {
+        x == f64::from_bits(x.to_bits().swap_bytes())
+    }
+
+    fn prop_f32(x: f32) {
+        use flatbuffers::byte_swap_f32;
+
+        let there = byte_swap_f32(x);
+
+        let back_again = byte_swap_f32(there);
+
+        if !palindrome_32(x) {
+            assert!(x != there);
+        }
+
+        assert_eq!(x, back_again);
+    }
+
+    fn prop_f64(x: f64) {
+        use flatbuffers::byte_swap_f64;
+
+        let there = byte_swap_f64(x);
+        let back_again = byte_swap_f64(there);
+
+        if !palindrome_64(x) {
+            assert!(x != there);
+        }
+
+        assert_eq!(x, back_again);
+    }
+
+    #[test]
+    fn fuzz_f32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_f32 as fn(f32)); }
+    #[test]
+    fn fuzz_f64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_f64 as fn(f64)); }
+}
+
+#[cfg(test)]
+mod roundtrip_vectors {
+
+    #[cfg(test)]
+    mod scalar {
+        extern crate quickcheck;
+        extern crate flatbuffers;
+
+        const N: u64 = 20;
+
+        fn prop<T>(xs: Vec<T>)
+        where
+            T: for<'a> flatbuffers::Follow<'a, Inner = T>
+                + flatbuffers::EndianScalar
+                + flatbuffers::Push
+                + ::std::fmt::Debug,
+        {
+            use flatbuffers::Follow;
+
+            let mut b = flatbuffers::FlatBufferBuilder::new();
+            b.start_vector::<T>(xs.len());
+            for i in (0..xs.len()).rev() {
+                b.push::<T>(xs[i]);
+            }
+            let vecend = b.end_vector::<T>(xs.len());
+            b.finish_minimal(vecend);
+
+            let buf = b.finished_data();
+
+            let got = <flatbuffers::ForwardsUOffset<flatbuffers::Vector<T>>>::follow(&buf[..], 0);
+            let mut result_vec: Vec<T> = Vec::with_capacity(got.len());
+            for i in 0..got.len() {
+                result_vec.push(got.get(i));
+            }
+            assert_eq!(result_vec, xs);
+        }
+
+        #[test]
+        fn easy_u8() {
+            prop::<u8>(vec![]);
+            prop::<u8>(vec![1u8]);
+            prop::<u8>(vec![1u8, 2u8]);
+            prop::<u8>(vec![1u8, 2u8, 3u8]);
+            prop::<u8>(vec![1u8, 2u8, 3u8, 4u8]);
+        }
+
+        #[test]
+        fn fuzz_bool() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<bool> as fn(Vec<_>)); }
+        #[test]
+        fn fuzz_u8() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<u8> as fn(Vec<_>)); }
+        #[test]
+        fn fuzz_i8() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<i8> as fn(Vec<_>)); }
+        #[test]
+        fn fuzz_u16() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<u16> as fn(Vec<_>)); }
+        #[test]
+        fn fuzz_i16() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<i16> as fn(Vec<_>)); }
+        #[test]
+        fn fuzz_u32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<u32> as fn(Vec<_>)); }
+        #[test]
+        fn fuzz_i32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<i32> as fn(Vec<_>)); }
+        #[test]
+        fn fuzz_u64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<u64> as fn(Vec<_>)); }
+        #[test]
+        fn fuzz_i64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<i64> as fn(Vec<_>)); }
+        #[test]
+        fn fuzz_f32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<f32> as fn(Vec<_>)); }
+        #[test]
+        fn fuzz_f64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<f64> as fn(Vec<_>)); }
+    }
+
+    #[cfg(test)]
+    mod create_vector_direct {
+        extern crate quickcheck;
+        extern crate flatbuffers;
+
+        const N: u64 = 20;
+
+        // This uses a macro because lifetimes for the trait-bounded function get too
+        // complicated.
+        macro_rules! impl_prop {
+            ($test_name:ident, $fn_name:ident, $ty:ident) => (
+                fn $fn_name(xs: Vec<$ty>) {
+                    use flatbuffers::Follow;
+
+                    let mut b = flatbuffers::FlatBufferBuilder::new();
+                    b.create_vector_direct(&xs[..]);
+                    let buf = b.unfinished_data();
+
+                    let got = <flatbuffers::Vector<$ty>>::follow(&buf[..], 0).safe_slice();
+                    assert_eq!(got, &xs[..]);
+                }
+                #[test]
+                fn $test_name() { quickcheck::QuickCheck::new().max_tests(N).quickcheck($fn_name as fn(Vec<_>)); }
+            )
+        }
+
+        impl_prop!(test_bool, prop_bool, bool);
+        impl_prop!(test_u8, prop_u8, u8);
+        impl_prop!(test_i8, prop_i8, i8);
+
+        #[cfg(test)]
+        #[cfg(target_endian = "little")]
+        mod host_is_le {
+            const N: u64 = 20;
+            use super::flatbuffers;
+            use super::quickcheck;
+            impl_prop!(test_u16, prop_u16, u16);
+            impl_prop!(test_u32, prop_u32, u32);
+            impl_prop!(test_u64, prop_u64, u64);
+            impl_prop!(test_i16, prop_i16, i16);
+            impl_prop!(test_i32, prop_i32, i32);
+            impl_prop!(test_i64, prop_i64, i64);
+            impl_prop!(test_f32, prop_f32, f32);
+            impl_prop!(test_f64, prop_f64, f64);
+        }
+    }
+
+    #[cfg(test)]
+    mod string_manual_build {
+        extern crate quickcheck;
+        extern crate flatbuffers;
+
+        fn prop(xs: Vec<String>) {
+            use flatbuffers::Follow;
+
+            let mut b = flatbuffers::FlatBufferBuilder::new();
+            let mut offsets = Vec::new();
+            for s in xs.iter().rev() {
+                offsets.push(b.create_string(s.as_str()));
+            }
+
+            b.start_vector::<flatbuffers::WIPOffset<&str>>(xs.len());
+            for &i in offsets.iter() {
+                b.push(i);
+            }
+            let vecend = b.end_vector::<flatbuffers::WIPOffset<&str>>(xs.len());
+
+            b.finish_minimal(vecend);
+
+            let buf = b.finished_data();
+            let got = <flatbuffers::ForwardsUOffset<flatbuffers::Vector<flatbuffers::ForwardsUOffset<&str>>>>::follow(buf, 0);
+
+            assert_eq!(got.len(), xs.len());
+            for i in 0..xs.len() {
+                assert_eq!(got.get(i), &xs[i][..]);
+            }
+        }
+
+        #[test]
+        fn fuzz() {
+            quickcheck::QuickCheck::new().max_tests(20).quickcheck(prop as fn(Vec<_>));
+        }
+    }
+
+    #[cfg(test)]
+    mod string_helper_build {
+        extern crate quickcheck;
+        extern crate flatbuffers;
+
+        fn prop(input: Vec<String>) {
+            let xs: Vec<&str> = input.iter().map(|s: &String| &s[..]).collect();
+
+            use flatbuffers::Follow;
+
+            let mut b = flatbuffers::FlatBufferBuilder::new();
+            let vecend = b.create_vector_of_strings(&xs[..]);
+
+            b.finish_minimal(vecend);
+
+            let buf = b.finished_data();
+            let got = <flatbuffers::ForwardsUOffset<flatbuffers::Vector<flatbuffers::ForwardsUOffset<&str>>>>::follow(buf, 0);
+
+            assert_eq!(got.len(), xs.len());
+            for i in 0..xs.len() {
+                assert_eq!(got.get(i), &xs[i][..]);
+            }
+        }
+
+        #[test]
+        fn fuzz() {
+            quickcheck::QuickCheck::new().max_tests(100).quickcheck(prop as fn(Vec<_>));
+        }
+    }
+
+    #[cfg(test)]
+    mod ubyte {
+        extern crate quickcheck;
+        extern crate flatbuffers;
+
+        #[test]
+        fn fuzz_manual_build() {
+            fn prop(vec: Vec<u8>) {
+                let xs = &vec[..];
+
+                let mut b1 = flatbuffers::FlatBufferBuilder::new();
+                b1.start_vector::<u8>(xs.len());
+
+                for i in (0..xs.len()).rev() {
+                    b1.push(xs[i]);
+                }
+                b1.end_vector::<u8>(xs.len());
+
+                let mut b2 = flatbuffers::FlatBufferBuilder::new();
+                b2.create_vector(xs);
+                assert_eq!(b1.unfinished_data(), b2.unfinished_data());
+            }
+            quickcheck::QuickCheck::new().max_tests(100).quickcheck(prop as fn(Vec<_>));
+        }
+    }
+}
+
+#[cfg(test)]
+mod framing_format {
+    extern crate flatbuffers;
+
+    use super::my_game;
+
+    #[test]
+    fn test_size_prefixed_buffer() {
+        // Create size prefixed buffer.
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let args = &my_game::example::MonsterArgs{
+            mana: 200,
+            hp: 300,
+            name: Some(b.create_string("bob")),
+            ..Default::default()
+        };
+        let mon = my_game::example::Monster::create(&mut b, &args);
+        b.finish_size_prefixed(mon, None);
+
+        // Access it.
+        let buf = b.finished_data();
+        let m = flatbuffers::get_size_prefixed_root::<my_game::example::Monster>(buf);
+        assert_eq!(m.mana(), 200);
+        assert_eq!(m.hp(), 300);
+        assert_eq!(m.name(), "bob");
+    }
+}
+
+#[cfg(test)]
+mod roundtrip_table {
+    use std::collections::HashMap;
+
+    extern crate flatbuffers;
+    extern crate quickcheck;
+
+    use super::LCG;
+
+    #[test]
+    fn table_of_mixed_scalars_fuzz() {
+        // Values we're testing against: chosen to ensure no bits get chopped
+        // off anywhere, and also be different from eachother.
+        let bool_val: bool = true;
+        let char_val: i8 = -127;  // 0x81
+        let uchar_val: u8 = 0xFF;
+        let short_val: i16 = -32222;  // 0x8222;
+        let ushort_val: u16 = 0xFEEE;
+        let int_val: i32 = unsafe { ::std::mem::transmute(0x83333333u32) };
+        let uint_val: u32 = 0xFDDDDDDD;
+        let long_val: i64 = unsafe { ::std::mem::transmute(0x8444444444444444u64) }; // TODO: byte literal?
+        let ulong_val: u64 = 0xFCCCCCCCCCCCCCCCu64;
+        let float_val: f32 = 3.14159;
+        let double_val: f64 = 3.14159265359;
+
+        let test_value_types_max: isize = 11;
+        let max_fields_per_object: flatbuffers::VOffsetT = 100;
+        let num_fuzz_objects: isize = 1000;  // The higher, the more thorough :)
+
+        let mut builder = flatbuffers::FlatBufferBuilder::new();
+        let mut lcg = LCG::new();
+
+        let mut objects: Vec<flatbuffers::UOffsetT> = vec![0; num_fuzz_objects as usize];
+
+        // Generate num_fuzz_objects random objects each consisting of
+        // fields_per_object fields, each of a random type.
+        for i in 0..(num_fuzz_objects as usize) {
+            let fields_per_object = (lcg.next() % (max_fields_per_object as u64)) as flatbuffers::VOffsetT;
+            let start = builder.start_table();
+
+            for j in 0..fields_per_object {
+                let choice = lcg.next() % (test_value_types_max as u64);
+
+                let f = flatbuffers::field_index_to_field_offset(j);
+
+                match choice {
+                    0 => {builder.push_slot::<bool>(f, bool_val, false);}
+                    1 => {builder.push_slot::<i8>(f, char_val, 0);}
+                    2 => {builder.push_slot::<u8>(f, uchar_val, 0);}
+                    3 => {builder.push_slot::<i16>(f, short_val, 0);}
+                    4 => {builder.push_slot::<u16>(f, ushort_val, 0);}
+                    5 => {builder.push_slot::<i32>(f, int_val, 0);}
+                    6 => {builder.push_slot::<u32>(f, uint_val, 0);}
+                    7 => {builder.push_slot::<i64>(f, long_val, 0);}
+                    8 => {builder.push_slot::<u64>(f, ulong_val, 0);}
+                    9 => {builder.push_slot::<f32>(f, float_val, 0.0);}
+                    10 => {builder.push_slot::<f64>(f, double_val, 0.0);}
+                    _ => { panic!("unknown choice: {}", choice); }
+                }
+            }
+            objects[i] = builder.end_table(start).value();
+        }
+
+        // Do some bookkeeping to generate stats on fuzzes:
+        let mut stats: HashMap<u64, u64> = HashMap::new();
+        let mut values_generated: u64 = 0;
+
+        // Embrace PRNG determinism:
+        lcg.reset();
+
+        // Test that all objects we generated are readable and return the
+        // expected values. We generate random objects in the same order
+        // so this is deterministic:
+        for i in 0..(num_fuzz_objects as usize) {
+            let table = {
+                let buf = builder.unfinished_data();
+                let loc = buf.len() as flatbuffers::UOffsetT - objects[i];
+                flatbuffers::Table::new(buf, loc as usize)
+            };
+
+            let fields_per_object = (lcg.next() % (max_fields_per_object as u64)) as flatbuffers::VOffsetT;
+            for j in 0..fields_per_object {
+                let choice = lcg.next() % (test_value_types_max as u64);
+
+                *stats.entry(choice).or_insert(0) += 1;
+                values_generated += 1;
+
+                let f = flatbuffers::field_index_to_field_offset(j);
+
+                match choice {
+                    0 => { assert_eq!(bool_val, table.get::<bool>(f, Some(false)).unwrap()); }
+                    1 => { assert_eq!(char_val, table.get::<i8>(f, Some(0)).unwrap()); }
+                    2 => { assert_eq!(uchar_val, table.get::<u8>(f, Some(0)).unwrap()); }
+                    3 => { assert_eq!(short_val, table.get::<i16>(f, Some(0)).unwrap()); }
+                    4 => { assert_eq!(ushort_val, table.get::<u16>(f, Some(0)).unwrap()); }
+                    5 => { assert_eq!(int_val, table.get::<i32>(f, Some(0)).unwrap()); }
+                    6 => { assert_eq!(uint_val, table.get::<u32>(f, Some(0)).unwrap()); }
+                    7 => { assert_eq!(long_val, table.get::<i64>(f, Some(0)).unwrap()); }
+                    8 => { assert_eq!(ulong_val, table.get::<u64>(f, Some(0)).unwrap()); }
+                    9 => { assert_eq!(float_val, table.get::<f32>(f, Some(0.0)).unwrap()); }
+                    10 => { assert_eq!(double_val, table.get::<f64>(f, Some(0.0)).unwrap()); }
+                    _ => { panic!("unknown choice: {}", choice); }
+                }
+            }
+        }
+
+        // Assert that we tested all the fuzz cases enough:
+        let min_tests_per_choice = 1000;
+        assert!(values_generated > 0);
+        assert!(min_tests_per_choice > 0);
+        for i in 0..test_value_types_max as u64 {
+            assert!(stats[&i] >= min_tests_per_choice,
+                    format!("inadequately-tested fuzz case: {}", i));
+        }
+    }
+
+    #[test]
+    fn table_of_byte_strings_fuzz() {
+        fn prop(vec: Vec<Vec<u8>>) {
+            use flatbuffers::field_index_to_field_offset as fi2fo;
+            use flatbuffers::Follow;
+
+            let xs = &vec[..];
+
+            // build
+            let mut b = flatbuffers::FlatBufferBuilder::new();
+            let str_offsets: Vec<flatbuffers::WIPOffset<_>> = xs.iter().map(|s| b.create_byte_string(&s[..])).collect();
+            let table_start = b.start_table();
+
+            for i in 0..xs.len() {
+                b.push_slot_always(fi2fo(i as flatbuffers::VOffsetT), str_offsets[i]);
+            }
+            let root = b.end_table(table_start);
+            b.finish_minimal(root);
+
+            // use
+            let buf = b.finished_data();
+            let tab = <flatbuffers::ForwardsUOffset<flatbuffers::Table>>::follow(buf, 0);
+
+            for i in 0..xs.len() {
+                let v = tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<u8>>>(fi2fo(i as flatbuffers::VOffsetT), None);
+                assert!(v.is_some());
+                let v2 = v.unwrap().safe_slice();
+                assert_eq!(v2, &xs[i][..]);
+            }
+        }
+        prop(vec![vec![1,2,3]]);
+
+        let n = 20;
+        quickcheck::QuickCheck::new().max_tests(n).quickcheck(prop as fn(Vec<_>));
+    }
+
+    #[test]
+    fn fuzz_table_of_strings() {
+        fn prop(vec: Vec<String>) {
+            use flatbuffers::field_index_to_field_offset as fi2fo;
+            use flatbuffers::Follow;
+
+            let xs = &vec[..];
+
+            // build
+            let mut b = flatbuffers::FlatBufferBuilder::new();
+            let str_offsets: Vec<flatbuffers::WIPOffset<_>> = xs.iter().map(|s| b.create_string(&s[..])).collect();
+            let table_start = b.start_table();
+
+            for i in 0..xs.len() {
+                b.push_slot_always(fi2fo(i as flatbuffers::VOffsetT), str_offsets[i]);
+            }
+            let root = b.end_table(table_start);
+            b.finish_minimal(root);
+
+            // use
+            let buf = b.finished_data();
+            let tab = <flatbuffers::ForwardsUOffset<flatbuffers::Table>>::follow(buf, 0);
+
+            for i in 0..xs.len() {
+                let v = tab.get::<flatbuffers::ForwardsUOffset<&str>>(fi2fo(i as flatbuffers::VOffsetT), None);
+                assert_eq!(v, Some(&xs[i][..]));
+            }
+        }
+        let n = 20;
+        quickcheck::QuickCheck::new().max_tests(n).quickcheck(prop as fn(Vec<String>));
+    }
+
+    mod table_of_vectors_of_scalars {
+        extern crate flatbuffers;
+        extern crate quickcheck;
+
+        const N: u64 = 20;
+
+        fn prop<T>(vecs: Vec<Vec<T>>)
+        where
+            T: for<'a> flatbuffers::Follow<'a, Inner = T>
+                + flatbuffers::EndianScalar
+                + flatbuffers::Push
+                + ::std::fmt::Debug,
+        {
+            use flatbuffers::field_index_to_field_offset as fi2fo;
+            use flatbuffers::Follow;
+
+            // build
+            let mut b = flatbuffers::FlatBufferBuilder::new();
+            let mut offs = vec![];
+            for vec in &vecs {
+                b.start_vector::<T>(vec.len());
+
+                let xs = &vec[..];
+                for i in (0..xs.len()).rev() {
+                    b.push::<T>(xs[i]);
+                }
+                let vecend = b.end_vector::<T>(xs.len());
+                offs.push(vecend);
+            }
+
+            let table_start = b.start_table();
+
+            for i in 0..vecs.len() {
+                b.push_slot_always(fi2fo(i as flatbuffers::VOffsetT), offs[i]);
+            }
+            let root = b.end_table(table_start);
+            b.finish_minimal(root);
+
+            // use
+            let buf = b.finished_data();
+            let tab = <flatbuffers::ForwardsUOffset<flatbuffers::Table>>::follow(buf, 0);
+
+            for i in 0..vecs.len() {
+                let got = tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<T>>>(fi2fo(i as flatbuffers::VOffsetT), None);
+                assert!(got.is_some());
+                let got2 = got.unwrap();
+                let mut got3: Vec<T> = Vec::with_capacity(got2.len());
+                for i in 0..got2.len() {
+                    got3.push(got2.get(i));
+                }
+                assert_eq!(vecs[i], got3);
+            }
+        }
+
+        #[test]
+        fn fuzz_bool() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<bool>>)); }
+
+        #[test]
+        fn fuzz_u8() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<u8>>)); }
+        #[test]
+        fn fuzz_u16() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<u16>>)); }
+        #[test]
+        fn fuzz_u32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<u32>>)); }
+        #[test]
+        fn fuzz_u64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<u64>>)); }
+
+        #[test]
+        fn fuzz_i8() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<u8>>)); }
+        #[test]
+        fn fuzz_i16() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<u16>>)); }
+        #[test]
+        fn fuzz_i32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<u32>>)); }
+        #[test]
+        fn fuzz_i64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<u64>>)); }
+
+        #[test]
+        fn fuzz_f32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<f32>>)); }
+        #[test]
+        fn fuzz_f64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<f64>>)); }
+    }
+}
+
+#[cfg(test)]
+mod roundtrip_scalars {
+    extern crate flatbuffers;
+    extern crate quickcheck;
+
+    const N: u64 = 1000;
+
+    fn prop<T: PartialEq + ::std::fmt::Debug + Copy + flatbuffers::EndianScalar>(x: T) {
+        let mut buf = vec![0u8; ::std::mem::size_of::<T>()];
+        flatbuffers::emplace_scalar(&mut buf[..], x);
+        let y = flatbuffers::read_scalar(&buf[..]);
+        assert_eq!(x, y);
+    }
+
+    #[test]
+    fn fuzz_bool() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<bool> as fn(_)); }
+    #[test]
+    fn fuzz_u8() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<u8> as fn(_)); }
+    #[test]
+    fn fuzz_i8() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<i8> as fn(_)); }
+
+    #[test]
+    fn fuzz_u16() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<u16> as fn(_)); }
+    #[test]
+    fn fuzz_i16() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<i16> as fn(_)); }
+
+    #[test]
+    fn fuzz_u32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<u32> as fn(_)); }
+    #[test]
+    fn fuzz_i32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<i32> as fn(_)); }
+
+    #[test]
+    fn fuzz_u64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<u64> as fn(_)); }
+    #[test]
+    fn fuzz_i64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<i64> as fn(_)); }
+
+    #[test]
+    fn fuzz_f32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<f32> as fn(_)); }
+    #[test]
+    fn fuzz_f64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<f64> as fn(_)); }
+}
+
+#[cfg(test)]
+mod roundtrip_push_follow_scalars {
+    extern crate flatbuffers;
+    extern crate quickcheck;
+
+    use flatbuffers::Push;
+
+    const N: u64 = 1000;
+
+    // This uses a macro because lifetimes for a trait-bounded function get too
+    // complicated.
+    macro_rules! impl_prop {
+        ($fn_name:ident, $ty:ident) => (
+            fn $fn_name(x: $ty) {
+                let mut buf = vec![0u8; ::std::mem::size_of::<$ty>()];
+                x.push(&mut buf[..], &[][..]);
+                let fs: flatbuffers::FollowStart<$ty> = flatbuffers::FollowStart::new();
+                assert_eq!(fs.self_follow(&buf[..], 0), x);
+            }
+        )
+    }
+
+    impl_prop!(prop_bool, bool);
+    impl_prop!(prop_u8, u8);
+    impl_prop!(prop_i8, i8);
+    impl_prop!(prop_u16, u16);
+    impl_prop!(prop_i16, i16);
+    impl_prop!(prop_u32, u32);
+    impl_prop!(prop_i32, i32);
+    impl_prop!(prop_u64, u64);
+    impl_prop!(prop_i64, i64);
+    impl_prop!(prop_f32, f32);
+    impl_prop!(prop_f64, f64);
+
+    #[test]
+    fn fuzz_bool() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_bool as fn(bool)); }
+    #[test]
+    fn fuzz_u8() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_u8 as fn(u8)); }
+    #[test]
+    fn fuzz_i8() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_i8 as fn(i8)); }
+    #[test]
+    fn fuzz_u16() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_u16 as fn(u16)); }
+    #[test]
+    fn fuzz_i16() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_i16 as fn(i16)); }
+    #[test]
+    fn fuzz_u32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_u32 as fn(u32)); }
+    #[test]
+    fn fuzz_i32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_i32 as fn(i32)); }
+    #[test]
+    fn fuzz_u64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_u64 as fn(u64)); }
+    #[test]
+    fn fuzz_i64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_i64 as fn(i64)); }
+    #[test]
+    fn fuzz_f32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_f32 as fn(f32)); }
+    #[test]
+    fn fuzz_f64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_f64 as fn(f64)); }
+}
+
+
+#[cfg(test)]
+mod write_and_read_examples {
+    extern crate flatbuffers;
+
+    use super::create_serialized_example_with_library_code;
+    use super::create_serialized_example_with_generated_code;
+    use super::serialized_example_is_accessible_and_correct;
+
+    #[test]
+    fn generated_code_creates_correct_example() {
+        let b = &mut flatbuffers::FlatBufferBuilder::new();
+        create_serialized_example_with_generated_code(b);
+        let buf = b.finished_data();
+        serialized_example_is_accessible_and_correct(&buf[..], true, false).unwrap();
+    }
+
+    #[test]
+    fn generated_code_creates_correct_example_repeatedly_with_reset() {
+        let b = &mut flatbuffers::FlatBufferBuilder::new();
+        for _ in 0..100 {
+            create_serialized_example_with_generated_code(b);
+            {
+                let buf = b.finished_data();
+                serialized_example_is_accessible_and_correct(&buf[..], true, false).unwrap();
+            }
+            b.reset();
+        }
+    }
+
+    #[test]
+    fn library_code_creates_correct_example() {
+        let b = &mut flatbuffers::FlatBufferBuilder::new();
+        create_serialized_example_with_library_code(b);
+        let buf = b.finished_data();
+        serialized_example_is_accessible_and_correct(&buf[..], true, false).unwrap();
+    }
+
+    #[test]
+    fn library_code_creates_correct_example_repeatedly_with_reset() {
+        let b = &mut flatbuffers::FlatBufferBuilder::new();
+        for _ in 0..100 {
+            create_serialized_example_with_library_code(b);
+            {
+                let buf = b.finished_data();
+                serialized_example_is_accessible_and_correct(&buf[..], true, false).unwrap();
+            }
+            b.reset();
+        }
+    }
+}
+
+#[cfg(test)]
+mod read_examples_from_other_language_ports {
+    extern crate flatbuffers;
+
+    use super::load_file;
+    use super::serialized_example_is_accessible_and_correct;
+
+    #[test]
+    fn gold_cpp_example_data_is_accessible_and_correct() {
+        let buf = load_file("../monsterdata_test.mon").expect("missing monsterdata_test.mon");
+        serialized_example_is_accessible_and_correct(&buf[..], true, false).unwrap();
+    }
+    #[test]
+    fn java_wire_example_data_is_accessible_and_correct() {
+        let buf = load_file("../monsterdata_java_wire.mon");
+        if buf.is_err() {
+            println!("skipping java wire test because it is not present");
+            return;
+        }
+        let buf = buf.unwrap();
+        serialized_example_is_accessible_and_correct(&buf[..], true, false).unwrap();
+    }
+    #[test]
+    fn java_wire_size_prefixed_example_data_is_accessible_and_correct() {
+        let buf = load_file("../monsterdata_java_wire_sp.mon");
+        if buf.is_err() {
+            println!("skipping java wire test because it is not present");
+            return;
+        }
+        let buf = buf.unwrap();
+        serialized_example_is_accessible_and_correct(&buf[..], true, true).unwrap();
+    }
+}
+
+#[cfg(test)]
+mod generated_code_asserts {
+    extern crate flatbuffers;
+
+    use super::my_game;
+
+    #[test]
+    #[should_panic]
+    fn monster_builder_fails_when_name_is_missing() {
+        let b = &mut flatbuffers::FlatBufferBuilder::new();
+        my_game::example::Monster::create(b, &my_game::example::MonsterArgs{..Default::default()});
+    }
+}
+
+#[cfg(test)]
+mod generated_key_comparisons {
+    extern crate flatbuffers;
+
+    use super::my_game;
+
+    #[test]
+    fn struct_ability_key_compare_less_than() {
+        let a = my_game::example::Ability::new(1, 2);
+        let b = my_game::example::Ability::new(2, 1);
+        let c = my_game::example::Ability::new(3, 3);
+
+        assert_eq!(a.key_compare_less_than(&a), false);
+        assert_eq!(b.key_compare_less_than(&b), false);
+        assert_eq!(c.key_compare_less_than(&c), false);
+
+        assert_eq!(a.key_compare_less_than(&b), true);
+        assert_eq!(a.key_compare_less_than(&c), true);
+
+        assert_eq!(b.key_compare_less_than(&a), false);
+        assert_eq!(b.key_compare_less_than(&c), true);
+
+        assert_eq!(c.key_compare_less_than(&a), false);
+        assert_eq!(c.key_compare_less_than(&b), false);
+    }
+
+    #[test]
+    fn struct_key_compare_with_value() {
+        let a = my_game::example::Ability::new(1, 2);
+
+        assert_eq!(a.key_compare_with_value(0), ::std::cmp::Ordering::Greater);
+        assert_eq!(a.key_compare_with_value(1), ::std::cmp::Ordering::Equal);
+        assert_eq!(a.key_compare_with_value(2), ::std::cmp::Ordering::Less);
+    }
+
+    #[test]
+    fn struct_key_compare_less_than() {
+        let a = my_game::example::Ability::new(1, 2);
+        let b = my_game::example::Ability::new(2, 1);
+        let c = my_game::example::Ability::new(3, 3);
+
+        assert_eq!(a.key_compare_less_than(&a), false);
+        assert_eq!(b.key_compare_less_than(&b), false);
+        assert_eq!(c.key_compare_less_than(&c), false);
+
+        assert_eq!(a.key_compare_less_than(&b), true);
+        assert_eq!(a.key_compare_less_than(&c), true);
+
+        assert_eq!(b.key_compare_less_than(&a), false);
+        assert_eq!(b.key_compare_less_than(&c), true);
+
+        assert_eq!(c.key_compare_less_than(&a), false);
+        assert_eq!(c.key_compare_less_than(&b), false);
+    }
+
+    #[test]
+    fn table_key_compare_with_value() {
+        // setup
+        let builder = &mut flatbuffers::FlatBufferBuilder::new();
+        super::create_serialized_example_with_library_code(builder);
+        let buf = builder.finished_data();
+        let a = my_game::example::get_root_as_monster(buf);
+
+        // preconditions
+        assert_eq!(a.name(), "MyMonster");
+
+        assert_eq!(a.key_compare_with_value("AAA"), ::std::cmp::Ordering::Greater);
+        assert_eq!(a.key_compare_with_value("MyMonster"), ::std::cmp::Ordering::Equal);
+        assert_eq!(a.key_compare_with_value("ZZZ"), ::std::cmp::Ordering::Less);
+    }
+
+    #[test]
+    fn table_key_compare_less_than() {
+        // setup
+        let builder = &mut flatbuffers::FlatBufferBuilder::new();
+        super::create_serialized_example_with_library_code(builder);
+        let buf = builder.finished_data();
+        let a = my_game::example::get_root_as_monster(buf);
+        let b = a.test_as_monster().unwrap();
+
+        // preconditions
+        assert_eq!(a.name(), "MyMonster");
+        assert_eq!(b.name(), "Fred");
+
+        assert_eq!(a.key_compare_less_than(&a), false);
+        assert_eq!(a.key_compare_less_than(&b), false);
+
+        assert_eq!(b.key_compare_less_than(&a), true);
+        assert_eq!(b.key_compare_less_than(&b), false);
+    }
+}
+
+#[cfg(test)]
+mod included_schema_generated_code {
+    extern crate flatbuffers;
+
+    //extern crate rust_usage_test;
+
+    // TODO(rw): make generated sub-namespace files importable
+    //#[test]
+    //fn namespace_test_mod_is_importable() {
+    //    use rust_usage_test::namespace_test;
+    //}
+    //#[test]
+    //fn namespace_test1_mod_is_importable() {
+    //    use rust_usage_test::namespace_test::namespace_test1_generated;
+    //}
+    //#[test]
+    //fn namespace_test2_mod_is_importable() {
+    //    use rust_usage_test::namespace_test::namespace_test2_generated;
+    //}
+}
+
+#[cfg(test)]
+mod builder_asserts {
+    extern crate flatbuffers;
+
+    #[test]
+    #[should_panic]
+    fn end_table_should_panic_when_not_in_table() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.end_table(flatbuffers::WIPOffset::new(0));
+    }
+
+    #[test]
+    #[should_panic]
+    fn create_string_should_panic_when_in_table() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.start_table();
+        b.create_string("foo");
+    }
+
+    #[test]
+    #[should_panic]
+    fn create_byte_string_should_panic_when_in_table() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.start_table();
+        b.create_byte_string(b"foo");
+    }
+
+    #[test]
+    #[should_panic]
+    fn push_struct_slot_should_panic_when_not_in_table() {
+        #[derive(Copy, Clone, Debug, PartialEq)]
+        #[repr(C, packed)]
+        struct foo { }
+        impl<'b> flatbuffers::Push for &'b foo {
+            type Output = foo;
+            fn push<'a>(&'a self, _dst: &'a mut [u8], _rest: &'a [u8]) { }
+        }
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.push_slot_always(0, &foo{});
+    }
+
+    #[test]
+    #[should_panic]
+    fn finished_bytes_should_panic_when_table_is_not_finished() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.start_table();
+        b.finished_data();
+    }
+
+    #[test]
+    #[should_panic]
+    fn required_panics_when_field_not_set() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let start = b.start_table();
+        let o = b.end_table(start);
+        b.required(o, 4 /* byte offset to first field */, "test field");
+    }
+}
+
+#[cfg(test)]
+mod follow_impls {
+    extern crate flatbuffers;
+    use flatbuffers::Follow;
+    use flatbuffers::field_index_to_field_offset as fi2fo;
+
+    // Define a test struct to use in a few tests. This replicates the work that the code generator
+    // would normally do when defining a FlatBuffer struct. For reference, compare the following
+    // `FooStruct` code with the code generated for the `Vec3` struct in
+    // `../../monster_test_generated.rs`.
+    use flatbuffers::EndianScalar;
+    #[derive(Copy, Clone, Debug, PartialEq)]
+    #[repr(C, packed)]
+    struct FooStruct {
+        a: i8,
+        b: u8,
+        c: i16,
+    }
+    impl FooStruct {
+        fn new(_a: i8, _b: u8, _c: i16) -> Self {
+            FooStruct {
+                a: _a.to_little_endian(),
+                b: _b.to_little_endian(),
+                c: _c.to_little_endian(),
+            }
+        }
+    }
+    impl flatbuffers::SafeSliceAccess for FooStruct {}
+    impl<'a> flatbuffers::Follow<'a> for FooStruct {
+        type Inner = &'a FooStruct;
+        #[inline(always)]
+        fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+            <&'a FooStruct>::follow(buf, loc)
+        }
+    }
+    impl<'a> flatbuffers::Follow<'a> for &'a FooStruct {
+        type Inner = &'a FooStruct;
+        #[inline(always)]
+        fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+            flatbuffers::follow_cast_ref::<FooStruct>(buf, loc)
+        }
+    }
+
+    #[test]
+    fn to_u8() {
+        let vec: Vec<u8> = vec![255, 3];
+        let fs: flatbuffers::FollowStart<u8> = flatbuffers::FollowStart::new();
+        assert_eq!(fs.self_follow(&vec[..], 1), 3);
+    }
+
+    #[test]
+    fn to_u16() {
+        let vec: Vec<u8> = vec![255, 255, 3, 4];
+        let fs: flatbuffers::FollowStart<u16> = flatbuffers::FollowStart::new();
+        assert_eq!(fs.self_follow(&vec[..], 2), 1027);
+    }
+
+    #[test]
+    fn to_f32() {
+        let vec: Vec<u8> = vec![255, 255, 255, 255, /* start of value */ 208, 15, 73, 64];
+        let fs: flatbuffers::FollowStart<f32> = flatbuffers::FollowStart::new();
+        assert_eq!(fs.self_follow(&vec[..], 4), 3.14159);
+    }
+
+    #[test]
+    fn to_string() {
+        let vec: Vec<u8> = vec![255,255,255,255, 3, 0, 0, 0, 'f' as u8, 'o' as u8, 'o' as u8, 0];
+        let off: flatbuffers::FollowStart<&str> = flatbuffers::FollowStart::new();
+        assert_eq!(off.self_follow(&vec[..], 4), "foo");
+    }
+
+    #[test]
+    fn to_byte_slice() {
+        let vec: Vec<u8> = vec![255, 255, 255, 255, 4, 0, 0, 0, 1, 2, 3, 4];
+        let off: flatbuffers::FollowStart<flatbuffers::Vector<u8>> = flatbuffers::FollowStart::new();
+        assert_eq!(off.self_follow(&vec[..], 4).safe_slice(), &[1, 2, 3, 4][..]);
+    }
+
+    #[test]
+    fn to_byte_vector() {
+        let vec: Vec<u8> = vec![255, 255, 255, 255, 4, 0, 0, 0, 1, 2, 3, 4];
+        let off: flatbuffers::FollowStart<flatbuffers::Vector<u8>> = flatbuffers::FollowStart::new();
+        assert_eq!(off.self_follow(&vec[..], 4).safe_slice(), &[1, 2, 3, 4][..]);
+    }
+
+    #[test]
+    fn to_byte_string_zero_teriminated() {
+        let vec: Vec<u8> = vec![255, 255, 255, 255, 3, 0, 0, 0, 1, 2, 3, 0];
+        let off: flatbuffers::FollowStart<flatbuffers::Vector<u8>> = flatbuffers::FollowStart::new();
+        assert_eq!(off.self_follow(&vec[..], 4).safe_slice(), &[1, 2, 3][..]);
+    }
+
+    #[cfg(target_endian = "little")]
+    #[test]
+    fn to_slice_of_u16() {
+        let vec: Vec<u8> = vec![255, 255, 255, 255, 2, 0, 0, 0, 1, 2, 3, 4];
+        let off: flatbuffers::FollowStart<&[u16]> = flatbuffers::FollowStart::new();
+        assert_eq!(off.self_follow(&vec[..], 4), &vec![513, 1027][..]);
+    }
+
+    #[test]
+    fn to_vector_of_u16() {
+        let vec: Vec<u8> = vec![255, 255, 255, 255, 2, 0, 0, 0, 1, 2, 3, 4];
+        let off: flatbuffers::FollowStart<flatbuffers::Vector<u16>> = flatbuffers::FollowStart::new();
+        assert_eq!(off.self_follow(&vec[..], 4).len(), 2);
+        assert_eq!(off.self_follow(&vec[..], 4).get(0), 513);
+        assert_eq!(off.self_follow(&vec[..], 4).get(1), 1027);
+    }
+
+    #[test]
+    fn to_struct() {
+        let vec: Vec<u8> = vec![255, 255, 255, 255, 1, 2, 3, 4];
+        let off: flatbuffers::FollowStart<&FooStruct> = flatbuffers::FollowStart::new();
+        assert_eq!(*off.self_follow(&vec[..], 4), FooStruct::new(1, 2, 1027));
+    }
+
+    #[test]
+    fn to_vector_of_offset_to_string_elements() {
+        let buf: Vec<u8> = vec![/* vec len */ 1, 0, 0, 0, /* offset to string */ 4, 0, 0, 0, /* str length */ 3, 0, 0, 0, 'f' as u8, 'o' as u8, 'o' as u8, 0];
+        let s: flatbuffers::FollowStart<flatbuffers::Vector<flatbuffers::ForwardsUOffset<&str>>> = flatbuffers::FollowStart::new();
+        assert_eq!(s.self_follow(&buf[..], 0).len(), 1);
+        assert_eq!(s.self_follow(&buf[..], 0).get(0), "foo");
+    }
+
+    #[test]
+    fn to_slice_of_struct_elements() {
+        let buf: Vec<u8> = vec![1, 0, 0, 0, /* struct data */ 1, 2, 3, 4];
+        let fs: flatbuffers::FollowStart<flatbuffers::Vector<FooStruct>> = flatbuffers::FollowStart::new();
+        assert_eq!(fs.self_follow(&buf[..], 0).safe_slice(), &vec![FooStruct::new(1, 2, 1027)][..]);
+    }
+
+    #[test]
+    fn to_vector_of_struct_elements() {
+        let buf: Vec<u8> = vec![1, 0, 0, 0, /* struct data */ 1, 2, 3, 4];
+        let fs: flatbuffers::FollowStart<flatbuffers::Vector<FooStruct>> = flatbuffers::FollowStart::new();
+        assert_eq!(fs.self_follow(&buf[..], 0).len(), 1);
+        assert_eq!(fs.self_follow(&buf[..], 0).get(0), &FooStruct::new(1, 2, 1027));
+    }
+
+    #[test]
+    fn to_root_to_empty_table() {
+        let buf: Vec<u8> = vec![
+            12, 0, 0, 0, // offset to root table
+            // enter vtable
+            4, 0, // vtable len
+            0, 0, // inline size
+            255, 255, 255, 255, // canary
+            // enter table
+            8, 0, 0, 0, // vtable location
+        ];
+        let fs: flatbuffers::FollowStart<flatbuffers::ForwardsUOffset<flatbuffers::Table>> = flatbuffers::FollowStart::new();
+        assert_eq!(fs.self_follow(&buf[..], 0), flatbuffers::Table::new(&buf[..], 12));
+    }
+
+    #[test]
+    fn to_root_table_get_slot_scalar_u8() {
+        let buf: Vec<u8> = vec![
+            14, 0, 0, 0, // offset to root table
+            // enter vtable
+            6, 0, // vtable len
+            2, 0, // inline size
+            5, 0, // value loc
+            255, 255, 255, 255, // canary
+            // enter table
+            10, 0, 0, 0, // vtable location
+            0, 99 // value (with padding)
+        ];
+        let fs: flatbuffers::FollowStart<flatbuffers::ForwardsUOffset<flatbuffers::Table>> = flatbuffers::FollowStart::new();
+        let tab = fs.self_follow(&buf[..], 0);
+        assert_eq!(tab.get::<u8>(fi2fo(0), Some(123)), Some(99));
+    }
+
+    #[test]
+    fn to_root_to_table_get_slot_scalar_u8_default_via_vtable_len() {
+        let buf: Vec<u8> = vec![
+            12, 0, 0, 0, // offset to root table
+            // enter vtable
+            4, 0, // vtable len
+            2, 0, // inline size
+            255, 255, 255, 255, // canary
+            // enter table
+            8, 0, 0, 0, // vtable location
+        ];
+        let fs: flatbuffers::FollowStart<flatbuffers::ForwardsUOffset<flatbuffers::Table>> = flatbuffers::FollowStart::new();
+        let tab = fs.self_follow(&buf[..], 0);
+        assert_eq!(tab.get::<u8>(fi2fo(0), Some(123)), Some(123));
+    }
+
+    #[test]
+    fn to_root_to_table_get_slot_scalar_u8_default_via_vtable_zero() {
+        let buf: Vec<u8> = vec![
+            14, 0, 0, 0, // offset to root table
+            // enter vtable
+            6, 0, // vtable len
+            2, 0, // inline size
+            0, 0, // zero means use the default value
+            255, 255, 255, 255, // canary
+            // enter table
+            10, 0, 0, 0, // vtable location
+        ];
+        let fs: flatbuffers::FollowStart<flatbuffers::ForwardsUOffset<flatbuffers::Table>> = flatbuffers::FollowStart::new();
+        let tab = fs.self_follow(&buf[..], 0);
+        assert_eq!(tab.get::<u8>(fi2fo(0), Some(123)), Some(123));
+    }
+
+    #[test]
+    fn to_root_to_table_get_slot_string_multiple_types() {
+        let buf: Vec<u8> = vec![
+            14, 0, 0, 0, // offset to root table
+            // enter vtable
+            6, 0, // vtable len
+            2, 0, // inline size
+            4, 0, // value loc
+            255, 255, 255, 255, // canary
+            // enter table
+            10, 0, 0, 0, // vtable location
+            8, 0, 0, 0, // offset to string
+            // leave table
+            255, 255, 255, 255, // canary
+            // enter string
+            3, 0, 0, 0, 109, 111, 111, 0 // string length and contents
+        ];
+        let tab = <flatbuffers::ForwardsUOffset<flatbuffers::Table>>::follow(&buf[..], 0);
+        assert_eq!(tab.get::<flatbuffers::ForwardsUOffset<&str>>(fi2fo(0), None), Some("moo"));
+        let byte_vec = tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<u8>>>(fi2fo(0), None).unwrap().safe_slice();
+        assert_eq!(byte_vec, &vec![109, 111, 111][..]);
+        let v = tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<u8>>>(fi2fo(0), None).unwrap();
+        assert_eq!(v.len(), 3);
+        assert_eq!(v.get(0), 109);
+        assert_eq!(v.get(1), 111);
+        assert_eq!(v.get(2), 111);
+    }
+
+    #[test]
+    fn to_root_to_table_get_slot_string_multiple_types_default_via_vtable_len() {
+        let buf: Vec<u8> = vec![
+            12, 0, 0, 0, // offset to root table
+            // enter vtable
+            4, 0, // vtable len
+            4, 0, // table inline len
+            255, 255, 255, 255, // canary
+            // enter table
+            8, 0, 0, 0, // vtable location
+        ];
+        let tab = <flatbuffers::ForwardsUOffset<flatbuffers::Table>>::follow(&buf[..], 0);
+        assert_eq!(tab.get::<flatbuffers::ForwardsUOffset<&str>>(fi2fo(0), Some("abc")), Some("abc"));
+        #[cfg(target_endian = "little")]
+        {
+            assert_eq!(tab.get::<flatbuffers::ForwardsUOffset<&[u8]>>(fi2fo(0), Some(&vec![70, 71, 72][..])), Some(&vec![70, 71, 72][..]));
+        }
+
+        let default_vec_buf: Vec<u8> = vec![3, 0, 0, 0, 70, 71, 72, 0];
+        let default_vec = flatbuffers::Vector::new(&default_vec_buf[..], 0);
+        let v = tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<u8>>>(fi2fo(0), Some(default_vec)).unwrap();
+        assert_eq!(v.len(), 3);
+        assert_eq!(v.get(0), 70);
+        assert_eq!(v.get(1), 71);
+        assert_eq!(v.get(2), 72);
+    }
+
+    #[test]
+    fn to_root_to_table_get_slot_string_multiple_types_default_via_vtable_zero() {
+        let buf: Vec<u8> = vec![
+            14, 0, 0, 0, // offset to root table
+            // enter vtable
+            6, 0, // vtable len
+            2, 0, // inline size
+            0, 0, // value loc
+            255, 255, 255, 255, // canary
+            // enter table
+            10, 0, 0, 0, // vtable location
+        ];
+        let tab = <flatbuffers::ForwardsUOffset<flatbuffers::Table>>::follow(&buf[..], 0);
+        assert_eq!(tab.get::<flatbuffers::ForwardsUOffset<&str>>(fi2fo(0), Some("abc")), Some("abc"));
+        #[cfg(target_endian = "little")]
+        {
+            assert_eq!(tab.get::<flatbuffers::ForwardsUOffset<&[u8]>>(fi2fo(0), Some(&vec![70, 71, 72][..])), Some(&vec![70, 71, 72][..]));
+        }
+
+        let default_vec_buf: Vec<u8> = vec![3, 0, 0, 0, 70, 71, 72, 0];
+        let default_vec = flatbuffers::Vector::new(&default_vec_buf[..], 0);
+        let v = tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<u8>>>(fi2fo(0), Some(default_vec)).unwrap();
+        assert_eq!(v.len(), 3);
+        assert_eq!(v.get(0), 70);
+        assert_eq!(v.get(1), 71);
+        assert_eq!(v.get(2), 72);
+    }
+}
+
+#[cfg(test)]
+mod push_impls {
+    extern crate flatbuffers;
+
+    use super::my_game;
+
+    fn check<'a>(b: &'a flatbuffers::FlatBufferBuilder, want: &'a [u8]) {
+        let got = b.unfinished_data();
+        assert_eq!(want, got);
+    }
+
+    #[test]
+    fn push_u8() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.push(123u8);
+        check(&b, &[123]);
+    }
+
+    #[test]
+    fn push_u64() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.push(0x12345678);
+        check(&b, &[0x78, 0x56, 0x34, 0x12]);
+    }
+
+    #[test]
+    fn push_f64() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.push(3.14159265359f64);
+        check(&b, &[234, 46, 68, 84, 251, 33, 9, 64]);
+    }
+
+    #[test]
+    fn push_generated_struct() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.push(my_game::example::Test::new(10, 20));
+        check(&b, &[10, 0, 20, 0]);
+    }
+
+    #[test]
+    fn push_u8_vector_with_offset_with_alignment() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off = b.create_vector(&[1u8, 2, 3, 4, 5, 6, 7, 8, 9][..]);
+        b.push(off);
+        check(&b, &[/* loc */ 4, 0, 0, 0, /* len */ 9, 0, 0, 0, /* val */ 1, 2, 3, 4, 5, 6, 7, 8, 9, /* padding */ 0, 0, 0]);
+    }
+
+    #[test]
+    fn push_u8_u16_alignment() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.push(1u8);
+        b.push(2u16);
+        check(&b, &[2, 0, 0, 1]);
+    }
+
+    #[test]
+    fn push_u8_u32_alignment() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.push(1u8);
+        b.push(2u32);
+        check(&b, &[2, 0, 0, 0, 0, 0, 0, 1]);
+    }
+
+    #[test]
+    fn push_u8_u64_alignment() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.push(1u8);
+        b.push(2u64);
+        check(&b, &[2, 0, 0, 0,
+                    0, 0, 0, 0,
+                    0, 0, 0, 0,
+                    0, 0, 0, 1]);
+    }
+}
+
+#[cfg(test)]
+mod vtable_deduplication {
+    extern crate flatbuffers;
+    use flatbuffers::field_index_to_field_offset as fi2fo;
+
+    fn check<'a>(b: &'a flatbuffers::FlatBufferBuilder, want: &'a [u8]) {
+        let got = b.unfinished_data();
+        assert_eq!(want, got);
+    }
+
+    #[test]
+    fn one_empty_table() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let start0 = b.start_table();
+        b.end_table(start0);
+        check(&b, &[
+              4, 0, // vtable size in bytes
+              4, 0, // object inline data in bytes
+
+              4, 0, 0, 0, // backwards offset to vtable
+        ]);
+    }
+
+    #[test]
+    fn two_empty_tables_are_deduplicated() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let start0 = b.start_table();
+        b.end_table(start0);
+        let start1 = b.start_table();
+        b.end_table(start1);
+        check(&b, &[
+              252, 255, 255, 255, // forwards offset to vtable
+
+              4, 0, // vtable size in bytes
+              4, 0, // object inline data in bytes
+
+              4, 0, 0, 0, // backwards offset to vtable
+        ]);
+    }
+
+    #[test]
+    fn two_tables_with_two_conveniently_sized_inline_elements_are_deduplicated() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let start0 = b.start_table();
+        b.push_slot::<u64>(fi2fo(0), 100, 0);
+        b.push_slot::<u32>(fi2fo(1), 101, 0);
+        b.end_table(start0);
+        let start1 = b.start_table();
+        b.push_slot::<u64>(fi2fo(0), 200, 0);
+        b.push_slot::<u32>(fi2fo(1), 201, 0);
+        b.end_table(start1);
+        check(&b, &[
+              240, 255, 255, 255, // forwards offset to vtable
+
+              201, 0, 0, 0, // value #1
+              200, 0, 0, 0, 0, 0, 0, 0, // value #0
+
+              8, 0, // vtable size in bytes
+              16, 0, // object inline data in bytes
+              8, 0, // offset in object for value #0
+              4, 0, // offset in object for value #1
+
+              8, 0, 0, 0, // backwards offset to vtable
+              101, 0, 0, 0, // value #1
+              100, 0, 0, 0, 0, 0, 0, 0 // value #0
+        ]);
+    }
+
+    #[test]
+    fn many_identical_tables_use_few_vtables() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        for _ in 0..1000 {
+            let start = b.start_table();
+            b.push_slot::<u8>(fi2fo(0), 100, 0);
+            b.push_slot::<u32>(fi2fo(1), 101, 0);
+            b.end_table(start);
+        }
+        assert!(b.num_written_vtables() <= 10);
+    }
+}
+
+#[cfg(test)]
+mod byte_layouts {
+    extern crate flatbuffers;
+    use flatbuffers::field_index_to_field_offset as fi2fo;
+
+    fn check<'a>(b: &'a flatbuffers::FlatBufferBuilder, want: &'a [u8]) {
+        let got = b.unfinished_data();
+        assert_eq!(want, got);
+    }
+
+    #[test]
+    fn layout_01_basic_numbers() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.push(true);
+        check(&b, &[1]);
+        b.push(-127i8);
+        check(&b, &[129, 1]);
+        b.push(255u8);
+        check(&b, &[255, 129, 1]);
+        b.push(-32222i16);
+        check(&b, &[0x22, 0x82, 0, 255, 129, 1]); // first pad
+        b.push(0xFEEEu16);
+        check(&b, &[0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1]); // no pad this time
+        b.push(-53687092i32);
+        check(&b, &[204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1]);
+        b.push(0x98765432u32);
+        check(&b, &[0x32, 0x54, 0x76, 0x98, 204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1]);
+    }
+
+    #[test]
+    fn layout_01b_bigger_numbers() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.push(0x1122334455667788u64);
+        check(&b, &[0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11]);
+    }
+
+    #[test]
+    fn layout_02_1xbyte_vector() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        check(&b, &[]);
+        b.start_vector::<u8>(1);
+        check(&b, &[0, 0, 0]); // align to 4bytes
+        b.push(1u8);
+        check(&b, &[1, 0, 0, 0]);
+        b.end_vector::<u8>(1);
+        check(&b, &[1, 0, 0, 0, 1, 0, 0, 0]); // padding
+    }
+
+    #[test]
+    fn layout_03_2xbyte_vector() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.start_vector::<u8>(2);
+        check(&b, &[0, 0]); // align to 4bytes
+        b.push(1u8);
+        check(&b, &[1, 0, 0]);
+        b.push(2u8);
+        check(&b, &[2, 1, 0, 0]);
+        b.end_vector::<u8>(2);
+        check(&b, &[2, 0, 0, 0, 2, 1, 0, 0]); // padding
+    }
+
+    #[test]
+    fn layout_03b_11xbyte_vector_matches_builder_size() {
+        let mut b = flatbuffers::FlatBufferBuilder::new_with_capacity(12);
+        b.start_vector::<u8>(8);
+
+        let mut gold = vec![0u8; 0];
+        check(&b, &gold[..]);
+
+        for i in 1u8..=8 {
+            b.push(i);
+            gold.insert(0, i);
+            check(&b, &gold[..]);
+        }
+        b.end_vector::<u8>(8);
+        let want = vec![8u8, 0, 0, 0,  8, 7, 6, 5, 4, 3, 2, 1];
+        check(&b, &want[..]);
+    }
+    #[test]
+    fn layout_04_1xuint16_vector() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.start_vector::<u16>(1);
+        check(&b, &[0, 0]); // align to 4bytes
+        b.push(1u16);
+        check(&b, &[1, 0, 0, 0]);
+        b.end_vector::<u16>(1);
+        check(&b, &[1, 0, 0, 0, 1, 0, 0, 0]); // padding
+    }
+
+    #[test]
+    fn layout_05_2xuint16_vector() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let _off = b.start_vector::<u16>(2);
+        check(&b, &[]); // align to 4bytes
+        b.push(0xABCDu16);
+        check(&b, &[0xCD, 0xAB]);
+        b.push(0xDCBAu16);
+        check(&b, &[0xBA, 0xDC, 0xCD, 0xAB]);
+        b.end_vector::<u16>(2);
+        check(&b, &[2, 0, 0, 0, 0xBA, 0xDC, 0xCD, 0xAB]);
+    }
+
+    #[test]
+    fn layout_06_create_string() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off0 = b.create_string("foo");
+        assert_eq!(8, off0.value());
+        check(&b, b"\x03\x00\x00\x00foo\x00"); // 0-terminated, no pad
+        let off1 = b.create_string("moop");
+        assert_eq!(20, off1.value());
+        check(&b, b"\x04\x00\x00\x00moop\x00\x00\x00\x00\
+                    \x03\x00\x00\x00foo\x00"); // 0-terminated, 3-byte pad
+    }
+
+    #[test]
+    fn layout_06b_create_string_unicode() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        // These characters are chinese from blog.golang.org/strings
+        // We use escape codes here so that editors without unicode support
+        // aren't bothered:
+        let uni_str = "\u{65e5}\u{672c}\u{8a9e}";
+        let off0 = b.create_string(uni_str);
+        assert_eq!(16, off0.value());
+        check(&b, &[9, 0, 0, 0, 230, 151, 165, 230, 156, 172, 232, 170, 158, 0, //  null-terminated, 2-byte pad
+                    0, 0]);
+    }
+
+    #[test]
+    fn layout_06c_create_byte_string() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off0 = b.create_byte_string(b"foo");
+        assert_eq!(8, off0.value());
+        check(&b, b"\x03\x00\x00\x00foo\x00"); // 0-terminated, no pad
+        let off1 = b.create_byte_string(b"moop");
+        assert_eq!(20, off1.value());
+        check(&b, b"\x04\x00\x00\x00moop\x00\x00\x00\x00\
+                    \x03\x00\x00\x00foo\x00"); // 0-terminated, 3-byte pad
+    }
+
+    #[test]
+    fn layout_07_empty_vtable() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off0 = b.start_table();
+        check(&b, &[]);
+        b.end_table(off0);
+        check(&b, &[4, 0, // vtable length
+                    4, 0, // length of table including vtable offset
+                    4, 0, 0, 0]); // offset for start of vtable
+    }
+
+    #[test]
+    fn layout_08_vtable_with_one_true_bool() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        check(&b, &[]);
+        let off0 = b.start_table();
+        assert_eq!(0, off0.value());
+        check(&b, &[]);
+        b.push_slot(fi2fo(0), true, false);
+        check(&b, &[1]);
+        let off1 = b.end_table(off0);
+        assert_eq!(8, off1.value());
+        check(&b, &[
+              6, 0, // vtable bytes
+              8, 0, // length of object including vtable offset
+              7, 0, // start of bool value
+              6, 0, 0, 0, // offset for start of vtable (int32)
+              0, 0, 0, // padded to 4 bytes
+              1, // bool value
+        ]);
+    }
+
+    #[test]
+    fn layout_09_vtable_with_one_default_bool() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        check(&b, &[]);
+        let off = b.start_table();
+        check(&b, &[]);
+        b.push_slot(fi2fo(0), false, false);
+        b.end_table(off);
+        check(&b, &[
+             4, 0, // vtable bytes
+             4, 0, // end of object from here
+             // entry 1 is zero and not stored.
+             4, 0, 0, 0, // offset for start of vtable (int32)
+        ]);
+    }
+
+    #[test]
+    fn layout_10_vtable_with_one_int16() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        check(&b, &[]);
+        let off = b.start_table();
+        b.push_slot(fi2fo(0), 0x789Ai16, 0);
+        b.end_table(off);
+        check(&b, &[
+              6, 0, // vtable bytes
+              8, 0, // end of object from here
+              6, 0, // offset to value
+              6, 0, 0, 0, // offset for start of vtable (int32)
+              0, 0, // padding to 4 bytes
+              0x9A, 0x78,
+        ]);
+    }
+
+    #[test]
+    fn layout_11_vtable_with_two_int16() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off = b.start_table();
+        b.push_slot(fi2fo(0), 0x3456i16, 0);
+        b.push_slot(fi2fo(1), 0x789Ai16, 0);
+        b.end_table(off);
+        check(&b, &[
+              8, 0, // vtable bytes
+              8, 0, // end of object from here
+              6, 0, // offset to value 0
+              4, 0, // offset to value 1
+              8, 0, 0, 0, // offset for start of vtable (int32)
+              0x9A, 0x78, // value 1
+              0x56, 0x34, // value 0
+        ]);
+    }
+
+    #[test]
+    fn layout_12_vtable_with_int16_and_bool() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off = b.start_table();
+        b.push_slot(fi2fo(0), 0x3456i16, 0);
+        b.push_slot(fi2fo(1), true, false);
+        b.end_table(off);
+        check(&b, &[
+            8, 0, // vtable bytes
+            8, 0, // end of object from here
+            6, 0, // offset to value 0
+            5, 0, // offset to value 1
+            8, 0, 0, 0, // offset for start of vtable (int32)
+            0,          // padding
+            1,          // value 1
+            0x56, 0x34, // value 0
+        ]);
+    }
+
+    #[test]
+    fn layout_12b_vtable_with_empty_vector() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.start_vector::<u8>(0);
+        let vecend = b.end_vector::<u8>(0);
+        let off = b.start_table();
+        b.push_slot_always(fi2fo(0), vecend);
+        b.end_table(off);
+        check(&b, &[
+              6, 0, // vtable bytes
+              8, 0,
+              4, 0, // offset to vector offset
+              6, 0, 0, 0, // offset for start of vtable (int32)
+              4, 0, 0, 0,
+              0, 0, 0, 0, // length of vector (not in struct)
+        ]);
+    }
+
+    #[test]
+    fn layout_12c_vtable_with_empty_vector_of_byte_and_some_scalars() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.start_vector::<u8>(0);
+        let vecend = b.end_vector::<u8>(0);
+        let off = b.start_table();
+        b.push_slot::<i16>(fi2fo(0), 55i16, 0);
+        b.push_slot_always::<flatbuffers::WIPOffset<_>>(fi2fo(1), vecend);
+        b.end_table(off);
+        check(&b, &[
+              8, 0, // vtable bytes
+              12, 0,
+              10, 0, // offset to value 0
+              4, 0, // offset to vector offset
+              8, 0, 0, 0, // vtable loc
+              8, 0, 0, 0, // value 1
+              0, 0, 55, 0, // value 0
+
+              0, 0, 0, 0, // length of vector (not in struct)
+        ]);
+    }
+    #[test]
+    fn layout_13_vtable_with_1_int16_and_2_vector_of_i16() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.start_vector::<i16>(2);
+        b.push(0x1234i16);
+        b.push(0x5678i16);
+        let vecend = b.end_vector::<i16>(2);
+        let off = b.start_table();
+        b.push_slot_always(fi2fo(1), vecend);
+        b.push_slot(fi2fo(0), 55i16, 0);
+        b.end_table(off);
+        check(&b, &[
+              8, 0, // vtable bytes
+              12, 0, // length of object
+              6, 0, // start of value 0 from end of vtable
+              8, 0, // start of value 1 from end of buffer
+              8, 0, 0, 0, // offset for start of vtable (int32)
+              0, 0, // padding
+              55, 0, // value 0
+              4, 0, 0, 0, // vector position from here
+              2, 0, 0, 0, // length of vector (uint32)
+              0x78, 0x56, // vector value 1
+              0x34, 0x12, // vector value 0
+        ]);
+    }
+    #[test]
+    fn layout_14_vtable_with_1_struct_of_int8_and_int16_and_int32() {
+        #[derive(Copy, Clone, Debug, Eq, PartialEq)]
+        #[repr(C, packed)]
+        struct foo {
+            a: i32,
+            _pad0: [u8; 2],
+            b: i16,
+            _pad1: [u8; 3],
+            c: i8,
+            _pad2: [u8; 4],
+        }
+        assert_eq!(::std::mem::size_of::<foo>(), 16);
+        impl<'b> flatbuffers::Push for &'b foo {
+            type Output = foo;
+            fn push<'a>(&'a self, dst: &'a mut [u8], _rest: &'a [u8]) {
+                let src = unsafe {
+                    ::std::slice::from_raw_parts(*self as *const foo as *const u8, ::std::mem::size_of::<foo>())
+                };
+                dst.copy_from_slice(src);
+            }
+        }
+
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off = b.start_table();
+        let x = foo{a: 0x12345678i32.to_le(), _pad0: [0,0], b: 0x1234i16.to_le(), _pad1: [0, 0, 0], c: 0x12i8.to_le(), _pad2: [0, 0, 0, 0]};
+        b.push_slot_always(fi2fo(0), &x);
+        b.end_table(off);
+        check(&b, &[
+              6, 0, // vtable bytes
+              20, 0, // end of object from here
+              4, 0, // start of struct from here
+              6, 0, 0, 0, // offset for start of vtable (int32)
+
+              0x78, 0x56, 0x34, 0x12, // value a
+              0, 0, // padding
+              0x34, 0x12, // value b
+              0, 0, 0, // padding
+              0x12, // value c
+              0, 0, 0, 0, // padding
+        ]);
+    }
+    #[test]
+    fn layout_15_vtable_with_1_vector_of_4_int8() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        b.start_vector::<i8>(4);
+        b.push(33i8);
+        b.push(44i8);
+        b.push(55i8);
+        b.push(66i8);
+        let vecend = b.end_vector::<i8>(4);
+        let off = b.start_table();
+        b.push_slot_always(fi2fo(0), vecend);
+        b.end_table(off);
+        check(&b, &[
+              6, 0, // vtable bytes
+              8, 0,
+              4, 0, // offset of vector offset
+              6, 0, 0, 0, // offset for start of vtable (int32)
+              4, 0, 0, 0, // vector start offset
+
+              4, 0, 0, 0, // vector length
+              66, // vector value 1,1
+              55, // vector value 1,0
+              44, // vector value 0,1
+              33, // vector value 0,0
+        ]);
+    }
+
+    #[test]
+    fn layout_16_table_with_some_elements() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off = b.start_table();
+        b.push_slot(fi2fo(0), 33i8, 0);
+        b.push_slot(fi2fo(1), 66i16, 0);
+        let off2 = b.end_table(off);
+        b.finish_minimal(off2);
+
+        check(&b, &[
+              12, 0, 0, 0, // root of table: points to vtable offset
+
+              8, 0, // vtable bytes
+              8, 0, // end of object from here
+              7, 0, // start of value 0
+              4, 0, // start of value 1
+
+              8, 0, 0, 0, // offset for start of vtable (int32)
+
+              66, 0, // value 1
+              0,  // padding
+              33, // value 0
+        ]);
+    }
+
+    #[test]
+    fn layout_17_one_unfinished_table_and_one_finished_table() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        {
+            let off = b.start_table();
+            b.push_slot(fi2fo(0), 33i8, 0);
+            b.push_slot(fi2fo(1), 44i8, 0);
+            b.end_table(off);
+        }
+
+        {
+            let off = b.start_table();
+            b.push_slot(fi2fo(0), 55i8, 0);
+            b.push_slot(fi2fo(1), 66i8, 0);
+            b.push_slot(fi2fo(2), 77i8, 0);
+            let off2 = b.end_table(off);
+            b.finish_minimal(off2);
+        }
+
+        check(&b, &[
+              16, 0, 0, 0, // root of table: points to object
+              0, 0, // padding
+
+              10, 0, // vtable bytes
+              8, 0, // size of object
+              7, 0, // start of value 0
+              6, 0, // start of value 1
+              5, 0, // start of value 2
+              10, 0, 0, 0, // offset for start of vtable (int32)
+              0,  // padding
+              77, // value 2
+              66, // value 1
+              55, // value 0
+
+              //12, 0, 0, 0, // root of table: points to object
+
+              8, 0, // vtable bytes
+              8, 0, // size of object
+              7, 0, // start of value 0
+              6, 0, // start of value 1
+              8, 0, 0, 0, // offset for start of vtable (int32)
+              0, 0, // padding
+              44, // value 1
+              33, // value 0
+              ]);
+    }
+
+    #[test]
+    fn layout_18_a_bunch_of_bools() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off = b.start_table();
+        b.push_slot(fi2fo(0), true, false);
+        b.push_slot(fi2fo(1), true, false);
+        b.push_slot(fi2fo(2), true, false);
+        b.push_slot(fi2fo(3), true, false);
+        b.push_slot(fi2fo(4), true, false);
+        b.push_slot(fi2fo(5), true, false);
+        b.push_slot(fi2fo(6), true, false);
+        b.push_slot(fi2fo(7), true, false);
+        let off2 = b.end_table(off);
+        b.finish_minimal(off2);
+
+        check(&b, &[
+              24, 0, 0, 0, // root of table: points to vtable offset
+
+              20, 0, // vtable bytes
+              12, 0, // size of object
+              11, 0, // start of value 0
+              10, 0, // start of value 1
+              9, 0, // start of value 2
+              8, 0, // start of value 3
+              7, 0, // start of value 4
+              6, 0, // start of value 5
+              5, 0, // start of value 6
+              4, 0, // start of value 7
+              20, 0, 0, 0, // vtable offset
+
+              1, // value 7
+              1, // value 6
+              1, // value 5
+              1, // value 4
+              1, // value 3
+              1, // value 2
+              1, // value 1
+              1, // value 0
+              ]);
+    }
+
+    #[test]
+    fn layout_19_three_bools() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off = b.start_table();
+        b.push_slot(fi2fo(0), true, false);
+        b.push_slot(fi2fo(1), true, false);
+        b.push_slot(fi2fo(2), true, false);
+        let off2 = b.end_table(off);
+        b.finish_minimal(off2);
+
+        check(&b, &[
+              16, 0, 0, 0, // root of table: points to vtable offset
+
+              0, 0, // padding
+
+              10, 0, // vtable bytes
+              8, 0, // size of object
+              7, 0, // start of value 0
+              6, 0, // start of value 1
+              5, 0, // start of value 2
+              10, 0, 0, 0, // vtable offset from here
+
+              0, // padding
+              1, // value 2
+              1, // value 1
+              1, // value 0
+        ]);
+    }
+
+    #[test]
+    fn layout_20_some_floats() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off = b.start_table();
+        b.push_slot(fi2fo(0), 1.0f32, 0.0);
+        b.end_table(off);
+
+        check(&b, &[
+              6, 0, // vtable bytes
+              8, 0, // size of object
+              4, 0, // start of value 0
+              6, 0, 0, 0, // vtable offset
+
+              0, 0, 128, 63, // value 0
+        ]);
+    }
+
+    #[test]
+    fn layout_21_vtable_defaults() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off = b.start_table();
+        b.push_slot::<i8>(fi2fo(0), 1, 1);
+        b.push_slot::<i8>(fi2fo(1), 3, 2);
+        b.push_slot::<i8>(fi2fo(2), 3, 3);
+        b.end_table(off);
+        check(&b, &[
+              8, 0, // vtable size in bytes
+              8, 0, // object inline data in bytes
+              0, 0, // entry 1/3: 0 => default
+              7, 0, // entry 2/3: 7 => table start + 7 bytes
+              // entry 3/3: not present => default
+              8, 0, 0, 0,
+              0, 0, 0,
+              3,
+        ]);
+    }
+
+    #[test]
+    fn layout_22_root() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off = b.start_table();
+        // skipped: b.push_slot_scalar::<i16>(0, 1, 1);
+        b.push_slot::<i16>(fi2fo(1), 3, 2);
+        b.push_slot::<i16>(fi2fo(2), 3, 3);
+        let table_end = b.end_table(off);
+        b.finish_minimal(table_end);
+        check(&b, &[
+              12, 0, 0, 0, // root
+
+              8, 0, // vtable size in bytes
+              8, 0, // object inline data in bytes
+              0, 0, // entry 1/3: 0 => default
+              6, 0, // entry 2/3: 6 => table start + 6 bytes
+              // entry 3/3: not present => default
+              8, 0, 0, 0, // size of table data in bytes
+              0, 0, // padding
+              3, 0, // value 2/3
+        ]);
+    }
+    #[test]
+    fn layout_23_varied_slots_and_root() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        let off = b.start_table();
+        b.push_slot::<i16>(fi2fo(0), 1, 0);
+        b.push_slot::<u8>(fi2fo(1), 2, 0);
+        b.push_slot::<f32>(fi2fo(2), 3.0, 0.0);
+        let table_end = b.end_table(off);
+        b.finish_minimal(table_end);
+        check(&b, &[
+              16, 0, 0, 0, // root
+              0, 0, // padding
+              10, 0, // vtable bytes
+              12, 0, // object inline data size
+              10, 0, // offset to value #1 (i16)
+              9, 0, // offset to value #2 (u8)
+              4, 0, // offset to value #3 (f32)
+              10, 0, // offset to vtable
+              0, 0, // padding
+              0, 0, 64, 64, // value #3 => 3.0 (float32)
+              0, 2, // value #1 => 2 (u8)
+              1, 0, // value #0 => 1 (int16)
+        ]);
+    }
+}
+
+// this is not technically a test, but we want to always keep this generated
+// file up-to-date, and the simplest way to do that is to make sure that when
+// tests are run, the file is generated.
+#[test]
+fn write_example_wire_data_to_file() {
+    let b = &mut flatbuffers::FlatBufferBuilder::new();
+    create_serialized_example_with_generated_code(b);
+
+    use ::std::io::Write;
+    let mut f = std::fs::File::create("../monsterdata_rust_wire.mon").unwrap();
+    f.write_all(b.finished_data()).unwrap();
+}
+
+fn load_file(filename: &str) -> Result<Vec<u8>, std::io::Error> {
+    use std::io::Read;
+    let mut f = std::fs::File::open(filename)?;
+    let mut buf = Vec::new();
+    f.read_to_end(&mut buf)?;
+    Ok(buf)
+}
diff --git a/third_party/flatbuffers/tests/test.cpp b/third_party/flatbuffers/tests/test.cpp
new file mode 100644
index 0000000..461840c
--- /dev/null
+++ b/third_party/flatbuffers/tests/test.cpp
@@ -0,0 +1,3068 @@
+/*
+ * 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 <cmath>
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/minireflect.h"
+#include "flatbuffers/registry.h"
+#include "flatbuffers/util.h"
+
+// clang-format off
+#ifdef FLATBUFFERS_CPP98_STL
+  #include "flatbuffers/stl_emulation.h"
+  namespace std {
+    using flatbuffers::unique_ptr;
+  }
+#endif
+// clang-format on
+
+#include "monster_test_generated.h"
+#include "namespace_test/namespace_test1_generated.h"
+#include "namespace_test/namespace_test2_generated.h"
+#include "union_vector/union_vector_generated.h"
+#include "monster_extra_generated.h"
+#if !defined(_MSC_VER) || _MSC_VER >= 1700
+#include "arrays_test_generated.h"
+#endif
+
+#include "native_type_test_generated.h"
+#include "test_assert.h"
+
+#include "flatbuffers/flexbuffers.h"
+
+
+// clang-format off
+// Check that char* and uint8_t* are interoperable types.
+// The reinterpret_cast<> between the pointers are used to simplify data loading.
+static_assert(flatbuffers::is_same<uint8_t, char>::value ||
+              flatbuffers::is_same<uint8_t, unsigned char>::value,
+              "unexpected uint8_t type");
+
+#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
+  // Ensure IEEE-754 support if tests of floats with NaN/Inf will run.
+  static_assert(std::numeric_limits<float>::is_iec559 &&
+                std::numeric_limits<double>::is_iec559,
+                "IEC-559 (IEEE-754) standard required");
+#endif
+// clang-format on
+
+// Shortcuts for the infinity.
+static const auto infinityf = std::numeric_limits<float>::infinity();
+static const auto infinityd = std::numeric_limits<double>::infinity();
+
+using namespace MyGame::Example;
+
+void FlatBufferBuilderTest();
+
+// Include simple random number generator to ensure results will be the
+// same cross platform.
+// http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator
+uint32_t lcg_seed = 48271;
+uint32_t lcg_rand() {
+  return lcg_seed = (static_cast<uint64_t>(lcg_seed) * 279470273UL) % 4294967291UL;
+}
+void lcg_reset() { lcg_seed = 48271; }
+
+std::string test_data_path =
+#ifdef BAZEL_TEST_DATA_PATH
+    "../com_github_google_flatbuffers/tests/";
+#else
+    "tests/";
+#endif
+
+// example of how to build up a serialized buffer algorithmically:
+flatbuffers::DetachedBuffer CreateFlatBufferTest(std::string &buffer) {
+  flatbuffers::FlatBufferBuilder builder;
+
+  auto vec = Vec3(1, 2, 3, 0, Color_Red, Test(10, 20));
+
+  auto name = builder.CreateString("MyMonster");
+
+  unsigned char inv_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+  auto inventory = builder.CreateVector(inv_data, 10);
+
+  // Alternatively, create the vector first, and fill in data later:
+  // unsigned char *inv_buf = nullptr;
+  // auto inventory = builder.CreateUninitializedVector<unsigned char>(
+  //                                                              10, &inv_buf);
+  // memcpy(inv_buf, inv_data, 10);
+
+  Test tests[] = { Test(10, 20), Test(30, 40) };
+  auto testv = builder.CreateVectorOfStructs(tests, 2);
+
+  // clang-format off
+  #ifndef FLATBUFFERS_CPP98_STL
+    // Create a vector of structures from a lambda.
+    auto testv2 = builder.CreateVectorOfStructs<Test>(
+          2, [&](size_t i, Test* s) -> void {
+            *s = tests[i];
+          });
+  #else
+    // Create a vector of structures using a plain old C++ function.
+    auto testv2 = builder.CreateVectorOfStructs<Test>(
+          2, [](size_t i, Test* s, void *state) -> void {
+            *s = (reinterpret_cast<Test*>(state))[i];
+          }, tests);
+  #endif  // FLATBUFFERS_CPP98_STL
+  // clang-format on
+
+  // create monster with very few fields set:
+  // (same functionality as CreateMonster below, but sets fields manually)
+  flatbuffers::Offset<Monster> mlocs[3];
+  auto fred = builder.CreateString("Fred");
+  auto barney = builder.CreateString("Barney");
+  auto wilma = builder.CreateString("Wilma");
+  MonsterBuilder mb1(builder);
+  mb1.add_name(fred);
+  mlocs[0] = mb1.Finish();
+  MonsterBuilder mb2(builder);
+  mb2.add_name(barney);
+  mb2.add_hp(1000);
+  mlocs[1] = mb2.Finish();
+  MonsterBuilder mb3(builder);
+  mb3.add_name(wilma);
+  mlocs[2] = mb3.Finish();
+
+  // Create an array of strings. Also test string pooling, and lambdas.
+  auto vecofstrings =
+      builder.CreateVector<flatbuffers::Offset<flatbuffers::String>>(
+          4,
+          [](size_t i, flatbuffers::FlatBufferBuilder *b)
+              -> flatbuffers::Offset<flatbuffers::String> {
+            static const char *names[] = { "bob", "fred", "bob", "fred" };
+            return b->CreateSharedString(names[i]);
+          },
+          &builder);
+
+  // Creating vectors of strings in one convenient call.
+  std::vector<std::string> names2;
+  names2.push_back("jane");
+  names2.push_back("mary");
+  auto vecofstrings2 = builder.CreateVectorOfStrings(names2);
+
+  // Create an array of sorted tables, can be used with binary search when read:
+  auto vecoftables = builder.CreateVectorOfSortedTables(mlocs, 3);
+
+  // Create an array of sorted structs,
+  // can be used with binary search when read:
+  std::vector<Ability> abilities;
+  abilities.push_back(Ability(4, 40));
+  abilities.push_back(Ability(3, 30));
+  abilities.push_back(Ability(2, 20));
+  abilities.push_back(Ability(1, 10));
+  auto vecofstructs = builder.CreateVectorOfSortedStructs(&abilities);
+
+  // Create a nested FlatBuffer.
+  // Nested FlatBuffers are stored in a ubyte vector, which can be convenient
+  // since they can be memcpy'd around much easier than other FlatBuffer
+  // values. They have little overhead compared to storing the table directly.
+  // As a test, create a mostly empty Monster buffer:
+  flatbuffers::FlatBufferBuilder nested_builder;
+  auto nmloc = CreateMonster(nested_builder, nullptr, 0, 0,
+                             nested_builder.CreateString("NestedMonster"));
+  FinishMonsterBuffer(nested_builder, nmloc);
+  // Now we can store the buffer in the parent. Note that by default, vectors
+  // are only aligned to their elements or size field, so in this case if the
+  // buffer contains 64-bit elements, they may not be correctly aligned. We fix
+  // that with:
+  builder.ForceVectorAlignment(nested_builder.GetSize(), sizeof(uint8_t),
+                               nested_builder.GetBufferMinAlignment());
+  // If for whatever reason you don't have the nested_builder available, you
+  // can substitute flatbuffers::largest_scalar_t (64-bit) for the alignment, or
+  // the largest force_align value in your schema if you're using it.
+  auto nested_flatbuffer_vector = builder.CreateVector(
+      nested_builder.GetBufferPointer(), nested_builder.GetSize());
+
+  // Test a nested FlexBuffer:
+  flexbuffers::Builder flexbuild;
+  flexbuild.Int(1234);
+  flexbuild.Finish();
+  auto flex = builder.CreateVector(flexbuild.GetBuffer());
+
+  // Test vector of enums.
+  Color colors[] = { Color_Blue, Color_Green };
+  // We use this special creation function because we have an array of
+  // pre-C++11 (enum class) enums whose size likely is int, yet its declared
+  // type in the schema is byte.
+  auto vecofcolors = builder.CreateVectorScalarCast<uint8_t, Color>(colors, 2);
+
+  // shortcut for creating monster with all fields set:
+  auto mloc = CreateMonster(builder, &vec, 150, 80, name, inventory, Color_Blue,
+                            Any_Monster, mlocs[1].Union(),  // Store a union.
+                            testv, vecofstrings, vecoftables, 0,
+                            nested_flatbuffer_vector, 0, false, 0, 0, 0, 0, 0,
+                            0, 0, 0, 0, 3.14159f, 3.0f, 0.0f, vecofstrings2,
+                            vecofstructs, flex, testv2, 0, 0, 0, 0, 0, 0, 0, 0,
+                            0, 0, 0, AnyUniqueAliases_NONE, 0,
+                            AnyAmbiguousAliases_NONE, 0, vecofcolors);
+
+  FinishMonsterBuffer(builder, mloc);
+
+  // clang-format off
+  #ifdef FLATBUFFERS_TEST_VERBOSE
+  // print byte data for debugging:
+  auto p = builder.GetBufferPointer();
+  for (flatbuffers::uoffset_t i = 0; i < builder.GetSize(); i++)
+    printf("%d ", p[i]);
+  #endif
+  // clang-format on
+
+  // return the buffer for the caller to use.
+  auto bufferpointer =
+      reinterpret_cast<const char *>(builder.GetBufferPointer());
+  buffer.assign(bufferpointer, bufferpointer + builder.GetSize());
+
+  return builder.Release();
+}
+
+//  example of accessing a buffer loaded in memory:
+void AccessFlatBufferTest(const uint8_t *flatbuf, size_t length,
+                          bool pooled = true) {
+  // First, verify the buffers integrity (optional)
+  flatbuffers::Verifier verifier(flatbuf, length);
+  TEST_EQ(VerifyMonsterBuffer(verifier), true);
+
+  // clang-format off
+  #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
+    std::vector<uint8_t> test_buff;
+    test_buff.resize(length * 2);
+    std::memcpy(&test_buff[0], flatbuf, length);
+    std::memcpy(&test_buff[length], flatbuf, length);
+
+    flatbuffers::Verifier verifier1(&test_buff[0], length);
+    TEST_EQ(VerifyMonsterBuffer(verifier1), true);
+    TEST_EQ(verifier1.GetComputedSize(), length);
+
+    flatbuffers::Verifier verifier2(&test_buff[length], length);
+    TEST_EQ(VerifyMonsterBuffer(verifier2), true);
+    TEST_EQ(verifier2.GetComputedSize(), length);
+  #endif
+  // clang-format on
+
+  TEST_EQ(strcmp(MonsterIdentifier(), "MONS"), 0);
+  TEST_EQ(MonsterBufferHasIdentifier(flatbuf), true);
+  TEST_EQ(strcmp(MonsterExtension(), "mon"), 0);
+
+  // Access the buffer from the root.
+  auto monster = GetMonster(flatbuf);
+
+  TEST_EQ(monster->hp(), 80);
+  TEST_EQ(monster->mana(), 150);  // default
+  TEST_EQ_STR(monster->name()->c_str(), "MyMonster");
+  // Can't access the following field, it is deprecated in the schema,
+  // which means accessors are not generated:
+  // monster.friendly()
+
+  auto pos = monster->pos();
+  TEST_NOTNULL(pos);
+  TEST_EQ(pos->z(), 3);
+  TEST_EQ(pos->test3().a(), 10);
+  TEST_EQ(pos->test3().b(), 20);
+
+  auto inventory = monster->inventory();
+  TEST_EQ(VectorLength(inventory), 10UL);  // Works even if inventory is null.
+  TEST_NOTNULL(inventory);
+  unsigned char inv_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+  // Check compatibilty of iterators with STL.
+  std::vector<unsigned char> inv_vec(inventory->begin(), inventory->end());
+  int n = 0;
+  for (auto it = inventory->begin(); it != inventory->end(); ++it, ++n) {
+    auto indx = it - inventory->begin();
+    TEST_EQ(*it, inv_vec.at(indx));  // Use bounds-check.
+    TEST_EQ(*it, inv_data[indx]);
+  }
+  TEST_EQ(n, inv_vec.size());
+
+  n = 0;
+  for (auto it = inventory->cbegin(); it != inventory->cend(); ++it, ++n) {
+    auto indx = it - inventory->cbegin();
+    TEST_EQ(*it, inv_vec.at(indx));  // Use bounds-check.
+    TEST_EQ(*it, inv_data[indx]);
+  }
+  TEST_EQ(n, inv_vec.size());
+
+  n = 0;
+  for (auto it = inventory->rbegin(); it != inventory->rend(); ++it, ++n) {
+    auto indx = inventory->rend() - it - 1;
+    TEST_EQ(*it, inv_vec.at(indx));  // Use bounds-check.
+    TEST_EQ(*it, inv_data[indx]);
+  }
+  TEST_EQ(n, inv_vec.size());
+
+  n = 0;
+  for (auto it = inventory->crbegin(); it != inventory->crend(); ++it, ++n) {
+    auto indx = inventory->crend() - it - 1;
+    TEST_EQ(*it, inv_vec.at(indx));  // Use bounds-check.
+    TEST_EQ(*it, inv_data[indx]);
+  }
+  TEST_EQ(n, inv_vec.size());
+
+  TEST_EQ(monster->color(), Color_Blue);
+
+  // Example of accessing a union:
+  TEST_EQ(monster->test_type(), Any_Monster);  // First make sure which it is.
+  auto monster2 = reinterpret_cast<const Monster *>(monster->test());
+  TEST_NOTNULL(monster2);
+  TEST_EQ_STR(monster2->name()->c_str(), "Fred");
+
+  // Example of accessing a vector of strings:
+  auto vecofstrings = monster->testarrayofstring();
+  TEST_EQ(vecofstrings->size(), 4U);
+  TEST_EQ_STR(vecofstrings->Get(0)->c_str(), "bob");
+  TEST_EQ_STR(vecofstrings->Get(1)->c_str(), "fred");
+  if (pooled) {
+    // These should have pointer equality because of string pooling.
+    TEST_EQ(vecofstrings->Get(0)->c_str(), vecofstrings->Get(2)->c_str());
+    TEST_EQ(vecofstrings->Get(1)->c_str(), vecofstrings->Get(3)->c_str());
+  }
+
+  auto vecofstrings2 = monster->testarrayofstring2();
+  if (vecofstrings2) {
+    TEST_EQ(vecofstrings2->size(), 2U);
+    TEST_EQ_STR(vecofstrings2->Get(0)->c_str(), "jane");
+    TEST_EQ_STR(vecofstrings2->Get(1)->c_str(), "mary");
+  }
+
+  // Example of accessing a vector of tables:
+  auto vecoftables = monster->testarrayoftables();
+  TEST_EQ(vecoftables->size(), 3U);
+  for (auto it = vecoftables->begin(); it != vecoftables->end(); ++it)
+    TEST_EQ(strlen(it->name()->c_str()) >= 4, true);
+  TEST_EQ_STR(vecoftables->Get(0)->name()->c_str(), "Barney");
+  TEST_EQ(vecoftables->Get(0)->hp(), 1000);
+  TEST_EQ_STR(vecoftables->Get(1)->name()->c_str(), "Fred");
+  TEST_EQ_STR(vecoftables->Get(2)->name()->c_str(), "Wilma");
+  TEST_NOTNULL(vecoftables->LookupByKey("Barney"));
+  TEST_NOTNULL(vecoftables->LookupByKey("Fred"));
+  TEST_NOTNULL(vecoftables->LookupByKey("Wilma"));
+
+  // Test accessing a vector of sorted structs
+  auto vecofstructs = monster->testarrayofsortedstruct();
+  if (vecofstructs) {  // not filled in monster_test.bfbs
+    for (flatbuffers::uoffset_t i = 0; i < vecofstructs->size() - 1; i++) {
+      auto left = vecofstructs->Get(i);
+      auto right = vecofstructs->Get(i + 1);
+      TEST_EQ(true, (left->KeyCompareLessThan(right)));
+    }
+    TEST_NOTNULL(vecofstructs->LookupByKey(3));
+    TEST_EQ(static_cast<const Ability *>(nullptr),
+            vecofstructs->LookupByKey(5));
+  }
+
+  // Test nested FlatBuffers if available:
+  auto nested_buffer = monster->testnestedflatbuffer();
+  if (nested_buffer) {
+    // nested_buffer is a vector of bytes you can memcpy. However, if you
+    // actually want to access the nested data, this is a convenient
+    // accessor that directly gives you the root table:
+    auto nested_monster = monster->testnestedflatbuffer_nested_root();
+    TEST_EQ_STR(nested_monster->name()->c_str(), "NestedMonster");
+  }
+
+  // Test flexbuffer if available:
+  auto flex = monster->flex();
+  // flex is a vector of bytes you can memcpy etc.
+  TEST_EQ(flex->size(), 4);  // Encoded FlexBuffer bytes.
+  // However, if you actually want to access the nested data, this is a
+  // convenient accessor that directly gives you the root value:
+  TEST_EQ(monster->flex_flexbuffer_root().AsInt16(), 1234);
+
+  // Test vector of enums:
+  auto colors = monster->vector_of_enums();
+  if (colors) {
+    TEST_EQ(colors->size(), 2);
+    TEST_EQ(colors->Get(0), Color_Blue);
+    TEST_EQ(colors->Get(1), Color_Green);
+  }
+
+  // Since Flatbuffers uses explicit mechanisms to override the default
+  // compiler alignment, double check that the compiler indeed obeys them:
+  // (Test consists of a short and byte):
+  TEST_EQ(flatbuffers::AlignOf<Test>(), 2UL);
+  TEST_EQ(sizeof(Test), 4UL);
+
+  const flatbuffers::Vector<const Test *> *tests_array[] = {
+    monster->test4(),
+    monster->test5(),
+  };
+  for (size_t i = 0; i < sizeof(tests_array) / sizeof(tests_array[0]); ++i) {
+    auto tests = tests_array[i];
+    TEST_NOTNULL(tests);
+    auto test_0 = tests->Get(0);
+    auto test_1 = tests->Get(1);
+    TEST_EQ(test_0->a(), 10);
+    TEST_EQ(test_0->b(), 20);
+    TEST_EQ(test_1->a(), 30);
+    TEST_EQ(test_1->b(), 40);
+    for (auto it = tests->begin(); it != tests->end(); ++it) {
+      TEST_EQ(it->a() == 10 || it->a() == 30, true);  // Just testing iterators.
+    }
+  }
+
+  // Checking for presence of fields:
+  TEST_EQ(flatbuffers::IsFieldPresent(monster, Monster::VT_HP), true);
+  TEST_EQ(flatbuffers::IsFieldPresent(monster, Monster::VT_MANA), false);
+
+  // Obtaining a buffer from a root:
+  TEST_EQ(GetBufferStartFromRootPointer(monster), flatbuf);
+}
+
+// Change a FlatBuffer in-place, after it has been constructed.
+void MutateFlatBuffersTest(uint8_t *flatbuf, std::size_t length) {
+  // Get non-const pointer to root.
+  auto monster = GetMutableMonster(flatbuf);
+
+  // Each of these tests mutates, then tests, then set back to the original,
+  // so we can test that the buffer in the end still passes our original test.
+  auto hp_ok = monster->mutate_hp(10);
+  TEST_EQ(hp_ok, true);  // Field was present.
+  TEST_EQ(monster->hp(), 10);
+  // Mutate to default value
+  auto hp_ok_default = monster->mutate_hp(100);
+  TEST_EQ(hp_ok_default, true);  // Field was present.
+  TEST_EQ(monster->hp(), 100);
+  // Test that mutate to default above keeps field valid for further mutations
+  auto hp_ok_2 = monster->mutate_hp(20);
+  TEST_EQ(hp_ok_2, true);
+  TEST_EQ(monster->hp(), 20);
+  monster->mutate_hp(80);
+
+  // Monster originally at 150 mana (default value)
+  auto mana_default_ok = monster->mutate_mana(150);  // Mutate to default value.
+  TEST_EQ(mana_default_ok,
+          true);  // Mutation should succeed, because default value.
+  TEST_EQ(monster->mana(), 150);
+  auto mana_ok = monster->mutate_mana(10);
+  TEST_EQ(mana_ok, false);  // Field was NOT present, because default value.
+  TEST_EQ(monster->mana(), 150);
+
+  // Mutate structs.
+  auto pos = monster->mutable_pos();
+  auto test3 = pos->mutable_test3();  // Struct inside a struct.
+  test3.mutate_a(50);                 // Struct fields never fail.
+  TEST_EQ(test3.a(), 50);
+  test3.mutate_a(10);
+
+  // Mutate vectors.
+  auto inventory = monster->mutable_inventory();
+  inventory->Mutate(9, 100);
+  TEST_EQ(inventory->Get(9), 100);
+  inventory->Mutate(9, 9);
+
+  auto tables = monster->mutable_testarrayoftables();
+  auto first = tables->GetMutableObject(0);
+  TEST_EQ(first->hp(), 1000);
+  first->mutate_hp(0);
+  TEST_EQ(first->hp(), 0);
+  first->mutate_hp(1000);
+
+  // Run the verifier and the regular test to make sure we didn't trample on
+  // anything.
+  AccessFlatBufferTest(flatbuf, length);
+}
+
+// Unpack a FlatBuffer into objects.
+void ObjectFlatBuffersTest(uint8_t *flatbuf) {
+  // Optional: we can specify resolver and rehasher functions to turn hashed
+  // strings into object pointers and back, to implement remote references
+  // and such.
+  auto resolver = flatbuffers::resolver_function_t(
+      [](void **pointer_adr, flatbuffers::hash_value_t hash) {
+        (void)pointer_adr;
+        (void)hash;
+        // Don't actually do anything, leave variable null.
+      });
+  auto rehasher = flatbuffers::rehasher_function_t(
+      [](void *pointer) -> flatbuffers::hash_value_t {
+        (void)pointer;
+        return 0;
+      });
+
+  // Turn a buffer into C++ objects.
+  auto monster1 = UnPackMonster(flatbuf, &resolver);
+
+  // Re-serialize the data.
+  flatbuffers::FlatBufferBuilder fbb1;
+  fbb1.Finish(CreateMonster(fbb1, monster1.get(), &rehasher),
+              MonsterIdentifier());
+
+  // Unpack again, and re-serialize again.
+  auto monster2 = UnPackMonster(fbb1.GetBufferPointer(), &resolver);
+  flatbuffers::FlatBufferBuilder fbb2;
+  fbb2.Finish(CreateMonster(fbb2, monster2.get(), &rehasher),
+              MonsterIdentifier());
+
+  // Now we've gone full round-trip, the two buffers should match.
+  auto len1 = fbb1.GetSize();
+  auto len2 = fbb2.GetSize();
+  TEST_EQ(len1, len2);
+  TEST_EQ(memcmp(fbb1.GetBufferPointer(), fbb2.GetBufferPointer(), len1), 0);
+
+  // Test it with the original buffer test to make sure all data survived.
+  AccessFlatBufferTest(fbb2.GetBufferPointer(), len2, false);
+
+  // Test accessing fields, similar to AccessFlatBufferTest above.
+  TEST_EQ(monster2->hp, 80);
+  TEST_EQ(monster2->mana, 150);  // default
+  TEST_EQ_STR(monster2->name.c_str(), "MyMonster");
+
+  auto &pos = monster2->pos;
+  TEST_NOTNULL(pos);
+  TEST_EQ(pos->z(), 3);
+  TEST_EQ(pos->test3().a(), 10);
+  TEST_EQ(pos->test3().b(), 20);
+
+  auto &inventory = monster2->inventory;
+  TEST_EQ(inventory.size(), 10UL);
+  unsigned char inv_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+  for (auto it = inventory.begin(); it != inventory.end(); ++it)
+    TEST_EQ(*it, inv_data[it - inventory.begin()]);
+
+  TEST_EQ(monster2->color, Color_Blue);
+
+  auto monster3 = monster2->test.AsMonster();
+  TEST_NOTNULL(monster3);
+  TEST_EQ_STR(monster3->name.c_str(), "Fred");
+
+  auto &vecofstrings = monster2->testarrayofstring;
+  TEST_EQ(vecofstrings.size(), 4U);
+  TEST_EQ_STR(vecofstrings[0].c_str(), "bob");
+  TEST_EQ_STR(vecofstrings[1].c_str(), "fred");
+
+  auto &vecofstrings2 = monster2->testarrayofstring2;
+  TEST_EQ(vecofstrings2.size(), 2U);
+  TEST_EQ_STR(vecofstrings2[0].c_str(), "jane");
+  TEST_EQ_STR(vecofstrings2[1].c_str(), "mary");
+
+  auto &vecoftables = monster2->testarrayoftables;
+  TEST_EQ(vecoftables.size(), 3U);
+  TEST_EQ_STR(vecoftables[0]->name.c_str(), "Barney");
+  TEST_EQ(vecoftables[0]->hp, 1000);
+  TEST_EQ_STR(vecoftables[1]->name.c_str(), "Fred");
+  TEST_EQ_STR(vecoftables[2]->name.c_str(), "Wilma");
+
+  auto &tests = monster2->test4;
+  TEST_EQ(tests[0].a(), 10);
+  TEST_EQ(tests[0].b(), 20);
+  TEST_EQ(tests[1].a(), 30);
+  TEST_EQ(tests[1].b(), 40);
+}
+
+// Prefix a FlatBuffer with a size field.
+void SizePrefixedTest() {
+  // Create size prefixed buffer.
+  flatbuffers::FlatBufferBuilder fbb;
+  FinishSizePrefixedMonsterBuffer(
+      fbb,
+      CreateMonster(fbb, 0, 200, 300, fbb.CreateString("bob")));
+
+  // Verify it.
+  flatbuffers::Verifier verifier(fbb.GetBufferPointer(), fbb.GetSize());
+  TEST_EQ(VerifySizePrefixedMonsterBuffer(verifier), true);
+
+  // Access it.
+  auto m = GetSizePrefixedMonster(fbb.GetBufferPointer());
+  TEST_EQ(m->mana(), 200);
+  TEST_EQ(m->hp(), 300);
+  TEST_EQ_STR(m->name()->c_str(), "bob");
+}
+
+void TriviallyCopyableTest() {
+  // clang-format off
+  #if __GNUG__ && __GNUC__ < 5
+    TEST_EQ(__has_trivial_copy(Vec3), true);
+  #else
+    #if __cplusplus >= 201103L
+      TEST_EQ(std::is_trivially_copyable<Vec3>::value, true);
+    #endif
+  #endif
+  // clang-format on
+}
+
+// Check stringify of an default enum value to json
+void JsonDefaultTest() {
+  // load FlatBuffer schema (.fbs) from disk
+  std::string schemafile;
+  TEST_EQ(flatbuffers::LoadFile((test_data_path + "monster_test.fbs").c_str(),
+                                false, &schemafile), true);
+  // parse schema first, so we can use it to parse the data after
+  flatbuffers::Parser parser;
+  auto include_test_path =
+      flatbuffers::ConCatPathFileName(test_data_path, "include_test");
+  const char *include_directories[] = { test_data_path.c_str(),
+                                        include_test_path.c_str(), nullptr };
+
+  TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
+  // create incomplete monster and store to json
+  parser.opts.output_default_scalars_in_json = true;
+  parser.opts.output_enum_identifiers = true;
+  flatbuffers::FlatBufferBuilder builder;
+  auto name = builder.CreateString("default_enum");
+  MonsterBuilder color_monster(builder);
+  color_monster.add_name(name);
+  FinishMonsterBuffer(builder, color_monster.Finish());
+  std::string jsongen;
+  auto result = GenerateText(parser, builder.GetBufferPointer(), &jsongen);
+  TEST_EQ(result, true);
+  // default value of the "color" field is Blue
+  TEST_EQ(std::string::npos != jsongen.find("color: \"Blue\""), true);
+  // default value of the "testf" field is 3.14159
+  TEST_EQ(std::string::npos != jsongen.find("testf: 3.14159"), true);
+}
+
+void JsonEnumsTest() {
+  // load FlatBuffer schema (.fbs) from disk
+  std::string schemafile;
+  TEST_EQ(flatbuffers::LoadFile((test_data_path + "monster_test.fbs").c_str(),
+                                false, &schemafile),
+          true);
+  // parse schema first, so we can use it to parse the data after
+  flatbuffers::Parser parser;
+  auto include_test_path =
+      flatbuffers::ConCatPathFileName(test_data_path, "include_test");
+  const char *include_directories[] = { test_data_path.c_str(),
+                                        include_test_path.c_str(), nullptr };
+  parser.opts.output_enum_identifiers = true;
+  TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
+  flatbuffers::FlatBufferBuilder builder;
+  auto name = builder.CreateString("bitflag_enum");
+  MonsterBuilder color_monster(builder);
+  color_monster.add_name(name);
+  color_monster.add_color(Color(Color_Blue | Color_Red));
+  FinishMonsterBuffer(builder, color_monster.Finish());
+  std::string jsongen;
+  auto result = GenerateText(parser, builder.GetBufferPointer(), &jsongen);
+  TEST_EQ(result, true);
+  TEST_EQ(std::string::npos != jsongen.find("color: \"Red Blue\""), true);
+}
+
+#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
+// The IEEE-754 quiet_NaN is not simple binary constant.
+// All binary NaN bit strings have all the bits of the biased exponent field E
+// set to 1. A quiet NaN bit string should be encoded with the first bit d[1]
+// of the trailing significand field T being 1 (d[0] is implicit bit).
+// It is assumed that endianness of floating-point is same as integer.
+template<typename T, typename U, U qnan_base> bool is_quiet_nan_impl(T v) {
+  static_assert(sizeof(T) == sizeof(U), "unexpected");
+  U b = 0;
+  std::memcpy(&b, &v, sizeof(T));
+  return ((b & qnan_base) == qnan_base);
+}
+static bool is_quiet_nan(float v) {
+  return is_quiet_nan_impl<float, uint32_t, 0x7FC00000u>(v);
+}
+static bool is_quiet_nan(double v) {
+  return is_quiet_nan_impl<double, uint64_t, 0x7FF8000000000000ul>(v);
+}
+
+void TestMonsterExtraFloats() {
+  TEST_EQ(is_quiet_nan(1.0), false);
+  TEST_EQ(is_quiet_nan(infinityd), false);
+  TEST_EQ(is_quiet_nan(-infinityf), false);
+  TEST_EQ(is_quiet_nan(std::numeric_limits<float>::quiet_NaN()), true);
+  TEST_EQ(is_quiet_nan(std::numeric_limits<double>::quiet_NaN()), true);
+
+  using namespace flatbuffers;
+  using namespace MyGame;
+  // Load FlatBuffer schema (.fbs) from disk.
+  std::string schemafile;
+  TEST_EQ(LoadFile((test_data_path + "monster_extra.fbs").c_str(), false,
+                   &schemafile),
+          true);
+  // Parse schema first, so we can use it to parse the data after.
+  Parser parser;
+  auto include_test_path = ConCatPathFileName(test_data_path, "include_test");
+  const char *include_directories[] = { test_data_path.c_str(),
+                                        include_test_path.c_str(), nullptr };
+  TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
+  // Create empty extra and store to json.
+  parser.opts.output_default_scalars_in_json = true;
+  parser.opts.output_enum_identifiers = true;
+  FlatBufferBuilder builder;
+  const auto def_root = MonsterExtraBuilder(builder).Finish();
+  FinishMonsterExtraBuffer(builder, def_root);
+  const auto def_obj = builder.GetBufferPointer();
+  const auto def_extra = GetMonsterExtra(def_obj);
+  TEST_NOTNULL(def_extra);
+  TEST_EQ(is_quiet_nan(def_extra->f0()), true);
+  TEST_EQ(is_quiet_nan(def_extra->f1()), true);
+  TEST_EQ(def_extra->f2(), +infinityf);
+  TEST_EQ(def_extra->f3(), -infinityf);
+  TEST_EQ(is_quiet_nan(def_extra->d0()), true);
+  TEST_EQ(is_quiet_nan(def_extra->d1()), true);
+  TEST_EQ(def_extra->d2(), +infinityd);
+  TEST_EQ(def_extra->d3(), -infinityd);
+  std::string jsongen;
+  auto result = GenerateText(parser, def_obj, &jsongen);
+  TEST_EQ(result, true);
+  // Check expected default values.
+  TEST_EQ(std::string::npos != jsongen.find("f0: nan"), true);
+  TEST_EQ(std::string::npos != jsongen.find("f1: nan"), true);
+  TEST_EQ(std::string::npos != jsongen.find("f2: inf"), true);
+  TEST_EQ(std::string::npos != jsongen.find("f3: -inf"), true);
+  TEST_EQ(std::string::npos != jsongen.find("d0: nan"), true);
+  TEST_EQ(std::string::npos != jsongen.find("d1: nan"), true);
+  TEST_EQ(std::string::npos != jsongen.find("d2: inf"), true);
+  TEST_EQ(std::string::npos != jsongen.find("d3: -inf"), true);
+  // Parse 'mosterdata_extra.json'.
+  const auto extra_base = test_data_path + "monsterdata_extra";
+  jsongen = "";
+  TEST_EQ(LoadFile((extra_base + ".json").c_str(), false, &jsongen), true);
+  TEST_EQ(parser.Parse(jsongen.c_str()), true);
+  const auto test_file = parser.builder_.GetBufferPointer();
+  const auto test_size = parser.builder_.GetSize();
+  Verifier verifier(test_file, test_size);
+  TEST_ASSERT(VerifyMonsterExtraBuffer(verifier));
+  const auto extra = GetMonsterExtra(test_file);
+  TEST_NOTNULL(extra);
+  TEST_EQ(is_quiet_nan(extra->f0()), true);
+  TEST_EQ(is_quiet_nan(extra->f1()), true);
+  TEST_EQ(extra->f2(), +infinityf);
+  TEST_EQ(extra->f3(), -infinityf);
+  TEST_EQ(is_quiet_nan(extra->d0()), true);
+  TEST_EQ(extra->d1(), +infinityd);
+  TEST_EQ(extra->d2(), -infinityd);
+  TEST_EQ(is_quiet_nan(extra->d3()), true);
+  TEST_NOTNULL(extra->fvec());
+  TEST_EQ(extra->fvec()->size(), 4);
+  TEST_EQ(extra->fvec()->Get(0), 1.0f);
+  TEST_EQ(extra->fvec()->Get(1), -infinityf);
+  TEST_EQ(extra->fvec()->Get(2), +infinityf);
+  TEST_EQ(is_quiet_nan(extra->fvec()->Get(3)), true);
+  TEST_NOTNULL(extra->dvec());
+  TEST_EQ(extra->dvec()->size(), 4);
+  TEST_EQ(extra->dvec()->Get(0), 2.0);
+  TEST_EQ(extra->dvec()->Get(1), +infinityd);
+  TEST_EQ(extra->dvec()->Get(2), -infinityd);
+  TEST_EQ(is_quiet_nan(extra->dvec()->Get(3)), true);
+}
+#else
+void TestMonsterExtraFloats() {}
+#endif
+
+// example of parsing text straight into a buffer, and generating
+// text back from it:
+void ParseAndGenerateTextTest(bool binary) {
+  // load FlatBuffer schema (.fbs) and JSON from disk
+  std::string schemafile;
+  std::string jsonfile;
+  TEST_EQ(flatbuffers::LoadFile(
+              (test_data_path + "monster_test." + (binary ? "bfbs" : "fbs"))
+                  .c_str(),
+              binary, &schemafile),
+          true);
+  TEST_EQ(flatbuffers::LoadFile(
+              (test_data_path + "monsterdata_test.golden").c_str(), false,
+              &jsonfile),
+          true);
+
+  auto include_test_path =
+    flatbuffers::ConCatPathFileName(test_data_path, "include_test");
+  const char *include_directories[] = { test_data_path.c_str(),
+                                        include_test_path.c_str(), nullptr };
+
+  // parse schema first, so we can use it to parse the data after
+  flatbuffers::Parser parser;
+  if (binary) {
+    flatbuffers::Verifier verifier(
+        reinterpret_cast<const uint8_t *>(schemafile.c_str()),
+        schemafile.size());
+    TEST_EQ(reflection::VerifySchemaBuffer(verifier), true);
+    //auto schema = reflection::GetSchema(schemafile.c_str());
+    TEST_EQ(parser.Deserialize((const uint8_t *)schemafile.c_str(), schemafile.size()), true);
+  } else {
+    TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
+  }
+  TEST_EQ(parser.Parse(jsonfile.c_str(), include_directories), true);
+
+  // here, parser.builder_ contains a binary buffer that is the parsed data.
+
+  // First, verify it, just in case:
+  flatbuffers::Verifier verifier(parser.builder_.GetBufferPointer(),
+                                 parser.builder_.GetSize());
+  TEST_EQ(VerifyMonsterBuffer(verifier), true);
+
+  AccessFlatBufferTest(parser.builder_.GetBufferPointer(),
+                       parser.builder_.GetSize(), false);
+
+  // to ensure it is correct, we now generate text back from the binary,
+  // and compare the two:
+  std::string jsongen;
+  auto result =
+      GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
+  TEST_EQ(result, true);
+  TEST_EQ_STR(jsongen.c_str(), jsonfile.c_str());
+
+  // We can also do the above using the convenient Registry that knows about
+  // a set of file_identifiers mapped to schemas.
+  flatbuffers::Registry registry;
+  // Make sure schemas can find their includes.
+  registry.AddIncludeDirectory(test_data_path.c_str());
+  registry.AddIncludeDirectory(include_test_path.c_str());
+  // Call this with many schemas if possible.
+  registry.Register(MonsterIdentifier(),
+                    (test_data_path + "monster_test.fbs").c_str());
+  // Now we got this set up, we can parse by just specifying the identifier,
+  // the correct schema will be loaded on the fly:
+  auto buf = registry.TextToFlatBuffer(jsonfile.c_str(), MonsterIdentifier());
+  // If this fails, check registry.lasterror_.
+  TEST_NOTNULL(buf.data());
+  // Test the buffer, to be sure:
+  AccessFlatBufferTest(buf.data(), buf.size(), false);
+  // We can use the registry to turn this back into text, in this case it
+  // will get the file_identifier from the binary:
+  std::string text;
+  auto ok = registry.FlatBufferToText(buf.data(), buf.size(), &text);
+  // If this fails, check registry.lasterror_.
+  TEST_EQ(ok, true);
+  TEST_EQ_STR(text.c_str(), jsonfile.c_str());
+
+  // Generate text for UTF-8 strings without escapes.
+  std::string jsonfile_utf8;
+  TEST_EQ(flatbuffers::LoadFile((test_data_path + "unicode_test.json").c_str(),
+                                false, &jsonfile_utf8),
+          true);
+  TEST_EQ(parser.Parse(jsonfile_utf8.c_str(), include_directories), true);
+  // To ensure it is correct, generate utf-8 text back from the binary.
+  std::string jsongen_utf8;
+  // request natural printing for utf-8 strings
+  parser.opts.natural_utf8 = true;
+  parser.opts.strict_json = true;
+  TEST_EQ(
+      GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen_utf8),
+      true);
+  TEST_EQ_STR(jsongen_utf8.c_str(), jsonfile_utf8.c_str());
+}
+
+void ReflectionTest(uint8_t *flatbuf, size_t length) {
+  // Load a binary schema.
+  std::string bfbsfile;
+  TEST_EQ(flatbuffers::LoadFile((test_data_path + "monster_test.bfbs").c_str(),
+                                true, &bfbsfile),
+          true);
+
+  // Verify it, just in case:
+  flatbuffers::Verifier verifier(
+      reinterpret_cast<const uint8_t *>(bfbsfile.c_str()), bfbsfile.length());
+  TEST_EQ(reflection::VerifySchemaBuffer(verifier), true);
+
+  // Make sure the schema is what we expect it to be.
+  auto &schema = *reflection::GetSchema(bfbsfile.c_str());
+  auto root_table = schema.root_table();
+  TEST_EQ_STR(root_table->name()->c_str(), "MyGame.Example.Monster");
+  auto fields = root_table->fields();
+  auto hp_field_ptr = fields->LookupByKey("hp");
+  TEST_NOTNULL(hp_field_ptr);
+  auto &hp_field = *hp_field_ptr;
+  TEST_EQ_STR(hp_field.name()->c_str(), "hp");
+  TEST_EQ(hp_field.id(), 2);
+  TEST_EQ(hp_field.type()->base_type(), reflection::Short);
+  auto friendly_field_ptr = fields->LookupByKey("friendly");
+  TEST_NOTNULL(friendly_field_ptr);
+  TEST_NOTNULL(friendly_field_ptr->attributes());
+  TEST_NOTNULL(friendly_field_ptr->attributes()->LookupByKey("priority"));
+
+  // Make sure the table index is what we expect it to be.
+  auto pos_field_ptr = fields->LookupByKey("pos");
+  TEST_NOTNULL(pos_field_ptr);
+  TEST_EQ(pos_field_ptr->type()->base_type(), reflection::Obj);
+  auto pos_table_ptr = schema.objects()->Get(pos_field_ptr->type()->index());
+  TEST_NOTNULL(pos_table_ptr);
+  TEST_EQ_STR(pos_table_ptr->name()->c_str(), "MyGame.Example.Vec3");
+
+  // Now use it to dynamically access a buffer.
+  auto &root = *flatbuffers::GetAnyRoot(flatbuf);
+
+  // Verify the buffer first using reflection based verification
+  TEST_EQ(flatbuffers::Verify(schema, *schema.root_table(), flatbuf, length),
+          true);
+
+  auto hp = flatbuffers::GetFieldI<uint16_t>(root, hp_field);
+  TEST_EQ(hp, 80);
+
+  // Rather than needing to know the type, we can also get the value of
+  // any field as an int64_t/double/string, regardless of what it actually is.
+  auto hp_int64 = flatbuffers::GetAnyFieldI(root, hp_field);
+  TEST_EQ(hp_int64, 80);
+  auto hp_double = flatbuffers::GetAnyFieldF(root, hp_field);
+  TEST_EQ(hp_double, 80.0);
+  auto hp_string = flatbuffers::GetAnyFieldS(root, hp_field, &schema);
+  TEST_EQ_STR(hp_string.c_str(), "80");
+
+  // Get struct field through reflection
+  auto pos_struct = flatbuffers::GetFieldStruct(root, *pos_field_ptr);
+  TEST_NOTNULL(pos_struct);
+  TEST_EQ(flatbuffers::GetAnyFieldF(*pos_struct,
+                                    *pos_table_ptr->fields()->LookupByKey("z")),
+          3.0f);
+
+  auto test3_field = pos_table_ptr->fields()->LookupByKey("test3");
+  auto test3_struct = flatbuffers::GetFieldStruct(*pos_struct, *test3_field);
+  TEST_NOTNULL(test3_struct);
+  auto test3_object = schema.objects()->Get(test3_field->type()->index());
+
+  TEST_EQ(flatbuffers::GetAnyFieldF(*test3_struct,
+                                    *test3_object->fields()->LookupByKey("a")),
+          10);
+
+  // We can also modify it.
+  flatbuffers::SetField<uint16_t>(&root, hp_field, 200);
+  hp = flatbuffers::GetFieldI<uint16_t>(root, hp_field);
+  TEST_EQ(hp, 200);
+
+  // We can also set fields generically:
+  flatbuffers::SetAnyFieldI(&root, hp_field, 300);
+  hp_int64 = flatbuffers::GetAnyFieldI(root, hp_field);
+  TEST_EQ(hp_int64, 300);
+  flatbuffers::SetAnyFieldF(&root, hp_field, 300.5);
+  hp_int64 = flatbuffers::GetAnyFieldI(root, hp_field);
+  TEST_EQ(hp_int64, 300);
+  flatbuffers::SetAnyFieldS(&root, hp_field, "300");
+  hp_int64 = flatbuffers::GetAnyFieldI(root, hp_field);
+  TEST_EQ(hp_int64, 300);
+
+  // Test buffer is valid after the modifications
+  TEST_EQ(flatbuffers::Verify(schema, *schema.root_table(), flatbuf, length),
+          true);
+
+  // Reset it, for further tests.
+  flatbuffers::SetField<uint16_t>(&root, hp_field, 80);
+
+  // More advanced functionality: changing the size of items in-line!
+  // First we put the FlatBuffer inside an std::vector.
+  std::vector<uint8_t> resizingbuf(flatbuf, flatbuf + length);
+  // Find the field we want to modify.
+  auto &name_field = *fields->LookupByKey("name");
+  // Get the root.
+  // This time we wrap the result from GetAnyRoot in a smartpointer that
+  // will keep rroot valid as resizingbuf resizes.
+  auto rroot = flatbuffers::piv(
+      flatbuffers::GetAnyRoot(flatbuffers::vector_data(resizingbuf)),
+      resizingbuf);
+  SetString(schema, "totally new string", GetFieldS(**rroot, name_field),
+            &resizingbuf);
+  // Here resizingbuf has changed, but rroot is still valid.
+  TEST_EQ_STR(GetFieldS(**rroot, name_field)->c_str(), "totally new string");
+  // Now lets extend a vector by 100 elements (10 -> 110).
+  auto &inventory_field = *fields->LookupByKey("inventory");
+  auto rinventory = flatbuffers::piv(
+      flatbuffers::GetFieldV<uint8_t>(**rroot, inventory_field), resizingbuf);
+  flatbuffers::ResizeVector<uint8_t>(schema, 110, 50, *rinventory,
+                                     &resizingbuf);
+  // rinventory still valid, so lets read from it.
+  TEST_EQ(rinventory->Get(10), 50);
+
+  // For reflection uses not covered already, there is a more powerful way:
+  // we can simply generate whatever object we want to add/modify in a
+  // FlatBuffer of its own, then add that to an existing FlatBuffer:
+  // As an example, let's add a string to an array of strings.
+  // First, find our field:
+  auto &testarrayofstring_field = *fields->LookupByKey("testarrayofstring");
+  // Find the vector value:
+  auto rtestarrayofstring = flatbuffers::piv(
+      flatbuffers::GetFieldV<flatbuffers::Offset<flatbuffers::String>>(
+          **rroot, testarrayofstring_field),
+      resizingbuf);
+  // It's a vector of 2 strings, to which we add one more, initialized to
+  // offset 0.
+  flatbuffers::ResizeVector<flatbuffers::Offset<flatbuffers::String>>(
+      schema, 3, 0, *rtestarrayofstring, &resizingbuf);
+  // Here we just create a buffer that contans a single string, but this
+  // could also be any complex set of tables and other values.
+  flatbuffers::FlatBufferBuilder stringfbb;
+  stringfbb.Finish(stringfbb.CreateString("hank"));
+  // Add the contents of it to our existing FlatBuffer.
+  // We do this last, so the pointer doesn't get invalidated (since it is
+  // at the end of the buffer):
+  auto string_ptr = flatbuffers::AddFlatBuffer(
+      resizingbuf, stringfbb.GetBufferPointer(), stringfbb.GetSize());
+  // Finally, set the new value in the vector.
+  rtestarrayofstring->MutateOffset(2, string_ptr);
+  TEST_EQ_STR(rtestarrayofstring->Get(0)->c_str(), "bob");
+  TEST_EQ_STR(rtestarrayofstring->Get(2)->c_str(), "hank");
+  // Test integrity of all resize operations above.
+  flatbuffers::Verifier resize_verifier(
+      reinterpret_cast<const uint8_t *>(flatbuffers::vector_data(resizingbuf)),
+      resizingbuf.size());
+  TEST_EQ(VerifyMonsterBuffer(resize_verifier), true);
+
+  // Test buffer is valid using reflection as well
+  TEST_EQ(flatbuffers::Verify(schema, *schema.root_table(),
+                              flatbuffers::vector_data(resizingbuf),
+                              resizingbuf.size()),
+          true);
+
+  // As an additional test, also set it on the name field.
+  // Note: unlike the name change above, this just overwrites the offset,
+  // rather than changing the string in-place.
+  SetFieldT(*rroot, name_field, string_ptr);
+  TEST_EQ_STR(GetFieldS(**rroot, name_field)->c_str(), "hank");
+
+  // Using reflection, rather than mutating binary FlatBuffers, we can also copy
+  // tables and other things out of other FlatBuffers into a FlatBufferBuilder,
+  // either part or whole.
+  flatbuffers::FlatBufferBuilder fbb;
+  auto root_offset = flatbuffers::CopyTable(
+      fbb, schema, *root_table, *flatbuffers::GetAnyRoot(flatbuf), true);
+  fbb.Finish(root_offset, MonsterIdentifier());
+  // Test that it was copied correctly:
+  AccessFlatBufferTest(fbb.GetBufferPointer(), fbb.GetSize());
+
+  // Test buffer is valid using reflection as well
+  TEST_EQ(flatbuffers::Verify(schema, *schema.root_table(),
+                              fbb.GetBufferPointer(), fbb.GetSize()),
+          true);
+}
+
+void MiniReflectFlatBuffersTest(uint8_t *flatbuf) {
+  auto s = flatbuffers::FlatBufferToString(flatbuf, Monster::MiniReflectTypeTable());
+  TEST_EQ_STR(
+      s.c_str(),
+      "{ "
+      "pos: { x: 1.0, y: 2.0, z: 3.0, test1: 0.0, test2: Red, test3: "
+      "{ a: 10, b: 20 } }, "
+      "hp: 80, "
+      "name: \"MyMonster\", "
+      "inventory: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], "
+      "test_type: Monster, "
+      "test: { name: \"Fred\" }, "
+      "test4: [ { a: 10, b: 20 }, { a: 30, b: 40 } ], "
+      "testarrayofstring: [ \"bob\", \"fred\", \"bob\", \"fred\" ], "
+      "testarrayoftables: [ { hp: 1000, name: \"Barney\" }, { name: \"Fred\" "
+      "}, "
+      "{ name: \"Wilma\" } ], "
+      // TODO(wvo): should really print this nested buffer correctly.
+      "testnestedflatbuffer: [ 20, 0, 0, 0, 77, 79, 78, 83, 12, 0, 12, 0, 0, "
+      "0, "
+      "4, 0, 6, 0, 8, 0, 12, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 13, 0, 0, 0, 78, "
+      "101, 115, 116, 101, 100, 77, 111, 110, 115, 116, 101, 114, 0, 0, 0 ], "
+      "testarrayofstring2: [ \"jane\", \"mary\" ], "
+      "testarrayofsortedstruct: [ { id: 1, distance: 10 }, "
+      "{ id: 2, distance: 20 }, { id: 3, distance: 30 }, "
+      "{ id: 4, distance: 40 } ], "
+      "flex: [ 210, 4, 5, 2 ], "
+      "test5: [ { a: 10, b: 20 }, { a: 30, b: 40 } ], "
+      "vector_of_enums: [ Blue, Green ] "
+      "}");
+
+  Test test(16, 32);
+  Vec3 vec(1,2,3, 1.5, Color_Red, test);
+  flatbuffers::FlatBufferBuilder vec_builder;
+  vec_builder.Finish(vec_builder.CreateStruct(vec));
+  auto vec_buffer = vec_builder.Release();
+  auto vec_str = flatbuffers::FlatBufferToString(vec_buffer.data(),
+                                                 Vec3::MiniReflectTypeTable());
+  TEST_EQ_STR(
+      vec_str.c_str(),
+      "{ x: 1.0, y: 2.0, z: 3.0, test1: 1.5, test2: Red, test3: { a: 16, b: 32 } }");
+}
+
+// Parse a .proto schema, output as .fbs
+void ParseProtoTest() {
+  // load the .proto and the golden file from disk
+  std::string protofile;
+  std::string goldenfile;
+  std::string goldenunionfile;
+  TEST_EQ(
+      flatbuffers::LoadFile((test_data_path + "prototest/test.proto").c_str(),
+                            false, &protofile),
+      true);
+  TEST_EQ(
+      flatbuffers::LoadFile((test_data_path + "prototest/test.golden").c_str(),
+                            false, &goldenfile),
+      true);
+  TEST_EQ(
+      flatbuffers::LoadFile((test_data_path +
+                            "prototest/test_union.golden").c_str(),
+                            false, &goldenunionfile),
+      true);
+
+  flatbuffers::IDLOptions opts;
+  opts.include_dependence_headers = false;
+  opts.proto_mode = true;
+
+  // Parse proto.
+  flatbuffers::Parser parser(opts);
+  auto protopath = test_data_path + "prototest/";
+  const char *include_directories[] = { protopath.c_str(), nullptr };
+  TEST_EQ(parser.Parse(protofile.c_str(), include_directories), true);
+
+  // Generate fbs.
+  auto fbs = flatbuffers::GenerateFBS(parser, "test");
+
+  // Ensure generated file is parsable.
+  flatbuffers::Parser parser2;
+  TEST_EQ(parser2.Parse(fbs.c_str(), nullptr), true);
+  TEST_EQ_STR(fbs.c_str(), goldenfile.c_str());
+
+  // Parse proto with --oneof-union option.
+  opts.proto_oneof_union = true;
+  flatbuffers::Parser parser3(opts);
+  TEST_EQ(parser3.Parse(protofile.c_str(), include_directories), true);
+
+  // Generate fbs.
+  auto fbs_union = flatbuffers::GenerateFBS(parser3, "test");
+
+  // Ensure generated file is parsable.
+  flatbuffers::Parser parser4;
+  TEST_EQ(parser4.Parse(fbs_union.c_str(), nullptr), true);
+  TEST_EQ_STR(fbs_union.c_str(), goldenunionfile.c_str());
+}
+
+template<typename T>
+void CompareTableFieldValue(flatbuffers::Table *table,
+                            flatbuffers::voffset_t voffset, T val) {
+  T read = table->GetField(voffset, static_cast<T>(0));
+  TEST_EQ(read, val);
+}
+
+// Low level stress/fuzz test: serialize/deserialize a variety of
+// different kinds of data in different combinations
+void FuzzTest1() {
+  // Values we're testing against: chosen to ensure no bits get chopped
+  // off anywhere, and also be different from eachother.
+  const uint8_t bool_val = true;
+  const int8_t char_val = -127;  // 0x81
+  const uint8_t uchar_val = 0xFF;
+  const int16_t short_val = -32222;  // 0x8222;
+  const uint16_t ushort_val = 0xFEEE;
+  const int32_t int_val = 0x83333333;
+  const uint32_t uint_val = 0xFDDDDDDD;
+  const int64_t long_val = 0x8444444444444444LL;
+  const uint64_t ulong_val = 0xFCCCCCCCCCCCCCCCULL;
+  const float float_val = 3.14159f;
+  const double double_val = 3.14159265359;
+
+  const int test_values_max = 11;
+  const flatbuffers::voffset_t fields_per_object = 4;
+  const int num_fuzz_objects = 10000;  // The higher, the more thorough :)
+
+  flatbuffers::FlatBufferBuilder builder;
+
+  lcg_reset();  // Keep it deterministic.
+
+  flatbuffers::uoffset_t objects[num_fuzz_objects];
+
+  // Generate num_fuzz_objects random objects each consisting of
+  // fields_per_object fields, each of a random type.
+  for (int i = 0; i < num_fuzz_objects; i++) {
+    auto start = builder.StartTable();
+    for (flatbuffers::voffset_t f = 0; f < fields_per_object; f++) {
+      int choice = lcg_rand() % test_values_max;
+      auto off = flatbuffers::FieldIndexToOffset(f);
+      switch (choice) {
+        case 0: builder.AddElement<uint8_t>(off, bool_val, 0); break;
+        case 1: builder.AddElement<int8_t>(off, char_val, 0); break;
+        case 2: builder.AddElement<uint8_t>(off, uchar_val, 0); break;
+        case 3: builder.AddElement<int16_t>(off, short_val, 0); break;
+        case 4: builder.AddElement<uint16_t>(off, ushort_val, 0); break;
+        case 5: builder.AddElement<int32_t>(off, int_val, 0); break;
+        case 6: builder.AddElement<uint32_t>(off, uint_val, 0); break;
+        case 7: builder.AddElement<int64_t>(off, long_val, 0); break;
+        case 8: builder.AddElement<uint64_t>(off, ulong_val, 0); break;
+        case 9: builder.AddElement<float>(off, float_val, 0); break;
+        case 10: builder.AddElement<double>(off, double_val, 0); break;
+      }
+    }
+    objects[i] = builder.EndTable(start);
+  }
+  builder.PreAlign<flatbuffers::largest_scalar_t>(0);  // Align whole buffer.
+
+  lcg_reset();  // Reset.
+
+  uint8_t *eob = builder.GetCurrentBufferPointer() + builder.GetSize();
+
+  // Test that all objects we generated are readable and return the
+  // expected values. We generate random objects in the same order
+  // so this is deterministic.
+  for (int i = 0; i < num_fuzz_objects; i++) {
+    auto table = reinterpret_cast<flatbuffers::Table *>(eob - objects[i]);
+    for (flatbuffers::voffset_t f = 0; f < fields_per_object; f++) {
+      int choice = lcg_rand() % test_values_max;
+      flatbuffers::voffset_t off = flatbuffers::FieldIndexToOffset(f);
+      switch (choice) {
+        case 0: CompareTableFieldValue(table, off, bool_val); break;
+        case 1: CompareTableFieldValue(table, off, char_val); break;
+        case 2: CompareTableFieldValue(table, off, uchar_val); break;
+        case 3: CompareTableFieldValue(table, off, short_val); break;
+        case 4: CompareTableFieldValue(table, off, ushort_val); break;
+        case 5: CompareTableFieldValue(table, off, int_val); break;
+        case 6: CompareTableFieldValue(table, off, uint_val); break;
+        case 7: CompareTableFieldValue(table, off, long_val); break;
+        case 8: CompareTableFieldValue(table, off, ulong_val); break;
+        case 9: CompareTableFieldValue(table, off, float_val); break;
+        case 10: CompareTableFieldValue(table, off, double_val); break;
+      }
+    }
+  }
+}
+
+// High level stress/fuzz test: generate a big schema and
+// matching json data in random combinations, then parse both,
+// generate json back from the binary, and compare with the original.
+void FuzzTest2() {
+  lcg_reset();  // Keep it deterministic.
+
+  const int num_definitions = 30;
+  const int num_struct_definitions = 5;  // Subset of num_definitions.
+  const int fields_per_definition = 15;
+  const int instances_per_definition = 5;
+  const int deprecation_rate = 10;  // 1 in deprecation_rate fields will
+                                    // be deprecated.
+
+  std::string schema = "namespace test;\n\n";
+
+  struct RndDef {
+    std::string instances[instances_per_definition];
+
+    // Since we're generating schema and corresponding data in tandem,
+    // this convenience function adds strings to both at once.
+    static void Add(RndDef (&definitions_l)[num_definitions],
+                    std::string &schema_l, const int instances_per_definition_l,
+                    const char *schema_add, const char *instance_add,
+                    int definition) {
+      schema_l += schema_add;
+      for (int i = 0; i < instances_per_definition_l; i++)
+        definitions_l[definition].instances[i] += instance_add;
+    }
+  };
+
+  // clang-format off
+  #define AddToSchemaAndInstances(schema_add, instance_add) \
+    RndDef::Add(definitions, schema, instances_per_definition, \
+                schema_add, instance_add, definition)
+
+  #define Dummy() \
+    RndDef::Add(definitions, schema, instances_per_definition, \
+                "byte", "1", definition)
+  // clang-format on
+
+  RndDef definitions[num_definitions];
+
+  // We are going to generate num_definitions, the first
+  // num_struct_definitions will be structs, the rest tables. For each
+  // generate random fields, some of which may be struct/table types
+  // referring to previously generated structs/tables.
+  // Simultanenously, we generate instances_per_definition JSON data
+  // definitions, which will have identical structure to the schema
+  // being generated. We generate multiple instances such that when creating
+  // hierarchy, we get some variety by picking one randomly.
+  for (int definition = 0; definition < num_definitions; definition++) {
+    std::string definition_name = "D" + flatbuffers::NumToString(definition);
+
+    bool is_struct = definition < num_struct_definitions;
+
+    AddToSchemaAndInstances(
+        ((is_struct ? "struct " : "table ") + definition_name + " {\n").c_str(),
+        "{\n");
+
+    for (int field = 0; field < fields_per_definition; field++) {
+      const bool is_last_field = field == fields_per_definition - 1;
+
+      // Deprecate 1 in deprecation_rate fields. Only table fields can be
+      // deprecated.
+      // Don't deprecate the last field to avoid dangling commas in JSON.
+      const bool deprecated =
+          !is_struct && !is_last_field && (lcg_rand() % deprecation_rate == 0);
+
+      std::string field_name = "f" + flatbuffers::NumToString(field);
+      AddToSchemaAndInstances(("  " + field_name + ":").c_str(),
+                              deprecated ? "" : (field_name + ": ").c_str());
+      // Pick random type:
+      auto base_type = static_cast<flatbuffers::BaseType>(
+          lcg_rand() % (flatbuffers::BASE_TYPE_UNION + 1));
+      switch (base_type) {
+        case flatbuffers::BASE_TYPE_STRING:
+          if (is_struct) {
+            Dummy();  // No strings in structs.
+          } else {
+            AddToSchemaAndInstances("string", deprecated ? "" : "\"hi\"");
+          }
+          break;
+        case flatbuffers::BASE_TYPE_VECTOR:
+          if (is_struct) {
+            Dummy();  // No vectors in structs.
+          } else {
+            AddToSchemaAndInstances("[ubyte]",
+                                    deprecated ? "" : "[\n0,\n1,\n255\n]");
+          }
+          break;
+        case flatbuffers::BASE_TYPE_NONE:
+        case flatbuffers::BASE_TYPE_UTYPE:
+        case flatbuffers::BASE_TYPE_STRUCT:
+        case flatbuffers::BASE_TYPE_UNION:
+          if (definition) {
+            // Pick a random previous definition and random data instance of
+            // that definition.
+            int defref = lcg_rand() % definition;
+            int instance = lcg_rand() % instances_per_definition;
+            AddToSchemaAndInstances(
+                ("D" + flatbuffers::NumToString(defref)).c_str(),
+                deprecated ? ""
+                           : definitions[defref].instances[instance].c_str());
+          } else {
+            // If this is the first definition, we have no definition we can
+            // refer to.
+            Dummy();
+          }
+          break;
+        case flatbuffers::BASE_TYPE_BOOL:
+          AddToSchemaAndInstances(
+              "bool", deprecated ? "" : (lcg_rand() % 2 ? "true" : "false"));
+          break;
+        case flatbuffers::BASE_TYPE_ARRAY:
+          if (!is_struct) {
+            AddToSchemaAndInstances(
+                "ubyte",
+                deprecated ? "" : "255");  // No fixed-length arrays in tables.
+          } else {
+            AddToSchemaAndInstances("[int:3]", deprecated ? "" : "[\n,\n,\n]");
+          }
+          break;
+        default:
+          // All the scalar types.
+          schema += flatbuffers::kTypeNames[base_type];
+
+          if (!deprecated) {
+            // We want each instance to use its own random value.
+            for (int inst = 0; inst < instances_per_definition; inst++)
+              definitions[definition].instances[inst] +=
+                  flatbuffers::IsFloat(base_type)
+                      ? flatbuffers::NumToString<double>(lcg_rand() % 128)
+                            .c_str()
+                      : flatbuffers::NumToString<int>(lcg_rand() % 128).c_str();
+          }
+      }
+      AddToSchemaAndInstances(deprecated ? "(deprecated);\n" : ";\n",
+                              deprecated ? "" : is_last_field ? "\n" : ",\n");
+    }
+    AddToSchemaAndInstances("}\n\n", "}");
+  }
+
+  schema += "root_type D" + flatbuffers::NumToString(num_definitions - 1);
+  schema += ";\n";
+
+  flatbuffers::Parser parser;
+
+  // Will not compare against the original if we don't write defaults
+  parser.builder_.ForceDefaults(true);
+
+  // Parse the schema, parse the generated data, then generate text back
+  // from the binary and compare against the original.
+  TEST_EQ(parser.Parse(schema.c_str()), true);
+
+  const std::string &json =
+      definitions[num_definitions - 1].instances[0] + "\n";
+
+  TEST_EQ(parser.Parse(json.c_str()), true);
+
+  std::string jsongen;
+  parser.opts.indent_step = 0;
+  auto result =
+      GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
+  TEST_EQ(result, true);
+
+  if (jsongen != json) {
+    // These strings are larger than a megabyte, so we show the bytes around
+    // the first bytes that are different rather than the whole string.
+    size_t len = std::min(json.length(), jsongen.length());
+    for (size_t i = 0; i < len; i++) {
+      if (json[i] != jsongen[i]) {
+        i -= std::min(static_cast<size_t>(10), i);  // show some context;
+        size_t end = std::min(len, i + 20);
+        for (; i < end; i++)
+          TEST_OUTPUT_LINE("at %d: found \"%c\", expected \"%c\"\n",
+                           static_cast<int>(i), jsongen[i], json[i]);
+        break;
+      }
+    }
+    TEST_NOTNULL(NULL);
+  }
+
+  // clang-format off
+  #ifdef FLATBUFFERS_TEST_VERBOSE
+    TEST_OUTPUT_LINE("%dk schema tested with %dk of json\n",
+                     static_cast<int>(schema.length() / 1024),
+                     static_cast<int>(json.length() / 1024));
+  #endif
+  // clang-format on
+}
+
+// Test that parser errors are actually generated.
+void TestError_(const char *src, const char *error_substr, bool strict_json,
+                const char *file, int line, const char *func) {
+  flatbuffers::IDLOptions opts;
+  opts.strict_json = strict_json;
+  flatbuffers::Parser parser(opts);
+  if (parser.Parse(src)) {
+    TestFail("true", "false",
+             ("parser.Parse(\"" + std::string(src) + "\")").c_str(), file, line,
+             func);
+  } else if (!strstr(parser.error_.c_str(), error_substr)) {
+    TestFail(parser.error_.c_str(), error_substr,
+             ("parser.Parse(\"" + std::string(src) + "\")").c_str(), file, line,
+             func);
+  }
+}
+
+void TestError_(const char *src, const char *error_substr, const char *file,
+                int line, const char *func) {
+  TestError_(src, error_substr, false, file, line, func);
+}
+
+#ifdef _WIN32
+#  define TestError(src, ...) \
+    TestError_(src, __VA_ARGS__, __FILE__, __LINE__, __FUNCTION__)
+#else
+#  define TestError(src, ...) \
+    TestError_(src, __VA_ARGS__, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#endif
+
+// Test that parsing errors occur as we'd expect.
+// Also useful for coverage, making sure these paths are run.
+void ErrorTest() {
+  // In order they appear in idl_parser.cpp
+  TestError("table X { Y:byte; } root_type X; { Y: 999 }", "does not fit");
+  TestError("\"\0", "illegal");
+  TestError("\"\\q", "escape code");
+  TestError("table ///", "documentation");
+  TestError("@", "illegal");
+  TestError("table 1", "expecting");
+  TestError("table X { Y:[[int]]; }", "nested vector");
+  TestError("table X { Y:1; }", "illegal type");
+  TestError("table X { Y:int; Y:int; }", "field already");
+  TestError("table Y {} table X { Y:int; }", "same as table");
+  TestError("struct X { Y:string; }", "only scalar");
+  TestError("table X { Y:string = \"\"; }", "default values");
+  TestError("struct X { a:uint = 42; }", "default values");
+  TestError("enum Y:byte { Z = 1 } table X { y:Y; }", "not part of enum");
+  TestError("struct X { Y:int (deprecated); }", "deprecate");
+  TestError("union Z { X } table X { Y:Z; } root_type X; { Y: {}, A:1 }",
+            "missing type field");
+  TestError("union Z { X } table X { Y:Z; } root_type X; { Y_type: 99, Y: {",
+            "type id");
+  TestError("table X { Y:int; } root_type X; { Z:", "unknown field");
+  TestError("table X { Y:int; } root_type X; { Y:", "string constant", true);
+  TestError("table X { Y:int; } root_type X; { \"Y\":1, }", "string constant",
+            true);
+  TestError(
+      "struct X { Y:int; Z:int; } table W { V:X; } root_type W; "
+      "{ V:{ Y:1 } }",
+      "wrong number");
+  TestError("enum E:byte { A } table X { Y:E; } root_type X; { Y:U }",
+            "unknown enum value");
+  TestError("table X { Y:byte; } root_type X; { Y:; }", "starting");
+  TestError("enum X:byte { Y } enum X {", "enum already");
+  TestError("enum X:float {}", "underlying");
+  TestError("enum X:byte { Y, Y }", "value already");
+  TestError("enum X:byte { Y=2, Z=1 }", "ascending");
+  TestError("table X { Y:int; } table X {", "datatype already");
+  TestError("struct X (force_align: 7) { Y:int; }", "force_align");
+  TestError("struct X {}", "size 0");
+  TestError("{}", "no root");
+  TestError("table X { Y:byte; } root_type X; { Y:1 } { Y:1 }", "end of file");
+  TestError("table X { Y:byte; } root_type X; { Y:1 } table Y{ Z:int }",
+            "end of file");
+  TestError("root_type X;", "unknown root");
+  TestError("struct X { Y:int; } root_type X;", "a table");
+  TestError("union X { Y }", "referenced");
+  TestError("union Z { X } struct X { Y:int; }", "only tables");
+  TestError("table X { Y:[int]; YLength:int; }", "clash");
+  TestError("table X { Y:byte; } root_type X; { Y:1, Y:2 }", "more than once");
+  // float to integer conversion is forbidden
+  TestError("table X { Y:int; } root_type X; { Y:1.0 }", "float");
+  TestError("table X { Y:bool; } root_type X; { Y:1.0 }", "float");
+  TestError("enum X:bool { Y = true }", "must be integral");
+}
+
+template<typename T>
+T TestValue(const char *json, const char *type_name,
+            const char *decls = nullptr) {
+  flatbuffers::Parser parser;
+  parser.builder_.ForceDefaults(true);  // return defaults
+  auto check_default = json ? false : true;
+  if (check_default) { parser.opts.output_default_scalars_in_json = true; }
+  // Simple schema.
+  std::string schema = std::string(decls ? decls : "") + "\n" +
+                       "table X { Y:" + std::string(type_name) +
+                       "; } root_type X;";
+  auto schema_done = parser.Parse(schema.c_str());
+  TEST_EQ_STR(parser.error_.c_str(), "");
+  TEST_EQ(schema_done, true);
+
+  auto done = parser.Parse(check_default ? "{}" : json);
+  TEST_EQ_STR(parser.error_.c_str(), "");
+  TEST_EQ(done, true);
+
+  // Check with print.
+  std::string print_back;
+  parser.opts.indent_step = -1;
+  TEST_EQ(GenerateText(parser, parser.builder_.GetBufferPointer(), &print_back),
+          true);
+  // restore value from its default
+  if (check_default) { TEST_EQ(parser.Parse(print_back.c_str()), true); }
+
+  auto root = flatbuffers::GetRoot<flatbuffers::Table>(
+      parser.builder_.GetBufferPointer());
+  return root->GetField<T>(flatbuffers::FieldIndexToOffset(0), 0);
+}
+
+bool FloatCompare(float a, float b) { return fabs(a - b) < 0.001; }
+
+// Additional parser testing not covered elsewhere.
+void ValueTest() {
+  // Test scientific notation numbers.
+  TEST_EQ(FloatCompare(TestValue<float>("{ Y:0.0314159e+2 }", "float"),
+                       3.14159f),
+          true);
+  // number in string
+  TEST_EQ(FloatCompare(TestValue<float>("{ Y:\"0.0314159e+2\" }", "float"),
+                       3.14159f),
+          true);
+
+  // Test conversion functions.
+  TEST_EQ(FloatCompare(TestValue<float>("{ Y:cos(rad(180)) }", "float"), -1),
+          true);
+
+  // int embedded to string
+  TEST_EQ(TestValue<int>("{ Y:\"-876\" }", "int=-123"), -876);
+  TEST_EQ(TestValue<int>("{ Y:\"876\" }", "int=-123"), 876);
+
+  // Test negative hex constant.
+  TEST_EQ(TestValue<int>("{ Y:-0x8ea0 }", "int=-0x8ea0"), -36512);
+  TEST_EQ(TestValue<int>(nullptr, "int=-0x8ea0"), -36512);
+
+  // positive hex constant
+  TEST_EQ(TestValue<int>("{ Y:0x1abcdef }", "int=0x1"), 0x1abcdef);
+  // with optional '+' sign
+  TEST_EQ(TestValue<int>("{ Y:+0x1abcdef }", "int=+0x1"), 0x1abcdef);
+  // hex in string
+  TEST_EQ(TestValue<int>("{ Y:\"0x1abcdef\" }", "int=+0x1"), 0x1abcdef);
+
+  // Make sure we do unsigned 64bit correctly.
+  TEST_EQ(TestValue<uint64_t>("{ Y:12335089644688340133 }", "ulong"),
+          12335089644688340133ULL);
+
+  // bool in string
+  TEST_EQ(TestValue<bool>("{ Y:\"false\" }", "bool=true"), false);
+  TEST_EQ(TestValue<bool>("{ Y:\"true\" }", "bool=\"true\""), true);
+  TEST_EQ(TestValue<bool>("{ Y:'false' }", "bool=true"), false);
+  TEST_EQ(TestValue<bool>("{ Y:'true' }", "bool=\"true\""), true);
+
+  // check comments before and after json object
+  TEST_EQ(TestValue<int>("/*before*/ { Y:1 } /*after*/", "int"), 1);
+  TEST_EQ(TestValue<int>("//before \n { Y:1 } //after", "int"), 1);
+
+}
+
+void NestedListTest() {
+  flatbuffers::Parser parser1;
+  TEST_EQ(parser1.Parse("struct Test { a:short; b:byte; } table T { F:[Test]; }"
+                        "root_type T;"
+                        "{ F:[ [10,20], [30,40]] }"),
+          true);
+}
+
+void EnumStringsTest() {
+  flatbuffers::Parser parser1;
+  TEST_EQ(parser1.Parse("enum E:byte { A, B, C } table T { F:[E]; }"
+                        "root_type T;"
+                        "{ F:[ A, B, \"C\", \"A B C\" ] }"),
+          true);
+  flatbuffers::Parser parser2;
+  TEST_EQ(parser2.Parse("enum E:byte { A, B, C } table T { F:[int]; }"
+                        "root_type T;"
+                        "{ F:[ \"E.C\", \"E.A E.B E.C\" ] }"),
+          true);
+  // unsigned bit_flags
+  flatbuffers::Parser parser3;
+  TEST_EQ(
+      parser3.Parse("enum E:uint16 (bit_flags) { F0, F07=7, F08, F14=14, F15 }"
+                    " table T { F: E = \"F15 F08\"; }"
+                    "root_type T;"),
+      true);
+}
+
+void EnumNamesTest() {
+  TEST_EQ_STR("Red", EnumNameColor(Color_Red));
+  TEST_EQ_STR("Green", EnumNameColor(Color_Green));
+  TEST_EQ_STR("Blue", EnumNameColor(Color_Blue));
+  // Check that Color to string don't crash while decode a mixture of Colors.
+  // 1) Example::Color enum is enum with unfixed underlying type.
+  // 2) Valid enum range: [0; 2^(ceil(log2(Color_ANY))) - 1].
+  // Consequence: A value is out of this range will lead to UB (since C++17).
+  // For details see C++17 standard or explanation on the SO:
+  // stackoverflow.com/questions/18195312/what-happens-if-you-static-cast-invalid-value-to-enum-class
+  TEST_EQ_STR("", EnumNameColor(static_cast<Color>(0)));
+  TEST_EQ_STR("", EnumNameColor(static_cast<Color>(Color_ANY-1)));
+  TEST_EQ_STR("", EnumNameColor(static_cast<Color>(Color_ANY+1)));
+}
+
+void EnumOutOfRangeTest() {
+  TestError("enum X:byte { Y = 128 }", "enum value does not fit");
+  TestError("enum X:byte { Y = -129 }", "enum value does not fit");
+  TestError("enum X:byte { Y = 126, Z0, Z1 }", "enum value does not fit");
+  TestError("enum X:ubyte { Y = -1 }", "enum value does not fit");
+  TestError("enum X:ubyte { Y = 256 }", "enum value does not fit");
+  TestError("enum X:ubyte { Y = 255, Z }", "enum value does not fit");
+  // Unions begin with an implicit "NONE = 0".
+  TestError("table Y{} union X { Y = -1 }",
+            "enum values must be specified in ascending order");
+  TestError("table Y{} union X { Y = 256 }", "enum value does not fit");
+  TestError("table Y{} union X { Y = 255, Z:Y }", "enum value does not fit");
+  TestError("enum X:int { Y = -2147483649 }", "enum value does not fit");
+  TestError("enum X:int { Y = 2147483648 }", "enum value does not fit");
+  TestError("enum X:uint { Y = -1 }", "enum value does not fit");
+  TestError("enum X:uint { Y = 4294967297 }", "enum value does not fit");
+  TestError("enum X:long { Y = 9223372036854775808 }", "does not fit");
+  TestError("enum X:long { Y = 9223372036854775807, Z }", "enum value does not fit");
+  TestError("enum X:ulong { Y = -1 }", "does not fit");
+  TestError("enum X:ubyte (bit_flags) { Y=8 }", "bit flag out");
+  TestError("enum X:byte (bit_flags) { Y=7 }", "must be unsigned"); // -128
+  // bit_flgs out of range
+  TestError("enum X:ubyte (bit_flags) { Y0,Y1,Y2,Y3,Y4,Y5,Y6,Y7,Y8 }", "out of range");
+}
+
+void EnumValueTest() {
+  // json: "{ Y:0 }", schema: table X { Y : "E"}
+  // 0 in enum (V=0) E then Y=0 is valid.
+  TEST_EQ(TestValue<int>("{ Y:0 }", "E", "enum E:int { V }"), 0);
+  TEST_EQ(TestValue<int>("{ Y:V }", "E", "enum E:int { V }"), 0);
+  // A default value of Y is 0.
+  TEST_EQ(TestValue<int>("{ }", "E", "enum E:int { V }"), 0);
+  TEST_EQ(TestValue<int>("{ Y:5 }", "E=V", "enum E:int { V=5 }"), 5);
+  // Generate json with defaults and check.
+  TEST_EQ(TestValue<int>(nullptr, "E=V", "enum E:int { V=5 }"), 5);
+  // 5 in enum
+  TEST_EQ(TestValue<int>("{ Y:5 }", "E", "enum E:int { Z, V=5 }"), 5);
+  TEST_EQ(TestValue<int>("{ Y:5 }", "E=V", "enum E:int { Z, V=5 }"), 5);
+  // Generate json with defaults and check.
+  TEST_EQ(TestValue<int>(nullptr, "E", "enum E:int { Z, V=5 }"), 0);
+  TEST_EQ(TestValue<int>(nullptr, "E=V", "enum E:int { Z, V=5 }"), 5);
+  // u84 test
+  TEST_EQ(TestValue<uint64_t>(nullptr, "E=V",
+                              "enum E:ulong { V = 13835058055282163712 }"),
+          13835058055282163712ULL);
+  TEST_EQ(TestValue<uint64_t>(nullptr, "E=V",
+                              "enum E:ulong { V = 18446744073709551615 }"),
+          18446744073709551615ULL);
+  // Assign non-enum value to enum field. Is it right?
+  TEST_EQ(TestValue<int>("{ Y:7 }", "E", "enum E:int { V = 0 }"), 7);
+}
+
+void IntegerOutOfRangeTest() {
+  TestError("table T { F:byte; } root_type T; { F:128 }",
+            "constant does not fit");
+  TestError("table T { F:byte; } root_type T; { F:-129 }",
+            "constant does not fit");
+  TestError("table T { F:ubyte; } root_type T; { F:256 }",
+            "constant does not fit");
+  TestError("table T { F:ubyte; } root_type T; { F:-1 }",
+            "constant does not fit");
+  TestError("table T { F:short; } root_type T; { F:32768 }",
+            "constant does not fit");
+  TestError("table T { F:short; } root_type T; { F:-32769 }",
+            "constant does not fit");
+  TestError("table T { F:ushort; } root_type T; { F:65536 }",
+            "constant does not fit");
+  TestError("table T { F:ushort; } root_type T; { F:-1 }",
+            "constant does not fit");
+  TestError("table T { F:int; } root_type T; { F:2147483648 }",
+            "constant does not fit");
+  TestError("table T { F:int; } root_type T; { F:-2147483649 }",
+            "constant does not fit");
+  TestError("table T { F:uint; } root_type T; { F:4294967296 }",
+            "constant does not fit");
+  TestError("table T { F:uint; } root_type T; { F:-1 }",
+            "constant does not fit");
+  // Check fixed width aliases
+  TestError("table X { Y:uint8; } root_type X; { Y: -1 }", "does not fit");
+  TestError("table X { Y:uint8; } root_type X; { Y: 256 }", "does not fit");
+  TestError("table X { Y:uint16; } root_type X; { Y: -1 }", "does not fit");
+  TestError("table X { Y:uint16; } root_type X; { Y: 65536 }", "does not fit");
+  TestError("table X { Y:uint32; } root_type X; { Y: -1 }", "");
+  TestError("table X { Y:uint32; } root_type X; { Y: 4294967296 }",
+            "does not fit");
+  TestError("table X { Y:uint64; } root_type X; { Y: -1 }", "");
+  TestError("table X { Y:uint64; } root_type X; { Y: -9223372036854775809 }",
+            "does not fit");
+  TestError("table X { Y:uint64; } root_type X; { Y: 18446744073709551616 }",
+            "does not fit");
+
+  TestError("table X { Y:int8; } root_type X; { Y: -129 }", "does not fit");
+  TestError("table X { Y:int8; } root_type X; { Y: 128 }", "does not fit");
+  TestError("table X { Y:int16; } root_type X; { Y: -32769 }", "does not fit");
+  TestError("table X { Y:int16; } root_type X; { Y: 32768 }", "does not fit");
+  TestError("table X { Y:int32; } root_type X; { Y: -2147483649 }", "");
+  TestError("table X { Y:int32; } root_type X; { Y: 2147483648 }",
+            "does not fit");
+  TestError("table X { Y:int64; } root_type X; { Y: -9223372036854775809 }",
+            "does not fit");
+  TestError("table X { Y:int64; } root_type X; { Y: 9223372036854775808 }",
+            "does not fit");
+  // check out-of-int64 as int8
+  TestError("table X { Y:int8; } root_type X; { Y: -9223372036854775809 }",
+            "does not fit");
+  TestError("table X { Y:int8; } root_type X; { Y: 9223372036854775808 }",
+            "does not fit");
+
+  // Check default values
+  TestError("table X { Y:int64=-9223372036854775809; } root_type X; {}",
+            "does not fit");
+  TestError("table X { Y:int64= 9223372036854775808; } root_type X; {}",
+            "does not fit");
+  TestError("table X { Y:uint64; } root_type X; { Y: -1 }", "");
+  TestError("table X { Y:uint64=-9223372036854775809; } root_type X; {}",
+            "does not fit");
+  TestError("table X { Y:uint64= 18446744073709551616; } root_type X; {}",
+            "does not fit");
+}
+
+void IntegerBoundaryTest() {
+  // Check numerical compatibility with non-C++ languages.
+  // By the C++ standard, std::numerical_limits<int64_t>::min() == -9223372036854775807 (-2^63+1) or less*
+  // The Flatbuffers grammar and most of the languages (C#, Java, Rust) expect
+  // that minimum values are: -128, -32768,.., -9223372036854775808.
+  // Since C++20, static_cast<int64>(0x8000000000000000ULL) is well-defined two's complement cast.
+  // Therefore -9223372036854775808 should be valid negative value.
+  TEST_EQ(flatbuffers::numeric_limits<int8_t>::min(), -128);
+  TEST_EQ(flatbuffers::numeric_limits<int8_t>::max(), 127);
+  TEST_EQ(flatbuffers::numeric_limits<int16_t>::min(), -32768);
+  TEST_EQ(flatbuffers::numeric_limits<int16_t>::max(), 32767);
+  TEST_EQ(flatbuffers::numeric_limits<int32_t>::min() + 1, -2147483647);
+  TEST_EQ(flatbuffers::numeric_limits<int32_t>::max(), 2147483647ULL);
+  TEST_EQ(flatbuffers::numeric_limits<int64_t>::min() + 1LL,
+          -9223372036854775807LL);
+  TEST_EQ(flatbuffers::numeric_limits<int64_t>::max(), 9223372036854775807ULL);
+  TEST_EQ(flatbuffers::numeric_limits<uint8_t>::max(), 255);
+  TEST_EQ(flatbuffers::numeric_limits<uint16_t>::max(), 65535);
+  TEST_EQ(flatbuffers::numeric_limits<uint32_t>::max(), 4294967295ULL);
+  TEST_EQ(flatbuffers::numeric_limits<uint64_t>::max(),
+          18446744073709551615ULL);
+
+  TEST_EQ(TestValue<int8_t>("{ Y:127 }", "byte"), 127);
+  TEST_EQ(TestValue<int8_t>("{ Y:-128 }", "byte"), -128);
+  TEST_EQ(TestValue<uint8_t>("{ Y:255 }", "ubyte"), 255);
+  TEST_EQ(TestValue<uint8_t>("{ Y:0 }", "ubyte"), 0);
+  TEST_EQ(TestValue<int16_t>("{ Y:32767 }", "short"), 32767);
+  TEST_EQ(TestValue<int16_t>("{ Y:-32768 }", "short"), -32768);
+  TEST_EQ(TestValue<uint16_t>("{ Y:65535 }", "ushort"), 65535);
+  TEST_EQ(TestValue<uint16_t>("{ Y:0 }", "ushort"), 0);
+  TEST_EQ(TestValue<int32_t>("{ Y:2147483647 }", "int"), 2147483647);
+  TEST_EQ(TestValue<int32_t>("{ Y:-2147483648 }", "int") + 1, -2147483647);
+  TEST_EQ(TestValue<uint32_t>("{ Y:4294967295 }", "uint"), 4294967295);
+  TEST_EQ(TestValue<uint32_t>("{ Y:0 }", "uint"), 0);
+  TEST_EQ(TestValue<int64_t>("{ Y:9223372036854775807 }", "long"),
+          9223372036854775807LL);
+  TEST_EQ(TestValue<int64_t>("{ Y:-9223372036854775808 }", "long") + 1LL,
+          -9223372036854775807LL);
+  TEST_EQ(TestValue<uint64_t>("{ Y:18446744073709551615 }", "ulong"),
+          18446744073709551615ULL);
+  TEST_EQ(TestValue<uint64_t>("{ Y:0 }", "ulong"), 0);
+  TEST_EQ(TestValue<uint64_t>("{ Y: 18446744073709551615 }", "uint64"),
+          18446744073709551615ULL);
+  // check that the default works
+  TEST_EQ(TestValue<uint64_t>(nullptr, "uint64 = 18446744073709551615"),
+          18446744073709551615ULL);
+}
+
+void ValidFloatTest() {
+  // check rounding to infinity
+  TEST_EQ(TestValue<float>("{ Y:+3.4029e+38 }", "float"), +infinityf);
+  TEST_EQ(TestValue<float>("{ Y:-3.4029e+38 }", "float"), -infinityf);
+  TEST_EQ(TestValue<double>("{ Y:+1.7977e+308 }", "double"), +infinityd);
+  TEST_EQ(TestValue<double>("{ Y:-1.7977e+308 }", "double"), -infinityd);
+
+  TEST_EQ(
+      FloatCompare(TestValue<float>("{ Y:0.0314159e+2 }", "float"), 3.14159f),
+      true);
+  // float in string
+  TEST_EQ(FloatCompare(TestValue<float>("{ Y:\" 0.0314159e+2  \" }", "float"),
+                       3.14159f),
+          true);
+
+  TEST_EQ(TestValue<float>("{ Y:1 }", "float"), 1.0f);
+  TEST_EQ(TestValue<float>("{ Y:1.0 }", "float"), 1.0f);
+  TEST_EQ(TestValue<float>("{ Y:1. }", "float"), 1.0f);
+  TEST_EQ(TestValue<float>("{ Y:+1. }", "float"), 1.0f);
+  TEST_EQ(TestValue<float>("{ Y:-1. }", "float"), -1.0f);
+  TEST_EQ(TestValue<float>("{ Y:1.e0 }", "float"), 1.0f);
+  TEST_EQ(TestValue<float>("{ Y:1.e+0 }", "float"), 1.0f);
+  TEST_EQ(TestValue<float>("{ Y:1.e-0 }", "float"), 1.0f);
+  TEST_EQ(TestValue<float>("{ Y:0.125 }", "float"), 0.125f);
+  TEST_EQ(TestValue<float>("{ Y:.125 }", "float"), 0.125f);
+  TEST_EQ(TestValue<float>("{ Y:-.125 }", "float"), -0.125f);
+  TEST_EQ(TestValue<float>("{ Y:+.125 }", "float"), +0.125f);
+  TEST_EQ(TestValue<float>("{ Y:5 }", "float"), 5.0f);
+  TEST_EQ(TestValue<float>("{ Y:\"5\" }", "float"), 5.0f);
+
+  #if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
+  // Old MSVC versions may have problem with this check.
+  // https://www.exploringbinary.com/visual-c-plus-plus-strtod-still-broken/
+  TEST_EQ(TestValue<double>("{ Y:6.9294956446009195e15 }", "double"),
+    6929495644600920.0);
+  // check nan's
+  TEST_EQ(std::isnan(TestValue<double>("{ Y:nan }", "double")), true);
+  TEST_EQ(std::isnan(TestValue<float>("{ Y:nan }", "float")), true);
+  TEST_EQ(std::isnan(TestValue<float>("{ Y:\"nan\" }", "float")), true);
+  TEST_EQ(std::isnan(TestValue<float>("{ Y:+nan }", "float")), true);
+  TEST_EQ(std::isnan(TestValue<float>("{ Y:-nan }", "float")), true);
+  TEST_EQ(std::isnan(TestValue<float>(nullptr, "float=nan")), true);
+  TEST_EQ(std::isnan(TestValue<float>(nullptr, "float=-nan")), true);
+  // check inf
+  TEST_EQ(TestValue<float>("{ Y:inf }", "float"), infinityf);
+  TEST_EQ(TestValue<float>("{ Y:\"inf\" }", "float"), infinityf);
+  TEST_EQ(TestValue<float>("{ Y:+inf }", "float"), infinityf);
+  TEST_EQ(TestValue<float>("{ Y:-inf }", "float"), -infinityf);
+  TEST_EQ(TestValue<float>(nullptr, "float=inf"), infinityf);
+  TEST_EQ(TestValue<float>(nullptr, "float=-inf"), -infinityf);
+  TestValue<double>(
+      "{ Y : [0.2, .2, 1.0, -1.0, -2., 2., 1e0, -1e0, 1.0e0, -1.0e0, -3.e2, "
+      "3.0e2] }",
+      "[double]");
+  TestValue<float>(
+      "{ Y : [0.2, .2, 1.0, -1.0, -2., 2., 1e0, -1e0, 1.0e0, -1.0e0, -3.e2, "
+      "3.0e2] }",
+      "[float]");
+
+  // Test binary format of float point.
+  // https://en.cppreference.com/w/cpp/language/floating_literal
+  // 0x11.12p-1 = (1*16^1 + 2*16^0 + 3*16^-1 + 4*16^-2) * 2^-1 =
+  TEST_EQ(TestValue<double>("{ Y:0x12.34p-1 }", "double"), 9.1015625);
+  // hex fraction 1.2 (decimal 1.125) scaled by 2^3, that is 9.0
+  TEST_EQ(TestValue<float>("{ Y:-0x0.2p0 }", "float"), -0.125f);
+  TEST_EQ(TestValue<float>("{ Y:-0x.2p1 }", "float"), -0.25f);
+  TEST_EQ(TestValue<float>("{ Y:0x1.2p3 }", "float"), 9.0f);
+  TEST_EQ(TestValue<float>("{ Y:0x10.1p0 }", "float"), 16.0625f);
+  TEST_EQ(TestValue<double>("{ Y:0x1.2p3 }", "double"), 9.0);
+  TEST_EQ(TestValue<double>("{ Y:0x10.1p0 }", "double"), 16.0625);
+  TEST_EQ(TestValue<double>("{ Y:0xC.68p+2 }", "double"), 49.625);
+  TestValue<double>("{ Y : [0x20.4ep1, +0x20.4ep1, -0x20.4ep1] }", "[double]");
+  TestValue<float>("{ Y : [0x20.4ep1, +0x20.4ep1, -0x20.4ep1] }", "[float]");
+
+#else   // FLATBUFFERS_HAS_NEW_STRTOD
+  TEST_OUTPUT_LINE("FLATBUFFERS_HAS_NEW_STRTOD tests skipped");
+#endif  // !FLATBUFFERS_HAS_NEW_STRTOD
+}
+
+void InvalidFloatTest() {
+  auto invalid_msg = "invalid number";
+  auto comma_msg = "expecting: ,";
+  TestError("table T { F:float; } root_type T; { F:1,0 }", "");
+  TestError("table T { F:float; } root_type T; { F:. }", "");
+  TestError("table T { F:float; } root_type T; { F:- }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:+ }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:-. }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:+. }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:.e }", "");
+  TestError("table T { F:float; } root_type T; { F:-e }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:+e }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:-.e }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:+.e }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:-e1 }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:+e1 }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:1.0e+ }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:1.0e- }", invalid_msg);
+  // exponent pP is mandatory for hex-float
+  TestError("table T { F:float; } root_type T; { F:0x0 }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:-0x. }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:0x. }", invalid_msg);
+  // eE not exponent in hex-float!
+  TestError("table T { F:float; } root_type T; { F:0x0.0e+ }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:0x0.0e- }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:0x0.0p }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:0x0.0p+ }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:0x0.0p- }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:0x0.0pa1 }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:0x0.0e+ }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:0x0.0e- }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:0x0.0e+0 }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:0x0.0e-0 }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:0x0.0ep+ }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:0x0.0ep- }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:1.2.3 }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:1.2.e3 }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:1.2e.3 }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:1.2e0.3 }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:1.2e3. }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:1.2e3.0 }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:+-1.0 }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:1.0e+-1 }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:\"1.0e+-1\" }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:1.e0e }", comma_msg);
+  TestError("table T { F:float; } root_type T; { F:0x1.p0e }", comma_msg);
+  TestError("table T { F:float; } root_type T; { F:\" 0x10 \" }", invalid_msg);
+  // floats in string
+  TestError("table T { F:float; } root_type T; { F:\"1,2.\" }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:\"1.2e3.\" }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:\"0x1.p0e\" }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:\"0x1.0\" }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:\" 0x1.0\" }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:\"+ 0\" }", invalid_msg);
+  // disable escapes for "number-in-string"
+  TestError("table T { F:float; } root_type T; { F:\"\\f1.2e3.\" }", "invalid");
+  TestError("table T { F:float; } root_type T; { F:\"\\t1.2e3.\" }", "invalid");
+  TestError("table T { F:float; } root_type T; { F:\"\\n1.2e3.\" }", "invalid");
+  TestError("table T { F:float; } root_type T; { F:\"\\r1.2e3.\" }", "invalid");
+  TestError("table T { F:float; } root_type T; { F:\"4\\x005\" }", "invalid");
+  TestError("table T { F:float; } root_type T; { F:\"\'12\'\" }", invalid_msg);
+  // null is not a number constant!
+  TestError("table T { F:float; } root_type T; { F:\"null\" }", invalid_msg);
+  TestError("table T { F:float; } root_type T; { F:null }", invalid_msg);
+}
+
+void GenerateTableTextTest() {
+  std::string schemafile;
+  std::string jsonfile;
+  bool ok =
+      flatbuffers::LoadFile((test_data_path + "monster_test.fbs").c_str(),
+                            false, &schemafile) &&
+      flatbuffers::LoadFile((test_data_path + "monsterdata_test.json").c_str(),
+                            false, &jsonfile);
+  TEST_EQ(ok, true);
+  auto include_test_path =
+      flatbuffers::ConCatPathFileName(test_data_path, "include_test");
+  const char *include_directories[] = {test_data_path.c_str(),
+                                       include_test_path.c_str(), nullptr};
+  flatbuffers::IDLOptions opt;
+  opt.indent_step = -1;
+  flatbuffers::Parser parser(opt);
+  ok = parser.Parse(schemafile.c_str(), include_directories) &&
+       parser.Parse(jsonfile.c_str(), include_directories);
+  TEST_EQ(ok, true);
+  // Test root table
+  const Monster *monster = GetMonster(parser.builder_.GetBufferPointer());
+  std::string jsongen;
+  auto result = GenerateTextFromTable(parser, monster, "MyGame.Example.Monster",
+                                      &jsongen);
+  TEST_EQ(result, true);
+  // Test sub table
+  const Vec3 *pos = monster->pos();
+  jsongen.clear();
+  result = GenerateTextFromTable(parser, pos, "MyGame.Example.Vec3", &jsongen);
+  TEST_EQ(result, true);
+  TEST_EQ_STR(
+      jsongen.c_str(),
+      "{x: 1.0,y: 2.0,z: 3.0,test1: 3.0,test2: \"Green\",test3: {a: 5,b: 6}}");
+  const Test &test3 = pos->test3();
+  jsongen.clear();
+  result =
+      GenerateTextFromTable(parser, &test3, "MyGame.Example.Test", &jsongen);
+  TEST_EQ(result, true);
+  TEST_EQ_STR(jsongen.c_str(), "{a: 5,b: 6}");
+  const Test *test4 = monster->test4()->Get(0);
+  jsongen.clear();
+  result =
+      GenerateTextFromTable(parser, test4, "MyGame.Example.Test", &jsongen);
+  TEST_EQ(result, true);
+  TEST_EQ_STR(jsongen.c_str(), "{a: 10,b: 20}");
+}
+
+template<typename T>
+void NumericUtilsTestInteger(const char *lower, const char *upper) {
+  T x;
+  TEST_EQ(flatbuffers::StringToNumber("1q", &x), false);
+  TEST_EQ(x, 0);
+  TEST_EQ(flatbuffers::StringToNumber(upper, &x), false);
+  TEST_EQ(x, flatbuffers::numeric_limits<T>::max());
+  TEST_EQ(flatbuffers::StringToNumber(lower, &x), false);
+  auto expval = flatbuffers::is_unsigned<T>::value
+                    ? flatbuffers::numeric_limits<T>::max()
+                    : flatbuffers::numeric_limits<T>::lowest();
+  TEST_EQ(x, expval);
+}
+
+template<typename T>
+void NumericUtilsTestFloat(const char *lower, const char *upper) {
+  T f;
+  TEST_EQ(flatbuffers::StringToNumber("", &f), false);
+  TEST_EQ(flatbuffers::StringToNumber("1q", &f), false);
+  TEST_EQ(f, 0);
+  TEST_EQ(flatbuffers::StringToNumber(upper, &f), true);
+  TEST_EQ(f, +flatbuffers::numeric_limits<T>::infinity());
+  TEST_EQ(flatbuffers::StringToNumber(lower, &f), true);
+  TEST_EQ(f, -flatbuffers::numeric_limits<T>::infinity());
+}
+
+void NumericUtilsTest() {
+  NumericUtilsTestInteger<uint64_t>("-1", "18446744073709551616");
+  NumericUtilsTestInteger<uint8_t>("-1", "256");
+  NumericUtilsTestInteger<int64_t>("-9223372036854775809",
+                                   "9223372036854775808");
+  NumericUtilsTestInteger<int8_t>("-129", "128");
+  NumericUtilsTestFloat<float>("-3.4029e+38", "+3.4029e+38");
+  NumericUtilsTestFloat<float>("-1.7977e+308", "+1.7977e+308");
+}
+
+void IsAsciiUtilsTest() {
+  char c = -128;
+  for (int cnt = 0; cnt < 256; cnt++) {
+    auto alpha = (('a' <= c) && (c <= 'z')) || (('A' <= c) && (c <= 'Z'));
+    auto dec = (('0' <= c) && (c <= '9'));
+    auto hex = (('a' <= c) && (c <= 'f')) || (('A' <= c) && (c <= 'F'));
+    TEST_EQ(flatbuffers::is_alpha(c), alpha);
+    TEST_EQ(flatbuffers::is_alnum(c), alpha || dec);
+    TEST_EQ(flatbuffers::is_digit(c), dec);
+    TEST_EQ(flatbuffers::is_xdigit(c), dec || hex);
+    c += 1;
+  }
+}
+
+void UnicodeTest() {
+  flatbuffers::Parser parser;
+  // Without setting allow_non_utf8 = true, we treat \x sequences as byte
+  // sequences which are then validated as UTF-8.
+  TEST_EQ(parser.Parse("table T { F:string; }"
+                       "root_type T;"
+                       "{ F:\"\\u20AC\\u00A2\\u30E6\\u30FC\\u30B6\\u30FC"
+                       "\\u5225\\u30B5\\u30A4\\u30C8\\xE2\\x82\\xAC\\u0080\\uD8"
+                       "3D\\uDE0E\" }"),
+          true);
+  std::string jsongen;
+  parser.opts.indent_step = -1;
+  auto result =
+      GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
+  TEST_EQ(result, true);
+  TEST_EQ_STR(jsongen.c_str(),
+              "{F: \"\\u20AC\\u00A2\\u30E6\\u30FC\\u30B6\\u30FC"
+              "\\u5225\\u30B5\\u30A4\\u30C8\\u20AC\\u0080\\uD83D\\uDE0E\"}");
+}
+
+void UnicodeTestAllowNonUTF8() {
+  flatbuffers::Parser parser;
+  parser.opts.allow_non_utf8 = true;
+  TEST_EQ(
+      parser.Parse(
+          "table T { F:string; }"
+          "root_type T;"
+          "{ F:\"\\u20AC\\u00A2\\u30E6\\u30FC\\u30B6\\u30FC"
+          "\\u5225\\u30B5\\u30A4\\u30C8\\x01\\x80\\u0080\\uD83D\\uDE0E\" }"),
+      true);
+  std::string jsongen;
+  parser.opts.indent_step = -1;
+  auto result =
+      GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
+  TEST_EQ(result, true);
+  TEST_EQ_STR(
+      jsongen.c_str(),
+      "{F: \"\\u20AC\\u00A2\\u30E6\\u30FC\\u30B6\\u30FC"
+      "\\u5225\\u30B5\\u30A4\\u30C8\\u0001\\x80\\u0080\\uD83D\\uDE0E\"}");
+}
+
+void UnicodeTestGenerateTextFailsOnNonUTF8() {
+  flatbuffers::Parser parser;
+  // Allow non-UTF-8 initially to model what happens when we load a binary
+  // flatbuffer from disk which contains non-UTF-8 strings.
+  parser.opts.allow_non_utf8 = true;
+  TEST_EQ(
+      parser.Parse(
+          "table T { F:string; }"
+          "root_type T;"
+          "{ F:\"\\u20AC\\u00A2\\u30E6\\u30FC\\u30B6\\u30FC"
+          "\\u5225\\u30B5\\u30A4\\u30C8\\x01\\x80\\u0080\\uD83D\\uDE0E\" }"),
+      true);
+  std::string jsongen;
+  parser.opts.indent_step = -1;
+  // Now, disallow non-UTF-8 (the default behavior) so GenerateText indicates
+  // failure.
+  parser.opts.allow_non_utf8 = false;
+  auto result =
+      GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
+  TEST_EQ(result, false);
+}
+
+void UnicodeSurrogatesTest() {
+  flatbuffers::Parser parser;
+
+  TEST_EQ(parser.Parse("table T { F:string (id: 0); }"
+                       "root_type T;"
+                       "{ F:\"\\uD83D\\uDCA9\"}"),
+          true);
+  auto root = flatbuffers::GetRoot<flatbuffers::Table>(
+      parser.builder_.GetBufferPointer());
+  auto string = root->GetPointer<flatbuffers::String *>(
+      flatbuffers::FieldIndexToOffset(0));
+  TEST_EQ_STR(string->c_str(), "\xF0\x9F\x92\xA9");
+}
+
+void UnicodeInvalidSurrogatesTest() {
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\\uD800\"}",
+      "unpaired high surrogate");
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\\uD800abcd\"}",
+      "unpaired high surrogate");
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\\uD800\\n\"}",
+      "unpaired high surrogate");
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\\uD800\\uD800\"}",
+      "multiple high surrogates");
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\\uDC00\"}",
+      "unpaired low surrogate");
+}
+
+void InvalidUTF8Test() {
+  // "1 byte" pattern, under min length of 2 bytes
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\x80\"}",
+      "illegal UTF-8 sequence");
+  // 2 byte pattern, string too short
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xDF\"}",
+      "illegal UTF-8 sequence");
+  // 3 byte pattern, string too short
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xEF\xBF\"}",
+      "illegal UTF-8 sequence");
+  // 4 byte pattern, string too short
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xF7\xBF\xBF\"}",
+      "illegal UTF-8 sequence");
+  // "5 byte" pattern, string too short
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xFB\xBF\xBF\xBF\"}",
+      "illegal UTF-8 sequence");
+  // "6 byte" pattern, string too short
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xFD\xBF\xBF\xBF\xBF\"}",
+      "illegal UTF-8 sequence");
+  // "7 byte" pattern, string too short
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xFE\xBF\xBF\xBF\xBF\xBF\"}",
+      "illegal UTF-8 sequence");
+  // "5 byte" pattern, over max length of 4 bytes
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xFB\xBF\xBF\xBF\xBF\"}",
+      "illegal UTF-8 sequence");
+  // "6 byte" pattern, over max length of 4 bytes
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xFD\xBF\xBF\xBF\xBF\xBF\"}",
+      "illegal UTF-8 sequence");
+  // "7 byte" pattern, over max length of 4 bytes
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xFE\xBF\xBF\xBF\xBF\xBF\xBF\"}",
+      "illegal UTF-8 sequence");
+
+  // Three invalid encodings for U+000A (\n, aka NEWLINE)
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xC0\x8A\"}",
+      "illegal UTF-8 sequence");
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xE0\x80\x8A\"}",
+      "illegal UTF-8 sequence");
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xF0\x80\x80\x8A\"}",
+      "illegal UTF-8 sequence");
+
+  // Two invalid encodings for U+00A9 (COPYRIGHT SYMBOL)
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xE0\x81\xA9\"}",
+      "illegal UTF-8 sequence");
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xF0\x80\x81\xA9\"}",
+      "illegal UTF-8 sequence");
+
+  // Invalid encoding for U+20AC (EURO SYMBOL)
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      "{ F:\"\xF0\x82\x82\xAC\"}",
+      "illegal UTF-8 sequence");
+
+  // UTF-16 surrogate values between U+D800 and U+DFFF cannot be encoded in
+  // UTF-8
+  TestError(
+      "table T { F:string; }"
+      "root_type T;"
+      // U+10400 "encoded" as U+D801 U+DC00
+      "{ F:\"\xED\xA0\x81\xED\xB0\x80\"}",
+      "illegal UTF-8 sequence");
+
+  // Check independence of identifier from locale.
+  std::string locale_ident;
+  locale_ident += "table T { F";
+  locale_ident += static_cast<char>(-32); // unsigned 0xE0
+  locale_ident += " :string; }";
+  locale_ident += "root_type T;";
+  locale_ident += "{}";
+  TestError(locale_ident.c_str(), "");
+}
+
+void UnknownFieldsTest() {
+  flatbuffers::IDLOptions opts;
+  opts.skip_unexpected_fields_in_json = true;
+  flatbuffers::Parser parser(opts);
+
+  TEST_EQ(parser.Parse("table T { str:string; i:int;}"
+                       "root_type T;"
+                       "{ str:\"test\","
+                       "unknown_string:\"test\","
+                       "\"unknown_string\":\"test\","
+                       "unknown_int:10,"
+                       "unknown_float:1.0,"
+                       "unknown_array: [ 1, 2, 3, 4],"
+                       "unknown_object: { i: 10 },"
+                       "\"unknown_object\": { \"i\": 10 },"
+                       "i:10}"),
+          true);
+
+  std::string jsongen;
+  parser.opts.indent_step = -1;
+  auto result =
+      GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
+  TEST_EQ(result, true);
+  TEST_EQ_STR(jsongen.c_str(), "{str: \"test\",i: 10}");
+}
+
+void ParseUnionTest() {
+  // Unions must be parseable with the type field following the object.
+  flatbuffers::Parser parser;
+  TEST_EQ(parser.Parse("table T { A:int; }"
+                       "union U { T }"
+                       "table V { X:U; }"
+                       "root_type V;"
+                       "{ X:{ A:1 }, X_type: T }"),
+          true);
+  // Unions must be parsable with prefixed namespace.
+  flatbuffers::Parser parser2;
+  TEST_EQ(parser2.Parse("namespace N; table A {} namespace; union U { N.A }"
+                        "table B { e:U; } root_type B;"
+                        "{ e_type: N_A, e: {} }"),
+          true);
+}
+
+void InvalidNestedFlatbufferTest() {
+  // First, load and parse FlatBuffer schema (.fbs)
+  std::string schemafile;
+  TEST_EQ(flatbuffers::LoadFile((test_data_path + "monster_test.fbs").c_str(),
+                                false, &schemafile),
+          true);
+  auto include_test_path =
+      flatbuffers::ConCatPathFileName(test_data_path, "include_test");
+  const char *include_directories[] = { test_data_path.c_str(),
+                                        include_test_path.c_str(), nullptr };
+  flatbuffers::Parser parser1;
+  TEST_EQ(parser1.Parse(schemafile.c_str(), include_directories), true);
+
+  // "color" inside nested flatbuffer contains invalid enum value
+  TEST_EQ(parser1.Parse("{ name: \"Bender\", testnestedflatbuffer: { name: "
+                        "\"Leela\", color: \"nonexistent\"}}"),
+          false);
+  // Check that Parser is destroyed correctly after parsing invalid json
+}
+
+void UnionVectorTest() {
+  // load FlatBuffer fbs schema and json.
+  std::string schemafile, jsonfile;
+  TEST_EQ(flatbuffers::LoadFile(
+              (test_data_path + "union_vector/union_vector.fbs").c_str(),
+              false, &schemafile),
+          true);
+  TEST_EQ(flatbuffers::LoadFile(
+              (test_data_path + "union_vector/union_vector.json").c_str(),
+              false, &jsonfile),
+          true);
+
+  // parse schema.
+  flatbuffers::IDLOptions idl_opts;
+  idl_opts.lang_to_generate |= flatbuffers::IDLOptions::kBinary;
+  flatbuffers::Parser parser(idl_opts);
+  TEST_EQ(parser.Parse(schemafile.c_str()), true);
+
+  flatbuffers::FlatBufferBuilder fbb;
+
+  // union types.
+  std::vector<uint8_t> types;
+  types.push_back(static_cast<uint8_t>(Character_Belle));
+  types.push_back(static_cast<uint8_t>(Character_MuLan));
+  types.push_back(static_cast<uint8_t>(Character_BookFan));
+  types.push_back(static_cast<uint8_t>(Character_Other));
+  types.push_back(static_cast<uint8_t>(Character_Unused));
+
+  // union values.
+  std::vector<flatbuffers::Offset<void>> characters;
+  characters.push_back(fbb.CreateStruct(BookReader(/*books_read=*/7)).Union());
+  characters.push_back(CreateAttacker(fbb, /*sword_attack_damage=*/5).Union());
+  characters.push_back(fbb.CreateStruct(BookReader(/*books_read=*/2)).Union());
+  characters.push_back(fbb.CreateString("Other").Union());
+  characters.push_back(fbb.CreateString("Unused").Union());
+
+  // create Movie.
+  const auto movie_offset =
+      CreateMovie(fbb, Character_Rapunzel,
+                  fbb.CreateStruct(Rapunzel(/*hair_length=*/6)).Union(),
+                  fbb.CreateVector(types), fbb.CreateVector(characters));
+  FinishMovieBuffer(fbb, movie_offset);
+  auto buf = fbb.GetBufferPointer();
+
+  flatbuffers::Verifier verifier(buf, fbb.GetSize());
+  TEST_EQ(VerifyMovieBuffer(verifier), true);
+
+  auto flat_movie = GetMovie(buf);
+
+  auto TestMovie = [](const Movie *movie) {
+    TEST_EQ(movie->main_character_type() == Character_Rapunzel, true);
+
+    auto cts = movie->characters_type();
+    TEST_EQ(movie->characters_type()->size(), 5);
+    TEST_EQ(cts->GetEnum<Character>(0) == Character_Belle, true);
+    TEST_EQ(cts->GetEnum<Character>(1) == Character_MuLan, true);
+    TEST_EQ(cts->GetEnum<Character>(2) == Character_BookFan, true);
+    TEST_EQ(cts->GetEnum<Character>(3) == Character_Other, true);
+    TEST_EQ(cts->GetEnum<Character>(4) == Character_Unused, true);
+
+    auto rapunzel = movie->main_character_as_Rapunzel();
+    TEST_NOTNULL(rapunzel);
+    TEST_EQ(rapunzel->hair_length(), 6);
+
+    auto cs = movie->characters();
+    TEST_EQ(cs->size(), 5);
+    auto belle = cs->GetAs<BookReader>(0);
+    TEST_EQ(belle->books_read(), 7);
+    auto mu_lan = cs->GetAs<Attacker>(1);
+    TEST_EQ(mu_lan->sword_attack_damage(), 5);
+    auto book_fan = cs->GetAs<BookReader>(2);
+    TEST_EQ(book_fan->books_read(), 2);
+    auto other = cs->GetAsString(3);
+    TEST_EQ_STR(other->c_str(), "Other");
+    auto unused = cs->GetAsString(4);
+    TEST_EQ_STR(unused->c_str(), "Unused");
+  };
+
+  TestMovie(flat_movie);
+
+  // Also test the JSON we loaded above.
+  TEST_EQ(parser.Parse(jsonfile.c_str()), true);
+  auto jbuf = parser.builder_.GetBufferPointer();
+  flatbuffers::Verifier jverifier(jbuf, parser.builder_.GetSize());
+  TEST_EQ(VerifyMovieBuffer(jverifier), true);
+  TestMovie(GetMovie(jbuf));
+
+  auto movie_object = flat_movie->UnPack();
+  TEST_EQ(movie_object->main_character.AsRapunzel()->hair_length(), 6);
+  TEST_EQ(movie_object->characters[0].AsBelle()->books_read(), 7);
+  TEST_EQ(movie_object->characters[1].AsMuLan()->sword_attack_damage, 5);
+  TEST_EQ(movie_object->characters[2].AsBookFan()->books_read(), 2);
+  TEST_EQ_STR(movie_object->characters[3].AsOther()->c_str(), "Other");
+  TEST_EQ_STR(movie_object->characters[4].AsUnused()->c_str(), "Unused");
+
+  fbb.Clear();
+  fbb.Finish(Movie::Pack(fbb, movie_object));
+
+  delete movie_object;
+
+  auto repacked_movie = GetMovie(fbb.GetBufferPointer());
+
+  TestMovie(repacked_movie);
+
+  auto s =
+      flatbuffers::FlatBufferToString(fbb.GetBufferPointer(), MovieTypeTable());
+  TEST_EQ_STR(
+      s.c_str(),
+      "{ main_character_type: Rapunzel, main_character: { hair_length: 6 }, "
+      "characters_type: [ Belle, MuLan, BookFan, Other, Unused ], "
+      "characters: [ { books_read: 7 }, { sword_attack_damage: 5 }, "
+      "{ books_read: 2 }, \"Other\", \"Unused\" ] }");
+
+
+  flatbuffers::ToStringVisitor visitor("\n", true, "  ");
+  IterateFlatBuffer(fbb.GetBufferPointer(), MovieTypeTable(), &visitor);
+  TEST_EQ_STR(
+      visitor.s.c_str(),
+      "{\n"
+      "  \"main_character_type\": \"Rapunzel\",\n"
+      "  \"main_character\": {\n"
+      "    \"hair_length\": 6\n"
+      "  },\n"
+      "  \"characters_type\": [\n"
+      "    \"Belle\",\n"
+      "    \"MuLan\",\n"
+      "    \"BookFan\",\n"
+      "    \"Other\",\n"
+      "    \"Unused\"\n"
+      "  ],\n"
+      "  \"characters\": [\n"
+      "    {\n"
+      "      \"books_read\": 7\n"
+      "    },\n"
+      "    {\n"
+      "      \"sword_attack_damage\": 5\n"
+      "    },\n"
+      "    {\n"
+      "      \"books_read\": 2\n"
+      "    },\n"
+      "    \"Other\",\n"
+      "    \"Unused\"\n"
+      "  ]\n"
+      "}");
+
+  flatbuffers::Parser parser2(idl_opts);
+  TEST_EQ(parser2.Parse("struct Bool { b:bool; }"
+                        "union Any { Bool }"
+                        "table Root { a:Any; }"
+                        "root_type Root;"), true);
+  TEST_EQ(parser2.Parse("{a_type:Bool,a:{b:true}}"), true);
+}
+
+void ConformTest() {
+  flatbuffers::Parser parser;
+  TEST_EQ(parser.Parse("table T { A:int; } enum E:byte { A }"), true);
+
+  auto test_conform = [](flatbuffers::Parser &parser1, const char *test,
+                         const char *expected_err) {
+    flatbuffers::Parser parser2;
+    TEST_EQ(parser2.Parse(test), true);
+    auto err = parser2.ConformTo(parser1);
+    TEST_NOTNULL(strstr(err.c_str(), expected_err));
+  };
+
+  test_conform(parser, "table T { A:byte; }", "types differ for field");
+  test_conform(parser, "table T { B:int; A:int; }", "offsets differ for field");
+  test_conform(parser, "table T { A:int = 1; }", "defaults differ for field");
+  test_conform(parser, "table T { B:float; }",
+               "field renamed to different type");
+  test_conform(parser, "enum E:byte { B, A }", "values differ for enum");
+}
+
+void ParseProtoBufAsciiTest() {
+  // We can put the parser in a mode where it will accept JSON that looks more
+  // like Protobuf ASCII, for users that have data in that format.
+  // This uses no "" for field names (which we already support by default,
+  // omits `,`, `:` before `{` and a couple of other features.
+  flatbuffers::Parser parser;
+  parser.opts.protobuf_ascii_alike = true;
+  TEST_EQ(
+      parser.Parse("table S { B:int; } table T { A:[int]; C:S; } root_type T;"),
+      true);
+  TEST_EQ(parser.Parse("{ A [1 2] C { B:2 }}"), true);
+  // Similarly, in text output, it should omit these.
+  std::string text;
+  auto ok = flatbuffers::GenerateText(
+      parser, parser.builder_.GetBufferPointer(), &text);
+  TEST_EQ(ok, true);
+  TEST_EQ_STR(text.c_str(),
+              "{\n  A [\n    1\n    2\n  ]\n  C {\n    B: 2\n  }\n}\n");
+}
+
+void FlexBuffersTest() {
+  flexbuffers::Builder slb(512,
+                           flexbuffers::BUILDER_FLAG_SHARE_KEYS_AND_STRINGS);
+
+  // Write the equivalent of:
+  // { vec: [ -100, "Fred", 4.0, false ], bar: [ 1, 2, 3 ], bar3: [ 1, 2, 3 ],
+  // foo: 100, bool: true, mymap: { foo: "Fred" } }
+  // clang-format off
+  #ifndef FLATBUFFERS_CPP98_STL
+    // It's possible to do this without std::function support as well.
+    slb.Map([&]() {
+       slb.Vector("vec", [&]() {
+        slb += -100;  // Equivalent to slb.Add(-100) or slb.Int(-100);
+        slb += "Fred";
+        slb.IndirectFloat(4.0f);
+        uint8_t blob[] = { 77 };
+        slb.Blob(blob, 1);
+        slb += false;
+      });
+      int ints[] = { 1, 2, 3 };
+      slb.Vector("bar", ints, 3);
+      slb.FixedTypedVector("bar3", ints, 3);
+      bool bools[] = {true, false, true, false};
+      slb.Vector("bools", bools, 4);
+      slb.Bool("bool", true);
+      slb.Double("foo", 100);
+      slb.Map("mymap", [&]() {
+        slb.String("foo", "Fred");  // Testing key and string reuse.
+      });
+    });
+    slb.Finish();
+  #else
+    // It's possible to do this without std::function support as well.
+    slb.Map([](flexbuffers::Builder& slb2) {
+       slb2.Vector("vec", [](flexbuffers::Builder& slb3) {
+        slb3 += -100;  // Equivalent to slb.Add(-100) or slb.Int(-100);
+        slb3 += "Fred";
+        slb3.IndirectFloat(4.0f);
+        uint8_t blob[] = { 77 };
+        slb3.Blob(blob, 1);
+        slb3 += false;
+      }, slb2);
+      int ints[] = { 1, 2, 3 };
+      slb2.Vector("bar", ints, 3);
+      slb2.FixedTypedVector("bar3", ints, 3);
+      slb2.Bool("bool", true);
+      slb2.Double("foo", 100);
+      slb2.Map("mymap", [](flexbuffers::Builder& slb3) {
+        slb3.String("foo", "Fred");  // Testing key and string reuse.
+      }, slb2);
+    }, slb);
+    slb.Finish();
+  #endif  // FLATBUFFERS_CPP98_STL
+
+  #ifdef FLATBUFFERS_TEST_VERBOSE
+    for (size_t i = 0; i < slb.GetBuffer().size(); i++)
+      printf("%d ", flatbuffers::vector_data(slb.GetBuffer())[i]);
+    printf("\n");
+  #endif
+  // clang-format on
+
+  auto map = flexbuffers::GetRoot(slb.GetBuffer()).AsMap();
+  TEST_EQ(map.size(), 7);
+  auto vec = map["vec"].AsVector();
+  TEST_EQ(vec.size(), 5);
+  TEST_EQ(vec[0].AsInt64(), -100);
+  TEST_EQ_STR(vec[1].AsString().c_str(), "Fred");
+  TEST_EQ(vec[1].AsInt64(), 0);  // Number parsing failed.
+  TEST_EQ(vec[2].AsDouble(), 4.0);
+  TEST_EQ(vec[2].AsString().IsTheEmptyString(), true);  // Wrong Type.
+  TEST_EQ_STR(vec[2].AsString().c_str(), "");     // This still works though.
+  TEST_EQ_STR(vec[2].ToString().c_str(), "4.0");  // Or have it converted.
+
+  // Few tests for templated version of As.
+  TEST_EQ(vec[0].As<int64_t>(), -100);
+  TEST_EQ_STR(vec[1].As<std::string>().c_str(), "Fred");
+  TEST_EQ(vec[1].As<int64_t>(), 0);  // Number parsing failed.
+  TEST_EQ(vec[2].As<double>(), 4.0);
+
+  // Test that the blob can be accessed.
+  TEST_EQ(vec[3].IsBlob(), true);
+  auto blob = vec[3].AsBlob();
+  TEST_EQ(blob.size(), 1);
+  TEST_EQ(blob.data()[0], 77);
+  TEST_EQ(vec[4].IsBool(), true);   // Check if type is a bool
+  TEST_EQ(vec[4].AsBool(), false);  // Check if value is false
+  auto tvec = map["bar"].AsTypedVector();
+  TEST_EQ(tvec.size(), 3);
+  TEST_EQ(tvec[2].AsInt8(), 3);
+  auto tvec3 = map["bar3"].AsFixedTypedVector();
+  TEST_EQ(tvec3.size(), 3);
+  TEST_EQ(tvec3[2].AsInt8(), 3);
+  TEST_EQ(map["bool"].AsBool(), true);
+  auto tvecb = map["bools"].AsTypedVector();
+  TEST_EQ(tvecb.ElementType(), flexbuffers::FBT_BOOL);
+  TEST_EQ(map["foo"].AsUInt8(), 100);
+  TEST_EQ(map["unknown"].IsNull(), true);
+  auto mymap = map["mymap"].AsMap();
+  // These should be equal by pointer equality, since key and value are shared.
+  TEST_EQ(mymap.Keys()[0].AsKey(), map.Keys()[4].AsKey());
+  TEST_EQ(mymap.Values()[0].AsString().c_str(), vec[1].AsString().c_str());
+  // We can mutate values in the buffer.
+  TEST_EQ(vec[0].MutateInt(-99), true);
+  TEST_EQ(vec[0].AsInt64(), -99);
+  TEST_EQ(vec[1].MutateString("John"), true);  // Size must match.
+  TEST_EQ_STR(vec[1].AsString().c_str(), "John");
+  TEST_EQ(vec[1].MutateString("Alfred"), false);  // Too long.
+  TEST_EQ(vec[2].MutateFloat(2.0f), true);
+  TEST_EQ(vec[2].AsFloat(), 2.0f);
+  TEST_EQ(vec[2].MutateFloat(3.14159), false);  // Double does not fit in float.
+  TEST_EQ(vec[4].AsBool(), false);              // Is false before change
+  TEST_EQ(vec[4].MutateBool(true), true);       // Can change a bool
+  TEST_EQ(vec[4].AsBool(), true);               // Changed bool is now true
+
+  // Parse from JSON:
+  flatbuffers::Parser parser;
+  slb.Clear();
+  auto jsontest = "{ a: [ 123, 456.0 ], b: \"hello\", c: true, d: false }";
+  TEST_EQ(parser.ParseFlexBuffer(jsontest, nullptr, &slb), true);
+  auto jroot = flexbuffers::GetRoot(slb.GetBuffer());
+  auto jmap = jroot.AsMap();
+  auto jvec = jmap["a"].AsVector();
+  TEST_EQ(jvec[0].AsInt64(), 123);
+  TEST_EQ(jvec[1].AsDouble(), 456.0);
+  TEST_EQ_STR(jmap["b"].AsString().c_str(), "hello");
+  TEST_EQ(jmap["c"].IsBool(), true);   // Parsed correctly to a bool
+  TEST_EQ(jmap["c"].AsBool(), true);   // Parsed correctly to true
+  TEST_EQ(jmap["d"].IsBool(), true);   // Parsed correctly to a bool
+  TEST_EQ(jmap["d"].AsBool(), false);  // Parsed correctly to false
+  // And from FlexBuffer back to JSON:
+  auto jsonback = jroot.ToString();
+  TEST_EQ_STR(jsontest, jsonback.c_str());
+}
+
+void TypeAliasesTest() {
+  flatbuffers::FlatBufferBuilder builder;
+
+  builder.Finish(CreateTypeAliases(
+      builder, flatbuffers::numeric_limits<int8_t>::min(),
+      flatbuffers::numeric_limits<uint8_t>::max(),
+      flatbuffers::numeric_limits<int16_t>::min(),
+      flatbuffers::numeric_limits<uint16_t>::max(),
+      flatbuffers::numeric_limits<int32_t>::min(),
+      flatbuffers::numeric_limits<uint32_t>::max(),
+      flatbuffers::numeric_limits<int64_t>::min(),
+      flatbuffers::numeric_limits<uint64_t>::max(), 2.3f, 2.3));
+
+  auto p = builder.GetBufferPointer();
+  auto ta = flatbuffers::GetRoot<TypeAliases>(p);
+
+  TEST_EQ(ta->i8(), flatbuffers::numeric_limits<int8_t>::min());
+  TEST_EQ(ta->u8(), flatbuffers::numeric_limits<uint8_t>::max());
+  TEST_EQ(ta->i16(), flatbuffers::numeric_limits<int16_t>::min());
+  TEST_EQ(ta->u16(), flatbuffers::numeric_limits<uint16_t>::max());
+  TEST_EQ(ta->i32(), flatbuffers::numeric_limits<int32_t>::min());
+  TEST_EQ(ta->u32(), flatbuffers::numeric_limits<uint32_t>::max());
+  TEST_EQ(ta->i64(), flatbuffers::numeric_limits<int64_t>::min());
+  TEST_EQ(ta->u64(), flatbuffers::numeric_limits<uint64_t>::max());
+  TEST_EQ(ta->f32(), 2.3f);
+  TEST_EQ(ta->f64(), 2.3);
+  using namespace flatbuffers; // is_same
+  static_assert(is_same<decltype(ta->i8()), int8_t>::value, "invalid type");
+  static_assert(is_same<decltype(ta->i16()), int16_t>::value, "invalid type");
+  static_assert(is_same<decltype(ta->i32()), int32_t>::value, "invalid type");
+  static_assert(is_same<decltype(ta->i64()), int64_t>::value, "invalid type");
+  static_assert(is_same<decltype(ta->u8()), uint8_t>::value, "invalid type");
+  static_assert(is_same<decltype(ta->u16()), uint16_t>::value, "invalid type");
+  static_assert(is_same<decltype(ta->u32()), uint32_t>::value, "invalid type");
+  static_assert(is_same<decltype(ta->u64()), uint64_t>::value, "invalid type");
+  static_assert(is_same<decltype(ta->f32()), float>::value, "invalid type");
+  static_assert(is_same<decltype(ta->f64()), double>::value, "invalid type");
+}
+
+void EndianSwapTest() {
+  TEST_EQ(flatbuffers::EndianSwap(static_cast<int16_t>(0x1234)), 0x3412);
+  TEST_EQ(flatbuffers::EndianSwap(static_cast<int32_t>(0x12345678)),
+          0x78563412);
+  TEST_EQ(flatbuffers::EndianSwap(static_cast<int64_t>(0x1234567890ABCDEF)),
+          0xEFCDAB9078563412);
+  TEST_EQ(flatbuffers::EndianSwap(flatbuffers::EndianSwap(3.14f)), 3.14f);
+}
+
+void UninitializedVectorTest() {
+  flatbuffers::FlatBufferBuilder builder;
+
+  Test *buf = nullptr;
+  auto vector_offset = builder.CreateUninitializedVectorOfStructs<Test>(2, &buf);
+  TEST_NOTNULL(buf);
+  buf[0] = Test(10, 20);
+  buf[1] = Test(30, 40);
+
+  auto required_name = builder.CreateString("myMonster");
+  auto monster_builder = MonsterBuilder(builder);
+  monster_builder.add_name(required_name); // required field mandated for monster.
+  monster_builder.add_test4(vector_offset);
+  builder.Finish(monster_builder.Finish());
+
+  auto p = builder.GetBufferPointer();
+  auto uvt = flatbuffers::GetRoot<Monster>(p);
+  TEST_NOTNULL(uvt);
+  auto vec = uvt->test4();
+  TEST_NOTNULL(vec);
+  auto test_0 = vec->Get(0);
+  auto test_1 = vec->Get(1);
+  TEST_EQ(test_0->a(), 10);
+  TEST_EQ(test_0->b(), 20);
+  TEST_EQ(test_1->a(), 30);
+  TEST_EQ(test_1->b(), 40);
+}
+
+void EqualOperatorTest() {
+  MonsterT a;
+  MonsterT b;
+  TEST_EQ(b == a, true);
+  TEST_EQ(b != a, false);
+
+  b.mana = 33;
+  TEST_EQ(b == a, false);
+  TEST_EQ(b != a, true);
+  b.mana = 150;
+  TEST_EQ(b == a, true);
+  TEST_EQ(b != a, false);
+
+  b.inventory.push_back(3);
+  TEST_EQ(b == a, false);
+  TEST_EQ(b != a, true);
+  b.inventory.clear();
+  TEST_EQ(b == a, true);
+  TEST_EQ(b != a, false);
+
+  b.test.type = Any_Monster;
+  TEST_EQ(b == a, false);
+  TEST_EQ(b != a, true);
+}
+
+// For testing any binaries, e.g. from fuzzing.
+void LoadVerifyBinaryTest() {
+  std::string binary;
+  if (flatbuffers::LoadFile((test_data_path +
+                             "fuzzer/your-filename-here").c_str(),
+                            true, &binary)) {
+    flatbuffers::Verifier verifier(
+          reinterpret_cast<const uint8_t *>(binary.data()), binary.size());
+    TEST_EQ(VerifyMonsterBuffer(verifier), true);
+  }
+}
+
+void CreateSharedStringTest() {
+  flatbuffers::FlatBufferBuilder builder;
+  const auto one1 = builder.CreateSharedString("one");
+  const auto two = builder.CreateSharedString("two");
+  const auto one2 = builder.CreateSharedString("one");
+  TEST_EQ(one1.o, one2.o);
+  const auto onetwo = builder.CreateSharedString("onetwo");
+  TEST_EQ(onetwo.o != one1.o, true);
+  TEST_EQ(onetwo.o != two.o, true);
+
+  // Support for embedded nulls
+  const char chars_b[] = {'a', '\0', 'b'};
+  const char chars_c[] = {'a', '\0', 'c'};
+  const auto null_b1 = builder.CreateSharedString(chars_b, sizeof(chars_b));
+  const auto null_c = builder.CreateSharedString(chars_c, sizeof(chars_c));
+  const auto null_b2 = builder.CreateSharedString(chars_b, sizeof(chars_b));
+  TEST_EQ(null_b1.o != null_c.o, true); // Issue#5058 repro
+  TEST_EQ(null_b1.o, null_b2.o);
+
+  // Put the strings into an array for round trip verification.
+  const flatbuffers::Offset<flatbuffers::String> array[7] = { one1, two, one2, onetwo, null_b1, null_c, null_b2 };
+  const auto vector_offset = builder.CreateVector(array, flatbuffers::uoffset_t(7));
+  MonsterBuilder monster_builder(builder);
+  monster_builder.add_name(two);
+  monster_builder.add_testarrayofstring(vector_offset);
+  builder.Finish(monster_builder.Finish());
+
+  // Read the Monster back.
+  const auto *monster = flatbuffers::GetRoot<Monster>(builder.GetBufferPointer());
+  TEST_EQ_STR(monster->name()->c_str(), "two");
+  const auto *testarrayofstring = monster->testarrayofstring();
+  TEST_EQ(testarrayofstring->size(), flatbuffers::uoffset_t(7));
+  const auto &a = *testarrayofstring;
+  TEST_EQ_STR(a[0]->c_str(), "one");
+  TEST_EQ_STR(a[1]->c_str(), "two");
+  TEST_EQ_STR(a[2]->c_str(), "one");
+  TEST_EQ_STR(a[3]->c_str(), "onetwo");
+  TEST_EQ(a[4]->str(), (std::string(chars_b, sizeof(chars_b))));
+  TEST_EQ(a[5]->str(), (std::string(chars_c, sizeof(chars_c))));
+  TEST_EQ(a[6]->str(), (std::string(chars_b, sizeof(chars_b))));
+
+  // Make sure String::operator< works, too, since it is related to StringOffsetCompare.
+  TEST_EQ((*a[0]) < (*a[1]), true);
+  TEST_EQ((*a[1]) < (*a[0]), false);
+  TEST_EQ((*a[1]) < (*a[2]), false);
+  TEST_EQ((*a[2]) < (*a[1]), true);
+  TEST_EQ((*a[4]) < (*a[3]), true);
+  TEST_EQ((*a[5]) < (*a[4]), false);
+  TEST_EQ((*a[5]) < (*a[4]), false);
+  TEST_EQ((*a[6]) < (*a[5]), true);
+}
+
+void FixedLengthArrayTest() {
+  // VS10 does not support typed enums, exclude from tests
+#if !defined(_MSC_VER) || _MSC_VER >= 1700
+  // Generate an ArrayTable containing one ArrayStruct.
+  flatbuffers::FlatBufferBuilder fbb;
+  MyGame::Example::NestedStruct nStruct0(MyGame::Example::TestEnum::B);
+  TEST_NOTNULL(nStruct0.mutable_a());
+  nStruct0.mutable_a()->Mutate(0, 1);
+  nStruct0.mutable_a()->Mutate(1, 2);
+  TEST_NOTNULL(nStruct0.mutable_c());
+  nStruct0.mutable_c()->Mutate(0, MyGame::Example::TestEnum::C);
+  nStruct0.mutable_c()->Mutate(1, MyGame::Example::TestEnum::A);
+  MyGame::Example::NestedStruct nStruct1(MyGame::Example::TestEnum::C);
+  TEST_NOTNULL(nStruct1.mutable_a());
+  nStruct1.mutable_a()->Mutate(0, 3);
+  nStruct1.mutable_a()->Mutate(1, 4);
+  TEST_NOTNULL(nStruct1.mutable_c());
+  nStruct1.mutable_c()->Mutate(0, MyGame::Example::TestEnum::C);
+  nStruct1.mutable_c()->Mutate(1, MyGame::Example::TestEnum::A);
+  MyGame::Example::ArrayStruct aStruct(2, 12);
+  TEST_NOTNULL(aStruct.b());
+  TEST_NOTNULL(aStruct.mutable_b());
+  TEST_NOTNULL(aStruct.mutable_d());
+  for (int i = 0; i < aStruct.b()->size(); i++)
+    aStruct.mutable_b()->Mutate(i, i + 1);
+  aStruct.mutable_d()->Mutate(0, nStruct0);
+  aStruct.mutable_d()->Mutate(1, nStruct1);
+  auto aTable = MyGame::Example::CreateArrayTable(fbb, &aStruct);
+  fbb.Finish(aTable);
+
+  // Verify correctness of the ArrayTable.
+  flatbuffers::Verifier verifier(fbb.GetBufferPointer(), fbb.GetSize());
+  MyGame::Example::VerifyArrayTableBuffer(verifier);
+  auto p = MyGame::Example::GetMutableArrayTable(fbb.GetBufferPointer());
+  auto mArStruct = p->mutable_a();
+  TEST_NOTNULL(mArStruct);
+  TEST_NOTNULL(mArStruct->b());
+  TEST_NOTNULL(mArStruct->d());
+  TEST_NOTNULL(mArStruct->mutable_b());
+  TEST_NOTNULL(mArStruct->mutable_d());
+  mArStruct->mutable_b()->Mutate(14, -14);
+  TEST_EQ(mArStruct->a(), 2);
+  TEST_EQ(mArStruct->b()->size(), 15);
+  TEST_EQ(mArStruct->b()->Get(aStruct.b()->size() - 1), -14);
+  TEST_EQ(mArStruct->c(), 12);
+  TEST_NOTNULL(mArStruct->d()->Get(0).a());
+  TEST_EQ(mArStruct->d()->Get(0).a()->Get(0), 1);
+  TEST_EQ(mArStruct->d()->Get(0).a()->Get(1), 2);
+  TEST_NOTNULL(mArStruct->d()->Get(1).a());
+  TEST_EQ(mArStruct->d()->Get(1).a()->Get(0), 3);
+  TEST_EQ(mArStruct->d()->Get(1).a()->Get(1), 4);
+  TEST_NOTNULL(mArStruct->mutable_d()->GetMutablePointer(1));
+  TEST_NOTNULL(mArStruct->mutable_d()->GetMutablePointer(1)->mutable_a());
+  mArStruct->mutable_d()->GetMutablePointer(1)->mutable_a()->Mutate(1, 5);
+  TEST_EQ(mArStruct->d()->Get(1).a()->Get(1), 5);
+  TEST_EQ(mArStruct->d()->Get(0).b() == MyGame::Example::TestEnum::B, true);
+  TEST_NOTNULL(mArStruct->d()->Get(0).c());
+  TEST_EQ(mArStruct->d()->Get(0).c()->Get(0) == MyGame::Example::TestEnum::C,
+          true);
+  TEST_EQ(mArStruct->d()->Get(0).c()->Get(1) == MyGame::Example::TestEnum::A,
+          true);
+  TEST_EQ(mArStruct->d()->Get(1).b() == MyGame::Example::TestEnum::C, true);
+  TEST_NOTNULL(mArStruct->d()->Get(1).c());
+  TEST_EQ(mArStruct->d()->Get(1).c()->Get(0) == MyGame::Example::TestEnum::C,
+          true);
+  TEST_EQ(mArStruct->d()->Get(1).c()->Get(1) == MyGame::Example::TestEnum::A,
+          true);
+  for (int i = 0; i < mArStruct->b()->size() - 1; i++)
+    TEST_EQ(mArStruct->b()->Get(i), i + 1);
+#endif
+}
+
+void NativeTypeTest() {
+  const int N = 3;
+
+  Geometry::ApplicationDataT src_data;
+  src_data.vectors.reserve(N);
+
+  for (int i = 0; i < N; ++i) {
+    src_data.vectors.push_back (Native::Vector3D(10 * i + 0.1f, 10 * i + 0.2f, 10 * i + 0.3f));
+  }
+
+  flatbuffers::FlatBufferBuilder fbb;
+  fbb.Finish(Geometry::ApplicationData::Pack(fbb, &src_data));
+
+  auto dstDataT =  Geometry::UnPackApplicationData(fbb.GetBufferPointer());
+
+  for (int i = 0; i < N; ++i) {
+    Native::Vector3D& v = dstDataT->vectors[i];
+    TEST_EQ(v.x, 10 * i + 0.1f);
+    TEST_EQ(v.y, 10 * i + 0.2f);
+    TEST_EQ(v.z, 10 * i + 0.3f);
+  }
+}
+
+void FixedLengthArrayJsonTest(bool binary) {  
+  // VS10 does not support typed enums, exclude from tests
+#if !defined(_MSC_VER) || _MSC_VER >= 1700
+  // load FlatBuffer schema (.fbs) and JSON from disk
+  std::string schemafile;
+  std::string jsonfile;
+  TEST_EQ(
+      flatbuffers::LoadFile(
+          (test_data_path + "arrays_test." + (binary ? "bfbs" : "fbs")).c_str(),
+          binary, &schemafile),
+      true);
+  TEST_EQ(flatbuffers::LoadFile((test_data_path + "arrays_test.golden").c_str(),
+                                false, &jsonfile),
+          true);
+
+  // parse schema first, so we can use it to parse the data after
+  flatbuffers::Parser parserOrg, parserGen;
+  if (binary) {
+    flatbuffers::Verifier verifier(
+        reinterpret_cast<const uint8_t *>(schemafile.c_str()),
+        schemafile.size());
+    TEST_EQ(reflection::VerifySchemaBuffer(verifier), true);
+    TEST_EQ(parserOrg.Deserialize((const uint8_t *)schemafile.c_str(),
+                                  schemafile.size()),
+            true);
+    TEST_EQ(parserGen.Deserialize((const uint8_t *)schemafile.c_str(),
+                                  schemafile.size()),
+            true);
+  } else {
+    TEST_EQ(parserOrg.Parse(schemafile.c_str()), true);
+    TEST_EQ(parserGen.Parse(schemafile.c_str()), true);
+  }
+  TEST_EQ(parserOrg.Parse(jsonfile.c_str()), true);
+
+  // First, verify it, just in case:
+  flatbuffers::Verifier verifierOrg(parserOrg.builder_.GetBufferPointer(),
+                                    parserOrg.builder_.GetSize());
+  TEST_EQ(VerifyArrayTableBuffer(verifierOrg), true);
+
+  // Export to JSON
+  std::string jsonGen;
+  TEST_EQ(
+      GenerateText(parserOrg, parserOrg.builder_.GetBufferPointer(), &jsonGen),
+      true);
+
+  // Import from JSON
+  TEST_EQ(parserGen.Parse(jsonGen.c_str()), true);
+
+  // Verify buffer from generated JSON
+  flatbuffers::Verifier verifierGen(parserGen.builder_.GetBufferPointer(),
+                                    parserGen.builder_.GetSize());
+  TEST_EQ(VerifyArrayTableBuffer(verifierGen), true);
+
+  // Compare generated buffer to original
+  TEST_EQ(parserOrg.builder_.GetSize(), parserGen.builder_.GetSize());
+  TEST_EQ(std::memcmp(parserOrg.builder_.GetBufferPointer(),
+                      parserGen.builder_.GetBufferPointer(),
+                      parserOrg.builder_.GetSize()),
+          0);
+#else
+  (void)binary;
+#endif
+}
+
+int FlatBufferTests() {
+  // clang-format off
+
+  // Run our various test suites:
+
+  std::string rawbuf;
+  auto flatbuf1 = CreateFlatBufferTest(rawbuf);
+  #if !defined(FLATBUFFERS_CPP98_STL)
+    auto flatbuf = std::move(flatbuf1);  // Test move assignment.
+  #else
+    auto &flatbuf = flatbuf1;
+  #endif // !defined(FLATBUFFERS_CPP98_STL)
+
+  TriviallyCopyableTest();
+
+  AccessFlatBufferTest(reinterpret_cast<const uint8_t *>(rawbuf.c_str()),
+                       rawbuf.length());
+  AccessFlatBufferTest(flatbuf.data(), flatbuf.size());
+
+  MutateFlatBuffersTest(flatbuf.data(), flatbuf.size());
+
+  ObjectFlatBuffersTest(flatbuf.data());
+
+  MiniReflectFlatBuffersTest(flatbuf.data());
+
+  SizePrefixedTest();
+
+  #ifndef FLATBUFFERS_NO_FILE_TESTS
+    #ifdef FLATBUFFERS_TEST_PATH_PREFIX
+      test_data_path = FLATBUFFERS_STRING(FLATBUFFERS_TEST_PATH_PREFIX) +
+                       test_data_path;
+    #endif
+    ParseAndGenerateTextTest(false);
+    ParseAndGenerateTextTest(true);
+    FixedLengthArrayJsonTest(false);
+    FixedLengthArrayJsonTest(true);
+    ReflectionTest(flatbuf.data(), flatbuf.size());
+    ParseProtoTest();
+    UnionVectorTest();
+    LoadVerifyBinaryTest();
+    GenerateTableTextTest();
+  #endif
+  // clang-format on
+
+  FuzzTest1();
+  FuzzTest2();
+
+  ErrorTest();
+  ValueTest();
+  EnumValueTest();
+  EnumStringsTest();
+  EnumNamesTest();
+  EnumOutOfRangeTest();
+  IntegerOutOfRangeTest();
+  IntegerBoundaryTest();
+  UnicodeTest();
+  UnicodeTestAllowNonUTF8();
+  UnicodeTestGenerateTextFailsOnNonUTF8();
+  UnicodeSurrogatesTest();
+  UnicodeInvalidSurrogatesTest();
+  InvalidUTF8Test();
+  UnknownFieldsTest();
+  ParseUnionTest();
+  InvalidNestedFlatbufferTest();
+  ConformTest();
+  ParseProtoBufAsciiTest();
+  TypeAliasesTest();
+  EndianSwapTest();
+  CreateSharedStringTest();
+  JsonDefaultTest();
+  JsonEnumsTest();
+  FlexBuffersTest();
+  UninitializedVectorTest();
+  EqualOperatorTest();
+  NumericUtilsTest();
+  IsAsciiUtilsTest();
+  ValidFloatTest();
+  InvalidFloatTest();
+  TestMonsterExtraFloats();
+  FixedLengthArrayTest();
+  NativeTypeTest();
+  return 0;
+}
+
+int main(int /*argc*/, const char * /*argv*/ []) {
+  InitTestEngine();
+
+  std::string req_locale;
+  if (flatbuffers::ReadEnvironmentVariable("FLATBUFFERS_TEST_LOCALE",
+                                           &req_locale)) {
+    TEST_OUTPUT_LINE("The environment variable FLATBUFFERS_TEST_LOCALE=%s",
+                     req_locale.c_str());
+    req_locale = flatbuffers::RemoveStringQuotes(req_locale);
+    std::string the_locale;
+    TEST_ASSERT_FUNC(
+        flatbuffers::SetGlobalTestLocale(req_locale.c_str(), &the_locale));
+    TEST_OUTPUT_LINE("The global C-locale changed: %s", the_locale.c_str());
+  }
+
+  FlatBufferTests();
+  FlatBufferBuilderTest();
+
+  if (!testing_fails) {
+    TEST_OUTPUT_LINE("ALL TESTS PASSED");
+  } else {
+    TEST_OUTPUT_LINE("%d FAILED TESTS", testing_fails);
+  }
+  return CloseTestEngine();
+}
diff --git a/third_party/flatbuffers/tests/test_assert.cpp b/third_party/flatbuffers/tests/test_assert.cpp
new file mode 100644
index 0000000..794ffe7
--- /dev/null
+++ b/third_party/flatbuffers/tests/test_assert.cpp
@@ -0,0 +1,69 @@
+#include "test_assert.h"
+
+#include <assert.h>
+
+#ifdef _MSC_VER
+#  include <crtdbg.h>
+#  include <windows.h>
+#endif
+
+int testing_fails = 0;
+static TestFailEventListener fail_listener_ = nullptr;
+
+void TestFail(const char *expval, const char *val, const char *exp,
+              const char *file, int line, const char *func) {
+  TEST_OUTPUT_LINE("VALUE: \"%s\"", expval);
+  TEST_OUTPUT_LINE("EXPECTED: \"%s\"", val);
+  TEST_OUTPUT_LINE("TEST FAILED: %s:%d, %s in %s", file, line, exp,
+                   func ? func : "");
+  testing_fails++;
+
+  // Notify, emulate 'gtest::OnTestPartResult' event handler.
+  if (fail_listener_) (*fail_listener_)(expval, val, exp, file, line, func);
+
+  assert(0);  // ignored in Release if NDEBUG defined
+}
+
+void TestEqStr(const char *expval, const char *val, const char *exp,
+               const char *file, int line) {
+  if (strcmp(expval, val) != 0) { TestFail(expval, val, exp, file, line); }
+}
+
+#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && defined(_MSC_VER) && \
+    defined(_DEBUG)
+#define FLATBUFFERS_MEMORY_LEAK_TRACKING_MSVC
+#endif
+
+void InitTestEngine(TestFailEventListener listener) {
+  testing_fails = 0;
+  // Disable stdout buffering to prevent information lost on assertion or core
+  // dump.
+  setvbuf(stdout, NULL, _IONBF, 0);
+  setvbuf(stderr, NULL, _IONBF, 0);
+
+  flatbuffers::SetupDefaultCRTReportMode();
+
+  // clang-format off
+
+  #if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING_MSVC)
+    // For more thorough checking:
+    // _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF
+    auto flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
+    _CrtSetDbgFlag(flags | _CRTDBG_ALLOC_MEM_DF);
+  #endif
+  // clang-format on
+
+  fail_listener_ = listener;
+}
+
+int CloseTestEngine(bool force_report) {
+  if (!testing_fails || force_report) {
+  #if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING_MSVC)
+      auto flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
+      flags &= ~_CRTDBG_DELAY_FREE_MEM_DF;
+      flags |= _CRTDBG_LEAK_CHECK_DF;
+      _CrtSetDbgFlag(flags);
+  #endif
+  }
+  return (0 != testing_fails);
+}
diff --git a/third_party/flatbuffers/tests/test_assert.h b/third_party/flatbuffers/tests/test_assert.h
new file mode 100644
index 0000000..883586b
--- /dev/null
+++ b/third_party/flatbuffers/tests/test_assert.h
@@ -0,0 +1,68 @@
+#ifndef TEST_ASSERT_H
+#define TEST_ASSERT_H
+
+#include "flatbuffers/base.h"
+#include "flatbuffers/util.h"
+
+// clang-format off
+
+#ifdef __ANDROID__
+  #include <android/log.h>
+  #define TEST_OUTPUT_LINE(...) \
+      __android_log_print(ANDROID_LOG_INFO, "FlatBuffers", __VA_ARGS__)
+  #define FLATBUFFERS_NO_FILE_TESTS
+#else
+  #define TEST_OUTPUT_LINE(...) \
+      { printf(__VA_ARGS__); printf("\n"); }
+#endif
+
+#define TEST_EQ(exp, val) TestEq(exp, val, #exp, __FILE__, __LINE__)
+#define TEST_ASSERT(exp) TestEq(exp, true, #exp, __FILE__, __LINE__)
+#define TEST_NOTNULL(exp) TestEq(exp == NULL, false, #exp, __FILE__, __LINE__)
+#define TEST_EQ_STR(exp, val) TestEqStr(exp, val, #exp, __FILE__, __LINE__)
+
+#ifdef _WIN32
+  #define TEST_ASSERT_FUNC(exp) TestEq(exp, true, #exp, __FILE__, __LINE__, __FUNCTION__)
+  #define TEST_EQ_FUNC(exp, val) TestEq(exp, val, #exp, __FILE__, __LINE__, __FUNCTION__)
+#else
+  #define TEST_ASSERT_FUNC(exp) TestEq(exp, true, #exp, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+  #define TEST_EQ_FUNC(exp, val) TestEq(exp, val, #exp, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#endif
+
+// clang-format on
+
+extern int testing_fails;
+
+// Listener of TestFail, like 'gtest::OnTestPartResult' event handler.
+// Called in TestFail after a failed assertion.
+typedef bool (*TestFailEventListener)(const char *expval, const char *val,
+                                      const char *exp, const char *file,
+                                      int line, const char *func);
+
+// Prepare test engine (MSVC assertion setup, etc).
+// listener - this function will be notified on each TestFail call.
+void InitTestEngine(TestFailEventListener listener = nullptr);
+
+// Release all test-engine resources.
+// Prints or schedule a debug report if all test passed.
+// Returns 0 if all tests passed or 1 otherwise.
+// Memory leak report: FLATBUFFERS_MEMORY_LEAK_TRACKING && _MSC_VER && _DEBUG.
+int CloseTestEngine(bool force_report = false);
+
+// Write captured state to a log and terminate test run.
+void TestFail(const char *expval, const char *val, const char *exp,
+              const char *file, int line, const char *func = 0);
+
+void TestEqStr(const char *expval, const char *val, const char *exp,
+               const char *file, int line);
+
+template<typename T, typename U>
+void TestEq(T expval, U val, const char *exp, const char *file, int line,
+            const char *func = 0) {
+  if (U(expval) != val) {
+    TestFail(flatbuffers::NumToString(expval).c_str(),
+             flatbuffers::NumToString(val).c_str(), exp, file, line, func);
+  }
+}
+
+#endif  // !TEST_ASSERT_H
diff --git a/third_party/flatbuffers/tests/test_builder.cpp b/third_party/flatbuffers/tests/test_builder.cpp
new file mode 100644
index 0000000..8c070c1
--- /dev/null
+++ b/third_party/flatbuffers/tests/test_builder.cpp
@@ -0,0 +1,148 @@
+#include "flatbuffers/stl_emulation.h"
+
+#include "monster_test_generated.h"
+#include "test_builder.h"
+
+using namespace MyGame::Example;
+
+const std::string m1_name = "Cyberdemon";
+const Color m1_color = Color_Red;
+const std::string m2_name = "Imp";
+const Color m2_color = Color_Green;
+
+struct OwnedAllocator : public flatbuffers::DefaultAllocator {};
+
+class TestHeapBuilder : public flatbuffers::FlatBufferBuilder {
+private:
+  // clang-format off
+  #if !defined(FLATBUFFERS_CPP98_STL)
+  TestHeapBuilder(const TestHeapBuilder &);
+  TestHeapBuilder &operator=(const TestHeapBuilder &);
+  #endif  // !defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+
+public:
+  TestHeapBuilder()
+    : flatbuffers::FlatBufferBuilder(2048, new OwnedAllocator(), true) {}
+
+  // clang-format off
+  #if !defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+  TestHeapBuilder(TestHeapBuilder &&other)
+    : FlatBufferBuilder(std::move(other)) { }
+
+  TestHeapBuilder &operator=(TestHeapBuilder &&other) {
+    FlatBufferBuilder::operator=(std::move(other));
+    return *this;
+  }
+  // clang-format off
+  #endif  // !defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+};
+
+// This class simulates flatbuffers::grpc::detail::SliceAllocatorMember
+struct AllocatorMember {
+  flatbuffers::DefaultAllocator member_allocator_;
+};
+
+struct GrpcLikeMessageBuilder : private AllocatorMember,
+                                public flatbuffers::FlatBufferBuilder {
+private:
+  GrpcLikeMessageBuilder(const GrpcLikeMessageBuilder &);
+  GrpcLikeMessageBuilder &operator=(const GrpcLikeMessageBuilder &);
+
+public:
+  GrpcLikeMessageBuilder()
+    : flatbuffers::FlatBufferBuilder(1024, &member_allocator_, false) {}
+
+  GrpcLikeMessageBuilder(GrpcLikeMessageBuilder &&other)
+    : FlatBufferBuilder(1024, &member_allocator_, false) {
+    // Default construct and swap idiom.
+    Swap(other);
+  }
+
+  // clang-format off
+  #if !defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+  GrpcLikeMessageBuilder &operator=(GrpcLikeMessageBuilder &&other) {
+    // Construct temporary and swap idiom
+    GrpcLikeMessageBuilder temp(std::move(other));
+    Swap(temp);
+    return *this;
+  }
+  // clang-format off
+  #endif  // !defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+
+  void Swap(GrpcLikeMessageBuilder &other) {
+    // No need to swap member_allocator_ because it's stateless.
+    FlatBufferBuilder::Swap(other);
+    // After swapping the FlatBufferBuilder, we swap back the allocator, which restores
+    // the original allocator back in place. This is necessary because MessageBuilder's
+    // allocator is its own member (SliceAllocatorMember). The allocator passed to
+    // FlatBufferBuilder::vector_downward must point to this member.
+    buf_.swap_allocator(other.buf_);
+  }
+};
+
+flatbuffers::Offset<Monster> populate1(flatbuffers::FlatBufferBuilder &builder) {
+  auto name_offset = builder.CreateString(m1_name);
+  return CreateMonster(builder, nullptr, 0, 0, name_offset, 0, m1_color);
+}
+
+flatbuffers::Offset<Monster> populate2(flatbuffers::FlatBufferBuilder &builder) {
+  auto name_offset = builder.CreateString(m2_name);
+  return CreateMonster(builder, nullptr, 0, 0, name_offset, 0, m2_color);
+}
+
+uint8_t *release_raw_base(flatbuffers::FlatBufferBuilder &fbb, size_t &size, size_t &offset) {
+  return fbb.ReleaseRaw(size, offset);
+}
+
+void free_raw(flatbuffers::grpc::MessageBuilder &, uint8_t *) {
+  // release_raw_base calls FlatBufferBuilder::ReleaseRaw on the argument MessageBuilder.
+  // It's semantically wrong as MessageBuilder has its own ReleaseRaw member function that
+  // takes three arguments. In such cases though, ~MessageBuilder() invokes
+  // ~SliceAllocator() that takes care of deleting memory as it calls grpc_slice_unref.
+  // Obviously, this behavior is very surprising as the pointer returned by
+  // FlatBufferBuilder::ReleaseRaw is not valid as soon as MessageBuilder goes out of scope.
+  // This problem does not occur with FlatBufferBuilder.
+}
+
+void free_raw(flatbuffers::FlatBufferBuilder &, uint8_t *buf) {
+  flatbuffers::DefaultAllocator().deallocate(buf, 0);
+}
+
+bool verify(const flatbuffers::DetachedBuffer &buf, const std::string &expected_name, Color color) {
+  const Monster *monster = flatbuffers::GetRoot<Monster>(buf.data());
+  return (monster->name()->str() == expected_name) && (monster->color() == color);
+}
+
+bool verify(const uint8_t *buf, size_t offset, const std::string &expected_name, Color color) {
+  const Monster *monster = flatbuffers::GetRoot<Monster>(buf+offset);
+  return (monster->name()->str() == expected_name) && (monster->color() == color);
+}
+
+bool release_n_verify(flatbuffers::FlatBufferBuilder &fbb, const std::string &expected_name, Color color) {
+  flatbuffers::DetachedBuffer buf = fbb.Release();
+  return verify(buf, expected_name, color);
+}
+
+void FlatBufferBuilderTest() {
+  using flatbuffers::FlatBufferBuilder;
+
+  BuilderTests<FlatBufferBuilder>::all_tests();
+  BuilderTests<TestHeapBuilder>::all_tests();
+  BuilderTests<GrpcLikeMessageBuilder>::all_tests();
+
+  BuilderReuseTestSelector tests[4] = {
+    REUSABLE_AFTER_RELEASE,
+    REUSABLE_AFTER_RELEASE_RAW,
+    REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN,
+    REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN
+  };
+
+  BuilderReuseTests<FlatBufferBuilder, FlatBufferBuilder>::run_tests(TestSelector(tests, tests+4));
+  BuilderReuseTests<TestHeapBuilder, TestHeapBuilder>::run_tests(TestSelector(tests, tests+4));
+  BuilderReuseTests<GrpcLikeMessageBuilder, GrpcLikeMessageBuilder>::run_tests(TestSelector(tests, tests+4));
+}
diff --git a/third_party/flatbuffers/tests/test_builder.h b/third_party/flatbuffers/tests/test_builder.h
new file mode 100644
index 0000000..1e2fa0a
--- /dev/null
+++ b/third_party/flatbuffers/tests/test_builder.h
@@ -0,0 +1,326 @@
+#ifndef TEST_BUILDER_H
+#define TEST_BUILDER_H
+
+#include <set>
+#include <type_traits>
+#include "monster_test_generated.h"
+#include "flatbuffers/flatbuffers.h"
+#include "test_assert.h"
+
+using MyGame::Example::Color;
+using MyGame::Example::Monster;
+
+namespace flatbuffers {
+namespace grpc {
+class MessageBuilder;
+}
+}
+
+template <class T, class U>
+struct is_same {
+  static const bool value = false;
+};
+
+template <class T>
+struct is_same<T, T> {
+  static const bool value = true;
+};
+
+extern const std::string m1_name;
+extern const Color m1_color;
+extern const std::string m2_name;
+extern const Color m2_color;
+
+flatbuffers::Offset<Monster> populate1(flatbuffers::FlatBufferBuilder &builder);
+flatbuffers::Offset<Monster> populate2(flatbuffers::FlatBufferBuilder &builder);
+
+uint8_t *release_raw_base(flatbuffers::FlatBufferBuilder &fbb, size_t &size, size_t &offset);
+
+void free_raw(flatbuffers::grpc::MessageBuilder &mbb, uint8_t *buf);
+void free_raw(flatbuffers::FlatBufferBuilder &fbb, uint8_t *buf);
+
+bool verify(const flatbuffers::DetachedBuffer &buf, const std::string &expected_name, Color color);
+bool verify(const uint8_t *buf, size_t offset, const std::string &expected_name, Color color);
+
+bool release_n_verify(flatbuffers::FlatBufferBuilder &fbb, const std::string &expected_name, Color color);
+bool release_n_verify(flatbuffers::grpc::MessageBuilder &mbb, const std::string &expected_name, Color color);
+
+// clang-format off
+#if !defined(FLATBUFFERS_CPP98_STL)
+// clang-format on
+// Invokes this function when testing the following Builder types
+// FlatBufferBuilder, TestHeapBuilder, and GrpcLikeMessageBuilder
+template <class Builder>
+void builder_move_assign_after_releaseraw_test(Builder b1) {
+  auto root_offset1 = populate1(b1);
+  b1.Finish(root_offset1);
+  size_t size, offset;
+  std::shared_ptr<uint8_t> raw(b1.ReleaseRaw(size, offset), [size](uint8_t *ptr) {
+    flatbuffers::DefaultAllocator::dealloc(ptr, size);
+  });
+  Builder src;
+  auto root_offset2 = populate2(src);
+  src.Finish(root_offset2);
+  auto src_size = src.GetSize();
+  // Move into a released builder.
+  b1 = std::move(src);
+  TEST_EQ_FUNC(b1.GetSize(), src_size);
+  TEST_ASSERT_FUNC(release_n_verify(b1, m2_name, m2_color));
+  TEST_EQ_FUNC(src.GetSize(), 0);
+}
+// clang-format off
+#endif  // !defined(FLATBUFFERS_CPP98_STL)
+// clang-format on
+
+void builder_move_assign_after_releaseraw_test(flatbuffers::grpc::MessageBuilder b1);
+
+template <class DestBuilder, class SrcBuilder = DestBuilder>
+struct BuilderTests {
+  // clang-format off
+  #if !defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+  static void empty_builder_movector_test() {
+    SrcBuilder src;
+    size_t src_size = src.GetSize();
+    DestBuilder dst(std::move(src));
+    size_t dst_size = dst.GetSize();
+    TEST_EQ_FUNC(src_size, 0);
+    TEST_EQ_FUNC(src_size, dst_size);
+  }
+
+  static void nonempty_builder_movector_test() {
+    SrcBuilder src;
+    populate1(src);
+    size_t src_size = src.GetSize();
+    DestBuilder dst(std::move(src));
+    TEST_EQ_FUNC(src_size, dst.GetSize());
+    TEST_EQ_FUNC(src.GetSize(), 0);
+  }
+
+  static void builder_movector_before_finish_test() {
+    SrcBuilder src;
+    auto root_offset1 = populate1(src);
+    DestBuilder dst(std::move(src));
+    dst.Finish(root_offset1);
+    TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
+    TEST_EQ_FUNC(src.GetSize(), 0);
+  }
+
+  static void builder_movector_after_finish_test() {
+    SrcBuilder src;
+    auto root_offset1 = populate1(src);
+    src.Finish(root_offset1);
+    auto src_size = src.GetSize();
+    DestBuilder dst(std::move(src));
+    TEST_EQ_FUNC(dst.GetSize(), src_size);
+    TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
+    TEST_EQ_FUNC(src.GetSize(), 0);
+  }
+
+  static void builder_move_assign_before_finish_test() {
+    SrcBuilder src;
+    auto root_offset1 = populate1(src);
+    DestBuilder dst;
+    populate2(dst);
+    dst = std::move(src);
+    dst.Finish(root_offset1);
+    TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
+    TEST_EQ_FUNC(src.GetSize(), 0);
+  }
+
+  static void builder_move_assign_after_finish_test() {
+    SrcBuilder src;
+    auto root_offset1 = populate1(src);
+    src.Finish(root_offset1);
+    auto src_size = src.GetSize();
+    DestBuilder dst;
+    auto root_offset2 = populate2(dst);
+    dst.Finish(root_offset2);
+    dst = std::move(src);
+    TEST_EQ_FUNC(dst.GetSize(), src_size);
+    TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
+    TEST_EQ_FUNC(src.GetSize(), 0);
+  }
+
+  static void builder_move_assign_after_release_test() {
+    DestBuilder dst;
+    auto root_offset1 = populate1(dst);
+    dst.Finish(root_offset1);
+    {
+      flatbuffers::DetachedBuffer dst_detached = dst.Release();
+      // detached buffer is deleted
+    }
+    SrcBuilder src;
+    auto root_offset2 = populate2(src);
+    src.Finish(root_offset2);
+    auto src_size = src.GetSize();
+    // Move into a released builder.
+    dst = std::move(src);
+    TEST_EQ_FUNC(dst.GetSize(), src_size);
+    TEST_ASSERT_FUNC(release_n_verify(dst, m2_name, m2_color));
+    TEST_EQ_FUNC(src.GetSize(), 0);
+  }
+  // clang-format off
+  #endif  // !defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+
+  static void builder_swap_before_finish_test(bool run = is_same<DestBuilder, SrcBuilder>::value) {
+    /// Swap is allowed only when lhs and rhs are the same concrete type.
+    if(run) {
+      SrcBuilder src;
+      auto root_offset1 = populate1(src);
+      auto size1 = src.GetSize();
+      DestBuilder dst;
+      auto root_offset2 = populate2(dst);
+      auto size2 = dst.GetSize();
+      src.Swap(dst);
+      src.Finish(root_offset2);
+      dst.Finish(root_offset1);
+      TEST_EQ_FUNC(src.GetSize() > size2, true);
+      TEST_EQ_FUNC(dst.GetSize() > size1, true);
+      TEST_ASSERT_FUNC(release_n_verify(src, m2_name, m2_color));
+      TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
+    }
+  }
+
+  static void builder_swap_after_finish_test(bool run = is_same<DestBuilder, SrcBuilder>::value) {
+    /// Swap is allowed only when lhs and rhs are the same concrete type.
+    if(run) {
+      SrcBuilder src;
+      auto root_offset1 = populate1(src);
+      src.Finish(root_offset1);
+      auto size1 = src.GetSize();
+      DestBuilder dst;
+      auto root_offset2 = populate2(dst);
+      dst.Finish(root_offset2);
+      auto size2 = dst.GetSize();
+      src.Swap(dst);
+      TEST_EQ_FUNC(src.GetSize(), size2);
+      TEST_EQ_FUNC(dst.GetSize(), size1);
+      TEST_ASSERT_FUNC(release_n_verify(src, m2_name, m2_color));
+      TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
+    }
+  }
+
+  static void all_tests() {
+    // clang-format off
+    #if !defined(FLATBUFFERS_CPP98_STL)
+    // clang-format on
+    empty_builder_movector_test();
+    nonempty_builder_movector_test();
+    builder_movector_before_finish_test();
+    builder_movector_after_finish_test();
+    builder_move_assign_before_finish_test();
+    builder_move_assign_after_finish_test();
+    builder_move_assign_after_release_test();
+    builder_move_assign_after_releaseraw_test(DestBuilder());
+    // clang-format off
+    #endif   // !defined(FLATBUFFERS_CPP98_STL)
+    // clang-format on
+    builder_swap_before_finish_test();
+    builder_swap_after_finish_test();
+  }
+};
+
+enum BuilderReuseTestSelector {
+  REUSABLE_AFTER_RELEASE = 1,
+  REUSABLE_AFTER_RELEASE_RAW = 2,
+  REUSABLE_AFTER_RELEASE_MESSAGE = 3,
+  REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN = 4,
+  REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN = 5,
+  REUSABLE_AFTER_RELEASE_MESSAGE_AND_MOVE_ASSIGN = 6
+};
+
+typedef std::set<BuilderReuseTestSelector> TestSelector;
+
+template <class DestBuilder, class SrcBuilder>
+struct BuilderReuseTests {
+  static void builder_reusable_after_release_test(TestSelector selector) {
+    if (!selector.count(REUSABLE_AFTER_RELEASE)) {
+      return;
+    }
+
+    DestBuilder fbb;
+    std::vector<flatbuffers::DetachedBuffer> buffers;
+    for (int i = 0; i < 5; ++i) {
+      auto root_offset1 = populate1(fbb);
+      fbb.Finish(root_offset1);
+      buffers.push_back(fbb.Release());
+      TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
+    }
+  }
+
+  static void builder_reusable_after_releaseraw_test(TestSelector selector) {
+    if (!selector.count(REUSABLE_AFTER_RELEASE_RAW)) {
+      return;
+    }
+
+    DestBuilder fbb;
+    for (int i = 0; i < 5; ++i) {
+      auto root_offset1 = populate1(fbb);
+      fbb.Finish(root_offset1);
+      size_t size, offset;
+      uint8_t *buf = release_raw_base(fbb, size, offset);
+      TEST_ASSERT_FUNC(verify(buf, offset, m1_name, m1_color));
+      free_raw(fbb, buf);
+    }
+  }
+
+  // clang-format off
+  #if !defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+  static void builder_reusable_after_release_and_move_assign_test(TestSelector selector) {
+    if (!selector.count(REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN)) {
+      return;
+    }
+
+    DestBuilder dst;
+    std::vector<flatbuffers::DetachedBuffer> buffers;
+    for (int i = 0; i < 5; ++i) {
+      auto root_offset1 = populate1(dst);
+      dst.Finish(root_offset1);
+      buffers.push_back(dst.Release());
+      TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
+      SrcBuilder src;
+      dst = std::move(src);
+      TEST_EQ_FUNC(src.GetSize(), 0);
+    }
+  }
+
+  static void builder_reusable_after_releaseraw_and_move_assign_test(TestSelector selector) {
+    if (!selector.count(REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN)) {
+      return;
+    }
+
+    DestBuilder dst;
+    for (int i = 0; i < 5; ++i) {
+      auto root_offset1 = populate1(dst);
+      dst.Finish(root_offset1);
+      size_t size, offset;
+      uint8_t *buf = release_raw_base(dst, size, offset);
+      TEST_ASSERT_FUNC(verify(buf, offset, m1_name, m1_color));
+      free_raw(dst, buf);
+      SrcBuilder src;
+      dst = std::move(src);
+      TEST_EQ_FUNC(src.GetSize(), 0);
+    }
+  }
+  // clang-format off
+  #endif  // !defined(FLATBUFFERS_CPP98_STL)
+  // clang-format on
+
+  static void run_tests(TestSelector selector) {
+    builder_reusable_after_release_test(selector);
+    builder_reusable_after_releaseraw_test(selector);
+    // clang-format off
+    #if !defined(FLATBUFFERS_CPP98_STL)
+    // clang-format on
+    builder_reusable_after_release_and_move_assign_test(selector);
+    builder_reusable_after_releaseraw_and_move_assign_test(selector);
+    // clang-format off
+    #endif  // !defined(FLATBUFFERS_CPP98_STL)
+    // clang-format on
+  }
+};
+
+#endif // TEST_BUILDER_H
diff --git a/third_party/flatbuffers/tests/unicode_test.json b/third_party/flatbuffers/tests/unicode_test.json
new file mode 100644
index 0000000..2894f0c
--- /dev/null
+++ b/third_party/flatbuffers/tests/unicode_test.json
@@ -0,0 +1,31 @@
+{
+  "name": "unicode_test",
+  "testarrayofstring": [
+    "Цлїςσδε",
+    "ﾌﾑｱﾑｶﾓｹﾓ",
+    "フムヤムカモケモ",
+    "㊀㊁㊂㊃㊄",
+    "☳☶☲",
+    "𡇙𝌆"
+  ],
+  "testarrayoftables": [
+    {
+      "name": "Цлїςσδε"
+    },
+    {
+      "name": "ﾌﾑｱﾑｶﾓｹﾓ"
+    },
+    {
+      "name": "フムヤムカモケモ"
+    },
+    {
+      "name": "㊀㊁㊂㊃㊄"
+    },
+    {
+      "name": "☳☶☲"
+    },
+    {
+      "name": "𡇙𝌆"
+    }
+  ]
+}
diff --git a/third_party/flatbuffers/tests/union_vector/Attacker.cs b/third_party/flatbuffers/tests/union_vector/Attacker.cs
new file mode 100644
index 0000000..0e3300a
--- /dev/null
+++ b/third_party/flatbuffers/tests/union_vector/Attacker.cs
@@ -0,0 +1,35 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+using global::System;
+using global::FlatBuffers;
+
+public struct Attacker : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static Attacker GetRootAsAttacker(ByteBuffer _bb) { return GetRootAsAttacker(_bb, new Attacker()); }
+  public static Attacker GetRootAsAttacker(ByteBuffer _bb, Attacker obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public Attacker __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public int SwordAttackDamage { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } }
+  public bool MutateSwordAttackDamage(int sword_attack_damage) { int o = __p.__offset(4); if (o != 0) { __p.bb.PutInt(o + __p.bb_pos, sword_attack_damage); return true; } else { return false; } }
+
+  public static Offset<Attacker> CreateAttacker(FlatBufferBuilder builder,
+      int sword_attack_damage = 0) {
+    builder.StartTable(1);
+    Attacker.AddSwordAttackDamage(builder, sword_attack_damage);
+    return Attacker.EndAttacker(builder);
+  }
+
+  public static void StartAttacker(FlatBufferBuilder builder) { builder.StartTable(1); }
+  public static void AddSwordAttackDamage(FlatBufferBuilder builder, int swordAttackDamage) { builder.AddInt(0, swordAttackDamage, 0); }
+  public static Offset<Attacker> EndAttacker(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<Attacker>(o);
+  }
+};
+
diff --git a/third_party/flatbuffers/tests/union_vector/Attacker.java b/third_party/flatbuffers/tests/union_vector/Attacker.java
new file mode 100644
index 0000000..afe6945
--- /dev/null
+++ b/third_party/flatbuffers/tests/union_vector/Attacker.java
@@ -0,0 +1,33 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class Attacker extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static Attacker getRootAsAttacker(ByteBuffer _bb) { return getRootAsAttacker(_bb, new Attacker()); }
+  public static Attacker getRootAsAttacker(ByteBuffer _bb, Attacker obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public Attacker __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public int swordAttackDamage() { int o = __offset(4); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
+  public boolean mutateSwordAttackDamage(int sword_attack_damage) { int o = __offset(4); if (o != 0) { bb.putInt(o + bb_pos, sword_attack_damage); return true; } else { return false; } }
+
+  public static int createAttacker(FlatBufferBuilder builder,
+      int sword_attack_damage) {
+    builder.startTable(1);
+    Attacker.addSwordAttackDamage(builder, sword_attack_damage);
+    return Attacker.endAttacker(builder);
+  }
+
+  public static void startAttacker(FlatBufferBuilder builder) { builder.startTable(1); }
+  public static void addSwordAttackDamage(FlatBufferBuilder builder, int swordAttackDamage) { builder.addInt(0, swordAttackDamage, 0); }
+  public static int endAttacker(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+}
+
diff --git a/third_party/flatbuffers/tests/union_vector/Attacker.kt b/third_party/flatbuffers/tests/union_vector/Attacker.kt
new file mode 100644
index 0000000..7d3dc68
--- /dev/null
+++ b/third_party/flatbuffers/tests/union_vector/Attacker.kt
@@ -0,0 +1,51 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Attacker : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : Attacker {
+        __init(_i, _bb)
+        return this
+    }
+    val swordAttackDamage : Int
+        get() {
+            val o = __offset(4)
+            return if(o != 0) bb.getInt(o + bb_pos) else 0
+        }
+    fun mutateSwordAttackDamage(swordAttackDamage: Int) : Boolean {
+        val o = __offset(4)
+        return if (o != 0) {
+            bb.putInt(o + bb_pos, swordAttackDamage)
+            true
+        } else {
+            false
+        }
+    }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsAttacker(_bb: ByteBuffer): Attacker = getRootAsAttacker(_bb, Attacker())
+        fun getRootAsAttacker(_bb: ByteBuffer, obj: Attacker): Attacker {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun createAttacker(builder: FlatBufferBuilder, swordAttackDamage: Int) : Int {
+            builder.startTable(1)
+            addSwordAttackDamage(builder, swordAttackDamage)
+            return endAttacker(builder)
+        }
+        fun startAttacker(builder: FlatBufferBuilder) = builder.startTable(1)
+        fun addSwordAttackDamage(builder: FlatBufferBuilder, swordAttackDamage: Int) = builder.addInt(0, swordAttackDamage, 0)
+        fun endAttacker(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+            return o
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/union_vector/Attacker.php b/third_party/flatbuffers/tests/union_vector/Attacker.php
new file mode 100644
index 0000000..e3ebfe6
--- /dev/null
+++ b/third_party/flatbuffers/tests/union_vector/Attacker.php
@@ -0,0 +1,92 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class Attacker extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return Attacker
+     */
+    public static function getRootAsAttacker(ByteBuffer $bb)
+    {
+        $obj = new Attacker();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    public static function AttackerIdentifier()
+    {
+        return "MOVI";
+    }
+
+    public static function AttackerBufferHasIdentifier(ByteBuffer $buf)
+    {
+        return self::__has_identifier($buf, self::AttackerIdentifier());
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return Attacker
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @return int
+     */
+    public function getSwordAttackDamage()
+    {
+        $o = $this->__offset(4);
+        return $o != 0 ? $this->bb->getInt($o + $this->bb_pos) : 0;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startAttacker(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(1);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return Attacker
+     */
+    public static function createAttacker(FlatBufferBuilder $builder, $sword_attack_damage)
+    {
+        $builder->startObject(1);
+        self::addSwordAttackDamage($builder, $sword_attack_damage);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int
+     * @return void
+     */
+    public static function addSwordAttackDamage(FlatBufferBuilder $builder, $swordAttackDamage)
+    {
+        $builder->addIntX(0, $swordAttackDamage, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endAttacker(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+}
diff --git a/third_party/flatbuffers/tests/union_vector/BookReader.cs b/third_party/flatbuffers/tests/union_vector/BookReader.cs
new file mode 100644
index 0000000..53fe736
--- /dev/null
+++ b/third_party/flatbuffers/tests/union_vector/BookReader.cs
@@ -0,0 +1,24 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+using global::System;
+using global::FlatBuffers;
+
+public struct BookReader : IFlatbufferObject
+{
+  private Struct __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
+  public BookReader __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public int BooksRead { get { return __p.bb.GetInt(__p.bb_pos + 0); } }
+  public void MutateBooksRead(int books_read) { __p.bb.PutInt(__p.bb_pos + 0, books_read); }
+
+  public static Offset<BookReader> CreateBookReader(FlatBufferBuilder builder, int BooksRead) {
+    builder.Prep(4, 4);
+    builder.PutInt(BooksRead);
+    return new Offset<BookReader>(builder.Offset);
+  }
+};
+
diff --git a/third_party/flatbuffers/tests/union_vector/BookReader.java b/third_party/flatbuffers/tests/union_vector/BookReader.java
new file mode 100644
index 0000000..20ff9e2
--- /dev/null
+++ b/third_party/flatbuffers/tests/union_vector/BookReader.java
@@ -0,0 +1,22 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class BookReader extends Struct {
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public BookReader __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public int booksRead() { return bb.getInt(bb_pos + 0); }
+  public void mutateBooksRead(int books_read) { bb.putInt(bb_pos + 0, books_read); }
+
+  public static int createBookReader(FlatBufferBuilder builder, int booksRead) {
+    builder.prep(4, 4);
+    builder.putInt(booksRead);
+    return builder.offset();
+  }
+}
+
diff --git a/third_party/flatbuffers/tests/union_vector/BookReader.kt b/third_party/flatbuffers/tests/union_vector/BookReader.kt
new file mode 100644
index 0000000..fc41473
--- /dev/null
+++ b/third_party/flatbuffers/tests/union_vector/BookReader.kt
@@ -0,0 +1,27 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class BookReader : Struct() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : BookReader {
+        __init(_i, _bb)
+        return this
+    }
+    val booksRead : Int get() = bb.getInt(bb_pos + 0)
+    fun mutateBooksRead(booksRead: Int) : ByteBuffer = bb.putInt(bb_pos + 0, booksRead)
+    companion object {
+        fun createBookReader(builder: FlatBufferBuilder, booksRead: Int) : Int {
+            builder.prep(4, 4)
+            builder.putInt(booksRead)
+            return builder.offset()
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/union_vector/BookReader.php b/third_party/flatbuffers/tests/union_vector/BookReader.php
new file mode 100644
index 0000000..1f8f8d8
--- /dev/null
+++ b/third_party/flatbuffers/tests/union_vector/BookReader.php
@@ -0,0 +1,41 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class BookReader extends Struct
+{
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return BookReader
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @return int
+     */
+    public function GetBooksRead()
+    {
+        return $this->bb->getInt($this->bb_pos + 0);
+    }
+
+
+    /**
+     * @return int offset
+     */
+    public static function createBookReader(FlatBufferBuilder $builder, $booksRead)
+    {
+        $builder->prep(4, 4);
+        $builder->putInt($booksRead);
+        return $builder->offset();
+    }
+}
diff --git a/third_party/flatbuffers/tests/union_vector/Character.cs b/third_party/flatbuffers/tests/union_vector/Character.cs
new file mode 100644
index 0000000..73a5cba
--- /dev/null
+++ b/third_party/flatbuffers/tests/union_vector/Character.cs
@@ -0,0 +1,15 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+public enum Character : byte
+{
+  NONE = 0,
+  MuLan = 1,
+  Rapunzel = 2,
+  Belle = 3,
+  BookFan = 4,
+  Other = 5,
+  Unused = 6,
+};
+
diff --git a/third_party/flatbuffers/tests/union_vector/Character.java b/third_party/flatbuffers/tests/union_vector/Character.java
new file mode 100644
index 0000000..5d6c5b7
--- /dev/null
+++ b/third_party/flatbuffers/tests/union_vector/Character.java
@@ -0,0 +1,17 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+public final class Character {
+  private Character() { }
+  public static final byte NONE = 0;
+  public static final byte MuLan = 1;
+  public static final byte Rapunzel = 2;
+  public static final byte Belle = 3;
+  public static final byte BookFan = 4;
+  public static final byte Other = 5;
+  public static final byte Unused = 6;
+
+  public static final String[] names = { "NONE", "MuLan", "Rapunzel", "Belle", "BookFan", "Other", "Unused", };
+
+  public static String name(int e) { return names[e]; }
+}
+
diff --git a/third_party/flatbuffers/tests/union_vector/Character.kt b/third_party/flatbuffers/tests/union_vector/Character.kt
new file mode 100644
index 0000000..ff7dd5e
--- /dev/null
+++ b/third_party/flatbuffers/tests/union_vector/Character.kt
@@ -0,0 +1,17 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Character_ private constructor() {
+    companion object {
+        const val NONE: UByte = 0u
+        const val MuLan: UByte = 1u
+        const val Rapunzel: UByte = 2u
+        const val Belle: UByte = 3u
+        const val BookFan: UByte = 4u
+        const val Other: UByte = 5u
+        const val Unused: UByte = 6u
+        val names : Array<String> = arrayOf("NONE", "MuLan", "Rapunzel", "Belle", "BookFan", "Other", "Unused")
+        fun name(e: Int) : String = names[e]
+    }
+}
diff --git a/third_party/flatbuffers/tests/union_vector/Character.php b/third_party/flatbuffers/tests/union_vector/Character.php
new file mode 100644
index 0000000..755958b
--- /dev/null
+++ b/third_party/flatbuffers/tests/union_vector/Character.php
@@ -0,0 +1,31 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+class Character
+{
+    const NONE = 0;
+    const MuLan = 1;
+    const Rapunzel = 2;
+    const Belle = 3;
+    const BookFan = 4;
+    const Other = 5;
+    const Unused = 6;
+
+    private static $names = array(
+        Character::NONE=>"NONE",
+        Character::MuLan=>"MuLan",
+        Character::Rapunzel=>"Rapunzel",
+        Character::Belle=>"Belle",
+        Character::BookFan=>"BookFan",
+        Character::Other=>"Other",
+        Character::Unused=>"Unused",
+    );
+
+    public static function Name($e)
+    {
+        if (!isset(self::$names[$e])) {
+            throw new \Exception();
+        }
+        return self::$names[$e];
+    }
+}
diff --git a/third_party/flatbuffers/tests/union_vector/Movie.cs b/third_party/flatbuffers/tests/union_vector/Movie.cs
new file mode 100644
index 0000000..13dbfac
--- /dev/null
+++ b/third_party/flatbuffers/tests/union_vector/Movie.cs
@@ -0,0 +1,65 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+using global::System;
+using global::FlatBuffers;
+
+public struct Movie : IFlatbufferObject
+{
+  private Table __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_11_1(); }
+  public static Movie GetRootAsMovie(ByteBuffer _bb) { return GetRootAsMovie(_bb, new Movie()); }
+  public static Movie GetRootAsMovie(ByteBuffer _bb, Movie obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+  public static bool MovieBufferHasIdentifier(ByteBuffer _bb) { return Table.__has_identifier(_bb, "MOVI"); }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+  public Movie __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public Character MainCharacterType { get { int o = __p.__offset(4); return o != 0 ? (Character)__p.bb.Get(o + __p.bb_pos) : Character.NONE; } }
+  public bool MutateMainCharacterType(Character main_character_type) { int o = __p.__offset(4); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)main_character_type); return true; } else { return false; } }
+  public TTable? MainCharacter<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(6); return o != 0 ? (TTable?)__p.__union<TTable>(o) : null; }
+  public Character CharactersType(int j) { int o = __p.__offset(8); return o != 0 ? (Character)__p.bb.Get(__p.__vector(o) + j * 1) : (Character)0; }
+  public int CharactersTypeLength { get { int o = __p.__offset(8); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+  public Span<byte> GetCharactersTypeBytes() { return __p.__vector_as_span(8); }
+#else
+  public ArraySegment<byte>? GetCharactersTypeBytes() { return __p.__vector_as_arraysegment(8); }
+#endif
+  public Character[] GetCharactersTypeArray() { return __p.__vector_as_array<Character>(8); }
+  public bool MutateCharactersType(int j, Character characters_type) { int o = __p.__offset(8); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, (byte)characters_type); return true; } else { return false; } }
+  public TTable? Characters<TTable>(int j) where TTable : struct, IFlatbufferObject { int o = __p.__offset(10); return o != 0 ? (TTable?)__p.__union<TTable>(__p.__vector(o) + j * 4 - __p.bb_pos) : null; }
+  public int CharactersLength { get { int o = __p.__offset(10); return o != 0 ? __p.__vector_len(o) : 0; } }
+
+  public static Offset<Movie> CreateMovie(FlatBufferBuilder builder,
+      Character main_character_type = Character.NONE,
+      int main_characterOffset = 0,
+      VectorOffset characters_typeOffset = default(VectorOffset),
+      VectorOffset charactersOffset = default(VectorOffset)) {
+    builder.StartTable(4);
+    Movie.AddCharacters(builder, charactersOffset);
+    Movie.AddCharactersType(builder, characters_typeOffset);
+    Movie.AddMainCharacter(builder, main_characterOffset);
+    Movie.AddMainCharacterType(builder, main_character_type);
+    return Movie.EndMovie(builder);
+  }
+
+  public static void StartMovie(FlatBufferBuilder builder) { builder.StartTable(4); }
+  public static void AddMainCharacterType(FlatBufferBuilder builder, Character mainCharacterType) { builder.AddByte(0, (byte)mainCharacterType, 0); }
+  public static void AddMainCharacter(FlatBufferBuilder builder, int mainCharacterOffset) { builder.AddOffset(1, mainCharacterOffset, 0); }
+  public static void AddCharactersType(FlatBufferBuilder builder, VectorOffset charactersTypeOffset) { builder.AddOffset(2, charactersTypeOffset.Value, 0); }
+  public static VectorOffset CreateCharactersTypeVector(FlatBufferBuilder builder, Character[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddByte((byte)data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateCharactersTypeVectorBlock(FlatBufferBuilder builder, Character[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); }
+  public static void StartCharactersTypeVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
+  public static void AddCharacters(FlatBufferBuilder builder, VectorOffset charactersOffset) { builder.AddOffset(3, charactersOffset.Value, 0); }
+  public static VectorOffset CreateCharactersVector(FlatBufferBuilder builder, int[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i]); return builder.EndVector(); }
+  public static VectorOffset CreateCharactersVectorBlock(FlatBufferBuilder builder, int[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
+  public static void StartCharactersVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
+  public static Offset<Movie> EndMovie(FlatBufferBuilder builder) {
+    int o = builder.EndTable();
+    return new Offset<Movie>(o);
+  }
+  public static void FinishMovieBuffer(FlatBufferBuilder builder, Offset<Movie> offset) { builder.Finish(offset.Value, "MOVI"); }
+  public static void FinishSizePrefixedMovieBuffer(FlatBufferBuilder builder, Offset<Movie> offset) { builder.FinishSizePrefixed(offset.Value, "MOVI"); }
+};
+
diff --git a/third_party/flatbuffers/tests/union_vector/Movie.java b/third_party/flatbuffers/tests/union_vector/Movie.java
new file mode 100644
index 0000000..0f6a19c
--- /dev/null
+++ b/third_party/flatbuffers/tests/union_vector/Movie.java
@@ -0,0 +1,57 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class Movie extends Table {
+  public static void ValidateVersion() { Constants.FLATBUFFERS_1_11_1(); }
+  public static Movie getRootAsMovie(ByteBuffer _bb) { return getRootAsMovie(_bb, new Movie()); }
+  public static Movie getRootAsMovie(ByteBuffer _bb, Movie obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+  public static boolean MovieBufferHasIdentifier(ByteBuffer _bb) { return __has_identifier(_bb, "MOVI"); }
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public Movie __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public byte mainCharacterType() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 0; }
+  public boolean mutateMainCharacterType(byte main_character_type) { int o = __offset(4); if (o != 0) { bb.put(o + bb_pos, main_character_type); return true; } else { return false; } }
+  public Table mainCharacter(Table obj) { int o = __offset(6); return o != 0 ? __union(obj, o) : null; }
+  public byte charactersType(int j) { int o = __offset(8); return o != 0 ? bb.get(__vector(o) + j * 1) : 0; }
+  public int charactersTypeLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; }
+  public ByteBuffer charactersTypeAsByteBuffer() { return __vector_as_bytebuffer(8, 1); }
+  public ByteBuffer charactersTypeInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 8, 1); }
+  public boolean mutateCharactersType(int j, byte characters_type) { int o = __offset(8); if (o != 0) { bb.put(__vector(o) + j * 1, characters_type); return true; } else { return false; } }
+  public Table characters(Table obj, int j) { int o = __offset(10); return o != 0 ? __union(obj, __vector(o) + j * 4 - bb_pos) : null; }
+  public int charactersLength() { int o = __offset(10); return o != 0 ? __vector_len(o) : 0; }
+
+  public static int createMovie(FlatBufferBuilder builder,
+      byte main_character_type,
+      int main_characterOffset,
+      int characters_typeOffset,
+      int charactersOffset) {
+    builder.startTable(4);
+    Movie.addCharacters(builder, charactersOffset);
+    Movie.addCharactersType(builder, characters_typeOffset);
+    Movie.addMainCharacter(builder, main_characterOffset);
+    Movie.addMainCharacterType(builder, main_character_type);
+    return Movie.endMovie(builder);
+  }
+
+  public static void startMovie(FlatBufferBuilder builder) { builder.startTable(4); }
+  public static void addMainCharacterType(FlatBufferBuilder builder, byte mainCharacterType) { builder.addByte(0, mainCharacterType, 0); }
+  public static void addMainCharacter(FlatBufferBuilder builder, int mainCharacterOffset) { builder.addOffset(1, mainCharacterOffset, 0); }
+  public static void addCharactersType(FlatBufferBuilder builder, int charactersTypeOffset) { builder.addOffset(2, charactersTypeOffset, 0); }
+  public static int createCharactersTypeVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); }
+  public static void startCharactersTypeVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
+  public static void addCharacters(FlatBufferBuilder builder, int charactersOffset) { builder.addOffset(3, charactersOffset, 0); }
+  public static int createCharactersVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
+  public static void startCharactersVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
+  public static int endMovie(FlatBufferBuilder builder) {
+    int o = builder.endTable();
+    return o;
+  }
+  public static void finishMovieBuffer(FlatBufferBuilder builder, int offset) { builder.finish(offset, "MOVI"); }
+  public static void finishSizePrefixedMovieBuffer(FlatBufferBuilder builder, int offset) { builder.finishSizePrefixed(offset, "MOVI"); }
+}
+
diff --git a/third_party/flatbuffers/tests/union_vector/Movie.kt b/third_party/flatbuffers/tests/union_vector/Movie.kt
new file mode 100644
index 0000000..b8a135b
--- /dev/null
+++ b/third_party/flatbuffers/tests/union_vector/Movie.kt
@@ -0,0 +1,114 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Movie : Table() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : Movie {
+        __init(_i, _bb)
+        return this
+    }
+    val mainCharacterType : UByte
+        get() {
+            val o = __offset(4)
+            return if(o != 0) bb.get(o + bb_pos).toUByte() else 0u
+        }
+    fun mutateMainCharacterType(mainCharacterType: UByte) : Boolean {
+        val o = __offset(4)
+        return if (o != 0) {
+            bb.put(o + bb_pos, mainCharacterType.toByte())
+            true
+        } else {
+            false
+        }
+    }
+    fun mainCharacter(obj: Table) : Table? {
+        val o = __offset(6); return if (o != 0) __union(obj, o) else null
+    }
+    fun charactersType(j: Int) : UByte {
+        val o = __offset(8)
+        return if (o != 0) {
+            bb.get(__vector(o) + j * 1).toUByte()
+        } else {
+            0u
+        }
+    }
+    val charactersTypeLength : Int
+        get() {
+            val o = __offset(8); return if (o != 0) __vector_len(o) else 0
+        }
+    val charactersTypeAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(8, 1)
+    fun charactersTypeInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 8, 1)
+    fun mutateCharactersType(j: Int, charactersType: UByte) : Boolean {
+        val o = __offset(8)
+        return if (o != 0) {
+            bb.put(__vector(o) + j * 1, charactersType.toByte())
+            true
+        } else {
+            false
+        }
+    }
+    fun characters(obj: Table, j: Int) : Table? {
+        val o = __offset(10)
+        return if (o != 0) {
+            __union(obj, __vector(o) + j * 4 - bb_pos)
+        } else {
+            null
+        }
+    }
+    val charactersLength : Int
+        get() {
+            val o = __offset(10); return if (o != 0) __vector_len(o) else 0
+        }
+    companion object {
+        fun validateVersion() = Constants.FLATBUFFERS_1_11_1()
+        fun getRootAsMovie(_bb: ByteBuffer): Movie = getRootAsMovie(_bb, Movie())
+        fun getRootAsMovie(_bb: ByteBuffer, obj: Movie): Movie {
+            _bb.order(ByteOrder.LITTLE_ENDIAN)
+            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+        }
+        fun MovieBufferHasIdentifier(_bb: ByteBuffer) : Boolean = __has_identifier(_bb, "MOVI")
+        fun createMovie(builder: FlatBufferBuilder, mainCharacterType: UByte, mainCharacterOffset: Int, charactersTypeOffset: Int, charactersOffset: Int) : Int {
+            builder.startTable(4)
+            addCharacters(builder, charactersOffset)
+            addCharactersType(builder, charactersTypeOffset)
+            addMainCharacter(builder, mainCharacterOffset)
+            addMainCharacterType(builder, mainCharacterType)
+            return endMovie(builder)
+        }
+        fun startMovie(builder: FlatBufferBuilder) = builder.startTable(4)
+        fun addMainCharacterType(builder: FlatBufferBuilder, mainCharacterType: UByte) = builder.addByte(0, mainCharacterType.toByte(), 0)
+        fun addMainCharacter(builder: FlatBufferBuilder, mainCharacter: Int) = builder.addOffset(1, mainCharacter, 0)
+        fun addCharactersType(builder: FlatBufferBuilder, charactersType: Int) = builder.addOffset(2, charactersType, 0)
+        fun createCharactersTypeVector(builder: FlatBufferBuilder, data: UByteArray) : Int {
+            builder.startVector(1, data.size, 1)
+            for (i in data.size - 1 downTo 0) {
+                builder.addByte(data[i].toByte())
+            }
+            return builder.endVector()
+        }
+        fun startCharactersTypeVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(1, numElems, 1)
+        fun addCharacters(builder: FlatBufferBuilder, characters: Int) = builder.addOffset(3, characters, 0)
+        fun createCharactersVector(builder: FlatBufferBuilder, data: IntArray) : Int {
+            builder.startVector(4, data.size, 4)
+            for (i in data.size - 1 downTo 0) {
+                builder.addOffset(data[i])
+            }
+            return builder.endVector()
+        }
+        fun startCharactersVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 4)
+        fun endMovie(builder: FlatBufferBuilder) : Int {
+            val o = builder.endTable()
+            return o
+        }
+        fun finishMovieBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finish(offset, "MOVI")
+        fun finishSizePrefixedMovieBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finishSizePrefixed(offset, "MOVI")
+    }
+}
diff --git a/third_party/flatbuffers/tests/union_vector/Movie.php b/third_party/flatbuffers/tests/union_vector/Movie.php
new file mode 100644
index 0000000..216cd28
--- /dev/null
+++ b/third_party/flatbuffers/tests/union_vector/Movie.php
@@ -0,0 +1,220 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class Movie extends Table
+{
+    /**
+     * @param ByteBuffer $bb
+     * @return Movie
+     */
+    public static function getRootAsMovie(ByteBuffer $bb)
+    {
+        $obj = new Movie();
+        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
+    }
+
+    public static function MovieIdentifier()
+    {
+        return "MOVI";
+    }
+
+    public static function MovieBufferHasIdentifier(ByteBuffer $buf)
+    {
+        return self::__has_identifier($buf, self::MovieIdentifier());
+    }
+
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return Movie
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @return byte
+     */
+    public function getMainCharacterType()
+    {
+        $o = $this->__offset(4);
+        return $o != 0 ? $this->bb->getByte($o + $this->bb_pos) : \Character::NONE;
+    }
+
+    /**
+     * @returnint
+     */
+    public function getMainCharacter($obj)
+    {
+        $o = $this->__offset(6);
+        return $o != 0 ? $this->__union($obj, $o) : null;
+    }
+
+    /**
+     * @param int offset
+     * @return byte
+     */
+    public function getCharactersType($j)
+    {
+        $o = $this->__offset(8);
+        return $o != 0 ? $this->bb->getByte($this->__vector($o) + $j * 1) : \Character::NONE;
+    }
+
+    /**
+     * @return int
+     */
+    public function getCharactersTypeLength()
+    {
+        $o = $this->__offset(8);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @param int offset
+     * @return Table
+     */
+    public function getCharacters($j, $obj)
+    {
+        $o = $this->__offset(10);
+        return $o != 0 ? $this->__union($obj, $this->__vector($o) + $j * 4 - $this->bb_pos) : null;
+    }
+
+    /**
+     * @return int
+     */
+    public function getCharactersLength()
+    {
+        $o = $this->__offset(10);
+        return $o != 0 ? $this->__vector_len($o) : 0;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return void
+     */
+    public static function startMovie(FlatBufferBuilder $builder)
+    {
+        $builder->StartObject(4);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return Movie
+     */
+    public static function createMovie(FlatBufferBuilder $builder, $main_character_type, $main_character, $characters_type, $characters)
+    {
+        $builder->startObject(4);
+        self::addMainCharacterType($builder, $main_character_type);
+        self::addMainCharacter($builder, $main_character);
+        self::addCharactersType($builder, $characters_type);
+        self::addCharacters($builder, $characters);
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param byte
+     * @return void
+     */
+    public static function addMainCharacterType(FlatBufferBuilder $builder, $mainCharacterType)
+    {
+        $builder->addByteX(0, $mainCharacterType, 0);
+    }
+
+    public static function addMainCharacter(FlatBufferBuilder $builder, $offset)
+    {
+        $builder->addOffsetX(1, $offset, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addCharactersType(FlatBufferBuilder $builder, $charactersType)
+    {
+        $builder->addOffsetX(2, $charactersType, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createCharactersTypeVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(1, count($data), 1);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putByte($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startCharactersTypeVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(1, $numElems, 1);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param VectorOffset
+     * @return void
+     */
+    public static function addCharacters(FlatBufferBuilder $builder, $characters)
+    {
+        $builder->addOffsetX(3, $characters, 0);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param array offset array
+     * @return int vector offset
+     */
+    public static function createCharactersVector(FlatBufferBuilder $builder, array $data)
+    {
+        $builder->startVector(4, count($data), 4);
+        for ($i = count($data) - 1; $i >= 0; $i--) {
+            $builder->putOffset($data[$i]);
+        }
+        return $builder->endVector();
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @param int $numElems
+     * @return void
+     */
+    public static function startCharactersVector(FlatBufferBuilder $builder, $numElems)
+    {
+        $builder->startVector(4, $numElems, 4);
+    }
+
+    /**
+     * @param FlatBufferBuilder $builder
+     * @return int table offset
+     */
+    public static function endMovie(FlatBufferBuilder $builder)
+    {
+        $o = $builder->endObject();
+        return $o;
+    }
+
+    public static function finishMovieBuffer(FlatBufferBuilder $builder, $offset)
+    {
+        $builder->finish($offset, "MOVI");
+    }
+}
diff --git a/third_party/flatbuffers/tests/union_vector/Rapunzel.cs b/third_party/flatbuffers/tests/union_vector/Rapunzel.cs
new file mode 100644
index 0000000..cb05d4a
--- /dev/null
+++ b/third_party/flatbuffers/tests/union_vector/Rapunzel.cs
@@ -0,0 +1,24 @@
+// <auto-generated>
+//  automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+using global::System;
+using global::FlatBuffers;
+
+public struct Rapunzel : IFlatbufferObject
+{
+  private Struct __p;
+  public ByteBuffer ByteBuffer { get { return __p.bb; } }
+  public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
+  public Rapunzel __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public int HairLength { get { return __p.bb.GetInt(__p.bb_pos + 0); } }
+  public void MutateHairLength(int hair_length) { __p.bb.PutInt(__p.bb_pos + 0, hair_length); }
+
+  public static Offset<Rapunzel> CreateRapunzel(FlatBufferBuilder builder, int HairLength) {
+    builder.Prep(4, 4);
+    builder.PutInt(HairLength);
+    return new Offset<Rapunzel>(builder.Offset);
+  }
+};
+
diff --git a/third_party/flatbuffers/tests/union_vector/Rapunzel.java b/third_party/flatbuffers/tests/union_vector/Rapunzel.java
new file mode 100644
index 0000000..852c061
--- /dev/null
+++ b/third_party/flatbuffers/tests/union_vector/Rapunzel.java
@@ -0,0 +1,22 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class Rapunzel extends Struct {
+  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+  public Rapunzel __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+  public int hairLength() { return bb.getInt(bb_pos + 0); }
+  public void mutateHairLength(int hair_length) { bb.putInt(bb_pos + 0, hair_length); }
+
+  public static int createRapunzel(FlatBufferBuilder builder, int hairLength) {
+    builder.prep(4, 4);
+    builder.putInt(hairLength);
+    return builder.offset();
+  }
+}
+
diff --git a/third_party/flatbuffers/tests/union_vector/Rapunzel.kt b/third_party/flatbuffers/tests/union_vector/Rapunzel.kt
new file mode 100644
index 0000000..080a7f7
--- /dev/null
+++ b/third_party/flatbuffers/tests/union_vector/Rapunzel.kt
@@ -0,0 +1,27 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Rapunzel : Struct() {
+
+    fun __init(_i: Int, _bb: ByteBuffer)  {
+        __reset(_i, _bb)
+    }
+    fun __assign(_i: Int, _bb: ByteBuffer) : Rapunzel {
+        __init(_i, _bb)
+        return this
+    }
+    val hairLength : Int get() = bb.getInt(bb_pos + 0)
+    fun mutateHairLength(hairLength: Int) : ByteBuffer = bb.putInt(bb_pos + 0, hairLength)
+    companion object {
+        fun createRapunzel(builder: FlatBufferBuilder, hairLength: Int) : Int {
+            builder.prep(4, 4)
+            builder.putInt(hairLength)
+            return builder.offset()
+        }
+    }
+}
diff --git a/third_party/flatbuffers/tests/union_vector/Rapunzel.php b/third_party/flatbuffers/tests/union_vector/Rapunzel.php
new file mode 100644
index 0000000..9842d95
--- /dev/null
+++ b/third_party/flatbuffers/tests/union_vector/Rapunzel.php
@@ -0,0 +1,41 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+use \Google\FlatBuffers\Struct;
+use \Google\FlatBuffers\Table;
+use \Google\FlatBuffers\ByteBuffer;
+use \Google\FlatBuffers\FlatBufferBuilder;
+
+class Rapunzel extends Struct
+{
+    /**
+     * @param int $_i offset
+     * @param ByteBuffer $_bb
+     * @return Rapunzel
+     **/
+    public function init($_i, ByteBuffer $_bb)
+    {
+        $this->bb_pos = $_i;
+        $this->bb = $_bb;
+        return $this;
+    }
+
+    /**
+     * @return int
+     */
+    public function GetHairLength()
+    {
+        return $this->bb->getInt($this->bb_pos + 0);
+    }
+
+
+    /**
+     * @return int offset
+     */
+    public static function createRapunzel(FlatBufferBuilder $builder, $hairLength)
+    {
+        $builder->prep(4, 4);
+        $builder->putInt($hairLength);
+        return $builder->offset();
+    }
+}
diff --git a/third_party/flatbuffers/tests/union_vector/union_vector.fbs b/third_party/flatbuffers/tests/union_vector/union_vector.fbs
new file mode 100644
index 0000000..495076f
--- /dev/null
+++ b/third_party/flatbuffers/tests/union_vector/union_vector.fbs
@@ -0,0 +1,31 @@
+// Demonstrates the ability to have vectors of unions, and also to
+// store structs and strings in unions.
+
+table Attacker {
+  sword_attack_damage: int;
+}
+
+struct Rapunzel {
+  hair_length: int;
+}
+
+struct BookReader {
+  books_read: int;
+}
+
+union Character {
+  MuLan: Attacker,  // Can have name be different from type.
+  Rapunzel,         // Or just both the same, as before.
+  Belle: BookReader,
+  BookFan: BookReader,
+  Other: string,
+  Unused: string
+}
+
+table Movie {
+  main_character: Character;
+  characters: [Character];
+}
+
+root_type Movie;
+file_identifier "MOVI";
diff --git a/third_party/flatbuffers/tests/union_vector/union_vector.json b/third_party/flatbuffers/tests/union_vector/union_vector.json
new file mode 100644
index 0000000..af0c9cb
--- /dev/null
+++ b/third_party/flatbuffers/tests/union_vector/union_vector.json
@@ -0,0 +1,26 @@
+{
+  "main_character_type": "Rapunzel",
+  "main_character": {
+    "hair_length": 6
+  },
+  "characters_type": [
+    "Belle",
+    "MuLan",
+    "BookFan",
+    "Other",
+    "Unused"
+  ],
+  "characters": [
+    {
+      "books_read": 7
+    },
+    {
+      "sword_attack_damage": 5
+    },
+    {
+      "books_read": 2
+    },
+    "Other",
+    "Unused"
+  ]
+}
diff --git a/third_party/flatbuffers/tests/union_vector/union_vector_generated.h b/third_party/flatbuffers/tests/union_vector/union_vector_generated.h
new file mode 100644
index 0000000..150c8f4
--- /dev/null
+++ b/third_party/flatbuffers/tests/union_vector/union_vector_generated.h
@@ -0,0 +1,859 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_UNIONVECTOR_H_
+#define FLATBUFFERS_GENERATED_UNIONVECTOR_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+struct Attacker;
+struct AttackerT;
+
+struct Rapunzel;
+
+struct BookReader;
+
+struct Movie;
+struct MovieT;
+
+bool operator==(const AttackerT &lhs, const AttackerT &rhs);
+bool operator!=(const AttackerT &lhs, const AttackerT &rhs);
+bool operator==(const Rapunzel &lhs, const Rapunzel &rhs);
+bool operator!=(const Rapunzel &lhs, const Rapunzel &rhs);
+bool operator==(const BookReader &lhs, const BookReader &rhs);
+bool operator!=(const BookReader &lhs, const BookReader &rhs);
+bool operator==(const MovieT &lhs, const MovieT &rhs);
+bool operator!=(const MovieT &lhs, const MovieT &rhs);
+
+inline const flatbuffers::TypeTable *AttackerTypeTable();
+
+inline const flatbuffers::TypeTable *RapunzelTypeTable();
+
+inline const flatbuffers::TypeTable *BookReaderTypeTable();
+
+inline const flatbuffers::TypeTable *MovieTypeTable();
+
+enum Character {
+  Character_NONE = 0,
+  Character_MuLan = 1,
+  Character_Rapunzel = 2,
+  Character_Belle = 3,
+  Character_BookFan = 4,
+  Character_Other = 5,
+  Character_Unused = 6,
+  Character_MIN = Character_NONE,
+  Character_MAX = Character_Unused
+};
+
+inline const Character (&EnumValuesCharacter())[7] {
+  static const Character values[] = {
+    Character_NONE,
+    Character_MuLan,
+    Character_Rapunzel,
+    Character_Belle,
+    Character_BookFan,
+    Character_Other,
+    Character_Unused
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesCharacter() {
+  static const char * const names[8] = {
+    "NONE",
+    "MuLan",
+    "Rapunzel",
+    "Belle",
+    "BookFan",
+    "Other",
+    "Unused",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameCharacter(Character e) {
+  if (e < Character_NONE || e > Character_Unused) return "";
+  const size_t index = static_cast<size_t>(e);
+  return EnumNamesCharacter()[index];
+}
+
+struct CharacterUnion {
+  Character type;
+  void *value;
+
+  CharacterUnion() : type(Character_NONE), value(nullptr) {}
+  CharacterUnion(CharacterUnion&& u) FLATBUFFERS_NOEXCEPT :
+    type(Character_NONE), value(nullptr)
+    { std::swap(type, u.type); std::swap(value, u.value); }
+  CharacterUnion(const CharacterUnion &) FLATBUFFERS_NOEXCEPT;
+  CharacterUnion &operator=(const CharacterUnion &u) FLATBUFFERS_NOEXCEPT
+    { CharacterUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; }
+  CharacterUnion &operator=(CharacterUnion &&u) FLATBUFFERS_NOEXCEPT
+    { std::swap(type, u.type); std::swap(value, u.value); return *this; }
+  ~CharacterUnion() { Reset(); }
+
+  void Reset();
+
+  static void *UnPack(const void *obj, Character type, const flatbuffers::resolver_function_t *resolver);
+  flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const;
+
+  AttackerT *AsMuLan() {
+    return type == Character_MuLan ?
+      reinterpret_cast<AttackerT *>(value) : nullptr;
+  }
+  const AttackerT *AsMuLan() const {
+    return type == Character_MuLan ?
+      reinterpret_cast<const AttackerT *>(value) : nullptr;
+  }
+  Rapunzel *AsRapunzel() {
+    return type == Character_Rapunzel ?
+      reinterpret_cast<Rapunzel *>(value) : nullptr;
+  }
+  const Rapunzel *AsRapunzel() const {
+    return type == Character_Rapunzel ?
+      reinterpret_cast<const Rapunzel *>(value) : nullptr;
+  }
+  BookReader *AsBelle() {
+    return type == Character_Belle ?
+      reinterpret_cast<BookReader *>(value) : nullptr;
+  }
+  const BookReader *AsBelle() const {
+    return type == Character_Belle ?
+      reinterpret_cast<const BookReader *>(value) : nullptr;
+  }
+  BookReader *AsBookFan() {
+    return type == Character_BookFan ?
+      reinterpret_cast<BookReader *>(value) : nullptr;
+  }
+  const BookReader *AsBookFan() const {
+    return type == Character_BookFan ?
+      reinterpret_cast<const BookReader *>(value) : nullptr;
+  }
+  std::string *AsOther() {
+    return type == Character_Other ?
+      reinterpret_cast<std::string *>(value) : nullptr;
+  }
+  const std::string *AsOther() const {
+    return type == Character_Other ?
+      reinterpret_cast<const std::string *>(value) : nullptr;
+  }
+  std::string *AsUnused() {
+    return type == Character_Unused ?
+      reinterpret_cast<std::string *>(value) : nullptr;
+  }
+  const std::string *AsUnused() const {
+    return type == Character_Unused ?
+      reinterpret_cast<const std::string *>(value) : nullptr;
+  }
+};
+
+
+inline bool operator==(const CharacterUnion &lhs, const CharacterUnion &rhs) {
+  if (lhs.type != rhs.type) return false;
+  switch (lhs.type) {
+    case Character_NONE: {
+      return true;
+    }
+    case Character_MuLan: {
+      return *(reinterpret_cast<const AttackerT *>(lhs.value)) ==
+             *(reinterpret_cast<const AttackerT *>(rhs.value));
+    }
+    case Character_Rapunzel: {
+      return *(reinterpret_cast<const Rapunzel *>(lhs.value)) ==
+             *(reinterpret_cast<const Rapunzel *>(rhs.value));
+    }
+    case Character_Belle: {
+      return *(reinterpret_cast<const BookReader *>(lhs.value)) ==
+             *(reinterpret_cast<const BookReader *>(rhs.value));
+    }
+    case Character_BookFan: {
+      return *(reinterpret_cast<const BookReader *>(lhs.value)) ==
+             *(reinterpret_cast<const BookReader *>(rhs.value));
+    }
+    case Character_Other: {
+      return *(reinterpret_cast<const std::string *>(lhs.value)) ==
+             *(reinterpret_cast<const std::string *>(rhs.value));
+    }
+    case Character_Unused: {
+      return *(reinterpret_cast<const std::string *>(lhs.value)) ==
+             *(reinterpret_cast<const std::string *>(rhs.value));
+    }
+    default: {
+      return false;
+    }
+  }
+}
+
+inline bool operator!=(const CharacterUnion &lhs, const CharacterUnion &rhs) {
+    return !(lhs == rhs);
+}
+
+bool VerifyCharacter(flatbuffers::Verifier &verifier, const void *obj, Character type);
+bool VerifyCharacterVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Rapunzel FLATBUFFERS_FINAL_CLASS {
+ private:
+  int32_t hair_length_;
+
+ public:
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return RapunzelTypeTable();
+  }
+  Rapunzel() {
+    memset(static_cast<void *>(this), 0, sizeof(Rapunzel));
+  }
+  Rapunzel(int32_t _hair_length)
+      : hair_length_(flatbuffers::EndianScalar(_hair_length)) {
+  }
+  int32_t hair_length() const {
+    return flatbuffers::EndianScalar(hair_length_);
+  }
+  void mutate_hair_length(int32_t _hair_length) {
+    flatbuffers::WriteScalar(&hair_length_, _hair_length);
+  }
+};
+FLATBUFFERS_STRUCT_END(Rapunzel, 4);
+
+inline bool operator==(const Rapunzel &lhs, const Rapunzel &rhs) {
+  return
+      (lhs.hair_length() == rhs.hair_length());
+}
+
+inline bool operator!=(const Rapunzel &lhs, const Rapunzel &rhs) {
+    return !(lhs == rhs);
+}
+
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) BookReader FLATBUFFERS_FINAL_CLASS {
+ private:
+  int32_t books_read_;
+
+ public:
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return BookReaderTypeTable();
+  }
+  BookReader() {
+    memset(static_cast<void *>(this), 0, sizeof(BookReader));
+  }
+  BookReader(int32_t _books_read)
+      : books_read_(flatbuffers::EndianScalar(_books_read)) {
+  }
+  int32_t books_read() const {
+    return flatbuffers::EndianScalar(books_read_);
+  }
+  void mutate_books_read(int32_t _books_read) {
+    flatbuffers::WriteScalar(&books_read_, _books_read);
+  }
+};
+FLATBUFFERS_STRUCT_END(BookReader, 4);
+
+inline bool operator==(const BookReader &lhs, const BookReader &rhs) {
+  return
+      (lhs.books_read() == rhs.books_read());
+}
+
+inline bool operator!=(const BookReader &lhs, const BookReader &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct AttackerT : public flatbuffers::NativeTable {
+  typedef Attacker TableType;
+  int32_t sword_attack_damage;
+  AttackerT()
+      : sword_attack_damage(0) {
+  }
+};
+
+inline bool operator==(const AttackerT &lhs, const AttackerT &rhs) {
+  return
+      (lhs.sword_attack_damage == rhs.sword_attack_damage);
+}
+
+inline bool operator!=(const AttackerT &lhs, const AttackerT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct Attacker FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef AttackerT NativeTableType;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return AttackerTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_SWORD_ATTACK_DAMAGE = 4
+  };
+  int32_t sword_attack_damage() const {
+    return GetField<int32_t>(VT_SWORD_ATTACK_DAMAGE, 0);
+  }
+  bool mutate_sword_attack_damage(int32_t _sword_attack_damage) {
+    return SetField<int32_t>(VT_SWORD_ATTACK_DAMAGE, _sword_attack_damage, 0);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<int32_t>(verifier, VT_SWORD_ATTACK_DAMAGE) &&
+           verifier.EndTable();
+  }
+  AttackerT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(AttackerT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<Attacker> Pack(flatbuffers::FlatBufferBuilder &_fbb, const AttackerT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct AttackerBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_sword_attack_damage(int32_t sword_attack_damage) {
+    fbb_.AddElement<int32_t>(Attacker::VT_SWORD_ATTACK_DAMAGE, sword_attack_damage, 0);
+  }
+  explicit AttackerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  AttackerBuilder &operator=(const AttackerBuilder &);
+  flatbuffers::Offset<Attacker> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Attacker>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Attacker> CreateAttacker(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    int32_t sword_attack_damage = 0) {
+  AttackerBuilder builder_(_fbb);
+  builder_.add_sword_attack_damage(sword_attack_damage);
+  return builder_.Finish();
+}
+
+flatbuffers::Offset<Attacker> CreateAttacker(flatbuffers::FlatBufferBuilder &_fbb, const AttackerT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+struct MovieT : public flatbuffers::NativeTable {
+  typedef Movie TableType;
+  CharacterUnion main_character;
+  std::vector<CharacterUnion> characters;
+  MovieT() {
+  }
+};
+
+inline bool operator==(const MovieT &lhs, const MovieT &rhs) {
+  return
+      (lhs.main_character == rhs.main_character) &&
+      (lhs.characters == rhs.characters);
+}
+
+inline bool operator!=(const MovieT &lhs, const MovieT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct Movie FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef MovieT NativeTableType;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return MovieTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_MAIN_CHARACTER_TYPE = 4,
+    VT_MAIN_CHARACTER = 6,
+    VT_CHARACTERS_TYPE = 8,
+    VT_CHARACTERS = 10
+  };
+  Character main_character_type() const {
+    return static_cast<Character>(GetField<uint8_t>(VT_MAIN_CHARACTER_TYPE, 0));
+  }
+  bool mutate_main_character_type(Character _main_character_type) {
+    return SetField<uint8_t>(VT_MAIN_CHARACTER_TYPE, static_cast<uint8_t>(_main_character_type), 0);
+  }
+  const void *main_character() const {
+    return GetPointer<const void *>(VT_MAIN_CHARACTER);
+  }
+  const Attacker *main_character_as_MuLan() const {
+    return main_character_type() == Character_MuLan ? static_cast<const Attacker *>(main_character()) : nullptr;
+  }
+  const Rapunzel *main_character_as_Rapunzel() const {
+    return main_character_type() == Character_Rapunzel ? static_cast<const Rapunzel *>(main_character()) : nullptr;
+  }
+  const BookReader *main_character_as_Belle() const {
+    return main_character_type() == Character_Belle ? static_cast<const BookReader *>(main_character()) : nullptr;
+  }
+  const BookReader *main_character_as_BookFan() const {
+    return main_character_type() == Character_BookFan ? static_cast<const BookReader *>(main_character()) : nullptr;
+  }
+  const flatbuffers::String *main_character_as_Other() const {
+    return main_character_type() == Character_Other ? static_cast<const flatbuffers::String *>(main_character()) : nullptr;
+  }
+  const flatbuffers::String *main_character_as_Unused() const {
+    return main_character_type() == Character_Unused ? static_cast<const flatbuffers::String *>(main_character()) : nullptr;
+  }
+  void *mutable_main_character() {
+    return GetPointer<void *>(VT_MAIN_CHARACTER);
+  }
+  const flatbuffers::Vector<uint8_t> *characters_type() const {
+    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_CHARACTERS_TYPE);
+  }
+  flatbuffers::Vector<uint8_t> *mutable_characters_type() {
+    return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_CHARACTERS_TYPE);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<void>> *characters() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<void>> *>(VT_CHARACTERS);
+  }
+  flatbuffers::Vector<flatbuffers::Offset<void>> *mutable_characters() {
+    return GetPointer<flatbuffers::Vector<flatbuffers::Offset<void>> *>(VT_CHARACTERS);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<uint8_t>(verifier, VT_MAIN_CHARACTER_TYPE) &&
+           VerifyOffset(verifier, VT_MAIN_CHARACTER) &&
+           VerifyCharacter(verifier, main_character(), main_character_type()) &&
+           VerifyOffset(verifier, VT_CHARACTERS_TYPE) &&
+           verifier.VerifyVector(characters_type()) &&
+           VerifyOffset(verifier, VT_CHARACTERS) &&
+           verifier.VerifyVector(characters()) &&
+           VerifyCharacterVector(verifier, characters(), characters_type()) &&
+           verifier.EndTable();
+  }
+  MovieT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(MovieT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<Movie> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MovieT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct MovieBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_main_character_type(Character main_character_type) {
+    fbb_.AddElement<uint8_t>(Movie::VT_MAIN_CHARACTER_TYPE, static_cast<uint8_t>(main_character_type), 0);
+  }
+  void add_main_character(flatbuffers::Offset<void> main_character) {
+    fbb_.AddOffset(Movie::VT_MAIN_CHARACTER, main_character);
+  }
+  void add_characters_type(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> characters_type) {
+    fbb_.AddOffset(Movie::VT_CHARACTERS_TYPE, characters_type);
+  }
+  void add_characters(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<void>>> characters) {
+    fbb_.AddOffset(Movie::VT_CHARACTERS, characters);
+  }
+  explicit MovieBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  MovieBuilder &operator=(const MovieBuilder &);
+  flatbuffers::Offset<Movie> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Movie>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Movie> CreateMovie(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    Character main_character_type = Character_NONE,
+    flatbuffers::Offset<void> main_character = 0,
+    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> characters_type = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<void>>> characters = 0) {
+  MovieBuilder builder_(_fbb);
+  builder_.add_characters(characters);
+  builder_.add_characters_type(characters_type);
+  builder_.add_main_character(main_character);
+  builder_.add_main_character_type(main_character_type);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Movie> CreateMovieDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    Character main_character_type = Character_NONE,
+    flatbuffers::Offset<void> main_character = 0,
+    const std::vector<uint8_t> *characters_type = nullptr,
+    const std::vector<flatbuffers::Offset<void>> *characters = nullptr) {
+  auto characters_type__ = characters_type ? _fbb.CreateVector<uint8_t>(*characters_type) : 0;
+  auto characters__ = characters ? _fbb.CreateVector<flatbuffers::Offset<void>>(*characters) : 0;
+  return CreateMovie(
+      _fbb,
+      main_character_type,
+      main_character,
+      characters_type__,
+      characters__);
+}
+
+flatbuffers::Offset<Movie> CreateMovie(flatbuffers::FlatBufferBuilder &_fbb, const MovieT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+inline AttackerT *Attacker::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = new AttackerT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+inline void Attacker::UnPackTo(AttackerT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = sword_attack_damage(); _o->sword_attack_damage = _e; };
+}
+
+inline flatbuffers::Offset<Attacker> Attacker::Pack(flatbuffers::FlatBufferBuilder &_fbb, const AttackerT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateAttacker(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<Attacker> CreateAttacker(flatbuffers::FlatBufferBuilder &_fbb, const AttackerT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const AttackerT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _sword_attack_damage = _o->sword_attack_damage;
+  return CreateAttacker(
+      _fbb,
+      _sword_attack_damage);
+}
+
+inline MovieT *Movie::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = new MovieT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+inline void Movie::UnPackTo(MovieT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = main_character_type(); _o->main_character.type = _e; };
+  { auto _e = main_character(); if (_e) _o->main_character.value = CharacterUnion::UnPack(_e, main_character_type(), _resolver); };
+  { auto _e = characters_type(); if (_e) { _o->characters.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->characters[_i].type = static_cast<Character>(_e->Get(_i)); } } };
+  { auto _e = characters(); if (_e) { _o->characters.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->characters[_i].value = CharacterUnion::UnPack(_e->Get(_i), characters_type()->GetEnum<Character>(_i), _resolver); } } };
+}
+
+inline flatbuffers::Offset<Movie> Movie::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MovieT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateMovie(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<Movie> CreateMovie(flatbuffers::FlatBufferBuilder &_fbb, const MovieT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const MovieT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _main_character_type = _o->main_character.type;
+  auto _main_character = _o->main_character.Pack(_fbb);
+  auto _characters_type = _o->characters.size() ? _fbb.CreateVector<uint8_t>(_o->characters.size(), [](size_t i, _VectorArgs *__va) { return static_cast<uint8_t>(__va->__o->characters[i].type); }, &_va) : 0;
+  auto _characters = _o->characters.size() ? _fbb.CreateVector<flatbuffers::Offset<void>>(_o->characters.size(), [](size_t i, _VectorArgs *__va) { return __va->__o->characters[i].Pack(*__va->__fbb, __va->__rehasher); }, &_va) : 0;
+  return CreateMovie(
+      _fbb,
+      _main_character_type,
+      _main_character,
+      _characters_type,
+      _characters);
+}
+
+inline bool VerifyCharacter(flatbuffers::Verifier &verifier, const void *obj, Character type) {
+  switch (type) {
+    case Character_NONE: {
+      return true;
+    }
+    case Character_MuLan: {
+      auto ptr = reinterpret_cast<const Attacker *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    case Character_Rapunzel: {
+      return verifier.Verify<Rapunzel>(static_cast<const uint8_t *>(obj), 0);
+    }
+    case Character_Belle: {
+      return verifier.Verify<BookReader>(static_cast<const uint8_t *>(obj), 0);
+    }
+    case Character_BookFan: {
+      return verifier.Verify<BookReader>(static_cast<const uint8_t *>(obj), 0);
+    }
+    case Character_Other: {
+      auto ptr = reinterpret_cast<const flatbuffers::String *>(obj);
+      return verifier.VerifyString(ptr);
+    }
+    case Character_Unused: {
+      auto ptr = reinterpret_cast<const flatbuffers::String *>(obj);
+      return verifier.VerifyString(ptr);
+    }
+    default: return false;
+  }
+}
+
+inline bool VerifyCharacterVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
+  if (!values || !types) return !values && !types;
+  if (values->size() != types->size()) return false;
+  for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+    if (!VerifyCharacter(
+        verifier,  values->Get(i), types->GetEnum<Character>(i))) {
+      return false;
+    }
+  }
+  return true;
+}
+
+inline void *CharacterUnion::UnPack(const void *obj, Character type, const flatbuffers::resolver_function_t *resolver) {
+  switch (type) {
+    case Character_MuLan: {
+      auto ptr = reinterpret_cast<const Attacker *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    case Character_Rapunzel: {
+      auto ptr = reinterpret_cast<const Rapunzel *>(obj);
+      return new Rapunzel(*ptr);
+    }
+    case Character_Belle: {
+      auto ptr = reinterpret_cast<const BookReader *>(obj);
+      return new BookReader(*ptr);
+    }
+    case Character_BookFan: {
+      auto ptr = reinterpret_cast<const BookReader *>(obj);
+      return new BookReader(*ptr);
+    }
+    case Character_Other: {
+      auto ptr = reinterpret_cast<const flatbuffers::String *>(obj);
+      return new std::string(ptr->c_str(), ptr->size());
+    }
+    case Character_Unused: {
+      auto ptr = reinterpret_cast<const flatbuffers::String *>(obj);
+      return new std::string(ptr->c_str(), ptr->size());
+    }
+    default: return nullptr;
+  }
+}
+
+inline flatbuffers::Offset<void> CharacterUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const {
+  switch (type) {
+    case Character_MuLan: {
+      auto ptr = reinterpret_cast<const AttackerT *>(value);
+      return CreateAttacker(_fbb, ptr, _rehasher).Union();
+    }
+    case Character_Rapunzel: {
+      auto ptr = reinterpret_cast<const Rapunzel *>(value);
+      return _fbb.CreateStruct(*ptr).Union();
+    }
+    case Character_Belle: {
+      auto ptr = reinterpret_cast<const BookReader *>(value);
+      return _fbb.CreateStruct(*ptr).Union();
+    }
+    case Character_BookFan: {
+      auto ptr = reinterpret_cast<const BookReader *>(value);
+      return _fbb.CreateStruct(*ptr).Union();
+    }
+    case Character_Other: {
+      auto ptr = reinterpret_cast<const std::string *>(value);
+      return _fbb.CreateString(*ptr).Union();
+    }
+    case Character_Unused: {
+      auto ptr = reinterpret_cast<const std::string *>(value);
+      return _fbb.CreateString(*ptr).Union();
+    }
+    default: return 0;
+  }
+}
+
+inline CharacterUnion::CharacterUnion(const CharacterUnion &u) FLATBUFFERS_NOEXCEPT : type(u.type), value(nullptr) {
+  switch (type) {
+    case Character_MuLan: {
+      value = new AttackerT(*reinterpret_cast<AttackerT *>(u.value));
+      break;
+    }
+    case Character_Rapunzel: {
+      value = new Rapunzel(*reinterpret_cast<Rapunzel *>(u.value));
+      break;
+    }
+    case Character_Belle: {
+      value = new BookReader(*reinterpret_cast<BookReader *>(u.value));
+      break;
+    }
+    case Character_BookFan: {
+      value = new BookReader(*reinterpret_cast<BookReader *>(u.value));
+      break;
+    }
+    case Character_Other: {
+      value = new std::string(*reinterpret_cast<std::string *>(u.value));
+      break;
+    }
+    case Character_Unused: {
+      value = new std::string(*reinterpret_cast<std::string *>(u.value));
+      break;
+    }
+    default:
+      break;
+  }
+}
+
+inline void CharacterUnion::Reset() {
+  switch (type) {
+    case Character_MuLan: {
+      auto ptr = reinterpret_cast<AttackerT *>(value);
+      delete ptr;
+      break;
+    }
+    case Character_Rapunzel: {
+      auto ptr = reinterpret_cast<Rapunzel *>(value);
+      delete ptr;
+      break;
+    }
+    case Character_Belle: {
+      auto ptr = reinterpret_cast<BookReader *>(value);
+      delete ptr;
+      break;
+    }
+    case Character_BookFan: {
+      auto ptr = reinterpret_cast<BookReader *>(value);
+      delete ptr;
+      break;
+    }
+    case Character_Other: {
+      auto ptr = reinterpret_cast<std::string *>(value);
+      delete ptr;
+      break;
+    }
+    case Character_Unused: {
+      auto ptr = reinterpret_cast<std::string *>(value);
+      delete ptr;
+      break;
+    }
+    default: break;
+  }
+  value = nullptr;
+  type = Character_NONE;
+}
+
+inline const flatbuffers::TypeTable *CharacterTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 0, -1 },
+    { flatbuffers::ET_SEQUENCE, 0, 0 },
+    { flatbuffers::ET_SEQUENCE, 0, 1 },
+    { flatbuffers::ET_SEQUENCE, 0, 2 },
+    { flatbuffers::ET_SEQUENCE, 0, 2 },
+    { flatbuffers::ET_STRING, 0, -1 },
+    { flatbuffers::ET_STRING, 0, -1 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    AttackerTypeTable,
+    RapunzelTypeTable,
+    BookReaderTypeTable
+  };
+  static const char * const names[] = {
+    "NONE",
+    "MuLan",
+    "Rapunzel",
+    "Belle",
+    "BookFan",
+    "Other",
+    "Unused"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_UNION, 7, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *AttackerTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_INT, 0, -1 }
+  };
+  static const char * const names[] = {
+    "sword_attack_damage"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 1, type_codes, nullptr, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *RapunzelTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_INT, 0, -1 }
+  };
+  static const int64_t values[] = { 0, 4 };
+  static const char * const names[] = {
+    "hair_length"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_STRUCT, 1, type_codes, nullptr, values, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *BookReaderTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_INT, 0, -1 }
+  };
+  static const int64_t values[] = { 0, 4 };
+  static const char * const names[] = {
+    "books_read"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_STRUCT, 1, type_codes, nullptr, values, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *MovieTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_UTYPE, 0, 0 },
+    { flatbuffers::ET_SEQUENCE, 0, 0 },
+    { flatbuffers::ET_UTYPE, 1, 0 },
+    { flatbuffers::ET_SEQUENCE, 1, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    CharacterTypeTable
+  };
+  static const char * const names[] = {
+    "main_character_type",
+    "main_character",
+    "characters_type",
+    "characters"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 4, type_codes, type_refs, nullptr, names
+  };
+  return &tt;
+}
+
+inline const Movie *GetMovie(const void *buf) {
+  return flatbuffers::GetRoot<Movie>(buf);
+}
+
+inline const Movie *GetSizePrefixedMovie(const void *buf) {
+  return flatbuffers::GetSizePrefixedRoot<Movie>(buf);
+}
+
+inline Movie *GetMutableMovie(void *buf) {
+  return flatbuffers::GetMutableRoot<Movie>(buf);
+}
+
+inline const char *MovieIdentifier() {
+  return "MOVI";
+}
+
+inline bool MovieBufferHasIdentifier(const void *buf) {
+  return flatbuffers::BufferHasIdentifier(
+      buf, MovieIdentifier());
+}
+
+inline bool VerifyMovieBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifyBuffer<Movie>(MovieIdentifier());
+}
+
+inline bool VerifySizePrefixedMovieBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifySizePrefixedBuffer<Movie>(MovieIdentifier());
+}
+
+inline void FinishMovieBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<Movie> root) {
+  fbb.Finish(root, MovieIdentifier());
+}
+
+inline void FinishSizePrefixedMovieBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<Movie> root) {
+  fbb.FinishSizePrefixed(root, MovieIdentifier());
+}
+
+inline flatbuffers::unique_ptr<MovieT> UnPackMovie(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return flatbuffers::unique_ptr<MovieT>(GetMovie(buf)->UnPack(res));
+}
+
+inline flatbuffers::unique_ptr<MovieT> UnPackSizePrefixedMovie(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return flatbuffers::unique_ptr<MovieT>(GetSizePrefixedMovie(buf)->UnPack(res));
+}
+
+#endif  // FLATBUFFERS_GENERATED_UNIONVECTOR_H_
diff --git a/third_party/flatbuffers/tests/union_vector/union_vector_generated.js b/third_party/flatbuffers/tests/union_vector/union_vector_generated.js
new file mode 100644
index 0000000..406cb2f
--- /dev/null
+++ b/third_party/flatbuffers/tests/union_vector/union_vector_generated.js
@@ -0,0 +1,505 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+/**
+ * @enum {number}
+ */
+var Character = {
+  NONE: 0,
+  MuLan: 1,
+  Rapunzel: 2,
+  Belle: 3,
+  BookFan: 4,
+  Other: 5,
+  Unused: 6
+};
+
+/**
+ * @enum {string}
+ */
+var CharacterName = {
+  0: 'NONE',
+  1: 'MuLan',
+  2: 'Rapunzel',
+  3: 'Belle',
+  4: 'BookFan',
+  5: 'Other',
+  6: 'Unused'
+};
+
+/**
+ * @constructor
+ */
+function Attacker() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+}
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {Attacker}
+ */
+Attacker.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {Attacker=} obj
+ * @returns {Attacker}
+ */
+Attacker.getRootAsAttacker = function(bb, obj) {
+  return (obj || new Attacker).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {Attacker=} obj
+ * @returns {Attacker}
+ */
+Attacker.getSizePrefixedRootAsAttacker = function(bb, obj) {
+  return (obj || new Attacker).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @returns {number}
+ */
+Attacker.prototype.swordAttackDamage = function() {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+  return offset ? this.bb.readInt32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+Attacker.prototype.mutate_sword_attack_damage = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ */
+Attacker.startAttacker = function(builder) {
+  builder.startObject(1);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} swordAttackDamage
+ */
+Attacker.addSwordAttackDamage = function(builder, swordAttackDamage) {
+  builder.addFieldInt32(0, swordAttackDamage, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+Attacker.endAttacker = function(builder) {
+  var offset = builder.endObject();
+  return offset;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} swordAttackDamage
+ * @returns {flatbuffers.Offset}
+ */
+Attacker.createAttacker = function(builder, swordAttackDamage) {
+  Attacker.startAttacker(builder);
+  Attacker.addSwordAttackDamage(builder, swordAttackDamage);
+  return Attacker.endAttacker(builder);
+}
+
+/**
+ * @constructor
+ */
+function Rapunzel() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+}
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {Rapunzel}
+ */
+Rapunzel.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @returns {number}
+ */
+Rapunzel.prototype.hairLength = function() {
+  return this.bb.readInt32(this.bb_pos);
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+Rapunzel.prototype.mutate_hair_length = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 0);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} hair_length
+ * @returns {flatbuffers.Offset}
+ */
+Rapunzel.createRapunzel = function(builder, hair_length) {
+  builder.prep(4, 4);
+  builder.writeInt32(hair_length);
+  return builder.offset();
+};
+
+/**
+ * @constructor
+ */
+function BookReader() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+}
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {BookReader}
+ */
+BookReader.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @returns {number}
+ */
+BookReader.prototype.booksRead = function() {
+  return this.bb.readInt32(this.bb_pos);
+};
+
+/**
+ * @param {number} value
+ * @returns {boolean}
+ */
+BookReader.prototype.mutate_books_read = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 0);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} books_read
+ * @returns {flatbuffers.Offset}
+ */
+BookReader.createBookReader = function(builder, books_read) {
+  builder.prep(4, 4);
+  builder.writeInt32(books_read);
+  return builder.offset();
+};
+
+/**
+ * @constructor
+ */
+function Movie() {
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   */
+  this.bb = null;
+
+  /**
+   * @type {number}
+   */
+  this.bb_pos = 0;
+}
+
+/**
+ * @param {number} i
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {Movie}
+ */
+Movie.prototype.__init = function(i, bb) {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {Movie=} obj
+ * @returns {Movie}
+ */
+Movie.getRootAsMovie = function(bb, obj) {
+  return (obj || new Movie).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {Movie=} obj
+ * @returns {Movie}
+ */
+Movie.getSizePrefixedRootAsMovie = function(bb, obj) {
+  return (obj || new Movie).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @returns {boolean}
+ */
+Movie.bufferHasIdentifier = function(bb) {
+  return bb.__has_identifier('MOVI');
+};
+
+/**
+ * @returns {Character}
+ */
+Movie.prototype.mainCharacterType = function() {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+  return offset ? /** @type {Character} */ (this.bb.readUint8(this.bb_pos + offset)) : Character.NONE;
+};
+
+/**
+ * @param {Character} value
+ * @returns {boolean}
+ */
+Movie.prototype.mutate_main_character_type = function(value) {
+  var offset = this.bb.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param {flatbuffers.Table} obj
+ * @returns {?flatbuffers.Table}
+ */
+Movie.prototype.mainCharacter = function(obj) {
+  var offset = this.bb.__offset(this.bb_pos, 6);
+  return offset ? this.bb.__union(obj, this.bb_pos + offset) : null;
+};
+
+/**
+ * @param {number} index
+ * @returns {Character}
+ */
+Movie.prototype.charactersType = function(index) {
+  var offset = this.bb.__offset(this.bb_pos, 8);
+  return offset ? /** @type {Character} */ (this.bb.readUint8(this.bb.__vector(this.bb_pos + offset) + index)) : /** @type {Character} */ (0);
+};
+
+/**
+ * @returns {number}
+ */
+Movie.prototype.charactersTypeLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 8);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns {Uint8Array}
+ */
+Movie.prototype.charactersTypeArray = function() {
+  var offset = this.bb.__offset(this.bb_pos, 8);
+  return offset ? new Uint8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param {number} index
+ * @param {flatbuffers.Table=} obj
+ * @returns {?flatbuffers.Table}
+ */
+Movie.prototype.characters = function(index, obj) {
+  var offset = this.bb.__offset(this.bb_pos, 10);
+  return offset ? this.bb.__union(obj, this.bb.__vector(this.bb_pos + offset) + index * 4) : null;
+};
+
+/**
+ * @returns {number}
+ */
+Movie.prototype.charactersLength = function() {
+  var offset = this.bb.__offset(this.bb_pos, 10);
+  return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ */
+Movie.startMovie = function(builder) {
+  builder.startObject(4);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Character} mainCharacterType
+ */
+Movie.addMainCharacterType = function(builder, mainCharacterType) {
+  builder.addFieldInt8(0, mainCharacterType, Character.NONE);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} mainCharacterOffset
+ */
+Movie.addMainCharacter = function(builder, mainCharacterOffset) {
+  builder.addFieldOffset(1, mainCharacterOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} charactersTypeOffset
+ */
+Movie.addCharactersType = function(builder, charactersTypeOffset) {
+  builder.addFieldOffset(2, charactersTypeOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<Character>} data
+ * @returns {flatbuffers.Offset}
+ */
+Movie.createCharactersTypeVector = function(builder, data) {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+Movie.startCharactersTypeVector = function(builder, numElems) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} charactersOffset
+ */
+Movie.addCharacters = function(builder, charactersOffset) {
+  builder.addFieldOffset(3, charactersOffset, 0);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Array.<flatbuffers.Offset>} data
+ * @returns {flatbuffers.Offset}
+ */
+Movie.createCharactersVector = function(builder, data) {
+  builder.startVector(4, data.length, 4);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addOffset(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {number} numElems
+ */
+Movie.startCharactersVector = function(builder, numElems) {
+  builder.startVector(4, numElems, 4);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @returns {flatbuffers.Offset}
+ */
+Movie.endMovie = function(builder) {
+  var offset = builder.endObject();
+  return offset;
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} offset
+ */
+Movie.finishMovieBuffer = function(builder, offset) {
+  builder.finish(offset, 'MOVI');
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} offset
+ */
+Movie.finishSizePrefixedMovieBuffer = function(builder, offset) {
+  builder.finish(offset, 'MOVI', true);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
+ * @param {Character} mainCharacterType
+ * @param {flatbuffers.Offset} mainCharacterOffset
+ * @param {flatbuffers.Offset} charactersTypeOffset
+ * @param {flatbuffers.Offset} charactersOffset
+ * @returns {flatbuffers.Offset}
+ */
+Movie.createMovie = function(builder, mainCharacterType, mainCharacterOffset, charactersTypeOffset, charactersOffset) {
+  Movie.startMovie(builder);
+  Movie.addMainCharacterType(builder, mainCharacterType);
+  Movie.addMainCharacter(builder, mainCharacterOffset);
+  Movie.addCharactersType(builder, charactersTypeOffset);
+  Movie.addCharacters(builder, charactersOffset);
+  return Movie.endMovie(builder);
+}
+
+// Exports for Node.js and RequireJS
+this.Character = Character;
+this.CharacterName = CharacterName;
+this.Attacker = Attacker;
+this.Rapunzel = Rapunzel;
+this.BookReader = BookReader;
+this.Movie = Movie;
diff --git a/third_party/flatbuffers/tests/union_vector/union_vector_generated.ts b/third_party/flatbuffers/tests/union_vector/union_vector_generated.ts
new file mode 100644
index 0000000..642f672
--- /dev/null
+++ b/third_party/flatbuffers/tests/union_vector/union_vector_generated.ts
@@ -0,0 +1,442 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+/**
+ * @enum {number}
+ */
+export enum Character{
+  NONE= 0,
+  MuLan= 1,
+  Rapunzel= 2,
+  Belle= 3,
+  BookFan= 4,
+  Other= 5,
+  Unused= 6
+};
+
+/**
+ * @constructor
+ */
+export class Attacker {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns Attacker
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):Attacker {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Attacker= obj
+ * @returns Attacker
+ */
+static getRootAsAttacker(bb:flatbuffers.ByteBuffer, obj?:Attacker):Attacker {
+  return (obj || new Attacker).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Attacker= obj
+ * @returns Attacker
+ */
+static getSizePrefixedRootAsAttacker(bb:flatbuffers.ByteBuffer, obj?:Attacker):Attacker {
+  return (obj || new Attacker).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @returns number
+ */
+swordAttackDamage():number {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+  return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_sword_attack_damage(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ */
+static startAttacker(builder:flatbuffers.Builder) {
+  builder.startObject(1);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number swordAttackDamage
+ */
+static addSwordAttackDamage(builder:flatbuffers.Builder, swordAttackDamage:number) {
+  builder.addFieldInt32(0, swordAttackDamage, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @returns flatbuffers.Offset
+ */
+static endAttacker(builder:flatbuffers.Builder):flatbuffers.Offset {
+  var offset = builder.endObject();
+  return offset;
+};
+
+static createAttacker(builder:flatbuffers.Builder, swordAttackDamage:number):flatbuffers.Offset {
+  Attacker.startAttacker(builder);
+  Attacker.addSwordAttackDamage(builder, swordAttackDamage);
+  return Attacker.endAttacker(builder);
+}
+}
+/**
+ * @constructor
+ */
+export class Rapunzel {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns Rapunzel
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):Rapunzel {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @returns number
+ */
+hairLength():number {
+  return this.bb!.readInt32(this.bb_pos);
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_hair_length(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 0);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number hair_length
+ * @returns flatbuffers.Offset
+ */
+static createRapunzel(builder:flatbuffers.Builder, hair_length: number):flatbuffers.Offset {
+  builder.prep(4, 4);
+  builder.writeInt32(hair_length);
+  return builder.offset();
+};
+
+}
+/**
+ * @constructor
+ */
+export class BookReader {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns BookReader
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):BookReader {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @returns number
+ */
+booksRead():number {
+  return this.bb!.readInt32(this.bb_pos);
+};
+
+/**
+ * @param number value
+ * @returns boolean
+ */
+mutate_books_read(value:number):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 0);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeInt32(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number books_read
+ * @returns flatbuffers.Offset
+ */
+static createBookReader(builder:flatbuffers.Builder, books_read: number):flatbuffers.Offset {
+  builder.prep(4, 4);
+  builder.writeInt32(books_read);
+  return builder.offset();
+};
+
+}
+/**
+ * @constructor
+ */
+export class Movie {
+  bb: flatbuffers.ByteBuffer|null = null;
+
+  bb_pos:number = 0;
+/**
+ * @param number i
+ * @param flatbuffers.ByteBuffer bb
+ * @returns Movie
+ */
+__init(i:number, bb:flatbuffers.ByteBuffer):Movie {
+  this.bb_pos = i;
+  this.bb = bb;
+  return this;
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Movie= obj
+ * @returns Movie
+ */
+static getRootAsMovie(bb:flatbuffers.ByteBuffer, obj?:Movie):Movie {
+  return (obj || new Movie).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Movie= obj
+ * @returns Movie
+ */
+static getSizePrefixedRootAsMovie(bb:flatbuffers.ByteBuffer, obj?:Movie):Movie {
+  return (obj || new Movie).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @returns boolean
+ */
+static bufferHasIdentifier(bb:flatbuffers.ByteBuffer):boolean {
+  return bb.__has_identifier('MOVI');
+};
+
+/**
+ * @returns Character
+ */
+mainCharacterType():Character {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+  return offset ? /**  */ (this.bb!.readUint8(this.bb_pos + offset)) : Character.NONE;
+};
+
+/**
+ * @param Character value
+ * @returns boolean
+ */
+mutate_main_character_type(value:Character):boolean {
+  var offset = this.bb!.__offset(this.bb_pos, 4);
+
+  if (offset === 0) {
+    return false;
+  }
+
+  this.bb!.writeUint8(this.bb_pos + offset, value);
+  return true;
+};
+
+/**
+ * @param flatbuffers.Table obj
+ * @returns ?flatbuffers.Table
+ */
+mainCharacter<T extends flatbuffers.Table>(obj:T):T|null {
+  var offset = this.bb!.__offset(this.bb_pos, 6);
+  return offset ? this.bb!.__union(obj, this.bb_pos + offset) : null;
+};
+
+/**
+ * @param number index
+ * @returns Character
+ */
+charactersType(index: number):Character|null {
+  var offset = this.bb!.__offset(this.bb_pos, 8);
+  return offset ? /**  */ (this.bb!.readUint8(this.bb!.__vector(this.bb_pos + offset) + index)) : /**  */ (0);
+};
+
+/**
+ * @returns number
+ */
+charactersTypeLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 8);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @returns Uint8Array
+ */
+charactersTypeArray():Uint8Array|null {
+  var offset = this.bb!.__offset(this.bb_pos, 8);
+  return offset ? new Uint8Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @param number index
+ * @param flatbuffers.Table= obj
+ * @returns ?flatbuffers.Table
+ */
+characters<T extends flatbuffers.Table>(index: number, obj:T):T|null {
+  var offset = this.bb!.__offset(this.bb_pos, 10);
+  return offset ? this.bb!.__union(obj, this.bb!.__vector(this.bb_pos + offset) + index * 4) : null;
+};
+
+/**
+ * @returns number
+ */
+charactersLength():number {
+  var offset = this.bb!.__offset(this.bb_pos, 10);
+  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ */
+static startMovie(builder:flatbuffers.Builder) {
+  builder.startObject(4);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Character mainCharacterType
+ */
+static addMainCharacterType(builder:flatbuffers.Builder, mainCharacterType:Character) {
+  builder.addFieldInt8(0, mainCharacterType, Character.NONE);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset mainCharacterOffset
+ */
+static addMainCharacter(builder:flatbuffers.Builder, mainCharacterOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(1, mainCharacterOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset charactersTypeOffset
+ */
+static addCharactersType(builder:flatbuffers.Builder, charactersTypeOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(2, charactersTypeOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<Character> data
+ * @returns flatbuffers.Offset
+ */
+static createCharactersTypeVector(builder:flatbuffers.Builder, data:Character[]):flatbuffers.Offset {
+  builder.startVector(1, data.length, 1);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addInt8(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startCharactersTypeVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(1, numElems, 1);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset charactersOffset
+ */
+static addCharacters(builder:flatbuffers.Builder, charactersOffset:flatbuffers.Offset) {
+  builder.addFieldOffset(3, charactersOffset, 0);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param Array.<flatbuffers.Offset> data
+ * @returns flatbuffers.Offset
+ */
+static createCharactersVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
+  builder.startVector(4, data.length, 4);
+  for (var i = data.length - 1; i >= 0; i--) {
+    builder.addOffset(data[i]);
+  }
+  return builder.endVector();
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param number numElems
+ */
+static startCharactersVector(builder:flatbuffers.Builder, numElems:number) {
+  builder.startVector(4, numElems, 4);
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @returns flatbuffers.Offset
+ */
+static endMovie(builder:flatbuffers.Builder):flatbuffers.Offset {
+  var offset = builder.endObject();
+  return offset;
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset offset
+ */
+static finishMovieBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {
+  builder.finish(offset, 'MOVI');
+};
+
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset offset
+ */
+static finishSizePrefixedMovieBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {
+  builder.finish(offset, 'MOVI', true);
+};
+
+static createMovie(builder:flatbuffers.Builder, mainCharacterType:Character, mainCharacterOffset:flatbuffers.Offset, charactersTypeOffset:flatbuffers.Offset, charactersOffset:flatbuffers.Offset):flatbuffers.Offset {
+  Movie.startMovie(builder);
+  Movie.addMainCharacterType(builder, mainCharacterType);
+  Movie.addMainCharacter(builder, mainCharacterOffset);
+  Movie.addCharactersType(builder, charactersTypeOffset);
+  Movie.addCharacters(builder, charactersOffset);
+  return Movie.endMovie(builder);
+}
+}
