/*
 * Copyright 2014 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// independent from idl_parser, since this code is not needed for most clients

#include "idl_gen_go.h"

#include <algorithm>
#include <cmath>
#include <sstream>
#include <string>

#include "flatbuffers/base.h"
#include "flatbuffers/code_generators.h"
#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"
#include "idl_namer.h"

#ifdef _WIN32
#include <direct.h>
#define PATH_SEPARATOR "\\"
#define mkdir(n, m) _mkdir(n)
#else
#include <sys/stat.h>
#define PATH_SEPARATOR "/"
#endif

namespace flatbuffers {

namespace go {

namespace {

// see https://golang.org/ref/spec#Keywords
static std::set<std::string> GoKeywords() {
  return {
      "break",    "default",     "func",   "interface", "select",
      "case",     "defer",       "go",     "map",       "struct",
      "chan",     "else",        "goto",   "package",   "switch",
      "const",    "fallthrough", "if",     "range",     "type",
      "continue", "for",         "import", "return",    "var",
  };
}

static Namer::Config GoDefaultConfig() {
  // Note that the functions with user defined types in the name use
  // upper camel case for all but the user defined type itself, which is keep
  // cased. Despite being a function, we interpret it as a Type.
  return {/*types=*/Case::kKeep,
          /*constants=*/Case::kUnknown,
          /*methods=*/Case::kUpperCamel,
          /*functions=*/Case::kUpperCamel,
          /*fields=*/Case::kUpperCamel,
          /*variables=*/Case::kLowerCamel,
          /*variants=*/Case::kKeep,
          /*enum_variant_seperator=*/"",  // I.e. Concatenate.
          /*escape_keywords=*/Namer::Config::Escape::AfterConvertingCase,
          /*namespaces=*/Case::kKeep,
          /*namespace_seperator=*/"__",
          /*object_prefix=*/"",
          /*object_suffix=*/"T",
          /*keyword_prefix=*/"",
          /*keyword_suffix=*/"_",
          /*filenames=*/Case::kKeep,
          /*directories=*/Case::kKeep,
          /*output_path=*/"",
          /*filename_suffix=*/"",
          /*filename_extension=*/".go"};
}

}  // namespace

class GoGenerator : public BaseGenerator {
 public:
  GoGenerator(const Parser& parser, const std::string& path,
              const std::string& file_name, const std::string& go_namespace)
      : BaseGenerator(parser, path, file_name, "" /* not used*/,
                      "" /* not used */, "go"),
        cur_name_space_(nullptr),
        namer_(WithFlagOptions(GoDefaultConfig(), parser.opts, path),
               GoKeywords()) {
    std::istringstream iss(go_namespace);
    std::string component;
    while (std::getline(iss, component, '.')) {
      go_namespace_.components.push_back(component);
    }
  }

  bool generate() {
    std::string one_file_code;

    if (!generateEnums(&one_file_code)) return false;
    if (!generateStructs(&one_file_code)) return false;

    if (parser_.opts.one_file) {
      std::string code = "";
      const bool is_enum = !parser_.enums_.vec.empty();
      BeginFile(LastNamespacePart(go_namespace_), true, is_enum, &code);
      code += one_file_code;
      const std::string filename =
          GeneratedFileName(path_, file_name_, parser_.opts);
      return SaveFile(filename.c_str(), code, false);
    }

    return true;
  }

