~ubuntu-branches/debian/squeeze/protobuf/squeeze

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Julien Cristau
  • Date: 2009-06-02 16:19:00 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20090602161900-vm176i3ryt35yk91
Tags: 2.0.3-2.2
* Non-maintainer upload.
* Fix FTBFS from -2.1: don't fail when we can't clean up the java build,
  such as when openjdk isn't installed.
* Disable parallel builds, because libtool is made of fail (if binary-arch
  and build-indep run concurrently, we relink a library while it's being
  used; that doesn't work so well).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
// Protocol Buffers - Google's data interchange format
2
 
// Copyright 2008 Google Inc.
 
2
// Copyright 2008 Google Inc.  All rights reserved.
3
3
// http://code.google.com/p/protobuf/
4
4
//
5
 
// Licensed under the Apache License, Version 2.0 (the "License");
6
 
// you may not use this file except in compliance with the License.
7
 
// You may obtain a copy of the License at
8
 
//
9
 
//      http://www.apache.org/licenses/LICENSE-2.0
10
 
//
11
 
// Unless required by applicable law or agreed to in writing, software
12
 
// distributed under the License is distributed on an "AS IS" BASIS,
13
 
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 
// See the License for the specific language governing permissions and
15
 
// limitations under the License.
 
5
// Redistribution and use in source and binary forms, with or without
 
6
// modification, are permitted provided that the following conditions are
 
7
// met:
 
8
//
 
9
//     * Redistributions of source code must retain the above copyright
 
10
// notice, this list of conditions and the following disclaimer.
 
11
//     * Redistributions in binary form must reproduce the above
 
12
// copyright notice, this list of conditions and the following disclaimer
 
13
// in the documentation and/or other materials provided with the
 
14
// distribution.
 
15
//     * Neither the name of Google Inc. nor the names of its
 
16
// contributors may be used to endorse or promote products derived from
 
17
// this software without specific prior written permission.
 
18
//
 
19
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
20
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
21
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
22
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 
23
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
24
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
25
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
26
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
27
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
28
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
29
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16
30
 
17
31
// Author: kenton@google.com (Kenton Varda)
18
32
//  Based on original Protocol Buffers design by
24
38
 
25
39
#include <google/protobuf/descriptor.h>
26
40
#include <google/protobuf/descriptor_database.h>
 
41
#include <google/protobuf/dynamic_message.h>
27
42
#include <google/protobuf/descriptor.pb.h>
28
43
#include <google/protobuf/text_format.h>
29
44
#include <google/protobuf/unittest.pb.h>
 
45
#include <google/protobuf/unittest_custom_options.pb.h>
30
46
#include <google/protobuf/stubs/strutil.h>
31
47
#include <google/protobuf/stubs/substitute.h>
32
48
 
37
53
namespace google {
38
54
namespace protobuf {
39
55
 
40
 
namespace {
 
56
namespace GOOGLE_ANONYMOUS_NAMESPACE{
41
57
 
42
58
// Some helpers to make assembling descriptors faster.
43
59
DescriptorProto* AddMessage(FileDescriptorProto* file, const string& name) {
1307
1323
    DescriptorProto* message = AddMessage(&file_proto, "TestMessage");
1308
1324
    FieldDescriptorProto* field =
1309
1325
      AddField(message, "foo", 1, FieldDescriptorProto::LABEL_OPTIONAL,
1310
 
               static_cast<FieldDescriptorProto::Type>(type));
 
1326
               static_cast<FieldDescriptorProto::Type>(static_cast<int>(type)));
1311
1327
 
1312
1328
    if (type == FieldDescriptor::TYPE_MESSAGE ||
1313
1329
        type == FieldDescriptor::TYPE_GROUP) {
1517
1533
  EXPECT_EQ(FieldOptions::CORD, bar->options().ctype());
1518
1534
}
1519
1535
 
 
1536
TEST(CustomOptions, OptionLocations) {
 
1537
  const Descriptor* message =
 
1538
      protobuf_unittest::TestMessageWithCustomOptions::descriptor();
 
1539
  const FileDescriptor* file = message->file();
 
1540
  const FieldDescriptor* field = message->FindFieldByName("field1");
 
1541
  const EnumDescriptor* enm = message->FindEnumTypeByName("AnEnum");
 
1542
  // TODO(benjy): Support EnumValue options, once the compiler does.
 
1543
  const ServiceDescriptor* service =
 
1544
      file->FindServiceByName("TestServiceWithCustomOptions");
 
1545
  const MethodDescriptor* method = service->FindMethodByName("Foo");
 
1546
 
 
1547
  EXPECT_EQ(GOOGLE_LONGLONG(9876543210),
 
1548
            file->options().GetExtension(protobuf_unittest::file_opt1));
 
1549
  EXPECT_EQ(-56,
 
1550
            message->options().GetExtension(protobuf_unittest::message_opt1));
 
1551
  EXPECT_EQ(GOOGLE_LONGLONG(8765432109),
 
1552
            field->options().GetExtension(protobuf_unittest::field_opt1));
 
1553
  EXPECT_EQ(42,  // Check that we get the default for an option we don't set.
 
1554
            field->options().GetExtension(protobuf_unittest::field_opt2));
 
1555
  EXPECT_EQ(-789,
 
1556
            enm->options().GetExtension(protobuf_unittest::enum_opt1));
 
1557
  EXPECT_EQ(123,
 
1558
            enm->value(1)->options().GetExtension(
 
1559
              protobuf_unittest::enum_value_opt1));
 
1560
  EXPECT_EQ(GOOGLE_LONGLONG(-9876543210),
 
1561
            service->options().GetExtension(protobuf_unittest::service_opt1));
 
1562
  EXPECT_EQ(protobuf_unittest::METHODOPT1_VAL2,
 
1563
            method->options().GetExtension(protobuf_unittest::method_opt1));
 
1564
 
 
1565
  // See that the regular options went through unscathed.
 
1566
  EXPECT_TRUE(message->options().has_message_set_wire_format());
 
1567
  EXPECT_EQ(FieldOptions::CORD, field->options().ctype());
 
1568
}
 
1569
 
 
1570
TEST(CustomOptions, OptionTypes) {
 
1571
  const MessageOptions* options = NULL;
 
1572
 
 
1573
  options =
 
1574
      &protobuf_unittest::CustomOptionMinIntegerValues::descriptor()->options();
 
1575
  EXPECT_EQ(false    , options->GetExtension(protobuf_unittest::bool_opt));
 
1576
  EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::int32_opt));
 
1577
  EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::int64_opt));
 
1578
  EXPECT_EQ(0        , options->GetExtension(protobuf_unittest::uint32_opt));
 
1579
  EXPECT_EQ(0        , options->GetExtension(protobuf_unittest::uint64_opt));
 
1580
  EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::sint32_opt));
 
