~statik/ubuntu/maverick/protobuf/A

« back to all changes in this revision

Viewing changes to src/google/protobuf/descriptor_unittest.cc

  • Committer: Bazaar Package Importer
  • Author(s): Steve Kowalik
  • Date: 2009-11-16 10:41:33 UTC
  • mfrom: (2.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20091116104133-ykhy3deg5l4975tw
Tags: 2.1.0-1ubuntu1
* Merge from Debian testing.
* Remaining Ubuntu changes:
  - Disable the death tests on IA64, now as a quilt patch.
  - Don't use python2.4, also as a quilt patch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
53
53
namespace google {
54
54
namespace protobuf {
55
55
 
56
 
namespace GOOGLE_ANONYMOUS_NAMESPACE{
 
56
// Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
 
57
namespace descriptor_unittest {
57
58
 
58
59
// Some helpers to make assembling descriptors faster.
59
60
DescriptorProto* AddMessage(FileDescriptorProto* file, const string& name) {
345
346
  EXPECT_TRUE(pool_.FindExtensionByNumber(foo_message_, 2) == NULL);
346
347
}
347
348
 
 
349
TEST_F(FileDescriptorTest, BuildAgain) {
 
350
  // Test that if te call BuildFile again on the same input we get the same
 
351
  // FileDescriptor back.
 
352
  FileDescriptorProto file;
 
353
  foo_file_->CopyTo(&file);
 
354
  EXPECT_EQ(foo_file_, pool_.BuildFile(file));
 
355
 
 
356
  // But if we change the file then it won't work.
 
357
  file.set_package("some.other.package");
 
358
  EXPECT_TRUE(pool_.BuildFile(file) == NULL);
 
359
}
 
360
 
348
361
// ===================================================================
349
362
 
350
363
// Test simple flat messages and fields.
631
644
 
632
645
// ===================================================================
633
646
 
 
647
class StylizedFieldNamesTest : public testing::Test {
 
648
 protected:
 
649
  void SetUp() {
 
650
    FileDescriptorProto file;
 
651
    file.set_name("foo.proto");
 
652
 
 
653
    AddExtensionRange(AddMessage(&file, "ExtendableMessage"), 1, 1000);
 
654
 
 
655
    DescriptorProto* message = AddMessage(&file, "TestMessage");
 
656
    AddField(message, "foo_foo", 1,
 
657
             FieldDescriptorProto::LABEL_OPTIONAL,
 
658
             FieldDescriptorProto::TYPE_INT32);
 
659
    AddField(message, "FooBar", 2,
 
660
             FieldDescriptorProto::LABEL_OPTIONAL,
 
661
             FieldDescriptorProto::TYPE_INT32);
 
662
    AddField(message, "fooBaz", 3,
 
663
             FieldDescriptorProto::LABEL_OPTIONAL,
 
664
             FieldDescriptorProto::TYPE_INT32);
 
665
    AddField(message, "fooFoo", 4,  // Camel-case conflict with foo_foo.
 
666
             FieldDescriptorProto::LABEL_OPTIONAL,
 
667
             FieldDescriptorProto::TYPE_INT32);
 
668
    AddField(message, "foobar", 5,  // Lower-case conflict with FooBar.
 
669
             FieldDescriptorProto::LABEL_OPTIONAL,
 
670
             FieldDescriptorProto::TYPE_INT32);
 
671
 
 
672
    AddNestedExtension(message, "ExtendableMessage", "bar_foo", 1,
 
673
                       FieldDescriptorProto::LABEL_OPTIONAL,
 
674
                       FieldDescriptorProto::TYPE_INT32);
 
675
    AddNestedExtension(message, "ExtendableMessage", "BarBar", 2,
 
676
                       FieldDescriptorProto::LABEL_OPTIONAL,
 
677
                       FieldDescriptorProto::TYPE_INT32);
 
678
    AddNestedExtension(message, "ExtendableMessage", "BarBaz", 3,
 
679
                       FieldDescriptorProto::LABEL_OPTIONAL,
 
680
                       FieldDescriptorProto::TYPE_INT32);
 
681
    AddNestedExtension(message, "ExtendableMessage", "barFoo", 4,  // Conflict
 
682
                       FieldDescriptorProto::LABEL_OPTIONAL,
 
683
                       FieldDescriptorProto::TYPE_INT32);
 
684
    AddNestedExtension(message, "ExtendableMessage", "barbar", 5,  // Conflict
 
685
                       FieldDescriptorProto::LABEL_OPTIONAL,
 
686
                       FieldDescriptorProto::TYPE_INT32);
 
687
 
 
688
    AddExtension(&file, "ExtendableMessage", "baz_foo", 11,
 
689
                 FieldDescriptorProto::LABEL_OPTIONAL,
 
690
                 FieldDescriptorProto::TYPE_INT32);
 
691
    AddExtension(&file, "ExtendableMessage", "BazBar", 12,
 
692
                 FieldDescriptorProto::LABEL_OPTIONAL,
 
693
                 FieldDescriptorProto::TYPE_INT32);
 
694
    AddExtension(&file, "ExtendableMessage", "BazBaz", 13,
 
695
                 FieldDescriptorProto::LABEL_OPTIONAL,
 
696
                 FieldDescriptorProto::TYPE_INT32);
 
697
    AddExtension(&file, "ExtendableMessage", "bazFoo", 14,  // Conflict
 
698
                 FieldDescriptorProto::LABEL_OPTIONAL,
 
699
                 FieldDescriptorProto::TYPE_INT32);
 
700
    AddExtension(&file, "ExtendableMessage", "bazbar", 15,  // Conflict
 
701
                 FieldDescriptorProto::LABEL_OPTIONAL,
 
702
                 FieldDescriptorProto::TYPE_INT32);
 
703
 
 
704
    file_ = pool_.BuildFile(file);
 
705
    ASSERT_TRUE(file_ != NULL);
 
706
    ASSERT_EQ(2, file_->message_type_count());
 
707
    message_ = file_->message_type(1);
 
708
    ASSERT_EQ("TestMessage", message_->name());
 
709
    ASSERT_EQ(5, message_->field_count());
 
710
    ASSERT_EQ(5, message_->extension_count());
 
711
    ASSERT_EQ(5, file_->extension_count());
 
712
  }
 
713
 
 
714
  DescriptorPool pool_;
 
715
  const FileDescriptor* file_;
 
716
  const Descriptor* message_;
 
717
};
 
718
 
 
719
TEST_F(StylizedFieldNamesTest, LowercaseName) {
 
720
  EXPECT_EQ("foo_foo", message_->field(0)->lowercase_name());
 
721
  EXPECT_EQ("foobar" , message_->field(1)->lowercase_name());
 
722
  EXPECT_EQ("foobaz" , message_->field(2)->lowercase_name());
 
723
  EXPECT_EQ("foofoo" , message_->field(3)->lowercase_name());
 
724
  EXPECT_EQ("foobar" , message_->field(4)->lowercase_name());
 
725
 
 
726
  EXPECT_EQ("bar_foo", message_->extension(0)->lowercase_name());
 
727
  EXPECT_EQ("barbar" , message_->extension(1)->lowercase_name());
 
728
  EXPECT_EQ("barbaz" , message_->extension(2)->lowercase_name());
 
729
  EXPECT_EQ("barfoo" , message_->extension(3)->lowercase_name());
 
730
  EXPECT_EQ("barbar" , message_->extension(4)->lowercase_name());
 
731
 
 
732
  EXPECT_EQ("baz_foo", file_->extension(0)->lowercase_name());
 
733
  EXPECT_EQ("bazbar" , file_->extension(1)->lowercase_name());
 
734
  EXPECT_EQ("bazbaz" , file_->extension(2)->lowercase_name());
 
735
  EXPECT_EQ("bazfoo" , file_->extension(3)->lowercase_name());
 
736
  EXPECT_EQ("bazbar" , file_->extension(4)->lowercase_name());
 
737
}
 
738
 
 
739
TEST_F(StylizedFieldNamesTest, CamelcaseName) {
 
740
  EXPECT_EQ("fooFoo", message_->field(0)->camelcase_name());
 
741
  EXPECT_EQ("fooBar", message_->field(1)->camelcase_name());
 
742
  EXPECT_EQ("fooBaz", message_->field(2)->camelcase_name());
 
743
  EXPECT_EQ("fooFoo", message_->field(3)->camelcase_name());
 
744
  EXPECT_EQ("foobar", message_->field(4)->camelcase_name());
 
745
 
 
746
  EXPECT_EQ("barFoo", message_->extension(0)->camelcase_name());
 
747
  EXPECT_EQ("barBar", message_->extension(1)->camelcase_name());
 
748
  EXPECT_EQ("barBaz", message_->extension(2)->camelcase_name());
 
749
  EXPECT_EQ("barFoo", message_->extension(3)->camelcase_name());
 
750
  EXPECT_EQ("barbar", message_->extension(4)->camelcase_name());
 
751
 
 
752
  EXPECT_EQ("bazFoo", file_->extension(0)->camelcase_name());
 
753
  EXPECT_EQ("bazBar", file_->extension(1)->camelcase_name());
 
754
  EXPECT_EQ("bazBaz", file_->extension(2)->camelcase_name());
 
755
  EXPECT_EQ("bazFoo", file_->extension(3)->camelcase_name());
 
756
  EXPECT_EQ("bazbar", file_->extension(4)->camelcase_name());
 
757
}
 
758
 
 
759
TEST_F(StylizedFieldNamesTest, FindByLowercaseName) {
 
760
  EXPECT_EQ(message_->field(0),
 
761
            message_->FindFieldByLowercaseName("foo_foo"));
 
762
  EXPECT_EQ(message_->field(1),
 
763
            message_->FindFieldByLowercaseName("foobar"));
 
764
  EXPECT_EQ(message_->field(2),
 
765
            message_->FindFieldByLowercaseName("foobaz"));
 
766
  EXPECT_TRUE(message_->FindFieldByLowercaseName("FooBar") == NULL);
 
767
  EXPECT_TRUE(message_->FindFieldByLowercaseName("fooBaz") == NULL);
 
768
  EXPECT_TRUE(message_->FindFieldByLowercaseName("bar_foo") == NULL);
 
769
  EXPECT_TRUE(message_->FindFieldByLowercaseName("nosuchfield") == NULL);
 
770
 
 
771
  EXPECT_EQ(message_->extension(0),
 
772
            message_->FindExtensionByLowercaseName("bar_foo"));
 
773
  EXPECT_EQ(message_->extension(1),
 
774
            message_->FindExtensionByLowercaseName("barbar"));
 
775
  EXPECT_EQ(message_->extension(2),
 
776
            message_->FindExtensionByLowercaseName("barbaz"));
 
777
  EXPECT_TRUE(message_->FindExtensionByLowercaseName("BarBar") == NULL);
 
778
  EXPECT_TRUE(message_->FindExtensionByLowercaseName("barBaz") == NULL);
 
779
  EXPECT_TRUE(message_->FindExtensionByLowercaseName("foo_foo") == NULL);
 
780
  EXPECT_TRUE(message_->FindExtensionByLowercaseName("nosuchfield") == NULL);
 
781
 
 
782
  EXPECT_EQ(file_->extension(0),
 
783
            file_->FindExtensionByLowercaseName("baz_foo"));
 
784
  EXPECT_EQ(file_->extension(1),
 
785
            file_->FindExtensionByLowercaseName("bazbar"));
 
786
  EXPECT_EQ(file_->extension(2),
 
787
            file_->FindExtensionByLowercaseName("bazbaz"));
 
788
  EXPECT_TRUE(file_->FindExtensionByLowercaseName("BazBar") == NULL);
 
789
  EXPECT_TRUE(file_->FindExtensionByLowercaseName("bazBaz") == NULL);
 
790
  EXPECT_TRUE(file_->FindExtensionByLowercaseName("nosuchfield") == NULL);
 
791
}
 
792
 
 
793
TEST_F(StylizedFieldNamesTest, FindByCamelcaseName) {
 
794
  EXPECT_EQ(message_->field(0),
 
795
            message_->FindFieldByCamelcaseName("fooFoo"));
 
796
  EXPECT_EQ(message_->field(1),
 
797
            message_->FindFieldByCamelcaseName("fooBar"));
 
798
  EXPECT_EQ(message_->field(2),
 
799
            message_->FindFieldByCamelcaseName("fooBaz"));
 
800
  EXPECT_TRUE(message_->FindFieldByCamelcaseName("foo_foo") == NULL);
 
801
  EXPECT_TRUE(message_->FindFieldByCamelcaseName("FooBar") == NULL);
 
802
  EXPECT_TRUE(message_->FindFieldByCamelcaseName("barFoo") == NULL);
 
803
  EXPECT_TRUE(message_->FindFieldByCamelcaseName("nosuchfield") == NULL);
 
804
 
 
805
  EXPECT_EQ(message_->extension(0),
 
806
            message_->FindExtensionByCamelcaseName("barFoo"));
 
807
  EXPECT_EQ(message_->extension(1),
 
808
            message_->FindExtensionByCamelcaseName("barBar"));
 
809
  EXPECT_EQ(message_->extension(2),
 
810
            message_->FindExtensionByCamelcaseName("barBaz"));
 
811
  EXPECT_TRUE(message_->FindExtensionByCamelcaseName("bar_foo") == NULL);
 
812
  EXPECT_TRUE(message_->FindExtensionByCamelcaseName("BarBar") == NULL);
 
813
  EXPECT_TRUE(message_->FindExtensionByCamelcaseName("fooFoo") == NULL);
 
814
  EXPECT_TRUE(message_->FindExtensionByCamelcaseName("nosuchfield") == NULL);
 
815
 
 
816
  EXPECT_EQ(file_->extension(0),
 
817
            file_->FindExtensionByCamelcaseName("bazFoo"));
 
818
  EXPECT_EQ(file_->extension(1),
 
819
            file_->FindExtensionByCamelcaseName("bazBar"));
 
820
  EXPECT_EQ(file_->extension(2),
 
821
            file_->FindExtensionByCamelcaseName("bazBaz"));
 
822
  EXPECT_TRUE(file_->FindExtensionByCamelcaseName("baz_foo") == NULL);
 
823
  EXPECT_TRUE(file_->FindExtensionByCamelcaseName("BazBar") == NULL);
 
824
  EXPECT_TRUE(file_->FindExtensionByCamelcaseName("nosuchfield") == NULL);
 
825
}
 
826
 
 
827
// ===================================================================
 
828
 
634
829
// Test enum descriptors.
635
830
class EnumDescriptorTest : public testing::Test {
636
831
 protected:
1309
1504
  EXPECT_TRUE(foo_->FindExtensionByName("foo_message") == NULL);
1310
1505
}
1311
1506
 
 
1507
TEST_F(ExtensionDescriptorTest, FindAllExtensions) {
 
1508
  vector<const FieldDescriptor*> extensions;
 
1509
  pool_.FindAllExtensions(foo_, &extensions);
 
1510
  ASSERT_EQ(4, extensions.size());
 
1511
  EXPECT_EQ(10, extensions[0]->number());
 
1512
  EXPECT_EQ(19, extensions[1]->number());
 
1513
  EXPECT_EQ(30, extensions[2]->number());
 
1514
  EXPECT_EQ(39, extensions[3]->number());
 
1515
}
 
1516
 
1312
1517
// ===================================================================
1313
1518
 
1314
1519
class MiscTest : public testing::Test {
1533
1738
  EXPECT_EQ(FieldOptions::CORD, bar->options().ctype());
1534
1739
}
1535
1740
 
 
1741
// ===================================================================
 
1742
 
 
1743
class AllowUnknownDependenciesTest : public testing::Test {
 
1744
 protected:
 
1745
  virtual void SetUp() {
 
1746
    FileDescriptorProto foo_proto, bar_proto;
 
1747
 
 
1748
    pool_.AllowUnknownDependencies();
 
1749
 
 
1750
    ASSERT_TRUE(TextFormat::ParseFromString(
 
1751
      "name: 'foo.proto'"
 
1752
      "dependency: 'bar.proto'"
 
1753
      "dependency: 'baz.proto'"
 
1754
      "message_type {"
 
1755
      "  name: 'Foo'"
 
1756
      "  field { name:'bar' number:1 label:LABEL_OPTIONAL type_name:'Bar' }"
 
1757
      "  field { name:'baz' number:2 label:LABEL_OPTIONAL type_name:'Baz' }"
 
1758
      "  field { name:'qux' number:3 label:LABEL_OPTIONAL"
 
1759
      "    type_name: '.corge.Qux'"
 
1760
      "    type: TYPE_ENUM"
 
1761
      "    options {"
 
1762
      "      uninterpreted_option {"
 
1763
      "        name {"
 
1764
      "          name_part: 'grault'"
 
1765
      "          is_extension: true"
 
1766
      "        }"
 
1767
      "        positive_int_value: 1234"
 
1768
      "      }"
 
1769
      "    }"
 
1770
      "  }"
 
1771
      "}",
 
1772
      &foo_proto));
 
1773
    ASSERT_TRUE(TextFormat::ParseFromString(
 
1774
      "name: 'bar.proto'"
 
1775
      "message_type { name: 'Bar' }",
 
1776
      &bar_proto));
 
1777
 
 
1778
    // Collect pointers to stuff.
 
1779
    bar_file_ = pool_.BuildFile(bar_proto);
 
1780
    ASSERT_TRUE(bar_file_ != NULL);
 
1781
 
 
1782
    ASSERT_EQ(1, bar_file_->message_type_count());
 
1783
    bar_type_ = bar_file_->message_type(0);
 
1784
 
 
1785
    foo_file_ = pool_.BuildFile(foo_proto);
 
1786
    ASSERT_TRUE(foo_file_ != NULL);
 
1787
 
 
1788
    ASSERT_EQ(1, foo_file_->message_type_count());
 
1789
    foo_type_ = foo_file_->message_type(0);
 
1790
 
 
1791
    ASSERT_EQ(3, foo_type_->field_count());
 
1792
    bar_field_ = foo_type_->field(0);
 
1793
    baz_field_ = foo_type_->field(1);
 
1794
    qux_field_ = foo_type_->field(2);
 
1795
  }
 
1796
 
 
1797
  const FileDescriptor* bar_file_;
 
1798
  const Descriptor* bar_type_;
 
1799
  const FileDescriptor* foo_file_;
 
1800
  const Descriptor* foo_type_;
 
1801
  const FieldDescriptor* bar_field_;
 
1802
  const FieldDescriptor* baz_field_;
 
1803
  const FieldDescriptor* qux_field_;
 
1804
 
 
1805
  DescriptorPool pool_;
 
1806
};
 
1807
 
 
1808
TEST_F(AllowUnknownDependenciesTest, PlaceholderFile) {
 
1809
  ASSERT_EQ(2, foo_file_->dependency_count());
 
1810
  EXPECT_EQ(bar_file_, foo_file_->dependency(0));
 
1811
 
 
1812
  const FileDescriptor* baz_file = foo_file_->dependency(1);
 
1813
  EXPECT_EQ("baz.proto", baz_file->name());
 
1814
  EXPECT_EQ(0, baz_file->message_type_count());
 
1815
 
 
1816
  // Placeholder files should not be findable.
 
1817
  EXPECT_EQ(bar_file_, pool_.FindFileByName(bar_file_->name()));
 
1818
  EXPECT_TRUE(pool_.FindFileByName(baz_file->name()) == NULL);
 
1819
}
 
1820
 
 
1821
TEST_F(AllowUnknownDependenciesTest, PlaceholderTypes) {
 
1822
  ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, bar_field_->type());
 
1823
  EXPECT_EQ(bar_type_, bar_field_->message_type());
 
1824
 
 
1825
  ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, baz_field_->type());
 
1826
  const Descriptor* baz_type = baz_field_->message_type();
 
1827
  EXPECT_EQ("Baz", baz_type->name());
 
1828
  EXPECT_EQ("Baz", baz_type->full_name());
 
1829
  EXPECT_EQ("Baz.placeholder.proto", baz_type->file()->name());
 
1830
  EXPECT_EQ(0, baz_type->extension_range_count());
 
1831
 
 
1832
  ASSERT_EQ(FieldDescriptor::TYPE_ENUM, qux_field_->type());
 
1833
  const EnumDescriptor* qux_type = qux_field_->enum_type();
 
1834
  EXPECT_EQ("Qux", qux_type->name());
 
1835
  EXPECT_EQ("corge.Qux", qux_type->full_name());
 
1836
  EXPECT_EQ("corge.Qux.placeholder.proto", qux_type->file()->name());
 
1837
 
 
1838
  // Placeholder types should not be findable.
 
1839
  EXPECT_EQ(bar_type_, pool_.FindMessageTypeByName(bar_type_->full_name()));
 
1840
  EXPECT_TRUE(pool_.FindMessageTypeByName(baz_type->full_name()) == NULL);
 
1841
  EXPECT_TRUE(pool_.FindEnumTypeByName(qux_type->full_name()) == NULL);
 
1842
}
 
1843
 
 
1844
TEST_F(AllowUnknownDependenciesTest, CopyTo) {
 
1845
  // FieldDescriptor::CopyTo() should write non-fully-qualified type names
 
1846
  // for placeholder types which were not originally fully-qualified.
 
1847
  FieldDescriptorProto proto;
 
1848
 
 
1849
  // Bar is not a placeholder, so it is fully-qualified.
 
1850
  bar_field_->CopyTo(&proto);
 
1851
  EXPECT_EQ(".Bar", proto.type_name());
 
1852
  EXPECT_EQ(FieldDescriptorProto::TYPE_MESSAGE, proto.type());
 
1853
 
 
1854
  // Baz is an unqualified placeholder.
 
1855
  proto.Clear();
 
1856
  baz_field_->CopyTo(&proto);
 
1857
  EXPECT_EQ("Baz", proto.type_name());
 
1858
  EXPECT_FALSE(proto.has_type());
 
1859
 
 
1860
  // Qux is a fully-qualified placeholder.
 
1861
  proto.Clear();
 
1862
  qux_field_->CopyTo(&proto);
 
1863
  EXPECT_EQ(".corge.Qux", proto.type_name());
 
1864
  EXPECT_EQ(FieldDescriptorProto::TYPE_ENUM, proto.type());
 
1865
}
 
1866
 
 
1867
TEST_F(AllowUnknownDependenciesTest, CustomOptions) {
 
1868
  // Qux should still have the uninterpreted option attached.
 
1869
  ASSERT_EQ(1, qux_field_->options().uninterpreted_option_size());
 
1870
  const UninterpretedOption& option =
 
1871
    qux_field_->options().uninterpreted_option(0);
 
1872
  ASSERT_EQ(1, option.name_size());
 
1873
  EXPECT_EQ("grault", option.name(0).name_part());
 
1874
}
 
1875
 
 
1876
TEST_F(AllowUnknownDependenciesTest, UnknownExtendee) {
 
1877
  // Test that we can extend an unknown type.  This is slightly tricky because
 
1878
  // it means that the placeholder type must have an extension range.
 
1879
 
 
1880
  FileDescriptorProto extension_proto;
 
1881
 
 
1882
  ASSERT_TRUE(TextFormat::ParseFromString(
 
1883
    "name: 'extension.proto'"
 
1884
    "extension { extendee: 'UnknownType' name:'some_extension' number:123"
 
1885
    "            label:LABEL_OPTIONAL type:TYPE_INT32 }",
 
1886
    &extension_proto));
 
1887
  const FileDescriptor* file = pool_.BuildFile(extension_proto);
 
1888
 
 
1889
  ASSERT_TRUE(file != NULL);
 
1890
 
 
1891
  ASSERT_EQ(1, file->extension_count());
 
1892
  const Descriptor* extendee = file->extension(0)->containing_type();
 
1893
  EXPECT_EQ("UnknownType", extendee->name());
 
1894
  ASSERT_EQ(1, extendee->extension_range_count());
 
1895
  EXPECT_EQ(1, extendee->extension_range(0)->start);
 
1896
  EXPECT_EQ(FieldDescriptor::kMaxNumber + 1, extendee->extension_range(0)->end);
 
1897
}
 
1898
 
 
1899
TEST_F(AllowUnknownDependenciesTest, CustomOption) {
 
1900
  // Test that we can use a custom option without having parsed
 
1901
  // descriptor.proto.
 
1902
 
 
1903
  FileDescriptorProto option_proto;
 
1904
 
 
1905
  ASSERT_TRUE(TextFormat::ParseFromString(
 
1906
    "name: \"unknown_custom_options.proto\" "
 
1907
    "dependency: \"google/protobuf/descriptor.proto\" "
 
1908
    "extension { "
 
1909
    "  extendee: \"google.protobuf.FileOptions\" "
 
1910
    "  name: \"some_option\" "
 
1911
    "  number: 123456 "
 
1912
    "  label: LABEL_OPTIONAL "
 
1913
    "  type: TYPE_INT32 "
 
1914
    "} "
 
1915
    "options { "
 
1916
    "  uninterpreted_option { "
 
1917
    "    name { "
 
1918
    "      name_part: \"some_option\" "
 
1919
    "      is_extension: true "
 
1920
    "    } "
 
1921
    "    positive_int_value: 1234 "
 
1922
    "  } "
 
1923
    "  uninterpreted_option { "
 
1924
    "    name { "
 
1925
    "      name_part: \"unknown_option\" "
 
1926
    "      is_extension: true "
 
1927
    "    } "
 
1928
    "    positive_int_value: 1234 "
 
1929
    "  } "
 
1930
    "  uninterpreted_option { "
 
1931
    "    name { "
 
1932
    "      name_part: \"optimize_for\" "
 
1933
    "      is_extension: false "
 
1934
    "    } "
 
1935
    "    identifier_value: \"SPEED\" "
 
1936
    "  } "
 
1937
    "}",
 
1938
    &option_proto));
 
1939
 
 
1940
  const FileDescriptor* file = pool_.BuildFile(option_proto);
 
1941
  ASSERT_TRUE(file != NULL);
 
1942
 
 
1943
  // Verify that no extension options were set, but they were left as
 
1944
  // uninterpreted_options.
 
1945
  vector<const FieldDescriptor*> fields;
 
1946
  file->options().GetReflection()->ListFields(file->options(), &fields);
 
1947
  ASSERT_EQ(2, fields.size());
 
1948
  EXPECT_TRUE(file->options().has_optimize_for());
 
1949
  EXPECT_EQ(2, file->options().uninterpreted_option_size());
 
1950
}
 
1951
 
 
1952
// ===================================================================
 
1953
 
1536
1954
TEST(CustomOptions, OptionLocations) {
1537
1955
  const Descriptor* message =
1538
1956
      protobuf_unittest::TestMessageWithCustomOptions::descriptor();
1925
2343
  //   defined.
1926
2344
  BuildFileWithErrors(
1927
2345
    "name: \"foo.proto\" "
1928
 
    "message_type { name: \"Foo\" }",
 
2346
    "message_type { name: \"Foo\" } "
 
2347
    // Add another type so that the files aren't identical (in which case there
 
2348
    // would be no error).
 
2349
    "enum_type { name: \"Bar\" }",
1929
2350
 
1930
2351
    "foo.proto: foo.proto: OTHER: A file with this name is already in the "
1931
2352
      "pool.\n");
1991
2412
    // we look up the type name.
1992
2413
    "  field { name: \"quux\" number: 5 label: LABEL_OPTIONAL"
1993
2414
    "          default_value: \"abc\" type_name: \"Foo\" }"
 
2415
 
 
2416
    // Repeateds can't have defaults.
 
2417
    "  field { name: \"corge\" number: 6 label: LABEL_REPEATED type: TYPE_INT32"
 
2418
    "          default_value: \"1\" }"
1994
2419
    "}",
1995
2420
 
1996
2421
    "foo.proto: Foo.foo: DEFAULT_VALUE: Couldn't parse default value.\n"
1998
2423
    "foo.proto: Foo.baz: DEFAULT_VALUE: Boolean default must be true or "
1999
2424
      "false.\n"
2000
2425
    "foo.proto: Foo.qux: DEFAULT_VALUE: Messages can't have default values.\n"
 
2426
    "foo.proto: Foo.corge: DEFAULT_VALUE: Repeated fields can't have default "
 
2427
      "values.\n"
 
2428
    // This ends up being reported later because the error is detected at
 
2429
    // cross-linking time.
2001
2430
    "foo.proto: Foo.quux: DEFAULT_VALUE: Messages can't have default "
2002
2431
      "values.\n");
2003
2432
}
2290
2719
    "foo.proto: Foo.baz: TYPE: \"Bar.Baz\" is not defined.\n");
2291
2720
}
2292
2721
 
 
2722
TEST_F(ValidationErrorTest, SearchMostLocalFirst2) {
 
2723
  // This test would find the most local "Bar" first, and does, but
 
2724
  // proceeds to find the outer one because the inner one's not an
 
2725
  // aggregate.
 
2726
  BuildFile(
 
2727
    "name: \"foo.proto\" "
 
2728
    "message_type {"
 
2729
    "  name: \"Bar\""
 
2730
    "  nested_type { name: \"Baz\" }"
 
2731
    "}"
 
2732
    "message_type {"
 
2733
    "  name: \"Foo\""
 
2734
    "  field { name: \"Bar\" number:1 type:TYPE_BYTES } "
 
2735
    "  field { name:\"baz\" number:2 label:LABEL_OPTIONAL"
 
2736
    "          type_name:\"Bar.Baz\" }"
 
2737
    "}");
 
2738
}
 
