| 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 |