| Index: third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum.cc
 | 
| diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum.cc
 | 
| index fda011a92ed40740812b532920ec8f8c40f8fe0c..1a11bce8579833990570c00214ea031f35da27c1 100644
 | 
| --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum.cc
 | 
| +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum.cc
 | 
| @@ -1,6 +1,6 @@
 | 
|  // Protocol Buffers - Google's data interchange format
 | 
|  // Copyright 2008 Google Inc.  All rights reserved.
 | 
| -// http://code.google.com/p/protobuf/
 | 
| +// 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
 | 
| @@ -32,7 +32,6 @@
 | 
|  //  Based on original Protocol Buffers design by
 | 
|  //  Sanjay Ghemawat, Jeff Dean, and others.
 | 
|  
 | 
| -#include <set>
 | 
|  #include <map>
 | 
|  
 | 
|  #include <google/protobuf/compiler/cpp/cpp_enum.h>
 | 
| @@ -45,29 +44,56 @@ namespace protobuf {
 | 
|  namespace compiler {
 | 
|  namespace cpp {
 | 
|  
 | 
| +namespace {
 | 
| +// The GOOGLE_ARRAYSIZE constant is the max enum value plus 1. If the max enum value
 | 
| +// is ::google::protobuf::kint32max, GOOGLE_ARRAYSIZE will overflow. In such cases we should omit the
 | 
| +// generation of the GOOGLE_ARRAYSIZE constant.
 | 
| +bool ShouldGenerateArraySize(const EnumDescriptor* descriptor) {
 | 
| +  int32 max_value = descriptor->value(0)->number();
 | 
| +  for (int i = 0; i < descriptor->value_count(); i++) {
 | 
| +    if (descriptor->value(i)->number() > max_value) {
 | 
| +      max_value = descriptor->value(i)->number();
 | 
| +    }
 | 
| +  }
 | 
| +  return max_value != ::google::protobuf::kint32max;
 | 
| +}
 | 
| +}  // namespace
 | 
| +
 | 
|  EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor,
 | 
|                               const Options& options)
 | 
|    : descriptor_(descriptor),
 | 
|      classname_(ClassName(descriptor, false)),
 | 
| -    options_(options) {
 | 
| +    options_(options),
 | 
| +    generate_array_size_(ShouldGenerateArraySize(descriptor)) {
 | 
|  }
 | 
|  
 | 
|  EnumGenerator::~EnumGenerator() {}
 | 
|  
 | 
| +void EnumGenerator::FillForwardDeclaration(set<string>* enum_names) {
 | 
| +  if (!options_.proto_h) {
 | 
| +    return;
 | 
| +  }
 | 
| +  enum_names->insert(classname_);
 | 
| +}
 | 
| +
 | 
|  void EnumGenerator::GenerateDefinition(io::Printer* printer) {
 | 
|    map<string, string> vars;
 | 
|    vars["classname"] = classname_;
 | 
|    vars["short_name"] = descriptor_->name();
 | 
| +  vars["enumbase"] = classname_ + (options_.proto_h ? " : int" : "");
 | 
|  
 | 
| -  printer->Print(vars, "enum $classname$ {\n");
 | 
| +  printer->Print(vars, "enum $enumbase$ {\n");
 | 
|    printer->Indent();
 | 
|  
 | 
|    const EnumValueDescriptor* min_value = descriptor_->value(0);
 | 
|    const EnumValueDescriptor* max_value = descriptor_->value(0);
 | 
|  
 | 
|    for (int i = 0; i < descriptor_->value_count(); i++) {
 | 
| -    vars["name"] = descriptor_->value(i)->name();
 | 
| -    vars["number"] = SimpleItoa(descriptor_->value(i)->number());
 | 
| +    vars["name"] = EnumValueName(descriptor_->value(i));
 | 
| +    // In C++, an value of -2147483648 gets interpreted as the negative of
 | 
| +    // 2147483648, and since 2147483648 can't fit in an integer, this produces a
 | 
| +    // compiler warning.  This works around that issue.
 | 
| +    vars["number"] = Int32ToString(descriptor_->value(i)->number());
 | 
|      vars["prefix"] = (descriptor_->containing_type() == NULL) ?
 | 
|        "" : classname_ + "_";
 | 
|  
 | 
| @@ -82,11 +108,20 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) {
 | 
|      }
 | 
|    }
 | 
|  
 | 
| +  if (HasPreservingUnknownEnumSemantics(descriptor_->file())) {
 | 
| +    // For new enum semantics: generate min and max sentinel values equal to
 | 
| +    // INT32_MIN and INT32_MAX
 | 
| +    if (descriptor_->value_count() > 0) printer->Print(",\n");
 | 
| +    printer->Print(vars,
 | 
| +        "$classname$_$prefix$INT_MIN_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32min,\n"
 | 
| +        "$classname$_$prefix$INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max");
 | 
| +  }
 | 
| +
 | 
|    printer->Outdent();
 | 
|    printer->Print("\n};\n");
 | 
|  
 | 
| -  vars["min_name"] = min_value->name();
 | 
| -  vars["max_name"] = max_value->name();
 | 
| +  vars["min_name"] = EnumValueName(min_value);
 | 
| +  vars["max_name"] = EnumValueName(max_value);
 | 
|  
 | 
|    if (options_.dllexport_decl.empty()) {
 | 
|      vars["dllexport"] = "";
 | 
| @@ -97,9 +132,13 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) {
 | 
|    printer->Print(vars,
 | 
|      "$dllexport$bool $classname$_IsValid(int value);\n"
 | 
|      "const $classname$ $prefix$$short_name$_MIN = $prefix$$min_name$;\n"
 | 
| -    "const $classname$ $prefix$$short_name$_MAX = $prefix$$max_name$;\n"
 | 
| -    "const int $prefix$$short_name$_ARRAYSIZE = $prefix$$short_name$_MAX + 1;\n"
 | 
| -    "\n");
 | 
| +    "const $classname$ $prefix$$short_name$_MAX = $prefix$$max_name$;\n");
 | 
| +
 | 
| +  if (generate_array_size_) {
 | 
| +    printer->Print(vars,
 | 
| +      "const int $prefix$$short_name$_ARRAYSIZE = "
 | 
| +      "$prefix$$short_name$_MAX + 1;\n\n");
 | 
| +  }
 | 
|  
 | 
|    if (HasDescriptorMethods(descriptor_->file())) {
 | 
|      printer->Print(vars,
 | 
| @@ -121,6 +160,10 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) {
 | 
|  
 | 
|  void EnumGenerator::
 | 
|  GenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
 | 
| +  printer->Print(
 | 
| +      "template <> struct is_proto_enum< $classname$> : ::google::protobuf::internal::true_type "
 | 
| +      "{};\n",
 | 
| +      "classname", ClassName(descriptor_, true));
 | 
|    if (HasDescriptorMethods(descriptor_->file())) {
 | 
|      printer->Print(
 | 
|        "template <>\n"
 | 
| @@ -138,7 +181,7 @@ void EnumGenerator::GenerateSymbolImports(io::Printer* printer) {
 | 
|    printer->Print(vars, "typedef $classname$ $nested_name$;\n");
 | 
|  
 | 
|    for (int j = 0; j < descriptor_->value_count(); j++) {
 | 
| -    vars["tag"] = descriptor_->value(j)->name();
 | 
| +    vars["tag"] = EnumValueName(descriptor_->value(j));
 | 
|      printer->Print(vars,
 | 
|        "static const $nested_name$ $tag$ = $classname$_$tag$;\n");
 | 
|    }
 | 
| @@ -150,9 +193,12 @@ void EnumGenerator::GenerateSymbolImports(io::Printer* printer) {
 | 
|      "static const $nested_name$ $nested_name$_MIN =\n"
 | 
|      "  $classname$_$nested_name$_MIN;\n"
 | 
|      "static const $nested_name$ $nested_name$_MAX =\n"
 | 
| -    "  $classname$_$nested_name$_MAX;\n"
 | 
| -    "static const int $nested_name$_ARRAYSIZE =\n"
 | 
| -    "  $classname$_$nested_name$_ARRAYSIZE;\n");
 | 
| +    "  $classname$_$nested_name$_MAX;\n");
 | 
| +  if (generate_array_size_) {
 | 
| +    printer->Print(vars,
 | 
| +      "static const int $nested_name$_ARRAYSIZE =\n"
 | 
| +      "  $classname$_$nested_name$_ARRAYSIZE;\n");
 | 
| +  }
 | 
|  
 | 
|    if (HasDescriptorMethods(descriptor_->file())) {
 | 
|      printer->Print(vars,
 | 
| @@ -218,7 +264,7 @@ void EnumGenerator::GenerateMethods(io::Printer* printer) {
 | 
|         iter != numbers.end(); ++iter) {
 | 
|      printer->Print(
 | 
|        "    case $number$:\n",
 | 
| -      "number", SimpleItoa(*iter));
 | 
| +      "number", Int32ToString(*iter));
 | 
|    }
 | 
|  
 | 
|    printer->Print(vars,
 | 
| @@ -239,16 +285,19 @@ void EnumGenerator::GenerateMethods(io::Printer* printer) {
 | 
|      vars["parent"] = ClassName(descriptor_->containing_type(), false);
 | 
|      vars["nested_name"] = descriptor_->name();
 | 
|      for (int i = 0; i < descriptor_->value_count(); i++) {
 | 
| -      vars["value"] = descriptor_->value(i)->name();
 | 
| +      vars["value"] = EnumValueName(descriptor_->value(i));
 | 
|        printer->Print(vars,
 | 
|          "const $classname$ $parent$::$value$;\n");
 | 
|      }
 | 
|      printer->Print(vars,
 | 
|        "const $classname$ $parent$::$nested_name$_MIN;\n"
 | 
| -      "const $classname$ $parent$::$nested_name$_MAX;\n"
 | 
| -      "const int $parent$::$nested_name$_ARRAYSIZE;\n");
 | 
| +      "const $classname$ $parent$::$nested_name$_MAX;\n");
 | 
| +    if (generate_array_size_) {
 | 
| +      printer->Print(vars,
 | 
| +        "const int $parent$::$nested_name$_ARRAYSIZE;\n");
 | 
| +    }
 | 
|  
 | 
| -    printer->Print("#endif  // _MSC_VER\n");
 | 
| +    printer->Print("#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900\n");
 | 
|    }
 | 
|  }
 | 
|  
 | 
| 
 |