Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(200)

Side by Side Diff: third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum.cc

Issue 1322483002: Revert https://codereview.chromium.org/1291903002 (protobuf roll). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Protocol Buffers - Google's data interchange format 1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved. 2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/ 3 // http://code.google.com/p/protobuf/
4 // 4 //
5 // Redistribution and use in source and binary forms, with or without 5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are 6 // modification, are permitted provided that the following conditions are
7 // met: 7 // met:
8 // 8 //
9 // * Redistributions of source code must retain the above copyright 9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer. 10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above 11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer 12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the 13 // in the documentation and/or other materials provided with the
(...skipping 24 matching lines...) Expand all
38 #include <google/protobuf/compiler/cpp/cpp_enum.h> 38 #include <google/protobuf/compiler/cpp/cpp_enum.h>
39 #include <google/protobuf/compiler/cpp/cpp_helpers.h> 39 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
40 #include <google/protobuf/io/printer.h> 40 #include <google/protobuf/io/printer.h>
41 #include <google/protobuf/stubs/strutil.h> 41 #include <google/protobuf/stubs/strutil.h>
42 42
43 namespace google { 43 namespace google {
44 namespace protobuf { 44 namespace protobuf {
45 namespace compiler { 45 namespace compiler {
46 namespace cpp { 46 namespace cpp {
47 47
48 namespace {
49 // The GOOGLE_ARRAYSIZE constant is the max enum value plus 1. If the max enum v alue
50 // is ::google::protobuf::kint32max, GOOGLE_ARRAYSIZE will overflow. In such cas es we should omit the
51 // generation of the GOOGLE_ARRAYSIZE constant.
52 bool ShouldGenerateArraySize(const EnumDescriptor* descriptor) {
53 int32 max_value = descriptor->value(0)->number();
54 for (int i = 0; i < descriptor->value_count(); i++) {
55 if (descriptor->value(i)->number() > max_value) {
56 max_value = descriptor->value(i)->number();
57 }
58 }
59 return max_value != ::google::protobuf::kint32max;
60 }
61 } // namespace
62
63 EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor, 48 EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor,
64 const Options& options) 49 const Options& options)
65 : descriptor_(descriptor), 50 : descriptor_(descriptor),
66 classname_(ClassName(descriptor, false)), 51 classname_(ClassName(descriptor, false)),
67 options_(options), 52 options_(options) {
68 generate_array_size_(ShouldGenerateArraySize(descriptor)) {
69 } 53 }
70 54
71 EnumGenerator::~EnumGenerator() {} 55 EnumGenerator::~EnumGenerator() {}
72 56
73 void EnumGenerator::GenerateForwardDeclaration(io::Printer* printer) {
74 if (!options_.proto_h) {
75 return;
76 }
77 map<string, string> vars;
78 vars["classname"] = classname_;
79 printer->Print(vars, "enum $classname$ : int;\n");
80 printer->Print(vars, "bool $classname$_IsValid(int value);\n");
81 }
82
83 void EnumGenerator::GenerateDefinition(io::Printer* printer) { 57 void EnumGenerator::GenerateDefinition(io::Printer* printer) {
84 map<string, string> vars; 58 map<string, string> vars;
85 vars["classname"] = classname_; 59 vars["classname"] = classname_;
86 vars["short_name"] = descriptor_->name(); 60 vars["short_name"] = descriptor_->name();
87 vars["enumbase"] = classname_ + (options_.proto_h ? " : int" : "");
88 61
89 printer->Print(vars, "enum $enumbase$ {\n"); 62 printer->Print(vars, "enum $classname$ {\n");
90 printer->Indent(); 63 printer->Indent();
91 64
92 const EnumValueDescriptor* min_value = descriptor_->value(0); 65 const EnumValueDescriptor* min_value = descriptor_->value(0);
93 const EnumValueDescriptor* max_value = descriptor_->value(0); 66 const EnumValueDescriptor* max_value = descriptor_->value(0);
94 67
95 for (int i = 0; i < descriptor_->value_count(); i++) { 68 for (int i = 0; i < descriptor_->value_count(); i++) {
96 vars["name"] = EnumValueName(descriptor_->value(i)); 69 vars["name"] = descriptor_->value(i)->name();
97 // In C++, an value of -2147483648 gets interpreted as the negative of 70 vars["number"] = SimpleItoa(descriptor_->value(i)->number());
98 // 2147483648, and since 2147483648 can't fit in an integer, this produces a
99 // compiler warning. This works around that issue.
100 vars["number"] = Int32ToString(descriptor_->value(i)->number());
101 vars["prefix"] = (descriptor_->containing_type() == NULL) ? 71 vars["prefix"] = (descriptor_->containing_type() == NULL) ?
102 "" : classname_ + "_"; 72 "" : classname_ + "_";
103 73
104 if (i > 0) printer->Print(",\n"); 74 if (i > 0) printer->Print(",\n");
105 printer->Print(vars, "$prefix$$name$ = $number$"); 75 printer->Print(vars, "$prefix$$name$ = $number$");
106 76
107 if (descriptor_->value(i)->number() < min_value->number()) { 77 if (descriptor_->value(i)->number() < min_value->number()) {
108 min_value = descriptor_->value(i); 78 min_value = descriptor_->value(i);
109 } 79 }
110 if (descriptor_->value(i)->number() > max_value->number()) { 80 if (descriptor_->value(i)->number() > max_value->number()) {
111 max_value = descriptor_->value(i); 81 max_value = descriptor_->value(i);
112 } 82 }
113 } 83 }
114 84
115 if (HasPreservingUnknownEnumSemantics(descriptor_->file())) {
116 // For new enum semantics: generate min and max sentinel values equal to
117 // INT32_MIN and INT32_MAX
118 if (descriptor_->value_count() > 0) printer->Print(",\n");
119 printer->Print(vars,
120 "$classname$_$prefix$INT_MIN_SENTINEL_DO_NOT_USE_ = ::google::protobuf:: kint32min,\n"
121 "$classname$_$prefix$INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf:: kint32max");
122 }
123
124 printer->Outdent(); 85 printer->Outdent();
125 printer->Print("\n};\n"); 86 printer->Print("\n};\n");
126 87
127 vars["min_name"] = EnumValueName(min_value); 88 vars["min_name"] = min_value->name();
128 vars["max_name"] = EnumValueName(max_value); 89 vars["max_name"] = max_value->name();
129 90
130 if (options_.dllexport_decl.empty()) { 91 if (options_.dllexport_decl.empty()) {
131 vars["dllexport"] = ""; 92 vars["dllexport"] = "";
132 } else { 93 } else {
133 vars["dllexport"] = options_.dllexport_decl + " "; 94 vars["dllexport"] = options_.dllexport_decl + " ";
134 } 95 }
135 96
136 printer->Print(vars, 97 printer->Print(vars,
137 "$dllexport$bool $classname$_IsValid(int value);\n" 98 "$dllexport$bool $classname$_IsValid(int value);\n"
138 "const $classname$ $prefix$$short_name$_MIN = $prefix$$min_name$;\n" 99 "const $classname$ $prefix$$short_name$_MIN = $prefix$$min_name$;\n"
139 "const $classname$ $prefix$$short_name$_MAX = $prefix$$max_name$;\n"); 100 "const $classname$ $prefix$$short_name$_MAX = $prefix$$max_name$;\n"
140 101 "const int $prefix$$short_name$_ARRAYSIZE = $prefix$$short_name$_MAX + 1;\n"
141 if (generate_array_size_) { 102 "\n");
142 printer->Print(vars,
143 "const int $prefix$$short_name$_ARRAYSIZE = "
144 "$prefix$$short_name$_MAX + 1;\n\n");
145 }
146 103
147 if (HasDescriptorMethods(descriptor_->file())) { 104 if (HasDescriptorMethods(descriptor_->file())) {
148 printer->Print(vars, 105 printer->Print(vars,
149 "$dllexport$const ::google::protobuf::EnumDescriptor* $classname$_descript or();\n"); 106 "$dllexport$const ::google::protobuf::EnumDescriptor* $classname$_descript or();\n");
150 // The _Name and _Parse methods 107 // The _Name and _Parse methods
151 printer->Print(vars, 108 printer->Print(vars,
152 "inline const ::std::string& $classname$_Name($classname$ value) {\n" 109 "inline const ::std::string& $classname$_Name($classname$ value) {\n"
153 " return ::google::protobuf::internal::NameOfEnum(\n" 110 " return ::google::protobuf::internal::NameOfEnum(\n"
154 " $classname$_descriptor(), value);\n" 111 " $classname$_descriptor(), value);\n"
155 "}\n"); 112 "}\n");
156 printer->Print(vars, 113 printer->Print(vars,
157 "inline bool $classname$_Parse(\n" 114 "inline bool $classname$_Parse(\n"
158 " const ::std::string& name, $classname$* value) {\n" 115 " const ::std::string& name, $classname$* value) {\n"
159 " return ::google::protobuf::internal::ParseNamedEnum<$classname$>(\n" 116 " return ::google::protobuf::internal::ParseNamedEnum<$classname$>(\n"
160 " $classname$_descriptor(), name, value);\n" 117 " $classname$_descriptor(), name, value);\n"
161 "}\n"); 118 "}\n");
162 } 119 }
163 } 120 }
164 121
165 void EnumGenerator:: 122 void EnumGenerator::
166 GenerateGetEnumDescriptorSpecializations(io::Printer* printer) { 123 GenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
167 printer->Print(
168 "template <> struct is_proto_enum< $classname$> : ::google::protobuf::inte rnal::true_type "
169 "{};\n",
170 "classname", ClassName(descriptor_, true));
171 if (HasDescriptorMethods(descriptor_->file())) { 124 if (HasDescriptorMethods(descriptor_->file())) {
172 printer->Print( 125 printer->Print(
173 "template <>\n" 126 "template <>\n"
174 "inline const EnumDescriptor* GetEnumDescriptor< $classname$>() {\n" 127 "inline const EnumDescriptor* GetEnumDescriptor< $classname$>() {\n"
175 " return $classname$_descriptor();\n" 128 " return $classname$_descriptor();\n"
176 "}\n", 129 "}\n",
177 "classname", ClassName(descriptor_, true)); 130 "classname", ClassName(descriptor_, true));
178 } 131 }
179 } 132 }
180 133
181 void EnumGenerator::GenerateSymbolImports(io::Printer* printer) { 134 void EnumGenerator::GenerateSymbolImports(io::Printer* printer) {
182 map<string, string> vars; 135 map<string, string> vars;
183 vars["nested_name"] = descriptor_->name(); 136 vars["nested_name"] = descriptor_->name();
184 vars["classname"] = classname_; 137 vars["classname"] = classname_;
185 printer->Print(vars, "typedef $classname$ $nested_name$;\n"); 138 printer->Print(vars, "typedef $classname$ $nested_name$;\n");
186 139
187 for (int j = 0; j < descriptor_->value_count(); j++) { 140 for (int j = 0; j < descriptor_->value_count(); j++) {
188 vars["tag"] = EnumValueName(descriptor_->value(j)); 141 vars["tag"] = descriptor_->value(j)->name();
189 printer->Print(vars, 142 printer->Print(vars,
190 "static const $nested_name$ $tag$ = $classname$_$tag$;\n"); 143 "static const $nested_name$ $tag$ = $classname$_$tag$;\n");
191 } 144 }
192 145
193 printer->Print(vars, 146 printer->Print(vars,
194 "static inline bool $nested_name$_IsValid(int value) {\n" 147 "static inline bool $nested_name$_IsValid(int value) {\n"
195 " return $classname$_IsValid(value);\n" 148 " return $classname$_IsValid(value);\n"
196 "}\n" 149 "}\n"
197 "static const $nested_name$ $nested_name$_MIN =\n" 150 "static const $nested_name$ $nested_name$_MIN =\n"
198 " $classname$_$nested_name$_MIN;\n" 151 " $classname$_$nested_name$_MIN;\n"
199 "static const $nested_name$ $nested_name$_MAX =\n" 152 "static const $nested_name$ $nested_name$_MAX =\n"
200 " $classname$_$nested_name$_MAX;\n"); 153 " $classname$_$nested_name$_MAX;\n"
201 if (generate_array_size_) { 154 "static const int $nested_name$_ARRAYSIZE =\n"
202 printer->Print(vars, 155 " $classname$_$nested_name$_ARRAYSIZE;\n");
203 "static const int $nested_name$_ARRAYSIZE =\n"
204 " $classname$_$nested_name$_ARRAYSIZE;\n");
205 }
206 156
207 if (HasDescriptorMethods(descriptor_->file())) { 157 if (HasDescriptorMethods(descriptor_->file())) {
208 printer->Print(vars, 158 printer->Print(vars,
209 "static inline const ::google::protobuf::EnumDescriptor*\n" 159 "static inline const ::google::protobuf::EnumDescriptor*\n"
210 "$nested_name$_descriptor() {\n" 160 "$nested_name$_descriptor() {\n"
211 " return $classname$_descriptor();\n" 161 " return $classname$_descriptor();\n"
212 "}\n"); 162 "}\n");
213 printer->Print(vars, 163 printer->Print(vars,
214 "static inline const ::std::string& $nested_name$_Name($nested_name$ value ) {\n" 164 "static inline const ::std::string& $nested_name$_Name($nested_name$ value ) {\n"
215 " return $classname$_Name(value);\n" 165 " return $classname$_Name(value);\n"
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 set<int> numbers; 211 set<int> numbers;
262 for (int j = 0; j < descriptor_->value_count(); j++) { 212 for (int j = 0; j < descriptor_->value_count(); j++) {
263 const EnumValueDescriptor* value = descriptor_->value(j); 213 const EnumValueDescriptor* value = descriptor_->value(j);
264 numbers.insert(value->number()); 214 numbers.insert(value->number());
265 } 215 }
266 216
267 for (set<int>::iterator iter = numbers.begin(); 217 for (set<int>::iterator iter = numbers.begin();
268 iter != numbers.end(); ++iter) { 218 iter != numbers.end(); ++iter) {
269 printer->Print( 219 printer->Print(
270 " case $number$:\n", 220 " case $number$:\n",
271 "number", Int32ToString(*iter)); 221 "number", SimpleItoa(*iter));
272 } 222 }
273 223
274 printer->Print(vars, 224 printer->Print(vars,
275 " return true;\n" 225 " return true;\n"
276 " default:\n" 226 " default:\n"
277 " return false;\n" 227 " return false;\n"
278 " }\n" 228 " }\n"
279 "}\n" 229 "}\n"
280 "\n"); 230 "\n");
281 231
282 if (descriptor_->containing_type() != NULL) { 232 if (descriptor_->containing_type() != NULL) {
283 // We need to "define" the static constants which were declared in the 233 // We need to "define" the static constants which were declared in the
284 // header, to give the linker a place to put them. Or at least the C++ 234 // header, to give the linker a place to put them. Or at least the C++
285 // standard says we have to. MSVC actually insists tha we do _not_ define 235 // standard says we have to. MSVC actually insists tha we do _not_ define
286 // them again in the .cc file. 236 // them again in the .cc file.
287 printer->Print("#ifndef _MSC_VER\n"); 237 printer->Print("#ifndef _MSC_VER\n");
288 238
289 vars["parent"] = ClassName(descriptor_->containing_type(), false); 239 vars["parent"] = ClassName(descriptor_->containing_type(), false);
290 vars["nested_name"] = descriptor_->name(); 240 vars["nested_name"] = descriptor_->name();
291 for (int i = 0; i < descriptor_->value_count(); i++) { 241 for (int i = 0; i < descriptor_->value_count(); i++) {
292 vars["value"] = EnumValueName(descriptor_->value(i)); 242 vars["value"] = descriptor_->value(i)->name();
293 printer->Print(vars, 243 printer->Print(vars,
294 "const $classname$ $parent$::$value$;\n"); 244 "const $classname$ $parent$::$value$;\n");
295 } 245 }
296 printer->Print(vars, 246 printer->Print(vars,
297 "const $classname$ $parent$::$nested_name$_MIN;\n" 247 "const $classname$ $parent$::$nested_name$_MIN;\n"
298 "const $classname$ $parent$::$nested_name$_MAX;\n"); 248 "const $classname$ $parent$::$nested_name$_MAX;\n"
299 if (generate_array_size_) { 249 "const int $parent$::$nested_name$_ARRAYSIZE;\n");
300 printer->Print(vars,
301 "const int $parent$::$nested_name$_ARRAYSIZE;\n");
302 }
303 250
304 printer->Print("#endif // _MSC_VER\n"); 251 printer->Print("#endif // _MSC_VER\n");
305 } 252 }
306 } 253 }
307 254
308 } // namespace cpp 255 } // namespace cpp
309 } // namespace compiler 256 } // namespace compiler
310 } // namespace protobuf 257 } // namespace protobuf
311 } // namespace google 258 } // namespace google
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698