2739
 
2293
2740
TEST_F(ValidationErrorTest, PackageOriginallyDeclaredInTransitiveDependent) {
2294
2741
  // Imagine we have the following:
2295
2742
  //
2336
2783
    "name: \"foo.proto\" "
2337
2784
    "message_type {"
2338
2785
    "  name: \"Foo\""
2339
 
    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"bar\" }"
 
2786
    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL "
 
2787
    "          type_name:\".Foo.bar\" }"
2340
2788
    "  field { name:\"bar\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
2341
2789
    "}",
2342
2790
 
2343
 
    "foo.proto: Foo.foo: TYPE: \"bar\" is not a type.\n");
 
2791
    "foo.proto: Foo.foo: TYPE: \".Foo.bar\" is not a type.\n");
 
2792
}
 
2793
 
 
2794
TEST_F(ValidationErrorTest, RelativeFieldTypeNotAType) {
 
2795
  BuildFileWithErrors(
 
2796
    "name: \"foo.proto\" "
 
2797
    "message_type {"
 
2798
    "  nested_type {"
 
2799
    "    name: \"Bar\""
 
2800
    "    field { name:\"Baz\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
 
2801
    "  }"
 
2802
    "  name: \"Foo\""
 
2803
    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL "
 
2804
    "          type_name:\"Bar.Baz\" }"
 
2805
    "}",
 
2806
    "foo.proto: Foo.foo: TYPE: \"Bar.Baz\" is not a type.\n");
 
2807
}
 