 private:
  bool generateEnums(std::string* one_file_code) {
    bool needs_imports = false;
    for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
         ++it) {
      if (!parser_.opts.one_file) {
        needs_imports = false;
        ResetImports();
      }
      auto& enum_def = **it;
      std::string enumcode;
      GenEnum(enum_def, &enumcode);
      if (enum_def.is_union && parser_.opts.generate_object_based_api) {
        GenNativeUnionCreator(enum_def, &enumcode);
        needs_imports = true;
      }
      if (parser_.opts.one_file) {
        *one_file_code += enumcode;
      } else {
        if (!SaveType(enum_def, enumcode, needs_imports, true)) return false;
      }
    }
    return true;
  }

  void GenNativeUnionCreator(const EnumDef& enum_def, std::string* code_ptr) {
    if (enum_def.generated) return;

    GenNativeUnion(enum_def, code_ptr);
    GenNativeUnionPack(enum_def, code_ptr);
    GenNativeUnionUnPack(enum_def, code_ptr);
  }

  bool generateStructs(std::string* one_file_code) {
    for (auto it = parser_.structs_.vec.begin();
         it != parser_.structs_.vec.end(); ++it) {
      if (!parser_.opts.one_file) {
        ResetImports();
      }
      std::string declcode;
      auto& struct_def = **it;
      GenStruct(struct_def, &declcode);
      if (parser_.opts.one_file) {
        *one_file_code += declcode;
      } else {
        if (!SaveType(struct_def, declcode, true, false)) return false;
      }
    }
    return true;
  }

  Namespace go_namespace_;
  Namespace* cur_name_space_;
  const IdlNamer namer_;

  struct NamespacePtrLess {
    bool operator()(const Definition* a, const Definition* b) const {
      return *a->defined_namespace < *b->defined_namespace;
    }
  };
  std::set<const Definition*, NamespacePtrLess> tracked_imported_namespaces_;
  bool needs_math_import_ = false;
  bool needs_bytes_import_ = false;

  // Most field accessors need to retrieve and test the field offset first,
  // this is the prefix code for that.
  std::string OffsetPrefix(const FieldDef& field) {
    return "{\n\to := flatbuffers.UOffsetT(rcv._tab.Offset(" +
           NumToString(field.value.offset) + "))\n\tif o != 0 {\n";
  }

  // Begin a class declaration.
  void BeginClass(const StructDef& struct_def, std::string* code_ptr) {
    std::string& code = *code_ptr;

    code += "type " + namer_.Type(struct_def) + " struct {\n\t";

    // _ is reserved in flatbuffers field names, so no chance of name
    // conflict:
    code += "_tab ";
    code += struct_def.fixed ? "flatbuffers.Struct" : "flatbuffers.Table";
    code += "\n}\n\n";
  }

  // Construct the name of the type for this enum.
  std::string GetEnumTypeName(const EnumDef& enum_def) {
    return WrapInNameSpaceAndTrack(&enum_def, namer_.Type(enum_def));
  }

  // Create a type for the enum values.
  void GenEnumType(const EnumDef& enum_def, std::string* code_ptr) {
    std::string& code = *code_ptr;
    code += "type " + GetEnumTypeName(enum_def) + " ";
    code += GenTypeBasic(enum_def.underlying_type) + "\n\n";
  }

  // Begin enum code with a class declaration.
  void BeginEnum(std::string* code_ptr) {
    std::string& code = *code_ptr;
    code += "const (\n";
  }

  // A single enum member.
  void EnumMember(const EnumDef& enum_def, const EnumVal& ev,
                  size_t max_name_length, std::string* code_ptr) {
    std::string& code = *code_ptr;
    code += "\t";
    code += namer_.EnumVariant(enum_def, ev);
    code += " ";
    code += std::string(max_name_length - ev.name.length(), ' ');
    code += GetEnumTypeName(enum_def);
    code += " = ";
    code += enum_def.ToString(ev) + "\n";
  }

  // End enum code.
  void EndEnum(std::string* code_ptr) {
    std::string& code = *code_ptr;
    code += ")\n\n";
  }

  // Begin enum name map.
  void BeginEnumNames(const EnumDef& enum_def, std::string* code_ptr) {
    std::string& code = *code_ptr;
    code += "var EnumNames";
    code += enum_def.name;
    code += " = map[" + GetEnumTypeName(enum_def) + "]string{\n";
  }

  // A single enum name member.
  void EnumNameMember(const EnumDef& enum_def, const EnumVal& ev,
                      size_t max_name_length, std::string* code_ptr) {
    std::string& code = *code_ptr;
    code += "\t";
    code += namer_.EnumVariant(enum_def, ev);
    code += ": ";
    code += std::string(max_name_length - ev.name.length(), ' ');
    code += "\"";
    code += ev.name;
    code += "\",\n";
  }

  // End enum name map.
  void EndEnumNames(std::string* code_ptr) {
    std::string& code = *code_ptr;
    code += "}\n\n";
  }

  // Generate String() method on enum type.
  void EnumStringer(const EnumDef& enum_def, std::string* code_ptr) {
    std::string& code = *code_ptr;
    const std::string enum_type = namer_.Type(enum_def);
    code += "func (v " + enum_type + ") String() string {\n";
    code += "\tif s, ok := EnumNames" + enum_type + "[v]; ok {\n";
    code += "\t\treturn s\n";
    code += "\t}\n";
    code += "\treturn \"" + enum_def.name;
    code += "(\" + strconv.FormatInt(int64(v), 10) + \")\"\n";
    code += "}\n\n";
  }

  // Begin enum value map.
  void BeginEnumValues(const EnumDef& enum_def, std::string* code_ptr) {
    std::string& code = *code_ptr;
    code += "var EnumValues";
    code += namer_.Type(enum_def);
    code += " = map[string]" + GetEnumTypeName(enum_def) + "{\n";
  }

  // A single enum value member.
  void EnumValueMember(const EnumDef& enum_def, const EnumVal& ev,
                       size_t max_name_length, std::string* code_ptr) {
    std::string& code = *code_ptr;
    code += "\t\"";
    code += ev.name;
    code += "\": ";
    code += std::string(max_name_length - ev.name.length(), ' ');
    code += namer_.EnumVariant(enum_def, ev);
    code += ",\n";
  }

  // End enum value map.
  void EndEnumValues(std::string* code_ptr) {
    std::string& code = *code_ptr;
    code += "}\n\n";
  }

  // Initialize a new struct or table from existing data.
  void NewRootTypeFromBuffer(const StructDef& struct_def,
                             std::string* code_ptr) {
    std::string& code = *code_ptr;
    const std::string size_prefix[] = {"", "SizePrefixed"};
    const std::string struct_type = namer_.Type(struct_def);

    bool has_file_identifier = (parser_.root_struct_def_ == &struct_def) &&
                               parser_.file_identifier_.length();

    if (has_file_identifier) {
      code += "const " + struct_type + "Identifier = \"" +
              parser_.file_identifier_ + "\"\n\n";
    }

    for (int i = 0; i < 2; i++) {
      code += "func Get" + size_prefix[i] + "RootAs" + struct_type;
      code += "(buf []byte, offset flatbuffers.UOffsetT) ";
      code += "*" + struct_type + "";
      code += " {\n";
      if (i == 0) {
        code += "\tn := flatbuffers.GetUOffsetT(buf[offset:])\n";
      } else {
        code +=
            "\tn := "
            "flatbuffers.GetUOffsetT(buf[offset+flatbuffers.SizeUint32:])\n";
      }
      code += "\tx := &" + struct_type + "{}\n";
      if (i == 0) {
        code += "\tx.Init(buf, n+offset)\n";
      } else {
        code += "\tx.Init(buf, n+offset+flatbuffers.SizeUint32)\n";
      }
      code += "\treturn x\n";
      code += "}\n\n";

      code += "func Finish" + size_prefix[i] + struct_type +
              "Buffer(builder *flatbuffers.Builder, offset "
              "flatbuffers.UOffsetT) {\n";
      if (has_file_identifier) {
        code += "\tidentifierBytes := []byte(" + struct_type + "Identifier)\n";
        code += "\tbuilder.Finish" + size_prefix[i] +
                "WithFileIdentifier(offset, identifierBytes)\n";
      } else {
        code += "\tbuilder.Finish" + size_prefix[i] + "(offset)\n";
      }
      code += "}\n\n";

      if (has_file_identifier) {
        code += "func " + size_prefix[i] + struct_type +
                "BufferHasIdentifier(buf []byte) bool {\n";
        code += "\treturn flatbuffers." + size_prefix[i] +
                "BufferHasIdentifier(buf, " + struct_type + "Identifier)\n";
        code += "}\n\n";
      }
    }
  }

  // Initialize an existing object with other data, to avoid an allocation.
  void InitializeExisting(const StructDef& struct_def, std::string* code_ptr) {
    std::string& code = *code_ptr;

    GenReceiver(struct_def, code_ptr);
    code += " Init(buf []byte, i flatbuffers.UOffsetT) ";
    code += "{\n";
    code += "\trcv._tab.Bytes = buf\n";
    code += "\trcv._tab.Pos = i\n";
    code += "}\n\n";
  }

  // Implement the table accessor
  void GenTableAccessor(const StructDef& struct_def, std::string* code_ptr) {
    std::string& code = *code_ptr;

    GenReceiver(struct_def, code_ptr);
    code += " Table() flatbuffers.Table ";
    code += "{\n";

    if (struct_def.fixed) {
      code += "\treturn rcv._tab.Table\n";
    } else {
      code += "\treturn rcv._tab\n";
    }
    code += "}\n\n";
  }

  // Get the length of a vector.
  void GetVectorLen(const StructDef& struct_def, const FieldDef& field,
                    std::string* code_ptr) {
    std::string& code = *code_ptr;

    GenReceiver(struct_def, code_ptr);
    code += " " + namer_.Function(field) + "Length(";
    code += ") int " + OffsetPrefix(field);
    code += "\t\treturn rcv._tab.VectorLen(o)\n\t}\n";
    code += "\treturn 0\n}\n\n";
  }

  // Get a [ubyte] vector as a byte slice.
  void GetUByteSlice(const StructDef& struct_def, const FieldDef& field,
                     std::string* code_ptr) {
    std::string& code = *code_ptr;

    GenReceiver(struct_def, code_ptr);
    code += " " + namer_.Function(field) + "Bytes(";
    code += ") []byte " + OffsetPrefix(field);
    code += "\t\treturn rcv._tab.ByteVector(o + rcv._tab.Pos)\n\t}\n";
    code += "\treturn nil\n}\n\n";
  }

  // Get the value of a struct's scalar.
  void GetScalarFieldOfStruct(const StructDef& struct_def,
                              const FieldDef& field, std::string* code_ptr) {
    std::string& code = *code_ptr;
    std::string getter = GenGetter(field.value.type);
    GenReceiver(struct_def, code_ptr);
    code += " " + namer_.Function(field);
    code += "() " + TypeName(field) + " {\n";
    code += "\treturn " +
            CastToEnum(field.value.type,
                       getter + "(rcv._tab.Pos + flatbuffers.UOffsetT(" +
                           NumToString(field.value.offset) + "))");
    code += "\n}\n";
  }

  // Get the value of a table's scalar.
  void GetScalarFieldOfTable(const StructDef& struct_def, const FieldDef& field,
                             std::string* code_ptr) {
    std::string& code = *code_ptr;
    std::string getter = GenGetter(field.value.type);
    GenReceiver(struct_def, code_ptr);
    code += " " + namer_.Function(field);
    code += "() " + TypeName(field) + " ";
    code += OffsetPrefix(field);
    if (field.IsScalarOptional()) {
      code += "\t\tv := ";
    } else {
      code += "\t\treturn ";
    }
    code += CastToEnum(field.value.type, getter + "(o + rcv._tab.Pos)");
    if (field.IsScalarOptional()) {
      code += "\n\t\treturn &v";
    }
    code += "\n\t}\n";
    code += "\treturn " + GenConstant(field) + "\n";
    code += "}\n\n";
  }

  // Get a struct by initializing an existing struct.
  // Specific to Struct.
  void GetStructFieldOfStruct(const StructDef& struct_def,
                              const FieldDef& field, std::string* code_ptr) {
    std::string& code = *code_ptr;
    GenReceiver(struct_def, code_ptr);
    code += " " + namer_.Function(field);
    code += "(obj *" + TypeName(field);
    code += ") *" + TypeName(field);
    code += " {\n";
    code += "\tif obj == nil {\n";
    code += "\t\tobj = new(" + TypeName(field) + ")\n";
    code += "\t}\n";
    code += "\tobj.Init(rcv._tab.Bytes, rcv._tab.Pos+";
    code += NumToString(field.value.offset) + ")";
    code += "\n\treturn obj\n";
    code += "}\n";
  }

  // Get a struct by initializing an existing struct.
  // Specific to Table.
  void GetStructFieldOfTable(const StructDef& struct_def, const FieldDef& field,
                             std::string* code_ptr) {
    std::string& code = *code_ptr;
    GenReceiver(struct_def, code_ptr);
    code += " " + namer_.Function(field);
    code += "(obj *";
    code += TypeName(field);
    code += ") *" + TypeName(field) + " " + OffsetPrefix(field);
    if (field.value.type.struct_def->fixed) {
      code += "\t\tx := o + rcv._tab.Pos\n";
    } else {
      code += "\t\tx := rcv._tab.Indirect(o + rcv._tab.Pos)\n";
    }
    code += "\t\tif obj == nil {\n";
    code += "\t\t\tobj = new(" + TypeName(field) + ")\n";
    code += "\t\t}\n";
    code += "\t\tobj.Init(rcv._tab.Bytes, x)\n";
    code += "\t\treturn obj\n\t}\n\treturn nil\n";
    code += "}\n\n";
  }

  // Get the value of a string.
  void GetStringField(const StructDef& struct_def, const FieldDef& field,
                      std::string* code_ptr) {
    std::string& code = *code_ptr;
    GenReceiver(struct_def, code_ptr);
    code += " " + namer_.Function(field);
    code += "() " + TypeName(field) + " ";
    code += OffsetPrefix(field) + "\t\treturn " + GenGetter(field.value.type);
    code += "(o + rcv._tab.Pos)\n\t}\n\treturn nil\n";
    code += "}\n\n";
  }

  // Get the value of a union from an object.
  void GetUnionField(const StructDef& struct_def, const FieldDef& field,
                     std::string* code_ptr) {
    std::string& code = *code_ptr;
    GenReceiver(struct_def, code_ptr);
    code += " " + namer_.Function(field) + "(";
    code += "obj " + GenTypePointer(field.value.type) + ") bool ";
    code += OffsetPrefix(field);
    code += "\t\t" + GenGetter(field.value.type);
    code += "(obj, o)\n\t\treturn true\n\t}\n";
    code += "\treturn false\n";
    code += "}\n\n";
  }

  // Get the value of a vector's struct member.
  void GetMemberOfVectorOfStruct(const StructDef& struct_def,
                                 const FieldDef& field, std::string* code_ptr) {
    std::string& code = *code_ptr;
    auto vectortype = field.value.type.VectorType();

    GenReceiver(struct_def, code_ptr);
    code += " " + namer_.Function(field);
    code += "(obj *" + TypeName(field);
    code += ", j int) bool " + OffsetPrefix(field);
    code += "\t\tx := rcv._tab.Vector(o)\n";
    code += "\t\tx += flatbuffers.UOffsetT(j) * ";
    code += NumToString(InlineSize(vectortype)) + "\n";
    if (!(vectortype.struct_def->fixed)) {
      code += "\t\tx = rcv._tab.Indirect(x)\n";
    }
    code += "\t\tobj.Init(rcv._tab.Bytes, x)\n";
    code += "\t\treturn true\n\t}\n";
    code += "\treturn false\n";
    code += "}\n\n";
  }

  void GetMemberOfVectorOfStructByKey(const StructDef& struct_def,
                                      const FieldDef& field,
                                      std::string* code_ptr) {
    std::string& code = *code_ptr;
    auto vectortype = field.value.type.VectorType();
    FLATBUFFERS_ASSERT(vectortype.struct_def->has_key);

    auto& vector_struct_fields = vectortype.struct_def->fields.vec;
    auto kit =
        std::find_if(vector_struct_fields.begin(), vector_struct_fields.end(),
                     [&](FieldDef* vector_struct_field) {
                       return vector_struct_field->key;
                     });

    auto& key_field = **kit;
    FLATBUFFERS_ASSERT(key_field.key);

    GenReceiver(struct_def, code_ptr);
    code += " " + namer_.Field(field) + "ByKey";
    code += "(obj *" + TypeName(field);
    code += ", key " + NativeType(key_field.value.type) + ") bool " +
            OffsetPrefix(field);
    code += "\t\tx := rcv._tab.Vector(o)\n";
    code += "\t\treturn ";
    code += "obj.LookupByKey(key, x, rcv._tab.Bytes)\n";
    code += "\t}\n";
    code += "\treturn false\n";
    code += "}\n\n";
  }

  // Get the value of a vector's non-struct member.
  void GetMemberOfVectorOfNonStruct(const StructDef& struct_def,
                                    const FieldDef& field,
                                    std::string* code_ptr) {
    std::string& code = *code_ptr;
    auto vectortype = field.value.type.VectorType();

    GenReceiver(struct_def, code_ptr);
    code += " " + namer_.Function(field);
    code += "(j int) " + TypeName(field) + " ";
    code += OffsetPrefix(field);
    code += "\t\ta := rcv._tab.Vector(o)\n";
    code += "\t\treturn " +
            CastToEnum(field.value.type,
                       GenGetter(field.value.type) +
                           "(a + flatbuffers.UOffsetT(j*" +
                           NumToString(InlineSize(vectortype)) + "))");
    code += "\n\t}\n";
    if (IsString(vectortype)) {
      code += "\treturn nil\n";
    } else if (vectortype.base_type == BASE_TYPE_BOOL) {
      code += "\treturn false\n";
    } else {
      code += "\treturn 0\n";
    }
    code += "}\n\n";
  }

  // Begin the creator function signature.
  void BeginBuilderArgs(const StructDef& struct_def, std::string* code_ptr) {
    std::string& code = *code_ptr;

    if (code.substr(code.length() - 2) != "\n\n") {
      // a previous mutate has not put an extra new line
      code += "\n";
    }
    code += "func Create" + struct_def.name;
    code += "(builder *flatbuffers.Builder";
  }

  // Recursively generate arguments for a constructor, to deal with nested
  // structs.
  void StructBuilderArgs(const StructDef& struct_def, const char* nameprefix,
                         std::string* code_ptr) {
    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      auto& field = **it;
      if (IsStruct(field.value.type)) {
        // Generate arguments for a struct inside a struct. To ensure names
        // don't clash, and to make it obvious these arguments are constructing
        // a nested struct, prefix the name with the field name.
        StructBuilderArgs(*field.value.type.struct_def,
                          (nameprefix + (field.name + "_")).c_str(), code_ptr);
      } else {
        std::string& code = *code_ptr;
        code += std::string(", ") + nameprefix;
        code += namer_.Variable(field);
        code += " " + TypeName(field);
      }
    }
  }

  // End the creator function signature.
  void EndBuilderArgs(std::string* code_ptr) {
    std::string& code = *code_ptr;
    code += ") flatbuffers.UOffsetT {\n";
  }

  // Recursively generate struct construction statements and instert manual
  // padding.
  void StructBuilderBody(const StructDef& struct_def, const char* nameprefix,
                         std::string* code_ptr) {
    std::string& code = *code_ptr;
    code += "\tbuilder.Prep(" + NumToString(struct_def.minalign) + ", ";
    code += NumToString(struct_def.bytesize) + ")\n";
    for (auto it = struct_def.fields.vec.rbegin();
         it != struct_def.fields.vec.rend(); ++it) {
      auto& field = **it;
      if (field.padding)
        code += "\tbuilder.Pad(" + NumToString(field.padding) + ")\n";
      if (IsStruct(field.value.type)) {
        StructBuilderBody(*field.value.type.struct_def,
                          (nameprefix + (field.name + "_")).c_str(), code_ptr);
      } else {
        code += "\tbuilder.Prepend" + GenMethod(field) + "(";
        code += CastToBaseType(field.value.type,
                               nameprefix + namer_.Variable(field)) +
                ")\n";
      }
    }
  }

  void EndBuilderBody(std::string* code_ptr) {
    std::string& code = *code_ptr;
    code += "\treturn builder.Offset()\n";
    code += "}\n";
  }

  // Get the value of a table's starting offset.
  void GetStartOfTable(const StructDef& struct_def, std::string* code_ptr) {
    std::string& code = *code_ptr;
    code += "func " + namer_.Type(struct_def) + "Start";
    code += "(builder *flatbuffers.Builder) {\n";
    code += "\tbuilder.StartObject(";
    code += NumToString(struct_def.fields.vec.size());
    code += ")\n}\n";
  }

  // Set the value of a table's field.
  void BuildFieldOfTable(const StructDef& struct_def, const FieldDef& field,
                         const size_t offset, std::string* code_ptr) {
    std::string& code = *code_ptr;
    const std::string field_var = namer_.Variable(field);
    code += "func " + namer_.Type(struct_def) + "Add" + namer_.Function(field);
    code += "(builder *flatbuffers.Builder, ";
    code += field_var + " ";
    if (!IsScalar(field.value.type.base_type) && (!struct_def.fixed)) {
      code += "flatbuffers.UOffsetT";
    } else {
      code += GenTypeGet(field.value.type);
    }
    code += ") {\n\t";
    code += "builder.Prepend";
    code += GenMethod(field);
    if (field.IsScalarOptional()) {
      code += "(";
    } else {
      code += "Slot(" + NumToString(offset) + ", ";
    }
    if (!IsScalar(field.value.type.base_type) && (!struct_def.fixed)) {
      code += "flatbuffers.UOffsetT";
      code += "(" + field_var + ")";
    } else {
      code += CastToBaseType(field.value.type, field_var);
    }
    if (field.IsScalarOptional()) {
      code += ")\n";
      code += "\tbuilder.Slot(" + NumToString(offset);
    } else {
      code += ", " + GenConstant(field);
    }
    code += ")\n";
    code += "}\n";
  }

  // Set the value of one of the members of a table's vector.
  void BuildVectorOfTable(const StructDef& struct_def, const FieldDef& field,
                          std::string* code_ptr) {
    std::string& code = *code_ptr;
    code += "func " + namer_.Type(struct_def) + "Start";
    code += namer_.Function(field);
    code += "Vector(builder *flatbuffers.Builder, numElems int) ";
    code += "flatbuffers.UOffsetT {\n\treturn builder.StartVector(";
    auto vector_type = field.value.type.VectorType();
    auto alignment = InlineAlignment(vector_type);
    auto elem_size = InlineSize(vector_type);
    code += NumToString(elem_size);
    code += ", numElems, " + NumToString(alignment);
    code += ")\n}\n";
  }

  // Get the offset of the end of a table.
  void GetEndOffsetOnTable(const StructDef& struct_def, std::string* code_ptr) {
    std::string& code = *code_ptr;
    code += "func " + namer_.Type(struct_def) + "End";
    code += "(builder *flatbuffers.Builder) flatbuffers.UOffsetT ";
    code += "{\n\treturn builder.EndObject()\n}\n";
  }

  // Generate the receiver for function signatures.
  void GenReceiver(const StructDef& struct_def, std::string* code_ptr) {
    std::string& code = *code_ptr;
    code += "func (rcv *" + namer_.Type(struct_def) + ")";
  }

  // Generate a struct field getter, conditioned on its child type(s).
  void GenStructAccessor(const StructDef& struct_def, const FieldDef& field,
                         std::string* code_ptr) {
    GenComment(field.doc_comment, code_ptr, nullptr, "");
    if (IsScalar(field.value.type.base_type)) {
      if (struct_def.fixed) {
        GetScalarFieldOfStruct(struct_def, field, code_ptr);
      } else {
        GetScalarFieldOfTable(struct_def, field, code_ptr);
      }
    } else {
      switch (field.value.type.base_type) {
        case BASE_TYPE_STRUCT:
          if (struct_def.fixed) {
            GetStructFieldOfStruct(struct_def, field, code_ptr);
          } else {
            GetStructFieldOfTable(struct_def, field, code_ptr);
          }
          break;
        case BASE_TYPE_STRING:
          GetStringField(struct_def, field, code_ptr);
          break;
        case BASE_TYPE_VECTOR: {
          auto vectortype = field.value.type.VectorType();
          if (vectortype.base_type == BASE_TYPE_STRUCT) {
            GetMemberOfVectorOfStruct(struct_def, field, code_ptr);
            // TODO(michaeltle): Support querying fixed struct by key.
            // Currently, we only support keyed tables.
            if (!vectortype.struct_def->fixed &&
                vectortype.struct_def->has_key) {
              GetMemberOfVectorOfStructByKey(struct_def, field, code_ptr);
            }
          } else {
            GetMemberOfVectorOfNonStruct(struct_def, field, code_ptr);
          }
          break;
        }
        case BASE_TYPE_UNION:
          GetUnionField(struct_def, field, code_ptr);
          break;
        default:
          FLATBUFFERS_ASSERT(0);
      }
    }
    if (IsVector(field.value.type)) {
      GetVectorLen(struct_def, field, code_ptr);
      if (field.value.type.element == BASE_TYPE_UCHAR) {
        GetUByteSlice(struct_def, field, code_ptr);
      }
    }
  }

  // Mutate the value of a struct's scalar.
  void MutateScalarFieldOfStruct(const StructDef& struct_def,
                                 const FieldDef& field, std::string* code_ptr) {
    std::string& code = *code_ptr;
    std::string setter =
        "rcv._tab.Mutate" + namer_.Method(GenTypeBasic(field.value.type));
    GenReceiver(struct_def, code_ptr);
    code += " Mutate" + namer_.Function(field);
    code +=
        "(n " + GenTypeGet(field.value.type) + ") bool {\n\treturn " + setter;
    code += "(rcv._tab.Pos+flatbuffers.UOffsetT(";
    code += NumToString(field.value.offset) + "), ";
    code += CastToBaseType(field.value.type, "n") + ")\n}\n\n";
  }

  // Mutate the value of a table's scalar.
  void MutateScalarFieldOfTable(const StructDef& struct_def,
                                const FieldDef& field, std::string* code_ptr) {
    std::string& code = *code_ptr;
    std::string setter = "rcv._tab.Mutate" +
                         namer_.Method(GenTypeBasic(field.value.type)) + "Slot";
    GenReceiver(struct_def, code_ptr);
    code += " Mutate" + namer_.Function(field);
    code += "(n " + GenTypeGet(field.value.type) + ") bool {\n\treturn ";
    code += setter + "(" + NumToString(field.value.offset) + ", ";
    code += CastToBaseType(field.value.type, "n") + ")\n";
    code += "}\n\n";
  }

  // Mutate an element of a vector of scalars.
  void MutateElementOfVectorOfNonStruct(const StructDef& struct_def,
                                        const FieldDef& field,
                                        std::string* code_ptr) {
    std::string& code = *code_ptr;
    auto vectortype = field.value.type.VectorType();
    std::string setter =
        "rcv._tab.Mutate" + namer_.Method(GenTypeBasic(vectortype));
    GenReceiver(struct_def, code_ptr);
    code += " Mutate" + namer_.Function(field);
    code += "(j int, n " + TypeName(field) + ") bool ";
    code += OffsetPrefix(field);
    code += "\t\ta := rcv._tab.Vector(o)\n";
    code += "\t\treturn " + setter + "(";
    code += "a+flatbuffers.UOffsetT(j*";
    code += NumToString(InlineSize(vectortype)) + "), ";
    code += CastToBaseType(vectortype, "n") + ")\n";
    code += "\t}\n";
    code += "\treturn false\n";
    code += "}\n\n";
  }

  // Generate a struct field setter, conditioned on its child type(s).
  void GenStructMutator(const StructDef& struct_def, const FieldDef& field,
                        std::string* code_ptr) {
    GenComment(field.doc_comment, code_ptr, nullptr, "");
    if (IsScalar(field.value.type.base_type)) {
      if (struct_def.fixed) {
        MutateScalarFieldOfStruct(struct_def, field, code_ptr);
      } else {
        MutateScalarFieldOfTable(struct_def, field, code_ptr);
      }
    } else if (IsVector(field.value.type)) {
      if (IsScalar(field.value.type.element)) {
        MutateElementOfVectorOfNonStruct(struct_def, field, code_ptr);
      }
    }
  }

  // Generate table constructors, conditioned on its members' types.
  void GenTableBuilders(const StructDef& struct_def, std::string* code_ptr) {
    GetStartOfTable(struct_def, code_ptr);

    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      auto& field = **it;
      if (field.deprecated) continue;

      auto offset = it - struct_def.fields.vec.begin();
      BuildFieldOfTable(struct_def, field, offset, code_ptr);
      if (IsVector(field.value.type)) {
        BuildVectorOfTable(struct_def, field, code_ptr);
      }
    }

    GetEndOffsetOnTable(struct_def, code_ptr);
  }

  // Generate struct or table methods.
  void GenStruct(const StructDef& struct_def, std::string* code_ptr) {
    if (struct_def.generated) return;

    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
      // the root type.
      NewRootTypeFromBuffer(struct_def, code_ptr);
    }
    // Generate the Init method that sets the field in a pre-existing
    // accessor object. This is to allow object reuse.
    InitializeExisting(struct_def, code_ptr);
    // Generate _tab accessor
    GenTableAccessor(struct_def, code_ptr);

    // Generate struct fields accessors
    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      auto& field = **it;
      if (field.deprecated) continue;

      GenStructAccessor(struct_def, field, code_ptr);
      GenStructMutator(struct_def, field, code_ptr);
      // TODO(michaeltle): Support querying fixed struct by key. Currently,
      // we only support keyed tables.
      if (!struct_def.fixed && field.key) {
        GenKeyCompare(struct_def, field, code_ptr);
        GenLookupByKey(struct_def, field, code_ptr);
      }
    }

    // Generate builders
    if (struct_def.fixed) {
      // create a struct constructor function
      GenStructBuilder(struct_def, code_ptr);
    } else {
      // Create a set of functions that allow table construction.
      GenTableBuilders(struct_def, code_ptr);
    }
  }

  void GenKeyCompare(const StructDef& struct_def, const FieldDef& field,
                     std::string* code_ptr) {
    FLATBUFFERS_ASSERT(struct_def.has_key);
    FLATBUFFERS_ASSERT(field.key);
    std::string& code = *code_ptr;

    code += "func " + namer_.Type(struct_def) + "KeyCompare(";
    code += "o1, o2 flatbuffers.UOffsetT, buf []byte) bool {\n";
    code += "\tobj1 := &" + namer_.Type(struct_def) + "{}\n";
    code += "\tobj2 := &" + namer_.Type(struct_def) + "{}\n";
    code += "\tobj1.Init(buf, flatbuffers.UOffsetT(len(buf))-o1)\n";
    code += "\tobj2.Init(buf, flatbuffers.UOffsetT(len(buf))-o2)\n";
    if (IsString(field.value.type)) {
      code += "\treturn string(obj1." + namer_.Function(field.name) + "()) < ";
      code += "string(obj2." + namer_.Function(field.name) + "())\n";
    } else {
      code += "\treturn obj1." + namer_.Function(field.name) + "() < ";
      code += "obj2." + namer_.Function(field.name) + "()\n";
    }
    code += "}\n\n";
  }

  void GenLookupByKey(const StructDef& struct_def, const FieldDef& field,
                      std::string* code_ptr) {
    FLATBUFFERS_ASSERT(struct_def.has_key);
    FLATBUFFERS_ASSERT(field.key);
    std::string& code = *code_ptr;

    GenReceiver(struct_def, code_ptr);
    code += " LookupByKey(";
    code += "key " + NativeType(field.value.type) + ", ";
    code += "vectorLocation flatbuffers.UOffsetT, ";
    code += "buf []byte) bool {\n";
    code += "\tspan := flatbuffers.GetUOffsetT(buf[vectorLocation-4:])\n";
    code += "\tstart := flatbuffers.UOffsetT(0)\n";
    if (IsString(field.value.type)) {
      code += "\tbKey := []byte(key)\n";
    }
    code += "\tfor span != 0 {\n";
    code += "\t\tmiddle := span / 2\n";
    code += "\t\ttableOffset := flatbuffers.GetIndirectOffset(buf, ";
    code += "vectorLocation+4*(start+middle))\n";

    code += "\t\tobj := &" + namer_.Type(struct_def) + "{}\n";
    code += "\t\tobj.Init(buf, tableOffset)\n";

    if (IsString(field.value.type)) {
      needs_bytes_import_ = true;
      code +=
          "\t\tcomp := bytes.Compare(obj." + namer_.Function(field.name) + "()";
      code += ", bKey)\n";
    } else {
      code += "\t\tval := obj." + namer_.Function(field.name) + "()\n";
      code += "\t\tcomp := 0\n";
      code += "\t\tif val > key {\n";
      code += "\t\t\tcomp = 1\n";
      code += "\t\t} else if val < key {\n";
      code += "\t\t\tcomp = -1\n";
      code += "\t\t}\n";
    }
    code += "\t\tif comp > 0 {\n";
    code += "\t\t\tspan = middle\n";
    code += "\t\t} else if comp < 0 {\n";
    code += "\t\t\tmiddle += 1\n";
    code += "\t\t\tstart += middle\n";
    code += "\t\t\tspan -= middle\n";
    code += "\t\t} else {\n";
    code += "\t\t\trcv.Init(buf, tableOffset)\n";
    code += "\t\t\treturn true\n";
    code += "\t\t}\n";
    code += "\t}\n";
    code += "\treturn false\n";
    code += "}\n\n";
  }

  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" + namer_.Field(field) + " ";
      if (field.IsScalarOptional()) {
        code += "*";
      }
      code += NativeType(field.value.type) + " `json:\"" + field.name + "\"`" +
              "\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) {
    if (enum_def.generated) return;

    std::string& code = *code_ptr;
    code += "type " + NativeName(enum_def) + " struct {\n";
    code += "\tType " + namer_.Type(enum_def) + "\n";
    code += "\tValue interface{}\n";
    code += "}\n\n";
  }

  void GenNativeUnionPack(const EnumDef& enum_def, std::string* code_ptr) {
    if (enum_def.generated) return;

    std::string& code = *code_ptr;
    code += "func (t *" + NativeName(enum_def) +
            ") Pack(builder *flatbuffers.Builder) 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 " + namer_.EnumVariant(enum_def, ev) + ":\n";
      code += "\t\treturn t.Value.(" + NativeType(ev.union_type) +
              ").Pack(builder)\n";
    }
    code += "\t}\n";
    code += "\treturn 0\n";
    code += "}\n\n";
  }

  void GenNativeUnionUnPack(const EnumDef& enum_def, std::string* code_ptr) {
    if (enum_def.generated) return;

    std::string& code = *code_ptr;

    code += "func (rcv " + namer_.Type(enum_def) +
            ") UnPack(table flatbuffers.Table) *" + NativeName(enum_def) +
            " {\n";
    code += "\tswitch rcv {\n";

    for (auto it2 = enum_def.Vals().begin(); it2 != enum_def.Vals().end();
         ++it2) {
      const EnumVal& ev = **it2;
      if (ev.IsZero()) continue;
      code += "\tcase " + namer_.EnumVariant(enum_def, ev) + ":\n";
      code += "\t\tvar x " +
              WrapInNameSpaceAndTrack(ev.union_type.struct_def,
                                      ev.union_type.struct_def->name) +
              "\n";
      code += "\t\tx.Init(table.Bytes, table.Pos)\n";

      code += "\t\treturn &" +
              WrapInNameSpaceAndTrack(&enum_def, NativeName(enum_def)) +
              "{Type: " + namer_.EnumVariant(enum_def, ev) +
              ", 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;
    const std::string struct_type = namer_.Type(struct_def);

    code += "func (t *" + NativeName(struct_def) +
            ") Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {\n";
    code += "\tif t == nil {\n\t\treturn 0\n\t}\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;

      const std::string field_field = namer_.Field(field);
      const std::string field_var = namer_.Variable(field);
      const std::string offset = field_var + "Offset";

      if (IsString(field.value.type)) {
        code += "\t" + offset + " := flatbuffers.UOffsetT(0)\n";
        code += "\tif t." + field_field + " != \"\" {\n";
        code += "\t\t" + offset + " = builder.CreateString(t." + field_field +
                ")\n";
        code += "\t}\n";
      } else if (IsVector(field.value.type) &&
                 field.value.type.element == BASE_TYPE_UCHAR &&
                 field.value.type.enum_def == nullptr) {
        code += "\t" + offset + " := flatbuffers.UOffsetT(0)\n";
        code += "\tif t." + field_field + " != nil {\n";
        code += "\t\t" + offset + " = builder.CreateByteString(t." +
                field_field + ")\n";
        code += "\t}\n";
      } else if (IsVector(field.value.type)) {
        code += "\t" + offset + " := flatbuffers.UOffsetT(0)\n";
        code += "\tif t." + field_field + " != nil {\n";
        std::string length = field_var + "Length";
        std::string offsets = field_var + "Offsets";
        code += "\t\t" + length + " := len(t." + field_field + ")\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." +
                  field_field + "[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] = t." + field_field +
                  "[j].Pack(builder)\n";
          code += "\t\t}\n";
        }
        code += "\t\t" + struct_type + "Start" + namer_.Function(field) +
                "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" +
                  namer_.Method(GenTypeBasic(field.value.type.VectorType())) +
                  "(" +
                  CastToBaseType(field.value.type.VectorType(),
                                 "t." + field_field + "[j]") +
                  ")\n";
        } else if (field.value.type.element == BASE_TYPE_STRUCT &&
                   field.value.type.struct_def->fixed) {
          code += "\t\t\tt." + field_field + "[j].Pack(builder)\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 + " := t." + field_field + ".Pack(builder)\n";
      } else if (field.value.type.base_type == BASE_TYPE_UNION) {
        code += "\t" + offset + " := t." + field_field + ".Pack(builder)\n\n";
      } else {
        FLATBUFFERS_ASSERT(0);
      }
    }
    code += "\t" + struct_type + "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;
      const std::string field_field = namer_.Field(field);
      const std::string field_fn = namer_.Function(field);
      const std::string offset = namer_.Variable(field) + "Offset";

      if (IsScalar(field.value.type.base_type)) {
        std::string prefix;
        if (field.IsScalarOptional()) {
          code += "\tif t." + field_field + " != nil {\n\t";
          prefix = "*";
        }
        if (field.value.type.enum_def == nullptr ||
            !field.value.type.enum_def->is_union) {
          code += "\t" + struct_type + "Add" + field_fn + "(builder, " +
                  prefix + "t." + field_field + ")\n";
        }
        if (field.IsScalarOptional()) {
          code += "\t}\n";
        }
      } else {
        if (field.value.type.base_type == BASE_TYPE_STRUCT &&
            field.value.type.struct_def->fixed) {
          code += "\t" + offset + " := t." + field_field + ".Pack(builder)\n";
        } else if (field.value.type.enum_def != nullptr &&
                   field.value.type.enum_def->is_union) {
          code += "\tif t." + field_field + " != nil {\n";
          code += "\t\t" + struct_type + "Add" +
                  namer_.Method(field.name + UnionTypeFieldSuffix()) +
                  "(builder, t." + field_field + ".Type)\n";
          code += "\t}\n";
        }
        code += "\t" + struct_type + "Add" + field_fn + "(builder, " + offset +
                ")\n";
      }
    }
    code += "\treturn " + struct_type + "End(builder)\n";
    code += "}\n\n";
  }

  void GenNativeTableUnPack(const StructDef& struct_def,
                            std::string* code_ptr) {
    std::string& code = *code_ptr;
    const std::string struct_type = namer_.Type(struct_def);

    code += "func (rcv *" + struct_type + ") UnPackTo(t *" +
            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;
      const std::string field_field = namer_.Field(field);
      const std::string field_var = namer_.Variable(field);
      const std::string length = field_var + "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_field + " = rcv." + field_field + "()\n";
      } else if (IsString(field.value.type)) {
        code += "\tt." + field_field + " = string(rcv." + field_field + "())\n";
      } else if (IsVector(field.value.type) &&
                 field.value.type.element == BASE_TYPE_UCHAR &&
                 field.value.type.enum_def == nullptr) {
        code += "\tt." + field_field + " = rcv." + field_field + "Bytes()\n";
      } else if (IsVector(field.value.type)) {
        code += "\t" + length + " := rcv." + field_field + "Length()\n";
        code += "\tt." + field_field + " = 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 := " +
                  WrapInNameSpaceAndTrack(field.value.type.struct_def,
                                          field.value.type.struct_def->name) +
                  "{}\n";
          code += "\t\trcv." + field_field + "(&x, j)\n";
        }
        code += "\t\tt." + field_field + "[j] = ";
        if (IsScalar(field.value.type.element)) {
          code += "rcv." + field_field + "(j)";
        } else if (field.value.type.element == BASE_TYPE_STRING) {
          code += "string(rcv." + field_field + "(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_field + " = rcv." + field_field + "(nil).UnPack()\n";
      } else if (field.value.type.base_type == BASE_TYPE_UNION) {
        const std::string field_table = field_var + "Table";
        code += "\t" + field_table + " := flatbuffers.Table{}\n";
        code +=
            "\tif rcv." + namer_.Method(field) + "(&" + field_table + ") {\n";
        code += "\t\tt." + field_field + " = rcv." +
                namer_.Method(field.name + UnionTypeFieldSuffix()) +
                "().UnPack(" + field_table + ")\n";
        code += "\t}\n";
      } else {
        FLATBUFFERS_ASSERT(0);
      }
    }
    code += "}\n\n";

    code += "func (rcv *" + struct_type + ") UnPack() *" +
            NativeName(struct_def) + " {\n";
    code += "\tif rcv == nil {\n\t\treturn nil\n\t}\n";
    code += "\tt := &" + NativeName(struct_def) + "{}\n";
    code += "\trcv.UnPackTo(t)\n";
    code += "\treturn t\n";
    code += "}\n\n";
  }

  void GenNativeStructPack(const StructDef& struct_def, std::string* code_ptr) {
    std::string& code = *code_ptr;

    code += "func (t *" + NativeName(struct_def) +
            ") Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {\n";
    code += "\tif t == nil {\n\t\treturn 0\n\t}\n";
    code += "\treturn Create" + namer_.Type(struct_def) + "(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 + namer_.Field(field) + ".").c_str(),
                       code_ptr);
      } else {
        code += std::string(", t.") + nameprefix + namer_.Field(field);
      }
    }
  }

  void GenNativeStructUnPack(const StructDef& struct_def,
                             std::string* code_ptr) {
    std::string& code = *code_ptr;

    code += "func (rcv *" + namer_.Type(struct_def) + ") UnPackTo(t *" +
            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." + namer_.Field(field) + " = rcv." +
                namer_.Method(field) + "(nil).UnPack()\n";
      } else {
        code += "\tt." + namer_.Field(field) + " = rcv." +
                namer_.Method(field) + "()\n";
      }
    }
    code += "}\n\n";

    code += "func (rcv *" + namer_.Type(struct_def) + ") UnPack() *" +
            NativeName(struct_def) + " {\n";
    code += "\tif rcv == nil {\n\t\treturn nil\n\t}\n";
    code += "\tt := &" + NativeName(struct_def) + "{}\n";
    code += "\trcv.UnPackTo(t)\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;

    auto max_name_length = MaxNameLength(enum_def);
    cur_name_space_ = enum_def.defined_namespace;

    GenComment(enum_def.doc_comment, code_ptr, nullptr);
    GenEnumType(enum_def, code_ptr);
    BeginEnum(code_ptr);
    for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
      const EnumVal& ev = **it;
      GenComment(ev.doc_comment, code_ptr, nullptr, "\t");
      EnumMember(enum_def, ev, max_name_length, code_ptr);
    }
    EndEnum(code_ptr);

    BeginEnumNames(enum_def, code_ptr);
    for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
      const EnumVal& ev = **it;
      EnumNameMember(enum_def, ev, max_name_length, code_ptr);
    }
    EndEnumNames(code_ptr);

    BeginEnumValues(enum_def, code_ptr);
    for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
      auto& ev = **it;
      EnumValueMember(enum_def, ev, max_name_length, code_ptr);
    }
    EndEnumValues(code_ptr);

    EnumStringer(enum_def, code_ptr);
  }

  // Returns the function name that is able to read a value of the given type.
  std::string GenGetter(const Type& type) {
    switch (type.base_type) {
      case BASE_TYPE_STRING:
        return "rcv._tab.ByteVector";
      case BASE_TYPE_UNION:
        return "rcv._tab.Union";
      case BASE_TYPE_VECTOR:
        return GenGetter(type.VectorType());
      default:
        return "rcv._tab.Get" + namer_.Function(GenTypeBasic(type));
    }
  }

  // Returns the method name for use with add/put calls.
  std::string GenMethod(const FieldDef& field) {
    return IsScalar(field.value.type.base_type)
               ? namer_.Method(GenTypeBasic(field.value.type))
               : (IsStruct(field.value.type) ? "Struct" : "UOffsetT");
  }

  std::string GenTypeBasic(const Type& type) {
    // clang-format off
    static const char *ctypename[] = {
      #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, ...) \
        #GTYPE,
        FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
      #undef FLATBUFFERS_TD
    };
    // clang-format on
    return ctypename[type.base_type];
  }

  std::string GenTypePointer(const Type& type) {
    switch (type.base_type) {
      case BASE_TYPE_STRING:
        return "[]byte";
      case BASE_TYPE_VECTOR:
        return GenTypeGet(type.VectorType());
      case BASE_TYPE_STRUCT:
        return WrapInNameSpaceAndTrack(type.struct_def, type.struct_def->name);
      case BASE_TYPE_UNION:
        // fall through
      default:
        return "*flatbuffers.Table";
    }
  }

  std::string GenTypeGet(const Type& type) {
    if (type.enum_def != nullptr) {
      return GetEnumTypeName(*type.enum_def);
    }
    return IsScalar(type.base_type) ? GenTypeBasic(type) : GenTypePointer(type);
  }

  std::string TypeName(const FieldDef& field) {
    std::string prefix;
    if (field.IsScalarOptional()) {
      prefix = "*";
    }
    return prefix + GenTypeGet(field.value.type);
  }

  // If type is an enum, returns value with a cast to the enum type, otherwise
  // returns value as-is.
  std::string CastToEnum(const Type& type, std::string value) {
    if (type.enum_def == nullptr) {
      return value;
    } else {
      return GenTypeGet(type) + "(" + value + ")";
    }
  }

  // If type is an enum, returns value with a cast to the enum base type,
  // otherwise returns value as-is.
  std::string CastToBaseType(const Type& type, std::string value) {
    if (type.enum_def == nullptr) {
      return value;
    } else {
      return GenTypeBasic(type) + "(" + value + ")";
    }
  }

  std::string GenConstant(const FieldDef& field) {
    if (field.IsScalarOptional()) {
      return "nil";
    }
    switch (field.value.type.base_type) {
      case BASE_TYPE_BOOL:
        return field.value.constant == "0" ? "false" : "true";
      case BASE_TYPE_FLOAT:
      case BASE_TYPE_DOUBLE: {
        const std::string float_type =
            field.value.type.base_type == BASE_TYPE_FLOAT ? "float32"
                                                          : "float64";
        if (StringIsFlatbufferNan(field.value.constant)) {
          needs_math_import_ = true;
          return float_type + "(math.NaN())";
        } else if (StringIsFlatbufferPositiveInfinity(field.value.constant)) {
          needs_math_import_ = true;
          return float_type + "(math.Inf(1))";
        } else if (StringIsFlatbufferNegativeInfinity(field.value.constant)) {
          needs_math_import_ = true;
          return float_type + "(math.Inf(-1))";
        }
        return field.value.constant;
      }
      default:
        return field.value.constant;
    }
  }

  std::string NativeName(const StructDef& struct_def) const {
    return namer_.ObjectType(struct_def);
  }

  std::string NativeName(const EnumDef& enum_def) const {
    return namer_.ObjectType(enum_def);
  }

  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 (IsString(type)) {
      return "string";
    } else if (IsVector(type)) {
      return "[]" + NativeType(type.VectorType());
    } else if (type.base_type == BASE_TYPE_STRUCT) {
      return "*" + WrapInNameSpaceAndTrack(type.struct_def,
                                           NativeName(*type.struct_def));
    } else if (type.base_type == BASE_TYPE_UNION) {
      return "*" +
             WrapInNameSpaceAndTrack(type.enum_def, 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);
    StructBuilderArgs(struct_def, "", code_ptr);
    EndBuilderArgs(code_ptr);

    StructBuilderBody(struct_def, "", code_ptr);
    EndBuilderBody(code_ptr);
  }

  // Begin by declaring namespace and imports.
  void BeginFile(const std::string& name_space_name, const bool needs_imports,
                 const bool is_enum, std::string* code_ptr) {
    std::string& code = *code_ptr;
    code = code +
           "// Code generated by the FlatBuffers compiler. DO NOT EDIT.\n\n";
    code += "package " + name_space_name + "\n\n";
    if (needs_imports) {
      code += "import (\n";
      // standard imports, in alphabetical order for go fmt
      if (needs_bytes_import_) code += "\t\"bytes\"\n";
      if (!parser_.opts.go_import.empty()) {
        code += "\tflatbuffers \"" + parser_.opts.go_import + "\"\n";
      } else {
        code += "\tflatbuffers \"github.com/google/flatbuffers/go\"\n";
      }
      // math is needed to support non-finite scalar default values.
      if (needs_math_import_) {
        code += "\t\"math\"\n";
      }
      if (is_enum) {
        code += "\t\"strconv\"\n";
      }

      if (tracked_imported_namespaces_.size() > 0) {
        code += "\n";
        for (auto it = tracked_imported_namespaces_.begin();
             it != tracked_imported_namespaces_.end(); ++it) {
          if ((*it)->defined_namespace->components.empty()) {
            code += "\t" + (*it)->name + " \"" + (*it)->name + "\"\n";
          } else {
            code += "\t" + NamespaceImportName((*it)->defined_namespace) +
                    " \"" + NamespaceImportPath((*it)->defined_namespace) +
                    "\"\n";
          }
        }
      }
      code += ")\n\n";
    } else {
      if (is_enum) {
        code += "import \"strconv\"\n\n";
      }
      if (needs_math_import_) {
        // math is needed to support non-finite scalar default values.
        code += "import \"math\"\n\n";
      }
    }
  }

  // Resets the needed imports before generating a new file.
  void ResetImports() {
    tracked_imported_namespaces_.clear();
    needs_bytes_import_ = false;
    needs_math_import_ = false;
  }

  // Save out the generated code for a Go Table type.
  bool SaveType(const Definition& def, const std::string& classcode,
                const bool needs_imports, const bool is_enum) {
    if (!classcode.length()) return true;

    Namespace& ns = go_namespace_.components.empty() ? *def.defined_namespace
                                                     : go_namespace_;
    std::string code = "";
    BeginFile(ns.components.empty() ? def.name : LastNamespacePart(ns),
              needs_imports, is_enum, &code);
    code += classcode;
    // Strip extra newlines at end of file to make it gofmt-clean.
    while (code.length() > 2 && code.substr(code.length() - 2) == "\n\n") {
      code.pop_back();
    }
    std::string directory = namer_.Directories(ns);
    std::string file = namer_.File(def, SkipFile::Suffix);
    EnsureDirExists(directory);
    std::string filename = directory + file;
    return SaveFile(filename.c_str(), code, false);
  }

  // Create the full name of the imported namespace (format: A__B__C).
  std::string NamespaceImportName(const Namespace* ns) const {
    return namer_.Namespace(*ns);
  }

  // Create the full path for the imported namespace (format: A/B/C).
  std::string NamespaceImportPath(const Namespace* ns) const {
    std::string path =
        namer_.Directories(*ns, SkipDir::OutputPathAndTrailingPathSeparator);
    if (!parser_.opts.go_module_name.empty()) {
      path = parser_.opts.go_module_name + "/" + path;
    }
    return path;
  }

  // Ensure that a type is prefixed with its go package import name if it is
  // used outside of its namespace.
  std::string WrapInNameSpaceAndTrack(const Definition* def,
                                      const std::string& name) {
    if (CurrentNameSpace() == def->defined_namespace) return name;
    tracked_imported_namespaces_.insert(def);
    if (def->defined_namespace->components.empty())
      return def->name + "." + name;
    else
      return NamespaceImportName(def->defined_namespace) + "." + name;
  }

  const Namespace* CurrentNameSpace() const { return cur_name_space_; }

  static size_t MaxNameLength(const EnumDef& enum_def) {
    size_t max = 0;
    for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
      max = std::max((*it)->name.length(), max);
    }
    return max;
  }
};
}  // namespace go

