OLD | NEW |
1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
3 // https://developers.google.com/protocol-buffers/ | 3 // https://developers.google.com/protocol-buffers/ |
4 // | 4 // |
5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
7 // met: | 7 // met: |
8 // | 8 // |
9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
(...skipping 23 matching lines...) Expand all Loading... |
34 // | 34 // |
35 // This file makes extensive use of RFC 3092. :) | 35 // This file makes extensive use of RFC 3092. :) |
36 | 36 |
37 #include <memory> | 37 #include <memory> |
38 #ifndef _SHARED_PTR_H | 38 #ifndef _SHARED_PTR_H |
39 #include <google/protobuf/stubs/shared_ptr.h> | 39 #include <google/protobuf/stubs/shared_ptr.h> |
40 #endif | 40 #endif |
41 #include <vector> | 41 #include <vector> |
42 | 42 |
43 #include <google/protobuf/compiler/importer.h> | 43 #include <google/protobuf/compiler/importer.h> |
| 44 #include <google/protobuf/compiler/parser.h> |
44 #include <google/protobuf/unittest.pb.h> | 45 #include <google/protobuf/unittest.pb.h> |
45 #include <google/protobuf/unittest_custom_options.pb.h> | 46 #include <google/protobuf/unittest_custom_options.pb.h> |
| 47 #include <google/protobuf/unittest_proto3_arena.pb.h> |
| 48 #include <google/protobuf/io/tokenizer.h> |
46 #include <google/protobuf/io/zero_copy_stream_impl.h> | 49 #include <google/protobuf/io/zero_copy_stream_impl.h> |
47 #include <google/protobuf/descriptor.pb.h> | 50 #include <google/protobuf/descriptor.pb.h> |
48 #include <google/protobuf/descriptor.h> | 51 #include <google/protobuf/descriptor.h> |
49 #include <google/protobuf/descriptor_database.h> | 52 #include <google/protobuf/descriptor_database.h> |
50 #include <google/protobuf/dynamic_message.h> | 53 #include <google/protobuf/dynamic_message.h> |
51 #include <google/protobuf/text_format.h> | 54 #include <google/protobuf/text_format.h> |
52 #include <google/protobuf/stubs/strutil.h> | 55 #include <google/protobuf/stubs/strutil.h> |
53 #include <google/protobuf/stubs/substitute.h> | 56 #include <google/protobuf/stubs/substitute.h> |
54 | 57 |
55 #include <google/protobuf/stubs/common.h> | 58 #include <google/protobuf/stubs/common.h> |
56 #include <google/protobuf/stubs/logging.h> | 59 #include <google/protobuf/stubs/logging.h> |
57 #include <google/protobuf/stubs/logging.h> | 60 #include <google/protobuf/stubs/logging.h> |
58 #include <google/protobuf/stubs/scoped_ptr.h> | 61 #include <google/protobuf/stubs/stringprintf.h> |
59 #include <google/protobuf/testing/googletest.h> | 62 #include <google/protobuf/testing/googletest.h> |
60 #include <gtest/gtest.h> | 63 #include <gtest/gtest.h> |
61 | 64 |
62 namespace google { | 65 namespace google { |
63 namespace protobuf { | 66 namespace protobuf { |
64 | 67 |
65 // Can't use an anonymous namespace here due to brokenness of Tru64 compiler. | 68 // Can't use an anonymous namespace here due to brokenness of Tru64 compiler. |
66 namespace descriptor_unittest { | 69 namespace descriptor_unittest { |
67 | 70 |
68 // Some helpers to make assembling descriptors faster. | 71 // Some helpers to make assembling descriptors faster. |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
482 DescriptorPool pool; | 485 DescriptorPool pool; |
483 const FileDescriptor* file = pool.BuildFile(proto); | 486 const FileDescriptor* file = pool.BuildFile(proto); |
484 EXPECT_TRUE(file != NULL); | 487 EXPECT_TRUE(file != NULL); |
485 EXPECT_EQ(FileDescriptor::SYNTAX_PROTO3, file->syntax()); | 488 EXPECT_EQ(FileDescriptor::SYNTAX_PROTO3, file->syntax()); |
486 FileDescriptorProto other; | 489 FileDescriptorProto other; |
487 file->CopyTo(&other); | 490 file->CopyTo(&other); |
488 EXPECT_EQ("proto3", other.syntax()); | 491 EXPECT_EQ("proto3", other.syntax()); |
489 } | 492 } |
490 } | 493 } |
491 | 494 |
| 495 void ExtractDebugString( |
| 496 const FileDescriptor* file, std::set<string>* visited, |
| 497 std::vector<std::pair<string, string> >* debug_strings) { |
| 498 if (!visited->insert(file->name()).second) { |
| 499 return; |
| 500 } |
| 501 for (int i = 0; i < file->dependency_count(); ++i) { |
| 502 ExtractDebugString(file->dependency(i), visited, debug_strings); |
| 503 } |
| 504 debug_strings->push_back(make_pair(file->name(), file->DebugString())); |
| 505 } |
| 506 |
| 507 class SimpleErrorCollector : public google::protobuf::io::ErrorCollector { |
| 508 public: |
| 509 // implements ErrorCollector --------------------------------------- |
| 510 void AddError(int line, int column, const string& message) { |
| 511 last_error_ = StringPrintf("%d:%d:", line, column) + message; |
| 512 } |
| 513 |
| 514 const string& last_error() { return last_error_; } |
| 515 |
| 516 private: |
| 517 string last_error_; |
| 518 }; |
| 519 // Test that the result of FileDescriptor::DebugString() can be used to create |
| 520 // the original descriptors. |
| 521 TEST_F(FileDescriptorTest, DebugStringRoundTrip) { |
| 522 std::set<string> visited; |
| 523 std::vector<std::pair<string, string> > debug_strings; |
| 524 ExtractDebugString(protobuf_unittest::TestAllTypes::descriptor()->file(), |
| 525 &visited, &debug_strings); |
| 526 ExtractDebugString( |
| 527 protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file(), |
| 528 &visited, &debug_strings); |
| 529 ExtractDebugString(proto3_arena_unittest::TestAllTypes::descriptor()->file(), |
| 530 &visited, &debug_strings); |
| 531 ASSERT_GE(debug_strings.size(), 3); |
| 532 |
| 533 DescriptorPool pool; |
| 534 for (int i = 0; i < debug_strings.size(); ++i) { |
| 535 const string& name = debug_strings[i].first; |
| 536 const string& content = debug_strings[i].second; |
| 537 google::protobuf::io::ArrayInputStream input_stream(content.data(), content.
size()); |
| 538 SimpleErrorCollector error_collector; |
| 539 google::protobuf::io::Tokenizer tokenizer(&input_stream, &error_collector); |
| 540 google::protobuf::compiler::Parser parser; |
| 541 parser.RecordErrorsTo(&error_collector); |
| 542 FileDescriptorProto proto; |
| 543 ASSERT_TRUE(parser.Parse(&tokenizer, &proto)) |
| 544 << error_collector.last_error() << "\n" |
| 545 << content; |
| 546 ASSERT_EQ("", error_collector.last_error()); |
| 547 proto.set_name(name); |
| 548 const FileDescriptor* descriptor = pool.BuildFile(proto); |
| 549 ASSERT_TRUE(descriptor != NULL) << proto.DebugString(); |
| 550 EXPECT_EQ(content, descriptor->DebugString()); |
| 551 } |
| 552 } |
| 553 |
492 // =================================================================== | 554 // =================================================================== |
493 | 555 |
494 // Test simple flat messages and fields. | 556 // Test simple flat messages and fields. |
495 class DescriptorTest : public testing::Test { | 557 class DescriptorTest : public testing::Test { |
496 protected: | 558 protected: |
497 virtual void SetUp() { | 559 virtual void SetUp() { |
498 // Build descriptors for the following definitions: | 560 // Build descriptors for the following definitions: |
499 // | 561 // |
500 // // in "foo.proto" | 562 // // in "foo.proto" |
501 // message TestForeign {} | 563 // message TestForeign {} |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
767 EXPECT_EQ("TestMessage.qux", qux_->full_name()); | 829 EXPECT_EQ("TestMessage.qux", qux_->full_name()); |
768 | 830 |
769 EXPECT_EQ("corge.grault.TestMessage2.foo", foo2_->full_name()); | 831 EXPECT_EQ("corge.grault.TestMessage2.foo", foo2_->full_name()); |
770 EXPECT_EQ("corge.grault.TestMessage2.bar", bar2_->full_name()); | 832 EXPECT_EQ("corge.grault.TestMessage2.bar", bar2_->full_name()); |
771 EXPECT_EQ("corge.grault.TestMessage2.quux", quux2_->full_name()); | 833 EXPECT_EQ("corge.grault.TestMessage2.quux", quux2_->full_name()); |
772 } | 834 } |
773 | 835 |
774 TEST_F(DescriptorTest, FieldJsonName) { | 836 TEST_F(DescriptorTest, FieldJsonName) { |
775 EXPECT_EQ("fieldName1", message4_->field(0)->json_name()); | 837 EXPECT_EQ("fieldName1", message4_->field(0)->json_name()); |
776 EXPECT_EQ("fieldName2", message4_->field(1)->json_name()); | 838 EXPECT_EQ("fieldName2", message4_->field(1)->json_name()); |
777 EXPECT_EQ("fieldName3", message4_->field(2)->json_name()); | 839 EXPECT_EQ("FieldName3", message4_->field(2)->json_name()); |
778 EXPECT_EQ("fieldName4", message4_->field(3)->json_name()); | 840 EXPECT_EQ("FieldName4", message4_->field(3)->json_name()); |
779 EXPECT_EQ("fIELDNAME5", message4_->field(4)->json_name()); | 841 EXPECT_EQ("FIELDNAME5", message4_->field(4)->json_name()); |
780 EXPECT_EQ("@type", message4_->field(5)->json_name()); | 842 EXPECT_EQ("@type", message4_->field(5)->json_name()); |
781 | 843 |
782 DescriptorProto proto; | 844 DescriptorProto proto; |
783 message4_->CopyTo(&proto); | 845 message4_->CopyTo(&proto); |
784 ASSERT_EQ(6, proto.field_size()); | 846 ASSERT_EQ(6, proto.field_size()); |
785 EXPECT_FALSE(proto.field(0).has_json_name()); | 847 EXPECT_FALSE(proto.field(0).has_json_name()); |
786 EXPECT_FALSE(proto.field(1).has_json_name()); | 848 EXPECT_FALSE(proto.field(1).has_json_name()); |
787 EXPECT_FALSE(proto.field(2).has_json_name()); | 849 EXPECT_FALSE(proto.field(2).has_json_name()); |
788 EXPECT_FALSE(proto.field(3).has_json_name()); | 850 EXPECT_FALSE(proto.field(3).has_json_name()); |
789 EXPECT_FALSE(proto.field(4).has_json_name()); | 851 EXPECT_FALSE(proto.field(4).has_json_name()); |
790 EXPECT_EQ("@type", proto.field(5).json_name()); | 852 EXPECT_EQ("@type", proto.field(5).json_name()); |
791 | 853 |
792 proto.Clear(); | 854 proto.Clear(); |
793 CopyWithJsonName(message4_, &proto); | 855 CopyWithJsonName(message4_, &proto); |
794 ASSERT_EQ(6, proto.field_size()); | 856 ASSERT_EQ(6, proto.field_size()); |
795 EXPECT_EQ("fieldName1", proto.field(0).json_name()); | 857 EXPECT_EQ("fieldName1", proto.field(0).json_name()); |
796 EXPECT_EQ("fieldName2", proto.field(1).json_name()); | 858 EXPECT_EQ("fieldName2", proto.field(1).json_name()); |
797 EXPECT_EQ("fieldName3", proto.field(2).json_name()); | 859 EXPECT_EQ("FieldName3", proto.field(2).json_name()); |
798 EXPECT_EQ("fieldName4", proto.field(3).json_name()); | 860 EXPECT_EQ("FieldName4", proto.field(3).json_name()); |
799 EXPECT_EQ("fIELDNAME5", proto.field(4).json_name()); | 861 EXPECT_EQ("FIELDNAME5", proto.field(4).json_name()); |
800 EXPECT_EQ("@type", proto.field(5).json_name()); | 862 EXPECT_EQ("@type", proto.field(5).json_name()); |
| 863 |
| 864 // Test generated descriptor. |
| 865 const Descriptor* generated = protobuf_unittest::TestJsonName::descriptor(); |
| 866 ASSERT_EQ(6, generated->field_count()); |
| 867 EXPECT_EQ("fieldName1", generated->field(0)->json_name()); |
| 868 EXPECT_EQ("fieldName2", generated->field(1)->json_name()); |
| 869 EXPECT_EQ("FieldName3", generated->field(2)->json_name()); |
| 870 EXPECT_EQ("FieldName4", generated->field(3)->json_name()); |
| 871 EXPECT_EQ("FIELDNAME5", generated->field(4)->json_name()); |
| 872 EXPECT_EQ("@type", generated->field(5)->json_name()); |
801 } | 873 } |
802 | 874 |
803 TEST_F(DescriptorTest, FieldFile) { | 875 TEST_F(DescriptorTest, FieldFile) { |
804 EXPECT_EQ(foo_file_, foo_->file()); | 876 EXPECT_EQ(foo_file_, foo_->file()); |
805 EXPECT_EQ(foo_file_, bar_->file()); | 877 EXPECT_EQ(foo_file_, bar_->file()); |
806 EXPECT_EQ(foo_file_, baz_->file()); | 878 EXPECT_EQ(foo_file_, baz_->file()); |
807 EXPECT_EQ(foo_file_, qux_->file()); | 879 EXPECT_EQ(foo_file_, qux_->file()); |
808 | 880 |
809 EXPECT_EQ(bar_file_, foo2_->file()); | 881 EXPECT_EQ(bar_file_, foo2_->file()); |
810 EXPECT_EQ(bar_file_, bar2_->file()); | 882 EXPECT_EQ(bar_file_, bar2_->file()); |
(...skipping 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1845 | 1917 |
1846 EXPECT_EQ(bar_->extension(0), bar_->FindExtensionByName("foo_message")); | 1918 EXPECT_EQ(bar_->extension(0), bar_->FindExtensionByName("foo_message")); |
1847 EXPECT_EQ(bar_->extension(1), bar_->FindExtensionByName("foo_group" )); | 1919 EXPECT_EQ(bar_->extension(1), bar_->FindExtensionByName("foo_group" )); |
1848 | 1920 |
1849 EXPECT_TRUE(bar_->FindExtensionByName("no_such_extension") == NULL); | 1921 EXPECT_TRUE(bar_->FindExtensionByName("no_such_extension") == NULL); |
1850 EXPECT_TRUE(foo_->FindExtensionByName("foo_int32") == NULL); | 1922 EXPECT_TRUE(foo_->FindExtensionByName("foo_int32") == NULL); |
1851 EXPECT_TRUE(foo_->FindExtensionByName("foo_message") == NULL); | 1923 EXPECT_TRUE(foo_->FindExtensionByName("foo_message") == NULL); |
1852 } | 1924 } |
1853 | 1925 |
1854 TEST_F(ExtensionDescriptorTest, FindAllExtensions) { | 1926 TEST_F(ExtensionDescriptorTest, FindAllExtensions) { |
1855 vector<const FieldDescriptor*> extensions; | 1927 std::vector<const FieldDescriptor*> extensions; |
1856 pool_.FindAllExtensions(foo_, &extensions); | 1928 pool_.FindAllExtensions(foo_, &extensions); |
1857 ASSERT_EQ(4, extensions.size()); | 1929 ASSERT_EQ(4, extensions.size()); |
1858 EXPECT_EQ(10, extensions[0]->number()); | 1930 EXPECT_EQ(10, extensions[0]->number()); |
1859 EXPECT_EQ(19, extensions[1]->number()); | 1931 EXPECT_EQ(19, extensions[1]->number()); |
1860 EXPECT_EQ(30, extensions[2]->number()); | 1932 EXPECT_EQ(30, extensions[2]->number()); |
1861 EXPECT_EQ(39, extensions[3]->number()); | 1933 EXPECT_EQ(39, extensions[3]->number()); |
1862 } | 1934 } |
1863 | 1935 |
1864 TEST_F(ExtensionDescriptorTest, DuplicateFieldNumber) { | 1936 TEST_F(ExtensionDescriptorTest, DuplicateFieldNumber) { |
1865 DescriptorPool pool; | 1937 DescriptorPool pool; |
(...skipping 743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2609 " identifier_value: \"SPEED\" " | 2681 " identifier_value: \"SPEED\" " |
2610 " } " | 2682 " } " |
2611 "}", | 2683 "}", |
2612 &option_proto)); | 2684 &option_proto)); |
2613 | 2685 |
2614 const FileDescriptor* file = BuildFile(option_proto); | 2686 const FileDescriptor* file = BuildFile(option_proto); |
2615 ASSERT_TRUE(file != NULL); | 2687 ASSERT_TRUE(file != NULL); |
2616 | 2688 |
2617 // Verify that no extension options were set, but they were left as | 2689 // Verify that no extension options were set, but they were left as |
2618 // uninterpreted_options. | 2690 // uninterpreted_options. |
2619 vector<const FieldDescriptor*> fields; | 2691 std::vector<const FieldDescriptor*> fields; |
2620 file->options().GetReflection()->ListFields(file->options(), &fields); | 2692 file->options().GetReflection()->ListFields(file->options(), &fields); |
2621 ASSERT_EQ(2, fields.size()); | 2693 ASSERT_EQ(2, fields.size()); |
2622 EXPECT_TRUE(file->options().has_optimize_for()); | 2694 EXPECT_TRUE(file->options().has_optimize_for()); |
2623 EXPECT_EQ(2, file->options().uninterpreted_option_size()); | 2695 EXPECT_EQ(2, file->options().uninterpreted_option_size()); |
2624 } | 2696 } |
2625 | 2697 |
2626 TEST_P(AllowUnknownDependenciesTest, | 2698 TEST_P(AllowUnknownDependenciesTest, |
2627 UndeclaredDependencyTriggersBuildOfDependency) { | 2699 UndeclaredDependencyTriggersBuildOfDependency) { |
2628 // Crazy case: suppose foo.proto refers to a symbol without declaring the | 2700 // Crazy case: suppose foo.proto refers to a symbol without declaring the |
2629 // dependency that finds it. In the event that the pool is backed by a | 2701 // dependency that finds it. In the event that the pool is backed by a |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2698 AllowUnknownDependenciesTest, | 2770 AllowUnknownDependenciesTest, |
2699 testing::Values(NO_DATABASE, FALLBACK_DATABASE)); | 2771 testing::Values(NO_DATABASE, FALLBACK_DATABASE)); |
2700 | 2772 |
2701 // =================================================================== | 2773 // =================================================================== |
2702 | 2774 |
2703 TEST(CustomOptions, OptionLocations) { | 2775 TEST(CustomOptions, OptionLocations) { |
2704 const Descriptor* message = | 2776 const Descriptor* message = |
2705 protobuf_unittest::TestMessageWithCustomOptions::descriptor(); | 2777 protobuf_unittest::TestMessageWithCustomOptions::descriptor(); |
2706 const FileDescriptor* file = message->file(); | 2778 const FileDescriptor* file = message->file(); |
2707 const FieldDescriptor* field = message->FindFieldByName("field1"); | 2779 const FieldDescriptor* field = message->FindFieldByName("field1"); |
| 2780 const OneofDescriptor* oneof = message->FindOneofByName("AnOneof"); |
2708 const EnumDescriptor* enm = message->FindEnumTypeByName("AnEnum"); | 2781 const EnumDescriptor* enm = message->FindEnumTypeByName("AnEnum"); |
2709 // TODO(benjy): Support EnumValue options, once the compiler does. | 2782 // TODO(benjy): Support EnumValue options, once the compiler does. |
2710 const ServiceDescriptor* service = | 2783 const ServiceDescriptor* service = |
2711 file->FindServiceByName("TestServiceWithCustomOptions"); | 2784 file->FindServiceByName("TestServiceWithCustomOptions"); |
2712 const MethodDescriptor* method = service->FindMethodByName("Foo"); | 2785 const MethodDescriptor* method = service->FindMethodByName("Foo"); |
2713 | 2786 |
2714 EXPECT_EQ(GOOGLE_LONGLONG(9876543210), | 2787 EXPECT_EQ(GOOGLE_LONGLONG(9876543210), |
2715 file->options().GetExtension(protobuf_unittest::file_opt1)); | 2788 file->options().GetExtension(protobuf_unittest::file_opt1)); |
2716 EXPECT_EQ(-56, | 2789 EXPECT_EQ(-56, |
2717 message->options().GetExtension(protobuf_unittest::message_opt1)); | 2790 message->options().GetExtension(protobuf_unittest::message_opt1)); |
2718 EXPECT_EQ(GOOGLE_LONGLONG(8765432109), | 2791 EXPECT_EQ(GOOGLE_LONGLONG(8765432109), |
2719 field->options().GetExtension(protobuf_unittest::field_opt1)); | 2792 field->options().GetExtension(protobuf_unittest::field_opt1)); |
2720 EXPECT_EQ(42, // Check that we get the default for an option we don't set. | 2793 EXPECT_EQ(42, // Check that we get the default for an option we don't set. |
2721 field->options().GetExtension(protobuf_unittest::field_opt2)); | 2794 field->options().GetExtension(protobuf_unittest::field_opt2)); |
| 2795 EXPECT_EQ(-99, |
| 2796 oneof->options().GetExtension(protobuf_unittest::oneof_opt1)); |
2722 EXPECT_EQ(-789, | 2797 EXPECT_EQ(-789, |
2723 enm->options().GetExtension(protobuf_unittest::enum_opt1)); | 2798 enm->options().GetExtension(protobuf_unittest::enum_opt1)); |
2724 EXPECT_EQ(123, | 2799 EXPECT_EQ(123, |
2725 enm->value(1)->options().GetExtension( | 2800 enm->value(1)->options().GetExtension( |
2726 protobuf_unittest::enum_value_opt1)); | 2801 protobuf_unittest::enum_value_opt1)); |
2727 EXPECT_EQ(GOOGLE_LONGLONG(-9876543210), | 2802 EXPECT_EQ(GOOGLE_LONGLONG(-9876543210), |
2728 service->options().GetExtension(protobuf_unittest::service_opt1)); | 2803 service->options().GetExtension(protobuf_unittest::service_opt1)); |
2729 EXPECT_EQ(protobuf_unittest::METHODOPT1_VAL2, | 2804 EXPECT_EQ(protobuf_unittest::METHODOPT1_VAL2, |
2730 method->options().GetExtension(protobuf_unittest::method_opt1)); | 2805 method->options().GetExtension(protobuf_unittest::method_opt1)); |
2731 | 2806 |
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3257 | 3332 |
3258 string buf; | 3333 string buf; |
3259 // Verify that the required enum field does show up when the option | 3334 // Verify that the required enum field does show up when the option |
3260 // is re-parsed as a NewOptionType message; | 3335 // is re-parsed as a NewOptionType message; |
3261 protobuf_unittest::NewOptionType new_enum_opt; | 3336 protobuf_unittest::NewOptionType new_enum_opt; |
3262 EXPECT_TRUE(old_enum_opt.AppendPartialToString(&buf)); | 3337 EXPECT_TRUE(old_enum_opt.AppendPartialToString(&buf)); |
3263 EXPECT_TRUE(new_enum_opt.ParseFromString(buf)); | 3338 EXPECT_TRUE(new_enum_opt.ParseFromString(buf)); |
3264 EXPECT_EQ(protobuf_unittest::NewOptionType::NEW_VALUE, new_enum_opt.value()); | 3339 EXPECT_EQ(protobuf_unittest::NewOptionType::NEW_VALUE, new_enum_opt.value()); |
3265 } | 3340 } |
3266 | 3341 |
| 3342 // Test that FileDescriptor::DebugString() formats custom options correctly. |
| 3343 TEST(CustomOptions, DebugString) { |
| 3344 DescriptorPool pool; |
| 3345 |
| 3346 FileDescriptorProto file_proto; |
| 3347 MessageOptions::descriptor()->file()->CopyTo(&file_proto); |
| 3348 ASSERT_TRUE(pool.BuildFile(file_proto) != NULL); |
| 3349 |
| 3350 // Add "foo.proto": |
| 3351 // import "google/protobuf/descriptor.proto"; |
| 3352 // package "protobuf_unittest"; |
| 3353 // option (protobuf_unittest.cc_option1) = 1; |
| 3354 // option (protobuf_unittest.cc_option2) = 2; |
| 3355 // extend google.protobuf.FieldOptions { |
| 3356 // optional int32 cc_option1 = 7736974; |
| 3357 // optional int32 cc_option2 = 7736975; |
| 3358 // } |
| 3359 ASSERT_TRUE(TextFormat::ParseFromString( |
| 3360 "name: \"foo.proto\" " |
| 3361 "package: \"protobuf_unittest\" " |
| 3362 "dependency: \"google/protobuf/descriptor.proto\" " |
| 3363 "options { " |
| 3364 " uninterpreted_option { " |
| 3365 " name { " |
| 3366 " name_part: \"protobuf_unittest.cc_option1\" " |
| 3367 " is_extension: true " |
| 3368 " } " |
| 3369 " positive_int_value: 1 " |
| 3370 " } " |
| 3371 " uninterpreted_option { " |
| 3372 " name { " |
| 3373 " name_part: \"protobuf_unittest.cc_option2\" " |
| 3374 " is_extension: true " |
| 3375 " } " |
| 3376 " positive_int_value: 2 " |
| 3377 " } " |
| 3378 "} " |
| 3379 "extension { " |
| 3380 " name: \"cc_option1\" " |
| 3381 " extendee: \".google.protobuf.FileOptions\" " |
| 3382 // This field number is intentionally chosen to be the same as |
| 3383 // (.fileopt1) defined in unittest_custom_options.proto (linked |
| 3384 // in this test binary). This is to test whether we are messing |
| 3385 // generated pool with custom descriptor pools when dealing with |
| 3386 // custom options. |
| 3387 " number: 7736974 " |
| 3388 " label: LABEL_OPTIONAL " |
| 3389 " type: TYPE_INT32 " |
| 3390 "}" |
| 3391 "extension { " |
| 3392 " name: \"cc_option2\" " |
| 3393 " extendee: \".google.protobuf.FileOptions\" " |
| 3394 " number: 7736975 " |
| 3395 " label: LABEL_OPTIONAL " |
| 3396 " type: TYPE_INT32 " |
| 3397 "}", |
| 3398 &file_proto)); |
| 3399 const FileDescriptor* descriptor = pool.BuildFile(file_proto); |
| 3400 ASSERT_TRUE(descriptor != NULL); |
| 3401 |
| 3402 EXPECT_EQ(2, descriptor->extension_count()); |
| 3403 |
| 3404 ASSERT_EQ( |
| 3405 "syntax = \"proto2\";\n" |
| 3406 "\n" |
| 3407 "import \"google/protobuf/descriptor.proto\";\n" |
| 3408 "package protobuf_unittest;\n" |
| 3409 "\n" |
| 3410 "option (.protobuf_unittest.cc_option1) = 1;\n" |
| 3411 "option (.protobuf_unittest.cc_option2) = 2;\n" |
| 3412 "\n" |
| 3413 "extend .google.protobuf.FileOptions {\n" |
| 3414 " optional int32 cc_option1 = 7736974;\n" |
| 3415 " optional int32 cc_option2 = 7736975;\n" |
| 3416 "}\n" |
| 3417 "\n", |
| 3418 descriptor->DebugString()); |
| 3419 } |
| 3420 |
3267 // =================================================================== | 3421 // =================================================================== |
3268 | 3422 |
3269 class ValidationErrorTest : public testing::Test { | 3423 class ValidationErrorTest : public testing::Test { |
3270 protected: | 3424 protected: |
3271 // Parse file_text as a FileDescriptorProto in text format and add it | 3425 // Parse file_text as a FileDescriptorProto in text format and add it |
3272 // to the DescriptorPool. Expect no errors. | 3426 // to the DescriptorPool. Expect no errors. |
3273 const FileDescriptor* BuildFile(const string& file_text) { | 3427 const FileDescriptor* BuildFile(const string& file_text) { |
3274 FileDescriptorProto file_proto; | 3428 FileDescriptorProto file_proto; |
3275 EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto)); | 3429 EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto)); |
3276 return GOOGLE_CHECK_NOTNULL(pool_.BuildFile(file_proto)); | 3430 return GOOGLE_CHECK_NOTNULL(pool_.BuildFile(file_proto)); |
(...skipping 1743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5020 "\"foo = { <proto text format> }\". To set fields within it, use " | 5174 "\"foo = { <proto text format> }\". To set fields within it, use " |
5021 "syntax like \"foo.foo = value\".\n"); | 5175 "syntax like \"foo.foo = value\".\n"); |
5022 } | 5176 } |
5023 | 5177 |
5024 TEST_F(ValidationErrorTest, AggregateValueParseError) { | 5178 TEST_F(ValidationErrorTest, AggregateValueParseError) { |
5025 BuildDescriptorMessagesInTestPool(); | 5179 BuildDescriptorMessagesInTestPool(); |
5026 | 5180 |
5027 BuildFileWithErrors( | 5181 BuildFileWithErrors( |
5028 EmbedAggregateValue("aggregate_value: \"1+2\""), | 5182 EmbedAggregateValue("aggregate_value: \"1+2\""), |
5029 "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option " | 5183 "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option " |
5030 "value for \"foo\": Expected identifier.\n"); | 5184 "value for \"foo\": Expected identifier, got: 1\n"); |
5031 } | 5185 } |
5032 | 5186 |
5033 TEST_F(ValidationErrorTest, AggregateValueUnknownFields) { | 5187 TEST_F(ValidationErrorTest, AggregateValueUnknownFields) { |
5034 BuildDescriptorMessagesInTestPool(); | 5188 BuildDescriptorMessagesInTestPool(); |
5035 | 5189 |
5036 BuildFileWithErrors( | 5190 BuildFileWithErrors( |
5037 EmbedAggregateValue("aggregate_value: \"x:100\""), | 5191 EmbedAggregateValue("aggregate_value: \"x:100\""), |
5038 "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option " | 5192 "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option " |
5039 "value for \"foo\": Message type \"Foo\" has no field named \"x\".\n"); | 5193 "value for \"foo\": Message type \"Foo\" has no field named \"x\".\n"); |
5040 } | 5194 } |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5150 // Test that errors are reported to GOOGLE_LOG(ERROR) if no error collector is | 5304 // Test that errors are reported to GOOGLE_LOG(ERROR) if no error collector is |
5151 // provided. | 5305 // provided. |
5152 | 5306 |
5153 FileDescriptorProto file_proto; | 5307 FileDescriptorProto file_proto; |
5154 ASSERT_TRUE(TextFormat::ParseFromString( | 5308 ASSERT_TRUE(TextFormat::ParseFromString( |
5155 "name: \"foo.proto\" " | 5309 "name: \"foo.proto\" " |
5156 "message_type { name: \"Foo\" } " | 5310 "message_type { name: \"Foo\" } " |
5157 "message_type { name: \"Foo\" } ", | 5311 "message_type { name: \"Foo\" } ", |
5158 &file_proto)); | 5312 &file_proto)); |
5159 | 5313 |
5160 vector<string> errors; | 5314 std::vector<string> errors; |
5161 | 5315 |
5162 { | 5316 { |
5163 ScopedMemoryLog log; | 5317 ScopedMemoryLog log; |
5164 EXPECT_TRUE(pool_.BuildFile(file_proto) == NULL); | 5318 EXPECT_TRUE(pool_.BuildFile(file_proto) == NULL); |
5165 errors = log.GetMessages(ERROR); | 5319 errors = log.GetMessages(ERROR); |
5166 } | 5320 } |
5167 | 5321 |
5168 ASSERT_EQ(2, errors.size()); | 5322 ASSERT_EQ(2, errors.size()); |
5169 | 5323 |
5170 EXPECT_EQ("Invalid proto descriptor for file \"foo.proto\":", errors[0]); | 5324 EXPECT_EQ("Invalid proto descriptor for file \"foo.proto\":", errors[0]); |
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5544 "}", | 5698 "}", |
5545 file_proto.mutable_message_type(0)); | 5699 file_proto.mutable_message_type(0)); |
5546 BuildFileWithErrors( | 5700 BuildFileWithErrors( |
5547 file_proto.DebugString(), | 5701 file_proto.DebugString(), |
5548 "foo.proto: Foo.FooMapEntry: NAME: \"FooMapEntry\" is already defined in " | 5702 "foo.proto: Foo.FooMapEntry: NAME: \"FooMapEntry\" is already defined in " |
5549 "\"Foo\".\n" | 5703 "\"Foo\".\n" |
5550 "foo.proto: Foo: NAME: Expanded map entry type FooMapEntry conflicts " | 5704 "foo.proto: Foo: NAME: Expanded map entry type FooMapEntry conflicts " |
5551 "with an existing enum type.\n"); | 5705 "with an existing enum type.\n"); |
5552 } | 5706 } |
5553 | 5707 |
| 5708 TEST_F(ValidationErrorTest, EnumValuesConflictWhenPrefixesStripped) { |
| 5709 BuildFileWithErrors( |
| 5710 "syntax: 'proto3'" |
| 5711 "name: 'foo.proto' " |
| 5712 "enum_type {" |
| 5713 " name: 'FooEnum' " |
| 5714 " value { name: 'FOO_ENUM_BAZ' number: 0 }" |
| 5715 " value { name: 'BAZ' number: 1 }" |
| 5716 "}", |
| 5717 "foo.proto: BAZ: NAME: When enum name is stripped and label is " |
| 5718 "PascalCased (Baz), this value label conflicts with FOO_ENUM_BAZ. This " |
| 5719 "will make the proto fail to compile for some languages, such as C#.\n"); |
| 5720 |
| 5721 BuildFileWithErrors( |
| 5722 "syntax: 'proto3'" |
| 5723 "name: 'foo.proto' " |
| 5724 "enum_type {" |
| 5725 " name: 'FooEnum' " |
| 5726 " value { name: 'FOOENUM_BAZ' number: 0 }" |
| 5727 " value { name: 'BAZ' number: 1 }" |
| 5728 "}", |
| 5729 "foo.proto: BAZ: NAME: When enum name is stripped and label is " |
| 5730 "PascalCased (Baz), this value label conflicts with FOOENUM_BAZ. This " |
| 5731 "will make the proto fail to compile for some languages, such as C#.\n"); |
| 5732 |
| 5733 BuildFileWithErrors( |
| 5734 "syntax: 'proto3'" |
| 5735 "name: 'foo.proto' " |
| 5736 "enum_type {" |
| 5737 " name: 'FooEnum' " |
| 5738 " value { name: 'FOO_ENUM_BAR_BAZ' number: 0 }" |
| 5739 " value { name: 'BAR__BAZ' number: 1 }" |
| 5740 "}", |
| 5741 "foo.proto: BAR__BAZ: NAME: When enum name is stripped and label is " |
| 5742 "PascalCased (BarBaz), this value label conflicts with " |
| 5743 "FOO_ENUM_BAR_BAZ. This will make the proto fail to compile for some " |
| 5744 "languages, such as C#.\n"); |
| 5745 |
| 5746 BuildFileWithErrors( |
| 5747 "syntax: 'proto3'" |
| 5748 "name: 'foo.proto' " |
| 5749 "enum_type {" |
| 5750 " name: 'FooEnum' " |
| 5751 " value { name: 'FOO_ENUM__BAR_BAZ' number: 0 }" |
| 5752 " value { name: 'BAR_BAZ' number: 1 }" |
| 5753 "}", |
| 5754 "foo.proto: BAR_BAZ: NAME: When enum name is stripped and label is " |
| 5755 "PascalCased (BarBaz), this value label conflicts with " |
| 5756 "FOO_ENUM__BAR_BAZ. This will make the proto fail to compile for some " |
| 5757 "languages, such as C#.\n"); |
| 5758 |
| 5759 // This isn't an error because the underscore will cause the PascalCase to |
| 5760 // differ by case (BarBaz vs. Barbaz). |
| 5761 BuildFile( |
| 5762 "syntax: 'proto3'" |
| 5763 "name: 'foo.proto' " |
| 5764 "enum_type {" |
| 5765 " name: 'FooEnum' " |
| 5766 " value { name: 'BAR_BAZ' number: 0 }" |
| 5767 " value { name: 'BARBAZ' number: 1 }" |
| 5768 "}"); |
| 5769 } |
| 5770 |
5554 TEST_F(ValidationErrorTest, MapEntryConflictsWithOneof) { | 5771 TEST_F(ValidationErrorTest, MapEntryConflictsWithOneof) { |
5555 FileDescriptorProto file_proto; | 5772 FileDescriptorProto file_proto; |
5556 FillValidMapEntry(&file_proto); | 5773 FillValidMapEntry(&file_proto); |
5557 TextFormat::MergeFromString( | 5774 TextFormat::MergeFromString( |
5558 "oneof_decl { " | 5775 "oneof_decl { " |
5559 " name: 'FooMapEntry' " | 5776 " name: 'FooMapEntry' " |
5560 "}" | 5777 "}" |
5561 "field { " | 5778 "field { " |
5562 " name: 'int_field' " | 5779 " name: 'int_field' " |
5563 " type: TYPE_INT32 " | 5780 " type: TYPE_INT32 " |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5827 TEST_F(ValidationErrorTest, ValidateProto3JsonName) { | 6044 TEST_F(ValidationErrorTest, ValidateProto3JsonName) { |
5828 // The comparison is case-insensitive. | 6045 // The comparison is case-insensitive. |
5829 BuildFileWithErrors( | 6046 BuildFileWithErrors( |
5830 "name: 'foo.proto' " | 6047 "name: 'foo.proto' " |
5831 "syntax: 'proto3' " | 6048 "syntax: 'proto3' " |
5832 "message_type {" | 6049 "message_type {" |
5833 " name: 'Foo'" | 6050 " name: 'Foo'" |
5834 " field { name:'name' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 }" | 6051 " field { name:'name' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 }" |
5835 " field { name:'Name' number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }" | 6052 " field { name:'Name' number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }" |
5836 "}", | 6053 "}", |
5837 "foo.proto: Foo: OTHER: The JSON camcel-case name of field \"Name\" " | 6054 "foo.proto: Foo: OTHER: The JSON camel-case name of field \"Name\" " |
5838 "conflicts with field \"name\". This is not allowed in proto3.\n"); | 6055 "conflicts with field \"name\". This is not allowed in proto3.\n"); |
5839 // Underscores are ignored. | 6056 // Underscores are ignored. |
5840 BuildFileWithErrors( | 6057 BuildFileWithErrors( |
5841 "name: 'foo.proto' " | 6058 "name: 'foo.proto' " |
5842 "syntax: 'proto3' " | 6059 "syntax: 'proto3' " |
5843 "message_type {" | 6060 "message_type {" |
5844 " name: 'Foo'" | 6061 " name: 'Foo'" |
5845 " field { name:'ab' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 }" | 6062 " field { name:'ab' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 }" |
5846 " field { name:'_a__b_' number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }" | 6063 " field { name:'_a__b_' number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }" |
5847 "}", | 6064 "}", |
5848 "foo.proto: Foo: OTHER: The JSON camcel-case name of field \"_a__b_\" " | 6065 "foo.proto: Foo: OTHER: The JSON camel-case name of field \"_a__b_\" " |
5849 "conflicts with field \"ab\". This is not allowed in proto3.\n"); | 6066 "conflicts with field \"ab\". This is not allowed in proto3.\n"); |
5850 } | 6067 } |
5851 | 6068 |
5852 // =================================================================== | 6069 // =================================================================== |
5853 // DescriptorDatabase | 6070 // DescriptorDatabase |
5854 | 6071 |
5855 static void AddToDatabase(SimpleDescriptorDatabase* database, | 6072 static void AddToDatabase(SimpleDescriptorDatabase* database, |
5856 const char* file_text) { | 6073 const char* file_text) { |
5857 FileDescriptorProto file_proto; | 6074 FileDescriptorProto file_proto; |
5858 EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto)); | 6075 EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto)); |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6077 } | 6294 } |
6078 | 6295 |
6079 TEST_F(DatabaseBackedPoolTest, FindAllExtensions) { | 6296 TEST_F(DatabaseBackedPoolTest, FindAllExtensions) { |
6080 DescriptorPool pool(&database_); | 6297 DescriptorPool pool(&database_); |
6081 | 6298 |
6082 const Descriptor* foo = pool.FindMessageTypeByName("Foo"); | 6299 const Descriptor* foo = pool.FindMessageTypeByName("Foo"); |
6083 | 6300 |
6084 for (int i = 0; i < 2; ++i) { | 6301 for (int i = 0; i < 2; ++i) { |
6085 // Repeat the lookup twice, to check that we get consistent | 6302 // Repeat the lookup twice, to check that we get consistent |
6086 // results despite the fallback database lookup mutating the pool. | 6303 // results despite the fallback database lookup mutating the pool. |
6087 vector<const FieldDescriptor*> extensions; | 6304 std::vector<const FieldDescriptor*> extensions; |
6088 pool.FindAllExtensions(foo, &extensions); | 6305 pool.FindAllExtensions(foo, &extensions); |
6089 ASSERT_EQ(1, extensions.size()); | 6306 ASSERT_EQ(1, extensions.size()); |
6090 EXPECT_EQ(5, extensions[0]->number()); | 6307 EXPECT_EQ(5, extensions[0]->number()); |
6091 } | 6308 } |
6092 } | 6309 } |
6093 | 6310 |
6094 TEST_F(DatabaseBackedPoolTest, ErrorWithoutErrorCollector) { | 6311 TEST_F(DatabaseBackedPoolTest, ErrorWithoutErrorCollector) { |
6095 ErrorDescriptorDatabase error_database; | 6312 ErrorDescriptorDatabase error_database; |
6096 DescriptorPool pool(&error_database); | 6313 DescriptorPool pool(&error_database); |
6097 | 6314 |
6098 vector<string> errors; | 6315 std::vector<string> errors; |
6099 | 6316 |
6100 { | 6317 { |
6101 ScopedMemoryLog log; | 6318 ScopedMemoryLog log; |
6102 EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL); | 6319 EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL); |
6103 errors = log.GetMessages(ERROR); | 6320 errors = log.GetMessages(ERROR); |
6104 } | 6321 } |
6105 | 6322 |
6106 EXPECT_FALSE(errors.empty()); | 6323 EXPECT_FALSE(errors.empty()); |
6107 } | 6324 } |
6108 | 6325 |
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6604 EXPECT_EQ(0, foo_location.span(1)); // Foo starts at column 0 | 6821 EXPECT_EQ(0, foo_location.span(1)); // Foo starts at column 0 |
6605 EXPECT_EQ(14, foo_location.span(2)); // Foo ends on column 14 | 6822 EXPECT_EQ(14, foo_location.span(2)); // Foo ends on column 14 |
6606 } | 6823 } |
6607 | 6824 |
6608 // =================================================================== | 6825 // =================================================================== |
6609 | 6826 |
6610 | 6827 |
6611 } // namespace descriptor_unittest | 6828 } // namespace descriptor_unittest |
6612 } // namespace protobuf | 6829 } // namespace protobuf |
6613 } // namespace google | 6830 } // namespace google |
OLD | NEW |