1581
  EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::sint64_opt));
 
1582
  EXPECT_EQ(0        , options->GetExtension(protobuf_unittest::fixed32_opt));
 
1583
  EXPECT_EQ(0        , options->GetExtension(protobuf_unittest::fixed64_opt));
 
1584
  EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::sfixed32_opt));
 
1585
  EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::sfixed64_opt));
 
1586
 
 
1587
  options =
 
1588
      &protobuf_unittest::CustomOptionMaxIntegerValues::descriptor()->options();
 
1589
  EXPECT_EQ(true      , options->GetExtension(protobuf_unittest::bool_opt));
 
1590
  EXPECT_EQ(kint32max , options->GetExtension(protobuf_unittest::int32_opt));
 
1591
  EXPECT_EQ(kint64max , options->GetExtension(protobuf_unittest::int64_opt));
 
1592
  EXPECT_EQ(kuint32max, options->GetExtension(protobuf_unittest::uint32_opt));
 
1593
  EXPECT_EQ(kuint64max, options->GetExtension(protobuf_unittest::uint64_opt));
 
1594
  EXPECT_EQ(kint32max , options->GetExtension(protobuf_unittest::sint32_opt));
 
1595
  EXPECT_EQ(kint64max , options->GetExtension(protobuf_unittest::sint64_opt));
 
1596
  EXPECT_EQ(kuint32max, options->GetExtension(protobuf_unittest::fixed32_opt));
 
1597
  EXPECT_EQ(kuint64max, options->GetExtension(protobuf_unittest::fixed64_opt));
 
1598
  EXPECT_EQ(kint32max , options->GetExtension(protobuf_unittest::sfixed32_opt));
 
1599
  EXPECT_EQ(kint64max , options->GetExtension(protobuf_unittest::sfixed64_opt));
 
1600
 
 
1601
  options =
 
1602
      &protobuf_unittest::CustomOptionOtherValues::descriptor()->options();
 
1603
  EXPECT_EQ(-100, options->GetExtension(protobuf_unittest::int32_opt));
 
1604
  EXPECT_FLOAT_EQ(12.3456789,
 
1605
                  options->GetExtension(protobuf_unittest::float_opt));
 
1606
  EXPECT_DOUBLE_EQ(1.234567890123456789,
 
1607
                   options->GetExtension(protobuf_unittest::double_opt));
 
1608
  EXPECT_EQ("Hello, \"World\"",
 
1609
            options->GetExtension(protobuf_unittest::string_opt));
 
1610
 
 
1611
  EXPECT_EQ(string("Hello\0World", 11),
 
1612
            options->GetExtension(protobuf_unittest::bytes_opt));
 
1613
 
 
1614
  EXPECT_EQ(protobuf_unittest::DummyMessageContainingEnum::TEST_OPTION_ENUM_TYPE2,
 
1615
            options->GetExtension(protobuf_unittest::enum_opt));
 
1616
 
 
1617
  options =
 
1618
      &protobuf_unittest::SettingRealsFromPositiveInts::descriptor()->options();
 
