// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <google/protobuf/compiler/js/js_generator.h>

#include <assert.h>
#include <algorithm>
#include <limits>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/stringprintf.h>
#include <google/protobuf/stubs/strutil.h>

#include <google/protobuf/compiler/scc.h>
#include <google/protobuf/compiler/js/well_known_types_embed.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/descriptor.h>


namespace google {
namespace protobuf {
namespace compiler {
namespace js {

// Sorted list of JavaScript keywords. These cannot be used as names. If they
// appear, we prefix them with "pb_".
const char* kKeyword[] = {
    "abstract",   "boolean",      "break",      "byte",    "case",
    "catch",      "char",         "class",      "const",   "continue",
    "debugger",   "default",      "delete",     "do",      "double",
    "else",       "enum",         "export",     "extends", "false",
    "final",      "finally",      "float",      "for",     "function",
    "goto",       "if",           "implements", "import",  "in",
    "instanceof", "int",          "interface",  "long",    "native",
    "new",        "null",         "package",    "private", "protected",
    "public",     "return",       "short",      "static",  "super",
    "switch",     "synchronized", "this",       "throw",   "throws",
    "transient",  "try",          "typeof",     "var",     "void",
    "volatile",   "while",        "with",
};

static const int kNumKeyword = sizeof(kKeyword) / sizeof(char*);

namespace {

// The mode of operation for bytes fields. Historically JSPB always carried
// bytes as JS {string}, containing base64 content by convention. With binary
// and proto3 serialization the new convention is to represent it as binary
// data in Uint8Array. See b/26173701 for background on the migration.
enum BytesMode {
  BYTES_DEFAULT,  // Default type for getBytesField to return.
  BYTES_B64,      // Explicitly coerce to base64 string where needed.
  BYTES_U8,       // Explicitly coerce to Uint8Array where needed.
};

bool IsReserved(const std::string& ident) {
  for (int i = 0; i < kNumKeyword; i++) {
    if (ident == kKeyword[i]) {
      return true;
    }
  }
  return false;
}

bool StrEndsWith(StringPiece sp, StringPiece x) {
  return sp.size() >= x.size() && sp.substr(sp.size() - x.size()) == x;
}

// Returns a copy of |filename| with any trailing ".protodevel" or ".proto
// suffix stripped.
// TODO(haberman): Unify with copy in compiler/cpp/internal/helpers.cc.
std::string StripProto(const std::string& filename) {
  const char* suffix =
      StrEndsWith(filename, ".protodevel") ? ".protodevel" : ".proto";
  return StripSuffixString(filename, suffix);
}

std::string GetSnakeFilename(const std::string& filename) {
  std::string snake_name = filename;
  ReplaceCharacters(&snake_name, "/", '_');
  return snake_name;
}

// Given a filename like foo/bar/baz.proto, returns the corresponding JavaScript
// file foo/bar/baz.js.
std::string GetJSFilename(const GeneratorOptions& options,
                          const std::string& filename) {
  return StripProto(filename) + options.GetFileNameExtension();
}

// Given a filename like foo/bar/baz.proto, returns the root directory
// path ../../
string GetRootPath(const std::string& from_filename,
                   const std::string& to_filename) {
  if (to_filename.find("google/protobuf") == 0) {
    // Well-known types (.proto files in the google/protobuf directory) are
    // assumed to come from the 'google-protobuf' npm package.  We may want to
    // generalize this exception later by letting others put generated code in
    // their own npm packages.
    return "google-protobuf/";
  }

  size_t slashes = std::count(from_filename.begin(), from_filename.end(), '/');
  if (slashes == 0) {
    return "./";
  }
  std::string result = "";
  for (size_t i = 0; i < slashes; i++) {
    result += "../";
  }
  return result;
}

// Returns the alias we assign to the module of the given .proto filename
// when importing.
std::string ModuleAlias(const std::string& filename) {
  // This scheme could technically cause problems if a file includes any 2 of:
  //   foo/bar_baz.proto
  //   foo_bar_baz.proto
  //   foo_bar/baz.proto
  //
  // We'll worry about this problem if/when we actually see it.  This name isn't
  // exposed to users so we can change it later if we need to.
  std::string basename = StripProto(filename);
  ReplaceCharacters(&basename, "-", '$');
  ReplaceCharacters(&basename, "/", '_');
  ReplaceCharacters(&basename, ".", '_');
  return basename + "_pb";
}

// Returns the fully normalized JavaScript namespace for the given
// file descriptor's package.
std::string GetNamespace(const GeneratorOptions& options,
                         const FileDescriptor* file) {
  if (!options.namespace_prefix.empty()) {
    return options.namespace_prefix;
  } else if (!file->package().empty()) {
    return "proto." + file->package();
  } else {
    return "proto";
  }
}

// Returns the name of the message with a leading dot and taking into account
// nesting, for example ".OuterMessage.InnerMessage", or returns empty if
// descriptor is null. This function does not handle namespacing, only message
// nesting.
std::string GetNestedMessageName(const Descriptor* descriptor) {
  if (descriptor == NULL) {
    return "";
  }
  std::string result = StripPrefixString(
      descriptor->full_name(), descriptor->file()->package());
  // Add a leading dot if one is not already present.
  if (!result.empty() && result[0] != '.') {
    result = "." + result;
  }
  return result;
}

// Returns the path prefix for a message or enumeration that
// lives under the given file and containing type.
std::string GetPrefix(const GeneratorOptions& options,
                      const FileDescriptor* file_descriptor,
                      const Descriptor* containing_type) {
  std::string prefix = GetNamespace(options, file_descriptor) +
                       GetNestedMessageName(containing_type);
  if (!prefix.empty()) {
    prefix += ".";
  }
  return prefix;
}

// Returns the fully normalized JavaScript path prefix for the given
// message descriptor.
std::string GetMessagePathPrefix(const GeneratorOptions& options,
                                 const Descriptor* descriptor) {
  return GetPrefix(options, descriptor->file(), descriptor->containing_type());
}

// Returns the fully normalized JavaScript path for the given
// message descriptor.
std::string GetMessagePath(const GeneratorOptions& options,
                           const Descriptor* descriptor) {
  return GetMessagePathPrefix(options, descriptor) + descriptor->name();
}

// Returns the fully normalized JavaScript path prefix for the given
// enumeration descriptor.
std::string GetEnumPathPrefix(const GeneratorOptions& options,
                              const EnumDescriptor* enum_descriptor) {
  return GetPrefix(options, enum_descriptor->file(),
                   enum_descriptor->containing_type());
}

// Returns the fully normalized JavaScript path for the given
// enumeration descriptor.
std::string GetEnumPath(const GeneratorOptions& options,
                        const EnumDescriptor* enum_descriptor) {
  return GetEnumPathPrefix(options, enum_descriptor) + enum_descriptor->name();
}

std::string MaybeCrossFileRef(const GeneratorOptions& options,
                              const FileDescriptor* from_file,
                              const Descriptor* to_message) {
  if ((options.import_style == GeneratorOptions::kImportCommonJs ||
       options.import_style == GeneratorOptions::kImportCommonJsStrict) &&
      from_file != to_message->file()) {
    // Cross-file ref in CommonJS needs to use the module alias instead of
    // the global name.
    return ModuleAlias(to_message->file()->name()) +
           GetNestedMessageName(to_message->containing_type()) + "." +
           to_message->name();
  } else {
    // Within a single file we use a full name.
    return GetMessagePath(options, to_message);
  }
}

std::string SubmessageTypeRef(const GeneratorOptions& options,
                              const FieldDescriptor* field) {
  GOOGLE_CHECK(field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE);
  return MaybeCrossFileRef(options, field->file(), field->message_type());
}

// - Object field name: LOWER_UNDERSCORE -> LOWER_CAMEL, except for group fields
// (UPPER_CAMEL -> LOWER_CAMEL), with "List" (or "Map") appended if appropriate,
// and with reserved words triggering a "pb_" prefix.
// - Getters/setters: LOWER_UNDERSCORE -> UPPER_CAMEL, except for group fields
// (use the name directly), then append "List" if appropriate, then append "$"
// if resulting name is equal to a reserved word.
// - Enums: just uppercase.

// Locale-independent version of ToLower that deals only with ASCII A-Z.
char ToLowerASCII(char c) {
  if (c >= 'A' && c <= 'Z') {
    return (c - 'A') + 'a';
  } else {
    return c;
  }
}

std::vector<std::string> ParseLowerUnderscore(const std::string& input) {
  std::vector<std::string> words;
  std::string running = "";
  for (int i = 0; i < input.size(); i++) {
    if (input[i] == '_') {
      if (!running.empty()) {
        words.push_back(running);
        running.clear();
      }
    } else {
      running += ToLowerASCII(input[i]);
    }
  }
  if (!running.empty()) {
    words.push_back(running);
  }
  return words;
}

std::vector<std::string> ParseUpperCamel(const std::string& input) {
  std::vector<std::string> words;
  std::string running = "";
  for (int i = 0; i < input.size(); i++) {
    if (input[i] >= 'A' && input[i] <= 'Z' && !running.empty()) {
      words.push_back(running);
      running.clear();
    }
    running += ToLowerASCII(input[i]);
  }
  if (!running.empty()) {
    words.push_back(running);
  }
  return words;
}

std::string ToLowerCamel(const std::vector<std::string>& words) {
  std::string result;
  for (int i = 0; i < words.size(); i++) {
    std::string word = words[i];
    if (i == 0 && (word[0] >= 'A' && word[0] <= 'Z')) {
      word[0] = (word[0] - 'A') + 'a';
    } else if (i != 0 && (word[0] >= 'a' && word[0] <= 'z')) {
      word[0] = (word[0] - 'a') + 'A';
    }
    result += word;
  }
  return result;
}

std::string ToUpperCamel(const std::vector<std::string>& words) {
  std::string result;
  for (int i = 0; i < words.size(); i++) {
    std::string word = words[i];
    if (word[0] >= 'a' && word[0] <= 'z') {
      word[0] = (word[0] - 'a') + 'A';
    }
    result += word;
  }
  return result;
}

// Based on code from descriptor.cc (Thanks Kenton!)
// Uppercases the entire string, turning ValueName into
// VALUENAME.
std::string ToEnumCase(const std::string& input) {
  std::string result;
  result.reserve(input.size());

  for (int i = 0; i < input.size(); i++) {
    if ('a' <= input[i] && input[i] <= 'z') {
      result.push_back(input[i] - 'a' + 'A');
    } else {
      result.push_back(input[i]);
    }
  }

  return result;
}

std::string ToLower(const std::string& input) {
  std::string result;
  result.reserve(input.size());

  for (int i = 0; i < input.size(); i++) {
    if ('A' <= input[i] && input[i] <= 'Z') {
      result.push_back(input[i] - 'A' + 'a');
    } else {
      result.push_back(input[i]);
    }
  }

  return result;
}

// When we're generating one output file per SCC, this is the filename
// that top-level extensions should go in.
// e.g. one proto file (test.proto):
// package a;
// extends Foo {
//   ...
// }
// If "with_filename" equals true, the extension filename will be
// "proto.a_test_extensions.js", otherwise will be "proto.a.js"
std::string GetExtensionFileName(const GeneratorOptions& options,
                                 const FileDescriptor* file,
                                 bool with_filename) {
  std::string snake_name = StripProto(GetSnakeFilename(file->name()));
  return options.output_dir + "/" + ToLower(GetNamespace(options, file)) +
         (with_filename ? ("_" + snake_name + "_extensions") : "") +
         options.GetFileNameExtension();
}
// When we're generating one output file per SCC, this is the filename
// that all messages in the SCC should go in.
// If with_package equals true, filename will have package prefix,
// If the filename length is longer than 200, the filename will be the
// SCC's proto filename with suffix "_long_sccs_(index)" (if with_package equals
// true it still has package prefix)
std::string GetMessagesFileName(const GeneratorOptions& options, const SCC* scc,
                                bool with_package) {
  static std::map<const Descriptor*, std::string>* long_name_dict =
      new std::map<const Descriptor*, std::string>();
  std::string package_base =
      with_package
          ? ToLower(GetNamespace(options, scc->GetRepresentative()->file()) +
                    "_")
          : "";
  std::string filename_base = "";
  std::vector<std::string> all_message_names;
  for (auto one_desc : scc->descriptors) {
    if (one_desc->containing_type() == nullptr) {
      all_message_names.push_back(ToLower(one_desc->name()));
    }
  }
  sort(all_message_names.begin(), all_message_names.end());
  for (auto one_message : all_message_names) {
    if (!filename_base.empty()) {
      filename_base += "_";
    }
    filename_base += one_message;
  }
  if (filename_base.size() + package_base.size() > 200) {
    if ((*long_name_dict).find(scc->GetRepresentative()) ==
        (*long_name_dict).end()) {
      std::string snake_name = StripProto(
          GetSnakeFilename(scc->GetRepresentative()->file()->name()));
      (*long_name_dict)[scc->GetRepresentative()] =
          StrCat(snake_name, "_long_sccs_",
                       static_cast<uint64>((*long_name_dict).size()));
    }
    filename_base = (*long_name_dict)[scc->GetRepresentative()];
  }
  return options.output_dir + "/" + package_base + filename_base +
         options.GetFileNameExtension();
}

// When we're generating one output file per type name, this is the filename
// that a top-level enum should go in.
// If with_package equals true, filename will have package prefix.
std::string GetEnumFileName(const GeneratorOptions& options,
                            const EnumDescriptor* desc, bool with_package) {
  return options.output_dir + "/" +
         (with_package ? ToLower(GetNamespace(options, desc->file()) + "_")
                       : "") +
         ToLower(desc->name()) + options.GetFileNameExtension();
}

// Returns the message/response ID, if set.
std::string GetMessageId(const Descriptor* desc) {
  return std::string();
}

bool IgnoreExtensionField(const FieldDescriptor* field) {
  // Exclude descriptor extensions from output "to avoid clutter" (from original
  // codegen).
  if (!field->is_extension()) return false;
  const FileDescriptor* file = field->containing_type()->file();
  return file->name() == "net/proto2/proto/descriptor.proto" ||
         file->name() == "google/protobuf/descriptor.proto";
}


// Used inside Google only -- do not remove.
bool IsResponse(const Descriptor* desc) { return false; }

bool IgnoreField(const FieldDescriptor* field) {
  return IgnoreExtensionField(field);
}


// Do we ignore this message type?
bool IgnoreMessage(const Descriptor* d) { return d->options().map_entry(); }

// Does JSPB ignore this entire oneof? True only if all fields are ignored.
bool IgnoreOneof(const OneofDescriptor* oneof) {
  for (int i = 0; i < oneof->field_count(); i++) {
    if (!IgnoreField(oneof->field(i))) {
      return false;
    }
  }
  return true;
}

std::string JSIdent(const GeneratorOptions& options,
                    const FieldDescriptor* field, bool is_upper_camel,
                    bool is_map, bool drop_list) {
  std::string result;
  if (field->type() == FieldDescriptor::TYPE_GROUP) {
    result = is_upper_camel
                 ? ToUpperCamel(ParseUpperCamel(field->message_type()->name()))
                 : ToLowerCamel(ParseUpperCamel(field->message_type()->name()));
  } else {
    result = is_upper_camel ? ToUpperCamel(ParseLowerUnderscore(field->name()))
                            : ToLowerCamel(ParseLowerUnderscore(field->name()));
  }
  if (is_map || field->is_map()) {
    // JSPB-style or proto3-style map.
    result += "Map";
  } else if (!drop_list && field->is_repeated()) {
    // Repeated field.
    result += "List";
  }
  return result;
}

std::string JSObjectFieldName(const GeneratorOptions& options,
                              const FieldDescriptor* field) {
  std::string name = JSIdent(options, field,
                             /* is_upper_camel = */ false,
                             /* is_map = */ false,
                             /* drop_list = */ false);
  if (IsReserved(name)) {
    name = "pb_" + name;
  }
  return name;
}

std::string JSByteGetterSuffix(BytesMode bytes_mode) {
  switch (bytes_mode) {
    case BYTES_DEFAULT:
      return "";
    case BYTES_B64:
      return "B64";
    case BYTES_U8:
      return "U8";
    default:
      assert(false);
  }
  return "";
}

// Returns the field name as a capitalized portion of a getter/setter method
// name, e.g. MyField for .getMyField().
std::string JSGetterName(const GeneratorOptions& options,
                         const FieldDescriptor* field,
                         BytesMode bytes_mode = BYTES_DEFAULT,
                         bool drop_list = false) {
  std::string name = JSIdent(options, field,
                             /* is_upper_camel = */ true,
                             /* is_map = */ false, drop_list);
  if (field->type() == FieldDescriptor::TYPE_BYTES) {
    std::string suffix = JSByteGetterSuffix(bytes_mode);
    if (!suffix.empty()) {
      name += "_as" + suffix;
    }
  }
  if (name == "Extension" || name == "JsPbMessageId") {
    // Avoid conflicts with base-class names.
    name += "$";
  }
  return name;
}


std::string JSOneofName(const OneofDescriptor* oneof) {
  return ToUpperCamel(ParseLowerUnderscore(oneof->name()));
}

// Returns the index corresponding to this field in the JSPB array (underlying
// data storage array).
std::string JSFieldIndex(const FieldDescriptor* field) {
  // Determine whether this field is a member of a group. Group fields are a bit
  // wonky: their "containing type" is a message type created just for the
  // group, and that type's parent type has a field with the group-message type
  // as its message type and TYPE_GROUP as its field type. For such fields, the
  // index we use is relative to the field number of the group submessage field.
  // For all other fields, we just use the field number.
  const Descriptor* containing_type = field->containing_type();
  const Descriptor* parent_type = containing_type->containing_type();
  if (parent_type != NULL) {
    for (int i = 0; i < parent_type->field_count(); i++) {
      if (parent_type->field(i)->type() == FieldDescriptor::TYPE_GROUP &&
          parent_type->field(i)->message_type() == containing_type) {
        return StrCat(field->number() - parent_type->field(i)->number());
      }
    }
  }
  return StrCat(field->number());
}

std::string JSOneofIndex(const OneofDescriptor* oneof) {
  int index = -1;
  for (int i = 0; i < oneof->containing_type()->oneof_decl_count(); i++) {
    const OneofDescriptor* o = oneof->containing_type()->oneof_decl(i);
    // If at least one field in this oneof is not JSPB-ignored, count the oneof.
    for (int j = 0; j < o->field_count(); j++) {
      const FieldDescriptor* f = o->field(j);
      if (!IgnoreField(f)) {
        index++;
        break;  // inner loop
      }
    }
    if (o == oneof) {
      break;
    }
  }
  return StrCat(index);
}

// Decodes a codepoint in \x0000 -- \xFFFF.
uint16 DecodeUTF8Codepoint(uint8* bytes, size_t* length) {
  if (*length == 0) {
    return 0;
  }
  size_t expected = 0;
  if ((*bytes & 0x80) == 0) {
    expected = 1;
  } else if ((*bytes & 0xe0) == 0xc0) {
    expected = 2;
  } else if ((*bytes & 0xf0) == 0xe0) {
    expected = 3;
  } else {
    // Too long -- don't accept.
    *length = 0;
    return 0;
  }

  if (*length < expected) {
    // Not enough bytes -- don't accept.
    *length = 0;
    return 0;
  }

  *length = expected;
  switch (expected) {
    case 1:
      return bytes[0];
    case 2:
      return ((bytes[0] & 0x1F) << 6) | ((bytes[1] & 0x3F) << 0);
    case 3:
      return ((bytes[0] & 0x0F) << 12) | ((bytes[1] & 0x3F) << 6) |
             ((bytes[2] & 0x3F) << 0);
    default:
      return 0;
  }
}

// Escapes the contents of a string to be included within double-quotes ("") in
// JavaScript. The input data should be a UTF-8 encoded C++ string of chars.
// Returns false if |out| was truncated because |in| contained invalid UTF-8 or
// codepoints outside the BMP.
// TODO(b/115551870): Support codepoints outside the BMP.
bool EscapeJSString(const std::string& in, std::string* out) {
  size_t decoded = 0;
  for (size_t i = 0; i < in.size(); i += decoded) {
    uint16 codepoint = 0;
    // Decode the next UTF-8 codepoint.
    size_t have_bytes = in.size() - i;
    uint8 bytes[3] = {
        static_cast<uint8>(in[i]),
        static_cast<uint8>(((i + 1) < in.size()) ? in[i + 1] : 0),
        static_cast<uint8>(((i + 2) < in.size()) ? in[i + 2] : 0),
    };
    codepoint = DecodeUTF8Codepoint(bytes, &have_bytes);
    if (have_bytes == 0) {
      return false;
    }
    decoded = have_bytes;

    switch (codepoint) {
      case '\'':
        *out += "\\x27";
        break;
      case '"':
        *out += "\\x22";
        break;
      case '<':
        *out += "\\x3c";
        break;
      case '=':
        *out += "\\x3d";
        break;
      case '>':
        *out += "\\x3e";
        break;
      case '&':
        *out += "\\x26";
        break;
      case '\b':
        *out += "\\b";
        break;
      case '\t':
        *out += "\\t";
        break;
      case '\n':
        *out += "\\n";
        break;
      case '\f':
        *out += "\\f";
        break;
      case '\r':
        *out += "\\r";
        break;
      case '\\':
        *out += "\\\\";
        break;
      default:
        // TODO(b/115551870): Once we're supporting codepoints outside the BMP,
        // use a single Unicode codepoint escape if the output language is
        // ECMAScript 2015 or above. Otherwise, use a surrogate pair.
        // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#String_literals
        if (codepoint >= 0x20 && codepoint <= 0x7e) {
          *out += static_cast<char>(codepoint);
        } else if (codepoint >= 0x100) {
          *out += StringPrintf("\\u%04x", codepoint);
        } else {
          *out += StringPrintf("\\x%02x", codepoint);
        }
        break;
    }
  }
  return true;
}

std::string EscapeBase64(const std::string& in) {
  static const char* kAlphabet =
      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  std::string result;

  for (size_t i = 0; i < in.size(); i += 3) {
    int value = (in[i] << 16) | (((i + 1) < in.size()) ? (in[i + 1] << 8) : 0) |
                (((i + 2) < in.size()) ? (in[i + 2] << 0) : 0);
    result += kAlphabet[(value >> 18) & 0x3f];
    result += kAlphabet[(value >> 12) & 0x3f];
    if ((i + 1) < in.size()) {
      result += kAlphabet[(value >> 6) & 0x3f];
    } else {
      result += '=';
    }
    if ((i + 2) < in.size()) {
      result += kAlphabet[(value >> 0) & 0x3f];
    } else {
      result += '=';
    }
  }

  return result;
}

// Post-process the result of SimpleFtoa/SimpleDtoa to *exactly* match the
// original codegen's formatting (which is just .toString() on java.lang.Double
// or java.lang.Float).
std::string PostProcessFloat(std::string result) {
  // If inf, -inf or nan, replace with +Infinity, -Infinity or NaN.
  if (result == "inf") {
    return "Infinity";
  } else if (result == "-inf") {
    return "-Infinity";
  } else if (result == "nan") {
    return "NaN";
  }

  // If scientific notation (e.g., "1e10"), (i) capitalize the "e", (ii)
  // ensure that the mantissa (portion prior to the "e") has at least one
  // fractional digit (after the decimal point), and (iii) strip any unnecessary
  // leading zeroes and/or '+' signs from the exponent.
  std::string::size_type exp_pos = result.find('e');
  if (exp_pos != std::string::npos) {
    std::string mantissa = result.substr(0, exp_pos);
    std::string exponent = result.substr(exp_pos + 1);

    // Add ".0" to mantissa if no fractional part exists.
    if (mantissa.find('.') == std::string::npos) {
      mantissa += ".0";
    }

    // Strip the sign off the exponent and store as |exp_neg|.
    bool exp_neg = false;
    if (!exponent.empty() && exponent[0] == '+') {
      exponent = exponent.substr(1);
    } else if (!exponent.empty() && exponent[0] == '-') {
      exp_neg = true;
      exponent = exponent.substr(1);
    }

    // Strip any leading zeroes off the exponent.
    while (exponent.size() > 1 && exponent[0] == '0') {
      exponent = exponent.substr(1);
    }

    return mantissa + "E" + string(exp_neg ? "-" : "") + exponent;
  }

  // Otherwise, this is an ordinary decimal number. Append ".0" if result has no
  // decimal/fractional part in order to match output of original codegen.
  if (result.find('.') == std::string::npos) {
    result += ".0";
  }

  return result;
}

std::string FloatToString(float value) {
  std::string result = SimpleFtoa(value);
  return PostProcessFloat(result);
}

std::string DoubleToString(double value) {
  std::string result = SimpleDtoa(value);
  return PostProcessFloat(result);
}

// Return true if this is an integral field that should be represented as string
// in JS.
bool IsIntegralFieldWithStringJSType(const FieldDescriptor* field) {
  switch (field->cpp_type()) {
    case FieldDescriptor::CPPTYPE_INT64:
    case FieldDescriptor::CPPTYPE_UINT64:
      // The default value of JSType is JS_NORMAL, which behaves the same as
      // JS_NUMBER.
      return field->options().jstype() == FieldOptions::JS_STRING;
    default:
      return false;
  }
}

std::string MaybeNumberString(const FieldDescriptor* field,
                              const std::string& orig) {
  return IsIntegralFieldWithStringJSType(field) ? ("\"" + orig + "\"") : orig;
}

std::string JSFieldDefault(const FieldDescriptor* field) {
  if (field->is_repeated()) {
    return "[]";
  }

  switch (field->cpp_type()) {
    case FieldDescriptor::CPPTYPE_INT32:
      return MaybeNumberString(field,
                               StrCat(field->default_value_int32()));
    case FieldDescriptor::CPPTYPE_UINT32:
      // The original codegen is in Java, and Java protobufs store unsigned
      // integer values as signed integer values. In order to exactly match the
      // output, we need to reinterpret as base-2 signed. Ugh.
      return MaybeNumberString(
          field,
          StrCat(static_cast<int32>(field->default_value_uint32())));
    case FieldDescriptor::CPPTYPE_INT64:
      return MaybeNumberString(field,
                               StrCat(field->default_value_int64()));
    case FieldDescriptor::CPPTYPE_UINT64:
      // See above note for uint32 -- reinterpreting as signed.
      return MaybeNumberString(
          field,
          StrCat(static_cast<int64>(field->default_value_uint64())));
    case FieldDescriptor::CPPTYPE_ENUM:
      return StrCat(field->default_value_enum()->number());
    case FieldDescriptor::CPPTYPE_BOOL:
      return field->default_value_bool() ? "true" : "false";
    case FieldDescriptor::CPPTYPE_FLOAT:
      return FloatToString(field->default_value_float());
    case FieldDescriptor::CPPTYPE_DOUBLE:
      return DoubleToString(field->default_value_double());
    case FieldDescriptor::CPPTYPE_STRING:
      if (field->type() == FieldDescriptor::TYPE_STRING) {
        std::string out;
        bool is_valid = EscapeJSString(field->default_value_string(), &out);
        if (!is_valid) {
          // TODO(b/115551870): Decide whether this should be a hard error.
          GOOGLE_LOG(WARNING) << "The default value for field " << field->full_name()
                       << " was truncated since it contained invalid UTF-8 or"
                          " codepoints outside the basic multilingual plane.";
        }
        return "\"" + out + "\"";
      } else {  // Bytes
        return "\"" + EscapeBase64(field->default_value_string()) + "\"";
      }
    case FieldDescriptor::CPPTYPE_MESSAGE:
      return "null";
  }
  GOOGLE_LOG(FATAL) << "Shouldn't reach here.";
  return "";
}

std::string ProtoTypeName(const GeneratorOptions& options,
                          const FieldDescriptor* field) {
  switch (field->type()) {
    case FieldDescriptor::TYPE_BOOL:
      return "bool";
    case FieldDescriptor::TYPE_INT32:
      return "int32";
    case FieldDescriptor::TYPE_UINT32:
      return "uint32";
    case FieldDescriptor::TYPE_SINT32:
      return "sint32";
    case FieldDescriptor::TYPE_FIXED32:
      return "fixed32";
    case FieldDescriptor::TYPE_SFIXED32:
      return "sfixed32";
    case FieldDescriptor::TYPE_INT64:
      return "int64";
    case FieldDescriptor::TYPE_UINT64:
      return "uint64";
    case FieldDescriptor::TYPE_SINT64:
      return "sint64";
    case FieldDescriptor::TYPE_FIXED64:
      return "fixed64";
    case FieldDescriptor::TYPE_SFIXED64:
      return "sfixed64";
    case FieldDescriptor::TYPE_FLOAT:
      return "float";
    case FieldDescriptor::TYPE_DOUBLE:
      return "double";
    case FieldDescriptor::TYPE_STRING:
      return "string";
    case FieldDescriptor::TYPE_BYTES:
      return "bytes";
    case FieldDescriptor::TYPE_GROUP:
      return GetMessagePath(options, field->message_type());
    case FieldDescriptor::TYPE_ENUM:
      return GetEnumPath(options, field->enum_type());
    case FieldDescriptor::TYPE_MESSAGE:
      return GetMessagePath(options, field->message_type());
    default:
      return "";
  }
}

std::string JSIntegerTypeName(const FieldDescriptor* field) {
  return IsIntegralFieldWithStringJSType(field) ? "string" : "number";
}

std::string JSStringTypeName(const GeneratorOptions& options,
                             const FieldDescriptor* field,
                             BytesMode bytes_mode) {
  if (field->type() == FieldDescriptor::TYPE_BYTES) {
    switch (bytes_mode) {
      case BYTES_DEFAULT:
        return "(string|Uint8Array)";
      case BYTES_B64:
        return "string";
      case BYTES_U8:
        return "Uint8Array";
      default:
        assert(false);
    }
  }
  return "string";
}

std::string JSTypeName(const GeneratorOptions& options,
                       const FieldDescriptor* field, BytesMode bytes_mode) {
  switch (field->cpp_type()) {
    case FieldDescriptor::CPPTYPE_BOOL:
      return "boolean";
    case FieldDescriptor::CPPTYPE_INT32:
      return JSIntegerTypeName(field);
    case FieldDescriptor::CPPTYPE_INT64:
      return JSIntegerTypeName(field);
    case FieldDescriptor::CPPTYPE_UINT32:
      return JSIntegerTypeName(field);
    case FieldDescriptor::CPPTYPE_UINT64:
      return JSIntegerTypeName(field);
    case FieldDescriptor::CPPTYPE_FLOAT:
      return "number";
    case FieldDescriptor::CPPTYPE_DOUBLE:
      return "number";
    case FieldDescriptor::CPPTYPE_STRING:
      return JSStringTypeName(options, field, bytes_mode);
    case FieldDescriptor::CPPTYPE_ENUM:
      return GetEnumPath(options, field->enum_type());
    case FieldDescriptor::CPPTYPE_MESSAGE:
      return GetMessagePath(options, field->message_type());
    default:
      return "";
  }
}

// Used inside Google only -- do not remove.
bool UseBrokenPresenceSemantics(const GeneratorOptions& options,
                                const FieldDescriptor* field) {
  return false;
}

// Returns true for fields that return "null" from accessors when they are
// unset. This should normally only be true for non-repeated submessages, but we
// have legacy users who relied on old behavior where accessors behaved this
// way.
bool ReturnsNullWhenUnset(const GeneratorOptions& options,
                          const FieldDescriptor* field) {
  if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
      field->is_optional()) {
    return true;
  }

