/*
 * Copyright 2014 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// independent from idl_parser, since this code is not needed for most clients

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

namespace flatbuffers {

static std::string GeneratedFileName(const std::string &path,
                                     const std::string &file_name) {
  return path + file_name + "_generated.js";
}

namespace js {
// Iterate through all definitions we haven't generate code for (enums, structs,
// and tables) and output them to a single file.
class JsGenerator : public BaseGenerator {
 public:
  JsGenerator(const Parser &parser, const std::string &path,
              const std::string &file_name)
      : BaseGenerator(parser, path, file_name, "", "."){};
  // Iterate through all definitions we haven't generate code for (enums,
  // structs, and tables) and output them to a single file.
  bool generate() {
    if (IsEverythingGenerated()) return true;

    std::string enum_code, struct_code, exports_code, code;
    generateEnums(&enum_code, &exports_code);
    generateStructs(&struct_code, &exports_code);

    code = code + "// " + FlatBuffersGeneratedWarning();

    // Generate code for all the namespace declarations.
    GenNamespaces(&code, &exports_code);

    // Output the main declaration code from above.
    code += enum_code;
    code += struct_code;

    if (!exports_code.empty() && !parser_.opts.skip_js_exports) {
      code += "// Exports for Node.js and RequireJS\n";
      code += exports_code;
    }

    return SaveFile(GeneratedFileName(path_, file_name_).c_str(), code, false);
  }

 private:
  // Generate code for all enums.
  void generateEnums(std::string *enum_code_ptr,
                     std::string *exports_code_ptr) {
    for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
         ++it) {
      auto &enum_def = **it;
      GenEnum(enum_def, enum_code_ptr, exports_code_ptr);
    }
  }

  // Generate code for all structs.
  void generateStructs(std::string *decl_code_ptr,
                       std::string *exports_code_ptr) {
    for (auto it = parser_.structs_.vec.begin();
         it != parser_.structs_.vec.end(); ++it) {
      auto &struct_def = **it;
      GenStruct(parser_, struct_def, decl_code_ptr, exports_code_ptr);
    }
  }
  void GenNamespaces(std::string *code_ptr, std::string *exports_ptr) {
  std::set<std::string> namespaces;

  for (auto it = parser_.namespaces_.begin();
       it != parser_.namespaces_.end(); ++it) {
    std::string namespace_so_far;

    // Gather all parent namespaces for this namespace
    for (auto component = (*it)->components.begin();
         component != (*it)->components.end(); ++component) {
      if (!namespace_so_far.empty()) {
        namespace_so_far += '.';
      }
      namespace_so_far += *component;
      namespaces.insert(namespace_so_far);
    }
  }

  // Make sure parent namespaces come before child namespaces
  std::vector<std::string> sorted_namespaces(
    namespaces.begin(), namespaces.end());
  std::sort(sorted_namespaces.begin(), sorted_namespaces.end());

  // Emit namespaces in a form that Closure Compiler can optimize
  std::string &code = *code_ptr;
  std::string &exports = *exports_ptr;
  for (auto it = sorted_namespaces.begin();
       it != sorted_namespaces.end(); it++) {
    code += "/**\n * @const\n * @namespace\n */\n";
    if (it->find('.') == std::string::npos) {
      code += "var ";
      if(parser_.opts.use_goog_js_export_format) {
        exports += "goog.exportSymbol('" + *it + "', " + *it + ");\n";
      } else {
        exports += "this." + *it + " = " + *it + ";\n";
      }
    }
    code += *it + " = " + *it + " || {};\n\n";
  }
}

// Generate a documentation comment, if available.
static void GenDocComment(const std::vector<std::string> &dc,
                          std::string *code_ptr,
                          const std::string &extra_lines,
                          const char *indent = nullptr) {
  if (dc.empty() && extra_lines.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;
    code += " *" + *it + "\n";
  }
  if (!extra_lines.empty()) {
    if (!dc.empty()) {
      if (indent) code += indent;
      code += " *\n";
    }
    if (indent) code += indent;
    std::string::size_type start = 0;
    for (;;) {
      auto end = extra_lines.find('\n', start);
      if (end != std::string::npos) {
        code += " * " + extra_lines.substr(start, end - start) + "\n";
        start = end + 1;
      } else {
        code += " * " + extra_lines.substr(start) + "\n";
        break;
      }
    }
  }
  if (indent) code += indent;
  code += " */\n";
}

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

