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

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

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