...

Source file src/github.com/google/flatbuffers/tests/go_test.go

Documentation: github.com/google/flatbuffers/tests

     1  /*
     2   * Copyright 2014 Google Inc. All rights reserved.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package main
    18  
    19  import (
    20  	mygame "MyGame"          // refers to generated code
    21  	example "MyGame/Example" // refers to generated code
    22  	pizza "Pizza"
    23  	"encoding/json"
    24  	optional_scalars "optional_scalars" // refers to generated code
    25  	order "order"
    26  
    27  	"bytes"
    28  	"flag"
    29  	"fmt"
    30  	"os"
    31  	"reflect"
    32  	"sort"
    33  	"testing"
    34  	"testing/quick"
    35  
    36  	flatbuffers "github.com/google/flatbuffers/go"
    37  )
    38  
    39  var (
    40  	cppData, javaData, outData string
    41  	fuzz                       bool
    42  	fuzzFields, fuzzObjects    int
    43  )
    44  
    45  func init() {
    46  	flag.StringVar(&cppData, "cpp_data", "",
    47  		"location of monsterdata_test.mon to verify against (required)")
    48  	flag.StringVar(&javaData, "java_data", "",
    49  		"location of monsterdata_java_wire.mon to verify against (optional)")
    50  	flag.StringVar(&outData, "out_data", "",
    51  		"location to write generated Go data")
    52  	flag.BoolVar(&fuzz, "fuzz", false, "perform fuzzing")
    53  	flag.IntVar(&fuzzFields, "fuzz_fields", 4, "fields per fuzzer object")
    54  	flag.IntVar(&fuzzObjects, "fuzz_objects", 10000,
    55  		"number of fuzzer objects (higher is slower and more thorough")
    56  }
    57  
    58  // Store specific byte patterns in these variables for the fuzzer. These
    59  // values are taken verbatim from the C++ function FuzzTest1.
    60  var (
    61  	overflowingInt32Val = flatbuffers.GetInt32([]byte{0x83, 0x33, 0x33, 0x33})
    62  	overflowingInt64Val = flatbuffers.GetInt64([]byte{0x84, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44})
    63  )
    64  
    65  func TestMain(m *testing.M) {
    66  	flag.Parse()
    67  	if cppData == "" {
    68  		fmt.Fprintf(os.Stderr, "cpp_data argument is required\n")
    69  		os.Exit(1)
    70  	}
    71  	os.Exit(m.Run())
    72  }
    73  
    74  // TestTextParsing test if text parsing works with object API.
    75  func TestTextParsing(t *testing.T) {
    76  	expectedMonster := example.MonsterT{
    77  		Mana:                  42,
    78  		Name:                  "foo",
    79  		LongEnumNormalDefault: example.LongEnumLongTwo,
    80  	}
    81  
    82  	buf := new(bytes.Buffer)
    83  	if err := json.NewEncoder(buf).Encode(expectedMonster); err != nil {
    84  		t.Fatal(err)
    85  	}
    86  
    87  	var monster example.MonsterT
    88  	if err := json.NewDecoder(buf).Decode(&monster); err != nil {
    89  		t.Fatal(err)
    90  	}
    91  
    92  	if monster.Mana != expectedMonster.Mana {
    93  		t.Fatal("wrong mana:", monster.Mana)
    94  	}
    95  	if monster.Name != expectedMonster.Name {
    96  		t.Fatal("wrong name:", monster.Name)
    97  	}
    98  	if monster.LongEnumNormalDefault != expectedMonster.LongEnumNormalDefault {
    99  		t.Fatal("wrong enum:", monster.LongEnumNormalDefault)
   100  	}
   101  }
   102  
   103  func CheckNoNamespaceImport(fail func(string, ...interface{})) {
   104  	const size = 13
   105  	// Order a pizza with specific size
   106  	builder := flatbuffers.NewBuilder(0)
   107  	ordered_pizza := pizza.PizzaT{Size: size}
   108  	food := order.FoodT{Pizza: &ordered_pizza}
   109  	builder.Finish(food.Pack(builder))
   110  
   111  	// Receive order
   112  	received_food := order.GetRootAsFood(builder.FinishedBytes(), 0)
   113  	received_pizza := received_food.Pizza(nil).UnPack()
   114  
   115  	// Check if received pizza is equal to ordered pizza
   116  	if !reflect.DeepEqual(ordered_pizza, *received_pizza) {
   117  		fail(FailString("no namespace import", ordered_pizza, received_pizza))
   118  	}
   119  }
   120  
   121  // TestAll runs all checks, failing if any errors occur.
   122  func TestAll(t *testing.T) {
   123  	// Verify that the Go FlatBuffers runtime library generates the
   124  	// expected bytes (does not use any schema):
   125  	CheckByteLayout(t.Fatalf)
   126  	CheckMutateMethods(t.Fatalf)
   127  
   128  	// Verify that panics are raised during exceptional conditions:
   129  	CheckNotInObjectError(t.Fatalf)
   130  	CheckStringIsNestedError(t.Fatalf)
   131  	CheckByteStringIsNestedError(t.Fatalf)
   132  	CheckStructIsNotInlineError(t.Fatalf)
   133  	CheckFinishedBytesError(t.Fatalf)
   134  	CheckSharedStrings(t.Fatalf)
   135  	CheckEmptiedBuilder(t.Fatalf)
   136  
   137  	// Verify that GetRootAs works for non-root tables
   138  	CheckGetRootAsForNonRootTable(t.Fatalf)
   139  	CheckTableAccessors(t.Fatalf)
   140  
   141  	// Verify that using the generated Go code builds a buffer without
   142  	// returning errors:
   143  	generated, off := CheckGeneratedBuild(false, false, t.Fatalf)
   144  
   145  	// Verify that the buffer generated by Go code is readable by the
   146  	// generated Go code:
   147  	CheckReadBuffer(generated, off, false, t.Fatalf)
   148  	CheckMutateBuffer(generated, off, false, t.Fatalf)
   149  	CheckObjectAPI(generated, off, false, t.Fatalf)
   150  
   151  	// Generate the buffer again, with file identifier.
   152  	generated, off = CheckGeneratedBuild(false, true, t.Fatalf)
   153  
   154  	// Check that this buffer with file identifier is usable
   155  	// and that the file identifier is correct.
   156  	CheckReadBuffer(generated, off, false, t.Fatalf)
   157  	CheckMutateBuffer(generated, off, false, t.Fatalf)
   158  	CheckObjectAPI(generated, off, false, t.Fatalf)
   159  	CheckFileIdentifier(generated, off, false, t.Fatalf)
   160  
   161  	// Verify that the buffer generated by C++ code is readable by the
   162  	// generated Go code:
   163  	monsterDataCpp, err := os.ReadFile(cppData)
   164  	if err != nil {
   165  		t.Fatal(err)
   166  	}
   167  	CheckReadBuffer(monsterDataCpp, 0, false, t.Fatalf)
   168  	CheckMutateBuffer(monsterDataCpp, 0, false, t.Fatalf)
   169  	CheckObjectAPI(monsterDataCpp, 0, false, t.Fatalf)
   170  	CheckFileIdentifier(monsterDataCpp, 0, false, t.Fatalf)
   171  
   172  	// Verify that vtables are deduplicated when written:
   173  	CheckVtableDeduplication(t.Fatalf)
   174  
   175  	// Verify the enum names
   176  	CheckEnumNames(t.Fatalf)
   177  
   178  	// Verify enum String methods
   179  	CheckEnumString(t.Fatalf)
   180  
   181  	// Verify the enum values maps
   182  	CheckEnumValues(t.Fatalf)
   183  
   184  	// Verify that the Go code used in FlatBuffers documentation passes
   185  	// some sanity checks:
   186  	CheckDocExample(generated, off, t.Fatalf)
   187  
   188  	// Check Builder.CreateByteVector
   189  	CheckCreateByteVector(t.Fatalf)
   190  
   191  	// Check a parent namespace import
   192  	CheckParentNamespace(t.Fatalf)
   193  
   194  	// Check a no namespace import
   195  	CheckNoNamespaceImport(t.Fatalf)
   196  
   197  	// Check size-prefixed flatbuffers
   198  	CheckSizePrefixedBuffer(t.Fatalf)
   199  
   200  	// Check that optional scalars works
   201  	CheckOptionalScalars(t.Fatalf)
   202  
   203  	// Check that getting vector element by key works
   204  	CheckByKey(t.Fatalf)
   205  
   206  	// If the filename of the FlatBuffers file generated by the Java test
   207  	// is given, check that Go code can read it, and that Go code
   208  	// generates an identical buffer when used to create the example data:
   209  	if javaData != "" {
   210  		monsterDataJava, err := os.ReadFile(javaData)
   211  		if err != nil {
   212  			t.Fatal(err)
   213  		}
   214  		CheckReadBuffer(monsterDataJava, 0, false, t.Fatalf)
   215  		CheckByteEquality(generated[off:], monsterDataJava, t.Fatalf)
   216  	}
   217  
   218  	// Verify that various fuzzing scenarios produce a valid FlatBuffer.
   219  	if fuzz {
   220  		checkFuzz(fuzzFields, fuzzObjects, t.Fatalf)
   221  	}
   222  
   223  	// Write the generated buffer out to a file:
   224  	err = os.WriteFile(outData, generated[off:], os.FileMode(0644))
   225  	if err != nil {
   226  		t.Fatal(err)
   227  	}
   228  }
   229  
   230  // CheckReadBuffer checks that the given buffer is evaluated correctly
   231  // as the example Monster.
   232  func CheckReadBuffer(buf []byte, offset flatbuffers.UOffsetT, sizePrefix bool, fail func(string, ...interface{})) {
   233  	// try the two ways of generating a monster
   234  	var monster1 *example.Monster
   235  	monster2 := &example.Monster{}
   236  
   237  	if sizePrefix {
   238  		monster1 = example.GetSizePrefixedRootAsMonster(buf, offset)
   239  		flatbuffers.GetSizePrefixedRootAs(buf, offset, monster2)
   240  	} else {
   241  		monster1 = example.GetRootAsMonster(buf, offset)
   242  		flatbuffers.GetRootAs(buf, offset, monster2)
   243  	}
   244  
   245  	for _, monster := range []*example.Monster{monster1, monster2} {
   246  		if got := monster.Hp(); 80 != got {
   247  			fail(FailString("hp", 80, got))
   248  		}
   249  
   250  		// default
   251  		if got := monster.Mana(); 150 != got {
   252  			fail(FailString("mana", 150, got))
   253  		}
   254  
   255  		if got := monster.Name(); !bytes.Equal([]byte("MyMonster"), got) {
   256  			fail(FailString("name", "MyMonster", got))
   257  		}
   258  
   259  		if got := monster.Color(); example.ColorBlue != got {
   260  			fail(FailString("color", example.ColorBlue, got))
   261  		}
   262  
   263  		if got := monster.Testbool(); true != got {
   264  			fail(FailString("testbool", true, got))
   265  		}
   266  
   267  		// initialize a Vec3 from Pos()
   268  		vec := new(example.Vec3)
   269  		vec = monster.Pos(vec)
   270  		if vec == nil {
   271  			fail("vec3 initialization failed")
   272  		}
   273  
   274  		// check that new allocs equal given ones:
   275  		vec2 := monster.Pos(nil)
   276  		if !reflect.DeepEqual(vec, vec2) {
   277  			fail("fresh allocation failed")
   278  		}
   279  
   280  		// verify the properties of the Vec3
   281  		if got := vec.X(); float32(1.0) != got {
   282  			fail(FailString("Pos.X", float32(1.0), got))
   283  		}
   284  
   285  		if got := vec.Y(); float32(2.0) != got {
   286  			fail(FailString("Pos.Y", float32(2.0), got))
   287  		}
   288  
   289  		if got := vec.Z(); float32(3.0) != got {
   290  			fail(FailString("Pos.Z", float32(3.0), got))
   291  		}
   292  
   293  		if got := vec.Test1(); float64(3.0) != got {
   294  			fail(FailString("Pos.Test1", float64(3.0), got))
   295  		}
   296  
   297  		if got := vec.Test2(); example.ColorGreen != got {
   298  			fail(FailString("Pos.Test2", example.ColorGreen, got))
   299  		}
   300  
   301  		// initialize a Test from Test3(...)
   302  		t := new(example.Test)
   303  		t = vec.Test3(t)
   304  		if t == nil {
   305  			fail("vec.Test3(&t) failed")
   306  		}
   307  
   308  		// check that new allocs equal given ones:
   309  		t2 := vec.Test3(nil)
   310  		if !reflect.DeepEqual(t, t2) {
   311  			fail("fresh allocation failed")
   312  		}
   313  
   314  		// verify the properties of the Test
   315  		if got := t.A(); int16(5) != got {
   316  			fail(FailString("t.A()", int16(5), got))
   317  		}
   318  
   319  		if got := t.B(); int8(6) != got {
   320  			fail(FailString("t.B()", int8(6), got))
   321  		}
   322  
   323  		if got := monster.TestType(); example.AnyMonster != got {
   324  			fail(FailString("monster.TestType()", example.AnyMonster, got))
   325  		}
   326  
   327  		// initialize a Table from a union field Test(...)
   328  		var table2 flatbuffers.Table
   329  		if ok := monster.Test(&table2); !ok {
   330  			fail("monster.Test(&monster2) failed")
   331  		}
   332  
   333  		// initialize a Monster from the Table from the union
   334  		var monster2 example.Monster
   335  		monster2.Init(table2.Bytes, table2.Pos)
   336  
   337  		if got := monster2.Name(); !bytes.Equal([]byte("Fred"), got) {
   338  			fail(FailString("monster2.Name()", "Fred", got))
   339  		}
   340  
   341  		inventorySlice := monster.InventoryBytes()
   342  		if len(inventorySlice) != monster.InventoryLength() {
   343  			fail(FailString("len(monster.InventoryBytes) != monster.InventoryLength", len(inventorySlice), monster.InventoryLength()))
   344  		}
   345  
   346  		if got := monster.InventoryLength(); 5 != got {
   347  			fail(FailString("monster.InventoryLength", 5, got))
   348  		}
   349  
   350  		invsum := 0
   351  		l := monster.InventoryLength()
   352  		for i := 0; i < l; i++ {
   353  			v := monster.Inventory(i)
   354  			if v != inventorySlice[i] {
   355  				fail(FailString("monster inventory slice[i] != Inventory(i)", v, inventorySlice[i]))
   356  			}
   357  			invsum += int(v)
   358  		}
   359  		if invsum != 10 {
   360  			fail(FailString("monster inventory sum", 10, invsum))
   361  		}
   362  
   363  		if got := monster.Test4Length(); 2 != got {
   364  			fail(FailString("monster.Test4Length()", 2, got))
   365  		}
   366  
   367  		var test0 example.Test
   368  		ok := monster.Test4(&test0, 0)
   369  		if !ok {
   370  			fail(FailString("monster.Test4(&test0, 0)", true, ok))
   371  		}
   372  
   373  		var test1 example.Test
   374  		ok = monster.Test4(&test1, 1)
   375  		if !ok {
   376  			fail(FailString("monster.Test4(&test1, 1)", true, ok))
   377  		}
   378  
   379  		// the position of test0 and test1 are swapped in monsterdata_java_wire
   380  		// and monsterdata_test_wire, so ignore ordering
   381  		v0 := test0.A()
   382  		v1 := test0.B()
   383  		v2 := test1.A()
   384  		v3 := test1.B()
   385  		sum := int(v0) + int(v1) + int(v2) + int(v3)
   386  
   387  		if 100 != sum {
   388  			fail(FailString("test0 and test1 sum", 100, sum))
   389  		}
   390  
   391  		if got := monster.TestarrayofstringLength(); 2 != got {
   392  			fail(FailString("Testarrayofstring length", 2, got))
   393  		}
   394  
   395  		if got := monster.Testarrayofstring(0); !bytes.Equal([]byte("test1"), got) {
   396  			fail(FailString("Testarrayofstring(0)", "test1", got))
   397  		}
   398  
   399  		if got := monster.Testarrayofstring(1); !bytes.Equal([]byte("test2"), got) {
   400  			fail(FailString("Testarrayofstring(1)", "test2", got))
   401  		}
   402  	}
   403  }
   404  
   405  // CheckFileIdentifier checks the "MONS" file identifier
   406  func CheckFileIdentifier(buf []byte, offset flatbuffers.UOffsetT, sizePrefix bool, fail func(string, ...interface{})) {
   407  	// Strip offset
   408  	buf = buf[offset:]
   409  
   410  	var fileIdentifier string
   411  	var hasFileIdentifier bool
   412  
   413  	if sizePrefix {
   414  		fileIdentifier = flatbuffers.GetSizePrefixedBufferIdentifier(buf)
   415  		hasFileIdentifier = example.SizePrefixedMonsterBufferHasIdentifier(buf)
   416  	} else {
   417  		fileIdentifier = flatbuffers.GetBufferIdentifier(buf)
   418  		hasFileIdentifier = example.MonsterBufferHasIdentifier(buf)
   419  	}
   420  
   421  	expectedFileIdentifier := "MONS"
   422  	if fileIdentifier != expectedFileIdentifier {
   423  		fail("expected file identifier %q, got %q", expectedFileIdentifier, fileIdentifier)
   424  	}
   425  	if !hasFileIdentifier {
   426  		fail("did not find file identifier")
   427  	}
   428  }
   429  
   430  // CheckMutateBuffer checks that the given buffer can be mutated correctly
   431  // as the example Monster. Only available scalar values are mutated.
   432  func CheckMutateBuffer(org []byte, offset flatbuffers.UOffsetT, sizePrefix bool, fail func(string, ...interface{})) {
   433  	// make a copy to mutate
   434  	buf := make([]byte, len(org))
   435  	copy(buf, org)
   436  
   437  	// load monster data from the buffer
   438  	var monster *example.Monster
   439  	if sizePrefix {
   440  		monster = example.GetSizePrefixedRootAsMonster(buf, offset)
   441  	} else {
   442  		monster = example.GetRootAsMonster(buf, offset)
   443  	}
   444  
   445  	// test case struct
   446  	type testcase struct {
   447  		field  string
   448  		testfn func() bool
   449  	}
   450  
   451  	testForOriginalValues := []testcase{
   452  		testcase{"Hp", func() bool { return monster.Hp() == 80 }},
   453  		testcase{"Mana", func() bool { return monster.Mana() == 150 }},
   454  		testcase{"Testbool", func() bool { return monster.Testbool() == true }},
   455  		testcase{"Pos.X'", func() bool { return monster.Pos(nil).X() == float32(1.0) }},
   456  		testcase{"Pos.Y'", func() bool { return monster.Pos(nil).Y() == float32(2.0) }},
   457  		testcase{"Pos.Z'", func() bool { return monster.Pos(nil).Z() == float32(3.0) }},
   458  		testcase{"Pos.Test1'", func() bool { return monster.Pos(nil).Test1() == float64(3.0) }},
   459  		testcase{"Pos.Test2'", func() bool { return monster.Pos(nil).Test2() == example.ColorGreen }},
   460  		testcase{"Pos.Test3.A", func() bool { return monster.Pos(nil).Test3(nil).A() == int16(5) }},
   461  		testcase{"Pos.Test3.B", func() bool { return monster.Pos(nil).Test3(nil).B() == int8(6) }},
   462  		testcase{"Inventory[2]", func() bool { return monster.Inventory(2) == byte(2) }},
   463  	}
   464  
   465  	testMutability := []testcase{
   466  		testcase{"Hp", func() bool { return monster.MutateHp(70) }},
   467  		testcase{"Mana", func() bool { return !monster.MutateMana(140) }},
   468  		testcase{"Testbool", func() bool { return monster.MutateTestbool(false) }},
   469  		testcase{"Pos.X", func() bool { return monster.Pos(nil).MutateX(10.0) }},
   470  		testcase{"Pos.Y", func() bool { return monster.Pos(nil).MutateY(20.0) }},
   471  		testcase{"Pos.Z", func() bool { return monster.Pos(nil).MutateZ(30.0) }},
   472  		testcase{"Pos.Test1", func() bool { return monster.Pos(nil).MutateTest1(30.0) }},
   473  		testcase{"Pos.Test2", func() bool { return monster.Pos(nil).MutateTest2(example.ColorBlue) }},
   474  		testcase{"Pos.Test3.A", func() bool { return monster.Pos(nil).Test3(nil).MutateA(50) }},
   475  		testcase{"Pos.Test3.B", func() bool { return monster.Pos(nil).Test3(nil).MutateB(60) }},
   476  		testcase{"Inventory[2]", func() bool { return monster.MutateInventory(2, 200) }},
   477  	}
   478  
   479  	testForMutatedValues := []testcase{
   480  		testcase{"Hp", func() bool { return monster.Hp() == 70 }},
   481  		testcase{"Mana", func() bool { return monster.Mana() == 150 }},
   482  		testcase{"Testbool", func() bool { return monster.Testbool() == false }},
   483  		testcase{"Pos.X'", func() bool { return monster.Pos(nil).X() == float32(10.0) }},
   484  		testcase{"Pos.Y'", func() bool { return monster.Pos(nil).Y() == float32(20.0) }},
   485  		testcase{"Pos.Z'", func() bool { return monster.Pos(nil).Z() == float32(30.0) }},
   486  		testcase{"Pos.Test1'", func() bool { return monster.Pos(nil).Test1() == float64(30.0) }},
   487  		testcase{"Pos.Test2'", func() bool { return monster.Pos(nil).Test2() == example.ColorBlue }},
   488  		testcase{"Pos.Test3.A", func() bool { return monster.Pos(nil).Test3(nil).A() == int16(50) }},
   489  		testcase{"Pos.Test3.B", func() bool { return monster.Pos(nil).Test3(nil).B() == int8(60) }},
   490  		testcase{"Inventory[2]", func() bool { return monster.Inventory(2) == byte(200) }},
   491  	}
   492  
   493  	testInvalidEnumValues := []testcase{
   494  		testcase{"Pos.Test2", func() bool { return monster.Pos(nil).MutateTest2(example.Color(20)) }},
   495  		testcase{"Pos.Test2", func() bool { return monster.Pos(nil).Test2() == example.Color(20) }},
   496  	}
   497  
   498  	// make sure original values are okay
   499  	for _, t := range testForOriginalValues {
   500  		if !t.testfn() {
   501  			fail("field '" + t.field + "' doesn't have the expected original value")
   502  		}
   503  	}
   504  
   505  	// try to mutate fields and check mutability
   506  	for _, t := range testMutability {
   507  		if !t.testfn() {
   508  			fail(FailString("field '"+t.field+"' failed mutability test", true, false))
   509  		}
   510  	}
   511  
   512  	// test whether values have changed
   513  	for _, t := range testForMutatedValues {
   514  		if !t.testfn() {
   515  			fail("field '" + t.field + "' doesn't have the expected mutated value")
   516  		}
   517  	}
   518  
   519  	// make sure the buffer has changed
   520  	if reflect.DeepEqual(buf, org) {
   521  		fail("mutate buffer failed")
   522  	}
   523  
   524  	// To make sure the buffer has changed accordingly
   525  	// Read data from the buffer and verify all fields
   526  	if sizePrefix {
   527  		monster = example.GetSizePrefixedRootAsMonster(buf, offset)
   528  	} else {
   529  		monster = example.GetRootAsMonster(buf, offset)
   530  	}
   531  
   532  	for _, t := range testForMutatedValues {
   533  		if !t.testfn() {
   534  			fail("field '" + t.field + "' doesn't have the expected mutated value")
   535  		}
   536  	}
   537  
   538  	// a couple extra tests for "invalid" enum values, which don't correspond to
   539  	// anything in the schema, but are allowed
   540  	for _, t := range testInvalidEnumValues {
   541  		if !t.testfn() {
   542  			fail("field '" + t.field + "' doesn't work with an invalid enum value")
   543  		}
   544  	}
   545  
   546  	// reverting all fields to original values should
   547  	// re-create the original buffer. Mutate all fields
   548  	// back to their original values and compare buffers.
   549  	// This test is done to make sure mutations do not do
   550  	// any unnecessary changes to the buffer.
   551  	if sizePrefix {
   552  		monster = example.GetSizePrefixedRootAsMonster(buf, offset)
   553  	} else {
   554  		monster = example.GetRootAsMonster(buf, offset)
   555  	}
   556  
   557  	monster.MutateHp(80)
   558  	monster.MutateTestbool(true)
   559  	monster.Pos(nil).MutateX(1.0)
   560  	monster.Pos(nil).MutateY(2.0)
   561  	monster.Pos(nil).MutateZ(3.0)
   562  	monster.Pos(nil).MutateTest1(3.0)
   563  	monster.Pos(nil).MutateTest2(example.ColorGreen)
   564  	monster.Pos(nil).Test3(nil).MutateA(5)
   565  	monster.Pos(nil).Test3(nil).MutateB(6)
   566  	monster.MutateInventory(2, 2)
   567  
   568  	for _, t := range testForOriginalValues {
   569  		if !t.testfn() {
   570  			fail("field '" + t.field + "' doesn't have the expected original value")
   571  		}
   572  	}
   573  
   574  	// buffer should have original values
   575  	if !reflect.DeepEqual(buf, org) {
   576  		fail("revert changes failed")
   577  	}
   578  }
   579  
   580  func CheckObjectAPI(buf []byte, offset flatbuffers.UOffsetT, sizePrefix bool, fail func(string, ...interface{})) {
   581  	var monster *example.MonsterT
   582  
   583  	if sizePrefix {
   584  		monster = example.GetSizePrefixedRootAsMonster(buf, offset).UnPack()
   585  	} else {
   586  		monster = example.GetRootAsMonster(buf, offset).UnPack()
   587  	}
   588  
   589  	if got := monster.Hp; 80 != got {
   590  		fail(FailString("hp", 80, got))
   591  	}
   592  
   593  	// default
   594  	if got := monster.Mana; 150 != got {
   595  		fail(FailString("mana", 150, got))
   596  	}
   597  
   598  	if monster.Test != nil && monster.Test.Type == example.AnyMonster {
   599  		monster.Test.Value.(*example.MonsterT).NanDefault = 0.0
   600  	}
   601  	if monster.Enemy != nil {
   602  		monster.Enemy.NanDefault = 0.0
   603  	}
   604  	monster.NanDefault = 0.0
   605  
   606  	builder := flatbuffers.NewBuilder(0)
   607  	builder.Finish(monster.Pack(builder))
   608  	monster2 := example.GetRootAsMonster(builder.FinishedBytes(), 0).UnPack()
   609  	if !reflect.DeepEqual(monster, monster2) {
   610  		fail(FailString("Pack/Unpack()", monster, monster2))
   611  	}
   612  }
   613  
   614  // Low level stress/fuzz test: serialize/deserialize a variety of
   615  // different kinds of data in different combinations
   616  func checkFuzz(fuzzFields, fuzzObjects int, fail func(string, ...interface{})) {
   617  
   618  	// Values we're testing against: chosen to ensure no bits get chopped
   619  	// off anywhere, and also be different from eachother.
   620  	boolVal := true
   621  	int8Val := int8(-127) // 0x81
   622  	uint8Val := uint8(0xFF)
   623  	int16Val := int16(-32222) // 0x8222
   624  	uint16Val := uint16(0xFEEE)
   625  	int32Val := int32(overflowingInt32Val)
   626  	uint32Val := uint32(0xFDDDDDDD)
   627  	int64Val := int64(overflowingInt64Val)
   628  	uint64Val := uint64(0xFCCCCCCCCCCCCCCC)
   629  	float32Val := float32(3.14159)
   630  	float64Val := float64(3.14159265359)
   631  
   632  	testValuesMax := 11 // hardcoded to the number of scalar types
   633  
   634  	builder := flatbuffers.NewBuilder(0)
   635  	l := NewLCG()
   636  
   637  	objects := make([]flatbuffers.UOffsetT, fuzzObjects)
   638  
   639  	// Generate fuzzObjects random objects each consisting of
   640  	// fuzzFields fields, each of a random type.
   641  	for i := 0; i < fuzzObjects; i++ {
   642  		builder.StartObject(fuzzFields)
   643  
   644  		for f := 0; f < fuzzFields; f++ {
   645  			choice := l.Next() % uint32(testValuesMax)
   646  			switch choice {
   647  			case 0:
   648  				builder.PrependBoolSlot(int(f), boolVal, false)
   649  			case 1:
   650  				builder.PrependInt8Slot(int(f), int8Val, 0)
   651  			case 2:
   652  				builder.PrependUint8Slot(int(f), uint8Val, 0)
   653  			case 3:
   654  				builder.PrependInt16Slot(int(f), int16Val, 0)
   655  			case 4:
   656  				builder.PrependUint16Slot(int(f), uint16Val, 0)
   657  			case 5:
   658  				builder.PrependInt32Slot(int(f), int32Val, 0)
   659  			case 6:
   660  				builder.PrependUint32Slot(int(f), uint32Val, 0)
   661  			case 7:
   662  				builder.PrependInt64Slot(int(f), int64Val, 0)
   663  			case 8:
   664  				builder.PrependUint64Slot(int(f), uint64Val, 0)
   665  			case 9:
   666  				builder.PrependFloat32Slot(int(f), float32Val, 0)
   667  			case 10:
   668  				builder.PrependFloat64Slot(int(f), float64Val, 0)
   669  			}
   670  		}
   671  
   672  		off := builder.EndObject()
   673  
   674  		// store the offset from the end of the builder buffer,
   675  		// since it will keep growing:
   676  		objects[i] = off
   677  	}
   678  
   679  	// Do some bookkeeping to generate stats on fuzzes:
   680  	stats := map[string]int{}
   681  	check := func(desc string, want, got interface{}) {
   682  		stats[desc]++
   683  		if want != got {
   684  			fail("%s want %v got %v", desc, want, got)
   685  		}
   686  	}
   687  
   688  	l = NewLCG() // Reset.
   689  
   690  	// Test that all objects we generated are readable and return the
   691  	// expected values. We generate random objects in the same order
   692  	// so this is deterministic.
   693  	for i := 0; i < fuzzObjects; i++ {
   694  
   695  		table := &flatbuffers.Table{
   696  			Bytes: builder.Bytes,
   697  			Pos:   flatbuffers.UOffsetT(len(builder.Bytes)) - objects[i],
   698  		}
   699  
   700  		for j := 0; j < fuzzFields; j++ {
   701  			f := flatbuffers.VOffsetT((flatbuffers.VtableMetadataFields + j) * flatbuffers.SizeVOffsetT)
   702  			choice := l.Next() % uint32(testValuesMax)
   703  
   704  			switch choice {
   705  			case 0:
   706  				check("bool", boolVal, table.GetBoolSlot(f, false))
   707  			case 1:
   708  				check("int8", int8Val, table.GetInt8Slot(f, 0))
   709  			case 2:
   710  				check("uint8", uint8Val, table.GetUint8Slot(f, 0))
   711  			case 3:
   712  				check("int16", int16Val, table.GetInt16Slot(f, 0))
   713  			case 4:
   714  				check("uint16", uint16Val, table.GetUint16Slot(f, 0))
   715  			case 5:
   716  				check("int32", int32Val, table.GetInt32Slot(f, 0))
   717  			case 6:
   718  				check("uint32", uint32Val, table.GetUint32Slot(f, 0))
   719  			case 7:
   720  				check("int64", int64Val, table.GetInt64Slot(f, 0))
   721  			case 8:
   722  				check("uint64", uint64Val, table.GetUint64Slot(f, 0))
   723  			case 9:
   724  				check("float32", float32Val, table.GetFloat32Slot(f, 0))
   725  			case 10:
   726  				check("float64", float64Val, table.GetFloat64Slot(f, 0))
   727  			}
   728  		}
   729  	}
   730  
   731  	// If enough checks were made, verify that all scalar types were used:
   732  	if fuzzFields*fuzzObjects >= testValuesMax {
   733  		if len(stats) != testValuesMax {
   734  			fail("fuzzing failed to test all scalar types")
   735  		}
   736  	}
   737  
   738  	// Print some counts, if needed:
   739  	if testing.Verbose() {
   740  		if fuzzFields == 0 || fuzzObjects == 0 {
   741  			fmt.Printf("fuzz\tfields: %d\tobjects: %d\t[none]\t%d\n",
   742  				fuzzFields, fuzzObjects, 0)
   743  		} else {
   744  			keys := make([]string, 0, len(stats))
   745  			for k := range stats {
   746  				keys = append(keys, k)
   747  			}
   748  			sort.Strings(keys)
   749  			for _, k := range keys {
   750  				fmt.Printf("fuzz\tfields: %d\tobjects: %d\t%s\t%d\n",
   751  					fuzzFields, fuzzObjects, k, stats[k])
   752  			}
   753  		}
   754  	}
   755  
   756  	return
   757  }
   758  
   759  // FailString makes a message for when expectations differ from reality.
   760  func FailString(name string, want, got interface{}) string {
   761  	return fmt.Sprintf("bad %s: want %#v got %#v", name, want, got)
   762  }
   763  
   764  // CheckByteLayout verifies the bytes of a Builder in various scenarios.
   765  func CheckByteLayout(fail func(string, ...interface{})) {
   766  	var b *flatbuffers.Builder
   767  
   768  	var i int
   769  	check := func(want []byte) {
   770  		i++
   771  		got := b.Bytes[b.Head():]
   772  		if !bytes.Equal(want, got) {
   773  			fail("case %d: want\n%v\nbut got\n%v\n", i, want, got)
   774  		}
   775  	}
   776  
   777  	// test 1: numbers
   778  
   779  	b = flatbuffers.NewBuilder(0)
   780  	check([]byte{})
   781  	b.PrependBool(true)
   782  	check([]byte{1})
   783  	b.PrependInt8(-127)
   784  	check([]byte{129, 1})
   785  	b.PrependUint8(255)
   786  	check([]byte{255, 129, 1})
   787  	b.PrependInt16(-32222)
   788  	check([]byte{0x22, 0x82, 0, 255, 129, 1}) // first pad
   789  	b.PrependUint16(0xFEEE)
   790  	check([]byte{0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1}) // no pad this time
   791  	b.PrependInt32(-53687092)
   792  	check([]byte{204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1})
   793  	b.PrependUint32(0x98765432)
   794  	check([]byte{0x32, 0x54, 0x76, 0x98, 204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1})
   795  
   796  	// test 1b: numbers 2
   797  
   798  	b = flatbuffers.NewBuilder(0)
   799  	b.PrependUint64(0x1122334455667788)
   800  	check([]byte{0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11})
   801  
   802  	// test 2: 1xbyte vector
   803  
   804  	b = flatbuffers.NewBuilder(0)
   805  	check([]byte{})
   806  	b.StartVector(flatbuffers.SizeByte, 1, 1)
   807  	check([]byte{0, 0, 0}) // align to 4bytes
   808  	b.PrependByte(1)
   809  	check([]byte{1, 0, 0, 0})
   810  	b.EndVector(1)
   811  	check([]byte{1, 0, 0, 0, 1, 0, 0, 0}) // padding
   812  
   813  	// test 3: 2xbyte vector
   814  
   815  	b = flatbuffers.NewBuilder(0)
   816  	b.StartVector(flatbuffers.SizeByte, 2, 1)
   817  	check([]byte{0, 0}) // align to 4bytes
   818  	b.PrependByte(1)
   819  	check([]byte{1, 0, 0})
   820  	b.PrependByte(2)
   821  	check([]byte{2, 1, 0, 0})
   822  	b.EndVector(2)
   823  	check([]byte{2, 0, 0, 0, 2, 1, 0, 0}) // padding
   824  
   825  	// test 3b: 11xbyte vector matches builder size
   826  
   827  	b = flatbuffers.NewBuilder(12)
   828  	b.StartVector(flatbuffers.SizeByte, 8, 1)
   829  	start := []byte{}
   830  	check(start)
   831  	for i := 1; i < 12; i++ {
   832  		b.PrependByte(byte(i))
   833  		start = append([]byte{byte(i)}, start...)
   834  		check(start)
   835  	}
   836  	b.EndVector(8)
   837  	check(append([]byte{8, 0, 0, 0}, start...))
   838  
   839  	// test 4: 1xuint16 vector
   840  
   841  	b = flatbuffers.NewBuilder(0)
   842  	b.StartVector(flatbuffers.SizeUint16, 1, 1)
   843  	check([]byte{0, 0}) // align to 4bytes
   844  	b.PrependUint16(1)
   845  	check([]byte{1, 0, 0, 0})
   846  	b.EndVector(1)
   847  	check([]byte{1, 0, 0, 0, 1, 0, 0, 0}) // padding
   848  
   849  	// test 5: 2xuint16 vector
   850  
   851  	b = flatbuffers.NewBuilder(0)
   852  	b.StartVector(flatbuffers.SizeUint16, 2, 1)
   853  	check([]byte{}) // align to 4bytes
   854  	b.PrependUint16(0xABCD)
   855  	check([]byte{0xCD, 0xAB})
   856  	b.PrependUint16(0xDCBA)
   857  	check([]byte{0xBA, 0xDC, 0xCD, 0xAB})
   858  	b.EndVector(2)
   859  	check([]byte{2, 0, 0, 0, 0xBA, 0xDC, 0xCD, 0xAB})
   860  
   861  	// test 6: CreateString
   862  
   863  	b = flatbuffers.NewBuilder(0)
   864  	b.CreateString("foo")
   865  	check([]byte{3, 0, 0, 0, 'f', 'o', 'o', 0}) // 0-terminated, no pad
   866  	b.CreateString("moop")
   867  	check([]byte{4, 0, 0, 0, 'm', 'o', 'o', 'p', 0, 0, 0, 0, // 0-terminated, 3-byte pad
   868  		3, 0, 0, 0, 'f', 'o', 'o', 0})
   869  
   870  	// test 6b: CreateString unicode
   871  
   872  	b = flatbuffers.NewBuilder(0)
   873  	// These characters are chinese from blog.golang.org/strings
   874  	// We use escape codes here so that editors without unicode support
   875  	// aren't bothered:
   876  	uni_str := "\u65e5\u672c\u8a9e"
   877  	b.CreateString(uni_str)
   878  	check([]byte{9, 0, 0, 0, 230, 151, 165, 230, 156, 172, 232, 170, 158, 0, //  null-terminated, 2-byte pad
   879  		0, 0})
   880  
   881  	// test 6c: CreateByteString
   882  
   883  	b = flatbuffers.NewBuilder(0)
   884  	b.CreateByteString([]byte("foo"))
   885  	check([]byte{3, 0, 0, 0, 'f', 'o', 'o', 0}) // 0-terminated, no pad
   886  	b.CreateByteString([]byte("moop"))
   887  	check([]byte{4, 0, 0, 0, 'm', 'o', 'o', 'p', 0, 0, 0, 0, // 0-terminated, 3-byte pad
   888  		3, 0, 0, 0, 'f', 'o', 'o', 0})
   889  
   890  	// test 7: empty vtable
   891  	b = flatbuffers.NewBuilder(0)
   892  	b.StartObject(0)
   893  	check([]byte{})
   894  	b.EndObject()
   895  	check([]byte{4, 0, 4, 0, 4, 0, 0, 0})
   896  
   897  	// test 8: vtable with one true bool
   898  	b = flatbuffers.NewBuilder(0)
   899  	check([]byte{})
   900  	b.StartObject(1)
   901  	check([]byte{})
   902  	b.PrependBoolSlot(0, true, false)
   903  	b.EndObject()
   904  	check([]byte{
   905  		6, 0, // vtable bytes
   906  		8, 0, // length of object including vtable offset
   907  		7, 0, // start of bool value
   908  		6, 0, 0, 0, // offset for start of vtable (int32)
   909  		0, 0, 0, // padded to 4 bytes
   910  		1, // bool value
   911  	})
   912  
   913  	// test 9: vtable with one default bool
   914  	b = flatbuffers.NewBuilder(0)
   915  	check([]byte{})
   916  	b.StartObject(1)
   917  	check([]byte{})
   918  	b.PrependBoolSlot(0, false, false)
   919  	b.EndObject()
   920  	check([]byte{
   921  		4, 0, // vtable bytes
   922  		4, 0, // end of object from here
   923  		// entry 1 is zero and not stored.
   924  		4, 0, 0, 0, // offset for start of vtable (int32)
   925  	})
   926  
   927  	// test 10: vtable with one int16
   928  	b = flatbuffers.NewBuilder(0)
   929  	b.StartObject(1)
   930  	b.PrependInt16Slot(0, 0x789A, 0)
   931  	b.EndObject()
   932  	check([]byte{
   933  		6, 0, // vtable bytes
   934  		8, 0, // end of object from here
   935  		6, 0, // offset to value
   936  		6, 0, 0, 0, // offset for start of vtable (int32)
   937  		0, 0, // padding to 4 bytes
   938  		0x9A, 0x78,
   939  	})
   940  
   941  	// test 11: vtable with two int16
   942  	b = flatbuffers.NewBuilder(0)
   943  	b.StartObject(2)
   944  	b.PrependInt16Slot(0, 0x3456, 0)
   945  	b.PrependInt16Slot(1, 0x789A, 0)
   946  	b.EndObject()
   947  	check([]byte{
   948  		8, 0, // vtable bytes
   949  		8, 0, // end of object from here
   950  		6, 0, // offset to value 0
   951  		4, 0, // offset to value 1
   952  		8, 0, 0, 0, // offset for start of vtable (int32)
   953  		0x9A, 0x78, // value 1
   954  		0x56, 0x34, // value 0
   955  	})
   956  
   957  	// test 12: vtable with int16 and bool
   958  	b = flatbuffers.NewBuilder(0)
   959  	b.StartObject(2)
   960  	b.PrependInt16Slot(0, 0x3456, 0)
   961  	b.PrependBoolSlot(1, true, false)
   962  	b.EndObject()
   963  	check([]byte{
   964  		8, 0, // vtable bytes
   965  		8, 0, // end of object from here
   966  		6, 0, // offset to value 0
   967  		5, 0, // offset to value 1
   968  		8, 0, 0, 0, // offset for start of vtable (int32)
   969  		0,          // padding
   970  		1,          // value 1
   971  		0x56, 0x34, // value 0
   972  	})
   973  
   974  	// test 12: vtable with empty vector
   975  	b = flatbuffers.NewBuilder(0)
   976  	b.StartVector(flatbuffers.SizeByte, 0, 1)
   977  	vecend := b.EndVector(0)
   978  	b.StartObject(1)
   979  	b.PrependUOffsetTSlot(0, vecend, 0)
   980  	b.EndObject()
   981  	check([]byte{
   982  		6, 0, // vtable bytes
   983  		8, 0,
   984  		4, 0, // offset to vector offset
   985  		6, 0, 0, 0, // offset for start of vtable (int32)
   986  		4, 0, 0, 0,
   987  		0, 0, 0, 0, // length of vector (not in struct)
   988  	})
   989  
   990  	// test 12b: vtable with empty vector of byte and some scalars
   991  	b = flatbuffers.NewBuilder(0)
   992  	b.StartVector(flatbuffers.SizeByte, 0, 1)
   993  	vecend = b.EndVector(0)
   994  	b.StartObject(2)
   995  	b.PrependInt16Slot(0, 55, 0)
   996  	b.PrependUOffsetTSlot(1, vecend, 0)
   997  	b.EndObject()
   998  	check([]byte{
   999  		8, 0, // vtable bytes
  1000  		12, 0,
  1001  		10, 0, // offset to value 0
  1002  		4, 0, // offset to vector offset
  1003  		8, 0, 0, 0, // vtable loc
  1004  		8, 0, 0, 0, // value 1
  1005  		0, 0, 55, 0, // value 0
  1006  
  1007  		0, 0, 0, 0, // length of vector (not in struct)
  1008  	})
  1009  
  1010  	// test 13: vtable with 1 int16 and 2-vector of int16
  1011  	b = flatbuffers.NewBuilder(0)
  1012  	b.StartVector(flatbuffers.SizeInt16, 2, 1)
  1013  	b.PrependInt16(0x1234)
  1014  	b.PrependInt16(0x5678)
  1015  	vecend = b.EndVector(2)
  1016  	b.StartObject(2)
  1017  	b.PrependUOffsetTSlot(1, vecend, 0)
  1018  	b.PrependInt16Slot(0, 55, 0)
  1019  	b.EndObject()
  1020  	check([]byte{
  1021  		8, 0, // vtable bytes
  1022  		12, 0, // length of object
  1023  		6, 0, // start of value 0 from end of vtable
  1024  		8, 0, // start of value 1 from end of buffer
  1025  		8, 0, 0, 0, // offset for start of vtable (int32)
  1026  		0, 0, // padding
  1027  		55, 0, // value 0
  1028  		4, 0, 0, 0, // vector position from here
  1029  		2, 0, 0, 0, // length of vector (uint32)
  1030  		0x78, 0x56, // vector value 1
  1031  		0x34, 0x12, // vector value 0
  1032  	})
  1033  
  1034  	// test 14: vtable with 1 struct of 1 int8, 1 int16, 1 int32
  1035  	b = flatbuffers.NewBuilder(0)
  1036  	b.StartObject(1)
  1037  	b.Prep(4+4+4, 0)
  1038  	b.PrependInt8(55)
  1039  	b.Pad(3)
  1040  	b.PrependInt16(0x1234)
  1041  	b.Pad(2)
  1042  	b.PrependInt32(0x12345678)
  1043  	structStart := b.Offset()
  1044  	b.PrependStructSlot(0, structStart, 0)
  1045  	b.EndObject()
  1046  	check([]byte{
  1047  		6, 0, // vtable bytes
  1048  		16, 0, // end of object from here
  1049  		4, 0, // start of struct from here
  1050  		6, 0, 0, 0, // offset for start of vtable (int32)
  1051  		0x78, 0x56, 0x34, 0x12, // value 2
  1052  		0, 0, // padding
  1053  		0x34, 0x12, // value 1
  1054  		0, 0, 0, // padding
  1055  		55, // value 0
  1056  	})
  1057  
  1058  	// test 15: vtable with 1 vector of 2 struct of 2 int8
  1059  	b = flatbuffers.NewBuilder(0)
  1060  	b.StartVector(flatbuffers.SizeInt8*2, 2, 1)
  1061  	b.PrependInt8(33)
  1062  	b.PrependInt8(44)
  1063  	b.PrependInt8(55)
  1064  	b.PrependInt8(66)
  1065  	vecend = b.EndVector(2)
  1066  	b.StartObject(1)
  1067  	b.PrependUOffsetTSlot(0, vecend, 0)
  1068  	b.EndObject()
  1069  	check([]byte{
  1070  		6, 0, // vtable bytes
  1071  		8, 0,
  1072  		4, 0, // offset of vector offset
  1073  		6, 0, 0, 0, // offset for start of vtable (int32)
  1074  		4, 0, 0, 0, // vector start offset
  1075  
  1076  		2, 0, 0, 0, // vector length
  1077  		66, // vector value 1,1
  1078  		55, // vector value 1,0
  1079  		44, // vector value 0,1
  1080  		33, // vector value 0,0
  1081  	})
  1082  
  1083  	// test 16: table with some elements
  1084  	b = flatbuffers.NewBuilder(0)
  1085  	b.StartObject(2)
  1086  	b.PrependInt8Slot(0, 33, 0)
  1087  	b.PrependInt16Slot(1, 66, 0)
  1088  	off := b.EndObject()
  1089  	b.Finish(off)
  1090  
  1091  	check([]byte{
  1092  		12, 0, 0, 0, // root of table: points to vtable offset
  1093  
  1094  		8, 0, // vtable bytes
  1095  		8, 0, // end of object from here
  1096  		7, 0, // start of value 0
  1097  		4, 0, // start of value 1
  1098  
  1099  		8, 0, 0, 0, // offset for start of vtable (int32)
  1100  
  1101  		66, 0, // value 1
  1102  		0,  // padding
  1103  		33, // value 0
  1104  	})
  1105  
  1106  	// test 16b: same as test 16, size prefixed
  1107  	b = flatbuffers.NewBuilder(0)
  1108  	b.StartObject(2)
  1109  	b.PrependInt8Slot(0, 33, 0)
  1110  	b.PrependInt16Slot(1, 66, 0)
  1111  	off = b.EndObject()
  1112  	b.FinishSizePrefixed(off)
  1113  
  1114  	check([]byte{
  1115  		20, 0, 0, 0, // size prefix
  1116  		12, 0, 0, 0, // root of table: points to vtable offset
  1117  
  1118  		8, 0, // vtable bytes
  1119  		8, 0, // end of object from here
  1120  		7, 0, // start of value 0
  1121  		4, 0, // start of value 1
  1122  
  1123  		8, 0, 0, 0, // offset for start of vtable (int32)
  1124  
  1125  		66, 0, // value 1
  1126  		0,  // padding
  1127  		33, // value 0
  1128  	})
  1129  
  1130  	// test 16c: same as test 16, with file identifier
  1131  	b = flatbuffers.NewBuilder(0)
  1132  	b.StartObject(2)
  1133  	b.PrependInt8Slot(0, 33, 0)
  1134  	b.PrependInt16Slot(1, 66, 0)
  1135  	off = b.EndObject()
  1136  	b.FinishWithFileIdentifier(off, []byte("TEST"))
  1137  
  1138  	check([]byte{
  1139  		16, 0, 0, 0, // root of table: points to vtable offset
  1140  		'T', 'E', 'S', 'T', // file identifier
  1141  
  1142  		8, 0, // vtable bytes
  1143  		8, 0, // end of object from here
  1144  		7, 0, // start of value 0
  1145  		4, 0, // start of value 1
  1146  
  1147  		8, 0, 0, 0, // offset for start of vtable (int32)
  1148  
  1149  		66, 0, // value 1
  1150  		0,  // padding
  1151  		33, // value 0
  1152  	})
  1153  
  1154  	// test 16d: same as test 16, size prefixed with file identifier
  1155  	b = flatbuffers.NewBuilder(0)
  1156  	b.StartObject(2)
  1157  	b.PrependInt8Slot(0, 33, 0)
  1158  	b.PrependInt16Slot(1, 66, 0)
  1159  	off = b.EndObject()
  1160  	b.FinishSizePrefixedWithFileIdentifier(off, []byte("TEST"))
  1161  
  1162  	check([]byte{
  1163  		24, 0, 0, 0, // size prefix
  1164  		16, 0, 0, 0, // root of table: points to vtable offset
  1165  		'T', 'E', 'S', 'T', // file identifier
  1166  
  1167  		8, 0, // vtable bytes
  1168  		8, 0, // end of object from here
  1169  		7, 0, // start of value 0
  1170  		4, 0, // start of value 1
  1171  
  1172  		8, 0, 0, 0, // offset for start of vtable (int32)
  1173  
  1174  		66, 0, // value 1
  1175  		0,  // padding
  1176  		33, // value 0
  1177  	})
  1178  
  1179  	// test 17: one unfinished table and one finished table
  1180  	b = flatbuffers.NewBuilder(0)
  1181  	b.StartObject(2)
  1182  	b.PrependInt8Slot(0, 33, 0)
  1183  	b.PrependInt8Slot(1, 44, 0)
  1184  	off = b.EndObject()
  1185  	b.Finish(off)
  1186  
  1187  	b.StartObject(3)
  1188  	b.PrependInt8Slot(0, 55, 0)
  1189  	b.PrependInt8Slot(1, 66, 0)
  1190  	b.PrependInt8Slot(2, 77, 0)
  1191  	off = b.EndObject()
  1192  	b.Finish(off)
  1193  
  1194  	check([]byte{
  1195  		16, 0, 0, 0, // root of table: points to object
  1196  		0, 0, // padding
  1197  
  1198  		10, 0, // vtable bytes
  1199  		8, 0, // size of object
  1200  		7, 0, // start of value 0
  1201  		6, 0, // start of value 1
  1202  		5, 0, // start of value 2
  1203  		10, 0, 0, 0, // offset for start of vtable (int32)
  1204  		0,  // padding
  1205  		77, // value 2
  1206  		66, // value 1
  1207  		55, // value 0
  1208  
  1209  		12, 0, 0, 0, // root of table: points to object
  1210  
  1211  		8, 0, // vtable bytes
  1212  		8, 0, // size of object
  1213  		7, 0, // start of value 0
  1214  		6, 0, // start of value 1
  1215  		8, 0, 0, 0, // offset for start of vtable (int32)
  1216  		0, 0, // padding
  1217  		44, // value 1
  1218  		33, // value 0
  1219  	})
  1220  
  1221  	// test 18: a bunch of bools
  1222  	b = flatbuffers.NewBuilder(0)
  1223  	b.StartObject(8)
  1224  	b.PrependBoolSlot(0, true, false)
  1225  	b.PrependBoolSlot(1, true, false)
  1226  	b.PrependBoolSlot(2, true, false)
  1227  	b.PrependBoolSlot(3, true, false)
  1228  	b.PrependBoolSlot(4, true, false)
  1229  	b.PrependBoolSlot(5, true, false)
  1230  	b.PrependBoolSlot(6, true, false)
  1231  	b.PrependBoolSlot(7, true, false)
  1232  	off = b.EndObject()
  1233  	b.Finish(off)
  1234  
  1235  	check([]byte{
  1236  		24, 0, 0, 0, // root of table: points to vtable offset
  1237  
  1238  		20, 0, // vtable bytes
  1239  		12, 0, // size of object
  1240  		11, 0, // start of value 0
  1241  		10, 0, // start of value 1
  1242  		9, 0, // start of value 2
  1243  		8, 0, // start of value 3
  1244  		7, 0, // start of value 4
  1245  		6, 0, // start of value 5
  1246  		5, 0, // start of value 6
  1247  		4, 0, // start of value 7
  1248  		20, 0, 0, 0, // vtable offset
  1249  
  1250  		1, // value 7
  1251  		1, // value 6
  1252  		1, // value 5
  1253  		1, // value 4
  1254  		1, // value 3
  1255  		1, // value 2
  1256  		1, // value 1
  1257  		1, // value 0
  1258  	})
  1259  
  1260  	// test 19: three bools
  1261  	b = flatbuffers.NewBuilder(0)
  1262  	b.StartObject(3)
  1263  	b.PrependBoolSlot(0, true, false)
  1264  	b.PrependBoolSlot(1, true, false)
  1265  	b.PrependBoolSlot(2, true, false)
  1266  	off = b.EndObject()
  1267  	b.Finish(off)
  1268  
  1269  	check([]byte{
  1270  		16, 0, 0, 0, // root of table: points to vtable offset
  1271  
  1272  		0, 0, // padding
  1273  
  1274  		10, 0, // vtable bytes
  1275  		8, 0, // size of object
  1276  		7, 0, // start of value 0
  1277  		6, 0, // start of value 1
  1278  		5, 0, // start of value 2
  1279  		10, 0, 0, 0, // vtable offset from here
  1280  
  1281  		0, // padding
  1282  		1, // value 2
  1283  		1, // value 1
  1284  		1, // value 0
  1285  	})
  1286  
  1287  	// test 20: some floats
  1288  	b = flatbuffers.NewBuilder(0)
  1289  	b.StartObject(1)
  1290  	b.PrependFloat32Slot(0, 1.0, 0.0)
  1291  	off = b.EndObject()
  1292  
  1293  	check([]byte{
  1294  		6, 0, // vtable bytes
  1295  		8, 0, // size of object
  1296  		4, 0, // start of value 0
  1297  		6, 0, 0, 0, // vtable offset
  1298  
  1299  		0, 0, 128, 63, // value 0
  1300  	})
  1301  }
  1302  
  1303  // CheckManualBuild builds a Monster manually.
  1304  func CheckManualBuild(fail func(string, ...interface{})) ([]byte, flatbuffers.UOffsetT) {
  1305  	b := flatbuffers.NewBuilder(0)
  1306  	str := b.CreateString("MyMonster")
  1307  
  1308  	b.StartVector(1, 5, 1)
  1309  	b.PrependByte(4)
  1310  	b.PrependByte(3)
  1311  	b.PrependByte(2)
  1312  	b.PrependByte(1)
  1313  	b.PrependByte(0)
  1314  	inv := b.EndVector(5)
  1315  
  1316  	b.StartObject(13)
  1317  	b.PrependInt16Slot(2, 20, 100)
  1318  	mon2 := b.EndObject()
  1319  
  1320  	// Test4Vector
  1321  	b.StartVector(4, 2, 1)
  1322  
  1323  	// Test 0
  1324  	b.Prep(2, 4)
  1325  	b.Pad(1)
  1326  	b.PlaceInt8(20)
  1327  	b.PlaceInt16(10)
  1328  
  1329  	// Test 1
  1330  	b.Prep(2, 4)
  1331  	b.Pad(1)
  1332  	b.PlaceInt8(40)
  1333  	b.PlaceInt16(30)
  1334  
  1335  	// end testvector
  1336  	test4 := b.EndVector(2)
  1337  
  1338  	b.StartObject(13)
  1339  
  1340  	// a vec3
  1341  	b.Prep(16, 32)
  1342  	b.Pad(2)
  1343  	b.Prep(2, 4)
  1344  	b.Pad(1)
  1345  	b.PlaceByte(6)
  1346  	b.PlaceInt16(5)
  1347  	b.Pad(1)
  1348  	b.PlaceByte(4)
  1349  	b.PlaceFloat64(3.0)
  1350  	b.Pad(4)
  1351  	b.PlaceFloat32(3.0)
  1352  	b.PlaceFloat32(2.0)
  1353  	b.PlaceFloat32(1.0)
  1354  	vec3Loc := b.Offset()
  1355  	// end vec3
  1356  
  1357  	b.PrependStructSlot(0, vec3Loc, 0) // vec3. noop
  1358  	b.PrependInt16Slot(2, 80, 100)     // hp
  1359  	b.PrependUOffsetTSlot(3, str, 0)
  1360  	b.PrependUOffsetTSlot(5, inv, 0) // inventory
  1361  	b.PrependByteSlot(7, 1, 0)
  1362  	b.PrependUOffsetTSlot(8, mon2, 0)
  1363  	b.PrependUOffsetTSlot(9, test4, 0)
  1364  	mon := b.EndObject()
  1365  
  1366  	b.Finish(mon)
  1367  
  1368  	return b.Bytes, b.Head()
  1369  }
  1370  
  1371  func CheckGetRootAsForNonRootTable(fail func(string, ...interface{})) {
  1372  	b := flatbuffers.NewBuilder(0)
  1373  	str := b.CreateString("MyStat")
  1374  	example.StatStart(b)
  1375  	example.StatAddId(b, str)
  1376  	example.StatAddVal(b, 12345678)
  1377  	example.StatAddCount(b, 12345)
  1378  	stat_end := example.StatEnd(b)
  1379  	b.Finish(stat_end)
  1380  
  1381  	stat := example.GetRootAsStat(b.Bytes, b.Head())
  1382  
  1383  	if got := stat.Id(); !bytes.Equal([]byte("MyStat"), got) {
  1384  		fail(FailString("stat.Id()", "MyStat", got))
  1385  	}
  1386  
  1387  	if got := stat.Val(); 12345678 != got {
  1388  		fail(FailString("stat.Val()", 12345678, got))
  1389  	}
  1390  
  1391  	if got := stat.Count(); 12345 != got {
  1392  		fail(FailString("stat.Count()", 12345, got))
  1393  	}
  1394  }
  1395  
  1396  // CheckGeneratedBuild uses generated code to build the example Monster.
  1397  func CheckGeneratedBuild(sizePrefix, fileIdentifier bool, fail func(string, ...interface{})) ([]byte, flatbuffers.UOffsetT) {
  1398  	b := flatbuffers.NewBuilder(0)
  1399  	str := b.CreateString("MyMonster")
  1400  	test1 := b.CreateString("test1")
  1401  	test2 := b.CreateString("test2")
  1402  	fred := b.CreateString("Fred")
  1403  
  1404  	example.MonsterStartInventoryVector(b, 5)
  1405  	b.PrependByte(4)
  1406  	b.PrependByte(3)
  1407  	b.PrependByte(2)
  1408  	b.PrependByte(1)
  1409  	b.PrependByte(0)
  1410  	inv := b.EndVector(5)
  1411  
  1412  	example.MonsterStart(b)
  1413  	example.MonsterAddName(b, fred)
  1414  	mon2 := example.MonsterEnd(b)
  1415  
  1416  	example.MonsterStartTest4Vector(b, 2)
  1417  	example.CreateTest(b, 10, 20)
  1418  	example.CreateTest(b, 30, 40)
  1419  	test4 := b.EndVector(2)
  1420  
  1421  	example.MonsterStartTestarrayofstringVector(b, 2)
  1422  	b.PrependUOffsetT(test2)
  1423  	b.PrependUOffsetT(test1)
  1424  	testArrayOfString := b.EndVector(2)
  1425  
  1426  	example.MonsterStart(b)
  1427  
  1428  	pos := example.CreateVec3(b, 1.0, 2.0, 3.0, 3.0, example.ColorGreen, 5, 6)
  1429  	example.MonsterAddPos(b, pos)
  1430  
  1431  	example.MonsterAddHp(b, 80)
  1432  	example.MonsterAddName(b, str)
  1433  	example.MonsterAddTestbool(b, true)
  1434  	example.MonsterAddInventory(b, inv)
  1435  	example.MonsterAddTestType(b, 1)
  1436  	example.MonsterAddTest(b, mon2)
  1437  	example.MonsterAddTest4(b, test4)
  1438  	example.MonsterAddTestarrayofstring(b, testArrayOfString)
  1439  	mon := example.MonsterEnd(b)
  1440  
  1441  	if fileIdentifier {
  1442  		if sizePrefix {
  1443  			example.FinishSizePrefixedMonsterBuffer(b, mon)
  1444  		} else {
  1445  			example.FinishMonsterBuffer(b, mon)
  1446  		}
  1447  	} else {
  1448  		if sizePrefix {
  1449  			b.FinishSizePrefixed(mon)
  1450  		} else {
  1451  			b.Finish(mon)
  1452  		}
  1453  	}
  1454  
  1455  	return b.Bytes, b.Head()
  1456  }
  1457  
  1458  // CheckTableAccessors checks that the table accessors work as expected.
  1459  func CheckTableAccessors(fail func(string, ...interface{})) {
  1460  	// test struct accessor
  1461  	b := flatbuffers.NewBuilder(0)
  1462  	pos := example.CreateVec3(b, 1.0, 2.0, 3.0, 3.0, 4, 5, 6)
  1463  	b.Finish(pos)
  1464  	vec3Bytes := b.FinishedBytes()
  1465  	vec3 := &example.Vec3{}
  1466  	flatbuffers.GetRootAs(vec3Bytes, 0, vec3)
  1467  
  1468  	if bytes.Compare(vec3Bytes, vec3.Table().Bytes) != 0 {
  1469  		fail("invalid vec3 table")
  1470  	}
  1471  
  1472  	// test table accessor
  1473  	b = flatbuffers.NewBuilder(0)
  1474  	str := b.CreateString("MyStat")
  1475  	example.StatStart(b)
  1476  	example.StatAddId(b, str)
  1477  	example.StatAddVal(b, 12345678)
  1478  	example.StatAddCount(b, 12345)
  1479  	pos = example.StatEnd(b)
  1480  	b.Finish(pos)
  1481  	statBytes := b.FinishedBytes()
  1482  	stat := &example.Stat{}
  1483  	flatbuffers.GetRootAs(statBytes, 0, stat)
  1484  
  1485  	if bytes.Compare(statBytes, stat.Table().Bytes) != 0 {
  1486  		fail("invalid stat table")
  1487  	}
  1488  }
  1489  
  1490  // CheckVtableDeduplication verifies that vtables are deduplicated.
  1491  func CheckVtableDeduplication(fail func(string, ...interface{})) {
  1492  	b := flatbuffers.NewBuilder(0)
  1493  
  1494  	b.StartObject(4)
  1495  	b.PrependByteSlot(0, 0, 0)
  1496  	b.PrependByteSlot(1, 11, 0)
  1497  	b.PrependByteSlot(2, 22, 0)
  1498  	b.PrependInt16Slot(3, 33, 0)
  1499  	obj0 := b.EndObject()
  1500  
  1501  	b.StartObject(4)
  1502  	b.PrependByteSlot(0, 0, 0)
  1503  	b.PrependByteSlot(1, 44, 0)
  1504  	b.PrependByteSlot(2, 55, 0)
  1505  	b.PrependInt16Slot(3, 66, 0)
  1506  	obj1 := b.EndObject()
  1507  
  1508  	b.StartObject(4)
  1509  	b.PrependByteSlot(0, 0, 0)
  1510  	b.PrependByteSlot(1, 77, 0)
  1511  	b.PrependByteSlot(2, 88, 0)
  1512  	b.PrependInt16Slot(3, 99, 0)
  1513  	obj2 := b.EndObject()
  1514  
  1515  	got := b.Bytes[b.Head():]
  1516  
  1517  	want := []byte{
  1518  		240, 255, 255, 255, // == -12. offset to dedupped vtable.
  1519  		99, 0,
  1520  		88,
  1521  		77,
  1522  		248, 255, 255, 255, // == -8. offset to dedupped vtable.
  1523  		66, 0,
  1524  		55,
  1525  		44,
  1526  		12, 0,
  1527  		8, 0,
  1528  		0, 0,
  1529  		7, 0,
  1530  		6, 0,
  1531  		4, 0,
  1532  		12, 0, 0, 0,
  1533  		33, 0,
  1534  		22,
  1535  		11,
  1536  	}
  1537  
  1538  	if !bytes.Equal(want, got) {
  1539  		fail("testVtableDeduplication want:\n%d %v\nbut got:\n%d %v\n",
  1540  			len(want), want, len(got), got)
  1541  	}
  1542  
  1543  	table0 := &flatbuffers.Table{Bytes: b.Bytes, Pos: flatbuffers.UOffsetT(len(b.Bytes)) - obj0}
  1544  	table1 := &flatbuffers.Table{Bytes: b.Bytes, Pos: flatbuffers.UOffsetT(len(b.Bytes)) - obj1}
  1545  	table2 := &flatbuffers.Table{Bytes: b.Bytes, Pos: flatbuffers.UOffsetT(len(b.Bytes)) - obj2}
  1546  
  1547  	testTable := func(tab *flatbuffers.Table, a flatbuffers.VOffsetT, b, c, d byte) {
  1548  		// vtable size
  1549  		if got := tab.GetVOffsetTSlot(0, 0); 12 != got {
  1550  			fail("failed 0, 0: %d", got)
  1551  		}
  1552  		// object size
  1553  		if got := tab.GetVOffsetTSlot(2, 0); 8 != got {
  1554  			fail("failed 2, 0: %d", got)
  1555  		}
  1556  		// default value
  1557  		if got := tab.GetVOffsetTSlot(4, 0); a != got {
  1558  			fail("failed 4, 0: %d", got)
  1559  		}
  1560  		if got := tab.GetByteSlot(6, 0); b != got {
  1561  			fail("failed 6, 0: %d", got)
  1562  		}
  1563  		if val := tab.GetByteSlot(8, 0); c != val {
  1564  			fail("failed 8, 0: %d", got)
  1565  		}
  1566  		if got := tab.GetByteSlot(10, 0); d != got {
  1567  			fail("failed 10, 0: %d", got)
  1568  		}
  1569  	}
  1570  
  1571  	testTable(table0, 0, 11, 22, 33)
  1572  	testTable(table1, 0, 44, 55, 66)
  1573  	testTable(table2, 0, 77, 88, 99)
  1574  }
  1575  
  1576  // CheckNotInObjectError verifies that `EndObject` fails if not inside an
  1577  // object.
  1578  func CheckNotInObjectError(fail func(string, ...interface{})) {
  1579  	b := flatbuffers.NewBuilder(0)
  1580  
  1581  	defer func() {
  1582  		r := recover()
  1583  		if r == nil {
  1584  			fail("expected panic in CheckNotInObjectError")
  1585  		}
  1586  	}()
  1587  	b.EndObject()
  1588  }
  1589  
  1590  // CheckStringIsNestedError verifies that a string can not be created inside
  1591  // another object.
  1592  func CheckStringIsNestedError(fail func(string, ...interface{})) {
  1593  	b := flatbuffers.NewBuilder(0)
  1594  	b.StartObject(0)
  1595  	defer func() {
  1596  		r := recover()
  1597  		if r == nil {
  1598  			fail("expected panic in CheckStringIsNestedError")
  1599  		}
  1600  	}()
  1601  	b.CreateString("foo")
  1602  }
  1603  
  1604  func CheckEmptiedBuilder(fail func(string, ...interface{})) {
  1605  	f := func(a, b string) bool {
  1606  		if a == b {
  1607  			return true
  1608  		}
  1609  
  1610  		builder := flatbuffers.NewBuilder(0)
  1611  
  1612  		a1 := builder.CreateSharedString(a)
  1613  		b1 := builder.CreateSharedString(b)
  1614  		builder.Reset()
  1615  		b2 := builder.CreateSharedString(b)
  1616  		a2 := builder.CreateSharedString(a)
  1617  
  1618  		return !(a1 == a2 || b1 == b2)
  1619  	}
  1620  	if err := quick.Check(f, nil); err != nil {
  1621  		fail("expected different offset")
  1622  	}
  1623  }
  1624  
  1625  func CheckSharedStrings(fail func(string, ...interface{})) {
  1626  	f := func(strings []string) bool {
  1627  		b := flatbuffers.NewBuilder(0)
  1628  		for _, s1 := range strings {
  1629  			for _, s2 := range strings {
  1630  				off1 := b.CreateSharedString(s1)
  1631  				off2 := b.CreateSharedString(s2)
  1632  
  1633  				if (s1 == s2) && (off1 != off2) {
  1634  					return false
  1635  				}
  1636  				if (s1 != s2) && (off1 == off2) {
  1637  					return false
  1638  				}
  1639  			}
  1640  		}
  1641  		return true
  1642  	}
  1643  	if err := quick.Check(f, nil); err != nil {
  1644  		fail("expected same offset")
  1645  	}
  1646  }
  1647  
  1648  // CheckByteStringIsNestedError verifies that a bytestring can not be created
  1649  // inside another object.
  1650  func CheckByteStringIsNestedError(fail func(string, ...interface{})) {
  1651  	b := flatbuffers.NewBuilder(0)
  1652  	b.StartObject(0)
  1653  	defer func() {
  1654  		r := recover()
  1655  		if r == nil {
  1656  			fail("expected panic in CheckByteStringIsNestedError")
  1657  		}
  1658  	}()
  1659  	b.CreateByteString([]byte("foo"))
  1660  }
  1661  
  1662  // CheckStructIsNotInlineError verifies that writing a struct in a location
  1663  // away from where it is used will cause a panic.
  1664  func CheckStructIsNotInlineError(fail func(string, ...interface{})) {
  1665  	b := flatbuffers.NewBuilder(0)
  1666  	b.StartObject(0)
  1667  	defer func() {
  1668  		r := recover()
  1669  		if r == nil {
  1670  			fail("expected panic in CheckStructIsNotInlineError")
  1671  		}
  1672  	}()
  1673  	b.PrependStructSlot(0, 1, 0)
  1674  }
  1675  
  1676  // CheckFinishedBytesError verifies that `FinishedBytes` panics if the table
  1677  // is not finished.
  1678  func CheckFinishedBytesError(fail func(string, ...interface{})) {
  1679  	b := flatbuffers.NewBuilder(0)
  1680  
  1681  	defer func() {
  1682  		r := recover()
  1683  		if r == nil {
  1684  			fail("expected panic in CheckFinishedBytesError")
  1685  		}
  1686  	}()
  1687  	b.FinishedBytes()
  1688  }
  1689  
  1690  // CheckEnumNames checks that the generated enum names are correct.
  1691  func CheckEnumNames(fail func(string, ...interface{})) {
  1692  	{
  1693  		want := map[example.Any]string{
  1694  			example.AnyNONE:                    "NONE",
  1695  			example.AnyMonster:                 "Monster",
  1696  			example.AnyTestSimpleTableWithEnum: "TestSimpleTableWithEnum",
  1697  			example.AnyMyGame_Example2_Monster: "MyGame_Example2_Monster",
  1698  		}
  1699  		got := example.EnumNamesAny
  1700  		if !reflect.DeepEqual(got, want) {
  1701  			fail("enum name is not equal")
  1702  		}
  1703  	}
  1704  	{
  1705  		want := map[example.Color]string{
  1706  			example.ColorRed:   "Red",
  1707  			example.ColorGreen: "Green",
  1708  			example.ColorBlue:  "Blue",
  1709  		}
  1710  		got := example.EnumNamesColor
  1711  		if !reflect.DeepEqual(got, want) {
  1712  			fail("enum name is not equal")
  1713  		}
  1714  	}
  1715  }
  1716  
  1717  // CheckEnumString checks the String method on generated enum types.
  1718  func CheckEnumString(fail func(string, ...interface{})) {
  1719  	if got := example.AnyMonster.String(); got != "Monster" {
  1720  		fail("Monster.String: %q != %q", got, "Monster")
  1721  	}
  1722  	if got := fmt.Sprintf("color: %s", example.ColorGreen); got != "color: Green" {
  1723  		fail("color.String: %q != %q", got, "color: Green")
  1724  	}
  1725  }
  1726  
  1727  // CheckEnumValues checks that the generated enum values maps are correct.
  1728  func CheckEnumValues(fail func(string, ...interface{})) {
  1729  	{
  1730  		want := map[string]example.Any{
  1731  			"NONE":                    example.AnyNONE,
  1732  			"Monster":                 example.AnyMonster,
  1733  			"TestSimpleTableWithEnum": example.AnyTestSimpleTableWithEnum,
  1734  			"MyGame_Example2_Monster": example.AnyMyGame_Example2_Monster,
  1735  		}
  1736  		got := example.EnumValuesAny
  1737  		if !reflect.DeepEqual(got, want) {
  1738  			fail("enum name is not equal")
  1739  		}
  1740  	}
  1741  	{
  1742  		want := map[string]example.Color{
  1743  			"Red":   example.ColorRed,
  1744  			"Green": example.ColorGreen,
  1745  			"Blue":  example.ColorBlue,
  1746  		}
  1747  		got := example.EnumValuesColor
  1748  		if !reflect.DeepEqual(got, want) {
  1749  			fail("enum name is not equal")
  1750  		}
  1751  	}
  1752  }
  1753  
  1754  // CheckDocExample checks that the code given in FlatBuffers documentation
  1755  // is syntactically correct.
  1756  func CheckDocExample(buf []byte, off flatbuffers.UOffsetT, fail func(string, ...interface{})) {
  1757  	monster := example.GetRootAsMonster(buf, off)
  1758  	_ = monster.Hp()
  1759  	_ = monster.Pos(nil)
  1760  	for i := 0; i < monster.InventoryLength(); i++ {
  1761  		_ = monster.Inventory(i) // do something here
  1762  	}
  1763  
  1764  	builder := flatbuffers.NewBuilder(0)
  1765  
  1766  	example.MonsterStartInventoryVector(builder, 5)
  1767  	for i := 4; i >= 0; i-- {
  1768  		builder.PrependByte(byte(i))
  1769  	}
  1770  	inv := builder.EndVector(5)
  1771  
  1772  	str := builder.CreateString("MyMonster")
  1773  	example.MonsterStart(builder)
  1774  	example.MonsterAddPos(builder, example.CreateVec3(builder, 1.0, 2.0, 3.0, 3.0, example.Color(4), 5, 6))
  1775  	example.MonsterAddHp(builder, 80)
  1776  	example.MonsterAddName(builder, str)
  1777  	example.MonsterAddInventory(builder, inv)
  1778  	example.MonsterAddTestType(builder, 1)
  1779  	example.MonsterAddColor(builder, example.ColorRed)
  1780  	// example.MonsterAddTest(builder, mon2)
  1781  	// example.MonsterAddTest4(builder, test4s)
  1782  	_ = example.MonsterEnd(builder)
  1783  }
  1784  
  1785  func CheckCreateByteVector(fail func(string, ...interface{})) {
  1786  	raw := [30]byte{}
  1787  	for i := 0; i < len(raw); i++ {
  1788  		raw[i] = byte(i)
  1789  	}
  1790  
  1791  	for size := 0; size < len(raw); size++ {
  1792  		b1 := flatbuffers.NewBuilder(0)
  1793  		b2 := flatbuffers.NewBuilder(0)
  1794  		b1.StartVector(1, size, 1)
  1795  		for i := size - 1; i >= 0; i-- {
  1796  			b1.PrependByte(raw[i])
  1797  		}
  1798  		b1.EndVector(size)
  1799  		b2.CreateByteVector(raw[:size])
  1800  		CheckByteEquality(b1.Bytes, b2.Bytes, fail)
  1801  	}
  1802  }
  1803  
  1804  func CheckParentNamespace(fail func(string, ...interface{})) {
  1805  	var empty, nonempty []byte
  1806  
  1807  	// create monster with an empty parent namespace field
  1808  	{
  1809  		builder := flatbuffers.NewBuilder(0)
  1810  
  1811  		example.MonsterStart(builder)
  1812  		m := example.MonsterEnd(builder)
  1813  		builder.Finish(m)
  1814  
  1815  		empty = make([]byte, len(builder.FinishedBytes()))
  1816  		copy(empty, builder.FinishedBytes())
  1817  	}
  1818  
  1819  	// create monster with a non-empty parent namespace field
  1820  	{
  1821  		builder := flatbuffers.NewBuilder(0)
  1822  		mygame.InParentNamespaceStart(builder)
  1823  		pn := mygame.InParentNamespaceEnd(builder)
  1824  
  1825  		example.MonsterStart(builder)
  1826  		example.MonsterAddParentNamespaceTest(builder, pn)
  1827  		m := example.MonsterEnd(builder)
  1828  
  1829  		builder.Finish(m)
  1830  
  1831  		nonempty = make([]byte, len(builder.FinishedBytes()))
  1832  		copy(nonempty, builder.FinishedBytes())
  1833  	}
  1834  
  1835  	// read monster with empty parent namespace field
  1836  	{
  1837  		m := example.GetRootAsMonster(empty, 0)
  1838  		if m.ParentNamespaceTest(nil) != nil {
  1839  			fail("expected nil ParentNamespaceTest for empty field")
  1840  		}
  1841  	}
  1842  
  1843  	// read monster with non-empty parent namespace field
  1844  	{
  1845  		m := example.GetRootAsMonster(nonempty, 0)
  1846  		if m.ParentNamespaceTest(nil) == nil {
  1847  			fail("expected non-nil ParentNamespaceTest for non-empty field")
  1848  		}
  1849  	}
  1850  }
  1851  
  1852  func CheckSizePrefixedBuffer(fail func(string, ...interface{})) {
  1853  	// Generate a size-prefixed flatbuffer, first without file identifier
  1854  	generated, off := CheckGeneratedBuild(true, false, fail)
  1855  
  1856  	// Check that the buffer can be used as expected
  1857  	CheckReadBuffer(generated, off, true, fail)
  1858  	CheckMutateBuffer(generated, off, true, fail)
  1859  	CheckObjectAPI(generated, off, true, fail)
  1860  
  1861  	// Now generate a size-prefixed flatbuffer with file identifier
  1862  	generated, off = CheckGeneratedBuild(true, true, fail)
  1863  
  1864  	// Check that the size prefix is the size of monsterdata_go_wire.mon,
  1865  	// plus 4 bytes for padding
  1866  	size := flatbuffers.GetSizePrefix(generated, off)
  1867  	expectedSize := uint32(228)
  1868  	if size != expectedSize {
  1869  		fail("mismatch between size prefix (%d) and expected size (%d)", size, expectedSize)
  1870  	}
  1871  
  1872  	// Check that the buffer can be used as expected
  1873  	CheckReadBuffer(generated, off, true, fail)
  1874  	CheckMutateBuffer(generated, off, true, fail)
  1875  	CheckObjectAPI(generated, off, true, fail)
  1876  	CheckFileIdentifier(generated, off, true, fail)
  1877  
  1878  	// Write generated buffer out to a file
  1879  	if err := os.WriteFile(outData+".sp", generated[off:], os.FileMode(0644)); err != nil {
  1880  		fail("failed to write file: %s", err)
  1881  	}
  1882  }
  1883  
  1884  // Include simple random number generator to ensure results will be the
  1885  // same cross platform.
  1886  // http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator
  1887  type LCG uint32
  1888  
  1889  const InitialLCGSeed = 48271
  1890  
  1891  func NewLCG() *LCG {
  1892  	n := uint32(InitialLCGSeed)
  1893  	l := LCG(n)
  1894  	return &l
  1895  }
  1896  
  1897  func (lcg *LCG) Reset() {
  1898  	*lcg = InitialLCGSeed
  1899  }
  1900  
  1901  func (lcg *LCG) Next() uint32 {
  1902  	n := uint32((uint64(*lcg) * uint64(279470273)) % uint64(4294967291))
  1903  	*lcg = LCG(n)
  1904  	return n
  1905  }
  1906  
  1907  // CheckByteEquality verifies that two byte buffers are the same.
  1908  func CheckByteEquality(a, b []byte, fail func(string, ...interface{})) {
  1909  	if !bytes.Equal(a, b) {
  1910  		fail("objects are not byte-wise equal")
  1911  	}
  1912  }
  1913  
  1914  // CheckMutateMethods checks all mutate methods one by one
  1915  func CheckMutateMethods(fail func(string, ...interface{})) {
  1916  	b := flatbuffers.NewBuilder(0)
  1917  	b.StartObject(15)
  1918  	b.PrependBoolSlot(0, true, false)
  1919  	b.PrependByteSlot(1, 1, 0)
  1920  	b.PrependUint8Slot(2, 2, 0)
  1921  	b.PrependUint16Slot(3, 3, 0)
  1922  	b.PrependUint32Slot(4, 4, 0)
  1923  	b.PrependUint64Slot(5, 5, 0)
  1924  	b.PrependInt8Slot(6, 6, 0)
  1925  	b.PrependInt16Slot(7, 7, 0)
  1926  	b.PrependInt32Slot(8, 8, 0)
  1927  	b.PrependInt64Slot(9, 9, 0)
  1928  	b.PrependFloat32Slot(10, 10, 0)
  1929  	b.PrependFloat64Slot(11, 11, 0)
  1930  
  1931  	b.PrependUOffsetTSlot(12, 12, 0)
  1932  	uoVal := b.Offset() - 12
  1933  
  1934  	b.PrependVOffsetT(13)
  1935  	b.Slot(13)
  1936  
  1937  	b.PrependSOffsetT(14)
  1938  	b.Slot(14)
  1939  	soVal := flatbuffers.SOffsetT(b.Offset() - 14)
  1940  
  1941  	offset := b.EndObject()
  1942  
  1943  	t := &flatbuffers.Table{
  1944  		Bytes: b.Bytes,
  1945  		Pos:   flatbuffers.UOffsetT(len(b.Bytes)) - offset,
  1946  	}
  1947  
  1948  	calcVOffsetT := func(slot int) (vtableOffset flatbuffers.VOffsetT) {
  1949  		return flatbuffers.VOffsetT((flatbuffers.VtableMetadataFields + slot) * flatbuffers.SizeVOffsetT)
  1950  	}
  1951  	calcUOffsetT := func(vtableOffset flatbuffers.VOffsetT) (valueOffset flatbuffers.UOffsetT) {
  1952  		return t.Pos + flatbuffers.UOffsetT(t.Offset(vtableOffset))
  1953  	}
  1954  
  1955  	type testcase struct {
  1956  		field  string
  1957  		testfn func() bool
  1958  	}
  1959  
  1960  	testForOriginalValues := []testcase{
  1961  		testcase{"BoolSlot", func() bool { return t.GetBoolSlot(calcVOffsetT(0), true) == true }},
  1962  		testcase{"ByteSlot", func() bool { return t.GetByteSlot(calcVOffsetT(1), 1) == 1 }},
  1963  		testcase{"Uint8Slot", func() bool { return t.GetUint8Slot(calcVOffsetT(2), 2) == 2 }},
  1964  		testcase{"Uint16Slot", func() bool { return t.GetUint16Slot(calcVOffsetT(3), 3) == 3 }},
  1965  		testcase{"Uint32Slot", func() bool { return t.GetUint32Slot(calcVOffsetT(4), 4) == 4 }},
  1966  		testcase{"Uint64Slot", func() bool { return t.GetUint64Slot(calcVOffsetT(5), 5) == 5 }},
  1967  		testcase{"Int8Slot", func() bool { return t.GetInt8Slot(calcVOffsetT(6), 6) == 6 }},
  1968  		testcase{"Int16Slot", func() bool { return t.GetInt16Slot(calcVOffsetT(7), 7) == 7 }},
  1969  		testcase{"Int32Slot", func() bool { return t.GetInt32Slot(calcVOffsetT(8), 8) == 8 }},
  1970  		testcase{"Int64Slot", func() bool { return t.GetInt64Slot(calcVOffsetT(9), 9) == 9 }},
  1971  		testcase{"Float32Slot", func() bool { return t.GetFloat32Slot(calcVOffsetT(10), 10) == 10 }},
  1972  		testcase{"Float64Slot", func() bool { return t.GetFloat64Slot(calcVOffsetT(11), 11) == 11 }},
  1973  		testcase{"UOffsetTSlot", func() bool { return t.GetUOffsetT(calcUOffsetT(calcVOffsetT(12))) == uoVal }},
  1974  		testcase{"VOffsetTSlot", func() bool { return t.GetVOffsetT(calcUOffsetT(calcVOffsetT(13))) == 13 }},
  1975  		testcase{"SOffsetTSlot", func() bool { return t.GetSOffsetT(calcUOffsetT(calcVOffsetT(14))) == soVal }},
  1976  	}
  1977  
  1978  	testMutability := []testcase{
  1979  		testcase{"BoolSlot", func() bool { return t.MutateBoolSlot(calcVOffsetT(0), false) }},
  1980  		testcase{"ByteSlot", func() bool { return t.MutateByteSlot(calcVOffsetT(1), 2) }},
  1981  		testcase{"Uint8Slot", func() bool { return t.MutateUint8Slot(calcVOffsetT(2), 4) }},
  1982  		testcase{"Uint16Slot", func() bool { return t.MutateUint16Slot(calcVOffsetT(3), 6) }},
  1983  		testcase{"Uint32Slot", func() bool { return t.MutateUint32Slot(calcVOffsetT(4), 8) }},
  1984  		testcase{"Uint64Slot", func() bool { return t.MutateUint64Slot(calcVOffsetT(5), 10) }},
  1985  		testcase{"Int8Slot", func() bool { return t.MutateInt8Slot(calcVOffsetT(6), 12) }},
  1986  		testcase{"Int16Slot", func() bool { return t.MutateInt16Slot(calcVOffsetT(7), 14) }},
  1987  		testcase{"Int32Slot", func() bool { return t.MutateInt32Slot(calcVOffsetT(8), 16) }},
  1988  		testcase{"Int64Slot", func() bool { return t.MutateInt64Slot(calcVOffsetT(9), 18) }},
  1989  		testcase{"Float32Slot", func() bool { return t.MutateFloat32Slot(calcVOffsetT(10), 20) }},
  1990  		testcase{"Float64Slot", func() bool { return t.MutateFloat64Slot(calcVOffsetT(11), 22) }},
  1991  		testcase{"UOffsetTSlot", func() bool { return t.MutateUOffsetT(calcUOffsetT(calcVOffsetT(12)), 24) }},
  1992  		testcase{"VOffsetTSlot", func() bool { return t.MutateVOffsetT(calcUOffsetT(calcVOffsetT(13)), 26) }},
  1993  		testcase{"SOffsetTSlot", func() bool { return t.MutateSOffsetT(calcUOffsetT(calcVOffsetT(14)), 28) }},
  1994  	}
  1995  
  1996  	testMutabilityWithoutSlot := []testcase{
  1997  		testcase{"BoolSlot", func() bool { return t.MutateBoolSlot(calcVOffsetT(16), false) }},
  1998  		testcase{"ByteSlot", func() bool { return t.MutateByteSlot(calcVOffsetT(16), 2) }},
  1999  		testcase{"Uint8Slot", func() bool { return t.MutateUint8Slot(calcVOffsetT(16), 2) }},
  2000  		testcase{"Uint16Slot", func() bool { return t.MutateUint16Slot(calcVOffsetT(16), 2) }},
  2001  		testcase{"Uint32Slot", func() bool { return t.MutateUint32Slot(calcVOffsetT(16), 2) }},
  2002  		testcase{"Uint64Slot", func() bool { return t.MutateUint64Slot(calcVOffsetT(16), 2) }},
  2003  		testcase{"Int8Slot", func() bool { return t.MutateInt8Slot(calcVOffsetT(16), 2) }},
  2004  		testcase{"Int16Slot", func() bool { return t.MutateInt16Slot(calcVOffsetT(16), 2) }},
  2005  		testcase{"Int32Slot", func() bool { return t.MutateInt32Slot(calcVOffsetT(16), 2) }},
  2006  		testcase{"Int64Slot", func() bool { return t.MutateInt64Slot(calcVOffsetT(16), 2) }},
  2007  		testcase{"Float32Slot", func() bool { return t.MutateFloat32Slot(calcVOffsetT(16), 2) }},
  2008  		testcase{"Float64Slot", func() bool { return t.MutateFloat64Slot(calcVOffsetT(16), 2) }},
  2009  	}
  2010  
  2011  	testForMutatedValues := []testcase{
  2012  		testcase{"BoolSlot", func() bool { return t.GetBoolSlot(calcVOffsetT(0), true) == false }},
  2013  		testcase{"ByteSlot", func() bool { return t.GetByteSlot(calcVOffsetT(1), 1) == 2 }},
  2014  		testcase{"Uint8Slot", func() bool { return t.GetUint8Slot(calcVOffsetT(2), 1) == 4 }},
  2015  		testcase{"Uint16Slot", func() bool { return t.GetUint16Slot(calcVOffsetT(3), 1) == 6 }},
  2016  		testcase{"Uint32Slot", func() bool { return t.GetUint32Slot(calcVOffsetT(4), 1) == 8 }},
  2017  		testcase{"Uint64Slot", func() bool { return t.GetUint64Slot(calcVOffsetT(5), 1) == 10 }},
  2018  		testcase{"Int8Slot", func() bool { return t.GetInt8Slot(calcVOffsetT(6), 1) == 12 }},
  2019  		testcase{"Int16Slot", func() bool { return t.GetInt16Slot(calcVOffsetT(7), 1) == 14 }},
  2020  		testcase{"Int32Slot", func() bool { return t.GetInt32Slot(calcVOffsetT(8), 1) == 16 }},
  2021  		testcase{"Int64Slot", func() bool { return t.GetInt64Slot(calcVOffsetT(9), 1) == 18 }},
  2022  		testcase{"Float32Slot", func() bool { return t.GetFloat32Slot(calcVOffsetT(10), 1) == 20 }},
  2023  		testcase{"Float64Slot", func() bool { return t.GetFloat64Slot(calcVOffsetT(11), 1) == 22 }},
  2024  		testcase{"UOffsetTSlot", func() bool { return t.GetUOffsetT(calcUOffsetT(calcVOffsetT(12))) == 24 }},
  2025  		testcase{"VOffsetTSlot", func() bool { return t.GetVOffsetT(calcUOffsetT(calcVOffsetT(13))) == 26 }},
  2026  		testcase{"SOffsetTSlot", func() bool { return t.GetSOffsetT(calcUOffsetT(calcVOffsetT(14))) == 28 }},
  2027  	}
  2028  
  2029  	// make sure original values are okay
  2030  	for _, t := range testForOriginalValues {
  2031  		if !t.testfn() {
  2032  			fail(t.field + "' field doesn't have the expected original value")
  2033  		}
  2034  	}
  2035  
  2036  	// try to mutate fields and check mutability
  2037  	for _, t := range testMutability {
  2038  		if !t.testfn() {
  2039  			fail(FailString(t.field+"' field failed mutability test", "passed", "failed"))
  2040  		}
  2041  	}
  2042  
  2043  	// try to mutate fields and check mutability
  2044  	// these have wrong slots so should fail
  2045  	for _, t := range testMutabilityWithoutSlot {
  2046  		if t.testfn() {
  2047  			fail(FailString(t.field+"' field failed no slot mutability test", "failed", "passed"))
  2048  		}
  2049  	}
  2050  
  2051  	// test whether values have changed
  2052  	for _, t := range testForMutatedValues {
  2053  		if !t.testfn() {
  2054  			fail(t.field + "' field doesn't have the expected mutated value")
  2055  		}
  2056  	}
  2057  }
  2058  
  2059  // CheckOptionalScalars verifies against the ScalarStuff schema.
  2060  func CheckOptionalScalars(fail func(string, ...interface{})) {
  2061  	type testCase struct {
  2062  		what           string
  2063  		result, expect interface{}
  2064  	}
  2065  
  2066  	makeDefaultTestCases := func(s *optional_scalars.ScalarStuff) []testCase {
  2067  		return []testCase{
  2068  			{"justI8", s.JustI8(), int8(0)},
  2069  			{"maybeI8", s.MaybeI8(), (*int8)(nil)},
  2070  			{"defaultI8", s.DefaultI8(), int8(42)},
  2071  			{"justU8", s.JustU8(), byte(0)},
  2072  			{"maybeU8", s.MaybeU8(), (*byte)(nil)},
  2073  			{"defaultU8", s.DefaultU8(), byte(42)},
  2074  			{"justI16", s.JustI16(), int16(0)},
  2075  			{"maybeI16", s.MaybeI16(), (*int16)(nil)},
  2076  			{"defaultI16", s.DefaultI16(), int16(42)},
  2077  			{"justU16", s.JustU16(), uint16(0)},
  2078  			{"maybeU16", s.MaybeU16(), (*uint16)(nil)},
  2079  			{"defaultU16", s.DefaultU16(), uint16(42)},
  2080  			{"justI32", s.JustI32(), int32(0)},
  2081  			{"maybeI32", s.MaybeI32(), (*int32)(nil)},
  2082  			{"defaultI32", s.DefaultI32(), int32(42)},
  2083  			{"justU32", s.JustU32(), uint32(0)},
  2084  			{"maybeU32", s.MaybeU32(), (*uint32)(nil)},
  2085  			{"defaultU32", s.DefaultU32(), uint32(42)},
  2086  			{"justI64", s.JustI64(), int64(0)},
  2087  			{"maybeI64", s.MaybeI64(), (*int64)(nil)},
  2088  			{"defaultI64", s.DefaultI64(), int64(42)},
  2089  			{"justU64", s.JustU64(), uint64(0)},
  2090  			{"maybeU64", s.MaybeU64(), (*uint64)(nil)},
  2091  			{"defaultU64", s.DefaultU64(), uint64(42)},
  2092  			{"justF32", s.JustF32(), float32(0)},
  2093  			{"maybeF32", s.MaybeF32(), (*float32)(nil)},
  2094  			{"defaultF32", s.DefaultF32(), float32(42)},
  2095  			{"justF64", s.JustF64(), float64(0)},
  2096  			{"maybeF64", s.MaybeF64(), (*float64)(nil)},
  2097  			{"defaultF64", s.DefaultF64(), float64(42)},
  2098  			{"justBool", s.JustBool(), false},
  2099  			{"maybeBool", s.MaybeBool(), (*bool)(nil)},
  2100  			{"defaultBool", s.DefaultBool(), true},
  2101  			{"justEnum", s.JustEnum(), optional_scalars.OptionalByte(0)},
  2102  			{"maybeEnum", s.MaybeEnum(), (*optional_scalars.OptionalByte)(nil)},
  2103  			{"defaultEnum", s.DefaultEnum(), optional_scalars.OptionalByteOne},
  2104  		}
  2105  	}
  2106  
  2107  	makeAssignedTestCases := func(s *optional_scalars.ScalarStuff) []testCase {
  2108  		return []testCase{
  2109  			{"justI8", s.JustI8(), int8(5)},
  2110  			{"maybeI8", s.MaybeI8(), int8(5)},
  2111  			{"defaultI8", s.DefaultI8(), int8(5)},
  2112  			{"justU8", s.JustU8(), byte(6)},
  2113  			{"maybeU8", s.MaybeU8(), byte(6)},
  2114  			{"defaultU8", s.DefaultU8(), byte(6)},
  2115  			{"justI16", s.JustI16(), int16(7)},
  2116  			{"maybeI16", s.MaybeI16(), int16(7)},
  2117  			{"defaultI16", s.DefaultI16(), int16(7)},
  2118  			{"justU16", s.JustU16(), uint16(8)},
  2119  			{"maybeU16", s.MaybeU16(), uint16(8)},
  2120  			{"defaultU16", s.DefaultU16(), uint16(8)},
  2121  			{"justI32", s.JustI32(), int32(9)},
  2122  			{"maybeI32", s.MaybeI32(), int32(9)},
  2123  			{"defaultI32", s.DefaultI32(), int32(9)},
  2124  			{"justU32", s.JustU32(), uint32(10)},
  2125  			{"maybeU32", s.MaybeU32(), uint32(10)},
  2126  			{"defaultU32", s.DefaultU32(), uint32(10)},
  2127  			{"justI64", s.JustI64(), int64(11)},
  2128  			{"maybeI64", s.MaybeI64(), int64(11)},
  2129  			{"defaultI64", s.DefaultI64(), int64(11)},
  2130  			{"justU64", s.JustU64(), uint64(12)},
  2131  			{"maybeU64", s.MaybeU64(), uint64(12)},
  2132  			{"defaultU64", s.DefaultU64(), uint64(12)},
  2133  			{"justF32", s.JustF32(), float32(13)},
  2134  			{"maybeF32", s.MaybeF32(), float32(13)},
  2135  			{"defaultF32", s.DefaultF32(), float32(13)},
  2136  			{"justF64", s.JustF64(), float64(14)},
  2137  			{"maybeF64", s.MaybeF64(), float64(14)},
  2138  			{"defaultF64", s.DefaultF64(), float64(14)},
  2139  			{"justBool", s.JustBool(), true},
  2140  			{"maybeBool", s.MaybeBool(), true},
  2141  			{"defaultBool", s.DefaultBool(), false},
  2142  			{"justEnum", s.JustEnum(), optional_scalars.OptionalByteTwo},
  2143  			{"maybeEnum", s.MaybeEnum(), optional_scalars.OptionalByteTwo},
  2144  			{"defaultEnum", s.DefaultEnum(), optional_scalars.OptionalByteTwo},
  2145  		}
  2146  	}
  2147  
  2148  	resolvePointer := func(v interface{}) interface{} {
  2149  		switch v := v.(type) {
  2150  		case *int8:
  2151  			return *v
  2152  		case *byte:
  2153  			return *v
  2154  		case *int16:
  2155  			return *v
  2156  		case *uint16:
  2157  			return *v
  2158  		case *int32:
  2159  			return *v
  2160  		case *uint32:
  2161  			return *v
  2162  		case *int64:
  2163  			return *v
  2164  		case *uint64:
  2165  			return *v
  2166  		case *float32:
  2167  			return *v
  2168  		case *float64:
  2169  			return *v
  2170  		case *bool:
  2171  			return *v
  2172  		case *optional_scalars.OptionalByte:
  2173  			return *v
  2174  		default:
  2175  			return v
  2176  		}
  2177  	}
  2178  
  2179  	buildAssignedTable := func(b *flatbuffers.Builder) *optional_scalars.ScalarStuff {
  2180  		optional_scalars.ScalarStuffStart(b)
  2181  		optional_scalars.ScalarStuffAddJustI8(b, int8(5))
  2182  		optional_scalars.ScalarStuffAddMaybeI8(b, int8(5))
  2183  		optional_scalars.ScalarStuffAddDefaultI8(b, int8(5))
  2184  		optional_scalars.ScalarStuffAddJustU8(b, byte(6))
  2185  		optional_scalars.ScalarStuffAddMaybeU8(b, byte(6))
  2186  		optional_scalars.ScalarStuffAddDefaultU8(b, byte(6))
  2187  		optional_scalars.ScalarStuffAddJustI16(b, int16(7))
  2188  		optional_scalars.ScalarStuffAddMaybeI16(b, int16(7))
  2189  		optional_scalars.ScalarStuffAddDefaultI16(b, int16(7))
  2190  		optional_scalars.ScalarStuffAddJustU16(b, uint16(8))
  2191  		optional_scalars.ScalarStuffAddMaybeU16(b, uint16(8))
  2192  		optional_scalars.ScalarStuffAddDefaultU16(b, uint16(8))
  2193  		optional_scalars.ScalarStuffAddJustI32(b, int32(9))
  2194  		optional_scalars.ScalarStuffAddMaybeI32(b, int32(9))
  2195  		optional_scalars.ScalarStuffAddDefaultI32(b, int32(9))
  2196  		optional_scalars.ScalarStuffAddJustU32(b, uint32(10))
  2197  		optional_scalars.ScalarStuffAddMaybeU32(b, uint32(10))
  2198  		optional_scalars.ScalarStuffAddDefaultU32(b, uint32(10))
  2199  		optional_scalars.ScalarStuffAddJustI64(b, int64(11))
  2200  		optional_scalars.ScalarStuffAddMaybeI64(b, int64(11))
  2201  		optional_scalars.ScalarStuffAddDefaultI64(b, int64(11))
  2202  		optional_scalars.ScalarStuffAddJustU64(b, uint64(12))
  2203  		optional_scalars.ScalarStuffAddMaybeU64(b, uint64(12))
  2204  		optional_scalars.ScalarStuffAddDefaultU64(b, uint64(12))
  2205  		optional_scalars.ScalarStuffAddJustF32(b, float32(13))
  2206  		optional_scalars.ScalarStuffAddMaybeF32(b, float32(13))
  2207  		optional_scalars.ScalarStuffAddDefaultF32(b, float32(13))
  2208  		optional_scalars.ScalarStuffAddJustF64(b, float64(14))
  2209  		optional_scalars.ScalarStuffAddMaybeF64(b, float64(14))
  2210  		optional_scalars.ScalarStuffAddDefaultF64(b, float64(14))
  2211  		optional_scalars.ScalarStuffAddJustBool(b, true)
  2212  		optional_scalars.ScalarStuffAddMaybeBool(b, true)
  2213  		optional_scalars.ScalarStuffAddDefaultBool(b, false)
  2214  		optional_scalars.ScalarStuffAddJustEnum(b, optional_scalars.OptionalByteTwo)
  2215  		optional_scalars.ScalarStuffAddMaybeEnum(b, optional_scalars.OptionalByteTwo)
  2216  		optional_scalars.ScalarStuffAddDefaultEnum(b, optional_scalars.OptionalByteTwo)
  2217  		b.Finish(optional_scalars.ScalarStuffEnd(b))
  2218  		return optional_scalars.GetRootAsScalarStuff(b.FinishedBytes(), 0)
  2219  	}
  2220  
  2221  	// test default values
  2222  
  2223  	fbb := flatbuffers.NewBuilder(1)
  2224  	optional_scalars.ScalarStuffStart(fbb)
  2225  	fbb.Finish(optional_scalars.ScalarStuffEnd(fbb))
  2226  	ss := optional_scalars.GetRootAsScalarStuff(fbb.FinishedBytes(), 0)
  2227  	for _, tc := range makeDefaultTestCases(ss) {
  2228  		if tc.result != tc.expect {
  2229  			fail(FailString("Default ScalarStuff: "+tc.what, tc.expect, tc.result))
  2230  		}
  2231  	}
  2232  
  2233  	// test assigned values
  2234  	fbb.Reset()
  2235  	ss = buildAssignedTable(fbb)
  2236  	for _, tc := range makeAssignedTestCases(ss) {
  2237  		if resolvePointer(tc.result) != tc.expect {
  2238  			fail(FailString("Assigned ScalarStuff: "+tc.what, tc.expect, tc.result))
  2239  		}
  2240  	}
  2241  
  2242  	// test native object pack
  2243  	fbb.Reset()
  2244  	i8 := int8(5)
  2245  	u8 := byte(6)
  2246  	i16 := int16(7)
  2247  	u16 := uint16(8)
  2248  	i32 := int32(9)
  2249  	u32 := uint32(10)
  2250  	i64 := int64(11)
  2251  	u64 := uint64(12)
  2252  	f32 := float32(13)
  2253  	f64 := float64(14)
  2254  	b := true
  2255  	enum := optional_scalars.OptionalByteTwo
  2256  	obj := optional_scalars.ScalarStuffT{
  2257  		JustI8:      5,
  2258  		MaybeI8:     &i8,
  2259  		DefaultI8:   5,
  2260  		JustU8:      6,
  2261  		MaybeU8:     &u8,
  2262  		DefaultU8:   6,
  2263  		JustI16:     7,
  2264  		MaybeI16:    &i16,
  2265  		DefaultI16:  7,
  2266  		JustU16:     8,
  2267  		MaybeU16:    &u16,
  2268  		DefaultU16:  8,
  2269  		JustI32:     9,
  2270  		MaybeI32:    &i32,
  2271  		DefaultI32:  9,
  2272  		JustU32:     10,
  2273  		MaybeU32:    &u32,
  2274  		DefaultU32:  10,
  2275  		JustI64:     11,
  2276  		MaybeI64:    &i64,
  2277  		DefaultI64:  11,
  2278  		JustU64:     12,
  2279  		MaybeU64:    &u64,
  2280  		DefaultU64:  12,
  2281  		JustF32:     13,
  2282  		MaybeF32:    &f32,
  2283  		DefaultF32:  13,
  2284  		JustF64:     14,
  2285  		MaybeF64:    &f64,
  2286  		DefaultF64:  14,
  2287  		JustBool:    true,
  2288  		MaybeBool:   &b,
  2289  		DefaultBool: false,
  2290  		JustEnum:    optional_scalars.OptionalByteTwo,
  2291  		MaybeEnum:   &enum,
  2292  		DefaultEnum: optional_scalars.OptionalByteTwo,
  2293  	}
  2294  	fbb.Finish(obj.Pack(fbb))
  2295  	ss = optional_scalars.GetRootAsScalarStuff(fbb.FinishedBytes(), 0)
  2296  	for _, tc := range makeAssignedTestCases(ss) {
  2297  		if resolvePointer(tc.result) != tc.expect {
  2298  			fail(FailString("Native Object ScalarStuff: "+tc.what, tc.expect, tc.result))
  2299  		}
  2300  	}
  2301  
  2302  	// test native object unpack
  2303  	fbb.Reset()
  2304  	ss = buildAssignedTable(fbb)
  2305  	ss.UnPackTo(&obj)
  2306  	expectEq := func(what string, a, b interface{}) {
  2307  		if resolvePointer(a) != b {
  2308  			fail(FailString("Native Object Unpack ScalarStuff: "+what, b, a))
  2309  		}
  2310  	}
  2311  	expectEq("justI8", obj.JustI8, int8(5))
  2312  	expectEq("maybeI8", obj.MaybeI8, int8(5))
  2313  	expectEq("defaultI8", obj.DefaultI8, int8(5))
  2314  	expectEq("justU8", obj.JustU8, byte(6))
  2315  	expectEq("maybeU8", obj.MaybeU8, byte(6))
  2316  	expectEq("defaultU8", obj.DefaultU8, byte(6))
  2317  	expectEq("justI16", obj.JustI16, int16(7))
  2318  	expectEq("maybeI16", obj.MaybeI16, int16(7))
  2319  	expectEq("defaultI16", obj.DefaultI16, int16(7))
  2320  	expectEq("justU16", obj.JustU16, uint16(8))
  2321  	expectEq("maybeU16", obj.MaybeU16, uint16(8))
  2322  	expectEq("defaultU16", obj.DefaultU16, uint16(8))
  2323  	expectEq("justI32", obj.JustI32, int32(9))
  2324  	expectEq("maybeI32", obj.MaybeI32, int32(9))
  2325  	expectEq("defaultI32", obj.DefaultI32, int32(9))
  2326  	expectEq("justU32", obj.JustU32, uint32(10))
  2327  	expectEq("maybeU32", obj.MaybeU32, uint32(10))
  2328  	expectEq("defaultU32", obj.DefaultU32, uint32(10))
  2329  	expectEq("justI64", obj.JustI64, int64(11))
  2330  	expectEq("maybeI64", obj.MaybeI64, int64(11))
  2331  	expectEq("defaultI64", obj.DefaultI64, int64(11))
  2332  	expectEq("justU64", obj.JustU64, uint64(12))
  2333  	expectEq("maybeU64", obj.MaybeU64, uint64(12))
  2334  	expectEq("defaultU64", obj.DefaultU64, uint64(12))
  2335  	expectEq("justF32", obj.JustF32, float32(13))
  2336  	expectEq("maybeF32", obj.MaybeF32, float32(13))
  2337  	expectEq("defaultF32", obj.DefaultF32, float32(13))
  2338  	expectEq("justF64", obj.JustF64, float64(14))
  2339  	expectEq("maybeF64", obj.MaybeF64, float64(14))
  2340  	expectEq("defaultF64", obj.DefaultF64, float64(14))
  2341  	expectEq("justBool", obj.JustBool, true)
  2342  	expectEq("maybeBool", obj.MaybeBool, true)
  2343  	expectEq("defaultBool", obj.DefaultBool, false)
  2344  	expectEq("justEnum", obj.JustEnum, optional_scalars.OptionalByteTwo)
  2345  	expectEq("maybeEnum", obj.MaybeEnum, optional_scalars.OptionalByteTwo)
  2346  	expectEq("defaultEnum", obj.DefaultEnum, optional_scalars.OptionalByteTwo)
  2347  }
  2348  
  2349  func CheckByKey(fail func(string, ...interface{})) {
  2350  	expectEq := func(what string, a, b interface{}) {
  2351  		if a != b {
  2352  			fail(FailString("Lookup by key: "+what, b, a))
  2353  		}
  2354  	}
  2355  
  2356  	b := flatbuffers.NewBuilder(0)
  2357  	name := b.CreateString("Boss")
  2358  
  2359  	slime := &example.MonsterT{Name: "Slime"}
  2360  	pig := &example.MonsterT{Name: "Pig"}
  2361  	slimeBoss := &example.MonsterT{Name: "SlimeBoss"}
  2362  	mushroom := &example.MonsterT{Name: "Mushroom"}
  2363  	ironPig := &example.MonsterT{Name: "Iron Pig"}
  2364  
  2365  	monsterOffsets := make([]flatbuffers.UOffsetT, 5)
  2366  	monsterOffsets[0] = slime.Pack(b)
  2367  	monsterOffsets[1] = pig.Pack(b)
  2368  	monsterOffsets[2] = slimeBoss.Pack(b)
  2369  	monsterOffsets[3] = mushroom.Pack(b)
  2370  	monsterOffsets[4] = ironPig.Pack(b)
  2371  	testarrayoftables := b.CreateVectorOfSortedTables(monsterOffsets, example.MonsterKeyCompare)
  2372  
  2373  	str := &example.StatT{Id: "Strength", Count: 42}
  2374  	luk := &example.StatT{Id: "Luck", Count: 51}
  2375  	hp := &example.StatT{Id: "Health", Count: 12}
  2376  	// Test default count value of 0
  2377  	mp := &example.StatT{Id: "Mana"}
  2378  
  2379  	statOffsets := make([]flatbuffers.UOffsetT, 4)
  2380  	statOffsets[0] = str.Pack(b)
  2381  	statOffsets[1] = luk.Pack(b)
  2382  	statOffsets[2] = hp.Pack(b)
  2383  	statOffsets[3] = mp.Pack(b)
  2384  	scalarKeySortedTablesOffset := b.CreateVectorOfSortedTables(statOffsets, example.StatKeyCompare)
  2385  
  2386  	example.MonsterStart(b)
  2387  	example.MonsterAddName(b, name)
  2388  	example.MonsterAddTestarrayoftables(b, testarrayoftables)
  2389  	example.MonsterAddScalarKeySortedTables(b, scalarKeySortedTablesOffset)
  2390  	moff := example.MonsterEnd(b)
  2391  	b.Finish(moff)
  2392  
  2393  	monster := example.GetRootAsMonster(b.Bytes, b.Head())
  2394  	slimeMon := &example.Monster{}
  2395  	monster.TestarrayoftablesByKey(slimeMon, slime.Name)
  2396  	mushroomMon := &example.Monster{}
  2397  	monster.TestarrayoftablesByKey(mushroomMon, mushroom.Name)
  2398  	slimeBossMon := &example.Monster{}
  2399  	monster.TestarrayoftablesByKey(slimeBossMon, slimeBoss.Name)
  2400  
  2401  	strStat := &example.Stat{}
  2402  	monster.ScalarKeySortedTablesByKey(strStat, str.Count)
  2403  	lukStat := &example.Stat{}
  2404  	monster.ScalarKeySortedTablesByKey(lukStat, luk.Count)
  2405  	mpStat := &example.Stat{}
  2406  	monster.ScalarKeySortedTablesByKey(mpStat, mp.Count)
  2407  
  2408  	expectEq("Boss name", string(monster.Name()), "Boss")
  2409  	expectEq("Slime name", string(slimeMon.Name()), slime.Name)
  2410  	expectEq("Mushroom name", string(mushroomMon.Name()), mushroom.Name)
  2411  	expectEq("SlimeBoss name", string(slimeBossMon.Name()), slimeBoss.Name)
  2412  	expectEq("Strength Id", string(strStat.Id()), str.Id)
  2413  	expectEq("Strength Count", strStat.Count(), str.Count)
  2414  	expectEq("Luck Id", string(lukStat.Id()), luk.Id)
  2415  	expectEq("Luck Count", lukStat.Count(), luk.Count)
  2416  	expectEq("Mana Id", string(mpStat.Id()), mp.Id)
  2417  	// Use default count value as key
  2418  	expectEq("Mana Count", mpStat.Count(), uint16(0))
  2419  }
  2420  
  2421  // BenchmarkVtableDeduplication measures the speed of vtable deduplication
  2422  // by creating prePop vtables, then populating b.N objects with a
  2423  // different single vtable.
  2424  //
  2425  // When b.N is large (as in long benchmarks), memory usage may be high.
  2426  func BenchmarkVtableDeduplication(b *testing.B) {
  2427  	prePop := 10
  2428  	builder := flatbuffers.NewBuilder(0)
  2429  
  2430  	// pre-populate some vtables:
  2431  	for i := 0; i < prePop; i++ {
  2432  		builder.StartObject(i)
  2433  		for j := 0; j < i; j++ {
  2434  			builder.PrependInt16Slot(j, int16(j), 0)
  2435  		}
  2436  		builder.EndObject()
  2437  	}
  2438  
  2439  	// benchmark deduplication of a new vtable:
  2440  	b.ResetTimer()
  2441  	for i := 0; i < b.N; i++ {
  2442  		lim := prePop
  2443  
  2444  		builder.StartObject(lim)
  2445  		for j := 0; j < lim; j++ {
  2446  			builder.PrependInt16Slot(j, int16(j), 0)
  2447  		}
  2448  		builder.EndObject()
  2449  	}
  2450  }
  2451  
  2452  // BenchmarkParseGold measures the speed of parsing the 'gold' data
  2453  // used throughout this test suite.
  2454  func BenchmarkParseGold(b *testing.B) {
  2455  	buf, offset := CheckGeneratedBuild(false, false, b.Fatalf)
  2456  	monster := example.GetRootAsMonster(buf, offset)
  2457  
  2458  	// use these to prevent allocations:
  2459  	reuse_pos := example.Vec3{}
  2460  	reuse_test3 := example.Test{}
  2461  	reuse_table2 := flatbuffers.Table{}
  2462  	reuse_monster2 := example.Monster{}
  2463  	reuse_test4_0 := example.Test{}
  2464  	reuse_test4_1 := example.Test{}
  2465  
  2466  	b.SetBytes(int64(len(buf[offset:])))
  2467  	b.ReportAllocs()
  2468  	b.ResetTimer()
  2469  	for i := 0; i < b.N; i++ {
  2470  		monster.Hp()
  2471  		monster.Mana()
  2472  		name := monster.Name()
  2473  		_ = name[0]
  2474  		_ = name[len(name)-1]
  2475  
  2476  		monster.Pos(&reuse_pos)
  2477  		reuse_pos.X()
  2478  		reuse_pos.Y()
  2479  		reuse_pos.Z()
  2480  		reuse_pos.Test1()
  2481  		reuse_pos.Test2()
  2482  		reuse_pos.Test3(&reuse_test3)
  2483  		reuse_test3.A()
  2484  		reuse_test3.B()
  2485  		monster.TestType()
  2486  		monster.Test(&reuse_table2)
  2487  		reuse_monster2.Init(reuse_table2.Bytes, reuse_table2.Pos)
  2488  		name2 := reuse_monster2.Name()
  2489  		_ = name2[0]
  2490  		_ = name2[len(name2)-1]
  2491  		monster.InventoryLength()
  2492  		l := monster.InventoryLength()
  2493  		for i := 0; i < l; i++ {
  2494  			monster.Inventory(i)
  2495  		}
  2496  		monster.Test4Length()
  2497  		monster.Test4(&reuse_test4_0, 0)
  2498  		monster.Test4(&reuse_test4_1, 1)
  2499  
  2500  		reuse_test4_0.A()
  2501  		reuse_test4_0.B()
  2502  		reuse_test4_1.A()
  2503  		reuse_test4_1.B()
  2504  
  2505  		monster.TestarrayofstringLength()
  2506  		str0 := monster.Testarrayofstring(0)
  2507  		_ = str0[0]
  2508  		_ = str0[len(str0)-1]
  2509  		str1 := monster.Testarrayofstring(1)
  2510  		_ = str1[0]
  2511  		_ = str1[len(str1)-1]
  2512  	}
  2513  }
  2514  
  2515  // BenchmarkBuildGold uses generated code to build the example Monster.
  2516  func BenchmarkBuildGold(b *testing.B) {
  2517  	buf, offset := CheckGeneratedBuild(false, false, b.Fatalf)
  2518  	bytes_length := int64(len(buf[offset:]))
  2519  
  2520  	reuse_str := "MyMonster"
  2521  	reuse_test1 := "test1"
  2522  	reuse_test2 := "test2"
  2523  	reuse_fred := "Fred"
  2524  
  2525  	b.SetBytes(bytes_length)
  2526  	bldr := flatbuffers.NewBuilder(0)
  2527  	b.ResetTimer()
  2528  	b.ReportAllocs()
  2529  	for i := 0; i < b.N; i++ {
  2530  		bldr.Reset()
  2531  
  2532  		str := bldr.CreateString(reuse_str)
  2533  		test1 := bldr.CreateString(reuse_test1)
  2534  		test2 := bldr.CreateString(reuse_test2)
  2535  		fred := bldr.CreateString(reuse_fred)
  2536  
  2537  		example.MonsterStartInventoryVector(bldr, 5)
  2538  		bldr.PrependByte(4)
  2539  		bldr.PrependByte(3)
  2540  		bldr.PrependByte(2)
  2541  		bldr.PrependByte(1)
  2542  		bldr.PrependByte(0)
  2543  		inv := bldr.EndVector(5)
  2544  
  2545  		example.MonsterStart(bldr)
  2546  		example.MonsterAddName(bldr, fred)
  2547  		mon2 := example.MonsterEnd(bldr)
  2548  
  2549  		example.MonsterStartTest4Vector(bldr, 2)
  2550  		example.CreateTest(bldr, 10, 20)
  2551  		example.CreateTest(bldr, 30, 40)
  2552  		test4 := bldr.EndVector(2)
  2553  
  2554  		example.MonsterStartTestarrayofstringVector(bldr, 2)
  2555  		bldr.PrependUOffsetT(test2)
  2556  		bldr.PrependUOffsetT(test1)
  2557  		testArrayOfString := bldr.EndVector(2)
  2558  
  2559  		example.MonsterStart(bldr)
  2560  
  2561  		pos := example.CreateVec3(bldr, 1.0, 2.0, 3.0, 3.0, example.ColorGreen, 5, 6)
  2562  		example.MonsterAddPos(bldr, pos)
  2563  
  2564  		example.MonsterAddHp(bldr, 80)
  2565  		example.MonsterAddName(bldr, str)
  2566  		example.MonsterAddInventory(bldr, inv)
  2567  		example.MonsterAddTestType(bldr, 1)
  2568  		example.MonsterAddTest(bldr, mon2)
  2569  		example.MonsterAddTest4(bldr, test4)
  2570  		example.MonsterAddTestarrayofstring(bldr, testArrayOfString)
  2571  		mon := example.MonsterEnd(bldr)
  2572  
  2573  		bldr.Finish(mon)
  2574  	}
  2575  }
  2576  

View as plain text