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

#include "idl_gen_ts.h"

#include <algorithm>
#include <cassert>
#include <cmath>
#include <iostream>
#include <unordered_map>
#include <unordered_set>

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

namespace flatbuffers {
namespace {
struct ImportDefinition {
  std::string name;
  std::string import_statement;
  std::string export_statement;
  std::string bare_file_path;
  std::string rel_file_path;
  std::string object_name;
  const Definition* dependent = nullptr;
  const Definition* dependency = nullptr;
};

struct NsDefinition {
  std::string path;
  std::string filepath;
  std::string symbolic_name;
  const Namespace* ns = nullptr;
  std::map<std::string, const Definition*> definitions;
};

Namer::Config TypeScriptDefaultConfig() {
  return {/*types=*/Case::kKeep,
          /*constants=*/Case::kUnknown,
          /*methods=*/Case::kLowerCamel,
          /*functions=*/Case::kLowerCamel,
          /*fields=*/Case::kLowerCamel,
          /*variables=*/Case::kLowerCamel,
          /*variants=*/Case::kKeep,
          /*enum_variant_seperator=*/"::",
          /*escape_keywords=*/Namer::Config::Escape::AfterConvertingCase,
          /*namespaces=*/Case::kKeep,
          /*namespace_seperator=*/"_",
          /*object_prefix=*/"",
          /*object_suffix=*/"T",
          /*keyword_prefix=*/"",
          /*keyword_suffix=*/"_",
          /*keywords_casing=*/Namer::Config::KeywordsCasing::CaseSensitive,
          /*filenames=*/Case::kDasher,
          /*directories=*/Case::kDasher,
          /*output_path=*/"",
          /*filename_suffix=*/"_generated",
          /*filename_extension=*/".ts"};
}

std::set<std::string> TypescriptKeywords() {
  // List of keywords retrieved from here:
  // https://github.com/microsoft/TypeScript/issues/2536
  return {
      "arguments", "break",    "case",      "catch",      "class",      "const",
      "continue",  "debugger", "default",   "delete",     "do",         "else",
      "enum",      "export",   "extends",   "false",      "finally",    "for",
      "function",  "if",       "import",    "in",         "instanceof", "new",
      "null",      "Object",   "return",    "super",      "switch",     "this",
      "throw",     "true",     "try",       "typeof",     "var",        "void",
      "while",     "with",     "as",        "implements", "interface",  "let",
      "package",   "private",  "protected", "public",     "static",     "yield",
      "undefined"  // Used with --ts-undefined-for-optionals
  };
}

enum AnnotationType { kParam = 0, kType = 1, kReturns = 2 };

template <typename T>
struct SupportsObjectAPI : std::false_type {};

template <>
struct SupportsObjectAPI<StructDef> : std::true_type {};

}  // namespace

namespace ts {
// Iterate through all definitions we haven't generate code for (enums, structs,
// and tables) and output them to a single file.
class TsGenerator : public BaseGenerator {
 public:
  typedef std::map<std::string, ImportDefinition> import_set;

  TsGenerator(const Parser& parser, const std::string& path,
              const std::string& file_name)
      : BaseGenerator(parser, path, file_name, "", "_", "ts"),
        namer_(WithFlagOptions(TypeScriptDefaultConfig(), parser.opts, path),
               TypescriptKeywords()),
        null_keyword_(parser_.opts.ts_undefined_for_optionals ? "undefined"
                                                              : "null") {}

  bool generate() {
    generateEnums();
    generateStructs();
    if (!parser_.opts.ts_omit_entrypoint) {
      generateEntry();
    }
    return true;
  }

  std::string GetTypeName(const EnumDef& def, const bool = false,
                          const bool force_ns_wrap = false) {
    if (force_ns_wrap) {
      return namer_.NamespacedType(def);
    }
    return namer_.Type(def);
  }

  std::string GetTypeName(const StructDef& def, const bool object_api = false,
                          const bool force_ns_wrap = false) {
    if (object_api && parser_.opts.generate_object_based_api) {
      if (force_ns_wrap) {
        return namer_.NamespacedObjectType(def);
      } else {
        return namer_.ObjectType(def);
      }
    } else {
      if (force_ns_wrap) {
        return namer_.NamespacedType(def);
      } else {
        return namer_.Type(def);
      }
    }
  }

  // Save out the generated code for a single class while adding
  // declaration boilerplate.
  bool SaveType(const Definition& definition, const std::string& class_code,
                import_set& imports, import_set& bare_imports) {
    if (!class_code.length()) return true;

    std::string code;

    code += "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n" +
            "/* eslint-disable @typescript-eslint/no-unused-vars, "
            "@typescript-eslint/no-explicit-any, "
            "@typescript-eslint/no-non-null-assertion */\n\n";

    for (auto it = bare_imports.begin(); it != bare_imports.end(); it++) {
      code += it->second.import_statement + "\n";
    }
    if (!bare_imports.empty()) code += "\n";

    for (auto it = imports.begin(); it != imports.end(); it++) {
      if (it->second.dependency != &definition) {
        code += it->second.import_statement + "\n";
      }
    }
    if (!imports.empty()) code += "\n\n";

    code += class_code;

    auto dirs = namer_.Directories(*definition.defined_namespace);
    EnsureDirExists(dirs);
    auto basename = dirs + namer_.File(definition, SkipFile::Suffix);

    return parser_.opts.file_saver->SaveFile(basename.c_str(), code, false);
  }

  void TrackNsDef(const Definition& definition, std::string type_name) {
    std::string path;
    std::string filepath;
    std::string symbolic_name;
    if (definition.defined_namespace->components.size() > 0) {
      path = namer_.Directories(*definition.defined_namespace,
                                SkipDir::TrailingPathSeperator);
      filepath = path + ".ts";
      path = namer_.Directories(*definition.defined_namespace,
                                SkipDir::OutputPathAndTrailingPathSeparator);
      symbolic_name = definition.defined_namespace->components.back();
    } else {
      auto def_mod_name = namer_.File(definition, SkipFile::SuffixAndExtension);
      symbolic_name = file_name_;
      filepath = path_ + symbolic_name + ".ts";
    }
    if (ns_defs_.count(path) == 0) {
      NsDefinition nsDef;
      nsDef.path = path;
      nsDef.filepath = filepath;
      nsDef.ns = definition.defined_namespace;
      nsDef.definitions.insert(std::make_pair(type_name, &definition));
      nsDef.symbolic_name = symbolic_name;
      ns_defs_[path] = nsDef;
    } else {
      ns_defs_[path].definitions.insert(std::make_pair(type_name, &definition));
    }
  }

 private:
  IdlNamer namer_;

  std::map<std::string, NsDefinition> ns_defs_;

  std::string null_keyword_;

  // Generate code for all enums.
  void generateEnums() {
    for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
         ++it) {
      import_set bare_imports;
      import_set imports;
      std::string enumcode;
      auto& enum_def = **it;
      GenEnum(enum_def, &enumcode, imports, false);
      GenEnum(enum_def, &enumcode, imports, true);
      std::string type_name = GetTypeName(enum_def);
      TrackNsDef(enum_def, type_name);
      SaveType(enum_def, enumcode, imports, bare_imports);
    }
  }

  // Generate code for all structs.
  void generateStructs() {
    for (auto it = parser_.structs_.vec.begin();
         it != parser_.structs_.vec.end(); ++it) {
      import_set bare_imports;
      import_set imports;
      AddImport(bare_imports, "* as flatbuffers", "flatbuffers");
      auto& struct_def = **it;
      std::string declcode;
      GenStruct(parser_, struct_def, &declcode, imports);
      std::string type_name = GetTypeName(struct_def);
      TrackNsDef(struct_def, type_name);
      SaveType(struct_def, declcode, imports, bare_imports);
    }
  }

  // Generate code for a single entry point module.
  void generateEntry() {
    std::string code;

    // add root namespace def if not already existing from defs tracking
    std::string root;
    if (ns_defs_.count(root) == 0) {
      NsDefinition nsDef;
      nsDef.path = root;
      nsDef.symbolic_name = file_name_;
      nsDef.filepath = path_ + file_name_ + ".ts";
      nsDef.ns = parser_.empty_namespace_;
      ns_defs_[nsDef.path] = nsDef;
    }

    for (const auto& it : ns_defs_) {
      code = "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n" +
             "/* eslint-disable @typescript-eslint/no-unused-vars, "
             "@typescript-eslint/no-explicit-any, "
             "@typescript-eslint/no-non-null-assertion */\n\n";

      // export all definitions in ns entry point module
      int export_counter = 0;
      for (const auto& def : it.second.definitions) {
        std::vector<std::string> rel_components;
        // build path for root level vs child level
        if (it.second.ns->components.size() > 0) {
          rel_components.push_back(it.second.ns->components.back());
        }
        auto base_file_name =
            namer_.File(*(def.second), SkipFile::SuffixAndExtension);
        auto base_name =
            namer_.Directories(it.second.ns->components, SkipDir::OutputPath) +
            base_file_name;
        auto ts_file_path = base_name + ".ts";
        auto base_name_rel = std::string("./");
        base_name_rel +=
            namer_.Directories(rel_components, SkipDir::OutputPath);
        base_name_rel += base_file_name;
        auto ts_file_path_rel = base_name_rel + ".ts";
        auto type_name = def.first;
        auto fully_qualified_type_name =
            it.second.ns->GetFullyQualifiedName(type_name);
        auto is_struct = parser_.structs_.Lookup(fully_qualified_type_name);
        code += "export { " + type_name;
        if (parser_.opts.generate_object_based_api && is_struct) {
          code += ", " + type_name + parser_.opts.object_suffix;
        }
        code += " } from '";
        std::string import_extension =
            parser_.opts.ts_no_import_ext ? "" : ".js";
        code += base_name_rel + import_extension + "';\n";
        export_counter++;
      }

      // re-export child namespace(s) in parent
      const auto child_ns_level = it.second.ns->components.size() + 1;
      for (const auto& it2 : ns_defs_) {
        if (it2.second.ns->components.size() != child_ns_level) continue;
        auto ts_file_path = it2.second.path + ".ts";
        code += "export * as " + it2.second.symbolic_name + " from './";
        int count = it2.second.ns->components.size() > 1 ? 2 : 1;
        std::vector<std::string> rel_path;
        std::copy(it2.second.ns->components.end() - count,
                  it2.second.ns->components.end(),
                  std::back_inserter(rel_path));
        code += namer_.Directories(
                    rel_path, SkipDir::OutputPathAndTrailingPathSeparator) +
                ".js';\n";
        export_counter++;
      }

      if (export_counter > 0) {
        parser_.opts.file_saver->SaveFile(it.second.filepath.c_str(), code,
                                          false);
      }
    }
  }

