1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // https://developers.google.com/protocol-buffers/ 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 9 // * Redistributions of source code must retain the above copyright 10 // notice, this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above 12 // copyright notice, this list of conditions and the following disclaimer 13 // in the documentation and/or other materials provided with the 14 // distribution. 15 // * Neither the name of Google Inc. nor the names of its 16 // contributors may be used to endorse or promote products derived from 17 // this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31 // Author: kenton (at) google.com (Kenton Varda) 32 // Based on original Protocol Buffers design by 33 // Sanjay Ghemawat, Jeff Dean, and others. 34 35 #include <google/protobuf/stubs/hash.h> 36 #include <map> 37 #include <memory> 38 #ifndef _SHARED_PTR_H 39 #include <google/protobuf/stubs/shared_ptr.h> 40 #endif 41 #include <set> 42 #include <string> 43 #include <vector> 44 #include <algorithm> 45 #include <limits> 46 47 #include <google/protobuf/descriptor.h> 48 #include <google/protobuf/descriptor_database.h> 49 #include <google/protobuf/descriptor.pb.h> 50 #include <google/protobuf/dynamic_message.h> 51 #include <google/protobuf/generated_message_util.h> 52 #include <google/protobuf/text_format.h> 53 #include <google/protobuf/unknown_field_set.h> 54 #include <google/protobuf/wire_format.h> 55 #include <google/protobuf/io/strtod.h> 56 #include <google/protobuf/io/coded_stream.h> 57 #include <google/protobuf/io/tokenizer.h> 58 #include <google/protobuf/io/zero_copy_stream_impl.h> 59 #include <google/protobuf/stubs/common.h> 60 #include <google/protobuf/stubs/logging.h> 61 #include <google/protobuf/stubs/mutex.h> 62 #include <google/protobuf/stubs/once.h> 63 #include <google/protobuf/stubs/stringprintf.h> 64 #include <google/protobuf/stubs/strutil.h> 65 #include <google/protobuf/stubs/substitute.h> 66 #include <google/protobuf/stubs/map_util.h> 67 #include <google/protobuf/stubs/stl_util.h> 68 69 #undef PACKAGE // autoheader #defines this. :( 70 71 namespace google { 72 namespace protobuf { 73 74 const FieldDescriptor::CppType 75 FieldDescriptor::kTypeToCppTypeMap[MAX_TYPE + 1] = { 76 static_cast<CppType>(0), // 0 is reserved for errors 77 78 CPPTYPE_DOUBLE, // TYPE_DOUBLE 79 CPPTYPE_FLOAT, // TYPE_FLOAT 80 CPPTYPE_INT64, // TYPE_INT64 81 CPPTYPE_UINT64, // TYPE_UINT64 82 CPPTYPE_INT32, // TYPE_INT32 83 CPPTYPE_UINT64, // TYPE_FIXED64 84 CPPTYPE_UINT32, // TYPE_FIXED32 85 CPPTYPE_BOOL, // TYPE_BOOL 86 CPPTYPE_STRING, // TYPE_STRING 87 CPPTYPE_MESSAGE, // TYPE_GROUP 88 CPPTYPE_MESSAGE, // TYPE_MESSAGE 89 CPPTYPE_STRING, // TYPE_BYTES 90 CPPTYPE_UINT32, // TYPE_UINT32 91 CPPTYPE_ENUM, // TYPE_ENUM 92 CPPTYPE_INT32, // TYPE_SFIXED32 93 CPPTYPE_INT64, // TYPE_SFIXED64 94 CPPTYPE_INT32, // TYPE_SINT32 95 CPPTYPE_INT64, // TYPE_SINT64 96 }; 97 98 const char * const FieldDescriptor::kTypeToName[MAX_TYPE + 1] = { 99 "ERROR", // 0 is reserved for errors 100 101 "double", // TYPE_DOUBLE 102 "float", // TYPE_FLOAT 103 "int64", // TYPE_INT64 104 "uint64", // TYPE_UINT64 105 "int32", // TYPE_INT32 106 "fixed64", // TYPE_FIXED64 107 "fixed32", // TYPE_FIXED32 108 "bool", // TYPE_BOOL 109 "string", // TYPE_STRING 110 "group", // TYPE_GROUP 111 "message", // TYPE_MESSAGE 112 "bytes", // TYPE_BYTES 113 "uint32", // TYPE_UINT32 114 "enum", // TYPE_ENUM 115 "sfixed32", // TYPE_SFIXED32 116 "sfixed64", // TYPE_SFIXED64 117 "sint32", // TYPE_SINT32 118 "sint64", // TYPE_SINT64 119 }; 120 121 const char * const FieldDescriptor::kCppTypeToName[MAX_CPPTYPE + 1] = { 122 "ERROR", // 0 is reserved for errors 123 124 "int32", // CPPTYPE_INT32 125 "int64", // CPPTYPE_INT64 126 "uint32", // CPPTYPE_UINT32 127 "uint64", // CPPTYPE_UINT64 128 "double", // CPPTYPE_DOUBLE 129 "float", // CPPTYPE_FLOAT 130 "bool", // CPPTYPE_BOOL 131 "enum", // CPPTYPE_ENUM 132 "string", // CPPTYPE_STRING 133 "message", // CPPTYPE_MESSAGE 134 }; 135 136 const char * const FieldDescriptor::kLabelToName[MAX_LABEL + 1] = { 137 "ERROR", // 0 is reserved for errors 138 139 "optional", // LABEL_OPTIONAL 140 "required", // LABEL_REQUIRED 141 "repeated", // LABEL_REPEATED 142 }; 143 144 const char* FileDescriptor::SyntaxName(FileDescriptor::Syntax syntax) { 145 switch (syntax) { 146 case SYNTAX_PROTO2: 147 return "proto2"; 148 case SYNTAX_PROTO3: 149 return "proto3"; 150 case SYNTAX_UNKNOWN: 151 return "unknown"; 152 } 153 GOOGLE_LOG(FATAL) << "can't reach here."; 154 return NULL; 155 } 156 157 static const char * const kNonLinkedWeakMessageReplacementName = "google.protobuf.Empty"; 158 159 #if !defined(_MSC_VER) || _MSC_VER >= 1900 160 const int FieldDescriptor::kMaxNumber; 161 const int FieldDescriptor::kFirstReservedNumber; 162 const int FieldDescriptor::kLastReservedNumber; 163 #endif 164 165 namespace { 166 167 string ToCamelCase(const string& input, bool lower_first) { 168 bool capitalize_next = !lower_first; 169 string result; 170 result.reserve(input.size()); 171 172 for (int i = 0; i < input.size(); i++) { 173 if (input[i] == '_') { 174 capitalize_next = true; 175 } else if (capitalize_next) { 176 // Note: I distrust ctype.h due to locales. 177 if ('a' <= input[i] && input[i] <= 'z') { 178 result.push_back(input[i] - 'a' + 'A'); 179 } else { 180 result.push_back(input[i]); 181 } 182 capitalize_next = false; 183 } else { 184 result.push_back(input[i]); 185 } 186 } 187 188 // Lower-case the first letter. 189 if (lower_first && !result.empty() && 'A' <= result[0] && result[0] <= 'Z') { 190 result[0] = result[0] - 'A' + 'a'; 191 } 192 193 return result; 194 } 195 196 // A DescriptorPool contains a bunch of hash_maps to implement the 197 // 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 199 // all objects in the pool rather than construct one or more small 200 // hash_maps for each object. 201 // 202 // The keys to these hash_maps are (parent, name) or (parent, number) 203 // pairs. Unfortunately STL doesn't provide hash functions for pair<>, 204 // so we must invent our own. 205 // 206 // 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* 208 // for the open source release. 209 210 typedef pair<const void*, const char*> PointerStringPair; 211 212 struct PointerStringPairEqual { 213 inline bool operator()(const PointerStringPair& a, 214 const PointerStringPair& b) const { 215 return a.first == b.first && strcmp(a.second, b.second) == 0; 216 } 217 }; 218 219 template<typename PairType> 220 struct PointerIntegerPairHash { 221 size_t operator()(const PairType& p) const { 222 // FIXME(kenton): What is the best way to compute this hash? I have 223 // no idea! This seems a bit better than an XOR. 224 return reinterpret_cast<intptr_t>(p.first) * ((1 << 16) - 1) + p.second; 225 } 226 227 #ifdef _MSC_VER 228 // Used only by MSVC and platforms where hash_map is not available. 229 static const size_t bucket_size = 4; 230 static const size_t min_buckets = 8; 231 #endif 232 inline bool operator()(const PairType& a, const PairType& b) const { 233 return a.first < b.first || 234 (a.first == b.first && a.second < b.second); 235 } 236 }; 237 238 typedef pair<const Descriptor*, int> DescriptorIntPair; 239 typedef pair<const EnumDescriptor*, int> EnumIntPair; 240 241 struct PointerStringPairHash { 242 size_t operator()(const PointerStringPair& p) const { 243 // FIXME(kenton): What is the best way to compute this hash? I have 244 // no idea! This seems a bit better than an XOR. 245 hash<const char*> cstring_hash; 246 return reinterpret_cast<intptr_t>(p.first) * ((1 << 16) - 1) + 247 cstring_hash(p.second); 248 } 249 250 #ifdef _MSC_VER 251 // Used only by MSVC and platforms where hash_map is not available. 252 static const size_t bucket_size = 4; 253 static const size_t min_buckets = 8; 254 #endif 255 inline bool operator()(const PointerStringPair& a, 256 const PointerStringPair& b) const { 257 if (a.first < b.first) return true; 258 if (a.first > b.first) return false; 259 return strcmp(a.second, b.second) < 0; 260 } 261 }; 262 263 264 struct Symbol { 265 enum Type { 266 NULL_SYMBOL, MESSAGE, FIELD, ONEOF, ENUM, ENUM_VALUE, SERVICE, METHOD, 267 PACKAGE 268 }; 269 Type type; 270 union { 271 const Descriptor* descriptor; 272 const FieldDescriptor* field_descriptor; 273 const OneofDescriptor* oneof_descriptor; 274 const EnumDescriptor* enum_descriptor; 275 const EnumValueDescriptor* enum_value_descriptor; 276 const ServiceDescriptor* service_descriptor; 277 const MethodDescriptor* method_descriptor; 278 const FileDescriptor* package_file_descriptor; 279 }; 280 281 inline Symbol() : type(NULL_SYMBOL) { descriptor = NULL; } 282 inline bool IsNull() const { return type == NULL_SYMBOL; } 283 inline bool IsType() const { 284 return type == MESSAGE || type == ENUM; 285 } 286 inline bool IsAggregate() const { 287 return type == MESSAGE || type == PACKAGE 288 || type == ENUM || type == SERVICE; 289 } 290 291 #define CONSTRUCTOR(TYPE, TYPE_CONSTANT, FIELD) \ 292 inline explicit Symbol(const TYPE* value) { \ 293 type = TYPE_CONSTANT; \ 294 this->FIELD = value; \ 295 } 296 297 CONSTRUCTOR(Descriptor , MESSAGE , descriptor ) 298 CONSTRUCTOR(FieldDescriptor , FIELD , field_descriptor ) 299 CONSTRUCTOR(OneofDescriptor , ONEOF , oneof_descriptor ) 300 CONSTRUCTOR(EnumDescriptor , ENUM , enum_descriptor ) 301 CONSTRUCTOR(EnumValueDescriptor, ENUM_VALUE, enum_value_descriptor ) 302 CONSTRUCTOR(ServiceDescriptor , SERVICE , service_descriptor ) 303 CONSTRUCTOR(MethodDescriptor , METHOD , method_descriptor ) 304 CONSTRUCTOR(FileDescriptor , PACKAGE , package_file_descriptor) 305 #undef CONSTRUCTOR 306 307 const FileDescriptor* GetFile() const { 308 switch (type) { 309 case NULL_SYMBOL: return NULL; 310 case MESSAGE : return descriptor ->file(); 311 case FIELD : return field_descriptor ->file(); 312 case ONEOF : return oneof_descriptor ->containing_type()->file(); 313 case ENUM : return enum_descriptor ->file(); 314 case ENUM_VALUE : return enum_value_descriptor->type()->file(); 315 case SERVICE : return service_descriptor ->file(); 316 case METHOD : return method_descriptor ->service()->file(); 317 case PACKAGE : return package_file_descriptor; 318 } 319 return NULL; 320 } 321 }; 322 323 const Symbol kNullSymbol; 324 325 typedef hash_map<const char*, Symbol, 326 hash<const char*>, streq> 327 SymbolsByNameMap; 328 typedef hash_map<PointerStringPair, Symbol, 329 PointerStringPairHash, PointerStringPairEqual> 330 SymbolsByParentMap; 331 typedef hash_map<const char*, const FileDescriptor*, 332 hash<const char*>, streq> 333 FilesByNameMap; 334 typedef hash_map<PointerStringPair, const FieldDescriptor*, 335 PointerStringPairHash, PointerStringPairEqual> 336 FieldsByNameMap; 337 typedef hash_map<DescriptorIntPair, const FieldDescriptor*, 338 PointerIntegerPairHash<DescriptorIntPair> > 339 FieldsByNumberMap; 340 typedef hash_map<EnumIntPair, const EnumValueDescriptor*, 341 PointerIntegerPairHash<EnumIntPair> > 342 EnumValuesByNumberMap; 343 // 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 345 // ordered data structure that implements lower_bound is convenient 346 // for that. 347 typedef map<DescriptorIntPair, const FieldDescriptor*> 348 ExtensionsGroupedByDescriptorMap; 349 typedef hash_map<string, const SourceCodeInfo_Location*> LocationsByPathMap; 350 351 set<string>* allowed_proto3_extendees_ = NULL; 352 GOOGLE_PROTOBUF_DECLARE_ONCE(allowed_proto3_extendees_init_); 353 354 void DeleteAllowedProto3Extendee() { 355 delete allowed_proto3_extendees_; 356 } 357 358 void InitAllowedProto3Extendee() { 359 allowed_proto3_extendees_ = new set<string>; 360 const char* kOptionNames[] = { 361 "FileOptions", "MessageOptions", "FieldOptions", "EnumOptions", 362 "EnumValueOptions", "ServiceOptions", "MethodOptions"}; 363 for (int i = 0; i < GOOGLE_ARRAYSIZE(kOptionNames); ++i) { 364 // descriptor.proto has a different package name in opensource. We allow 365 // both so the opensource protocol compiler can also compile internal 366 // proto3 files with custom options. See: b/27567912 367 allowed_proto3_extendees_->insert(string("google.protobuf.") + 368 kOptionNames[i]); 369 // Split the word to trick the opensource processing scripts so they 370 // will keep the origial package name. 371 allowed_proto3_extendees_->insert(string("proto") + "2." + kOptionNames[i]); 372 } 373 374 google::protobuf::internal::OnShutdown(&DeleteAllowedProto3Extendee); 375 } 376 377 // Checks whether the extendee type is allowed in proto3. 378 // Only extensions to descriptor options are allowed. We use name comparison 379 // instead of comparing the descriptor directly because the extensions may be 380 // defined in a different pool. 381 bool AllowedExtendeeInProto3(const string& name) { 382 ::google::protobuf::GoogleOnceInit(&allowed_proto3_extendees_init_, &InitAllowedProto3Extendee); 383 return allowed_proto3_extendees_->find(name) != 384 allowed_proto3_extendees_->end(); 385 } 386 387 } // anonymous namespace 388 389 // =================================================================== 390 // DescriptorPool::Tables 391 392 class DescriptorPool::Tables { 393 public: 394 Tables(); 395 ~Tables(); 396 397 // Record the current state of the tables to the stack of checkpoints. 398 // Each call to AddCheckpoint() must be paired with exactly one call to either 399 // ClearLastCheckpoint() or RollbackToLastCheckpoint(). 400 // 401 // This is used when building files, since some kinds of validation errors 402 // cannot be detected until the file's descriptors have already been added to 403 // the tables. 404 // 405 // This supports recursive checkpoints, since building a file may trigger 406 // recursive building of other files. Note that recursive checkpoints are not 407 // normally necessary; explicit dependencies are built prior to checkpointing. 408 // So although we recursively build transitive imports, there is at most one 409 // checkpoint in the stack during dependency building. 410 // 411 // Recursive checkpoints only arise during cross-linking of the descriptors. 412 // Symbol references must be resolved, via DescriptorBuilder::FindSymbol and 413 // friends. If the pending file references an unknown symbol 414 // (e.g., it is not defined in the pending file's explicit dependencies), and 415 // the pool is using a fallback database, and that database contains a file 416 // defining that symbol, and that file has not yet been built by the pool, 417 // the pool builds the file during cross-linking, leading to another 418 // checkpoint. 419 void AddCheckpoint(); 420 421 // Mark the last checkpoint as having cleared successfully, removing it from 422 // the stack. If the stack is empty, all pending symbols will be committed. 423 // 424 // Note that this does not guarantee that the symbols added since the last 425 // checkpoint won't be rolled back: if a checkpoint gets rolled back, 426 // everything past that point gets rolled back, including symbols added after 427 // checkpoints that were pushed onto the stack after it and marked as cleared. 428 void ClearLastCheckpoint(); 429 430 // 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. 432 void RollbackToLastCheckpoint(); 433 434 // The stack of files which are currently being built. Used to detect 435 // cyclic dependencies when loading files from a DescriptorDatabase. Not 436 // used when fallback_database_ == NULL. 437 vector<string> pending_files_; 438 439 // 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 441 // 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. 443 // Not used when fallback_database_ == NULL. 444 hash_set<string> known_bad_files_; 445 446 // 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 448 // execution of the current public API call, but for compatibility with 449 // legacy clients, this is cleared at the beginning of each public API call. 450 hash_set<string> known_bad_symbols_; 451 452 // The set of descriptors for which we've already loaded the full 453 // set of extensions numbers from fallback_database_. 454 hash_set<const Descriptor*> extensions_loaded_from_db_; 455 456 // ----------------------------------------------------------------- 457 // Finding items. 458 459 // Find symbols. This returns a null Symbol (symbol.IsNull() is true) 460 // if not found. 461 inline Symbol FindSymbol(const string& key) const; 462 463 // This implements the body of DescriptorPool::Find*ByName(). It should 464 // really be a private method of DescriptorPool, but that would require 465 // declaring Symbol in descriptor.h, which would drag all kinds of other 466 // stuff into the header. Yay C++. 467 Symbol FindByNameHelper( 468 const DescriptorPool* pool, const string& name); 469 470 // These return NULL if not found. 471 inline const FileDescriptor* FindFile(const string& key) const; 472 inline const FieldDescriptor* FindExtension(const Descriptor* extendee, 473 int number); 474 inline void FindAllExtensions(const Descriptor* extendee, 475 vector<const FieldDescriptor*>* out) const; 476 477 // ----------------------------------------------------------------- 478 // Adding items. 479 480 // These add items to the corresponding tables. They return false if 481 // 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 483 // be used as a key in the symbols_by_name_ map without copying. 484 bool AddSymbol(const string& full_name, Symbol symbol); 485 bool AddFile(const FileDescriptor* file); 486 bool AddExtension(const FieldDescriptor* field); 487 488 // ----------------------------------------------------------------- 489 // Allocating memory. 490 491 // Allocate an object which will be reclaimed when the pool is 492 // destroyed. Note that the object's destructor will never be called, 493 // so its fields must be plain old data (primitive data types and 494 // pointers). All of the descriptor types are such objects. 495 template<typename Type> Type* Allocate(); 496 497 // Allocate an array of objects which will be reclaimed when the 498 // pool in destroyed. Again, destructors are never called. 499 template<typename Type> Type* AllocateArray(int count); 500 501 // Allocate a string which will be destroyed when the pool is destroyed. 502 // The string is initialized to the given value for convenience. 503 string* AllocateString(const string& value); 504 505 // Allocate a protocol message object. Some older versions of GCC have 506 // 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 508 // parameter instead of specifying the type explicitly. 509 template<typename Type> Type* AllocateMessage(Type* dummy = NULL); 510 511 // Allocate a FileDescriptorTables object. 512 FileDescriptorTables* AllocateFileTables(); 513 514 private: 515 vector<string*> strings_; // All strings in the pool. 516 vector<Message*> messages_; // All messages in the pool. 517 vector<FileDescriptorTables*> file_tables_; // All file tables in the pool. 518 vector<void*> allocations_; // All other memory allocated in the pool. 519 520 SymbolsByNameMap symbols_by_name_; 521 FilesByNameMap files_by_name_; 522 ExtensionsGroupedByDescriptorMap extensions_; 523 524 struct CheckPoint { 525 explicit CheckPoint(const Tables* tables) 526 : strings_before_checkpoint(tables->strings_.size()), 527 messages_before_checkpoint(tables->messages_.size()), 528 file_tables_before_checkpoint(tables->file_tables_.size()), 529 allocations_before_checkpoint(tables->allocations_.size()), 530 pending_symbols_before_checkpoint( 531 tables->symbols_after_checkpoint_.size()), 532 pending_files_before_checkpoint( 533 tables->files_after_checkpoint_.size()), 534 pending_extensions_before_checkpoint( 535 tables->extensions_after_checkpoint_.size()) { 536 } 537 int strings_before_checkpoint; 538 int messages_before_checkpoint; 539 int file_tables_before_checkpoint; 540 int allocations_before_checkpoint; 541 int pending_symbols_before_checkpoint; 542 int pending_files_before_checkpoint; 543 int pending_extensions_before_checkpoint; 544 }; 545 vector<CheckPoint> checkpoints_; 546 vector<const char* > symbols_after_checkpoint_; 547 vector<const char* > files_after_checkpoint_; 548 vector<DescriptorIntPair> extensions_after_checkpoint_; 549 550 // Allocate some bytes which will be reclaimed when the pool is 551 // destroyed. 552 void* AllocateBytes(int size); 553 }; 554 555 // Contains tables specific to a particular file. These tables are not 556 // 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 558 // contents of a single file -- e.g. Descriptor::FindFieldByName() -- 559 // lock-free. 560 // 561 // For historical reasons, the definitions of the methods of 562 // FileDescriptorTables and DescriptorPool::Tables are interleaved below. 563 // These used to be a single class. 564 class FileDescriptorTables { 565 public: 566 FileDescriptorTables(); 567 ~FileDescriptorTables(); 568 569 // Empty table, used with placeholder files. 570 inline static const FileDescriptorTables& GetEmptyInstance(); 571 572 // ----------------------------------------------------------------- 573 // Finding items. 574 575 // Find symbols. These return a null Symbol (symbol.IsNull() is true) 576 // if not found. 577 inline Symbol FindNestedSymbol(const void* parent, 578 const string& name) const; 579 inline Symbol FindNestedSymbolOfType(const void* parent, 580 const string& name, 581 const Symbol::Type type) const; 582 583 // These return NULL if not found. 584 inline const FieldDescriptor* FindFieldByNumber( 585 const Descriptor* parent, int number) const; 586 inline const FieldDescriptor* FindFieldByLowercaseName( 587 const void* parent, const string& lowercase_name) const; 588 inline const FieldDescriptor* FindFieldByCamelcaseName( 589 const void* parent, const string& camelcase_name) const; 590 inline const EnumValueDescriptor* FindEnumValueByNumber( 591 const EnumDescriptor* parent, int number) const; 592 // This creates a new EnumValueDescriptor if not found, in a thread-safe way. 593 inline const EnumValueDescriptor* FindEnumValueByNumberCreatingIfUnknown( 594 const EnumDescriptor* parent, int number) const; 595 596 // ----------------------------------------------------------------- 597 // Adding items. 598 599 // These add items to the corresponding tables. They return false if 600 // the key already exists in the table. For AddAliasUnderParent(), the 601 // string passed in must be one that was constructed using AllocateString(), 602 // as it will be used as a key in the symbols_by_parent_ map without copying. 603 bool AddAliasUnderParent(const void* parent, const string& name, 604 Symbol symbol); 605 bool AddFieldByNumber(const FieldDescriptor* field); 606 bool AddEnumValueByNumber(const EnumValueDescriptor* value); 607 608 // 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. 610 void AddFieldByStylizedNames(const FieldDescriptor* field); 611 612 // Populates p->first->locations_by_path_ from p->second. 613 // Unusual signature dictated by GoogleOnceDynamic. 614 static void BuildLocationsByPath( 615 pair<const FileDescriptorTables*, const SourceCodeInfo*>* p); 616 617 // Returns the location denoted by the specified path through info, 618 // or NULL if not found. 619 // The value of info must be that of the corresponding FileDescriptor. 620 // (Conceptually a pure function, but stateful as an optimisation.) 621 const SourceCodeInfo_Location* GetSourceLocation( 622 const vector<int>& path, const SourceCodeInfo* info) const; 623 624 private: 625 SymbolsByParentMap symbols_by_parent_; 626 FieldsByNameMap fields_by_lowercase_name_; 627 FieldsByNameMap fields_by_camelcase_name_; 628 FieldsByNumberMap fields_by_number_; // Not including extensions. 629 EnumValuesByNumberMap enum_values_by_number_; 630 mutable EnumValuesByNumberMap unknown_enum_values_by_number_ 631 GOOGLE_GUARDED_BY(unknown_enum_values_mu_); 632 633 // Populated on first request to save space, hence constness games. 634 mutable GoogleOnceDynamic locations_by_path_once_; 635 mutable LocationsByPathMap locations_by_path_; 636 637 // Mutex to protect the unknown-enum-value map due to dynamic 638 // EnumValueDescriptor creation on unknown values. 639 mutable Mutex unknown_enum_values_mu_; 640 }; 641 642 DescriptorPool::Tables::Tables() 643 // Start some hash_map and hash_set objects with a small # of buckets 644 : known_bad_files_(3), 645 known_bad_symbols_(3), 646 extensions_loaded_from_db_(3), 647 symbols_by_name_(3), 648 files_by_name_(3) {} 649 650 651 DescriptorPool::Tables::~Tables() { 652 GOOGLE_DCHECK(checkpoints_.empty()); 653 // Note that the deletion order is important, since the destructors of some 654 // messages may refer to objects in allocations_. 655 STLDeleteElements(&messages_); 656 for (int i = 0; i < allocations_.size(); i++) { 657 operator delete(allocations_[i]); 658 } 659 STLDeleteElements(&strings_); 660 STLDeleteElements(&file_tables_); 661 } 662 663 FileDescriptorTables::FileDescriptorTables() 664 // Initialize all the hash tables to start out with a small # of buckets 665 : symbols_by_parent_(3), 666 fields_by_lowercase_name_(3), 667 fields_by_camelcase_name_(3), 668 fields_by_number_(3), 669 enum_values_by_number_(3), 670 unknown_enum_values_by_number_(3) { 671 } 672 673 FileDescriptorTables::~FileDescriptorTables() {} 674 675 namespace { 676 677 FileDescriptorTables* file_descriptor_tables_ = NULL; 678 GOOGLE_PROTOBUF_DECLARE_ONCE(file_descriptor_tables_once_init_); 679 680 void DeleteFileDescriptorTables() { 681 delete file_descriptor_tables_; 682 file_descriptor_tables_ = NULL; 683 } 684 685 void InitFileDescriptorTables() { 686 file_descriptor_tables_ = new FileDescriptorTables(); 687 internal::OnShutdown(&DeleteFileDescriptorTables); 688 } 689 690 inline void InitFileDescriptorTablesOnce() { 691 ::google::protobuf::GoogleOnceInit( 692 &file_descriptor_tables_once_init_, &InitFileDescriptorTables); 693 } 694 695 } // anonymous namespace 696 697 inline const FileDescriptorTables& FileDescriptorTables::GetEmptyInstance() { 698 InitFileDescriptorTablesOnce(); 699 return *file_descriptor_tables_; 700 } 701 702 void DescriptorPool::Tables::AddCheckpoint() { 703 checkpoints_.push_back(CheckPoint(this)); 704 } 705 706 void DescriptorPool::Tables::ClearLastCheckpoint() { 707 GOOGLE_DCHECK(!checkpoints_.empty()); 708 checkpoints_.pop_back(); 709 if (checkpoints_.empty()) { 710 // All checkpoints have been cleared: we can now commit all of the pending 711 // data. 712 symbols_after_checkpoint_.clear(); 713 files_after_checkpoint_.clear(); 714 extensions_after_checkpoint_.clear(); 715 } 716 } 717 718 void DescriptorPool::Tables::RollbackToLastCheckpoint() { 719 GOOGLE_DCHECK(!checkpoints_.empty()); 720 const CheckPoint& checkpoint = checkpoints_.back(); 721 722 for (int i = checkpoint.pending_symbols_before_checkpoint; 723 i < symbols_after_checkpoint_.size(); 724 i++) { 725 symbols_by_name_.erase(symbols_after_checkpoint_[i]); 726 } 727 for (int i = checkpoint.pending_files_before_checkpoint; 728 i < files_after_checkpoint_.size(); 729 i++) { 730 files_by_name_.erase(files_after_checkpoint_[i]); 731 } 732 for (int i = checkpoint.pending_extensions_before_checkpoint; 733 i < extensions_after_checkpoint_.size(); 734 i++) { 735 extensions_.erase(extensions_after_checkpoint_[i]); 736 } 737 738 symbols_after_checkpoint_.resize( 739 checkpoint.pending_symbols_before_checkpoint); 740 files_after_checkpoint_.resize(checkpoint.pending_files_before_checkpoint); 741 extensions_after_checkpoint_.resize( 742 checkpoint.pending_extensions_before_checkpoint); 743 744 STLDeleteContainerPointers( 745 strings_.begin() + checkpoint.strings_before_checkpoint, strings_.end()); 746 STLDeleteContainerPointers( 747 messages_.begin() + checkpoint.messages_before_checkpoint, 748 messages_.end()); 749 STLDeleteContainerPointers( 750 file_tables_.begin() + checkpoint.file_tables_before_checkpoint, 751 file_tables_.end()); 752 for (int i = checkpoint.allocations_before_checkpoint; 753 i < allocations_.size(); 754 i++) { 755 operator delete(allocations_[i]); 756 } 757 758 strings_.resize(checkpoint.strings_before_checkpoint); 759 messages_.resize(checkpoint.messages_before_checkpoint); 760 file_tables_.resize(checkpoint.file_tables_before_checkpoint); 761 allocations_.resize(checkpoint.allocations_before_checkpoint); 762 checkpoints_.pop_back(); 763 } 764 765 // ------------------------------------------------------------------- 766 767 inline Symbol DescriptorPool::Tables::FindSymbol(const string& key) const { 768 const Symbol* result = FindOrNull(symbols_by_name_, key.c_str()); 769 if (result == NULL) { 770 return kNullSymbol; 771 } else { 772 return *result; 773 } 774 } 775 776 inline Symbol FileDescriptorTables::FindNestedSymbol( 777 const void* parent, const string& name) const { 778 const Symbol* result = 779 FindOrNull(symbols_by_parent_, PointerStringPair(parent, name.c_str())); 780 if (result == NULL) { 781 return kNullSymbol; 782 } else { 783 return *result; 784 } 785 } 786 787 inline Symbol FileDescriptorTables::FindNestedSymbolOfType( 788 const void* parent, const string& name, const Symbol::Type type) const { 789 Symbol result = FindNestedSymbol(parent, name); 790 if (result.type != type) return kNullSymbol; 791 return result; 792 } 793 794 Symbol DescriptorPool::Tables::FindByNameHelper( 795 const DescriptorPool* pool, const string& name) { 796 MutexLockMaybe lock(pool->mutex_); 797 known_bad_symbols_.clear(); 798 known_bad_files_.clear(); 799 Symbol result = FindSymbol(name); 800 801 if (result.IsNull() && pool->underlay_ != NULL) { 802 // Symbol not found; check the underlay. 803 result = 804 pool->underlay_->tables_->FindByNameHelper(pool->underlay_, name); 805 } 806 807 if (result.IsNull()) { 808 // Symbol still not found, so check fallback database. 809 if (pool->TryFindSymbolInFallbackDatabase(name)) { 810 result = FindSymbol(name); 811 } 812 } 813 814 return result; 815 } 816 817 inline const FileDescriptor* DescriptorPool::Tables::FindFile( 818 const string& key) const { 819 return FindPtrOrNull(files_by_name_, key.c_str()); 820 } 821 822 inline const FieldDescriptor* FileDescriptorTables::FindFieldByNumber( 823 const Descriptor* parent, int number) const { 824 return FindPtrOrNull(fields_by_number_, std::make_pair(parent, number)); 825 } 826 827 inline const FieldDescriptor* FileDescriptorTables::FindFieldByLowercaseName( 828 const void* parent, const string& lowercase_name) const { 829 return FindPtrOrNull(fields_by_lowercase_name_, 830 PointerStringPair(parent, lowercase_name.c_str())); 831 } 832 833 inline const FieldDescriptor* FileDescriptorTables::FindFieldByCamelcaseName( 834 const void* parent, const string& camelcase_name) const { 835 return FindPtrOrNull(fields_by_camelcase_name_, 836 PointerStringPair(parent, camelcase_name.c_str())); 837 } 838 839 inline const EnumValueDescriptor* FileDescriptorTables::FindEnumValueByNumber( 840 const EnumDescriptor* parent, int number) const { 841 return FindPtrOrNull(enum_values_by_number_, std::make_pair(parent, number)); 842 } 843 844 inline const EnumValueDescriptor* 845 FileDescriptorTables::FindEnumValueByNumberCreatingIfUnknown( 846 const EnumDescriptor* parent, int number) const { 847 // First try, with map of compiled-in values. 848 { 849 const EnumValueDescriptor* desc = 850 FindPtrOrNull(enum_values_by_number_, std::make_pair(parent, number)); 851 if (desc != NULL) { 852 return desc; 853 } 854 } 855 // Second try, with reader lock held on unknown enum values: common case. 856 { 857 ReaderMutexLock l(&unknown_enum_values_mu_); 858 const EnumValueDescriptor* desc = FindPtrOrNull( 859 unknown_enum_values_by_number_, std::make_pair(parent, number)); 860 if (desc != NULL) { 861 return desc; 862 } 863 } 864 // If not found, try again with writer lock held, and create new descriptor if 865 // necessary. 866 { 867 WriterMutexLock l(&unknown_enum_values_mu_); 868 const EnumValueDescriptor* desc = FindPtrOrNull( 869 unknown_enum_values_by_number_, std::make_pair(parent, number)); 870 if (desc != NULL) { 871 return desc; 872 } 873 874 // Create an EnumValueDescriptor dynamically. We don't insert it into the 875 // EnumDescriptor (it's not a part of the enum as originally defined), but 876 // we do insert it into the table so that we can return the same pointer 877 // later. 878 string enum_value_name = StringPrintf( 879 "UNKNOWN_ENUM_VALUE_%s_%d", parent->name().c_str(), number); 880 DescriptorPool::Tables* tables = 881 const_cast<DescriptorPool::Tables*>(DescriptorPool::generated_pool()-> 882 tables_.get()); 883 EnumValueDescriptor* result = tables->Allocate<EnumValueDescriptor>(); 884 result->name_ = tables->AllocateString(enum_value_name); 885 result->full_name_ = tables->AllocateString(parent->full_name() + 886 "." + enum_value_name); 887 result->number_ = number; 888 result->type_ = parent; 889 result->options_ = &EnumValueOptions::default_instance(); 890 InsertIfNotPresent(&unknown_enum_values_by_number_, 891 std::make_pair(parent, number), result); 892 return result; 893 } 894 } 895 896 897 inline const FieldDescriptor* DescriptorPool::Tables::FindExtension( 898 const Descriptor* extendee, int number) { 899 return FindPtrOrNull(extensions_, std::make_pair(extendee, number)); 900 } 901 902 inline void DescriptorPool::Tables::FindAllExtensions( 903 const Descriptor* extendee, vector<const FieldDescriptor*>* out) const { 904 ExtensionsGroupedByDescriptorMap::const_iterator it = 905 extensions_.lower_bound(std::make_pair(extendee, 0)); 906 for (; it != extensions_.end() && it->first.first == extendee; ++it) { 907 out->push_back(it->second); 908 } 909 } 910 911 // ------------------------------------------------------------------- 912 913 bool DescriptorPool::Tables::AddSymbol( 914 const string& full_name, Symbol symbol) { 915 if (InsertIfNotPresent(&symbols_by_name_, full_name.c_str(), symbol)) { 916 symbols_after_checkpoint_.push_back(full_name.c_str()); 917 return true; 918 } else { 919 return false; 920 } 921 } 922 923 bool FileDescriptorTables::AddAliasUnderParent( 924 const void* parent, const string& name, Symbol symbol) { 925 PointerStringPair by_parent_key(parent, name.c_str()); 926 return InsertIfNotPresent(&symbols_by_parent_, by_parent_key, symbol); 927 } 928 929 bool DescriptorPool::Tables::AddFile(const FileDescriptor* file) { 930 if (InsertIfNotPresent(&files_by_name_, file->name().c_str(), file)) { 931 files_after_checkpoint_.push_back(file->name().c_str()); 932 return true; 933 } else { 934 return false; 935 } 936 } 937 938 void FileDescriptorTables::AddFieldByStylizedNames( 939 const FieldDescriptor* field) { 940 const void* parent; 941 if (field->is_extension()) { 942 if (field->extension_scope() == NULL) { 943 parent = field->file(); 944 } else { 945 parent = field->extension_scope(); 946 } 947 } else { 948 parent = field->containing_type(); 949 } 950 951 PointerStringPair lowercase_key(parent, field->lowercase_name().c_str()); 952 InsertIfNotPresent(&fields_by_lowercase_name_, lowercase_key, field); 953 954 PointerStringPair camelcase_key(parent, field->camelcase_name().c_str()); 955 InsertIfNotPresent(&fields_by_camelcase_name_, camelcase_key, field); 956 } 957 958 bool FileDescriptorTables::AddFieldByNumber(const FieldDescriptor* field) { 959 DescriptorIntPair key(field->containing_type(), field->number()); 960 return InsertIfNotPresent(&fields_by_number_, key, field); 961 } 962 963 bool FileDescriptorTables::AddEnumValueByNumber( 964 const EnumValueDescriptor* value) { 965 EnumIntPair key(value->type(), value->number()); 966 return InsertIfNotPresent(&enum_values_by_number_, key, value); 967 } 968 969 bool DescriptorPool::Tables::AddExtension(const FieldDescriptor* field) { 970 DescriptorIntPair key(field->containing_type(), field->number()); 971 if (InsertIfNotPresent(&extensions_, key, field)) { 972 extensions_after_checkpoint_.push_back(key); 973 return true; 974 } else { 975 return false; 976 } 977 } 978 979 // ------------------------------------------------------------------- 980 981 template<typename Type> 982 Type* DescriptorPool::Tables::Allocate() { 983 return reinterpret_cast<Type*>(AllocateBytes(sizeof(Type))); 984 } 985 986 template<typename Type> 987 Type* DescriptorPool::Tables::AllocateArray(int count) { 988 return reinterpret_cast<Type*>(AllocateBytes(sizeof(Type) * count)); 989 } 990 991 string* DescriptorPool::Tables::AllocateString(const string& value) { 992 string* result = new string(value); 993 strings_.push_back(result); 994 return result; 995 } 996 997 template<typename Type> 998 Type* DescriptorPool::Tables::AllocateMessage(Type* /* dummy */) { 999 Type* result = new Type; 1000 messages_.push_back(result); 1001 return result; 1002 } 1003 1004 FileDescriptorTables* DescriptorPool::Tables::AllocateFileTables() { 1005 FileDescriptorTables* result = new FileDescriptorTables; 1006 file_tables_.push_back(result); 1007 return result; 1008 } 1009 1010 void* DescriptorPool::Tables::AllocateBytes(int size) { 1011 // TODO(kenton): Would it be worthwhile to implement this in some more 1012 // sophisticated way? Probably not for the open source release, but for 1013 // internal use we could easily plug in one of our existing memory pool 1014 // allocators... 1015 if (size == 0) return NULL; 1016 1017 void* result = operator new(size); 1018 allocations_.push_back(result); 1019 return result; 1020 } 1021 1022 void FileDescriptorTables::BuildLocationsByPath( 1023 pair<const FileDescriptorTables*, const SourceCodeInfo*>* p) { 1024 for (int i = 0, len = p->second->location_size(); i < len; ++i) { 1025 const SourceCodeInfo_Location* loc = &p->second->location().Get(i); 1026 p->first->locations_by_path_[Join(loc->path(), ",")] = loc; 1027 } 1028 } 1029 1030 const SourceCodeInfo_Location* FileDescriptorTables::GetSourceLocation( 1031 const vector<int>& path, const SourceCodeInfo* info) const { 1032 pair<const FileDescriptorTables*, const SourceCodeInfo*> p( 1033 std::make_pair(this, info)); 1034 locations_by_path_once_.Init(&FileDescriptorTables::BuildLocationsByPath, &p); 1035 return FindPtrOrNull(locations_by_path_, Join(path, ",")); 1036 } 1037 1038 // =================================================================== 1039 // DescriptorPool 1040 1041 DescriptorPool::ErrorCollector::~ErrorCollector() {} 1042 1043 DescriptorPool::DescriptorPool() 1044 : mutex_(NULL), 1045 fallback_database_(NULL), 1046 default_error_collector_(NULL), 1047 underlay_(NULL), 1048 tables_(new Tables), 1049 enforce_dependencies_(true), 1050 allow_unknown_(false), 1051 enforce_weak_(false) {} 1052 1053 DescriptorPool::DescriptorPool(DescriptorDatabase* fallback_database, 1054 ErrorCollector* error_collector) 1055 : mutex_(new Mutex), 1056 fallback_database_(fallback_database), 1057 default_error_collector_(error_collector), 1058 underlay_(NULL), 1059 tables_(new Tables), 1060 enforce_dependencies_(true), 1061 allow_unknown_(false), 1062 enforce_weak_(false) { 1063 } 1064 1065 DescriptorPool::DescriptorPool(const DescriptorPool* underlay) 1066 : mutex_(NULL), 1067 fallback_database_(NULL), 1068 default_error_collector_(NULL), 1069 underlay_(underlay), 1070 tables_(new Tables), 1071 enforce_dependencies_(true), 1072 allow_unknown_(false), 1073 enforce_weak_(false) {} 1074 1075 DescriptorPool::~DescriptorPool() { 1076 if (mutex_ != NULL) delete mutex_; 1077 } 1078 1079 // DescriptorPool::BuildFile() defined later. 1080 // DescriptorPool::BuildFileCollectingErrors() defined later. 1081 1082 void DescriptorPool::InternalDontEnforceDependencies() { 1083 enforce_dependencies_ = false; 1084 } 1085 1086 void DescriptorPool::AddUnusedImportTrackFile(const string& file_name) { 1087 unused_import_track_files_.insert(file_name); 1088 } 1089 1090 void DescriptorPool::ClearUnusedImportTrackFiles() { 1091 unused_import_track_files_.clear(); 1092 } 1093 1094 bool DescriptorPool::InternalIsFileLoaded(const string& filename) const { 1095 MutexLockMaybe lock(mutex_); 1096 return tables_->FindFile(filename) != NULL; 1097 } 1098 1099 // generated_pool ==================================================== 1100 1101 namespace { 1102 1103 1104 EncodedDescriptorDatabase* generated_database_ = NULL; 1105 DescriptorPool* generated_pool_ = NULL; 1106 GOOGLE_PROTOBUF_DECLARE_ONCE(generated_pool_init_); 1107 1108 void DeleteGeneratedPool() { 1109 delete generated_database_; 1110 generated_database_ = NULL; 1111 delete generated_pool_; 1112 generated_pool_ = NULL; 1113 } 1114 1115 static void InitGeneratedPool() { 1116 generated_database_ = new EncodedDescriptorDatabase; 1117 generated_pool_ = new DescriptorPool(generated_database_); 1118 1119 internal::OnShutdown(&DeleteGeneratedPool); 1120 } 1121 1122 inline void InitGeneratedPoolOnce() { 1123 ::google::protobuf::GoogleOnceInit(&generated_pool_init_, &InitGeneratedPool); 1124 } 1125 1126 } // anonymous namespace 1127 1128 const DescriptorPool* DescriptorPool::generated_pool() { 1129 InitGeneratedPoolOnce(); 1130 return generated_pool_; 1131 } 1132 1133 1134 DescriptorPool* DescriptorPool::internal_generated_pool() { 1135 InitGeneratedPoolOnce(); 1136 return generated_pool_; 1137 } 1138 1139 void DescriptorPool::InternalAddGeneratedFile( 1140 const void* encoded_file_descriptor, int size) { 1141 // So, this function is called in the process of initializing the 1142 // descriptors for generated proto classes. Each generated .pb.cc file 1143 // has an internal procedure called AddDescriptors() which is called at 1144 // process startup, and that function calls this one in order to register 1145 // the raw bytes of the FileDescriptorProto representing the file. 1146 // 1147 // We do not actually construct the descriptor objects right away. We just 1148 // hang on to the bytes until they are actually needed. We actually construct 1149 // the descriptor the first time one of the following things happens: 1150 // * Someone calls a method like descriptor(), GetDescriptor(), or 1151 // GetReflection() on the generated types, which requires returning the 1152 // descriptor or an object based on it. 1153 // * Someone looks up the descriptor in DescriptorPool::generated_pool(). 1154 // 1155 // Once one of these happens, the DescriptorPool actually parses the 1156 // FileDescriptorProto and generates a FileDescriptor (and all its children) 1157 // based on it. 1158 // 1159 // Note that FileDescriptorProto is itself a generated protocol message. 1160 // Therefore, when we parse one, we have to be very careful to avoid using 1161 // any descriptor-based operations, since this might cause infinite recursion 1162 // or deadlock. 1163 InitGeneratedPoolOnce(); 1164 GOOGLE_CHECK(generated_database_->Add(encoded_file_descriptor, size)); 1165 } 1166 1167 1168 // Find*By* methods ================================================== 1169 1170 // TODO(kenton): There's a lot of repeated code here, but I'm not sure if 1171 // there's any good way to factor it out. Think about this some time when 1172 // there's nothing more important to do (read: never). 1173 1174 const FileDescriptor* DescriptorPool::FindFileByName(const string& name) const { 1175 MutexLockMaybe lock(mutex_); 1176 tables_->known_bad_symbols_.clear(); 1177 tables_->known_bad_files_.clear(); 1178 const FileDescriptor* result = tables_->FindFile(name); 1179 if (result != NULL) return result; 1180 if (underlay_ != NULL) { 1181 result = underlay_->FindFileByName(name); 1182 if (result != NULL) return result; 1183 } 1184 if (TryFindFileInFallbackDatabase(name)) { 1185 result = tables_->FindFile(name); 1186 if (result != NULL) return result; 1187 } 1188 return NULL; 1189 } 1190 1191 const FileDescriptor* DescriptorPool::FindFileContainingSymbol( 1192 const string& symbol_name) const { 1193 MutexLockMaybe lock(mutex_); 1194 tables_->known_bad_symbols_.clear(); 1195 tables_->known_bad_files_.clear(); 1196 Symbol result = tables_->FindSymbol(symbol_name); 1197 if (!result.IsNull()) return result.GetFile(); 1198 if (underlay_ != NULL) { 1199 const FileDescriptor* file_result = 1200 underlay_->FindFileContainingSymbol(symbol_name); 1201 if (file_result != NULL) return file_result; 1202 } 1203 if (TryFindSymbolInFallbackDatabase(symbol_name)) { 1204 result = tables_->FindSymbol(symbol_name); 1205 if (!result.IsNull()) return result.GetFile(); 1206 } 1207 return NULL; 1208 } 1209 1210 const Descriptor* DescriptorPool::FindMessageTypeByName( 1211 const string& name) const { 1212 Symbol result = tables_->FindByNameHelper(this, name); 1213 return (result.type == Symbol::MESSAGE) ? result.descriptor : NULL; 1214 } 1215 1216 const FieldDescriptor* DescriptorPool::FindFieldByName( 1217 const string& name) const { 1218 Symbol result = tables_->FindByNameHelper(this, name); 1219 if (result.type == Symbol::FIELD && 1220 !result.field_descriptor->is_extension()) { 1221 return result.field_descriptor; 1222 } else { 1223 return NULL; 1224 } 1225 } 1226 1227 const FieldDescriptor* DescriptorPool::FindExtensionByName( 1228 const string& name) const { 1229 Symbol result = tables_->FindByNameHelper(this, name); 1230 if (result.type == Symbol::FIELD && 1231 result.field_descriptor->is_extension()) { 1232 return result.field_descriptor; 1233 } else { 1234 return NULL; 1235 } 1236 } 1237 1238 const OneofDescriptor* DescriptorPool::FindOneofByName( 1239 const string& name) const { 1240 Symbol result = tables_->FindByNameHelper(this, name); 1241 return (result.type == Symbol::ONEOF) ? result.oneof_descriptor : NULL; 1242 } 1243 1244 const EnumDescriptor* DescriptorPool::FindEnumTypeByName( 1245 const string& name) const { 1246 Symbol result = tables_->FindByNameHelper(this, name); 1247 return (result.type == Symbol::ENUM) ? result.enum_descriptor : NULL; 1248 } 1249 1250 const EnumValueDescriptor* DescriptorPool::FindEnumValueByName( 1251 const string& name) const { 1252 Symbol result = tables_->FindByNameHelper(this, name); 1253 return (result.type == Symbol::ENUM_VALUE) ? 1254 result.enum_value_descriptor : NULL; 1255 } 1256 1257 const ServiceDescriptor* DescriptorPool::FindServiceByName( 1258 const string& name) const { 1259 Symbol result = tables_->FindByNameHelper(this, name); 1260 return (result.type == Symbol::SERVICE) ? result.service_descriptor : NULL; 1261 } 1262 1263 const MethodDescriptor* DescriptorPool::FindMethodByName( 1264 const string& name) const { 1265 Symbol result = tables_->FindByNameHelper(this, name); 1266 return (result.type == Symbol::METHOD) ? result.method_descriptor : NULL; 1267 } 1268 1269 const FieldDescriptor* DescriptorPool::FindExtensionByNumber( 1270 const Descriptor* extendee, int number) const { 1271 MutexLockMaybe lock(mutex_); 1272 tables_->known_bad_symbols_.clear(); 1273 tables_->known_bad_files_.clear(); 1274 const FieldDescriptor* result = tables_->FindExtension(extendee, number); 1275 if (result != NULL) { 1276 return result; 1277 } 1278 if (underlay_ != NULL) { 1279 result = underlay_->FindExtensionByNumber(extendee, number); 1280 if (result != NULL) return result; 1281 } 1282 if (TryFindExtensionInFallbackDatabase(extendee, number)) { 1283 result = tables_->FindExtension(extendee, number); 1284 if (result != NULL) { 1285 return result; 1286 } 1287 } 1288 return NULL; 1289 } 1290 1291 void DescriptorPool::FindAllExtensions( 1292 const Descriptor* extendee, vector<const FieldDescriptor*>* out) const { 1293 MutexLockMaybe lock(mutex_); 1294 tables_->known_bad_symbols_.clear(); 1295 tables_->known_bad_files_.clear(); 1296 1297 // Initialize tables_->extensions_ from the fallback database first 1298 // (but do this only once per descriptor). 1299 if (fallback_database_ != NULL && 1300 tables_->extensions_loaded_from_db_.count(extendee) == 0) { 1301 vector<int> numbers; 1302 if (fallback_database_->FindAllExtensionNumbers(extendee->full_name(), 1303 &numbers)) { 1304 for (int i = 0; i < numbers.size(); ++i) { 1305 int number = numbers[i]; 1306 if (tables_->FindExtension(extendee, number) == NULL) { 1307 TryFindExtensionInFallbackDatabase(extendee, number); 1308 } 1309 } 1310 tables_->extensions_loaded_from_db_.insert(extendee); 1311 } 1312 } 1313 1314 tables_->FindAllExtensions(extendee, out); 1315 if (underlay_ != NULL) { 1316 underlay_->FindAllExtensions(extendee, out); 1317 } 1318 } 1319 1320 1321 // ------------------------------------------------------------------- 1322 1323 const FieldDescriptor* 1324 Descriptor::FindFieldByNumber(int key) const { 1325 const FieldDescriptor* result = 1326 file()->tables_->FindFieldByNumber(this, key); 1327 if (result == NULL || result->is_extension()) { 1328 return NULL; 1329 } else { 1330 return result; 1331 } 1332 } 1333 1334 const FieldDescriptor* 1335 Descriptor::FindFieldByLowercaseName(const string& key) const { 1336 const FieldDescriptor* result = 1337 file()->tables_->FindFieldByLowercaseName(this, key); 1338 if (result == NULL || result->is_extension()) { 1339 return NULL; 1340 } else { 1341 return result; 1342 } 1343 } 1344 1345 const FieldDescriptor* 1346 Descriptor::FindFieldByCamelcaseName(const string& key) const { 1347 const FieldDescriptor* result = 1348 file()->tables_->FindFieldByCamelcaseName(this, key); 1349 if (result == NULL || result->is_extension()) { 1350 return NULL; 1351 } else { 1352 return result; 1353 } 1354 } 1355 1356 const FieldDescriptor* 1357 Descriptor::FindFieldByName(const string& key) const { 1358 Symbol result = 1359 file()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD); 1360 if (!result.IsNull() && !result.field_descriptor->is_extension()) { 1361 return result.field_descriptor; 1362 } else { 1363 return NULL; 1364 } 1365 } 1366 1367 const OneofDescriptor* 1368 Descriptor::FindOneofByName(const string& key) const { 1369 Symbol result = 1370 file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ONEOF); 1371 if (!result.IsNull()) { 1372 return result.oneof_descriptor; 1373 } else { 1374 return NULL; 1375 } 1376 } 1377 1378 const FieldDescriptor* 1379 Descriptor::FindExtensionByName(const string& key) const { 1380 Symbol result = 1381 file()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD); 1382 if (!result.IsNull() && result.field_descriptor->is_extension()) { 1383 return result.field_descriptor; 1384 } else { 1385 return NULL; 1386 } 1387 } 1388 1389 const FieldDescriptor* 1390 Descriptor::FindExtensionByLowercaseName(const string& key) const { 1391 const FieldDescriptor* result = 1392 file()->tables_->FindFieldByLowercaseName(this, key); 1393 if (result == NULL || !result->is_extension()) { 1394 return NULL; 1395 } else { 1396 return result; 1397 } 1398 } 1399 1400 const FieldDescriptor* 1401 Descriptor::FindExtensionByCamelcaseName(const string& key) const { 1402 const FieldDescriptor* result = 1403 file()->tables_->FindFieldByCamelcaseName(this, key); 1404 if (result == NULL || !result->is_extension()) { 1405 return NULL; 1406 } else { 1407 return result; 1408 } 1409 } 1410 1411 const Descriptor* 1412 Descriptor::FindNestedTypeByName(const string& key) const { 1413 Symbol result = 1414 file()->tables_->FindNestedSymbolOfType(this, key, Symbol::MESSAGE); 1415 if (!result.IsNull()) { 1416 return result.descriptor; 1417 } else { 1418 return NULL; 1419 } 1420 } 1421 1422 const EnumDescriptor* 1423 Descriptor::FindEnumTypeByName(const string& key) const { 1424 Symbol result = 1425 file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM); 1426 if (!result.IsNull()) { 1427 return result.enum_descriptor; 1428 } else { 1429 return NULL; 1430 } 1431 } 1432 1433 const EnumValueDescriptor* 1434 Descriptor::FindEnumValueByName(const string& key) const { 1435 Symbol result = 1436 file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE); 1437 if (!result.IsNull()) { 1438 return result.enum_value_descriptor; 1439 } else { 1440 return NULL; 1441 } 1442 } 1443 1444 const EnumValueDescriptor* 1445 EnumDescriptor::FindValueByName(const string& key) const { 1446 Symbol result = 1447 file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE); 1448 if (!result.IsNull()) { 1449 return result.enum_value_descriptor; 1450 } else { 1451 return NULL; 1452 } 1453 } 1454 1455 const EnumValueDescriptor* 1456 EnumDescriptor::FindValueByNumber(int key) const { 1457 return file()->tables_->FindEnumValueByNumber(this, key); 1458 } 1459 1460 const EnumValueDescriptor* 1461 EnumDescriptor::FindValueByNumberCreatingIfUnknown(int key) const { 1462 return file()->tables_->FindEnumValueByNumberCreatingIfUnknown(this, key); 1463 } 1464 1465 const MethodDescriptor* 1466 ServiceDescriptor::FindMethodByName(const string& key) const { 1467 Symbol result = 1468 file()->tables_->FindNestedSymbolOfType(this, key, Symbol::METHOD); 1469 if (!result.IsNull()) { 1470 return result.method_descriptor; 1471 } else { 1472 return NULL; 1473 } 1474 } 1475 1476 const Descriptor* 1477 FileDescriptor::FindMessageTypeByName(const string& key) const { 1478 Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::MESSAGE); 1479 if (!result.IsNull()) { 1480 return result.descriptor; 1481 } else { 1482 return NULL; 1483 } 1484 } 1485 1486 const EnumDescriptor* 1487 FileDescriptor::FindEnumTypeByName(const string& key) const { 1488 Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM); 1489 if (!result.IsNull()) { 1490 return result.enum_descriptor; 1491 } else { 1492 return NULL; 1493 } 1494 } 1495 1496 const EnumValueDescriptor* 1497 FileDescriptor::FindEnumValueByName(const string& key) const { 1498 Symbol result = 1499 tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE); 1500 if (!result.IsNull()) { 1501 return result.enum_value_descriptor; 1502 } else { 1503 return NULL; 1504 } 1505 } 1506 1507 const ServiceDescriptor* 1508 FileDescriptor::FindServiceByName(const string& key) const { 1509 Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::SERVICE); 1510 if (!result.IsNull()) { 1511 return result.service_descriptor; 1512 } else { 1513 return NULL; 1514 } 1515 } 1516 1517 const FieldDescriptor* 1518 FileDescriptor::FindExtensionByName(const string& key) const { 1519 Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD); 1520 if (!result.IsNull() && result.field_descriptor->is_extension()) { 1521 return result.field_descriptor; 1522 } else { 1523 return NULL; 1524 } 1525 } 1526 1527 const FieldDescriptor* 1528 FileDescriptor::FindExtensionByLowercaseName(const string& key) const { 1529 const FieldDescriptor* result = tables_->FindFieldByLowercaseName(this, key); 1530 if (result == NULL || !result->is_extension()) { 1531 return NULL; 1532 } else { 1533 return result; 1534 } 1535 } 1536 1537 const FieldDescriptor* 1538 FileDescriptor::FindExtensionByCamelcaseName(const string& key) const { 1539 const FieldDescriptor* result = tables_->FindFieldByCamelcaseName(this, key); 1540 if (result == NULL || !result->is_extension()) { 1541 return NULL; 1542 } else { 1543 return result; 1544 } 1545 } 1546 1547 const Descriptor::ExtensionRange* 1548 Descriptor::FindExtensionRangeContainingNumber(int number) const { 1549 // Linear search should be fine because we don't expect a message to have 1550 // more than a couple extension ranges. 1551 for (int i = 0; i < extension_range_count(); i++) { 1552 if (number >= extension_range(i)->start && 1553 number < extension_range(i)->end) { 1554 return extension_range(i); 1555 } 1556 } 1557 return NULL; 1558 } 1559 1560 const Descriptor::ReservedRange* 1561 Descriptor::FindReservedRangeContainingNumber(int number) const { 1562 // TODO(chrisn): Consider a non-linear search. 1563 for (int i = 0; i < reserved_range_count(); i++) { 1564 if (number >= reserved_range(i)->start && 1565 number < reserved_range(i)->end) { 1566 return reserved_range(i); 1567 } 1568 } 1569 return NULL; 1570 } 1571 1572 // ------------------------------------------------------------------- 1573 1574 bool DescriptorPool::TryFindFileInFallbackDatabase(const string& name) const { 1575 if (fallback_database_ == NULL) return false; 1576 1577 if (tables_->known_bad_files_.count(name) > 0) return false; 1578 1579 FileDescriptorProto file_proto; 1580 if (!fallback_database_->FindFileByName(name, &file_proto) || 1581 BuildFileFromDatabase(file_proto) == NULL) { 1582 tables_->known_bad_files_.insert(name); 1583 return false; 1584 } 1585 return true; 1586 } 1587 1588 bool DescriptorPool::IsSubSymbolOfBuiltType(const string& name) const { 1589 string prefix = name; 1590 for (;;) { 1591 string::size_type dot_pos = prefix.find_last_of('.'); 1592 if (dot_pos == string::npos) { 1593 break; 1594 } 1595 prefix = prefix.substr(0, dot_pos); 1596 Symbol symbol = tables_->FindSymbol(prefix); 1597 // If the symbol type is anything other than PACKAGE, then its complete 1598 // definition is already known. 1599 if (!symbol.IsNull() && symbol.type != Symbol::PACKAGE) { 1600 return true; 1601 } 1602 } 1603 if (underlay_ != NULL) { 1604 // Check to see if any prefix of this symbol exists in the underlay. 1605 return underlay_->IsSubSymbolOfBuiltType(name); 1606 } 1607 return false; 1608 } 1609 1610 bool DescriptorPool::TryFindSymbolInFallbackDatabase(const string& name) const { 1611 if (fallback_database_ == NULL) return false; 1612 1613 if (tables_->known_bad_symbols_.count(name) > 0) return false; 1614 1615 FileDescriptorProto file_proto; 1616 if (// We skip looking in the fallback database if the name is a sub-symbol 1617 // of any descriptor that already exists in the descriptor pool (except 1618 // for package descriptors). This is valid because all symbols except 1619 // for packages are defined in a single file, so if the symbol exists 1620 // then we should already have its definition. 1621 // 1622 // The other reason to do this is to support "overriding" type 1623 // definitions by merging two databases that define the same type. (Yes, 1624 // people do this.) The main difficulty with making this work is that 1625 // FindFileContainingSymbol() is allowed to return both false positives 1626 // (e.g., SimpleDescriptorDatabase, UpgradedDescriptorDatabase) and false 1627 // negatives (e.g. ProtoFileParser, SourceTreeDescriptorDatabase). 1628 // When two such databases are merged, looking up a non-existent 1629 // sub-symbol of a type that already exists in the descriptor pool can 1630 // result in an attempt to load multiple definitions of the same type. 1631 // The check below avoids this. 1632 IsSubSymbolOfBuiltType(name) 1633 1634 // Look up file containing this symbol in fallback database. 1635 || !fallback_database_->FindFileContainingSymbol(name, &file_proto) 1636 1637 // Check if we've already built this file. If so, it apparently doesn't 1638 // contain the symbol we're looking for. Some DescriptorDatabases 1639 // return false positives. 1640 || tables_->FindFile(file_proto.name()) != NULL 1641 1642 // Build the file. 1643 || BuildFileFromDatabase(file_proto) == NULL) { 1644 tables_->known_bad_symbols_.insert(name); 1645 return false; 1646 } 1647 1648 return true; 1649 } 1650 1651 bool DescriptorPool::TryFindExtensionInFallbackDatabase( 1652 const Descriptor* containing_type, int field_number) const { 1653 if (fallback_database_ == NULL) return false; 1654 1655 FileDescriptorProto file_proto; 1656 if (!fallback_database_->FindFileContainingExtension( 1657 containing_type->full_name(), field_number, &file_proto)) { 1658 return false; 1659 } 1660 1661 if (tables_->FindFile(file_proto.name()) != NULL) { 1662 // We've already loaded this file, and it apparently doesn't contain the 1663 // extension we're looking for. Some DescriptorDatabases return false 1664 // positives. 1665 return false; 1666 } 1667 1668 if (BuildFileFromDatabase(file_proto) == NULL) { 1669 return false; 1670 } 1671 1672 return true; 1673 } 1674 1675 // =================================================================== 1676 1677 bool FieldDescriptor::is_map() const { 1678 return type() == TYPE_MESSAGE && message_type()->options().map_entry(); 1679 } 1680 1681 string FieldDescriptor::DefaultValueAsString(bool quote_string_type) const { 1682 GOOGLE_CHECK(has_default_value()) << "No default value"; 1683 switch (cpp_type()) { 1684 case CPPTYPE_INT32: 1685 return SimpleItoa(default_value_int32()); 1686 break; 1687 case CPPTYPE_INT64: 1688 return SimpleItoa(default_value_int64()); 1689 break; 1690 case CPPTYPE_UINT32: 1691 return SimpleItoa(default_value_uint32()); 1692 break; 1693 case CPPTYPE_UINT64: 1694 return SimpleItoa(default_value_uint64()); 1695 break; 1696 case CPPTYPE_FLOAT: 1697 return SimpleFtoa(default_value_float()); 1698 break; 1699 case CPPTYPE_DOUBLE: 1700 return SimpleDtoa(default_value_double()); 1701 break; 1702 case CPPTYPE_BOOL: 1703 return default_value_bool() ? "true" : "false"; 1704 break; 1705 case CPPTYPE_STRING: 1706 if (quote_string_type) { 1707 return "\"" + CEscape(default_value_string()) + "\""; 1708 } else { 1709 if (type() == TYPE_BYTES) { 1710 return CEscape(default_value_string()); 1711 } else { 1712 return default_value_string(); 1713 } 1714 } 1715 break; 1716 case CPPTYPE_ENUM: 1717 return default_value_enum()->name(); 1718 break; 1719 case CPPTYPE_MESSAGE: 1720 GOOGLE_LOG(DFATAL) << "Messages can't have default values!"; 1721 break; 1722 } 1723 GOOGLE_LOG(FATAL) << "Can't get here: failed to get default value as string"; 1724 return ""; 1725 } 1726 1727 // CopyTo methods ==================================================== 1728 1729 void FileDescriptor::CopyTo(FileDescriptorProto* proto) const { 1730 proto->set_name(name()); 1731 if (!package().empty()) proto->set_package(package()); 1732 // TODO(liujisi): Also populate when syntax="proto2". 1733 if (syntax() == SYNTAX_PROTO3) proto->set_syntax(SyntaxName(syntax())); 1734 1735 for (int i = 0; i < dependency_count(); i++) { 1736 proto->add_dependency(dependency(i)->name()); 1737 } 1738 1739 for (int i = 0; i < public_dependency_count(); i++) { 1740 proto->add_public_dependency(public_dependencies_[i]); 1741 } 1742 1743 for (int i = 0; i < weak_dependency_count(); i++) { 1744 proto->add_weak_dependency(weak_dependencies_[i]); 1745 } 1746 1747 for (int i = 0; i < message_type_count(); i++) { 1748 message_type(i)->CopyTo(proto->add_message_type()); 1749 } 1750 for (int i = 0; i < enum_type_count(); i++) { 1751 enum_type(i)->CopyTo(proto->add_enum_type()); 1752 } 1753 for (int i = 0; i < service_count(); i++) { 1754 service(i)->CopyTo(proto->add_service()); 1755 } 1756 for (int i = 0; i < extension_count(); i++) { 1757 extension(i)->CopyTo(proto->add_extension()); 1758 } 1759 1760 if (&options() != &FileOptions::default_instance()) { 1761 proto->mutable_options()->CopyFrom(options()); 1762 } 1763 } 1764 1765 void FileDescriptor::CopyJsonNameTo(FileDescriptorProto* proto) const { 1766 if (message_type_count() != proto->message_type_size() || 1767 extension_count() != proto->extension_size()) { 1768 GOOGLE_LOG(ERROR) << "Cannot copy json_name to a proto of a different size."; 1769 return; 1770 } 1771 for (int i = 0; i < message_type_count(); i++) { 1772 message_type(i)->CopyJsonNameTo(proto->mutable_message_type(i)); 1773 } 1774 for (int i = 0; i < extension_count(); i++) { 1775 extension(i)->CopyJsonNameTo(proto->mutable_extension(i)); 1776 } 1777 } 1778 1779 void FileDescriptor::CopySourceCodeInfoTo(FileDescriptorProto* proto) const { 1780 if (source_code_info_ && 1781 source_code_info_ != &SourceCodeInfo::default_instance()) { 1782 proto->mutable_source_code_info()->CopyFrom(*source_code_info_); 1783 } 1784 } 1785 1786 void Descriptor::CopyTo(DescriptorProto* proto) const { 1787 proto->set_name(name()); 1788 1789 for (int i = 0; i < field_count(); i++) { 1790 field(i)->CopyTo(proto->add_field()); 1791 } 1792 for (int i = 0; i < oneof_decl_count(); i++) { 1793 oneof_decl(i)->CopyTo(proto->add_oneof_decl()); 1794 } 1795 for (int i = 0; i < nested_type_count(); i++) { 1796 nested_type(i)->CopyTo(proto->add_nested_type()); 1797 } 1798 for (int i = 0; i < enum_type_count(); i++) { 1799 enum_type(i)->CopyTo(proto->add_enum_type()); 1800 } 1801 for (int i = 0; i < extension_range_count(); i++) { 1802 DescriptorProto::ExtensionRange* range = proto->add_extension_range(); 1803 range->set_start(extension_range(i)->start); 1804 range->set_end(extension_range(i)->end); 1805 } 1806 for (int i = 0; i < extension_count(); i++) { 1807 extension(i)->CopyTo(proto->add_extension()); 1808 } 1809 for (int i = 0; i < reserved_range_count(); i++) { 1810 DescriptorProto::ReservedRange* range = proto->add_reserved_range(); 1811 range->set_start(reserved_range(i)->start); 1812 range->set_end(reserved_range(i)->end); 1813 } 1814 for (int i = 0; i < reserved_name_count(); i++) { 1815 proto->add_reserved_name(reserved_name(i)); 1816 } 1817 1818 if (&options() != &MessageOptions::default_instance()) { 1819 proto->mutable_options()->CopyFrom(options()); 1820 } 1821 } 1822 1823 void Descriptor::CopyJsonNameTo(DescriptorProto* proto) const { 1824 if (field_count() != proto->field_size() || 1825 nested_type_count() != proto->nested_type_size() || 1826 extension_count() != proto->extension_size()) { 1827 GOOGLE_LOG(ERROR) << "Cannot copy json_name to a proto of a different size."; 1828 return; 1829 } 1830 for (int i = 0; i < field_count(); i++) { 1831 field(i)->CopyJsonNameTo(proto->mutable_field(i)); 1832 } 1833 for (int i = 0; i < nested_type_count(); i++) { 1834 nested_type(i)->CopyJsonNameTo(proto->mutable_nested_type(i)); 1835 } 1836 for (int i = 0; i < extension_count(); i++) { 1837 extension(i)->CopyJsonNameTo(proto->mutable_extension(i)); 1838 } 1839 } 1840 1841 void FieldDescriptor::CopyTo(FieldDescriptorProto* proto) const { 1842 proto->set_name(name()); 1843 proto->set_number(number()); 1844 if (has_json_name_) { 1845 proto->set_json_name(json_name()); 1846 } 1847 1848 // Some compilers do not allow static_cast directly between two enum types, 1849 // so we must cast to int first. 1850 proto->set_label(static_cast<FieldDescriptorProto::Label>( 1851 implicit_cast<int>(label()))); 1852 proto->set_type(static_cast<FieldDescriptorProto::Type>( 1853 implicit_cast<int>(type()))); 1854 1855 if (is_extension()) { 1856 if (!containing_type()->is_unqualified_placeholder_) { 1857 proto->set_extendee("."); 1858 } 1859 proto->mutable_extendee()->append(containing_type()->full_name()); 1860 } 1861 1862 if (cpp_type() == CPPTYPE_MESSAGE) { 1863 if (message_type()->is_placeholder_) { 1864 // We don't actually know if the type is a message type. It could be 1865 // an enum. 1866 proto->clear_type(); 1867 } 1868 1869 if (!message_type()->is_unqualified_placeholder_) { 1870 proto->set_type_name("."); 1871 } 1872 proto->mutable_type_name()->append(message_type()->full_name()); 1873 } else if (cpp_type() == CPPTYPE_ENUM) { 1874 if (!enum_type()->is_unqualified_placeholder_) { 1875 proto->set_type_name("."); 1876 } 1877 proto->mutable_type_name()->append(enum_type()->full_name()); 1878 } 1879 1880 if (has_default_value()) { 1881 proto->set_default_value(DefaultValueAsString(false)); 1882 } 1883 1884 if (containing_oneof() != NULL && !is_extension()) { 1885 proto->set_oneof_index(containing_oneof()->index()); 1886 } 1887 1888 if (&options() != &FieldOptions::default_instance()) { 1889 proto->mutable_options()->CopyFrom(options()); 1890 } 1891 } 1892 1893 void FieldDescriptor::CopyJsonNameTo(FieldDescriptorProto* proto) const { 1894 proto->set_json_name(json_name()); 1895 } 1896 1897 void OneofDescriptor::CopyTo(OneofDescriptorProto* proto) const { 1898 proto->set_name(name()); 1899 } 1900 1901 void EnumDescriptor::CopyTo(EnumDescriptorProto* proto) const { 1902 proto->set_name(name()); 1903 1904 for (int i = 0; i < value_count(); i++) { 1905 value(i)->CopyTo(proto->add_value()); 1906 } 1907 1908 if (&options() != &EnumOptions::default_instance()) { 1909 proto->mutable_options()->CopyFrom(options()); 1910 } 1911 } 1912 1913 void EnumValueDescriptor::CopyTo(EnumValueDescriptorProto* proto) const { 1914 proto->set_name(name()); 1915 proto->set_number(number()); 1916 1917 if (&options() != &EnumValueOptions::default_instance()) { 1918 proto->mutable_options()->CopyFrom(options()); 1919 } 1920 } 1921 1922 void ServiceDescriptor::CopyTo(ServiceDescriptorProto* proto) const { 1923 proto->set_name(name()); 1924 1925 for (int i = 0; i < method_count(); i++) { 1926 method(i)->CopyTo(proto->add_method()); 1927 } 1928 1929 if (&options() != &ServiceOptions::default_instance()) { 1930 proto->mutable_options()->CopyFrom(options()); 1931 } 1932 } 1933 1934 void MethodDescriptor::CopyTo(MethodDescriptorProto* proto) const { 1935 proto->set_name(name()); 1936 1937 if (!input_type()->is_unqualified_placeholder_) { 1938 proto->set_input_type("."); 1939 } 1940 proto->mutable_input_type()->append(input_type()->full_name()); 1941 1942 if (!output_type()->is_unqualified_placeholder_) { 1943 proto->set_output_type("."); 1944 } 1945 proto->mutable_output_type()->append(output_type()->full_name()); 1946 1947 if (&options() != &MethodOptions::default_instance()) { 1948 proto->mutable_options()->CopyFrom(options()); 1949 } 1950 1951 if (client_streaming_) { 1952 proto->set_client_streaming(true); 1953 } 1954 if (server_streaming_) { 1955 proto->set_server_streaming(true); 1956 } 1957 } 1958 1959 // DebugString methods =============================================== 1960 1961 namespace { 1962 1963 // Used by each of the option formatters. 1964 bool RetrieveOptions(int depth, 1965 const Message &options, 1966 vector<string> *option_entries) { 1967 option_entries->clear(); 1968 const Reflection* reflection = options.GetReflection(); 1969 vector<const FieldDescriptor*> fields; 1970 reflection->ListFields(options, &fields); 1971 for (int i = 0; i < fields.size(); i++) { 1972 int count = 1; 1973 bool repeated = false; 1974 if (fields[i]->is_repeated()) { 1975 count = reflection->FieldSize(options, fields[i]); 1976 repeated = true; 1977 } 1978 for (int j = 0; j < count; j++) { 1979 string fieldval; 1980 if (fields[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 1981 string tmp; 1982 TextFormat::Printer printer; 1983 printer.SetInitialIndentLevel(depth + 1); 1984 printer.PrintFieldValueToString(options, fields[i], 1985 repeated ? j : -1, &tmp); 1986 fieldval.append("{\n"); 1987 fieldval.append(tmp); 1988 fieldval.append(depth * 2, ' '); 1989 fieldval.append("}"); 1990 } else { 1991 TextFormat::PrintFieldValueToString(options, fields[i], 1992 repeated ? j : -1, &fieldval); 1993 } 1994 string name; 1995 if (fields[i]->is_extension()) { 1996 name = "(." + fields[i]->full_name() + ")"; 1997 } else { 1998 name = fields[i]->name(); 1999 } 2000 option_entries->push_back(name + " = " + fieldval); 2001 } 2002 } 2003 return !option_entries->empty(); 2004 } 2005 2006 // Formats options that all appear together in brackets. Does not include 2007 // brackets. 2008 bool FormatBracketedOptions(int depth, const Message &options, string *output) { 2009 vector<string> all_options; 2010 if (RetrieveOptions(depth, options, &all_options)) { 2011 output->append(Join(all_options, ", ")); 2012 } 2013 return !all_options.empty(); 2014 } 2015 2016 // Formats options one per line 2017 bool FormatLineOptions(int depth, const Message &options, string *output) { 2018 string prefix(depth * 2, ' '); 2019 vector<string> all_options; 2020 if (RetrieveOptions(depth, options, &all_options)) { 2021 for (int i = 0; i < all_options.size(); i++) { 2022 strings::SubstituteAndAppend(output, "$0option $1;\n", 2023 prefix, all_options[i]); 2024 } 2025 } 2026 return !all_options.empty(); 2027 } 2028 2029 class SourceLocationCommentPrinter { 2030 public: 2031 template<typename DescType> 2032 SourceLocationCommentPrinter(const DescType* desc, 2033 const string& prefix, 2034 const DebugStringOptions& options) 2035 : options_(options), prefix_(prefix) { 2036 // Perform the SourceLocation lookup only if we're including user comments, 2037 // because the lookup is fairly expensive. 2038 have_source_loc_ = options.include_comments && 2039 desc->GetSourceLocation(&source_loc_); 2040 } 2041 SourceLocationCommentPrinter(const FileDescriptor* file, 2042 const vector<int>& path, 2043 const string& prefix, 2044 const DebugStringOptions& options) 2045 : options_(options), prefix_(prefix) { 2046 // Perform the SourceLocation lookup only if we're including user comments, 2047 // because the lookup is fairly expensive. 2048 have_source_loc_ = options.include_comments && 2049 file->GetSourceLocation(path, &source_loc_); 2050 } 2051 void AddPreComment(string* output) { 2052 if (have_source_loc_) { 2053 // Detached leading comments. 2054 for (int i = 0 ; i < source_loc_.leading_detached_comments.size(); ++i) { 2055 *output += FormatComment(source_loc_.leading_detached_comments[i]); 2056 *output += "\n"; 2057 } 2058 // Attached leading comments. 2059 if (!source_loc_.leading_comments.empty()) { 2060 *output += FormatComment(source_loc_.leading_comments); 2061 } 2062 } 2063 } 2064 void AddPostComment(string* output) { 2065 if (have_source_loc_ && source_loc_.trailing_comments.size() > 0) { 2066 *output += FormatComment(source_loc_.trailing_comments); 2067 } 2068 } 2069 2070 // Format comment such that each line becomes a full-line C++-style comment in 2071 // the DebugString() output. 2072 string FormatComment(const string& comment_text) { 2073 string stripped_comment = comment_text; 2074 StripWhitespace(&stripped_comment); 2075 vector<string> lines = Split(stripped_comment, "\n"); 2076 string output; 2077 for (int i = 0; i < lines.size(); ++i) { 2078 const string& line = lines[i]; 2079 strings::SubstituteAndAppend(&output, "$0// $1\n", prefix_, line); 2080 } 2081 return output; 2082 } 2083 2084 private: 2085 2086 bool have_source_loc_; 2087 SourceLocation source_loc_; 2088 DebugStringOptions options_; 2089 string prefix_; 2090 }; 2091 2092 } // anonymous namespace 2093 2094 string FileDescriptor::DebugString() const { 2095 DebugStringOptions options; // default options 2096 return DebugStringWithOptions(options); 2097 } 2098 2099 string FileDescriptor::DebugStringWithOptions( 2100 const DebugStringOptions& debug_string_options) const { 2101 string contents; 2102 { 2103 vector<int> path; 2104 path.push_back(FileDescriptorProto::kSyntaxFieldNumber); 2105 SourceLocationCommentPrinter syntax_comment( 2106 this, path, "", debug_string_options); 2107 syntax_comment.AddPreComment(&contents); 2108 strings::SubstituteAndAppend(&contents, "syntax = \"$0\";\n\n", 2109 SyntaxName(syntax())); 2110 syntax_comment.AddPostComment(&contents); 2111 } 2112 2113 SourceLocationCommentPrinter 2114 comment_printer(this, "", debug_string_options); 2115 comment_printer.AddPreComment(&contents); 2116 2117 set<int> public_dependencies; 2118 set<int> weak_dependencies; 2119 public_dependencies.insert(public_dependencies_, 2120 public_dependencies_ + public_dependency_count_); 2121 weak_dependencies.insert(weak_dependencies_, 2122 weak_dependencies_ + weak_dependency_count_); 2123 2124 for (int i = 0; i < dependency_count(); i++) { 2125 if (public_dependencies.count(i) > 0) { 2126 strings::SubstituteAndAppend(&contents, "import public \"$0\";\n", 2127 dependency(i)->name()); 2128 } else if (weak_dependencies.count(i) > 0) { 2129 strings::SubstituteAndAppend(&contents, "import weak \"$0\";\n", 2130 dependency(i)->name()); 2131 } else { 2132 strings::SubstituteAndAppend(&contents, "import \"$0\";\n", 2133 dependency(i)->name()); 2134 } 2135 } 2136 2137 if (!package().empty()) { 2138 vector<int> path; 2139 path.push_back(FileDescriptorProto::kPackageFieldNumber); 2140 SourceLocationCommentPrinter package_comment( 2141 this, path, "", debug_string_options); 2142 package_comment.AddPreComment(&contents); 2143 strings::SubstituteAndAppend(&contents, "package $0;\n\n", package()); 2144 package_comment.AddPostComment(&contents); 2145 } 2146 2147 if (FormatLineOptions(0, options(), &contents)) { 2148 contents.append("\n"); // add some space if we had options 2149 } 2150 2151 for (int i = 0; i < enum_type_count(); i++) { 2152 enum_type(i)->DebugString(0, &contents, debug_string_options); 2153 contents.append("\n"); 2154 } 2155 2156 // Find all the 'group' type extensions; we will not output their nested 2157 // definitions (those will be done with their group field descriptor). 2158 set<const Descriptor*> groups; 2159 for (int i = 0; i < extension_count(); i++) { 2160 if (extension(i)->type() == FieldDescriptor::TYPE_GROUP) { 2161 groups.insert(extension(i)->message_type()); 2162 } 2163 } 2164 2165 for (int i = 0; i < message_type_count(); i++) { 2166 if (groups.count(message_type(i)) == 0) { 2167 message_type(i)->DebugString(0, &contents, debug_string_options, 2168 /* include_opening_clause */ true); 2169 contents.append("\n"); 2170 } 2171 } 2172 2173 for (int i = 0; i < service_count(); i++) { 2174 service(i)->DebugString(&contents, debug_string_options); 2175 contents.append("\n"); 2176 } 2177 2178 const Descriptor* containing_type = NULL; 2179 for (int i = 0; i < extension_count(); i++) { 2180 if (extension(i)->containing_type() != containing_type) { 2181 if (i > 0) contents.append("}\n\n"); 2182 containing_type = extension(i)->containing_type(); 2183 strings::SubstituteAndAppend(&contents, "extend .$0 {\n", 2184 containing_type->full_name()); 2185 } 2186 extension(i)->DebugString(1, FieldDescriptor::PRINT_LABEL, &contents, 2187 debug_string_options); 2188 } 2189 if (extension_count() > 0) contents.append("}\n\n"); 2190 2191 comment_printer.AddPostComment(&contents); 2192 2193 return contents; 2194 } 2195 2196 string Descriptor::DebugString() const { 2197 DebugStringOptions options; // default options 2198 return DebugStringWithOptions(options); 2199 } 2200 2201 string Descriptor::DebugStringWithOptions( 2202 const DebugStringOptions& options) const { 2203 string contents; 2204 DebugString(0, &contents, options, /* include_opening_clause */ true); 2205 return contents; 2206 } 2207 2208 void Descriptor::DebugString(int depth, string *contents, 2209 const DebugStringOptions& 2210 debug_string_options, 2211 bool include_opening_clause) const { 2212 if (options().map_entry()) { 2213 // Do not generate debug string for auto-generated map-entry type. 2214 return; 2215 } 2216 string prefix(depth * 2, ' '); 2217 ++depth; 2218 2219 SourceLocationCommentPrinter 2220 comment_printer(this, prefix, debug_string_options); 2221 comment_printer.AddPreComment(contents); 2222 2223 if (include_opening_clause) { 2224 strings::SubstituteAndAppend(contents, "$0message $1", prefix, name()); 2225 } 2226 contents->append(" {\n"); 2227 2228 FormatLineOptions(depth, options(), contents); 2229 2230 // 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 2232 // descriptor). 2233 set<const Descriptor*> groups; 2234 for (int i = 0; i < field_count(); i++) { 2235 if (field(i)->type() == FieldDescriptor::TYPE_GROUP) { 2236 groups.insert(field(i)->message_type()); 2237 } 2238 } 2239 for (int i = 0; i < extension_count(); i++) { 2240 if (extension(i)->type() == FieldDescriptor::TYPE_GROUP) { 2241 groups.insert(extension(i)->message_type()); 2242 } 2243 } 2244 2245 for (int i = 0; i < nested_type_count(); i++) { 2246 if (groups.count(nested_type(i)) == 0) { 2247 nested_type(i)->DebugString(depth, contents, debug_string_options, 2248 /* include_opening_clause */ true); 2249 } 2250 } 2251 for (int i = 0; i < enum_type_count(); i++) { 2252 enum_type(i)->DebugString(depth, contents, debug_string_options); 2253 } 2254 for (int i = 0; i < field_count(); i++) { 2255 if (field(i)->containing_oneof() == NULL) { 2256 field(i)->DebugString(depth, FieldDescriptor::PRINT_LABEL, contents, 2257 debug_string_options); 2258 } else if (field(i)->containing_oneof()->field(0) == field(i)) { 2259 // This is the first field in this oneof, so print the whole oneof. 2260 field(i)->containing_oneof()->DebugString(depth, contents, 2261 debug_string_options); 2262 } 2263 } 2264 2265 for (int i = 0; i < extension_range_count(); i++) { 2266 strings::SubstituteAndAppend(contents, "$0 extensions $1 to $2;\n", 2267 prefix, 2268 extension_range(i)->start, 2269 extension_range(i)->end - 1); 2270 } 2271 2272 // Group extensions by what they extend, so they can be printed out together. 2273 const Descriptor* containing_type = NULL; 2274 for (int i = 0; i < extension_count(); i++) { 2275 if (extension(i)->containing_type() != containing_type) { 2276 if (i > 0) strings::SubstituteAndAppend(contents, "$0 }\n", prefix); 2277 containing_type = extension(i)->containing_type(); 2278 strings::SubstituteAndAppend(contents, "$0 extend .$1 {\n", 2279 prefix, containing_type->full_name()); 2280 } 2281 extension(i)->DebugString( 2282 depth + 1, FieldDescriptor::PRINT_LABEL, contents, 2283 debug_string_options); 2284 } 2285 if (extension_count() > 0) 2286 strings::SubstituteAndAppend(contents, "$0 }\n", prefix); 2287 2288 if (reserved_range_count() > 0) { 2289 strings::SubstituteAndAppend(contents, "$0 reserved ", prefix); 2290 for (int i = 0; i < reserved_range_count(); i++) { 2291 const Descriptor::ReservedRange* range = reserved_range(i); 2292 if (range->end == range->start + 1) { 2293 strings::SubstituteAndAppend(contents, "$0, ", range->start); 2294 } else { 2295 strings::SubstituteAndAppend(contents, "$0 to $1, ", 2296 range->start, range->end - 1); 2297 } 2298 } 2299 contents->replace(contents->size() - 2, 2, ";\n"); 2300 } 2301 2302 if (reserved_name_count() > 0) { 2303 strings::SubstituteAndAppend(contents, "$0 reserved ", prefix); 2304 for (int i = 0; i < reserved_name_count(); i++) { 2305 strings::SubstituteAndAppend(contents, "\"$0\", ", 2306 CEscape(reserved_name(i))); 2307 } 2308 contents->replace(contents->size() - 2, 2, ";\n"); 2309 } 2310 2311 strings::SubstituteAndAppend(contents, "$0}\n", prefix); 2312 comment_printer.AddPostComment(contents); 2313 } 2314 2315 string FieldDescriptor::DebugString() const { 2316 DebugStringOptions options; // default options 2317 return DebugStringWithOptions(options); 2318 } 2319 2320 string FieldDescriptor::DebugStringWithOptions( 2321 const DebugStringOptions& debug_string_options) const { 2322 string contents; 2323 int depth = 0; 2324 if (is_extension()) { 2325 strings::SubstituteAndAppend(&contents, "extend .$0 {\n", 2326 containing_type()->full_name()); 2327 depth = 1; 2328 } 2329 DebugString(depth, PRINT_LABEL, &contents, debug_string_options); 2330 if (is_extension()) { 2331 contents.append("}\n"); 2332 } 2333 return contents; 2334 } 2335 2336 // The field type string used in FieldDescriptor::DebugString() 2337 string FieldDescriptor::FieldTypeNameDebugString() const { 2338 switch(type()) { 2339 case TYPE_MESSAGE: 2340 return "." + message_type()->full_name(); 2341 case TYPE_ENUM: 2342 return "." + enum_type()->full_name(); 2343 default: 2344 return kTypeToName[type()]; 2345 } 2346 } 2347 2348 void FieldDescriptor::DebugString(int depth, 2349 PrintLabelFlag print_label_flag, 2350 string *contents, 2351 const DebugStringOptions& 2352 debug_string_options) const { 2353 string prefix(depth * 2, ' '); 2354 string field_type; 2355 2356 // Special case map fields. 2357 if (is_map()) { 2358 strings::SubstituteAndAppend( 2359 &field_type, "map<$0, $1>", 2360 message_type()->field(0)->FieldTypeNameDebugString(), 2361 message_type()->field(1)->FieldTypeNameDebugString()); 2362 } else { 2363 field_type = FieldTypeNameDebugString(); 2364 } 2365 2366 string label; 2367 if (print_label_flag == PRINT_LABEL && !is_map()) { 2368 label = kLabelToName[this->label()]; 2369 label.push_back(' '); 2370 } 2371 2372 SourceLocationCommentPrinter 2373 comment_printer(this, prefix, debug_string_options); 2374 comment_printer.AddPreComment(contents); 2375 2376 strings::SubstituteAndAppend(contents, "$0$1$2 $3 = $4", 2377 prefix, 2378 label, 2379 field_type, 2380 type() == TYPE_GROUP ? message_type()->name() : 2381 name(), 2382 number()); 2383 2384 bool bracketed = false; 2385 if (has_default_value()) { 2386 bracketed = true; 2387 strings::SubstituteAndAppend(contents, " [default = $0", 2388 DefaultValueAsString(true)); 2389 } 2390 2391 string formatted_options; 2392 if (FormatBracketedOptions(depth, options(), &formatted_options)) { 2393 contents->append(bracketed ? ", " : " ["); 2394 bracketed = true; 2395 contents->append(formatted_options); 2396 } 2397 2398 if (bracketed) { 2399 contents->append("]"); 2400 } 2401 2402 if (type() == TYPE_GROUP) { 2403 if (debug_string_options.elide_group_body) { 2404 contents->append(" { ... };\n"); 2405 } else { 2406 message_type()->DebugString(depth, contents, debug_string_options, 2407 /* include_opening_clause */ false); 2408 } 2409 } else { 2410 contents->append(";\n"); 2411 } 2412 2413 comment_printer.AddPostComment(contents); 2414 } 2415 2416 string OneofDescriptor::DebugString() const { 2417 DebugStringOptions options; // default values 2418 return DebugStringWithOptions(options); 2419 } 2420 2421 string OneofDescriptor::DebugStringWithOptions( 2422 const DebugStringOptions& options) const { 2423 string contents; 2424 DebugString(0, &contents, options); 2425 return contents; 2426 } 2427 2428 void OneofDescriptor::DebugString(int depth, string* contents, 2429 const DebugStringOptions& 2430 debug_string_options) const { 2431 string prefix(depth * 2, ' '); 2432 ++depth; 2433 SourceLocationCommentPrinter 2434 comment_printer(this, prefix, debug_string_options); 2435 comment_printer.AddPreComment(contents); 2436 strings::SubstituteAndAppend( 2437 contents, "$0 oneof $1 {", prefix, name()); 2438 if (debug_string_options.elide_oneof_body) { 2439 contents->append(" ... }\n"); 2440 } else { 2441 for (int i = 0; i < field_count(); i++) { 2442 field(i)->DebugString(depth, FieldDescriptor::OMIT_LABEL, contents, 2443 debug_string_options); 2444 } 2445 strings::SubstituteAndAppend(contents, "$0}\n", prefix); 2446 } 2447 comment_printer.AddPostComment(contents); 2448 } 2449 2450 string EnumDescriptor::DebugString() const { 2451 DebugStringOptions options; // default values 2452 return DebugStringWithOptions(options); 2453 } 2454 2455 string EnumDescriptor::DebugStringWithOptions( 2456 const DebugStringOptions& options) const { 2457 string contents; 2458 DebugString(0, &contents, options); 2459 return contents; 2460 } 2461 2462 void EnumDescriptor::DebugString(int depth, string *contents, 2463 const DebugStringOptions& 2464 debug_string_options) const { 2465 string prefix(depth * 2, ' '); 2466 ++depth; 2467 2468 SourceLocationCommentPrinter 2469 comment_printer(this, prefix, debug_string_options); 2470 comment_printer.AddPreComment(contents); 2471 2472 strings::SubstituteAndAppend(contents, "$0enum $1 {\n", 2473 prefix, name()); 2474 2475 FormatLineOptions(depth, options(), contents); 2476 2477 for (int i = 0; i < value_count(); i++) { 2478 value(i)->DebugString(depth, contents, debug_string_options); 2479 } 2480 strings::SubstituteAndAppend(contents, "$0}\n", prefix); 2481 2482 comment_printer.AddPostComment(contents); 2483 } 2484 2485 string EnumValueDescriptor::DebugString() const { 2486 DebugStringOptions options; // default values 2487 return DebugStringWithOptions(options); 2488 } 2489 2490 string EnumValueDescriptor::DebugStringWithOptions( 2491 const DebugStringOptions& options) const { 2492 string contents; 2493 DebugString(0, &contents, options); 2494 return contents; 2495 } 2496 2497 void EnumValueDescriptor::DebugString(int depth, string *contents, 2498 const DebugStringOptions& 2499 debug_string_options) const { 2500 string prefix(depth * 2, ' '); 2501 2502 SourceLocationCommentPrinter 2503 comment_printer(this, prefix, debug_string_options); 2504 comment_printer.AddPreComment(contents); 2505 2506 strings::SubstituteAndAppend(contents, "$0$1 = $2", 2507 prefix, name(), number()); 2508 2509 string formatted_options; 2510 if (FormatBracketedOptions(depth, options(), &formatted_options)) { 2511 strings::SubstituteAndAppend(contents, " [$0]", formatted_options); 2512 } 2513 contents->append(";\n"); 2514 2515 comment_printer.AddPostComment(contents); 2516 } 2517 2518 string ServiceDescriptor::DebugString() const { 2519 DebugStringOptions options; // default values 2520 return DebugStringWithOptions(options); 2521 } 2522 2523 string ServiceDescriptor::DebugStringWithOptions( 2524 const DebugStringOptions& options) const { 2525 string contents; 2526 DebugString(&contents, options); 2527 return contents; 2528 } 2529 2530 void ServiceDescriptor::DebugString(string *contents, 2531 const DebugStringOptions& 2532 debug_string_options) const { 2533 SourceLocationCommentPrinter 2534 comment_printer(this, /* prefix */ "", debug_string_options); 2535 comment_printer.AddPreComment(contents); 2536 2537 strings::SubstituteAndAppend(contents, "service $0 {\n", name()); 2538 2539 FormatLineOptions(1, options(), contents); 2540 2541 for (int i = 0; i < method_count(); i++) { 2542 method(i)->DebugString(1, contents, debug_string_options); 2543 } 2544 2545 contents->append("}\n"); 2546 2547 comment_printer.AddPostComment(contents); 2548 } 2549 2550 string MethodDescriptor::DebugString() const { 2551 DebugStringOptions options; // default values 2552 return DebugStringWithOptions(options); 2553 } 2554 2555 string MethodDescriptor::DebugStringWithOptions( 2556 const DebugStringOptions& options) const { 2557 string contents; 2558 DebugString(0, &contents, options); 2559 return contents; 2560 } 2561 2562 void MethodDescriptor::DebugString(int depth, string *contents, 2563 const DebugStringOptions& 2564 debug_string_options) const { 2565 string prefix(depth * 2, ' '); 2566 ++depth; 2567 2568 SourceLocationCommentPrinter 2569 comment_printer(this, prefix, debug_string_options); 2570 comment_printer.AddPreComment(contents); 2571 2572 strings::SubstituteAndAppend(contents, "$0rpc $1($4.$2) returns ($5.$3)", 2573 prefix, name(), 2574 input_type()->full_name(), 2575 output_type()->full_name(), 2576 client_streaming() ? "stream " : "", 2577 server_streaming() ? "stream " : ""); 2578 2579 string formatted_options; 2580 if (FormatLineOptions(depth, options(), &formatted_options)) { 2581 strings::SubstituteAndAppend(contents, " {\n$0$1}\n", 2582 formatted_options, prefix); 2583 } else { 2584 contents->append(";\n"); 2585 } 2586 2587 comment_printer.AddPostComment(contents); 2588 } 2589 2590 2591 // Location methods =============================================== 2592 2593 bool FileDescriptor::GetSourceLocation(const vector<int>& path, 2594 SourceLocation* out_location) const { 2595 GOOGLE_CHECK_NOTNULL(out_location); 2596 if (source_code_info_) { 2597 if (const SourceCodeInfo_Location* loc = 2598 tables_->GetSourceLocation(path, source_code_info_)) { 2599 const RepeatedField<int32>& span = loc->span(); 2600 if (span.size() == 3 || span.size() == 4) { 2601 out_location->start_line = span.Get(0); 2602 out_location->start_column = span.Get(1); 2603 out_location->end_line = span.Get(span.size() == 3 ? 0 : 2); 2604 out_location->end_column = span.Get(span.size() - 1); 2605 2606 out_location->leading_comments = loc->leading_comments(); 2607 out_location->trailing_comments = loc->trailing_comments(); 2608 out_location->leading_detached_comments.assign( 2609 loc->leading_detached_comments().begin(), 2610 loc->leading_detached_comments().end()); 2611 return true; 2612 } 2613 } 2614 } 2615 return false; 2616 } 2617 2618 bool FileDescriptor::GetSourceLocation(SourceLocation* out_location) const { 2619 vector<int> path; // empty path for root FileDescriptor 2620 return GetSourceLocation(path, out_location); 2621 } 2622 2623 bool FieldDescriptor::is_packed() const { 2624 if (!is_packable()) return false; 2625 if (file_->syntax() == FileDescriptor::SYNTAX_PROTO2) { 2626 return (options_ != NULL) && options_->packed(); 2627 } else { 2628 return options_ == NULL || !options_->has_packed() || options_->packed(); 2629 } 2630 } 2631 2632 bool Descriptor::GetSourceLocation(SourceLocation* out_location) const { 2633 vector<int> path; 2634 GetLocationPath(&path); 2635 return file()->GetSourceLocation(path, out_location); 2636 } 2637 2638 bool FieldDescriptor::GetSourceLocation(SourceLocation* out_location) const { 2639 vector<int> path; 2640 GetLocationPath(&path); 2641 return file()->GetSourceLocation(path, out_location); 2642 } 2643 2644 bool OneofDescriptor::GetSourceLocation(SourceLocation* out_location) const { 2645 vector<int> path; 2646 GetLocationPath(&path); 2647 return containing_type()->file()->GetSourceLocation(path, out_location); 2648 } 2649 2650 bool EnumDescriptor::GetSourceLocation(SourceLocation* out_location) const { 2651 vector<int> path; 2652 GetLocationPath(&path); 2653 return file()->GetSourceLocation(path, out_location); 2654 } 2655 2656 bool MethodDescriptor::GetSourceLocation(SourceLocation* out_location) const { 2657 vector<int> path; 2658 GetLocationPath(&path); 2659 return service()->file()->GetSourceLocation(path, out_location); 2660 } 2661 2662 bool ServiceDescriptor::GetSourceLocation(SourceLocation* out_location) const { 2663 vector<int> path; 2664 GetLocationPath(&path); 2665 return file()->GetSourceLocation(path, out_location); 2666 } 2667 2668 bool EnumValueDescriptor::GetSourceLocation( 2669 SourceLocation* out_location) const { 2670 vector<int> path; 2671 GetLocationPath(&path); 2672 return type()->file()->GetSourceLocation(path, out_location); 2673 } 2674 2675 void Descriptor::GetLocationPath(vector<int>* output) const { 2676 if (containing_type()) { 2677 containing_type()->GetLocationPath(output); 2678 output->push_back(DescriptorProto::kNestedTypeFieldNumber); 2679 output->push_back(index()); 2680 } else { 2681 output->push_back(FileDescriptorProto::kMessageTypeFieldNumber); 2682 output->push_back(index()); 2683 } 2684 } 2685 2686 void FieldDescriptor::GetLocationPath(vector<int>* output) const { 2687 if (is_extension()) { 2688 if (extension_scope() == NULL) { 2689 output->push_back(FileDescriptorProto::kExtensionFieldNumber); 2690 output->push_back(index()); 2691 } else { 2692 extension_scope()->GetLocationPath(output); 2693 output->push_back(DescriptorProto::kExtensionFieldNumber); 2694 output->push_back(index()); 2695 } 2696 } else { 2697 containing_type()->GetLocationPath(output); 2698 output->push_back(DescriptorProto::kFieldFieldNumber); 2699 output->push_back(index()); 2700 } 2701 } 2702 2703 void OneofDescriptor::GetLocationPath(vector<int>* output) const { 2704 containing_type()->GetLocationPath(output); 2705 output->push_back(DescriptorProto::kOneofDeclFieldNumber); 2706 output->push_back(index()); 2707 } 2708 2709 void EnumDescriptor::GetLocationPath(vector<int>* output) const { 2710 if (containing_type()) { 2711 containing_type()->GetLocationPath(output); 2712 output->push_back(DescriptorProto::kEnumTypeFieldNumber); 2713 output->push_back(index()); 2714 } else { 2715 output->push_back(FileDescriptorProto::kEnumTypeFieldNumber); 2716 output->push_back(index()); 2717 } 2718 } 2719 2720 void EnumValueDescriptor::GetLocationPath(vector<int>* output) const { 2721 type()->GetLocationPath(output); 2722 output->push_back(EnumDescriptorProto::kValueFieldNumber); 2723 output->push_back(index()); 2724 } 2725 2726 void ServiceDescriptor::GetLocationPath(vector<int>* output) const { 2727 output->push_back(FileDescriptorProto::kServiceFieldNumber); 2728 output->push_back(index()); 2729 } 2730 2731 void MethodDescriptor::GetLocationPath(vector<int>* output) const { 2732 service()->GetLocationPath(output); 2733 output->push_back(ServiceDescriptorProto::kMethodFieldNumber); 2734 output->push_back(index()); 2735 } 2736 2737 // =================================================================== 2738 2739 namespace { 2740 2741 // Represents an options message to interpret. Extension names in the option 2742 // name are resolved relative to name_scope. element_name and orig_opt are 2743 // used only for error reporting (since the parser records locations against 2744 // pointers in the original options, not the mutable copy). The Message must be 2745 // one of the Options messages in descriptor.proto. 2746 struct OptionsToInterpret { 2747 OptionsToInterpret(const string& ns, 2748 const string& el, 2749 const Message* orig_opt, 2750 Message* opt) 2751 : name_scope(ns), 2752 element_name(el), 2753 original_options(orig_opt), 2754 options(opt) { 2755 } 2756 string name_scope; 2757 string element_name; 2758 const Message* original_options; 2759 Message* options; 2760 }; 2761 2762 } // namespace 2763 2764 class DescriptorBuilder { 2765 public: 2766 DescriptorBuilder(const DescriptorPool* pool, 2767 DescriptorPool::Tables* tables, 2768 DescriptorPool::ErrorCollector* error_collector); 2769 ~DescriptorBuilder(); 2770 2771 const FileDescriptor* BuildFile(const FileDescriptorProto& proto); 2772 2773 private: 2774 friend class OptionInterpreter; 2775 2776 // Non-recursive part of BuildFile functionality. 2777 const FileDescriptor* BuildFileImpl(const FileDescriptorProto& proto); 2778 2779 const DescriptorPool* pool_; 2780 DescriptorPool::Tables* tables_; // for convenience 2781 DescriptorPool::ErrorCollector* error_collector_; 2782 2783 // 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 2785 // can later (after cross-linking) interpret those options. 2786 vector<OptionsToInterpret> options_to_interpret_; 2787 2788 bool had_errors_; 2789 string filename_; 2790 FileDescriptor* file_; 2791 FileDescriptorTables* file_tables_; 2792 set<const FileDescriptor*> dependencies_; 2793 2794 // unused_dependency_ is used to record the unused imported files. 2795 // Note: public import is not considered. 2796 set<const FileDescriptor*> unused_dependency_; 2797 2798 // 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 2800 // possible_undeclared_dependency_ to point at that file. This is only used 2801 // by AddNotDefinedError() to report a more useful error message. 2802 // possible_undeclared_dependency_name_ is the name of the symbol that was 2803 // actually found in possible_undeclared_dependency_, which may be a parent 2804 // of the symbol actually looked for. 2805 const FileDescriptor* possible_undeclared_dependency_; 2806 string possible_undeclared_dependency_name_; 2807 2808 // If LookupSymbol() could resolve a symbol which is not defined, 2809 // record the resolved name. This is only used by AddNotDefinedError() 2810 // to report a more useful error message. 2811 string undefine_resolved_name_; 2812 2813 void AddError(const string& element_name, 2814 const Message& descriptor, 2815 DescriptorPool::ErrorCollector::ErrorLocation location, 2816 const string& error); 2817 void AddError(const string& element_name, 2818 const Message& descriptor, 2819 DescriptorPool::ErrorCollector::ErrorLocation location, 2820 const char* error); 2821 void AddRecursiveImportError(const FileDescriptorProto& proto, int from_here); 2822 void AddTwiceListedError(const FileDescriptorProto& proto, int index); 2823 void AddImportError(const FileDescriptorProto& proto, int index); 2824 2825 // Adds an error indicating that undefined_symbol was not defined. Must 2826 // only be called after LookupSymbol() fails. 2827 void AddNotDefinedError( 2828 const string& element_name, 2829 const Message& descriptor, 2830 DescriptorPool::ErrorCollector::ErrorLocation location, 2831 const string& undefined_symbol); 2832 2833 void AddWarning(const string& element_name, const Message& descriptor, 2834 DescriptorPool::ErrorCollector::ErrorLocation location, 2835 const string& error); 2836 2837 // Silly helper which determines if the given file is in the given package. 2838 // I.e., either file->package() == package_name or file->package() is a 2839 // nested package within package_name. 2840 bool IsInPackage(const FileDescriptor* file, const string& package_name); 2841 2842 // Helper function which finds all public dependencies of the given file, and 2843 // stores the them in the dependencies_ set in the builder. 2844 void RecordPublicDependencies(const FileDescriptor* file); 2845 2846 // Like tables_->FindSymbol(), but additionally: 2847 // - Search the pool's underlay if not found in tables_. 2848 // - Insure that the resulting Symbol is from one of the file's declared 2849 // dependencies. 2850 Symbol FindSymbol(const string& name); 2851 2852 // Like FindSymbol() but does not require that the symbol is in one of the 2853 // file's declared dependencies. 2854 Symbol FindSymbolNotEnforcingDeps(const string& name); 2855 2856 // This implements the body of FindSymbolNotEnforcingDeps(). 2857 Symbol FindSymbolNotEnforcingDepsHelper(const DescriptorPool* pool, 2858 const string& name); 2859 2860 // Like FindSymbol(), but looks up the name relative to some other symbol 2861 // name. This first searches siblings of relative_to, then siblings of its 2862 // parents, etc. For example, LookupSymbol("foo.bar", "baz.qux.corge") makes 2863 // the following calls, returning the first non-null result: 2864 // FindSymbol("baz.qux.foo.bar"), FindSymbol("baz.foo.bar"), 2865 // FindSymbol("foo.bar"). If AllowUnknownDependencies() has been called 2866 // on the DescriptorPool, this will generate a placeholder type if 2867 // the name is not found (unless the name itself is malformed). The 2868 // placeholder_type parameter indicates what kind of placeholder should be 2869 // constructed in this case. The resolve_mode parameter determines whether 2870 // any symbol is returned, or only symbols that are types. Note, however, 2871 // that LookupSymbol may still return a non-type symbol in LOOKUP_TYPES mode, 2872 // if it believes that's all it could refer to. The caller should always 2873 // check that it receives the type of symbol it was expecting. 2874 enum PlaceholderType { 2875 PLACEHOLDER_MESSAGE, 2876 PLACEHOLDER_ENUM, 2877 PLACEHOLDER_EXTENDABLE_MESSAGE 2878 }; 2879 enum ResolveMode { 2880 LOOKUP_ALL, LOOKUP_TYPES 2881 }; 2882 Symbol LookupSymbol(const string& name, const string& relative_to, 2883 PlaceholderType placeholder_type = PLACEHOLDER_MESSAGE, 2884 ResolveMode resolve_mode = LOOKUP_ALL); 2885 2886 // Like LookupSymbol() but will not return a placeholder even if 2887 // AllowUnknownDependencies() has been used. 2888 Symbol LookupSymbolNoPlaceholder(const string& name, 2889 const string& relative_to, 2890 ResolveMode resolve_mode = LOOKUP_ALL); 2891 2892 // Creates a placeholder type suitable for return from LookupSymbol(). May 2893 // return kNullSymbol if the name is not a valid type name. 2894 Symbol NewPlaceholder(const string& name, PlaceholderType placeholder_type); 2895 2896 // Creates a placeholder file. Never returns NULL. This is used when an 2897 // import is not found and AllowUnknownDependencies() is enabled. 2898 FileDescriptor* NewPlaceholderFile(const string& name); 2899 2900 // Calls tables_->AddSymbol() and records an error if it fails. Returns 2901 // true if successful or false if failed, though most callers can ignore 2902 // the return value since an error has already been recorded. 2903 bool AddSymbol(const string& full_name, 2904 const void* parent, const string& name, 2905 const Message& proto, Symbol symbol); 2906 2907 // Like AddSymbol(), but succeeds if the symbol is already defined as long 2908 // as the existing definition is also a package (because it's OK to define 2909 // the same package in two different files). Also adds all parents of the 2910 // packgae to the symbol table (e.g. AddPackage("foo.bar", ...) will add 2911 // "foo.bar" and "foo" to the table). 2912 void AddPackage(const string& name, const Message& proto, 2913 const FileDescriptor* file); 2914 2915 // Checks that the symbol name contains only alphanumeric characters and 2916 // underscores. Records an error otherwise. 2917 void ValidateSymbolName(const string& name, const string& full_name, 2918 const Message& proto); 2919 2920 // Like ValidateSymbolName(), but the name is allowed to contain periods and 2921 // an error is indicated by returning false (not recording the error). 2922 bool ValidateQualifiedName(const string& name); 2923 2924 // Used by BUILD_ARRAY macro (below) to avoid having to have the type 2925 // specified as a macro parameter. 2926 template <typename Type> 2927 inline void AllocateArray(int size, Type** output) { 2928 *output = tables_->AllocateArray<Type>(size); 2929 } 2930 2931 // Allocates a copy of orig_options in tables_ and stores it in the 2932 // descriptor. Remembers its uninterpreted options, to be interpreted 2933 // later. DescriptorT must be one of the Descriptor messages from 2934 // descriptor.proto. 2935 template<class DescriptorT> void AllocateOptions( 2936 const typename DescriptorT::OptionsType& orig_options, 2937 DescriptorT* descriptor); 2938 // Specialization for FileOptions. 2939 void AllocateOptions(const FileOptions& orig_options, 2940 FileDescriptor* descriptor); 2941 2942 // Implementation for AllocateOptions(). Don't call this directly. 2943 template<class DescriptorT> void AllocateOptionsImpl( 2944 const string& name_scope, 2945 const string& element_name, 2946 const typename DescriptorT::OptionsType& orig_options, 2947 DescriptorT* descriptor); 2948 2949 // These methods all have the same signature for the sake of the BUILD_ARRAY 2950 // macro, below. 2951 void BuildMessage(const DescriptorProto& proto, 2952 const Descriptor* parent, 2953 Descriptor* result); 2954 void BuildFieldOrExtension(const FieldDescriptorProto& proto, 2955 const Descriptor* parent, 2956 FieldDescriptor* result, 2957 bool is_extension); 2958 void BuildField(const FieldDescriptorProto& proto, 2959 const Descriptor* parent, 2960 FieldDescriptor* result) { 2961 BuildFieldOrExtension(proto, parent, result, false); 2962 } 2963 void BuildExtension(const FieldDescriptorProto& proto, 2964 const Descriptor* parent, 2965 FieldDescriptor* result) { 2966 BuildFieldOrExtension(proto, parent, result, true); 2967 } 2968 void BuildExtensionRange(const DescriptorProto::ExtensionRange& proto, 2969 const Descriptor* parent, 2970 Descriptor::ExtensionRange* result); 2971 void BuildReservedRange(const DescriptorProto::ReservedRange& proto, 2972 const Descriptor* parent, 2973 Descriptor::ReservedRange* result); 2974 void BuildOneof(const OneofDescriptorProto& proto, 2975 Descriptor* parent, 2976 OneofDescriptor* result); 2977 void BuildEnum(const EnumDescriptorProto& proto, 2978 const Descriptor* parent, 2979 EnumDescriptor* result); 2980 void BuildEnumValue(const EnumValueDescriptorProto& proto, 2981 const EnumDescriptor* parent, 2982 EnumValueDescriptor* result); 2983 void BuildService(const ServiceDescriptorProto& proto, 2984 const void* dummy, 2985 ServiceDescriptor* result); 2986 void BuildMethod(const MethodDescriptorProto& proto, 2987 const ServiceDescriptor* parent, 2988 MethodDescriptor* result); 2989 2990 void LogUnusedDependency(const FileDescriptorProto& proto, 2991 const FileDescriptor* result); 2992 2993 // Must be run only after building. 2994 // 2995 // NOTE: Options will not be available during cross-linking, as they 2996 // have not yet been interpreted. Defer any handling of options to the 2997 // Validate*Options methods. 2998 void CrossLinkFile(FileDescriptor* file, const FileDescriptorProto& proto); 2999 void CrossLinkMessage(Descriptor* message, const DescriptorProto& proto); 3000 void CrossLinkField(FieldDescriptor* field, 3001 const FieldDescriptorProto& proto); 3002 void CrossLinkEnum(EnumDescriptor* enum_type, 3003 const EnumDescriptorProto& proto); 3004 void CrossLinkEnumValue(EnumValueDescriptor* enum_value, 3005 const EnumValueDescriptorProto& proto); 3006 void CrossLinkService(ServiceDescriptor* service, 3007 const ServiceDescriptorProto& proto); 3008 void CrossLinkMethod(MethodDescriptor* method, 3009 const MethodDescriptorProto& proto); 3010 3011 // Must be run only after cross-linking. 3012 void InterpretOptions(); 3013 3014 // A helper class for interpreting options. 3015 class OptionInterpreter { 3016 public: 3017 // Creates an interpreter that operates in the context of the pool of the 3018 // specified builder, which must not be NULL. We don't take ownership of the 3019 // builder. 3020 explicit OptionInterpreter(DescriptorBuilder* builder); 3021 3022 ~OptionInterpreter(); 3023 3024 // Interprets the uninterpreted options in the specified Options message. 3025 // On error, calls AddError() on the underlying builder and returns false. 3026 // Otherwise returns true. 3027 bool InterpretOptions(OptionsToInterpret* options_to_interpret); 3028 3029 class AggregateOptionFinder; 3030 3031 private: 3032 // Interprets uninterpreted_option_ on the specified message, which 3033 // must be the mutable copy of the original options message to which 3034 // uninterpreted_option_ belongs. 3035 bool InterpretSingleOption(Message* options); 3036 3037 // Adds the uninterpreted_option to the given options message verbatim. 3038 // Used when AllowUnknownDependencies() is in effect and we can't find 3039 // the option's definition. 3040 void AddWithoutInterpreting(const UninterpretedOption& uninterpreted_option, 3041 Message* options); 3042 3043 // A recursive helper function that drills into the intermediate fields 3044 // in unknown_fields to check if field innermost_field is set on the 3045 // innermost message. Returns false and sets an error if so. 3046 bool ExamineIfOptionIsSet( 3047 vector<const FieldDescriptor*>::const_iterator intermediate_fields_iter, 3048 vector<const FieldDescriptor*>::const_iterator intermediate_fields_end, 3049 const FieldDescriptor* innermost_field, const string& debug_msg_name, 3050 const UnknownFieldSet& unknown_fields); 3051 3052 // Validates the value for the option field of the currently interpreted 3053 // option and then sets it on the unknown_field. 3054 bool SetOptionValue(const FieldDescriptor* option_field, 3055 UnknownFieldSet* unknown_fields); 3056 3057 // Parses an aggregate value for a CPPTYPE_MESSAGE option and 3058 // saves it into *unknown_fields. 3059 bool SetAggregateOption(const FieldDescriptor* option_field, 3060 UnknownFieldSet* unknown_fields); 3061 3062 // Convenience functions to set an int field the right way, depending on 3063 // its wire type (a single int CppType can represent multiple wire types). 3064 void SetInt32(int number, int32 value, FieldDescriptor::Type type, 3065 UnknownFieldSet* unknown_fields); 3066 void SetInt64(int number, int64 value, FieldDescriptor::Type type, 3067 UnknownFieldSet* unknown_fields); 3068 void SetUInt32(int number, uint32 value, FieldDescriptor::Type type, 3069 UnknownFieldSet* unknown_fields); 3070 void SetUInt64(int number, uint64 value, FieldDescriptor::Type type, 3071 UnknownFieldSet* unknown_fields); 3072 3073 // A helper function that adds an error at the specified location of the 3074 // option we're currently interpreting, and returns false. 3075 bool AddOptionError(DescriptorPool::ErrorCollector::ErrorLocation location, 3076 const string& msg) { 3077 builder_->AddError(options_to_interpret_->element_name, 3078 *uninterpreted_option_, location, msg); 3079 return false; 3080 } 3081 3082 // A helper function that adds an error at the location of the option name 3083 // and returns false. 3084 bool AddNameError(const string& msg) { 3085 return AddOptionError(DescriptorPool::ErrorCollector::OPTION_NAME, msg); 3086 } 3087 3088 // A helper function that adds an error at the location of the option name 3089 // and returns false. 3090 bool AddValueError(const string& msg) { 3091 return AddOptionError(DescriptorPool::ErrorCollector::OPTION_VALUE, msg); 3092 } 3093 3094 // We interpret against this builder's pool. Is never NULL. We don't own 3095 // this pointer. 3096 DescriptorBuilder* builder_; 3097 3098 // The options we're currently interpreting, or NULL if we're not in a call 3099 // to InterpretOptions. 3100 const OptionsToInterpret* options_to_interpret_; 3101 3102 // The option we're currently interpreting within options_to_interpret_, or 3103 // NULL if we're not in a call to InterpretOptions(). This points to a 3104 // submessage of the original option, not the mutable copy. Therefore we 3105 // can use it to find locations recorded by the parser. 3106 const UninterpretedOption* uninterpreted_option_; 3107 3108 // Factory used to create the dynamic messages we need to parse 3109 // any aggregate option values we encounter. 3110 DynamicMessageFactory dynamic_factory_; 3111 3112 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OptionInterpreter); 3113 }; 3114 3115 // Work-around for broken compilers: According to the C++ standard, 3116 // OptionInterpreter should have access to the private members of any class 3117 // which has declared DescriptorBuilder as a friend. Unfortunately some old 3118 // versions of GCC and other compilers do not implement this correctly. So, 3119 // we have to have these intermediate methods to provide access. We also 3120 // redundantly declare OptionInterpreter a friend just to make things extra 3121 // clear for these bad compilers. 3122 friend class OptionInterpreter; 3123 friend class OptionInterpreter::AggregateOptionFinder; 3124 3125 static inline bool get_allow_unknown(const DescriptorPool* pool) { 3126 return pool->allow_unknown_; 3127 } 3128 static inline bool get_enforce_weak(const DescriptorPool* pool) { 3129 return pool->enforce_weak_; 3130 } 3131 static inline bool get_is_placeholder(const Descriptor* descriptor) { 3132 return descriptor->is_placeholder_; 3133 } 3134 static inline void assert_mutex_held(const DescriptorPool* pool) { 3135 if (pool->mutex_ != NULL) { 3136 pool->mutex_->AssertHeld(); 3137 } 3138 } 3139 3140 // Must be run only after options have been interpreted. 3141 // 3142 // NOTE: Validation code must only reference the options in the mutable 3143 // descriptors, which are the ones that have been interpreted. The const 3144 // proto references are passed in only so they can be provided to calls to 3145 // AddError(). Do not look at their options, which have not been interpreted. 3146 void ValidateFileOptions(FileDescriptor* file, 3147 const FileDescriptorProto& proto); 3148 void ValidateMessageOptions(Descriptor* message, 3149 const DescriptorProto& proto); 3150 void ValidateFieldOptions(FieldDescriptor* field, 3151 const FieldDescriptorProto& proto); 3152 void ValidateEnumOptions(EnumDescriptor* enm, 3153 const EnumDescriptorProto& proto); 3154 void ValidateEnumValueOptions(EnumValueDescriptor* enum_value, 3155 const EnumValueDescriptorProto& proto); 3156 void ValidateServiceOptions(ServiceDescriptor* service, 3157 const ServiceDescriptorProto& proto); 3158 void ValidateMethodOptions(MethodDescriptor* method, 3159 const MethodDescriptorProto& proto); 3160 void ValidateProto3(FileDescriptor* file, 3161 const FileDescriptorProto& proto); 3162 void ValidateProto3Message(Descriptor* message, 3163 const DescriptorProto& proto); 3164 void ValidateProto3Field(FieldDescriptor* field, 3165 const FieldDescriptorProto& proto); 3166 void ValidateProto3Enum(EnumDescriptor* enm, 3167 const EnumDescriptorProto& proto); 3168 3169 // Returns true if the map entry message is compatible with the 3170 // auto-generated entry message from map fields syntax. 3171 bool ValidateMapEntry(FieldDescriptor* field, 3172 const FieldDescriptorProto& proto); 3173 3174 // Recursively detects naming conflicts with map entry types for a 3175 // better error message. 3176 void DetectMapConflicts(const Descriptor* message, 3177 const DescriptorProto& proto); 3178 3179 }; 3180 3181 const FileDescriptor* DescriptorPool::BuildFile( 3182 const FileDescriptorProto& proto) { 3183 GOOGLE_CHECK(fallback_database_ == NULL) 3184 << "Cannot call BuildFile on a DescriptorPool that uses a " 3185 "DescriptorDatabase. You must instead find a way to get your file " 3186 "into the underlying database."; 3187 GOOGLE_CHECK(mutex_ == NULL); // Implied by the above GOOGLE_CHECK. 3188 tables_->known_bad_symbols_.clear(); 3189 tables_->known_bad_files_.clear(); 3190 return DescriptorBuilder(this, tables_.get(), NULL).BuildFile(proto); 3191 } 3192 3193 const FileDescriptor* DescriptorPool::BuildFileCollectingErrors( 3194 const FileDescriptorProto& proto, 3195 ErrorCollector* error_collector) { 3196 GOOGLE_CHECK(fallback_database_ == NULL) 3197 << "Cannot call BuildFile on a DescriptorPool that uses a " 3198 "DescriptorDatabase. You must instead find a way to get your file " 3199 "into the underlying database."; 3200 GOOGLE_CHECK(mutex_ == NULL); // Implied by the above GOOGLE_CHECK. 3201 tables_->known_bad_symbols_.clear(); 3202 tables_->known_bad_files_.clear(); 3203 return DescriptorBuilder(this, tables_.get(), 3204 error_collector).BuildFile(proto); 3205 } 3206 3207 const FileDescriptor* DescriptorPool::BuildFileFromDatabase( 3208 const FileDescriptorProto& proto) const { 3209 mutex_->AssertHeld(); 3210 if (tables_->known_bad_files_.count(proto.name()) > 0) { 3211 return NULL; 3212 } 3213 const FileDescriptor* result = 3214 DescriptorBuilder(this, tables_.get(), 3215 default_error_collector_).BuildFile(proto); 3216 if (result == NULL) { 3217 tables_->known_bad_files_.insert(proto.name()); 3218 } 3219 return result; 3220 } 3221 3222 DescriptorBuilder::DescriptorBuilder( 3223 const DescriptorPool* pool, 3224 DescriptorPool::Tables* tables, 3225 DescriptorPool::ErrorCollector* error_collector) 3226 : pool_(pool), 3227 tables_(tables), 3228 error_collector_(error_collector), 3229 had_errors_(false), 3230 possible_undeclared_dependency_(NULL), 3231 undefine_resolved_name_("") {} 3232 3233 DescriptorBuilder::~DescriptorBuilder() {} 3234 3235 void DescriptorBuilder::AddError( 3236 const string& element_name, 3237 const Message& descriptor, 3238 DescriptorPool::ErrorCollector::ErrorLocation location, 3239 const string& error) { 3240 if (error_collector_ == NULL) { 3241 if (!had_errors_) { 3242 GOOGLE_LOG(ERROR) << "Invalid proto descriptor for file \"" << filename_ 3243 << "\":"; 3244 } 3245 GOOGLE_LOG(ERROR) << " " << element_name << ": " << error; 3246 } else { 3247 error_collector_->AddError(filename_, element_name, 3248 &descriptor, location, error); 3249 } 3250 had_errors_ = true; 3251 } 3252 3253 void DescriptorBuilder::AddError( 3254 const string& element_name, 3255 const Message& descriptor, 3256 DescriptorPool::ErrorCollector::ErrorLocation location, 3257 const char* error) { 3258 AddError(element_name, descriptor, location, string(error)); 3259 } 3260 3261 void DescriptorBuilder::AddNotDefinedError( 3262 const string& element_name, 3263 const Message& descriptor, 3264 DescriptorPool::ErrorCollector::ErrorLocation location, 3265 const string& undefined_symbol) { 3266 if (possible_undeclared_dependency_ == NULL && 3267 undefine_resolved_name_.empty()) { 3268 AddError(element_name, descriptor, location, 3269 "\"" + undefined_symbol + "\" is not defined."); 3270 } else { 3271 if (possible_undeclared_dependency_ != NULL) { 3272 AddError(element_name, descriptor, location, 3273 "\"" + possible_undeclared_dependency_name_ + 3274 "\" seems to be defined in \"" + 3275 possible_undeclared_dependency_->name() + "\", which is not " 3276 "imported by \"" + filename_ + "\". To use it here, please " 3277 "add the necessary import."); 3278 } 3279 if (!undefine_resolved_name_.empty()) { 3280 AddError(element_name, descriptor, location, 3281 "\"" + undefined_symbol + "\" is resolved to \"" + 3282 undefine_resolved_name_ + "\", which is not defined. " 3283 "The innermost scope is searched first in name resolution. " 3284 "Consider using a leading '.'(i.e., \"." 3285 + undefined_symbol + 3286 "\") to start from the outermost scope."); 3287 } 3288 } 3289 } 3290 3291 void DescriptorBuilder::AddWarning( 3292 const string& element_name, const Message& descriptor, 3293 DescriptorPool::ErrorCollector::ErrorLocation location, 3294 const string& error) { 3295 if (error_collector_ == NULL) { 3296 GOOGLE_LOG(WARNING) << filename_ << " " << element_name << ": " << error; 3297 } else { 3298 error_collector_->AddWarning(filename_, element_name, &descriptor, location, 3299 error); 3300 } 3301 } 3302 3303 bool DescriptorBuilder::IsInPackage(const FileDescriptor* file, 3304 const string& package_name) { 3305 return HasPrefixString(file->package(), package_name) && 3306 (file->package().size() == package_name.size() || 3307 file->package()[package_name.size()] == '.'); 3308 } 3309 3310 void DescriptorBuilder::RecordPublicDependencies(const FileDescriptor* file) { 3311 if (file == NULL || !dependencies_.insert(file).second) return; 3312 for (int i = 0; file != NULL && i < file->public_dependency_count(); i++) { 3313 RecordPublicDependencies(file->public_dependency(i)); 3314 } 3315 } 3316 3317 Symbol DescriptorBuilder::FindSymbolNotEnforcingDepsHelper( 3318 const DescriptorPool* pool, const string& name) { 3319 // If we are looking at an underlay, we must lock its mutex_, since we are 3320 // accessing the underlay's tables_ directly. 3321 MutexLockMaybe lock((pool == pool_) ? NULL : pool->mutex_); 3322 3323 Symbol result = pool->tables_->FindSymbol(name); 3324 if (result.IsNull() && pool->underlay_ != NULL) { 3325 // Symbol not found; check the underlay. 3326 result = FindSymbolNotEnforcingDepsHelper(pool->underlay_, name); 3327 } 3328 3329 if (result.IsNull()) { 3330 // In theory, we shouldn't need to check fallback_database_ because the 3331 // symbol should be in one of its file's direct dependencies, and we have 3332 // already loaded those by the time we get here. But we check anyway so 3333 // that we can generate better error message when dependencies are missing 3334 // (i.e., "missing dependency" rather than "type is not defined"). 3335 if (pool->TryFindSymbolInFallbackDatabase(name)) { 3336 result = pool->tables_->FindSymbol(name); 3337 } 3338 } 3339 3340 return result; 3341 } 3342 3343 Symbol DescriptorBuilder::FindSymbolNotEnforcingDeps(const string& name) { 3344 return FindSymbolNotEnforcingDepsHelper(pool_, name); 3345 } 3346 3347 Symbol DescriptorBuilder::FindSymbol(const string& name) { 3348 Symbol result = FindSymbolNotEnforcingDeps(name); 3349 3350 if (result.IsNull()) return result; 3351 3352 if (!pool_->enforce_dependencies_) { 3353 // Hack for CompilerUpgrader. 3354 return result; 3355 } 3356 3357 // Only find symbols which were defined in this file or one of its 3358 // dependencies. 3359 const FileDescriptor* file = result.GetFile(); 3360 if (file == file_ || dependencies_.count(file) > 0) { 3361 unused_dependency_.erase(file); 3362 return result; 3363 } 3364 3365 if (result.type == Symbol::PACKAGE) { 3366 // Arg, this is overcomplicated. The symbol is a package name. It could 3367 // 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 3369 // 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 3371 // dependency also defines the same package. We can't really rule out this 3372 // symbol unless none of the dependencies define it. 3373 if (IsInPackage(file_, name)) return result; 3374 for (set<const FileDescriptor*>::const_iterator it = dependencies_.begin(); 3375 it != dependencies_.end(); ++it) { 3376 // Note: A dependency may be NULL if it was not found or had errors. 3377 if (*it != NULL && IsInPackage(*it, name)) return result; 3378 } 3379 } 3380 3381 possible_undeclared_dependency_ = file; 3382 possible_undeclared_dependency_name_ = name; 3383 return kNullSymbol; 3384 } 3385 3386 Symbol DescriptorBuilder::LookupSymbolNoPlaceholder( 3387 const string& name, const string& relative_to, ResolveMode resolve_mode) { 3388 possible_undeclared_dependency_ = NULL; 3389 undefine_resolved_name_.clear(); 3390 3391 if (name.size() > 0 && name[0] == '.') { 3392 // Fully-qualified name. 3393 return FindSymbol(name.substr(1)); 3394 } 3395 3396 // If name is something like "Foo.Bar.baz", and symbols named "Foo" are 3397 // defined in multiple parent scopes, we only want to find "Bar.baz" in the 3398 // innermost one. E.g., the following should produce an error: 3399 // message Bar { message Baz {} } 3400 // message Foo { 3401 // message Bar { 3402 // } 3403 // optional Bar.Baz baz = 1; 3404 // } 3405 // So, we look for just "Foo" first, then look for "Bar.baz" within it if 3406 // found. 3407 string::size_type name_dot_pos = name.find_first_of('.'); 3408 string first_part_of_name; 3409 if (name_dot_pos == string::npos) { 3410 first_part_of_name = name; 3411 } else { 3412 first_part_of_name = name.substr(0, name_dot_pos); 3413 } 3414 3415 string scope_to_try(relative_to); 3416 3417 while (true) { 3418 // Chop off the last component of the scope. 3419 string::size_type dot_pos = scope_to_try.find_last_of('.'); 3420 if (dot_pos == string::npos) { 3421 return FindSymbol(name); 3422 } else { 3423 scope_to_try.erase(dot_pos); 3424 } 3425 3426 // Append ".first_part_of_name" and try to find. 3427 string::size_type old_size = scope_to_try.size(); 3428 scope_to_try.append(1, '.'); 3429 scope_to_try.append(first_part_of_name); 3430 Symbol result = FindSymbol(scope_to_try); 3431 if (!result.IsNull()) { 3432 if (first_part_of_name.size() < name.size()) { 3433 // name is a compound symbol, of which we only found the first part. 3434 // Now try to look up the rest of it. 3435 if (result.IsAggregate()) { 3436 scope_to_try.append(name, first_part_of_name.size(), 3437 name.size() - first_part_of_name.size()); 3438 result = FindSymbol(scope_to_try); 3439 if (result.IsNull()) { 3440 undefine_resolved_name_ = scope_to_try; 3441 } 3442 return result; 3443 } else { 3444 // We found a symbol but it's not an aggregate. Continue the loop. 3445 } 3446 } else { 3447 if (resolve_mode == LOOKUP_TYPES && !result.IsType()) { 3448 // We found a symbol but it's not a type. Continue the loop. 3449 } else { 3450 return result; 3451 } 3452 } 3453 } 3454 3455 // Not found. Remove the name so we can try again. 3456 scope_to_try.erase(old_size); 3457 } 3458 } 3459 3460 Symbol DescriptorBuilder::LookupSymbol( 3461 const string& name, const string& relative_to, 3462 PlaceholderType placeholder_type, ResolveMode resolve_mode) { 3463 Symbol result = LookupSymbolNoPlaceholder( 3464 name, relative_to, resolve_mode); 3465 if (result.IsNull() && pool_->allow_unknown_) { 3466 // Not found, but AllowUnknownDependencies() is enabled. Return a 3467 // placeholder instead. 3468 result = NewPlaceholder(name, placeholder_type); 3469 } 3470 return result; 3471 } 3472 3473 Symbol DescriptorBuilder::NewPlaceholder(const string& name, 3474 PlaceholderType placeholder_type) { 3475 // Compute names. 3476 const string* placeholder_full_name; 3477 const string* placeholder_name; 3478 const string* placeholder_package; 3479 3480 if (!ValidateQualifiedName(name)) return kNullSymbol; 3481 if (name[0] == '.') { 3482 // Fully-qualified. 3483 placeholder_full_name = tables_->AllocateString(name.substr(1)); 3484 } else { 3485 placeholder_full_name = tables_->AllocateString(name); 3486 } 3487 3488 string::size_type dotpos = placeholder_full_name->find_last_of('.'); 3489 if (dotpos != string::npos) { 3490 placeholder_package = tables_->AllocateString( 3491 placeholder_full_name->substr(0, dotpos)); 3492 placeholder_name = tables_->AllocateString( 3493 placeholder_full_name->substr(dotpos + 1)); 3494 } else { 3495 placeholder_package = &internal::GetEmptyString(); 3496 placeholder_name = placeholder_full_name; 3497 } 3498 3499 // Create the placeholders. 3500 FileDescriptor* placeholder_file = NewPlaceholderFile( 3501 *placeholder_full_name + ".placeholder.proto"); 3502 placeholder_file->package_ = placeholder_package; 3503 3504 if (placeholder_type == PLACEHOLDER_ENUM) { 3505 placeholder_file->enum_type_count_ = 1; 3506 placeholder_file->enum_types_ = 3507 tables_->AllocateArray<EnumDescriptor>(1); 3508 3509 EnumDescriptor* placeholder_enum = &placeholder_file->enum_types_[0]; 3510 memset(placeholder_enum, 0, sizeof(*placeholder_enum)); 3511 3512 placeholder_enum->full_name_ = placeholder_full_name; 3513 placeholder_enum->name_ = placeholder_name; 3514 placeholder_enum->file_ = placeholder_file; 3515 placeholder_enum->options_ = &EnumOptions::default_instance(); 3516 placeholder_enum->is_placeholder_ = true; 3517 placeholder_enum->is_unqualified_placeholder_ = (name[0] != '.'); 3518 3519 // Enums must have at least one value. 3520 placeholder_enum->value_count_ = 1; 3521 placeholder_enum->values_ = tables_->AllocateArray<EnumValueDescriptor>(1); 3522 3523 EnumValueDescriptor* placeholder_value = &placeholder_enum->values_[0]; 3524 memset(placeholder_value, 0, sizeof(*placeholder_value)); 3525 3526 placeholder_value->name_ = tables_->AllocateString("PLACEHOLDER_VALUE"); 3527 // Note that enum value names are siblings of their type, not children. 3528 placeholder_value->full_name_ = 3529 placeholder_package->empty() ? placeholder_value->name_ : 3530 tables_->AllocateString(*placeholder_package + ".PLACEHOLDER_VALUE"); 3531 3532 placeholder_value->number_ = 0; 3533 placeholder_value->type_ = placeholder_enum; 3534 placeholder_value->options_ = &EnumValueOptions::default_instance(); 3535 3536 return Symbol(placeholder_enum); 3537 } else { 3538 placeholder_file->message_type_count_ = 1; 3539 placeholder_file->message_types_ = 3540 tables_->AllocateArray<Descriptor>(1); 3541 3542 Descriptor* placeholder_message = &placeholder_file->message_types_[0]; 3543 memset(placeholder_message, 0, sizeof(*placeholder_message)); 3544 3545 placeholder_message->full_name_ = placeholder_full_name; 3546 placeholder_message->name_ = placeholder_name; 3547 placeholder_message->file_ = placeholder_file; 3548 placeholder_message->options_ = &MessageOptions::default_instance(); 3549 placeholder_message->is_placeholder_ = true; 3550 placeholder_message->is_unqualified_placeholder_ = (name[0] != '.'); 3551 3552 if (placeholder_type == PLACEHOLDER_EXTENDABLE_MESSAGE) { 3553 placeholder_message->extension_range_count_ = 1; 3554 placeholder_message->extension_ranges_ = 3555 tables_->AllocateArray<Descriptor::ExtensionRange>(1); 3556 placeholder_message->extension_ranges_->start = 1; 3557 // kMaxNumber + 1 because ExtensionRange::end is exclusive. 3558 placeholder_message->extension_ranges_->end = 3559 FieldDescriptor::kMaxNumber + 1; 3560 } 3561 3562 return Symbol(placeholder_message); 3563 } 3564 } 3565 3566 FileDescriptor* DescriptorBuilder::NewPlaceholderFile( 3567 const string& name) { 3568 FileDescriptor* placeholder = tables_->Allocate<FileDescriptor>(); 3569 memset(placeholder, 0, sizeof(*placeholder)); 3570 3571 placeholder->name_ = tables_->AllocateString(name); 3572 placeholder->package_ = &internal::GetEmptyString(); 3573 placeholder->pool_ = pool_; 3574 placeholder->options_ = &FileOptions::default_instance(); 3575 placeholder->tables_ = &FileDescriptorTables::GetEmptyInstance(); 3576 placeholder->source_code_info_ = &SourceCodeInfo::default_instance(); 3577 placeholder->is_placeholder_ = true; 3578 placeholder->syntax_ = FileDescriptor::SYNTAX_PROTO2; 3579 // All other fields are zero or NULL. 3580 3581 return placeholder; 3582 } 3583 3584 bool DescriptorBuilder::AddSymbol( 3585 const string& full_name, const void* parent, const string& name, 3586 const Message& proto, Symbol symbol) { 3587 // If the caller passed NULL for the parent, the symbol is at file scope. 3588 // Use its file as the parent instead. 3589 if (parent == NULL) parent = file_; 3590 3591 if (tables_->AddSymbol(full_name, symbol)) { 3592 if (!file_tables_->AddAliasUnderParent(parent, name, symbol)) { 3593 GOOGLE_LOG(DFATAL) << "\"" << full_name << "\" not previously defined in " 3594 "symbols_by_name_, but was defined in symbols_by_parent_; " 3595 "this shouldn't be possible."; 3596 return false; 3597 } 3598 return true; 3599 } else { 3600 const FileDescriptor* other_file = tables_->FindSymbol(full_name).GetFile(); 3601 if (other_file == file_) { 3602 string::size_type dot_pos = full_name.find_last_of('.'); 3603 if (dot_pos == string::npos) { 3604 AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, 3605 "\"" + full_name + "\" is already defined."); 3606 } else { 3607 AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, 3608 "\"" + full_name.substr(dot_pos + 1) + 3609 "\" is already defined in \"" + 3610 full_name.substr(0, dot_pos) + "\"."); 3611 } 3612 } else { 3613 // Symbol seems to have been defined in a different file. 3614 AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, 3615 "\"" + full_name + "\" is already defined in file \"" + 3616 other_file->name() + "\"."); 3617 } 3618 return false; 3619 } 3620 } 3621 3622 void DescriptorBuilder::AddPackage( 3623 const string& name, const Message& proto, const FileDescriptor* file) { 3624 if (tables_->AddSymbol(name, Symbol(file))) { 3625 // Success. Also add parent package, if any. 3626 string::size_type dot_pos = name.find_last_of('.'); 3627 if (dot_pos == string::npos) { 3628 // No parents. 3629 ValidateSymbolName(name, name, proto); 3630 } else { 3631 // Has parent. 3632 string* parent_name = tables_->AllocateString(name.substr(0, dot_pos)); 3633 AddPackage(*parent_name, proto, file); 3634 ValidateSymbolName(name.substr(dot_pos + 1), name, proto); 3635 } 3636 } else { 3637 Symbol existing_symbol = tables_->FindSymbol(name); 3638 // It's OK to redefine a package. 3639 if (existing_symbol.type != Symbol::PACKAGE) { 3640 // Symbol seems to have been defined in a different file. 3641 AddError(name, proto, DescriptorPool::ErrorCollector::NAME, 3642 "\"" + name + "\" is already defined (as something other than " 3643 "a package) in file \"" + existing_symbol.GetFile()->name() + 3644 "\"."); 3645 } 3646 } 3647 } 3648 3649 void DescriptorBuilder::ValidateSymbolName( 3650 const string& name, const string& full_name, const Message& proto) { 3651 if (name.empty()) { 3652 AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, 3653 "Missing name."); 3654 } else { 3655 for (int i = 0; i < name.size(); i++) { 3656 // I don't trust isalnum() due to locales. :( 3657 if ((name[i] < 'a' || 'z' < name[i]) && 3658 (name[i] < 'A' || 'Z' < name[i]) && 3659 (name[i] < '0' || '9' < name[i]) && 3660 (name[i] != '_')) { 3661 AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, 3662 "\"" + name + "\" is not a valid identifier."); 3663 } 3664 } 3665 } 3666 } 3667 3668 bool DescriptorBuilder::ValidateQualifiedName(const string& name) { 3669 bool last_was_period = false; 3670 3671 for (int i = 0; i < name.size(); i++) { 3672 // I don't trust isalnum() due to locales. :( 3673 if (('a' <= name[i] && name[i] <= 'z') || 3674 ('A' <= name[i] && name[i] <= 'Z') || 3675 ('0' <= name[i] && name[i] <= '9') || 3676 (name[i] == '_')) { 3677 last_was_period = false; 3678 } else if (name[i] == '.') { 3679 if (last_was_period) return false; 3680 last_was_period = true; 3681 } else { 3682 return false; 3683 } 3684 } 3685 3686 return !name.empty() && !last_was_period; 3687 } 3688 3689 // ------------------------------------------------------------------- 3690 3691 // This generic implementation is good for all descriptors except 3692 // FileDescriptor. 3693 template<class DescriptorT> void DescriptorBuilder::AllocateOptions( 3694 const typename DescriptorT::OptionsType& orig_options, 3695 DescriptorT* descriptor) { 3696 AllocateOptionsImpl(descriptor->full_name(), descriptor->full_name(), 3697 orig_options, descriptor); 3698 } 3699 3700 // We specialize for FileDescriptor. 3701 void DescriptorBuilder::AllocateOptions(const FileOptions& orig_options, 3702 FileDescriptor* descriptor) { 3703 // We add the dummy token so that LookupSymbol does the right thing. 3704 AllocateOptionsImpl(descriptor->package() + ".dummy", descriptor->name(), 3705 orig_options, descriptor); 3706 } 3707 3708 template<class DescriptorT> void DescriptorBuilder::AllocateOptionsImpl( 3709 const string& name_scope, 3710 const string& element_name, 3711 const typename DescriptorT::OptionsType& orig_options, 3712 DescriptorT* descriptor) { 3713 // We need to use a dummy pointer to work around a bug in older versions of 3714 // GCC. Otherwise, the following two lines could be replaced with: 3715 // typename DescriptorT::OptionsType* options = 3716 // tables_->AllocateMessage<typename DescriptorT::OptionsType>(); 3717 typename DescriptorT::OptionsType* const dummy = NULL; 3718 typename DescriptorT::OptionsType* options = tables_->AllocateMessage(dummy); 3719 // Avoid using MergeFrom()/CopyFrom() in this class to make it -fno-rtti 3720 // friendly. Without RTTI, MergeFrom() and CopyFrom() will fallback to the 3721 // reflection based method, which requires the Descriptor. However, we are in 3722 // the middle of building the descriptors, thus the deadlock. 3723 options->ParseFromString(orig_options.SerializeAsString()); 3724 descriptor->options_ = options; 3725 3726 // Don't add to options_to_interpret_ unless there were uninterpreted 3727 // options. This not only avoids unnecessary work, but prevents a 3728 // bootstrapping problem when building descriptors for descriptor.proto. 3729 // descriptor.proto does not contain any uninterpreted options, but 3730 // attempting to interpret options anyway will cause 3731 // OptionsType::GetDescriptor() to be called which may then deadlock since 3732 // we're still trying to build it. 3733 if (options->uninterpreted_option_size() > 0) { 3734 options_to_interpret_.push_back( 3735 OptionsToInterpret(name_scope, element_name, &orig_options, options)); 3736 } 3737 } 3738 3739 3740 // A common pattern: We want to convert a repeated field in the descriptor 3741 // to an array of values, calling some method to build each value. 3742 #define BUILD_ARRAY(INPUT, OUTPUT, NAME, METHOD, PARENT) \ 3743 OUTPUT->NAME##_count_ = INPUT.NAME##_size(); \ 3744 AllocateArray(INPUT.NAME##_size(), &OUTPUT->NAME##s_); \ 3745 for (int i = 0; i < INPUT.NAME##_size(); i++) { \ 3746 METHOD(INPUT.NAME(i), PARENT, OUTPUT->NAME##s_ + i); \ 3747 } 3748 3749 void DescriptorBuilder::AddRecursiveImportError( 3750 const FileDescriptorProto& proto, int from_here) { 3751 string error_message("File recursively imports itself: "); 3752 for (int i = from_here; i < tables_->pending_files_.size(); i++) { 3753 error_message.append(tables_->pending_files_[i]); 3754 error_message.append(" -> "); 3755 } 3756 error_message.append(proto.name()); 3757 3758 AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, 3759 error_message); 3760 } 3761 3762 void DescriptorBuilder::AddTwiceListedError(const FileDescriptorProto& proto, 3763 int index) { 3764 AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, 3765 "Import \"" + proto.dependency(index) + "\" was listed twice."); 3766 } 3767 3768 void DescriptorBuilder::AddImportError(const FileDescriptorProto& proto, 3769 int index) { 3770 string message; 3771 if (pool_->fallback_database_ == NULL) { 3772 message = "Import \"" + proto.dependency(index) + 3773 "\" has not been loaded."; 3774 } else { 3775 message = "Import \"" + proto.dependency(index) + 3776 "\" was not found or had errors."; 3777 } 3778 AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, message); 3779 } 3780 3781 static bool ExistingFileMatchesProto(const FileDescriptor* existing_file, 3782 const FileDescriptorProto& proto) { 3783 FileDescriptorProto existing_proto; 3784 existing_file->CopyTo(&existing_proto); 3785 // TODO(liujisi): Remove it when CopyTo supports copying syntax params when 3786 // syntax="proto2". 3787 if (existing_file->syntax() == FileDescriptor::SYNTAX_PROTO2 && 3788 proto.has_syntax()) { 3789 existing_proto.set_syntax( 3790 existing_file->SyntaxName(existing_file->syntax())); 3791 } 3792 3793 return existing_proto.SerializeAsString() == proto.SerializeAsString(); 3794 } 3795 3796 const FileDescriptor* DescriptorBuilder::BuildFile( 3797 const FileDescriptorProto& proto) { 3798 filename_ = proto.name(); 3799 3800 // Check if the file already exists and is identical to the one being built. 3801 // Note: This only works if the input is canonical -- that is, it 3802 // fully-qualifies all type names, has no UninterpretedOptions, etc. 3803 // This is fine, because this idempotency "feature" really only exists to 3804 // accommodate one hack in the proto1->proto2 migration layer. 3805 const FileDescriptor* existing_file = tables_->FindFile(filename_); 3806 if (existing_file != NULL) { 3807 // File already in pool. Compare the existing one to the input. 3808 if (ExistingFileMatchesProto(existing_file, proto)) { 3809 // They're identical. Return the existing descriptor. 3810 return existing_file; 3811 } 3812 3813 // Not a match. The error will be detected and handled later. 3814 } 3815 3816 // Check to see if this file is already on the pending files list. 3817 // TODO(kenton): Allow recursive imports? It may not work with some 3818 // (most?) programming languages. E.g., in C++, a forward declaration 3819 // of a type is not sufficient to allow it to be used even in a 3820 // generated header file due to inlining. This could perhaps be 3821 // worked around using tricks involving inserting #include statements 3822 // mid-file, but that's pretty ugly, and I'm pretty sure there are 3823 // some languages out there that do not allow recursive dependencies 3824 // at all. 3825 for (int i = 0; i < tables_->pending_files_.size(); i++) { 3826 if (tables_->pending_files_[i] == proto.name()) { 3827 AddRecursiveImportError(proto, i); 3828 return NULL; 3829 } 3830 } 3831 3832 // If we have a fallback_database_, attempt to load all dependencies now, 3833 // before checkpointing tables_. This avoids confusion with recursive 3834 // checkpoints. 3835 if (pool_->fallback_database_ != NULL) { 3836 tables_->pending_files_.push_back(proto.name()); 3837 for (int i = 0; i < proto.dependency_size(); i++) { 3838 if (tables_->FindFile(proto.dependency(i)) == NULL && 3839 (pool_->underlay_ == NULL || 3840 pool_->underlay_->FindFileByName(proto.dependency(i)) == NULL)) { 3841 // We don't care what this returns since we'll find out below anyway. 3842 pool_->TryFindFileInFallbackDatabase(proto.dependency(i)); 3843 } 3844 } 3845 tables_->pending_files_.pop_back(); 3846 } 3847 return BuildFileImpl(proto); 3848 } 3849 3850 const FileDescriptor* DescriptorBuilder::BuildFileImpl( 3851 const FileDescriptorProto& proto) { 3852 // Checkpoint the tables so that we can roll back if something goes wrong. 3853 tables_->AddCheckpoint(); 3854 3855 FileDescriptor* result = tables_->Allocate<FileDescriptor>(); 3856 file_ = result; 3857 3858 result->is_placeholder_ = false; 3859 if (proto.has_source_code_info()) { 3860 SourceCodeInfo *info = tables_->AllocateMessage<SourceCodeInfo>(); 3861 info->CopyFrom(proto.source_code_info()); 3862 result->source_code_info_ = info; 3863 } else { 3864 result->source_code_info_ = &SourceCodeInfo::default_instance(); 3865 } 3866 3867 file_tables_ = tables_->AllocateFileTables(); 3868 file_->tables_ = file_tables_; 3869 3870 if (!proto.has_name()) { 3871 AddError("", proto, DescriptorPool::ErrorCollector::OTHER, 3872 "Missing field: FileDescriptorProto.name."); 3873 } 3874 3875 // TODO(liujisi): Report error when the syntax is empty after all the protos 3876 // have added the syntax statement. 3877 if (proto.syntax().empty() || proto.syntax() == "proto2") { 3878 file_->syntax_ = FileDescriptor::SYNTAX_PROTO2; 3879 } else if (proto.syntax() == "proto3") { 3880 file_->syntax_ = FileDescriptor::SYNTAX_PROTO3; 3881 } else { 3882 file_->syntax_ = FileDescriptor::SYNTAX_UNKNOWN; 3883 AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, 3884 "Unrecognized syntax: " + proto.syntax()); 3885 } 3886 3887 result->name_ = tables_->AllocateString(proto.name()); 3888 if (proto.has_package()) { 3889 result->package_ = tables_->AllocateString(proto.package()); 3890 } else { 3891 // We cannot rely on proto.package() returning a valid string if 3892 // proto.has_package() is false, because we might be running at static 3893 // initialization time, in which case default values have not yet been 3894 // initialized. 3895 result->package_ = tables_->AllocateString(""); 3896 } 3897 result->pool_ = pool_; 3898 3899 // Add to tables. 3900 if (!tables_->AddFile(result)) { 3901 AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, 3902 "A file with this name is already in the pool."); 3903 // 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. 3905 tables_->RollbackToLastCheckpoint(); 3906 return NULL; 3907 } 3908 if (!result->package().empty()) { 3909 AddPackage(result->package(), proto, result); 3910 } 3911 3912 // Make sure all dependencies are loaded. 3913 set<string> seen_dependencies; 3914 result->dependency_count_ = proto.dependency_size(); 3915 result->dependencies_ = 3916 tables_->AllocateArray<const FileDescriptor*>(proto.dependency_size()); 3917 unused_dependency_.clear(); 3918 set<int> weak_deps; 3919 for (int i = 0; i < proto.weak_dependency_size(); ++i) { 3920 weak_deps.insert(proto.weak_dependency(i)); 3921 } 3922 for (int i = 0; i < proto.dependency_size(); i++) { 3923 if (!seen_dependencies.insert(proto.dependency(i)).second) { 3924 AddTwiceListedError(proto, i); 3925 } 3926 3927 const FileDescriptor* dependency = tables_->FindFile(proto.dependency(i)); 3928 if (dependency == NULL && pool_->underlay_ != NULL) { 3929 dependency = pool_->underlay_->FindFileByName(proto.dependency(i)); 3930 } 3931 3932 if (dependency == NULL) { 3933 if (pool_->allow_unknown_ || 3934 (!pool_->enforce_weak_ && weak_deps.find(i) != weak_deps.end())) { 3935 dependency = NewPlaceholderFile(proto.dependency(i)); 3936 } else { 3937 AddImportError(proto, i); 3938 } 3939 } else { 3940 // Add to unused_dependency_ to track unused imported files. 3941 // Note: do not track unused imported files for public import. 3942 if (pool_->enforce_dependencies_ && 3943 (pool_->unused_import_track_files_.find(proto.name()) != 3944 pool_->unused_import_track_files_.end()) && 3945 (dependency->public_dependency_count() == 0)) { 3946 unused_dependency_.insert(dependency); 3947 } 3948 } 3949 3950 result->dependencies_[i] = dependency; 3951 } 3952 3953 // Check public dependencies. 3954 int public_dependency_count = 0; 3955 result->public_dependencies_ = tables_->AllocateArray<int>( 3956 proto.public_dependency_size()); 3957 for (int i = 0; i < proto.public_dependency_size(); i++) { 3958 // Only put valid public dependency indexes. 3959 int index = proto.public_dependency(i); 3960 if (index >= 0 && index < proto.dependency_size()) { 3961 result->public_dependencies_[public_dependency_count++] = index; 3962 // Do not track unused imported files for public import. 3963 unused_dependency_.erase(result->dependency(index)); 3964 } else { 3965 AddError(proto.name(), proto, 3966 DescriptorPool::ErrorCollector::OTHER, 3967 "Invalid public dependency index."); 3968 } 3969 } 3970 result->public_dependency_count_ = public_dependency_count; 3971 3972 // Build dependency set 3973 dependencies_.clear(); 3974 for (int i = 0; i < result->dependency_count(); i++) { 3975 RecordPublicDependencies(result->dependency(i)); 3976 } 3977 3978 // Check weak dependencies. 3979 int weak_dependency_count = 0; 3980 result->weak_dependencies_ = tables_->AllocateArray<int>( 3981 proto.weak_dependency_size()); 3982 for (int i = 0; i < proto.weak_dependency_size(); i++) { 3983 int index = proto.weak_dependency(i); 3984 if (index >= 0 && index < proto.dependency_size()) { 3985 result->weak_dependencies_[weak_dependency_count++] = index; 3986 } else { 3987 AddError(proto.name(), proto, 3988 DescriptorPool::ErrorCollector::OTHER, 3989 "Invalid weak dependency index."); 3990 } 3991 } 3992 result->weak_dependency_count_ = weak_dependency_count; 3993 3994 // Convert children. 3995 BUILD_ARRAY(proto, result, message_type, BuildMessage , NULL); 3996 BUILD_ARRAY(proto, result, enum_type , BuildEnum , NULL); 3997 BUILD_ARRAY(proto, result, service , BuildService , NULL); 3998 BUILD_ARRAY(proto, result, extension , BuildExtension, NULL); 3999 4000 // Copy options. 4001 if (!proto.has_options()) { 4002 result->options_ = NULL; // Will set to default_instance later. 4003 } else { 4004 AllocateOptions(proto.options(), result); 4005 } 4006 4007 // Note that the following steps must occur in exactly the specified order. 4008 4009 // Cross-link. 4010 CrossLinkFile(result, proto); 4011 4012 // Interpret any remaining uninterpreted options gathered into 4013 // options_to_interpret_ during descriptor building. Cross-linking has made 4014 // extension options known, so all interpretations should now succeed. 4015 if (!had_errors_) { 4016 OptionInterpreter option_interpreter(this); 4017 for (vector<OptionsToInterpret>::iterator iter = 4018 options_to_interpret_.begin(); 4019 iter != options_to_interpret_.end(); ++iter) { 4020 option_interpreter.InterpretOptions(&(*iter)); 4021 } 4022 options_to_interpret_.clear(); 4023 } 4024 4025 // Validate options. 4026 if (!had_errors_) { 4027 ValidateFileOptions(result, proto); 4028 } 4029 4030 // Additional naming conflict check for map entry types. Only need to check 4031 // this if there are already errors. 4032 if (had_errors_) { 4033 for (int i = 0; i < proto.message_type_size(); ++i) { 4034 DetectMapConflicts(result->message_type(i), proto.message_type(i)); 4035 } 4036 } 4037 4038 4039 if (!unused_dependency_.empty()) { 4040 LogUnusedDependency(proto, result); 4041 } 4042 4043 if (had_errors_) { 4044 tables_->RollbackToLastCheckpoint(); 4045 return NULL; 4046 } else { 4047 tables_->ClearLastCheckpoint(); 4048 return result; 4049 } 4050 } 4051 4052 void DescriptorBuilder::BuildMessage(const DescriptorProto& proto, 4053 const Descriptor* parent, 4054 Descriptor* result) { 4055 const string& scope = (parent == NULL) ? 4056 file_->package() : parent->full_name(); 4057 string* full_name = tables_->AllocateString(scope); 4058 if (!full_name->empty()) full_name->append(1, '.'); 4059 full_name->append(proto.name()); 4060 4061 ValidateSymbolName(proto.name(), *full_name, proto); 4062 4063 result->name_ = tables_->AllocateString(proto.name()); 4064 result->full_name_ = full_name; 4065 result->file_ = file_; 4066 result->containing_type_ = parent; 4067 result->is_placeholder_ = false; 4068 result->is_unqualified_placeholder_ = false; 4069 4070 // Build oneofs first so that fields and extension ranges can refer to them. 4071 BUILD_ARRAY(proto, result, oneof_decl , BuildOneof , result); 4072 BUILD_ARRAY(proto, result, field , BuildField , result); 4073 BUILD_ARRAY(proto, result, nested_type , BuildMessage , result); 4074 BUILD_ARRAY(proto, result, enum_type , BuildEnum , result); 4075 BUILD_ARRAY(proto, result, extension_range, BuildExtensionRange, result); 4076 BUILD_ARRAY(proto, result, extension , BuildExtension , result); 4077 BUILD_ARRAY(proto, result, reserved_range , BuildReservedRange , result); 4078 4079 // Copy reserved names. 4080 int reserved_name_count = proto.reserved_name_size(); 4081 result->reserved_name_count_ = reserved_name_count; 4082 result->reserved_names_ = 4083 tables_->AllocateArray<const string*>(reserved_name_count); 4084 for (int i = 0; i < reserved_name_count; ++i) { 4085 result->reserved_names_[i] = 4086 tables_->AllocateString(proto.reserved_name(i)); 4087 } 4088 4089 // Copy options. 4090 if (!proto.has_options()) { 4091 result->options_ = NULL; // Will set to default_instance later. 4092 } else { 4093 AllocateOptions(proto.options(), result); 4094 } 4095 4096 AddSymbol(result->full_name(), parent, result->name(), 4097 proto, Symbol(result)); 4098 4099 for (int i = 0; i < proto.reserved_range_size(); i++) { 4100 const DescriptorProto_ReservedRange& range1 = proto.reserved_range(i); 4101 for (int j = i + 1; j < proto.reserved_range_size(); j++) { 4102 const DescriptorProto_ReservedRange& range2 = proto.reserved_range(j); 4103 if (range1.end() > range2.start() && range2.end() > range1.start()) { 4104 AddError(result->full_name(), proto.reserved_range(i), 4105 DescriptorPool::ErrorCollector::NUMBER, 4106 strings::Substitute("Reserved range $0 to $1 overlaps with " 4107 "already-defined range $2 to $3.", 4108 range2.start(), range2.end() - 1, 4109 range1.start(), range1.end() - 1)); 4110 } 4111 } 4112 } 4113 4114 hash_set<string> reserved_name_set; 4115 for (int i = 0; i < proto.reserved_name_size(); i++) { 4116 const string& name = proto.reserved_name(i); 4117 if (reserved_name_set.find(name) == reserved_name_set.end()) { 4118 reserved_name_set.insert(name); 4119 } else { 4120 AddError(name, proto, DescriptorPool::ErrorCollector::NAME, 4121 strings::Substitute( 4122 "Field name \"$0\" is reserved multiple times.", 4123 name)); 4124 } 4125 } 4126 4127 for (int i = 0; i < result->field_count(); i++) { 4128 const FieldDescriptor* field = result->field(i); 4129 for (int j = 0; j < result->extension_range_count(); j++) { 4130 const Descriptor::ExtensionRange* range = result->extension_range(j); 4131 if (range->start <= field->number() && field->number() < range->end) { 4132 AddError(field->full_name(), proto.extension_range(j), 4133 DescriptorPool::ErrorCollector::NUMBER, 4134 strings::Substitute( 4135 "Extension range $0 to $1 includes field \"$2\" ($3).", 4136 range->start, range->end - 1, 4137 field->name(), field->number())); 4138 } 4139 } 4140 for (int j = 0; j < result->reserved_range_count(); j++) { 4141 const Descriptor::ReservedRange* range = result->reserved_range(j); 4142 if (range->start <= field->number() && field->number() < range->end) { 4143 AddError(field->full_name(), proto.reserved_range(j), 4144 DescriptorPool::ErrorCollector::NUMBER, 4145 strings::Substitute( 4146 "Field \"$0\" uses reserved number $1.", 4147 field->name(), field->number())); 4148 } 4149 } 4150 if (reserved_name_set.find(field->name()) != reserved_name_set.end()) { 4151 AddError(field->full_name(), proto.field(i), 4152 DescriptorPool::ErrorCollector::NAME, 4153 strings::Substitute( 4154 "Field name \"$0\" is reserved.", field->name())); 4155 } 4156 } 4157 4158 // Check that extension ranges don't overlap and don't include 4159 // reserved field numbers. 4160 for (int i = 0; i < result->extension_range_count(); i++) { 4161 const Descriptor::ExtensionRange* range1 = result->extension_range(i); 4162 for (int j = 0; j < result->reserved_range_count(); j++) { 4163 const Descriptor::ReservedRange* range2 = result->reserved_range(j); 4164 if (range1->end > range2->start && range2->end > range1->start) { 4165 AddError(result->full_name(), proto.extension_range(j), 4166 DescriptorPool::ErrorCollector::NUMBER, 4167 strings::Substitute("Extension range $0 to $1 overlaps with " 4168 "reserved range $2 to $3.", 4169 range1->start, range1->end - 1, 4170 range2->start, range2->end - 1)); 4171 } 4172 } 4173 for (int j = i + 1; j < result->extension_range_count(); j++) { 4174 const Descriptor::ExtensionRange* range2 = result->extension_range(j); 4175 if (range1->end > range2->start && range2->end > range1->start) { 4176 AddError(result->full_name(), proto.extension_range(j), 4177 DescriptorPool::ErrorCollector::NUMBER, 4178 strings::Substitute("Extension range $0 to $1 overlaps with " 4179 "already-defined range $2 to $3.", 4180 range2->start, range2->end - 1, 4181 range1->start, range1->end - 1)); 4182 } 4183 } 4184 } 4185 } 4186 4187 4188 void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto, 4189 const Descriptor* parent, 4190 FieldDescriptor* result, 4191 bool is_extension) { 4192 const string& scope = (parent == NULL) ? 4193 file_->package() : parent->full_name(); 4194 string* full_name = tables_->AllocateString(scope); 4195 if (!full_name->empty()) full_name->append(1, '.'); 4196 full_name->append(proto.name()); 4197 4198 ValidateSymbolName(proto.name(), *full_name, proto); 4199 4200 result->name_ = tables_->AllocateString(proto.name()); 4201 result->full_name_ = full_name; 4202 result->file_ = file_; 4203 result->number_ = proto.number(); 4204 result->is_extension_ = is_extension; 4205 4206 // If .proto files follow the style guide then the name should already be 4207 // lower-cased. If that's the case we can just reuse the string we already 4208 // allocated rather than allocate a new one. 4209 string lowercase_name(proto.name()); 4210 LowerString(&lowercase_name); 4211 if (lowercase_name == proto.name()) { 4212 result->lowercase_name_ = result->name_; 4213 } else { 4214 result->lowercase_name_ = tables_->AllocateString(lowercase_name); 4215 } 4216 4217 // Don't bother with the above optimization for camel-case names since 4218 // .proto files that follow the guide shouldn't be using names in this 4219 // format, so the optimization wouldn't help much. 4220 result->camelcase_name_ = 4221 tables_->AllocateString(ToCamelCase(proto.name(), 4222 /* lower_first = */ true)); 4223 4224 if (proto.has_json_name()) { 4225 result->has_json_name_ = true; 4226 result->json_name_ = tables_->AllocateString(proto.json_name()); 4227 } else { 4228 result->has_json_name_ = false; 4229 result->json_name_ = result->camelcase_name_; 4230 } 4231 4232 // Some compilers do not allow static_cast directly between two enum types, 4233 // so we must cast to int first. 4234 result->type_ = static_cast<FieldDescriptor::Type>( 4235 implicit_cast<int>(proto.type())); 4236 result->label_ = static_cast<FieldDescriptor::Label>( 4237 implicit_cast<int>(proto.label())); 4238 4239 // An extension cannot have a required field (b/13365836). 4240 if (result->is_extension_ && 4241 result->label_ == FieldDescriptor::LABEL_REQUIRED) { 4242 AddError(result->full_name(), proto, 4243 // Error location `TYPE`: we would really like to indicate 4244 // `LABEL`, but the `ErrorLocation` enum has no entry for this, and 4245 // we don't necessarily know about all implementations of the 4246 // `ErrorCollector` interface to extend them to handle the new 4247 // error location type properly. 4248 DescriptorPool::ErrorCollector::TYPE, 4249 "Message extensions cannot have required fields."); 4250 } 4251 4252 // Some of these may be filled in when cross-linking. 4253 result->containing_type_ = NULL; 4254 result->extension_scope_ = NULL; 4255 result->message_type_ = NULL; 4256 result->enum_type_ = NULL; 4257 4258 result->has_default_value_ = proto.has_default_value(); 4259 if (proto.has_default_value() && result->is_repeated()) { 4260 AddError(result->full_name(), proto, 4261 DescriptorPool::ErrorCollector::DEFAULT_VALUE, 4262 "Repeated fields can't have default values."); 4263 } 4264 4265 if (proto.has_type()) { 4266 if (proto.has_default_value()) { 4267 char* end_pos = NULL; 4268 switch (result->cpp_type()) { 4269 case FieldDescriptor::CPPTYPE_INT32: 4270 result->default_value_int32_ = 4271 strtol(proto.default_value().c_str(), &end_pos, 0); 4272 break; 4273 case FieldDescriptor::CPPTYPE_INT64: 4274 result->default_value_int64_ = 4275 strto64(proto.default_value().c_str(), &end_pos, 0); 4276 break; 4277 case FieldDescriptor::CPPTYPE_UINT32: 4278 result->default_value_uint32_ = 4279 strtoul(proto.default_value().c_str(), &end_pos, 0); 4280 break; 4281 case FieldDescriptor::CPPTYPE_UINT64: 4282 result->default_value_uint64_ = 4283 strtou64(proto.default_value().c_str(), &end_pos, 0); 4284 break; 4285 case FieldDescriptor::CPPTYPE_FLOAT: 4286 if (proto.default_value() == "inf") { 4287 result->default_value_float_ = numeric_limits<float>::infinity(); 4288 } else if (proto.default_value() == "-inf") { 4289 result->default_value_float_ = -numeric_limits<float>::infinity(); 4290 } else if (proto.default_value() == "nan") { 4291 result->default_value_float_ = numeric_limits<float>::quiet_NaN(); 4292 } else { 4293 result->default_value_float_ = io::SafeDoubleToFloat( 4294 io::NoLocaleStrtod(proto.default_value().c_str(), &end_pos)); 4295 } 4296 break; 4297 case FieldDescriptor::CPPTYPE_DOUBLE: 4298 if (proto.default_value() == "inf") { 4299 result->default_value_double_ = numeric_limits<double>::infinity(); 4300 } else if (proto.default_value() == "-inf") { 4301 result->default_value_double_ = -numeric_limits<double>::infinity(); 4302 } else if (proto.default_value() == "nan") { 4303 result->default_value_double_ = numeric_limits<double>::quiet_NaN(); 4304 } else { 4305 result->default_value_double_ = 4306 io::NoLocaleStrtod(proto.default_value().c_str(), &end_pos); 4307 } 4308 break; 4309 case FieldDescriptor::CPPTYPE_BOOL: 4310 if (proto.default_value() == "true") { 4311 result->default_value_bool_ = true; 4312 } else if (proto.default_value() == "false") { 4313 result->default_value_bool_ = false; 4314 } else { 4315 AddError(result->full_name(), proto, 4316 DescriptorPool::ErrorCollector::DEFAULT_VALUE, 4317 "Boolean default must be true or false."); 4318 } 4319 break; 4320 case FieldDescriptor::CPPTYPE_ENUM: 4321 // This will be filled in when cross-linking. 4322 result->default_value_enum_ = NULL; 4323 break; 4324 case FieldDescriptor::CPPTYPE_STRING: 4325 if (result->type() == FieldDescriptor::TYPE_BYTES) { 4326 result->default_value_string_ = tables_->AllocateString( 4327 UnescapeCEscapeString(proto.default_value())); 4328 } else { 4329 result->default_value_string_ = 4330 tables_->AllocateString(proto.default_value()); 4331 } 4332 break; 4333 case FieldDescriptor::CPPTYPE_MESSAGE: 4334 AddError(result->full_name(), proto, 4335 DescriptorPool::ErrorCollector::DEFAULT_VALUE, 4336 "Messages can't have default values."); 4337 result->has_default_value_ = false; 4338 break; 4339 } 4340 4341 if (end_pos != NULL) { 4342 // end_pos is only set non-NULL by the parsers for numeric types, above. 4343 // This checks that the default was non-empty and had no extra junk 4344 // after the end of the number. 4345 if (proto.default_value().empty() || *end_pos != '\0') { 4346 AddError(result->full_name(), proto, 4347 DescriptorPool::ErrorCollector::DEFAULT_VALUE, 4348 "Couldn't parse default value \"" + proto.default_value() + 4349 "\"."); 4350 } 4351 } 4352 } else { 4353 // No explicit default value 4354 switch (result->cpp_type()) { 4355 case FieldDescriptor::CPPTYPE_INT32: 4356 result->default_value_int32_ = 0; 4357 break; 4358 case FieldDescriptor::CPPTYPE_INT64: 4359 result->default_value_int64_ = 0; 4360 break; 4361 case FieldDescriptor::CPPTYPE_UINT32: 4362 result->default_value_uint32_ = 0; 4363 break; 4364 case FieldDescriptor::CPPTYPE_UINT64: 4365 result->default_value_uint64_ = 0; 4366 break; 4367 case FieldDescriptor::CPPTYPE_FLOAT: 4368 result->default_value_float_ = 0.0f; 4369 break; 4370 case FieldDescriptor::CPPTYPE_DOUBLE: 4371 result->default_value_double_ = 0.0; 4372 break; 4373 case FieldDescriptor::CPPTYPE_BOOL: 4374 result->default_value_bool_ = false; 4375 break; 4376 case FieldDescriptor::CPPTYPE_ENUM: 4377 // This will be filled in when cross-linking. 4378 result->default_value_enum_ = NULL; 4379 break; 4380 case FieldDescriptor::CPPTYPE_STRING: 4381 result->default_value_string_ = &internal::GetEmptyString(); 4382 break; 4383 case FieldDescriptor::CPPTYPE_MESSAGE: 4384 break; 4385 } 4386 } 4387 } 4388 4389 if (result->number() <= 0) { 4390 AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, 4391 "Field numbers must be positive integers."); 4392 } else if (!is_extension && result->number() > FieldDescriptor::kMaxNumber) { 4393 // Only validate that the number is within the valid field range if it is 4394 // not an extension. Since extension numbers are validated with the 4395 // extendee's valid set of extension numbers, and those are in turn 4396 // validated against the max allowed number, the check is unnecessary for 4397 // extension fields. 4398 // This avoids cross-linking issues that arise when attempting to check if 4399 // the extendee is a message_set_wire_format message, which has a higher max 4400 // on extension numbers. 4401 AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, 4402 strings::Substitute("Field numbers cannot be greater than $0.", 4403 FieldDescriptor::kMaxNumber)); 4404 } else if (result->number() >= FieldDescriptor::kFirstReservedNumber && 4405 result->number() <= FieldDescriptor::kLastReservedNumber) { 4406 AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, 4407 strings::Substitute( 4408 "Field numbers $0 through $1 are reserved for the protocol " 4409 "buffer library implementation.", 4410 FieldDescriptor::kFirstReservedNumber, 4411 FieldDescriptor::kLastReservedNumber)); 4412 } 4413 4414 if (is_extension) { 4415 if (!proto.has_extendee()) { 4416 AddError(result->full_name(), proto, 4417 DescriptorPool::ErrorCollector::EXTENDEE, 4418 "FieldDescriptorProto.extendee not set for extension field."); 4419 } 4420 4421 result->extension_scope_ = parent; 4422 4423 if (proto.has_oneof_index()) { 4424 AddError(result->full_name(), proto, 4425 DescriptorPool::ErrorCollector::OTHER, 4426 "FieldDescriptorProto.oneof_index should not be set for " 4427 "extensions."); 4428 } 4429 4430 // Fill in later (maybe). 4431 result->containing_oneof_ = NULL; 4432 } else { 4433 if (proto.has_extendee()) { 4434 AddError(result->full_name(), proto, 4435 DescriptorPool::ErrorCollector::EXTENDEE, 4436 "FieldDescriptorProto.extendee set for non-extension field."); 4437 } 4438 4439 result->containing_type_ = parent; 4440 4441 if (proto.has_oneof_index()) { 4442 if (proto.oneof_index() < 0 || 4443 proto.oneof_index() >= parent->oneof_decl_count()) { 4444 AddError(result->full_name(), proto, 4445 DescriptorPool::ErrorCollector::OTHER, 4446 strings::Substitute("FieldDescriptorProto.oneof_index $0 is " 4447 "out of range for type \"$1\".", 4448 proto.oneof_index(), 4449 parent->name())); 4450 result->containing_oneof_ = NULL; 4451 } else { 4452 result->containing_oneof_ = parent->oneof_decl(proto.oneof_index()); 4453 } 4454 } else { 4455 result->containing_oneof_ = NULL; 4456 } 4457 } 4458 4459 // Copy options. 4460 if (!proto.has_options()) { 4461 result->options_ = NULL; // Will set to default_instance later. 4462 } else { 4463 AllocateOptions(proto.options(), result); 4464 } 4465 4466 4467 AddSymbol(result->full_name(), parent, result->name(), 4468 proto, Symbol(result)); 4469 } 4470 4471 void DescriptorBuilder::BuildExtensionRange( 4472 const DescriptorProto::ExtensionRange& proto, 4473 const Descriptor* parent, 4474 Descriptor::ExtensionRange* result) { 4475 result->start = proto.start(); 4476 result->end = proto.end(); 4477 if (result->start <= 0) { 4478 AddError(parent->full_name(), proto, 4479 DescriptorPool::ErrorCollector::NUMBER, 4480 "Extension numbers must be positive integers."); 4481 } 4482 4483 // Checking of the upper bound of the extension range is deferred until after 4484 // options interpreting. This allows messages with message_set_wire_format to 4485 // have extensions beyond FieldDescriptor::kMaxNumber, since the extension 4486 // numbers are actually used as int32s in the message_set_wire_format. 4487 4488 if (result->start >= result->end) { 4489 AddError(parent->full_name(), proto, 4490 DescriptorPool::ErrorCollector::NUMBER, 4491 "Extension range end number must be greater than start number."); 4492 } 4493 } 4494 4495 void DescriptorBuilder::BuildReservedRange( 4496 const DescriptorProto::ReservedRange& proto, 4497 const Descriptor* parent, 4498 Descriptor::ReservedRange* result) { 4499 result->start = proto.start(); 4500 result->end = proto.end(); 4501 if (result->start <= 0) { 4502 AddError(parent->full_name(), proto, 4503 DescriptorPool::ErrorCollector::NUMBER, 4504 "Reserved numbers must be positive integers."); 4505 } 4506 } 4507 4508 void DescriptorBuilder::BuildOneof(const OneofDescriptorProto& proto, 4509 Descriptor* parent, 4510 OneofDescriptor* result) { 4511 string* full_name = tables_->AllocateString(parent->full_name()); 4512 full_name->append(1, '.'); 4513 full_name->append(proto.name()); 4514 4515 ValidateSymbolName(proto.name(), *full_name, proto); 4516 4517 result->name_ = tables_->AllocateString(proto.name()); 4518 result->full_name_ = full_name; 4519 4520 result->containing_type_ = parent; 4521 4522 // We need to fill these in later. 4523 result->field_count_ = 0; 4524 result->fields_ = NULL; 4525 4526 AddSymbol(result->full_name(), parent, result->name(), 4527 proto, Symbol(result)); 4528 } 4529 4530 void DescriptorBuilder::BuildEnum(const EnumDescriptorProto& proto, 4531 const Descriptor* parent, 4532 EnumDescriptor* result) { 4533 const string& scope = (parent == NULL) ? 4534 file_->package() : parent->full_name(); 4535 string* full_name = tables_->AllocateString(scope); 4536 if (!full_name->empty()) full_name->append(1, '.'); 4537 full_name->append(proto.name()); 4538 4539 ValidateSymbolName(proto.name(), *full_name, proto); 4540 4541 result->name_ = tables_->AllocateString(proto.name()); 4542 result->full_name_ = full_name; 4543 result->file_ = file_; 4544 result->containing_type_ = parent; 4545 result->is_placeholder_ = false; 4546 result->is_unqualified_placeholder_ = false; 4547 4548 if (proto.value_size() == 0) { 4549 // We cannot allow enums with no values because this would mean there 4550 // would be no valid default value for fields of this type. 4551 AddError(result->full_name(), proto, 4552 DescriptorPool::ErrorCollector::NAME, 4553 "Enums must contain at least one value."); 4554 } 4555 4556 BUILD_ARRAY(proto, result, value, BuildEnumValue, result); 4557 4558 // Copy options. 4559 if (!proto.has_options()) { 4560 result->options_ = NULL; // Will set to default_instance later. 4561 } else { 4562 AllocateOptions(proto.options(), result); 4563 } 4564 4565 AddSymbol(result->full_name(), parent, result->name(), 4566 proto, Symbol(result)); 4567 } 4568 4569 void DescriptorBuilder::BuildEnumValue(const EnumValueDescriptorProto& proto, 4570 const EnumDescriptor* parent, 4571 EnumValueDescriptor* result) { 4572 result->name_ = tables_->AllocateString(proto.name()); 4573 result->number_ = proto.number(); 4574 result->type_ = parent; 4575 4576 // Note: full_name for enum values is a sibling to the parent's name, not a 4577 // child of it. 4578 string* full_name = tables_->AllocateString(*parent->full_name_); 4579 full_name->resize(full_name->size() - parent->name_->size()); 4580 full_name->append(*result->name_); 4581 result->full_name_ = full_name; 4582 4583 ValidateSymbolName(proto.name(), *full_name, proto); 4584 4585 // Copy options. 4586 if (!proto.has_options()) { 4587 result->options_ = NULL; // Will set to default_instance later. 4588 } else { 4589 AllocateOptions(proto.options(), result); 4590 } 4591 4592 // Again, enum values are weird because we makes them appear as siblings 4593 // of the enum type instead of children of it. So, we use 4594 // parent->containing_type() as the value's parent. 4595 bool added_to_outer_scope = 4596 AddSymbol(result->full_name(), parent->containing_type(), result->name(), 4597 proto, Symbol(result)); 4598 4599 // However, we also want to be able to search for values within a single 4600 // enum type, so we add it as a child of the enum type itself, too. 4601 // Note: This could fail, but if it does, the error has already been 4602 // reported by the above AddSymbol() call, so we ignore the return code. 4603 bool added_to_inner_scope = 4604 file_tables_->AddAliasUnderParent(parent, result->name(), Symbol(result)); 4605 4606 if (added_to_inner_scope && !added_to_outer_scope) { 4607 // This value did not conflict with any values defined in the same enum, 4608 // but it did conflict with some other symbol defined in the enum type's 4609 // scope. Let's print an additional error to explain this. 4610 string outer_scope; 4611 if (parent->containing_type() == NULL) { 4612 outer_scope = file_->package(); 4613 } else { 4614 outer_scope = parent->containing_type()->full_name(); 4615 } 4616 4617 if (outer_scope.empty()) { 4618 outer_scope = "the global scope"; 4619 } else { 4620 outer_scope = "\"" + outer_scope + "\""; 4621 } 4622 4623 AddError(result->full_name(), proto, 4624 DescriptorPool::ErrorCollector::NAME, 4625 "Note that enum values use C++ scoping rules, meaning that " 4626 "enum values are siblings of their type, not children of it. " 4627 "Therefore, \"" + result->name() + "\" must be unique within " 4628 + outer_scope + ", not just within \"" + parent->name() + "\"."); 4629 } 4630 4631 // An enum is allowed to define two numbers that refer to the same value. 4632 // FindValueByNumber() should return the first such value, so we simply 4633 // ignore AddEnumValueByNumber()'s return code. 4634 file_tables_->AddEnumValueByNumber(result); 4635 } 4636 4637 void DescriptorBuilder::BuildService(const ServiceDescriptorProto& proto, 4638 const void* /* dummy */, 4639 ServiceDescriptor* result) { 4640 string* full_name = tables_->AllocateString(file_->package()); 4641 if (!full_name->empty()) full_name->append(1, '.'); 4642 full_name->append(proto.name()); 4643 4644 ValidateSymbolName(proto.name(), *full_name, proto); 4645 4646 result->name_ = tables_->AllocateString(proto.name()); 4647 result->full_name_ = full_name; 4648 result->file_ = file_; 4649 4650 BUILD_ARRAY(proto, result, method, BuildMethod, result); 4651 4652 // Copy options. 4653 if (!proto.has_options()) { 4654 result->options_ = NULL; // Will set to default_instance later. 4655 } else { 4656 AllocateOptions(proto.options(), result); 4657 } 4658 4659 AddSymbol(result->full_name(), NULL, result->name(), 4660 proto, Symbol(result)); 4661 } 4662 4663 void DescriptorBuilder::BuildMethod(const MethodDescriptorProto& proto, 4664 const ServiceDescriptor* parent, 4665 MethodDescriptor* result) { 4666 result->name_ = tables_->AllocateString(proto.name()); 4667 result->service_ = parent; 4668 4669 string* full_name = tables_->AllocateString(parent->full_name()); 4670 full_name->append(1, '.'); 4671 full_name->append(*result->name_); 4672 result->full_name_ = full_name; 4673 4674 ValidateSymbolName(proto.name(), *full_name, proto); 4675 4676 // These will be filled in when cross-linking. 4677 result->input_type_ = NULL; 4678 result->output_type_ = NULL; 4679 4680 // Copy options. 4681 if (!proto.has_options()) { 4682 result->options_ = NULL; // Will set to default_instance later. 4683 } else { 4684 AllocateOptions(proto.options(), result); 4685 } 4686 4687 result->client_streaming_ = proto.client_streaming(); 4688 result->server_streaming_ = proto.server_streaming(); 4689 4690 AddSymbol(result->full_name(), parent, result->name(), 4691 proto, Symbol(result)); 4692 } 4693 4694 #undef BUILD_ARRAY 4695 4696 // ------------------------------------------------------------------- 4697 4698 void DescriptorBuilder::CrossLinkFile( 4699 FileDescriptor* file, const FileDescriptorProto& proto) { 4700 if (file->options_ == NULL) { 4701 file->options_ = &FileOptions::default_instance(); 4702 } 4703 4704 for (int i = 0; i < file->message_type_count(); i++) { 4705 CrossLinkMessage(&file->message_types_[i], proto.message_type(i)); 4706 } 4707 4708 for (int i = 0; i < file->extension_count(); i++) { 4709 CrossLinkField(&file->extensions_[i], proto.extension(i)); 4710 } 4711 4712 for (int i = 0; i < file->enum_type_count(); i++) { 4713 CrossLinkEnum(&file->enum_types_[i], proto.enum_type(i)); 4714 } 4715 4716 for (int i = 0; i < file->service_count(); i++) { 4717 CrossLinkService(&file->services_[i], proto.service(i)); 4718 } 4719 } 4720 4721 void DescriptorBuilder::CrossLinkMessage( 4722 Descriptor* message, const DescriptorProto& proto) { 4723 if (message->options_ == NULL) { 4724 message->options_ = &MessageOptions::default_instance(); 4725 } 4726 4727 for (int i = 0; i < message->nested_type_count(); i++) { 4728 CrossLinkMessage(&message->nested_types_[i], proto.nested_type(i)); 4729 } 4730 4731 for (int i = 0; i < message->enum_type_count(); i++) { 4732 CrossLinkEnum(&message->enum_types_[i], proto.enum_type(i)); 4733 } 4734 4735 for (int i = 0; i < message->field_count(); i++) { 4736 CrossLinkField(&message->fields_[i], proto.field(i)); 4737 } 4738 4739 for (int i = 0; i < message->extension_count(); i++) { 4740 CrossLinkField(&message->extensions_[i], proto.extension(i)); 4741 } 4742 4743 // Set up field array for each oneof. 4744 4745 // First count the number of fields per oneof. 4746 for (int i = 0; i < message->field_count(); i++) { 4747 const OneofDescriptor* oneof_decl = message->field(i)->containing_oneof(); 4748 if (oneof_decl != NULL) { 4749 // Make sure fields belonging to the same oneof are defined consecutively. 4750 // This enables optimizations in codegens and reflection libraries to 4751 // skip fields in the oneof group, as only one of the field can be set. 4752 // Note that field_count() returns how many fields in this oneof we have 4753 // seen so far. field_count() > 0 guarantees that i > 0, so field(i-1) is 4754 // safe. 4755 if (oneof_decl->field_count() > 0 && 4756 message->field(i - 1)->containing_oneof() != oneof_decl) { 4757 AddError( 4758 message->full_name() + "." + message->field(i - 1)->name(), 4759 proto.field(i - 1), DescriptorPool::ErrorCollector::OTHER, 4760 strings::Substitute( 4761 "Fields in the same oneof must be defined consecutively. " 4762 "\"$0\" cannot be defined before the completion of the " 4763 "\"$1\" oneof definition.", 4764 message->field(i - 1)->name(), oneof_decl->name())); 4765 } 4766 // Must go through oneof_decls_ array to get a non-const version of the 4767 // OneofDescriptor. 4768 ++message->oneof_decls_[oneof_decl->index()].field_count_; 4769 } 4770 } 4771 4772 // Then allocate the arrays. 4773 for (int i = 0; i < message->oneof_decl_count(); i++) { 4774 OneofDescriptor* oneof_decl = &message->oneof_decls_[i]; 4775 4776 if (oneof_decl->field_count() == 0) { 4777 AddError(message->full_name() + "." + oneof_decl->name(), 4778 proto.oneof_decl(i), 4779 DescriptorPool::ErrorCollector::NAME, 4780 "Oneof must have at least one field."); 4781 } 4782 4783 oneof_decl->fields_ = 4784 tables_->AllocateArray<const FieldDescriptor*>(oneof_decl->field_count_); 4785 oneof_decl->field_count_ = 0; 4786 } 4787 4788 // Then fill them in. 4789 for (int i = 0; i < message->field_count(); i++) { 4790 const OneofDescriptor* oneof_decl = message->field(i)->containing_oneof(); 4791 if (oneof_decl != NULL) { 4792 OneofDescriptor* mutable_oneof_decl = 4793 &message->oneof_decls_[oneof_decl->index()]; 4794 message->fields_[i].index_in_oneof_ = mutable_oneof_decl->field_count_; 4795 mutable_oneof_decl->fields_[mutable_oneof_decl->field_count_++] = 4796 message->field(i); 4797 } 4798 } 4799 } 4800 4801 void DescriptorBuilder::CrossLinkField( 4802 FieldDescriptor* field, const FieldDescriptorProto& proto) { 4803 if (field->options_ == NULL) { 4804 field->options_ = &FieldOptions::default_instance(); 4805 } 4806 4807 if (proto.has_extendee()) { 4808 Symbol extendee = LookupSymbol(proto.extendee(), field->full_name(), 4809 PLACEHOLDER_EXTENDABLE_MESSAGE); 4810 if (extendee.IsNull()) { 4811 AddNotDefinedError(field->full_name(), proto, 4812 DescriptorPool::ErrorCollector::EXTENDEE, 4813 proto.extendee()); 4814 return; 4815 } else if (extendee.type != Symbol::MESSAGE) { 4816 AddError(field->full_name(), proto, 4817 DescriptorPool::ErrorCollector::EXTENDEE, 4818 "\"" + proto.extendee() + "\" is not a message type."); 4819 return; 4820 } 4821 field->containing_type_ = extendee.descriptor; 4822 4823 const Descriptor::ExtensionRange* extension_range = field->containing_type() 4824 ->FindExtensionRangeContainingNumber(field->number()); 4825 4826 if (extension_range == NULL) { 4827 AddError(field->full_name(), proto, 4828 DescriptorPool::ErrorCollector::NUMBER, 4829 strings::Substitute("\"$0\" does not declare $1 as an " 4830 "extension number.", 4831 field->containing_type()->full_name(), 4832 field->number())); 4833 } 4834 } 4835 4836 if (field->containing_oneof() != NULL) { 4837 if (field->label() != FieldDescriptor::LABEL_OPTIONAL) { 4838 // Note that this error will never happen when parsing .proto files. 4839 // It can only happen if you manually construct a FileDescriptorProto 4840 // that is incorrect. 4841 AddError(field->full_name(), proto, 4842 DescriptorPool::ErrorCollector::NAME, 4843 "Fields of oneofs must themselves have label LABEL_OPTIONAL."); 4844 } 4845 } 4846 4847 if (proto.has_type_name()) { 4848 // Assume we are expecting a message type unless the proto contains some 4849 // evidence that it expects an enum type. This only makes a difference if 4850 // we end up creating a placeholder. 4851 bool expecting_enum = (proto.type() == FieldDescriptorProto::TYPE_ENUM) || 4852 proto.has_default_value(); 4853 4854 Symbol type = 4855 LookupSymbol(proto.type_name(), field->full_name(), 4856 expecting_enum ? PLACEHOLDER_ENUM : PLACEHOLDER_MESSAGE, 4857 LOOKUP_TYPES); 4858 4859 // If the type is a weak type, we change the type to a google.protobuf.Empty field. 4860 if (type.IsNull() && !pool_->enforce_weak_ && proto.options().weak()) { 4861 type = FindSymbol(kNonLinkedWeakMessageReplacementName); 4862 } 4863 4864 if (type.IsNull()) { 4865 AddNotDefinedError(field->full_name(), proto, 4866 DescriptorPool::ErrorCollector::TYPE, 4867 proto.type_name()); 4868 return; 4869 } 4870 4871 if (!proto.has_type()) { 4872 // Choose field type based on symbol. 4873 if (type.type == Symbol::MESSAGE) { 4874 field->type_ = FieldDescriptor::TYPE_MESSAGE; 4875 } else if (type.type == Symbol::ENUM) { 4876 field->type_ = FieldDescriptor::TYPE_ENUM; 4877 } else { 4878 AddError(field->full_name(), proto, 4879 DescriptorPool::ErrorCollector::TYPE, 4880 "\"" + proto.type_name() + "\" is not a type."); 4881 return; 4882 } 4883 } 4884 4885 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 4886 if (type.type != Symbol::MESSAGE) { 4887 AddError(field->full_name(), proto, 4888 DescriptorPool::ErrorCollector::TYPE, 4889 "\"" + proto.type_name() + "\" is not a message type."); 4890 return; 4891 } 4892 field->message_type_ = type.descriptor; 4893 4894 if (field->has_default_value()) { 4895 AddError(field->full_name(), proto, 4896 DescriptorPool::ErrorCollector::DEFAULT_VALUE, 4897 "Messages can't have default values."); 4898 } 4899 } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { 4900 if (type.type != Symbol::ENUM) { 4901 AddError(field->full_name(), proto, 4902 DescriptorPool::ErrorCollector::TYPE, 4903 "\"" + proto.type_name() + "\" is not an enum type."); 4904 return; 4905 } 4906 field->enum_type_ = type.enum_descriptor; 4907 4908 if (field->enum_type()->is_placeholder_) { 4909 // We can't look up default values for placeholder types. We'll have 4910 // to just drop them. 4911 field->has_default_value_ = false; 4912 } 4913 4914 if (field->has_default_value()) { 4915 // Ensure that the default value is an identifier. Parser cannot always 4916 // verify this because it does not have complete type information. 4917 // N.B. that this check yields better error messages but is not 4918 // necessary for correctness (an enum symbol must be a valid identifier 4919 // anyway), only for better errors. 4920 if (!io::Tokenizer::IsIdentifier(proto.default_value())) { 4921 AddError(field->full_name(), proto, 4922 DescriptorPool::ErrorCollector::DEFAULT_VALUE, 4923 "Default value for an enum field must be an identifier."); 4924 } else { 4925 // We can't just use field->enum_type()->FindValueByName() here 4926 // because that locks the pool's mutex, which we have already locked 4927 // at this point. 4928 Symbol default_value = 4929 LookupSymbolNoPlaceholder(proto.default_value(), 4930 field->enum_type()->full_name()); 4931 4932 if (default_value.type == Symbol::ENUM_VALUE && 4933 default_value.enum_value_descriptor->type() == 4934 field->enum_type()) { 4935 field->default_value_enum_ = default_value.enum_value_descriptor; 4936 } else { 4937 AddError(field->full_name(), proto, 4938 DescriptorPool::ErrorCollector::DEFAULT_VALUE, 4939 "Enum type \"" + field->enum_type()->full_name() + 4940 "\" has no value named \"" + proto.default_value() + 4941 "\"."); 4942 } 4943 } 4944 } else if (field->enum_type()->value_count() > 0) { 4945 // All enums must have at least one value, or we would have reported 4946 // an error elsewhere. We use the first defined value as the default 4947 // if a default is not explicitly defined. 4948 field->default_value_enum_ = field->enum_type()->value(0); 4949 } 4950 } else { 4951 AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, 4952 "Field with primitive type has type_name."); 4953 } 4954 } else { 4955 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE || 4956 field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { 4957 AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, 4958 "Field with message or enum type missing type_name."); 4959 } 4960 } 4961 4962 // Add the field to the fields-by-number table. 4963 // Note: We have to do this *after* cross-linking because extensions do not 4964 // know their containing type until now. 4965 if (!file_tables_->AddFieldByNumber(field)) { 4966 const FieldDescriptor* conflicting_field = 4967 file_tables_->FindFieldByNumber(field->containing_type(), 4968 field->number()); 4969 if (field->is_extension()) { 4970 AddError(field->full_name(), proto, 4971 DescriptorPool::ErrorCollector::NUMBER, 4972 strings::Substitute("Extension number $0 has already been used " 4973 "in \"$1\" by extension \"$2\".", 4974 field->number(), 4975 field->containing_type()->full_name(), 4976 conflicting_field->full_name())); 4977 } else { 4978 AddError(field->full_name(), proto, 4979 DescriptorPool::ErrorCollector::NUMBER, 4980 strings::Substitute("Field number $0 has already been used in " 4981 "\"$1\" by field \"$2\".", 4982 field->number(), 4983 field->containing_type()->full_name(), 4984 conflicting_field->name())); 4985 } 4986 } else { 4987 if (field->is_extension()) { 4988 if (!tables_->AddExtension(field)) { 4989 const FieldDescriptor* conflicting_field = 4990 tables_->FindExtension(field->containing_type(), field->number()); 4991 string error_msg = strings::Substitute( 4992 "Extension number $0 has already been used in \"$1\" by extension " 4993 "\"$2\" defined in $3.", 4994 field->number(), 4995 field->containing_type()->full_name(), 4996 conflicting_field->full_name(), 4997 conflicting_field->file()->name()); 4998 // Conflicting extension numbers should be an error. However, before 4999 // turning this into an error we need to fix all existing broken 5000 // protos first. 5001 // TODO(xiaofeng): Change this to an error. 5002 AddWarning(field->full_name(), proto, 5003 DescriptorPool::ErrorCollector::NUMBER, error_msg); 5004 } 5005 } 5006 } 5007 5008 // Add the field to the lowercase-name and camelcase-name tables. 5009 file_tables_->AddFieldByStylizedNames(field); 5010 } 5011 5012 void DescriptorBuilder::CrossLinkEnum( 5013 EnumDescriptor* enum_type, const EnumDescriptorProto& proto) { 5014 if (enum_type->options_ == NULL) { 5015 enum_type->options_ = &EnumOptions::default_instance(); 5016 } 5017 5018 for (int i = 0; i < enum_type->value_count(); i++) { 5019 CrossLinkEnumValue(&enum_type->values_[i], proto.value(i)); 5020 } 5021 } 5022 5023 void DescriptorBuilder::CrossLinkEnumValue( 5024 EnumValueDescriptor* enum_value, 5025 const EnumValueDescriptorProto& /* proto */) { 5026 if (enum_value->options_ == NULL) { 5027 enum_value->options_ = &EnumValueOptions::default_instance(); 5028 } 5029 } 5030 5031 void DescriptorBuilder::CrossLinkService( 5032 ServiceDescriptor* service, const ServiceDescriptorProto& proto) { 5033 if (service->options_ == NULL) { 5034 service->options_ = &ServiceOptions::default_instance(); 5035 } 5036 5037 for (int i = 0; i < service->method_count(); i++) { 5038 CrossLinkMethod(&service->methods_[i], proto.method(i)); 5039 } 5040 } 5041 5042 void DescriptorBuilder::CrossLinkMethod( 5043 MethodDescriptor* method, const MethodDescriptorProto& proto) { 5044 if (method->options_ == NULL) { 5045 method->options_ = &MethodOptions::default_instance(); 5046 } 5047 5048 Symbol input_type = LookupSymbol(proto.input_type(), method->full_name()); 5049 if (input_type.IsNull()) { 5050 AddNotDefinedError(method->full_name(), proto, 5051 DescriptorPool::ErrorCollector::INPUT_TYPE, 5052 proto.input_type()); 5053 } else if (input_type.type != Symbol::MESSAGE) { 5054 AddError(method->full_name(), proto, 5055 DescriptorPool::ErrorCollector::INPUT_TYPE, 5056 "\"" + proto.input_type() + "\" is not a message type."); 5057 } else { 5058 method->input_type_ = input_type.descriptor; 5059 } 5060 5061 Symbol output_type = LookupSymbol(proto.output_type(), method->full_name()); 5062 if (output_type.IsNull()) { 5063 AddNotDefinedError(method->full_name(), proto, 5064 DescriptorPool::ErrorCollector::OUTPUT_TYPE, 5065 proto.output_type()); 5066 } else if (output_type.type != Symbol::MESSAGE) { 5067 AddError(method->full_name(), proto, 5068 DescriptorPool::ErrorCollector::OUTPUT_TYPE, 5069 "\"" + proto.output_type() + "\" is not a message type."); 5070 } else { 5071 method->output_type_ = output_type.descriptor; 5072 } 5073 } 5074 5075 // ------------------------------------------------------------------- 5076 5077 #define VALIDATE_OPTIONS_FROM_ARRAY(descriptor, array_name, type) \ 5078 for (int i = 0; i < descriptor->array_name##_count(); ++i) { \ 5079 Validate##type##Options(descriptor->array_name##s_ + i, \ 5080 proto.array_name(i)); \ 5081 } 5082 5083 // Determine if the file uses optimize_for = LITE_RUNTIME, being careful to 5084 // avoid problems that exist at init time. 5085 static bool IsLite(const FileDescriptor* file) { 5086 // TODO(kenton): I don't even remember how many of these conditions are 5087 // actually possible. I'm just being super-safe. 5088 return file != NULL && 5089 &file->options() != &FileOptions::default_instance() && 5090 file->options().optimize_for() == FileOptions::LITE_RUNTIME; 5091 } 5092 5093 void DescriptorBuilder::ValidateFileOptions(FileDescriptor* file, 5094 const FileDescriptorProto& proto) { 5095 VALIDATE_OPTIONS_FROM_ARRAY(file, message_type, Message); 5096 VALIDATE_OPTIONS_FROM_ARRAY(file, enum_type, Enum); 5097 VALIDATE_OPTIONS_FROM_ARRAY(file, service, Service); 5098 VALIDATE_OPTIONS_FROM_ARRAY(file, extension, Field); 5099 5100 // Lite files can only be imported by other Lite files. 5101 if (!IsLite(file)) { 5102 for (int i = 0; i < file->dependency_count(); i++) { 5103 if (IsLite(file->dependency(i))) { 5104 AddError( 5105 file->name(), proto, 5106 DescriptorPool::ErrorCollector::OTHER, 5107 "Files that do not use optimize_for = LITE_RUNTIME cannot import " 5108 "files which do use this option. This file is not lite, but it " 5109 "imports \"" + file->dependency(i)->name() + "\" which is."); 5110 break; 5111 } 5112 } 5113 } 5114 if (file->syntax() == FileDescriptor::SYNTAX_PROTO3) { 5115 ValidateProto3(file, proto); 5116 } 5117 } 5118 5119 void DescriptorBuilder::ValidateProto3( 5120 FileDescriptor* file, const FileDescriptorProto& proto) { 5121 for (int i = 0; i < file->extension_count(); ++i) { 5122 ValidateProto3Field(file->extensions_ + i, proto.extension(i)); 5123 } 5124 for (int i = 0; i < file->message_type_count(); ++i) { 5125 ValidateProto3Message(file->message_types_ + i, proto.message_type(i)); 5126 } 5127 for (int i = 0; i < file->enum_type_count(); ++i) { 5128 ValidateProto3Enum(file->enum_types_ + i, proto.enum_type(i)); 5129 } 5130 } 5131 5132 static string ToLowercaseWithoutUnderscores(const string& name) { 5133 string result; 5134 for (int i = 0; i < name.size(); ++i) { 5135 if (name[i] != '_') { 5136 if (name[i] >= 'A' && name[i] <= 'Z') { 5137 result.push_back(name[i] - 'A' + 'a'); 5138 } else { 5139 result.push_back(name[i]); 5140 } 5141 } 5142 } 5143 return result; 5144 } 5145 5146 void DescriptorBuilder::ValidateProto3Message( 5147 Descriptor* message, const DescriptorProto& proto) { 5148 for (int i = 0; i < message->nested_type_count(); ++i) { 5149 ValidateProto3Message(message->nested_types_ + i, 5150 proto.nested_type(i)); 5151 } 5152 for (int i = 0; i < message->enum_type_count(); ++i) { 5153 ValidateProto3Enum(message->enum_types_ + i, 5154 proto.enum_type(i)); 5155 } 5156 for (int i = 0; i < message->field_count(); ++i) { 5157 ValidateProto3Field(message->fields_ + i, proto.field(i)); 5158 } 5159 for (int i = 0; i < message->extension_count(); ++i) { 5160 ValidateProto3Field(message->extensions_ +i, proto.extension(i)); 5161 } 5162 if (message->extension_range_count() > 0) { 5163 AddError(message->full_name(), proto, 5164 DescriptorPool::ErrorCollector::OTHER, 5165 "Extension ranges are not allowed in proto3."); 5166 } 5167 if (message->options().message_set_wire_format()) { 5168 // Using MessageSet doesn't make sense since we disallow extensions. 5169 AddError(message->full_name(), proto, 5170 DescriptorPool::ErrorCollector::OTHER, 5171 "MessageSet is not supported in proto3."); 5172 } 5173 5174 // In proto3, we reject field names if they conflict in camelCase. 5175 // Note that we currently enforce a stricter rule: Field names must be 5176 // unique after being converted to lowercase with underscores removed. 5177 map<string, const FieldDescriptor*> name_to_field; 5178 for (int i = 0; i < message->field_count(); ++i) { 5179 string lowercase_name = ToLowercaseWithoutUnderscores( 5180 message->field(i)->name()); 5181 if (name_to_field.find(lowercase_name) != name_to_field.end()) { 5182 AddError(message->full_name(), proto, 5183 DescriptorPool::ErrorCollector::OTHER, 5184 "The JSON camcel-case name of field \"" + 5185 message->field(i)->name() + "\" conflicts with field \"" + 5186 name_to_field[lowercase_name]->name() + "\". This is not " + 5187 "allowed in proto3."); 5188 } else { 5189 name_to_field[lowercase_name] = message->field(i); 5190 } 5191 } 5192 } 5193 5194 void DescriptorBuilder::ValidateProto3Field( 5195 FieldDescriptor* field, const FieldDescriptorProto& proto) { 5196 if (field->is_extension() && 5197 !AllowedExtendeeInProto3(field->containing_type()->full_name())) { 5198 AddError(field->full_name(), proto, 5199 DescriptorPool::ErrorCollector::OTHER, 5200 "Extensions in proto3 are only allowed for defining options."); 5201 } 5202 if (field->is_required()) { 5203 AddError(field->full_name(), proto, 5204 DescriptorPool::ErrorCollector::OTHER, 5205 "Required fields are not allowed in proto3."); 5206 } 5207 if (field->has_default_value()) { 5208 AddError( 5209 field->full_name(), proto, DescriptorPool::ErrorCollector::OTHER, 5210 "Explicit default values are not allowed in proto3."); 5211 } 5212 if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM && 5213 field->enum_type() && 5214 field->enum_type()->file()->syntax() != FileDescriptor::SYNTAX_PROTO3) { 5215 // Proto3 messages can only use Proto3 enum types; otherwise we can't 5216 // guarantee that the default value is zero. 5217 AddError(field->full_name(), proto, 5218 DescriptorPool::ErrorCollector::TYPE, 5219 "Enum type \"" + field->enum_type()->full_name() + 5220 "\" is not a proto3 enum, but is used in \"" + 5221 field->containing_type()->full_name() + 5222 "\" which is a proto3 message type."); 5223 } 5224 if (field->type() == FieldDescriptor::TYPE_GROUP) { 5225 AddError(field->full_name(), proto, 5226 DescriptorPool::ErrorCollector::TYPE, 5227 "Groups are not supported in proto3 syntax."); 5228 } 5229 } 5230 5231 void DescriptorBuilder::ValidateProto3Enum( 5232 EnumDescriptor* enm, const EnumDescriptorProto& proto) { 5233 if (enm->value_count() > 0 && enm->value(0)->number() != 0) { 5234 AddError( 5235 enm->full_name(), proto, DescriptorPool::ErrorCollector::OTHER, 5236 "The first enum value must be zero in proto3."); 5237 } 5238 } 5239 5240 void DescriptorBuilder::ValidateMessageOptions(Descriptor* message, 5241 const DescriptorProto& proto) { 5242 VALIDATE_OPTIONS_FROM_ARRAY(message, field, Field); 5243 VALIDATE_OPTIONS_FROM_ARRAY(message, nested_type, Message); 5244 VALIDATE_OPTIONS_FROM_ARRAY(message, enum_type, Enum); 5245 VALIDATE_OPTIONS_FROM_ARRAY(message, extension, Field); 5246 5247 const int64 max_extension_range = 5248 static_cast<int64>(message->options().message_set_wire_format() ? 5249 kint32max : 5250 FieldDescriptor::kMaxNumber); 5251 for (int i = 0; i < message->extension_range_count(); ++i) { 5252 if (message->extension_range(i)->end > max_extension_range + 1) { 5253 AddError( 5254 message->full_name(), proto.extension_range(i), 5255 DescriptorPool::ErrorCollector::NUMBER, 5256 strings::Substitute("Extension numbers cannot be greater than $0.", 5257 max_extension_range)); 5258 } 5259 } 5260 } 5261 5262 void DescriptorBuilder::ValidateFieldOptions(FieldDescriptor* field, 5263 const FieldDescriptorProto& proto) { 5264 // Only message type fields may be lazy. 5265 if (field->options().lazy()) { 5266 if (field->type() != FieldDescriptor::TYPE_MESSAGE) { 5267 AddError(field->full_name(), proto, 5268 DescriptorPool::ErrorCollector::TYPE, 5269 "[lazy = true] can only be specified for submessage fields."); 5270 } 5271 } 5272 5273 // Only repeated primitive fields may be packed. 5274 if (field->options().packed() && !field->is_packable()) { 5275 AddError( 5276 field->full_name(), proto, 5277 DescriptorPool::ErrorCollector::TYPE, 5278 "[packed = true] can only be specified for repeated primitive fields."); 5279 } 5280 5281 // Note: Default instance may not yet be initialized here, so we have to 5282 // avoid reading from it. 5283 if (field->containing_type_ != NULL && 5284 &field->containing_type()->options() != 5285 &MessageOptions::default_instance() && 5286 field->containing_type()->options().message_set_wire_format()) { 5287 if (field->is_extension()) { 5288 if (!field->is_optional() || 5289 field->type() != FieldDescriptor::TYPE_MESSAGE) { 5290 AddError(field->full_name(), proto, 5291 DescriptorPool::ErrorCollector::TYPE, 5292 "Extensions of MessageSets must be optional messages."); 5293 } 5294 } else { 5295 AddError(field->full_name(), proto, 5296 DescriptorPool::ErrorCollector::NAME, 5297 "MessageSets cannot have fields, only extensions."); 5298 } 5299 } 5300 5301 // Lite extensions can only be of Lite types. 5302 if (IsLite(field->file()) && 5303 field->containing_type_ != NULL && 5304 !IsLite(field->containing_type()->file())) { 5305 AddError(field->full_name(), proto, 5306 DescriptorPool::ErrorCollector::EXTENDEE, 5307 "Extensions to non-lite types can only be declared in non-lite " 5308 "files. Note that you cannot extend a non-lite type to contain " 5309 "a lite type, but the reverse is allowed."); 5310 } 5311 5312 // Validate map types. 5313 if (field->is_map()) { 5314 if (!ValidateMapEntry(field, proto)) { 5315 AddError(field->full_name(), proto, 5316 DescriptorPool::ErrorCollector::OTHER, 5317 "map_entry should not be set explicitly. Use map<KeyType, " 5318 "ValueType> instead."); 5319 } 5320 } 5321 5322 } 5323 5324 void DescriptorBuilder::ValidateEnumOptions(EnumDescriptor* enm, 5325 const EnumDescriptorProto& proto) { 5326 VALIDATE_OPTIONS_FROM_ARRAY(enm, value, EnumValue); 5327 if (!enm->options().has_allow_alias() || !enm->options().allow_alias()) { 5328 map<int, string> used_values; 5329 for (int i = 0; i < enm->value_count(); ++i) { 5330 const EnumValueDescriptor* enum_value = enm->value(i); 5331 if (used_values.find(enum_value->number()) != used_values.end()) { 5332 string error = 5333 "\"" + enum_value->full_name() + 5334 "\" uses the same enum value as \"" + 5335 used_values[enum_value->number()] + "\". If this is intended, set " 5336 "'option allow_alias = true;' to the enum definition."; 5337 if (!enm->options().allow_alias()) { 5338 // Generate error if duplicated enum values are explicitly disallowed. 5339 AddError(enm->full_name(), proto, 5340 DescriptorPool::ErrorCollector::NUMBER, 5341 error); 5342 } else { 5343 // Generate warning if duplicated values are found but the option 5344 // isn't set. 5345 GOOGLE_LOG(ERROR) << error; 5346 } 5347 } else { 5348 used_values[enum_value->number()] = enum_value->full_name(); 5349 } 5350 } 5351 } 5352 } 5353 5354 void DescriptorBuilder::ValidateEnumValueOptions( 5355 EnumValueDescriptor* /* enum_value */, 5356 const EnumValueDescriptorProto& /* proto */) { 5357 // Nothing to do so far. 5358 } 5359 void DescriptorBuilder::ValidateServiceOptions(ServiceDescriptor* service, 5360 const ServiceDescriptorProto& proto) { 5361 if (IsLite(service->file()) && 5362 (service->file()->options().cc_generic_services() || 5363 service->file()->options().java_generic_services())) { 5364 AddError(service->full_name(), proto, 5365 DescriptorPool::ErrorCollector::NAME, 5366 "Files with optimize_for = LITE_RUNTIME cannot define services " 5367 "unless you set both options cc_generic_services and " 5368 "java_generic_sevices to false."); 5369 } 5370 5371 VALIDATE_OPTIONS_FROM_ARRAY(service, method, Method); 5372 } 5373 5374 void DescriptorBuilder::ValidateMethodOptions(MethodDescriptor* /* method */, 5375 const MethodDescriptorProto& /* proto */) { 5376 // Nothing to do so far. 5377 } 5378 5379 bool DescriptorBuilder::ValidateMapEntry(FieldDescriptor* field, 5380 const FieldDescriptorProto& proto) { 5381 const Descriptor* message = field->message_type(); 5382 if (// Must not contain extensions, extension range or nested message or 5383 // enums 5384 message->extension_count() != 0 || 5385 field->label() != FieldDescriptor::LABEL_REPEATED || 5386 message->extension_range_count() != 0 || 5387 message->nested_type_count() != 0 || message->enum_type_count() != 0 || 5388 // Must contain exactly two fields 5389 message->field_count() != 2 || 5390 // Field name and message name must match 5391 message->name() != ToCamelCase(field->name(), false) + "Entry" || 5392 // Entry message must be in the same containing type of the field. 5393 field->containing_type() != message->containing_type()) { 5394 return false; 5395 } 5396 5397 const FieldDescriptor* key = message->field(0); 5398 const FieldDescriptor* value = message->field(1); 5399 if (key->label() != FieldDescriptor::LABEL_OPTIONAL || key->number() != 1 || 5400 key->name() != "key") { 5401 return false; 5402 } 5403 if (value->label() != FieldDescriptor::LABEL_OPTIONAL || 5404 value->number() != 2 || value->name() != "value") { 5405 return false; 5406 } 5407 5408 // Check key types are legal. 5409 switch (key->type()) { 5410 case FieldDescriptor::TYPE_ENUM: 5411 AddError( 5412 field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, 5413 "Key in map fields cannot be enum types."); 5414 break; 5415 case FieldDescriptor::TYPE_FLOAT: 5416 case FieldDescriptor::TYPE_DOUBLE: 5417 case FieldDescriptor::TYPE_MESSAGE: 5418 case FieldDescriptor::TYPE_GROUP: 5419 case FieldDescriptor::TYPE_BYTES: 5420 AddError( 5421 field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, 5422 "Key in map fields cannot be float/double, bytes or message types."); 5423 break; 5424 case FieldDescriptor::TYPE_BOOL: 5425 case FieldDescriptor::TYPE_INT32: 5426 case FieldDescriptor::TYPE_INT64: 5427 case FieldDescriptor::TYPE_SINT32: 5428 case FieldDescriptor::TYPE_SINT64: 5429 case FieldDescriptor::TYPE_STRING: 5430 case FieldDescriptor::TYPE_UINT32: 5431 case FieldDescriptor::TYPE_UINT64: 5432 case FieldDescriptor::TYPE_FIXED32: 5433 case FieldDescriptor::TYPE_FIXED64: 5434 case FieldDescriptor::TYPE_SFIXED32: 5435 case FieldDescriptor::TYPE_SFIXED64: 5436 // Legal cases 5437 break; 5438 // Do not add a default, so that the compiler will complain when new types 5439 // are added. 5440 } 5441 5442 if (value->type() == FieldDescriptor::TYPE_ENUM) { 5443 if (value->enum_type()->value(0)->number() != 0) { 5444 AddError( 5445 field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, 5446 "Enum value in map must define 0 as the first value."); 5447 } 5448 } 5449 5450 return true; 5451 } 5452 5453 void DescriptorBuilder::DetectMapConflicts(const Descriptor* message, 5454 const DescriptorProto& proto) { 5455 map<string, const Descriptor*> seen_types; 5456 for (int i = 0; i < message->nested_type_count(); ++i) { 5457 const Descriptor* nested = message->nested_type(i); 5458 pair<map<string, const Descriptor*>::iterator, bool> result = 5459 seen_types.insert(std::make_pair(nested->name(), nested)); 5460 if (!result.second) { 5461 if (result.first->second->options().map_entry() || 5462 nested->options().map_entry()) { 5463 AddError(message->full_name(), proto, 5464 DescriptorPool::ErrorCollector::NAME, 5465 "Expanded map entry type " + nested->name() + 5466 " conflicts with an existing nested message type."); 5467 } 5468 } 5469 // Recursively test on the nested types. 5470 DetectMapConflicts(message->nested_type(i), proto.nested_type(i)); 5471 } 5472 // Check for conflicted field names. 5473 for (int i = 0; i < message->field_count(); ++i) { 5474 const FieldDescriptor* field = message->field(i); 5475 map<string, const Descriptor*>::iterator iter = 5476 seen_types.find(field->name()); 5477 if (iter != seen_types.end() && iter->second->options().map_entry()) { 5478 AddError(message->full_name(), proto, 5479 DescriptorPool::ErrorCollector::NAME, 5480 "Expanded map entry type " + iter->second->name() + 5481 " conflicts with an existing field."); 5482 } 5483 } 5484 // Check for conflicted enum names. 5485 for (int i = 0; i < message->enum_type_count(); ++i) { 5486 const EnumDescriptor* enum_desc = message->enum_type(i); 5487 map<string, const Descriptor*>::iterator iter = 5488 seen_types.find(enum_desc->name()); 5489 if (iter != seen_types.end() && iter->second->options().map_entry()) { 5490 AddError(message->full_name(), proto, 5491 DescriptorPool::ErrorCollector::NAME, 5492 "Expanded map entry type " + iter->second->name() + 5493 " conflicts with an existing enum type."); 5494 } 5495 } 5496 // Check for conflicted oneof names. 5497 for (int i = 0; i < message->oneof_decl_count(); ++i) { 5498 const OneofDescriptor* oneof_desc = message->oneof_decl(i); 5499 map<string, const Descriptor*>::iterator iter = 5500 seen_types.find(oneof_desc->name()); 5501 if (iter != seen_types.end() && iter->second->options().map_entry()) { 5502 AddError(message->full_name(), proto, 5503 DescriptorPool::ErrorCollector::NAME, 5504 "Expanded map entry type " + iter->second->name() + 5505 " conflicts with an existing oneof type."); 5506 } 5507 } 5508 } 5509 5510 5511 #undef VALIDATE_OPTIONS_FROM_ARRAY 5512 5513 // ------------------------------------------------------------------- 5514 5515 DescriptorBuilder::OptionInterpreter::OptionInterpreter( 5516 DescriptorBuilder* builder) : builder_(builder) { 5517 GOOGLE_CHECK(builder_); 5518 } 5519 5520 DescriptorBuilder::OptionInterpreter::~OptionInterpreter() { 5521 } 5522 5523 bool DescriptorBuilder::OptionInterpreter::InterpretOptions( 5524 OptionsToInterpret* options_to_interpret) { 5525 // Note that these may be in different pools, so we can't use the same 5526 // descriptor and reflection objects on both. 5527 Message* options = options_to_interpret->options; 5528 const Message* original_options = options_to_interpret->original_options; 5529 5530 bool failed = false; 5531 options_to_interpret_ = options_to_interpret; 5532 5533 // Find the uninterpreted_option field in the mutable copy of the options 5534 // and clear them, since we're about to interpret them. 5535 const FieldDescriptor* uninterpreted_options_field = 5536 options->GetDescriptor()->FindFieldByName("uninterpreted_option"); 5537 GOOGLE_CHECK(uninterpreted_options_field != NULL) 5538 << "No field named \"uninterpreted_option\" in the Options proto."; 5539 options->GetReflection()->ClearField(options, uninterpreted_options_field); 5540 5541 // Find the uninterpreted_option field in the original options. 5542 const FieldDescriptor* original_uninterpreted_options_field = 5543 original_options->GetDescriptor()-> 5544 FindFieldByName("uninterpreted_option"); 5545 GOOGLE_CHECK(original_uninterpreted_options_field != NULL) 5546 << "No field named \"uninterpreted_option\" in the Options proto."; 5547 5548 const int num_uninterpreted_options = original_options->GetReflection()-> 5549 FieldSize(*original_options, original_uninterpreted_options_field); 5550 for (int i = 0; i < num_uninterpreted_options; ++i) { 5551 uninterpreted_option_ = down_cast<const UninterpretedOption*>( 5552 &original_options->GetReflection()->GetRepeatedMessage( 5553 *original_options, original_uninterpreted_options_field, i)); 5554 if (!InterpretSingleOption(options)) { 5555 // Error already added by InterpretSingleOption(). 5556 failed = true; 5557 break; 5558 } 5559 } 5560 // Reset these, so we don't have any dangling pointers. 5561 uninterpreted_option_ = NULL; 5562 options_to_interpret_ = NULL; 5563 5564 if (!failed) { 5565 // InterpretSingleOption() added the interpreted options in the 5566 // UnknownFieldSet, in case the option isn't yet known to us. Now we 5567 // serialize the options message and deserialize it back. That way, any 5568 // option fields that we do happen to know about will get moved from the 5569 // UnknownFieldSet into the real fields, and thus be available right away. 5570 // If they are not known, that's OK too. They will get reparsed into the 5571 // UnknownFieldSet and wait there until the message is parsed by something 5572 // that does know about the options. 5573 string buf; 5574 GOOGLE_CHECK(options->AppendPartialToString(&buf)) 5575 << "Protocol message could not be serialized."; 5576 GOOGLE_CHECK(options->ParsePartialFromString(buf)) 5577 << "Protocol message serialized itself in invalid fashion."; 5578 if (!options->IsInitialized()) { 5579 builder_->AddWarning( 5580 options_to_interpret->element_name, *original_options, 5581 DescriptorPool::ErrorCollector::OTHER, 5582 "Options could not be fully parsed using the proto descriptors " 5583 "compiled into this binary. Missing required fields: " + 5584 options->InitializationErrorString()); 5585 } 5586 } 5587 return !failed; 5588 } 5589 5590 bool DescriptorBuilder::OptionInterpreter::InterpretSingleOption( 5591 Message* options) { 5592 // First do some basic validation. 5593 if (uninterpreted_option_->name_size() == 0) { 5594 // This should never happen unless the parser has gone seriously awry or 5595 // someone has manually created the uninterpreted option badly. 5596 return AddNameError("Option must have a name."); 5597 } 5598 if (uninterpreted_option_->name(0).name_part() == "uninterpreted_option") { 5599 return AddNameError("Option must not use reserved name " 5600 "\"uninterpreted_option\"."); 5601 } 5602 5603 const Descriptor* options_descriptor = NULL; 5604 // Get the options message's descriptor from the builder's pool, so that we 5605 // get the version that knows about any extension options declared in the 5606 // file we're currently building. The descriptor should be there as long as 5607 // the file we're building imported "google/protobuf/descriptors.proto". 5608 5609 // Note that we use DescriptorBuilder::FindSymbolNotEnforcingDeps(), not 5610 // DescriptorPool::FindMessageTypeByName() because we're already holding the 5611 // pool's mutex, and the latter method locks it again. We don't use 5612 // FindSymbol() because files that use custom options only need to depend on 5613 // the file that defines the option, not descriptor.proto itself. 5614 Symbol symbol = builder_->FindSymbolNotEnforcingDeps( 5615 options->GetDescriptor()->full_name()); 5616 if (!symbol.IsNull() && symbol.type == Symbol::MESSAGE) { 5617 options_descriptor = symbol.descriptor; 5618 } else { 5619 // The options message's descriptor was not in the builder's pool, so use 5620 // the standard version from the generated pool. We're not holding the 5621 // generated pool's mutex, so we can search it the straightforward way. 5622 options_descriptor = options->GetDescriptor(); 5623 } 5624 GOOGLE_CHECK(options_descriptor); 5625 5626 // 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 5628 // submessage's descriptor in |descriptor| and the next field in that 5629 // 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 5631 // name in |debug_msg_name|, for use in error messages. 5632 const Descriptor* descriptor = options_descriptor; 5633 const FieldDescriptor* field = NULL; 5634 vector<const FieldDescriptor*> intermediate_fields; 5635 string debug_msg_name = ""; 5636 5637 for (int i = 0; i < uninterpreted_option_->name_size(); ++i) { 5638 const string& name_part = uninterpreted_option_->name(i).name_part(); 5639 if (debug_msg_name.size() > 0) { 5640 debug_msg_name += "."; 5641 } 5642 if (uninterpreted_option_->name(i).is_extension()) { 5643 debug_msg_name += "(" + name_part + ")"; 5644 // Search for the extension's descriptor as an extension in the builder's 5645 // pool. Note that we use DescriptorBuilder::LookupSymbol(), not 5646 // DescriptorPool::FindExtensionByName(), for two reasons: 1) It allows 5647 // relative lookups, and 2) because we're already holding the pool's 5648 // mutex, and the latter method locks it again. 5649 symbol = builder_->LookupSymbol(name_part, 5650 options_to_interpret_->name_scope); 5651 if (!symbol.IsNull() && symbol.type == Symbol::FIELD) { 5652 field = symbol.field_descriptor; 5653 } 5654 // If we don't find the field then the field's descriptor was not in the 5655 // builder's pool, but there's no point in looking in the generated 5656 // pool. We require that you import the file that defines any extensions 5657 // you use, so they must be present in the builder's pool. 5658 } else { 5659 debug_msg_name += name_part; 5660 // Search for the field's descriptor as a regular field. 5661 field = descriptor->FindFieldByName(name_part); 5662 } 5663 5664 if (field == NULL) { 5665 if (get_allow_unknown(builder_->pool_)) { 5666 // We can't find the option, but AllowUnknownDependencies() is enabled, 5667 // so we will just leave it as uninterpreted. 5668 AddWithoutInterpreting(*uninterpreted_option_, options); 5669 return true; 5670 } else if (!(builder_->undefine_resolved_name_).empty()) { 5671 // Option is resolved to a name which is not defined. 5672 return AddNameError( 5673 "Option \"" + debug_msg_name + "\" is resolved to \"(" + 5674 builder_->undefine_resolved_name_ + 5675 ")\", which is not defined. The innermost scope is searched first " 5676 "in name resolution. Consider using a leading '.'(i.e., \"(." + 5677 debug_msg_name.substr(1) + 5678 "\") to start from the outermost scope."); 5679 } else { 5680 return AddNameError("Option \"" + debug_msg_name + "\" unknown."); 5681 } 5682 } else if (field->containing_type() != descriptor) { 5683 if (get_is_placeholder(field->containing_type())) { 5684 // The field is an extension of a placeholder type, so we can't 5685 // reliably verify whether it is a valid extension to use here (e.g. 5686 // we don't know if it is an extension of the correct *Options message, 5687 // or if it has a valid field number, etc.). Just leave it as 5688 // uninterpreted instead. 5689 AddWithoutInterpreting(*uninterpreted_option_, options); 5690 return true; 5691 } else { 5692 // This can only happen if, due to some insane misconfiguration of the 5693 // pools, we find the options message in one pool but the field in 5694 // another. This would probably imply a hefty bug somewhere. 5695 return AddNameError("Option field \"" + debug_msg_name + 5696 "\" is not a field or extension of message \"" + 5697 descriptor->name() + "\"."); 5698 } 5699 } else if (i < uninterpreted_option_->name_size() - 1) { 5700 if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { 5701 return AddNameError("Option \"" + debug_msg_name + 5702 "\" is an atomic type, not a message."); 5703 } else if (field->is_repeated()) { 5704 return AddNameError("Option field \"" + debug_msg_name + 5705 "\" is a repeated message. Repeated message " 5706 "options must be initialized using an " 5707 "aggregate value."); 5708 } else { 5709 // Drill down into the submessage. 5710 intermediate_fields.push_back(field); 5711 descriptor = field->message_type(); 5712 } 5713 } 5714 } 5715 5716 // We've found the leaf field. Now we use UnknownFieldSets to set its value 5717 // on the options message. We do so because the message may not yet know 5718 // about its extension fields, so we may not be able to set the fields 5719 // directly. But the UnknownFieldSets will serialize to the same wire-format 5720 // message, so reading that message back in once the extension fields are 5721 // known will populate them correctly. 5722 5723 // First see if the option is already set. 5724 if (!field->is_repeated() && !ExamineIfOptionIsSet( 5725 intermediate_fields.begin(), 5726 intermediate_fields.end(), 5727 field, debug_msg_name, 5728 options->GetReflection()->GetUnknownFields(*options))) { 5729 return false; // ExamineIfOptionIsSet() already added the error. 5730 } 5731 5732 5733 // First set the value on the UnknownFieldSet corresponding to the 5734 // innermost message. 5735 google::protobuf::scoped_ptr<UnknownFieldSet> unknown_fields(new UnknownFieldSet()); 5736 if (!SetOptionValue(field, unknown_fields.get())) { 5737 return false; // SetOptionValue() already added the error. 5738 } 5739 5740 // Now wrap the UnknownFieldSet with UnknownFieldSets corresponding to all 5741 // the intermediate messages. 5742 for (vector<const FieldDescriptor*>::reverse_iterator iter = 5743 intermediate_fields.rbegin(); 5744 iter != intermediate_fields.rend(); ++iter) { 5745 google::protobuf::scoped_ptr<UnknownFieldSet> parent_unknown_fields( 5746 new UnknownFieldSet()); 5747 switch ((*iter)->type()) { 5748 case FieldDescriptor::TYPE_MESSAGE: { 5749 io::StringOutputStream outstr( 5750 parent_unknown_fields->AddLengthDelimited((*iter)->number())); 5751 io::CodedOutputStream out(&outstr); 5752 internal::WireFormat::SerializeUnknownFields(*unknown_fields, &out); 5753 GOOGLE_CHECK(!out.HadError()) 5754 << "Unexpected failure while serializing option submessage " 5755 << debug_msg_name << "\"."; 5756 break; 5757 } 5758 5759 case FieldDescriptor::TYPE_GROUP: { 5760 parent_unknown_fields->AddGroup((*iter)->number()) 5761 ->MergeFrom(*unknown_fields); 5762 break; 5763 } 5764 5765 default: 5766 GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: " 5767 << (*iter)->type(); 5768 return false; 5769 } 5770 unknown_fields.reset(parent_unknown_fields.release()); 5771 } 5772 5773 // Now merge the UnknownFieldSet corresponding to the top-level message into 5774 // the options message. 5775 options->GetReflection()->MutableUnknownFields(options)->MergeFrom( 5776 *unknown_fields); 5777 5778 return true; 5779 } 5780 5781 void DescriptorBuilder::OptionInterpreter::AddWithoutInterpreting( 5782 const UninterpretedOption& uninterpreted_option, Message* options) { 5783 const FieldDescriptor* field = 5784 options->GetDescriptor()->FindFieldByName("uninterpreted_option"); 5785 GOOGLE_CHECK(field != NULL); 5786 5787 options->GetReflection()->AddMessage(options, field) 5788 ->CopyFrom(uninterpreted_option); 5789 } 5790 5791 bool DescriptorBuilder::OptionInterpreter::ExamineIfOptionIsSet( 5792 vector<const FieldDescriptor*>::const_iterator intermediate_fields_iter, 5793 vector<const FieldDescriptor*>::const_iterator intermediate_fields_end, 5794 const FieldDescriptor* innermost_field, const string& debug_msg_name, 5795 const UnknownFieldSet& unknown_fields) { 5796 // 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 5798 // contain more than a handful of options. 5799 5800 if (intermediate_fields_iter == intermediate_fields_end) { 5801 // We're at the innermost submessage. 5802 for (int i = 0; i < unknown_fields.field_count(); i++) { 5803 if (unknown_fields.field(i).number() == innermost_field->number()) { 5804 return AddNameError("Option \"" + debug_msg_name + 5805 "\" was already set."); 5806 } 5807 } 5808 return true; 5809 } 5810 5811 for (int i = 0; i < unknown_fields.field_count(); i++) { 5812 if (unknown_fields.field(i).number() == 5813 (*intermediate_fields_iter)->number()) { 5814 const UnknownField* unknown_field = &unknown_fields.field(i); 5815 FieldDescriptor::Type type = (*intermediate_fields_iter)->type(); 5816 // Recurse into the next submessage. 5817 switch (type) { 5818 case FieldDescriptor::TYPE_MESSAGE: 5819 if (unknown_field->type() == UnknownField::TYPE_LENGTH_DELIMITED) { 5820 UnknownFieldSet intermediate_unknown_fields; 5821 if (intermediate_unknown_fields.ParseFromString( 5822 unknown_field->length_delimited()) && 5823 !ExamineIfOptionIsSet(intermediate_fields_iter + 1, 5824 intermediate_fields_end, 5825 innermost_field, debug_msg_name, 5826 intermediate_unknown_fields)) { 5827 return false; // Error already added. 5828 } 5829 } 5830 break; 5831 5832 case FieldDescriptor::TYPE_GROUP: 5833 if (unknown_field->type() == UnknownField::TYPE_GROUP) { 5834 if (!ExamineIfOptionIsSet(intermediate_fields_iter + 1, 5835 intermediate_fields_end, 5836 innermost_field, debug_msg_name, 5837 unknown_field->group())) { 5838 return false; // Error already added. 5839 } 5840 } 5841 break; 5842 5843 default: 5844 GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: " << type; 5845 return false; 5846 } 5847 } 5848 } 5849 return true; 5850 } 5851 5852 bool DescriptorBuilder::OptionInterpreter::SetOptionValue( 5853 const FieldDescriptor* option_field, 5854 UnknownFieldSet* unknown_fields) { 5855 // We switch on the CppType to validate. 5856 switch (option_field->cpp_type()) { 5857 5858 case FieldDescriptor::CPPTYPE_INT32: 5859 if (uninterpreted_option_->has_positive_int_value()) { 5860 if (uninterpreted_option_->positive_int_value() > 5861 static_cast<uint64>(kint32max)) { 5862 return AddValueError("Value out of range for int32 option \"" + 5863 option_field->full_name() + "\"."); 5864 } else { 5865 SetInt32(option_field->number(), 5866 uninterpreted_option_->positive_int_value(), 5867 option_field->type(), unknown_fields); 5868 } 5869 } else if (uninterpreted_option_->has_negative_int_value()) { 5870 if (uninterpreted_option_->negative_int_value() < 5871 static_cast<int64>(kint32min)) { 5872 return AddValueError("Value out of range for int32 option \"" + 5873 option_field->full_name() + "\"."); 5874 } else { 5875 SetInt32(option_field->number(), 5876 uninterpreted_option_->negative_int_value(), 5877 option_field->type(), unknown_fields); 5878 } 5879 } else { 5880 return AddValueError("Value must be integer for int32 option \"" + 5881 option_field->full_name() + "\"."); 5882 } 5883 break; 5884 5885 case FieldDescriptor::CPPTYPE_INT64: 5886 if (uninterpreted_option_->has_positive_int_value()) { 5887 if (uninterpreted_option_->positive_int_value() > 5888 static_cast<uint64>(kint64max)) { 5889 return AddValueError("Value out of range for int64 option \"" + 5890 option_field->full_name() + "\"."); 5891 } else { 5892 SetInt64(option_field->number(), 5893 uninterpreted_option_->positive_int_value(), 5894 option_field->type(), unknown_fields); 5895 } 5896 } else if (uninterpreted_option_->has_negative_int_value()) { 5897 SetInt64(option_field->number(), 5898 uninterpreted_option_->negative_int_value(), 5899 option_field->type(), unknown_fields); 5900 } else { 5901 return AddValueError("Value must be integer for int64 option \"" + 5902 option_field->full_name() + "\"."); 5903 } 5904 break; 5905 5906 case FieldDescriptor::CPPTYPE_UINT32: 5907 if (uninterpreted_option_->has_positive_int_value()) { 5908 if (uninterpreted_option_->positive_int_value() > kuint32max) { 5909 return AddValueError("Value out of range for uint32 option \"" + 5910 option_field->name() + "\"."); 5911 } else { 5912 SetUInt32(option_field->number(), 5913 uninterpreted_option_->positive_int_value(), 5914 option_field->type(), unknown_fields); 5915 } 5916 } else { 5917 return AddValueError("Value must be non-negative integer for uint32 " 5918 "option \"" + option_field->full_name() + "\"."); 5919 } 5920 break; 5921 5922 case FieldDescriptor::CPPTYPE_UINT64: 5923 if (uninterpreted_option_->has_positive_int_value()) { 5924 SetUInt64(option_field->number(), 5925 uninterpreted_option_->positive_int_value(), 5926 option_field->type(), unknown_fields); 5927 } else { 5928 return AddValueError("Value must be non-negative integer for uint64 " 5929 "option \"" + option_field->full_name() + "\"."); 5930 } 5931 break; 5932 5933 case FieldDescriptor::CPPTYPE_FLOAT: { 5934 float value; 5935 if (uninterpreted_option_->has_double_value()) { 5936 value = uninterpreted_option_->double_value(); 5937 } else if (uninterpreted_option_->has_positive_int_value()) { 5938 value = uninterpreted_option_->positive_int_value(); 5939 } else if (uninterpreted_option_->has_negative_int_value()) { 5940 value = uninterpreted_option_->negative_int_value(); 5941 } else { 5942 return AddValueError("Value must be number for float option \"" + 5943 option_field->full_name() + "\"."); 5944 } 5945 unknown_fields->AddFixed32(option_field->number(), 5946 google::protobuf::internal::WireFormatLite::EncodeFloat(value)); 5947 break; 5948 } 5949 5950 case FieldDescriptor::CPPTYPE_DOUBLE: { 5951 double value; 5952 if (uninterpreted_option_->has_double_value()) { 5953 value = uninterpreted_option_->double_value(); 5954 } else if (uninterpreted_option_->has_positive_int_value()) { 5955 value = uninterpreted_option_->positive_int_value(); 5956 } else if (uninterpreted_option_->has_negative_int_value()) { 5957 value = uninterpreted_option_->negative_int_value(); 5958 } else { 5959 return AddValueError("Value must be number for double option \"" + 5960 option_field->full_name() + "\"."); 5961 } 5962 unknown_fields->AddFixed64(option_field->number(), 5963 google::protobuf::internal::WireFormatLite::EncodeDouble(value)); 5964 break; 5965 } 5966 5967 case FieldDescriptor::CPPTYPE_BOOL: 5968 uint64 value; 5969 if (!uninterpreted_option_->has_identifier_value()) { 5970 return AddValueError("Value must be identifier for boolean option " 5971 "\"" + option_field->full_name() + "\"."); 5972 } 5973 if (uninterpreted_option_->identifier_value() == "true") { 5974 value = 1; 5975 } else if (uninterpreted_option_->identifier_value() == "false") { 5976 value = 0; 5977 } else { 5978 return AddValueError("Value must be \"true\" or \"false\" for boolean " 5979 "option \"" + option_field->full_name() + "\"."); 5980 } 5981 unknown_fields->AddVarint(option_field->number(), value); 5982 break; 5983 5984 case FieldDescriptor::CPPTYPE_ENUM: { 5985 if (!uninterpreted_option_->has_identifier_value()) { 5986 return AddValueError("Value must be identifier for enum-valued option " 5987 "\"" + option_field->full_name() + "\"."); 5988 } 5989 const EnumDescriptor* enum_type = option_field->enum_type(); 5990 const string& value_name = uninterpreted_option_->identifier_value(); 5991 const EnumValueDescriptor* enum_value = NULL; 5992 5993 if (enum_type->file()->pool() != DescriptorPool::generated_pool()) { 5994 // Note that the enum value's fully-qualified name is a sibling of the 5995 // enum's name, not a child of it. 5996 string fully_qualified_name = enum_type->full_name(); 5997 fully_qualified_name.resize(fully_qualified_name.size() - 5998 enum_type->name().size()); 5999 fully_qualified_name += value_name; 6000 6001 // Search for the enum value's descriptor in the builder's pool. Note 6002 // that we use DescriptorBuilder::FindSymbolNotEnforcingDeps(), not 6003 // DescriptorPool::FindEnumValueByName() because we're already holding 6004 // the pool's mutex, and the latter method locks it again. 6005 Symbol symbol = 6006 builder_->FindSymbolNotEnforcingDeps(fully_qualified_name); 6007 if (!symbol.IsNull() && symbol.type == Symbol::ENUM_VALUE) { 6008 if (symbol.enum_value_descriptor->type() != enum_type) { 6009 return AddValueError("Enum type \"" + enum_type->full_name() + 6010 "\" has no value named \"" + value_name + "\" for option \"" + 6011 option_field->full_name() + 6012 "\". This appears to be a value from a sibling type."); 6013 } else { 6014 enum_value = symbol.enum_value_descriptor; 6015 } 6016 } 6017 } else { 6018 // The enum type is in the generated pool, so we can search for the 6019 // value there. 6020 enum_value = enum_type->FindValueByName(value_name); 6021 } 6022 6023 if (enum_value == NULL) { 6024 return AddValueError("Enum type \"" + 6025 option_field->enum_type()->full_name() + 6026 "\" has no value named \"" + value_name + "\" for " 6027 "option \"" + option_field->full_name() + "\"."); 6028 } else { 6029 // Sign-extension is not a problem, since we cast directly from int32 to 6030 // uint64, without first going through uint32. 6031 unknown_fields->AddVarint(option_field->number(), 6032 static_cast<uint64>(static_cast<int64>(enum_value->number()))); 6033 } 6034 break; 6035 } 6036 6037 case FieldDescriptor::CPPTYPE_STRING: 6038 if (!uninterpreted_option_->has_string_value()) { 6039 return AddValueError("Value must be quoted string for string option " 6040 "\"" + option_field->full_name() + "\"."); 6041 } 6042 // The string has already been unquoted and unescaped by the parser. 6043 unknown_fields->AddLengthDelimited(option_field->number(), 6044 uninterpreted_option_->string_value()); 6045 break; 6046 6047 case FieldDescriptor::CPPTYPE_MESSAGE: 6048 if (!SetAggregateOption(option_field, unknown_fields)) { 6049 return false; 6050 } 6051 break; 6052 } 6053 6054 return true; 6055 } 6056 6057 class DescriptorBuilder::OptionInterpreter::AggregateOptionFinder 6058 : public TextFormat::Finder { 6059 public: 6060 DescriptorBuilder* builder_; 6061 6062 virtual const FieldDescriptor* FindExtension( 6063 Message* message, const string& name) const { 6064 assert_mutex_held(builder_->pool_); 6065 const Descriptor* descriptor = message->GetDescriptor(); 6066 Symbol result = builder_->LookupSymbolNoPlaceholder( 6067 name, descriptor->full_name()); 6068 if (result.type == Symbol::FIELD && 6069 result.field_descriptor->is_extension()) { 6070 return result.field_descriptor; 6071 } else if (result.type == Symbol::MESSAGE && 6072 descriptor->options().message_set_wire_format()) { 6073 const Descriptor* foreign_type = result.descriptor; 6074 // The text format allows MessageSet items to be specified using 6075 // the type name, rather than the extension identifier. If the symbol 6076 // lookup returned a Message, and the enclosing Message has 6077 // message_set_wire_format = true, then return the message set 6078 // extension, if one exists. 6079 for (int i = 0; i < foreign_type->extension_count(); i++) { 6080 const FieldDescriptor* extension = foreign_type->extension(i); 6081 if (extension->containing_type() == descriptor && 6082 extension->type() == FieldDescriptor::TYPE_MESSAGE && 6083 extension->is_optional() && 6084 extension->message_type() == foreign_type) { 6085 // Found it. 6086 return extension; 6087 } 6088 } 6089 } 6090 return NULL; 6091 } 6092 }; 6093 6094 // A custom error collector to record any text-format parsing errors 6095 namespace { 6096 class AggregateErrorCollector : public io::ErrorCollector { 6097 public: 6098 string error_; 6099 6100 virtual void AddError(int /* line */, int /* column */, 6101 const string& message) { 6102 if (!error_.empty()) { 6103 error_ += "; "; 6104 } 6105 error_ += message; 6106 } 6107 6108 virtual void AddWarning(int /* line */, int /* column */, 6109 const string& /* message */) { 6110 // Ignore warnings 6111 } 6112 }; 6113 } 6114 6115 // We construct a dynamic message of the type corresponding to 6116 // option_field, parse the supplied text-format string into this 6117 // message, and serialize the resulting message to produce the value. 6118 bool DescriptorBuilder::OptionInterpreter::SetAggregateOption( 6119 const FieldDescriptor* option_field, 6120 UnknownFieldSet* unknown_fields) { 6121 if (!uninterpreted_option_->has_aggregate_value()) { 6122 return AddValueError("Option \"" + option_field->full_name() + 6123 "\" is a message. To set the entire message, use " 6124 "syntax like \"" + option_field->name() + 6125 " = { <proto text format> }\". " 6126 "To set fields within it, use " 6127 "syntax like \"" + option_field->name() + 6128 ".foo = value\"."); 6129 } 6130 6131 const Descriptor* type = option_field->message_type(); 6132 google::protobuf::scoped_ptr<Message> dynamic(dynamic_factory_.GetPrototype(type)->New()); 6133 GOOGLE_CHECK(dynamic.get() != NULL) 6134 << "Could not create an instance of " << option_field->DebugString(); 6135 6136 AggregateErrorCollector collector; 6137 AggregateOptionFinder finder; 6138 finder.builder_ = builder_; 6139 TextFormat::Parser parser; 6140 parser.RecordErrorsTo(&collector); 6141 parser.SetFinder(&finder); 6142 if (!parser.ParseFromString(uninterpreted_option_->aggregate_value(), 6143 dynamic.get())) { 6144 AddValueError("Error while parsing option value for \"" + 6145 option_field->name() + "\": " + collector.error_); 6146 return false; 6147 } else { 6148 string serial; 6149 dynamic->SerializeToString(&serial); // Never fails 6150 if (option_field->type() == FieldDescriptor::TYPE_MESSAGE) { 6151 unknown_fields->AddLengthDelimited(option_field->number(), serial); 6152 } else { 6153 GOOGLE_CHECK_EQ(option_field->type(), FieldDescriptor::TYPE_GROUP); 6154 UnknownFieldSet* group = unknown_fields->AddGroup(option_field->number()); 6155 group->ParseFromString(serial); 6156 } 6157 return true; 6158 } 6159 } 6160 6161 void DescriptorBuilder::OptionInterpreter::SetInt32(int number, int32 value, 6162 FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) { 6163 switch (type) { 6164 case FieldDescriptor::TYPE_INT32: 6165 unknown_fields->AddVarint(number, 6166 static_cast<uint64>(static_cast<int64>(value))); 6167 break; 6168 6169 case FieldDescriptor::TYPE_SFIXED32: 6170 unknown_fields->AddFixed32(number, static_cast<uint32>(value)); 6171 break; 6172 6173 case FieldDescriptor::TYPE_SINT32: 6174 unknown_fields->AddVarint(number, 6175 google::protobuf::internal::WireFormatLite::ZigZagEncode32(value)); 6176 break; 6177 6178 default: 6179 GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT32: " << type; 6180 break; 6181 } 6182 } 6183 6184 void DescriptorBuilder::OptionInterpreter::SetInt64(int number, int64 value, 6185 FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) { 6186 switch (type) { 6187 case FieldDescriptor::TYPE_INT64: 6188 unknown_fields->AddVarint(number, static_cast<uint64>(value)); 6189 break; 6190 6191 case FieldDescriptor::TYPE_SFIXED64: 6192 unknown_fields->AddFixed64(number, static_cast<uint64>(value)); 6193 break; 6194 6195 case FieldDescriptor::TYPE_SINT64: 6196 unknown_fields->AddVarint(number, 6197 google::protobuf::internal::WireFormatLite::ZigZagEncode64(value)); 6198 break; 6199 6200 default: 6201 GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT64: " << type; 6202 break; 6203 } 6204 } 6205 6206 void DescriptorBuilder::OptionInterpreter::SetUInt32(int number, uint32 value, 6207 FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) { 6208 switch (type) { 6209 case FieldDescriptor::TYPE_UINT32: 6210 unknown_fields->AddVarint(number, static_cast<uint64>(value)); 6211 break; 6212 6213 case FieldDescriptor::TYPE_FIXED32: 6214 unknown_fields->AddFixed32(number, static_cast<uint32>(value)); 6215 break; 6216 6217 default: 6218 GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT32: " << type; 6219 break; 6220 } 6221 } 6222 6223 void DescriptorBuilder::OptionInterpreter::SetUInt64(int number, uint64 value, 6224 FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) { 6225 switch (type) { 6226 case FieldDescriptor::TYPE_UINT64: 6227 unknown_fields->AddVarint(number, value); 6228 break; 6229 6230 case FieldDescriptor::TYPE_FIXED64: 6231 unknown_fields->AddFixed64(number, value); 6232 break; 6233 6234 default: 6235 GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT64: " << type; 6236 break; 6237 } 6238 } 6239 6240 void DescriptorBuilder::LogUnusedDependency(const FileDescriptorProto& proto, 6241 const FileDescriptor* result) { 6242 6243 if (!unused_dependency_.empty()) { 6244 std::set<string> annotation_extensions; 6245 annotation_extensions.insert("google.protobuf.MessageOptions"); 6246 annotation_extensions.insert("google.protobuf.FileOptions"); 6247 annotation_extensions.insert("google.protobuf.FieldOptions"); 6248 annotation_extensions.insert("google.protobuf.EnumOptions"); 6249 annotation_extensions.insert("google.protobuf.EnumValueOptions"); 6250 annotation_extensions.insert("google.protobuf.ServiceOptions"); 6251 annotation_extensions.insert("google.protobuf.MethodOptions"); 6252 annotation_extensions.insert("google.protobuf.StreamOptions"); 6253 for (set<const FileDescriptor*>::const_iterator 6254 it = unused_dependency_.begin(); 6255 it != unused_dependency_.end(); ++it) { 6256 // Do not log warnings for proto files which extend annotations. 6257 int i; 6258 for (i = 0 ; i < (*it)->extension_count(); ++i) { 6259 if (annotation_extensions.find( 6260 (*it)->extension(i)->containing_type()->full_name()) 6261 != annotation_extensions.end()) { 6262 break; 6263 } 6264 } 6265 // Log warnings for unused imported files. 6266 if (i == (*it)->extension_count()) { 6267 string error_message = "Import " + (*it)->name() + " but not used."; 6268 AddWarning((*it)->name(), proto, DescriptorPool::ErrorCollector::OTHER, 6269 error_message); 6270 } 6271 } 6272 } 6273 } 6274 6275 } // namespace protobuf 6276 } // namespace google 6277