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