/*
 * 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_python.h"

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <map>
#include <set>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

#include "codegen/idl_namer.h"
#include "codegen/python.h"
#include "flatbuffers/code_generators.h"
#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"

namespace flatbuffers {
namespace python {

namespace {

typedef std::pair<std::string, std::string> ImportMapEntry;
typedef std::set<ImportMapEntry> ImportMap;

// Hardcode spaces per indentation.
static const CommentConfig def_comment = {nullptr, "#", nullptr};
static const std::string Indent = "    ";

class PythonStubGenerator {
 public:
  PythonStubGenerator(const Parser& parser, const std::string& path,
                      const Version& version)
      : parser_{parser},
        namer_{WithFlagOptions(kStubConfig, parser.opts, path),
               Keywords(version)},
        version_(version) {}

  bool Generate() {
    if (parser_.opts.one_file) {
      Imports imports;
      std::stringstream stub;

      DeclareUOffset(stub, &imports);
      for (const EnumDef* def : parser_.enums_.vec) {
        if (def->generated) continue;
        GenerateEnumStub(stub, def, &imports);
      }
      for (const StructDef* def : parser_.structs_.vec) {
        if (def->generated) continue;
        GenerateStructStub(stub, def, &imports);
      }

      std::string filename =
          namer_.config_.output_path +
          StripPath(StripExtension(parser_.file_being_parsed_)) +
          namer_.config_.filename_suffix + namer_.config_.filename_extension;

      return SaveFile(filename, imports, stub);
    }

    for (const EnumDef* def : parser_.enums_.vec) {
      if (def->generated) continue;

      Imports imports;
      std::stringstream stub;

      DeclareUOffset(stub, &imports);
      GenerateEnumStub(stub, def, &imports);

      std::string filename = namer_.Directories(*def->defined_namespace) +
                             namer_.File(*def, SkipFile::Suffix);
      if (!SaveFile(filename, imports, stub)) return false;
    }

    for (const StructDef* def : parser_.structs_.vec) {
      if (def->generated) continue;

      Imports imports;
      std::stringstream stub;

      DeclareUOffset(stub, &imports);
      GenerateStructStub(stub, def, &imports);

      std::string filename = namer_.Directories(*def->defined_namespace) +
                             namer_.File(*def, SkipFile::Suffix);
      if (!SaveFile(filename, imports, stub)) return false;
    }

    return true;
  }

 private:
  bool SaveFile(const std::string& filename, const Imports& imports,
                const std::stringstream& content) {
    std::stringstream ss;
    GenerateImports(ss, imports);
    ss << '\n';
    ss << content.str() << '\n';

    EnsureDirExists(StripFileName(filename));
    return parser_.opts.file_saver->SaveFile(filename.c_str(), ss.str(), false);
  }

  static void DeclareUOffset(std::stringstream& stub, Imports* imports) {
    imports->Import("flatbuffers");
    imports->Import("typing");
    stub << "uoffset: typing.TypeAlias = "
            "flatbuffers.number_types.UOffsetTFlags.py_type\n"
         << '\n';
  }

  std::string ModuleForFile(const std::string& file) const {
    if (parser_.file_being_parsed_ == file) return ".";

    std::string module = parser_.opts.include_prefix + StripExtension(file) +
                         parser_.opts.filename_suffix;
    std::replace(module.begin(), module.end(), '/', '.');
    return module;
  }

  template <typename T>
  std::string ModuleFor(const T* def) const {
    if (parser_.opts.one_file) return ModuleForFile(def->file);
    return namer_.NamespacedType(*def);
  }

  const StructDef* GetNestedStruct(const FieldDef* field) const {
    const Value* nested = field->attributes.Lookup("nested_flatbuffer");
    if (nested == nullptr) return nullptr;

    StructDef* nested_def = parser_.LookupStruct(nested->constant);
    if (nested_def != nullptr) return nested_def;

    return parser_.LookupStruct(namer_.NamespacedType(
        parser_.current_namespace_->components, nested->constant));
  }

  static std::string ScalarType(BaseType type) {
    if (IsBool(type)) return "bool";
    if (IsInteger(type)) return "int";
    if (IsFloat(type)) return "float";
    FLATBUFFERS_ASSERT(false);
    return "None";
  }

  template <typename F>
  std::string UnionType(const EnumDef& enum_def, Imports* imports,
                        F type) const {
    imports->Import("typing");

    std::string result = "";
    for (const EnumVal* val : enum_def.Vals()) {
      if (!result.empty()) result += ", ";

      switch (val->union_type.base_type) {
        case BASE_TYPE_STRUCT: {
          Import import = imports->Import(ModuleFor(val->union_type.struct_def),
                                          type(*val->union_type.struct_def));
          result += import.name;
          break;
        }
        case BASE_TYPE_STRING:
          result += "str";
          break;
        case BASE_TYPE_NONE:
          result += "None";
          break;
        default:
          break;
      }
    }
    return "typing.Union[" + result + "]";
  }

  std::string UnionObjectType(const EnumDef& enum_def, Imports* imports) const {
    return UnionType(enum_def, imports, [this](const StructDef& struct_def) {
      return namer_.ObjectType(struct_def);
    });
  }

  std::string UnionType(const EnumDef& enum_def, Imports* imports) const {
    return UnionType(enum_def, imports, [this](const StructDef& struct_def) {
      return namer_.Type(struct_def);
    });
  }

  std::string EnumType(const EnumDef& enum_def, Imports* imports) const {
    imports->Import("typing");
    const Import& import =
        imports->Import(ModuleFor(&enum_def), namer_.Type(enum_def));

    std::string result = "";
    for (const EnumVal* val : enum_def.Vals()) {
      if (!result.empty()) result += ", ";
      result += import.name + "." + namer_.Variant(*val);
    }
    return "typing.Literal[" + result + "]";
  }

  std::string TypeOf(const Type& type, Imports* imports) const {
    if (type.enum_def != nullptr) return EnumType(*type.enum_def, imports);
    if (IsScalar(type.base_type)) return ScalarType(type.base_type);

    switch (type.base_type) {
      case BASE_TYPE_STRUCT: {
        const Import& import = imports->Import(ModuleFor(type.struct_def),
                                               namer_.Type(*type.struct_def));
        return import.name;
      }
      case BASE_TYPE_STRING:
        return "str";
      case BASE_TYPE_ARRAY:
      case BASE_TYPE_VECTOR: {
        imports->Import("typing");
        return "typing.List[" + TypeOf(type.VectorType(), imports) + "]";
      }
      case BASE_TYPE_UNION:
        return UnionType(*type.enum_def, imports);
      default:
        FLATBUFFERS_ASSERT(0);
        return "";
    }
  }

  std::string GenerateObjectFieldStub(const FieldDef* field,
                                      Imports* imports) const {
    std::string field_name = namer_.Field(*field);

    const Type& field_type = field->value.type;
    if (IsScalar(field_type.base_type)) {
      std::string result = field_name + ": " + TypeOf(field_type, imports);
      if (field->IsOptional()) result += " | None";
      return result;
    }

    switch (field_type.base_type) {
      case BASE_TYPE_STRUCT: {
        Import import =
            imports->Import(ModuleFor(field_type.struct_def),
                            namer_.ObjectType(*field_type.struct_def));
        return field_name + ": " + import.name + " | None";
      }
      case BASE_TYPE_STRING:
        return field_name + ": str | None";
      case BASE_TYPE_ARRAY:
      case BASE_TYPE_VECTOR: {
        imports->Import("typing");
        if (field_type.element == BASE_TYPE_STRUCT) {
          Import import =
              imports->Import(ModuleFor(field_type.struct_def),
                              namer_.ObjectType(*field_type.struct_def));
          return field_name + ": typing.List[" + import.name + "]";
        }
        if (field_type.element == BASE_TYPE_STRING) {
          return field_name + ": typing.List[str]";
        }
        return field_name + ": typing.List[" +
               TypeOf(field_type.VectorType(), imports) + "]";
      }
      case BASE_TYPE_UNION:
        return field_name + ": " +
               UnionObjectType(*field->value.type.enum_def, imports);
      default:
        return field_name;
    }
  }

  void GenerateObjectInitializerStub(std::stringstream& stub,
                                     const StructDef* struct_def,
                                     Imports* imports) const {
    stub << "  def __init__(\n";
    stub << "    self,\n";

    for (const FieldDef* field : struct_def->fields.vec) {
      if (field->deprecated) continue;

      std::string field_name = namer_.Field(*field);
      std::string field_type;
      const Type& type = field->value.type;

      if (IsScalar(type.base_type)) {
        field_type = TypeOf(type, imports);
        if (field->IsOptional()) {
          field_type += " | None";
        }
      } else {
        switch (type.base_type) {
          case BASE_TYPE_STRUCT: {
            Import import_ =
                imports->Import(ModuleFor(type.struct_def),
                                namer_.ObjectType(*type.struct_def));
            field_type = "'" + import_.name + "' | None";
            break;
          }
          case BASE_TYPE_STRING:
            field_type = "str | None";
            break;
          case BASE_TYPE_ARRAY:
          case BASE_TYPE_VECTOR: {
            imports->Import("typing");
            if (type.element == BASE_TYPE_STRUCT) {
              Import import_ =
                  imports->Import(ModuleFor(type.struct_def),
                                  namer_.ObjectType(*type.struct_def));
              field_type = "typing.List['" + import_.name + "'] | None";
            } else if (type.element == BASE_TYPE_STRING) {
              field_type = "typing.List[str] | None";
            } else {
              field_type = "typing.List[" + TypeOf(type.VectorType(), imports) +
                           "] | None";
            }
            break;
          }
          case BASE_TYPE_UNION:
            field_type = UnionObjectType(*type.enum_def, imports);
            break;
          default:
            field_type = "typing.Any";
            break;
        }
      }
      stub << "    " << field_name << ": " << field_type << " = ...,\n";
    }
    stub << "  ) -> None: ...\n";
  }

  void GenerateObjectStub(std::stringstream& stub, const StructDef* struct_def,
                          Imports* imports) const {
    std::string name = namer_.ObjectType(*struct_def);
    imports->Export(ModuleFor(struct_def), namer_.Type(*struct_def));

    stub << "class " << name;
    if (version_.major != 3) stub << "(object)";
    stub << ":\n";
    for (const FieldDef* field : struct_def->fields.vec) {
      if (field->deprecated) continue;
      stub << "  " << GenerateObjectFieldStub(field, imports) << "\n";
    }

    GenerateObjectInitializerStub(stub, struct_def, imports);

    stub << "  @classmethod\n";
    stub << "  def InitFromBuf(cls, buf: bytes, pos: int) -> " << name
         << ": ...\n";

    stub << "  @classmethod\n";
    stub << "  def InitFromPackedBuf(cls, buf: bytes, pos: int = 0) -> " << name
         << ": ...\n";

    const Import& import =
        imports->Import(ModuleFor(struct_def), namer_.Type(*struct_def));

    stub << "  @classmethod\n";
    stub << "  def InitFromObj(cls, " << namer_.Variable(*struct_def)
         << ": " + import.name + ") -> " << name << ": ...\n";

    stub << "  def _UnPack(self, " << namer_.Variable(*struct_def) << ": "
         << import.name << ") -> None: ...\n";

    stub << "  def Pack(self, builder: flatbuffers.Builder) -> None: ...\n";

    if (parser_.opts.gen_compare) {
      stub << "  def __eq__(self, other: " << name + ") -> bool: ...\n";
    }
  }

  void GenerateStructStub(std::stringstream& stub, const StructDef* struct_def,
                          Imports* imports) const {
    std::string type = namer_.Type(*struct_def);
    imports->Export(ModuleFor(struct_def), namer_.Type(*struct_def));

    stub << "class " << type;
    if (version_.major != 3) stub << "(object)";
    stub << ":\n";
    if (struct_def->fixed) {
      stub << "  @classmethod\n";
      stub << "  def SizeOf(cls) -> int: ...\n\n";
    } else {
      stub << "  @classmethod\n";
      stub << "  def GetRootAs(cls, buf: bytes, offset: int) -> " << type
           << ": ...\n";

      if (!parser_.opts.python_no_type_prefix_suffix) {
        stub << "  @classmethod\n";
        stub << "  def GetRootAs" << type
             << "(cls, buf: bytes, offset: int) -> " << type << ": ...\n";
      }
      if (parser_.file_identifier_.length()) {
        stub << "  @classmethod\n";
        stub << "  def " << type
             << "BufferHasIdentifier(cls, buf: bytes, offset: int, "
                "size_prefixed: bool) -> bool: ...\n";
      }
    }

    stub << "  def Init(self, buf: bytes, pos: int) -> None: ...\n";

    for (const FieldDef* field : struct_def->fields.vec) {
      if (field->deprecated) continue;

      std::string name = namer_.Method(*field);

      const Type& field_type = field->value.type;
      if (IsScalar(field_type.base_type)) {
        stub << "  def " << name << "(self) -> " << TypeOf(field_type, imports);
        if (field->IsOptional()) stub << " | None";
        stub << ": ...\n";
      } else {
        switch (field_type.base_type) {
          case BASE_TYPE_STRUCT: {
            const Import& import =
                imports->Import(ModuleFor(field_type.struct_def),
                                namer_.Type(*field_type.struct_def));
            if (struct_def->fixed) {
              stub << "  def " << name << "(self, obj: " << import.name
                   << ") -> " << import.name << ": ...\n";
            } else {
              stub << "  def " << name + "(self) -> " << import.name
                   << " | None: ...\n";
            }
            break;
          }
          case BASE_TYPE_STRING:
            stub << "  def " << name << "(self) -> str | None: ...\n";
            break;
          case BASE_TYPE_ARRAY:
          case BASE_TYPE_VECTOR: {
            switch (field_type.element) {
              case BASE_TYPE_STRUCT: {
                const Import& import =
                    imports->Import(ModuleFor(field_type.struct_def),
                                    namer_.Type(*field_type.struct_def));
                stub << "  def " << name << "(self, i: int) -> " << import.name
                     << " | None: ...\n";
                break;
              }
              case BASE_TYPE_STRING:
                stub << "  def " << name << "(self, i: int) -> str: ...\n";
                break;
              default:  // scalars
                stub << "  def " << name << "(self, i: int) -> "
                     << TypeOf(field_type, imports) << ": ...\n";

                if (parser_.opts.python_gen_numpy) {
                  stub << "  def " << name
                       << "AsNumpy(self) -> np.ndarray: ...\n";
                }

                const StructDef* nested_def = GetNestedStruct(field);
                if (nested_def != nullptr) {
                  const Import& import = imports->Import(
                      ModuleFor(nested_def), namer_.Type(*nested_def));

                  stub << "  def " << name + "NestedRoot(self) -> "
                       << import.name << " | None: ...\n";
                }
                break;
            }
            stub << "  def " << name << "Length(self) -> int: ...\n";
            stub << "  def " << name << "IsNone(self) -> bool: ...\n";
            break;
          }
          case BASE_TYPE_UNION: {
            imports->Import("flatbuffers", "table");
            stub << "  def " << name << "(self) -> table.Table | None: ...\n";
            break;
          }
          default:
            break;
        }
      }
    }

    if (parser_.opts.generate_object_based_api) {
      GenerateObjectStub(stub, struct_def, imports);
    }

    if (struct_def->fixed) {
      GenerateStructBuilderStub(stub, struct_def, imports);
    } else {
      GenerateTableBuilderStub(stub, struct_def, imports);
    }
  }

  void StructBuilderArgs(const StructDef& struct_def, const std::string prefix,
                         Imports* imports,
                         std::vector<std::string>* args) const {
    for (const FieldDef* field : struct_def.fields.vec) {
      const Type type = IsArray(field->value.type)
                            ? field->value.type.VectorType()
                            : field->value.type;
      if (type.base_type == BASE_TYPE_STRUCT) {
        StructBuilderArgs(*field->value.type.struct_def,
                          prefix + namer_.Field(*field) + "_", imports, args);
      } else {
        args->push_back(prefix + namer_.Field(*field) + ": " +
                        TypeOf(type, imports));
      }
    }
  }

  void GenerateStructBuilderStub(std::stringstream& stub,
                                 const StructDef* struct_def,
                                 Imports* imports) const {
    imports->Import("flatbuffers");

    std::vector<std::string> args;
    StructBuilderArgs(*struct_def, "", imports, &args);

    stub << '\n';
    stub << "def Create" + namer_.Type(*struct_def)
         << "(builder: flatbuffers.Builder";
    for (const std::string& arg : args) {
      stub << ", " << arg;
    }
    stub << ") -> uoffset: ...\n";
  }

  void GenerateTableBuilderStub(std::stringstream& stub,
                                const StructDef* struct_def,
                                Imports* imports) const {
    std::string type = namer_.Type(*struct_def);

    /**************************** def TableStart ****************************/
    stub << "def ";
    if (!parser_.opts.python_no_type_prefix_suffix) stub << type;
    stub << "Start(builder: flatbuffers.Builder) -> None: ...\n";
    if (!parser_.opts.one_file && !parser_.opts.python_no_type_prefix_suffix) {
      stub << "def Start(builder: flatbuffers.Builder) -> None: ...\n";
    }

    /************************** def TableAddField ***************************/
    for (const FieldDef* field : struct_def->fields.vec) {
      if (field->deprecated) continue;

      stub << "def ";
      if (!parser_.opts.python_no_type_prefix_suffix) stub << type;
      stub << "Add" << namer_.Method(*field)
           << "(builder: flatbuffers.Builder, "
           << namer_.Variable(*field) + ": ";
      if (IsScalar(field->value.type.base_type)) {
        stub << TypeOf(field->value.type, imports);
      } else if (IsArray(field->value.type)) {
        stub << TypeOf(field->value.type.VectorType(), imports);
      } else {
        stub << "uoffset";
      }
      stub << ") -> None: ...\n";

      if (IsVector(field->value.type)) {
        stub << "def ";
        if (!parser_.opts.python_no_type_prefix_suffix) stub << type;
        stub << "Start" << namer_.Method(*field)
             << "Vector(builder: flatbuffers.Builder, num_elems: int) -> "
                "uoffset: ...\n";

        if (!parser_.opts.one_file &&
            !parser_.opts.python_no_type_prefix_suffix) {
          stub << "def Start" << namer_.Method(*field)
               << "Vector(builder: flatbuffers.Builder, num_elems: int) -> "
                  "uoffset: ...\n";
        }

        if (GetNestedStruct(field) != nullptr) {
          stub << "def " << type << "Make" << namer_.Method(*field)
               << "VectorFromBytes(builder: flatbuffers.Builder, buf: "
                  "bytes) -> uoffset: ...\n";
          if (!parser_.opts.one_file) {
            stub << "def Make" << namer_.Method(*field)
                 << "VectorFromBytes(builder: flatbuffers.Builder, buf: "
                    "bytes) -> uoffset: ...\n";
          }
        }

        stub << "def ";
        if (!parser_.opts.python_no_type_prefix_suffix) stub << type;
        stub << "Create" << namer_.Method(*field)
             << "Vector(builder: flatbuffers.Builder, data: typing.Iterable["
                "typing.Any]) -> uoffset: ...\n";
        if (!parser_.opts.one_file &&
            !parser_.opts.python_no_type_prefix_suffix) {
          stub << "def Create" << namer_.Method(*field)
               << "Vector(builder: flatbuffers.Builder, data: "
                  "typing.Iterable[typing.Any]) -> uoffset: ...\n";
        }
      }
    }

    /***************************** def TableEnd *****************************/
    stub << "def ";
    if (!parser_.opts.python_no_type_prefix_suffix) stub << type;
    stub << "End(builder: flatbuffers.Builder) -> uoffset: ...\n";
    if (!parser_.opts.one_file && !parser_.opts.python_no_type_prefix_suffix) {
      stub << "def End(builder: flatbuffers.Builder) -> uoffset: ...\n";
    }
  }

  void GenerateEnumStub(std::stringstream& stub, const EnumDef* enum_def,
                        Imports* imports) const {
    stub << "class " << namer_.Type(*enum_def);
    imports->Export(ModuleFor(enum_def), namer_.Type(*enum_def));

    imports->Import("typing", "cast");

    if (version_.major == 3) {
      imports->Import("enum", "IntEnum");
      stub << "(IntEnum)";
    } else {
      stub << "(object)";
    }

    stub << ":\n";
    for (const EnumVal* val : enum_def->Vals()) {
      stub << "  " << namer_.Variant(*val) << " = cast("
           << ScalarType(enum_def->underlying_type.base_type) << ", ...)\n";
    }

    if (parser_.opts.generate_object_based_api & enum_def->is_union) {
      imports->Import("flatbuffers", "table");
      stub << "def " << namer_.Function(*enum_def)
           << "Creator(union_type: " << EnumType(*enum_def, imports)
           << ", table: table.Table) -> " << UnionType(*enum_def, imports)
           << ": ...\n";
    }
  }

  void GenerateImports(std::stringstream& ss, const Imports& imports) {
    ss << "from __future__ import annotations\n";
    ss << '\n';
    ss << "import flatbuffers\n";
    if (parser_.opts.python_gen_numpy) {
      ss << "import numpy as np\n";
    }
    ss << '\n';

    std::set<std::string> modules;
    std::map<std::string, std::set<std::string>> names_by_module;
    for (const Import& import : imports.imports) {
      if (import.IsLocal()) continue;  // skip all local imports
      if (import.module == "flatbuffers" && import.name == "")
        continue;  // skip double include hardcoded flatbuffers
      if (import.name == "") {
        modules.insert(import.module);
      } else {
        names_by_module[import.module].insert(import.name);
      }
    }

    // Remove imports from exports
    for (const Import& import : imports.exports) {
      if (import.name == "") {
        modules.erase(import.module);
      } else {
        auto search = names_by_module.find(import.module);
        if (search != names_by_module.end()) {
          search->second.erase(import.name);
        }
      }
    }

    for (const std::string& module : modules) {
      ss << "import " << module << '\n';
    }
    for (const auto& import : names_by_module) {
      if (!import.second.empty()) {
        ss << "from " << import.first << " import ";
        size_t i = 0;
        for (const std::string& name : import.second) {
          if (i > 0) ss << ", ";
          ss << name;
          ++i;
        }
        ss << '\n';
      }
    }
  }

  const Parser& parser_;
  const IdlNamer namer_;
  const Version version_;
};
}  // namespace

