protobuf/src/google/protobuf/descriptor_unittest.cc
Go to the documentation of this file.
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // Author: kenton@google.com (Kenton Varda)
32 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others.
34 //
35 // This file makes extensive use of RFC 3092. :)
36 
37 #include <limits>
38 #include <memory>
39 #include <vector>
40 
41 #include <google/protobuf/any.pb.h>
42 #include <google/protobuf/compiler/importer.h>
43 #include <google/protobuf/compiler/parser.h>
44 #include <google/protobuf/unittest.pb.h>
45 #include <google/protobuf/unittest_custom_options.pb.h>
46 #include <google/protobuf/stubs/common.h>
47 #include <google/protobuf/stubs/logging.h>
48 #include <google/protobuf/stubs/stringprintf.h>
49 #include <google/protobuf/unittest_lazy_dependencies.pb.h>
50 #include <google/protobuf/unittest_proto3_arena.pb.h>
51 #include <google/protobuf/io/tokenizer.h>
52 #include <google/protobuf/io/zero_copy_stream_impl.h>
53 #include <google/protobuf/descriptor.pb.h>
54 #include <google/protobuf/descriptor.h>
55 #include <google/protobuf/descriptor_database.h>
56 #include <google/protobuf/dynamic_message.h>
57 #include <google/protobuf/text_format.h>
58 #include <google/protobuf/stubs/strutil.h>
59 #include <gmock/gmock.h>
60 #include <google/protobuf/testing/googletest.h>
61 #include <gtest/gtest.h>
62 #include <google/protobuf/stubs/logging.h>
63 #include <google/protobuf/stubs/substitute.h>
64 
65 
66 #include <google/protobuf/port_def.inc>
67 
68 namespace google {
69 namespace protobuf {
70 
71 // Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
72 namespace descriptor_unittest {
73 
74 // Some helpers to make assembling descriptors faster.
76  const std::string& name) {
77  DescriptorProto* result = file->add_message_type();
78  result->set_name(name);
79  return result;
80 }
81 
83  const std::string& name) {
85  result->set_name(name);
86  return result;
87 }
88 
90  const std::string& name) {
91  EnumDescriptorProto* result = file->add_enum_type();
92  result->set_name(name);
93  return result;
94 }
95 
97  const std::string& name) {
99  result->set_name(name);
100  return result;
101 }
102 
104  const std::string& name) {
105  ServiceDescriptorProto* result = file->add_service();
106  result->set_name(name);
107  return result;
108 }
109 
114  result->set_name(name);
115  result->set_number(number);
116  result->set_label(label);
117  result->set_type(type);
118  return result;
119 }
120 
122  const std::string& extendee,
123  const std::string& name, int number,
126  FieldDescriptorProto* result = file->add_extension();
127  result->set_name(name);
128  result->set_number(number);
129  result->set_label(label);
130  result->set_type(type);
131  result->set_extendee(extendee);
132  return result;
133 }
134 
136  const std::string& extendee,
137  const std::string& name, int number,
141  result->set_name(name);
142  result->set_number(number);
143  result->set_label(label);
144  result->set_type(type);
145  result->set_extendee(extendee);
146  return result;
147 }
148 
150  int start, int end) {
152  result->set_start(start);
153  result->set_end(end);
154  return result;
155 }
156 
158  int start, int end) {
160  result->set_start(start);
161  result->set_end(end);
162  return result;
163 }
164 
166  EnumDescriptorProto* parent, int start, int end) {
168  result->set_start(start);
169  result->set_end(end);
170  return result;
171 }
172 
174  const std::string& name, int number) {
175  EnumValueDescriptorProto* result = enum_proto->add_value();
176  result->set_name(name);
177  result->set_number(number);
178  return result;
179 }
180 
182  const std::string& name,
183  const std::string& input_type,
184  const std::string& output_type) {
185  MethodDescriptorProto* result = service->add_method();
186  result->set_name(name);
187  result->set_input_type(input_type);
188  result->set_output_type(output_type);
189  return result;
190 }
191 
192 // Empty enums technically aren't allowed. We need to insert a dummy value
193 // into them.
195  AddEnumValue(AddEnum(file, name), name + "_DUMMY", 1);
196 }
197 
198 class MockErrorCollector : public DescriptorPool::ErrorCollector {
199  public:
202 
205 
206  // implements ErrorCollector ---------------------------------------
208  const Message* descriptor, ErrorLocation location,
209  const std::string& message) override {
210  const char* location_name = nullptr;
211  switch (location) {
212  case NAME:
213  location_name = "NAME";
214  break;
215  case NUMBER:
216  location_name = "NUMBER";
217  break;
218  case TYPE:
219  location_name = "TYPE";
220  break;
221  case EXTENDEE:
222  location_name = "EXTENDEE";
223  break;
224  case DEFAULT_VALUE:
225  location_name = "DEFAULT_VALUE";
226  break;
227  case OPTION_NAME:
228  location_name = "OPTION_NAME";
229  break;
230  case OPTION_VALUE:
231  location_name = "OPTION_VALUE";
232  break;
233  case INPUT_TYPE:
234  location_name = "INPUT_TYPE";
235  break;
236  case OUTPUT_TYPE:
237  location_name = "OUTPUT_TYPE";
238  break;
239  case IMPORT:
240  location_name = "IMPORT";
241  break;
242  case OTHER:
243  location_name = "OTHER";
244  break;
245  }
246 
247  strings::SubstituteAndAppend(&text_, "$0: $1: $2: $3\n", filename,
248  element_name, location_name, message);
249  }
250 
251  // implements ErrorCollector ---------------------------------------
253  const Message* descriptor, ErrorLocation location,
254  const std::string& message) override {
255  const char* location_name = nullptr;
256  switch (location) {
257  case NAME:
258  location_name = "NAME";
259  break;
260  case NUMBER:
261  location_name = "NUMBER";
262  break;
263  case TYPE:
264  location_name = "TYPE";
265  break;
266  case EXTENDEE:
267  location_name = "EXTENDEE";
268  break;
269  case DEFAULT_VALUE:
270  location_name = "DEFAULT_VALUE";
271  break;
272  case OPTION_NAME:
273  location_name = "OPTION_NAME";
274  break;
275  case OPTION_VALUE:
276  location_name = "OPTION_VALUE";
277  break;
278  case INPUT_TYPE:
279  location_name = "INPUT_TYPE";
280  break;
281  case OUTPUT_TYPE:
282  location_name = "OUTPUT_TYPE";
283  break;
284  case IMPORT:
285  location_name = "IMPORT";
286  break;
287  case OTHER:
288  location_name = "OTHER";
289  break;
290  }
291 
293  element_name, location_name, message);
294  }
295 };
296 
297 // ===================================================================
298 
299 // Test simple files.
300 class FileDescriptorTest : public testing::Test {
301  protected:
302  void SetUp() override {
303  // Build descriptors for the following definitions:
304  //
305  // // in "foo.proto"
306  // message FooMessage { extensions 1; }
307  // enum FooEnum {FOO_ENUM_VALUE = 1;}
308  // service FooService {}
309  // extend FooMessage { optional int32 foo_extension = 1; }
310  //
311  // // in "bar.proto"
312  // package bar_package;
313  // message BarMessage { extensions 1; }
314  // enum BarEnum {BAR_ENUM_VALUE = 1;}
315  // service BarService {}
316  // extend BarMessage { optional int32 bar_extension = 1; }
317  //
318  // Also, we have an empty file "baz.proto". This file's purpose is to
319  // make sure that even though it has the same package as foo.proto,
320  // searching it for members of foo.proto won't work.
321 
322  FileDescriptorProto foo_file;
323  foo_file.set_name("foo.proto");
324  AddExtensionRange(AddMessage(&foo_file, "FooMessage"), 1, 2);
325  AddEnumValue(AddEnum(&foo_file, "FooEnum"), "FOO_ENUM_VALUE", 1);
326  AddService(&foo_file, "FooService");
327  AddExtension(&foo_file, "FooMessage", "foo_extension", 1,
330 
331  FileDescriptorProto bar_file;
332  bar_file.set_name("bar.proto");
333  bar_file.set_package("bar_package");
334  bar_file.add_dependency("foo.proto");
335  AddExtensionRange(AddMessage(&bar_file, "BarMessage"), 1, 2);
336  AddEnumValue(AddEnum(&bar_file, "BarEnum"), "BAR_ENUM_VALUE", 1);
337  AddService(&bar_file, "BarService");
338  AddExtension(&bar_file, "bar_package.BarMessage", "bar_extension", 1,
341 
342  FileDescriptorProto baz_file;
343  baz_file.set_name("baz.proto");
344 
345  // Build the descriptors and get the pointers.
346  foo_file_ = pool_.BuildFile(foo_file);
347  ASSERT_TRUE(foo_file_ != nullptr);
348 
349  bar_file_ = pool_.BuildFile(bar_file);
350  ASSERT_TRUE(bar_file_ != nullptr);
351 
352  baz_file_ = pool_.BuildFile(baz_file);
353  ASSERT_TRUE(baz_file_ != nullptr);
354 
365 
376  }
377 
379 
380  const FileDescriptor* foo_file_;
381  const FileDescriptor* bar_file_;
382  const FileDescriptor* baz_file_;
383 
384  const Descriptor* foo_message_;
385  const EnumDescriptor* foo_enum_;
389 
390  const Descriptor* bar_message_;
391  const EnumDescriptor* bar_enum_;
395 };
396 
397 TEST_F(FileDescriptorTest, Name) {
398  EXPECT_EQ("foo.proto", foo_file_->name());
399  EXPECT_EQ("bar.proto", bar_file_->name());
400  EXPECT_EQ("baz.proto", baz_file_->name());
401 }
402 
403 TEST_F(FileDescriptorTest, Package) {
404  EXPECT_EQ("", foo_file_->package());
405  EXPECT_EQ("bar_package", bar_file_->package());
406 }
407 
408 TEST_F(FileDescriptorTest, Dependencies) {
409  EXPECT_EQ(0, foo_file_->dependency_count());
410  EXPECT_EQ(1, bar_file_->dependency_count());
411  EXPECT_EQ(foo_file_, bar_file_->dependency(0));
412 }
413 
414 TEST_F(FileDescriptorTest, FindMessageTypeByName) {
415  EXPECT_EQ(foo_message_, foo_file_->FindMessageTypeByName("FooMessage"));
416  EXPECT_EQ(bar_message_, bar_file_->FindMessageTypeByName("BarMessage"));
417 
418  EXPECT_TRUE(foo_file_->FindMessageTypeByName("BarMessage") == nullptr);
419  EXPECT_TRUE(bar_file_->FindMessageTypeByName("FooMessage") == nullptr);
420  EXPECT_TRUE(baz_file_->FindMessageTypeByName("FooMessage") == nullptr);
421 
422  EXPECT_TRUE(foo_file_->FindMessageTypeByName("NoSuchMessage") == nullptr);
423  EXPECT_TRUE(foo_file_->FindMessageTypeByName("FooEnum") == nullptr);
424 }
425 
426 TEST_F(FileDescriptorTest, FindEnumTypeByName) {
427  EXPECT_EQ(foo_enum_, foo_file_->FindEnumTypeByName("FooEnum"));
428  EXPECT_EQ(bar_enum_, bar_file_->FindEnumTypeByName("BarEnum"));
429 
430  EXPECT_TRUE(foo_file_->FindEnumTypeByName("BarEnum") == nullptr);
431  EXPECT_TRUE(bar_file_->FindEnumTypeByName("FooEnum") == nullptr);
432  EXPECT_TRUE(baz_file_->FindEnumTypeByName("FooEnum") == nullptr);
433 
434  EXPECT_TRUE(foo_file_->FindEnumTypeByName("NoSuchEnum") == nullptr);
435  EXPECT_TRUE(foo_file_->FindEnumTypeByName("FooMessage") == nullptr);
436 }
437 
438 TEST_F(FileDescriptorTest, FindEnumValueByName) {
439  EXPECT_EQ(foo_enum_value_, foo_file_->FindEnumValueByName("FOO_ENUM_VALUE"));
440  EXPECT_EQ(bar_enum_value_, bar_file_->FindEnumValueByName("BAR_ENUM_VALUE"));
441 
442  EXPECT_TRUE(foo_file_->FindEnumValueByName("BAR_ENUM_VALUE") == nullptr);
443  EXPECT_TRUE(bar_file_->FindEnumValueByName("FOO_ENUM_VALUE") == nullptr);
444  EXPECT_TRUE(baz_file_->FindEnumValueByName("FOO_ENUM_VALUE") == nullptr);
445 
446  EXPECT_TRUE(foo_file_->FindEnumValueByName("NO_SUCH_VALUE") == nullptr);
447  EXPECT_TRUE(foo_file_->FindEnumValueByName("FooMessage") == nullptr);
448 }
449 
450 TEST_F(FileDescriptorTest, FindServiceByName) {
451  EXPECT_EQ(foo_service_, foo_file_->FindServiceByName("FooService"));
452  EXPECT_EQ(bar_service_, bar_file_->FindServiceByName("BarService"));
453 
454  EXPECT_TRUE(foo_file_->FindServiceByName("BarService") == nullptr);
455  EXPECT_TRUE(bar_file_->FindServiceByName("FooService") == nullptr);
456  EXPECT_TRUE(baz_file_->FindServiceByName("FooService") == nullptr);
457 
458  EXPECT_TRUE(foo_file_->FindServiceByName("NoSuchService") == nullptr);
459  EXPECT_TRUE(foo_file_->FindServiceByName("FooMessage") == nullptr);
460 }
461 
462 TEST_F(FileDescriptorTest, FindExtensionByName) {
463  EXPECT_EQ(foo_extension_, foo_file_->FindExtensionByName("foo_extension"));
464  EXPECT_EQ(bar_extension_, bar_file_->FindExtensionByName("bar_extension"));
465 
466  EXPECT_TRUE(foo_file_->FindExtensionByName("bar_extension") == nullptr);
467  EXPECT_TRUE(bar_file_->FindExtensionByName("foo_extension") == nullptr);
468  EXPECT_TRUE(baz_file_->FindExtensionByName("foo_extension") == nullptr);
469 
470  EXPECT_TRUE(foo_file_->FindExtensionByName("no_such_extension") == nullptr);
471  EXPECT_TRUE(foo_file_->FindExtensionByName("FooMessage") == nullptr);
472 }
473 
474 TEST_F(FileDescriptorTest, FindExtensionByNumber) {
475  EXPECT_EQ(foo_extension_, pool_.FindExtensionByNumber(foo_message_, 1));
476  EXPECT_EQ(bar_extension_, pool_.FindExtensionByNumber(bar_message_, 1));
477 
478  EXPECT_TRUE(pool_.FindExtensionByNumber(foo_message_, 2) == nullptr);
479 }
480 
481 
482 TEST_F(FileDescriptorTest, BuildAgain) {
483  // Test that if we call BuildFile again on the same input we get the same
484  // FileDescriptor back.
486  foo_file_->CopyTo(&file);
487  EXPECT_EQ(foo_file_, pool_.BuildFile(file));
488 
489  // But if we change the file then it won't work.
490  file.set_package("some.other.package");
491  EXPECT_TRUE(pool_.BuildFile(file) == nullptr);
492 }
493 
494 TEST_F(FileDescriptorTest, BuildAgainWithSyntax) {
495  // Test that if we call BuildFile again on the same input we get the same
496  // FileDescriptor back even if syntax param is specified.
497  FileDescriptorProto proto_syntax2;
498  proto_syntax2.set_name("foo_syntax2");
499  proto_syntax2.set_syntax("proto2");
500 
501  const FileDescriptor* proto2_descriptor = pool_.BuildFile(proto_syntax2);
502  EXPECT_TRUE(proto2_descriptor != nullptr);
503  EXPECT_EQ(proto2_descriptor, pool_.BuildFile(proto_syntax2));
504 
505  FileDescriptorProto implicit_proto2;
506  implicit_proto2.set_name("foo_implicit_syntax2");
507 
508  const FileDescriptor* implicit_proto2_descriptor =
509  pool_.BuildFile(implicit_proto2);
510  EXPECT_TRUE(implicit_proto2_descriptor != nullptr);
511  // We get the same FileDescriptor back if syntax param is explicitly
512  // specified.
513  implicit_proto2.set_syntax("proto2");
514  EXPECT_EQ(implicit_proto2_descriptor, pool_.BuildFile(implicit_proto2));
515 
516  FileDescriptorProto proto_syntax3;
517  proto_syntax3.set_name("foo_syntax3");
518  proto_syntax3.set_syntax("proto3");
519 
520  const FileDescriptor* proto3_descriptor = pool_.BuildFile(proto_syntax3);
521  EXPECT_TRUE(proto3_descriptor != nullptr);
522  EXPECT_EQ(proto3_descriptor, pool_.BuildFile(proto_syntax3));
523 }
524 
525 TEST_F(FileDescriptorTest, Syntax) {
526  FileDescriptorProto proto;
527  proto.set_name("foo");
528  // Enable the test when we also populate the syntax for proto2.
529 #if 0
530  {
531  proto.set_syntax("proto2");
533  const FileDescriptor* file = pool.BuildFile(proto);
534  EXPECT_TRUE(file != nullptr);
536  FileDescriptorProto other;
537  file->CopyTo(&other);
538  EXPECT_EQ("proto2", other.syntax());
539  }
540 #endif
541  {
542  proto.set_syntax("proto3");
544  const FileDescriptor* file = pool.BuildFile(proto);
545  EXPECT_TRUE(file != nullptr);
547  FileDescriptorProto other;
548  file->CopyTo(&other);
549  EXPECT_EQ("proto3", other.syntax());
550  }
551 }
552 
553 void ExtractDebugString(
554  const FileDescriptor* file, std::set<std::string>* visited,
555  std::vector<std::pair<std::string, std::string>>* debug_strings) {
556  if (!visited->insert(file->name()).second) {
557  return;
558  }
559  for (int i = 0; i < file->dependency_count(); ++i) {
560  ExtractDebugString(file->dependency(i), visited, debug_strings);
561  }
562  debug_strings->push_back(std::make_pair(file->name(), file->DebugString()));
563 }
564 
565 class SimpleErrorCollector : public io::ErrorCollector {
566  public:
567  // implements ErrorCollector ---------------------------------------
568  void AddError(int line, int column, const std::string& message) override {
569  last_error_ = StringPrintf("%d:%d:", line, column) + message;
570  }
571 
572  const std::string& last_error() { return last_error_; }
573 
574  private:
576 };
577 // Test that the result of FileDescriptor::DebugString() can be used to create
578 // the original descriptors.
579 TEST_F(FileDescriptorTest, DebugStringRoundTrip) {
580  std::set<std::string> visited;
581  std::vector<std::pair<std::string, std::string>> debug_strings;
583  &visited, &debug_strings);
586  &visited, &debug_strings);
588  &visited, &debug_strings);
589  ASSERT_GE(debug_strings.size(), 3);
590 
592  for (int i = 0; i < debug_strings.size(); ++i) {
593  const std::string& name = debug_strings[i].first;
594  const std::string& content = debug_strings[i].second;
595  io::ArrayInputStream input_stream(content.data(), content.size());
596  SimpleErrorCollector error_collector;
597  io::Tokenizer tokenizer(&input_stream, &error_collector);
599  parser.RecordErrorsTo(&error_collector);
600  FileDescriptorProto proto;
601  ASSERT_TRUE(parser.Parse(&tokenizer, &proto))
602  << error_collector.last_error() << "\n"
603  << content;
604  ASSERT_EQ("", error_collector.last_error());
605  proto.set_name(name);
606  const FileDescriptor* descriptor = pool.BuildFile(proto);
607  ASSERT_TRUE(descriptor != nullptr) << proto.DebugString();
608  EXPECT_EQ(content, descriptor->DebugString());
609  }
610 }
611 
612 // ===================================================================
613 
614 // Test simple flat messages and fields.
615 class DescriptorTest : public testing::Test {
616  protected:
617  void SetUp() override {
618  // Build descriptors for the following definitions:
619  //
620  // // in "foo.proto"
621  // message TestForeign {}
622  // enum TestEnum {}
623  //
624  // message TestMessage {
625  // required string foo = 1;
626  // optional TestEnum bar = 6;
627  // repeated TestForeign baz = 500000000;
628  // optional group qux = 15 {}
629  // }
630  //
631  // // in "bar.proto"
632  // package corge.grault;
633  // message TestMessage2 {
634  // required string foo = 1;
635  // required string bar = 2;
636  // required string quux = 6;
637  // }
638  //
639  // // in "map.proto"
640  // message TestMessage3 {
641  // map<int32, int32> map_int32_int32 = 1;
642  // }
643  //
644  // // in "json.proto"
645  // message TestMessage4 {
646  // optional int32 field_name1 = 1;
647  // optional int32 fieldName2 = 2;
648  // optional int32 FieldName3 = 3;
649  // optional int32 _field_name4 = 4;
650  // optional int32 FIELD_NAME5 = 5;
651  // optional int32 field_name6 = 6 [json_name = "@type"];
652  // }
653  //
654  // We cheat and use TestForeign as the type for qux rather than create
655  // an actual nested type.
656  //
657  // Since all primitive types (including string) use the same building
658  // code, there's no need to test each one individually.
659  //
660  // TestMessage2 is primarily here to test FindFieldByName and friends.
661  // All messages created from the same DescriptorPool share the same lookup
662  // table, so we need to insure that they don't interfere.
663 
664  FileDescriptorProto foo_file;
665  foo_file.set_name("foo.proto");
666  AddMessage(&foo_file, "TestForeign");
667  AddEmptyEnum(&foo_file, "TestEnum");
668 
669  DescriptorProto* message = AddMessage(&foo_file, "TestMessage");
674  ->set_type_name("TestEnum");
677  ->set_type_name("TestForeign");
680  ->set_type_name("TestForeign");
681 
682  FileDescriptorProto bar_file;
683  bar_file.set_name("bar.proto");
684  bar_file.set_package("corge.grault");
685 
686  DescriptorProto* message2 = AddMessage(&bar_file, "TestMessage2");
691  AddField(message2, "quux", 6, FieldDescriptorProto::LABEL_REQUIRED,
693 
694  FileDescriptorProto map_file;
695  map_file.set_name("map.proto");
696  DescriptorProto* message3 = AddMessage(&map_file, "TestMessage3");
697 
698  DescriptorProto* entry = AddNestedMessage(message3, "MapInt32Int32Entry");
703  entry->mutable_options()->set_map_entry(true);
704 
705  AddField(message3, "map_int32_int32", 1,
708  ->set_type_name("MapInt32Int32Entry");
709 
710  FileDescriptorProto json_file;
711  json_file.set_name("json.proto");
712  json_file.set_syntax("proto3");
713  DescriptorProto* message4 = AddMessage(&json_file, "TestMessage4");
714  AddField(message4, "field_name1", 1, FieldDescriptorProto::LABEL_OPTIONAL,
716  AddField(message4, "fieldName2", 2, FieldDescriptorProto::LABEL_OPTIONAL,
718  AddField(message4, "FieldName3", 3, FieldDescriptorProto::LABEL_OPTIONAL,
720  AddField(message4, "_field_name4", 4, FieldDescriptorProto::LABEL_OPTIONAL,
722  AddField(message4, "FIELD_NAME5", 5, FieldDescriptorProto::LABEL_OPTIONAL,
724  AddField(message4, "field_name6", 6, FieldDescriptorProto::LABEL_OPTIONAL,
726  ->set_json_name("@type");
727  AddField(message4, "fieldname7", 7, FieldDescriptorProto::LABEL_OPTIONAL,
729 
730  // Build the descriptors and get the pointers.
731  foo_file_ = pool_.BuildFile(foo_file);
732  ASSERT_TRUE(foo_file_ != nullptr);
733 
734  bar_file_ = pool_.BuildFile(bar_file);
735  ASSERT_TRUE(bar_file_ != nullptr);
736 
737  map_file_ = pool_.BuildFile(map_file);
738  ASSERT_TRUE(map_file_ != nullptr);
739 
740  json_file_ = pool_.BuildFile(json_file);
741  ASSERT_TRUE(json_file_ != nullptr);
742 
744  enum_ = foo_file_->enum_type(0);
745 
749 
751  foo_ = message_->field(0);
752  bar_ = message_->field(1);
753  baz_ = message_->field(2);
754  qux_ = message_->field(3);
755 
758 
760  foo2_ = message2_->field(0);
761  bar2_ = message2_->field(1);
762  quux2_ = message2_->field(2);
763 
766 
768  map_ = message3_->field(0);
769 
772  }
773 
775  message->CopyTo(proto);
776  message->CopyJsonNameTo(proto);
777  }
778 
780  const EnumDescriptor* desc, int number) {
781  return desc->FindValueByNumberCreatingIfUnknown(number);
782  }
783 
785 
786  const FileDescriptor* foo_file_;
787  const FileDescriptor* bar_file_;
788  const FileDescriptor* map_file_;
789  const FileDescriptor* json_file_;
790 
791  const Descriptor* message_;
792  const Descriptor* message2_;
793  const Descriptor* message3_;
794  const Descriptor* message4_;
795  const Descriptor* foreign_;
796  const EnumDescriptor* enum_;
797 
798  const FieldDescriptor* foo_;
799  const FieldDescriptor* bar_;
800  const FieldDescriptor* baz_;
801  const FieldDescriptor* qux_;
802 
803  const FieldDescriptor* foo2_;
804  const FieldDescriptor* bar2_;
805  const FieldDescriptor* quux2_;
806 
807  const FieldDescriptor* map_;
808 };
809 
810 TEST_F(DescriptorTest, Name) {
811  EXPECT_EQ("TestMessage", message_->name());
812  EXPECT_EQ("TestMessage", message_->full_name());
813  EXPECT_EQ(foo_file_, message_->file());
814 
815  EXPECT_EQ("TestMessage2", message2_->name());
816  EXPECT_EQ("corge.grault.TestMessage2", message2_->full_name());
817  EXPECT_EQ(bar_file_, message2_->file());
818 }
819 
820 TEST_F(DescriptorTest, ContainingType) {
821  EXPECT_TRUE(message_->containing_type() == nullptr);
822  EXPECT_TRUE(message2_->containing_type() == nullptr);
823 }
824 
825 TEST_F(DescriptorTest, FieldNamesDedup) {
826  const auto collect_unique_names = [](const FieldDescriptor* field) {
827  std::set<std::string> names{field->name(), field->lowercase_name(),
828  field->camelcase_name(), field->json_name()};
829  // Verify that we have the same number of string objects as we have string
830  // values. That is, duplicate names use the same std::string object.
831  // This is for memory efficiency.
832  EXPECT_EQ(names.size(), (std::set<const std::string*>{
833  &field->name(), &field->lowercase_name(),
834  &field->camelcase_name(), &field->json_name()}
835  .size()))
837  return names;
838  };
839 
840  using testing::ElementsAre;
841  // field_name1
842  EXPECT_THAT(collect_unique_names(message4_->field(0)),
843  ElementsAre("fieldName1", "field_name1"));
844  // fieldName2
845  EXPECT_THAT(collect_unique_names(message4_->field(1)),
846  ElementsAre("fieldName2", "fieldname2"));
847  // FieldName3
848  EXPECT_THAT(collect_unique_names(message4_->field(2)),
849  ElementsAre("FieldName3", "fieldName3", "fieldname3"));
850  // _field_name4
851  EXPECT_THAT(collect_unique_names(message4_->field(3)),
852  ElementsAre("FieldName4", "_field_name4", "fieldName4"));
853  // FIELD_NAME5
854  EXPECT_THAT(
855  collect_unique_names(message4_->field(4)),
856  ElementsAre("FIELDNAME5", "FIELD_NAME5", "fIELDNAME5", "field_name5"));
857  // field_name6, with json name @type
858  EXPECT_THAT(collect_unique_names(message4_->field(5)),
859  ElementsAre("@type", "fieldName6", "field_name6"));
860  // fieldname7
861  EXPECT_THAT(collect_unique_names(message4_->field(6)),
862  ElementsAre("fieldname7"));
863 }
864 
865 TEST_F(DescriptorTest, FieldsByIndex) {
866  ASSERT_EQ(4, message_->field_count());
867  EXPECT_EQ(foo_, message_->field(0));
868  EXPECT_EQ(bar_, message_->field(1));
869  EXPECT_EQ(baz_, message_->field(2));
870  EXPECT_EQ(qux_, message_->field(3));
871 }
872 
873 TEST_F(DescriptorTest, FindFieldByName) {
874  // All messages in the same DescriptorPool share a single lookup table for
875  // fields. So, in addition to testing that FindFieldByName finds the fields
876  // of the message, we need to test that it does *not* find the fields of
877  // *other* messages.
878 
879  EXPECT_EQ(foo_, message_->FindFieldByName("foo"));
880  EXPECT_EQ(bar_, message_->FindFieldByName("bar"));
881  EXPECT_EQ(baz_, message_->FindFieldByName("baz"));
882  EXPECT_EQ(qux_, message_->FindFieldByName("qux"));
883  EXPECT_TRUE(message_->FindFieldByName("no_such_field") == nullptr);
884  EXPECT_TRUE(message_->FindFieldByName("quux") == nullptr);
885 
886  EXPECT_EQ(foo2_, message2_->FindFieldByName("foo"));
887  EXPECT_EQ(bar2_, message2_->FindFieldByName("bar"));
888  EXPECT_EQ(quux2_, message2_->FindFieldByName("quux"));
889  EXPECT_TRUE(message2_->FindFieldByName("baz") == nullptr);
890  EXPECT_TRUE(message2_->FindFieldByName("qux") == nullptr);
891 }
892 
893 TEST_F(DescriptorTest, FindFieldByNumber) {
894  EXPECT_EQ(foo_, message_->FindFieldByNumber(1));
895  EXPECT_EQ(bar_, message_->FindFieldByNumber(6));
896  EXPECT_EQ(baz_, message_->FindFieldByNumber(500000000));
897  EXPECT_EQ(qux_, message_->FindFieldByNumber(15));
898  EXPECT_TRUE(message_->FindFieldByNumber(837592) == nullptr);
899  EXPECT_TRUE(message_->FindFieldByNumber(2) == nullptr);
900 
901  EXPECT_EQ(foo2_, message2_->FindFieldByNumber(1));
902  EXPECT_EQ(bar2_, message2_->FindFieldByNumber(2));
903  EXPECT_EQ(quux2_, message2_->FindFieldByNumber(6));
904  EXPECT_TRUE(message2_->FindFieldByNumber(15) == nullptr);
905  EXPECT_TRUE(message2_->FindFieldByNumber(500000000) == nullptr);
906 }
907 
908 TEST_F(DescriptorTest, FieldName) {
909  EXPECT_EQ("foo", foo_->name());
910  EXPECT_EQ("bar", bar_->name());
911  EXPECT_EQ("baz", baz_->name());
912  EXPECT_EQ("qux", qux_->name());
913 }
914 
915 TEST_F(DescriptorTest, FieldFullName) {
916  EXPECT_EQ("TestMessage.foo", foo_->full_name());
917  EXPECT_EQ("TestMessage.bar", bar_->full_name());
918  EXPECT_EQ("TestMessage.baz", baz_->full_name());
919  EXPECT_EQ("TestMessage.qux", qux_->full_name());
920 
921  EXPECT_EQ("corge.grault.TestMessage2.foo", foo2_->full_name());
922  EXPECT_EQ("corge.grault.TestMessage2.bar", bar2_->full_name());
923  EXPECT_EQ("corge.grault.TestMessage2.quux", quux2_->full_name());
924 }
925 
926 TEST_F(DescriptorTest, PrintableNameIsFullNameForNonExtensionFields) {
927  EXPECT_EQ("TestMessage.foo", foo_->PrintableNameForExtension());
928  EXPECT_EQ("TestMessage.bar", bar_->PrintableNameForExtension());
929  EXPECT_EQ("TestMessage.baz", baz_->PrintableNameForExtension());
930  EXPECT_EQ("TestMessage.qux", qux_->PrintableNameForExtension());
931 
932  EXPECT_EQ("corge.grault.TestMessage2.foo",
933  foo2_->PrintableNameForExtension());
934  EXPECT_EQ("corge.grault.TestMessage2.bar",
935  bar2_->PrintableNameForExtension());
936  EXPECT_EQ("corge.grault.TestMessage2.quux",
937  quux2_->PrintableNameForExtension());
938 }
939 
940 TEST_F(DescriptorTest, PrintableNameIsFullNameForNonMessageSetExtension) {
941  EXPECT_EQ("protobuf_unittest.Aggregate.nested",
943  ->FindExtensionByName("nested")
944  ->PrintableNameForExtension());
945 }
946 
947 TEST_F(DescriptorTest, PrintableNameIsExtendingTypeForMessageSetExtension) {
948  EXPECT_EQ("protobuf_unittest.AggregateMessageSetElement",
950  ->FindExtensionByName("message_set_extension")
951  ->PrintableNameForExtension());
952 }
953 
954 TEST_F(DescriptorTest, FieldJsonName) {
955  EXPECT_EQ("fieldName1", message4_->field(0)->json_name());
956  EXPECT_EQ("fieldName2", message4_->field(1)->json_name());
957  EXPECT_EQ("FieldName3", message4_->field(2)->json_name());
958  EXPECT_EQ("FieldName4", message4_->field(3)->json_name());
959  EXPECT_EQ("FIELDNAME5", message4_->field(4)->json_name());
960  EXPECT_EQ("@type", message4_->field(5)->json_name());
961 
962  DescriptorProto proto;
963  message4_->CopyTo(&proto);
964  ASSERT_EQ(7, proto.field_size());
965  EXPECT_FALSE(proto.field(0).has_json_name());
966  EXPECT_FALSE(proto.field(1).has_json_name());
967  EXPECT_FALSE(proto.field(2).has_json_name());
968  EXPECT_FALSE(proto.field(3).has_json_name());
969  EXPECT_FALSE(proto.field(4).has_json_name());
970  EXPECT_EQ("@type", proto.field(5).json_name());
971  EXPECT_FALSE(proto.field(6).has_json_name());
972 
973  proto.Clear();
974  CopyWithJsonName(message4_, &proto);
975  ASSERT_EQ(7, proto.field_size());
976  EXPECT_EQ("fieldName1", proto.field(0).json_name());
977  EXPECT_EQ("fieldName2", proto.field(1).json_name());
978  EXPECT_EQ("FieldName3", proto.field(2).json_name());
979  EXPECT_EQ("FieldName4", proto.field(3).json_name());
980  EXPECT_EQ("FIELDNAME5", proto.field(4).json_name());
981  EXPECT_EQ("@type", proto.field(5).json_name());
982  EXPECT_EQ("fieldname7", proto.field(6).json_name());
983 
984  // Test generated descriptor.
986  ASSERT_EQ(7, generated->field_count());
987  EXPECT_EQ("fieldName1", generated->field(0)->json_name());
988  EXPECT_EQ("fieldName2", generated->field(1)->json_name());
989  EXPECT_EQ("FieldName3", generated->field(2)->json_name());
990  EXPECT_EQ("FieldName4", generated->field(3)->json_name());
991  EXPECT_EQ("FIELDNAME5", generated->field(4)->json_name());
992  EXPECT_EQ("@type", generated->field(5)->json_name());
993  EXPECT_EQ("fieldname7", generated->field(6)->json_name());
994 }
995 
996 TEST_F(DescriptorTest, FieldFile) {
997  EXPECT_EQ(foo_file_, foo_->file());
998  EXPECT_EQ(foo_file_, bar_->file());
999  EXPECT_EQ(foo_file_, baz_->file());
1000  EXPECT_EQ(foo_file_, qux_->file());
1001 
1002  EXPECT_EQ(bar_file_, foo2_->file());
1003  EXPECT_EQ(bar_file_, bar2_->file());
1004  EXPECT_EQ(bar_file_, quux2_->file());
1005 }
1006 
1007 TEST_F(DescriptorTest, FieldIndex) {
1008  EXPECT_EQ(0, foo_->index());
1009  EXPECT_EQ(1, bar_->index());
1010  EXPECT_EQ(2, baz_->index());
1011  EXPECT_EQ(3, qux_->index());
1012 }
1013 
1014 TEST_F(DescriptorTest, FieldNumber) {
1015  EXPECT_EQ(1, foo_->number());
1016  EXPECT_EQ(6, bar_->number());
1017  EXPECT_EQ(500000000, baz_->number());
1018  EXPECT_EQ(15, qux_->number());
1019 }
1020 
1021 TEST_F(DescriptorTest, FieldType) {
1022  EXPECT_EQ(FieldDescriptor::TYPE_STRING, foo_->type());
1023  EXPECT_EQ(FieldDescriptor::TYPE_ENUM, bar_->type());
1025  EXPECT_EQ(FieldDescriptor::TYPE_GROUP, qux_->type());
1026 }
1027 
1028 TEST_F(DescriptorTest, FieldLabel) {
1033 
1034  EXPECT_TRUE(foo_->is_required());
1035  EXPECT_FALSE(foo_->is_optional());
1036  EXPECT_FALSE(foo_->is_repeated());
1037 
1038  EXPECT_FALSE(bar_->is_required());
1039  EXPECT_TRUE(bar_->is_optional());
1040  EXPECT_FALSE(bar_->is_repeated());
1041 
1042  EXPECT_FALSE(baz_->is_required());
1043  EXPECT_FALSE(baz_->is_optional());
1044  EXPECT_TRUE(baz_->is_repeated());
1045 }
1046 
1047 TEST_F(DescriptorTest, IsMap) {
1048  EXPECT_TRUE(map_->is_map());
1049  EXPECT_FALSE(baz_->is_map());
1050  EXPECT_TRUE(map_->message_type()->options().map_entry());
1051 }
1052 
1054  const Descriptor* map_desc = map_->message_type();
1055  const FieldDescriptor* map_key = map_desc->map_key();
1056  ASSERT_TRUE(map_key != nullptr);
1057  EXPECT_EQ(map_key->name(), "key");
1058  EXPECT_EQ(map_key->number(), 1);
1059 
1060  const FieldDescriptor* map_value = map_desc->map_value();
1061  ASSERT_TRUE(map_value != nullptr);
1062  EXPECT_EQ(map_value->name(), "value");
1063  EXPECT_EQ(map_value->number(), 2);
1064 
1065  EXPECT_EQ(message_->map_key(), nullptr);
1066  EXPECT_EQ(message_->map_value(), nullptr);
1067 }
1068 
1069 TEST_F(DescriptorTest, FieldHasDefault) {
1070  EXPECT_FALSE(foo_->has_default_value());
1071  EXPECT_FALSE(bar_->has_default_value());
1072  EXPECT_FALSE(baz_->has_default_value());
1073  EXPECT_FALSE(qux_->has_default_value());
1074 }
1075 
1076 TEST_F(DescriptorTest, FieldContainingType) {
1077  EXPECT_EQ(message_, foo_->containing_type());
1078  EXPECT_EQ(message_, bar_->containing_type());
1079  EXPECT_EQ(message_, baz_->containing_type());
1080  EXPECT_EQ(message_, qux_->containing_type());
1081 
1082  EXPECT_EQ(message2_, foo2_->containing_type());
1083  EXPECT_EQ(message2_, bar2_->containing_type());
1084  EXPECT_EQ(message2_, quux2_->containing_type());
1085 }
1086 
1087 TEST_F(DescriptorTest, FieldMessageType) {
1088  EXPECT_TRUE(foo_->message_type() == nullptr);
1089  EXPECT_TRUE(bar_->message_type() == nullptr);
1090 
1091  EXPECT_EQ(foreign_, baz_->message_type());
1092  EXPECT_EQ(foreign_, qux_->message_type());
1093 }
1094 
1095 TEST_F(DescriptorTest, FieldEnumType) {
1096  EXPECT_TRUE(foo_->enum_type() == nullptr);
1097  EXPECT_TRUE(baz_->enum_type() == nullptr);
1098  EXPECT_TRUE(qux_->enum_type() == nullptr);
1099 
1100  EXPECT_EQ(enum_, bar_->enum_type());
1101 }
1102 
1103 
1104 // ===================================================================
1105 
1106 // Test simple flat messages and fields.
1107 class OneofDescriptorTest : public testing::Test {
1108  protected:
1109  void SetUp() override {
1110  // Build descriptors for the following definitions:
1111  //
1112  // package garply;
1113  // message TestOneof {
1114  // optional int32 a = 1;
1115  // oneof foo {
1116  // string b = 2;
1117  // TestOneof c = 3;
1118  // }
1119  // oneof bar {
1120  // float d = 4;
1121  // }
1122  // }
1123 
1124  FileDescriptorProto baz_file;
1125  baz_file.set_name("baz.proto");
1126  baz_file.set_package("garply");
1127 
1128  DescriptorProto* oneof_message = AddMessage(&baz_file, "TestOneof");
1129  oneof_message->add_oneof_decl()->set_name("foo");
1130  oneof_message->add_oneof_decl()->set_name("bar");
1131 
1132  AddField(oneof_message, "a", 1, FieldDescriptorProto::LABEL_OPTIONAL,
1134  AddField(oneof_message, "b", 2, FieldDescriptorProto::LABEL_OPTIONAL,
1136  oneof_message->mutable_field(1)->set_oneof_index(0);
1137  AddField(oneof_message, "c", 3, FieldDescriptorProto::LABEL_OPTIONAL,
1139  oneof_message->mutable_field(2)->set_oneof_index(0);
1140  oneof_message->mutable_field(2)->set_type_name("TestOneof");
1141 
1142  AddField(oneof_message, "d", 4, FieldDescriptorProto::LABEL_OPTIONAL,
1144  oneof_message->mutable_field(3)->set_oneof_index(1);
1145 
1146  // Build the descriptors and get the pointers.
1147  baz_file_ = pool_.BuildFile(baz_file);
1148  ASSERT_TRUE(baz_file_ != nullptr);
1149 
1152 
1156 
1158  a_ = oneof_message_->field(0);
1159  b_ = oneof_message_->field(1);
1160  c_ = oneof_message_->field(2);
1161  d_ = oneof_message_->field(3);
1162  }
1163 
1165 
1166  const FileDescriptor* baz_file_;
1167 
1168  const Descriptor* oneof_message_;
1169 
1170  const OneofDescriptor* oneof_;
1171  const OneofDescriptor* oneof2_;
1172  const FieldDescriptor* a_;
1173  const FieldDescriptor* b_;
1174  const FieldDescriptor* c_;
1175  const FieldDescriptor* d_;
1176 };
1177 
1178 TEST_F(OneofDescriptorTest, Normal) {
1179  EXPECT_EQ("foo", oneof_->name());
1180  EXPECT_EQ("garply.TestOneof.foo", oneof_->full_name());
1181  EXPECT_EQ(0, oneof_->index());
1182  ASSERT_EQ(2, oneof_->field_count());
1183  EXPECT_EQ(b_, oneof_->field(0));
1184  EXPECT_EQ(c_, oneof_->field(1));
1185  EXPECT_TRUE(a_->containing_oneof() == nullptr);
1186  EXPECT_EQ(oneof_, b_->containing_oneof());
1187  EXPECT_EQ(oneof_, c_->containing_oneof());
1188 }
1189 
1190 TEST_F(OneofDescriptorTest, FindByName) {
1191  EXPECT_EQ(oneof_, oneof_message_->FindOneofByName("foo"));
1192  EXPECT_EQ(oneof2_, oneof_message_->FindOneofByName("bar"));
1193  EXPECT_TRUE(oneof_message_->FindOneofByName("no_such_oneof") == nullptr);
1194 }
1195 
1196 // ===================================================================
1197 
1198 class StylizedFieldNamesTest : public testing::Test {
1199  protected:
1200  void SetUp() override {
1202  file.set_name("foo.proto");
1203 
1204  AddExtensionRange(AddMessage(&file, "ExtendableMessage"), 1, 1000);
1205 
1206  DescriptorProto* message = AddMessage(&file, "TestMessage");
1213  AddField(message, "fooFoo", 4, // Camel-case conflict with foo_foo.
1216  AddField(message, "foobar", 5, // Lower-case conflict with FooBar.
1219 
1220  AddNestedExtension(message, "ExtendableMessage", "bar_foo", 1,
1223  AddNestedExtension(message, "ExtendableMessage", "BarBar", 2,
1226  AddNestedExtension(message, "ExtendableMessage", "BarBaz", 3,
1229  AddNestedExtension(message, "ExtendableMessage", "barFoo", 4, // Conflict
1232  AddNestedExtension(message, "ExtendableMessage", "barbar", 5, // Conflict
1235 
1236  AddExtension(&file, "ExtendableMessage", "baz_foo", 11,
1239  AddExtension(&file, "ExtendableMessage", "BazBar", 12,
1242  AddExtension(&file, "ExtendableMessage", "BazBaz", 13,
1245  AddExtension(&file, "ExtendableMessage", "bazFoo", 14, // Conflict
1248  AddExtension(&file, "ExtendableMessage", "bazbar", 15, // Conflict
1251 
1253  ASSERT_TRUE(file_ != nullptr);
1255  message_ = file_->message_type(1);
1256  ASSERT_EQ("TestMessage", message_->name());
1260  }
1261 
1263  const FileDescriptor* file_;
1264  const Descriptor* message_;
1265 };
1266 
1267 TEST_F(StylizedFieldNamesTest, LowercaseName) {
1268  EXPECT_EQ("foo_foo", message_->field(0)->lowercase_name());
1269  EXPECT_EQ("foobar", message_->field(1)->lowercase_name());
1270  EXPECT_EQ("foobaz", message_->field(2)->lowercase_name());
1271  EXPECT_EQ("foofoo", message_->field(3)->lowercase_name());
1272  EXPECT_EQ("foobar", message_->field(4)->lowercase_name());
1273 
1274  EXPECT_EQ("bar_foo", message_->extension(0)->lowercase_name());
1275  EXPECT_EQ("barbar", message_->extension(1)->lowercase_name());
1276  EXPECT_EQ("barbaz", message_->extension(2)->lowercase_name());
1277  EXPECT_EQ("barfoo", message_->extension(3)->lowercase_name());
1278  EXPECT_EQ("barbar", message_->extension(4)->lowercase_name());
1279 
1280  EXPECT_EQ("baz_foo", file_->extension(0)->lowercase_name());
1281  EXPECT_EQ("bazbar", file_->extension(1)->lowercase_name());
1282  EXPECT_EQ("bazbaz", file_->extension(2)->lowercase_name());
1283  EXPECT_EQ("bazfoo", file_->extension(3)->lowercase_name());
1284  EXPECT_EQ("bazbar", file_->extension(4)->lowercase_name());
1285 }
1286 
1287 TEST_F(StylizedFieldNamesTest, CamelcaseName) {
1288  EXPECT_EQ("fooFoo", message_->field(0)->camelcase_name());
1289  EXPECT_EQ("fooBar", message_->field(1)->camelcase_name());
1290  EXPECT_EQ("fooBaz", message_->field(2)->camelcase_name());
1291  EXPECT_EQ("fooFoo", message_->field(3)->camelcase_name());
1292  EXPECT_EQ("foobar", message_->field(4)->camelcase_name());
1293 
1294  EXPECT_EQ("barFoo", message_->extension(0)->camelcase_name());
1295  EXPECT_EQ("barBar", message_->extension(1)->camelcase_name());
1296  EXPECT_EQ("barBaz", message_->extension(2)->camelcase_name());
1297  EXPECT_EQ("barFoo", message_->extension(3)->camelcase_name());
1298  EXPECT_EQ("barbar", message_->extension(4)->camelcase_name());
1299 
1300  EXPECT_EQ("bazFoo", file_->extension(0)->camelcase_name());
1301  EXPECT_EQ("bazBar", file_->extension(1)->camelcase_name());
1302  EXPECT_EQ("bazBaz", file_->extension(2)->camelcase_name());
1303  EXPECT_EQ("bazFoo", file_->extension(3)->camelcase_name());
1304  EXPECT_EQ("bazbar", file_->extension(4)->camelcase_name());
1305 }
1306 
1307 TEST_F(StylizedFieldNamesTest, FindByLowercaseName) {
1308  EXPECT_EQ(message_->field(0), message_->FindFieldByLowercaseName("foo_foo"));
1309  EXPECT_EQ(message_->field(1), message_->FindFieldByLowercaseName("foobar"));
1310  EXPECT_EQ(message_->field(2), message_->FindFieldByLowercaseName("foobaz"));
1311  EXPECT_TRUE(message_->FindFieldByLowercaseName("FooBar") == nullptr);
1312  EXPECT_TRUE(message_->FindFieldByLowercaseName("fooBaz") == nullptr);
1313  EXPECT_TRUE(message_->FindFieldByLowercaseName("bar_foo") == nullptr);
1314  EXPECT_TRUE(message_->FindFieldByLowercaseName("nosuchfield") == nullptr);
1315 
1316  EXPECT_EQ(message_->extension(0),
1317  message_->FindExtensionByLowercaseName("bar_foo"));
1318  EXPECT_EQ(message_->extension(1),
1319  message_->FindExtensionByLowercaseName("barbar"));
1320  EXPECT_EQ(message_->extension(2),
1321  message_->FindExtensionByLowercaseName("barbaz"));
1322  EXPECT_TRUE(message_->FindExtensionByLowercaseName("BarBar") == nullptr);
1323  EXPECT_TRUE(message_->FindExtensionByLowercaseName("barBaz") == nullptr);
1324  EXPECT_TRUE(message_->FindExtensionByLowercaseName("foo_foo") == nullptr);
1325  EXPECT_TRUE(message_->FindExtensionByLowercaseName("nosuchfield") == nullptr);
1326 
1328  file_->FindExtensionByLowercaseName("baz_foo"));
1329  EXPECT_EQ(file_->extension(1), file_->FindExtensionByLowercaseName("bazbar"));
1330  EXPECT_EQ(file_->extension(2), file_->FindExtensionByLowercaseName("bazbaz"));
1331  EXPECT_TRUE(file_->FindExtensionByLowercaseName("BazBar") == nullptr);
1332  EXPECT_TRUE(file_->FindExtensionByLowercaseName("bazBaz") == nullptr);
1333  EXPECT_TRUE(file_->FindExtensionByLowercaseName("nosuchfield") == nullptr);
1334 }
1335 
1336 TEST_F(StylizedFieldNamesTest, FindByCamelcaseName) {
1337  EXPECT_EQ(message_->field(0), message_->FindFieldByCamelcaseName("fooFoo"));
1338  EXPECT_EQ(message_->field(1), message_->FindFieldByCamelcaseName("fooBar"));
1339  EXPECT_EQ(message_->field(2), message_->FindFieldByCamelcaseName("fooBaz"));
1340  EXPECT_TRUE(message_->FindFieldByCamelcaseName("foo_foo") == nullptr);
1341  EXPECT_TRUE(message_->FindFieldByCamelcaseName("FooBar") == nullptr);
1342  EXPECT_TRUE(message_->FindFieldByCamelcaseName("barFoo") == nullptr);
1343  EXPECT_TRUE(message_->FindFieldByCamelcaseName("nosuchfield") == nullptr);
1344 
1345  EXPECT_EQ(message_->extension(0),
1346  message_->FindExtensionByCamelcaseName("barFoo"));
1347  EXPECT_EQ(message_->extension(1),
1348  message_->FindExtensionByCamelcaseName("barBar"));
1349  EXPECT_EQ(message_->extension(2),
1350  message_->FindExtensionByCamelcaseName("barBaz"));
1351  EXPECT_TRUE(message_->FindExtensionByCamelcaseName("bar_foo") == nullptr);
1352  EXPECT_TRUE(message_->FindExtensionByCamelcaseName("BarBar") == nullptr);
1353  EXPECT_TRUE(message_->FindExtensionByCamelcaseName("fooFoo") == nullptr);
1354  EXPECT_TRUE(message_->FindExtensionByCamelcaseName("nosuchfield") == nullptr);
1355 
1356  EXPECT_EQ(file_->extension(0), file_->FindExtensionByCamelcaseName("bazFoo"));
1357  EXPECT_EQ(file_->extension(1), file_->FindExtensionByCamelcaseName("bazBar"));
1358  EXPECT_EQ(file_->extension(2), file_->FindExtensionByCamelcaseName("bazBaz"));
1359  EXPECT_TRUE(file_->FindExtensionByCamelcaseName("baz_foo") == nullptr);
1360  EXPECT_TRUE(file_->FindExtensionByCamelcaseName("BazBar") == nullptr);
1361  EXPECT_TRUE(file_->FindExtensionByCamelcaseName("nosuchfield") == nullptr);
1362 }
1363 
1364 // ===================================================================
1365 
1366 // Test enum descriptors.
1367 class EnumDescriptorTest : public testing::Test {
1368  protected:
1369  void SetUp() override {
1370  // Build descriptors for the following definitions:
1371  //
1372  // // in "foo.proto"
1373  // enum TestEnum {
1374  // FOO = 1;
1375  // BAR = 2;
1376  // }
1377  //
1378  // // in "bar.proto"
1379  // package corge.grault;
1380  // enum TestEnum2 {
1381  // FOO = 1;
1382  // BAZ = 3;
1383  // }
1384  //
1385  // TestEnum2 is primarily here to test FindValueByName and friends.
1386  // All enums created from the same DescriptorPool share the same lookup
1387  // table, so we need to insure that they don't interfere.
1388 
1389  // TestEnum
1390  FileDescriptorProto foo_file;
1391  foo_file.set_name("foo.proto");
1392 
1393  EnumDescriptorProto* enum_proto = AddEnum(&foo_file, "TestEnum");
1394  AddEnumValue(enum_proto, "FOO", 1);
1395  AddEnumValue(enum_proto, "BAR", 2);
1396 
1397  // TestEnum2
1398  FileDescriptorProto bar_file;
1399  bar_file.set_name("bar.proto");
1400  bar_file.set_package("corge.grault");
1401 
1402  EnumDescriptorProto* enum2_proto = AddEnum(&bar_file, "TestEnum2");
1403  AddEnumValue(enum2_proto, "FOO", 1);
1404  AddEnumValue(enum2_proto, "BAZ", 3);
1405 
1406  // Build the descriptors and get the pointers.
1407  foo_file_ = pool_.BuildFile(foo_file);
1408  ASSERT_TRUE(foo_file_ != nullptr);
1409 
1410  bar_file_ = pool_.BuildFile(bar_file);
1411  ASSERT_TRUE(bar_file_ != nullptr);
1412 
1414  enum_ = foo_file_->enum_type(0);
1415 
1416  ASSERT_EQ(2, enum_->value_count());
1417  foo_ = enum_->value(0);
1418  bar_ = enum_->value(1);
1419 
1421  enum2_ = bar_file_->enum_type(0);
1422 
1423  ASSERT_EQ(2, enum2_->value_count());
1424  foo2_ = enum2_->value(0);
1425  baz2_ = enum2_->value(1);
1426  }
1427 
1429 
1430  const FileDescriptor* foo_file_;
1431  const FileDescriptor* bar_file_;
1432 
1433  const EnumDescriptor* enum_;
1434  const EnumDescriptor* enum2_;
1435 
1436  const EnumValueDescriptor* foo_;
1437  const EnumValueDescriptor* bar_;
1438 
1439  const EnumValueDescriptor* foo2_;
1440  const EnumValueDescriptor* baz2_;
1441 };
1442 
1443 TEST_F(EnumDescriptorTest, Name) {
1444  EXPECT_EQ("TestEnum", enum_->name());
1445  EXPECT_EQ("TestEnum", enum_->full_name());
1446  EXPECT_EQ(foo_file_, enum_->file());
1447 
1448  EXPECT_EQ("TestEnum2", enum2_->name());
1449  EXPECT_EQ("corge.grault.TestEnum2", enum2_->full_name());
1450  EXPECT_EQ(bar_file_, enum2_->file());
1451 }
1452 
1453 TEST_F(EnumDescriptorTest, ContainingType) {
1454  EXPECT_TRUE(enum_->containing_type() == nullptr);
1455  EXPECT_TRUE(enum2_->containing_type() == nullptr);
1456 }
1457 
1458 TEST_F(EnumDescriptorTest, ValuesByIndex) {
1459  ASSERT_EQ(2, enum_->value_count());
1460  EXPECT_EQ(foo_, enum_->value(0));
1461  EXPECT_EQ(bar_, enum_->value(1));
1462 }
1463 
1464 TEST_F(EnumDescriptorTest, FindValueByName) {
1465  EXPECT_EQ(foo_, enum_->FindValueByName("FOO"));
1466  EXPECT_EQ(bar_, enum_->FindValueByName("BAR"));
1467  EXPECT_EQ(foo2_, enum2_->FindValueByName("FOO"));
1468  EXPECT_EQ(baz2_, enum2_->FindValueByName("BAZ"));
1469 
1470  EXPECT_TRUE(enum_->FindValueByName("NO_SUCH_VALUE") == nullptr);
1471  EXPECT_TRUE(enum_->FindValueByName("BAZ") == nullptr);
1472  EXPECT_TRUE(enum2_->FindValueByName("BAR") == nullptr);
1473 }
1474 
1475 TEST_F(EnumDescriptorTest, FindValueByNumber) {
1476  EXPECT_EQ(foo_, enum_->FindValueByNumber(1));
1477  EXPECT_EQ(bar_, enum_->FindValueByNumber(2));
1478  EXPECT_EQ(foo2_, enum2_->FindValueByNumber(1));
1479  EXPECT_EQ(baz2_, enum2_->FindValueByNumber(3));
1480 
1481  EXPECT_TRUE(enum_->FindValueByNumber(416) == nullptr);
1482  EXPECT_TRUE(enum_->FindValueByNumber(3) == nullptr);
1483  EXPECT_TRUE(enum2_->FindValueByNumber(2) == nullptr);
1484 }
1485 
1486 TEST_F(EnumDescriptorTest, ValueName) {
1487  EXPECT_EQ("FOO", foo_->name());
1488  EXPECT_EQ("BAR", bar_->name());
1489 }
1490 
1491 TEST_F(EnumDescriptorTest, ValueFullName) {
1492  EXPECT_EQ("FOO", foo_->full_name());
1493  EXPECT_EQ("BAR", bar_->full_name());
1494  EXPECT_EQ("corge.grault.FOO", foo2_->full_name());
1495  EXPECT_EQ("corge.grault.BAZ", baz2_->full_name());
1496 }
1497 
1498 TEST_F(EnumDescriptorTest, ValueIndex) {
1499  EXPECT_EQ(0, foo_->index());
1500  EXPECT_EQ(1, bar_->index());
1501 }
1502 
1503 TEST_F(EnumDescriptorTest, ValueNumber) {
1504  EXPECT_EQ(1, foo_->number());
1505  EXPECT_EQ(2, bar_->number());
1506 }
1507 
1508 TEST_F(EnumDescriptorTest, ValueType) {
1509  EXPECT_EQ(enum_, foo_->type());
1510  EXPECT_EQ(enum_, bar_->type());
1511  EXPECT_EQ(enum2_, foo2_->type());
1512  EXPECT_EQ(enum2_, baz2_->type());
1513 }
1514 
1515 // ===================================================================
1516 
1517 // Test service descriptors.
1518 class ServiceDescriptorTest : public testing::Test {
1519  protected:
1520  void SetUp() override {
1521  // Build descriptors for the following messages and service:
1522  // // in "foo.proto"
1523  // message FooRequest {}
1524  // message FooResponse {}
1525  // message BarRequest {}
1526  // message BarResponse {}
1527  // message BazRequest {}
1528  // message BazResponse {}
1529  //
1530  // service TestService {
1531  // rpc Foo(FooRequest) returns (FooResponse);
1532  // rpc Bar(BarRequest) returns (BarResponse);
1533  // }
1534  //
1535  // // in "bar.proto"
1536  // package corge.grault
1537  // service TestService2 {
1538  // rpc Foo(FooRequest) returns (FooResponse);
1539  // rpc Baz(BazRequest) returns (BazResponse);
1540  // }
1541 
1542  FileDescriptorProto foo_file;
1543  foo_file.set_name("foo.proto");
1544 
1545  AddMessage(&foo_file, "FooRequest");
1546  AddMessage(&foo_file, "FooResponse");
1547  AddMessage(&foo_file, "BarRequest");
1548  AddMessage(&foo_file, "BarResponse");
1549  AddMessage(&foo_file, "BazRequest");
1550  AddMessage(&foo_file, "BazResponse");
1551 
1552  ServiceDescriptorProto* service = AddService(&foo_file, "TestService");
1553  AddMethod(service, "Foo", "FooRequest", "FooResponse");
1554  AddMethod(service, "Bar", "BarRequest", "BarResponse");
1555 
1556  FileDescriptorProto bar_file;
1557  bar_file.set_name("bar.proto");
1558  bar_file.set_package("corge.grault");
1559  bar_file.add_dependency("foo.proto");
1560 
1561  ServiceDescriptorProto* service2 = AddService(&bar_file, "TestService2");
1562  AddMethod(service2, "Foo", "FooRequest", "FooResponse");
1563  AddMethod(service2, "Baz", "BazRequest", "BazResponse");
1564 
1565  // Build the descriptors and get the pointers.
1566  foo_file_ = pool_.BuildFile(foo_file);
1567  ASSERT_TRUE(foo_file_ != nullptr);
1568 
1569  bar_file_ = pool_.BuildFile(bar_file);
1570  ASSERT_TRUE(bar_file_ != nullptr);
1571 
1579 
1581  service_ = foo_file_->service(0);
1582 
1584  foo_ = service_->method(0);
1585  bar_ = service_->method(1);
1586 
1588  service2_ = bar_file_->service(0);
1589 
1591  foo2_ = service2_->method(0);
1592  baz2_ = service2_->method(1);
1593  }
1594 
1596 
1597  const FileDescriptor* foo_file_;
1598  const FileDescriptor* bar_file_;
1599 
1600  const Descriptor* foo_request_;
1601  const Descriptor* foo_response_;
1602  const Descriptor* bar_request_;
1603  const Descriptor* bar_response_;
1604  const Descriptor* baz_request_;
1605  const Descriptor* baz_response_;
1606 
1607  const ServiceDescriptor* service_;
1609 
1610  const MethodDescriptor* foo_;
1611  const MethodDescriptor* bar_;
1612 
1613  const MethodDescriptor* foo2_;
1614  const MethodDescriptor* baz2_;
1615 };
1616 
1617 TEST_F(ServiceDescriptorTest, Name) {
1618  EXPECT_EQ("TestService", service_->name());
1619  EXPECT_EQ("TestService", service_->full_name());
1620  EXPECT_EQ(foo_file_, service_->file());
1621 
1622  EXPECT_EQ("TestService2", service2_->name());
1623  EXPECT_EQ("corge.grault.TestService2", service2_->full_name());
1624  EXPECT_EQ(bar_file_, service2_->file());
1625 }
1626 
1627 TEST_F(ServiceDescriptorTest, MethodsByIndex) {
1628  ASSERT_EQ(2, service_->method_count());
1629  EXPECT_EQ(foo_, service_->method(0));
1630  EXPECT_EQ(bar_, service_->method(1));
1631 }
1632 
1633 TEST_F(ServiceDescriptorTest, FindMethodByName) {
1634  EXPECT_EQ(foo_, service_->FindMethodByName("Foo"));
1635  EXPECT_EQ(bar_, service_->FindMethodByName("Bar"));
1636  EXPECT_EQ(foo2_, service2_->FindMethodByName("Foo"));
1637  EXPECT_EQ(baz2_, service2_->FindMethodByName("Baz"));
1638 
1639  EXPECT_TRUE(service_->FindMethodByName("NoSuchMethod") == nullptr);
1640  EXPECT_TRUE(service_->FindMethodByName("Baz") == nullptr);
1641  EXPECT_TRUE(service2_->FindMethodByName("Bar") == nullptr);
1642 }
1643 
1644 TEST_F(ServiceDescriptorTest, MethodName) {
1645  EXPECT_EQ("Foo", foo_->name());
1646  EXPECT_EQ("Bar", bar_->name());
1647 }
1648 
1649 TEST_F(ServiceDescriptorTest, MethodFullName) {
1650  EXPECT_EQ("TestService.Foo", foo_->full_name());
1651  EXPECT_EQ("TestService.Bar", bar_->full_name());
1652  EXPECT_EQ("corge.grault.TestService2.Foo", foo2_->full_name());
1653  EXPECT_EQ("corge.grault.TestService2.Baz", baz2_->full_name());
1654 }
1655 
1656 TEST_F(ServiceDescriptorTest, MethodIndex) {
1657  EXPECT_EQ(0, foo_->index());
1658  EXPECT_EQ(1, bar_->index());
1659 }
1660 
1661 TEST_F(ServiceDescriptorTest, MethodParent) {
1662  EXPECT_EQ(service_, foo_->service());
1663  EXPECT_EQ(service_, bar_->service());
1664 }
1665 
1666 TEST_F(ServiceDescriptorTest, MethodInputType) {
1667  EXPECT_EQ(foo_request_, foo_->input_type());
1668  EXPECT_EQ(bar_request_, bar_->input_type());
1669 }
1670 
1671 TEST_F(ServiceDescriptorTest, MethodOutputType) {
1672  EXPECT_EQ(foo_response_, foo_->output_type());
1673  EXPECT_EQ(bar_response_, bar_->output_type());
1674 }
1675 
1676 // ===================================================================
1677 
1678 // Test nested types.
1679 class NestedDescriptorTest : public testing::Test {
1680  protected:
1681  void SetUp() override {
1682  // Build descriptors for the following definitions:
1683  //
1684  // // in "foo.proto"
1685  // message TestMessage {
1686  // message Foo {}
1687  // message Bar {}
1688  // enum Baz { A = 1; }
1689  // enum Qux { B = 1; }
1690  // }
1691  //
1692  // // in "bar.proto"
1693  // package corge.grault;
1694  // message TestMessage2 {
1695  // message Foo {}
1696  // message Baz {}
1697  // enum Qux { A = 1; }
1698  // enum Quux { C = 1; }
1699  // }
1700  //
1701  // TestMessage2 is primarily here to test FindNestedTypeByName and friends.
1702  // All messages created from the same DescriptorPool share the same lookup
1703  // table, so we need to insure that they don't interfere.
1704  //
1705  // We add enum values to the enums in order to test searching for enum
1706  // values across a message's scope.
1707 
1708  FileDescriptorProto foo_file;
1709  foo_file.set_name("foo.proto");
1710 
1711  DescriptorProto* message = AddMessage(&foo_file, "TestMessage");
1712  AddNestedMessage(message, "Foo");
1713  AddNestedMessage(message, "Bar");
1714  EnumDescriptorProto* baz = AddNestedEnum(message, "Baz");
1715  AddEnumValue(baz, "A", 1);
1716  EnumDescriptorProto* qux = AddNestedEnum(message, "Qux");
1717  AddEnumValue(qux, "B", 1);
1718 
1719  FileDescriptorProto bar_file;
1720  bar_file.set_name("bar.proto");
1721  bar_file.set_package("corge.grault");
1722 
1723  DescriptorProto* message2 = AddMessage(&bar_file, "TestMessage2");
1724  AddNestedMessage(message2, "Foo");
1725  AddNestedMessage(message2, "Baz");
1726  EnumDescriptorProto* qux2 = AddNestedEnum(message2, "Qux");
1727  AddEnumValue(qux2, "A", 1);
1728  EnumDescriptorProto* quux2 = AddNestedEnum(message2, "Quux");
1729  AddEnumValue(quux2, "C", 1);
1730 
1731  // Build the descriptors and get the pointers.
1732  foo_file_ = pool_.BuildFile(foo_file);
1733  ASSERT_TRUE(foo_file_ != nullptr);
1734 
1735  bar_file_ = pool_.BuildFile(bar_file);
1736  ASSERT_TRUE(bar_file_ != nullptr);
1737 
1740 
1742  foo_ = message_->nested_type(0);
1743  bar_ = message_->nested_type(1);
1744 
1746  baz_ = message_->enum_type(0);
1747  qux_ = message_->enum_type(1);
1748 
1749  ASSERT_EQ(1, baz_->value_count());
1750  a_ = baz_->value(0);
1751  ASSERT_EQ(1, qux_->value_count());
1752  b_ = qux_->value(0);
1753 
1756 
1758  foo2_ = message2_->nested_type(0);
1759  baz2_ = message2_->nested_type(1);
1760 
1762  qux2_ = message2_->enum_type(0);
1763  quux2_ = message2_->enum_type(1);
1764 
1765  ASSERT_EQ(1, qux2_->value_count());
1766  a2_ = qux2_->value(0);
1767  ASSERT_EQ(1, quux2_->value_count());
1768  c2_ = quux2_->value(0);
1769  }
1770 
1772 
1773  const FileDescriptor* foo_file_;
1774  const FileDescriptor* bar_file_;
1775 
1776  const Descriptor* message_;
1777  const Descriptor* message2_;
1778 
1779  const Descriptor* foo_;
1780  const Descriptor* bar_;
1781  const EnumDescriptor* baz_;
1782  const EnumDescriptor* qux_;
1783  const EnumValueDescriptor* a_;
1784  const EnumValueDescriptor* b_;
1785 
1786  const Descriptor* foo2_;
1787  const Descriptor* baz2_;
1788  const EnumDescriptor* qux2_;
1789  const EnumDescriptor* quux2_;
1790  const EnumValueDescriptor* a2_;
1791  const EnumValueDescriptor* c2_;
1792 };
1793 
1794 TEST_F(NestedDescriptorTest, MessageName) {
1795  EXPECT_EQ("Foo", foo_->name());
1796  EXPECT_EQ("Bar", bar_->name());
1797  EXPECT_EQ("Foo", foo2_->name());
1798  EXPECT_EQ("Baz", baz2_->name());
1799 
1800  EXPECT_EQ("TestMessage.Foo", foo_->full_name());
1801  EXPECT_EQ("TestMessage.Bar", bar_->full_name());
1802  EXPECT_EQ("corge.grault.TestMessage2.Foo", foo2_->full_name());
1803  EXPECT_EQ("corge.grault.TestMessage2.Baz", baz2_->full_name());
1804 }
1805 
1806 TEST_F(NestedDescriptorTest, MessageContainingType) {
1807  EXPECT_EQ(message_, foo_->containing_type());
1808  EXPECT_EQ(message_, bar_->containing_type());
1809  EXPECT_EQ(message2_, foo2_->containing_type());
1810  EXPECT_EQ(message2_, baz2_->containing_type());
1811 }
1812 
1813 TEST_F(NestedDescriptorTest, NestedMessagesByIndex) {
1814  ASSERT_EQ(2, message_->nested_type_count());
1815  EXPECT_EQ(foo_, message_->nested_type(0));
1816  EXPECT_EQ(bar_, message_->nested_type(1));
1817 }
1818 
1819 TEST_F(NestedDescriptorTest, FindFieldByNameDoesntFindNestedTypes) {
1820  EXPECT_TRUE(message_->FindFieldByName("Foo") == nullptr);
1821  EXPECT_TRUE(message_->FindFieldByName("Qux") == nullptr);
1822  EXPECT_TRUE(message_->FindExtensionByName("Foo") == nullptr);
1823  EXPECT_TRUE(message_->FindExtensionByName("Qux") == nullptr);
1824 }
1825 
1826 TEST_F(NestedDescriptorTest, FindNestedTypeByName) {
1827  EXPECT_EQ(foo_, message_->FindNestedTypeByName("Foo"));
1828  EXPECT_EQ(bar_, message_->FindNestedTypeByName("Bar"));
1829  EXPECT_EQ(foo2_, message2_->FindNestedTypeByName("Foo"));
1830  EXPECT_EQ(baz2_, message2_->FindNestedTypeByName("Baz"));
1831 
1832  EXPECT_TRUE(message_->FindNestedTypeByName("NoSuchType") == nullptr);
1833  EXPECT_TRUE(message_->FindNestedTypeByName("Baz") == nullptr);
1834  EXPECT_TRUE(message2_->FindNestedTypeByName("Bar") == nullptr);
1835 
1836  EXPECT_TRUE(message_->FindNestedTypeByName("Qux") == nullptr);
1837 }
1838 
1839 TEST_F(NestedDescriptorTest, EnumName) {
1840  EXPECT_EQ("Baz", baz_->name());
1841  EXPECT_EQ("Qux", qux_->name());
1842  EXPECT_EQ("Qux", qux2_->name());
1843  EXPECT_EQ("Quux", quux2_->name());
1844 
1845  EXPECT_EQ("TestMessage.Baz", baz_->full_name());
1846  EXPECT_EQ("TestMessage.Qux", qux_->full_name());
1847  EXPECT_EQ("corge.grault.TestMessage2.Qux", qux2_->full_name());
1848  EXPECT_EQ("corge.grault.TestMessage2.Quux", quux2_->full_name());
1849 }
1850 
1851 TEST_F(NestedDescriptorTest, EnumContainingType) {
1852  EXPECT_EQ(message_, baz_->containing_type());
1853  EXPECT_EQ(message_, qux_->containing_type());
1854  EXPECT_EQ(message2_, qux2_->containing_type());
1855  EXPECT_EQ(message2_, quux2_->containing_type());
1856 }
1857 
1858 TEST_F(NestedDescriptorTest, NestedEnumsByIndex) {
1859  ASSERT_EQ(2, message_->nested_type_count());
1860  EXPECT_EQ(foo_, message_->nested_type(0));
1861  EXPECT_EQ(bar_, message_->nested_type(1));
1862 }
1863 
1864 TEST_F(NestedDescriptorTest, FindEnumTypeByName) {
1865  EXPECT_EQ(baz_, message_->FindEnumTypeByName("Baz"));
1866  EXPECT_EQ(qux_, message_->FindEnumTypeByName("Qux"));
1867  EXPECT_EQ(qux2_, message2_->FindEnumTypeByName("Qux"));
1868  EXPECT_EQ(quux2_, message2_->FindEnumTypeByName("Quux"));
1869 
1870  EXPECT_TRUE(message_->FindEnumTypeByName("NoSuchType") == nullptr);
1871  EXPECT_TRUE(message_->FindEnumTypeByName("Quux") == nullptr);
1872  EXPECT_TRUE(message2_->FindEnumTypeByName("Baz") == nullptr);
1873 
1874  EXPECT_TRUE(message_->FindEnumTypeByName("Foo") == nullptr);
1875 }
1876 
1877 TEST_F(NestedDescriptorTest, FindEnumValueByName) {
1878  EXPECT_EQ(a_, message_->FindEnumValueByName("A"));
1879  EXPECT_EQ(b_, message_->FindEnumValueByName("B"));
1880  EXPECT_EQ(a2_, message2_->FindEnumValueByName("A"));
1881  EXPECT_EQ(c2_, message2_->FindEnumValueByName("C"));
1882 
1883  EXPECT_TRUE(message_->FindEnumValueByName("NO_SUCH_VALUE") == nullptr);
1884  EXPECT_TRUE(message_->FindEnumValueByName("C") == nullptr);
1885  EXPECT_TRUE(message2_->FindEnumValueByName("B") == nullptr);
1886 
1887  EXPECT_TRUE(message_->FindEnumValueByName("Foo") == nullptr);
1888 }
1889 
1890 // ===================================================================
1891 
1892 // Test extensions.
1893 class ExtensionDescriptorTest : public testing::Test {
1894  protected:
1895  void SetUp() override {
1896  // Build descriptors for the following definitions:
1897  //
1898  // enum Baz {}
1899  // message Qux {}
1900  //
1901  // message Foo {
1902  // extensions 10 to 19;
1903  // extensions 30 to 39;
1904  // }
1905  // extend Foo {
1906  // optional int32 foo_int32 = 10;
1907  // }
1908  // extend Foo {
1909  // repeated TestEnum foo_enum = 19;
1910  // }
1911  // message Bar {
1912  // optional int32 non_ext_int32 = 1;
1913  // extend Foo {
1914  // optional Qux foo_message = 30;
1915  // repeated Qux foo_group = 39; // (but internally set to TYPE_GROUP)
1916  // }
1917  // }
1918 
1919  FileDescriptorProto foo_file;
1920  foo_file.set_name("foo.proto");
1921 
1922  AddEmptyEnum(&foo_file, "Baz");
1923  AddMessage(&foo_file, "Qux");
1924 
1925  DescriptorProto* foo = AddMessage(&foo_file, "Foo");
1926  AddExtensionRange(foo, 10, 20);
1927  AddExtensionRange(foo, 30, 40);
1928 
1929  AddExtension(&foo_file, "Foo", "foo_int32", 10,
1932  AddExtension(&foo_file, "Foo", "foo_enum", 19,
1935  ->set_type_name("Baz");
1936 
1937  DescriptorProto* bar = AddMessage(&foo_file, "Bar");
1938  AddField(bar, "non_ext_int32", 1, FieldDescriptorProto::LABEL_OPTIONAL,
1940  AddNestedExtension(bar, "Foo", "foo_message", 30,
1943  ->set_type_name("Qux");
1944  AddNestedExtension(bar, "Foo", "foo_group", 39,
1947  ->set_type_name("Qux");
1948 
1949  // Build the descriptors and get the pointers.
1950  foo_file_ = pool_.BuildFile(foo_file);
1951  ASSERT_TRUE(foo_file_ != nullptr);
1952 
1954  baz_ = foo_file_->enum_type(0);
1955 
1957  qux_ = foo_file_->message_type(0);
1958  foo_ = foo_file_->message_type(1);
1959  bar_ = foo_file_->message_type(2);
1960  }
1961 
1963 
1964  const FileDescriptor* foo_file_;
1965 
1966  const Descriptor* foo_;
1967  const Descriptor* bar_;
1968  const EnumDescriptor* baz_;
1969  const Descriptor* qux_;
1970 };
1971 
1972 TEST_F(ExtensionDescriptorTest, ExtensionRanges) {
1973  EXPECT_EQ(0, bar_->extension_range_count());
1974  ASSERT_EQ(2, foo_->extension_range_count());
1975 
1976  EXPECT_EQ(10, foo_->extension_range(0)->start);
1977  EXPECT_EQ(30, foo_->extension_range(1)->start);
1978 
1979  EXPECT_EQ(20, foo_->extension_range(0)->end);
1980  EXPECT_EQ(40, foo_->extension_range(1)->end);
1981 }
1982 
1983 TEST_F(ExtensionDescriptorTest, Extensions) {
1984  EXPECT_EQ(0, foo_->extension_count());
1985  ASSERT_EQ(2, foo_file_->extension_count());
1986  ASSERT_EQ(2, bar_->extension_count());
1987 
1988  EXPECT_TRUE(foo_file_->extension(0)->is_extension());
1989  EXPECT_TRUE(foo_file_->extension(1)->is_extension());
1990  EXPECT_TRUE(bar_->extension(0)->is_extension());
1991  EXPECT_TRUE(bar_->extension(1)->is_extension());
1992 
1993  EXPECT_EQ("foo_int32", foo_file_->extension(0)->name());
1994  EXPECT_EQ("foo_enum", foo_file_->extension(1)->name());
1995  EXPECT_EQ("foo_message", bar_->extension(0)->name());
1996  EXPECT_EQ("foo_group", bar_->extension(1)->name());
1997 
1998  EXPECT_EQ(10, foo_file_->extension(0)->number());
1999  EXPECT_EQ(19, foo_file_->extension(1)->number());
2000  EXPECT_EQ(30, bar_->extension(0)->number());
2001  EXPECT_EQ(39, bar_->extension(1)->number());
2002 
2003  EXPECT_EQ(FieldDescriptor::TYPE_INT32, foo_file_->extension(0)->type());
2004  EXPECT_EQ(FieldDescriptor::TYPE_ENUM, foo_file_->extension(1)->type());
2005  EXPECT_EQ(FieldDescriptor::TYPE_MESSAGE, bar_->extension(0)->type());
2006  EXPECT_EQ(FieldDescriptor::TYPE_GROUP, bar_->extension(1)->type());
2007 
2008  EXPECT_EQ(baz_, foo_file_->extension(1)->enum_type());
2009  EXPECT_EQ(qux_, bar_->extension(0)->message_type());
2010  EXPECT_EQ(qux_, bar_->extension(1)->message_type());
2011 
2012  EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, foo_file_->extension(0)->label());
2013  EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, foo_file_->extension(1)->label());
2014  EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, bar_->extension(0)->label());
2015  EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, bar_->extension(1)->label());
2016 
2017  EXPECT_EQ(foo_, foo_file_->extension(0)->containing_type());
2018  EXPECT_EQ(foo_, foo_file_->extension(1)->containing_type());
2019  EXPECT_EQ(foo_, bar_->extension(0)->containing_type());
2020  EXPECT_EQ(foo_, bar_->extension(1)->containing_type());
2021 
2022  EXPECT_TRUE(foo_file_->extension(0)->extension_scope() == nullptr);
2023  EXPECT_TRUE(foo_file_->extension(1)->extension_scope() == nullptr);
2024  EXPECT_EQ(bar_, bar_->extension(0)->extension_scope());
2025  EXPECT_EQ(bar_, bar_->extension(1)->extension_scope());
2026 }
2027 
2028 TEST_F(ExtensionDescriptorTest, IsExtensionNumber) {
2029  EXPECT_FALSE(foo_->IsExtensionNumber(9));
2030  EXPECT_TRUE(foo_->IsExtensionNumber(10));
2031  EXPECT_TRUE(foo_->IsExtensionNumber(19));
2032  EXPECT_FALSE(foo_->IsExtensionNumber(20));
2033  EXPECT_FALSE(foo_->IsExtensionNumber(29));
2034  EXPECT_TRUE(foo_->IsExtensionNumber(30));
2035  EXPECT_TRUE(foo_->IsExtensionNumber(39));
2036  EXPECT_FALSE(foo_->IsExtensionNumber(40));
2037 }
2038 
2039 TEST_F(ExtensionDescriptorTest, FindExtensionByName) {
2040  // Note that FileDescriptor::FindExtensionByName() is tested by
2041  // FileDescriptorTest.
2042  ASSERT_EQ(2, bar_->extension_count());
2043 
2044  EXPECT_EQ(bar_->extension(0), bar_->FindExtensionByName("foo_message"));
2045  EXPECT_EQ(bar_->extension(1), bar_->FindExtensionByName("foo_group"));
2046 
2047  EXPECT_TRUE(bar_->FindExtensionByName("no_such_extension") == nullptr);
2048  EXPECT_TRUE(foo_->FindExtensionByName("foo_int32") == nullptr);
2049  EXPECT_TRUE(foo_->FindExtensionByName("foo_message") == nullptr);
2050 }
2051 
2052 TEST_F(ExtensionDescriptorTest, FieldVsExtension) {
2053  EXPECT_EQ(foo_->FindFieldByName("foo_message"), nullptr);
2054  EXPECT_EQ(bar_->FindFieldByName("foo_message"), nullptr);
2055  EXPECT_NE(bar_->FindFieldByName("non_ext_int32"), nullptr);
2056  EXPECT_EQ(foo_->FindExtensionByName("foo_message"), nullptr);
2057  EXPECT_NE(bar_->FindExtensionByName("foo_message"), nullptr);
2058  EXPECT_EQ(bar_->FindExtensionByName("non_ext_int32"), nullptr);
2059 }
2060 
2061 TEST_F(ExtensionDescriptorTest, FindExtensionByPrintableName) {
2062  EXPECT_TRUE(pool_.FindExtensionByPrintableName(foo_, "no_such_extension") ==
2063  nullptr);
2064  EXPECT_TRUE(pool_.FindExtensionByPrintableName(bar_, "no_such_extension") ==
2065  nullptr);
2066 
2067  ASSERT_FALSE(pool_.FindExtensionByPrintableName(foo_, "Bar.foo_message") ==
2068  nullptr);
2069  ASSERT_FALSE(pool_.FindExtensionByPrintableName(foo_, "Bar.foo_group") ==
2070  nullptr);
2071  EXPECT_TRUE(pool_.FindExtensionByPrintableName(bar_, "foo_message") ==
2072  nullptr);
2073  EXPECT_TRUE(pool_.FindExtensionByPrintableName(bar_, "foo_group") == nullptr);
2074  EXPECT_EQ(bar_->FindExtensionByName("foo_message"),
2075  pool_.FindExtensionByPrintableName(foo_, "Bar.foo_message"));
2076  EXPECT_EQ(bar_->FindExtensionByName("foo_group"),
2077  pool_.FindExtensionByPrintableName(foo_, "Bar.foo_group"));
2078 
2079  ASSERT_FALSE(pool_.FindExtensionByPrintableName(foo_, "foo_int32") ==
2080  nullptr);
2081  ASSERT_FALSE(pool_.FindExtensionByPrintableName(foo_, "foo_enum") == nullptr);
2082  EXPECT_TRUE(pool_.FindExtensionByPrintableName(bar_, "foo_int32") == nullptr);
2083  EXPECT_TRUE(pool_.FindExtensionByPrintableName(bar_, "foo_enum") == nullptr);
2084  EXPECT_EQ(foo_file_->FindExtensionByName("foo_int32"),
2085  pool_.FindExtensionByPrintableName(foo_, "foo_int32"));
2086  EXPECT_EQ(foo_file_->FindExtensionByName("foo_enum"),
2087  pool_.FindExtensionByPrintableName(foo_, "foo_enum"));
2088 }
2089 
2090 TEST_F(ExtensionDescriptorTest, FindAllExtensions) {
2091  std::vector<const FieldDescriptor*> extensions;
2092  pool_.FindAllExtensions(foo_, &extensions);
2093  ASSERT_EQ(4, extensions.size());
2094  EXPECT_EQ(10, extensions[0]->number());
2095  EXPECT_EQ(19, extensions[1]->number());
2096  EXPECT_EQ(30, extensions[2]->number());
2097  EXPECT_EQ(39, extensions[3]->number());
2098 }
2099 
2100 
2101 TEST_F(ExtensionDescriptorTest, DuplicateFieldNumber) {
2103  FileDescriptorProto file_proto;
2104  // Add "google/protobuf/descriptor.proto".
2105  FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
2106  ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
2107  // Add "foo.proto":
2108  // import "google/protobuf/descriptor.proto";
2109  // extend google.protobuf.FieldOptions {
2110  // optional int32 option1 = 1000;
2111  // }
2112  file_proto.Clear();
2113  file_proto.set_name("foo.proto");
2114  file_proto.add_dependency("google/protobuf/descriptor.proto");
2115  AddExtension(&file_proto, "google.protobuf.FieldOptions", "option1", 1000,
2118  ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
2119  // Add "bar.proto":
2120  // import "google/protobuf/descriptor.proto";
2121  // extend google.protobuf.FieldOptions {
2122  // optional int32 option2 = 1000;
2123  // }
2124  file_proto.Clear();
2125  file_proto.set_name("bar.proto");
2126  file_proto.add_dependency("google/protobuf/descriptor.proto");
2127  AddExtension(&file_proto, "google.protobuf.FieldOptions", "option2", 1000,
2130  // Currently we only generate a warning for conflicting extension numbers.
2131  // TODO(xiaofeng): Change it to an error.
2132  ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
2133 }
2134 
2135 // ===================================================================
2136 
2137 // Ensure that overlapping extension ranges are not allowed.
2138 TEST(OverlappingExtensionRangeTest, ExtensionRangeInternal) {
2139  // Build descriptors for the following definitions:
2140  //
2141  // message Foo {
2142  // extensions 10 to 19;
2143  // extensions 15;
2144  // }
2145  FileDescriptorProto foo_file;
2146  foo_file.set_name("foo.proto");
2147 
2148  DescriptorProto* foo = AddMessage(&foo_file, "Foo");
2149  AddExtensionRange(foo, 10, 20);
2150  AddExtensionRange(foo, 15, 16);
2151 
2153  MockErrorCollector error_collector;
2154  // The extensions ranges are invalid, so the proto shouldn't build.
2155  ASSERT_TRUE(pool.BuildFileCollectingErrors(foo_file, &error_collector) ==
2156  nullptr);
2157  ASSERT_EQ(
2158  "foo.proto: Foo: NUMBER: Extension range 15 to 15 overlaps with "
2159  "already-defined range 10 to 19.\n",
2160  error_collector.text_);
2161 }
2162 
2163 TEST(OverlappingExtensionRangeTest, ExtensionRangeAfter) {
2164  // Build descriptors for the following definitions:
2165  //
2166  // message Foo {
2167  // extensions 10 to 19;
2168  // extensions 15 to 24;
2169  // }
2170  FileDescriptorProto foo_file;
2171  foo_file.set_name("foo.proto");
2172 
2173  DescriptorProto* foo = AddMessage(&foo_file, "Foo");
2174  AddExtensionRange(foo, 10, 20);
2175  AddExtensionRange(foo, 15, 25);
2176 
2178  MockErrorCollector error_collector;
2179  // The extensions ranges are invalid, so the proto shouldn't build.
2180  ASSERT_TRUE(pool.BuildFileCollectingErrors(foo_file, &error_collector) ==
2181  nullptr);
2182  ASSERT_EQ(
2183  "foo.proto: Foo: NUMBER: Extension range 15 to 24 overlaps with "
2184  "already-defined range 10 to 19.\n",
2185  error_collector.text_);
2186 }
2187 
2188 TEST(OverlappingExtensionRangeTest, ExtensionRangeBefore) {
2189  // Build descriptors for the following definitions:
2190  //
2191  // message Foo {
2192  // extensions 10 to 19;
2193  // extensions 5 to 14;
2194  // }
2195  FileDescriptorProto foo_file;
2196  foo_file.set_name("foo.proto");
2197 
2198  DescriptorProto* foo = AddMessage(&foo_file, "Foo");
2199  AddExtensionRange(foo, 10, 20);
2200  AddExtensionRange(foo, 5, 15);
2201 
2203  MockErrorCollector error_collector;
2204  // The extensions ranges are invalid, so the proto shouldn't build.
2205  ASSERT_TRUE(pool.BuildFileCollectingErrors(foo_file, &error_collector) ==
2206  nullptr);
2207  ASSERT_EQ(
2208  "foo.proto: Foo: NUMBER: Extension range 5 to 14 overlaps with "
2209  "already-defined range 10 to 19.\n",
2210  error_collector.text_);
2211 }
2212 
2213 // ===================================================================
2214 
2215 // Test reserved fields.
2216 class ReservedDescriptorTest : public testing::Test {
2217  protected:
2218  void SetUp() override {
2219  // Build descriptors for the following definitions:
2220  //
2221  // message Foo {
2222  // reserved 2, 9 to 11, 15;
2223  // reserved "foo", "bar";
2224  // }
2225 
2226  FileDescriptorProto foo_file;
2227  foo_file.set_name("foo.proto");
2228 
2229  DescriptorProto* foo = AddMessage(&foo_file, "Foo");
2230  AddReservedRange(foo, 2, 3);
2231  AddReservedRange(foo, 9, 12);
2232  AddReservedRange(foo, 15, 16);
2233 
2234  foo->add_reserved_name("foo");
2235  foo->add_reserved_name("bar");
2236 
2237  // Build the descriptors and get the pointers.
2238  foo_file_ = pool_.BuildFile(foo_file);
2239  ASSERT_TRUE(foo_file_ != nullptr);
2240 
2242  foo_ = foo_file_->message_type(0);
2243  }
2244 
2246  const FileDescriptor* foo_file_;
2247  const Descriptor* foo_;
2248 };
2249 
2250 TEST_F(ReservedDescriptorTest, ReservedRanges) {
2251  ASSERT_EQ(3, foo_->reserved_range_count());
2252 
2253  EXPECT_EQ(2, foo_->reserved_range(0)->start);
2254  EXPECT_EQ(3, foo_->reserved_range(0)->end);
2255 
2256  EXPECT_EQ(9, foo_->reserved_range(1)->start);
2257  EXPECT_EQ(12, foo_->reserved_range(1)->end);
2258 
2259  EXPECT_EQ(15, foo_->reserved_range(2)->start);
2260  EXPECT_EQ(16, foo_->reserved_range(2)->end);
2261 }
2262 
2263 TEST_F(ReservedDescriptorTest, IsReservedNumber) {
2264  EXPECT_FALSE(foo_->IsReservedNumber(1));
2265  EXPECT_TRUE(foo_->IsReservedNumber(2));
2266  EXPECT_FALSE(foo_->IsReservedNumber(3));
2267  EXPECT_FALSE(foo_->IsReservedNumber(8));
2268  EXPECT_TRUE(foo_->IsReservedNumber(9));
2269  EXPECT_TRUE(foo_->IsReservedNumber(10));
2270  EXPECT_TRUE(foo_->IsReservedNumber(11));
2271  EXPECT_FALSE(foo_->IsReservedNumber(12));
2272  EXPECT_FALSE(foo_->IsReservedNumber(13));
2273  EXPECT_FALSE(foo_->IsReservedNumber(14));
2274  EXPECT_TRUE(foo_->IsReservedNumber(15));
2275  EXPECT_FALSE(foo_->IsReservedNumber(16));
2276 }
2277 
2278 TEST_F(ReservedDescriptorTest, ReservedNames) {
2279  ASSERT_EQ(2, foo_->reserved_name_count());
2280 
2281  EXPECT_EQ("foo", foo_->reserved_name(0));
2282  EXPECT_EQ("bar", foo_->reserved_name(1));
2283 }
2284 
2285 TEST_F(ReservedDescriptorTest, IsReservedName) {
2286  EXPECT_TRUE(foo_->IsReservedName("foo"));
2287  EXPECT_TRUE(foo_->IsReservedName("bar"));
2288  EXPECT_FALSE(foo_->IsReservedName("baz"));
2289 }
2290 
2291 // ===================================================================
2292 
2293 // Test reserved enum fields.
2294 class ReservedEnumDescriptorTest : public testing::Test {
2295  protected:
2296  void SetUp() override {
2297  // Build descriptors for the following definitions:
2298  //
2299  // enum Foo {
2300  // BAR = 1;
2301  // reserved 2, 9 to 11, 15;
2302  // reserved "foo", "bar";
2303  // }
2304 
2305  FileDescriptorProto foo_file;
2306  foo_file.set_name("foo.proto");
2307 
2308  EnumDescriptorProto* foo = AddEnum(&foo_file, "Foo");
2309  EnumDescriptorProto* edge1 = AddEnum(&foo_file, "Edge1");
2310  EnumDescriptorProto* edge2 = AddEnum(&foo_file, "Edge2");
2311 
2312  AddEnumValue(foo, "BAR", 4);
2313  AddReservedRange(foo, -5, -3);
2314  AddReservedRange(foo, -2, 1);
2315  AddReservedRange(foo, 2, 3);
2316  AddReservedRange(foo, 9, 12);
2317  AddReservedRange(foo, 15, 16);
2318 
2319  foo->add_reserved_name("foo");
2320  foo->add_reserved_name("bar");
2321 
2322  // Some additional edge cases that cover most or all of the range of enum
2323  // values
2324 
2325  // Note: We use INT_MAX as the maximum reserved range upper bound,
2326  // inclusive.
2327  AddEnumValue(edge1, "EDGE1", 1);
2328  AddReservedRange(edge1, 10, INT_MAX);
2329  AddEnumValue(edge2, "EDGE2", 15);
2330  AddReservedRange(edge2, INT_MIN, 10);
2331 
2332  // Build the descriptors and get the pointers.
2333  foo_file_ = pool_.BuildFile(foo_file);
2334  ASSERT_TRUE(foo_file_ != nullptr);
2335 
2337  foo_ = foo_file_->enum_type(0);
2338  edge1_ = foo_file_->enum_type(1);
2339  edge2_ = foo_file_->enum_type(2);
2340  }
2341 
2343  const FileDescriptor* foo_file_;
2344  const EnumDescriptor* foo_;
2345  const EnumDescriptor* edge1_;
2346  const EnumDescriptor* edge2_;
2347 };
2348 
2349 TEST_F(ReservedEnumDescriptorTest, ReservedRanges) {
2350  ASSERT_EQ(5, foo_->reserved_range_count());
2351 
2352  EXPECT_EQ(-5, foo_->reserved_range(0)->start);
2353  EXPECT_EQ(-3, foo_->reserved_range(0)->end);
2354 
2355  EXPECT_EQ(-2, foo_->reserved_range(1)->start);
2356  EXPECT_EQ(1, foo_->reserved_range(1)->end);
2357 
2358  EXPECT_EQ(2, foo_->reserved_range(2)->start);
2359  EXPECT_EQ(3, foo_->reserved_range(2)->end);
2360 
2361  EXPECT_EQ(9, foo_->reserved_range(3)->start);
2362  EXPECT_EQ(12, foo_->reserved_range(3)->end);
2363 
2364  EXPECT_EQ(15, foo_->reserved_range(4)->start);
2365  EXPECT_EQ(16, foo_->reserved_range(4)->end);
2366 
2367  ASSERT_EQ(1, edge1_->reserved_range_count());
2368  EXPECT_EQ(10, edge1_->reserved_range(0)->start);
2369  EXPECT_EQ(INT_MAX, edge1_->reserved_range(0)->end);
2370 
2371  ASSERT_EQ(1, edge2_->reserved_range_count());
2372  EXPECT_EQ(INT_MIN, edge2_->reserved_range(0)->start);
2373  EXPECT_EQ(10, edge2_->reserved_range(0)->end);
2374 }
2375 
2376 TEST_F(ReservedEnumDescriptorTest, IsReservedNumber) {
2377  EXPECT_TRUE(foo_->IsReservedNumber(-5));
2378  EXPECT_TRUE(foo_->IsReservedNumber(-4));
2379  EXPECT_TRUE(foo_->IsReservedNumber(-3));
2380  EXPECT_TRUE(foo_->IsReservedNumber(-2));
2381  EXPECT_TRUE(foo_->IsReservedNumber(-1));
2382  EXPECT_TRUE(foo_->IsReservedNumber(0));
2383  EXPECT_TRUE(foo_->IsReservedNumber(1));
2384  EXPECT_TRUE(foo_->IsReservedNumber(2));
2385  EXPECT_TRUE(foo_->IsReservedNumber(3));
2386  EXPECT_FALSE(foo_->IsReservedNumber(8));
2387  EXPECT_TRUE(foo_->IsReservedNumber(9));
2388  EXPECT_TRUE(foo_->IsReservedNumber(10));
2389  EXPECT_TRUE(foo_->IsReservedNumber(11));
2390  EXPECT_TRUE(foo_->IsReservedNumber(12));
2391  EXPECT_FALSE(foo_->IsReservedNumber(13));
2392  EXPECT_FALSE(foo_->IsReservedNumber(13));
2393  EXPECT_FALSE(foo_->IsReservedNumber(14));
2394  EXPECT_TRUE(foo_->IsReservedNumber(15));
2395  EXPECT_TRUE(foo_->IsReservedNumber(16));
2396  EXPECT_FALSE(foo_->IsReservedNumber(17));
2397 
2398  EXPECT_FALSE(edge1_->IsReservedNumber(9));
2399  EXPECT_TRUE(edge1_->IsReservedNumber(10));
2400  EXPECT_TRUE(edge1_->IsReservedNumber(INT_MAX - 1));
2401  EXPECT_TRUE(edge1_->IsReservedNumber(INT_MAX));
2402 
2403  EXPECT_TRUE(edge2_->IsReservedNumber(INT_MIN));
2404  EXPECT_TRUE(edge2_->IsReservedNumber(9));
2405  EXPECT_TRUE(edge2_->IsReservedNumber(10));
2406  EXPECT_FALSE(edge2_->IsReservedNumber(11));
2407 }
2408 
2409 TEST_F(ReservedEnumDescriptorTest, ReservedNames) {
2410  ASSERT_EQ(2, foo_->reserved_name_count());
2411 
2412  EXPECT_EQ("foo", foo_->reserved_name(0));
2413  EXPECT_EQ("bar", foo_->reserved_name(1));
2414 }
2415 
2416 TEST_F(ReservedEnumDescriptorTest, IsReservedName) {
2417  EXPECT_TRUE(foo_->IsReservedName("foo"));
2418  EXPECT_TRUE(foo_->IsReservedName("bar"));
2419  EXPECT_FALSE(foo_->IsReservedName("baz"));
2420 }
2421 
2422 // ===================================================================
2423 
2424 class MiscTest : public testing::Test {
2425  protected:
2426  // Function which makes a field descriptor of the given type.
2428  FileDescriptorProto file_proto;
2429  file_proto.set_name("foo.proto");
2430  AddEmptyEnum(&file_proto, "DummyEnum");
2431 
2432  DescriptorProto* message = AddMessage(&file_proto, "TestMessage");
2435  static_cast<FieldDescriptorProto::Type>(static_cast<int>(type)));
2436 
2439  field->set_type_name("TestMessage");
2440  } else if (type == FieldDescriptor::TYPE_ENUM) {
2441  field->set_type_name("DummyEnum");
2442  }
2443 
2444  // Build the descriptors and get the pointers.
2445  pool_.reset(new DescriptorPool());
2446  const FileDescriptor* file = pool_->BuildFile(file_proto);
2447 
2448  if (file != nullptr && file->message_type_count() == 1 &&
2449  file->message_type(0)->field_count() == 1) {
2450  return file->message_type(0)->field(0);
2451  } else {
2452  return nullptr;
2453  }
2454  }
2455 
2458  return field != nullptr ? field->type_name() : "";
2459  }
2460 
2463  return field != nullptr ? field->cpp_type()
2464  : static_cast<FieldDescriptor::CppType>(0);
2465  }
2466 
2469  return field != nullptr ? field->cpp_type_name() : "";
2470  }
2471 
2475  return field != nullptr ? field->message_type() : nullptr;
2476  }
2477 
2481  return field != nullptr ? field->enum_type() : nullptr;
2482  }
2483 
2484  std::unique_ptr<DescriptorPool> pool_;
2485 };
2486 
2487 TEST_F(MiscTest, TypeNames) {
2488  // Test that correct type names are returned.
2489 
2490  typedef FieldDescriptor FD; // avoid ugly line wrapping
2491 
2492  EXPECT_STREQ("double", GetTypeNameForFieldType(FD::TYPE_DOUBLE));
2493  EXPECT_STREQ("float", GetTypeNameForFieldType(FD::TYPE_FLOAT));
2494  EXPECT_STREQ("int64", GetTypeNameForFieldType(FD::TYPE_INT64));
2495  EXPECT_STREQ("uint64", GetTypeNameForFieldType(FD::TYPE_UINT64));
2496  EXPECT_STREQ("int32", GetTypeNameForFieldType(FD::TYPE_INT32));
2497  EXPECT_STREQ("fixed64", GetTypeNameForFieldType(FD::TYPE_FIXED64));
2498  EXPECT_STREQ("fixed32", GetTypeNameForFieldType(FD::TYPE_FIXED32));
2499  EXPECT_STREQ("bool", GetTypeNameForFieldType(FD::TYPE_BOOL));
2500  EXPECT_STREQ("string", GetTypeNameForFieldType(FD::TYPE_STRING));
2501  EXPECT_STREQ("group", GetTypeNameForFieldType(FD::TYPE_GROUP));
2502  EXPECT_STREQ("message", GetTypeNameForFieldType(FD::TYPE_MESSAGE));
2503  EXPECT_STREQ("bytes", GetTypeNameForFieldType(FD::TYPE_BYTES));
2504  EXPECT_STREQ("uint32", GetTypeNameForFieldType(FD::TYPE_UINT32));
2505  EXPECT_STREQ("enum", GetTypeNameForFieldType(FD::TYPE_ENUM));
2506  EXPECT_STREQ("sfixed32", GetTypeNameForFieldType(FD::TYPE_SFIXED32));
2507  EXPECT_STREQ("sfixed64", GetTypeNameForFieldType(FD::TYPE_SFIXED64));
2508  EXPECT_STREQ("sint32", GetTypeNameForFieldType(FD::TYPE_SINT32));
2509  EXPECT_STREQ("sint64", GetTypeNameForFieldType(FD::TYPE_SINT64));
2510 }
2511 
2512 TEST_F(MiscTest, StaticTypeNames) {
2513  // Test that correct type names are returned.
2514 
2515  typedef FieldDescriptor FD; // avoid ugly line wrapping
2516 
2517  EXPECT_STREQ("double", FD::TypeName(FD::TYPE_DOUBLE));
2518  EXPECT_STREQ("float", FD::TypeName(FD::TYPE_FLOAT));
2519  EXPECT_STREQ("int64", FD::TypeName(FD::TYPE_INT64));
2520  EXPECT_STREQ("uint64", FD::TypeName(FD::TYPE_UINT64));
2521  EXPECT_STREQ("int32", FD::TypeName(FD::TYPE_INT32));
2522  EXPECT_STREQ("fixed64", FD::TypeName(FD::TYPE_FIXED64));
2523  EXPECT_STREQ("fixed32", FD::TypeName(FD::TYPE_FIXED32));
2524  EXPECT_STREQ("bool", FD::TypeName(FD::TYPE_BOOL));
2525  EXPECT_STREQ("string", FD::TypeName(FD::TYPE_STRING));
2526  EXPECT_STREQ("group", FD::TypeName(FD::TYPE_GROUP));
2527  EXPECT_STREQ("message", FD::TypeName(FD::TYPE_MESSAGE));
2528  EXPECT_STREQ("bytes", FD::TypeName(FD::TYPE_BYTES));
2529  EXPECT_STREQ("uint32", FD::TypeName(FD::TYPE_UINT32));
2530  EXPECT_STREQ("enum", FD::TypeName(FD::TYPE_ENUM));
2531  EXPECT_STREQ("sfixed32", FD::TypeName(FD::TYPE_SFIXED32));
2532  EXPECT_STREQ("sfixed64", FD::TypeName(FD::TYPE_SFIXED64));
2533  EXPECT_STREQ("sint32", FD::TypeName(FD::TYPE_SINT32));
2534  EXPECT_STREQ("sint64", FD::TypeName(FD::TYPE_SINT64));
2535 }
2536 
2537 TEST_F(MiscTest, CppTypes) {
2538  // Test that CPP types are assigned correctly.
2539 
2540  typedef FieldDescriptor FD; // avoid ugly line wrapping
2541 
2542  EXPECT_EQ(FD::CPPTYPE_DOUBLE, GetCppTypeForFieldType(FD::TYPE_DOUBLE));
2543  EXPECT_EQ(FD::CPPTYPE_FLOAT, GetCppTypeForFieldType(FD::TYPE_FLOAT));
2544  EXPECT_EQ(FD::CPPTYPE_INT64, GetCppTypeForFieldType(FD::TYPE_INT64));
2545  EXPECT_EQ(FD::CPPTYPE_UINT64, GetCppTypeForFieldType(FD::TYPE_UINT64));
2546  EXPECT_EQ(FD::CPPTYPE_INT32, GetCppTypeForFieldType(FD::TYPE_INT32));
2547  EXPECT_EQ(FD::CPPTYPE_UINT64, GetCppTypeForFieldType(FD::TYPE_FIXED64));
2548  EXPECT_EQ(FD::CPPTYPE_UINT32, GetCppTypeForFieldType(FD::TYPE_FIXED32));
2549  EXPECT_EQ(FD::CPPTYPE_BOOL, GetCppTypeForFieldType(FD::TYPE_BOOL));
2550  EXPECT_EQ(FD::CPPTYPE_STRING, GetCppTypeForFieldType(FD::TYPE_STRING));
2551  EXPECT_EQ(FD::CPPTYPE_MESSAGE, GetCppTypeForFieldType(FD::TYPE_GROUP));
2552  EXPECT_EQ(FD::CPPTYPE_MESSAGE, GetCppTypeForFieldType(FD::TYPE_MESSAGE));
2553  EXPECT_EQ(FD::CPPTYPE_STRING, GetCppTypeForFieldType(FD::TYPE_BYTES));
2554  EXPECT_EQ(FD::CPPTYPE_UINT32, GetCppTypeForFieldType(FD::TYPE_UINT32));
2555  EXPECT_EQ(FD::CPPTYPE_ENUM, GetCppTypeForFieldType(FD::TYPE_ENUM));
2556  EXPECT_EQ(FD::CPPTYPE_INT32, GetCppTypeForFieldType(FD::TYPE_SFIXED32));
2557  EXPECT_EQ(FD::CPPTYPE_INT64, GetCppTypeForFieldType(FD::TYPE_SFIXED64));
2558  EXPECT_EQ(FD::CPPTYPE_INT32, GetCppTypeForFieldType(FD::TYPE_SINT32));
2559  EXPECT_EQ(FD::CPPTYPE_INT64, GetCppTypeForFieldType(FD::TYPE_SINT64));
2560 }
2561 
2562 TEST_F(MiscTest, CppTypeNames) {
2563  // Test that correct CPP type names are returned.
2564 
2565  typedef FieldDescriptor FD; // avoid ugly line wrapping
2566 
2567  EXPECT_STREQ("double", GetCppTypeNameForFieldType(FD::TYPE_DOUBLE));
2568  EXPECT_STREQ("float", GetCppTypeNameForFieldType(FD::TYPE_FLOAT));
2569  EXPECT_STREQ("int64", GetCppTypeNameForFieldType(FD::TYPE_INT64));
2570  EXPECT_STREQ("uint64", GetCppTypeNameForFieldType(FD::TYPE_UINT64));
2571  EXPECT_STREQ("int32", GetCppTypeNameForFieldType(FD::TYPE_INT32));
2572  EXPECT_STREQ("uint64", GetCppTypeNameForFieldType(FD::TYPE_FIXED64));
2573  EXPECT_STREQ("uint32", GetCppTypeNameForFieldType(FD::TYPE_FIXED32));
2574  EXPECT_STREQ("bool", GetCppTypeNameForFieldType(FD::TYPE_BOOL));
2575  EXPECT_STREQ("string", GetCppTypeNameForFieldType(FD::TYPE_STRING));
2576  EXPECT_STREQ("message", GetCppTypeNameForFieldType(FD::TYPE_GROUP));
2577  EXPECT_STREQ("message", GetCppTypeNameForFieldType(FD::TYPE_MESSAGE));
2578  EXPECT_STREQ("string", GetCppTypeNameForFieldType(FD::TYPE_BYTES));
2579  EXPECT_STREQ("uint32", GetCppTypeNameForFieldType(FD::TYPE_UINT32));
2580  EXPECT_STREQ("enum", GetCppTypeNameForFieldType(FD::TYPE_ENUM));
2581  EXPECT_STREQ("int32", GetCppTypeNameForFieldType(FD::TYPE_SFIXED32));
2582  EXPECT_STREQ("int64", GetCppTypeNameForFieldType(FD::TYPE_SFIXED64));
2583  EXPECT_STREQ("int32", GetCppTypeNameForFieldType(FD::TYPE_SINT32));
2584  EXPECT_STREQ("int64", GetCppTypeNameForFieldType(FD::TYPE_SINT64));
2585 }
2586 
2587 TEST_F(MiscTest, StaticCppTypeNames) {
2588  // Test that correct CPP type names are returned.
2589 
2590  typedef FieldDescriptor FD; // avoid ugly line wrapping
2591 
2592  EXPECT_STREQ("int32", FD::CppTypeName(FD::CPPTYPE_INT32));
2593  EXPECT_STREQ("int64", FD::CppTypeName(FD::CPPTYPE_INT64));
2594  EXPECT_STREQ("uint32", FD::CppTypeName(FD::CPPTYPE_UINT32));
2595  EXPECT_STREQ("uint64", FD::CppTypeName(FD::CPPTYPE_UINT64));
2596  EXPECT_STREQ("double", FD::CppTypeName(FD::CPPTYPE_DOUBLE));
2597  EXPECT_STREQ("float", FD::CppTypeName(FD::CPPTYPE_FLOAT));
2598  EXPECT_STREQ("bool", FD::CppTypeName(FD::CPPTYPE_BOOL));
2599  EXPECT_STREQ("enum", FD::CppTypeName(FD::CPPTYPE_ENUM));
2600  EXPECT_STREQ("string", FD::CppTypeName(FD::CPPTYPE_STRING));
2601  EXPECT_STREQ("message", FD::CppTypeName(FD::CPPTYPE_MESSAGE));
2602 }
2603 
2604 TEST_F(MiscTest, MessageType) {
2605  // Test that message_type() is nullptr for non-aggregate fields
2606 
2607  typedef FieldDescriptor FD; // avoid ugly line wrapping
2608 
2609  EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_DOUBLE));
2610  EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_FLOAT));
2611  EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_INT64));
2612  EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_UINT64));
2613  EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_INT32));
2614  EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_FIXED64));
2615  EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_FIXED32));
2616  EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_BOOL));
2617  EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_STRING));
2618  EXPECT_TRUE(nullptr != GetMessageDescriptorForFieldType(FD::TYPE_GROUP));
2619  EXPECT_TRUE(nullptr != GetMessageDescriptorForFieldType(FD::TYPE_MESSAGE));
2620  EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_BYTES));
2621  EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_UINT32));
2622  EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_ENUM));
2623  EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_SFIXED32));
2624  EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_SFIXED64));
2625  EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_SINT32));
2626  EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_SINT64));
2627 }
2628 
2629 TEST_F(MiscTest, EnumType) {
2630  // Test that enum_type() is nullptr for non-enum fields
2631 
2632  typedef FieldDescriptor FD; // avoid ugly line wrapping
2633 
2634  EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_DOUBLE));
2635  EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_FLOAT));
2636  EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_INT64));
2637  EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_UINT64));
2638  EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_INT32));
2639  EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_FIXED64));
2640  EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_FIXED32));
2641  EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_BOOL));
2642  EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_STRING));
2643  EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_GROUP));
2644  EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_MESSAGE));
2645  EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_BYTES));
2646  EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_UINT32));
2647  EXPECT_TRUE(nullptr != GetEnumDescriptorForFieldType(FD::TYPE_ENUM));
2648  EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_SFIXED32));
2649  EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_SFIXED64));
2650  EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_SINT32));
2651  EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_SINT64));
2652 }
2653 
2654 TEST_F(MiscTest, DefaultValues) {
2655  // Test that setting default values works.
2656  FileDescriptorProto file_proto;
2657  file_proto.set_name("foo.proto");
2658 
2659  EnumDescriptorProto* enum_type_proto = AddEnum(&file_proto, "DummyEnum");
2660  AddEnumValue(enum_type_proto, "A", 1);
2661  AddEnumValue(enum_type_proto, "B", 2);
2662 
2663  DescriptorProto* message_proto = AddMessage(&file_proto, "TestMessage");
2664 
2665  typedef FieldDescriptorProto FD; // avoid ugly line wrapping
2666  const FD::Label label = FD::LABEL_OPTIONAL;
2667 
2668  // Create fields of every CPP type with default values.
2669  AddField(message_proto, "int32", 1, label, FD::TYPE_INT32)
2670  ->set_default_value("-1");
2671  AddField(message_proto, "int64", 2, label, FD::TYPE_INT64)
2672  ->set_default_value("-1000000000000");
2673  AddField(message_proto, "uint32", 3, label, FD::TYPE_UINT32)
2674  ->set_default_value("42");
2675  AddField(message_proto, "uint64", 4, label, FD::TYPE_UINT64)
2676  ->set_default_value("2000000000000");
2677  AddField(message_proto, "float", 5, label, FD::TYPE_FLOAT)
2678  ->set_default_value("4.5");
2679  AddField(message_proto, "double", 6, label, FD::TYPE_DOUBLE)
2680  ->set_default_value("10e100");
2681  AddField(message_proto, "bool", 7, label, FD::TYPE_BOOL)
2682  ->set_default_value("true");
2683  AddField(message_proto, "string", 8, label, FD::TYPE_STRING)
2684  ->set_default_value("hello");
2685  AddField(message_proto, "data", 9, label, FD::TYPE_BYTES)
2686  ->set_default_value("\\001\\002\\003");
2687 
2688  FieldDescriptorProto* enum_field =
2689  AddField(message_proto, "enum", 10, label, FD::TYPE_ENUM);
2690  enum_field->set_type_name("DummyEnum");
2691  enum_field->set_default_value("B");
2692 
2693  // Strings are allowed to have empty defaults. (At one point, due to
2694  // a bug, empty defaults for strings were rejected. Oops.)
2695  AddField(message_proto, "empty_string", 11, label, FD::TYPE_STRING)
2696  ->set_default_value("");
2697 
2698  // Add a second set of fields with implicit default values.
2699  AddField(message_proto, "implicit_int32", 21, label, FD::TYPE_INT32);
2700  AddField(message_proto, "implicit_int64", 22, label, FD::TYPE_INT64);
2701  AddField(message_proto, "implicit_uint32", 23, label, FD::TYPE_UINT32);
2702  AddField(message_proto, "implicit_uint64", 24, label, FD::TYPE_UINT64);
2703  AddField(message_proto, "implicit_float", 25, label, FD::TYPE_FLOAT);
2704  AddField(message_proto, "implicit_double", 26, label, FD::TYPE_DOUBLE);
2705  AddField(message_proto, "implicit_bool", 27, label, FD::TYPE_BOOL);
2706  AddField(message_proto, "implicit_string", 28, label, FD::TYPE_STRING);
2707  AddField(message_proto, "implicit_data", 29, label, FD::TYPE_BYTES);
2708  AddField(message_proto, "implicit_enum", 30, label, FD::TYPE_ENUM)
2709  ->set_type_name("DummyEnum");
2710 
2711  // Build it.
2713  const FileDescriptor* file = pool.BuildFile(file_proto);
2714  ASSERT_TRUE(file != nullptr);
2715 
2716  ASSERT_EQ(1, file->enum_type_count());
2717  const EnumDescriptor* enum_type = file->enum_type(0);
2718  ASSERT_EQ(2, enum_type->value_count());
2719  const EnumValueDescriptor* enum_value_a = enum_type->value(0);
2720  const EnumValueDescriptor* enum_value_b = enum_type->value(1);
2721 
2722  ASSERT_EQ(1, file->message_type_count());
2723  const Descriptor* message = file->message_type(0);
2724 
2725  ASSERT_EQ(21, message->field_count());
2726 
2727  // Check the default values.
2728  ASSERT_TRUE(message->field(0)->has_default_value());
2729  ASSERT_TRUE(message->field(1)->has_default_value());
2730  ASSERT_TRUE(message->field(2)->has_default_value());
2731  ASSERT_TRUE(message->field(3)->has_default_value());
2732  ASSERT_TRUE(message->field(4)->has_default_value());
2733  ASSERT_TRUE(message->field(5)->has_default_value());
2734  ASSERT_TRUE(message->field(6)->has_default_value());
2735  ASSERT_TRUE(message->field(7)->has_default_value());
2736  ASSERT_TRUE(message->field(8)->has_default_value());
2737  ASSERT_TRUE(message->field(9)->has_default_value());
2738  ASSERT_TRUE(message->field(10)->has_default_value());
2739 
2740  EXPECT_EQ(-1, message->field(0)->default_value_int32());
2741  EXPECT_EQ(int64{-1000000000000}, message->field(1)->default_value_int64());
2742  EXPECT_EQ(42, message->field(2)->default_value_uint32());
2743  EXPECT_EQ(uint64{2000000000000}, message->field(3)->default_value_uint64());
2744  EXPECT_EQ(4.5, message->field(4)->default_value_float());
2745  EXPECT_EQ(10e100, message->field(5)->default_value_double());
2746  EXPECT_TRUE(message->field(6)->default_value_bool());
2747  EXPECT_EQ("hello", message->field(7)->default_value_string());
2748  EXPECT_EQ("\001\002\003", message->field(8)->default_value_string());
2749  EXPECT_EQ(enum_value_b, message->field(9)->default_value_enum());
2750  EXPECT_EQ("", message->field(10)->default_value_string());
2751 
2752  ASSERT_FALSE(message->field(11)->has_default_value());
2753  ASSERT_FALSE(message->field(12)->has_default_value());
2754  ASSERT_FALSE(message->field(13)->has_default_value());
2755  ASSERT_FALSE(message->field(14)->has_default_value());
2756  ASSERT_FALSE(message->field(15)->has_default_value());
2757  ASSERT_FALSE(message->field(16)->has_default_value());
2758  ASSERT_FALSE(message->field(17)->has_default_value());
2759  ASSERT_FALSE(message->field(18)->has_default_value());
2760  ASSERT_FALSE(message->field(19)->has_default_value());
2761  ASSERT_FALSE(message->field(20)->has_default_value());
2762 
2763  EXPECT_EQ(0, message->field(11)->default_value_int32());
2764  EXPECT_EQ(0, message->field(12)->default_value_int64());
2765  EXPECT_EQ(0, message->field(13)->default_value_uint32());
2766  EXPECT_EQ(0, message->field(14)->default_value_uint64());
2767  EXPECT_EQ(0.0f, message->field(15)->default_value_float());
2768  EXPECT_EQ(0.0, message->field(16)->default_value_double());
2769  EXPECT_FALSE(message->field(17)->default_value_bool());
2770  EXPECT_EQ("", message->field(18)->default_value_string());
2771  EXPECT_EQ("", message->field(19)->default_value_string());
2772  EXPECT_EQ(enum_value_a, message->field(20)->default_value_enum());
2773 }
2774 
2775 TEST_F(MiscTest, FieldOptions) {
2776  // Try setting field options.
2777 
2778  FileDescriptorProto file_proto;
2779  file_proto.set_name("foo.proto");
2780 
2781  DescriptorProto* message_proto = AddMessage(&file_proto, "TestMessage");
2782  AddField(message_proto, "foo", 1, FieldDescriptorProto::LABEL_OPTIONAL,
2784  FieldDescriptorProto* bar_proto =
2785  AddField(message_proto, "bar", 2, FieldDescriptorProto::LABEL_OPTIONAL,
2787 
2788  FieldOptions* options = bar_proto->mutable_options();
2789  options->set_ctype(FieldOptions::CORD);
2790 
2791  // Build the descriptors and get the pointers.
2793  const FileDescriptor* file = pool.BuildFile(file_proto);
2794  ASSERT_TRUE(file != nullptr);
2795 
2796  ASSERT_EQ(1, file->message_type_count());
2797  const Descriptor* message = file->message_type(0);
2798 
2799  ASSERT_EQ(2, message->field_count());
2800  const FieldDescriptor* foo = message->field(0);
2801  const FieldDescriptor* bar = message->field(1);
2802 
2803  // "foo" had no options set, so it should return the default options.
2804  EXPECT_EQ(&FieldOptions::default_instance(), &foo->options());
2805 
2806  // "bar" had options set.
2808  EXPECT_TRUE(bar->options().has_ctype());
2809  EXPECT_EQ(FieldOptions::CORD, bar->options().ctype());
2810 }
2811 
2812 // ===================================================================
2814 
2815 class AllowUnknownDependenciesTest
2816  : public testing::TestWithParam<
2817  std::tuple<DescriptorPoolMode, const char*>> {
2818  protected:
2819  DescriptorPoolMode mode() { return std::get<0>(GetParam()); }
2820  const char* syntax() { return std::get<1>(GetParam()); }
2821 
2822  void SetUp() override {
2823  FileDescriptorProto foo_proto, bar_proto;
2824 
2825  switch (mode()) {
2826  case NO_DATABASE:
2827  pool_.reset(new DescriptorPool);
2828  break;
2829  case FALLBACK_DATABASE:
2830  pool_.reset(new DescriptorPool(&db_));
2831  break;
2832  }
2833 
2834  pool_->AllowUnknownDependencies();
2835 
2837  "name: 'foo.proto'"
2838  "dependency: 'bar.proto'"
2839  "dependency: 'baz.proto'"
2840  "message_type {"
2841  " name: 'Foo'"
2842  " field { name:'bar' number:1 label:LABEL_OPTIONAL type_name:'Bar' }"
2843  " field { name:'baz' number:2 label:LABEL_OPTIONAL type_name:'Baz' }"
2844  " field { name:'qux' number:3 label:LABEL_OPTIONAL"
2845  " type_name: '.corge.Qux'"
2846  " type: TYPE_ENUM"
2847  " options {"
2848  " uninterpreted_option {"
2849  " name {"
2850  " name_part: 'grault'"
2851  " is_extension: true"
2852  " }"
2853  " positive_int_value: 1234"
2854  " }"
2855  " }"
2856  " }"
2857  "}",
2858  &foo_proto));
2859  foo_proto.set_syntax(syntax());
2860 
2861  ASSERT_TRUE(
2862  TextFormat::ParseFromString("name: 'bar.proto'"
2863  "message_type { name: 'Bar' }",
2864  &bar_proto));
2865  bar_proto.set_syntax(syntax());
2866 
2867  // Collect pointers to stuff.
2868  bar_file_ = BuildFile(bar_proto);
2869  ASSERT_TRUE(bar_file_ != nullptr);
2870 
2873 
2874  foo_file_ = BuildFile(foo_proto);
2875  ASSERT_TRUE(foo_file_ != nullptr);
2876 
2879 
2881  bar_field_ = foo_type_->field(0);
2882  baz_field_ = foo_type_->field(1);
2883  qux_field_ = foo_type_->field(2);
2884  }
2885 
2887  switch (mode()) {
2888  case NO_DATABASE:
2889  return pool_->BuildFile(proto);
2890  break;
2891  case FALLBACK_DATABASE: {
2892  EXPECT_TRUE(db_.Add(proto));
2893  return pool_->FindFileByName(proto.name());
2894  }
2895  }
2896  GOOGLE_LOG(FATAL) << "Can't get here.";
2897  return nullptr;
2898  }
2899 
2900  const FileDescriptor* bar_file_;
2901  const Descriptor* bar_type_;
2902  const FileDescriptor* foo_file_;
2903  const Descriptor* foo_type_;
2904  const FieldDescriptor* bar_field_;
2905  const FieldDescriptor* baz_field_;
2906  const FieldDescriptor* qux_field_;
2907 
2908  SimpleDescriptorDatabase db_; // used if in FALLBACK_DATABASE mode.
2909  std::unique_ptr<DescriptorPool> pool_;
2910 };
2911 
2912 TEST_P(AllowUnknownDependenciesTest, PlaceholderFile) {
2913  ASSERT_EQ(2, foo_file_->dependency_count());
2914  EXPECT_EQ(bar_file_, foo_file_->dependency(0));
2915  EXPECT_FALSE(bar_file_->is_placeholder());
2916 
2917  const FileDescriptor* baz_file = foo_file_->dependency(1);
2918  EXPECT_EQ("baz.proto", baz_file->name());
2919  EXPECT_EQ(0, baz_file->message_type_count());
2920  EXPECT_TRUE(baz_file->is_placeholder());
2921 
2922  // Placeholder files should not be findable.
2923  EXPECT_EQ(bar_file_, pool_->FindFileByName(bar_file_->name()));
2924  EXPECT_TRUE(pool_->FindFileByName(baz_file->name()) == nullptr);
2925 
2926  // Copy*To should not crash for placeholder files.
2927  FileDescriptorProto baz_file_proto;
2928  baz_file->CopyTo(&baz_file_proto);
2929  baz_file->CopySourceCodeInfoTo(&baz_file_proto);
2930  EXPECT_FALSE(baz_file_proto.has_source_code_info());
2931 }
2932 
2933 TEST_P(AllowUnknownDependenciesTest, PlaceholderTypes) {
2934  ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, bar_field_->type());
2935  EXPECT_EQ(bar_type_, bar_field_->message_type());
2936  EXPECT_FALSE(bar_type_->is_placeholder());
2937 
2938  ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, baz_field_->type());
2939  const Descriptor* baz_type = baz_field_->message_type();
2940  EXPECT_EQ("Baz", baz_type->name());
2941  EXPECT_EQ("Baz", baz_type->full_name());
2942  EXPECT_EQ(0, baz_type->extension_range_count());
2943  EXPECT_TRUE(baz_type->is_placeholder());
2944 
2945  ASSERT_EQ(FieldDescriptor::TYPE_ENUM, qux_field_->type());
2946  const EnumDescriptor* qux_type = qux_field_->enum_type();
2947  EXPECT_EQ("Qux", qux_type->name());
2948  EXPECT_EQ("corge.Qux", qux_type->full_name());
2949  EXPECT_TRUE(qux_type->is_placeholder());
2950  // Placeholder enum values should not be findable.
2951  EXPECT_EQ(qux_type->FindValueByNumber(0), nullptr);
2952 
2953  // Placeholder types should not be findable.
2954  EXPECT_EQ(bar_type_, pool_->FindMessageTypeByName(bar_type_->full_name()));
2955  EXPECT_TRUE(pool_->FindMessageTypeByName(baz_type->full_name()) == nullptr);
2956  EXPECT_TRUE(pool_->FindEnumTypeByName(qux_type->full_name()) == nullptr);
2957 }
2958 
2959 TEST_P(AllowUnknownDependenciesTest, CopyTo) {
2960  // FieldDescriptor::CopyTo() should write non-fully-qualified type names
2961  // for placeholder types which were not originally fully-qualified.
2962  FieldDescriptorProto proto;
2963 
2964  // Bar is not a placeholder, so it is fully-qualified.
2965  bar_field_->CopyTo(&proto);
2966  EXPECT_EQ(".Bar", proto.type_name());
2968 
2969  // Baz is an unqualified placeholder.
2970  proto.Clear();
2971  baz_field_->CopyTo(&proto);
2972  EXPECT_EQ("Baz", proto.type_name());
2973  EXPECT_FALSE(proto.has_type());
2974 
2975  // Qux is a fully-qualified placeholder.
2976  proto.Clear();
2977  qux_field_->CopyTo(&proto);
2978  EXPECT_EQ(".corge.Qux", proto.type_name());
2980 }
2981 
2982 TEST_P(AllowUnknownDependenciesTest, CustomOptions) {
2983  // Qux should still have the uninterpreted option attached.
2984  ASSERT_EQ(1, qux_field_->options().uninterpreted_option_size());
2985  const UninterpretedOption& option =
2986  qux_field_->options().uninterpreted_option(0);
2987  ASSERT_EQ(1, option.name_size());
2988  EXPECT_EQ("grault", option.name(0).name_part());
2989 }
2990 
2991 TEST_P(AllowUnknownDependenciesTest, UnknownExtendee) {
2992  // Test that we can extend an unknown type. This is slightly tricky because
2993  // it means that the placeholder type must have an extension range.
2994 
2995  FileDescriptorProto extension_proto;
2996 
2998  "name: 'extension.proto'"
2999  "extension { extendee: 'UnknownType' name:'some_extension' number:123"
3000  " label:LABEL_OPTIONAL type:TYPE_INT32 }",
3001  &extension_proto));
3002  const FileDescriptor* file = BuildFile(extension_proto);
3003 
3004  ASSERT_TRUE(file != nullptr);
3005 
3006  ASSERT_EQ(1, file->extension_count());
3007  const Descriptor* extendee = file->extension(0)->containing_type();
3008  EXPECT_EQ("UnknownType", extendee->name());
3009  EXPECT_TRUE(extendee->is_placeholder());
3010  ASSERT_EQ(1, extendee->extension_range_count());
3011  EXPECT_EQ(1, extendee->extension_range(0)->start);
3012  EXPECT_EQ(FieldDescriptor::kMaxNumber + 1, extendee->extension_range(0)->end);
3013 }
3014 
3015 TEST_P(AllowUnknownDependenciesTest, CustomOption) {
3016  // Test that we can use a custom option without having parsed
3017  // descriptor.proto.
3018 
3019  FileDescriptorProto option_proto;
3020 
3022  "name: \"unknown_custom_options.proto\" "
3023  "dependency: \"google/protobuf/descriptor.proto\" "
3024  "extension { "
3025  " extendee: \"google.protobuf.FileOptions\" "
3026  " name: \"some_option\" "
3027  " number: 123456 "
3028  " label: LABEL_OPTIONAL "
3029  " type: TYPE_INT32 "
3030  "} "
3031  "options { "
3032  " uninterpreted_option { "
3033  " name { "
3034  " name_part: \"some_option\" "
3035  " is_extension: true "
3036  " } "
3037  " positive_int_value: 1234 "
3038  " } "
3039  " uninterpreted_option { "
3040  " name { "
3041  " name_part: \"unknown_option\" "
3042  " is_extension: true "
3043  " } "
3044  " positive_int_value: 1234 "
3045  " } "
3046  " uninterpreted_option { "
3047  " name { "
3048  " name_part: \"optimize_for\" "
3049  " is_extension: false "
3050  " } "
3051  " identifier_value: \"SPEED\" "
3052  " } "
3053  "}",
3054  &option_proto));
3055 
3056  const FileDescriptor* file = BuildFile(option_proto);
3057  ASSERT_TRUE(file != nullptr);
3058 
3059  // Verify that no extension options were set, but they were left as
3060  // uninterpreted_options.
3061  std::vector<const FieldDescriptor*> fields;
3062  file->options().GetReflection()->ListFields(file->options(), &fields);
3063  ASSERT_EQ(2, fields.size());
3064  EXPECT_TRUE(file->options().has_optimize_for());
3065  EXPECT_EQ(2, file->options().uninterpreted_option_size());
3066 }
3067 
3068 TEST_P(AllowUnknownDependenciesTest,
3069  UndeclaredDependencyTriggersBuildOfDependency) {
3070  // Crazy case: suppose foo.proto refers to a symbol without declaring the
3071  // dependency that finds it. In the event that the pool is backed by a
3072  // DescriptorDatabase, the pool will attempt to find the symbol in the
3073  // database. If successful, it will build the undeclared dependency to verify
3074  // that the file does indeed contain the symbol. If that file fails to build,
3075  // then its descriptors must be rolled back. However, we still want foo.proto
3076  // to build successfully, since we are allowing unknown dependencies.
3077 
3078  FileDescriptorProto undeclared_dep_proto;
3079  // We make this file fail to build by giving it two fields with tag 1.
3081  "name: \"invalid_file_as_undeclared_dep.proto\" "
3082  "package: \"undeclared\" "
3083  "message_type: { "
3084  " name: \"Quux\" "
3085  " field { "
3086  " name:'qux' number:1 label:LABEL_OPTIONAL type: TYPE_INT32 "
3087  " }"
3088  " field { "
3089  " name:'quux' number:1 label:LABEL_OPTIONAL type: TYPE_INT64 "
3090  " }"
3091  "}",
3092  &undeclared_dep_proto));
3093  // We can't use the BuildFile() helper because we don't actually want to build
3094  // it into the descriptor pool in the fallback database case: it just needs to
3095  // be sitting in the database so that it gets built during the building of
3096  // test.proto below.
3097  switch (mode()) {
3098  case NO_DATABASE: {
3099  ASSERT_TRUE(pool_->BuildFile(undeclared_dep_proto) == nullptr);
3100  break;
3101  }
3102  case FALLBACK_DATABASE: {
3103  ASSERT_TRUE(db_.Add(undeclared_dep_proto));
3104  }
3105  }
3106 
3107  FileDescriptorProto test_proto;
3109  "name: \"test.proto\" "
3110  "message_type: { "
3111  " name: \"Corge\" "
3112  " field { "
3113  " name:'quux' number:1 label: LABEL_OPTIONAL "
3114  " type_name:'undeclared.Quux' type: TYPE_MESSAGE "
3115  " }"
3116  "}",
3117  &test_proto));
3118 
3119  const FileDescriptor* file = BuildFile(test_proto);
3120  ASSERT_TRUE(file != nullptr);
3121  GOOGLE_LOG(INFO) << file->DebugString();
3122 
3123  EXPECT_EQ(0, file->dependency_count());
3124  ASSERT_EQ(1, file->message_type_count());
3125  const Descriptor* corge_desc = file->message_type(0);
3126  ASSERT_EQ("Corge", corge_desc->name());
3127  ASSERT_EQ(1, corge_desc->field_count());
3128  EXPECT_FALSE(corge_desc->is_placeholder());
3129 
3130  const FieldDescriptor* quux_field = corge_desc->field(0);
3131  ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, quux_field->type());
3132  ASSERT_EQ("Quux", quux_field->message_type()->name());
3133  ASSERT_EQ("undeclared.Quux", quux_field->message_type()->full_name());
3134  EXPECT_TRUE(quux_field->message_type()->is_placeholder());
3135  // The place holder type should not be findable.
3136  ASSERT_TRUE(pool_->FindMessageTypeByName("undeclared.Quux") == nullptr);
3137 }
3138 
3139 INSTANTIATE_TEST_SUITE_P(DatabaseSource, AllowUnknownDependenciesTest,
3142  testing::Values("proto2", "proto3")));
3143 
3144 // ===================================================================
3145 
3146 TEST(CustomOptions, OptionLocations) {
3147  const Descriptor* message =
3149  const FileDescriptor* file = message->file();
3150  const FieldDescriptor* field = message->FindFieldByName("field1");
3151  const OneofDescriptor* oneof = message->FindOneofByName("AnOneof");
3152  const FieldDescriptor* map_field = message->FindFieldByName("map_field");
3153  const EnumDescriptor* enm = message->FindEnumTypeByName("AnEnum");
3154  // TODO(benjy): Support EnumValue options, once the compiler does.
3155  const ServiceDescriptor* service =
3156  file->FindServiceByName("TestServiceWithCustomOptions");
3157  const MethodDescriptor* method = service->FindMethodByName("Foo");
3158 
3159  EXPECT_EQ(int64{9876543210},
3160  file->options().GetExtension(protobuf_unittest::file_opt1));
3161  EXPECT_EQ(-56,
3162  message->options().GetExtension(protobuf_unittest::message_opt1));
3163  EXPECT_EQ(int64{8765432109},
3164  field->options().GetExtension(protobuf_unittest::field_opt1));
3165  EXPECT_EQ(42, // Check that we get the default for an option we don't set.
3166  field->options().GetExtension(protobuf_unittest::field_opt2));
3167  EXPECT_EQ(-99, oneof->options().GetExtension(protobuf_unittest::oneof_opt1));
3168  EXPECT_EQ(int64_t{12345},
3169  map_field->options().GetExtension(protobuf_unittest::field_opt1));
3170  EXPECT_EQ(-789, enm->options().GetExtension(protobuf_unittest::enum_opt1));
3171  EXPECT_EQ(123, enm->value(1)->options().GetExtension(
3172  protobuf_unittest::enum_value_opt1));
3173  EXPECT_EQ(int64{-9876543210},
3174  service->options().GetExtension(protobuf_unittest::service_opt1));
3175  EXPECT_EQ(protobuf_unittest::METHODOPT1_VAL2,
3176  method->options().GetExtension(protobuf_unittest::method_opt1));
3177 
3178  // See that the regular options went through unscathed.
3179  EXPECT_TRUE(message->options().has_message_set_wire_format());
3180  EXPECT_EQ(FieldOptions::CORD, field->options().ctype());
3181 }
3182 
3183 TEST(CustomOptions, OptionTypes) {
3184  const MessageOptions* options = nullptr;
3185 
3192 
3193  options =
3195  EXPECT_EQ(false, options->GetExtension(protobuf_unittest::bool_opt));
3196  EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::int32_opt));
3197  EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::int64_opt));
3198  EXPECT_EQ(0, options->GetExtension(protobuf_unittest::uint32_opt));
3199  EXPECT_EQ(0, options->GetExtension(protobuf_unittest::uint64_opt));
3200  EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::sint32_opt));
3201  EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::sint64_opt));
3202  EXPECT_EQ(0, options->GetExtension(protobuf_unittest::fixed32_opt));
3203  EXPECT_EQ(0, options->GetExtension(protobuf_unittest::fixed64_opt));
3204  EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::sfixed32_opt));
3205  EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::sfixed64_opt));
3206 
3207  options =
3209  EXPECT_EQ(true, options->GetExtension(protobuf_unittest::bool_opt));
3210  EXPECT_EQ(kint32max, options->GetExtension(protobuf_unittest::int32_opt));
3211  EXPECT_EQ(kint64max, options->GetExtension(protobuf_unittest::int64_opt));
3212  EXPECT_EQ(kuint32max, options->GetExtension(protobuf_unittest::uint32_opt));
3213  EXPECT_EQ(kuint64max, options->GetExtension(protobuf_unittest::uint64_opt));
3214  EXPECT_EQ(kint32max, options->GetExtension(protobuf_unittest::sint32_opt));
3215  EXPECT_EQ(kint64max, options->GetExtension(protobuf_unittest::sint64_opt));
3216  EXPECT_EQ(kuint32max, options->GetExtension(protobuf_unittest::fixed32_opt));
3217  EXPECT_EQ(kuint64max, options->GetExtension(protobuf_unittest::fixed64_opt));
3218  EXPECT_EQ(kint32max, options->GetExtension(protobuf_unittest::sfixed32_opt));
3219  EXPECT_EQ(kint64max, options->GetExtension(protobuf_unittest::sfixed64_opt));
3220 
3222  EXPECT_EQ(-100, options->GetExtension(protobuf_unittest::int32_opt));
3223  EXPECT_FLOAT_EQ(12.3456789,
3224  options->GetExtension(protobuf_unittest::float_opt));
3225  EXPECT_DOUBLE_EQ(1.234567890123456789,
3226  options->GetExtension(protobuf_unittest::double_opt));
3227  EXPECT_EQ("Hello, \"World\"",
3228  options->GetExtension(protobuf_unittest::string_opt));
3229 
3230  EXPECT_EQ(std::string("Hello\0World", 11),
3231  options->GetExtension(protobuf_unittest::bytes_opt));
3232 
3233  EXPECT_EQ(protobuf_unittest::DummyMessageContainingEnum::TEST_OPTION_ENUM_TYPE2,
3234  options->GetExtension(protobuf_unittest::enum_opt));
3235 
3236  options =
3238  EXPECT_FLOAT_EQ(12, options->GetExtension(protobuf_unittest::float_opt));
3239  EXPECT_DOUBLE_EQ(154, options->GetExtension(protobuf_unittest::double_opt));
3240 
3241  options =
3243  EXPECT_FLOAT_EQ(-12, options->GetExtension(protobuf_unittest::float_opt));
3244  EXPECT_DOUBLE_EQ(-154, options->GetExtension(protobuf_unittest::double_opt));
3245 }
3246 
3247 TEST(CustomOptions, ComplexExtensionOptions) {
3248  const MessageOptions* options =
3250  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1).foo(), 42);
3251  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1)
3252  .GetExtension(protobuf_unittest::quux),
3253  324);
3254  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1)
3255  .GetExtension(protobuf_unittest::corge)
3256  .qux(),
3257  876);
3258  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).baz(), 987);
3259  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2)
3260  .GetExtension(protobuf_unittest::grault),
3261  654);
3262  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).bar().foo(),
3263  743);
3264  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2)
3265  .bar()
3266  .GetExtension(protobuf_unittest::quux),
3267  1999);
3268  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2)
3269  .bar()
3270  .GetExtension(protobuf_unittest::corge)
3271  .qux(),
3272  2008);
3273  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2)
3274  .GetExtension(protobuf_unittest::garply)
3275  .foo(),
3276  741);
3277  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2)
3278  .GetExtension(protobuf_unittest::garply)
3279  .GetExtension(protobuf_unittest::quux),
3280  1998);
3281  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2)
3282  .GetExtension(protobuf_unittest::garply)
3283  .GetExtension(protobuf_unittest::corge)
3284  .qux(),
3285  2121);
3287  ->GetExtension(protobuf_unittest::ComplexOptionType2::
3288  ComplexOptionType4::complex_opt4)
3289  .waldo(),
3290  1971);
3291  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).fred().waldo(),
3292  321);
3293  EXPECT_EQ(9, options->GetExtension(protobuf_unittest::complex_opt3).qux());
3294  EXPECT_EQ(22, options->GetExtension(protobuf_unittest::complex_opt3)
3295  .complexoptiontype5()
3296  .plugh());
3297  EXPECT_EQ(24, options->GetExtension(protobuf_unittest::complexopt6).xyzzy());
3298 }
3299 
3300 TEST(CustomOptions, OptionsFromOtherFile) {
3301  // Test that to use a custom option, we only need to import the file
3302  // defining the option; we do not also have to import descriptor.proto.
3304 
3305  FileDescriptorProto file_proto;
3306  FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
3307  ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
3308 
3309  // We have to import the Any dependency.
3310  FileDescriptorProto any_proto;
3311  google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto);
3312  ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr);
3313 
3315  &file_proto);
3316  ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
3317 
3319  "name: \"custom_options_import.proto\" "
3320  "package: \"protobuf_unittest\" "
3321  "dependency: \"google/protobuf/unittest_custom_options.proto\" "
3322  "options { "
3323  " uninterpreted_option { "
3324  " name { "
3325  " name_part: \"file_opt1\" "
3326  " is_extension: true "
3327  " } "
3328  " positive_int_value: 1234 "
3329  " } "
3330  // Test a non-extension option too. (At one point this failed due to a
3331  // bug.)
3332  " uninterpreted_option { "
3333  " name { "
3334  " name_part: \"java_package\" "
3335  " is_extension: false "
3336  " } "
3337  " string_value: \"foo\" "
3338  " } "
3339  // Test that enum-typed options still work too. (At one point this also
3340  // failed due to a bug.)
3341  " uninterpreted_option { "
3342  " name { "
3343  " name_part: \"optimize_for\" "
3344  " is_extension: false "
3345  " } "
3346  " identifier_value: \"SPEED\" "
3347  " } "
3348  "}",
3349  &file_proto));
3350 
3351  const FileDescriptor* file = pool.BuildFile(file_proto);
3352  ASSERT_TRUE(file != nullptr);
3353  EXPECT_EQ(1234, file->options().GetExtension(protobuf_unittest::file_opt1));
3354  EXPECT_TRUE(file->options().has_java_package());
3355  EXPECT_EQ("foo", file->options().java_package());
3356  EXPECT_TRUE(file->options().has_optimize_for());
3357  EXPECT_EQ(FileOptions::SPEED, file->options().optimize_for());
3358 }
3359 
3360 TEST(CustomOptions, MessageOptionThreeFieldsSet) {
3361  // This tests a bug which previously existed in custom options parsing. The
3362  // bug occurred when you defined a custom option with message type and then
3363  // set three fields of that option on a single definition (see the example
3364  // below). The bug is a bit hard to explain, so check the change history if
3365  // you want to know more.
3367 
3368  FileDescriptorProto file_proto;
3369  FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
3370  ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
3371 
3372  FileDescriptorProto any_proto;
3373  google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto);
3374  ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr);
3375 
3377  &file_proto);
3378  ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
3379 
3380  // The following represents the definition:
3381  //
3382  // import "google/protobuf/unittest_custom_options.proto"
3383  // package protobuf_unittest;
3384  // message Foo {
3385  // option (complex_opt1).foo = 1234;
3386  // option (complex_opt1).foo2 = 1234;
3387  // option (complex_opt1).foo3 = 1234;
3388  // }
3390  "name: \"custom_options_import.proto\" "
3391  "package: \"protobuf_unittest\" "
3392  "dependency: \"google/protobuf/unittest_custom_options.proto\" "
3393  "message_type { "
3394  " name: \"Foo\" "
3395  " options { "
3396  " uninterpreted_option { "
3397  " name { "
3398  " name_part: \"complex_opt1\" "
3399  " is_extension: true "
3400  " } "
3401  " name { "
3402  " name_part: \"foo\" "
3403  " is_extension: false "
3404  " } "
3405  " positive_int_value: 1234 "
3406  " } "
3407  " uninterpreted_option { "
3408  " name { "
3409  " name_part: \"complex_opt1\" "
3410  " is_extension: true "
3411  " } "
3412  " name { "
3413  " name_part: \"foo2\" "
3414  " is_extension: false "
3415  " } "
3416  " positive_int_value: 1234 "
3417  " } "
3418  " uninterpreted_option { "
3419  " name { "
3420  " name_part: \"complex_opt1\" "
3421  " is_extension: true "
3422  " } "
3423  " name { "
3424  " name_part: \"foo3\" "
3425  " is_extension: false "
3426  " } "
3427  " positive_int_value: 1234 "
3428  " } "
3429  " } "
3430  "}",
3431  &file_proto));
3432 
3433  const FileDescriptor* file = pool.BuildFile(file_proto);
3434  ASSERT_TRUE(file != nullptr);
3435  ASSERT_EQ(1, file->message_type_count());
3436 
3437  const MessageOptions& options = file->message_type(0)->options();
3438  EXPECT_EQ(1234, options.GetExtension(protobuf_unittest::complex_opt1).foo());
3439 }
3440 
3441 TEST(CustomOptions, MessageOptionRepeatedLeafFieldSet) {
3442  // This test verifies that repeated fields in custom options can be
3443  // given multiple values by repeating the option with a different value.
3444  // This test checks repeated leaf values. Each repeated custom value
3445  // appears in a different uninterpreted_option, which will be concatenated
3446  // when they are merged into the final option value.
3448 
3449  FileDescriptorProto file_proto;
3450  FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
3451  ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
3452 
3453  FileDescriptorProto any_proto;
3454  google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto);
3455  ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr);
3456 
3458  &file_proto);
3459  ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
3460 
3461  // The following represents the definition:
3462  //
3463  // import "google/protobuf/unittest_custom_options.proto"
3464  // package protobuf_unittest;
3465  // message Foo {
3466  // option (complex_opt1).foo4 = 12;
3467  // option (complex_opt1).foo4 = 34;
3468  // option (complex_opt1).foo4 = 56;
3469  // }
3471  "name: \"custom_options_import.proto\" "
3472  "package: \"protobuf_unittest\" "
3473  "dependency: \"google/protobuf/unittest_custom_options.proto\" "
3474  "message_type { "
3475  " name: \"Foo\" "
3476  " options { "
3477  " uninterpreted_option { "
3478  " name { "
3479  " name_part: \"complex_opt1\" "
3480  " is_extension: true "
3481  " } "
3482  " name { "
3483  " name_part: \"foo4\" "
3484  " is_extension: false "
3485  " } "
3486  " positive_int_value: 12 "
3487  " } "
3488  " uninterpreted_option { "
3489  " name { "
3490  " name_part: \"complex_opt1\" "
3491  " is_extension: true "
3492  " } "
3493  " name { "
3494  " name_part: \"foo4\" "
3495  " is_extension: false "
3496  " } "
3497  " positive_int_value: 34 "
3498  " } "
3499  " uninterpreted_option { "
3500  " name { "
3501  " name_part: \"complex_opt1\" "
3502  " is_extension: true "
3503  " } "
3504  " name { "
3505  " name_part: \"foo4\" "
3506  " is_extension: false "
3507  " } "
3508  " positive_int_value: 56 "
3509  " } "
3510  " } "
3511  "}",
3512  &file_proto));
3513 
3514  const FileDescriptor* file = pool.BuildFile(file_proto);
3515  ASSERT_TRUE(file != nullptr);
3516  ASSERT_EQ(1, file->message_type_count());
3517 
3518  const MessageOptions& options = file->message_type(0)->options();
3519  EXPECT_EQ(3, options.GetExtension(protobuf_unittest::complex_opt1).foo4_size());
3520  EXPECT_EQ(12, options.GetExtension(protobuf_unittest::complex_opt1).foo4(0));
3521  EXPECT_EQ(34, options.GetExtension(protobuf_unittest::complex_opt1).foo4(1));
3522  EXPECT_EQ(56, options.GetExtension(protobuf_unittest::complex_opt1).foo4(2));
3523 }
3524 
3525 TEST(CustomOptions, MessageOptionRepeatedMsgFieldSet) {
3526  // This test verifies that repeated fields in custom options can be
3527  // given multiple values by repeating the option with a different value.
3528  // This test checks repeated message values. Each repeated custom value
3529  // appears in a different uninterpreted_option, which will be concatenated
3530  // when they are merged into the final option value.
3532 
3533  FileDescriptorProto file_proto;
3534  FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
3535  ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
3536 
3537  FileDescriptorProto any_proto;
3538  google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto);
3539  ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr);
3540 
3542  &file_proto);
3543  ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
3544 
3545  // The following represents the definition:
3546  //
3547  // import "google/protobuf/unittest_custom_options.proto"
3548  // package protobuf_unittest;
3549  // message Foo {
3550  // option (complex_opt2).barney = {waldo: 1};
3551  // option (complex_opt2).barney = {waldo: 10};
3552  // option (complex_opt2).barney = {waldo: 100};
3553  // }
3555  "name: \"custom_options_import.proto\" "
3556  "package: \"protobuf_unittest\" "
3557  "dependency: \"google/protobuf/unittest_custom_options.proto\" "
3558  "message_type { "
3559  " name: \"Foo\" "
3560  " options { "
3561  " uninterpreted_option { "
3562  " name { "
3563  " name_part: \"complex_opt2\" "
3564  " is_extension: true "
3565  " } "
3566  " name { "
3567  " name_part: \"barney\" "
3568  " is_extension: false "
3569  " } "
3570  " aggregate_value: \"waldo: 1\" "
3571  " } "
3572  " uninterpreted_option { "
3573  " name { "
3574  " name_part: \"complex_opt2\" "
3575  " is_extension: true "
3576  " } "
3577  " name { "
3578  " name_part: \"barney\" "
3579  " is_extension: false "
3580  " } "
3581  " aggregate_value: \"waldo: 10\" "
3582  " } "
3583  " uninterpreted_option { "
3584  " name { "
3585  " name_part: \"complex_opt2\" "
3586  " is_extension: true "
3587  " } "
3588  " name { "
3589  " name_part: \"barney\" "
3590  " is_extension: false "
3591  " } "
3592  " aggregate_value: \"waldo: 100\" "
3593  " } "
3594  " } "
3595  "}",
3596  &file_proto));
3597 
3598  const FileDescriptor* file = pool.BuildFile(file_proto);
3599  ASSERT_TRUE(file != nullptr);
3600  ASSERT_EQ(1, file->message_type_count());
3601 
3602  const MessageOptions& options = file->message_type(0)->options();
3603  EXPECT_EQ(3,
3604  options.GetExtension(protobuf_unittest::complex_opt2).barney_size());
3605  EXPECT_EQ(
3606  1, options.GetExtension(protobuf_unittest::complex_opt2).barney(0).waldo());
3607  EXPECT_EQ(
3608  10,
3609  options.GetExtension(protobuf_unittest::complex_opt2).barney(1).waldo());
3610  EXPECT_EQ(
3611  100,
3612  options.GetExtension(protobuf_unittest::complex_opt2).barney(2).waldo());
3613 }
3614 
3615 // Check that aggregate options were parsed and saved correctly in
3616 // the appropriate descriptors.
3617 TEST(CustomOptions, AggregateOptions) {
3619  const FileDescriptor* file = msg->file();
3620  const FieldDescriptor* field = msg->FindFieldByName("fieldname");
3621  const EnumDescriptor* enumd = file->FindEnumTypeByName("AggregateEnum");
3622  const EnumValueDescriptor* enumv = enumd->FindValueByName("VALUE");
3623  const ServiceDescriptor* service =
3624  file->FindServiceByName("AggregateService");
3625  const MethodDescriptor* method = service->FindMethodByName("Method");
3626 
3627  // Tests for the different types of data embedded in fileopt
3628  const protobuf_unittest::Aggregate& file_options =
3629  file->options().GetExtension(protobuf_unittest::fileopt);
3630  EXPECT_EQ(100, file_options.i());
3631  EXPECT_EQ("FileAnnotation", file_options.s());
3632  EXPECT_EQ("NestedFileAnnotation", file_options.sub().s());
3633  EXPECT_EQ("FileExtensionAnnotation",
3634  file_options.file().GetExtension(protobuf_unittest::fileopt).s());
3635  EXPECT_EQ("EmbeddedMessageSetElement",
3636  file_options.mset()
3637  .GetExtension(protobuf_unittest::AggregateMessageSetElement ::
3638  message_set_extension)
3639  .s());
3640 
3641  protobuf_unittest::AggregateMessageSetElement any_payload;
3642  ASSERT_TRUE(file_options.any().UnpackTo(&any_payload));
3643  EXPECT_EQ("EmbeddedMessageSetElement", any_payload.s());
3644 
3645  // Simple tests for all the other types of annotations
3646  EXPECT_EQ("MessageAnnotation",
3647  msg->options().GetExtension(protobuf_unittest::msgopt).s());
3648  EXPECT_EQ("FieldAnnotation",
3649  field->options().GetExtension(protobuf_unittest::fieldopt).s());
3650  EXPECT_EQ("EnumAnnotation",
3651  enumd->options().GetExtension(protobuf_unittest::enumopt).s());
3652  EXPECT_EQ("EnumValueAnnotation",
3653  enumv->options().GetExtension(protobuf_unittest::enumvalopt).s());
3654  EXPECT_EQ("ServiceAnnotation",
3655  service->options().GetExtension(protobuf_unittest::serviceopt).s());
3656  EXPECT_EQ("MethodAnnotation",
3657  method->options().GetExtension(protobuf_unittest::methodopt).s());
3658 }
3659 
3660 TEST(CustomOptions, UnusedImportError) {
3662 
3663  FileDescriptorProto file_proto;
3664  FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
3665  ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
3666 
3667  FileDescriptorProto any_proto;
3668  google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto);
3669  ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr);
3670 
3672  &file_proto);
3673  ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
3674 
3675  pool.AddUnusedImportTrackFile("custom_options_import.proto", true);
3677  "name: \"custom_options_import.proto\" "
3678  "package: \"protobuf_unittest\" "
3679  "dependency: \"google/protobuf/unittest_custom_options.proto\" ",
3680  &file_proto));
3681 
3682  MockErrorCollector error_collector;
3683  EXPECT_FALSE(pool.BuildFileCollectingErrors(file_proto, &error_collector));
3684  EXPECT_EQ(
3685  "custom_options_import.proto: "
3686  "google/protobuf/unittest_custom_options.proto: IMPORT: Import "
3687  "google/protobuf/unittest_custom_options.proto is unused.\n",
3688  error_collector.text_);
3689 }
3690 
3691 // Verifies that proto files can correctly be parsed, even if the
3692 // custom options defined in the file are incompatible with those
3693 // compiled in the binary. See http://b/19276250.
3694 TEST(CustomOptions, OptionsWithIncompatibleDescriptors) {
3696 
3697  FileDescriptorProto file_proto;
3698  MessageOptions::descriptor()->file()->CopyTo(&file_proto);
3699  ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
3700 
3701  // Create a new file descriptor proto containing a subset of the
3702  // messages defined in google/protobuf/unittest_custom_options.proto.
3703  file_proto.Clear();
3704  file_proto.set_name("unittest_custom_options.proto");
3705  file_proto.set_package("protobuf_unittest");
3706  file_proto.add_dependency("google/protobuf/descriptor.proto");
3707 
3708  // Add the "required_enum_opt" extension.
3711  ->file()
3712  ->FindExtensionByName("required_enum_opt")
3713  ->CopyTo(extension);
3714 
3715  // Add a test message that uses the "required_enum_opt" option.
3716  DescriptorProto* test_message_type = file_proto.add_message_type();
3718  test_message_type);
3719 
3720  // Instruct the extension to use NewOptionType instead of
3721  // OldOptionType, and add the descriptor of NewOptionType.
3722  extension->set_type_name(".protobuf_unittest.NewOptionType");
3723  DescriptorProto* new_option_type = file_proto.add_message_type();
3724  protobuf_unittest::NewOptionType::descriptor()->CopyTo(new_option_type);
3725 
3726  // Replace the value of the "required_enum_opt" option used in the
3727  // test message with an enum value that only exists in NewOptionType.
3728  ASSERT_TRUE(
3729  TextFormat::ParseFromString("uninterpreted_option { "
3730  " name { "
3731  " name_part: 'required_enum_opt' "
3732  " is_extension: true "
3733  " } "
3734  " aggregate_value: 'value: NEW_VALUE'"
3735  "}",
3736  test_message_type->mutable_options()));
3737 
3738  // Adding the file descriptor to the pool should fail.
3739  EXPECT_TRUE(pool.BuildFile(file_proto) == nullptr);
3740 }
3741 
3742 // Test that FileDescriptor::DebugString() formats custom options correctly.
3743 TEST(CustomOptions, DebugString) {
3745 
3746  FileDescriptorProto file_proto;
3747  MessageOptions::descriptor()->file()->CopyTo(&file_proto);
3748  ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
3749 
3750  // Add "foo.proto":
3751  // import "google/protobuf/descriptor.proto";
3752  // package "protobuf_unittest";
3753  // option (protobuf_unittest.cc_option1) = 1;
3754  // option (protobuf_unittest.cc_option2) = 2;
3755  // extend google.protobuf.FieldOptions {
3756  // optional int32 cc_option1 = 7736974;
3757  // optional int32 cc_option2 = 7736975;
3758  // }
3760  "name: \"foo.proto\" "
3761  "package: \"protobuf_unittest\" "
3762  "dependency: \"google/protobuf/descriptor.proto\" "
3763  "options { "
3764  " uninterpreted_option { "
3765  " name { "
3766  " name_part: \"protobuf_unittest.cc_option1\" "
3767  " is_extension: true "
3768  " } "
3769  " positive_int_value: 1 "
3770  " } "
3771  " uninterpreted_option { "
3772  " name { "
3773  " name_part: \"protobuf_unittest.cc_option2\" "
3774  " is_extension: true "
3775  " } "
3776  " positive_int_value: 2 "
3777  " } "
3778  "} "
3779  "extension { "
3780  " name: \"cc_option1\" "
3781  " extendee: \".google.protobuf.FileOptions\" "
3782  // This field number is intentionally chosen to be the same as
3783  // (.fileopt1) defined in unittest_custom_options.proto (linked
3784  // in this test binary). This is to test whether we are messing
3785  // generated pool with custom descriptor pools when dealing with
3786  // custom options.
3787  " number: 7736974 "
3788  " label: LABEL_OPTIONAL "
3789  " type: TYPE_INT32 "
3790  "}"
3791  "extension { "
3792  " name: \"cc_option2\" "
3793  " extendee: \".google.protobuf.FileOptions\" "
3794  " number: 7736975 "
3795  " label: LABEL_OPTIONAL "
3796  " type: TYPE_INT32 "
3797  "}",
3798  &file_proto));
3799  const FileDescriptor* descriptor = pool.BuildFile(file_proto);
3800  ASSERT_TRUE(descriptor != nullptr);
3801 
3802  EXPECT_EQ(2, descriptor->extension_count());
3803 
3804  ASSERT_EQ(
3805  "syntax = \"proto2\";\n"
3806  "\n"
3807  "import \"google/protobuf/descriptor.proto\";\n"
3808  "package protobuf_unittest;\n"
3809  "\n"
3810  "option (.protobuf_unittest.cc_option1) = 1;\n"
3811  "option (.protobuf_unittest.cc_option2) = 2;\n"
3812  "\n"
3813  "extend .google.protobuf.FileOptions {\n"
3814  " optional int32 cc_option1 = 7736974;\n"
3815  " optional int32 cc_option2 = 7736975;\n"
3816  "}\n"
3817  "\n",
3818  descriptor->DebugString());
3819 }
3820 
3821 // ===================================================================
3822 
3823 class ValidationErrorTest : public testing::Test {
3824  protected:
3825  // Parse file_text as a FileDescriptorProto in text format and add it
3826  // to the DescriptorPool. Expect no errors.
3827  const FileDescriptor* BuildFile(const std::string& file_text) {
3828  FileDescriptorProto file_proto;
3829  EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
3830  return GOOGLE_CHECK_NOTNULL(pool_.BuildFile(file_proto));
3831  }
3832 
3833  // Parse file_text as a FileDescriptorProto in text format and add it
3834  // to the DescriptorPool. Expect errors to be produced which match the
3835  // given error text.
3836  void BuildFileWithErrors(const std::string& file_text,
3837  const std::string& expected_errors) {
3838  FileDescriptorProto file_proto;
3839  ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
3840 
3841  MockErrorCollector error_collector;
3842  EXPECT_TRUE(pool_.BuildFileCollectingErrors(file_proto, &error_collector) ==
3843  nullptr);
3844  EXPECT_EQ(expected_errors, error_collector.text_);
3845  }
3846 
3847  // Parse file_text as a FileDescriptorProto in text format and add it
3848  // to the DescriptorPool. Expect errors to be produced which match the
3849  // given warning text.
3850  void BuildFileWithWarnings(const std::string& file_text,
3851  const std::string& expected_warnings) {
3852  FileDescriptorProto file_proto;
3853  ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
3854 
3855  MockErrorCollector error_collector;
3856  EXPECT_TRUE(pool_.BuildFileCollectingErrors(file_proto, &error_collector));
3857  EXPECT_EQ(expected_warnings, error_collector.warning_text_);
3858  }
3859 
3860  // Builds some already-parsed file in our test pool.
3862  FileDescriptorProto file_proto;
3863  file->CopyTo(&file_proto);
3864  ASSERT_TRUE(pool_.BuildFile(file_proto) != nullptr);
3865  }
3866 
3867  // Build descriptor.proto in our test pool. This allows us to extend it in
3868  // the test pool, so we can test custom options.
3871  }
3872 
3874 };
3875 
3876 TEST_F(ValidationErrorTest, AlreadyDefined) {
3877  BuildFileWithErrors(
3878  "name: \"foo.proto\" "
3879  "message_type { name: \"Foo\" }"
3880  "message_type { name: \"Foo\" }",
3881 
3882  "foo.proto: Foo: NAME: \"Foo\" is already defined.\n");
3883 }
3884 
3885 TEST_F(ValidationErrorTest, AlreadyDefinedInPackage) {
3886  BuildFileWithErrors(
3887  "name: \"foo.proto\" "
3888  "package: \"foo.bar\" "
3889  "message_type { name: \"Foo\" }"
3890  "message_type { name: \"Foo\" }",
3891 
3892  "foo.proto: foo.bar.Foo: NAME: \"Foo\" is already defined in "
3893  "\"foo.bar\".\n");
3894 }
3895 
3896 TEST_F(ValidationErrorTest, AlreadyDefinedInOtherFile) {
3897  BuildFile(
3898  "name: \"foo.proto\" "
3899  "message_type { name: \"Foo\" }");
3900 
3901  BuildFileWithErrors(
3902  "name: \"bar.proto\" "
3903  "message_type { name: \"Foo\" }",
3904 
3905  "bar.proto: Foo: NAME: \"Foo\" is already defined in file "
3906  "\"foo.proto\".\n");
3907 }
3908 
3909 TEST_F(ValidationErrorTest, PackageAlreadyDefined) {
3910  BuildFile(
3911  "name: \"foo.proto\" "
3912  "message_type { name: \"foo\" }");
3913  BuildFileWithErrors(
3914  "name: \"bar.proto\" "
3915  "package: \"foo.bar\"",
3916 
3917  "bar.proto: foo: NAME: \"foo\" is already defined (as something other "
3918  "than a package) in file \"foo.proto\".\n");
3919 }
3920 
3921 TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParent) {
3922  BuildFileWithErrors(
3923  "name: \"foo.proto\" "
3924  "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } "
3925  "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ",
3926 
3927  "foo.proto: FOO: NAME: \"FOO\" is already defined.\n"
3928  "foo.proto: FOO: NAME: Note that enum values use C++ scoping rules, "
3929  "meaning that enum values are siblings of their type, not children of "
3930  "it. Therefore, \"FOO\" must be unique within the global scope, not "
3931  "just within \"Bar\".\n");
3932 }
3933 
3934 TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParentNonGlobal) {
3935  BuildFileWithErrors(
3936  "name: \"foo.proto\" "
3937  "package: \"pkg\" "
3938  "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } "
3939  "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ",
3940 
3941  "foo.proto: pkg.FOO: NAME: \"FOO\" is already defined in \"pkg\".\n"
3942  "foo.proto: pkg.FOO: NAME: Note that enum values use C++ scoping rules, "
3943  "meaning that enum values are siblings of their type, not children of "
3944  "it. Therefore, \"FOO\" must be unique within \"pkg\", not just within "
3945  "\"Bar\".\n");
3946 }
3947 
3948 TEST_F(ValidationErrorTest, MissingName) {
3949  BuildFileWithErrors(
3950  "name: \"foo.proto\" "
3951  "message_type { }",
3952 
3953  "foo.proto: : NAME: Missing name.\n");
3954 }
3955 
3956 TEST_F(ValidationErrorTest, InvalidName) {
3957  BuildFileWithErrors(
3958  "name: \"foo.proto\" "
3959  "message_type { name: \"$\" }",
3960 
3961  "foo.proto: $: NAME: \"$\" is not a valid identifier.\n");
3962 }
3963 
3964 TEST_F(ValidationErrorTest, InvalidPackageName) {
3965  BuildFileWithErrors(
3966  "name: \"foo.proto\" "
3967  "package: \"foo.$\"",
3968 
3969  "foo.proto: foo.$: NAME: \"$\" is not a valid identifier.\n");
3970 }
3971 
3972 // 'str' is a static C-style string that may contain '\0'
3973 #define STATIC_STR(str) std::string((str), sizeof(str) - 1)
3974 
3975 TEST_F(ValidationErrorTest, NullCharSymbolName) {
3976  BuildFileWithErrors(
3977  "name: \"bar.proto\" "
3978  "package: \"foo\""
3979  "message_type { "
3980  " name: '\\000\\001\\013.Bar' "
3981  " field { name: \"foo\" number: 9 label:LABEL_OPTIONAL type:TYPE_INT32 "
3982  "} "
3983  "}",
3984  STATIC_STR("bar.proto: foo.\0\x1\v.Bar: NAME: \"\0\x1\v.Bar\" is not a "
3985  "valid identifier.\nbar.proto: foo.\0\x1\v.Bar: NAME: "
3986  "\"\0\x1\v.Bar\" is not a valid identifier.\nbar.proto: "
3987  "foo.\0\x1\v.Bar: NAME: \"\0\x1\v.Bar\" is not a valid "
3988  "identifier.\nbar.proto: foo.\0\x1\v.Bar: NAME: "
3989  "\"\0\x1\v.Bar\" is not a valid identifier.\nbar.proto: "
3990  "foo.\0\x1\v.Bar.foo: NAME: \"foo.\0\x1\v.Bar.foo\" contains "
3991  "null character.\nbar.proto: foo.\0\x1\v.Bar: NAME: "
3992  "\"foo.\0\x1\v.Bar\" contains null character.\n"));
3993 }
3994 
3995 TEST_F(ValidationErrorTest, NullCharFileName) {
3996  BuildFileWithErrors(
3997  "name: \"bar\\000\\001\\013.proto\" "
3998  "package: \"outer.foo\"",
3999  STATIC_STR("bar\0\x1\v.proto: bar\0\x1\v.proto: NAME: "
4000  "\"bar\0\x1\v.proto\" contains null character.\n"));
4001 }
4002 
4003 TEST_F(ValidationErrorTest, NullCharPackageName) {
4004  BuildFileWithErrors(
4005  "name: \"bar.proto\" "
4006  "package: \"\\000\\001\\013.\"",
4007  STATIC_STR("bar.proto: \0\x1\v.: NAME: \"\0\x1\v.\" contains null "
4008  "character.\n"));
4009 }
4010 
4011 TEST_F(ValidationErrorTest, MissingFileName) {
4012  BuildFileWithErrors("",
4013 
4014  ": : OTHER: Missing field: FileDescriptorProto.name.\n");
4015 }
4016 
4017 TEST_F(ValidationErrorTest, DupeDependency) {
4018  BuildFile("name: \"foo.proto\"");
4019  BuildFileWithErrors(
4020  "name: \"bar.proto\" "
4021  "dependency: \"foo.proto\" "
4022  "dependency: \"foo.proto\" ",
4023 
4024  "bar.proto: foo.proto: IMPORT: Import \"foo.proto\" was listed twice.\n");
4025 }
4026 
4027 TEST_F(ValidationErrorTest, UnknownDependency) {
4028  BuildFileWithErrors(
4029  "name: \"bar.proto\" "
4030  "dependency: \"foo.proto\" ",
4031 
4032  "bar.proto: foo.proto: IMPORT: Import \"foo.proto\" has not been "
4033  "loaded.\n");
4034 }
4035 
4036 TEST_F(ValidationErrorTest, InvalidPublicDependencyIndex) {
4037  BuildFile("name: \"foo.proto\"");
4038  BuildFileWithErrors(
4039  "name: \"bar.proto\" "
4040  "dependency: \"foo.proto\" "
4041  "public_dependency: 1",
4042  "bar.proto: bar.proto: OTHER: Invalid public dependency index.\n");
4043 }
4044 
4045 TEST_F(ValidationErrorTest, ForeignUnimportedPackageNoCrash) {
4046  // Used to crash: If we depend on a non-existent file and then refer to a
4047  // package defined in a file that we didn't import, and that package is
4048  // nested within a parent package which this file is also in, and we don't
4049  // include that parent package in the name (i.e. we do a relative lookup)...
4050  // Yes, really.
4051  BuildFile(
4052  "name: 'foo.proto' "
4053  "package: 'outer.foo' ");
4054  BuildFileWithErrors(
4055  "name: 'bar.proto' "
4056  "dependency: 'baz.proto' "
4057  "package: 'outer.bar' "
4058  "message_type { "
4059  " name: 'Bar' "
4060  " field { name:'bar' number:1 label:LABEL_OPTIONAL type_name:'foo.Foo' }"
4061  "}",
4062 
4063  "bar.proto: baz.proto: IMPORT: Import \"baz.proto\" has not been "
4064  "loaded.\n"
4065  "bar.proto: outer.bar.Bar.bar: TYPE: \"outer.foo\" seems to be defined "
4066  "in "
4067  "\"foo.proto\", which is not imported by \"bar.proto\". To use it here, "
4068  "please add the necessary import.\n");
4069 }
4070 
4071 TEST_F(ValidationErrorTest, DupeFile) {
4072  BuildFile(
4073  "name: \"foo.proto\" "
4074  "message_type { name: \"Foo\" }");
4075  // Note: We should *not* get redundant errors about "Foo" already being
4076  // defined.
4077  BuildFileWithErrors(
4078  "name: \"foo.proto\" "
4079  "message_type { name: \"Foo\" } "
4080  // Add another type so that the files aren't identical (in which case
4081  // there would be no error).
4082  "enum_type { name: \"Bar\" }",
4083 
4084  "foo.proto: foo.proto: OTHER: A file with this name is already in the "
4085  "pool.\n");
4086 }
4087 
4088 TEST_F(ValidationErrorTest, FieldInExtensionRange) {
4089  BuildFileWithErrors(
4090  "name: \"foo.proto\" "
4091  "message_type {"
4092  " name: \"Foo\""
4093  " field { name: \"foo\" number: 9 label:LABEL_OPTIONAL type:TYPE_INT32 "
4094  "}"
4095  " field { name: \"bar\" number: 10 label:LABEL_OPTIONAL type:TYPE_INT32 "
4096  "}"
4097  " field { name: \"baz\" number: 19 label:LABEL_OPTIONAL type:TYPE_INT32 "
4098  "}"
4099  " field { name: \"qux\" number: 20 label:LABEL_OPTIONAL type:TYPE_INT32 "
4100  "}"
4101  " extension_range { start: 10 end: 20 }"
4102  "}",
4103 
4104  "foo.proto: Foo.bar: NUMBER: Extension range 10 to 19 includes field "
4105  "\"bar\" (10).\n"
4106  "foo.proto: Foo.baz: NUMBER: Extension range 10 to 19 includes field "
4107  "\"baz\" (19).\n");
4108 }
4109 
4110 TEST_F(ValidationErrorTest, OverlappingExtensionRanges) {
4111  BuildFileWithErrors(
4112  "name: \"foo.proto\" "
4113  "message_type {"
4114  " name: \"Foo\""
4115  " extension_range { start: 10 end: 20 }"
4116  " extension_range { start: 20 end: 30 }"
4117  " extension_range { start: 19 end: 21 }"
4118  "}",
4119 
4120  "foo.proto: Foo: NUMBER: Extension range 19 to 20 overlaps with "
4121  "already-defined range 10 to 19.\n"
4122  "foo.proto: Foo: NUMBER: Extension range 19 to 20 overlaps with "
4123  "already-defined range 20 to 29.\n");
4124 }
4125 
4126 TEST_F(ValidationErrorTest, ReservedFieldError) {
4127  BuildFileWithErrors(
4128  "name: \"foo.proto\" "
4129  "message_type {"
4130  " name: \"Foo\""
4131  " field { name: \"foo\" number: 15 label:LABEL_OPTIONAL type:TYPE_INT32 "
4132  "}"
4133  " reserved_range { start: 10 end: 20 }"
4134  "}",
4135 
4136  "foo.proto: Foo.foo: NUMBER: Field \"foo\" uses reserved number 15.\n");
4137 }
4138 
4139 TEST_F(ValidationErrorTest, ReservedExtensionRangeError) {
4140  BuildFileWithErrors(
4141  "name: \"foo.proto\" "
4142  "message_type {"
4143  " name: \"Foo\""
4144  " extension_range { start: 10 end: 20 }"
4145  " reserved_range { start: 5 end: 15 }"
4146  "}",
4147 
4148  "foo.proto: Foo: NUMBER: Extension range 10 to 19"
4149  " overlaps with reserved range 5 to 14.\n");
4150 }
4151 
4152 TEST_F(ValidationErrorTest, ReservedExtensionRangeAdjacent) {
4153  BuildFile(
4154  "name: \"foo.proto\" "
4155  "message_type {"
4156  " name: \"Foo\""
4157  " extension_range { start: 10 end: 20 }"
4158  " reserved_range { start: 5 end: 10 }"
4159  "}");
4160 }
4161 
4162 TEST_F(ValidationErrorTest, ReservedRangeOverlap) {
4163  BuildFileWithErrors(
4164  "name: \"foo.proto\" "
4165  "message_type {"
4166  " name: \"Foo\""
4167  " reserved_range { start: 10 end: 20 }"
4168  " reserved_range { start: 5 end: 15 }"
4169  "}",
4170 
4171  "foo.proto: Foo: NUMBER: Reserved range 5 to 14"
4172  " overlaps with already-defined range 10 to 19.\n");
4173 }
4174 
4175 TEST_F(ValidationErrorTest, ReservedNameError) {
4176  BuildFileWithErrors(
4177  "name: \"foo.proto\" "
4178  "message_type {"
4179  " name: \"Foo\""
4180  " field { name: \"foo\" number: 15 label:LABEL_OPTIONAL type:TYPE_INT32 "
4181  "}"
4182  " field { name: \"bar\" number: 16 label:LABEL_OPTIONAL type:TYPE_INT32 "
4183  "}"
4184  " field { name: \"baz\" number: 17 label:LABEL_OPTIONAL type:TYPE_INT32 "
4185  "}"
4186  " reserved_name: \"foo\""
4187  " reserved_name: \"bar\""
4188  "}",
4189 
4190  "foo.proto: Foo.foo: NAME: Field name \"foo\" is reserved.\n"
4191  "foo.proto: Foo.bar: NAME: Field name \"bar\" is reserved.\n");
4192 }
4193 
4194 TEST_F(ValidationErrorTest, ReservedNameRedundant) {
4195  BuildFileWithErrors(
4196  "name: \"foo.proto\" "
4197  "message_type {"
4198  " name: \"Foo\""
4199  " reserved_name: \"foo\""
4200  " reserved_name: \"foo\""
4201  "}",
4202 
4203  "foo.proto: foo: NAME: Field name \"foo\" is reserved multiple times.\n");
4204 }
4205 
4206 TEST_F(ValidationErrorTest, ReservedFieldsDebugString) {
4207  const FileDescriptor* file = BuildFile(
4208  "name: \"foo.proto\" "
4209  "message_type {"
4210  " name: \"Foo\""
4211  " reserved_name: \"foo\""
4212  " reserved_name: \"bar\""
4213  " reserved_range { start: 5 end: 6 }"
4214  " reserved_range { start: 10 end: 20 }"
4215  "}");
4216 
4217  ASSERT_EQ(
4218  "syntax = \"proto2\";\n\n"
4219  "message Foo {\n"
4220  " reserved 5, 10 to 19;\n"
4221  " reserved \"foo\", \"bar\";\n"
4222  "}\n\n",
4223  file->DebugString());
4224 }
4225 
4226 TEST_F(ValidationErrorTest, DebugStringReservedRangeMax) {
4227  const FileDescriptor* file = BuildFile(strings::Substitute(
4228  "name: \"foo.proto\" "
4229  "enum_type { "
4230  " name: \"Bar\""
4231  " value { name:\"BAR\" number:1 }"
4232  " reserved_range { start: 5 end: $0 }"
4233  "}"
4234  "message_type {"
4235  " name: \"Foo\""
4236  " reserved_range { start: 5 end: $1 }"
4237  "}",
4239 
4240  ASSERT_EQ(
4241  "syntax = \"proto2\";\n\n"
4242  "enum Bar {\n"
4243  " BAR = 1;\n"
4244  " reserved 5 to max;\n"
4245  "}\n\n"
4246  "message Foo {\n"
4247  " reserved 5 to max;\n"
4248  "}\n\n",
4249  file->DebugString());
4250 }
4251 
4252 TEST_F(ValidationErrorTest, EnumReservedFieldError) {
4253  BuildFileWithErrors(
4254  "name: \"foo.proto\" "
4255  "enum_type {"
4256  " name: \"Foo\""
4257  " value { name:\"BAR\" number:15 }"
4258  " reserved_range { start: 10 end: 20 }"
4259  "}",
4260 
4261  "foo.proto: BAR: NUMBER: Enum value \"BAR\" uses reserved number 15.\n");
4262 }
4263 
4264 TEST_F(ValidationErrorTest, EnumNegativeReservedFieldError) {
4265  BuildFileWithErrors(
4266  "name: \"foo.proto\" "
4267  "enum_type {"
4268  " name: \"Foo\""
4269  " value { name:\"BAR\" number:-15 }"
4270  " reserved_range { start: -20 end: -10 }"
4271  "}",
4272 
4273  "foo.proto: BAR: NUMBER: Enum value \"BAR\" uses reserved number -15.\n");
4274 }
4275 
4276 TEST_F(ValidationErrorTest, EnumReservedRangeOverlap) {
4277  BuildFileWithErrors(
4278  "name: \"foo.proto\" "
4279  "enum_type {"
4280  " name: \"Foo\""
4281  " value { name:\"BAR\" number:0 }"
4282  " reserved_range { start: 10 end: 20 }"
4283  " reserved_range { start: 5 end: 15 }"
4284  "}",
4285 
4286  "foo.proto: Foo: NUMBER: Reserved range 5 to 15"
4287  " overlaps with already-defined range 10 to 20.\n");
4288 }
4289 
4290 TEST_F(ValidationErrorTest, EnumReservedRangeOverlapByOne) {
4291  BuildFileWithErrors(
4292  "name: \"foo.proto\" "
4293  "enum_type {"
4294  " name: \"Foo\""
4295  " value { name:\"BAR\" number:0 }"
4296  " reserved_range { start: 10 end: 20 }"
4297  " reserved_range { start: 5 end: 10 }"
4298  "}",
4299 
4300  "foo.proto: Foo: NUMBER: Reserved range 5 to 10"
4301  " overlaps with already-defined range 10 to 20.\n");
4302 }
4303 
4304 TEST_F(ValidationErrorTest, EnumNegativeReservedRangeOverlap) {
4305  BuildFileWithErrors(
4306  "name: \"foo.proto\" "
4307  "enum_type {"
4308  " name: \"Foo\""
4309  " value { name:\"BAR\" number:0 }"
4310  " reserved_range { start: -20 end: -10 }"
4311  " reserved_range { start: -15 end: -5 }"
4312  "}",
4313 
4314  "foo.proto: Foo: NUMBER: Reserved range -15 to -5"
4315  " overlaps with already-defined range -20 to -10.\n");
4316 }
4317 
4318 TEST_F(ValidationErrorTest, EnumMixedReservedRangeOverlap) {
4319  BuildFileWithErrors(
4320  "name: \"foo.proto\" "
4321  "enum_type {"
4322  " name: \"Foo\""
4323  " value { name:\"BAR\" number:20 }"
4324  " reserved_range { start: -20 end: 10 }"
4325  " reserved_range { start: -15 end: 5 }"
4326  "}",
4327 
4328  "foo.proto: Foo: NUMBER: Reserved range -15 to 5"
4329  " overlaps with already-defined range -20 to 10.\n");
4330 }
4331 
4332 TEST_F(ValidationErrorTest, EnumMixedReservedRangeOverlap2) {
4333  BuildFileWithErrors(
4334  "name: \"foo.proto\" "
4335  "enum_type {"
4336  " name: \"Foo\""
4337  " value { name:\"BAR\" number:20 }"
4338  " reserved_range { start: -20 end: 10 }"
4339  " reserved_range { start: 10 end: 10 }"
4340  "}",
4341 
4342  "foo.proto: Foo: NUMBER: Reserved range 10 to 10"
4343  " overlaps with already-defined range -20 to 10.\n");
4344 }
4345 
4346 TEST_F(ValidationErrorTest, EnumReservedRangeStartGreaterThanEnd) {
4347  BuildFileWithErrors(
4348  "name: \"foo.proto\" "
4349  "enum_type {"
4350  " name: \"Foo\""
4351  " value { name:\"BAR\" number:20 }"
4352  " reserved_range { start: 11 end: 10 }"
4353  "}",
4354 
4355  "foo.proto: Foo: NUMBER: Reserved range end number must be greater"
4356  " than start number.\n");
4357 }
4358 
4359 TEST_F(ValidationErrorTest, EnumReservedNameError) {
4360  BuildFileWithErrors(
4361  "name: \"foo.proto\" "
4362  "enum_type {"
4363  " name: \"Foo\""
4364  " value { name:\"FOO\" number:15 }"
4365  " value { name:\"BAR\" number:15 }"
4366  " reserved_name: \"FOO\""
4367  " reserved_name: \"BAR\""
4368  "}",
4369 
4370  "foo.proto: FOO: NAME: Enum value \"FOO\" is reserved.\n"
4371  "foo.proto: BAR: NAME: Enum value \"BAR\" is reserved.\n");
4372 }
4373 
4374 TEST_F(ValidationErrorTest, EnumReservedNameRedundant) {
4375  BuildFileWithErrors(
4376  "name: \"foo.proto\" "
4377  "enum_type {"
4378  " name: \"Foo\""
4379  " value { name:\"FOO\" number:15 }"
4380  " reserved_name: \"foo\""
4381  " reserved_name: \"foo\""
4382  "}",
4383 
4384  "foo.proto: foo: NAME: Enum value \"foo\" is reserved multiple times.\n");
4385 }
4386 
4387 TEST_F(ValidationErrorTest, EnumReservedFieldsDebugString) {
4388  const FileDescriptor* file = BuildFile(
4389  "name: \"foo.proto\" "
4390  "enum_type {"
4391  " name: \"Foo\""
4392  " value { name:\"FOO\" number:3 }"
4393  " reserved_name: \"foo\""
4394  " reserved_name: \"bar\""
4395  " reserved_range { start: -6 end: -6 }"
4396  " reserved_range { start: -5 end: -4 }"
4397  " reserved_range { start: -1 end: 1 }"
4398  " reserved_range { start: 5 end: 5 }"
4399  " reserved_range { start: 10 end: 19 }"
4400  "}");
4401 
4402  ASSERT_EQ(
4403  "syntax = \"proto2\";\n\n"
4404  "enum Foo {\n"
4405  " FOO = 3;\n"
4406  " reserved -6, -5 to -4, -1 to 1, 5, 10 to 19;\n"
4407  " reserved \"foo\", \"bar\";\n"
4408  "}\n\n",
4409  file->DebugString());
4410 }
4411 
4412 TEST_F(ValidationErrorTest, InvalidDefaults) {
4413  BuildFileWithErrors(
4414  "name: \"foo.proto\" "
4415  "message_type {"
4416  " name: \"Foo\""
4417 
4418  // Invalid number.
4419  " field { name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32"
4420  " default_value: \"abc\" }"
4421 
4422  // Empty default value.
4423  " field { name: \"bar\" number: 2 label: LABEL_OPTIONAL type: TYPE_INT32"
4424  " default_value: \"\" }"
4425 
4426  // Invalid boolean.
4427  " field { name: \"baz\" number: 3 label: LABEL_OPTIONAL type: TYPE_BOOL"
4428  " default_value: \"abc\" }"
4429 
4430  // Messages can't have defaults.
4431  " field { name: \"qux\" number: 4 label: LABEL_OPTIONAL type: "
4432  "TYPE_MESSAGE"
4433  " default_value: \"abc\" type_name: \"Foo\" }"
4434 
4435  // Same thing, but we don't know that this field has message type until
4436  // we look up the type name.
4437  " field { name: \"quux\" number: 5 label: LABEL_OPTIONAL"
4438  " default_value: \"abc\" type_name: \"Foo\" }"
4439 
4440  // Repeateds can't have defaults.
4441  " field { name: \"corge\" number: 6 label: LABEL_REPEATED type: "
4442  "TYPE_INT32"
4443  " default_value: \"1\" }"
4444  "}",
4445 
4446  "foo.proto: Foo.foo: DEFAULT_VALUE: Couldn't parse default value "
4447  "\"abc\".\n"
4448  "foo.proto: Foo.bar: DEFAULT_VALUE: Couldn't parse default value \"\".\n"
4449  "foo.proto: Foo.baz: DEFAULT_VALUE: Boolean default must be true or "
4450  "false.\n"
4451  "foo.proto: Foo.qux: DEFAULT_VALUE: Messages can't have default values.\n"
4452  "foo.proto: Foo.corge: DEFAULT_VALUE: Repeated fields can't have default "
4453  "values.\n"
4454  // This ends up being reported later because the error is detected at
4455  // cross-linking time.
4456  "foo.proto: Foo.quux: DEFAULT_VALUE: Messages can't have default "
4457  "values.\n");
4458 }
4459 
4460 TEST_F(ValidationErrorTest, NegativeFieldNumber) {
4461  BuildFileWithErrors(
4462  "name: \"foo.proto\" "
4463  "message_type {"
4464  " name: \"Foo\""
4465  " field { name: \"foo\" number: -1 label:LABEL_OPTIONAL type:TYPE_INT32 "
4466  "}"
4467  "}",
4468 
4469  "foo.proto: Foo.foo: NUMBER: Field numbers must be positive integers.\n");
4470 }
4471 
4472 TEST_F(ValidationErrorTest, HugeFieldNumber) {
4473  BuildFileWithErrors(
4474  "name: \"foo.proto\" "
4475  "message_type {"
4476  " name: \"Foo\""
4477  " field { name: \"foo\" number: 0x70000000 "
4478  " label:LABEL_OPTIONAL type:TYPE_INT32 }"
4479  "}",
4480 
4481  "foo.proto: Foo.foo: NUMBER: Field numbers cannot be greater than "
4482  "536870911.\n");
4483 }
4484 
4485 TEST_F(ValidationErrorTest, ReservedFieldNumber) {
4486  BuildFileWithErrors(
4487  "name: \"foo.proto\" "
4488  "message_type {"
4489  " name: \"Foo\""
4490  " field {name:\"foo\" number: 18999 label:LABEL_OPTIONAL "
4491  "type:TYPE_INT32 }"
4492  " field {name:\"bar\" number: 19000 label:LABEL_OPTIONAL "
4493  "type:TYPE_INT32 }"
4494  " field {name:\"baz\" number: 19999 label:LABEL_OPTIONAL "
4495  "type:TYPE_INT32 }"
4496  " field {name:\"qux\" number: 20000 label:LABEL_OPTIONAL "
4497  "type:TYPE_INT32 }"
4498  "}",
4499 
4500  "foo.proto: Foo.bar: NUMBER: Field numbers 19000 through 19999 are "
4501  "reserved for the protocol buffer library implementation.\n"
4502  "foo.proto: Foo.baz: NUMBER: Field numbers 19000 through 19999 are "
4503  "reserved for the protocol buffer library implementation.\n");
4504 }
4505 
4506 TEST_F(ValidationErrorTest, ExtensionMissingExtendee) {
4507  BuildFileWithErrors(
4508  "name: \"foo.proto\" "
4509  "message_type {"
4510  " name: \"Foo\""
4511  " extension { name: \"foo\" number: 1 label: LABEL_OPTIONAL"
4512  " type_name: \"Foo\" }"
4513  "}",
4514 
4515  "foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee not set for "
4516  "extension field.\n");
4517 }
4518 
4519 TEST_F(ValidationErrorTest, NonExtensionWithExtendee) {
4520  BuildFileWithErrors(
4521  "name: \"foo.proto\" "
4522  "message_type {"
4523  " name: \"Bar\""
4524  " extension_range { start: 1 end: 2 }"
4525  "}"
4526  "message_type {"
4527  " name: \"Foo\""
4528  " field { name: \"foo\" number: 1 label: LABEL_OPTIONAL"
4529  " type_name: \"Foo\" extendee: \"Bar\" }"
4530  "}",
4531 
4532  "foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee set for "
4533  "non-extension field.\n");
4534 }
4535 
4536 TEST_F(ValidationErrorTest, FieldOneofIndexTooLarge) {
4537  BuildFileWithErrors(
4538  "name: \"foo.proto\" "
4539  "message_type {"
4540  " name: \"Foo\""
4541  " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32 "
4542  " oneof_index: 1 }"
4543  " field { name:\"dummy\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 "
4544  " oneof_index: 0 }"
4545  " oneof_decl { name:\"bar\" }"
4546  "}",
4547 
4548  "foo.proto: Foo.foo: TYPE: FieldDescriptorProto.oneof_index 1 is out of "
4549  "range for type \"Foo\".\n");
4550 }
4551 
4552 TEST_F(ValidationErrorTest, FieldOneofIndexNegative) {
4553  BuildFileWithErrors(
4554  "name: \"foo.proto\" "
4555  "message_type {"
4556  " name: \"Foo\""
4557  " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32 "
4558  " oneof_index: -1 }"
4559  " field { name:\"dummy\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 "
4560  " oneof_index: 0 }"
4561  " oneof_decl { name:\"bar\" }"
4562  "}",
4563 
4564  "foo.proto: Foo.foo: TYPE: FieldDescriptorProto.oneof_index -1 is out "
4565  "of "
4566  "range for type \"Foo\".\n");
4567 }
4568 
4569 TEST_F(ValidationErrorTest, OneofFieldsConsecutiveDefinition) {
4570  // Fields belonging to the same oneof must be defined consecutively.
4571  BuildFileWithErrors(
4572  "name: \"foo.proto\" "
4573  "message_type {"
4574  " name: \"Foo\""
4575  " field { name:\"foo1\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 "
4576  " oneof_index: 0 }"
4577  " field { name:\"bar\" number: 2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
4578  " field { name:\"foo2\" number: 3 label:LABEL_OPTIONAL type:TYPE_INT32 "
4579  " oneof_index: 0 }"
4580  " oneof_decl { name:\"foos\" }"
4581  "}",
4582 
4583  "foo.proto: Foo.bar: TYPE: Fields in the same oneof must be defined "
4584  "consecutively. \"bar\" cannot be defined before the completion of the "
4585  "\"foos\" oneof definition.\n");
4586 
4587  // Prevent interleaved fields, which belong to different oneofs.
4588  BuildFileWithErrors(
4589  "name: \"foo2.proto\" "
4590  "message_type {"
4591  " name: \"Foo2\""
4592  " field { name:\"foo1\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 "
4593  " oneof_index: 0 }"
4594  " field { name:\"bar1\" number: 2 label:LABEL_OPTIONAL type:TYPE_INT32 "
4595  " oneof_index: 1 }"
4596  " field { name:\"foo2\" number: 3 label:LABEL_OPTIONAL type:TYPE_INT32 "
4597  " oneof_index: 0 }"
4598  " field { name:\"bar2\" number: 4 label:LABEL_OPTIONAL type:TYPE_INT32 "
4599  " oneof_index: 1 }"
4600  " oneof_decl { name:\"foos\" }"
4601  " oneof_decl { name:\"bars\" }"
4602  "}",
4603  "foo2.proto: Foo2.bar1: TYPE: Fields in the same oneof must be defined "
4604  "consecutively. \"bar1\" cannot be defined before the completion of the "
4605  "\"foos\" oneof definition.\n"
4606  "foo2.proto: Foo2.foo2: TYPE: Fields in the same oneof must be defined "
4607  "consecutively. \"foo2\" cannot be defined before the completion of the "
4608  "\"bars\" oneof definition.\n");
4609 
4610  // Another case for normal fields and different oneof fields interleave.
4611  BuildFileWithErrors(
4612  "name: \"foo3.proto\" "
4613  "message_type {"
4614  " name: \"Foo3\""
4615  " field { name:\"foo1\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 "
4616  " oneof_index: 0 }"
4617  " field { name:\"bar1\" number: 2 label:LABEL_OPTIONAL type:TYPE_INT32 "
4618  " oneof_index: 1 }"
4619  " field { name:\"baz\" number: 3 label:LABEL_OPTIONAL type:TYPE_INT32 }"
4620  " field { name:\"foo2\" number: 4 label:LABEL_OPTIONAL type:TYPE_INT32 "
4621  " oneof_index: 0 }"
4622  " oneof_decl { name:\"foos\" }"
4623  " oneof_decl { name:\"bars\" }"
4624  "}",
4625  "foo3.proto: Foo3.baz: TYPE: Fields in the same oneof must be defined "
4626  "consecutively. \"baz\" cannot be defined before the completion of the "
4627  "\"foos\" oneof definition.\n");
4628 }
4629 
4630 TEST_F(ValidationErrorTest, FieldNumberConflict) {
4631  BuildFileWithErrors(
4632  "name: \"foo.proto\" "
4633  "message_type {"
4634  " name: \"Foo\""
4635  " field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
4636  " field { name: \"bar\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
4637  "}",
4638 
4639  "foo.proto: Foo.bar: NUMBER: Field number 1 has already been used in "
4640  "\"Foo\" by field \"foo\".\n");
4641 }
4642 
4643 TEST_F(ValidationErrorTest, BadMessageSetExtensionType) {
4644  BuildFileWithErrors(
4645  "name: \"foo.proto\" "
4646  "message_type {"
4647  " name: \"MessageSet\""
4648  " options { message_set_wire_format: true }"
4649  " extension_range { start: 4 end: 5 }"
4650  "}"
4651  "message_type {"
4652  " name: \"Foo\""
4653  " extension { name:\"foo\" number:4 label:LABEL_OPTIONAL type:TYPE_INT32"
4654  " extendee: \"MessageSet\" }"
4655  "}",
4656 
4657  "foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional "
4658  "messages.\n");
4659 }
4660 
4661 TEST_F(ValidationErrorTest, BadMessageSetExtensionLabel) {
4662  BuildFileWithErrors(
4663  "name: \"foo.proto\" "
4664  "message_type {"
4665  " name: \"MessageSet\""
4666  " options { message_set_wire_format: true }"
4667  " extension_range { start: 4 end: 5 }"
4668  "}"
4669  "message_type {"
4670  " name: \"Foo\""
4671  " extension { name:\"foo\" number:4 label:LABEL_REPEATED "
4672  "type:TYPE_MESSAGE"
4673  " type_name: \"Foo\" extendee: \"MessageSet\" }"
4674  "}",
4675 
4676  "foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional "
4677  "messages.\n");
4678 }
4679 
4680 TEST_F(ValidationErrorTest, FieldInMessageSet) {
4681  BuildFileWithErrors(
4682  "name: \"foo.proto\" "
4683  "message_type {"
4684  " name: \"Foo\""
4685  " options { message_set_wire_format: true }"
4686  " field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
4687  "}",
4688 
4689  "foo.proto: Foo.foo: NAME: MessageSets cannot have fields, only "
4690  "extensions.\n");
4691 }
4692 
4693 TEST_F(ValidationErrorTest, NegativeExtensionRangeNumber) {
4694  BuildFileWithErrors(
4695  "name: \"foo.proto\" "
4696  "message_type {"
4697  " name: \"Foo\""
4698  " extension_range { start: -10 end: -1 }"
4699  "}",
4700 
4701  "foo.proto: Foo: NUMBER: Extension numbers must be positive integers.\n");
4702 }
4703 
4704 TEST_F(ValidationErrorTest, HugeExtensionRangeNumber) {
4705  BuildFileWithErrors(
4706  "name: \"foo.proto\" "
4707  "message_type {"
4708  " name: \"Foo\""
4709  " extension_range { start: 1 end: 0x70000000 }"
4710  "}",
4711 
4712  "foo.proto: Foo: NUMBER: Extension numbers cannot be greater than "
4713  "536870911.\n");
4714 }
4715 
4716 TEST_F(ValidationErrorTest, ExtensionRangeEndBeforeStart) {
4717  BuildFileWithErrors(
4718  "name: \"foo.proto\" "
4719  "message_type {"
4720  " name: \"Foo\""
4721  " extension_range { start: 10 end: 10 }"
4722  " extension_range { start: 10 end: 5 }"
4723  "}",
4724 
4725  "foo.proto: Foo: NUMBER: Extension range end number must be greater than "
4726  "start number.\n"
4727  "foo.proto: Foo: NUMBER: Extension range end number must be greater than "
4728  "start number.\n");
4729 }
4730 
4731 TEST_F(ValidationErrorTest, EmptyEnum) {
4732  BuildFileWithErrors(
4733  "name: \"foo.proto\" "
4734  "enum_type { name: \"Foo\" }"
4735  // Also use the empty enum in a message to make sure there are no crashes
4736  // during validation (possible if the code attempts to derive a default
4737  // value for the field).
4738  "message_type {"
4739  " name: \"Bar\""
4740  " field { name: \"foo\" number: 1 label:LABEL_OPTIONAL "
4741  "type_name:\"Foo\" }"
4742  " field { name: \"bar\" number: 2 label:LABEL_OPTIONAL "
4743  "type_name:\"Foo\" "
4744  " default_value: \"NO_SUCH_VALUE\" }"
4745  "}",
4746 
4747  "foo.proto: Foo: NAME: Enums must contain at least one value.\n"
4748  "foo.proto: Bar.bar: DEFAULT_VALUE: Enum type \"Foo\" has no value named "
4749  "\"NO_SUCH_VALUE\".\n");
4750 }
4751 
4752 TEST_F(ValidationErrorTest, UndefinedExtendee) {
4753  BuildFileWithErrors(
4754  "name: \"foo.proto\" "
4755  "message_type {"
4756  " name: \"Foo\""
4757  " extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
4758  " extendee: \"Bar\" }"
4759  "}",
4760 
4761  "foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not defined.\n");
4762 }
4763 
4764 TEST_F(ValidationErrorTest, NonMessageExtendee) {
4765  BuildFileWithErrors(
4766  "name: \"foo.proto\" "
4767  "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } }"
4768  "message_type {"
4769  " name: \"Foo\""
4770  " extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
4771  " extendee: \"Bar\" }"
4772  "}",
4773 
4774  "foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not a message type.\n");
4775 }
4776 
4777 TEST_F(ValidationErrorTest, NotAnExtensionNumber) {
4778  BuildFileWithErrors(
4779  "name: \"foo.proto\" "
4780  "message_type {"
4781  " name: \"Bar\""
4782  "}"
4783  "message_type {"
4784  " name: \"Foo\""
4785  " extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
4786  " extendee: \"Bar\" }"
4787  "}",
4788 
4789  "foo.proto: Foo.foo: NUMBER: \"Bar\" does not declare 1 as an extension "
4790  "number.\n");
4791 }
4792 
4793 TEST_F(ValidationErrorTest, RequiredExtension) {
4794  BuildFileWithErrors(
4795  "name: \"foo.proto\" "
4796  "message_type {"
4797  " name: \"Bar\""
4798  " extension_range { start: 1000 end: 10000 }"
4799  "}"
4800  "message_type {"
4801  " name: \"Foo\""
4802  " extension {"
4803  " name:\"foo\""
4804  " number:1000"
4805  " label:LABEL_REQUIRED"
4806  " type:TYPE_INT32"
4807  " extendee: \"Bar\""
4808  " }"
4809  "}",
4810 
4811  "foo.proto: Foo.foo: TYPE: The extension Foo.foo cannot be required.\n");
4812 }
4813 
4814 TEST_F(ValidationErrorTest, UndefinedFieldType) {
4815  BuildFileWithErrors(
4816  "name: \"foo.proto\" "
4817  "message_type {"
4818  " name: \"Foo\""
4819  " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
4820  "}",
4821 
4822  "foo.proto: Foo.foo: TYPE: \"Bar\" is not defined.\n");
4823 }
4824 
4825 TEST_F(ValidationErrorTest, UndefinedFieldTypeWithDefault) {
4826  // See b/12533582. Previously this failed because the default value was not
4827  // accepted by the parser, which assumed an enum type, leading to an unclear
4828  // error message. We want this input to yield a validation error instead,
4829  // since the unknown type is the primary problem.
4830  BuildFileWithErrors(
4831  "name: \"foo.proto\" "
4832  "message_type {"
4833  " name: \"Foo\""
4834  " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"int\" "
4835  " default_value:\"1\" }"
4836  "}",
4837 
4838  "foo.proto: Foo.foo: TYPE: \"int\" is not defined.\n");
4839 }
4840 
4841 TEST_F(ValidationErrorTest, UndefinedNestedFieldType) {
4842  BuildFileWithErrors(
4843  "name: \"foo.proto\" "
4844  "message_type {"
4845  " name: \"Foo\""
4846  " nested_type { name:\"Baz\" }"
4847  " field { name:\"foo\" number:1"
4848  " label:LABEL_OPTIONAL"
4849  " type_name:\"Foo.Baz.Bar\" }"
4850  "}",
4851 
4852  "foo.proto: Foo.foo: TYPE: \"Foo.Baz.Bar\" is not defined.\n");
4853 }
4854 
4855 TEST_F(ValidationErrorTest, FieldTypeDefinedInUndeclaredDependency) {
4856  BuildFile(
4857  "name: \"bar.proto\" "
4858  "message_type { name: \"Bar\" } ");
4859 
4860  BuildFileWithErrors(
4861  "name: \"foo.proto\" "
4862  "message_type {"
4863  " name: \"Foo\""
4864  " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
4865  "}",
4866  "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", "
4867  "which is not imported by \"foo.proto\". To use it here, please add the "
4868  "necessary import.\n");
4869 }
4870 
4871 TEST_F(ValidationErrorTest, FieldTypeDefinedInIndirectDependency) {
4872  // Test for hidden dependencies.
4873  //
4874  // // bar.proto
4875  // message Bar{}
4876  //
4877  // // forward.proto
4878  // import "bar.proto"
4879  //
4880  // // foo.proto
4881  // import "forward.proto"
4882  // message Foo {
4883  // optional Bar foo = 1; // Error, needs to import bar.proto explicitly.
4884  // }
4885  //
4886  BuildFile(
4887  "name: \"bar.proto\" "
4888  "message_type { name: \"Bar\" }");
4889 
4890  BuildFile(
4891  "name: \"forward.proto\""
4892  "dependency: \"bar.proto\"");
4893 
4894  BuildFileWithErrors(
4895  "name: \"foo.proto\" "
4896  "dependency: \"forward.proto\" "
4897  "message_type {"
4898  " name: \"Foo\""
4899  " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
4900  "}",
4901  "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", "
4902  "which is not imported by \"foo.proto\". To use it here, please add the "
4903  "necessary import.\n");
4904 }
4905 
4906 TEST_F(ValidationErrorTest, FieldTypeDefinedInPublicDependency) {
4907  // Test for public dependencies.
4908  //
4909  // // bar.proto
4910  // message Bar{}
4911  //
4912  // // forward.proto
4913  // import public "bar.proto"
4914  //
4915  // // foo.proto
4916  // import "forward.proto"
4917  // message Foo {
4918  // optional Bar foo = 1; // Correct. "bar.proto" is public imported into
4919  // // forward.proto, so when "foo.proto" imports
4920  // // "forward.proto", it imports "bar.proto" too.
4921  // }
4922  //
4923  BuildFile(
4924  "name: \"bar.proto\" "
4925  "message_type { name: \"Bar\" }");
4926 
4927  BuildFile(
4928  "name: \"forward.proto\""
4929  "dependency: \"bar.proto\" "
4930  "public_dependency: 0");
4931 
4932  BuildFile(
4933  "name: \"foo.proto\" "
4934  "dependency: \"forward.proto\" "
4935  "message_type {"
4936  " name: \"Foo\""
4937  " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
4938  "}");
4939 }
4940 
4941 TEST_F(ValidationErrorTest, FieldTypeDefinedInTransitivePublicDependency) {
4942  // Test for public dependencies.
4943  //
4944  // // bar.proto
4945  // message Bar{}
4946  //
4947  // // forward.proto
4948  // import public "bar.proto"
4949  //
4950  // // forward2.proto
4951  // import public "forward.proto"
4952  //
4953  // // foo.proto
4954  // import "forward2.proto"
4955  // message Foo {
4956  // optional Bar foo = 1; // Correct, public imports are transitive.
4957  // }
4958  //
4959  BuildFile(
4960  "name: \"bar.proto\" "
4961  "message_type { name: \"Bar\" }");
4962 
4963  BuildFile(
4964  "name: \"forward.proto\""
4965  "dependency: \"bar.proto\" "
4966  "public_dependency: 0");
4967 
4968  BuildFile(
4969  "name: \"forward2.proto\""
4970  "dependency: \"forward.proto\" "
4971  "public_dependency: 0");
4972 
4973  BuildFile(
4974  "name: \"foo.proto\" "
4975  "dependency: \"forward2.proto\" "
4976  "message_type {"
4977  " name: \"Foo\""
4978  " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
4979  "}");
4980 }
4981 
4982 TEST_F(ValidationErrorTest,
4983  FieldTypeDefinedInPrivateDependencyOfPublicDependency) {
4984  // Test for public dependencies.
4985  //
4986  // // bar.proto
4987  // message Bar{}
4988  //
4989  // // forward.proto
4990  // import "bar.proto"
4991  //
4992  // // forward2.proto
4993  // import public "forward.proto"
4994  //
4995  // // foo.proto
4996  // import "forward2.proto"
4997  // message Foo {
4998  // optional Bar foo = 1; // Error, the "bar.proto" is not public imported
4999  // // into "forward.proto", so will not be imported
5000  // // into either "forward2.proto" or "foo.proto".
5001  // }
5002  //
5003  BuildFile(
5004  "name: \"bar.proto\" "
5005  "message_type { name: \"Bar\" }");
5006 
5007  BuildFile(
5008  "name: \"forward.proto\""
5009  "dependency: \"bar.proto\"");
5010 
5011  BuildFile(
5012  "name: \"forward2.proto\""
5013  "dependency: \"forward.proto\" "
5014  "public_dependency: 0");
5015 
5016  BuildFileWithErrors(
5017  "name: \"foo.proto\" "
5018  "dependency: \"forward2.proto\" "
5019  "message_type {"
5020  " name: \"Foo\""
5021  " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
5022  "}",
5023  "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", "
5024  "which is not imported by \"foo.proto\". To use it here, please add the "
5025  "necessary import.\n");
5026 }
5027 
5028 
5029 TEST_F(ValidationErrorTest, SearchMostLocalFirst) {
5030  // The following should produce an error that Bar.Baz is resolved but
5031  // not defined:
5032  // message Bar { message Baz {} }
5033  // message Foo {
5034  // message Bar {
5035  // // Placing "message Baz{}" here, or removing Foo.Bar altogether,
5036  // // would fix the error.
5037  // }
5038  // optional Bar.Baz baz = 1;
5039  // }
5040  // An one point the lookup code incorrectly did not produce an error in this
5041  // case, because when looking for Bar.Baz, it would try "Foo.Bar.Baz" first,
5042  // fail, and ten try "Bar.Baz" and succeed, even though "Bar" should actually
5043  // refer to the inner Bar, not the outer one.
5044  BuildFileWithErrors(
5045  "name: \"foo.proto\" "
5046  "message_type {"
5047  " name: \"Bar\""
5048  " nested_type { name: \"Baz\" }"
5049  "}"
5050  "message_type {"
5051  " name: \"Foo\""
5052  " nested_type { name: \"Bar\" }"
5053  " field { name:\"baz\" number:1 label:LABEL_OPTIONAL"
5054  " type_name:\"Bar.Baz\" }"
5055  "}",
5056 
5057  "foo.proto: Foo.baz: TYPE: \"Bar.Baz\" is resolved to \"Foo.Bar.Baz\","
5058  " which is not defined. The innermost scope is searched first in name "
5059  "resolution. Consider using a leading '.'(i.e., \".Bar.Baz\") to start "
5060  "from the outermost scope.\n");
5061 }
5062 
5063 TEST_F(ValidationErrorTest, SearchMostLocalFirst2) {
5064  // This test would find the most local "Bar" first, and does, but
5065  // proceeds to find the outer one because the inner one's not an
5066  // aggregate.
5067  BuildFile(
5068  "name: \"foo.proto\" "
5069  "message_type {"
5070  " name: \"Bar\""
5071  " nested_type { name: \"Baz\" }"
5072  "}"
5073  "message_type {"
5074  " name: \"Foo\""
5075  " field { name: \"Bar\" number:1 type:TYPE_BYTES } "
5076  " field { name:\"baz\" number:2 label:LABEL_OPTIONAL"
5077  " type_name:\"Bar.Baz\" }"
5078  "}");
5079 }
5080 
5081 TEST_F(ValidationErrorTest, PackageOriginallyDeclaredInTransitiveDependent) {
5082  // Imagine we have the following:
5083  //
5084  // foo.proto:
5085  // package foo.bar;
5086  // bar.proto:
5087  // package foo.bar;
5088  // import "foo.proto";
5089  // message Bar {}
5090  // baz.proto:
5091  // package foo;
5092  // import "bar.proto"
5093  // message Baz { optional bar.Bar qux = 1; }
5094  //
5095  // When validating baz.proto, we will look up "bar.Bar". As part of this
5096  // lookup, we first lookup "bar" then try to find "Bar" within it. "bar"
5097  // should resolve to "foo.bar". Note, though, that "foo.bar" was originally
5098  // defined in foo.proto, which is not a direct dependency of baz.proto. The
5099  // implementation of FindSymbol() normally only returns symbols in direct
5100  // dependencies, not indirect ones. This test insures that this does not
5101  // prevent it from finding "foo.bar".
5102 
5103  BuildFile(
5104  "name: \"foo.proto\" "
5105  "package: \"foo.bar\" ");
5106  BuildFile(
5107  "name: \"bar.proto\" "
5108  "package: \"foo.bar\" "
5109  "dependency: \"foo.proto\" "
5110  "message_type { name: \"Bar\" }");
5111  BuildFile(
5112  "name: \"baz.proto\" "
5113  "package: \"foo\" "
5114  "dependency: \"bar.proto\" "
5115  "message_type { "
5116  " name: \"Baz\" "
5117  " field { name:\"qux\" number:1 label:LABEL_OPTIONAL "
5118  " type_name:\"bar.Bar\" }"
5119  "}");
5120 }
5121 
5122 TEST_F(ValidationErrorTest, FieldTypeNotAType) {
5123  BuildFileWithErrors(
5124  "name: \"foo.proto\" "
5125  "message_type {"
5126  " name: \"Foo\""
5127  " field { name:\"foo\" number:1 label:LABEL_OPTIONAL "
5128  " type_name:\".Foo.bar\" }"
5129  " field { name:\"bar\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
5130  "}",
5131 
5132  "foo.proto: Foo.foo: TYPE: \".Foo.bar\" is not a type.\n");
5133 }
5134 
5135 TEST_F(ValidationErrorTest, RelativeFieldTypeNotAType) {
5136  BuildFileWithErrors(
5137  "name: \"foo.proto\" "
5138  "message_type {"
5139  " nested_type {"
5140  " name: \"Bar\""
5141  " field { name:\"Baz\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
5142  " }"
5143  " name: \"Foo\""
5144  " field { name:\"foo\" number:1 label:LABEL_OPTIONAL "
5145  " type_name:\"Bar.Baz\" }"
5146  "}",
5147  "foo.proto: Foo.foo: TYPE: \"Bar.Baz\" is not a type.\n");
5148 }
5149 
5150 TEST_F(ValidationErrorTest, FieldTypeMayBeItsName) {
5151  BuildFile(
5152  "name: \"foo.proto\" "
5153  "message_type {"
5154  " name: \"Bar\""
5155  "}"
5156  "message_type {"
5157  " name: \"Foo\""
5158  " field { name:\"Bar\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
5159  "}");
5160 }
5161 
5162 TEST_F(ValidationErrorTest, EnumFieldTypeIsMessage) {
5163  BuildFileWithErrors(
5164  "name: \"foo.proto\" "
5165  "message_type { name: \"Bar\" } "
5166  "message_type {"
5167  " name: \"Foo\""
5168  " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_ENUM"
5169  " type_name:\"Bar\" }"
5170  "}",
5171 
5172  "foo.proto: Foo.foo: TYPE: \"Bar\" is not an enum type.\n");
5173 }
5174 
5175 TEST_F(ValidationErrorTest, MessageFieldTypeIsEnum) {
5176  BuildFileWithErrors(
5177  "name: \"foo.proto\" "
5178  "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
5179  "message_type {"
5180  " name: \"Foo\""
5181  " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE"
5182  " type_name:\"Bar\" }"
5183  "}",
5184 
5185  "foo.proto: Foo.foo: TYPE: \"Bar\" is not a message type.\n");
5186 }
5187 
5188 TEST_F(ValidationErrorTest, BadEnumDefaultValue) {
5189  BuildFileWithErrors(
5190  "name: \"foo.proto\" "
5191  "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
5192  "message_type {"
5193  " name: \"Foo\""
5194  " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\""
5195  " default_value:\"NO_SUCH_VALUE\" }"
5196  "}",
5197 
5198  "foo.proto: Foo.foo: DEFAULT_VALUE: Enum type \"Bar\" has no value named "
5199  "\"NO_SUCH_VALUE\".\n");
5200 }
5201 
5202 TEST_F(ValidationErrorTest, EnumDefaultValueIsInteger) {
5203  BuildFileWithErrors(
5204  "name: \"foo.proto\" "
5205  "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
5206  "message_type {"
5207  " name: \"Foo\""
5208  " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\""
5209  " default_value:\"0\" }"
5210  "}",
5211 
5212  "foo.proto: Foo.foo: DEFAULT_VALUE: Default value for an enum field must "
5213  "be an identifier.\n");
5214 }
5215 
5216 TEST_F(ValidationErrorTest, PrimitiveWithTypeName) {
5217  BuildFileWithErrors(
5218  "name: \"foo.proto\" "
5219  "message_type {"
5220  " name: \"Foo\""
5221  " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
5222  " type_name:\"Foo\" }"
5223  "}",
5224 
5225  "foo.proto: Foo.foo: TYPE: Field with primitive type has type_name.\n");
5226 }
5227 
5228 TEST_F(ValidationErrorTest, NonPrimitiveWithoutTypeName) {
5229  BuildFileWithErrors(
5230  "name: \"foo.proto\" "
5231  "message_type {"
5232  " name: \"Foo\""
5233  " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE }"
5234  "}",
5235 
5236  "foo.proto: Foo.foo: TYPE: Field with message or enum type missing "
5237  "type_name.\n");
5238 }
5239 
5240 TEST_F(ValidationErrorTest, OneofWithNoFields) {
5241  BuildFileWithErrors(
5242  "name: \"foo.proto\" "
5243  "message_type {"
5244  " name: \"Foo\""
5245  " oneof_decl { name:\"bar\" }"
5246  "}",
5247 
5248  "foo.proto: Foo.bar: NAME: Oneof must have at least one field.\n");
5249 }
5250 
5251 TEST_F(ValidationErrorTest, OneofLabelMismatch) {
5252  BuildFileWithErrors(
5253  "name: \"foo.proto\" "
5254  "message_type {"
5255  " name: \"Foo\""
5256  " field { name:\"foo\" number:1 label:LABEL_REPEATED type:TYPE_INT32 "
5257  " oneof_index:0 }"
5258  " oneof_decl { name:\"bar\" }"
5259  "}",
5260 
5261  "foo.proto: Foo.foo: NAME: Fields of oneofs must themselves have label "
5262  "LABEL_OPTIONAL.\n");
5263 }
5264 
5265 TEST_F(ValidationErrorTest, InputTypeNotDefined) {
5266  BuildFileWithErrors(
5267  "name: \"foo.proto\" "
5268  "message_type { name: \"Foo\" } "
5269  "service {"
5270  " name: \"TestService\""
5271  " method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }"
5272  "}",
5273 
5274  "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not defined.\n"
5275  );
5276 }
5277 
5278 TEST_F(ValidationErrorTest, InputTypeNotAMessage) {
5279  BuildFileWithErrors(
5280  "name: \"foo.proto\" "
5281  "message_type { name: \"Foo\" } "
5282  "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
5283  "service {"
5284  " name: \"TestService\""
5285  " method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }"
5286  "}",
5287 
5288  "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not a message type.\n"
5289  );
5290 }
5291 
5292 TEST_F(ValidationErrorTest, OutputTypeNotDefined) {
5293  BuildFileWithErrors(
5294  "name: \"foo.proto\" "
5295  "message_type { name: \"Foo\" } "
5296  "service {"
5297  " name: \"TestService\""
5298  " method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }"
5299  "}",
5300 
5301  "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not defined.\n"
5302  );
5303 }
5304 
5305 TEST_F(ValidationErrorTest, OutputTypeNotAMessage) {
5306  BuildFileWithErrors(
5307  "name: \"foo.proto\" "
5308  "message_type { name: \"Foo\" } "
5309  "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
5310  "service {"
5311  " name: \"TestService\""
5312  " method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }"
5313  "}",
5314 
5315  "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not a message type.\n"
5316  );
5317 }
5318 
5319 
5320 TEST_F(ValidationErrorTest, IllegalPackedField) {
5321  BuildFileWithErrors(
5322  "name: \"foo.proto\" "
5323  "message_type {\n"
5324  " name: \"Foo\""
5325  " field { name:\"packed_string\" number:1 label:LABEL_REPEATED "
5326  " type:TYPE_STRING "
5327  " options { uninterpreted_option {"
5328  " name { name_part: \"packed\" is_extension: false }"
5329  " identifier_value: \"true\" }}}\n"
5330  " field { name:\"packed_message\" number:3 label:LABEL_REPEATED "
5331  " type_name: \"Foo\""
5332  " options { uninterpreted_option {"
5333  " name { name_part: \"packed\" is_extension: false }"
5334  " identifier_value: \"true\" }}}\n"
5335  " field { name:\"optional_int32\" number: 4 label: LABEL_OPTIONAL "
5336  " type:TYPE_INT32 "
5337  " options { uninterpreted_option {"
5338  " name { name_part: \"packed\" is_extension: false }"
5339  " identifier_value: \"true\" }}}\n"
5340  "}",
5341 
5342  "foo.proto: Foo.packed_string: TYPE: [packed = true] can only be "
5343  "specified for repeated primitive fields.\n"
5344  "foo.proto: Foo.packed_message: TYPE: [packed = true] can only be "
5345  "specified for repeated primitive fields.\n"
5346  "foo.proto: Foo.optional_int32: TYPE: [packed = true] can only be "
5347  "specified for repeated primitive fields.\n");
5348 }
5349 
5350 TEST_F(ValidationErrorTest, OptionWrongType) {
5351  BuildFileWithErrors(
5352  "name: \"foo.proto\" "
5353  "message_type { "
5354  " name: \"TestMessage\" "
5355  " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING "
5356  " options { uninterpreted_option { name { name_part: \"ctype\" "
5357  " is_extension: false }"
5358  " positive_int_value: 1 }"
5359  " }"
5360  " }"
5361  "}\n",
5362 
5363  "foo.proto: TestMessage.foo: OPTION_VALUE: Value must be identifier for "
5364  "enum-valued option \"google.protobuf.FieldOptions.ctype\".\n");
5365 }
5366 
5367 TEST_F(ValidationErrorTest, OptionExtendsAtomicType) {
5368  BuildFileWithErrors(
5369  "name: \"foo.proto\" "
5370  "message_type { "
5371  " name: \"TestMessage\" "
5372  " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING "
5373  " options { uninterpreted_option { name { name_part: \"ctype\" "
5374  " is_extension: false }"
5375  " name { name_part: \"foo\" "
5376  " is_extension: true }"
5377  " positive_int_value: 1 }"
5378  " }"
5379  " }"
5380  "}\n",
5381 
5382  "foo.proto: TestMessage.foo: OPTION_NAME: Option \"ctype\" is an "
5383  "atomic type, not a message.\n");
5384 }
5385 
5386 TEST_F(ValidationErrorTest, DupOption) {
5387  BuildFileWithErrors(
5388  "name: \"foo.proto\" "
5389  "message_type { "
5390  " name: \"TestMessage\" "
5391  " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_UINT32 "
5392  " options { uninterpreted_option { name { name_part: \"ctype\" "
5393  " is_extension: false }"
5394  " identifier_value: \"CORD\" }"
5395  " uninterpreted_option { name { name_part: \"ctype\" "
5396  " is_extension: false }"
5397  " identifier_value: \"CORD\" }"
5398  " }"
5399  " }"
5400  "}\n",
5401 
5402  "foo.proto: TestMessage.foo: OPTION_NAME: Option \"ctype\" was "
5403  "already set.\n");
5404 }
5405 
5406 TEST_F(ValidationErrorTest, InvalidOptionName) {
5407  BuildFileWithErrors(
5408  "name: \"foo.proto\" "
5409  "message_type { "
5410  " name: \"TestMessage\" "
5411  " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_BOOL "
5412  " options { uninterpreted_option { "
5413  " name { name_part: \"uninterpreted_option\" "
5414  " is_extension: false }"
5415  " positive_int_value: 1 "
5416  " }"
5417  " }"
5418  " }"
5419  "}\n",
5420 
5421  "foo.proto: TestMessage.foo: OPTION_NAME: Option must not use "
5422  "reserved name \"uninterpreted_option\".\n");
5423 }
5424 
5425 TEST_F(ValidationErrorTest, RepeatedMessageOption) {
5426  BuildDescriptorMessagesInTestPool();
5427 
5428  BuildFileWithErrors(
5429  "name: \"foo.proto\" "
5430  "dependency: \"google/protobuf/descriptor.proto\" "
5431  "message_type: { name: \"Bar\" field: { "
5432  " name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 } "
5433  "} "
5434  "extension { name: \"bar\" number: 7672757 label: LABEL_REPEATED "
5435  " type: TYPE_MESSAGE type_name: \"Bar\" "
5436  " extendee: \"google.protobuf.FileOptions\" }"
5437  "options { uninterpreted_option { name { name_part: \"bar\" "
5438  " is_extension: true } "
5439  " name { name_part: \"foo\" "
5440  " is_extension: false } "
5441  " positive_int_value: 1 } }",
5442 
5443  "foo.proto: foo.proto: OPTION_NAME: Option field \"(bar)\" is a "
5444  "repeated message. Repeated message options must be initialized "
5445  "using an aggregate value.\n");
5446 }
5447 
5448 TEST_F(ValidationErrorTest, ResolveUndefinedOption) {
5449  // The following should produce an error that baz.bar is resolved but not
5450  // defined.
5451  // foo.proto:
5452  // package baz
5453  // import google/protobuf/descriptor.proto
5454  // message Bar { optional int32 foo = 1; }
5455  // extend FileOptions { optional Bar bar = 7672757; }
5456  //
5457  // qux.proto:
5458  // package qux.baz
5459  // option (baz.bar).foo = 1;
5460  //
5461  // Although "baz.bar" is already defined, the lookup code will try
5462  // "qux.baz.bar", since it's the match from the innermost scope, which will
5463  // cause a symbol not defined error.
5464  BuildDescriptorMessagesInTestPool();
5465 
5466  BuildFile(
5467  "name: \"foo.proto\" "
5468  "package: \"baz\" "
5469  "dependency: \"google/protobuf/descriptor.proto\" "
5470  "message_type: { name: \"Bar\" field: { "
5471  " name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 } "
5472  "} "
5473  "extension { name: \"bar\" number: 7672757 label: LABEL_OPTIONAL "
5474  " type: TYPE_MESSAGE type_name: \"Bar\" "
5475  " extendee: \"google.protobuf.FileOptions\" }");
5476 
5477  BuildFileWithErrors(
5478  "name: \"qux.proto\" "
5479  "package: \"qux.baz\" "
5480  "options { uninterpreted_option { name { name_part: \"baz.bar\" "
5481  " is_extension: true } "
5482  " name { name_part: \"foo\" "
5483  " is_extension: false } "
5484  " positive_int_value: 1 } }",
5485 
5486  "qux.proto: qux.proto: OPTION_NAME: Option \"(baz.bar)\" is resolved to "
5487  "\"(qux.baz.bar)\","
5488  " which is not defined. The innermost scope is searched first in name "
5489  "resolution. Consider using a leading '.'(i.e., \"(.baz.bar)\") to start "
5490  "from the outermost scope.\n");
5491 }
5492 
5493 TEST_F(ValidationErrorTest, UnknownOption) {
5494  BuildFileWithErrors(
5495  "name: \"qux.proto\" "
5496  "package: \"qux.baz\" "
5497  "options { uninterpreted_option { name { name_part: \"baaz.bar\" "
5498  " is_extension: true } "
5499  " name { name_part: \"foo\" "
5500  " is_extension: false } "
5501  " positive_int_value: 1 } }",
5502 
5503  "qux.proto: qux.proto: OPTION_NAME: Option \"(baaz.bar)\" unknown. "
5504  "Ensure "
5505  "that your proto definition file imports the proto which defines the "
5506  "option.\n");
5507 }
5508 
5509 TEST_F(ValidationErrorTest, CustomOptionConflictingFieldNumber) {
5510  BuildDescriptorMessagesInTestPool();
5511 
5512  BuildFileWithErrors(
5513  "name: \"foo.proto\" "
5514  "dependency: \"google/protobuf/descriptor.proto\" "
5515  "extension { name: \"foo1\" number: 7672757 label: LABEL_OPTIONAL "
5516  " type: TYPE_INT32 extendee: \"google.protobuf.FieldOptions\" }"
5517  "extension { name: \"foo2\" number: 7672757 label: LABEL_OPTIONAL "
5518  " type: TYPE_INT32 extendee: \"google.protobuf.FieldOptions\" }",
5519 
5520  "foo.proto: foo2: NUMBER: Extension number 7672757 has already been used "
5521  "in \"google.protobuf.FieldOptions\" by extension \"foo1\".\n");
5522 }
5523 
5524 TEST_F(ValidationErrorTest, Int32OptionValueOutOfPositiveRange) {
5525  BuildDescriptorMessagesInTestPool();
5526 
5527  BuildFileWithErrors(
5528  "name: \"foo.proto\" "
5529  "dependency: \"google/protobuf/descriptor.proto\" "
5530  "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5531  " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
5532  "options { uninterpreted_option { name { name_part: \"foo\" "
5533  " is_extension: true } "
5534  " positive_int_value: 0x80000000 } "
5535  "}",
5536 
5537  "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
5538  "for int32 option \"foo\".\n");
5539 }
5540 
5541 TEST_F(ValidationErrorTest, Int32OptionValueOutOfNegativeRange) {
5542  BuildDescriptorMessagesInTestPool();
5543 
5544  BuildFileWithErrors(
5545  "name: \"foo.proto\" "
5546  "dependency: \"google/protobuf/descriptor.proto\" "
5547  "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5548  " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
5549  "options { uninterpreted_option { name { name_part: \"foo\" "
5550  " is_extension: true } "
5551  " negative_int_value: -0x80000001 } "
5552  "}",
5553 
5554  "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
5555  "for int32 option \"foo\".\n");
5556 }
5557 
5558 TEST_F(ValidationErrorTest, Int32OptionValueIsNotPositiveInt) {
5559  BuildDescriptorMessagesInTestPool();
5560 
5561  BuildFileWithErrors(
5562  "name: \"foo.proto\" "
5563  "dependency: \"google/protobuf/descriptor.proto\" "
5564  "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5565  " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
5566  "options { uninterpreted_option { name { name_part: \"foo\" "
5567  " is_extension: true } "
5568  " string_value: \"5\" } }",
5569 
5570  "foo.proto: foo.proto: OPTION_VALUE: Value must be integer "
5571  "for int32 option \"foo\".\n");
5572 }
5573 
5574 TEST_F(ValidationErrorTest, Int64OptionValueOutOfRange) {
5575  BuildDescriptorMessagesInTestPool();
5576 
5577  BuildFileWithErrors(
5578  "name: \"foo.proto\" "
5579  "dependency: \"google/protobuf/descriptor.proto\" "
5580  "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5581  " type: TYPE_INT64 extendee: \"google.protobuf.FileOptions\" }"
5582  "options { uninterpreted_option { name { name_part: \"foo\" "
5583  " is_extension: true } "
5584  " positive_int_value: 0x8000000000000000 "
5585  "} "
5586  "}",
5587 
5588  "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
5589  "for int64 option \"foo\".\n");
5590 }
5591 
5592 TEST_F(ValidationErrorTest, Int64OptionValueIsNotPositiveInt) {
5593  BuildDescriptorMessagesInTestPool();
5594 
5595  BuildFileWithErrors(
5596  "name: \"foo.proto\" "
5597  "dependency: \"google/protobuf/descriptor.proto\" "
5598  "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5599  " type: TYPE_INT64 extendee: \"google.protobuf.FileOptions\" }"
5600  "options { uninterpreted_option { name { name_part: \"foo\" "
5601  " is_extension: true } "
5602  " identifier_value: \"5\" } }",
5603 
5604  "foo.proto: foo.proto: OPTION_VALUE: Value must be integer "
5605  "for int64 option \"foo\".\n");
5606 }
5607 
5608 TEST_F(ValidationErrorTest, UInt32OptionValueOutOfRange) {
5609  BuildDescriptorMessagesInTestPool();
5610 
5611  BuildFileWithErrors(
5612  "name: \"foo.proto\" "
5613  "dependency: \"google/protobuf/descriptor.proto\" "
5614  "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5615  " type: TYPE_UINT32 extendee: \"google.protobuf.FileOptions\" }"
5616  "options { uninterpreted_option { name { name_part: \"foo\" "
5617  " is_extension: true } "
5618  " positive_int_value: 0x100000000 } }",
5619 
5620  "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
5621  "for uint32 option \"foo\".\n");
5622 }
5623 
5624 TEST_F(ValidationErrorTest, UInt32OptionValueIsNotPositiveInt) {
5625  BuildDescriptorMessagesInTestPool();
5626 
5627  BuildFileWithErrors(
5628  "name: \"foo.proto\" "
5629  "dependency: \"google/protobuf/descriptor.proto\" "
5630  "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5631  " type: TYPE_UINT32 extendee: \"google.protobuf.FileOptions\" }"
5632  "options { uninterpreted_option { name { name_part: \"foo\" "
5633  " is_extension: true } "
5634  " double_value: -5.6 } }",
5635 
5636  "foo.proto: foo.proto: OPTION_VALUE: Value must be non-negative integer "
5637  "for uint32 option \"foo\".\n");
5638 }
5639 
5640 TEST_F(ValidationErrorTest, UInt64OptionValueIsNotPositiveInt) {
5641  BuildDescriptorMessagesInTestPool();
5642 
5643  BuildFileWithErrors(
5644  "name: \"foo.proto\" "
5645  "dependency: \"google/protobuf/descriptor.proto\" "
5646  "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5647  " type: TYPE_UINT64 extendee: \"google.protobuf.FileOptions\" }"
5648  "options { uninterpreted_option { name { name_part: \"foo\" "
5649  " is_extension: true } "
5650  " negative_int_value: -5 } }",
5651 
5652  "foo.proto: foo.proto: OPTION_VALUE: Value must be non-negative integer "
5653  "for uint64 option \"foo\".\n");
5654 }
5655 
5656 TEST_F(ValidationErrorTest, FloatOptionValueIsNotNumber) {
5657  BuildDescriptorMessagesInTestPool();
5658 
5659  BuildFileWithErrors(
5660  "name: \"foo.proto\" "
5661  "dependency: \"google/protobuf/descriptor.proto\" "
5662  "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5663  " type: TYPE_FLOAT extendee: \"google.protobuf.FileOptions\" }"
5664  "options { uninterpreted_option { name { name_part: \"foo\" "
5665  " is_extension: true } "
5666  " string_value: \"bar\" } }",
5667 
5668  "foo.proto: foo.proto: OPTION_VALUE: Value must be number "
5669  "for float option \"foo\".\n");
5670 }
5671 
5672 TEST_F(ValidationErrorTest, DoubleOptionValueIsNotNumber) {
5673  BuildDescriptorMessagesInTestPool();
5674 
5675  BuildFileWithErrors(
5676  "name: \"foo.proto\" "
5677  "dependency: \"google/protobuf/descriptor.proto\" "
5678  "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5679  " type: TYPE_DOUBLE extendee: \"google.protobuf.FileOptions\" }"
5680  "options { uninterpreted_option { name { name_part: \"foo\" "
5681  " is_extension: true } "
5682  " string_value: \"bar\" } }",
5683 
5684  "foo.proto: foo.proto: OPTION_VALUE: Value must be number "
5685  "for double option \"foo\".\n");
5686 }
5687 
5688 TEST_F(ValidationErrorTest, BoolOptionValueIsNotTrueOrFalse) {
5689  BuildDescriptorMessagesInTestPool();
5690 
5691  BuildFileWithErrors(
5692  "name: \"foo.proto\" "
5693  "dependency: \"google/protobuf/descriptor.proto\" "
5694  "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5695  " type: TYPE_BOOL extendee: \"google.protobuf.FileOptions\" }"
5696  "options { uninterpreted_option { name { name_part: \"foo\" "
5697  " is_extension: true } "
5698  " identifier_value: \"bar\" } }",
5699 
5700  "foo.proto: foo.proto: OPTION_VALUE: Value must be \"true\" or \"false\" "
5701  "for boolean option \"foo\".\n");
5702 }
5703 
5704 TEST_F(ValidationErrorTest, EnumOptionValueIsNotIdentifier) {
5705  BuildDescriptorMessagesInTestPool();
5706 
5707  BuildFileWithErrors(
5708  "name: \"foo.proto\" "
5709  "dependency: \"google/protobuf/descriptor.proto\" "
5710  "enum_type { name: \"FooEnum\" value { name: \"BAR\" number: 1 } "
5711  " value { name: \"BAZ\" number: 2 } }"
5712  "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5713  " type: TYPE_ENUM type_name: \"FooEnum\" "
5714  " extendee: \"google.protobuf.FileOptions\" }"
5715  "options { uninterpreted_option { name { name_part: \"foo\" "
5716  " is_extension: true } "
5717  " string_value: \"QUUX\" } }",
5718 
5719  "foo.proto: foo.proto: OPTION_VALUE: Value must be identifier for "
5720  "enum-valued option \"foo\".\n");
5721 }
5722 
5723 TEST_F(ValidationErrorTest, EnumOptionValueIsNotEnumValueName) {
5724  BuildDescriptorMessagesInTestPool();
5725 
5726  BuildFileWithErrors(
5727  "name: \"foo.proto\" "
5728  "dependency: \"google/protobuf/descriptor.proto\" "
5729  "enum_type { name: \"FooEnum\" value { name: \"BAR\" number: 1 } "
5730  " value { name: \"BAZ\" number: 2 } }"
5731  "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5732  " type: TYPE_ENUM type_name: \"FooEnum\" "
5733  " extendee: \"google.protobuf.FileOptions\" }"
5734  "options { uninterpreted_option { name { name_part: \"foo\" "
5735  " is_extension: true } "
5736  " identifier_value: \"QUUX\" } }",
5737 
5738  "foo.proto: foo.proto: OPTION_VALUE: Enum type \"FooEnum\" has no value "
5739  "named \"QUUX\" for option \"foo\".\n");
5740 }
5741 
5742 TEST_F(ValidationErrorTest, EnumOptionValueIsSiblingEnumValueName) {
5743  BuildDescriptorMessagesInTestPool();
5744 
5745  BuildFileWithErrors(
5746  "name: \"foo.proto\" "
5747  "dependency: \"google/protobuf/descriptor.proto\" "
5748  "enum_type { name: \"FooEnum1\" value { name: \"BAR\" number: 1 } "
5749  " value { name: \"BAZ\" number: 2 } }"
5750  "enum_type { name: \"FooEnum2\" value { name: \"QUX\" number: 1 } "
5751  " value { name: \"QUUX\" number: 2 } }"
5752  "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5753  " type: TYPE_ENUM type_name: \"FooEnum1\" "
5754  " extendee: \"google.protobuf.FileOptions\" }"
5755  "options { uninterpreted_option { name { name_part: \"foo\" "
5756  " is_extension: true } "
5757  " identifier_value: \"QUUX\" } }",
5758 
5759  "foo.proto: foo.proto: OPTION_VALUE: Enum type \"FooEnum1\" has no value "
5760  "named \"QUUX\" for option \"foo\". This appears to be a value from a "
5761  "sibling type.\n");
5762 }
5763 
5764 TEST_F(ValidationErrorTest, StringOptionValueIsNotString) {
5765  BuildDescriptorMessagesInTestPool();
5766 
5767  BuildFileWithErrors(
5768  "name: \"foo.proto\" "
5769  "dependency: \"google/protobuf/descriptor.proto\" "
5770  "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5771  " type: TYPE_STRING extendee: \"google.protobuf.FileOptions\" }"
5772  "options { uninterpreted_option { name { name_part: \"foo\" "
5773  " is_extension: true } "
5774  " identifier_value: \"QUUX\" } }",
5775 
5776  "foo.proto: foo.proto: OPTION_VALUE: Value must be quoted string "
5777  "for "
5778  "string option \"foo\".\n");
5779 }
5780 
5781 TEST_F(ValidationErrorTest, JsonNameOptionOnExtensions) {
5782  BuildFileWithErrors(
5783  "name: \"foo.proto\" "
5784  "package: \"foo\" "
5785  "message_type {"
5786  " name: \"Foo\""
5787  " extension_range { start: 10 end: 20 }"
5788  "}"
5789  "extension {"
5790  " name: \"value\""
5791  " number: 10"
5792  " label: LABEL_OPTIONAL"
5793  " type: TYPE_INT32"
5794  " extendee: \"foo.Foo\""
5795  " json_name: \"myName\""
5796  "}",
5797  "foo.proto: foo.value: OPTION_NAME: option json_name is not allowed on "
5798  "extension fields.\n");
5799 }
5800 
5801 TEST_F(ValidationErrorTest, DuplicateExtensionFieldNumber) {
5802  BuildDescriptorMessagesInTestPool();
5803 
5804  BuildFile(
5805  "name: \"foo.proto\" "
5806  "dependency: \"google/protobuf/descriptor.proto\" "
5807  "extension { name: \"option1\" number: 1000 label: LABEL_OPTIONAL "
5808  " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }");
5809 
5810  BuildFileWithWarnings(
5811  "name: \"bar.proto\" "
5812  "dependency: \"google/protobuf/descriptor.proto\" "
5813  "extension { name: \"option2\" number: 1000 label: LABEL_OPTIONAL "
5814  " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }",
5815  "bar.proto: option2: NUMBER: Extension number 1000 has already been used "
5816  "in \"google.protobuf.FileOptions\" by extension \"option1\" defined in "
5817  "foo.proto.\n");
5818 }
5819 
5820 // Helper function for tests that check for aggregate value parsing
5821 // errors. The "value" argument is embedded inside the
5822 // "uninterpreted_option" portion of the result.
5824  return strings::Substitute(
5825  "name: \"foo.proto\" "
5826  "dependency: \"google/protobuf/descriptor.proto\" "
5827  "message_type { name: \"Foo\" } "
5828  "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5829  " type: TYPE_MESSAGE type_name: \"Foo\" "
5830  " extendee: \"google.protobuf.FileOptions\" }"
5831  "options { uninterpreted_option { name { name_part: \"foo\" "
5832  " is_extension: true } "
5833  " $0 } }",
5834  value);
5835 }
5836 
5837 TEST_F(ValidationErrorTest, AggregateValueNotFound) {
5838  BuildDescriptorMessagesInTestPool();
5839 
5840  BuildFileWithErrors(
5841  EmbedAggregateValue("string_value: \"\""),
5842  "foo.proto: foo.proto: OPTION_VALUE: Option \"foo\" is a message. "
5843  "To set the entire message, use syntax like "
5844  "\"foo = { <proto text format> }\". To set fields within it, use "
5845  "syntax like \"foo.foo = value\".\n");
5846 }
5847 
5848 TEST_F(ValidationErrorTest, AggregateValueParseError) {
5849  BuildDescriptorMessagesInTestPool();
5850 
5851  BuildFileWithErrors(
5852  EmbedAggregateValue("aggregate_value: \"1+2\""),
5853  "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option "
5854  "value for \"foo\": Expected identifier, got: 1\n");
5855 }
5856 
5857 TEST_F(ValidationErrorTest, AggregateValueUnknownFields) {
5858  BuildDescriptorMessagesInTestPool();
5859 
5860  BuildFileWithErrors(
5861  EmbedAggregateValue("aggregate_value: \"x:100\""),
5862  "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option "
5863  "value for \"foo\": Message type \"Foo\" has no field named \"x\".\n");
5864 }
5865 
5866 TEST_F(ValidationErrorTest, NotLiteImportsLite) {
5867  BuildFile(
5868  "name: \"bar.proto\" "
5869  "options { optimize_for: LITE_RUNTIME } ");
5870 
5871  BuildFileWithErrors(
5872  "name: \"foo.proto\" "
5873  "dependency: \"bar.proto\" ",
5874 
5875  "foo.proto: bar.proto: IMPORT: Files that do not use optimize_for = "
5876  "LITE_RUNTIME cannot import files which do use this option. This file "
5877  "is not lite, but it imports \"bar.proto\" which is.\n");
5878 }
5879 
5880 TEST_F(ValidationErrorTest, LiteExtendsNotLite) {
5881  BuildFile(
5882  "name: \"bar.proto\" "
5883  "message_type: {"
5884  " name: \"Bar\""
5885  " extension_range { start: 1 end: 1000 }"
5886  "}");
5887 
5888  BuildFileWithErrors(
5889  "name: \"foo.proto\" "
5890  "dependency: \"bar.proto\" "
5891  "options { optimize_for: LITE_RUNTIME } "
5892  "extension { name: \"ext\" number: 123 label: LABEL_OPTIONAL "
5893  " type: TYPE_INT32 extendee: \"Bar\" }",
5894 
5895  "foo.proto: ext: EXTENDEE: Extensions to non-lite types can only be "
5896  "declared in non-lite files. Note that you cannot extend a non-lite "
5897  "type to contain a lite type, but the reverse is allowed.\n");
5898 }
5899 
5900 TEST_F(ValidationErrorTest, NoLiteServices) {
5901  BuildFileWithErrors(
5902  "name: \"foo.proto\" "
5903  "options {"
5904  " optimize_for: LITE_RUNTIME"
5905  " cc_generic_services: true"
5906  " java_generic_services: true"
5907  "} "
5908  "service { name: \"Foo\" }",
5909 
5910  "foo.proto: Foo: NAME: Files with optimize_for = LITE_RUNTIME cannot "
5911  "define services unless you set both options cc_generic_services and "
5912  "java_generic_services to false.\n");
5913 
5914  BuildFile(
5915  "name: \"bar.proto\" "
5916  "options {"
5917  " optimize_for: LITE_RUNTIME"
5918  " cc_generic_services: false"
5919  " java_generic_services: false"
5920  "} "
5921  "service { name: \"Bar\" }");
5922 }
5923 
5924 TEST_F(ValidationErrorTest, RollbackAfterError) {
5925  // Build a file which contains every kind of construct but references an
5926  // undefined type. All these constructs will be added to the symbol table
5927  // before the undefined type error is noticed. The DescriptorPool will then
5928  // have to roll everything back.
5929  BuildFileWithErrors(
5930  "name: \"foo.proto\" "
5931  "message_type {"
5932  " name: \"TestMessage\""
5933  " field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }"
5934  "} "
5935  "enum_type {"
5936  " name: \"TestEnum\""
5937  " value { name:\"BAR\" number:1 }"
5938  "} "
5939  "service {"
5940  " name: \"TestService\""
5941  " method {"
5942  " name: \"Baz\""
5943  " input_type: \"NoSuchType\"" // error
5944  " output_type: \"TestMessage\""
5945  " }"
5946  "}",
5947 
5948  "foo.proto: TestService.Baz: INPUT_TYPE: \"NoSuchType\" is not defined.\n"
5949  );
5950 
5951  // Make sure that if we build the same file again with the error fixed,
5952  // it works. If the above rollback was incomplete, then some symbols will
5953  // be left defined, and this second attempt will fail since it tries to
5954  // re-define the same symbols.
5955  BuildFile(
5956  "name: \"foo.proto\" "
5957  "message_type {"
5958  " name: \"TestMessage\""
5959  " field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }"
5960  "} "
5961  "enum_type {"
5962  " name: \"TestEnum\""
5963  " value { name:\"BAR\" number:1 }"
5964  "} "
5965  "service {"
5966  " name: \"TestService\""
5967  " method { name:\"Baz\""
5968  " input_type:\"TestMessage\""
5969  " output_type:\"TestMessage\" }"
5970  "}");
5971 }
5972 
5973 TEST_F(ValidationErrorTest, ErrorsReportedToLogError) {
5974  // Test that errors are reported to GOOGLE_LOG(ERROR) if no error collector is
5975  // provided.
5976 
5977  FileDescriptorProto file_proto;
5978  ASSERT_TRUE(
5979  TextFormat::ParseFromString("name: \"foo.proto\" "
5980  "message_type { name: \"Foo\" } "
5981  "message_type { name: \"Foo\" } ",
5982  &file_proto));
5983 
5984  std::vector<std::string> errors;
5985 
5986  {
5987  ScopedMemoryLog log;
5988  EXPECT_TRUE(pool_.BuildFile(file_proto) == nullptr);
5989  errors = log.GetMessages(ERROR);
5990  }
5991 
5992  ASSERT_EQ(2, errors.size());
5993 
5994  EXPECT_EQ("Invalid proto descriptor for file \"foo.proto\":", errors[0]);
5995  EXPECT_EQ(" Foo: \"Foo\" is already defined.", errors[1]);
5996 }
5997 
5998 TEST_F(ValidationErrorTest, DisallowEnumAlias) {
5999  BuildFileWithErrors(
6000  "name: \"foo.proto\" "
6001  "enum_type {"
6002  " name: \"Bar\""
6003  " value { name:\"ENUM_A\" number:0 }"
6004  " value { name:\"ENUM_B\" number:0 }"
6005  "}",
6006  "foo.proto: Bar: NUMBER: "
6007  "\"ENUM_B\" uses the same enum value as \"ENUM_A\". "
6008  "If this is intended, set 'option allow_alias = true;' to the enum "
6009  "definition.\n");
6010 }
6011 
6012 TEST_F(ValidationErrorTest, AllowEnumAlias) {
6013  BuildFile(
6014  "name: \"foo.proto\" "
6015  "enum_type {"
6016  " name: \"Bar\""
6017  " value { name:\"ENUM_A\" number:0 }"
6018  " value { name:\"ENUM_B\" number:0 }"
6019  " options { allow_alias: true }"
6020  "}");
6021 }
6022 
6023 TEST_F(ValidationErrorTest, UnusedImportWarning) {
6024  pool_.AddUnusedImportTrackFile("bar.proto");
6025  BuildFile(
6026  "name: \"bar.proto\" "
6027  "message_type { name: \"Bar\" }");
6028 
6029  pool_.AddUnusedImportTrackFile("base.proto");
6030  BuildFile(
6031  "name: \"base.proto\" "
6032  "message_type { name: \"Base\" }");
6033 
6034  pool_.AddUnusedImportTrackFile("baz.proto");
6035  BuildFile(
6036  "name: \"baz.proto\" "
6037  "message_type { name: \"Baz\" }");
6038 
6039  pool_.AddUnusedImportTrackFile("public.proto");
6040  BuildFile(
6041  "name: \"public.proto\" "
6042  "dependency: \"bar.proto\""
6043  "public_dependency: 0");
6044 
6045  // // forward.proto
6046  // import "base.proto" // No warning: Base message is used.
6047  // import "bar.proto" // Will log a warning.
6048  // import public "baz.proto" // No warning: Do not track import public.
6049  // import "public.proto" // No warning: public.proto has import public.
6050  // message Forward {
6051  // optional Base base = 1;
6052  // }
6053  //
6054  pool_.AddUnusedImportTrackFile("forward.proto");
6055  BuildFileWithWarnings(
6056  "name: \"forward.proto\""
6057  "dependency: \"base.proto\""
6058  "dependency: \"bar.proto\""
6059  "dependency: \"baz.proto\""
6060  "dependency: \"public.proto\""
6061  "public_dependency: 2 "
6062  "message_type {"
6063  " name: \"Forward\""
6064  " field { name:\"base\" number:1 label:LABEL_OPTIONAL "
6065  "type_name:\"Base\" }"
6066  "}",
6067  "forward.proto: bar.proto: IMPORT: Import bar.proto is unused.\n");
6068 }
6069 
6070 namespace {
6071 void FillValidMapEntry(FileDescriptorProto* file_proto) {
6073  "name: 'foo.proto' "
6074  "message_type { "
6075  " name: 'Foo' "
6076  " field { "
6077  " name: 'foo_map' number: 1 label:LABEL_REPEATED "
6078  " type_name: 'FooMapEntry' "
6079  " } "
6080  " nested_type { "
6081  " name: 'FooMapEntry' "
6082  " options { map_entry: true } "
6083  " field { "
6084  " name: 'key' number: 1 type:TYPE_INT32 label:LABEL_OPTIONAL "
6085  " } "
6086  " field { "
6087  " name: 'value' number: 2 type:TYPE_INT32 label:LABEL_OPTIONAL "
6088  " } "
6089  " } "
6090  "} "
6091  "message_type { "
6092  " name: 'Bar' "
6093  " extension_range { start: 1 end: 10 }"
6094  "} ",
6095  file_proto));
6096 }
6097 static const char* kMapEntryErrorMessage =
6098  "foo.proto: Foo.foo_map: TYPE: map_entry should not be set explicitly. "
6099  "Use map<KeyType, ValueType> instead.\n";
6100 static const char* kMapEntryKeyTypeErrorMessage =
6101  "foo.proto: Foo.foo_map: TYPE: Key in map fields cannot be float/double, "
6102  "bytes or message types.\n";
6103 
6104 } // namespace
6105 
6106 TEST_F(ValidationErrorTest, MapEntryBase) {
6107  FileDescriptorProto file_proto;
6108  FillValidMapEntry(&file_proto);
6109  BuildFile(file_proto.DebugString());
6110 }
6111 
6112 TEST_F(ValidationErrorTest, MapEntryExtensionRange) {
6113  FileDescriptorProto file_proto;
6114  FillValidMapEntry(&file_proto);
6116  "extension_range { "
6117  " start: 10 end: 20 "
6118  "} ",
6119  file_proto.mutable_message_type(0)->mutable_nested_type(0));
6120  BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6121 }
6122 
6123 TEST_F(ValidationErrorTest, MapEntryExtension) {
6124  FileDescriptorProto file_proto;
6125  FillValidMapEntry(&file_proto);
6127  "extension { "
6128  " name: 'foo_ext' extendee: '.Bar' number: 5"
6129  "} ",
6130  file_proto.mutable_message_type(0)->mutable_nested_type(0));
6131  BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6132 }
6133 
6134 TEST_F(ValidationErrorTest, MapEntryNestedType) {
6135  FileDescriptorProto file_proto;
6136  FillValidMapEntry(&file_proto);
6138  "nested_type { "
6139  " name: 'Bar' "
6140  "} ",
6141  file_proto.mutable_message_type(0)->mutable_nested_type(0));
6142  BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6143 }
6144 
6145 TEST_F(ValidationErrorTest, MapEntryEnumTypes) {
6146  FileDescriptorProto file_proto;
6147  FillValidMapEntry(&file_proto);
6149  "enum_type { "
6150  " name: 'BarEnum' "
6151  " value { name: 'BAR_BAR' number:0 } "
6152  "} ",
6153  file_proto.mutable_message_type(0)->mutable_nested_type(0));
6154  BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6155 }
6156 
6157 TEST_F(ValidationErrorTest, MapEntryExtraField) {
6158  FileDescriptorProto file_proto;
6159  FillValidMapEntry(&file_proto);
6161  "field { "
6162  " name: 'other_field' "
6163  " label: LABEL_OPTIONAL "
6164  " type: TYPE_INT32 "
6165  " number: 3 "
6166  "} ",
6167  file_proto.mutable_message_type(0)->mutable_nested_type(0));
6168  BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6169 }
6170 
6171 TEST_F(ValidationErrorTest, MapEntryMessageName) {
6172  FileDescriptorProto file_proto;
6173  FillValidMapEntry(&file_proto);
6174  file_proto.mutable_message_type(0)->mutable_nested_type(0)->set_name(
6175  "OtherMapEntry");
6176  file_proto.mutable_message_type(0)->mutable_field(0)->set_type_name(
6177  "OtherMapEntry");
6178  BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6179 }
6180 
6181 TEST_F(ValidationErrorTest, MapEntryNoneRepeatedMapEntry) {
6182  FileDescriptorProto file_proto;
6183  FillValidMapEntry(&file_proto);
6184  file_proto.mutable_message_type(0)->mutable_field(0)->set_label(
6186  BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6187 }
6188 
6189 TEST_F(ValidationErrorTest, MapEntryDifferentContainingType) {
6190  FileDescriptorProto file_proto;
6191  FillValidMapEntry(&file_proto);
6192  // Move the nested MapEntry message into the top level, which should not pass
6193  // the validation.
6194  file_proto.mutable_message_type()->AddAllocated(
6195  file_proto.mutable_message_type(0)->mutable_nested_type()->ReleaseLast());
6196  BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6197 }
6198 
6199 TEST_F(ValidationErrorTest, MapEntryKeyName) {
6200  FileDescriptorProto file_proto;
6201  FillValidMapEntry(&file_proto);
6203  file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
6204  0);
6205  key->set_name("Key");
6206  BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6207 }
6208 
6209 TEST_F(ValidationErrorTest, MapEntryKeyLabel) {
6210  FileDescriptorProto file_proto;
6211  FillValidMapEntry(&file_proto);
6213  file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
6214  0);
6216  BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6217 }
6218 
6219 TEST_F(ValidationErrorTest, MapEntryKeyNumber) {
6220  FileDescriptorProto file_proto;
6221  FillValidMapEntry(&file_proto);
6223  file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
6224  0);
6225  key->set_number(3);
6226  BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6227 }
6228 
6229 TEST_F(ValidationErrorTest, MapEntryValueName) {
6230  FileDescriptorProto file_proto;
6231  FillValidMapEntry(&file_proto);
6233  file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
6234  1);
6235  value->set_name("Value");
6236  BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6237 }
6238 
6239 TEST_F(ValidationErrorTest, MapEntryValueLabel) {
6240  FileDescriptorProto file_proto;
6241  FillValidMapEntry(&file_proto);
6243  file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
6244  1);
6246  BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6247 }
6248 
6249 TEST_F(ValidationErrorTest, MapEntryValueNumber) {
6250  FileDescriptorProto file_proto;
6251  FillValidMapEntry(&file_proto);
6253  file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
6254  1);
6255  value->set_number(3);
6256  BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6257 }
6258 
6259 TEST_F(ValidationErrorTest, MapEntryKeyTypeFloat) {
6260  FileDescriptorProto file_proto;
6261  FillValidMapEntry(&file_proto);
6263  file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
6264  0);
6266  BuildFileWithErrors(file_proto.DebugString(), kMapEntryKeyTypeErrorMessage);
6267 }
6268 
6269 TEST_F(ValidationErrorTest, MapEntryKeyTypeDouble) {
6270  FileDescriptorProto file_proto;
6271  FillValidMapEntry(&file_proto);
6273  file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
6274  0);
6276  BuildFileWithErrors(file_proto.DebugString(), kMapEntryKeyTypeErrorMessage);
6277 }
6278 
6279 TEST_F(ValidationErrorTest, MapEntryKeyTypeBytes) {
6280  FileDescriptorProto file_proto;
6281  FillValidMapEntry(&file_proto);
6283  file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
6284  0);
6286  BuildFileWithErrors(file_proto.DebugString(), kMapEntryKeyTypeErrorMessage);
6287 }
6288 
6289 TEST_F(ValidationErrorTest, MapEntryKeyTypeEnum) {
6290  FileDescriptorProto file_proto;
6291  FillValidMapEntry(&file_proto);
6293  file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
6294  0);
6295  key->clear_type();
6296  key->set_type_name("BarEnum");
6297  EnumDescriptorProto* enum_proto = file_proto.add_enum_type();
6298  enum_proto->set_name("BarEnum");
6299  EnumValueDescriptorProto* enum_value_proto = enum_proto->add_value();
6300  enum_value_proto->set_name("BAR_VALUE0");
6301  enum_value_proto->set_number(0);
6302  BuildFileWithErrors(file_proto.DebugString(),
6303  "foo.proto: Foo.foo_map: TYPE: Key in map fields cannot "
6304  "be enum types.\n");
6305  // Enum keys are not allowed in proto3 as well.
6306  // Get rid of extensions for proto3 to make it proto3 compatible.
6307  file_proto.mutable_message_type()->RemoveLast();
6308  file_proto.set_syntax("proto3");
6309  BuildFileWithErrors(file_proto.DebugString(),
6310  "foo.proto: Foo.foo_map: TYPE: Key in map fields cannot "
6311  "be enum types.\n");
6312 }
6313 
6314 TEST_F(ValidationErrorTest, MapEntryKeyTypeMessage) {
6315  FileDescriptorProto file_proto;
6316  FillValidMapEntry(&file_proto);
6318  file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
6319  0);
6320  key->clear_type();
6321  key->set_type_name(".Bar");
6322  BuildFileWithErrors(file_proto.DebugString(), kMapEntryKeyTypeErrorMessage);
6323 }
6324 
6325 TEST_F(ValidationErrorTest, MapEntryConflictsWithField) {
6326  FileDescriptorProto file_proto;
6327  FillValidMapEntry(&file_proto);
6329  "field { "
6330  " name: 'FooMapEntry' "
6331  " type: TYPE_INT32 "
6332  " label: LABEL_OPTIONAL "
6333  " number: 100 "
6334  "}",
6335  file_proto.mutable_message_type(0));
6336  BuildFileWithErrors(
6337  file_proto.DebugString(),
6338  "foo.proto: Foo.FooMapEntry: NAME: \"FooMapEntry\" is already defined in "
6339  "\"Foo\".\n"
6340  "foo.proto: Foo.foo_map: TYPE: \"FooMapEntry\" is not defined.\n"
6341  "foo.proto: Foo: NAME: Expanded map entry type FooMapEntry conflicts "
6342  "with an existing field.\n");
6343 }
6344 
6345 TEST_F(ValidationErrorTest, MapEntryConflictsWithMessage) {
6346  FileDescriptorProto file_proto;
6347  FillValidMapEntry(&file_proto);
6349  "nested_type { "
6350  " name: 'FooMapEntry' "
6351  "}",
6352  file_proto.mutable_message_type(0));
6353  BuildFileWithErrors(
6354  file_proto.DebugString(),
6355  "foo.proto: Foo.FooMapEntry: NAME: \"FooMapEntry\" is already defined in "
6356  "\"Foo\".\n"
6357  "foo.proto: Foo: NAME: Expanded map entry type FooMapEntry conflicts "
6358  "with an existing nested message type.\n");
6359 }
6360 
6361 TEST_F(ValidationErrorTest, MapEntryConflictsWithEnum) {
6362  FileDescriptorProto file_proto;
6363  FillValidMapEntry(&file_proto);
6365  "enum_type { "
6366  " name: 'FooMapEntry' "
6367  " value { name: 'ENTRY_FOO' number: 0 }"
6368  "}",
6369  file_proto.mutable_message_type(0));
6370  BuildFileWithErrors(
6371  file_proto.DebugString(),
6372  "foo.proto: Foo.FooMapEntry: NAME: \"FooMapEntry\" is already defined in "
6373  "\"Foo\".\n"
6374  "foo.proto: Foo: NAME: Expanded map entry type FooMapEntry conflicts "
6375  "with an existing enum type.\n");
6376 }
6377 
6378 TEST_F(ValidationErrorTest, EnumValuesConflictWithDifferentCasing) {
6379  BuildFileWithErrors(
6380  "syntax: 'proto3'"
6381  "name: 'foo.proto' "
6382  "enum_type {"
6383  " name: 'FooEnum' "
6384  " value { name: 'BAR' number: 0 }"
6385  " value { name: 'bar' number: 1 }"
6386  "}",
6387  "foo.proto: bar: NAME: Enum name bar has the same name as BAR "
6388  "if you ignore case and strip out the enum name prefix (if any). "
6389  "This is error-prone and can lead to undefined behavior. "
6390  "Please avoid doing this. If you are using allow_alias, please assign "
6391  "the same numeric value to both enums.\n");
6392 
6393  // Not an error because both enums are mapped to the same value.
6394  BuildFile(
6395  "syntax: 'proto3'"
6396  "name: 'foo.proto' "
6397  "enum_type {"
6398  " name: 'FooEnum' "
6399  " options { allow_alias: true }"
6400  " value { name: 'UNKNOWN' number: 0 }"
6401  " value { name: 'BAR' number: 1 }"
6402  " value { name: 'bar' number: 1 }"
6403  "}");
6404 }
6405 
6406 TEST_F(ValidationErrorTest, EnumValuesConflictWhenPrefixesStripped) {
6407  BuildFileWithErrors(
6408  "syntax: 'proto3'"
6409  "name: 'foo.proto' "
6410  "enum_type {"
6411  " name: 'FooEnum' "
6412  " value { name: 'FOO_ENUM_BAZ' number: 0 }"
6413  " value { name: 'BAZ' number: 1 }"
6414  "}",
6415  "foo.proto: BAZ: NAME: Enum name BAZ has the same name as FOO_ENUM_BAZ "
6416  "if you ignore case and strip out the enum name prefix (if any). "
6417  "This is error-prone and can lead to undefined behavior. "
6418  "Please avoid doing this. If you are using allow_alias, please assign "
6419  "the same numeric value to both enums.\n");
6420 
6421  BuildFileWithErrors(
6422  "syntax: 'proto3'"
6423  "name: 'foo.proto' "
6424  "enum_type {"
6425  " name: 'FooEnum' "
6426  " value { name: 'FOOENUM_BAZ' number: 0 }"
6427  " value { name: 'BAZ' number: 1 }"
6428  "}",
6429  "foo.proto: BAZ: NAME: Enum name BAZ has the same name as FOOENUM_BAZ "
6430  "if you ignore case and strip out the enum name prefix (if any). "
6431  "This is error-prone and can lead to undefined behavior. "
6432  "Please avoid doing this. If you are using allow_alias, please assign "
6433  "the same numeric value to both enums.\n");
6434 
6435  BuildFileWithErrors(
6436  "syntax: 'proto3'"
6437  "name: 'foo.proto' "
6438  "enum_type {"
6439  " name: 'FooEnum' "
6440  " value { name: 'FOO_ENUM_BAR_BAZ' number: 0 }"
6441  " value { name: 'BAR__BAZ' number: 1 }"
6442  "}",
6443  "foo.proto: BAR__BAZ: NAME: Enum name BAR__BAZ has the same name as "
6444  "FOO_ENUM_BAR_BAZ if you ignore case and strip out the enum name prefix "
6445  "(if any). This is error-prone and can lead to undefined behavior. "
6446  "Please avoid doing this. If you are using allow_alias, please assign "
6447  "the same numeric value to both enums.\n");
6448 
6449  BuildFileWithErrors(
6450  "syntax: 'proto3'"
6451  "name: 'foo.proto' "
6452  "enum_type {"
6453  " name: 'FooEnum' "
6454  " value { name: 'FOO_ENUM__BAR_BAZ' number: 0 }"
6455  " value { name: 'BAR_BAZ' number: 1 }"
6456  "}",
6457  "foo.proto: BAR_BAZ: NAME: Enum name BAR_BAZ has the same name as "
6458  "FOO_ENUM__BAR_BAZ if you ignore case and strip out the enum name prefix "
6459  "(if any). This is error-prone and can lead to undefined behavior. "
6460  "Please avoid doing this. If you are using allow_alias, please assign "
6461  "the same numeric value to both enums.\n");
6462 
6463  // This isn't an error because the underscore will cause the PascalCase to
6464  // differ by case (BarBaz vs. Barbaz).
6465  BuildFile(
6466  "syntax: 'proto3'"
6467  "name: 'foo.proto' "
6468  "enum_type {"
6469  " name: 'FooEnum' "
6470  " value { name: 'BAR_BAZ' number: 0 }"
6471  " value { name: 'BARBAZ' number: 1 }"
6472  "}");
6473 }
6474 
6475 TEST_F(ValidationErrorTest, MapEntryConflictsWithOneof) {
6476  FileDescriptorProto file_proto;
6477  FillValidMapEntry(&file_proto);
6479  "oneof_decl { "
6480  " name: 'FooMapEntry' "
6481  "}"
6482  "field { "
6483  " name: 'int_field' "
6484  " type: TYPE_INT32 "
6485  " label: LABEL_OPTIONAL "
6486  " oneof_index: 0 "
6487  " number: 100 "
6488  "} ",
6489  file_proto.mutable_message_type(0));
6490  BuildFileWithErrors(
6491  file_proto.DebugString(),
6492  "foo.proto: Foo.FooMapEntry: NAME: \"FooMapEntry\" is already defined in "
6493  "\"Foo\".\n"
6494  "foo.proto: Foo.foo_map: TYPE: \"FooMapEntry\" is not defined.\n"
6495  "foo.proto: Foo: NAME: Expanded map entry type FooMapEntry conflicts "
6496  "with an existing oneof type.\n");
6497 }
6498 
6499 TEST_F(ValidationErrorTest, MapEntryUsesNoneZeroEnumDefaultValue) {
6500  BuildFileWithErrors(
6501  "name: \"foo.proto\" "
6502  "enum_type {"
6503  " name: \"Bar\""
6504  " value { name:\"ENUM_A\" number:1 }"
6505  " value { name:\"ENUM_B\" number:2 }"
6506  "}"
6507  "message_type {"
6508  " name: 'Foo' "
6509  " field { "
6510  " name: 'foo_map' number: 1 label:LABEL_REPEATED "
6511  " type_name: 'FooMapEntry' "
6512  " } "
6513  " nested_type { "
6514  " name: 'FooMapEntry' "
6515  " options { map_entry: true } "
6516  " field { "
6517  " name: 'key' number: 1 type:TYPE_INT32 label:LABEL_OPTIONAL "
6518  " } "
6519  " field { "
6520  " name: 'value' number: 2 type_name:\"Bar\" label:LABEL_OPTIONAL "
6521  " } "
6522  " } "
6523  "}",
6524  "foo.proto: Foo.foo_map: "
6525  "TYPE: Enum value in map must define 0 as the first value.\n");
6526 }
6527 
6528 TEST_F(ValidationErrorTest, Proto3RequiredFields) {
6529  BuildFileWithErrors(
6530  "name: 'foo.proto' "
6531  "syntax: 'proto3' "
6532  "message_type { "
6533  " name: 'Foo' "
6534  " field { name:'foo' number:1 label:LABEL_REQUIRED type:TYPE_INT32 } "
6535  "}",
6536  "foo.proto: Foo.foo: TYPE: Required fields are not allowed in "
6537  "proto3.\n");
6538 
6539  // applied to nested types as well.
6540  BuildFileWithErrors(
6541  "name: 'foo.proto' "
6542  "syntax: 'proto3' "
6543  "message_type { "
6544  " name: 'Foo' "
6545  " nested_type { "
6546  " name : 'Bar' "
6547  " field { name:'bar' number:1 label:LABEL_REQUIRED type:TYPE_INT32 } "
6548  " } "
6549  "}",
6550  "foo.proto: Foo.Bar.bar: TYPE: Required fields are not allowed in "
6551  "proto3.\n");
6552 
6553  // optional and repeated fields are OK.
6554  BuildFile(
6555  "name: 'foo.proto' "
6556  "syntax: 'proto3' "
6557  "message_type { "
6558  " name: 'Foo' "
6559  " field { name:'foo' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 } "
6560  " field { name:'bar' number:2 label:LABEL_REPEATED type:TYPE_INT32 } "
6561  "}");
6562 }
6563 
6564 TEST_F(ValidationErrorTest, ValidateProto3DefaultValue) {
6565  BuildFileWithErrors(
6566  "name: 'foo.proto' "
6567  "syntax: 'proto3' "
6568  "message_type { "
6569  " name: 'Foo' "
6570  " field { name:'foo' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 "
6571  " default_value: '1' }"
6572  "}",
6573  "foo.proto: Foo.foo: DEFAULT_VALUE: Explicit default values are not "
6574  "allowed in proto3.\n");
6575 
6576  BuildFileWithErrors(
6577  "name: 'foo.proto' "
6578  "syntax: 'proto3' "
6579  "message_type { "
6580  " name: 'Foo' "
6581  " nested_type { "
6582  " name : 'Bar' "
6583  " field { name:'bar' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 "
6584  " default_value: '1' }"
6585  " } "
6586  "}",
6587  "foo.proto: Foo.Bar.bar: DEFAULT_VALUE: Explicit default values are not "
6588  "allowed in proto3.\n");
6589 }
6590 
6591 TEST_F(ValidationErrorTest, ValidateProto3ExtensionRange) {
6592  BuildFileWithErrors(
6593  "name: 'foo.proto' "
6594  "syntax: 'proto3' "
6595  "message_type { "
6596  " name: 'Foo' "
6597  " field { name:'foo' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 } "
6598  " extension_range { start:10 end:100 } "
6599  "}",
6600  "foo.proto: Foo: NUMBER: Extension ranges are not allowed in "
6601  "proto3.\n");
6602 
6603  BuildFileWithErrors(
6604  "name: 'foo.proto' "
6605  "syntax: 'proto3' "
6606  "message_type { "
6607  " name: 'Foo' "
6608  " nested_type { "
6609  " name : 'Bar' "
6610  " field { name:'bar' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 } "
6611  " extension_range { start:10 end:100 } "
6612  " } "
6613  "}",
6614  "foo.proto: Foo.Bar: NUMBER: Extension ranges are not allowed in "
6615  "proto3.\n");
6616 }
6617 
6618 TEST_F(ValidationErrorTest, ValidateProto3MessageSetWireFormat) {
6619  BuildFileWithErrors(
6620  "name: 'foo.proto' "
6621  "syntax: 'proto3' "
6622  "message_type { "
6623  " name: 'Foo' "
6624  " options { message_set_wire_format: true } "
6625  "}",
6626  "foo.proto: Foo: NAME: MessageSet is not supported "
6627  "in proto3.\n");
6628 }
6629 
6630 TEST_F(ValidationErrorTest, ValidateProto3Enum) {
6631  BuildFileWithErrors(
6632  "name: 'foo.proto' "
6633  "syntax: 'proto3' "
6634  "enum_type { "
6635  " name: 'FooEnum' "
6636  " value { name: 'FOO_FOO' number:1 } "
6637  "}",
6638  "foo.proto: FooEnum: NUMBER: The first enum value must be "
6639  "zero in proto3.\n");
6640 
6641  BuildFileWithErrors(
6642  "name: 'foo.proto' "
6643  "syntax: 'proto3' "
6644  "message_type { "
6645  " name: 'Foo' "
6646  " enum_type { "
6647  " name: 'FooEnum' "
6648  " value { name: 'FOO_FOO' number:1 } "
6649  " } "
6650  "}",
6651  "foo.proto: Foo.FooEnum: NUMBER: The first enum value must be "
6652  "zero in proto3.\n");
6653 
6654  // valid case.
6655  BuildFile(
6656  "name: 'foo.proto' "
6657  "syntax: 'proto3' "
6658  "enum_type { "
6659  " name: 'FooEnum' "
6660  " value { name: 'FOO_FOO' number:0 } "
6661  "}");
6662 }
6663 
6664 TEST_F(ValidationErrorTest, ValidateProto3Group) {
6665  BuildFileWithErrors(
6666  "name: 'foo.proto' "
6667  "syntax: 'proto3' "
6668  "message_type { "
6669  " name: 'Foo' "
6670  " nested_type { "
6671  " name: 'FooGroup' "
6672  " } "
6673  " field { name:'foo_group' number: 1 label:LABEL_OPTIONAL "
6674  " type: TYPE_GROUP type_name:'FooGroup' } "
6675  "}",
6676  "foo.proto: Foo.foo_group: TYPE: Groups are not supported in proto3 "
6677  "syntax.\n");
6678 }
6679 
6680 
6681 TEST_F(ValidationErrorTest, ValidateProto3EnumFromProto2) {
6682  // Define an enum in a proto2 file.
6683  BuildFile(
6684  "name: 'foo.proto' "
6685  "package: 'foo' "
6686  "syntax: 'proto2' "
6687  "enum_type { "
6688  " name: 'FooEnum' "
6689  " value { name: 'DEFAULT_OPTION' number:0 } "
6690  "}");
6691 
6692  // Now try to refer to it. (All tests in the fixture use the same pool, so we
6693  // can refer to the enum above in this definition.)
6694  BuildFileWithErrors(
6695  "name: 'bar.proto' "
6696  "dependency: 'foo.proto' "
6697  "syntax: 'proto3' "
6698  "message_type { "
6699  " name: 'Foo' "
6700  " field { name:'bar' number:1 label:LABEL_OPTIONAL type:TYPE_ENUM "
6701  " type_name: 'foo.FooEnum' }"
6702  "}",
6703  "bar.proto: Foo.bar: TYPE: Enum type \"foo.FooEnum\" is not a proto3 "
6704  "enum, but is used in \"Foo\" which is a proto3 message type.\n");
6705 }
6706 
6707 TEST_F(ValidationErrorTest, ValidateProto3Extension) {
6708  // Valid for options.
6710  FileDescriptorProto file_proto;
6711  // Add "google/protobuf/descriptor.proto".
6712  FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
6713  ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
6714  // Add "foo.proto":
6715  // import "google/protobuf/descriptor.proto";
6716  // extend google.protobuf.FieldOptions {
6717  // optional int32 option1 = 1000;
6718  // }
6719  file_proto.Clear();
6720  file_proto.set_name("foo.proto");
6721  file_proto.set_syntax("proto3");
6722  file_proto.add_dependency("google/protobuf/descriptor.proto");
6723  AddExtension(&file_proto, "google.protobuf.FieldOptions", "option1", 1000,
6726  ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
6727 
6728  // Copy and change the package of the descriptor.proto
6729  BuildFile(
6730  "name: 'google.protobuf.proto' "
6731  "syntax: 'proto2' "
6732  "message_type { "
6733  " name: 'Container' extension_range { start: 1 end: 1000 } "
6734  "}");
6735  BuildFileWithErrors(
6736  "name: 'bar.proto' "
6737  "syntax: 'proto3' "
6738  "dependency: 'google.protobuf.proto' "
6739  "extension { "
6740  " name: 'bar' number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 "
6741  " extendee: 'Container' "
6742  "}",
6743  "bar.proto: bar: EXTENDEE: Extensions in proto3 are only allowed for "
6744  "defining options.\n");
6745 }
6746 
6747 // Test that field names that may conflict in JSON is not allowed by protoc.
6748 TEST_F(ValidationErrorTest, ValidateProto3JsonName) {
6749  // The comparison is case-insensitive.
6750  BuildFileWithErrors(
6751  "name: 'foo.proto' "
6752  "syntax: 'proto3' "
6753  "message_type {"
6754  " name: 'Foo'"
6755  " field { name:'name' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
6756  " field { name:'Name' number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
6757  "}",
6758  "foo.proto: Foo: NAME: The JSON camel-case name of field \"Name\" "
6759  "conflicts with field \"name\". This is not allowed in proto3.\n");
6760  // Underscores are ignored.
6761  BuildFileWithErrors(
6762  "name: 'foo.proto' "
6763  "syntax: 'proto3' "
6764  "message_type {"
6765  " name: 'Foo'"
6766  " field { name:'ab' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
6767  " field { name:'_a__b_' number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
6768  "}",
6769  "foo.proto: Foo: NAME: The JSON camel-case name of field \"_a__b_\" "
6770  "conflicts with field \"ab\". This is not allowed in proto3.\n");
6771 }
6772 
6773 
6774 TEST_F(ValidationErrorTest, UnusedImportWithOtherError) {
6775  BuildFile(
6776  "name: 'bar.proto' "
6777  "message_type {"
6778  " name: 'Bar'"
6779  "}");
6780 
6781  pool_.AddUnusedImportTrackFile("foo.proto", true);
6782  BuildFileWithErrors(
6783  "name: 'foo.proto' "
6784  "dependency: 'bar.proto' "
6785  "message_type {"
6786  " name: 'Foo'"
6787  " extension { name:'foo' number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
6788  " extendee: 'Baz' }"
6789  "}",
6790 
6791  // Should not also contain unused import error.
6792  "foo.proto: Foo.foo: EXTENDEE: \"Baz\" is not defined.\n");
6793 }
6794 
6795 
6796 // ===================================================================
6797 // DescriptorDatabase
6798 
6800  const char* file_text) {
6801  FileDescriptorProto file_proto;
6802  EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
6803  database->Add(file_proto);
6804 }
6805 
6806 class DatabaseBackedPoolTest : public testing::Test {
6807  protected:
6809 
6811 
6812  void SetUp() override {
6813  AddToDatabase(
6814  &database_,
6815  "name: 'foo.proto' "
6816  "message_type { name:'Foo' extension_range { start: 1 end: 100 } } "
6817  "enum_type { name:'TestEnum' value { name:'DUMMY' number:0 } } "
6818  "service { name:'TestService' } ");
6820  "name: 'bar.proto' "
6821  "dependency: 'foo.proto' "
6822  "message_type { name:'Bar' } "
6823  "extension { name:'foo_ext' extendee: '.Foo' number:5 "
6824  " label:LABEL_OPTIONAL type:TYPE_INT32 } ");
6825  // Baz has an undeclared dependency on Foo.
6826  AddToDatabase(
6827  &database_,
6828  "name: 'baz.proto' "
6829  "message_type { "
6830  " name:'Baz' "
6831  " field { name:'foo' number:1 label:LABEL_OPTIONAL type_name:'Foo' } "
6832  "}");
6833  }
6834 
6835  // We can't inject a file containing errors into a DescriptorPool, so we
6836  // need an actual mock DescriptorDatabase to test errors.
6837  class ErrorDescriptorDatabase : public DescriptorDatabase {
6838  public:
6841 
6842  // implements DescriptorDatabase ---------------------------------
6844  FileDescriptorProto* output) override {
6845  // error.proto and error2.proto cyclically import each other.
6846  if (filename == "error.proto") {
6847  output->Clear();
6848  output->set_name("error.proto");
6849  output->add_dependency("error2.proto");
6850  return true;
6851  } else if (filename == "error2.proto") {
6852  output->Clear();
6853  output->set_name("error2.proto");
6854  output->add_dependency("error.proto");
6855  return true;
6856  } else {
6857  return false;
6858  }
6859  }
6860  bool FindFileContainingSymbol(const std::string& symbol_name,
6861  FileDescriptorProto* output) override {
6862  return false;
6863  }
6865  int field_number,
6866  FileDescriptorProto* output) override {
6867  return false;
6868  }
6869  };
6870 
6871  // A DescriptorDatabase that counts how many times each method has been
6872  // called and forwards to some other DescriptorDatabase.
6873  class CallCountingDatabase : public DescriptorDatabase {
6874  public:
6876  : wrapped_db_(wrapped_db) {
6877  Clear();
6878  }
6880 
6882 
6883  int call_count_;
6884 
6885  void Clear() { call_count_ = 0; }
6886 
6887  // implements DescriptorDatabase ---------------------------------
6889  FileDescriptorProto* output) override {
6890  ++call_count_;
6892  }
6893  bool FindFileContainingSymbol(const std::string& symbol_name,
6894  FileDescriptorProto* output) override {
6895  ++call_count_;
6896  return wrapped_db_->FindFileContainingSymbol(symbol_name, output);
6897  }
6899  int field_number,
6900  FileDescriptorProto* output) override {
6901  ++call_count_;
6903  field_number, output);
6904  }
6905  };
6906 
6907  // A DescriptorDatabase which falsely always returns foo.proto when searching
6908  // for any symbol or extension number. This shouldn't cause the
6909  // DescriptorPool to reload foo.proto if it is already loaded.
6910  class FalsePositiveDatabase : public DescriptorDatabase {
6911  public:
6913  : wrapped_db_(wrapped_db) {}
6915 
6917 
6918  // implements DescriptorDatabase ---------------------------------
6920  FileDescriptorProto* output) override {
6922  }
6923  bool FindFileContainingSymbol(const std::string& symbol_name,
6924  FileDescriptorProto* output) override {
6925  return FindFileByName("foo.proto", output);
6926  }
6928  int field_number,
6929  FileDescriptorProto* output) override {
6930  return FindFileByName("foo.proto", output);
6931  }
6932  };
6933 };
6934 
6935 TEST_F(DatabaseBackedPoolTest, FindFileByName) {
6936  DescriptorPool pool(&database_);
6937 
6938  const FileDescriptor* foo = pool.FindFileByName("foo.proto");
6939  ASSERT_TRUE(foo != nullptr);
6940  EXPECT_EQ("foo.proto", foo->name());
6941  ASSERT_EQ(1, foo->message_type_count());
6942  EXPECT_EQ("Foo", foo->message_type(0)->name());
6943 
6944  EXPECT_EQ(foo, pool.FindFileByName("foo.proto"));
6945 
6946  EXPECT_TRUE(pool.FindFileByName("no_such_file.proto") == nullptr);
6947 }
6948 
6949 TEST_F(DatabaseBackedPoolTest, FindDependencyBeforeDependent) {
6950  DescriptorPool pool(&database_);
6951 
6952  const FileDescriptor* foo = pool.FindFileByName("foo.proto");
6953  ASSERT_TRUE(foo != nullptr);
6954  EXPECT_EQ("foo.proto", foo->name());
6955  ASSERT_EQ(1, foo->message_type_count());
6956  EXPECT_EQ("Foo", foo->message_type(0)->name());
6957 
6958  const FileDescriptor* bar = pool.FindFileByName("bar.proto");
6959  ASSERT_TRUE(bar != nullptr);
6960  EXPECT_EQ("bar.proto", bar->name());
6961  ASSERT_EQ(1, bar->message_type_count());
6962  EXPECT_EQ("Bar", bar->message_type(0)->name());
6963 
6964  ASSERT_EQ(1, bar->dependency_count());
6965  EXPECT_EQ(foo, bar->dependency(0));
6966 }
6967 
6968 TEST_F(DatabaseBackedPoolTest, FindDependentBeforeDependency) {
6969  DescriptorPool pool(&database_);
6970 
6971  const FileDescriptor* bar = pool.FindFileByName("bar.proto");
6972  ASSERT_TRUE(bar != nullptr);
6973  EXPECT_EQ("bar.proto", bar->name());
6974  ASSERT_EQ(1, bar->message_type_count());
6975  ASSERT_EQ("Bar", bar->message_type(0)->name());
6976 
6977  const FileDescriptor* foo = pool.FindFileByName("foo.proto");
6978  ASSERT_TRUE(foo != nullptr);
6979  EXPECT_EQ("foo.proto", foo->name());
6980  ASSERT_EQ(1, foo->message_type_count());
6981  ASSERT_EQ("Foo", foo->message_type(0)->name());
6982 
6983  ASSERT_EQ(1, bar->dependency_count());
6984  EXPECT_EQ(foo, bar->dependency(0));
6985 }
6986 
6987 TEST_F(DatabaseBackedPoolTest, FindFileContainingSymbol) {
6988  DescriptorPool pool(&database_);
6989 
6990  const FileDescriptor* file = pool.FindFileContainingSymbol("Foo");
6991  ASSERT_TRUE(file != nullptr);
6992  EXPECT_EQ("foo.proto", file->name());
6993  EXPECT_EQ(file, pool.FindFileByName("foo.proto"));
6994 
6995  EXPECT_TRUE(pool.FindFileContainingSymbol("NoSuchSymbol") == nullptr);
6996 }
6997 
6998 TEST_F(DatabaseBackedPoolTest, FindMessageTypeByName) {
6999  DescriptorPool pool(&database_);
7000 
7001  const Descriptor* type = pool.FindMessageTypeByName("Foo");
7002  ASSERT_TRUE(type != nullptr);
7003  EXPECT_EQ("Foo", type->name());
7004  EXPECT_EQ(type->file(), pool.FindFileByName("foo.proto"));
7005 
7006  EXPECT_TRUE(pool.FindMessageTypeByName("NoSuchType") == nullptr);
7007 }
7008 
7009 TEST_F(DatabaseBackedPoolTest, FindExtensionByNumber) {
7010  DescriptorPool pool(&database_);
7011 
7012  const Descriptor* foo = pool.FindMessageTypeByName("Foo");
7013  ASSERT_TRUE(foo != nullptr);
7014 
7015  const FieldDescriptor* extension = pool.FindExtensionByNumber(foo, 5);
7016  ASSERT_TRUE(extension != nullptr);
7017  EXPECT_EQ("foo_ext", extension->name());
7018  EXPECT_EQ(extension->file(), pool.FindFileByName("bar.proto"));
7019 
7020  EXPECT_TRUE(pool.FindExtensionByNumber(foo, 12) == nullptr);
7021 }
7022 
7023 TEST_F(DatabaseBackedPoolTest, FindAllExtensions) {
7024  DescriptorPool pool(&database_);
7025 
7026  const Descriptor* foo = pool.FindMessageTypeByName("Foo");
7027 
7028  for (int i = 0; i < 2; ++i) {
7029  // Repeat the lookup twice, to check that we get consistent
7030  // results despite the fallback database lookup mutating the pool.
7031  std::vector<const FieldDescriptor*> extensions;
7032  pool.FindAllExtensions(foo, &extensions);
7033  ASSERT_EQ(1, extensions.size());
7034  EXPECT_EQ(5, extensions[0]->number());
7035  }
7036 }
7037 
7038 TEST_F(DatabaseBackedPoolTest, ErrorWithoutErrorCollector) {
7039  ErrorDescriptorDatabase error_database;
7040  DescriptorPool pool(&error_database);
7041 
7042  std::vector<std::string> errors;
7043 
7044  {
7045  ScopedMemoryLog log;
7046  EXPECT_TRUE(pool.FindFileByName("error.proto") == nullptr);
7047  errors = log.GetMessages(ERROR);
7048  }
7049 
7050  EXPECT_FALSE(errors.empty());
7051 }
7052 
7053 TEST_F(DatabaseBackedPoolTest, ErrorWithErrorCollector) {
7054  ErrorDescriptorDatabase error_database;
7055  MockErrorCollector error_collector;
7056  DescriptorPool pool(&error_database, &error_collector);
7057 
7058  EXPECT_TRUE(pool.FindFileByName("error.proto") == nullptr);
7059  EXPECT_EQ(
7060  "error.proto: error2.proto: IMPORT: File recursively imports itself: "
7061  "error.proto -> error2.proto -> error.proto\n"
7062  "error2.proto: error.proto: IMPORT: Import \"error.proto\" was not "
7063  "found or had errors.\n"
7064  "error.proto: error2.proto: IMPORT: Import \"error2.proto\" was not "
7065  "found or had errors.\n",
7066  error_collector.text_);
7067 }
7068 
7069 TEST_F(DatabaseBackedPoolTest, UndeclaredDependencyOnUnbuiltType) {
7070  // Check that we find and report undeclared dependencies on types that exist
7071  // in the descriptor database but that have not not been built yet.
7072  MockErrorCollector error_collector;
7073  DescriptorPool pool(&database_, &error_collector);
7074  EXPECT_TRUE(pool.FindMessageTypeByName("Baz") == nullptr);
7075  EXPECT_EQ(
7076  "baz.proto: Baz.foo: TYPE: \"Foo\" seems to be defined in \"foo.proto\", "
7077  "which is not imported by \"baz.proto\". To use it here, please add "
7078  "the necessary import.\n",
7079  error_collector.text_);
7080 }
7081 
7082 TEST_F(DatabaseBackedPoolTest, RollbackAfterError) {
7083  // Make sure that all traces of bad types are removed from the pool. This used
7084  // to be b/4529436, due to the fact that a symbol resolution failure could
7085  // potentially cause another file to be recursively built, which would trigger
7086  // a checkpoint _past_ possibly invalid symbols.
7087  // Baz is defined in the database, but the file is invalid because it is
7088  // missing a necessary import.
7089  DescriptorPool pool(&database_);
7090  EXPECT_TRUE(pool.FindMessageTypeByName("Baz") == nullptr);
7091  // Make sure that searching again for the file or the type fails.
7092  EXPECT_TRUE(pool.FindFileByName("baz.proto") == nullptr);
7093  EXPECT_TRUE(pool.FindMessageTypeByName("Baz") == nullptr);
7094 }
7095 
7096 TEST_F(DatabaseBackedPoolTest, UnittestProto) {
7097  // Try to load all of unittest.proto from a DescriptorDatabase. This should
7098  // thoroughly test all paths through DescriptorBuilder to insure that there
7099  // are no deadlocking problems when pool_->mutex_ is non-null.
7100  const FileDescriptor* original_file =
7102 
7105  const FileDescriptor* file_from_database =
7106  pool.FindFileByName(original_file->name());
7107 
7108  ASSERT_TRUE(file_from_database != nullptr);
7109 
7110  FileDescriptorProto original_file_proto;
7111  original_file->CopyTo(&original_file_proto);
7112 
7113  FileDescriptorProto file_from_database_proto;
7114  file_from_database->CopyTo(&file_from_database_proto);
7115 
7116  EXPECT_EQ(original_file_proto.DebugString(),
7117  file_from_database_proto.DebugString());
7118 
7119  // Also verify that CopyTo() did not omit any information.
7120  EXPECT_EQ(original_file->DebugString(), file_from_database->DebugString());
7121 }
7122 
7123 TEST_F(DatabaseBackedPoolTest, DoesntRetryDbUnnecessarily) {
7124  // Searching for a child of an existing descriptor should never fall back
7125  // to the DescriptorDatabase even if it isn't found, because we know all
7126  // children are already loaded.
7127  CallCountingDatabase call_counter(&database_);
7128  DescriptorPool pool(&call_counter);
7129 
7130  const FileDescriptor* file = pool.FindFileByName("foo.proto");
7131  ASSERT_TRUE(file != nullptr);
7132  const Descriptor* foo = pool.FindMessageTypeByName("Foo");
7133  ASSERT_TRUE(foo != nullptr);
7134  const EnumDescriptor* test_enum = pool.FindEnumTypeByName("TestEnum");
7135  ASSERT_TRUE(test_enum != nullptr);
7136  const ServiceDescriptor* test_service = pool.FindServiceByName("TestService");
7137  ASSERT_TRUE(test_service != nullptr);
7138 
7139  EXPECT_NE(0, call_counter.call_count_);
7140  call_counter.Clear();
7141 
7142  EXPECT_TRUE(foo->FindFieldByName("no_such_field") == nullptr);
7143  EXPECT_TRUE(foo->FindExtensionByName("no_such_extension") == nullptr);
7144  EXPECT_TRUE(foo->FindNestedTypeByName("NoSuchMessageType") == nullptr);
7145  EXPECT_TRUE(foo->FindEnumTypeByName("NoSuchEnumType") == nullptr);
7146  EXPECT_TRUE(foo->FindEnumValueByName("NO_SUCH_VALUE") == nullptr);
7147  EXPECT_TRUE(test_enum->FindValueByName("NO_SUCH_VALUE") == nullptr);
7148  EXPECT_TRUE(test_service->FindMethodByName("NoSuchMethod") == nullptr);
7149 
7150  EXPECT_TRUE(file->FindMessageTypeByName("NoSuchMessageType") == nullptr);
7151  EXPECT_TRUE(file->FindEnumTypeByName("NoSuchEnumType") == nullptr);
7152  EXPECT_TRUE(file->FindEnumValueByName("NO_SUCH_VALUE") == nullptr);
7153  EXPECT_TRUE(file->FindServiceByName("NO_SUCH_VALUE") == nullptr);
7154  EXPECT_TRUE(file->FindExtensionByName("no_such_extension") == nullptr);
7155 
7156  EXPECT_TRUE(pool.FindFileContainingSymbol("Foo.no.such.field") == nullptr);
7157  EXPECT_TRUE(pool.FindFileContainingSymbol("Foo.no_such_field") == nullptr);
7158  EXPECT_TRUE(pool.FindMessageTypeByName("Foo.NoSuchMessageType") == nullptr);
7159  EXPECT_TRUE(pool.FindFieldByName("Foo.no_such_field") == nullptr);
7160  EXPECT_TRUE(pool.FindExtensionByName("Foo.no_such_extension") == nullptr);
7161  EXPECT_TRUE(pool.FindEnumTypeByName("Foo.NoSuchEnumType") == nullptr);
7162  EXPECT_TRUE(pool.FindEnumValueByName("Foo.NO_SUCH_VALUE") == nullptr);
7163  EXPECT_TRUE(pool.FindMethodByName("TestService.NoSuchMethod") == nullptr);
7164 
7165  EXPECT_EQ(0, call_counter.call_count_);
7166 }
7167 
7168 TEST_F(DatabaseBackedPoolTest, DoesntReloadFilesUncesessarily) {
7169  // If FindFileContainingSymbol() or FindFileContainingExtension() return a
7170  // file that is already in the DescriptorPool, it should not attempt to
7171  // reload the file.
7172  FalsePositiveDatabase false_positive_database(&database_);
7173  MockErrorCollector error_collector;
7174  DescriptorPool pool(&false_positive_database, &error_collector);
7175 
7176  // First make sure foo.proto is loaded.
7177  const Descriptor* foo = pool.FindMessageTypeByName("Foo");
7178  ASSERT_TRUE(foo != nullptr);
7179 
7180  // Try inducing false positives.
7181  EXPECT_TRUE(pool.FindMessageTypeByName("NoSuchSymbol") == nullptr);
7182  EXPECT_TRUE(pool.FindExtensionByNumber(foo, 22) == nullptr);
7183 
7184  // No errors should have been reported. (If foo.proto was incorrectly
7185  // loaded multiple times, errors would have been reported.)
7186  EXPECT_EQ("", error_collector.text_);
7187 }
7188 
7189 // DescriptorDatabase that attempts to induce exponentially-bad performance
7190 // in DescriptorPool. For every positive N, the database contains a file
7191 // fileN.proto, which defines a message MessageN, which contains fields of
7192 // type MessageK for all K in [0,N). Message0 is not defined anywhere
7193 // (file0.proto exists, but is empty), so every other file and message type
7194 // will fail to build.
7195 //
7196 // If the DescriptorPool is not careful to memoize errors, an attempt to
7197 // build a descriptor for MessageN can require O(2^N) time.
7198 class ExponentialErrorDatabase : public DescriptorDatabase {
7199  public:
7202 
7203  // implements DescriptorDatabase ---------------------------------
7205  FileDescriptorProto* output) override {
7206  int file_num = -1;
7207  FullMatch(filename, "file", ".proto", &file_num);
7208  if (file_num > -1) {
7209  return PopulateFile(file_num, output);
7210  } else {
7211  return false;
7212  }
7213  }
7214  bool FindFileContainingSymbol(const std::string& symbol_name,
7215  FileDescriptorProto* output) override {
7216  int file_num = -1;
7217  FullMatch(symbol_name, "Message", "", &file_num);
7218  if (file_num > 0) {
7219  return PopulateFile(file_num, output);
7220  } else {
7221  return false;
7222  }
7223  }
7225  int field_number,
7226  FileDescriptorProto* output) override {
7227  return false;
7228  }
7229 
7230  private:
7231  void FullMatch(const std::string& name, const std::string& begin_with,
7232  const std::string& end_with, int* file_num) {
7233  int begin_size = begin_with.size();
7234  int end_size = end_with.size();
7235  if (name.substr(0, begin_size) != begin_with ||
7236  name.substr(name.size() - end_size, end_size) != end_with) {
7237  return;
7238  }
7239  safe_strto32(
7240  name.substr(begin_size, name.size() - end_size - begin_size), file_num);
7241  }
7242 
7245  output->Clear();
7246  output->set_name(strings::Substitute("file$0.proto", file_num));
7247  // file0.proto doesn't define Message0
7248  if (file_num > 0) {
7249  DescriptorProto* message = output->add_message_type();
7250  message->set_name(strings::Substitute("Message$0", file_num));
7251  for (int i = 0; i < file_num; ++i) {
7252  output->add_dependency(strings::Substitute("file$0.proto", i));
7253  FieldDescriptorProto* field = message->add_field();
7254  field->set_name(strings::Substitute("field$0", i));
7255  field->set_number(i);
7258  field->set_type_name(strings::Substitute("Message$0", i));
7259  }
7260  }
7261  return true;
7262  }
7263 };
7264 
7265 TEST_F(DatabaseBackedPoolTest, DoesntReloadKnownBadFiles) {
7266  ExponentialErrorDatabase error_database;
7267  DescriptorPool pool(&error_database);
7268 
7269  GOOGLE_LOG(INFO) << "A timeout in this test probably indicates a real bug.";
7270 
7271  EXPECT_TRUE(pool.FindFileByName("file40.proto") == nullptr);
7272  EXPECT_TRUE(pool.FindMessageTypeByName("Message40") == nullptr);
7273 }
7274 
7275 TEST_F(DatabaseBackedPoolTest, DoesntFallbackOnWrongType) {
7276  // If a lookup finds a symbol of the wrong type (e.g. we pass a type name
7277  // to FindFieldByName()), we should fail fast, without checking the fallback
7278  // database.
7279  CallCountingDatabase call_counter(&database_);
7280  DescriptorPool pool(&call_counter);
7281 
7282  const FileDescriptor* file = pool.FindFileByName("foo.proto");
7283  ASSERT_TRUE(file != nullptr);
7284  const Descriptor* foo = pool.FindMessageTypeByName("Foo");
7285  ASSERT_TRUE(foo != nullptr);
7286  const EnumDescriptor* test_enum = pool.FindEnumTypeByName("TestEnum");
7287  ASSERT_TRUE(test_enum != nullptr);
7288 
7289  EXPECT_NE(0, call_counter.call_count_);
7290  call_counter.Clear();
7291 
7292  EXPECT_TRUE(pool.FindMessageTypeByName("TestEnum") == nullptr);
7293  EXPECT_TRUE(pool.FindFieldByName("Foo") == nullptr);
7294  EXPECT_TRUE(pool.FindExtensionByName("Foo") == nullptr);
7295  EXPECT_TRUE(pool.FindEnumTypeByName("Foo") == nullptr);
7296  EXPECT_TRUE(pool.FindEnumValueByName("Foo") == nullptr);
7297  EXPECT_TRUE(pool.FindServiceByName("Foo") == nullptr);
7298  EXPECT_TRUE(pool.FindMethodByName("Foo") == nullptr);
7299 
7300  EXPECT_EQ(0, call_counter.call_count_);
7301 }
7302 
7303 // ===================================================================
7304 
7305 class AbortingErrorCollector : public DescriptorPool::ErrorCollector {
7306  public:
7308 
7310  const Message* message, ErrorLocation location,
7311  const std::string& error_message) override {
7312  GOOGLE_LOG(FATAL) << "AddError() called unexpectedly: " << filename << " ["
7313  << element_name << "]: " << error_message;
7314  }
7315 
7316  private:
7318 };
7319 
7320 // A source tree containing only one file.
7321 class SingletonSourceTree : public compiler::SourceTree {
7322  public:
7325 
7327  return filename == filename_
7328  ? new io::ArrayInputStream(contents_.data(), contents_.size())
7329  : nullptr;
7330  }
7331 
7332  private:
7333  const std::string filename_;
7334  const std::string contents_;
7335 
7337 };
7338 
7339 const char* const kSourceLocationTestInput =
7340  "syntax = \"proto2\";\n"
7341  "option java_package = \"com.foo.bar\";\n"
7342  "option (test_file_opt) = \"foobar\";\n"
7343  "message A {\n"
7344  " option (test_msg_opt) = \"foobar\";\n"
7345  " optional int32 a = 1 [deprecated = true];\n"
7346  " message B {\n"
7347  " required double b = 1 [(test_field_opt) = \"foobar\"];\n"
7348  " }\n"
7349  " oneof c {\n"
7350  " option (test_oneof_opt) = \"foobar\";\n"
7351  " string d = 2;\n"
7352  " string e = 3;\n"
7353  " string f = 4;\n"
7354  " }\n"
7355  "}\n"
7356  "enum Indecision {\n"
7357  " option (test_enum_opt) = 21;\n"
7358  " option (test_enum_opt) = 42;\n"
7359  " option (test_enum_opt) = 63;\n"
7360  " YES = 1 [(test_enumval_opt).a = 100];\n"
7361  " NO = 2 [(test_enumval_opt) = {a:200}];\n"
7362  " MAYBE = 3;\n"
7363  "}\n"
7364  "service S {\n"
7365  " option (test_svc_opt) = {a:100};\n"
7366  " option (test_svc_opt) = {a:200};\n"
7367  " option (test_svc_opt) = {a:300};\n"
7368  " rpc Method(A) returns (A.B);\n"
7369  // Put an empty line here to make the source location range match.
7370  "\n"
7371  " rpc OtherMethod(A) returns (A) {\n"
7372  " option deprecated = true;\n"
7373  " option (test_method_opt) = \"foobar\";\n"
7374  " }\n"
7375  "}\n"
7376  "message MessageWithExtensions {\n"
7377  " extensions 1000 to 2000, 2001 to max [(test_ext_opt) = \"foobar\"];\n"
7378  "}\n"
7379  "extend MessageWithExtensions {\n"
7380  " repeated int32 int32_extension = 1001 [packed=true];\n"
7381  "}\n"
7382  "message C {\n"
7383  " extend MessageWithExtensions {\n"
7384  " optional C message_extension = 1002;\n"
7385  " }\n"
7386  "}\n"
7387  "import \"google/protobuf/descriptor.proto\";\n"
7388  "extend google.protobuf.FileOptions {\n"
7389  " optional string test_file_opt = 10101;\n"
7390  "}\n"
7391  "extend google.protobuf.MessageOptions {\n"
7392  " optional string test_msg_opt = 10101;\n"
7393  "}\n"
7394  "extend google.protobuf.FieldOptions {\n"
7395  " optional string test_field_opt = 10101;\n"
7396  "}\n"
7397  "extend google.protobuf.EnumOptions {\n"
7398  " repeated int32 test_enum_opt = 10101;\n"
7399  "}\n"
7400  "extend google.protobuf.EnumValueOptions {\n"
7401  " optional A test_enumval_opt = 10101;\n"
7402  "}\n"
7403  "extend google.protobuf.ServiceOptions {\n"
7404  " repeated A test_svc_opt = 10101;\n"
7405  "}\n"
7406  "extend google.protobuf.MethodOptions {\n"
7407  " optional string test_method_opt = 10101;\n"
7408  "}\n"
7409  "extend google.protobuf.OneofOptions {\n"
7410  " optional string test_oneof_opt = 10101;\n"
7411  "}\n"
7412  "extend google.protobuf.ExtensionRangeOptions {\n"
7413  " optional string test_ext_opt = 10101;\n"
7414  "}\n";
7415 
7416 class SourceLocationTest : public testing::Test {
7417  public:
7419  : source_tree_("/test/test.proto", kSourceLocationTestInput),
7420  simple_db_(),
7424  // we need descriptor.proto to be accessible by the pool
7425  // since our test file imports it
7426  FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto_);
7428  }
7429 
7431  return strings::Substitute("$0:$1-$2:$3", 1 + loc.start_line,
7432  1 + loc.start_column, 1 + loc.end_line,
7433  1 + loc.end_column);
7434  }
7435 
7436  private:
7440  SimpleDescriptorDatabase simple_db_; // contains descriptor.proto
7442  MergedDescriptorDatabase merged_db_; // combines above two dbs
7443 
7444  protected:
7446 
7447  // tag number of all custom options in above test file
7448  static constexpr int kCustomOptionFieldNumber = 10101;
7449  // tag number of field "a" in message type "A" in above test file
7450  static constexpr int kAFieldNumber = 1;
7451 };
7452 
7453 // TODO(adonovan): implement support for option fields and for
7454 // subparts of declarations.
7455 
7456 TEST_F(SourceLocationTest, GetSourceLocation) {
7458 
7459  const FileDescriptor* file_desc =
7460  GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
7461 
7462  const Descriptor* a_desc = file_desc->FindMessageTypeByName("A");
7463  EXPECT_TRUE(a_desc->GetSourceLocation(&loc));
7464  EXPECT_EQ("4:1-16:2", PrintSourceLocation(loc));
7465 
7466  const Descriptor* a_b_desc = a_desc->FindNestedTypeByName("B");
7467  EXPECT_TRUE(a_b_desc->GetSourceLocation(&loc));
7468  EXPECT_EQ("7:3-9:4", PrintSourceLocation(loc));
7469 
7470  const EnumDescriptor* e_desc = file_desc->FindEnumTypeByName("Indecision");
7471  EXPECT_TRUE(e_desc->GetSourceLocation(&loc));
7472  EXPECT_EQ("17:1-24:2", PrintSourceLocation(loc));
7473 
7474  const EnumValueDescriptor* yes_desc = e_desc->FindValueByName("YES");
7475  EXPECT_TRUE(yes_desc->GetSourceLocation(&loc));
7476  EXPECT_EQ("21:3-21:42", PrintSourceLocation(loc));
7477 
7478  const ServiceDescriptor* s_desc = file_desc->FindServiceByName("S");
7479  EXPECT_TRUE(s_desc->GetSourceLocation(&loc));
7480  EXPECT_EQ("25:1-35:2", PrintSourceLocation(loc));
7481 
7482  const MethodDescriptor* m_desc = s_desc->FindMethodByName("Method");
7483  EXPECT_TRUE(m_desc->GetSourceLocation(&loc));
7484  EXPECT_EQ("29:3-29:31", PrintSourceLocation(loc));
7485 
7486 }
7487 
7488 TEST_F(SourceLocationTest, ExtensionSourceLocation) {
7490 
7491  const FileDescriptor* file_desc =
7492  GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
7493 
7494  const FieldDescriptor* int32_extension_desc =
7495  file_desc->FindExtensionByName("int32_extension");
7496  EXPECT_TRUE(int32_extension_desc->GetSourceLocation(&loc));
7497  EXPECT_EQ("40:3-40:55", PrintSourceLocation(loc));
7498 
7499  const Descriptor* c_desc = file_desc->FindMessageTypeByName("C");
7500  EXPECT_TRUE(c_desc->GetSourceLocation(&loc));
7501  EXPECT_EQ("42:1-46:2", PrintSourceLocation(loc));
7502 
7503  const FieldDescriptor* message_extension_desc =
7504  c_desc->FindExtensionByName("message_extension");
7505  EXPECT_TRUE(message_extension_desc->GetSourceLocation(&loc));
7506  EXPECT_EQ("44:5-44:41", PrintSourceLocation(loc));
7507 }
7508 TEST_F(SourceLocationTest, InterpretedOptionSourceLocation) {
7509  // This one's a doozy. It checks every kind of option, including
7510  // extension range options.
7511 
7512  // We are verifying that the file's source info contains correct
7513  // info for interpreted options and that it does *not* contain
7514  // any info for corresponding uninterpreted option path.
7515 
7517 
7518  const FileDescriptor* file_desc =
7519  GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
7520 
7521  // File options
7522  {
7527 
7528  std::vector<int> vpath(path, path + 2);
7529  EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
7530  EXPECT_EQ("2:1-2:37", PrintSourceLocation(loc));
7531 
7532  std::vector<int> vunint(unint, unint + 3);
7533  EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
7534  }
7535  {
7537  kCustomOptionFieldNumber};
7540  std::vector<int> vpath(path, path + 2);
7541  EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
7542  EXPECT_EQ("3:1-3:35", PrintSourceLocation(loc));
7543 
7544  std::vector<int> vunint(unint, unint + 3);
7545  EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
7546  }
7547 
7548  // Message option
7549  {
7552  kCustomOptionFieldNumber};
7556  std::vector<int> vpath(path, path + 4);
7557  EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
7558  EXPECT_EQ("5:3-5:36", PrintSourceLocation(loc));
7559 
7560  std::vector<int> vunint(unint, unint + 5);
7561  EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
7562  }
7563 
7564  // Field option
7565  {
7567  0,
7569  0,
7573  0,
7575  0,
7578  0};
7579  std::vector<int> vpath(path, path + 6);
7580  EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
7581  EXPECT_EQ("6:25-6:42", PrintSourceLocation(loc));
7582 
7583  std::vector<int> vunint(unint, unint + 7);
7584  EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
7585  }
7586 
7587  // Nested message option
7588  {
7589  int path[] = {
7593  FieldDescriptorProto::kOptionsFieldNumber, kCustomOptionFieldNumber};
7595  0,
7597  0,
7599  0,
7602  0};
7603  std::vector<int> vpath(path, path + 8);
7604  EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
7605  EXPECT_EQ("8:28-8:55", PrintSourceLocation(loc));
7606 
7607  std::vector<int> vunint(unint, unint + 9);
7608  EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
7609  }
7610 
7611  // One-of option
7612  {
7613  int path[] = {
7616  OneofDescriptorProto::kOptionsFieldNumber, kCustomOptionFieldNumber};
7618  0,
7620  0,
7623  0};
7624  std::vector<int> vpath(path, path + 6);
7625  EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
7626  EXPECT_EQ("11:5-11:40", PrintSourceLocation(loc));
7627 
7628  std::vector<int> vunint(unint, unint + 7);
7629  EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
7630  }
7631 
7632  // Enum option, repeated options
7633  {
7636  kCustomOptionFieldNumber, 0};
7640  std::vector<int> vpath(path, path + 5);
7641  EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
7642  EXPECT_EQ("18:3-18:31", PrintSourceLocation(loc));
7643 
7644  std::vector<int> vunint(unint, unint + 5);
7645  EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
7646  }
7647  {
7650  kCustomOptionFieldNumber, 1};
7654  std::vector<int> vpath(path, path + 5);
7655  EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
7656  EXPECT_EQ("19:3-19:31", PrintSourceLocation(loc));
7657 
7658  std::vector<int> vunint(unint, unint + 5);
7659  EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
7660  }
7661  {
7664  kCustomOptionFieldNumber, 2};
7668  std::vector<int> vpath(path, path + 5);
7669  EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
7670  EXPECT_EQ("20:3-20:31", PrintSourceLocation(loc));
7671 
7672  std::vector<int> vunint(unint, unint + 5);
7673  EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
7674  }
7675 
7676  // Enum value options
7677  {
7678  // option w/ message type that directly sets field
7680  0,
7682  0,
7684  kCustomOptionFieldNumber,
7685  kAFieldNumber};
7687  0,
7689  0,
7692  0};
7693  std::vector<int> vpath(path, path + 7);
7694  EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
7695  EXPECT_EQ("21:14-21:40", PrintSourceLocation(loc));
7696 
7697  std::vector<int> vunint(unint, unint + 7);
7698  EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
7699  }
7700  {
7702  0,
7704  1,
7706  kCustomOptionFieldNumber};
7708  0,
7710  1,
7713  0};
7714  std::vector<int> vpath(path, path + 6);
7715  EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
7716  EXPECT_EQ("22:14-22:42", PrintSourceLocation(loc));
7717 
7718  std::vector<int> vunint(unint, unint + 7);
7719  EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
7720  }
7721 
7722  // Service option, repeated options
7723  {
7726  kCustomOptionFieldNumber, 0};
7727  int unint[] = {FileDescriptorProto::kServiceFieldNumber, 0,
7730  std::vector<int> vpath(path, path + 5);
7731  EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
7732  EXPECT_EQ("26:3-26:35", PrintSourceLocation(loc));
7733 
7734  std::vector<int> vunint(unint, unint + 5);
7735  EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
7736  }
7737  {
7740  kCustomOptionFieldNumber, 1};
7741  int unint[] = {FileDescriptorProto::kServiceFieldNumber, 0,
7744  std::vector<int> vpath(path, path + 5);
7745  EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
7746  EXPECT_EQ("27:3-27:35", PrintSourceLocation(loc));
7747 
7748  std::vector<int> vunint(unint, unint + 5);
7749  EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
7750  }
7751  {
7754  kCustomOptionFieldNumber, 2};
7755  int unint[] = {FileDescriptorProto::kServiceFieldNumber, 0,
7758  std::vector<int> vpath(path, path + 5);
7759  EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
7760  EXPECT_EQ("28:3-28:35", PrintSourceLocation(loc));
7761 
7762  std::vector<int> vunint(unint, unint + 5);
7763  EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
7764  }
7765 
7766  // Method options
7767  {
7769  0,
7771  1,
7775  0,
7777  1,
7780  0};
7781  std::vector<int> vpath(path, path + 6);
7782  EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
7783  EXPECT_EQ("32:5-32:30", PrintSourceLocation(loc));
7784 
7785  std::vector<int> vunint(unint, unint + 7);
7786  EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
7787  }
7788  {
7789  int path[] = {
7792  MethodDescriptorProto::kOptionsFieldNumber, kCustomOptionFieldNumber};
7794  0,
7796  1,
7799  1};
7800  std::vector<int> vpath(path, path + 6);
7801  EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
7802  EXPECT_EQ("33:5-33:41", PrintSourceLocation(loc));
7803 
7804  std::vector<int> vunint(unint, unint + 7);
7805  EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
7806  }
7807 
7808  // Extension range options
7809  {
7813  std::vector<int> vpath(path, path + 5);
7814  EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
7815  EXPECT_EQ("37:40-37:67", PrintSourceLocation(loc));
7816  }
7817  {
7819  1,
7821  0,
7823  kCustomOptionFieldNumber};
7825  1,
7827  0,
7830  0};
7831  std::vector<int> vpath(path, path + 6);
7832  EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
7833  EXPECT_EQ("37:41-37:66", PrintSourceLocation(loc));
7834 
7835  std::vector<int> vunint(unint, unint + 7);
7836  EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
7837  }
7838  {
7840  1,
7842  1,
7844  kCustomOptionFieldNumber};
7846  1,
7848  1,
7851  0};
7852  std::vector<int> vpath(path, path + 6);
7853  EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
7854  EXPECT_EQ("37:41-37:66", PrintSourceLocation(loc));
7855 
7856  std::vector<int> vunint(unint, unint + 7);
7857  EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
7858  }
7859 
7860  // Field option on extension
7861  {
7868  std::vector<int> vpath(path, path + 4);
7869  EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
7870  EXPECT_EQ("40:42-40:53", PrintSourceLocation(loc));
7871 
7872  std::vector<int> vunint(unint, unint + 5);
7873  EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
7874  }
7875 }
7876 
7877 // Missing SourceCodeInfo doesn't cause crash:
7878 TEST_F(SourceLocationTest, GetSourceLocation_MissingSourceCodeInfo) {
7880 
7881  const FileDescriptor* file_desc =
7882  GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
7883 
7884  FileDescriptorProto proto;
7885  file_desc->CopyTo(&proto); // Note, this discards the SourceCodeInfo.
7887 
7888  DescriptorPool bad1_pool(&pool_);
7889  const FileDescriptor* bad1_file_desc =
7890  GOOGLE_CHECK_NOTNULL(bad1_pool.BuildFile(proto));
7891  const Descriptor* bad1_a_desc = bad1_file_desc->FindMessageTypeByName("A");
7892  EXPECT_FALSE(bad1_a_desc->GetSourceLocation(&loc));
7893 }
7894 
7895 // Corrupt SourceCodeInfo doesn't cause crash:
7896 TEST_F(SourceLocationTest, GetSourceLocation_BogusSourceCodeInfo) {
7898 
7899  const FileDescriptor* file_desc =
7900  GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
7901 
7902  FileDescriptorProto proto;
7903  file_desc->CopyTo(&proto); // Note, this discards the SourceCodeInfo.
7905  SourceCodeInfo_Location* loc_msg =
7906  proto.mutable_source_code_info()->add_location();
7907  loc_msg->add_path(1);
7908  loc_msg->add_path(2);
7909  loc_msg->add_path(3);
7910  loc_msg->add_span(4);
7911  loc_msg->add_span(5);
7912  loc_msg->add_span(6);
7913 
7914  DescriptorPool bad2_pool(&pool_);
7915  const FileDescriptor* bad2_file_desc =
7916  GOOGLE_CHECK_NOTNULL(bad2_pool.BuildFile(proto));
7917  const Descriptor* bad2_a_desc = bad2_file_desc->FindMessageTypeByName("A");
7918  EXPECT_FALSE(bad2_a_desc->GetSourceLocation(&loc));
7919 }
7920 
7921 // ===================================================================
7922 
7923 const char* const kCopySourceCodeInfoToTestInput =
7924  "syntax = \"proto2\";\n"
7925  "message Foo {}\n";
7926 
7927 // Required since source code information is not preserved by
7928 // FileDescriptorTest.
7929 class CopySourceCodeInfoToTest : public testing::Test {
7930  public:
7932  : source_tree_("/test/test.proto", kCopySourceCodeInfoToTestInput),
7933  db_(&source_tree_),
7934  pool_(&db_, &collector_) {}
7935 
7936  private:
7940 
7941  protected:
7943 };
7944 
7945 TEST_F(CopySourceCodeInfoToTest, CopyTo_DoesNotCopySourceCodeInfo) {
7946  const FileDescriptor* file_desc =
7947  GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
7948  FileDescriptorProto file_desc_proto;
7949  ASSERT_FALSE(file_desc_proto.has_source_code_info());
7950 
7951  file_desc->CopyTo(&file_desc_proto);
7952  EXPECT_FALSE(file_desc_proto.has_source_code_info());
7953 }
7954 
7955 TEST_F(CopySourceCodeInfoToTest, CopySourceCodeInfoTo) {
7956  const FileDescriptor* file_desc =
7957  GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
7958  FileDescriptorProto file_desc_proto;
7959  ASSERT_FALSE(file_desc_proto.has_source_code_info());
7960 
7961  file_desc->CopySourceCodeInfoTo(&file_desc_proto);
7962  const SourceCodeInfo& info = file_desc_proto.source_code_info();
7963  ASSERT_EQ(4, info.location_size());
7964  // Get the Foo message location
7965  const SourceCodeInfo_Location& foo_location = info.location(2);
7966  ASSERT_EQ(2, foo_location.path_size());
7968  EXPECT_EQ(0, foo_location.path(1)); // Foo is the first message defined
7969  ASSERT_EQ(3, foo_location.span_size()); // Foo spans one line
7970  EXPECT_EQ(1, foo_location.span(0)); // Foo is declared on line 1
7971  EXPECT_EQ(0, foo_location.span(1)); // Foo starts at column 0
7972  EXPECT_EQ(14, foo_location.span(2)); // Foo ends on column 14
7973 }
7974 
7975 // ===================================================================
7976 
7977 class LazilyBuildDependenciesTest : public testing::Test {
7978  public:
7981  }
7982 
7983  void ParseProtoAndAddToDb(const char* proto) {
7986  db_.Add(tmp);
7987  }
7988 
7989  void ParseProtoAndAddToDb(const std::string& proto) {
7992  db_.Add(tmp);
7993  }
7994 
7995  void AddSimpleMessageProtoFileToDb(const char* file_name,
7996  const char* message_name) {
7997  ParseProtoAndAddToDb("name: '" + std::string(file_name) +
7998  ".proto' "
7999  "package: \"protobuf_unittest\" "
8000  "message_type { "
8001  " name:'" +
8002  std::string(message_name) +
8003  "' "
8004  " field { name:'a' number:1 "
8005  " label:LABEL_OPTIONAL "
8006  " type_name:'int32' } "
8007  "}");
8008  }
8009 
8010  void AddSimpleEnumProtoFileToDb(const char* file_name, const char* enum_name,
8011  const char* enum_value_name) {
8012  ParseProtoAndAddToDb("name: '" + std::string(file_name) +
8013  ".proto' "
8014  "package: 'protobuf_unittest' "
8015  "enum_type { "
8016  " name:'" +
8017  std::string(enum_name) +
8018  "' "
8019  " value { name:'" +
8020  std::string(enum_value_name) +
8021  "' number:1 } "
8022  "}");
8023  }
8024 
8025  protected:
8028 };
8029 
8030 TEST_F(LazilyBuildDependenciesTest, Message) {
8031  ParseProtoAndAddToDb(
8032  "name: 'foo.proto' "
8033  "package: 'protobuf_unittest' "
8034  "dependency: 'bar.proto' "
8035  "message_type { "
8036  " name:'Foo' "
8037  " field { name:'bar' number:1 label:LABEL_OPTIONAL "
8038  "type_name:'.protobuf_unittest.Bar' } "
8039  "}");
8040  AddSimpleMessageProtoFileToDb("bar", "Bar");
8041 
8042  // Verify neither has been built yet.
8043  EXPECT_FALSE(pool_.InternalIsFileLoaded("foo.proto"));
8044  EXPECT_FALSE(pool_.InternalIsFileLoaded("bar.proto"));
8045 
8046  const FileDescriptor* file = pool_.FindFileByName("foo.proto");
8047 
8048  // Verify only foo gets built when asking for foo.proto
8049  EXPECT_TRUE(file != nullptr);
8050  EXPECT_TRUE(pool_.InternalIsFileLoaded("foo.proto"));
8051  EXPECT_FALSE(pool_.InternalIsFileLoaded("bar.proto"));
8052 
8053  // Verify calling FindFieldBy* works when the type of the field was
8054  // not built at cross link time. Verify this doesn't build the file
8055  // the field's type is defined in, as well.
8056  const Descriptor* desc = file->FindMessageTypeByName("Foo");
8057  const FieldDescriptor* field = desc->FindFieldByName("bar");
8058  EXPECT_TRUE(field != nullptr);
8059  EXPECT_EQ(field, desc->FindFieldByNumber(1));
8060  EXPECT_EQ(field, desc->FindFieldByLowercaseName("bar"));
8061  EXPECT_EQ(field, desc->FindFieldByCamelcaseName("bar"));
8062  EXPECT_FALSE(pool_.InternalIsFileLoaded("bar.proto"));
8063 
8064  // Finally, verify that if we call message_type() on the field, we will
8065  // build the file where the message is defined, and get a valid descriptor
8066  EXPECT_TRUE(field->message_type() != nullptr);
8067  EXPECT_TRUE(pool_.InternalIsFileLoaded("bar.proto"));
8068 }
8069 
8070 TEST_F(LazilyBuildDependenciesTest, Enum) {
8071  ParseProtoAndAddToDb(
8072  "name: 'foo.proto' "
8073  "package: 'protobuf_unittest' "
8074  "dependency: 'enum1.proto' "
8075  "dependency: 'enum2.proto' "
8076  "message_type { "
8077  " name:'Lazy' "
8078  " field { name:'enum1' number:1 label:LABEL_OPTIONAL "
8079  "type_name:'.protobuf_unittest.Enum1' } "
8080  " field { name:'enum2' number:1 label:LABEL_OPTIONAL "
8081  "type_name:'.protobuf_unittest.Enum2' } "
8082  "}");
8083  AddSimpleEnumProtoFileToDb("enum1", "Enum1", "ENUM1");
8084  AddSimpleEnumProtoFileToDb("enum2", "Enum2", "ENUM2");
8085 
8086  const FileDescriptor* file = pool_.FindFileByName("foo.proto");
8087 
8088  // Verify calling enum_type() on a field whose definition is not
8089  // yet built will build the file and return a descriptor.
8090  EXPECT_FALSE(pool_.InternalIsFileLoaded("enum1.proto"));
8091  const Descriptor* desc = file->FindMessageTypeByName("Lazy");
8092  EXPECT_TRUE(desc != nullptr);
8093  const FieldDescriptor* field = desc->FindFieldByName("enum1");
8094  EXPECT_TRUE(field != nullptr);
8095  EXPECT_TRUE(field->enum_type() != nullptr);
8096  EXPECT_TRUE(pool_.InternalIsFileLoaded("enum1.proto"));
8097 
8098  // Verify calling default_value_enum() on a field whose definition is not
8099  // yet built will build the file and return a descriptor to the value.
8100  EXPECT_FALSE(pool_.InternalIsFileLoaded("enum2.proto"));
8101  field = desc->FindFieldByName("enum2");
8102  EXPECT_TRUE(field != nullptr);
8103  EXPECT_TRUE(field->default_value_enum() != nullptr);
8104  EXPECT_TRUE(pool_.InternalIsFileLoaded("enum2.proto"));
8105 }
8106 
8107 TEST_F(LazilyBuildDependenciesTest, Type) {
8108  ParseProtoAndAddToDb(
8109  "name: 'foo.proto' "
8110  "package: 'protobuf_unittest' "
8111  "dependency: 'message1.proto' "
8112  "dependency: 'message2.proto' "
8113  "dependency: 'enum1.proto' "
8114  "dependency: 'enum2.proto' "
8115  "message_type { "
8116  " name:'Lazy' "
8117  " field { name:'message1' number:1 label:LABEL_OPTIONAL "
8118  "type_name:'.protobuf_unittest.Message1' } "
8119  " field { name:'message2' number:1 label:LABEL_OPTIONAL "
8120  "type_name:'.protobuf_unittest.Message2' } "
8121  " field { name:'enum1' number:1 label:LABEL_OPTIONAL "
8122  "type_name:'.protobuf_unittest.Enum1' } "
8123  " field { name:'enum2' number:1 label:LABEL_OPTIONAL "
8124  "type_name:'.protobuf_unittest.Enum2' } "
8125  "}");
8126  AddSimpleMessageProtoFileToDb("message1", "Message1");
8127  AddSimpleMessageProtoFileToDb("message2", "Message2");
8128  AddSimpleEnumProtoFileToDb("enum1", "Enum1", "ENUM1");
8129  AddSimpleEnumProtoFileToDb("enum2", "Enum2", "ENUM2");
8130 
8131  const FileDescriptor* file = pool_.FindFileByName("foo.proto");
8132 
8133  // Verify calling type() on a field that is a message type will
8134  // build the type defined in another file.
8135  EXPECT_FALSE(pool_.InternalIsFileLoaded("message1.proto"));
8136  const Descriptor* desc = file->FindMessageTypeByName("Lazy");
8137  EXPECT_TRUE(desc != nullptr);
8138  const FieldDescriptor* field = desc->FindFieldByName("message1");
8139  EXPECT_TRUE(field != nullptr);
8141  EXPECT_TRUE(pool_.InternalIsFileLoaded("message1.proto"));
8142 
8143  // Verify calling cpp_type() on a field that is a message type will
8144  // build the type defined in another file.
8145  EXPECT_FALSE(pool_.InternalIsFileLoaded("message2.proto"));
8146  field = desc->FindFieldByName("message2");
8147  EXPECT_TRUE(field != nullptr);
8149  EXPECT_TRUE(pool_.InternalIsFileLoaded("message2.proto"));
8150 
8151  // Verify calling type() on a field that is an enum type will
8152  // build the type defined in another file.
8153  EXPECT_FALSE(pool_.InternalIsFileLoaded("enum1.proto"));
8154  field = desc->FindFieldByName("enum1");
8155  EXPECT_TRUE(field != nullptr);
8157  EXPECT_TRUE(pool_.InternalIsFileLoaded("enum1.proto"));
8158 
8159  // Verify calling cpp_type() on a field that is an enum type will
8160  // build the type defined in another file.
8161  EXPECT_FALSE(pool_.InternalIsFileLoaded("enum2.proto"));
8162  field = desc->FindFieldByName("enum2");
8163  EXPECT_TRUE(field != nullptr);
8165  EXPECT_TRUE(pool_.InternalIsFileLoaded("enum2.proto"));
8166 }
8167 
8168 TEST_F(LazilyBuildDependenciesTest, Extension) {
8169  ParseProtoAndAddToDb(
8170  "name: 'foo.proto' "
8171  "package: 'protobuf_unittest' "
8172  "dependency: 'bar.proto' "
8173  "dependency: 'baz.proto' "
8174  "extension { extendee: '.protobuf_unittest.Bar' name:'bar' number:11"
8175  " label:LABEL_OPTIONAL type_name:'.protobuf_unittest.Baz' }");
8176  ParseProtoAndAddToDb(
8177  "name: 'bar.proto' "
8178  "package: 'protobuf_unittest' "
8179  "message_type { "
8180  " name:'Bar' "
8181  " extension_range { start: 10 end: 20 }"
8182  "}");
8183  AddSimpleMessageProtoFileToDb("baz", "Baz");
8184 
8185  // Verify none have been built yet.
8186  EXPECT_FALSE(pool_.InternalIsFileLoaded("foo.proto"));
8187  EXPECT_FALSE(pool_.InternalIsFileLoaded("bar.proto"));
8188  EXPECT_FALSE(pool_.InternalIsFileLoaded("baz.proto"));
8189 
8190  const FileDescriptor* file = pool_.FindFileByName("foo.proto");
8191 
8192  // Verify foo.bar gets loaded, and bar.proto gets loaded
8193  // to register the extension. baz.proto should not get loaded.
8194  EXPECT_TRUE(file != nullptr);
8195  EXPECT_TRUE(pool_.InternalIsFileLoaded("foo.proto"));
8196  EXPECT_TRUE(pool_.InternalIsFileLoaded("bar.proto"));
8197  EXPECT_FALSE(pool_.InternalIsFileLoaded("baz.proto"));
8198 }
8199 
8200 TEST_F(LazilyBuildDependenciesTest, Service) {
8201  ParseProtoAndAddToDb(
8202  "name: 'foo.proto' "
8203  "package: 'protobuf_unittest' "
8204  "dependency: 'message1.proto' "
8205  "dependency: 'message2.proto' "
8206  "dependency: 'message3.proto' "
8207  "dependency: 'message4.proto' "
8208  "service {"
8209  " name: 'LazyService'"
8210  " method { name: 'A' input_type: '.protobuf_unittest.Message1' "
8211  " output_type: '.protobuf_unittest.Message2' }"
8212  "}");
8213  AddSimpleMessageProtoFileToDb("message1", "Message1");
8214  AddSimpleMessageProtoFileToDb("message2", "Message2");
8215  AddSimpleMessageProtoFileToDb("message3", "Message3");
8216  AddSimpleMessageProtoFileToDb("message4", "Message4");
8217 
8218  const FileDescriptor* file = pool_.FindFileByName("foo.proto");
8219 
8220  // Verify calling FindServiceByName or FindMethodByName doesn't build the
8221  // files defining the input and output type, and input_type() and
8222  // output_type() does indeed build the appropriate files.
8223  const ServiceDescriptor* service = file->FindServiceByName("LazyService");
8224  EXPECT_TRUE(service != nullptr);
8225  const MethodDescriptor* method = service->FindMethodByName("A");
8226  EXPECT_FALSE(pool_.InternalIsFileLoaded("message1.proto"));
8227  EXPECT_FALSE(pool_.InternalIsFileLoaded("message2.proto"));
8228  EXPECT_TRUE(method != nullptr);
8229  EXPECT_TRUE(method->input_type() != nullptr);
8230  EXPECT_TRUE(pool_.InternalIsFileLoaded("message1.proto"));
8231  EXPECT_FALSE(pool_.InternalIsFileLoaded("message2.proto"));
8232  EXPECT_TRUE(method->output_type() != nullptr);
8233  EXPECT_TRUE(pool_.InternalIsFileLoaded("message2.proto"));
8234 }
8235 
8236 
8237 TEST_F(LazilyBuildDependenciesTest, GeneratedFile) {
8238  // Most testing is done with custom pools with lazy dependencies forced on,
8239  // do some sanity checking that lazy imports is on by default for the
8240  // generated pool, and do custom options testing with generated to
8241  // be able to use the GetExtension ids for the custom options.
8242 
8243  // Verify none of the files are loaded yet.
8244  EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
8245  "google/protobuf/unittest_lazy_dependencies.proto"));
8246  EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
8247  "google/protobuf/unittest_lazy_dependencies_custom_option.proto"));
8248  EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
8249  "google/protobuf/unittest_lazy_dependencies_enum.proto"));
8250 
8251  // Verify calling autogenerated function to get a descriptor in the base
8252  // file will build that file but none of it's imports. This verifies that
8253  // lazily_build_dependencies_ is set on the generated pool, and also that
8254  // the generated function "descriptor()" doesn't somehow subvert the laziness
8255  // by manually loading the dependencies or something.
8257  nullptr);
8258  EXPECT_TRUE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
8259  "google/protobuf/unittest_lazy_dependencies.proto"));
8260  EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
8261  "google/protobuf/unittest_lazy_dependencies_custom_option.proto"));
8262  EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
8263  "google/protobuf/unittest_lazy_dependencies_enum.proto"));
8264 
8265  // Verify custom options work when defined in an import that isn't loaded,
8266  // and that a non-default value of a custom option doesn't load the file
8267  // where that enum is defined.
8268  const MessageOptions& options =
8270  ->options();
8271  protobuf_unittest::lazy_imports::LazyEnum custom_option_value =
8272  options.GetExtension(protobuf_unittest::lazy_imports::lazy_enum_option);
8273 
8274  EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
8275  "google/protobuf/unittest_lazy_dependencies_custom_option.proto"));
8276  EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
8277  "google/protobuf/unittest_lazy_dependencies_enum.proto"));
8278  EXPECT_EQ(custom_option_value, protobuf_unittest::lazy_imports::LAZY_ENUM_1);
8279 
8280  const MessageOptions& options2 =
8282  ->options();
8283  custom_option_value =
8284  options2.GetExtension(protobuf_unittest::lazy_imports::lazy_enum_option);
8285 
8286  EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
8287  "google/protobuf/unittest_lazy_dependencies_custom_option.proto"));
8288  EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
8289  "google/protobuf/unittest_lazy_dependencies_enum.proto"));
8290  EXPECT_EQ(custom_option_value, protobuf_unittest::lazy_imports::LAZY_ENUM_0);
8291 }
8292 
8293 TEST_F(LazilyBuildDependenciesTest, Dependency) {
8294  ParseProtoAndAddToDb(
8295  "name: 'foo.proto' "
8296  "package: 'protobuf_unittest' "
8297  "dependency: 'bar.proto' "
8298  "message_type { "
8299  " name:'Foo' "
8300  " field { name:'bar' number:1 label:LABEL_OPTIONAL "
8301  "type_name:'.protobuf_unittest.Bar' } "
8302  "}");
8303  ParseProtoAndAddToDb(
8304  "name: 'bar.proto' "
8305  "package: 'protobuf_unittest' "
8306  "dependency: 'baz.proto' "
8307  "message_type { "
8308  " name:'Bar' "
8309  " field { name:'baz' number:1 label:LABEL_OPTIONAL "
8310  "type_name:'.protobuf_unittest.Baz' } "
8311  "}");
8312  AddSimpleMessageProtoFileToDb("baz", "Baz");
8313 
8314  const FileDescriptor* foo_file = pool_.FindFileByName("foo.proto");
8315  EXPECT_TRUE(foo_file != nullptr);
8316  // As expected, requesting foo.proto shouldn't build it's dependencies
8317  EXPECT_TRUE(pool_.InternalIsFileLoaded("foo.proto"));
8318  EXPECT_FALSE(pool_.InternalIsFileLoaded("bar.proto"));
8319  EXPECT_FALSE(pool_.InternalIsFileLoaded("baz.proto"));
8320 
8321  // Verify calling dependency(N) will build the dependency, but
8322  // not that file's dependencies.
8323  const FileDescriptor* bar_file = foo_file->dependency(0);
8324  EXPECT_TRUE(bar_file != nullptr);
8325  EXPECT_TRUE(pool_.InternalIsFileLoaded("bar.proto"));
8326  EXPECT_FALSE(pool_.InternalIsFileLoaded("baz.proto"));
8327 }
8328 
8329 // ===================================================================
8330 
8331 
8332 } // namespace descriptor_unittest
8333 } // namespace protobuf
8334 } // namespace google
8335 
8336 #include <google/protobuf/port_undef.inc>
FileDescriptorProto::name
const std::string & name() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7321
google::protobuf::FieldDescriptor::Type
Type
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:521
google::protobuf::descriptor_unittest::DescriptorPoolMode
DescriptorPoolMode
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:2652
google::protobuf::descriptor_unittest::NestedDescriptorTest::quux2_
const EnumDescriptor * quux2_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1721
EXPECT_FALSE
#define EXPECT_FALSE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1970
grpc::protobuf::DescriptorPoolDatabase
GRPC_CUSTOM_DESCRIPTORPOOLDATABASE DescriptorPoolDatabase
Definition: config_grpc_cli.h:56
google::protobuf::descriptor_unittest::AllowUnknownDependenciesTest::bar_file_
const FileDescriptor * bar_file_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:2734
FieldDescriptorProto_Type
FieldDescriptorProto_Type
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:172
check_grpcio_tools.content
content
Definition: check_grpcio_tools.py:26
FileDescriptorProto::add_message_type
PROTOBUF_NAMESPACE_ID::DescriptorProto * add_message_type()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7692
google::protobuf::python::cdescriptor_pool::FindEnumTypeByName
PyObject * FindEnumTypeByName(PyDescriptorPool *self, PyObject *arg)
Definition: bloaty/third_party/protobuf/python/google/protobuf/pyext/descriptor_pool.cc:318
google::protobuf::descriptor_unittest::AddMessage
DescriptorProto * AddMessage(FileDescriptorProto *file, const std::string &name)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:73
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
google::protobuf::FileDescriptor::is_placeholder
bool is_placeholder() const
google::protobuf::Descriptor::map_key
const FieldDescriptor * map_key() const
Definition: protobuf/src/google/protobuf/descriptor.cc:2320
google::protobuf::descriptor_unittest::LazilyBuildDependenciesTest::ParseProtoAndAddToDb
void ParseProtoAndAddToDb(const char *proto)
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:7983
MethodOptions::kUninterpretedOptionFieldNumber
@ kUninterpretedOptionFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:5824
google::protobuf::descriptor_unittest::EnumDescriptorTest::baz2_
const EnumValueDescriptor * baz2_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1372
google::protobuf::descriptor_unittest::FileDescriptorTest::pool_
DescriptorPool pool_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:376
FileOptions::kJavaPackageFieldNumber
@ kJavaPackageFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:3862
google::protobuf::descriptor_unittest::NestedDescriptorTest::bar_file_
const FileDescriptor * bar_file_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1706
google::protobuf::DescriptorPool::BuildFileCollectingErrors
const FileDescriptor * BuildFileCollectingErrors(const FileDescriptorProto &proto, ErrorCollector *error_collector)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3541
filename
const char * filename
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:135
google::protobuf::descriptor_unittest::NestedDescriptorTest::bar_
const Descriptor * bar_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1712
google::protobuf::descriptor_unittest::DescriptorTest::bar_file_
const FileDescriptor * bar_file_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:778
google::protobuf::descriptor_unittest::ServiceDescriptorTest::foo_request_
const Descriptor * foo_request_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1532
google::protobuf::descriptor_unittest::ExtensionDescriptorTest::qux_
const Descriptor * qux_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1893
google::protobuf::descriptor_unittest::ReservedEnumDescriptorTest::SetUp
void SetUp() override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:2296
SourceCodeInfo_Location::span_size
int span_size() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:13380
google::protobuf.internal::FieldType
uint8 FieldType
Definition: bloaty/third_party/protobuf/src/google/protobuf/extension_set.h:83
google::protobuf::DescriptorPool::ErrorCollector::INPUT_TYPE
@ INPUT_TYPE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1644
google::protobuf::value
const Descriptor::ReservedRange value
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1954
google::protobuf::EnumValueDescriptor::options
const EnumValueOptions & options() const
google::protobuf::descriptor_unittest::ReservedDescriptorTest::pool_
DescriptorPool pool_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:2082
google::protobuf::descriptor_unittest::SourceLocationTest::pool_
DescriptorPool pool_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:7156
google::protobuf::FieldDescriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:515
google::protobuf::FileDescriptor::enum_type
const EnumDescriptor * enum_type(int index) const
google::protobuf::descriptor_unittest::NestedDescriptorTest::a_
const EnumValueDescriptor * a_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1715
google::protobuf::descriptor_unittest::kSourceLocationTestInput
const char *const kSourceLocationTestInput
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:7050
google::protobuf::descriptor_unittest::SourceLocationTest
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:7127
EnumDescriptorProto::kOptionsFieldNumber
@ kOptionsFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:2844
SourceCodeInfo_Location::add_path
void add_path(::PROTOBUF_NAMESPACE_ID::int32 value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:13353
google::protobuf::DescriptorPool::BuildFile
const FileDescriptor * BuildFile(const FileDescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3529
google::protobuf::descriptor_unittest::NestedDescriptorTest::c2_
const EnumValueDescriptor * c2_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1723
google::protobuf::descriptor_unittest::ServiceDescriptorTest::SetUp
void SetUp() override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:1520
DescriptorProto::kOneofDeclFieldNumber
@ kOneofDeclFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1453
google::protobuf::descriptor_unittest::ValidationErrorTest::pool_
DescriptorPool pool_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:3669
google::protobuf::descriptor_unittest::StylizedFieldNamesTest::SetUp
void SetUp() override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:1200
google::protobuf::descriptor_unittest::ServiceDescriptorTest::bar_response_
const Descriptor * bar_response_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1535
google::protobuf::extension
const Descriptor::ReservedRange const EnumValueDescriptor const MethodDescriptor extension
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:2001
file
const grpc_generator::File * file
Definition: python_private_generator.h:38
google::protobuf::MethodDescriptor::GetSourceLocation
bool GetSourceLocation(SourceLocation *out_location) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2996
google::protobuf::compiler::Parser
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/compiler/parser.h:68
ServiceOptions::kUninterpretedOptionFieldNumber
@ kUninterpretedOptionFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:5606
google::protobuf::descriptor_unittest::ExponentialErrorDatabase::FindFileContainingSymbol
bool FindFileContainingSymbol(const std::string &symbol_name, FileDescriptorProto *output) override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:7214
EnumValueDescriptorProto::set_name
void set_name(const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10004
google::protobuf::descriptor_unittest::ExtensionDescriptorTest::foo_file_
const FileDescriptor * foo_file_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1888
EnumDescriptorProto::add_reserved_range
PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange * add_reserved_range()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9900
google::protobuf::compiler::cpp::FieldName
std::string FieldName(const FieldDescriptor *field)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.cc:416
google::protobuf::python::cdescriptor_pool::FindFileByName
static PyObject * FindFileByName(PyObject *self, PyObject *arg)
Definition: bloaty/third_party/protobuf/python/google/protobuf/pyext/descriptor_pool.cc:258
google::protobuf::int64
int64_t int64
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/stubs/port.h:151
element_name
std::string element_name
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3096
google::protobuf::safe_strto32
bool safe_strto32(const string &str, int32 *value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/strutil.cc:1366
EXPECT_THAT
#define EXPECT_THAT(value, matcher)
google::protobuf::descriptor_unittest::DatabaseBackedPoolTest::FalsePositiveDatabase::FindFileByName
bool FindFileByName(const std::string &filename, FileDescriptorProto *output) override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:6919
google::protobuf::descriptor_unittest::AddService
ServiceDescriptorProto * AddService(FileDescriptorProto *file, const std::string &name)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:101
google::protobuf::descriptor_unittest::MockErrorCollector::~MockErrorCollector
~MockErrorCollector()
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:201
google::protobuf::descriptor_unittest::ValidationErrorTest::BuildDescriptorMessagesInTestPool
void BuildDescriptorMessagesInTestPool()
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:3869
google::protobuf::DescriptorPool::ErrorCollector::IMPORT
@ IMPORT
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1648
FileDescriptorProto::source_code_info
const PROTOBUF_NAMESPACE_ID::SourceCodeInfo & source_code_info() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7905
FieldOptions::kUninterpretedOptionFieldNumber
@ kUninterpretedOptionFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:4787
google::protobuf::descriptor_unittest::AllowUnknownDependenciesTest::qux_field_
const FieldDescriptor * qux_field_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:2740
google::protobuf::FileDescriptor::SYNTAX_PROTO2
@ SYNTAX_PROTO2
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1393
google::protobuf::descriptor_unittest::DatabaseBackedPoolTest::ErrorDescriptorDatabase::ErrorDescriptorDatabase
ErrorDescriptorDatabase()
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:6839
google::protobuf::descriptor_unittest::AllowUnknownDependenciesTest::mode
DescriptorPoolMode mode()
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:2819
google::protobuf::EnumDescriptor::value_count
int value_count() const
google::protobuf::io::Tokenizer
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/tokenizer.h:93
google::protobuf::descriptor_unittest::AddExtension
FieldDescriptorProto * AddExtension(FileDescriptorProto *file, const std::string &extendee, const std::string &name, int number, FieldDescriptorProto::Label label, FieldDescriptorProto::Type type)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:119
FieldOptions
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:4590
google::protobuf::descriptor_unittest::DescriptorTest::map_
const FieldDescriptor * map_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:798
bar
Definition: bloaty/third_party/googletest/googletest/test/googletest-output-test_.cc:562
google::protobuf::descriptor_unittest::MiscTest::GetTypeNameForFieldType
const char * GetTypeNameForFieldType(FieldDescriptor::Type type)
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:2456
file_
FileDescriptorProto * file_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/annotation_test_util.cc:68
options
double_dict options[]
Definition: capstone_test.c:55
google::protobuf::descriptor_unittest::FileDescriptorTest::bar_file_
const FileDescriptor * bar_file_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:379
google::protobuf::descriptor_unittest::LazilyBuildDependenciesTest::pool_
DescriptorPool pool_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:7738
google::protobuf::descriptor_unittest::ServiceDescriptorTest::baz2_
const MethodDescriptor * baz2_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1546
DescriptorProto::descriptor
static const ::PROTOBUF_NAMESPACE_ID::Descriptor * descriptor()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1350
google::protobuf::FileDescriptor::FindServiceByName
const ServiceDescriptor * FindServiceByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1745
google::protobuf::descriptor_unittest::NestedDescriptorTest::a2_
const EnumValueDescriptor * a2_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1722
google::protobuf::descriptor_unittest::SourceLocationTest::SourceLocationTest
SourceLocationTest()
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:7418
names
sub_type names
Definition: cxa_demangle.cpp:4905
UninterpretedOption
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:6089
google::protobuf::descriptor_unittest::DescriptorTest::message2_
const Descriptor * message2_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:783
FieldDescriptorProto
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1851
google::protobuf::descriptor_unittest::EnumDescriptorTest::pool_
DescriptorPool pool_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1360
google::protobuf::Descriptor::GetSourceLocation
bool GetSourceLocation(SourceLocation *out_location) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2972
FileOptions::kUninterpretedOptionFieldNumber
@ kUninterpretedOptionFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:3861
google::protobuf::descriptor_unittest::ReservedDescriptorTest::foo_file_
const FileDescriptor * foo_file_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:2083
FileDescriptorProto::set_syntax
void set_syntax(const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7971
FileDescriptor
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:128
DebugString
std::string DebugString(const google::protobuf::Message &message)
Definition: bloaty/tests/test.h:60
google::protobuf::descriptor_unittest::OneofDescriptorTest::b_
const FieldDescriptor * b_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1105
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
google::protobuf::descriptor_unittest::DescriptorTest::bar2_
const FieldDescriptor * bar2_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:795
google::protobuf::descriptor_unittest::LazilyBuildDependenciesTest::AddSimpleEnumProtoFileToDb
void AddSimpleEnumProtoFileToDb(const char *file_name, const char *enum_name, const char *enum_value_name)
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:8010
google::protobuf::Descriptor::nested_type_count
int nested_type_count() const
google::protobuf::descriptor_unittest::LazilyBuildDependenciesTest::LazilyBuildDependenciesTest
LazilyBuildDependenciesTest()
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:7979
google::protobuf::descriptor_unittest::AllowUnknownDependenciesTest::BuildFile
const FileDescriptor * BuildFile(const FileDescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:2720
google::protobuf::descriptor_unittest::OneofDescriptorTest::oneof_
const OneofDescriptor * oneof_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1102
google::protobuf::descriptor_unittest::ServiceDescriptorTest::foo2_
const MethodDescriptor * foo2_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1545
google::protobuf::descriptor_unittest::ReservedEnumDescriptorTest::foo_
const EnumDescriptor * foo_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:2181
DescriptorProto::add_extension_range
PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange * add_extension_range()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8518
google::protobuf::descriptor_unittest::ServiceDescriptorTest::service2_
const ServiceDescriptor * service2_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1540
google::protobuf::descriptor_unittest::MiscTest::GetCppTypeNameForFieldType
const char * GetCppTypeNameForFieldType(FieldDescriptor::Type type)
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:2467
loc
OPENSSL_EXPORT X509_EXTENSION int loc
Definition: x509.h:1418
google::protobuf::descriptor_unittest::ExponentialErrorDatabase::PopulateFile
bool PopulateFile(int file_num, FileDescriptorProto *output)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:6952
FileDescriptorProto::kExtensionFieldNumber
@ kExtensionFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:638
google::protobuf::descriptor_unittest::AllowUnknownDependenciesTest::baz_field_
const FieldDescriptor * baz_field_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:2739
file
Definition: bloaty/third_party/zlib/examples/gzappend.c:170
ASSERT_GE
#define ASSERT_GE(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2072
ServiceDescriptorProto
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:3186
c_
char c_
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:921
SourceCodeInfo_Location::span
::PROTOBUF_NAMESPACE_ID::int32 span(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:13389
google::protobuf
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:12
google::protobuf::descriptor_unittest::AddNestedMessage
DescriptorProto * AddNestedMessage(DescriptorProto *parent, const std::string &name)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:80
FileDescriptorProto::kMessageTypeFieldNumber
@ kMessageTypeFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:635
google::protobuf::descriptor_unittest::SourceLocationTest::kAFieldNumber
static const int kAFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:7161
google::protobuf::descriptor_unittest::ExponentialErrorDatabase::FindFileContainingExtension
bool FindFileContainingExtension(const std::string &containing_type, int field_number, FileDescriptorProto *output) override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:7224
visited
bool visited
Definition: abseil-cpp/absl/synchronization/internal/graphcycles.cc:282
Syntax
Syntax
Definition: bloaty/third_party/protobuf/src/google/protobuf/type.pb.h:155
foo
Definition: bloaty/third_party/googletest/googletest/test/googletest-output-test_.cc:546
google::protobuf::descriptor_unittest::NestedDescriptorTest::foo_
const Descriptor * foo_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1711
google::protobuf::descriptor_unittest::EnumDescriptorTest::SetUp
void SetUp() override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:1369
google::protobuf::DescriptorPool::ErrorCollector::NUMBER
@ NUMBER
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1640
FieldDescriptorProto::set_default_value
void set_default_value(const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9176
FieldDescriptorProto::type_name
const std::string & type_name() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8986
google::protobuf::descriptor_unittest::ExtensionDescriptorTest::baz_
const EnumDescriptor * baz_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1892
mode
const char int mode
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:135
google::protobuf::OneofDescriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:843
pool_
DescriptorPool pool_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/parser_unittest.cc:181
FileDescriptorProto::add_dependency
std::string * add_dependency()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7505
MethodDescriptorProto
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:3405
setup.name
name
Definition: setup.py:542
google::protobuf::descriptor_unittest::DescriptorTest::pool_
DescriptorPool pool_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:775
google::protobuf::descriptor_unittest::SourceLocationTest::simple_db_
SimpleDescriptorDatabase simple_db_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:7151
google::protobuf::EnumDescriptor::FindValueByName
const EnumValueDescriptor * FindValueByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1683
google::protobuf::DescriptorDatabase::FindFileContainingExtension
virtual bool FindFileContainingExtension(const std::string &containing_type, int field_number, FileDescriptorProto *output)=0
google::protobuf::descriptor_unittest::ServiceDescriptorTest::bar_file_
const FileDescriptor * bar_file_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1530
grpc::protobuf::DescriptorPool
GRPC_CUSTOM_DESCRIPTORPOOL DescriptorPool
Definition: include/grpcpp/impl/codegen/config_protobuf.h:82
check_documentation.path
path
Definition: check_documentation.py:57
google::protobuf::compiler::SourceTreeDescriptorDatabase
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/importer.h:80
google::protobuf::descriptor_unittest::ExponentialErrorDatabase::FindFileByName
bool FindFileByName(const std::string &filename, FileDescriptorProto *output) override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:7204
OneofDescriptorProto::kOptionsFieldNumber
@ kOptionsFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:2462
google::protobuf::descriptor_unittest::ValidationErrorTest
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:3619
google::protobuf::SourceLocation
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:145
google::protobuf::FieldDescriptor::LABEL_OPTIONAL
@ LABEL_OPTIONAL
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:572
google::protobuf::descriptor_unittest::LazilyBuildDependenciesTest::ParseProtoAndAddToDb
void ParseProtoAndAddToDb(const std::string &proto)
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:7989
SourceCodeInfo::location_size
int location_size() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:13691
google::protobuf::kint64min
static const int64 kint64min
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/stubs/port.h:162
google::protobuf::FieldDescriptor::TYPE_GROUP
@ TYPE_GROUP
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:535
google::protobuf::descriptor_unittest::DescriptorTest::foo_
const FieldDescriptor * foo_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:789
FileDescriptorProto::kOptionsFieldNumber
@ kOptionsFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:644
google::protobuf::DescriptorPool::ErrorCollector::OPTION_NAME
@ OPTION_NAME
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1646
google::protobuf::MergedDescriptorDatabase
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_database.h:371
google::protobuf::DescriptorPool::InternalSetLazilyBuildDependencies
void InternalSetLazilyBuildDependencies()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1768
google::protobuf::descriptor_unittest::DescriptorTest::message3_
const Descriptor * message3_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:784
ServiceDescriptorProto::kMethodFieldNumber
@ kMethodFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:3319
DescriptorProto::Clear
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.cc:2957
message
char * message
Definition: libuv/docs/code/tty-gravity/main.c:12
FieldOptions::default_instance
static const FieldOptions & default_instance()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.cc:7687
google::protobuf::python::cdescriptor_pool::FindServiceByName
static PyObject * FindServiceByName(PyObject *self, PyObject *arg)
Definition: bloaty/third_party/protobuf/python/google/protobuf/pyext/descriptor_pool.cc:360
google::protobuf::descriptor_unittest::ExponentialErrorDatabase::ExponentialErrorDatabase
ExponentialErrorDatabase()
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:7200
EnumValueDescriptorProto
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:2972
google::protobuf::descriptor_unittest::SourceLocationTest::merged_db_
MergedDescriptorDatabase merged_db_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:7153
Enum
Definition: bloaty/third_party/protobuf/src/google/protobuf/type.pb.h:867
Descriptor
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:121
google::protobuf::descriptor_unittest::ServiceDescriptorTest::pool_
DescriptorPool pool_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1527
testing::Test
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:402
google::protobuf::descriptor_unittest::ServiceDescriptorTest::baz_response_
const Descriptor * baz_response_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1537
FieldDescriptorProto::TYPE_GROUP
static constexpr Type TYPE_GROUP
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:2000
FieldOptions::CORD
static constexpr CType CORD
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:4723
google::protobuf::descriptor_unittest::CopySourceCodeInfoToTest::source_tree_
SingletonSourceTree source_tree_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:7649
testing::TestWithParam
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1883
google::protobuf::FileDescriptor::enum_type_count
int enum_type_count() const
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
testing::ElementsAre
internal::ElementsAreMatcher< ::testing::tuple<> > ElementsAre()
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:13040
google::protobuf::descriptor_unittest::SourceLocationTest::source_tree_db_
compiler::SourceTreeDescriptorDatabase source_tree_db_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:7152
render.file_num
int file_num
Definition: render.py:24
EnumDescriptorProto_EnumReservedRange
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:2527
google::protobuf::FileDescriptor::FindMessageTypeByName
const Descriptor * FindMessageTypeByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1714
google::protobuf::descriptor_unittest::MiscTest::GetFieldDescriptorOfType
const FieldDescriptor * GetFieldDescriptorOfType(FieldDescriptor::Type type)
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:2427
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
google::protobuf::descriptor_unittest::DescriptorTest::CopyWithJsonName
void CopyWithJsonName(const Descriptor *message, DescriptorProto *proto)
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:774
google::protobuf::descriptor_unittest::SingletonSourceTree
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:7032
google::protobuf::EnumValueDescriptor::name
const std::string & name() const
google::protobuf::DescriptorPool::ErrorCollector::NAME
@ NAME
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1639
google::protobuf::FileDescriptor::SYNTAX_PROTO3
@ SYNTAX_PROTO3
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1394
google::protobuf::descriptor_unittest::AddNestedExtension
FieldDescriptorProto * AddNestedExtension(DescriptorProto *parent, const std::string &extendee, const std::string &name, int number, FieldDescriptorProto::Label label, FieldDescriptorProto::Type type)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:133
google::protobuf::descriptor_unittest::DescriptorTest::SetUp
void SetUp() override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:617
google::protobuf::descriptor_unittest::AbortingErrorCollector::AbortingErrorCollector
AbortingErrorCollector()
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:7307
DescriptorProto::kFieldFieldNumber
@ kFieldFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1448
FieldDescriptor
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:133
google::protobuf::descriptor_unittest::NestedDescriptorTest::qux2_
const EnumDescriptor * qux2_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1720
google::protobuf::FieldDescriptor::TYPE_ENUM
@ TYPE_ENUM
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:540
google::protobuf::descriptor_unittest::DatabaseBackedPoolTest::FalsePositiveDatabase::FindFileByName
bool FindFileByName(const std::string &filename, FileDescriptorProto *output)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:6628
google::protobuf.internal.python_message.Extensions
Extensions
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/python_message.py:584
google::protobuf::FileDescriptor::FindEnumTypeByName
const EnumDescriptor * FindEnumTypeByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1724
DescriptorProto::kOptionsFieldNumber
@ kOptionsFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1457
google::protobuf::Descriptor::field
const FieldDescriptor * field(int index) const
google::protobuf::ServiceDescriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1152
google::protobuf::python::cdescriptor_pool::FindFileContainingSymbol
static PyObject * FindFileContainingSymbol(PyObject *self, PyObject *arg)
Definition: bloaty/third_party/protobuf/python/google/protobuf/pyext/descriptor_pool.cc:400
start
static uint64_t start
Definition: benchmark-pound.c:74
google::protobuf::python::cdescriptor_pool::FindExtensionByNumber
static PyObject * FindExtensionByNumber(PyObject *self, PyObject *args)
Definition: bloaty/third_party/protobuf/python/google/protobuf/pyext/descriptor_pool.cc:420
google::protobuf::descriptor_unittest::FileDescriptorTest::bar_extension_
const FieldDescriptor * bar_extension_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:392
EnumDescriptorProto::kValueFieldNumber
@ kValueFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:2840
google::protobuf::descriptor_unittest::DatabaseBackedPoolTest::FalsePositiveDatabase::wrapped_db_
DescriptorDatabase * wrapped_db_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:6625
google::protobuf::descriptor_unittest::ValidationErrorTest::BuildFileWithErrors
void BuildFileWithErrors(const std::string &file_text, const std::string &expected_errors)
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:3836
google::protobuf::descriptor_unittest::MockErrorCollector::AddError
void AddError(const std::string &filename, const std::string &element_name, const Message *descriptor, ErrorLocation location, const std::string &message) override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:207
DescriptorProto::kExtensionRangeFieldNumber
@ kExtensionRangeFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1451
FieldDescriptorProto::LABEL_OPTIONAL
static constexpr Label LABEL_OPTIONAL
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:2044
google::protobuf::descriptor_unittest::EnumDescriptorTest::bar_file_
const FileDescriptor * bar_file_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1363
asyncio_get_stats.parser
parser
Definition: asyncio_get_stats.py:34
google::protobuf::python::service_descriptor::FindMethodByName
static PyObject * FindMethodByName(PyBaseDescriptor *self, PyObject *arg)
Definition: bloaty/third_party/protobuf/python/google/protobuf/pyext/descriptor.cc:1685
google::protobuf::descriptor_unittest::DatabaseBackedPoolTest::database_
SimpleDescriptorDatabase database_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:6519
DescriptorProto_ExtensionRange
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:936
google::protobuf::descriptor_unittest::SourceLocationTest::collector_
AbortingErrorCollector collector_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:7149
google::protobuf::descriptor_unittest::AllowUnknownDependenciesTest::bar_type_
const Descriptor * bar_type_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:2735
errors
const char * errors
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/tokenizer_unittest.cc:841
end
char * end
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1008
FieldDescriptorProto::TYPE_INT32
static constexpr Type TYPE_INT32
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1990
google::protobuf::descriptor_unittest::SimpleErrorCollector::last_error_
std::string last_error_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:573
google::protobuf::descriptor_unittest::SingletonSourceTree::SingletonSourceTree
SingletonSourceTree(const std::string &filename, const std::string &contents)
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:7323
google::protobuf::descriptor_unittest::NestedDescriptorTest::foo_file_
const FileDescriptor * foo_file_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1705
DescriptorProto::add_reserved_range
PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange * add_reserved_range()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8664
FileDescriptorProto::kEnumTypeFieldNumber
@ kEnumTypeFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:636
google::protobuf::descriptor_unittest::MiscTest::GetEnumDescriptorForFieldType
const EnumDescriptor * GetEnumDescriptorForFieldType(FieldDescriptor::Type type)
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:2478
google::protobuf::descriptor_unittest::DatabaseBackedPoolTest::CallCountingDatabase::wrapped_db_
DescriptorDatabase * wrapped_db_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:6590
google::protobuf::descriptor_unittest::LazilyBuildDependenciesTest::AddSimpleMessageProtoFileToDb
void AddSimpleMessageProtoFileToDb(const char *file_name, const char *message_name)
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:7995
google::protobuf::descriptor_unittest::EnumDescriptorTest::bar_
const EnumValueDescriptor * bar_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1369
FieldDescriptorProto::TYPE_DOUBLE
static constexpr Type TYPE_DOUBLE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1982
gen_synthetic_protos.label
label
Definition: gen_synthetic_protos.py:102
google::protobuf::descriptor_unittest::DatabaseBackedPoolTest::SetUp
void SetUp() override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:6812
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
google::protobuf::descriptor_unittest::SingletonSourceTree::Open
io::ZeroCopyInputStream * Open(const std::string &filename) override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:7326
max
int max
Definition: bloaty/third_party/zlib/examples/enough.c:170
gmock_output_test.output
output
Definition: bloaty/third_party/googletest/googlemock/test/gmock_output_test.py:175
Type
Definition: bloaty/third_party/protobuf/src/google/protobuf/type.pb.h:182
python_utils.jobset.INFO
INFO
Definition: jobset.py:111
google::protobuf::FileDescriptor::service
const ServiceDescriptor * service(int index) const
EXPECT_NE
#define EXPECT_NE(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2028
google::protobuf::python::GetMap
static MapContainer * GetMap(PyObject *obj)
Definition: bloaty/third_party/protobuf/python/google/protobuf/pyext/map_container.cc:307
google::protobuf::python::cdescriptor_pool::FindFieldByName
PyObject * FindFieldByName(PyDescriptorPool *self, PyObject *arg)
Definition: bloaty/third_party/protobuf/python/google/protobuf/pyext/descriptor_pool.cc:275
google::protobuf::descriptor_unittest::FileDescriptorTest::bar_message_
const Descriptor * bar_message_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:388
google::protobuf::descriptor_unittest::CopySourceCodeInfoToTest::pool_
DescriptorPool pool_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:7653
FieldDescriptorProto::mutable_options
PROTOBUF_NAMESPACE_ID::FieldOptions * mutable_options()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9418
google::protobuf::descriptor_unittest::NestedDescriptorTest::pool_
DescriptorPool pool_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1703
FieldDescriptorProto::type
PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type type() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8960
GOOGLE_CHECK_NOTNULL
#define GOOGLE_CHECK_NOTNULL(A)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/logging.h:173
FileDescriptorProto::set_name
void set_name(const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7325
google::protobuf::descriptor_unittest::TEST_F
TEST_F(FileDescriptorTest, Name)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:395
DescriptorProto::add_field
PROTOBUF_NAMESPACE_ID::FieldDescriptorProto * add_field()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8362
google::protobuf::python::cdescriptor_pool::FindExtensionByName
PyObject * FindExtensionByName(PyDescriptorPool *self, PyObject *arg)
Definition: bloaty/third_party/protobuf/python/google/protobuf/pyext/descriptor_pool.cc:296
google::protobuf::descriptor_unittest::DescriptorTest::foo2_
const FieldDescriptor * foo2_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:794
google::protobuf::DescriptorPool::ErrorCollector::OUTPUT_TYPE
@ OUTPUT_TYPE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1645
google::protobuf::descriptor_unittest::DescriptorTest::FindValueByNumberCreatingIfUnknown
const EnumValueDescriptor * FindValueByNumberCreatingIfUnknown(const EnumDescriptor *desc, int number)
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:779
google::protobuf::descriptor_unittest::LazilyBuildDependenciesTest::db_
SimpleDescriptorDatabase db_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:7737
google::protobuf::descriptor_unittest::AllowUnknownDependenciesTest::foo_file_
const FileDescriptor * foo_file_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:2736
google::protobuf::descriptor_unittest::FileDescriptorTest::foo_enum_value_
const EnumValueDescriptor * foo_enum_value_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:384
GOOGLE_CHECK_GE
#define GOOGLE_CHECK_GE(A, B)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/logging.h:161
MessageOptions::kUninterpretedOptionFieldNumber
@ kUninterpretedOptionFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:4492
google::protobuf::descriptor_unittest::AbortingErrorCollector
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:7015
google::protobuf::descriptor_unittest::EnumDescriptorTest::foo_file_
const FileDescriptor * foo_file_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1362
google::protobuf::descriptor_unittest::AddReservedRange
DescriptorProto::ReservedRange * AddReservedRange(DescriptorProto *parent, int start, int end)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:155
FileDescriptorProto::set_package
void set_package(const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7418
grpc::protobuf::MethodDescriptor
GRPC_CUSTOM_METHODDESCRIPTOR MethodDescriptor
Definition: include/grpcpp/impl/codegen/config_protobuf.h:87
google::protobuf::TextFormat::ParseFromString
static bool ParseFromString(const std::string &input, Message *output)
Definition: bloaty/third_party/protobuf/src/google/protobuf/text_format.cc:1485
FileDescriptorProto::kServiceFieldNumber
@ kServiceFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:637
google::protobuf::Descriptor::oneof_decl
const OneofDescriptor * oneof_decl(int index) const
uint64_t
unsigned __int64 uint64_t
Definition: stdint-msvc2008.h:90
google::protobuf::descriptor_unittest::ServiceDescriptorTest::foo_
const MethodDescriptor * foo_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1542
google::protobuf::descriptor_unittest::SingletonSourceTree::contents_
const std::string contents_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:7045
google::protobuf::descriptor_unittest::SimpleErrorCollector::AddError
void AddError(int line, int column, const std::string &message) override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:568
google::protobuf::descriptor_unittest::FileDescriptorTest::foo_extension_
const FieldDescriptor * foo_extension_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:386
google::protobuf::DescriptorPool::ErrorCollector::ErrorLocation
ErrorLocation
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1638
google::protobuf::EnumDescriptor::value
const EnumValueDescriptor * value(int index) const
google::protobuf::FieldDescriptor::LABEL_REQUIRED
@ LABEL_REQUIRED
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:573
google::protobuf::DescriptorPool
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1539
google::protobuf::StringPrintf
string StringPrintf(const char *format,...)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/stringprintf.cc:109
FieldDescriptorProto::LABEL_REPEATED
static constexpr Label LABEL_REPEATED
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:2048
MessageOptions
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:4359
google::protobuf::util::converter::IsMap
bool IsMap(const google::protobuf::Field &field, const google::protobuf::Type &type)
Definition: bloaty/third_party/protobuf/src/google/protobuf/util/internal/utility.cc:360
google::protobuf::descriptor_unittest::CopySourceCodeInfoToTest::collector_
AbortingErrorCollector collector_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:7648
google::protobuf::descriptor_unittest::DatabaseBackedPoolTest::FalsePositiveDatabase::~FalsePositiveDatabase
~FalsePositiveDatabase()
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:6914
google::protobuf::FileDescriptor::CopySourceCodeInfoTo
void CopySourceCodeInfoTo(FileDescriptorProto *proto) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2040
DescriptorProto::add_oneof_decl
PROTOBUF_NAMESPACE_ID::OneofDescriptorProto * add_oneof_decl()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8557
google::protobuf::descriptor_unittest::MockErrorCollector::MockErrorCollector
MockErrorCollector()
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:200
google::protobuf::descriptor_unittest::FileDescriptorTest::SetUp
void SetUp() override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:302
google::protobuf::Descriptor::oneof_decl_count
int oneof_decl_count() const
google::protobuf::descriptor_unittest::DatabaseBackedPoolTest::CallCountingDatabase::call_count_
int call_count_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:6592
number
int32_t number
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:850
FieldDescriptorProto::TYPE_STRING
static constexpr Type TYPE_STRING
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1998
google::protobuf::FieldDescriptor::number
int number() const
google::protobuf::descriptor_unittest::ServiceDescriptorTest::foo_response_
const Descriptor * foo_response_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1533
google::protobuf::descriptor_unittest::SimpleErrorCollector::last_error
const std::string & last_error()
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:572
google::protobuf::descriptor_unittest::NestedDescriptorTest::qux_
const EnumDescriptor * qux_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1714
google::protobuf::Descriptor::extension_count
int extension_count() const
database
database
Definition: benchmark/.ycm_extra_conf.py:35
EnumValueDescriptor
Definition: protobuf/php/ext/google/protobuf/def.c:63
google::protobuf::Descriptor::enum_type
const EnumDescriptor * enum_type(int index) const
google::protobuf::descriptor_unittest::FileDescriptorTest::bar_enum_
const EnumDescriptor * bar_enum_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:389
google::protobuf::io::ArrayInputStream
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.h:66
google::protobuf::descriptor_unittest::DatabaseBackedPoolTest::ErrorDescriptorDatabase::FindFileContainingExtension
bool FindFileContainingExtension(const std::string &containing_type, int field_number, FileDescriptorProto *output) override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:6864
FileDescriptorProto::descriptor
static const ::PROTOBUF_NAMESPACE_ID::Descriptor * descriptor()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:539
FileOptions::SPEED
static constexpr OptimizeMode SPEED
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:3827
google::protobuf::uint64
uint64_t uint64
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/stubs/port.h:156
google::protobuf::FieldDescriptor::LABEL_REPEATED
@ LABEL_REPEATED
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:574
google::protobuf::descriptor_unittest::NO_DATABASE
@ NO_DATABASE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:2652
google::protobuf::descriptor_unittest::SingletonSourceTree::GOOGLE_DISALLOW_EVIL_CONSTRUCTORS
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SingletonSourceTree)
google::protobuf::descriptor_unittest::FileDescriptorTest::bar_service_
const ServiceDescriptor * bar_service_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:391
google::protobuf::descriptor_unittest::kCopySourceCodeInfoToTestInput
const char *const kCopySourceCodeInfoToTestInput
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:7634
absl::flags_internal::Package
absl::string_view Package(absl::string_view filename)
Definition: abseil-cpp/absl/flags/internal/path_util.h:50
EnumOptions::kUninterpretedOptionFieldNumber
@ kUninterpretedOptionFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:5219
grpc::protobuf::DescriptorDatabase
GRPC_CUSTOM_DESCRIPTORDATABASE DescriptorDatabase
Definition: include/grpcpp/impl/codegen/config_protobuf.h:83
google::protobuf::Descriptor::FindNestedTypeByName
const Descriptor * FindNestedTypeByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1650
conf.extensions
list extensions
Definition: doc/python/sphinx/conf.py:54
a_
arena< N > & a_
Definition: cxa_demangle.cpp:4778
google::protobuf::descriptor_unittest::AllowUnknownDependenciesTest::syntax
const char * syntax()
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:2820
phone_pb2.containing_type
containing_type
Definition: phone_pb2.py:199
google::protobuf::strings::Substitute
string Substitute(const char *format, const SubstituteArg &arg0, const SubstituteArg &arg1, const SubstituteArg &arg2, const SubstituteArg &arg3, const SubstituteArg &arg4, const SubstituteArg &arg5, const SubstituteArg &arg6, const SubstituteArg &arg7, const SubstituteArg &arg8, const SubstituteArg &arg9)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/substitute.cc:55
EnumValueOptions::GetExtension
_proto_TypeTraits::Singular::ConstType GetExtension(const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed > &id) const
Definition: protobuf/src/google/protobuf/descriptor.pb.h:6253
ServiceDescriptorProto::kOptionsFieldNumber
@ kOptionsFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:3321
google::protobuf::DescriptorPool::ErrorCollector::TYPE
@ TYPE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1641
min
#define min(a, b)
Definition: qsort.h:83
FileDescriptorProto
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:501
google::protobuf::descriptor_unittest::ExtensionDescriptorTest
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1825
google::protobuf::Descriptor::field_count
int field_count() const
EnumValueDescriptorProto::kOptionsFieldNumber
@ kOptionsFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:3106
EnumDescriptor
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:143
google::protobuf::descriptor_unittest::DescriptorTest::map_file_
const FileDescriptor * map_file_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:779
FileDescriptorProto::Clear
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.cc:1753
log
Definition: bloaty/third_party/zlib/examples/gzlog.c:289
google::protobuf::descriptor_unittest::ReservedDescriptorTest::foo_
const Descriptor * foo_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:2084
SourceCodeInfo_Location::path_size
int path_size() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:13333
SourceCodeInfo_Location::path
::PROTOBUF_NAMESPACE_ID::int32 path(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:13342
google::protobuf::descriptor_unittest::ExtractDebugString
void ExtractDebugString(const FileDescriptor *file, std::set< std::string > *visited, std::vector< std::pair< std::string, std::string >> *debug_strings)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:551
FieldOptions::kPackedFieldNumber
@ kPackedFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:4789
google::protobuf::descriptor_unittest::EnumDescriptorTest::foo2_
const EnumValueDescriptor * foo2_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1371
MessageOptions::GetExtension
_proto_TypeTraits::Singular::ConstType GetExtension(const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< MessageOptions, _proto_TypeTraits, _field_type, _is_packed > &id) const
Definition: protobuf/src/google/protobuf/descriptor.pb.h:4632
SourceCodeInfo_Location::add_span
void add_span(::PROTOBUF_NAMESPACE_ID::int32 value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:13400
google::protobuf::MethodDescriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1234
FileDescriptorProto::extension
const PROTOBUF_NAMESPACE_ID::FieldDescriptorProto & extension(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7802
google::protobuf::descriptor_unittest::SourceLocationTest::source_tree_
SingletonSourceTree source_tree_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:7150
Json::ValueType
ValueType
Type of the value held by a Value object.
Definition: third_party/bloaty/third_party/protobuf/conformance/third_party/jsoncpp/json.h:463
google::protobuf::descriptor_unittest::AddNestedEnum
EnumDescriptorProto * AddNestedEnum(DescriptorProto *parent, const std::string &name)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:94
google::protobuf::ERROR
static const LogLevel ERROR
Definition: bloaty/third_party/protobuf/src/google/protobuf/testing/googletest.h:70
google::protobuf::descriptor_unittest::ReservedEnumDescriptorTest::edge2_
const EnumDescriptor * edge2_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:2183
google::protobuf::descriptor_unittest::AddMethod
MethodDescriptorProto * AddMethod(ServiceDescriptorProto *service, const std::string &name, const std::string &input_type, const std::string &output_type)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:179
absl::container_internal::internal_layout::adl_barrier::TypeName
std::string TypeName()
Definition: abseil-cpp/absl/container/internal/layout.h:295
google::protobuf::descriptor_unittest::DatabaseBackedPoolTest::CallCountingDatabase::~CallCountingDatabase
~CallCountingDatabase()
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:6879
FieldDescriptorProto::Clear
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.cc:3794
msg
std::string msg
Definition: client_interceptors_end2end_test.cc:372
google::protobuf::FileDescriptor::CopyTo
void CopyTo(FileDescriptorProto *proto) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1990
google::protobuf::descriptor_unittest::DatabaseBackedPoolTest::CallCountingDatabase::CallCountingDatabase
CallCountingDatabase(DescriptorDatabase *wrapped_db)
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:6875
google::protobuf::descriptor_unittest::ReservedEnumDescriptorTest::edge1_
const EnumDescriptor * edge1_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:2182
google::protobuf::DescriptorDatabase
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_database.h:71
FieldDescriptorProto::set_type_name
void set_type_name(const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8990
google::protobuf::descriptor_unittest::FileDescriptorTest::foo_message_
const Descriptor * foo_message_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:382
google::protobuf::DescriptorPool::ErrorCollector::OTHER
@ OTHER
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1649
google::protobuf::descriptor_unittest::ExponentialErrorDatabase::FullMatch
void FullMatch(const std::string &name, const std::string &begin_with, const std::string &end_with, int *file_num)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:6940
google::protobuf::ServiceDescriptor::FindMethodByName
const MethodDescriptor * FindMethodByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1703
google::protobuf::descriptor_unittest::FileDescriptorTest::foo_file_
const FileDescriptor * foo_file_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:378
google::protobuf::descriptor_unittest::FileDescriptorTest::bar_enum_value_
const EnumValueDescriptor * bar_enum_value_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:390
google::protobuf::descriptor_unittest::CopySourceCodeInfoToTest::db_
compiler::SourceTreeDescriptorDatabase db_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:7650
google::protobuf::descriptor_unittest::AddField
FieldDescriptorProto * AddField(DescriptorProto *parent, const std::string &name, int number, FieldDescriptorProto::Label label, FieldDescriptorProto::Type type)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:108
FileDescriptorProto::mutable_message_type
PROTOBUF_NAMESPACE_ID::DescriptorProto * mutable_message_type(int index)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7673
google::protobuf::io::ZeroCopyInputStream
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/zero_copy_stream.h:126
EXPECT_STREQ
#define EXPECT_STREQ(s1, s2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2095
google::protobuf::kuint32max
static const uint32 kuint32max
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/stubs/port.h:163
google::protobuf::descriptor_unittest::StylizedFieldNamesTest::message_
const Descriptor * message_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1196
FileDescriptorProto::add_extension
PROTOBUF_NAMESPACE_ID::FieldDescriptorProto * add_extension()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7809
FieldDescriptorProto::TYPE_FLOAT
static constexpr Type TYPE_FLOAT
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1984
google::protobuf::descriptor_unittest::MiscTest::GetMessageDescriptorForFieldType
const Descriptor * GetMessageDescriptorForFieldType(FieldDescriptor::Type type)
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:2472
google::protobuf::Descriptor::nested_type
const Descriptor * nested_type(int index) const
google::protobuf::FileDescriptor::FindExtensionByName
const FieldDescriptor * FindExtensionByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1755
FATAL
#define FATAL(msg)
Definition: task.h:88
google::protobuf::Descriptor::enum_type_count
int enum_type_count() const
google::protobuf::descriptor_unittest::OneofDescriptorTest::baz_file_
const FileDescriptor * baz_file_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1098
google::protobuf::FileDescriptor::name
const std::string & name() const
google::protobuf::descriptor_unittest::DescriptorTest::bar_
const FieldDescriptor * bar_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:790
google::protobuf::descriptor_unittest::AllowUnknownDependenciesTest::pool_
std::unique_ptr< DescriptorPool > pool_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:2743
FieldDescriptorProto::TYPE_ENUM
static constexpr Type TYPE_ENUM
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:2008
contents
string_view contents
Definition: elf.cc:597
google::protobuf::descriptor_unittest::DescriptorTest::foreign_
const Descriptor * foreign_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:786
google::protobuf::descriptor_unittest::ExtensionDescriptorTest::bar_
const Descriptor * bar_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1891
FieldDescriptorProto::TYPE_MESSAGE
static constexpr Type TYPE_MESSAGE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:2002
google::protobuf::descriptor_unittest::DescriptorTest::qux_
const FieldDescriptor * qux_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:792
google::protobuf::descriptor_unittest::ReservedEnumDescriptorTest::foo_file_
const FileDescriptor * foo_file_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:2180
google::protobuf::descriptor_unittest::StylizedFieldNamesTest::file_
const FileDescriptor * file_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1195
google::protobuf::descriptor_unittest::NestedDescriptorTest::baz2_
const Descriptor * baz2_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1719
google::protobuf::Message
Definition: bloaty/third_party/protobuf/src/google/protobuf/message.h:205
field
const FieldDescriptor * field
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/parser_unittest.cc:2692
google::protobuf::descriptor_unittest::AllowUnknownDependenciesTest::SetUp
void SetUp() override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:2822
FileDescriptorProto::syntax
const std::string & syntax() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7967
google::protobuf::FieldDescriptor::kMaxNumber
static const int kMaxNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:581
google::protobuf::descriptor_unittest::DescriptorTest::message_
const Descriptor * message_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:782
key
const char * key
Definition: hpack_parser_table.cc:164
testing::Values
internal::ValueArray< T... > Values(T... v)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest-param-test.h:335
DescriptorProto_ExtensionRange::kOptionsFieldNumber
@ kOptionsFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1069
google::protobuf::descriptor_unittest::MockErrorCollector::text_
std::string text_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:201
google::protobuf::descriptor_unittest::DatabaseBackedPoolTest::FalsePositiveDatabase::FindFileContainingExtension
bool FindFileContainingExtension(const std::string &containing_type, int field_number, FileDescriptorProto *output) override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:6927
EnumValueDescriptorProto::set_number
void set_number(::PROTOBUF_NAMESPACE_ID::int32 value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10104
google::protobuf::kint32max
static const int32 kint32max
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/stubs/port.h:159
google::protobuf::descriptor_unittest::DescriptorTest::json_file_
const FileDescriptor * json_file_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:780
EnumDescriptorProto::add_value
PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto * add_value()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9793
google::protobuf::descriptor_unittest::SourceLocationTest::PrintSourceLocation
static std::string PrintSourceLocation(const SourceLocation &loc)
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:7430
google::protobuf::FieldDescriptor::name
const std::string & name() const
OneofOptions::kUninterpretedOptionFieldNumber
@ kUninterpretedOptionFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:5048
google::protobuf::descriptor_unittest::FileDescriptorTest::foo_enum_
const EnumDescriptor * foo_enum_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:383
google::protobuf::descriptor_unittest::ServiceDescriptorTest::bar_
const MethodDescriptor * bar_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1543
OneofDescriptor
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:138
google::protobuf::FileDescriptor::message_type
const Descriptor * message_type(int index) const
google::protobuf::descriptor_unittest::OneofDescriptorTest::oneof_message_
const Descriptor * oneof_message_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1100
google::protobuf::descriptor_unittest::MiscTest::GetCppTypeForFieldType
FieldDescriptor::CppType GetCppTypeForFieldType(FieldDescriptor::Type type)
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:2461
EnumDescriptorProto
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:2705
google::protobuf::descriptor_unittest::SourceLocationTest::kCustomOptionFieldNumber
static const int kCustomOptionFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:7159
google::protobuf::descriptor_unittest::MiscTest::pool_
std::unique_ptr< DescriptorPool > pool_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:2321
google::protobuf::descriptor_unittest::NestedDescriptorTest::b_
const EnumValueDescriptor * b_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1716
google::protobuf::FileDescriptor::dependency
const FileDescriptor * dependency(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:7235
google::protobuf::descriptor_unittest::OneofDescriptorTest::pool_
DescriptorPool pool_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1096
google::protobuf::descriptor_unittest::DatabaseBackedPoolTest::ErrorDescriptorDatabase::~ErrorDescriptorDatabase
~ErrorDescriptorDatabase()
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:6840
google::protobuf::descriptor_unittest::ReservedEnumDescriptorTest::pool_
DescriptorPool pool_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:2179
google::protobuf::descriptor_unittest::FileDescriptorTest::baz_file_
const FileDescriptor * baz_file_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:380
testing::Combine
internal::CartesianProductHolder< Generator... > Combine(const Generator &... g)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest-param-test.h:410
google::protobuf::descriptor_unittest::ServiceDescriptorTest::bar_request_
const Descriptor * bar_request_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1534
google::protobuf::FileDescriptor::extension
const FieldDescriptor * extension(int index) const
google::protobuf::descriptor_unittest::EnumDescriptorTest::foo_
const EnumValueDescriptor * foo_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1368
SourceCodeInfo_Location
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:6397
google::protobuf::descriptor_unittest::AllowUnknownDependenciesTest::db_
SimpleDescriptorDatabase db_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:2742
google::protobuf::FileDescriptor::service_count
int service_count() const
profile_analyzer.fields
list fields
Definition: profile_analyzer.py:266
google::protobuf::descriptor_unittest::ExtensionDescriptorTest::pool_
DescriptorPool pool_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1886
google::protobuf::descriptor_unittest::TEST_P
TEST_P(AllowUnknownDependenciesTest, PlaceholderFile)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:2746
google::protobuf::descriptor_unittest::AllowUnknownDependenciesTest::bar_field_
const FieldDescriptor * bar_field_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:2738
google::protobuf::descriptor_unittest::ExponentialErrorDatabase::~ExponentialErrorDatabase
~ExponentialErrorDatabase()
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:7201
google::protobuf::FieldDescriptor::CPPTYPE_ENUM
@ CPPTYPE_ENUM
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:561
DescriptorProto::add_nested_type
PROTOBUF_NAMESPACE_ID::DescriptorProto * add_nested_type()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8440
google::protobuf::DescriptorPool::generated_pool
static const DescriptorPool * generated_pool()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1326
MethodDescriptorProto::kOptionsFieldNumber
@ kOptionsFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:3541
google::protobuf::descriptor_unittest::DatabaseBackedPoolTest::CallCountingDatabase::Clear
void Clear()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:6594
google::protobuf::Descriptor::name
const std::string & name() const
SourceCodeInfo
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:6683
regen-readme.line
line
Definition: regen-readme.py:30
google::protobuf::ServiceDescriptor::method_count
int method_count() const
google::protobuf::descriptor_unittest::DescriptorTest::foo_file_
const FileDescriptor * foo_file_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:777
google::protobuf::descriptor_unittest::DatabaseBackedPoolTest::DatabaseBackedPoolTest
DatabaseBackedPoolTest()
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:6808
ASSERT_TRUE
#define ASSERT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1973
testing::WithParamInterface< DescriptorPoolMode >::GetParam
static const ParamType & GetParam()
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1855
ASSERT_FALSE
#define ASSERT_FALSE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1976
DescriptorProto::mutable_options
PROTOBUF_NAMESPACE_ID::MessageOptions * mutable_options()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8611
google::protobuf::descriptor_unittest::DatabaseBackedPoolTest::FalsePositiveDatabase::FindFileContainingSymbol
bool FindFileContainingSymbol(const std::string &symbol_name, FileDescriptorProto *output) override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:6923
FileDescriptorProto::add_enum_type
PROTOBUF_NAMESPACE_ID::EnumDescriptorProto * add_enum_type()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7731
DescriptorProto
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1312
google::protobuf::EnumValueDescriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1075
google::protobuf::python::cdescriptor_pool::FindAllExtensions
static PyObject * FindAllExtensions(PyObject *self, PyObject *arg)
Definition: bloaty/third_party/protobuf/python/google/protobuf/pyext/descriptor_pool.cc:453
google::protobuf::Descriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:231
google::protobuf::FieldDescriptor::TYPE_MESSAGE
@ TYPE_MESSAGE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:536
google::protobuf::descriptor_unittest::ServiceDescriptorTest::foo_file_
const FileDescriptor * foo_file_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1529
desc
#define desc
Definition: bloaty/third_party/protobuf/src/google/protobuf/extension_set.h:338
google::protobuf::descriptor_unittest::EmbedAggregateValue
static std::string EmbedAggregateValue(const char *value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:5554
google::protobuf::descriptor_unittest::TEST
TEST(CustomOptions, OptionLocations)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:2976
google::protobuf::Descriptor::FindExtensionByName
const FieldDescriptor * FindExtensionByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1617
log
bool log
Definition: abseil-cpp/absl/synchronization/mutex.cc:310
google::protobuf::descriptor_unittest::DatabaseBackedPoolTest::CallCountingDatabase::FindFileByName
bool FindFileByName(const std::string &filename, FileDescriptorProto *output) override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:6888
google::protobuf::descriptor_unittest::AddExtensionRange
DescriptorProto::ExtensionRange * AddExtensionRange(DescriptorProto *parent, int start, int end)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:147
google::protobuf::DescriptorPool::ErrorCollector::EXTENDEE
@ EXTENDEE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1642
STATIC_STR
#define STATIC_STR(str)
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:3973
upbc::MessageName
std::string MessageName(const protobuf::Descriptor *descriptor)
Definition: upb/upbc/common.cc:65
google::protobuf::descriptor_unittest::ExtensionDescriptorTest::foo_
const Descriptor * foo_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1890
FileDescriptorProto::mutable_source_code_info
PROTOBUF_NAMESPACE_ID::SourceCodeInfo * mutable_source_code_info()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7931
google::protobuf::descriptor_unittest::OneofDescriptorTest::d_
const FieldDescriptor * d_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1107
google::protobuf::FieldDescriptor::GetSourceLocation
bool GetSourceLocation(SourceLocation *out_location) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2978
google::protobuf::descriptor_unittest::NestedDescriptorTest::SetUp
void SetUp() override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:1681
google::protobuf::descriptor_unittest::AddEnum
EnumDescriptorProto * AddEnum(FileDescriptorProto *file, const std::string &name)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:87
EnumDescriptorProto::set_name
void set_name(const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9687
google::protobuf::descriptor_unittest::ExtensionDescriptorTest::SetUp
void SetUp() override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:1895
google::protobuf::descriptor_unittest::ServiceDescriptorTest::service_
const ServiceDescriptor * service_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1539
google::protobuf::descriptor_unittest::CopySourceCodeInfoToTest::CopySourceCodeInfoToTest
CopySourceCodeInfoToTest()
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:7931
google::protobuf::descriptor_unittest::ValidationErrorTest::BuildFile
const FileDescriptor * BuildFile(const std::string &file_text)
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:3827
EXPECT_TRUE
#define EXPECT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1967
pool
InternalDescriptorPool * pool
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:807
google::protobuf::FileDescriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1320
EXPECT_DOUBLE_EQ
#define EXPECT_DOUBLE_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:28
grpc::protobuf::SourceLocation
GRPC_CUSTOM_SOURCELOCATION SourceLocation
Definition: include/grpcpp/impl/codegen/config_protobuf.h:90
b_
const char * b_
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/common_unittest.cc:194
FieldDescriptorProto::has_type
bool has_type() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8950
EnumValueOptions::kUninterpretedOptionFieldNumber
@ kUninterpretedOptionFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:5420
FieldDescriptorProto::TYPE_BYTES
static constexpr Type TYPE_BYTES
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:2004
google::protobuf::kint64max
static const int64 kint64max
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/stubs/port.h:161
FieldDescriptorProto::kOptionsFieldNumber
@ kOptionsFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:2083
google::protobuf::descriptor_unittest::DatabaseBackedPoolTest::FalsePositiveDatabase::FalsePositiveDatabase
FalsePositiveDatabase(DescriptorDatabase *wrapped_db)
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:6912
google::protobuf::descriptor_unittest::AddEmptyEnum
void AddEmptyEnum(FileDescriptorProto *file, const std::string &name)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:192
google::protobuf::EnumValueDescriptor::GetSourceLocation
bool GetSourceLocation(SourceLocation *out_location) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3008
google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE
@ CPPTYPE_MESSAGE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:563
google::protobuf::descriptor_unittest::MockErrorCollector
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:196
google::protobuf::Descriptor::map_value
const FieldDescriptor * map_value() const
Definition: protobuf/src/google/protobuf/descriptor.cc:2326
google::protobuf::descriptor_unittest::OneofDescriptorTest::a_
const FieldDescriptor * a_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1104
google::protobuf::compiler::objectivec::EnumName
string EnumName(const EnumDescriptor *descriptor)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc:472
google::protobuf::DescriptorDatabase::FindFileByName
virtual bool FindFileByName(const std::string &filename, FileDescriptorProto *output)=0
google::protobuf::descriptor_unittest::AllowUnknownDependenciesTest::foo_type_
const Descriptor * foo_type_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:2737
google::protobuf::ServiceDescriptor::method
const MethodDescriptor * method(int index) const
FieldDescriptorProto::LABEL_REQUIRED
static constexpr Label LABEL_REQUIRED
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:2046
google::protobuf::descriptor_unittest::ServiceDescriptorTest::baz_request_
const Descriptor * baz_request_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1536
FileDescriptorProto::has_source_code_info
bool has_source_code_info() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7893
ExtensionRangeOptions::kUninterpretedOptionFieldNumber
@ kUninterpretedOptionFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1813
google::protobuf::descriptor_unittest::NestedDescriptorTest::message2_
const Descriptor * message2_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1709
google::protobuf::descriptor_unittest::AbortingErrorCollector::GOOGLE_DISALLOW_EVIL_CONSTRUCTORS
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(AbortingErrorCollector)
google::protobuf::descriptor_unittest::DatabaseBackedPoolTest::ErrorDescriptorDatabase::FindFileContainingSymbol
bool FindFileContainingSymbol(const std::string &symbol_name, FileDescriptorProto *output) override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:6860
google::protobuf::kuint64max
static const uint64 kuint64max
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/stubs/port.h:164
google::protobuf::descriptor_unittest::NestedDescriptorTest::message_
const Descriptor * message_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1708
DescriptorProto::add_extension
PROTOBUF_NAMESPACE_ID::FieldDescriptorProto * add_extension()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8401
google::protobuf::compiler::SourceTree
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/importer.h:215
FieldDescriptorProto::set_json_name
void set_json_name(const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9297
google::protobuf::descriptor_unittest::MockErrorCollector::warning_text_
std::string warning_text_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:202
google::protobuf::descriptor_unittest::OneofDescriptorTest::oneof2_
const OneofDescriptor * oneof2_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1103
SourceCodeInfo::location
const PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location & location(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:13709
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
google::protobuf::EnumDescriptor::GetSourceLocation
bool GetSourceLocation(SourceLocation *out_location) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2990
google::protobuf::descriptor_unittest::NestedDescriptorTest::baz_
const EnumDescriptor * baz_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1713
autogen_x86imm.tmp
tmp
Definition: autogen_x86imm.py:12
google::protobuf::FieldDescriptor::TYPE_INT32
@ TYPE_INT32
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:528
google::protobuf::DescriptorDatabase::FindFileContainingSymbol
virtual bool FindFileContainingSymbol(const std::string &symbol_name, FileDescriptorProto *output)=0
google::protobuf::SimpleDescriptorDatabase
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_database.h:162
google::protobuf::descriptor_unittest::DatabaseBackedPoolTest::CallCountingDatabase::FindFileContainingExtension
bool FindFileContainingExtension(const std::string &containing_type, int field_number, FileDescriptorProto *output) override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:6898
FieldOptions::kDeprecatedFieldNumber
@ kDeprecatedFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:4791
google::protobuf::descriptor_unittest::AddEnumValue
EnumValueDescriptorProto * AddEnumValue(EnumDescriptorProto *enum_proto, const std::string &name, int number)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:171
EXPECT_FLOAT_EQ
#define EXPECT_FLOAT_EQ(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2127
google::protobuf::DescriptorPool::ErrorCollector::DEFAULT_VALUE
@ DEFAULT_VALUE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1643
DescriptorProto::field_size
int field_size() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8337
file::name
char * name
Definition: bloaty/third_party/zlib/examples/gzappend.c:176
google::protobuf::descriptor_unittest::EnumDescriptorTest::enum_
const EnumDescriptor * enum_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1365
DescriptorProto::kNestedTypeFieldNumber
@ kNestedTypeFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1449
google::protobuf::EnumValueDescriptor::file
const FileDescriptor * file() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:2115
google::protobuf::descriptor_unittest::FileDescriptorTest::foo_service_
const ServiceDescriptor * foo_service_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:385
google::protobuf::descriptor_unittest::DescriptorTest::quux2_
const FieldDescriptor * quux2_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:796
int32_t
signed int int32_t
Definition: stdint-msvc2008.h:77
DescriptorProto::mutable_field
PROTOBUF_NAMESPACE_ID::FieldDescriptorProto * mutable_field(int index)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8343
google::protobuf::descriptor_unittest::SingletonSourceTree::filename_
const std::string filename_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:7044
google::protobuf::EnumDescriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:918
google::protobuf::descriptor_unittest::DescriptorTest::enum_
const EnumDescriptor * enum_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:787
DescriptorPool
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:110
google::protobuf::descriptor_unittest::StylizedFieldNamesTest::pool_
DescriptorPool pool_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1194
google::protobuf::descriptor_unittest::ValidationErrorTest::BuildFileInTestPool
void BuildFileInTestPool(const FileDescriptor *file)
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:3861
GOOGLE_LOG
#define GOOGLE_LOG(LEVEL)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/logging.h:146
google::protobuf::descriptor_unittest::MockErrorCollector::AddWarning
void AddWarning(const std::string &filename, const std::string &element_name, const Message *descriptor, ErrorLocation location, const std::string &message) override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:252
google::protobuf::descriptor_unittest::DatabaseBackedPoolTest::ErrorDescriptorDatabase::FindFileByName
bool FindFileByName(const std::string &filename, FileDescriptorProto *output) override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:6843
google::protobuf::DescriptorPool::ErrorCollector::OPTION_VALUE
@ OPTION_VALUE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1647
google::protobuf::ServiceDescriptor::GetSourceLocation
bool GetSourceLocation(SourceLocation *out_location) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3002
DescriptorProto::add_enum_type
PROTOBUF_NAMESPACE_ID::EnumDescriptorProto * add_enum_type()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8479
google::protobuf::descriptor_unittest::SourceLocationTest::file_proto_
FileDescriptorProto file_proto_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:7148
phone_pb2.enum_type
enum_type
Definition: phone_pb2.py:198
google::protobuf::TextFormat::MergeFromString
static bool MergeFromString(const std::string &input, Message *output)
Definition: bloaty/third_party/protobuf/src/google/protobuf/text_format.cc:1490
descriptor
static const char descriptor[1336]
Definition: certs.upbdefs.c:16
google::protobuf::FileDescriptor::message_type_count
int message_type_count() const
google_benchmark.option
option
Definition: third_party/benchmark/bindings/python/google_benchmark/__init__.py:115
google::protobuf::FieldDescriptor::TYPE_STRING
@ TYPE_STRING
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:534
FieldDescriptorProto_Label
FieldDescriptorProto_Label
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:211
grpc::protobuf::ServiceDescriptor
GRPC_CUSTOM_SERVICEDESCRIPTOR ServiceDescriptor
Definition: include/grpcpp/impl/codegen/config_protobuf.h:88
google::protobuf::descriptor_unittest::AddToDatabase
static void AddToDatabase(SimpleDescriptorDatabase *database, const char *file_text)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:6508
google::protobuf::descriptor_unittest::OneofDescriptorTest::SetUp
void SetUp() override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:1109
google::protobuf::descriptor_unittest::NestedDescriptorTest::foo2_
const Descriptor * foo2_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1718
google::protobuf::descriptor_unittest::FALLBACK_DATABASE
@ FALLBACK_DATABASE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:2652
google::protobuf::FieldDescriptor::CppType
CppType
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:553
google
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:11
google::protobuf::descriptor_unittest::DatabaseBackedPoolTest::CallCountingDatabase::FindFileContainingSymbol
bool FindFileContainingSymbol(const std::string &symbol_name, FileDescriptorProto *output) override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:6893
google::protobuf::descriptor_unittest::EnumDescriptorTest::enum2_
const EnumDescriptor * enum2_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1366
google::protobuf::FileDescriptor::extension_count
int extension_count() const
google::protobuf::descriptor_unittest::ValidationErrorTest::BuildFileWithWarnings
void BuildFileWithWarnings(const std::string &file_text, const std::string &expected_warnings)
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:3850
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
google::protobuf::method
const Descriptor::ReservedRange const EnumValueDescriptor method
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1973
google::protobuf::descriptor_unittest::DescriptorTest::message4_
const Descriptor * message4_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:785
MethodOptions::kDeprecatedFieldNumber
@ kDeprecatedFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:5825
google::protobuf::descriptor_unittest::INSTANTIATE_TEST_SUITE_P
INSTANTIATE_TEST_SUITE_P(DatabaseSource, AllowUnknownDependenciesTest, testing::Values(NO_DATABASE, FALLBACK_DATABASE))
google::protobuf::descriptor_unittest::OneofDescriptorTest::c_
const FieldDescriptor * c_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:1106
DescriptorProto_ReservedRange
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1134
DescriptorProto::field
const PROTOBUF_NAMESPACE_ID::FieldDescriptorProto & field(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8355
service_
std::unique_ptr< grpc::testing::TestServiceImpl > service_
Definition: end2end_binder_transport_test.cc:71
google::protobuf::descriptor_unittest::DescriptorTest
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:613
ASSERT_EQ
#define ASSERT_EQ(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2056
google::protobuf::descriptor_unittest::ReservedDescriptorTest::SetUp
void SetUp() override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:2218
google::protobuf::kint32min
static const int32 kint32min
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/stubs/port.h:160
MessageOptions::descriptor
static const ::PROTOBUF_NAMESPACE_ID::Descriptor * descriptor()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:4397
google::protobuf::strings::SubstituteAndAppend
void SubstituteAndAppend(string *output, const char *format, const SubstituteArg &arg0, const SubstituteArg &arg1, const SubstituteArg &arg2, const SubstituteArg &arg3, const SubstituteArg &arg4, const SubstituteArg &arg5, const SubstituteArg &arg6, const SubstituteArg &arg7, const SubstituteArg &arg8, const SubstituteArg &arg9)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/substitute.cc:68
google::protobuf::descriptor_unittest::AbortingErrorCollector::AddError
void AddError(const std::string &filename, const std::string &element_name, const Message *message, ErrorLocation location, const std::string &error_message) override
Definition: protobuf/src/google/protobuf/descriptor_unittest.cc:7309
google::protobuf::SimpleDescriptorDatabase::Add
bool Add(const FileDescriptorProto &file)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_database.cc:333
google::protobuf::service
const Descriptor::ReservedRange const EnumDescriptor::ReservedRange service
Definition: protobuf/src/google/protobuf/descriptor.h:2177
testing::PrintToString
::std::string PrintToString(const T &value)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest-printers.h:915
google::protobuf::descriptor_unittest::DescriptorTest::baz_
const FieldDescriptor * baz_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:791


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:15