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 #include <google/protobuf/stubs/once.h> | 62 #include <google/protobuf/stubs/once.h> |
63 #include <google/protobuf/stubs/stringprintf.h> | 63 #include <google/protobuf/stubs/stringprintf.h> |
64 #include <google/protobuf/stubs/strutil.h> | 64 #include <google/protobuf/stubs/strutil.h> |
65 #include <google/protobuf/stubs/substitute.h> | 65 #include <google/protobuf/stubs/substitute.h> |
66 #include <google/protobuf/stubs/map_util.h> | 66 #include <google/protobuf/stubs/map_util.h> |
67 #include <google/protobuf/stubs/stl_util.h> | 67 #include <google/protobuf/stubs/stl_util.h> |
68 | 68 |
69 #undef PACKAGE // autoheader #defines this. :( | 69 #undef PACKAGE // autoheader #defines this. :( |
70 | 70 |
71 namespace google { | 71 namespace google { |
72 | |
73 namespace protobuf { | 72 namespace protobuf { |
74 | 73 |
75 const FieldDescriptor::CppType | 74 const FieldDescriptor::CppType |
76 FieldDescriptor::kTypeToCppTypeMap[MAX_TYPE + 1] = { | 75 FieldDescriptor::kTypeToCppTypeMap[MAX_TYPE + 1] = { |
77 static_cast<CppType>(0), // 0 is reserved for errors | 76 static_cast<CppType>(0), // 0 is reserved for errors |
78 | 77 |
79 CPPTYPE_DOUBLE, // TYPE_DOUBLE | 78 CPPTYPE_DOUBLE, // TYPE_DOUBLE |
80 CPPTYPE_FLOAT, // TYPE_FLOAT | 79 CPPTYPE_FLOAT, // TYPE_FLOAT |
81 CPPTYPE_INT64, // TYPE_INT64 | 80 CPPTYPE_INT64, // TYPE_INT64 |
82 CPPTYPE_UINT64, // TYPE_UINT64 | 81 CPPTYPE_UINT64, // TYPE_UINT64 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 static const char * const kNonLinkedWeakMessageReplacementName = "google.protobu
f.Empty"; | 157 static const char * const kNonLinkedWeakMessageReplacementName = "google.protobu
f.Empty"; |
159 | 158 |
160 #if !defined(_MSC_VER) || _MSC_VER >= 1900 | 159 #if !defined(_MSC_VER) || _MSC_VER >= 1900 |
161 const int FieldDescriptor::kMaxNumber; | 160 const int FieldDescriptor::kMaxNumber; |
162 const int FieldDescriptor::kFirstReservedNumber; | 161 const int FieldDescriptor::kFirstReservedNumber; |
163 const int FieldDescriptor::kLastReservedNumber; | 162 const int FieldDescriptor::kLastReservedNumber; |
164 #endif | 163 #endif |
165 | 164 |
166 namespace { | 165 namespace { |
167 | 166 |
168 // Note: I distrust ctype.h due to locales. | |
169 char ToUpper(char ch) { | |
170 return (ch >= 'a' && ch <= 'z') ? (ch - 'a' + 'A') : ch; | |
171 } | |
172 | |
173 char ToLower(char ch) { | |
174 return (ch >= 'A' && ch <= 'Z') ? (ch - 'A' + 'a') : ch; | |
175 } | |
176 | |
177 string ToCamelCase(const string& input, bool lower_first) { | 167 string ToCamelCase(const string& input, bool lower_first) { |
178 bool capitalize_next = !lower_first; | 168 bool capitalize_next = !lower_first; |
179 string result; | 169 string result; |
180 result.reserve(input.size()); | 170 result.reserve(input.size()); |
181 | 171 |
182 for (int i = 0; i < input.size(); i++) { | 172 for (int i = 0; i < input.size(); i++) { |
183 if (input[i] == '_') { | 173 if (input[i] == '_') { |
184 capitalize_next = true; | 174 capitalize_next = true; |
185 } else if (capitalize_next) { | 175 } else if (capitalize_next) { |
186 result.push_back(ToUpper(input[i])); | 176 // Note: I distrust ctype.h due to locales. |
| 177 if ('a' <= input[i] && input[i] <= 'z') { |
| 178 result.push_back(input[i] - 'a' + 'A'); |
| 179 } else { |
| 180 result.push_back(input[i]); |
| 181 } |
187 capitalize_next = false; | 182 capitalize_next = false; |
188 } else { | 183 } else { |
189 result.push_back(input[i]); | 184 result.push_back(input[i]); |
190 } | 185 } |
191 } | 186 } |
192 | 187 |
193 // Lower-case the first letter. | 188 // Lower-case the first letter. |
194 if (lower_first && !result.empty()) { | 189 if (lower_first && !result.empty() && 'A' <= result[0] && result[0] <= 'Z') { |
195 result[0] = ToLower(result[0]); | 190 result[0] = result[0] - 'A' + 'a'; |
196 } | 191 } |
197 | 192 |
198 return result; | 193 return result; |
199 } | 194 } |
200 | 195 |
201 string ToJsonName(const string& input) { | |
202 bool capitalize_next = false; | |
203 string result; | |
204 result.reserve(input.size()); | |
205 | |
206 for (int i = 0; i < input.size(); i++) { | |
207 if (input[i] == '_') { | |
208 capitalize_next = true; | |
209 } else if (capitalize_next) { | |
210 result.push_back(ToUpper(input[i])); | |
211 capitalize_next = false; | |
212 } else { | |
213 result.push_back(input[i]); | |
214 } | |
215 } | |
216 | |
217 return result; | |
218 } | |
219 | |
220 string EnumValueToPascalCase(const string& input) { | |
221 bool next_upper = true; | |
222 string result; | |
223 result.reserve(input.size()); | |
224 | |
225 for (int i = 0; i < input.size(); i++) { | |
226 if (input[i] == '_') { | |
227 next_upper = true; | |
228 } else { | |
229 if (next_upper) { | |
230 result.push_back(ToUpper(input[i])); | |
231 } else { | |
232 result.push_back(ToLower(input[i])); | |
233 } | |
234 next_upper = false; | |
235 } | |
236 } | |
237 | |
238 return result; | |
239 } | |
240 | |
241 // Class to remove an enum prefix from enum values. | |
242 class PrefixRemover { | |
243 public: | |
244 PrefixRemover(StringPiece prefix) { | |
245 // Strip underscores and lower-case the prefix. | |
246 for (int i = 0; i < prefix.size(); i++) { | |
247 if (prefix[i] != '_') { | |
248 prefix_ += ascii_tolower(prefix[i]); | |
249 } | |
250 } | |
251 } | |
252 | |
253 // Tries to remove the enum prefix from this enum value. | |
254 // If this is not possible, returns the input verbatim. | |
255 string MaybeRemove(StringPiece str) { | |
256 // We can't just lowercase and strip str and look for a prefix. | |
257 // We need to properly recognize the difference between: | |
258 // | |
259 // enum Foo { | |
260 // FOO_BAR_BAZ = 0; | |
261 // FOO_BARBAZ = 1; | |
262 // } | |
263 // | |
264 // This is acceptable (though perhaps not advisable) because even when | |
265 // we PascalCase, these two will still be distinct (BarBaz vs. Barbaz). | |
266 size_t i, j; | |
267 | |
268 // Skip past prefix_ in str if we can. | |
269 for (i = 0, j = 0; i < str.size() && j < prefix_.size(); i++) { | |
270 if (str[i] == '_') { | |
271 continue; | |
272 } | |
273 | |
274 if (ascii_tolower(str[i]) != prefix_[j++]) { | |
275 return str.as_string(); | |
276 } | |
277 } | |
278 | |
279 // If we didn't make it through the prefix, we've failed to strip the | |
280 // prefix. | |
281 if (j < prefix_.size()) { | |
282 return str.as_string(); | |
283 } | |
284 | |
285 // Skip underscores between prefix and further characters. | |
286 while (i < str.size() && str[i] == '_') { | |
287 i++; | |
288 } | |
289 | |
290 // Enum label can't be the empty string. | |
291 if (i == str.size()) { | |
292 return str.as_string(); | |
293 } | |
294 | |
295 // We successfully stripped the prefix. | |
296 str.remove_prefix(i); | |
297 return str.as_string(); | |
298 } | |
299 | |
300 private: | |
301 string prefix_; | |
302 }; | |
303 | |
304 // A DescriptorPool contains a bunch of hash_maps to implement the | 196 // A DescriptorPool contains a bunch of hash_maps to implement the |
305 // various Find*By*() methods. Since hashtable lookups are O(1), it's | 197 // various Find*By*() methods. Since hashtable lookups are O(1), it's |
306 // most efficient to construct a fixed set of large hash_maps used by | 198 // most efficient to construct a fixed set of large hash_maps used by |
307 // all objects in the pool rather than construct one or more small | 199 // all objects in the pool rather than construct one or more small |
308 // hash_maps for each object. | 200 // hash_maps for each object. |
309 // | 201 // |
310 // The keys to these hash_maps are (parent, name) or (parent, number) | 202 // The keys to these hash_maps are (parent, name) or (parent, number) |
311 // pairs. Unfortunately STL doesn't provide hash functions for pair<>, | 203 // pairs. Unfortunately STL doesn't provide hash functions for pair<>, |
312 // so we must invent our own. | 204 // so we must invent our own. |
313 // | 205 // |
314 // TODO(kenton): Use StringPiece rather than const char* in keys? It would | 206 // TODO(kenton): Use StringPiece rather than const char* in keys? It would |
315 // be a lot cleaner but we'd just have to convert it back to const char* | 207 // be a lot cleaner but we'd just have to convert it back to const char* |
316 // for the open source release. | 208 // for the open source release. |
317 | 209 |
318 typedef std::pair<const void*, const char*> PointerStringPair; | 210 typedef pair<const void*, const char*> PointerStringPair; |
319 | 211 |
320 struct PointerStringPairEqual { | 212 struct PointerStringPairEqual { |
321 inline bool operator()(const PointerStringPair& a, | 213 inline bool operator()(const PointerStringPair& a, |
322 const PointerStringPair& b) const { | 214 const PointerStringPair& b) const { |
323 return a.first == b.first && strcmp(a.second, b.second) == 0; | 215 return a.first == b.first && strcmp(a.second, b.second) == 0; |
324 } | 216 } |
325 }; | 217 }; |
326 | 218 |
327 template<typename PairType> | 219 template<typename PairType> |
328 struct PointerIntegerPairHash { | 220 struct PointerIntegerPairHash { |
329 size_t operator()(const PairType& p) const { | 221 size_t operator()(const PairType& p) const { |
330 // FIXME(kenton): What is the best way to compute this hash? I have | 222 // FIXME(kenton): What is the best way to compute this hash? I have |
331 // no idea! This seems a bit better than an XOR. | 223 // no idea! This seems a bit better than an XOR. |
332 return reinterpret_cast<intptr_t>(p.first) * ((1 << 16) - 1) + p.second; | 224 return reinterpret_cast<intptr_t>(p.first) * ((1 << 16) - 1) + p.second; |
333 } | 225 } |
334 | 226 |
335 #ifdef _MSC_VER | 227 #ifdef _MSC_VER |
336 // Used only by MSVC and platforms where hash_map is not available. | 228 // Used only by MSVC and platforms where hash_map is not available. |
337 static const size_t bucket_size = 4; | 229 static const size_t bucket_size = 4; |
338 static const size_t min_buckets = 8; | 230 static const size_t min_buckets = 8; |
339 #endif | 231 #endif |
340 inline bool operator()(const PairType& a, const PairType& b) const { | 232 inline bool operator()(const PairType& a, const PairType& b) const { |
341 return a.first < b.first || | 233 return a.first < b.first || |
342 (a.first == b.first && a.second < b.second); | 234 (a.first == b.first && a.second < b.second); |
343 } | 235 } |
344 }; | 236 }; |
345 | 237 |
346 typedef std::pair<const Descriptor*, int> DescriptorIntPair; | 238 typedef pair<const Descriptor*, int> DescriptorIntPair; |
347 typedef std::pair<const EnumDescriptor*, int> EnumIntPair; | 239 typedef pair<const EnumDescriptor*, int> EnumIntPair; |
348 | 240 |
349 struct PointerStringPairHash { | 241 struct PointerStringPairHash { |
350 size_t operator()(const PointerStringPair& p) const { | 242 size_t operator()(const PointerStringPair& p) const { |
351 // FIXME(kenton): What is the best way to compute this hash? I have | 243 // FIXME(kenton): What is the best way to compute this hash? I have |
352 // no idea! This seems a bit better than an XOR. | 244 // no idea! This seems a bit better than an XOR. |
353 hash<const char*> cstring_hash; | 245 hash<const char*> cstring_hash; |
354 return reinterpret_cast<intptr_t>(p.first) * ((1 << 16) - 1) + | 246 return reinterpret_cast<intptr_t>(p.first) * ((1 << 16) - 1) + |
355 cstring_hash(p.second); | 247 cstring_hash(p.second); |
356 } | 248 } |
357 | 249 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 typedef hash_map<DescriptorIntPair, const FieldDescriptor*, | 337 typedef hash_map<DescriptorIntPair, const FieldDescriptor*, |
446 PointerIntegerPairHash<DescriptorIntPair> > | 338 PointerIntegerPairHash<DescriptorIntPair> > |
447 FieldsByNumberMap; | 339 FieldsByNumberMap; |
448 typedef hash_map<EnumIntPair, const EnumValueDescriptor*, | 340 typedef hash_map<EnumIntPair, const EnumValueDescriptor*, |
449 PointerIntegerPairHash<EnumIntPair> > | 341 PointerIntegerPairHash<EnumIntPair> > |
450 EnumValuesByNumberMap; | 342 EnumValuesByNumberMap; |
451 // This is a map rather than a hash_map, since we use it to iterate | 343 // This is a map rather than a hash_map, since we use it to iterate |
452 // through all the extensions that extend a given Descriptor, and an | 344 // through all the extensions that extend a given Descriptor, and an |
453 // ordered data structure that implements lower_bound is convenient | 345 // ordered data structure that implements lower_bound is convenient |
454 // for that. | 346 // for that. |
455 typedef std::map<DescriptorIntPair, const FieldDescriptor*> | 347 typedef map<DescriptorIntPair, const FieldDescriptor*> |
456 ExtensionsGroupedByDescriptorMap; | 348 ExtensionsGroupedByDescriptorMap; |
457 typedef hash_map<string, const SourceCodeInfo_Location*> LocationsByPathMap; | 349 typedef hash_map<string, const SourceCodeInfo_Location*> LocationsByPathMap; |
458 | 350 |
459 std::set<string>* allowed_proto3_extendees_ = NULL; | 351 set<string>* allowed_proto3_extendees_ = NULL; |
460 GOOGLE_PROTOBUF_DECLARE_ONCE(allowed_proto3_extendees_init_); | 352 GOOGLE_PROTOBUF_DECLARE_ONCE(allowed_proto3_extendees_init_); |
461 | 353 |
462 void DeleteAllowedProto3Extendee() { | 354 void DeleteAllowedProto3Extendee() { |
463 delete allowed_proto3_extendees_; | 355 delete allowed_proto3_extendees_; |
464 } | 356 } |
465 | 357 |
466 void InitAllowedProto3Extendee() { | 358 void InitAllowedProto3Extendee() { |
467 allowed_proto3_extendees_ = new std::set<string>; | 359 allowed_proto3_extendees_ = new set<string>; |
468 const char* kOptionNames[] = { | 360 const char* kOptionNames[] = { |
469 "FileOptions", "MessageOptions", "FieldOptions", "EnumOptions", | 361 "FileOptions", "MessageOptions", "FieldOptions", "EnumOptions", |
470 "EnumValueOptions", "ServiceOptions", "MethodOptions"}; | 362 "EnumValueOptions", "ServiceOptions", "MethodOptions"}; |
471 for (int i = 0; i < GOOGLE_ARRAYSIZE(kOptionNames); ++i) { | 363 for (int i = 0; i < GOOGLE_ARRAYSIZE(kOptionNames); ++i) { |
472 // descriptor.proto has a different package name in opensource. We allow | 364 // descriptor.proto has a different package name in opensource. We allow |
473 // both so the opensource protocol compiler can also compile internal | 365 // both so the opensource protocol compiler can also compile internal |
474 // proto3 files with custom options. See: b/27567912 | 366 // proto3 files with custom options. See: b/27567912 |
475 allowed_proto3_extendees_->insert(string("google.protobuf.") + | 367 allowed_proto3_extendees_->insert(string("google.protobuf.") + |
476 kOptionNames[i]); | 368 kOptionNames[i]); |
477 // Split the word to trick the opensource processing scripts so they | 369 // Split the word to trick the opensource processing scripts so they |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
535 // checkpoints that were pushed onto the stack after it and marked as cleared. | 427 // checkpoints that were pushed onto the stack after it and marked as cleared. |
536 void ClearLastCheckpoint(); | 428 void ClearLastCheckpoint(); |
537 | 429 |
538 // Roll back the Tables to the state of the checkpoint at the top of the | 430 // Roll back the Tables to the state of the checkpoint at the top of the |
539 // stack, removing everything that was added after that point. | 431 // stack, removing everything that was added after that point. |
540 void RollbackToLastCheckpoint(); | 432 void RollbackToLastCheckpoint(); |
541 | 433 |
542 // The stack of files which are currently being built. Used to detect | 434 // The stack of files which are currently being built. Used to detect |
543 // cyclic dependencies when loading files from a DescriptorDatabase. Not | 435 // cyclic dependencies when loading files from a DescriptorDatabase. Not |
544 // used when fallback_database_ == NULL. | 436 // used when fallback_database_ == NULL. |
545 std::vector<string> pending_files_; | 437 vector<string> pending_files_; |
546 | 438 |
547 // A set of files which we have tried to load from the fallback database | 439 // A set of files which we have tried to load from the fallback database |
548 // and encountered errors. We will not attempt to load them again during | 440 // and encountered errors. We will not attempt to load them again during |
549 // execution of the current public API call, but for compatibility with | 441 // execution of the current public API call, but for compatibility with |
550 // legacy clients, this is cleared at the beginning of each public API call. | 442 // legacy clients, this is cleared at the beginning of each public API call. |
551 // Not used when fallback_database_ == NULL. | 443 // Not used when fallback_database_ == NULL. |
552 hash_set<string> known_bad_files_; | 444 hash_set<string> known_bad_files_; |
553 | 445 |
554 // A set of symbols which we have tried to load from the fallback database | 446 // A set of symbols which we have tried to load from the fallback database |
555 // and encountered errors. We will not attempt to load them again during | 447 // and encountered errors. We will not attempt to load them again during |
(...skipping 17 matching lines...) Expand all Loading... |
573 // declaring Symbol in descriptor.h, which would drag all kinds of other | 465 // declaring Symbol in descriptor.h, which would drag all kinds of other |
574 // stuff into the header. Yay C++. | 466 // stuff into the header. Yay C++. |
575 Symbol FindByNameHelper( | 467 Symbol FindByNameHelper( |
576 const DescriptorPool* pool, const string& name); | 468 const DescriptorPool* pool, const string& name); |
577 | 469 |
578 // These return NULL if not found. | 470 // These return NULL if not found. |
579 inline const FileDescriptor* FindFile(const string& key) const; | 471 inline const FileDescriptor* FindFile(const string& key) const; |
580 inline const FieldDescriptor* FindExtension(const Descriptor* extendee, | 472 inline const FieldDescriptor* FindExtension(const Descriptor* extendee, |
581 int number); | 473 int number); |
582 inline void FindAllExtensions(const Descriptor* extendee, | 474 inline void FindAllExtensions(const Descriptor* extendee, |
583 std::vector<const FieldDescriptor*>* out) const; | 475 vector<const FieldDescriptor*>* out) const; |
584 | 476 |
585 // ----------------------------------------------------------------- | 477 // ----------------------------------------------------------------- |
586 // Adding items. | 478 // Adding items. |
587 | 479 |
588 // These add items to the corresponding tables. They return false if | 480 // These add items to the corresponding tables. They return false if |
589 // the key already exists in the table. For AddSymbol(), the string passed | 481 // the key already exists in the table. For AddSymbol(), the string passed |
590 // in must be one that was constructed using AllocateString(), as it will | 482 // in must be one that was constructed using AllocateString(), as it will |
591 // be used as a key in the symbols_by_name_ map without copying. | 483 // be used as a key in the symbols_by_name_ map without copying. |
592 bool AddSymbol(const string& full_name, Symbol symbol); | 484 bool AddSymbol(const string& full_name, Symbol symbol); |
593 bool AddFile(const FileDescriptor* file); | 485 bool AddFile(const FileDescriptor* file); |
(...skipping 19 matching lines...) Expand all Loading... |
613 // Allocate a protocol message object. Some older versions of GCC have | 505 // Allocate a protocol message object. Some older versions of GCC have |
614 // trouble understanding explicit template instantiations in some cases, so | 506 // trouble understanding explicit template instantiations in some cases, so |
615 // in those cases we have to pass a dummy pointer of the right type as the | 507 // in those cases we have to pass a dummy pointer of the right type as the |
616 // parameter instead of specifying the type explicitly. | 508 // parameter instead of specifying the type explicitly. |
617 template<typename Type> Type* AllocateMessage(Type* dummy = NULL); | 509 template<typename Type> Type* AllocateMessage(Type* dummy = NULL); |
618 | 510 |
619 // Allocate a FileDescriptorTables object. | 511 // Allocate a FileDescriptorTables object. |
620 FileDescriptorTables* AllocateFileTables(); | 512 FileDescriptorTables* AllocateFileTables(); |
621 | 513 |
622 private: | 514 private: |
623 std::vector<string*> strings_; // All strings in the pool. | 515 vector<string*> strings_; // All strings in the pool. |
624 std::vector<Message*> messages_; // All messages in the pool. | 516 vector<Message*> messages_; // All messages in the pool. |
625 std::vector<FileDescriptorTables*> | 517 vector<FileDescriptorTables*> file_tables_; // All file tables in the pool. |
626 file_tables_; // All file tables in the pool. | 518 vector<void*> allocations_; // All other memory allocated in the pool. |
627 std::vector<void*> allocations_; // All other memory allocated in the pool. | |
628 | 519 |
629 SymbolsByNameMap symbols_by_name_; | 520 SymbolsByNameMap symbols_by_name_; |
630 FilesByNameMap files_by_name_; | 521 FilesByNameMap files_by_name_; |
631 ExtensionsGroupedByDescriptorMap extensions_; | 522 ExtensionsGroupedByDescriptorMap extensions_; |
632 | 523 |
633 struct CheckPoint { | 524 struct CheckPoint { |
634 explicit CheckPoint(const Tables* tables) | 525 explicit CheckPoint(const Tables* tables) |
635 : strings_before_checkpoint(tables->strings_.size()), | 526 : strings_before_checkpoint(tables->strings_.size()), |
636 messages_before_checkpoint(tables->messages_.size()), | 527 messages_before_checkpoint(tables->messages_.size()), |
637 file_tables_before_checkpoint(tables->file_tables_.size()), | 528 file_tables_before_checkpoint(tables->file_tables_.size()), |
638 allocations_before_checkpoint(tables->allocations_.size()), | 529 allocations_before_checkpoint(tables->allocations_.size()), |
639 pending_symbols_before_checkpoint( | 530 pending_symbols_before_checkpoint( |
640 tables->symbols_after_checkpoint_.size()), | 531 tables->symbols_after_checkpoint_.size()), |
641 pending_files_before_checkpoint( | 532 pending_files_before_checkpoint( |
642 tables->files_after_checkpoint_.size()), | 533 tables->files_after_checkpoint_.size()), |
643 pending_extensions_before_checkpoint( | 534 pending_extensions_before_checkpoint( |
644 tables->extensions_after_checkpoint_.size()) { | 535 tables->extensions_after_checkpoint_.size()) { |
645 } | 536 } |
646 int strings_before_checkpoint; | 537 int strings_before_checkpoint; |
647 int messages_before_checkpoint; | 538 int messages_before_checkpoint; |
648 int file_tables_before_checkpoint; | 539 int file_tables_before_checkpoint; |
649 int allocations_before_checkpoint; | 540 int allocations_before_checkpoint; |
650 int pending_symbols_before_checkpoint; | 541 int pending_symbols_before_checkpoint; |
651 int pending_files_before_checkpoint; | 542 int pending_files_before_checkpoint; |
652 int pending_extensions_before_checkpoint; | 543 int pending_extensions_before_checkpoint; |
653 }; | 544 }; |
654 std::vector<CheckPoint> checkpoints_; | 545 vector<CheckPoint> checkpoints_; |
655 std::vector<const char* > symbols_after_checkpoint_; | 546 vector<const char* > symbols_after_checkpoint_; |
656 std::vector<const char* > files_after_checkpoint_; | 547 vector<const char* > files_after_checkpoint_; |
657 std::vector<DescriptorIntPair> extensions_after_checkpoint_; | 548 vector<DescriptorIntPair> extensions_after_checkpoint_; |
658 | 549 |
659 // Allocate some bytes which will be reclaimed when the pool is | 550 // Allocate some bytes which will be reclaimed when the pool is |
660 // destroyed. | 551 // destroyed. |
661 void* AllocateBytes(int size); | 552 void* AllocateBytes(int size); |
662 }; | 553 }; |
663 | 554 |
664 // Contains tables specific to a particular file. These tables are not | 555 // Contains tables specific to a particular file. These tables are not |
665 // modified once the file has been constructed, so they need not be | 556 // modified once the file has been constructed, so they need not be |
666 // protected by a mutex. This makes operations that depend only on the | 557 // protected by a mutex. This makes operations that depend only on the |
667 // contents of a single file -- e.g. Descriptor::FindFieldByName() -- | 558 // contents of a single file -- e.g. Descriptor::FindFieldByName() -- |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
714 bool AddFieldByNumber(const FieldDescriptor* field); | 605 bool AddFieldByNumber(const FieldDescriptor* field); |
715 bool AddEnumValueByNumber(const EnumValueDescriptor* value); | 606 bool AddEnumValueByNumber(const EnumValueDescriptor* value); |
716 | 607 |
717 // Adds the field to the lowercase_name and camelcase_name maps. Never | 608 // Adds the field to the lowercase_name and camelcase_name maps. Never |
718 // fails because we allow duplicates; the first field by the name wins. | 609 // fails because we allow duplicates; the first field by the name wins. |
719 void AddFieldByStylizedNames(const FieldDescriptor* field); | 610 void AddFieldByStylizedNames(const FieldDescriptor* field); |
720 | 611 |
721 // Populates p->first->locations_by_path_ from p->second. | 612 // Populates p->first->locations_by_path_ from p->second. |
722 // Unusual signature dictated by GoogleOnceDynamic. | 613 // Unusual signature dictated by GoogleOnceDynamic. |
723 static void BuildLocationsByPath( | 614 static void BuildLocationsByPath( |
724 std::pair<const FileDescriptorTables*, const SourceCodeInfo*>* p); | 615 pair<const FileDescriptorTables*, const SourceCodeInfo*>* p); |
725 | 616 |
726 // Returns the location denoted by the specified path through info, | 617 // Returns the location denoted by the specified path through info, |
727 // or NULL if not found. | 618 // or NULL if not found. |
728 // The value of info must be that of the corresponding FileDescriptor. | 619 // The value of info must be that of the corresponding FileDescriptor. |
729 // (Conceptually a pure function, but stateful as an optimisation.) | 620 // (Conceptually a pure function, but stateful as an optimisation.) |
730 const SourceCodeInfo_Location* GetSourceLocation( | 621 const SourceCodeInfo_Location* GetSourceLocation( |
731 const std::vector<int>& path, const SourceCodeInfo* info) const; | 622 const vector<int>& path, const SourceCodeInfo* info) const; |
732 | 623 |
733 private: | 624 private: |
734 SymbolsByParentMap symbols_by_parent_; | 625 SymbolsByParentMap symbols_by_parent_; |
735 FieldsByNameMap fields_by_lowercase_name_; | 626 FieldsByNameMap fields_by_lowercase_name_; |
736 FieldsByNameMap fields_by_camelcase_name_; | 627 FieldsByNameMap fields_by_camelcase_name_; |
737 FieldsByNumberMap fields_by_number_; // Not including extensions. | 628 FieldsByNumberMap fields_by_number_; // Not including extensions. |
738 EnumValuesByNumberMap enum_values_by_number_; | 629 EnumValuesByNumberMap enum_values_by_number_; |
739 mutable EnumValuesByNumberMap unknown_enum_values_by_number_ | 630 mutable EnumValuesByNumberMap unknown_enum_values_by_number_ |
740 GOOGLE_GUARDED_BY(unknown_enum_values_mu_); | 631 GOOGLE_GUARDED_BY(unknown_enum_values_mu_); |
741 | 632 |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1002 } | 893 } |
1003 } | 894 } |
1004 | 895 |
1005 | 896 |
1006 inline const FieldDescriptor* DescriptorPool::Tables::FindExtension( | 897 inline const FieldDescriptor* DescriptorPool::Tables::FindExtension( |
1007 const Descriptor* extendee, int number) { | 898 const Descriptor* extendee, int number) { |
1008 return FindPtrOrNull(extensions_, std::make_pair(extendee, number)); | 899 return FindPtrOrNull(extensions_, std::make_pair(extendee, number)); |
1009 } | 900 } |
1010 | 901 |
1011 inline void DescriptorPool::Tables::FindAllExtensions( | 902 inline void DescriptorPool::Tables::FindAllExtensions( |
1012 const Descriptor* extendee, | 903 const Descriptor* extendee, vector<const FieldDescriptor*>* out) const { |
1013 std::vector<const FieldDescriptor*>* out) const { | |
1014 ExtensionsGroupedByDescriptorMap::const_iterator it = | 904 ExtensionsGroupedByDescriptorMap::const_iterator it = |
1015 extensions_.lower_bound(std::make_pair(extendee, 0)); | 905 extensions_.lower_bound(std::make_pair(extendee, 0)); |
1016 for (; it != extensions_.end() && it->first.first == extendee; ++it) { | 906 for (; it != extensions_.end() && it->first.first == extendee; ++it) { |
1017 out->push_back(it->second); | 907 out->push_back(it->second); |
1018 } | 908 } |
1019 } | 909 } |
1020 | 910 |
1021 // ------------------------------------------------------------------- | 911 // ------------------------------------------------------------------- |
1022 | 912 |
1023 bool DescriptorPool::Tables::AddSymbol( | 913 bool DescriptorPool::Tables::AddSymbol( |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1123 // internal use we could easily plug in one of our existing memory pool | 1013 // internal use we could easily plug in one of our existing memory pool |
1124 // allocators... | 1014 // allocators... |
1125 if (size == 0) return NULL; | 1015 if (size == 0) return NULL; |
1126 | 1016 |
1127 void* result = operator new(size); | 1017 void* result = operator new(size); |
1128 allocations_.push_back(result); | 1018 allocations_.push_back(result); |
1129 return result; | 1019 return result; |
1130 } | 1020 } |
1131 | 1021 |
1132 void FileDescriptorTables::BuildLocationsByPath( | 1022 void FileDescriptorTables::BuildLocationsByPath( |
1133 std::pair<const FileDescriptorTables*, const SourceCodeInfo*>* p) { | 1023 pair<const FileDescriptorTables*, const SourceCodeInfo*>* p) { |
1134 for (int i = 0, len = p->second->location_size(); i < len; ++i) { | 1024 for (int i = 0, len = p->second->location_size(); i < len; ++i) { |
1135 const SourceCodeInfo_Location* loc = &p->second->location().Get(i); | 1025 const SourceCodeInfo_Location* loc = &p->second->location().Get(i); |
1136 p->first->locations_by_path_[Join(loc->path(), ",")] = loc; | 1026 p->first->locations_by_path_[Join(loc->path(), ",")] = loc; |
1137 } | 1027 } |
1138 } | 1028 } |
1139 | 1029 |
1140 const SourceCodeInfo_Location* FileDescriptorTables::GetSourceLocation( | 1030 const SourceCodeInfo_Location* FileDescriptorTables::GetSourceLocation( |
1141 const std::vector<int>& path, const SourceCodeInfo* info) const { | 1031 const vector<int>& path, const SourceCodeInfo* info) const { |
1142 std::pair<const FileDescriptorTables*, const SourceCodeInfo*> p( | 1032 pair<const FileDescriptorTables*, const SourceCodeInfo*> p( |
1143 std::make_pair(this, info)); | 1033 std::make_pair(this, info)); |
1144 locations_by_path_once_.Init(&FileDescriptorTables::BuildLocationsByPath, &p); | 1034 locations_by_path_once_.Init(&FileDescriptorTables::BuildLocationsByPath, &p); |
1145 return FindPtrOrNull(locations_by_path_, Join(path, ",")); | 1035 return FindPtrOrNull(locations_by_path_, Join(path, ",")); |
1146 } | 1036 } |
1147 | 1037 |
1148 // =================================================================== | 1038 // =================================================================== |
1149 // DescriptorPool | 1039 // DescriptorPool |
1150 | 1040 |
1151 DescriptorPool::ErrorCollector::~ErrorCollector() {} | 1041 DescriptorPool::ErrorCollector::~ErrorCollector() {} |
1152 | 1042 |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1234 } | 1124 } |
1235 | 1125 |
1236 } // anonymous namespace | 1126 } // anonymous namespace |
1237 | 1127 |
1238 const DescriptorPool* DescriptorPool::generated_pool() { | 1128 const DescriptorPool* DescriptorPool::generated_pool() { |
1239 InitGeneratedPoolOnce(); | 1129 InitGeneratedPoolOnce(); |
1240 return generated_pool_; | 1130 return generated_pool_; |
1241 } | 1131 } |
1242 | 1132 |
1243 | 1133 |
1244 | |
1245 DescriptorPool* DescriptorPool::internal_generated_pool() { | 1134 DescriptorPool* DescriptorPool::internal_generated_pool() { |
1246 InitGeneratedPoolOnce(); | 1135 InitGeneratedPoolOnce(); |
1247 return generated_pool_; | 1136 return generated_pool_; |
1248 } | 1137 } |
1249 | 1138 |
1250 void DescriptorPool::InternalAddGeneratedFile( | 1139 void DescriptorPool::InternalAddGeneratedFile( |
1251 const void* encoded_file_descriptor, int size) { | 1140 const void* encoded_file_descriptor, int size) { |
1252 // So, this function is called in the process of initializing the | 1141 // So, this function is called in the process of initializing the |
1253 // descriptors for generated proto classes. Each generated .pb.cc file | 1142 // descriptors for generated proto classes. Each generated .pb.cc file |
1254 // has an internal procedure called AddDescriptors() which is called at | 1143 // has an internal procedure called AddDescriptors() which is called at |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1393 if (TryFindExtensionInFallbackDatabase(extendee, number)) { | 1282 if (TryFindExtensionInFallbackDatabase(extendee, number)) { |
1394 result = tables_->FindExtension(extendee, number); | 1283 result = tables_->FindExtension(extendee, number); |
1395 if (result != NULL) { | 1284 if (result != NULL) { |
1396 return result; | 1285 return result; |
1397 } | 1286 } |
1398 } | 1287 } |
1399 return NULL; | 1288 return NULL; |
1400 } | 1289 } |
1401 | 1290 |
1402 void DescriptorPool::FindAllExtensions( | 1291 void DescriptorPool::FindAllExtensions( |
1403 const Descriptor* extendee, | 1292 const Descriptor* extendee, vector<const FieldDescriptor*>* out) const { |
1404 std::vector<const FieldDescriptor*>* out) const { | |
1405 MutexLockMaybe lock(mutex_); | 1293 MutexLockMaybe lock(mutex_); |
1406 tables_->known_bad_symbols_.clear(); | 1294 tables_->known_bad_symbols_.clear(); |
1407 tables_->known_bad_files_.clear(); | 1295 tables_->known_bad_files_.clear(); |
1408 | 1296 |
1409 // Initialize tables_->extensions_ from the fallback database first | 1297 // Initialize tables_->extensions_ from the fallback database first |
1410 // (but do this only once per descriptor). | 1298 // (but do this only once per descriptor). |
1411 if (fallback_database_ != NULL && | 1299 if (fallback_database_ != NULL && |
1412 tables_->extensions_loaded_from_db_.count(extendee) == 0) { | 1300 tables_->extensions_loaded_from_db_.count(extendee) == 0) { |
1413 std::vector<int> numbers; | 1301 vector<int> numbers; |
1414 if (fallback_database_->FindAllExtensionNumbers(extendee->full_name(), | 1302 if (fallback_database_->FindAllExtensionNumbers(extendee->full_name(), |
1415 &numbers)) { | 1303 &numbers)) { |
1416 for (int i = 0; i < numbers.size(); ++i) { | 1304 for (int i = 0; i < numbers.size(); ++i) { |
1417 int number = numbers[i]; | 1305 int number = numbers[i]; |
1418 if (tables_->FindExtension(extendee, number) == NULL) { | 1306 if (tables_->FindExtension(extendee, number) == NULL) { |
1419 TryFindExtensionInFallbackDatabase(extendee, number); | 1307 TryFindExtensionInFallbackDatabase(extendee, number); |
1420 } | 1308 } |
1421 } | 1309 } |
1422 tables_->extensions_loaded_from_db_.insert(extendee); | 1310 tables_->extensions_loaded_from_db_.insert(extendee); |
1423 } | 1311 } |
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2001 proto->mutable_options()->CopyFrom(options()); | 1889 proto->mutable_options()->CopyFrom(options()); |
2002 } | 1890 } |
2003 } | 1891 } |
2004 | 1892 |
2005 void FieldDescriptor::CopyJsonNameTo(FieldDescriptorProto* proto) const { | 1893 void FieldDescriptor::CopyJsonNameTo(FieldDescriptorProto* proto) const { |
2006 proto->set_json_name(json_name()); | 1894 proto->set_json_name(json_name()); |
2007 } | 1895 } |
2008 | 1896 |
2009 void OneofDescriptor::CopyTo(OneofDescriptorProto* proto) const { | 1897 void OneofDescriptor::CopyTo(OneofDescriptorProto* proto) const { |
2010 proto->set_name(name()); | 1898 proto->set_name(name()); |
2011 if (&options() != &OneofOptions::default_instance()) { | |
2012 proto->mutable_options()->CopyFrom(options()); | |
2013 } | |
2014 } | 1899 } |
2015 | 1900 |
2016 void EnumDescriptor::CopyTo(EnumDescriptorProto* proto) const { | 1901 void EnumDescriptor::CopyTo(EnumDescriptorProto* proto) const { |
2017 proto->set_name(name()); | 1902 proto->set_name(name()); |
2018 | 1903 |
2019 for (int i = 0; i < value_count(); i++) { | 1904 for (int i = 0; i < value_count(); i++) { |
2020 value(i)->CopyTo(proto->add_value()); | 1905 value(i)->CopyTo(proto->add_value()); |
2021 } | 1906 } |
2022 | 1907 |
2023 if (&options() != &EnumOptions::default_instance()) { | 1908 if (&options() != &EnumOptions::default_instance()) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2068 } | 1953 } |
2069 if (server_streaming_) { | 1954 if (server_streaming_) { |
2070 proto->set_server_streaming(true); | 1955 proto->set_server_streaming(true); |
2071 } | 1956 } |
2072 } | 1957 } |
2073 | 1958 |
2074 // DebugString methods =============================================== | 1959 // DebugString methods =============================================== |
2075 | 1960 |
2076 namespace { | 1961 namespace { |
2077 | 1962 |
2078 bool RetrieveOptionsAssumingRightPool(int depth, const Message& options, | 1963 // Used by each of the option formatters. |
2079 std::vector<string>* option_entries) { | 1964 bool RetrieveOptions(int depth, |
| 1965 const Message &options, |
| 1966 vector<string> *option_entries) { |
2080 option_entries->clear(); | 1967 option_entries->clear(); |
2081 const Reflection* reflection = options.GetReflection(); | 1968 const Reflection* reflection = options.GetReflection(); |
2082 std::vector<const FieldDescriptor*> fields; | 1969 vector<const FieldDescriptor*> fields; |
2083 reflection->ListFields(options, &fields); | 1970 reflection->ListFields(options, &fields); |
2084 for (int i = 0; i < fields.size(); i++) { | 1971 for (int i = 0; i < fields.size(); i++) { |
2085 int count = 1; | 1972 int count = 1; |
2086 bool repeated = false; | 1973 bool repeated = false; |
2087 if (fields[i]->is_repeated()) { | 1974 if (fields[i]->is_repeated()) { |
2088 count = reflection->FieldSize(options, fields[i]); | 1975 count = reflection->FieldSize(options, fields[i]); |
2089 repeated = true; | 1976 repeated = true; |
2090 } | 1977 } |
2091 for (int j = 0; j < count; j++) { | 1978 for (int j = 0; j < count; j++) { |
2092 string fieldval; | 1979 string fieldval; |
(...skipping 16 matching lines...) Expand all Loading... |
2109 name = "(." + fields[i]->full_name() + ")"; | 1996 name = "(." + fields[i]->full_name() + ")"; |
2110 } else { | 1997 } else { |
2111 name = fields[i]->name(); | 1998 name = fields[i]->name(); |
2112 } | 1999 } |
2113 option_entries->push_back(name + " = " + fieldval); | 2000 option_entries->push_back(name + " = " + fieldval); |
2114 } | 2001 } |
2115 } | 2002 } |
2116 return !option_entries->empty(); | 2003 return !option_entries->empty(); |
2117 } | 2004 } |
2118 | 2005 |
2119 // Used by each of the option formatters. | |
2120 bool RetrieveOptions(int depth, const Message& options, | |
2121 const DescriptorPool* pool, | |
2122 std::vector<string>* option_entries) { | |
2123 // When printing custom options for a descriptor, we must use an options | |
2124 // message built on top of the same DescriptorPool where the descriptor | |
2125 // is coming from. This is to ensure we are interpreting custom options | |
2126 // against the right pool. | |
2127 if (options.GetDescriptor()->file()->pool() == pool) { | |
2128 return RetrieveOptionsAssumingRightPool(depth, options, option_entries); | |
2129 } else { | |
2130 const Descriptor* option_descriptor = | |
2131 pool->FindMessageTypeByName(options.GetDescriptor()->full_name()); | |
2132 if (option_descriptor == NULL) { | |
2133 // google/protobuf/descriptor.proto is not in the pool. This means no | |
2134 // custom options are used so we are safe to proceed with the compiled | |
2135 // options message type. | |
2136 return RetrieveOptionsAssumingRightPool(depth, options, option_entries); | |
2137 } | |
2138 DynamicMessageFactory factory; | |
2139 google::protobuf::scoped_ptr<Message> dynamic_options( | |
2140 factory.GetPrototype(option_descriptor)->New()); | |
2141 if (dynamic_options->ParseFromString(options.SerializeAsString())) { | |
2142 return RetrieveOptionsAssumingRightPool(depth, *dynamic_options, | |
2143 option_entries); | |
2144 } else { | |
2145 GOOGLE_LOG(ERROR) << "Found invalid proto option data for: " | |
2146 << options.GetDescriptor()->full_name(); | |
2147 return RetrieveOptionsAssumingRightPool(depth, options, option_entries); | |
2148 } | |
2149 } | |
2150 } | |
2151 | |
2152 // Formats options that all appear together in brackets. Does not include | 2006 // Formats options that all appear together in brackets. Does not include |
2153 // brackets. | 2007 // brackets. |
2154 bool FormatBracketedOptions(int depth, const Message& options, | 2008 bool FormatBracketedOptions(int depth, const Message &options, string *output) { |
2155 const DescriptorPool* pool, string* output) { | 2009 vector<string> all_options; |
2156 std::vector<string> all_options; | 2010 if (RetrieveOptions(depth, options, &all_options)) { |
2157 if (RetrieveOptions(depth, options, pool, &all_options)) { | |
2158 output->append(Join(all_options, ", ")); | 2011 output->append(Join(all_options, ", ")); |
2159 } | 2012 } |
2160 return !all_options.empty(); | 2013 return !all_options.empty(); |
2161 } | 2014 } |
2162 | 2015 |
2163 // Formats options one per line | 2016 // Formats options one per line |
2164 bool FormatLineOptions(int depth, const Message& options, | 2017 bool FormatLineOptions(int depth, const Message &options, string *output) { |
2165 const DescriptorPool* pool, string* output) { | |
2166 string prefix(depth * 2, ' '); | 2018 string prefix(depth * 2, ' '); |
2167 std::vector<string> all_options; | 2019 vector<string> all_options; |
2168 if (RetrieveOptions(depth, options, pool, &all_options)) { | 2020 if (RetrieveOptions(depth, options, &all_options)) { |
2169 for (int i = 0; i < all_options.size(); i++) { | 2021 for (int i = 0; i < all_options.size(); i++) { |
2170 strings::SubstituteAndAppend(output, "$0option $1;\n", | 2022 strings::SubstituteAndAppend(output, "$0option $1;\n", |
2171 prefix, all_options[i]); | 2023 prefix, all_options[i]); |
2172 } | 2024 } |
2173 } | 2025 } |
2174 return !all_options.empty(); | 2026 return !all_options.empty(); |
2175 } | 2027 } |
2176 | 2028 |
2177 class SourceLocationCommentPrinter { | 2029 class SourceLocationCommentPrinter { |
2178 public: | 2030 public: |
2179 template<typename DescType> | 2031 template<typename DescType> |
2180 SourceLocationCommentPrinter(const DescType* desc, | 2032 SourceLocationCommentPrinter(const DescType* desc, |
2181 const string& prefix, | 2033 const string& prefix, |
2182 const DebugStringOptions& options) | 2034 const DebugStringOptions& options) |
2183 : options_(options), prefix_(prefix) { | 2035 : options_(options), prefix_(prefix) { |
2184 // Perform the SourceLocation lookup only if we're including user comments, | 2036 // Perform the SourceLocation lookup only if we're including user comments, |
2185 // because the lookup is fairly expensive. | 2037 // because the lookup is fairly expensive. |
2186 have_source_loc_ = options.include_comments && | 2038 have_source_loc_ = options.include_comments && |
2187 desc->GetSourceLocation(&source_loc_); | 2039 desc->GetSourceLocation(&source_loc_); |
2188 } | 2040 } |
2189 SourceLocationCommentPrinter(const FileDescriptor* file, | 2041 SourceLocationCommentPrinter(const FileDescriptor* file, |
2190 const std::vector<int>& path, | 2042 const vector<int>& path, |
2191 const string& prefix, | 2043 const string& prefix, |
2192 const DebugStringOptions& options) | 2044 const DebugStringOptions& options) |
2193 : options_(options), prefix_(prefix) { | 2045 : options_(options), prefix_(prefix) { |
2194 // Perform the SourceLocation lookup only if we're including user comments, | 2046 // Perform the SourceLocation lookup only if we're including user comments, |
2195 // because the lookup is fairly expensive. | 2047 // because the lookup is fairly expensive. |
2196 have_source_loc_ = options.include_comments && | 2048 have_source_loc_ = options.include_comments && |
2197 file->GetSourceLocation(path, &source_loc_); | 2049 file->GetSourceLocation(path, &source_loc_); |
2198 } | 2050 } |
2199 void AddPreComment(string* output) { | 2051 void AddPreComment(string* output) { |
2200 if (have_source_loc_) { | 2052 if (have_source_loc_) { |
(...skipping 12 matching lines...) Expand all Loading... |
2213 if (have_source_loc_ && source_loc_.trailing_comments.size() > 0) { | 2065 if (have_source_loc_ && source_loc_.trailing_comments.size() > 0) { |
2214 *output += FormatComment(source_loc_.trailing_comments); | 2066 *output += FormatComment(source_loc_.trailing_comments); |
2215 } | 2067 } |
2216 } | 2068 } |
2217 | 2069 |
2218 // Format comment such that each line becomes a full-line C++-style comment in | 2070 // Format comment such that each line becomes a full-line C++-style comment in |
2219 // the DebugString() output. | 2071 // the DebugString() output. |
2220 string FormatComment(const string& comment_text) { | 2072 string FormatComment(const string& comment_text) { |
2221 string stripped_comment = comment_text; | 2073 string stripped_comment = comment_text; |
2222 StripWhitespace(&stripped_comment); | 2074 StripWhitespace(&stripped_comment); |
2223 std::vector<string> lines = Split(stripped_comment, "\n"); | 2075 vector<string> lines = Split(stripped_comment, "\n"); |
2224 string output; | 2076 string output; |
2225 for (int i = 0; i < lines.size(); ++i) { | 2077 for (int i = 0; i < lines.size(); ++i) { |
2226 const string& line = lines[i]; | 2078 const string& line = lines[i]; |
2227 strings::SubstituteAndAppend(&output, "$0// $1\n", prefix_, line); | 2079 strings::SubstituteAndAppend(&output, "$0// $1\n", prefix_, line); |
2228 } | 2080 } |
2229 return output; | 2081 return output; |
2230 } | 2082 } |
2231 | 2083 |
2232 private: | 2084 private: |
2233 | 2085 |
2234 bool have_source_loc_; | 2086 bool have_source_loc_; |
2235 SourceLocation source_loc_; | 2087 SourceLocation source_loc_; |
2236 DebugStringOptions options_; | 2088 DebugStringOptions options_; |
2237 string prefix_; | 2089 string prefix_; |
2238 }; | 2090 }; |
2239 | 2091 |
2240 } // anonymous namespace | 2092 } // anonymous namespace |
2241 | 2093 |
2242 string FileDescriptor::DebugString() const { | 2094 string FileDescriptor::DebugString() const { |
2243 DebugStringOptions options; // default options | 2095 DebugStringOptions options; // default options |
2244 return DebugStringWithOptions(options); | 2096 return DebugStringWithOptions(options); |
2245 } | 2097 } |
2246 | 2098 |
2247 string FileDescriptor::DebugStringWithOptions( | 2099 string FileDescriptor::DebugStringWithOptions( |
2248 const DebugStringOptions& debug_string_options) const { | 2100 const DebugStringOptions& debug_string_options) const { |
2249 string contents; | 2101 string contents; |
2250 { | 2102 { |
2251 std::vector<int> path; | 2103 vector<int> path; |
2252 path.push_back(FileDescriptorProto::kSyntaxFieldNumber); | 2104 path.push_back(FileDescriptorProto::kSyntaxFieldNumber); |
2253 SourceLocationCommentPrinter syntax_comment( | 2105 SourceLocationCommentPrinter syntax_comment( |
2254 this, path, "", debug_string_options); | 2106 this, path, "", debug_string_options); |
2255 syntax_comment.AddPreComment(&contents); | 2107 syntax_comment.AddPreComment(&contents); |
2256 strings::SubstituteAndAppend(&contents, "syntax = \"$0\";\n\n", | 2108 strings::SubstituteAndAppend(&contents, "syntax = \"$0\";\n\n", |
2257 SyntaxName(syntax())); | 2109 SyntaxName(syntax())); |
2258 syntax_comment.AddPostComment(&contents); | 2110 syntax_comment.AddPostComment(&contents); |
2259 } | 2111 } |
2260 | 2112 |
2261 SourceLocationCommentPrinter | 2113 SourceLocationCommentPrinter |
2262 comment_printer(this, "", debug_string_options); | 2114 comment_printer(this, "", debug_string_options); |
2263 comment_printer.AddPreComment(&contents); | 2115 comment_printer.AddPreComment(&contents); |
2264 | 2116 |
2265 std::set<int> public_dependencies; | 2117 set<int> public_dependencies; |
2266 std::set<int> weak_dependencies; | 2118 set<int> weak_dependencies; |
2267 public_dependencies.insert(public_dependencies_, | 2119 public_dependencies.insert(public_dependencies_, |
2268 public_dependencies_ + public_dependency_count_); | 2120 public_dependencies_ + public_dependency_count_); |
2269 weak_dependencies.insert(weak_dependencies_, | 2121 weak_dependencies.insert(weak_dependencies_, |
2270 weak_dependencies_ + weak_dependency_count_); | 2122 weak_dependencies_ + weak_dependency_count_); |
2271 | 2123 |
2272 for (int i = 0; i < dependency_count(); i++) { | 2124 for (int i = 0; i < dependency_count(); i++) { |
2273 if (public_dependencies.count(i) > 0) { | 2125 if (public_dependencies.count(i) > 0) { |
2274 strings::SubstituteAndAppend(&contents, "import public \"$0\";\n", | 2126 strings::SubstituteAndAppend(&contents, "import public \"$0\";\n", |
2275 dependency(i)->name()); | 2127 dependency(i)->name()); |
2276 } else if (weak_dependencies.count(i) > 0) { | 2128 } else if (weak_dependencies.count(i) > 0) { |
2277 strings::SubstituteAndAppend(&contents, "import weak \"$0\";\n", | 2129 strings::SubstituteAndAppend(&contents, "import weak \"$0\";\n", |
2278 dependency(i)->name()); | 2130 dependency(i)->name()); |
2279 } else { | 2131 } else { |
2280 strings::SubstituteAndAppend(&contents, "import \"$0\";\n", | 2132 strings::SubstituteAndAppend(&contents, "import \"$0\";\n", |
2281 dependency(i)->name()); | 2133 dependency(i)->name()); |
2282 } | 2134 } |
2283 } | 2135 } |
2284 | 2136 |
2285 if (!package().empty()) { | 2137 if (!package().empty()) { |
2286 std::vector<int> path; | 2138 vector<int> path; |
2287 path.push_back(FileDescriptorProto::kPackageFieldNumber); | 2139 path.push_back(FileDescriptorProto::kPackageFieldNumber); |
2288 SourceLocationCommentPrinter package_comment( | 2140 SourceLocationCommentPrinter package_comment( |
2289 this, path, "", debug_string_options); | 2141 this, path, "", debug_string_options); |
2290 package_comment.AddPreComment(&contents); | 2142 package_comment.AddPreComment(&contents); |
2291 strings::SubstituteAndAppend(&contents, "package $0;\n\n", package()); | 2143 strings::SubstituteAndAppend(&contents, "package $0;\n\n", package()); |
2292 package_comment.AddPostComment(&contents); | 2144 package_comment.AddPostComment(&contents); |
2293 } | 2145 } |
2294 | 2146 |
2295 if (FormatLineOptions(0, options(), pool(), &contents)) { | 2147 if (FormatLineOptions(0, options(), &contents)) { |
2296 contents.append("\n"); // add some space if we had options | 2148 contents.append("\n"); // add some space if we had options |
2297 } | 2149 } |
2298 | 2150 |
2299 for (int i = 0; i < enum_type_count(); i++) { | 2151 for (int i = 0; i < enum_type_count(); i++) { |
2300 enum_type(i)->DebugString(0, &contents, debug_string_options); | 2152 enum_type(i)->DebugString(0, &contents, debug_string_options); |
2301 contents.append("\n"); | 2153 contents.append("\n"); |
2302 } | 2154 } |
2303 | 2155 |
2304 // Find all the 'group' type extensions; we will not output their nested | 2156 // Find all the 'group' type extensions; we will not output their nested |
2305 // definitions (those will be done with their group field descriptor). | 2157 // definitions (those will be done with their group field descriptor). |
2306 std::set<const Descriptor*> groups; | 2158 set<const Descriptor*> groups; |
2307 for (int i = 0; i < extension_count(); i++) { | 2159 for (int i = 0; i < extension_count(); i++) { |
2308 if (extension(i)->type() == FieldDescriptor::TYPE_GROUP) { | 2160 if (extension(i)->type() == FieldDescriptor::TYPE_GROUP) { |
2309 groups.insert(extension(i)->message_type()); | 2161 groups.insert(extension(i)->message_type()); |
2310 } | 2162 } |
2311 } | 2163 } |
2312 | 2164 |
2313 for (int i = 0; i < message_type_count(); i++) { | 2165 for (int i = 0; i < message_type_count(); i++) { |
2314 if (groups.count(message_type(i)) == 0) { | 2166 if (groups.count(message_type(i)) == 0) { |
2315 message_type(i)->DebugString(0, &contents, debug_string_options, | 2167 message_type(i)->DebugString(0, &contents, debug_string_options, |
2316 /* include_opening_clause */ true); | 2168 /* include_opening_clause */ true); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2366 | 2218 |
2367 SourceLocationCommentPrinter | 2219 SourceLocationCommentPrinter |
2368 comment_printer(this, prefix, debug_string_options); | 2220 comment_printer(this, prefix, debug_string_options); |
2369 comment_printer.AddPreComment(contents); | 2221 comment_printer.AddPreComment(contents); |
2370 | 2222 |
2371 if (include_opening_clause) { | 2223 if (include_opening_clause) { |
2372 strings::SubstituteAndAppend(contents, "$0message $1", prefix, name()); | 2224 strings::SubstituteAndAppend(contents, "$0message $1", prefix, name()); |
2373 } | 2225 } |
2374 contents->append(" {\n"); | 2226 contents->append(" {\n"); |
2375 | 2227 |
2376 FormatLineOptions(depth, options(), file()->pool(), contents); | 2228 FormatLineOptions(depth, options(), contents); |
2377 | 2229 |
2378 // Find all the 'group' types for fields and extensions; we will not output | 2230 // Find all the 'group' types for fields and extensions; we will not output |
2379 // their nested definitions (those will be done with their group field | 2231 // their nested definitions (those will be done with their group field |
2380 // descriptor). | 2232 // descriptor). |
2381 std::set<const Descriptor*> groups; | 2233 set<const Descriptor*> groups; |
2382 for (int i = 0; i < field_count(); i++) { | 2234 for (int i = 0; i < field_count(); i++) { |
2383 if (field(i)->type() == FieldDescriptor::TYPE_GROUP) { | 2235 if (field(i)->type() == FieldDescriptor::TYPE_GROUP) { |
2384 groups.insert(field(i)->message_type()); | 2236 groups.insert(field(i)->message_type()); |
2385 } | 2237 } |
2386 } | 2238 } |
2387 for (int i = 0; i < extension_count(); i++) { | 2239 for (int i = 0; i < extension_count(); i++) { |
2388 if (extension(i)->type() == FieldDescriptor::TYPE_GROUP) { | 2240 if (extension(i)->type() == FieldDescriptor::TYPE_GROUP) { |
2389 groups.insert(extension(i)->message_type()); | 2241 groups.insert(extension(i)->message_type()); |
2390 } | 2242 } |
2391 } | 2243 } |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2504 // Special case map fields. | 2356 // Special case map fields. |
2505 if (is_map()) { | 2357 if (is_map()) { |
2506 strings::SubstituteAndAppend( | 2358 strings::SubstituteAndAppend( |
2507 &field_type, "map<$0, $1>", | 2359 &field_type, "map<$0, $1>", |
2508 message_type()->field(0)->FieldTypeNameDebugString(), | 2360 message_type()->field(0)->FieldTypeNameDebugString(), |
2509 message_type()->field(1)->FieldTypeNameDebugString()); | 2361 message_type()->field(1)->FieldTypeNameDebugString()); |
2510 } else { | 2362 } else { |
2511 field_type = FieldTypeNameDebugString(); | 2363 field_type = FieldTypeNameDebugString(); |
2512 } | 2364 } |
2513 | 2365 |
2514 bool print_label = true; | |
2515 // Determine whether to omit label: | |
2516 // 1. For an optional field, omit label if it's in oneof or in proto3. | |
2517 // 2. For a repeated field, omit label if it's a map. | |
2518 if (is_optional() && (print_label_flag == OMIT_LABEL || | |
2519 file()->syntax() == FileDescriptor::SYNTAX_PROTO3)) { | |
2520 print_label = false; | |
2521 } else if (is_map()) { | |
2522 print_label = false; | |
2523 } | |
2524 string label; | 2366 string label; |
2525 if (print_label) { | 2367 if (print_label_flag == PRINT_LABEL && !is_map()) { |
2526 label = kLabelToName[this->label()]; | 2368 label = kLabelToName[this->label()]; |
2527 label.push_back(' '); | 2369 label.push_back(' '); |
2528 } | 2370 } |
2529 | 2371 |
2530 SourceLocationCommentPrinter | 2372 SourceLocationCommentPrinter |
2531 comment_printer(this, prefix, debug_string_options); | 2373 comment_printer(this, prefix, debug_string_options); |
2532 comment_printer.AddPreComment(contents); | 2374 comment_printer.AddPreComment(contents); |
2533 | 2375 |
2534 strings::SubstituteAndAppend(contents, "$0$1$2 $3 = $4", | 2376 strings::SubstituteAndAppend(contents, "$0$1$2 $3 = $4", |
2535 prefix, | 2377 prefix, |
2536 label, | 2378 label, |
2537 field_type, | 2379 field_type, |
2538 type() == TYPE_GROUP ? message_type()->name() : | 2380 type() == TYPE_GROUP ? message_type()->name() : |
2539 name(), | 2381 name(), |
2540 number()); | 2382 number()); |
2541 | 2383 |
2542 bool bracketed = false; | 2384 bool bracketed = false; |
2543 if (has_default_value()) { | 2385 if (has_default_value()) { |
2544 bracketed = true; | 2386 bracketed = true; |
2545 strings::SubstituteAndAppend(contents, " [default = $0", | 2387 strings::SubstituteAndAppend(contents, " [default = $0", |
2546 DefaultValueAsString(true)); | 2388 DefaultValueAsString(true)); |
2547 } | 2389 } |
2548 if (has_json_name_) { | |
2549 if (!bracketed) { | |
2550 bracketed = true; | |
2551 contents->append("["); | |
2552 } else { | |
2553 contents->append(", "); | |
2554 } | |
2555 contents->append("json_name = \""); | |
2556 contents->append(CEscape(json_name())); | |
2557 contents->append("\""); | |
2558 } | |
2559 | 2390 |
2560 string formatted_options; | 2391 string formatted_options; |
2561 if (FormatBracketedOptions(depth, options(), file()->pool(), | 2392 if (FormatBracketedOptions(depth, options(), &formatted_options)) { |
2562 &formatted_options)) { | |
2563 contents->append(bracketed ? ", " : " ["); | 2393 contents->append(bracketed ? ", " : " ["); |
2564 bracketed = true; | 2394 bracketed = true; |
2565 contents->append(formatted_options); | 2395 contents->append(formatted_options); |
2566 } | 2396 } |
2567 | 2397 |
2568 if (bracketed) { | 2398 if (bracketed) { |
2569 contents->append("]"); | 2399 contents->append("]"); |
2570 } | 2400 } |
2571 | 2401 |
2572 if (type() == TYPE_GROUP) { | 2402 if (type() == TYPE_GROUP) { |
(...skipping 23 matching lines...) Expand all Loading... |
2596 } | 2426 } |
2597 | 2427 |
2598 void OneofDescriptor::DebugString(int depth, string* contents, | 2428 void OneofDescriptor::DebugString(int depth, string* contents, |
2599 const DebugStringOptions& | 2429 const DebugStringOptions& |
2600 debug_string_options) const { | 2430 debug_string_options) const { |
2601 string prefix(depth * 2, ' '); | 2431 string prefix(depth * 2, ' '); |
2602 ++depth; | 2432 ++depth; |
2603 SourceLocationCommentPrinter | 2433 SourceLocationCommentPrinter |
2604 comment_printer(this, prefix, debug_string_options); | 2434 comment_printer(this, prefix, debug_string_options); |
2605 comment_printer.AddPreComment(contents); | 2435 comment_printer.AddPreComment(contents); |
2606 strings::SubstituteAndAppend(contents, "$0oneof $1 {", prefix, name()); | 2436 strings::SubstituteAndAppend( |
2607 | 2437 contents, "$0 oneof $1 {", prefix, name()); |
2608 FormatLineOptions(depth, options(), containing_type()->file()->pool(), | |
2609 contents); | |
2610 | |
2611 if (debug_string_options.elide_oneof_body) { | 2438 if (debug_string_options.elide_oneof_body) { |
2612 contents->append(" ... }\n"); | 2439 contents->append(" ... }\n"); |
2613 } else { | 2440 } else { |
2614 contents->append("\n"); | |
2615 for (int i = 0; i < field_count(); i++) { | 2441 for (int i = 0; i < field_count(); i++) { |
2616 field(i)->DebugString(depth, FieldDescriptor::OMIT_LABEL, contents, | 2442 field(i)->DebugString(depth, FieldDescriptor::OMIT_LABEL, contents, |
2617 debug_string_options); | 2443 debug_string_options); |
2618 } | 2444 } |
2619 strings::SubstituteAndAppend(contents, "$0}\n", prefix); | 2445 strings::SubstituteAndAppend(contents, "$0}\n", prefix); |
2620 } | 2446 } |
2621 comment_printer.AddPostComment(contents); | 2447 comment_printer.AddPostComment(contents); |
2622 } | 2448 } |
2623 | 2449 |
2624 string EnumDescriptor::DebugString() const { | 2450 string EnumDescriptor::DebugString() const { |
(...skipping 14 matching lines...) Expand all Loading... |
2639 string prefix(depth * 2, ' '); | 2465 string prefix(depth * 2, ' '); |
2640 ++depth; | 2466 ++depth; |
2641 | 2467 |
2642 SourceLocationCommentPrinter | 2468 SourceLocationCommentPrinter |
2643 comment_printer(this, prefix, debug_string_options); | 2469 comment_printer(this, prefix, debug_string_options); |
2644 comment_printer.AddPreComment(contents); | 2470 comment_printer.AddPreComment(contents); |
2645 | 2471 |
2646 strings::SubstituteAndAppend(contents, "$0enum $1 {\n", | 2472 strings::SubstituteAndAppend(contents, "$0enum $1 {\n", |
2647 prefix, name()); | 2473 prefix, name()); |
2648 | 2474 |
2649 FormatLineOptions(depth, options(), file()->pool(), contents); | 2475 FormatLineOptions(depth, options(), contents); |
2650 | 2476 |
2651 for (int i = 0; i < value_count(); i++) { | 2477 for (int i = 0; i < value_count(); i++) { |
2652 value(i)->DebugString(depth, contents, debug_string_options); | 2478 value(i)->DebugString(depth, contents, debug_string_options); |
2653 } | 2479 } |
2654 strings::SubstituteAndAppend(contents, "$0}\n", prefix); | 2480 strings::SubstituteAndAppend(contents, "$0}\n", prefix); |
2655 | 2481 |
2656 comment_printer.AddPostComment(contents); | 2482 comment_printer.AddPostComment(contents); |
2657 } | 2483 } |
2658 | 2484 |
2659 string EnumValueDescriptor::DebugString() const { | 2485 string EnumValueDescriptor::DebugString() const { |
(...skipping 14 matching lines...) Expand all Loading... |
2674 string prefix(depth * 2, ' '); | 2500 string prefix(depth * 2, ' '); |
2675 | 2501 |
2676 SourceLocationCommentPrinter | 2502 SourceLocationCommentPrinter |
2677 comment_printer(this, prefix, debug_string_options); | 2503 comment_printer(this, prefix, debug_string_options); |
2678 comment_printer.AddPreComment(contents); | 2504 comment_printer.AddPreComment(contents); |
2679 | 2505 |
2680 strings::SubstituteAndAppend(contents, "$0$1 = $2", | 2506 strings::SubstituteAndAppend(contents, "$0$1 = $2", |
2681 prefix, name(), number()); | 2507 prefix, name(), number()); |
2682 | 2508 |
2683 string formatted_options; | 2509 string formatted_options; |
2684 if (FormatBracketedOptions(depth, options(), type()->file()->pool(), | 2510 if (FormatBracketedOptions(depth, options(), &formatted_options)) { |
2685 &formatted_options)) { | |
2686 strings::SubstituteAndAppend(contents, " [$0]", formatted_options); | 2511 strings::SubstituteAndAppend(contents, " [$0]", formatted_options); |
2687 } | 2512 } |
2688 contents->append(";\n"); | 2513 contents->append(";\n"); |
2689 | 2514 |
2690 comment_printer.AddPostComment(contents); | 2515 comment_printer.AddPostComment(contents); |
2691 } | 2516 } |
2692 | 2517 |
2693 string ServiceDescriptor::DebugString() const { | 2518 string ServiceDescriptor::DebugString() const { |
2694 DebugStringOptions options; // default values | 2519 DebugStringOptions options; // default values |
2695 return DebugStringWithOptions(options); | 2520 return DebugStringWithOptions(options); |
2696 } | 2521 } |
2697 | 2522 |
2698 string ServiceDescriptor::DebugStringWithOptions( | 2523 string ServiceDescriptor::DebugStringWithOptions( |
2699 const DebugStringOptions& options) const { | 2524 const DebugStringOptions& options) const { |
2700 string contents; | 2525 string contents; |
2701 DebugString(&contents, options); | 2526 DebugString(&contents, options); |
2702 return contents; | 2527 return contents; |
2703 } | 2528 } |
2704 | 2529 |
2705 void ServiceDescriptor::DebugString(string *contents, | 2530 void ServiceDescriptor::DebugString(string *contents, |
2706 const DebugStringOptions& | 2531 const DebugStringOptions& |
2707 debug_string_options) const { | 2532 debug_string_options) const { |
2708 SourceLocationCommentPrinter | 2533 SourceLocationCommentPrinter |
2709 comment_printer(this, /* prefix */ "", debug_string_options); | 2534 comment_printer(this, /* prefix */ "", debug_string_options); |
2710 comment_printer.AddPreComment(contents); | 2535 comment_printer.AddPreComment(contents); |
2711 | 2536 |
2712 strings::SubstituteAndAppend(contents, "service $0 {\n", name()); | 2537 strings::SubstituteAndAppend(contents, "service $0 {\n", name()); |
2713 | 2538 |
2714 FormatLineOptions(1, options(), file()->pool(), contents); | 2539 FormatLineOptions(1, options(), contents); |
2715 | 2540 |
2716 for (int i = 0; i < method_count(); i++) { | 2541 for (int i = 0; i < method_count(); i++) { |
2717 method(i)->DebugString(1, contents, debug_string_options); | 2542 method(i)->DebugString(1, contents, debug_string_options); |
2718 } | 2543 } |
2719 | 2544 |
2720 contents->append("}\n"); | 2545 contents->append("}\n"); |
2721 | 2546 |
2722 comment_printer.AddPostComment(contents); | 2547 comment_printer.AddPostComment(contents); |
2723 } | 2548 } |
2724 | 2549 |
(...skipping 20 matching lines...) Expand all Loading... |
2745 comment_printer.AddPreComment(contents); | 2570 comment_printer.AddPreComment(contents); |
2746 | 2571 |
2747 strings::SubstituteAndAppend(contents, "$0rpc $1($4.$2) returns ($5.$3)", | 2572 strings::SubstituteAndAppend(contents, "$0rpc $1($4.$2) returns ($5.$3)", |
2748 prefix, name(), | 2573 prefix, name(), |
2749 input_type()->full_name(), | 2574 input_type()->full_name(), |
2750 output_type()->full_name(), | 2575 output_type()->full_name(), |
2751 client_streaming() ? "stream " : "", | 2576 client_streaming() ? "stream " : "", |
2752 server_streaming() ? "stream " : ""); | 2577 server_streaming() ? "stream " : ""); |
2753 | 2578 |
2754 string formatted_options; | 2579 string formatted_options; |
2755 if (FormatLineOptions(depth, options(), service()->file()->pool(), | 2580 if (FormatLineOptions(depth, options(), &formatted_options)) { |
2756 &formatted_options)) { | |
2757 strings::SubstituteAndAppend(contents, " {\n$0$1}\n", | 2581 strings::SubstituteAndAppend(contents, " {\n$0$1}\n", |
2758 formatted_options, prefix); | 2582 formatted_options, prefix); |
2759 } else { | 2583 } else { |
2760 contents->append(";\n"); | 2584 contents->append(";\n"); |
2761 } | 2585 } |
2762 | 2586 |
2763 comment_printer.AddPostComment(contents); | 2587 comment_printer.AddPostComment(contents); |
2764 } | 2588 } |
2765 | 2589 |
2766 | 2590 |
2767 // Location methods =============================================== | 2591 // Location methods =============================================== |
2768 | 2592 |
2769 bool FileDescriptor::GetSourceLocation(const std::vector<int>& path, | 2593 bool FileDescriptor::GetSourceLocation(const vector<int>& path, |
2770 SourceLocation* out_location) const { | 2594 SourceLocation* out_location) const { |
2771 GOOGLE_CHECK_NOTNULL(out_location); | 2595 GOOGLE_CHECK_NOTNULL(out_location); |
2772 if (source_code_info_) { | 2596 if (source_code_info_) { |
2773 if (const SourceCodeInfo_Location* loc = | 2597 if (const SourceCodeInfo_Location* loc = |
2774 tables_->GetSourceLocation(path, source_code_info_)) { | 2598 tables_->GetSourceLocation(path, source_code_info_)) { |
2775 const RepeatedField<int32>& span = loc->span(); | 2599 const RepeatedField<int32>& span = loc->span(); |
2776 if (span.size() == 3 || span.size() == 4) { | 2600 if (span.size() == 3 || span.size() == 4) { |
2777 out_location->start_line = span.Get(0); | 2601 out_location->start_line = span.Get(0); |
2778 out_location->start_column = span.Get(1); | 2602 out_location->start_column = span.Get(1); |
2779 out_location->end_line = span.Get(span.size() == 3 ? 0 : 2); | 2603 out_location->end_line = span.Get(span.size() == 3 ? 0 : 2); |
2780 out_location->end_column = span.Get(span.size() - 1); | 2604 out_location->end_column = span.Get(span.size() - 1); |
2781 | 2605 |
2782 out_location->leading_comments = loc->leading_comments(); | 2606 out_location->leading_comments = loc->leading_comments(); |
2783 out_location->trailing_comments = loc->trailing_comments(); | 2607 out_location->trailing_comments = loc->trailing_comments(); |
2784 out_location->leading_detached_comments.assign( | 2608 out_location->leading_detached_comments.assign( |
2785 loc->leading_detached_comments().begin(), | 2609 loc->leading_detached_comments().begin(), |
2786 loc->leading_detached_comments().end()); | 2610 loc->leading_detached_comments().end()); |
2787 return true; | 2611 return true; |
2788 } | 2612 } |
2789 } | 2613 } |
2790 } | 2614 } |
2791 return false; | 2615 return false; |
2792 } | 2616 } |
2793 | 2617 |
2794 bool FileDescriptor::GetSourceLocation(SourceLocation* out_location) const { | 2618 bool FileDescriptor::GetSourceLocation(SourceLocation* out_location) const { |
2795 std::vector<int> path; // empty path for root FileDescriptor | 2619 vector<int> path; // empty path for root FileDescriptor |
2796 return GetSourceLocation(path, out_location); | 2620 return GetSourceLocation(path, out_location); |
2797 } | 2621 } |
2798 | 2622 |
2799 bool FieldDescriptor::is_packed() const { | 2623 bool FieldDescriptor::is_packed() const { |
2800 if (!is_packable()) return false; | 2624 if (!is_packable()) return false; |
2801 if (file_->syntax() == FileDescriptor::SYNTAX_PROTO2) { | 2625 if (file_->syntax() == FileDescriptor::SYNTAX_PROTO2) { |
2802 return (options_ != NULL) && options_->packed(); | 2626 return (options_ != NULL) && options_->packed(); |
2803 } else { | 2627 } else { |
2804 return options_ == NULL || !options_->has_packed() || options_->packed(); | 2628 return options_ == NULL || !options_->has_packed() || options_->packed(); |
2805 } | 2629 } |
2806 } | 2630 } |
2807 | 2631 |
2808 bool Descriptor::GetSourceLocation(SourceLocation* out_location) const { | 2632 bool Descriptor::GetSourceLocation(SourceLocation* out_location) const { |
2809 std::vector<int> path; | 2633 vector<int> path; |
2810 GetLocationPath(&path); | 2634 GetLocationPath(&path); |
2811 return file()->GetSourceLocation(path, out_location); | 2635 return file()->GetSourceLocation(path, out_location); |
2812 } | 2636 } |
2813 | 2637 |
2814 bool FieldDescriptor::GetSourceLocation(SourceLocation* out_location) const { | 2638 bool FieldDescriptor::GetSourceLocation(SourceLocation* out_location) const { |
2815 std::vector<int> path; | 2639 vector<int> path; |
2816 GetLocationPath(&path); | 2640 GetLocationPath(&path); |
2817 return file()->GetSourceLocation(path, out_location); | 2641 return file()->GetSourceLocation(path, out_location); |
2818 } | 2642 } |
2819 | 2643 |
2820 bool OneofDescriptor::GetSourceLocation(SourceLocation* out_location) const { | 2644 bool OneofDescriptor::GetSourceLocation(SourceLocation* out_location) const { |
2821 std::vector<int> path; | 2645 vector<int> path; |
2822 GetLocationPath(&path); | 2646 GetLocationPath(&path); |
2823 return containing_type()->file()->GetSourceLocation(path, out_location); | 2647 return containing_type()->file()->GetSourceLocation(path, out_location); |
2824 } | 2648 } |
2825 | 2649 |
2826 bool EnumDescriptor::GetSourceLocation(SourceLocation* out_location) const { | 2650 bool EnumDescriptor::GetSourceLocation(SourceLocation* out_location) const { |
2827 std::vector<int> path; | 2651 vector<int> path; |
2828 GetLocationPath(&path); | 2652 GetLocationPath(&path); |
2829 return file()->GetSourceLocation(path, out_location); | 2653 return file()->GetSourceLocation(path, out_location); |
2830 } | 2654 } |
2831 | 2655 |
2832 bool MethodDescriptor::GetSourceLocation(SourceLocation* out_location) const { | 2656 bool MethodDescriptor::GetSourceLocation(SourceLocation* out_location) const { |
2833 std::vector<int> path; | 2657 vector<int> path; |
2834 GetLocationPath(&path); | 2658 GetLocationPath(&path); |
2835 return service()->file()->GetSourceLocation(path, out_location); | 2659 return service()->file()->GetSourceLocation(path, out_location); |
2836 } | 2660 } |
2837 | 2661 |
2838 bool ServiceDescriptor::GetSourceLocation(SourceLocation* out_location) const { | 2662 bool ServiceDescriptor::GetSourceLocation(SourceLocation* out_location) const { |
2839 std::vector<int> path; | 2663 vector<int> path; |
2840 GetLocationPath(&path); | 2664 GetLocationPath(&path); |
2841 return file()->GetSourceLocation(path, out_location); | 2665 return file()->GetSourceLocation(path, out_location); |
2842 } | 2666 } |
2843 | 2667 |
2844 bool EnumValueDescriptor::GetSourceLocation( | 2668 bool EnumValueDescriptor::GetSourceLocation( |
2845 SourceLocation* out_location) const { | 2669 SourceLocation* out_location) const { |
2846 std::vector<int> path; | 2670 vector<int> path; |
2847 GetLocationPath(&path); | 2671 GetLocationPath(&path); |
2848 return type()->file()->GetSourceLocation(path, out_location); | 2672 return type()->file()->GetSourceLocation(path, out_location); |
2849 } | 2673 } |
2850 | 2674 |
2851 void Descriptor::GetLocationPath(std::vector<int>* output) const { | 2675 void Descriptor::GetLocationPath(vector<int>* output) const { |
2852 if (containing_type()) { | 2676 if (containing_type()) { |
2853 containing_type()->GetLocationPath(output); | 2677 containing_type()->GetLocationPath(output); |
2854 output->push_back(DescriptorProto::kNestedTypeFieldNumber); | 2678 output->push_back(DescriptorProto::kNestedTypeFieldNumber); |
2855 output->push_back(index()); | 2679 output->push_back(index()); |
2856 } else { | 2680 } else { |
2857 output->push_back(FileDescriptorProto::kMessageTypeFieldNumber); | 2681 output->push_back(FileDescriptorProto::kMessageTypeFieldNumber); |
2858 output->push_back(index()); | 2682 output->push_back(index()); |
2859 } | 2683 } |
2860 } | 2684 } |
2861 | 2685 |
2862 void FieldDescriptor::GetLocationPath(std::vector<int>* output) const { | 2686 void FieldDescriptor::GetLocationPath(vector<int>* output) const { |
2863 if (is_extension()) { | 2687 if (is_extension()) { |
2864 if (extension_scope() == NULL) { | 2688 if (extension_scope() == NULL) { |
2865 output->push_back(FileDescriptorProto::kExtensionFieldNumber); | 2689 output->push_back(FileDescriptorProto::kExtensionFieldNumber); |
2866 output->push_back(index()); | 2690 output->push_back(index()); |
2867 } else { | 2691 } else { |
2868 extension_scope()->GetLocationPath(output); | 2692 extension_scope()->GetLocationPath(output); |
2869 output->push_back(DescriptorProto::kExtensionFieldNumber); | 2693 output->push_back(DescriptorProto::kExtensionFieldNumber); |
2870 output->push_back(index()); | 2694 output->push_back(index()); |
2871 } | 2695 } |
2872 } else { | 2696 } else { |
2873 containing_type()->GetLocationPath(output); | 2697 containing_type()->GetLocationPath(output); |
2874 output->push_back(DescriptorProto::kFieldFieldNumber); | 2698 output->push_back(DescriptorProto::kFieldFieldNumber); |
2875 output->push_back(index()); | 2699 output->push_back(index()); |
2876 } | 2700 } |
2877 } | 2701 } |
2878 | 2702 |
2879 void OneofDescriptor::GetLocationPath(std::vector<int>* output) const { | 2703 void OneofDescriptor::GetLocationPath(vector<int>* output) const { |
2880 containing_type()->GetLocationPath(output); | 2704 containing_type()->GetLocationPath(output); |
2881 output->push_back(DescriptorProto::kOneofDeclFieldNumber); | 2705 output->push_back(DescriptorProto::kOneofDeclFieldNumber); |
2882 output->push_back(index()); | 2706 output->push_back(index()); |
2883 } | 2707 } |
2884 | 2708 |
2885 void EnumDescriptor::GetLocationPath(std::vector<int>* output) const { | 2709 void EnumDescriptor::GetLocationPath(vector<int>* output) const { |
2886 if (containing_type()) { | 2710 if (containing_type()) { |
2887 containing_type()->GetLocationPath(output); | 2711 containing_type()->GetLocationPath(output); |
2888 output->push_back(DescriptorProto::kEnumTypeFieldNumber); | 2712 output->push_back(DescriptorProto::kEnumTypeFieldNumber); |
2889 output->push_back(index()); | 2713 output->push_back(index()); |
2890 } else { | 2714 } else { |
2891 output->push_back(FileDescriptorProto::kEnumTypeFieldNumber); | 2715 output->push_back(FileDescriptorProto::kEnumTypeFieldNumber); |
2892 output->push_back(index()); | 2716 output->push_back(index()); |
2893 } | 2717 } |
2894 } | 2718 } |
2895 | 2719 |
2896 void EnumValueDescriptor::GetLocationPath(std::vector<int>* output) const { | 2720 void EnumValueDescriptor::GetLocationPath(vector<int>* output) const { |
2897 type()->GetLocationPath(output); | 2721 type()->GetLocationPath(output); |
2898 output->push_back(EnumDescriptorProto::kValueFieldNumber); | 2722 output->push_back(EnumDescriptorProto::kValueFieldNumber); |
2899 output->push_back(index()); | 2723 output->push_back(index()); |
2900 } | 2724 } |
2901 | 2725 |
2902 void ServiceDescriptor::GetLocationPath(std::vector<int>* output) const { | 2726 void ServiceDescriptor::GetLocationPath(vector<int>* output) const { |
2903 output->push_back(FileDescriptorProto::kServiceFieldNumber); | 2727 output->push_back(FileDescriptorProto::kServiceFieldNumber); |
2904 output->push_back(index()); | 2728 output->push_back(index()); |
2905 } | 2729 } |
2906 | 2730 |
2907 void MethodDescriptor::GetLocationPath(std::vector<int>* output) const { | 2731 void MethodDescriptor::GetLocationPath(vector<int>* output) const { |
2908 service()->GetLocationPath(output); | 2732 service()->GetLocationPath(output); |
2909 output->push_back(ServiceDescriptorProto::kMethodFieldNumber); | 2733 output->push_back(ServiceDescriptorProto::kMethodFieldNumber); |
2910 output->push_back(index()); | 2734 output->push_back(index()); |
2911 } | 2735 } |
2912 | 2736 |
2913 // =================================================================== | 2737 // =================================================================== |
2914 | 2738 |
2915 namespace { | 2739 namespace { |
2916 | 2740 |
2917 // Represents an options message to interpret. Extension names in the option | 2741 // Represents an options message to interpret. Extension names in the option |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2952 // Non-recursive part of BuildFile functionality. | 2776 // Non-recursive part of BuildFile functionality. |
2953 const FileDescriptor* BuildFileImpl(const FileDescriptorProto& proto); | 2777 const FileDescriptor* BuildFileImpl(const FileDescriptorProto& proto); |
2954 | 2778 |
2955 const DescriptorPool* pool_; | 2779 const DescriptorPool* pool_; |
2956 DescriptorPool::Tables* tables_; // for convenience | 2780 DescriptorPool::Tables* tables_; // for convenience |
2957 DescriptorPool::ErrorCollector* error_collector_; | 2781 DescriptorPool::ErrorCollector* error_collector_; |
2958 | 2782 |
2959 // As we build descriptors we store copies of the options messages in | 2783 // As we build descriptors we store copies of the options messages in |
2960 // them. We put pointers to those copies in this vector, as we build, so we | 2784 // them. We put pointers to those copies in this vector, as we build, so we |
2961 // can later (after cross-linking) interpret those options. | 2785 // can later (after cross-linking) interpret those options. |
2962 std::vector<OptionsToInterpret> options_to_interpret_; | 2786 vector<OptionsToInterpret> options_to_interpret_; |
2963 | 2787 |
2964 bool had_errors_; | 2788 bool had_errors_; |
2965 string filename_; | 2789 string filename_; |
2966 FileDescriptor* file_; | 2790 FileDescriptor* file_; |
2967 FileDescriptorTables* file_tables_; | 2791 FileDescriptorTables* file_tables_; |
2968 std::set<const FileDescriptor*> dependencies_; | 2792 set<const FileDescriptor*> dependencies_; |
2969 | 2793 |
2970 // unused_dependency_ is used to record the unused imported files. | 2794 // unused_dependency_ is used to record the unused imported files. |
2971 // Note: public import is not considered. | 2795 // Note: public import is not considered. |
2972 std::set<const FileDescriptor*> unused_dependency_; | 2796 set<const FileDescriptor*> unused_dependency_; |
2973 | 2797 |
2974 // If LookupSymbol() finds a symbol that is in a file which is not a declared | 2798 // If LookupSymbol() finds a symbol that is in a file which is not a declared |
2975 // dependency of this file, it will fail, but will set | 2799 // dependency of this file, it will fail, but will set |
2976 // possible_undeclared_dependency_ to point at that file. This is only used | 2800 // possible_undeclared_dependency_ to point at that file. This is only used |
2977 // by AddNotDefinedError() to report a more useful error message. | 2801 // by AddNotDefinedError() to report a more useful error message. |
2978 // possible_undeclared_dependency_name_ is the name of the symbol that was | 2802 // possible_undeclared_dependency_name_ is the name of the symbol that was |
2979 // actually found in possible_undeclared_dependency_, which may be a parent | 2803 // actually found in possible_undeclared_dependency_, which may be a parent |
2980 // of the symbol actually looked for. | 2804 // of the symbol actually looked for. |
2981 const FileDescriptor* possible_undeclared_dependency_; | 2805 const FileDescriptor* possible_undeclared_dependency_; |
2982 string possible_undeclared_dependency_name_; | 2806 string possible_undeclared_dependency_name_; |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3143 } | 2967 } |
3144 void BuildExtensionRange(const DescriptorProto::ExtensionRange& proto, | 2968 void BuildExtensionRange(const DescriptorProto::ExtensionRange& proto, |
3145 const Descriptor* parent, | 2969 const Descriptor* parent, |
3146 Descriptor::ExtensionRange* result); | 2970 Descriptor::ExtensionRange* result); |
3147 void BuildReservedRange(const DescriptorProto::ReservedRange& proto, | 2971 void BuildReservedRange(const DescriptorProto::ReservedRange& proto, |
3148 const Descriptor* parent, | 2972 const Descriptor* parent, |
3149 Descriptor::ReservedRange* result); | 2973 Descriptor::ReservedRange* result); |
3150 void BuildOneof(const OneofDescriptorProto& proto, | 2974 void BuildOneof(const OneofDescriptorProto& proto, |
3151 Descriptor* parent, | 2975 Descriptor* parent, |
3152 OneofDescriptor* result); | 2976 OneofDescriptor* result); |
3153 void CheckEnumValueUniqueness(const EnumDescriptorProto& proto, | |
3154 const EnumDescriptor* result); | |
3155 void BuildEnum(const EnumDescriptorProto& proto, | 2977 void BuildEnum(const EnumDescriptorProto& proto, |
3156 const Descriptor* parent, | 2978 const Descriptor* parent, |
3157 EnumDescriptor* result); | 2979 EnumDescriptor* result); |
3158 void BuildEnumValue(const EnumValueDescriptorProto& proto, | 2980 void BuildEnumValue(const EnumValueDescriptorProto& proto, |
3159 const EnumDescriptor* parent, | 2981 const EnumDescriptor* parent, |
3160 EnumValueDescriptor* result); | 2982 EnumValueDescriptor* result); |
3161 void BuildService(const ServiceDescriptorProto& proto, | 2983 void BuildService(const ServiceDescriptorProto& proto, |
3162 const void* dummy, | 2984 const void* dummy, |
3163 ServiceDescriptor* result); | 2985 ServiceDescriptor* result); |
3164 void BuildMethod(const MethodDescriptorProto& proto, | 2986 void BuildMethod(const MethodDescriptorProto& proto, |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3215 // Adds the uninterpreted_option to the given options message verbatim. | 3037 // Adds the uninterpreted_option to the given options message verbatim. |
3216 // Used when AllowUnknownDependencies() is in effect and we can't find | 3038 // Used when AllowUnknownDependencies() is in effect and we can't find |
3217 // the option's definition. | 3039 // the option's definition. |
3218 void AddWithoutInterpreting(const UninterpretedOption& uninterpreted_option, | 3040 void AddWithoutInterpreting(const UninterpretedOption& uninterpreted_option, |
3219 Message* options); | 3041 Message* options); |
3220 | 3042 |
3221 // A recursive helper function that drills into the intermediate fields | 3043 // A recursive helper function that drills into the intermediate fields |
3222 // in unknown_fields to check if field innermost_field is set on the | 3044 // in unknown_fields to check if field innermost_field is set on the |
3223 // innermost message. Returns false and sets an error if so. | 3045 // innermost message. Returns false and sets an error if so. |
3224 bool ExamineIfOptionIsSet( | 3046 bool ExamineIfOptionIsSet( |
3225 std::vector<const FieldDescriptor*>::const_iterator | 3047 vector<const FieldDescriptor*>::const_iterator intermediate_fields_iter, |
3226 intermediate_fields_iter, | 3048 vector<const FieldDescriptor*>::const_iterator intermediate_fields_end, |
3227 std::vector<const FieldDescriptor*>::const_iterator | |
3228 intermediate_fields_end, | |
3229 const FieldDescriptor* innermost_field, const string& debug_msg_name, | 3049 const FieldDescriptor* innermost_field, const string& debug_msg_name, |
3230 const UnknownFieldSet& unknown_fields); | 3050 const UnknownFieldSet& unknown_fields); |
3231 | 3051 |
3232 // Validates the value for the option field of the currently interpreted | 3052 // Validates the value for the option field of the currently interpreted |
3233 // option and then sets it on the unknown_field. | 3053 // option and then sets it on the unknown_field. |
3234 bool SetOptionValue(const FieldDescriptor* option_field, | 3054 bool SetOptionValue(const FieldDescriptor* option_field, |
3235 UnknownFieldSet* unknown_fields); | 3055 UnknownFieldSet* unknown_fields); |
3236 | 3056 |
3237 // Parses an aggregate value for a CPPTYPE_MESSAGE option and | 3057 // Parses an aggregate value for a CPPTYPE_MESSAGE option and |
3238 // saves it into *unknown_fields. | 3058 // saves it into *unknown_fields. |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3544 | 3364 |
3545 if (result.type == Symbol::PACKAGE) { | 3365 if (result.type == Symbol::PACKAGE) { |
3546 // Arg, this is overcomplicated. The symbol is a package name. It could | 3366 // Arg, this is overcomplicated. The symbol is a package name. It could |
3547 // be that the package was defined in multiple files. result.GetFile() | 3367 // be that the package was defined in multiple files. result.GetFile() |
3548 // returns the first file we saw that used this package. We've determined | 3368 // returns the first file we saw that used this package. We've determined |
3549 // that that file is not a direct dependency of the file we are currently | 3369 // that that file is not a direct dependency of the file we are currently |
3550 // building, but it could be that some other file which *is* a direct | 3370 // building, but it could be that some other file which *is* a direct |
3551 // dependency also defines the same package. We can't really rule out this | 3371 // dependency also defines the same package. We can't really rule out this |
3552 // symbol unless none of the dependencies define it. | 3372 // symbol unless none of the dependencies define it. |
3553 if (IsInPackage(file_, name)) return result; | 3373 if (IsInPackage(file_, name)) return result; |
3554 for (std::set<const FileDescriptor*>::const_iterator it = | 3374 for (set<const FileDescriptor*>::const_iterator it = dependencies_.begin(); |
3555 dependencies_.begin(); | |
3556 it != dependencies_.end(); ++it) { | 3375 it != dependencies_.end(); ++it) { |
3557 // Note: A dependency may be NULL if it was not found or had errors. | 3376 // Note: A dependency may be NULL if it was not found or had errors. |
3558 if (*it != NULL && IsInPackage(*it, name)) return result; | 3377 if (*it != NULL && IsInPackage(*it, name)) return result; |
3559 } | 3378 } |
3560 } | 3379 } |
3561 | 3380 |
3562 possible_undeclared_dependency_ = file; | 3381 possible_undeclared_dependency_ = file; |
3563 possible_undeclared_dependency_name_ = name; | 3382 possible_undeclared_dependency_name_ = name; |
3564 return kNullSymbol; | 3383 return kNullSymbol; |
3565 } | 3384 } |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3764 | 3583 |
3765 bool DescriptorBuilder::AddSymbol( | 3584 bool DescriptorBuilder::AddSymbol( |
3766 const string& full_name, const void* parent, const string& name, | 3585 const string& full_name, const void* parent, const string& name, |
3767 const Message& proto, Symbol symbol) { | 3586 const Message& proto, Symbol symbol) { |
3768 // If the caller passed NULL for the parent, the symbol is at file scope. | 3587 // If the caller passed NULL for the parent, the symbol is at file scope. |
3769 // Use its file as the parent instead. | 3588 // Use its file as the parent instead. |
3770 if (parent == NULL) parent = file_; | 3589 if (parent == NULL) parent = file_; |
3771 | 3590 |
3772 if (tables_->AddSymbol(full_name, symbol)) { | 3591 if (tables_->AddSymbol(full_name, symbol)) { |
3773 if (!file_tables_->AddAliasUnderParent(parent, name, symbol)) { | 3592 if (!file_tables_->AddAliasUnderParent(parent, name, symbol)) { |
3774 // This is only possible if there was already an error adding something of | 3593 GOOGLE_LOG(DFATAL) << "\"" << full_name << "\" not previously defined in " |
3775 // the same name. | 3594 "symbols_by_name_, but was defined in symbols_by_parent_; " |
3776 if (!had_errors_) { | 3595 "this shouldn't be possible."; |
3777 GOOGLE_LOG(DFATAL) << "\"" << full_name << "\" not previously defined in
" | |
3778 "symbols_by_name_, but was defined in " | |
3779 "symbols_by_parent_; this shouldn't be possible."; | |
3780 } | |
3781 return false; | 3596 return false; |
3782 } | 3597 } |
3783 return true; | 3598 return true; |
3784 } else { | 3599 } else { |
3785 const FileDescriptor* other_file = tables_->FindSymbol(full_name).GetFile(); | 3600 const FileDescriptor* other_file = tables_->FindSymbol(full_name).GetFile(); |
3786 if (other_file == file_) { | 3601 if (other_file == file_) { |
3787 string::size_type dot_pos = full_name.find_last_of('.'); | 3602 string::size_type dot_pos = full_name.find_last_of('.'); |
3788 if (dot_pos == string::npos) { | 3603 if (dot_pos == string::npos) { |
3789 AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, | 3604 AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, |
3790 "\"" + full_name + "\" is already defined."); | 3605 "\"" + full_name + "\" is already defined."); |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4088 // Bail out early so that if this is actually the exact same file, we | 3903 // Bail out early so that if this is actually the exact same file, we |
4089 // don't end up reporting that every single symbol is already defined. | 3904 // don't end up reporting that every single symbol is already defined. |
4090 tables_->RollbackToLastCheckpoint(); | 3905 tables_->RollbackToLastCheckpoint(); |
4091 return NULL; | 3906 return NULL; |
4092 } | 3907 } |
4093 if (!result->package().empty()) { | 3908 if (!result->package().empty()) { |
4094 AddPackage(result->package(), proto, result); | 3909 AddPackage(result->package(), proto, result); |
4095 } | 3910 } |
4096 | 3911 |
4097 // Make sure all dependencies are loaded. | 3912 // Make sure all dependencies are loaded. |
4098 std::set<string> seen_dependencies; | 3913 set<string> seen_dependencies; |
4099 result->dependency_count_ = proto.dependency_size(); | 3914 result->dependency_count_ = proto.dependency_size(); |
4100 result->dependencies_ = | 3915 result->dependencies_ = |
4101 tables_->AllocateArray<const FileDescriptor*>(proto.dependency_size()); | 3916 tables_->AllocateArray<const FileDescriptor*>(proto.dependency_size()); |
4102 unused_dependency_.clear(); | 3917 unused_dependency_.clear(); |
4103 std::set<int> weak_deps; | 3918 set<int> weak_deps; |
4104 for (int i = 0; i < proto.weak_dependency_size(); ++i) { | 3919 for (int i = 0; i < proto.weak_dependency_size(); ++i) { |
4105 weak_deps.insert(proto.weak_dependency(i)); | 3920 weak_deps.insert(proto.weak_dependency(i)); |
4106 } | 3921 } |
4107 for (int i = 0; i < proto.dependency_size(); i++) { | 3922 for (int i = 0; i < proto.dependency_size(); i++) { |
4108 if (!seen_dependencies.insert(proto.dependency(i)).second) { | 3923 if (!seen_dependencies.insert(proto.dependency(i)).second) { |
4109 AddTwiceListedError(proto, i); | 3924 AddTwiceListedError(proto, i); |
4110 } | 3925 } |
4111 | 3926 |
4112 const FileDescriptor* dependency = tables_->FindFile(proto.dependency(i)); | 3927 const FileDescriptor* dependency = tables_->FindFile(proto.dependency(i)); |
4113 if (dependency == NULL && pool_->underlay_ != NULL) { | 3928 if (dependency == NULL && pool_->underlay_ != NULL) { |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4192 // Note that the following steps must occur in exactly the specified order. | 4007 // Note that the following steps must occur in exactly the specified order. |
4193 | 4008 |
4194 // Cross-link. | 4009 // Cross-link. |
4195 CrossLinkFile(result, proto); | 4010 CrossLinkFile(result, proto); |
4196 | 4011 |
4197 // Interpret any remaining uninterpreted options gathered into | 4012 // Interpret any remaining uninterpreted options gathered into |
4198 // options_to_interpret_ during descriptor building. Cross-linking has made | 4013 // options_to_interpret_ during descriptor building. Cross-linking has made |
4199 // extension options known, so all interpretations should now succeed. | 4014 // extension options known, so all interpretations should now succeed. |
4200 if (!had_errors_) { | 4015 if (!had_errors_) { |
4201 OptionInterpreter option_interpreter(this); | 4016 OptionInterpreter option_interpreter(this); |
4202 for (std::vector<OptionsToInterpret>::iterator iter = | 4017 for (vector<OptionsToInterpret>::iterator iter = |
4203 options_to_interpret_.begin(); | 4018 options_to_interpret_.begin(); |
4204 iter != options_to_interpret_.end(); ++iter) { | 4019 iter != options_to_interpret_.end(); ++iter) { |
4205 option_interpreter.InterpretOptions(&(*iter)); | 4020 option_interpreter.InterpretOptions(&(*iter)); |
4206 } | 4021 } |
4207 options_to_interpret_.clear(); | 4022 options_to_interpret_.clear(); |
4208 } | 4023 } |
4209 | 4024 |
4210 // Validate options. | 4025 // Validate options. |
4211 if (!had_errors_) { | 4026 if (!had_errors_) { |
4212 ValidateFileOptions(result, proto); | 4027 ValidateFileOptions(result, proto); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4340 } | 4155 } |
4341 } | 4156 } |
4342 | 4157 |
4343 // Check that extension ranges don't overlap and don't include | 4158 // Check that extension ranges don't overlap and don't include |
4344 // reserved field numbers. | 4159 // reserved field numbers. |
4345 for (int i = 0; i < result->extension_range_count(); i++) { | 4160 for (int i = 0; i < result->extension_range_count(); i++) { |
4346 const Descriptor::ExtensionRange* range1 = result->extension_range(i); | 4161 const Descriptor::ExtensionRange* range1 = result->extension_range(i); |
4347 for (int j = 0; j < result->reserved_range_count(); j++) { | 4162 for (int j = 0; j < result->reserved_range_count(); j++) { |
4348 const Descriptor::ReservedRange* range2 = result->reserved_range(j); | 4163 const Descriptor::ReservedRange* range2 = result->reserved_range(j); |
4349 if (range1->end > range2->start && range2->end > range1->start) { | 4164 if (range1->end > range2->start && range2->end > range1->start) { |
4350 AddError(result->full_name(), proto.extension_range(i), | 4165 AddError(result->full_name(), proto.extension_range(j), |
4351 DescriptorPool::ErrorCollector::NUMBER, | 4166 DescriptorPool::ErrorCollector::NUMBER, |
4352 strings::Substitute("Extension range $0 to $1 overlaps with " | 4167 strings::Substitute("Extension range $0 to $1 overlaps with " |
4353 "reserved range $2 to $3.", | 4168 "reserved range $2 to $3.", |
4354 range1->start, range1->end - 1, | 4169 range1->start, range1->end - 1, |
4355 range2->start, range2->end - 1)); | 4170 range2->start, range2->end - 1)); |
4356 } | 4171 } |
4357 } | 4172 } |
4358 for (int j = i + 1; j < result->extension_range_count(); j++) { | 4173 for (int j = i + 1; j < result->extension_range_count(); j++) { |
4359 const Descriptor::ExtensionRange* range2 = result->extension_range(j); | 4174 const Descriptor::ExtensionRange* range2 = result->extension_range(j); |
4360 if (range1->end > range2->start && range2->end > range1->start) { | 4175 if (range1->end > range2->start && range2->end > range1->start) { |
4361 AddError(result->full_name(), proto.extension_range(i), | 4176 AddError(result->full_name(), proto.extension_range(j), |
4362 DescriptorPool::ErrorCollector::NUMBER, | 4177 DescriptorPool::ErrorCollector::NUMBER, |
4363 strings::Substitute("Extension range $0 to $1 overlaps with " | 4178 strings::Substitute("Extension range $0 to $1 overlaps with " |
4364 "already-defined range $2 to $3.", | 4179 "already-defined range $2 to $3.", |
4365 range2->start, range2->end - 1, | 4180 range2->start, range2->end - 1, |
4366 range1->start, range1->end - 1)); | 4181 range1->start, range1->end - 1)); |
4367 } | 4182 } |
4368 } | 4183 } |
4369 } | 4184 } |
4370 } | 4185 } |
4371 | 4186 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4404 // format, so the optimization wouldn't help much. | 4219 // format, so the optimization wouldn't help much. |
4405 result->camelcase_name_ = | 4220 result->camelcase_name_ = |
4406 tables_->AllocateString(ToCamelCase(proto.name(), | 4221 tables_->AllocateString(ToCamelCase(proto.name(), |
4407 /* lower_first = */ true)); | 4222 /* lower_first = */ true)); |
4408 | 4223 |
4409 if (proto.has_json_name()) { | 4224 if (proto.has_json_name()) { |
4410 result->has_json_name_ = true; | 4225 result->has_json_name_ = true; |
4411 result->json_name_ = tables_->AllocateString(proto.json_name()); | 4226 result->json_name_ = tables_->AllocateString(proto.json_name()); |
4412 } else { | 4227 } else { |
4413 result->has_json_name_ = false; | 4228 result->has_json_name_ = false; |
4414 result->json_name_ = tables_->AllocateString(ToJsonName(proto.name())); | 4229 result->json_name_ = result->camelcase_name_; |
4415 } | 4230 } |
4416 | 4231 |
4417 // Some compilers do not allow static_cast directly between two enum types, | 4232 // Some compilers do not allow static_cast directly between two enum types, |
4418 // so we must cast to int first. | 4233 // so we must cast to int first. |
4419 result->type_ = static_cast<FieldDescriptor::Type>( | 4234 result->type_ = static_cast<FieldDescriptor::Type>( |
4420 implicit_cast<int>(proto.type())); | 4235 implicit_cast<int>(proto.type())); |
4421 result->label_ = static_cast<FieldDescriptor::Label>( | 4236 result->label_ = static_cast<FieldDescriptor::Label>( |
4422 implicit_cast<int>(proto.label())); | 4237 implicit_cast<int>(proto.label())); |
4423 | 4238 |
4424 // An extension cannot have a required field (b/13365836). | 4239 // An extension cannot have a required field (b/13365836). |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4462 case FieldDescriptor::CPPTYPE_UINT32: | 4277 case FieldDescriptor::CPPTYPE_UINT32: |
4463 result->default_value_uint32_ = | 4278 result->default_value_uint32_ = |
4464 strtoul(proto.default_value().c_str(), &end_pos, 0); | 4279 strtoul(proto.default_value().c_str(), &end_pos, 0); |
4465 break; | 4280 break; |
4466 case FieldDescriptor::CPPTYPE_UINT64: | 4281 case FieldDescriptor::CPPTYPE_UINT64: |
4467 result->default_value_uint64_ = | 4282 result->default_value_uint64_ = |
4468 strtou64(proto.default_value().c_str(), &end_pos, 0); | 4283 strtou64(proto.default_value().c_str(), &end_pos, 0); |
4469 break; | 4284 break; |
4470 case FieldDescriptor::CPPTYPE_FLOAT: | 4285 case FieldDescriptor::CPPTYPE_FLOAT: |
4471 if (proto.default_value() == "inf") { | 4286 if (proto.default_value() == "inf") { |
4472 result->default_value_float_ = | 4287 result->default_value_float_ = numeric_limits<float>::infinity(); |
4473 std::numeric_limits<float>::infinity(); | |
4474 } else if (proto.default_value() == "-inf") { | 4288 } else if (proto.default_value() == "-inf") { |
4475 result->default_value_float_ = | 4289 result->default_value_float_ = -numeric_limits<float>::infinity(); |
4476 -std::numeric_limits<float>::infinity(); | |
4477 } else if (proto.default_value() == "nan") { | 4290 } else if (proto.default_value() == "nan") { |
4478 result->default_value_float_ = | 4291 result->default_value_float_ = numeric_limits<float>::quiet_NaN(); |
4479 std::numeric_limits<float>::quiet_NaN(); | |
4480 } else { | 4292 } else { |
4481 result->default_value_float_ = io::SafeDoubleToFloat( | 4293 result->default_value_float_ = io::SafeDoubleToFloat( |
4482 io::NoLocaleStrtod(proto.default_value().c_str(), &end_pos)); | 4294 io::NoLocaleStrtod(proto.default_value().c_str(), &end_pos)); |
4483 } | 4295 } |
4484 break; | 4296 break; |
4485 case FieldDescriptor::CPPTYPE_DOUBLE: | 4297 case FieldDescriptor::CPPTYPE_DOUBLE: |
4486 if (proto.default_value() == "inf") { | 4298 if (proto.default_value() == "inf") { |
4487 result->default_value_double_ = | 4299 result->default_value_double_ = numeric_limits<double>::infinity(); |
4488 std::numeric_limits<double>::infinity(); | |
4489 } else if (proto.default_value() == "-inf") { | 4300 } else if (proto.default_value() == "-inf") { |
4490 result->default_value_double_ = | 4301 result->default_value_double_ = -numeric_limits<double>::infinity(); |
4491 -std::numeric_limits<double>::infinity(); | |
4492 } else if (proto.default_value() == "nan") { | 4302 } else if (proto.default_value() == "nan") { |
4493 result->default_value_double_ = | 4303 result->default_value_double_ = numeric_limits<double>::quiet_NaN(); |
4494 std::numeric_limits<double>::quiet_NaN(); | |
4495 } else { | 4304 } else { |
4496 result->default_value_double_ = | 4305 result->default_value_double_ = |
4497 io::NoLocaleStrtod(proto.default_value().c_str(), &end_pos); | 4306 io::NoLocaleStrtod(proto.default_value().c_str(), &end_pos); |
4498 } | 4307 } |
4499 break; | 4308 break; |
4500 case FieldDescriptor::CPPTYPE_BOOL: | 4309 case FieldDescriptor::CPPTYPE_BOOL: |
4501 if (proto.default_value() == "true") { | 4310 if (proto.default_value() == "true") { |
4502 result->default_value_bool_ = true; | 4311 result->default_value_bool_ = true; |
4503 } else if (proto.default_value() == "false") { | 4312 } else if (proto.default_value() == "false") { |
4504 result->default_value_bool_ = false; | 4313 result->default_value_bool_ = false; |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4707 | 4516 |
4708 result->name_ = tables_->AllocateString(proto.name()); | 4517 result->name_ = tables_->AllocateString(proto.name()); |
4709 result->full_name_ = full_name; | 4518 result->full_name_ = full_name; |
4710 | 4519 |
4711 result->containing_type_ = parent; | 4520 result->containing_type_ = parent; |
4712 | 4521 |
4713 // We need to fill these in later. | 4522 // We need to fill these in later. |
4714 result->field_count_ = 0; | 4523 result->field_count_ = 0; |
4715 result->fields_ = NULL; | 4524 result->fields_ = NULL; |
4716 | 4525 |
4717 // Copy options. | |
4718 if (!proto.has_options()) { | |
4719 result->options_ = NULL; // Will set to default_instance later. | |
4720 } else { | |
4721 AllocateOptions(proto.options(), result); | |
4722 } | |
4723 | |
4724 AddSymbol(result->full_name(), parent, result->name(), | 4526 AddSymbol(result->full_name(), parent, result->name(), |
4725 proto, Symbol(result)); | 4527 proto, Symbol(result)); |
4726 } | 4528 } |
4727 | 4529 |
4728 void DescriptorBuilder::CheckEnumValueUniqueness( | |
4729 const EnumDescriptorProto& proto, const EnumDescriptor* result) { | |
4730 | |
4731 // Check that enum labels are still unique when we remove the enum prefix from | |
4732 // values that have it. | |
4733 // | |
4734 // This will fail for something like: | |
4735 // | |
4736 // enum MyEnum { | |
4737 // MY_ENUM_FOO = 0; | |
4738 // FOO = 1; | |
4739 // } | |
4740 // | |
4741 // By enforcing this reasonable constraint, we allow code generators to strip | |
4742 // the prefix and/or PascalCase it without creating conflicts. This can lead | |
4743 // to much nicer language-specific enums like: | |
4744 // | |
4745 // enum NameType { | |
4746 // FirstName = 1, | |
4747 // LastName = 2, | |
4748 // } | |
4749 // | |
4750 // Instead of: | |
4751 // | |
4752 // enum NameType { | |
4753 // NAME_TYPE_FIRST_NAME = 1, | |
4754 // NAME_TYPE_LAST_NAME = 2, | |
4755 // } | |
4756 PrefixRemover remover(result->name()); | |
4757 std::map<string, const google::protobuf::EnumValueDescriptor*> values; | |
4758 for (int i = 0; i < result->value_count(); i++) { | |
4759 const google::protobuf::EnumValueDescriptor* value = result->value(i); | |
4760 string stripped = | |
4761 EnumValueToPascalCase(remover.MaybeRemove(value->name())); | |
4762 std::pair<std::map<string, const google::protobuf::EnumValueDescriptor*>::it
erator, | |
4763 bool> | |
4764 insert_result = values.insert(std::make_pair(stripped, value)); | |
4765 bool inserted = insert_result.second; | |
4766 | |
4767 // We don't throw the error if the two conflicting symbols are identical, or | |
4768 // if they map to the same number. In the former case, the normal symbol | |
4769 // duplication error will fire so we don't need to (and its error message | |
4770 // will make more sense). We allow the latter case so users can create | |
4771 // aliases which add or remove the prefix (code generators that do prefix | |
4772 // stripping should de-dup the labels in this case). | |
4773 if (!inserted && insert_result.first->second->name() != value->name() && | |
4774 insert_result.first->second->number() != value->number()) { | |
4775 string error_message = | |
4776 "When enum name is stripped and label is PascalCased (" + stripped + | |
4777 "), this value label conflicts with " + values[stripped]->name() + | |
4778 ". This will make the proto fail to compile for some languages, such " | |
4779 "as C#."; | |
4780 // There are proto2 enums out there with conflicting names, so to preserve | |
4781 // compatibility we issue only a warning for proto2. | |
4782 if (result->file()->syntax() == FileDescriptor::SYNTAX_PROTO2) { | |
4783 AddWarning(value->full_name(), proto.value(i), | |
4784 DescriptorPool::ErrorCollector::NAME, error_message); | |
4785 } else { | |
4786 AddError(value->full_name(), proto.value(i), | |
4787 DescriptorPool::ErrorCollector::NAME, error_message); | |
4788 } | |
4789 } | |
4790 } | |
4791 } | |
4792 | |
4793 void DescriptorBuilder::BuildEnum(const EnumDescriptorProto& proto, | 4530 void DescriptorBuilder::BuildEnum(const EnumDescriptorProto& proto, |
4794 const Descriptor* parent, | 4531 const Descriptor* parent, |
4795 EnumDescriptor* result) { | 4532 EnumDescriptor* result) { |
4796 const string& scope = (parent == NULL) ? | 4533 const string& scope = (parent == NULL) ? |
4797 file_->package() : parent->full_name(); | 4534 file_->package() : parent->full_name(); |
4798 string* full_name = tables_->AllocateString(scope); | 4535 string* full_name = tables_->AllocateString(scope); |
4799 if (!full_name->empty()) full_name->append(1, '.'); | 4536 if (!full_name->empty()) full_name->append(1, '.'); |
4800 full_name->append(proto.name()); | 4537 full_name->append(proto.name()); |
4801 | 4538 |
4802 ValidateSymbolName(proto.name(), *full_name, proto); | 4539 ValidateSymbolName(proto.name(), *full_name, proto); |
4803 | 4540 |
4804 result->name_ = tables_->AllocateString(proto.name()); | 4541 result->name_ = tables_->AllocateString(proto.name()); |
4805 result->full_name_ = full_name; | 4542 result->full_name_ = full_name; |
4806 result->file_ = file_; | 4543 result->file_ = file_; |
4807 result->containing_type_ = parent; | 4544 result->containing_type_ = parent; |
4808 result->is_placeholder_ = false; | 4545 result->is_placeholder_ = false; |
4809 result->is_unqualified_placeholder_ = false; | 4546 result->is_unqualified_placeholder_ = false; |
4810 | 4547 |
4811 if (proto.value_size() == 0) { | 4548 if (proto.value_size() == 0) { |
4812 // We cannot allow enums with no values because this would mean there | 4549 // We cannot allow enums with no values because this would mean there |
4813 // would be no valid default value for fields of this type. | 4550 // would be no valid default value for fields of this type. |
4814 AddError(result->full_name(), proto, | 4551 AddError(result->full_name(), proto, |
4815 DescriptorPool::ErrorCollector::NAME, | 4552 DescriptorPool::ErrorCollector::NAME, |
4816 "Enums must contain at least one value."); | 4553 "Enums must contain at least one value."); |
4817 } | 4554 } |
4818 | 4555 |
4819 BUILD_ARRAY(proto, result, value, BuildEnumValue, result); | 4556 BUILD_ARRAY(proto, result, value, BuildEnumValue, result); |
4820 | 4557 |
4821 CheckEnumValueUniqueness(proto, result); | |
4822 | |
4823 // Copy options. | 4558 // Copy options. |
4824 if (!proto.has_options()) { | 4559 if (!proto.has_options()) { |
4825 result->options_ = NULL; // Will set to default_instance later. | 4560 result->options_ = NULL; // Will set to default_instance later. |
4826 } else { | 4561 } else { |
4827 AllocateOptions(proto.options(), result); | 4562 AllocateOptions(proto.options(), result); |
4828 } | 4563 } |
4829 | 4564 |
4830 AddSymbol(result->full_name(), parent, result->name(), | 4565 AddSymbol(result->full_name(), parent, result->name(), |
4831 proto, Symbol(result)); | 4566 proto, Symbol(result)); |
4832 } | 4567 } |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5041 if (oneof_decl->field_count() == 0) { | 4776 if (oneof_decl->field_count() == 0) { |
5042 AddError(message->full_name() + "." + oneof_decl->name(), | 4777 AddError(message->full_name() + "." + oneof_decl->name(), |
5043 proto.oneof_decl(i), | 4778 proto.oneof_decl(i), |
5044 DescriptorPool::ErrorCollector::NAME, | 4779 DescriptorPool::ErrorCollector::NAME, |
5045 "Oneof must have at least one field."); | 4780 "Oneof must have at least one field."); |
5046 } | 4781 } |
5047 | 4782 |
5048 oneof_decl->fields_ = | 4783 oneof_decl->fields_ = |
5049 tables_->AllocateArray<const FieldDescriptor*>(oneof_decl->field_count_); | 4784 tables_->AllocateArray<const FieldDescriptor*>(oneof_decl->field_count_); |
5050 oneof_decl->field_count_ = 0; | 4785 oneof_decl->field_count_ = 0; |
5051 | |
5052 if (oneof_decl->options_ == NULL) { | |
5053 oneof_decl->options_ = &OneofOptions::default_instance(); | |
5054 } | |
5055 } | 4786 } |
5056 | 4787 |
5057 // Then fill them in. | 4788 // Then fill them in. |
5058 for (int i = 0; i < message->field_count(); i++) { | 4789 for (int i = 0; i < message->field_count(); i++) { |
5059 const OneofDescriptor* oneof_decl = message->field(i)->containing_oneof(); | 4790 const OneofDescriptor* oneof_decl = message->field(i)->containing_oneof(); |
5060 if (oneof_decl != NULL) { | 4791 if (oneof_decl != NULL) { |
5061 OneofDescriptor* mutable_oneof_decl = | 4792 OneofDescriptor* mutable_oneof_decl = |
5062 &message->oneof_decls_[oneof_decl->index()]; | 4793 &message->oneof_decls_[oneof_decl->index()]; |
5063 message->fields_[i].index_in_oneof_ = mutable_oneof_decl->field_count_; | 4794 message->fields_[i].index_in_oneof_ = mutable_oneof_decl->field_count_; |
5064 mutable_oneof_decl->fields_[mutable_oneof_decl->field_count_++] = | 4795 mutable_oneof_decl->fields_[mutable_oneof_decl->field_count_++] = |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5228 } | 4959 } |
5229 } | 4960 } |
5230 | 4961 |
5231 // Add the field to the fields-by-number table. | 4962 // Add the field to the fields-by-number table. |
5232 // Note: We have to do this *after* cross-linking because extensions do not | 4963 // Note: We have to do this *after* cross-linking because extensions do not |
5233 // know their containing type until now. | 4964 // know their containing type until now. |
5234 if (!file_tables_->AddFieldByNumber(field)) { | 4965 if (!file_tables_->AddFieldByNumber(field)) { |
5235 const FieldDescriptor* conflicting_field = | 4966 const FieldDescriptor* conflicting_field = |
5236 file_tables_->FindFieldByNumber(field->containing_type(), | 4967 file_tables_->FindFieldByNumber(field->containing_type(), |
5237 field->number()); | 4968 field->number()); |
5238 string containing_type_name = field->containing_type() == NULL | |
5239 ? "unknown" | |
5240 : field->containing_type()->full_name(); | |
5241 if (field->is_extension()) { | 4969 if (field->is_extension()) { |
5242 AddError(field->full_name(), proto, | 4970 AddError(field->full_name(), proto, |
5243 DescriptorPool::ErrorCollector::NUMBER, | 4971 DescriptorPool::ErrorCollector::NUMBER, |
5244 strings::Substitute("Extension number $0 has already been used " | 4972 strings::Substitute("Extension number $0 has already been used " |
5245 "in \"$1\" by extension \"$2\".", | 4973 "in \"$1\" by extension \"$2\".", |
5246 field->number(), | 4974 field->number(), |
5247 containing_type_name, | 4975 field->containing_type()->full_name(), |
5248 conflicting_field->full_name())); | 4976 conflicting_field->full_name())); |
5249 } else { | 4977 } else { |
5250 AddError(field->full_name(), proto, | 4978 AddError(field->full_name(), proto, |
5251 DescriptorPool::ErrorCollector::NUMBER, | 4979 DescriptorPool::ErrorCollector::NUMBER, |
5252 strings::Substitute("Field number $0 has already been used in " | 4980 strings::Substitute("Field number $0 has already been used in " |
5253 "\"$1\" by field \"$2\".", | 4981 "\"$1\" by field \"$2\".", |
5254 field->number(), | 4982 field->number(), |
5255 containing_type_name, | 4983 field->containing_type()->full_name(), |
5256 conflicting_field->name())); | 4984 conflicting_field->name())); |
5257 } | 4985 } |
5258 } else { | 4986 } else { |
5259 if (field->is_extension()) { | 4987 if (field->is_extension()) { |
5260 if (!tables_->AddExtension(field)) { | 4988 if (!tables_->AddExtension(field)) { |
5261 const FieldDescriptor* conflicting_field = | 4989 const FieldDescriptor* conflicting_field = |
5262 tables_->FindExtension(field->containing_type(), field->number()); | 4990 tables_->FindExtension(field->containing_type(), field->number()); |
5263 string error_msg = strings::Substitute( | 4991 string error_msg = strings::Substitute( |
5264 "Extension number $0 has already been used in \"$1\" by extension " | 4992 "Extension number $0 has already been used in \"$1\" by extension " |
5265 "\"$2\" defined in $3.", | 4993 "\"$2\" defined in $3.", |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5439 if (message->options().message_set_wire_format()) { | 5167 if (message->options().message_set_wire_format()) { |
5440 // Using MessageSet doesn't make sense since we disallow extensions. | 5168 // Using MessageSet doesn't make sense since we disallow extensions. |
5441 AddError(message->full_name(), proto, | 5169 AddError(message->full_name(), proto, |
5442 DescriptorPool::ErrorCollector::OTHER, | 5170 DescriptorPool::ErrorCollector::OTHER, |
5443 "MessageSet is not supported in proto3."); | 5171 "MessageSet is not supported in proto3."); |
5444 } | 5172 } |
5445 | 5173 |
5446 // In proto3, we reject field names if they conflict in camelCase. | 5174 // In proto3, we reject field names if they conflict in camelCase. |
5447 // Note that we currently enforce a stricter rule: Field names must be | 5175 // Note that we currently enforce a stricter rule: Field names must be |
5448 // unique after being converted to lowercase with underscores removed. | 5176 // unique after being converted to lowercase with underscores removed. |
5449 std::map<string, const FieldDescriptor*> name_to_field; | 5177 map<string, const FieldDescriptor*> name_to_field; |
5450 for (int i = 0; i < message->field_count(); ++i) { | 5178 for (int i = 0; i < message->field_count(); ++i) { |
5451 string lowercase_name = ToLowercaseWithoutUnderscores( | 5179 string lowercase_name = ToLowercaseWithoutUnderscores( |
5452 message->field(i)->name()); | 5180 message->field(i)->name()); |
5453 if (name_to_field.find(lowercase_name) != name_to_field.end()) { | 5181 if (name_to_field.find(lowercase_name) != name_to_field.end()) { |
5454 AddError(message->full_name(), proto, | 5182 AddError(message->full_name(), proto, |
5455 DescriptorPool::ErrorCollector::OTHER, | 5183 DescriptorPool::ErrorCollector::OTHER, |
5456 "The JSON camel-case name of field \"" + | 5184 "The JSON camcel-case name of field \"" + |
5457 message->field(i)->name() + "\" conflicts with field \"" + | 5185 message->field(i)->name() + "\" conflicts with field \"" + |
5458 name_to_field[lowercase_name]->name() + "\". This is not " + | 5186 name_to_field[lowercase_name]->name() + "\". This is not " + |
5459 "allowed in proto3."); | 5187 "allowed in proto3."); |
5460 } else { | 5188 } else { |
5461 name_to_field[lowercase_name] = message->field(i); | 5189 name_to_field[lowercase_name] = message->field(i); |
5462 } | 5190 } |
5463 } | 5191 } |
5464 } | 5192 } |
5465 | 5193 |
5466 void DescriptorBuilder::ValidateProto3Field( | 5194 void DescriptorBuilder::ValidateProto3Field( |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5590 "ValueType> instead."); | 5318 "ValueType> instead."); |
5591 } | 5319 } |
5592 } | 5320 } |
5593 | 5321 |
5594 } | 5322 } |
5595 | 5323 |
5596 void DescriptorBuilder::ValidateEnumOptions(EnumDescriptor* enm, | 5324 void DescriptorBuilder::ValidateEnumOptions(EnumDescriptor* enm, |
5597 const EnumDescriptorProto& proto) { | 5325 const EnumDescriptorProto& proto) { |
5598 VALIDATE_OPTIONS_FROM_ARRAY(enm, value, EnumValue); | 5326 VALIDATE_OPTIONS_FROM_ARRAY(enm, value, EnumValue); |
5599 if (!enm->options().has_allow_alias() || !enm->options().allow_alias()) { | 5327 if (!enm->options().has_allow_alias() || !enm->options().allow_alias()) { |
5600 std::map<int, string> used_values; | 5328 map<int, string> used_values; |
5601 for (int i = 0; i < enm->value_count(); ++i) { | 5329 for (int i = 0; i < enm->value_count(); ++i) { |
5602 const EnumValueDescriptor* enum_value = enm->value(i); | 5330 const EnumValueDescriptor* enum_value = enm->value(i); |
5603 if (used_values.find(enum_value->number()) != used_values.end()) { | 5331 if (used_values.find(enum_value->number()) != used_values.end()) { |
5604 string error = | 5332 string error = |
5605 "\"" + enum_value->full_name() + | 5333 "\"" + enum_value->full_name() + |
5606 "\" uses the same enum value as \"" + | 5334 "\" uses the same enum value as \"" + |
5607 used_values[enum_value->number()] + "\". If this is intended, set " | 5335 used_values[enum_value->number()] + "\". If this is intended, set " |
5608 "'option allow_alias = true;' to the enum definition."; | 5336 "'option allow_alias = true;' to the enum definition."; |
5609 if (!enm->options().allow_alias()) { | 5337 if (!enm->options().allow_alias()) { |
5610 // Generate error if duplicated enum values are explicitly disallowed. | 5338 // Generate error if duplicated enum values are explicitly disallowed. |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5717 field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, | 5445 field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, |
5718 "Enum value in map must define 0 as the first value."); | 5446 "Enum value in map must define 0 as the first value."); |
5719 } | 5447 } |
5720 } | 5448 } |
5721 | 5449 |
5722 return true; | 5450 return true; |
5723 } | 5451 } |
5724 | 5452 |
5725 void DescriptorBuilder::DetectMapConflicts(const Descriptor* message, | 5453 void DescriptorBuilder::DetectMapConflicts(const Descriptor* message, |
5726 const DescriptorProto& proto) { | 5454 const DescriptorProto& proto) { |
5727 std::map<string, const Descriptor*> seen_types; | 5455 map<string, const Descriptor*> seen_types; |
5728 for (int i = 0; i < message->nested_type_count(); ++i) { | 5456 for (int i = 0; i < message->nested_type_count(); ++i) { |
5729 const Descriptor* nested = message->nested_type(i); | 5457 const Descriptor* nested = message->nested_type(i); |
5730 std::pair<std::map<string, const Descriptor*>::iterator, bool> result = | 5458 pair<map<string, const Descriptor*>::iterator, bool> result = |
5731 seen_types.insert(std::make_pair(nested->name(), nested)); | 5459 seen_types.insert(std::make_pair(nested->name(), nested)); |
5732 if (!result.second) { | 5460 if (!result.second) { |
5733 if (result.first->second->options().map_entry() || | 5461 if (result.first->second->options().map_entry() || |
5734 nested->options().map_entry()) { | 5462 nested->options().map_entry()) { |
5735 AddError(message->full_name(), proto, | 5463 AddError(message->full_name(), proto, |
5736 DescriptorPool::ErrorCollector::NAME, | 5464 DescriptorPool::ErrorCollector::NAME, |
5737 "Expanded map entry type " + nested->name() + | 5465 "Expanded map entry type " + nested->name() + |
5738 " conflicts with an existing nested message type."); | 5466 " conflicts with an existing nested message type."); |
5739 } | 5467 } |
5740 } | 5468 } |
5741 // Recursively test on the nested types. | 5469 // Recursively test on the nested types. |
5742 DetectMapConflicts(message->nested_type(i), proto.nested_type(i)); | 5470 DetectMapConflicts(message->nested_type(i), proto.nested_type(i)); |
5743 } | 5471 } |
5744 // Check for conflicted field names. | 5472 // Check for conflicted field names. |
5745 for (int i = 0; i < message->field_count(); ++i) { | 5473 for (int i = 0; i < message->field_count(); ++i) { |
5746 const FieldDescriptor* field = message->field(i); | 5474 const FieldDescriptor* field = message->field(i); |
5747 std::map<string, const Descriptor*>::iterator iter = | 5475 map<string, const Descriptor*>::iterator iter = |
5748 seen_types.find(field->name()); | 5476 seen_types.find(field->name()); |
5749 if (iter != seen_types.end() && iter->second->options().map_entry()) { | 5477 if (iter != seen_types.end() && iter->second->options().map_entry()) { |
5750 AddError(message->full_name(), proto, | 5478 AddError(message->full_name(), proto, |
5751 DescriptorPool::ErrorCollector::NAME, | 5479 DescriptorPool::ErrorCollector::NAME, |
5752 "Expanded map entry type " + iter->second->name() + | 5480 "Expanded map entry type " + iter->second->name() + |
5753 " conflicts with an existing field."); | 5481 " conflicts with an existing field."); |
5754 } | 5482 } |
5755 } | 5483 } |
5756 // Check for conflicted enum names. | 5484 // Check for conflicted enum names. |
5757 for (int i = 0; i < message->enum_type_count(); ++i) { | 5485 for (int i = 0; i < message->enum_type_count(); ++i) { |
5758 const EnumDescriptor* enum_desc = message->enum_type(i); | 5486 const EnumDescriptor* enum_desc = message->enum_type(i); |
5759 std::map<string, const Descriptor*>::iterator iter = | 5487 map<string, const Descriptor*>::iterator iter = |
5760 seen_types.find(enum_desc->name()); | 5488 seen_types.find(enum_desc->name()); |
5761 if (iter != seen_types.end() && iter->second->options().map_entry()) { | 5489 if (iter != seen_types.end() && iter->second->options().map_entry()) { |
5762 AddError(message->full_name(), proto, | 5490 AddError(message->full_name(), proto, |
5763 DescriptorPool::ErrorCollector::NAME, | 5491 DescriptorPool::ErrorCollector::NAME, |
5764 "Expanded map entry type " + iter->second->name() + | 5492 "Expanded map entry type " + iter->second->name() + |
5765 " conflicts with an existing enum type."); | 5493 " conflicts with an existing enum type."); |
5766 } | 5494 } |
5767 } | 5495 } |
5768 // Check for conflicted oneof names. | 5496 // Check for conflicted oneof names. |
5769 for (int i = 0; i < message->oneof_decl_count(); ++i) { | 5497 for (int i = 0; i < message->oneof_decl_count(); ++i) { |
5770 const OneofDescriptor* oneof_desc = message->oneof_decl(i); | 5498 const OneofDescriptor* oneof_desc = message->oneof_decl(i); |
5771 std::map<string, const Descriptor*>::iterator iter = | 5499 map<string, const Descriptor*>::iterator iter = |
5772 seen_types.find(oneof_desc->name()); | 5500 seen_types.find(oneof_desc->name()); |
5773 if (iter != seen_types.end() && iter->second->options().map_entry()) { | 5501 if (iter != seen_types.end() && iter->second->options().map_entry()) { |
5774 AddError(message->full_name(), proto, | 5502 AddError(message->full_name(), proto, |
5775 DescriptorPool::ErrorCollector::NAME, | 5503 DescriptorPool::ErrorCollector::NAME, |
5776 "Expanded map entry type " + iter->second->name() + | 5504 "Expanded map entry type " + iter->second->name() + |
5777 " conflicts with an existing oneof type."); | 5505 " conflicts with an existing oneof type."); |
5778 } | 5506 } |
5779 } | 5507 } |
5780 } | 5508 } |
5781 | 5509 |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5896 GOOGLE_CHECK(options_descriptor); | 5624 GOOGLE_CHECK(options_descriptor); |
5897 | 5625 |
5898 // We iterate over the name parts to drill into the submessages until we find | 5626 // We iterate over the name parts to drill into the submessages until we find |
5899 // the leaf field for the option. As we drill down we remember the current | 5627 // the leaf field for the option. As we drill down we remember the current |
5900 // submessage's descriptor in |descriptor| and the next field in that | 5628 // submessage's descriptor in |descriptor| and the next field in that |
5901 // submessage in |field|. We also track the fields we're drilling down | 5629 // submessage in |field|. We also track the fields we're drilling down |
5902 // through in |intermediate_fields|. As we go, we reconstruct the full option | 5630 // through in |intermediate_fields|. As we go, we reconstruct the full option |
5903 // name in |debug_msg_name|, for use in error messages. | 5631 // name in |debug_msg_name|, for use in error messages. |
5904 const Descriptor* descriptor = options_descriptor; | 5632 const Descriptor* descriptor = options_descriptor; |
5905 const FieldDescriptor* field = NULL; | 5633 const FieldDescriptor* field = NULL; |
5906 std::vector<const FieldDescriptor*> intermediate_fields; | 5634 vector<const FieldDescriptor*> intermediate_fields; |
5907 string debug_msg_name = ""; | 5635 string debug_msg_name = ""; |
5908 | 5636 |
5909 for (int i = 0; i < uninterpreted_option_->name_size(); ++i) { | 5637 for (int i = 0; i < uninterpreted_option_->name_size(); ++i) { |
5910 const string& name_part = uninterpreted_option_->name(i).name_part(); | 5638 const string& name_part = uninterpreted_option_->name(i).name_part(); |
5911 if (debug_msg_name.size() > 0) { | 5639 if (debug_msg_name.size() > 0) { |
5912 debug_msg_name += "."; | 5640 debug_msg_name += "."; |
5913 } | 5641 } |
5914 if (uninterpreted_option_->name(i).is_extension()) { | 5642 if (uninterpreted_option_->name(i).is_extension()) { |
5915 debug_msg_name += "(" + name_part + ")"; | 5643 debug_msg_name += "(" + name_part + ")"; |
5916 // Search for the extension's descriptor as an extension in the builder's | 5644 // Search for the extension's descriptor as an extension in the builder's |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6004 | 5732 |
6005 // First set the value on the UnknownFieldSet corresponding to the | 5733 // First set the value on the UnknownFieldSet corresponding to the |
6006 // innermost message. | 5734 // innermost message. |
6007 google::protobuf::scoped_ptr<UnknownFieldSet> unknown_fields(new UnknownFieldS
et()); | 5735 google::protobuf::scoped_ptr<UnknownFieldSet> unknown_fields(new UnknownFieldS
et()); |
6008 if (!SetOptionValue(field, unknown_fields.get())) { | 5736 if (!SetOptionValue(field, unknown_fields.get())) { |
6009 return false; // SetOptionValue() already added the error. | 5737 return false; // SetOptionValue() already added the error. |
6010 } | 5738 } |
6011 | 5739 |
6012 // Now wrap the UnknownFieldSet with UnknownFieldSets corresponding to all | 5740 // Now wrap the UnknownFieldSet with UnknownFieldSets corresponding to all |
6013 // the intermediate messages. | 5741 // the intermediate messages. |
6014 for (std::vector<const FieldDescriptor*>::reverse_iterator iter = | 5742 for (vector<const FieldDescriptor*>::reverse_iterator iter = |
6015 intermediate_fields.rbegin(); | 5743 intermediate_fields.rbegin(); |
6016 iter != intermediate_fields.rend(); ++iter) { | 5744 iter != intermediate_fields.rend(); ++iter) { |
6017 google::protobuf::scoped_ptr<UnknownFieldSet> parent_unknown_fields( | 5745 google::protobuf::scoped_ptr<UnknownFieldSet> parent_unknown_fields( |
6018 new UnknownFieldSet()); | 5746 new UnknownFieldSet()); |
6019 switch ((*iter)->type()) { | 5747 switch ((*iter)->type()) { |
6020 case FieldDescriptor::TYPE_MESSAGE: { | 5748 case FieldDescriptor::TYPE_MESSAGE: { |
6021 io::StringOutputStream outstr( | 5749 io::StringOutputStream outstr( |
6022 parent_unknown_fields->AddLengthDelimited((*iter)->number())); | 5750 parent_unknown_fields->AddLengthDelimited((*iter)->number())); |
6023 io::CodedOutputStream out(&outstr); | 5751 io::CodedOutputStream out(&outstr); |
6024 internal::WireFormat::SerializeUnknownFields(*unknown_fields, &out); | 5752 internal::WireFormat::SerializeUnknownFields(*unknown_fields, &out); |
(...skipping 29 matching lines...) Expand all Loading... |
6054 const UninterpretedOption& uninterpreted_option, Message* options) { | 5782 const UninterpretedOption& uninterpreted_option, Message* options) { |
6055 const FieldDescriptor* field = | 5783 const FieldDescriptor* field = |
6056 options->GetDescriptor()->FindFieldByName("uninterpreted_option"); | 5784 options->GetDescriptor()->FindFieldByName("uninterpreted_option"); |
6057 GOOGLE_CHECK(field != NULL); | 5785 GOOGLE_CHECK(field != NULL); |
6058 | 5786 |
6059 options->GetReflection()->AddMessage(options, field) | 5787 options->GetReflection()->AddMessage(options, field) |
6060 ->CopyFrom(uninterpreted_option); | 5788 ->CopyFrom(uninterpreted_option); |
6061 } | 5789 } |
6062 | 5790 |
6063 bool DescriptorBuilder::OptionInterpreter::ExamineIfOptionIsSet( | 5791 bool DescriptorBuilder::OptionInterpreter::ExamineIfOptionIsSet( |
6064 std::vector<const FieldDescriptor*>::const_iterator | 5792 vector<const FieldDescriptor*>::const_iterator intermediate_fields_iter, |
6065 intermediate_fields_iter, | 5793 vector<const FieldDescriptor*>::const_iterator intermediate_fields_end, |
6066 std::vector<const FieldDescriptor*>::const_iterator intermediate_fields_end, | |
6067 const FieldDescriptor* innermost_field, const string& debug_msg_name, | 5794 const FieldDescriptor* innermost_field, const string& debug_msg_name, |
6068 const UnknownFieldSet& unknown_fields) { | 5795 const UnknownFieldSet& unknown_fields) { |
6069 // We do linear searches of the UnknownFieldSet and its sub-groups. This | 5796 // We do linear searches of the UnknownFieldSet and its sub-groups. This |
6070 // should be fine since it's unlikely that any one options structure will | 5797 // should be fine since it's unlikely that any one options structure will |
6071 // contain more than a handful of options. | 5798 // contain more than a handful of options. |
6072 | 5799 |
6073 if (intermediate_fields_iter == intermediate_fields_end) { | 5800 if (intermediate_fields_iter == intermediate_fields_end) { |
6074 // We're at the innermost submessage. | 5801 // We're at the innermost submessage. |
6075 for (int i = 0; i < unknown_fields.field_count(); i++) { | 5802 for (int i = 0; i < unknown_fields.field_count(); i++) { |
6076 if (unknown_fields.field(i).number() == innermost_field->number()) { | 5803 if (unknown_fields.field(i).number() == innermost_field->number()) { |
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6516 if (!unused_dependency_.empty()) { | 6243 if (!unused_dependency_.empty()) { |
6517 std::set<string> annotation_extensions; | 6244 std::set<string> annotation_extensions; |
6518 annotation_extensions.insert("google.protobuf.MessageOptions"); | 6245 annotation_extensions.insert("google.protobuf.MessageOptions"); |
6519 annotation_extensions.insert("google.protobuf.FileOptions"); | 6246 annotation_extensions.insert("google.protobuf.FileOptions"); |
6520 annotation_extensions.insert("google.protobuf.FieldOptions"); | 6247 annotation_extensions.insert("google.protobuf.FieldOptions"); |
6521 annotation_extensions.insert("google.protobuf.EnumOptions"); | 6248 annotation_extensions.insert("google.protobuf.EnumOptions"); |
6522 annotation_extensions.insert("google.protobuf.EnumValueOptions"); | 6249 annotation_extensions.insert("google.protobuf.EnumValueOptions"); |
6523 annotation_extensions.insert("google.protobuf.ServiceOptions"); | 6250 annotation_extensions.insert("google.protobuf.ServiceOptions"); |
6524 annotation_extensions.insert("google.protobuf.MethodOptions"); | 6251 annotation_extensions.insert("google.protobuf.MethodOptions"); |
6525 annotation_extensions.insert("google.protobuf.StreamOptions"); | 6252 annotation_extensions.insert("google.protobuf.StreamOptions"); |
6526 for (std::set<const FileDescriptor*>::const_iterator | 6253 for (set<const FileDescriptor*>::const_iterator |
6527 it = unused_dependency_.begin(); | 6254 it = unused_dependency_.begin(); |
6528 it != unused_dependency_.end(); ++it) { | 6255 it != unused_dependency_.end(); ++it) { |
6529 // Do not log warnings for proto files which extend annotations. | 6256 // Do not log warnings for proto files which extend annotations. |
6530 int i; | 6257 int i; |
6531 for (i = 0 ; i < (*it)->extension_count(); ++i) { | 6258 for (i = 0 ; i < (*it)->extension_count(); ++i) { |
6532 if (annotation_extensions.find( | 6259 if (annotation_extensions.find( |
6533 (*it)->extension(i)->containing_type()->full_name()) | 6260 (*it)->extension(i)->containing_type()->full_name()) |
6534 != annotation_extensions.end()) { | 6261 != annotation_extensions.end()) { |
6535 break; | 6262 break; |
6536 } | 6263 } |
6537 } | 6264 } |
6538 // Log warnings for unused imported files. | 6265 // Log warnings for unused imported files. |
6539 if (i == (*it)->extension_count()) { | 6266 if (i == (*it)->extension_count()) { |
6540 string error_message = "Import " + (*it)->name() + " but not used."; | 6267 string error_message = "Import " + (*it)->name() + " but not used."; |
6541 AddWarning((*it)->name(), proto, DescriptorPool::ErrorCollector::OTHER, | 6268 AddWarning((*it)->name(), proto, DescriptorPool::ErrorCollector::OTHER, |
6542 error_message); | 6269 error_message); |
6543 } | 6270 } |
6544 } | 6271 } |
6545 } | 6272 } |
6546 } | 6273 } |
6547 | 6274 |
6548 } // namespace protobuf | 6275 } // namespace protobuf |
6549 } // namespace google | 6276 } // namespace google |
OLD | NEW |