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