| 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 |