/*
 * 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";
          }
        }
      }
    }

    /***************************** 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.

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

    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";
    }
  }

  // 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) 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);
        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);
    }
  }

  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_type = namer_.Type(enum_def);

    if (parser_.opts.include_dependence_headers) {
      union_type = namer_.NamespacedType(enum_def) + "." + union_type;
    }
    code += GenIndents(2) + "self." + field_field + " = " + union_type +
            "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
