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