  // Generate a documentation comment, if available.
  static void GenDocComment(const std::vector<std::string>& dc,
                            std::string* code_ptr,
                            const char* indent = nullptr) {
    if (dc.empty()) {
      // Don't output empty comment blocks with 0 lines of comment content.
      return;
    }

    std::string& code = *code_ptr;
    if (indent) code += indent;
    code += "/**\n";
    for (auto it = dc.begin(); it != dc.end(); ++it) {
      if (indent) code += indent;
      std::string safe = *it;
      for (size_t pos = 0; (pos = safe.find("*/", pos)) != std::string::npos;) {
        safe.replace(pos, 2, "*\\/");
        pos += 3;
      }
      code += " *" + safe + "\n";
    }
    if (indent) code += indent;
    code += " */\n";
  }

  static void GenDocComment(std::string* code_ptr) {
    GenDocComment(std::vector<std::string>(), code_ptr);
  }

  // Generate an enum declaration and an enum string lookup table.
  void GenEnum(EnumDef& enum_def, std::string* code_ptr, import_set& imports,
               bool reverse) {
    if (enum_def.generated) return;
    if (reverse) return;  // FIXME.
    std::string& code = *code_ptr;
    GenDocComment(enum_def.doc_comment, code_ptr);
    code += "export enum ";
    code += GetTypeName(enum_def);
    code += " {\n";
    for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
      auto& ev = **it;
      if (!ev.doc_comment.empty()) {
        if (it != enum_def.Vals().begin()) {
          code += '\n';
        }
        GenDocComment(ev.doc_comment, code_ptr, "  ");
      }

      // Generate mapping between EnumName: EnumValue(int)
      if (reverse) {
        code += "  '" + enum_def.ToString(ev) + "'";
        code += " = ";
        code += "'" + namer_.Variant(ev) + "'";
      } else {
        code += "  " + namer_.Variant(ev);
        code += " = ";
        // Unfortunately, because typescript does not support bigint enums,
        // for 64-bit enums, we instead map the enum names to strings.
        switch (enum_def.underlying_type.base_type) {
          case BASE_TYPE_LONG:
          case BASE_TYPE_ULONG: {
            code += "'" + enum_def.ToString(ev) + "'";
            break;
          }
          default:
            code += enum_def.ToString(ev);
        }
      }

      code += (it + 1) != enum_def.Vals().end() ? ",\n" : "\n";
    }
    code += "}";

    if (enum_def.is_union) {
      code += GenUnionConvFunc(enum_def.underlying_type, imports);
    }

    code += "\n";
  }

  static std::string GenType(const Type& type) {
    switch (type.base_type) {
      case BASE_TYPE_BOOL:
      case BASE_TYPE_CHAR:
        return "Int8";
      case BASE_TYPE_UTYPE:
        return GenType(GetUnionUnderlyingType(type));
      case BASE_TYPE_UCHAR:
        return "Uint8";
      case BASE_TYPE_SHORT:
        return "Int16";
      case BASE_TYPE_USHORT:
        return "Uint16";
      case BASE_TYPE_INT:
        return "Int32";
      case BASE_TYPE_UINT:
        return "Uint32";
      case BASE_TYPE_LONG:
        return "Int64";
      case BASE_TYPE_ULONG:
        return "Uint64";
      case BASE_TYPE_FLOAT:
        return "Float32";
      case BASE_TYPE_DOUBLE:
        return "Float64";
      case BASE_TYPE_STRING:
        return "String";
      case BASE_TYPE_VECTOR:
        return GenType(type.VectorType());
      case BASE_TYPE_STRUCT:
        return type.struct_def->name;
      default:
        return "flatbuffers.Table";
    }
  }

  std::string GenGetter(const Type& type, const std::string& arguments) {
    switch (type.base_type) {
      case BASE_TYPE_STRING:
        return GenBBAccess() + ".__string" + arguments;
      case BASE_TYPE_STRUCT:
        return GenBBAccess() + ".__struct" + arguments;
      case BASE_TYPE_UNION:
        if (!UnionHasStringType(*type.enum_def)) {
          return GenBBAccess() + ".__union" + arguments;
        }
        return GenBBAccess() + ".__union_with_string" + arguments;
      case BASE_TYPE_VECTOR:
        return GenGetter(type.VectorType(), arguments);
      default: {
        auto getter = GenBBAccess() + "." + "read" + GenType(type) + arguments;
        if (type.base_type == BASE_TYPE_BOOL) {
          getter = "!!" + getter;
        }
        return getter;
      }
    }
  }

  std::string GenBBAccess() const { return "this.bb!"; }

  std::string GenDefaultValue(const FieldDef& field, import_set& imports) {
    if (field.IsScalarOptional()) {
      return null_keyword_;
    }

    const auto& value = field.value;
    if (value.type.enum_def && value.type.base_type != BASE_TYPE_UNION &&
        value.type.base_type != BASE_TYPE_VECTOR) {
      switch (value.type.base_type) {
        case BASE_TYPE_ARRAY: {
          std::string ret = "[";
          for (auto i = 0; i < value.type.fixed_length; ++i) {
            std::string enum_name =
                AddImport(imports, *value.type.enum_def, *value.type.enum_def)
                    .name;
            const EnumVal* val =
                value.type.enum_def->FindByValue(value.constant);
            if (val == nullptr) {
              val = value.type.enum_def->MinValue();
            }
            std::string enum_value = namer_.Variant(*val);
            ret += enum_name + "." + enum_value +
                   (i < value.type.fixed_length - 1 ? ", " : "");
          }
          ret += "]";
          return ret;
        }
        case BASE_TYPE_LONG:
        case BASE_TYPE_ULONG: {
          // If the value is an enum with a 64-bit base type, we have to just
          // return the bigint value directly since typescript does not support
          // enums with bigint backing types.
          return "BigInt('" + value.constant + "')";
        }
        default: {
          const EnumVal* val = value.type.enum_def->FindByValue(value.constant);
          if (val == nullptr) {
            val = value.type.enum_def->MinValue();
          }
          return AddImport(imports, *value.type.enum_def, *value.type.enum_def)
                     .name +
                 "." + namer_.Variant(*val);
        }
      }
    }

    switch (value.type.base_type) {
      case BASE_TYPE_BOOL:
        return value.constant == "0" ? "false" : "true";

      case BASE_TYPE_STRING:
      case BASE_TYPE_UNION:
      case BASE_TYPE_STRUCT: {
        return null_keyword_;
      }

      case BASE_TYPE_ARRAY:
      case BASE_TYPE_VECTOR:
        return "[]";

      case BASE_TYPE_LONG:
      case BASE_TYPE_ULONG: {
        return "BigInt('" + value.constant + "')";
      }

      default: {
        if (StringIsFlatbufferNan(value.constant)) {
          return "NaN";
        } else if (StringIsFlatbufferPositiveInfinity(value.constant)) {
          return "Infinity";
        } else if (StringIsFlatbufferNegativeInfinity(value.constant)) {
          return "-Infinity";
        }
        return value.constant;
      }
    }
  }

  std::string GenTypeName(import_set& imports, const Definition& owner,
                          const Type& type, bool input,
                          bool allowNull = false) {
    if (!input) {
      if (IsString(type) || type.base_type == BASE_TYPE_STRUCT) {
        std::string name;
        if (IsString(type)) {
          name = "string|Uint8Array";
        } else {
          name = AddImport(imports, owner, *type.struct_def).name;
        }
        return allowNull ? (name + "|" + null_keyword_) : name;
      }
    }

    switch (type.base_type) {
      case BASE_TYPE_BOOL:
        return allowNull ? ("boolean|" + null_keyword_) : "boolean";
      case BASE_TYPE_LONG:
      case BASE_TYPE_ULONG:
        return allowNull ? ("bigint|" + null_keyword_) : "bigint";
      case BASE_TYPE_ARRAY: {
        std::string name;
        if (type.element == BASE_TYPE_LONG || type.element == BASE_TYPE_ULONG) {
          name = "bigint[]";
        } else if (type.element != BASE_TYPE_STRUCT) {
          name = "number[]";
        } else {
          name = "any[]";
          if (parser_.opts.generate_object_based_api) {
            name = "(any|" +
                   GetTypeName(*type.struct_def, /*object_api =*/true) + ")[]";
          }
        }

        return name + (allowNull ? ("|" + null_keyword_) : "");
      }
      default:
        if (IsScalar(type.base_type)) {
          if (type.enum_def) {
            const auto enum_name =
                AddImport(imports, owner, *type.enum_def).name;
            return allowNull ? (enum_name + "|" + null_keyword_) : enum_name;
          }
          return allowNull ? ("number|" + null_keyword_) : "number";
        }
        return "flatbuffers.Offset";
    }
  }

  static Type GetUnionUnderlyingType(const Type& type) {
    if (type.enum_def != nullptr &&
        type.enum_def->underlying_type.base_type != type.base_type) {
      return type.enum_def->underlying_type;
    } else {
      return Type(BASE_TYPE_UCHAR);
    }
  }