1619
  EXPECT_FLOAT_EQ(12, options->GetExtension(protobuf_unittest::float_opt));
 
1620
  EXPECT_DOUBLE_EQ(154, options->GetExtension(protobuf_unittest::double_opt));
 
1621
 
 
1622
  options =
 
1623
      &protobuf_unittest::SettingRealsFromNegativeInts::descriptor()->options();
 
1624
  EXPECT_FLOAT_EQ(-12, options->GetExtension(protobuf_unittest::float_opt));
 
1625
  EXPECT_DOUBLE_EQ(-154, options->GetExtension(protobuf_unittest::double_opt));
 
1626
}
 
1627
 
 
1628
TEST(CustomOptions, ComplexExtensionOptions) {
 
1629
  const MessageOptions* options =
 
1630
      &protobuf_unittest::VariousComplexOptions::descriptor()->options();
 
1631
  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1).foo(), 42);
 
1632
  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1).
 
1633
            GetExtension(protobuf_unittest::quux), 324);
 
1634
  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1).
 
1635
            GetExtension(protobuf_unittest::corge).qux(), 876);
 
1636
  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).baz(), 987);
 
1637
  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
 
1638
            GetExtension(protobuf_unittest::grault), 654);
 
1639
  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).bar().foo(),
 
1640
            743);
 
1641
  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).bar().
 
1642
            GetExtension(protobuf_unittest::quux), 1999);
 
1643
  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).bar().
 
1644
            GetExtension(protobuf_unittest::corge).qux(), 2008);
 
1645
  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
 
1646
            GetExtension(protobuf_unittest::garply).foo(), 741);
 
1647
  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
 
1648
            GetExtension(protobuf_unittest::garply).
 
1649
            GetExtension(protobuf_unittest::quux), 1998);
 
1650
  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
 
1651
            GetExtension(protobuf_unittest::garply).
 
1652
            GetExtension(protobuf_unittest::corge).qux(), 2121);
 
1653
  EXPECT_EQ(options->GetExtension(
 
1654
      protobuf_unittest::ComplexOptionType2::ComplexOptionType4::complex_opt4).
 
1655
            waldo(), 1971);
 
1656
  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
 
1657
            fred().waldo(), 321);
 
1658
  EXPECT_EQ(9, options->GetExtension(protobuf_unittest::complex_opt3).qux());
 
1659
  EXPECT_EQ(22, options->GetExtension(protobuf_unittest::complex_opt3).
 
1660
                complexoptiontype5().plugh());
 
1661
  EXPECT_EQ(24, options->GetExtension(protobuf_unittest::complexopt6).xyzzy());
 
1662
}
 
1663
 
 
1664
TEST(CustomOptions, OptionsFromOtherFile) {
 
1665
  // Test that to use a custom option, we only need to import the file
 
1666
  // defining the option; we do not also have to import descriptor.proto.
 
1667
  DescriptorPool pool;
 
1668
 
 
1669
  FileDescriptorProto file_proto;
 
1670
  FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
 
1671
  ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
 
1672
 
 
1673
  protobuf_unittest::TestMessageWithCustomOptions::descriptor()
 
1674
    ->file()->CopyTo(&file_proto);
 
1675
  ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
 
1676
 
 
1677
  ASSERT_TRUE(TextFormat::ParseFromString(
 
1678
    "name: \"custom_options_import.proto\" "
 
1679
    "package: \"protobuf_unittest\" "
 
1680
    "dependency: \"google/protobuf/unittest_custom_options.proto\" "
 
1681
    "options { "
 
1682
    "  uninterpreted_option { "
 
1683
    "    name { "
 
1684
    "      name_part: \"file_opt1\" "
 
1685
    "      is_extension: true "
 
1686
    "    } "
 
1687
    "    positive_int_value: 1234 "
 
1688
    "  } "
 
1689
    // Test a non-extension option too.  (At one point this failed due to a
 
1690
    // bug.)
 
1691
    "  uninterpreted_option { "
 
1692
    "    name { "
 
1693
    "      name_part: \"java_package\" "
 
1694
    "      is_extension: false "
 
1695
    "    } "
 
1696
    "    string_value: \"foo\" "
 
1697
    "  } "
 
1698
    // Test that enum-typed options still work too.  (At one point this also
 
1699
    // failed due to a bug.)
 
1700
    "  uninterpreted_option { "
 
1701
    "    name { "
 
1702
    "      name_part: \"optimize_for\" "
 
1703
    "      is_extension: false "
 
1704
    "    } "
 
1705
    "    identifier_value: \"SPEED\" "
 
1706
    "  } "
 
1707
    "}"
 
1708
    ,
 
1709
    &file_proto));
 
1710
 
 
1711
  const FileDescriptor* file = pool.BuildFile(file_proto);
 
1712
  ASSERT_TRUE(file != NULL);
 
1713
  EXPECT_EQ(1234, file->options().GetExtension(protobuf_unittest::file_opt1));
 
1714
  EXPECT_TRUE(file->options().has_java_package());
 
1715
  EXPECT_EQ("foo", file->options().java_package());
 
1716
  EXPECT_TRUE(file->options().has_optimize_for());
 
1717
  EXPECT_EQ(FileOptions::SPEED, file->options().optimize_for());
 
1718
}
 
