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

Side by Side Diff: third_party/protobuf/src/google/protobuf/descriptor.cc

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

Powered by Google App Engine
This is Rietveld 408576698