PageRenderTime 81ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/thirdparty/breakpad/third_party/protobuf/protobuf/src/google/protobuf/descriptor.cc

http://github.com/tomahawk-player/tomahawk
C++ | 1943 lines | 1412 code | 279 blank | 252 comment | 292 complexity | 169581e021afaf1ffcb5e8223a3b3ca5 MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause, GPL-3.0, GPL-2.0
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // http://code.google.com/p/protobuf/
  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. // Author: kenton@google.com (Kenton Varda)
  31. // Based on original Protocol Buffers design by
  32. // Sanjay Ghemawat, Jeff Dean, and others.
  33. #include <google/protobuf/stubs/hash.h>
  34. #include <map>
  35. #include <set>
  36. #include <vector>
  37. #include <algorithm>
  38. #include <limits>
  39. #include <google/protobuf/descriptor.h>
  40. #include <google/protobuf/descriptor_database.h>
  41. #include <google/protobuf/descriptor.pb.h>
  42. #include <google/protobuf/dynamic_message.h>
  43. #include <google/protobuf/text_format.h>
  44. #include <google/protobuf/unknown_field_set.h>
  45. #include <google/protobuf/wire_format.h>
  46. #include <google/protobuf/io/coded_stream.h>
  47. #include <google/protobuf/io/tokenizer.h>
  48. #include <google/protobuf/io/zero_copy_stream_impl.h>
  49. #include <google/protobuf/stubs/common.h>
  50. #include <google/protobuf/stubs/once.h>
  51. #include <google/protobuf/stubs/strutil.h>
  52. #include <google/protobuf/stubs/substitute.h>
  53. #include <google/protobuf/stubs/map-util.h>
  54. #include <google/protobuf/stubs/stl_util-inl.h>
  55. #undef PACKAGE // autoheader #defines this. :(
  56. namespace google {
  57. namespace protobuf {
  58. const FieldDescriptor::CppType
  59. FieldDescriptor::kTypeToCppTypeMap[MAX_TYPE + 1] = {
  60. static_cast<CppType>(0), // 0 is reserved for errors
  61. CPPTYPE_DOUBLE, // TYPE_DOUBLE
  62. CPPTYPE_FLOAT, // TYPE_FLOAT
  63. CPPTYPE_INT64, // TYPE_INT64
  64. CPPTYPE_UINT64, // TYPE_UINT64
  65. CPPTYPE_INT32, // TYPE_INT32
  66. CPPTYPE_UINT64, // TYPE_FIXED64
  67. CPPTYPE_UINT32, // TYPE_FIXED32
  68. CPPTYPE_BOOL, // TYPE_BOOL
  69. CPPTYPE_STRING, // TYPE_STRING
  70. CPPTYPE_MESSAGE, // TYPE_GROUP
  71. CPPTYPE_MESSAGE, // TYPE_MESSAGE
  72. CPPTYPE_STRING, // TYPE_BYTES
  73. CPPTYPE_UINT32, // TYPE_UINT32
  74. CPPTYPE_ENUM, // TYPE_ENUM
  75. CPPTYPE_INT32, // TYPE_SFIXED32
  76. CPPTYPE_INT64, // TYPE_SFIXED64
  77. CPPTYPE_INT32, // TYPE_SINT32
  78. CPPTYPE_INT64, // TYPE_SINT64
  79. };
  80. const char * const FieldDescriptor::kTypeToName[MAX_TYPE + 1] = {
  81. "ERROR", // 0 is reserved for errors
  82. "double", // TYPE_DOUBLE
  83. "float", // TYPE_FLOAT
  84. "int64", // TYPE_INT64
  85. "uint64", // TYPE_UINT64
  86. "int32", // TYPE_INT32
  87. "fixed64", // TYPE_FIXED64
  88. "fixed32", // TYPE_FIXED32
  89. "bool", // TYPE_BOOL
  90. "string", // TYPE_STRING
  91. "group", // TYPE_GROUP
  92. "message", // TYPE_MESSAGE
  93. "bytes", // TYPE_BYTES
  94. "uint32", // TYPE_UINT32
  95. "enum", // TYPE_ENUM
  96. "sfixed32", // TYPE_SFIXED32
  97. "sfixed64", // TYPE_SFIXED64
  98. "sint32", // TYPE_SINT32
  99. "sint64", // TYPE_SINT64
  100. };
  101. const char * const FieldDescriptor::kLabelToName[MAX_LABEL + 1] = {
  102. "ERROR", // 0 is reserved for errors
  103. "optional", // LABEL_OPTIONAL
  104. "required", // LABEL_REQUIRED
  105. "repeated", // LABEL_REPEATED
  106. };
  107. #ifndef _MSC_VER // MSVC doesn't need these and won't even accept them.
  108. const int FieldDescriptor::kMaxNumber;
  109. const int FieldDescriptor::kFirstReservedNumber;
  110. const int FieldDescriptor::kLastReservedNumber;
  111. #endif
  112. namespace {
  113. const string kEmptyString;
  114. string ToCamelCase(const string& input) {
  115. bool capitalize_next = false;
  116. string result;
  117. result.reserve(input.size());
  118. for (int i = 0; i < input.size(); i++) {
  119. if (input[i] == '_') {
  120. capitalize_next = true;
  121. } else if (capitalize_next) {
  122. // Note: I distrust ctype.h due to locales.
  123. if ('a' <= input[i] && input[i] <= 'z') {
  124. result.push_back(input[i] - 'a' + 'A');
  125. } else {
  126. result.push_back(input[i]);
  127. }
  128. capitalize_next = false;
  129. } else {
  130. result.push_back(input[i]);
  131. }
  132. }
  133. // Lower-case the first letter.
  134. if (!result.empty() && 'A' <= result[0] && result[0] <= 'Z') {
  135. result[0] = result[0] - 'A' + 'a';
  136. }
  137. return result;
  138. }
  139. // A DescriptorPool contains a bunch of hash_maps to implement the
  140. // various Find*By*() methods. Since hashtable lookups are O(1), it's
  141. // most efficient to construct a fixed set of large hash_maps used by
  142. // all objects in the pool rather than construct one or more small
  143. // hash_maps for each object.
  144. //
  145. // The keys to these hash_maps are (parent, name) or (parent, number)
  146. // pairs. Unfortunately STL doesn't provide hash functions for pair<>,
  147. // so we must invent our own.
  148. //
  149. // TODO(kenton): Use StringPiece rather than const char* in keys? It would
  150. // be a lot cleaner but we'd just have to convert it back to const char*
  151. // for the open source release.
  152. typedef pair<const void*, const char*> PointerStringPair;
  153. struct PointerStringPairEqual {
  154. inline bool operator()(const PointerStringPair& a,
  155. const PointerStringPair& b) const {
  156. return a.first == b.first && strcmp(a.second, b.second) == 0;
  157. }
  158. };
  159. template<typename PairType>
  160. struct PointerIntegerPairHash {
  161. size_t operator()(const PairType& p) const {
  162. // FIXME(kenton): What is the best way to compute this hash? I have
  163. // no idea! This seems a bit better than an XOR.
  164. return reinterpret_cast<intptr_t>(p.first) * ((1 << 16) - 1) + p.second;
  165. }
  166. // Used only by MSVC and platforms where hash_map is not available.
  167. static const size_t bucket_size = 4;
  168. static const size_t min_buckets = 8;
  169. inline bool operator()(const PairType& a, const PairType& b) const {
  170. return a.first < b.first ||
  171. (a.first == b.first && a.second < b.second);
  172. }
  173. };
  174. typedef pair<const Descriptor*, int> DescriptorIntPair;
  175. typedef pair<const EnumDescriptor*, int> EnumIntPair;
  176. struct PointerStringPairHash {
  177. size_t operator()(const PointerStringPair& p) const {
  178. // FIXME(kenton): What is the best way to compute this hash? I have
  179. // no idea! This seems a bit better than an XOR.
  180. hash<const char*> cstring_hash;
  181. return reinterpret_cast<intptr_t>(p.first) * ((1 << 16) - 1) +
  182. cstring_hash(p.second);
  183. }
  184. // Used only by MSVC and platforms where hash_map is not available.
  185. static const size_t bucket_size = 4;
  186. static const size_t min_buckets = 8;
  187. inline bool operator()(const PointerStringPair& a,
  188. const PointerStringPair& b) const {
  189. if (a.first < b.first) return true;
  190. if (a.first > b.first) return false;
  191. return strcmp(a.second, b.second) < 0;
  192. }
  193. };
  194. struct Symbol {
  195. enum Type {
  196. NULL_SYMBOL, MESSAGE, FIELD, ENUM, ENUM_VALUE, SERVICE, METHOD, PACKAGE
  197. };
  198. Type type;
  199. union {
  200. const Descriptor* descriptor;
  201. const FieldDescriptor* field_descriptor;
  202. const EnumDescriptor* enum_descriptor;
  203. const EnumValueDescriptor* enum_value_descriptor;
  204. const ServiceDescriptor* service_descriptor;
  205. const MethodDescriptor* method_descriptor;
  206. const FileDescriptor* package_file_descriptor;
  207. };
  208. inline Symbol() : type(NULL_SYMBOL) { descriptor = NULL; }
  209. inline bool IsNull() const { return type == NULL_SYMBOL; }
  210. inline bool IsType() const {
  211. return type == MESSAGE || type == ENUM;
  212. }
  213. inline bool IsAggregate() const {
  214. return type == MESSAGE || type == PACKAGE
  215. || type == ENUM || type == SERVICE;
  216. }
  217. #define CONSTRUCTOR(TYPE, TYPE_CONSTANT, FIELD) \
  218. inline explicit Symbol(const TYPE* value) { \
  219. type = TYPE_CONSTANT; \
  220. this->FIELD = value; \
  221. }
  222. CONSTRUCTOR(Descriptor , MESSAGE , descriptor )
  223. CONSTRUCTOR(FieldDescriptor , FIELD , field_descriptor )
  224. CONSTRUCTOR(EnumDescriptor , ENUM , enum_descriptor )
  225. CONSTRUCTOR(EnumValueDescriptor, ENUM_VALUE, enum_value_descriptor )
  226. CONSTRUCTOR(ServiceDescriptor , SERVICE , service_descriptor )
  227. CONSTRUCTOR(MethodDescriptor , METHOD , method_descriptor )
  228. CONSTRUCTOR(FileDescriptor , PACKAGE , package_file_descriptor)
  229. #undef CONSTRUCTOR
  230. const FileDescriptor* GetFile() const {
  231. switch (type) {
  232. case NULL_SYMBOL: return NULL;
  233. case MESSAGE : return descriptor ->file();
  234. case FIELD : return field_descriptor ->file();
  235. case ENUM : return enum_descriptor ->file();
  236. case ENUM_VALUE : return enum_value_descriptor->type()->file();
  237. case SERVICE : return service_descriptor ->file();
  238. case METHOD : return method_descriptor ->service()->file();
  239. case PACKAGE : return package_file_descriptor;
  240. }
  241. return NULL;
  242. }
  243. };
  244. const Symbol kNullSymbol;
  245. typedef hash_map<const char*, Symbol,
  246. hash<const char*>, streq>
  247. SymbolsByNameMap;
  248. typedef hash_map<PointerStringPair, Symbol,
  249. PointerStringPairHash, PointerStringPairEqual>
  250. SymbolsByParentMap;
  251. typedef hash_map<const char*, const FileDescriptor*,
  252. hash<const char*>, streq>
  253. FilesByNameMap;
  254. typedef hash_map<PointerStringPair, const FieldDescriptor*,
  255. PointerStringPairHash, PointerStringPairEqual>
  256. FieldsByNameMap;
  257. typedef hash_map<DescriptorIntPair, const FieldDescriptor*,
  258. PointerIntegerPairHash<DescriptorIntPair> >
  259. FieldsByNumberMap;
  260. typedef hash_map<EnumIntPair, const EnumValueDescriptor*,
  261. PointerIntegerPairHash<EnumIntPair> >
  262. EnumValuesByNumberMap;
  263. // This is a map rather than a hash_map, since we use it to iterate
  264. // through all the extensions that extend a given Descriptor, and an
  265. // ordered data structure that implements lower_bound is convenient
  266. // for that.
  267. typedef map<DescriptorIntPair, const FieldDescriptor*>
  268. ExtensionsGroupedByDescriptorMap;
  269. } // anonymous namespace
  270. // ===================================================================
  271. // DescriptorPool::Tables
  272. class DescriptorPool::Tables {
  273. public:
  274. Tables();
  275. ~Tables();
  276. // Checkpoint the state of the tables. Future calls to Rollback() will
  277. // return the Tables to this state. This is used when building files, since
  278. // some kinds of validation errors cannot be detected until the file's
  279. // descriptors have already been added to the tables. BuildFile() calls
  280. // Checkpoint() before it starts building and Rollback() if it encounters
  281. // an error.
  282. void Checkpoint();
  283. // Roll back the Tables to the state of the last Checkpoint(), removing
  284. // everything that was added after that point.
  285. void Rollback();
  286. // The stack of files which are currently being built. Used to detect
  287. // cyclic dependencies when loading files from a DescriptorDatabase. Not
  288. // used when fallback_database_ == NULL.
  289. vector<string> pending_files_;
  290. // A set of files which we have tried to load from the fallback database
  291. // and encountered errors. We will not attempt to load them again.
  292. // Not used when fallback_database_ == NULL.
  293. hash_set<string> known_bad_files_;
  294. // The set of descriptors for which we've already loaded the full
  295. // set of extensions numbers from fallback_database_.
  296. hash_set<const Descriptor*> extensions_loaded_from_db_;
  297. // -----------------------------------------------------------------
  298. // Finding items.
  299. // Find symbols. This returns a null Symbol (symbol.IsNull() is true)
  300. // if not found.
  301. inline Symbol FindSymbol(const string& key) const;
  302. // This implements the body of DescriptorPool::Find*ByName(). It should
  303. // really be a private method of DescriptorPool, but that would require
  304. // declaring Symbol in descriptor.h, which would drag all kinds of other
  305. // stuff into the header. Yay C++.
  306. Symbol FindByNameHelper(
  307. const DescriptorPool* pool, const string& name) const;
  308. // These return NULL if not found.
  309. inline const FileDescriptor* FindFile(const string& key) const;
  310. inline const FieldDescriptor* FindExtension(const Descriptor* extendee,
  311. int number);
  312. inline void FindAllExtensions(const Descriptor* extendee,
  313. vector<const FieldDescriptor*>* out) const;
  314. // -----------------------------------------------------------------
  315. // Adding items.
  316. // These add items to the corresponding tables. They return false if
  317. // the key already exists in the table. For AddSymbol(), the string passed
  318. // in must be one that was constructed using AllocateString(), as it will
  319. // be used as a key in the symbols_by_name_ map without copying.
  320. bool AddSymbol(const string& full_name, Symbol symbol);
  321. bool AddFile(const FileDescriptor* file);
  322. bool AddExtension(const FieldDescriptor* field);
  323. // -----------------------------------------------------------------
  324. // Allocating memory.
  325. // Allocate an object which will be reclaimed when the pool is
  326. // destroyed. Note that the object's destructor will never be called,
  327. // so its fields must be plain old data (primitive data types and
  328. // pointers). All of the descriptor types are such objects.
  329. template<typename Type> Type* Allocate();
  330. // Allocate an array of objects which will be reclaimed when the
  331. // pool in destroyed. Again, destructors are never called.
  332. template<typename Type> Type* AllocateArray(int count);
  333. // Allocate a string which will be destroyed when the pool is destroyed.
  334. // The string is initialized to the given value for convenience.
  335. string* AllocateString(const string& value);
  336. // Allocate a protocol message object. Some older versions of GCC have
  337. // trouble understanding explicit template instantiations in some cases, so
  338. // in those cases we have to pass a dummy pointer of the right type as the
  339. // parameter instead of specifying the type explicitly.
  340. template<typename Type> Type* AllocateMessage(Type* dummy = NULL);
  341. // Allocate a FileDescriptorTables object.
  342. FileDescriptorTables* AllocateFileTables();
  343. private:
  344. vector<string*> strings_; // All strings in the pool.
  345. vector<Message*> messages_; // All messages in the pool.
  346. vector<FileDescriptorTables*> file_tables_; // All file tables in the pool.
  347. vector<void*> allocations_; // All other memory allocated in the pool.
  348. SymbolsByNameMap symbols_by_name_;
  349. FilesByNameMap files_by_name_;
  350. ExtensionsGroupedByDescriptorMap extensions_;
  351. int strings_before_checkpoint_;
  352. int messages_before_checkpoint_;
  353. int file_tables_before_checkpoint_;
  354. int allocations_before_checkpoint_;
  355. vector<const char* > symbols_after_checkpoint_;
  356. vector<const char* > files_after_checkpoint_;
  357. vector<DescriptorIntPair> extensions_after_checkpoint_;
  358. // Allocate some bytes which will be reclaimed when the pool is
  359. // destroyed.
  360. void* AllocateBytes(int size);
  361. };
  362. // Contains tables specific to a particular file. These tables are not
  363. // modified once the file has been constructed, so they need not be
  364. // protected by a mutex. This makes operations that depend only on the
  365. // contents of a single file -- e.g. Descriptor::FindFieldByName() --
  366. // lock-free.
  367. //
  368. // For historical reasons, the definitions of the methods of
  369. // FileDescriptorTables and DescriptorPool::Tables are interleaved below.
  370. // These used to be a single class.
  371. class FileDescriptorTables {
  372. public:
  373. FileDescriptorTables();
  374. ~FileDescriptorTables();
  375. // Empty table, used with placeholder files.
  376. static const FileDescriptorTables kEmpty;
  377. // -----------------------------------------------------------------
  378. // Finding items.
  379. // Find symbols. These return a null Symbol (symbol.IsNull() is true)
  380. // if not found.
  381. inline Symbol FindNestedSymbol(const void* parent,
  382. const string& name) const;
  383. inline Symbol FindNestedSymbolOfType(const void* parent,
  384. const string& name,
  385. const Symbol::Type type) const;
  386. // These return NULL if not found.
  387. inline const FieldDescriptor* FindFieldByNumber(
  388. const Descriptor* parent, int number) const;
  389. inline const FieldDescriptor* FindFieldByLowercaseName(
  390. const void* parent, const string& lowercase_name) const;
  391. inline const FieldDescriptor* FindFieldByCamelcaseName(
  392. const void* parent, const string& camelcase_name) const;
  393. inline const EnumValueDescriptor* FindEnumValueByNumber(
  394. const EnumDescriptor* parent, int number) const;
  395. // -----------------------------------------------------------------
  396. // Adding items.
  397. // These add items to the corresponding tables. They return false if
  398. // the key already exists in the table. For AddAliasUnderParent(), the
  399. // string passed in must be one that was constructed using AllocateString(),
  400. // as it will be used as a key in the symbols_by_parent_ map without copying.
  401. bool AddAliasUnderParent(const void* parent, const string& name,
  402. Symbol symbol);
  403. bool AddFieldByNumber(const FieldDescriptor* field);
  404. bool AddEnumValueByNumber(const EnumValueDescriptor* value);
  405. // Adds the field to the lowercase_name and camelcase_name maps. Never
  406. // fails because we allow duplicates; the first field by the name wins.
  407. void AddFieldByStylizedNames(const FieldDescriptor* field);
  408. private:
  409. SymbolsByParentMap symbols_by_parent_;
  410. FieldsByNameMap fields_by_lowercase_name_;
  411. FieldsByNameMap fields_by_camelcase_name_;
  412. FieldsByNumberMap fields_by_number_; // Not including extensions.
  413. EnumValuesByNumberMap enum_values_by_number_;
  414. };
  415. DescriptorPool::Tables::Tables()
  416. : strings_before_checkpoint_(0),
  417. messages_before_checkpoint_(0),
  418. allocations_before_checkpoint_(0) {}
  419. DescriptorPool::Tables::~Tables() {
  420. // Note that the deletion order is important, since the destructors of some
  421. // messages may refer to objects in allocations_.
  422. STLDeleteElements(&messages_);
  423. for (int i = 0; i < allocations_.size(); i++) {
  424. operator delete(allocations_[i]);
  425. }
  426. STLDeleteElements(&strings_);
  427. STLDeleteElements(&file_tables_);
  428. }
  429. FileDescriptorTables::FileDescriptorTables() {}
  430. FileDescriptorTables::~FileDescriptorTables() {}
  431. const FileDescriptorTables FileDescriptorTables::kEmpty;
  432. void DescriptorPool::Tables::Checkpoint() {
  433. strings_before_checkpoint_ = strings_.size();
  434. messages_before_checkpoint_ = messages_.size();
  435. file_tables_before_checkpoint_ = file_tables_.size();
  436. allocations_before_checkpoint_ = allocations_.size();
  437. symbols_after_checkpoint_.clear();
  438. files_after_checkpoint_.clear();
  439. extensions_after_checkpoint_.clear();
  440. }
  441. void DescriptorPool::Tables::Rollback() {
  442. for (int i = 0; i < symbols_after_checkpoint_.size(); i++) {
  443. symbols_by_name_.erase(symbols_after_checkpoint_[i]);
  444. }
  445. for (int i = 0; i < files_after_checkpoint_.size(); i++) {
  446. files_by_name_.erase(files_after_checkpoint_[i]);
  447. }
  448. for (int i = 0; i < extensions_after_checkpoint_.size(); i++) {
  449. extensions_.erase(extensions_after_checkpoint_[i]);
  450. }
  451. symbols_after_checkpoint_.clear();
  452. files_after_checkpoint_.clear();
  453. extensions_after_checkpoint_.clear();
  454. STLDeleteContainerPointers(
  455. strings_.begin() + strings_before_checkpoint_, strings_.end());
  456. STLDeleteContainerPointers(
  457. messages_.begin() + messages_before_checkpoint_, messages_.end());
  458. STLDeleteContainerPointers(
  459. file_tables_.begin() + file_tables_before_checkpoint_, file_tables_.end());
  460. for (int i = allocations_before_checkpoint_; i < allocations_.size(); i++) {
  461. operator delete(allocations_[i]);
  462. }
  463. strings_.resize(strings_before_checkpoint_);
  464. messages_.resize(messages_before_checkpoint_);
  465. file_tables_.resize(file_tables_before_checkpoint_);
  466. allocations_.resize(allocations_before_checkpoint_);
  467. }
  468. // -------------------------------------------------------------------
  469. inline Symbol DescriptorPool::Tables::FindSymbol(const string& key) const {
  470. const Symbol* result = FindOrNull(symbols_by_name_, key.c_str());
  471. if (result == NULL) {
  472. return kNullSymbol;
  473. } else {
  474. return *result;
  475. }
  476. }
  477. inline Symbol FileDescriptorTables::FindNestedSymbol(
  478. const void* parent, const string& name) const {
  479. const Symbol* result =
  480. FindOrNull(symbols_by_parent_, PointerStringPair(parent, name.c_str()));
  481. if (result == NULL) {
  482. return kNullSymbol;
  483. } else {
  484. return *result;
  485. }
  486. }
  487. inline Symbol FileDescriptorTables::FindNestedSymbolOfType(
  488. const void* parent, const string& name, const Symbol::Type type) const {
  489. Symbol result = FindNestedSymbol(parent, name);
  490. if (result.type != type) return kNullSymbol;
  491. return result;
  492. }
  493. Symbol DescriptorPool::Tables::FindByNameHelper(
  494. const DescriptorPool* pool, const string& name) const {
  495. MutexLockMaybe lock(pool->mutex_);
  496. Symbol result = FindSymbol(name);
  497. if (result.IsNull() && pool->underlay_ != NULL) {
  498. // Symbol not found; check the underlay.
  499. result =
  500. pool->underlay_->tables_->FindByNameHelper(pool->underlay_, name);
  501. }
  502. if (result.IsNull()) {
  503. // Symbol still not found, so check fallback database.
  504. if (pool->TryFindSymbolInFallbackDatabase(name)) {
  505. result = FindSymbol(name);
  506. }
  507. }
  508. return result;
  509. }
  510. inline const FileDescriptor* DescriptorPool::Tables::FindFile(
  511. const string& key) const {
  512. return FindPtrOrNull(files_by_name_, key.c_str());
  513. }
  514. inline const FieldDescriptor* FileDescriptorTables::FindFieldByNumber(
  515. const Descriptor* parent, int number) const {
  516. return FindPtrOrNull(fields_by_number_, make_pair(parent, number));
  517. }
  518. inline const FieldDescriptor* FileDescriptorTables::FindFieldByLowercaseName(
  519. const void* parent, const string& lowercase_name) const {
  520. return FindPtrOrNull(fields_by_lowercase_name_,
  521. PointerStringPair(parent, lowercase_name.c_str()));
  522. }
  523. inline const FieldDescriptor* FileDescriptorTables::FindFieldByCamelcaseName(
  524. const void* parent, const string& camelcase_name) const {
  525. return FindPtrOrNull(fields_by_camelcase_name_,
  526. PointerStringPair(parent, camelcase_name.c_str()));
  527. }
  528. inline const EnumValueDescriptor* FileDescriptorTables::FindEnumValueByNumber(
  529. const EnumDescriptor* parent, int number) const {
  530. return FindPtrOrNull(enum_values_by_number_, make_pair(parent, number));
  531. }
  532. inline const FieldDescriptor* DescriptorPool::Tables::FindExtension(
  533. const Descriptor* extendee, int number) {
  534. return FindPtrOrNull(extensions_, make_pair(extendee, number));
  535. }
  536. inline void DescriptorPool::Tables::FindAllExtensions(
  537. const Descriptor* extendee, vector<const FieldDescriptor*>* out) const {
  538. ExtensionsGroupedByDescriptorMap::const_iterator it =
  539. extensions_.lower_bound(make_pair(extendee, 0));
  540. for (; it != extensions_.end() && it->first.first == extendee; ++it) {
  541. out->push_back(it->second);
  542. }
  543. }
  544. // -------------------------------------------------------------------
  545. bool DescriptorPool::Tables::AddSymbol(
  546. const string& full_name, Symbol symbol) {
  547. if (InsertIfNotPresent(&symbols_by_name_, full_name.c_str(), symbol)) {
  548. symbols_after_checkpoint_.push_back(full_name.c_str());
  549. return true;
  550. } else {
  551. return false;
  552. }
  553. }
  554. bool FileDescriptorTables::AddAliasUnderParent(
  555. const void* parent, const string& name, Symbol symbol) {
  556. PointerStringPair by_parent_key(parent, name.c_str());
  557. return InsertIfNotPresent(&symbols_by_parent_, by_parent_key, symbol);
  558. }
  559. bool DescriptorPool::Tables::AddFile(const FileDescriptor* file) {
  560. if (InsertIfNotPresent(&files_by_name_, file->name().c_str(), file)) {
  561. files_after_checkpoint_.push_back(file->name().c_str());
  562. return true;
  563. } else {
  564. return false;
  565. }
  566. }
  567. void FileDescriptorTables::AddFieldByStylizedNames(
  568. const FieldDescriptor* field) {
  569. const void* parent;
  570. if (field->is_extension()) {
  571. if (field->extension_scope() == NULL) {
  572. parent = field->file();
  573. } else {
  574. parent = field->extension_scope();
  575. }
  576. } else {
  577. parent = field->containing_type();
  578. }
  579. PointerStringPair lowercase_key(parent, field->lowercase_name().c_str());
  580. InsertIfNotPresent(&fields_by_lowercase_name_, lowercase_key, field);
  581. PointerStringPair camelcase_key(parent, field->camelcase_name().c_str());
  582. InsertIfNotPresent(&fields_by_camelcase_name_, camelcase_key, field);
  583. }
  584. bool FileDescriptorTables::AddFieldByNumber(const FieldDescriptor* field) {
  585. DescriptorIntPair key(field->containing_type(), field->number());
  586. return InsertIfNotPresent(&fields_by_number_, key, field);
  587. }
  588. bool FileDescriptorTables::AddEnumValueByNumber(
  589. const EnumValueDescriptor* value) {
  590. EnumIntPair key(value->type(), value->number());
  591. return InsertIfNotPresent(&enum_values_by_number_, key, value);
  592. }
  593. bool DescriptorPool::Tables::AddExtension(const FieldDescriptor* field) {
  594. DescriptorIntPair key(field->containing_type(), field->number());
  595. if (InsertIfNotPresent(&extensions_, key, field)) {
  596. extensions_after_checkpoint_.push_back(key);
  597. return true;
  598. } else {
  599. return false;
  600. }
  601. }
  602. // -------------------------------------------------------------------
  603. template<typename Type>
  604. Type* DescriptorPool::Tables::Allocate() {
  605. return reinterpret_cast<Type*>(AllocateBytes(sizeof(Type)));
  606. }
  607. template<typename Type>
  608. Type* DescriptorPool::Tables::AllocateArray(int count) {
  609. return reinterpret_cast<Type*>(AllocateBytes(sizeof(Type) * count));
  610. }
  611. string* DescriptorPool::Tables::AllocateString(const string& value) {
  612. string* result = new string(value);
  613. strings_.push_back(result);
  614. return result;
  615. }
  616. template<typename Type>
  617. Type* DescriptorPool::Tables::AllocateMessage(Type* dummy) {
  618. Type* result = new Type;
  619. messages_.push_back(result);
  620. return result;
  621. }
  622. FileDescriptorTables* DescriptorPool::Tables::AllocateFileTables() {
  623. FileDescriptorTables* result = new FileDescriptorTables;
  624. file_tables_.push_back(result);
  625. return result;
  626. }
  627. void* DescriptorPool::Tables::AllocateBytes(int size) {
  628. // TODO(kenton): Would it be worthwhile to implement this in some more
  629. // sophisticated way? Probably not for the open source release, but for
  630. // internal use we could easily plug in one of our existing memory pool
  631. // allocators...
  632. if (size == 0) return NULL;
  633. void* result = operator new(size);
  634. allocations_.push_back(result);
  635. return result;
  636. }
  637. // ===================================================================
  638. // DescriptorPool
  639. DescriptorPool::ErrorCollector::~ErrorCollector() {}
  640. DescriptorPool::DescriptorPool()
  641. : mutex_(NULL),
  642. fallback_database_(NULL),
  643. default_error_collector_(NULL),
  644. underlay_(NULL),
  645. tables_(new Tables),
  646. enforce_dependencies_(true),
  647. allow_unknown_(false) {}
  648. DescriptorPool::DescriptorPool(DescriptorDatabase* fallback_database,
  649. ErrorCollector* error_collector)
  650. : mutex_(new Mutex),
  651. fallback_database_(fallback_database),
  652. default_error_collector_(error_collector),
  653. underlay_(NULL),
  654. tables_(new Tables),
  655. enforce_dependencies_(true),
  656. allow_unknown_(false) {
  657. }
  658. DescriptorPool::DescriptorPool(const DescriptorPool* underlay)
  659. : mutex_(NULL),
  660. fallback_database_(NULL),
  661. default_error_collector_(NULL),
  662. underlay_(underlay),
  663. tables_(new Tables),
  664. enforce_dependencies_(true),
  665. allow_unknown_(false) {}
  666. DescriptorPool::~DescriptorPool() {
  667. if (mutex_ != NULL) delete mutex_;
  668. }
  669. // DescriptorPool::BuildFile() defined later.
  670. // DescriptorPool::BuildFileCollectingErrors() defined later.
  671. void DescriptorPool::InternalDontEnforceDependencies() {
  672. enforce_dependencies_ = false;
  673. }
  674. bool DescriptorPool::InternalIsFileLoaded(const string& filename) const {
  675. MutexLockMaybe lock(mutex_);
  676. return tables_->FindFile(filename) != NULL;
  677. }
  678. // generated_pool ====================================================
  679. namespace {
  680. EncodedDescriptorDatabase* generated_database_ = NULL;
  681. DescriptorPool* generated_pool_ = NULL;
  682. GOOGLE_PROTOBUF_DECLARE_ONCE(generated_pool_init_);
  683. void DeleteGeneratedPool() {
  684. delete generated_database_;
  685. generated_database_ = NULL;
  686. delete generated_pool_;
  687. generated_pool_ = NULL;
  688. }
  689. void InitGeneratedPool() {
  690. generated_database_ = new EncodedDescriptorDatabase;
  691. generated_pool_ = new DescriptorPool(generated_database_);
  692. internal::OnShutdown(&DeleteGeneratedPool);
  693. }
  694. inline void InitGeneratedPoolOnce() {
  695. ::google::protobuf::GoogleOnceInit(&generated_pool_init_, &InitGeneratedPool);
  696. }
  697. } // anonymous namespace
  698. const DescriptorPool* DescriptorPool::generated_pool() {
  699. InitGeneratedPoolOnce();
  700. return generated_pool_;
  701. }
  702. DescriptorPool* DescriptorPool::internal_generated_pool() {
  703. InitGeneratedPoolOnce();
  704. return generated_pool_;
  705. }
  706. void DescriptorPool::InternalAddGeneratedFile(
  707. const void* encoded_file_descriptor, int size) {
  708. // So, this function is called in the process of initializing the
  709. // descriptors for generated proto classes. Each generated .pb.cc file
  710. // has an internal procedure called AddDescriptors() which is called at
  711. // process startup, and that function calls this one in order to register
  712. // the raw bytes of the FileDescriptorProto representing the file.
  713. //
  714. // We do not actually construct the descriptor objects right away. We just
  715. // hang on to the bytes until they are actually needed. We actually construct
  716. // the descriptor the first time one of the following things happens:
  717. // * Someone calls a method like descriptor(), GetDescriptor(), or
  718. // GetReflection() on the generated types, which requires returning the
  719. // descriptor or an object based on it.
  720. // * Someone looks up the descriptor in DescriptorPool::generated_pool().
  721. //
  722. // Once one of these happens, the DescriptorPool actually parses the
  723. // FileDescriptorProto and generates a FileDescriptor (and all its children)
  724. // based on it.
  725. //
  726. // Note that FileDescriptorProto is itself a generated protocol message.
  727. // Therefore, when we parse one, we have to be very careful to avoid using
  728. // any descriptor-based operations, since this might cause infinite recursion
  729. // or deadlock.
  730. InitGeneratedPoolOnce();
  731. GOOGLE_CHECK(generated_database_->Add(encoded_file_descriptor, size));
  732. }
  733. // Find*By* methods ==================================================
  734. // TODO(kenton): There's a lot of repeated code here, but I'm not sure if
  735. // there's any good way to factor it out. Think about this some time when
  736. // there's nothing more important to do (read: never).
  737. const FileDescriptor* DescriptorPool::FindFileByName(const string& name) const {
  738. MutexLockMaybe lock(mutex_);
  739. const FileDescriptor* result = tables_->FindFile(name);
  740. if (result != NULL) return result;
  741. if (underlay_ != NULL) {
  742. const FileDescriptor* result = underlay_->FindFileByName(name);
  743. if (result != NULL) return result;
  744. }
  745. if (TryFindFileInFallbackDatabase(name)) {
  746. const FileDescriptor* result = tables_->FindFile(name);
  747. if (result != NULL) return result;
  748. }
  749. return NULL;
  750. }
  751. const FileDescriptor* DescriptorPool::FindFileContainingSymbol(
  752. const string& symbol_name) const {
  753. MutexLockMaybe lock(mutex_);
  754. Symbol result = tables_->FindSymbol(symbol_name);
  755. if (!result.IsNull()) return result.GetFile();
  756. if (underlay_ != NULL) {
  757. const FileDescriptor* result =
  758. underlay_->FindFileContainingSymbol(symbol_name);
  759. if (result != NULL) return result;
  760. }
  761. if (TryFindSymbolInFallbackDatabase(symbol_name)) {
  762. Symbol result = tables_->FindSymbol(symbol_name);
  763. if (!result.IsNull()) return result.GetFile();
  764. }
  765. return NULL;
  766. }
  767. const Descriptor* DescriptorPool::FindMessageTypeByName(
  768. const string& name) const {
  769. Symbol result = tables_->FindByNameHelper(this, name);
  770. return (result.type == Symbol::MESSAGE) ? result.descriptor : NULL;
  771. }
  772. const FieldDescriptor* DescriptorPool::FindFieldByName(
  773. const string& name) const {
  774. Symbol result = tables_->FindByNameHelper(this, name);
  775. if (result.type == Symbol::FIELD &&
  776. !result.field_descriptor->is_extension()) {
  777. return result.field_descriptor;
  778. } else {
  779. return NULL;
  780. }
  781. }
  782. const FieldDescriptor* DescriptorPool::FindExtensionByName(
  783. const string& name) const {
  784. Symbol result = tables_->FindByNameHelper(this, name);
  785. if (result.type == Symbol::FIELD &&
  786. result.field_descriptor->is_extension()) {
  787. return result.field_descriptor;
  788. } else {
  789. return NULL;
  790. }
  791. }
  792. const EnumDescriptor* DescriptorPool::FindEnumTypeByName(
  793. const string& name) const {
  794. Symbol result = tables_->FindByNameHelper(this, name);
  795. return (result.type == Symbol::ENUM) ? result.enum_descriptor : NULL;
  796. }
  797. const EnumValueDescriptor* DescriptorPool::FindEnumValueByName(
  798. const string& name) const {
  799. Symbol result = tables_->FindByNameHelper(this, name);
  800. return (result.type == Symbol::ENUM_VALUE) ?
  801. result.enum_value_descriptor : NULL;
  802. }
  803. const ServiceDescriptor* DescriptorPool::FindServiceByName(
  804. const string& name) const {
  805. Symbol result = tables_->FindByNameHelper(this, name);
  806. return (result.type == Symbol::SERVICE) ? result.service_descriptor : NULL;
  807. }
  808. const MethodDescriptor* DescriptorPool::FindMethodByName(
  809. const string& name) const {
  810. Symbol result = tables_->FindByNameHelper(this, name);
  811. return (result.type == Symbol::METHOD) ? result.method_descriptor : NULL;
  812. }
  813. const FieldDescriptor* DescriptorPool::FindExtensionByNumber(
  814. const Descriptor* extendee, int number) const {
  815. MutexLockMaybe lock(mutex_);
  816. const FieldDescriptor* result = tables_->FindExtension(extendee, number);
  817. if (result != NULL) {
  818. return result;
  819. }
  820. if (underlay_ != NULL) {
  821. const FieldDescriptor* result =
  822. underlay_->FindExtensionByNumber(extendee, number);
  823. if (result != NULL) return result;
  824. }
  825. if (TryFindExtensionInFallbackDatabase(extendee, number)) {
  826. const FieldDescriptor* result = tables_->FindExtension(extendee, number);
  827. if (result != NULL) {
  828. return result;
  829. }
  830. }
  831. return NULL;
  832. }
  833. void DescriptorPool::FindAllExtensions(
  834. const Descriptor* extendee, vector<const FieldDescriptor*>* out) const {
  835. MutexLockMaybe lock(mutex_);
  836. // Initialize tables_->extensions_ from the fallback database first
  837. // (but do this only once per descriptor).
  838. if (fallback_database_ != NULL &&
  839. tables_->extensions_loaded_from_db_.count(extendee) == 0) {
  840. vector<int> numbers;
  841. if (fallback_database_->FindAllExtensionNumbers(extendee->full_name(),
  842. &numbers)) {
  843. for (int i = 0; i < numbers.size(); ++i) {
  844. int number = numbers[i];
  845. if (tables_->FindExtension(extendee, number) == NULL) {
  846. TryFindExtensionInFallbackDatabase(extendee, number);
  847. }
  848. }
  849. tables_->extensions_loaded_from_db_.insert(extendee);
  850. }
  851. }
  852. tables_->FindAllExtensions(extendee, out);
  853. if (underlay_ != NULL) {
  854. underlay_->FindAllExtensions(extendee, out);
  855. }
  856. }
  857. // -------------------------------------------------------------------
  858. const FieldDescriptor*
  859. Descriptor::FindFieldByNumber(int key) const {
  860. const FieldDescriptor* result =
  861. file()->tables_->FindFieldByNumber(this, key);
  862. if (result == NULL || result->is_extension()) {
  863. return NULL;
  864. } else {
  865. return result;
  866. }
  867. }
  868. const FieldDescriptor*
  869. Descriptor::FindFieldByLowercaseName(const string& key) const {
  870. const FieldDescriptor* result =
  871. file()->tables_->FindFieldByLowercaseName(this, key);
  872. if (result == NULL || result->is_extension()) {
  873. return NULL;
  874. } else {
  875. return result;
  876. }
  877. }
  878. const FieldDescriptor*
  879. Descriptor::FindFieldByCamelcaseName(const string& key) const {
  880. const FieldDescriptor* result =
  881. file()->tables_->FindFieldByCamelcaseName(this, key);
  882. if (result == NULL || result->is_extension()) {
  883. return NULL;
  884. } else {
  885. return result;
  886. }
  887. }
  888. const FieldDescriptor*
  889. Descriptor::FindFieldByName(const string& key) const {
  890. Symbol result =
  891. file()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD);
  892. if (!result.IsNull() && !result.field_descriptor->is_extension()) {
  893. return result.field_descriptor;
  894. } else {
  895. return NULL;
  896. }
  897. }
  898. const FieldDescriptor*
  899. Descriptor::FindExtensionByName(const string& key) const {
  900. Symbol result =
  901. file()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD);
  902. if (!result.IsNull() && result.field_descriptor->is_extension()) {
  903. return result.field_descriptor;
  904. } else {
  905. return NULL;
  906. }
  907. }
  908. const FieldDescriptor*
  909. Descriptor::FindExtensionByLowercaseName(const string& key) const {
  910. const FieldDescriptor* result =
  911. file()->tables_->FindFieldByLowercaseName(this, key);
  912. if (result == NULL || !result->is_extension()) {
  913. return NULL;
  914. } else {
  915. return result;
  916. }
  917. }
  918. const FieldDescriptor*
  919. Descriptor::FindExtensionByCamelcaseName(const string& key) const {
  920. const FieldDescriptor* result =
  921. file()->tables_->FindFieldByCamelcaseName(this, key);
  922. if (result == NULL || !result->is_extension()) {
  923. return NULL;
  924. } else {
  925. return result;
  926. }
  927. }
  928. const Descriptor*
  929. Descriptor::FindNestedTypeByName(const string& key) const {
  930. Symbol result =
  931. file()->tables_->FindNestedSymbolOfType(this, key, Symbol::MESSAGE);
  932. if (!result.IsNull()) {
  933. return result.descriptor;
  934. } else {
  935. return NULL;
  936. }
  937. }
  938. const EnumDescriptor*
  939. Descriptor::FindEnumTypeByName(const string& key) const {
  940. Symbol result =
  941. file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM);
  942. if (!result.IsNull()) {
  943. return result.enum_descriptor;
  944. } else {
  945. return NULL;
  946. }
  947. }
  948. const EnumValueDescriptor*
  949. Descriptor::FindEnumValueByName(const string& key) const {
  950. Symbol result =
  951. file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE);
  952. if (!result.IsNull()) {
  953. return result.enum_value_descriptor;
  954. } else {
  955. return NULL;
  956. }
  957. }
  958. const EnumValueDescriptor*
  959. EnumDescriptor::FindValueByName(const string& key) const {
  960. Symbol result =
  961. file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE);
  962. if (!result.IsNull()) {
  963. return result.enum_value_descriptor;
  964. } else {
  965. return NULL;
  966. }
  967. }
  968. const EnumValueDescriptor*
  969. EnumDescriptor::FindValueByNumber(int key) const {
  970. return file()->tables_->FindEnumValueByNumber(this, key);
  971. }
  972. const MethodDescriptor*
  973. ServiceDescriptor::FindMethodByName(const string& key) const {
  974. Symbol result =
  975. file()->tables_->FindNestedSymbolOfType(this, key, Symbol::METHOD);
  976. if (!result.IsNull()) {
  977. return result.method_descriptor;
  978. } else {
  979. return NULL;
  980. }
  981. }
  982. const Descriptor*
  983. FileDescriptor::FindMessageTypeByName(const string& key) const {
  984. Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::MESSAGE);
  985. if (!result.IsNull()) {
  986. return result.descriptor;
  987. } else {
  988. return NULL;
  989. }
  990. }
  991. const EnumDescriptor*
  992. FileDescriptor::FindEnumTypeByName(const string& key) const {
  993. Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM);
  994. if (!result.IsNull()) {
  995. return result.enum_descriptor;
  996. } else {
  997. return NULL;
  998. }
  999. }
  1000. const EnumValueDescriptor*
  1001. FileDescriptor::FindEnumValueByName(const string& key) const {
  1002. Symbol result =
  1003. tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE);
  1004. if (!result.IsNull()) {
  1005. return result.enum_value_descriptor;
  1006. } else {
  1007. return NULL;
  1008. }
  1009. }
  1010. const ServiceDescriptor*
  1011. FileDescriptor::FindServiceByName(const string& key) const {
  1012. Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::SERVICE);
  1013. if (!result.IsNull()) {
  1014. return result.service_descriptor;
  1015. } else {
  1016. return NULL;
  1017. }
  1018. }
  1019. const FieldDescriptor*
  1020. FileDescriptor::FindExtensionByName(const string& key) const {
  1021. Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD);
  1022. if (!result.IsNull() && result.field_descriptor->is_extension()) {
  1023. return result.field_descriptor;
  1024. } else {
  1025. return NULL;
  1026. }
  1027. }
  1028. const FieldDescriptor*
  1029. FileDescriptor::FindExtensionByLowercaseName(const string& key) const {
  1030. const FieldDescriptor* result = tables_->FindFieldByLowercaseName(this, key);
  1031. if (result == NULL || !result->is_extension()) {
  1032. return NULL;
  1033. } else {
  1034. return result;
  1035. }
  1036. }
  1037. const FieldDescriptor*
  1038. FileDescriptor::FindExtensionByCamelcaseName(const string& key) const {
  1039. const FieldDescriptor* result = tables_->FindFieldByCamelcaseName(this, key);
  1040. if (result == NULL || !result->is_extension()) {
  1041. return NULL;
  1042. } else {
  1043. return result;
  1044. }
  1045. }
  1046. bool Descriptor::IsExtensionNumber(int number) const {
  1047. // Linear search should be fine because we don't expect a message to have
  1048. // more than a couple extension ranges.
  1049. for (int i = 0; i < extension_range_count(); i++) {
  1050. if (number >= extension_range(i)->start &&
  1051. number < extension_range(i)->end) {
  1052. return true;
  1053. }
  1054. }
  1055. return false;
  1056. }
  1057. // -------------------------------------------------------------------
  1058. bool DescriptorPool::TryFindFileInFallbackDatabase(const string& name) const {
  1059. if (fallback_database_ == NULL) return false;
  1060. if (tables_->known_bad_files_.count(name) > 0) return false;
  1061. FileDescriptorProto file_proto;
  1062. if (!fallback_database_->FindFileByName(name, &file_proto) ||
  1063. BuildFileFromDatabase(file_proto) == NULL) {
  1064. tables_->known_bad_files_.insert(name);
  1065. return false;
  1066. }
  1067. return true;
  1068. }
  1069. bool DescriptorPool::TryFindSymbolInFallbackDatabase(const string& name) const {
  1070. if (fallback_database_ == NULL) return false;
  1071. FileDescriptorProto file_proto;
  1072. if (!fallback_database_->FindFileContainingSymbol(name, &file_proto)) {
  1073. return false;
  1074. }
  1075. if (tables_->FindFile(file_proto.name()) != NULL) {
  1076. // We've already loaded this file, and it apparently doesn't contain the
  1077. // symbol we're looking for. Some DescriptorDatabases return false
  1078. // positives.
  1079. return false;
  1080. }
  1081. if (BuildFileFromDatabase(file_proto) == NULL) {
  1082. return false;
  1083. }
  1084. return true;
  1085. }
  1086. bool DescriptorPool::TryFindExtensionInFallbackDatabase(
  1087. const Descriptor* containing_type, int field_number) const {
  1088. if (fallback_database_ == NULL) return false;
  1089. FileDescriptorProto file_proto;
  1090. if (!fallback_database_->FindFileContainingExtension(
  1091. containing_type->full_name(), field_number, &file_proto)) {
  1092. return false;
  1093. }
  1094. if (tables_->FindFile(file_proto.name()) != NULL) {
  1095. // We've already loaded this file, and it apparently doesn't contain the
  1096. // extension we're looking for. Some DescriptorDatabases return false
  1097. // positives.
  1098. return false;
  1099. }
  1100. if (BuildFileFromDatabase(file_proto) == NULL) {
  1101. return false;
  1102. }
  1103. return true;
  1104. }
  1105. // ===================================================================
  1106. string FieldDescriptor::DefaultValueAsString(bool quote_string_type) const {
  1107. GOOGLE_CHECK(has_default_value()) << "No default value";
  1108. switch (cpp_type()) {
  1109. case CPPTYPE_INT32:
  1110. return SimpleItoa(default_value_int32());
  1111. break;
  1112. case CPPTYPE_INT64:
  1113. return SimpleItoa(default_value_int64());
  1114. break;
  1115. case CPPTYPE_UINT32:
  1116. return SimpleItoa(default_value_uint32());
  1117. break;
  1118. case CPPTYPE_UINT64:
  1119. return SimpleItoa(default_value_uint64());
  1120. break;
  1121. case CPPTYPE_FLOAT:
  1122. return SimpleFtoa(default_value_float());
  1123. break;
  1124. case CPPTYPE_DOUBLE:
  1125. return SimpleDtoa(default_value_double());
  1126. break;
  1127. case CPPTYPE_BOOL:
  1128. return default_value_bool() ? "true" : "false";
  1129. break;
  1130. case CPPTYPE_STRING:
  1131. if (quote_string_type) {
  1132. return "\"" + CEscape(default_value_string()) + "\"";
  1133. } else {
  1134. if (type() == TYPE_BYTES) {
  1135. return CEscape(default_value_string());
  1136. } else {
  1137. return default_value_string();
  1138. }
  1139. }
  1140. break;
  1141. case CPPTYPE_ENUM:
  1142. return default_value_enum()->name();
  1143. break;
  1144. case CPPTYPE_MESSAGE:
  1145. GOOGLE_LOG(DFATAL) << "Messages can't have default values!";
  1146. break;
  1147. }
  1148. GOOGLE_LOG(FATAL) << "Can't get here: failed to get default value as string";
  1149. return "";
  1150. }
  1151. // CopyTo methods ====================================================
  1152. void FileDescriptor::CopyTo(FileDescriptorProto* proto) const {
  1153. proto->set_name(name());
  1154. if (!package().empty()) proto->set_package(package());
  1155. for (int i = 0; i < dependency_count(); i++) {
  1156. proto->add_dependency(dependency(i)->name());
  1157. }
  1158. for (int i = 0; i < message_type_count(); i++) {
  1159. message_type(i)->CopyTo(proto->add_message_type());
  1160. }
  1161. for (int i = 0; i < enum_type_count(); i++) {
  1162. enum_type(i)->CopyTo(proto->add_enum_type());
  1163. }
  1164. for (int i = 0; i < service_count(); i++) {
  1165. service(i)->CopyTo(proto->add_service());
  1166. }
  1167. for (int i = 0; i < extension_count(); i++) {
  1168. extension(i)->CopyTo(proto->add_extension());
  1169. }
  1170. if (&options() != &FileOptions::default_instance()) {
  1171. proto->mutable_options()->CopyFrom(options());
  1172. }
  1173. }
  1174. void Descriptor::CopyTo(DescriptorProto* proto) const {
  1175. proto->set_name(name());
  1176. for (int i = 0; i < field_count(); i++) {
  1177. field(i)->CopyTo(proto->add_field());
  1178. }
  1179. for (int i = 0; i < nested_type_count(); i++) {
  1180. nested_type(i)->CopyTo(proto->add_nested_type());
  1181. }
  1182. for (int i = 0; i < enum_type_count(); i++) {
  1183. enum_type(i)->CopyTo(proto->add_enum_type());
  1184. }
  1185. for (int i = 0; i < extension_range_count(); i++) {
  1186. DescriptorProto::ExtensionRange* range = proto->add_extension_range();
  1187. range->set_start(extension_range(i)->start);
  1188. range->set_end(extension_range(i)->end);
  1189. }
  1190. for (int i = 0; i < extension_count(); i++) {
  1191. extension(i)->CopyTo(proto->add_extension());
  1192. }
  1193. if (&options() != &MessageOptions::default_instance()) {
  1194. proto->mutable_options()->CopyFrom(options());
  1195. }
  1196. }
  1197. void FieldDescriptor::CopyTo(FieldDescriptorProto* proto) const {
  1198. proto->set_name(name());
  1199. proto->set_number(number());
  1200. // Some compilers do not allow static_cast directly between two enum types,
  1201. // so we must cast to int first.
  1202. proto->set_label(static_cast<FieldDescriptorProto::Label>(
  1203. implicit_cast<int>(label())));
  1204. proto->set_type(static_cast<FieldDescriptorProto::Type>(
  1205. implicit_cast<int>(type())));
  1206. if (is_extension()) {
  1207. if (!containing_type()->is_unqualified_placeholder_) {
  1208. proto->set_extendee(".");
  1209. }
  1210. proto->mutable_extendee()->append(containing_type()->full_name());
  1211. }
  1212. if (cpp_type() == CPPTYPE_MESSAGE) {
  1213. if (message_type()->is_placeholder_) {
  1214. // We don't actually know if the type is a message type. It could be
  1215. // an enum.
  1216. proto->clear_type();
  1217. }
  1218. if (!message_type()->is_unqualified_placeholder_) {
  1219. proto->set_type_name(".");
  1220. }
  1221. proto->mutable_type_name()->append(message_type()->full_name());
  1222. } else if (cpp_type() == CPPTYPE_ENUM) {
  1223. if (!enum_type()->is_unqualified_placeholder_) {
  1224. proto->set_type_name(".");
  1225. }
  1226. proto->mutable_type_name()->append(enum_type()->full_name());
  1227. }
  1228. if (has_default_value()) {
  1229. proto->set_default_value(DefaultValueAsString(false));
  1230. }
  1231. if (&options() != &FieldOptions::default_instance()) {
  1232. proto->mutable_options()->CopyFrom(options());
  1233. }
  1234. }
  1235. void EnumDescriptor::CopyTo(EnumDescriptorProto* proto) const {
  1236. proto->set_name(name());
  1237. for (int i = 0; i < value_count(); i++) {
  1238. value(i)->CopyTo(proto->add_value());
  1239. }
  1240. if (&options() != &EnumOptions::default_instance()) {
  1241. proto->mutable_options()->CopyFrom(options());
  1242. }
  1243. }
  1244. void EnumValueDescriptor::CopyTo(EnumValueDescriptorProto* proto) const {
  1245. proto->set_name(name());
  1246. proto->set_number(number());
  1247. if (&options() != &EnumValueOptions::default_instance()) {
  1248. proto->mutable_options()->CopyFrom(options());
  1249. }
  1250. }
  1251. void ServiceDescriptor::CopyTo(ServiceDescriptorProto* proto) const {
  1252. proto->set_name(name());
  1253. for (int i = 0; i < method_count(); i++) {
  1254. method(i)->CopyTo(proto->add_method());
  1255. }
  1256. if (&options() != &ServiceOptions::default_instance()) {
  1257. proto->mutable_options()->CopyFrom(options());
  1258. }
  1259. }
  1260. void MethodDescriptor::CopyTo(MethodDescriptorProto* proto) const {
  1261. proto->set_name(name());
  1262. if (!input_type()->is_unqualified_placeholder_) {
  1263. proto->set_input_type(".");
  1264. }
  1265. proto->mutable_input_type()->append(input_type()->full_name());
  1266. if (!output_type()->is_unqualified_placeholder_) {
  1267. proto->set_output_type(".");
  1268. }
  1269. proto->mutable_output_type()->append(output_type()->full_name());
  1270. if (&options() != &MethodOptions::default_instance()) {
  1271. proto->mutable_options()->CopyFrom(options());
  1272. }
  1273. }
  1274. // DebugString methods ===============================================
  1275. namespace {
  1276. // Used by each of the option formatters.
  1277. bool RetrieveOptions(const Message &options, vector<string> *option_entries) {
  1278. option_entries->clear();
  1279. const Reflection* reflection = options.GetReflection();
  1280. vector<const FieldDescriptor*> fields;
  1281. reflection->ListFields(options, &fields);
  1282. for (int i = 0; i < fields.size(); i++) {
  1283. // Doesn't make sense to have message type fields here
  1284. if (fields[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
  1285. continue;
  1286. }
  1287. int count = 1;
  1288. bool repeated = false;
  1289. if (fields[i]->is_repeated()) {
  1290. count = reflection->FieldSize(options, fields[i]);
  1291. repeated = true;
  1292. }
  1293. for (int j = 0; j < count; j++) {
  1294. string fieldval;
  1295. TextFormat::PrintFieldValueToString(options, fields[i],
  1296. repeated ? count : -1, &fieldval);
  1297. option_entries->push_back(fields[i]->name() + " = " + fieldval);
  1298. }
  1299. }
  1300. return !option_entries->empty();
  1301. }
  1302. // Formats options that all appear together in brackets. Does not include
  1303. // brackets.
  1304. bool FormatBracketedOptions(const Message &options, string *output) {
  1305. vector<string> all_options;
  1306. if (RetrieveOptions(options, &all_options)) {
  1307. output->append(JoinStrings(all_options, ", "));
  1308. }
  1309. return !all_options.empty();
  1310. }
  1311. // Formats options one per line
  1312. bool FormatLineOptions(int depth, const Message &options, string *output) {
  1313. string prefix(depth * 2, ' ');
  1314. vector<string> all_options;
  1315. if (RetrieveOptions(options, &all_options)) {
  1316. for (int i = 0; i < all_options.size(); i++) {
  1317. strings::SubstituteAndAppend(output, "$0option $1;\n",
  1318. prefix, all_options[i]);
  1319. }
  1320. }
  1321. return !all_options.empty();
  1322. }
  1323. } // anonymous namespace
  1324. string FileDescriptor::DebugString() const {
  1325. string contents = "syntax = \"proto2\";\n\n";
  1326. for (int i = 0; i < dependency_count(); i++) {
  1327. strings::SubstituteAndAppend(&contents, "import \"$0\";\n",
  1328. dependency(i)->name());
  1329. }
  1330. if (!package().empty()) {
  1331. strings::SubstituteAndAppend(&contents, "package $0;\n\n", package());
  1332. }
  1333. if (FormatLineOptions(0, options(), &contents)) {
  1334. contents.append("\n"); // add some space if we had options
  1335. }
  1336. for (int i = 0; i < enum_type_count(); i++) {
  1337. enum_type(i)->DebugString(0, &contents);
  1338. contents.append("\n");
  1339. }
  1340. // Find all the 'group' type extensions; we will not output their nested
  1341. // definitions (those will be done with their group field descriptor).
  1342. set<const Descriptor*> groups;
  1343. for (int i = 0; i < extension_count(); i++) {
  1344. if (extension(i)->type() == FieldDescriptor::TYPE_GROUP) {
  1345. groups.insert(extension(i)->message_type());
  1346. }
  1347. }
  1348. for (int i = 0; i < message_type_count(); i++) {
  1349. if (groups.count(message_type(i)) == 0) {
  1350. strings::SubstituteAndAppend(&contents, "message $0",
  1351. message_type(i)->name());
  1352. message_type(i)->DebugString(0, &contents);
  1353. contents.append("\n");
  1354. }
  1355. }
  1356. for (int i = 0; i < service_count(); i++) {
  1357. service(i)->DebugString(&contents);
  1358. contents.append("\n");
  1359. }
  1360. const Descriptor* containing_type = NULL;
  1361. for (int i = 0; i < extension_count(); i++) {
  1362. if (extension(i)->containing_type() != containing_type) {
  1363. if (i > 0) contents.append("}\n\n");
  1364. containing_type = extension(i)->containing_type();
  1365. strings::SubstituteAndAppend(&contents, "extend .$0 {\n",
  1366. containing_type->full_name());
  1367. }
  1368. extension(i)->DebugString(1, &contents);
  1369. }
  1370. if (extension_count() > 0) contents.append("}\n\n");
  1371. return contents;
  1372. }
  1373. string Descriptor::DebugString() const {
  1374. string contents;
  1375. strings::SubstituteAndAppend(&contents, "message $0", name());
  1376. DebugString(0, &contents);
  1377. return contents;
  1378. }
  1379. void Descriptor::DebugString(int depth, string *contents) const {
  1380. string prefix(depth * 2, ' ');
  1381. ++depth;
  1382. contents->append(" {\n");
  1383. FormatLineOptions(depth, options(), contents);
  1384. // Find all the 'group' types for fields and extensions; we will not output
  1385. // their nested definitions (those will be done with their group field
  1386. // descriptor).
  1387. set<const Descriptor*> groups;
  1388. for (int i = 0; i < field_count(); i++) {
  1389. if (field(i)->type() == FieldDescriptor::TYPE_GROUP) {
  1390. groups.insert(field(i)->message_type());
  1391. }
  1392. }
  1393. for (int i = 0; i < extension_count(); i++) {
  1394. if (extension(i)->type() == FieldDescriptor::TYPE_GROUP) {
  1395. groups.insert(extension(i)->message_type());
  1396. }
  1397. }
  1398. for (int i = 0; i < nested_type_count(); i++) {
  1399. if (groups.count(nested_type(i)) == 0) {
  1400. strings::SubstituteAndAppend(contents, "$0 message $1",
  1401. prefix, nested_type(i)->name());
  1402. nested_type(i)->DebugString(depth, contents);
  1403. }
  1404. }
  1405. for (int i = 0; i < enum_type_count(); i++) {
  1406. enum_type(i)->DebugString(depth, contents);
  1407. }
  1408. for (int i = 0; i < field_count(); i++) {
  1409. field(i)->DebugString(depth, contents);
  1410. }
  1411. for (int i = 0; i < extension_range_count(); i++) {
  1412. strings::SubstituteAndAppend(contents, "$0 extensions $1 to $2;\n",
  1413. prefix,
  1414. extension_range(i)->start,
  1415. extension_range(i)->end - 1);
  1416. }
  1417. // Group extensions by what they extend, so they can be printed out together.
  1418. const Descriptor* containing_type = NULL;
  1419. for (int i = 0; i < extension_count(); i++) {
  1420. if (extension(i)->containing_type() != containing_type) {
  1421. if (i > 0) strings::SubstituteAndAppend(contents, "$0 }\n", prefix);
  1422. containing_type = extension(i)->containing_type();
  1423. strings::SubstituteAndAppend(contents, "$0 extend .$1 {\n",
  1424. prefix, containing_type->full_name());
  1425. }
  1426. extension(i)->DebugString(depth + 1, contents);
  1427. }
  1428. if (extension_count() > 0)
  1429. strings::SubstituteAndAppend(contents, "$0 }\n", prefix);
  1430. strings::SubstituteAndAppend(contents, "$0}\n", prefix);
  1431. }
  1432. string FieldDescriptor::DebugString() const {
  1433. string contents;
  1434. int depth = 0;
  1435. if (is_extension()) {
  1436. strings::SubstituteAndAppend(&contents, "extend .$0 {\n",
  1437. containing_type()->full_name());
  1438. depth = 1;
  1439. }
  1440. DebugString(depth, &contents);
  1441. if (is_extension()) {
  1442. contents.append("}\n");
  1443. }
  1444. return contents;
  1445. }
  1446. void FieldDescriptor::DebugString(int depth, string *contents) const {
  1447. string prefix(depth * 2, ' ');
  1448. string field_type;
  1449. switch (type()) {
  1450. case TYPE_MESSAGE:
  1451. field_type = "." + message_type()->full_name();
  1452. break;
  1453. case TYPE_ENUM:
  1454. field_type = "." + enum_type()->full_name();
  1455. break;
  1456. default:
  1457. field_type = kTypeToName[type()];
  1458. }
  1459. strings::SubstituteAndAppend(contents, "$0$1 $2 $3 = $4",
  1460. prefix,
  1461. kLabelToName[label()],
  1462. field_type,
  1463. type() == TYPE_GROUP ? message_type()->name() :
  1464. name(),
  1465. number());
  1466. bool bracketed = false;
  1467. if (has_default_value()) {
  1468. bracketed = true;
  1469. strings::SubstituteAndAppend(contents, " [default = $0",
  1470. DefaultValueAsString(true));
  1471. }
  1472. string formatted_options;
  1473. if (FormatBracketedOptions(options(), &formatted_options)) {
  1474. contents->append(bracketed ? ", " : " [");
  1475. bracketed = true;
  1476. contents->append(formatted_options);
  1477. }
  1478. if (bracketed) {
  1479. contents->append("]");
  1480. }
  1481. if (type() == TYPE_GROUP) {
  1482. message_type()->DebugString(depth, contents);
  1483. } else {
  1484. contents->append(";\n");
  1485. }
  1486. }
  1487. string EnumDescriptor::DebugString() const {
  1488. string contents;
  1489. DebugString(0, &contents);
  1490. return contents;
  1491. }
  1492. void EnumDescriptor::DebugString(int depth, string *contents) const {
  1493. string prefix(depth * 2, ' ');
  1494. ++depth;
  1495. strings::SubstituteAndAppend(contents, "$0enum $1 {\n",
  1496. prefix, name());
  1497. FormatLineOptions(depth, options(), contents);
  1498. for (int i = 0; i < value_count(); i++) {
  1499. value(i)->DebugString(depth, contents);
  1500. }
  1501. strings::SubstituteAndAppend(contents, "$0}\n", prefix);
  1502. }
  1503. string EnumValueDescriptor::DebugString() const {
  1504. string contents;
  1505. DebugString(0, &contents);
  1506. return contents;
  1507. }
  1508. void EnumValueDescriptor::DebugString(int depth, string *contents) const {
  1509. string prefix(depth * 2, ' ');
  1510. strings::SubstituteAndAppend(contents, "$0$1 = $2",
  1511. prefix, name(), number());
  1512. string formatted_options;
  1513. if (FormatBracketedOptions(options(), &formatted_options)) {
  1514. strings::SubstituteAndAppend(contents, " [$0]", formatted_options);
  1515. }
  1516. contents->append(";\n");
  1517. }
  1518. string ServiceDescriptor::DebugString() const {
  1519. string contents;
  1520. DebugString(&contents);
  1521. return contents;
  1522. }
  1523. void ServiceDescriptor::DebugString(string *contents) const {
  1524. strings::SubstituteAndAppend(contents, "service $0 {\n", name());
  1525. FormatLineOptions(1, options(), contents);
  1526. for (int i = 0; i < method_count(); i++) {
  1527. method(i)->DebugString(1, contents);
  1528. }
  1529. contents->append("}\n");
  1530. }
  1531. string MethodDescriptor::DebugString() const {
  1532. string contents;
  1533. DebugString(0, &contents);
  1534. return contents;
  1535. }
  1536. void MethodDescriptor::DebugString(int depth, string *contents) const {
  1537. string prefix(depth * 2, ' ');
  1538. ++depth;
  1539. strings::SubstituteAndAppend(contents, "$0rpc $1(.$2) returns (.$3)",
  1540. prefix, name(),
  1541. input_type()->full_name(),
  1542. output_type()->full_name());
  1543. string formatted_options;
  1544. if (FormatLineOptions(depth, options(), &formatted_options)) {
  1545. strings::SubstituteAndAppend(contents, " {\n$0$1}\n",
  1546. formatted_options, prefix);
  1547. } else {
  1548. contents->append(";\n");
  1549. }
  1550. }
  1551. // ===================================================================
  1552. namespace {
  1553. // Represents an options message to interpret. Extension names in the option
  1554. // name are respolved relative to name_scope. element_name and orig_opt are
  1555. // used only for error reporting (since the parser records locations against
  1556. // pointers in the original options, not the mutable copy). The Message must be
  1557. // one of the Options messages in descriptor.proto.
  1558. struct OptionsToInterpret {
  1559. OptionsToInterpret(const string& ns,
  1560. const string& el,
  1561. const Message* orig_opt,
  1562. Message* opt)
  1563. : name_scope(ns),
  1564. element_name(el),
  1565. original_options(orig_opt),
  1566. options(opt) {
  1567. }
  1568. string name_scope;
  1569. string element_name;
  1570. const Message* original_options;
  1571. Message* options;
  1572. };
  1573. } // namespace
  1574. class DescriptorBuilder {
  1575. public:
  1576. DescriptorBuilder(const DescriptorPool* pool,
  1577. DescriptorPool::Tables* tables,
  1578. DescriptorPool::ErrorCollector* error_collector);
  1579. ~DescriptorBuilder();
  1580. const FileDescriptor* BuildFile(const FileDescriptorProto& proto);
  1581. private:
  1582. friend class OptionInterpreter;
  1583. const DescriptorPool* pool_;
  1584. DescriptorPool::Tables* tables_; // for convenience
  1585. DescriptorPool::ErrorCollector* error_collector_;
  1586. // As we build descriptors we store copies of the options messages in
  1587. // them. We put pointers to those copies in this vector, as we build, so we
  1588. // can later (after cross-linking) interpret those options.
  1589. vector<OptionsToInterpret> options_to_interpret_;
  1590. bool had_errors_;
  1591. string filename_;
  1592. FileDescriptor* file_;
  1593. FileDescriptorTables* file_tables_;
  1594. // If LookupSymbol() finds a symbol that is in a file which is not a declared
  1595. // dependency of this file, it will fail, but will set
  1596. // possible_undeclared_dependency_ to point at that file. This is only used
  1597. // by AddNotDefinedError() to report a more useful error message.
  1598. // possible_undeclared_dependency_name_ is the name of the symbol that was
  1599. // actually found in possible_undeclared_dependency_, which may be a parent
  1600. // of the symbol actually looked for.
  1601. const FileDescriptor* possible_undeclared_dependency_;
  1602. string possible_undeclared_dependency_name_;
  1603. void AddError(const string& element_name,
  1604. const Message& descriptor,
  1605. DescriptorPool::ErrorCollector::ErrorLocation location,
  1606. const string& error);
  1607. // Adds an error indicating that undefined_symbol was not defined. Must
  1608. // only be called after LookupSymbol() fails.
  1609. void AddNotDefinedError(
  1610. const string& element_name,
  1611. const Message& descriptor,
  1612. DescriptorPool::ErrorCollector::ErrorLocation location,
  1613. const string& undefined_symbol);
  1614. // Silly helper which determines if the given file is in the given package.
  1615. // I.e., either file->package() == package_name or file->package() is a
  1616. // nested package within package_name.
  1617. bool IsInPackage(const FileDescriptor* file, const string& package_name);
  1618. // Like tables_->FindSymbol(), but additionally:
  1619. // - Search the pool's underlay if not found in tables_.
  1620. // - Insure that the resulting Symbol is from one of the file's declared
  1621. // dependencies.
  1622. Symbol FindSymbol(const string& name);
  1623. // Like FindSymbol() but does not require that the symbol is in one of the
  1624. // file's declared dependencies.
  1625. Symbol FindSymbolNotEnforcingDeps(const string& name);
  1626. // Like FindSymbol(), but looks up the name relative to some other symbol
  1627. // name. This first searches siblings of relative_to, then siblings of its
  1628. // parents, etc. For example, LookupSymbol("foo.bar", "baz.qux.corge") makes
  1629. // the following calls, returning the first non-null result:
  1630. // FindSymbol("baz.qux.foo.bar"), FindSymbol("baz.foo.bar"),
  1631. // FindSymbol("foo.bar"). If AllowUnknownDependencies() has been called
  1632. // on the DescriptorPool, this will generate a placeholder type if
  1633. // the name is not found (unless the name itself is malformed). The
  1634. // placeholder_type parameter indicates what kind of placeholder should be
  1635. // constructed in this case. The resolve_mode parameter determines whether
  1636. // any symbol is returned, or only symbols that are types. Note, however,
  1637. // that LookupSymbol may still return a non-type symbol in LOOKUP_TYPES mode,
  1638. // if it believes that's all it could refer to. The caller should always
  1639. // check that it receives the type of symbol it was expecting.
  1640. enum PlaceholderType {
  1641. PLACEHOLDER_MESSAGE,
  1642. PLACEHOLDER_ENUM,
  1643. PLACEHOLDER_EXTENDABLE_MESSAGE
  1644. };
  1645. enum ResolveMode {
  1646. LOOKUP_ALL, LOOKUP_TYPES
  1647. };
  1648. Symbol LookupSymbol(const string& name, const string& relative_to,
  1649. PlaceholderType placeholder_type = PLACEHOLDER_MESSAGE,
  1650. ResolveMode resolve_mode = LOOKUP_ALL);
  1651. // Like LookupSymbol() but will not return a placeholder even if
  1652. // AllowUnknownDependencies() has been used.
  1653. Symbol LookupSymbolNoPlaceholder(const string& name,
  1654. const string& relative_to,
  1655. ResolveMode resolve_mode = LOOKUP_ALL);
  1656. // Creates a placeholder type suitable for return from LookupSymbol(). May
  1657. // return kNullSymbol if the name is not a valid type name.
  1658. Symbol NewPlaceholder(const string& name, PlaceholderType placeholder_type);
  1659. // Creates a placeholder file. Never returns NULL. This is used when an
  1660. // import is not found and AllowUnknownDependencies() is enabled.
  1661. const FileDescriptor* NewPlaceholderFile(const string& name);
  1662. // Calls tables_->AddSymbol() and records an error if it fails. Returns
  1663. // true if successful or false if failed, though most callers can ignore
  1664. // the return value since