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

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

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

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

      // For scalar types, emit a typed array helper
      auto vectorType = field.value.type.VectorType();
      if (IsScalar(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.__vector(this.bb_pos + offset), "
          "this.bb.__vector_len(this.bb_pos + offset)) : null;\n};\n\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
