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