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

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()) {}

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

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

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

      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") : name;
      }
    }

    switch (type.base_type) {
      case BASE_TYPE_BOOL:
        return allowNull ? "boolean|null" : "boolean";
      case BASE_TYPE_LONG:
      case BASE_TYPE_ULONG:
        return allowNull ? "bigint|null" : "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" : "");
      }
      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") : enum_name;
          }
          return allowNull ? "number|null" : "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,
                     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, arguments,
                      nameprefix + field.name + "_");
      } else {
        *arguments += ", " + nameprefix + field.name + ": " +
                      GenTypeName(imports, field, 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;
  }

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

    std::string bare_file_path;
    std::string rel_file_path;
    if (dependent.defined_namespace) {
      const auto& dep_comps = dependent.defined_namespace->components;
      for (size_t i = 0; i < dep_comps.size(); i++) {
        rel_file_path += i == 0 ? ".." : (kPathSeparator + std::string(".."));
      }
      if (dep_comps.size() == 0) {
        rel_file_path += ".";
      }
    } else {
      rel_file_path += "..";
    }

    bare_file_path +=
        kPathSeparator +
        namer_.Directories(dependency.defined_namespace->components,
                           SkipDir::OutputPath) +
        namer_.File(dependency, SkipFile::SuffixAndExtension);
    rel_file_path += bare_file_path;

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

      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; \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;\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) { return null; }\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 || " + enum_type +
               "[targetEnum!] === 'NONE') { "
               "continue; }\n\n";
        ret += "      const temp = " + conversion_function + "(targetEnum, " +
               field_binded_method + ", targetEnumIndex);\n";
        ret += "      if(temp === null) { 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 "";
  }

  static std::string GenNullCheckConditional(
      const std::string& nullCheckVar, const std::string& trueVal,
      const std::string& falseVal = "null") {
    return "(" + nullCheckVar + " !== null ? " + trueVal + " : " + falseVal +
           ")";
  }

  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()");
            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
        field_type += is_vector ? "" : "|null";
      }

      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)\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 = null;\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\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 {\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;\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 {\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";
                }
                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 {\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";
              } else {
                code += "0";
              }
            } else {
              code += "null";
            }
            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 "
                    "{\n";

            code += offset_prefix +
                    GenGetter(field.value.type, "(obj, this.bb_pos + offset)") +
                    " : null;\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 {\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;\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, &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";
        } 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)\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";
    }
  }

  static 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