1719
 
 
1720
 
1520
1721
// ===================================================================
1521
1722
 
1522
1723
// The tests below trigger every unique call to AddError() in descriptor.cc,
1542
1743
      case TYPE         : location_name = "TYPE"         ; break;
1543
1744
      case EXTENDEE     : location_name = "EXTENDEE"     ; break;
1544
1745
      case DEFAULT_VALUE: location_name = "DEFAULT_VALUE"; break;
 
1746
      case OPTION_NAME  : location_name = "OPTION_NAME"  ; break;
 
1747
      case OPTION_VALUE : location_name = "OPTION_VALUE" ; break;
1545
1748
      case INPUT_TYPE   : location_name = "INPUT_TYPE"   ; break;
1546
1749
      case OUTPUT_TYPE  : location_name = "OUTPUT_TYPE"  ; break;
1547
1750
      case OTHER        : location_name = "OTHER"        ; break;
1577
1780
    EXPECT_EQ(expected_errors, error_collector.text_);
1578
1781
  }
1579
1782
 
 
1783
  // Builds some already-parsed file in our test pool.
 
1784
  void BuildFileInTestPool(const FileDescriptor* file) {
 
1785
    FileDescriptorProto file_proto;
 
1786
    file->CopyTo(&file_proto);
 
1787
    ASSERT_TRUE(pool_.BuildFile(file_proto) != NULL);
 
1788
  }
 
1789
 
 
1790
  // Build descriptor.proto in our test pool. This allows us to extend it in
 
1791
  // the test pool, so we can test custom options.
 
1792
  void BuildDescriptorMessagesInTestPool() {
 
1793
    BuildFileInTestPool(DescriptorProto::descriptor()->file());
 
1794
  }
 
1795
 
1580
1796
  DescriptorPool pool_;
1581
1797
};
1582
1798
 
1625
1841
      "than a package) in file \"foo.proto\".\n");
1626
1842
}
1627
1843
 
 
1844
TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParent) {
 
1845
  BuildFileWithErrors(
 
1846
    "name: \"foo.proto\" "
 
1847
    "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } "
 
1848
    "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ",
 
1849
 
 
1850
    "foo.proto: FOO: NAME: \"FOO\" is already defined.\n"
 
1851
    "foo.proto: FOO: NAME: Note that enum values use C++ scoping rules, "
 
1852
      "meaning that enum values are siblings of their type, not children of "
 
1853
      "it.  Therefore, \"FOO\" must be unique within the global scope, not "
 
1854
      "just within \"Bar\".\n");
 
1855
}
 
1856
 
 
1857
TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParentNonGlobal) {
 
1858
  BuildFileWithErrors(
 
1859
    "name: \"foo.proto\" "
 
1860
    "package: \"pkg\" "
 
1861
    "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } "
 
1862
    "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ",
 
1863
 
 
1864
    "foo.proto: pkg.FOO: NAME: \"FOO\" is already defined in \"pkg\".\n"
 
1865
    "foo.proto: pkg.FOO: NAME: Note that enum values use C++ scoping rules, "
 
1866
      "meaning that enum values are siblings of their type, not children of "
 
1867
      "it.  Therefore, \"FOO\" must be unique within \"pkg\", not just within "
 
1868
      "\"Bar\".\n");
 
1869
}
 
1870
 
1628
1871
TEST_F(ValidationErrorTest, MissingName) {
1629
1872
  BuildFileWithErrors(
1630
1873
    "name: \"foo.proto\" "
2214
2457
    "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not a message type.\n");
2215
2458
}
2216
2459
 
 
2460
 
 
2461
TEST_F(ValidationErrorTest, OptionWrongType) {
 
2462
  BuildFileWithErrors(
 
2463
    "name: \"foo.proto\" "
 
2464
    "message_type { "
 
2465
    "  name: \"TestMessage\" "
 
2466
    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING "
 
2467
    "          options { uninterpreted_option { name { name_part: \"ctype\" "
 
2468
    "                                                  is_extension: false }"
 
2469
    "                                           positive_int_value: 1 }"
 
2470
    "          }"
 
2471
    "  }"
 
2472
    "}\n",
 
2473
 
 
2474
    "foo.proto: TestMessage.foo: OPTION_VALUE: Value must be identifier for "
 
2475
    "enum-valued option \"google.protobuf.FieldOptions.ctype\".\n");
 
2476
}
 
