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


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:50