OLD | NEW |
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 // https://developers.google.com/protocol-buffers/ |
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. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor, | 62 EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor, |
63 const Options& options) | 63 const Options& options) |
64 : descriptor_(descriptor), | 64 : descriptor_(descriptor), |
65 classname_(ClassName(descriptor, false)), | 65 classname_(ClassName(descriptor, false)), |
66 options_(options), | 66 options_(options), |
67 generate_array_size_(ShouldGenerateArraySize(descriptor)) { | 67 generate_array_size_(ShouldGenerateArraySize(descriptor)) { |
68 } | 68 } |
69 | 69 |
70 EnumGenerator::~EnumGenerator() {} | 70 EnumGenerator::~EnumGenerator() {} |
71 | 71 |
72 void EnumGenerator::FillForwardDeclaration(set<string>* enum_names) { | 72 void EnumGenerator::FillForwardDeclaration( |
| 73 map<string, const EnumDescriptor*>* enum_names) { |
73 if (!options_.proto_h) { | 74 if (!options_.proto_h) { |
74 return; | 75 return; |
75 } | 76 } |
76 enum_names->insert(classname_); | 77 (*enum_names)[classname_] = descriptor_; |
77 } | 78 } |
78 | 79 |
79 void EnumGenerator::GenerateDefinition(io::Printer* printer) { | 80 void EnumGenerator::GenerateDefinition(io::Printer* printer) { |
80 map<string, string> vars; | 81 map<string, string> vars; |
81 vars["classname"] = classname_; | 82 vars["classname"] = classname_; |
82 vars["short_name"] = descriptor_->name(); | 83 vars["short_name"] = descriptor_->name(); |
83 vars["enumbase"] = classname_ + (options_.proto_h ? " : int" : ""); | 84 vars["enumbase"] = classname_ + (options_.proto_h ? " : int" : ""); |
84 | 85 |
85 printer->Print(vars, "enum $enumbase$ {\n"); | 86 printer->Print(vars, "enum $enumbase$ {\n"); |
| 87 printer->Annotate("enumbase", descriptor_); |
86 printer->Indent(); | 88 printer->Indent(); |
87 | 89 |
88 const EnumValueDescriptor* min_value = descriptor_->value(0); | 90 const EnumValueDescriptor* min_value = descriptor_->value(0); |
89 const EnumValueDescriptor* max_value = descriptor_->value(0); | 91 const EnumValueDescriptor* max_value = descriptor_->value(0); |
90 | 92 |
91 for (int i = 0; i < descriptor_->value_count(); i++) { | 93 for (int i = 0; i < descriptor_->value_count(); i++) { |
92 vars["name"] = EnumValueName(descriptor_->value(i)); | 94 vars["name"] = EnumValueName(descriptor_->value(i)); |
93 // In C++, an value of -2147483648 gets interpreted as the negative of | 95 // In C++, an value of -2147483648 gets interpreted as the negative of |
94 // 2147483648, and since 2147483648 can't fit in an integer, this produces a | 96 // 2147483648, and since 2147483648 can't fit in an integer, this produces a |
95 // compiler warning. This works around that issue. | 97 // compiler warning. This works around that issue. |
96 vars["number"] = Int32ToString(descriptor_->value(i)->number()); | 98 vars["number"] = Int32ToString(descriptor_->value(i)->number()); |
97 vars["prefix"] = (descriptor_->containing_type() == NULL) ? | 99 vars["prefix"] = (descriptor_->containing_type() == NULL) ? |
98 "" : classname_ + "_"; | 100 "" : classname_ + "_"; |
| 101 vars["deprecation"] = descriptor_->value(i)->options().deprecated() ? |
| 102 " PROTOBUF_DEPRECATED" : ""; |
99 | 103 |
100 if (i > 0) printer->Print(",\n"); | 104 if (i > 0) printer->Print(",\n"); |
101 printer->Print(vars, "$prefix$$name$ = $number$"); | 105 printer->Print(vars, "$prefix$$name$$deprecation$ = $number$"); |
102 | 106 |
103 if (descriptor_->value(i)->number() < min_value->number()) { | 107 if (descriptor_->value(i)->number() < min_value->number()) { |
104 min_value = descriptor_->value(i); | 108 min_value = descriptor_->value(i); |
105 } | 109 } |
106 if (descriptor_->value(i)->number() > max_value->number()) { | 110 if (descriptor_->value(i)->number() > max_value->number()) { |
107 max_value = descriptor_->value(i); | 111 max_value = descriptor_->value(i); |
108 } | 112 } |
109 } | 113 } |
110 | 114 |
111 if (HasPreservingUnknownEnumSemantics(descriptor_->file())) { | 115 if (HasPreservingUnknownEnumSemantics(descriptor_->file())) { |
(...skipping 21 matching lines...) Expand all Loading... |
133 "$dllexport$bool $classname$_IsValid(int value);\n" | 137 "$dllexport$bool $classname$_IsValid(int value);\n" |
134 "const $classname$ $prefix$$short_name$_MIN = $prefix$$min_name$;\n" | 138 "const $classname$ $prefix$$short_name$_MIN = $prefix$$min_name$;\n" |
135 "const $classname$ $prefix$$short_name$_MAX = $prefix$$max_name$;\n"); | 139 "const $classname$ $prefix$$short_name$_MAX = $prefix$$max_name$;\n"); |
136 | 140 |
137 if (generate_array_size_) { | 141 if (generate_array_size_) { |
138 printer->Print(vars, | 142 printer->Print(vars, |
139 "const int $prefix$$short_name$_ARRAYSIZE = " | 143 "const int $prefix$$short_name$_ARRAYSIZE = " |
140 "$prefix$$short_name$_MAX + 1;\n\n"); | 144 "$prefix$$short_name$_MAX + 1;\n\n"); |
141 } | 145 } |
142 | 146 |
143 if (HasDescriptorMethods(descriptor_->file())) { | 147 if (HasDescriptorMethods(descriptor_->file(), options_)) { |
144 printer->Print(vars, | 148 printer->Print(vars, |
145 "$dllexport$const ::google::protobuf::EnumDescriptor* $classname$_descript
or();\n"); | 149 "$dllexport$const ::google::protobuf::EnumDescriptor* $classname$_descript
or();\n"); |
146 // The _Name and _Parse methods | 150 // The _Name and _Parse methods |
147 printer->Print(vars, | 151 printer->Print( |
148 "inline const ::std::string& $classname$_Name($classname$ value) {\n" | 152 vars, |
149 " return ::google::protobuf::internal::NameOfEnum(\n" | 153 "inline const ::std::string& $classname$_Name($classname$ value) {\n" |
150 " $classname$_descriptor(), value);\n" | 154 " return ::google::protobuf::internal::NameOfEnum(\n" |
151 "}\n"); | 155 " $classname$_descriptor(), value);\n" |
| 156 "}\n"); |
152 printer->Print(vars, | 157 printer->Print(vars, |
153 "inline bool $classname$_Parse(\n" | 158 "inline bool $classname$_Parse(\n" |
154 " const ::std::string& name, $classname$* value) {\n" | 159 " const ::std::string& name, $classname$* value) {\n" |
155 " return ::google::protobuf::internal::ParseNamedEnum<$classname$>(\n" | 160 " return ::google::protobuf::internal::ParseNamedEnum<$classname$>(\n" |
156 " $classname$_descriptor(), name, value);\n" | 161 " $classname$_descriptor(), name, value);\n" |
157 "}\n"); | 162 "}\n"); |
158 } | 163 } |
159 } | 164 } |
160 | 165 |
161 void EnumGenerator:: | 166 void EnumGenerator:: |
162 GenerateGetEnumDescriptorSpecializations(io::Printer* printer) { | 167 GenerateGetEnumDescriptorSpecializations(io::Printer* printer) { |
163 printer->Print( | 168 printer->Print( |
164 "template <> struct is_proto_enum< $classname$> : ::google::protobuf::inte
rnal::true_type " | 169 "template <> struct is_proto_enum< $classname$> : ::google::protobuf::inte
rnal::true_type " |
165 "{};\n", | 170 "{};\n", |
166 "classname", ClassName(descriptor_, true)); | 171 "classname", ClassName(descriptor_, true)); |
167 if (HasDescriptorMethods(descriptor_->file())) { | 172 if (HasDescriptorMethods(descriptor_->file(), options_)) { |
168 printer->Print( | 173 printer->Print( |
169 "template <>\n" | 174 "template <>\n" |
170 "inline const EnumDescriptor* GetEnumDescriptor< $classname$>() {\n" | 175 "inline const EnumDescriptor* GetEnumDescriptor< $classname$>() {\n" |
171 " return $classname$_descriptor();\n" | 176 " return $classname$_descriptor();\n" |
172 "}\n", | 177 "}\n", |
173 "classname", ClassName(descriptor_, true)); | 178 "classname", ClassName(descriptor_, true)); |
174 } | 179 } |
175 } | 180 } |
176 | 181 |
177 void EnumGenerator::GenerateSymbolImports(io::Printer* printer) { | 182 void EnumGenerator::GenerateSymbolImports(io::Printer* printer) { |
178 map<string, string> vars; | 183 map<string, string> vars; |
179 vars["nested_name"] = descriptor_->name(); | 184 vars["nested_name"] = descriptor_->name(); |
180 vars["classname"] = classname_; | 185 vars["classname"] = classname_; |
| 186 vars["constexpr"] = options_.proto_h ? "constexpr " : ""; |
181 printer->Print(vars, "typedef $classname$ $nested_name$;\n"); | 187 printer->Print(vars, "typedef $classname$ $nested_name$;\n"); |
182 | 188 |
183 for (int j = 0; j < descriptor_->value_count(); j++) { | 189 for (int j = 0; j < descriptor_->value_count(); j++) { |
184 vars["tag"] = EnumValueName(descriptor_->value(j)); | 190 vars["tag"] = EnumValueName(descriptor_->value(j)); |
| 191 vars["deprecated_attr"] = descriptor_->value(j)->options().deprecated() ? |
| 192 "PROTOBUF_DEPRECATED_ATTR " : ""; |
185 printer->Print(vars, | 193 printer->Print(vars, |
186 "static const $nested_name$ $tag$ = $classname$_$tag$;\n"); | 194 "$deprecated_attr$static $constexpr$const $nested_name$ $tag$ =\n" |
| 195 " $classname$_$tag$;\n"); |
187 } | 196 } |
188 | 197 |
189 printer->Print(vars, | 198 printer->Print(vars, |
190 "static inline bool $nested_name$_IsValid(int value) {\n" | 199 "static inline bool $nested_name$_IsValid(int value) {\n" |
191 " return $classname$_IsValid(value);\n" | 200 " return $classname$_IsValid(value);\n" |
192 "}\n" | 201 "}\n" |
193 "static const $nested_name$ $nested_name$_MIN =\n" | 202 "static const $nested_name$ $nested_name$_MIN =\n" |
194 " $classname$_$nested_name$_MIN;\n" | 203 " $classname$_$nested_name$_MIN;\n" |
195 "static const $nested_name$ $nested_name$_MAX =\n" | 204 "static const $nested_name$ $nested_name$_MAX =\n" |
196 " $classname$_$nested_name$_MAX;\n"); | 205 " $classname$_$nested_name$_MAX;\n"); |
197 if (generate_array_size_) { | 206 if (generate_array_size_) { |
198 printer->Print(vars, | 207 printer->Print(vars, |
199 "static const int $nested_name$_ARRAYSIZE =\n" | 208 "static const int $nested_name$_ARRAYSIZE =\n" |
200 " $classname$_$nested_name$_ARRAYSIZE;\n"); | 209 " $classname$_$nested_name$_ARRAYSIZE;\n"); |
201 } | 210 } |
202 | 211 |
203 if (HasDescriptorMethods(descriptor_->file())) { | 212 if (HasDescriptorMethods(descriptor_->file(), options_)) { |
204 printer->Print(vars, | 213 printer->Print(vars, |
205 "static inline const ::google::protobuf::EnumDescriptor*\n" | 214 "static inline const ::google::protobuf::EnumDescriptor*\n" |
206 "$nested_name$_descriptor() {\n" | 215 "$nested_name$_descriptor() {\n" |
207 " return $classname$_descriptor();\n" | 216 " return $classname$_descriptor();\n" |
208 "}\n"); | 217 "}\n"); |
209 printer->Print(vars, | 218 printer->Print(vars, |
210 "static inline const ::std::string& $nested_name$_Name($nested_name$ value
) {\n" | 219 "static inline const ::std::string& " |
211 " return $classname$_Name(value);\n" | 220 "$nested_name$_Name($nested_name$ value) {" |
212 "}\n"); | 221 "\n" |
| 222 " return $classname$_Name(value);\n" |
| 223 "}\n"); |
213 printer->Print(vars, | 224 printer->Print(vars, |
214 "static inline bool $nested_name$_Parse(const ::std::string& name,\n" | 225 "static inline bool $nested_name$_Parse(const ::std::string& name,\n" |
215 " $nested_name$* value) {\n" | 226 " $nested_name$* value) {\n" |
216 " return $classname$_Parse(name, value);\n" | 227 " return $classname$_Parse(name, value);\n" |
217 "}\n"); | 228 "}\n"); |
218 } | 229 } |
219 } | 230 } |
220 | 231 |
221 void EnumGenerator::GenerateDescriptorInitializer( | 232 void EnumGenerator::GenerateDescriptorInitializer( |
222 io::Printer* printer, int index) { | 233 io::Printer* printer, int index) { |
223 map<string, string> vars; | 234 map<string, string> vars; |
224 vars["classname"] = classname_; | 235 vars["classname"] = classname_; |
225 vars["index"] = SimpleItoa(index); | 236 vars["index"] = SimpleItoa(index); |
226 | 237 |
227 if (descriptor_->containing_type() == NULL) { | 238 if (descriptor_->containing_type() == NULL) { |
228 printer->Print(vars, | 239 printer->Print(vars, |
229 "$classname$_descriptor_ = file->enum_type($index$);\n"); | 240 "$classname$_descriptor_ = file->enum_type($index$);\n"); |
230 } else { | 241 } else { |
231 vars["parent"] = ClassName(descriptor_->containing_type(), false); | 242 vars["parent"] = ClassName(descriptor_->containing_type(), false); |
232 printer->Print(vars, | 243 printer->Print(vars, |
233 "$classname$_descriptor_ = $parent$_descriptor_->enum_type($index$);\n"); | 244 "$classname$_descriptor_ = $parent$_descriptor_->enum_type($index$);\n"); |
234 } | 245 } |
235 } | 246 } |
236 | 247 |
237 void EnumGenerator::GenerateMethods(io::Printer* printer) { | 248 void EnumGenerator::GenerateMethods(io::Printer* printer) { |
238 map<string, string> vars; | 249 map<string, string> vars; |
239 vars["classname"] = classname_; | 250 vars["classname"] = classname_; |
| 251 vars["constexpr"] = options_.proto_h ? "constexpr " : ""; |
240 | 252 |
241 if (HasDescriptorMethods(descriptor_->file())) { | 253 if (HasDescriptorMethods(descriptor_->file(), options_)) { |
242 printer->Print(vars, | 254 printer->Print(vars, |
243 "const ::google::protobuf::EnumDescriptor* $classname$_descriptor() {\n" | 255 "const ::google::protobuf::EnumDescriptor* $classname$_descriptor() {\n" |
244 " protobuf_AssignDescriptorsOnce();\n" | 256 " protobuf_AssignDescriptorsOnce();\n" |
245 " return $classname$_descriptor_;\n" | 257 " return $classname$_descriptor_;\n" |
246 "}\n"); | 258 "}\n"); |
247 } | 259 } |
248 | 260 |
249 printer->Print(vars, | 261 printer->Print(vars, |
250 "bool $classname$_IsValid(int value) {\n" | 262 "bool $classname$_IsValid(int value) {\n" |
251 " switch(value) {\n"); | 263 " switch(value) {\n"); |
(...skipping 28 matching lines...) Expand all Loading... |
280 // header, to give the linker a place to put them. Or at least the C++ | 292 // header, to give the linker a place to put them. Or at least the C++ |
281 // standard says we have to. MSVC actually insists that we do _not_ define | 293 // standard says we have to. MSVC actually insists that we do _not_ define |
282 // them again in the .cc file, prior to VC++ 2015. | 294 // them again in the .cc file, prior to VC++ 2015. |
283 printer->Print("#if !defined(_MSC_VER) || _MSC_VER >= 1900\n"); | 295 printer->Print("#if !defined(_MSC_VER) || _MSC_VER >= 1900\n"); |
284 | 296 |
285 vars["parent"] = ClassName(descriptor_->containing_type(), false); | 297 vars["parent"] = ClassName(descriptor_->containing_type(), false); |
286 vars["nested_name"] = descriptor_->name(); | 298 vars["nested_name"] = descriptor_->name(); |
287 for (int i = 0; i < descriptor_->value_count(); i++) { | 299 for (int i = 0; i < descriptor_->value_count(); i++) { |
288 vars["value"] = EnumValueName(descriptor_->value(i)); | 300 vars["value"] = EnumValueName(descriptor_->value(i)); |
289 printer->Print(vars, | 301 printer->Print(vars, |
290 "const $classname$ $parent$::$value$;\n"); | 302 "$constexpr$const $classname$ $parent$::$value$;\n"); |
291 } | 303 } |
292 printer->Print(vars, | 304 printer->Print(vars, |
293 "const $classname$ $parent$::$nested_name$_MIN;\n" | 305 "const $classname$ $parent$::$nested_name$_MIN;\n" |
294 "const $classname$ $parent$::$nested_name$_MAX;\n"); | 306 "const $classname$ $parent$::$nested_name$_MAX;\n"); |
295 if (generate_array_size_) { | 307 if (generate_array_size_) { |
296 printer->Print(vars, | 308 printer->Print(vars, |
297 "const int $parent$::$nested_name$_ARRAYSIZE;\n"); | 309 "const int $parent$::$nested_name$_ARRAYSIZE;\n"); |
298 } | 310 } |
299 | 311 |
300 printer->Print("#endif // !defined(_MSC_VER) || _MSC_VER >= 1900\n"); | 312 printer->Print("#endif // !defined(_MSC_VER) || _MSC_VER >= 1900\n"); |
301 } | 313 } |
302 } | 314 } |
303 | 315 |
304 } // namespace cpp | 316 } // namespace cpp |
305 } // namespace compiler | 317 } // namespace compiler |
306 } // namespace protobuf | 318 } // namespace protobuf |
307 } // namespace google | 319 } // namespace google |
OLD | NEW |