2477
 
 
2478
TEST_F(ValidationErrorTest, OptionExtendsAtomicType) {
 
2479
  BuildFileWithErrors(
 
2480
    "name: \"foo.proto\" "
 
2481
    "message_type { "
 
2482
    "  name: \"TestMessage\" "
 
2483
    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING "
 
2484
    "          options { uninterpreted_option { name { name_part: \"ctype\" "
 
2485
    "                                                  is_extension: false }"
 
2486
    "                                           name { name_part: \"foo\" "
 
2487
    "                                                  is_extension: true }"
 
2488
    "                                           positive_int_value: 1 }"
 
2489
    "          }"
 
2490
    "  }"
 
2491
    "}\n",
 
2492
 
 
2493
    "foo.proto: TestMessage.foo: OPTION_NAME: Option \"ctype\" is an "
 
2494
    "atomic type, not a message.\n");
 
2495
}
 
2496
 
 
2497
TEST_F(ValidationErrorTest, DupOption) {
 
2498
  BuildFileWithErrors(
 
2499
    "name: \"foo.proto\" "
 
2500
    "message_type { "
 
2501
    "  name: \"TestMessage\" "
 
2502
    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_UINT32 "
 
2503
    "          options { uninterpreted_option { name { name_part: \"ctype\" "
 
2504
    "                                                  is_extension: false }"
 
2505
    "                                           identifier_value: \"CORD\" }"
 
2506
    "                    uninterpreted_option { name { name_part: \"ctype\" "
 
2507
    "                                                  is_extension: false }"
 
2508
    "                                           identifier_value: \"CORD\" }"
 
2509
    "          }"
 
2510
    "  }"
 
2511
    "}\n",
 
2512
 
 
2513
    "foo.proto: TestMessage.foo: OPTION_NAME: Option \"ctype\" was "
 
2514
    "already set.\n");
 
2515
}
 
2516
 
 
2517
TEST_F(ValidationErrorTest, InvalidOptionName) {
 
2518
  BuildFileWithErrors(
 
2519
    "name: \"foo.proto\" "
 
2520
    "message_type { "
 
2521
    "  name: \"TestMessage\" "
 
2522
    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_BOOL "
 
2523
    "          options { uninterpreted_option { "
 
2524
    "                      name { name_part: \"uninterpreted_option\" "
 
2525
    "                             is_extension: false }"
 
2526
    "                      positive_int_value: 1 "
 
2527
    "                    }"
 
2528
    "          }"
 
2529
    "  }"
 
2530
    "}\n",
 
2531
 
 
2532
    "foo.proto: TestMessage.foo: OPTION_NAME: Option must not use "
 
2533
    "reserved name \"uninterpreted_option\".\n");
 
2534
}
 
2535
 
 
2536
TEST_F(ValidationErrorTest, RepeatedOption) {
 
2537
  BuildDescriptorMessagesInTestPool();
 
2538
 
 
2539
  BuildFileWithErrors(
 
2540
    "name: \"foo.proto\" "
 
2541
    "dependency: \"google/protobuf/descriptor.proto\" "
 
2542
    "extension { name: \"foo\" number: 7672757 label: LABEL_REPEATED "
 
2543
    "            type: TYPE_FLOAT extendee: \"google.protobuf.FileOptions\" }"
 
2544
    "options { uninterpreted_option { name { name_part: \"foo\" "
 
2545
    "                                        is_extension: true } "
 
2546
    "                                 double_value: 1.2 } }",
 
2547
 
 
2548
    "foo.proto: foo.proto: OPTION_NAME: Option field \"(foo)\" is repeated. "
 
2549
    "Repeated options are not supported.\n");
 
2550
}
 
2551
 
 
2552
TEST_F(ValidationErrorTest, CustomOptionConflictingFieldNumber) {
 
2553
  BuildDescriptorMessagesInTestPool();
 
2554
 
 
2555
  BuildFileWithErrors(
 
2556
    "name: \"foo.proto\" "
 
2557
    "dependency: \"google/protobuf/descriptor.proto\" "
 
2558
    "extension { name: \"foo1\" number: 7672757 label: LABEL_OPTIONAL "
 
2559
    "            type: TYPE_INT32 extendee: \"google.protobuf.FieldOptions\" }"
 
2560
    "extension { name: \"foo2\" number: 7672757 label: LABEL_OPTIONAL "
 
2561
    "            type: TYPE_INT32 extendee: \"google.protobuf.FieldOptions\" }",
 
2562
 
 
2563
    "foo.proto: foo2: NUMBER: Extension number 7672757 has already been used "
 
2564
    "in \"google.protobuf.FieldOptions\" by extension \"foo1\".\n");
 
2565
}
 
2566
 
 
2567
TEST_F(ValidationErrorTest, Int32OptionValueOutOfPositiveRange) {
 
2568
  BuildDescriptorMessagesInTestPool();
 
2569
 
 
2570
  BuildFileWithErrors(
 
2571
    "name: \"foo.proto\" "
 
2572
    "dependency: \"google/protobuf/descriptor.proto\" "
 
2573
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
 
2574
    "            type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
 
2575
    "options { uninterpreted_option { name { name_part: \"foo\" "
 
2576
    "                                        is_extension: true } "
 
2577
    "                                 positive_int_value: 0x80000000 } "
 
2578
    "}",
 
2579
 
 
2580
    "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
 
2581
    "for int32 option \"foo\".\n");
 
2582
}
 