  // TODO(haberman): remove this case and unconditionally return false.
  return UseBrokenPresenceSemantics(options, field) && !field->is_repeated() &&
         !field->has_default_value();
}

// In a sane world, this would be the same as ReturnsNullWhenUnset().  But in
// the status quo, some fields declare that they never return null/undefined
// even though they actually do:
//   * required fields
//   * optional enum fields
//   * proto3 primitive fields.
bool DeclaredReturnTypeIsNullable(const GeneratorOptions& options,
                                  const FieldDescriptor* field) {
  if (field->is_required() || field->type() == FieldDescriptor::TYPE_ENUM) {
    return false;
  }

  if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 &&
      field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
    return false;
  }

  return ReturnsNullWhenUnset(options, field);
}

bool SetterAcceptsUndefined(const GeneratorOptions& options,
                            const FieldDescriptor* field) {
  if (ReturnsNullWhenUnset(options, field)) {
    return true;
  }

  // Broken presence semantics always accepts undefined for setters.
  return UseBrokenPresenceSemantics(options, field);
}

bool SetterAcceptsNull(const GeneratorOptions& options,
                       const FieldDescriptor* field) {
  if (ReturnsNullWhenUnset(options, field)) {
    return true;
  }

  // With broken presence semantics, fields with defaults accept "null" for
  // setters, but other fields do not.  This is a strange quirk of the old
  // codegen.
  return UseBrokenPresenceSemantics(options, field) &&
         field->has_default_value();
}

// Returns types which are known to by non-nullable by default.
// The style guide requires that we omit "!" in this case.
bool IsPrimitive(const std::string& type) {
  return type == "undefined" || type == "string" || type == "number" ||
         type == "boolean";
}

std::string JSFieldTypeAnnotation(const GeneratorOptions& options,
                                  const FieldDescriptor* field,
                                  bool is_setter_argument, bool force_present,
                                  bool singular_if_not_packed,
                                  BytesMode bytes_mode = BYTES_DEFAULT,
                                  bool force_singular = false) {
  std::string jstype = JSTypeName(options, field, bytes_mode);

  if (!force_singular && field->is_repeated() &&
      (field->is_packed() || !singular_if_not_packed)) {
    if (field->type() == FieldDescriptor::TYPE_BYTES &&
        bytes_mode == BYTES_DEFAULT) {
      jstype = "(Array<!Uint8Array>|Array<string>)";
    } else {
      if (!IsPrimitive(jstype)) {
        jstype = "!" + jstype;
      }
      jstype = "Array<" + jstype + ">";
    }
  }

  bool is_null_or_undefined = false;

  if (is_setter_argument) {
    if (SetterAcceptsNull(options, field)) {
      jstype = "?" + jstype;
      is_null_or_undefined = true;
    }

    if (SetterAcceptsUndefined(options, field)) {
      jstype += "|undefined";
      is_null_or_undefined = true;
    }
  } else if (force_present) {
    // Don't add null or undefined.
  } else {
    if (DeclaredReturnTypeIsNullable(options, field)) {
      jstype = "?" + jstype;
      is_null_or_undefined = true;
    }
  }

  if (!is_null_or_undefined && !IsPrimitive(jstype)) {
    jstype = "!" + jstype;
  }

  return jstype;
}

std::string JSBinaryReaderMethodType(const FieldDescriptor* field) {
  std::string name = field->type_name();
  if (name[0] >= 'a' && name[0] <= 'z') {
    name[0] = (name[0] - 'a') + 'A';
  }
  return IsIntegralFieldWithStringJSType(field) ? (name + "String") : name;
}

std::string JSBinaryReadWriteMethodName(const FieldDescriptor* field,
                                        bool is_writer) {
  std::string name = JSBinaryReaderMethodType(field);
  if (field->is_packed()) {
    name = "Packed" + name;
  } else if (is_writer && field->is_repeated()) {
    name = "Repeated" + name;
  }
  return name;
}

std::string JSBinaryReaderMethodName(const GeneratorOptions& options,
                                     const FieldDescriptor* field) {
  return "jspb.BinaryReader.prototype.read" +
         JSBinaryReadWriteMethodName(field, /* is_writer = */ false);
}

std::string JSBinaryWriterMethodName(const GeneratorOptions& options,
                                     const FieldDescriptor* field) {
  if (field->containing_type() &&
      field->containing_type()->options().message_set_wire_format()) {
    return "jspb.BinaryWriter.prototype.writeMessageSet";
  }
  return "jspb.BinaryWriter.prototype.write" +
         JSBinaryReadWriteMethodName(field, /* is_writer = */ true);
}

std::string JSReturnClause(const FieldDescriptor* desc) {
  return "";
}

std::string JSTypeTag(const FieldDescriptor* desc) {
  switch (desc->type()) {
    case FieldDescriptor::TYPE_DOUBLE:
    case FieldDescriptor::TYPE_FLOAT:
      return "Float";
    case FieldDescriptor::TYPE_INT32:
    case FieldDescriptor::TYPE_UINT32:
    case FieldDescriptor::TYPE_INT64:
    case FieldDescriptor::TYPE_UINT64:
    case FieldDescriptor::TYPE_FIXED32:
    case FieldDescriptor::TYPE_FIXED64:
    case FieldDescriptor::TYPE_SINT32:
    case FieldDescriptor::TYPE_SINT64:
    case FieldDescriptor::TYPE_SFIXED32:
    case FieldDescriptor::TYPE_SFIXED64:
      if (IsIntegralFieldWithStringJSType(desc)) {
        return "StringInt";
      } else {
        return "Int";
      }
    case FieldDescriptor::TYPE_BOOL:
      return "Boolean";
    case FieldDescriptor::TYPE_STRING:
      return "String";
    case FieldDescriptor::TYPE_BYTES:
      return "Bytes";
    case FieldDescriptor::TYPE_ENUM:
      return "Enum";
    default:
      assert(false);
  }
  return "";
}

std::string JSReturnDoc(const GeneratorOptions& options,
                        const FieldDescriptor* desc) {
  return "";
}

bool HasRepeatedFields(const GeneratorOptions& options,
                       const Descriptor* desc) {
  for (int i = 0; i < desc->field_count(); i++) {
    if (desc->field(i)->is_repeated() && !desc->field(i)->is_map()) {
      return true;
    }
  }
  return false;
}

static const char* kRepeatedFieldArrayName = ".repeatedFields_";

std::string RepeatedFieldsArrayName(const GeneratorOptions& options,
                                    const Descriptor* desc) {
  return HasRepeatedFields(options, desc)
             ? (GetMessagePath(options, desc) + kRepeatedFieldArrayName)
             : "null";
}

bool HasOneofFields(const Descriptor* desc) {
  for (int i = 0; i < desc->field_count(); i++) {
    if (desc->field(i)->containing_oneof()) {
      return true;
    }
  }
  return false;
}

static const char* kOneofGroupArrayName = ".oneofGroups_";

std::string OneofFieldsArrayName(const GeneratorOptions& options,
                                 const Descriptor* desc) {
  return HasOneofFields(desc)
             ? (GetMessagePath(options, desc) + kOneofGroupArrayName)
             : "null";
}

std::string RepeatedFieldNumberList(const GeneratorOptions& options,
                                    const Descriptor* desc) {
  std::vector<std::string> numbers;
  for (int i = 0; i < desc->field_count(); i++) {
    if (desc->field(i)->is_repeated() && !desc->field(i)->is_map()) {
      numbers.push_back(JSFieldIndex(desc->field(i)));
    }
  }
  return "[" + Join(numbers, ",") + "]";
}

std::string OneofGroupList(const Descriptor* desc) {
  // List of arrays (one per oneof), each of which is a list of field indices
  std::vector<std::string> oneof_entries;
  for (int i = 0; i < desc->oneof_decl_count(); i++) {
    const OneofDescriptor* oneof = desc->oneof_decl(i);
    if (IgnoreOneof(oneof)) {
      continue;
    }

    std::vector<std::string> oneof_fields;
    for (int j = 0; j < oneof->field_count(); j++) {
      if (IgnoreField(oneof->field(j))) {
        continue;
      }
      oneof_fields.push_back(JSFieldIndex(oneof->field(j)));
    }
    oneof_entries.push_back("[" + Join(oneof_fields, ",") + "]");
  }
  return "[" + Join(oneof_entries, ",") + "]";
}

std::string JSOneofArray(const GeneratorOptions& options,
                         const FieldDescriptor* field) {
  return OneofFieldsArrayName(options, field->containing_type()) + "[" +
         JSOneofIndex(field->containing_oneof()) + "]";
}

std::string RelativeTypeName(const FieldDescriptor* field) {
  assert(field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM ||
         field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE);
  // For a field with an enum or message type, compute a name relative to the
  // path name of the message type containing this field.
  std::string package = field->file()->package();
  std::string containing_type = field->containing_type()->full_name() + ".";
  std::string type = (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM)
                         ? field->enum_type()->full_name()
                         : field->message_type()->full_name();

  // |prefix| is advanced as we find separators '.' past the common package
  // prefix that yield common prefixes in the containing type's name and this
  // type's name.
  int prefix = 0;
  for (int i = 0; i < type.size() && i < containing_type.size(); i++) {
    if (type[i] != containing_type[i]) {
      break;
    }
    if (type[i] == '.' && i >= package.size()) {
      prefix = i + 1;
    }
  }

  return type.substr(prefix);
}

std::string JSExtensionsObjectName(const GeneratorOptions& options,
                                   const FileDescriptor* from_file,
                                   const Descriptor* desc) {
  if (desc->full_name() == "google.protobuf.bridge.MessageSet") {
    // TODO(haberman): fix this for the kImportCommonJs case.
    return "jspb.Message.messageSetExtensions";
  } else {
    return MaybeCrossFileRef(options, from_file, desc) + ".extensions";
  }
}

static const int kMapKeyField = 1;
static const int kMapValueField = 2;

const FieldDescriptor* MapFieldKey(const FieldDescriptor* field) {
  assert(field->is_map());
  return field->message_type()->FindFieldByNumber(kMapKeyField);
}

const FieldDescriptor* MapFieldValue(const FieldDescriptor* field) {
  assert(field->is_map());
  return field->message_type()->FindFieldByNumber(kMapValueField);
}

std::string FieldDefinition(const GeneratorOptions& options,
                            const FieldDescriptor* field) {
  if (field->is_map()) {
    const FieldDescriptor* key_field = MapFieldKey(field);
    const FieldDescriptor* value_field = MapFieldValue(field);
    std::string key_type = ProtoTypeName(options, key_field);
    std::string value_type;
    if (value_field->type() == FieldDescriptor::TYPE_ENUM ||
        value_field->type() == FieldDescriptor::TYPE_MESSAGE) {
      value_type = RelativeTypeName(value_field);
    } else {
      value_type = ProtoTypeName(options, value_field);
    }
    return StringPrintf("map<%s, %s> %s = %d;", key_type.c_str(),
                        value_type.c_str(), field->name().c_str(),
                        field->number());
  } else {
    std::string qualifier =
        field->is_repeated() ? "repeated"
                             : (field->is_optional() ? "optional" : "required");
    std::string type, name;
    if (field->type() == FieldDescriptor::TYPE_ENUM ||
        field->type() == FieldDescriptor::TYPE_MESSAGE) {
      type = RelativeTypeName(field);
      name = field->name();
    } else if (field->type() == FieldDescriptor::TYPE_GROUP) {
      type = "group";
      name = field->message_type()->name();
    } else {
      type = ProtoTypeName(options, field);
      name = field->name();
    }
    return StringPrintf("%s %s %s = %d;", qualifier.c_str(), type.c_str(),
                        name.c_str(), field->number());
  }
}

std::string FieldComments(const FieldDescriptor* field, BytesMode bytes_mode) {
  std::string comments;
  if (field->type() == FieldDescriptor::TYPE_BYTES && bytes_mode == BYTES_U8) {
    comments +=
        " * Note that Uint8Array is not supported on all browsers.\n"
        " * @see http://caniuse.com/Uint8Array\n";
  }
  return comments;
}

bool ShouldGenerateExtension(const FieldDescriptor* field) {
  return field->is_extension() && !IgnoreField(field);
}

bool HasExtensions(const Descriptor* desc) {
  for (int i = 0; i < desc->extension_count(); i++) {
    if (ShouldGenerateExtension(desc->extension(i))) {
      return true;
    }
  }
  for (int i = 0; i < desc->nested_type_count(); i++) {
    if (HasExtensions(desc->nested_type(i))) {
      return true;
    }
  }
  return false;
}

bool HasExtensions(const FileDescriptor* file) {
  for (int i = 0; i < file->extension_count(); i++) {
    if (ShouldGenerateExtension(file->extension(i))) {
      return true;
    }
  }
  for (int i = 0; i < file->message_type_count(); i++) {
    if (HasExtensions(file->message_type(i))) {
      return true;
    }
  }
  return false;
}

bool HasMap(const GeneratorOptions& options, const Descriptor* desc) {
  for (int i = 0; i < desc->field_count(); i++) {
    if (desc->field(i)->is_map()) {
      return true;
    }
  }
  for (int i = 0; i < desc->nested_type_count(); i++) {
    if (HasMap(options, desc->nested_type(i))) {
      return true;
    }
  }
  return false;
}

bool FileHasMap(const GeneratorOptions& options, const FileDescriptor* desc) {
  for (int i = 0; i < desc->message_type_count(); i++) {
    if (HasMap(options, desc->message_type(i))) {
      return true;
    }
  }
  return false;
}

bool IsExtendable(const Descriptor* desc) {
  return desc->extension_range_count() > 0;
}

// Returns the max index in the underlying data storage array beyond which the
// extension object is used.
std::string GetPivot(const Descriptor* desc) {
  static const int kDefaultPivot = 500;

  // Find the max field number
  int max_field_number = 0;
  for (int i = 0; i < desc->field_count(); i++) {
    if (!IgnoreField(desc->field(i)) &&
        desc->field(i)->number() > max_field_number) {
      max_field_number = desc->field(i)->number();
    }
  }

  int pivot = -1;
  if (IsExtendable(desc) || (max_field_number >= kDefaultPivot)) {
    pivot = ((max_field_number + 1) < kDefaultPivot) ? (max_field_number + 1)
                                                     : kDefaultPivot;
  }

  return StrCat(pivot);
}

// Whether this field represents presence.  For fields with presence, we
// generate extra methods (clearFoo() and hasFoo()) for this field.
bool HasFieldPresence(const GeneratorOptions& options,
                      const FieldDescriptor* field) {
  if (field->is_repeated() || field->is_map()) {
    // We say repeated fields and maps don't have presence, but we still do
    // generate clearFoo() methods for them through a special case elsewhere.
    return false;
  }

  if (UseBrokenPresenceSemantics(options, field)) {
    // Proto3 files with broken presence semantics have field presence.
    return true;
  }

  return field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
         field->containing_oneof() != NULL ||
         field->file()->syntax() == FileDescriptor::SYNTAX_PROTO2;
}

// We use this to implement the semantics that same file can be generated
// multiple times, but only the last one keep the short name. Others all use
// long name with extra information to distinguish (For message and enum, the
// extra information is package name, for file level extension, the extra
// information is proto's filename).
// We never actually write the files, but we keep a set of which descriptors
// were the final one for a given filename.
class FileDeduplicator {
 public:
  explicit FileDeduplicator(const GeneratorOptions& options)
      : error_on_conflict_(options.error_on_name_conflict) {}

