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
17package main
18
19import (
20	mygame "MyGame"          // refers to generated code
21	example "MyGame/Example" // refers to generated code
22
23	"bytes"
24	"flag"
25	"fmt"
26	"io/ioutil"
27	"os"
28	"reflect"
29	"sort"
30	"testing"
31
32	flatbuffers "github.com/google/flatbuffers/go"
33)
34
35var (
36	cppData, javaData, outData string
37	fuzz                       bool
38	fuzzFields, fuzzObjects    int
39)
40
41func init() {
42	flag.StringVar(&cppData, "cpp_data", "",
43		"location of monsterdata_test.mon to verify against (required)")
44	flag.StringVar(&javaData, "java_data", "",
45		"location of monsterdata_java_wire.mon to verify against (optional)")
46	flag.StringVar(&outData, "out_data", "",
47		"location to write generated Go data")
48	flag.BoolVar(&fuzz, "fuzz", false, "perform fuzzing")
49	flag.IntVar(&fuzzFields, "fuzz_fields", 4, "fields per fuzzer object")
50	flag.IntVar(&fuzzObjects, "fuzz_objects", 10000,
51		"number of fuzzer objects (higher is slower and more thorough")
52	flag.Parse()
53
54	if cppData == "" {
55		fmt.Fprintf(os.Stderr, "cpp_data argument is required\n")
56		os.Exit(1)
57	}
58}
59
60// Store specific byte patterns in these variables for the fuzzer. These
61// values are taken verbatim from the C++ function FuzzTest1.
62var (
63	overflowingInt32Val = flatbuffers.GetInt32([]byte{0x83, 0x33, 0x33, 0x33})
64	overflowingInt64Val = flatbuffers.GetInt64([]byte{0x84, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44})
65)
66
67// TestAll runs all checks, failing if any errors occur.
68func TestAll(t *testing.T) {
69	// Verify that the Go FlatBuffers runtime library generates the
70	// expected bytes (does not use any schema):
71	CheckByteLayout(t.Fatalf)
72	CheckMutateMethods(t.Fatalf)
73
74	// Verify that panics are raised during exceptional conditions:
75	CheckNotInObjectError(t.Fatalf)
76	CheckStringIsNestedError(t.Fatalf)
77	CheckByteStringIsNestedError(t.Fatalf)
78	CheckStructIsNotInlineError(t.Fatalf)
79	CheckFinishedBytesError(t.Fatalf)
80
81	// Verify that GetRootAs works for non-root tables
82	CheckGetRootAsForNonRootTable(t.Fatalf)
83	CheckTableAccessors(t.Fatalf)
84
85	// Verify that using the generated Go code builds a buffer without
86	// returning errors:
87	generated, off := CheckGeneratedBuild(t.Fatalf)
88
89	// Verify that the buffer generated by Go code is readable by the
90	// generated Go code:
91	CheckReadBuffer(generated, off, t.Fatalf)
92	CheckMutateBuffer(generated, off, t.Fatalf)
93
94	// Verify that the buffer generated by C++ code is readable by the
95	// generated Go code:
96	monsterDataCpp, err := ioutil.ReadFile(cppData)
97	if err != nil {
98		t.Fatal(err)
99	}
100	CheckReadBuffer(monsterDataCpp, 0, t.Fatalf)
101	CheckMutateBuffer(monsterDataCpp, 0, t.Fatalf)
102
103	// Verify that vtables are deduplicated when written:
104	CheckVtableDeduplication(t.Fatalf)
105
106	// Verify the enum names
107	CheckEnumNames(t.Fatalf)
108
109	// Verify enum String methods
110	CheckEnumString(t.Fatalf)
111
112	// Verify the enum values maps
113	CheckEnumValues(t.Fatalf)
114
115	// Verify that the Go code used in FlatBuffers documentation passes
116	// some sanity checks:
117	CheckDocExample(generated, off, t.Fatalf)
118
119	// Check Builder.CreateByteVector
120	CheckCreateByteVector(t.Fatalf)
121
122	// Check a parent namespace import
123	CheckParentNamespace(t.Fatalf)
124
125	// If the filename of the FlatBuffers file generated by the Java test
126	// is given, check that Go code can read it, and that Go code
127	// generates an identical buffer when used to create the example data:
128	if javaData != "" {
129		monsterDataJava, err := ioutil.ReadFile(javaData)
130		if err != nil {
131			t.Fatal(err)
132		}
133		CheckReadBuffer(monsterDataJava, 0, t.Fatalf)
134		CheckByteEquality(generated[off:], monsterDataJava, t.Fatalf)
135	}
136
137	// Verify that various fuzzing scenarios produce a valid FlatBuffer.
138	if fuzz {
139		checkFuzz(fuzzFields, fuzzObjects, t.Fatalf)
140	}
141
142	// Write the generated buffer out to a file:
143	err = ioutil.WriteFile(outData, generated[off:], os.FileMode(0644))
144	if err != nil {
145		t.Fatal(err)
146	}
147}
148
149// CheckReadBuffer checks that the given buffer is evaluated correctly
150// as the example Monster.
151func CheckReadBuffer(buf []byte, offset flatbuffers.UOffsetT, fail func(string, ...interface{})) {
152	// try the two ways of generating a monster
153	monster1 := example.GetRootAsMonster(buf, offset)
154	monster2 := &example.Monster{}
155	flatbuffers.GetRootAs(buf, offset, monster2)
156	for _, monster := range []*example.Monster{monster1, monster2} {
157		if got := monster.Hp(); 80 != got {
158			fail(FailString("hp", 80, got))
159		}
160
161		// default
162		if got := monster.Mana(); 150 != got {
163			fail(FailString("mana", 150, got))
164		}
165
166		if got := monster.Name(); !bytes.Equal([]byte("MyMonster"), got) {
167			fail(FailString("name", "MyMonster", got))
168		}
169
170		if got := monster.Color(); example.ColorBlue != got {
171			fail(FailString("color", example.ColorBlue, got))
172		}
173
174		if got := monster.Testbool(); true != got {
175			fail(FailString("testbool", true, got))
176		}
177
178		// initialize a Vec3 from Pos()
179		vec := new(example.Vec3)
180		vec = monster.Pos(vec)
181		if vec == nil {
182			fail("vec3 initialization failed")
183		}
184
185		// check that new allocs equal given ones:
186		vec2 := monster.Pos(nil)
187		if !reflect.DeepEqual(vec, vec2) {
188			fail("fresh allocation failed")
189		}
190
191		// verify the properties of the Vec3
192		if got := vec.X(); float32(1.0) != got {
193			fail(FailString("Pos.X", float32(1.0), got))
194		}
195
196		if got := vec.Y(); float32(2.0) != got {
197			fail(FailString("Pos.Y", float32(2.0), got))
198		}
199
200		if got := vec.Z(); float32(3.0) != got {
201			fail(FailString("Pos.Z", float32(3.0), got))
202		}
203
204		if got := vec.Test1(); float64(3.0) != got {
205			fail(FailString("Pos.Test1", float64(3.0), got))
206		}
207
208		if got := vec.Test2(); example.ColorGreen != got {
209			fail(FailString("Pos.Test2", example.ColorGreen, got))
210		}
211
212		// initialize a Test from Test3(...)
213		t := new(example.Test)
214		t = vec.Test3(t)
215		if t == nil {
216			fail("vec.Test3(&t) failed")
217		}
218
219		// check that new allocs equal given ones:
220		t2 := vec.Test3(nil)
221		if !reflect.DeepEqual(t, t2) {
222			fail("fresh allocation failed")
223		}
224
225		// verify the properties of the Test
226		if got := t.A(); int16(5) != got {
227			fail(FailString("t.A()", int16(5), got))
228		}
229
230		if got := t.B(); int8(6) != got {
231			fail(FailString("t.B()", int8(6), got))
232		}
233
234		if got := monster.TestType(); example.AnyMonster != got {
235			fail(FailString("monster.TestType()", example.AnyMonster, got))
236		}
237
238		// initialize a Table from a union field Test(...)
239		var table2 flatbuffers.Table
240		if ok := monster.Test(&table2); !ok {
241			fail("monster.Test(&monster2) failed")
242		}
243
244		// initialize a Monster from the Table from the union
245		var monster2 example.Monster
246		monster2.Init(table2.Bytes, table2.Pos)
247
248		if got := monster2.Name(); !bytes.Equal([]byte("Fred"), got) {
249			fail(FailString("monster2.Name()", "Fred", got))
250		}
251
252		inventorySlice := monster.InventoryBytes()
253		if len(inventorySlice) != monster.InventoryLength() {
254			fail(FailString("len(monster.InventoryBytes) != monster.InventoryLength", len(inventorySlice), monster.InventoryLength()))
255		}
256
257		if got := monster.InventoryLength(); 5 != got {
258			fail(FailString("monster.InventoryLength", 5, got))
259		}
260
261		invsum := 0
262		l := monster.InventoryLength()
263		for i := 0; i < l; i++ {
264			v := monster.Inventory(i)
265			if v != inventorySlice[i] {
266				fail(FailString("monster inventory slice[i] != Inventory(i)", v, inventorySlice[i]))
267			}
268			invsum += int(v)
269		}
270		if invsum != 10 {
271			fail(FailString("monster inventory sum", 10, invsum))
272		}
273
274		if got := monster.Test4Length(); 2 != got {
275			fail(FailString("monster.Test4Length()", 2, got))
276		}
277
278		var test0 example.Test
279		ok := monster.Test4(&test0, 0)
280		if !ok {
281			fail(FailString("monster.Test4(&test0, 0)", true, ok))
282		}
283
284		var test1 example.Test
285		ok = monster.Test4(&test1, 1)
286		if !ok {
287			fail(FailString("monster.Test4(&test1, 1)", true, ok))
288		}
289
290		// the position of test0 and test1 are swapped in monsterdata_java_wire
291		// and monsterdata_test_wire, so ignore ordering
292		v0 := test0.A()
293		v1 := test0.B()
294		v2 := test1.A()
295		v3 := test1.B()
296		sum := int(v0) + int(v1) + int(v2) + int(v3)
297
298		if 100 != sum {
299			fail(FailString("test0 and test1 sum", 100, sum))
300		}
301
302		if got := monster.TestarrayofstringLength(); 2 != got {
303			fail(FailString("Testarrayofstring length", 2, got))
304		}
305
306		if got := monster.Testarrayofstring(0); !bytes.Equal([]byte("test1"), got) {
307			fail(FailString("Testarrayofstring(0)", "test1", got))
308		}
309
310		if got := monster.Testarrayofstring(1); !bytes.Equal([]byte("test2"), got) {
311			fail(FailString("Testarrayofstring(1)", "test2", got))
312		}
313	}
314}
315
316// CheckMutateBuffer checks that the given buffer can be mutated correctly
317// as the example Monster. Only available scalar values are mutated.
318func CheckMutateBuffer(org []byte, offset flatbuffers.UOffsetT, fail func(string, ...interface{})) {
319	// make a copy to mutate
320	buf := make([]byte, len(org))
321	copy(buf, org)
322
323	// load monster data from the buffer
324	monster := example.GetRootAsMonster(buf, offset)
325
326	// test case struct
327	type testcase struct {
328		field  string
329		testfn func() bool
330	}
331
332	testForOriginalValues := []testcase{
333		testcase{"Hp", func() bool { return monster.Hp() == 80 }},
334		testcase{"Mana", func() bool { return monster.Mana() == 150 }},
335		testcase{"Testbool", func() bool { return monster.Testbool() == true }},
336		testcase{"Pos.X'", func() bool { return monster.Pos(nil).X() == float32(1.0) }},
337		testcase{"Pos.Y'", func() bool { return monster.Pos(nil).Y() == float32(2.0) }},
338		testcase{"Pos.Z'", func() bool { return monster.Pos(nil).Z() == float32(3.0) }},
339		testcase{"Pos.Test1'", func() bool { return monster.Pos(nil).Test1() == float64(3.0) }},
340		testcase{"Pos.Test2'", func() bool { return monster.Pos(nil).Test2() == example.ColorGreen }},
341		testcase{"Pos.Test3.A", func() bool { return monster.Pos(nil).Test3(nil).A() == int16(5) }},
342		testcase{"Pos.Test3.B", func() bool { return monster.Pos(nil).Test3(nil).B() == int8(6) }},
343		testcase{"Inventory[2]", func() bool { return monster.Inventory(2) == byte(2) }},
344	}
345
346	testMutability := []testcase{
347		testcase{"Hp", func() bool { return monster.MutateHp(70) }},
348		testcase{"Mana", func() bool { return !monster.MutateMana(140) }},
349		testcase{"Testbool", func() bool { return monster.MutateTestbool(false) }},
350		testcase{"Pos.X", func() bool { return monster.Pos(nil).MutateX(10.0) }},
351		testcase{"Pos.Y", func() bool { return monster.Pos(nil).MutateY(20.0) }},
352		testcase{"Pos.Z", func() bool { return monster.Pos(nil).MutateZ(30.0) }},
353		testcase{"Pos.Test1", func() bool { return monster.Pos(nil).MutateTest1(30.0) }},
354		testcase{"Pos.Test2", func() bool { return monster.Pos(nil).MutateTest2(example.ColorBlue) }},
355		testcase{"Pos.Test3.A", func() bool { return monster.Pos(nil).Test3(nil).MutateA(50) }},
356		testcase{"Pos.Test3.B", func() bool { return monster.Pos(nil).Test3(nil).MutateB(60) }},
357		testcase{"Inventory[2]", func() bool { return monster.MutateInventory(2, 200) }},
358	}
359
360	testForMutatedValues := []testcase{
361		testcase{"Hp", func() bool { return monster.Hp() == 70 }},
362		testcase{"Mana", func() bool { return monster.Mana() == 150 }},
363		testcase{"Testbool", func() bool { return monster.Testbool() == false }},
364		testcase{"Pos.X'", func() bool { return monster.Pos(nil).X() == float32(10.0) }},
365		testcase{"Pos.Y'", func() bool { return monster.Pos(nil).Y() == float32(20.0) }},
366		testcase{"Pos.Z'", func() bool { return monster.Pos(nil).Z() == float32(30.0) }},
367		testcase{"Pos.Test1'", func() bool { return monster.Pos(nil).Test1() == float64(30.0) }},
368		testcase{"Pos.Test2'", func() bool { return monster.Pos(nil).Test2() == example.ColorBlue }},
369		testcase{"Pos.Test3.A", func() bool { return monster.Pos(nil).Test3(nil).A() == int16(50) }},
370		testcase{"Pos.Test3.B", func() bool { return monster.Pos(nil).Test3(nil).B() == int8(60) }},
371		testcase{"Inventory[2]", func() bool { return monster.Inventory(2) == byte(200) }},
372	}
373
374	testInvalidEnumValues := []testcase{
375		testcase{"Pos.Test2", func() bool { return monster.Pos(nil).MutateTest2(example.Color(20)) }},
376		testcase{"Pos.Test2", func() bool { return monster.Pos(nil).Test2() == example.Color(20) }},
377	}
378
379	// make sure original values are okay
380	for _, t := range testForOriginalValues {
381		if !t.testfn() {
382			fail("field '" + t.field + "' doesn't have the expected original value")
383		}
384	}
385
386	// try to mutate fields and check mutability
387	for _, t := range testMutability {
388		if !t.testfn() {
389			fail(FailString("field '"+t.field+"' failed mutability test", true, false))
390		}
391	}
392
393	// test whether values have changed
394	for _, t := range testForMutatedValues {
395		if !t.testfn() {
396			fail("field '" + t.field + "' doesn't have the expected mutated value")
397		}
398	}
399
400	// make sure the buffer has changed
401	if reflect.DeepEqual(buf, org) {
402		fail("mutate buffer failed")
403	}
404
405	// To make sure the buffer has changed accordingly
406	// Read data from the buffer and verify all fields
407	monster = example.GetRootAsMonster(buf, offset)
408	for _, t := range testForMutatedValues {
409		if !t.testfn() {
410			fail("field '" + t.field + "' doesn't have the expected mutated value")
411		}
412	}
413
414	// a couple extra tests for "invalid" enum values, which don't correspond to
415	// anything in the schema, but are allowed
416	for _, t := range testInvalidEnumValues {
417		if !t.testfn() {
418			fail("field '" + t.field + "' doesn't work with an invalid enum value")
419		}
420	}
421
422	// reverting all fields to original values should
423	// re-create the original buffer. Mutate all fields
424	// back to their original values and compare buffers.
425	// This test is done to make sure mutations do not do
426	// any unnecessary changes to the buffer.
427	monster = example.GetRootAsMonster(buf, offset)
428	monster.MutateHp(80)
429	monster.MutateTestbool(true)
430	monster.Pos(nil).MutateX(1.0)
431	monster.Pos(nil).MutateY(2.0)
432	monster.Pos(nil).MutateZ(3.0)
433	monster.Pos(nil).MutateTest1(3.0)
434	monster.Pos(nil).MutateTest2(example.ColorGreen)
435	monster.Pos(nil).Test3(nil).MutateA(5)
436	monster.Pos(nil).Test3(nil).MutateB(6)
437	monster.MutateInventory(2, 2)
438
439	for _, t := range testForOriginalValues {
440		if !t.testfn() {
441			fail("field '" + t.field + "' doesn't have the expected original value")
442		}
443	}
444
445	// buffer should have original values
446	if !reflect.DeepEqual(buf, org) {
447		fail("revert changes failed")
448	}
449}
450
451// Low level stress/fuzz test: serialize/deserialize a variety of
452// different kinds of data in different combinations
453func checkFuzz(fuzzFields, fuzzObjects int, fail func(string, ...interface{})) {
454
455	// Values we're testing against: chosen to ensure no bits get chopped
456	// off anywhere, and also be different from eachother.
457	boolVal := true
458	int8Val := int8(-127) // 0x81
459	uint8Val := uint8(0xFF)
460	int16Val := int16(-32222) // 0x8222
461	uint16Val := uint16(0xFEEE)
462	int32Val := int32(overflowingInt32Val)
463	uint32Val := uint32(0xFDDDDDDD)
464	int64Val := int64(overflowingInt64Val)
465	uint64Val := uint64(0xFCCCCCCCCCCCCCCC)
466	float32Val := float32(3.14159)
467	float64Val := float64(3.14159265359)
468
469	testValuesMax := 11 // hardcoded to the number of scalar types
470
471	builder := flatbuffers.NewBuilder(0)
472	l := NewLCG()
473
474	objects := make([]flatbuffers.UOffsetT, fuzzObjects)
475
476	// Generate fuzzObjects random objects each consisting of
477	// fuzzFields fields, each of a random type.
478	for i := 0; i < fuzzObjects; i++ {
479		builder.StartObject(fuzzFields)
480
481		for f := 0; f < fuzzFields; f++ {
482			choice := l.Next() % uint32(testValuesMax)
483			switch choice {
484			case 0:
485				builder.PrependBoolSlot(int(f), boolVal, false)
486			case 1:
487				builder.PrependInt8Slot(int(f), int8Val, 0)
488			case 2:
489				builder.PrependUint8Slot(int(f), uint8Val, 0)
490			case 3:
491				builder.PrependInt16Slot(int(f), int16Val, 0)
492			case 4:
493				builder.PrependUint16Slot(int(f), uint16Val, 0)
494			case 5:
495				builder.PrependInt32Slot(int(f), int32Val, 0)
496			case 6:
497				builder.PrependUint32Slot(int(f), uint32Val, 0)
498			case 7:
499				builder.PrependInt64Slot(int(f), int64Val, 0)
500			case 8:
501				builder.PrependUint64Slot(int(f), uint64Val, 0)
502			case 9:
503				builder.PrependFloat32Slot(int(f), float32Val, 0)
504			case 10:
505				builder.PrependFloat64Slot(int(f), float64Val, 0)
506			}
507		}
508
509		off := builder.EndObject()
510
511		// store the offset from the end of the builder buffer,
512		// since it will keep growing:
513		objects[i] = off
514	}
515
516	// Do some bookkeeping to generate stats on fuzzes:
517	stats := map[string]int{}
518	check := func(desc string, want, got interface{}) {
519		stats[desc]++
520		if want != got {
521			fail("%s want %v got %v", desc, want, got)
522		}
523	}
524
525	l = NewLCG() // Reset.
526
527	// Test that all objects we generated are readable and return the
528	// expected values. We generate random objects in the same order
529	// so this is deterministic.
530	for i := 0; i < fuzzObjects; i++ {
531
532		table := &flatbuffers.Table{
533			Bytes: builder.Bytes,
534			Pos:   flatbuffers.UOffsetT(len(builder.Bytes)) - objects[i],
535		}
536
537		for j := 0; j < fuzzFields; j++ {
538			f := flatbuffers.VOffsetT((flatbuffers.VtableMetadataFields + j) * flatbuffers.SizeVOffsetT)
539			choice := l.Next() % uint32(testValuesMax)
540
541			switch choice {
542			case 0:
543				check("bool", boolVal, table.GetBoolSlot(f, false))
544			case 1:
545				check("int8", int8Val, table.GetInt8Slot(f, 0))
546			case 2:
547				check("uint8", uint8Val, table.GetUint8Slot(f, 0))
548			case 3:
549				check("int16", int16Val, table.GetInt16Slot(f, 0))
550			case 4:
551				check("uint16", uint16Val, table.GetUint16Slot(f, 0))
552			case 5:
553				check("int32", int32Val, table.GetInt32Slot(f, 0))
554			case 6:
555				check("uint32", uint32Val, table.GetUint32Slot(f, 0))
556			case 7:
557				check("int64", int64Val, table.GetInt64Slot(f, 0))
558			case 8:
559				check("uint64", uint64Val, table.GetUint64Slot(f, 0))
560			case 9:
561				check("float32", float32Val, table.GetFloat32Slot(f, 0))
562			case 10:
563				check("float64", float64Val, table.GetFloat64Slot(f, 0))
564			}
565		}
566	}
567
568	// If enough checks were made, verify that all scalar types were used:
569	if fuzzFields*fuzzObjects >= testValuesMax {
570		if len(stats) != testValuesMax {
571			fail("fuzzing failed to test all scalar types")
572		}
573	}
574
575	// Print some counts, if needed:
576	if testing.Verbose() {
577		if fuzzFields == 0 || fuzzObjects == 0 {
578			fmt.Printf("fuzz\tfields: %d\tobjects: %d\t[none]\t%d\n",
579				fuzzFields, fuzzObjects, 0)
580		} else {
581			keys := make([]string, 0, len(stats))
582			for k := range stats {
583				keys = append(keys, k)
584			}
585			sort.Strings(keys)
586			for _, k := range keys {
587				fmt.Printf("fuzz\tfields: %d\tobjects: %d\t%s\t%d\n",
588					fuzzFields, fuzzObjects, k, stats[k])
589			}
590		}
591	}
592
593	return
594}
595
596// FailString makes a message for when expectations differ from reality.
597func FailString(name string, want, got interface{}) string {
598	return fmt.Sprintf("bad %s: want %#v got %#v", name, want, got)
599}
600
601// CheckByteLayout verifies the bytes of a Builder in various scenarios.
602func CheckByteLayout(fail func(string, ...interface{})) {
603	var b *flatbuffers.Builder
604
605	var i int
606	check := func(want []byte) {
607		i++
608		got := b.Bytes[b.Head():]
609		if !bytes.Equal(want, got) {
610			fail("case %d: want\n%v\nbut got\n%v\n", i, want, got)
611		}
612	}
613
614	// test 1: numbers
615
616	b = flatbuffers.NewBuilder(0)
617	check([]byte{})
618	b.PrependBool(true)
619	check([]byte{1})
620	b.PrependInt8(-127)
621	check([]byte{129, 1})
622	b.PrependUint8(255)
623	check([]byte{255, 129, 1})
624	b.PrependInt16(-32222)
625	check([]byte{0x22, 0x82, 0, 255, 129, 1}) // first pad
626	b.PrependUint16(0xFEEE)
627	check([]byte{0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1}) // no pad this time
628	b.PrependInt32(-53687092)
629	check([]byte{204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1})
630	b.PrependUint32(0x98765432)
631	check([]byte{0x32, 0x54, 0x76, 0x98, 204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1})
632
633	// test 1b: numbers 2
634
635	b = flatbuffers.NewBuilder(0)
636	b.PrependUint64(0x1122334455667788)
637	check([]byte{0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11})
638
639	// test 2: 1xbyte vector
640
641	b = flatbuffers.NewBuilder(0)
642	check([]byte{})
643	b.StartVector(flatbuffers.SizeByte, 1, 1)
644	check([]byte{0, 0, 0}) // align to 4bytes
645	b.PrependByte(1)
646	check([]byte{1, 0, 0, 0})
647	b.EndVector(1)
648	check([]byte{1, 0, 0, 0, 1, 0, 0, 0}) // padding
649
650	// test 3: 2xbyte vector
651
652	b = flatbuffers.NewBuilder(0)
653	b.StartVector(flatbuffers.SizeByte, 2, 1)
654	check([]byte{0, 0}) // align to 4bytes
655	b.PrependByte(1)
656	check([]byte{1, 0, 0})
657	b.PrependByte(2)
658	check([]byte{2, 1, 0, 0})
659	b.EndVector(2)
660	check([]byte{2, 0, 0, 0, 2, 1, 0, 0}) // padding
661
662	// test 3b: 11xbyte vector matches builder size
663
664	b = flatbuffers.NewBuilder(12)
665	b.StartVector(flatbuffers.SizeByte, 8, 1)
666	start := []byte{}
667	check(start)
668	for i := 1; i < 12; i++ {
669		b.PrependByte(byte(i))
670		start = append([]byte{byte(i)}, start...)
671		check(start)
672	}
673	b.EndVector(8)
674	check(append([]byte{8, 0, 0, 0}, start...))
675
676	// test 4: 1xuint16 vector
677
678	b = flatbuffers.NewBuilder(0)
679	b.StartVector(flatbuffers.SizeUint16, 1, 1)
680	check([]byte{0, 0}) // align to 4bytes
681	b.PrependUint16(1)
682	check([]byte{1, 0, 0, 0})
683	b.EndVector(1)
684	check([]byte{1, 0, 0, 0, 1, 0, 0, 0}) // padding
685
686	// test 5: 2xuint16 vector
687
688	b = flatbuffers.NewBuilder(0)
689	b.StartVector(flatbuffers.SizeUint16, 2, 1)
690	check([]byte{}) // align to 4bytes
691	b.PrependUint16(0xABCD)
692	check([]byte{0xCD, 0xAB})
693	b.PrependUint16(0xDCBA)
694	check([]byte{0xBA, 0xDC, 0xCD, 0xAB})
695	b.EndVector(2)
696	check([]byte{2, 0, 0, 0, 0xBA, 0xDC, 0xCD, 0xAB})
697
698	// test 6: CreateString
699
700	b = flatbuffers.NewBuilder(0)
701	b.CreateString("foo")
702	check([]byte{3, 0, 0, 0, 'f', 'o', 'o', 0}) // 0-terminated, no pad
703	b.CreateString("moop")
704	check([]byte{4, 0, 0, 0, 'm', 'o', 'o', 'p', 0, 0, 0, 0, // 0-terminated, 3-byte pad
705		3, 0, 0, 0, 'f', 'o', 'o', 0})
706
707	// test 6b: CreateString unicode
708
709	b = flatbuffers.NewBuilder(0)
710	// These characters are chinese from blog.golang.org/strings
711	// We use escape codes here so that editors without unicode support
712	// aren't bothered:
713	uni_str := "\u65e5\u672c\u8a9e"
714	b.CreateString(uni_str)
715	check([]byte{9, 0, 0, 0, 230, 151, 165, 230, 156, 172, 232, 170, 158, 0, //  null-terminated, 2-byte pad
716		0, 0})
717
718	// test 6c: CreateByteString
719
720	b = flatbuffers.NewBuilder(0)
721	b.CreateByteString([]byte("foo"))
722	check([]byte{3, 0, 0, 0, 'f', 'o', 'o', 0}) // 0-terminated, no pad
723	b.CreateByteString([]byte("moop"))
724	check([]byte{4, 0, 0, 0, 'm', 'o', 'o', 'p', 0, 0, 0, 0, // 0-terminated, 3-byte pad
725		3, 0, 0, 0, 'f', 'o', 'o', 0})
726
727	// test 7: empty vtable
728	b = flatbuffers.NewBuilder(0)
729	b.StartObject(0)
730	check([]byte{})
731	b.EndObject()
732	check([]byte{4, 0, 4, 0, 4, 0, 0, 0})
733
734	// test 8: vtable with one true bool
735	b = flatbuffers.NewBuilder(0)
736	check([]byte{})
737	b.StartObject(1)
738	check([]byte{})
739	b.PrependBoolSlot(0, true, false)
740	b.EndObject()
741	check([]byte{
742		6, 0, // vtable bytes
743		8, 0, // length of object including vtable offset
744		7, 0, // start of bool value
745		6, 0, 0, 0, // offset for start of vtable (int32)
746		0, 0, 0, // padded to 4 bytes
747		1, // bool value
748	})
749
750	// test 9: vtable with one default bool
751	b = flatbuffers.NewBuilder(0)
752	check([]byte{})
753	b.StartObject(1)
754	check([]byte{})
755	b.PrependBoolSlot(0, false, false)
756	b.EndObject()
757	check([]byte{
758		4, 0, // vtable bytes
759		4, 0, // end of object from here
760		// entry 1 is zero and not stored.
761		4, 0, 0, 0, // offset for start of vtable (int32)
762	})
763
764	// test 10: vtable with one int16
765	b = flatbuffers.NewBuilder(0)
766	b.StartObject(1)
767	b.PrependInt16Slot(0, 0x789A, 0)
768	b.EndObject()
769	check([]byte{
770		6, 0, // vtable bytes
771		8, 0, // end of object from here
772		6, 0, // offset to value
773		6, 0, 0, 0, // offset for start of vtable (int32)
774		0, 0, // padding to 4 bytes
775		0x9A, 0x78,
776	})
777
778	// test 11: vtable with two int16
779	b = flatbuffers.NewBuilder(0)
780	b.StartObject(2)
781	b.PrependInt16Slot(0, 0x3456, 0)
782	b.PrependInt16Slot(1, 0x789A, 0)
783	b.EndObject()
784	check([]byte{
785		8, 0, // vtable bytes
786		8, 0, // end of object from here
787		6, 0, // offset to value 0
788		4, 0, // offset to value 1
789		8, 0, 0, 0, // offset for start of vtable (int32)
790		0x9A, 0x78, // value 1
791		0x56, 0x34, // value 0
792	})
793
794	// test 12: vtable with int16 and bool
795	b = flatbuffers.NewBuilder(0)
796	b.StartObject(2)
797	b.PrependInt16Slot(0, 0x3456, 0)
798	b.PrependBoolSlot(1, true, false)
799	b.EndObject()
800	check([]byte{
801		8, 0, // vtable bytes
802		8, 0, // end of object from here
803		6, 0, // offset to value 0
804		5, 0, // offset to value 1
805		8, 0, 0, 0, // offset for start of vtable (int32)
806		0,          // padding
807		1,          // value 1
808		0x56, 0x34, // value 0
809	})
810
811	// test 12: vtable with empty vector
812	b = flatbuffers.NewBuilder(0)
813	b.StartVector(flatbuffers.SizeByte, 0, 1)
814	vecend := b.EndVector(0)
815	b.StartObject(1)
816	b.PrependUOffsetTSlot(0, vecend, 0)
817	b.EndObject()
818	check([]byte{
819		6, 0, // vtable bytes
820		8, 0,
821		4, 0, // offset to vector offset
822		6, 0, 0, 0, // offset for start of vtable (int32)
823		4, 0, 0, 0,
824		0, 0, 0, 0, // length of vector (not in struct)
825	})
826
827	// test 12b: vtable with empty vector of byte and some scalars
828	b = flatbuffers.NewBuilder(0)
829	b.StartVector(flatbuffers.SizeByte, 0, 1)
830	vecend = b.EndVector(0)
831	b.StartObject(2)
832	b.PrependInt16Slot(0, 55, 0)
833	b.PrependUOffsetTSlot(1, vecend, 0)
834	b.EndObject()
835	check([]byte{
836		8, 0, // vtable bytes
837		12, 0,
838		10, 0, // offset to value 0
839		4, 0, // offset to vector offset
840		8, 0, 0, 0, // vtable loc
841		8, 0, 0, 0, // value 1
842		0, 0, 55, 0, // value 0
843
844		0, 0, 0, 0, // length of vector (not in struct)
845	})
846
847	// test 13: vtable with 1 int16 and 2-vector of int16
848	b = flatbuffers.NewBuilder(0)
849	b.StartVector(flatbuffers.SizeInt16, 2, 1)
850	b.PrependInt16(0x1234)
851	b.PrependInt16(0x5678)
852	vecend = b.EndVector(2)
853	b.StartObject(2)
854	b.PrependUOffsetTSlot(1, vecend, 0)
855	b.PrependInt16Slot(0, 55, 0)
856	b.EndObject()
857	check([]byte{
858		8, 0, // vtable bytes
859		12, 0, // length of object
860		6, 0, // start of value 0 from end of vtable
861		8, 0, // start of value 1 from end of buffer
862		8, 0, 0, 0, // offset for start of vtable (int32)
863		0, 0, // padding
864		55, 0, // value 0
865		4, 0, 0, 0, // vector position from here
866		2, 0, 0, 0, // length of vector (uint32)
867		0x78, 0x56, // vector value 1
868		0x34, 0x12, // vector value 0
869	})
870
871	// test 14: vtable with 1 struct of 1 int8, 1 int16, 1 int32
872	b = flatbuffers.NewBuilder(0)
873	b.StartObject(1)
874	b.Prep(4+4+4, 0)
875	b.PrependInt8(55)
876	b.Pad(3)
877	b.PrependInt16(0x1234)
878	b.Pad(2)
879	b.PrependInt32(0x12345678)
880	structStart := b.Offset()
881	b.PrependStructSlot(0, structStart, 0)
882	b.EndObject()
883	check([]byte{
884		6, 0, // vtable bytes
885		16, 0, // end of object from here
886		4, 0, // start of struct from here
887		6, 0, 0, 0, // offset for start of vtable (int32)
888		0x78, 0x56, 0x34, 0x12, // value 2
889		0, 0, // padding
890		0x34, 0x12, // value 1
891		0, 0, 0, // padding
892		55, // value 0
893	})
894
895	// test 15: vtable with 1 vector of 2 struct of 2 int8
896	b = flatbuffers.NewBuilder(0)
897	b.StartVector(flatbuffers.SizeInt8*2, 2, 1)
898	b.PrependInt8(33)
899	b.PrependInt8(44)
900	b.PrependInt8(55)
901	b.PrependInt8(66)
902	vecend = b.EndVector(2)
903	b.StartObject(1)
904	b.PrependUOffsetTSlot(0, vecend, 0)
905	b.EndObject()
906	check([]byte{
907		6, 0, // vtable bytes
908		8, 0,
909		4, 0, // offset of vector offset
910		6, 0, 0, 0, // offset for start of vtable (int32)
911		4, 0, 0, 0, // vector start offset
912
913		2, 0, 0, 0, // vector length
914		66, // vector value 1,1
915		55, // vector value 1,0
916		44, // vector value 0,1
917		33, // vector value 0,0
918	})
919
920	// test 16: table with some elements
921	b = flatbuffers.NewBuilder(0)
922	b.StartObject(2)
923	b.PrependInt8Slot(0, 33, 0)
924	b.PrependInt16Slot(1, 66, 0)
925	off := b.EndObject()
926	b.Finish(off)
927
928	check([]byte{
929		12, 0, 0, 0, // root of table: points to vtable offset
930
931		8, 0, // vtable bytes
932		8, 0, // end of object from here
933		7, 0, // start of value 0
934		4, 0, // start of value 1
935
936		8, 0, 0, 0, // offset for start of vtable (int32)
937
938		66, 0, // value 1
939		0,  // padding
940		33, // value 0
941	})
942
943	// test 17: one unfinished table and one finished table
944	b = flatbuffers.NewBuilder(0)
945	b.StartObject(2)
946	b.PrependInt8Slot(0, 33, 0)
947	b.PrependInt8Slot(1, 44, 0)
948	off = b.EndObject()
949	b.Finish(off)
950
951	b.StartObject(3)
952	b.PrependInt8Slot(0, 55, 0)
953	b.PrependInt8Slot(1, 66, 0)
954	b.PrependInt8Slot(2, 77, 0)
955	off = b.EndObject()
956	b.Finish(off)
957
958	check([]byte{
959		16, 0, 0, 0, // root of table: points to object
960		0, 0, // padding
961
962		10, 0, // vtable bytes
963		8, 0, // size of object
964		7, 0, // start of value 0
965		6, 0, // start of value 1
966		5, 0, // start of value 2
967		10, 0, 0, 0, // offset for start of vtable (int32)
968		0,  // padding
969		77, // value 2
970		66, // value 1
971		55, // value 0
972
973		12, 0, 0, 0, // root of table: points to object
974
975		8, 0, // vtable bytes
976		8, 0, // size of object
977		7, 0, // start of value 0
978		6, 0, // start of value 1
979		8, 0, 0, 0, // offset for start of vtable (int32)
980		0, 0, // padding
981		44, // value 1
982		33, // value 0
983	})
984
985	// test 18: a bunch of bools
986	b = flatbuffers.NewBuilder(0)
987	b.StartObject(8)
988	b.PrependBoolSlot(0, true, false)
989	b.PrependBoolSlot(1, true, false)
990	b.PrependBoolSlot(2, true, false)
991	b.PrependBoolSlot(3, true, false)
992	b.PrependBoolSlot(4, true, false)
993	b.PrependBoolSlot(5, true, false)
994	b.PrependBoolSlot(6, true, false)
995	b.PrependBoolSlot(7, true, false)
996	off = b.EndObject()
997	b.Finish(off)
998
999	check([]byte{
1000		24, 0, 0, 0, // root of table: points to vtable offset
1001
1002		20, 0, // vtable bytes
1003		12, 0, // size of object
1004		11, 0, // start of value 0
1005		10, 0, // start of value 1
1006		9, 0, // start of value 2
1007		8, 0, // start of value 3
1008		7, 0, // start of value 4
1009		6, 0, // start of value 5
1010		5, 0, // start of value 6
1011		4, 0, // start of value 7
1012		20, 0, 0, 0, // vtable offset
1013
1014		1, // value 7
1015		1, // value 6
1016		1, // value 5
1017		1, // value 4
1018		1, // value 3
1019		1, // value 2
1020		1, // value 1
1021		1, // value 0
1022	})
1023
1024	// test 19: three bools
1025	b = flatbuffers.NewBuilder(0)
1026	b.StartObject(3)
1027	b.PrependBoolSlot(0, true, false)
1028	b.PrependBoolSlot(1, true, false)
1029	b.PrependBoolSlot(2, true, false)
1030	off = b.EndObject()
1031	b.Finish(off)
1032
1033	check([]byte{
1034		16, 0, 0, 0, // root of table: points to vtable offset
1035
1036		0, 0, // padding
1037
1038		10, 0, // vtable bytes
1039		8, 0, // size of object
1040		7, 0, // start of value 0
1041		6, 0, // start of value 1
1042		5, 0, // start of value 2
1043		10, 0, 0, 0, // vtable offset from here
1044
1045		0, // padding
1046		1, // value 2
1047		1, // value 1
1048		1, // value 0
1049	})
1050
1051	// test 20: some floats
1052	b = flatbuffers.NewBuilder(0)
1053	b.StartObject(1)
1054	b.PrependFloat32Slot(0, 1.0, 0.0)
1055	off = b.EndObject()
1056
1057	check([]byte{
1058		6, 0, // vtable bytes
1059		8, 0, // size of object
1060		4, 0, // start of value 0
1061		6, 0, 0, 0, // vtable offset
1062
1063		0, 0, 128, 63, // value 0
1064	})
1065}
1066
1067// CheckManualBuild builds a Monster manually.
1068func CheckManualBuild(fail func(string, ...interface{})) ([]byte, flatbuffers.UOffsetT) {
1069	b := flatbuffers.NewBuilder(0)
1070	str := b.CreateString("MyMonster")
1071
1072	b.StartVector(1, 5, 1)
1073	b.PrependByte(4)
1074	b.PrependByte(3)
1075	b.PrependByte(2)
1076	b.PrependByte(1)
1077	b.PrependByte(0)
1078	inv := b.EndVector(5)
1079
1080	b.StartObject(13)
1081	b.PrependInt16Slot(2, 20, 100)
1082	mon2 := b.EndObject()
1083
1084	// Test4Vector
1085	b.StartVector(4, 2, 1)
1086
1087	// Test 0
1088	b.Prep(2, 4)
1089	b.Pad(1)
1090	b.PlaceInt8(20)
1091	b.PlaceInt16(10)
1092
1093	// Test 1
1094	b.Prep(2, 4)
1095	b.Pad(1)
1096	b.PlaceInt8(40)
1097	b.PlaceInt16(30)
1098
1099	// end testvector
1100	test4 := b.EndVector(2)
1101
1102	b.StartObject(13)
1103
1104	// a vec3
1105	b.Prep(16, 32)
1106	b.Pad(2)
1107	b.Prep(2, 4)
1108	b.Pad(1)
1109	b.PlaceByte(6)
1110	b.PlaceInt16(5)
1111	b.Pad(1)
1112	b.PlaceByte(4)
1113	b.PlaceFloat64(3.0)
1114	b.Pad(4)
1115	b.PlaceFloat32(3.0)
1116	b.PlaceFloat32(2.0)
1117	b.PlaceFloat32(1.0)
1118	vec3Loc := b.Offset()
1119	// end vec3
1120
1121	b.PrependStructSlot(0, vec3Loc, 0) // vec3. noop
1122	b.PrependInt16Slot(2, 80, 100)     // hp
1123	b.PrependUOffsetTSlot(3, str, 0)
1124	b.PrependUOffsetTSlot(5, inv, 0) // inventory
1125	b.PrependByteSlot(7, 1, 0)
1126	b.PrependUOffsetTSlot(8, mon2, 0)
1127	b.PrependUOffsetTSlot(9, test4, 0)
1128	mon := b.EndObject()
1129
1130	b.Finish(mon)
1131
1132	return b.Bytes, b.Head()
1133}
1134
1135func CheckGetRootAsForNonRootTable(fail func(string, ...interface{})) {
1136	b := flatbuffers.NewBuilder(0)
1137	str := b.CreateString("MyStat")
1138	example.StatStart(b)
1139	example.StatAddId(b, str)
1140	example.StatAddVal(b, 12345678)
1141	example.StatAddCount(b, 12345)
1142	stat_end := example.StatEnd(b)
1143	b.Finish(stat_end)
1144
1145	stat := example.GetRootAsStat(b.Bytes, b.Head())
1146
1147	if got := stat.Id(); !bytes.Equal([]byte("MyStat"), got) {
1148		fail(FailString("stat.Id()", "MyStat", got))
1149	}
1150
1151	if got := stat.Val(); 12345678 != got {
1152		fail(FailString("stat.Val()", 12345678, got))
1153	}
1154
1155	if got := stat.Count(); 12345 != got {
1156		fail(FailString("stat.Count()", 12345, got))
1157	}
1158}
1159
1160// CheckGeneratedBuild uses generated code to build the example Monster.
1161func CheckGeneratedBuild(fail func(string, ...interface{})) ([]byte, flatbuffers.UOffsetT) {
1162	b := flatbuffers.NewBuilder(0)
1163	str := b.CreateString("MyMonster")
1164	test1 := b.CreateString("test1")
1165	test2 := b.CreateString("test2")
1166	fred := b.CreateString("Fred")
1167
1168	example.MonsterStartInventoryVector(b, 5)
1169	b.PrependByte(4)
1170	b.PrependByte(3)
1171	b.PrependByte(2)
1172	b.PrependByte(1)
1173	b.PrependByte(0)
1174	inv := b.EndVector(5)
1175
1176	example.MonsterStart(b)
1177	example.MonsterAddName(b, fred)
1178	mon2 := example.MonsterEnd(b)
1179
1180	example.MonsterStartTest4Vector(b, 2)
1181	example.CreateTest(b, 10, 20)
1182	example.CreateTest(b, 30, 40)
1183	test4 := b.EndVector(2)
1184
1185	example.MonsterStartTestarrayofstringVector(b, 2)
1186	b.PrependUOffsetT(test2)
1187	b.PrependUOffsetT(test1)
1188	testArrayOfString := b.EndVector(2)
1189
1190	example.MonsterStart(b)
1191
1192	pos := example.CreateVec3(b, 1.0, 2.0, 3.0, 3.0, example.ColorGreen, 5, 6)
1193	example.MonsterAddPos(b, pos)
1194
1195	example.MonsterAddHp(b, 80)
1196	example.MonsterAddName(b, str)
1197	example.MonsterAddTestbool(b, true)
1198	example.MonsterAddInventory(b, inv)
1199	example.MonsterAddTestType(b, 1)
1200	example.MonsterAddTest(b, mon2)
1201	example.MonsterAddTest4(b, test4)
1202	example.MonsterAddTestarrayofstring(b, testArrayOfString)
1203	mon := example.MonsterEnd(b)
1204
1205	b.Finish(mon)
1206
1207	return b.Bytes, b.Head()
1208}
1209
1210// CheckTableAccessors checks that the table accessors work as expected.
1211func CheckTableAccessors(fail func(string, ...interface{})) {
1212	// test struct accessor
1213	b := flatbuffers.NewBuilder(0)
1214	pos := example.CreateVec3(b, 1.0, 2.0, 3.0, 3.0, 4, 5, 6)
1215	b.Finish(pos)
1216	vec3Bytes := b.FinishedBytes()
1217	vec3 := &example.Vec3{}
1218	flatbuffers.GetRootAs(vec3Bytes, 0, vec3)
1219
1220	if bytes.Compare(vec3Bytes, vec3.Table().Bytes) != 0 {
1221		fail("invalid vec3 table")
1222	}
1223
1224	// test table accessor
1225	b = flatbuffers.NewBuilder(0)
1226	str := b.CreateString("MyStat")
1227	example.StatStart(b)
1228	example.StatAddId(b, str)
1229	example.StatAddVal(b, 12345678)
1230	example.StatAddCount(b, 12345)
1231	pos = example.StatEnd(b)
1232	b.Finish(pos)
1233	statBytes := b.FinishedBytes()
1234	stat := &example.Stat{}
1235	flatbuffers.GetRootAs(statBytes, 0, stat)
1236
1237	if bytes.Compare(statBytes, stat.Table().Bytes) != 0 {
1238		fail("invalid stat table")
1239	}
1240}
1241
1242// CheckVtableDeduplication verifies that vtables are deduplicated.
1243func CheckVtableDeduplication(fail func(string, ...interface{})) {
1244	b := flatbuffers.NewBuilder(0)
1245
1246	b.StartObject(4)
1247	b.PrependByteSlot(0, 0, 0)
1248	b.PrependByteSlot(1, 11, 0)
1249	b.PrependByteSlot(2, 22, 0)
1250	b.PrependInt16Slot(3, 33, 0)
1251	obj0 := b.EndObject()
1252
1253	b.StartObject(4)
1254	b.PrependByteSlot(0, 0, 0)
1255	b.PrependByteSlot(1, 44, 0)
1256	b.PrependByteSlot(2, 55, 0)
1257	b.PrependInt16Slot(3, 66, 0)
1258	obj1 := b.EndObject()
1259
1260	b.StartObject(4)
1261	b.PrependByteSlot(0, 0, 0)
1262	b.PrependByteSlot(1, 77, 0)
1263	b.PrependByteSlot(2, 88, 0)
1264	b.PrependInt16Slot(3, 99, 0)
1265	obj2 := b.EndObject()
1266
1267	got := b.Bytes[b.Head():]
1268
1269	want := []byte{
1270		240, 255, 255, 255, // == -12. offset to dedupped vtable.
1271		99, 0,
1272		88,
1273		77,
1274		248, 255, 255, 255, // == -8. offset to dedupped vtable.
1275		66, 0,
1276		55,
1277		44,
1278		12, 0,
1279		8, 0,
1280		0, 0,
1281		7, 0,
1282		6, 0,
1283		4, 0,
1284		12, 0, 0, 0,
1285		33, 0,
1286		22,
1287		11,
1288	}
1289
1290	if !bytes.Equal(want, got) {
1291		fail("testVtableDeduplication want:\n%d %v\nbut got:\n%d %v\n",
1292			len(want), want, len(got), got)
1293	}
1294
1295	table0 := &flatbuffers.Table{Bytes: b.Bytes, Pos: flatbuffers.UOffsetT(len(b.Bytes)) - obj0}
1296	table1 := &flatbuffers.Table{Bytes: b.Bytes, Pos: flatbuffers.UOffsetT(len(b.Bytes)) - obj1}
1297	table2 := &flatbuffers.Table{Bytes: b.Bytes, Pos: flatbuffers.UOffsetT(len(b.Bytes)) - obj2}
1298
1299	testTable := func(tab *flatbuffers.Table, a flatbuffers.VOffsetT, b, c, d byte) {
1300		// vtable size
1301		if got := tab.GetVOffsetTSlot(0, 0); 12 != got {
1302			fail("failed 0, 0: %d", got)
1303		}
1304		// object size
1305		if got := tab.GetVOffsetTSlot(2, 0); 8 != got {
1306			fail("failed 2, 0: %d", got)
1307		}
1308		// default value
1309		if got := tab.GetVOffsetTSlot(4, 0); a != got {
1310			fail("failed 4, 0: %d", got)
1311		}
1312		if got := tab.GetByteSlot(6, 0); b != got {
1313			fail("failed 6, 0: %d", got)
1314		}
1315		if val := tab.GetByteSlot(8, 0); c != val {
1316			fail("failed 8, 0: %d", got)
1317		}
1318		if got := tab.GetByteSlot(10, 0); d != got {
1319			fail("failed 10, 0: %d", got)
1320		}
1321	}
1322
1323	testTable(table0, 0, 11, 22, 33)
1324	testTable(table1, 0, 44, 55, 66)
1325	testTable(table2, 0, 77, 88, 99)
1326}
1327
1328// CheckNotInObjectError verifies that `EndObject` fails if not inside an
1329// object.
1330func CheckNotInObjectError(fail func(string, ...interface{})) {
1331	b := flatbuffers.NewBuilder(0)
1332
1333	defer func() {
1334		r := recover()
1335		if r == nil {
1336			fail("expected panic in CheckNotInObjectError")
1337		}
1338	}()
1339	b.EndObject()
1340}
1341
1342// CheckStringIsNestedError verifies that a string can not be created inside
1343// another object.
1344func CheckStringIsNestedError(fail func(string, ...interface{})) {
1345	b := flatbuffers.NewBuilder(0)
1346	b.StartObject(0)
1347	defer func() {
1348		r := recover()
1349		if r == nil {
1350			fail("expected panic in CheckStringIsNestedError")
1351		}
1352	}()
1353	b.CreateString("foo")
1354}
1355
1356// CheckByteStringIsNestedError verifies that a bytestring can not be created
1357// inside another object.
1358func CheckByteStringIsNestedError(fail func(string, ...interface{})) {
1359	b := flatbuffers.NewBuilder(0)
1360	b.StartObject(0)
1361	defer func() {
1362		r := recover()
1363		if r == nil {
1364			fail("expected panic in CheckByteStringIsNestedError")
1365		}
1366	}()
1367	b.CreateByteString([]byte("foo"))
1368}
1369
1370// CheckStructIsNotInlineError verifies that writing a struct in a location
1371// away from where it is used will cause a panic.
1372func CheckStructIsNotInlineError(fail func(string, ...interface{})) {
1373	b := flatbuffers.NewBuilder(0)
1374	b.StartObject(0)
1375	defer func() {
1376		r := recover()
1377		if r == nil {
1378			fail("expected panic in CheckStructIsNotInlineError")
1379		}
1380	}()
1381	b.PrependStructSlot(0, 1, 0)
1382}
1383
1384// CheckFinishedBytesError verifies that `FinishedBytes` panics if the table
1385// is not finished.
1386func CheckFinishedBytesError(fail func(string, ...interface{})) {
1387	b := flatbuffers.NewBuilder(0)
1388
1389	defer func() {
1390		r := recover()
1391		if r == nil {
1392			fail("expected panic in CheckFinishedBytesError")
1393		}
1394	}()
1395	b.FinishedBytes()
1396}
1397
1398// CheckEnumNames checks that the generated enum names are correct.
1399func CheckEnumNames(fail func(string, ...interface{})) {
1400	{
1401		want := map[example.Any]string{
1402			example.AnyNONE:                    "NONE",
1403			example.AnyMonster:                 "Monster",
1404			example.AnyTestSimpleTableWithEnum: "TestSimpleTableWithEnum",
1405			example.AnyMyGame_Example2_Monster: "MyGame_Example2_Monster",
1406		}
1407		got := example.EnumNamesAny
1408		if !reflect.DeepEqual(got, want) {
1409			fail("enum name is not equal")
1410		}
1411	}
1412	{
1413		want := map[example.Color]string{
1414			example.ColorRed:   "Red",
1415			example.ColorGreen: "Green",
1416			example.ColorBlue:  "Blue",
1417		}
1418		got := example.EnumNamesColor
1419		if !reflect.DeepEqual(got, want) {
1420			fail("enum name is not equal")
1421		}
1422	}
1423}
1424
1425// CheckEnumString checks the String method on generated enum types.
1426func CheckEnumString(fail func(string, ...interface{})) {
1427	if got := example.AnyMonster.String(); got != "Monster" {
1428		fail("Monster.String: %q != %q", got, "Monster")
1429	}
1430	if got := fmt.Sprintf("color: %s", example.ColorGreen); got != "color: Green" {
1431		fail("color.String: %q != %q", got, "color: Green")
1432	}
1433}
1434
1435// CheckEnumValues checks that the generated enum values maps are correct.
1436func CheckEnumValues(fail func(string, ...interface{})) {
1437	{
1438		want := map[string]example.Any{
1439			"NONE":                    example.AnyNONE,
1440			"Monster":                 example.AnyMonster,
1441			"TestSimpleTableWithEnum": example.AnyTestSimpleTableWithEnum,
1442			"MyGame_Example2_Monster": example.AnyMyGame_Example2_Monster,
1443		}
1444		got := example.EnumValuesAny
1445		if !reflect.DeepEqual(got, want) {
1446			fail("enum name is not equal")
1447		}
1448	}
1449	{
1450		want := map[string]example.Color{
1451			"Red":   example.ColorRed,
1452			"Green": example.ColorGreen,
1453			"Blue":  example.ColorBlue,
1454		}
1455		got := example.EnumValuesColor
1456		if !reflect.DeepEqual(got, want) {
1457			fail("enum name is not equal")
1458		}
1459	}
1460}
1461
1462// CheckDocExample checks that the code given in FlatBuffers documentation
1463// is syntactically correct.
1464func CheckDocExample(buf []byte, off flatbuffers.UOffsetT, fail func(string, ...interface{})) {
1465	monster := example.GetRootAsMonster(buf, off)
1466	_ = monster.Hp()
1467	_ = monster.Pos(nil)
1468	for i := 0; i < monster.InventoryLength(); i++ {
1469		_ = monster.Inventory(i) // do something here
1470	}
1471
1472	builder := flatbuffers.NewBuilder(0)
1473
1474	example.MonsterStartInventoryVector(builder, 5)
1475	for i := 4; i >= 0; i-- {
1476		builder.PrependByte(byte(i))
1477	}
1478	inv := builder.EndVector(5)
1479
1480	str := builder.CreateString("MyMonster")
1481	example.MonsterStart(builder)
1482	example.MonsterAddPos(builder, example.CreateVec3(builder, 1.0, 2.0, 3.0, 3.0, example.Color(4), 5, 6))
1483	example.MonsterAddHp(builder, 80)
1484	example.MonsterAddName(builder, str)
1485	example.MonsterAddInventory(builder, inv)
1486	example.MonsterAddTestType(builder, 1)
1487	example.MonsterAddColor(builder, example.ColorRed)
1488	// example.MonsterAddTest(builder, mon2)
1489	// example.MonsterAddTest4(builder, test4s)
1490	_ = example.MonsterEnd(builder)
1491}
1492
1493func CheckCreateByteVector(fail func(string, ...interface{})) {
1494	raw := [30]byte{}
1495	for i := 0; i < len(raw); i++ {
1496		raw[i] = byte(i)
1497	}
1498
1499	for size := 0; size < len(raw); size++ {
1500		b1 := flatbuffers.NewBuilder(0)
1501		b2 := flatbuffers.NewBuilder(0)
1502		b1.StartVector(1, size, 1)
1503		for i := size - 1; i >= 0; i-- {
1504			b1.PrependByte(raw[i])
1505		}
1506		b1.EndVector(size)
1507		b2.CreateByteVector(raw[:size])
1508		CheckByteEquality(b1.Bytes, b2.Bytes, fail)
1509	}
1510}
1511
1512func CheckParentNamespace(fail func(string, ...interface{})) {
1513	var empty, nonempty []byte
1514
1515	// create monster with an empty parent namespace field
1516	{
1517		builder := flatbuffers.NewBuilder(0)
1518
1519		example.MonsterStart(builder)
1520		m := example.MonsterEnd(builder)
1521		builder.Finish(m)
1522
1523		empty = make([]byte, len(builder.FinishedBytes()))
1524		copy(empty, builder.FinishedBytes())
1525	}
1526
1527	// create monster with a non-empty parent namespace field
1528	{
1529		builder := flatbuffers.NewBuilder(0)
1530		mygame.InParentNamespaceStart(builder)
1531		pn := mygame.InParentNamespaceEnd(builder)
1532
1533		example.MonsterStart(builder)
1534		example.MonsterAddParentNamespaceTest(builder, pn)
1535		m := example.MonsterEnd(builder)
1536
1537		builder.Finish(m)
1538
1539		nonempty = make([]byte, len(builder.FinishedBytes()))
1540		copy(nonempty, builder.FinishedBytes())
1541	}
1542
1543	// read monster with empty parent namespace field
1544	{
1545		m := example.GetRootAsMonster(empty, 0)
1546		if m.ParentNamespaceTest(nil) != nil {
1547			fail("expected nil ParentNamespaceTest for empty field")
1548		}
1549	}
1550
1551	// read monster with non-empty parent namespace field
1552	{
1553		m := example.GetRootAsMonster(nonempty, 0)
1554		if m.ParentNamespaceTest(nil) == nil {
1555			fail("expected non-nil ParentNamespaceTest for non-empty field")
1556		}
1557	}
1558}
1559
1560// Include simple random number generator to ensure results will be the
1561// same cross platform.
1562// http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator
1563type LCG uint32
1564
1565const InitialLCGSeed = 48271
1566
1567func NewLCG() *LCG {
1568	n := uint32(InitialLCGSeed)
1569	l := LCG(n)
1570	return &l
1571}
1572
1573func (lcg *LCG) Reset() {
1574	*lcg = InitialLCGSeed
1575}
1576
1577func (lcg *LCG) Next() uint32 {
1578	n := uint32((uint64(*lcg) * uint64(279470273)) % uint64(4294967291))
1579	*lcg = LCG(n)
1580	return n
1581}
1582
1583// CheckByteEquality verifies that two byte buffers are the same.
1584func CheckByteEquality(a, b []byte, fail func(string, ...interface{})) {
1585	if !bytes.Equal(a, b) {
1586		fail("objects are not byte-wise equal")
1587	}
1588}
1589
1590// CheckMutateMethods checks all mutate methods one by one
1591func CheckMutateMethods(fail func(string, ...interface{})) {
1592	b := flatbuffers.NewBuilder(0)
1593	b.StartObject(15)
1594	b.PrependBoolSlot(0, true, false)
1595	b.PrependByteSlot(1, 1, 0)
1596	b.PrependUint8Slot(2, 2, 0)
1597	b.PrependUint16Slot(3, 3, 0)
1598	b.PrependUint32Slot(4, 4, 0)
1599	b.PrependUint64Slot(5, 5, 0)
1600	b.PrependInt8Slot(6, 6, 0)
1601	b.PrependInt16Slot(7, 7, 0)
1602	b.PrependInt32Slot(8, 8, 0)
1603	b.PrependInt64Slot(9, 9, 0)
1604	b.PrependFloat32Slot(10, 10, 0)
1605	b.PrependFloat64Slot(11, 11, 0)
1606
1607	b.PrependUOffsetTSlot(12, 12, 0)
1608	uoVal := b.Offset() - 12
1609
1610	b.PrependVOffsetT(13)
1611	b.Slot(13)
1612
1613	b.PrependSOffsetT(14)
1614	b.Slot(14)
1615	soVal := flatbuffers.SOffsetT(b.Offset() - 14)
1616
1617	offset := b.EndObject()
1618
1619	t := &flatbuffers.Table{
1620		Bytes: b.Bytes,
1621		Pos:   flatbuffers.UOffsetT(len(b.Bytes)) - offset,
1622	}
1623
1624	calcVOffsetT := func(slot int) (vtableOffset flatbuffers.VOffsetT) {
1625		return flatbuffers.VOffsetT((flatbuffers.VtableMetadataFields + slot) * flatbuffers.SizeVOffsetT)
1626	}
1627	calcUOffsetT := func(vtableOffset flatbuffers.VOffsetT) (valueOffset flatbuffers.UOffsetT) {
1628		return t.Pos + flatbuffers.UOffsetT(t.Offset(vtableOffset))
1629	}
1630
1631	type testcase struct {
1632		field  string
1633		testfn func() bool
1634	}
1635
1636	testForOriginalValues := []testcase{
1637		testcase{"BoolSlot", func() bool { return t.GetBoolSlot(calcVOffsetT(0), true) == true }},
1638		testcase{"ByteSlot", func() bool { return t.GetByteSlot(calcVOffsetT(1), 1) == 1 }},
1639		testcase{"Uint8Slot", func() bool { return t.GetUint8Slot(calcVOffsetT(2), 2) == 2 }},
1640		testcase{"Uint16Slot", func() bool { return t.GetUint16Slot(calcVOffsetT(3), 3) == 3 }},
1641		testcase{"Uint32Slot", func() bool { return t.GetUint32Slot(calcVOffsetT(4), 4) == 4 }},
1642		testcase{"Uint64Slot", func() bool { return t.GetUint64Slot(calcVOffsetT(5), 5) == 5 }},
1643		testcase{"Int8Slot", func() bool { return t.GetInt8Slot(calcVOffsetT(6), 6) == 6 }},
1644		testcase{"Int16Slot", func() bool { return t.GetInt16Slot(calcVOffsetT(7), 7) == 7 }},
1645		testcase{"Int32Slot", func() bool { return t.GetInt32Slot(calcVOffsetT(8), 8) == 8 }},
1646		testcase{"Int64Slot", func() bool { return t.GetInt64Slot(calcVOffsetT(9), 9) == 9 }},
1647		testcase{"Float32Slot", func() bool { return t.GetFloat32Slot(calcVOffsetT(10), 10) == 10 }},
1648		testcase{"Float64Slot", func() bool { return t.GetFloat64Slot(calcVOffsetT(11), 11) == 11 }},
1649		testcase{"UOffsetTSlot", func() bool { return t.GetUOffsetT(calcUOffsetT(calcVOffsetT(12))) == uoVal }},
1650		testcase{"VOffsetTSlot", func() bool { return t.GetVOffsetT(calcUOffsetT(calcVOffsetT(13))) == 13 }},
1651		testcase{"SOffsetTSlot", func() bool { return t.GetSOffsetT(calcUOffsetT(calcVOffsetT(14))) == soVal }},
1652	}
1653
1654	testMutability := []testcase{
1655		testcase{"BoolSlot", func() bool { return t.MutateBoolSlot(calcVOffsetT(0), false) }},
1656		testcase{"ByteSlot", func() bool { return t.MutateByteSlot(calcVOffsetT(1), 2) }},
1657		testcase{"Uint8Slot", func() bool { return t.MutateUint8Slot(calcVOffsetT(2), 4) }},
1658		testcase{"Uint16Slot", func() bool { return t.MutateUint16Slot(calcVOffsetT(3), 6) }},
1659		testcase{"Uint32Slot", func() bool { return t.MutateUint32Slot(calcVOffsetT(4), 8) }},
1660		testcase{"Uint64Slot", func() bool { return t.MutateUint64Slot(calcVOffsetT(5), 10) }},
1661		testcase{"Int8Slot", func() bool { return t.MutateInt8Slot(calcVOffsetT(6), 12) }},
1662		testcase{"Int16Slot", func() bool { return t.MutateInt16Slot(calcVOffsetT(7), 14) }},
1663		testcase{"Int32Slot", func() bool { return t.MutateInt32Slot(calcVOffsetT(8), 16) }},
1664		testcase{"Int64Slot", func() bool { return t.MutateInt64Slot(calcVOffsetT(9), 18) }},
1665		testcase{"Float32Slot", func() bool { return t.MutateFloat32Slot(calcVOffsetT(10), 20) }},
1666		testcase{"Float64Slot", func() bool { return t.MutateFloat64Slot(calcVOffsetT(11), 22) }},
1667		testcase{"UOffsetTSlot", func() bool { return t.MutateUOffsetT(calcUOffsetT(calcVOffsetT(12)), 24) }},
1668		testcase{"VOffsetTSlot", func() bool { return t.MutateVOffsetT(calcUOffsetT(calcVOffsetT(13)), 26) }},
1669		testcase{"SOffsetTSlot", func() bool { return t.MutateSOffsetT(calcUOffsetT(calcVOffsetT(14)), 28) }},
1670	}
1671
1672	testMutabilityWithoutSlot := []testcase{
1673		testcase{"BoolSlot", func() bool { return t.MutateBoolSlot(calcVOffsetT(16), false) }},
1674		testcase{"ByteSlot", func() bool { return t.MutateByteSlot(calcVOffsetT(16), 2) }},
1675		testcase{"Uint8Slot", func() bool { return t.MutateUint8Slot(calcVOffsetT(16), 2) }},
1676		testcase{"Uint16Slot", func() bool { return t.MutateUint16Slot(calcVOffsetT(16), 2) }},
1677		testcase{"Uint32Slot", func() bool { return t.MutateUint32Slot(calcVOffsetT(16), 2) }},
1678		testcase{"Uint64Slot", func() bool { return t.MutateUint64Slot(calcVOffsetT(16), 2) }},
1679		testcase{"Int8Slot", func() bool { return t.MutateInt8Slot(calcVOffsetT(16), 2) }},
1680		testcase{"Int16Slot", func() bool { return t.MutateInt16Slot(calcVOffsetT(16), 2) }},
1681		testcase{"Int32Slot", func() bool { return t.MutateInt32Slot(calcVOffsetT(16), 2) }},
1682		testcase{"Int64Slot", func() bool { return t.MutateInt64Slot(calcVOffsetT(16), 2) }},
1683		testcase{"Float32Slot", func() bool { return t.MutateFloat32Slot(calcVOffsetT(16), 2) }},
1684		testcase{"Float64Slot", func() bool { return t.MutateFloat64Slot(calcVOffsetT(16), 2) }},
1685	}
1686
1687	testForMutatedValues := []testcase{
1688		testcase{"BoolSlot", func() bool { return t.GetBoolSlot(calcVOffsetT(0), true) == false }},
1689		testcase{"ByteSlot", func() bool { return t.GetByteSlot(calcVOffsetT(1), 1) == 2 }},
1690		testcase{"Uint8Slot", func() bool { return t.GetUint8Slot(calcVOffsetT(2), 1) == 4 }},
1691		testcase{"Uint16Slot", func() bool { return t.GetUint16Slot(calcVOffsetT(3), 1) == 6 }},
1692		testcase{"Uint32Slot", func() bool { return t.GetUint32Slot(calcVOffsetT(4), 1) == 8 }},
1693		testcase{"Uint64Slot", func() bool { return t.GetUint64Slot(calcVOffsetT(5), 1) == 10 }},
1694		testcase{"Int8Slot", func() bool { return t.GetInt8Slot(calcVOffsetT(6), 1) == 12 }},
1695		testcase{"Int16Slot", func() bool { return t.GetInt16Slot(calcVOffsetT(7), 1) == 14 }},
1696		testcase{"Int32Slot", func() bool { return t.GetInt32Slot(calcVOffsetT(8), 1) == 16 }},
1697		testcase{"Int64Slot", func() bool { return t.GetInt64Slot(calcVOffsetT(9), 1) == 18 }},
1698		testcase{"Float32Slot", func() bool { return t.GetFloat32Slot(calcVOffsetT(10), 1) == 20 }},
1699		testcase{"Float64Slot", func() bool { return t.GetFloat64Slot(calcVOffsetT(11), 1) == 22 }},
1700		testcase{"UOffsetTSlot", func() bool { return t.GetUOffsetT(calcUOffsetT(calcVOffsetT(12))) == 24 }},
1701		testcase{"VOffsetTSlot", func() bool { return t.GetVOffsetT(calcUOffsetT(calcVOffsetT(13))) == 26 }},
1702		testcase{"SOffsetTSlot", func() bool { return t.GetSOffsetT(calcUOffsetT(calcVOffsetT(14))) == 28 }},
1703	}
1704
1705	// make sure original values are okay
1706	for _, t := range testForOriginalValues {
1707		if !t.testfn() {
1708			fail(t.field + "' field doesn't have the expected original value")
1709		}
1710	}
1711
1712	// try to mutate fields and check mutability
1713	for _, t := range testMutability {
1714		if !t.testfn() {
1715			fail(FailString(t.field+"' field failed mutability test", "passed", "failed"))
1716		}
1717	}
1718
1719	// try to mutate fields and check mutability
1720	// these have wrong slots so should fail
1721	for _, t := range testMutabilityWithoutSlot {
1722		if t.testfn() {
1723			fail(FailString(t.field+"' field failed no slot mutability test", "failed", "passed"))
1724		}
1725	}
1726
1727	// test whether values have changed
1728	for _, t := range testForMutatedValues {
1729		if !t.testfn() {
1730			fail(t.field + "' field doesn't have the expected mutated value")
1731		}
1732	}
1733}
1734
1735// BenchmarkVtableDeduplication measures the speed of vtable deduplication
1736// by creating prePop vtables, then populating b.N objects with a
1737// different single vtable.
1738//
1739// When b.N is large (as in long benchmarks), memory usage may be high.
1740func BenchmarkVtableDeduplication(b *testing.B) {
1741	prePop := 10
1742	builder := flatbuffers.NewBuilder(0)
1743
1744	// pre-populate some vtables:
1745	for i := 0; i < prePop; i++ {
1746		builder.StartObject(i)
1747		for j := 0; j < i; j++ {
1748			builder.PrependInt16Slot(j, int16(j), 0)
1749		}
1750		builder.EndObject()
1751	}
1752
1753	// benchmark deduplication of a new vtable:
1754	b.ResetTimer()
1755	for i := 0; i < b.N; i++ {
1756		lim := prePop
1757
1758		builder.StartObject(lim)
1759		for j := 0; j < lim; j++ {
1760			builder.PrependInt16Slot(j, int16(j), 0)
1761		}
1762		builder.EndObject()
1763	}
1764}
1765
1766// BenchmarkParseGold measures the speed of parsing the 'gold' data
1767// used throughout this test suite.
1768func BenchmarkParseGold(b *testing.B) {
1769	buf, offset := CheckGeneratedBuild(b.Fatalf)
1770	monster := example.GetRootAsMonster(buf, offset)
1771
1772	// use these to prevent allocations:
1773	reuse_pos := example.Vec3{}
1774	reuse_test3 := example.Test{}
1775	reuse_table2 := flatbuffers.Table{}
1776	reuse_monster2 := example.Monster{}
1777	reuse_test4_0 := example.Test{}
1778	reuse_test4_1 := example.Test{}
1779
1780	b.SetBytes(int64(len(buf[offset:])))
1781	b.ReportAllocs()
1782	b.ResetTimer()
1783	for i := 0; i < b.N; i++ {
1784		monster.Hp()
1785		monster.Mana()
1786		name := monster.Name()
1787		_ = name[0]
1788		_ = name[len(name)-1]
1789
1790		monster.Pos(&reuse_pos)
1791		reuse_pos.X()
1792		reuse_pos.Y()
1793		reuse_pos.Z()
1794		reuse_pos.Test1()
1795		reuse_pos.Test2()
1796		reuse_pos.Test3(&reuse_test3)
1797		reuse_test3.A()
1798		reuse_test3.B()
1799		monster.TestType()
1800		monster.Test(&reuse_table2)
1801		reuse_monster2.Init(reuse_table2.Bytes, reuse_table2.Pos)
1802		name2 := reuse_monster2.Name()
1803		_ = name2[0]
1804		_ = name2[len(name2)-1]
1805		monster.InventoryLength()
1806		l := monster.InventoryLength()
1807		for i := 0; i < l; i++ {
1808			monster.Inventory(i)
1809		}
1810		monster.Test4Length()
1811		monster.Test4(&reuse_test4_0, 0)
1812		monster.Test4(&reuse_test4_1, 1)
1813
1814		reuse_test4_0.A()
1815		reuse_test4_0.B()
1816		reuse_test4_1.A()
1817		reuse_test4_1.B()
1818
1819		monster.TestarrayofstringLength()
1820		str0 := monster.Testarrayofstring(0)
1821		_ = str0[0]
1822		_ = str0[len(str0)-1]
1823		str1 := monster.Testarrayofstring(1)
1824		_ = str1[0]
1825		_ = str1[len(str1)-1]
1826	}
1827}
1828
1829// BenchmarkBuildGold uses generated code to build the example Monster.
1830func BenchmarkBuildGold(b *testing.B) {
1831	buf, offset := CheckGeneratedBuild(b.Fatalf)
1832	bytes_length := int64(len(buf[offset:]))
1833
1834	reuse_str := "MyMonster"
1835	reuse_test1 := "test1"
1836	reuse_test2 := "test2"
1837	reuse_fred := "Fred"
1838
1839	b.SetBytes(bytes_length)
1840	bldr := flatbuffers.NewBuilder(0)
1841	b.ResetTimer()
1842	b.ReportAllocs()
1843	for i := 0; i < b.N; i++ {
1844		bldr.Reset()
1845
1846		str := bldr.CreateString(reuse_str)
1847		test1 := bldr.CreateString(reuse_test1)
1848		test2 := bldr.CreateString(reuse_test2)
1849		fred := bldr.CreateString(reuse_fred)
1850
1851		example.MonsterStartInventoryVector(bldr, 5)
1852		bldr.PrependByte(4)
1853		bldr.PrependByte(3)
1854		bldr.PrependByte(2)
1855		bldr.PrependByte(1)
1856		bldr.PrependByte(0)
1857		inv := bldr.EndVector(5)
1858
1859		example.MonsterStart(bldr)
1860		example.MonsterAddName(bldr, fred)
1861		mon2 := example.MonsterEnd(bldr)
1862
1863		example.MonsterStartTest4Vector(bldr, 2)
1864		example.CreateTest(bldr, 10, 20)
1865		example.CreateTest(bldr, 30, 40)
1866		test4 := bldr.EndVector(2)
1867
1868		example.MonsterStartTestarrayofstringVector(bldr, 2)
1869		bldr.PrependUOffsetT(test2)
1870		bldr.PrependUOffsetT(test1)
1871		testArrayOfString := bldr.EndVector(2)
1872
1873		example.MonsterStart(bldr)
1874
1875		pos := example.CreateVec3(bldr, 1.0, 2.0, 3.0, 3.0, example.ColorGreen, 5, 6)
1876		example.MonsterAddPos(bldr, pos)
1877
1878		example.MonsterAddHp(bldr, 80)
1879		example.MonsterAddName(bldr, str)
1880		example.MonsterAddInventory(bldr, inv)
1881		example.MonsterAddTestType(bldr, 1)
1882		example.MonsterAddTest(bldr, mon2)
1883		example.MonsterAddTest4(bldr, test4)
1884		example.MonsterAddTestarrayofstring(bldr, testArrayOfString)
1885		mon := example.MonsterEnd(bldr)
1886
1887		bldr.Finish(mon)
1888	}
1889}
1890