2583
 
 
2584
TEST_F(ValidationErrorTest, Int32OptionValueOutOfNegativeRange) {
 
2585
  BuildDescriptorMessagesInTestPool();
 
2586
 
 
2587
  BuildFileWithErrors(
 
2588
    "name: \"foo.proto\" "
 
2589
    "dependency: \"google/protobuf/descriptor.proto\" "
 
2590
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
 
2591
    "            type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
 
2592
    "options { uninterpreted_option { name { name_part: \"foo\" "
 
2593
    "                                        is_extension: true } "
 
2594
    "                                 negative_int_value: -0x80000001 } "
 
2595
    "}",
 
2596
 
 
2597
    "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
 
2598
    "for int32 option \"foo\".\n");
 
2599
}
 
2600
 
 
2601
TEST_F(ValidationErrorTest, Int32OptionValueIsNotPositiveInt) {
 
2602
  BuildDescriptorMessagesInTestPool();
 
2603
 
 
2604
  BuildFileWithErrors(
 
2605
    "name: \"foo.proto\" "
 
2606
    "dependency: \"google/protobuf/descriptor.proto\" "
 
2607
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
 
2608
    "            type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
 
2609
    "options { uninterpreted_option { name { name_part: \"foo\" "
 
2610
    "                                        is_extension: true } "
 
2611
    "                                 string_value: \"5\" } }",
 
2612
 
 
2613
    "foo.proto: foo.proto: OPTION_VALUE: Value must be integer "
 
2614
    "for int32 option \"foo\".\n");
 
2615
}
 
2616
 
 
2617
TEST_F(ValidationErrorTest, Int64OptionValueOutOfRange) {
 
2618
  BuildDescriptorMessagesInTestPool();
 
2619
 
 
2620
  BuildFileWithErrors(
 
2621
    "name: \"foo.proto\" "
 
2622
    "dependency: \"google/protobuf/descriptor.proto\" "
 
2623
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
 
2624
    "            type: TYPE_INT64 extendee: \"google.protobuf.FileOptions\" }"
 
2625
    "options { uninterpreted_option { name { name_part: \"foo\" "
 
2626
    "                                        is_extension: true } "
 
2627
    "                                 positive_int_value: 0x8000000000000000 } "
 
2628
    "}",
 
2629
 
 
2630
    "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
 
2631
    "for int64 option \"foo\".\n");
 
2632
}
 
2633
 
 
2634
TEST_F(ValidationErrorTest, Int64OptionValueIsNotPositiveInt) {
 
2635
  BuildDescriptorMessagesInTestPool();
 
2636
 
 
2637
  BuildFileWithErrors(
 
2638
    "name: \"foo.proto\" "
 
2639
    "dependency: \"google/protobuf/descriptor.proto\" "
 
2640
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
 
2641
    "            type: TYPE_INT64 extendee: \"google.protobuf.FileOptions\" }"
 
2642
    "options { uninterpreted_option { name { name_part: \"foo\" "
 
2643
    "                                        is_extension: true } "
 
2644
    "                                 identifier_value: \"5\" } }",
 
2645
 
 
2646
    "foo.proto: foo.proto: OPTION_VALUE: Value must be integer "
 
2647
    "for int64 option \"foo\".\n");
 
2648
}
 
2649
 
 
2650
TEST_F(ValidationErrorTest, UInt32OptionValueOutOfRange) {
 
2651
  BuildDescriptorMessagesInTestPool();
 
2652
 
 
2653
  BuildFileWithErrors(
 
2654
    "name: \"foo.proto\" "
 
2655
    "dependency: \"google/protobuf/descriptor.proto\" "
 
2656
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
 
2657
    "            type: TYPE_UINT32 extendee: \"google.protobuf.FileOptions\" }"
 
2658
    "options { uninterpreted_option { name { name_part: \"foo\" "
 
2659
    "                                        is_extension: true } "
 
2660
    "                                 positive_int_value: 0x100000000 } }",
 
2661
 
 
2662
    "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
 
2663
    "for uint32 option \"foo\".\n");
 
2664
}
 
2665
 
 
2666
TEST_F(ValidationErrorTest, UInt32OptionValueIsNotPositiveInt) {
 
2667
  BuildDescriptorMessagesInTestPool();
 
2668
 
 
2669
  BuildFileWithErrors(
 
2670
    "name: \"foo.proto\" "
 
2671
    "dependency: \"google/protobuf/descriptor.proto\" "
 
2672
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
 
2673
    "            type: TYPE_UINT32 extendee: \"google.protobuf.FileOptions\" }"
 
2674
    "options { uninterpreted_option { name { name_part: \"foo\" "
 
2675
    "                                        is_extension: true } "
 
2676
    "                                 double_value: -5.6 } }",
 
2677
 
 
2678
    "foo.proto: foo.proto: OPTION_VALUE: Value must be non-negative integer "
 
2679
    "for uint32 option \"foo\".\n");
 
2680
}
 
