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>
  <input type="radio" name="language" value="swift">Swift</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">
No sample binary is provided, since JS needs to be transpiled from TypeScript. Please see TypeScript support.
</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>
<div class="language-swift">
[sample_binary.swift](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.swift)
</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`. If unspecified, scalar fields (like `int`,
`uint`, or `float`) will be given a default of `0` while strings and tables will
be given a default of `null`. Another thing to note is the line `friendly:bool =
false (deprecated);`. Since you cannot delete fields from a `table` (to support
backwards compatibility), 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`
union. 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 --ts-flat-files --ts monster.fbs
  # produces ts/js modules and js bundle monster_generated.js
~~~
</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>
<div class="language-swift">
~~~{.sh}
  cd flatbuffers/samples
  ./../flatc --swift 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 Google.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 an example - use your desired module flavor by transpiling from TS. 
  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">
~~~{.ts}
  // 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::{root_as_monster,
                                               Color, Equipment,
                                               Monster, MonsterArgs,
                                               Vec3,
                                               Weapon, WeaponArgs};
~~~
</div>
<div class="language-swift">
~~~{.swift}
  /**
  // make sure that monster_generated.swift is included in your project
  */
  import Flatbuffers

  // typealiases for convenience
  typealias Monster = MyGame1_Sample_Monster
  typealias Weapon = MyGame1_Sample_Weapon
  typealias Color = MyGame1_Sample_Color
  typealias Vec3 = MyGame1_Sample_Vec3
~~~
</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::with_capacity(1024);
~~~
</div>
<div class="language-swift">
~~~{.swift}
  // create a `FlatBufferBuilder`, which will be used to serialize objects
  let builder = FlatBufferBuilder(initialSize: 1024)
~~~
</div>

After creating the `builder`, we can start serializing our data. Before we make
our `orc` Monster, let's 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.Start(builder)
  MyGame.Sample.Weapon.AddName(builder, weapon_one)
  MyGame.Sample.Weapon.AddDamage(builder, 3)
  sword = MyGame.Sample.Weapon.End(builder)

  # Create the second `Weapon` ('Axe').
  MyGame.Sample.Weapon.Start(builder)
  MyGame.Sample.Weapon.AddName(builder, weapon_two)
  MyGame.Sample.Weapon.AddDamage(builder, 5)
  axe = MyGame.Sample.Weapon.End(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">
~~~{.ts}
  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>
<div class="language-swift">
~~~{.swift}
  let weapon1Name = builder.create(string: "Sword")
  let weapon2Name = builder.create(string: "Axe")

  // start creating the weapon by calling startWeapon
  let weapon1Start = Weapon.startWeapon(&builder)
  Weapon.add(name: weapon1Name, &builder)
  Weapon.add(damage: 3, &builder)
  // end the object by passing the start point for the weapon 1
  let sword = Weapon.endWeapon(&builder, start: weapon1Start)

  let weapon2Start = Weapon.startWeapon(&builder)
  Weapon.add(name: weapon2Name, &builder)
  Weapon.add(damage: 5, &builder)
  let axe = Weapon.endWeapon(&builder, start: weapon2Start)
~~~
</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 therein, 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.StartInventoryVector(builder, 10)
  for i in reversed(range(0, 10)):
    builder.PrependByte(i)
  inv = builder.EndVector()
~~~
</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">
~~~{.ts}
  // 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 monster, 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>
<div class="language-swift">
~~~{.swift}
  // Name of the Monster.
  let name = builder.create(string: "Orc")

  // create inventory
  let inventory: [Byte] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  let inventoryOffset = builder.createVector(inventory)
~~~
</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.StartWeaponsVector(builder, 2)
  builder.PrependUOffsetTRelative(axe)
  builder.PrependUOffsetTRelative(sword)
  weapons = builder.EndVector()
~~~
</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>
<div class="language-swift">
~~~{.swift}
  // Create a FlatBuffer `vector` that contains offsets to the sword and axe
  // we created above.
  let weaponsOffset = builder.createVector(ofOffsets: [sword, axe])
~~~
</div>

<br>
Note there are 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.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)
  path = builder.EndVector()
~~~
</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>
<div class="language-swift">
~~~{.swift}
  //
  let points = fbb.createVector(ofStructs: [
    Vec3(x: 1, y: 2, z: 3),
    Vec3(x: 4, y: 5, z: 6)
  ])

  // OR
  var vec3 = [
    Vec3(x: 1, y: 2, z: 3),
    Vec3(x: 4, y: 5, z: 6)
  ]
  Monster.startVectorOfVec3(2, in: &fbb)
  for i in obj {
    _ = create(struct: i)
  }
  let points = fbb.endVector(len: size)
