/*
 * 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 flatbuffers::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 GenerateObjectStub(std::stringstream &stub, const StructDef *struct_def,
                          Imports *imports) const {
    std::string name = namer_.ObjectType(*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";
    }

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

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

    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) << ": "
           << 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.name == "") {
        modules.insert(import.module);
      } else {
        names_by_module[import.module].insert(import.name);
      }
    }

    for (const std::string &module : modules) {
      ss << "import " << module << '\n';
    }
    for (const auto &import : names_by_module) {
      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_.Type(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);
          }
          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 code;
    std::set<std::string> import_typing_list;
    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()) {
            field_type = "Optional[" + field_type + "]";
          }
          break;
      }

      const auto default_value = GetDefaultValue(field);
      // Writes the init statement.
      const auto field_field = namer_.Field(field);
      code += GenIndents(2) + "self." + field_field + " = " + default_value +
              "  # type: " + field_type;
    }

    // Writes __init__ method.
    auto &code_base = *code_ptr;
    GenReceiverForObjectAPI(struct_def, code_ptr);
    code_base += "__init__(self):";
    if (code.empty()) {
      code_base += GenIndents(2) + "pass";
    } else {
      code_base += code;
    }
    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;

      // Wrties the comparison statement for this field.
      const auto field_field = namer_.Field(field);
      code += " and \\" + GenIndents(3) + "self." + field_field +
              " == " + "other." + field_field;
    }
    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;

      auto field_type = TypeName(field);
      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 = path_.size() + 1; i != std::string::npos;
         i = directories.find(kPathSeparator, i + 1)) {
      const std::string init_py =
          directories.substr(0, i) + kPathSeparator + "__init__.py";
      SaveFile(init_py.c_str(), "", false);
    }

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

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

}  // namespace python

static bool GeneratePython(const Parser &parser, const std::string &path,
                           const std::string &file_name) {
  python::Version version{parser.opts.python_version};
  if (!version.IsValid()) return false;

  python::PythonGenerator generator(parser, path, file_name, version);
  if (!generator.generate()) return false;

  if (parser.opts.python_typing) {
    python::PythonStubGenerator stub_generator(parser, path, version);
    if (!stub_generator.Generate()) return false;
  }
  return true;
}

namespace {

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

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

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

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

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

  bool IsSchemaOnly() const override { return true; }

  bool SupportsBfbsGeneration() const override { return false; }
  bool SupportsRootFileGeneration() const override { return false; }

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

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

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

}  // namespace flatbuffers
