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> | |
45 #include <google/protobuf/unittest.pb.h> | 44 #include <google/protobuf/unittest.pb.h> |
46 #include <google/protobuf/unittest_custom_options.pb.h> | 45 #include <google/protobuf/unittest_custom_options.pb.h> |
47 #include <google/protobuf/unittest_proto3_arena.pb.h> | |
48 #include <google/protobuf/io/tokenizer.h> | |
49 #include <google/protobuf/io/zero_copy_stream_impl.h> | 46 #include <google/protobuf/io/zero_copy_stream_impl.h> |
50 #include <google/protobuf/descriptor.pb.h> | 47 #include <google/protobuf/descriptor.pb.h> |
51 #include <google/protobuf/descriptor.h> | 48 #include <google/protobuf/descriptor.h> |
52 #include <google/protobuf/descriptor_database.h> | 49 #include <google/protobuf/descriptor_database.h> |
53 #include <google/protobuf/dynamic_message.h> | 50 #include <google/protobuf/dynamic_message.h> |
54 #include <google/protobuf/text_format.h> | 51 #include <google/protobuf/text_format.h> |
55 #include <google/protobuf/stubs/strutil.h> | 52 #include <google/protobuf/stubs/strutil.h> |
56 #include <google/protobuf/stubs/substitute.h> | 53 #include <google/protobuf/stubs/substitute.h> |
57 | 54 |
58 #include <google/protobuf/stubs/common.h> | 55 #include <google/protobuf/stubs/common.h> |
59 #include <google/protobuf/stubs/logging.h> | 56 #include <google/protobuf/stubs/logging.h> |
60 #include <google/protobuf/stubs/logging.h> | 57 #include <google/protobuf/stubs/logging.h> |
61 #include <google/protobuf/stubs/stringprintf.h> | 58 #include <google/protobuf/stubs/scoped_ptr.h> |
62 #include <google/protobuf/testing/googletest.h> | 59 #include <google/protobuf/testing/googletest.h> |
63 #include <gtest/gtest.h> | 60 #include <gtest/gtest.h> |
64 | 61 |
65 namespace google { | 62 namespace google { |
66 namespace protobuf { | 63 namespace protobuf { |
67 | 64 |
68 // Can't use an anonymous namespace here due to brokenness of Tru64 compiler. | 65 // Can't use an anonymous namespace here due to brokenness of Tru64 compiler. |
69 namespace descriptor_unittest { | 66 namespace descriptor_unittest { |
70 | 67 |
71 // Some helpers to make assembling descriptors faster. | 68 // Some helpers to make assembling descriptors faster. |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 DescriptorPool pool; | 482 DescriptorPool pool; |
486 const FileDescriptor* file = pool.BuildFile(proto); | 483 const FileDescriptor* file = pool.BuildFile(proto); |
487 EXPECT_TRUE(file != NULL); | 484 EXPECT_TRUE(file != NULL); |
488 EXPECT_EQ(FileDescriptor::SYNTAX_PROTO3, file->syntax()); | 485 EXPECT_EQ(FileDescriptor::SYNTAX_PROTO3, file->syntax()); |
489 FileDescriptorProto other; | 486 FileDescriptorProto other; |
490 file->CopyTo(&other); | 487 file->CopyTo(&other); |
491 EXPECT_EQ("proto3", other.syntax()); | 488 EXPECT_EQ("proto3", other.syntax()); |
492 } | 489 } |
493 } | 490 } |
494 | 491 |
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 | |
554 // =================================================================== | 492 // =================================================================== |
555 | 493 |
556 // Test simple flat messages and fields. | 494 // Test simple flat messages and fields. |
557 class DescriptorTest : public testing::Test { | 495 class DescriptorTest : public testing::Test { |
558 protected: | 496 protected: |
559 virtual void SetUp() { | 497 virtual void SetUp() { |
560 // Build descriptors for the following definitions: | 498 // Build descriptors for the following definitions: |
561 // | 499 // |
562 // // in "foo.proto" | 500 // // in "foo.proto" |
563 // message TestForeign {} | 501 // message TestForeign {} |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
829 EXPECT_EQ("TestMessage.qux", qux_->full_name()); | 767 EXPECT_EQ("TestMessage.qux", qux_->full_name()); |
830 | 768 |
831 EXPECT_EQ("corge.grault.TestMessage2.foo", foo2_->full_name()); | 769 EXPECT_EQ("corge.grault.TestMessage2.foo", foo2_->full_name()); |
832 EXPECT_EQ("corge.grault.TestMessage2.bar", bar2_->full_name()); | 770 EXPECT_EQ("corge.grault.TestMessage2.bar", bar2_->full_name()); |
833 EXPECT_EQ("corge.grault.TestMessage2.quux", quux2_->full_name()); | 771 EXPECT_EQ("corge.grault.TestMessage2.quux", quux2_->full_name()); |
834 } | 772 } |
835 | 773 |
836 TEST_F(DescriptorTest, FieldJsonName) { | 774 TEST_F(DescriptorTest, FieldJsonName) { |
837 EXPECT_EQ("fieldName1", message4_->field(0)->json_name()); | 775 EXPECT_EQ("fieldName1", message4_->field(0)->json_name()); |
838 EXPECT_EQ("fieldName2", message4_->field(1)->json_name()); | 776 EXPECT_EQ("fieldName2", message4_->field(1)->json_name()); |
839 EXPECT_EQ("FieldName3", message4_->field(2)->json_name()); | 777 EXPECT_EQ("fieldName3", message4_->field(2)->json_name()); |
840 EXPECT_EQ("FieldName4", message4_->field(3)->json_name()); | 778 EXPECT_EQ("fieldName4", message4_->field(3)->json_name()); |
841 EXPECT_EQ("FIELDNAME5", message4_->field(4)->json_name()); | 779 EXPECT_EQ("fIELDNAME5", message4_->field(4)->json_name()); |
842 EXPECT_EQ("@type", message4_->field(5)->json_name()); | 780 EXPECT_EQ("@type", message4_->field(5)->json_name()); |
843 | 781 |
844 DescriptorProto proto; | 782 DescriptorProto proto; |
845 message4_->CopyTo(&proto); | 783 message4_->CopyTo(&proto); |
846 ASSERT_EQ(6, proto.field_size()); | 784 ASSERT_EQ(6, proto.field_size()); |
847 EXPECT_FALSE(proto.field(0).has_json_name()); | 785 EXPECT_FALSE(proto.field(0).has_json_name()); |
848 EXPECT_FALSE(proto.field(1).has_json_name()); | 786 EXPECT_FALSE(proto.field(1).has_json_name()); |
849 EXPECT_FALSE(proto.field(2).has_json_name()); | 787 EXPECT_FALSE(proto.field(2).has_json_name()); |
850 EXPECT_FALSE(proto.field(3).has_json_name()); | 788 EXPECT_FALSE(proto.field(3).has_json_name()); |
851 EXPECT_FALSE(proto.field(4).has_json_name()); | 789 EXPECT_FALSE(proto.field(4).has_json_name()); |
852 EXPECT_EQ("@type", proto.field(5).json_name()); | 790 EXPECT_EQ("@type", proto.field(5).json_name()); |
853 | 791 |
854 proto.Clear(); | 792 proto.Clear(); |
855 CopyWithJsonName(message4_, &proto); | 793 CopyWithJsonName(message4_, &proto); |
856 ASSERT_EQ(6, proto.field_size()); | 794 ASSERT_EQ(6, proto.field_size()); |
857 EXPECT_EQ("fieldName1", proto.field(0).json_name()); | 795 EXPECT_EQ("fieldName1", proto.field(0).json_name()); |
858 EXPECT_EQ("fieldName2", proto.field(1).json_name()); | 796 EXPECT_EQ("fieldName2", proto.field(1).json_name()); |
859 EXPECT_EQ("FieldName3", proto.field(2).json_name()); | 797 EXPECT_EQ("fieldName3", proto.field(2).json_name()); |
860 EXPECT_EQ("FieldName4", proto.field(3).json_name()); | 798 EXPECT_EQ("fieldName4", proto.field(3).json_name()); |
861 EXPECT_EQ("FIELDNAME5", proto.field(4).json_name()); | 799 EXPECT_EQ("fIELDNAME5", proto.field(4).json_name()); |
862 EXPECT_EQ("@type", proto.field(5).json_name()); | 800 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()); | |
873 } | 801 } |
874 | 802 |
875 TEST_F(DescriptorTest, FieldFile) { | 803 TEST_F(DescriptorTest, FieldFile) { |
876 EXPECT_EQ(foo_file_, foo_->file()); | 804 EXPECT_EQ(foo_file_, foo_->file()); |
877 EXPECT_EQ(foo_file_, bar_->file()); | 805 EXPECT_EQ(foo_file_, bar_->file()); |
878 EXPECT_EQ(foo_file_, baz_->file()); | 806 EXPECT_EQ(foo_file_, baz_->file()); |
879 EXPECT_EQ(foo_file_, qux_->file()); | 807 EXPECT_EQ(foo_file_, qux_->file()); |
880 | 808 |
881 EXPECT_EQ(bar_file_, foo2_->file()); | 809 EXPECT_EQ(bar_file_, foo2_->file()); |
882 EXPECT_EQ(bar_file_, bar2_->file()); | 810 EXPECT_EQ(bar_file_, bar2_->file()); |
(...skipping 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1917 | 1845 |
1918 EXPECT_EQ(bar_->extension(0), bar_->FindExtensionByName("foo_message")); | 1846 EXPECT_EQ(bar_->extension(0), bar_->FindExtensionByName("foo_message")); |
1919 EXPECT_EQ(bar_->extension(1), bar_->FindExtensionByName("foo_group" )); | 1847 EXPECT_EQ(bar_->extension(1), bar_->FindExtensionByName("foo_group" )); |
1920 | 1848 |
1921 EXPECT_TRUE(bar_->FindExtensionByName("no_such_extension") == NULL); | 1849 EXPECT_TRUE(bar_->FindExtensionByName("no_such_extension") == NULL); |
1922 EXPECT_TRUE(foo_->FindExtensionByName("foo_int32") == NULL); | 1850 EXPECT_TRUE(foo_->FindExtensionByName("foo_int32") == NULL); |
1923 EXPECT_TRUE(foo_->FindExtensionByName("foo_message") == NULL); | 1851 EXPECT_TRUE(foo_->FindExtensionByName("foo_message") == NULL); |
1924 } | 1852 } |
1925 | 1853 |
1926 TEST_F(ExtensionDescriptorTest, FindAllExtensions) { | 1854 TEST_F(ExtensionDescriptorTest, FindAllExtensions) { |
1927 std::vector<const FieldDescriptor*> extensions; | 1855 vector<const FieldDescriptor*> extensions; |
1928 pool_.FindAllExtensions(foo_, &extensions); | 1856 pool_.FindAllExtensions(foo_, &extensions); |
1929 ASSERT_EQ(4, extensions.size()); | 1857 ASSERT_EQ(4, extensions.size()); |
1930 EXPECT_EQ(10, extensions[0]->number()); | 1858 EXPECT_EQ(10, extensions[0]->number()); |
1931 EXPECT_EQ(19, extensions[1]->number()); | 1859 EXPECT_EQ(19, extensions[1]->number()); |
1932 EXPECT_EQ(30, extensions[2]->number()); | 1860 EXPECT_EQ(30, extensions[2]->number()); |
1933 EXPECT_EQ(39, extensions[3]->number()); | 1861 EXPECT_EQ(39, extensions[3]->number()); |
1934 } | 1862 } |
1935 | 1863 |
1936 TEST_F(ExtensionDescriptorTest, DuplicateFieldNumber) { | 1864 TEST_F(ExtensionDescriptorTest, DuplicateFieldNumber) { |
1937 DescriptorPool pool; | 1865 DescriptorPool pool; |
(...skipping 743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2681 " identifier_value: \"SPEED\" " | 2609 " identifier_value: \"SPEED\" " |
2682 " } " | 2610 " } " |
2683 "}", | 2611 "}", |
2684 &option_proto)); | 2612 &option_proto)); |
2685 | 2613 |
2686 const FileDescriptor* file = BuildFile(option_proto); | 2614 const FileDescriptor* file = BuildFile(option_proto); |
2687 ASSERT_TRUE(file != NULL); | 2615 ASSERT_TRUE(file != NULL); |
2688 | 2616 |
2689 // Verify that no extension options were set, but they were left as | 2617 // Verify that no extension options were set, but they were left as |
2690 // uninterpreted_options. | 2618 // uninterpreted_options. |
2691 std::vector<const FieldDescriptor*> fields; | 2619 vector<const FieldDescriptor*> fields; |
2692 file->options().GetReflection()->ListFields(file->options(), &fields); | 2620 file->options().GetReflection()->ListFields(file->options(), &fields); |
2693 ASSERT_EQ(2, fields.size()); | 2621 ASSERT_EQ(2, fields.size()); |
2694 EXPECT_TRUE(file->options().has_optimize_for()); | 2622 EXPECT_TRUE(file->options().has_optimize_for()); |
2695 EXPECT_EQ(2, file->options().uninterpreted_option_size()); | 2623 EXPECT_EQ(2, file->options().uninterpreted_option_size()); |
2696 } | 2624 } |
2697 | 2625 |
2698 TEST_P(AllowUnknownDependenciesTest, | 2626 TEST_P(AllowUnknownDependenciesTest, |
2699 UndeclaredDependencyTriggersBuildOfDependency) { | 2627 UndeclaredDependencyTriggersBuildOfDependency) { |
2700 // Crazy case: suppose foo.proto refers to a symbol without declaring the | 2628 // Crazy case: suppose foo.proto refers to a symbol without declaring the |
2701 // dependency that finds it. In the event that the pool is backed by a | 2629 // 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... |
2770 AllowUnknownDependenciesTest, | 2698 AllowUnknownDependenciesTest, |
2771 testing::Values(NO_DATABASE, FALLBACK_DATABASE)); | 2699 testing::Values(NO_DATABASE, FALLBACK_DATABASE)); |
2772 | 2700 |
2773 // =================================================================== | 2701 // =================================================================== |
2774 | 2702 |
2775 TEST(CustomOptions, OptionLocations) { | 2703 TEST(CustomOptions, OptionLocations) { |
2776 const Descriptor* message = | 2704 const Descriptor* message = |
2777 protobuf_unittest::TestMessageWithCustomOptions::descriptor(); | 2705 protobuf_unittest::TestMessageWithCustomOptions::descriptor(); |
2778 const FileDescriptor* file = message->file(); | 2706 const FileDescriptor* file = message->file(); |
2779 const FieldDescriptor* field = message->FindFieldByName("field1"); | 2707 const FieldDescriptor* field = message->FindFieldByName("field1"); |
2780 const OneofDescriptor* oneof = message->FindOneofByName("AnOneof"); | |
2781 const EnumDescriptor* enm = message->FindEnumTypeByName("AnEnum"); | 2708 const EnumDescriptor* enm = message->FindEnumTypeByName("AnEnum"); |
2782 // TODO(benjy): Support EnumValue options, once the compiler does. | 2709 // TODO(benjy): Support EnumValue options, once the compiler does. |
2783 const ServiceDescriptor* service = | 2710 const ServiceDescriptor* service = |
2784 file->FindServiceByName("TestServiceWithCustomOptions"); | 2711 file->FindServiceByName("TestServiceWithCustomOptions"); |
2785 const MethodDescriptor* method = service->FindMethodByName("Foo"); | 2712 const MethodDescriptor* method = service->FindMethodByName("Foo"); |
2786 | 2713 |
2787 EXPECT_EQ(GOOGLE_LONGLONG(9876543210), | 2714 EXPECT_EQ(GOOGLE_LONGLONG(9876543210), |
2788 file->options().GetExtension(protobuf_unittest::file_opt1)); | 2715 file->options().GetExtension(protobuf_unittest::file_opt1)); |
2789 EXPECT_EQ(-56, | 2716 EXPECT_EQ(-56, |
2790 message->options().GetExtension(protobuf_unittest::message_opt1)); | 2717 message->options().GetExtension(protobuf_unittest::message_opt1)); |
2791 EXPECT_EQ(GOOGLE_LONGLONG(8765432109), | 2718 EXPECT_EQ(GOOGLE_LONGLONG(8765432109), |
2792 field->options().GetExtension(protobuf_unittest::field_opt1)); | 2719 field->options().GetExtension(protobuf_unittest::field_opt1)); |
2793 EXPECT_EQ(42, // Check that we get the default for an option we don't set. | 2720 EXPECT_EQ(42, // Check that we get the default for an option we don't set. |
2794 field->options().GetExtension(protobuf_unittest::field_opt2)); | 2721 field->options().GetExtension(protobuf_unittest::field_opt2)); |
2795 EXPECT_EQ(-99, | |
2796 oneof->options().GetExtension(protobuf_unittest::oneof_opt1)); | |
2797 EXPECT_EQ(-789, | 2722 EXPECT_EQ(-789, |
2798 enm->options().GetExtension(protobuf_unittest::enum_opt1)); | 2723 enm->options().GetExtension(protobuf_unittest::enum_opt1)); |
2799 EXPECT_EQ(123, | 2724 EXPECT_EQ(123, |
2800 enm->value(1)->options().GetExtension( | 2725 enm->value(1)->options().GetExtension( |
2801 protobuf_unittest::enum_value_opt1)); | 2726 protobuf_unittest::enum_value_opt1)); |
2802 EXPECT_EQ(GOOGLE_LONGLONG(-9876543210), | 2727 EXPECT_EQ(GOOGLE_LONGLONG(-9876543210), |
2803 service->options().GetExtension(protobuf_unittest::service_opt1)); | 2728 service->options().GetExtension(protobuf_unittest::service_opt1)); |
2804 EXPECT_EQ(protobuf_unittest::METHODOPT1_VAL2, | 2729 EXPECT_EQ(protobuf_unittest::METHODOPT1_VAL2, |
2805 method->options().GetExtension(protobuf_unittest::method_opt1)); | 2730 method->options().GetExtension(protobuf_unittest::method_opt1)); |
2806 | 2731 |
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3332 | 3257 |
3333 string buf; | 3258 string buf; |
3334 // Verify that the required enum field does show up when the option | 3259 // Verify that the required enum field does show up when the option |
3335 // is re-parsed as a NewOptionType message; | 3260 // is re-parsed as a NewOptionType message; |
3336 protobuf_unittest::NewOptionType new_enum_opt; | 3261 protobuf_unittest::NewOptionType new_enum_opt; |
3337 EXPECT_TRUE(old_enum_opt.AppendPartialToString(&buf)); | 3262 EXPECT_TRUE(old_enum_opt.AppendPartialToString(&buf)); |
3338 EXPECT_TRUE(new_enum_opt.ParseFromString(buf)); | 3263 EXPECT_TRUE(new_enum_opt.ParseFromString(buf)); |
3339 EXPECT_EQ(protobuf_unittest::NewOptionType::NEW_VALUE, new_enum_opt.value()); | 3264 EXPECT_EQ(protobuf_unittest::NewOptionType::NEW_VALUE, new_enum_opt.value()); |
3340 } | 3265 } |
3341 | 3266 |
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 | |
3421 // =================================================================== | 3267 // =================================================================== |
3422 | 3268 |
3423 class ValidationErrorTest : public testing::Test { | 3269 class ValidationErrorTest : public testing::Test { |
3424 protected: | 3270 protected: |
3425 // Parse file_text as a FileDescriptorProto in text format and add it | 3271 // Parse file_text as a FileDescriptorProto in text format and add it |
3426 // to the DescriptorPool. Expect no errors. | 3272 // to the DescriptorPool. Expect no errors. |
3427 const FileDescriptor* BuildFile(const string& file_text) { | 3273 const FileDescriptor* BuildFile(const string& file_text) { |
3428 FileDescriptorProto file_proto; | 3274 FileDescriptorProto file_proto; |
3429 EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto)); | 3275 EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto)); |
3430 return GOOGLE_CHECK_NOTNULL(pool_.BuildFile(file_proto)); | 3276 return GOOGLE_CHECK_NOTNULL(pool_.BuildFile(file_proto)); |
(...skipping 1743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5174 "\"foo = { <proto text format> }\". To set fields within it, use " | 5020 "\"foo = { <proto text format> }\". To set fields within it, use " |
5175 "syntax like \"foo.foo = value\".\n"); | 5021 "syntax like \"foo.foo = value\".\n"); |
5176 } | 5022 } |
5177 | 5023 |
5178 TEST_F(ValidationErrorTest, AggregateValueParseError) { | 5024 TEST_F(ValidationErrorTest, AggregateValueParseError) { |
5179 BuildDescriptorMessagesInTestPool(); | 5025 BuildDescriptorMessagesInTestPool(); |
5180 | 5026 |
5181 BuildFileWithErrors( | 5027 BuildFileWithErrors( |
5182 EmbedAggregateValue("aggregate_value: \"1+2\""), | 5028 EmbedAggregateValue("aggregate_value: \"1+2\""), |
5183 "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option " | 5029 "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option " |
5184 "value for \"foo\": Expected identifier, got: 1\n"); | 5030 "value for \"foo\": Expected identifier.\n"); |
5185 } | 5031 } |
5186 | 5032 |
5187 TEST_F(ValidationErrorTest, AggregateValueUnknownFields) { | 5033 TEST_F(ValidationErrorTest, AggregateValueUnknownFields) { |
5188 BuildDescriptorMessagesInTestPool(); | 5034 BuildDescriptorMessagesInTestPool(); |
5189 | 5035 |
5190 BuildFileWithErrors( | 5036 BuildFileWithErrors( |
5191 EmbedAggregateValue("aggregate_value: \"x:100\""), | 5037 EmbedAggregateValue("aggregate_value: \"x:100\""), |
5192 "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option " | 5038 "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option " |
5193 "value for \"foo\": Message type \"Foo\" has no field named \"x\".\n"); | 5039 "value for \"foo\": Message type \"Foo\" has no field named \"x\".\n"); |
5194 } | 5040 } |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5304 // Test that errors are reported to GOOGLE_LOG(ERROR) if no error collector is | 5150 // Test that errors are reported to GOOGLE_LOG(ERROR) if no error collector is |
5305 // provided. | 5151 // provided. |
5306 | 5152 |
5307 FileDescriptorProto file_proto; | 5153 FileDescriptorProto file_proto; |
5308 ASSERT_TRUE(TextFormat::ParseFromString( | 5154 ASSERT_TRUE(TextFormat::ParseFromString( |
5309 "name: \"foo.proto\" " | 5155 "name: \"foo.proto\" " |
5310 "message_type { name: \"Foo\" } " | 5156 "message_type { name: \"Foo\" } " |
5311 "message_type { name: \"Foo\" } ", | 5157 "message_type { name: \"Foo\" } ", |
5312 &file_proto)); | 5158 &file_proto)); |
5313 | 5159 |
5314 std::vector<string> errors; | 5160 vector<string> errors; |
5315 | 5161 |
5316 { | 5162 { |
5317 ScopedMemoryLog log; | 5163 ScopedMemoryLog log; |
5318 EXPECT_TRUE(pool_.BuildFile(file_proto) == NULL); | 5164 EXPECT_TRUE(pool_.BuildFile(file_proto) == NULL); |
5319 errors = log.GetMessages(ERROR); | 5165 errors = log.GetMessages(ERROR); |
5320 } | 5166 } |
5321 | 5167 |
5322 ASSERT_EQ(2, errors.size()); | 5168 ASSERT_EQ(2, errors.size()); |
5323 | 5169 |
5324 EXPECT_EQ("Invalid proto descriptor for file \"foo.proto\":", errors[0]); | 5170 EXPECT_EQ("Invalid proto descriptor for file \"foo.proto\":", errors[0]); |
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5698 "}", | 5544 "}", |
5699 file_proto.mutable_message_type(0)); | 5545 file_proto.mutable_message_type(0)); |
5700 BuildFileWithErrors( | 5546 BuildFileWithErrors( |
5701 file_proto.DebugString(), | 5547 file_proto.DebugString(), |
5702 "foo.proto: Foo.FooMapEntry: NAME: \"FooMapEntry\" is already defined in " | 5548 "foo.proto: Foo.FooMapEntry: NAME: \"FooMapEntry\" is already defined in " |
5703 "\"Foo\".\n" | 5549 "\"Foo\".\n" |
5704 "foo.proto: Foo: NAME: Expanded map entry type FooMapEntry conflicts " | 5550 "foo.proto: Foo: NAME: Expanded map entry type FooMapEntry conflicts " |
5705 "with an existing enum type.\n"); | 5551 "with an existing enum type.\n"); |
5706 } | 5552 } |
5707 | 5553 |
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 | |
5771 TEST_F(ValidationErrorTest, MapEntryConflictsWithOneof) { | 5554 TEST_F(ValidationErrorTest, MapEntryConflictsWithOneof) { |
5772 FileDescriptorProto file_proto; | 5555 FileDescriptorProto file_proto; |
5773 FillValidMapEntry(&file_proto); | 5556 FillValidMapEntry(&file_proto); |
5774 TextFormat::MergeFromString( | 5557 TextFormat::MergeFromString( |
5775 "oneof_decl { " | 5558 "oneof_decl { " |
5776 " name: 'FooMapEntry' " | 5559 " name: 'FooMapEntry' " |
5777 "}" | 5560 "}" |
5778 "field { " | 5561 "field { " |
5779 " name: 'int_field' " | 5562 " name: 'int_field' " |
5780 " type: TYPE_INT32 " | 5563 " type: TYPE_INT32 " |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6044 TEST_F(ValidationErrorTest, ValidateProto3JsonName) { | 5827 TEST_F(ValidationErrorTest, ValidateProto3JsonName) { |
6045 // The comparison is case-insensitive. | 5828 // The comparison is case-insensitive. |
6046 BuildFileWithErrors( | 5829 BuildFileWithErrors( |
6047 "name: 'foo.proto' " | 5830 "name: 'foo.proto' " |
6048 "syntax: 'proto3' " | 5831 "syntax: 'proto3' " |
6049 "message_type {" | 5832 "message_type {" |
6050 " name: 'Foo'" | 5833 " name: 'Foo'" |
6051 " field { name:'name' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 }" | 5834 " field { name:'name' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 }" |
6052 " field { name:'Name' number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }" | 5835 " field { name:'Name' number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }" |
6053 "}", | 5836 "}", |
6054 "foo.proto: Foo: OTHER: The JSON camel-case name of field \"Name\" " | 5837 "foo.proto: Foo: OTHER: The JSON camcel-case name of field \"Name\" " |
6055 "conflicts with field \"name\". This is not allowed in proto3.\n"); | 5838 "conflicts with field \"name\". This is not allowed in proto3.\n"); |
6056 // Underscores are ignored. | 5839 // Underscores are ignored. |
6057 BuildFileWithErrors( | 5840 BuildFileWithErrors( |
6058 "name: 'foo.proto' " | 5841 "name: 'foo.proto' " |
6059 "syntax: 'proto3' " | 5842 "syntax: 'proto3' " |
6060 "message_type {" | 5843 "message_type {" |
6061 " name: 'Foo'" | 5844 " name: 'Foo'" |
6062 " field { name:'ab' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 }" | 5845 " field { name:'ab' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 }" |
6063 " field { name:'_a__b_' number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }" | 5846 " field { name:'_a__b_' number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }" |
6064 "}", | 5847 "}", |
6065 "foo.proto: Foo: OTHER: The JSON camel-case name of field \"_a__b_\" " | 5848 "foo.proto: Foo: OTHER: The JSON camcel-case name of field \"_a__b_\" " |
6066 "conflicts with field \"ab\". This is not allowed in proto3.\n"); | 5849 "conflicts with field \"ab\". This is not allowed in proto3.\n"); |
6067 } | 5850 } |
6068 | 5851 |
6069 // =================================================================== | 5852 // =================================================================== |
6070 // DescriptorDatabase | 5853 // DescriptorDatabase |
6071 | 5854 |
6072 static void AddToDatabase(SimpleDescriptorDatabase* database, | 5855 static void AddToDatabase(SimpleDescriptorDatabase* database, |
6073 const char* file_text) { | 5856 const char* file_text) { |
6074 FileDescriptorProto file_proto; | 5857 FileDescriptorProto file_proto; |
6075 EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto)); | 5858 EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto)); |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6294 } | 6077 } |
6295 | 6078 |
6296 TEST_F(DatabaseBackedPoolTest, FindAllExtensions) { | 6079 TEST_F(DatabaseBackedPoolTest, FindAllExtensions) { |
6297 DescriptorPool pool(&database_); | 6080 DescriptorPool pool(&database_); |
6298 | 6081 |
6299 const Descriptor* foo = pool.FindMessageTypeByName("Foo"); | 6082 const Descriptor* foo = pool.FindMessageTypeByName("Foo"); |
6300 | 6083 |
6301 for (int i = 0; i < 2; ++i) { | 6084 for (int i = 0; i < 2; ++i) { |
6302 // Repeat the lookup twice, to check that we get consistent | 6085 // Repeat the lookup twice, to check that we get consistent |
6303 // results despite the fallback database lookup mutating the pool. | 6086 // results despite the fallback database lookup mutating the pool. |
6304 std::vector<const FieldDescriptor*> extensions; | 6087 vector<const FieldDescriptor*> extensions; |
6305 pool.FindAllExtensions(foo, &extensions); | 6088 pool.FindAllExtensions(foo, &extensions); |
6306 ASSERT_EQ(1, extensions.size()); | 6089 ASSERT_EQ(1, extensions.size()); |
6307 EXPECT_EQ(5, extensions[0]->number()); | 6090 EXPECT_EQ(5, extensions[0]->number()); |
6308 } | 6091 } |
6309 } | 6092 } |
6310 | 6093 |
6311 TEST_F(DatabaseBackedPoolTest, ErrorWithoutErrorCollector) { | 6094 TEST_F(DatabaseBackedPoolTest, ErrorWithoutErrorCollector) { |
6312 ErrorDescriptorDatabase error_database; | 6095 ErrorDescriptorDatabase error_database; |
6313 DescriptorPool pool(&error_database); | 6096 DescriptorPool pool(&error_database); |
6314 | 6097 |
6315 std::vector<string> errors; | 6098 vector<string> errors; |
6316 | 6099 |
6317 { | 6100 { |
6318 ScopedMemoryLog log; | 6101 ScopedMemoryLog log; |
6319 EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL); | 6102 EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL); |
6320 errors = log.GetMessages(ERROR); | 6103 errors = log.GetMessages(ERROR); |
6321 } | 6104 } |
6322 | 6105 |
6323 EXPECT_FALSE(errors.empty()); | 6106 EXPECT_FALSE(errors.empty()); |
6324 } | 6107 } |
6325 | 6108 |
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6821 EXPECT_EQ(0, foo_location.span(1)); // Foo starts at column 0 | 6604 EXPECT_EQ(0, foo_location.span(1)); // Foo starts at column 0 |
6822 EXPECT_EQ(14, foo_location.span(2)); // Foo ends on column 14 | 6605 EXPECT_EQ(14, foo_location.span(2)); // Foo ends on column 14 |
6823 } | 6606 } |
6824 | 6607 |
6825 // =================================================================== | 6608 // =================================================================== |
6826 | 6609 |
6827 | 6610 |
6828 } // namespace descriptor_unittest | 6611 } // namespace descriptor_unittest |
6829 } // namespace protobuf | 6612 } // namespace protobuf |
6830 } // namespace google | 6613 } // namespace google |
OLD | NEW |