  static Type GetUnderlyingVectorType(const Type& vector_type) {
    return (vector_type.base_type == BASE_TYPE_UTYPE)
               ? GetUnionUnderlyingType(vector_type)
               : vector_type;
  }

  // Returns the method name for use with add/put calls.
  std::string GenWriteMethod(const Type& type) {
    // Forward to signed versions since unsigned versions don't exist
    switch (type.base_type) {
      case BASE_TYPE_UTYPE:
        return GenWriteMethod(GetUnionUnderlyingType(type));
      case BASE_TYPE_UCHAR:
        return GenWriteMethod(Type(BASE_TYPE_CHAR));
      case BASE_TYPE_USHORT:
        return GenWriteMethod(Type(BASE_TYPE_SHORT));
      case BASE_TYPE_UINT:
        return GenWriteMethod(Type(BASE_TYPE_INT));
      case BASE_TYPE_ULONG:
        return GenWriteMethod(Type(BASE_TYPE_LONG));
      default:
        break;
    }

    return IsScalar(type.base_type) ? namer_.Type(GenType(type))
                                    : (IsStruct(type) ? "Struct" : "Offset");
  }

  template <typename T>
  static std::string MaybeAdd(T value) {
    return value != 0 ? " + " + NumToString(value) : "";
  }

  template <typename T>
  static std::string MaybeScale(T value) {
    return value != 1 ? " * " + NumToString(value) : "";
  }

