From 32254b7acdad8a0bd07f4f8348953b855e9b65c6 Mon Sep 17 00:00:00 2001 From: iceboy Date: Thu, 31 Oct 2019 11:13:45 -0700 Subject: [PATCH] [Go] Object API support (#5339) * start * works for current usages! * unpack: vector of struct * optimize byte slice * support nested struct * support null table * support struct * support union * update generated code * grumble * fix compiler warning * update generated code * wrap type in namespace * bug * wrap in namespace * enum byte arrays * generate struct for unions * basic testing * remove branching * fix assert * pack vector of fixed structs correctly * omit null vectors * Refactor Union Pack and UnPack methods Remove append usage to increase code efficiency when dealing with large vectors * generate goldens --- src/idl_gen_go.cpp | 373 +++++++++++++++- tests/GoTest.sh | 2 +- tests/MyGame/Example/Ability.go | 17 + tests/MyGame/Example/Any.go | 43 +- tests/MyGame/Example/AnyAmbiguousAliases.go | 41 +- tests/MyGame/Example/AnyUniqueAliases.go | 43 +- tests/MyGame/Example/Monster.go | 418 ++++++++++++++++++ tests/MyGame/Example/Referrable.go | 18 + tests/MyGame/Example/Stat.go | 25 ++ tests/MyGame/Example/Test.go | 17 + .../MyGame/Example/TestSimpleTableWithEnum.go | 18 + tests/MyGame/Example/TypeAliases.go | 77 ++++ tests/MyGame/Example/Vec3.go | 25 ++ tests/MyGame/Example2/Monster.go | 15 + tests/MyGame/InParentNamespace.go | 15 + tests/go_test.go | 22 + 16 files changed, 1160 insertions(+), 9 deletions(-) diff --git a/src/idl_gen_go.cpp b/src/idl_gen_go.cpp index 5e62b6170..b092e5eab 100644 --- a/src/idl_gen_go.cpp +++ b/src/idl_gen_go.cpp @@ -75,15 +75,23 @@ class GoGenerator : public BaseGenerator { bool generate() { std::string one_file_code; + bool needs_imports = false; for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end(); ++it) { tracked_imported_namespaces_.clear(); + needs_imports = false; std::string enumcode; + if ((*it)->is_union && parser_.opts.generate_object_based_api) { + GenNativeUnion(**it, &enumcode); + GenNativeUnionPack(**it, &enumcode); + GenNativeUnionUnPack(**it, &enumcode); + needs_imports = true; + } GenEnum(**it, &enumcode); if (parser_.opts.one_file) { one_file_code += enumcode; } else { - if (!SaveType(**it, enumcode, false, true)) return false; + if (!SaveType(**it, enumcode, needs_imports, true)) return false; } } @@ -644,7 +652,7 @@ class GoGenerator : public BaseGenerator { } } - // Mutate the value of a struct's scalar. + // Mutate the value of a struct's scalar. void MutateScalarFieldOfStruct(const StructDef &struct_def, const FieldDef &field, std::string *code_ptr) { @@ -739,6 +747,9 @@ class GoGenerator : public BaseGenerator { cur_name_space_ = struct_def.defined_namespace; GenComment(struct_def.doc_comment, code_ptr, nullptr); + if (parser_.opts.generate_object_based_api) { + GenNativeStruct(struct_def, code_ptr); + } BeginClass(struct_def, code_ptr); if (!struct_def.fixed) { // Generate a special accessor for the table that has been declared as @@ -771,6 +782,326 @@ class GoGenerator : public BaseGenerator { } } + void GenNativeStruct(const StructDef &struct_def, std::string *code_ptr) { + std::string &code = *code_ptr; + + code += "type " + NativeName(struct_def) + " struct {\n"; + for (auto it = struct_def.fields.vec.begin(); + it != struct_def.fields.vec.end(); ++it) { + const FieldDef &field = **it; + if (field.deprecated) continue; + if (IsScalar(field.value.type.base_type) && + field.value.type.enum_def != nullptr && + field.value.type.enum_def->is_union) + continue; + code += "\t" + MakeCamel(field.name) + " " + + NativeType(field.value.type) + "\n"; + } + code += "}\n\n"; + + if (!struct_def.fixed) { + GenNativeTablePack(struct_def, code_ptr); + GenNativeTableUnPack(struct_def, code_ptr); + } else { + GenNativeStructPack(struct_def, code_ptr); + GenNativeStructUnPack(struct_def, code_ptr); + } + } + + void GenNativeUnion(const EnumDef &enum_def, std::string *code_ptr) { + std::string &code = *code_ptr; + code += "type " + NativeName(enum_def) + " struct {\n"; + code += "\tType " + enum_def.name + "\n"; + code += "\tValue interface{}\n"; + code += "}\n\n"; + } + + void GenNativeUnionPack(const EnumDef &enum_def, std::string *code_ptr) { + std::string &code = *code_ptr; + code += "func " + enum_def.name + "Pack(builder *flatbuffers.Builder, t *" + + NativeName(enum_def) + ") flatbuffers.UOffsetT {\n"; + code += "\tif t == nil {\n\t\treturn 0\n\t}\n"; + + code += "\tswitch t.Type {\n"; + for (auto it2 = enum_def.Vals().begin(); it2 != enum_def.Vals().end(); + ++it2) { + const EnumVal &ev = **it2; + if (ev.IsZero()) continue; + code += "\tcase " + enum_def.name + ev.name + ":\n"; + code += "\t\treturn " + + WrapInNameSpaceAndTrack(*ev.union_type.struct_def) + + "Pack(builder, t.Value.(" + NativeType(ev.union_type) + "))\n"; + } + code += "\t}\n"; + code += "\treturn 0\n"; + code += "}\n\n"; + } + + void GenNativeUnionUnPack(const EnumDef &enum_def, std::string *code_ptr) { + std::string &code = *code_ptr; + + code += "func " + enum_def.name + "UnPack(t " + enum_def.name + + ", table flatbuffers.Table) *" + NativeName(enum_def) + " {\n"; + code += "\tswitch t {\n"; + + for (auto it2 = enum_def.Vals().begin(); it2 != enum_def.Vals().end(); + ++it2) { + const EnumVal &ev = **it2; + if (ev.IsZero()) continue; + code += "\tcase " + enum_def.name + ev.name + ":\n"; + code += "\t\tx := " + ev.union_type.struct_def->name + "{_tab: table}\n"; + + code += "\t\treturn &" + + WrapInNameSpaceAndTrack(enum_def.defined_namespace, + NativeName(enum_def)) + + "{ Type: " + enum_def.name + ev.name + ", Value: x.UnPack() }\n"; + } + code += "\t}\n"; + code += "\treturn nil\n"; + code += "}\n\n"; + } + + void GenNativeTablePack(const StructDef &struct_def, std::string *code_ptr) { + std::string &code = *code_ptr; + + code += "func " + struct_def.name + + "Pack(builder *flatbuffers.Builder, t *" + NativeName(struct_def) + + ") flatbuffers.UOffsetT {\n"; + code += "\tif t == nil { return 0 }\n"; + for (auto it = struct_def.fields.vec.begin(); + it != struct_def.fields.vec.end(); ++it) { + const FieldDef &field = **it; + if (field.deprecated) continue; + if (IsScalar(field.value.type.base_type)) continue; + + std::string offset = MakeCamel(field.name, false) + "Offset"; + + if (field.value.type.base_type == BASE_TYPE_STRING) { + code += "\t" + offset + " := builder.CreateString(t." + + MakeCamel(field.name) + ")\n"; + } else if (field.value.type.base_type == BASE_TYPE_VECTOR && + field.value.type.element == BASE_TYPE_UCHAR && + field.value.type.enum_def == nullptr) { + code += "\t" + offset + " := flatbuffers.UOffsetT(0)\n"; + code += "\tif t." + MakeCamel(field.name) + " != nil {\n"; + code += "\t\t" + offset + " = builder.CreateByteString(t." + + MakeCamel(field.name) + ")\n"; + code += "\t}\n"; + } else if (field.value.type.base_type == BASE_TYPE_VECTOR) { + code += "\t" + offset + " := flatbuffers.UOffsetT(0)\n"; + code += "\tif t." + MakeCamel(field.name) + " != nil {\n"; + std::string length = MakeCamel(field.name, false) + "Length"; + std::string offsets = MakeCamel(field.name, false) + "Offsets"; + code += "\t\t" + length + " := len(t." + MakeCamel(field.name) + ")\n"; + if (field.value.type.element == BASE_TYPE_STRING) { + code += "\t\t" + offsets + " := make([]flatbuffers.UOffsetT, " + + length + ")\n"; + code += "\t\tfor j := 0; j < " + length + "; j++ {\n"; + code += "\t\t\t" + offsets + "[j] = builder.CreateString(t." + + MakeCamel(field.name) + "[j])\n"; + code += "\t\t}\n"; + } else if (field.value.type.element == BASE_TYPE_STRUCT && + !field.value.type.struct_def->fixed) { + code += "\t\t" + offsets + " := make([]flatbuffers.UOffsetT, " + + length + ")\n"; + code += "\t\tfor j := 0; j < " + length + "; j++ {\n"; + code += "\t\t\t" + offsets + "[j] = " + + WrapInNameSpaceAndTrack(*field.value.type.struct_def) + + "Pack(builder, t." + MakeCamel(field.name) + "[j])\n"; + code += "\t\t}\n"; + } + code += "\t\t" + struct_def.name + "Start" + MakeCamel(field.name) + + "Vector(builder, " + length + ")\n"; + code += "\t\tfor j := " + length + " - 1; j >= 0; j-- {\n"; + if (IsScalar(field.value.type.element)) { + code += "\t\t\tbuilder.Prepend" + + MakeCamel(GenTypeBasic(field.value.type.VectorType())) + "(" + + CastToBaseType( + field.value.type.VectorType(), + "t." + MakeCamel(field.name) + "[j]") + ")\n"; + } else if (field.value.type.element == BASE_TYPE_STRUCT && + field.value.type.struct_def->fixed) { + code += "\t\t\t" + + WrapInNameSpaceAndTrack(*field.value.type.struct_def) + + "Pack(builder, t." + MakeCamel(field.name) + "[j])\n"; + } else { + code += "\t\t\tbuilder.PrependUOffsetT(" + offsets + "[j])\n"; + } + code += "\t\t}\n"; + code += "\t\t" + offset + " = builder.EndVector(" + length + ")\n"; + code += "\t}\n"; + } else if (field.value.type.base_type == BASE_TYPE_STRUCT) { + if (field.value.type.struct_def->fixed) continue; + code += "\t" + offset + + " := " + WrapInNameSpaceAndTrack(*field.value.type.struct_def) + + "Pack(builder, t." + MakeCamel(field.name) + ")\n"; + } else if (field.value.type.base_type == BASE_TYPE_UNION) { + code += "\t" + offset + + " := " + WrapInNameSpaceAndTrack(*field.value.type.enum_def) + + "Pack(builder, t." + MakeCamel(field.name) + ")\n"; + code += "\t\n"; + } else { + FLATBUFFERS_ASSERT(0); + } + } + code += "\t" + struct_def.name + "Start(builder)\n"; + for (auto it = struct_def.fields.vec.begin(); + it != struct_def.fields.vec.end(); ++it) { + const FieldDef &field = **it; + if (field.deprecated) continue; + + std::string offset = MakeCamel(field.name, false) + "Offset"; + if (IsScalar(field.value.type.base_type)) { + if (field.value.type.enum_def == nullptr || + !field.value.type.enum_def->is_union) { + code += "\t" + struct_def.name + "Add" + MakeCamel(field.name) + + "(builder, t." + MakeCamel(field.name) + ")\n"; + } + } else { + if (field.value.type.base_type == BASE_TYPE_STRUCT && + field.value.type.struct_def->fixed) { + code += "\t" + offset + " := " + + WrapInNameSpaceAndTrack(*field.value.type.struct_def) + + "Pack(builder, t." + MakeCamel(field.name) + ")\n"; + } else if (field.value.type.enum_def != nullptr && + field.value.type.enum_def->is_union) { + code += "\tif t." + MakeCamel(field.name) + " != nil {\n"; + code += "\t\t" + struct_def.name + "Add" + + MakeCamel(field.name + UnionTypeFieldSuffix()) + + "(builder, t." + MakeCamel(field.name) + ".Type)\n"; + code += "\t}\n"; + } + code += "\t" + struct_def.name + "Add" + MakeCamel(field.name) + + "(builder, " + offset + ")\n"; + } + } + code += "\treturn " + struct_def.name + "End(builder)\n"; + code += "}\n\n"; + } + + void GenNativeTableUnPack( + const StructDef &struct_def, std::string *code_ptr) { + std::string &code = *code_ptr; + + code += "func (rcv *" + struct_def.name + ") UnPack() *" + + NativeName(struct_def) + " {\n"; + code += "\tif rcv == nil { return nil }\n"; + code += "\tt := &" + NativeName(struct_def) + "{}\n"; + for (auto it = struct_def.fields.vec.begin(); + it != struct_def.fields.vec.end(); ++it) { + const FieldDef &field = **it; + if (field.deprecated) continue; + std::string field_name_camel = MakeCamel(field.name); + std::string length = MakeCamel(field.name, false) + "Length"; + if (IsScalar(field.value.type.base_type)) { + if (field.value.type.enum_def != nullptr && + field.value.type.enum_def->is_union) + continue; + code += "\tt." + field_name_camel + " = rcv." + field_name_camel + + "()\n"; + } else if (field.value.type.base_type == BASE_TYPE_STRING) { + code += "\tt." + field_name_camel + " = string(rcv." + + field_name_camel + "())\n"; + } else if (field.value.type.base_type == BASE_TYPE_VECTOR && + field.value.type.element == BASE_TYPE_UCHAR && + field.value.type.enum_def == nullptr) { + code += "\tt." + field_name_camel + " = rcv." + field_name_camel + + "Bytes()\n"; + } else if (field.value.type.base_type == BASE_TYPE_VECTOR) { + code += "\t" + length + " := rcv." + field_name_camel + "Length()\n"; + code += "\tt." + field_name_camel + " = make(" + + NativeType(field.value.type) + ", " + length + ")\n"; + code += "\tfor j := 0; j < " + length + "; j++ {\n"; + if (field.value.type.element == BASE_TYPE_STRUCT) { + code += "\t\tx := " + field.value.type.struct_def->name + "{}\n"; + code += "\t\trcv." + field_name_camel + "(&x, j)\n"; + } + code += "\t\tt." + field_name_camel + "[j] = "; + if (IsScalar(field.value.type.element)) { + code += "rcv." + field_name_camel + "(j)"; + } else if (field.value.type.element == BASE_TYPE_STRING) { + code += "string(rcv." + field_name_camel + "(j))"; + } else if (field.value.type.element == BASE_TYPE_STRUCT) { + code += "x.UnPack()"; + } else { + // TODO(iceboy): Support vector of unions. + FLATBUFFERS_ASSERT(0); + } + code += "\n"; + code += "\t}\n"; + } else if (field.value.type.base_type == BASE_TYPE_STRUCT) { + code += "\tt." + field_name_camel + " = rcv." + field_name_camel + + "(nil).UnPack()\n"; + } else if (field.value.type.base_type == BASE_TYPE_UNION) { + const EnumDef &enum_def = *field.value.type.enum_def; + std::string field_table = MakeCamel(field.name, false) + "Table"; + code += "\t" + field_table + " := flatbuffers.Table{}\n"; + code += + "\tif rcv." + MakeCamel(field.name) + "(&" + field_table + ") {\n"; + code += "\t\tt." + field_name_camel + " = " + enum_def.name + + "UnPack(rcv." + MakeCamel(field.name + UnionTypeFieldSuffix()) + + "(), " + field_table + ")\n"; + code += "\t}\n"; + } else { + FLATBUFFERS_ASSERT(0); + } + } + code += "\treturn t\n"; + code += "}\n\n"; + } + + void GenNativeStructPack(const StructDef &struct_def, std::string *code_ptr) { + std::string &code = *code_ptr; + + code += "func " + struct_def.name + + "Pack(builder *flatbuffers.Builder, t *" + NativeName(struct_def) + + ") flatbuffers.UOffsetT {\n"; + code += "\tif t == nil { return 0 }\n"; + code += "\treturn Create" + struct_def.name + "(builder"; + StructPackArgs(struct_def, "", code_ptr); + code += ")\n"; + code += "}\n"; + } + + void StructPackArgs(const StructDef &struct_def, const char *nameprefix, + std::string *code_ptr) { + std::string &code = *code_ptr; + for (auto it = struct_def.fields.vec.begin(); + it != struct_def.fields.vec.end(); ++it) { + const FieldDef &field = **it; + if (field.value.type.base_type == BASE_TYPE_STRUCT) { + StructPackArgs(*field.value.type.struct_def, + (nameprefix + MakeCamel(field.name) + ".").c_str(), + code_ptr); + } else { + code += std::string(", t.") + nameprefix + MakeCamel(field.name); + } + } + } + + void GenNativeStructUnPack( + const StructDef &struct_def, std::string *code_ptr) { + std::string &code = *code_ptr; + + code += "func (rcv *" + struct_def.name + ") UnPack() *" + + NativeName(struct_def) + " {\n"; + code += "\tif rcv == nil { return nil }\n"; + code += "\tt := &" + NativeName(struct_def) + "{}\n"; + for (auto it = struct_def.fields.vec.begin(); + it != struct_def.fields.vec.end(); ++it) { + const FieldDef &field = **it; + if (field.value.type.base_type == BASE_TYPE_STRUCT) { + code += "\tt." + MakeCamel(field.name) + " = rcv." + + MakeCamel(field.name) + "(nil).UnPack()\n"; + } else { + code += "\tt." + MakeCamel(field.name) + " = rcv." + + MakeCamel(field.name) + "()\n"; + } + } + code += "\treturn t\n"; + code += "}\n\n"; + } + // Generate enum declarations. void GenEnum(const EnumDef &enum_def, std::string *code_ptr) { if (enum_def.generated) return; @@ -782,7 +1113,7 @@ class GoGenerator : public BaseGenerator { GenEnumType(enum_def, code_ptr); BeginEnum(code_ptr); for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { - auto &ev = **it; + const EnumVal &ev = **it; GenComment(ev.doc_comment, code_ptr, nullptr, "\t"); EnumMember(enum_def, ev, max_name_length, code_ptr); } @@ -790,7 +1121,7 @@ class GoGenerator : public BaseGenerator { BeginEnumNames(enum_def, code_ptr); for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { - auto &ev = **it; + const EnumVal &ev = **it; EnumNameMember(enum_def, ev, max_name_length, code_ptr); } EndEnumNames(code_ptr); @@ -880,11 +1211,43 @@ class GoGenerator : public BaseGenerator { std::string GenConstant(const FieldDef &field) { switch (field.value.type.base_type) { - case BASE_TYPE_BOOL: return field.value.constant == "0" ? "false" : "true";; + case BASE_TYPE_BOOL: return field.value.constant == "0" ? "false" : "true"; default: return field.value.constant; } } + std::string NativeName(const StructDef &struct_def) { + return parser_.opts.object_prefix + struct_def.name + + parser_.opts.object_suffix; + } + + std::string NativeName(const EnumDef &enum_def) { + return parser_.opts.object_prefix + enum_def.name + + parser_.opts.object_suffix; + } + + std::string NativeType(const Type &type) { + if (IsScalar(type.base_type)) { + if (type.enum_def == nullptr) { + return GenTypeBasic(type); + } else { + return GetEnumTypeName(*type.enum_def); + } + } else if (type.base_type == BASE_TYPE_STRING) { + return "string"; + } else if (type.base_type == BASE_TYPE_VECTOR) { + return "[]" + NativeType(type.VectorType()); + } else if (type.base_type == BASE_TYPE_STRUCT) { + return "*" + WrapInNameSpaceAndTrack( + type.struct_def->defined_namespace, NativeName(*type.struct_def)); + } else if (type.base_type == BASE_TYPE_UNION) { + return "*" + WrapInNameSpaceAndTrack( + type.enum_def->defined_namespace, NativeName(*type.enum_def)); + } + FLATBUFFERS_ASSERT(0); + return std::string(); + } + // Create a struct with a builder and the struct's arguments. void GenStructBuilder(const StructDef &struct_def, std::string *code_ptr) { BeginBuilderArgs(struct_def, code_ptr); diff --git a/tests/GoTest.sh b/tests/GoTest.sh index e69f0d8cb..60ef92778 100755 --- a/tests/GoTest.sh +++ b/tests/GoTest.sh @@ -20,7 +20,7 @@ go_path=${test_dir}/go_gen go_src=${go_path}/src # Emit Go code for the example schema in the test dir: -../flatc -g -I include_test monster_test.fbs +../flatc -g --gen-object-api -I include_test 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 diff --git a/tests/MyGame/Example/Ability.go b/tests/MyGame/Example/Ability.go index a56b44521..12ff1e58d 100644 --- a/tests/MyGame/Example/Ability.go +++ b/tests/MyGame/Example/Ability.go @@ -6,6 +6,23 @@ import ( flatbuffers "github.com/google/flatbuffers/go" ) +type AbilityT struct { + Id uint32 + Distance uint32 +} + +func AbilityPack(builder *flatbuffers.Builder, t *AbilityT) flatbuffers.UOffsetT { + if t == nil { return 0 } + return CreateAbility(builder, t.Id, t.Distance) +} +func (rcv *Ability) UnPack() *AbilityT { + if rcv == nil { return nil } + t := &AbilityT{} + t.Id = rcv.Id() + t.Distance = rcv.Distance() + return t +} + type Ability struct { _tab flatbuffers.Struct } diff --git a/tests/MyGame/Example/Any.go b/tests/MyGame/Example/Any.go index 8d9067e1d..7b9ffb918 100644 --- a/tests/MyGame/Example/Any.go +++ b/tests/MyGame/Example/Any.go @@ -2,7 +2,48 @@ package Example -import "strconv" +import ( + "strconv" + + flatbuffers "github.com/google/flatbuffers/go" + + MyGame__Example2 "MyGame/Example2" +) + +type AnyT struct { + Type Any + Value interface{} +} + +func AnyPack(builder *flatbuffers.Builder, t *AnyT) flatbuffers.UOffsetT { + if t == nil { + return 0 + } + switch t.Type { + case AnyMonster: + return MonsterPack(builder, t.Value.(*MonsterT)) + case AnyTestSimpleTableWithEnum: + return TestSimpleTableWithEnumPack(builder, t.Value.(*TestSimpleTableWithEnumT)) + case AnyMyGame_Example2_Monster: + return MyGame__Example2.MonsterPack(builder, t.Value.(*MyGame__Example2.MonsterT)) + } + return 0 +} + +func AnyUnPack(t Any, table flatbuffers.Table) *AnyT { + switch t { + case AnyMonster: + x := Monster{_tab: table} + return &AnyT{ Type: AnyMonster, Value: x.UnPack() } + case AnyTestSimpleTableWithEnum: + x := TestSimpleTableWithEnum{_tab: table} + return &AnyT{ Type: AnyTestSimpleTableWithEnum, Value: x.UnPack() } + case AnyMyGame_Example2_Monster: + x := Monster{_tab: table} + return &AnyT{ Type: AnyMyGame_Example2_Monster, Value: x.UnPack() } + } + return nil +} type Any byte diff --git a/tests/MyGame/Example/AnyAmbiguousAliases.go b/tests/MyGame/Example/AnyAmbiguousAliases.go index b9c3793a3..cc4adb8a0 100644 --- a/tests/MyGame/Example/AnyAmbiguousAliases.go +++ b/tests/MyGame/Example/AnyAmbiguousAliases.go @@ -2,7 +2,46 @@ package Example -import "strconv" +import ( + "strconv" + + flatbuffers "github.com/google/flatbuffers/go" +) + +type AnyAmbiguousAliasesT struct { + Type AnyAmbiguousAliases + Value interface{} +} + +func AnyAmbiguousAliasesPack(builder *flatbuffers.Builder, t *AnyAmbiguousAliasesT) flatbuffers.UOffsetT { + if t == nil { + return 0 + } + switch t.Type { + case AnyAmbiguousAliasesM1: + return MonsterPack(builder, t.Value.(*MonsterT)) + case AnyAmbiguousAliasesM2: + return MonsterPack(builder, t.Value.(*MonsterT)) + case AnyAmbiguousAliasesM3: + return MonsterPack(builder, t.Value.(*MonsterT)) + } + return 0 +} + +func AnyAmbiguousAliasesUnPack(t AnyAmbiguousAliases, table flatbuffers.Table) *AnyAmbiguousAliasesT { + switch t { + case AnyAmbiguousAliasesM1: + x := Monster{_tab: table} + return &AnyAmbiguousAliasesT{ Type: AnyAmbiguousAliasesM1, Value: x.UnPack() } + case AnyAmbiguousAliasesM2: + x := Monster{_tab: table} + return &AnyAmbiguousAliasesT{ Type: AnyAmbiguousAliasesM2, Value: x.UnPack() } + case AnyAmbiguousAliasesM3: + x := Monster{_tab: table} + return &AnyAmbiguousAliasesT{ Type: AnyAmbiguousAliasesM3, Value: x.UnPack() } + } + return nil +} type AnyAmbiguousAliases byte diff --git a/tests/MyGame/Example/AnyUniqueAliases.go b/tests/MyGame/Example/AnyUniqueAliases.go index 23d86491d..56b516380 100644 --- a/tests/MyGame/Example/AnyUniqueAliases.go +++ b/tests/MyGame/Example/AnyUniqueAliases.go @@ -2,7 +2,48 @@ package Example -import "strconv" +import ( + "strconv" + + flatbuffers "github.com/google/flatbuffers/go" + + MyGame__Example2 "MyGame/Example2" +) + +type AnyUniqueAliasesT struct { + Type AnyUniqueAliases + Value interface{} +} + +func AnyUniqueAliasesPack(builder *flatbuffers.Builder, t *AnyUniqueAliasesT) flatbuffers.UOffsetT { + if t == nil { + return 0 + } + switch t.Type { + case AnyUniqueAliasesM: + return MonsterPack(builder, t.Value.(*MonsterT)) + case AnyUniqueAliasesTS: + return TestSimpleTableWithEnumPack(builder, t.Value.(*TestSimpleTableWithEnumT)) + case AnyUniqueAliasesM2: + return MyGame__Example2.MonsterPack(builder, t.Value.(*MyGame__Example2.MonsterT)) + } + return 0 +} + +func AnyUniqueAliasesUnPack(t AnyUniqueAliases, table flatbuffers.Table) *AnyUniqueAliasesT { + switch t { + case AnyUniqueAliasesM: + x := Monster{_tab: table} + return &AnyUniqueAliasesT{ Type: AnyUniqueAliasesM, Value: x.UnPack() } + case AnyUniqueAliasesTS: + x := TestSimpleTableWithEnum{_tab: table} + return &AnyUniqueAliasesT{ Type: AnyUniqueAliasesTS, Value: x.UnPack() } + case AnyUniqueAliasesM2: + x := Monster{_tab: table} + return &AnyUniqueAliasesT{ Type: AnyUniqueAliasesM2, Value: x.UnPack() } + } + return nil +} type AnyUniqueAliases byte diff --git a/tests/MyGame/Example/Monster.go b/tests/MyGame/Example/Monster.go index 6199049cc..32be49f19 100644 --- a/tests/MyGame/Example/Monster.go +++ b/tests/MyGame/Example/Monster.go @@ -9,6 +9,424 @@ import ( ) /// an example documentation comment: monster object +type MonsterT struct { + Pos *Vec3T + Mana int16 + Hp int16 + Name string + Inventory []byte + Color Color + Test *AnyT + Test4 []*TestT + Testarrayofstring []string + Testarrayoftables []*MonsterT + Enemy *MonsterT + Testnestedflatbuffer []byte + Testempty *StatT + Testbool bool + Testhashs32Fnv1 int32 + Testhashu32Fnv1 uint32 + Testhashs64Fnv1 int64 + Testhashu64Fnv1 uint64 + Testhashs32Fnv1a int32 + Testhashu32Fnv1a uint32 + Testhashs64Fnv1a int64 + Testhashu64Fnv1a uint64 + Testarrayofbools []bool + Testf float32 + Testf2 float32 + Testf3 float32 + Testarrayofstring2 []string + Testarrayofsortedstruct []*AbilityT + Flex []byte + Test5 []*TestT + VectorOfLongs []int64 + VectorOfDoubles []float64 + ParentNamespaceTest *MyGame.InParentNamespaceT + VectorOfReferrables []*ReferrableT + SingleWeakReference uint64 + VectorOfWeakReferences []uint64 + VectorOfStrongReferrables []*ReferrableT + CoOwningReference uint64 + VectorOfCoOwningReferences []uint64 + NonOwningReference uint64 + VectorOfNonOwningReferences []uint64 + AnyUnique *AnyUniqueAliasesT + AnyAmbiguous *AnyAmbiguousAliasesT + VectorOfEnums []Color + SignedEnum Race +} + +func MonsterPack(builder *flatbuffers.Builder, t *MonsterT) flatbuffers.UOffsetT { + if t == nil { return 0 } + nameOffset := builder.CreateString(t.Name) + inventoryOffset := flatbuffers.UOffsetT(0) + if t.Inventory != nil { + inventoryOffset = builder.CreateByteString(t.Inventory) + } + testOffset := AnyPack(builder, t.Test) + + test4Offset := flatbuffers.UOffsetT(0) + if t.Test4 != nil { + test4Length := len(t.Test4) + MonsterStartTest4Vector(builder, test4Length) + for j := test4Length - 1; j >= 0; j-- { + TestPack(builder, t.Test4[j]) + } + test4Offset = builder.EndVector(test4Length) + } + testarrayofstringOffset := flatbuffers.UOffsetT(0) + if t.Testarrayofstring != nil { + testarrayofstringLength := len(t.Testarrayofstring) + testarrayofstringOffsets := make([]flatbuffers.UOffsetT, testarrayofstringLength) + for j := 0; j < testarrayofstringLength; j++ { + testarrayofstringOffsets[j] = builder.CreateString(t.Testarrayofstring[j]) + } + MonsterStartTestarrayofstringVector(builder, testarrayofstringLength) + for j := testarrayofstringLength - 1; j >= 0; j-- { + builder.PrependUOffsetT(testarrayofstringOffsets[j]) + } + testarrayofstringOffset = builder.EndVector(testarrayofstringLength) + } + testarrayoftablesOffset := flatbuffers.UOffsetT(0) + if t.Testarrayoftables != nil { + testarrayoftablesLength := len(t.Testarrayoftables) + testarrayoftablesOffsets := make([]flatbuffers.UOffsetT, testarrayoftablesLength) + for j := 0; j < testarrayoftablesLength; j++ { + testarrayoftablesOffsets[j] = MonsterPack(builder, t.Testarrayoftables[j]) + } + MonsterStartTestarrayoftablesVector(builder, testarrayoftablesLength) + for j := testarrayoftablesLength - 1; j >= 0; j-- { + builder.PrependUOffsetT(testarrayoftablesOffsets[j]) + } + testarrayoftablesOffset = builder.EndVector(testarrayoftablesLength) + } + enemyOffset := MonsterPack(builder, t.Enemy) + testnestedflatbufferOffset := flatbuffers.UOffsetT(0) + if t.Testnestedflatbuffer != nil { + testnestedflatbufferOffset = builder.CreateByteString(t.Testnestedflatbuffer) + } + testemptyOffset := StatPack(builder, t.Testempty) + testarrayofboolsOffset := flatbuffers.UOffsetT(0) + if t.Testarrayofbools != nil { + testarrayofboolsLength := len(t.Testarrayofbools) + MonsterStartTestarrayofboolsVector(builder, testarrayofboolsLength) + for j := testarrayofboolsLength - 1; j >= 0; j-- { + builder.PrependBool(t.Testarrayofbools[j]) + } + testarrayofboolsOffset = builder.EndVector(testarrayofboolsLength) + } + testarrayofstring2Offset := flatbuffers.UOffsetT(0) + if t.Testarrayofstring2 != nil { + testarrayofstring2Length := len(t.Testarrayofstring2) + testarrayofstring2Offsets := make([]flatbuffers.UOffsetT, testarrayofstring2Length) + for j := 0; j < testarrayofstring2Length; j++ { + testarrayofstring2Offsets[j] = builder.CreateString(t.Testarrayofstring2[j]) + } + MonsterStartTestarrayofstring2Vector(builder, testarrayofstring2Length) + for j := testarrayofstring2Length - 1; j >= 0; j-- { + builder.PrependUOffsetT(testarrayofstring2Offsets[j]) + } + testarrayofstring2Offset = builder.EndVector(testarrayofstring2Length) + } + testarrayofsortedstructOffset := flatbuffers.UOffsetT(0) + if t.Testarrayofsortedstruct != nil { + testarrayofsortedstructLength := len(t.Testarrayofsortedstruct) + MonsterStartTestarrayofsortedstructVector(builder, testarrayofsortedstructLength) + for j := testarrayofsortedstructLength - 1; j >= 0; j-- { + AbilityPack(builder, t.Testarrayofsortedstruct[j]) + } + testarrayofsortedstructOffset = builder.EndVector(testarrayofsortedstructLength) + } + flexOffset := flatbuffers.UOffsetT(0) + if t.Flex != nil { + flexOffset = builder.CreateByteString(t.Flex) + } + test5Offset := flatbuffers.UOffsetT(0) + if t.Test5 != nil { + test5Length := len(t.Test5) + MonsterStartTest5Vector(builder, test5Length) + for j := test5Length - 1; j >= 0; j-- { + TestPack(builder, t.Test5[j]) + } + test5Offset = builder.EndVector(test5Length) + } + vectorOfLongsOffset := flatbuffers.UOffsetT(0) + if t.VectorOfLongs != nil { + vectorOfLongsLength := len(t.VectorOfLongs) + MonsterStartVectorOfLongsVector(builder, vectorOfLongsLength) + for j := vectorOfLongsLength - 1; j >= 0; j-- { + builder.PrependInt64(t.VectorOfLongs[j]) + } + vectorOfLongsOffset = builder.EndVector(vectorOfLongsLength) + } + vectorOfDoublesOffset := flatbuffers.UOffsetT(0) + if t.VectorOfDoubles != nil { + vectorOfDoublesLength := len(t.VectorOfDoubles) + MonsterStartVectorOfDoublesVector(builder, vectorOfDoublesLength) + for j := vectorOfDoublesLength - 1; j >= 0; j-- { + builder.PrependFloat64(t.VectorOfDoubles[j]) + } + vectorOfDoublesOffset = builder.EndVector(vectorOfDoublesLength) + } + parentNamespaceTestOffset := MyGame.InParentNamespacePack(builder, t.ParentNamespaceTest) + vectorOfReferrablesOffset := flatbuffers.UOffsetT(0) + if t.VectorOfReferrables != nil { + vectorOfReferrablesLength := len(t.VectorOfReferrables) + vectorOfReferrablesOffsets := make([]flatbuffers.UOffsetT, vectorOfReferrablesLength) + for j := 0; j < vectorOfReferrablesLength; j++ { + vectorOfReferrablesOffsets[j] = ReferrablePack(builder, t.VectorOfReferrables[j]) + } + MonsterStartVectorOfReferrablesVector(builder, vectorOfReferrablesLength) + for j := vectorOfReferrablesLength - 1; j >= 0; j-- { + builder.PrependUOffsetT(vectorOfReferrablesOffsets[j]) + } + vectorOfReferrablesOffset = builder.EndVector(vectorOfReferrablesLength) + } + vectorOfWeakReferencesOffset := flatbuffers.UOffsetT(0) + if t.VectorOfWeakReferences != nil { + vectorOfWeakReferencesLength := len(t.VectorOfWeakReferences) + MonsterStartVectorOfWeakReferencesVector(builder, vectorOfWeakReferencesLength) + for j := vectorOfWeakReferencesLength - 1; j >= 0; j-- { + builder.PrependUint64(t.VectorOfWeakReferences[j]) + } + vectorOfWeakReferencesOffset = builder.EndVector(vectorOfWeakReferencesLength) + } + vectorOfStrongReferrablesOffset := flatbuffers.UOffsetT(0) + if t.VectorOfStrongReferrables != nil { + vectorOfStrongReferrablesLength := len(t.VectorOfStrongReferrables) + vectorOfStrongReferrablesOffsets := make([]flatbuffers.UOffsetT, vectorOfStrongReferrablesLength) + for j := 0; j < vectorOfStrongReferrablesLength; j++ { + vectorOfStrongReferrablesOffsets[j] = ReferrablePack(builder, t.VectorOfStrongReferrables[j]) + } + MonsterStartVectorOfStrongReferrablesVector(builder, vectorOfStrongReferrablesLength) + for j := vectorOfStrongReferrablesLength - 1; j >= 0; j-- { + builder.PrependUOffsetT(vectorOfStrongReferrablesOffsets[j]) + } + vectorOfStrongReferrablesOffset = builder.EndVector(vectorOfStrongReferrablesLength) + } + vectorOfCoOwningReferencesOffset := flatbuffers.UOffsetT(0) + if t.VectorOfCoOwningReferences != nil { + vectorOfCoOwningReferencesLength := len(t.VectorOfCoOwningReferences) + MonsterStartVectorOfCoOwningReferencesVector(builder, vectorOfCoOwningReferencesLength) + for j := vectorOfCoOwningReferencesLength - 1; j >= 0; j-- { + builder.PrependUint64(t.VectorOfCoOwningReferences[j]) + } + vectorOfCoOwningReferencesOffset = builder.EndVector(vectorOfCoOwningReferencesLength) + } + vectorOfNonOwningReferencesOffset := flatbuffers.UOffsetT(0) + if t.VectorOfNonOwningReferences != nil { + vectorOfNonOwningReferencesLength := len(t.VectorOfNonOwningReferences) + MonsterStartVectorOfNonOwningReferencesVector(builder, vectorOfNonOwningReferencesLength) + for j := vectorOfNonOwningReferencesLength - 1; j >= 0; j-- { + builder.PrependUint64(t.VectorOfNonOwningReferences[j]) + } + vectorOfNonOwningReferencesOffset = builder.EndVector(vectorOfNonOwningReferencesLength) + } + anyUniqueOffset := AnyUniqueAliasesPack(builder, t.AnyUnique) + + anyAmbiguousOffset := AnyAmbiguousAliasesPack(builder, t.AnyAmbiguous) + + vectorOfEnumsOffset := flatbuffers.UOffsetT(0) + if t.VectorOfEnums != nil { + vectorOfEnumsLength := len(t.VectorOfEnums) + MonsterStartVectorOfEnumsVector(builder, vectorOfEnumsLength) + for j := vectorOfEnumsLength - 1; j >= 0; j-- { + builder.PrependByte(byte(t.VectorOfEnums[j])) + } + vectorOfEnumsOffset = builder.EndVector(vectorOfEnumsLength) + } + MonsterStart(builder) + posOffset := Vec3Pack(builder, t.Pos) + MonsterAddPos(builder, posOffset) + MonsterAddMana(builder, t.Mana) + MonsterAddHp(builder, t.Hp) + MonsterAddName(builder, nameOffset) + MonsterAddInventory(builder, inventoryOffset) + MonsterAddColor(builder, t.Color) + if t.Test != nil { + MonsterAddTestType(builder, t.Test.Type) + } + MonsterAddTest(builder, testOffset) + MonsterAddTest4(builder, test4Offset) + MonsterAddTestarrayofstring(builder, testarrayofstringOffset) + MonsterAddTestarrayoftables(builder, testarrayoftablesOffset) + MonsterAddEnemy(builder, enemyOffset) + MonsterAddTestnestedflatbuffer(builder, testnestedflatbufferOffset) + MonsterAddTestempty(builder, testemptyOffset) + MonsterAddTestbool(builder, t.Testbool) + MonsterAddTesthashs32Fnv1(builder, t.Testhashs32Fnv1) + MonsterAddTesthashu32Fnv1(builder, t.Testhashu32Fnv1) + MonsterAddTesthashs64Fnv1(builder, t.Testhashs64Fnv1) + MonsterAddTesthashu64Fnv1(builder, t.Testhashu64Fnv1) + MonsterAddTesthashs32Fnv1a(builder, t.Testhashs32Fnv1a) + MonsterAddTesthashu32Fnv1a(builder, t.Testhashu32Fnv1a) + MonsterAddTesthashs64Fnv1a(builder, t.Testhashs64Fnv1a) + MonsterAddTesthashu64Fnv1a(builder, t.Testhashu64Fnv1a) + MonsterAddTestarrayofbools(builder, testarrayofboolsOffset) + MonsterAddTestf(builder, t.Testf) + MonsterAddTestf2(builder, t.Testf2) + MonsterAddTestf3(builder, t.Testf3) + MonsterAddTestarrayofstring2(builder, testarrayofstring2Offset) + MonsterAddTestarrayofsortedstruct(builder, testarrayofsortedstructOffset) + MonsterAddFlex(builder, flexOffset) + MonsterAddTest5(builder, test5Offset) + MonsterAddVectorOfLongs(builder, vectorOfLongsOffset) + MonsterAddVectorOfDoubles(builder, vectorOfDoublesOffset) + MonsterAddParentNamespaceTest(builder, parentNamespaceTestOffset) + MonsterAddVectorOfReferrables(builder, vectorOfReferrablesOffset) + MonsterAddSingleWeakReference(builder, t.SingleWeakReference) + MonsterAddVectorOfWeakReferences(builder, vectorOfWeakReferencesOffset) + MonsterAddVectorOfStrongReferrables(builder, vectorOfStrongReferrablesOffset) + MonsterAddCoOwningReference(builder, t.CoOwningReference) + MonsterAddVectorOfCoOwningReferences(builder, vectorOfCoOwningReferencesOffset) + MonsterAddNonOwningReference(builder, t.NonOwningReference) + MonsterAddVectorOfNonOwningReferences(builder, vectorOfNonOwningReferencesOffset) + if t.AnyUnique != nil { + MonsterAddAnyUniqueType(builder, t.AnyUnique.Type) + } + MonsterAddAnyUnique(builder, anyUniqueOffset) + if t.AnyAmbiguous != nil { + MonsterAddAnyAmbiguousType(builder, t.AnyAmbiguous.Type) + } + MonsterAddAnyAmbiguous(builder, anyAmbiguousOffset) + MonsterAddVectorOfEnums(builder, vectorOfEnumsOffset) + MonsterAddSignedEnum(builder, t.SignedEnum) + return MonsterEnd(builder) +} + +func (rcv *Monster) UnPack() *MonsterT { + if rcv == nil { return nil } + t := &MonsterT{} + t.Pos = rcv.Pos(nil).UnPack() + t.Mana = rcv.Mana() + t.Hp = rcv.Hp() + t.Name = string(rcv.Name()) + t.Inventory = rcv.InventoryBytes() + t.Color = rcv.Color() + testTable := flatbuffers.Table{} + if rcv.Test(&testTable) { + t.Test = AnyUnPack(rcv.TestType(), testTable) + } + test4Length := rcv.Test4Length() + t.Test4 = make([]*TestT, test4Length) + for j := 0; j < test4Length; j++ { + x := Test{} + rcv.Test4(&x, j) + t.Test4[j] = x.UnPack() + } + testarrayofstringLength := rcv.TestarrayofstringLength() + t.Testarrayofstring = make([]string, testarrayofstringLength) + for j := 0; j < testarrayofstringLength; j++ { + t.Testarrayofstring[j] = string(rcv.Testarrayofstring(j)) + } + testarrayoftablesLength := rcv.TestarrayoftablesLength() + t.Testarrayoftables = make([]*MonsterT, testarrayoftablesLength) + for j := 0; j < testarrayoftablesLength; j++ { + x := Monster{} + rcv.Testarrayoftables(&x, j) + t.Testarrayoftables[j] = x.UnPack() + } + t.Enemy = rcv.Enemy(nil).UnPack() + t.Testnestedflatbuffer = rcv.TestnestedflatbufferBytes() + t.Testempty = rcv.Testempty(nil).UnPack() + t.Testbool = rcv.Testbool() + t.Testhashs32Fnv1 = rcv.Testhashs32Fnv1() + t.Testhashu32Fnv1 = rcv.Testhashu32Fnv1() + t.Testhashs64Fnv1 = rcv.Testhashs64Fnv1() + t.Testhashu64Fnv1 = rcv.Testhashu64Fnv1() + t.Testhashs32Fnv1a = rcv.Testhashs32Fnv1a() + t.Testhashu32Fnv1a = rcv.Testhashu32Fnv1a() + t.Testhashs64Fnv1a = rcv.Testhashs64Fnv1a() + t.Testhashu64Fnv1a = rcv.Testhashu64Fnv1a() + testarrayofboolsLength := rcv.TestarrayofboolsLength() + t.Testarrayofbools = make([]bool, testarrayofboolsLength) + for j := 0; j < testarrayofboolsLength; j++ { + t.Testarrayofbools[j] = rcv.Testarrayofbools(j) + } + t.Testf = rcv.Testf() + t.Testf2 = rcv.Testf2() + t.Testf3 = rcv.Testf3() + testarrayofstring2Length := rcv.Testarrayofstring2Length() + t.Testarrayofstring2 = make([]string, testarrayofstring2Length) + for j := 0; j < testarrayofstring2Length; j++ { + t.Testarrayofstring2[j] = string(rcv.Testarrayofstring2(j)) + } + testarrayofsortedstructLength := rcv.TestarrayofsortedstructLength() + t.Testarrayofsortedstruct = make([]*AbilityT, testarrayofsortedstructLength) + for j := 0; j < testarrayofsortedstructLength; j++ { + x := Ability{} + rcv.Testarrayofsortedstruct(&x, j) + t.Testarrayofsortedstruct[j] = x.UnPack() + } + t.Flex = rcv.FlexBytes() + test5Length := rcv.Test5Length() + t.Test5 = make([]*TestT, test5Length) + for j := 0; j < test5Length; j++ { + x := Test{} + rcv.Test5(&x, j) + t.Test5[j] = x.UnPack() + } + vectorOfLongsLength := rcv.VectorOfLongsLength() + t.VectorOfLongs = make([]int64, vectorOfLongsLength) + for j := 0; j < vectorOfLongsLength; j++ { + t.VectorOfLongs[j] = rcv.VectorOfLongs(j) + } + vectorOfDoublesLength := rcv.VectorOfDoublesLength() + t.VectorOfDoubles = make([]float64, vectorOfDoublesLength) + for j := 0; j < vectorOfDoublesLength; j++ { + t.VectorOfDoubles[j] = rcv.VectorOfDoubles(j) + } + t.ParentNamespaceTest = rcv.ParentNamespaceTest(nil).UnPack() + vectorOfReferrablesLength := rcv.VectorOfReferrablesLength() + t.VectorOfReferrables = make([]*ReferrableT, vectorOfReferrablesLength) + for j := 0; j < vectorOfReferrablesLength; j++ { + x := Referrable{} + rcv.VectorOfReferrables(&x, j) + t.VectorOfReferrables[j] = x.UnPack() + } + t.SingleWeakReference = rcv.SingleWeakReference() + vectorOfWeakReferencesLength := rcv.VectorOfWeakReferencesLength() + t.VectorOfWeakReferences = make([]uint64, vectorOfWeakReferencesLength) + for j := 0; j < vectorOfWeakReferencesLength; j++ { + t.VectorOfWeakReferences[j] = rcv.VectorOfWeakReferences(j) + } + vectorOfStrongReferrablesLength := rcv.VectorOfStrongReferrablesLength() + t.VectorOfStrongReferrables = make([]*ReferrableT, vectorOfStrongReferrablesLength) + for j := 0; j < vectorOfStrongReferrablesLength; j++ { + x := Referrable{} + rcv.VectorOfStrongReferrables(&x, j) + t.VectorOfStrongReferrables[j] = x.UnPack() + } + t.CoOwningReference = rcv.CoOwningReference() + vectorOfCoOwningReferencesLength := rcv.VectorOfCoOwningReferencesLength() + t.VectorOfCoOwningReferences = make([]uint64, vectorOfCoOwningReferencesLength) + for j := 0; j < vectorOfCoOwningReferencesLength; j++ { + t.VectorOfCoOwningReferences[j] = rcv.VectorOfCoOwningReferences(j) + } + t.NonOwningReference = rcv.NonOwningReference() + vectorOfNonOwningReferencesLength := rcv.VectorOfNonOwningReferencesLength() + t.VectorOfNonOwningReferences = make([]uint64, vectorOfNonOwningReferencesLength) + for j := 0; j < vectorOfNonOwningReferencesLength; j++ { + t.VectorOfNonOwningReferences[j] = rcv.VectorOfNonOwningReferences(j) + } + anyUniqueTable := flatbuffers.Table{} + if rcv.AnyUnique(&anyUniqueTable) { + t.AnyUnique = AnyUniqueAliasesUnPack(rcv.AnyUniqueType(), anyUniqueTable) + } + anyAmbiguousTable := flatbuffers.Table{} + if rcv.AnyAmbiguous(&anyAmbiguousTable) { + t.AnyAmbiguous = AnyAmbiguousAliasesUnPack(rcv.AnyAmbiguousType(), anyAmbiguousTable) + } + vectorOfEnumsLength := rcv.VectorOfEnumsLength() + t.VectorOfEnums = make([]Color, vectorOfEnumsLength) + for j := 0; j < vectorOfEnumsLength; j++ { + t.VectorOfEnums[j] = rcv.VectorOfEnums(j) + } + t.SignedEnum = rcv.SignedEnum() + return t +} + type Monster struct { _tab flatbuffers.Table } diff --git a/tests/MyGame/Example/Referrable.go b/tests/MyGame/Example/Referrable.go index 0fb06fb20..c2eb784dc 100644 --- a/tests/MyGame/Example/Referrable.go +++ b/tests/MyGame/Example/Referrable.go @@ -6,6 +6,24 @@ import ( flatbuffers "github.com/google/flatbuffers/go" ) +type ReferrableT struct { + Id uint64 +} + +func ReferrablePack(builder *flatbuffers.Builder, t *ReferrableT) flatbuffers.UOffsetT { + if t == nil { return 0 } + ReferrableStart(builder) + ReferrableAddId(builder, t.Id) + return ReferrableEnd(builder) +} + +func (rcv *Referrable) UnPack() *ReferrableT { + if rcv == nil { return nil } + t := &ReferrableT{} + t.Id = rcv.Id() + return t +} + type Referrable struct { _tab flatbuffers.Table } diff --git a/tests/MyGame/Example/Stat.go b/tests/MyGame/Example/Stat.go index 401712fbf..64ece1f0f 100644 --- a/tests/MyGame/Example/Stat.go +++ b/tests/MyGame/Example/Stat.go @@ -6,6 +6,31 @@ import ( flatbuffers "github.com/google/flatbuffers/go" ) +type StatT struct { + Id string + Val int64 + Count uint16 +} + +func StatPack(builder *flatbuffers.Builder, t *StatT) flatbuffers.UOffsetT { + if t == nil { return 0 } + idOffset := builder.CreateString(t.Id) + StatStart(builder) + StatAddId(builder, idOffset) + StatAddVal(builder, t.Val) + StatAddCount(builder, t.Count) + return StatEnd(builder) +} + +func (rcv *Stat) UnPack() *StatT { + if rcv == nil { return nil } + t := &StatT{} + t.Id = string(rcv.Id()) + t.Val = rcv.Val() + t.Count = rcv.Count() + return t +} + type Stat struct { _tab flatbuffers.Table } diff --git a/tests/MyGame/Example/Test.go b/tests/MyGame/Example/Test.go index 53f53fd41..31110d975 100644 --- a/tests/MyGame/Example/Test.go +++ b/tests/MyGame/Example/Test.go @@ -6,6 +6,23 @@ import ( flatbuffers "github.com/google/flatbuffers/go" ) +type TestT struct { + A int16 + B int8 +} + +func TestPack(builder *flatbuffers.Builder, t *TestT) flatbuffers.UOffsetT { + if t == nil { return 0 } + return CreateTest(builder, t.A, t.B) +} +func (rcv *Test) UnPack() *TestT { + if rcv == nil { return nil } + t := &TestT{} + t.A = rcv.A() + t.B = rcv.B() + return t +} + type Test struct { _tab flatbuffers.Struct } diff --git a/tests/MyGame/Example/TestSimpleTableWithEnum.go b/tests/MyGame/Example/TestSimpleTableWithEnum.go index 35a6c7c09..7af1edb09 100644 --- a/tests/MyGame/Example/TestSimpleTableWithEnum.go +++ b/tests/MyGame/Example/TestSimpleTableWithEnum.go @@ -6,6 +6,24 @@ import ( flatbuffers "github.com/google/flatbuffers/go" ) +type TestSimpleTableWithEnumT struct { + Color Color +} + +func TestSimpleTableWithEnumPack(builder *flatbuffers.Builder, t *TestSimpleTableWithEnumT) flatbuffers.UOffsetT { + if t == nil { return 0 } + TestSimpleTableWithEnumStart(builder) + TestSimpleTableWithEnumAddColor(builder, t.Color) + return TestSimpleTableWithEnumEnd(builder) +} + +func (rcv *TestSimpleTableWithEnum) UnPack() *TestSimpleTableWithEnumT { + if rcv == nil { return nil } + t := &TestSimpleTableWithEnumT{} + t.Color = rcv.Color() + return t +} + type TestSimpleTableWithEnum struct { _tab flatbuffers.Table } diff --git a/tests/MyGame/Example/TypeAliases.go b/tests/MyGame/Example/TypeAliases.go index d017b5bc3..497d5743a 100644 --- a/tests/MyGame/Example/TypeAliases.go +++ b/tests/MyGame/Example/TypeAliases.go @@ -6,6 +6,83 @@ import ( flatbuffers "github.com/google/flatbuffers/go" ) +type TypeAliasesT struct { + I8 int8 + U8 byte + I16 int16 + U16 uint16 + I32 int32 + U32 uint32 + I64 int64 + U64 uint64 + F32 float32 + F64 float64 + V8 []int8 + Vf64 []float64 +} + +func TypeAliasesPack(builder *flatbuffers.Builder, t *TypeAliasesT) flatbuffers.UOffsetT { + if t == nil { return 0 } + v8Offset := flatbuffers.UOffsetT(0) + if t.V8 != nil { + v8Length := len(t.V8) + TypeAliasesStartV8Vector(builder, v8Length) + for j := v8Length - 1; j >= 0; j-- { + builder.PrependInt8(t.V8[j]) + } + v8Offset = builder.EndVector(v8Length) + } + vf64Offset := flatbuffers.UOffsetT(0) + if t.Vf64 != nil { + vf64Length := len(t.Vf64) + TypeAliasesStartVf64Vector(builder, vf64Length) + for j := vf64Length - 1; j >= 0; j-- { + builder.PrependFloat64(t.Vf64[j]) + } + vf64Offset = builder.EndVector(vf64Length) + } + TypeAliasesStart(builder) + TypeAliasesAddI8(builder, t.I8) + TypeAliasesAddU8(builder, t.U8) + TypeAliasesAddI16(builder, t.I16) + TypeAliasesAddU16(builder, t.U16) + TypeAliasesAddI32(builder, t.I32) + TypeAliasesAddU32(builder, t.U32) + TypeAliasesAddI64(builder, t.I64) + TypeAliasesAddU64(builder, t.U64) + TypeAliasesAddF32(builder, t.F32) + TypeAliasesAddF64(builder, t.F64) + TypeAliasesAddV8(builder, v8Offset) + TypeAliasesAddVf64(builder, vf64Offset) + return TypeAliasesEnd(builder) +} + +func (rcv *TypeAliases) UnPack() *TypeAliasesT { + if rcv == nil { return nil } + t := &TypeAliasesT{} + t.I8 = rcv.I8() + t.U8 = rcv.U8() + t.I16 = rcv.I16() + t.U16 = rcv.U16() + t.I32 = rcv.I32() + t.U32 = rcv.U32() + t.I64 = rcv.I64() + t.U64 = rcv.U64() + t.F32 = rcv.F32() + t.F64 = rcv.F64() + v8Length := rcv.V8Length() + t.V8 = make([]int8, v8Length) + for j := 0; j < v8Length; j++ { + t.V8[j] = rcv.V8(j) + } + vf64Length := rcv.Vf64Length() + t.Vf64 = make([]float64, vf64Length) + for j := 0; j < vf64Length; j++ { + t.Vf64[j] = rcv.Vf64(j) + } + return t +} + type TypeAliases struct { _tab flatbuffers.Table } diff --git a/tests/MyGame/Example/Vec3.go b/tests/MyGame/Example/Vec3.go index 9131afdc1..3a75c88a1 100644 --- a/tests/MyGame/Example/Vec3.go +++ b/tests/MyGame/Example/Vec3.go @@ -6,6 +6,31 @@ import ( flatbuffers "github.com/google/flatbuffers/go" ) +type Vec3T struct { + X float32 + Y float32 + Z float32 + Test1 float64 + Test2 Color + Test3 *TestT +} + +func Vec3Pack(builder *flatbuffers.Builder, t *Vec3T) flatbuffers.UOffsetT { + if t == nil { return 0 } + return CreateVec3(builder, t.X, t.Y, t.Z, t.Test1, t.Test2, t.Test3.A, t.Test3.B) +} +func (rcv *Vec3) UnPack() *Vec3T { + if rcv == nil { return nil } + t := &Vec3T{} + t.X = rcv.X() + t.Y = rcv.Y() + t.Z = rcv.Z() + t.Test1 = rcv.Test1() + t.Test2 = rcv.Test2() + t.Test3 = rcv.Test3(nil).UnPack() + return t +} + type Vec3 struct { _tab flatbuffers.Struct } diff --git a/tests/MyGame/Example2/Monster.go b/tests/MyGame/Example2/Monster.go index d0fae94d9..b329d4322 100644 --- a/tests/MyGame/Example2/Monster.go +++ b/tests/MyGame/Example2/Monster.go @@ -6,6 +6,21 @@ import ( flatbuffers "github.com/google/flatbuffers/go" ) +type MonsterT struct { +} + +func MonsterPack(builder *flatbuffers.Builder, t *MonsterT) flatbuffers.UOffsetT { + if t == nil { return 0 } + MonsterStart(builder) + return MonsterEnd(builder) +} + +func (rcv *Monster) UnPack() *MonsterT { + if rcv == nil { return nil } + t := &MonsterT{} + return t +} + type Monster struct { _tab flatbuffers.Table } diff --git a/tests/MyGame/InParentNamespace.go b/tests/MyGame/InParentNamespace.go index fc6ce3263..186666a13 100644 --- a/tests/MyGame/InParentNamespace.go +++ b/tests/MyGame/InParentNamespace.go @@ -6,6 +6,21 @@ import ( flatbuffers "github.com/google/flatbuffers/go" ) +type InParentNamespaceT struct { +} + +func InParentNamespacePack(builder *flatbuffers.Builder, t *InParentNamespaceT) flatbuffers.UOffsetT { + if t == nil { return 0 } + InParentNamespaceStart(builder) + return InParentNamespaceEnd(builder) +} + +func (rcv *InParentNamespace) UnPack() *InParentNamespaceT { + if rcv == nil { return nil } + t := &InParentNamespaceT{} + return t +} + type InParentNamespace struct { _tab flatbuffers.Table } diff --git a/tests/go_test.go b/tests/go_test.go index 478470508..255b44038 100644 --- a/tests/go_test.go +++ b/tests/go_test.go @@ -90,6 +90,7 @@ func TestAll(t *testing.T) { // generated Go code: CheckReadBuffer(generated, off, t.Fatalf) CheckMutateBuffer(generated, off, t.Fatalf) + CheckObjectAPI(generated, off, t.Fatalf) // Verify that the buffer generated by C++ code is readable by the // generated Go code: @@ -99,6 +100,7 @@ func TestAll(t *testing.T) { } CheckReadBuffer(monsterDataCpp, 0, t.Fatalf) CheckMutateBuffer(monsterDataCpp, 0, t.Fatalf) + CheckObjectAPI(monsterDataCpp, 0, t.Fatalf) // Verify that vtables are deduplicated when written: CheckVtableDeduplication(t.Fatalf) @@ -448,6 +450,26 @@ func CheckMutateBuffer(org []byte, offset flatbuffers.UOffsetT, fail func(string } } +func CheckObjectAPI(buf []byte, offset flatbuffers.UOffsetT, fail func(string, ...interface{})) { + monster := example.GetRootAsMonster(buf, offset).UnPack() + + if got := monster.Hp; 80 != got { + fail(FailString("hp", 80, got)) + } + + // default + if got := monster.Mana; 150 != got { + fail(FailString("mana", 150, got)) + } + + builder := flatbuffers.NewBuilder(0) + builder.Finish(example.MonsterPack(builder, monster)) + monster2 := example.GetRootAsMonster(builder.FinishedBytes(), 0).UnPack() + if !reflect.DeepEqual(monster, monster2) { + fail(FailString("Pack/Unpack()", monster, monster2)) + } +} + // Low level stress/fuzz test: serialize/deserialize a variety of // different kinds of data in different combinations func checkFuzz(fuzzFields, fuzzObjects int, fail func(string, ...interface{})) {