mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-22 22:28:53 +00:00
Port FlatBuffers to Go.
Implement code generation and runtime library for Go, derived from the Java implementation. Additionally, the test suite verifies: - the exact bytes in the Builder buffer during object construction, - vtable deduplication, and - table construction, via a fuzzer derived from the C++ implementation. Change-Id: Ib95a019c684891def2b50281e570b4843fea7baa
This commit is contained in:
committed by
Wouter van Oortmerssen
parent
3fb6a86d02
commit
74d5f3701f
54
tests/GoTest.sh
Executable file
54
tests/GoTest.sh
Executable file
@@ -0,0 +1,54 @@
|
||||
#!/bin/bash -eu
|
||||
# Copyright 2014 Google Inc. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
pushd "$(dirname $0)" >/dev/null
|
||||
test_dir="$(pwd)"
|
||||
go_path=${test_dir}/go_gen
|
||||
go_src=${go_path}/src
|
||||
|
||||
# Emit Go code for the example schema in the test dir:
|
||||
../flatc -g monster_test.fbs
|
||||
|
||||
# Go requires a particular layout of files in order to link multiple packages.
|
||||
# Copy flatbuffer Go files to their own package directories to compile the
|
||||
# test binary:
|
||||
mkdir -p ${go_src}/MyGame/Example
|
||||
mkdir -p ${go_src}/github.com/google/flatbuffers/go
|
||||
mkdir -p ${go_src}/flatbuffers_test
|
||||
|
||||
cp -u MyGame/Example/*.go ./go_gen/src/MyGame/Example/
|
||||
cp -u ../go/* ./go_gen/src/github.com/google/flatbuffers/go
|
||||
cp -u ./go_test.go ./go_gen/src/flatbuffers_test/
|
||||
|
||||
# Run tests with necessary flags.
|
||||
# Developers may wish to see more detail by appending the verbosity flag
|
||||
# -test.v to arguments for this command, as in:
|
||||
# go -test -test.v ...
|
||||
# Developers may also wish to run benchmarks, which may be achieved with the
|
||||
# flag -test.bench and the wildcard regexp ".":
|
||||
# go -test -test.bench=. ...
|
||||
GOPATH=${go_path} go test flatbuffers_test \
|
||||
--test.coverpkg=github.com/google/flatbuffers/go \
|
||||
--cpp_data=${test_dir}/monsterdata_test.bin \
|
||||
--java_data=${test_dir}/monsterdata_java_wire.bin \
|
||||
--out_data=${test_dir}/monsterdata_go_wire.bin \
|
||||
--fuzz=true \
|
||||
--super_fuzz=false \
|
||||
--fuzz_fields=4 \
|
||||
--fuzz_objects=10000
|
||||
|
||||
rm -rf ./go_gen/{pkg,src}
|
||||
|
||||
echo "OK: Go tests passed."
|
||||
8
tests/MyGame/Example/Any.go
Normal file
8
tests/MyGame/Example/Any.go
Normal file
@@ -0,0 +1,8 @@
|
||||
// automatically generated, do not modify
|
||||
|
||||
package Example
|
||||
|
||||
const (
|
||||
AnyNONE = 0
|
||||
AnyMonster = 1
|
||||
)
|
||||
9
tests/MyGame/Example/Color.go
Normal file
9
tests/MyGame/Example/Color.go
Normal file
@@ -0,0 +1,9 @@
|
||||
// automatically generated, do not modify
|
||||
|
||||
package Example
|
||||
|
||||
const (
|
||||
ColorRed = 0
|
||||
ColorGreen = 1
|
||||
ColorBlue = 2
|
||||
)
|
||||
196
tests/MyGame/Example/Monster.go
Normal file
196
tests/MyGame/Example/Monster.go
Normal file
@@ -0,0 +1,196 @@
|
||||
// automatically generated, do not modify
|
||||
|
||||
package Example
|
||||
|
||||
import (
|
||||
flatbuffers "github.com/google/flatbuffers/go"
|
||||
)
|
||||
type Monster struct {
|
||||
_tab flatbuffers.Table
|
||||
}
|
||||
|
||||
func GetRootAsMonster(buf []byte, offset flatbuffers.UOffsetT) *Monster {
|
||||
n := flatbuffers.GetUOffsetT(buf[offset:])
|
||||
x := &Monster{}
|
||||
x.Init(buf, n + offset)
|
||||
return x
|
||||
}
|
||||
|
||||
func (rcv *Monster) Init(buf []byte, i flatbuffers.UOffsetT) {
|
||||
rcv._tab.Bytes = buf
|
||||
rcv._tab.Pos = i
|
||||
}
|
||||
|
||||
func (rcv *Monster) Pos(obj *Vec3) *Vec3 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
x := o + rcv._tab.Pos
|
||||
if obj == nil {
|
||||
obj = new(Vec3)
|
||||
}
|
||||
obj.Init(rcv._tab.Bytes, x)
|
||||
return obj
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *Monster) Mana() int16 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetInt16(o + rcv._tab.Pos)
|
||||
}
|
||||
return 150
|
||||
}
|
||||
|
||||
func (rcv *Monster) Hp() int16 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetInt16(o + rcv._tab.Pos)
|
||||
}
|
||||
return 100
|
||||
}
|
||||
|
||||
func (rcv *Monster) Name() string {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(10))
|
||||
if o != 0 {
|
||||
return rcv._tab.String(o)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (rcv *Monster) Inventory(j int) byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(14))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
return rcv._tab.GetByte(a + flatbuffers.UOffsetT(j * 1))
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *Monster) InventoryLength() int {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(14))
|
||||
if o != 0 {
|
||||
return rcv._tab.VectorLen(o)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *Monster) Color() int8 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(16))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetInt8(o + rcv._tab.Pos)
|
||||
}
|
||||
return 2
|
||||
}
|
||||
|
||||
func (rcv *Monster) TestType() byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(18))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetByte(o + rcv._tab.Pos)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *Monster) Test(obj *flatbuffers.Table) bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(20))
|
||||
if o != 0 {
|
||||
rcv._tab.Union(obj, o)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (rcv *Monster) Test4(obj *Test, j int) bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(22))
|
||||
if o != 0 {
|
||||
x := rcv._tab.Vector(o)
|
||||
x += flatbuffers.UOffsetT(j) * 4
|
||||
if obj == nil {
|
||||
obj = new(Test)
|
||||
}
|
||||
obj.Init(rcv._tab.Bytes, x)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (rcv *Monster) Test4Length() int {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(22))
|
||||
if o != 0 {
|
||||
return rcv._tab.VectorLen(o)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *Monster) Testarrayofstring(j int) string {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(24))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
return rcv._tab.String(a + flatbuffers.UOffsetT(j * 4))
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (rcv *Monster) TestarrayofstringLength() int {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(24))
|
||||
if o != 0 {
|
||||
return rcv._tab.VectorLen(o)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
/// an example documentation comment: this will end up in the generated code multiline too
|
||||
func (rcv *Monster) Testarrayoftables(obj *Monster, j int) bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(26))
|
||||
if o != 0 {
|
||||
x := rcv._tab.Vector(o)
|
||||
x += flatbuffers.UOffsetT(j) * 4
|
||||
x = rcv._tab.Indirect(x)
|
||||
if obj == nil {
|
||||
obj = new(Monster)
|
||||
}
|
||||
obj.Init(rcv._tab.Bytes, x)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (rcv *Monster) TestarrayoftablesLength() int {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(26))
|
||||
if o != 0 {
|
||||
return rcv._tab.VectorLen(o)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *Monster) Enemy(obj *Monster) *Monster {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(28))
|
||||
if o != 0 {
|
||||
x := rcv._tab.Indirect(o + rcv._tab.Pos)
|
||||
if obj == nil {
|
||||
obj = new(Monster)
|
||||
}
|
||||
obj.Init(rcv._tab.Bytes, x)
|
||||
return obj
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func MonsterStart(builder *flatbuffers.Builder) { builder.StartObject(13) }
|
||||
func MonsterAddPos(builder *flatbuffers.Builder, pos flatbuffers.UOffsetT) { builder.PrependStructSlot(0, flatbuffers.UOffsetT(pos), 0) }
|
||||
func MonsterAddMana(builder *flatbuffers.Builder, mana int16) { builder.PrependInt16Slot(1, mana, 150) }
|
||||
func MonsterAddHp(builder *flatbuffers.Builder, hp int16) { builder.PrependInt16Slot(2, hp, 100) }
|
||||
func MonsterAddName(builder *flatbuffers.Builder, name flatbuffers.UOffsetT) { builder.PrependUOffsetTSlot(3, flatbuffers.UOffsetT(name), 0) }
|
||||
func MonsterAddInventory(builder *flatbuffers.Builder, inventory flatbuffers.UOffsetT) { builder.PrependUOffsetTSlot(5, flatbuffers.UOffsetT(inventory), 0) }
|
||||
func MonsterStartInventoryVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT { return builder.StartVector(1, numElems) }
|
||||
func MonsterAddColor(builder *flatbuffers.Builder, color int8) { builder.PrependInt8Slot(6, color, 2) }
|
||||
func MonsterAddTestType(builder *flatbuffers.Builder, testType byte) { builder.PrependByteSlot(7, testType, 0) }
|
||||
func MonsterAddTest(builder *flatbuffers.Builder, test flatbuffers.UOffsetT) { builder.PrependUOffsetTSlot(8, flatbuffers.UOffsetT(test), 0) }
|
||||
func MonsterAddTest4(builder *flatbuffers.Builder, test4 flatbuffers.UOffsetT) { builder.PrependUOffsetTSlot(9, flatbuffers.UOffsetT(test4), 0) }
|
||||
func MonsterStartTest4Vector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT { return builder.StartVector(4, numElems) }
|
||||
func MonsterAddTestarrayofstring(builder *flatbuffers.Builder, testarrayofstring flatbuffers.UOffsetT) { builder.PrependUOffsetTSlot(10, flatbuffers.UOffsetT(testarrayofstring), 0) }
|
||||
func MonsterStartTestarrayofstringVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT { return builder.StartVector(4, numElems) }
|
||||
func MonsterAddTestarrayoftables(builder *flatbuffers.Builder, testarrayoftables flatbuffers.UOffsetT) { builder.PrependUOffsetTSlot(11, flatbuffers.UOffsetT(testarrayoftables), 0) }
|
||||
func MonsterStartTestarrayoftablesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT { return builder.StartVector(4, numElems) }
|
||||
func MonsterAddEnemy(builder *flatbuffers.Builder, enemy flatbuffers.UOffsetT) { builder.PrependUOffsetTSlot(12, flatbuffers.UOffsetT(enemy), 0) }
|
||||
func MonsterEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT { return builder.EndObject() }
|
||||
26
tests/MyGame/Example/Test.go
Normal file
26
tests/MyGame/Example/Test.go
Normal file
@@ -0,0 +1,26 @@
|
||||
// automatically generated, do not modify
|
||||
|
||||
package Example
|
||||
|
||||
import (
|
||||
flatbuffers "github.com/google/flatbuffers/go"
|
||||
)
|
||||
type Test struct {
|
||||
_tab flatbuffers.Struct
|
||||
}
|
||||
|
||||
func (rcv *Test) Init(buf []byte, i flatbuffers.UOffsetT) {
|
||||
rcv._tab.Bytes = buf
|
||||
rcv._tab.Pos = i
|
||||
}
|
||||
|
||||
func (rcv *Test) A() int16 { return rcv._tab.GetInt16(rcv._tab.Pos + flatbuffers.UOffsetT(0)) }
|
||||
func (rcv *Test) B() int8 { return rcv._tab.GetInt8(rcv._tab.Pos + flatbuffers.UOffsetT(2)) }
|
||||
|
||||
func CreateTest(builder *flatbuffers.Builder, a int16, b int8) flatbuffers.UOffsetT {
|
||||
builder.Prep(2, 4)
|
||||
builder.Pad(1)
|
||||
builder.PrependInt8(b)
|
||||
builder.PrependInt16(a)
|
||||
return builder.Offset()
|
||||
}
|
||||
45
tests/MyGame/Example/Vec3.go
Normal file
45
tests/MyGame/Example/Vec3.go
Normal file
@@ -0,0 +1,45 @@
|
||||
// automatically generated, do not modify
|
||||
|
||||
package Example
|
||||
|
||||
import (
|
||||
flatbuffers "github.com/google/flatbuffers/go"
|
||||
)
|
||||
type Vec3 struct {
|
||||
_tab flatbuffers.Struct
|
||||
}
|
||||
|
||||
func (rcv *Vec3) Init(buf []byte, i flatbuffers.UOffsetT) {
|
||||
rcv._tab.Bytes = buf
|
||||
rcv._tab.Pos = i
|
||||
}
|
||||
|
||||
func (rcv *Vec3) X() float32 { return rcv._tab.GetFloat32(rcv._tab.Pos + flatbuffers.UOffsetT(0)) }
|
||||
func (rcv *Vec3) Y() float32 { return rcv._tab.GetFloat32(rcv._tab.Pos + flatbuffers.UOffsetT(4)) }
|
||||
func (rcv *Vec3) Z() float32 { return rcv._tab.GetFloat32(rcv._tab.Pos + flatbuffers.UOffsetT(8)) }
|
||||
func (rcv *Vec3) Test1() float64 { return rcv._tab.GetFloat64(rcv._tab.Pos + flatbuffers.UOffsetT(16)) }
|
||||
func (rcv *Vec3) Test2() int8 { return rcv._tab.GetInt8(rcv._tab.Pos + flatbuffers.UOffsetT(24)) }
|
||||
func (rcv *Vec3) Test3(obj *Test) *Test {
|
||||
if obj == nil {
|
||||
obj = new(Test)
|
||||
}
|
||||
obj.Init(rcv._tab.Bytes, rcv._tab.Pos + 26)
|
||||
return obj
|
||||
}
|
||||
|
||||
func CreateVec3(builder *flatbuffers.Builder, x float32, y float32, z float32, test1 float64, test2 int8, Test_a int16, Test_b int8) flatbuffers.UOffsetT {
|
||||
builder.Prep(16, 32)
|
||||
builder.Pad(2)
|
||||
builder.Prep(2, 4)
|
||||
builder.Pad(1)
|
||||
builder.PrependInt8(Test_b)
|
||||
builder.PrependInt16(Test_a)
|
||||
builder.Pad(1)
|
||||
builder.PrependInt8(test2)
|
||||
builder.PrependFloat64(test1)
|
||||
builder.Pad(4)
|
||||
builder.PrependFloat32(z)
|
||||
builder.PrependFloat32(y)
|
||||
builder.PrependFloat32(x)
|
||||
return builder.Offset()
|
||||
}
|
||||
1096
tests/go_test.go
Normal file
1096
tests/go_test.go
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user