  void GenStructArgs(import_set& imports, const StructDef& struct_def,
                     const Definition& owner, std::string* arguments,
                     const std::string& nameprefix) {
    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      auto& field = **it;
      if (IsStruct(field.value.type)) {
        // Generate arguments for a struct inside a struct. To ensure names
        // don't clash, and to make it obvious these arguments are constructing
        // a nested struct, prefix the name with the field name.
        GenStructArgs(imports, *field.value.type.struct_def, owner, arguments,
                      nameprefix + field.name + "_");
      } else {
        *arguments += ", " + nameprefix + field.name + ": " +
                      GenTypeName(imports, owner, field.value.type, true,
                                  field.IsOptional());
      }
    }
  }

  void GenStructBody(const StructDef& struct_def, std::string* body,
                     const std::string& nameprefix) {
    *body += "  builder.prep(";
    *body += NumToString(struct_def.minalign) + ", ";
    *body += NumToString(struct_def.bytesize) + ");\n";

    for (auto it = struct_def.fields.vec.rbegin();
         it != struct_def.fields.vec.rend(); ++it) {
      auto& field = **it;
      if (field.padding) {
        *body += "  builder.pad(" + NumToString(field.padding) + ");\n";
      }
      if (IsStruct(field.value.type)) {
        // Generate arguments for a struct inside a struct. To ensure names
        // don't clash, and to make it obvious these arguments are constructing
        // a nested struct, prefix the name with the field name.
        GenStructBody(
            *field.value.type.struct_def, body,
            nameprefix.length() ? nameprefix + "_" + field.name : field.name);
      } else {
        auto element_type = field.value.type.element;

        if (field.value.type.base_type == BASE_TYPE_ARRAY) {
          switch (field.value.type.element) {
            case BASE_TYPE_STRUCT: {
              std::string str_last_item_idx =
                  NumToString(field.value.type.fixed_length - 1);
              *body += "\n  for (let i = " + str_last_item_idx +
                       "; i >= 0; --i" + ") {\n";

              std::string fname = nameprefix.length()
                                      ? nameprefix + "_" + field.name
                                      : field.name;

              *body += "    const item = " + fname + "?.[i];\n\n";

              if (parser_.opts.generate_object_based_api) {
                *body += "    if (item instanceof " +
                         GetTypeName(*field.value.type.struct_def,
                                     /*object_api =*/true) +
                         ") {\n";
                *body += "      item.pack(builder);\n";
                *body += "      continue;\n";
                *body += "    }\n\n";
              }

              std::string class_name =
                  GetPrefixedName(*field.value.type.struct_def);
              std::string pack_func_create_call =
                  class_name + ".create" + class_name + "(builder,\n";
              pack_func_create_call +=
                  "    " +
                  GenStructMemberValueTS(*field.value.type.struct_def, "item",
                                         ",\n    ", false) +
                  "\n  ";
              *body += "    " + pack_func_create_call;
              *body += "  );\n  }\n\n";

              break;
            }
            default: {
              std::string str_last_item_idx =
                  NumToString(field.value.type.fixed_length - 1);
              std::string fname = nameprefix.length()
                                      ? nameprefix + "_" + field.name
                                      : field.name;

              *body += "\n  for (let i = " + str_last_item_idx +
                       "; i >= 0; --i) {\n";
              *body += "    builder.write";
              *body += GenWriteMethod(
                  static_cast<flatbuffers::Type>(field.value.type.element));
              *body += "(";
              *body += element_type == BASE_TYPE_BOOL ? "+" : "";

              if (element_type == BASE_TYPE_LONG ||
                  element_type == BASE_TYPE_ULONG) {
                *body += "BigInt(" + fname + "?.[i] ?? 0));\n";
              } else {
                *body += "(" + fname + "?.[i] ?? 0));\n\n";
              }
              *body += "  }\n\n";
              break;
            }
          }
        } else {
          std::string fname =
              nameprefix.length() ? nameprefix + "_" + field.name : field.name;

          *body += "  builder.write" + GenWriteMethod(field.value.type) + "(";
          if (field.value.type.base_type == BASE_TYPE_BOOL) {
            *body += "Number(Boolean(" + fname + ")));\n";
            continue;
          } else if (field.value.type.base_type == BASE_TYPE_LONG ||
                     field.value.type.base_type == BASE_TYPE_ULONG) {
            *body += "BigInt(" + fname + " ?? 0));\n";
            continue;
          }

          *body += fname + ");\n";
        }
      }
    }
  }

  std::string GenerateNewExpression(const std::string& object_name) {
    return "new " + namer_.Type(object_name) + "()";
  }

  void GenerateRootAccessor(StructDef& struct_def, std::string* code_ptr,
                            std::string& code, const std::string& object_name,
                            bool size_prefixed) {
    if (!struct_def.fixed) {
      GenDocComment(code_ptr);
      std::string sizePrefixed("SizePrefixed");
      code += "static get" + (size_prefixed ? sizePrefixed : "") + "Root" +
              GetPrefixedName(struct_def, "As");
      code += "(bb:flatbuffers.ByteBuffer, obj?:" + object_name +
              "):" + object_name + " {\n";
      if (size_prefixed) {
        code +=
            "  bb.setPosition(bb.position() + "
            "flatbuffers.SIZE_PREFIX_LENGTH);\n";
      }
      code += "  return (obj || " + GenerateNewExpression(object_name);
      code += ").__init(bb.readInt32(bb.position()) + bb.position(), bb);\n";
      code += "}\n\n";
    }
  }

  void GenerateFinisher(StructDef& struct_def, std::string* code_ptr,
                        std::string& code, bool size_prefixed) {
    if (parser_.root_struct_def_ == &struct_def) {
      std::string sizePrefixed("SizePrefixed");
      GenDocComment(code_ptr);

      code += "static finish" + (size_prefixed ? sizePrefixed : "") +
              GetPrefixedName(struct_def) + "Buffer";
      code += "(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {\n";
      code += "  builder.finish(offset";
      if (!parser_.file_identifier_.empty()) {
        code += ", '" + parser_.file_identifier_ + "'";
      }
      if (size_prefixed) {
        if (parser_.file_identifier_.empty()) {
          code += ", undefined";
        }
        code += ", true";
      }
      code += ");\n";
      code += "}\n\n";
    }
  }

  bool UnionHasStringType(const EnumDef& union_enum) {
    return std::any_of(union_enum.Vals().begin(), union_enum.Vals().end(),
                       [](const EnumVal* ev) {
                         return !ev->IsZero() && IsString(ev->union_type);
                       });
  }

  std::string GenUnionGenericTypeTS(const EnumDef& union_enum) {
    // TODO: make it work without any
    // return std::string("T") + (UnionHasStringType(union_enum) ? "|string" :
    // "");
    return std::string("any") +
           (UnionHasStringType(union_enum) ? "|string" : "");
  }

  std::string GenUnionTypeTS(const EnumDef& union_enum, import_set& imports) {
    std::string ret;
    std::set<std::string> type_list;

    for (auto it = union_enum.Vals().begin(); it != union_enum.Vals().end();
         ++it) {
      const auto& ev = **it;
      if (ev.IsZero()) {
        continue;
      }

      std::string type = "";
      if (IsString(ev.union_type)) {
        type = "string";  // no need to wrap string type in namespace
      } else if (ev.union_type.base_type == BASE_TYPE_STRUCT) {
        type = AddImport(imports, union_enum, *ev.union_type.struct_def).name;
      } else {
        FLATBUFFERS_ASSERT(false);
      }
      type_list.insert(type);
    }

    for (auto it = type_list.begin(); it != type_list.end(); ++it) {
      ret += *it + ((std::next(it) == type_list.end()) ? "" : "|");
    }

    return ret;
  }

  static bool CheckIfNameClashes(const import_set& imports,
                                 const std::string& name) {
    // TODO: this would be better as a hashset.
    for (auto it = imports.begin(); it != imports.end(); it++) {
      if (it->second.name == name) {
        return true;
      }
    }
    return false;
  }

  std::string GenSymbolExpression(const StructDef& struct_def,
                                  const bool has_name_clash,
                                  const std::string& import_name,
                                  const std::string& name,
                                  const std::string& object_name) {
    std::string symbols_expression;

    if (has_name_clash) {
      // We have a name clash
      symbols_expression += import_name + " as " + name;

      if (parser_.opts.generate_object_based_api) {
        symbols_expression += ", " +
                              GetTypeName(struct_def, /*object_api =*/true) +
                              " as " + object_name;
      }
    } else {
      // No name clash, use the provided name
      symbols_expression += name;

      if (parser_.opts.generate_object_based_api) {
        symbols_expression += ", " + object_name;
      }
    }

    return symbols_expression;
  }

  std::string GenSymbolExpression(const EnumDef& enum_def,
                                  const bool has_name_clash,
                                  const std::string& import_name,
                                  const std::string& name, const std::string&) {
    std::string symbols_expression;
    if (has_name_clash) {
      symbols_expression += import_name + " as " + name;
    } else {
      symbols_expression += name;
    }

    if (enum_def.is_union) {
      symbols_expression += (", " + namer_.Function("unionTo" + name));
      symbols_expression += (", " + namer_.Function("unionListTo" + name));
    }

    return symbols_expression;
  }

  std::vector<std::string> PathComponents(const std::string& path) const {
    std::vector<std::string> components;
    size_t start = 0;
    while (start < path.size()) {
      auto end = path.find(kPathSeparator, start);
      if (end == std::string::npos) end = path.size();
      if (end > start) {
        components.emplace_back(path.substr(start, end - start));
      }
      if (end == path.size()) break;
      start = end + 1;
    }
    return components;
  }

  std::string RelativeDirectory(const std::vector<std::string>& from,
                                const std::vector<std::string>& to) const {
    size_t common = 0;
    while (common < from.size() && common < to.size() &&
           from[common] == to[common]) {
      ++common;
    }

    std::string rel;
    const size_t ups = from.size() - common;
    if (ups == 0) {
      rel = ".";
    } else {
      for (size_t i = 0; i < ups; ++i) {
        if (!rel.empty()) rel += kPathSeparator;
        rel += "..";
      }
    }

    for (size_t i = common; i < to.size(); ++i) {
      if (!rel.empty()) rel += kPathSeparator;
      rel += to[i];
    }

    return rel;
  }

  template <typename DefinitionT>
  ImportDefinition AddImport(import_set& imports, const Definition& dependent,
                             const DefinitionT& dependency) {
    // The unique name of the dependency, fully qualified in its namespace.
    const std::string unique_name = GetTypeName(
        dependency, /*object_api = */ false, /*force_ns_wrap=*/true);

    // Look if we have already added this import and return its name if found.
    const auto import_pair = imports.find(unique_name);
    if (import_pair != imports.end()) {
      return import_pair->second;
    }

    // Check if this name would have a name clash with another type. Just use
    // the "base" name (properly escaped) without any namespacing applied.
    const std::string import_name = GetTypeName(dependency);
    const bool has_name_clash = CheckIfNameClashes(imports, import_name);

    // If we have a name clash, use the unique name, otherwise use simple name.
    std::string name = has_name_clash ? unique_name : import_name;

    const std::string object_name =
        GetTypeName(dependency, /*object_api=*/true, has_name_clash);

    const std::string symbols_expression = GenSymbolExpression(
        dependency, has_name_clash, import_name, name, object_name);

    const Namespace* dependent_ns = dependent.defined_namespace
                                        ? dependent.defined_namespace
                                        : parser_.empty_namespace_;
    const Namespace* dependency_ns = dependency.defined_namespace
                                         ? dependency.defined_namespace
                                         : parser_.empty_namespace_;

    const std::string dependent_dirs =
        namer_.Directories(*dependent_ns, SkipDir::OutputPath);
    const std::string dependency_dirs =
        namer_.Directories(*dependency_ns, SkipDir::OutputPath);

    const auto dependent_components = PathComponents(dependent_dirs);
    const auto dependency_components = PathComponents(dependency_dirs);

    std::string rel_dir =
        RelativeDirectory(dependent_components, dependency_components);
    if (rel_dir.empty()) rel_dir = ".";
    if (!rel_dir.empty()) rel_dir += kPathSeparator;

    std::string rel_file_path =
        rel_dir + namer_.File(dependency, SkipFile::SuffixAndExtension);

    std::string bare_file_path =
        kPathSeparator + dependency_dirs +
        namer_.File(dependency, SkipFile::SuffixAndExtension);

    ImportDefinition import;
    import.name = name;
    import.object_name = object_name;
    import.bare_file_path = bare_file_path;
    import.rel_file_path = rel_file_path;
    std::string import_extension = parser_.opts.ts_no_import_ext ? "" : ".js";
    import.import_statement = "import { " + symbols_expression + " } from '" +
                              rel_file_path + import_extension + "';";
    import.export_statement = "export { " + symbols_expression + " } from '." +
                              bare_file_path + import_extension + "';";
    import.dependency = &dependency;
    import.dependent = &dependent;

    imports.insert(std::make_pair(unique_name, import));

    return import;
  }

  void AddImport(import_set& imports, std::string import_name,
                 std::string fileName) {
    ImportDefinition import;
    import.name = import_name;
    import.import_statement =
        "import " + import_name + " from '" + fileName + "';";
    imports.insert(std::make_pair(import_name, import));
  }

  // Generate a TS union type based on a union's enum
  std::string GenObjApiUnionTypeTS(import_set& imports,
                                   const StructDef& dependent,
                                   const IDLOptions&,
                                   const EnumDef& union_enum) {
    std::string ret = "";
    std::set<std::string> type_list;

    for (auto it = union_enum.Vals().begin(); it != union_enum.Vals().end();
         ++it) {
      const auto& ev = **it;
      if (ev.IsZero()) {
        continue;
      }

      std::string type = "";
      if (IsString(ev.union_type)) {
        type = "string";  // no need to wrap string type in namespace
      } else if (ev.union_type.base_type == BASE_TYPE_STRUCT) {
        type = AddImport(imports, dependent, *ev.union_type.struct_def)
                   .object_name;
      } else {
        FLATBUFFERS_ASSERT(false);
      }
      type_list.insert(type);
    }

    size_t totalPrinted = 0;
    for (auto it = type_list.begin(); it != type_list.end(); ++it) {
      ++totalPrinted;
      ret += *it + ((totalPrinted == type_list.size()) ? "" : "|");
    }

    return ret;
  }

  std::string GenUnionConvFuncName(const EnumDef& enum_def) {
    return namer_.Function("unionTo", enum_def);
  }

  std::string GenUnionListConvFuncName(const EnumDef& enum_def) {
    return namer_.Function("unionListTo", enum_def);
  }

  std::string GenUnionConvFunc(const Type& union_type, import_set& imports) {
    if (union_type.enum_def) {
      const auto& enum_def = *union_type.enum_def;

      const auto valid_union_type = GenUnionTypeTS(enum_def, imports);
      const auto valid_union_type_with_null =
          valid_union_type + "|" + null_keyword_;

      auto ret = "\n\nexport function " + GenUnionConvFuncName(enum_def) +
                 "(\n  type: " + GetTypeName(enum_def) +
                 ",\n  accessor: (obj:" + valid_union_type + ") => " +
                 valid_union_type_with_null +
                 "\n): " + valid_union_type_with_null + " {\n";

      const auto enum_type = AddImport(imports, enum_def, enum_def).name;

      const auto union_enum_loop = [&](const std::string& accessor_str) {
        ret += "  switch(" + enum_type + "[type]) {\n";
        ret += "    case 'NONE': return " + null_keyword_ + "; \n";

        for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
             ++it) {
          const auto& ev = **it;
          if (ev.IsZero()) {
            continue;
          }

          ret += "    case '" + namer_.Variant(ev) + "': ";

          if (IsString(ev.union_type)) {
            ret += "return " + accessor_str + "'') as string;";
          } else if (ev.union_type.base_type == BASE_TYPE_STRUCT) {
            const auto type =
                AddImport(imports, enum_def, *ev.union_type.struct_def).name;
            ret += "return " + accessor_str + "new " + type + "())! as " +
                   type + ";";
          } else {
            FLATBUFFERS_ASSERT(false);
          }
          ret += "\n";
        }

        ret += "    default: return " + null_keyword_ + ";\n";
        ret += "  }\n";
      };

      union_enum_loop("accessor(");
      ret += "}";

      ret += "\n\nexport function " + GenUnionListConvFuncName(enum_def) +
             "(\n  type: " + GetTypeName(enum_def) +
             ", \n  accessor: (index: number, obj:" + valid_union_type +
             ") => " + valid_union_type_with_null +
             ", \n  index: number\n): " + valid_union_type_with_null + " {\n";
      union_enum_loop("accessor(index, ");
      ret += "}";

      return ret;
    }
    FLATBUFFERS_ASSERT(0);
    return "";
  }

  // Used for generating a short function that returns the correct class
  // based on union enum type. Assume the context is inside the non object api
  // type
  std::string GenUnionValTS(import_set& imports, const StructDef& dependent,
                            const std::string& field_name,
                            const Type& union_type,
                            const bool is_array = false) {
    if (union_type.enum_def) {
      const auto& enum_def = *union_type.enum_def;
      const auto enum_type = AddImport(imports, dependent, enum_def).name;
      const std::string union_accessor = "this." + field_name;

      const auto union_has_string = UnionHasStringType(enum_def);
      const auto field_binded_method = "this." + field_name + ".bind(this)";

      std::string ret;

      if (!is_array) {
        const auto conversion_function = GenUnionConvFuncName(enum_def);

        ret = "(() => {\n";
        ret += "      const temp = " + conversion_function + "(this." +
               namer_.Method(field_name, "Type") + "(), " +
               field_binded_method + ");\n";
        ret += "      if(temp === " + null_keyword_ + ") { return " +
               null_keyword_ + "; }\n";
        ret += union_has_string
                   ? "      if(typeof temp === 'string') { return temp; }\n"
                   : "";
        ret += "      return temp.unpack()\n";
        ret += "  })()";
      } else {
        const auto conversion_function = GenUnionListConvFuncName(enum_def);

        ret = "(() => {\n";
        ret += "    const ret: (" +
               GenObjApiUnionTypeTS(imports, *union_type.struct_def,
                                    parser_.opts, *union_type.enum_def) +
               ")[] = [];\n";
        ret += "    for(let targetEnumIndex = 0; targetEnumIndex < this." +
               namer_.Method(field_name, "TypeLength") + "()" +
               "; "
               "++targetEnumIndex) {\n";
        ret += "      const targetEnum = this." +
               namer_.Method(field_name, "Type") + "(targetEnumIndex);\n";
        ret += "      if(targetEnum === " + null_keyword_ + " || " + enum_type +
               "[targetEnum!] === 'NONE') { "
               "continue; }\n\n";
        ret += "      const temp = " + conversion_function + "(targetEnum, " +
               field_binded_method + ", targetEnumIndex);\n";
        ret += "      if(temp === " + null_keyword_ + ") { continue; }\n";
        ret += union_has_string ? "      if(typeof temp === 'string') { "
                                  "ret.push(temp); continue; }\n"
                                : "";
        ret += "      ret.push(temp.unpack());\n";
        ret += "    }\n";
        ret += "    return ret;\n";
        ret += "  })()";
      }

      return ret;
    }

    FLATBUFFERS_ASSERT(0);
    return "";
  }

  std::string GenNullCheckConditional(const std::string& nullCheckVar,
                                      const std::string& trueVal,
                                      const std::string& falseVal = "") {
    std::string false_val = falseVal.empty() ? null_keyword_ : falseVal;
    return "(" + nullCheckVar + " !== " + null_keyword_ + " ? " + trueVal +
           " : " + false_val + ")";
  }

  std::string GenStructMemberValueTS(const StructDef& struct_def,
                                     const std::string& prefix,
                                     const std::string& delimiter,
                                     const bool nullCheck = true) {
    std::string ret;
    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      auto& field = **it;

      auto curr_member_accessor = prefix + "." + namer_.Method(field);
      if (prefix != "this") {
        curr_member_accessor = prefix + "?." + namer_.Method(field);
      }
      if (IsStruct(field.value.type)) {
        ret += GenStructMemberValueTS(*field.value.type.struct_def,
                                      curr_member_accessor, delimiter);
      } else {
        if (nullCheck) {
          std::string nullValue = "0";
          if (field.value.type.base_type == BASE_TYPE_BOOL) {
            nullValue = "false";
          } else if (field.value.type.base_type == BASE_TYPE_LONG ||
                     field.value.type.base_type == BASE_TYPE_ULONG) {
            nullValue = "BigInt(0)";
          } else if (field.value.type.base_type == BASE_TYPE_ARRAY) {
            nullValue = "[]";
          }
          ret += "(" + curr_member_accessor + " ?? " + nullValue + ")";
        } else {
          ret += curr_member_accessor;
        }
      }

      if (std::next(it) != struct_def.fields.vec.end()) {
        ret += delimiter;
      }
    }

    return ret;
  }

  void GenObjApi(const Parser& parser, StructDef& struct_def,
                 std::string& obj_api_unpack_func, std::string& obj_api_class,
                 import_set& imports) {
    const auto class_name = GetTypeName(struct_def, /*object_api=*/true);

    std::string unpack_func = "\nunpack(): " + class_name +
                              " {\n  return new " + class_name + "(" +
                              (struct_def.fields.vec.empty() ? "" : "\n");
    std::string unpack_to_func = "\nunpackTo(_o: " + class_name + "): void {" +
                                 +(struct_def.fields.vec.empty() ? "" : "\n");

    std::string constructor_func = "constructor(";
    constructor_func += (struct_def.fields.vec.empty() ? "" : "\n");

    const auto has_create =
        struct_def.fixed || CanCreateFactoryMethod(struct_def);

    std::string pack_func_prototype =
        "\npack(builder:flatbuffers.Builder): flatbuffers.Offset {\n";

    std::string pack_func_offset_decl;
    std::string pack_func_create_call;

    const auto struct_name = AddImport(imports, struct_def, struct_def).name;

    if (has_create) {
      pack_func_create_call = "  return " + struct_name + ".create" +
                              GetPrefixedName(struct_def) + "(builder" +
                              (struct_def.fields.vec.empty() ? "" : ",\n    ");
    } else {
      pack_func_create_call = "  " + struct_name + ".start" +
                              GetPrefixedName(struct_def) + "(builder);\n";
    }

    if (struct_def.fixed) {
      // when packing struct, nested struct's members instead of the struct's
      // offset are used
      pack_func_create_call +=
          GenStructMemberValueTS(struct_def, "this", ",\n    ", false) + "\n  ";
    }

    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);
      const std::string field_binded_method =
          "this." + field_method + ".bind(this)";

      std::string field_val;
      std::string field_type;
      // a string that declares a variable containing the
      // offset for things that can't be generated inline
      // empty otw
      std::string field_offset_decl;
      // a string that contains values for things that can be created inline or
      // the variable name from field_offset_decl
      std::string field_offset_val;
      const auto field_default_val = GenDefaultValue(field, imports);

      // Emit a scalar field
      const auto is_string = IsString(field.value.type);
      if (IsScalar(field.value.type.base_type) || is_string) {
        const auto has_null_default = is_string || HasNullDefault(field);

        field_type += GenTypeName(imports, field, field.value.type, false,
                                  has_null_default);
        field_val = "this." + namer_.Method(field) + "()";

        if (field.value.type.base_type != BASE_TYPE_STRING) {
          field_offset_val = "this." + namer_.Field(field);
        } else {
          field_offset_decl = GenNullCheckConditional(
              "this." + namer_.Field(field),
              "builder.createString(this." + field_field + "!)", "0");
        }
      }

      // Emit an object field
      else {
        auto is_vector = false;
        switch (field.value.type.base_type) {
          case BASE_TYPE_STRUCT: {
            const auto& sd = *field.value.type.struct_def;
            field_type += AddImport(imports, struct_def, sd).object_name;

            const std::string field_accessor =
                "this." + namer_.Method(field) + "()";
            field_val = GenNullCheckConditional(
                field_accessor, field_accessor + "!.unpack()", null_keyword_);
            auto packing = GenNullCheckConditional(
                "this." + field_field,
                "this." + field_field + "!.pack(builder)", "0");

            if (sd.fixed) {
              field_offset_val = std::move(packing);
            } else {
              field_offset_decl = std::move(packing);
            }

            break;
          }

          case BASE_TYPE_ARRAY: {
            auto vectortype = field.value.type.VectorType();
            auto vectortypename =
                GenTypeName(imports, struct_def, vectortype, false);
            is_vector = true;

            field_type = "(";

            switch (vectortype.base_type) {
              case BASE_TYPE_STRUCT: {
                const auto& sd = *field.value.type.struct_def;
                const auto field_type_name =
                    GetTypeName(sd, /*object_api=*/true);
                field_type += field_type_name;
                field_type += ")[]";

                field_val = GenBBAccess() + ".createObjList<" + vectortypename +
                            ", " + field_type_name + ">(" +
                            field_binded_method + ", " +
                            NumToString(field.value.type.fixed_length) + ")";

                if (sd.fixed) {
                  field_offset_decl =
                      "builder.createStructOffsetList(this." + field_field +
                      ", " + AddImport(imports, struct_def, struct_def).name +
                      "." + namer_.Method("start", field, "Vector") + ")";
                } else {
                  field_offset_decl =
                      AddImport(imports, struct_def, struct_def).name + "." +
                      namer_.Method("create", field, "Vector") +
                      "(builder, builder.createObjectOffsetList(" + "this." +
                      field_field + "))";
                }

                break;
              }

              case BASE_TYPE_STRING: {
                field_type += "string)[]";
                field_val = GenBBAccess() + ".createScalarList<string>(" +
                            field_binded_method + ", this." +
                            namer_.Field(field, "Length") + "())";
                field_offset_decl =
                    AddImport(imports, struct_def, struct_def).name + "." +
                    namer_.Method("create", field, "Vector") +
                    "(builder, builder.createObjectOffsetList(" + "this." +
                    namer_.Field(field) + "))";
                break;
              }

              case BASE_TYPE_UNION: {
                field_type += GenObjApiUnionTypeTS(
                    imports, struct_def, parser.opts, *(vectortype.enum_def));
                field_type += ")[]";
                field_val = GenUnionValTS(imports, struct_def, field_method,
                                          vectortype, true);

                field_offset_decl =
                    AddImport(imports, struct_def, struct_def).name + "." +
                    namer_.Method("create", field, "Vector") +
                    "(builder, builder.createObjectOffsetList(" + "this." +
                    namer_.Field(field) + "))";

                break;
              }
              default: {
                if (vectortype.enum_def) {
                  field_type += GenTypeName(imports, struct_def, vectortype,
                                            false, HasNullDefault(field));
                } else {
                  field_type += vectortypename;
                }
                field_type += ")[]";
                field_val = GenBBAccess() + ".createScalarList<" +
                            vectortypename + ">(" + field_binded_method + ", " +
                            NumToString(field.value.type.fixed_length) + ")";

                field_offset_decl =
                    AddImport(imports, struct_def, struct_def).name + "." +
                    namer_.Method("create", field, "Vector") +
                    "(builder, this." + field_field + ")";

                break;
              }
            }

            break;
          }

          case BASE_TYPE_VECTOR: {
            auto vectortype = field.value.type.VectorType();
            auto vectortypename =
                GenTypeName(imports, struct_def, vectortype, false);
            is_vector = true;

            field_type = "(";

            switch (vectortype.base_type) {
              case BASE_TYPE_STRUCT: {
                const auto& sd = *field.value.type.struct_def;
                const auto field_type_name =
                    GetTypeName(sd, /*object_api=*/true);
                field_type += field_type_name;
                field_type += ")[]";

                field_val = GenBBAccess() + ".createObjList<" + vectortypename +
                            ", " + field_type_name + ">(" +
                            field_binded_method + ", this." +
                            namer_.Method(field, "Length") + "())";

                if (sd.fixed) {
                  field_offset_decl =
                      "builder.createStructOffsetList(this." + field_field +
                      ", " + AddImport(imports, struct_def, struct_def).name +
                      "." + namer_.Method("start", field, "Vector") + ")";
                } else {
                  field_offset_decl =
                      AddImport(imports, struct_def, struct_def).name + "." +
                      namer_.Method("create", field, "Vector") +
                      "(builder, builder.createObjectOffsetList(" + "this." +
                      field_field + "))";
                }

                break;
              }

              case BASE_TYPE_STRING: {
                field_type += "string)[]";
                field_val = GenBBAccess() + ".createScalarList<string>(" +
                            field_binded_method + ", this." +
                            namer_.Field(field, "Length") + "())";
                field_offset_decl =
                    AddImport(imports, struct_def, struct_def).name + "." +
                    namer_.Method("create", field, "Vector") +
                    "(builder, builder.createObjectOffsetList(" + "this." +
                    namer_.Field(field) + "))";
                break;
              }

              case BASE_TYPE_UNION: {
                field_type += GenObjApiUnionTypeTS(
                    imports, struct_def, parser.opts, *(vectortype.enum_def));
                field_type += ")[]";
                field_val = GenUnionValTS(imports, struct_def, field_method,
                                          vectortype, true);

                field_offset_decl =
                    AddImport(imports, struct_def, struct_def).name + "." +
                    namer_.Method("create", field, "Vector") +
                    "(builder, builder.createObjectOffsetList(" + "this." +
                    namer_.Field(field) + "))";

                break;
              }
              default: {
                if (vectortype.enum_def) {
                  field_type += GenTypeName(imports, struct_def, vectortype,
                                            false, HasNullDefault(field));
                } else {
                  field_type += vectortypename;
                }
                field_type += ")[]";
                field_val = GenBBAccess() + ".createScalarList<" +
                            vectortypename + ">(" + field_binded_method +
                            ", this." + namer_.Method(field, "Length") + "())";

                field_offset_decl =
                    AddImport(imports, struct_def, struct_def).name + "." +
                    namer_.Method("create", field, "Vector") +
                    "(builder, this." + field_field + ")";

                break;
              }
            }

            break;
          }

          case BASE_TYPE_UNION: {
            field_type += GenObjApiUnionTypeTS(imports, struct_def, parser.opts,
                                               *(field.value.type.enum_def));

            field_val = GenUnionValTS(imports, struct_def, field_method,
                                      field.value.type);
            field_offset_decl =
                "builder.createObjectOffset(this." + field_field + ")";
            break;
          }

          default:
            FLATBUFFERS_ASSERT(0);
            break;
        }

        // length 0 vector is simply empty instead of null/undefined.
        field_type += is_vector ? "" : ("|" + null_keyword_);
      }

      if (!field_offset_decl.empty()) {
        field_offset_decl =
            "  const " + field_field + " = " + field_offset_decl + ";";
      }
      if (field_offset_val.empty()) {
        field_offset_val = field_field;
      }

      unpack_func += "    " + field_val;
      unpack_to_func += "  _o." + field_field + " = " + field_val + ";";

      // FIXME: if field_type and field_field are identical, then
      // this generates invalid typescript.
      constructor_func += "  public " + field_field + ": " + field_type +
                          " = " + field_default_val;

      if (!struct_def.fixed) {
        if (!field_offset_decl.empty()) {
          pack_func_offset_decl += field_offset_decl + "\n";
        }

        if (has_create) {
          pack_func_create_call += field_offset_val;
        } else {
          if (field.IsScalarOptional()) {
            pack_func_create_call +=
                "  if (" + field_offset_val + " !== " + null_keyword_ + ")\n  ";
          }
          pack_func_create_call += "  " + struct_name + "." +
                                   namer_.Method("add", field) + "(builder, " +
                                   field_offset_val + ");\n";
        }
      }

      if (std::next(it) != struct_def.fields.vec.end()) {
        constructor_func += ",\n";

        if (!struct_def.fixed && has_create) {
          pack_func_create_call += ",\n    ";
        }

        unpack_func += ",\n";
        unpack_to_func += "\n";
      } else {
        constructor_func += "\n";
        if (!struct_def.fixed) {
          pack_func_offset_decl += (pack_func_offset_decl.empty() ? "" : "\n");
          pack_func_create_call += "\n  ";
        }

        unpack_func += "\n  ";
        unpack_to_func += "\n";
      }
    }

    constructor_func += "){}\n\n";

    if (has_create) {
      pack_func_create_call += ");";
    } else {
      pack_func_create_call += "return " + struct_name + ".end" +
                               GetPrefixedName(struct_def) + "(builder);";
    }
    obj_api_class = "\n";
    obj_api_class += "export class ";
    obj_api_class += GetTypeName(struct_def, /*object_api=*/true);
    obj_api_class += " implements flatbuffers.IGeneratedObject {\n";
    obj_api_class += constructor_func;
    obj_api_class += pack_func_prototype + pack_func_offset_decl +
                     pack_func_create_call + "\n}";

    obj_api_class += "\n}\n";

    unpack_func += ");\n}";
    unpack_to_func += "}\n";

    obj_api_unpack_func = unpack_func + "\n\n" + unpack_to_func;
  }

  static bool CanCreateFactoryMethod(const StructDef& struct_def) {
    // to preserve backwards compatibility, we allow the first field to be a
    // struct
    return struct_def.fields.vec.size() < 2 ||
           std::all_of(
               std::begin(struct_def.fields.vec) + 1,
               std::end(struct_def.fields.vec),
               [](const FieldDef* f) -> bool {
                 FLATBUFFERS_ASSERT(f != nullptr);
                 return f->value.type.base_type != BASE_TYPE_STRUCT;
               });
  }

  // Generate an accessor struct with constructor for a flatbuffers struct.
  void GenStruct(const Parser& parser, StructDef& struct_def,
                 std::string* code_ptr, import_set& imports) {
    if (struct_def.generated) return;
    std::string& code = *code_ptr;

    // Special case for the root struct, since no one will necessarily reference
    // it, we have to explicitly add it to the import list.
    if (&struct_def == parser_.root_struct_def_) {
      AddImport(imports, struct_def, struct_def);
    }

    const std::string object_name = GetTypeName(struct_def);
    const std::string object_api_name = GetTypeName(struct_def, true);

    // Emit constructor
    GenDocComment(struct_def.doc_comment, code_ptr);
    code += "export class ";
    code += object_name;
    if (parser.opts.generate_object_based_api) {
      code += " implements flatbuffers.IUnpackableObject<" + object_api_name +
              "> {\n";
    } else {
      code += " {\n";
    }
    code += "  bb: flatbuffers.ByteBuffer|" + null_keyword_ + " = " +
            null_keyword_ + ";\n";
    code += "  bb_pos = 0;\n";

    // Generate the __init method that sets the field in a pre-existing
    // accessor object. This is to allow object reuse.
    code +=
        "  __init(i:number, bb:flatbuffers.ByteBuffer):" + object_name + " {\n";
    code += "  this.bb_pos = i;\n";
    code += "  this.bb = bb;\n";
    code += "  return this;\n";
    code += "}\n\n";

    // Generate special accessors for the table that when used as the root of a
    // FlatBuffer
    GenerateRootAccessor(struct_def, code_ptr, code, object_name, false);
    GenerateRootAccessor(struct_def, code_ptr, code, object_name, true);

    // Generate the identifier check method
    if (!struct_def.fixed && parser_.root_struct_def_ == &struct_def &&
        !parser_.file_identifier_.empty()) {
      GenDocComment(code_ptr);
      code +=
          "static bufferHasIdentifier(bb:flatbuffers.ByteBuffer):boolean "
          "{\n";
      code += "  return bb.__has_identifier('" + parser_.file_identifier_;
      code += "');\n}\n\n";
    }

    // Emit field accessors
    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      auto& field = **it;
      if (field.deprecated) continue;
      std::string offset_prefix = "";

      if (field.value.type.base_type == BASE_TYPE_ARRAY) {
        offset_prefix = "    return ";
      } else {
        offset_prefix = "  const offset = " + GenBBAccess() +
                        ".__offset(this.bb_pos, " +
                        NumToString(field.value.offset) + ");\n";
        offset_prefix += "  return offset ? ";
      }

      // Emit a scalar field
      const auto is_string = IsString(field.value.type);
      if (IsScalar(field.value.type.base_type) || is_string) {
        const auto has_null_default = is_string || HasNullDefault(field);

        GenDocComment(field.doc_comment, code_ptr);
        std::string prefix = namer_.Method(field) + "(";
        if (is_string) {
          code += prefix + "):string|" + null_keyword_ + "\n";
          code +=
              prefix + "optionalEncoding:flatbuffers.Encoding" + "):" +
              GenTypeName(imports, struct_def, field.value.type, false, true) +
              "\n";
          code += prefix + "optionalEncoding?:any";
        } else {
          code += prefix;
        }
        if (field.value.type.enum_def) {
          code += "):" +
                  GenTypeName(imports, struct_def, field.value.type, false,
                              field.IsOptional()) +
                  " {\n";
        } else {
          code += "):" +
                  GenTypeName(imports, struct_def, field.value.type, false,
                              has_null_default) +
                  " {\n";
        }

        if (struct_def.fixed) {
          code +=
              "  return " +
              GenGetter(field.value.type,
                        "(this.bb_pos" + MaybeAdd(field.value.offset) + ")") +
              ";\n";
        } else {
          std::string index = "this.bb_pos + offset";
          if (is_string) {
            index += ", optionalEncoding";
          }
          code +=
              offset_prefix + GenGetter(field.value.type, "(" + index + ")");
          if (field.value.type.base_type != BASE_TYPE_ARRAY) {
            code += " : " + GenDefaultValue(field, imports);
          }
          code += ";\n";
        }
      }

      // Emit an object field
      else {
        switch (field.value.type.base_type) {
          case BASE_TYPE_STRUCT: {
            const auto type =
                AddImport(imports, struct_def, *field.value.type.struct_def)
                    .name;
            GenDocComment(field.doc_comment, code_ptr);
            code += namer_.Method(field);
            code +=
                "(obj?:" + type + "):" + type + "|" + null_keyword_ + " {\n";

            if (struct_def.fixed) {
              code += "  return (obj || " + GenerateNewExpression(type);
              code += ").__init(this.bb_pos";
              code +=
                  MaybeAdd(field.value.offset) + ", " + GenBBAccess() + ");\n";
            } else {
              code += offset_prefix + "(obj || " + GenerateNewExpression(type) +
                      ").__init(";
              code += field.value.type.struct_def->fixed
                          ? "this.bb_pos + offset"
                          : GenBBAccess() + ".__indirect(this.bb_pos + offset)";
              code += ", " + GenBBAccess() + ") : " + null_keyword_ + ";\n";
            }

            break;
          }

          case BASE_TYPE_ARRAY: {
            auto vectortype = field.value.type.VectorType();
            auto vectortypename =
                GenTypeName(imports, struct_def, vectortype, false);
            auto inline_size = InlineSize(vectortype);
            auto index = "this.bb_pos + " + NumToString(field.value.offset) +
                         " + index" + MaybeScale(inline_size);
            std::string ret_type;
            bool is_union = false;
            switch (vectortype.base_type) {
              case BASE_TYPE_STRUCT:
                ret_type = vectortypename;
                break;
              case BASE_TYPE_STRING:
                ret_type = vectortypename;
                break;
              case BASE_TYPE_UNION:
                ret_type = "?flatbuffers.Table";
                is_union = true;
                break;
              default:
                ret_type = vectortypename;
            }
            GenDocComment(field.doc_comment, code_ptr);
            std::string prefix = namer_.Method(field);
            // TODO: make it work without any
            // if (is_union) { prefix += "<T extends flatbuffers.Table>"; }
            if (is_union) {
              prefix += "";
            }
            prefix += "(index: number";
            if (is_union) {
              const auto union_type =
                  GenUnionGenericTypeTS(*(field.value.type.enum_def));

              vectortypename = union_type;
              code += prefix + ", obj:" + union_type;
            } else if (vectortype.base_type == BASE_TYPE_STRUCT) {
              code += prefix + ", obj?:" + vectortypename;
            } else if (IsString(vectortype)) {
              code += prefix + "):string\n";
              code += prefix + ",optionalEncoding:flatbuffers.Encoding" +
                      "):" + vectortypename + "\n";
              code += prefix + ",optionalEncoding?:any";
            } else {
              code += prefix;
            }
            code += "):" + vectortypename + "|" + null_keyword_ + " {\n";

            if (vectortype.base_type == BASE_TYPE_STRUCT) {
              code += offset_prefix + "(obj || " +
                      GenerateNewExpression(vectortypename);
              code += ").__init(";
              code += vectortype.struct_def->fixed
                          ? index
                          : GenBBAccess() + ".__indirect(" + index + ")";
              code += ", " + GenBBAccess() + ")";
            } else {
              if (is_union) {
                index = "obj, " + index;
              } else if (IsString(vectortype)) {
                index += ", optionalEncoding";
              }
              code += offset_prefix + GenGetter(vectortype, "(" + index + ")");
            }

            switch (field.value.type.base_type) {
              case BASE_TYPE_ARRAY: {
                break;
              }
              case BASE_TYPE_BOOL: {
                code += " : false";
                break;
              }
              case BASE_TYPE_LONG:
              case BASE_TYPE_ULONG: {
                code += " : BigInt(0)";
                break;
              }
              default: {
                if (IsScalar(field.value.type.element)) {
                  if (field.value.type.enum_def) {
                    code += field.value.constant;
                  } else {
                    code += " : 0";
                  }
                } else {
                  code += ": " + null_keyword_;
                }
                break;
              }
            }
            code += ";\n";
            break;
          }

          case BASE_TYPE_VECTOR: {
            auto vectortype = field.value.type.VectorType();
            auto vectortypename =
                GenTypeName(imports, struct_def, vectortype, false);
            auto type = GetUnderlyingVectorType(vectortype);
            auto inline_size = InlineSize(type);
            auto index = GenBBAccess() +
                         ".__vector(this.bb_pos + offset) + index" +
                         MaybeScale(inline_size);
            std::string ret_type;
            bool is_union = false;
            switch (vectortype.base_type) {
              case BASE_TYPE_STRUCT:
                ret_type = vectortypename;
                break;
              case BASE_TYPE_STRING:
                ret_type = vectortypename;
                break;
              case BASE_TYPE_UNION:
                ret_type = "?flatbuffers.Table";
                is_union = true;
                break;
              default:
                ret_type = vectortypename;
            }
            GenDocComment(field.doc_comment, code_ptr);
            std::string prefix = namer_.Method(field);
            // TODO: make it work without any
            // if (is_union) { prefix += "<T extends flatbuffers.Table>"; }
            if (is_union) {
              prefix += "";
            }
            prefix += "(index: number";
            if (is_union) {
              const auto union_type =
                  GenUnionGenericTypeTS(*(field.value.type.enum_def));

              vectortypename = union_type;
              code += prefix + ", obj:" + union_type;
            } else if (vectortype.base_type == BASE_TYPE_STRUCT) {
              code += prefix + ", obj?:" + vectortypename;
            } else if (IsString(vectortype)) {
              code += prefix + "):string\n";
              code += prefix + ",optionalEncoding:flatbuffers.Encoding" +
                      "):" + vectortypename + "\n";
              code += prefix + ",optionalEncoding?:any";
            } else {
              code += prefix;
            }
            code += "):" + vectortypename + "|" + null_keyword_ + " {\n";

            if (vectortype.base_type == BASE_TYPE_STRUCT) {
              code += offset_prefix + "(obj || " +
                      GenerateNewExpression(vectortypename);
              code += ").__init(";
              code += vectortype.struct_def->fixed
                          ? index
                          : GenBBAccess() + ".__indirect(" + index + ")";
              code += ", " + GenBBAccess() + ")";
            } else {
              if (is_union) {
                index = "obj, " + index;
              } else if (IsString(vectortype)) {
                index += ", optionalEncoding";
              }
              code += offset_prefix + GenGetter(vectortype, "(" + index + ")");
            }
            code += " : ";
            if (field.value.type.element == BASE_TYPE_BOOL) {
              code += "false";
            } else if (field.value.type.element == BASE_TYPE_LONG ||
                       field.value.type.element == BASE_TYPE_ULONG) {
              code += "BigInt(0)";
            } else if (IsScalar(field.value.type.element)) {
              if (field.value.type.enum_def) {
                code += null_keyword_;
              } else {
                code += "0";
              }
            } else {
              code += null_keyword_;
            }
            code += ";\n";
            break;
          }

          case BASE_TYPE_UNION: {
            GenDocComment(field.doc_comment, code_ptr);
            code += namer_.Method(field);

            const auto& union_enum = *(field.value.type.enum_def);
            const auto union_type = GenUnionGenericTypeTS(union_enum);
            code += "<T extends flatbuffers.Table>(obj:" + union_type +
                    "):" + union_type + "|" + null_keyword_ +
                    " "
                    "{\n";

            code += offset_prefix +
                    GenGetter(field.value.type, "(obj, this.bb_pos + offset)") +
                    " : " + null_keyword_ + ";\n";
            break;
          }
          default:
            FLATBUFFERS_ASSERT(0);
        }
      }
      code += "}\n\n";

      // Adds the mutable scalar value to the output
      if (IsScalar(field.value.type.base_type) && parser.opts.mutable_buffer &&
          !IsUnion(field.value.type)) {
        std::string type =
            GenTypeName(imports, struct_def, field.value.type, true);

        code += namer_.LegacyTsMutateMethod(field) + "(value:" + type +
                "):boolean {\n";

        const std::string write_method =
            "." + namer_.Method("write", GenType(field.value.type));

        if (struct_def.fixed) {
          code += "  " + GenBBAccess() + write_method + "(this.bb_pos + " +
                  NumToString(field.value.offset) + ", ";
        } else {
          code += "  const offset = " + GenBBAccess() +
                  ".__offset(this.bb_pos, " + NumToString(field.value.offset) +
                  ");\n\n";
          code += "  if (offset === 0) {\n";
          code += "    return false;\n";
          code += "  }\n\n";

          code +=
              "  " + GenBBAccess() + write_method + "(this.bb_pos + offset, ";
        }

        // special case for bools, which are treated as uint8
        if (field.value.type.base_type == BASE_TYPE_BOOL) {
          code += "+";
        }

        code += "value);\n";
        code += "  return true;\n";
        code += "}\n\n";
      }

      // Emit vector helpers
      if (IsVector(field.value.type)) {
        // Emit a length helper
        GenDocComment(code_ptr);
        code += namer_.Method(field, "Length");
        code += "():number {\n" + offset_prefix;

        code +=
            GenBBAccess() + ".__vector_len(this.bb_pos + offset) : 0;\n}\n\n";

        // For scalar types, emit a typed array helper
        auto vectorType = field.value.type.VectorType();
        if (IsScalar(vectorType.base_type) && !IsLong(vectorType.base_type)) {
          GenDocComment(code_ptr);

          code += namer_.Method(field, "Array");
          code += "():" + GenType(vectorType) + "Array|" + null_keyword_ +
                  " {\n" + offset_prefix;

          code += "new " + GenType(vectorType) + "Array(" + GenBBAccess() +
                  ".bytes().buffer, " + GenBBAccess() +
                  ".bytes().byteOffset + " + GenBBAccess() +
                  ".__vector(this.bb_pos + offset), " + GenBBAccess() +
                  ".__vector_len(this.bb_pos + offset)) : " + null_keyword_ +
                  ";\n}\n\n";
        }
      }
    }

    // Emit the fully qualified name
    if (parser_.opts.generate_name_strings) {
      const std::string fullyQualifiedName =
          struct_def.defined_namespace->GetFullyQualifiedName(struct_def.name);

      GenDocComment(code_ptr);
      code += "static getFullyQualifiedName(): \"";
      code += fullyQualifiedName;
      code += "\" {\n";
      code += "  return '" + fullyQualifiedName + "';\n";
      code += "}\n\n";
    }

    // Emit the size of the struct.
    if (struct_def.fixed) {
      GenDocComment(code_ptr);
      code += "static sizeOf():number {\n";
      code += "  return " + NumToString(struct_def.bytesize) + ";\n";
      code += "}\n\n";
    }

    // Emit a factory constructor
    if (struct_def.fixed) {
      std::string arguments;
      GenStructArgs(imports, struct_def, struct_def, &arguments, "");
      GenDocComment(code_ptr);

      code += "static create" + GetPrefixedName(struct_def) +
              "(builder:flatbuffers.Builder";
      code += arguments + "):flatbuffers.Offset {\n";

      GenStructBody(struct_def, &code, "");
      code += "  return builder.offset();\n}\n\n";
    } else {
      // Generate a method to start building a new object
      GenDocComment(code_ptr);

      code += "static start" + GetPrefixedName(struct_def) +
              "(builder:flatbuffers.Builder) {\n";

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

      // Generate a set of static methods that allow table construction
      for (auto it = struct_def.fields.vec.begin();
           it != struct_def.fields.vec.end(); ++it) {
        auto& field = **it;
        if (field.deprecated) continue;
        const auto argname = GetArgName(field);

        // Generate the field insertion method
        GenDocComment(code_ptr);
        code += "static " + namer_.Method("add", field);
        code += "(builder:flatbuffers.Builder, " + argname + ":" +
                GetArgType(imports, struct_def, field, false) + ") {\n";
        code += "  builder.addField" + GenWriteMethod(field.value.type) + "(";
        code += NumToString(it - struct_def.fields.vec.begin()) + ", ";
        if (field.value.type.base_type == BASE_TYPE_BOOL) {
          code += "+";
        }
        code += argname + ", ";
        if (!IsScalar(field.value.type.base_type)) {
          code += "0";
        } else if (HasNullDefault(field)) {
          code += null_keyword_;
        } else {
          if (field.value.type.base_type == BASE_TYPE_BOOL) {
            code += "+";
          }
          code += GenDefaultValue(field, imports);
        }
        code += ");\n}\n\n";

        if (IsVector(field.value.type)) {
          auto vector_type = field.value.type.VectorType();
          auto type = GetUnderlyingVectorType(vector_type);
          auto alignment = InlineAlignment(type);
          auto elem_size = InlineSize(type);

          // Generate a method to create a vector from a JavaScript array
          if (!IsStruct(vector_type)) {
            GenDocComment(code_ptr);

            const std::string sig_begin =
                "static " + namer_.Method("create", field, "Vector") +
                "(builder:flatbuffers.Builder, data:";
            const std::string sig_end = "):flatbuffers.Offset";
            std::string type =
                GenTypeName(imports, struct_def, vector_type, true) + "[]";
            if (type == "number[]") {
              const auto& array_type = GenType(vector_type);
              // the old type should be deprecated in the future
              std::string type_old = "number[]|Uint8Array";
              std::string type_new = "number[]|" + array_type + "Array";
              if (type_old == type_new) {
                type = type_new;
              } else {
                // add function overloads
                code += sig_begin + type_new + sig_end + ";\n";
                code +=
                    "/**\n * @deprecated This Uint8Array overload will "
                    "be removed in the future.\n */\n";
                code += sig_begin + type_old + sig_end + ";\n";
                type = type_new + "|Uint8Array";
              }
            }
            code += sig_begin + type + sig_end + " {\n";
            code += "  builder.startVector(" + NumToString(elem_size);
            code += ", data.length, " + NumToString(alignment) + ");\n";
            code += "  for (let i = data.length - 1; i >= 0; i--) {\n";
            code += "    builder.add" + GenWriteMethod(vector_type) + "(";
            if (vector_type.base_type == BASE_TYPE_BOOL) {
              code += "+";
            }
            code += "data[i]!);\n";
            code += "  }\n";
            code += "  return builder.endVector();\n";
            code += "}\n\n";
          }

          // Generate a method to start a vector, data to be added manually
          // after
          GenDocComment(code_ptr);

          code += "static ";
          code += namer_.Method("start", field, "Vector");
          code += "(builder:flatbuffers.Builder, numElems:number) {\n";
          code += "  builder.startVector(" + NumToString(elem_size);
          code += ", numElems, " + NumToString(alignment) + ");\n";
          code += "}\n\n";
        }
      }

      // Generate a method to stop building a new object
      GenDocComment(code_ptr);

      code += "static end" + GetPrefixedName(struct_def);
      code += "(builder:flatbuffers.Builder):flatbuffers.Offset {\n";

      code += "  const offset = builder.endObject();\n";
      for (auto it = struct_def.fields.vec.begin();
           it != struct_def.fields.vec.end(); ++it) {
        auto& field = **it;
        if (!field.deprecated && field.IsRequired()) {
          code += "  builder.requiredField(offset, ";
          code += NumToString(field.value.offset);
          code += ") // " + field.name + "\n";
        }
      }
      code += "  return offset;\n";
      code += "}\n\n";

      // Generate the methods to complete buffer construction
      GenerateFinisher(struct_def, code_ptr, code, false);
      GenerateFinisher(struct_def, code_ptr, code, true);

      // Generate a convenient CreateX function
      if (CanCreateFactoryMethod(struct_def)) {
        code += "static create" + GetPrefixedName(struct_def);
        code += "(builder:flatbuffers.Builder";
        for (auto it = struct_def.fields.vec.begin();
             it != struct_def.fields.vec.end(); ++it) {
          const auto& field = **it;
          if (field.deprecated) continue;
          code += ", " + GetArgName(field) + ":" +
                  GetArgType(imports, struct_def, field, true);
        }

        code += "):flatbuffers.Offset {\n";
        code += "  " + object_name + ".start" + GetPrefixedName(struct_def) +
                "(builder);\n";

        std::string methodPrefix = object_name;
        for (auto it = struct_def.fields.vec.begin();
             it != struct_def.fields.vec.end(); ++it) {
          const auto& field = **it;
          if (field.deprecated) continue;

          const auto arg_name = GetArgName(field);

          if (field.IsScalarOptional()) {
            code += "  if (" + arg_name + " !== " + null_keyword_ + ")\n  ";
          }

          code += "  " + methodPrefix + "." + namer_.Method("add", field) + "(";
          code += "builder, " + arg_name + ");\n";
        }

        code += "  return " + methodPrefix + ".end" +
                GetPrefixedName(struct_def) + "(builder);\n";
        code += "}\n";
      }
    }

    if (!struct_def.fixed && parser_.services_.vec.size() != 0) {
      auto name = GetPrefixedName(struct_def, "");
      code += "\n";
      code += "serialize():Uint8Array {\n";
      code += "  return this.bb!.bytes();\n";
      code += "}\n";

      code += "\n";
      code += "static deserialize(buffer: Uint8Array):" +
              namer_.EscapeKeyword(name) + " {\n";
      code += "  return " + AddImport(imports, struct_def, struct_def).name +
              ".getRootAs" + name + "(new flatbuffers.ByteBuffer(buffer))\n";
      code += "}\n";
    }

    if (parser_.opts.generate_object_based_api) {
      std::string obj_api_class;
      std::string obj_api_unpack_func;
      GenObjApi(parser_, struct_def, obj_api_unpack_func, obj_api_class,
                imports);

      code += obj_api_unpack_func + "}\n" + obj_api_class;
    } else {
      code += "}\n";
    }
  }

  bool HasNullDefault(const FieldDef& field) {
    return field.IsOptional() && field.value.constant == "null";
  }

  std::string GetArgType(import_set& imports, const Definition& owner,
                         const FieldDef& field, bool allowNull) {
    return GenTypeName(imports, owner, field.value.type, true,
                       allowNull && field.IsOptional());
  }

  std::string GetArgName(const FieldDef& field) {
    auto argname = namer_.Variable(field);
    if (!IsScalar(field.value.type.base_type)) {
      argname += "Offset";
    }
    return argname;
  }

  std::string GetPrefixedName(const StructDef& struct_def,
                              const char* prefix = "") {
    return prefix + struct_def.name;
  }
};  // namespace ts
}  // namespace ts

