[golang] Add support for text parsing with json struct tags (#7353)

* [golang] Add support for text parsing with json struct tags

Add struct tags to Go native structs generated when object API is used.

This allows to use the same JSON file as for C++ text
parsing(i.e. snake_case vs CamelCase) and thus enabling text parsing
for Go(when using object API).

* [golang] Add test for text parsing

Added small test to check and demonstrate text parsing in Go.
Also, ran clang-format on cpp file changes.
This commit is contained in:
Andrei Burdulescu
2022-08-08 21:30:06 +03:00
committed by GitHub
parent ee2ced236d
commit c793621567
13 changed files with 151 additions and 120 deletions

View File

@@ -842,7 +842,8 @@ class GoGenerator : public BaseGenerator {
continue; continue;
code += "\t" + namer_.Field(field) + " "; code += "\t" + namer_.Field(field) + " ";
if (field.IsScalarOptional()) { code += "*"; } if (field.IsScalarOptional()) { code += "*"; }
code += NativeType(field.value.type) + "\n"; code += NativeType(field.value.type) + " `json:\"" + field.name + "\"`" +
"\n";
} }
code += "}\n\n"; code += "}\n\n";

View File

@@ -7,8 +7,8 @@ import (
) )
type AbilityT struct { type AbilityT struct {
Id uint32 Id uint32 `json:"id"`
Distance uint32 Distance uint32 `json:"distance"`
} }
func (t *AbilityT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT { func (t *AbilityT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {

View File

@@ -10,56 +10,56 @@ import (
/// an example documentation comment: "monster object" /// an example documentation comment: "monster object"
type MonsterT struct { type MonsterT struct {
Pos *Vec3T Pos *Vec3T `json:"pos"`
Mana int16 Mana int16 `json:"mana"`
Hp int16 Hp int16 `json:"hp"`
Name string Name string `json:"name"`
Inventory []byte Inventory []byte `json:"inventory"`
Color Color Color Color `json:"color"`
Test *AnyT Test *AnyT `json:"test"`
Test4 []*TestT Test4 []*TestT `json:"test4"`
Testarrayofstring []string Testarrayofstring []string `json:"testarrayofstring"`
Testarrayoftables []*MonsterT Testarrayoftables []*MonsterT `json:"testarrayoftables"`
Enemy *MonsterT Enemy *MonsterT `json:"enemy"`
Testnestedflatbuffer []byte Testnestedflatbuffer []byte `json:"testnestedflatbuffer"`
Testempty *StatT Testempty *StatT `json:"testempty"`
Testbool bool Testbool bool `json:"testbool"`
Testhashs32Fnv1 int32 Testhashs32Fnv1 int32 `json:"testhashs32_fnv1"`
Testhashu32Fnv1 uint32 Testhashu32Fnv1 uint32 `json:"testhashu32_fnv1"`
Testhashs64Fnv1 int64 Testhashs64Fnv1 int64 `json:"testhashs64_fnv1"`
Testhashu64Fnv1 uint64 Testhashu64Fnv1 uint64 `json:"testhashu64_fnv1"`
Testhashs32Fnv1a int32 Testhashs32Fnv1a int32 `json:"testhashs32_fnv1a"`
Testhashu32Fnv1a uint32 Testhashu32Fnv1a uint32 `json:"testhashu32_fnv1a"`
Testhashs64Fnv1a int64 Testhashs64Fnv1a int64 `json:"testhashs64_fnv1a"`
Testhashu64Fnv1a uint64 Testhashu64Fnv1a uint64 `json:"testhashu64_fnv1a"`
Testarrayofbools []bool Testarrayofbools []bool `json:"testarrayofbools"`
Testf float32 Testf float32 `json:"testf"`
Testf2 float32 Testf2 float32 `json:"testf2"`
Testf3 float32 Testf3 float32 `json:"testf3"`
Testarrayofstring2 []string Testarrayofstring2 []string `json:"testarrayofstring2"`
Testarrayofsortedstruct []*AbilityT Testarrayofsortedstruct []*AbilityT `json:"testarrayofsortedstruct"`
Flex []byte Flex []byte `json:"flex"`
Test5 []*TestT Test5 []*TestT `json:"test5"`
VectorOfLongs []int64 VectorOfLongs []int64 `json:"vector_of_longs"`
VectorOfDoubles []float64 VectorOfDoubles []float64 `json:"vector_of_doubles"`
ParentNamespaceTest *MyGame.InParentNamespaceT ParentNamespaceTest *MyGame.InParentNamespaceT `json:"parent_namespace_test"`
VectorOfReferrables []*ReferrableT VectorOfReferrables []*ReferrableT `json:"vector_of_referrables"`
SingleWeakReference uint64 SingleWeakReference uint64 `json:"single_weak_reference"`
VectorOfWeakReferences []uint64 VectorOfWeakReferences []uint64 `json:"vector_of_weak_references"`
VectorOfStrongReferrables []*ReferrableT VectorOfStrongReferrables []*ReferrableT `json:"vector_of_strong_referrables"`
CoOwningReference uint64 CoOwningReference uint64 `json:"co_owning_reference"`
VectorOfCoOwningReferences []uint64 VectorOfCoOwningReferences []uint64 `json:"vector_of_co_owning_references"`
NonOwningReference uint64 NonOwningReference uint64 `json:"non_owning_reference"`
VectorOfNonOwningReferences []uint64 VectorOfNonOwningReferences []uint64 `json:"vector_of_non_owning_references"`
AnyUnique *AnyUniqueAliasesT AnyUnique *AnyUniqueAliasesT `json:"any_unique"`
AnyAmbiguous *AnyAmbiguousAliasesT AnyAmbiguous *AnyAmbiguousAliasesT `json:"any_ambiguous"`
VectorOfEnums []Color VectorOfEnums []Color `json:"vector_of_enums"`
SignedEnum Race SignedEnum Race `json:"signed_enum"`
Testrequirednestedflatbuffer []byte Testrequirednestedflatbuffer []byte `json:"testrequirednestedflatbuffer"`
ScalarKeySortedTables []*StatT ScalarKeySortedTables []*StatT `json:"scalar_key_sorted_tables"`
NativeInline *TestT NativeInline *TestT `json:"native_inline"`
LongEnumNonEnumDefault LongEnum LongEnumNonEnumDefault LongEnum `json:"long_enum_non_enum_default"`
LongEnumNormalDefault LongEnum LongEnumNormalDefault LongEnum `json:"long_enum_normal_default"`
} }
func (t *MonsterT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT { func (t *MonsterT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {

View File

@@ -7,7 +7,7 @@ import (
) )
type ReferrableT struct { type ReferrableT struct {
Id uint64 Id uint64 `json:"id"`
} }
func (t *ReferrableT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT { func (t *ReferrableT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {

View File

@@ -7,9 +7,9 @@ import (
) )
type StatT struct { type StatT struct {
Id string Id string `json:"id"`
Val int64 Val int64 `json:"val"`
Count uint16 Count uint16 `json:"count"`
} }
func (t *StatT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT { func (t *StatT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {

View File

@@ -7,9 +7,9 @@ import (
) )
type StructOfStructsT struct { type StructOfStructsT struct {
A *AbilityT A *AbilityT `json:"a"`
B *TestT B *TestT `json:"b"`
C *AbilityT C *AbilityT `json:"c"`
} }
func (t *StructOfStructsT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT { func (t *StructOfStructsT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {

View File

@@ -7,7 +7,7 @@ import (
) )
type StructOfStructsOfStructsT struct { type StructOfStructsOfStructsT struct {
A *StructOfStructsT A *StructOfStructsT `json:"a"`
} }
func (t *StructOfStructsOfStructsT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT { func (t *StructOfStructsOfStructsT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {

View File

@@ -7,8 +7,8 @@ import (
) )
type TestT struct { type TestT struct {
A int16 A int16 `json:"a"`
B int8 B int8 `json:"b"`
} }
func (t *TestT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT { func (t *TestT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {

View File

@@ -7,7 +7,7 @@ import (
) )
type TestSimpleTableWithEnumT struct { type TestSimpleTableWithEnumT struct {
Color Color Color Color `json:"color"`
} }
func (t *TestSimpleTableWithEnumT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT { func (t *TestSimpleTableWithEnumT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {

View File

@@ -7,18 +7,18 @@ import (
) )
type TypeAliasesT struct { type TypeAliasesT struct {
I8 int8 I8 int8 `json:"i8"`
U8 byte U8 byte `json:"u8"`
I16 int16 I16 int16 `json:"i16"`
U16 uint16 U16 uint16 `json:"u16"`
I32 int32 I32 int32 `json:"i32"`
U32 uint32 U32 uint32 `json:"u32"`
I64 int64 I64 int64 `json:"i64"`
U64 uint64 U64 uint64 `json:"u64"`
F32 float32 F32 float32 `json:"f32"`
F64 float64 F64 float64 `json:"f64"`
V8 []int8 V8 []int8 `json:"v8"`
Vf64 []float64 Vf64 []float64 `json:"vf64"`
} }
func (t *TypeAliasesT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT { func (t *TypeAliasesT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {

View File

@@ -7,12 +7,12 @@ import (
) )
type Vec3T struct { type Vec3T struct {
X float32 X float32 `json:"x"`
Y float32 Y float32 `json:"y"`
Z float32 Z float32 `json:"z"`
Test1 float64 Test1 float64 `json:"test1"`
Test2 Color Test2 Color `json:"test2"`
Test3 *TestT Test3 *TestT `json:"test3"`
} }
func (t *Vec3T) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT { func (t *Vec3T) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {

View File

@@ -17,8 +17,9 @@
package main package main
import ( import (
mygame "MyGame" // refers to generated code mygame "MyGame" // refers to generated code
example "MyGame/Example" // refers to generated code example "MyGame/Example" // refers to generated code
"encoding/json"
optional_scalars "optional_scalars" // refers to generated code optional_scalars "optional_scalars" // refers to generated code
"bytes" "bytes"
@@ -68,6 +69,35 @@ func TestMain(m *testing.M) {
os.Exit(m.Run()) os.Exit(m.Run())
} }
// TestTextParsing test if text parsing works with object API.
func TestTextParsing(t *testing.T) {
expectedMonster := example.MonsterT{
Mana: 42,
Name: "foo",
LongEnumNormalDefault: example.LongEnumLongTwo,
}
buf := new(bytes.Buffer)
if err := json.NewEncoder(buf).Encode(expectedMonster); err != nil {
t.Fatal(err)
}
var monster example.MonsterT
if err := json.NewDecoder(buf).Decode(&monster); err != nil {
t.Fatal(err)
}
if monster.Mana != expectedMonster.Mana {
t.Fatal("wrong mana:", monster.Mana)
}
if monster.Name != expectedMonster.Name {
t.Fatal("wrong name:", monster.Name)
}
if monster.LongEnumNormalDefault != expectedMonster.LongEnumNormalDefault {
t.Fatal("wrong enum:", monster.LongEnumNormalDefault)
}
}
// TestAll runs all checks, failing if any errors occur. // TestAll runs all checks, failing if any errors occur.
func TestAll(t *testing.T) { func TestAll(t *testing.T) {
// Verify that the Go FlatBuffers runtime library generates the // Verify that the Go FlatBuffers runtime library generates the

View File

@@ -7,42 +7,42 @@ import (
) )
type ScalarStuffT struct { type ScalarStuffT struct {
JustI8 int8 JustI8 int8 `json:"just_i8"`
MaybeI8 *int8 MaybeI8 *int8 `json:"maybe_i8"`
DefaultI8 int8 DefaultI8 int8 `json:"default_i8"`
JustU8 byte JustU8 byte `json:"just_u8"`
MaybeU8 *byte MaybeU8 *byte `json:"maybe_u8"`
DefaultU8 byte DefaultU8 byte `json:"default_u8"`
JustI16 int16 JustI16 int16 `json:"just_i16"`
MaybeI16 *int16 MaybeI16 *int16 `json:"maybe_i16"`
DefaultI16 int16 DefaultI16 int16 `json:"default_i16"`
JustU16 uint16 JustU16 uint16 `json:"just_u16"`
MaybeU16 *uint16 MaybeU16 *uint16 `json:"maybe_u16"`
DefaultU16 uint16 DefaultU16 uint16 `json:"default_u16"`
JustI32 int32 JustI32 int32 `json:"just_i32"`
MaybeI32 *int32 MaybeI32 *int32 `json:"maybe_i32"`
DefaultI32 int32 DefaultI32 int32 `json:"default_i32"`
JustU32 uint32 JustU32 uint32 `json:"just_u32"`
MaybeU32 *uint32 MaybeU32 *uint32 `json:"maybe_u32"`
DefaultU32 uint32 DefaultU32 uint32 `json:"default_u32"`
JustI64 int64 JustI64 int64 `json:"just_i64"`
MaybeI64 *int64 MaybeI64 *int64 `json:"maybe_i64"`
DefaultI64 int64 DefaultI64 int64 `json:"default_i64"`
JustU64 uint64 JustU64 uint64 `json:"just_u64"`
MaybeU64 *uint64 MaybeU64 *uint64 `json:"maybe_u64"`
DefaultU64 uint64 DefaultU64 uint64 `json:"default_u64"`
JustF32 float32 JustF32 float32 `json:"just_f32"`
MaybeF32 *float32 MaybeF32 *float32 `json:"maybe_f32"`
DefaultF32 float32 DefaultF32 float32 `json:"default_f32"`
JustF64 float64 JustF64 float64 `json:"just_f64"`
MaybeF64 *float64 MaybeF64 *float64 `json:"maybe_f64"`
DefaultF64 float64 DefaultF64 float64 `json:"default_f64"`
JustBool bool JustBool bool `json:"just_bool"`
MaybeBool *bool MaybeBool *bool `json:"maybe_bool"`
DefaultBool bool DefaultBool bool `json:"default_bool"`
JustEnum OptionalByte JustEnum OptionalByte `json:"just_enum"`
MaybeEnum *OptionalByte MaybeEnum *OptionalByte `json:"maybe_enum"`
DefaultEnum OptionalByte DefaultEnum OptionalByte `json:"default_enum"`
} }
func (t *ScalarStuffT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT { func (t *ScalarStuffT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {