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

// Author: kenton@google.com (Kenton Varda)
//  Based on original Protocol Buffers design by
//  Sanjay Ghemawat, Jeff Dean, and others.

#include <functional>
#include <limits>
#include <map>
#include <queue>
#include <unordered_set>
#include <vector>

#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/descriptor.h>

#include <google/protobuf/compiler/scc.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/wire_format_lite.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>


#include <google/protobuf/stubs/hash.h>

#include <google/protobuf/port_def.inc>

namespace google {
namespace protobuf {
namespace compiler {
namespace cpp {

namespace {

static const char kAnyMessageName[] = "Any";
static const char kAnyProtoFile[] = "google/protobuf/any.proto";
static const char kGoogleProtobufPrefix[] = "google/protobuf/";

std::string DotsToColons(const std::string& name) {
  return StringReplace(name, ".", "::", true);
}

static const char* const kKeywordList[] = {  //
    "NULL",
    "alignas",
    "alignof",
    "and",
    "and_eq",
    "asm",
    "auto",
    "bitand",
    "bitor",
    "bool",
    "break",
    "case",
    "catch",
    "char",
    "class",
    "compl",
    "const",
    "constexpr",
    "const_cast",
    "continue",
    "decltype",
    "default",
    "delete",
    "do",
    "double",
    "dynamic_cast",
    "else",
    "enum",
    "explicit",
    "export",
    "extern",
    "false",
    "float",
    "for",
    "friend",
    "goto",
    "if",
    "inline",
    "int",
    "long",
    "mutable",
    "namespace",
    "new",
    "noexcept",
    "not",
    "not_eq",
    "nullptr",
    "operator",
    "or",
    "or_eq",
    "private",
    "protected",
    "public",
    "register",
    "reinterpret_cast",
    "return",
    "short",
    "signed",
    "sizeof",
    "static",
    "static_assert",
    "static_cast",
    "struct",
    "switch",
    "template",
    "this",
    "thread_local",
    "throw",
    "true",
    "try",
    "typedef",
    "typeid",
    "typename",
    "union",
    "unsigned",
    "using",
    "virtual",
    "void",
    "volatile",
    "wchar_t",
    "while",
    "xor",
    "xor_eq"};

static std::unordered_set<std::string>* MakeKeywordsMap() {
  auto* result = new std::unordered_set<std::string>();
  for (const auto keyword : kKeywordList) {
    result->emplace(keyword);
  }
  return result;
}

static std::unordered_set<std::string>& kKeywords = *MakeKeywordsMap();

// Returns whether the provided descriptor has an extension. This includes its
// nested types.
bool HasExtension(const Descriptor* descriptor) {
  if (descriptor->extension_count() > 0) {
    return true;
  }
  for (int i = 0; i < descriptor->nested_type_count(); ++i) {
    if (HasExtension(descriptor->nested_type(i))) {
      return true;
    }
  }
  return false;
}

// Encode [0..63] as 'A'-'Z', 'a'-'z', '0'-'9', '_'
char Base63Char(int value) {
  GOOGLE_CHECK_GE(value, 0);
  if (value < 26) return 'A' + value;
  value -= 26;
  if (value < 26) return 'a' + value;
  value -= 26;
  if (value < 10) return '0' + value;
  GOOGLE_CHECK_EQ(value, 10);
  return '_';
}

// Given a c identifier has 63 legal characters we can't implement base64
// encoding. So we return the k least significant "digits" in base 63.
template <typename I>
std::string Base63(I n, int k) {
  std::string res;
  while (k-- > 0) {
    res += Base63Char(static_cast<int>(n % 63));
    n /= 63;
  }
  return res;
}

std::string IntTypeName(const Options& options, const std::string& type) {
  if (options.opensource_runtime) {
    return "::PROTOBUF_NAMESPACE_ID::" + type;
  } else {
    return "::" + type;
  }
}

void SetIntVar(const Options& options, const std::string& type,
               std::map<std::string, std::string>* variables) {
  (*variables)[type] = IntTypeName(options, type);
}

}  // namespace

void SetCommonVars(const Options& options,
                   std::map<std::string, std::string>* variables) {
  (*variables)["proto_ns"] = ProtobufNamespace(options);

  // Warning: there is some clever naming/splitting here to avoid extract script
  // rewrites.  The names of these variables must not be things that the extract
  // script will rewrite.  That's why we use "CHK" (for example) instead of
  // "GOOGLE_CHECK".
  if (options.opensource_runtime) {
    (*variables)["GOOGLE_PROTOBUF"] = "GOOGLE_PROTOBUF";
    (*variables)["CHK"] = "GOOGLE_CHECK";
    (*variables)["DCHK"] = "GOOGLE_DCHECK";
  } else {
    // These values are things the extract script would rewrite if we did not
    // split them.  It might not strictly matter since we don't generate google3
    // code in open-source.  But it's good to prevent surprising things from
    // happening.
    (*variables)["GOOGLE_PROTOBUF"] =
        "GOOGLE3"
        "_PROTOBUF";
    (*variables)["CHK"] =
        "CH"
        "ECK";
    (*variables)["DCHK"] =
        "DCH"
        "ECK";
  }

  SetIntVar(options, "int8", variables);
  SetIntVar(options, "uint8", variables);
  SetIntVar(options, "uint32", variables);
  SetIntVar(options, "uint64", variables);
  SetIntVar(options, "int32", variables);
  SetIntVar(options, "int64", variables);
  (*variables)["string"] = "std::string";
}

std::string UnderscoresToCamelCase(const std::string& input,
                                   bool cap_next_letter) {
  std::string result;
  // Note:  I distrust ctype.h due to locales.
  for (int i = 0; i < input.size(); i++) {
    if ('a' <= input[i] && input[i] <= 'z') {
      if (cap_next_letter) {
        result += input[i] + ('A' - 'a');
      } else {
        result += input[i];
      }
      cap_next_letter = false;
    } else if ('A' <= input[i] && input[i] <= 'Z') {
      // Capital letters are left as-is.
      result += input[i];
      cap_next_letter = false;
    } else if ('0' <= input[i] && input[i] <= '9') {
      result += input[i];
      cap_next_letter = true;
    } else {
      cap_next_letter = true;
    }
  }
  return result;
}

const char kThickSeparator[] =
    "// ===================================================================\n";
const char kThinSeparator[] =
    "// -------------------------------------------------------------------\n";

bool CanInitializeByZeroing(const FieldDescriptor* field) {
  if (field->is_repeated() || field->is_extension()) return false;
  switch (field->cpp_type()) {
    case FieldDescriptor::CPPTYPE_ENUM:
      return field->default_value_enum()->number() == 0;
    case FieldDescriptor::CPPTYPE_INT32:
      return field->default_value_int32() == 0;
    case FieldDescriptor::CPPTYPE_INT64:
      return field->default_value_int64() == 0;
    case FieldDescriptor::CPPTYPE_UINT32:
      return field->default_value_uint32() == 0;
    case FieldDescriptor::CPPTYPE_UINT64:
      return field->default_value_uint64() == 0;
    case FieldDescriptor::CPPTYPE_FLOAT:
      return field->default_value_float() == 0;
    case FieldDescriptor::CPPTYPE_DOUBLE:
      return field->default_value_double() == 0;
    case FieldDescriptor::CPPTYPE_BOOL:
      return field->default_value_bool() == false;
    default:
      return false;
  }
}

std::string ClassName(const Descriptor* descriptor) {
  const Descriptor* parent = descriptor->containing_type();
  std::string res;
  if (parent) res += ClassName(parent) + "_";
  res += descriptor->name();
  if (IsMapEntryMessage(descriptor)) res += "_DoNotUse";
  return ResolveKeyword(res);
}

std::string ClassName(const EnumDescriptor* enum_descriptor) {
  if (enum_descriptor->containing_type() == nullptr) {
    return ResolveKeyword(enum_descriptor->name());
  } else {
    return ClassName(enum_descriptor->containing_type()) + "_" +
           enum_descriptor->name();
  }
}

std::string QualifiedClassName(const Descriptor* d, const Options& options) {
  return QualifiedFileLevelSymbol(d->file(), ClassName(d), options);
}

std::string QualifiedClassName(const EnumDescriptor* d,
                               const Options& options) {
  return QualifiedFileLevelSymbol(d->file(), ClassName(d), options);
}

std::string QualifiedClassName(const Descriptor* d) {
  return QualifiedClassName(d, Options());
}

std::string QualifiedClassName(const EnumDescriptor* d) {
  return QualifiedClassName(d, Options());
}

std::string Namespace(const std::string& package) {
  if (package.empty()) return "";
  return "::" + DotsToColons(package);
}

std::string Namespace(const FileDescriptor* d, const Options& options) {
  std::string ret = Namespace(d->package());
  if (IsWellKnownMessage(d) && options.opensource_runtime) {
    // Written with string concatenation to prevent rewriting of
    // ::google::protobuf.
    ret = StringReplace(ret,
                        "::google::"
                        "protobuf",
                        "PROTOBUF_NAMESPACE_ID", false);
  }
  return ret;
}

std::string Namespace(const Descriptor* d, const Options& options) {
  return Namespace(d->file(), options);
}

std::string Namespace(const FieldDescriptor* d, const Options& options) {
  return Namespace(d->file(), options);
}

std::string Namespace(const EnumDescriptor* d, const Options& options) {
  return Namespace(d->file(), options);
}

std::string DefaultInstanceName(const Descriptor* descriptor,
                                const Options& options) {
  return QualifiedFileLevelSymbol(
      descriptor->file(),
      "_" + ClassName(descriptor, false) + "_default_instance_", options);
}

std::string ReferenceFunctionName(const Descriptor* descriptor,
                                  const Options& options) {
  return QualifiedClassName(descriptor, options) + "_ReferenceStrong";
}

std::string SuperClassName(const Descriptor* descriptor,
                           const Options& options) {
  return "::" + ProtobufNamespace(options) +
         (HasDescriptorMethods(descriptor->file(), options) ? "::Message"
                                                            : "::MessageLite");
}

std::string ResolveKeyword(const string& name) {
  if (kKeywords.count(name) > 0) {
    return name + "_";
  }
  return name;
}

std::string FieldName(const FieldDescriptor* field) {
  std::string result = field->name();
  LowerString(&result);
  if (kKeywords.count(result) > 0) {
    result.append("_");
  }
  return result;
}

std::string EnumValueName(const EnumValueDescriptor* enum_value) {
  std::string result = enum_value->name();
  if (kKeywords.count(result) > 0) {
    result.append("_");
  }
  return result;
}

int EstimateAlignmentSize(const FieldDescriptor* field) {
  if (field == nullptr) return 0;
  if (field->is_repeated()) return 8;
  switch (field->cpp_type()) {
    case FieldDescriptor::CPPTYPE_BOOL:
      return 1;

    case FieldDescriptor::CPPTYPE_INT32:
    case FieldDescriptor::CPPTYPE_UINT32:
    case FieldDescriptor::CPPTYPE_ENUM:
    case FieldDescriptor::CPPTYPE_FLOAT:
      return 4;

    case FieldDescriptor::CPPTYPE_INT64:
    case FieldDescriptor::CPPTYPE_UINT64:
    case FieldDescriptor::CPPTYPE_DOUBLE:
    case FieldDescriptor::CPPTYPE_STRING:
    case FieldDescriptor::CPPTYPE_MESSAGE:
      return 8;
  }
  GOOGLE_LOG(FATAL) << "Can't get here.";
  return -1;  // Make compiler happy.
}

std::string FieldConstantName(const FieldDescriptor* field) {
  std::string field_name = UnderscoresToCamelCase(field->name(), true);
  std::string result = "k" + field_name + "FieldNumber";

  if (!field->is_extension() &&
      field->containing_type()->FindFieldByCamelcaseName(
          field->camelcase_name()) != field) {
    // This field's camelcase name is not unique.  As a hack, add the field
    // number to the constant name.  This makes the constant rather useless,
    // but what can we do?
    result += "_" + StrCat(field->number());
  }

  return result;
}

std::string FieldMessageTypeName(const FieldDescriptor* field,
                                 const Options& options) {
  // Note:  The Google-internal version of Protocol Buffers uses this function
  //   as a hook point for hacks to support legacy code.
  return QualifiedClassName(field->message_type(), options);
}

std::string StripProto(const std::string& filename) {
  if (HasSuffixString(filename, ".protodevel")) {
    return StripSuffixString(filename, ".protodevel");
  } else {
    return StripSuffixString(filename, ".proto");
  }
}

const char* PrimitiveTypeName(FieldDescriptor::CppType type) {
  switch (type) {
    case FieldDescriptor::CPPTYPE_INT32:
      return "::google::protobuf::int32";
    case FieldDescriptor::CPPTYPE_INT64:
      return "::google::protobuf::int64";
    case FieldDescriptor::CPPTYPE_UINT32:
      return "::google::protobuf::uint32";
    case FieldDescriptor::CPPTYPE_UINT64:
      return "::google::protobuf::uint64";
    case FieldDescriptor::CPPTYPE_DOUBLE:
      return "double";
    case FieldDescriptor::CPPTYPE_FLOAT:
      return "float";
    case FieldDescriptor::CPPTYPE_BOOL:
      return "bool";
    case FieldDescriptor::CPPTYPE_ENUM:
      return "int";
    case FieldDescriptor::CPPTYPE_STRING:
      return "std::string";
    case FieldDescriptor::CPPTYPE_MESSAGE:
      return nullptr;

      // No default because we want the compiler to complain if any new
      // CppTypes are added.
  }

  GOOGLE_LOG(FATAL) << "Can't get here.";
  return nullptr;
}

std::string PrimitiveTypeName(const Options& options,
                              FieldDescriptor::CppType type) {
  switch (type) {
    case FieldDescriptor::CPPTYPE_INT32:
      return IntTypeName(options, "int32");
    case FieldDescriptor::CPPTYPE_INT64:
      return IntTypeName(options, "int64");
    case FieldDescriptor::CPPTYPE_UINT32:
      return IntTypeName(options, "uint32");
    case FieldDescriptor::CPPTYPE_UINT64:
      return IntTypeName(options, "uint64");
    case FieldDescriptor::CPPTYPE_DOUBLE:
      return "double";
    case FieldDescriptor::CPPTYPE_FLOAT:
      return "float";
    case FieldDescriptor::CPPTYPE_BOOL:
      return "bool";
    case FieldDescriptor::CPPTYPE_ENUM:
      return "int";
    case FieldDescriptor::CPPTYPE_STRING:
      return "std::string";
    case FieldDescriptor::CPPTYPE_MESSAGE:
      return "";

      // No default because we want the compiler to complain if any new
      // CppTypes are added.
  }

  GOOGLE_LOG(FATAL) << "Can't get here.";
  return "";
}

const char* DeclaredTypeMethodName(FieldDescriptor::Type type) {
  switch (type) {
    case FieldDescriptor::TYPE_INT32:
      return "Int32";
    case FieldDescriptor::TYPE_INT64:
      return "Int64";
    case FieldDescriptor::TYPE_UINT32:
      return "UInt32";
    case FieldDescriptor::TYPE_UINT64:
      return "UInt64";
    case FieldDescriptor::TYPE_SINT32:
      return "SInt32";
    case FieldDescriptor::TYPE_SINT64:
      return "SInt64";
    case FieldDescriptor::TYPE_FIXED32:
      return "Fixed32";
    case FieldDescriptor::TYPE_FIXED64:
      return "Fixed64";
    case FieldDescriptor::TYPE_SFIXED32:
      return "SFixed32";
    case FieldDescriptor::TYPE_SFIXED64:
      return "SFixed64";
    case FieldDescriptor::TYPE_FLOAT:
      return "Float";
    case FieldDescriptor::TYPE_DOUBLE:
      return "Double";

    case FieldDescriptor::TYPE_BOOL:
      return "Bool";
    case FieldDescriptor::TYPE_ENUM:
      return "Enum";

    case FieldDescriptor::TYPE_STRING:
      return "String";
    case FieldDescriptor::TYPE_BYTES:
      return "Bytes";
    case FieldDescriptor::TYPE_GROUP:
      return "Group";
    case FieldDescriptor::TYPE_MESSAGE:
      return "Message";

      // No default because we want the compiler to complain if any new
      // types are added.
  }
  GOOGLE_LOG(FATAL) << "Can't get here.";
  return "";
}

std::string Int32ToString(int number) {
  if (number == kint32min) {
    // This needs to be special-cased, see explanation here:
    // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52661
    return StrCat(number + 1, " - 1");
  } else {
    return StrCat(number);
  }
}

std::string Int64ToString(const std::string& macro_prefix, int64 number) {
  if (number == kint64min) {
    // This needs to be special-cased, see explanation here:
    // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52661
    return StrCat(macro_prefix, "_LONGLONG(", number + 1, ") - 1");
  }
  return StrCat(macro_prefix, "_LONGLONG(", number, ")");
}

std::string UInt64ToString(const std::string& macro_prefix, uint64 number) {
  return StrCat(macro_prefix, "_ULONGLONG(", number, ")");
}

std::string DefaultValue(const FieldDescriptor* field) {
  switch (field->cpp_type()) {
    case FieldDescriptor::CPPTYPE_INT64:
      return Int64ToString("GG", field->default_value_int64());
    case FieldDescriptor::CPPTYPE_UINT64:
      return UInt64ToString("GG", field->default_value_uint64());
    default:
      return DefaultValue(Options(), field);
  }
}

std::string DefaultValue(const Options& options, const FieldDescriptor* field) {
  switch (field->cpp_type()) {
    case FieldDescriptor::CPPTYPE_INT32:
      return Int32ToString(field->default_value_int32());
    case FieldDescriptor::CPPTYPE_UINT32:
      return StrCat(field->default_value_uint32()) + "u";
    case FieldDescriptor::CPPTYPE_INT64:
      return Int64ToString("PROTOBUF", field->default_value_int64());
    case FieldDescriptor::CPPTYPE_UINT64:
      return UInt64ToString("PROTOBUF", field->default_value_uint64());
    case FieldDescriptor::CPPTYPE_DOUBLE: {
      double value = field->default_value_double();
      if (value == std::numeric_limits<double>::infinity()) {
        return "std::numeric_limits<double>::infinity()";
      } else if (value == -std::numeric_limits<double>::infinity()) {
        return "-std::numeric_limits<double>::infinity()";
      } else if (value != value) {
        return "std::numeric_limits<double>::quiet_NaN()";
      } else {
        return SimpleDtoa(value);
      }
    }
    case FieldDescriptor::CPPTYPE_FLOAT: {
      float value = field->default_value_float();
      if (value == std::numeric_limits<float>::infinity()) {
        return "std::numeric_limits<float>::infinity()";
      } else if (value == -std::numeric_limits<float>::infinity()) {
        return "-std::numeric_limits<float>::infinity()";
      } else if (value != value) {
        return "std::numeric_limits<float>::quiet_NaN()";
      } else {
        std::string float_value = SimpleFtoa(value);
        // If floating point value contains a period (.) or an exponent
        // (either E or e), then append suffix 'f' to make it a float
        // literal.
        if (float_value.find_first_of(".eE") != string::npos) {
          float_value.push_back('f');
        }
        return float_value;
      }
    }
    case FieldDescriptor::CPPTYPE_BOOL:
      return field->default_value_bool() ? "true" : "false";
    case FieldDescriptor::CPPTYPE_ENUM:
      // Lazy:  Generate a static_cast because we don't have a helper function
      //   that constructs the full name of an enum value.
      return strings::Substitute(
          "static_cast< $0 >($1)", ClassName(field->enum_type(), true),
          Int32ToString(field->default_value_enum()->number()));
    case FieldDescriptor::CPPTYPE_STRING:
      return "\"" +
             EscapeTrigraphs(CEscape(field->default_value_string())) +
             "\"";
    case FieldDescriptor::CPPTYPE_MESSAGE:
      return "*" + FieldMessageTypeName(field, options) +
             "::internal_default_instance()";
  }
  // Can't actually get here; make compiler happy.  (We could add a default
  // case above but then we wouldn't get the nice compiler warning when a
  // new type is added.)
  GOOGLE_LOG(FATAL) << "Can't get here.";
  return "";
}

// Convert a file name into a valid identifier.
std::string FilenameIdentifier(const std::string& filename) {
  std::string result;
  for (int i = 0; i < filename.size(); i++) {
    if (ascii_isalnum(filename[i])) {
      result.push_back(filename[i]);
    } else {
      // Not alphanumeric.  To avoid any possibility of name conflicts we
      // use the hex code for the character.
      StrAppend(&result, "_", strings::Hex(static_cast<uint8>(filename[i])));
    }
  }
  return result;
}

string UniqueName(const std::string& name, const std::string& filename,
                  const Options& options) {
  return name + "_" + FilenameIdentifier(filename);
}

// Return the qualified C++ name for a file level symbol.
std::string QualifiedFileLevelSymbol(const FileDescriptor* file,
                                     const std::string& name,
                                     const Options& options) {
  if (file->package().empty()) {
    return StrCat("::", name);
  }
  return StrCat(Namespace(file, options), "::", name);
}

// Escape C++ trigraphs by escaping question marks to \?
std::string EscapeTrigraphs(const std::string& to_escape) {
  return StringReplace(to_escape, "?", "\\?", true);
}

// Escaped function name to eliminate naming conflict.
std::string SafeFunctionName(const Descriptor* descriptor,
                             const FieldDescriptor* field,
                             const std::string& prefix) {
  // Do not use FieldName() since it will escape keywords.
  std::string name = field->name();
  LowerString(&name);
  std::string function_name = prefix + name;
  if (descriptor->FindFieldByName(function_name)) {
    // Single underscore will also make it conflicting with the private data
    // member. We use double underscore to escape function names.
    function_name.append("__");
  } else if (kKeywords.count(name) > 0) {
    // If the field name is a keyword, we append the underscore back to keep it
    // consistent with other function names.
    function_name.append("_");
  }
  return function_name;
}

bool IsStringInlined(const FieldDescriptor* descriptor,
                     const Options& options) {
  if (options.opensource_runtime) return false;

  // TODO(ckennelly): Handle inlining for any.proto.
  if (IsAnyMessage(descriptor->containing_type(), options)) return false;
  if (descriptor->containing_type()->options().map_entry()) return false;

  // Limit to proto2, as we rely on has bits to distinguish field presence for
  // release_$name$.  On proto3, we cannot use the address of the string
  // instance when the field has been inlined.
  if (!HasFieldPresence(descriptor->file())) return false;

  if (options.access_info_map) {
    if (descriptor->is_required()) return true;
  }
  return false;
}

static bool HasLazyFields(const Descriptor* descriptor,
                          const Options& options) {
  for (int field_idx = 0; field_idx < descriptor->field_count(); field_idx++) {
    if (IsLazy(descriptor->field(field_idx), options)) {
      return true;
    }
  }
  for (int idx = 0; idx < descriptor->extension_count(); idx++) {
    if (IsLazy(descriptor->extension(idx), options)) {
      return true;
    }
  }
  for (int idx = 0; idx < descriptor->nested_type_count(); idx++) {
    if (HasLazyFields(descriptor->nested_type(idx), options)) {
      return true;
    }
  }
  return false;
}

// Does the given FileDescriptor use lazy fields?
bool HasLazyFields(const FileDescriptor* file, const Options& options) {
  for (int i = 0; i < file->message_type_count(); i++) {
    const Descriptor* descriptor(file->message_type(i));
    if (HasLazyFields(descriptor, options)) {
      return true;
    }
  }
  for (int field_idx = 0; field_idx < file->extension_count(); field_idx++) {
    if (IsLazy(file->extension(field_idx), options)) {
      return true;
    }
  }
  return false;
}

static bool HasRepeatedFields(const Descriptor* descriptor) {
  for (int i = 0; i < descriptor->field_count(); ++i) {
    if (descriptor->field(i)->label() == FieldDescriptor::LABEL_REPEATED) {
      return true;
    }
  }
  for (int i = 0; i < descriptor->nested_type_count(); ++i) {
    if (HasRepeatedFields(descriptor->nested_type(i))) return true;
  }
  return false;
}

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

static bool IsStringPieceField(const FieldDescriptor* field,
                               const Options& options) {
  return field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
         EffectiveStringCType(field, options) == FieldOptions::STRING_PIECE;
}

static bool HasStringPieceFields(const Descriptor* descriptor,
                                 const Options& options) {
  for (int i = 0; i < descriptor->field_count(); ++i) {
    if (IsStringPieceField(descriptor->field(i), options)) return true;
  }
  for (int i = 0; i < descriptor->nested_type_count(); ++i) {
    if (HasStringPieceFields(descriptor->nested_type(i), options)) return true;
  }
  return false;
}

bool HasStringPieceFields(const FileDescriptor* file, const Options& options) {
  for (int i = 0; i < file->message_type_count(); ++i) {
    if (HasStringPieceFields(file->message_type(i), options)) return true;
  }
  return false;
}

static bool IsCordField(const FieldDescriptor* field, const Options& options) {
  return field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
         EffectiveStringCType(field, options) == FieldOptions::CORD;
}

static bool HasCordFields(const Descriptor* descriptor,
                          const Options& options) {
  for (int i = 0; i < descriptor->field_count(); ++i) {
    if (IsCordField(descriptor->field(i), options)) return true;
  }
  for (int i = 0; i < descriptor->nested_type_count(); ++i) {
    if (HasCordFields(descriptor->nested_type(i), options)) return true;
  }
  return false;
}

bool HasCordFields(const FileDescriptor* file, const Options& options) {
  for (int i = 0; i < file->message_type_count(); ++i) {
    if (HasCordFields(file->message_type(i), options)) return true;
  }
  return false;
}

static bool HasExtensionsOrExtendableMessage(const Descriptor* descriptor) {
  if (descriptor->extension_range_count() > 0) return true;
  if (descriptor->extension_count() > 0) return true;
  for (int i = 0; i < descriptor->nested_type_count(); ++i) {
    if (HasExtensionsOrExtendableMessage(descriptor->nested_type(i))) {
      return true;
    }
  }
  return false;
}

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

static bool HasMapFields(const Descriptor* descriptor) {
  for (int i = 0; i < descriptor->field_count(); ++i) {
    if (descriptor->field(i)->is_map()) {
      return true;
    }
  }
  for (int i = 0; i < descriptor->nested_type_count(); ++i) {
    if (HasMapFields(descriptor->nested_type(i))) return true;
  }
  return false;
}

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

static bool HasEnumDefinitions(const Descriptor* message_type) {
  if (message_type->enum_type_count() > 0) return true;
  for (int i = 0; i < message_type->nested_type_count(); ++i) {
    if (HasEnumDefinitions(message_type->nested_type(i))) return true;
  }
  return false;
}

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

bool IsStringOrMessage(const FieldDescriptor* field) {
  switch (field->cpp_type()) {
    case FieldDescriptor::CPPTYPE_INT32:
    case FieldDescriptor::CPPTYPE_INT64:
    case FieldDescriptor::CPPTYPE_UINT32:
    case FieldDescriptor::CPPTYPE_UINT64:
    case FieldDescriptor::CPPTYPE_DOUBLE:
    case FieldDescriptor::CPPTYPE_FLOAT:
    case FieldDescriptor::CPPTYPE_BOOL:
    case FieldDescriptor::CPPTYPE_ENUM:
      return false;
    case FieldDescriptor::CPPTYPE_STRING:
    case FieldDescriptor::CPPTYPE_MESSAGE:
      return true;
  }

  GOOGLE_LOG(FATAL) << "Can't get here.";
  return false;
}

FieldOptions::CType EffectiveStringCType(const FieldDescriptor* field,
                                         const Options& options) {
  GOOGLE_DCHECK(field->cpp_type() == FieldDescriptor::CPPTYPE_STRING);
  if (options.opensource_runtime) {
    // Open-source protobuf release only supports STRING ctype.
    return FieldOptions::STRING;
  } else {
    // Google-internal supports all ctypes.
    return field->options().ctype();
  }
}

bool IsAnyMessage(const FileDescriptor* descriptor, const Options& options) {
  return descriptor->name() == kAnyProtoFile;
}

bool IsAnyMessage(const Descriptor* descriptor, const Options& options) {
  return descriptor->name() == kAnyMessageName &&
         IsAnyMessage(descriptor->file(), options);
}

bool IsWellKnownMessage(const FileDescriptor* file) {
  static const std::unordered_set<std::string> well_known_files{
      "google/protobuf/any.proto",
      "google/protobuf/api.proto",
      "google/protobuf/compiler/plugin.proto",
      "google/protobuf/descriptor.proto",
      "google/protobuf/duration.proto",
      "google/protobuf/empty.proto",
      "google/protobuf/field_mask.proto",
      "google/protobuf/source_context.proto",
      "google/protobuf/struct.proto",
      "google/protobuf/timestamp.proto",
      "google/protobuf/type.proto",
      "google/protobuf/wrappers.proto",
  };
  return well_known_files.find(file->name()) != well_known_files.end();
}

enum Utf8CheckMode {
  STRICT = 0,  // Parsing will fail if non UTF-8 data is in string fields.
  VERIFY = 1,  // Only log an error but parsing will succeed.
  NONE = 2,    // No UTF-8 check.
};

static bool FieldEnforceUtf8(const FieldDescriptor* field,
                             const Options& options) {
  return true;
}

static bool FileUtf8Verification(const FileDescriptor* file,
                                 const Options& options) {
  return true;
}

// Which level of UTF-8 enforcemant is placed on this file.
static Utf8CheckMode GetUtf8CheckMode(const FieldDescriptor* field,
                                      const Options& options) {
  if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 &&
      FieldEnforceUtf8(field, options)) {
    return STRICT;
  } else if (GetOptimizeFor(field->file(), options) !=
                 FileOptions::LITE_RUNTIME &&
             FileUtf8Verification(field->file(), options)) {
    return VERIFY;
  } else {
    return NONE;
  }
}

std::string GetUtf8Suffix(const FieldDescriptor* field,
                          const Options& options) {
  switch (GetUtf8CheckMode(field, options)) {
    case STRICT:
      return "UTF8";
    case VERIFY:
      return "UTF8Verify";
    case NONE:
    default:  // Some build configs warn on missing return without default.
      return "";
  }
}

static void GenerateUtf8CheckCode(const FieldDescriptor* field,
                                  const Options& options, bool for_parse,
                                  const char* parameters,
                                  const char* strict_function,
                                  const char* verify_function,
                                  const Formatter& format) {
  switch (GetUtf8CheckMode(field, options)) {
    case STRICT: {
      if (for_parse) {
        format("DO_(");
      }
      format("::$proto_ns$::internal::WireFormatLite::$1$(\n", strict_function);
      format.Indent();
      format(parameters);
      if (for_parse) {
        format("::$proto_ns$::internal::WireFormatLite::PARSE,\n");
      } else {
        format("::$proto_ns$::internal::WireFormatLite::SERIALIZE,\n");
      }
      format("\"$1$\")", field->full_name());
      if (for_parse) {
        format(")");
      }
      format(";\n");
      format.Outdent();
      break;
    }
    case VERIFY: {
      format("::$proto_ns$::internal::WireFormat::$1$(\n", verify_function);
      format.Indent();
      format(parameters);
      if (for_parse) {
        format("::$proto_ns$::internal::WireFormat::PARSE,\n");
      } else {
        format("::$proto_ns$::internal::WireFormat::SERIALIZE,\n");
      }
      format("\"$1$\");\n", field->full_name());
      format.Outdent();
      break;
    }
    case NONE:
      break;
  }
}

void GenerateUtf8CheckCodeForString(const FieldDescriptor* field,
                                    const Options& options, bool for_parse,
                                    const char* parameters,
                                    const Formatter& format) {
  GenerateUtf8CheckCode(field, options, for_parse, parameters,
                        "VerifyUtf8String", "VerifyUTF8StringNamedField",
                        format);
}

void GenerateUtf8CheckCodeForCord(const FieldDescriptor* field,
                                  const Options& options, bool for_parse,
                                  const char* parameters,
                                  const Formatter& format) {
  GenerateUtf8CheckCode(field, options, for_parse, parameters, "VerifyUtf8Cord",
                        "VerifyUTF8CordNamedField", format);
}

namespace {

void Flatten(const Descriptor* descriptor,
             std::vector<const Descriptor*>* flatten) {
  for (int i = 0; i < descriptor->nested_type_count(); i++)
    Flatten(descriptor->nested_type(i), flatten);
  flatten->push_back(descriptor);
}

}  // namespace

void FlattenMessagesInFile(const FileDescriptor* file,
                           std::vector<const Descriptor*>* result) {
  for (int i = 0; i < file->message_type_count(); i++) {
    Flatten(file->message_type(i), result);
  }
}

bool HasWeakFields(const Descriptor* descriptor, const Options& options) {
  for (int i = 0; i < descriptor->field_count(); i++) {
    if (IsWeak(descriptor->field(i), options)) return true;
  }
  return false;
}

bool HasWeakFields(const FileDescriptor* file, const Options& options) {
  for (int i = 0; i < file->message_type_count(); ++i) {
    if (HasWeakFields(file->message_type(i), options)) return true;
  }
  return false;
}

bool UsingImplicitWeakFields(const FileDescriptor* file,
                             const Options& options) {
  return options.lite_implicit_weak_fields &&
         GetOptimizeFor(file, options) == FileOptions::LITE_RUNTIME;
}

bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options,
                         MessageSCCAnalyzer* scc_analyzer) {
  return UsingImplicitWeakFields(field->file(), options) &&
         field->type() == FieldDescriptor::TYPE_MESSAGE &&
         !field->is_required() && !field->is_map() &&
         field->containing_oneof() == nullptr &&
         !IsWellKnownMessage(field->message_type()->file()) &&
         field->message_type()->file()->name() !=
             "net/proto2/proto/descriptor.proto" &&
         // We do not support implicit weak fields between messages in the same
         // strongly-connected component.
         scc_analyzer->GetSCC(field->containing_type()) !=
             scc_analyzer->GetSCC(field->message_type());
}

MessageAnalysis MessageSCCAnalyzer::GetSCCAnalysis(const SCC* scc) {
  if (analysis_cache_.count(scc)) return analysis_cache_[scc];
  MessageAnalysis result{};
  for (int i = 0; i < scc->descriptors.size(); i++) {
    const Descriptor* descriptor = scc->descriptors[i];
    if (descriptor->extension_range_count() > 0) {
      result.contains_extension = true;
      // Extensions are found by looking up default_instance and extension
      // number in a map. So you'd maybe expect here
      // result.constructor_requires_initialization = true;
      // However the extension registration mechanism already makes sure
      // the default will be initialized.
    }
    for (int i = 0; i < descriptor->field_count(); i++) {
      const FieldDescriptor* field = descriptor->field(i);
      if (field->is_required()) {
        result.contains_required = true;
      }
      switch (field->type()) {
        case FieldDescriptor::TYPE_STRING:
        case FieldDescriptor::TYPE_BYTES: {
          result.constructor_requires_initialization = true;
          if (field->options().ctype() == FieldOptions::CORD) {
            result.contains_cord = true;
          }
          break;
        }
        case FieldDescriptor::TYPE_GROUP:
        case FieldDescriptor::TYPE_MESSAGE: {
          result.constructor_requires_initialization = true;
          const SCC* child = analyzer_.GetSCC(field->message_type());
          if (child != scc) {
            MessageAnalysis analysis = GetSCCAnalysis(child);
            result.contains_cord |= analysis.contains_cord;
            result.contains_extension |= analysis.contains_extension;
            if (!ShouldIgnoreRequiredFieldCheck(field, options_)) {
              result.contains_required |= analysis.contains_required;
            }
          } else {
            // This field points back into the same SCC hence the messages
            // in the SCC are recursive. Note if SCC contains more than two
            // nodes it has to be recursive, however this test also works for
            // a single node that is recursive.
            result.is_recursive = true;
          }
          break;
        }
        default:
          break;
      }
    }
  }
  // We deliberately only insert the result here. After we contracted the SCC
  // in the graph, the graph should be a DAG. Hence we shouldn't need to mark
  // nodes visited as we can never return to them. By inserting them here
  // we will go in an infinite loop if the SCC is not correct.
  return analysis_cache_[scc] = result;
}

void ListAllFields(const Descriptor* d,
                   std::vector<const FieldDescriptor*>* fields) {
  // Collect sub messages
  for (int i = 0; i < d->nested_type_count(); i++) {
    ListAllFields(d->nested_type(i), fields);
  }
  // Collect message level extensions.
  for (int i = 0; i < d->extension_count(); i++) {
    fields->push_back(d->extension(i));
  }
  // Add types of fields necessary
  for (int i = 0; i < d->field_count(); i++) {
    fields->push_back(d->field(i));
  }
}

void ListAllFields(const FileDescriptor* d,
                   std::vector<const FieldDescriptor*>* fields) {
  // Collect file level message.
  for (int i = 0; i < d->message_type_count(); i++) {
    ListAllFields(d->message_type(i), fields);
  }
  // Collect message level extensions.
  for (int i = 0; i < d->extension_count(); i++) {
    fields->push_back(d->extension(i));
  }
}

void ListAllTypesForServices(const FileDescriptor* fd,
                             std::vector<const Descriptor*>* types) {
  for (int i = 0; i < fd->service_count(); i++) {
    const ServiceDescriptor* sd = fd->service(i);
    for (int j = 0; j < sd->method_count(); j++) {
      const MethodDescriptor* method = sd->method(j);
      types->push_back(method->input_type());
      types->push_back(method->output_type());
    }
  }
}

bool GetBootstrapBasename(const Options& options, const std::string& basename,
                          std::string* bootstrap_basename) {
  if (options.opensource_runtime) {
    return false;
  }

  std::unordered_map<std::string, std::string> bootstrap_mapping{
      {"net/proto2/proto/descriptor",
       "net/proto2/internal/descriptor"},
      {"net/proto2/compiler/proto/plugin",
       "net/proto2/compiler/proto/plugin"},
      {"net/proto2/compiler/proto/profile",
       "net/proto2/compiler/proto/profile_bootstrap"},
  };
  auto iter = bootstrap_mapping.find(basename);
  if (iter == bootstrap_mapping.end()) {
    *bootstrap_basename = basename;
    return false;
  } else {
    *bootstrap_basename = iter->second;
    return true;
  }
}

bool IsBootstrapProto(const Options& options, const FileDescriptor* file) {
  std::string my_name = StripProto(file->name());
  return GetBootstrapBasename(options, my_name, &my_name);
}

bool MaybeBootstrap(const Options& options, GeneratorContext* generator_context,
                    bool bootstrap_flag, std::string* basename) {
  std::string bootstrap_basename;
  if (!GetBootstrapBasename(options, *basename, &bootstrap_basename)) {
    return false;
  }

  if (bootstrap_flag) {
    // Adjust basename, but don't abort code generation.
    *basename = bootstrap_basename;
    return false;
  } else {
    std::string forward_to_basename = bootstrap_basename;

    // Generate forwarding headers and empty .pb.cc.
    {
      std::unique_ptr<io::ZeroCopyOutputStream> output(
          generator_context->Open(*basename + ".pb.h"));
      io::Printer printer(output.get(), '$', nullptr);
      printer.Print(
          "#ifndef PROTOBUF_INCLUDED_$filename_identifier$_FORWARD_PB_H\n"
          "#define PROTOBUF_INCLUDED_$filename_identifier$_FORWARD_PB_H\n"
          "#include \"$forward_to_basename$.pb.h\"  // IWYU pragma: export\n"
          "#endif  // PROTOBUF_INCLUDED_$filename_identifier$_FORWARD_PB_H\n",
          "forward_to_basename", forward_to_basename, "filename_identifier",
          FilenameIdentifier(*basename));

      if (!options.opensource_runtime) {
        // HACK HACK HACK, tech debt from the deeps of proto1 and SWIG
        // protocoltype is SWIG'ed and we need to forward
        if (*basename == "net/proto/protocoltype") {
          printer.Print(
              "#ifdef SWIG\n"
              "%include \"$forward_to_basename$.pb.h\"\n"
              "#endif  // SWIG\n",
              "forward_to_basename", forward_to_basename);
        }
      }
    }

    {
      std::unique_ptr<io::ZeroCopyOutputStream> output(
          generator_context->Open(*basename + ".proto.h"));
      io::Printer printer(output.get(), '$', nullptr);
      printer.Print(
          "#ifndef PROTOBUF_INCLUDED_$filename_identifier$_FORWARD_PROTO_H\n"
          "#define PROTOBUF_INCLUDED_$filename_identifier$_FORWARD_PROTO_H\n"
          "#include \"$forward_to_basename$.proto.h\"  // IWYU pragma: "
          "export\n"
          "#endif  // "
          "PROTOBUF_INCLUDED_$filename_identifier$_FORWARD_PROTO_H\n",
          "forward_to_basename", forward_to_basename, "filename_identifier",
          FilenameIdentifier(*basename));
    }

    {
      std::unique_ptr<io::ZeroCopyOutputStream> output(
          generator_context->Open(*basename + ".pb.cc"));
      io::Printer printer(output.get(), '$', nullptr);
      printer.Print("\n");
    }

    {
      std::unique_ptr<io::ZeroCopyOutputStream> output(
          generator_context->Open(*basename + ".pb.h.meta"));
    }

    {
      std::unique_ptr<io::ZeroCopyOutputStream> output(
          generator_context->Open(*basename + ".proto.h.meta"));
    }

    // Abort code generation.
    return true;
  }
}

bool ShouldRepeat(const FieldDescriptor* descriptor,
                  internal::WireFormatLite::WireType wiretype) {
  constexpr int kMaxTwoByteFieldNumber = 16 * 128;
  return descriptor->number() < kMaxTwoByteFieldNumber &&
         descriptor->is_repeated() &&
         (!descriptor->is_packable() ||
          wiretype != internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
}

class ParseLoopGenerator {
 public:
  ParseLoopGenerator(int num_hasbits, const Options& options,
                     MessageSCCAnalyzer* scc_analyzer, io::Printer* printer)
      : scc_analyzer_(scc_analyzer),
        options_(options),
        format_(printer),
        num_hasbits_(num_hasbits) {}

  void GenerateParserLoop(const Descriptor* descriptor) {
    format_.Set("classname", ClassName(descriptor));
    format_.Set("p_ns", "::" + ProtobufNamespace(options_));
    format_.Set("pi_ns",
                StrCat("::", ProtobufNamespace(options_), "::internal"));
    format_.Set("GOOGLE_PROTOBUF", MacroPrefix(options_));
    std::map<std::string, std::string> vars;
    SetCommonVars(options_, &vars);
    format_.AddMap(vars);

    std::vector<const FieldDescriptor*> ordered_fields;
    for (auto field : FieldRange(descriptor)) {
      ordered_fields.push_back(field);
    }
    std::sort(ordered_fields.begin(), ordered_fields.end(),
              [](const FieldDescriptor* a, const FieldDescriptor* b) {
                return a->number() < b->number();
              });

    format_(
        "const char* $classname$::_InternalParse(const char* ptr, "
        "$pi_ns$::ParseContext* ctx) {\n"
        "#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure\n");
    format_.Indent();
    int hasbits_size = 0;
    if (HasFieldPresence(descriptor->file())) {
      hasbits_size = (num_hasbits_ + 31) / 32;
    }
    // For now only optimize small hasbits.
    if (hasbits_size != 1) hasbits_size = 0;
    if (hasbits_size) {
      format_("HasBitSetters::HasBits has_bits{};\n");
      format_.Set("has_bits", "has_bits");
    } else {
      format_.Set("has_bits", "_has_bits_");
    }

    if (descriptor->file()->options().cc_enable_arenas()) {
      format_("$p_ns$::Arena* arena = GetArenaNoVirtual(); (void)arena;\n");
    }
    GenerateParseLoop(descriptor, ordered_fields);
    format_.Outdent();
    format_("success:\n");
    if (hasbits_size) format_("  _has_bits_.Or(has_bits);\n");
    format_(
        "  return ptr;\n"
        "failure:\n"
        "  ptr = nullptr;\n"
        "  goto success;\n"
        "#undef CHK_\n"
        "}\n");
  }

 private:
  MessageSCCAnalyzer* scc_analyzer_;
  const Options& options_;
  Formatter format_;
  int num_hasbits_;

  using WireFormat = internal::WireFormat;
  using WireFormatLite = internal::WireFormatLite;

  void GenerateArenaString(const FieldDescriptor* field,
                           const std::string& utf8, std::string field_name) {
    if (!field_name.empty()) {
      format_("static const char kFieldName[] = $1$;\n",
              field_name.substr(2));  // remove ", "
      field_name = ", kFieldName";
    }
    if (HasFieldPresence(field->file())) {
      format_("HasBitSetters::set_has_$1$(&$has_bits$);\n", FieldName(field));
    }
    string default_string =
        field->default_value_string().empty()
            ? "::" + ProtobufNamespace(options_) +
                  "::internal::GetEmptyStringAlreadyInited()"
            : QualifiedClassName(field->containing_type(), options_) +
                  "::" + MakeDefaultName(field) + ".get()";
    format_(
        "if (arena != nullptr) {\n"
        "  ptr = $pi_ns$::InlineCopyIntoArenaString$1$(&$2$_, ptr, ctx, "
        "  arena$3$);\n"
        "} else {\n"
        "  ptr = "
        "$pi_ns$::InlineGreedyStringParser$1$($2$_.MutableNoArenaNoDefault(&$4$"
        "), ptr, ctx$3$);"
        "\n}\n",
        utf8, FieldName(field), field_name, default_string);
  }

  void GenerateStrings(const FieldDescriptor* field, bool check_utf8) {
    std::string utf8;
    std::string field_name;
    if (check_utf8) {
      utf8 = GetUtf8Suffix(field, options_);
      if (!utf8.empty()) {
        field_name = ", nullptr";
        if (HasDescriptorMethods(field->file(), options_)) {
          field_name = StrCat(", \"", field->full_name(), "\"");
        }
      }
    }
    FieldOptions::CType ctype = FieldOptions::STRING;
    if (!options_.opensource_runtime) {
      // Open source doesn't support other ctypes;
      ctype = field->options().ctype();
    }
    if (field->file()->options().cc_enable_arenas() && !field->is_repeated() &&
        !options_.opensource_runtime &&
        GetOptimizeFor(field->file(), options_) != FileOptions::LITE_RUNTIME &&
        // For now only use arena string for strings with empty defaults.
        field->default_value_string().empty() &&
        !IsStringInlined(field, options_) &&
        field->containing_oneof() == nullptr && ctype == FieldOptions::STRING) {
      GenerateArenaString(field, utf8, field_name);
      return;
    }
    std::string name;
    switch (ctype) {
      case FieldOptions::STRING:
        name = "GreedyStringParser" + utf8;
        break;
      case FieldOptions::CORD:
        name = "CordParser" + utf8;
        break;
      case FieldOptions::STRING_PIECE:
        name = "StringPieceParser" + utf8;
        break;
    }
    format_("ptr = $pi_ns$::Inline$1$($2$_$3$(), ptr, ctx$4$);\n", name,
            field->is_repeated() && !field->is_packable() ? "add" : "mutable",
            FieldName(field), field_name);
  }

  void GenerateLengthDelim(const FieldDescriptor* field) {
    if (field->is_packable()) {
      std::string enum_validator;
      if (field->type() == FieldDescriptor::TYPE_ENUM &&
          !HasPreservingUnknownEnumSemantics(field)) {
        enum_validator = StrCat(
            ", ", QualifiedClassName(field->enum_type(), options_),
            "_IsValid, mutable_unknown_fields(), ", field->number());
      }
      format_("ptr = $pi_ns$::Packed$1$Parser(mutable_$2$(), ptr, ctx$3$);\n",
              DeclaredTypeMethodName(field->type()), FieldName(field),
              enum_validator);
    } else {
      auto field_type = field->type();
      switch (field_type) {
        case FieldDescriptor::TYPE_STRING:
          GenerateStrings(field, true /* utf8 */);
          break;
        case FieldDescriptor::TYPE_BYTES:
          GenerateStrings(field, false /* utf8 */);
          break;
        case FieldDescriptor::TYPE_MESSAGE: {
          if (field->is_map()) {
            const FieldDescriptor* val =
                field->message_type()->FindFieldByName("value");
            GOOGLE_CHECK(val);
            if (HasFieldPresence(field->file()) &&
                val->type() == FieldDescriptor::TYPE_ENUM) {
              format_(
                  "auto object = ::$proto_ns$::internal::InitEnumParseWrapper("
                  "&$1$_, $2$_IsValid, $3$, &_internal_metadata_);\n"
                  "ptr = ctx->ParseMessage(&object, ptr);\n",
                  FieldName(field), QualifiedClassName(val->enum_type()),
                  field->number());
            } else {
              format_("ptr = ctx->ParseMessage(&$1$_, ptr);\n",
                      FieldName(field));
            }
          } else if (IsLazy(field, options_)) {
            if (field->containing_oneof() != nullptr) {
              format_(
                  "if (!has_$1$()) {\n"
                  "  clear_$1$();\n"
                  "  $2$_.$1$_ = ::$proto_ns$::Arena::CreateMessage<\n"
                  "      $pi_ns$::LazyField>("
                  "GetArenaNoVirtual());\n"
                  "  set_has_$1$();\n"
                  "}\n"
                  "ptr = ctx->ParseMessage($2$_.$1$_, ptr);\n",
                  FieldName(field), field->containing_oneof()->name());
            } else if (HasFieldPresence(field->file())) {
              format_(
                  "HasBitSetters::set_has_$1$(&$has_bits$);\n"
                  "ptr = ctx->ParseMessage(&$1$_, ptr);\n",
                  FieldName(field));
            } else {
              format_("ptr = ctx->ParseMessage(&$1$_, ptr);\n",
                      FieldName(field));
            }
          } else if (IsImplicitWeakField(field, options_, scc_analyzer_)) {
            if (!field->is_repeated()) {
              format_(
                  "ptr = ctx->ParseMessage(HasBitSetters::mutable_$1$(this), "
                  "ptr);\n",
                  FieldName(field));
            } else {
              format_(
                  "ptr = ctx->ParseMessage("
                  "CastToBase(&$1$_)->AddWeak(reinterpret_cast<const "
                  "::$proto_ns$::MessageLite*>(&$2$::_$3$_default_instance_)), "
                  "ptr);\n",
                  FieldName(field), Namespace(field->message_type(), options_),
                  ClassName(field->message_type()));
            }
          } else if (IsWeak(field, options_)) {
            format_(
                "ptr = ctx->ParseMessage(_weak_field_map_.MutableMessage($1$,"
                " _$classname$_default_instance_.$2$_), ptr);\n",
                field->number(), FieldName(field));
          } else {
            format_("ptr = ctx->ParseMessage($1$_$2$(), ptr);\n",
                    field->is_repeated() ? "add" : "mutable", FieldName(field));
          }
          break;
        }
        default:
          GOOGLE_LOG(FATAL) << "Illegal combination for length delimited wiretype "
                     << " filed type is " << field->type();
      }
    }
  }

  void GenerateCaseBody(internal::WireFormatLite::WireType wiretype,
                        const FieldDescriptor* field) {
    if (ShouldRepeat(field, wiretype)) {
      format_("while (true) {\n");
      format_.Indent();
    }
    switch (wiretype) {
      case WireFormatLite::WIRETYPE_VARINT: {
        std::string type = PrimitiveTypeName(options_, field->cpp_type());
        std::string prefix = field->is_repeated() ? "add" : "set";
        if (field->type() == FieldDescriptor::TYPE_ENUM) {
          format_(
              "$uint64$ val = $pi_ns$::ReadVarint(&ptr);\n"
              "CHK_(ptr);\n");
          if (!HasPreservingUnknownEnumSemantics(field)) {
            format_(
                "if (!$1$_IsValid(val)) {\n"
                "  $pi_ns$::WriteVarint($2$, val, "
                "mutable_unknown_fields());\n"
                "  break;\n"
                "}\n",
                QualifiedClassName(field->enum_type(), options_),
                field->number());
          }
          format_("$1$_$2$(static_cast<$3$>(val));\n", prefix, FieldName(field),
                  QualifiedClassName(field->enum_type(), options_));
        } else {
          int size = field->type() == FieldDescriptor::TYPE_SINT32 ? 32 : 64;
          std::string zigzag;
          if ((field->type() == FieldDescriptor::TYPE_SINT32 ||
               field->type() == FieldDescriptor::TYPE_SINT64)) {
            zigzag = StrCat("ZigZag", size);
          }
          if (field->is_repeated() || field->containing_oneof()) {
            string prefix = field->is_repeated() ? "add" : "set";
            format_(
                "$1$_$2$($pi_ns$::ReadVarint$3$(&ptr));\n"
                "CHK_(ptr);\n",
                prefix, FieldName(field), zigzag);
          } else {
            if (HasFieldPresence(field->file())) {
              format_("HasBitSetters::set_has_$1$(&$has_bits$);\n",
                      FieldName(field));
            }
            format_(
                "$1$_ = $pi_ns$::ReadVarint$2$(&ptr);\n"
                "CHK_(ptr);\n",
                FieldName(field), zigzag);
          }
        }
        break;
      }
      case WireFormatLite::WIRETYPE_FIXED32:
      case WireFormatLite::WIRETYPE_FIXED64: {
        std::string type = PrimitiveTypeName(options_, field->cpp_type());
        if (field->is_repeated() || field->containing_oneof()) {
          string prefix = field->is_repeated() ? "add" : "set";
          format_(
              "$1$_$2$($pi_ns$::UnalignedLoad<$3$>(ptr));\n"
              "ptr += sizeof($3$);\n",
              prefix, FieldName(field), type);
        } else {
          if (HasFieldPresence(field->file())) {
            format_("HasBitSetters::set_has_$1$(&$has_bits$);\n",
                    FieldName(field));
          }
          format_(
              "$1$_ = $pi_ns$::UnalignedLoad<$2$>(ptr);\n"
              "ptr += sizeof($2$);\n",
              FieldName(field), type);
        }
        break;
      }
      case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
        GenerateLengthDelim(field);
        format_("CHK_(ptr);\n");
        break;
      }
      case WireFormatLite::WIRETYPE_START_GROUP: {
        format_(
            "ptr = ctx->ParseGroup($1$_$2$(), ptr, tag);\n"
            "CHK_(ptr);\n",
            field->is_repeated() ? "add" : "mutable", FieldName(field));
        break;
      }
      case WireFormatLite::WIRETYPE_END_GROUP: {
        GOOGLE_LOG(FATAL) << "Can't have end group field\n";
        break;
      }
    }  // switch (wire_type)

    if (ShouldRepeat(field, wiretype)) {
      uint32 x = field->number() * 8 + wiretype;
      int cnt = 1;
      string type = "uint8";
      if (x >= 128) {
        x += (x & 0xFF80) + 128;
        cnt = 2;
        type = "uint16";
      }
      format_(
          "if (!ctx->DataAvailable(ptr)) break;\n"
          "if ($pi_ns$::UnalignedLoad<$1$>(ptr) != $2$) break;\n"
          "ptr += $3$;\n",
          IntTypeName(options_, type), x, cnt);
      format_.Outdent();
      format_("}\n");
    }
    format_("break;\n");
  }

  void GenerateCaseBody(const FieldDescriptor* field) {
    if (field->is_packable()) {
      auto expected_wiretype = WireFormat::WireTypeForFieldType(field->type());
      GOOGLE_CHECK(expected_wiretype != WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
      uint32 expected_tag =
          WireFormatLite::MakeTag(field->number(), expected_wiretype);
      auto fallback_wiretype = WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
      uint32 fallback_tag =
          WireFormatLite::MakeTag(field->number(), fallback_wiretype);

      if (field->is_packed()) {
        std::swap(expected_tag, fallback_tag);
        std::swap(expected_wiretype, fallback_wiretype);
      }

      format_("if (static_cast<$uint8$>(tag) == $1$) {\n", expected_tag & 0xFF);
      format_.Indent();
      GenerateCaseBody(expected_wiretype, field);
      format_.Outdent();
      format_(
          "} else if (static_cast<$uint8$>(tag) != $1$) goto handle_unusual;\n",
          fallback_tag & 0xFF);
      GenerateCaseBody(fallback_wiretype, field);
    } else {
      auto wiretype = WireFormat::WireTypeForField(field);
      format_("if (static_cast<$uint8$>(tag) != $1$) goto handle_unusual;\n",
              WireFormat::MakeTag(field) & 0xFF);
      GenerateCaseBody(wiretype, field);
    }
  }

  void GenerateParseLoop(
      const Descriptor* descriptor,
      const std::vector<const FieldDescriptor*>& ordered_fields) {
    format_(
        "while (!ctx->Done(&ptr)) {\n"
        "  $uint32$ tag;\n"
        "  ptr = $pi_ns$::ReadTag(ptr, &tag);\n"
        "  CHK_(ptr);\n"
        "  switch (tag >> 3) {\n");

    format_.Indent();
    format_.Indent();

    for (const auto* field : ordered_fields) {
      // Print the field's (or oneof's) proto-syntax definition as a comment.
      // We don't want to print group bodies so we cut off after the first
      // line.
      std::string def;
      {
        DebugStringOptions options;
        options.elide_group_body = true;
        options.elide_oneof_body = true;
        def = field->DebugStringWithOptions(options);
        def = def.substr(0, def.find_first_of('\n'));
      }
      format_(
          "// $1$\n"
          "case $2$: {\n",
          def, field->number());
      format_.Indent();
      GenerateCaseBody(field);
      format_.Outdent();
      format_("}\n");  // case
    }                  // for fields

    // Default case
    format_("default: {\n");
    if (!ordered_fields.empty()) format_("handle_unusual:\n");
    format_(
        "  if ((tag & 7) == 4 || tag == 0) {\n"
        "    ctx->SetLastTag(tag);\n"
        "    goto success;\n"
        "  }\n");
    if (IsMapEntryMessage(descriptor)) {
      format_("  break;\n");
    } else {
      if (descriptor->extension_range_count() > 0) {
        format_("if (");
        for (int i = 0; i < descriptor->extension_range_count(); i++) {
          const Descriptor::ExtensionRange* range =
              descriptor->extension_range(i);
          if (i > 0) format_(" ||\n    ");

          uint32 start_tag = WireFormatLite::MakeTag(
              range->start, static_cast<WireFormatLite::WireType>(0));
          uint32 end_tag = WireFormatLite::MakeTag(
              range->end, static_cast<WireFormatLite::WireType>(0));

          if (range->end > FieldDescriptor::kMaxNumber) {
            format_("($1$u <= tag)", start_tag);
          } else {
            format_("($1$u <= tag && tag < $2$u)", start_tag, end_tag);
          }
        }
        format_(") {\n");
        format_(
            "  ptr = _extensions_.ParseField(tag, ptr, \n"
            "      internal_default_instance(), &_internal_metadata_, "
            "ctx);\n"
            "  CHK_(ptr != nullptr);\n"
            "  break;\n"
            "}\n");
      }
      format_(
          "  ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx);\n"
          "  CHK_(ptr != nullptr);\n"
          "  break;\n");
    }
    format_("}\n");  // default case
    format_.Outdent();
    format_.Outdent();
    format_(
        "  }  // switch\n"
        "}  // while\n");
  }
};

void GenerateParserLoop(const Descriptor* descriptor, int num_hasbits,
                        const Options& options,
                        MessageSCCAnalyzer* scc_analyzer,
                        io::Printer* printer) {
  ParseLoopGenerator generator(num_hasbits, options, scc_analyzer, printer);
  generator.GenerateParserLoop(descriptor);
}

}  // namespace cpp
}  // namespace compiler
}  // namespace protobuf
}  // namespace google