class PythonGenerator : public BaseGenerator {
 public:
  PythonGenerator(const Parser& parser, const std::string& path,
                  const std::string& file_name, const Version& version)
      : BaseGenerator(parser, path, file_name, "" /* not used */,
                      "" /* not used */, "py"),
        float_const_gen_("float('nan')", "float('inf')", "float('-inf')"),
        namer_(WithFlagOptions(kConfig, parser.opts, path), Keywords(version)) {
  }

  // 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, bool new_line = true) const {
    return "\n" + Indent + Indent +
           "o = flatbuffers.number_types.UOffsetTFlags.py_type" +
           "(self._tab.Offset(" + NumToString(field.value.offset) + "))\n" +
           Indent + Indent + "if o != 0:" + (new_line ? "\n" : "");
  }

  // Begin a class declaration.
  void BeginClass(const StructDef& struct_def, std::string* code_ptr) const {
    auto& code = *code_ptr;
    code += "class " + namer_.Type(struct_def) + "(object):\n";
    code += Indent + "__slots__ = ['_tab']";
    code += "\n\n";
  }

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

  // Starts a new line and then indents.
  std::string GenIndents(int num) const {
    return "\n" + std::string(num * Indent.length(), ' ');
  }

  // A single enum member.
  void EnumMember(const EnumDef& enum_def, const EnumVal& ev,
                  std::string* code_ptr) const {
    auto& code = *code_ptr;
    code += Indent;
    code += namer_.Variant(ev);
    code += " = ";
    code += enum_def.ToString(ev) + "\n";
  }

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

    code += Indent + "@classmethod\n";
    code += Indent + "def GetRootAs";
    if (parser_.opts.python_typing) {
      code += "(cls, buf, offset: int = 0):";
    } else {
      code += "(cls, buf, offset=0):";
    }
    code += "\n";
    code += Indent + Indent;
    code += "n = flatbuffers.encode.Get";
    code += "(flatbuffers.packer.uoffset, buf, offset)\n";
    code += Indent + Indent + "x = " + struct_type + "()\n";
    code += Indent + Indent + "x.Init(buf, n + offset)\n";
    code += Indent + Indent + "return x\n";
    code += "\n";

    if (!parser_.opts.python_no_type_prefix_suffix) {
      // Add an alias with the old name
      code += Indent + "@classmethod\n";
      code +=
          Indent + "def GetRootAs" + struct_type + "(cls, buf, offset=0):\n";
      code += Indent + Indent +
              "\"\"\"This method is deprecated. Please switch to "
              "GetRootAs.\"\"\"\n";
      code += Indent + Indent + "return cls.GetRootAs(buf, offset)\n";
    }
  }

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

    GenReceiver(struct_def, code_ptr);
    if (parser_.opts.python_typing) {
      code += "Init(self, buf: bytes, pos: int):\n";
    } else {
      code += "Init(self, buf, pos):\n";
    }
    code += Indent + Indent + "self._tab = flatbuffers.table.Table(buf, pos)\n";
    code += "\n";
  }

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

    GenReceiver(struct_def, code_ptr);
    code += namer_.Method(field) + "Length(self)";
    if (parser_.opts.python_typing) {
      code += " -> int";
    }
    code += ":";
    if (!IsArray(field.value.type)) {
      code += OffsetPrefix(field, false);
      code += GenIndents(3) + "return self._tab.VectorLen(o)";
      code += GenIndents(2) + "return 0\n\n";
    } else {
      code += GenIndents(2) + "return " +
              NumToString(field.value.type.fixed_length) + "\n\n";
    }
  }

  // Determines whether a vector is none or not.
  void GetVectorIsNone(const StructDef& struct_def, const FieldDef& field,
                       std::string* code_ptr) const {
    auto& code = *code_ptr;

    GenReceiver(struct_def, code_ptr);
    code += namer_.Method(field) + "IsNone(self)";
    if (parser_.opts.python_typing) {
      code += " -> bool";
    }
    code += ":";
    if (!IsArray(field.value.type)) {
      code += GenIndents(2) +
              "o = flatbuffers.number_types.UOffsetTFlags.py_type" +
              "(self._tab.Offset(" + NumToString(field.value.offset) + "))";
      code += GenIndents(2) + "return o == 0";
    } else {
      // assume that we always have an array as memory is preassigned
      code += GenIndents(2) + "return False";
    }
    code += "\n\n";
  }

  // Get the value of a struct's scalar.
  void GetScalarFieldOfStruct(const StructDef& struct_def,
                              const FieldDef& field,
                              std::string* code_ptr) const {
    auto& code = *code_ptr;
    std::string getter = GenGetter(field.value.type);
    GenReceiver(struct_def, code_ptr);
    code += namer_.Method(field);
    code += "(self): return " + getter;
    code += "self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(";
    code += NumToString(field.value.offset) + "))\n";
  }

  // Get the value of a table's scalar.
  void GetScalarFieldOfTable(const StructDef& struct_def, const FieldDef& field,
                             std::string* code_ptr) const {
    auto& code = *code_ptr;
    std::string getter = GenGetter(field.value.type);
    GenReceiver(struct_def, code_ptr);
    code += namer_.Method(field);
    code += "(self):";
    code += OffsetPrefix(field);
    getter += "o + self._tab.Pos)";
    auto is_bool = IsBool(field.value.type.base_type);
    if (is_bool) {
      getter = "bool(" + getter + ")";
    }
    code += Indent + Indent + Indent + "return " + getter + "\n";
    std::string default_value;
    if (field.IsScalarOptional()) {
      default_value = "None";
    } else if (is_bool) {
      default_value = field.value.constant == "0" ? "False" : "True";
    } else {
      default_value = IsFloat(field.value.type.base_type)
                          ? float_const_gen_.GenFloatConstant(field)
                          : field.value.constant;
    }
    code += Indent + Indent + "return " + default_value + "\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) const {
    auto& code = *code_ptr;
    GenReceiver(struct_def, code_ptr);
    code += namer_.Method(field);
    code += "(self, obj):\n";
    code += Indent + Indent + "obj.Init(self._tab.Bytes, self._tab.Pos + ";
    code += NumToString(field.value.offset) + ")";
    code += "\n" + Indent + Indent + "return obj\n\n";
  }

  // Get the value of a fixed size array.
  void GetArrayOfStruct(const StructDef& struct_def, const FieldDef& field,
                        std::string* code_ptr, ImportMap& imports) const {
    auto& code = *code_ptr;
    const auto vec_type = field.value.type.VectorType();
    GenReceiver(struct_def, code_ptr);
    code += namer_.Method(field);

    const ImportMapEntry import_entry = {GenPackageReference(field.value.type),
                                         TypeName(field)};

    if (parser_.opts.python_typing) {
      const std::string return_type = ReturnType(struct_def, field);
      code += "(self, i: int)";
      code += " -> " + return_type + ":";

      imports.insert(import_entry);
    } else {
      code += "(self, i):";
    }

    if (parser_.opts.include_dependence_headers &&
        !parser_.opts.python_typing) {
      code += GenIndents(2);
      code += "from " + import_entry.first + " import " + import_entry.second +
              "\n";
    }

    code += GenIndents(2) + "obj = " + TypeName(field) + "()";
    code += GenIndents(2) + "obj.Init(self._tab.Bytes, self._tab.Pos + ";
    code += NumToString(field.value.offset) + " + i * ";
    code += NumToString(InlineSize(vec_type));
    code += ")" + GenIndents(2) + "return obj\n\n";
  }

  // Get the value of a vector's non-struct member. Uses a named return
  // argument to conveniently set the zero value for the result.
  void GetArrayOfNonStruct(const StructDef& struct_def, const FieldDef& field,
                           std::string* code_ptr) const {
    auto& code = *code_ptr;
    GenReceiver(struct_def, code_ptr);
    code += namer_.Method(field);
    code += "(self, j = None):";
    code += GenIndents(2) + "if j is None:";
    code += GenIndents(3) + "return [" + GenGetter(field.value.type);
    code += "self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(";
    code += NumToString(field.value.offset) + " + i * ";
    code += NumToString(InlineSize(field.value.type.VectorType()));
    code += ")) for i in range(";
    code += "self." + namer_.Method(field) + "Length()" + ")]";
    code += GenIndents(2) + "elif j >= 0 and j < self." + namer_.Method(field) +
            "Length():";
    code += GenIndents(3) + "return " + GenGetter(field.value.type);
    code += "self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(";
    code += NumToString(field.value.offset) + " + j * ";
    code += NumToString(InlineSize(field.value.type.VectorType()));
    code += "))";
    code += GenIndents(2) + "else:";
    code += GenIndents(3) + "return None\n\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, ImportMap& imports) const {
    auto& code = *code_ptr;
    GenReceiver(struct_def, code_ptr);
    code += namer_.Method(field) + "(self)";

    const ImportMapEntry import_entry = {GenPackageReference(field.value.type),
                                         TypeName(field)};

    if (parser_.opts.python_typing) {
      const std::string return_type = ReturnType(struct_def, field);
      code += " -> Optional[" + return_type + "]";
      imports.insert(ImportMapEntry{"typing", "Optional"});
      imports.insert(import_entry);
    }
    code += ":";
    code += OffsetPrefix(field);
    if (field.value.type.struct_def->fixed) {
      code += Indent + Indent + Indent + "x = o + self._tab.Pos\n";
    } else {
      code += Indent + Indent + Indent;
      code += "x = self._tab.Indirect(o + self._tab.Pos)\n";
    }

    if (parser_.opts.include_dependence_headers &&
        !parser_.opts.python_typing) {
      code += Indent + Indent + Indent;
      code += "from " + import_entry.first + " import " + import_entry.second +
              "\n";
    }
    code += Indent + Indent + Indent + "obj = " + TypeName(field) + "()\n";
    code += Indent + Indent + Indent + "obj.Init(self._tab.Bytes, x)\n";
    code += Indent + Indent + Indent + "return obj\n";
    code += Indent + Indent + "return None\n\n";
  }

  // Get the value of a string.
  void GetStringField(const StructDef& struct_def, const FieldDef& field,
                      std::string* code_ptr, ImportMap& imports) const {
    auto& code = *code_ptr;
    GenReceiver(struct_def, code_ptr);
    code += namer_.Method(field);

    if (parser_.opts.python_typing) {
      code += "(self) -> Optional[str]:";
      imports.insert(ImportMapEntry{"typing", "Optional"});
    } else {
      code += "(self):";
    }

    code += OffsetPrefix(field);
    code += Indent + Indent + Indent + "return " + GenGetter(field.value.type);
    code += "o + self._tab.Pos)\n";
    code += Indent + Indent + "return None\n\n";
  }

  // Get the value of a union from an object.
  void GetUnionField(const StructDef& struct_def, const FieldDef& field,
                     std::string* code_ptr, ImportMap& imports) const {
    auto& code = *code_ptr;
    GenReceiver(struct_def, code_ptr);
    std::string return_ty = "flatbuffers.table.Table";

    bool is_native_table = TypeName(field) == "*flatbuffers.Table";
    ImportMapEntry import_entry;
    if (is_native_table) {
      import_entry = ImportMapEntry{"flatbuffers.table", "Table"};
    } else {
      return_ty = TypeName(field);
      import_entry = ImportMapEntry{GenPackageReference(field.value.type),
                                    TypeName(field)};
    }

    code += namer_.Method(field) + "(self)";
    if (parser_.opts.python_typing) {
      code += " -> Optional[" + return_ty + "]";
      imports.insert(ImportMapEntry{"typing", "Optional"});
      imports.insert(import_entry);
    }
    code += ":";
    code += OffsetPrefix(field);

    if (!parser_.opts.python_typing) {
      code += Indent + Indent + Indent;
      code += "from " + import_entry.first + " import " + import_entry.second +
              "\n";
    }
    code += Indent + Indent + Indent + "obj = Table(bytearray(), 0)\n";
    code += Indent + Indent + Indent + GenGetter(field.value.type);
    code += "obj, o)\n" + Indent + Indent + Indent + "return obj\n";
    code += Indent + Indent + "return None\n\n";
  }

  template <typename T>
  std::string ModuleFor(const T* def) const {
    if (!parser_.opts.one_file) {
      return namer_.NamespacedType(*def);
    }

    std::string filename =
        StripExtension(def->file) + parser_.opts.filename_suffix;
    if (parser_.file_being_parsed_ == def->file) {
      return "." + StripPath(filename);  // make it a "local" import
    }

    std::string module = parser_.opts.include_prefix + filename;
    std::replace(module.begin(), module.end(), '/', '.');
    return module;
  }

  // Generate the package reference when importing a struct or enum from its
  // module.
  std::string GenPackageReference(const Type& type) const {
    if (type.struct_def) return ModuleFor(type.struct_def);
    if (type.enum_def) return ModuleFor(type.enum_def);
    return "." + GenTypeGet(type);
  }

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

    GenReceiver(struct_def, code_ptr);
    code += namer_.Method(field);
    const ImportMapEntry import_entry = {GenPackageReference(field.value.type),
                                         TypeName(field)};

    if (parser_.opts.python_typing) {
      const std::string return_type = ReturnType(struct_def, field);
      code += "(self, j: int) -> Optional[" + return_type + "]";
      imports.insert(ImportMapEntry{"typing", "Optional"});
      imports.insert(import_entry);
    } else {
      code += "(self, j)";
    }
    code += ":" + OffsetPrefix(field);
    code += Indent + Indent + Indent + "x = self._tab.Vector(o)\n";
    code += Indent + Indent + Indent;
    code += "x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * ";
    code += NumToString(InlineSize(vectortype)) + "\n";
    if (!(vectortype.struct_def->fixed)) {
      code += Indent + Indent + Indent + "x = self._tab.Indirect(x)\n";
    }
    if (parser_.opts.include_dependence_headers &&
        !parser_.opts.python_typing) {
      code += Indent + Indent + Indent;
      code += "from " + import_entry.first + " import " + import_entry.second +
              "\n";
    }
    code += Indent + Indent + Indent + "obj = " + TypeName(field) + "()\n";
    code += Indent + Indent + Indent + "obj.Init(self._tab.Bytes, x)\n";
    code += Indent + Indent + Indent + "return obj\n";
    code += Indent + Indent + "return None\n\n";
  }

  // Get the value of a vector's non-struct member. Uses a named return
  // argument to conveniently set the zero value for the result.
  void GetMemberOfVectorOfNonStruct(const StructDef& struct_def,
                                    const FieldDef& field,
                                    std::string* code_ptr) const {
    auto& code = *code_ptr;
    auto vectortype = field.value.type.VectorType();

    GenReceiver(struct_def, code_ptr);
    code += namer_.Method(field);
    if (parser_.opts.python_typing) {
      code += "(self, j: int)";
    } else {
      code += "(self, j)";
    }
    code += ":";
    code += OffsetPrefix(field);
    code += Indent + Indent + Indent + "a = self._tab.Vector(o)\n";
    code += Indent + Indent + Indent;
    code += "return " + GenGetter(field.value.type);
    code += "a + flatbuffers.number_types.UOffsetTFlags.py_type(j * ";
    code += NumToString(InlineSize(vectortype)) + "))\n";
    if (IsString(vectortype)) {
      code += Indent + Indent + "return \"\"\n";
    } else {
      code += Indent + Indent + "return 0\n";
    }
    code += "\n";
  }

  // Returns a non-struct vector as a numpy array. Much faster
  // than iterating over the vector element by element.
  void GetVectorOfNonStructAsNumpy(const StructDef& struct_def,
                                   const FieldDef& field,
                                   std::string* code_ptr) const {
    auto& code = *code_ptr;
    auto vectortype = field.value.type.VectorType();

    // Currently, we only support accessing as numpy array if
    // the vector type is a scalar.
    if (!(IsScalar(vectortype.base_type))) {
      return;
    }

    GenReceiver(struct_def, code_ptr);
    code += namer_.Method(field) + "AsNumpy(self):";
    if (!IsArray(field.value.type)) {
      code += OffsetPrefix(field, false);

      code += GenIndents(3);
      code += "return ";
      code += "self._tab.GetVectorAsNumpy(flatbuffers.number_types.";
      code += namer_.Method(GenTypeGet(field.value.type));
      code += "Flags, o)";

      if (IsString(vectortype)) {
        code += GenIndents(2) + "return \"\"\n";
      } else {
        code += GenIndents(2) + "return 0\n";
      }
    } else {
      code += GenIndents(2) + "return ";
      code += "self._tab.GetArrayAsNumpy(flatbuffers.number_types.";
      code += namer_.Method(GenTypeGet(field.value.type.VectorType()));
      code += "Flags, self._tab.Pos + " + NumToString(field.value.offset) +
              ", " + NumToString("self." + namer_.Method(field) + "Length()") +
              ")\n";
    }
    code += "\n";
  }

  std::string NestedFlatbufferType(std::string unqualified_name) const {
    StructDef* nested_root = parser_.LookupStruct(unqualified_name);
    std::string qualified_name;
    if (nested_root == nullptr) {
      qualified_name = namer_.NamespacedType(
          parser_.current_namespace_->components, unqualified_name);
      // Double check qualified name just to be sure it exists.
      nested_root = parser_.LookupStruct(qualified_name);
    }
    FLATBUFFERS_ASSERT(nested_root);  // Guaranteed to exist by parser.
    return qualified_name;
  }

  // Returns a nested flatbuffer as itself.
  void GetVectorAsNestedFlatbuffer(const StructDef& struct_def,
                                   const FieldDef& field, std::string* code_ptr,
                                   ImportMap& imports) const {
    auto nested = field.attributes.Lookup("nested_flatbuffer");
    if (!nested) {
      return;
    }  // There is no nested flatbuffer.

    std::string unqualified_name = nested->constant;
    std::string qualified_name = NestedFlatbufferType(unqualified_name);
    if (qualified_name.empty()) {
      qualified_name = nested->constant;
    }

    // name may be partially qualified -- need to get the true unqualified name
    unqualified_name = namer_.Denamespace(qualified_name);

    const ImportMapEntry import_entry = {qualified_name, unqualified_name};

    auto& code = *code_ptr;
    GenReceiver(struct_def, code_ptr);
    code += namer_.Method(field) + "NestedRoot(self)";
    if (parser_.opts.python_typing) {
      code += " -> Union[" + unqualified_name + ", int]";
      imports.insert(ImportMapEntry{"typing", "Union"});
      imports.insert(import_entry);
    }
    code += ":";

    code += OffsetPrefix(field);

    if (!parser_.opts.python_typing) {
      code += Indent + Indent + Indent;
      code += "from " + import_entry.first + " import " + import_entry.second +
              "\n";
    }
    code += Indent + Indent + Indent + "return " + unqualified_name;
    code += ".GetRootAs";
    code += "(self._tab.Bytes, self._tab.Vector(o))\n";
    code += Indent + Indent + "return 0\n";
    code += "\n";
  }

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

    code += "\n";
    code += "def Create" + namer_.Function(struct_def);
    code += "(builder";
  }

  // Recursively generate arguments for a constructor, to deal with nested
  // structs.
  void StructBuilderArgs(const StructDef& struct_def,
                         const std::string nameprefix,
                         const std::string namesuffix, bool has_field_name,
                         const std::string fieldname_suffix,
                         std::string* code_ptr) const {
    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      auto& field = **it;
      const auto& field_type = field.value.type;
      const auto& type =
          IsArray(field_type) ? field_type.VectorType() : field_type;
      if (IsStruct(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.
        auto subprefix = nameprefix;
        if (has_field_name) {
          subprefix += namer_.Field(field) + fieldname_suffix;
        }
        StructBuilderArgs(*field.value.type.struct_def, subprefix, namesuffix,
                          has_field_name, fieldname_suffix, code_ptr);
      } else {
        auto& code = *code_ptr;
        code += std::string(", ") + nameprefix;
        if (has_field_name) {
          code += namer_.Field(field);
        }
        code += namesuffix;
      }
    }
  }

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

  // Recursively generate struct construction statements and instert manual
  // padding.
  void StructBuilderBody(const StructDef& struct_def, const char* nameprefix,
                         std::string* code_ptr, size_t index = 0,
                         bool in_array = false) const {
    auto& code = *code_ptr;
    std::string indent(index * 4, ' ');
    code +=
        indent + "    builder.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;
      const auto& field_type = field.value.type;
      const auto& type =
          IsArray(field_type) ? field_type.VectorType() : field_type;
      if (field.padding)
        code +=
            indent + "    builder.Pad(" + NumToString(field.padding) + ")\n";
      if (IsStruct(field_type)) {
        StructBuilderBody(*field_type.struct_def,
                          (nameprefix + (namer_.Field(field) + "_")).c_str(),
                          code_ptr, index, in_array);
      } else {
        const auto index_var = "_idx" + NumToString(index);
        if (IsArray(field_type)) {
          code += indent + "    for " + index_var + " in range(";
          code += NumToString(field_type.fixed_length);
          code += " , 0, -1):\n";
          in_array = true;
        }
        if (IsStruct(type)) {
          StructBuilderBody(*field_type.struct_def,
                            (nameprefix + (namer_.Field(field) + "_")).c_str(),
                            code_ptr, index + 1, in_array);
        } else {
          code += IsArray(field_type) ? "    " : "";
          code += indent + "    builder.Prepend" + GenMethod(field) + "(";
          code += nameprefix + namer_.Variable(field);
          size_t array_cnt = index + (IsArray(field_type) ? 1 : 0);
          for (size_t i = 0; in_array && i < array_cnt; i++) {
            code += "[_idx" + NumToString(i) + "-1]";
          }
          code += ")\n";
        }
      }
    }
  }

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

  // Get the value of a table's starting offset.
  void GetStartOfTable(const StructDef& struct_def,
                       std::string* code_ptr) const {
    auto& code = *code_ptr;
    const auto struct_type = namer_.Type(struct_def);
    // Generate method with struct name.

    const auto name = parser_.opts.python_no_type_prefix_suffix
                          ? "Start"
                          : struct_type + "Start";

    code += "def " + name;
    if (parser_.opts.python_typing) {
      code += "(builder: flatbuffers.Builder):\n";
    } else {
      code += "(builder):\n";
    }

    code += Indent + "builder.StartObject(";
    code += NumToString(struct_def.fields.vec.size());
    code += ")\n\n";

    if (!parser_.opts.one_file && !parser_.opts.python_no_type_prefix_suffix) {
      // Generate method without struct name.
      if (parser_.opts.python_typing) {
        code += "def Start(builder: flatbuffers.Builder):\n";
      } else {
        code += "def Start(builder):\n";
      }
      code += Indent + struct_type + "Start(builder)\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) const {
    auto& code = *code_ptr;
    const std::string field_var = namer_.Variable(field);
    const std::string field_method = namer_.Method(field);
    const std::string field_ty = GenFieldTy(field);

    const auto name = parser_.opts.python_no_type_prefix_suffix
                          ? "Add" + field_method
                          : namer_.Type(struct_def) + "Add" + field_method;

    // Generate method with struct name.
    code += "def " + name;
    if (parser_.opts.python_typing) {
      code += "(builder: flatbuffers.Builder, " + field_var + ": " + field_ty;
    } else {
      code += "(builder, " + field_var;
    }
    code += "):\n";
    code += Indent + "builder.Prepend";
    code += GenMethod(field) + "Slot(";
    code += NumToString(offset) + ", ";
    if (!IsScalar(field.value.type.base_type) && (!struct_def.fixed)) {
      code += "flatbuffers.number_types.UOffsetTFlags.py_type";
      code += "(" + field_var + ")";
    } else {
      code += field_var;
    }
    code += ", ";
    if (field.IsScalarOptional()) {
      code += "None";
    } else if (IsFloat(field.value.type.base_type)) {
      code += float_const_gen_.GenFloatConstant(field);
    } else {
      code += field.value.constant;
    }
    code += ")\n\n";

    if (!parser_.opts.one_file && !parser_.opts.python_no_type_prefix_suffix) {
      // Generate method without struct name.
      code += "def Add" + field_method;
      if (parser_.opts.python_typing) {
        code += "(builder: flatbuffers.Builder, " + field_var + ": " + field_ty;
      } else {
        code += "(builder, " + field_var;
      }
      code += "):\n";
      code += Indent + namer_.Type(struct_def) + "Add" + field_method;
      code += "(builder, ";
      code += field_var;
      code += ")\n\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) const {
    auto& code = *code_ptr;
    const std::string struct_type = namer_.Type(struct_def);
    const std::string field_method = namer_.Method(field);

    // Generate method with struct name.
    const auto name = parser_.opts.python_no_type_prefix_suffix
                          ? "Start" + field_method
                          : struct_type + "Start" + field_method;
    code += "def " + name;
    if (parser_.opts.python_typing) {
      code += "Vector(builder, numElems: int) -> int:\n";
    } else {
      code += "Vector(builder, numElems):\n";
    }

    code += Indent + "return 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";

    if (!parser_.opts.one_file && !parser_.opts.python_no_type_prefix_suffix) {
      // Generate method without struct name.
      if (parser_.opts.python_typing) {
        code += "def Start" + field_method +
                "Vector(builder, numElems: int) -> int:\n";
      } else {
        code += "def Start" + field_method + "Vector(builder, numElems):\n";
      }
      code += Indent + "return " + struct_type + "Start";
      code += field_method + "Vector(builder, numElems)\n\n";
    }
  }

  void BuildVectorCreationHelper(const StructDef& struct_def,
                                 const FieldDef& field, std::string* code_ptr,
                                 ImportMap& imports) const {
    auto& code = *code_ptr;
    const auto vector_type = field.value.type.VectorType();
    const bool is_struct_vector = IsStruct(vector_type);
    const bool is_scalar_vector =
        IsScalar(vector_type.base_type) || vector_type.enum_def != nullptr;
    const std::string struct_type = namer_.Type(struct_def);
    const std::string field_method = namer_.Method(field);
    const std::string helper_name =
        parser_.opts.python_no_type_prefix_suffix
            ? "Create" + field_method + "Vector"
            : struct_type + "Create" + field_method + "Vector";

    if (parser_.opts.python_typing) {
      imports.insert(ImportMapEntry{"typing", "Iterable"});
      code += "def " + helper_name +
              "(builder: flatbuffers.Builder, data: Iterable[Any]) -> int:\n";
    } else {
      code += "def " + helper_name + "(builder, data):\n";
    }

    if (is_scalar_vector || is_struct_vector) {
      auto alignment = InlineAlignment(vector_type);
      auto elem_size = InlineSize(vector_type);
      code += Indent + "data = list(data)\n";
      code += Indent + "builder.StartVector(" + NumToString(elem_size) +
              ", len(data), " + NumToString(alignment) + ")\n";
      code += Indent + "for item in reversed(data):\n";
      if (is_struct_vector) {
        code += Indent + Indent + "item.Pack(builder)\n";
      } else {
        code += Indent + Indent + "builder.Prepend" +
                namer_.Method(GenTypeBasic(vector_type)) + "(item)\n";
      }
      code += Indent + "return builder.EndVector()\n\n";
    } else {
      code += Indent + "return builder.CreateVectorOfTables(data)\n\n";
    }

    if (!parser_.opts.one_file && !parser_.opts.python_no_type_prefix_suffix) {
      if (parser_.opts.python_typing) {
        code += "def Create" + field_method +
                "Vector(builder: flatbuffers.Builder, data: Iterable[Any]) "
                "-> int:\n";
      } else {
        code += "def Create" + field_method + "Vector(builder, data):\n";
      }
      code += Indent + "return " + helper_name + "(builder, data)\n\n";
    }
  }

  // Set the value of one of the members of a table's vector and fills in the
  // elements from a bytearray. This is for simplifying the use of nested
  // flatbuffers.
  void BuildVectorOfTableFromBytes(const StructDef& struct_def,
                                   const FieldDef& field,
                                   std::string* code_ptr) const {
    auto nested = field.attributes.Lookup("nested_flatbuffer");
    if (!nested) {
      return;
    }  // There is no nested flatbuffer.

    auto& code = *code_ptr;
    const std::string field_method = namer_.Method(field);
    const std::string struct_type = namer_.Type(struct_def);

    // Generate method with struct and field name.
    code += "def " + struct_type + "Make" + field_method;
    code += "VectorFromBytes(builder, bytes):\n";
    code += Indent + "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 += ", len(bytes), " + NumToString(alignment);
    code += ")\n";
    code += Indent + "builder.head = builder.head - len(bytes)\n";
    code += Indent + "builder.Bytes[builder.head : builder.head + len(bytes)]";
    code += " = bytes\n";
    code += Indent + "return builder.EndVector()\n";

    if (!parser_.opts.one_file) {
      // Generate method without struct and field name.
      code += "def Make" + field_method + "VectorFromBytes(builder, bytes):\n";
      code += Indent + "return " + struct_type + "Make" + field_method +
              "VectorFromBytes(builder, bytes)\n";
    }
  }

  // Get the offset of the end of a table.
  void GetEndOffsetOnTable(const StructDef& struct_def,
                           std::string* code_ptr) const {
    auto& code = *code_ptr;

    const auto name = parser_.opts.python_no_type_prefix_suffix
                          ? "End"
                          : namer_.Type(struct_def) + "End";
    // Generate method with struct name.
    if (parser_.opts.python_typing) {
      code += "def " + name + "(builder: flatbuffers.Builder) -> int:\n";
    } else {
      code += "def " + name + "(builder):\n";
    }
    code += Indent + "return builder.EndObject()\n\n";

    if (!parser_.opts.one_file && !parser_.opts.python_no_type_prefix_suffix) {
      // Generate method without struct name.
      if (parser_.opts.python_typing) {
        code += "def End(builder: flatbuffers.Builder) -> int:\n";
      } else {
        code += "def End(builder):\n";
      }
      code += Indent + "return " + namer_.Type(struct_def) + "End(builder)";
      code += "\n";
    }
  }

  // Generate the receiver for function signatures.
  void GenReceiver(const StructDef& struct_def, std::string* code_ptr) const {
    auto& code = *code_ptr;
    code += Indent + "# " + namer_.Type(struct_def) + "\n";
    code += Indent + "def ";
  }

  // Generate a struct field, conditioned on its child type(s).
  void GenStructAccessor(const StructDef& struct_def, const FieldDef& field,
                         std::string* code_ptr, ImportMap& imports) const {
    GenComment(field.doc_comment, code_ptr, &def_comment, Indent.c_str());
    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, imports);
          }
          break;
        case BASE_TYPE_STRING:
          GetStringField(struct_def, field, code_ptr, imports);
          break;
        case BASE_TYPE_VECTOR: {
          auto vectortype = field.value.type.VectorType();
          if (vectortype.base_type == BASE_TYPE_STRUCT) {
            GetMemberOfVectorOfStruct(struct_def, field, code_ptr, imports);
          } else {
            GetMemberOfVectorOfNonStruct(struct_def, field, code_ptr);
            if (parser_.opts.python_gen_numpy) {
              GetVectorOfNonStructAsNumpy(struct_def, field, code_ptr);
            }
            GetVectorAsNestedFlatbuffer(struct_def, field, code_ptr, imports);
          }
          break;
        }
        case BASE_TYPE_ARRAY: {
          auto vectortype = field.value.type.VectorType();
          if (vectortype.base_type == BASE_TYPE_STRUCT) {
            GetArrayOfStruct(struct_def, field, code_ptr, imports);
          } else {
            GetArrayOfNonStruct(struct_def, field, code_ptr);
            if (parser_.opts.python_gen_numpy) {
              GetVectorOfNonStructAsNumpy(struct_def, field, code_ptr);
            }
            GetVectorAsNestedFlatbuffer(struct_def, field, code_ptr, imports);
          }
          break;
        }
        case BASE_TYPE_UNION:
          GetUnionField(struct_def, field, code_ptr, imports);
          break;
        default:
          FLATBUFFERS_ASSERT(0);
      }
    }
    if (IsVector(field.value.type) || IsArray(field.value.type)) {
      GetVectorLen(struct_def, field, code_ptr);
      GetVectorIsNone(struct_def, field, code_ptr);
    }
  }

  // Generate struct sizeof.
  void GenStructSizeOf(const StructDef& struct_def,
                       std::string* code_ptr) const {
    auto& code = *code_ptr;
    code += Indent + "@classmethod\n";
    if (parser_.opts.python_typing) {
      code += Indent + "def SizeOf(cls) -> int:\n";
    } else {
      code += Indent + "def SizeOf(cls):\n";
    }
    code +=
        Indent + Indent + "return " + NumToString(struct_def.bytesize) + "\n";
    code += "\n";
  }

  // Generate table constructors, conditioned on its members' types.
  void GenTableBuilders(const StructDef& struct_def, std::string* code_ptr,
                        ImportMap& imports) const {
    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);
        BuildVectorCreationHelper(struct_def, field, code_ptr, imports);
        BuildVectorOfTableFromBytes(struct_def, field, code_ptr);
      }
    }

    GetEndOffsetOnTable(struct_def, code_ptr);
  }

  // Generate function to check for proper file identifier
  void GenHasFileIdentifier(const StructDef& struct_def,
                            std::string* code_ptr) const {
    auto& code = *code_ptr;
    std::string escapedID;
    // In the event any of file_identifier characters are special(NULL, \, etc),
    // problems occur. To prevent this, convert all chars to their hex-escaped
    // equivalent.
    for (auto it = parser_.file_identifier_.begin();
         it != parser_.file_identifier_.end(); ++it) {
      escapedID += "\\x" + IntToStringHex(*it, 2);
    }

    code += Indent + "@classmethod\n";
    code += Indent + "def " + namer_.Type(struct_def);
    code += "BufferHasIdentifier(cls, buf, offset, size_prefixed=False):";
    code += "\n";
    code += Indent + Indent;
    code += "return flatbuffers.util.BufferHasIdentifier(buf, offset, b\"";
    code += escapedID;
    code += "\", size_prefixed=size_prefixed)\n";
    code += "\n";
  }

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

    GenComment(struct_def.doc_comment, code_ptr, &def_comment);
    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);
      if (parser_.file_identifier_.length()) {
        // Generate a special function to test file_identifier
        GenHasFileIdentifier(struct_def, code_ptr);
      }
    } else {
      // Generates the SizeOf method for all structs.
      GenStructSizeOf(struct_def, code_ptr);
    }
    // Generates the Init method that sets the field in a pre-existing
    // accessor object. This is to allow object reuse.
    InitializeExisting(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;

      GenStructAccessor(struct_def, field, code_ptr, imports);
    }

    if (struct_def.fixed) {
      // creates a struct constructor function
      GenStructBuilder(struct_def, code_ptr);
    } else {
      // Creates a set of functions that allow table construction.
      GenTableBuilders(struct_def, code_ptr, imports);
    }
  }

  void GenReceiverForObjectAPI(const StructDef& struct_def,
                               std::string* code_ptr) const {
    auto& code = *code_ptr;
    code += GenIndents(1) + "# " + namer_.ObjectType(struct_def);
    code += GenIndents(1) + "def ";
  }

  void BeginClassForObjectAPI(const StructDef& struct_def,
                              std::string* code_ptr) const {
    auto& code = *code_ptr;
    code += "\n";
    code += "class " + namer_.ObjectType(struct_def) + "(object):";
    code += "\n";
  }

  // Gets the accoresponding python builtin type of a BaseType for scalars and
  // string.
  std::string GetBasePythonTypeForScalarAndString(
      const BaseType& base_type) const {
    if (IsBool(base_type)) {
      return "bool";
    } else if (IsFloat(base_type)) {
      return "float";
    } else if (IsInteger(base_type)) {
      return "int";
    } else if (base_type == BASE_TYPE_STRING) {
      return "Optional[str]";
    } else {
      FLATBUFFERS_ASSERT(false && "base_type is not a scalar or string type.");
      return "";
    }
  }

  std::string GetDefaultValue(const FieldDef& field) const {
    BaseType base_type = field.value.type.base_type;
    if (field.IsScalarOptional()) {
      return "None";
    } else if (IsBool(base_type)) {
      return field.value.constant == "0" ? "False" : "True";
    } else if (IsFloat(base_type)) {
      return float_const_gen_.GenFloatConstant(field);
    } else if (IsInteger(base_type)) {
      return field.value.constant;
    } else {
      // For string, struct, and table.
      return "None";
    }
  }

  void GenUnionInit(const FieldDef& field, std::string* field_types_ptr,
                    std::set<std::string>* import_list,
                    std::set<std::string>* import_typing_list) const {
    // Gets all possible types in the union.
    import_typing_list->insert("Union");
    auto& field_types = *field_types_ptr;
    field_types = "Union[";

    std::string separator_string = ", ";
    auto enum_def = field.value.type.enum_def;
    for (auto it = enum_def->Vals().begin(); it != enum_def->Vals().end();
         ++it) {
      auto& ev = **it;
      // Union only supports string and table.
      std::string field_type;
      switch (ev.union_type.base_type) {
        case BASE_TYPE_STRUCT:
          field_type = namer_.ObjectType(*ev.union_type.struct_def);
          if (parser_.opts.include_dependence_headers) {
            auto package_reference = GenPackageReference(ev.union_type);
            field_type = package_reference + "." + field_type;
            import_list->insert("import " + package_reference);
          }
          field_type = "'" + field_type + "'";
          break;
        case BASE_TYPE_STRING:
          field_type += "str";
          break;
        case BASE_TYPE_NONE:
          field_type += "None";
          break;
        default:
          break;
      }
      field_types += field_type + separator_string;
    }

    // Removes the last separator_string.
    field_types.erase(field_types.length() - separator_string.size());
    field_types += "]";

    // Gets the import lists for the union.
    if (parser_.opts.include_dependence_headers) {
      const auto package_reference = GenPackageReference(field.value.type);
      import_list->insert("import " + package_reference);
    }
  }

  void GenStructInit(const FieldDef& field, std::string* out_ptr,
                     std::set<std::string>* import_list,
                     std::set<std::string>* import_typing_list) const {
    import_typing_list->insert("Optional");
    auto& output = *out_ptr;
    const Type& type = field.value.type;
    const std::string object_type = namer_.ObjectType(*type.struct_def);
    if (parser_.opts.include_dependence_headers) {
      auto package_reference = GenPackageReference(type);
      output = package_reference + "." + object_type + "]";
      import_list->insert("import " + package_reference);
    } else {
      output = object_type + "]";
    }
    output = "Optional[" + output;
  }

  void GenVectorInit(const FieldDef& field, std::string* field_type_ptr,
                     std::set<std::string>* import_list,
                     std::set<std::string>* import_typing_list) const {
    import_typing_list->insert("List");
    auto& field_type = *field_type_ptr;
    const Type& vector_type = field.value.type.VectorType();
    const BaseType base_type = vector_type.base_type;
    if (base_type == BASE_TYPE_STRUCT) {
      const std::string object_type =
          namer_.ObjectType(*vector_type.struct_def);
      field_type = object_type + "]";
      if (parser_.opts.include_dependence_headers) {
        auto package_reference = GenPackageReference(vector_type);
        field_type = package_reference + "." + object_type + "]";
        import_list->insert("import " + package_reference);
      }
      field_type = "Optional[List[" + field_type + "]";
    } else {
      field_type = "Optional[List[" +
                   GetBasePythonTypeForScalarAndString(base_type) + "]]";
    }
  }

  void GenInitialize(const StructDef& struct_def, std::string* code_ptr,
                     std::set<std::string>* import_list) const {
    std::string signature_params;
    std::string init_body;
    std::set<std::string> import_typing_list;

    signature_params += GenIndents(2) + "self,";

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

      // Determines field type, default value, and typing imports.
      auto base_type = field.value.type.base_type;
      std::string field_type;
      switch (base_type) {
        case BASE_TYPE_UNION: {
          GenUnionInit(field, &field_type, import_list, &import_typing_list);
          break;
        }
        case BASE_TYPE_STRUCT: {
          GenStructInit(field, &field_type, import_list, &import_typing_list);
          break;
        }
        case BASE_TYPE_VECTOR:
        case BASE_TYPE_ARRAY: {
          GenVectorInit(field, &field_type, import_list, &import_typing_list);
          break;
        }
        default:
          // Scalar or sting fields.
          field_type = GetBasePythonTypeForScalarAndString(base_type);
          if (field.IsScalarOptional()) {
            import_typing_list.insert("Optional");
            field_type = "Optional[" + field_type + "]";
          }
          break;
      }

      const auto default_value = GetDefaultValue(field);
      // Writes the init statement.
      const auto field_field = namer_.Field(field);

      // Build signature with keyword arguments, type hints, and default values.
      signature_params +=
          GenIndents(2) + field_field + " = " + default_value + ",";

      // Build the body of the __init__ method.
      init_body += GenIndents(2) + "self." + field_field + " = " + field_field +
                   "  # type: " + field_type;
    }

    // Writes __init__ method.
    auto& code_base = *code_ptr;
    GenReceiverForObjectAPI(struct_def, code_ptr);
    code_base += "__init__(" + signature_params + GenIndents(1) + "):";
    if (init_body.empty()) {
      code_base += GenIndents(2) + "pass";
    } else {
      code_base += init_body;
    }
    code_base += "\n";

    // Merges the typing imports into import_list.
    if (!import_typing_list.empty()) {
      // Adds the try statement.
      std::string typing_imports = "try:";
      typing_imports += GenIndents(1) + "from typing import ";
      std::string separator_string = ", ";
      for (auto it = import_typing_list.begin(); it != import_typing_list.end();
           ++it) {
        const std::string& im = *it;
        typing_imports += im + separator_string;
      }
      // Removes the last separator_string.
      typing_imports.erase(typing_imports.length() - separator_string.size());

      // Adds the except statement.
      typing_imports += "\n";
      typing_imports += "except:";
      typing_imports += GenIndents(1) + "pass";
      import_list->insert(typing_imports);
    }

    // Removes the import of the struct itself, if applied.
    auto struct_import = "import " + namer_.NamespacedType(struct_def);
    import_list->erase(struct_import);
  }

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

    code += GenIndents(1) + "@classmethod";
    code += GenIndents(1) + "def InitFromBuf(cls, buf, pos):";
    code += GenIndents(2) + struct_var + " = " + struct_type + "()";
    code += GenIndents(2) + struct_var + ".Init(buf, pos)";
    code += GenIndents(2) + "return cls.InitFromObj(" + struct_var + ")";
    code += "\n";
  }

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

    code += GenIndents(1) + "@classmethod";
    code += GenIndents(1) + "def InitFromPackedBuf(cls, buf, pos=0):";
    code += GenIndents(2) +
            "n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos)";
    code += GenIndents(2) + "return cls.InitFromBuf(buf, pos+n)";
    code += "\n";
  }

  void InitializeFromObjForObject(const StructDef& struct_def,
                                  std::string* code_ptr) const {
    auto& code = *code_ptr;
    const auto struct_var = namer_.Variable(struct_def);
    const auto struct_object = namer_.ObjectType(struct_def);

    code += GenIndents(1) + "@classmethod";
    code += GenIndents(1) + "def InitFromObj(cls, " + struct_var + "):";
    code += GenIndents(2) + "x = " + struct_object + "()";
    code += GenIndents(2) + "x._UnPack(" + struct_var + ")";
    code += GenIndents(2) + "return x";
    code += "\n";
  }

  void GenCompareOperator(const StructDef& struct_def,
                          std::string* code_ptr) const {
    auto& code = *code_ptr;
    code += GenIndents(1) + "def __eq__(self, other):";
    code += GenIndents(2) + "return type(self) == type(other)";
    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      auto& field = **it;
      if (field.deprecated) continue;

      // Writes the comparison statement for this field.
      const auto field_name = namer_.Field(field);
      if (parser_.opts.python_gen_numpy &&
          field.value.type.base_type == BASE_TYPE_VECTOR) {
        code += " and \\" + GenIndents(3) + "np.array_equal(self." +
                field_name + ", " + "other." + field_name + ")";
      } else {
        code += " and \\" + GenIndents(3) + "self." + field_name +
                " == " + "other." + field_name;
      }
    }
    code += "\n";
  }

  void GenUnPackForStruct(const StructDef& struct_def, const FieldDef& field,
                          std::string* code_ptr) const {
    auto& code = *code_ptr;
    const auto struct_var = namer_.Variable(struct_def);
    const auto field_field = namer_.Field(field);
    const auto field_method = namer_.Method(field);
    auto field_type = TypeName(field);

    if (parser_.opts.include_dependence_headers) {
      auto package_reference = GenPackageReference(field.value.type);
      field_type = package_reference + "." + TypeName(field);
    }

    code += GenIndents(2) + "if " + struct_var + "." + field_method + "(";
    // if field is a struct, we need to create an instance for it first.
    if (struct_def.fixed && field.value.type.base_type == BASE_TYPE_STRUCT) {
      code += field_type + "()";
    }
    code += ") is not None:";
    code += GenIndents(3) + "self." + field_field + " = " +
            namer_.ObjectType(field_type) + +".InitFromObj(" + struct_var +
            "." + field_method + "(";
    // A struct's accessor requires a struct buf instance.
    if (struct_def.fixed && field.value.type.base_type == BASE_TYPE_STRUCT) {
      code += field_type + "()";
    }
    code += "))";
  }

  void GenUnPackForUnion(const StructDef& struct_def, const FieldDef& field,
                         std::string* code_ptr) const {
    auto& code = *code_ptr;
    const auto field_field = namer_.Field(field);
    const auto field_method = namer_.Method(field);
    const auto struct_var = namer_.Variable(struct_def);
    const EnumDef& enum_def = *field.value.type.enum_def;
    auto union_fn = namer_.Function(enum_def);

    if (parser_.opts.include_dependence_headers) {
      union_fn = namer_.NamespacedType(enum_def) + "." + union_fn;
    }
    code += GenIndents(2) + "self." + field_field + " = " + union_fn +
            "Creator(" + "self." + field_field + "Type, " + struct_var + "." +
            field_method + "())";
  }

  void GenUnPackForStructVector(const StructDef& struct_def,
                                const FieldDef& field,
                                std::string* code_ptr) const {
    auto& code = *code_ptr;
    const auto field_field = namer_.Field(field);
    const auto field_method = namer_.Method(field);
    const auto struct_var = namer_.Variable(struct_def);

    code += GenIndents(2) + "if not " + struct_var + "." + field_method +
            "IsNone():";
    code += GenIndents(3) + "self." + field_field + " = []";
    code += GenIndents(3) + "for i in range(" + struct_var + "." +
            field_method + "Length()):";

    auto field_type = TypeName(field);
    auto one_instance = field_type + "_";
    one_instance[0] = CharToLower(one_instance[0]);
    if (parser_.opts.include_dependence_headers) {
      auto package_reference = GenPackageReference(field.value.type);
      field_type = package_reference + "." + TypeName(field);
    }
    code += GenIndents(4) + "if " + struct_var + "." + field_method +
            "(i) is None:";
    code += GenIndents(5) + "self." + field_field + ".append(None)";
    code += GenIndents(4) + "else:";
    code += GenIndents(5) + one_instance + " = " +
            namer_.ObjectType(field_type) + ".InitFromObj(" + struct_var + "." +
            field_method + "(i))";
    code +=
        GenIndents(5) + "self." + field_field + ".append(" + one_instance + ")";
  }

  void GenUnpackForTableVector(const StructDef& struct_def,
                               const FieldDef& field,
                               std::string* code_ptr) const {
    auto& code = *code_ptr;
    const auto field_field = namer_.Field(field);
    const auto field_method = namer_.Method(field);
    const auto struct_var = namer_.Variable(struct_def);

    code += GenIndents(2) + "if not " + struct_var + "." + field_method +
            "IsNone():";
    code += GenIndents(3) + "self." + field_field + " = []";
    code += GenIndents(3) + "for i in range(" + struct_var + "." +
            field_method + "Length()):";

    auto field_type = TypeName(field);
    auto one_instance = field_type + "_";
    one_instance[0] = CharToLower(one_instance[0]);
    if (parser_.opts.include_dependence_headers) {
      auto package_reference = GenPackageReference(field.value.type);
      field_type = package_reference + "." + TypeName(field);
    }
    code += GenIndents(4) + "if " + struct_var + "." + field_method +
            "(i) is None:";
    code += GenIndents(5) + "self." + field_field + ".append(None)";
    code += GenIndents(4) + "else:";
    code += GenIndents(5) + one_instance + " = " +
            namer_.ObjectType(field_type) + ".InitFromObj(" + struct_var + "." +
            field_method + "(i))";
    code +=
        GenIndents(5) + "self." + field_field + ".append(" + one_instance + ")";
  }

  void GenUnpackforScalarVectorHelper(const StructDef& struct_def,
                                      const FieldDef& field,
                                      std::string* code_ptr,
                                      int indents) const {
    auto& code = *code_ptr;
    const auto field_field = namer_.Field(field);
    const auto field_method = namer_.Method(field);
    const auto struct_var = namer_.Variable(struct_def);

    code += GenIndents(indents) + "self." + field_field + " = []";
    code += GenIndents(indents) + "for i in range(" + struct_var + "." +
            field_method + "Length()):";
    code += GenIndents(indents + 1) + "self." + field_field + ".append(" +
            struct_var + "." + field_method + "(i))";
  }

  void GenUnPackForScalarVector(const StructDef& struct_def,
                                const FieldDef& field,
                                std::string* code_ptr) const {
    auto& code = *code_ptr;
    const auto field_field = namer_.Field(field);
    const auto field_method = namer_.Method(field);
    const auto struct_var = namer_.Variable(struct_def);

    code += GenIndents(2) + "if not " + struct_var + "." + field_method +
            "IsNone():";

    // String does not have the AsNumpy method.
    if (!(IsScalar(field.value.type.VectorType().base_type))) {
      GenUnpackforScalarVectorHelper(struct_def, field, code_ptr, 3);
      return;
    }

    if (parser_.opts.python_gen_numpy) {
      code += GenIndents(3) + "if np is None:";
      GenUnpackforScalarVectorHelper(struct_def, field, code_ptr, 4);

      // If numpy exists, use the AsNumpy method to optimize the unpack speed.
      code += GenIndents(3) + "else:";
      code += GenIndents(4) + "self." + field_field + " = " + struct_var + "." +
              field_method + "AsNumpy()";
    } else {
      GenUnpackforScalarVectorHelper(struct_def, field, code_ptr, 3);
    }
  }

  void GenUnPackForString(const StructDef& struct_def, const FieldDef& field,
                          std::string* code_ptr) const {
    auto& code = *code_ptr;
    const auto field_field = namer_.Field(field);
    const auto field_method = namer_.Method(field);
    const auto struct_var = namer_.Variable(struct_def);

    code += GenIndents(2) + "self." + field_field + " = " + struct_var + "." +
            field_method + "()";
    code += GenIndents(2) + "if self." + field_field + " is not None:";
    code += GenIndents(3) + "self." + field_field + " = self." + field_field +
            ".decode('utf-8')";
  }

  void GenUnPackForScalar(const StructDef& struct_def, const FieldDef& field,
                          std::string* code_ptr) const {
    auto& code = *code_ptr;
    const auto field_field = namer_.Field(field);
    const auto field_method = namer_.Method(field);
    const auto struct_var = namer_.Variable(struct_def);

    code += GenIndents(2) + "self." + field_field + " = " + struct_var + "." +
            field_method + "()";
  }

  // Generates the UnPack method for the object class.
  void GenUnPack(const StructDef& struct_def, std::string* code_ptr) const {
    std::string code;
    // Items that needs to be imported. No duplicate modules will be imported.
    std::set<std::string> import_list;

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

      switch (field.value.type.base_type) {
        case BASE_TYPE_STRUCT: {
          GenUnPackForStruct(struct_def, field, &code);
          break;
        }
        case BASE_TYPE_UNION: {
          GenUnPackForUnion(struct_def, field, &code);
          break;
        }
        case BASE_TYPE_ARRAY:
        case BASE_TYPE_VECTOR: {
          auto vectortype = field.value.type.VectorType();
          if (vectortype.base_type == BASE_TYPE_STRUCT) {
            GenUnPackForStructVector(struct_def, field, &code);
          } else {
            GenUnPackForScalarVector(struct_def, field, &code);
          }
          break;
        }
        case BASE_TYPE_STRING: {
          if (parser_.opts.python_decode_obj_api_strings) {
            GenUnPackForString(struct_def, field, &code);
          } else {
            GenUnPackForScalar(struct_def, field, &code);
          }
          break;
        }
        default:
          GenUnPackForScalar(struct_def, field, &code);
      }
    }

    // Writes import statements and code into the generated file.
    auto& code_base = *code_ptr;
    const auto struct_var = namer_.Variable(struct_def);

    GenReceiverForObjectAPI(struct_def, code_ptr);
    code_base += "_UnPack(self, " + struct_var + "):";
    code_base += GenIndents(2) + "if " + struct_var + " is None:";
    code_base += GenIndents(3) + "return";

    // Write the import statements.
    for (std::set<std::string>::iterator it = import_list.begin();
         it != import_list.end(); ++it) {
      code_base += GenIndents(2) + *it;
    }

    // Write the code.
    code_base += code;
    code_base += "\n";
  }

  void GenPackForStruct(const StructDef& struct_def,
                        std::string* code_ptr) const {
    auto& code = *code_ptr;
    const auto struct_fn = namer_.Function(struct_def);

    GenReceiverForObjectAPI(struct_def, code_ptr);
    code += "Pack(self, builder):";
    code += GenIndents(2) + "return Create" + struct_fn + "(builder";

    StructBuilderArgs(struct_def,
                      /* nameprefix = */ "self.",
                      /* namesuffix = */ "",
                      /* has_field_name = */ true,
                      /* fieldname_suffix = */ ".", code_ptr);
    code += ")\n";
  }

  void GenPackForStructVectorField(const StructDef& struct_def,
                                   const FieldDef& field,
                                   std::string* code_prefix_ptr,
                                   std::string* code_ptr) const {
    auto& code_prefix = *code_prefix_ptr;
    auto& code = *code_ptr;
    const auto field_field = namer_.Field(field);
    const auto struct_type = namer_.Type(struct_def);
    const auto field_method = namer_.Method(field);

    // Creates the field.
    code_prefix += GenIndents(2) + "if self." + field_field + " is not None:";
    if (field.value.type.struct_def->fixed) {
      code_prefix += GenIndents(3) + struct_type + "Start" + field_method +
                     "Vector(builder, len(self." + field_field + "))";
      code_prefix += GenIndents(3) + "for i in reversed(range(len(self." +
                     field_field + "))):";
      code_prefix +=
          GenIndents(4) + "self." + field_field + "[i].Pack(builder)";
      code_prefix += GenIndents(3) + field_field + " = builder.EndVector()";
    } else {
      // If the vector is a struct vector, we need to first build accessor for
      // each struct element.
      code_prefix += GenIndents(3) + field_field + "list = []";
      code_prefix += GenIndents(3);
      code_prefix += "for i in range(len(self." + field_field + ")):";
      code_prefix += GenIndents(4) + field_field + "list.append(self." +
                     field_field + "[i].Pack(builder))";

      code_prefix += GenIndents(3) + struct_type + "Start" + field_method +
                     "Vector(builder, len(self." + field_field + "))";
      code_prefix += GenIndents(3) + "for i in reversed(range(len(self." +
                     field_field + "))):";
      code_prefix += GenIndents(4) + "builder.PrependUOffsetTRelative" + "(" +
                     field_field + "list[i])";
      code_prefix += GenIndents(3) + field_field + " = builder.EndVector()";
    }

    // Adds the field into the struct.
    code += GenIndents(2) + "if self." + field_field + " is not None:";
    code += GenIndents(3) + struct_type + "Add" + field_method + "(builder, " +
            field_field + ")";
  }

  void GenPackForScalarVectorFieldHelper(const StructDef& struct_def,
                                         const FieldDef& field,
                                         std::string* code_ptr,
                                         int indents) const {
    auto& code = *code_ptr;
    const auto field_field = namer_.Field(field);
    const auto field_method = namer_.Method(field);
    const auto struct_type = namer_.Type(struct_def);
    const auto vectortype = field.value.type.VectorType();

    code += GenIndents(indents) + struct_type + "Start" + field_method +
            "Vector(builder, len(self." + field_field + "))";
    code += GenIndents(indents) + "for i in reversed(range(len(self." +
            field_field + "))):";
    code += GenIndents(indents + 1) + "builder.Prepend";

    std::string type_name;
    switch (vectortype.base_type) {
      case BASE_TYPE_BOOL:
        type_name = "Bool";
        break;
      case BASE_TYPE_CHAR:
        type_name = "Byte";
        break;
      case BASE_TYPE_UCHAR:
        type_name = "Uint8";
        break;
      case BASE_TYPE_SHORT:
        type_name = "Int16";
        break;
      case BASE_TYPE_USHORT:
        type_name = "Uint16";
        break;
      case BASE_TYPE_INT:
        type_name = "Int32";
        break;
      case BASE_TYPE_UINT:
        type_name = "Uint32";
        break;
      case BASE_TYPE_LONG:
        type_name = "Int64";
        break;
      case BASE_TYPE_ULONG:
        type_name = "Uint64";
        break;
      case BASE_TYPE_FLOAT:
        type_name = "Float32";
        break;
      case BASE_TYPE_DOUBLE:
        type_name = "Float64";
        break;
      case BASE_TYPE_STRING:
        type_name = "UOffsetTRelative";
        break;
      default:
        type_name = "VOffsetT";
        break;
    }
    code += type_name;
  }

  void GenPackForScalarVectorField(const StructDef& struct_def,
                                   const FieldDef& field,
                                   std::string* code_prefix_ptr,
                                   std::string* code_ptr) const {
    auto& code = *code_ptr;
    auto& code_prefix = *code_prefix_ptr;
    const auto field_field = namer_.Field(field);
    const auto field_method = namer_.Method(field);
    const auto struct_type = namer_.Type(struct_def);

    // Adds the field into the struct.
    code += GenIndents(2) + "if self." + field_field + " is not None:";
    code += GenIndents(3) + struct_type + "Add" + field_method + "(builder, " +
            field_field + ")";

    // Creates the field.
    code_prefix += GenIndents(2) + "if self." + field_field + " is not None:";
    // If the vector is a string vector, we need to first build accessor for
    // each string element. And this generated code, needs to be
    // placed ahead of code_prefix.
    auto vectortype = field.value.type.VectorType();
    if (IsString(vectortype)) {
      code_prefix += GenIndents(3) + field_field + "list = []";
      code_prefix +=
          GenIndents(3) + "for i in range(len(self." + field_field + ")):";
      code_prefix += GenIndents(4) + field_field +
                     "list.append(builder.CreateString(self." + field_field +
                     "[i]))";
      GenPackForScalarVectorFieldHelper(struct_def, field, code_prefix_ptr, 3);
      code_prefix += "(" + field_field + "list[i])";
      code_prefix += GenIndents(3) + field_field + " = builder.EndVector()";
      return;
    }

    if (parser_.opts.python_gen_numpy) {
      code_prefix += GenIndents(3) + "if np is not None and type(self." +
                     field_field + ") is np.ndarray:";
      code_prefix += GenIndents(4) + field_field +
                     " = builder.CreateNumpyVector(self." + field_field + ")";
      code_prefix += GenIndents(3) + "else:";
      GenPackForScalarVectorFieldHelper(struct_def, field, code_prefix_ptr, 4);
      code_prefix += "(self." + field_field + "[i])";
      code_prefix += GenIndents(4) + field_field + " = builder.EndVector()";
    } else {
      GenPackForScalarVectorFieldHelper(struct_def, field, code_prefix_ptr, 3);
      code_prefix += "(self." + field_field + "[i])";
      code_prefix += GenIndents(4) + field_field + " = builder.EndVector()";
    }
  }

  void GenPackForStructField(const StructDef& struct_def, const FieldDef& field,
                             std::string* code_prefix_ptr,
                             std::string* code_ptr) const {
    auto& code_prefix = *code_prefix_ptr;
    auto& code = *code_ptr;
    const auto field_field = namer_.Field(field);
    const auto field_method = namer_.Method(field);
    const auto struct_type = namer_.Type(struct_def);

    if (field.value.type.struct_def->fixed) {
      // Pure struct fields need to be created along with their parent
      // structs.
      code += GenIndents(2) + "if self." + field_field + " is not None:";
      code += GenIndents(3) + field_field + " = self." + field_field +
              ".Pack(builder)";
    } else {
      // Tables need to be created before their parent structs are created.
      code_prefix += GenIndents(2) + "if self." + field_field + " is not None:";
      code_prefix += GenIndents(3) + field_field + " = self." + field_field +
                     ".Pack(builder)";
      code += GenIndents(2) + "if self." + field_field + " is not None:";
    }

    code += GenIndents(3) + struct_type + "Add" + field_method + "(builder, " +
            field_field + ")";
  }

  void GenPackForUnionField(const StructDef& struct_def, const FieldDef& field,
                            std::string* code_prefix_ptr,
                            std::string* code_ptr) const {
    auto& code_prefix = *code_prefix_ptr;
    auto& code = *code_ptr;
    const auto field_field = namer_.Field(field);
    const auto field_method = namer_.Method(field);
    const auto struct_type = namer_.Type(struct_def);

    // TODO(luwa): TypeT should be moved under the None check as well.
    code_prefix += GenIndents(2) + "if self." + field_field + " is not None:";
    code_prefix += GenIndents(3) + field_field + " = self." + field_field +
                   ".Pack(builder)";
    code += GenIndents(2) + "if self." + field_field + " is not None:";
    code += GenIndents(3) + struct_type + "Add" + field_method + "(builder, " +
            field_field + ")";
  }

  void GenPackForTable(const StructDef& struct_def,
                       std::string* code_ptr) const {
    auto& code_base = *code_ptr;
    std::string code, code_prefix;
    const auto struct_var = namer_.Variable(struct_def);
    const auto struct_type = namer_.Type(struct_def);

    GenReceiverForObjectAPI(struct_def, code_ptr);
    code_base += "Pack(self, builder):";
    code += GenIndents(2) + struct_type + "Start(builder)";
    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      auto& field = **it;
      if (field.deprecated) continue;

      const auto field_method = namer_.Method(field);
      const auto field_field = namer_.Field(field);

      switch (field.value.type.base_type) {
        case BASE_TYPE_STRUCT: {
          GenPackForStructField(struct_def, field, &code_prefix, &code);
          break;
        }
        case BASE_TYPE_UNION: {
          GenPackForUnionField(struct_def, field, &code_prefix, &code);
          break;
        }
        case BASE_TYPE_ARRAY:
        case BASE_TYPE_VECTOR: {
          auto vectortype = field.value.type.VectorType();
          if (vectortype.base_type == BASE_TYPE_STRUCT) {
            GenPackForStructVectorField(struct_def, field, &code_prefix, &code);
          } else {
            GenPackForScalarVectorField(struct_def, field, &code_prefix, &code);
          }
          break;
        }
        case BASE_TYPE_STRING: {
          code_prefix +=
              GenIndents(2) + "if self." + field_field + " is not None:";
          code_prefix += GenIndents(3) + field_field +
                         " = builder.CreateString(self." + field_field + ")";
          code += GenIndents(2) + "if self." + field_field + " is not None:";
          code += GenIndents(3) + struct_type + "Add" + field_method +
                  "(builder, " + field_field + ")";
          break;
        }
        default:
          // Generates code for scalar values. If the value equals to the
          // default value, builder will automatically ignore it. So we don't
          // need to check the value ahead.
          code += GenIndents(2) + struct_type + "Add" + field_method +
                  "(builder, self." + field_field + ")";
          break;
      }
    }

    code += GenIndents(2) + struct_var + " = " + struct_type + "End(builder)";
    code += GenIndents(2) + "return " + struct_var;

    code_base += code_prefix + code;
    code_base += "\n";
  }

  void GenStructForObjectAPI(const StructDef& struct_def,
                             std::string* code_ptr) const {
    if (struct_def.generated) return;

    std::set<std::string> import_list;
    std::string code;

    // Creates an object class for a struct or a table
    BeginClassForObjectAPI(struct_def, &code);

    GenInitialize(struct_def, &code, &import_list);

    InitializeFromBuf(struct_def, &code);

    InitializeFromPackedBuf(struct_def, &code);

    InitializeFromObjForObject(struct_def, &code);

    if (parser_.opts.gen_compare) {
      GenCompareOperator(struct_def, &code);
    }

    GenUnPack(struct_def, &code);

    if (struct_def.fixed) {
      GenPackForStruct(struct_def, &code);
    } else {
      GenPackForTable(struct_def, &code);
    }

    // Adds the imports at top.
    auto& code_base = *code_ptr;
    code_base += "\n";
    for (auto it = import_list.begin(); it != import_list.end(); it++) {
      auto im = *it;
      code_base += im + "\n";
    }
    code_base += code;
  }

  void GenUnionCreatorForStruct(const EnumDef& enum_def, const EnumVal& ev,
                                std::string* code_ptr) const {
    auto& code = *code_ptr;
    const auto union_type = namer_.Type(enum_def);
    const auto variant = namer_.Variant(ev);
    auto field_type = namer_.ObjectType(*ev.union_type.struct_def);

    code +=
        GenIndents(1) + "if unionType == " + union_type + "." + variant + ":";
    if (parser_.opts.include_dependence_headers) {
      auto package_reference = GenPackageReference(ev.union_type);
      code += GenIndents(2) + "import " + package_reference;
      field_type = package_reference + "." + field_type;
    }
    code += GenIndents(2) + "return " + field_type +
            ".InitFromBuf(table.Bytes, table.Pos)";
  }

  void GenUnionCreatorForString(const EnumDef& enum_def, const EnumVal& ev,
                                std::string* code_ptr) const {
    auto& code = *code_ptr;
    const auto union_type = namer_.Type(enum_def);
    const auto variant = namer_.Variant(ev);

    code +=
        GenIndents(1) + "if unionType == " + union_type + "()." + variant + ":";
    code += GenIndents(2) + "tab = Table(table.Bytes, table.Pos)";
    code += GenIndents(2) + "union = tab.String(table.Pos)";
    code += GenIndents(2) + "return union";
  }

  // Creates an union object based on union type.
  void GenUnionCreator(const EnumDef& enum_def, std::string* code_ptr) const {
    if (enum_def.generated) return;

    auto& code = *code_ptr;
    const auto enum_fn = namer_.Function(enum_def);

    code += "\n";
    code += "def " + enum_fn + "Creator(unionType, table):";
    code += GenIndents(1) + "from flatbuffers.table import Table";
    code += GenIndents(1) + "if not isinstance(table, Table):";
    code += GenIndents(2) + "return None";

    for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
      auto& ev = **it;
      // Union only supports string and table.
      switch (ev.union_type.base_type) {
        case BASE_TYPE_STRUCT:
          GenUnionCreatorForStruct(enum_def, ev, &code);
          break;
        case BASE_TYPE_STRING:
          GenUnionCreatorForString(enum_def, ev, &code);
          break;
        default:
          break;
      }
    }
    code += GenIndents(1) + "return None";
    code += "\n";
  }

  // Generate enum declarations.
  void GenEnum(const EnumDef& enum_def, std::string* code_ptr) const {
    if (enum_def.generated) return;

    GenComment(enum_def.doc_comment, code_ptr, &def_comment);
    BeginEnum(enum_def, code_ptr);
    for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
      auto& ev = **it;
      GenComment(ev.doc_comment, code_ptr, &def_comment, Indent.c_str());
      EnumMember(enum_def, ev, code_ptr);
    }
  }

  // Returns the function name that is able to read a value of the given type.
  std::string GenGetter(const Type& type) const {
    switch (type.base_type) {
      case BASE_TYPE_STRING:
        return "self._tab.String(";
      case BASE_TYPE_UNION:
        return "self._tab.Union(";
      case BASE_TYPE_VECTOR:
        return GenGetter(type.VectorType());
      default:
        return "self._tab.Get(flatbuffers.number_types." +
               namer_.Method(GenTypeGet(type)) + "Flags, ";
    }
  }

  std::string GenFieldTy(const FieldDef& field) const {
    if (IsScalar(field.value.type.base_type) || IsArray(field.value.type)) {
      const std::string ty = GenTypeBasic(field.value.type);
      if (ty.find("int") != std::string::npos) {
        return "int";
      }

      if (ty.find("float") != std::string::npos) {
        return "float";
      }

      if (ty == "bool") {
        return "bool";
      }

      return "Any";
    } else {
      if (IsStruct(field.value.type)) {
        return "Any";
      } else {
        return "int";
      }
    }
  }

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

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

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

  std::string GenTypeGet(const Type& type) const {
    return IsScalar(type.base_type) ? GenTypeBasic(type) : GenTypePointer(type);
  }

  std::string TypeName(const FieldDef& field) const {
    return GenTypeGet(field.value.type);
  }

  std::string ReturnType(const StructDef& struct_def,
                         const FieldDef& field) const {
    // If we have a class member that returns an instance of the same class,
    // for example:
    // class Field(object):
    //   def Children(self, j: int) -> Optional[Field]:
    //     pass
    //
    // we need to quote the return type:
    // class Field(object):
    //   def Children(self, j: int) -> Optional['Field']:
    //     pass
    //
    // because Python is unable to resolve the name during parse and will return
    // an error.
    // (see PEP 484 under forward references:
    // https://peps.python.org/pep-0484/#forward-references)
    const std::string self_type = struct_def.name;
    std::string field_type = TypeName(field);

    if (self_type == field_type) {
      field_type = "'" + field_type + "'";
    }

    return field_type;
  }

  // Create a struct with a builder and the struct's arguments.
  void GenStructBuilder(const StructDef& struct_def,
                        std::string* code_ptr) const {
    BeginBuilderArgs(struct_def, code_ptr);
    StructBuilderArgs(struct_def,
                      /* nameprefix = */ "",
                      /* namesuffix = */ "",
                      /* has_field_name = */ true,
                      /* fieldname_suffix = */ "_", code_ptr);
    EndBuilderArgs(code_ptr);

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

  bool generate() {
    std::string one_file_code;
    ImportMap one_file_imports;
    if (!generateEnums(&one_file_code)) return false;
    if (!generateStructs(&one_file_code, one_file_imports)) return false;

    if (parser_.opts.one_file) {
      const std::string mod = file_name_ + parser_.opts.filename_suffix;

      // Legacy file format uses keep casing.
      return SaveType(mod + ".py", *parser_.current_namespace_, one_file_code,
                      one_file_imports, mod, true);
    }

    return true;
  }

 private:
  bool generateEnums(std::string* one_file_code) const {
    for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
         ++it) {
      auto& enum_def = **it;
      std::string enumcode;
      GenEnum(enum_def, &enumcode);
      if (parser_.opts.generate_object_based_api & enum_def.is_union) {
        GenUnionCreator(enum_def, &enumcode);
      }

      if (parser_.opts.one_file && !enumcode.empty()) {
        *one_file_code += enumcode + "\n\n";
      } else {
        ImportMap imports;
        const std::string mod =
            namer_.File(enum_def, SkipFile::SuffixAndExtension);

        if (!SaveType(namer_.File(enum_def, SkipFile::Suffix),
                      *enum_def.defined_namespace, enumcode, imports, mod,
                      false))
          return false;
      }
    }
    return true;
  }

  bool generateStructs(std::string* one_file_code,
                       ImportMap& one_file_imports) const {
    for (auto it = parser_.structs_.vec.begin();
         it != parser_.structs_.vec.end(); ++it) {
      auto& struct_def = **it;
      std::string declcode;
      ImportMap imports;
      GenStruct(struct_def, &declcode, imports);
      if (parser_.opts.generate_object_based_api) {
        GenStructForObjectAPI(struct_def, &declcode);
      }

      if (parser_.opts.one_file) {
        if (!declcode.empty()) {
          *one_file_code += declcode + "\n\n";
        }

        for (auto import_str : imports) {
          one_file_imports.insert(import_str);
        }
      } else {
        const std::string mod =
            namer_.File(struct_def, SkipFile::SuffixAndExtension);
        if (!SaveType(namer_.File(struct_def, SkipFile::Suffix),
                      *struct_def.defined_namespace, declcode, imports, mod,
                      true))
          return false;
      }
    }
    return true;
  }

  // Begin by declaring namespace and imports.
  void BeginFile(const std::string& name_space_name, const bool needs_imports,
                 std::string* code_ptr, const std::string& mod,
                 const ImportMap& imports) const {
    auto& code = *code_ptr;
    code = code + "# " + FlatBuffersGeneratedWarning() + "\n\n";
    code += "# namespace: " + name_space_name + "\n\n";

    if (needs_imports) {
      const std::string local_import = "." + mod;

      code += "import flatbuffers\n";
      if (parser_.opts.python_gen_numpy) {
        code += "from flatbuffers.compat import import_numpy\n";
      }
      if (parser_.opts.python_typing) {
        code += "from typing import Any\n";

        for (auto import_entry : imports) {
          // If we have a file called, say, "MyType.py" and in it we have a
          // class "MyType", we can generate imports -- usually when we
          // have a type that contains arrays of itself -- of the type
          // "from .MyType import MyType", which Python can't resolve. So
          // if we are trying to import ourself, we skip.
          if (import_entry.first != local_import) {
            code += "from " + import_entry.first + " import " +
                    import_entry.second + "\n";
          }
        }
      }
      if (parser_.opts.python_gen_numpy) {
        code += "np = import_numpy()\n\n";
      }
    }
  }

  // Save out the generated code for a Python Table type.
  bool SaveType(const std::string& defname, const Namespace& ns,
                const std::string& classcode, const ImportMap& imports,
                const std::string& mod, bool needs_imports) const {
    if (classcode.empty()) return true;

    std::string code = "";
    BeginFile(LastNamespacePart(ns), needs_imports, &code, mod, imports);
    code += classcode;

    const std::string directories =
        parser_.opts.one_file ? path_ : namer_.Directories(ns.components);
    EnsureDirExists(directories);

    for (size_t i = directories.find(kPathSeparator, path_.size());
         i != std::string::npos; i = directories.find(kPathSeparator, i + 1)) {
      const std::string init_py =
          directories.substr(0, i) + kPathSeparator + "__init__.py";
      parser_.opts.file_saver->SaveFile(init_py.c_str(), "", false);
    }

    const std::string filename = directories + defname;
    return parser_.opts.file_saver->SaveFile(filename.c_str(), code, false);
  }

 private:
  const SimpleFloatConstantGenerator float_const_gen_;
  const IdlNamer namer_;
};

}  // namespace python

static const char* GeneratePython(const Parser& parser, const std::string& path,
                                  const std::string& file_name) {
  python::Version version{parser.opts.python_version};
  if (!version.IsValid()) return "The provided Python version is not valid";

  python::PythonGenerator generator(parser, path, file_name, version);
  if (!generator.generate()) return "could not generate Python code";

  if (parser.opts.python_typing) {
    python::PythonStubGenerator stub_generator(parser, path, version);
    if (!stub_generator.Generate())
      return "could not generate Python type stubs";
  }
  return nullptr;
}

namespace {

class PythonCodeGenerator : public CodeGenerator {
 public:
  Status GenerateCode(const Parser& parser, const std::string& path,
                      const std::string& filename) override {
    auto err = GeneratePython(parser, path, filename);
    if (err) {
      status_detail = " " + std::string(err);
      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 (!GeneratePythonGRPC(parser, path,
                            filename)) {  // TODO add status GeneratePythonGRPC
      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::kPython; }

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

std::unique_ptr<CodeGenerator> NewPythonCodeGenerator() {
  return std::unique_ptr<PythonCodeGenerator>(new PythonCodeGenerator());
}

}  // namespace flatbuffers