static bool GenerateTS(const Parser& parser, const std::string& path,
                       const std::string& file_name) {
  ts::TsGenerator generator(parser, path, file_name);
  return generator.generate();
}

static std::string TSMakeRule(const Parser& parser, const std::string& path,
                              const std::string& file_name) {
  std::string filebase =
      flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
  ts::TsGenerator generator(parser, path, file_name);
  std::string make_rule =
      generator.GeneratedFileName(path, filebase, parser.opts) + ": ";

  auto included_files = parser.GetIncludedFilesRecursive(file_name);
  for (auto it = included_files.begin(); it != included_files.end(); ++it) {
    make_rule += " " + *it;
  }
  return make_rule;
}

namespace {

class TsCodeGenerator : public CodeGenerator {
 public:
  Status GenerateCode(const Parser& parser, const std::string& path,
                      const std::string& filename) override {
    if (!GenerateTS(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 {
    output = TSMakeRule(parser, path, filename);
    return Status::OK;
  }

  Status GenerateGrpcCode(const Parser& parser, const std::string& path,
                          const std::string& filename) override {
    if (!GenerateTSGRPC(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::kTs; }

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

std::unique_ptr<CodeGenerator> NewTsCodeGenerator() {
  return std::unique_ptr<TsCodeGenerator>(new TsCodeGenerator());
}

}  // namespace flatbuffers
