41 #include <google/protobuf/any.pb.h>
42 #include <google/protobuf/compiler/importer.h>
43 #include <google/protobuf/compiler/parser.h>
44 #include <google/protobuf/unittest.pb.h>
45 #include <google/protobuf/unittest_custom_options.pb.h>
46 #include <google/protobuf/stubs/common.h>
47 #include <google/protobuf/stubs/logging.h>
48 #include <google/protobuf/stubs/stringprintf.h>
49 #include <google/protobuf/unittest_lazy_dependencies.pb.h>
50 #include <google/protobuf/unittest_proto3_arena.pb.h>
51 #include <google/protobuf/io/tokenizer.h>
52 #include <google/protobuf/io/zero_copy_stream_impl.h>
53 #include <google/protobuf/descriptor.pb.h>
54 #include <google/protobuf/descriptor.h>
55 #include <google/protobuf/descriptor_database.h>
56 #include <google/protobuf/dynamic_message.h>
57 #include <google/protobuf/text_format.h>
58 #include <google/protobuf/stubs/strutil.h>
59 #include <gmock/gmock.h>
60 #include <google/protobuf/testing/googletest.h>
61 #include <gtest/gtest.h>
62 #include <google/protobuf/stubs/logging.h>
63 #include <google/protobuf/stubs/substitute.h>
66 #include <google/protobuf/port_def.inc>
72 namespace descriptor_unittest {
131 result->set_extendee(extendee);
145 result->set_extendee(extendee);
187 result->set_input_type(input_type);
188 result->set_output_type(output_type);
198 class MockErrorCollector :
public DescriptorPool::ErrorCollector {
210 const char* location_name =
nullptr;
213 location_name =
"NAME";
216 location_name =
"NUMBER";
219 location_name =
"TYPE";
222 location_name =
"EXTENDEE";
225 location_name =
"DEFAULT_VALUE";
228 location_name =
"OPTION_NAME";
231 location_name =
"OPTION_VALUE";
234 location_name =
"INPUT_TYPE";
237 location_name =
"OUTPUT_TYPE";
240 location_name =
"IMPORT";
243 location_name =
"OTHER";
255 const char* location_name =
nullptr;
258 location_name =
"NAME";
261 location_name =
"NUMBER";
264 location_name =
"TYPE";
267 location_name =
"EXTENDEE";
270 location_name =
"DEFAULT_VALUE";
273 location_name =
"OPTION_NAME";
276 location_name =
"OPTION_VALUE";
279 location_name =
"INPUT_TYPE";
282 location_name =
"OUTPUT_TYPE";
285 location_name =
"IMPORT";
288 location_name =
"OTHER";
327 AddExtension(&foo_file,
"FooMessage",
"foo_extension", 1,
338 AddExtension(&bar_file,
"bar_package.BarMessage",
"bar_extension", 1,
397 TEST_F(FileDescriptorTest, Name) {
398 EXPECT_EQ(
"foo.proto", foo_file_->name());
399 EXPECT_EQ(
"bar.proto", bar_file_->name());
400 EXPECT_EQ(
"baz.proto", baz_file_->name());
405 EXPECT_EQ(
"bar_package", bar_file_->package());
408 TEST_F(FileDescriptorTest, Dependencies) {
409 EXPECT_EQ(0, foo_file_->dependency_count());
410 EXPECT_EQ(1, bar_file_->dependency_count());
411 EXPECT_EQ(foo_file_, bar_file_->dependency(0));
414 TEST_F(FileDescriptorTest, FindMessageTypeByName) {
415 EXPECT_EQ(foo_message_, foo_file_->FindMessageTypeByName(
"FooMessage"));
416 EXPECT_EQ(bar_message_, bar_file_->FindMessageTypeByName(
"BarMessage"));
418 EXPECT_TRUE(foo_file_->FindMessageTypeByName(
"BarMessage") ==
nullptr);
419 EXPECT_TRUE(bar_file_->FindMessageTypeByName(
"FooMessage") ==
nullptr);
420 EXPECT_TRUE(baz_file_->FindMessageTypeByName(
"FooMessage") ==
nullptr);
422 EXPECT_TRUE(foo_file_->FindMessageTypeByName(
"NoSuchMessage") ==
nullptr);
423 EXPECT_TRUE(foo_file_->FindMessageTypeByName(
"FooEnum") ==
nullptr);
427 EXPECT_EQ(foo_enum_, foo_file_->FindEnumTypeByName(
"FooEnum"));
428 EXPECT_EQ(bar_enum_, bar_file_->FindEnumTypeByName(
"BarEnum"));
430 EXPECT_TRUE(foo_file_->FindEnumTypeByName(
"BarEnum") ==
nullptr);
431 EXPECT_TRUE(bar_file_->FindEnumTypeByName(
"FooEnum") ==
nullptr);
432 EXPECT_TRUE(baz_file_->FindEnumTypeByName(
"FooEnum") ==
nullptr);
434 EXPECT_TRUE(foo_file_->FindEnumTypeByName(
"NoSuchEnum") ==
nullptr);
435 EXPECT_TRUE(foo_file_->FindEnumTypeByName(
"FooMessage") ==
nullptr);
438 TEST_F(FileDescriptorTest, FindEnumValueByName) {
439 EXPECT_EQ(foo_enum_value_, foo_file_->FindEnumValueByName(
"FOO_ENUM_VALUE"));
440 EXPECT_EQ(bar_enum_value_, bar_file_->FindEnumValueByName(
"BAR_ENUM_VALUE"));
442 EXPECT_TRUE(foo_file_->FindEnumValueByName(
"BAR_ENUM_VALUE") ==
nullptr);
443 EXPECT_TRUE(bar_file_->FindEnumValueByName(
"FOO_ENUM_VALUE") ==
nullptr);
444 EXPECT_TRUE(baz_file_->FindEnumValueByName(
"FOO_ENUM_VALUE") ==
nullptr);
446 EXPECT_TRUE(foo_file_->FindEnumValueByName(
"NO_SUCH_VALUE") ==
nullptr);
447 EXPECT_TRUE(foo_file_->FindEnumValueByName(
"FooMessage") ==
nullptr);
451 EXPECT_EQ(foo_service_, foo_file_->FindServiceByName(
"FooService"));
452 EXPECT_EQ(bar_service_, bar_file_->FindServiceByName(
"BarService"));
454 EXPECT_TRUE(foo_file_->FindServiceByName(
"BarService") ==
nullptr);
455 EXPECT_TRUE(bar_file_->FindServiceByName(
"FooService") ==
nullptr);
456 EXPECT_TRUE(baz_file_->FindServiceByName(
"FooService") ==
nullptr);
458 EXPECT_TRUE(foo_file_->FindServiceByName(
"NoSuchService") ==
nullptr);
459 EXPECT_TRUE(foo_file_->FindServiceByName(
"FooMessage") ==
nullptr);
463 EXPECT_EQ(foo_extension_, foo_file_->FindExtensionByName(
"foo_extension"));
464 EXPECT_EQ(bar_extension_, bar_file_->FindExtensionByName(
"bar_extension"));
466 EXPECT_TRUE(foo_file_->FindExtensionByName(
"bar_extension") ==
nullptr);
467 EXPECT_TRUE(bar_file_->FindExtensionByName(
"foo_extension") ==
nullptr);
468 EXPECT_TRUE(baz_file_->FindExtensionByName(
"foo_extension") ==
nullptr);
470 EXPECT_TRUE(foo_file_->FindExtensionByName(
"no_such_extension") ==
nullptr);
471 EXPECT_TRUE(foo_file_->FindExtensionByName(
"FooMessage") ==
nullptr);
475 EXPECT_EQ(foo_extension_,
pool_.FindExtensionByNumber(foo_message_, 1));
476 EXPECT_EQ(bar_extension_,
pool_.FindExtensionByNumber(bar_message_, 1));
482 TEST_F(FileDescriptorTest, BuildAgain) {
486 foo_file_->CopyTo(&
file);
490 file.set_package(
"some.other.package");
494 TEST_F(FileDescriptorTest, BuildAgainWithSyntax) {
498 proto_syntax2.
set_name(
"foo_syntax2");
506 implicit_proto2.
set_name(
"foo_implicit_syntax2");
509 pool_.BuildFile(implicit_proto2);
510 EXPECT_TRUE(implicit_proto2_descriptor !=
nullptr);
514 EXPECT_EQ(implicit_proto2_descriptor,
pool_.BuildFile(implicit_proto2));
517 proto_syntax3.
set_name(
"foo_syntax3");
537 file->CopyTo(&other);
548 file->CopyTo(&other);
555 std::vector<std::pair<std::string, std::string>>* debug_strings) {
559 for (
int i = 0;
i <
file->dependency_count(); ++
i) {
562 debug_strings->push_back(std::make_pair(
file->
name(),
file->DebugString()));
565 class SimpleErrorCollector :
public io::ErrorCollector {
579 TEST_F(FileDescriptorTest, DebugStringRoundTrip) {
581 std::vector<std::pair<std::string, std::string>> debug_strings;
592 for (
int i = 0;
i < debug_strings.size(); ++
i) {
596 SimpleErrorCollector error_collector;
599 parser.RecordErrorsTo(&error_collector);
602 << error_collector.last_error() <<
"\n"
604 ASSERT_EQ(
"", error_collector.last_error());
705 AddField(message3,
"map_int32_int32", 1,
776 message->CopyJsonNameTo(proto);
781 return desc->FindValueByNumberCreatingIfUnknown(
number);
810 TEST_F(DescriptorTest, Name) {
811 EXPECT_EQ(
"TestMessage", message_->name());
812 EXPECT_EQ(
"TestMessage", message_->full_name());
815 EXPECT_EQ(
"TestMessage2", message2_->name());
816 EXPECT_EQ(
"corge.grault.TestMessage2", message2_->full_name());
820 TEST_F(DescriptorTest, ContainingType) {
821 EXPECT_TRUE(message_->containing_type() ==
nullptr);
822 EXPECT_TRUE(message2_->containing_type() ==
nullptr);
833 &field->name(), &field->lowercase_name(),
834 &field->camelcase_name(), &field->json_name()}
842 EXPECT_THAT(collect_unique_names(message4_->field(0)),
845 EXPECT_THAT(collect_unique_names(message4_->field(1)),
848 EXPECT_THAT(collect_unique_names(message4_->field(2)),
849 ElementsAre(
"FieldName3",
"fieldName3",
"fieldname3"));
851 EXPECT_THAT(collect_unique_names(message4_->field(3)),
852 ElementsAre(
"FieldName4",
"_field_name4",
"fieldName4"));
855 collect_unique_names(message4_->field(4)),
856 ElementsAre(
"FIELDNAME5",
"FIELD_NAME5",
"fIELDNAME5",
"field_name5"));
858 EXPECT_THAT(collect_unique_names(message4_->field(5)),
859 ElementsAre(
"@type",
"fieldName6",
"field_name6"));
861 EXPECT_THAT(collect_unique_names(message4_->field(6)),
865 TEST_F(DescriptorTest, FieldsByIndex) {
879 EXPECT_EQ(foo_, message_->FindFieldByName(
"foo"));
880 EXPECT_EQ(bar_, message_->FindFieldByName(
"bar"));
881 EXPECT_EQ(baz_, message_->FindFieldByName(
"baz"));
882 EXPECT_EQ(qux_, message_->FindFieldByName(
"qux"));
883 EXPECT_TRUE(message_->FindFieldByName(
"no_such_field") ==
nullptr);
884 EXPECT_TRUE(message_->FindFieldByName(
"quux") ==
nullptr);
886 EXPECT_EQ(foo2_, message2_->FindFieldByName(
"foo"));
887 EXPECT_EQ(bar2_, message2_->FindFieldByName(
"bar"));
888 EXPECT_EQ(quux2_, message2_->FindFieldByName(
"quux"));
889 EXPECT_TRUE(message2_->FindFieldByName(
"baz") ==
nullptr);
890 EXPECT_TRUE(message2_->FindFieldByName(
"qux") ==
nullptr);
893 TEST_F(DescriptorTest, FindFieldByNumber) {
894 EXPECT_EQ(foo_, message_->FindFieldByNumber(1));
895 EXPECT_EQ(bar_, message_->FindFieldByNumber(6));
896 EXPECT_EQ(baz_, message_->FindFieldByNumber(500000000));
897 EXPECT_EQ(qux_, message_->FindFieldByNumber(15));
898 EXPECT_TRUE(message_->FindFieldByNumber(837592) ==
nullptr);
899 EXPECT_TRUE(message_->FindFieldByNumber(2) ==
nullptr);
901 EXPECT_EQ(foo2_, message2_->FindFieldByNumber(1));
902 EXPECT_EQ(bar2_, message2_->FindFieldByNumber(2));
903 EXPECT_EQ(quux2_, message2_->FindFieldByNumber(6));
904 EXPECT_TRUE(message2_->FindFieldByNumber(15) ==
nullptr);
905 EXPECT_TRUE(message2_->FindFieldByNumber(500000000) ==
nullptr);
915 TEST_F(DescriptorTest, FieldFullName) {
916 EXPECT_EQ(
"TestMessage.foo", foo_->full_name());
917 EXPECT_EQ(
"TestMessage.bar", bar_->full_name());
918 EXPECT_EQ(
"TestMessage.baz", baz_->full_name());
919 EXPECT_EQ(
"TestMessage.qux", qux_->full_name());
921 EXPECT_EQ(
"corge.grault.TestMessage2.foo", foo2_->full_name());
922 EXPECT_EQ(
"corge.grault.TestMessage2.bar", bar2_->full_name());
923 EXPECT_EQ(
"corge.grault.TestMessage2.quux", quux2_->full_name());
926 TEST_F(DescriptorTest, PrintableNameIsFullNameForNonExtensionFields) {
927 EXPECT_EQ(
"TestMessage.foo", foo_->PrintableNameForExtension());
928 EXPECT_EQ(
"TestMessage.bar", bar_->PrintableNameForExtension());
929 EXPECT_EQ(
"TestMessage.baz", baz_->PrintableNameForExtension());
930 EXPECT_EQ(
"TestMessage.qux", qux_->PrintableNameForExtension());
932 EXPECT_EQ(
"corge.grault.TestMessage2.foo",
933 foo2_->PrintableNameForExtension());
934 EXPECT_EQ(
"corge.grault.TestMessage2.bar",
935 bar2_->PrintableNameForExtension());
936 EXPECT_EQ(
"corge.grault.TestMessage2.quux",
937 quux2_->PrintableNameForExtension());
940 TEST_F(DescriptorTest, PrintableNameIsFullNameForNonMessageSetExtension) {
941 EXPECT_EQ(
"protobuf_unittest.Aggregate.nested",
944 ->PrintableNameForExtension());
947 TEST_F(DescriptorTest, PrintableNameIsExtendingTypeForMessageSetExtension) {
948 EXPECT_EQ(
"protobuf_unittest.AggregateMessageSetElement",
951 ->PrintableNameForExtension());
954 TEST_F(DescriptorTest, FieldJsonName) {
955 EXPECT_EQ(
"fieldName1", message4_->field(0)->json_name());
956 EXPECT_EQ(
"fieldName2", message4_->field(1)->json_name());
957 EXPECT_EQ(
"FieldName3", message4_->field(2)->json_name());
958 EXPECT_EQ(
"FieldName4", message4_->field(3)->json_name());
959 EXPECT_EQ(
"FIELDNAME5", message4_->field(4)->json_name());
960 EXPECT_EQ(
"@type", message4_->field(5)->json_name());
963 message4_->CopyTo(&proto);
974 CopyWithJsonName(message4_, &proto);
987 EXPECT_EQ(
"fieldName1", generated->field(0)->json_name());
988 EXPECT_EQ(
"fieldName2", generated->field(1)->json_name());
989 EXPECT_EQ(
"FieldName3", generated->field(2)->json_name());
990 EXPECT_EQ(
"FieldName4", generated->field(3)->json_name());
991 EXPECT_EQ(
"FIELDNAME5", generated->field(4)->json_name());
992 EXPECT_EQ(
"@type", generated->field(5)->json_name());
993 EXPECT_EQ(
"fieldname7", generated->field(6)->json_name());
996 TEST_F(DescriptorTest, FieldFile) {
1007 TEST_F(DescriptorTest, FieldIndex) {
1014 TEST_F(DescriptorTest, FieldNumber) {
1028 TEST_F(DescriptorTest, FieldLabel) {
1050 EXPECT_TRUE(map_->message_type()->options().map_entry());
1054 const Descriptor* map_desc = map_->message_type();
1065 EXPECT_EQ(message_->map_key(),
nullptr);
1066 EXPECT_EQ(message_->map_value(),
nullptr);
1069 TEST_F(DescriptorTest, FieldHasDefault) {
1076 TEST_F(DescriptorTest, FieldContainingType) {
1077 EXPECT_EQ(message_, foo_->containing_type());
1078 EXPECT_EQ(message_, bar_->containing_type());
1079 EXPECT_EQ(message_, baz_->containing_type());
1080 EXPECT_EQ(message_, qux_->containing_type());
1082 EXPECT_EQ(message2_, foo2_->containing_type());
1083 EXPECT_EQ(message2_, bar2_->containing_type());
1084 EXPECT_EQ(message2_, quux2_->containing_type());
1087 TEST_F(DescriptorTest, FieldMessageType) {
1091 EXPECT_EQ(foreign_, baz_->message_type());
1092 EXPECT_EQ(foreign_, qux_->message_type());
1095 TEST_F(DescriptorTest, FieldEnumType) {
1140 oneof_message->
mutable_field(2)->set_type_name(
"TestOneof");
1178 TEST_F(OneofDescriptorTest, Normal) {
1180 EXPECT_EQ(
"garply.TestOneof.foo", oneof_->full_name());
1190 TEST_F(OneofDescriptorTest, FindByName) {
1191 EXPECT_EQ(oneof_, oneof_message_->FindOneofByName(
"foo"));
1192 EXPECT_EQ(oneof2_, oneof_message_->FindOneofByName(
"bar"));
1193 EXPECT_TRUE(oneof_message_->FindOneofByName(
"no_such_oneof") ==
nullptr);
1202 file.set_name(
"foo.proto");
1267 TEST_F(StylizedFieldNamesTest, LowercaseName) {
1268 EXPECT_EQ(
"foo_foo", message_->field(0)->lowercase_name());
1269 EXPECT_EQ(
"foobar", message_->field(1)->lowercase_name());
1270 EXPECT_EQ(
"foobaz", message_->field(2)->lowercase_name());
1271 EXPECT_EQ(
"foofoo", message_->field(3)->lowercase_name());
1272 EXPECT_EQ(
"foobar", message_->field(4)->lowercase_name());
1274 EXPECT_EQ(
"bar_foo", message_->extension(0)->lowercase_name());
1275 EXPECT_EQ(
"barbar", message_->extension(1)->lowercase_name());
1276 EXPECT_EQ(
"barbaz", message_->extension(2)->lowercase_name());
1277 EXPECT_EQ(
"barfoo", message_->extension(3)->lowercase_name());
1278 EXPECT_EQ(
"barbar", message_->extension(4)->lowercase_name());
1287 TEST_F(StylizedFieldNamesTest, CamelcaseName) {
1288 EXPECT_EQ(
"fooFoo", message_->field(0)->camelcase_name());
1289 EXPECT_EQ(
"fooBar", message_->field(1)->camelcase_name());
1290 EXPECT_EQ(
"fooBaz", message_->field(2)->camelcase_name());
1291 EXPECT_EQ(
"fooFoo", message_->field(3)->camelcase_name());
1292 EXPECT_EQ(
"foobar", message_->field(4)->camelcase_name());
1294 EXPECT_EQ(
"barFoo", message_->extension(0)->camelcase_name());
1295 EXPECT_EQ(
"barBar", message_->extension(1)->camelcase_name());
1296 EXPECT_EQ(
"barBaz", message_->extension(2)->camelcase_name());
1297 EXPECT_EQ(
"barFoo", message_->extension(3)->camelcase_name());
1298 EXPECT_EQ(
"barbar", message_->extension(4)->camelcase_name());
1307 TEST_F(StylizedFieldNamesTest, FindByLowercaseName) {
1308 EXPECT_EQ(message_->field(0), message_->FindFieldByLowercaseName(
"foo_foo"));
1309 EXPECT_EQ(message_->field(1), message_->FindFieldByLowercaseName(
"foobar"));
1310 EXPECT_EQ(message_->field(2), message_->FindFieldByLowercaseName(
"foobaz"));
1311 EXPECT_TRUE(message_->FindFieldByLowercaseName(
"FooBar") ==
nullptr);
1312 EXPECT_TRUE(message_->FindFieldByLowercaseName(
"fooBaz") ==
nullptr);
1313 EXPECT_TRUE(message_->FindFieldByLowercaseName(
"bar_foo") ==
nullptr);
1314 EXPECT_TRUE(message_->FindFieldByLowercaseName(
"nosuchfield") ==
nullptr);
1317 message_->FindExtensionByLowercaseName(
"bar_foo"));
1319 message_->FindExtensionByLowercaseName(
"barbar"));
1321 message_->FindExtensionByLowercaseName(
"barbaz"));
1322 EXPECT_TRUE(message_->FindExtensionByLowercaseName(
"BarBar") ==
nullptr);
1323 EXPECT_TRUE(message_->FindExtensionByLowercaseName(
"barBaz") ==
nullptr);
1324 EXPECT_TRUE(message_->FindExtensionByLowercaseName(
"foo_foo") ==
nullptr);
1325 EXPECT_TRUE(message_->FindExtensionByLowercaseName(
"nosuchfield") ==
nullptr);
1328 file_->FindExtensionByLowercaseName(
"baz_foo"));
1333 EXPECT_TRUE(
file_->FindExtensionByLowercaseName(
"nosuchfield") ==
nullptr);
1336 TEST_F(StylizedFieldNamesTest, FindByCamelcaseName) {
1337 EXPECT_EQ(message_->field(0), message_->FindFieldByCamelcaseName(
"fooFoo"));
1338 EXPECT_EQ(message_->field(1), message_->FindFieldByCamelcaseName(
"fooBar"));
1339 EXPECT_EQ(message_->field(2), message_->FindFieldByCamelcaseName(
"fooBaz"));
1340 EXPECT_TRUE(message_->FindFieldByCamelcaseName(
"foo_foo") ==
nullptr);
1341 EXPECT_TRUE(message_->FindFieldByCamelcaseName(
"FooBar") ==
nullptr);
1342 EXPECT_TRUE(message_->FindFieldByCamelcaseName(
"barFoo") ==
nullptr);
1343 EXPECT_TRUE(message_->FindFieldByCamelcaseName(
"nosuchfield") ==
nullptr);
1346 message_->FindExtensionByCamelcaseName(
"barFoo"));
1348 message_->FindExtensionByCamelcaseName(
"barBar"));
1350 message_->FindExtensionByCamelcaseName(
"barBaz"));
1351 EXPECT_TRUE(message_->FindExtensionByCamelcaseName(
"bar_foo") ==
nullptr);
1352 EXPECT_TRUE(message_->FindExtensionByCamelcaseName(
"BarBar") ==
nullptr);
1353 EXPECT_TRUE(message_->FindExtensionByCamelcaseName(
"fooFoo") ==
nullptr);
1354 EXPECT_TRUE(message_->FindExtensionByCamelcaseName(
"nosuchfield") ==
nullptr);
1361 EXPECT_TRUE(
file_->FindExtensionByCamelcaseName(
"nosuchfield") ==
nullptr);
1443 TEST_F(EnumDescriptorTest, Name) {
1445 EXPECT_EQ(
"TestEnum", enum_->full_name());
1449 EXPECT_EQ(
"corge.grault.TestEnum2", enum2_->full_name());
1453 TEST_F(EnumDescriptorTest, ContainingType) {
1455 EXPECT_TRUE(enum2_->containing_type() ==
nullptr);
1458 TEST_F(EnumDescriptorTest, ValuesByIndex) {
1464 TEST_F(EnumDescriptorTest, FindValueByName) {
1465 EXPECT_EQ(foo_, enum_->FindValueByName(
"FOO"));
1466 EXPECT_EQ(bar_, enum_->FindValueByName(
"BAR"));
1467 EXPECT_EQ(foo2_, enum2_->FindValueByName(
"FOO"));
1468 EXPECT_EQ(baz2_, enum2_->FindValueByName(
"BAZ"));
1470 EXPECT_TRUE(enum_->FindValueByName(
"NO_SUCH_VALUE") ==
nullptr);
1471 EXPECT_TRUE(enum_->FindValueByName(
"BAZ") ==
nullptr);
1472 EXPECT_TRUE(enum2_->FindValueByName(
"BAR") ==
nullptr);
1475 TEST_F(EnumDescriptorTest, FindValueByNumber) {
1476 EXPECT_EQ(foo_, enum_->FindValueByNumber(1));
1477 EXPECT_EQ(bar_, enum_->FindValueByNumber(2));
1478 EXPECT_EQ(foo2_, enum2_->FindValueByNumber(1));
1479 EXPECT_EQ(baz2_, enum2_->FindValueByNumber(3));
1481 EXPECT_TRUE(enum_->FindValueByNumber(416) ==
nullptr);
1482 EXPECT_TRUE(enum_->FindValueByNumber(3) ==
nullptr);
1483 EXPECT_TRUE(enum2_->FindValueByNumber(2) ==
nullptr);
1486 TEST_F(EnumDescriptorTest, ValueName) {
1491 TEST_F(EnumDescriptorTest, ValueFullName) {
1494 EXPECT_EQ(
"corge.grault.FOO", foo2_->full_name());
1495 EXPECT_EQ(
"corge.grault.BAZ", baz2_->full_name());
1498 TEST_F(EnumDescriptorTest, ValueIndex) {
1503 TEST_F(EnumDescriptorTest, ValueNumber) {
1562 AddMethod(service2,
"Foo",
"FooRequest",
"FooResponse");
1563 AddMethod(service2,
"Baz",
"BazRequest",
"BazResponse");
1617 TEST_F(ServiceDescriptorTest, Name) {
1622 EXPECT_EQ(
"TestService2", service2_->name());
1623 EXPECT_EQ(
"corge.grault.TestService2", service2_->full_name());
1624 EXPECT_EQ(bar_file_, service2_->file());
1627 TEST_F(ServiceDescriptorTest, MethodsByIndex) {
1636 EXPECT_EQ(foo2_, service2_->FindMethodByName(
"Foo"));
1637 EXPECT_EQ(baz2_, service2_->FindMethodByName(
"Baz"));
1641 EXPECT_TRUE(service2_->FindMethodByName(
"Bar") ==
nullptr);
1644 TEST_F(ServiceDescriptorTest, MethodName) {
1649 TEST_F(ServiceDescriptorTest, MethodFullName) {
1650 EXPECT_EQ(
"TestService.Foo", foo_->full_name());
1651 EXPECT_EQ(
"TestService.Bar", bar_->full_name());
1652 EXPECT_EQ(
"corge.grault.TestService2.Foo", foo2_->full_name());
1653 EXPECT_EQ(
"corge.grault.TestService2.Baz", baz2_->full_name());
1656 TEST_F(ServiceDescriptorTest, MethodIndex) {
1661 TEST_F(ServiceDescriptorTest, MethodParent) {
1666 TEST_F(ServiceDescriptorTest, MethodInputType) {
1667 EXPECT_EQ(foo_request_, foo_->input_type());
1668 EXPECT_EQ(bar_request_, bar_->input_type());
1671 TEST_F(ServiceDescriptorTest, MethodOutputType) {
1672 EXPECT_EQ(foo_response_, foo_->output_type());
1673 EXPECT_EQ(bar_response_, bar_->output_type());
1800 EXPECT_EQ(
"TestMessage.Foo", foo_->full_name());
1801 EXPECT_EQ(
"TestMessage.Bar", bar_->full_name());
1802 EXPECT_EQ(
"corge.grault.TestMessage2.Foo", foo2_->full_name());
1803 EXPECT_EQ(
"corge.grault.TestMessage2.Baz", baz2_->full_name());
1806 TEST_F(NestedDescriptorTest, MessageContainingType) {
1807 EXPECT_EQ(message_, foo_->containing_type());
1808 EXPECT_EQ(message_, bar_->containing_type());
1809 EXPECT_EQ(message2_, foo2_->containing_type());
1810 EXPECT_EQ(message2_, baz2_->containing_type());
1813 TEST_F(NestedDescriptorTest, NestedMessagesByIndex) {
1814 ASSERT_EQ(2, message_->nested_type_count());
1815 EXPECT_EQ(foo_, message_->nested_type(0));
1816 EXPECT_EQ(bar_, message_->nested_type(1));
1819 TEST_F(NestedDescriptorTest, FindFieldByNameDoesntFindNestedTypes) {
1820 EXPECT_TRUE(message_->FindFieldByName(
"Foo") ==
nullptr);
1821 EXPECT_TRUE(message_->FindFieldByName(
"Qux") ==
nullptr);
1822 EXPECT_TRUE(message_->FindExtensionByName(
"Foo") ==
nullptr);
1823 EXPECT_TRUE(message_->FindExtensionByName(
"Qux") ==
nullptr);
1826 TEST_F(NestedDescriptorTest, FindNestedTypeByName) {
1827 EXPECT_EQ(foo_, message_->FindNestedTypeByName(
"Foo"));
1828 EXPECT_EQ(bar_, message_->FindNestedTypeByName(
"Bar"));
1829 EXPECT_EQ(foo2_, message2_->FindNestedTypeByName(
"Foo"));
1830 EXPECT_EQ(baz2_, message2_->FindNestedTypeByName(
"Baz"));
1832 EXPECT_TRUE(message_->FindNestedTypeByName(
"NoSuchType") ==
nullptr);
1833 EXPECT_TRUE(message_->FindNestedTypeByName(
"Baz") ==
nullptr);
1834 EXPECT_TRUE(message2_->FindNestedTypeByName(
"Bar") ==
nullptr);
1836 EXPECT_TRUE(message_->FindNestedTypeByName(
"Qux") ==
nullptr);
1845 EXPECT_EQ(
"TestMessage.Baz", baz_->full_name());
1846 EXPECT_EQ(
"TestMessage.Qux", qux_->full_name());
1847 EXPECT_EQ(
"corge.grault.TestMessage2.Qux", qux2_->full_name());
1848 EXPECT_EQ(
"corge.grault.TestMessage2.Quux", quux2_->full_name());
1851 TEST_F(NestedDescriptorTest, EnumContainingType) {
1852 EXPECT_EQ(message_, baz_->containing_type());
1853 EXPECT_EQ(message_, qux_->containing_type());
1854 EXPECT_EQ(message2_, qux2_->containing_type());
1855 EXPECT_EQ(message2_, quux2_->containing_type());
1858 TEST_F(NestedDescriptorTest, NestedEnumsByIndex) {
1859 ASSERT_EQ(2, message_->nested_type_count());
1860 EXPECT_EQ(foo_, message_->nested_type(0));
1861 EXPECT_EQ(bar_, message_->nested_type(1));
1865 EXPECT_EQ(baz_, message_->FindEnumTypeByName(
"Baz"));
1866 EXPECT_EQ(qux_, message_->FindEnumTypeByName(
"Qux"));
1867 EXPECT_EQ(qux2_, message2_->FindEnumTypeByName(
"Qux"));
1868 EXPECT_EQ(quux2_, message2_->FindEnumTypeByName(
"Quux"));
1870 EXPECT_TRUE(message_->FindEnumTypeByName(
"NoSuchType") ==
nullptr);
1871 EXPECT_TRUE(message_->FindEnumTypeByName(
"Quux") ==
nullptr);
1872 EXPECT_TRUE(message2_->FindEnumTypeByName(
"Baz") ==
nullptr);
1874 EXPECT_TRUE(message_->FindEnumTypeByName(
"Foo") ==
nullptr);
1877 TEST_F(NestedDescriptorTest, FindEnumValueByName) {
1878 EXPECT_EQ(
a_, message_->FindEnumValueByName(
"A"));
1879 EXPECT_EQ(
b_, message_->FindEnumValueByName(
"B"));
1880 EXPECT_EQ(a2_, message2_->FindEnumValueByName(
"A"));
1881 EXPECT_EQ(c2_, message2_->FindEnumValueByName(
"C"));
1883 EXPECT_TRUE(message_->FindEnumValueByName(
"NO_SUCH_VALUE") ==
nullptr);
1884 EXPECT_TRUE(message_->FindEnumValueByName(
"C") ==
nullptr);
1885 EXPECT_TRUE(message2_->FindEnumValueByName(
"B") ==
nullptr);
1887 EXPECT_TRUE(message_->FindEnumValueByName(
"Foo") ==
nullptr);
1972 TEST_F(ExtensionDescriptorTest, ExtensionRanges) {
1973 EXPECT_EQ(0, bar_->extension_range_count());
1974 ASSERT_EQ(2, foo_->extension_range_count());
1976 EXPECT_EQ(10, foo_->extension_range(0)->start);
1977 EXPECT_EQ(30, foo_->extension_range(1)->start);
1979 EXPECT_EQ(20, foo_->extension_range(0)->end);
1980 EXPECT_EQ(40, foo_->extension_range(1)->end);
1985 ASSERT_EQ(2, foo_file_->extension_count());
1988 EXPECT_TRUE(foo_file_->extension(0)->is_extension());
1989 EXPECT_TRUE(foo_file_->extension(1)->is_extension());
1993 EXPECT_EQ(
"foo_int32", foo_file_->extension(0)->name());
1994 EXPECT_EQ(
"foo_enum", foo_file_->extension(1)->name());
1995 EXPECT_EQ(
"foo_message", bar_->extension(0)->name());
1996 EXPECT_EQ(
"foo_group", bar_->extension(1)->name());
1998 EXPECT_EQ(10, foo_file_->extension(0)->number());
1999 EXPECT_EQ(19, foo_file_->extension(1)->number());
2000 EXPECT_EQ(30, bar_->extension(0)->number());
2001 EXPECT_EQ(39, bar_->extension(1)->number());
2008 EXPECT_EQ(baz_, foo_file_->extension(1)->enum_type());
2009 EXPECT_EQ(qux_, bar_->extension(0)->message_type());
2010 EXPECT_EQ(qux_, bar_->extension(1)->message_type());
2017 EXPECT_EQ(foo_, foo_file_->extension(0)->containing_type());
2018 EXPECT_EQ(foo_, foo_file_->extension(1)->containing_type());
2019 EXPECT_EQ(foo_, bar_->extension(0)->containing_type());
2020 EXPECT_EQ(foo_, bar_->extension(1)->containing_type());
2022 EXPECT_TRUE(foo_file_->extension(0)->extension_scope() ==
nullptr);
2023 EXPECT_TRUE(foo_file_->extension(1)->extension_scope() ==
nullptr);
2024 EXPECT_EQ(bar_, bar_->extension(0)->extension_scope());
2025 EXPECT_EQ(bar_, bar_->extension(1)->extension_scope());
2028 TEST_F(ExtensionDescriptorTest, IsExtensionNumber) {
2044 EXPECT_EQ(bar_->extension(0), bar_->FindExtensionByName(
"foo_message"));
2045 EXPECT_EQ(bar_->extension(1), bar_->FindExtensionByName(
"foo_group"));
2047 EXPECT_TRUE(bar_->FindExtensionByName(
"no_such_extension") ==
nullptr);
2048 EXPECT_TRUE(foo_->FindExtensionByName(
"foo_int32") ==
nullptr);
2049 EXPECT_TRUE(foo_->FindExtensionByName(
"foo_message") ==
nullptr);
2053 EXPECT_EQ(foo_->FindFieldByName(
"foo_message"),
nullptr);
2054 EXPECT_EQ(bar_->FindFieldByName(
"foo_message"),
nullptr);
2055 EXPECT_NE(bar_->FindFieldByName(
"non_ext_int32"),
nullptr);
2056 EXPECT_EQ(foo_->FindExtensionByName(
"foo_message"),
nullptr);
2057 EXPECT_NE(bar_->FindExtensionByName(
"foo_message"),
nullptr);
2058 EXPECT_EQ(bar_->FindExtensionByName(
"non_ext_int32"),
nullptr);
2061 TEST_F(ExtensionDescriptorTest, FindExtensionByPrintableName) {
2062 EXPECT_TRUE(
pool_.FindExtensionByPrintableName(foo_,
"no_such_extension") ==
2064 EXPECT_TRUE(
pool_.FindExtensionByPrintableName(bar_,
"no_such_extension") ==
2073 EXPECT_TRUE(
pool_.FindExtensionByPrintableName(bar_,
"foo_group") ==
nullptr);
2074 EXPECT_EQ(bar_->FindExtensionByName(
"foo_message"),
2075 pool_.FindExtensionByPrintableName(foo_,
"Bar.foo_message"));
2076 EXPECT_EQ(bar_->FindExtensionByName(
"foo_group"),
2077 pool_.FindExtensionByPrintableName(foo_,
"Bar.foo_group"));
2082 EXPECT_TRUE(
pool_.FindExtensionByPrintableName(bar_,
"foo_int32") ==
nullptr);
2083 EXPECT_TRUE(
pool_.FindExtensionByPrintableName(bar_,
"foo_enum") ==
nullptr);
2084 EXPECT_EQ(foo_file_->FindExtensionByName(
"foo_int32"),
2085 pool_.FindExtensionByPrintableName(foo_,
"foo_int32"));
2086 EXPECT_EQ(foo_file_->FindExtensionByName(
"foo_enum"),
2087 pool_.FindExtensionByPrintableName(foo_,
"foo_enum"));
2091 std::vector<const FieldDescriptor*>
extensions;
2101 TEST_F(ExtensionDescriptorTest, DuplicateFieldNumber) {
2115 AddExtension(&file_proto,
"google.protobuf.FieldOptions",
"option1", 1000,
2127 AddExtension(&file_proto,
"google.protobuf.FieldOptions",
"option2", 1000,
2138 TEST(OverlappingExtensionRangeTest, ExtensionRangeInternal) {
2155 ASSERT_TRUE(
pool.BuildFileCollectingErrors(foo_file, &error_collector) ==
2158 "foo.proto: Foo: NUMBER: Extension range 15 to 15 overlaps with "
2159 "already-defined range 10 to 19.\n",
2160 error_collector.text_);
2163 TEST(OverlappingExtensionRangeTest, ExtensionRangeAfter) {
2180 ASSERT_TRUE(
pool.BuildFileCollectingErrors(foo_file, &error_collector) ==
2183 "foo.proto: Foo: NUMBER: Extension range 15 to 24 overlaps with "
2184 "already-defined range 10 to 19.\n",
2185 error_collector.text_);
2188 TEST(OverlappingExtensionRangeTest, ExtensionRangeBefore) {
2205 ASSERT_TRUE(
pool.BuildFileCollectingErrors(foo_file, &error_collector) ==
2208 "foo.proto: Foo: NUMBER: Extension range 5 to 14 overlaps with "
2209 "already-defined range 10 to 19.\n",
2210 error_collector.text_);
2234 foo->add_reserved_name(
"foo");
2235 foo->add_reserved_name(
"bar");
2250 TEST_F(ReservedDescriptorTest, ReservedRanges) {
2251 ASSERT_EQ(3, foo_->reserved_range_count());
2253 EXPECT_EQ(2, foo_->reserved_range(0)->start);
2254 EXPECT_EQ(3, foo_->reserved_range(0)->end);
2256 EXPECT_EQ(9, foo_->reserved_range(1)->start);
2257 EXPECT_EQ(12, foo_->reserved_range(1)->end);
2259 EXPECT_EQ(15, foo_->reserved_range(2)->start);
2260 EXPECT_EQ(16, foo_->reserved_range(2)->end);
2263 TEST_F(ReservedDescriptorTest, IsReservedNumber) {
2278 TEST_F(ReservedDescriptorTest, ReservedNames) {
2279 ASSERT_EQ(2, foo_->reserved_name_count());
2281 EXPECT_EQ(
"foo", foo_->reserved_name(0));
2282 EXPECT_EQ(
"bar", foo_->reserved_name(1));
2285 TEST_F(ReservedDescriptorTest, IsReservedName) {
2319 foo->add_reserved_name(
"foo");
2320 foo->add_reserved_name(
"bar");
2349 TEST_F(ReservedEnumDescriptorTest, ReservedRanges) {
2350 ASSERT_EQ(5, foo_->reserved_range_count());
2352 EXPECT_EQ(-5, foo_->reserved_range(0)->start);
2353 EXPECT_EQ(-3, foo_->reserved_range(0)->end);
2355 EXPECT_EQ(-2, foo_->reserved_range(1)->start);
2356 EXPECT_EQ(1, foo_->reserved_range(1)->end);
2358 EXPECT_EQ(2, foo_->reserved_range(2)->start);
2359 EXPECT_EQ(3, foo_->reserved_range(2)->end);
2361 EXPECT_EQ(9, foo_->reserved_range(3)->start);
2362 EXPECT_EQ(12, foo_->reserved_range(3)->end);
2364 EXPECT_EQ(15, foo_->reserved_range(4)->start);
2365 EXPECT_EQ(16, foo_->reserved_range(4)->end);
2367 ASSERT_EQ(1, edge1_->reserved_range_count());
2368 EXPECT_EQ(10, edge1_->reserved_range(0)->start);
2369 EXPECT_EQ(INT_MAX, edge1_->reserved_range(0)->end);
2371 ASSERT_EQ(1, edge2_->reserved_range_count());
2372 EXPECT_EQ(INT_MIN, edge2_->reserved_range(0)->start);
2373 EXPECT_EQ(10, edge2_->reserved_range(0)->end);
2376 TEST_F(ReservedEnumDescriptorTest, IsReservedNumber) {
2400 EXPECT_TRUE(edge1_->IsReservedNumber(INT_MAX - 1));
2409 TEST_F(ReservedEnumDescriptorTest, ReservedNames) {
2410 ASSERT_EQ(2, foo_->reserved_name_count());
2412 EXPECT_EQ(
"foo", foo_->reserved_name(0));
2413 EXPECT_EQ(
"bar", foo_->reserved_name(1));
2416 TEST_F(ReservedEnumDescriptorTest, IsReservedName) {
2439 field->set_type_name(
"TestMessage");
2441 field->set_type_name(
"DummyEnum");
2448 if (
file !=
nullptr &&
file->message_type_count() == 1 &&
2449 file->message_type(0)->field_count() == 1) {
2450 return file->message_type(0)->field(0);
2458 return field !=
nullptr ?
field->type_name() :
"";
2469 return field !=
nullptr ?
field->cpp_type_name() :
"";
2475 return field !=
nullptr ?
field->message_type() :
nullptr;
2481 return field !=
nullptr ?
field->enum_type() :
nullptr;
2484 std::unique_ptr<DescriptorPool>
pool_;
2487 TEST_F(MiscTest, TypeNames) {
2492 EXPECT_STREQ(
"double", GetTypeNameForFieldType(FD::TYPE_DOUBLE));
2493 EXPECT_STREQ(
"float", GetTypeNameForFieldType(FD::TYPE_FLOAT));
2494 EXPECT_STREQ(
"int64", GetTypeNameForFieldType(FD::TYPE_INT64));
2495 EXPECT_STREQ(
"uint64", GetTypeNameForFieldType(FD::TYPE_UINT64));
2496 EXPECT_STREQ(
"int32", GetTypeNameForFieldType(FD::TYPE_INT32));
2497 EXPECT_STREQ(
"fixed64", GetTypeNameForFieldType(FD::TYPE_FIXED64));
2498 EXPECT_STREQ(
"fixed32", GetTypeNameForFieldType(FD::TYPE_FIXED32));
2499 EXPECT_STREQ(
"bool", GetTypeNameForFieldType(FD::TYPE_BOOL));
2500 EXPECT_STREQ(
"string", GetTypeNameForFieldType(FD::TYPE_STRING));
2501 EXPECT_STREQ(
"group", GetTypeNameForFieldType(FD::TYPE_GROUP));
2502 EXPECT_STREQ(
"message", GetTypeNameForFieldType(FD::TYPE_MESSAGE));
2503 EXPECT_STREQ(
"bytes", GetTypeNameForFieldType(FD::TYPE_BYTES));
2504 EXPECT_STREQ(
"uint32", GetTypeNameForFieldType(FD::TYPE_UINT32));
2505 EXPECT_STREQ(
"enum", GetTypeNameForFieldType(FD::TYPE_ENUM));
2506 EXPECT_STREQ(
"sfixed32", GetTypeNameForFieldType(FD::TYPE_SFIXED32));
2507 EXPECT_STREQ(
"sfixed64", GetTypeNameForFieldType(FD::TYPE_SFIXED64));
2508 EXPECT_STREQ(
"sint32", GetTypeNameForFieldType(FD::TYPE_SINT32));
2509 EXPECT_STREQ(
"sint64", GetTypeNameForFieldType(FD::TYPE_SINT64));
2512 TEST_F(MiscTest, StaticTypeNames) {
2537 TEST_F(MiscTest, CppTypes) {
2542 EXPECT_EQ(FD::CPPTYPE_DOUBLE, GetCppTypeForFieldType(FD::TYPE_DOUBLE));
2543 EXPECT_EQ(FD::CPPTYPE_FLOAT, GetCppTypeForFieldType(FD::TYPE_FLOAT));
2544 EXPECT_EQ(FD::CPPTYPE_INT64, GetCppTypeForFieldType(FD::TYPE_INT64));
2545 EXPECT_EQ(FD::CPPTYPE_UINT64, GetCppTypeForFieldType(FD::TYPE_UINT64));
2546 EXPECT_EQ(FD::CPPTYPE_INT32, GetCppTypeForFieldType(FD::TYPE_INT32));
2547 EXPECT_EQ(FD::CPPTYPE_UINT64, GetCppTypeForFieldType(FD::TYPE_FIXED64));
2548 EXPECT_EQ(FD::CPPTYPE_UINT32, GetCppTypeForFieldType(FD::TYPE_FIXED32));
2549 EXPECT_EQ(FD::CPPTYPE_BOOL, GetCppTypeForFieldType(FD::TYPE_BOOL));
2550 EXPECT_EQ(FD::CPPTYPE_STRING, GetCppTypeForFieldType(FD::TYPE_STRING));
2551 EXPECT_EQ(FD::CPPTYPE_MESSAGE, GetCppTypeForFieldType(FD::TYPE_GROUP));
2552 EXPECT_EQ(FD::CPPTYPE_MESSAGE, GetCppTypeForFieldType(FD::TYPE_MESSAGE));
2553 EXPECT_EQ(FD::CPPTYPE_STRING, GetCppTypeForFieldType(FD::TYPE_BYTES));
2554 EXPECT_EQ(FD::CPPTYPE_UINT32, GetCppTypeForFieldType(FD::TYPE_UINT32));
2555 EXPECT_EQ(FD::CPPTYPE_ENUM, GetCppTypeForFieldType(FD::TYPE_ENUM));
2556 EXPECT_EQ(FD::CPPTYPE_INT32, GetCppTypeForFieldType(FD::TYPE_SFIXED32));
2557 EXPECT_EQ(FD::CPPTYPE_INT64, GetCppTypeForFieldType(FD::TYPE_SFIXED64));
2558 EXPECT_EQ(FD::CPPTYPE_INT32, GetCppTypeForFieldType(FD::TYPE_SINT32));
2559 EXPECT_EQ(FD::CPPTYPE_INT64, GetCppTypeForFieldType(FD::TYPE_SINT64));
2562 TEST_F(MiscTest, CppTypeNames) {
2567 EXPECT_STREQ(
"double", GetCppTypeNameForFieldType(FD::TYPE_DOUBLE));
2568 EXPECT_STREQ(
"float", GetCppTypeNameForFieldType(FD::TYPE_FLOAT));
2569 EXPECT_STREQ(
"int64", GetCppTypeNameForFieldType(FD::TYPE_INT64));
2570 EXPECT_STREQ(
"uint64", GetCppTypeNameForFieldType(FD::TYPE_UINT64));
2571 EXPECT_STREQ(
"int32", GetCppTypeNameForFieldType(FD::TYPE_INT32));
2572 EXPECT_STREQ(
"uint64", GetCppTypeNameForFieldType(FD::TYPE_FIXED64));
2573 EXPECT_STREQ(
"uint32", GetCppTypeNameForFieldType(FD::TYPE_FIXED32));
2574 EXPECT_STREQ(
"bool", GetCppTypeNameForFieldType(FD::TYPE_BOOL));
2575 EXPECT_STREQ(
"string", GetCppTypeNameForFieldType(FD::TYPE_STRING));
2576 EXPECT_STREQ(
"message", GetCppTypeNameForFieldType(FD::TYPE_GROUP));
2577 EXPECT_STREQ(
"message", GetCppTypeNameForFieldType(FD::TYPE_MESSAGE));
2578 EXPECT_STREQ(
"string", GetCppTypeNameForFieldType(FD::TYPE_BYTES));
2579 EXPECT_STREQ(
"uint32", GetCppTypeNameForFieldType(FD::TYPE_UINT32));
2580 EXPECT_STREQ(
"enum", GetCppTypeNameForFieldType(FD::TYPE_ENUM));
2581 EXPECT_STREQ(
"int32", GetCppTypeNameForFieldType(FD::TYPE_SFIXED32));
2582 EXPECT_STREQ(
"int64", GetCppTypeNameForFieldType(FD::TYPE_SFIXED64));
2583 EXPECT_STREQ(
"int32", GetCppTypeNameForFieldType(FD::TYPE_SINT32));
2584 EXPECT_STREQ(
"int64", GetCppTypeNameForFieldType(FD::TYPE_SINT64));
2587 TEST_F(MiscTest, StaticCppTypeNames) {
2592 EXPECT_STREQ(
"int32", FD::CppTypeName(FD::CPPTYPE_INT32));
2593 EXPECT_STREQ(
"int64", FD::CppTypeName(FD::CPPTYPE_INT64));
2594 EXPECT_STREQ(
"uint32", FD::CppTypeName(FD::CPPTYPE_UINT32));
2595 EXPECT_STREQ(
"uint64", FD::CppTypeName(FD::CPPTYPE_UINT64));
2596 EXPECT_STREQ(
"double", FD::CppTypeName(FD::CPPTYPE_DOUBLE));
2597 EXPECT_STREQ(
"float", FD::CppTypeName(FD::CPPTYPE_FLOAT));
2598 EXPECT_STREQ(
"bool", FD::CppTypeName(FD::CPPTYPE_BOOL));
2599 EXPECT_STREQ(
"enum", FD::CppTypeName(FD::CPPTYPE_ENUM));
2600 EXPECT_STREQ(
"string", FD::CppTypeName(FD::CPPTYPE_STRING));
2601 EXPECT_STREQ(
"message", FD::CppTypeName(FD::CPPTYPE_MESSAGE));
2604 TEST_F(MiscTest, MessageType) {
2609 EXPECT_TRUE(
nullptr == GetMessageDescriptorForFieldType(FD::TYPE_DOUBLE));
2610 EXPECT_TRUE(
nullptr == GetMessageDescriptorForFieldType(FD::TYPE_FLOAT));
2611 EXPECT_TRUE(
nullptr == GetMessageDescriptorForFieldType(FD::TYPE_INT64));
2612 EXPECT_TRUE(
nullptr == GetMessageDescriptorForFieldType(FD::TYPE_UINT64));
2613 EXPECT_TRUE(
nullptr == GetMessageDescriptorForFieldType(FD::TYPE_INT32));
2614 EXPECT_TRUE(
nullptr == GetMessageDescriptorForFieldType(FD::TYPE_FIXED64));
2615 EXPECT_TRUE(
nullptr == GetMessageDescriptorForFieldType(FD::TYPE_FIXED32));
2616 EXPECT_TRUE(
nullptr == GetMessageDescriptorForFieldType(FD::TYPE_BOOL));
2617 EXPECT_TRUE(
nullptr == GetMessageDescriptorForFieldType(FD::TYPE_STRING));
2618 EXPECT_TRUE(
nullptr != GetMessageDescriptorForFieldType(FD::TYPE_GROUP));
2619 EXPECT_TRUE(
nullptr != GetMessageDescriptorForFieldType(FD::TYPE_MESSAGE));
2620 EXPECT_TRUE(
nullptr == GetMessageDescriptorForFieldType(FD::TYPE_BYTES));
2621 EXPECT_TRUE(
nullptr == GetMessageDescriptorForFieldType(FD::TYPE_UINT32));
2622 EXPECT_TRUE(
nullptr == GetMessageDescriptorForFieldType(FD::TYPE_ENUM));
2623 EXPECT_TRUE(
nullptr == GetMessageDescriptorForFieldType(FD::TYPE_SFIXED32));
2624 EXPECT_TRUE(
nullptr == GetMessageDescriptorForFieldType(FD::TYPE_SFIXED64));
2625 EXPECT_TRUE(
nullptr == GetMessageDescriptorForFieldType(FD::TYPE_SINT32));
2626 EXPECT_TRUE(
nullptr == GetMessageDescriptorForFieldType(FD::TYPE_SINT64));
2629 TEST_F(MiscTest, EnumType) {
2634 EXPECT_TRUE(
nullptr == GetEnumDescriptorForFieldType(FD::TYPE_DOUBLE));
2635 EXPECT_TRUE(
nullptr == GetEnumDescriptorForFieldType(FD::TYPE_FLOAT));
2636 EXPECT_TRUE(
nullptr == GetEnumDescriptorForFieldType(FD::TYPE_INT64));
2637 EXPECT_TRUE(
nullptr == GetEnumDescriptorForFieldType(FD::TYPE_UINT64));
2638 EXPECT_TRUE(
nullptr == GetEnumDescriptorForFieldType(FD::TYPE_INT32));
2639 EXPECT_TRUE(
nullptr == GetEnumDescriptorForFieldType(FD::TYPE_FIXED64));
2640 EXPECT_TRUE(
nullptr == GetEnumDescriptorForFieldType(FD::TYPE_FIXED32));
2641 EXPECT_TRUE(
nullptr == GetEnumDescriptorForFieldType(FD::TYPE_BOOL));
2642 EXPECT_TRUE(
nullptr == GetEnumDescriptorForFieldType(FD::TYPE_STRING));
2643 EXPECT_TRUE(
nullptr == GetEnumDescriptorForFieldType(FD::TYPE_GROUP));
2644 EXPECT_TRUE(
nullptr == GetEnumDescriptorForFieldType(FD::TYPE_MESSAGE));
2645 EXPECT_TRUE(
nullptr == GetEnumDescriptorForFieldType(FD::TYPE_BYTES));
2646 EXPECT_TRUE(
nullptr == GetEnumDescriptorForFieldType(FD::TYPE_UINT32));
2647 EXPECT_TRUE(
nullptr != GetEnumDescriptorForFieldType(FD::TYPE_ENUM));
2648 EXPECT_TRUE(
nullptr == GetEnumDescriptorForFieldType(FD::TYPE_SFIXED32));
2649 EXPECT_TRUE(
nullptr == GetEnumDescriptorForFieldType(FD::TYPE_SFIXED64));
2650 EXPECT_TRUE(
nullptr == GetEnumDescriptorForFieldType(FD::TYPE_SINT32));
2651 EXPECT_TRUE(
nullptr == GetEnumDescriptorForFieldType(FD::TYPE_SINT64));
2654 TEST_F(MiscTest, DefaultValues) {
2666 const FD::Label
label = FD::LABEL_OPTIONAL;
2673 AddField(message_proto,
"uint32", 3,
label, FD::TYPE_UINT32)
2675 AddField(message_proto,
"uint64", 4,
label, FD::TYPE_UINT64)
2679 AddField(message_proto,
"double", 6,
label, FD::TYPE_DOUBLE)
2683 AddField(message_proto,
"string", 8,
label, FD::TYPE_STRING)
2695 AddField(message_proto,
"empty_string", 11,
label, FD::TYPE_STRING)
2699 AddField(message_proto,
"implicit_int32", 21,
label, FD::TYPE_INT32);
2700 AddField(message_proto,
"implicit_int64", 22,
label, FD::TYPE_INT64);
2701 AddField(message_proto,
"implicit_uint32", 23,
label, FD::TYPE_UINT32);
2702 AddField(message_proto,
"implicit_uint64", 24,
label, FD::TYPE_UINT64);
2703 AddField(message_proto,
"implicit_float", 25,
label, FD::TYPE_FLOAT);
2704 AddField(message_proto,
"implicit_double", 26,
label, FD::TYPE_DOUBLE);
2705 AddField(message_proto,
"implicit_bool", 27,
label, FD::TYPE_BOOL);
2706 AddField(message_proto,
"implicit_string", 28,
label, FD::TYPE_STRING);
2707 AddField(message_proto,
"implicit_data", 29,
label, FD::TYPE_BYTES);
2708 AddField(message_proto,
"implicit_enum", 30,
label, FD::TYPE_ENUM)
2815 class AllowUnknownDependenciesTest
2817 std::tuple<DescriptorPoolMode, const char*>> {
2834 pool_->AllowUnknownDependencies();
2838 "dependency: 'bar.proto'"
2839 "dependency: 'baz.proto'"
2842 " field { name:'bar' number:1 label:LABEL_OPTIONAL type_name:'Bar' }"
2843 " field { name:'baz' number:2 label:LABEL_OPTIONAL type_name:'Baz' }"
2844 " field { name:'qux' number:3 label:LABEL_OPTIONAL"
2845 " type_name: '.corge.Qux'"
2848 " uninterpreted_option {"
2850 " name_part: 'grault'"
2851 " is_extension: true"
2853 " positive_int_value: 1234"
2863 "message_type { name: 'Bar' }",
2889 return pool_->BuildFile(proto);
2893 return pool_->FindFileByName(proto.
name());
2909 std::unique_ptr<DescriptorPool>
pool_;
2912 TEST_P(AllowUnknownDependenciesTest, PlaceholderFile) {
2913 ASSERT_EQ(2, foo_file_->dependency_count());
2914 EXPECT_EQ(bar_file_, foo_file_->dependency(0));
2928 baz_file->
CopyTo(&baz_file_proto);
2933 TEST_P(AllowUnknownDependenciesTest, PlaceholderTypes) {
2935 EXPECT_EQ(bar_type_, bar_field_->message_type());
2939 const Descriptor* baz_type = baz_field_->message_type();
2941 EXPECT_EQ(
"Baz", baz_type->full_name());
2942 EXPECT_EQ(0, baz_type->extension_range_count());
2948 EXPECT_EQ(
"corge.Qux", qux_type->full_name());
2951 EXPECT_EQ(qux_type->FindValueByNumber(0),
nullptr);
2954 EXPECT_EQ(bar_type_,
pool_->FindMessageTypeByName(bar_type_->full_name()));
2955 EXPECT_TRUE(
pool_->FindMessageTypeByName(baz_type->full_name()) ==
nullptr);
2959 TEST_P(AllowUnknownDependenciesTest, CopyTo) {
2965 bar_field_->CopyTo(&proto);
2971 baz_field_->CopyTo(&proto);
2977 qux_field_->CopyTo(&proto);
2982 TEST_P(AllowUnknownDependenciesTest, CustomOptions) {
2984 ASSERT_EQ(1, qux_field_->options().uninterpreted_option_size());
2986 qux_field_->options().uninterpreted_option(0);
2991 TEST_P(AllowUnknownDependenciesTest, UnknownExtendee) {
2998 "name: 'extension.proto'"
2999 "extension { extendee: 'UnknownType' name:'some_extension' number:123"
3000 " label:LABEL_OPTIONAL type:TYPE_INT32 }",
3007 const Descriptor* extendee =
file->extension(0)->containing_type();
3008 EXPECT_EQ(
"UnknownType", extendee->name());
3010 ASSERT_EQ(1, extendee->extension_range_count());
3011 EXPECT_EQ(1, extendee->extension_range(0)->start);
3015 TEST_P(AllowUnknownDependenciesTest, CustomOption) {
3022 "name: \"unknown_custom_options.proto\" "
3023 "dependency: \"google/protobuf/descriptor.proto\" "
3025 " extendee: \"google.protobuf.FileOptions\" "
3026 " name: \"some_option\" "
3028 " label: LABEL_OPTIONAL "
3029 " type: TYPE_INT32 "
3032 " uninterpreted_option { "
3034 " name_part: \"some_option\" "
3035 " is_extension: true "
3037 " positive_int_value: 1234 "
3039 " uninterpreted_option { "
3041 " name_part: \"unknown_option\" "
3042 " is_extension: true "
3044 " positive_int_value: 1234 "
3046 " uninterpreted_option { "
3048 " name_part: \"optimize_for\" "
3049 " is_extension: false "
3051 " identifier_value: \"SPEED\" "
3061 std::vector<const FieldDescriptor*>
fields;
3062 file->options().GetReflection()->ListFields(
file->options(), &
fields);
3068 TEST_P(AllowUnknownDependenciesTest,
3069 UndeclaredDependencyTriggersBuildOfDependency) {
3081 "name: \"invalid_file_as_undeclared_dep.proto\" "
3082 "package: \"undeclared\" "
3086 " name:'qux' number:1 label:LABEL_OPTIONAL type: TYPE_INT32 "
3089 " name:'quux' number:1 label:LABEL_OPTIONAL type: TYPE_INT64 "
3092 &undeclared_dep_proto));
3109 "name: \"test.proto\" "
3113 " name:'quux' number:1 label: LABEL_OPTIONAL "
3114 " type_name:'undeclared.Quux' type: TYPE_MESSAGE "
3127 ASSERT_EQ(1, corge_desc->field_count());
3132 ASSERT_EQ(
"Quux", quux_field->message_type()->name());
3133 ASSERT_EQ(
"undeclared.Quux", quux_field->message_type()->full_name());
3134 EXPECT_TRUE(quux_field->message_type()->is_placeholder());
3146 TEST(CustomOptions, OptionLocations) {
3156 file->FindServiceByName(
"TestServiceWithCustomOptions");
3160 file->options().GetExtension(protobuf_unittest::file_opt1));
3162 message->options().GetExtension(protobuf_unittest::message_opt1));
3164 field->options().GetExtension(protobuf_unittest::field_opt1));
3166 field->options().GetExtension(protobuf_unittest::field_opt2));
3167 EXPECT_EQ(-99, oneof->options().GetExtension(protobuf_unittest::oneof_opt1));
3169 map_field->options().GetExtension(protobuf_unittest::field_opt1));
3170 EXPECT_EQ(-789, enm->options().GetExtension(protobuf_unittest::enum_opt1));
3171 EXPECT_EQ(123, enm->value(1)->options().GetExtension(
3172 protobuf_unittest::enum_value_opt1));
3174 service->options().GetExtension(protobuf_unittest::service_opt1));
3175 EXPECT_EQ(protobuf_unittest::METHODOPT1_VAL2,
3183 TEST(CustomOptions, OptionTypes) {
3224 options->GetExtension(protobuf_unittest::float_opt));
3226 options->GetExtension(protobuf_unittest::double_opt));
3228 options->GetExtension(protobuf_unittest::string_opt));
3231 options->GetExtension(protobuf_unittest::bytes_opt));
3233 EXPECT_EQ(protobuf_unittest::DummyMessageContainingEnum::TEST_OPTION_ENUM_TYPE2,
3234 options->GetExtension(protobuf_unittest::enum_opt));
3247 TEST(CustomOptions, ComplexExtensionOptions) {
3250 EXPECT_EQ(
options->GetExtension(protobuf_unittest::complex_opt1).foo(), 42);
3252 .GetExtension(protobuf_unittest::quux),
3255 .GetExtension(protobuf_unittest::corge)
3258 EXPECT_EQ(
options->GetExtension(protobuf_unittest::complex_opt2).baz(), 987);
3260 .GetExtension(protobuf_unittest::grault),
3262 EXPECT_EQ(
options->GetExtension(protobuf_unittest::complex_opt2).bar().foo(),
3266 .GetExtension(protobuf_unittest::quux),
3270 .GetExtension(protobuf_unittest::corge)
3274 .GetExtension(protobuf_unittest::garply)
3278 .GetExtension(protobuf_unittest::garply)
3279 .GetExtension(protobuf_unittest::quux),
3282 .GetExtension(protobuf_unittest::garply)
3283 .GetExtension(protobuf_unittest::corge)
3287 ->GetExtension(protobuf_unittest::ComplexOptionType2::
3288 ComplexOptionType4::complex_opt4)
3291 EXPECT_EQ(
options->GetExtension(protobuf_unittest::complex_opt2).fred().waldo(),
3293 EXPECT_EQ(9,
options->GetExtension(protobuf_unittest::complex_opt3).qux());
3295 .complexoptiontype5()
3297 EXPECT_EQ(24,
options->GetExtension(protobuf_unittest::complexopt6).xyzzy());
3300 TEST(CustomOptions, OptionsFromOtherFile) {
3319 "name: \"custom_options_import.proto\" "
3320 "package: \"protobuf_unittest\" "
3321 "dependency: \"google/protobuf/unittest_custom_options.proto\" "
3323 " uninterpreted_option { "
3325 " name_part: \"file_opt1\" "
3326 " is_extension: true "
3328 " positive_int_value: 1234 "
3332 " uninterpreted_option { "
3334 " name_part: \"java_package\" "
3335 " is_extension: false "
3337 " string_value: \"foo\" "
3341 " uninterpreted_option { "
3343 " name_part: \"optimize_for\" "
3344 " is_extension: false "
3346 " identifier_value: \"SPEED\" "
3353 EXPECT_EQ(1234,
file->options().GetExtension(protobuf_unittest::file_opt1));
3360 TEST(CustomOptions, MessageOptionThreeFieldsSet) {
3390 "name: \"custom_options_import.proto\" "
3391 "package: \"protobuf_unittest\" "
3392 "dependency: \"google/protobuf/unittest_custom_options.proto\" "
3396 " uninterpreted_option { "
3398 " name_part: \"complex_opt1\" "
3399 " is_extension: true "
3402 " name_part: \"foo\" "
3403 " is_extension: false "
3405 " positive_int_value: 1234 "
3407 " uninterpreted_option { "
3409 " name_part: \"complex_opt1\" "
3410 " is_extension: true "
3413 " name_part: \"foo2\" "
3414 " is_extension: false "
3416 " positive_int_value: 1234 "
3418 " uninterpreted_option { "
3420 " name_part: \"complex_opt1\" "
3421 " is_extension: true "
3424 " name_part: \"foo3\" "
3425 " is_extension: false "
3427 " positive_int_value: 1234 "
3438 EXPECT_EQ(1234,
options.GetExtension(protobuf_unittest::complex_opt1).foo());
3441 TEST(CustomOptions, MessageOptionRepeatedLeafFieldSet) {
3471 "name: \"custom_options_import.proto\" "
3472 "package: \"protobuf_unittest\" "
3473 "dependency: \"google/protobuf/unittest_custom_options.proto\" "
3477 " uninterpreted_option { "
3479 " name_part: \"complex_opt1\" "
3480 " is_extension: true "
3483 " name_part: \"foo4\" "
3484 " is_extension: false "
3486 " positive_int_value: 12 "
3488 " uninterpreted_option { "
3490 " name_part: \"complex_opt1\" "
3491 " is_extension: true "
3494 " name_part: \"foo4\" "
3495 " is_extension: false "
3497 " positive_int_value: 34 "
3499 " uninterpreted_option { "
3501 " name_part: \"complex_opt1\" "
3502 " is_extension: true "
3505 " name_part: \"foo4\" "
3506 " is_extension: false "
3508 " positive_int_value: 56 "
3519 EXPECT_EQ(3,
options.GetExtension(protobuf_unittest::complex_opt1).foo4_size());
3520 EXPECT_EQ(12,
options.GetExtension(protobuf_unittest::complex_opt1).foo4(0));
3521 EXPECT_EQ(34,
options.GetExtension(protobuf_unittest::complex_opt1).foo4(1));
3522 EXPECT_EQ(56,
options.GetExtension(protobuf_unittest::complex_opt1).foo4(2));
3525 TEST(CustomOptions, MessageOptionRepeatedMsgFieldSet) {
3555 "name: \"custom_options_import.proto\" "
3556 "package: \"protobuf_unittest\" "
3557 "dependency: \"google/protobuf/unittest_custom_options.proto\" "
3561 " uninterpreted_option { "
3563 " name_part: \"complex_opt2\" "
3564 " is_extension: true "
3567 " name_part: \"barney\" "
3568 " is_extension: false "
3570 " aggregate_value: \"waldo: 1\" "
3572 " uninterpreted_option { "
3574 " name_part: \"complex_opt2\" "
3575 " is_extension: true "
3578 " name_part: \"barney\" "
3579 " is_extension: false "
3581 " aggregate_value: \"waldo: 10\" "
3583 " uninterpreted_option { "
3585 " name_part: \"complex_opt2\" "
3586 " is_extension: true "
3589 " name_part: \"barney\" "
3590 " is_extension: false "
3592 " aggregate_value: \"waldo: 100\" "
3604 options.GetExtension(protobuf_unittest::complex_opt2).barney_size());
3606 1,
options.GetExtension(protobuf_unittest::complex_opt2).barney(0).waldo());
3609 options.GetExtension(protobuf_unittest::complex_opt2).barney(1).waldo());
3612 options.GetExtension(protobuf_unittest::complex_opt2).barney(2).waldo());
3617 TEST(CustomOptions, AggregateOptions) {
3624 file->FindServiceByName(
"AggregateService");
3628 const protobuf_unittest::Aggregate& file_options =
3629 file->options().GetExtension(protobuf_unittest::fileopt);
3631 EXPECT_EQ(
"FileAnnotation", file_options.s());
3632 EXPECT_EQ(
"NestedFileAnnotation", file_options.sub().s());
3634 file_options.file().GetExtension(protobuf_unittest::fileopt).s());
3637 .GetExtension(protobuf_unittest::AggregateMessageSetElement ::
3638 message_set_extension)
3641 protobuf_unittest::AggregateMessageSetElement any_payload;
3642 ASSERT_TRUE(file_options.any().UnpackTo(&any_payload));
3643 EXPECT_EQ(
"EmbeddedMessageSetElement", any_payload.s());
3647 msg->options().GetExtension(protobuf_unittest::msgopt).s());
3649 field->options().GetExtension(protobuf_unittest::fieldopt).s());
3651 enumd->options().GetExtension(protobuf_unittest::enumopt).s());
3653 enumv->options().GetExtension(protobuf_unittest::enumvalopt).s());
3655 service->options().GetExtension(protobuf_unittest::serviceopt).s());
3660 TEST(CustomOptions, UnusedImportError) {
3675 pool.AddUnusedImportTrackFile(
"custom_options_import.proto",
true);
3677 "name: \"custom_options_import.proto\" "
3678 "package: \"protobuf_unittest\" "
3679 "dependency: \"google/protobuf/unittest_custom_options.proto\" ",
3683 EXPECT_FALSE(
pool.BuildFileCollectingErrors(file_proto, &error_collector));
3685 "custom_options_import.proto: "
3686 "google/protobuf/unittest_custom_options.proto: IMPORT: Import "
3687 "google/protobuf/unittest_custom_options.proto is unused.\n",
3688 error_collector.text_);
3694 TEST(CustomOptions, OptionsWithIncompatibleDescriptors) {
3704 file_proto.
set_name(
"unittest_custom_options.proto");
3712 ->FindExtensionByName(
"required_enum_opt")
3722 extension->set_type_name(
".protobuf_unittest.NewOptionType");
3731 " name_part: 'required_enum_opt' "
3732 " is_extension: true "
3734 " aggregate_value: 'value: NEW_VALUE'"
3760 "name: \"foo.proto\" "
3761 "package: \"protobuf_unittest\" "
3762 "dependency: \"google/protobuf/descriptor.proto\" "
3764 " uninterpreted_option { "
3766 " name_part: \"protobuf_unittest.cc_option1\" "
3767 " is_extension: true "
3769 " positive_int_value: 1 "
3771 " uninterpreted_option { "
3773 " name_part: \"protobuf_unittest.cc_option2\" "
3774 " is_extension: true "
3776 " positive_int_value: 2 "
3780 " name: \"cc_option1\" "
3781 " extendee: \".google.protobuf.FileOptions\" "
3788 " label: LABEL_OPTIONAL "
3789 " type: TYPE_INT32 "
3792 " name: \"cc_option2\" "
3793 " extendee: \".google.protobuf.FileOptions\" "
3795 " label: LABEL_OPTIONAL "
3796 " type: TYPE_INT32 "
3805 "syntax = \"proto2\";\n"
3807 "import \"google/protobuf/descriptor.proto\";\n"
3808 "package protobuf_unittest;\n"
3810 "option (.protobuf_unittest.cc_option1) = 1;\n"
3811 "option (.protobuf_unittest.cc_option2) = 2;\n"
3813 "extend .google.protobuf.FileOptions {\n"
3814 " optional int32 cc_option1 = 7736974;\n"
3815 " optional int32 cc_option2 = 7736975;\n"
3844 EXPECT_EQ(expected_errors, error_collector.text_);
3857 EXPECT_EQ(expected_warnings, error_collector.warning_text_);
3863 file->CopyTo(&file_proto);
3876 TEST_F(ValidationErrorTest, AlreadyDefined) {
3877 BuildFileWithErrors(
3878 "name: \"foo.proto\" "
3879 "message_type { name: \"Foo\" }"
3880 "message_type { name: \"Foo\" }",
3882 "foo.proto: Foo: NAME: \"Foo\" is already defined.\n");
3885 TEST_F(ValidationErrorTest, AlreadyDefinedInPackage) {
3886 BuildFileWithErrors(
3887 "name: \"foo.proto\" "
3888 "package: \"foo.bar\" "
3889 "message_type { name: \"Foo\" }"
3890 "message_type { name: \"Foo\" }",
3892 "foo.proto: foo.bar.Foo: NAME: \"Foo\" is already defined in "
3896 TEST_F(ValidationErrorTest, AlreadyDefinedInOtherFile) {
3898 "name: \"foo.proto\" "
3899 "message_type { name: \"Foo\" }");
3901 BuildFileWithErrors(
3902 "name: \"bar.proto\" "
3903 "message_type { name: \"Foo\" }",
3905 "bar.proto: Foo: NAME: \"Foo\" is already defined in file "
3906 "\"foo.proto\".\n");
3909 TEST_F(ValidationErrorTest, PackageAlreadyDefined) {
3911 "name: \"foo.proto\" "
3912 "message_type { name: \"foo\" }");
3913 BuildFileWithErrors(
3914 "name: \"bar.proto\" "
3915 "package: \"foo.bar\"",
3917 "bar.proto: foo: NAME: \"foo\" is already defined (as something other "
3918 "than a package) in file \"foo.proto\".\n");
3921 TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParent) {
3922 BuildFileWithErrors(
3923 "name: \"foo.proto\" "
3924 "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } "
3925 "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ",
3927 "foo.proto: FOO: NAME: \"FOO\" is already defined.\n"
3928 "foo.proto: FOO: NAME: Note that enum values use C++ scoping rules, "
3929 "meaning that enum values are siblings of their type, not children of "
3930 "it. Therefore, \"FOO\" must be unique within the global scope, not "
3931 "just within \"Bar\".\n");
3934 TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParentNonGlobal) {
3935 BuildFileWithErrors(
3936 "name: \"foo.proto\" "
3938 "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } "
3939 "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ",
3941 "foo.proto: pkg.FOO: NAME: \"FOO\" is already defined in \"pkg\".\n"
3942 "foo.proto: pkg.FOO: NAME: Note that enum values use C++ scoping rules, "
3943 "meaning that enum values are siblings of their type, not children of "
3944 "it. Therefore, \"FOO\" must be unique within \"pkg\", not just within "
3948 TEST_F(ValidationErrorTest, MissingName) {
3949 BuildFileWithErrors(
3950 "name: \"foo.proto\" "
3953 "foo.proto: : NAME: Missing name.\n");
3956 TEST_F(ValidationErrorTest, InvalidName) {
3957 BuildFileWithErrors(
3958 "name: \"foo.proto\" "
3959 "message_type { name: \"$\" }",
3961 "foo.proto: $: NAME: \"$\" is not a valid identifier.\n");
3964 TEST_F(ValidationErrorTest, InvalidPackageName) {
3965 BuildFileWithErrors(
3966 "name: \"foo.proto\" "
3967 "package: \"foo.$\"",
3969 "foo.proto: foo.$: NAME: \"$\" is not a valid identifier.\n");
3973 #define STATIC_STR(str) std::string((str), sizeof(str) - 1)
3976 BuildFileWithErrors(
3977 "name: \"bar.proto\" "
3980 " name: '\\000\\001\\013.Bar' "
3981 " field { name: \"foo\" number: 9 label:LABEL_OPTIONAL type:TYPE_INT32 "
3984 STATIC_STR(
"bar.proto: foo.\0\x1\v.Bar: NAME: \"\0\x1\v.Bar\" is not a "
3985 "valid identifier.\nbar.proto: foo.\0\x1\v.Bar: NAME: "
3986 "\"\0\x1\v.Bar\" is not a valid identifier.\nbar.proto: "
3987 "foo.\0\x1\v.Bar: NAME: \"\0\x1\v.Bar\" is not a valid "
3988 "identifier.\nbar.proto: foo.\0\x1\v.Bar: NAME: "
3989 "\"\0\x1\v.Bar\" is not a valid identifier.\nbar.proto: "
3990 "foo.\0\x1\v.Bar.foo: NAME: \"foo.\0\x1\v.Bar.foo\" contains "
3991 "null character.\nbar.proto: foo.\0\x1\v.Bar: NAME: "
3992 "\"foo.\0\x1\v.Bar\" contains null character.\n"));
3996 BuildFileWithErrors(
3997 "name: \"bar\\000\\001\\013.proto\" "
3998 "package: \"outer.foo\"",
3999 STATIC_STR(
"bar\0\x1\v.proto: bar\0\x1\v.proto: NAME: "
4000 "\"bar\0\x1\v.proto\" contains null character.\n"));
4004 BuildFileWithErrors(
4005 "name: \"bar.proto\" "
4006 "package: \"\\000\\001\\013.\"",
4007 STATIC_STR(
"bar.proto: \0\x1\v.: NAME: \"\0\x1\v.\" contains null "
4011 TEST_F(ValidationErrorTest, MissingFileName) {
4012 BuildFileWithErrors(
"",
4014 ": : OTHER: Missing field: FileDescriptorProto.name.\n");
4017 TEST_F(ValidationErrorTest, DupeDependency) {
4018 BuildFile(
"name: \"foo.proto\"");
4019 BuildFileWithErrors(
4020 "name: \"bar.proto\" "
4021 "dependency: \"foo.proto\" "
4022 "dependency: \"foo.proto\" ",
4024 "bar.proto: foo.proto: IMPORT: Import \"foo.proto\" was listed twice.\n");
4027 TEST_F(ValidationErrorTest, UnknownDependency) {
4028 BuildFileWithErrors(
4029 "name: \"bar.proto\" "
4030 "dependency: \"foo.proto\" ",
4032 "bar.proto: foo.proto: IMPORT: Import \"foo.proto\" has not been "
4036 TEST_F(ValidationErrorTest, InvalidPublicDependencyIndex) {
4037 BuildFile(
"name: \"foo.proto\"");
4038 BuildFileWithErrors(
4039 "name: \"bar.proto\" "
4040 "dependency: \"foo.proto\" "
4041 "public_dependency: 1",
4042 "bar.proto: bar.proto: OTHER: Invalid public dependency index.\n");
4045 TEST_F(ValidationErrorTest, ForeignUnimportedPackageNoCrash) {
4052 "name: 'foo.proto' "
4053 "package: 'outer.foo' ");
4054 BuildFileWithErrors(
4055 "name: 'bar.proto' "
4056 "dependency: 'baz.proto' "
4057 "package: 'outer.bar' "
4060 " field { name:'bar' number:1 label:LABEL_OPTIONAL type_name:'foo.Foo' }"
4063 "bar.proto: baz.proto: IMPORT: Import \"baz.proto\" has not been "
4065 "bar.proto: outer.bar.Bar.bar: TYPE: \"outer.foo\" seems to be defined "
4067 "\"foo.proto\", which is not imported by \"bar.proto\". To use it here, "
4068 "please add the necessary import.\n");
4071 TEST_F(ValidationErrorTest, DupeFile) {
4073 "name: \"foo.proto\" "
4074 "message_type { name: \"Foo\" }");
4077 BuildFileWithErrors(
4078 "name: \"foo.proto\" "
4079 "message_type { name: \"Foo\" } "
4082 "enum_type { name: \"Bar\" }",
4084 "foo.proto: foo.proto: OTHER: A file with this name is already in the "
4088 TEST_F(ValidationErrorTest, FieldInExtensionRange) {
4089 BuildFileWithErrors(
4090 "name: \"foo.proto\" "
4093 " field { name: \"foo\" number: 9 label:LABEL_OPTIONAL type:TYPE_INT32 "
4095 " field { name: \"bar\" number: 10 label:LABEL_OPTIONAL type:TYPE_INT32 "
4097 " field { name: \"baz\" number: 19 label:LABEL_OPTIONAL type:TYPE_INT32 "
4099 " field { name: \"qux\" number: 20 label:LABEL_OPTIONAL type:TYPE_INT32 "
4101 " extension_range { start: 10 end: 20 }"
4104 "foo.proto: Foo.bar: NUMBER: Extension range 10 to 19 includes field "
4106 "foo.proto: Foo.baz: NUMBER: Extension range 10 to 19 includes field "
4110 TEST_F(ValidationErrorTest, OverlappingExtensionRanges) {
4111 BuildFileWithErrors(
4112 "name: \"foo.proto\" "
4115 " extension_range { start: 10 end: 20 }"
4116 " extension_range { start: 20 end: 30 }"
4117 " extension_range { start: 19 end: 21 }"
4120 "foo.proto: Foo: NUMBER: Extension range 19 to 20 overlaps with "
4121 "already-defined range 10 to 19.\n"
4122 "foo.proto: Foo: NUMBER: Extension range 19 to 20 overlaps with "
4123 "already-defined range 20 to 29.\n");
4126 TEST_F(ValidationErrorTest, ReservedFieldError) {
4127 BuildFileWithErrors(
4128 "name: \"foo.proto\" "
4131 " field { name: \"foo\" number: 15 label:LABEL_OPTIONAL type:TYPE_INT32 "
4133 " reserved_range { start: 10 end: 20 }"
4136 "foo.proto: Foo.foo: NUMBER: Field \"foo\" uses reserved number 15.\n");
4139 TEST_F(ValidationErrorTest, ReservedExtensionRangeError) {
4140 BuildFileWithErrors(
4141 "name: \"foo.proto\" "
4144 " extension_range { start: 10 end: 20 }"
4145 " reserved_range { start: 5 end: 15 }"
4148 "foo.proto: Foo: NUMBER: Extension range 10 to 19"
4149 " overlaps with reserved range 5 to 14.\n");
4152 TEST_F(ValidationErrorTest, ReservedExtensionRangeAdjacent) {
4154 "name: \"foo.proto\" "
4157 " extension_range { start: 10 end: 20 }"
4158 " reserved_range { start: 5 end: 10 }"
4162 TEST_F(ValidationErrorTest, ReservedRangeOverlap) {
4163 BuildFileWithErrors(
4164 "name: \"foo.proto\" "
4167 " reserved_range { start: 10 end: 20 }"
4168 " reserved_range { start: 5 end: 15 }"
4171 "foo.proto: Foo: NUMBER: Reserved range 5 to 14"
4172 " overlaps with already-defined range 10 to 19.\n");
4175 TEST_F(ValidationErrorTest, ReservedNameError) {
4176 BuildFileWithErrors(
4177 "name: \"foo.proto\" "
4180 " field { name: \"foo\" number: 15 label:LABEL_OPTIONAL type:TYPE_INT32 "
4182 " field { name: \"bar\" number: 16 label:LABEL_OPTIONAL type:TYPE_INT32 "
4184 " field { name: \"baz\" number: 17 label:LABEL_OPTIONAL type:TYPE_INT32 "
4186 " reserved_name: \"foo\""
4187 " reserved_name: \"bar\""
4190 "foo.proto: Foo.foo: NAME: Field name \"foo\" is reserved.\n"
4191 "foo.proto: Foo.bar: NAME: Field name \"bar\" is reserved.\n");
4194 TEST_F(ValidationErrorTest, ReservedNameRedundant) {
4195 BuildFileWithErrors(
4196 "name: \"foo.proto\" "
4199 " reserved_name: \"foo\""
4200 " reserved_name: \"foo\""
4203 "foo.proto: foo: NAME: Field name \"foo\" is reserved multiple times.\n");
4206 TEST_F(ValidationErrorTest, ReservedFieldsDebugString) {
4208 "name: \"foo.proto\" "
4211 " reserved_name: \"foo\""
4212 " reserved_name: \"bar\""
4213 " reserved_range { start: 5 end: 6 }"
4214 " reserved_range { start: 10 end: 20 }"
4218 "syntax = \"proto2\";\n\n"
4220 " reserved 5, 10 to 19;\n"
4221 " reserved \"foo\", \"bar\";\n"
4223 file->DebugString());
4228 "name: \"foo.proto\" "
4231 " value { name:\"BAR\" number:1 }"
4232 " reserved_range { start: 5 end: $0 }"
4236 " reserved_range { start: 5 end: $1 }"
4241 "syntax = \"proto2\";\n\n"
4244 " reserved 5 to max;\n"
4247 " reserved 5 to max;\n"
4249 file->DebugString());
4252 TEST_F(ValidationErrorTest, EnumReservedFieldError) {
4253 BuildFileWithErrors(
4254 "name: \"foo.proto\" "
4257 " value { name:\"BAR\" number:15 }"
4258 " reserved_range { start: 10 end: 20 }"
4261 "foo.proto: BAR: NUMBER: Enum value \"BAR\" uses reserved number 15.\n");
4264 TEST_F(ValidationErrorTest, EnumNegativeReservedFieldError) {
4265 BuildFileWithErrors(
4266 "name: \"foo.proto\" "
4269 " value { name:\"BAR\" number:-15 }"
4270 " reserved_range { start: -20 end: -10 }"
4273 "foo.proto: BAR: NUMBER: Enum value \"BAR\" uses reserved number -15.\n");
4276 TEST_F(ValidationErrorTest, EnumReservedRangeOverlap) {
4277 BuildFileWithErrors(
4278 "name: \"foo.proto\" "
4281 " value { name:\"BAR\" number:0 }"
4282 " reserved_range { start: 10 end: 20 }"
4283 " reserved_range { start: 5 end: 15 }"
4286 "foo.proto: Foo: NUMBER: Reserved range 5 to 15"
4287 " overlaps with already-defined range 10 to 20.\n");
4290 TEST_F(ValidationErrorTest, EnumReservedRangeOverlapByOne) {
4291 BuildFileWithErrors(
4292 "name: \"foo.proto\" "
4295 " value { name:\"BAR\" number:0 }"
4296 " reserved_range { start: 10 end: 20 }"
4297 " reserved_range { start: 5 end: 10 }"
4300 "foo.proto: Foo: NUMBER: Reserved range 5 to 10"
4301 " overlaps with already-defined range 10 to 20.\n");
4304 TEST_F(ValidationErrorTest, EnumNegativeReservedRangeOverlap) {
4305 BuildFileWithErrors(
4306 "name: \"foo.proto\" "
4309 " value { name:\"BAR\" number:0 }"
4310 " reserved_range { start: -20 end: -10 }"
4311 " reserved_range { start: -15 end: -5 }"
4314 "foo.proto: Foo: NUMBER: Reserved range -15 to -5"
4315 " overlaps with already-defined range -20 to -10.\n");
4318 TEST_F(ValidationErrorTest, EnumMixedReservedRangeOverlap) {
4319 BuildFileWithErrors(
4320 "name: \"foo.proto\" "
4323 " value { name:\"BAR\" number:20 }"
4324 " reserved_range { start: -20 end: 10 }"
4325 " reserved_range { start: -15 end: 5 }"
4328 "foo.proto: Foo: NUMBER: Reserved range -15 to 5"
4329 " overlaps with already-defined range -20 to 10.\n");
4332 TEST_F(ValidationErrorTest, EnumMixedReservedRangeOverlap2) {
4333 BuildFileWithErrors(
4334 "name: \"foo.proto\" "
4337 " value { name:\"BAR\" number:20 }"
4338 " reserved_range { start: -20 end: 10 }"
4339 " reserved_range { start: 10 end: 10 }"
4342 "foo.proto: Foo: NUMBER: Reserved range 10 to 10"
4343 " overlaps with already-defined range -20 to 10.\n");
4346 TEST_F(ValidationErrorTest, EnumReservedRangeStartGreaterThanEnd) {
4347 BuildFileWithErrors(
4348 "name: \"foo.proto\" "
4351 " value { name:\"BAR\" number:20 }"
4352 " reserved_range { start: 11 end: 10 }"
4355 "foo.proto: Foo: NUMBER: Reserved range end number must be greater"
4356 " than start number.\n");
4359 TEST_F(ValidationErrorTest, EnumReservedNameError) {
4360 BuildFileWithErrors(
4361 "name: \"foo.proto\" "
4364 " value { name:\"FOO\" number:15 }"
4365 " value { name:\"BAR\" number:15 }"
4366 " reserved_name: \"FOO\""
4367 " reserved_name: \"BAR\""
4370 "foo.proto: FOO: NAME: Enum value \"FOO\" is reserved.\n"
4371 "foo.proto: BAR: NAME: Enum value \"BAR\" is reserved.\n");
4374 TEST_F(ValidationErrorTest, EnumReservedNameRedundant) {
4375 BuildFileWithErrors(
4376 "name: \"foo.proto\" "
4379 " value { name:\"FOO\" number:15 }"
4380 " reserved_name: \"foo\""
4381 " reserved_name: \"foo\""
4384 "foo.proto: foo: NAME: Enum value \"foo\" is reserved multiple times.\n");
4387 TEST_F(ValidationErrorTest, EnumReservedFieldsDebugString) {
4389 "name: \"foo.proto\" "
4392 " value { name:\"FOO\" number:3 }"
4393 " reserved_name: \"foo\""
4394 " reserved_name: \"bar\""
4395 " reserved_range { start: -6 end: -6 }"
4396 " reserved_range { start: -5 end: -4 }"
4397 " reserved_range { start: -1 end: 1 }"
4398 " reserved_range { start: 5 end: 5 }"
4399 " reserved_range { start: 10 end: 19 }"
4403 "syntax = \"proto2\";\n\n"
4406 " reserved -6, -5 to -4, -1 to 1, 5, 10 to 19;\n"
4407 " reserved \"foo\", \"bar\";\n"
4409 file->DebugString());
4412 TEST_F(ValidationErrorTest, InvalidDefaults) {
4413 BuildFileWithErrors(
4414 "name: \"foo.proto\" "
4419 " field { name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32"
4420 " default_value: \"abc\" }"
4423 " field { name: \"bar\" number: 2 label: LABEL_OPTIONAL type: TYPE_INT32"
4424 " default_value: \"\" }"
4427 " field { name: \"baz\" number: 3 label: LABEL_OPTIONAL type: TYPE_BOOL"
4428 " default_value: \"abc\" }"
4431 " field { name: \"qux\" number: 4 label: LABEL_OPTIONAL type: "
4433 " default_value: \"abc\" type_name: \"Foo\" }"
4437 " field { name: \"quux\" number: 5 label: LABEL_OPTIONAL"
4438 " default_value: \"abc\" type_name: \"Foo\" }"
4441 " field { name: \"corge\" number: 6 label: LABEL_REPEATED type: "
4443 " default_value: \"1\" }"
4446 "foo.proto: Foo.foo: DEFAULT_VALUE: Couldn't parse default value "
4448 "foo.proto: Foo.bar: DEFAULT_VALUE: Couldn't parse default value \"\".\n"
4449 "foo.proto: Foo.baz: DEFAULT_VALUE: Boolean default must be true or "
4451 "foo.proto: Foo.qux: DEFAULT_VALUE: Messages can't have default values.\n"
4452 "foo.proto: Foo.corge: DEFAULT_VALUE: Repeated fields can't have default "
4456 "foo.proto: Foo.quux: DEFAULT_VALUE: Messages can't have default "
4460 TEST_F(ValidationErrorTest, NegativeFieldNumber) {
4461 BuildFileWithErrors(
4462 "name: \"foo.proto\" "
4465 " field { name: \"foo\" number: -1 label:LABEL_OPTIONAL type:TYPE_INT32 "
4469 "foo.proto: Foo.foo: NUMBER: Field numbers must be positive integers.\n");
4472 TEST_F(ValidationErrorTest, HugeFieldNumber) {
4473 BuildFileWithErrors(
4474 "name: \"foo.proto\" "
4477 " field { name: \"foo\" number: 0x70000000 "
4478 " label:LABEL_OPTIONAL type:TYPE_INT32 }"
4481 "foo.proto: Foo.foo: NUMBER: Field numbers cannot be greater than "
4485 TEST_F(ValidationErrorTest, ReservedFieldNumber) {
4486 BuildFileWithErrors(
4487 "name: \"foo.proto\" "
4490 " field {name:\"foo\" number: 18999 label:LABEL_OPTIONAL "
4492 " field {name:\"bar\" number: 19000 label:LABEL_OPTIONAL "
4494 " field {name:\"baz\" number: 19999 label:LABEL_OPTIONAL "
4496 " field {name:\"qux\" number: 20000 label:LABEL_OPTIONAL "
4500 "foo.proto: Foo.bar: NUMBER: Field numbers 19000 through 19999 are "
4501 "reserved for the protocol buffer library implementation.\n"
4502 "foo.proto: Foo.baz: NUMBER: Field numbers 19000 through 19999 are "
4503 "reserved for the protocol buffer library implementation.\n");
4506 TEST_F(ValidationErrorTest, ExtensionMissingExtendee) {
4507 BuildFileWithErrors(
4508 "name: \"foo.proto\" "
4511 " extension { name: \"foo\" number: 1 label: LABEL_OPTIONAL"
4512 " type_name: \"Foo\" }"
4515 "foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee not set for "
4516 "extension field.\n");
4519 TEST_F(ValidationErrorTest, NonExtensionWithExtendee) {
4520 BuildFileWithErrors(
4521 "name: \"foo.proto\" "
4524 " extension_range { start: 1 end: 2 }"
4528 " field { name: \"foo\" number: 1 label: LABEL_OPTIONAL"
4529 " type_name: \"Foo\" extendee: \"Bar\" }"
4532 "foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee set for "
4533 "non-extension field.\n");
4536 TEST_F(ValidationErrorTest, FieldOneofIndexTooLarge) {
4537 BuildFileWithErrors(
4538 "name: \"foo.proto\" "
4541 " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32 "
4543 " field { name:\"dummy\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 "
4545 " oneof_decl { name:\"bar\" }"
4548 "foo.proto: Foo.foo: TYPE: FieldDescriptorProto.oneof_index 1 is out of "
4549 "range for type \"Foo\".\n");
4552 TEST_F(ValidationErrorTest, FieldOneofIndexNegative) {
4553 BuildFileWithErrors(
4554 "name: \"foo.proto\" "
4557 " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32 "
4558 " oneof_index: -1 }"
4559 " field { name:\"dummy\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 "
4561 " oneof_decl { name:\"bar\" }"
4564 "foo.proto: Foo.foo: TYPE: FieldDescriptorProto.oneof_index -1 is out "
4566 "range for type \"Foo\".\n");
4569 TEST_F(ValidationErrorTest, OneofFieldsConsecutiveDefinition) {
4571 BuildFileWithErrors(
4572 "name: \"foo.proto\" "
4575 " field { name:\"foo1\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 "
4577 " field { name:\"bar\" number: 2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
4578 " field { name:\"foo2\" number: 3 label:LABEL_OPTIONAL type:TYPE_INT32 "
4580 " oneof_decl { name:\"foos\" }"
4583 "foo.proto: Foo.bar: TYPE: Fields in the same oneof must be defined "
4584 "consecutively. \"bar\" cannot be defined before the completion of the "
4585 "\"foos\" oneof definition.\n");
4588 BuildFileWithErrors(
4589 "name: \"foo2.proto\" "
4592 " field { name:\"foo1\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 "
4594 " field { name:\"bar1\" number: 2 label:LABEL_OPTIONAL type:TYPE_INT32 "
4596 " field { name:\"foo2\" number: 3 label:LABEL_OPTIONAL type:TYPE_INT32 "
4598 " field { name:\"bar2\" number: 4 label:LABEL_OPTIONAL type:TYPE_INT32 "
4600 " oneof_decl { name:\"foos\" }"
4601 " oneof_decl { name:\"bars\" }"
4603 "foo2.proto: Foo2.bar1: TYPE: Fields in the same oneof must be defined "
4604 "consecutively. \"bar1\" cannot be defined before the completion of the "
4605 "\"foos\" oneof definition.\n"
4606 "foo2.proto: Foo2.foo2: TYPE: Fields in the same oneof must be defined "
4607 "consecutively. \"foo2\" cannot be defined before the completion of the "
4608 "\"bars\" oneof definition.\n");
4611 BuildFileWithErrors(
4612 "name: \"foo3.proto\" "
4615 " field { name:\"foo1\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 "
4617 " field { name:\"bar1\" number: 2 label:LABEL_OPTIONAL type:TYPE_INT32 "
4619 " field { name:\"baz\" number: 3 label:LABEL_OPTIONAL type:TYPE_INT32 }"
4620 " field { name:\"foo2\" number: 4 label:LABEL_OPTIONAL type:TYPE_INT32 "
4622 " oneof_decl { name:\"foos\" }"
4623 " oneof_decl { name:\"bars\" }"
4625 "foo3.proto: Foo3.baz: TYPE: Fields in the same oneof must be defined "
4626 "consecutively. \"baz\" cannot be defined before the completion of the "
4627 "\"foos\" oneof definition.\n");
4630 TEST_F(ValidationErrorTest, FieldNumberConflict) {
4631 BuildFileWithErrors(
4632 "name: \"foo.proto\" "
4635 " field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
4636 " field { name: \"bar\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
4639 "foo.proto: Foo.bar: NUMBER: Field number 1 has already been used in "
4640 "\"Foo\" by field \"foo\".\n");
4643 TEST_F(ValidationErrorTest, BadMessageSetExtensionType) {
4644 BuildFileWithErrors(
4645 "name: \"foo.proto\" "
4647 " name: \"MessageSet\""
4648 " options { message_set_wire_format: true }"
4649 " extension_range { start: 4 end: 5 }"
4653 " extension { name:\"foo\" number:4 label:LABEL_OPTIONAL type:TYPE_INT32"
4654 " extendee: \"MessageSet\" }"
4657 "foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional "
4661 TEST_F(ValidationErrorTest, BadMessageSetExtensionLabel) {
4662 BuildFileWithErrors(
4663 "name: \"foo.proto\" "
4665 " name: \"MessageSet\""
4666 " options { message_set_wire_format: true }"
4667 " extension_range { start: 4 end: 5 }"
4671 " extension { name:\"foo\" number:4 label:LABEL_REPEATED "
4673 " type_name: \"Foo\" extendee: \"MessageSet\" }"
4676 "foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional "
4680 TEST_F(ValidationErrorTest, FieldInMessageSet) {
4681 BuildFileWithErrors(
4682 "name: \"foo.proto\" "
4685 " options { message_set_wire_format: true }"
4686 " field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
4689 "foo.proto: Foo.foo: NAME: MessageSets cannot have fields, only "
4693 TEST_F(ValidationErrorTest, NegativeExtensionRangeNumber) {
4694 BuildFileWithErrors(
4695 "name: \"foo.proto\" "
4698 " extension_range { start: -10 end: -1 }"
4701 "foo.proto: Foo: NUMBER: Extension numbers must be positive integers.\n");
4704 TEST_F(ValidationErrorTest, HugeExtensionRangeNumber) {
4705 BuildFileWithErrors(
4706 "name: \"foo.proto\" "
4709 " extension_range { start: 1 end: 0x70000000 }"
4712 "foo.proto: Foo: NUMBER: Extension numbers cannot be greater than "
4716 TEST_F(ValidationErrorTest, ExtensionRangeEndBeforeStart) {
4717 BuildFileWithErrors(
4718 "name: \"foo.proto\" "
4721 " extension_range { start: 10 end: 10 }"
4722 " extension_range { start: 10 end: 5 }"
4725 "foo.proto: Foo: NUMBER: Extension range end number must be greater than "
4727 "foo.proto: Foo: NUMBER: Extension range end number must be greater than "
4731 TEST_F(ValidationErrorTest, EmptyEnum) {
4732 BuildFileWithErrors(
4733 "name: \"foo.proto\" "
4734 "enum_type { name: \"Foo\" }"
4740 " field { name: \"foo\" number: 1 label:LABEL_OPTIONAL "
4741 "type_name:\"Foo\" }"
4742 " field { name: \"bar\" number: 2 label:LABEL_OPTIONAL "
4743 "type_name:\"Foo\" "
4744 " default_value: \"NO_SUCH_VALUE\" }"
4747 "foo.proto: Foo: NAME: Enums must contain at least one value.\n"
4748 "foo.proto: Bar.bar: DEFAULT_VALUE: Enum type \"Foo\" has no value named "
4749 "\"NO_SUCH_VALUE\".\n");
4752 TEST_F(ValidationErrorTest, UndefinedExtendee) {
4753 BuildFileWithErrors(
4754 "name: \"foo.proto\" "
4757 " extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
4758 " extendee: \"Bar\" }"
4761 "foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not defined.\n");
4764 TEST_F(ValidationErrorTest, NonMessageExtendee) {
4765 BuildFileWithErrors(
4766 "name: \"foo.proto\" "
4767 "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } }"
4770 " extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
4771 " extendee: \"Bar\" }"
4774 "foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not a message type.\n");
4777 TEST_F(ValidationErrorTest, NotAnExtensionNumber) {
4778 BuildFileWithErrors(
4779 "name: \"foo.proto\" "
4785 " extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
4786 " extendee: \"Bar\" }"
4789 "foo.proto: Foo.foo: NUMBER: \"Bar\" does not declare 1 as an extension "
4793 TEST_F(ValidationErrorTest, RequiredExtension) {
4794 BuildFileWithErrors(
4795 "name: \"foo.proto\" "
4798 " extension_range { start: 1000 end: 10000 }"
4805 " label:LABEL_REQUIRED"
4807 " extendee: \"Bar\""
4811 "foo.proto: Foo.foo: TYPE: The extension Foo.foo cannot be required.\n");
4814 TEST_F(ValidationErrorTest, UndefinedFieldType) {
4815 BuildFileWithErrors(
4816 "name: \"foo.proto\" "
4819 " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
4822 "foo.proto: Foo.foo: TYPE: \"Bar\" is not defined.\n");
4825 TEST_F(ValidationErrorTest, UndefinedFieldTypeWithDefault) {
4830 BuildFileWithErrors(
4831 "name: \"foo.proto\" "
4834 " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"int\" "
4835 " default_value:\"1\" }"
4838 "foo.proto: Foo.foo: TYPE: \"int\" is not defined.\n");
4841 TEST_F(ValidationErrorTest, UndefinedNestedFieldType) {
4842 BuildFileWithErrors(
4843 "name: \"foo.proto\" "
4846 " nested_type { name:\"Baz\" }"
4847 " field { name:\"foo\" number:1"
4848 " label:LABEL_OPTIONAL"
4849 " type_name:\"Foo.Baz.Bar\" }"
4852 "foo.proto: Foo.foo: TYPE: \"Foo.Baz.Bar\" is not defined.\n");
4855 TEST_F(ValidationErrorTest, FieldTypeDefinedInUndeclaredDependency) {
4857 "name: \"bar.proto\" "
4858 "message_type { name: \"Bar\" } ");
4860 BuildFileWithErrors(
4861 "name: \"foo.proto\" "
4864 " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
4866 "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", "
4867 "which is not imported by \"foo.proto\". To use it here, please add the "
4868 "necessary import.\n");
4871 TEST_F(ValidationErrorTest, FieldTypeDefinedInIndirectDependency) {
4887 "name: \"bar.proto\" "
4888 "message_type { name: \"Bar\" }");
4891 "name: \"forward.proto\""
4892 "dependency: \"bar.proto\"");
4894 BuildFileWithErrors(
4895 "name: \"foo.proto\" "
4896 "dependency: \"forward.proto\" "
4899 " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
4901 "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", "
4902 "which is not imported by \"foo.proto\". To use it here, please add the "
4903 "necessary import.\n");
4906 TEST_F(ValidationErrorTest, FieldTypeDefinedInPublicDependency) {
4924 "name: \"bar.proto\" "
4925 "message_type { name: \"Bar\" }");
4928 "name: \"forward.proto\""
4929 "dependency: \"bar.proto\" "
4930 "public_dependency: 0");
4933 "name: \"foo.proto\" "
4934 "dependency: \"forward.proto\" "
4937 " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
4941 TEST_F(ValidationErrorTest, FieldTypeDefinedInTransitivePublicDependency) {
4960 "name: \"bar.proto\" "
4961 "message_type { name: \"Bar\" }");
4964 "name: \"forward.proto\""
4965 "dependency: \"bar.proto\" "
4966 "public_dependency: 0");
4969 "name: \"forward2.proto\""
4970 "dependency: \"forward.proto\" "
4971 "public_dependency: 0");
4974 "name: \"foo.proto\" "
4975 "dependency: \"forward2.proto\" "
4978 " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
4982 TEST_F(ValidationErrorTest,
4983 FieldTypeDefinedInPrivateDependencyOfPublicDependency) {
5004 "name: \"bar.proto\" "
5005 "message_type { name: \"Bar\" }");
5008 "name: \"forward.proto\""
5009 "dependency: \"bar.proto\"");
5012 "name: \"forward2.proto\""
5013 "dependency: \"forward.proto\" "
5014 "public_dependency: 0");
5016 BuildFileWithErrors(
5017 "name: \"foo.proto\" "
5018 "dependency: \"forward2.proto\" "
5021 " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
5023 "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", "
5024 "which is not imported by \"foo.proto\". To use it here, please add the "
5025 "necessary import.\n");
5029 TEST_F(ValidationErrorTest, SearchMostLocalFirst) {
5044 BuildFileWithErrors(
5045 "name: \"foo.proto\" "
5048 " nested_type { name: \"Baz\" }"
5052 " nested_type { name: \"Bar\" }"
5053 " field { name:\"baz\" number:1 label:LABEL_OPTIONAL"
5054 " type_name:\"Bar.Baz\" }"
5057 "foo.proto: Foo.baz: TYPE: \"Bar.Baz\" is resolved to \"Foo.Bar.Baz\","
5058 " which is not defined. The innermost scope is searched first in name "
5059 "resolution. Consider using a leading '.'(i.e., \".Bar.Baz\") to start "
5060 "from the outermost scope.\n");
5063 TEST_F(ValidationErrorTest, SearchMostLocalFirst2) {
5068 "name: \"foo.proto\" "
5071 " nested_type { name: \"Baz\" }"
5075 " field { name: \"Bar\" number:1 type:TYPE_BYTES } "
5076 " field { name:\"baz\" number:2 label:LABEL_OPTIONAL"
5077 " type_name:\"Bar.Baz\" }"
5081 TEST_F(ValidationErrorTest, PackageOriginallyDeclaredInTransitiveDependent) {
5104 "name: \"foo.proto\" "
5105 "package: \"foo.bar\" ");
5107 "name: \"bar.proto\" "
5108 "package: \"foo.bar\" "
5109 "dependency: \"foo.proto\" "
5110 "message_type { name: \"Bar\" }");
5112 "name: \"baz.proto\" "
5114 "dependency: \"bar.proto\" "
5117 " field { name:\"qux\" number:1 label:LABEL_OPTIONAL "
5118 " type_name:\"bar.Bar\" }"
5122 TEST_F(ValidationErrorTest, FieldTypeNotAType) {
5123 BuildFileWithErrors(
5124 "name: \"foo.proto\" "
5127 " field { name:\"foo\" number:1 label:LABEL_OPTIONAL "
5128 " type_name:\".Foo.bar\" }"
5129 " field { name:\"bar\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
5132 "foo.proto: Foo.foo: TYPE: \".Foo.bar\" is not a type.\n");
5135 TEST_F(ValidationErrorTest, RelativeFieldTypeNotAType) {
5136 BuildFileWithErrors(
5137 "name: \"foo.proto\" "
5141 " field { name:\"Baz\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
5144 " field { name:\"foo\" number:1 label:LABEL_OPTIONAL "
5145 " type_name:\"Bar.Baz\" }"
5147 "foo.proto: Foo.foo: TYPE: \"Bar.Baz\" is not a type.\n");
5150 TEST_F(ValidationErrorTest, FieldTypeMayBeItsName) {
5152 "name: \"foo.proto\" "
5158 " field { name:\"Bar\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
5162 TEST_F(ValidationErrorTest, EnumFieldTypeIsMessage) {
5163 BuildFileWithErrors(
5164 "name: \"foo.proto\" "
5165 "message_type { name: \"Bar\" } "
5168 " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_ENUM"
5169 " type_name:\"Bar\" }"
5172 "foo.proto: Foo.foo: TYPE: \"Bar\" is not an enum type.\n");
5175 TEST_F(ValidationErrorTest, MessageFieldTypeIsEnum) {
5176 BuildFileWithErrors(
5177 "name: \"foo.proto\" "
5178 "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
5181 " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE"
5182 " type_name:\"Bar\" }"
5185 "foo.proto: Foo.foo: TYPE: \"Bar\" is not a message type.\n");
5188 TEST_F(ValidationErrorTest, BadEnumDefaultValue) {
5189 BuildFileWithErrors(
5190 "name: \"foo.proto\" "
5191 "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
5194 " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\""
5195 " default_value:\"NO_SUCH_VALUE\" }"
5198 "foo.proto: Foo.foo: DEFAULT_VALUE: Enum type \"Bar\" has no value named "
5199 "\"NO_SUCH_VALUE\".\n");
5202 TEST_F(ValidationErrorTest, EnumDefaultValueIsInteger) {
5203 BuildFileWithErrors(
5204 "name: \"foo.proto\" "
5205 "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
5208 " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\""
5209 " default_value:\"0\" }"
5212 "foo.proto: Foo.foo: DEFAULT_VALUE: Default value for an enum field must "
5213 "be an identifier.\n");
5216 TEST_F(ValidationErrorTest, PrimitiveWithTypeName) {
5217 BuildFileWithErrors(
5218 "name: \"foo.proto\" "
5221 " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
5222 " type_name:\"Foo\" }"
5225 "foo.proto: Foo.foo: TYPE: Field with primitive type has type_name.\n");
5228 TEST_F(ValidationErrorTest, NonPrimitiveWithoutTypeName) {
5229 BuildFileWithErrors(
5230 "name: \"foo.proto\" "
5233 " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE }"
5236 "foo.proto: Foo.foo: TYPE: Field with message or enum type missing "
5240 TEST_F(ValidationErrorTest, OneofWithNoFields) {
5241 BuildFileWithErrors(
5242 "name: \"foo.proto\" "
5245 " oneof_decl { name:\"bar\" }"
5248 "foo.proto: Foo.bar: NAME: Oneof must have at least one field.\n");
5251 TEST_F(ValidationErrorTest, OneofLabelMismatch) {
5252 BuildFileWithErrors(
5253 "name: \"foo.proto\" "
5256 " field { name:\"foo\" number:1 label:LABEL_REPEATED type:TYPE_INT32 "
5258 " oneof_decl { name:\"bar\" }"
5261 "foo.proto: Foo.foo: NAME: Fields of oneofs must themselves have label "
5262 "LABEL_OPTIONAL.\n");
5265 TEST_F(ValidationErrorTest, InputTypeNotDefined) {
5266 BuildFileWithErrors(
5267 "name: \"foo.proto\" "
5268 "message_type { name: \"Foo\" } "
5270 " name: \"TestService\""
5271 " method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }"
5274 "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not defined.\n"
5278 TEST_F(ValidationErrorTest, InputTypeNotAMessage) {
5279 BuildFileWithErrors(
5280 "name: \"foo.proto\" "
5281 "message_type { name: \"Foo\" } "
5282 "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
5284 " name: \"TestService\""
5285 " method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }"
5288 "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not a message type.\n"
5292 TEST_F(ValidationErrorTest, OutputTypeNotDefined) {
5293 BuildFileWithErrors(
5294 "name: \"foo.proto\" "
5295 "message_type { name: \"Foo\" } "
5297 " name: \"TestService\""
5298 " method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }"
5301 "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not defined.\n"
5305 TEST_F(ValidationErrorTest, OutputTypeNotAMessage) {
5306 BuildFileWithErrors(
5307 "name: \"foo.proto\" "
5308 "message_type { name: \"Foo\" } "
5309 "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
5311 " name: \"TestService\""
5312 " method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }"
5315 "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not a message type.\n"
5320 TEST_F(ValidationErrorTest, IllegalPackedField) {
5321 BuildFileWithErrors(
5322 "name: \"foo.proto\" "
5325 " field { name:\"packed_string\" number:1 label:LABEL_REPEATED "
5326 " type:TYPE_STRING "
5327 " options { uninterpreted_option {"
5328 " name { name_part: \"packed\" is_extension: false }"
5329 " identifier_value: \"true\" }}}\n"
5330 " field { name:\"packed_message\" number:3 label:LABEL_REPEATED "
5331 " type_name: \"Foo\""
5332 " options { uninterpreted_option {"
5333 " name { name_part: \"packed\" is_extension: false }"
5334 " identifier_value: \"true\" }}}\n"
5335 " field { name:\"optional_int32\" number: 4 label: LABEL_OPTIONAL "
5337 " options { uninterpreted_option {"
5338 " name { name_part: \"packed\" is_extension: false }"
5339 " identifier_value: \"true\" }}}\n"
5342 "foo.proto: Foo.packed_string: TYPE: [packed = true] can only be "
5343 "specified for repeated primitive fields.\n"
5344 "foo.proto: Foo.packed_message: TYPE: [packed = true] can only be "
5345 "specified for repeated primitive fields.\n"
5346 "foo.proto: Foo.optional_int32: TYPE: [packed = true] can only be "
5347 "specified for repeated primitive fields.\n");
5350 TEST_F(ValidationErrorTest, OptionWrongType) {
5351 BuildFileWithErrors(
5352 "name: \"foo.proto\" "
5354 " name: \"TestMessage\" "
5355 " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING "
5356 " options { uninterpreted_option { name { name_part: \"ctype\" "
5357 " is_extension: false }"
5358 " positive_int_value: 1 }"
5363 "foo.proto: TestMessage.foo: OPTION_VALUE: Value must be identifier for "
5364 "enum-valued option \"google.protobuf.FieldOptions.ctype\".\n");
5367 TEST_F(ValidationErrorTest, OptionExtendsAtomicType) {
5368 BuildFileWithErrors(
5369 "name: \"foo.proto\" "
5371 " name: \"TestMessage\" "
5372 " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING "
5373 " options { uninterpreted_option { name { name_part: \"ctype\" "
5374 " is_extension: false }"
5375 " name { name_part: \"foo\" "
5376 " is_extension: true }"
5377 " positive_int_value: 1 }"
5382 "foo.proto: TestMessage.foo: OPTION_NAME: Option \"ctype\" is an "
5383 "atomic type, not a message.\n");
5386 TEST_F(ValidationErrorTest, DupOption) {
5387 BuildFileWithErrors(
5388 "name: \"foo.proto\" "
5390 " name: \"TestMessage\" "
5391 " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_UINT32 "
5392 " options { uninterpreted_option { name { name_part: \"ctype\" "
5393 " is_extension: false }"
5394 " identifier_value: \"CORD\" }"
5395 " uninterpreted_option { name { name_part: \"ctype\" "
5396 " is_extension: false }"
5397 " identifier_value: \"CORD\" }"
5402 "foo.proto: TestMessage.foo: OPTION_NAME: Option \"ctype\" was "
5406 TEST_F(ValidationErrorTest, InvalidOptionName) {
5407 BuildFileWithErrors(
5408 "name: \"foo.proto\" "
5410 " name: \"TestMessage\" "
5411 " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_BOOL "
5412 " options { uninterpreted_option { "
5413 " name { name_part: \"uninterpreted_option\" "
5414 " is_extension: false }"
5415 " positive_int_value: 1 "
5421 "foo.proto: TestMessage.foo: OPTION_NAME: Option must not use "
5422 "reserved name \"uninterpreted_option\".\n");
5425 TEST_F(ValidationErrorTest, RepeatedMessageOption) {
5426 BuildDescriptorMessagesInTestPool();
5428 BuildFileWithErrors(
5429 "name: \"foo.proto\" "
5430 "dependency: \"google/protobuf/descriptor.proto\" "
5431 "message_type: { name: \"Bar\" field: { "
5432 " name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 } "
5434 "extension { name: \"bar\" number: 7672757 label: LABEL_REPEATED "
5435 " type: TYPE_MESSAGE type_name: \"Bar\" "
5436 " extendee: \"google.protobuf.FileOptions\" }"
5437 "options { uninterpreted_option { name { name_part: \"bar\" "
5438 " is_extension: true } "
5439 " name { name_part: \"foo\" "
5440 " is_extension: false } "
5441 " positive_int_value: 1 } }",
5443 "foo.proto: foo.proto: OPTION_NAME: Option field \"(bar)\" is a "
5444 "repeated message. Repeated message options must be initialized "
5445 "using an aggregate value.\n");
5448 TEST_F(ValidationErrorTest, ResolveUndefinedOption) {
5464 BuildDescriptorMessagesInTestPool();
5467 "name: \"foo.proto\" "
5469 "dependency: \"google/protobuf/descriptor.proto\" "
5470 "message_type: { name: \"Bar\" field: { "
5471 " name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 } "
5473 "extension { name: \"bar\" number: 7672757 label: LABEL_OPTIONAL "
5474 " type: TYPE_MESSAGE type_name: \"Bar\" "
5475 " extendee: \"google.protobuf.FileOptions\" }");
5477 BuildFileWithErrors(
5478 "name: \"qux.proto\" "
5479 "package: \"qux.baz\" "
5480 "options { uninterpreted_option { name { name_part: \"baz.bar\" "
5481 " is_extension: true } "
5482 " name { name_part: \"foo\" "
5483 " is_extension: false } "
5484 " positive_int_value: 1 } }",
5486 "qux.proto: qux.proto: OPTION_NAME: Option \"(baz.bar)\" is resolved to "
5487 "\"(qux.baz.bar)\","
5488 " which is not defined. The innermost scope is searched first in name "
5489 "resolution. Consider using a leading '.'(i.e., \"(.baz.bar)\") to start "
5490 "from the outermost scope.\n");
5493 TEST_F(ValidationErrorTest, UnknownOption) {
5494 BuildFileWithErrors(
5495 "name: \"qux.proto\" "
5496 "package: \"qux.baz\" "
5497 "options { uninterpreted_option { name { name_part: \"baaz.bar\" "
5498 " is_extension: true } "
5499 " name { name_part: \"foo\" "
5500 " is_extension: false } "
5501 " positive_int_value: 1 } }",
5503 "qux.proto: qux.proto: OPTION_NAME: Option \"(baaz.bar)\" unknown. "
5505 "that your proto definition file imports the proto which defines the "
5509 TEST_F(ValidationErrorTest, CustomOptionConflictingFieldNumber) {
5510 BuildDescriptorMessagesInTestPool();
5512 BuildFileWithErrors(
5513 "name: \"foo.proto\" "
5514 "dependency: \"google/protobuf/descriptor.proto\" "
5515 "extension { name: \"foo1\" number: 7672757 label: LABEL_OPTIONAL "
5516 " type: TYPE_INT32 extendee: \"google.protobuf.FieldOptions\" }"
5517 "extension { name: \"foo2\" number: 7672757 label: LABEL_OPTIONAL "
5518 " type: TYPE_INT32 extendee: \"google.protobuf.FieldOptions\" }",
5520 "foo.proto: foo2: NUMBER: Extension number 7672757 has already been used "
5521 "in \"google.protobuf.FieldOptions\" by extension \"foo1\".\n");
5524 TEST_F(ValidationErrorTest, Int32OptionValueOutOfPositiveRange) {
5525 BuildDescriptorMessagesInTestPool();
5527 BuildFileWithErrors(
5528 "name: \"foo.proto\" "
5529 "dependency: \"google/protobuf/descriptor.proto\" "
5530 "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5531 " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
5532 "options { uninterpreted_option { name { name_part: \"foo\" "
5533 " is_extension: true } "
5534 " positive_int_value: 0x80000000 } "
5537 "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
5538 "for int32 option \"foo\".\n");
5541 TEST_F(ValidationErrorTest, Int32OptionValueOutOfNegativeRange) {
5542 BuildDescriptorMessagesInTestPool();
5544 BuildFileWithErrors(
5545 "name: \"foo.proto\" "
5546 "dependency: \"google/protobuf/descriptor.proto\" "
5547 "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5548 " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
5549 "options { uninterpreted_option { name { name_part: \"foo\" "
5550 " is_extension: true } "
5551 " negative_int_value: -0x80000001 } "
5554 "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
5555 "for int32 option \"foo\".\n");
5558 TEST_F(ValidationErrorTest, Int32OptionValueIsNotPositiveInt) {
5559 BuildDescriptorMessagesInTestPool();
5561 BuildFileWithErrors(
5562 "name: \"foo.proto\" "
5563 "dependency: \"google/protobuf/descriptor.proto\" "
5564 "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5565 " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
5566 "options { uninterpreted_option { name { name_part: \"foo\" "
5567 " is_extension: true } "
5568 " string_value: \"5\" } }",
5570 "foo.proto: foo.proto: OPTION_VALUE: Value must be integer "
5571 "for int32 option \"foo\".\n");
5574 TEST_F(ValidationErrorTest, Int64OptionValueOutOfRange) {
5575 BuildDescriptorMessagesInTestPool();
5577 BuildFileWithErrors(
5578 "name: \"foo.proto\" "
5579 "dependency: \"google/protobuf/descriptor.proto\" "
5580 "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5581 " type: TYPE_INT64 extendee: \"google.protobuf.FileOptions\" }"
5582 "options { uninterpreted_option { name { name_part: \"foo\" "
5583 " is_extension: true } "
5584 " positive_int_value: 0x8000000000000000 "
5588 "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
5589 "for int64 option \"foo\".\n");
5592 TEST_F(ValidationErrorTest, Int64OptionValueIsNotPositiveInt) {
5593 BuildDescriptorMessagesInTestPool();
5595 BuildFileWithErrors(
5596 "name: \"foo.proto\" "
5597 "dependency: \"google/protobuf/descriptor.proto\" "
5598 "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5599 " type: TYPE_INT64 extendee: \"google.protobuf.FileOptions\" }"
5600 "options { uninterpreted_option { name { name_part: \"foo\" "
5601 " is_extension: true } "
5602 " identifier_value: \"5\" } }",
5604 "foo.proto: foo.proto: OPTION_VALUE: Value must be integer "
5605 "for int64 option \"foo\".\n");
5608 TEST_F(ValidationErrorTest, UInt32OptionValueOutOfRange) {
5609 BuildDescriptorMessagesInTestPool();
5611 BuildFileWithErrors(
5612 "name: \"foo.proto\" "
5613 "dependency: \"google/protobuf/descriptor.proto\" "
5614 "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5615 " type: TYPE_UINT32 extendee: \"google.protobuf.FileOptions\" }"
5616 "options { uninterpreted_option { name { name_part: \"foo\" "
5617 " is_extension: true } "
5618 " positive_int_value: 0x100000000 } }",
5620 "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
5621 "for uint32 option \"foo\".\n");
5624 TEST_F(ValidationErrorTest, UInt32OptionValueIsNotPositiveInt) {
5625 BuildDescriptorMessagesInTestPool();
5627 BuildFileWithErrors(
5628 "name: \"foo.proto\" "
5629 "dependency: \"google/protobuf/descriptor.proto\" "
5630 "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5631 " type: TYPE_UINT32 extendee: \"google.protobuf.FileOptions\" }"
5632 "options { uninterpreted_option { name { name_part: \"foo\" "
5633 " is_extension: true } "
5634 " double_value: -5.6 } }",
5636 "foo.proto: foo.proto: OPTION_VALUE: Value must be non-negative integer "
5637 "for uint32 option \"foo\".\n");
5640 TEST_F(ValidationErrorTest, UInt64OptionValueIsNotPositiveInt) {
5641 BuildDescriptorMessagesInTestPool();
5643 BuildFileWithErrors(
5644 "name: \"foo.proto\" "
5645 "dependency: \"google/protobuf/descriptor.proto\" "
5646 "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5647 " type: TYPE_UINT64 extendee: \"google.protobuf.FileOptions\" }"
5648 "options { uninterpreted_option { name { name_part: \"foo\" "
5649 " is_extension: true } "
5650 " negative_int_value: -5 } }",
5652 "foo.proto: foo.proto: OPTION_VALUE: Value must be non-negative integer "
5653 "for uint64 option \"foo\".\n");
5656 TEST_F(ValidationErrorTest, FloatOptionValueIsNotNumber) {
5657 BuildDescriptorMessagesInTestPool();
5659 BuildFileWithErrors(
5660 "name: \"foo.proto\" "
5661 "dependency: \"google/protobuf/descriptor.proto\" "
5662 "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5663 " type: TYPE_FLOAT extendee: \"google.protobuf.FileOptions\" }"
5664 "options { uninterpreted_option { name { name_part: \"foo\" "
5665 " is_extension: true } "
5666 " string_value: \"bar\" } }",
5668 "foo.proto: foo.proto: OPTION_VALUE: Value must be number "
5669 "for float option \"foo\".\n");
5672 TEST_F(ValidationErrorTest, DoubleOptionValueIsNotNumber) {
5673 BuildDescriptorMessagesInTestPool();
5675 BuildFileWithErrors(
5676 "name: \"foo.proto\" "
5677 "dependency: \"google/protobuf/descriptor.proto\" "
5678 "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5679 " type: TYPE_DOUBLE extendee: \"google.protobuf.FileOptions\" }"
5680 "options { uninterpreted_option { name { name_part: \"foo\" "
5681 " is_extension: true } "
5682 " string_value: \"bar\" } }",
5684 "foo.proto: foo.proto: OPTION_VALUE: Value must be number "
5685 "for double option \"foo\".\n");
5688 TEST_F(ValidationErrorTest, BoolOptionValueIsNotTrueOrFalse) {
5689 BuildDescriptorMessagesInTestPool();
5691 BuildFileWithErrors(
5692 "name: \"foo.proto\" "
5693 "dependency: \"google/protobuf/descriptor.proto\" "
5694 "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5695 " type: TYPE_BOOL extendee: \"google.protobuf.FileOptions\" }"
5696 "options { uninterpreted_option { name { name_part: \"foo\" "
5697 " is_extension: true } "
5698 " identifier_value: \"bar\" } }",
5700 "foo.proto: foo.proto: OPTION_VALUE: Value must be \"true\" or \"false\" "
5701 "for boolean option \"foo\".\n");
5704 TEST_F(ValidationErrorTest, EnumOptionValueIsNotIdentifier) {
5705 BuildDescriptorMessagesInTestPool();
5707 BuildFileWithErrors(
5708 "name: \"foo.proto\" "
5709 "dependency: \"google/protobuf/descriptor.proto\" "
5710 "enum_type { name: \"FooEnum\" value { name: \"BAR\" number: 1 } "
5711 " value { name: \"BAZ\" number: 2 } }"
5712 "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5713 " type: TYPE_ENUM type_name: \"FooEnum\" "
5714 " extendee: \"google.protobuf.FileOptions\" }"
5715 "options { uninterpreted_option { name { name_part: \"foo\" "
5716 " is_extension: true } "
5717 " string_value: \"QUUX\" } }",
5719 "foo.proto: foo.proto: OPTION_VALUE: Value must be identifier for "
5720 "enum-valued option \"foo\".\n");
5723 TEST_F(ValidationErrorTest, EnumOptionValueIsNotEnumValueName) {
5724 BuildDescriptorMessagesInTestPool();
5726 BuildFileWithErrors(
5727 "name: \"foo.proto\" "
5728 "dependency: \"google/protobuf/descriptor.proto\" "
5729 "enum_type { name: \"FooEnum\" value { name: \"BAR\" number: 1 } "
5730 " value { name: \"BAZ\" number: 2 } }"
5731 "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5732 " type: TYPE_ENUM type_name: \"FooEnum\" "
5733 " extendee: \"google.protobuf.FileOptions\" }"
5734 "options { uninterpreted_option { name { name_part: \"foo\" "
5735 " is_extension: true } "
5736 " identifier_value: \"QUUX\" } }",
5738 "foo.proto: foo.proto: OPTION_VALUE: Enum type \"FooEnum\" has no value "
5739 "named \"QUUX\" for option \"foo\".\n");
5742 TEST_F(ValidationErrorTest, EnumOptionValueIsSiblingEnumValueName) {
5743 BuildDescriptorMessagesInTestPool();
5745 BuildFileWithErrors(
5746 "name: \"foo.proto\" "
5747 "dependency: \"google/protobuf/descriptor.proto\" "
5748 "enum_type { name: \"FooEnum1\" value { name: \"BAR\" number: 1 } "
5749 " value { name: \"BAZ\" number: 2 } }"
5750 "enum_type { name: \"FooEnum2\" value { name: \"QUX\" number: 1 } "
5751 " value { name: \"QUUX\" number: 2 } }"
5752 "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5753 " type: TYPE_ENUM type_name: \"FooEnum1\" "
5754 " extendee: \"google.protobuf.FileOptions\" }"
5755 "options { uninterpreted_option { name { name_part: \"foo\" "
5756 " is_extension: true } "
5757 " identifier_value: \"QUUX\" } }",
5759 "foo.proto: foo.proto: OPTION_VALUE: Enum type \"FooEnum1\" has no value "
5760 "named \"QUUX\" for option \"foo\". This appears to be a value from a "
5764 TEST_F(ValidationErrorTest, StringOptionValueIsNotString) {
5765 BuildDescriptorMessagesInTestPool();
5767 BuildFileWithErrors(
5768 "name: \"foo.proto\" "
5769 "dependency: \"google/protobuf/descriptor.proto\" "
5770 "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5771 " type: TYPE_STRING extendee: \"google.protobuf.FileOptions\" }"
5772 "options { uninterpreted_option { name { name_part: \"foo\" "
5773 " is_extension: true } "
5774 " identifier_value: \"QUUX\" } }",
5776 "foo.proto: foo.proto: OPTION_VALUE: Value must be quoted string "
5778 "string option \"foo\".\n");
5781 TEST_F(ValidationErrorTest, JsonNameOptionOnExtensions) {
5782 BuildFileWithErrors(
5783 "name: \"foo.proto\" "
5787 " extension_range { start: 10 end: 20 }"
5792 " label: LABEL_OPTIONAL"
5794 " extendee: \"foo.Foo\""
5795 " json_name: \"myName\""
5797 "foo.proto: foo.value: OPTION_NAME: option json_name is not allowed on "
5798 "extension fields.\n");
5801 TEST_F(ValidationErrorTest, DuplicateExtensionFieldNumber) {
5802 BuildDescriptorMessagesInTestPool();
5805 "name: \"foo.proto\" "
5806 "dependency: \"google/protobuf/descriptor.proto\" "
5807 "extension { name: \"option1\" number: 1000 label: LABEL_OPTIONAL "
5808 " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }");
5810 BuildFileWithWarnings(
5811 "name: \"bar.proto\" "
5812 "dependency: \"google/protobuf/descriptor.proto\" "
5813 "extension { name: \"option2\" number: 1000 label: LABEL_OPTIONAL "
5814 " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }",
5815 "bar.proto: option2: NUMBER: Extension number 1000 has already been used "
5816 "in \"google.protobuf.FileOptions\" by extension \"option1\" defined in "
5825 "name: \"foo.proto\" "
5826 "dependency: \"google/protobuf/descriptor.proto\" "
5827 "message_type { name: \"Foo\" } "
5828 "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
5829 " type: TYPE_MESSAGE type_name: \"Foo\" "
5830 " extendee: \"google.protobuf.FileOptions\" }"
5831 "options { uninterpreted_option { name { name_part: \"foo\" "
5832 " is_extension: true } "
5837 TEST_F(ValidationErrorTest, AggregateValueNotFound) {
5838 BuildDescriptorMessagesInTestPool();
5840 BuildFileWithErrors(
5842 "foo.proto: foo.proto: OPTION_VALUE: Option \"foo\" is a message. "
5843 "To set the entire message, use syntax like "
5844 "\"foo = { <proto text format> }\". To set fields within it, use "
5845 "syntax like \"foo.foo = value\".\n");
5848 TEST_F(ValidationErrorTest, AggregateValueParseError) {
5849 BuildDescriptorMessagesInTestPool();
5851 BuildFileWithErrors(
5853 "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option "
5854 "value for \"foo\": Expected identifier, got: 1\n");
5857 TEST_F(ValidationErrorTest, AggregateValueUnknownFields) {
5858 BuildDescriptorMessagesInTestPool();
5860 BuildFileWithErrors(
5862 "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option "
5863 "value for \"foo\": Message type \"Foo\" has no field named \"x\".\n");
5866 TEST_F(ValidationErrorTest, NotLiteImportsLite) {
5868 "name: \"bar.proto\" "
5869 "options { optimize_for: LITE_RUNTIME } ");
5871 BuildFileWithErrors(
5872 "name: \"foo.proto\" "
5873 "dependency: \"bar.proto\" ",
5875 "foo.proto: bar.proto: IMPORT: Files that do not use optimize_for = "
5876 "LITE_RUNTIME cannot import files which do use this option. This file "
5877 "is not lite, but it imports \"bar.proto\" which is.\n");
5880 TEST_F(ValidationErrorTest, LiteExtendsNotLite) {
5882 "name: \"bar.proto\" "
5885 " extension_range { start: 1 end: 1000 }"
5888 BuildFileWithErrors(
5889 "name: \"foo.proto\" "
5890 "dependency: \"bar.proto\" "
5891 "options { optimize_for: LITE_RUNTIME } "
5892 "extension { name: \"ext\" number: 123 label: LABEL_OPTIONAL "
5893 " type: TYPE_INT32 extendee: \"Bar\" }",
5895 "foo.proto: ext: EXTENDEE: Extensions to non-lite types can only be "
5896 "declared in non-lite files. Note that you cannot extend a non-lite "
5897 "type to contain a lite type, but the reverse is allowed.\n");
5900 TEST_F(ValidationErrorTest, NoLiteServices) {
5901 BuildFileWithErrors(
5902 "name: \"foo.proto\" "
5904 " optimize_for: LITE_RUNTIME"
5905 " cc_generic_services: true"
5906 " java_generic_services: true"
5908 "service { name: \"Foo\" }",
5910 "foo.proto: Foo: NAME: Files with optimize_for = LITE_RUNTIME cannot "
5911 "define services unless you set both options cc_generic_services and "
5912 "java_generic_services to false.\n");
5915 "name: \"bar.proto\" "
5917 " optimize_for: LITE_RUNTIME"
5918 " cc_generic_services: false"
5919 " java_generic_services: false"
5921 "service { name: \"Bar\" }");
5924 TEST_F(ValidationErrorTest, RollbackAfterError) {
5929 BuildFileWithErrors(
5930 "name: \"foo.proto\" "
5932 " name: \"TestMessage\""
5933 " field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }"
5936 " name: \"TestEnum\""
5937 " value { name:\"BAR\" number:1 }"
5940 " name: \"TestService\""
5943 " input_type: \"NoSuchType\""
5944 " output_type: \"TestMessage\""
5948 "foo.proto: TestService.Baz: INPUT_TYPE: \"NoSuchType\" is not defined.\n"
5956 "name: \"foo.proto\" "
5958 " name: \"TestMessage\""
5959 " field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }"
5962 " name: \"TestEnum\""
5963 " value { name:\"BAR\" number:1 }"
5966 " name: \"TestService\""
5967 " method { name:\"Baz\""
5968 " input_type:\"TestMessage\""
5969 " output_type:\"TestMessage\" }"
5973 TEST_F(ValidationErrorTest, ErrorsReportedToLogError) {
5980 "message_type { name: \"Foo\" } "
5981 "message_type { name: \"Foo\" } ",
5984 std::vector<std::string>
errors;
5987 ScopedMemoryLog
log;
5994 EXPECT_EQ(
"Invalid proto descriptor for file \"foo.proto\":",
errors[0]);
5998 TEST_F(ValidationErrorTest, DisallowEnumAlias) {
5999 BuildFileWithErrors(
6000 "name: \"foo.proto\" "
6003 " value { name:\"ENUM_A\" number:0 }"
6004 " value { name:\"ENUM_B\" number:0 }"
6006 "foo.proto: Bar: NUMBER: "
6007 "\"ENUM_B\" uses the same enum value as \"ENUM_A\". "
6008 "If this is intended, set 'option allow_alias = true;' to the enum "
6012 TEST_F(ValidationErrorTest, AllowEnumAlias) {
6014 "name: \"foo.proto\" "
6017 " value { name:\"ENUM_A\" number:0 }"
6018 " value { name:\"ENUM_B\" number:0 }"
6019 " options { allow_alias: true }"
6023 TEST_F(ValidationErrorTest, UnusedImportWarning) {
6024 pool_.AddUnusedImportTrackFile(
"bar.proto");
6026 "name: \"bar.proto\" "
6027 "message_type { name: \"Bar\" }");
6029 pool_.AddUnusedImportTrackFile(
"base.proto");
6031 "name: \"base.proto\" "
6032 "message_type { name: \"Base\" }");
6034 pool_.AddUnusedImportTrackFile(
"baz.proto");
6036 "name: \"baz.proto\" "
6037 "message_type { name: \"Baz\" }");
6039 pool_.AddUnusedImportTrackFile(
"public.proto");
6041 "name: \"public.proto\" "
6042 "dependency: \"bar.proto\""
6043 "public_dependency: 0");
6054 pool_.AddUnusedImportTrackFile(
"forward.proto");
6055 BuildFileWithWarnings(
6056 "name: \"forward.proto\""
6057 "dependency: \"base.proto\""
6058 "dependency: \"bar.proto\""
6059 "dependency: \"baz.proto\""
6060 "dependency: \"public.proto\""
6061 "public_dependency: 2 "
6063 " name: \"Forward\""
6064 " field { name:\"base\" number:1 label:LABEL_OPTIONAL "
6065 "type_name:\"Base\" }"
6067 "forward.proto: bar.proto: IMPORT: Import bar.proto is unused.\n");
6073 "name: 'foo.proto' "
6077 " name: 'foo_map' number: 1 label:LABEL_REPEATED "
6078 " type_name: 'FooMapEntry' "
6081 " name: 'FooMapEntry' "
6082 " options { map_entry: true } "
6084 " name: 'key' number: 1 type:TYPE_INT32 label:LABEL_OPTIONAL "
6087 " name: 'value' number: 2 type:TYPE_INT32 label:LABEL_OPTIONAL "
6093 " extension_range { start: 1 end: 10 }"
6097 static const char* kMapEntryErrorMessage =
6098 "foo.proto: Foo.foo_map: TYPE: map_entry should not be set explicitly. "
6099 "Use map<KeyType, ValueType> instead.\n";
6100 static const char* kMapEntryKeyTypeErrorMessage =
6101 "foo.proto: Foo.foo_map: TYPE: Key in map fields cannot be float/double, "
6102 "bytes or message types.\n";
6106 TEST_F(ValidationErrorTest, MapEntryBase) {
6108 FillValidMapEntry(&file_proto);
6109 BuildFile(file_proto.DebugString());
6112 TEST_F(ValidationErrorTest, MapEntryExtensionRange) {
6114 FillValidMapEntry(&file_proto);
6116 "extension_range { "
6117 " start: 10 end: 20 "
6120 BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6123 TEST_F(ValidationErrorTest, MapEntryExtension) {
6125 FillValidMapEntry(&file_proto);
6128 " name: 'foo_ext' extendee: '.Bar' number: 5"
6131 BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6134 TEST_F(ValidationErrorTest, MapEntryNestedType) {
6136 FillValidMapEntry(&file_proto);
6142 BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6145 TEST_F(ValidationErrorTest, MapEntryEnumTypes) {
6147 FillValidMapEntry(&file_proto);
6151 " value { name: 'BAR_BAR' number:0 } "
6154 BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6157 TEST_F(ValidationErrorTest, MapEntryExtraField) {
6159 FillValidMapEntry(&file_proto);
6162 " name: 'other_field' "
6163 " label: LABEL_OPTIONAL "
6164 " type: TYPE_INT32 "
6168 BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6171 TEST_F(ValidationErrorTest, MapEntryMessageName) {
6173 FillValidMapEntry(&file_proto);
6178 BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6181 TEST_F(ValidationErrorTest, MapEntryNoneRepeatedMapEntry) {
6183 FillValidMapEntry(&file_proto);
6186 BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6189 TEST_F(ValidationErrorTest, MapEntryDifferentContainingType) {
6191 FillValidMapEntry(&file_proto);
6196 BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6199 TEST_F(ValidationErrorTest, MapEntryKeyName) {
6201 FillValidMapEntry(&file_proto);
6205 key->set_name(
"Key");
6206 BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6209 TEST_F(ValidationErrorTest, MapEntryKeyLabel) {
6211 FillValidMapEntry(&file_proto);
6216 BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6219 TEST_F(ValidationErrorTest, MapEntryKeyNumber) {
6221 FillValidMapEntry(&file_proto);
6226 BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6229 TEST_F(ValidationErrorTest, MapEntryValueName) {
6231 FillValidMapEntry(&file_proto);
6235 value->set_name(
"Value");
6236 BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6239 TEST_F(ValidationErrorTest, MapEntryValueLabel) {
6241 FillValidMapEntry(&file_proto);
6246 BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6249 TEST_F(ValidationErrorTest, MapEntryValueNumber) {
6251 FillValidMapEntry(&file_proto);
6255 value->set_number(3);
6256 BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
6259 TEST_F(ValidationErrorTest, MapEntryKeyTypeFloat) {
6261 FillValidMapEntry(&file_proto);
6266 BuildFileWithErrors(file_proto.DebugString(), kMapEntryKeyTypeErrorMessage);
6269 TEST_F(ValidationErrorTest, MapEntryKeyTypeDouble) {
6271 FillValidMapEntry(&file_proto);
6276 BuildFileWithErrors(file_proto.DebugString(), kMapEntryKeyTypeErrorMessage);
6279 TEST_F(ValidationErrorTest, MapEntryKeyTypeBytes) {
6281 FillValidMapEntry(&file_proto);
6286 BuildFileWithErrors(file_proto.DebugString(), kMapEntryKeyTypeErrorMessage);
6289 TEST_F(ValidationErrorTest, MapEntryKeyTypeEnum) {
6291 FillValidMapEntry(&file_proto);
6296 key->set_type_name(
"BarEnum");
6300 enum_value_proto->
set_name(
"BAR_VALUE0");
6302 BuildFileWithErrors(file_proto.DebugString(),
6303 "foo.proto: Foo.foo_map: TYPE: Key in map fields cannot "
6304 "be enum types.\n");
6309 BuildFileWithErrors(file_proto.DebugString(),
6310 "foo.proto: Foo.foo_map: TYPE: Key in map fields cannot "
6311 "be enum types.\n");
6314 TEST_F(ValidationErrorTest, MapEntryKeyTypeMessage) {
6316 FillValidMapEntry(&file_proto);
6321 key->set_type_name(
".Bar");
6322 BuildFileWithErrors(file_proto.DebugString(), kMapEntryKeyTypeErrorMessage);
6325 TEST_F(ValidationErrorTest, MapEntryConflictsWithField) {
6327 FillValidMapEntry(&file_proto);
6330 " name: 'FooMapEntry' "
6331 " type: TYPE_INT32 "
6332 " label: LABEL_OPTIONAL "
6336 BuildFileWithErrors(
6337 file_proto.DebugString(),
6338 "foo.proto: Foo.FooMapEntry: NAME: \"FooMapEntry\" is already defined in "
6340 "foo.proto: Foo.foo_map: TYPE: \"FooMapEntry\" is not defined.\n"
6341 "foo.proto: Foo: NAME: Expanded map entry type FooMapEntry conflicts "
6342 "with an existing field.\n");
6345 TEST_F(ValidationErrorTest, MapEntryConflictsWithMessage) {
6347 FillValidMapEntry(&file_proto);
6350 " name: 'FooMapEntry' "
6353 BuildFileWithErrors(
6354 file_proto.DebugString(),
6355 "foo.proto: Foo.FooMapEntry: NAME: \"FooMapEntry\" is already defined in "
6357 "foo.proto: Foo: NAME: Expanded map entry type FooMapEntry conflicts "
6358 "with an existing nested message type.\n");
6361 TEST_F(ValidationErrorTest, MapEntryConflictsWithEnum) {
6363 FillValidMapEntry(&file_proto);
6366 " name: 'FooMapEntry' "
6367 " value { name: 'ENTRY_FOO' number: 0 }"
6370 BuildFileWithErrors(
6371 file_proto.DebugString(),
6372 "foo.proto: Foo.FooMapEntry: NAME: \"FooMapEntry\" is already defined in "
6374 "foo.proto: Foo: NAME: Expanded map entry type FooMapEntry conflicts "
6375 "with an existing enum type.\n");
6378 TEST_F(ValidationErrorTest, EnumValuesConflictWithDifferentCasing) {
6379 BuildFileWithErrors(
6381 "name: 'foo.proto' "
6384 " value { name: 'BAR' number: 0 }"
6385 " value { name: 'bar' number: 1 }"
6387 "foo.proto: bar: NAME: Enum name bar has the same name as BAR "
6388 "if you ignore case and strip out the enum name prefix (if any). "
6389 "This is error-prone and can lead to undefined behavior. "
6390 "Please avoid doing this. If you are using allow_alias, please assign "
6391 "the same numeric value to both enums.\n");
6396 "name: 'foo.proto' "
6399 " options { allow_alias: true }"
6400 " value { name: 'UNKNOWN' number: 0 }"
6401 " value { name: 'BAR' number: 1 }"
6402 " value { name: 'bar' number: 1 }"
6406 TEST_F(ValidationErrorTest, EnumValuesConflictWhenPrefixesStripped) {
6407 BuildFileWithErrors(
6409 "name: 'foo.proto' "
6412 " value { name: 'FOO_ENUM_BAZ' number: 0 }"
6413 " value { name: 'BAZ' number: 1 }"
6415 "foo.proto: BAZ: NAME: Enum name BAZ has the same name as FOO_ENUM_BAZ "
6416 "if you ignore case and strip out the enum name prefix (if any). "
6417 "This is error-prone and can lead to undefined behavior. "
6418 "Please avoid doing this. If you are using allow_alias, please assign "
6419 "the same numeric value to both enums.\n");
6421 BuildFileWithErrors(
6423 "name: 'foo.proto' "
6426 " value { name: 'FOOENUM_BAZ' number: 0 }"
6427 " value { name: 'BAZ' number: 1 }"
6429 "foo.proto: BAZ: NAME: Enum name BAZ has the same name as FOOENUM_BAZ "
6430 "if you ignore case and strip out the enum name prefix (if any). "
6431 "This is error-prone and can lead to undefined behavior. "
6432 "Please avoid doing this. If you are using allow_alias, please assign "
6433 "the same numeric value to both enums.\n");
6435 BuildFileWithErrors(
6437 "name: 'foo.proto' "
6440 " value { name: 'FOO_ENUM_BAR_BAZ' number: 0 }"
6441 " value { name: 'BAR__BAZ' number: 1 }"
6443 "foo.proto: BAR__BAZ: NAME: Enum name BAR__BAZ has the same name as "
6444 "FOO_ENUM_BAR_BAZ if you ignore case and strip out the enum name prefix "
6445 "(if any). This is error-prone and can lead to undefined behavior. "
6446 "Please avoid doing this. If you are using allow_alias, please assign "
6447 "the same numeric value to both enums.\n");
6449 BuildFileWithErrors(
6451 "name: 'foo.proto' "
6454 " value { name: 'FOO_ENUM__BAR_BAZ' number: 0 }"
6455 " value { name: 'BAR_BAZ' number: 1 }"
6457 "foo.proto: BAR_BAZ: NAME: Enum name BAR_BAZ has the same name as "
6458 "FOO_ENUM__BAR_BAZ if you ignore case and strip out the enum name prefix "
6459 "(if any). This is error-prone and can lead to undefined behavior. "
6460 "Please avoid doing this. If you are using allow_alias, please assign "
6461 "the same numeric value to both enums.\n");
6467 "name: 'foo.proto' "
6470 " value { name: 'BAR_BAZ' number: 0 }"
6471 " value { name: 'BARBAZ' number: 1 }"
6475 TEST_F(ValidationErrorTest, MapEntryConflictsWithOneof) {
6477 FillValidMapEntry(&file_proto);
6480 " name: 'FooMapEntry' "
6483 " name: 'int_field' "
6484 " type: TYPE_INT32 "
6485 " label: LABEL_OPTIONAL "
6490 BuildFileWithErrors(
6491 file_proto.DebugString(),
6492 "foo.proto: Foo.FooMapEntry: NAME: \"FooMapEntry\" is already defined in "
6494 "foo.proto: Foo.foo_map: TYPE: \"FooMapEntry\" is not defined.\n"
6495 "foo.proto: Foo: NAME: Expanded map entry type FooMapEntry conflicts "
6496 "with an existing oneof type.\n");
6499 TEST_F(ValidationErrorTest, MapEntryUsesNoneZeroEnumDefaultValue) {
6500 BuildFileWithErrors(
6501 "name: \"foo.proto\" "
6504 " value { name:\"ENUM_A\" number:1 }"
6505 " value { name:\"ENUM_B\" number:2 }"
6510 " name: 'foo_map' number: 1 label:LABEL_REPEATED "
6511 " type_name: 'FooMapEntry' "
6514 " name: 'FooMapEntry' "
6515 " options { map_entry: true } "
6517 " name: 'key' number: 1 type:TYPE_INT32 label:LABEL_OPTIONAL "
6520 " name: 'value' number: 2 type_name:\"Bar\" label:LABEL_OPTIONAL "
6524 "foo.proto: Foo.foo_map: "
6525 "TYPE: Enum value in map must define 0 as the first value.\n");
6528 TEST_F(ValidationErrorTest, Proto3RequiredFields) {
6529 BuildFileWithErrors(
6530 "name: 'foo.proto' "
6534 " field { name:'foo' number:1 label:LABEL_REQUIRED type:TYPE_INT32 } "
6536 "foo.proto: Foo.foo: TYPE: Required fields are not allowed in "
6540 BuildFileWithErrors(
6541 "name: 'foo.proto' "
6547 " field { name:'bar' number:1 label:LABEL_REQUIRED type:TYPE_INT32 } "
6550 "foo.proto: Foo.Bar.bar: TYPE: Required fields are not allowed in "
6555 "name: 'foo.proto' "
6559 " field { name:'foo' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 } "
6560 " field { name:'bar' number:2 label:LABEL_REPEATED type:TYPE_INT32 } "
6564 TEST_F(ValidationErrorTest, ValidateProto3DefaultValue) {
6565 BuildFileWithErrors(
6566 "name: 'foo.proto' "
6570 " field { name:'foo' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 "
6571 " default_value: '1' }"
6573 "foo.proto: Foo.foo: DEFAULT_VALUE: Explicit default values are not "
6574 "allowed in proto3.\n");
6576 BuildFileWithErrors(
6577 "name: 'foo.proto' "
6583 " field { name:'bar' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 "
6584 " default_value: '1' }"
6587 "foo.proto: Foo.Bar.bar: DEFAULT_VALUE: Explicit default values are not "
6588 "allowed in proto3.\n");
6591 TEST_F(ValidationErrorTest, ValidateProto3ExtensionRange) {
6592 BuildFileWithErrors(
6593 "name: 'foo.proto' "
6597 " field { name:'foo' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 } "
6598 " extension_range { start:10 end:100 } "
6600 "foo.proto: Foo: NUMBER: Extension ranges are not allowed in "
6603 BuildFileWithErrors(
6604 "name: 'foo.proto' "
6610 " field { name:'bar' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 } "
6611 " extension_range { start:10 end:100 } "
6614 "foo.proto: Foo.Bar: NUMBER: Extension ranges are not allowed in "
6618 TEST_F(ValidationErrorTest, ValidateProto3MessageSetWireFormat) {
6619 BuildFileWithErrors(
6620 "name: 'foo.proto' "
6624 " options { message_set_wire_format: true } "
6626 "foo.proto: Foo: NAME: MessageSet is not supported "
6630 TEST_F(ValidationErrorTest, ValidateProto3Enum) {
6631 BuildFileWithErrors(
6632 "name: 'foo.proto' "
6636 " value { name: 'FOO_FOO' number:1 } "
6638 "foo.proto: FooEnum: NUMBER: The first enum value must be "
6639 "zero in proto3.\n");
6641 BuildFileWithErrors(
6642 "name: 'foo.proto' "
6648 " value { name: 'FOO_FOO' number:1 } "
6651 "foo.proto: Foo.FooEnum: NUMBER: The first enum value must be "
6652 "zero in proto3.\n");
6656 "name: 'foo.proto' "
6660 " value { name: 'FOO_FOO' number:0 } "
6664 TEST_F(ValidationErrorTest, ValidateProto3Group) {
6665 BuildFileWithErrors(
6666 "name: 'foo.proto' "
6671 " name: 'FooGroup' "
6673 " field { name:'foo_group' number: 1 label:LABEL_OPTIONAL "
6674 " type: TYPE_GROUP type_name:'FooGroup' } "
6676 "foo.proto: Foo.foo_group: TYPE: Groups are not supported in proto3 "
6681 TEST_F(ValidationErrorTest, ValidateProto3EnumFromProto2) {
6684 "name: 'foo.proto' "
6689 " value { name: 'DEFAULT_OPTION' number:0 } "
6694 BuildFileWithErrors(
6695 "name: 'bar.proto' "
6696 "dependency: 'foo.proto' "
6700 " field { name:'bar' number:1 label:LABEL_OPTIONAL type:TYPE_ENUM "
6701 " type_name: 'foo.FooEnum' }"
6703 "bar.proto: Foo.bar: TYPE: Enum type \"foo.FooEnum\" is not a proto3 "
6704 "enum, but is used in \"Foo\" which is a proto3 message type.\n");
6707 TEST_F(ValidationErrorTest, ValidateProto3Extension) {
6723 AddExtension(&file_proto,
"google.protobuf.FieldOptions",
"option1", 1000,
6730 "name: 'google.protobuf.proto' "
6733 " name: 'Container' extension_range { start: 1 end: 1000 } "
6735 BuildFileWithErrors(
6736 "name: 'bar.proto' "
6738 "dependency: 'google.protobuf.proto' "
6740 " name: 'bar' number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 "
6741 " extendee: 'Container' "
6743 "bar.proto: bar: EXTENDEE: Extensions in proto3 are only allowed for "
6744 "defining options.\n");
6748 TEST_F(ValidationErrorTest, ValidateProto3JsonName) {
6750 BuildFileWithErrors(
6751 "name: 'foo.proto' "
6755 " field { name:'name' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
6756 " field { name:'Name' number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
6758 "foo.proto: Foo: NAME: The JSON camel-case name of field \"Name\" "
6759 "conflicts with field \"name\". This is not allowed in proto3.\n");
6761 BuildFileWithErrors(
6762 "name: 'foo.proto' "
6766 " field { name:'ab' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
6767 " field { name:'_a__b_' number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
6769 "foo.proto: Foo: NAME: The JSON camel-case name of field \"_a__b_\" "
6770 "conflicts with field \"ab\". This is not allowed in proto3.\n");
6776 "name: 'bar.proto' "
6781 pool_.AddUnusedImportTrackFile(
"foo.proto",
true);
6782 BuildFileWithErrors(
6783 "name: 'foo.proto' "
6784 "dependency: 'bar.proto' "
6787 " extension { name:'foo' number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
6788 " extendee: 'Baz' }"
6792 "foo.proto: Foo.foo: EXTENDEE: \"Baz\" is not defined.\n");
6800 const char* file_text) {
6815 "name: 'foo.proto' "
6816 "message_type { name:'Foo' extension_range { start: 1 end: 100 } } "
6817 "enum_type { name:'TestEnum' value { name:'DUMMY' number:0 } } "
6818 "service { name:'TestService' } ");
6820 "name: 'bar.proto' "
6821 "dependency: 'foo.proto' "
6822 "message_type { name:'Bar' } "
6823 "extension { name:'foo_ext' extendee: '.Foo' number:5 "
6824 " label:LABEL_OPTIONAL type:TYPE_INT32 } ");
6828 "name: 'baz.proto' "
6831 " field { name:'foo' number:1 label:LABEL_OPTIONAL type_name:'Foo' } "
6848 output->set_name(
"error.proto");
6849 output->add_dependency(
"error2.proto");
6851 }
else if (
filename ==
"error2.proto") {
6853 output->set_name(
"error2.proto");
6854 output->add_dependency(
"error.proto");
6949 TEST_F(DatabaseBackedPoolTest, FindDependencyBeforeDependent) {
6968 TEST_F(DatabaseBackedPoolTest, FindDependentBeforeDependency) {
6995 EXPECT_TRUE(
pool.FindFileContainingSymbol(
"NoSuchSymbol") ==
nullptr);
6998 TEST_F(DatabaseBackedPoolTest, FindMessageTypeByName) {
7028 for (
int i = 0;
i < 2; ++
i) {
7031 std::vector<const FieldDescriptor*>
extensions;
7038 TEST_F(DatabaseBackedPoolTest, ErrorWithoutErrorCollector) {
7039 ErrorDescriptorDatabase error_database;
7042 std::vector<std::string>
errors;
7045 ScopedMemoryLog
log;
7053 TEST_F(DatabaseBackedPoolTest, ErrorWithErrorCollector) {
7054 ErrorDescriptorDatabase error_database;
7055 MockErrorCollector error_collector;
7060 "error.proto: error2.proto: IMPORT: File recursively imports itself: "
7061 "error.proto -> error2.proto -> error.proto\n"
7062 "error2.proto: error.proto: IMPORT: Import \"error.proto\" was not "
7063 "found or had errors.\n"
7064 "error.proto: error2.proto: IMPORT: Import \"error2.proto\" was not "
7065 "found or had errors.\n",
7066 error_collector.text_);
7069 TEST_F(DatabaseBackedPoolTest, UndeclaredDependencyOnUnbuiltType) {
7072 MockErrorCollector error_collector;
7076 "baz.proto: Baz.foo: TYPE: \"Foo\" seems to be defined in \"foo.proto\", "
7077 "which is not imported by \"baz.proto\". To use it here, please add "
7078 "the necessary import.\n",
7079 error_collector.text_);
7082 TEST_F(DatabaseBackedPoolTest, RollbackAfterError) {
7096 TEST_F(DatabaseBackedPoolTest, UnittestProto) {
7106 pool.FindFileByName(original_file->name());
7111 original_file->CopyTo(&original_file_proto);
7114 file_from_database->CopyTo(&file_from_database_proto);
7116 EXPECT_EQ(original_file_proto.DebugString(),
7117 file_from_database_proto.DebugString());
7120 EXPECT_EQ(original_file->DebugString(), file_from_database->DebugString());
7123 TEST_F(DatabaseBackedPoolTest, DoesntRetryDbUnnecessarily) {
7127 CallCountingDatabase call_counter(&database_);
7140 call_counter.Clear();
7143 EXPECT_TRUE(
foo->FindExtensionByName(
"no_such_extension") ==
nullptr);
7144 EXPECT_TRUE(
foo->FindNestedTypeByName(
"NoSuchMessageType") ==
nullptr);
7145 EXPECT_TRUE(
foo->FindEnumTypeByName(
"NoSuchEnumType") ==
nullptr);
7146 EXPECT_TRUE(
foo->FindEnumValueByName(
"NO_SUCH_VALUE") ==
nullptr);
7147 EXPECT_TRUE(test_enum->FindValueByName(
"NO_SUCH_VALUE") ==
nullptr);
7148 EXPECT_TRUE(test_service->FindMethodByName(
"NoSuchMethod") ==
nullptr);
7150 EXPECT_TRUE(
file->FindMessageTypeByName(
"NoSuchMessageType") ==
nullptr);
7154 EXPECT_TRUE(
file->FindExtensionByName(
"no_such_extension") ==
nullptr);
7156 EXPECT_TRUE(
pool.FindFileContainingSymbol(
"Foo.no.such.field") ==
nullptr);
7157 EXPECT_TRUE(
pool.FindFileContainingSymbol(
"Foo.no_such_field") ==
nullptr);
7158 EXPECT_TRUE(
pool.FindMessageTypeByName(
"Foo.NoSuchMessageType") ==
nullptr);
7160 EXPECT_TRUE(
pool.FindExtensionByName(
"Foo.no_such_extension") ==
nullptr);
7161 EXPECT_TRUE(
pool.FindEnumTypeByName(
"Foo.NoSuchEnumType") ==
nullptr);
7162 EXPECT_TRUE(
pool.FindEnumValueByName(
"Foo.NO_SUCH_VALUE") ==
nullptr);
7163 EXPECT_TRUE(
pool.FindMethodByName(
"TestService.NoSuchMethod") ==
nullptr);
7168 TEST_F(DatabaseBackedPoolTest, DoesntReloadFilesUncesessarily) {
7172 FalsePositiveDatabase false_positive_database(&database_);
7173 MockErrorCollector error_collector;
7233 int begin_size = begin_with.size();
7234 int end_size = end_with.size();
7235 if (
name.substr(0, begin_size) != begin_with ||
7236 name.substr(
name.size() - end_size, end_size) != end_with) {
7265 TEST_F(DatabaseBackedPoolTest, DoesntReloadKnownBadFiles) {
7266 ExponentialErrorDatabase error_database;
7269 GOOGLE_LOG(
INFO) <<
"A timeout in this test probably indicates a real bug.";
7275 TEST_F(DatabaseBackedPoolTest, DoesntFallbackOnWrongType) {
7279 CallCountingDatabase call_counter(&database_);
7290 call_counter.Clear();
7305 class AbortingErrorCollector :
public DescriptorPool::ErrorCollector {
7340 "syntax = \"proto2\";\n"
7341 "option java_package = \"com.foo.bar\";\n"
7342 "option (test_file_opt) = \"foobar\";\n"
7344 " option (test_msg_opt) = \"foobar\";\n"
7345 " optional int32 a = 1 [deprecated = true];\n"
7347 " required double b = 1 [(test_field_opt) = \"foobar\"];\n"
7350 " option (test_oneof_opt) = \"foobar\";\n"
7356 "enum Indecision {\n"
7357 " option (test_enum_opt) = 21;\n"
7358 " option (test_enum_opt) = 42;\n"
7359 " option (test_enum_opt) = 63;\n"
7360 " YES = 1 [(test_enumval_opt).a = 100];\n"
7361 " NO = 2 [(test_enumval_opt) = {a:200}];\n"
7365 " option (test_svc_opt) = {a:100};\n"
7366 " option (test_svc_opt) = {a:200};\n"
7367 " option (test_svc_opt) = {a:300};\n"
7368 " rpc Method(A) returns (A.B);\n"
7371 " rpc OtherMethod(A) returns (A) {\n"
7372 " option deprecated = true;\n"
7373 " option (test_method_opt) = \"foobar\";\n"
7376 "message MessageWithExtensions {\n"
7377 " extensions 1000 to 2000, 2001 to max [(test_ext_opt) = \"foobar\"];\n"
7379 "extend MessageWithExtensions {\n"
7380 " repeated int32 int32_extension = 1001 [packed=true];\n"
7383 " extend MessageWithExtensions {\n"
7384 " optional C message_extension = 1002;\n"
7387 "import \"google/protobuf/descriptor.proto\";\n"
7388 "extend google.protobuf.FileOptions {\n"
7389 " optional string test_file_opt = 10101;\n"
7391 "extend google.protobuf.MessageOptions {\n"
7392 " optional string test_msg_opt = 10101;\n"
7394 "extend google.protobuf.FieldOptions {\n"
7395 " optional string test_field_opt = 10101;\n"
7397 "extend google.protobuf.EnumOptions {\n"
7398 " repeated int32 test_enum_opt = 10101;\n"
7400 "extend google.protobuf.EnumValueOptions {\n"
7401 " optional A test_enumval_opt = 10101;\n"
7403 "extend google.protobuf.ServiceOptions {\n"
7404 " repeated A test_svc_opt = 10101;\n"
7406 "extend google.protobuf.MethodOptions {\n"
7407 " optional string test_method_opt = 10101;\n"
7409 "extend google.protobuf.OneofOptions {\n"
7410 " optional string test_oneof_opt = 10101;\n"
7412 "extend google.protobuf.ExtensionRangeOptions {\n"
7413 " optional string test_ext_opt = 10101;\n"
7432 1 +
loc.start_column, 1 +
loc.end_line,
7433 1 +
loc.end_column);
7488 TEST_F(SourceLocationTest, ExtensionSourceLocation) {
7508 TEST_F(SourceLocationTest, InterpretedOptionSourceLocation) {
7528 std::vector<int> vpath(
path,
path + 2);
7532 std::vector<int> vunint(unint, unint + 3);
7537 kCustomOptionFieldNumber};
7540 std::vector<int> vpath(
path,
path + 2);
7544 std::vector<int> vunint(unint, unint + 3);
7552 kCustomOptionFieldNumber};
7556 std::vector<int> vpath(
path,
path + 4);
7560 std::vector<int> vunint(unint, unint + 5);
7579 std::vector<int> vpath(
path,
path + 6);
7583 std::vector<int> vunint(unint, unint + 7);
7603 std::vector<int> vpath(
path,
path + 8);
7607 std::vector<int> vunint(unint, unint + 9);
7624 std::vector<int> vpath(
path,
path + 6);
7628 std::vector<int> vunint(unint, unint + 7);
7636 kCustomOptionFieldNumber, 0};
7640 std::vector<int> vpath(
path,
path + 5);
7644 std::vector<int> vunint(unint, unint + 5);
7650 kCustomOptionFieldNumber, 1};
7654 std::vector<int> vpath(
path,
path + 5);
7658 std::vector<int> vunint(unint, unint + 5);
7664 kCustomOptionFieldNumber, 2};
7668 std::vector<int> vpath(
path,
path + 5);
7672 std::vector<int> vunint(unint, unint + 5);
7684 kCustomOptionFieldNumber,
7693 std::vector<int> vpath(
path,
path + 7);
7697 std::vector<int> vunint(unint, unint + 7);
7706 kCustomOptionFieldNumber};
7714 std::vector<int> vpath(
path,
path + 6);
7718 std::vector<int> vunint(unint, unint + 7);
7726 kCustomOptionFieldNumber, 0};
7730 std::vector<int> vpath(
path,
path + 5);
7734 std::vector<int> vunint(unint, unint + 5);
7740 kCustomOptionFieldNumber, 1};
7744 std::vector<int> vpath(
path,
path + 5);
7748 std::vector<int> vunint(unint, unint + 5);
7754 kCustomOptionFieldNumber, 2};
7758 std::vector<int> vpath(
path,
path + 5);
7762 std::vector<int> vunint(unint, unint + 5);
7781 std::vector<int> vpath(
path,
path + 6);
7785 std::vector<int> vunint(unint, unint + 7);
7800 std::vector<int> vpath(
path,
path + 6);
7804 std::vector<int> vunint(unint, unint + 7);
7813 std::vector<int> vpath(
path,
path + 5);
7823 kCustomOptionFieldNumber};
7831 std::vector<int> vpath(
path,
path + 6);
7835 std::vector<int> vunint(unint, unint + 7);
7844 kCustomOptionFieldNumber};
7852 std::vector<int> vpath(
path,
path + 6);
7856 std::vector<int> vunint(unint, unint + 7);
7868 std::vector<int> vpath(
path,
path + 4);
7872 std::vector<int> vunint(unint, unint + 5);
7878 TEST_F(SourceLocationTest, GetSourceLocation_MissingSourceCodeInfo) {
7885 file_desc->CopyTo(&proto);
7891 const Descriptor* bad1_a_desc = bad1_file_desc->FindMessageTypeByName(
"A");
7896 TEST_F(SourceLocationTest, GetSourceLocation_BogusSourceCodeInfo) {
7903 file_desc->CopyTo(&proto);
7917 const Descriptor* bad2_a_desc = bad2_file_desc->FindMessageTypeByName(
"A");
7924 "syntax = \"proto2\";\n"
7945 TEST_F(CopySourceCodeInfoToTest, CopyTo_DoesNotCopySourceCodeInfo) {
7951 file_desc->
CopyTo(&file_desc_proto);
7955 TEST_F(CopySourceCodeInfoToTest, CopySourceCodeInfoTo) {
7961 file_desc->CopySourceCodeInfoTo(&file_desc_proto);
7996 const char* message_name) {
7999 "package: \"protobuf_unittest\" "
8004 " field { name:'a' number:1 "
8005 " label:LABEL_OPTIONAL "
8006 " type_name:'int32' } "
8011 const char* enum_value_name) {
8014 "package: 'protobuf_unittest' "
8031 ParseProtoAndAddToDb(
8032 "name: 'foo.proto' "
8033 "package: 'protobuf_unittest' "
8034 "dependency: 'bar.proto' "
8037 " field { name:'bar' number:1 label:LABEL_OPTIONAL "
8038 "type_name:'.protobuf_unittest.Bar' } "
8040 AddSimpleMessageProtoFileToDb(
"bar",
"Bar");
8071 ParseProtoAndAddToDb(
8072 "name: 'foo.proto' "
8073 "package: 'protobuf_unittest' "
8074 "dependency: 'enum1.proto' "
8075 "dependency: 'enum2.proto' "
8078 " field { name:'enum1' number:1 label:LABEL_OPTIONAL "
8079 "type_name:'.protobuf_unittest.Enum1' } "
8080 " field { name:'enum2' number:1 label:LABEL_OPTIONAL "
8081 "type_name:'.protobuf_unittest.Enum2' } "
8083 AddSimpleEnumProtoFileToDb(
"enum1",
"Enum1",
"ENUM1");
8084 AddSimpleEnumProtoFileToDb(
"enum2",
"Enum2",
"ENUM2");
8108 ParseProtoAndAddToDb(
8109 "name: 'foo.proto' "
8110 "package: 'protobuf_unittest' "
8111 "dependency: 'message1.proto' "
8112 "dependency: 'message2.proto' "
8113 "dependency: 'enum1.proto' "
8114 "dependency: 'enum2.proto' "
8117 " field { name:'message1' number:1 label:LABEL_OPTIONAL "
8118 "type_name:'.protobuf_unittest.Message1' } "
8119 " field { name:'message2' number:1 label:LABEL_OPTIONAL "
8120 "type_name:'.protobuf_unittest.Message2' } "
8121 " field { name:'enum1' number:1 label:LABEL_OPTIONAL "
8122 "type_name:'.protobuf_unittest.Enum1' } "
8123 " field { name:'enum2' number:1 label:LABEL_OPTIONAL "
8124 "type_name:'.protobuf_unittest.Enum2' } "
8126 AddSimpleMessageProtoFileToDb(
"message1",
"Message1");
8127 AddSimpleMessageProtoFileToDb(
"message2",
"Message2");
8128 AddSimpleEnumProtoFileToDb(
"enum1",
"Enum1",
"ENUM1");
8129 AddSimpleEnumProtoFileToDb(
"enum2",
"Enum2",
"ENUM2");
8146 field =
desc->FindFieldByName(
"message2");
8168 TEST_F(LazilyBuildDependenciesTest, Extension) {
8169 ParseProtoAndAddToDb(
8170 "name: 'foo.proto' "
8171 "package: 'protobuf_unittest' "
8172 "dependency: 'bar.proto' "
8173 "dependency: 'baz.proto' "
8174 "extension { extendee: '.protobuf_unittest.Bar' name:'bar' number:11"
8175 " label:LABEL_OPTIONAL type_name:'.protobuf_unittest.Baz' }");
8176 ParseProtoAndAddToDb(
8177 "name: 'bar.proto' "
8178 "package: 'protobuf_unittest' "
8181 " extension_range { start: 10 end: 20 }"
8183 AddSimpleMessageProtoFileToDb(
"baz",
"Baz");
8200 TEST_F(LazilyBuildDependenciesTest, Service) {
8201 ParseProtoAndAddToDb(
8202 "name: 'foo.proto' "
8203 "package: 'protobuf_unittest' "
8204 "dependency: 'message1.proto' "
8205 "dependency: 'message2.proto' "
8206 "dependency: 'message3.proto' "
8207 "dependency: 'message4.proto' "
8209 " name: 'LazyService'"
8210 " method { name: 'A' input_type: '.protobuf_unittest.Message1' "
8211 " output_type: '.protobuf_unittest.Message2' }"
8213 AddSimpleMessageProtoFileToDb(
"message1",
"Message1");
8214 AddSimpleMessageProtoFileToDb(
"message2",
"Message2");
8215 AddSimpleMessageProtoFileToDb(
"message3",
"Message3");
8216 AddSimpleMessageProtoFileToDb(
"message4",
"Message4");
8237 TEST_F(LazilyBuildDependenciesTest, GeneratedFile) {
8245 "google/protobuf/unittest_lazy_dependencies.proto"));
8247 "google/protobuf/unittest_lazy_dependencies_custom_option.proto"));
8249 "google/protobuf/unittest_lazy_dependencies_enum.proto"));
8259 "google/protobuf/unittest_lazy_dependencies.proto"));
8261 "google/protobuf/unittest_lazy_dependencies_custom_option.proto"));
8263 "google/protobuf/unittest_lazy_dependencies_enum.proto"));
8271 protobuf_unittest::lazy_imports::LazyEnum custom_option_value =
8272 options.GetExtension(protobuf_unittest::lazy_imports::lazy_enum_option);
8275 "google/protobuf/unittest_lazy_dependencies_custom_option.proto"));
8277 "google/protobuf/unittest_lazy_dependencies_enum.proto"));
8278 EXPECT_EQ(custom_option_value, protobuf_unittest::lazy_imports::LAZY_ENUM_1);
8283 custom_option_value =
8284 options2.
GetExtension(protobuf_unittest::lazy_imports::lazy_enum_option);
8287 "google/protobuf/unittest_lazy_dependencies_custom_option.proto"));
8289 "google/protobuf/unittest_lazy_dependencies_enum.proto"));
8290 EXPECT_EQ(custom_option_value, protobuf_unittest::lazy_imports::LAZY_ENUM_0);
8293 TEST_F(LazilyBuildDependenciesTest, Dependency) {
8294 ParseProtoAndAddToDb(
8295 "name: 'foo.proto' "
8296 "package: 'protobuf_unittest' "
8297 "dependency: 'bar.proto' "
8300 " field { name:'bar' number:1 label:LABEL_OPTIONAL "
8301 "type_name:'.protobuf_unittest.Bar' } "
8303 ParseProtoAndAddToDb(
8304 "name: 'bar.proto' "
8305 "package: 'protobuf_unittest' "
8306 "dependency: 'baz.proto' "
8309 " field { name:'baz' number:1 label:LABEL_OPTIONAL "
8310 "type_name:'.protobuf_unittest.Baz' } "
8312 AddSimpleMessageProtoFileToDb(
"baz",
"Baz");
8336 #include <google/protobuf/port_undef.inc>