~~~
</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 `Monster.Start()` and `Monster.End()`.
  MyGame.Sample.Monster.Start(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.Color().Red)
  MyGame.Sample.Monster.AddWeapons(builder, weapons)
  MyGame.Sample.Monster.AddEquippedType(
      builder, MyGame.Sample.Equipment.Equipment().Weapon)
  MyGame.Sample.Monster.AddEquipped(builder, axe)
  MyGame.Sample.Monster.AddPath(builder, path)
  orc = MyGame.Sample.Monster.End(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>
<div class="language-swift">
~~~{.swift}
  let orc = Monster.createMonster(
    &builder,
    pos: MyGame_Sample_Vec3(x: 1, y: 2, z: 3),
    hp: 300,
    nameOffset: name,
    inventoryVectorOffset: inventoryOffset,
    color: .red,
    weaponsVectorOffset: weaponsOffset,
    equippedType: .weapon,
    equippedOffset: axe)
~~~
</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 about 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>

<div class="language-swift">
~~~{.swift}
  let start = Monster.startMonster(&builder)
  Monster.add(pos: Vec3(x: 1, y: 2, z: 3), &builder)
  Monster.add(hp: 300, &builder)
  Monster.add(name: name, &builder)
  Monster.addVectorOf(inventory: inventoryOffset, &builder)
  Monster.add(color: .red, &builder)
  Monster.addVectorOf(weapons: weaponsOffset, &builder)
  Monster.add(equippedType: .weapon, &builder)
  Monster.add(equipped: axe, &builder)
  var orc = Monster.endMonster(&builder, start: start)
~~~
</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 of 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()); // 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.AddEquippedType(            # Union type
        builder, MyGame.Sample.Equipment.Equipment().Weapon)
    MyGame.Sample.Monster.AddEquipped(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>
<div class="language-swift">
  ~~~{.swift}
    Monster.add(equippedType: .weapon, builder) // Type of union
    Monster.add(equipped: axe, builder) // 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>
<div class="language-swift">
~~~{.swift}
  // Call `finish(offset:)` to instruct the builder that this monster is complete.
  builder.finish(offset: orc)
~~~
</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>
<div class="language-swift">
~~~{.swift}
  // This must be called after `finish()`.
  // `sizedByteArray` returns the finished buf of type [UInt8].
  let buf = builder.sizedByteArray
  // or you can use to get an object of type Data
  let bufData = ByteBuffer(data: builder.data)
~~~
</div>

Now you can write the bytes to a file or 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.

<div class="language-javascript">
For example, in Node you can simply do:
~~~{.js}
  writeFileSync('monster.bin', buf, 'binary');
~~~
</div>
<div class="language-typescript">
For example, in Node you can simply do:
~~~{.ts}
  writeFileSync('monster.bin', buf, 'binary');
~~~
</div>

#### 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 Google.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 an example - use your desired module flavor by transpiling from TS. 
  var flatbuffers = require('/js/flatbuffers').flatbuffers;
  var MyGame = require('./monster_generated').MyGame; // Generated by `flatc`.

  //--------------------------------------------------------------------------//

  // The following code an example 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">
~~~{.ts}
  // note: import flatbuffers with your desired import method

  // note: the `./monster_generated.js` file was previously generated by `flatc` above using the `monster.fbs` schema
  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::{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 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.GetRootAs(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}
  // the data you just read, as a `Uint8Array`
  // Note that the example here uses `readFileSync` from the built-in `fs` module,
  // but other methods for accessing the file contents will also work.
  var bytes = new Uint8Array(readFileSync('./monsterdata.bin'));

  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}
  // the data you just read, as a `Uint8Array`.
  // Note that the example here uses `readFileSync` from the built-in `fs` module,
  // but other methods for accessing the file contents will also work.
  let bytes = new Uint8Array(readFileSync('./monsterdata.bin'));

  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 = root_as_monster(buf).unwrap();
~~~
</div>
<div class="language-swift">
~~~{.swift}
  // create a ByteBuffer(:) from an [UInt8] or Data()
  var buf = // Get your data
  // Get an accessor to the root object inside the buffer.
  let monster: Monster = try! getCheckedRoot(byteBuffer: &byteBuffer)
  // let monster: Monster = getRoot(byteBuffer: &byteBuffer)
~~~
</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>
<div class="language-swift">
~~~{.swift}
  let hp = monster.hp
  let mana = monster.mana
  let name = monster.name // returns an optional string
~~~
</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>
<div class="language-swift">
~~~{.swift}
  let pos = monster.pos
  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 and 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>
<div class="language-swift">
~~~{.swift}
  // Get a the count of objects in the vector
  let count = monster.inventoryCount

  // get item at index 4
  let object = monster.inventory(at: 4)

  // or you can fetch the entire array
  let inv = monster.inventory
  // inv[4] should equal object
~~~
</div>

For `vector`s of `table`s, you can access the elements like any other vector,
except you 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>
<div class="language-swift">
~~~{.swift}
  // Get the count of weapon objects
  let wepsCount = monster.weaponsCount

  let weapon2 = monster.weapons(at: 1)
  let weaponName = weapon2.name
  let weaponDmg = weapon2.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 weaponName = monster.equipped(new MyGame.Sample.Weapon()).name();     // 'Axe'
    var weaponDamage = 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 weaponName = monster.equipped(new MyGame.Sample.Weapon()).name();     // 'Axe'
    let weaponDamage = 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` if 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>
<div class="language-swift">
~~~{.swift}
  // Get and check if the monster has an equipped item
  if monster.equippedType == .weapon {
    let _weapon = monster.equipped(type: Weapon.self)
    let name = _weapon.name // should return "Axe"
    let dmg = _weapon.damage // should return 5
  }
~~~
</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>
<div class="language-swift">
~~~{.swift}
  let monster = Monster.getRootAsMonster(bb: ByteBuffer(bytes: buf))
  monster.mutate(hp: 10) // mutates a value in a table
  /// to mutate structs in swift you have to use the mutable accessors
  monster.mutablePos.mutate(z: 4) // mutates a value in a struct
  monster.mutate(inventory: 6, at index: 0) // mutates a value in an Scalar array
~~~
</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
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

Let's 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 --binary 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

### Vector of Unions

Some languages support storing unions directly in a vector.

~~~
// File found in tests/union_vector/union_vector.fbs
namespace Example.VectorOfUnions;

// 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];
}
~~~

#### Creating

Analagously to how a union adds two fields to a table a vector of unions creates two different vectors:
one for the union data and one for the data types.

<div class="language-cpp">
C++ supports vectors of unions, but it isn't currently documented.
</div>
<div class="language-typescript">
Typescript supports vectors of unions, but it isn't currently documented.
</div>
<div class="language-php">
PHP supports vectors of unions, but it isn't currently documented.
</div>
<div class="language-java">
Java supports vectors of unions, but it isn't currently documented.
</div>
<div class="language-csharp">
~~~{.cs}
using Google.FlatBuffers;
using Example.VectorOfUnions;

var fbb = new FlatBufferBuilder(100);

var characterTypes = new[]
{
    Character.MuLan,
    Character.Belle,
    Character.Other,
};
var characterTypesOffset = Movie.CreateCharactersTypeVector(fbb, characterTypes);

var characters = new[]
{
    Attacker.CreateAttacker(fbb, 10).Value,
    BookReader.CreateBookReader(fbb, 20).Value,
    fbb.CreateSharedString("Chip").Value,
};
var charactersOffset = Movie.CreateCharactersVector(fbb, characters);

var movieOffset = Movie.CreateMovie(
    fbb,
    Character.Rapunzel,
    rapunzel,
    characterTypesOffset,
    charactersOffset);
Movie.FinishMovieBuffer(fbb, movieOffset);
~~~
</div>
<div class="language-kotlin">
Kotlin supports vectors of unions, but it isn't currently documented.
</div>
<div class="language-swift">
Swift supports vectors of unions, but it isn't currently documented.
</div>

#### Reading
<div class="language-csharp">
~~~{.cs}
var movie = Movie.GetRootAsMovie(fbb.DataBuffer);

for (var i = 0; i <= movie.CharactersLength; i++)
{
  if (movie.CharactersType(i) == Character.MuLan)
  {
    var mulanSwordDamage = movie.Characters<Attacker>(i).Value.SwordAttackDamage;
  }
  else if (movie.CharactersType(i) == Character.Belle)
  {
    var belleBooksRead = movie.Characters<BookReader>(i).Value.BooksRead;
  }
  else if (movie.CharactersType(i) == Character.Other)
  {
    var otherStr = movie.CharactersAsString(i);
  }
}
~~~
</div>

### Further Reading

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](@ref flatbuffers_guide_use_java)
</div>
<div class="language-kotlin">
[Use in Kotlin](@ref flatbuffers_guide_use_kotlin)
</div>
<div class="language-csharp">
[Use in C#](@ref flatbuffers_guide_use_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>
<div class="language-swift">
[Use in Swift](@ref flatbuffers_guide_use_swift)
</div>
<br>
