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