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