Home | History | Annotate | Download | only in compiler
      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 #include <memory>
     36 #ifndef _SHARED_PTR_H
     37 #include <google/protobuf/stubs/shared_ptr.h>
     38 #endif
     39 #include <vector>
     40 #include <algorithm>
     41 #include <map>
     42 
     43 #include <google/protobuf/compiler/parser.h>
     44 
     45 #include <google/protobuf/io/tokenizer.h>
     46 #include <google/protobuf/io/zero_copy_stream_impl.h>
     47 #include <google/protobuf/descriptor.pb.h>
     48 #include <google/protobuf/wire_format.h>
     49 #include <google/protobuf/text_format.h>
     50 #include <google/protobuf/unittest.pb.h>
     51 #include <google/protobuf/unittest_custom_options.pb.h>
     52 #include <google/protobuf/stubs/strutil.h>
     53 #include <google/protobuf/stubs/substitute.h>
     54 #include <google/protobuf/stubs/map_util.h>
     55 
     56 #include <google/protobuf/testing/googletest.h>
     57 #include <gtest/gtest.h>
     58 
     59 namespace google {
     60 namespace protobuf {
     61 namespace compiler {
     62 
     63 namespace {
     64 
     65 class MockErrorCollector : public io::ErrorCollector {
     66  public:
     67   MockErrorCollector() {}
     68   ~MockErrorCollector() {}
     69 
     70   string text_;
     71 
     72   // implements ErrorCollector ---------------------------------------
     73   void AddError(int line, int column, const string& message) {
     74     strings::SubstituteAndAppend(&text_, "$0:$1: $2\n",
     75                                  line, column, message);
     76   }
     77 };
     78 
     79 class MockValidationErrorCollector : public DescriptorPool::ErrorCollector {
     80  public:
     81   MockValidationErrorCollector(const SourceLocationTable& source_locations,
     82                                io::ErrorCollector* wrapped_collector)
     83     : source_locations_(source_locations),
     84       wrapped_collector_(wrapped_collector) {}
     85   ~MockValidationErrorCollector() {}
     86 
     87   // implements ErrorCollector ---------------------------------------
     88   void AddError(const string& filename,
     89                 const string& element_name,
     90                 const Message* descriptor,
     91                 ErrorLocation location,
     92                 const string& message) {
     93     int line, column;
     94     source_locations_.Find(descriptor, location, &line, &column);
     95     wrapped_collector_->AddError(line, column, message);
     96   }
     97 
     98  private:
     99   const SourceLocationTable& source_locations_;
    100   io::ErrorCollector* wrapped_collector_;
    101 };
    102 
    103 class ParserTest : public testing::Test {
    104  protected:
    105   ParserTest()
    106     : require_syntax_identifier_(false) {}
    107 
    108   // Set up the parser to parse the given text.
    109   void SetupParser(const char* text) {
    110     raw_input_.reset(new io::ArrayInputStream(text, strlen(text)));
    111     input_.reset(new io::Tokenizer(raw_input_.get(), &error_collector_));
    112     parser_.reset(new Parser());
    113     parser_->RecordErrorsTo(&error_collector_);
    114     parser_->SetRequireSyntaxIdentifier(require_syntax_identifier_);
    115   }
    116 
    117   // Parse the input and expect that the resulting FileDescriptorProto matches
    118   // the given output.  The output is a FileDescriptorProto in protocol buffer
    119   // text format.
    120   void ExpectParsesTo(const char* input, const char* output) {
    121     SetupParser(input);
    122     FileDescriptorProto actual, expected;
    123 
    124     parser_->Parse(input_.get(), &actual);
    125     EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
    126     ASSERT_EQ("", error_collector_.text_);
    127 
    128     // We don't cover SourceCodeInfo in these tests.
    129     actual.clear_source_code_info();
    130 
    131     // Parse the ASCII representation in order to canonicalize it.  We could
    132     // just compare directly to actual.DebugString(), but that would require
    133     // that the caller precisely match the formatting that DebugString()
    134     // produces.
    135     ASSERT_TRUE(TextFormat::ParseFromString(output, &expected));
    136 
    137     // Compare by comparing debug strings.
    138     // TODO(kenton):  Use differencer, once it is available.
    139     EXPECT_EQ(expected.DebugString(), actual.DebugString());
    140   }
    141 
    142   // Parse the text and expect that the given errors are reported.
    143   void ExpectHasErrors(const char* text, const char* expected_errors) {
    144     ExpectHasEarlyExitErrors(text, expected_errors);
    145     EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
    146   }
    147 
    148   // Same as above but does not expect that the parser parses the complete
    149   // input.
    150   void ExpectHasEarlyExitErrors(const char* text, const char* expected_errors) {
    151     SetupParser(text);
    152     FileDescriptorProto file;
    153     parser_->Parse(input_.get(), &file);
    154     EXPECT_EQ(expected_errors, error_collector_.text_);
    155   }
    156 
    157   // Parse the text as a file and validate it (with a DescriptorPool), and
    158   // expect that the validation step reports the given errors.
    159   void ExpectHasValidationErrors(const char* text,
    160                                  const char* expected_errors) {
    161     SetupParser(text);
    162     SourceLocationTable source_locations;
    163     parser_->RecordSourceLocationsTo(&source_locations);
    164 
    165     FileDescriptorProto file;
    166     file.set_name("foo.proto");
    167     parser_->Parse(input_.get(), &file);
    168     EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
    169     ASSERT_EQ("", error_collector_.text_);
    170 
    171     MockValidationErrorCollector validation_error_collector(
    172       source_locations, &error_collector_);
    173     EXPECT_TRUE(pool_.BuildFileCollectingErrors(
    174       file, &validation_error_collector) == NULL);
    175     EXPECT_EQ(expected_errors, error_collector_.text_);
    176   }
    177 
    178   MockErrorCollector error_collector_;
    179   DescriptorPool pool_;
    180 
    181   google::protobuf::scoped_ptr<io::ZeroCopyInputStream> raw_input_;
    182   google::protobuf::scoped_ptr<io::Tokenizer> input_;
    183   google::protobuf::scoped_ptr<Parser> parser_;
    184   bool require_syntax_identifier_;
    185 };
    186 
    187 // ===================================================================
    188 
    189 TEST_F(ParserTest, StopAfterSyntaxIdentifier) {
    190   SetupParser(
    191     "// blah\n"
    192     "syntax = \"foobar\";\n"
    193     "this line will not be parsed\n");
    194   parser_->SetStopAfterSyntaxIdentifier(true);
    195   EXPECT_TRUE(parser_->Parse(input_.get(), NULL));
    196   EXPECT_EQ("", error_collector_.text_);
    197   EXPECT_EQ("foobar", parser_->GetSyntaxIdentifier());
    198 }
    199 
    200 TEST_F(ParserTest, StopAfterOmittedSyntaxIdentifier) {
    201   SetupParser(
    202     "// blah\n"
    203     "this line will not be parsed\n");
    204   parser_->SetStopAfterSyntaxIdentifier(true);
    205   EXPECT_TRUE(parser_->Parse(input_.get(), NULL));
    206   EXPECT_EQ("", error_collector_.text_);
    207   EXPECT_EQ("", parser_->GetSyntaxIdentifier());
    208 }
    209 
    210 TEST_F(ParserTest, StopAfterSyntaxIdentifierWithErrors) {
    211   SetupParser(
    212     "// blah\n"
    213     "syntax = error;\n");
    214   parser_->SetStopAfterSyntaxIdentifier(true);
    215   EXPECT_FALSE(parser_->Parse(input_.get(), NULL));
    216   EXPECT_EQ("1:9: Expected syntax identifier.\n", error_collector_.text_);
    217 }
    218 
    219 TEST_F(ParserTest, WarnIfSyntaxIdentifierOmmitted) {
    220   SetupParser("message A {}");
    221   FileDescriptorProto file;
    222   CaptureTestStderr();
    223   EXPECT_TRUE(parser_->Parse(input_.get(), &file));
    224   EXPECT_TRUE(
    225       GetCapturedTestStderr().find("No syntax specified") != string::npos);
    226 }
    227 
    228 // ===================================================================
    229 
    230 typedef ParserTest ParseMessageTest;
    231 
    232 TEST_F(ParseMessageTest, IgnoreBOM) {
    233   char input[] = "   message TestMessage {\n"
    234       "  required int32 foo = 1;\n"
    235       "}\n";
    236   // Set UTF-8 BOM.
    237   input[0] = (char)0xEF;
    238   input[1] = (char)0xBB;
    239   input[2] = (char)0xBF;
    240   ExpectParsesTo(input,
    241     "message_type {"
    242     "  name: \"TestMessage\""
    243     "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
    244     "}");
    245 }
    246 
    247 TEST_F(ParseMessageTest, BOMError) {
    248   char input[] = "   message TestMessage {\n"
    249       "  required int32 foo = 1;\n"
    250       "}\n";
    251   input[0] = (char)0xEF;
    252   ExpectHasErrors(input,
    253                   "0:1: Proto file starts with 0xEF but not UTF-8 BOM. "
    254                   "Only UTF-8 is accepted for proto file.\n"
    255                   "0:0: Expected top-level statement (e.g. \"message\").\n");
    256 }
    257 
    258 TEST_F(ParseMessageTest, SimpleMessage) {
    259   ExpectParsesTo(
    260     "message TestMessage {\n"
    261     "  required int32 foo = 1;\n"
    262     "}\n",
    263 
    264     "message_type {"
    265     "  name: \"TestMessage\""
    266     "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
    267     "}");
    268 }
    269 
    270 TEST_F(ParseMessageTest, ImplicitSyntaxIdentifier) {
    271   require_syntax_identifier_ = false;
    272   ExpectParsesTo(
    273     "message TestMessage {\n"
    274     "  required int32 foo = 1;\n"
    275     "}\n",
    276 
    277     "message_type {"
    278     "  name: \"TestMessage\""
    279     "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
    280     "}");
    281   EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier());
    282 }
    283 
    284 TEST_F(ParseMessageTest, ExplicitSyntaxIdentifier) {
    285   ExpectParsesTo(
    286     "syntax = \"proto2\";\n"
    287     "message TestMessage {\n"
    288     "  required int32 foo = 1;\n"
    289     "}\n",
    290 
    291     "syntax: 'proto2' "
    292     "message_type {"
    293     "  name: \"TestMessage\""
    294     "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
    295     "}");
    296   EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier());
    297 }
    298 
    299 TEST_F(ParseMessageTest, ExplicitRequiredSyntaxIdentifier) {
    300   require_syntax_identifier_ = true;
    301   ExpectParsesTo(
    302     "syntax = \"proto2\";\n"
    303     "message TestMessage {\n"
    304     "  required int32 foo = 1;\n"
    305     "}\n",
    306 
    307     "syntax: 'proto2' "
    308     "message_type {"
    309     "  name: \"TestMessage\""
    310     "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
    311     "}");
    312   EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier());
    313 }
    314 
    315 TEST_F(ParseMessageTest, SimpleFields) {
    316   ExpectParsesTo(
    317     "message TestMessage {\n"
    318     "  required int32 foo = 15;\n"
    319     "  optional int32 bar = 34;\n"
    320     "  repeated int32 baz = 3;\n"
    321     "}\n",
    322 
    323     "message_type {"
    324     "  name: \"TestMessage\""
    325     "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:15 }"
    326     "  field { name:\"bar\" label:LABEL_OPTIONAL type:TYPE_INT32 number:34 }"
    327     "  field { name:\"baz\" label:LABEL_REPEATED type:TYPE_INT32 number:3  }"
    328     "}");
    329 }
    330 
    331 TEST_F(ParseMessageTest, PrimitiveFieldTypes) {
    332   ExpectParsesTo(
    333     "message TestMessage {\n"
    334     "  required int32    foo = 1;\n"
    335     "  required int64    foo = 1;\n"
    336     "  required uint32   foo = 1;\n"
    337     "  required uint64   foo = 1;\n"
    338     "  required sint32   foo = 1;\n"
    339     "  required sint64   foo = 1;\n"
    340     "  required fixed32  foo = 1;\n"
    341     "  required fixed64  foo = 1;\n"
    342     "  required sfixed32 foo = 1;\n"
    343     "  required sfixed64 foo = 1;\n"
    344     "  required float    foo = 1;\n"
    345     "  required double   foo = 1;\n"
    346     "  required string   foo = 1;\n"
    347     "  required bytes    foo = 1;\n"
    348     "  required bool     foo = 1;\n"
    349     "}\n",
    350 
    351     "message_type {"
    352     "  name: \"TestMessage\""
    353     "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32    number:1 }"
    354     "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT64    number:1 }"
    355     "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_UINT32   number:1 }"
    356     "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_UINT64   number:1 }"
    357     "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SINT32   number:1 }"
    358     "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SINT64   number:1 }"
    359     "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_FIXED32  number:1 }"
    360     "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_FIXED64  number:1 }"
    361     "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SFIXED32 number:1 }"
    362     "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SFIXED64 number:1 }"
    363     "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_FLOAT    number:1 }"
    364     "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_DOUBLE   number:1 }"
    365     "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_STRING   number:1 }"
    366     "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_BYTES    number:1 }"
    367     "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_BOOL     number:1 }"
    368     "}");
    369 }
    370 
    371 TEST_F(ParseMessageTest, FieldDefaults) {
    372   ExpectParsesTo(
    373     "message TestMessage {\n"
    374     "  required int32  foo = 1 [default=  1  ];\n"
    375     "  required int32  foo = 1 [default= -2  ];\n"
    376     "  required int64  foo = 1 [default=  3  ];\n"
    377     "  required int64  foo = 1 [default= -4  ];\n"
    378     "  required uint32 foo = 1 [default=  5  ];\n"
    379     "  required uint64 foo = 1 [default=  6  ];\n"
    380     "  required float  foo = 1 [default=  7.5];\n"
    381     "  required float  foo = 1 [default= -8.5];\n"
    382     "  required float  foo = 1 [default=  9  ];\n"
    383     "  required double foo = 1 [default= 10.5];\n"
    384     "  required double foo = 1 [default=-11.5];\n"
    385     "  required double foo = 1 [default= 12  ];\n"
    386     "  required double foo = 1 [default= inf ];\n"
    387     "  required double foo = 1 [default=-inf ];\n"
    388     "  required double foo = 1 [default= nan ];\n"
    389     "  required string foo = 1 [default='13\\001'];\n"
    390     "  required string foo = 1 [default='a' \"b\" \n \"c\"];\n"
    391     "  required bytes  foo = 1 [default='14\\002'];\n"
    392     "  required bytes  foo = 1 [default='a' \"b\" \n 'c'];\n"
    393     "  required bool   foo = 1 [default=true ];\n"
    394     "  required Foo    foo = 1 [default=FOO  ];\n"
    395 
    396     "  required int32  foo = 1 [default= 0x7FFFFFFF];\n"
    397     "  required int32  foo = 1 [default=-0x80000000];\n"
    398     "  required uint32 foo = 1 [default= 0xFFFFFFFF];\n"
    399     "  required int64  foo = 1 [default= 0x7FFFFFFFFFFFFFFF];\n"
    400     "  required int64  foo = 1 [default=-0x8000000000000000];\n"
    401     "  required uint64 foo = 1 [default= 0xFFFFFFFFFFFFFFFF];\n"
    402     "  required double foo = 1 [default= 0xabcd];\n"
    403     "}\n",
    404 
    405 #define ETC "name:\"foo\" label:LABEL_REQUIRED number:1"
    406     "message_type {"
    407     "  name: \"TestMessage\""
    408     "  field { type:TYPE_INT32   default_value:\"1\"         " ETC " }"
    409     "  field { type:TYPE_INT32   default_value:\"-2\"        " ETC " }"
    410     "  field { type:TYPE_INT64   default_value:\"3\"         " ETC " }"
    411     "  field { type:TYPE_INT64   default_value:\"-4\"        " ETC " }"
    412     "  field { type:TYPE_UINT32  default_value:\"5\"         " ETC " }"
    413     "  field { type:TYPE_UINT64  default_value:\"6\"         " ETC " }"
    414     "  field { type:TYPE_FLOAT   default_value:\"7.5\"       " ETC " }"
    415     "  field { type:TYPE_FLOAT   default_value:\"-8.5\"      " ETC " }"
    416     "  field { type:TYPE_FLOAT   default_value:\"9\"         " ETC " }"
    417     "  field { type:TYPE_DOUBLE  default_value:\"10.5\"      " ETC " }"
    418     "  field { type:TYPE_DOUBLE  default_value:\"-11.5\"     " ETC " }"
    419     "  field { type:TYPE_DOUBLE  default_value:\"12\"        " ETC " }"
    420     "  field { type:TYPE_DOUBLE  default_value:\"inf\"       " ETC " }"
    421     "  field { type:TYPE_DOUBLE  default_value:\"-inf\"      " ETC " }"
    422     "  field { type:TYPE_DOUBLE  default_value:\"nan\"       " ETC " }"
    423     "  field { type:TYPE_STRING  default_value:\"13\\001\"   " ETC " }"
    424     "  field { type:TYPE_STRING  default_value:\"abc\"       " ETC " }"
    425     "  field { type:TYPE_BYTES   default_value:\"14\\\\002\" " ETC " }"
    426     "  field { type:TYPE_BYTES   default_value:\"abc\"       " ETC " }"
    427     "  field { type:TYPE_BOOL    default_value:\"true\"      " ETC " }"
    428     "  field { type_name:\"Foo\" default_value:\"FOO\"       " ETC " }"
    429 
    430     "  field {"
    431     "    type:TYPE_INT32   default_value:\"2147483647\"           " ETC
    432     "  }"
    433     "  field {"
    434     "    type:TYPE_INT32   default_value:\"-2147483648\"          " ETC
    435     "  }"
    436     "  field {"
    437     "    type:TYPE_UINT32  default_value:\"4294967295\"           " ETC
    438     "  }"
    439     "  field {"
    440     "    type:TYPE_INT64   default_value:\"9223372036854775807\"  " ETC
    441     "  }"
    442     "  field {"
    443     "    type:TYPE_INT64   default_value:\"-9223372036854775808\" " ETC
    444     "  }"
    445     "  field {"
    446     "    type:TYPE_UINT64  default_value:\"18446744073709551615\" " ETC
    447     "  }"
    448     "  field {"
    449     "    type:TYPE_DOUBLE  default_value:\"43981\"                " ETC
    450     "  }"
    451     "}");
    452 #undef ETC
    453 }
    454 
    455 TEST_F(ParseMessageTest, FieldJsonName) {
    456   ExpectParsesTo(
    457     "message TestMessage {\n"
    458     "  optional string foo = 1 [json_name = \"@type\"];\n"
    459     "}\n",
    460     "message_type {"
    461     "  name: \"TestMessage\""
    462     "  field {\n"
    463     "    name: \"foo\" label: LABEL_OPTIONAL type: TYPE_STRING number: 1"
    464     "    json_name: \"@type\"\n"
    465     "  }\n"
    466     "}\n");
    467 }
    468 
    469 TEST_F(ParseMessageTest, FieldOptions) {
    470   ExpectParsesTo(
    471     "message TestMessage {\n"
    472     "  optional string foo = 1\n"
    473     "      [ctype=CORD, (foo)=7, foo.(.bar.baz).qux.quux.(corge)=-33, \n"
    474     "       (quux)=\"x\040y\", (baz.qux)=hey];\n"
    475     "}\n",
    476 
    477     "message_type {"
    478     "  name: \"TestMessage\""
    479     "  field { name: \"foo\" label: LABEL_OPTIONAL type: TYPE_STRING number: 1"
    480     "          options { uninterpreted_option: { name { name_part: \"ctype\" "
    481     "                                                   is_extension: false } "
    482     "                                            identifier_value: \"CORD\"  }"
    483     "                    uninterpreted_option: { name { name_part: \"foo\" "
    484     "                                                   is_extension: true } "
    485     "                                            positive_int_value: 7  }"
    486     "                    uninterpreted_option: { name { name_part: \"foo\" "
    487     "                                                   is_extension: false } "
    488     "                                            name { name_part: \".bar.baz\""
    489     "                                                   is_extension: true } "
    490     "                                            name { name_part: \"qux\" "
    491     "                                                   is_extension: false } "
    492     "                                            name { name_part: \"quux\" "
    493     "                                                   is_extension: false } "
    494     "                                            name { name_part: \"corge\" "
    495     "                                                   is_extension: true } "
    496     "                                            negative_int_value: -33 }"
    497     "                    uninterpreted_option: { name { name_part: \"quux\" "
    498     "                                                   is_extension: true } "
    499     "                                            string_value: \"x y\" }"
    500     "                    uninterpreted_option: { name { name_part: \"baz.qux\" "
    501     "                                                   is_extension: true } "
    502     "                                            identifier_value: \"hey\" }"
    503     "          }"
    504     "  }"
    505     "}");
    506 }
    507 
    508 TEST_F(ParseMessageTest, Oneof) {
    509   ExpectParsesTo(
    510     "message TestMessage {\n"
    511     "  oneof foo {\n"
    512     "    int32 a = 1;\n"
    513     "    string b = 2;\n"
    514     "    TestMessage c = 3;\n"
    515     "    group D = 4 { optional int32 i = 5; }\n"
    516     "  }\n"
    517     "}\n",
    518 
    519     "message_type {"
    520     "  name: \"TestMessage\""
    521     "  field { name:\"a\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 "
    522     "          oneof_index:0 }"
    523     "  field { name:\"b\" label:LABEL_OPTIONAL type:TYPE_STRING number:2 "
    524     "          oneof_index:0 }"
    525     "  field { name:\"c\" label:LABEL_OPTIONAL type_name:\"TestMessage\" "
    526     "          number:3 oneof_index:0 }"
    527     "  field { name:\"d\" label:LABEL_OPTIONAL type:TYPE_GROUP "
    528     "          type_name:\"D\" number:4 oneof_index:0 }"
    529     "  oneof_decl {"
    530     "    name: \"foo\""
    531     "  }"
    532     "  nested_type {"
    533     "    name: \"D\""
    534     "    field { name:\"i\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 }"
    535     "  }"
    536     "}");
    537 }
    538 
    539 TEST_F(ParseMessageTest, MultipleOneofs) {
    540   ExpectParsesTo(
    541     "message TestMessage {\n"
    542     "  oneof foo {\n"
    543     "    int32 a = 1;\n"
    544     "    string b = 2;\n"
    545     "  }\n"
    546     "  oneof bar {\n"
    547     "    int32 c = 3;\n"
    548     "    string d = 4;\n"
    549     "  }\n"
    550     "}\n",
    551 
    552     "message_type {"
    553     "  name: \"TestMessage\""
    554     "  field { name:\"a\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 "
    555     "          oneof_index:0 }"
    556     "  field { name:\"b\" label:LABEL_OPTIONAL type:TYPE_STRING number:2 "
    557     "          oneof_index:0 }"
    558     "  field { name:\"c\" label:LABEL_OPTIONAL type:TYPE_INT32 number:3 "
    559     "          oneof_index:1 }"
    560     "  field { name:\"d\" label:LABEL_OPTIONAL type:TYPE_STRING number:4 "
    561     "          oneof_index:1 }"
    562     "  oneof_decl {"
    563     "    name: \"foo\""
    564     "  }"
    565     "  oneof_decl {"
    566     "    name: \"bar\""
    567     "  }"
    568     "}");
    569 }
    570 
    571 TEST_F(ParseMessageTest, Maps) {
    572   ExpectParsesTo(
    573     "message TestMessage {\n"
    574     "  map<int32, string> primitive_type_map = 1;\n"
    575     "  map<KeyType, ValueType> composite_type_map = 2;\n"
    576     "}\n",
    577 
    578     "message_type {"
    579     "  name: \"TestMessage\""
    580     "  nested_type {"
    581     "    name: \"PrimitiveTypeMapEntry\""
    582     "    field { "
    583     "       name: \"key\" number: 1 label:LABEL_OPTIONAL"
    584     "       type:TYPE_INT32"
    585     "    }"
    586     "    field { "
    587     "       name: \"value\" number: 2 label:LABEL_OPTIONAL"
    588     "       type:TYPE_STRING"
    589     "    }"
    590     "    options { map_entry: true }"
    591     "  }"
    592     "  nested_type {"
    593     "    name: \"CompositeTypeMapEntry\""
    594     "    field { "
    595     "       name: \"key\" number: 1 label:LABEL_OPTIONAL"
    596     "       type_name: \"KeyType\""
    597     "    }"
    598     "    field { "
    599     "       name: \"value\" number: 2 label:LABEL_OPTIONAL"
    600     "       type_name: \"ValueType\""
    601     "    }"
    602     "    options { map_entry: true }"
    603     "  }"
    604     "  field {"
    605     "    name: \"primitive_type_map\""
    606     "    label: LABEL_REPEATED"
    607     "    type_name: \"PrimitiveTypeMapEntry\""
    608     "    number: 1"
    609     "  }"
    610     "  field {"
    611     "    name: \"composite_type_map\""
    612     "    label: LABEL_REPEATED"
    613     "    type_name: \"CompositeTypeMapEntry\""
    614     "    number: 2"
    615     "  }"
    616     "}");
    617 }
    618 
    619 TEST_F(ParseMessageTest, Group) {
    620   ExpectParsesTo(
    621     "message TestMessage {\n"
    622     "  optional group TestGroup = 1 {};\n"
    623     "}\n",
    624 
    625     "message_type {"
    626     "  name: \"TestMessage\""
    627     "  nested_type { name: \"TestGroup\" }"
    628     "  field { name:\"testgroup\" label:LABEL_OPTIONAL number:1"
    629     "          type:TYPE_GROUP type_name: \"TestGroup\" }"
    630     "}");
    631 }
    632 
    633 TEST_F(ParseMessageTest, NestedMessage) {
    634   ExpectParsesTo(
    635     "message TestMessage {\n"
    636     "  message Nested {}\n"
    637     "  optional Nested test_nested = 1;\n"
    638     "}\n",
    639 
    640     "message_type {"
    641     "  name: \"TestMessage\""
    642     "  nested_type { name: \"Nested\" }"
    643     "  field { name:\"test_nested\" label:LABEL_OPTIONAL number:1"
    644     "          type_name: \"Nested\" }"
    645     "}");
    646 }
    647 
    648 TEST_F(ParseMessageTest, NestedEnum) {
    649   ExpectParsesTo(
    650     "message TestMessage {\n"
    651     "  enum NestedEnum {}\n"
    652     "  optional NestedEnum test_enum = 1;\n"
    653     "}\n",
    654 
    655     "message_type {"
    656     "  name: \"TestMessage\""
    657     "  enum_type { name: \"NestedEnum\" }"
    658     "  field { name:\"test_enum\" label:LABEL_OPTIONAL number:1"
    659     "          type_name: \"NestedEnum\" }"
    660     "}");
    661 }
    662 
    663 TEST_F(ParseMessageTest, ReservedRange) {
    664   ExpectParsesTo(
    665     "message TestMessage {\n"
    666     "  required int32 foo = 1;\n"
    667     "  reserved 2, 15, 9 to 11, 3;\n"
    668     "}\n",
    669 
    670     "message_type {"
    671     "  name: \"TestMessage\""
    672     "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
    673     "  reserved_range { start:2   end:3         }"
    674     "  reserved_range { start:15  end:16        }"
    675     "  reserved_range { start:9   end:12        }"
    676     "  reserved_range { start:3   end:4         }"
    677     "}");
    678 }
    679 
    680 TEST_F(ParseMessageTest, ReservedNames) {
    681   ExpectParsesTo(
    682     "message TestMessage {\n"
    683     "  reserved \"foo\", \"bar\";\n"
    684     "}\n",
    685 
    686     "message_type {"
    687     "  name: \"TestMessage\""
    688     "  reserved_name: \"foo\""
    689     "  reserved_name: \"bar\""
    690     "}");
    691 }
    692 
    693 TEST_F(ParseMessageTest, ExtensionRange) {
    694   ExpectParsesTo(
    695     "message TestMessage {\n"
    696     "  extensions 10 to 19;\n"
    697     "  extensions 30 to max;\n"
    698     "}\n",
    699 
    700     "message_type {"
    701     "  name: \"TestMessage\""
    702     "  extension_range { start:10 end:20        }"
    703     "  extension_range { start:30 end:536870912 }"
    704     "}");
    705 }
    706 
    707 TEST_F(ParseMessageTest, CompoundExtensionRange) {
    708   ExpectParsesTo(
    709     "message TestMessage {\n"
    710     "  extensions 2, 15, 9 to 11, 100 to max, 3;\n"
    711     "}\n",
    712 
    713     "message_type {"
    714     "  name: \"TestMessage\""
    715     "  extension_range { start:2   end:3         }"
    716     "  extension_range { start:15  end:16        }"
    717     "  extension_range { start:9   end:12        }"
    718     "  extension_range { start:100 end:536870912 }"
    719     "  extension_range { start:3   end:4         }"
    720     "}");
    721 }
    722 
    723 TEST_F(ParseMessageTest, LargerMaxForMessageSetWireFormatMessages) {
    724   // Messages using the message_set_wire_format option can accept larger
    725   // extension numbers, as the numbers are not encoded as int32 field values
    726   // rather than tags.
    727   ExpectParsesTo(
    728     "message TestMessage {\n"
    729     "  extensions 4 to max;\n"
    730     "  option message_set_wire_format = true;\n"
    731     "}\n",
    732 
    733     "message_type {"
    734     "  name: \"TestMessage\""
    735     "    extension_range { start:4 end: 0x7fffffff }"
    736     "  options {\n"
    737     "    uninterpreted_option { \n"
    738     "      name {\n"
    739     "        name_part: \"message_set_wire_format\"\n"
    740     "        is_extension: false\n"
    741     "      }\n"
    742     "      identifier_value: \"true\"\n"
    743     "    }\n"
    744     "  }\n"
    745     "}");
    746 }
    747 
    748 TEST_F(ParseMessageTest, Extensions) {
    749   ExpectParsesTo(
    750     "extend Extendee1 { optional int32 foo = 12; }\n"
    751     "extend Extendee2 { repeated TestMessage bar = 22; }\n",
    752 
    753     "extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:12"
    754     "            extendee: \"Extendee1\" } "
    755     "extension { name:\"bar\" label:LABEL_REPEATED number:22"
    756     "            type_name:\"TestMessage\" extendee: \"Extendee2\" }");
    757 }
    758 
    759 TEST_F(ParseMessageTest, ExtensionsInMessageScope) {
    760   ExpectParsesTo(
    761     "message TestMessage {\n"
    762     "  extend Extendee1 { optional int32 foo = 12; }\n"
    763     "  extend Extendee2 { repeated TestMessage bar = 22; }\n"
    764     "}\n",
    765 
    766     "message_type {"
    767     "  name: \"TestMessage\""
    768     "  extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:12"
    769     "              extendee: \"Extendee1\" }"
    770     "  extension { name:\"bar\" label:LABEL_REPEATED number:22"
    771     "              type_name:\"TestMessage\" extendee: \"Extendee2\" }"
    772     "}");
    773 }
    774 
    775 TEST_F(ParseMessageTest, MultipleExtensionsOneExtendee) {
    776   ExpectParsesTo(
    777     "extend Extendee1 {\n"
    778     "  optional int32 foo = 12;\n"
    779     "  repeated TestMessage bar = 22;\n"
    780     "}\n",
    781 
    782     "extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:12"
    783     "            extendee: \"Extendee1\" } "
    784     "extension { name:\"bar\" label:LABEL_REPEATED number:22"
    785     "            type_name:\"TestMessage\" extendee: \"Extendee1\" }");
    786 }
    787 
    788 TEST_F(ParseMessageTest, OptionalLabelProto3) {
    789   ExpectParsesTo(
    790     "syntax = \"proto3\";\n"
    791     "message TestMessage {\n"
    792     "  int32 foo = 1;\n"
    793     "}\n",
    794 
    795     "syntax: \"proto3\" "
    796     "message_type {"
    797     "  name: \"TestMessage\""
    798     "  field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 } }");
    799 }
    800 
    801 // ===================================================================
    802 
    803 typedef ParserTest ParseEnumTest;
    804 
    805 TEST_F(ParseEnumTest, SimpleEnum) {
    806   ExpectParsesTo(
    807     "enum TestEnum {\n"
    808     "  FOO = 0;\n"
    809     "}\n",
    810 
    811     "enum_type {"
    812     "  name: \"TestEnum\""
    813     "  value { name:\"FOO\" number:0 }"
    814     "}");
    815 }
    816 
    817 TEST_F(ParseEnumTest, Values) {
    818   ExpectParsesTo(
    819     "enum TestEnum {\n"
    820     "  FOO = 13;\n"
    821     "  BAR = -10;\n"
    822     "  BAZ = 500;\n"
    823     "  HEX_MAX = 0x7FFFFFFF;\n"
    824     "  HEX_MIN = -0x80000000;\n"
    825     "  INT_MAX = 2147483647;\n"
    826     "  INT_MIN = -2147483648;\n"
    827     "}\n",
    828 
    829     "enum_type {"
    830     "  name: \"TestEnum\""
    831     "  value { name:\"FOO\" number:13 }"
    832     "  value { name:\"BAR\" number:-10 }"
    833     "  value { name:\"BAZ\" number:500 }"
    834     "  value { name:\"HEX_MAX\" number:2147483647 }"
    835     "  value { name:\"HEX_MIN\" number:-2147483648 }"
    836     "  value { name:\"INT_MAX\" number:2147483647 }"
    837     "  value { name:\"INT_MIN\" number:-2147483648 }"
    838     "}");
    839 }
    840 
    841 TEST_F(ParseEnumTest, ValueOptions) {
    842   ExpectParsesTo(
    843     "enum TestEnum {\n"
    844     "  FOO = 13;\n"
    845     "  BAR = -10 [ (something.text) = 'abc' ];\n"
    846     "  BAZ = 500 [ (something.text) = 'def', other = 1 ];\n"
    847     "}\n",
    848 
    849     "enum_type {"
    850     "  name: \"TestEnum\""
    851     "  value { name: \"FOO\" number: 13 }"
    852     "  value { name: \"BAR\" number: -10 "
    853     "    options { "
    854     "      uninterpreted_option { "
    855     "        name { name_part: \"something.text\" is_extension: true } "
    856     "        string_value: \"abc\" "
    857     "      } "
    858     "    } "
    859     "  } "
    860     "  value { name: \"BAZ\" number: 500 "
    861     "    options { "
    862     "      uninterpreted_option { "
    863     "        name { name_part: \"something.text\" is_extension: true } "
    864     "        string_value: \"def\" "
    865     "      } "
    866     "      uninterpreted_option { "
    867     "        name { name_part: \"other\" is_extension: false } "
    868     "        positive_int_value: 1 "
    869     "      } "
    870     "    } "
    871     "  } "
    872     "}");
    873 }
    874 
    875 // ===================================================================
    876 
    877 typedef ParserTest ParseServiceTest;
    878 
    879 TEST_F(ParseServiceTest, SimpleService) {
    880   ExpectParsesTo(
    881     "service TestService {\n"
    882     "  rpc Foo(In) returns (Out);\n"
    883     "}\n",
    884 
    885     "service {"
    886     "  name: \"TestService\""
    887     "  method { name:\"Foo\" input_type:\"In\" output_type:\"Out\" }"
    888     "}");
    889 }
    890 
    891 TEST_F(ParseServiceTest, MethodsAndStreams) {
    892   ExpectParsesTo(
    893     "service TestService {\n"
    894     "  rpc Foo(In1) returns (Out1);\n"
    895     "  rpc Bar(In2) returns (Out2);\n"
    896     "  rpc Baz(In3) returns (Out3);\n"
    897     "}\n",
    898 
    899     "service {"
    900     "  name: \"TestService\""
    901     "  method { name:\"Foo\" input_type:\"In1\" output_type:\"Out1\" }"
    902     "  method { name:\"Bar\" input_type:\"In2\" output_type:\"Out2\" }"
    903     "  method { name:\"Baz\" input_type:\"In3\" output_type:\"Out3\" }"
    904     "}");
    905 }
    906 
    907 
    908 
    909 // ===================================================================
    910 // imports and packages
    911 
    912 typedef ParserTest ParseMiscTest;
    913 
    914 TEST_F(ParseMiscTest, ParseImport) {
    915   ExpectParsesTo(
    916     "import \"foo/bar/baz.proto\";\n",
    917     "dependency: \"foo/bar/baz.proto\"");
    918 }
    919 
    920 TEST_F(ParseMiscTest, ParseMultipleImports) {
    921   ExpectParsesTo(
    922     "import \"foo.proto\";\n"
    923     "import \"bar.proto\";\n"
    924     "import \"baz.proto\";\n",
    925     "dependency: \"foo.proto\""
    926     "dependency: \"bar.proto\""
    927     "dependency: \"baz.proto\"");
    928 }
    929 
    930 TEST_F(ParseMiscTest, ParsePublicImports) {
    931   ExpectParsesTo(
    932     "import \"foo.proto\";\n"
    933     "import public \"bar.proto\";\n"
    934     "import \"baz.proto\";\n"
    935     "import public \"qux.proto\";\n",
    936     "dependency: \"foo.proto\""
    937     "dependency: \"bar.proto\""
    938     "dependency: \"baz.proto\""
    939     "dependency: \"qux.proto\""
    940     "public_dependency: 1 "
    941     "public_dependency: 3 ");
    942 }
    943 
    944 TEST_F(ParseMiscTest, ParsePackage) {
    945   ExpectParsesTo(
    946     "package foo.bar.baz;\n",
    947     "package: \"foo.bar.baz\"");
    948 }
    949 
    950 TEST_F(ParseMiscTest, ParsePackageWithSpaces) {
    951   ExpectParsesTo(
    952     "package foo   .   bar.  \n"
    953     "  baz;\n",
    954     "package: \"foo.bar.baz\"");
    955 }
    956 
    957 // ===================================================================
    958 // options
    959 
    960 TEST_F(ParseMiscTest, ParseFileOptions) {
    961   ExpectParsesTo(
    962     "option java_package = \"com.google.foo\";\n"
    963     "option optimize_for = CODE_SIZE;",
    964 
    965     "options {"
    966     "uninterpreted_option { name { name_part: \"java_package\" "
    967     "                              is_extension: false }"
    968     "                       string_value: \"com.google.foo\"} "
    969     "uninterpreted_option { name { name_part: \"optimize_for\" "
    970     "                              is_extension: false }"
    971     "                       identifier_value: \"CODE_SIZE\" } "
    972     "}");
    973 }
    974 
    975 // ===================================================================
    976 // Error tests
    977 //
    978 // There are a very large number of possible errors that the parser could
    979 // report, so it's infeasible to test every single one of them.  Instead,
    980 // we test each unique call to AddError() in parser.h.  This does not mean
    981 // we are testing every possible error that Parser can generate because
    982 // each variant of the Consume() helper only counts as one unique call to
    983 // AddError().
    984 
    985 typedef ParserTest ParseErrorTest;
    986 
    987 TEST_F(ParseErrorTest, MissingSyntaxIdentifier) {
    988   require_syntax_identifier_ = true;
    989   ExpectHasEarlyExitErrors("message TestMessage {}",
    990                            "0:0: File must begin with a syntax statement, e.g. "
    991                            "'syntax = \"proto2\";'.\n");
    992   EXPECT_EQ("", parser_->GetSyntaxIdentifier());
    993 }
    994 
    995 TEST_F(ParseErrorTest, UnknownSyntaxIdentifier) {
    996   ExpectHasEarlyExitErrors(
    997     "syntax = \"no_such_syntax\";",
    998     "0:9: Unrecognized syntax identifier \"no_such_syntax\".  This parser "
    999       "only recognizes \"proto2\" and \"proto3\".\n");
   1000   EXPECT_EQ("no_such_syntax", parser_->GetSyntaxIdentifier());
   1001 }
   1002 
   1003 TEST_F(ParseErrorTest, SimpleSyntaxError) {
   1004   ExpectHasErrors(
   1005     "message TestMessage @#$ { blah }",
   1006     "0:20: Expected \"{\".\n");
   1007   EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier());
   1008 }
   1009 
   1010 TEST_F(ParseErrorTest, ExpectedTopLevel) {
   1011   ExpectHasErrors(
   1012     "blah;",
   1013     "0:0: Expected top-level statement (e.g. \"message\").\n");
   1014 }
   1015 
   1016 TEST_F(ParseErrorTest, UnmatchedCloseBrace) {
   1017   // This used to cause an infinite loop.  Doh.
   1018   ExpectHasErrors(
   1019     "}",
   1020     "0:0: Expected top-level statement (e.g. \"message\").\n"
   1021     "0:0: Unmatched \"}\".\n");
   1022 }
   1023 
   1024 // -------------------------------------------------------------------
   1025 // Message errors
   1026 
   1027 TEST_F(ParseErrorTest, MessageMissingName) {
   1028   ExpectHasErrors(
   1029     "message {}",
   1030     "0:8: Expected message name.\n");
   1031 }
   1032 
   1033 TEST_F(ParseErrorTest, MessageMissingBody) {
   1034   ExpectHasErrors(
   1035     "message TestMessage;",
   1036     "0:19: Expected \"{\".\n");
   1037 }
   1038 
   1039 TEST_F(ParseErrorTest, EofInMessage) {
   1040   ExpectHasErrors(
   1041     "message TestMessage {",
   1042     "0:21: Reached end of input in message definition (missing '}').\n");
   1043 }
   1044 
   1045 TEST_F(ParseErrorTest, MissingFieldNumber) {
   1046   ExpectHasErrors(
   1047     "message TestMessage {\n"
   1048     "  optional int32 foo;\n"
   1049     "}\n",
   1050     "1:20: Missing field number.\n");
   1051 }
   1052 
   1053 TEST_F(ParseErrorTest, ExpectedFieldNumber) {
   1054   ExpectHasErrors(
   1055     "message TestMessage {\n"
   1056     "  optional int32 foo = ;\n"
   1057     "}\n",
   1058     "1:23: Expected field number.\n");
   1059 }
   1060 
   1061 TEST_F(ParseErrorTest, FieldNumberOutOfRange) {
   1062   ExpectHasErrors(
   1063     "message TestMessage {\n"
   1064     "  optional int32 foo = 0x100000000;\n"
   1065     "}\n",
   1066     "1:23: Integer out of range.\n");
   1067 }
   1068 
   1069 TEST_F(ParseErrorTest, MissingLabel) {
   1070   ExpectHasErrors(
   1071     "message TestMessage {\n"
   1072     "  int32 foo = 1;\n"
   1073     "}\n",
   1074     "1:2: Expected \"required\", \"optional\", or \"repeated\".\n");
   1075 }
   1076 
   1077 TEST_F(ParseErrorTest, ExpectedOptionName) {
   1078   ExpectHasErrors(
   1079     "message TestMessage {\n"
   1080     "  optional uint32 foo = 1 [];\n"
   1081     "}\n",
   1082     "1:27: Expected identifier.\n");
   1083 }
   1084 
   1085 TEST_F(ParseErrorTest, NonExtensionOptionNameBeginningWithDot) {
   1086   ExpectHasErrors(
   1087     "message TestMessage {\n"
   1088     "  optional uint32 foo = 1 [.foo=1];\n"
   1089     "}\n",
   1090     "1:27: Expected identifier.\n");
   1091 }
   1092 
   1093 TEST_F(ParseErrorTest, DefaultValueTypeMismatch) {
   1094   ExpectHasErrors(
   1095     "message TestMessage {\n"
   1096     "  optional uint32 foo = 1 [default=true];\n"
   1097     "}\n",
   1098     "1:35: Expected integer for field default value.\n");
   1099 }
   1100 
   1101 TEST_F(ParseErrorTest, DefaultValueNotBoolean) {
   1102   ExpectHasErrors(
   1103     "message TestMessage {\n"
   1104     "  optional bool foo = 1 [default=blah];\n"
   1105     "}\n",
   1106     "1:33: Expected \"true\" or \"false\".\n");
   1107 }
   1108 
   1109 TEST_F(ParseErrorTest, DefaultValueNotString) {
   1110   ExpectHasErrors(
   1111     "message TestMessage {\n"
   1112     "  optional string foo = 1 [default=1];\n"
   1113     "}\n",
   1114     "1:35: Expected string for field default value.\n");
   1115 }
   1116 
   1117 TEST_F(ParseErrorTest, DefaultValueUnsignedNegative) {
   1118   ExpectHasErrors(
   1119     "message TestMessage {\n"
   1120     "  optional uint32 foo = 1 [default=-1];\n"
   1121     "}\n",
   1122     "1:36: Unsigned field can't have negative default value.\n");
   1123 }
   1124 
   1125 TEST_F(ParseErrorTest, DefaultValueTooLarge) {
   1126   ExpectHasErrors(
   1127     "message TestMessage {\n"
   1128     "  optional int32  foo = 1 [default= 0x80000000];\n"
   1129     "  optional int32  foo = 1 [default=-0x80000001];\n"
   1130     "  optional uint32 foo = 1 [default= 0x100000000];\n"
   1131     "  optional int64  foo = 1 [default= 0x80000000000000000];\n"
   1132     "  optional int64  foo = 1 [default=-0x80000000000000001];\n"
   1133     "  optional uint64 foo = 1 [default= 0x100000000000000000];\n"
   1134     "}\n",
   1135     "1:36: Integer out of range.\n"
   1136     "2:36: Integer out of range.\n"
   1137     "3:36: Integer out of range.\n"
   1138     "4:36: Integer out of range.\n"
   1139     "5:36: Integer out of range.\n"
   1140     "6:36: Integer out of range.\n");
   1141 }
   1142 
   1143 TEST_F(ParseErrorTest, JsonNameNotString) {
   1144   ExpectHasErrors(
   1145     "message TestMessage {\n"
   1146     "  optional string foo = 1 [json_name=1];\n"
   1147     "}\n",
   1148     "1:37: Expected string for JSON name.\n");
   1149 }
   1150 
   1151 TEST_F(ParseErrorTest, DuplicateJsonName) {
   1152   ExpectHasErrors(
   1153     "message TestMessage {\n"
   1154     "  optional uint32 foo = 1 [json_name=\"a\",json_name=\"b\"];\n"
   1155     "}\n",
   1156     "1:41: Already set option \"json_name\".\n");
   1157 }
   1158 
   1159 TEST_F(ParseErrorTest, EnumValueOutOfRange) {
   1160   ExpectHasErrors(
   1161     "enum TestEnum {\n"
   1162     "  HEX_TOO_BIG   =  0x80000000;\n"
   1163     "  HEX_TOO_SMALL = -0x80000001;\n"
   1164     "  INT_TOO_BIG   =  2147483648;\n"
   1165     "  INT_TOO_SMALL = -2147483649;\n"
   1166     "}\n",
   1167     "1:19: Integer out of range.\n"
   1168     "2:19: Integer out of range.\n"
   1169     "3:19: Integer out of range.\n"
   1170     "4:19: Integer out of range.\n");
   1171 }
   1172 
   1173 TEST_F(ParseErrorTest, EnumAllowAliasFalse) {
   1174   ExpectHasErrors(
   1175     "enum Foo {\n"
   1176     "  option allow_alias = false;\n"
   1177     "  BAR = 1;\n"
   1178     "  BAZ = 2;\n"
   1179     "}\n",
   1180     "5:0: \"Foo\" declares 'option allow_alias = false;' which has no effect. "
   1181     "Please remove the declaration.\n");
   1182 }
   1183 
   1184 TEST_F(ParseErrorTest, UnnecessaryEnumAllowAlias) {
   1185   ExpectHasErrors(
   1186     "enum Foo {\n"
   1187     "  option allow_alias = true;\n"
   1188     "  BAR = 1;\n"
   1189     "  BAZ = 2;\n"
   1190     "}\n",
   1191     "5:0: \"Foo\" declares support for enum aliases but no enum values share "
   1192     "field numbers. Please remove the unnecessary 'option allow_alias = true;' "
   1193     "declaration.\n");
   1194 }
   1195 
   1196 TEST_F(ParseErrorTest, DefaultValueMissing) {
   1197   ExpectHasErrors(
   1198     "message TestMessage {\n"
   1199     "  optional uint32 foo = 1 [default=];\n"
   1200     "}\n",
   1201     "1:35: Expected integer for field default value.\n");
   1202 }
   1203 
   1204 TEST_F(ParseErrorTest, DefaultValueForGroup) {
   1205   ExpectHasErrors(
   1206     "message TestMessage {\n"
   1207     "  optional group Foo = 1 [default=blah] {}\n"
   1208     "}\n",
   1209     "1:34: Messages can't have default values.\n");
   1210 }
   1211 
   1212 TEST_F(ParseErrorTest, DuplicateDefaultValue) {
   1213   ExpectHasErrors(
   1214     "message TestMessage {\n"
   1215     "  optional uint32 foo = 1 [default=1,default=2];\n"
   1216     "}\n",
   1217     "1:37: Already set option \"default\".\n");
   1218 }
   1219 
   1220 TEST_F(ParseErrorTest, MissingOneofName) {
   1221   ExpectHasErrors(
   1222     "message TestMessage {\n"
   1223     "  oneof {\n"
   1224     "    int32 bar = 1;\n"
   1225     "  }\n"
   1226     "}\n",
   1227     "1:8: Expected oneof name.\n");
   1228 }
   1229 
   1230 TEST_F(ParseErrorTest, LabelInOneof) {
   1231   ExpectHasErrors(
   1232     "message TestMessage {\n"
   1233     "  oneof foo {\n"
   1234     "    optional int32 bar = 1;\n"
   1235     "  }\n"
   1236     "}\n",
   1237     "2:4: Fields in oneofs must not have labels (required / optional "
   1238       "/ repeated).\n");
   1239 }
   1240 
   1241 TEST_F(ParseErrorTest, MapInOneof) {
   1242   ExpectHasErrors(
   1243     "message TestMessage {\n"
   1244     "  oneof foo {\n"
   1245     "    map<int32, int32> foo_map = 1;\n"
   1246     "    map message_field = 2;\n"  // a normal message field is OK
   1247     "  }\n"
   1248     "}\n",
   1249     "2:7: Map fields are not allowed in oneofs.\n");
   1250 }
   1251 
   1252 TEST_F(ParseErrorTest, LabelForMap) {
   1253   ExpectHasErrors(
   1254     "message TestMessage {\n"
   1255     "  optional map<int32, int32> int_map = 1;\n"
   1256     "  required map<int32, int32> int_map2 = 2;\n"
   1257     "  repeated map<int32, int32> int_map3 = 3;\n"
   1258     "  optional map map_message = 4;\n"  // a normal message field is OK
   1259     "}\n",
   1260     "1:14: Field labels (required/optional/repeated) are not allowed on map "
   1261     "fields.\n"
   1262     "2:14: Field labels (required/optional/repeated) are not allowed on map "
   1263     "fields.\n"
   1264     "3:14: Field labels (required/optional/repeated) are not allowed on map "
   1265     "fields.\n");
   1266 }
   1267 
   1268 TEST_F(ParseErrorTest, MalformedMaps) {
   1269   ExpectHasErrors(
   1270     "message TestMessage {\n"
   1271     "  map map_message = 1;\n"   // a normal message field lacking label
   1272     "  map<string> str_map = 2;\n"
   1273     "  map<string,> str_map2 = 3;\n"
   1274     "  map<,string> str_map3 = 4;\n"
   1275     "  map<> empty_map = 5;\n"
   1276     "  map<string,string str_map6 = 6;\n"
   1277     "}"
   1278     "extend SomeMessage {\n"
   1279     "  map<int32, int32> int_map = 1;\n"
   1280     "}",
   1281     "1:6: Expected \"required\", \"optional\", or \"repeated\".\n"
   1282     "2:12: Expected \",\".\n"
   1283     "3:13: Expected type name.\n"
   1284     "4:6: Expected type name.\n"
   1285     "5:6: Expected type name.\n"
   1286     "6:20: Expected \">\".\n"
   1287     "8:5: Map fields are not allowed to be extensions.\n");
   1288 }
   1289 
   1290 TEST_F(ParseErrorTest, GroupNotCapitalized) {
   1291   ExpectHasErrors(
   1292     "message TestMessage {\n"
   1293     "  optional group foo = 1 {}\n"
   1294     "}\n",
   1295     "1:17: Group names must start with a capital letter.\n");
   1296 }
   1297 
   1298 TEST_F(ParseErrorTest, GroupMissingBody) {
   1299   ExpectHasErrors(
   1300     "message TestMessage {\n"
   1301     "  optional group Foo = 1;\n"
   1302     "}\n",
   1303     "1:24: Missing group body.\n");
   1304 }
   1305 
   1306 TEST_F(ParseErrorTest, ExtendingPrimitive) {
   1307   ExpectHasErrors(
   1308     "extend int32 { optional string foo = 4; }\n",
   1309     "0:7: Expected message type.\n");
   1310 }
   1311 
   1312 TEST_F(ParseErrorTest, ErrorInExtension) {
   1313   ExpectHasErrors(
   1314     "message Foo { extensions 100 to 199; }\n"
   1315     "extend Foo { optional string foo; }\n",
   1316     "1:32: Missing field number.\n");
   1317 }
   1318 
   1319 TEST_F(ParseErrorTest, MultipleParseErrors) {
   1320   // When a statement has a parse error, the parser should be able to continue
   1321   // parsing at the next statement.
   1322   ExpectHasErrors(
   1323     "message TestMessage {\n"
   1324     "  optional int32 foo;\n"
   1325     "  !invalid statement ending in a block { blah blah { blah } blah }\n"
   1326     "  optional int32 bar = 3 {}\n"
   1327     "}\n",
   1328     "1:20: Missing field number.\n"
   1329     "2:2: Expected \"required\", \"optional\", or \"repeated\".\n"
   1330     "2:2: Expected type name.\n"
   1331     "3:25: Expected \";\".\n");
   1332 }
   1333 
   1334 TEST_F(ParseErrorTest, EofInAggregateValue) {
   1335   ExpectHasErrors(
   1336       "option (fileopt) = { i:100\n",
   1337       "1:0: Unexpected end of stream while parsing aggregate value.\n");
   1338 }
   1339 
   1340 TEST_F(ParseErrorTest, ExplicitOptionalLabelProto3) {
   1341   ExpectHasErrors(
   1342       "syntax = 'proto3';\n"
   1343       "message TestMessage {\n"
   1344       "  optional int32 foo = 1;\n"
   1345       "}\n",
   1346       "2:11: Explicit 'optional' labels are disallowed in the Proto3 syntax. "
   1347       "To define 'optional' fields in Proto3, simply remove the 'optional' "
   1348       "label, as fields are 'optional' by default.\n");
   1349 }
   1350 
   1351 
   1352 // -------------------------------------------------------------------
   1353 // Enum errors
   1354 
   1355 TEST_F(ParseErrorTest, EofInEnum) {
   1356   ExpectHasErrors(
   1357     "enum TestEnum {",
   1358     "0:15: Reached end of input in enum definition (missing '}').\n");
   1359 }
   1360 
   1361 TEST_F(ParseErrorTest, EnumValueMissingNumber) {
   1362   ExpectHasErrors(
   1363     "enum TestEnum {\n"
   1364     "  FOO;\n"
   1365     "}\n",
   1366     "1:5: Missing numeric value for enum constant.\n");
   1367 }
   1368 
   1369 // -------------------------------------------------------------------
   1370 // Reserved field number errors
   1371 
   1372 TEST_F(ParseErrorTest, ReservedMaxNotAllowed) {
   1373   ExpectHasErrors(
   1374     "message Foo {\n"
   1375     "  reserved 10 to max;\n"
   1376     "}\n",
   1377     "1:17: Expected integer.\n");
   1378 }
   1379 
   1380 TEST_F(ParseErrorTest, ReservedMixNameAndNumber) {
   1381   ExpectHasErrors(
   1382     "message Foo {\n"
   1383     "  reserved 10, \"foo\";\n"
   1384     "}\n",
   1385     "1:15: Expected field number range.\n");
   1386 }
   1387 
   1388 TEST_F(ParseErrorTest, ReservedMissingQuotes) {
   1389   ExpectHasErrors(
   1390     "message Foo {\n"
   1391     "  reserved foo;\n"
   1392     "}\n",
   1393     "1:11: Expected field name or number range.\n");
   1394 }
   1395 
   1396 // -------------------------------------------------------------------
   1397 // Service errors
   1398 
   1399 TEST_F(ParseErrorTest, EofInService) {
   1400   ExpectHasErrors(
   1401     "service TestService {",
   1402     "0:21: Reached end of input in service definition (missing '}').\n");
   1403 }
   1404 
   1405 TEST_F(ParseErrorTest, ServiceMethodPrimitiveParams) {
   1406   ExpectHasErrors(
   1407     "service TestService {\n"
   1408     "  rpc Foo(int32) returns (string);\n"
   1409     "}\n",
   1410     "1:10: Expected message type.\n"
   1411     "1:26: Expected message type.\n");
   1412 }
   1413 
   1414 
   1415 TEST_F(ParseErrorTest, EofInMethodOptions) {
   1416   ExpectHasErrors(
   1417     "service TestService {\n"
   1418     "  rpc Foo(Bar) returns(Bar) {",
   1419     "1:29: Reached end of input in method options (missing '}').\n"
   1420     "1:29: Reached end of input in service definition (missing '}').\n");
   1421 }
   1422 
   1423 
   1424 TEST_F(ParseErrorTest, PrimitiveMethodInput) {
   1425   ExpectHasErrors(
   1426     "service TestService {\n"
   1427     "  rpc Foo(int32) returns(Bar);\n"
   1428     "}\n",
   1429     "1:10: Expected message type.\n");
   1430 }
   1431 
   1432 
   1433 TEST_F(ParseErrorTest, MethodOptionTypeError) {
   1434   // This used to cause an infinite loop.
   1435   ExpectHasErrors(
   1436     "message Baz {}\n"
   1437     "service Foo {\n"
   1438     "  rpc Bar(Baz) returns(Baz) { option invalid syntax; }\n"
   1439     "}\n",
   1440     "2:45: Expected \"=\".\n");
   1441 }
   1442 
   1443 
   1444 // -------------------------------------------------------------------
   1445 // Import and package errors
   1446 
   1447 TEST_F(ParseErrorTest, ImportNotQuoted) {
   1448   ExpectHasErrors(
   1449     "import foo;\n",
   1450     "0:7: Expected a string naming the file to import.\n");
   1451 }
   1452 
   1453 TEST_F(ParseErrorTest, MultiplePackagesInFile) {
   1454   ExpectHasErrors(
   1455     "package foo;\n"
   1456     "package bar;\n",
   1457     "1:0: Multiple package definitions.\n");
   1458 }
   1459 
   1460 // ===================================================================
   1461 // Test that errors detected by DescriptorPool correctly report line and
   1462 // column numbers.  We have one test for every call to RecordLocation() in
   1463 // parser.cc.
   1464 
   1465 typedef ParserTest ParserValidationErrorTest;
   1466 
   1467 TEST_F(ParserValidationErrorTest, PackageNameError) {
   1468   // Create another file which defines symbol "foo".
   1469   FileDescriptorProto other_file;
   1470   other_file.set_name("bar.proto");
   1471   other_file.add_message_type()->set_name("foo");
   1472   EXPECT_TRUE(pool_.BuildFile(other_file) != NULL);
   1473 
   1474   // Now try to define it as a package.
   1475   ExpectHasValidationErrors(
   1476     "package foo.bar;",
   1477     "0:8: \"foo\" is already defined (as something other than a package) "
   1478       "in file \"bar.proto\".\n");
   1479 }
   1480 
   1481 TEST_F(ParserValidationErrorTest, MessageNameError) {
   1482   ExpectHasValidationErrors(
   1483     "message Foo {}\n"
   1484     "message Foo {}\n",
   1485     "1:8: \"Foo\" is already defined.\n");
   1486 }
   1487 
   1488 TEST_F(ParserValidationErrorTest, FieldNameError) {
   1489   ExpectHasValidationErrors(
   1490     "message Foo {\n"
   1491     "  optional int32 bar = 1;\n"
   1492     "  optional int32 bar = 2;\n"
   1493     "}\n",
   1494     "2:17: \"bar\" is already defined in \"Foo\".\n");
   1495 }
   1496 
   1497 TEST_F(ParserValidationErrorTest, FieldTypeError) {
   1498   ExpectHasValidationErrors(
   1499     "message Foo {\n"
   1500     "  optional Baz bar = 1;\n"
   1501     "}\n",
   1502     "1:11: \"Baz\" is not defined.\n");
   1503 }
   1504 
   1505 TEST_F(ParserValidationErrorTest, FieldNumberError) {
   1506   ExpectHasValidationErrors(
   1507     "message Foo {\n"
   1508     "  optional int32 bar = 0;\n"
   1509     "}\n",
   1510     "1:23: Field numbers must be positive integers.\n");
   1511 }
   1512 
   1513 TEST_F(ParserValidationErrorTest, FieldExtendeeError) {
   1514   ExpectHasValidationErrors(
   1515     "extend Baz { optional int32 bar = 1; }\n",
   1516     "0:7: \"Baz\" is not defined.\n");
   1517 }
   1518 
   1519 TEST_F(ParserValidationErrorTest, FieldDefaultValueError) {
   1520   ExpectHasValidationErrors(
   1521     "enum Baz { QUX = 1; }\n"
   1522     "message Foo {\n"
   1523     "  optional Baz bar = 1 [default=NO_SUCH_VALUE];\n"
   1524     "}\n",
   1525     "2:32: Enum type \"Baz\" has no value named \"NO_SUCH_VALUE\".\n");
   1526 }
   1527 
   1528 TEST_F(ParserValidationErrorTest, FileOptionNameError) {
   1529   ExpectHasValidationErrors(
   1530     "option foo = 5;",
   1531     "0:7: Option \"foo\" unknown.\n");
   1532 }
   1533 
   1534 TEST_F(ParserValidationErrorTest, FileOptionValueError) {
   1535   ExpectHasValidationErrors(
   1536     "option java_outer_classname = 5;",
   1537     "0:30: Value must be quoted string for string option "
   1538     "\"google.protobuf.FileOptions.java_outer_classname\".\n");
   1539 }
   1540 
   1541 TEST_F(ParserValidationErrorTest, FieldOptionNameError) {
   1542   ExpectHasValidationErrors(
   1543     "message Foo {\n"
   1544     "  optional bool bar = 1 [foo=1];\n"
   1545     "}\n",
   1546     "1:25: Option \"foo\" unknown.\n");
   1547 }
   1548 
   1549 TEST_F(ParserValidationErrorTest, FieldOptionValueError) {
   1550   ExpectHasValidationErrors(
   1551     "message Foo {\n"
   1552     "  optional int32 bar = 1 [ctype=1];\n"
   1553     "}\n",
   1554     "1:32: Value must be identifier for enum-valued option "
   1555     "\"google.protobuf.FieldOptions.ctype\".\n");
   1556 }
   1557 
   1558 TEST_F(ParserValidationErrorTest, ExtensionRangeNumberError) {
   1559   ExpectHasValidationErrors(
   1560     "message Foo {\n"
   1561     "  extensions 0;\n"
   1562     "}\n",
   1563     "1:13: Extension numbers must be positive integers.\n");
   1564 }
   1565 
   1566 TEST_F(ParserValidationErrorTest, EnumNameError) {
   1567   ExpectHasValidationErrors(
   1568     "enum Foo {A = 1;}\n"
   1569     "enum Foo {B = 1;}\n",
   1570     "1:5: \"Foo\" is already defined.\n");
   1571 }
   1572 
   1573 TEST_F(ParserValidationErrorTest, EnumValueNameError) {
   1574   ExpectHasValidationErrors(
   1575     "enum Foo {\n"
   1576     "  BAR = 1;\n"
   1577     "  BAR = 1;\n"
   1578     "}\n",
   1579     "2:2: \"BAR\" is already defined.\n");
   1580 }
   1581 
   1582 TEST_F(ParserValidationErrorTest, ServiceNameError) {
   1583   ExpectHasValidationErrors(
   1584     "service Foo {}\n"
   1585     "service Foo {}\n",
   1586     "1:8: \"Foo\" is already defined.\n");
   1587 }
   1588 
   1589 TEST_F(ParserValidationErrorTest, MethodNameError) {
   1590   ExpectHasValidationErrors(
   1591     "message Baz {}\n"
   1592     "service Foo {\n"
   1593     "  rpc Bar(Baz) returns(Baz);\n"
   1594     "  rpc Bar(Baz) returns(Baz);\n"
   1595     "}\n",
   1596     "3:6: \"Bar\" is already defined in \"Foo\".\n");
   1597 }
   1598 
   1599 
   1600 TEST_F(ParserValidationErrorTest, MethodInputTypeError) {
   1601   ExpectHasValidationErrors(
   1602     "message Baz {}\n"
   1603     "service Foo {\n"
   1604     "  rpc Bar(Qux) returns(Baz);\n"
   1605     "}\n",
   1606     "2:10: \"Qux\" is not defined.\n");
   1607 }
   1608 
   1609 
   1610 TEST_F(ParserValidationErrorTest, MethodOutputTypeError) {
   1611   ExpectHasValidationErrors(
   1612     "message Baz {}\n"
   1613     "service Foo {\n"
   1614     "  rpc Bar(Baz) returns(Qux);\n"
   1615     "}\n",
   1616     "2:23: \"Qux\" is not defined.\n");
   1617 }
   1618 
   1619 
   1620 TEST_F(ParserValidationErrorTest, ResovledUndefinedError) {
   1621   // Create another file which defines symbol ".base.bar".
   1622   FileDescriptorProto other_file;
   1623   other_file.set_name("base.proto");
   1624   other_file.set_package("base");
   1625   other_file.add_message_type()->set_name("bar");
   1626   EXPECT_TRUE(pool_.BuildFile(other_file) != NULL);
   1627 
   1628   // Define "foo.base" and try "base.bar".
   1629   // "base.bar" is resolved to "foo.base.bar" which is not defined.
   1630   ExpectHasValidationErrors(
   1631     "package foo.base;\n"
   1632     "import \"base.proto\";\n"
   1633     "message qux {\n"
   1634     "  optional base.bar baz = 1;\n"
   1635     "  optional .base.bar quz = 2;\n"
   1636     "}\n",
   1637     "3:11: \"base.bar\" is resolved to \"foo.base.bar\","
   1638     " which is not defined. The innermost scope is searched first "
   1639     "in name resolution. Consider using a leading '.'(i.e., \".base.bar\")"
   1640     " to start from the outermost scope.\n");
   1641 }
   1642 
   1643 TEST_F(ParserValidationErrorTest, ResovledUndefinedOptionError) {
   1644   // Build descriptor message in test pool
   1645   FileDescriptorProto descriptor_proto;
   1646   DescriptorProto::descriptor()->file()->CopyTo(&descriptor_proto);
   1647   ASSERT_TRUE(pool_.BuildFile(descriptor_proto) != NULL);
   1648 
   1649   // base2.proto:
   1650   //   package baz
   1651   //   import google/protobuf/descriptor.proto
   1652   //   message Bar { optional int32 foo = 1; }
   1653   //   extend FileOptions { optional Bar bar = 7672757; }
   1654   FileDescriptorProto other_file;
   1655   other_file.set_name("base2.proto");
   1656   other_file.set_package("baz");
   1657   other_file.add_dependency();
   1658   other_file.set_dependency(0, descriptor_proto.name());
   1659 
   1660   DescriptorProto* message(other_file.add_message_type());
   1661   message->set_name("Bar");
   1662   FieldDescriptorProto* field(message->add_field());
   1663   field->set_name("foo");
   1664   field->set_number(1);
   1665   field->set_label(FieldDescriptorProto_Label_LABEL_OPTIONAL);
   1666   field->set_type(FieldDescriptorProto_Type_TYPE_INT32);
   1667 
   1668   FieldDescriptorProto* extension(other_file.add_extension());
   1669   extension->set_name("bar");
   1670   extension->set_number(7672757);
   1671   extension->set_label(FieldDescriptorProto_Label_LABEL_OPTIONAL);
   1672   extension->set_type(FieldDescriptorProto_Type_TYPE_MESSAGE);
   1673   extension->set_type_name("Bar");
   1674   extension->set_extendee("google.protobuf.FileOptions");
   1675 
   1676   EXPECT_TRUE(pool_.BuildFile(other_file) != NULL);
   1677 
   1678   // qux.proto:
   1679   //   package qux.baz
   1680   //   option (baz.bar).foo = 1;
   1681   //
   1682   // Although "baz.bar" is already defined, the lookup code will try
   1683   // "qux.baz.bar", since it's the match from the innermost scope,
   1684   // which will cause a symbol not defined error.
   1685   ExpectHasValidationErrors(
   1686       "package qux.baz;\n"
   1687       "import \"base2.proto\";\n"
   1688       "option (baz.bar).foo = 1;\n",
   1689       "2:7: Option \"(baz.bar)\" is resolved to \"(qux.baz.bar)\","
   1690       " which is not defined. The innermost scope is searched first "
   1691       "in name resolution. Consider using a leading '.'(i.e., \"(.baz.bar)\")"
   1692       " to start from the outermost scope.\n");
   1693 }
   1694 
   1695 // ===================================================================
   1696 // Test that the output from FileDescriptor::DebugString() (and all other
   1697 // descriptor types) is parseable, and results in the same Descriptor
   1698 // definitions again afoter parsing (note, however, that the order of messages
   1699 // cannot be guaranteed to be the same)
   1700 
   1701 typedef ParserTest ParseDescriptorDebugTest;
   1702 
   1703 class CompareDescriptorNames {
   1704  public:
   1705   bool operator()(const DescriptorProto* left,
   1706                   const DescriptorProto* right) const {
   1707     return left->name() < right->name();
   1708   }
   1709 };
   1710 
   1711 // Sorts nested DescriptorProtos of a DescriptoProto, by name.
   1712 void SortMessages(DescriptorProto *descriptor_proto) {
   1713   int size = descriptor_proto->nested_type_size();
   1714   // recursively sort; we can't guarantee the order of nested messages either
   1715   for (int i = 0; i < size; ++i) {
   1716     SortMessages(descriptor_proto->mutable_nested_type(i));
   1717   }
   1718   DescriptorProto **data =
   1719     descriptor_proto->mutable_nested_type()->mutable_data();
   1720   std::sort(data, data + size, CompareDescriptorNames());
   1721 }
   1722 
   1723 // Sorts DescriptorProtos belonging to a FileDescriptorProto, by name.
   1724 void SortMessages(FileDescriptorProto *file_descriptor_proto) {
   1725   int size = file_descriptor_proto->message_type_size();
   1726   // recursively sort; we can't guarantee the order of nested messages either
   1727   for (int i = 0; i < size; ++i) {
   1728     SortMessages(file_descriptor_proto->mutable_message_type(i));
   1729   }
   1730   DescriptorProto **data =
   1731     file_descriptor_proto->mutable_message_type()->mutable_data();
   1732   std::sort(data, data + size, CompareDescriptorNames());
   1733 }
   1734 
   1735 // Strips the message and enum field type names for comparison purpose only.
   1736 void StripFieldTypeName(DescriptorProto* proto) {
   1737   for (int i = 0; i < proto->field_size(); ++i) {
   1738     string type_name = proto->field(i).type_name();
   1739     string::size_type pos = type_name.find_last_of(".");
   1740     if (pos != string::npos) {
   1741       proto->mutable_field(i)->mutable_type_name()->assign(
   1742           type_name.begin() + pos + 1, type_name.end());
   1743     }
   1744   }
   1745   for (int i = 0; i < proto->nested_type_size(); ++i) {
   1746     StripFieldTypeName(proto->mutable_nested_type(i));
   1747   }
   1748 }
   1749 
   1750 void StripFieldTypeName(FileDescriptorProto* file_proto) {
   1751   for (int i = 0; i < file_proto->message_type_size(); ++i) {
   1752     StripFieldTypeName(file_proto->mutable_message_type(i));
   1753   }
   1754 }
   1755 
   1756 TEST_F(ParseDescriptorDebugTest, TestAllDescriptorTypes) {
   1757   const FileDescriptor* original_file =
   1758      protobuf_unittest::TestAllTypes::descriptor()->file();
   1759   FileDescriptorProto expected;
   1760   original_file->CopyTo(&expected);
   1761 
   1762   // Get the DebugString of the unittest.proto FileDecriptor, which includes
   1763   // all other descriptor types
   1764   string debug_string = original_file->DebugString();
   1765 
   1766   // Parse the debug string
   1767   SetupParser(debug_string.c_str());
   1768   FileDescriptorProto parsed;
   1769   parser_->Parse(input_.get(), &parsed);
   1770   EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
   1771   ASSERT_EQ("", error_collector_.text_)
   1772       << "Failed to parse:\n" << debug_string;
   1773 
   1774   // We now have a FileDescriptorProto, but to compare with the expected we
   1775   // need to link to a FileDecriptor, then output back to a proto. We'll
   1776   // also need to give it the same name as the original.
   1777   parsed.set_name("google/protobuf/unittest.proto");
   1778   // We need the imported dependency before we can build our parsed proto
   1779   const FileDescriptor* public_import =
   1780       protobuf_unittest_import::PublicImportMessage::descriptor()->file();
   1781   FileDescriptorProto public_import_proto;
   1782   public_import->CopyTo(&public_import_proto);
   1783   ASSERT_TRUE(pool_.BuildFile(public_import_proto) != NULL);
   1784   const FileDescriptor* import =
   1785        protobuf_unittest_import::ImportMessage::descriptor()->file();
   1786   FileDescriptorProto import_proto;
   1787   import->CopyTo(&import_proto);
   1788   ASSERT_TRUE(pool_.BuildFile(import_proto) != NULL);
   1789   const FileDescriptor* actual = pool_.BuildFile(parsed);
   1790   parsed.Clear();
   1791   ASSERT_TRUE(actual != NULL)
   1792       << "Failed to validate:\n" << debug_string;
   1793   actual->CopyTo(&parsed);
   1794   ASSERT_TRUE(actual != NULL);
   1795 
   1796   // The messages might be in different orders, making them hard to compare.
   1797   // So, sort the messages in the descriptor protos (including nested messages,
   1798   // recursively).
   1799   SortMessages(&expected);
   1800   SortMessages(&parsed);
   1801 
   1802   // I really wanted to use StringDiff here for the debug output on fail,
   1803   // but the strings are too long for it, and if I increase its max size,
   1804   // we get a memory allocation failure :(
   1805   EXPECT_EQ(expected.DebugString(), parsed.DebugString());
   1806 }
   1807 
   1808 TEST_F(ParseDescriptorDebugTest, TestCustomOptions) {
   1809   const FileDescriptor* original_file =
   1810      protobuf_unittest::AggregateMessage::descriptor()->file();
   1811   FileDescriptorProto expected;
   1812   original_file->CopyTo(&expected);
   1813 
   1814   string debug_string = original_file->DebugString();
   1815 
   1816   // Parse the debug string
   1817   SetupParser(debug_string.c_str());
   1818   FileDescriptorProto parsed;
   1819   parser_->Parse(input_.get(), &parsed);
   1820   EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
   1821   ASSERT_EQ("", error_collector_.text_);
   1822 
   1823   // We now have a FileDescriptorProto, but to compare with the expected we
   1824   // need to link to a FileDecriptor, then output back to a proto. We'll
   1825   // also need to give it the same name as the original.
   1826   parsed.set_name(original_file->name());
   1827 
   1828   // unittest_custom_options.proto depends on descriptor.proto.
   1829   const FileDescriptor* import = FileDescriptorProto::descriptor()->file();
   1830   FileDescriptorProto import_proto;
   1831   import->CopyTo(&import_proto);
   1832   ASSERT_TRUE(pool_.BuildFile(import_proto) != NULL);
   1833   const FileDescriptor* actual = pool_.BuildFile(parsed);
   1834   ASSERT_TRUE(actual != NULL);
   1835   parsed.Clear();
   1836   actual->CopyTo(&parsed);
   1837 
   1838   // The messages might be in different orders, making them hard to compare.
   1839   // So, sort the messages in the descriptor protos (including nested messages,
   1840   // recursively).
   1841   SortMessages(&expected);
   1842   SortMessages(&parsed);
   1843 
   1844   EXPECT_EQ(expected.DebugString(), parsed.DebugString());
   1845 }
   1846 
   1847 // Ensure that DebugStringWithOptions(), with |include_comments| set to true,
   1848 // includes comments from the original parser input in all of the appropriate
   1849 // places.
   1850 TEST_F(ParseDescriptorDebugTest, TestCommentsInDebugString) {
   1851   SetupParser(
   1852       "// Detached comment before syntax.\n"
   1853       "\n"
   1854       "// Syntax comment.\n"
   1855       "syntax = \"proto2\";\n"
   1856       "\n"
   1857       "// Detached comment before package.\n"
   1858       "\n"
   1859       "// Package comment.\n"
   1860       "package comment_test;\n"
   1861       "\n"
   1862       "// Detached comment before TestMessage1.\n"
   1863       "\n"
   1864       "// Message comment.\n"
   1865       "//\n"
   1866       "// More detail in message comment.\n"
   1867       "message TestMessage1 {\n"
   1868       "\n"
   1869       "  // Detached comment before foo.\n"
   1870       "\n"
   1871       "  // Field comment.\n"
   1872       "  optional int32 foo = 1;\n"
   1873       "\n"
   1874       "  // Detached comment before NestedMessage.\n"
   1875       "\n"
   1876       "  // Nested-message comment.\n"
   1877       "  message NestedMessage {\n"
   1878       "    optional int32 bar = 1;\n"
   1879       "  }\n"
   1880       "}\n"
   1881       "\n"
   1882       "// Detached comment before MyEnumType.\n"
   1883       "\n"
   1884       "// Enum comment.\n"
   1885       "enum MyEnumType {\n"
   1886       "\n"
   1887       "  // Detached comment before ASDF.\n"
   1888       "\n"
   1889       "  // Enum-value comment.\n"
   1890       "  ASDF = 1;\n"
   1891       "}\n"
   1892       "\n"
   1893       "// Detached comment before MyService.\n"
   1894       "\n"
   1895       "// Service comment.\n"
   1896       "service MyService {\n"
   1897       "\n"
   1898       "  // Detached comment before MyRPCCall.\n"
   1899       "\n"
   1900       "  // RPC comment.\n"
   1901       "  rpc MyRPCCall(TestMessage1) returns (TestMessage1) { }\n"
   1902       "}\n");
   1903 
   1904   FileDescriptorProto parsed_desc;
   1905   parsed_desc.set_name("foo.proto");
   1906   SourceLocationTable source_locations;
   1907   parser_->RecordSourceLocationsTo(&source_locations);
   1908   parser_->Parse(input_.get(), &parsed_desc);
   1909   EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
   1910   ASSERT_EQ("", error_collector_.text_);
   1911 
   1912   // We need to import the FileDescriptorProto to get a FileDescriptor.
   1913   MockValidationErrorCollector collector(source_locations, &error_collector_);
   1914   const FileDescriptor* descriptor =
   1915       pool_.BuildFileCollectingErrors(parsed_desc, &collector);
   1916   ASSERT_TRUE(descriptor != NULL);
   1917 
   1918   // Ensure that each of the comments appears somewhere in the DebugString().
   1919   // We don't test the exact comment placement or formatting, because we do not
   1920   // want to be too fragile here.
   1921   const char* expected_comments[] = {
   1922     "Detached comment before syntax.",
   1923     "Syntax comment.",
   1924     "Detached comment before package.",
   1925     "Package comment.",
   1926     "Detached comment before TestMessage1.",
   1927     "Message comment.",
   1928     "More detail in message comment.",
   1929     "Detached comment before foo.",
   1930     "Field comment",
   1931     "Detached comment before NestedMessage.",
   1932     "Nested-message comment",
   1933     "Detached comment before MyEnumType.",
   1934     "Enum comment",
   1935     "Detached comment before ASDF.",
   1936     "Enum-value comment",
   1937     "Detached comment before MyService.",
   1938     "Service comment",
   1939     "Detached comment before MyRPCCall.",
   1940     "RPC comment",
   1941   };
   1942 
   1943   DebugStringOptions debug_string_options;
   1944   debug_string_options.include_comments = true;
   1945 
   1946   {
   1947     const string debug_string =
   1948         descriptor->DebugStringWithOptions(debug_string_options);
   1949 
   1950     for (int i = 0; i < GOOGLE_ARRAYSIZE(expected_comments); ++i) {
   1951       string::size_type found_pos = debug_string.find(expected_comments[i]);
   1952       EXPECT_TRUE(found_pos != string::npos)
   1953           << "\"" << expected_comments[i] << "\" not found.";
   1954     }
   1955 
   1956     // Result of DebugStringWithOptions should be parseable.
   1957     SetupParser(debug_string.c_str());
   1958     FileDescriptorProto parsed;
   1959     parser_->Parse(input_.get(), &parsed);
   1960     EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
   1961     ASSERT_EQ("", error_collector_.text_)
   1962         << "Failed to parse:\n" << debug_string;
   1963   }
   1964 
   1965 }
   1966 
   1967 TEST_F(ParseDescriptorDebugTest, TestMaps) {
   1968   SetupParser(
   1969       "syntax = \"proto3\"; "
   1970       "message Foo { "
   1971       "  message Bar { } "
   1972       "  map<int32, Bar> enum_message_map = 1; "
   1973       "  map<string, float> primitive_map = 2; "
   1974       "} ");
   1975   FileDescriptorProto original;
   1976   EXPECT_TRUE(parser_->Parse(input_.get(), &original));
   1977   original.set_name("foo.proto");
   1978   const FileDescriptor* file = pool_.BuildFile(original);
   1979   ASSERT_TRUE(file != NULL);
   1980 
   1981   // Make sure the debug string uses map syntax and does not have the auto
   1982   // generated entry.
   1983   string debug_string = file->DebugString();
   1984   EXPECT_TRUE(debug_string.find("map<") != string::npos);
   1985   EXPECT_TRUE(debug_string.find("option map_entry") == string::npos);
   1986   EXPECT_TRUE(debug_string.find("MapEntry") == string::npos);
   1987 
   1988   // Make sure the descriptor debug string is parsable.
   1989   FileDescriptorProto parsed;
   1990   SetupParser(debug_string.c_str());
   1991   parsed.set_name("foo.proto");
   1992   ASSERT_TRUE(parser_->Parse(input_.get(), &parsed));
   1993 
   1994   original.clear_source_code_info();
   1995   parsed.clear_source_code_info();
   1996   StripFieldTypeName(&original);
   1997   StripFieldTypeName(&parsed);
   1998   EXPECT_EQ(original.DebugString(), parsed.DebugString());
   1999 }
   2000 
   2001 // ===================================================================
   2002 // SourceCodeInfo tests.
   2003 
   2004 // Follows a path -- as defined by SourceCodeInfo.Location.path -- from a
   2005 // message to a particular sub-field.
   2006 // * If the target is itself a message, sets *output_message to point at it,
   2007 //   *output_field to NULL, and *output_index to -1.
   2008 // * Otherwise, if the target is an element of a repeated field, sets
   2009 //   *output_message to the containing message, *output_field to the descriptor
   2010 //   of the field, and *output_index to the index of the element.
   2011 // * Otherwise, the target is a field (possibly a repeated field, but not any
   2012 //   one element).  Sets *output_message to the containing message,
   2013 //   *output_field to the descriptor of the field, and *output_index to -1.
   2014 // Returns true if the path was valid, false otherwise.  A gTest failure is
   2015 // recorded before returning false.
   2016 bool FollowPath(const Message& root,
   2017                 const int* path_begin, const int* path_end,
   2018                 const Message** output_message,
   2019                 const FieldDescriptor** output_field,
   2020                 int* output_index) {
   2021   if (path_begin == path_end) {
   2022     // Path refers to this whole message.
   2023     *output_message = &root;
   2024     *output_field = NULL;
   2025     *output_index = -1;
   2026     return true;
   2027   }
   2028 
   2029   const Descriptor* descriptor = root.GetDescriptor();
   2030   const Reflection* reflection = root.GetReflection();
   2031 
   2032   const FieldDescriptor* field = descriptor->FindFieldByNumber(*path_begin);
   2033 
   2034   if (field == NULL) {
   2035     ADD_FAILURE() << descriptor->name() << " has no field number: "
   2036                   << *path_begin;
   2037     return false;
   2038   }
   2039 
   2040   ++path_begin;
   2041 
   2042   if (field->is_repeated()) {
   2043     if (path_begin == path_end) {
   2044       // Path refers to the whole repeated field.
   2045       *output_message = &root;
   2046       *output_field = field;
   2047       *output_index = -1;
   2048       return true;
   2049     }
   2050 
   2051     int index = *path_begin++;
   2052     int size = reflection->FieldSize(root, field);
   2053 
   2054     if (index >= size) {
   2055       ADD_FAILURE() << descriptor->name() << "." << field->name()
   2056                     << " has size " << size << ", but path contained index: "
   2057                     << index;
   2058       return false;
   2059     }
   2060 
   2061     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
   2062       // Descend into child message.
   2063       const Message& child = reflection->GetRepeatedMessage(root, field, index);
   2064       return FollowPath(child, path_begin, path_end,
   2065                         output_message, output_field, output_index);
   2066     } else if (path_begin == path_end) {
   2067       // Path refers to this element.
   2068       *output_message = &root;
   2069       *output_field = field;
   2070       *output_index = index;
   2071       return true;
   2072     } else {
   2073       ADD_FAILURE() << descriptor->name() << "." << field->name()
   2074                     << " is not a message; cannot descend into it.";
   2075       return false;
   2076     }
   2077   } else {
   2078     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
   2079       const Message& child = reflection->GetMessage(root, field);
   2080       return FollowPath(child, path_begin, path_end,
   2081                         output_message, output_field, output_index);
   2082     } else if (path_begin == path_end) {
   2083       // Path refers to this field.
   2084       *output_message = &root;
   2085       *output_field = field;
   2086       *output_index = -1;
   2087       return true;
   2088     } else {
   2089       ADD_FAILURE() << descriptor->name() << "." << field->name()
   2090                     << " is not a message; cannot descend into it.";
   2091       return false;
   2092     }
   2093   }
   2094 }
   2095 
   2096 // Check if two spans are equal.
   2097 bool CompareSpans(const RepeatedField<int>& span1,
   2098                   const RepeatedField<int>& span2) {
   2099   if (span1.size() != span2.size()) return false;
   2100   for (int i = 0; i < span1.size(); i++) {
   2101     if (span1.Get(i) != span2.Get(i)) return false;
   2102   }
   2103   return true;
   2104 }
   2105 
   2106 // Test fixture for source info tests, which check that source locations are
   2107 // recorded correctly in FileDescriptorProto.source_code_info.location.
   2108 class SourceInfoTest : public ParserTest {
   2109  protected:
   2110   // The parsed file (initialized by Parse()).
   2111   FileDescriptorProto file_;
   2112 
   2113   // Parse the given text as a .proto file and populate the spans_ map with
   2114   // all the source location spans in its SourceCodeInfo table.
   2115   bool Parse(const char* text) {
   2116     ExtractMarkers(text);
   2117     SetupParser(text_without_markers_.c_str());
   2118     if (!parser_->Parse(input_.get(), &file_)) {
   2119       return false;
   2120     }
   2121 
   2122     const SourceCodeInfo& source_info = file_.source_code_info();
   2123     for (int i = 0; i < source_info.location_size(); i++) {
   2124       const SourceCodeInfo::Location& location = source_info.location(i);
   2125       const Message* descriptor_proto = NULL;
   2126       const FieldDescriptor* field = NULL;
   2127       int index = 0;
   2128       if (!FollowPath(file_, location.path().begin(), location.path().end(),
   2129                       &descriptor_proto, &field, &index)) {
   2130         return false;
   2131       }
   2132 
   2133       spans_.insert(
   2134           std::make_pair(SpanKey(*descriptor_proto, field, index), &location));
   2135     }
   2136 
   2137     return true;
   2138   }
   2139 
   2140   virtual void TearDown() {
   2141     EXPECT_TRUE(spans_.empty())
   2142         << "Forgot to call HasSpan() for:\n"
   2143         << spans_.begin()->second->DebugString();
   2144   }
   2145 
   2146   // -----------------------------------------------------------------
   2147   // HasSpan() checks that the span of source code delimited by the given
   2148   // tags (comments) correspond via the SourceCodeInfo table to the given
   2149   // part of the FileDescriptorProto.  (If unclear, look at the actual tests;
   2150   // it should quickly become obvious.)
   2151 
   2152   bool HasSpan(char start_marker, char end_marker,
   2153                const Message& descriptor_proto) {
   2154     return HasSpanWithComment(
   2155         start_marker, end_marker, descriptor_proto, NULL, -1, NULL, NULL, NULL);
   2156   }
   2157 
   2158   bool HasSpanWithComment(char start_marker, char end_marker,
   2159                           const Message& descriptor_proto,
   2160                           const char* expected_leading_comments,
   2161                           const char* expected_trailing_comments,
   2162                           const char* expected_leading_detached_comments) {
   2163     return HasSpanWithComment(
   2164         start_marker, end_marker, descriptor_proto, NULL, -1,
   2165         expected_leading_comments, expected_trailing_comments,
   2166         expected_leading_detached_comments);
   2167   }
   2168 
   2169   bool HasSpan(char start_marker, char end_marker,
   2170                const Message& descriptor_proto, const string& field_name) {
   2171     return HasSpan(start_marker, end_marker, descriptor_proto, field_name, -1);
   2172   }
   2173 
   2174   bool HasSpan(char start_marker, char end_marker,
   2175                const Message& descriptor_proto, const string& field_name,
   2176                int index) {
   2177     return HasSpan(start_marker, end_marker, descriptor_proto,
   2178                    field_name, index, NULL, NULL, NULL);
   2179   }
   2180 
   2181   bool HasSpan(char start_marker, char end_marker,
   2182                const Message& descriptor_proto,
   2183                const string& field_name, int index,
   2184                const char* expected_leading_comments,
   2185                const char* expected_trailing_comments,
   2186                const char* expected_leading_detached_comments) {
   2187     const FieldDescriptor* field =
   2188         descriptor_proto.GetDescriptor()->FindFieldByName(field_name);
   2189     if (field == NULL) {
   2190       ADD_FAILURE() << descriptor_proto.GetDescriptor()->name()
   2191                     << " has no such field: " << field_name;
   2192       return false;
   2193     }
   2194 
   2195     return HasSpanWithComment(
   2196         start_marker, end_marker, descriptor_proto, field, index,
   2197         expected_leading_comments, expected_trailing_comments,
   2198         expected_leading_detached_comments);
   2199   }
   2200 
   2201   bool HasSpan(const Message& descriptor_proto) {
   2202     return HasSpanWithComment(
   2203         '\0', '\0', descriptor_proto, NULL, -1, NULL, NULL, NULL);
   2204   }
   2205 
   2206   bool HasSpan(const Message& descriptor_proto, const string& field_name) {
   2207     return HasSpan('\0', '\0', descriptor_proto, field_name, -1);
   2208   }
   2209 
   2210   bool HasSpan(const Message& descriptor_proto, const string& field_name,
   2211                int index) {
   2212     return HasSpan('\0', '\0', descriptor_proto, field_name, index);
   2213   }
   2214 
   2215   bool HasSpanWithComment(
   2216       char start_marker, char end_marker, const Message& descriptor_proto,
   2217       const FieldDescriptor* field, int index,
   2218       const char* expected_leading_comments,
   2219       const char* expected_trailing_comments,
   2220       const char* expected_leading_detached_comments) {
   2221     pair<SpanMap::iterator, SpanMap::iterator> range =
   2222         spans_.equal_range(SpanKey(descriptor_proto, field, index));
   2223 
   2224     if (start_marker == '\0') {
   2225       if (range.first == range.second) {
   2226         return false;
   2227       } else {
   2228         spans_.erase(range.first);
   2229         return true;
   2230       }
   2231     } else {
   2232       pair<int, int> start_pos = FindOrDie(markers_, start_marker);
   2233       pair<int, int> end_pos = FindOrDie(markers_, end_marker);
   2234 
   2235       RepeatedField<int> expected_span;
   2236       expected_span.Add(start_pos.first);
   2237       expected_span.Add(start_pos.second);
   2238       if (end_pos.first != start_pos.first) {
   2239         expected_span.Add(end_pos.first);
   2240       }
   2241       expected_span.Add(end_pos.second);
   2242 
   2243       for (SpanMap::iterator iter = range.first; iter != range.second; ++iter) {
   2244         if (CompareSpans(expected_span, iter->second->span())) {
   2245           if (expected_leading_comments == NULL) {
   2246             EXPECT_FALSE(iter->second->has_leading_comments());
   2247           } else {
   2248             EXPECT_TRUE(iter->second->has_leading_comments());
   2249             EXPECT_EQ(expected_leading_comments,
   2250                       iter->second->leading_comments());
   2251           }
   2252           if (expected_trailing_comments == NULL) {
   2253             EXPECT_FALSE(iter->second->has_trailing_comments());
   2254           } else {
   2255             EXPECT_TRUE(iter->second->has_trailing_comments());
   2256             EXPECT_EQ(expected_trailing_comments,
   2257                       iter->second->trailing_comments());
   2258           }
   2259           if (expected_leading_detached_comments == NULL) {
   2260             EXPECT_EQ(0, iter->second->leading_detached_comments_size());
   2261           } else {
   2262             EXPECT_EQ(
   2263                 expected_leading_detached_comments,
   2264                 Join(iter->second->leading_detached_comments(), "\n"));
   2265           }
   2266 
   2267           spans_.erase(iter);
   2268           return true;
   2269         }
   2270       }
   2271 
   2272       return false;
   2273     }
   2274   }
   2275 
   2276  private:
   2277   struct SpanKey {
   2278     const Message* descriptor_proto;
   2279     const FieldDescriptor* field;
   2280     int index;
   2281 
   2282     inline SpanKey() {}
   2283     inline SpanKey(const Message& descriptor_proto_param,
   2284                    const FieldDescriptor* field_param,
   2285                    int index_param)
   2286         : descriptor_proto(&descriptor_proto_param), field(field_param),
   2287           index(index_param) {}
   2288 
   2289     inline bool operator<(const SpanKey& other) const {
   2290       if (descriptor_proto < other.descriptor_proto) return true;
   2291       if (descriptor_proto > other.descriptor_proto) return false;
   2292       if (field < other.field) return true;
   2293       if (field > other.field) return false;
   2294       return index < other.index;
   2295     }
   2296   };
   2297 
   2298   typedef multimap<SpanKey, const SourceCodeInfo::Location*> SpanMap;
   2299   SpanMap spans_;
   2300   map<char, pair<int, int> > markers_;
   2301   string text_without_markers_;
   2302 
   2303   void ExtractMarkers(const char* text) {
   2304     markers_.clear();
   2305     text_without_markers_.clear();
   2306     int line = 0;
   2307     int column = 0;
   2308     while (*text != '\0') {
   2309       if (*text == '$') {
   2310         ++text;
   2311         GOOGLE_CHECK_NE('\0', *text);
   2312         if (*text == '$') {
   2313           text_without_markers_ += '$';
   2314           ++column;
   2315         } else {
   2316           markers_[*text] = std::make_pair(line, column);
   2317           ++text;
   2318           GOOGLE_CHECK_EQ('$', *text);
   2319         }
   2320       } else if (*text == '\n') {
   2321         ++line;
   2322         column = 0;
   2323         text_without_markers_ += *text;
   2324       } else {
   2325         text_without_markers_ += *text;
   2326         ++column;
   2327       }
   2328       ++text;
   2329     }
   2330   }
   2331 };
   2332 
   2333 TEST_F(SourceInfoTest, BasicFileDecls) {
   2334   EXPECT_TRUE(Parse(
   2335       "$a$syntax = \"proto2\";$i$\n"
   2336       "package $b$foo.bar$c$;\n"
   2337       "import $d$\"baz.proto\"$e$;\n"
   2338       "import $f$\"qux.proto\"$g$;$h$\n"
   2339       "\n"
   2340       "// comment ignored\n"));
   2341 
   2342   EXPECT_TRUE(HasSpan('a', 'h', file_));
   2343   EXPECT_TRUE(HasSpan('b', 'c', file_, "package"));
   2344   EXPECT_TRUE(HasSpan('d', 'e', file_, "dependency", 0));
   2345   EXPECT_TRUE(HasSpan('f', 'g', file_, "dependency", 1));
   2346   EXPECT_TRUE(HasSpan('a', 'i', file_, "syntax"));
   2347 }
   2348 
   2349 TEST_F(SourceInfoTest, Messages) {
   2350   EXPECT_TRUE(Parse(
   2351       "$a$message $b$Foo$c$ {}$d$\n"
   2352       "$e$message $f$Bar$g$ {}$h$\n"));
   2353 
   2354   EXPECT_TRUE(HasSpan('a', 'd', file_.message_type(0)));
   2355   EXPECT_TRUE(HasSpan('b', 'c', file_.message_type(0), "name"));
   2356   EXPECT_TRUE(HasSpan('e', 'h', file_.message_type(1)));
   2357   EXPECT_TRUE(HasSpan('f', 'g', file_.message_type(1), "name"));
   2358 
   2359   // Ignore these.
   2360   EXPECT_TRUE(HasSpan(file_));
   2361 }
   2362 
   2363 TEST_F(SourceInfoTest, Fields) {
   2364   EXPECT_TRUE(Parse(
   2365       "message Foo {\n"
   2366       "  $a$optional$b$ $c$int32$d$ $e$bar$f$ = $g$1$h$;$i$\n"
   2367       "  $j$repeated$k$ $l$X.Y$m$ $n$baz$o$ = $p$2$q$;$r$\n"
   2368       "}\n"));
   2369 
   2370   const FieldDescriptorProto& field1 = file_.message_type(0).field(0);
   2371   const FieldDescriptorProto& field2 = file_.message_type(0).field(1);
   2372 
   2373   EXPECT_TRUE(HasSpan('a', 'i', field1));
   2374   EXPECT_TRUE(HasSpan('a', 'b', field1, "label"));
   2375   EXPECT_TRUE(HasSpan('c', 'd', field1, "type"));
   2376   EXPECT_TRUE(HasSpan('e', 'f', field1, "name"));
   2377   EXPECT_TRUE(HasSpan('g', 'h', field1, "number"));
   2378 
   2379   EXPECT_TRUE(HasSpan('j', 'r', field2));
   2380   EXPECT_TRUE(HasSpan('j', 'k', field2, "label"));
   2381   EXPECT_TRUE(HasSpan('l', 'm', field2, "type_name"));
   2382   EXPECT_TRUE(HasSpan('n', 'o', field2, "name"));
   2383   EXPECT_TRUE(HasSpan('p', 'q', field2, "number"));
   2384 
   2385   // Ignore these.
   2386   EXPECT_TRUE(HasSpan(file_));
   2387   EXPECT_TRUE(HasSpan(file_.message_type(0)));
   2388   EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
   2389 }
   2390 
   2391 TEST_F(SourceInfoTest, Extensions) {
   2392   EXPECT_TRUE(Parse(
   2393       "$a$extend $b$Foo$c$ {\n"
   2394       "  $d$optional$e$ int32 bar = 1;$f$\n"
   2395       "  $g$repeated$h$ X.Y baz = 2;$i$\n"
   2396       "}$j$\n"
   2397       "$k$extend $l$Bar$m$ {\n"
   2398       "  $n$optional int32 qux = 1;$o$\n"
   2399       "}$p$\n"));
   2400 
   2401   const FieldDescriptorProto& field1 = file_.extension(0);
   2402   const FieldDescriptorProto& field2 = file_.extension(1);
   2403   const FieldDescriptorProto& field3 = file_.extension(2);
   2404 
   2405   EXPECT_TRUE(HasSpan('a', 'j', file_, "extension"));
   2406   EXPECT_TRUE(HasSpan('k', 'p', file_, "extension"));
   2407 
   2408   EXPECT_TRUE(HasSpan('d', 'f', field1));
   2409   EXPECT_TRUE(HasSpan('d', 'e', field1, "label"));
   2410   EXPECT_TRUE(HasSpan('b', 'c', field1, "extendee"));
   2411 
   2412   EXPECT_TRUE(HasSpan('g', 'i', field2));
   2413   EXPECT_TRUE(HasSpan('g', 'h', field2, "label"));
   2414   EXPECT_TRUE(HasSpan('b', 'c', field2, "extendee"));
   2415 
   2416   EXPECT_TRUE(HasSpan('n', 'o', field3));
   2417   EXPECT_TRUE(HasSpan('l', 'm', field3, "extendee"));
   2418 
   2419   // Ignore these.
   2420   EXPECT_TRUE(HasSpan(file_));
   2421   EXPECT_TRUE(HasSpan(field1, "type"));
   2422   EXPECT_TRUE(HasSpan(field1, "name"));
   2423   EXPECT_TRUE(HasSpan(field1, "number"));
   2424   EXPECT_TRUE(HasSpan(field2, "type_name"));
   2425   EXPECT_TRUE(HasSpan(field2, "name"));
   2426   EXPECT_TRUE(HasSpan(field2, "number"));
   2427   EXPECT_TRUE(HasSpan(field3, "label"));
   2428   EXPECT_TRUE(HasSpan(field3, "type"));
   2429   EXPECT_TRUE(HasSpan(field3, "name"));
   2430   EXPECT_TRUE(HasSpan(field3, "number"));
   2431 }
   2432 
   2433 TEST_F(SourceInfoTest, NestedExtensions) {
   2434   EXPECT_TRUE(Parse(
   2435       "message Message {\n"
   2436       "  $a$extend $b$Foo$c$ {\n"
   2437       "    $d$optional$e$ int32 bar = 1;$f$\n"
   2438       "    $g$repeated$h$ X.Y baz = 2;$i$\n"
   2439       "  }$j$\n"
   2440       "  $k$extend $l$Bar$m$ {\n"
   2441       "    $n$optional int32 qux = 1;$o$\n"
   2442       "  }$p$\n"
   2443       "}\n"));
   2444 
   2445   const FieldDescriptorProto& field1 = file_.message_type(0).extension(0);
   2446   const FieldDescriptorProto& field2 = file_.message_type(0).extension(1);
   2447   const FieldDescriptorProto& field3 = file_.message_type(0).extension(2);
   2448 
   2449   EXPECT_TRUE(HasSpan('a', 'j', file_.message_type(0), "extension"));
   2450   EXPECT_TRUE(HasSpan('k', 'p', file_.message_type(0), "extension"));
   2451 
   2452   EXPECT_TRUE(HasSpan('d', 'f', field1));
   2453   EXPECT_TRUE(HasSpan('d', 'e', field1, "label"));
   2454   EXPECT_TRUE(HasSpan('b', 'c', field1, "extendee"));
   2455 
   2456   EXPECT_TRUE(HasSpan('g', 'i', field2));
   2457   EXPECT_TRUE(HasSpan('g', 'h', field2, "label"));
   2458   EXPECT_TRUE(HasSpan('b', 'c', field2, "extendee"));
   2459 
   2460   EXPECT_TRUE(HasSpan('n', 'o', field3));
   2461   EXPECT_TRUE(HasSpan('l', 'm', field3, "extendee"));
   2462 
   2463   // Ignore these.
   2464   EXPECT_TRUE(HasSpan(file_));
   2465   EXPECT_TRUE(HasSpan(file_.message_type(0)));
   2466   EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
   2467   EXPECT_TRUE(HasSpan(field1, "type"));
   2468   EXPECT_TRUE(HasSpan(field1, "name"));
   2469   EXPECT_TRUE(HasSpan(field1, "number"));
   2470   EXPECT_TRUE(HasSpan(field2, "type_name"));
   2471   EXPECT_TRUE(HasSpan(field2, "name"));
   2472   EXPECT_TRUE(HasSpan(field2, "number"));
   2473   EXPECT_TRUE(HasSpan(field3, "label"));
   2474   EXPECT_TRUE(HasSpan(field3, "type"));
   2475   EXPECT_TRUE(HasSpan(field3, "name"));
   2476   EXPECT_TRUE(HasSpan(field3, "number"));
   2477 }
   2478 
   2479 TEST_F(SourceInfoTest, ExtensionRanges) {
   2480   EXPECT_TRUE(Parse(
   2481       "message Message {\n"
   2482       "  $a$extensions $b$1$c$ to $d$4$e$, $f$6$g$;$h$\n"
   2483       "  $i$extensions $j$8$k$ to $l$max$m$;$n$\n"
   2484       "}\n"));
   2485 
   2486   const DescriptorProto::ExtensionRange& range1 =
   2487       file_.message_type(0).extension_range(0);
   2488   const DescriptorProto::ExtensionRange& range2 =
   2489       file_.message_type(0).extension_range(1);
   2490   const DescriptorProto::ExtensionRange& range3 =
   2491       file_.message_type(0).extension_range(2);
   2492 
   2493   EXPECT_TRUE(HasSpan('a', 'h', file_.message_type(0), "extension_range"));
   2494   EXPECT_TRUE(HasSpan('i', 'n', file_.message_type(0), "extension_range"));
   2495 
   2496   EXPECT_TRUE(HasSpan('b', 'e', range1));
   2497   EXPECT_TRUE(HasSpan('b', 'c', range1, "start"));
   2498   EXPECT_TRUE(HasSpan('d', 'e', range1, "end"));
   2499 
   2500   EXPECT_TRUE(HasSpan('f', 'g', range2));
   2501   EXPECT_TRUE(HasSpan('f', 'g', range2, "start"));
   2502   EXPECT_TRUE(HasSpan('f', 'g', range2, "end"));
   2503 
   2504   EXPECT_TRUE(HasSpan('j', 'm', range3));
   2505   EXPECT_TRUE(HasSpan('j', 'k', range3, "start"));
   2506   EXPECT_TRUE(HasSpan('l', 'm', range3, "end"));
   2507 
   2508   // Ignore these.
   2509   EXPECT_TRUE(HasSpan(file_));
   2510   EXPECT_TRUE(HasSpan(file_.message_type(0)));
   2511   EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
   2512 }
   2513 
   2514 TEST_F(SourceInfoTest, Oneofs) {
   2515   EXPECT_TRUE(Parse(
   2516       "message Foo {\n"
   2517       "  $a$oneof $c$foo$d$ {\n"
   2518       "    $e$int32$f$ $g$a$h$ = $i$1$j$;$k$\n"
   2519       "  }$r$\n"
   2520       "}\n"));
   2521 
   2522   const OneofDescriptorProto& oneof_decl = file_.message_type(0).oneof_decl(0);
   2523   const FieldDescriptorProto& field = file_.message_type(0).field(0);
   2524 
   2525   EXPECT_TRUE(HasSpan('a', 'r', oneof_decl));
   2526   EXPECT_TRUE(HasSpan('c', 'd', oneof_decl, "name"));
   2527 
   2528   EXPECT_TRUE(HasSpan('e', 'k', field));
   2529   EXPECT_TRUE(HasSpan('e', 'f', field, "type"));
   2530   EXPECT_TRUE(HasSpan('g', 'h', field, "name"));
   2531   EXPECT_TRUE(HasSpan('i', 'j', field, "number"));
   2532 
   2533   // Ignore these.
   2534   EXPECT_TRUE(HasSpan(file_));
   2535   EXPECT_TRUE(HasSpan(file_.message_type(0)));
   2536   EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
   2537 }
   2538 
   2539 TEST_F(SourceInfoTest, NestedMessages) {
   2540   EXPECT_TRUE(Parse(
   2541       "message Foo {\n"
   2542       "  $a$message $b$Bar$c$ {\n"
   2543       "    $d$message $e$Baz$f$ {}$g$\n"
   2544       "  }$h$\n"
   2545       "  $i$message $j$Qux$k$ {}$l$\n"
   2546       "}\n"));
   2547 
   2548   const DescriptorProto& bar = file_.message_type(0).nested_type(0);
   2549   const DescriptorProto& baz = bar.nested_type(0);
   2550   const DescriptorProto& qux = file_.message_type(0).nested_type(1);
   2551 
   2552   EXPECT_TRUE(HasSpan('a', 'h', bar));
   2553   EXPECT_TRUE(HasSpan('b', 'c', bar, "name"));
   2554   EXPECT_TRUE(HasSpan('d', 'g', baz));
   2555   EXPECT_TRUE(HasSpan('e', 'f', baz, "name"));
   2556   EXPECT_TRUE(HasSpan('i', 'l', qux));
   2557   EXPECT_TRUE(HasSpan('j', 'k', qux, "name"));
   2558 
   2559   // Ignore these.
   2560   EXPECT_TRUE(HasSpan(file_));
   2561   EXPECT_TRUE(HasSpan(file_.message_type(0)));
   2562   EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
   2563 }
   2564 
   2565 TEST_F(SourceInfoTest, Groups) {
   2566   EXPECT_TRUE(Parse(
   2567       "message Foo {\n"
   2568       "  message Bar {}\n"
   2569       "  $a$optional$b$ $c$group$d$ $e$Baz$f$ = $g$1$h$ {\n"
   2570       "    $i$message Qux {}$j$\n"
   2571       "  }$k$\n"
   2572       "}\n"));
   2573 
   2574   const DescriptorProto& bar = file_.message_type(0).nested_type(0);
   2575   const DescriptorProto& baz = file_.message_type(0).nested_type(1);
   2576   const DescriptorProto& qux = baz.nested_type(0);
   2577   const FieldDescriptorProto& field = file_.message_type(0).field(0);
   2578 
   2579   EXPECT_TRUE(HasSpan('a', 'k', field));
   2580   EXPECT_TRUE(HasSpan('a', 'b', field, "label"));
   2581   EXPECT_TRUE(HasSpan('c', 'd', field, "type"));
   2582   EXPECT_TRUE(HasSpan('e', 'f', field, "name"));
   2583   EXPECT_TRUE(HasSpan('e', 'f', field, "type_name"));
   2584   EXPECT_TRUE(HasSpan('g', 'h', field, "number"));
   2585 
   2586   EXPECT_TRUE(HasSpan('a', 'k', baz));
   2587   EXPECT_TRUE(HasSpan('e', 'f', baz, "name"));
   2588   EXPECT_TRUE(HasSpan('i', 'j', qux));
   2589 
   2590   // Ignore these.
   2591   EXPECT_TRUE(HasSpan(file_));
   2592   EXPECT_TRUE(HasSpan(file_.message_type(0)));
   2593   EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
   2594   EXPECT_TRUE(HasSpan(bar));
   2595   EXPECT_TRUE(HasSpan(bar, "name"));
   2596   EXPECT_TRUE(HasSpan(qux, "name"));
   2597 }
   2598 
   2599 TEST_F(SourceInfoTest, Enums) {
   2600   EXPECT_TRUE(Parse(
   2601       "$a$enum $b$Foo$c$ {}$d$\n"
   2602       "$e$enum $f$Bar$g$ {}$h$\n"));
   2603 
   2604   EXPECT_TRUE(HasSpan('a', 'd', file_.enum_type(0)));
   2605   EXPECT_TRUE(HasSpan('b', 'c', file_.enum_type(0), "name"));
   2606   EXPECT_TRUE(HasSpan('e', 'h', file_.enum_type(1)));
   2607   EXPECT_TRUE(HasSpan('f', 'g', file_.enum_type(1), "name"));
   2608 
   2609   // Ignore these.
   2610   EXPECT_TRUE(HasSpan(file_));
   2611 }
   2612 
   2613 TEST_F(SourceInfoTest, EnumValues) {
   2614   EXPECT_TRUE(Parse(
   2615       "enum Foo {\n"
   2616       "  $a$BAR$b$ = $c$1$d$;$e$\n"
   2617       "  $f$BAZ$g$ = $h$2$i$;$j$\n"
   2618       "}"));
   2619 
   2620   const EnumValueDescriptorProto& bar = file_.enum_type(0).value(0);
   2621   const EnumValueDescriptorProto& baz = file_.enum_type(0).value(1);
   2622 
   2623   EXPECT_TRUE(HasSpan('a', 'e', bar));
   2624   EXPECT_TRUE(HasSpan('a', 'b', bar, "name"));
   2625   EXPECT_TRUE(HasSpan('c', 'd', bar, "number"));
   2626   EXPECT_TRUE(HasSpan('f', 'j', baz));
   2627   EXPECT_TRUE(HasSpan('f', 'g', baz, "name"));
   2628   EXPECT_TRUE(HasSpan('h', 'i', baz, "number"));
   2629 
   2630   // Ignore these.
   2631   EXPECT_TRUE(HasSpan(file_));
   2632   EXPECT_TRUE(HasSpan(file_.enum_type(0)));
   2633   EXPECT_TRUE(HasSpan(file_.enum_type(0), "name"));
   2634 }
   2635 
   2636 TEST_F(SourceInfoTest, NestedEnums) {
   2637   EXPECT_TRUE(Parse(
   2638       "message Foo {\n"
   2639       "  $a$enum $b$Bar$c$ {}$d$\n"
   2640       "  $e$enum $f$Baz$g$ {}$h$\n"
   2641       "}\n"));
   2642 
   2643   const EnumDescriptorProto& bar = file_.message_type(0).enum_type(0);
   2644   const EnumDescriptorProto& baz = file_.message_type(0).enum_type(1);
   2645 
   2646   EXPECT_TRUE(HasSpan('a', 'd', bar));
   2647   EXPECT_TRUE(HasSpan('b', 'c', bar, "name"));
   2648   EXPECT_TRUE(HasSpan('e', 'h', baz));
   2649   EXPECT_TRUE(HasSpan('f', 'g', baz, "name"));
   2650 
   2651   // Ignore these.
   2652   EXPECT_TRUE(HasSpan(file_));
   2653   EXPECT_TRUE(HasSpan(file_.message_type(0)));
   2654   EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
   2655 }
   2656 
   2657 TEST_F(SourceInfoTest, Services) {
   2658   EXPECT_TRUE(Parse(
   2659       "$a$service $b$Foo$c$ {}$d$\n"
   2660       "$e$service $f$Bar$g$ {}$h$\n"));
   2661 
   2662   EXPECT_TRUE(HasSpan('a', 'd', file_.service(0)));
   2663   EXPECT_TRUE(HasSpan('b', 'c', file_.service(0), "name"));
   2664   EXPECT_TRUE(HasSpan('e', 'h', file_.service(1)));
   2665   EXPECT_TRUE(HasSpan('f', 'g', file_.service(1), "name"));
   2666 
   2667   // Ignore these.
   2668   EXPECT_TRUE(HasSpan(file_));
   2669 }
   2670 
   2671 TEST_F(SourceInfoTest, MethodsAndStreams) {
   2672   EXPECT_TRUE(Parse(
   2673       "service Foo {\n"
   2674       "  $a$rpc $b$Bar$c$($d$X$e$) returns($f$Y$g$);$h$"
   2675       "  $i$rpc $j$Baz$k$($l$Z$m$) returns($n$W$o$);$p$"
   2676       "}"));
   2677 
   2678   const MethodDescriptorProto& bar = file_.service(0).method(0);
   2679   const MethodDescriptorProto& baz = file_.service(0).method(1);
   2680 
   2681   EXPECT_TRUE(HasSpan('a', 'h', bar));
   2682   EXPECT_TRUE(HasSpan('b', 'c', bar, "name"));
   2683   EXPECT_TRUE(HasSpan('d', 'e', bar, "input_type"));
   2684   EXPECT_TRUE(HasSpan('f', 'g', bar, "output_type"));
   2685 
   2686   EXPECT_TRUE(HasSpan('i', 'p', baz));
   2687   EXPECT_TRUE(HasSpan('j', 'k', baz, "name"));
   2688   EXPECT_TRUE(HasSpan('l', 'm', baz, "input_type"));
   2689   EXPECT_TRUE(HasSpan('n', 'o', baz, "output_type"));
   2690 
   2691   // Ignore these.
   2692   EXPECT_TRUE(HasSpan(file_));
   2693   EXPECT_TRUE(HasSpan(file_.service(0)));
   2694   EXPECT_TRUE(HasSpan(file_.service(0), "name"));
   2695 }
   2696 
   2697 
   2698 TEST_F(SourceInfoTest, Options) {
   2699   EXPECT_TRUE(Parse(
   2700       "$a$option $b$foo$c$.$d$($e$bar.baz$f$)$g$ = "
   2701           "$h$123$i$;$j$\n"
   2702       "$k$option qux = $l$-123$m$;$n$\n"
   2703       "$o$option corge = $p$abc$q$;$r$\n"
   2704       "$s$option grault = $t$'blah'$u$;$v$\n"
   2705       "$w$option garply = $x${ yadda yadda }$y$;$z$\n"
   2706       "$0$option waldo = $1$123.0$2$;$3$\n"
   2707   ));
   2708 
   2709   const UninterpretedOption& option1 = file_.options().uninterpreted_option(0);
   2710   const UninterpretedOption& option2 = file_.options().uninterpreted_option(1);
   2711   const UninterpretedOption& option3 = file_.options().uninterpreted_option(2);
   2712   const UninterpretedOption& option4 = file_.options().uninterpreted_option(3);
   2713   const UninterpretedOption& option5 = file_.options().uninterpreted_option(4);
   2714   const UninterpretedOption& option6 = file_.options().uninterpreted_option(5);
   2715 
   2716   EXPECT_TRUE(HasSpan('a', 'j', file_.options()));
   2717   EXPECT_TRUE(HasSpan('a', 'j', option1));
   2718   EXPECT_TRUE(HasSpan('b', 'g', option1, "name"));
   2719   EXPECT_TRUE(HasSpan('b', 'c', option1.name(0)));
   2720   EXPECT_TRUE(HasSpan('b', 'c', option1.name(0), "name_part"));
   2721   EXPECT_TRUE(HasSpan('d', 'g', option1.name(1)));
   2722   EXPECT_TRUE(HasSpan('e', 'f', option1.name(1), "name_part"));
   2723   EXPECT_TRUE(HasSpan('h', 'i', option1, "positive_int_value"));
   2724 
   2725   EXPECT_TRUE(HasSpan('k', 'n', file_.options()));
   2726   EXPECT_TRUE(HasSpan('l', 'm', option2, "negative_int_value"));
   2727 
   2728   EXPECT_TRUE(HasSpan('o', 'r', file_.options()));
   2729   EXPECT_TRUE(HasSpan('p', 'q', option3, "identifier_value"));
   2730 
   2731   EXPECT_TRUE(HasSpan('s', 'v', file_.options()));
   2732   EXPECT_TRUE(HasSpan('t', 'u', option4, "string_value"));
   2733 
   2734   EXPECT_TRUE(HasSpan('w', 'z', file_.options()));
   2735   EXPECT_TRUE(HasSpan('x', 'y', option5, "aggregate_value"));
   2736 
   2737   EXPECT_TRUE(HasSpan('0', '3', file_.options()));
   2738   EXPECT_TRUE(HasSpan('1', '2', option6, "double_value"));
   2739 
   2740   // Ignore these.
   2741   EXPECT_TRUE(HasSpan(file_));
   2742   EXPECT_TRUE(HasSpan(option2));
   2743   EXPECT_TRUE(HasSpan(option3));
   2744   EXPECT_TRUE(HasSpan(option4));
   2745   EXPECT_TRUE(HasSpan(option5));
   2746   EXPECT_TRUE(HasSpan(option6));
   2747   EXPECT_TRUE(HasSpan(option2, "name"));
   2748   EXPECT_TRUE(HasSpan(option3, "name"));
   2749   EXPECT_TRUE(HasSpan(option4, "name"));
   2750   EXPECT_TRUE(HasSpan(option5, "name"));
   2751   EXPECT_TRUE(HasSpan(option6, "name"));
   2752   EXPECT_TRUE(HasSpan(option2.name(0)));
   2753   EXPECT_TRUE(HasSpan(option3.name(0)));
   2754   EXPECT_TRUE(HasSpan(option4.name(0)));
   2755   EXPECT_TRUE(HasSpan(option5.name(0)));
   2756   EXPECT_TRUE(HasSpan(option6.name(0)));
   2757   EXPECT_TRUE(HasSpan(option2.name(0), "name_part"));
   2758   EXPECT_TRUE(HasSpan(option3.name(0), "name_part"));
   2759   EXPECT_TRUE(HasSpan(option4.name(0), "name_part"));
   2760   EXPECT_TRUE(HasSpan(option5.name(0), "name_part"));
   2761   EXPECT_TRUE(HasSpan(option6.name(0), "name_part"));
   2762 }
   2763 
   2764 TEST_F(SourceInfoTest, ScopedOptions) {
   2765   EXPECT_TRUE(Parse(
   2766     "message Foo {\n"
   2767     "  $a$option mopt = 1;$b$\n"
   2768     "}\n"
   2769     "enum Bar {\n"
   2770     "  $c$option eopt = 1;$d$\n"
   2771     "}\n"
   2772     "service Baz {\n"
   2773     "  $e$option sopt = 1;$f$\n"
   2774     "  rpc M(X) returns(Y) {\n"
   2775     "    $g$option mopt = 1;$h$\n"
   2776     "  }\n"
   2777     "  rpc MS4($1$stream$2$ X) returns($3$stream$4$ Y) {\n"
   2778     "    $k$option mopt = 1;$l$\n"
   2779     "  }\n"
   2780     "}\n"));
   2781 
   2782   EXPECT_TRUE(HasSpan('a', 'b', file_.message_type(0).options()));
   2783   EXPECT_TRUE(HasSpan('c', 'd', file_.enum_type(0).options()));
   2784   EXPECT_TRUE(HasSpan('e', 'f', file_.service(0).options()));
   2785   EXPECT_TRUE(HasSpan('g', 'h', file_.service(0).method(0).options()));
   2786 
   2787   // Ignore these.
   2788   EXPECT_TRUE(HasSpan(file_));
   2789   EXPECT_TRUE(HasSpan(file_.message_type(0)));
   2790   EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
   2791   EXPECT_TRUE(HasSpan(file_.message_type(0).options()
   2792                       .uninterpreted_option(0)));
   2793   EXPECT_TRUE(HasSpan(file_.message_type(0).options()
   2794                       .uninterpreted_option(0), "name"));
   2795   EXPECT_TRUE(HasSpan(file_.message_type(0).options()
   2796                       .uninterpreted_option(0).name(0)));
   2797   EXPECT_TRUE(HasSpan(file_.message_type(0).options()
   2798                       .uninterpreted_option(0).name(0), "name_part"));
   2799   EXPECT_TRUE(HasSpan(file_.message_type(0).options()
   2800                       .uninterpreted_option(0), "positive_int_value"));
   2801   EXPECT_TRUE(HasSpan(file_.enum_type(0)));
   2802   EXPECT_TRUE(HasSpan(file_.enum_type(0), "name"));
   2803   EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
   2804                       .uninterpreted_option(0)));
   2805   EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
   2806                       .uninterpreted_option(0), "name"));
   2807   EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
   2808                       .uninterpreted_option(0).name(0)));
   2809   EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
   2810                       .uninterpreted_option(0).name(0), "name_part"));
   2811   EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
   2812                       .uninterpreted_option(0), "positive_int_value"));
   2813   EXPECT_TRUE(HasSpan(file_.service(0)));
   2814   EXPECT_TRUE(HasSpan(file_.service(0), "name"));
   2815   EXPECT_TRUE(HasSpan(file_.service(0).method(0)));
   2816   EXPECT_TRUE(HasSpan(file_.service(0).options()
   2817                       .uninterpreted_option(0)));
   2818   EXPECT_TRUE(HasSpan(file_.service(0).options()
   2819                       .uninterpreted_option(0), "name"));
   2820   EXPECT_TRUE(HasSpan(file_.service(0).options()
   2821                       .uninterpreted_option(0).name(0)));
   2822   EXPECT_TRUE(HasSpan(file_.service(0).options()
   2823                       .uninterpreted_option(0).name(0), "name_part"));
   2824   EXPECT_TRUE(HasSpan(file_.service(0).options()
   2825                       .uninterpreted_option(0), "positive_int_value"));
   2826   EXPECT_TRUE(HasSpan(file_.service(0).method(0), "name"));
   2827   EXPECT_TRUE(HasSpan(file_.service(0).method(0), "input_type"));
   2828   EXPECT_TRUE(HasSpan(file_.service(0).method(0), "output_type"));
   2829   EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
   2830                       .uninterpreted_option(0)));
   2831   EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
   2832                       .uninterpreted_option(0), "name"));
   2833   EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
   2834                       .uninterpreted_option(0).name(0)));
   2835   EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
   2836                       .uninterpreted_option(0).name(0), "name_part"));
   2837   EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
   2838                       .uninterpreted_option(0), "positive_int_value"));
   2839 
   2840   EXPECT_TRUE(HasSpan('k', 'l', file_.service(0).method(1).options()));
   2841   EXPECT_TRUE(HasSpan(file_.service(0).method(1)));
   2842   EXPECT_TRUE(HasSpan(file_.service(0).method(1), "name"));
   2843   EXPECT_TRUE(HasSpan(file_.service(0).method(1), "input_type"));
   2844   EXPECT_TRUE(HasSpan(file_.service(0).method(1), "output_type"));
   2845   EXPECT_TRUE(HasSpan(file_.service(0).method(1).options()
   2846                       .uninterpreted_option(0)));
   2847   EXPECT_TRUE(HasSpan(file_.service(0).method(1).options()
   2848                       .uninterpreted_option(0), "name"));
   2849   EXPECT_TRUE(HasSpan(file_.service(0).method(1).options()
   2850                       .uninterpreted_option(0).name(0)));
   2851   EXPECT_TRUE(HasSpan(file_.service(0).method(1).options()
   2852                       .uninterpreted_option(0).name(0), "name_part"));
   2853   EXPECT_TRUE(HasSpan(file_.service(0).method(1).options()
   2854                       .uninterpreted_option(0), "positive_int_value"));
   2855   EXPECT_TRUE(HasSpan('1', '2', file_.service(0).method(1),
   2856                       "client_streaming"));
   2857   EXPECT_TRUE(HasSpan('3', '4', file_.service(0).method(1),
   2858                       "server_streaming"));
   2859 }
   2860 
   2861 TEST_F(SourceInfoTest, FieldOptions) {
   2862   // The actual "name = value" pairs are parsed by the same code as for
   2863   // top-level options so we won't re-test that -- just make sure that the
   2864   // syntax used for field options is understood.
   2865   EXPECT_TRUE(Parse(
   2866       "message Foo {"
   2867       "  optional int32 bar = 1 "
   2868           "$a$[default=$b$123$c$,$d$opt1=123$e$,"
   2869           "$f$opt2='hi'$g$]$h$;"
   2870       "}\n"
   2871   ));
   2872 
   2873   const FieldDescriptorProto& field = file_.message_type(0).field(0);
   2874   const UninterpretedOption& option1 = field.options().uninterpreted_option(0);
   2875   const UninterpretedOption& option2 = field.options().uninterpreted_option(1);
   2876 
   2877   EXPECT_TRUE(HasSpan('a', 'h', field.options()));
   2878   EXPECT_TRUE(HasSpan('b', 'c', field, "default_value"));
   2879   EXPECT_TRUE(HasSpan('d', 'e', option1));
   2880   EXPECT_TRUE(HasSpan('f', 'g', option2));
   2881 
   2882   // Ignore these.
   2883   EXPECT_TRUE(HasSpan(file_));
   2884   EXPECT_TRUE(HasSpan(file_.message_type(0)));
   2885   EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
   2886   EXPECT_TRUE(HasSpan(field));
   2887   EXPECT_TRUE(HasSpan(field, "label"));
   2888   EXPECT_TRUE(HasSpan(field, "type"));
   2889   EXPECT_TRUE(HasSpan(field, "name"));
   2890   EXPECT_TRUE(HasSpan(field, "number"));
   2891   EXPECT_TRUE(HasSpan(option1, "name"));
   2892   EXPECT_TRUE(HasSpan(option2, "name"));
   2893   EXPECT_TRUE(HasSpan(option1.name(0)));
   2894   EXPECT_TRUE(HasSpan(option2.name(0)));
   2895   EXPECT_TRUE(HasSpan(option1.name(0), "name_part"));
   2896   EXPECT_TRUE(HasSpan(option2.name(0), "name_part"));
   2897   EXPECT_TRUE(HasSpan(option1, "positive_int_value"));
   2898   EXPECT_TRUE(HasSpan(option2, "string_value"));
   2899 }
   2900 
   2901 TEST_F(SourceInfoTest, EnumValueOptions) {
   2902   // The actual "name = value" pairs are parsed by the same code as for
   2903   // top-level options so we won't re-test that -- just make sure that the
   2904   // syntax used for enum options is understood.
   2905   EXPECT_TRUE(Parse(
   2906       "enum Foo {"
   2907       "  BAR = 1 $a$[$b$opt1=123$c$,$d$opt2='hi'$e$]$f$;"
   2908       "}\n"
   2909   ));
   2910 
   2911   const EnumValueDescriptorProto& value = file_.enum_type(0).value(0);
   2912   const UninterpretedOption& option1 = value.options().uninterpreted_option(0);
   2913   const UninterpretedOption& option2 = value.options().uninterpreted_option(1);
   2914 
   2915   EXPECT_TRUE(HasSpan('a', 'f', value.options()));
   2916   EXPECT_TRUE(HasSpan('b', 'c', option1));
   2917   EXPECT_TRUE(HasSpan('d', 'e', option2));
   2918 
   2919   // Ignore these.
   2920   EXPECT_TRUE(HasSpan(file_));
   2921   EXPECT_TRUE(HasSpan(file_.enum_type(0)));
   2922   EXPECT_TRUE(HasSpan(file_.enum_type(0), "name"));
   2923   EXPECT_TRUE(HasSpan(value));
   2924   EXPECT_TRUE(HasSpan(value, "name"));
   2925   EXPECT_TRUE(HasSpan(value, "number"));
   2926   EXPECT_TRUE(HasSpan(option1, "name"));
   2927   EXPECT_TRUE(HasSpan(option2, "name"));
   2928   EXPECT_TRUE(HasSpan(option1.name(0)));
   2929   EXPECT_TRUE(HasSpan(option2.name(0)));
   2930   EXPECT_TRUE(HasSpan(option1.name(0), "name_part"));
   2931   EXPECT_TRUE(HasSpan(option2.name(0), "name_part"));
   2932   EXPECT_TRUE(HasSpan(option1, "positive_int_value"));
   2933   EXPECT_TRUE(HasSpan(option2, "string_value"));
   2934 }
   2935 
   2936 TEST_F(SourceInfoTest, DocComments) {
   2937   EXPECT_TRUE(Parse(
   2938       "// Foo leading\n"
   2939       "// line 2\n"
   2940       "$a$message Foo {\n"
   2941       "  // Foo trailing\n"
   2942       "  // line 2\n"
   2943       "\n"
   2944       "  // detached\n"
   2945       "\n"
   2946       "  // bar leading\n"
   2947       "  $b$optional int32 bar = 1;$c$\n"
   2948       "  // bar trailing\n"
   2949       "}$d$\n"
   2950       "// ignored\n"
   2951   ));
   2952 
   2953   const DescriptorProto& foo = file_.message_type(0);
   2954   const FieldDescriptorProto& bar = foo.field(0);
   2955 
   2956   EXPECT_TRUE(HasSpanWithComment('a', 'd', foo,
   2957       " Foo leading\n line 2\n",
   2958       " Foo trailing\n line 2\n",
   2959       NULL));
   2960   EXPECT_TRUE(HasSpanWithComment('b', 'c', bar,
   2961       " bar leading\n",
   2962       " bar trailing\n",
   2963       " detached\n"));
   2964 
   2965   // Ignore these.
   2966   EXPECT_TRUE(HasSpan(file_));
   2967   EXPECT_TRUE(HasSpan(foo, "name"));
   2968   EXPECT_TRUE(HasSpan(bar, "label"));
   2969   EXPECT_TRUE(HasSpan(bar, "type"));
   2970   EXPECT_TRUE(HasSpan(bar, "name"));
   2971   EXPECT_TRUE(HasSpan(bar, "number"));
   2972 }
   2973 
   2974 TEST_F(SourceInfoTest, DocComments2) {
   2975   EXPECT_TRUE(Parse(
   2976       "// detached before message.\n"
   2977       "\n"
   2978       "// Foo leading\n"
   2979       "// line 2\n"
   2980       "$a$message Foo {\n"
   2981       "  /* Foo trailing\n"
   2982       "   * line 2 */\n"
   2983       "  // detached\n"
   2984       "  /* bar leading\n"
   2985       "   */"
   2986       "  $b$optional int32 bar = 1;$c$  // bar trailing\n"
   2987       "  // ignored detached\n"
   2988       "}$d$\n"
   2989       "// ignored\n"
   2990       "\n"
   2991       "// detached before option\n"
   2992       "\n"
   2993       "// option leading\n"
   2994       "$e$option baz = 123;$f$\n"
   2995       "// option trailing\n"
   2996   ));
   2997 
   2998   const DescriptorProto& foo = file_.message_type(0);
   2999   const FieldDescriptorProto& bar = foo.field(0);
   3000   const UninterpretedOption& baz = file_.options().uninterpreted_option(0);
   3001 
   3002   EXPECT_TRUE(HasSpanWithComment('a', 'd', foo,
   3003       " Foo leading\n line 2\n",
   3004       " Foo trailing\n line 2 ",
   3005       " detached before message.\n"));
   3006   EXPECT_TRUE(HasSpanWithComment('b', 'c', bar,
   3007       " bar leading\n",
   3008       " bar trailing\n",
   3009       " detached\n"));
   3010   EXPECT_TRUE(HasSpanWithComment('e', 'f', baz,
   3011       " option leading\n",
   3012       " option trailing\n",
   3013       " detached before option\n"));
   3014 
   3015   // Ignore these.
   3016   EXPECT_TRUE(HasSpan(file_));
   3017   EXPECT_TRUE(HasSpan(foo, "name"));
   3018   EXPECT_TRUE(HasSpan(bar, "label"));
   3019   EXPECT_TRUE(HasSpan(bar, "type"));
   3020   EXPECT_TRUE(HasSpan(bar, "name"));
   3021   EXPECT_TRUE(HasSpan(bar, "number"));
   3022   EXPECT_TRUE(HasSpan(file_.options()));
   3023   EXPECT_TRUE(HasSpan(baz, "name"));
   3024   EXPECT_TRUE(HasSpan(baz.name(0)));
   3025   EXPECT_TRUE(HasSpan(baz.name(0), "name_part"));
   3026   EXPECT_TRUE(HasSpan(baz, "positive_int_value"));
   3027 }
   3028 
   3029 TEST_F(SourceInfoTest, DocComments3) {
   3030   EXPECT_TRUE(Parse(
   3031       "$a$message Foo {\n"
   3032       "  // bar leading\n"
   3033       "  $b$optional int32 bar = 1 [(baz.qux) = {}];$c$\n"
   3034       "  // bar trailing\n"
   3035       "}$d$\n"
   3036       "// ignored\n"
   3037   ));
   3038 
   3039   const DescriptorProto& foo = file_.message_type(0);
   3040   const FieldDescriptorProto& bar = foo.field(0);
   3041 
   3042   EXPECT_TRUE(HasSpanWithComment('b', 'c', bar,
   3043       " bar leading\n",
   3044       " bar trailing\n",
   3045       NULL));
   3046 
   3047   // Ignore these.
   3048   EXPECT_TRUE(HasSpan(file_));
   3049   EXPECT_TRUE(HasSpan(foo));
   3050   EXPECT_TRUE(HasSpan(foo, "name"));
   3051   EXPECT_TRUE(HasSpan(bar, "label"));
   3052   EXPECT_TRUE(HasSpan(bar, "type"));
   3053   EXPECT_TRUE(HasSpan(bar, "name"));
   3054   EXPECT_TRUE(HasSpan(bar, "number"));
   3055   EXPECT_TRUE(HasSpan(bar.options()));
   3056   EXPECT_TRUE(HasSpan(bar.options().uninterpreted_option(0)));
   3057   EXPECT_TRUE(HasSpan(bar.options().uninterpreted_option(0), "name"));
   3058   EXPECT_TRUE(HasSpan(bar.options().uninterpreted_option(0).name(0)));
   3059   EXPECT_TRUE(HasSpan(
   3060       bar.options().uninterpreted_option(0).name(0), "name_part"));
   3061   EXPECT_TRUE(HasSpan(
   3062       bar.options().uninterpreted_option(0), "aggregate_value"));
   3063 }
   3064 
   3065 TEST_F(SourceInfoTest, DocCommentsTopLevel) {
   3066   EXPECT_TRUE(Parse(
   3067       "// detached before syntax paragraph 1\n"
   3068       "\n"
   3069       "// detached before syntax paragraph 2\n"
   3070       "\n"
   3071       "// syntax leading\n"
   3072       "$a$syntax = \"proto2\";$b$\n"
   3073       "// syntax trailing\n"
   3074       "\n"
   3075       "// syntax-package detached comments\n"
   3076       "\n"
   3077       ";\n"
   3078       "\n"
   3079       "// detached after empty before package\n"
   3080       "\n"
   3081       "// package leading\n"
   3082       "package $c$foo$d$;\n"
   3083       "// package trailing\n"
   3084       "\n"
   3085       "// ignored detach\n"
   3086       "\n"));
   3087 
   3088   EXPECT_TRUE(HasSpan('a', 'b', file_, "syntax", -1,
   3089       " syntax leading\n",
   3090       " syntax trailing\n",
   3091       " detached before syntax paragraph 1\n"
   3092       "\n"
   3093       " detached before syntax paragraph 2\n"));
   3094   EXPECT_TRUE(HasSpan('c', 'd', file_, "package", -1,
   3095       " package leading\n",
   3096       " package trailing\n",
   3097       " syntax-package detached comments\n"
   3098       "\n"
   3099       " detached after empty before package\n"));
   3100 
   3101   // ignore these.
   3102   EXPECT_TRUE(HasSpan(file_));
   3103 }
   3104 
   3105 TEST_F(SourceInfoTest, DocCommentsOneof) {
   3106   EXPECT_TRUE(Parse(
   3107       "// Foo leading\n"
   3108       "$a$message Foo {\n"
   3109       "  /* Foo trailing\n"
   3110       "   */\n"
   3111       "  // detached before oneof\n"
   3112       "  /* bar leading\n"
   3113       "   * line 2 */\n"
   3114       "  $b$oneof bar {\n"
   3115       "  /* bar trailing\n"
   3116       "   * line 2 */\n"
   3117       "  // detached before bar_int\n"
   3118       "  /* bar_int leading\n"
   3119       "   */\n"
   3120       "  $c$int32 bar_int = 1;$d$  // bar_int trailing\n"
   3121       "  // detach comment ignored\n"
   3122       "  }$e$\n"
   3123       "}$f$\n"));
   3124 
   3125   const DescriptorProto& foo = file_.message_type(0);
   3126   const OneofDescriptorProto& bar = foo.oneof_decl(0);
   3127   const FieldDescriptorProto& bar_int = foo.field(0);
   3128 
   3129   EXPECT_TRUE(HasSpanWithComment('a', 'f', foo,
   3130       " Foo leading\n",
   3131       " Foo trailing\n",
   3132       NULL));
   3133   EXPECT_TRUE(HasSpanWithComment('b', 'e', bar,
   3134       " bar leading\n line 2 ",
   3135       " bar trailing\n line 2 ",
   3136       " detached before oneof\n"));
   3137   EXPECT_TRUE(HasSpanWithComment('c', 'd', bar_int,
   3138       " bar_int leading\n",
   3139       " bar_int trailing\n",
   3140       " detached before bar_int\n"));
   3141 
   3142   // Ignore these.
   3143   EXPECT_TRUE(HasSpan(file_));
   3144   EXPECT_TRUE(HasSpan(foo, "name"));
   3145   EXPECT_TRUE(HasSpan(bar, "name"));
   3146   EXPECT_TRUE(HasSpan(bar_int, "type"));
   3147   EXPECT_TRUE(HasSpan(bar_int, "name"));
   3148   EXPECT_TRUE(HasSpan(bar_int, "number"));
   3149 }
   3150 
   3151 // ===================================================================
   3152 
   3153 }  // anonymous namespace
   3154 
   3155 }  // namespace compiler
   3156 }  // namespace protobuf
   3157 }  // namespace google
   3158