2808
 
 
2809
TEST_F(ValidationErrorTest, FieldTypeMayBeItsName) {
 
2810
  BuildFile(
 
2811
    "name: \"foo.proto\" "
 
2812
    "message_type {"
 
2813
    "  name: \"Bar\""
 
2814
    "}"
 
2815
    "message_type {"
 
2816
    "  name: \"Foo\""
 
2817
    "  field { name:\"Bar\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
 
2818
    "}");
2344
2819
}
2345
2820
 
2346
2821
TEST_F(ValidationErrorTest, EnumFieldTypeIsMessage) {
2457
2932
    "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not a message type.\n");
2458
2933
}
2459
2934
 
 
2935
TEST_F(ValidationErrorTest, IllegalPackedField) {
 
2936
  BuildFileWithErrors(
 
2937
    "name: \"foo.proto\" "
 
2938
    "message_type {\n"
 
2939
    "  name: \"Foo\""
 
2940
    "  field { name:\"packed_string\" number:1 label:LABEL_REPEATED "
 
2941
    "          type:TYPE_STRING "
 
2942
    "          options { uninterpreted_option {"
 
2943
    "            name { name_part: \"packed\" is_extension: false }"
 
2944
    "            identifier_value: \"true\" }}}\n"
 
2945
    "  field { name:\"packed_message\" number:3 label:LABEL_REPEATED "
 
2946
    "          type_name: \"Foo\""
 
2947
    "          options { uninterpreted_option {"
 
2948
    "            name { name_part: \"packed\" is_extension: false }"
 
2949
    "            identifier_value: \"true\" }}}\n"
 
2950
    "  field { name:\"optional_int32\" number: 4 label: LABEL_OPTIONAL "
 
2951
    "          type:TYPE_INT32 "
 
2952
    "          options { uninterpreted_option {"
 
2953
    "            name { name_part: \"packed\" is_extension: false }"
 
2954
    "            identifier_value: \"true\" }}}\n"
 
2955
    "}",
 
2956
 
 
2957
    "foo.proto: Foo.packed_string: TYPE: [packed = true] can only be "
 
2958
        "specified for repeated primitive fields.\n"
 
2959
    "foo.proto: Foo.packed_message: TYPE: [packed = true] can only be "
 
2960
        "specified for repeated primitive fields.\n"
 
2961
    "foo.proto: Foo.optional_int32: TYPE: [packed = true] can only be "
 
2962
        "specified for repeated primitive fields.\n"
 
2963
        );
 
2964
}
2460
2965
 