  // params:
  //   filenames: a pair of {short filename, full filename}
  //              (short filename don't have extra information, full filename
  //               contains extra information)
  //   desc: The Descriptor or SCC pointer or EnumDescriptor.
  //   error: The returned error information.
  bool AddFile(const std::pair<std::string, std::string> filenames,
               const void* desc, std::string* error) {
    if (descs_by_shortname_.find(filenames.first) !=
        descs_by_shortname_.end()) {
      if (error_on_conflict_) {
        *error = "Name conflict: file name " + filenames.first +
                 " would be generated by two descriptors";
        return false;
      }
      // Change old pointer's actual name to full name.
      auto short_name_desc = descs_by_shortname_[filenames.first];
      allowed_descs_actual_name_[short_name_desc] =
          allowed_descs_full_name_[short_name_desc];
    }
    descs_by_shortname_[filenames.first] = desc;
    allowed_descs_actual_name_[desc] = filenames.first;
    allowed_descs_full_name_[desc] = filenames.second;

    return true;
  }

  void GetAllowedMap(std::map<const void*, std::string>* allowed_set) {
    *allowed_set = allowed_descs_actual_name_;
  }

 private:
  bool error_on_conflict_;
  // The map that restores all the descs that are using short name as filename.
  std::map<std::string, const void*> descs_by_shortname_;
  // The final actual filename map.
  std::map<const void*, std::string> allowed_descs_actual_name_;
  // The full name map.
  std::map<const void*, std::string> allowed_descs_full_name_;
};

void DepthFirstSearch(const FileDescriptor* file,
                      std::vector<const FileDescriptor*>* list,
                      std::set<const FileDescriptor*>* seen) {
  if (!seen->insert(file).second) {
    return;
  }

  // Add all dependencies.
  for (int i = 0; i < file->dependency_count(); i++) {
    DepthFirstSearch(file->dependency(i), list, seen);
  }

  // Add this file.
  list->push_back(file);
}

// A functor for the predicate to remove_if() below.  Returns true if a given
// FileDescriptor is not in the given set.
class NotInSet {
 public:
  explicit NotInSet(const std::set<const FileDescriptor*>& file_set)
      : file_set_(file_set) {}

  bool operator()(const FileDescriptor* file) {
    return file_set_.count(file) == 0;
  }

 private:
  const std::set<const FileDescriptor*>& file_set_;
};

// This function generates an ordering of the input FileDescriptors that matches
// the logic of the old code generator.  The order is significant because two
// different input files can generate the same output file, and the last one
// needs to win.
void GenerateJspbFileOrder(const std::vector<const FileDescriptor*>& input,
                           std::vector<const FileDescriptor*>* ordered) {
  // First generate an ordering of all reachable files (including dependencies)
  // with depth-first search.  This mimics the behavior of --include_imports,
  // which is what the old codegen used.
  ordered->clear();
  std::set<const FileDescriptor*> seen;
  std::set<const FileDescriptor*> input_set;
  for (int i = 0; i < input.size(); i++) {
    DepthFirstSearch(input[i], ordered, &seen);
    input_set.insert(input[i]);
  }

  // Now remove the entries that are not actually in our input list.
  ordered->erase(
      std::remove_if(ordered->begin(), ordered->end(), NotInSet(input_set)),
      ordered->end());
}

// If we're generating code in file-per-type mode, avoid overwriting files
// by choosing the last descriptor that writes each filename and permitting
// only those to generate code.

struct DepsGenerator {
  std::vector<const Descriptor*> operator()(const Descriptor* desc) const {
    std::vector<const Descriptor*> deps;
    auto maybe_add = [&](const Descriptor* d) {
      if (d) deps.push_back(d);
    };
    for (int i = 0; i < desc->field_count(); i++) {
      if (!IgnoreField(desc->field(i))) {
        maybe_add(desc->field(i)->message_type());
      }
    }
    for (int i = 0; i < desc->extension_count(); i++) {
      maybe_add(desc->extension(i)->message_type());
      maybe_add(desc->extension(i)->containing_type());
    }
    for (int i = 0; i < desc->nested_type_count(); i++) {
      maybe_add(desc->nested_type(i));
    }
    maybe_add(desc->containing_type());

    return deps;
  }
};

bool GenerateJspbAllowedMap(const GeneratorOptions& options,
                            const std::vector<const FileDescriptor*>& files,
                            std::map<const void*, std::string>* allowed_set,
                            SCCAnalyzer<DepsGenerator>* analyzer,
                            std::string* error) {
  std::vector<const FileDescriptor*> files_ordered;
  GenerateJspbFileOrder(files, &files_ordered);

  // Choose the last descriptor for each filename.
  FileDeduplicator dedup(options);
  std::set<const SCC*> added;
  for (int i = 0; i < files_ordered.size(); i++) {
    for (int j = 0; j < files_ordered[i]->message_type_count(); j++) {
      const Descriptor* desc = files_ordered[i]->message_type(j);
      if (added.insert(analyzer->GetSCC(desc)).second &&
          !dedup.AddFile(
              std::make_pair(
                  GetMessagesFileName(options, analyzer->GetSCC(desc), false),
                  GetMessagesFileName(options, analyzer->GetSCC(desc), true)),
              analyzer->GetSCC(desc), error)) {
        return false;
      }
    }
    for (int j = 0; j < files_ordered[i]->enum_type_count(); j++) {
      const EnumDescriptor* desc = files_ordered[i]->enum_type(j);
      if (!dedup.AddFile(std::make_pair(GetEnumFileName(options, desc, false),
                                        GetEnumFileName(options, desc, true)),
                         desc, error)) {
        return false;
      }
    }

    // Pull out all free-floating extensions and generate files for those too.
    bool has_extension = false;

    for (int j = 0; j < files_ordered[i]->extension_count(); j++) {
      if (ShouldGenerateExtension(files_ordered[i]->extension(j))) {
        has_extension = true;
      }
    }

    if (has_extension) {
      if (!dedup.AddFile(
              std::make_pair(
                  GetExtensionFileName(options, files_ordered[i], false),
                  GetExtensionFileName(options, files_ordered[i], true)),
              files_ordered[i], error)) {
        return false;
      }
    }
  }

  dedup.GetAllowedMap(allowed_set);

  return true;
}

// Embeds base64 encoded GeneratedCodeInfo proto in a comment at the end of
// file.
void EmbedCodeAnnotations(const GeneratedCodeInfo& annotations,
                          io::Printer* printer) {
  // Serialize annotations proto into base64 string.
  std::string meta_content;
  annotations.SerializeToString(&meta_content);
  std::string meta_64;
  Base64Escape(meta_content, &meta_64);

  // Print base64 encoded annotations at the end of output file in
  // a comment.
  printer->Print("\n// Below is base64 encoded GeneratedCodeInfo proto");
  printer->Print("\n// $encoded_proto$\n", "encoded_proto", meta_64);
}

bool IsWellKnownTypeFile(const FileDescriptor* file) {
  return HasPrefixString(file->name(), "google/protobuf/");
}

}  // anonymous namespace

void Generator::GenerateHeader(const GeneratorOptions& options,
                               io::Printer* printer) const {
  printer->Print(
      "/**\n"
      " * @fileoverview\n"
      " * @enhanceable\n"
      " * @suppress {messageConventions} JS Compiler reports an "
      "error if a variable or\n"
      " *     field starts with 'MSG_' and isn't a translatable "
      "message.\n"
      " * @public\n"
      " */\n"
      "// GENERATED CODE -- DO NOT EDIT!\n"
      "\n");
}

void Generator::FindProvidesForFile(const GeneratorOptions& options,
                                    io::Printer* printer,
                                    const FileDescriptor* file,
                                    std::set<std::string>* provided) const {
  for (int i = 0; i < file->message_type_count(); i++) {
    FindProvidesForMessage(options, printer, file->message_type(i), provided);
  }
  for (int i = 0; i < file->enum_type_count(); i++) {
    FindProvidesForEnum(options, printer, file->enum_type(i), provided);
  }
}

void Generator::FindProvides(const GeneratorOptions& options,
                             io::Printer* printer,
                             const std::vector<const FileDescriptor*>& files,
                             std::set<std::string>* provided) const {
  for (int i = 0; i < files.size(); i++) {
    FindProvidesForFile(options, printer, files[i], provided);
  }

  printer->Print("\n");
}

void Generator::FindProvidesForMessage(const GeneratorOptions& options,
                                       io::Printer* printer,
                                       const Descriptor* desc,
                                       std::set<std::string>* provided) const {
  if (IgnoreMessage(desc)) {
    return;
  }

  std::string name = GetMessagePath(options, desc);
  provided->insert(name);

  for (int i = 0; i < desc->enum_type_count(); i++) {
    FindProvidesForEnum(options, printer, desc->enum_type(i), provided);
  }
  for (int i = 0; i < desc->nested_type_count(); i++) {
    FindProvidesForMessage(options, printer, desc->nested_type(i), provided);
  }
}

void Generator::FindProvidesForEnum(const GeneratorOptions& options,
                                    io::Printer* printer,
                                    const EnumDescriptor* enumdesc,
                                    std::set<std::string>* provided) const {
  std::string name = GetEnumPath(options, enumdesc);
  provided->insert(name);
}

void Generator::FindProvidesForFields(
    const GeneratorOptions& options, io::Printer* printer,
    const std::vector<const FieldDescriptor*>& fields,
    std::set<std::string>* provided) const {
  for (int i = 0; i < fields.size(); i++) {
    const FieldDescriptor* field = fields[i];

    if (IgnoreField(field)) {
      continue;
    }

    std::string name = GetNamespace(options, field->file()) + "." +
                       JSObjectFieldName(options, field);
    provided->insert(name);
  }
}

void Generator::GenerateProvides(const GeneratorOptions& options,
                                 io::Printer* printer,
                                 std::set<std::string>* provided) const {
  for (std::set<std::string>::iterator it = provided->begin();
       it != provided->end(); ++it) {
    if (options.import_style == GeneratorOptions::kImportClosure) {
      printer->Print("goog.provide('$name$');\n", "name", *it);
    } else {
      // We aren't using Closure's import system, but we use goog.exportSymbol()
      // to construct the expected tree of objects, eg.
      //
      //   goog.exportSymbol('foo.bar.Baz', null, this);
      //
      //   // Later generated code expects foo.bar = {} to exist:
      //   foo.bar.Baz = function() { /* ... */ }

      // Do not use global scope in strict mode
      if (options.import_style == GeneratorOptions::kImportCommonJsStrict) {
        std::string namespaceObject = *it;
        // Remove "proto." from the namespace object
        GOOGLE_CHECK_EQ(0, namespaceObject.compare(0, 6, "proto."));
        namespaceObject.erase(0, 6);
        printer->Print("goog.exportSymbol('$name$', null, proto);\n", "name",
                       namespaceObject);
      } else {
        printer->Print("goog.exportSymbol('$name$', null, global);\n", "name",
                       *it);
      }
    }
  }
}

void Generator::GenerateRequiresForSCC(const GeneratorOptions& options,
                                       io::Printer* printer, const SCC* scc,
                                       std::set<std::string>* provided) const {
  std::set<std::string> required;
  std::set<std::string> forwards;
  bool have_message = false;
  bool has_extension = false;
  bool has_map = false;
  for (auto desc : scc->descriptors) {
    if (desc->containing_type() == nullptr) {
      FindRequiresForMessage(options, desc, &required, &forwards,
                             &have_message);
      has_extension = (has_extension || HasExtensions(desc));
      has_map = (has_map || HasMap(options, desc));
    }
  }

  GenerateRequiresImpl(options, printer, &required, &forwards, provided,
                       /* require_jspb = */ have_message,
                       /* require_extension = */ has_extension,
                       /* require_map = */ has_map);
}

void Generator::GenerateRequiresForLibrary(
    const GeneratorOptions& options, io::Printer* printer,
    const std::vector<const FileDescriptor*>& files,
    std::set<std::string>* provided) const {
  GOOGLE_CHECK_EQ(options.import_style, GeneratorOptions::kImportClosure);
  // For Closure imports we need to import every message type individually.
  std::set<std::string> required;
  std::set<std::string> forwards;
  bool have_extensions = false;
  bool have_map = false;
  bool have_message = false;

  for (int i = 0; i < files.size(); i++) {
    for (int j = 0; j < files[i]->message_type_count(); j++) {
      const Descriptor* desc = files[i]->message_type(j);
      if (!IgnoreMessage(desc)) {
        FindRequiresForMessage(options, desc, &required, &forwards,
                               &have_message);
      }
    }

    if (!have_extensions && HasExtensions(files[i])) {
      have_extensions = true;
    }

    if (!have_map && FileHasMap(options, files[i])) {
      have_map = true;
    }

    for (int j = 0; j < files[i]->extension_count(); j++) {
      const FieldDescriptor* extension = files[i]->extension(j);
      if (IgnoreField(extension)) {
        continue;
      }
      if (extension->containing_type()->full_name() !=
          "google.protobuf.bridge.MessageSet") {
        required.insert(GetMessagePath(options, extension->containing_type()));
      }
      FindRequiresForField(options, extension, &required, &forwards);
      have_extensions = true;
    }
  }

  GenerateRequiresImpl(options, printer, &required, &forwards, provided,
                       /* require_jspb = */ have_message,
                       /* require_extension = */ have_extensions,
                       /* require_map = */ have_map);
}

void Generator::GenerateRequiresForExtensions(
    const GeneratorOptions& options, io::Printer* printer,
    const std::vector<const FieldDescriptor*>& fields,
    std::set<std::string>* provided) const {
  std::set<std::string> required;
  std::set<std::string> forwards;
  for (int i = 0; i < fields.size(); i++) {
    const FieldDescriptor* field = fields[i];
    if (IgnoreField(field)) {
      continue;
    }
    FindRequiresForExtension(options, field, &required, &forwards);
  }

  GenerateRequiresImpl(options, printer, &required, &forwards, provided,
                       /* require_jspb = */ false,
                       /* require_extension = */ fields.size() > 0,
                       /* require_map = */ false);
}

void Generator::GenerateRequiresImpl(const GeneratorOptions& options,
                                     io::Printer* printer,
                                     std::set<std::string>* required,
                                     std::set<std::string>* forwards,
                                     std::set<std::string>* provided,
                                     bool require_jspb, bool require_extension,
                                     bool require_map) const {
  if (require_jspb) {
    required->insert("jspb.Message");
    required->insert("jspb.BinaryReader");
    required->insert("jspb.BinaryWriter");
  }
  if (require_extension) {
    required->insert("jspb.ExtensionFieldBinaryInfo");
    required->insert("jspb.ExtensionFieldInfo");
  }
  if (require_map) {
    required->insert("jspb.Map");
  }

  std::set<std::string>::iterator it;
  for (it = required->begin(); it != required->end(); ++it) {
    if (provided->find(*it) != provided->end()) {
      continue;
    }
    printer->Print("goog.require('$name$');\n", "name", *it);
  }

  printer->Print("\n");

  for (it = forwards->begin(); it != forwards->end(); ++it) {
    if (provided->find(*it) != provided->end()) {
      continue;
    }
    printer->Print("goog.forwardDeclare('$name$');\n", "name", *it);
  }
}

bool NamespaceOnly(const Descriptor* desc) {
  return false;
}

void Generator::FindRequiresForMessage(const GeneratorOptions& options,
                                       const Descriptor* desc,
                                       std::set<std::string>* required,
                                       std::set<std::string>* forwards,
                                       bool* have_message) const {

  if (!NamespaceOnly(desc)) {
    *have_message = true;
    for (int i = 0; i < desc->field_count(); i++) {
      const FieldDescriptor* field = desc->field(i);
      if (IgnoreField(field)) {
        continue;
      }
      FindRequiresForField(options, field, required, forwards);
    }
  }

  for (int i = 0; i < desc->extension_count(); i++) {
    const FieldDescriptor* field = desc->extension(i);
    if (IgnoreField(field)) {
      continue;
    }
    FindRequiresForExtension(options, field, required, forwards);
  }

  for (int i = 0; i < desc->nested_type_count(); i++) {
    FindRequiresForMessage(options, desc->nested_type(i), required, forwards,
                           have_message);
  }
}

void Generator::FindRequiresForField(const GeneratorOptions& options,
                                     const FieldDescriptor* field,
                                     std::set<std::string>* required,
                                     std::set<std::string>* forwards) const {
  if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM &&
      // N.B.: file-level extensions with enum type do *not* create
      // dependencies, as per original codegen.
      !(field->is_extension() && field->extension_scope() == nullptr)) {
    if (options.add_require_for_enums) {
      required->insert(GetEnumPath(options, field->enum_type()));
    } else {
      forwards->insert(GetEnumPath(options, field->enum_type()));
    }
  } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
    if (!IgnoreMessage(field->message_type())) {
      required->insert(GetMessagePath(options, field->message_type()));
    }
  }
}

void Generator::FindRequiresForExtension(
    const GeneratorOptions& options, const FieldDescriptor* field,
    std::set<std::string>* required, std::set<std::string>* forwards) const {
  if (field->containing_type()->full_name() != "google.protobuf.bridge.MessageSet") {
    required->insert(GetMessagePath(options, field->containing_type()));
  }
  FindRequiresForField(options, field, required, forwards);
}

void Generator::GenerateTestOnly(const GeneratorOptions& options,
                                 io::Printer* printer) const {
  if (options.testonly) {
    printer->Print("goog.setTestOnly();\n\n");
  }
  printer->Print("\n");
}

void Generator::GenerateClassesAndEnums(const GeneratorOptions& options,
                                        io::Printer* printer,
                                        const FileDescriptor* file) const {
  for (int i = 0; i < file->message_type_count(); i++) {
    GenerateClassConstructorAndDeclareExtensionFieldInfo(options, printer,
                                                         file->message_type(i));
  }
  for (int i = 0; i < file->message_type_count(); i++) {
    GenerateClass(options, printer, file->message_type(i));
  }
  for (int i = 0; i < file->enum_type_count(); i++) {
    GenerateEnum(options, printer, file->enum_type(i));
  }
}

void Generator::GenerateClass(const GeneratorOptions& options,
                              io::Printer* printer,
                              const Descriptor* desc) const {
  if (IgnoreMessage(desc)) {
    return;
  }

  if (!NamespaceOnly(desc)) {
    printer->Print("\n");
    GenerateClassFieldInfo(options, printer, desc);


    GenerateClassToObject(options, printer, desc);
    // These must come *before* the extension-field info generation in
    // GenerateClassRegistration so that references to the binary
    // serialization/deserialization functions may be placed in the extension
    // objects.
    GenerateClassDeserializeBinary(options, printer, desc);
    GenerateClassSerializeBinary(options, printer, desc);
  }

  // Recurse on nested types. These must come *before* the extension-field
  // info generation in GenerateClassRegistration so that extensions that
  // reference nested types proceed the definitions of the nested types.
  for (int i = 0; i < desc->enum_type_count(); i++) {
    GenerateEnum(options, printer, desc->enum_type(i));
  }
  for (int i = 0; i < desc->nested_type_count(); i++) {
    GenerateClass(options, printer, desc->nested_type(i));
  }

  if (!NamespaceOnly(desc)) {
    GenerateClassRegistration(options, printer, desc);
    GenerateClassFields(options, printer, desc);

    if (options.import_style != GeneratorOptions::kImportClosure) {
      for (int i = 0; i < desc->extension_count(); i++) {
        GenerateExtension(options, printer, desc->extension(i));
      }
    }
  }
}