// Generate an enum declaration and an enum string lookup table.
void GenEnum(EnumDef &enum_def, std::string *code_ptr,
                    std::string *exports_ptr) {
  if (enum_def.generated) return;
  std::string &code = *code_ptr;
  std::string &exports = *exports_ptr;
  GenDocComment(enum_def.doc_comment, code_ptr, "@enum");
  if (enum_def.defined_namespace->components.empty()) {
    code += "var ";
    if(parser_.opts.use_goog_js_export_format) {
      exports += "goog.exportSymbol('" + enum_def.name + "', " + enum_def.name +
        ");\n";
    } else {
      exports += "this." + enum_def.name + " = " + enum_def.name + ";\n";
    }
  }
  code += WrapInNameSpace(enum_def) + " = {\n";
  for (auto it = enum_def.vals.vec.begin();
       it != enum_def.vals.vec.end(); ++it) {
    auto &ev = **it;
    if (!ev.doc_comment.empty()) {
      if (it != enum_def.vals.vec.begin()) {
        code += '\n';
      }
      GenDocComment(ev.doc_comment, code_ptr, "", "  ");
    }
    code += "  " + ev.name + ": " + NumToString(ev.value);
    code += (it + 1) != enum_def.vals.vec.end() ? ",\n" : "\n";
  }
  code += "};\n\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:
    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 "Table";
  }
}

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

std::string GenDefaultValue(const Value &value, const std::string &context) {
  if (value.type.enum_def) {
    if (auto val = value.type.enum_def->ReverseLookup(
        atoi(value.constant.c_str()), false)) {
      return WrapInNameSpace(*value.type.enum_def) + "." + val->name;
    } else {
      return "/** @type {" + WrapInNameSpace(*value.type.enum_def) + "} */ ("
        + value.constant + ")";
    }
  }

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

    case BASE_TYPE_STRING:
      return "null";

    case BASE_TYPE_LONG:
    case BASE_TYPE_ULONG: {
      int64_t constant = StringToInt(value.constant.c_str());
      return context + ".createLong(" + NumToString((int32_t)constant) +
        ", " + NumToString((int32_t)(constant >> 32)) + ")";
    }

    default:
      return value.constant;
  }
}

std::string GenTypeName(const Type &type, bool input) {
  if (!input) {
    if (type.base_type == BASE_TYPE_STRING) {
      return "string|Uint8Array";
    }
    if (type.base_type == BASE_TYPE_STRUCT) {
      return WrapInNameSpace(*type.struct_def);
    }
  }

  switch (type.base_type) {
    case BASE_TYPE_BOOL: return "boolean";
    case BASE_TYPE_LONG:
    case BASE_TYPE_ULONG: return "flatbuffers.Long";
    default:
      if (IsScalar(type.base_type)) {
        if (type.enum_def) {
          return WrapInNameSpace(*type.enum_def);
        }
        return "number";
      }
      return "flatbuffers.Offset";
  }
}

// Returns the method name for use with add/put calls.
static std::string GenWriteMethod(const Type &type) {
  // Forward to signed versions since unsigned versions don't exist
  switch (type.base_type) {
    case BASE_TYPE_UTYPE:
    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)
    ? MakeCamel(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(const StructDef &struct_def,
                          std::string *annotations,
                          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(*field.value.type.struct_def, annotations, arguments,
                    nameprefix + field.name + "_");
    } else {
      *annotations += "@param {" + GenTypeName(field.value.type, true);
      *annotations += "} " + nameprefix + field.name + "\n";
      *arguments += ", " + nameprefix + field.name;
    }
  }
}

