[Go] Object API support (#5339)
authoriceboy <me@iceboy.org>
Thu, 31 Oct 2019 18:13:45 +0000 (11:13 -0700)
committerWouter van Oortmerssen <aardappel@gmail.com>
Thu, 31 Oct 2019 18:13:45 +0000 (11:13 -0700)
* 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

16 files changed:
src/idl_gen_go.cpp
tests/GoTest.sh
tests/MyGame/Example/Ability.go
tests/MyGame/Example/Any.go
tests/MyGame/Example/AnyAmbiguousAliases.go
tests/MyGame/Example/AnyUniqueAliases.go
tests/MyGame/Example/Monster.go
tests/MyGame/Example/Referrable.go
tests/MyGame/Example/Stat.go
tests/MyGame/Example/Test.go
tests/MyGame/Example/TestSimpleTableWithEnum.go
tests/MyGame/Example/TypeAliases.go
tests/MyGame/Example/Vec3.go
tests/MyGame/Example2/Monster.go
tests/MyGame/InParentNamespace.go
tests/go_test.go

index 5e62b61..b092e5e 100644 (file)
@@ -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);
index e69f0d8..60ef927 100755 (executable)
@@ -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
index a56b445..12ff1e5 100644 (file)
@@ -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
 }
index 8d9067e..7b9ffb9 100644 (file)
@@ -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
 
index b9c3793..cc4adb8 100644 (file)
@@ -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
 
index 23d8649..56b5163 100644 (file)
@@ -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
 
index 6199049..32be49f 100644 (file)
@@ -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
 }
index 0fb06fb..c2eb784 100644 (file)
@@ -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
 }
index 401712f..64ece1f 100644 (file)
@@ -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
 }
index 53f53fd..31110d9 100644 (file)
@@ -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
 }
index 35a6c7c..7af1edb 100644 (file)
@@ -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
 }
index d017b5b..497d574 100644 (file)
@@ -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
 }
index 9131afd..3a75c88 100644 (file)
@@ -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
 }
index d0fae94..b329d43 100644 (file)
@@ -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
 }
index fc6ce32..186666a 100644 (file)
@@ -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
 }
index 4784705..255b440 100644 (file)
@@ -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{})) {