void Generator::GenerateClassConstructor(const GeneratorOptions& options,
                                         io::Printer* printer,
                                         const Descriptor* desc) const {
  printer->Print(
      "/**\n"
      " * Generated by JsPbCodeGenerator.\n"
      " * @param {Array=} opt_data Optional initial data array, typically "
      "from a\n"
      " * server response, or constructed directly in Javascript. The array "
      "is used\n"
      " * in place and becomes part of the constructed object. It is not "
      "cloned.\n"
      " * If no data is provided, the constructed object will be empty, but "
      "still\n"
      " * valid.\n"
      " * @extends {jspb.Message}\n"
      " * @constructor\n"
      " */\n"
      "$classprefix$$classname$ = function(opt_data) {\n",
      "classprefix", GetMessagePathPrefix(options, desc), "classname",
      desc->name());
  printer->Annotate("classname", desc);
  std::string message_id = GetMessageId(desc);
  printer->Print(
      "  jspb.Message.initialize(this, opt_data, $messageId$, $pivot$, "
      "$rptfields$, $oneoffields$);\n",
      "messageId",
      !message_id.empty() ? ("'" + message_id + "'")
                          : (IsResponse(desc) ? "''" : "0"),
      "pivot", GetPivot(desc), "rptfields",
      RepeatedFieldsArrayName(options, desc), "oneoffields",
      OneofFieldsArrayName(options, desc));
  printer->Print(
      "};\n"
      "goog.inherits($classname$, jspb.Message);\n"
      "if (goog.DEBUG && !COMPILED) {\n"
      // displayName overrides Function.prototype.displayName
      // http://google3/javascript/externs/es3.js?l=511
      "  /**\n"
      "   * @public\n"
      "   * @override\n"
      "   */\n"
      "  $classname$.displayName = '$classname$';\n"
      "}\n",
      "classname", GetMessagePath(options, desc));
}

void Generator::GenerateClassConstructorAndDeclareExtensionFieldInfo(
    const GeneratorOptions& options, io::Printer* printer,
    const Descriptor* desc) const {
  if (!NamespaceOnly(desc)) {
    GenerateClassConstructor(options, printer, desc);
    if (IsExtendable(desc) && desc->full_name() != "google.protobuf.bridge.MessageSet") {
      GenerateClassExtensionFieldInfo(options, printer, desc);
    }
  }
  for (int i = 0; i < desc->nested_type_count(); i++) {
    if (!IgnoreMessage(desc->nested_type(i))) {
      GenerateClassConstructorAndDeclareExtensionFieldInfo(
          options, printer, desc->nested_type(i));
    }
  }
}

void Generator::GenerateClassFieldInfo(const GeneratorOptions& options,
                                       io::Printer* printer,
                                       const Descriptor* desc) const {
  if (HasRepeatedFields(options, desc)) {
    printer->Print(
        "/**\n"
        " * List of repeated fields within this message type.\n"
        " * @private {!Array<number>}\n"
        " * @const\n"
        " */\n"
        "$classname$$rptfieldarray$ = $rptfields$;\n"
        "\n",
        "classname", GetMessagePath(options, desc), "rptfieldarray",
        kRepeatedFieldArrayName, "rptfields",
        RepeatedFieldNumberList(options, desc));
  }

  if (HasOneofFields(desc)) {
    printer->Print(
        "/**\n"
        " * Oneof group definitions for this message. Each group defines the "
        "field\n"
        " * numbers belonging to that group. When of these fields' value is "
        "set, all\n"
        " * other fields in the group are cleared. During deserialization, if "
        "multiple\n"
        " * fields are encountered for a group, only the last value seen will "
        "be kept.\n"
        " * @private {!Array<!Array<number>>}\n"
        " * @const\n"
        " */\n"
        "$classname$$oneofgrouparray$ = $oneofgroups$;\n"
        "\n",
        "classname", GetMessagePath(options, desc), "oneofgrouparray",
        kOneofGroupArrayName, "oneofgroups", OneofGroupList(desc));

    for (int i = 0; i < desc->oneof_decl_count(); i++) {
      if (IgnoreOneof(desc->oneof_decl(i))) {
        continue;
      }
      GenerateOneofCaseDefinition(options, printer, desc->oneof_decl(i));
    }
  }
}

void Generator::GenerateClassXid(const GeneratorOptions& options,
                                 io::Printer* printer,
                                 const Descriptor* desc) const {
  printer->Print(
      "\n"
      "\n"
      "$class$.prototype.messageXid = xid('$class$');\n",
      "class", GetMessagePath(options, desc));
}

void Generator::GenerateOneofCaseDefinition(
    const GeneratorOptions& options, io::Printer* printer,
    const OneofDescriptor* oneof) const {
  printer->Print(
      "/**\n"
      " * @enum {number}\n"
      " */\n"
      "$classname$.$oneof$Case = {\n"
      "  $upcase$_NOT_SET: 0",
      "classname", GetMessagePath(options, oneof->containing_type()), "oneof",
      JSOneofName(oneof), "upcase", ToEnumCase(oneof->name()));

  for (int i = 0; i < oneof->field_count(); i++) {
    if (IgnoreField(oneof->field(i))) {
      continue;
    }

    printer->Print(
        ",\n"
        "  $upcase$: $number$",
        "upcase", ToEnumCase(oneof->field(i)->name()), "number",
        JSFieldIndex(oneof->field(i)));
    printer->Annotate("upcase", oneof->field(i));
  }

  printer->Print(
      "\n"
      "};\n"
      "\n"
      "/**\n"
      " * @return {$class$.$oneof$Case}\n"
      " */\n"
      "$class$.prototype.get$oneof$Case = function() {\n"
      "  return /** @type {$class$.$oneof$Case} */(jspb.Message."
      "computeOneofCase(this, $class$.oneofGroups_[$oneofindex$]));\n"
      "};\n"
      "\n",
      "class", GetMessagePath(options, oneof->containing_type()), "oneof",
      JSOneofName(oneof), "oneofindex", JSOneofIndex(oneof));
}

void Generator::GenerateClassToObject(const GeneratorOptions& options,
                                      io::Printer* printer,
                                      const Descriptor* desc) const {
  printer->Print(
      "\n"
      "\n"
      "if (jspb.Message.GENERATE_TO_OBJECT) {\n"
      "/**\n"
      " * Creates an object representation of this proto.\n"
      " * Field names that are reserved in JavaScript and will be renamed to "
      "pb_name.\n"
      " * Optional fields that are not set will be set to undefined.\n"
      " * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.\n"
      " * For the list of reserved names please see:\n"
      " *     net/proto2/compiler/js/internal/generator.cc#kKeyword.\n"
      " * @param {boolean=} opt_includeInstance Deprecated. whether to include "
      "the\n"
      " *     JSPB instance for transitional soy proto support:\n"
      " *     http://goto/soy-param-migration\n"
      " * @return {!Object}\n"
      " */\n"
      "$classname$.prototype.toObject = function(opt_includeInstance) {\n"
      "  return $classname$.toObject(opt_includeInstance, this);\n"
      "};\n"
      "\n"
      "\n"
      "/**\n"
      " * Static version of the {@see toObject} method.\n"
      " * @param {boolean|undefined} includeInstance Deprecated. Whether to "
      "include\n"
      " *     the JSPB instance for transitional soy proto support:\n"
      " *     http://goto/soy-param-migration\n"
      " * @param {!$classname$} msg The msg instance to transform.\n"
      " * @return {!Object}\n"
      " * @suppress {unusedLocalVariables} f is only used for nested messages\n"
      " */\n"
      "$classname$.toObject = function(includeInstance, msg) {\n"
      "  var f, obj = {",
      "classname", GetMessagePath(options, desc));

  bool first = true;
  for (int i = 0; i < desc->field_count(); i++) {
    const FieldDescriptor* field = desc->field(i);
    if (IgnoreField(field)) {
      continue;
    }

    if (!first) {
      printer->Print(",\n    ");
    } else {
      printer->Print("\n    ");
      first = false;
    }

    GenerateClassFieldToObject(options, printer, field);
  }

  if (!first) {
    printer->Print("\n  };\n\n");
  } else {
    printer->Print("\n\n  };\n\n");
  }

  if (IsExtendable(desc)) {
    printer->Print(
        "  jspb.Message.toObjectExtension(/** @type {!jspb.Message} */ (msg), "
        "obj,\n"
        "      $extObject$, $class$.prototype.getExtension,\n"
        "      includeInstance);\n",
        "extObject", JSExtensionsObjectName(options, desc->file(), desc),
        "class", GetMessagePath(options, desc));
  }

  printer->Print(
      "  if (includeInstance) {\n"
      "    obj.$$jspbMessageInstance = msg;\n"
      "  }\n"
      "  return obj;\n"
      "};\n"
      "}\n"
      "\n"
      "\n",
      "classname", GetMessagePath(options, desc));
}

void Generator::GenerateFieldValueExpression(io::Printer* printer,
                                             const char* obj_reference,
                                             const FieldDescriptor* field,
                                             bool use_default) const {
  const bool is_float_or_double =
      field->cpp_type() == FieldDescriptor::CPPTYPE_FLOAT ||
      field->cpp_type() == FieldDescriptor::CPPTYPE_DOUBLE;
  const bool is_boolean = field->cpp_type() == FieldDescriptor::CPPTYPE_BOOL;

  const string with_default = use_default ? "WithDefault" : "";
  const string default_arg =
      use_default ? StrCat(", ", JSFieldDefault(field)) : "";
  const string cardinality = field->is_repeated() ? "Repeated" : "";
  string type = "";
  if (is_float_or_double) {
    type = "FloatingPoint";
  }
  if (is_boolean) {
    type = "Boolean";
  }

  // Prints the appropriate function, among:
  // - getField
  // - getBooleanField
  // - getFloatingPointField => Replaced by getOptionalFloatingPointField to
  //   preserve backward compatibility.
  // - getFieldWithDefault
  // - getBooleanFieldWithDefault
  // - getFloatingPointFieldWithDefault
  // - getRepeatedField
  // - getRepeatedBooleanField
  // - getRepeatedFloatingPointField
  if (is_float_or_double && !field->is_repeated() && !use_default) {
    printer->Print(
        "jspb.Message.getOptionalFloatingPointField($obj$, "
        "$index$$default$)",
        "obj", obj_reference, "index", JSFieldIndex(field), "default",
        default_arg);
  } else {
    printer->Print(
        "jspb.Message.get$cardinality$$type$Field$with_default$($obj$, "
        "$index$$default$)",
        "cardinality", cardinality, "type", type, "with_default", with_default,
        "obj", obj_reference, "index", JSFieldIndex(field), "default",
        default_arg);
  }
}

void Generator::GenerateClassFieldToObject(const GeneratorOptions& options,
                                           io::Printer* printer,
                                           const FieldDescriptor* field) const {
  printer->Print("$fieldname$: ", "fieldname",
                 JSObjectFieldName(options, field));

  if (field->is_map()) {
    const FieldDescriptor* value_field = MapFieldValue(field);
    // If the map values are of a message type, we must provide their static
    // toObject() method; otherwise we pass undefined for that argument.
    std::string value_to_object;
    if (value_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
      value_to_object =
          GetMessagePath(options, value_field->message_type()) + ".toObject";
    } else {
      value_to_object = "undefined";
    }
    printer->Print(
        "(f = msg.get$name$()) ? f.toObject(includeInstance, $valuetoobject$) "
        ": []",
        "name", JSGetterName(options, field), "valuetoobject", value_to_object);
  } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
    // Message field.
    if (field->is_repeated()) {
      {
        printer->Print(
            "jspb.Message.toObjectList(msg.get$getter$(),\n"
            "    $type$.toObject, includeInstance)",
            "getter", JSGetterName(options, field), "type",
            SubmessageTypeRef(options, field));
      }
    } else {
      printer->Print(
          "(f = msg.get$getter$()) && "
          "$type$.toObject(includeInstance, f)",
          "getter", JSGetterName(options, field), "type",
          SubmessageTypeRef(options, field));
    }
  } else if (field->type() == FieldDescriptor::TYPE_BYTES) {
    // For bytes fields we want to always return the B64 data.
    printer->Print("msg.get$getter$()", "getter",
                   JSGetterName(options, field, BYTES_B64));
  } else {
    bool use_default = field->has_default_value();

    if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 &&
        // Repeated fields get initialized to their default in the constructor
        // (why?), so we emit a plain getField() call for them.
        !field->is_repeated() && !UseBrokenPresenceSemantics(options, field)) {
      // Proto3 puts all defaults (including implicit defaults) in toObject().
      // But for proto2 we leave the existing semantics unchanged: unset fields
      // without default are unset.
      use_default = true;
    }

    // We don't implement this by calling the accessors, because the semantics
    // of the accessors are changing independently of the toObject() semantics.
    // We are migrating the accessors to return defaults instead of null, but
    // it may take longer to migrate toObject (or we might not want to do it at
    // all).  So we want to generate independent code.
    // The accessor for unset optional values without default should return
    // null. Those are converted to undefined in the generated object.
    if (!use_default) {
      printer->Print("(f = ");
    }
    GenerateFieldValueExpression(printer, "msg", field, use_default);
    if (!use_default) {
      printer->Print(") == null ? undefined : f");
    }
  }
}

void Generator::GenerateObjectTypedef(const GeneratorOptions& options,
                                      io::Printer* printer,
                                      const Descriptor* desc) const {
  // TODO(b/122687752): Consider renaming nested messages called ObjectFormat
  //     to prevent collisions.
  const std::string type_name = GetMessagePath(options, desc) + ".ObjectFormat";

  printer->Print(
      "/**\n"
      " * The raw object form of $messageName$ as accepted by the `fromObject` "
      "method.\n"
      " * @record\n"
      " */\n"
      "$typeName$ = function() {};\n\n",
      "messageName", desc->name(), "typeName", type_name);

  for (int i = 0; i < desc->field_count(); i++) {
    printer->Print(
        "/** @type {$fieldType$|undefined} */\n"
        "$typeName$.prototype.$fieldName$;\n\n",
        "typeName", type_name, "fieldName",
        JSObjectFieldName(options, desc->field(i)),
        // TODO(b/121097361): Add type checking for field values.
        "fieldType", "?");
  }
}

void Generator::GenerateClassFromObject(const GeneratorOptions& options,
                                        io::Printer* printer,
                                        const Descriptor* desc) const {
  printer->Print("if (jspb.Message.GENERATE_FROM_OBJECT) {\n\n");

  GenerateObjectTypedef(options, printer, desc);

  printer->Print(
      "/**\n"
      " * Loads data from an object into a new instance of this proto.\n"
      " * @param {!$classname$.ObjectFormat} obj\n"
      " *     The object representation of this proto to load the data from.\n"
      " * @return {!$classname$}\n"
      " */\n"
      "$classname$.fromObject = function(obj) {\n"
      "  var msg = new $classname$();\n",
      "classname", GetMessagePath(options, desc));

  for (int i = 0; i < desc->field_count(); i++) {
    const FieldDescriptor* field = desc->field(i);
    if (!IgnoreField(field)) {
      GenerateClassFieldFromObject(options, printer, field);
    }
  }

  printer->Print(
      "  return msg;\n"
      "};\n"
      "}\n\n");
}

void Generator::GenerateClassFieldFromObject(
    const GeneratorOptions& options, io::Printer* printer,
    const FieldDescriptor* field) const {
  if (field->is_map()) {
    const FieldDescriptor* value_field = MapFieldValue(field);
    if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) {
      // Since the map values are of message type, we have to do some extra work
      // to recursively call fromObject() on them before setting the map field.
      printer->Print(
          "  obj.$name$ && jspb.Message.setWrapperField(\n"
          "      msg, $index$, jspb.Map.fromObject(obj.$name$, $fieldclass$, "
          "$fieldclass$.fromObject));\n",
          "name", JSObjectFieldName(options, field), "index",
          JSFieldIndex(field), "fieldclass",
          GetMessagePath(options, value_field->message_type()));
    } else {
      // `msg` is a newly-constructed message object that has not yet built any
      // map containers wrapping underlying arrays, so we can simply directly
      // set the array here without fear of a stale wrapper.
      printer->Print(
          "  obj.$name$ && "
          "jspb.Message.setField(msg, $index$, obj.$name$);\n",
          "name", JSObjectFieldName(options, field), "index",
          JSFieldIndex(field));
    }
  } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
    // Message field (singular or repeated)
    if (field->is_repeated()) {
      {
        printer->Print(
            "  obj.$name$ && "
            "jspb.Message.setRepeatedWrapperField(\n"
            "      msg, $index$, obj.$name$.map(\n"
            "          $fieldclass$.fromObject));\n",
            "name", JSObjectFieldName(options, field), "index",
            JSFieldIndex(field), "fieldclass",
            SubmessageTypeRef(options, field));
      }
    } else {
      printer->Print(
          "  obj.$name$ && jspb.Message.setWrapperField(\n"
          "      msg, $index$, $fieldclass$.fromObject(obj.$name$));\n",
          "name", JSObjectFieldName(options, field), "index",
          JSFieldIndex(field), "fieldclass", SubmessageTypeRef(options, field));
    }
  } else {
    // Simple (primitive) field.
    printer->Print(
        "  obj.$name$ != null && jspb.Message.setField(msg, $index$, "
        "obj.$name$);\n",
        "name", JSObjectFieldName(options, field), "index",
        JSFieldIndex(field));
  }
}

void Generator::GenerateClassRegistration(const GeneratorOptions& options,
                                          io::Printer* printer,
                                          const Descriptor* desc) const {
  // Register any extensions defined inside this message type.
  for (int i = 0; i < desc->extension_count(); i++) {
    const FieldDescriptor* extension = desc->extension(i);
    if (ShouldGenerateExtension(extension)) {
      GenerateExtension(options, printer, extension);
    }
  }

}

void Generator::GenerateClassFields(const GeneratorOptions& options,
                                    io::Printer* printer,
                                    const Descriptor* desc) const {
  for (int i = 0; i < desc->field_count(); i++) {
    if (!IgnoreField(desc->field(i))) {
      GenerateClassField(options, printer, desc->field(i));
    }
  }
}

void GenerateBytesWrapper(const GeneratorOptions& options, io::Printer* printer,
                          const FieldDescriptor* field, BytesMode bytes_mode) {
  std::string type =
      JSFieldTypeAnnotation(options, field,
                            /* is_setter_argument = */ false,
                            /* force_present = */ false,
                            /* singular_if_not_packed = */ false, bytes_mode);
  printer->Print(
      "/**\n"
      " * $fielddef$\n"
      "$comment$"
      " * This is a type-conversion wrapper around `get$defname$()`\n"
      " * @return {$type$}\n"
      " */\n"
      "$class$.prototype.get$name$ = function() {\n"
      "  return /** @type {$type$} */ (jspb.Message.bytes$list$As$suffix$(\n"
      "      this.get$defname$()));\n"
      "};\n"
      "\n"
      "\n",
      "fielddef", FieldDefinition(options, field), "comment",
      FieldComments(field, bytes_mode), "type", type, "class",
      GetMessagePath(options, field->containing_type()), "name",
      JSGetterName(options, field, bytes_mode), "list",
      field->is_repeated() ? "List" : "", "suffix",
      JSByteGetterSuffix(bytes_mode), "defname",
      JSGetterName(options, field, BYTES_DEFAULT));
}

void Generator::GenerateClassField(const GeneratorOptions& options,
                                   io::Printer* printer,
                                   const FieldDescriptor* field) const {
  if (field->is_map()) {
    const FieldDescriptor* key_field = MapFieldKey(field);
    const FieldDescriptor* value_field = MapFieldValue(field);
    // Map field: special handling to instantiate the map object on demand.
    std::string key_type =
        JSFieldTypeAnnotation(options, key_field,
                              /* is_setter_argument = */ false,
                              /* force_present = */ true,
                              /* singular_if_not_packed = */ false);
    std::string value_type =
        JSFieldTypeAnnotation(options, value_field,
                              /* is_setter_argument = */ false,
                              /* force_present = */ true,
                              /* singular_if_not_packed = */ false);

    printer->Print(
        "/**\n"
        " * $fielddef$\n"
        " * @param {boolean=} opt_noLazyCreate Do not create the map if\n"
        " * empty, instead returning `undefined`\n"
        " * @return {!jspb.Map<$keytype$,$valuetype$>}\n"
        " */\n",
        "fielddef", FieldDefinition(options, field), "keytype", key_type,
        "valuetype", value_type);
    printer->Print(
        "$class$.prototype.$gettername$ = function(opt_noLazyCreate) {\n"
        "  return /** @type {!jspb.Map<$keytype$,$valuetype$>} */ (\n",
        "class", GetMessagePath(options, field->containing_type()),
        "gettername", "get" + JSGetterName(options, field), "keytype", key_type,
        "valuetype", value_type);
    printer->Annotate("gettername", field);
    printer->Print(
        "      jspb.Message.getMapField(this, $index$, opt_noLazyCreate",
        "index", JSFieldIndex(field));

    if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) {
      printer->Print(
          ",\n"
          "      $messageType$",
          "messageType", GetMessagePath(options, value_field->message_type()));
    } else {
      printer->Print(
          ",\n"
          "      null");
    }

    printer->Print("));\n");

    printer->Print(
        "};\n"
        "\n"
        "\n");
  } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
    // Message field: special handling in order to wrap the underlying data
    // array with a message object.

    printer->Print(
        "/**\n"
        " * $fielddef$\n"
        "$comment$"
        " * @return {$type$}\n"
        " */\n",
        "fielddef", FieldDefinition(options, field), "comment",
        FieldComments(field, BYTES_DEFAULT), "type",
        JSFieldTypeAnnotation(options, field,
                              /* is_setter_argument = */ false,
                              /* force_present = */ false,
                              /* singular_if_not_packed = */ false));
    printer->Print(
        "$class$.prototype.$gettername$ = function() {\n"
        "  return /** @type{$type$} */ (\n"
        "    jspb.Message.get$rpt$WrapperField(this, $wrapperclass$, "
        "$index$$required$));\n"
        "};\n"
        "\n"
        "\n",
        "class", GetMessagePath(options, field->containing_type()),
        "gettername", "get" + JSGetterName(options, field), "type",
        JSFieldTypeAnnotation(options, field,
                              /* is_setter_argument = */ false,
                              /* force_present = */ false,
                              /* singular_if_not_packed = */ false),
        "rpt", (field->is_repeated() ? "Repeated" : ""), "index",
        JSFieldIndex(field), "wrapperclass", SubmessageTypeRef(options, field),
        "required",
        (field->label() == FieldDescriptor::LABEL_REQUIRED ? ", 1" : ""));
    printer->Annotate("gettername", field);
    printer->Print(
        "/** @param {$optionaltype$} value$returndoc$ */\n"
        "$class$.prototype.$settername$ = function(value) {\n"
        "  jspb.Message.set$oneoftag$$repeatedtag$WrapperField(",
        "optionaltype",
        JSFieldTypeAnnotation(options, field,
                              /* is_setter_argument = */ true,
                              /* force_present = */ false,
                              /* singular_if_not_packed = */ false),
        "returndoc", JSReturnDoc(options, field), "class",
        GetMessagePath(options, field->containing_type()), "settername",
        "set" + JSGetterName(options, field), "oneoftag",
        (field->containing_oneof() ? "Oneof" : ""), "repeatedtag",
        (field->is_repeated() ? "Repeated" : ""));
    printer->Annotate("settername", field);

    printer->Print(
        "this, $index$$oneofgroup$, value);$returnvalue$\n"
        "};\n"
        "\n"
        "\n",
        "index", JSFieldIndex(field), "oneofgroup",
        (field->containing_oneof() ? (", " + JSOneofArray(options, field))
                                   : ""),
        "returnvalue", JSReturnClause(field));

    if (field->is_repeated()) {
      GenerateRepeatedMessageHelperMethods(options, printer, field);
    }

  } else {
    bool untyped =
        false;

    // Simple (primitive) field, either singular or repeated.

    // TODO(b/26173701): Always use BYTES_DEFAULT for the getter return type;
    // at this point we "lie" to non-binary users and tell the return
    // type is always base64 string, pending a LSC to migrate to typed getters.
    BytesMode bytes_mode =
        field->type() == FieldDescriptor::TYPE_BYTES && !options.binary
            ? BYTES_B64
            : BYTES_DEFAULT;
    std::string typed_annotation =
        JSFieldTypeAnnotation(options, field,
                              /* is_setter_argument = */ false,
                              /* force_present = */ false,
                              /* singular_if_not_packed = */ false,
                              /* bytes_mode = */ bytes_mode);
    if (untyped) {
      printer->Print(
          "/**\n"
          " * @return {?} Raw field, untyped.\n"
          " */\n");
    } else {
      printer->Print(
          "/**\n"
          " * $fielddef$\n"
          "$comment$"
          " * @return {$type$}\n"
          " */\n",
          "fielddef", FieldDefinition(options, field), "comment",
          FieldComments(field, bytes_mode), "type", typed_annotation);
    }

    printer->Print("$class$.prototype.$gettername$ = function() {\n", "class",
                   GetMessagePath(options, field->containing_type()),
                   "gettername", "get" + JSGetterName(options, field));
    printer->Annotate("gettername", field);

    if (untyped) {
      printer->Print("  return ");
    } else {
      printer->Print("  return /** @type {$type$} */ (", "type",
                     typed_annotation);
    }

    bool use_default = !ReturnsNullWhenUnset(options, field);

    // Raw fields with no default set should just return undefined.
    if (untyped && !field->has_default_value()) {
      use_default = false;
    }

    // Repeated fields get initialized to their default in the constructor
    // (why?), so we emit a plain getField() call for them.
    if (field->is_repeated()) {
      use_default = false;
    }

    GenerateFieldValueExpression(printer, "this", field, use_default);

    if (untyped) {
      printer->Print(
          ";\n"
          "};\n"
          "\n"
          "\n");
    } else {
      printer->Print(
          ");\n"
          "};\n"
          "\n"
          "\n");
    }

    if (field->type() == FieldDescriptor::TYPE_BYTES && !untyped) {
      GenerateBytesWrapper(options, printer, field, BYTES_B64);
      GenerateBytesWrapper(options, printer, field, BYTES_U8);
    }

    if (untyped) {
      printer->Print(
          "/**\n"
          " * @param {*} value$returndoc$\n"
          " */\n",
          "returndoc", JSReturnDoc(options, field));
    } else {
      printer->Print(
          "/** @param {$optionaltype$} value$returndoc$ */\n", "optionaltype",
          JSFieldTypeAnnotation(options, field,
                                /* is_setter_argument = */ true,
                                /* force_present = */ false,
                                /* singular_if_not_packed = */ false),
          "returndoc", JSReturnDoc(options, field));
    }

    if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 &&
        !field->is_repeated() && !field->is_map() &&
        !HasFieldPresence(options, field)) {
      // Proto3 non-repeated and non-map fields without presence use the
      // setProto3*Field function.
      printer->Print(
          "$class$.prototype.$settername$ = function(value) {\n"
          "  jspb.Message.setProto3$typetag$Field(this, $index$, "
          "value);$returnvalue$\n"
          "};\n"
          "\n"
          "\n",
          "class", GetMessagePath(options, field->containing_type()),
          "settername", "set" + JSGetterName(options, field), "typetag",
          JSTypeTag(field), "index", JSFieldIndex(field), "returnvalue",
          JSReturnClause(field));
      printer->Annotate("settername", field);
    } else {
      // Otherwise, use the regular setField function.
      printer->Print(
          "$class$.prototype.$settername$ = function(value) {\n"
          "  jspb.Message.set$oneoftag$Field(this, $index$",
          "class", GetMessagePath(options, field->containing_type()),
          "settername", "set" + JSGetterName(options, field), "oneoftag",
          (field->containing_oneof() ? "Oneof" : ""), "index",
          JSFieldIndex(field));
      printer->Annotate("settername", field);
      printer->Print(
          "$oneofgroup$, $type$value$rptvalueinit$$typeclose$);$returnvalue$\n"
          "};\n"
          "\n"
          "\n",
          "type",
          untyped ? "/** @type{string|number|boolean|Array|undefined} */(" : "",
          "typeclose", untyped ? ")" : "", "oneofgroup",
          (field->containing_oneof() ? (", " + JSOneofArray(options, field))
                                     : ""),
          "returnvalue", JSReturnClause(field), "rptvalueinit",
          (field->is_repeated() ? " || []" : ""));
    }

    if (untyped) {
      printer->Print(
          "/**\n"
          " * Clears the value.$returndoc$\n"
          " */\n",
          "returndoc", JSReturnDoc(options, field));
    }

    if (field->is_repeated()) {
      GenerateRepeatedPrimitiveHelperMethods(options, printer, field, untyped);
    }
  }

  // Generate clearFoo() method for map fields, repeated fields, and other
  // fields with presence.
  if (field->is_map()) {
    // clang-format off
    printer->Print(
        "/**\n"
        " * Clears values from the map. The map will be non-null."
        "$returndoc$\n"
        " */\n"
        "$class$.prototype.$clearername$ = function() {\n"
        "  this.$gettername$().clear();$returnvalue$\n"
        "};\n"
        "\n"
        "\n",
        "returndoc", JSReturnDoc(options, field),
        "class", GetMessagePath(options, field->containing_type()),
        "clearername", "clear" + JSGetterName(options, field),
        "gettername", "get" + JSGetterName(options, field),
        "returnvalue", JSReturnClause(field));
    // clang-format on
    printer->Annotate("clearername", field);
  } else if (field->is_repeated() ||
             (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
              !field->is_required())) {
    // Fields where we can delegate to the regular setter.
    // clang-format off
    printer->Print(
        "/**\n"
        " * $jsdoc$$returndoc$\n"
        " */\n"
        "$class$.prototype.$clearername$ = function() {\n"
        "  this.$settername$($clearedvalue$);$returnvalue$\n"
        "};\n"
        "\n"
        "\n",
       "jsdoc", field->is_repeated()
           ? "Clears the list making it empty but non-null."
           : "Clears the message field making it undefined.",
        "returndoc", JSReturnDoc(options, field),
        "class", GetMessagePath(options, field->containing_type()),
        "clearername", "clear" + JSGetterName(options, field),
        "settername", "set" + JSGetterName(options, field),
        "clearedvalue", (field->is_repeated() ? "[]" : "undefined"),
        "returnvalue", JSReturnClause(field));
    // clang-format on
    printer->Annotate("clearername", field);
  } else if (HasFieldPresence(options, field)) {
    // Fields where we can't delegate to the regular setter because it doesn't
    // accept "undefined" as an argument.
    // clang-format off
    printer->Print(
        "/**\n"
        " * Clears the field making it undefined.$returndoc$\n"
        " */\n"
        "$class$.prototype.$clearername$ = function() {\n"
        "  jspb.Message.set$maybeoneof$Field(this, "
        "$index$$maybeoneofgroup$, ",
        "returndoc", JSReturnDoc(options, field),
        "class", GetMessagePath(options, field->containing_type()),
        "clearername", "clear" + JSGetterName(options, field),
        "maybeoneof", (field->containing_oneof() ? "Oneof" : ""),
        "maybeoneofgroup", (field->containing_oneof()
                            ? (", " + JSOneofArray(options, field))
                            : ""),
        "index", JSFieldIndex(field));
    // clang-format on
    printer->Annotate("clearername", field);
    printer->Print(
        "$clearedvalue$);$returnvalue$\n"
        "};\n"
        "\n"
        "\n",
        "clearedvalue", (field->is_repeated() ? "[]" : "undefined"),
        "returnvalue", JSReturnClause(field));
  }

  if (HasFieldPresence(options, field)) {
    printer->Print(
        "/**\n"
        " * Returns whether this field is set.\n"
        " * @return {boolean}\n"
        " */\n"
        "$class$.prototype.$hasername$ = function() {\n"
        "  return jspb.Message.getField(this, $index$) != null;\n"
        "};\n"
        "\n"
        "\n",
        "class", GetMessagePath(options, field->containing_type()), "hasername",
        "has" + JSGetterName(options, field), "index", JSFieldIndex(field));
    printer->Annotate("hasername", field);
  }
}

void Generator::GenerateRepeatedPrimitiveHelperMethods(
    const GeneratorOptions& options, io::Printer* printer,
    const FieldDescriptor* field, bool untyped) const {
  // clang-format off
  printer->Print(
      "/**\n"
      " * @param {$optionaltype$} value\n"
      " * @param {number=} opt_index$returndoc$\n"
      " */\n"
      "$class$.prototype.$addername$ = function(value, opt_index) {\n"
      "  jspb.Message.addToRepeatedField(this, $index$",
      "class", GetMessagePath(options, field->containing_type()), "addername",
      "add" + JSGetterName(options, field, BYTES_DEFAULT,
                           /* drop_list = */ true),
      "optionaltype",
          JSFieldTypeAnnotation(
                                options, field,
                                /* is_setter_argument = */ false,
                                /* force_present = */ true,
                                /* singular_if_not_packed = */ false,
                                BYTES_DEFAULT,
                                /* force_singular = */ true),
      "index", JSFieldIndex(field),
      "returndoc", JSReturnDoc(options, field));
  printer->Annotate("addername", field);
  printer->Print(
      "$oneofgroup$, $type$value$rptvalueinit$$typeclose$, "
      "opt_index);$returnvalue$\n"
      "};\n"
      "\n"
      "\n",
      "type", untyped ? "/** @type{string|number|boolean|!Uint8Array} */(" : "",
      "typeclose", untyped ? ")" : "", "oneofgroup",
      (field->containing_oneof() ? (", " + JSOneofArray(options, field)) : ""),
      "rptvalueinit", "",
      "returnvalue", JSReturnClause(field));
  // clang-format on
}

void Generator::GenerateRepeatedMessageHelperMethods(
    const GeneratorOptions& options, io::Printer* printer,
    const FieldDescriptor* field) const {
  printer->Print(
      "/**\n"
      " * @param {!$optionaltype$=} opt_value\n"
      " * @param {number=} opt_index\n"
      " * @return {!$optionaltype$}\n"
      " */\n"
      "$class$.prototype.$addername$ = function(opt_value, opt_index) {\n"
      "  return jspb.Message.addTo$repeatedtag$WrapperField(",
      "optionaltype", JSTypeName(options, field, BYTES_DEFAULT), "class",
      GetMessagePath(options, field->containing_type()), "addername",
      "add" + JSGetterName(options, field, BYTES_DEFAULT,
                           /* drop_list = */ true),
      "repeatedtag", (field->is_repeated() ? "Repeated" : ""));

  printer->Annotate("addername", field);
  printer->Print(
      "this, $index$$oneofgroup$, opt_value, $ctor$, opt_index);\n"
      "};\n"
      "\n"
      "\n",
      "index", JSFieldIndex(field), "oneofgroup",
      (field->containing_oneof() ? (", " + JSOneofArray(options, field)) : ""),
      "ctor", GetMessagePath(options, field->message_type()));
}

void Generator::GenerateClassExtensionFieldInfo(const GeneratorOptions& options,
                                                io::Printer* printer,
                                                const Descriptor* desc) const {
  if (IsExtendable(desc)) {
    printer->Print(
        "\n"
        "/**\n"
        " * The extensions registered with this message class. This is a "
        "map of\n"
        " * extension field number to fieldInfo object.\n"
        " *\n"
        " * For example:\n"
        " *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, "
        "ctor: proto.example.MyMessage} }\n"
        " *\n"
        " * fieldName contains the JsCompiler renamed field name property "
        "so that it\n"
        " * works in OPTIMIZED mode.\n"
        " *\n"
        " * @type {!Object<number, jspb.ExtensionFieldInfo>}\n"
        " */\n"
        "$class$.extensions = {};\n"
        "\n",
        "class", GetMessagePath(options, desc));

    printer->Print(
        "\n"
        "/**\n"
        " * The extensions registered with this message class. This is a "
        "map of\n"
        " * extension field number to fieldInfo object.\n"
        " *\n"
        " * For example:\n"
        " *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, "
        "ctor: proto.example.MyMessage} }\n"
        " *\n"
        " * fieldName contains the JsCompiler renamed field name property "
        "so that it\n"
        " * works in OPTIMIZED mode.\n"
        " *\n"
        " * @type {!Object<number, jspb.ExtensionFieldBinaryInfo>}\n"
        " */\n"
        "$class$.extensionsBinary = {};\n"
        "\n",
        "class", GetMessagePath(options, desc));
  }
}


void Generator::GenerateClassDeserializeBinary(const GeneratorOptions& options,
                                               io::Printer* printer,
                                               const Descriptor* desc) const {
  // TODO(cfallin): Handle lazy decoding when requested by field option and/or
  // by default for 'bytes' fields and packed repeated fields.

  printer->Print(
      "/**\n"
      " * Deserializes binary data (in protobuf wire format).\n"
      " * @param {jspb.ByteSource} bytes The bytes to deserialize.\n"
      " * @return {!$class$}\n"
      " */\n"
      "$class$.deserializeBinary = function(bytes) {\n"
      "  var reader = new jspb.BinaryReader(bytes);\n"
      "  var msg = new $class$;\n"
      "  return $class$.deserializeBinaryFromReader(msg, reader);\n"
      "};\n"
      "\n"
      "\n"
      "/**\n"
      " * Deserializes binary data (in protobuf wire format) from the\n"
      " * given reader into the given message object.\n"
      " * @param {!$class$} msg The message object to deserialize into.\n"
      " * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n"
      " * @return {!$class$}\n"
      " */\n"
      "$class$.deserializeBinaryFromReader = function(msg, reader) {\n"
      "  while (reader.nextField()) {\n",
      "class", GetMessagePath(options, desc));
    printer->Print(
        "    if (reader.isEndGroup()) {\n"
        "      break;\n"
        "    }\n"
        "    var field = reader.getFieldNumber();\n"
        "    switch (field) {\n");

    for (int i = 0; i < desc->field_count(); i++) {
      if (!IgnoreField(desc->field(i))) {
        GenerateClassDeserializeBinaryField(options, printer, desc->field(i));
      }
    }

    printer->Print("    default:\n");
    if (IsExtendable(desc)) {
      printer->Print(
          "      jspb.Message.readBinaryExtension(msg, reader,\n"
          "        $extobj$Binary,\n"
          "        $class$.prototype.getExtension,\n"
          "        $class$.prototype.setExtension);\n"
          "      break;\n"
          "    }\n",
          "extobj", JSExtensionsObjectName(options, desc->file(), desc),
          "class", GetMessagePath(options, desc));
    } else {
      printer->Print(
          "      reader.skipField();\n"
          "      break;\n"
          "    }\n");
    }

  printer->Print(
      "  }\n"
      "  return msg;\n"
      "};\n"
      "\n"
      "\n");
}

void Generator::GenerateClassDeserializeBinaryField(
    const GeneratorOptions& options, io::Printer* printer,
    const FieldDescriptor* field) const {
  printer->Print("    case $num$:\n", "num", StrCat(field->number()));

  if (field->is_map()) {
    const FieldDescriptor* key_field = MapFieldKey(field);
    const FieldDescriptor* value_field = MapFieldValue(field);
    printer->Print(
        "      var value = msg.get$name$();\n"
        "      reader.readMessage(value, function(message, reader) {\n",
        "name", JSGetterName(options, field));

    printer->Print(
        "        jspb.Map.deserializeBinary(message, reader, "
        "$keyReaderFn$, $valueReaderFn$",
        "keyReaderFn", JSBinaryReaderMethodName(options, key_field),
        "valueReaderFn", JSBinaryReaderMethodName(options, value_field));

    if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) {
      printer->Print(", $messageType$.deserializeBinaryFromReader",
                     "messageType",
                     GetMessagePath(options, value_field->message_type()));
    } else {
      printer->Print(", null");
    }
    printer->Print(", $defaultKey$", "defaultKey", JSFieldDefault(key_field));
    printer->Print(");\n");
    printer->Print("         });\n");
  } else {
    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
      printer->Print(
          "      var value = new $fieldclass$;\n"
          "      reader.read$msgOrGroup$($grpfield$value,"
          "$fieldclass$.deserializeBinaryFromReader);\n",
          "fieldclass", SubmessageTypeRef(options, field), "msgOrGroup",
          (field->type() == FieldDescriptor::TYPE_GROUP) ? "Group" : "Message",
          "grpfield",
          (field->type() == FieldDescriptor::TYPE_GROUP)
              ? (StrCat(field->number()) + ", ")
              : "");
    } else {
      printer->Print(
          "      var value = /** @type {$fieldtype$} */ "
          "(reader.read$reader$());\n",
          "fieldtype",
          JSFieldTypeAnnotation(options, field, false, true,
                                /* singular_if_not_packed */ true, BYTES_U8),
          "reader",
          JSBinaryReadWriteMethodName(field, /* is_writer = */ false));
    }

    if (field->is_repeated() && !field->is_packed()) {
      printer->Print(
          "      msg.add$name$(value);\n", "name",
          JSGetterName(options, field, BYTES_DEFAULT, /* drop_list = */ true));
    } else {
      // Singular fields, and packed repeated fields, receive a |value| either
      // as the field's value or as the array of all the field's values; set
      // this as the field's value directly.
      printer->Print("      msg.set$name$(value);\n", "name",
                     JSGetterName(options, field));
    }
  }

  printer->Print("      break;\n");
}

void Generator::GenerateClassSerializeBinary(const GeneratorOptions& options,
                                             io::Printer* printer,
                                             const Descriptor* desc) const {
  printer->Print(
      "/**\n"
      " * Serializes the message to binary data (in protobuf wire format).\n"
      " * @return {!Uint8Array}\n"
      " */\n"
      "$class$.prototype.serializeBinary = function() {\n"
      "  var writer = new jspb.BinaryWriter();\n"
      "  $class$.serializeBinaryToWriter(this, writer);\n"
      "  return writer.getResultBuffer();\n"
      "};\n"
      "\n"
      "\n"
      "/**\n"
      " * Serializes the given message to binary data (in protobuf wire\n"
      " * format), writing to the given BinaryWriter.\n"
      " * @param {!$class$} message\n"
      " * @param {!jspb.BinaryWriter} writer\n"
      " * @suppress {unusedLocalVariables} f is only used for nested messages\n"
      " */\n"
      "$class$.serializeBinaryToWriter = function(message, "
      "writer) {\n"
      "  var f = undefined;\n",
      "class", GetMessagePath(options, desc));

  for (int i = 0; i < desc->field_count(); i++) {
    if (!IgnoreField(desc->field(i))) {
      GenerateClassSerializeBinaryField(options, printer, desc->field(i));
    }
  }

  if (IsExtendable(desc)) {
    printer->Print(
        "  jspb.Message.serializeBinaryExtensions(message, writer,\n"
        "    $extobj$Binary, $class$.prototype.getExtension);\n",
        "extobj", JSExtensionsObjectName(options, desc->file(), desc), "class",
        GetMessagePath(options, desc));
  }

  printer->Print(
      "};\n"
      "\n"
      "\n");
}

void Generator::GenerateClassSerializeBinaryField(
    const GeneratorOptions& options, io::Printer* printer,
    const FieldDescriptor* field) const {
  if (HasFieldPresence(options, field) &&
      field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
    std::string typed_annotation =
        JSFieldTypeAnnotation(options, field,
                              /* is_setter_argument = */ false,
                              /* force_present = */ false,
                              /* singular_if_not_packed = */ false,
                              /* bytes_mode = */ BYTES_DEFAULT);
    printer->Print(
        "  f = /** @type {$type$} */ "
        "(jspb.Message.getField(message, $index$));\n",
        "index", JSFieldIndex(field), "type", typed_annotation);
  } else {
    printer->Print(
        "  f = message.get$name$($nolazy$);\n", "name",
        JSGetterName(options, field, BYTES_U8),
        // No lazy creation for maps containers -- fastpath the empty case.
        "nolazy", field->is_map() ? "true" : "");
  }

  // Print an `if (condition)` statement that evaluates to true if the field
  // goes on the wire.
  if (field->is_map()) {
    printer->Print("  if (f && f.getLength() > 0) {\n");
  } else if (field->is_repeated()) {
    printer->Print("  if (f.length > 0) {\n");
  } else {
    if (HasFieldPresence(options, field)) {
      printer->Print("  if (f != null) {\n");
    } else {
      // No field presence: serialize onto the wire only if value is
      // non-default.  Defaults are documented here:
      // https://goto.google.com/lhdfm
      switch (field->cpp_type()) {
        case FieldDescriptor::CPPTYPE_INT32:
        case FieldDescriptor::CPPTYPE_INT64:
        case FieldDescriptor::CPPTYPE_UINT32:
        case FieldDescriptor::CPPTYPE_UINT64: {
          if (IsIntegralFieldWithStringJSType(field)) {
            // We can use `parseInt` here even though it will not be precise for
            // 64-bit quantities because we are only testing for zero/nonzero,
            // and JS numbers (64-bit floating point values, i.e., doubles) are
            // integer-precise in the range that includes zero.
            printer->Print("  if (parseInt(f, 10) !== 0) {\n");
          } else {
            printer->Print("  if (f !== 0) {\n");
          }
          break;
        }

        case FieldDescriptor::CPPTYPE_ENUM:
        case FieldDescriptor::CPPTYPE_FLOAT:
        case FieldDescriptor::CPPTYPE_DOUBLE:
          printer->Print("  if (f !== 0.0) {\n");
          break;
        case FieldDescriptor::CPPTYPE_BOOL:
          printer->Print("  if (f) {\n");
          break;
        case FieldDescriptor::CPPTYPE_STRING:
          printer->Print("  if (f.length > 0) {\n");
          break;
        default:
          assert(false);
          break;
      }
    }
  }

  // Write the field on the wire.
  if (field->is_map()) {
    const FieldDescriptor* key_field = MapFieldKey(field);
    const FieldDescriptor* value_field = MapFieldValue(field);
    printer->Print(
        "    f.serializeBinary($index$, writer, "
        "$keyWriterFn$, $valueWriterFn$",
        "index", StrCat(field->number()), "keyWriterFn",
        JSBinaryWriterMethodName(options, key_field), "valueWriterFn",
        JSBinaryWriterMethodName(options, value_field));

    if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) {
      printer->Print(", $messageType$.serializeBinaryToWriter", "messageType",
                     GetMessagePath(options, value_field->message_type()));
    }

    printer->Print(");\n");
  } else {
    printer->Print(
        "    writer.write$method$(\n"
        "      $index$,\n"
        "      f",
        "method", JSBinaryReadWriteMethodName(field, /* is_writer = */ true),
        "index", StrCat(field->number()));

    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
        !field->is_map()) {
      printer->Print(
          ",\n"
          "      $submsg$.serializeBinaryToWriter\n",
          "submsg", SubmessageTypeRef(options, field));
    } else {
      printer->Print("\n");
    }

    printer->Print("    );\n");
  }

  // Close the `if`.
  printer->Print("  }\n");
}

void Generator::GenerateEnum(const GeneratorOptions& options,
                             io::Printer* printer,
                             const EnumDescriptor* enumdesc) const {
  printer->Print(
      "/**\n"
      " * @enum {number}\n"
      " */\n"
      "$enumprefix$$name$ = {\n",
      "enumprefix", GetEnumPathPrefix(options, enumdesc), "name",
      enumdesc->name());
  printer->Annotate("name", enumdesc);

  for (int i = 0; i < enumdesc->value_count(); i++) {
    const EnumValueDescriptor* value = enumdesc->value(i);
    printer->Print("  $name$: $value$$comma$\n", "name",
                   ToEnumCase(value->name()), "value",
                   StrCat(value->number()), "comma",
                   (i == enumdesc->value_count() - 1) ? "" : ",");
    printer->Annotate("name", value);
  }

  printer->Print(
      "};\n"
      "\n");
}

void Generator::GenerateExtension(const GeneratorOptions& options,
                                  io::Printer* printer,
                                  const FieldDescriptor* field) const {
  std::string extension_scope =
      (field->extension_scope()
           ? GetMessagePath(options, field->extension_scope())
           : GetNamespace(options, field->file()));

  const std::string extension_object_name = JSObjectFieldName(options, field);
  printer->Print(
      "\n"
      "/**\n"
      " * A tuple of {field number, class constructor} for the extension\n"
      " * field named `$nameInComment$`.\n"
      " * @type {!jspb.ExtensionFieldInfo<$extensionType$>}\n"
      " */\n"
      "$class$.$name$ = new jspb.ExtensionFieldInfo(\n",
      "nameInComment", extension_object_name, "name", extension_object_name,
      "class", extension_scope, "extensionType",
      JSFieldTypeAnnotation(options, field,
                            /* is_setter_argument = */ false,
                            /* force_present = */ true,
                            /* singular_if_not_packed = */ false));
  printer->Annotate("name", field);
  printer->Print(
      "    $index$,\n"
      "    {$name$: 0},\n"
      "    $ctor$,\n"
      "     /** @type {?function((boolean|undefined),!jspb.Message=): "
      "!Object} */ (\n"
      "         $toObject$),\n"
      "    $repeated$);\n",
      "index", StrCat(field->number()), "name", extension_object_name,
      "ctor",
      (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE
           ? SubmessageTypeRef(options, field)
           : std::string("null")),
      "toObject",
      (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE
           ? (SubmessageTypeRef(options, field) + ".toObject")
           : std::string("null")),
      "repeated", (field->is_repeated() ? "1" : "0"));

  printer->Print(
      "\n"
      "$extendName$Binary[$index$] = new jspb.ExtensionFieldBinaryInfo(\n"
      "    $class$.$name$,\n"
      "    $binaryReaderFn$,\n"
      "    $binaryWriterFn$,\n"
      "    $binaryMessageSerializeFn$,\n"
      "    $binaryMessageDeserializeFn$,\n",
      "extendName",
      JSExtensionsObjectName(options, field->file(), field->containing_type()),
      "index", StrCat(field->number()), "class", extension_scope, "name",
      extension_object_name, "binaryReaderFn",
      JSBinaryReaderMethodName(options, field), "binaryWriterFn",
      JSBinaryWriterMethodName(options, field), "binaryMessageSerializeFn",
      (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE)
          ? (SubmessageTypeRef(options, field) + ".serializeBinaryToWriter")
          : "undefined",
      "binaryMessageDeserializeFn",
      (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE)
          ? (SubmessageTypeRef(options, field) + ".deserializeBinaryFromReader")
          : "undefined");

  printer->Print("    $isPacked$);\n", "isPacked",
                 (field->is_packed() ? "true" : "false"));

  printer->Print(
      "// This registers the extension field with the extended class, so that\n"
      "// toObject() will function correctly.\n"
      "$extendName$[$index$] = $class$.$name$;\n"
      "\n",
      "extendName",
      JSExtensionsObjectName(options, field->file(), field->containing_type()),
      "index", StrCat(field->number()), "class", extension_scope, "name",
      extension_object_name);
}