2461
2966
TEST_F(ValidationErrorTest, OptionWrongType) {
2462
2967
  BuildFileWithErrors(
3133
3638
  EXPECT_TRUE(pool.FindExtensionByNumber(foo, 12) == NULL);
3134
3639
}
3135
3640
 
 
3641
TEST_F(DatabaseBackedPoolTest, FindAllExtensions) {
 
3642
  DescriptorPool pool(&database_);
 
3643
 
 
3644
  const Descriptor* foo = pool.FindMessageTypeByName("Foo");
 
3645
 
 
3646
  for (int i = 0; i < 2; ++i) {
 
3647
    // Repeat the lookup twice, to check that we get consistent
 
3648
    // results despite the fallback database lookup mutating the pool.
 
3649
    vector<const FieldDescriptor*> extensions;
 
3650
    pool.FindAllExtensions(foo, &extensions);
 
3651
    ASSERT_EQ(1, extensions.size());
 
3652
    EXPECT_EQ(5, extensions[0]->number());
 
3653
  }
 
3654
}
 
3655
 
3136
3656
TEST_F(DatabaseBackedPoolTest, ErrorWithoutErrorCollector) {
3137
3657
  ErrorDescriptorDatabase error_database;
3138
3658
  DescriptorPool pool(&error_database);
3255
3775
  EXPECT_EQ("", error_collector.text_);
3256
3776
}
3257
3777
 
3258
 
}  // anonymous namespace
 
