诸暨麻将添加redis
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

615 行
22 KiB

  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. // 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/descriptor_database.h>
  34. #include <set>
  35. #include <google/protobuf/descriptor.pb.h>
  36. #include <google/protobuf/stubs/strutil.h>
  37. #include <google/protobuf/stubs/map_util.h>
  38. #include <google/protobuf/stubs/stl_util.h>
  39. namespace google {
  40. namespace protobuf {
  41. namespace {
  42. void RecordMessageNames(const DescriptorProto& desc_proto,
  43. const std::string& prefix,
  44. std::set<std::string>* output) {
  45. GOOGLE_CHECK(desc_proto.has_name());
  46. std::string full_name = prefix.empty()
  47. ? desc_proto.name()
  48. : StrCat(prefix, ".", desc_proto.name());
  49. output->insert(full_name);
  50. for (const auto& d : desc_proto.nested_type()) {
  51. RecordMessageNames(d, full_name, output);
  52. }
  53. }
  54. void RecordMessageNames(const FileDescriptorProto& file_proto,
  55. std::set<std::string>* output) {
  56. for (const auto& d : file_proto.message_type()) {
  57. RecordMessageNames(d, file_proto.package(), output);
  58. }
  59. }
  60. template <typename Fn>
  61. bool ForAllFileProtos(DescriptorDatabase* db, Fn callback,
  62. std::vector<std::string>* output) {
  63. std::vector<std::string> file_names;
  64. if (!db->FindAllFileNames(&file_names)) {
  65. return false;
  66. }
  67. std::set<std::string> set;
  68. FileDescriptorProto file_proto;
  69. for (const auto& f : file_names) {
  70. file_proto.Clear();
  71. if (!db->FindFileByName(f, &file_proto)) {
  72. GOOGLE_LOG(ERROR) << "File not found in database (unexpected): " << f;
  73. return false;
  74. }
  75. callback(file_proto, &set);
  76. }
  77. output->insert(output->end(), set.begin(), set.end());
  78. return true;
  79. }
  80. } // namespace
  81. DescriptorDatabase::~DescriptorDatabase() {}
  82. bool DescriptorDatabase::FindAllPackageNames(std::vector<std::string>* output) {
  83. return ForAllFileProtos(
  84. this,
  85. [](const FileDescriptorProto& file_proto, std::set<std::string>* set) {
  86. set->insert(file_proto.package());
  87. },
  88. output);
  89. }
  90. bool DescriptorDatabase::FindAllMessageNames(std::vector<std::string>* output) {
  91. return ForAllFileProtos(
  92. this,
  93. [](const FileDescriptorProto& file_proto, std::set<std::string>* set) {
  94. RecordMessageNames(file_proto, set);
  95. },
  96. output);
  97. }
  98. // ===================================================================
  99. SimpleDescriptorDatabase::SimpleDescriptorDatabase() {}
  100. SimpleDescriptorDatabase::~SimpleDescriptorDatabase() {}
  101. template <typename Value>
  102. bool SimpleDescriptorDatabase::DescriptorIndex<Value>::AddFile(
  103. const FileDescriptorProto& file, Value value) {
  104. if (!InsertIfNotPresent(&by_name_, file.name(), value)) {
  105. GOOGLE_LOG(ERROR) << "File already exists in database: " << file.name();
  106. return false;
  107. }
  108. // We must be careful here -- calling file.package() if file.has_package() is
  109. // false could access an uninitialized static-storage variable if we are being
  110. // run at startup time.
  111. std::string path = file.has_package() ? file.package() : std::string();
  112. if (!path.empty()) path += '.';
  113. for (int i = 0; i < file.message_type_size(); i++) {
  114. if (!AddSymbol(path + file.message_type(i).name(), value)) return false;
  115. if (!AddNestedExtensions(file.name(), file.message_type(i), value))
  116. return false;
  117. }
  118. for (int i = 0; i < file.enum_type_size(); i++) {
  119. if (!AddSymbol(path + file.enum_type(i).name(), value)) return false;
  120. }
  121. for (int i = 0; i < file.extension_size(); i++) {
  122. if (!AddSymbol(path + file.extension(i).name(), value)) return false;
  123. if (!AddExtension(file.name(), file.extension(i), value)) return false;
  124. }
  125. for (int i = 0; i < file.service_size(); i++) {
  126. if (!AddSymbol(path + file.service(i).name(), value)) return false;
  127. }
  128. return true;
  129. }
  130. template <typename Value>
  131. bool SimpleDescriptorDatabase::DescriptorIndex<Value>::AddSymbol(
  132. const std::string& name, Value value) {
  133. // We need to make sure not to violate our map invariant.
  134. // If the symbol name is invalid it could break our lookup algorithm (which
  135. // relies on the fact that '.' sorts before all other characters that are
  136. // valid in symbol names).
  137. if (!ValidateSymbolName(name)) {
  138. GOOGLE_LOG(ERROR) << "Invalid symbol name: " << name;
  139. return false;
  140. }
  141. // Try to look up the symbol to make sure a super-symbol doesn't already
  142. // exist.
  143. typename std::map<std::string, Value>::iterator iter =
  144. FindLastLessOrEqual(name);
  145. if (iter == by_symbol_.end()) {
  146. // Apparently the map is currently empty. Just insert and be done with it.
  147. by_symbol_.insert(
  148. typename std::map<std::string, Value>::value_type(name, value));
  149. return true;
  150. }
  151. if (IsSubSymbol(iter->first, name)) {
  152. GOOGLE_LOG(ERROR) << "Symbol name \"" << name
  153. << "\" conflicts with the existing "
  154. "symbol \""
  155. << iter->first << "\".";
  156. return false;
  157. }
  158. // OK, that worked. Now we have to make sure that no symbol in the map is
  159. // a sub-symbol of the one we are inserting. The only symbol which could
  160. // be so is the first symbol that is greater than the new symbol. Since
  161. // |iter| points at the last symbol that is less than or equal, we just have
  162. // to increment it.
  163. ++iter;
  164. if (iter != by_symbol_.end() && IsSubSymbol(name, iter->first)) {
  165. GOOGLE_LOG(ERROR) << "Symbol name \"" << name
  166. << "\" conflicts with the existing "
  167. "symbol \""
  168. << iter->first << "\".";
  169. return false;
  170. }
  171. // OK, no conflicts.
  172. // Insert the new symbol using the iterator as a hint, the new entry will
  173. // appear immediately before the one the iterator is pointing at.
  174. by_symbol_.insert(
  175. iter, typename std::map<std::string, Value>::value_type(name, value));
  176. return true;
  177. }
  178. template <typename Value>
  179. bool SimpleDescriptorDatabase::DescriptorIndex<Value>::AddNestedExtensions(
  180. const std::string& filename, const DescriptorProto& message_type,
  181. Value value) {
  182. for (int i = 0; i < message_type.nested_type_size(); i++) {
  183. if (!AddNestedExtensions(filename, message_type.nested_type(i), value))
  184. return false;
  185. }
  186. for (int i = 0; i < message_type.extension_size(); i++) {
  187. if (!AddExtension(filename, message_type.extension(i), value)) return false;
  188. }
  189. return true;
  190. }
  191. template <typename Value>
  192. bool SimpleDescriptorDatabase::DescriptorIndex<Value>::AddExtension(
  193. const std::string& filename, const FieldDescriptorProto& field,
  194. Value value) {
  195. if (!field.extendee().empty() && field.extendee()[0] == '.') {
  196. // The extension is fully-qualified. We can use it as a lookup key in
  197. // the by_symbol_ table.
  198. if (!InsertIfNotPresent(
  199. &by_extension_,
  200. std::make_pair(field.extendee().substr(1), field.number()),
  201. value)) {
  202. GOOGLE_LOG(ERROR) << "Extension conflicts with extension already in database: "
  203. "extend "
  204. << field.extendee() << " { " << field.name() << " = "
  205. << field.number() << " } from:" << filename;
  206. return false;
  207. }
  208. } else {
  209. // Not fully-qualified. We can't really do anything here, unfortunately.
  210. // We don't consider this an error, though, because the descriptor is
  211. // valid.
  212. }
  213. return true;
  214. }
  215. template <typename Value>
  216. Value SimpleDescriptorDatabase::DescriptorIndex<Value>::FindFile(
  217. const std::string& filename) {
  218. return FindWithDefault(by_name_, filename, Value());
  219. }
  220. template <typename Value>
  221. Value SimpleDescriptorDatabase::DescriptorIndex<Value>::FindSymbol(
  222. const std::string& name) {
  223. typename std::map<std::string, Value>::iterator iter =
  224. FindLastLessOrEqual(name);
  225. return (iter != by_symbol_.end() && IsSubSymbol(iter->first, name))
  226. ? iter->second
  227. : Value();
  228. }
  229. template <typename Value>
  230. Value SimpleDescriptorDatabase::DescriptorIndex<Value>::FindExtension(
  231. const std::string& containing_type, int field_number) {
  232. return FindWithDefault(
  233. by_extension_, std::make_pair(containing_type, field_number), Value());
  234. }
  235. template <typename Value>
  236. bool SimpleDescriptorDatabase::DescriptorIndex<Value>::FindAllExtensionNumbers(
  237. const std::string& containing_type, std::vector<int>* output) {
  238. typename std::map<std::pair<std::string, int>, Value>::const_iterator it =
  239. by_extension_.lower_bound(std::make_pair(containing_type, 0));
  240. bool success = false;
  241. for (; it != by_extension_.end() && it->first.first == containing_type;
  242. ++it) {
  243. output->push_back(it->first.second);
  244. success = true;
  245. }
  246. return success;
  247. }
  248. template <typename Value>
  249. void SimpleDescriptorDatabase::DescriptorIndex<Value>::FindAllFileNames(
  250. std::vector<std::string>* output) {
  251. output->resize(by_name_.size());
  252. int i = 0;
  253. for (const auto& kv : by_name_) {
  254. (*output)[i] = kv.first;
  255. i++;
  256. }
  257. }
  258. template <typename Value>
  259. typename std::map<std::string, Value>::iterator
  260. SimpleDescriptorDatabase::DescriptorIndex<Value>::FindLastLessOrEqual(
  261. const std::string& name) {
  262. // Find the last key in the map which sorts less than or equal to the
  263. // symbol name. Since upper_bound() returns the *first* key that sorts
  264. // *greater* than the input, we want the element immediately before that.
  265. typename std::map<std::string, Value>::iterator iter =
  266. by_symbol_.upper_bound(name);
  267. if (iter != by_symbol_.begin()) --iter;
  268. return iter;
  269. }
  270. template <typename Value>
  271. bool SimpleDescriptorDatabase::DescriptorIndex<Value>::IsSubSymbol(
  272. const std::string& sub_symbol, const std::string& super_symbol) {
  273. return sub_symbol == super_symbol ||
  274. (HasPrefixString(super_symbol, sub_symbol) &&
  275. super_symbol[sub_symbol.size()] == '.');
  276. }
  277. template <typename Value>
  278. bool SimpleDescriptorDatabase::DescriptorIndex<Value>::ValidateSymbolName(
  279. const std::string& name) {
  280. for (int i = 0; i < name.size(); i++) {
  281. // I don't trust ctype.h due to locales. :(
  282. if (name[i] != '.' && name[i] != '_' && (name[i] < '0' || name[i] > '9') &&
  283. (name[i] < 'A' || name[i] > 'Z') && (name[i] < 'a' || name[i] > 'z')) {
  284. return false;
  285. }
  286. }
  287. return true;
  288. }
  289. // -------------------------------------------------------------------
  290. bool SimpleDescriptorDatabase::Add(const FileDescriptorProto& file) {
  291. FileDescriptorProto* new_file = new FileDescriptorProto;
  292. new_file->CopyFrom(file);
  293. return AddAndOwn(new_file);
  294. }
  295. bool SimpleDescriptorDatabase::AddAndOwn(const FileDescriptorProto* file) {
  296. files_to_delete_.emplace_back(file);
  297. return index_.AddFile(*file, file);
  298. }
  299. bool SimpleDescriptorDatabase::FindFileByName(const std::string& filename,
  300. FileDescriptorProto* output) {
  301. return MaybeCopy(index_.FindFile(filename), output);
  302. }
  303. bool SimpleDescriptorDatabase::FindFileContainingSymbol(
  304. const std::string& symbol_name, FileDescriptorProto* output) {
  305. return MaybeCopy(index_.FindSymbol(symbol_name), output);
  306. }
  307. bool SimpleDescriptorDatabase::FindFileContainingExtension(
  308. const std::string& containing_type, int field_number,
  309. FileDescriptorProto* output) {
  310. return MaybeCopy(index_.FindExtension(containing_type, field_number), output);
  311. }
  312. bool SimpleDescriptorDatabase::FindAllExtensionNumbers(
  313. const std::string& extendee_type, std::vector<int>* output) {
  314. return index_.FindAllExtensionNumbers(extendee_type, output);
  315. }
  316. bool SimpleDescriptorDatabase::FindAllFileNames(
  317. std::vector<std::string>* output) {
  318. index_.FindAllFileNames(output);
  319. return true;
  320. }
  321. bool SimpleDescriptorDatabase::MaybeCopy(const FileDescriptorProto* file,
  322. FileDescriptorProto* output) {
  323. if (file == NULL) return false;
  324. output->CopyFrom(*file);
  325. return true;
  326. }
  327. // -------------------------------------------------------------------
  328. EncodedDescriptorDatabase::EncodedDescriptorDatabase() {}
  329. EncodedDescriptorDatabase::~EncodedDescriptorDatabase() {
  330. for (int i = 0; i < files_to_delete_.size(); i++) {
  331. operator delete(files_to_delete_[i]);
  332. }
  333. }
  334. bool EncodedDescriptorDatabase::Add(const void* encoded_file_descriptor,
  335. int size) {
  336. FileDescriptorProto file;
  337. if (file.ParseFromArray(encoded_file_descriptor, size)) {
  338. return index_.AddFile(file, std::make_pair(encoded_file_descriptor, size));
  339. } else {
  340. GOOGLE_LOG(ERROR) << "Invalid file descriptor data passed to "
  341. "EncodedDescriptorDatabase::Add().";
  342. return false;
  343. }
  344. }
  345. bool EncodedDescriptorDatabase::AddCopy(const void* encoded_file_descriptor,
  346. int size) {
  347. void* copy = operator new(size);
  348. memcpy(copy, encoded_file_descriptor, size);
  349. files_to_delete_.push_back(copy);
  350. return Add(copy, size);
  351. }
  352. bool EncodedDescriptorDatabase::FindFileByName(const std::string& filename,
  353. FileDescriptorProto* output) {
  354. return MaybeParse(index_.FindFile(filename), output);
  355. }
  356. bool EncodedDescriptorDatabase::FindFileContainingSymbol(
  357. const std::string& symbol_name, FileDescriptorProto* output) {
  358. return MaybeParse(index_.FindSymbol(symbol_name), output);
  359. }
  360. bool EncodedDescriptorDatabase::FindNameOfFileContainingSymbol(
  361. const std::string& symbol_name, std::string* output) {
  362. std::pair<const void*, int> encoded_file = index_.FindSymbol(symbol_name);
  363. if (encoded_file.first == NULL) return false;
  364. // Optimization: The name should be the first field in the encoded message.
  365. // Try to just read it directly.
  366. io::CodedInputStream input(reinterpret_cast<const uint8*>(encoded_file.first),
  367. encoded_file.second);
  368. const uint32 kNameTag = internal::WireFormatLite::MakeTag(
  369. FileDescriptorProto::kNameFieldNumber,
  370. internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
  371. if (input.ReadTagNoLastTag() == kNameTag) {
  372. // Success!
  373. return internal::WireFormatLite::ReadString(&input, output);
  374. } else {
  375. // Slow path. Parse whole message.
  376. FileDescriptorProto file_proto;
  377. if (!file_proto.ParseFromArray(encoded_file.first, encoded_file.second)) {
  378. return false;
  379. }
  380. *output = file_proto.name();
  381. return true;
  382. }
  383. }
  384. bool EncodedDescriptorDatabase::FindFileContainingExtension(
  385. const std::string& containing_type, int field_number,
  386. FileDescriptorProto* output) {
  387. return MaybeParse(index_.FindExtension(containing_type, field_number),
  388. output);
  389. }
  390. bool EncodedDescriptorDatabase::FindAllExtensionNumbers(
  391. const std::string& extendee_type, std::vector<int>* output) {
  392. return index_.FindAllExtensionNumbers(extendee_type, output);
  393. }
  394. bool EncodedDescriptorDatabase::FindAllFileNames(
  395. std::vector<std::string>* output) {
  396. index_.FindAllFileNames(output);
  397. return true;
  398. }
  399. bool EncodedDescriptorDatabase::MaybeParse(
  400. std::pair<const void*, int> encoded_file, FileDescriptorProto* output) {
  401. if (encoded_file.first == NULL) return false;
  402. return output->ParseFromArray(encoded_file.first, encoded_file.second);
  403. }
  404. // ===================================================================
  405. DescriptorPoolDatabase::DescriptorPoolDatabase(const DescriptorPool& pool)
  406. : pool_(pool) {}
  407. DescriptorPoolDatabase::~DescriptorPoolDatabase() {}
  408. bool DescriptorPoolDatabase::FindFileByName(const std::string& filename,
  409. FileDescriptorProto* output) {
  410. const FileDescriptor* file = pool_.FindFileByName(filename);
  411. if (file == NULL) return false;
  412. output->Clear();
  413. file->CopyTo(output);
  414. return true;
  415. }
  416. bool DescriptorPoolDatabase::FindFileContainingSymbol(
  417. const std::string& symbol_name, FileDescriptorProto* output) {
  418. const FileDescriptor* file = pool_.FindFileContainingSymbol(symbol_name);
  419. if (file == NULL) return false;
  420. output->Clear();
  421. file->CopyTo(output);
  422. return true;
  423. }
  424. bool DescriptorPoolDatabase::FindFileContainingExtension(
  425. const std::string& containing_type, int field_number,
  426. FileDescriptorProto* output) {
  427. const Descriptor* extendee = pool_.FindMessageTypeByName(containing_type);
  428. if (extendee == NULL) return false;
  429. const FieldDescriptor* extension =
  430. pool_.FindExtensionByNumber(extendee, field_number);
  431. if (extension == NULL) return false;
  432. output->Clear();
  433. extension->file()->CopyTo(output);
  434. return true;
  435. }
  436. bool DescriptorPoolDatabase::FindAllExtensionNumbers(
  437. const std::string& extendee_type, std::vector<int>* output) {
  438. const Descriptor* extendee = pool_.FindMessageTypeByName(extendee_type);
  439. if (extendee == NULL) return false;
  440. std::vector<const FieldDescriptor*> extensions;
  441. pool_.FindAllExtensions(extendee, &extensions);
  442. for (int i = 0; i < extensions.size(); ++i) {
  443. output->push_back(extensions[i]->number());
  444. }
  445. return true;
  446. }
  447. // ===================================================================
  448. MergedDescriptorDatabase::MergedDescriptorDatabase(
  449. DescriptorDatabase* source1, DescriptorDatabase* source2) {
  450. sources_.push_back(source1);
  451. sources_.push_back(source2);
  452. }
  453. MergedDescriptorDatabase::MergedDescriptorDatabase(
  454. const std::vector<DescriptorDatabase*>& sources)
  455. : sources_(sources) {}
  456. MergedDescriptorDatabase::~MergedDescriptorDatabase() {}
  457. bool MergedDescriptorDatabase::FindFileByName(const std::string& filename,
  458. FileDescriptorProto* output) {
  459. for (int i = 0; i < sources_.size(); i++) {
  460. if (sources_[i]->FindFileByName(filename, output)) {
  461. return true;
  462. }
  463. }
  464. return false;
  465. }
  466. bool MergedDescriptorDatabase::FindFileContainingSymbol(
  467. const std::string& symbol_name, FileDescriptorProto* output) {
  468. for (int i = 0; i < sources_.size(); i++) {
  469. if (sources_[i]->FindFileContainingSymbol(symbol_name, output)) {
  470. // The symbol was found in source i. However, if one of the previous
  471. // sources defines a file with the same name (which presumably doesn't
  472. // contain the symbol, since it wasn't found in that source), then we
  473. // must hide it from the caller.
  474. FileDescriptorProto temp;
  475. for (int j = 0; j < i; j++) {
  476. if (sources_[j]->FindFileByName(output->name(), &temp)) {
  477. // Found conflicting file in a previous source.
  478. return false;
  479. }
  480. }
  481. return true;
  482. }
  483. }
  484. return false;
  485. }
  486. bool MergedDescriptorDatabase::FindFileContainingExtension(
  487. const std::string& containing_type, int field_number,
  488. FileDescriptorProto* output) {
  489. for (int i = 0; i < sources_.size(); i++) {
  490. if (sources_[i]->FindFileContainingExtension(containing_type, field_number,
  491. output)) {
  492. // The symbol was found in source i. However, if one of the previous
  493. // sources defines a file with the same name (which presumably doesn't
  494. // contain the symbol, since it wasn't found in that source), then we
  495. // must hide it from the caller.
  496. FileDescriptorProto temp;
  497. for (int j = 0; j < i; j++) {
  498. if (sources_[j]->FindFileByName(output->name(), &temp)) {
  499. // Found conflicting file in a previous source.
  500. return false;
  501. }
  502. }
  503. return true;
  504. }
  505. }
  506. return false;
  507. }
  508. bool MergedDescriptorDatabase::FindAllExtensionNumbers(
  509. const std::string& extendee_type, std::vector<int>* output) {
  510. std::set<int> merged_results;
  511. std::vector<int> results;
  512. bool success = false;
  513. for (int i = 0; i < sources_.size(); i++) {
  514. if (sources_[i]->FindAllExtensionNumbers(extendee_type, &results)) {
  515. std::copy(results.begin(), results.end(),
  516. std::insert_iterator<std::set<int> >(merged_results,
  517. merged_results.begin()));
  518. success = true;
  519. }
  520. results.clear();
  521. }
  522. std::copy(merged_results.begin(), merged_results.end(),
  523. std::insert_iterator<std::vector<int> >(*output, output->end()));
  524. return success;
  525. }
  526. } // namespace protobuf
  527. } // namespace google