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

http://github.com/tomahawk-player/tomahawk · C++ · 748 lines · 552 code · 99 blank · 97 comment · 3 complexity · 0edfa43a07598cc7a8ca05b7e0f38560 MD5 · raw file

  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. //
  34. // This file makes extensive use of RFC 3092. :)
  35. #include <algorithm>
  36. #include <google/protobuf/descriptor_database.h>
  37. #include <google/protobuf/descriptor.h>
  38. #include <google/protobuf/descriptor.pb.h>
  39. #include <google/protobuf/text_format.h>
  40. #include <google/protobuf/stubs/strutil.h>
  41. #include <google/protobuf/stubs/common.h>
  42. #include <google/protobuf/testing/googletest.h>
  43. #include <gtest/gtest.h>
  44. namespace google {
  45. namespace protobuf {
  46. namespace {
  47. static void AddToDatabase(SimpleDescriptorDatabase* database,
  48. const char* file_text) {
  49. FileDescriptorProto file_proto;
  50. EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
  51. database->Add(file_proto);
  52. }
  53. static void ExpectContainsType(const FileDescriptorProto& proto,
  54. const string& type_name) {
  55. for (int i = 0; i < proto.message_type_size(); i++) {
  56. if (proto.message_type(i).name() == type_name) return;
  57. }
  58. ADD_FAILURE() << "\"" << proto.name()
  59. << "\" did not contain expected type \""
  60. << type_name << "\".";
  61. }
  62. // ===================================================================
  63. #if GTEST_HAS_PARAM_TEST
  64. // SimpleDescriptorDatabase, EncodedDescriptorDatabase, and
  65. // DescriptorPoolDatabase call for very similar tests. Instead of writing
  66. // three nearly-identical sets of tests, we use parameterized tests to apply
  67. // the same code to all three.
  68. // The parameterized test runs against a DescriptarDatabaseTestCase. We have
  69. // implementations for each of the three classes we want to test.
  70. class DescriptorDatabaseTestCase {
  71. public:
  72. virtual ~DescriptorDatabaseTestCase() {}
  73. virtual DescriptorDatabase* GetDatabase() = 0;
  74. virtual bool AddToDatabase(const FileDescriptorProto& file) = 0;
  75. };
  76. // Factory function type.
  77. typedef DescriptorDatabaseTestCase* DescriptorDatabaseTestCaseFactory();
  78. // Specialization for SimpleDescriptorDatabase.
  79. class SimpleDescriptorDatabaseTestCase : public DescriptorDatabaseTestCase {
  80. public:
  81. static DescriptorDatabaseTestCase* New() {
  82. return new SimpleDescriptorDatabaseTestCase;
  83. }
  84. virtual ~SimpleDescriptorDatabaseTestCase() {}
  85. virtual DescriptorDatabase* GetDatabase() {
  86. return &database_;
  87. }
  88. virtual bool AddToDatabase(const FileDescriptorProto& file) {
  89. return database_.Add(file);
  90. }
  91. private:
  92. SimpleDescriptorDatabase database_;
  93. };
  94. // Specialization for EncodedDescriptorDatabase.
  95. class EncodedDescriptorDatabaseTestCase : public DescriptorDatabaseTestCase {
  96. public:
  97. static DescriptorDatabaseTestCase* New() {
  98. return new EncodedDescriptorDatabaseTestCase;
  99. }
  100. virtual ~EncodedDescriptorDatabaseTestCase() {}
  101. virtual DescriptorDatabase* GetDatabase() {
  102. return &database_;
  103. }
  104. virtual bool AddToDatabase(const FileDescriptorProto& file) {
  105. string data;
  106. file.SerializeToString(&data);
  107. return database_.AddCopy(data.data(), data.size());
  108. }
  109. private:
  110. EncodedDescriptorDatabase database_;
  111. };
  112. // Specialization for DescriptorPoolDatabase.
  113. class DescriptorPoolDatabaseTestCase : public DescriptorDatabaseTestCase {
  114. public:
  115. static DescriptorDatabaseTestCase* New() {
  116. return new EncodedDescriptorDatabaseTestCase;
  117. }
  118. DescriptorPoolDatabaseTestCase() : database_(pool_) {}
  119. virtual ~DescriptorPoolDatabaseTestCase() {}
  120. virtual DescriptorDatabase* GetDatabase() {
  121. return &database_;
  122. }
  123. virtual bool AddToDatabase(const FileDescriptorProto& file) {
  124. return pool_.BuildFile(file);
  125. }
  126. private:
  127. DescriptorPool pool_;
  128. DescriptorPoolDatabase database_;
  129. };
  130. // -------------------------------------------------------------------
  131. class DescriptorDatabaseTest
  132. : public testing::TestWithParam<DescriptorDatabaseTestCaseFactory*> {
  133. protected:
  134. virtual void SetUp() {
  135. test_case_.reset(GetParam()());
  136. database_ = test_case_->GetDatabase();
  137. }
  138. void AddToDatabase(const char* file_descriptor_text) {
  139. FileDescriptorProto file_proto;
  140. EXPECT_TRUE(TextFormat::ParseFromString(file_descriptor_text, &file_proto));
  141. EXPECT_TRUE(test_case_->AddToDatabase(file_proto));
  142. }
  143. void AddToDatabaseWithError(const char* file_descriptor_text) {
  144. FileDescriptorProto file_proto;
  145. EXPECT_TRUE(TextFormat::ParseFromString(file_descriptor_text, &file_proto));
  146. EXPECT_FALSE(test_case_->AddToDatabase(file_proto));
  147. }
  148. scoped_ptr<DescriptorDatabaseTestCase> test_case_;
  149. DescriptorDatabase* database_;
  150. };
  151. TEST_P(DescriptorDatabaseTest, FindFileByName) {
  152. AddToDatabase(
  153. "name: \"foo.proto\" "
  154. "message_type { name:\"Foo\" }");
  155. AddToDatabase(
  156. "name: \"bar.proto\" "
  157. "message_type { name:\"Bar\" }");
  158. {
  159. FileDescriptorProto file;
  160. EXPECT_TRUE(database_->FindFileByName("foo.proto", &file));
  161. EXPECT_EQ("foo.proto", file.name());
  162. ExpectContainsType(file, "Foo");
  163. }
  164. {
  165. FileDescriptorProto file;
  166. EXPECT_TRUE(database_->FindFileByName("bar.proto", &file));
  167. EXPECT_EQ("bar.proto", file.name());
  168. ExpectContainsType(file, "Bar");
  169. }
  170. {
  171. // Fails to find undefined files.
  172. FileDescriptorProto file;
  173. EXPECT_FALSE(database_->FindFileByName("baz.proto", &file));
  174. }
  175. }
  176. TEST_P(DescriptorDatabaseTest, FindFileContainingSymbol) {
  177. AddToDatabase(
  178. "name: \"foo.proto\" "
  179. "message_type { "
  180. " name: \"Foo\" "
  181. " field { name:\"qux\" }"
  182. " nested_type { name: \"Grault\" } "
  183. " enum_type { name: \"Garply\" } "
  184. "} "
  185. "enum_type { "
  186. " name: \"Waldo\" "
  187. " value { name:\"FRED\" } "
  188. "} "
  189. "extension { name: \"plugh\" } "
  190. "service { "
  191. " name: \"Xyzzy\" "
  192. " method { name: \"Thud\" } "
  193. "}"
  194. );
  195. AddToDatabase(
  196. "name: \"bar.proto\" "
  197. "package: \"corge\" "
  198. "message_type { name: \"Bar\" }");
  199. {
  200. FileDescriptorProto file;
  201. EXPECT_TRUE(database_->FindFileContainingSymbol("Foo", &file));
  202. EXPECT_EQ("foo.proto", file.name());
  203. }
  204. {
  205. // Can find fields.
  206. FileDescriptorProto file;
  207. EXPECT_TRUE(database_->FindFileContainingSymbol("Foo.qux", &file));
  208. EXPECT_EQ("foo.proto", file.name());
  209. }
  210. {
  211. // Can find nested types.
  212. FileDescriptorProto file;
  213. EXPECT_TRUE(database_->FindFileContainingSymbol("Foo.Grault", &file));
  214. EXPECT_EQ("foo.proto", file.name());
  215. }
  216. {
  217. // Can find nested enums.
  218. FileDescriptorProto file;
  219. EXPECT_TRUE(database_->FindFileContainingSymbol("Foo.Garply", &file));
  220. EXPECT_EQ("foo.proto", file.name());
  221. }
  222. {
  223. // Can find enum types.
  224. FileDescriptorProto file;
  225. EXPECT_TRUE(database_->FindFileContainingSymbol("Waldo", &file));
  226. EXPECT_EQ("foo.proto", file.name());
  227. }
  228. {
  229. // Can find enum values.
  230. FileDescriptorProto file;
  231. EXPECT_TRUE(database_->FindFileContainingSymbol("Waldo.FRED", &file));
  232. EXPECT_EQ("foo.proto", file.name());
  233. }
  234. {
  235. // Can find extensions.
  236. FileDescriptorProto file;
  237. EXPECT_TRUE(database_->FindFileContainingSymbol("plugh", &file));
  238. EXPECT_EQ("foo.proto", file.name());
  239. }
  240. {
  241. // Can find services.
  242. FileDescriptorProto file;
  243. EXPECT_TRUE(database_->FindFileContainingSymbol("Xyzzy", &file));
  244. EXPECT_EQ("foo.proto", file.name());
  245. }
  246. {
  247. // Can find methods.
  248. FileDescriptorProto file;
  249. EXPECT_TRUE(database_->FindFileContainingSymbol("Xyzzy.Thud", &file));
  250. EXPECT_EQ("foo.proto", file.name());
  251. }
  252. {
  253. // Can find things in packages.
  254. FileDescriptorProto file;
  255. EXPECT_TRUE(database_->FindFileContainingSymbol("corge.Bar", &file));
  256. EXPECT_EQ("bar.proto", file.name());
  257. }
  258. {
  259. // Fails to find undefined symbols.
  260. FileDescriptorProto file;
  261. EXPECT_FALSE(database_->FindFileContainingSymbol("Baz", &file));
  262. }
  263. {
  264. // Names must be fully-qualified.
  265. FileDescriptorProto file;
  266. EXPECT_FALSE(database_->FindFileContainingSymbol("Bar", &file));
  267. }
  268. }
  269. TEST_P(DescriptorDatabaseTest, FindFileContainingExtension) {
  270. AddToDatabase(
  271. "name: \"foo.proto\" "
  272. "message_type { "
  273. " name: \"Foo\" "
  274. " extension_range { start: 1 end: 1000 } "
  275. " extension { name:\"qux\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 "
  276. " extendee: \".Foo\" }"
  277. "}");
  278. AddToDatabase(
  279. "name: \"bar.proto\" "
  280. "package: \"corge\" "
  281. "dependency: \"foo.proto\" "
  282. "message_type { "
  283. " name: \"Bar\" "
  284. " extension_range { start: 1 end: 1000 } "
  285. "} "
  286. "extension { name:\"grault\" extendee: \".Foo\" number:32 } "
  287. "extension { name:\"garply\" extendee: \".corge.Bar\" number:70 } "
  288. "extension { name:\"waldo\" extendee: \"Bar\" number:56 } ");
  289. {
  290. FileDescriptorProto file;
  291. EXPECT_TRUE(database_->FindFileContainingExtension("Foo", 5, &file));
  292. EXPECT_EQ("foo.proto", file.name());
  293. }
  294. {
  295. FileDescriptorProto file;
  296. EXPECT_TRUE(database_->FindFileContainingExtension("Foo", 32, &file));
  297. EXPECT_EQ("bar.proto", file.name());
  298. }
  299. {
  300. // Can find extensions for qualified type names.
  301. FileDescriptorProto file;
  302. EXPECT_TRUE(database_->FindFileContainingExtension("corge.Bar", 70, &file));
  303. EXPECT_EQ("bar.proto", file.name());
  304. }
  305. {
  306. // Can't find extensions whose extendee was not fully-qualified in the
  307. // FileDescriptorProto.
  308. FileDescriptorProto file;
  309. EXPECT_FALSE(database_->FindFileContainingExtension("Bar", 56, &file));
  310. EXPECT_FALSE(
  311. database_->FindFileContainingExtension("corge.Bar", 56, &file));
  312. }
  313. {
  314. // Can't find non-existent extension numbers.
  315. FileDescriptorProto file;
  316. EXPECT_FALSE(database_->FindFileContainingExtension("Foo", 12, &file));
  317. }
  318. {
  319. // Can't find extensions for non-existent types.
  320. FileDescriptorProto file;
  321. EXPECT_FALSE(
  322. database_->FindFileContainingExtension("NoSuchType", 5, &file));
  323. }
  324. {
  325. // Can't find extensions for unqualified type names.
  326. FileDescriptorProto file;
  327. EXPECT_FALSE(database_->FindFileContainingExtension("Bar", 70, &file));
  328. }
  329. }
  330. TEST_P(DescriptorDatabaseTest, FindAllExtensionNumbers) {
  331. AddToDatabase(
  332. "name: \"foo.proto\" "
  333. "message_type { "
  334. " name: \"Foo\" "
  335. " extension_range { start: 1 end: 1000 } "
  336. " extension { name:\"qux\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 "
  337. " extendee: \".Foo\" }"
  338. "}");
  339. AddToDatabase(
  340. "name: \"bar.proto\" "
  341. "package: \"corge\" "
  342. "dependency: \"foo.proto\" "
  343. "message_type { "
  344. " name: \"Bar\" "
  345. " extension_range { start: 1 end: 1000 } "
  346. "} "
  347. "extension { name:\"grault\" extendee: \".Foo\" number:32 } "
  348. "extension { name:\"garply\" extendee: \".corge.Bar\" number:70 } "
  349. "extension { name:\"waldo\" extendee: \"Bar\" number:56 } ");
  350. {
  351. vector<int> numbers;
  352. EXPECT_TRUE(database_->FindAllExtensionNumbers("Foo", &numbers));
  353. ASSERT_EQ(2, numbers.size());
  354. sort(numbers.begin(), numbers.end());
  355. EXPECT_EQ(5, numbers[0]);
  356. EXPECT_EQ(32, numbers[1]);
  357. }
  358. {
  359. vector<int> numbers;
  360. EXPECT_TRUE(database_->FindAllExtensionNumbers("corge.Bar", &numbers));
  361. // Note: won't find extension 56 due to the name not being fully qualified.
  362. ASSERT_EQ(1, numbers.size());
  363. EXPECT_EQ(70, numbers[0]);
  364. }
  365. {
  366. // Can't find extensions for non-existent types.
  367. vector<int> numbers;
  368. EXPECT_FALSE(database_->FindAllExtensionNumbers("NoSuchType", &numbers));
  369. }
  370. {
  371. // Can't find extensions for unqualified types.
  372. vector<int> numbers;
  373. EXPECT_FALSE(database_->FindAllExtensionNumbers("Bar", &numbers));
  374. }
  375. }
  376. TEST_P(DescriptorDatabaseTest, ConflictingFileError) {
  377. AddToDatabase(
  378. "name: \"foo.proto\" "
  379. "message_type { "
  380. " name: \"Foo\" "
  381. "}");
  382. AddToDatabaseWithError(
  383. "name: \"foo.proto\" "
  384. "message_type { "
  385. " name: \"Bar\" "
  386. "}");
  387. }
  388. TEST_P(DescriptorDatabaseTest, ConflictingTypeError) {
  389. AddToDatabase(
  390. "name: \"foo.proto\" "
  391. "message_type { "
  392. " name: \"Foo\" "
  393. "}");
  394. AddToDatabaseWithError(
  395. "name: \"bar.proto\" "
  396. "message_type { "
  397. " name: \"Foo\" "
  398. "}");
  399. }
  400. TEST_P(DescriptorDatabaseTest, ConflictingExtensionError) {
  401. AddToDatabase(
  402. "name: \"foo.proto\" "
  403. "extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 "
  404. " extendee: \".Foo\" }");
  405. AddToDatabaseWithError(
  406. "name: \"bar.proto\" "
  407. "extension { name:\"bar\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 "
  408. " extendee: \".Foo\" }");
  409. }
  410. INSTANTIATE_TEST_CASE_P(Simple, DescriptorDatabaseTest,
  411. testing::Values(&SimpleDescriptorDatabaseTestCase::New));
  412. INSTANTIATE_TEST_CASE_P(MemoryConserving, DescriptorDatabaseTest,
  413. testing::Values(&EncodedDescriptorDatabaseTestCase::New));
  414. INSTANTIATE_TEST_CASE_P(Pool, DescriptorDatabaseTest,
  415. testing::Values(&DescriptorPoolDatabaseTestCase::New));
  416. #endif // GTEST_HAS_PARAM_TEST
  417. TEST(EncodedDescriptorDatabaseExtraTest, FindNameOfFileContainingSymbol) {
  418. // Create two files, one of which is in two parts.
  419. FileDescriptorProto file1, file2a, file2b;
  420. file1.set_name("foo.proto");
  421. file1.set_package("foo");
  422. file1.add_message_type()->set_name("Foo");
  423. file2a.set_name("bar.proto");
  424. file2b.set_package("bar");
  425. file2b.add_message_type()->set_name("Bar");
  426. // Normal serialization allows our optimization to kick in.
  427. string data1 = file1.SerializeAsString();
  428. // Force out-of-order serialization to test slow path.
  429. string data2 = file2b.SerializeAsString() + file2a.SerializeAsString();
  430. // Create EncodedDescriptorDatabase containing both files.
  431. EncodedDescriptorDatabase db;
  432. db.Add(data1.data(), data1.size());
  433. db.Add(data2.data(), data2.size());
  434. // Test!
  435. string filename;
  436. EXPECT_TRUE(db.FindNameOfFileContainingSymbol("foo.Foo", &filename));
  437. EXPECT_EQ("foo.proto", filename);
  438. EXPECT_TRUE(db.FindNameOfFileContainingSymbol("foo.Foo.Blah", &filename));
  439. EXPECT_EQ("foo.proto", filename);
  440. EXPECT_TRUE(db.FindNameOfFileContainingSymbol("bar.Bar", &filename));
  441. EXPECT_EQ("bar.proto", filename);
  442. EXPECT_FALSE(db.FindNameOfFileContainingSymbol("foo", &filename));
  443. EXPECT_FALSE(db.FindNameOfFileContainingSymbol("bar", &filename));
  444. EXPECT_FALSE(db.FindNameOfFileContainingSymbol("baz.Baz", &filename));
  445. }
  446. // ===================================================================
  447. class MergedDescriptorDatabaseTest : public testing::Test {
  448. protected:
  449. MergedDescriptorDatabaseTest()
  450. : forward_merged_(&database1_, &database2_),
  451. reverse_merged_(&database2_, &database1_) {}
  452. virtual void SetUp() {
  453. AddToDatabase(&database1_,
  454. "name: \"foo.proto\" "
  455. "message_type { name:\"Foo\" extension_range { start: 1 end: 100 } } "
  456. "extension { name:\"foo_ext\" extendee: \".Foo\" number:3 "
  457. " label:LABEL_OPTIONAL type:TYPE_INT32 } ");
  458. AddToDatabase(&database2_,
  459. "name: \"bar.proto\" "
  460. "message_type { name:\"Bar\" extension_range { start: 1 end: 100 } } "
  461. "extension { name:\"bar_ext\" extendee: \".Bar\" number:5 "
  462. " label:LABEL_OPTIONAL type:TYPE_INT32 } ");
  463. // baz.proto exists in both pools, with different definitions.
  464. AddToDatabase(&database1_,
  465. "name: \"baz.proto\" "
  466. "message_type { name:\"Baz\" extension_range { start: 1 end: 100 } } "
  467. "message_type { name:\"FromPool1\" } "
  468. "extension { name:\"baz_ext\" extendee: \".Baz\" number:12 "
  469. " label:LABEL_OPTIONAL type:TYPE_INT32 } "
  470. "extension { name:\"database1_only_ext\" extendee: \".Baz\" number:13 "
  471. " label:LABEL_OPTIONAL type:TYPE_INT32 } ");
  472. AddToDatabase(&database2_,
  473. "name: \"baz.proto\" "
  474. "message_type { name:\"Baz\" extension_range { start: 1 end: 100 } } "
  475. "message_type { name:\"FromPool2\" } "
  476. "extension { name:\"baz_ext\" extendee: \".Baz\" number:12 "
  477. " label:LABEL_OPTIONAL type:TYPE_INT32 } ");
  478. }
  479. SimpleDescriptorDatabase database1_;
  480. SimpleDescriptorDatabase database2_;
  481. MergedDescriptorDatabase forward_merged_;
  482. MergedDescriptorDatabase reverse_merged_;
  483. };
  484. TEST_F(MergedDescriptorDatabaseTest, FindFileByName) {
  485. {
  486. // Can find file that is only in database1_.
  487. FileDescriptorProto file;
  488. EXPECT_TRUE(forward_merged_.FindFileByName("foo.proto", &file));
  489. EXPECT_EQ("foo.proto", file.name());
  490. ExpectContainsType(file, "Foo");
  491. }
  492. {
  493. // Can find file that is only in database2_.
  494. FileDescriptorProto file;
  495. EXPECT_TRUE(forward_merged_.FindFileByName("bar.proto", &file));
  496. EXPECT_EQ("bar.proto", file.name());
  497. ExpectContainsType(file, "Bar");
  498. }
  499. {
  500. // In forward_merged_, database1_'s baz.proto takes precedence.
  501. FileDescriptorProto file;
  502. EXPECT_TRUE(forward_merged_.FindFileByName("baz.proto", &file));
  503. EXPECT_EQ("baz.proto", file.name());
  504. ExpectContainsType(file, "FromPool1");
  505. }
  506. {
  507. // In reverse_merged_, database2_'s baz.proto takes precedence.
  508. FileDescriptorProto file;
  509. EXPECT_TRUE(reverse_merged_.FindFileByName("baz.proto", &file));
  510. EXPECT_EQ("baz.proto", file.name());
  511. ExpectContainsType(file, "FromPool2");
  512. }
  513. {
  514. // Can't find non-existent file.
  515. FileDescriptorProto file;
  516. EXPECT_FALSE(forward_merged_.FindFileByName("no_such.proto", &file));
  517. }
  518. }
  519. TEST_F(MergedDescriptorDatabaseTest, FindFileContainingSymbol) {
  520. {
  521. // Can find file that is only in database1_.
  522. FileDescriptorProto file;
  523. EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("Foo", &file));
  524. EXPECT_EQ("foo.proto", file.name());
  525. ExpectContainsType(file, "Foo");
  526. }
  527. {
  528. // Can find file that is only in database2_.
  529. FileDescriptorProto file;
  530. EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("Bar", &file));
  531. EXPECT_EQ("bar.proto", file.name());
  532. ExpectContainsType(file, "Bar");
  533. }
  534. {
  535. // In forward_merged_, database1_'s baz.proto takes precedence.
  536. FileDescriptorProto file;
  537. EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("Baz", &file));
  538. EXPECT_EQ("baz.proto", file.name());
  539. ExpectContainsType(file, "FromPool1");
  540. }
  541. {
  542. // In reverse_merged_, database2_'s baz.proto takes precedence.
  543. FileDescriptorProto file;
  544. EXPECT_TRUE(reverse_merged_.FindFileContainingSymbol("Baz", &file));
  545. EXPECT_EQ("baz.proto", file.name());
  546. ExpectContainsType(file, "FromPool2");
  547. }
  548. {
  549. // FromPool1 only shows up in forward_merged_ because it is masked by
  550. // database2_'s baz.proto in reverse_merged_.
  551. FileDescriptorProto file;
  552. EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("FromPool1", &file));
  553. EXPECT_FALSE(reverse_merged_.FindFileContainingSymbol("FromPool1", &file));
  554. }
  555. {
  556. // Can't find non-existent symbol.
  557. FileDescriptorProto file;
  558. EXPECT_FALSE(
  559. forward_merged_.FindFileContainingSymbol("NoSuchType", &file));
  560. }
  561. }
  562. TEST_F(MergedDescriptorDatabaseTest, FindFileContainingExtension) {
  563. {
  564. // Can find file that is only in database1_.
  565. FileDescriptorProto file;
  566. EXPECT_TRUE(
  567. forward_merged_.FindFileContainingExtension("Foo", 3, &file));
  568. EXPECT_EQ("foo.proto", file.name());
  569. ExpectContainsType(file, "Foo");
  570. }
  571. {
  572. // Can find file that is only in database2_.
  573. FileDescriptorProto file;
  574. EXPECT_TRUE(
  575. forward_merged_.FindFileContainingExtension("Bar", 5, &file));
  576. EXPECT_EQ("bar.proto", file.name());
  577. ExpectContainsType(file, "Bar");
  578. }
  579. {
  580. // In forward_merged_, database1_'s baz.proto takes precedence.
  581. FileDescriptorProto file;
  582. EXPECT_TRUE(
  583. forward_merged_.FindFileContainingExtension("Baz", 12, &file));
  584. EXPECT_EQ("baz.proto", file.name());
  585. ExpectContainsType(file, "FromPool1");
  586. }
  587. {
  588. // In reverse_merged_, database2_'s baz.proto takes precedence.
  589. FileDescriptorProto file;
  590. EXPECT_TRUE(
  591. reverse_merged_.FindFileContainingExtension("Baz", 12, &file));
  592. EXPECT_EQ("baz.proto", file.name());
  593. ExpectContainsType(file, "FromPool2");
  594. }
  595. {
  596. // Baz's extension 13 only shows up in forward_merged_ because it is
  597. // masked by database2_'s baz.proto in reverse_merged_.
  598. FileDescriptorProto file;
  599. EXPECT_TRUE(forward_merged_.FindFileContainingExtension("Baz", 13, &file));
  600. EXPECT_FALSE(reverse_merged_.FindFileContainingExtension("Baz", 13, &file));
  601. }
  602. {
  603. // Can't find non-existent extension.
  604. FileDescriptorProto file;
  605. EXPECT_FALSE(
  606. forward_merged_.FindFileContainingExtension("Foo", 6, &file));
  607. }
  608. }
  609. TEST_F(MergedDescriptorDatabaseTest, FindAllExtensionNumbers) {
  610. {
  611. // Message only has extension in database1_
  612. vector<int> numbers;
  613. EXPECT_TRUE(forward_merged_.FindAllExtensionNumbers("Foo", &numbers));
  614. ASSERT_EQ(1, numbers.size());
  615. EXPECT_EQ(3, numbers[0]);
  616. }
  617. {
  618. // Message only has extension in database2_
  619. vector<int> numbers;
  620. EXPECT_TRUE(forward_merged_.FindAllExtensionNumbers("Bar", &numbers));
  621. ASSERT_EQ(1, numbers.size());
  622. EXPECT_EQ(5, numbers[0]);
  623. }
  624. {
  625. // Merge results from the two databases.
  626. vector<int> numbers;
  627. EXPECT_TRUE(forward_merged_.FindAllExtensionNumbers("Baz", &numbers));
  628. ASSERT_EQ(2, numbers.size());
  629. sort(numbers.begin(), numbers.end());
  630. EXPECT_EQ(12, numbers[0]);
  631. EXPECT_EQ(13, numbers[1]);
  632. }
  633. {
  634. vector<int> numbers;
  635. EXPECT_TRUE(reverse_merged_.FindAllExtensionNumbers("Baz", &numbers));
  636. ASSERT_EQ(2, numbers.size());
  637. sort(numbers.begin(), numbers.end());
  638. EXPECT_EQ(12, numbers[0]);
  639. EXPECT_EQ(13, numbers[1]);
  640. }
  641. {
  642. // Can't find extensions for a non-existent message.
  643. vector<int> numbers;
  644. EXPECT_FALSE(reverse_merged_.FindAllExtensionNumbers("Blah", &numbers));
  645. }
  646. }
  647. } // anonymous namespace
  648. } // namespace protobuf
  649. } // namespace google