bool GeneratorOptions::ParseFromOptions(
    const std::vector<std::pair<std::string, std::string> >& options,
    std::string* error) {
  for (int i = 0; i < options.size(); i++) {
    if (options[i].first == "add_require_for_enums") {
      if (options[i].second != "") {
        *error = "Unexpected option value for add_require_for_enums";
        return false;
      }
      add_require_for_enums = true;
    } else if (options[i].first == "binary") {
      if (options[i].second != "") {
        *error = "Unexpected option value for binary";
        return false;
      }
      binary = true;
    } else if (options[i].first == "testonly") {
      if (options[i].second != "") {
        *error = "Unexpected option value for testonly";
        return false;
      }
      testonly = true;
    } else if (options[i].first == "error_on_name_conflict") {
      if (options[i].second != "") {
        *error = "Unexpected option value for error_on_name_conflict";
        return false;
      }
      error_on_name_conflict = true;
    } else if (options[i].first == "output_dir") {
      output_dir = options[i].second;
    } else if (options[i].first == "namespace_prefix") {
      namespace_prefix = options[i].second;
    } else if (options[i].first == "library") {
      library = options[i].second;
    } else if (options[i].first == "import_style") {
      if (options[i].second == "closure") {
        import_style = kImportClosure;
      } else if (options[i].second == "commonjs") {
        import_style = kImportCommonJs;
      } else if (options[i].second == "commonjs_strict") {
        import_style = kImportCommonJsStrict;
      } else if (options[i].second == "browser") {
        import_style = kImportBrowser;
      } else if (options[i].second == "es6") {
        import_style = kImportEs6;
      } else {
        *error = "Unknown import style " + options[i].second + ", expected " +
                 "one of: closure, commonjs, browser, es6.";
      }
    } else if (options[i].first == "extension") {
      extension = options[i].second;
    } else if (options[i].first == "one_output_file_per_input_file") {
      if (!options[i].second.empty()) {
        *error = "Unexpected option value for one_output_file_per_input_file";
        return false;
      }
      one_output_file_per_input_file = true;
    } else if (options[i].first == "annotate_code") {
      if (!options[i].second.empty()) {
        *error = "Unexpected option value for annotate_code";
        return false;
      }
      annotate_code = true;
    } else {
      // Assume any other option is an output directory, as long as it is a bare
      // `key` rather than a `key=value` option.
      if (options[i].second != "") {
        *error = "Unknown option: " + options[i].first;
        return false;
      }
      output_dir = options[i].first;
    }
  }

  if (import_style != kImportClosure &&
      (add_require_for_enums || testonly || !library.empty() ||
       error_on_name_conflict || extension != ".js" ||
       one_output_file_per_input_file)) {
    *error =
        "The add_require_for_enums, testonly, library, error_on_name_conflict, "
        "extension, and one_output_file_per_input_file options should only be "
        "used for import_style=closure";
    return false;
  }

  return true;
}

GeneratorOptions::OutputMode GeneratorOptions::output_mode() const {
  // We use one output file per input file if we are not using Closure or if
  // this is explicitly requested.
  if (import_style != kImportClosure || one_output_file_per_input_file) {
    return kOneOutputFilePerInputFile;
  }

  // If a library name is provided, we put everything in that one file.
  if (!library.empty()) {
    return kEverythingInOneFile;
  }

  // Otherwise, we create one output file per SCC.
  return kOneOutputFilePerSCC;
}

void Generator::GenerateFilesInDepOrder(
    const GeneratorOptions& options, io::Printer* printer,
    const std::vector<const FileDescriptor*>& files) const {
  // Build a std::set over all files so that the DFS can detect when it recurses
  // into a dep not specified in the user's command line.
  std::set<const FileDescriptor*> all_files(files.begin(), files.end());
  // Track the in-progress set of files that have been generated already.
  std::set<const FileDescriptor*> generated;
  for (int i = 0; i < files.size(); i++) {
    GenerateFileAndDeps(options, printer, files[i], &all_files, &generated);
  }
}

void Generator::GenerateFileAndDeps(
    const GeneratorOptions& options, io::Printer* printer,
    const FileDescriptor* root, std::set<const FileDescriptor*>* all_files,
    std::set<const FileDescriptor*>* generated) const {
  // Skip if already generated.
  if (generated->find(root) != generated->end()) {
    return;
  }
  generated->insert(root);

  // Generate all dependencies before this file's content.
  for (int i = 0; i < root->dependency_count(); i++) {
    const FileDescriptor* dep = root->dependency(i);
    GenerateFileAndDeps(options, printer, dep, all_files, generated);
  }

  // Generate this file's content.  Only generate if the file is part of the
  // original set requested to be generated; i.e., don't take all transitive
  // deps down to the roots.
  if (all_files->find(root) != all_files->end()) {
    GenerateClassesAndEnums(options, printer, root);
  }
}

bool Generator::GenerateFile(const FileDescriptor* file,
                             const GeneratorOptions& options,
                             GeneratorContext* context,
                             bool use_short_name) const {
  std::string filename =
      options.output_dir + "/" +
      GetJSFilename(options, use_short_name
                                 ? file->name().substr(file->name().rfind('/'))
                                 : file->name());
  std::unique_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
  GOOGLE_CHECK(output);
  GeneratedCodeInfo annotations;
  io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
      &annotations);
  io::Printer printer(output.get(), '$',
                      options.annotate_code ? &annotation_collector : nullptr);

  GenerateFile(options, &printer, file);

  if (printer.failed()) {
    return false;
  }

  if (options.annotate_code) {
    EmbedCodeAnnotations(annotations, &printer);
  }

  return true;
}

void Generator::GenerateFile(const GeneratorOptions& options,
                             io::Printer* printer,
                             const FileDescriptor* file) const {
  GenerateHeader(options, printer);

  // Generate "require" statements.
  if ((options.import_style == GeneratorOptions::kImportCommonJs ||
       options.import_style == GeneratorOptions::kImportCommonJsStrict)) {
    printer->Print("var jspb = require('google-protobuf');\n");
    printer->Print("var goog = jspb;\n");

    // Do not use global scope in strict mode
    if (options.import_style == GeneratorOptions::kImportCommonJsStrict) {
      printer->Print("var proto = {};\n\n");
    } else {
      printer->Print("var global = Function('return this')();\n\n");
    }

    for (int i = 0; i < file->dependency_count(); i++) {
      const std::string& name = file->dependency(i)->name();
      printer->Print(
          "var $alias$ = require('$file$');\n"
          "goog.object.extend(proto, $alias$);\n",
          "alias", ModuleAlias(name), "file",
          GetRootPath(file->name(), name) + GetJSFilename(options, name));
    }
  }

  std::set<std::string> provided;
  std::set<const FieldDescriptor*> extensions;
  for (int i = 0; i < file->extension_count(); i++) {
    // We honor the jspb::ignore option here only when working with
    // Closure-style imports. Use of this option is discouraged and so we want
    // to avoid adding new support for it.
    if (options.import_style == GeneratorOptions::kImportClosure &&
        IgnoreField(file->extension(i))) {
      continue;
    }
    provided.insert(GetNamespace(options, file) + "." +
                    JSObjectFieldName(options, file->extension(i)));
    extensions.insert(file->extension(i));
  }

  FindProvidesForFile(options, printer, file, &provided);
  GenerateProvides(options, printer, &provided);
  std::vector<const FileDescriptor*> files;
  files.push_back(file);
  if (options.import_style == GeneratorOptions::kImportClosure) {
    GenerateRequiresForLibrary(options, printer, files, &provided);
  }

  GenerateClassesAndEnums(options, printer, file);

  // Generate code for top-level extensions. Extensions nested inside messages
  // are emitted inside GenerateClassesAndEnums().
  for (std::set<const FieldDescriptor*>::const_iterator it = extensions.begin();
       it != extensions.end(); ++it) {
    GenerateExtension(options, printer, *it);
  }

  // if provided is empty, do not export anything
  if (options.import_style == GeneratorOptions::kImportCommonJs &&
      !provided.empty()) {
    printer->Print("goog.object.extend(exports, $package$);\n", "package",
                   GetNamespace(options, file));
  } else if (options.import_style == GeneratorOptions::kImportCommonJsStrict) {
    printer->Print("goog.object.extend(exports, proto);\n", "package",
                   GetNamespace(options, file));
  }

  // Emit well-known type methods.
  for (FileToc* toc = well_known_types_js; toc->name != NULL; toc++) {
    std::string name = std::string("google/protobuf/") + toc->name;
    if (name == StripProto(file->name()) + ".js") {
      printer->Print(toc->data);
    }
  }
}

bool Generator::GenerateAll(const std::vector<const FileDescriptor*>& files,
                            const std::string& parameter,
                            GeneratorContext* context,
                            std::string* error) const {
  std::vector<std::pair<std::string, std::string> > option_pairs;
  ParseGeneratorParameter(parameter, &option_pairs);
  GeneratorOptions options;
  if (!options.ParseFromOptions(option_pairs, error)) {
    return false;
  }


  if (options.output_mode() == GeneratorOptions::kEverythingInOneFile) {
    // All output should go in a single file.
    std::string filename = options.output_dir + "/" + options.library +
                           options.GetFileNameExtension();
    std::unique_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
    GOOGLE_CHECK(output.get());
    io::Printer printer(output.get(), '$');

    // Pull out all extensions -- we need these to generate all
    // provides/requires.
    std::vector<const FieldDescriptor*> extensions;
    for (int i = 0; i < files.size(); i++) {
      for (int j = 0; j < files[i]->extension_count(); j++) {
        const FieldDescriptor* extension = files[i]->extension(j);
        extensions.push_back(extension);
      }
    }

    GenerateHeader(options, &printer);

    std::set<std::string> provided;
    FindProvides(options, &printer, files, &provided);
    FindProvidesForFields(options, &printer, extensions, &provided);
    GenerateProvides(options, &printer, &provided);
    GenerateTestOnly(options, &printer);
    GenerateRequiresForLibrary(options, &printer, files, &provided);

    GenerateFilesInDepOrder(options, &printer, files);

    for (int i = 0; i < extensions.size(); i++) {
      if (ShouldGenerateExtension(extensions[i])) {
        GenerateExtension(options, &printer, extensions[i]);
      }
    }

    if (printer.failed()) {
      return false;
    }
  } else if (options.output_mode() == GeneratorOptions::kOneOutputFilePerSCC) {
    std::set<const Descriptor*> have_printed;
    SCCAnalyzer<DepsGenerator> analyzer;
    std::map<const void*, std::string> allowed_map;
    if (!GenerateJspbAllowedMap(options, files, &allowed_map, &analyzer,
                                error)) {
      return false;
    }

    bool generated = false;
    for (int i = 0; i < files.size(); i++) {
      const FileDescriptor* file = files[i];
      // Force well known type to generate in a whole file.
      if (IsWellKnownTypeFile(file)) {
        if (!GenerateFile(file, options, context, true)) {
          return false;
        }
        generated = true;
        continue;
      }
      for (int j = 0; j < file->message_type_count(); j++) {
        const Descriptor* desc = file->message_type(j);
        if (have_printed.count(desc) ||
            allowed_map.count(analyzer.GetSCC(desc)) == 0) {
          continue;
        }

        generated = true;
        const SCC* scc = analyzer.GetSCC(desc);
        const std::string& filename = allowed_map[scc];
        std::unique_ptr<io::ZeroCopyOutputStream> output(
            context->Open(filename));
        GOOGLE_CHECK(output.get());
        GeneratedCodeInfo annotations;
        io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
            &annotations);
        io::Printer printer(
            output.get(), '$',
            options.annotate_code ? &annotation_collector : nullptr);

        GenerateHeader(options, &printer);

        std::set<std::string> provided;
        for (auto one_desc : scc->descriptors) {
          if (one_desc->containing_type() == nullptr) {
            FindProvidesForMessage(options, &printer, one_desc, &provided);
          }
        }
        GenerateProvides(options, &printer, &provided);
        GenerateTestOnly(options, &printer);
        GenerateRequiresForSCC(options, &printer, scc, &provided);

        for (auto one_desc : scc->descriptors) {
          if (one_desc->containing_type() == nullptr) {
            GenerateClassConstructorAndDeclareExtensionFieldInfo(
                options, &printer, one_desc);
          }
        }
        for (auto one_desc : scc->descriptors) {
          if (one_desc->containing_type() == nullptr) {
            GenerateClass(options, &printer, one_desc);
          }
        }

        for (auto one_desc : scc->descriptors) {
          have_printed.insert(one_desc);
        }

        if (printer.failed()) {
          return false;
        }
        if (options.annotate_code) {
          EmbedCodeAnnotations(annotations, &printer);
        }
      }
      for (int j = 0; j < file->enum_type_count(); j++) {
        const EnumDescriptor* enumdesc = file->enum_type(j);
        if (allowed_map.count(enumdesc) == 0) {
          continue;
        }

        generated = true;
        const std::string& filename = allowed_map[enumdesc];
        std::unique_ptr<io::ZeroCopyOutputStream> output(
            context->Open(filename));
        GOOGLE_CHECK(output.get());
        GeneratedCodeInfo annotations;
        io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
            &annotations);
        io::Printer printer(
            output.get(), '$',
            options.annotate_code ? &annotation_collector : nullptr);

        GenerateHeader(options, &printer);

        std::set<std::string> provided;
        FindProvidesForEnum(options, &printer, enumdesc, &provided);
        GenerateProvides(options, &printer, &provided);
        GenerateTestOnly(options, &printer);

        GenerateEnum(options, &printer, enumdesc);

        if (printer.failed()) {
          return false;
        }
        if (options.annotate_code) {
          EmbedCodeAnnotations(annotations, &printer);
        }
      }
      // File-level extensions (message-level extensions are generated under
      // the enclosing message).
      if (allowed_map.count(file) == 1) {
        generated = true;
        const std::string& filename = allowed_map[file];

        std::unique_ptr<io::ZeroCopyOutputStream> output(
            context->Open(filename));
        GOOGLE_CHECK(output.get());
        GeneratedCodeInfo annotations;
        io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
            &annotations);
        io::Printer printer(
            output.get(), '$',
            options.annotate_code ? &annotation_collector : nullptr);

        GenerateHeader(options, &printer);

        std::set<std::string> provided;
        std::vector<const FieldDescriptor*> fields;

        for (int j = 0; j < files[i]->extension_count(); j++) {
          if (ShouldGenerateExtension(files[i]->extension(j))) {
            fields.push_back(files[i]->extension(j));
          }
        }

        FindProvidesForFields(options, &printer, fields, &provided);
        GenerateProvides(options, &printer, &provided);
        GenerateTestOnly(options, &printer);
        GenerateRequiresForExtensions(options, &printer, fields, &provided);

        for (int j = 0; j < files[i]->extension_count(); j++) {
          if (ShouldGenerateExtension(files[i]->extension(j))) {
            GenerateExtension(options, &printer, files[i]->extension(j));
          }
        }
        if (options.annotate_code) {
          EmbedCodeAnnotations(annotations, &printer);
        }
      }
    }
    if (!generated) {
      std::string filename = options.output_dir + "/" +
                             "empty_no_content_void_file" +
                             options.GetFileNameExtension();
      std::unique_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
    }
  } else /* options.output_mode() == kOneOutputFilePerInputFile */ {
    // Generate one output file per input (.proto) file.

    for (int i = 0; i < files.size(); i++) {
      const FileDescriptor* file = files[i];
      if (!GenerateFile(file, options, context, false)) {
        return false;
      }
    }
  }
  return true;
}

}  // namespace js
}  // namespace compiler
}  // namespace protobuf
}  // namespace google
