Squashed 'third_party/flatbuffers/' content from commit acc9990ab

Change-Id: I48550d40d78fea996ebe74e9723a5d1f910de491
git-subtree-dir: third_party/flatbuffers
git-subtree-split: acc9990abd2206491480291b0f85f925110102ea
diff --git a/tests/go_test.go b/tests/go_test.go
new file mode 100644
index 0000000..4784705
--- /dev/null
+++ b/tests/go_test.go
@@ -0,0 +1,1889 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package main
+
+import (
+	mygame "MyGame"          // refers to generated code
+	example "MyGame/Example" // refers to generated code
+
+	"bytes"
+	"flag"
+	"fmt"
+	"io/ioutil"
+	"os"
+	"reflect"
+	"sort"
+	"testing"
+
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+
+var (
+	cppData, javaData, outData string
+	fuzz                       bool
+	fuzzFields, fuzzObjects    int
+)
+
+func init() {
+	flag.StringVar(&cppData, "cpp_data", "",
+		"location of monsterdata_test.mon to verify against (required)")
+	flag.StringVar(&javaData, "java_data", "",
+		"location of monsterdata_java_wire.mon to verify against (optional)")
+	flag.StringVar(&outData, "out_data", "",
+		"location to write generated Go data")
+	flag.BoolVar(&fuzz, "fuzz", false, "perform fuzzing")
+	flag.IntVar(&fuzzFields, "fuzz_fields", 4, "fields per fuzzer object")
+	flag.IntVar(&fuzzObjects, "fuzz_objects", 10000,
+		"number of fuzzer objects (higher is slower and more thorough")
+	flag.Parse()
+
+	if cppData == "" {
+		fmt.Fprintf(os.Stderr, "cpp_data argument is required\n")
+		os.Exit(1)
+	}
+}
+
+// Store specific byte patterns in these variables for the fuzzer. These
+// values are taken verbatim from the C++ function FuzzTest1.
+var (
+	overflowingInt32Val = flatbuffers.GetInt32([]byte{0x83, 0x33, 0x33, 0x33})
+	overflowingInt64Val = flatbuffers.GetInt64([]byte{0x84, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44})
+)
+
+// TestAll runs all checks, failing if any errors occur.
+func TestAll(t *testing.T) {
+	// Verify that the Go FlatBuffers runtime library generates the
+	// expected bytes (does not use any schema):
+	CheckByteLayout(t.Fatalf)
+	CheckMutateMethods(t.Fatalf)
+
+	// Verify that panics are raised during exceptional conditions:
+	CheckNotInObjectError(t.Fatalf)
+	CheckStringIsNestedError(t.Fatalf)
+	CheckByteStringIsNestedError(t.Fatalf)
+	CheckStructIsNotInlineError(t.Fatalf)
+	CheckFinishedBytesError(t.Fatalf)
+
+	// Verify that GetRootAs works for non-root tables
+	CheckGetRootAsForNonRootTable(t.Fatalf)
+	CheckTableAccessors(t.Fatalf)
+
+	// Verify that using the generated Go code builds a buffer without
+	// returning errors:
+	generated, off := CheckGeneratedBuild(t.Fatalf)
+
+	// Verify that the buffer generated by Go code is readable by the
+	// generated Go code:
+	CheckReadBuffer(generated, off, t.Fatalf)
+	CheckMutateBuffer(generated, off, t.Fatalf)
+
+	// Verify that the buffer generated by C++ code is readable by the
+	// generated Go code:
+	monsterDataCpp, err := ioutil.ReadFile(cppData)
+	if err != nil {
+		t.Fatal(err)
+	}
+	CheckReadBuffer(monsterDataCpp, 0, t.Fatalf)
+	CheckMutateBuffer(monsterDataCpp, 0, t.Fatalf)
+
+	// Verify that vtables are deduplicated when written:
+	CheckVtableDeduplication(t.Fatalf)
+
+	// Verify the enum names
+	CheckEnumNames(t.Fatalf)
+
+	// Verify enum String methods
+	CheckEnumString(t.Fatalf)
+
+	// Verify the enum values maps
+	CheckEnumValues(t.Fatalf)
+
+	// Verify that the Go code used in FlatBuffers documentation passes
+	// some sanity checks:
+	CheckDocExample(generated, off, t.Fatalf)
+
+	// Check Builder.CreateByteVector
+	CheckCreateByteVector(t.Fatalf)
+
+	// Check a parent namespace import
+	CheckParentNamespace(t.Fatalf)
+
+	// If the filename of the FlatBuffers file generated by the Java test
+	// is given, check that Go code can read it, and that Go code
+	// generates an identical buffer when used to create the example data:
+	if javaData != "" {
+		monsterDataJava, err := ioutil.ReadFile(javaData)
+		if err != nil {
+			t.Fatal(err)
+		}
+		CheckReadBuffer(monsterDataJava, 0, t.Fatalf)
+		CheckByteEquality(generated[off:], monsterDataJava, t.Fatalf)
+	}
+
+	// Verify that various fuzzing scenarios produce a valid FlatBuffer.
+	if fuzz {
+		checkFuzz(fuzzFields, fuzzObjects, t.Fatalf)
+	}
+
+	// Write the generated buffer out to a file:
+	err = ioutil.WriteFile(outData, generated[off:], os.FileMode(0644))
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+// CheckReadBuffer checks that the given buffer is evaluated correctly
+// as the example Monster.
+func CheckReadBuffer(buf []byte, offset flatbuffers.UOffsetT, fail func(string, ...interface{})) {
+	// try the two ways of generating a monster
+	monster1 := example.GetRootAsMonster(buf, offset)
+	monster2 := &example.Monster{}
+	flatbuffers.GetRootAs(buf, offset, monster2)
+	for _, monster := range []*example.Monster{monster1, monster2} {
+		if got := monster.Hp(); 80 != got {
+			fail(FailString("hp", 80, got))
+		}
+
+		// default
+		if got := monster.Mana(); 150 != got {
+			fail(FailString("mana", 150, got))
+		}
+
+		if got := monster.Name(); !bytes.Equal([]byte("MyMonster"), got) {
+			fail(FailString("name", "MyMonster", got))
+		}
+
+		if got := monster.Color(); example.ColorBlue != got {
+			fail(FailString("color", example.ColorBlue, got))
+		}
+
+		if got := monster.Testbool(); true != got {
+			fail(FailString("testbool", true, got))
+		}
+
+		// initialize a Vec3 from Pos()
+		vec := new(example.Vec3)
+		vec = monster.Pos(vec)
+		if vec == nil {
+			fail("vec3 initialization failed")
+		}
+
+		// check that new allocs equal given ones:
+		vec2 := monster.Pos(nil)
+		if !reflect.DeepEqual(vec, vec2) {
+			fail("fresh allocation failed")
+		}
+
+		// verify the properties of the Vec3
+		if got := vec.X(); float32(1.0) != got {
+			fail(FailString("Pos.X", float32(1.0), got))
+		}
+
+		if got := vec.Y(); float32(2.0) != got {
+			fail(FailString("Pos.Y", float32(2.0), got))
+		}
+
+		if got := vec.Z(); float32(3.0) != got {
+			fail(FailString("Pos.Z", float32(3.0), got))
+		}
+
+		if got := vec.Test1(); float64(3.0) != got {
+			fail(FailString("Pos.Test1", float64(3.0), got))
+		}
+
+		if got := vec.Test2(); example.ColorGreen != got {
+			fail(FailString("Pos.Test2", example.ColorGreen, got))
+		}
+
+		// initialize a Test from Test3(...)
+		t := new(example.Test)
+		t = vec.Test3(t)
+		if t == nil {
+			fail("vec.Test3(&t) failed")
+		}
+
+		// check that new allocs equal given ones:
+		t2 := vec.Test3(nil)
+		if !reflect.DeepEqual(t, t2) {
+			fail("fresh allocation failed")
+		}
+
+		// verify the properties of the Test
+		if got := t.A(); int16(5) != got {
+			fail(FailString("t.A()", int16(5), got))
+		}
+
+		if got := t.B(); int8(6) != got {
+			fail(FailString("t.B()", int8(6), got))
+		}
+
+		if got := monster.TestType(); example.AnyMonster != got {
+			fail(FailString("monster.TestType()", example.AnyMonster, got))
+		}
+
+		// initialize a Table from a union field Test(...)
+		var table2 flatbuffers.Table
+		if ok := monster.Test(&table2); !ok {
+			fail("monster.Test(&monster2) failed")
+		}
+
+		// initialize a Monster from the Table from the union
+		var monster2 example.Monster
+		monster2.Init(table2.Bytes, table2.Pos)
+
+		if got := monster2.Name(); !bytes.Equal([]byte("Fred"), got) {
+			fail(FailString("monster2.Name()", "Fred", got))
+		}
+
+		inventorySlice := monster.InventoryBytes()
+		if len(inventorySlice) != monster.InventoryLength() {
+			fail(FailString("len(monster.InventoryBytes) != monster.InventoryLength", len(inventorySlice), monster.InventoryLength()))
+		}
+
+		if got := monster.InventoryLength(); 5 != got {
+			fail(FailString("monster.InventoryLength", 5, got))
+		}
+
+		invsum := 0
+		l := monster.InventoryLength()
+		for i := 0; i < l; i++ {
+			v := monster.Inventory(i)
+			if v != inventorySlice[i] {
+				fail(FailString("monster inventory slice[i] != Inventory(i)", v, inventorySlice[i]))
+			}
+			invsum += int(v)
+		}
+		if invsum != 10 {
+			fail(FailString("monster inventory sum", 10, invsum))
+		}
+
+		if got := monster.Test4Length(); 2 != got {
+			fail(FailString("monster.Test4Length()", 2, got))
+		}
+
+		var test0 example.Test
+		ok := monster.Test4(&test0, 0)
+		if !ok {
+			fail(FailString("monster.Test4(&test0, 0)", true, ok))
+		}
+
+		var test1 example.Test
+		ok = monster.Test4(&test1, 1)
+		if !ok {
+			fail(FailString("monster.Test4(&test1, 1)", true, ok))
+		}
+
+		// the position of test0 and test1 are swapped in monsterdata_java_wire
+		// and monsterdata_test_wire, so ignore ordering
+		v0 := test0.A()
+		v1 := test0.B()
+		v2 := test1.A()
+		v3 := test1.B()
+		sum := int(v0) + int(v1) + int(v2) + int(v3)
+
+		if 100 != sum {
+			fail(FailString("test0 and test1 sum", 100, sum))
+		}
+
+		if got := monster.TestarrayofstringLength(); 2 != got {
+			fail(FailString("Testarrayofstring length", 2, got))
+		}
+
+		if got := monster.Testarrayofstring(0); !bytes.Equal([]byte("test1"), got) {
+			fail(FailString("Testarrayofstring(0)", "test1", got))
+		}
+
+		if got := monster.Testarrayofstring(1); !bytes.Equal([]byte("test2"), got) {
+			fail(FailString("Testarrayofstring(1)", "test2", got))
+		}
+	}
+}
+
+// CheckMutateBuffer checks that the given buffer can be mutated correctly
+// as the example Monster. Only available scalar values are mutated.
+func CheckMutateBuffer(org []byte, offset flatbuffers.UOffsetT, fail func(string, ...interface{})) {
+	// make a copy to mutate
+	buf := make([]byte, len(org))
+	copy(buf, org)
+
+	// load monster data from the buffer
+	monster := example.GetRootAsMonster(buf, offset)
+
+	// test case struct
+	type testcase struct {
+		field  string
+		testfn func() bool
+	}
+
+	testForOriginalValues := []testcase{
+		testcase{"Hp", func() bool { return monster.Hp() == 80 }},
+		testcase{"Mana", func() bool { return monster.Mana() == 150 }},
+		testcase{"Testbool", func() bool { return monster.Testbool() == true }},
+		testcase{"Pos.X'", func() bool { return monster.Pos(nil).X() == float32(1.0) }},
+		testcase{"Pos.Y'", func() bool { return monster.Pos(nil).Y() == float32(2.0) }},
+		testcase{"Pos.Z'", func() bool { return monster.Pos(nil).Z() == float32(3.0) }},
+		testcase{"Pos.Test1'", func() bool { return monster.Pos(nil).Test1() == float64(3.0) }},
+		testcase{"Pos.Test2'", func() bool { return monster.Pos(nil).Test2() == example.ColorGreen }},
+		testcase{"Pos.Test3.A", func() bool { return monster.Pos(nil).Test3(nil).A() == int16(5) }},
+		testcase{"Pos.Test3.B", func() bool { return monster.Pos(nil).Test3(nil).B() == int8(6) }},
+		testcase{"Inventory[2]", func() bool { return monster.Inventory(2) == byte(2) }},
+	}
+
+	testMutability := []testcase{
+		testcase{"Hp", func() bool { return monster.MutateHp(70) }},
+		testcase{"Mana", func() bool { return !monster.MutateMana(140) }},
+		testcase{"Testbool", func() bool { return monster.MutateTestbool(false) }},
+		testcase{"Pos.X", func() bool { return monster.Pos(nil).MutateX(10.0) }},
+		testcase{"Pos.Y", func() bool { return monster.Pos(nil).MutateY(20.0) }},
+		testcase{"Pos.Z", func() bool { return monster.Pos(nil).MutateZ(30.0) }},
+		testcase{"Pos.Test1", func() bool { return monster.Pos(nil).MutateTest1(30.0) }},
+		testcase{"Pos.Test2", func() bool { return monster.Pos(nil).MutateTest2(example.ColorBlue) }},
+		testcase{"Pos.Test3.A", func() bool { return monster.Pos(nil).Test3(nil).MutateA(50) }},
+		testcase{"Pos.Test3.B", func() bool { return monster.Pos(nil).Test3(nil).MutateB(60) }},
+		testcase{"Inventory[2]", func() bool { return monster.MutateInventory(2, 200) }},
+	}
+
+	testForMutatedValues := []testcase{
+		testcase{"Hp", func() bool { return monster.Hp() == 70 }},
+		testcase{"Mana", func() bool { return monster.Mana() == 150 }},
+		testcase{"Testbool", func() bool { return monster.Testbool() == false }},
+		testcase{"Pos.X'", func() bool { return monster.Pos(nil).X() == float32(10.0) }},
+		testcase{"Pos.Y'", func() bool { return monster.Pos(nil).Y() == float32(20.0) }},
+		testcase{"Pos.Z'", func() bool { return monster.Pos(nil).Z() == float32(30.0) }},
+		testcase{"Pos.Test1'", func() bool { return monster.Pos(nil).Test1() == float64(30.0) }},
+		testcase{"Pos.Test2'", func() bool { return monster.Pos(nil).Test2() == example.ColorBlue }},
+		testcase{"Pos.Test3.A", func() bool { return monster.Pos(nil).Test3(nil).A() == int16(50) }},
+		testcase{"Pos.Test3.B", func() bool { return monster.Pos(nil).Test3(nil).B() == int8(60) }},
+		testcase{"Inventory[2]", func() bool { return monster.Inventory(2) == byte(200) }},
+	}
+
+	testInvalidEnumValues := []testcase{
+		testcase{"Pos.Test2", func() bool { return monster.Pos(nil).MutateTest2(example.Color(20)) }},
+		testcase{"Pos.Test2", func() bool { return monster.Pos(nil).Test2() == example.Color(20) }},
+	}
+
+	// make sure original values are okay
+	for _, t := range testForOriginalValues {
+		if !t.testfn() {
+			fail("field '" + t.field + "' doesn't have the expected original value")
+		}
+	}
+
+	// try to mutate fields and check mutability
+	for _, t := range testMutability {
+		if !t.testfn() {
+			fail(FailString("field '"+t.field+"' failed mutability test", true, false))
+		}
+	}
+
+	// test whether values have changed
+	for _, t := range testForMutatedValues {
+		if !t.testfn() {
+			fail("field '" + t.field + "' doesn't have the expected mutated value")
+		}
+	}
+
+	// make sure the buffer has changed
+	if reflect.DeepEqual(buf, org) {
+		fail("mutate buffer failed")
+	}
+
+	// To make sure the buffer has changed accordingly
+	// Read data from the buffer and verify all fields
+	monster = example.GetRootAsMonster(buf, offset)
+	for _, t := range testForMutatedValues {
+		if !t.testfn() {
+			fail("field '" + t.field + "' doesn't have the expected mutated value")
+		}
+	}
+
+	// a couple extra tests for "invalid" enum values, which don't correspond to
+	// anything in the schema, but are allowed
+	for _, t := range testInvalidEnumValues {
+		if !t.testfn() {
+			fail("field '" + t.field + "' doesn't work with an invalid enum value")
+		}
+	}
+
+	// reverting all fields to original values should
+	// re-create the original buffer. Mutate all fields
+	// back to their original values and compare buffers.
+	// This test is done to make sure mutations do not do
+	// any unnecessary changes to the buffer.
+	monster = example.GetRootAsMonster(buf, offset)
+	monster.MutateHp(80)
+	monster.MutateTestbool(true)
+	monster.Pos(nil).MutateX(1.0)
+	monster.Pos(nil).MutateY(2.0)
+	monster.Pos(nil).MutateZ(3.0)
+	monster.Pos(nil).MutateTest1(3.0)
+	monster.Pos(nil).MutateTest2(example.ColorGreen)
+	monster.Pos(nil).Test3(nil).MutateA(5)
+	monster.Pos(nil).Test3(nil).MutateB(6)
+	monster.MutateInventory(2, 2)
+
+	for _, t := range testForOriginalValues {
+		if !t.testfn() {
+			fail("field '" + t.field + "' doesn't have the expected original value")
+		}
+	}
+
+	// buffer should have original values
+	if !reflect.DeepEqual(buf, org) {
+		fail("revert changes failed")
+	}
+}
+
+// Low level stress/fuzz test: serialize/deserialize a variety of
+// different kinds of data in different combinations
+func checkFuzz(fuzzFields, fuzzObjects int, fail func(string, ...interface{})) {
+
+	// Values we're testing against: chosen to ensure no bits get chopped
+	// off anywhere, and also be different from eachother.
+	boolVal := true
+	int8Val := int8(-127) // 0x81
+	uint8Val := uint8(0xFF)
+	int16Val := int16(-32222) // 0x8222
+	uint16Val := uint16(0xFEEE)
+	int32Val := int32(overflowingInt32Val)
+	uint32Val := uint32(0xFDDDDDDD)
+	int64Val := int64(overflowingInt64Val)
+	uint64Val := uint64(0xFCCCCCCCCCCCCCCC)
+	float32Val := float32(3.14159)
+	float64Val := float64(3.14159265359)
+
+	testValuesMax := 11 // hardcoded to the number of scalar types
+
+	builder := flatbuffers.NewBuilder(0)
+	l := NewLCG()
+
+	objects := make([]flatbuffers.UOffsetT, fuzzObjects)
+
+	// Generate fuzzObjects random objects each consisting of
+	// fuzzFields fields, each of a random type.
+	for i := 0; i < fuzzObjects; i++ {
+		builder.StartObject(fuzzFields)
+
+		for f := 0; f < fuzzFields; f++ {
+			choice := l.Next() % uint32(testValuesMax)
+			switch choice {
+			case 0:
+				builder.PrependBoolSlot(int(f), boolVal, false)
+			case 1:
+				builder.PrependInt8Slot(int(f), int8Val, 0)
+			case 2:
+				builder.PrependUint8Slot(int(f), uint8Val, 0)
+			case 3:
+				builder.PrependInt16Slot(int(f), int16Val, 0)
+			case 4:
+				builder.PrependUint16Slot(int(f), uint16Val, 0)
+			case 5:
+				builder.PrependInt32Slot(int(f), int32Val, 0)
+			case 6:
+				builder.PrependUint32Slot(int(f), uint32Val, 0)
+			case 7:
+				builder.PrependInt64Slot(int(f), int64Val, 0)
+			case 8:
+				builder.PrependUint64Slot(int(f), uint64Val, 0)
+			case 9:
+				builder.PrependFloat32Slot(int(f), float32Val, 0)
+			case 10:
+				builder.PrependFloat64Slot(int(f), float64Val, 0)
+			}
+		}
+
+		off := builder.EndObject()
+
+		// store the offset from the end of the builder buffer,
+		// since it will keep growing:
+		objects[i] = off
+	}
+
+	// Do some bookkeeping to generate stats on fuzzes:
+	stats := map[string]int{}
+	check := func(desc string, want, got interface{}) {
+		stats[desc]++
+		if want != got {
+			fail("%s want %v got %v", desc, want, got)
+		}
+	}
+
+	l = NewLCG() // Reset.
+
+	// Test that all objects we generated are readable and return the
+	// expected values. We generate random objects in the same order
+	// so this is deterministic.
+	for i := 0; i < fuzzObjects; i++ {
+
+		table := &flatbuffers.Table{
+			Bytes: builder.Bytes,
+			Pos:   flatbuffers.UOffsetT(len(builder.Bytes)) - objects[i],
+		}
+
+		for j := 0; j < fuzzFields; j++ {
+			f := flatbuffers.VOffsetT((flatbuffers.VtableMetadataFields + j) * flatbuffers.SizeVOffsetT)
+			choice := l.Next() % uint32(testValuesMax)
+
+			switch choice {
+			case 0:
+				check("bool", boolVal, table.GetBoolSlot(f, false))
+			case 1:
+				check("int8", int8Val, table.GetInt8Slot(f, 0))
+			case 2:
+				check("uint8", uint8Val, table.GetUint8Slot(f, 0))
+			case 3:
+				check("int16", int16Val, table.GetInt16Slot(f, 0))
+			case 4:
+				check("uint16", uint16Val, table.GetUint16Slot(f, 0))
+			case 5:
+				check("int32", int32Val, table.GetInt32Slot(f, 0))
+			case 6:
+				check("uint32", uint32Val, table.GetUint32Slot(f, 0))
+			case 7:
+				check("int64", int64Val, table.GetInt64Slot(f, 0))
+			case 8:
+				check("uint64", uint64Val, table.GetUint64Slot(f, 0))
+			case 9:
+				check("float32", float32Val, table.GetFloat32Slot(f, 0))
+			case 10:
+				check("float64", float64Val, table.GetFloat64Slot(f, 0))
+			}
+		}
+	}
+
+	// If enough checks were made, verify that all scalar types were used:
+	if fuzzFields*fuzzObjects >= testValuesMax {
+		if len(stats) != testValuesMax {
+			fail("fuzzing failed to test all scalar types")
+		}
+	}
+
+	// Print some counts, if needed:
+	if testing.Verbose() {
+		if fuzzFields == 0 || fuzzObjects == 0 {
+			fmt.Printf("fuzz\tfields: %d\tobjects: %d\t[none]\t%d\n",
+				fuzzFields, fuzzObjects, 0)
+		} else {
+			keys := make([]string, 0, len(stats))
+			for k := range stats {
+				keys = append(keys, k)
+			}
+			sort.Strings(keys)
+			for _, k := range keys {
+				fmt.Printf("fuzz\tfields: %d\tobjects: %d\t%s\t%d\n",
+					fuzzFields, fuzzObjects, k, stats[k])
+			}
+		}
+	}
+
+	return
+}
+
+// FailString makes a message for when expectations differ from reality.
+func FailString(name string, want, got interface{}) string {
+	return fmt.Sprintf("bad %s: want %#v got %#v", name, want, got)
+}
+
+// CheckByteLayout verifies the bytes of a Builder in various scenarios.
+func CheckByteLayout(fail func(string, ...interface{})) {
+	var b *flatbuffers.Builder
+
+	var i int
+	check := func(want []byte) {
+		i++
+		got := b.Bytes[b.Head():]
+		if !bytes.Equal(want, got) {
+			fail("case %d: want\n%v\nbut got\n%v\n", i, want, got)
+		}
+	}
+
+	// test 1: numbers
+
+	b = flatbuffers.NewBuilder(0)
+	check([]byte{})
+	b.PrependBool(true)
+	check([]byte{1})
+	b.PrependInt8(-127)
+	check([]byte{129, 1})
+	b.PrependUint8(255)
+	check([]byte{255, 129, 1})
+	b.PrependInt16(-32222)
+	check([]byte{0x22, 0x82, 0, 255, 129, 1}) // first pad
+	b.PrependUint16(0xFEEE)
+	check([]byte{0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1}) // no pad this time
+	b.PrependInt32(-53687092)
+	check([]byte{204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1})
+	b.PrependUint32(0x98765432)
+	check([]byte{0x32, 0x54, 0x76, 0x98, 204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1})
+
+	// test 1b: numbers 2
+
+	b = flatbuffers.NewBuilder(0)
+	b.PrependUint64(0x1122334455667788)
+	check([]byte{0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11})
+
+	// test 2: 1xbyte vector
+
+	b = flatbuffers.NewBuilder(0)
+	check([]byte{})
+	b.StartVector(flatbuffers.SizeByte, 1, 1)
+	check([]byte{0, 0, 0}) // align to 4bytes
+	b.PrependByte(1)
+	check([]byte{1, 0, 0, 0})
+	b.EndVector(1)
+	check([]byte{1, 0, 0, 0, 1, 0, 0, 0}) // padding
+
+	// test 3: 2xbyte vector
+
+	b = flatbuffers.NewBuilder(0)
+	b.StartVector(flatbuffers.SizeByte, 2, 1)
+	check([]byte{0, 0}) // align to 4bytes
+	b.PrependByte(1)
+	check([]byte{1, 0, 0})
+	b.PrependByte(2)
+	check([]byte{2, 1, 0, 0})
+	b.EndVector(2)
+	check([]byte{2, 0, 0, 0, 2, 1, 0, 0}) // padding
+
+	// test 3b: 11xbyte vector matches builder size
+
+	b = flatbuffers.NewBuilder(12)
+	b.StartVector(flatbuffers.SizeByte, 8, 1)
+	start := []byte{}
+	check(start)
+	for i := 1; i < 12; i++ {
+		b.PrependByte(byte(i))
+		start = append([]byte{byte(i)}, start...)
+		check(start)
+	}
+	b.EndVector(8)
+	check(append([]byte{8, 0, 0, 0}, start...))
+
+	// test 4: 1xuint16 vector
+
+	b = flatbuffers.NewBuilder(0)
+	b.StartVector(flatbuffers.SizeUint16, 1, 1)
+	check([]byte{0, 0}) // align to 4bytes
+	b.PrependUint16(1)
+	check([]byte{1, 0, 0, 0})
+	b.EndVector(1)
+	check([]byte{1, 0, 0, 0, 1, 0, 0, 0}) // padding
+
+	// test 5: 2xuint16 vector
+
+	b = flatbuffers.NewBuilder(0)
+	b.StartVector(flatbuffers.SizeUint16, 2, 1)
+	check([]byte{}) // align to 4bytes
+	b.PrependUint16(0xABCD)
+	check([]byte{0xCD, 0xAB})
+	b.PrependUint16(0xDCBA)
+	check([]byte{0xBA, 0xDC, 0xCD, 0xAB})
+	b.EndVector(2)
+	check([]byte{2, 0, 0, 0, 0xBA, 0xDC, 0xCD, 0xAB})
+
+	// test 6: CreateString
+
+	b = flatbuffers.NewBuilder(0)
+	b.CreateString("foo")
+	check([]byte{3, 0, 0, 0, 'f', 'o', 'o', 0}) // 0-terminated, no pad
+	b.CreateString("moop")
+	check([]byte{4, 0, 0, 0, 'm', 'o', 'o', 'p', 0, 0, 0, 0, // 0-terminated, 3-byte pad
+		3, 0, 0, 0, 'f', 'o', 'o', 0})
+
+	// test 6b: CreateString unicode
+
+	b = flatbuffers.NewBuilder(0)
+	// These characters are chinese from blog.golang.org/strings
+	// We use escape codes here so that editors without unicode support
+	// aren't bothered:
+	uni_str := "\u65e5\u672c\u8a9e"
+	b.CreateString(uni_str)
+	check([]byte{9, 0, 0, 0, 230, 151, 165, 230, 156, 172, 232, 170, 158, 0, //  null-terminated, 2-byte pad
+		0, 0})
+
+	// test 6c: CreateByteString
+
+	b = flatbuffers.NewBuilder(0)
+	b.CreateByteString([]byte("foo"))
+	check([]byte{3, 0, 0, 0, 'f', 'o', 'o', 0}) // 0-terminated, no pad
+	b.CreateByteString([]byte("moop"))
+	check([]byte{4, 0, 0, 0, 'm', 'o', 'o', 'p', 0, 0, 0, 0, // 0-terminated, 3-byte pad
+		3, 0, 0, 0, 'f', 'o', 'o', 0})
+
+	// test 7: empty vtable
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(0)
+	check([]byte{})
+	b.EndObject()
+	check([]byte{4, 0, 4, 0, 4, 0, 0, 0})
+
+	// test 8: vtable with one true bool
+	b = flatbuffers.NewBuilder(0)
+	check([]byte{})
+	b.StartObject(1)
+	check([]byte{})
+	b.PrependBoolSlot(0, true, false)
+	b.EndObject()
+	check([]byte{
+		6, 0, // vtable bytes
+		8, 0, // length of object including vtable offset
+		7, 0, // start of bool value
+		6, 0, 0, 0, // offset for start of vtable (int32)
+		0, 0, 0, // padded to 4 bytes
+		1, // bool value
+	})
+
+	// test 9: vtable with one default bool
+	b = flatbuffers.NewBuilder(0)
+	check([]byte{})
+	b.StartObject(1)
+	check([]byte{})
+	b.PrependBoolSlot(0, false, false)
+	b.EndObject()
+	check([]byte{
+		4, 0, // vtable bytes
+		4, 0, // end of object from here
+		// entry 1 is zero and not stored.
+		4, 0, 0, 0, // offset for start of vtable (int32)
+	})
+
+	// test 10: vtable with one int16
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(1)
+	b.PrependInt16Slot(0, 0x789A, 0)
+	b.EndObject()
+	check([]byte{
+		6, 0, // vtable bytes
+		8, 0, // end of object from here
+		6, 0, // offset to value
+		6, 0, 0, 0, // offset for start of vtable (int32)
+		0, 0, // padding to 4 bytes
+		0x9A, 0x78,
+	})
+
+	// test 11: vtable with two int16
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(2)
+	b.PrependInt16Slot(0, 0x3456, 0)
+	b.PrependInt16Slot(1, 0x789A, 0)
+	b.EndObject()
+	check([]byte{
+		8, 0, // vtable bytes
+		8, 0, // end of object from here
+		6, 0, // offset to value 0
+		4, 0, // offset to value 1
+		8, 0, 0, 0, // offset for start of vtable (int32)
+		0x9A, 0x78, // value 1
+		0x56, 0x34, // value 0
+	})
+
+	// test 12: vtable with int16 and bool
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(2)
+	b.PrependInt16Slot(0, 0x3456, 0)
+	b.PrependBoolSlot(1, true, false)
+	b.EndObject()
+	check([]byte{
+		8, 0, // vtable bytes
+		8, 0, // end of object from here
+		6, 0, // offset to value 0
+		5, 0, // offset to value 1
+		8, 0, 0, 0, // offset for start of vtable (int32)
+		0,          // padding
+		1,          // value 1
+		0x56, 0x34, // value 0
+	})
+
+	// test 12: vtable with empty vector
+	b = flatbuffers.NewBuilder(0)
+	b.StartVector(flatbuffers.SizeByte, 0, 1)
+	vecend := b.EndVector(0)
+	b.StartObject(1)
+	b.PrependUOffsetTSlot(0, vecend, 0)
+	b.EndObject()
+	check([]byte{
+		6, 0, // vtable bytes
+		8, 0,
+		4, 0, // offset to vector offset
+		6, 0, 0, 0, // offset for start of vtable (int32)
+		4, 0, 0, 0,
+		0, 0, 0, 0, // length of vector (not in struct)
+	})
+
+	// test 12b: vtable with empty vector of byte and some scalars
+	b = flatbuffers.NewBuilder(0)
+	b.StartVector(flatbuffers.SizeByte, 0, 1)
+	vecend = b.EndVector(0)
+	b.StartObject(2)
+	b.PrependInt16Slot(0, 55, 0)
+	b.PrependUOffsetTSlot(1, vecend, 0)
+	b.EndObject()
+	check([]byte{
+		8, 0, // vtable bytes
+		12, 0,
+		10, 0, // offset to value 0
+		4, 0, // offset to vector offset
+		8, 0, 0, 0, // vtable loc
+		8, 0, 0, 0, // value 1
+		0, 0, 55, 0, // value 0
+
+		0, 0, 0, 0, // length of vector (not in struct)
+	})
+
+	// test 13: vtable with 1 int16 and 2-vector of int16
+	b = flatbuffers.NewBuilder(0)
+	b.StartVector(flatbuffers.SizeInt16, 2, 1)
+	b.PrependInt16(0x1234)
+	b.PrependInt16(0x5678)
+	vecend = b.EndVector(2)
+	b.StartObject(2)
+	b.PrependUOffsetTSlot(1, vecend, 0)
+	b.PrependInt16Slot(0, 55, 0)
+	b.EndObject()
+	check([]byte{
+		8, 0, // vtable bytes
+		12, 0, // length of object
+		6, 0, // start of value 0 from end of vtable
+		8, 0, // start of value 1 from end of buffer
+		8, 0, 0, 0, // offset for start of vtable (int32)
+		0, 0, // padding
+		55, 0, // value 0
+		4, 0, 0, 0, // vector position from here
+		2, 0, 0, 0, // length of vector (uint32)
+		0x78, 0x56, // vector value 1
+		0x34, 0x12, // vector value 0
+	})
+
+	// test 14: vtable with 1 struct of 1 int8, 1 int16, 1 int32
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(1)
+	b.Prep(4+4+4, 0)
+	b.PrependInt8(55)
+	b.Pad(3)
+	b.PrependInt16(0x1234)
+	b.Pad(2)
+	b.PrependInt32(0x12345678)
+	structStart := b.Offset()
+	b.PrependStructSlot(0, structStart, 0)
+	b.EndObject()
+	check([]byte{
+		6, 0, // vtable bytes
+		16, 0, // end of object from here
+		4, 0, // start of struct from here
+		6, 0, 0, 0, // offset for start of vtable (int32)
+		0x78, 0x56, 0x34, 0x12, // value 2
+		0, 0, // padding
+		0x34, 0x12, // value 1
+		0, 0, 0, // padding
+		55, // value 0
+	})
+
+	// test 15: vtable with 1 vector of 2 struct of 2 int8
+	b = flatbuffers.NewBuilder(0)
+	b.StartVector(flatbuffers.SizeInt8*2, 2, 1)
+	b.PrependInt8(33)
+	b.PrependInt8(44)
+	b.PrependInt8(55)
+	b.PrependInt8(66)
+	vecend = b.EndVector(2)
+	b.StartObject(1)
+	b.PrependUOffsetTSlot(0, vecend, 0)
+	b.EndObject()
+	check([]byte{
+		6, 0, // vtable bytes
+		8, 0,
+		4, 0, // offset of vector offset
+		6, 0, 0, 0, // offset for start of vtable (int32)
+		4, 0, 0, 0, // vector start offset
+
+		2, 0, 0, 0, // vector length
+		66, // vector value 1,1
+		55, // vector value 1,0
+		44, // vector value 0,1
+		33, // vector value 0,0
+	})
+
+	// test 16: table with some elements
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(2)
+	b.PrependInt8Slot(0, 33, 0)
+	b.PrependInt16Slot(1, 66, 0)
+	off := b.EndObject()
+	b.Finish(off)
+
+	check([]byte{
+		12, 0, 0, 0, // root of table: points to vtable offset
+
+		8, 0, // vtable bytes
+		8, 0, // end of object from here
+		7, 0, // start of value 0
+		4, 0, // start of value 1
+
+		8, 0, 0, 0, // offset for start of vtable (int32)
+
+		66, 0, // value 1
+		0,  // padding
+		33, // value 0
+	})
+
+	// test 17: one unfinished table and one finished table
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(2)
+	b.PrependInt8Slot(0, 33, 0)
+	b.PrependInt8Slot(1, 44, 0)
+	off = b.EndObject()
+	b.Finish(off)
+
+	b.StartObject(3)
+	b.PrependInt8Slot(0, 55, 0)
+	b.PrependInt8Slot(1, 66, 0)
+	b.PrependInt8Slot(2, 77, 0)
+	off = b.EndObject()
+	b.Finish(off)
+
+	check([]byte{
+		16, 0, 0, 0, // root of table: points to object
+		0, 0, // padding
+
+		10, 0, // vtable bytes
+		8, 0, // size of object
+		7, 0, // start of value 0
+		6, 0, // start of value 1
+		5, 0, // start of value 2
+		10, 0, 0, 0, // offset for start of vtable (int32)
+		0,  // padding
+		77, // value 2
+		66, // value 1
+		55, // value 0
+
+		12, 0, 0, 0, // root of table: points to object
+
+		8, 0, // vtable bytes
+		8, 0, // size of object
+		7, 0, // start of value 0
+		6, 0, // start of value 1
+		8, 0, 0, 0, // offset for start of vtable (int32)
+		0, 0, // padding
+		44, // value 1
+		33, // value 0
+	})
+
+	// test 18: a bunch of bools
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(8)
+	b.PrependBoolSlot(0, true, false)
+	b.PrependBoolSlot(1, true, false)
+	b.PrependBoolSlot(2, true, false)
+	b.PrependBoolSlot(3, true, false)
+	b.PrependBoolSlot(4, true, false)
+	b.PrependBoolSlot(5, true, false)
+	b.PrependBoolSlot(6, true, false)
+	b.PrependBoolSlot(7, true, false)
+	off = b.EndObject()
+	b.Finish(off)
+
+	check([]byte{
+		24, 0, 0, 0, // root of table: points to vtable offset
+
+		20, 0, // vtable bytes
+		12, 0, // size of object
+		11, 0, // start of value 0
+		10, 0, // start of value 1
+		9, 0, // start of value 2
+		8, 0, // start of value 3
+		7, 0, // start of value 4
+		6, 0, // start of value 5
+		5, 0, // start of value 6
+		4, 0, // start of value 7
+		20, 0, 0, 0, // vtable offset
+
+		1, // value 7
+		1, // value 6
+		1, // value 5
+		1, // value 4
+		1, // value 3
+		1, // value 2
+		1, // value 1
+		1, // value 0
+	})
+
+	// test 19: three bools
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(3)
+	b.PrependBoolSlot(0, true, false)
+	b.PrependBoolSlot(1, true, false)
+	b.PrependBoolSlot(2, true, false)
+	off = b.EndObject()
+	b.Finish(off)
+
+	check([]byte{
+		16, 0, 0, 0, // root of table: points to vtable offset
+
+		0, 0, // padding
+
+		10, 0, // vtable bytes
+		8, 0, // size of object
+		7, 0, // start of value 0
+		6, 0, // start of value 1
+		5, 0, // start of value 2
+		10, 0, 0, 0, // vtable offset from here
+
+		0, // padding
+		1, // value 2
+		1, // value 1
+		1, // value 0
+	})
+
+	// test 20: some floats
+	b = flatbuffers.NewBuilder(0)
+	b.StartObject(1)
+	b.PrependFloat32Slot(0, 1.0, 0.0)
+	off = b.EndObject()
+
+	check([]byte{
+		6, 0, // vtable bytes
+		8, 0, // size of object
+		4, 0, // start of value 0
+		6, 0, 0, 0, // vtable offset
+
+		0, 0, 128, 63, // value 0
+	})
+}
+
+// CheckManualBuild builds a Monster manually.
+func CheckManualBuild(fail func(string, ...interface{})) ([]byte, flatbuffers.UOffsetT) {
+	b := flatbuffers.NewBuilder(0)
+	str := b.CreateString("MyMonster")
+
+	b.StartVector(1, 5, 1)
+	b.PrependByte(4)
+	b.PrependByte(3)
+	b.PrependByte(2)
+	b.PrependByte(1)
+	b.PrependByte(0)
+	inv := b.EndVector(5)
+
+	b.StartObject(13)
+	b.PrependInt16Slot(2, 20, 100)
+	mon2 := b.EndObject()
+
+	// Test4Vector
+	b.StartVector(4, 2, 1)
+
+	// Test 0
+	b.Prep(2, 4)
+	b.Pad(1)
+	b.PlaceInt8(20)
+	b.PlaceInt16(10)
+
+	// Test 1
+	b.Prep(2, 4)
+	b.Pad(1)
+	b.PlaceInt8(40)
+	b.PlaceInt16(30)
+
+	// end testvector
+	test4 := b.EndVector(2)
+
+	b.StartObject(13)
+
+	// a vec3
+	b.Prep(16, 32)
+	b.Pad(2)
+	b.Prep(2, 4)
+	b.Pad(1)
+	b.PlaceByte(6)
+	b.PlaceInt16(5)
+	b.Pad(1)
+	b.PlaceByte(4)
+	b.PlaceFloat64(3.0)
+	b.Pad(4)
+	b.PlaceFloat32(3.0)
+	b.PlaceFloat32(2.0)
+	b.PlaceFloat32(1.0)
+	vec3Loc := b.Offset()
+	// end vec3
+
+	b.PrependStructSlot(0, vec3Loc, 0) // vec3. noop
+	b.PrependInt16Slot(2, 80, 100)     // hp
+	b.PrependUOffsetTSlot(3, str, 0)
+	b.PrependUOffsetTSlot(5, inv, 0) // inventory
+	b.PrependByteSlot(7, 1, 0)
+	b.PrependUOffsetTSlot(8, mon2, 0)
+	b.PrependUOffsetTSlot(9, test4, 0)
+	mon := b.EndObject()
+
+	b.Finish(mon)
+
+	return b.Bytes, b.Head()
+}
+
+func CheckGetRootAsForNonRootTable(fail func(string, ...interface{})) {
+	b := flatbuffers.NewBuilder(0)
+	str := b.CreateString("MyStat")
+	example.StatStart(b)
+	example.StatAddId(b, str)
+	example.StatAddVal(b, 12345678)
+	example.StatAddCount(b, 12345)
+	stat_end := example.StatEnd(b)
+	b.Finish(stat_end)
+
+	stat := example.GetRootAsStat(b.Bytes, b.Head())
+
+	if got := stat.Id(); !bytes.Equal([]byte("MyStat"), got) {
+		fail(FailString("stat.Id()", "MyStat", got))
+	}
+
+	if got := stat.Val(); 12345678 != got {
+		fail(FailString("stat.Val()", 12345678, got))
+	}
+
+	if got := stat.Count(); 12345 != got {
+		fail(FailString("stat.Count()", 12345, got))
+	}
+}
+
+// CheckGeneratedBuild uses generated code to build the example Monster.
+func CheckGeneratedBuild(fail func(string, ...interface{})) ([]byte, flatbuffers.UOffsetT) {
+	b := flatbuffers.NewBuilder(0)
+	str := b.CreateString("MyMonster")
+	test1 := b.CreateString("test1")
+	test2 := b.CreateString("test2")
+	fred := b.CreateString("Fred")
+
+	example.MonsterStartInventoryVector(b, 5)
+	b.PrependByte(4)
+	b.PrependByte(3)
+	b.PrependByte(2)
+	b.PrependByte(1)
+	b.PrependByte(0)
+	inv := b.EndVector(5)
+
+	example.MonsterStart(b)
+	example.MonsterAddName(b, fred)
+	mon2 := example.MonsterEnd(b)
+
+	example.MonsterStartTest4Vector(b, 2)
+	example.CreateTest(b, 10, 20)
+	example.CreateTest(b, 30, 40)
+	test4 := b.EndVector(2)
+
+	example.MonsterStartTestarrayofstringVector(b, 2)
+	b.PrependUOffsetT(test2)
+	b.PrependUOffsetT(test1)
+	testArrayOfString := b.EndVector(2)
+
+	example.MonsterStart(b)
+
+	pos := example.CreateVec3(b, 1.0, 2.0, 3.0, 3.0, example.ColorGreen, 5, 6)
+	example.MonsterAddPos(b, pos)
+
+	example.MonsterAddHp(b, 80)
+	example.MonsterAddName(b, str)
+	example.MonsterAddTestbool(b, true)
+	example.MonsterAddInventory(b, inv)
+	example.MonsterAddTestType(b, 1)
+	example.MonsterAddTest(b, mon2)
+	example.MonsterAddTest4(b, test4)
+	example.MonsterAddTestarrayofstring(b, testArrayOfString)
+	mon := example.MonsterEnd(b)
+
+	b.Finish(mon)
+
+	return b.Bytes, b.Head()
+}
+
+// CheckTableAccessors checks that the table accessors work as expected.
+func CheckTableAccessors(fail func(string, ...interface{})) {
+	// test struct accessor
+	b := flatbuffers.NewBuilder(0)
+	pos := example.CreateVec3(b, 1.0, 2.0, 3.0, 3.0, 4, 5, 6)
+	b.Finish(pos)
+	vec3Bytes := b.FinishedBytes()
+	vec3 := &example.Vec3{}
+	flatbuffers.GetRootAs(vec3Bytes, 0, vec3)
+
+	if bytes.Compare(vec3Bytes, vec3.Table().Bytes) != 0 {
+		fail("invalid vec3 table")
+	}
+
+	// test table accessor
+	b = flatbuffers.NewBuilder(0)
+	str := b.CreateString("MyStat")
+	example.StatStart(b)
+	example.StatAddId(b, str)
+	example.StatAddVal(b, 12345678)
+	example.StatAddCount(b, 12345)
+	pos = example.StatEnd(b)
+	b.Finish(pos)
+	statBytes := b.FinishedBytes()
+	stat := &example.Stat{}
+	flatbuffers.GetRootAs(statBytes, 0, stat)
+
+	if bytes.Compare(statBytes, stat.Table().Bytes) != 0 {
+		fail("invalid stat table")
+	}
+}
+
+// CheckVtableDeduplication verifies that vtables are deduplicated.
+func CheckVtableDeduplication(fail func(string, ...interface{})) {
+	b := flatbuffers.NewBuilder(0)
+
+	b.StartObject(4)
+	b.PrependByteSlot(0, 0, 0)
+	b.PrependByteSlot(1, 11, 0)
+	b.PrependByteSlot(2, 22, 0)
+	b.PrependInt16Slot(3, 33, 0)
+	obj0 := b.EndObject()
+
+	b.StartObject(4)
+	b.PrependByteSlot(0, 0, 0)
+	b.PrependByteSlot(1, 44, 0)
+	b.PrependByteSlot(2, 55, 0)
+	b.PrependInt16Slot(3, 66, 0)
+	obj1 := b.EndObject()
+
+	b.StartObject(4)
+	b.PrependByteSlot(0, 0, 0)
+	b.PrependByteSlot(1, 77, 0)
+	b.PrependByteSlot(2, 88, 0)
+	b.PrependInt16Slot(3, 99, 0)
+	obj2 := b.EndObject()
+
+	got := b.Bytes[b.Head():]
+
+	want := []byte{
+		240, 255, 255, 255, // == -12. offset to dedupped vtable.
+		99, 0,
+		88,
+		77,
+		248, 255, 255, 255, // == -8. offset to dedupped vtable.
+		66, 0,
+		55,
+		44,
+		12, 0,
+		8, 0,
+		0, 0,
+		7, 0,
+		6, 0,
+		4, 0,
+		12, 0, 0, 0,
+		33, 0,
+		22,
+		11,
+	}
+
+	if !bytes.Equal(want, got) {
+		fail("testVtableDeduplication want:\n%d %v\nbut got:\n%d %v\n",
+			len(want), want, len(got), got)
+	}
+
+	table0 := &flatbuffers.Table{Bytes: b.Bytes, Pos: flatbuffers.UOffsetT(len(b.Bytes)) - obj0}
+	table1 := &flatbuffers.Table{Bytes: b.Bytes, Pos: flatbuffers.UOffsetT(len(b.Bytes)) - obj1}
+	table2 := &flatbuffers.Table{Bytes: b.Bytes, Pos: flatbuffers.UOffsetT(len(b.Bytes)) - obj2}
+
+	testTable := func(tab *flatbuffers.Table, a flatbuffers.VOffsetT, b, c, d byte) {
+		// vtable size
+		if got := tab.GetVOffsetTSlot(0, 0); 12 != got {
+			fail("failed 0, 0: %d", got)
+		}
+		// object size
+		if got := tab.GetVOffsetTSlot(2, 0); 8 != got {
+			fail("failed 2, 0: %d", got)
+		}
+		// default value
+		if got := tab.GetVOffsetTSlot(4, 0); a != got {
+			fail("failed 4, 0: %d", got)
+		}
+		if got := tab.GetByteSlot(6, 0); b != got {
+			fail("failed 6, 0: %d", got)
+		}
+		if val := tab.GetByteSlot(8, 0); c != val {
+			fail("failed 8, 0: %d", got)
+		}
+		if got := tab.GetByteSlot(10, 0); d != got {
+			fail("failed 10, 0: %d", got)
+		}
+	}
+
+	testTable(table0, 0, 11, 22, 33)
+	testTable(table1, 0, 44, 55, 66)
+	testTable(table2, 0, 77, 88, 99)
+}
+
+// CheckNotInObjectError verifies that `EndObject` fails if not inside an
+// object.
+func CheckNotInObjectError(fail func(string, ...interface{})) {
+	b := flatbuffers.NewBuilder(0)
+
+	defer func() {
+		r := recover()
+		if r == nil {
+			fail("expected panic in CheckNotInObjectError")
+		}
+	}()
+	b.EndObject()
+}
+
+// CheckStringIsNestedError verifies that a string can not be created inside
+// another object.
+func CheckStringIsNestedError(fail func(string, ...interface{})) {
+	b := flatbuffers.NewBuilder(0)
+	b.StartObject(0)
+	defer func() {
+		r := recover()
+		if r == nil {
+			fail("expected panic in CheckStringIsNestedError")
+		}
+	}()
+	b.CreateString("foo")
+}
+
+// CheckByteStringIsNestedError verifies that a bytestring can not be created
+// inside another object.
+func CheckByteStringIsNestedError(fail func(string, ...interface{})) {
+	b := flatbuffers.NewBuilder(0)
+	b.StartObject(0)
+	defer func() {
+		r := recover()
+		if r == nil {
+			fail("expected panic in CheckByteStringIsNestedError")
+		}
+	}()
+	b.CreateByteString([]byte("foo"))
+}
+
+// CheckStructIsNotInlineError verifies that writing a struct in a location
+// away from where it is used will cause a panic.
+func CheckStructIsNotInlineError(fail func(string, ...interface{})) {
+	b := flatbuffers.NewBuilder(0)
+	b.StartObject(0)
+	defer func() {
+		r := recover()
+		if r == nil {
+			fail("expected panic in CheckStructIsNotInlineError")
+		}
+	}()
+	b.PrependStructSlot(0, 1, 0)
+}
+
+// CheckFinishedBytesError verifies that `FinishedBytes` panics if the table
+// is not finished.
+func CheckFinishedBytesError(fail func(string, ...interface{})) {
+	b := flatbuffers.NewBuilder(0)
+
+	defer func() {
+		r := recover()
+		if r == nil {
+			fail("expected panic in CheckFinishedBytesError")
+		}
+	}()
+	b.FinishedBytes()
+}
+
+// CheckEnumNames checks that the generated enum names are correct.
+func CheckEnumNames(fail func(string, ...interface{})) {
+	{
+		want := map[example.Any]string{
+			example.AnyNONE:                    "NONE",
+			example.AnyMonster:                 "Monster",
+			example.AnyTestSimpleTableWithEnum: "TestSimpleTableWithEnum",
+			example.AnyMyGame_Example2_Monster: "MyGame_Example2_Monster",
+		}
+		got := example.EnumNamesAny
+		if !reflect.DeepEqual(got, want) {
+			fail("enum name is not equal")
+		}
+	}
+	{
+		want := map[example.Color]string{
+			example.ColorRed:   "Red",
+			example.ColorGreen: "Green",
+			example.ColorBlue:  "Blue",
+		}
+		got := example.EnumNamesColor
+		if !reflect.DeepEqual(got, want) {
+			fail("enum name is not equal")
+		}
+	}
+}
+
+// CheckEnumString checks the String method on generated enum types.
+func CheckEnumString(fail func(string, ...interface{})) {
+	if got := example.AnyMonster.String(); got != "Monster" {
+		fail("Monster.String: %q != %q", got, "Monster")
+	}
+	if got := fmt.Sprintf("color: %s", example.ColorGreen); got != "color: Green" {
+		fail("color.String: %q != %q", got, "color: Green")
+	}
+}
+
+// CheckEnumValues checks that the generated enum values maps are correct.
+func CheckEnumValues(fail func(string, ...interface{})) {
+	{
+		want := map[string]example.Any{
+			"NONE":                    example.AnyNONE,
+			"Monster":                 example.AnyMonster,
+			"TestSimpleTableWithEnum": example.AnyTestSimpleTableWithEnum,
+			"MyGame_Example2_Monster": example.AnyMyGame_Example2_Monster,
+		}
+		got := example.EnumValuesAny
+		if !reflect.DeepEqual(got, want) {
+			fail("enum name is not equal")
+		}
+	}
+	{
+		want := map[string]example.Color{
+			"Red":   example.ColorRed,
+			"Green": example.ColorGreen,
+			"Blue":  example.ColorBlue,
+		}
+		got := example.EnumValuesColor
+		if !reflect.DeepEqual(got, want) {
+			fail("enum name is not equal")
+		}
+	}
+}
+
+// CheckDocExample checks that the code given in FlatBuffers documentation
+// is syntactically correct.
+func CheckDocExample(buf []byte, off flatbuffers.UOffsetT, fail func(string, ...interface{})) {
+	monster := example.GetRootAsMonster(buf, off)
+	_ = monster.Hp()
+	_ = monster.Pos(nil)
+	for i := 0; i < monster.InventoryLength(); i++ {
+		_ = monster.Inventory(i) // do something here
+	}
+
+	builder := flatbuffers.NewBuilder(0)
+
+	example.MonsterStartInventoryVector(builder, 5)
+	for i := 4; i >= 0; i-- {
+		builder.PrependByte(byte(i))
+	}
+	inv := builder.EndVector(5)
+
+	str := builder.CreateString("MyMonster")
+	example.MonsterStart(builder)
+	example.MonsterAddPos(builder, example.CreateVec3(builder, 1.0, 2.0, 3.0, 3.0, example.Color(4), 5, 6))
+	example.MonsterAddHp(builder, 80)
+	example.MonsterAddName(builder, str)
+	example.MonsterAddInventory(builder, inv)
+	example.MonsterAddTestType(builder, 1)
+	example.MonsterAddColor(builder, example.ColorRed)
+	// example.MonsterAddTest(builder, mon2)
+	// example.MonsterAddTest4(builder, test4s)
+	_ = example.MonsterEnd(builder)
+}
+
+func CheckCreateByteVector(fail func(string, ...interface{})) {
+	raw := [30]byte{}
+	for i := 0; i < len(raw); i++ {
+		raw[i] = byte(i)
+	}
+
+	for size := 0; size < len(raw); size++ {
+		b1 := flatbuffers.NewBuilder(0)
+		b2 := flatbuffers.NewBuilder(0)
+		b1.StartVector(1, size, 1)
+		for i := size - 1; i >= 0; i-- {
+			b1.PrependByte(raw[i])
+		}
+		b1.EndVector(size)
+		b2.CreateByteVector(raw[:size])
+		CheckByteEquality(b1.Bytes, b2.Bytes, fail)
+	}
+}
+
+func CheckParentNamespace(fail func(string, ...interface{})) {
+	var empty, nonempty []byte
+
+	// create monster with an empty parent namespace field
+	{
+		builder := flatbuffers.NewBuilder(0)
+
+		example.MonsterStart(builder)
+		m := example.MonsterEnd(builder)
+		builder.Finish(m)
+
+		empty = make([]byte, len(builder.FinishedBytes()))
+		copy(empty, builder.FinishedBytes())
+	}
+
+	// create monster with a non-empty parent namespace field
+	{
+		builder := flatbuffers.NewBuilder(0)
+		mygame.InParentNamespaceStart(builder)
+		pn := mygame.InParentNamespaceEnd(builder)
+
+		example.MonsterStart(builder)
+		example.MonsterAddParentNamespaceTest(builder, pn)
+		m := example.MonsterEnd(builder)
+
+		builder.Finish(m)
+
+		nonempty = make([]byte, len(builder.FinishedBytes()))
+		copy(nonempty, builder.FinishedBytes())
+	}
+
+	// read monster with empty parent namespace field
+	{
+		m := example.GetRootAsMonster(empty, 0)
+		if m.ParentNamespaceTest(nil) != nil {
+			fail("expected nil ParentNamespaceTest for empty field")
+		}
+	}
+
+	// read monster with non-empty parent namespace field
+	{
+		m := example.GetRootAsMonster(nonempty, 0)
+		if m.ParentNamespaceTest(nil) == nil {
+			fail("expected non-nil ParentNamespaceTest for non-empty field")
+		}
+	}
+}
+
+// Include simple random number generator to ensure results will be the
+// same cross platform.
+// http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator
+type LCG uint32
+
+const InitialLCGSeed = 48271
+
+func NewLCG() *LCG {
+	n := uint32(InitialLCGSeed)
+	l := LCG(n)
+	return &l
+}
+
+func (lcg *LCG) Reset() {
+	*lcg = InitialLCGSeed
+}
+
+func (lcg *LCG) Next() uint32 {
+	n := uint32((uint64(*lcg) * uint64(279470273)) % uint64(4294967291))
+	*lcg = LCG(n)
+	return n
+}
+
+// CheckByteEquality verifies that two byte buffers are the same.
+func CheckByteEquality(a, b []byte, fail func(string, ...interface{})) {
+	if !bytes.Equal(a, b) {
+		fail("objects are not byte-wise equal")
+	}
+}
+
+// CheckMutateMethods checks all mutate methods one by one
+func CheckMutateMethods(fail func(string, ...interface{})) {
+	b := flatbuffers.NewBuilder(0)
+	b.StartObject(15)
+	b.PrependBoolSlot(0, true, false)
+	b.PrependByteSlot(1, 1, 0)
+	b.PrependUint8Slot(2, 2, 0)
+	b.PrependUint16Slot(3, 3, 0)
+	b.PrependUint32Slot(4, 4, 0)
+	b.PrependUint64Slot(5, 5, 0)
+	b.PrependInt8Slot(6, 6, 0)
+	b.PrependInt16Slot(7, 7, 0)
+	b.PrependInt32Slot(8, 8, 0)
+	b.PrependInt64Slot(9, 9, 0)
+	b.PrependFloat32Slot(10, 10, 0)
+	b.PrependFloat64Slot(11, 11, 0)
+
+	b.PrependUOffsetTSlot(12, 12, 0)
+	uoVal := b.Offset() - 12
+
+	b.PrependVOffsetT(13)
+	b.Slot(13)
+
+	b.PrependSOffsetT(14)
+	b.Slot(14)
+	soVal := flatbuffers.SOffsetT(b.Offset() - 14)
+
+	offset := b.EndObject()
+
+	t := &flatbuffers.Table{
+		Bytes: b.Bytes,
+		Pos:   flatbuffers.UOffsetT(len(b.Bytes)) - offset,
+	}
+
+	calcVOffsetT := func(slot int) (vtableOffset flatbuffers.VOffsetT) {
+		return flatbuffers.VOffsetT((flatbuffers.VtableMetadataFields + slot) * flatbuffers.SizeVOffsetT)
+	}
+	calcUOffsetT := func(vtableOffset flatbuffers.VOffsetT) (valueOffset flatbuffers.UOffsetT) {
+		return t.Pos + flatbuffers.UOffsetT(t.Offset(vtableOffset))
+	}
+
+	type testcase struct {
+		field  string
+		testfn func() bool
+	}
+
+	testForOriginalValues := []testcase{
+		testcase{"BoolSlot", func() bool { return t.GetBoolSlot(calcVOffsetT(0), true) == true }},
+		testcase{"ByteSlot", func() bool { return t.GetByteSlot(calcVOffsetT(1), 1) == 1 }},
+		testcase{"Uint8Slot", func() bool { return t.GetUint8Slot(calcVOffsetT(2), 2) == 2 }},
+		testcase{"Uint16Slot", func() bool { return t.GetUint16Slot(calcVOffsetT(3), 3) == 3 }},
+		testcase{"Uint32Slot", func() bool { return t.GetUint32Slot(calcVOffsetT(4), 4) == 4 }},
+		testcase{"Uint64Slot", func() bool { return t.GetUint64Slot(calcVOffsetT(5), 5) == 5 }},
+		testcase{"Int8Slot", func() bool { return t.GetInt8Slot(calcVOffsetT(6), 6) == 6 }},
+		testcase{"Int16Slot", func() bool { return t.GetInt16Slot(calcVOffsetT(7), 7) == 7 }},
+		testcase{"Int32Slot", func() bool { return t.GetInt32Slot(calcVOffsetT(8), 8) == 8 }},
+		testcase{"Int64Slot", func() bool { return t.GetInt64Slot(calcVOffsetT(9), 9) == 9 }},
+		testcase{"Float32Slot", func() bool { return t.GetFloat32Slot(calcVOffsetT(10), 10) == 10 }},
+		testcase{"Float64Slot", func() bool { return t.GetFloat64Slot(calcVOffsetT(11), 11) == 11 }},
+		testcase{"UOffsetTSlot", func() bool { return t.GetUOffsetT(calcUOffsetT(calcVOffsetT(12))) == uoVal }},
+		testcase{"VOffsetTSlot", func() bool { return t.GetVOffsetT(calcUOffsetT(calcVOffsetT(13))) == 13 }},
+		testcase{"SOffsetTSlot", func() bool { return t.GetSOffsetT(calcUOffsetT(calcVOffsetT(14))) == soVal }},
+	}
+
+	testMutability := []testcase{
+		testcase{"BoolSlot", func() bool { return t.MutateBoolSlot(calcVOffsetT(0), false) }},
+		testcase{"ByteSlot", func() bool { return t.MutateByteSlot(calcVOffsetT(1), 2) }},
+		testcase{"Uint8Slot", func() bool { return t.MutateUint8Slot(calcVOffsetT(2), 4) }},
+		testcase{"Uint16Slot", func() bool { return t.MutateUint16Slot(calcVOffsetT(3), 6) }},
+		testcase{"Uint32Slot", func() bool { return t.MutateUint32Slot(calcVOffsetT(4), 8) }},
+		testcase{"Uint64Slot", func() bool { return t.MutateUint64Slot(calcVOffsetT(5), 10) }},
+		testcase{"Int8Slot", func() bool { return t.MutateInt8Slot(calcVOffsetT(6), 12) }},
+		testcase{"Int16Slot", func() bool { return t.MutateInt16Slot(calcVOffsetT(7), 14) }},
+		testcase{"Int32Slot", func() bool { return t.MutateInt32Slot(calcVOffsetT(8), 16) }},
+		testcase{"Int64Slot", func() bool { return t.MutateInt64Slot(calcVOffsetT(9), 18) }},
+		testcase{"Float32Slot", func() bool { return t.MutateFloat32Slot(calcVOffsetT(10), 20) }},
+		testcase{"Float64Slot", func() bool { return t.MutateFloat64Slot(calcVOffsetT(11), 22) }},
+		testcase{"UOffsetTSlot", func() bool { return t.MutateUOffsetT(calcUOffsetT(calcVOffsetT(12)), 24) }},
+		testcase{"VOffsetTSlot", func() bool { return t.MutateVOffsetT(calcUOffsetT(calcVOffsetT(13)), 26) }},
+		testcase{"SOffsetTSlot", func() bool { return t.MutateSOffsetT(calcUOffsetT(calcVOffsetT(14)), 28) }},
+	}
+
+	testMutabilityWithoutSlot := []testcase{
+		testcase{"BoolSlot", func() bool { return t.MutateBoolSlot(calcVOffsetT(16), false) }},
+		testcase{"ByteSlot", func() bool { return t.MutateByteSlot(calcVOffsetT(16), 2) }},
+		testcase{"Uint8Slot", func() bool { return t.MutateUint8Slot(calcVOffsetT(16), 2) }},
+		testcase{"Uint16Slot", func() bool { return t.MutateUint16Slot(calcVOffsetT(16), 2) }},
+		testcase{"Uint32Slot", func() bool { return t.MutateUint32Slot(calcVOffsetT(16), 2) }},
+		testcase{"Uint64Slot", func() bool { return t.MutateUint64Slot(calcVOffsetT(16), 2) }},
+		testcase{"Int8Slot", func() bool { return t.MutateInt8Slot(calcVOffsetT(16), 2) }},
+		testcase{"Int16Slot", func() bool { return t.MutateInt16Slot(calcVOffsetT(16), 2) }},
+		testcase{"Int32Slot", func() bool { return t.MutateInt32Slot(calcVOffsetT(16), 2) }},
+		testcase{"Int64Slot", func() bool { return t.MutateInt64Slot(calcVOffsetT(16), 2) }},
+		testcase{"Float32Slot", func() bool { return t.MutateFloat32Slot(calcVOffsetT(16), 2) }},
+		testcase{"Float64Slot", func() bool { return t.MutateFloat64Slot(calcVOffsetT(16), 2) }},
+	}
+
+	testForMutatedValues := []testcase{
+		testcase{"BoolSlot", func() bool { return t.GetBoolSlot(calcVOffsetT(0), true) == false }},
+		testcase{"ByteSlot", func() bool { return t.GetByteSlot(calcVOffsetT(1), 1) == 2 }},
+		testcase{"Uint8Slot", func() bool { return t.GetUint8Slot(calcVOffsetT(2), 1) == 4 }},
+		testcase{"Uint16Slot", func() bool { return t.GetUint16Slot(calcVOffsetT(3), 1) == 6 }},
+		testcase{"Uint32Slot", func() bool { return t.GetUint32Slot(calcVOffsetT(4), 1) == 8 }},
+		testcase{"Uint64Slot", func() bool { return t.GetUint64Slot(calcVOffsetT(5), 1) == 10 }},
+		testcase{"Int8Slot", func() bool { return t.GetInt8Slot(calcVOffsetT(6), 1) == 12 }},
+		testcase{"Int16Slot", func() bool { return t.GetInt16Slot(calcVOffsetT(7), 1) == 14 }},
+		testcase{"Int32Slot", func() bool { return t.GetInt32Slot(calcVOffsetT(8), 1) == 16 }},
+		testcase{"Int64Slot", func() bool { return t.GetInt64Slot(calcVOffsetT(9), 1) == 18 }},
+		testcase{"Float32Slot", func() bool { return t.GetFloat32Slot(calcVOffsetT(10), 1) == 20 }},
+		testcase{"Float64Slot", func() bool { return t.GetFloat64Slot(calcVOffsetT(11), 1) == 22 }},
+		testcase{"UOffsetTSlot", func() bool { return t.GetUOffsetT(calcUOffsetT(calcVOffsetT(12))) == 24 }},
+		testcase{"VOffsetTSlot", func() bool { return t.GetVOffsetT(calcUOffsetT(calcVOffsetT(13))) == 26 }},
+		testcase{"SOffsetTSlot", func() bool { return t.GetSOffsetT(calcUOffsetT(calcVOffsetT(14))) == 28 }},
+	}
+
+	// make sure original values are okay
+	for _, t := range testForOriginalValues {
+		if !t.testfn() {
+			fail(t.field + "' field doesn't have the expected original value")
+		}
+	}
+
+	// try to mutate fields and check mutability
+	for _, t := range testMutability {
+		if !t.testfn() {
+			fail(FailString(t.field+"' field failed mutability test", "passed", "failed"))
+		}
+	}
+
+	// try to mutate fields and check mutability
+	// these have wrong slots so should fail
+	for _, t := range testMutabilityWithoutSlot {
+		if t.testfn() {
+			fail(FailString(t.field+"' field failed no slot mutability test", "failed", "passed"))
+		}
+	}
+
+	// test whether values have changed
+	for _, t := range testForMutatedValues {
+		if !t.testfn() {
+			fail(t.field + "' field doesn't have the expected mutated value")
+		}
+	}
+}
+
+// BenchmarkVtableDeduplication measures the speed of vtable deduplication
+// by creating prePop vtables, then populating b.N objects with a
+// different single vtable.
+//
+// When b.N is large (as in long benchmarks), memory usage may be high.
+func BenchmarkVtableDeduplication(b *testing.B) {
+	prePop := 10
+	builder := flatbuffers.NewBuilder(0)
+
+	// pre-populate some vtables:
+	for i := 0; i < prePop; i++ {
+		builder.StartObject(i)
+		for j := 0; j < i; j++ {
+			builder.PrependInt16Slot(j, int16(j), 0)
+		}
+		builder.EndObject()
+	}
+
+	// benchmark deduplication of a new vtable:
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		lim := prePop
+
+		builder.StartObject(lim)
+		for j := 0; j < lim; j++ {
+			builder.PrependInt16Slot(j, int16(j), 0)
+		}
+		builder.EndObject()
+	}
+}
+
+// BenchmarkParseGold measures the speed of parsing the 'gold' data
+// used throughout this test suite.
+func BenchmarkParseGold(b *testing.B) {
+	buf, offset := CheckGeneratedBuild(b.Fatalf)
+	monster := example.GetRootAsMonster(buf, offset)
+
+	// use these to prevent allocations:
+	reuse_pos := example.Vec3{}
+	reuse_test3 := example.Test{}
+	reuse_table2 := flatbuffers.Table{}
+	reuse_monster2 := example.Monster{}
+	reuse_test4_0 := example.Test{}
+	reuse_test4_1 := example.Test{}
+
+	b.SetBytes(int64(len(buf[offset:])))
+	b.ReportAllocs()
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		monster.Hp()
+		monster.Mana()
+		name := monster.Name()
+		_ = name[0]
+		_ = name[len(name)-1]
+
+		monster.Pos(&reuse_pos)
+		reuse_pos.X()
+		reuse_pos.Y()
+		reuse_pos.Z()
+		reuse_pos.Test1()
+		reuse_pos.Test2()
+		reuse_pos.Test3(&reuse_test3)
+		reuse_test3.A()
+		reuse_test3.B()
+		monster.TestType()
+		monster.Test(&reuse_table2)
+		reuse_monster2.Init(reuse_table2.Bytes, reuse_table2.Pos)
+		name2 := reuse_monster2.Name()
+		_ = name2[0]
+		_ = name2[len(name2)-1]
+		monster.InventoryLength()
+		l := monster.InventoryLength()
+		for i := 0; i < l; i++ {
+			monster.Inventory(i)
+		}
+		monster.Test4Length()
+		monster.Test4(&reuse_test4_0, 0)
+		monster.Test4(&reuse_test4_1, 1)
+
+		reuse_test4_0.A()
+		reuse_test4_0.B()
+		reuse_test4_1.A()
+		reuse_test4_1.B()
+
+		monster.TestarrayofstringLength()
+		str0 := monster.Testarrayofstring(0)
+		_ = str0[0]
+		_ = str0[len(str0)-1]
+		str1 := monster.Testarrayofstring(1)
+		_ = str1[0]
+		_ = str1[len(str1)-1]
+	}
+}
+
+// BenchmarkBuildGold uses generated code to build the example Monster.
+func BenchmarkBuildGold(b *testing.B) {
+	buf, offset := CheckGeneratedBuild(b.Fatalf)
+	bytes_length := int64(len(buf[offset:]))
+
+	reuse_str := "MyMonster"
+	reuse_test1 := "test1"
+	reuse_test2 := "test2"
+	reuse_fred := "Fred"
+
+	b.SetBytes(bytes_length)
+	bldr := flatbuffers.NewBuilder(0)
+	b.ResetTimer()
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		bldr.Reset()
+
+		str := bldr.CreateString(reuse_str)
+		test1 := bldr.CreateString(reuse_test1)
+		test2 := bldr.CreateString(reuse_test2)
+		fred := bldr.CreateString(reuse_fred)
+
+		example.MonsterStartInventoryVector(bldr, 5)
+		bldr.PrependByte(4)
+		bldr.PrependByte(3)
+		bldr.PrependByte(2)
+		bldr.PrependByte(1)
+		bldr.PrependByte(0)
+		inv := bldr.EndVector(5)
+
+		example.MonsterStart(bldr)
+		example.MonsterAddName(bldr, fred)
+		mon2 := example.MonsterEnd(bldr)
+
+		example.MonsterStartTest4Vector(bldr, 2)
+		example.CreateTest(bldr, 10, 20)
+		example.CreateTest(bldr, 30, 40)
+		test4 := bldr.EndVector(2)
+
+		example.MonsterStartTestarrayofstringVector(bldr, 2)
+		bldr.PrependUOffsetT(test2)
+		bldr.PrependUOffsetT(test1)
+		testArrayOfString := bldr.EndVector(2)
+
+		example.MonsterStart(bldr)
+
+		pos := example.CreateVec3(bldr, 1.0, 2.0, 3.0, 3.0, example.ColorGreen, 5, 6)
+		example.MonsterAddPos(bldr, pos)
+
+		example.MonsterAddHp(bldr, 80)
+		example.MonsterAddName(bldr, str)
+		example.MonsterAddInventory(bldr, inv)
+		example.MonsterAddTestType(bldr, 1)
+		example.MonsterAddTest(bldr, mon2)
+		example.MonsterAddTest4(bldr, test4)
+		example.MonsterAddTestarrayofstring(bldr, testArrayOfString)
+		mon := example.MonsterEnd(bldr)
+
+		bldr.Finish(mon)
+	}
+}