3778
TEST_F(DatabaseBackedPoolTest, DoesntFallbackOnWrongType) {
 
3779
  // If a lookup finds a symbol of the wrong type (e.g. we pass a type name
 
3780
  // to FindFieldByName()), we should fail fast, without checking the fallback
 
3781
  // database.
 
3782
  CallCountingDatabase call_counter(&database_);
 
3783
  DescriptorPool pool(&call_counter);
 
3784
 
 
3785
  const FileDescriptor* file = pool.FindFileByName("foo.proto");
 
3786
  ASSERT_TRUE(file != NULL);
 
3787
  const Descriptor* foo = pool.FindMessageTypeByName("Foo");
 
3788
  ASSERT_TRUE(foo != NULL);
 
3789
  const EnumDescriptor* test_enum = pool.FindEnumTypeByName("TestEnum");
 
3790
  ASSERT_TRUE(test_enum != NULL);
 
3791
 
 
3792
  EXPECT_NE(0, call_counter.call_count_);
 
3793
  call_counter.Clear();
 
3794
 
 
3795
  EXPECT_TRUE(pool.FindMessageTypeByName("TestEnum") == NULL);
 
3796
  EXPECT_TRUE(pool.FindFieldByName("Foo") == NULL);
 
3797
  EXPECT_TRUE(pool.FindExtensionByName("Foo") == NULL);
 
3798
  EXPECT_TRUE(pool.FindEnumTypeByName("Foo") == NULL);
 
3799
  EXPECT_TRUE(pool.FindEnumValueByName("Foo") == NULL);
 
3800
  EXPECT_TRUE(pool.FindServiceByName("Foo") == NULL);
 
3801
  EXPECT_TRUE(pool.FindMethodByName("Foo") == NULL);
 
3802
 
 
3803
  EXPECT_EQ(0, call_counter.call_count_);
 
3804
}
 
3805
 
 
3806
}  // namespace descriptor_unittest
3259
3807
}  // namespace protobuf
3260
3808
}  // namespace google