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 compatability), you can set fields as `deprecated`, which will prevent
the generation of accessors for this field in the generated code. Be careful
when using `deprecated`, however, as it may break legacy code that used this
accessor.

The `Weapon` table is a sub-table used within our FlatBuffer. It is
used twice: once within the `Monster` table and once within the `Equipment`
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 monster.fbs
  # customize your TS -> JS transpilation
  tsc monster_generated.ts
~~~
</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 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::{get_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::new_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 mosnter, called 'orc'
    local name = builder:CreateString("Orc")

    -- Create a `vector` representing the inventory of the Orc. Each number
    -- could correspond to an item that can be claimed after he is slain.
    -- Note: Since we prepend the bytes, this loop iterates in reverse.
    monster.StartInventoryVector(builder, 10)
    for i=10,1,-1 do
        builder:PrependByte(i)
    end
    local inv = builder:EndVector(10)
~~~
</div>
<div class="language-lobster">
~~~{.lobster}
  // Name of the monster.
  let name = builder.CreateString("Orc")

  // Inventory.
  let inv = builder.MyGame_Sample_MonsterCreateInventoryVector(map(10): _)
~~~
</div>
<div class="language-rust">
~~~{.rs}
  // Name of the Monster.
  let name = builder.create_string("Orc");

  // Inventory.
  let inventory = builder.create_vector(&[0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
~~~
</div>
<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 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.ts` 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::{get_root_as_monster,
                                               Color, Equipment,
                                               Monster, MonsterArgs,
                                               Vec3,
                                               Weapon, WeaponArgs};
~~~
</div>

Then, assuming you have a buffer of bytes received from disk,
network, etc., you can 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 = get_root_as_monster(buf);
~~~
</div>
<div class="language-swift">
~~~{.swift}
  // create a ByteBuffer(:) from an [UInt8] or Data()
  let buf = // Get your data

  // Get an accessor to the root object inside the buffer.
  let monster = Monster.getRootAsMonster(bb: ByteBuffer(bytes: buf))
~~~
</div>

If you look in the generated files from the schema compiler, you will see it generated
accessors for all non-`deprecated` fields. For example:

<div class="language-cpp">
~~~{.cpp}
  auto hp = monster->hp();
  auto mana = monster->mana();
  auto name = monster->name()->c_str();
~~~
</div>
<div class="language-java">
~~~{.java}
  short hp = monster.hp();
  short mana = monster.mana();
  String name = monster.name();
~~~
</div>
<div class="language-kotlin">
~~~{.kt}
  val hp = monster.hp
  val mana = monster.mana
  val name = monster.name
~~~
</div>
<div class="language-csharp">
~~~{.cs}
  // For C#, unlike most other languages support by FlatBuffers, most values (except for
  // vectors and unions) are available as properties instead of accessor methods.
  var hp = monster.Hp
  var mana = monster.Mana
  var name = monster.Name
~~~
</div>
<div class="language-go">
~~~{.go}
  hp := monster.Hp()
  mana := monster.Mana()
  name := string(monster.Name()) // Note: `monster.Name()` returns a byte[].
~~~
</div>
<div class="language-python">
~~~{.py}
  hp = monster.Hp()
  mana = monster.Mana()
  name = monster.Name()
~~~
</div>
<div class="language-javascript">
~~~{.js}
  var hp = monster.hp();
  var mana = monster.mana();
  var name = monster.name();
~~~
</div>
<div class="language-typescript">
~~~{.ts}
  let hp = monster.hp();
  let mana = monster.mana();
  let name = monster.name();
~~~
</div>
<div class="language-php">
~~~{.php}
  $hp = $monster->getHp();
  $mana = $monster->getMana();
  $name = monster->getName();
~~~
</div>
<div class="language-c">
~~~{.c}
  uint16_t hp = ns(Monster_hp(monster));
  uint16_t mana = ns(Monster_mana(monster));
  flatbuffers_string_t name = ns(Monster_name(monster));
~~~
</div>
<div class="language-dart">
~~~{.dart}
  // For Dart, unlike other languages support by FlatBuffers, most values
  // are available as properties instead of accessor methods.
  var hp = monster.hp;
  var mana = monster.mana;
  var name = monster.name;
~~~
</div>
<div class="language-lua">
~~~{.lua}
  local hp = mon:Hp()
  local mana = mon:Mana()
  local name = mon:Name()
~~~
</div>
<div class="language-lobster">
~~~{.lobster}
  let hp = monster.hp
  let mana = monster.mana
  let name = monster.name
~~~
</div>
<div class="language-rust">
~~~{.rs}
  // Get and test some scalar types from the FlatBuffer.
  let hp = monster.hp();
  let mana = monster.mana();
  let name = monster.name();
~~~
</div>
<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

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>