static bool GenerateGo(const Parser& parser, const std::string& path,
                       const std::string& file_name) {
  go::GoGenerator generator(parser, path, file_name, parser.opts.go_namespace);
  return generator.generate();
}

namespace {

class GoCodeGenerator : public CodeGenerator {
 public:
  Status GenerateCode(const Parser& parser, const std::string& path,
                      const std::string& filename) override {
    if (!GenerateGo(parser, path, filename)) {
      return Status::ERROR;
    }
    return Status::OK;
  }

  Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
    return Status::NOT_IMPLEMENTED;
  }

  Status GenerateMakeRule(const Parser& parser, const std::string& path,
                          const std::string& filename,
                          std::string& output) override {
    (void)parser;
    (void)path;
    (void)filename;
    (void)output;
    return Status::NOT_IMPLEMENTED;
  }

  Status GenerateGrpcCode(const Parser& parser, const std::string& path,
                          const std::string& filename) override {
    if (!GenerateGoGRPC(parser, path, filename)) {
      return Status::ERROR;
    }
    return Status::OK;
  }

  Status GenerateRootFile(const Parser& parser,
                          const std::string& path) override {
    (void)parser;
    (void)path;
    return Status::NOT_IMPLEMENTED;
  }

  bool IsSchemaOnly() const override { return true; }

  bool SupportsBfbsGeneration() const override { return false; }

  bool SupportsRootFileGeneration() const override { return false; }

  IDLOptions::Language Language() const override { return IDLOptions::kGo; }

  std::string LanguageName() const override { return "Go"; }
};
}  // namespace

std::unique_ptr<CodeGenerator> NewGoCodeGenerator() {
  return std::unique_ptr<GoCodeGenerator>(new GoCodeGenerator());
}

}  // namespace flatbuffers