2681
 
 
2682
TEST_F(ValidationErrorTest, UInt64OptionValueIsNotPositiveInt) {
 
2683
  BuildDescriptorMessagesInTestPool();
 
2684
 
 
2685
  BuildFileWithErrors(
 
2686
    "name: \"foo.proto\" "
 
2687
    "dependency: \"google/protobuf/descriptor.proto\" "
 
2688
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
 
2689
    "            type: TYPE_UINT64 extendee: \"google.protobuf.FileOptions\" }"
 
2690
    "options { uninterpreted_option { name { name_part: \"foo\" "
 
2691
    "                                        is_extension: true } "
 
2692
    "                                 negative_int_value: -5 } }",
 
2693
 
 
2694
    "foo.proto: foo.proto: OPTION_VALUE: Value must be non-negative integer "
 
2695
    "for uint64 option \"foo\".\n");
 
2696
}
 
2697
 
 
2698
TEST_F(ValidationErrorTest, FloatOptionValueIsNotNumber) {
 
2699
  BuildDescriptorMessagesInTestPool();
 
2700
 
 
2701
  BuildFileWithErrors(
 
2702
    "name: \"foo.proto\" "
 
2703
    "dependency: \"google/protobuf/descriptor.proto\" "
 
2704
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
 
2705
    "            type: TYPE_FLOAT extendee: \"google.protobuf.FileOptions\" }"
 
2706
    "options { uninterpreted_option { name { name_part: \"foo\" "
 
2707
    "                                        is_extension: true } "
 
2708
    "                                 string_value: \"bar\" } }",
 
2709
 
 
2710
    "foo.proto: foo.proto: OPTION_VALUE: Value must be number "
 
2711
    "for float option \"foo\".\n");
 
2712
}
 
2713
 
 
2714
TEST_F(ValidationErrorTest, DoubleOptionValueIsNotNumber) {
 
2715
  BuildDescriptorMessagesInTestPool();
 
2716
 
 
2717
  BuildFileWithErrors(
 
2718
    "name: \"foo.proto\" "
 
2719
    "dependency: \"google/protobuf/descriptor.proto\" "
 
2720
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
 
2721
    "            type: TYPE_DOUBLE extendee: \"google.protobuf.FileOptions\" }"
 
2722
    "options { uninterpreted_option { name { name_part: \"foo\" "
 
2723
    "                                        is_extension: true } "
 
2724
    "                                 string_value: \"bar\" } }",
 
2725
 
 
2726
    "foo.proto: foo.proto: OPTION_VALUE: Value must be number "
 
2727
    "for double option \"foo\".\n");
 
2728
}
 
2729
 
 
2730
TEST_F(ValidationErrorTest, BoolOptionValueIsNotTrueOrFalse) {
 
2731
  BuildDescriptorMessagesInTestPool();
 
2732
 
 
2733
  BuildFileWithErrors(
 
2734
    "name: \"foo.proto\" "
 
2735
    "dependency: \"google/protobuf/descriptor.proto\" "
 
2736
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
 
2737
    "            type: TYPE_BOOL extendee: \"google.protobuf.FileOptions\" }"
 
2738
    "options { uninterpreted_option { name { name_part: \"foo\" "
 
2739
    "                                        is_extension: true } "
 
2740
    "                                 identifier_value: \"bar\" } }",
 
2741
 
 
2742
    "foo.proto: foo.proto: OPTION_VALUE: Value must be \"true\" or \"false\" "
 
2743
    "for boolean option \"foo\".\n");
 
2744
}
 
2745
 
 
2746
TEST_F(ValidationErrorTest, EnumOptionValueIsNotIdentifier) {
 
2747
  BuildDescriptorMessagesInTestPool();
 
2748
 
 
2749
  BuildFileWithErrors(
 
2750
    "name: \"foo.proto\" "
 
2751
    "dependency: \"google/protobuf/descriptor.proto\" "
 
2752
    "enum_type { name: \"FooEnum\" value { name: \"BAR\" number: 1 } "
 
2753
    "                              value { name: \"BAZ\" number: 2 } }"
 
2754
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
 
2755
    "            type: TYPE_ENUM type_name: \"FooEnum\" "
 
2756
    "            extendee: \"google.protobuf.FileOptions\" }"
 
2757
    "options { uninterpreted_option { name { name_part: \"foo\" "
 
2758
    "                                        is_extension: true } "
 
2759
    "                                 string_value: \"QUUX\" } }",
 
2760
 
 
2761
    "foo.proto: foo.proto: OPTION_VALUE: Value must be identifier for "
 
2762
    "enum-valued option \"foo\".\n");
 
2763
}
 