static 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 + field.name + "_");
    } else {
      *body += "  builder.write" + GenWriteMethod(field.value.type) + "(";
      if (field.value.type.base_type == BASE_TYPE_BOOL) {
        *body += "+";
      }
      *body += nameprefix + field.name + ");\n";
    }
  }
}

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

  // Emit constructor
  bool isStatement = struct_def.defined_namespace->components.empty();
  std::string object_name = WrapInNameSpace(struct_def);
  GenDocComment(struct_def.doc_comment, code_ptr, "@constructor");
  if (isStatement) {
    if(parser_.opts.use_goog_js_export_format) {
      exports += "goog.exportSymbol('" + struct_def.name + "', " +
        struct_def.name + ");\n";
    } else {
      exports += "this." + struct_def.name + " = " + struct_def.name + ";\n";
    }
    code += "function " + object_name;
  } else {
    code += object_name + " = function";
  }
  code += "() {\n";
  code += "  /**\n";
  code += "   * @type {flatbuffers.ByteBuffer}\n";
  code += "   */\n";
  code += "  this.bb = null;\n";
  code += "\n";
  code += "  /**\n";
  code += "   * @type {number}\n";
  code += "   */\n";
  code += "  this.bb_pos = 0;\n";
  code += isStatement ? "}\n\n" : "};\n\n";

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

  // Generate a special accessor for the table that when used as the root of a
  // FlatBuffer
  if (!struct_def.fixed) {
    GenDocComment(code_ptr,
      "@param {flatbuffers.ByteBuffer} bb\n"
      "@param {" + object_name + "=} obj\n"
      "@returns {" + object_name + "}");
    code += object_name + ".getRootAs" + struct_def.name;
    code += " = function(bb, obj) {\n";
    code += "  return (obj || new " + object_name;
    code += ").__init(bb.readInt32(bb.position()) + bb.position(), bb);\n";
    code += "};\n\n";

    // Generate the identifier check method
    if (parser_.root_struct_def_ == &struct_def &&
        !parser_.file_identifier_.empty()) {
      GenDocComment(code_ptr,
        "@param {flatbuffers.ByteBuffer} bb\n"
        "@returns {boolean}");
      code += object_name + ".bufferHasIdentifier = function(bb) {\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;
    auto offset_prefix = "  var offset = this.bb.__offset(this.bb_pos, " +
      NumToString(field.value.offset) + ");\n  return offset ? ";

    // Emit a scalar field
    if (IsScalar(field.value.type.base_type) ||
        field.value.type.base_type == BASE_TYPE_STRING) {
      GenDocComment(field.doc_comment, code_ptr,
        std::string(field.value.type.base_type == BASE_TYPE_STRING ?
          "@param {flatbuffers.Encoding=} optionalEncoding\n" : "") +
        "@returns {" + GenTypeName(field.value.type, false) + "}");
      code += object_name + ".prototype." + MakeCamel(field.name, false);
      code += " = function(";
      if (field.value.type.base_type == BASE_TYPE_STRING) {
        code += "optionalEncoding";
      }
      code += ") {\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 (field.value.type.base_type == BASE_TYPE_STRING) {
          index += ", optionalEncoding";
        }
        code += offset_prefix + GenGetter(field.value.type,
          "(" + index + ")") + " : " + GenDefaultValue(field.value, "this.bb");
        code += ";\n";
      }
    }

    // Emit an object field
    else {
      switch (field.value.type.base_type) {
        case BASE_TYPE_STRUCT: {
          auto type = WrapInNameSpace(*field.value.type.struct_def);
          GenDocComment(field.doc_comment, code_ptr,
            "@param {" + type + "=} obj\n@returns {" + type + "}");
          code += object_name + ".prototype." + MakeCamel(field.name, false);
          code += " = function(obj) {\n";
          if (struct_def.fixed) {
            code += "  return (obj || new " + type;
            code += ").__init(this.bb_pos";
            code += MaybeAdd(field.value.offset) + ", this.bb);\n";
          } else {
            code += offset_prefix + "(obj || new " + type + ").__init(";
            code += field.value.type.struct_def->fixed
              ? "this.bb_pos + offset"
              : "this.bb.__indirect(this.bb_pos + offset)";
            code += ", this.bb) : null;\n";
          }
          break;
        }

        case BASE_TYPE_VECTOR: {
          auto vectortype = field.value.type.VectorType();
          auto vectortypename = GenTypeName(vectortype, false);
          auto inline_size = InlineSize(vectortype);
          auto index = "this.bb.__vector(this.bb_pos + offset) + index" +
                       MaybeScale(inline_size);
          std::string args = "@param {number} index\n";
          if (vectortype.base_type == BASE_TYPE_STRUCT) {
            args += "@param {" + vectortypename + "=} obj\n";
          } else if (vectortype.base_type == BASE_TYPE_STRING) {
            args += "@param {flatbuffers.Encoding=} optionalEncoding\n";
          }
          GenDocComment(field.doc_comment, code_ptr, args +
            "@returns {" + vectortypename + "}");
          code += object_name + ".prototype." + MakeCamel(field.name, false);
          code += " = function(index";
          if (vectortype.base_type == BASE_TYPE_STRUCT) {
            code += ", obj";
          } else if (vectortype.base_type == BASE_TYPE_STRING) {
            code += ", optionalEncoding";
          }
          code += ") {\n";
          if (vectortype.base_type == BASE_TYPE_STRUCT) {
            code += offset_prefix + "(obj || new " + vectortypename;
            code += ").__init(";
            code += vectortype.struct_def->fixed
              ? index
              : "this.bb.__indirect(" + index + ")";
            code += ", this.bb)";
          } else {
            if (vectortype.base_type == BASE_TYPE_STRING) {
              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 += "this.bb.createLong(0, 0)";
          } else if (IsScalar(field.value.type.element)) {
            if (field.value.type.enum_def) {
              code += "/** @type {" +
                WrapInNameSpace(*field.value.type.enum_def) + "} */ (" +
                field.value.constant + ")";
            } else {
              code += "0";
            }
          } else {
            code += "null";
          }
          code += ";\n";
          break;
        }

        case BASE_TYPE_UNION:
          GenDocComment(field.doc_comment, code_ptr,
            "@param {flatbuffers.Table} obj\n"
            "@returns {?flatbuffers.Table}");
          code += object_name + ".prototype." + MakeCamel(field.name, false);
          code += " = function(obj) {\n";
          code += offset_prefix + GenGetter(field.value.type,
            "(obj, this.bb_pos + offset)") + " : null;\n";
          break;

        default:
          assert(0);
      }
    }
    code += "};\n\n";

    if(parser_.opts.use_goog_js_export_format) {
      exports += "goog.exportProperty(" + object_name + ".prototype, '" +
        MakeCamel(field.name, false) + "', " + object_name + ".prototype." +
        MakeCamel(field.name, false) + ");\n";
    }

    // Adds the mutable scalar value to the output
    if (IsScalar(field.value.type.base_type) && parser.opts.mutable_buffer) {
      std::string annotations = "@param {" + GenTypeName(field.value.type, true) + "} value\n";
      GenDocComment(code_ptr, annotations +
        "@returns {boolean}");

      code += object_name + ".prototype.mutate_" + field.name + " = function(value) {\n";
      code += "  var offset = this.bb.__offset(this.bb_pos, " + NumToString(field.value.offset) + ");\n\n";
      code += "  if (offset === 0) {\n";
      code += "    return false;\n";
      code += "  }\n\n";
      code += "  this.bb.write" + MakeCamel(GenType(field.value.type)) + "(this.bb_pos + offset, value);\n";
      code += "  return true;\n";
      code += "};\n\n";

      if(parser_.opts.use_goog_js_export_format) {
        exports += "goog.exportProperty(" + object_name +
          ".prototype, 'mutate_" + field.name + "', " + object_name +
          ".prototype.mutate_" + field.name + ");\n";
      }
    }

    // Emit vector helpers
    if (field.value.type.base_type == BASE_TYPE_VECTOR) {
      // Emit a length helper
      GenDocComment(code_ptr, "@returns {number}");
      code += object_name + ".prototype." + MakeCamel(field.name, false);
      code += "Length = function() {\n" + offset_prefix;
      code += "this.bb.__vector_len(this.bb_pos + offset) : 0;\n};\n\n";

      if(parser_.opts.use_goog_js_export_format) {
        exports += "goog.exportProperty(" + object_name + ".prototype, '" +
          MakeCamel(field.name, false) + "Length', " + object_name +
          ".prototype." + MakeCamel(field.name, false) + "Length);\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, "@returns {" + GenType(vectorType) + "Array}");
        code += object_name + ".prototype." + MakeCamel(field.name, false);
        code += "Array = function() {\n" + offset_prefix;
        code += "new " + GenType(vectorType) + "Array(this.bb.bytes().buffer, "
          "this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), "
          "this.bb.__vector_len(this.bb_pos + offset)) : null;\n};\n\n";

        if(parser_.opts.use_goog_js_export_format) {
          exports += "goog.exportProperty(" + object_name + ".prototype, '" +
            MakeCamel(field.name, false) + "Array', " + object_name +
            ".prototype." + MakeCamel(field.name, false) + "Array);\n";
        }
      }
    }
  }

  // Emit a factory constructor
  if (struct_def.fixed) {
    std::string annotations = "@param {flatbuffers.Builder} builder\n";
    std::string arguments;
    GenStructArgs(struct_def, &annotations, &arguments, "");
    GenDocComment(code_ptr, annotations +
      "@returns {flatbuffers.Offset}");
    code += object_name + ".create" + struct_def.name + " = function(builder";
    code += arguments + ") {\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,
      "@param {flatbuffers.Builder} builder");
    code += object_name + ".start" + struct_def.name;
    code += " = function(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;
      auto argname = MakeCamel(field.name, false);
      if (!IsScalar(field.value.type.base_type)) {
        argname += "Offset";
      }

      // Generate the field insertion method
      GenDocComment(code_ptr,
        "@param {flatbuffers.Builder} builder\n"
        "@param {" + GenTypeName(field.value.type, true) + "} " +
        argname);
      code += object_name + ".add" + MakeCamel(field.name);
      code += " = function(builder, " + argname + ") {\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 (field.value.type.base_type == BASE_TYPE_BOOL) {
          code += "+";
        }
        code += GenDefaultValue(field.value, "builder");
      }
      code += ");\n};\n\n";

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

        // Generate a method to create a vector from a JavaScript array
        if (!IsStruct(vector_type)) {
          GenDocComment(code_ptr,
            "@param {flatbuffers.Builder} builder\n"
            "@param {Array.<" + GenTypeName(vector_type, true) +
            ">} data\n"
            "@returns {flatbuffers.Offset}");
          code += object_name + ".create" + MakeCamel(field.name);
          code += "Vector = function(builder, data) {\n";
          code += "  builder.startVector(" + NumToString(elem_size);
          code += ", data.length, " + NumToString(alignment) + ");\n";
          code += "  for (var 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,
          "@param {flatbuffers.Builder} builder\n"
          "@param {number} numElems");
        code += object_name + ".start" + MakeCamel(field.name);
        code += "Vector = function(builder, numElems) {\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,
      "@param {flatbuffers.Builder} builder\n"
      "@returns {flatbuffers.Offset}");
    code += object_name + ".end" + struct_def.name;
    code += " = function(builder) {\n";
    code += "  var 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.required) {
        code += "  builder.requiredField(offset, ";
        code += NumToString(field.value.offset);
        code += "); // " + field.name + "\n";
      }
    }
    code += "  return offset;\n";
    code += "};\n\n";

    // Generate the method to complete buffer construction
    if (parser_.root_struct_def_ == &struct_def) {
      GenDocComment(code_ptr,
        "@param {flatbuffers.Builder} builder\n"
        "@param {flatbuffers.Offset} offset");
      code += object_name + ".finish" + struct_def.name + "Buffer";
      code += " = function(builder, offset) {\n";
      code += "  builder.finish(offset";
      if (!parser_.file_identifier_.empty()) {
        code += ", '" + parser_.file_identifier_ + "'";
      }
      code += ");\n";
      code += "};\n\n";
    }
  }
}
};
}  // namespace js

bool GenerateJS(const Parser &parser, const std::string &path,
                const std::string &file_name) {
  js::JsGenerator generator(parser, path, file_name);
  return generator.generate();
}

std::string JSMakeRule(const Parser &parser,
                       const std::string &path,
                       const std::string &file_name) {
  std::string filebase = flatbuffers::StripPath(
      flatbuffers::StripExtension(file_name));
  std::string make_rule = GeneratedFileName(path, filebase) + ": ";
  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 flatbuffers
