Home | History | Annotate | Download | only in protobuf
      1 // Protocol Buffers - Google's data interchange format
      2 // Copyright 2008 Google Inc.  All rights reserved.
      3 // https://developers.google.com/protocol-buffers/
      4 //
      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.
     30 
     31 // Author: kenton (at) google.com (Kenton Varda)
     32 //  Based on original Protocol Buffers design by
     33 //  Sanjay Ghemawat, Jeff Dean, and others.
     34 //
     35 // This file makes extensive use of RFC 3092.  :)
     36 
     37 #include <vector>
     38 
     39 #include <google/protobuf/compiler/importer.h>
     40 #include <google/protobuf/unittest.pb.h>
     41 #include <google/protobuf/unittest_custom_options.pb.h>
     42 #include <google/protobuf/io/zero_copy_stream_impl.h>
     43 #include <google/protobuf/descriptor.pb.h>
     44 #include <google/protobuf/descriptor.h>
     45 #include <google/protobuf/descriptor_database.h>
     46 #include <google/protobuf/dynamic_message.h>
     47 #include <google/protobuf/text_format.h>
     48 #include <google/protobuf/stubs/strutil.h>
     49 #include <google/protobuf/stubs/substitute.h>
     50 
     51 #include <google/protobuf/stubs/common.h>
     52 #include <google/protobuf/testing/googletest.h>
     53 #include <gtest/gtest.h>
     54 
     55 namespace google {
     56 namespace protobuf {
     57 
     58 // Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
     59 namespace descriptor_unittest {
     60 
     61 // Some helpers to make assembling descriptors faster.
     62 DescriptorProto* AddMessage(FileDescriptorProto* file, const string& name) {
     63   DescriptorProto* result = file->add_message_type();
     64   result->set_name(name);
     65   return result;
     66 }
     67 
     68 DescriptorProto* AddNestedMessage(DescriptorProto* parent, const string& name) {
     69   DescriptorProto* result = parent->add_nested_type();
     70   result->set_name(name);
     71   return result;
     72 }
     73 
     74 EnumDescriptorProto* AddEnum(FileDescriptorProto* file, const string& name) {
     75   EnumDescriptorProto* result = file->add_enum_type();
     76   result->set_name(name);
     77   return result;
     78 }
     79 
     80 EnumDescriptorProto* AddNestedEnum(DescriptorProto* parent,
     81                                    const string& name) {
     82   EnumDescriptorProto* result = parent->add_enum_type();
     83   result->set_name(name);
     84   return result;
     85 }
     86 
     87 ServiceDescriptorProto* AddService(FileDescriptorProto* file,
     88                                    const string& name) {
     89   ServiceDescriptorProto* result = file->add_service();
     90   result->set_name(name);
     91   return result;
     92 }
     93 
     94 FieldDescriptorProto* AddField(DescriptorProto* parent,
     95                                const string& name, int number,
     96                                FieldDescriptorProto::Label label,
     97                                FieldDescriptorProto::Type type) {
     98   FieldDescriptorProto* result = parent->add_field();
     99   result->set_name(name);
    100   result->set_number(number);
    101   result->set_label(label);
    102   result->set_type(type);
    103   return result;
    104 }
    105 
    106 FieldDescriptorProto* AddExtension(FileDescriptorProto* file,
    107                                    const string& extendee,
    108                                    const string& name, int number,
    109                                    FieldDescriptorProto::Label label,
    110                                    FieldDescriptorProto::Type type) {
    111   FieldDescriptorProto* result = file->add_extension();
    112   result->set_name(name);
    113   result->set_number(number);
    114   result->set_label(label);
    115   result->set_type(type);
    116   result->set_extendee(extendee);
    117   return result;
    118 }
    119 
    120 FieldDescriptorProto* AddNestedExtension(DescriptorProto* parent,
    121                                          const string& extendee,
    122                                          const string& name, int number,
    123                                          FieldDescriptorProto::Label label,
    124                                          FieldDescriptorProto::Type type) {
    125   FieldDescriptorProto* result = parent->add_extension();
    126   result->set_name(name);
    127   result->set_number(number);
    128   result->set_label(label);
    129   result->set_type(type);
    130   result->set_extendee(extendee);
    131   return result;
    132 }
    133 
    134 DescriptorProto::ExtensionRange* AddExtensionRange(DescriptorProto* parent,
    135                                                    int start, int end) {
    136   DescriptorProto::ExtensionRange* result = parent->add_extension_range();
    137   result->set_start(start);
    138   result->set_end(end);
    139   return result;
    140 }
    141 
    142 EnumValueDescriptorProto* AddEnumValue(EnumDescriptorProto* enum_proto,
    143                                        const string& name, int number) {
    144   EnumValueDescriptorProto* result = enum_proto->add_value();
    145   result->set_name(name);
    146   result->set_number(number);
    147   return result;
    148 }
    149 
    150 MethodDescriptorProto* AddMethod(ServiceDescriptorProto* service,
    151                                  const string& name,
    152                                  const string& input_type,
    153                                  const string& output_type) {
    154   MethodDescriptorProto* result = service->add_method();
    155   result->set_name(name);
    156   result->set_input_type(input_type);
    157   result->set_output_type(output_type);
    158   return result;
    159 }
    160 
    161 // Empty enums technically aren't allowed.  We need to insert a dummy value
    162 // into them.
    163 void AddEmptyEnum(FileDescriptorProto* file, const string& name) {
    164   AddEnumValue(AddEnum(file, name), name + "_DUMMY", 1);
    165 }
    166 
    167 // ===================================================================
    168 
    169 // Test simple files.
    170 class FileDescriptorTest : public testing::Test {
    171  protected:
    172   virtual void SetUp() {
    173     // Build descriptors for the following definitions:
    174     //
    175     //   // in "foo.proto"
    176     //   message FooMessage { extensions 1; }
    177     //   enum FooEnum {FOO_ENUM_VALUE = 1;}
    178     //   service FooService {}
    179     //   extend FooMessage { optional int32 foo_extension = 1; }
    180     //
    181     //   // in "bar.proto"
    182     //   package bar_package;
    183     //   message BarMessage { extensions 1; }
    184     //   enum BarEnum {BAR_ENUM_VALUE = 1;}
    185     //   service BarService {}
    186     //   extend BarMessage { optional int32 bar_extension = 1; }
    187     //
    188     // Also, we have an empty file "baz.proto".  This file's purpose is to
    189     // make sure that even though it has the same package as foo.proto,
    190     // searching it for members of foo.proto won't work.
    191 
    192     FileDescriptorProto foo_file;
    193     foo_file.set_name("foo.proto");
    194     AddExtensionRange(AddMessage(&foo_file, "FooMessage"), 1, 2);
    195     AddEnumValue(AddEnum(&foo_file, "FooEnum"), "FOO_ENUM_VALUE", 1);
    196     AddService(&foo_file, "FooService");
    197     AddExtension(&foo_file, "FooMessage", "foo_extension", 1,
    198                  FieldDescriptorProto::LABEL_OPTIONAL,
    199                  FieldDescriptorProto::TYPE_INT32);
    200 
    201     FileDescriptorProto bar_file;
    202     bar_file.set_name("bar.proto");
    203     bar_file.set_package("bar_package");
    204     bar_file.add_dependency("foo.proto");
    205     AddExtensionRange(AddMessage(&bar_file, "BarMessage"), 1, 2);
    206     AddEnumValue(AddEnum(&bar_file, "BarEnum"), "BAR_ENUM_VALUE", 1);
    207     AddService(&bar_file, "BarService");
    208     AddExtension(&bar_file, "bar_package.BarMessage", "bar_extension", 1,
    209                  FieldDescriptorProto::LABEL_OPTIONAL,
    210                  FieldDescriptorProto::TYPE_INT32);
    211 
    212     FileDescriptorProto baz_file;
    213     baz_file.set_name("baz.proto");
    214 
    215     // Build the descriptors and get the pointers.
    216     foo_file_ = pool_.BuildFile(foo_file);
    217     ASSERT_TRUE(foo_file_ != NULL);
    218 
    219     bar_file_ = pool_.BuildFile(bar_file);
    220     ASSERT_TRUE(bar_file_ != NULL);
    221 
    222     baz_file_ = pool_.BuildFile(baz_file);
    223     ASSERT_TRUE(baz_file_ != NULL);
    224 
    225     ASSERT_EQ(1, foo_file_->message_type_count());
    226     foo_message_ = foo_file_->message_type(0);
    227     ASSERT_EQ(1, foo_file_->enum_type_count());
    228     foo_enum_ = foo_file_->enum_type(0);
    229     ASSERT_EQ(1, foo_enum_->value_count());
    230     foo_enum_value_ = foo_enum_->value(0);
    231     ASSERT_EQ(1, foo_file_->service_count());
    232     foo_service_ = foo_file_->service(0);
    233     ASSERT_EQ(1, foo_file_->extension_count());
    234     foo_extension_ = foo_file_->extension(0);
    235 
    236     ASSERT_EQ(1, bar_file_->message_type_count());
    237     bar_message_ = bar_file_->message_type(0);
    238     ASSERT_EQ(1, bar_file_->enum_type_count());
    239     bar_enum_ = bar_file_->enum_type(0);
    240     ASSERT_EQ(1, bar_enum_->value_count());
    241     bar_enum_value_ = bar_enum_->value(0);
    242     ASSERT_EQ(1, bar_file_->service_count());
    243     bar_service_ = bar_file_->service(0);
    244     ASSERT_EQ(1, bar_file_->extension_count());
    245     bar_extension_ = bar_file_->extension(0);
    246   }
    247 
    248   DescriptorPool pool_;
    249 
    250   const FileDescriptor* foo_file_;
    251   const FileDescriptor* bar_file_;
    252   const FileDescriptor* baz_file_;
    253 
    254   const Descriptor*          foo_message_;
    255   const EnumDescriptor*      foo_enum_;
    256   const EnumValueDescriptor* foo_enum_value_;
    257   const ServiceDescriptor*   foo_service_;
    258   const FieldDescriptor*     foo_extension_;
    259 
    260   const Descriptor*          bar_message_;
    261   const EnumDescriptor*      bar_enum_;
    262   const EnumValueDescriptor* bar_enum_value_;
    263   const ServiceDescriptor*   bar_service_;
    264   const FieldDescriptor*     bar_extension_;
    265 };
    266 
    267 TEST_F(FileDescriptorTest, Name) {
    268   EXPECT_EQ("foo.proto", foo_file_->name());
    269   EXPECT_EQ("bar.proto", bar_file_->name());
    270   EXPECT_EQ("baz.proto", baz_file_->name());
    271 }
    272 
    273 TEST_F(FileDescriptorTest, Package) {
    274   EXPECT_EQ("", foo_file_->package());
    275   EXPECT_EQ("bar_package", bar_file_->package());
    276 }
    277 
    278 TEST_F(FileDescriptorTest, Dependencies) {
    279   EXPECT_EQ(0, foo_file_->dependency_count());
    280   EXPECT_EQ(1, bar_file_->dependency_count());
    281   EXPECT_EQ(foo_file_, bar_file_->dependency(0));
    282 }
    283 
    284 TEST_F(FileDescriptorTest, FindMessageTypeByName) {
    285   EXPECT_EQ(foo_message_, foo_file_->FindMessageTypeByName("FooMessage"));
    286   EXPECT_EQ(bar_message_, bar_file_->FindMessageTypeByName("BarMessage"));
    287 
    288   EXPECT_TRUE(foo_file_->FindMessageTypeByName("BarMessage") == NULL);
    289   EXPECT_TRUE(bar_file_->FindMessageTypeByName("FooMessage") == NULL);
    290   EXPECT_TRUE(baz_file_->FindMessageTypeByName("FooMessage") == NULL);
    291 
    292   EXPECT_TRUE(foo_file_->FindMessageTypeByName("NoSuchMessage") == NULL);
    293   EXPECT_TRUE(foo_file_->FindMessageTypeByName("FooEnum") == NULL);
    294 }
    295 
    296 TEST_F(FileDescriptorTest, FindEnumTypeByName) {
    297   EXPECT_EQ(foo_enum_, foo_file_->FindEnumTypeByName("FooEnum"));
    298   EXPECT_EQ(bar_enum_, bar_file_->FindEnumTypeByName("BarEnum"));
    299 
    300   EXPECT_TRUE(foo_file_->FindEnumTypeByName("BarEnum") == NULL);
    301   EXPECT_TRUE(bar_file_->FindEnumTypeByName("FooEnum") == NULL);
    302   EXPECT_TRUE(baz_file_->FindEnumTypeByName("FooEnum") == NULL);
    303 
    304   EXPECT_TRUE(foo_file_->FindEnumTypeByName("NoSuchEnum") == NULL);
    305   EXPECT_TRUE(foo_file_->FindEnumTypeByName("FooMessage") == NULL);
    306 }
    307 
    308 TEST_F(FileDescriptorTest, FindEnumValueByName) {
    309   EXPECT_EQ(foo_enum_value_, foo_file_->FindEnumValueByName("FOO_ENUM_VALUE"));
    310   EXPECT_EQ(bar_enum_value_, bar_file_->FindEnumValueByName("BAR_ENUM_VALUE"));
    311 
    312   EXPECT_TRUE(foo_file_->FindEnumValueByName("BAR_ENUM_VALUE") == NULL);
    313   EXPECT_TRUE(bar_file_->FindEnumValueByName("FOO_ENUM_VALUE") == NULL);
    314   EXPECT_TRUE(baz_file_->FindEnumValueByName("FOO_ENUM_VALUE") == NULL);
    315 
    316   EXPECT_TRUE(foo_file_->FindEnumValueByName("NO_SUCH_VALUE") == NULL);
    317   EXPECT_TRUE(foo_file_->FindEnumValueByName("FooMessage") == NULL);
    318 }
    319 
    320 TEST_F(FileDescriptorTest, FindServiceByName) {
    321   EXPECT_EQ(foo_service_, foo_file_->FindServiceByName("FooService"));
    322   EXPECT_EQ(bar_service_, bar_file_->FindServiceByName("BarService"));
    323 
    324   EXPECT_TRUE(foo_file_->FindServiceByName("BarService") == NULL);
    325   EXPECT_TRUE(bar_file_->FindServiceByName("FooService") == NULL);
    326   EXPECT_TRUE(baz_file_->FindServiceByName("FooService") == NULL);
    327 
    328   EXPECT_TRUE(foo_file_->FindServiceByName("NoSuchService") == NULL);
    329   EXPECT_TRUE(foo_file_->FindServiceByName("FooMessage") == NULL);
    330 }
    331 
    332 TEST_F(FileDescriptorTest, FindExtensionByName) {
    333   EXPECT_EQ(foo_extension_, foo_file_->FindExtensionByName("foo_extension"));
    334   EXPECT_EQ(bar_extension_, bar_file_->FindExtensionByName("bar_extension"));
    335 
    336   EXPECT_TRUE(foo_file_->FindExtensionByName("bar_extension") == NULL);
    337   EXPECT_TRUE(bar_file_->FindExtensionByName("foo_extension") == NULL);
    338   EXPECT_TRUE(baz_file_->FindExtensionByName("foo_extension") == NULL);
    339 
    340   EXPECT_TRUE(foo_file_->FindExtensionByName("no_such_extension") == NULL);
    341   EXPECT_TRUE(foo_file_->FindExtensionByName("FooMessage") == NULL);
    342 }
    343 
    344 TEST_F(FileDescriptorTest, FindExtensionByNumber) {
    345   EXPECT_EQ(foo_extension_, pool_.FindExtensionByNumber(foo_message_, 1));
    346   EXPECT_EQ(bar_extension_, pool_.FindExtensionByNumber(bar_message_, 1));
    347 
    348   EXPECT_TRUE(pool_.FindExtensionByNumber(foo_message_, 2) == NULL);
    349 }
    350 
    351 TEST_F(FileDescriptorTest, BuildAgain) {
    352   // Test that if te call BuildFile again on the same input we get the same
    353   // FileDescriptor back.
    354   FileDescriptorProto file;
    355   foo_file_->CopyTo(&file);
    356   EXPECT_EQ(foo_file_, pool_.BuildFile(file));
    357 
    358   // But if we change the file then it won't work.
    359   file.set_package("some.other.package");
    360   EXPECT_TRUE(pool_.BuildFile(file) == NULL);
    361 }
    362 
    363 // ===================================================================
    364 
    365 // Test simple flat messages and fields.
    366 class DescriptorTest : public testing::Test {
    367  protected:
    368   virtual void SetUp() {
    369     // Build descriptors for the following definitions:
    370     //
    371     //   // in "foo.proto"
    372     //   message TestForeign {}
    373     //   enum TestEnum {}
    374     //
    375     //   message TestMessage {
    376     //     required string      foo = 1;
    377     //     optional TestEnum    bar = 6;
    378     //     repeated TestForeign baz = 500000000;
    379     //     optional group       qux = 15 {}
    380     //   }
    381     //
    382     //   // in "bar.proto"
    383     //   package corge.grault;
    384     //   message TestMessage2 {
    385     //     required string foo = 1;
    386     //     required string bar = 2;
    387     //     required string quux = 6;
    388     //   }
    389     //
    390     // We cheat and use TestForeign as the type for qux rather than create
    391     // an actual nested type.
    392     //
    393     // Since all primitive types (including string) use the same building
    394     // code, there's no need to test each one individually.
    395     //
    396     // TestMessage2 is primarily here to test FindFieldByName and friends.
    397     // All messages created from the same DescriptorPool share the same lookup
    398     // table, so we need to insure that they don't interfere.
    399 
    400     FileDescriptorProto foo_file;
    401     foo_file.set_name("foo.proto");
    402     AddMessage(&foo_file, "TestForeign");
    403     AddEmptyEnum(&foo_file, "TestEnum");
    404 
    405     DescriptorProto* message = AddMessage(&foo_file, "TestMessage");
    406     AddField(message, "foo", 1,
    407              FieldDescriptorProto::LABEL_REQUIRED,
    408              FieldDescriptorProto::TYPE_STRING);
    409     AddField(message, "bar", 6,
    410              FieldDescriptorProto::LABEL_OPTIONAL,
    411              FieldDescriptorProto::TYPE_ENUM)
    412       ->set_type_name("TestEnum");
    413     AddField(message, "baz", 500000000,
    414              FieldDescriptorProto::LABEL_REPEATED,
    415              FieldDescriptorProto::TYPE_MESSAGE)
    416       ->set_type_name("TestForeign");
    417     AddField(message, "qux", 15,
    418              FieldDescriptorProto::LABEL_OPTIONAL,
    419              FieldDescriptorProto::TYPE_GROUP)
    420       ->set_type_name("TestForeign");
    421 
    422     FileDescriptorProto bar_file;
    423     bar_file.set_name("bar.proto");
    424     bar_file.set_package("corge.grault");
    425 
    426     DescriptorProto* message2 = AddMessage(&bar_file, "TestMessage2");
    427     AddField(message2, "foo", 1,
    428              FieldDescriptorProto::LABEL_REQUIRED,
    429              FieldDescriptorProto::TYPE_STRING);
    430     AddField(message2, "bar", 2,
    431              FieldDescriptorProto::LABEL_REQUIRED,
    432              FieldDescriptorProto::TYPE_STRING);
    433     AddField(message2, "quux", 6,
    434              FieldDescriptorProto::LABEL_REQUIRED,
    435              FieldDescriptorProto::TYPE_STRING);
    436 
    437     // Build the descriptors and get the pointers.
    438     foo_file_ = pool_.BuildFile(foo_file);
    439     ASSERT_TRUE(foo_file_ != NULL);
    440 
    441     bar_file_ = pool_.BuildFile(bar_file);
    442     ASSERT_TRUE(bar_file_ != NULL);
    443 
    444     ASSERT_EQ(1, foo_file_->enum_type_count());
    445     enum_ = foo_file_->enum_type(0);
    446 
    447     ASSERT_EQ(2, foo_file_->message_type_count());
    448     foreign_ = foo_file_->message_type(0);
    449     message_ = foo_file_->message_type(1);
    450 
    451     ASSERT_EQ(4, message_->field_count());
    452     foo_ = message_->field(0);
    453     bar_ = message_->field(1);
    454     baz_ = message_->field(2);
    455     qux_ = message_->field(3);
    456 
    457     ASSERT_EQ(1, bar_file_->message_type_count());
    458     message2_ = bar_file_->message_type(0);
    459 
    460     ASSERT_EQ(3, message2_->field_count());
    461     foo2_  = message2_->field(0);
    462     bar2_  = message2_->field(1);
    463     quux2_ = message2_->field(2);
    464   }
    465 
    466   DescriptorPool pool_;
    467 
    468   const FileDescriptor* foo_file_;
    469   const FileDescriptor* bar_file_;
    470 
    471   const Descriptor* message_;
    472   const Descriptor* message2_;
    473   const Descriptor* foreign_;
    474   const EnumDescriptor* enum_;
    475 
    476   const FieldDescriptor* foo_;
    477   const FieldDescriptor* bar_;
    478   const FieldDescriptor* baz_;
    479   const FieldDescriptor* qux_;
    480 
    481   const FieldDescriptor* foo2_;
    482   const FieldDescriptor* bar2_;
    483   const FieldDescriptor* quux2_;
    484 };
    485 
    486 TEST_F(DescriptorTest, Name) {
    487   EXPECT_EQ("TestMessage", message_->name());
    488   EXPECT_EQ("TestMessage", message_->full_name());
    489   EXPECT_EQ(foo_file_, message_->file());
    490 
    491   EXPECT_EQ("TestMessage2", message2_->name());
    492   EXPECT_EQ("corge.grault.TestMessage2", message2_->full_name());
    493   EXPECT_EQ(bar_file_, message2_->file());
    494 }
    495 
    496 TEST_F(DescriptorTest, ContainingType) {
    497   EXPECT_TRUE(message_->containing_type() == NULL);
    498   EXPECT_TRUE(message2_->containing_type() == NULL);
    499 }
    500 
    501 TEST_F(DescriptorTest, FieldsByIndex) {
    502   ASSERT_EQ(4, message_->field_count());
    503   EXPECT_EQ(foo_, message_->field(0));
    504   EXPECT_EQ(bar_, message_->field(1));
    505   EXPECT_EQ(baz_, message_->field(2));
    506   EXPECT_EQ(qux_, message_->field(3));
    507 }
    508 
    509 TEST_F(DescriptorTest, FindFieldByName) {
    510   // All messages in the same DescriptorPool share a single lookup table for
    511   // fields.  So, in addition to testing that FindFieldByName finds the fields
    512   // of the message, we need to test that it does *not* find the fields of
    513   // *other* messages.
    514 
    515   EXPECT_EQ(foo_, message_->FindFieldByName("foo"));
    516   EXPECT_EQ(bar_, message_->FindFieldByName("bar"));
    517   EXPECT_EQ(baz_, message_->FindFieldByName("baz"));
    518   EXPECT_EQ(qux_, message_->FindFieldByName("qux"));
    519   EXPECT_TRUE(message_->FindFieldByName("no_such_field") == NULL);
    520   EXPECT_TRUE(message_->FindFieldByName("quux") == NULL);
    521 
    522   EXPECT_EQ(foo2_ , message2_->FindFieldByName("foo" ));
    523   EXPECT_EQ(bar2_ , message2_->FindFieldByName("bar" ));
    524   EXPECT_EQ(quux2_, message2_->FindFieldByName("quux"));
    525   EXPECT_TRUE(message2_->FindFieldByName("baz") == NULL);
    526   EXPECT_TRUE(message2_->FindFieldByName("qux") == NULL);
    527 }
    528 
    529 TEST_F(DescriptorTest, FindFieldByNumber) {
    530   EXPECT_EQ(foo_, message_->FindFieldByNumber(1));
    531   EXPECT_EQ(bar_, message_->FindFieldByNumber(6));
    532   EXPECT_EQ(baz_, message_->FindFieldByNumber(500000000));
    533   EXPECT_EQ(qux_, message_->FindFieldByNumber(15));
    534   EXPECT_TRUE(message_->FindFieldByNumber(837592) == NULL);
    535   EXPECT_TRUE(message_->FindFieldByNumber(2) == NULL);
    536 
    537   EXPECT_EQ(foo2_ , message2_->FindFieldByNumber(1));
    538   EXPECT_EQ(bar2_ , message2_->FindFieldByNumber(2));
    539   EXPECT_EQ(quux2_, message2_->FindFieldByNumber(6));
    540   EXPECT_TRUE(message2_->FindFieldByNumber(15) == NULL);
    541   EXPECT_TRUE(message2_->FindFieldByNumber(500000000) == NULL);
    542 }
    543 
    544 TEST_F(DescriptorTest, FieldName) {
    545   EXPECT_EQ("foo", foo_->name());
    546   EXPECT_EQ("bar", bar_->name());
    547   EXPECT_EQ("baz", baz_->name());
    548   EXPECT_EQ("qux", qux_->name());
    549 }
    550 
    551 TEST_F(DescriptorTest, FieldFullName) {
    552   EXPECT_EQ("TestMessage.foo", foo_->full_name());
    553   EXPECT_EQ("TestMessage.bar", bar_->full_name());
    554   EXPECT_EQ("TestMessage.baz", baz_->full_name());
    555   EXPECT_EQ("TestMessage.qux", qux_->full_name());
    556 
    557   EXPECT_EQ("corge.grault.TestMessage2.foo", foo2_->full_name());
    558   EXPECT_EQ("corge.grault.TestMessage2.bar", bar2_->full_name());
    559   EXPECT_EQ("corge.grault.TestMessage2.quux", quux2_->full_name());
    560 }
    561 
    562 TEST_F(DescriptorTest, FieldFile) {
    563   EXPECT_EQ(foo_file_, foo_->file());
    564   EXPECT_EQ(foo_file_, bar_->file());
    565   EXPECT_EQ(foo_file_, baz_->file());
    566   EXPECT_EQ(foo_file_, qux_->file());
    567 
    568   EXPECT_EQ(bar_file_, foo2_->file());
    569   EXPECT_EQ(bar_file_, bar2_->file());
    570   EXPECT_EQ(bar_file_, quux2_->file());
    571 }
    572 
    573 TEST_F(DescriptorTest, FieldIndex) {
    574   EXPECT_EQ(0, foo_->index());
    575   EXPECT_EQ(1, bar_->index());
    576   EXPECT_EQ(2, baz_->index());
    577   EXPECT_EQ(3, qux_->index());
    578 }
    579 
    580 TEST_F(DescriptorTest, FieldNumber) {
    581   EXPECT_EQ(        1, foo_->number());
    582   EXPECT_EQ(        6, bar_->number());
    583   EXPECT_EQ(500000000, baz_->number());
    584   EXPECT_EQ(       15, qux_->number());
    585 }
    586 
    587 TEST_F(DescriptorTest, FieldType) {
    588   EXPECT_EQ(FieldDescriptor::TYPE_STRING , foo_->type());
    589   EXPECT_EQ(FieldDescriptor::TYPE_ENUM   , bar_->type());
    590   EXPECT_EQ(FieldDescriptor::TYPE_MESSAGE, baz_->type());
    591   EXPECT_EQ(FieldDescriptor::TYPE_GROUP  , qux_->type());
    592 }
    593 
    594 TEST_F(DescriptorTest, FieldLabel) {
    595   EXPECT_EQ(FieldDescriptor::LABEL_REQUIRED, foo_->label());
    596   EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, bar_->label());
    597   EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, baz_->label());
    598   EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, qux_->label());
    599 
    600   EXPECT_TRUE (foo_->is_required());
    601   EXPECT_FALSE(foo_->is_optional());
    602   EXPECT_FALSE(foo_->is_repeated());
    603 
    604   EXPECT_FALSE(bar_->is_required());
    605   EXPECT_TRUE (bar_->is_optional());
    606   EXPECT_FALSE(bar_->is_repeated());
    607 
    608   EXPECT_FALSE(baz_->is_required());
    609   EXPECT_FALSE(baz_->is_optional());
    610   EXPECT_TRUE (baz_->is_repeated());
    611 }
    612 
    613 TEST_F(DescriptorTest, FieldHasDefault) {
    614   EXPECT_FALSE(foo_->has_default_value());
    615   EXPECT_FALSE(bar_->has_default_value());
    616   EXPECT_FALSE(baz_->has_default_value());
    617   EXPECT_FALSE(qux_->has_default_value());
    618 }
    619 
    620 TEST_F(DescriptorTest, FieldContainingType) {
    621   EXPECT_EQ(message_, foo_->containing_type());
    622   EXPECT_EQ(message_, bar_->containing_type());
    623   EXPECT_EQ(message_, baz_->containing_type());
    624   EXPECT_EQ(message_, qux_->containing_type());
    625 
    626   EXPECT_EQ(message2_, foo2_ ->containing_type());
    627   EXPECT_EQ(message2_, bar2_ ->containing_type());
    628   EXPECT_EQ(message2_, quux2_->containing_type());
    629 }
    630 
    631 TEST_F(DescriptorTest, FieldMessageType) {
    632   EXPECT_TRUE(foo_->message_type() == NULL);
    633   EXPECT_TRUE(bar_->message_type() == NULL);
    634 
    635   EXPECT_EQ(foreign_, baz_->message_type());
    636   EXPECT_EQ(foreign_, qux_->message_type());
    637 }
    638 
    639 TEST_F(DescriptorTest, FieldEnumType) {
    640   EXPECT_TRUE(foo_->enum_type() == NULL);
    641   EXPECT_TRUE(baz_->enum_type() == NULL);
    642   EXPECT_TRUE(qux_->enum_type() == NULL);
    643 
    644   EXPECT_EQ(enum_, bar_->enum_type());
    645 }
    646 
    647 // ===================================================================
    648 
    649 // Test simple flat messages and fields.
    650 class OneofDescriptorTest : public testing::Test {
    651  protected:
    652   virtual void SetUp() {
    653     // Build descriptors for the following definitions:
    654     //
    655     //   package garply;
    656     //   message TestOneof {
    657     //     optional int32 a = 1;
    658     //     oneof foo {
    659     //       string b = 2;
    660     //       TestOneof c = 3;
    661     //     }
    662     //     oneof bar {
    663     //       float d = 4;
    664     //     }
    665     //   }
    666 
    667     FileDescriptorProto baz_file;
    668     baz_file.set_name("baz.proto");
    669     baz_file.set_package("garply");
    670 
    671     DescriptorProto* oneof_message = AddMessage(&baz_file, "TestOneof");
    672     oneof_message->add_oneof_decl()->set_name("foo");
    673     oneof_message->add_oneof_decl()->set_name("bar");
    674 
    675     AddField(oneof_message, "a", 1,
    676              FieldDescriptorProto::LABEL_OPTIONAL,
    677              FieldDescriptorProto::TYPE_INT32);
    678     AddField(oneof_message, "b", 2,
    679              FieldDescriptorProto::LABEL_OPTIONAL,
    680              FieldDescriptorProto::TYPE_STRING);
    681     oneof_message->mutable_field(1)->set_oneof_index(0);
    682     AddField(oneof_message, "c", 3,
    683              FieldDescriptorProto::LABEL_OPTIONAL,
    684              FieldDescriptorProto::TYPE_MESSAGE);
    685     oneof_message->mutable_field(2)->set_oneof_index(0);
    686     oneof_message->mutable_field(2)->set_type_name("TestOneof");
    687 
    688     AddField(oneof_message, "d", 4,
    689              FieldDescriptorProto::LABEL_OPTIONAL,
    690              FieldDescriptorProto::TYPE_FLOAT);
    691     oneof_message->mutable_field(3)->set_oneof_index(1);
    692 
    693     // Build the descriptors and get the pointers.
    694     baz_file_ = pool_.BuildFile(baz_file);
    695     ASSERT_TRUE(baz_file_ != NULL);
    696 
    697     ASSERT_EQ(1, baz_file_->message_type_count());
    698     oneof_message_ = baz_file_->message_type(0);
    699 
    700     ASSERT_EQ(2, oneof_message_->oneof_decl_count());
    701     oneof_ = oneof_message_->oneof_decl(0);
    702     oneof2_ = oneof_message_->oneof_decl(1);
    703 
    704     ASSERT_EQ(4, oneof_message_->field_count());
    705     a_ = oneof_message_->field(0);
    706     b_ = oneof_message_->field(1);
    707     c_ = oneof_message_->field(2);
    708     d_ = oneof_message_->field(3);
    709   }
    710 
    711   DescriptorPool pool_;
    712 
    713   const FileDescriptor* baz_file_;
    714 
    715   const Descriptor* oneof_message_;
    716 
    717   const OneofDescriptor* oneof_;
    718   const OneofDescriptor* oneof2_;
    719   const FieldDescriptor* a_;
    720   const FieldDescriptor* b_;
    721   const FieldDescriptor* c_;
    722   const FieldDescriptor* d_;
    723   const FieldDescriptor* e_;
    724   const FieldDescriptor* f_;
    725 };
    726 
    727 TEST_F(OneofDescriptorTest, Normal) {
    728   EXPECT_EQ("foo", oneof_->name());
    729   EXPECT_EQ("garply.TestOneof.foo", oneof_->full_name());
    730   EXPECT_EQ(0, oneof_->index());
    731   ASSERT_EQ(2, oneof_->field_count());
    732   EXPECT_EQ(b_, oneof_->field(0));
    733   EXPECT_EQ(c_, oneof_->field(1));
    734   EXPECT_TRUE(a_->containing_oneof() == NULL);
    735   EXPECT_EQ(oneof_, b_->containing_oneof());
    736   EXPECT_EQ(oneof_, c_->containing_oneof());
    737 }
    738 
    739 TEST_F(OneofDescriptorTest, FindByName) {
    740   EXPECT_EQ(oneof_, oneof_message_->FindOneofByName("foo"));
    741   EXPECT_EQ(oneof2_, oneof_message_->FindOneofByName("bar"));
    742   EXPECT_TRUE(oneof_message_->FindOneofByName("no_such_oneof") == NULL);
    743 }
    744 
    745 // ===================================================================
    746 
    747 class StylizedFieldNamesTest : public testing::Test {
    748  protected:
    749   void SetUp() {
    750     FileDescriptorProto file;
    751     file.set_name("foo.proto");
    752 
    753     AddExtensionRange(AddMessage(&file, "ExtendableMessage"), 1, 1000);
    754 
    755     DescriptorProto* message = AddMessage(&file, "TestMessage");
    756     AddField(message, "foo_foo", 1,
    757              FieldDescriptorProto::LABEL_OPTIONAL,
    758              FieldDescriptorProto::TYPE_INT32);
    759     AddField(message, "FooBar", 2,
    760              FieldDescriptorProto::LABEL_OPTIONAL,
    761              FieldDescriptorProto::TYPE_INT32);
    762     AddField(message, "fooBaz", 3,
    763              FieldDescriptorProto::LABEL_OPTIONAL,
    764              FieldDescriptorProto::TYPE_INT32);
    765     AddField(message, "fooFoo", 4,  // Camel-case conflict with foo_foo.
    766              FieldDescriptorProto::LABEL_OPTIONAL,
    767              FieldDescriptorProto::TYPE_INT32);
    768     AddField(message, "foobar", 5,  // Lower-case conflict with FooBar.
    769              FieldDescriptorProto::LABEL_OPTIONAL,
    770              FieldDescriptorProto::TYPE_INT32);
    771 
    772     AddNestedExtension(message, "ExtendableMessage", "bar_foo", 1,
    773                        FieldDescriptorProto::LABEL_OPTIONAL,
    774                        FieldDescriptorProto::TYPE_INT32);
    775     AddNestedExtension(message, "ExtendableMessage", "BarBar", 2,
    776                        FieldDescriptorProto::LABEL_OPTIONAL,
    777                        FieldDescriptorProto::TYPE_INT32);
    778     AddNestedExtension(message, "ExtendableMessage", "BarBaz", 3,
    779                        FieldDescriptorProto::LABEL_OPTIONAL,
    780                        FieldDescriptorProto::TYPE_INT32);
    781     AddNestedExtension(message, "ExtendableMessage", "barFoo", 4,  // Conflict
    782                        FieldDescriptorProto::LABEL_OPTIONAL,
    783                        FieldDescriptorProto::TYPE_INT32);
    784     AddNestedExtension(message, "ExtendableMessage", "barbar", 5,  // Conflict
    785                        FieldDescriptorProto::LABEL_OPTIONAL,
    786                        FieldDescriptorProto::TYPE_INT32);
    787 
    788     AddExtension(&file, "ExtendableMessage", "baz_foo", 11,
    789                  FieldDescriptorProto::LABEL_OPTIONAL,
    790                  FieldDescriptorProto::TYPE_INT32);
    791     AddExtension(&file, "ExtendableMessage", "BazBar", 12,
    792                  FieldDescriptorProto::LABEL_OPTIONAL,
    793                  FieldDescriptorProto::TYPE_INT32);
    794     AddExtension(&file, "ExtendableMessage", "BazBaz", 13,
    795                  FieldDescriptorProto::LABEL_OPTIONAL,
    796                  FieldDescriptorProto::TYPE_INT32);
    797     AddExtension(&file, "ExtendableMessage", "bazFoo", 14,  // Conflict
    798                  FieldDescriptorProto::LABEL_OPTIONAL,
    799                  FieldDescriptorProto::TYPE_INT32);
    800     AddExtension(&file, "ExtendableMessage", "bazbar", 15,  // Conflict
    801                  FieldDescriptorProto::LABEL_OPTIONAL,
    802                  FieldDescriptorProto::TYPE_INT32);
    803 
    804     file_ = pool_.BuildFile(file);
    805     ASSERT_TRUE(file_ != NULL);
    806     ASSERT_EQ(2, file_->message_type_count());
    807     message_ = file_->message_type(1);
    808     ASSERT_EQ("TestMessage", message_->name());
    809     ASSERT_EQ(5, message_->field_count());
    810     ASSERT_EQ(5, message_->extension_count());
    811     ASSERT_EQ(5, file_->extension_count());
    812   }
    813 
    814   DescriptorPool pool_;
    815   const FileDescriptor* file_;
    816   const Descriptor* message_;
    817 };
    818 
    819 TEST_F(StylizedFieldNamesTest, LowercaseName) {
    820   EXPECT_EQ("foo_foo", message_->field(0)->lowercase_name());
    821   EXPECT_EQ("foobar" , message_->field(1)->lowercase_name());
    822   EXPECT_EQ("foobaz" , message_->field(2)->lowercase_name());
    823   EXPECT_EQ("foofoo" , message_->field(3)->lowercase_name());
    824   EXPECT_EQ("foobar" , message_->field(4)->lowercase_name());
    825 
    826   EXPECT_EQ("bar_foo", message_->extension(0)->lowercase_name());
    827   EXPECT_EQ("barbar" , message_->extension(1)->lowercase_name());
    828   EXPECT_EQ("barbaz" , message_->extension(2)->lowercase_name());
    829   EXPECT_EQ("barfoo" , message_->extension(3)->lowercase_name());
    830   EXPECT_EQ("barbar" , message_->extension(4)->lowercase_name());
    831 
    832   EXPECT_EQ("baz_foo", file_->extension(0)->lowercase_name());
    833   EXPECT_EQ("bazbar" , file_->extension(1)->lowercase_name());
    834   EXPECT_EQ("bazbaz" , file_->extension(2)->lowercase_name());
    835   EXPECT_EQ("bazfoo" , file_->extension(3)->lowercase_name());
    836   EXPECT_EQ("bazbar" , file_->extension(4)->lowercase_name());
    837 }
    838 
    839 TEST_F(StylizedFieldNamesTest, CamelcaseName) {
    840   EXPECT_EQ("fooFoo", message_->field(0)->camelcase_name());
    841   EXPECT_EQ("fooBar", message_->field(1)->camelcase_name());
    842   EXPECT_EQ("fooBaz", message_->field(2)->camelcase_name());
    843   EXPECT_EQ("fooFoo", message_->field(3)->camelcase_name());
    844   EXPECT_EQ("foobar", message_->field(4)->camelcase_name());
    845 
    846   EXPECT_EQ("barFoo", message_->extension(0)->camelcase_name());
    847   EXPECT_EQ("barBar", message_->extension(1)->camelcase_name());
    848   EXPECT_EQ("barBaz", message_->extension(2)->camelcase_name());
    849   EXPECT_EQ("barFoo", message_->extension(3)->camelcase_name());
    850   EXPECT_EQ("barbar", message_->extension(4)->camelcase_name());
    851 
    852   EXPECT_EQ("bazFoo", file_->extension(0)->camelcase_name());
    853   EXPECT_EQ("bazBar", file_->extension(1)->camelcase_name());
    854   EXPECT_EQ("bazBaz", file_->extension(2)->camelcase_name());
    855   EXPECT_EQ("bazFoo", file_->extension(3)->camelcase_name());
    856   EXPECT_EQ("bazbar", file_->extension(4)->camelcase_name());
    857 }
    858 
    859 TEST_F(StylizedFieldNamesTest, FindByLowercaseName) {
    860   EXPECT_EQ(message_->field(0),
    861             message_->FindFieldByLowercaseName("foo_foo"));
    862   EXPECT_EQ(message_->field(1),
    863             message_->FindFieldByLowercaseName("foobar"));
    864   EXPECT_EQ(message_->field(2),
    865             message_->FindFieldByLowercaseName("foobaz"));
    866   EXPECT_TRUE(message_->FindFieldByLowercaseName("FooBar") == NULL);
    867   EXPECT_TRUE(message_->FindFieldByLowercaseName("fooBaz") == NULL);
    868   EXPECT_TRUE(message_->FindFieldByLowercaseName("bar_foo") == NULL);
    869   EXPECT_TRUE(message_->FindFieldByLowercaseName("nosuchfield") == NULL);
    870 
    871   EXPECT_EQ(message_->extension(0),
    872             message_->FindExtensionByLowercaseName("bar_foo"));
    873   EXPECT_EQ(message_->extension(1),
    874             message_->FindExtensionByLowercaseName("barbar"));
    875   EXPECT_EQ(message_->extension(2),
    876             message_->FindExtensionByLowercaseName("barbaz"));
    877   EXPECT_TRUE(message_->FindExtensionByLowercaseName("BarBar") == NULL);
    878   EXPECT_TRUE(message_->FindExtensionByLowercaseName("barBaz") == NULL);
    879   EXPECT_TRUE(message_->FindExtensionByLowercaseName("foo_foo") == NULL);
    880   EXPECT_TRUE(message_->FindExtensionByLowercaseName("nosuchfield") == NULL);
    881 
    882   EXPECT_EQ(file_->extension(0),
    883             file_->FindExtensionByLowercaseName("baz_foo"));
    884   EXPECT_EQ(file_->extension(1),
    885             file_->FindExtensionByLowercaseName("bazbar"));
    886   EXPECT_EQ(file_->extension(2),
    887             file_->FindExtensionByLowercaseName("bazbaz"));
    888   EXPECT_TRUE(file_->FindExtensionByLowercaseName("BazBar") == NULL);
    889   EXPECT_TRUE(file_->FindExtensionByLowercaseName("bazBaz") == NULL);
    890   EXPECT_TRUE(file_->FindExtensionByLowercaseName("nosuchfield") == NULL);
    891 }
    892 
    893 TEST_F(StylizedFieldNamesTest, FindByCamelcaseName) {
    894   EXPECT_EQ(message_->field(0),
    895             message_->FindFieldByCamelcaseName("fooFoo"));
    896   EXPECT_EQ(message_->field(1),
    897             message_->FindFieldByCamelcaseName("fooBar"));
    898   EXPECT_EQ(message_->field(2),
    899             message_->FindFieldByCamelcaseName("fooBaz"));
    900   EXPECT_TRUE(message_->FindFieldByCamelcaseName("foo_foo") == NULL);
    901   EXPECT_TRUE(message_->FindFieldByCamelcaseName("FooBar") == NULL);
    902   EXPECT_TRUE(message_->FindFieldByCamelcaseName("barFoo") == NULL);
    903   EXPECT_TRUE(message_->FindFieldByCamelcaseName("nosuchfield") == NULL);
    904 
    905   EXPECT_EQ(message_->extension(0),
    906             message_->FindExtensionByCamelcaseName("barFoo"));
    907   EXPECT_EQ(message_->extension(1),
    908             message_->FindExtensionByCamelcaseName("barBar"));
    909   EXPECT_EQ(message_->extension(2),
    910             message_->FindExtensionByCamelcaseName("barBaz"));
    911   EXPECT_TRUE(message_->FindExtensionByCamelcaseName("bar_foo") == NULL);
    912   EXPECT_TRUE(message_->FindExtensionByCamelcaseName("BarBar") == NULL);
    913   EXPECT_TRUE(message_->FindExtensionByCamelcaseName("fooFoo") == NULL);
    914   EXPECT_TRUE(message_->FindExtensionByCamelcaseName("nosuchfield") == NULL);
    915 
    916   EXPECT_EQ(file_->extension(0),
    917             file_->FindExtensionByCamelcaseName("bazFoo"));
    918   EXPECT_EQ(file_->extension(1),
    919             file_->FindExtensionByCamelcaseName("bazBar"));
    920   EXPECT_EQ(file_->extension(2),
    921             file_->FindExtensionByCamelcaseName("bazBaz"));
    922   EXPECT_TRUE(file_->FindExtensionByCamelcaseName("baz_foo") == NULL);
    923   EXPECT_TRUE(file_->FindExtensionByCamelcaseName("BazBar") == NULL);
    924   EXPECT_TRUE(file_->FindExtensionByCamelcaseName("nosuchfield") == NULL);
    925 }
    926 
    927 // ===================================================================
    928 
    929 // Test enum descriptors.
    930 class EnumDescriptorTest : public testing::Test {
    931  protected:
    932   virtual void SetUp() {
    933     // Build descriptors for the following definitions:
    934     //
    935     //   // in "foo.proto"
    936     //   enum TestEnum {
    937     //     FOO = 1;
    938     //     BAR = 2;
    939     //   }
    940     //
    941     //   // in "bar.proto"
    942     //   package corge.grault;
    943     //   enum TestEnum2 {
    944     //     FOO = 1;
    945     //     BAZ = 3;
    946     //   }
    947     //
    948     // TestEnum2 is primarily here to test FindValueByName and friends.
    949     // All enums created from the same DescriptorPool share the same lookup
    950     // table, so we need to insure that they don't interfere.
    951 
    952     // TestEnum
    953     FileDescriptorProto foo_file;
    954     foo_file.set_name("foo.proto");
    955 
    956     EnumDescriptorProto* enum_proto = AddEnum(&foo_file, "TestEnum");
    957     AddEnumValue(enum_proto, "FOO", 1);
    958     AddEnumValue(enum_proto, "BAR", 2);
    959 
    960     // TestEnum2
    961     FileDescriptorProto bar_file;
    962     bar_file.set_name("bar.proto");
    963     bar_file.set_package("corge.grault");
    964 
    965     EnumDescriptorProto* enum2_proto = AddEnum(&bar_file, "TestEnum2");
    966     AddEnumValue(enum2_proto, "FOO", 1);
    967     AddEnumValue(enum2_proto, "BAZ", 3);
    968 
    969     // Build the descriptors and get the pointers.
    970     foo_file_ = pool_.BuildFile(foo_file);
    971     ASSERT_TRUE(foo_file_ != NULL);
    972 
    973     bar_file_ = pool_.BuildFile(bar_file);
    974     ASSERT_TRUE(bar_file_ != NULL);
    975 
    976     ASSERT_EQ(1, foo_file_->enum_type_count());
    977     enum_ = foo_file_->enum_type(0);
    978 
    979     ASSERT_EQ(2, enum_->value_count());
    980     foo_ = enum_->value(0);
    981     bar_ = enum_->value(1);
    982 
    983     ASSERT_EQ(1, bar_file_->enum_type_count());
    984     enum2_ = bar_file_->enum_type(0);
    985 
    986     ASSERT_EQ(2, enum2_->value_count());
    987     foo2_ = enum2_->value(0);
    988     baz2_ = enum2_->value(1);
    989   }
    990 
    991   DescriptorPool pool_;
    992 
    993   const FileDescriptor* foo_file_;
    994   const FileDescriptor* bar_file_;
    995 
    996   const EnumDescriptor* enum_;
    997   const EnumDescriptor* enum2_;
    998 
    999   const EnumValueDescriptor* foo_;
   1000   const EnumValueDescriptor* bar_;
   1001 
   1002   const EnumValueDescriptor* foo2_;
   1003   const EnumValueDescriptor* baz2_;
   1004 };
   1005 
   1006 TEST_F(EnumDescriptorTest, Name) {
   1007   EXPECT_EQ("TestEnum", enum_->name());
   1008   EXPECT_EQ("TestEnum", enum_->full_name());
   1009   EXPECT_EQ(foo_file_, enum_->file());
   1010 
   1011   EXPECT_EQ("TestEnum2", enum2_->name());
   1012   EXPECT_EQ("corge.grault.TestEnum2", enum2_->full_name());
   1013   EXPECT_EQ(bar_file_, enum2_->file());
   1014 }
   1015 
   1016 TEST_F(EnumDescriptorTest, ContainingType) {
   1017   EXPECT_TRUE(enum_->containing_type() == NULL);
   1018   EXPECT_TRUE(enum2_->containing_type() == NULL);
   1019 }
   1020 
   1021 TEST_F(EnumDescriptorTest, ValuesByIndex) {
   1022   ASSERT_EQ(2, enum_->value_count());
   1023   EXPECT_EQ(foo_, enum_->value(0));
   1024   EXPECT_EQ(bar_, enum_->value(1));
   1025 }
   1026 
   1027 TEST_F(EnumDescriptorTest, FindValueByName) {
   1028   EXPECT_EQ(foo_ , enum_ ->FindValueByName("FOO"));
   1029   EXPECT_EQ(bar_ , enum_ ->FindValueByName("BAR"));
   1030   EXPECT_EQ(foo2_, enum2_->FindValueByName("FOO"));
   1031   EXPECT_EQ(baz2_, enum2_->FindValueByName("BAZ"));
   1032 
   1033   EXPECT_TRUE(enum_ ->FindValueByName("NO_SUCH_VALUE") == NULL);
   1034   EXPECT_TRUE(enum_ ->FindValueByName("BAZ"          ) == NULL);
   1035   EXPECT_TRUE(enum2_->FindValueByName("BAR"          ) == NULL);
   1036 }
   1037 
   1038 TEST_F(EnumDescriptorTest, FindValueByNumber) {
   1039   EXPECT_EQ(foo_ , enum_ ->FindValueByNumber(1));
   1040   EXPECT_EQ(bar_ , enum_ ->FindValueByNumber(2));
   1041   EXPECT_EQ(foo2_, enum2_->FindValueByNumber(1));
   1042   EXPECT_EQ(baz2_, enum2_->FindValueByNumber(3));
   1043 
   1044   EXPECT_TRUE(enum_ ->FindValueByNumber(416) == NULL);
   1045   EXPECT_TRUE(enum_ ->FindValueByNumber(3) == NULL);
   1046   EXPECT_TRUE(enum2_->FindValueByNumber(2) == NULL);
   1047 }
   1048 
   1049 TEST_F(EnumDescriptorTest, ValueName) {
   1050   EXPECT_EQ("FOO", foo_->name());
   1051   EXPECT_EQ("BAR", bar_->name());
   1052 }
   1053 
   1054 TEST_F(EnumDescriptorTest, ValueFullName) {
   1055   EXPECT_EQ("FOO", foo_->full_name());
   1056   EXPECT_EQ("BAR", bar_->full_name());
   1057   EXPECT_EQ("corge.grault.FOO", foo2_->full_name());
   1058   EXPECT_EQ("corge.grault.BAZ", baz2_->full_name());
   1059 }
   1060 
   1061 TEST_F(EnumDescriptorTest, ValueIndex) {
   1062   EXPECT_EQ(0, foo_->index());
   1063   EXPECT_EQ(1, bar_->index());
   1064 }
   1065 
   1066 TEST_F(EnumDescriptorTest, ValueNumber) {
   1067   EXPECT_EQ(1, foo_->number());
   1068   EXPECT_EQ(2, bar_->number());
   1069 }
   1070 
   1071 TEST_F(EnumDescriptorTest, ValueType) {
   1072   EXPECT_EQ(enum_ , foo_ ->type());
   1073   EXPECT_EQ(enum_ , bar_ ->type());
   1074   EXPECT_EQ(enum2_, foo2_->type());
   1075   EXPECT_EQ(enum2_, baz2_->type());
   1076 }
   1077 
   1078 // ===================================================================
   1079 
   1080 // Test service descriptors.
   1081 class ServiceDescriptorTest : public testing::Test {
   1082  protected:
   1083   virtual void SetUp() {
   1084     // Build descriptors for the following messages and service:
   1085     //    // in "foo.proto"
   1086     //    message FooRequest  {}
   1087     //    message FooResponse {}
   1088     //    message BarRequest  {}
   1089     //    message BarResponse {}
   1090     //    message BazRequest  {}
   1091     //    message BazResponse {}
   1092     //
   1093     //    service TestService {
   1094     //      rpc Foo(FooRequest) returns (FooResponse);
   1095     //      rpc Bar(BarRequest) returns (BarResponse);
   1096     //    }
   1097     //
   1098     //    // in "bar.proto"
   1099     //    package corge.grault
   1100     //    service TestService2 {
   1101     //      rpc Foo(FooRequest) returns (FooResponse);
   1102     //      rpc Baz(BazRequest) returns (BazResponse);
   1103     //    }
   1104 
   1105     FileDescriptorProto foo_file;
   1106     foo_file.set_name("foo.proto");
   1107 
   1108     AddMessage(&foo_file, "FooRequest");
   1109     AddMessage(&foo_file, "FooResponse");
   1110     AddMessage(&foo_file, "BarRequest");
   1111     AddMessage(&foo_file, "BarResponse");
   1112     AddMessage(&foo_file, "BazRequest");
   1113     AddMessage(&foo_file, "BazResponse");
   1114 
   1115     ServiceDescriptorProto* service = AddService(&foo_file, "TestService");
   1116     AddMethod(service, "Foo", "FooRequest", "FooResponse");
   1117     AddMethod(service, "Bar", "BarRequest", "BarResponse");
   1118 
   1119     FileDescriptorProto bar_file;
   1120     bar_file.set_name("bar.proto");
   1121     bar_file.set_package("corge.grault");
   1122     bar_file.add_dependency("foo.proto");
   1123 
   1124     ServiceDescriptorProto* service2 = AddService(&bar_file, "TestService2");
   1125     AddMethod(service2, "Foo", "FooRequest", "FooResponse");
   1126     AddMethod(service2, "Baz", "BazRequest", "BazResponse");
   1127 
   1128     // Build the descriptors and get the pointers.
   1129     foo_file_ = pool_.BuildFile(foo_file);
   1130     ASSERT_TRUE(foo_file_ != NULL);
   1131 
   1132     bar_file_ = pool_.BuildFile(bar_file);
   1133     ASSERT_TRUE(bar_file_ != NULL);
   1134 
   1135     ASSERT_EQ(6, foo_file_->message_type_count());
   1136     foo_request_  = foo_file_->message_type(0);
   1137     foo_response_ = foo_file_->message_type(1);
   1138     bar_request_  = foo_file_->message_type(2);
   1139     bar_response_ = foo_file_->message_type(3);
   1140     baz_request_  = foo_file_->message_type(4);
   1141     baz_response_ = foo_file_->message_type(5);
   1142 
   1143     ASSERT_EQ(1, foo_file_->service_count());
   1144     service_ = foo_file_->service(0);
   1145 
   1146     ASSERT_EQ(2, service_->method_count());
   1147     foo_ = service_->method(0);
   1148     bar_ = service_->method(1);
   1149 
   1150     ASSERT_EQ(1, bar_file_->service_count());
   1151     service2_ = bar_file_->service(0);
   1152 
   1153     ASSERT_EQ(2, service2_->method_count());
   1154     foo2_ = service2_->method(0);
   1155     baz2_ = service2_->method(1);
   1156   }
   1157 
   1158   DescriptorPool pool_;
   1159 
   1160   const FileDescriptor* foo_file_;
   1161   const FileDescriptor* bar_file_;
   1162 
   1163   const Descriptor* foo_request_;
   1164   const Descriptor* foo_response_;
   1165   const Descriptor* bar_request_;
   1166   const Descriptor* bar_response_;
   1167   const Descriptor* baz_request_;
   1168   const Descriptor* baz_response_;
   1169 
   1170   const ServiceDescriptor* service_;
   1171   const ServiceDescriptor* service2_;
   1172 
   1173   const MethodDescriptor* foo_;
   1174   const MethodDescriptor* bar_;
   1175 
   1176   const MethodDescriptor* foo2_;
   1177   const MethodDescriptor* baz2_;
   1178 };
   1179 
   1180 TEST_F(ServiceDescriptorTest, Name) {
   1181   EXPECT_EQ("TestService", service_->name());
   1182   EXPECT_EQ("TestService", service_->full_name());
   1183   EXPECT_EQ(foo_file_, service_->file());
   1184 
   1185   EXPECT_EQ("TestService2", service2_->name());
   1186   EXPECT_EQ("corge.grault.TestService2", service2_->full_name());
   1187   EXPECT_EQ(bar_file_, service2_->file());
   1188 }
   1189 
   1190 TEST_F(ServiceDescriptorTest, MethodsByIndex) {
   1191   ASSERT_EQ(2, service_->method_count());
   1192   EXPECT_EQ(foo_, service_->method(0));
   1193   EXPECT_EQ(bar_, service_->method(1));
   1194 }
   1195 
   1196 TEST_F(ServiceDescriptorTest, FindMethodByName) {
   1197   EXPECT_EQ(foo_ , service_ ->FindMethodByName("Foo"));
   1198   EXPECT_EQ(bar_ , service_ ->FindMethodByName("Bar"));
   1199   EXPECT_EQ(foo2_, service2_->FindMethodByName("Foo"));
   1200   EXPECT_EQ(baz2_, service2_->FindMethodByName("Baz"));
   1201 
   1202   EXPECT_TRUE(service_ ->FindMethodByName("NoSuchMethod") == NULL);
   1203   EXPECT_TRUE(service_ ->FindMethodByName("Baz"         ) == NULL);
   1204   EXPECT_TRUE(service2_->FindMethodByName("Bar"         ) == NULL);
   1205 }
   1206 
   1207 TEST_F(ServiceDescriptorTest, MethodName) {
   1208   EXPECT_EQ("Foo", foo_->name());
   1209   EXPECT_EQ("Bar", bar_->name());
   1210 }
   1211 
   1212 TEST_F(ServiceDescriptorTest, MethodFullName) {
   1213   EXPECT_EQ("TestService.Foo", foo_->full_name());
   1214   EXPECT_EQ("TestService.Bar", bar_->full_name());
   1215   EXPECT_EQ("corge.grault.TestService2.Foo", foo2_->full_name());
   1216   EXPECT_EQ("corge.grault.TestService2.Baz", baz2_->full_name());
   1217 }
   1218 
   1219 TEST_F(ServiceDescriptorTest, MethodIndex) {
   1220   EXPECT_EQ(0, foo_->index());
   1221   EXPECT_EQ(1, bar_->index());
   1222 }
   1223 
   1224 TEST_F(ServiceDescriptorTest, MethodParent) {
   1225   EXPECT_EQ(service_, foo_->service());
   1226   EXPECT_EQ(service_, bar_->service());
   1227 }
   1228 
   1229 TEST_F(ServiceDescriptorTest, MethodInputType) {
   1230   EXPECT_EQ(foo_request_, foo_->input_type());
   1231   EXPECT_EQ(bar_request_, bar_->input_type());
   1232 }
   1233 
   1234 TEST_F(ServiceDescriptorTest, MethodOutputType) {
   1235   EXPECT_EQ(foo_response_, foo_->output_type());
   1236   EXPECT_EQ(bar_response_, bar_->output_type());
   1237 }
   1238 
   1239 // ===================================================================
   1240 
   1241 // Test nested types.
   1242 class NestedDescriptorTest : public testing::Test {
   1243  protected:
   1244   virtual void SetUp() {
   1245     // Build descriptors for the following definitions:
   1246     //
   1247     //   // in "foo.proto"
   1248     //   message TestMessage {
   1249     //     message Foo {}
   1250     //     message Bar {}
   1251     //     enum Baz { A = 1; }
   1252     //     enum Qux { B = 1; }
   1253     //   }
   1254     //
   1255     //   // in "bar.proto"
   1256     //   package corge.grault;
   1257     //   message TestMessage2 {
   1258     //     message Foo {}
   1259     //     message Baz {}
   1260     //     enum Qux  { A = 1; }
   1261     //     enum Quux { C = 1; }
   1262     //   }
   1263     //
   1264     // TestMessage2 is primarily here to test FindNestedTypeByName and friends.
   1265     // All messages created from the same DescriptorPool share the same lookup
   1266     // table, so we need to insure that they don't interfere.
   1267     //
   1268     // We add enum values to the enums in order to test searching for enum
   1269     // values across a message's scope.
   1270 
   1271     FileDescriptorProto foo_file;
   1272     foo_file.set_name("foo.proto");
   1273 
   1274     DescriptorProto* message = AddMessage(&foo_file, "TestMessage");
   1275     AddNestedMessage(message, "Foo");
   1276     AddNestedMessage(message, "Bar");
   1277     EnumDescriptorProto* baz = AddNestedEnum(message, "Baz");
   1278     AddEnumValue(baz, "A", 1);
   1279     EnumDescriptorProto* qux = AddNestedEnum(message, "Qux");
   1280     AddEnumValue(qux, "B", 1);
   1281 
   1282     FileDescriptorProto bar_file;
   1283     bar_file.set_name("bar.proto");
   1284     bar_file.set_package("corge.grault");
   1285 
   1286     DescriptorProto* message2 = AddMessage(&bar_file, "TestMessage2");
   1287     AddNestedMessage(message2, "Foo");
   1288     AddNestedMessage(message2, "Baz");
   1289     EnumDescriptorProto* qux2 = AddNestedEnum(message2, "Qux");
   1290     AddEnumValue(qux2, "A", 1);
   1291     EnumDescriptorProto* quux2 = AddNestedEnum(message2, "Quux");
   1292     AddEnumValue(quux2, "C", 1);
   1293 
   1294     // Build the descriptors and get the pointers.
   1295     foo_file_ = pool_.BuildFile(foo_file);
   1296     ASSERT_TRUE(foo_file_ != NULL);
   1297 
   1298     bar_file_ = pool_.BuildFile(bar_file);
   1299     ASSERT_TRUE(bar_file_ != NULL);
   1300 
   1301     ASSERT_EQ(1, foo_file_->message_type_count());
   1302     message_ = foo_file_->message_type(0);
   1303 
   1304     ASSERT_EQ(2, message_->nested_type_count());
   1305     foo_ = message_->nested_type(0);
   1306     bar_ = message_->nested_type(1);
   1307 
   1308     ASSERT_EQ(2, message_->enum_type_count());
   1309     baz_ = message_->enum_type(0);
   1310     qux_ = message_->enum_type(1);
   1311 
   1312     ASSERT_EQ(1, baz_->value_count());
   1313     a_ = baz_->value(0);
   1314     ASSERT_EQ(1, qux_->value_count());
   1315     b_ = qux_->value(0);
   1316 
   1317     ASSERT_EQ(1, bar_file_->message_type_count());
   1318     message2_ = bar_file_->message_type(0);
   1319 
   1320     ASSERT_EQ(2, message2_->nested_type_count());
   1321     foo2_ = message2_->nested_type(0);
   1322     baz2_ = message2_->nested_type(1);
   1323 
   1324     ASSERT_EQ(2, message2_->enum_type_count());
   1325     qux2_ = message2_->enum_type(0);
   1326     quux2_ = message2_->enum_type(1);
   1327 
   1328     ASSERT_EQ(1, qux2_->value_count());
   1329     a2_ = qux2_->value(0);
   1330     ASSERT_EQ(1, quux2_->value_count());
   1331     c2_ = quux2_->value(0);
   1332   }
   1333 
   1334   DescriptorPool pool_;
   1335 
   1336   const FileDescriptor* foo_file_;
   1337   const FileDescriptor* bar_file_;
   1338 
   1339   const Descriptor* message_;
   1340   const Descriptor* message2_;
   1341 
   1342   const Descriptor* foo_;
   1343   const Descriptor* bar_;
   1344   const EnumDescriptor* baz_;
   1345   const EnumDescriptor* qux_;
   1346   const EnumValueDescriptor* a_;
   1347   const EnumValueDescriptor* b_;
   1348 
   1349   const Descriptor* foo2_;
   1350   const Descriptor* baz2_;
   1351   const EnumDescriptor* qux2_;
   1352   const EnumDescriptor* quux2_;
   1353   const EnumValueDescriptor* a2_;
   1354   const EnumValueDescriptor* c2_;
   1355 };
   1356 
   1357 TEST_F(NestedDescriptorTest, MessageName) {
   1358   EXPECT_EQ("Foo", foo_ ->name());
   1359   EXPECT_EQ("Bar", bar_ ->name());
   1360   EXPECT_EQ("Foo", foo2_->name());
   1361   EXPECT_EQ("Baz", baz2_->name());
   1362 
   1363   EXPECT_EQ("TestMessage.Foo", foo_->full_name());
   1364   EXPECT_EQ("TestMessage.Bar", bar_->full_name());
   1365   EXPECT_EQ("corge.grault.TestMessage2.Foo", foo2_->full_name());
   1366   EXPECT_EQ("corge.grault.TestMessage2.Baz", baz2_->full_name());
   1367 }
   1368 
   1369 TEST_F(NestedDescriptorTest, MessageContainingType) {
   1370   EXPECT_EQ(message_ , foo_ ->containing_type());
   1371   EXPECT_EQ(message_ , bar_ ->containing_type());
   1372   EXPECT_EQ(message2_, foo2_->containing_type());
   1373   EXPECT_EQ(message2_, baz2_->containing_type());
   1374 }
   1375 
   1376 TEST_F(NestedDescriptorTest, NestedMessagesByIndex) {
   1377   ASSERT_EQ(2, message_->nested_type_count());
   1378   EXPECT_EQ(foo_, message_->nested_type(0));
   1379   EXPECT_EQ(bar_, message_->nested_type(1));
   1380 }
   1381 
   1382 TEST_F(NestedDescriptorTest, FindFieldByNameDoesntFindNestedTypes) {
   1383   EXPECT_TRUE(message_->FindFieldByName("Foo") == NULL);
   1384   EXPECT_TRUE(message_->FindFieldByName("Qux") == NULL);
   1385   EXPECT_TRUE(message_->FindExtensionByName("Foo") == NULL);
   1386   EXPECT_TRUE(message_->FindExtensionByName("Qux") == NULL);
   1387 }
   1388 
   1389 TEST_F(NestedDescriptorTest, FindNestedTypeByName) {
   1390   EXPECT_EQ(foo_ , message_ ->FindNestedTypeByName("Foo"));
   1391   EXPECT_EQ(bar_ , message_ ->FindNestedTypeByName("Bar"));
   1392   EXPECT_EQ(foo2_, message2_->FindNestedTypeByName("Foo"));
   1393   EXPECT_EQ(baz2_, message2_->FindNestedTypeByName("Baz"));
   1394 
   1395   EXPECT_TRUE(message_ ->FindNestedTypeByName("NoSuchType") == NULL);
   1396   EXPECT_TRUE(message_ ->FindNestedTypeByName("Baz"       ) == NULL);
   1397   EXPECT_TRUE(message2_->FindNestedTypeByName("Bar"       ) == NULL);
   1398 
   1399   EXPECT_TRUE(message_->FindNestedTypeByName("Qux") == NULL);
   1400 }
   1401 
   1402 TEST_F(NestedDescriptorTest, EnumName) {
   1403   EXPECT_EQ("Baz" , baz_ ->name());
   1404   EXPECT_EQ("Qux" , qux_ ->name());
   1405   EXPECT_EQ("Qux" , qux2_->name());
   1406   EXPECT_EQ("Quux", quux2_->name());
   1407 
   1408   EXPECT_EQ("TestMessage.Baz", baz_->full_name());
   1409   EXPECT_EQ("TestMessage.Qux", qux_->full_name());
   1410   EXPECT_EQ("corge.grault.TestMessage2.Qux" , qux2_ ->full_name());
   1411   EXPECT_EQ("corge.grault.TestMessage2.Quux", quux2_->full_name());
   1412 }
   1413 
   1414 TEST_F(NestedDescriptorTest, EnumContainingType) {
   1415   EXPECT_EQ(message_ , baz_  ->containing_type());
   1416   EXPECT_EQ(message_ , qux_  ->containing_type());
   1417   EXPECT_EQ(message2_, qux2_ ->containing_type());
   1418   EXPECT_EQ(message2_, quux2_->containing_type());
   1419 }
   1420 
   1421 TEST_F(NestedDescriptorTest, NestedEnumsByIndex) {
   1422   ASSERT_EQ(2, message_->nested_type_count());
   1423   EXPECT_EQ(foo_, message_->nested_type(0));
   1424   EXPECT_EQ(bar_, message_->nested_type(1));
   1425 }
   1426 
   1427 TEST_F(NestedDescriptorTest, FindEnumTypeByName) {
   1428   EXPECT_EQ(baz_  , message_ ->FindEnumTypeByName("Baz" ));
   1429   EXPECT_EQ(qux_  , message_ ->FindEnumTypeByName("Qux" ));
   1430   EXPECT_EQ(qux2_ , message2_->FindEnumTypeByName("Qux" ));
   1431   EXPECT_EQ(quux2_, message2_->FindEnumTypeByName("Quux"));
   1432 
   1433   EXPECT_TRUE(message_ ->FindEnumTypeByName("NoSuchType") == NULL);
   1434   EXPECT_TRUE(message_ ->FindEnumTypeByName("Quux"      ) == NULL);
   1435   EXPECT_TRUE(message2_->FindEnumTypeByName("Baz"       ) == NULL);
   1436 
   1437   EXPECT_TRUE(message_->FindEnumTypeByName("Foo") == NULL);
   1438 }
   1439 
   1440 TEST_F(NestedDescriptorTest, FindEnumValueByName) {
   1441   EXPECT_EQ(a_ , message_ ->FindEnumValueByName("A"));
   1442   EXPECT_EQ(b_ , message_ ->FindEnumValueByName("B"));
   1443   EXPECT_EQ(a2_, message2_->FindEnumValueByName("A"));
   1444   EXPECT_EQ(c2_, message2_->FindEnumValueByName("C"));
   1445 
   1446   EXPECT_TRUE(message_ ->FindEnumValueByName("NO_SUCH_VALUE") == NULL);
   1447   EXPECT_TRUE(message_ ->FindEnumValueByName("C"            ) == NULL);
   1448   EXPECT_TRUE(message2_->FindEnumValueByName("B"            ) == NULL);
   1449 
   1450   EXPECT_TRUE(message_->FindEnumValueByName("Foo") == NULL);
   1451 }
   1452 
   1453 // ===================================================================
   1454 
   1455 // Test extensions.
   1456 class ExtensionDescriptorTest : public testing::Test {
   1457  protected:
   1458   virtual void SetUp() {
   1459     // Build descriptors for the following definitions:
   1460     //
   1461     //   enum Baz {}
   1462     //   message Qux {}
   1463     //
   1464     //   message Foo {
   1465     //     extensions 10 to 19;
   1466     //     extensions 30 to 39;
   1467     //   }
   1468     //   extends Foo with optional int32 foo_int32 = 10;
   1469     //   extends Foo with repeated TestEnum foo_enum = 19;
   1470     //   message Bar {
   1471     //     extends Foo with optional Qux foo_message = 30;
   1472     //     // (using Qux as the group type)
   1473     //     extends Foo with repeated group foo_group = 39;
   1474     //   }
   1475 
   1476     FileDescriptorProto foo_file;
   1477     foo_file.set_name("foo.proto");
   1478 
   1479     AddEmptyEnum(&foo_file, "Baz");
   1480     AddMessage(&foo_file, "Qux");
   1481 
   1482     DescriptorProto* foo = AddMessage(&foo_file, "Foo");
   1483     AddExtensionRange(foo, 10, 20);
   1484     AddExtensionRange(foo, 30, 40);
   1485 
   1486     AddExtension(&foo_file, "Foo", "foo_int32", 10,
   1487                  FieldDescriptorProto::LABEL_OPTIONAL,
   1488                  FieldDescriptorProto::TYPE_INT32);
   1489     AddExtension(&foo_file, "Foo", "foo_enum", 19,
   1490                  FieldDescriptorProto::LABEL_REPEATED,
   1491                  FieldDescriptorProto::TYPE_ENUM)
   1492       ->set_type_name("Baz");
   1493 
   1494     DescriptorProto* bar = AddMessage(&foo_file, "Bar");
   1495     AddNestedExtension(bar, "Foo", "foo_message", 30,
   1496                        FieldDescriptorProto::LABEL_OPTIONAL,
   1497                        FieldDescriptorProto::TYPE_MESSAGE)
   1498       ->set_type_name("Qux");
   1499     AddNestedExtension(bar, "Foo", "foo_group", 39,
   1500                        FieldDescriptorProto::LABEL_REPEATED,
   1501                        FieldDescriptorProto::TYPE_GROUP)
   1502       ->set_type_name("Qux");
   1503 
   1504     // Build the descriptors and get the pointers.
   1505     foo_file_ = pool_.BuildFile(foo_file);
   1506     ASSERT_TRUE(foo_file_ != NULL);
   1507 
   1508     ASSERT_EQ(1, foo_file_->enum_type_count());
   1509     baz_ = foo_file_->enum_type(0);
   1510 
   1511     ASSERT_EQ(3, foo_file_->message_type_count());
   1512     qux_ = foo_file_->message_type(0);
   1513     foo_ = foo_file_->message_type(1);
   1514     bar_ = foo_file_->message_type(2);
   1515   }
   1516 
   1517   DescriptorPool pool_;
   1518 
   1519   const FileDescriptor* foo_file_;
   1520 
   1521   const Descriptor* foo_;
   1522   const Descriptor* bar_;
   1523   const EnumDescriptor* baz_;
   1524   const Descriptor* qux_;
   1525 };
   1526 
   1527 TEST_F(ExtensionDescriptorTest, ExtensionRanges) {
   1528   EXPECT_EQ(0, bar_->extension_range_count());
   1529   ASSERT_EQ(2, foo_->extension_range_count());
   1530 
   1531   EXPECT_EQ(10, foo_->extension_range(0)->start);
   1532   EXPECT_EQ(30, foo_->extension_range(1)->start);
   1533 
   1534   EXPECT_EQ(20, foo_->extension_range(0)->end);
   1535   EXPECT_EQ(40, foo_->extension_range(1)->end);
   1536 };
   1537 
   1538 TEST_F(ExtensionDescriptorTest, Extensions) {
   1539   EXPECT_EQ(0, foo_->extension_count());
   1540   ASSERT_EQ(2, foo_file_->extension_count());
   1541   ASSERT_EQ(2, bar_->extension_count());
   1542 
   1543   EXPECT_TRUE(foo_file_->extension(0)->is_extension());
   1544   EXPECT_TRUE(foo_file_->extension(1)->is_extension());
   1545   EXPECT_TRUE(bar_->extension(0)->is_extension());
   1546   EXPECT_TRUE(bar_->extension(1)->is_extension());
   1547 
   1548   EXPECT_EQ("foo_int32"  , foo_file_->extension(0)->name());
   1549   EXPECT_EQ("foo_enum"   , foo_file_->extension(1)->name());
   1550   EXPECT_EQ("foo_message", bar_->extension(0)->name());
   1551   EXPECT_EQ("foo_group"  , bar_->extension(1)->name());
   1552 
   1553   EXPECT_EQ(10, foo_file_->extension(0)->number());
   1554   EXPECT_EQ(19, foo_file_->extension(1)->number());
   1555   EXPECT_EQ(30, bar_->extension(0)->number());
   1556   EXPECT_EQ(39, bar_->extension(1)->number());
   1557 
   1558   EXPECT_EQ(FieldDescriptor::TYPE_INT32  , foo_file_->extension(0)->type());
   1559   EXPECT_EQ(FieldDescriptor::TYPE_ENUM   , foo_file_->extension(1)->type());
   1560   EXPECT_EQ(FieldDescriptor::TYPE_MESSAGE, bar_->extension(0)->type());
   1561   EXPECT_EQ(FieldDescriptor::TYPE_GROUP  , bar_->extension(1)->type());
   1562 
   1563   EXPECT_EQ(baz_, foo_file_->extension(1)->enum_type());
   1564   EXPECT_EQ(qux_, bar_->extension(0)->message_type());
   1565   EXPECT_EQ(qux_, bar_->extension(1)->message_type());
   1566 
   1567   EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, foo_file_->extension(0)->label());
   1568   EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, foo_file_->extension(1)->label());
   1569   EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, bar_->extension(0)->label());
   1570   EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, bar_->extension(1)->label());
   1571 
   1572   EXPECT_EQ(foo_, foo_file_->extension(0)->containing_type());
   1573   EXPECT_EQ(foo_, foo_file_->extension(1)->containing_type());
   1574   EXPECT_EQ(foo_, bar_->extension(0)->containing_type());
   1575   EXPECT_EQ(foo_, bar_->extension(1)->containing_type());
   1576 
   1577   EXPECT_TRUE(foo_file_->extension(0)->extension_scope() == NULL);
   1578   EXPECT_TRUE(foo_file_->extension(1)->extension_scope() == NULL);
   1579   EXPECT_EQ(bar_, bar_->extension(0)->extension_scope());
   1580   EXPECT_EQ(bar_, bar_->extension(1)->extension_scope());
   1581 };
   1582 
   1583 TEST_F(ExtensionDescriptorTest, IsExtensionNumber) {
   1584   EXPECT_FALSE(foo_->IsExtensionNumber( 9));
   1585   EXPECT_TRUE (foo_->IsExtensionNumber(10));
   1586   EXPECT_TRUE (foo_->IsExtensionNumber(19));
   1587   EXPECT_FALSE(foo_->IsExtensionNumber(20));
   1588   EXPECT_FALSE(foo_->IsExtensionNumber(29));
   1589   EXPECT_TRUE (foo_->IsExtensionNumber(30));
   1590   EXPECT_TRUE (foo_->IsExtensionNumber(39));
   1591   EXPECT_FALSE(foo_->IsExtensionNumber(40));
   1592 }
   1593 
   1594 TEST_F(ExtensionDescriptorTest, FindExtensionByName) {
   1595   // Note that FileDescriptor::FindExtensionByName() is tested by
   1596   // FileDescriptorTest.
   1597   ASSERT_EQ(2, bar_->extension_count());
   1598 
   1599   EXPECT_EQ(bar_->extension(0), bar_->FindExtensionByName("foo_message"));
   1600   EXPECT_EQ(bar_->extension(1), bar_->FindExtensionByName("foo_group"  ));
   1601 
   1602   EXPECT_TRUE(bar_->FindExtensionByName("no_such_extension") == NULL);
   1603   EXPECT_TRUE(foo_->FindExtensionByName("foo_int32") == NULL);
   1604   EXPECT_TRUE(foo_->FindExtensionByName("foo_message") == NULL);
   1605 }
   1606 
   1607 TEST_F(ExtensionDescriptorTest, FindAllExtensions) {
   1608   vector<const FieldDescriptor*> extensions;
   1609   pool_.FindAllExtensions(foo_, &extensions);
   1610   ASSERT_EQ(4, extensions.size());
   1611   EXPECT_EQ(10, extensions[0]->number());
   1612   EXPECT_EQ(19, extensions[1]->number());
   1613   EXPECT_EQ(30, extensions[2]->number());
   1614   EXPECT_EQ(39, extensions[3]->number());
   1615 }
   1616 
   1617 TEST_F(ExtensionDescriptorTest, DuplicateFieldNumber) {
   1618   DescriptorPool pool;
   1619   FileDescriptorProto file_proto;
   1620   // Add "google/protobuf/descriptor.proto".
   1621   FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
   1622   ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
   1623   // Add "foo.proto":
   1624   //   import "google/protobuf/descriptor.proto";
   1625   //   extend google.protobuf.FieldOptions {
   1626   //     optional int32 option1 = 1000;
   1627   //   }
   1628   file_proto.Clear();
   1629   file_proto.set_name("foo.proto");
   1630   file_proto.add_dependency("google/protobuf/descriptor.proto");
   1631   AddExtension(&file_proto, "google.protobuf.FieldOptions", "option1", 1000,
   1632                FieldDescriptorProto::LABEL_OPTIONAL,
   1633                FieldDescriptorProto::TYPE_INT32);
   1634   ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
   1635   // Add "bar.proto":
   1636   //   import "google/protobuf/descriptor.proto";
   1637   //   extend google.protobuf.FieldOptions {
   1638   //     optional int32 option2 = 1000;
   1639   //   }
   1640   file_proto.Clear();
   1641   file_proto.set_name("bar.proto");
   1642   file_proto.add_dependency("google/protobuf/descriptor.proto");
   1643   AddExtension(&file_proto, "google.protobuf.FieldOptions", "option2", 1000,
   1644                FieldDescriptorProto::LABEL_OPTIONAL,
   1645                FieldDescriptorProto::TYPE_INT32);
   1646   // Currently we only generate a warning for conflicting extension numbers.
   1647   // TODO(xiaofeng): Change it to an error.
   1648   ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
   1649 }
   1650 
   1651 // ===================================================================
   1652 
   1653 class MiscTest : public testing::Test {
   1654  protected:
   1655   // Function which makes a field descriptor of the given type.
   1656   const FieldDescriptor* GetFieldDescriptorOfType(FieldDescriptor::Type type) {
   1657     FileDescriptorProto file_proto;
   1658     file_proto.set_name("foo.proto");
   1659     AddEmptyEnum(&file_proto, "DummyEnum");
   1660 
   1661     DescriptorProto* message = AddMessage(&file_proto, "TestMessage");
   1662     FieldDescriptorProto* field =
   1663       AddField(message, "foo", 1, FieldDescriptorProto::LABEL_OPTIONAL,
   1664                static_cast<FieldDescriptorProto::Type>(static_cast<int>(type)));
   1665 
   1666     if (type == FieldDescriptor::TYPE_MESSAGE ||
   1667         type == FieldDescriptor::TYPE_GROUP) {
   1668       field->set_type_name("TestMessage");
   1669     } else if (type == FieldDescriptor::TYPE_ENUM) {
   1670       field->set_type_name("DummyEnum");
   1671     }
   1672 
   1673     // Build the descriptors and get the pointers.
   1674     pool_.reset(new DescriptorPool());
   1675     const FileDescriptor* file = pool_->BuildFile(file_proto);
   1676 
   1677     if (file != NULL &&
   1678         file->message_type_count() == 1 &&
   1679         file->message_type(0)->field_count() == 1) {
   1680       return file->message_type(0)->field(0);
   1681     } else {
   1682       return NULL;
   1683     }
   1684   }
   1685 
   1686   const char* GetTypeNameForFieldType(FieldDescriptor::Type type) {
   1687     const FieldDescriptor* field = GetFieldDescriptorOfType(type);
   1688     return field != NULL ? field->type_name() : "";
   1689   }
   1690 
   1691   FieldDescriptor::CppType GetCppTypeForFieldType(FieldDescriptor::Type type) {
   1692     const FieldDescriptor* field = GetFieldDescriptorOfType(type);
   1693     return field != NULL ? field->cpp_type() :
   1694         static_cast<FieldDescriptor::CppType>(0);
   1695   }
   1696 
   1697   const char* GetCppTypeNameForFieldType(FieldDescriptor::Type type) {
   1698     const FieldDescriptor* field = GetFieldDescriptorOfType(type);
   1699     return field != NULL ? field->cpp_type_name() : "";
   1700   }
   1701 
   1702   const Descriptor* GetMessageDescriptorForFieldType(
   1703       FieldDescriptor::Type type) {
   1704     const FieldDescriptor* field = GetFieldDescriptorOfType(type);
   1705     return field != NULL ? field->message_type() : NULL;
   1706   }
   1707 
   1708   const EnumDescriptor* GetEnumDescriptorForFieldType(
   1709     FieldDescriptor::Type type) {
   1710     const FieldDescriptor* field = GetFieldDescriptorOfType(type);
   1711     return field != NULL ? field->enum_type() : NULL;
   1712   }
   1713 
   1714   scoped_ptr<DescriptorPool> pool_;
   1715 };
   1716 
   1717 TEST_F(MiscTest, TypeNames) {
   1718   // Test that correct type names are returned.
   1719 
   1720   typedef FieldDescriptor FD;  // avoid ugly line wrapping
   1721 
   1722   EXPECT_STREQ("double"  , GetTypeNameForFieldType(FD::TYPE_DOUBLE  ));
   1723   EXPECT_STREQ("float"   , GetTypeNameForFieldType(FD::TYPE_FLOAT   ));
   1724   EXPECT_STREQ("int64"   , GetTypeNameForFieldType(FD::TYPE_INT64   ));
   1725   EXPECT_STREQ("uint64"  , GetTypeNameForFieldType(FD::TYPE_UINT64  ));
   1726   EXPECT_STREQ("int32"   , GetTypeNameForFieldType(FD::TYPE_INT32   ));
   1727   EXPECT_STREQ("fixed64" , GetTypeNameForFieldType(FD::TYPE_FIXED64 ));
   1728   EXPECT_STREQ("fixed32" , GetTypeNameForFieldType(FD::TYPE_FIXED32 ));
   1729   EXPECT_STREQ("bool"    , GetTypeNameForFieldType(FD::TYPE_BOOL    ));
   1730   EXPECT_STREQ("string"  , GetTypeNameForFieldType(FD::TYPE_STRING  ));
   1731   EXPECT_STREQ("group"   , GetTypeNameForFieldType(FD::TYPE_GROUP   ));
   1732   EXPECT_STREQ("message" , GetTypeNameForFieldType(FD::TYPE_MESSAGE ));
   1733   EXPECT_STREQ("bytes"   , GetTypeNameForFieldType(FD::TYPE_BYTES   ));
   1734   EXPECT_STREQ("uint32"  , GetTypeNameForFieldType(FD::TYPE_UINT32  ));
   1735   EXPECT_STREQ("enum"    , GetTypeNameForFieldType(FD::TYPE_ENUM    ));
   1736   EXPECT_STREQ("sfixed32", GetTypeNameForFieldType(FD::TYPE_SFIXED32));
   1737   EXPECT_STREQ("sfixed64", GetTypeNameForFieldType(FD::TYPE_SFIXED64));
   1738   EXPECT_STREQ("sint32"  , GetTypeNameForFieldType(FD::TYPE_SINT32  ));
   1739   EXPECT_STREQ("sint64"  , GetTypeNameForFieldType(FD::TYPE_SINT64  ));
   1740 }
   1741 
   1742 TEST_F(MiscTest, StaticTypeNames) {
   1743   // Test that correct type names are returned.
   1744 
   1745   typedef FieldDescriptor FD;  // avoid ugly line wrapping
   1746 
   1747   EXPECT_STREQ("double"  , FD::TypeName(FD::TYPE_DOUBLE  ));
   1748   EXPECT_STREQ("float"   , FD::TypeName(FD::TYPE_FLOAT   ));
   1749   EXPECT_STREQ("int64"   , FD::TypeName(FD::TYPE_INT64   ));
   1750   EXPECT_STREQ("uint64"  , FD::TypeName(FD::TYPE_UINT64  ));
   1751   EXPECT_STREQ("int32"   , FD::TypeName(FD::TYPE_INT32   ));
   1752   EXPECT_STREQ("fixed64" , FD::TypeName(FD::TYPE_FIXED64 ));
   1753   EXPECT_STREQ("fixed32" , FD::TypeName(FD::TYPE_FIXED32 ));
   1754   EXPECT_STREQ("bool"    , FD::TypeName(FD::TYPE_BOOL    ));
   1755   EXPECT_STREQ("string"  , FD::TypeName(FD::TYPE_STRING  ));
   1756   EXPECT_STREQ("group"   , FD::TypeName(FD::TYPE_GROUP   ));
   1757   EXPECT_STREQ("message" , FD::TypeName(FD::TYPE_MESSAGE ));
   1758   EXPECT_STREQ("bytes"   , FD::TypeName(FD::TYPE_BYTES   ));
   1759   EXPECT_STREQ("uint32"  , FD::TypeName(FD::TYPE_UINT32  ));
   1760   EXPECT_STREQ("enum"    , FD::TypeName(FD::TYPE_ENUM    ));
   1761   EXPECT_STREQ("sfixed32", FD::TypeName(FD::TYPE_SFIXED32));
   1762   EXPECT_STREQ("sfixed64", FD::TypeName(FD::TYPE_SFIXED64));
   1763   EXPECT_STREQ("sint32"  , FD::TypeName(FD::TYPE_SINT32  ));
   1764   EXPECT_STREQ("sint64"  , FD::TypeName(FD::TYPE_SINT64  ));
   1765 }
   1766 
   1767 TEST_F(MiscTest, CppTypes) {
   1768   // Test that CPP types are assigned correctly.
   1769 
   1770   typedef FieldDescriptor FD;  // avoid ugly line wrapping
   1771 
   1772   EXPECT_EQ(FD::CPPTYPE_DOUBLE , GetCppTypeForFieldType(FD::TYPE_DOUBLE  ));
   1773   EXPECT_EQ(FD::CPPTYPE_FLOAT  , GetCppTypeForFieldType(FD::TYPE_FLOAT   ));
   1774   EXPECT_EQ(FD::CPPTYPE_INT64  , GetCppTypeForFieldType(FD::TYPE_INT64   ));
   1775   EXPECT_EQ(FD::CPPTYPE_UINT64 , GetCppTypeForFieldType(FD::TYPE_UINT64  ));
   1776   EXPECT_EQ(FD::CPPTYPE_INT32  , GetCppTypeForFieldType(FD::TYPE_INT32   ));
   1777   EXPECT_EQ(FD::CPPTYPE_UINT64 , GetCppTypeForFieldType(FD::TYPE_FIXED64 ));
   1778   EXPECT_EQ(FD::CPPTYPE_UINT32 , GetCppTypeForFieldType(FD::TYPE_FIXED32 ));
   1779   EXPECT_EQ(FD::CPPTYPE_BOOL   , GetCppTypeForFieldType(FD::TYPE_BOOL    ));
   1780   EXPECT_EQ(FD::CPPTYPE_STRING , GetCppTypeForFieldType(FD::TYPE_STRING  ));
   1781   EXPECT_EQ(FD::CPPTYPE_MESSAGE, GetCppTypeForFieldType(FD::TYPE_GROUP   ));
   1782   EXPECT_EQ(FD::CPPTYPE_MESSAGE, GetCppTypeForFieldType(FD::TYPE_MESSAGE ));
   1783   EXPECT_EQ(FD::CPPTYPE_STRING , GetCppTypeForFieldType(FD::TYPE_BYTES   ));
   1784   EXPECT_EQ(FD::CPPTYPE_UINT32 , GetCppTypeForFieldType(FD::TYPE_UINT32  ));
   1785   EXPECT_EQ(FD::CPPTYPE_ENUM   , GetCppTypeForFieldType(FD::TYPE_ENUM    ));
   1786   EXPECT_EQ(FD::CPPTYPE_INT32  , GetCppTypeForFieldType(FD::TYPE_SFIXED32));
   1787   EXPECT_EQ(FD::CPPTYPE_INT64  , GetCppTypeForFieldType(FD::TYPE_SFIXED64));
   1788   EXPECT_EQ(FD::CPPTYPE_INT32  , GetCppTypeForFieldType(FD::TYPE_SINT32  ));
   1789   EXPECT_EQ(FD::CPPTYPE_INT64  , GetCppTypeForFieldType(FD::TYPE_SINT64  ));
   1790 }
   1791 
   1792 TEST_F(MiscTest, CppTypeNames) {
   1793   // Test that correct CPP type names are returned.
   1794 
   1795   typedef FieldDescriptor FD;  // avoid ugly line wrapping
   1796 
   1797   EXPECT_STREQ("double" , GetCppTypeNameForFieldType(FD::TYPE_DOUBLE  ));
   1798   EXPECT_STREQ("float"  , GetCppTypeNameForFieldType(FD::TYPE_FLOAT   ));
   1799   EXPECT_STREQ("int64"  , GetCppTypeNameForFieldType(FD::TYPE_INT64   ));
   1800   EXPECT_STREQ("uint64" , GetCppTypeNameForFieldType(FD::TYPE_UINT64  ));
   1801   EXPECT_STREQ("int32"  , GetCppTypeNameForFieldType(FD::TYPE_INT32   ));
   1802   EXPECT_STREQ("uint64" , GetCppTypeNameForFieldType(FD::TYPE_FIXED64 ));
   1803   EXPECT_STREQ("uint32" , GetCppTypeNameForFieldType(FD::TYPE_FIXED32 ));
   1804   EXPECT_STREQ("bool"   , GetCppTypeNameForFieldType(FD::TYPE_BOOL    ));
   1805   EXPECT_STREQ("string" , GetCppTypeNameForFieldType(FD::TYPE_STRING  ));
   1806   EXPECT_STREQ("message", GetCppTypeNameForFieldType(FD::TYPE_GROUP   ));
   1807   EXPECT_STREQ("message", GetCppTypeNameForFieldType(FD::TYPE_MESSAGE ));
   1808   EXPECT_STREQ("string" , GetCppTypeNameForFieldType(FD::TYPE_BYTES   ));
   1809   EXPECT_STREQ("uint32" , GetCppTypeNameForFieldType(FD::TYPE_UINT32  ));
   1810   EXPECT_STREQ("enum"   , GetCppTypeNameForFieldType(FD::TYPE_ENUM    ));
   1811   EXPECT_STREQ("int32"  , GetCppTypeNameForFieldType(FD::TYPE_SFIXED32));
   1812   EXPECT_STREQ("int64"  , GetCppTypeNameForFieldType(FD::TYPE_SFIXED64));
   1813   EXPECT_STREQ("int32"  , GetCppTypeNameForFieldType(FD::TYPE_SINT32  ));
   1814   EXPECT_STREQ("int64"  , GetCppTypeNameForFieldType(FD::TYPE_SINT64  ));
   1815 }
   1816 
   1817 TEST_F(MiscTest, StaticCppTypeNames) {
   1818   // Test that correct CPP type names are returned.
   1819 
   1820   typedef FieldDescriptor FD;  // avoid ugly line wrapping
   1821 
   1822   EXPECT_STREQ("int32"  , FD::CppTypeName(FD::CPPTYPE_INT32  ));
   1823   EXPECT_STREQ("int64"  , FD::CppTypeName(FD::CPPTYPE_INT64  ));
   1824   EXPECT_STREQ("uint32" , FD::CppTypeName(FD::CPPTYPE_UINT32 ));
   1825   EXPECT_STREQ("uint64" , FD::CppTypeName(FD::CPPTYPE_UINT64 ));
   1826   EXPECT_STREQ("double" , FD::CppTypeName(FD::CPPTYPE_DOUBLE ));
   1827   EXPECT_STREQ("float"  , FD::CppTypeName(FD::CPPTYPE_FLOAT  ));
   1828   EXPECT_STREQ("bool"   , FD::CppTypeName(FD::CPPTYPE_BOOL   ));
   1829   EXPECT_STREQ("enum"   , FD::CppTypeName(FD::CPPTYPE_ENUM   ));
   1830   EXPECT_STREQ("string" , FD::CppTypeName(FD::CPPTYPE_STRING ));
   1831   EXPECT_STREQ("message", FD::CppTypeName(FD::CPPTYPE_MESSAGE));
   1832 }
   1833 
   1834 TEST_F(MiscTest, MessageType) {
   1835   // Test that message_type() is NULL for non-aggregate fields
   1836 
   1837   typedef FieldDescriptor FD;  // avoid ugly line wrapping
   1838 
   1839   EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_DOUBLE  ));
   1840   EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_FLOAT   ));
   1841   EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_INT64   ));
   1842   EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_UINT64  ));
   1843   EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_INT32   ));
   1844   EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_FIXED64 ));
   1845   EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_FIXED32 ));
   1846   EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_BOOL    ));
   1847   EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_STRING  ));
   1848   EXPECT_TRUE(NULL != GetMessageDescriptorForFieldType(FD::TYPE_GROUP   ));
   1849   EXPECT_TRUE(NULL != GetMessageDescriptorForFieldType(FD::TYPE_MESSAGE ));
   1850   EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_BYTES   ));
   1851   EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_UINT32  ));
   1852   EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_ENUM    ));
   1853   EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_SFIXED32));
   1854   EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_SFIXED64));
   1855   EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_SINT32  ));
   1856   EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_SINT64  ));
   1857 }
   1858 
   1859 TEST_F(MiscTest, EnumType) {
   1860   // Test that enum_type() is NULL for non-enum fields
   1861 
   1862   typedef FieldDescriptor FD;  // avoid ugly line wrapping
   1863 
   1864   EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_DOUBLE  ));
   1865   EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_FLOAT   ));
   1866   EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_INT64   ));
   1867   EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_UINT64  ));
   1868   EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_INT32   ));
   1869   EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_FIXED64 ));
   1870   EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_FIXED32 ));
   1871   EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_BOOL    ));
   1872   EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_STRING  ));
   1873   EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_GROUP   ));
   1874   EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_MESSAGE ));
   1875   EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_BYTES   ));
   1876   EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_UINT32  ));
   1877   EXPECT_TRUE(NULL != GetEnumDescriptorForFieldType(FD::TYPE_ENUM    ));
   1878   EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_SFIXED32));
   1879   EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_SFIXED64));
   1880   EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_SINT32  ));
   1881   EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_SINT64  ));
   1882 }
   1883 
   1884 
   1885 TEST_F(MiscTest, DefaultValues) {
   1886   // Test that setting default values works.
   1887   FileDescriptorProto file_proto;
   1888   file_proto.set_name("foo.proto");
   1889 
   1890   EnumDescriptorProto* enum_type_proto = AddEnum(&file_proto, "DummyEnum");
   1891   AddEnumValue(enum_type_proto, "A", 1);
   1892   AddEnumValue(enum_type_proto, "B", 2);
   1893 
   1894   DescriptorProto* message_proto = AddMessage(&file_proto, "TestMessage");
   1895 
   1896   typedef FieldDescriptorProto FD;  // avoid ugly line wrapping
   1897   const FD::Label label = FD::LABEL_OPTIONAL;
   1898 
   1899   // Create fields of every CPP type with default values.
   1900   AddField(message_proto, "int32" , 1, label, FD::TYPE_INT32 )
   1901     ->set_default_value("-1");
   1902   AddField(message_proto, "int64" , 2, label, FD::TYPE_INT64 )
   1903     ->set_default_value("-1000000000000");
   1904   AddField(message_proto, "uint32", 3, label, FD::TYPE_UINT32)
   1905     ->set_default_value("42");
   1906   AddField(message_proto, "uint64", 4, label, FD::TYPE_UINT64)
   1907     ->set_default_value("2000000000000");
   1908   AddField(message_proto, "float" , 5, label, FD::TYPE_FLOAT )
   1909     ->set_default_value("4.5");
   1910   AddField(message_proto, "double", 6, label, FD::TYPE_DOUBLE)
   1911     ->set_default_value("10e100");
   1912   AddField(message_proto, "bool"  , 7, label, FD::TYPE_BOOL  )
   1913     ->set_default_value("true");
   1914   AddField(message_proto, "string", 8, label, FD::TYPE_STRING)
   1915     ->set_default_value("hello");
   1916   AddField(message_proto, "data"  , 9, label, FD::TYPE_BYTES )
   1917     ->set_default_value("\\001\\002\\003");
   1918 
   1919   FieldDescriptorProto* enum_field =
   1920     AddField(message_proto, "enum", 10, label, FD::TYPE_ENUM);
   1921   enum_field->set_type_name("DummyEnum");
   1922   enum_field->set_default_value("B");
   1923 
   1924   // Strings are allowed to have empty defaults.  (At one point, due to
   1925   // a bug, empty defaults for strings were rejected.  Oops.)
   1926   AddField(message_proto, "empty_string", 11, label, FD::TYPE_STRING)
   1927     ->set_default_value("");
   1928 
   1929   // Add a second set of fields with implicit defalut values.
   1930   AddField(message_proto, "implicit_int32" , 21, label, FD::TYPE_INT32 );
   1931   AddField(message_proto, "implicit_int64" , 22, label, FD::TYPE_INT64 );
   1932   AddField(message_proto, "implicit_uint32", 23, label, FD::TYPE_UINT32);
   1933   AddField(message_proto, "implicit_uint64", 24, label, FD::TYPE_UINT64);
   1934   AddField(message_proto, "implicit_float" , 25, label, FD::TYPE_FLOAT );
   1935   AddField(message_proto, "implicit_double", 26, label, FD::TYPE_DOUBLE);
   1936   AddField(message_proto, "implicit_bool"  , 27, label, FD::TYPE_BOOL  );
   1937   AddField(message_proto, "implicit_string", 28, label, FD::TYPE_STRING);
   1938   AddField(message_proto, "implicit_data"  , 29, label, FD::TYPE_BYTES );
   1939   AddField(message_proto, "implicit_enum"  , 30, label, FD::TYPE_ENUM)
   1940     ->set_type_name("DummyEnum");
   1941 
   1942   // Build it.
   1943   DescriptorPool pool;
   1944   const FileDescriptor* file = pool.BuildFile(file_proto);
   1945   ASSERT_TRUE(file != NULL);
   1946 
   1947   ASSERT_EQ(1, file->enum_type_count());
   1948   const EnumDescriptor* enum_type = file->enum_type(0);
   1949   ASSERT_EQ(2, enum_type->value_count());
   1950   const EnumValueDescriptor* enum_value_a = enum_type->value(0);
   1951   const EnumValueDescriptor* enum_value_b = enum_type->value(1);
   1952 
   1953   ASSERT_EQ(1, file->message_type_count());
   1954   const Descriptor* message = file->message_type(0);
   1955 
   1956   ASSERT_EQ(21, message->field_count());
   1957 
   1958   // Check the default values.
   1959   ASSERT_TRUE(message->field(0)->has_default_value());
   1960   ASSERT_TRUE(message->field(1)->has_default_value());
   1961   ASSERT_TRUE(message->field(2)->has_default_value());
   1962   ASSERT_TRUE(message->field(3)->has_default_value());
   1963   ASSERT_TRUE(message->field(4)->has_default_value());
   1964   ASSERT_TRUE(message->field(5)->has_default_value());
   1965   ASSERT_TRUE(message->field(6)->has_default_value());
   1966   ASSERT_TRUE(message->field(7)->has_default_value());
   1967   ASSERT_TRUE(message->field(8)->has_default_value());
   1968   ASSERT_TRUE(message->field(9)->has_default_value());
   1969   ASSERT_TRUE(message->field(10)->has_default_value());
   1970 
   1971   EXPECT_EQ(-1              , message->field(0)->default_value_int32 ());
   1972   EXPECT_EQ(-GOOGLE_ULONGLONG(1000000000000),
   1973             message->field(1)->default_value_int64 ());
   1974   EXPECT_EQ(42              , message->field(2)->default_value_uint32());
   1975   EXPECT_EQ(GOOGLE_ULONGLONG(2000000000000),
   1976             message->field(3)->default_value_uint64());
   1977   EXPECT_EQ(4.5             , message->field(4)->default_value_float ());
   1978   EXPECT_EQ(10e100          , message->field(5)->default_value_double());
   1979   EXPECT_TRUE(                message->field(6)->default_value_bool  ());
   1980   EXPECT_EQ("hello"         , message->field(7)->default_value_string());
   1981   EXPECT_EQ("\001\002\003"  , message->field(8)->default_value_string());
   1982   EXPECT_EQ(enum_value_b    , message->field(9)->default_value_enum  ());
   1983   EXPECT_EQ(""              , message->field(10)->default_value_string());
   1984 
   1985   ASSERT_FALSE(message->field(11)->has_default_value());
   1986   ASSERT_FALSE(message->field(12)->has_default_value());
   1987   ASSERT_FALSE(message->field(13)->has_default_value());
   1988   ASSERT_FALSE(message->field(14)->has_default_value());
   1989   ASSERT_FALSE(message->field(15)->has_default_value());
   1990   ASSERT_FALSE(message->field(16)->has_default_value());
   1991   ASSERT_FALSE(message->field(17)->has_default_value());
   1992   ASSERT_FALSE(message->field(18)->has_default_value());
   1993   ASSERT_FALSE(message->field(19)->has_default_value());
   1994   ASSERT_FALSE(message->field(20)->has_default_value());
   1995 
   1996   EXPECT_EQ(0    , message->field(11)->default_value_int32 ());
   1997   EXPECT_EQ(0    , message->field(12)->default_value_int64 ());
   1998   EXPECT_EQ(0    , message->field(13)->default_value_uint32());
   1999   EXPECT_EQ(0    , message->field(14)->default_value_uint64());
   2000   EXPECT_EQ(0.0f , message->field(15)->default_value_float ());
   2001   EXPECT_EQ(0.0  , message->field(16)->default_value_double());
   2002   EXPECT_FALSE(    message->field(17)->default_value_bool  ());
   2003   EXPECT_EQ(""   , message->field(18)->default_value_string());
   2004   EXPECT_EQ(""   , message->field(19)->default_value_string());
   2005   EXPECT_EQ(enum_value_a, message->field(20)->default_value_enum());
   2006 }
   2007 
   2008 TEST_F(MiscTest, FieldOptions) {
   2009   // Try setting field options.
   2010 
   2011   FileDescriptorProto file_proto;
   2012   file_proto.set_name("foo.proto");
   2013 
   2014   DescriptorProto* message_proto = AddMessage(&file_proto, "TestMessage");
   2015   AddField(message_proto, "foo", 1,
   2016            FieldDescriptorProto::LABEL_OPTIONAL,
   2017            FieldDescriptorProto::TYPE_INT32);
   2018   FieldDescriptorProto* bar_proto =
   2019     AddField(message_proto, "bar", 2,
   2020              FieldDescriptorProto::LABEL_OPTIONAL,
   2021              FieldDescriptorProto::TYPE_INT32);
   2022 
   2023   FieldOptions* options = bar_proto->mutable_options();
   2024   options->set_ctype(FieldOptions::CORD);
   2025 
   2026   // Build the descriptors and get the pointers.
   2027   DescriptorPool pool;
   2028   const FileDescriptor* file = pool.BuildFile(file_proto);
   2029   ASSERT_TRUE(file != NULL);
   2030 
   2031   ASSERT_EQ(1, file->message_type_count());
   2032   const Descriptor* message = file->message_type(0);
   2033 
   2034   ASSERT_EQ(2, message->field_count());
   2035   const FieldDescriptor* foo = message->field(0);
   2036   const FieldDescriptor* bar = message->field(1);
   2037 
   2038   // "foo" had no options set, so it should return the default options.
   2039   EXPECT_EQ(&FieldOptions::default_instance(), &foo->options());
   2040 
   2041   // "bar" had options set.
   2042   EXPECT_NE(&FieldOptions::default_instance(), options);
   2043   EXPECT_TRUE(bar->options().has_ctype());
   2044   EXPECT_EQ(FieldOptions::CORD, bar->options().ctype());
   2045 }
   2046 
   2047 // ===================================================================
   2048 enum DescriptorPoolMode {
   2049   NO_DATABASE,
   2050   FALLBACK_DATABASE
   2051 };
   2052 
   2053 class AllowUnknownDependenciesTest
   2054     : public testing::TestWithParam<DescriptorPoolMode> {
   2055  protected:
   2056   DescriptorPoolMode mode() {
   2057     return GetParam();
   2058    }
   2059 
   2060   virtual void SetUp() {
   2061     FileDescriptorProto foo_proto, bar_proto;
   2062 
   2063     switch (mode()) {
   2064       case NO_DATABASE:
   2065         pool_.reset(new DescriptorPool);
   2066         break;
   2067       case FALLBACK_DATABASE:
   2068         pool_.reset(new DescriptorPool(&db_));
   2069         break;
   2070     }
   2071 
   2072     pool_->AllowUnknownDependencies();
   2073 
   2074     ASSERT_TRUE(TextFormat::ParseFromString(
   2075       "name: 'foo.proto'"
   2076       "dependency: 'bar.proto'"
   2077       "dependency: 'baz.proto'"
   2078       "message_type {"
   2079       "  name: 'Foo'"
   2080       "  field { name:'bar' number:1 label:LABEL_OPTIONAL type_name:'Bar' }"
   2081       "  field { name:'baz' number:2 label:LABEL_OPTIONAL type_name:'Baz' }"
   2082       "  field { name:'qux' number:3 label:LABEL_OPTIONAL"
   2083       "    type_name: '.corge.Qux'"
   2084       "    type: TYPE_ENUM"
   2085       "    options {"
   2086       "      uninterpreted_option {"
   2087       "        name {"
   2088       "          name_part: 'grault'"
   2089       "          is_extension: true"
   2090       "        }"
   2091       "        positive_int_value: 1234"
   2092       "      }"
   2093       "    }"
   2094       "  }"
   2095       "}",
   2096       &foo_proto));
   2097     ASSERT_TRUE(TextFormat::ParseFromString(
   2098       "name: 'bar.proto'"
   2099       "message_type { name: 'Bar' }",
   2100       &bar_proto));
   2101 
   2102     // Collect pointers to stuff.
   2103     bar_file_ = BuildFile(bar_proto);
   2104     ASSERT_TRUE(bar_file_ != NULL);
   2105 
   2106     ASSERT_EQ(1, bar_file_->message_type_count());
   2107     bar_type_ = bar_file_->message_type(0);
   2108 
   2109     foo_file_ = BuildFile(foo_proto);
   2110     ASSERT_TRUE(foo_file_ != NULL);
   2111 
   2112     ASSERT_EQ(1, foo_file_->message_type_count());
   2113     foo_type_ = foo_file_->message_type(0);
   2114 
   2115     ASSERT_EQ(3, foo_type_->field_count());
   2116     bar_field_ = foo_type_->field(0);
   2117     baz_field_ = foo_type_->field(1);
   2118     qux_field_ = foo_type_->field(2);
   2119   }
   2120 
   2121   const FileDescriptor* BuildFile(const FileDescriptorProto& proto) {
   2122     switch (mode()) {
   2123       case NO_DATABASE:
   2124         return pool_->BuildFile(proto);
   2125         break;
   2126       case FALLBACK_DATABASE: {
   2127         EXPECT_TRUE(db_.Add(proto));
   2128         return pool_->FindFileByName(proto.name());
   2129       }
   2130     }
   2131     GOOGLE_LOG(FATAL) << "Can't get here.";
   2132     return NULL;
   2133   }
   2134 
   2135   const FileDescriptor* bar_file_;
   2136   const Descriptor* bar_type_;
   2137   const FileDescriptor* foo_file_;
   2138   const Descriptor* foo_type_;
   2139   const FieldDescriptor* bar_field_;
   2140   const FieldDescriptor* baz_field_;
   2141   const FieldDescriptor* qux_field_;
   2142 
   2143   SimpleDescriptorDatabase db_;        // used if in FALLBACK_DATABASE mode.
   2144   scoped_ptr<DescriptorPool> pool_;
   2145 };
   2146 
   2147 TEST_P(AllowUnknownDependenciesTest, PlaceholderFile) {
   2148   ASSERT_EQ(2, foo_file_->dependency_count());
   2149   EXPECT_EQ(bar_file_, foo_file_->dependency(0));
   2150   EXPECT_FALSE(bar_file_->is_placeholder());
   2151 
   2152   const FileDescriptor* baz_file = foo_file_->dependency(1);
   2153   EXPECT_EQ("baz.proto", baz_file->name());
   2154   EXPECT_EQ(0, baz_file->message_type_count());
   2155   EXPECT_TRUE(baz_file->is_placeholder());
   2156 
   2157   // Placeholder files should not be findable.
   2158   EXPECT_EQ(bar_file_, pool_->FindFileByName(bar_file_->name()));
   2159   EXPECT_TRUE(pool_->FindFileByName(baz_file->name()) == NULL);
   2160 }
   2161 
   2162 TEST_P(AllowUnknownDependenciesTest, PlaceholderTypes) {
   2163   ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, bar_field_->type());
   2164   EXPECT_EQ(bar_type_, bar_field_->message_type());
   2165   EXPECT_FALSE(bar_type_->is_placeholder());
   2166 
   2167   ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, baz_field_->type());
   2168   const Descriptor* baz_type = baz_field_->message_type();
   2169   EXPECT_EQ("Baz", baz_type->name());
   2170   EXPECT_EQ("Baz", baz_type->full_name());
   2171   EXPECT_EQ(0, baz_type->extension_range_count());
   2172   EXPECT_TRUE(baz_type->is_placeholder());
   2173 
   2174   ASSERT_EQ(FieldDescriptor::TYPE_ENUM, qux_field_->type());
   2175   const EnumDescriptor* qux_type = qux_field_->enum_type();
   2176   EXPECT_EQ("Qux", qux_type->name());
   2177   EXPECT_EQ("corge.Qux", qux_type->full_name());
   2178   EXPECT_TRUE(qux_type->is_placeholder());
   2179 
   2180   // Placeholder types should not be findable.
   2181   EXPECT_EQ(bar_type_, pool_->FindMessageTypeByName(bar_type_->full_name()));
   2182   EXPECT_TRUE(pool_->FindMessageTypeByName(baz_type->full_name()) == NULL);
   2183   EXPECT_TRUE(pool_->FindEnumTypeByName(qux_type->full_name()) == NULL);
   2184 }
   2185 
   2186 TEST_P(AllowUnknownDependenciesTest, CopyTo) {
   2187   // FieldDescriptor::CopyTo() should write non-fully-qualified type names
   2188   // for placeholder types which were not originally fully-qualified.
   2189   FieldDescriptorProto proto;
   2190 
   2191   // Bar is not a placeholder, so it is fully-qualified.
   2192   bar_field_->CopyTo(&proto);
   2193   EXPECT_EQ(".Bar", proto.type_name());
   2194   EXPECT_EQ(FieldDescriptorProto::TYPE_MESSAGE, proto.type());
   2195 
   2196   // Baz is an unqualified placeholder.
   2197   proto.Clear();
   2198   baz_field_->CopyTo(&proto);
   2199   EXPECT_EQ("Baz", proto.type_name());
   2200   EXPECT_FALSE(proto.has_type());
   2201 
   2202   // Qux is a fully-qualified placeholder.
   2203   proto.Clear();
   2204   qux_field_->CopyTo(&proto);
   2205   EXPECT_EQ(".corge.Qux", proto.type_name());
   2206   EXPECT_EQ(FieldDescriptorProto::TYPE_ENUM, proto.type());
   2207 }
   2208 
   2209 TEST_P(AllowUnknownDependenciesTest, CustomOptions) {
   2210   // Qux should still have the uninterpreted option attached.
   2211   ASSERT_EQ(1, qux_field_->options().uninterpreted_option_size());
   2212   const UninterpretedOption& option =
   2213     qux_field_->options().uninterpreted_option(0);
   2214   ASSERT_EQ(1, option.name_size());
   2215   EXPECT_EQ("grault", option.name(0).name_part());
   2216 }
   2217 
   2218 TEST_P(AllowUnknownDependenciesTest, UnknownExtendee) {
   2219   // Test that we can extend an unknown type.  This is slightly tricky because
   2220   // it means that the placeholder type must have an extension range.
   2221 
   2222   FileDescriptorProto extension_proto;
   2223 
   2224   ASSERT_TRUE(TextFormat::ParseFromString(
   2225     "name: 'extension.proto'"
   2226     "extension { extendee: 'UnknownType' name:'some_extension' number:123"
   2227     "            label:LABEL_OPTIONAL type:TYPE_INT32 }",
   2228     &extension_proto));
   2229   const FileDescriptor* file = BuildFile(extension_proto);
   2230 
   2231   ASSERT_TRUE(file != NULL);
   2232 
   2233   ASSERT_EQ(1, file->extension_count());
   2234   const Descriptor* extendee = file->extension(0)->containing_type();
   2235   EXPECT_EQ("UnknownType", extendee->name());
   2236   EXPECT_TRUE(extendee->is_placeholder());
   2237   ASSERT_EQ(1, extendee->extension_range_count());
   2238   EXPECT_EQ(1, extendee->extension_range(0)->start);
   2239   EXPECT_EQ(FieldDescriptor::kMaxNumber + 1, extendee->extension_range(0)->end);
   2240 }
   2241 
   2242 TEST_P(AllowUnknownDependenciesTest, CustomOption) {
   2243   // Test that we can use a custom option without having parsed
   2244   // descriptor.proto.
   2245 
   2246   FileDescriptorProto option_proto;
   2247 
   2248   ASSERT_TRUE(TextFormat::ParseFromString(
   2249     "name: \"unknown_custom_options.proto\" "
   2250     "dependency: \"google/protobuf/descriptor.proto\" "
   2251     "extension { "
   2252     "  extendee: \"google.protobuf.FileOptions\" "
   2253     "  name: \"some_option\" "
   2254     "  number: 123456 "
   2255     "  label: LABEL_OPTIONAL "
   2256     "  type: TYPE_INT32 "
   2257     "} "
   2258     "options { "
   2259     "  uninterpreted_option { "
   2260     "    name { "
   2261     "      name_part: \"some_option\" "
   2262     "      is_extension: true "
   2263     "    } "
   2264     "    positive_int_value: 1234 "
   2265     "  } "
   2266     "  uninterpreted_option { "
   2267     "    name { "
   2268     "      name_part: \"unknown_option\" "
   2269     "      is_extension: true "
   2270     "    } "
   2271     "    positive_int_value: 1234 "
   2272     "  } "
   2273     "  uninterpreted_option { "
   2274     "    name { "
   2275     "      name_part: \"optimize_for\" "
   2276     "      is_extension: false "
   2277     "    } "
   2278     "    identifier_value: \"SPEED\" "
   2279     "  } "
   2280     "}",
   2281     &option_proto));
   2282 
   2283   const FileDescriptor* file = BuildFile(option_proto);
   2284   ASSERT_TRUE(file != NULL);
   2285 
   2286   // Verify that no extension options were set, but they were left as
   2287   // uninterpreted_options.
   2288   vector<const FieldDescriptor*> fields;
   2289   file->options().GetReflection()->ListFields(file->options(), &fields);
   2290   ASSERT_EQ(2, fields.size());
   2291   EXPECT_TRUE(file->options().has_optimize_for());
   2292   EXPECT_EQ(2, file->options().uninterpreted_option_size());
   2293 }
   2294 
   2295 TEST_P(AllowUnknownDependenciesTest,
   2296        UndeclaredDependencyTriggersBuildOfDependency) {
   2297   // Crazy case: suppose foo.proto refers to a symbol without declaring the
   2298   // dependency that finds it. In the event that the pool is backed by a
   2299   // DescriptorDatabase, the pool will attempt to find the symbol in the
   2300   // database. If successful, it will build the undeclared dependency to verify
   2301   // that the file does indeed contain the symbol. If that file fails to build,
   2302   // then its descriptors must be rolled back. However, we still want foo.proto
   2303   // to build successfully, since we are allowing unknown dependencies.
   2304 
   2305   FileDescriptorProto undeclared_dep_proto;
   2306   // We make this file fail to build by giving it two fields with tag 1.
   2307   ASSERT_TRUE(TextFormat::ParseFromString(
   2308     "name: \"invalid_file_as_undeclared_dep.proto\" "
   2309     "package: \"undeclared\" "
   2310     "message_type: {  "
   2311     "  name: \"Quux\"  "
   2312     "  field { "
   2313     "    name:'qux' number:1 label:LABEL_OPTIONAL type: TYPE_INT32 "
   2314     "  }"
   2315     "  field { "
   2316     "    name:'quux' number:1 label:LABEL_OPTIONAL type: TYPE_INT64 "
   2317     "  }"
   2318     "}",
   2319     &undeclared_dep_proto));
   2320   // We can't use the BuildFile() helper because we don't actually want to build
   2321   // it into the descriptor pool in the fallback database case: it just needs to
   2322   // be sitting in the database so that it gets built during the building of
   2323   // test.proto below.
   2324   switch (mode()) {
   2325     case NO_DATABASE: {
   2326       ASSERT_TRUE(pool_->BuildFile(undeclared_dep_proto) == NULL);
   2327       break;
   2328     }
   2329     case FALLBACK_DATABASE: {
   2330       ASSERT_TRUE(db_.Add(undeclared_dep_proto));
   2331     }
   2332   }
   2333 
   2334   FileDescriptorProto test_proto;
   2335   ASSERT_TRUE(TextFormat::ParseFromString(
   2336     "name: \"test.proto\" "
   2337     "message_type: { "
   2338     "  name: \"Corge\" "
   2339     "  field { "
   2340     "    name:'quux' number:1 label: LABEL_OPTIONAL "
   2341     "    type_name:'undeclared.Quux' type: TYPE_MESSAGE "
   2342     "  }"
   2343     "}",
   2344     &test_proto));
   2345 
   2346   const FileDescriptor* file = BuildFile(test_proto);
   2347   ASSERT_TRUE(file != NULL);
   2348   GOOGLE_LOG(INFO) << file->DebugString();
   2349 
   2350   EXPECT_EQ(0, file->dependency_count());
   2351   ASSERT_EQ(1, file->message_type_count());
   2352   const Descriptor* corge_desc = file->message_type(0);
   2353   ASSERT_EQ("Corge", corge_desc->name());
   2354   ASSERT_EQ(1, corge_desc->field_count());
   2355   EXPECT_FALSE(corge_desc->is_placeholder());
   2356 
   2357   const FieldDescriptor* quux_field = corge_desc->field(0);
   2358   ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, quux_field->type());
   2359   ASSERT_EQ("Quux", quux_field->message_type()->name());
   2360   ASSERT_EQ("undeclared.Quux", quux_field->message_type()->full_name());
   2361   EXPECT_TRUE(quux_field->message_type()->is_placeholder());
   2362   // The place holder type should not be findable.
   2363   ASSERT_TRUE(pool_->FindMessageTypeByName("undeclared.Quux") == NULL);
   2364 }
   2365 
   2366 INSTANTIATE_TEST_CASE_P(DatabaseSource,
   2367                         AllowUnknownDependenciesTest,
   2368                         testing::Values(NO_DATABASE, FALLBACK_DATABASE));
   2369 
   2370 // ===================================================================
   2371 
   2372 TEST(CustomOptions, OptionLocations) {
   2373   const Descriptor* message =
   2374       protobuf_unittest::TestMessageWithCustomOptions::descriptor();
   2375   const FileDescriptor* file = message->file();
   2376   const FieldDescriptor* field = message->FindFieldByName("field1");
   2377   const EnumDescriptor* enm = message->FindEnumTypeByName("AnEnum");
   2378   // TODO(benjy): Support EnumValue options, once the compiler does.
   2379   const ServiceDescriptor* service =
   2380       file->FindServiceByName("TestServiceWithCustomOptions");
   2381   const MethodDescriptor* method = service->FindMethodByName("Foo");
   2382 
   2383   EXPECT_EQ(GOOGLE_LONGLONG(9876543210),
   2384             file->options().GetExtension(protobuf_unittest::file_opt1));
   2385   EXPECT_EQ(-56,
   2386             message->options().GetExtension(protobuf_unittest::message_opt1));
   2387   EXPECT_EQ(GOOGLE_LONGLONG(8765432109),
   2388             field->options().GetExtension(protobuf_unittest::field_opt1));
   2389   EXPECT_EQ(42,  // Check that we get the default for an option we don't set.
   2390             field->options().GetExtension(protobuf_unittest::field_opt2));
   2391   EXPECT_EQ(-789,
   2392             enm->options().GetExtension(protobuf_unittest::enum_opt1));
   2393   EXPECT_EQ(123,
   2394             enm->value(1)->options().GetExtension(
   2395               protobuf_unittest::enum_value_opt1));
   2396   EXPECT_EQ(GOOGLE_LONGLONG(-9876543210),
   2397             service->options().GetExtension(protobuf_unittest::service_opt1));
   2398   EXPECT_EQ(protobuf_unittest::METHODOPT1_VAL2,
   2399             method->options().GetExtension(protobuf_unittest::method_opt1));
   2400 
   2401   // See that the regular options went through unscathed.
   2402   EXPECT_TRUE(message->options().has_message_set_wire_format());
   2403   EXPECT_EQ(FieldOptions::CORD, field->options().ctype());
   2404 }
   2405 
   2406 TEST(CustomOptions, OptionTypes) {
   2407   const MessageOptions* options = NULL;
   2408 
   2409   options =
   2410       &protobuf_unittest::CustomOptionMinIntegerValues::descriptor()->options();
   2411   EXPECT_EQ(false    , options->GetExtension(protobuf_unittest::bool_opt));
   2412   EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::int32_opt));
   2413   EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::int64_opt));
   2414   EXPECT_EQ(0        , options->GetExtension(protobuf_unittest::uint32_opt));
   2415   EXPECT_EQ(0        , options->GetExtension(protobuf_unittest::uint64_opt));
   2416   EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::sint32_opt));
   2417   EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::sint64_opt));
   2418   EXPECT_EQ(0        , options->GetExtension(protobuf_unittest::fixed32_opt));
   2419   EXPECT_EQ(0        , options->GetExtension(protobuf_unittest::fixed64_opt));
   2420   EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::sfixed32_opt));
   2421   EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::sfixed64_opt));
   2422 
   2423   options =
   2424       &protobuf_unittest::CustomOptionMaxIntegerValues::descriptor()->options();
   2425   EXPECT_EQ(true      , options->GetExtension(protobuf_unittest::bool_opt));
   2426   EXPECT_EQ(kint32max , options->GetExtension(protobuf_unittest::int32_opt));
   2427   EXPECT_EQ(kint64max , options->GetExtension(protobuf_unittest::int64_opt));
   2428   EXPECT_EQ(kuint32max, options->GetExtension(protobuf_unittest::uint32_opt));
   2429   EXPECT_EQ(kuint64max, options->GetExtension(protobuf_unittest::uint64_opt));
   2430   EXPECT_EQ(kint32max , options->GetExtension(protobuf_unittest::sint32_opt));
   2431   EXPECT_EQ(kint64max , options->GetExtension(protobuf_unittest::sint64_opt));
   2432   EXPECT_EQ(kuint32max, options->GetExtension(protobuf_unittest::fixed32_opt));
   2433   EXPECT_EQ(kuint64max, options->GetExtension(protobuf_unittest::fixed64_opt));
   2434   EXPECT_EQ(kint32max , options->GetExtension(protobuf_unittest::sfixed32_opt));
   2435   EXPECT_EQ(kint64max , options->GetExtension(protobuf_unittest::sfixed64_opt));
   2436 
   2437   options =
   2438       &protobuf_unittest::CustomOptionOtherValues::descriptor()->options();
   2439   EXPECT_EQ(-100, options->GetExtension(protobuf_unittest::int32_opt));
   2440   EXPECT_FLOAT_EQ(12.3456789,
   2441                   options->GetExtension(protobuf_unittest::float_opt));
   2442   EXPECT_DOUBLE_EQ(1.234567890123456789,
   2443                    options->GetExtension(protobuf_unittest::double_opt));
   2444   EXPECT_EQ("Hello, \"World\"",
   2445             options->GetExtension(protobuf_unittest::string_opt));
   2446 
   2447   EXPECT_EQ(string("Hello\0World", 11),
   2448             options->GetExtension(protobuf_unittest::bytes_opt));
   2449 
   2450   EXPECT_EQ(protobuf_unittest::DummyMessageContainingEnum::TEST_OPTION_ENUM_TYPE2,
   2451             options->GetExtension(protobuf_unittest::enum_opt));
   2452 
   2453   options =
   2454       &protobuf_unittest::SettingRealsFromPositiveInts::descriptor()->options();
   2455   EXPECT_FLOAT_EQ(12, options->GetExtension(protobuf_unittest::float_opt));
   2456   EXPECT_DOUBLE_EQ(154, options->GetExtension(protobuf_unittest::double_opt));
   2457 
   2458   options =
   2459       &protobuf_unittest::SettingRealsFromNegativeInts::descriptor()->options();
   2460   EXPECT_FLOAT_EQ(-12, options->GetExtension(protobuf_unittest::float_opt));
   2461   EXPECT_DOUBLE_EQ(-154, options->GetExtension(protobuf_unittest::double_opt));
   2462 }
   2463 
   2464 TEST(CustomOptions, ComplexExtensionOptions) {
   2465   const MessageOptions* options =
   2466       &protobuf_unittest::VariousComplexOptions::descriptor()->options();
   2467   EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1).foo(), 42);
   2468   EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1).
   2469             GetExtension(protobuf_unittest::quux), 324);
   2470   EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1).
   2471             GetExtension(protobuf_unittest::corge).qux(), 876);
   2472   EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).baz(), 987);
   2473   EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
   2474             GetExtension(protobuf_unittest::grault), 654);
   2475   EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).bar().foo(),
   2476             743);
   2477   EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).bar().
   2478             GetExtension(protobuf_unittest::quux), 1999);
   2479   EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).bar().
   2480             GetExtension(protobuf_unittest::corge).qux(), 2008);
   2481   EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
   2482             GetExtension(protobuf_unittest::garply).foo(), 741);
   2483   EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
   2484             GetExtension(protobuf_unittest::garply).
   2485             GetExtension(protobuf_unittest::quux), 1998);
   2486   EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
   2487             GetExtension(protobuf_unittest::garply).
   2488             GetExtension(protobuf_unittest::corge).qux(), 2121);
   2489   EXPECT_EQ(options->GetExtension(
   2490       protobuf_unittest::ComplexOptionType2::ComplexOptionType4::complex_opt4).
   2491             waldo(), 1971);
   2492   EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
   2493             fred().waldo(), 321);
   2494   EXPECT_EQ(9, options->GetExtension(protobuf_unittest::complex_opt3).qux());
   2495   EXPECT_EQ(22, options->GetExtension(protobuf_unittest::complex_opt3).
   2496                 complexoptiontype5().plugh());
   2497   EXPECT_EQ(24, options->GetExtension(protobuf_unittest::complexopt6).xyzzy());
   2498 }
   2499 
   2500 TEST(CustomOptions, OptionsFromOtherFile) {
   2501   // Test that to use a custom option, we only need to import the file
   2502   // defining the option; we do not also have to import descriptor.proto.
   2503   DescriptorPool pool;
   2504 
   2505   FileDescriptorProto file_proto;
   2506   FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
   2507   ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
   2508 
   2509   protobuf_unittest::TestMessageWithCustomOptions::descriptor()
   2510     ->file()->CopyTo(&file_proto);
   2511   ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
   2512 
   2513   ASSERT_TRUE(TextFormat::ParseFromString(
   2514     "name: \"custom_options_import.proto\" "
   2515     "package: \"protobuf_unittest\" "
   2516     "dependency: \"google/protobuf/unittest_custom_options.proto\" "
   2517     "options { "
   2518     "  uninterpreted_option { "
   2519     "    name { "
   2520     "      name_part: \"file_opt1\" "
   2521     "      is_extension: true "
   2522     "    } "
   2523     "    positive_int_value: 1234 "
   2524     "  } "
   2525     // Test a non-extension option too.  (At one point this failed due to a
   2526     // bug.)
   2527     "  uninterpreted_option { "
   2528     "    name { "
   2529     "      name_part: \"java_package\" "
   2530     "      is_extension: false "
   2531     "    } "
   2532     "    string_value: \"foo\" "
   2533     "  } "
   2534     // Test that enum-typed options still work too.  (At one point this also
   2535     // failed due to a bug.)
   2536     "  uninterpreted_option { "
   2537     "    name { "
   2538     "      name_part: \"optimize_for\" "
   2539     "      is_extension: false "
   2540     "    } "
   2541     "    identifier_value: \"SPEED\" "
   2542     "  } "
   2543     "}"
   2544     ,
   2545     &file_proto));
   2546 
   2547   const FileDescriptor* file = pool.BuildFile(file_proto);
   2548   ASSERT_TRUE(file != NULL);
   2549   EXPECT_EQ(1234, file->options().GetExtension(protobuf_unittest::file_opt1));
   2550   EXPECT_TRUE(file->options().has_java_package());
   2551   EXPECT_EQ("foo", file->options().java_package());
   2552   EXPECT_TRUE(file->options().has_optimize_for());
   2553   EXPECT_EQ(FileOptions::SPEED, file->options().optimize_for());
   2554 }
   2555 
   2556 TEST(CustomOptions, MessageOptionThreeFieldsSet) {
   2557   // This tests a bug which previously existed in custom options parsing.  The
   2558   // bug occurred when you defined a custom option with message type and then
   2559   // set three fields of that option on a single definition (see the example
   2560   // below).  The bug is a bit hard to explain, so check the change history if
   2561   // you want to know more.
   2562   DescriptorPool pool;
   2563 
   2564   FileDescriptorProto file_proto;
   2565   FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
   2566   ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
   2567 
   2568   protobuf_unittest::TestMessageWithCustomOptions::descriptor()
   2569     ->file()->CopyTo(&file_proto);
   2570   ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
   2571 
   2572   // The following represents the definition:
   2573   //
   2574   //   import "google/protobuf/unittest_custom_options.proto"
   2575   //   package protobuf_unittest;
   2576   //   message Foo {
   2577   //     option (complex_opt1).foo  = 1234;
   2578   //     option (complex_opt1).foo2 = 1234;
   2579   //     option (complex_opt1).foo3 = 1234;
   2580   //   }
   2581   ASSERT_TRUE(TextFormat::ParseFromString(
   2582     "name: \"custom_options_import.proto\" "
   2583     "package: \"protobuf_unittest\" "
   2584     "dependency: \"google/protobuf/unittest_custom_options.proto\" "
   2585     "message_type { "
   2586     "  name: \"Foo\" "
   2587     "  options { "
   2588     "    uninterpreted_option { "
   2589     "      name { "
   2590     "        name_part: \"complex_opt1\" "
   2591     "        is_extension: true "
   2592     "      } "
   2593     "      name { "
   2594     "        name_part: \"foo\" "
   2595     "        is_extension: false "
   2596     "      } "
   2597     "      positive_int_value: 1234 "
   2598     "    } "
   2599     "    uninterpreted_option { "
   2600     "      name { "
   2601     "        name_part: \"complex_opt1\" "
   2602     "        is_extension: true "
   2603     "      } "
   2604     "      name { "
   2605     "        name_part: \"foo2\" "
   2606     "        is_extension: false "
   2607     "      } "
   2608     "      positive_int_value: 1234 "
   2609     "    } "
   2610     "    uninterpreted_option { "
   2611     "      name { "
   2612     "        name_part: \"complex_opt1\" "
   2613     "        is_extension: true "
   2614     "      } "
   2615     "      name { "
   2616     "        name_part: \"foo3\" "
   2617     "        is_extension: false "
   2618     "      } "
   2619     "      positive_int_value: 1234 "
   2620     "    } "
   2621     "  } "
   2622     "}",
   2623     &file_proto));
   2624 
   2625   const FileDescriptor* file = pool.BuildFile(file_proto);
   2626   ASSERT_TRUE(file != NULL);
   2627   ASSERT_EQ(1, file->message_type_count());
   2628 
   2629   const MessageOptions& options = file->message_type(0)->options();
   2630   EXPECT_EQ(1234, options.GetExtension(protobuf_unittest::complex_opt1).foo());
   2631 }
   2632 
   2633 TEST(CustomOptions, MessageOptionRepeatedLeafFieldSet) {
   2634   // This test verifies that repeated fields in custom options can be
   2635   // given multiple values by repeating the option with a different value.
   2636   // This test checks repeated leaf values. Each repeated custom value
   2637   // appears in a different uninterpreted_option, which will be concatenated
   2638   // when they are merged into the final option value.
   2639   DescriptorPool pool;
   2640 
   2641   FileDescriptorProto file_proto;
   2642   FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
   2643   ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
   2644 
   2645   protobuf_unittest::TestMessageWithCustomOptions::descriptor()
   2646     ->file()->CopyTo(&file_proto);
   2647   ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
   2648 
   2649   // The following represents the definition:
   2650   //
   2651   //   import "google/protobuf/unittest_custom_options.proto"
   2652   //   package protobuf_unittest;
   2653   //   message Foo {
   2654   //     option (complex_opt1).foo4 = 12;
   2655   //     option (complex_opt1).foo4 = 34;
   2656   //     option (complex_opt1).foo4 = 56;
   2657   //   }
   2658   ASSERT_TRUE(TextFormat::ParseFromString(
   2659     "name: \"custom_options_import.proto\" "
   2660     "package: \"protobuf_unittest\" "
   2661     "dependency: \"google/protobuf/unittest_custom_options.proto\" "
   2662     "message_type { "
   2663     "  name: \"Foo\" "
   2664     "  options { "
   2665     "    uninterpreted_option { "
   2666     "      name { "
   2667     "        name_part: \"complex_opt1\" "
   2668     "        is_extension: true "
   2669     "      } "
   2670     "      name { "
   2671     "        name_part: \"foo4\" "
   2672     "        is_extension: false "
   2673     "      } "
   2674     "      positive_int_value: 12 "
   2675     "    } "
   2676     "    uninterpreted_option { "
   2677     "      name { "
   2678     "        name_part: \"complex_opt1\" "
   2679     "        is_extension: true "
   2680     "      } "
   2681     "      name { "
   2682     "        name_part: \"foo4\" "
   2683     "        is_extension: false "
   2684     "      } "
   2685     "      positive_int_value: 34 "
   2686     "    } "
   2687     "    uninterpreted_option { "
   2688     "      name { "
   2689     "        name_part: \"complex_opt1\" "
   2690     "        is_extension: true "
   2691     "      } "
   2692     "      name { "
   2693     "        name_part: \"foo4\" "
   2694     "        is_extension: false "
   2695     "      } "
   2696     "      positive_int_value: 56 "
   2697     "    } "
   2698     "  } "
   2699     "}",
   2700     &file_proto));
   2701 
   2702   const FileDescriptor* file = pool.BuildFile(file_proto);
   2703   ASSERT_TRUE(file != NULL);
   2704   ASSERT_EQ(1, file->message_type_count());
   2705 
   2706   const MessageOptions& options = file->message_type(0)->options();
   2707   EXPECT_EQ(3, options.GetExtension(protobuf_unittest::complex_opt1).foo4_size());
   2708   EXPECT_EQ(12, options.GetExtension(protobuf_unittest::complex_opt1).foo4(0));
   2709   EXPECT_EQ(34, options.GetExtension(protobuf_unittest::complex_opt1).foo4(1));
   2710   EXPECT_EQ(56, options.GetExtension(protobuf_unittest::complex_opt1).foo4(2));
   2711 }
   2712 
   2713 TEST(CustomOptions, MessageOptionRepeatedMsgFieldSet) {
   2714   // This test verifies that repeated fields in custom options can be
   2715   // given multiple values by repeating the option with a different value.
   2716   // This test checks repeated message values. Each repeated custom value
   2717   // appears in a different uninterpreted_option, which will be concatenated
   2718   // when they are merged into the final option value.
   2719   DescriptorPool pool;
   2720 
   2721   FileDescriptorProto file_proto;
   2722   FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
   2723   ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
   2724 
   2725   protobuf_unittest::TestMessageWithCustomOptions::descriptor()
   2726     ->file()->CopyTo(&file_proto);
   2727   ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
   2728 
   2729   // The following represents the definition:
   2730   //
   2731   //   import "google/protobuf/unittest_custom_options.proto"
   2732   //   package protobuf_unittest;
   2733   //   message Foo {
   2734   //     option (complex_opt2).barney = {waldo: 1};
   2735   //     option (complex_opt2).barney = {waldo: 10};
   2736   //     option (complex_opt2).barney = {waldo: 100};
   2737   //   }
   2738   ASSERT_TRUE(TextFormat::ParseFromString(
   2739     "name: \"custom_options_import.proto\" "
   2740     "package: \"protobuf_unittest\" "
   2741     "dependency: \"google/protobuf/unittest_custom_options.proto\" "
   2742     "message_type { "
   2743     "  name: \"Foo\" "
   2744     "  options { "
   2745     "    uninterpreted_option { "
   2746     "      name { "
   2747     "        name_part: \"complex_opt2\" "
   2748     "        is_extension: true "
   2749     "      } "
   2750     "      name { "
   2751     "        name_part: \"barney\" "
   2752     "        is_extension: false "
   2753     "      } "
   2754     "      aggregate_value: \"waldo: 1\" "
   2755     "    } "
   2756     "    uninterpreted_option { "
   2757     "      name { "
   2758     "        name_part: \"complex_opt2\" "
   2759     "        is_extension: true "
   2760     "      } "
   2761     "      name { "
   2762     "        name_part: \"barney\" "
   2763     "        is_extension: false "
   2764     "      } "
   2765     "      aggregate_value: \"waldo: 10\" "
   2766     "    } "
   2767     "    uninterpreted_option { "
   2768     "      name { "
   2769     "        name_part: \"complex_opt2\" "
   2770     "        is_extension: true "
   2771     "      } "
   2772     "      name { "
   2773     "        name_part: \"barney\" "
   2774     "        is_extension: false "
   2775     "      } "
   2776     "      aggregate_value: \"waldo: 100\" "
   2777     "    } "
   2778     "  } "
   2779     "}",
   2780     &file_proto));
   2781 
   2782   const FileDescriptor* file = pool.BuildFile(file_proto);
   2783   ASSERT_TRUE(file != NULL);
   2784   ASSERT_EQ(1, file->message_type_count());
   2785 
   2786   const MessageOptions& options = file->message_type(0)->options();
   2787   EXPECT_EQ(3, options.GetExtension(
   2788       protobuf_unittest::complex_opt2).barney_size());
   2789   EXPECT_EQ(1,options.GetExtension(
   2790       protobuf_unittest::complex_opt2).barney(0).waldo());
   2791   EXPECT_EQ(10, options.GetExtension(
   2792       protobuf_unittest::complex_opt2).barney(1).waldo());
   2793   EXPECT_EQ(100, options.GetExtension(
   2794       protobuf_unittest::complex_opt2).barney(2).waldo());
   2795 }
   2796 
   2797 // Check that aggregate options were parsed and saved correctly in
   2798 // the appropriate descriptors.
   2799 TEST(CustomOptions, AggregateOptions) {
   2800   const Descriptor* msg = protobuf_unittest::AggregateMessage::descriptor();
   2801   const FileDescriptor* file = msg->file();
   2802   const FieldDescriptor* field = msg->FindFieldByName("fieldname");
   2803   const EnumDescriptor* enumd = file->FindEnumTypeByName("AggregateEnum");
   2804   const EnumValueDescriptor* enumv = enumd->FindValueByName("VALUE");
   2805   const ServiceDescriptor* service = file->FindServiceByName(
   2806       "AggregateService");
   2807   const MethodDescriptor* method = service->FindMethodByName("Method");
   2808 
   2809   // Tests for the different types of data embedded in fileopt
   2810   const protobuf_unittest::Aggregate& file_options =
   2811       file->options().GetExtension(protobuf_unittest::fileopt);
   2812   EXPECT_EQ(100, file_options.i());
   2813   EXPECT_EQ("FileAnnotation", file_options.s());
   2814   EXPECT_EQ("NestedFileAnnotation", file_options.sub().s());
   2815   EXPECT_EQ("FileExtensionAnnotation",
   2816             file_options.file().GetExtension(protobuf_unittest::fileopt).s());
   2817   EXPECT_EQ("EmbeddedMessageSetElement",
   2818             file_options.mset().GetExtension(
   2819                 protobuf_unittest::AggregateMessageSetElement
   2820                 ::message_set_extension).s());
   2821 
   2822   // Simple tests for all the other types of annotations
   2823   EXPECT_EQ("MessageAnnotation",
   2824             msg->options().GetExtension(protobuf_unittest::msgopt).s());
   2825   EXPECT_EQ("FieldAnnotation",
   2826             field->options().GetExtension(protobuf_unittest::fieldopt).s());
   2827   EXPECT_EQ("EnumAnnotation",
   2828             enumd->options().GetExtension(protobuf_unittest::enumopt).s());
   2829   EXPECT_EQ("EnumValueAnnotation",
   2830             enumv->options().GetExtension(protobuf_unittest::enumvalopt).s());
   2831   EXPECT_EQ("ServiceAnnotation",
   2832             service->options().GetExtension(protobuf_unittest::serviceopt).s());
   2833   EXPECT_EQ("MethodAnnotation",
   2834             method->options().GetExtension(protobuf_unittest::methodopt).s());
   2835 }
   2836 
   2837 TEST(CustomOptions, UnusedImportWarning) {
   2838   DescriptorPool pool;
   2839 
   2840   FileDescriptorProto file_proto;
   2841   FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
   2842   ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
   2843 
   2844   protobuf_unittest::TestMessageWithCustomOptions::descriptor()
   2845       ->file()->CopyTo(&file_proto);
   2846   ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
   2847 
   2848 
   2849   pool.AddUnusedImportTrackFile("custom_options_import.proto");
   2850   ASSERT_TRUE(TextFormat::ParseFromString(
   2851     "name: \"custom_options_import.proto\" "
   2852     "package: \"protobuf_unittest\" "
   2853     "dependency: \"google/protobuf/unittest_custom_options.proto\" ",
   2854     &file_proto));
   2855   pool.BuildFile(file_proto);
   2856 }
   2857 
   2858 // ===================================================================
   2859 
   2860 // The tests below trigger every unique call to AddError() in descriptor.cc,
   2861 // in the order in which they appear in that file.  I'm using TextFormat here
   2862 // to specify the input descriptors because building them using code would
   2863 // be too bulky.
   2864 
   2865 class MockErrorCollector : public DescriptorPool::ErrorCollector {
   2866  public:
   2867   MockErrorCollector() {}
   2868   ~MockErrorCollector() {}
   2869 
   2870   string text_;
   2871   string warning_text_;
   2872 
   2873   // implements ErrorCollector ---------------------------------------
   2874   void AddError(const string& filename,
   2875                 const string& element_name, const Message* descriptor,
   2876                 ErrorLocation location, const string& message) {
   2877     const char* location_name = NULL;
   2878     switch (location) {
   2879       case NAME         : location_name = "NAME"         ; break;
   2880       case NUMBER       : location_name = "NUMBER"       ; break;
   2881       case TYPE         : location_name = "TYPE"         ; break;
   2882       case EXTENDEE     : location_name = "EXTENDEE"     ; break;
   2883       case DEFAULT_VALUE: location_name = "DEFAULT_VALUE"; break;
   2884       case OPTION_NAME  : location_name = "OPTION_NAME"  ; break;
   2885       case OPTION_VALUE : location_name = "OPTION_VALUE" ; break;
   2886       case INPUT_TYPE   : location_name = "INPUT_TYPE"   ; break;
   2887       case OUTPUT_TYPE  : location_name = "OUTPUT_TYPE"  ; break;
   2888       case OTHER        : location_name = "OTHER"        ; break;
   2889     }
   2890 
   2891     strings::SubstituteAndAppend(
   2892       &text_, "$0: $1: $2: $3\n",
   2893       filename, element_name, location_name, message);
   2894   }
   2895 
   2896   // implements ErrorCollector ---------------------------------------
   2897   void AddWarning(const string& filename, const string& element_name,
   2898                   const Message* descriptor, ErrorLocation location,
   2899                   const string& message) {
   2900     const char* location_name = NULL;
   2901     switch (location) {
   2902       case NAME         : location_name = "NAME"         ; break;
   2903       case NUMBER       : location_name = "NUMBER"       ; break;
   2904       case TYPE         : location_name = "TYPE"         ; break;
   2905       case EXTENDEE     : location_name = "EXTENDEE"     ; break;
   2906       case DEFAULT_VALUE: location_name = "DEFAULT_VALUE"; break;
   2907       case OPTION_NAME  : location_name = "OPTION_NAME"  ; break;
   2908       case OPTION_VALUE : location_name = "OPTION_VALUE" ; break;
   2909       case INPUT_TYPE   : location_name = "INPUT_TYPE"   ; break;
   2910       case OUTPUT_TYPE  : location_name = "OUTPUT_TYPE"  ; break;
   2911       case OTHER        : location_name = "OTHER"        ; break;
   2912     }
   2913 
   2914     strings::SubstituteAndAppend(
   2915       &warning_text_, "$0: $1: $2: $3\n",
   2916       filename, element_name, location_name, message);
   2917   }
   2918 };
   2919 
   2920 class ValidationErrorTest : public testing::Test {
   2921  protected:
   2922   // Parse file_text as a FileDescriptorProto in text format and add it
   2923   // to the DescriptorPool.  Expect no errors.
   2924   void BuildFile(const string& file_text) {
   2925     FileDescriptorProto file_proto;
   2926     ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
   2927     ASSERT_TRUE(pool_.BuildFile(file_proto) != NULL);
   2928   }
   2929 
   2930   // Parse file_text as a FileDescriptorProto in text format and add it
   2931   // to the DescriptorPool.  Expect errors to be produced which match the
   2932   // given error text.
   2933   void BuildFileWithErrors(const string& file_text,
   2934                            const string& expected_errors) {
   2935     FileDescriptorProto file_proto;
   2936     ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
   2937 
   2938     MockErrorCollector error_collector;
   2939     EXPECT_TRUE(
   2940       pool_.BuildFileCollectingErrors(file_proto, &error_collector) == NULL);
   2941     EXPECT_EQ(expected_errors, error_collector.text_);
   2942   }
   2943 
   2944   // Parse file_text as a FileDescriptorProto in text format and add it
   2945   // to the DescriptorPool.  Expect errors to be produced which match the
   2946   // given warning text.
   2947   void BuildFileWithWarnings(const string& file_text,
   2948                              const string& expected_warnings) {
   2949     FileDescriptorProto file_proto;
   2950     ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
   2951 
   2952     MockErrorCollector error_collector;
   2953     EXPECT_TRUE(pool_.BuildFileCollectingErrors(file_proto, &error_collector));
   2954     EXPECT_EQ(expected_warnings, error_collector.warning_text_);
   2955   }
   2956 
   2957   // Builds some already-parsed file in our test pool.
   2958   void BuildFileInTestPool(const FileDescriptor* file) {
   2959     FileDescriptorProto file_proto;
   2960     file->CopyTo(&file_proto);
   2961     ASSERT_TRUE(pool_.BuildFile(file_proto) != NULL);
   2962   }
   2963 
   2964   // Build descriptor.proto in our test pool. This allows us to extend it in
   2965   // the test pool, so we can test custom options.
   2966   void BuildDescriptorMessagesInTestPool() {
   2967     BuildFileInTestPool(DescriptorProto::descriptor()->file());
   2968   }
   2969 
   2970   DescriptorPool pool_;
   2971 };
   2972 
   2973 TEST_F(ValidationErrorTest, AlreadyDefined) {
   2974   BuildFileWithErrors(
   2975     "name: \"foo.proto\" "
   2976     "message_type { name: \"Foo\" }"
   2977     "message_type { name: \"Foo\" }",
   2978 
   2979     "foo.proto: Foo: NAME: \"Foo\" is already defined.\n");
   2980 }
   2981 
   2982 TEST_F(ValidationErrorTest, AlreadyDefinedInPackage) {
   2983   BuildFileWithErrors(
   2984     "name: \"foo.proto\" "
   2985     "package: \"foo.bar\" "
   2986     "message_type { name: \"Foo\" }"
   2987     "message_type { name: \"Foo\" }",
   2988 
   2989     "foo.proto: foo.bar.Foo: NAME: \"Foo\" is already defined in "
   2990       "\"foo.bar\".\n");
   2991 }
   2992 
   2993 TEST_F(ValidationErrorTest, AlreadyDefinedInOtherFile) {
   2994   BuildFile(
   2995     "name: \"foo.proto\" "
   2996     "message_type { name: \"Foo\" }");
   2997 
   2998   BuildFileWithErrors(
   2999     "name: \"bar.proto\" "
   3000     "message_type { name: \"Foo\" }",
   3001 
   3002     "bar.proto: Foo: NAME: \"Foo\" is already defined in file "
   3003       "\"foo.proto\".\n");
   3004 }
   3005 
   3006 TEST_F(ValidationErrorTest, PackageAlreadyDefined) {
   3007   BuildFile(
   3008     "name: \"foo.proto\" "
   3009     "message_type { name: \"foo\" }");
   3010   BuildFileWithErrors(
   3011     "name: \"bar.proto\" "
   3012     "package: \"foo.bar\"",
   3013 
   3014     "bar.proto: foo: NAME: \"foo\" is already defined (as something other "
   3015       "than a package) in file \"foo.proto\".\n");
   3016 }
   3017 
   3018 TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParent) {
   3019   BuildFileWithErrors(
   3020     "name: \"foo.proto\" "
   3021     "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } "
   3022     "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ",
   3023 
   3024     "foo.proto: FOO: NAME: \"FOO\" is already defined.\n"
   3025     "foo.proto: FOO: NAME: Note that enum values use C++ scoping rules, "
   3026       "meaning that enum values are siblings of their type, not children of "
   3027       "it.  Therefore, \"FOO\" must be unique within the global scope, not "
   3028       "just within \"Bar\".\n");
   3029 }
   3030 
   3031 TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParentNonGlobal) {
   3032   BuildFileWithErrors(
   3033     "name: \"foo.proto\" "
   3034     "package: \"pkg\" "
   3035     "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } "
   3036     "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ",
   3037 
   3038     "foo.proto: pkg.FOO: NAME: \"FOO\" is already defined in \"pkg\".\n"
   3039     "foo.proto: pkg.FOO: NAME: Note that enum values use C++ scoping rules, "
   3040       "meaning that enum values are siblings of their type, not children of "
   3041       "it.  Therefore, \"FOO\" must be unique within \"pkg\", not just within "
   3042       "\"Bar\".\n");
   3043 }
   3044 
   3045 TEST_F(ValidationErrorTest, MissingName) {
   3046   BuildFileWithErrors(
   3047     "name: \"foo.proto\" "
   3048     "message_type { }",
   3049 
   3050     "foo.proto: : NAME: Missing name.\n");
   3051 }
   3052 
   3053 TEST_F(ValidationErrorTest, InvalidName) {
   3054   BuildFileWithErrors(
   3055     "name: \"foo.proto\" "
   3056     "message_type { name: \"$\" }",
   3057 
   3058     "foo.proto: $: NAME: \"$\" is not a valid identifier.\n");
   3059 }
   3060 
   3061 TEST_F(ValidationErrorTest, InvalidPackageName) {
   3062   BuildFileWithErrors(
   3063     "name: \"foo.proto\" "
   3064     "package: \"foo.$\"",
   3065 
   3066     "foo.proto: foo.$: NAME: \"$\" is not a valid identifier.\n");
   3067 }
   3068 
   3069 TEST_F(ValidationErrorTest, MissingFileName) {
   3070   BuildFileWithErrors(
   3071     "",
   3072 
   3073     ": : OTHER: Missing field: FileDescriptorProto.name.\n");
   3074 }
   3075 
   3076 TEST_F(ValidationErrorTest, DupeDependency) {
   3077   BuildFile("name: \"foo.proto\"");
   3078   BuildFileWithErrors(
   3079     "name: \"bar.proto\" "
   3080     "dependency: \"foo.proto\" "
   3081     "dependency: \"foo.proto\" ",
   3082 
   3083     "bar.proto: bar.proto: OTHER: Import \"foo.proto\" was listed twice.\n");
   3084 }
   3085 
   3086 TEST_F(ValidationErrorTest, UnknownDependency) {
   3087   BuildFileWithErrors(
   3088     "name: \"bar.proto\" "
   3089     "dependency: \"foo.proto\" ",
   3090 
   3091     "bar.proto: bar.proto: OTHER: Import \"foo.proto\" has not been loaded.\n");
   3092 }
   3093 
   3094 TEST_F(ValidationErrorTest, InvalidPublicDependencyIndex) {
   3095   BuildFile("name: \"foo.proto\"");
   3096   BuildFileWithErrors(
   3097     "name: \"bar.proto\" "
   3098     "dependency: \"foo.proto\" "
   3099     "public_dependency: 1",
   3100     "bar.proto: bar.proto: OTHER: Invalid public dependency index.\n");
   3101 }
   3102 
   3103 TEST_F(ValidationErrorTest, ForeignUnimportedPackageNoCrash) {
   3104   // Used to crash:  If we depend on a non-existent file and then refer to a
   3105   // package defined in a file that we didn't import, and that package is
   3106   // nested within a parent package which this file is also in, and we don't
   3107   // include that parent package in the name (i.e. we do a relative lookup)...
   3108   // Yes, really.
   3109   BuildFile(
   3110     "name: 'foo.proto' "
   3111     "package: 'outer.foo' ");
   3112   BuildFileWithErrors(
   3113     "name: 'bar.proto' "
   3114     "dependency: 'baz.proto' "
   3115     "package: 'outer.bar' "
   3116     "message_type { "
   3117     "  name: 'Bar' "
   3118     "  field { name:'bar' number:1 label:LABEL_OPTIONAL type_name:'foo.Foo' }"
   3119     "}",
   3120 
   3121     "bar.proto: bar.proto: OTHER: Import \"baz.proto\" has not been loaded.\n"
   3122     "bar.proto: outer.bar.Bar.bar: TYPE: \"outer.foo\" seems to be defined in "
   3123       "\"foo.proto\", which is not imported by \"bar.proto\".  To use it here, "
   3124       "please add the necessary import.\n");
   3125 }
   3126 
   3127 TEST_F(ValidationErrorTest, DupeFile) {
   3128   BuildFile(
   3129     "name: \"foo.proto\" "
   3130     "message_type { name: \"Foo\" }");
   3131   // Note:  We should *not* get redundant errors about "Foo" already being
   3132   //   defined.
   3133   BuildFileWithErrors(
   3134     "name: \"foo.proto\" "
   3135     "message_type { name: \"Foo\" } "
   3136     // Add another type so that the files aren't identical (in which case there
   3137     // would be no error).
   3138     "enum_type { name: \"Bar\" }",
   3139 
   3140     "foo.proto: foo.proto: OTHER: A file with this name is already in the "
   3141       "pool.\n");
   3142 }
   3143 
   3144 TEST_F(ValidationErrorTest, FieldInExtensionRange) {
   3145   BuildFileWithErrors(
   3146     "name: \"foo.proto\" "
   3147     "message_type {"
   3148     "  name: \"Foo\""
   3149     "  field { name: \"foo\" number:  9 label:LABEL_OPTIONAL type:TYPE_INT32 }"
   3150     "  field { name: \"bar\" number: 10 label:LABEL_OPTIONAL type:TYPE_INT32 }"
   3151     "  field { name: \"baz\" number: 19 label:LABEL_OPTIONAL type:TYPE_INT32 }"
   3152     "  field { name: \"qux\" number: 20 label:LABEL_OPTIONAL type:TYPE_INT32 }"
   3153     "  extension_range { start: 10 end: 20 }"
   3154     "}",
   3155 
   3156     "foo.proto: Foo.bar: NUMBER: Extension range 10 to 19 includes field "
   3157       "\"bar\" (10).\n"
   3158     "foo.proto: Foo.baz: NUMBER: Extension range 10 to 19 includes field "
   3159       "\"baz\" (19).\n");
   3160 }
   3161 
   3162 TEST_F(ValidationErrorTest, OverlappingExtensionRanges) {
   3163   BuildFileWithErrors(
   3164     "name: \"foo.proto\" "
   3165     "message_type {"
   3166     "  name: \"Foo\""
   3167     "  extension_range { start: 10 end: 20 }"
   3168     "  extension_range { start: 20 end: 30 }"
   3169     "  extension_range { start: 19 end: 21 }"
   3170     "}",
   3171 
   3172     "foo.proto: Foo: NUMBER: Extension range 19 to 20 overlaps with "
   3173       "already-defined range 10 to 19.\n"
   3174     "foo.proto: Foo: NUMBER: Extension range 19 to 20 overlaps with "
   3175       "already-defined range 20 to 29.\n");
   3176 }
   3177 
   3178 TEST_F(ValidationErrorTest, InvalidDefaults) {
   3179   BuildFileWithErrors(
   3180     "name: \"foo.proto\" "
   3181     "message_type {"
   3182     "  name: \"Foo\""
   3183 
   3184     // Invalid number.
   3185     "  field { name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32"
   3186     "          default_value: \"abc\" }"
   3187 
   3188     // Empty default value.
   3189     "  field { name: \"bar\" number: 2 label: LABEL_OPTIONAL type: TYPE_INT32"
   3190     "          default_value: \"\" }"
   3191 
   3192     // Invalid boolean.
   3193     "  field { name: \"baz\" number: 3 label: LABEL_OPTIONAL type: TYPE_BOOL"
   3194     "          default_value: \"abc\" }"
   3195 
   3196     // Messages can't have defaults.
   3197     "  field { name: \"qux\" number: 4 label: LABEL_OPTIONAL type: TYPE_MESSAGE"
   3198     "          default_value: \"abc\" type_name: \"Foo\" }"
   3199 
   3200     // Same thing, but we don't know that this field has message type until
   3201     // we look up the type name.
   3202     "  field { name: \"quux\" number: 5 label: LABEL_OPTIONAL"
   3203     "          default_value: \"abc\" type_name: \"Foo\" }"
   3204 
   3205     // Repeateds can't have defaults.
   3206     "  field { name: \"corge\" number: 6 label: LABEL_REPEATED type: TYPE_INT32"
   3207     "          default_value: \"1\" }"
   3208     "}",
   3209 
   3210     "foo.proto: Foo.foo: DEFAULT_VALUE: Couldn't parse default value \"abc\".\n"
   3211     "foo.proto: Foo.bar: DEFAULT_VALUE: Couldn't parse default value \"\".\n"
   3212     "foo.proto: Foo.baz: DEFAULT_VALUE: Boolean default must be true or "
   3213       "false.\n"
   3214     "foo.proto: Foo.qux: DEFAULT_VALUE: Messages can't have default values.\n"
   3215     "foo.proto: Foo.corge: DEFAULT_VALUE: Repeated fields can't have default "
   3216       "values.\n"
   3217     // This ends up being reported later because the error is detected at
   3218     // cross-linking time.
   3219     "foo.proto: Foo.quux: DEFAULT_VALUE: Messages can't have default "
   3220       "values.\n");
   3221 }
   3222 
   3223 TEST_F(ValidationErrorTest, NegativeFieldNumber) {
   3224   BuildFileWithErrors(
   3225     "name: \"foo.proto\" "
   3226     "message_type {"
   3227     "  name: \"Foo\""
   3228     "  field { name: \"foo\" number: -1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
   3229     "}",
   3230 
   3231     "foo.proto: Foo.foo: NUMBER: Field numbers must be positive integers.\n");
   3232 }
   3233 
   3234 TEST_F(ValidationErrorTest, HugeFieldNumber) {
   3235   BuildFileWithErrors(
   3236     "name: \"foo.proto\" "
   3237     "message_type {"
   3238     "  name: \"Foo\""
   3239     "  field { name: \"foo\" number: 0x70000000 "
   3240     "          label:LABEL_OPTIONAL type:TYPE_INT32 }"
   3241     "}",
   3242 
   3243     "foo.proto: Foo.foo: NUMBER: Field numbers cannot be greater than "
   3244       "536870911.\n");
   3245 }
   3246 
   3247 TEST_F(ValidationErrorTest, ReservedFieldNumber) {
   3248   BuildFileWithErrors(
   3249     "name: \"foo.proto\" "
   3250     "message_type {"
   3251     "  name: \"Foo\""
   3252     "  field {name:\"foo\" number: 18999 label:LABEL_OPTIONAL type:TYPE_INT32 }"
   3253     "  field {name:\"bar\" number: 19000 label:LABEL_OPTIONAL type:TYPE_INT32 }"
   3254     "  field {name:\"baz\" number: 19999 label:LABEL_OPTIONAL type:TYPE_INT32 }"
   3255     "  field {name:\"qux\" number: 20000 label:LABEL_OPTIONAL type:TYPE_INT32 }"
   3256     "}",
   3257 
   3258     "foo.proto: Foo.bar: NUMBER: Field numbers 19000 through 19999 are "
   3259       "reserved for the protocol buffer library implementation.\n"
   3260     "foo.proto: Foo.baz: NUMBER: Field numbers 19000 through 19999 are "
   3261       "reserved for the protocol buffer library implementation.\n");
   3262 }
   3263 
   3264 TEST_F(ValidationErrorTest, ExtensionMissingExtendee) {
   3265   BuildFileWithErrors(
   3266     "name: \"foo.proto\" "
   3267     "message_type {"
   3268     "  name: \"Foo\""
   3269     "  extension { name: \"foo\" number: 1 label: LABEL_OPTIONAL"
   3270     "              type_name: \"Foo\" }"
   3271     "}",
   3272 
   3273     "foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee not set for "
   3274       "extension field.\n");
   3275 }
   3276 
   3277 TEST_F(ValidationErrorTest, NonExtensionWithExtendee) {
   3278   BuildFileWithErrors(
   3279     "name: \"foo.proto\" "
   3280     "message_type {"
   3281     "  name: \"Bar\""
   3282     "  extension_range { start: 1 end: 2 }"
   3283     "}"
   3284     "message_type {"
   3285     "  name: \"Foo\""
   3286     "  field { name: \"foo\" number: 1 label: LABEL_OPTIONAL"
   3287     "          type_name: \"Foo\" extendee: \"Bar\" }"
   3288     "}",
   3289 
   3290     "foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee set for "
   3291       "non-extension field.\n");
   3292 }
   3293 
   3294 TEST_F(ValidationErrorTest, FieldOneofIndexTooLarge) {
   3295   BuildFileWithErrors(
   3296     "name: \"foo.proto\" "
   3297     "message_type {"
   3298     "  name: \"Foo\""
   3299     "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32 "
   3300     "          oneof_index: 1 }"
   3301     "  field { name:\"dummy\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 "
   3302     "          oneof_index: 0 }"
   3303     "  oneof_decl { name:\"bar\" }"
   3304     "}",
   3305 
   3306     "foo.proto: Foo.foo: OTHER: FieldDescriptorProto.oneof_index 1 is out of "
   3307       "range for type \"Foo\".\n");
   3308 }
   3309 
   3310 TEST_F(ValidationErrorTest, FieldOneofIndexNegative) {
   3311   BuildFileWithErrors(
   3312     "name: \"foo.proto\" "
   3313     "message_type {"
   3314     "  name: \"Foo\""
   3315     "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32 "
   3316     "          oneof_index: -1 }"
   3317     "  field { name:\"dummy\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 "
   3318     "          oneof_index: 0 }"
   3319     "  oneof_decl { name:\"bar\" }"
   3320     "}",
   3321 
   3322     "foo.proto: Foo.foo: OTHER: FieldDescriptorProto.oneof_index -1 is out of "
   3323       "range for type \"Foo\".\n");
   3324 }
   3325 
   3326 TEST_F(ValidationErrorTest, FieldNumberConflict) {
   3327   BuildFileWithErrors(
   3328     "name: \"foo.proto\" "
   3329     "message_type {"
   3330     "  name: \"Foo\""
   3331     "  field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
   3332     "  field { name: \"bar\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
   3333     "}",
   3334 
   3335     "foo.proto: Foo.bar: NUMBER: Field number 1 has already been used in "
   3336       "\"Foo\" by field \"foo\".\n");
   3337 }
   3338 
   3339 TEST_F(ValidationErrorTest, BadMessageSetExtensionType) {
   3340   BuildFileWithErrors(
   3341     "name: \"foo.proto\" "
   3342     "message_type {"
   3343     "  name: \"MessageSet\""
   3344     "  options { message_set_wire_format: true }"
   3345     "  extension_range { start: 4 end: 5 }"
   3346     "}"
   3347     "message_type {"
   3348     "  name: \"Foo\""
   3349     "  extension { name:\"foo\" number:4 label:LABEL_OPTIONAL type:TYPE_INT32"
   3350     "              extendee: \"MessageSet\" }"
   3351     "}",
   3352 
   3353     "foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional "
   3354       "messages.\n");
   3355 }
   3356 
   3357 TEST_F(ValidationErrorTest, BadMessageSetExtensionLabel) {
   3358   BuildFileWithErrors(
   3359     "name: \"foo.proto\" "
   3360     "message_type {"
   3361     "  name: \"MessageSet\""
   3362     "  options { message_set_wire_format: true }"
   3363     "  extension_range { start: 4 end: 5 }"
   3364     "}"
   3365     "message_type {"
   3366     "  name: \"Foo\""
   3367     "  extension { name:\"foo\" number:4 label:LABEL_REPEATED type:TYPE_MESSAGE"
   3368     "              type_name: \"Foo\" extendee: \"MessageSet\" }"
   3369     "}",
   3370 
   3371     "foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional "
   3372       "messages.\n");
   3373 }
   3374 
   3375 TEST_F(ValidationErrorTest, FieldInMessageSet) {
   3376   BuildFileWithErrors(
   3377     "name: \"foo.proto\" "
   3378     "message_type {"
   3379     "  name: \"Foo\""
   3380     "  options { message_set_wire_format: true }"
   3381     "  field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
   3382     "}",
   3383 
   3384     "foo.proto: Foo.foo: NAME: MessageSets cannot have fields, only "
   3385       "extensions.\n");
   3386 }
   3387 
   3388 TEST_F(ValidationErrorTest, NegativeExtensionRangeNumber) {
   3389   BuildFileWithErrors(
   3390     "name: \"foo.proto\" "
   3391     "message_type {"
   3392     "  name: \"Foo\""
   3393     "  extension_range { start: -10 end: -1 }"
   3394     "}",
   3395 
   3396     "foo.proto: Foo: NUMBER: Extension numbers must be positive integers.\n");
   3397 }
   3398 
   3399 TEST_F(ValidationErrorTest, HugeExtensionRangeNumber) {
   3400   BuildFileWithErrors(
   3401     "name: \"foo.proto\" "
   3402     "message_type {"
   3403     "  name: \"Foo\""
   3404     "  extension_range { start: 1 end: 0x70000000 }"
   3405     "}",
   3406 
   3407     "foo.proto: Foo: NUMBER: Extension numbers cannot be greater than "
   3408       "536870911.\n");
   3409 }
   3410 
   3411 TEST_F(ValidationErrorTest, ExtensionRangeEndBeforeStart) {
   3412   BuildFileWithErrors(
   3413     "name: \"foo.proto\" "
   3414     "message_type {"
   3415     "  name: \"Foo\""
   3416     "  extension_range { start: 10 end: 10 }"
   3417     "  extension_range { start: 10 end: 5 }"
   3418     "}",
   3419 
   3420     "foo.proto: Foo: NUMBER: Extension range end number must be greater than "
   3421       "start number.\n"
   3422     "foo.proto: Foo: NUMBER: Extension range end number must be greater than "
   3423       "start number.\n");
   3424 }
   3425 
   3426 TEST_F(ValidationErrorTest, EmptyEnum) {
   3427   BuildFileWithErrors(
   3428     "name: \"foo.proto\" "
   3429     "enum_type { name: \"Foo\" }"
   3430     // Also use the empty enum in a message to make sure there are no crashes
   3431     // during validation (possible if the code attempts to derive a default
   3432     // value for the field).
   3433     "message_type {"
   3434     "  name: \"Bar\""
   3435     "  field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type_name:\"Foo\" }"
   3436     "  field { name: \"bar\" number: 2 label:LABEL_OPTIONAL type_name:\"Foo\" "
   3437     "          default_value: \"NO_SUCH_VALUE\" }"
   3438     "}",
   3439 
   3440     "foo.proto: Foo: NAME: Enums must contain at least one value.\n"
   3441     "foo.proto: Bar.bar: DEFAULT_VALUE: Enum type \"Foo\" has no value named "
   3442       "\"NO_SUCH_VALUE\".\n");
   3443 }
   3444 
   3445 TEST_F(ValidationErrorTest, UndefinedExtendee) {
   3446   BuildFileWithErrors(
   3447     "name: \"foo.proto\" "
   3448     "message_type {"
   3449     "  name: \"Foo\""
   3450     "  extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
   3451     "              extendee: \"Bar\" }"
   3452     "}",
   3453 
   3454     "foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not defined.\n");
   3455 }
   3456 
   3457 TEST_F(ValidationErrorTest, NonMessageExtendee) {
   3458   BuildFileWithErrors(
   3459     "name: \"foo.proto\" "
   3460     "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } }"
   3461     "message_type {"
   3462     "  name: \"Foo\""
   3463     "  extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
   3464     "              extendee: \"Bar\" }"
   3465     "}",
   3466 
   3467     "foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not a message type.\n");
   3468 }
   3469 
   3470 TEST_F(ValidationErrorTest, NotAnExtensionNumber) {
   3471   BuildFileWithErrors(
   3472     "name: \"foo.proto\" "
   3473     "message_type {"
   3474     "  name: \"Bar\""
   3475     "}"
   3476     "message_type {"
   3477     "  name: \"Foo\""
   3478     "  extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
   3479     "              extendee: \"Bar\" }"
   3480     "}",
   3481 
   3482     "foo.proto: Foo.foo: NUMBER: \"Bar\" does not declare 1 as an extension "
   3483       "number.\n");
   3484 }
   3485 
   3486 TEST_F(ValidationErrorTest, RequiredExtension) {
   3487   BuildFileWithErrors(
   3488     "name: \"foo.proto\" "
   3489     "message_type {"
   3490     "  name: \"Bar\""
   3491     "  extension_range { start: 1000 end: 10000 }"
   3492     "}"
   3493     "message_type {"
   3494     "  name: \"Foo\""
   3495     "  extension {"
   3496     "    name:\"foo\""
   3497     "    number:1000"
   3498     "    label:LABEL_REQUIRED"
   3499     "    type:TYPE_INT32"
   3500     "    extendee: \"Bar\""
   3501     "  }"
   3502     "}",
   3503 
   3504     "foo.proto: Foo.foo: TYPE: Message extensions cannot have required "
   3505     "fields.\n");
   3506 }
   3507 
   3508 TEST_F(ValidationErrorTest, UndefinedFieldType) {
   3509   BuildFileWithErrors(
   3510     "name: \"foo.proto\" "
   3511     "message_type {"
   3512     "  name: \"Foo\""
   3513     "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
   3514     "}",
   3515 
   3516     "foo.proto: Foo.foo: TYPE: \"Bar\" is not defined.\n");
   3517 }
   3518 
   3519 TEST_F(ValidationErrorTest, UndefinedFieldTypeWithDefault) {
   3520   // See b/12533582. Previously this failed because the default value was not
   3521   // accepted by the parser, which assumed an enum type, leading to an unclear
   3522   // error message. We want this input to yield a validation error instead,
   3523   // since the unknown type is the primary problem.
   3524   BuildFileWithErrors(
   3525     "name: \"foo.proto\" "
   3526     "message_type {"
   3527     "  name: \"Foo\""
   3528     "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"int\" "
   3529     "          default_value:\"1\" }"
   3530     "}",
   3531 
   3532     "foo.proto: Foo.foo: TYPE: \"int\" is not defined.\n");
   3533 }
   3534 
   3535 TEST_F(ValidationErrorTest, UndefinedNestedFieldType) {
   3536   BuildFileWithErrors(
   3537     "name: \"foo.proto\" "
   3538     "message_type {"
   3539     "  name: \"Foo\""
   3540     "  nested_type { name:\"Baz\" }"
   3541     "  field { name:\"foo\" number:1"
   3542     "          label:LABEL_OPTIONAL"
   3543     "          type_name:\"Foo.Baz.Bar\" }"
   3544     "}",
   3545 
   3546     "foo.proto: Foo.foo: TYPE: \"Foo.Baz.Bar\" is not defined.\n");
   3547 }
   3548 
   3549 TEST_F(ValidationErrorTest, FieldTypeDefinedInUndeclaredDependency) {
   3550   BuildFile(
   3551     "name: \"bar.proto\" "
   3552     "message_type { name: \"Bar\" } ");
   3553 
   3554   BuildFileWithErrors(
   3555     "name: \"foo.proto\" "
   3556     "message_type {"
   3557     "  name: \"Foo\""
   3558     "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
   3559     "}",
   3560     "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", "
   3561       "which is not imported by \"foo.proto\".  To use it here, please add the "
   3562       "necessary import.\n");
   3563 }
   3564 
   3565 TEST_F(ValidationErrorTest, FieldTypeDefinedInIndirectDependency) {
   3566   // Test for hidden dependencies.
   3567   //
   3568   // // bar.proto
   3569   // message Bar{}
   3570   //
   3571   // // forward.proto
   3572   // import "bar.proto"
   3573   //
   3574   // // foo.proto
   3575   // import "forward.proto"
   3576   // message Foo {
   3577   //   optional Bar foo = 1;  // Error, needs to import bar.proto explicitly.
   3578   // }
   3579   //
   3580   BuildFile(
   3581     "name: \"bar.proto\" "
   3582     "message_type { name: \"Bar\" }");
   3583 
   3584   BuildFile(
   3585     "name: \"forward.proto\""
   3586     "dependency: \"bar.proto\"");
   3587 
   3588   BuildFileWithErrors(
   3589     "name: \"foo.proto\" "
   3590     "dependency: \"forward.proto\" "
   3591     "message_type {"
   3592     "  name: \"Foo\""
   3593     "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
   3594     "}",
   3595     "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", "
   3596       "which is not imported by \"foo.proto\".  To use it here, please add the "
   3597       "necessary import.\n");
   3598 }
   3599 
   3600 TEST_F(ValidationErrorTest, FieldTypeDefinedInPublicDependency) {
   3601   // Test for public dependencies.
   3602   //
   3603   // // bar.proto
   3604   // message Bar{}
   3605   //
   3606   // // forward.proto
   3607   // import public "bar.proto"
   3608   //
   3609   // // foo.proto
   3610   // import "forward.proto"
   3611   // message Foo {
   3612   //   optional Bar foo = 1;  // Correct. "bar.proto" is public imported into
   3613   //                          // forward.proto, so when "foo.proto" imports
   3614   //                          // "forward.proto", it imports "bar.proto" too.
   3615   // }
   3616   //
   3617   BuildFile(
   3618     "name: \"bar.proto\" "
   3619     "message_type { name: \"Bar\" }");
   3620 
   3621   BuildFile(
   3622     "name: \"forward.proto\""
   3623     "dependency: \"bar.proto\" "
   3624     "public_dependency: 0");
   3625 
   3626   BuildFile(
   3627     "name: \"foo.proto\" "
   3628     "dependency: \"forward.proto\" "
   3629     "message_type {"
   3630     "  name: \"Foo\""
   3631     "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
   3632     "}");
   3633 }
   3634 
   3635 TEST_F(ValidationErrorTest, FieldTypeDefinedInTransitivePublicDependency) {
   3636   // Test for public dependencies.
   3637   //
   3638   // // bar.proto
   3639   // message Bar{}
   3640   //
   3641   // // forward.proto
   3642   // import public "bar.proto"
   3643   //
   3644   // // forward2.proto
   3645   // import public "forward.proto"
   3646   //
   3647   // // foo.proto
   3648   // import "forward2.proto"
   3649   // message Foo {
   3650   //   optional Bar foo = 1;  // Correct, public imports are transitive.
   3651   // }
   3652   //
   3653   BuildFile(
   3654     "name: \"bar.proto\" "
   3655     "message_type { name: \"Bar\" }");
   3656 
   3657   BuildFile(
   3658     "name: \"forward.proto\""
   3659     "dependency: \"bar.proto\" "
   3660     "public_dependency: 0");
   3661 
   3662   BuildFile(
   3663     "name: \"forward2.proto\""
   3664     "dependency: \"forward.proto\" "
   3665     "public_dependency: 0");
   3666 
   3667   BuildFile(
   3668     "name: \"foo.proto\" "
   3669     "dependency: \"forward2.proto\" "
   3670     "message_type {"
   3671     "  name: \"Foo\""
   3672     "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
   3673     "}");
   3674 }
   3675 
   3676 TEST_F(ValidationErrorTest,
   3677        FieldTypeDefinedInPrivateDependencyOfPublicDependency) {
   3678   // Test for public dependencies.
   3679   //
   3680   // // bar.proto
   3681   // message Bar{}
   3682   //
   3683   // // forward.proto
   3684   // import "bar.proto"
   3685   //
   3686   // // forward2.proto
   3687   // import public "forward.proto"
   3688   //
   3689   // // foo.proto
   3690   // import "forward2.proto"
   3691   // message Foo {
   3692   //   optional Bar foo = 1;  // Error, the "bar.proto" is not public imported
   3693   //                          // into "forward.proto", so will not be imported
   3694   //                          // into either "forward2.proto" or "foo.proto".
   3695   // }
   3696   //
   3697   BuildFile(
   3698     "name: \"bar.proto\" "
   3699     "message_type { name: \"Bar\" }");
   3700 
   3701   BuildFile(
   3702     "name: \"forward.proto\""
   3703     "dependency: \"bar.proto\"");
   3704 
   3705   BuildFile(
   3706     "name: \"forward2.proto\""
   3707     "dependency: \"forward.proto\" "
   3708     "public_dependency: 0");
   3709 
   3710   BuildFileWithErrors(
   3711     "name: \"foo.proto\" "
   3712     "dependency: \"forward2.proto\" "
   3713     "message_type {"
   3714     "  name: \"Foo\""
   3715     "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
   3716     "}",
   3717     "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", "
   3718       "which is not imported by \"foo.proto\".  To use it here, please add the "
   3719       "necessary import.\n");
   3720 }
   3721 
   3722 
   3723 TEST_F(ValidationErrorTest, SearchMostLocalFirst) {
   3724   // The following should produce an error that Bar.Baz is resolved but
   3725   // not defined:
   3726   //   message Bar { message Baz {} }
   3727   //   message Foo {
   3728   //     message Bar {
   3729   //       // Placing "message Baz{}" here, or removing Foo.Bar altogether,
   3730   //       // would fix the error.
   3731   //     }
   3732   //     optional Bar.Baz baz = 1;
   3733   //   }
   3734   // An one point the lookup code incorrectly did not produce an error in this
   3735   // case, because when looking for Bar.Baz, it would try "Foo.Bar.Baz" first,
   3736   // fail, and ten try "Bar.Baz" and succeed, even though "Bar" should actually
   3737   // refer to the inner Bar, not the outer one.
   3738   BuildFileWithErrors(
   3739     "name: \"foo.proto\" "
   3740     "message_type {"
   3741     "  name: \"Bar\""
   3742     "  nested_type { name: \"Baz\" }"
   3743     "}"
   3744     "message_type {"
   3745     "  name: \"Foo\""
   3746     "  nested_type { name: \"Bar\" }"
   3747     "  field { name:\"baz\" number:1 label:LABEL_OPTIONAL"
   3748     "          type_name:\"Bar.Baz\" }"
   3749     "}",
   3750 
   3751     "foo.proto: Foo.baz: TYPE: \"Bar.Baz\" is resolved to \"Foo.Bar.Baz\","
   3752     " which is not defined. The innermost scope is searched first in name "
   3753     "resolution. Consider using a leading '.'(i.e., \".Bar.Baz\") to start "
   3754     "from the outermost scope.\n");
   3755 }
   3756 
   3757 TEST_F(ValidationErrorTest, SearchMostLocalFirst2) {
   3758   // This test would find the most local "Bar" first, and does, but
   3759   // proceeds to find the outer one because the inner one's not an
   3760   // aggregate.
   3761   BuildFile(
   3762     "name: \"foo.proto\" "
   3763     "message_type {"
   3764     "  name: \"Bar\""
   3765     "  nested_type { name: \"Baz\" }"
   3766     "}"
   3767     "message_type {"
   3768     "  name: \"Foo\""
   3769     "  field { name: \"Bar\" number:1 type:TYPE_BYTES } "
   3770     "  field { name:\"baz\" number:2 label:LABEL_OPTIONAL"
   3771     "          type_name:\"Bar.Baz\" }"
   3772     "}");
   3773 }
   3774 
   3775 TEST_F(ValidationErrorTest, PackageOriginallyDeclaredInTransitiveDependent) {
   3776   // Imagine we have the following:
   3777   //
   3778   // foo.proto:
   3779   //   package foo.bar;
   3780   // bar.proto:
   3781   //   package foo.bar;
   3782   //   import "foo.proto";
   3783   //   message Bar {}
   3784   // baz.proto:
   3785   //   package foo;
   3786   //   import "bar.proto"
   3787   //   message Baz { optional bar.Bar qux = 1; }
   3788   //
   3789   // When validating baz.proto, we will look up "bar.Bar".  As part of this
   3790   // lookup, we first lookup "bar" then try to find "Bar" within it.  "bar"
   3791   // should resolve to "foo.bar".  Note, though, that "foo.bar" was originally
   3792   // defined in foo.proto, which is not a direct dependency of baz.proto.  The
   3793   // implementation of FindSymbol() normally only returns symbols in direct
   3794   // dependencies, not indirect ones.  This test insures that this does not
   3795   // prevent it from finding "foo.bar".
   3796 
   3797   BuildFile(
   3798     "name: \"foo.proto\" "
   3799     "package: \"foo.bar\" ");
   3800   BuildFile(
   3801     "name: \"bar.proto\" "
   3802     "package: \"foo.bar\" "
   3803     "dependency: \"foo.proto\" "
   3804     "message_type { name: \"Bar\" }");
   3805   BuildFile(
   3806     "name: \"baz.proto\" "
   3807     "package: \"foo\" "
   3808     "dependency: \"bar.proto\" "
   3809     "message_type { "
   3810     "  name: \"Baz\" "
   3811     "  field { name:\"qux\" number:1 label:LABEL_OPTIONAL "
   3812     "          type_name:\"bar.Bar\" }"
   3813     "}");
   3814 }
   3815 
   3816 TEST_F(ValidationErrorTest, FieldTypeNotAType) {
   3817   BuildFileWithErrors(
   3818     "name: \"foo.proto\" "
   3819     "message_type {"
   3820     "  name: \"Foo\""
   3821     "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL "
   3822     "          type_name:\".Foo.bar\" }"
   3823     "  field { name:\"bar\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
   3824     "}",
   3825 
   3826     "foo.proto: Foo.foo: TYPE: \".Foo.bar\" is not a type.\n");
   3827 }
   3828 
   3829 TEST_F(ValidationErrorTest, RelativeFieldTypeNotAType) {
   3830   BuildFileWithErrors(
   3831     "name: \"foo.proto\" "
   3832     "message_type {"
   3833     "  nested_type {"
   3834     "    name: \"Bar\""
   3835     "    field { name:\"Baz\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
   3836     "  }"
   3837     "  name: \"Foo\""
   3838     "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL "
   3839     "          type_name:\"Bar.Baz\" }"
   3840     "}",
   3841     "foo.proto: Foo.foo: TYPE: \"Bar.Baz\" is not a type.\n");
   3842 }
   3843 
   3844 TEST_F(ValidationErrorTest, FieldTypeMayBeItsName) {
   3845   BuildFile(
   3846     "name: \"foo.proto\" "
   3847     "message_type {"
   3848     "  name: \"Bar\""
   3849     "}"
   3850     "message_type {"
   3851     "  name: \"Foo\""
   3852     "  field { name:\"Bar\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
   3853     "}");
   3854 }
   3855 
   3856 TEST_F(ValidationErrorTest, EnumFieldTypeIsMessage) {
   3857   BuildFileWithErrors(
   3858     "name: \"foo.proto\" "
   3859     "message_type { name: \"Bar\" } "
   3860     "message_type {"
   3861     "  name: \"Foo\""
   3862     "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_ENUM"
   3863     "          type_name:\"Bar\" }"
   3864     "}",
   3865 
   3866     "foo.proto: Foo.foo: TYPE: \"Bar\" is not an enum type.\n");
   3867 }
   3868 
   3869 TEST_F(ValidationErrorTest, MessageFieldTypeIsEnum) {
   3870   BuildFileWithErrors(
   3871     "name: \"foo.proto\" "
   3872     "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
   3873     "message_type {"
   3874     "  name: \"Foo\""
   3875     "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE"
   3876     "          type_name:\"Bar\" }"
   3877     "}",
   3878 
   3879     "foo.proto: Foo.foo: TYPE: \"Bar\" is not a message type.\n");
   3880 }
   3881 
   3882 TEST_F(ValidationErrorTest, BadEnumDefaultValue) {
   3883   BuildFileWithErrors(
   3884     "name: \"foo.proto\" "
   3885     "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
   3886     "message_type {"
   3887     "  name: \"Foo\""
   3888     "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\""
   3889     "          default_value:\"NO_SUCH_VALUE\" }"
   3890     "}",
   3891 
   3892     "foo.proto: Foo.foo: DEFAULT_VALUE: Enum type \"Bar\" has no value named "
   3893       "\"NO_SUCH_VALUE\".\n");
   3894 }
   3895 
   3896 TEST_F(ValidationErrorTest, EnumDefaultValueIsInteger) {
   3897   BuildFileWithErrors(
   3898     "name: \"foo.proto\" "
   3899     "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
   3900     "message_type {"
   3901     "  name: \"Foo\""
   3902     "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\""
   3903     "          default_value:\"0\" }"
   3904     "}",
   3905 
   3906     "foo.proto: Foo.foo: DEFAULT_VALUE: Default value for an enum field must "
   3907     "be an identifier.\n");
   3908 }
   3909 
   3910 TEST_F(ValidationErrorTest, PrimitiveWithTypeName) {
   3911   BuildFileWithErrors(
   3912     "name: \"foo.proto\" "
   3913     "message_type {"
   3914     "  name: \"Foo\""
   3915     "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
   3916     "          type_name:\"Foo\" }"
   3917     "}",
   3918 
   3919     "foo.proto: Foo.foo: TYPE: Field with primitive type has type_name.\n");
   3920 }
   3921 
   3922 TEST_F(ValidationErrorTest, NonPrimitiveWithoutTypeName) {
   3923   BuildFileWithErrors(
   3924     "name: \"foo.proto\" "
   3925     "message_type {"
   3926     "  name: \"Foo\""
   3927     "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE }"
   3928     "}",
   3929 
   3930     "foo.proto: Foo.foo: TYPE: Field with message or enum type missing "
   3931       "type_name.\n");
   3932 }
   3933 
   3934 TEST_F(ValidationErrorTest, OneofWithNoFields) {
   3935   BuildFileWithErrors(
   3936     "name: \"foo.proto\" "
   3937     "message_type {"
   3938     "  name: \"Foo\""
   3939     "  oneof_decl { name:\"bar\" }"
   3940     "}",
   3941 
   3942     "foo.proto: Foo.bar: NAME: Oneof must have at least one field.\n");
   3943 }
   3944 
   3945 TEST_F(ValidationErrorTest, OneofLabelMismatch) {
   3946   BuildFileWithErrors(
   3947     "name: \"foo.proto\" "
   3948     "message_type {"
   3949     "  name: \"Foo\""
   3950     "  field { name:\"foo\" number:1 label:LABEL_REPEATED type:TYPE_INT32 "
   3951     "          oneof_index:0 }"
   3952     "  oneof_decl { name:\"bar\" }"
   3953     "}",
   3954 
   3955     "foo.proto: Foo.foo: NAME: Fields of oneofs must themselves have label "
   3956       "LABEL_OPTIONAL.\n");
   3957 }
   3958 
   3959 TEST_F(ValidationErrorTest, InputTypeNotDefined) {
   3960   BuildFileWithErrors(
   3961     "name: \"foo.proto\" "
   3962     "message_type { name: \"Foo\" } "
   3963     "service {"
   3964     "  name: \"TestService\""
   3965     "  method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }"
   3966     "}",
   3967 
   3968     "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not defined.\n"
   3969     );
   3970 }
   3971 
   3972 TEST_F(ValidationErrorTest, InputTypeNotAMessage) {
   3973   BuildFileWithErrors(
   3974     "name: \"foo.proto\" "
   3975     "message_type { name: \"Foo\" } "
   3976     "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
   3977     "service {"
   3978     "  name: \"TestService\""
   3979     "  method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }"
   3980     "}",
   3981 
   3982     "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not a message type.\n"
   3983     );
   3984 }
   3985 
   3986 TEST_F(ValidationErrorTest, OutputTypeNotDefined) {
   3987   BuildFileWithErrors(
   3988     "name: \"foo.proto\" "
   3989     "message_type { name: \"Foo\" } "
   3990     "service {"
   3991     "  name: \"TestService\""
   3992     "  method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }"
   3993     "}",
   3994 
   3995     "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not defined.\n"
   3996     );
   3997 }
   3998 
   3999 TEST_F(ValidationErrorTest, OutputTypeNotAMessage) {
   4000   BuildFileWithErrors(
   4001     "name: \"foo.proto\" "
   4002     "message_type { name: \"Foo\" } "
   4003     "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
   4004     "service {"
   4005     "  name: \"TestService\""
   4006     "  method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }"
   4007     "}",
   4008 
   4009     "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not a message type.\n"
   4010     );
   4011 }
   4012 
   4013 
   4014 TEST_F(ValidationErrorTest, IllegalPackedField) {
   4015   BuildFileWithErrors(
   4016     "name: \"foo.proto\" "
   4017     "message_type {\n"
   4018     "  name: \"Foo\""
   4019     "  field { name:\"packed_string\" number:1 label:LABEL_REPEATED "
   4020     "          type:TYPE_STRING "
   4021     "          options { uninterpreted_option {"
   4022     "            name { name_part: \"packed\" is_extension: false }"
   4023     "            identifier_value: \"true\" }}}\n"
   4024     "  field { name:\"packed_message\" number:3 label:LABEL_REPEATED "
   4025     "          type_name: \"Foo\""
   4026     "          options { uninterpreted_option {"
   4027     "            name { name_part: \"packed\" is_extension: false }"
   4028     "            identifier_value: \"true\" }}}\n"
   4029     "  field { name:\"optional_int32\" number: 4 label: LABEL_OPTIONAL "
   4030     "          type:TYPE_INT32 "
   4031     "          options { uninterpreted_option {"
   4032     "            name { name_part: \"packed\" is_extension: false }"
   4033     "            identifier_value: \"true\" }}}\n"
   4034     "}",
   4035 
   4036     "foo.proto: Foo.packed_string: TYPE: [packed = true] can only be "
   4037         "specified for repeated primitive fields.\n"
   4038     "foo.proto: Foo.packed_message: TYPE: [packed = true] can only be "
   4039         "specified for repeated primitive fields.\n"
   4040     "foo.proto: Foo.optional_int32: TYPE: [packed = true] can only be "
   4041         "specified for repeated primitive fields.\n"
   4042         );
   4043 }
   4044 
   4045 TEST_F(ValidationErrorTest, OptionWrongType) {
   4046   BuildFileWithErrors(
   4047     "name: \"foo.proto\" "
   4048     "message_type { "
   4049     "  name: \"TestMessage\" "
   4050     "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING "
   4051     "          options { uninterpreted_option { name { name_part: \"ctype\" "
   4052     "                                                  is_extension: false }"
   4053     "                                           positive_int_value: 1 }"
   4054     "          }"
   4055     "  }"
   4056     "}\n",
   4057 
   4058     "foo.proto: TestMessage.foo: OPTION_VALUE: Value must be identifier for "
   4059     "enum-valued option \"google.protobuf.FieldOptions.ctype\".\n");
   4060 }
   4061 
   4062 TEST_F(ValidationErrorTest, OptionExtendsAtomicType) {
   4063   BuildFileWithErrors(
   4064     "name: \"foo.proto\" "
   4065     "message_type { "
   4066     "  name: \"TestMessage\" "
   4067     "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING "
   4068     "          options { uninterpreted_option { name { name_part: \"ctype\" "
   4069     "                                                  is_extension: false }"
   4070     "                                           name { name_part: \"foo\" "
   4071     "                                                  is_extension: true }"
   4072     "                                           positive_int_value: 1 }"
   4073     "          }"
   4074     "  }"
   4075     "}\n",
   4076 
   4077     "foo.proto: TestMessage.foo: OPTION_NAME: Option \"ctype\" is an "
   4078     "atomic type, not a message.\n");
   4079 }
   4080 
   4081 TEST_F(ValidationErrorTest, DupOption) {
   4082   BuildFileWithErrors(
   4083     "name: \"foo.proto\" "
   4084     "message_type { "
   4085     "  name: \"TestMessage\" "
   4086     "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_UINT32 "
   4087     "          options { uninterpreted_option { name { name_part: \"ctype\" "
   4088     "                                                  is_extension: false }"
   4089     "                                           identifier_value: \"CORD\" }"
   4090     "                    uninterpreted_option { name { name_part: \"ctype\" "
   4091     "                                                  is_extension: false }"
   4092     "                                           identifier_value: \"CORD\" }"
   4093     "          }"
   4094     "  }"
   4095     "}\n",
   4096 
   4097     "foo.proto: TestMessage.foo: OPTION_NAME: Option \"ctype\" was "
   4098     "already set.\n");
   4099 }
   4100 
   4101 TEST_F(ValidationErrorTest, InvalidOptionName) {
   4102   BuildFileWithErrors(
   4103     "name: \"foo.proto\" "
   4104     "message_type { "
   4105     "  name: \"TestMessage\" "
   4106     "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_BOOL "
   4107     "          options { uninterpreted_option { "
   4108     "                      name { name_part: \"uninterpreted_option\" "
   4109     "                             is_extension: false }"
   4110     "                      positive_int_value: 1 "
   4111     "                    }"
   4112     "          }"
   4113     "  }"
   4114     "}\n",
   4115 
   4116     "foo.proto: TestMessage.foo: OPTION_NAME: Option must not use "
   4117     "reserved name \"uninterpreted_option\".\n");
   4118 }
   4119 
   4120 TEST_F(ValidationErrorTest, RepeatedMessageOption) {
   4121   BuildDescriptorMessagesInTestPool();
   4122 
   4123   BuildFileWithErrors(
   4124     "name: \"foo.proto\" "
   4125     "dependency: \"google/protobuf/descriptor.proto\" "
   4126     "message_type: { name: \"Bar\" field: { "
   4127     "  name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 } "
   4128     "} "
   4129     "extension { name: \"bar\" number: 7672757 label: LABEL_REPEATED "
   4130     "            type: TYPE_MESSAGE type_name: \"Bar\" "
   4131     "            extendee: \"google.protobuf.FileOptions\" }"
   4132     "options { uninterpreted_option { name { name_part: \"bar\" "
   4133     "                                        is_extension: true } "
   4134     "                                 name { name_part: \"foo\" "
   4135     "                                        is_extension: false } "
   4136     "                                 positive_int_value: 1 } }",
   4137 
   4138     "foo.proto: foo.proto: OPTION_NAME: Option field \"(bar)\" is a "
   4139     "repeated message. Repeated message options must be initialized "
   4140     "using an aggregate value.\n");
   4141 }
   4142 
   4143 TEST_F(ValidationErrorTest, ResolveUndefinedOption) {
   4144   // The following should produce an eror that baz.bar is resolved but not
   4145   // defined.
   4146   // foo.proto:
   4147   //   package baz
   4148   //   import google/protobuf/descriptor.proto
   4149   //   message Bar { optional int32 foo = 1; }
   4150   //   extend FileOptions { optional Bar bar = 7672757; }
   4151   //
   4152   // qux.proto:
   4153   //   package qux.baz
   4154   //   option (baz.bar).foo = 1;
   4155   //
   4156   // Although "baz.bar" is already defined, the lookup code will try
   4157   // "qux.baz.bar", since it's the match from the innermost scope, which will
   4158   // cause a symbol not defined error.
   4159   BuildDescriptorMessagesInTestPool();
   4160 
   4161   BuildFile(
   4162     "name: \"foo.proto\" "
   4163     "package: \"baz\" "
   4164     "dependency: \"google/protobuf/descriptor.proto\" "
   4165     "message_type: { name: \"Bar\" field: { "
   4166     "  name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 } "
   4167     "} "
   4168     "extension { name: \"bar\" number: 7672757 label: LABEL_OPTIONAL "
   4169     "            type: TYPE_MESSAGE type_name: \"Bar\" "
   4170     "            extendee: \"google.protobuf.FileOptions\" }");
   4171 
   4172   BuildFileWithErrors(
   4173     "name: \"qux.proto\" "
   4174     "package: \"qux.baz\" "
   4175     "options { uninterpreted_option { name { name_part: \"baz.bar\" "
   4176     "                                        is_extension: true } "
   4177     "                                 name { name_part: \"foo\" "
   4178     "                                        is_extension: false } "
   4179     "                                 positive_int_value: 1 } }",
   4180 
   4181     "qux.proto: qux.proto: OPTION_NAME: Option \"(baz.bar)\" is resolved to "
   4182     "\"(qux.baz.bar)\","
   4183     " which is not defined. The innermost scope is searched first in name "
   4184     "resolution. Consider using a leading '.'(i.e., \"(.baz.bar)\") to start "
   4185     "from the outermost scope.\n");
   4186 }
   4187 
   4188 TEST_F(ValidationErrorTest, UnknownOption) {
   4189   BuildFileWithErrors(
   4190     "name: \"qux.proto\" "
   4191     "package: \"qux.baz\" "
   4192     "options { uninterpreted_option { name { name_part: \"baaz.bar\" "
   4193     "                                        is_extension: true } "
   4194     "                                 name { name_part: \"foo\" "
   4195     "                                        is_extension: false } "
   4196     "                                 positive_int_value: 1 } }",
   4197 
   4198     "qux.proto: qux.proto: OPTION_NAME: Option \"(baaz.bar)\" unknown.\n");
   4199 }
   4200 
   4201 TEST_F(ValidationErrorTest, CustomOptionConflictingFieldNumber) {
   4202   BuildDescriptorMessagesInTestPool();
   4203 
   4204   BuildFileWithErrors(
   4205     "name: \"foo.proto\" "
   4206     "dependency: \"google/protobuf/descriptor.proto\" "
   4207     "extension { name: \"foo1\" number: 7672757 label: LABEL_OPTIONAL "
   4208     "            type: TYPE_INT32 extendee: \"google.protobuf.FieldOptions\" }"
   4209     "extension { name: \"foo2\" number: 7672757 label: LABEL_OPTIONAL "
   4210     "            type: TYPE_INT32 extendee: \"google.protobuf.FieldOptions\" }",
   4211 
   4212     "foo.proto: foo2: NUMBER: Extension number 7672757 has already been used "
   4213     "in \"google.protobuf.FieldOptions\" by extension \"foo1\".\n");
   4214 }
   4215 
   4216 TEST_F(ValidationErrorTest, Int32OptionValueOutOfPositiveRange) {
   4217   BuildDescriptorMessagesInTestPool();
   4218 
   4219   BuildFileWithErrors(
   4220     "name: \"foo.proto\" "
   4221     "dependency: \"google/protobuf/descriptor.proto\" "
   4222     "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
   4223     "            type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
   4224     "options { uninterpreted_option { name { name_part: \"foo\" "
   4225     "                                        is_extension: true } "
   4226     "                                 positive_int_value: 0x80000000 } "
   4227     "}",
   4228 
   4229     "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
   4230     "for int32 option \"foo\".\n");
   4231 }
   4232 
   4233 TEST_F(ValidationErrorTest, Int32OptionValueOutOfNegativeRange) {
   4234   BuildDescriptorMessagesInTestPool();
   4235 
   4236   BuildFileWithErrors(
   4237     "name: \"foo.proto\" "
   4238     "dependency: \"google/protobuf/descriptor.proto\" "
   4239     "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
   4240     "            type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
   4241     "options { uninterpreted_option { name { name_part: \"foo\" "
   4242     "                                        is_extension: true } "
   4243     "                                 negative_int_value: -0x80000001 } "
   4244     "}",
   4245 
   4246     "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
   4247     "for int32 option \"foo\".\n");
   4248 }
   4249 
   4250 TEST_F(ValidationErrorTest, Int32OptionValueIsNotPositiveInt) {
   4251   BuildDescriptorMessagesInTestPool();
   4252 
   4253   BuildFileWithErrors(
   4254     "name: \"foo.proto\" "
   4255     "dependency: \"google/protobuf/descriptor.proto\" "
   4256     "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
   4257     "            type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
   4258     "options { uninterpreted_option { name { name_part: \"foo\" "
   4259     "                                        is_extension: true } "
   4260     "                                 string_value: \"5\" } }",
   4261 
   4262     "foo.proto: foo.proto: OPTION_VALUE: Value must be integer "
   4263     "for int32 option \"foo\".\n");
   4264 }
   4265 
   4266 TEST_F(ValidationErrorTest, Int64OptionValueOutOfRange) {
   4267   BuildDescriptorMessagesInTestPool();
   4268 
   4269   BuildFileWithErrors(
   4270     "name: \"foo.proto\" "
   4271     "dependency: \"google/protobuf/descriptor.proto\" "
   4272     "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
   4273     "            type: TYPE_INT64 extendee: \"google.protobuf.FileOptions\" }"
   4274     "options { uninterpreted_option { name { name_part: \"foo\" "
   4275     "                                        is_extension: true } "
   4276     "                                 positive_int_value: 0x8000000000000000 } "
   4277     "}",
   4278 
   4279     "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
   4280     "for int64 option \"foo\".\n");
   4281 }
   4282 
   4283 TEST_F(ValidationErrorTest, Int64OptionValueIsNotPositiveInt) {
   4284   BuildDescriptorMessagesInTestPool();
   4285 
   4286   BuildFileWithErrors(
   4287     "name: \"foo.proto\" "
   4288     "dependency: \"google/protobuf/descriptor.proto\" "
   4289     "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
   4290     "            type: TYPE_INT64 extendee: \"google.protobuf.FileOptions\" }"
   4291     "options { uninterpreted_option { name { name_part: \"foo\" "
   4292     "                                        is_extension: true } "
   4293     "                                 identifier_value: \"5\" } }",
   4294 
   4295     "foo.proto: foo.proto: OPTION_VALUE: Value must be integer "
   4296     "for int64 option \"foo\".\n");
   4297 }
   4298 
   4299 TEST_F(ValidationErrorTest, UInt32OptionValueOutOfRange) {
   4300   BuildDescriptorMessagesInTestPool();
   4301 
   4302   BuildFileWithErrors(
   4303     "name: \"foo.proto\" "
   4304     "dependency: \"google/protobuf/descriptor.proto\" "
   4305     "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
   4306     "            type: TYPE_UINT32 extendee: \"google.protobuf.FileOptions\" }"
   4307     "options { uninterpreted_option { name { name_part: \"foo\" "
   4308     "                                        is_extension: true } "
   4309     "                                 positive_int_value: 0x100000000 } }",
   4310 
   4311     "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
   4312     "for uint32 option \"foo\".\n");
   4313 }
   4314 
   4315 TEST_F(ValidationErrorTest, UInt32OptionValueIsNotPositiveInt) {
   4316   BuildDescriptorMessagesInTestPool();
   4317 
   4318   BuildFileWithErrors(
   4319     "name: \"foo.proto\" "
   4320     "dependency: \"google/protobuf/descriptor.proto\" "
   4321     "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
   4322     "            type: TYPE_UINT32 extendee: \"google.protobuf.FileOptions\" }"
   4323     "options { uninterpreted_option { name { name_part: \"foo\" "
   4324     "                                        is_extension: true } "
   4325     "                                 double_value: -5.6 } }",
   4326 
   4327     "foo.proto: foo.proto: OPTION_VALUE: Value must be non-negative integer "
   4328     "for uint32 option \"foo\".\n");
   4329 }
   4330 
   4331 TEST_F(ValidationErrorTest, UInt64OptionValueIsNotPositiveInt) {
   4332   BuildDescriptorMessagesInTestPool();
   4333 
   4334   BuildFileWithErrors(
   4335     "name: \"foo.proto\" "
   4336     "dependency: \"google/protobuf/descriptor.proto\" "
   4337     "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
   4338     "            type: TYPE_UINT64 extendee: \"google.protobuf.FileOptions\" }"
   4339     "options { uninterpreted_option { name { name_part: \"foo\" "
   4340     "                                        is_extension: true } "
   4341     "                                 negative_int_value: -5 } }",
   4342 
   4343     "foo.proto: foo.proto: OPTION_VALUE: Value must be non-negative integer "
   4344     "for uint64 option \"foo\".\n");
   4345 }
   4346 
   4347 TEST_F(ValidationErrorTest, FloatOptionValueIsNotNumber) {
   4348   BuildDescriptorMessagesInTestPool();
   4349 
   4350   BuildFileWithErrors(
   4351     "name: \"foo.proto\" "
   4352     "dependency: \"google/protobuf/descriptor.proto\" "
   4353     "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
   4354     "            type: TYPE_FLOAT extendee: \"google.protobuf.FileOptions\" }"
   4355     "options { uninterpreted_option { name { name_part: \"foo\" "
   4356     "                                        is_extension: true } "
   4357     "                                 string_value: \"bar\" } }",
   4358 
   4359     "foo.proto: foo.proto: OPTION_VALUE: Value must be number "
   4360     "for float option \"foo\".\n");
   4361 }
   4362 
   4363 TEST_F(ValidationErrorTest, DoubleOptionValueIsNotNumber) {
   4364   BuildDescriptorMessagesInTestPool();
   4365 
   4366   BuildFileWithErrors(
   4367     "name: \"foo.proto\" "
   4368     "dependency: \"google/protobuf/descriptor.proto\" "
   4369     "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
   4370     "            type: TYPE_DOUBLE extendee: \"google.protobuf.FileOptions\" }"
   4371     "options { uninterpreted_option { name { name_part: \"foo\" "
   4372     "                                        is_extension: true } "
   4373     "                                 string_value: \"bar\" } }",
   4374 
   4375     "foo.proto: foo.proto: OPTION_VALUE: Value must be number "
   4376     "for double option \"foo\".\n");
   4377 }
   4378 
   4379 TEST_F(ValidationErrorTest, BoolOptionValueIsNotTrueOrFalse) {
   4380   BuildDescriptorMessagesInTestPool();
   4381 
   4382   BuildFileWithErrors(
   4383     "name: \"foo.proto\" "
   4384     "dependency: \"google/protobuf/descriptor.proto\" "
   4385     "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
   4386     "            type: TYPE_BOOL extendee: \"google.protobuf.FileOptions\" }"
   4387     "options { uninterpreted_option { name { name_part: \"foo\" "
   4388     "                                        is_extension: true } "
   4389     "                                 identifier_value: \"bar\" } }",
   4390 
   4391     "foo.proto: foo.proto: OPTION_VALUE: Value must be \"true\" or \"false\" "
   4392     "for boolean option \"foo\".\n");
   4393 }
   4394 
   4395 TEST_F(ValidationErrorTest, EnumOptionValueIsNotIdentifier) {
   4396   BuildDescriptorMessagesInTestPool();
   4397 
   4398   BuildFileWithErrors(
   4399     "name: \"foo.proto\" "
   4400     "dependency: \"google/protobuf/descriptor.proto\" "
   4401     "enum_type { name: \"FooEnum\" value { name: \"BAR\" number: 1 } "
   4402     "                              value { name: \"BAZ\" number: 2 } }"
   4403     "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
   4404     "            type: TYPE_ENUM type_name: \"FooEnum\" "
   4405     "            extendee: \"google.protobuf.FileOptions\" }"
   4406     "options { uninterpreted_option { name { name_part: \"foo\" "
   4407     "                                        is_extension: true } "
   4408     "                                 string_value: \"QUUX\" } }",
   4409 
   4410     "foo.proto: foo.proto: OPTION_VALUE: Value must be identifier for "
   4411     "enum-valued option \"foo\".\n");
   4412 }
   4413 
   4414 TEST_F(ValidationErrorTest, EnumOptionValueIsNotEnumValueName) {
   4415   BuildDescriptorMessagesInTestPool();
   4416 
   4417   BuildFileWithErrors(
   4418     "name: \"foo.proto\" "
   4419     "dependency: \"google/protobuf/descriptor.proto\" "
   4420     "enum_type { name: \"FooEnum\" value { name: \"BAR\" number: 1 } "
   4421     "                              value { name: \"BAZ\" number: 2 } }"
   4422     "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
   4423     "            type: TYPE_ENUM type_name: \"FooEnum\" "
   4424     "            extendee: \"google.protobuf.FileOptions\" }"
   4425     "options { uninterpreted_option { name { name_part: \"foo\" "
   4426     "                                        is_extension: true } "
   4427     "                                 identifier_value: \"QUUX\" } }",
   4428 
   4429     "foo.proto: foo.proto: OPTION_VALUE: Enum type \"FooEnum\" has no value "
   4430     "named \"QUUX\" for option \"foo\".\n");
   4431 }
   4432 
   4433 TEST_F(ValidationErrorTest, EnumOptionValueIsSiblingEnumValueName) {
   4434   BuildDescriptorMessagesInTestPool();
   4435 
   4436   BuildFileWithErrors(
   4437     "name: \"foo.proto\" "
   4438     "dependency: \"google/protobuf/descriptor.proto\" "
   4439     "enum_type { name: \"FooEnum1\" value { name: \"BAR\" number: 1 } "
   4440     "                               value { name: \"BAZ\" number: 2 } }"
   4441     "enum_type { name: \"FooEnum2\" value { name: \"QUX\" number: 1 } "
   4442     "                               value { name: \"QUUX\" number: 2 } }"
   4443     "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
   4444     "            type: TYPE_ENUM type_name: \"FooEnum1\" "
   4445     "            extendee: \"google.protobuf.FileOptions\" }"
   4446     "options { uninterpreted_option { name { name_part: \"foo\" "
   4447     "                                        is_extension: true } "
   4448     "                                 identifier_value: \"QUUX\" } }",
   4449 
   4450     "foo.proto: foo.proto: OPTION_VALUE: Enum type \"FooEnum1\" has no value "
   4451     "named \"QUUX\" for option \"foo\". This appears to be a value from a "
   4452     "sibling type.\n");
   4453 }
   4454 
   4455 TEST_F(ValidationErrorTest, StringOptionValueIsNotString) {
   4456   BuildDescriptorMessagesInTestPool();
   4457 
   4458   BuildFileWithErrors(
   4459     "name: \"foo.proto\" "
   4460     "dependency: \"google/protobuf/descriptor.proto\" "
   4461     "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
   4462     "            type: TYPE_STRING extendee: \"google.protobuf.FileOptions\" }"
   4463     "options { uninterpreted_option { name { name_part: \"foo\" "
   4464     "                                        is_extension: true } "
   4465     "                                 identifier_value: \"QUUX\" } }",
   4466 
   4467     "foo.proto: foo.proto: OPTION_VALUE: Value must be quoted string for "
   4468     "string option \"foo\".\n");
   4469 }
   4470 
   4471 TEST_F(ValidationErrorTest, DuplicateExtensionFieldNumber) {
   4472   BuildDescriptorMessagesInTestPool();
   4473 
   4474   BuildFile(
   4475       "name: \"foo.proto\" "
   4476       "dependency: \"google/protobuf/descriptor.proto\" "
   4477       "extension { name: \"option1\" number: 1000 label: LABEL_OPTIONAL "
   4478       "            type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }");
   4479 
   4480   BuildFileWithWarnings(
   4481       "name: \"bar.proto\" "
   4482       "dependency: \"google/protobuf/descriptor.proto\" "
   4483       "extension { name: \"option2\" number: 1000 label: LABEL_OPTIONAL "
   4484       "            type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }",
   4485       "bar.proto: option2: NUMBER: Extension number 1000 has already been used "
   4486       "in \"google.protobuf.FileOptions\" by extension \"option1\" defined in "
   4487       "foo.proto.\n");
   4488 }
   4489 
   4490 // Helper function for tests that check for aggregate value parsing
   4491 // errors.  The "value" argument is embedded inside the
   4492 // "uninterpreted_option" portion of the result.
   4493 static string EmbedAggregateValue(const char* value) {
   4494   return strings::Substitute(
   4495       "name: \"foo.proto\" "
   4496       "dependency: \"google/protobuf/descriptor.proto\" "
   4497       "message_type { name: \"Foo\" } "
   4498       "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
   4499       "            type: TYPE_MESSAGE type_name: \"Foo\" "
   4500       "            extendee: \"google.protobuf.FileOptions\" }"
   4501       "options { uninterpreted_option { name { name_part: \"foo\" "
   4502       "                                        is_extension: true } "
   4503       "                                 $0 } }",
   4504       value);
   4505 }
   4506 
   4507 TEST_F(ValidationErrorTest, AggregateValueNotFound) {
   4508   BuildDescriptorMessagesInTestPool();
   4509 
   4510   BuildFileWithErrors(
   4511       EmbedAggregateValue("string_value: \"\""),
   4512       "foo.proto: foo.proto: OPTION_VALUE: Option \"foo\" is a message. "
   4513       "To set the entire message, use syntax like "
   4514       "\"foo = { <proto text format> }\". To set fields within it, use "
   4515       "syntax like \"foo.foo = value\".\n");
   4516 }
   4517 
   4518 TEST_F(ValidationErrorTest, AggregateValueParseError) {
   4519   BuildDescriptorMessagesInTestPool();
   4520 
   4521   BuildFileWithErrors(
   4522       EmbedAggregateValue("aggregate_value: \"1+2\""),
   4523       "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option "
   4524       "value for \"foo\": Expected identifier.\n");
   4525 }
   4526 
   4527 TEST_F(ValidationErrorTest, AggregateValueUnknownFields) {
   4528   BuildDescriptorMessagesInTestPool();
   4529 
   4530   BuildFileWithErrors(
   4531       EmbedAggregateValue("aggregate_value: \"x:100\""),
   4532       "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option "
   4533       "value for \"foo\": Message type \"Foo\" has no field named \"x\".\n");
   4534 }
   4535 
   4536 TEST_F(ValidationErrorTest, NotLiteImportsLite) {
   4537   BuildFile(
   4538     "name: \"bar.proto\" "
   4539     "options { optimize_for: LITE_RUNTIME } ");
   4540 
   4541   BuildFileWithErrors(
   4542     "name: \"foo.proto\" "
   4543     "dependency: \"bar.proto\" ",
   4544 
   4545     "foo.proto: foo.proto: OTHER: Files that do not use optimize_for = "
   4546       "LITE_RUNTIME cannot import files which do use this option.  This file "
   4547       "is not lite, but it imports \"bar.proto\" which is.\n");
   4548 }
   4549 
   4550 TEST_F(ValidationErrorTest, LiteExtendsNotLite) {
   4551   BuildFile(
   4552     "name: \"bar.proto\" "
   4553     "message_type: {"
   4554     "  name: \"Bar\""
   4555     "  extension_range { start: 1 end: 1000 }"
   4556     "}");
   4557 
   4558   BuildFileWithErrors(
   4559     "name: \"foo.proto\" "
   4560     "dependency: \"bar.proto\" "
   4561     "options { optimize_for: LITE_RUNTIME } "
   4562     "extension { name: \"ext\" number: 123 label: LABEL_OPTIONAL "
   4563     "            type: TYPE_INT32 extendee: \"Bar\" }",
   4564 
   4565     "foo.proto: ext: EXTENDEE: Extensions to non-lite types can only be "
   4566       "declared in non-lite files.  Note that you cannot extend a non-lite "
   4567       "type to contain a lite type, but the reverse is allowed.\n");
   4568 }
   4569 
   4570 TEST_F(ValidationErrorTest, NoLiteServices) {
   4571   BuildFileWithErrors(
   4572     "name: \"foo.proto\" "
   4573     "options {"
   4574     "  optimize_for: LITE_RUNTIME"
   4575     "  cc_generic_services: true"
   4576     "  java_generic_services: true"
   4577     "} "
   4578     "service { name: \"Foo\" }",
   4579 
   4580     "foo.proto: Foo: NAME: Files with optimize_for = LITE_RUNTIME cannot "
   4581     "define services unless you set both options cc_generic_services and "
   4582     "java_generic_sevices to false.\n");
   4583 
   4584   BuildFile(
   4585     "name: \"bar.proto\" "
   4586     "options {"
   4587     "  optimize_for: LITE_RUNTIME"
   4588     "  cc_generic_services: false"
   4589     "  java_generic_services: false"
   4590     "} "
   4591     "service { name: \"Bar\" }");
   4592 }
   4593 
   4594 TEST_F(ValidationErrorTest, RollbackAfterError) {
   4595   // Build a file which contains every kind of construct but references an
   4596   // undefined type.  All these constructs will be added to the symbol table
   4597   // before the undefined type error is noticed.  The DescriptorPool will then
   4598   // have to roll everything back.
   4599   BuildFileWithErrors(
   4600     "name: \"foo.proto\" "
   4601     "message_type {"
   4602     "  name: \"TestMessage\""
   4603     "  field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }"
   4604     "} "
   4605     "enum_type {"
   4606     "  name: \"TestEnum\""
   4607     "  value { name:\"BAR\" number:1 }"
   4608     "} "
   4609     "service {"
   4610     "  name: \"TestService\""
   4611     "  method {"
   4612     "    name: \"Baz\""
   4613     "    input_type: \"NoSuchType\""    // error
   4614     "    output_type: \"TestMessage\""
   4615     "  }"
   4616     "}",
   4617 
   4618     "foo.proto: TestService.Baz: INPUT_TYPE: \"NoSuchType\" is not defined.\n"
   4619     );
   4620 
   4621   // Make sure that if we build the same file again with the error fixed,
   4622   // it works.  If the above rollback was incomplete, then some symbols will
   4623   // be left defined, and this second attempt will fail since it tries to
   4624   // re-define the same symbols.
   4625   BuildFile(
   4626     "name: \"foo.proto\" "
   4627     "message_type {"
   4628     "  name: \"TestMessage\""
   4629     "  field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }"
   4630     "} "
   4631     "enum_type {"
   4632     "  name: \"TestEnum\""
   4633     "  value { name:\"BAR\" number:1 }"
   4634     "} "
   4635     "service {"
   4636     "  name: \"TestService\""
   4637     "  method { name:\"Baz\""
   4638     "           input_type:\"TestMessage\""
   4639     "           output_type:\"TestMessage\" }"
   4640     "}");
   4641 }
   4642 
   4643 TEST_F(ValidationErrorTest, ErrorsReportedToLogError) {
   4644   // Test that errors are reported to GOOGLE_LOG(ERROR) if no error collector is
   4645   // provided.
   4646 
   4647   FileDescriptorProto file_proto;
   4648   ASSERT_TRUE(TextFormat::ParseFromString(
   4649     "name: \"foo.proto\" "
   4650     "message_type { name: \"Foo\" } "
   4651     "message_type { name: \"Foo\" } ",
   4652     &file_proto));
   4653 
   4654   vector<string> errors;
   4655 
   4656   {
   4657     ScopedMemoryLog log;
   4658     EXPECT_TRUE(pool_.BuildFile(file_proto) == NULL);
   4659     errors = log.GetMessages(ERROR);
   4660   }
   4661 
   4662   ASSERT_EQ(2, errors.size());
   4663 
   4664   EXPECT_EQ("Invalid proto descriptor for file \"foo.proto\":", errors[0]);
   4665   EXPECT_EQ("  Foo: \"Foo\" is already defined.", errors[1]);
   4666 }
   4667 
   4668 TEST_F(ValidationErrorTest, DisallowEnumAlias) {
   4669   BuildFileWithErrors(
   4670     "name: \"foo.proto\" "
   4671     "enum_type {"
   4672     "  name: \"Bar\""
   4673     "  value { name:\"ENUM_A\" number:0 }"
   4674     "  value { name:\"ENUM_B\" number:0 }"
   4675     "}",
   4676     "foo.proto: Bar: NUMBER: "
   4677     "\"ENUM_B\" uses the same enum value as \"ENUM_A\". "
   4678     "If this is intended, set 'option allow_alias = true;' to the enum "
   4679     "definition.\n");
   4680 }
   4681 
   4682 TEST_F(ValidationErrorTest, AllowEnumAlias) {
   4683   BuildFile(
   4684     "name: \"foo.proto\" "
   4685     "enum_type {"
   4686     "  name: \"Bar\""
   4687     "  value { name:\"ENUM_A\" number:0 }"
   4688     "  value { name:\"ENUM_B\" number:0 }"
   4689     "  options { allow_alias: true }"
   4690     "}");
   4691 }
   4692 
   4693 TEST_F(ValidationErrorTest, UnusedImportWarning) {
   4694 
   4695   pool_.AddUnusedImportTrackFile("bar.proto");
   4696   BuildFile(
   4697     "name: \"bar.proto\" "
   4698     "message_type { name: \"Bar\" }");
   4699 
   4700   pool_.AddUnusedImportTrackFile("base.proto");
   4701   BuildFile(
   4702     "name: \"base.proto\" "
   4703     "message_type { name: \"Base\" }");
   4704 
   4705   pool_.AddUnusedImportTrackFile("baz.proto");
   4706   BuildFile(
   4707     "name: \"baz.proto\" "
   4708     "message_type { name: \"Baz\" }");
   4709 
   4710   pool_.AddUnusedImportTrackFile("public.proto");
   4711   BuildFile(
   4712     "name: \"public.proto\" "
   4713     "dependency: \"bar.proto\""
   4714     "public_dependency: 0");
   4715 
   4716   // // forward.proto
   4717   // import "base.proto"       // No warning: Base message is used.
   4718   // import "bar.proto"        // Will log a warning.
   4719   // import public "baz.proto" // No warning: Do not track import public.
   4720   // import "public.proto"     // No warning: public.proto has import public.
   4721   // message Forward {
   4722   //   optional Base base = 1;
   4723   // }
   4724   //
   4725   pool_.AddUnusedImportTrackFile("forward.proto");
   4726   BuildFile(
   4727     "name: \"forward.proto\""
   4728     "dependency: \"base.proto\""
   4729     "dependency: \"bar.proto\""
   4730     "dependency: \"baz.proto\""
   4731     "dependency: \"public.proto\""
   4732     "public_dependency: 2 "
   4733     "message_type {"
   4734     "  name: \"Forward\""
   4735     "  field { name:\"base\" number:1 label:LABEL_OPTIONAL type_name:\"Base\" }"
   4736     "}");
   4737 }
   4738 
   4739 
   4740 // ===================================================================
   4741 // DescriptorDatabase
   4742 
   4743 static void AddToDatabase(SimpleDescriptorDatabase* database,
   4744                           const char* file_text) {
   4745   FileDescriptorProto file_proto;
   4746   EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
   4747   database->Add(file_proto);
   4748 }
   4749 
   4750 class DatabaseBackedPoolTest : public testing::Test {
   4751  protected:
   4752   DatabaseBackedPoolTest() {}
   4753 
   4754   SimpleDescriptorDatabase database_;
   4755 
   4756   virtual void SetUp() {
   4757     AddToDatabase(&database_,
   4758       "name: 'foo.proto' "
   4759       "message_type { name:'Foo' extension_range { start: 1 end: 100 } } "
   4760       "enum_type { name:'TestEnum' value { name:'DUMMY' number:0 } } "
   4761       "service { name:'TestService' } ");
   4762     AddToDatabase(&database_,
   4763       "name: 'bar.proto' "
   4764       "dependency: 'foo.proto' "
   4765       "message_type { name:'Bar' } "
   4766       "extension { name:'foo_ext' extendee: '.Foo' number:5 "
   4767       "            label:LABEL_OPTIONAL type:TYPE_INT32 } ");
   4768     // Baz has an undeclared dependency on Foo.
   4769     AddToDatabase(&database_,
   4770       "name: 'baz.proto' "
   4771       "message_type { "
   4772       "  name:'Baz' "
   4773       "  field { name:'foo' number:1 label:LABEL_OPTIONAL type_name:'Foo' } "
   4774       "}");
   4775   }
   4776 
   4777   // We can't inject a file containing errors into a DescriptorPool, so we
   4778   // need an actual mock DescriptorDatabase to test errors.
   4779   class ErrorDescriptorDatabase : public DescriptorDatabase {
   4780    public:
   4781     ErrorDescriptorDatabase() {}
   4782     ~ErrorDescriptorDatabase() {}
   4783 
   4784     // implements DescriptorDatabase ---------------------------------
   4785     bool FindFileByName(const string& filename,
   4786                         FileDescriptorProto* output) {
   4787       // error.proto and error2.proto cyclically import each other.
   4788       if (filename == "error.proto") {
   4789         output->Clear();
   4790         output->set_name("error.proto");
   4791         output->add_dependency("error2.proto");
   4792         return true;
   4793       } else if (filename == "error2.proto") {
   4794         output->Clear();
   4795         output->set_name("error2.proto");
   4796         output->add_dependency("error.proto");
   4797         return true;
   4798       } else {
   4799         return false;
   4800       }
   4801     }
   4802     bool FindFileContainingSymbol(const string& symbol_name,
   4803                                   FileDescriptorProto* output) {
   4804       return false;
   4805     }
   4806     bool FindFileContainingExtension(const string& containing_type,
   4807                                      int field_number,
   4808                                      FileDescriptorProto* output) {
   4809       return false;
   4810     }
   4811   };
   4812 
   4813   // A DescriptorDatabase that counts how many times each method has been
   4814   // called and forwards to some other DescriptorDatabase.
   4815   class CallCountingDatabase : public DescriptorDatabase {
   4816    public:
   4817     CallCountingDatabase(DescriptorDatabase* wrapped_db)
   4818       : wrapped_db_(wrapped_db) {
   4819       Clear();
   4820     }
   4821     ~CallCountingDatabase() {}
   4822 
   4823     DescriptorDatabase* wrapped_db_;
   4824 
   4825     int call_count_;
   4826 
   4827     void Clear() {
   4828       call_count_ = 0;
   4829     }
   4830 
   4831     // implements DescriptorDatabase ---------------------------------
   4832     bool FindFileByName(const string& filename,
   4833                         FileDescriptorProto* output) {
   4834       ++call_count_;
   4835       return wrapped_db_->FindFileByName(filename, output);
   4836     }
   4837     bool FindFileContainingSymbol(const string& symbol_name,
   4838                                   FileDescriptorProto* output) {
   4839       ++call_count_;
   4840       return wrapped_db_->FindFileContainingSymbol(symbol_name, output);
   4841     }
   4842     bool FindFileContainingExtension(const string& containing_type,
   4843                                      int field_number,
   4844                                      FileDescriptorProto* output) {
   4845       ++call_count_;
   4846       return wrapped_db_->FindFileContainingExtension(
   4847         containing_type, field_number, output);
   4848     }
   4849   };
   4850 
   4851   // A DescriptorDatabase which falsely always returns foo.proto when searching
   4852   // for any symbol or extension number.  This shouldn't cause the
   4853   // DescriptorPool to reload foo.proto if it is already loaded.
   4854   class FalsePositiveDatabase : public DescriptorDatabase {
   4855    public:
   4856     FalsePositiveDatabase(DescriptorDatabase* wrapped_db)
   4857       : wrapped_db_(wrapped_db) {}
   4858     ~FalsePositiveDatabase() {}
   4859 
   4860     DescriptorDatabase* wrapped_db_;
   4861 
   4862     // implements DescriptorDatabase ---------------------------------
   4863     bool FindFileByName(const string& filename,
   4864                         FileDescriptorProto* output) {
   4865       return wrapped_db_->FindFileByName(filename, output);
   4866     }
   4867     bool FindFileContainingSymbol(const string& symbol_name,
   4868                                   FileDescriptorProto* output) {
   4869       return FindFileByName("foo.proto", output);
   4870     }
   4871     bool FindFileContainingExtension(const string& containing_type,
   4872                                      int field_number,
   4873                                      FileDescriptorProto* output) {
   4874       return FindFileByName("foo.proto", output);
   4875     }
   4876   };
   4877 };
   4878 
   4879 TEST_F(DatabaseBackedPoolTest, FindFileByName) {
   4880   DescriptorPool pool(&database_);
   4881 
   4882   const FileDescriptor* foo = pool.FindFileByName("foo.proto");
   4883   ASSERT_TRUE(foo != NULL);
   4884   EXPECT_EQ("foo.proto", foo->name());
   4885   ASSERT_EQ(1, foo->message_type_count());
   4886   EXPECT_EQ("Foo", foo->message_type(0)->name());
   4887 
   4888   EXPECT_EQ(foo, pool.FindFileByName("foo.proto"));
   4889 
   4890   EXPECT_TRUE(pool.FindFileByName("no_such_file.proto") == NULL);
   4891 }
   4892 
   4893 TEST_F(DatabaseBackedPoolTest, FindDependencyBeforeDependent) {
   4894   DescriptorPool pool(&database_);
   4895 
   4896   const FileDescriptor* foo = pool.FindFileByName("foo.proto");
   4897   ASSERT_TRUE(foo != NULL);
   4898   EXPECT_EQ("foo.proto", foo->name());
   4899   ASSERT_EQ(1, foo->message_type_count());
   4900   EXPECT_EQ("Foo", foo->message_type(0)->name());
   4901 
   4902   const FileDescriptor* bar = pool.FindFileByName("bar.proto");
   4903   ASSERT_TRUE(bar != NULL);
   4904   EXPECT_EQ("bar.proto", bar->name());
   4905   ASSERT_EQ(1, bar->message_type_count());
   4906   EXPECT_EQ("Bar", bar->message_type(0)->name());
   4907 
   4908   ASSERT_EQ(1, bar->dependency_count());
   4909   EXPECT_EQ(foo, bar->dependency(0));
   4910 }
   4911 
   4912 TEST_F(DatabaseBackedPoolTest, FindDependentBeforeDependency) {
   4913   DescriptorPool pool(&database_);
   4914 
   4915   const FileDescriptor* bar = pool.FindFileByName("bar.proto");
   4916   ASSERT_TRUE(bar != NULL);
   4917   EXPECT_EQ("bar.proto", bar->name());
   4918   ASSERT_EQ(1, bar->message_type_count());
   4919   ASSERT_EQ("Bar", bar->message_type(0)->name());
   4920 
   4921   const FileDescriptor* foo = pool.FindFileByName("foo.proto");
   4922   ASSERT_TRUE(foo != NULL);
   4923   EXPECT_EQ("foo.proto", foo->name());
   4924   ASSERT_EQ(1, foo->message_type_count());
   4925   ASSERT_EQ("Foo", foo->message_type(0)->name());
   4926 
   4927   ASSERT_EQ(1, bar->dependency_count());
   4928   EXPECT_EQ(foo, bar->dependency(0));
   4929 }
   4930 
   4931 TEST_F(DatabaseBackedPoolTest, FindFileContainingSymbol) {
   4932   DescriptorPool pool(&database_);
   4933 
   4934   const FileDescriptor* file = pool.FindFileContainingSymbol("Foo");
   4935   ASSERT_TRUE(file != NULL);
   4936   EXPECT_EQ("foo.proto", file->name());
   4937   EXPECT_EQ(file, pool.FindFileByName("foo.proto"));
   4938 
   4939   EXPECT_TRUE(pool.FindFileContainingSymbol("NoSuchSymbol") == NULL);
   4940 }
   4941 
   4942 TEST_F(DatabaseBackedPoolTest, FindMessageTypeByName) {
   4943   DescriptorPool pool(&database_);
   4944 
   4945   const Descriptor* type = pool.FindMessageTypeByName("Foo");
   4946   ASSERT_TRUE(type != NULL);
   4947   EXPECT_EQ("Foo", type->name());
   4948   EXPECT_EQ(type->file(), pool.FindFileByName("foo.proto"));
   4949 
   4950   EXPECT_TRUE(pool.FindMessageTypeByName("NoSuchType") == NULL);
   4951 }
   4952 
   4953 TEST_F(DatabaseBackedPoolTest, FindExtensionByNumber) {
   4954   DescriptorPool pool(&database_);
   4955 
   4956   const Descriptor* foo = pool.FindMessageTypeByName("Foo");
   4957   ASSERT_TRUE(foo != NULL);
   4958 
   4959   const FieldDescriptor* extension = pool.FindExtensionByNumber(foo, 5);
   4960   ASSERT_TRUE(extension != NULL);
   4961   EXPECT_EQ("foo_ext", extension->name());
   4962   EXPECT_EQ(extension->file(), pool.FindFileByName("bar.proto"));
   4963 
   4964   EXPECT_TRUE(pool.FindExtensionByNumber(foo, 12) == NULL);
   4965 }
   4966 
   4967 TEST_F(DatabaseBackedPoolTest, FindAllExtensions) {
   4968   DescriptorPool pool(&database_);
   4969 
   4970   const Descriptor* foo = pool.FindMessageTypeByName("Foo");
   4971 
   4972   for (int i = 0; i < 2; ++i) {
   4973     // Repeat the lookup twice, to check that we get consistent
   4974     // results despite the fallback database lookup mutating the pool.
   4975     vector<const FieldDescriptor*> extensions;
   4976     pool.FindAllExtensions(foo, &extensions);
   4977     ASSERT_EQ(1, extensions.size());
   4978     EXPECT_EQ(5, extensions[0]->number());
   4979   }
   4980 }
   4981 
   4982 TEST_F(DatabaseBackedPoolTest, ErrorWithoutErrorCollector) {
   4983   ErrorDescriptorDatabase error_database;
   4984   DescriptorPool pool(&error_database);
   4985 
   4986   vector<string> errors;
   4987 
   4988   {
   4989     ScopedMemoryLog log;
   4990     EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL);
   4991     errors = log.GetMessages(ERROR);
   4992   }
   4993 
   4994   EXPECT_FALSE(errors.empty());
   4995 }
   4996 
   4997 TEST_F(DatabaseBackedPoolTest, ErrorWithErrorCollector) {
   4998   ErrorDescriptorDatabase error_database;
   4999   MockErrorCollector error_collector;
   5000   DescriptorPool pool(&error_database, &error_collector);
   5001 
   5002   EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL);
   5003   EXPECT_EQ(
   5004     "error.proto: error.proto: OTHER: File recursively imports itself: "
   5005       "error.proto -> error2.proto -> error.proto\n"
   5006     "error2.proto: error2.proto: OTHER: Import \"error.proto\" was not "
   5007       "found or had errors.\n"
   5008     "error.proto: error.proto: OTHER: Import \"error2.proto\" was not "
   5009       "found or had errors.\n",
   5010     error_collector.text_);
   5011 }
   5012 
   5013 TEST_F(DatabaseBackedPoolTest, UndeclaredDependencyOnUnbuiltType) {
   5014   // Check that we find and report undeclared dependencies on types that exist
   5015   // in the descriptor database but that have not not been built yet.
   5016   MockErrorCollector error_collector;
   5017   DescriptorPool pool(&database_, &error_collector);
   5018   EXPECT_TRUE(pool.FindMessageTypeByName("Baz") == NULL);
   5019   EXPECT_EQ(
   5020     "baz.proto: Baz.foo: TYPE: \"Foo\" seems to be defined in \"foo.proto\", "
   5021     "which is not imported by \"baz.proto\".  To use it here, please add "
   5022     "the necessary import.\n",
   5023     error_collector.text_);
   5024 }
   5025 
   5026 TEST_F(DatabaseBackedPoolTest, RollbackAfterError) {
   5027   // Make sure that all traces of bad types are removed from the pool. This used
   5028   // to be b/4529436, due to the fact that a symbol resolution failure could
   5029   // potentially cause another file to be recursively built, which would trigger
   5030   // a checkpoint _past_ possibly invalid symbols.
   5031   // Baz is defined in the database, but the file is invalid because it is
   5032   // missing a necessary import.
   5033   DescriptorPool pool(&database_);
   5034   EXPECT_TRUE(pool.FindMessageTypeByName("Baz") == NULL);
   5035   // Make sure that searching again for the file or the type fails.
   5036   EXPECT_TRUE(pool.FindFileByName("baz.proto") == NULL);
   5037   EXPECT_TRUE(pool.FindMessageTypeByName("Baz") == NULL);
   5038 }
   5039 
   5040 TEST_F(DatabaseBackedPoolTest, UnittestProto) {
   5041   // Try to load all of unittest.proto from a DescriptorDatabase.  This should
   5042   // thoroughly test all paths through DescriptorBuilder to insure that there
   5043   // are no deadlocking problems when pool_->mutex_ is non-NULL.
   5044   const FileDescriptor* original_file =
   5045     protobuf_unittest::TestAllTypes::descriptor()->file();
   5046 
   5047   DescriptorPoolDatabase database(*DescriptorPool::generated_pool());
   5048   DescriptorPool pool(&database);
   5049   const FileDescriptor* file_from_database =
   5050     pool.FindFileByName(original_file->name());
   5051 
   5052   ASSERT_TRUE(file_from_database != NULL);
   5053 
   5054   FileDescriptorProto original_file_proto;
   5055   original_file->CopyTo(&original_file_proto);
   5056 
   5057   FileDescriptorProto file_from_database_proto;
   5058   file_from_database->CopyTo(&file_from_database_proto);
   5059 
   5060   EXPECT_EQ(original_file_proto.DebugString(),
   5061             file_from_database_proto.DebugString());
   5062 
   5063   // Also verify that CopyTo() did not omit any information.
   5064   EXPECT_EQ(original_file->DebugString(),
   5065             file_from_database->DebugString());
   5066 }
   5067 
   5068 TEST_F(DatabaseBackedPoolTest, DoesntRetryDbUnnecessarily) {
   5069   // Searching for a child of an existing descriptor should never fall back
   5070   // to the DescriptorDatabase even if it isn't found, because we know all
   5071   // children are already loaded.
   5072   CallCountingDatabase call_counter(&database_);
   5073   DescriptorPool pool(&call_counter);
   5074 
   5075   const FileDescriptor* file = pool.FindFileByName("foo.proto");
   5076   ASSERT_TRUE(file != NULL);
   5077   const Descriptor* foo = pool.FindMessageTypeByName("Foo");
   5078   ASSERT_TRUE(foo != NULL);
   5079   const EnumDescriptor* test_enum = pool.FindEnumTypeByName("TestEnum");
   5080   ASSERT_TRUE(test_enum != NULL);
   5081   const ServiceDescriptor* test_service = pool.FindServiceByName("TestService");
   5082   ASSERT_TRUE(test_service != NULL);
   5083 
   5084   EXPECT_NE(0, call_counter.call_count_);
   5085   call_counter.Clear();
   5086 
   5087   EXPECT_TRUE(foo->FindFieldByName("no_such_field") == NULL);
   5088   EXPECT_TRUE(foo->FindExtensionByName("no_such_extension") == NULL);
   5089   EXPECT_TRUE(foo->FindNestedTypeByName("NoSuchMessageType") == NULL);
   5090   EXPECT_TRUE(foo->FindEnumTypeByName("NoSuchEnumType") == NULL);
   5091   EXPECT_TRUE(foo->FindEnumValueByName("NO_SUCH_VALUE") == NULL);
   5092   EXPECT_TRUE(test_enum->FindValueByName("NO_SUCH_VALUE") == NULL);
   5093   EXPECT_TRUE(test_service->FindMethodByName("NoSuchMethod") == NULL);
   5094 
   5095   EXPECT_TRUE(file->FindMessageTypeByName("NoSuchMessageType") == NULL);
   5096   EXPECT_TRUE(file->FindEnumTypeByName("NoSuchEnumType") == NULL);
   5097   EXPECT_TRUE(file->FindEnumValueByName("NO_SUCH_VALUE") == NULL);
   5098   EXPECT_TRUE(file->FindServiceByName("NO_SUCH_VALUE") == NULL);
   5099   EXPECT_TRUE(file->FindExtensionByName("no_such_extension") == NULL);
   5100 
   5101   EXPECT_TRUE(pool.FindFileContainingSymbol("Foo.no.such.field") == NULL);
   5102   EXPECT_TRUE(pool.FindFileContainingSymbol("Foo.no_such_field") == NULL);
   5103   EXPECT_TRUE(pool.FindMessageTypeByName("Foo.NoSuchMessageType") == NULL);
   5104   EXPECT_TRUE(pool.FindFieldByName("Foo.no_such_field") == NULL);
   5105   EXPECT_TRUE(pool.FindExtensionByName("Foo.no_such_extension") == NULL);
   5106   EXPECT_TRUE(pool.FindEnumTypeByName("Foo.NoSuchEnumType") == NULL);
   5107   EXPECT_TRUE(pool.FindEnumValueByName("Foo.NO_SUCH_VALUE") == NULL);
   5108   EXPECT_TRUE(pool.FindMethodByName("TestService.NoSuchMethod") == NULL);
   5109 
   5110   EXPECT_EQ(0, call_counter.call_count_);
   5111 }
   5112 
   5113 TEST_F(DatabaseBackedPoolTest, DoesntReloadFilesUncesessarily) {
   5114   // If FindFileContainingSymbol() or FindFileContainingExtension() return a
   5115   // file that is already in the DescriptorPool, it should not attempt to
   5116   // reload the file.
   5117   FalsePositiveDatabase false_positive_database(&database_);
   5118   MockErrorCollector error_collector;
   5119   DescriptorPool pool(&false_positive_database, &error_collector);
   5120 
   5121   // First make sure foo.proto is loaded.
   5122   const Descriptor* foo = pool.FindMessageTypeByName("Foo");
   5123   ASSERT_TRUE(foo != NULL);
   5124 
   5125   // Try inducing false positives.
   5126   EXPECT_TRUE(pool.FindMessageTypeByName("NoSuchSymbol") == NULL);
   5127   EXPECT_TRUE(pool.FindExtensionByNumber(foo, 22) == NULL);
   5128 
   5129   // No errors should have been reported.  (If foo.proto was incorrectly
   5130   // loaded multiple times, errors would have been reported.)
   5131   EXPECT_EQ("", error_collector.text_);
   5132 }
   5133 
   5134 // DescriptorDatabase that attempts to induce exponentially-bad performance
   5135 // in DescriptorPool. For every positive N, the database contains a file
   5136 // fileN.proto, which defines a message MessageN, which contains fields of
   5137 // type MessageK for all K in [0,N). Message0 is not defined anywhere
   5138 // (file0.proto exists, but is empty), so every other file and message type
   5139 // will fail to build.
   5140 //
   5141 // If the DescriptorPool is not careful to memoize errors, an attempt to
   5142 // build a descriptor for MessageN can require O(2^N) time.
   5143 class ExponentialErrorDatabase : public DescriptorDatabase {
   5144  public:
   5145   ExponentialErrorDatabase() {}
   5146   ~ExponentialErrorDatabase() {}
   5147 
   5148   // implements DescriptorDatabase ---------------------------------
   5149   bool FindFileByName(const string& filename,
   5150                       FileDescriptorProto* output) {
   5151     int file_num = -1;
   5152     FullMatch(filename, "file", ".proto", &file_num);
   5153     if (file_num > -1) {
   5154       return PopulateFile(file_num, output);
   5155     } else {
   5156       return false;
   5157     }
   5158   }
   5159   bool FindFileContainingSymbol(const string& symbol_name,
   5160                                 FileDescriptorProto* output) {
   5161     int file_num = -1;
   5162     FullMatch(symbol_name, "Message", "", &file_num);
   5163     if (file_num > 0) {
   5164       return PopulateFile(file_num, output);
   5165     } else {
   5166       return false;
   5167     }
   5168   }
   5169   bool FindFileContainingExtension(const string& containing_type,
   5170                                    int field_number,
   5171                                    FileDescriptorProto* output) {
   5172     return false;
   5173   }
   5174 
   5175  private:
   5176   void FullMatch(const string& name,
   5177                  const string& begin_with,
   5178                  const string& end_with,
   5179                  int* file_num) {
   5180     int begin_size = begin_with.size();
   5181     int end_size = end_with.size();
   5182     if (name.substr(0, begin_size) != begin_with ||
   5183         name.substr(name.size()- end_size, end_size) != end_with) {
   5184       return;
   5185     }
   5186     safe_strto32(name.substr(begin_size, name.size() - end_size - begin_size),
   5187                  file_num);
   5188   }
   5189 
   5190   bool PopulateFile(int file_num, FileDescriptorProto* output) {
   5191     using strings::Substitute;
   5192     GOOGLE_CHECK_GE(file_num, 0);
   5193     output->Clear();
   5194     output->set_name(Substitute("file$0.proto", file_num));
   5195     // file0.proto doesn't define Message0
   5196     if (file_num > 0) {
   5197       DescriptorProto* message = output->add_message_type();
   5198       message->set_name(Substitute("Message$0", file_num));
   5199       for (int i = 0; i < file_num; ++i) {
   5200         output->add_dependency(Substitute("file$0.proto", i));
   5201         FieldDescriptorProto* field = message->add_field();
   5202         field->set_name(Substitute("field$0", i));
   5203         field->set_number(i);
   5204         field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
   5205         field->set_type(FieldDescriptorProto::TYPE_MESSAGE);
   5206         field->set_type_name(Substitute("Message$0", i));
   5207       }
   5208     }
   5209     return true;
   5210   }
   5211 };
   5212 
   5213 TEST_F(DatabaseBackedPoolTest, DoesntReloadKnownBadFiles) {
   5214   ExponentialErrorDatabase error_database;
   5215   DescriptorPool pool(&error_database);
   5216 
   5217   GOOGLE_LOG(INFO) << "A timeout in this test probably indicates a real bug.";
   5218 
   5219   EXPECT_TRUE(pool.FindFileByName("file40.proto") == NULL);
   5220   EXPECT_TRUE(pool.FindMessageTypeByName("Message40") == NULL);
   5221 }
   5222 
   5223 TEST_F(DatabaseBackedPoolTest, DoesntFallbackOnWrongType) {
   5224   // If a lookup finds a symbol of the wrong type (e.g. we pass a type name
   5225   // to FindFieldByName()), we should fail fast, without checking the fallback
   5226   // database.
   5227   CallCountingDatabase call_counter(&database_);
   5228   DescriptorPool pool(&call_counter);
   5229 
   5230   const FileDescriptor* file = pool.FindFileByName("foo.proto");
   5231   ASSERT_TRUE(file != NULL);
   5232   const Descriptor* foo = pool.FindMessageTypeByName("Foo");
   5233   ASSERT_TRUE(foo != NULL);
   5234   const EnumDescriptor* test_enum = pool.FindEnumTypeByName("TestEnum");
   5235   ASSERT_TRUE(test_enum != NULL);
   5236 
   5237   EXPECT_NE(0, call_counter.call_count_);
   5238   call_counter.Clear();
   5239 
   5240   EXPECT_TRUE(pool.FindMessageTypeByName("TestEnum") == NULL);
   5241   EXPECT_TRUE(pool.FindFieldByName("Foo") == NULL);
   5242   EXPECT_TRUE(pool.FindExtensionByName("Foo") == NULL);
   5243   EXPECT_TRUE(pool.FindEnumTypeByName("Foo") == NULL);
   5244   EXPECT_TRUE(pool.FindEnumValueByName("Foo") == NULL);
   5245   EXPECT_TRUE(pool.FindServiceByName("Foo") == NULL);
   5246   EXPECT_TRUE(pool.FindMethodByName("Foo") == NULL);
   5247 
   5248   EXPECT_EQ(0, call_counter.call_count_);
   5249 }
   5250 
   5251 // ===================================================================
   5252 
   5253 class AbortingErrorCollector : public DescriptorPool::ErrorCollector {
   5254  public:
   5255   AbortingErrorCollector() {}
   5256 
   5257   virtual void AddError(
   5258       const string &filename,
   5259       const string &element_name,
   5260       const Message *message,
   5261       ErrorLocation location,
   5262       const string &error_message) {
   5263     GOOGLE_LOG(FATAL) << "AddError() called unexpectedly: " << filename << ": "
   5264                << error_message;
   5265   }
   5266  private:
   5267   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(AbortingErrorCollector);
   5268 };
   5269 
   5270 // A source tree containing only one file.
   5271 class SingletonSourceTree : public compiler::SourceTree {
   5272  public:
   5273   SingletonSourceTree(const string& filename, const string& contents)
   5274       : filename_(filename), contents_(contents) {}
   5275 
   5276   virtual io::ZeroCopyInputStream* Open(const string& filename) {
   5277     return filename == filename_ ?
   5278         new io::ArrayInputStream(contents_.data(), contents_.size()) : NULL;
   5279   }
   5280 
   5281  private:
   5282   const string filename_;
   5283   const string contents_;
   5284 
   5285   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SingletonSourceTree);
   5286 };
   5287 
   5288 const char *const kSourceLocationTestInput =
   5289   "syntax = \"proto2\";\n"
   5290   "message A {\n"
   5291   "  optional int32 a = 1;\n"
   5292   "  message B {\n"
   5293   "    required double b = 1;\n"
   5294   "  }\n"
   5295   "}\n"
   5296   "enum Indecision {\n"
   5297   "  YES   = 1;\n"
   5298   "  NO    = 2;\n"
   5299   "  MAYBE = 3;\n"
   5300   "}\n"
   5301   "service S {\n"
   5302   "  rpc Method(A) returns (A.B);\n"
   5303   // Put an empty line here to make the source location range match.
   5304   "\n"
   5305   "}\n"
   5306   "message MessageWithExtensions {\n"
   5307   "  extensions 1000 to max;\n"
   5308   "}\n"
   5309   "extend MessageWithExtensions {\n"
   5310   "  optional int32 int32_extension = 1001;\n"
   5311   "}\n"
   5312   "message C {\n"
   5313   "  extend MessageWithExtensions {\n"
   5314   "    optional C message_extension = 1002;\n"
   5315   "  }\n"
   5316   "}\n";
   5317 
   5318 class SourceLocationTest : public testing::Test {
   5319  public:
   5320   SourceLocationTest()
   5321       : source_tree_("/test/test.proto", kSourceLocationTestInput),
   5322         db_(&source_tree_),
   5323         pool_(&db_, &collector_) {}
   5324 
   5325   static string PrintSourceLocation(const SourceLocation &loc) {
   5326     return strings::Substitute("$0:$1-$2:$3",
   5327                                1 + loc.start_line,
   5328                                1 + loc.start_column,
   5329                                1 + loc.end_line,
   5330                                1 + loc.end_column);
   5331   }
   5332 
   5333  private:
   5334   AbortingErrorCollector collector_;
   5335   SingletonSourceTree source_tree_;
   5336   compiler::SourceTreeDescriptorDatabase db_;
   5337 
   5338  protected:
   5339   DescriptorPool pool_;
   5340 };
   5341 
   5342 // TODO(adonovan): implement support for option fields and for
   5343 // subparts of declarations.
   5344 
   5345 TEST_F(SourceLocationTest, GetSourceLocation) {
   5346   SourceLocation loc;
   5347 
   5348   const FileDescriptor *file_desc =
   5349       GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
   5350 
   5351   const Descriptor *a_desc = file_desc->FindMessageTypeByName("A");
   5352   EXPECT_TRUE(a_desc->GetSourceLocation(&loc));
   5353   EXPECT_EQ("2:1-7:2", PrintSourceLocation(loc));
   5354 
   5355   const Descriptor *a_b_desc = a_desc->FindNestedTypeByName("B");
   5356   EXPECT_TRUE(a_b_desc->GetSourceLocation(&loc));
   5357   EXPECT_EQ("4:3-6:4", PrintSourceLocation(loc));
   5358 
   5359   const EnumDescriptor *e_desc = file_desc->FindEnumTypeByName("Indecision");
   5360   EXPECT_TRUE(e_desc->GetSourceLocation(&loc));
   5361   EXPECT_EQ("8:1-12:2", PrintSourceLocation(loc));
   5362 
   5363   const EnumValueDescriptor *yes_desc = e_desc->FindValueByName("YES");
   5364   EXPECT_TRUE(yes_desc->GetSourceLocation(&loc));
   5365   EXPECT_EQ("9:3-9:13", PrintSourceLocation(loc));
   5366 
   5367   const ServiceDescriptor *s_desc = file_desc->FindServiceByName("S");
   5368   EXPECT_TRUE(s_desc->GetSourceLocation(&loc));
   5369   EXPECT_EQ("13:1-16:2", PrintSourceLocation(loc));
   5370 
   5371   const MethodDescriptor *m_desc = s_desc->FindMethodByName("Method");
   5372   EXPECT_TRUE(m_desc->GetSourceLocation(&loc));
   5373   EXPECT_EQ("14:3-14:31", PrintSourceLocation(loc));
   5374 
   5375 }
   5376 
   5377 TEST_F(SourceLocationTest, ExtensionSourceLocation) {
   5378   SourceLocation loc;
   5379 
   5380   const FileDescriptor *file_desc =
   5381       GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
   5382 
   5383   const FieldDescriptor *int32_extension_desc =
   5384       file_desc->FindExtensionByName("int32_extension");
   5385   EXPECT_TRUE(int32_extension_desc->GetSourceLocation(&loc));
   5386   EXPECT_EQ("21:3-21:41", PrintSourceLocation(loc));
   5387 
   5388   const Descriptor *c_desc = file_desc->FindMessageTypeByName("C");
   5389   EXPECT_TRUE(c_desc->GetSourceLocation(&loc));
   5390   EXPECT_EQ("23:1-27:2", PrintSourceLocation(loc));
   5391 
   5392   const FieldDescriptor *message_extension_desc =
   5393       c_desc->FindExtensionByName("message_extension");
   5394   EXPECT_TRUE(message_extension_desc->GetSourceLocation(&loc));
   5395   EXPECT_EQ("25:5-25:41", PrintSourceLocation(loc));
   5396 }
   5397 
   5398 // Missing SourceCodeInfo doesn't cause crash:
   5399 TEST_F(SourceLocationTest, GetSourceLocation_MissingSourceCodeInfo) {
   5400   SourceLocation loc;
   5401 
   5402   const FileDescriptor *file_desc =
   5403       GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
   5404 
   5405   FileDescriptorProto proto;
   5406   file_desc->CopyTo(&proto);  // Note, this discards the SourceCodeInfo.
   5407   EXPECT_FALSE(proto.has_source_code_info());
   5408 
   5409   DescriptorPool bad1_pool(&pool_);
   5410   const FileDescriptor* bad1_file_desc =
   5411       GOOGLE_CHECK_NOTNULL(bad1_pool.BuildFile(proto));
   5412   const Descriptor *bad1_a_desc = bad1_file_desc->FindMessageTypeByName("A");
   5413   EXPECT_FALSE(bad1_a_desc->GetSourceLocation(&loc));
   5414 }
   5415 
   5416 // Corrupt SourceCodeInfo doesn't cause crash:
   5417 TEST_F(SourceLocationTest, GetSourceLocation_BogusSourceCodeInfo) {
   5418   SourceLocation loc;
   5419 
   5420   const FileDescriptor *file_desc =
   5421       GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
   5422 
   5423   FileDescriptorProto proto;
   5424   file_desc->CopyTo(&proto);  // Note, this discards the SourceCodeInfo.
   5425   EXPECT_FALSE(proto.has_source_code_info());
   5426   SourceCodeInfo_Location *loc_msg =
   5427       proto.mutable_source_code_info()->add_location();
   5428   loc_msg->add_path(1);
   5429   loc_msg->add_path(2);
   5430   loc_msg->add_path(3);
   5431   loc_msg->add_span(4);
   5432   loc_msg->add_span(5);
   5433   loc_msg->add_span(6);
   5434 
   5435   DescriptorPool bad2_pool(&pool_);
   5436   const FileDescriptor* bad2_file_desc =
   5437       GOOGLE_CHECK_NOTNULL(bad2_pool.BuildFile(proto));
   5438   const Descriptor *bad2_a_desc = bad2_file_desc->FindMessageTypeByName("A");
   5439   EXPECT_FALSE(bad2_a_desc->GetSourceLocation(&loc));
   5440 }
   5441 
   5442 // ===================================================================
   5443 
   5444 const char* const kCopySourceCodeInfoToTestInput =
   5445   "syntax = \"proto2\";\n"
   5446   "message Foo {}\n";
   5447 
   5448 // Required since source code information is not preserved by
   5449 // FileDescriptorTest.
   5450 class CopySourceCodeInfoToTest : public testing::Test {
   5451  public:
   5452   CopySourceCodeInfoToTest()
   5453       : source_tree_("/test/test.proto", kCopySourceCodeInfoToTestInput),
   5454         db_(&source_tree_),
   5455         pool_(&db_, &collector_) {}
   5456 
   5457  private:
   5458   AbortingErrorCollector collector_;
   5459   SingletonSourceTree source_tree_;
   5460   compiler::SourceTreeDescriptorDatabase db_;
   5461 
   5462  protected:
   5463   DescriptorPool pool_;
   5464 };
   5465 
   5466 TEST_F(CopySourceCodeInfoToTest, CopyTo_DoesNotCopySourceCodeInfo) {
   5467   const FileDescriptor* file_desc =
   5468       GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
   5469   FileDescriptorProto file_desc_proto;
   5470   ASSERT_FALSE(file_desc_proto.has_source_code_info());
   5471 
   5472   file_desc->CopyTo(&file_desc_proto);
   5473   EXPECT_FALSE(file_desc_proto.has_source_code_info());
   5474 }
   5475 
   5476 TEST_F(CopySourceCodeInfoToTest, CopySourceCodeInfoTo) {
   5477   const FileDescriptor* file_desc =
   5478       GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
   5479   FileDescriptorProto file_desc_proto;
   5480   ASSERT_FALSE(file_desc_proto.has_source_code_info());
   5481 
   5482   file_desc->CopySourceCodeInfoTo(&file_desc_proto);
   5483   const SourceCodeInfo& info = file_desc_proto.source_code_info();
   5484   ASSERT_EQ(3, info.location_size());
   5485   // Get the Foo message location
   5486   const SourceCodeInfo_Location& foo_location = info.location(1);
   5487   ASSERT_EQ(2, foo_location.path_size());
   5488   EXPECT_EQ(FileDescriptorProto::kMessageTypeFieldNumber, foo_location.path(0));
   5489   EXPECT_EQ(0, foo_location.path(1));      // Foo is the first message defined
   5490   ASSERT_EQ(3, foo_location.span_size());  // Foo spans one line
   5491   EXPECT_EQ(1, foo_location.span(0));      // Foo is declared on line 1
   5492   EXPECT_EQ(0, foo_location.span(1));      // Foo starts at column 0
   5493   EXPECT_EQ(14, foo_location.span(2));     // Foo ends on column 14
   5494 }
   5495 
   5496 // ===================================================================
   5497 
   5498 
   5499 }  // namespace descriptor_unittest
   5500 }  // namespace protobuf
   5501 }  // namespace google
   5502