2764
 
 
2765
TEST_F(ValidationErrorTest, EnumOptionValueIsNotEnumValueName) {
 
2766
  BuildDescriptorMessagesInTestPool();
 
2767
 
 
2768
  BuildFileWithErrors(
 
2769
    "name: \"foo.proto\" "
 
2770
    "dependency: \"google/protobuf/descriptor.proto\" "
 
2771
    "enum_type { name: \"FooEnum\" value { name: \"BAR\" number: 1 } "
 
2772
    "                              value { name: \"BAZ\" number: 2 } }"
 
2773
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
 
2774
    "            type: TYPE_ENUM type_name: \"FooEnum\" "
 
2775
    "            extendee: \"google.protobuf.FileOptions\" }"
 
2776
    "options { uninterpreted_option { name { name_part: \"foo\" "
 
2777
    "                                        is_extension: true } "
 
2778
    "                                 identifier_value: \"QUUX\" } }",
 
2779
 
 
2780
    "foo.proto: foo.proto: OPTION_VALUE: Enum type \"FooEnum\" has no value "
 
2781
    "named \"QUUX\" for option \"foo\".\n");
 
2782
}
 
2783
 
 
2784
TEST_F(ValidationErrorTest, EnumOptionValueIsSiblingEnumValueName) {
 
2785
  BuildDescriptorMessagesInTestPool();
 
2786
 
 
2787
  BuildFileWithErrors(
 
2788
    "name: \"foo.proto\" "
 
2789
    "dependency: \"google/protobuf/descriptor.proto\" "
 
2790
    "enum_type { name: \"FooEnum1\" value { name: \"BAR\" number: 1 } "
 
2791
    "                               value { name: \"BAZ\" number: 2 } }"
 
2792
    "enum_type { name: \"FooEnum2\" value { name: \"QUX\" number: 1 } "
 
2793
    "                               value { name: \"QUUX\" number: 2 } }"
 
2794
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
 
2795
    "            type: TYPE_ENUM type_name: \"FooEnum1\" "
 
2796
    "            extendee: \"google.protobuf.FileOptions\" }"
 
2797
    "options { uninterpreted_option { name { name_part: \"foo\" "
 
2798
    "                                        is_extension: true } "
 
2799
    "                                 identifier_value: \"QUUX\" } }",
 
2800
 
 
2801
    "foo.proto: foo.proto: OPTION_VALUE: Enum type \"FooEnum1\" has no value "
 
2802
    "named \"QUUX\" for option \"foo\". This appears to be a value from a "
 
2803
    "sibling type.\n");
 
2804
}
 
2805
 
 
2806
TEST_F(ValidationErrorTest, StringOptionValueIsNotString) {
 
2807
  BuildDescriptorMessagesInTestPool();
 
2808
 
 
2809
  BuildFileWithErrors(
 
2810
    "name: \"foo.proto\" "
 
2811
    "dependency: \"google/protobuf/descriptor.proto\" "
 
2812
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
 
2813
    "            type: TYPE_STRING extendee: \"google.protobuf.FileOptions\" }"
 
2814
    "options { uninterpreted_option { name { name_part: \"foo\" "
 
2815
    "                                        is_extension: true } "
 
2816
    "                                 identifier_value: \"QUUX\" } }",
 
2817
 
 
2818
    "foo.proto: foo.proto: OPTION_VALUE: Value must be quoted string for "
 
2819
    "string option \"foo\".\n");
 
2820
}
 
2821
 
 
2822
TEST_F(ValidationErrorTest, TryingToSetMessageValuedOption) {
 
2823
  BuildDescriptorMessagesInTestPool();
 
2824
 
 
2825
  BuildFileWithErrors(
 
2826
    "name: \"foo.proto\" "
 
2827
    "dependency: \"google/protobuf/descriptor.proto\" "
 
2828
    "message_type { "
 
2829
    "  name: \"TestMessage\" "
 
2830
    "  field { name:\"baz\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING }"
 
2831
    "}"
 
2832
    "extension { name: \"bar\" number: 7672757 label: LABEL_OPTIONAL "
 
2833
    "            type: TYPE_MESSAGE type_name: \"TestMessage\" "
 
2834
    "            extendee: \"google.protobuf.FileOptions\" }"
 
2835
    "options { uninterpreted_option { name { name_part: \"bar\" "
 
2836
    "                                        is_extension: true } "
 
2837
    "                                 identifier_value: \"QUUX\" } }",
 
2838
 
 
2839
    "foo.proto: foo.proto: OPTION_NAME: Option field \"(bar)\" cannot be of "
 
2840
    "message type.\n");
 
2841
}
 
2842
 
2217
2843
TEST_F(ValidationErrorTest, RollbackAfterError) {
2218
2844
  // Build a file which contains every kind of construct but references an
2219
2845
  // undefined type.  All these constructs will be added to the symbol table