Line data Source code
1 : // Protocol Buffers - Google's data interchange format
2 : // Copyright 2008 Google Inc. All rights reserved.
3 : // https://developers.google.com/protocol-buffers/
4 : //
5 : // Redistribution and use in source and binary forms, with or without
6 : // modification, are permitted provided that the following conditions are
7 : // met:
8 : //
9 : // * Redistributions of source code must retain the above copyright
10 : // notice, this list of conditions and the following disclaimer.
11 : // * Redistributions in binary form must reproduce the above
12 : // copyright notice, this list of conditions and the following disclaimer
13 : // in the documentation and/or other materials provided with the
14 : // distribution.
15 : // * Neither the name of Google Inc. nor the names of its
16 : // contributors may be used to endorse or promote products derived from
17 : // this software without specific prior written permission.
18 : //
19 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 :
31 : // Author: kenton@google.com (Kenton Varda)
32 : // Based on original Protocol Buffers design by
33 : // Sanjay Ghemawat, Jeff Dean, and others.
34 : //
35 : // Recursive descent FTW.
36 :
37 : #include <float.h>
38 : #include <google/protobuf/stubs/hash.h>
39 : #include <limits>
40 :
41 :
42 : #include <google/protobuf/compiler/parser.h>
43 : #include <google/protobuf/descriptor.h>
44 : #include <google/protobuf/descriptor.pb.h>
45 : #include <google/protobuf/wire_format.h>
46 : #include <google/protobuf/io/tokenizer.h>
47 : #include <google/protobuf/stubs/logging.h>
48 : #include <google/protobuf/stubs/common.h>
49 : #include <google/protobuf/stubs/strutil.h>
50 : #include <google/protobuf/stubs/map_util.h>
51 :
52 : namespace google {
53 : namespace protobuf {
54 : namespace compiler {
55 :
56 : using internal::WireFormat;
57 :
58 : namespace {
59 :
60 : typedef hash_map<string, FieldDescriptorProto::Type> TypeNameMap;
61 :
62 17 : TypeNameMap MakeTypeNameTable() {
63 17 : TypeNameMap result;
64 :
65 34 : result["double" ] = FieldDescriptorProto::TYPE_DOUBLE;
66 34 : result["float" ] = FieldDescriptorProto::TYPE_FLOAT;
67 34 : result["uint64" ] = FieldDescriptorProto::TYPE_UINT64;
68 34 : result["fixed64" ] = FieldDescriptorProto::TYPE_FIXED64;
69 34 : result["fixed32" ] = FieldDescriptorProto::TYPE_FIXED32;
70 34 : result["bool" ] = FieldDescriptorProto::TYPE_BOOL;
71 34 : result["string" ] = FieldDescriptorProto::TYPE_STRING;
72 34 : result["group" ] = FieldDescriptorProto::TYPE_GROUP;
73 :
74 34 : result["bytes" ] = FieldDescriptorProto::TYPE_BYTES;
75 34 : result["uint32" ] = FieldDescriptorProto::TYPE_UINT32;
76 34 : result["sfixed32"] = FieldDescriptorProto::TYPE_SFIXED32;
77 34 : result["sfixed64"] = FieldDescriptorProto::TYPE_SFIXED64;
78 34 : result["int32" ] = FieldDescriptorProto::TYPE_INT32;
79 34 : result["int64" ] = FieldDescriptorProto::TYPE_INT64;
80 34 : result["sint32" ] = FieldDescriptorProto::TYPE_SINT32;
81 34 : result["sint64" ] = FieldDescriptorProto::TYPE_SINT64;
82 :
83 17 : return result;
84 : }
85 :
86 17 : const TypeNameMap kTypeNames = MakeTypeNameTable();
87 :
88 : // Camel-case the field name and append "Entry" for generated map entry name.
89 : // e.g. map<KeyType, ValueType> foo_map => FooMapEntry
90 124 : string MapEntryName(const string& field_name) {
91 : string result;
92 : static const char kSuffix[] = "Entry";
93 124 : result.reserve(field_name.size() + sizeof(kSuffix));
94 : bool cap_next = true;
95 3716 : for (int i = 0; i < field_name.size(); ++i) {
96 3592 : if (field_name[i] == '_') {
97 : cap_next = true;
98 1593 : } else if (cap_next) {
99 : // Note: Do not use ctype.h due to locales.
100 327 : if ('a' <= field_name[i] && field_name[i] <= 'z') {
101 327 : result.push_back(field_name[i] - 'a' + 'A');
102 : } else {
103 0 : result.push_back(field_name[i]);
104 : }
105 : cap_next = false;
106 : } else {
107 1266 : result.push_back(field_name[i]);
108 : }
109 : }
110 124 : result.append(kSuffix);
111 124 : return result;
112 : }
113 :
114 : } // anonymous namespace
115 :
116 : // Makes code slightly more readable. The meaning of "DO(foo)" is
117 : // "Execute foo and fail if it fails.", where failure is indicated by
118 : // returning false.
119 : #define DO(STATEMENT) if (STATEMENT) {} else return false
120 :
121 : // ===================================================================
122 :
123 78 : Parser::Parser()
124 : : input_(NULL),
125 : error_collector_(NULL),
126 : source_location_table_(NULL),
127 : had_errors_(false),
128 : require_syntax_identifier_(false),
129 234 : stop_after_syntax_identifier_(false) {
130 78 : }
131 :
132 156 : Parser::~Parser() {
133 78 : }
134 :
135 : // ===================================================================
136 :
137 : inline bool Parser::LookingAt(const char* text) {
138 64670 : return input_->current().text == text;
139 : }
140 :
141 : inline bool Parser::LookingAtType(io::Tokenizer::TokenType token_type) {
142 16684 : return input_->current().type == token_type;
143 : }
144 :
145 4481 : inline bool Parser::AtEnd() {
146 4481 : return LookingAtType(io::Tokenizer::TYPE_END);
147 : }
148 :
149 23462 : bool Parser::TryConsume(const char* text) {
150 46924 : if (LookingAt(text)) {
151 13774 : input_->Next();
152 13774 : return true;
153 : } else {
154 : return false;
155 : }
156 : }
157 :
158 3368 : bool Parser::Consume(const char* text, const char* error) {
159 3368 : if (TryConsume(text)) {
160 : return true;
161 : } else {
162 0 : AddError(error);
163 0 : return false;
164 : }
165 : }
166 :
167 7510 : bool Parser::Consume(const char* text) {
168 7510 : if (TryConsume(text)) {
169 : return true;
170 : } else {
171 0 : AddError("Expected \"" + string(text) + "\".");
172 0 : return false;
173 : }
174 : }
175 :
176 6085 : bool Parser::ConsumeIdentifier(string* output, const char* error) {
177 12170 : if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
178 6085 : *output = input_->current().text;
179 6085 : input_->Next();
180 6085 : return true;
181 : } else {
182 0 : AddError(error);
183 0 : return false;
184 : }
185 : }
186 :
187 3068 : bool Parser::ConsumeInteger(int* output, const char* error) {
188 6136 : if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
189 3068 : uint64 value = 0;
190 6136 : if (!io::Tokenizer::ParseInteger(input_->current().text,
191 3068 : kint32max, &value)) {
192 0 : AddError("Integer out of range.");
193 : // We still return true because we did, in fact, parse an integer.
194 : }
195 3068 : *output = value;
196 3068 : input_->Next();
197 : return true;
198 : } else {
199 0 : AddError(error);
200 0 : return false;
201 : }
202 : }
203 :
204 259 : bool Parser::ConsumeSignedInteger(int* output, const char* error) {
205 259 : bool is_negative = false;
206 259 : uint64 max_value = kint32max;
207 259 : if (TryConsume("-")) {
208 6 : is_negative = true;
209 6 : max_value += 1;
210 : }
211 259 : uint64 value = 0;
212 259 : DO(ConsumeInteger64(max_value, &value, error));
213 259 : if (is_negative) value *= -1;
214 259 : *output = value;
215 259 : return true;
216 : }
217 :
218 371 : bool Parser::ConsumeInteger64(uint64 max_value, uint64* output,
219 371 : const char* error) {
220 742 : if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
221 742 : if (!io::Tokenizer::ParseInteger(input_->current().text, max_value,
222 371 : output)) {
223 0 : AddError("Integer out of range.");
224 : // We still return true because we did, in fact, parse an integer.
225 0 : *output = 0;
226 : }
227 371 : input_->Next();
228 371 : return true;
229 : } else {
230 0 : AddError(error);
231 0 : return false;
232 : }
233 : }
234 :
235 27 : bool Parser::ConsumeNumber(double* output, const char* error) {
236 50 : if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) {
237 16 : *output = io::Tokenizer::ParseFloat(input_->current().text);
238 16 : input_->Next();
239 16 : return true;
240 18 : } else if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
241 : // Also accept integers.
242 3 : uint64 value = 0;
243 6 : if (!io::Tokenizer::ParseInteger(input_->current().text,
244 3 : kuint64max, &value)) {
245 0 : AddError("Integer out of range.");
246 : // We still return true because we did, in fact, parse a number.
247 : }
248 3 : *output = value;
249 3 : input_->Next();
250 : return true;
251 12 : } else if (LookingAt("inf")) {
252 4 : *output = numeric_limits<double>::infinity();
253 4 : input_->Next();
254 4 : return true;
255 4 : } else if (LookingAt("nan")) {
256 2 : *output = numeric_limits<double>::quiet_NaN();
257 2 : input_->Next();
258 2 : return true;
259 : } else {
260 0 : AddError(error);
261 0 : return false;
262 : }
263 : }
264 :
265 2484 : bool Parser::ConsumeString(string* output, const char* error) {
266 2484 : if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
267 1242 : io::Tokenizer::ParseString(input_->current().text, output);
268 1242 : input_->Next();
269 : // Allow C++ like concatenation of adjacent string tokens.
270 3726 : while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
271 0 : io::Tokenizer::ParseStringAppend(input_->current().text, output);
272 0 : input_->Next();
273 : }
274 : return true;
275 : } else {
276 0 : AddError(error);
277 0 : return false;
278 : }
279 : }
280 :
281 12470 : bool Parser::TryConsumeEndOfDeclaration(
282 12470 : const char* text, const LocationRecorder* location) {
283 24940 : if (LookingAt(text)) {
284 : string leading, trailing;
285 5042 : vector<string> detached;
286 5042 : input_->NextWithComments(&trailing, &detached, &leading);
287 :
288 : // Save the leading comments for next time, and recall the leading comments
289 : // from last time.
290 5042 : leading.swap(upcoming_doc_comments_);
291 :
292 5042 : if (location != NULL) {
293 4394 : upcoming_detached_comments_.swap(detached);
294 4394 : location->AttachComments(&leading, &trailing, &detached);
295 648 : } else if (strcmp(text, "}") == 0) {
296 : // If the current location is null and we are finishing the current scope,
297 : // drop pending upcoming detached comments.
298 637 : upcoming_detached_comments_.swap(detached);
299 : } else {
300 : // Otherwise, append the new detached comments to the existing upcoming
301 : // detached comments.
302 : upcoming_detached_comments_.insert(upcoming_detached_comments_.end(),
303 22 : detached.begin(), detached.end());
304 : }
305 :
306 : return true;
307 : } else {
308 : return false;
309 : }
310 : }
311 :
312 4394 : bool Parser::ConsumeEndOfDeclaration(
313 : const char* text, const LocationRecorder* location) {
314 4394 : if (TryConsumeEndOfDeclaration(text, location)) {
315 : return true;
316 : } else {
317 0 : AddError("Expected \"" + string(text) + "\".");
318 0 : return false;
319 : }
320 : }
321 :
322 : // -------------------------------------------------------------------
323 :
324 0 : void Parser::AddError(int line, int column, const string& error) {
325 0 : if (error_collector_ != NULL) {
326 0 : error_collector_->AddError(line, column, error);
327 : }
328 0 : had_errors_ = true;
329 0 : }
330 :
331 0 : void Parser::AddError(const string& error) {
332 0 : AddError(input_->current().line, input_->current().column, error);
333 0 : }
334 :
335 : // -------------------------------------------------------------------
336 :
337 78 : Parser::LocationRecorder::LocationRecorder(Parser* parser)
338 : : parser_(parser),
339 156 : location_(parser_->source_code_info_->add_location()) {
340 78 : location_->add_span(parser_->input_->current().line);
341 78 : location_->add_span(parser_->input_->current().column);
342 78 : }
343 :
344 3463 : Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent) {
345 3463 : Init(parent);
346 3463 : }
347 :
348 15167 : Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent,
349 : int path1) {
350 15167 : Init(parent);
351 15167 : AddPath(path1);
352 15167 : }
353 :
354 4132 : Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent,
355 : int path1, int path2) {
356 4132 : Init(parent);
357 4132 : AddPath(path1);
358 4132 : AddPath(path2);
359 4132 : }
360 :
361 22762 : void Parser::LocationRecorder::Init(const LocationRecorder& parent) {
362 22762 : parser_ = parent.parser_;
363 45524 : location_ = parser_->source_code_info_->add_location();
364 22762 : location_->mutable_path()->CopyFrom(parent.location_->path());
365 :
366 22762 : location_->add_span(parser_->input_->current().line);
367 22762 : location_->add_span(parser_->input_->current().column);
368 22762 : }
369 :
370 22840 : Parser::LocationRecorder::~LocationRecorder() {
371 45680 : if (location_->span_size() <= 2) {
372 22391 : EndAt(parser_->input_->previous());
373 : }
374 22840 : }
375 :
376 26921 : void Parser::LocationRecorder::AddPath(int path_component) {
377 26921 : location_->add_path(path_component);
378 26921 : }
379 :
380 312 : void Parser::LocationRecorder::StartAt(const io::Tokenizer::Token& token) {
381 312 : location_->set_span(0, token.line);
382 312 : location_->set_span(1, token.column);
383 312 : }
384 :
385 27 : void Parser::LocationRecorder::StartAt(const LocationRecorder& other) {
386 54 : location_->set_span(0, other.location_->span(0));
387 54 : location_->set_span(1, other.location_->span(1));
388 27 : }
389 :
390 22840 : void Parser::LocationRecorder::EndAt(const io::Tokenizer::Token& token) {
391 45680 : if (token.line != location_->span(0)) {
392 1537 : location_->add_span(token.line);
393 : }
394 22840 : location_->add_span(token.end_column);
395 22840 : }
396 :
397 12526 : void Parser::LocationRecorder::RecordLegacyLocation(const Message* descriptor,
398 : DescriptorPool::ErrorCollector::ErrorLocation location) {
399 12526 : if (parser_->source_location_table_ != NULL) {
400 : parser_->source_location_table_->Add(
401 37578 : descriptor, location, location_->span(0), location_->span(1));
402 : }
403 12526 : }
404 :
405 4394 : void Parser::LocationRecorder::AttachComments(
406 : string* leading, string* trailing,
407 9016 : vector<string>* detached_comments) const {
408 13182 : GOOGLE_CHECK(!location_->has_leading_comments());
409 13182 : GOOGLE_CHECK(!location_->has_trailing_comments());
410 :
411 4394 : if (!leading->empty()) {
412 647 : location_->mutable_leading_comments()->swap(*leading);
413 : }
414 4394 : if (!trailing->empty()) {
415 58 : location_->mutable_trailing_comments()->swap(*trailing);
416 : }
417 13638 : for (int i = 0; i < detached_comments->size(); ++i) {
418 : location_->add_leading_detached_comments()->swap(
419 342 : (*detached_comments)[i]);
420 : }
421 4394 : detached_comments->clear();
422 4394 : }
423 :
424 : // -------------------------------------------------------------------
425 :
426 0 : void Parser::SkipStatement() {
427 : while (true) {
428 0 : if (AtEnd()) {
429 : return;
430 0 : } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) {
431 0 : if (TryConsumeEndOfDeclaration(";", NULL)) {
432 : return;
433 0 : } else if (TryConsume("{")) {
434 0 : SkipRestOfBlock();
435 0 : return;
436 0 : } else if (LookingAt("}")) {
437 : return;
438 : }
439 : }
440 0 : input_->Next();
441 : }
442 : }
443 :
444 0 : void Parser::SkipRestOfBlock() {
445 : while (true) {
446 0 : if (AtEnd()) {
447 : return;
448 0 : } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) {
449 0 : if (TryConsumeEndOfDeclaration("}", NULL)) {
450 : return;
451 0 : } else if (TryConsume("{")) {
452 0 : SkipRestOfBlock();
453 : }
454 : }
455 0 : input_->Next();
456 : }
457 : }
458 :
459 : // ===================================================================
460 :
461 234 : bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) {
462 78 : input_ = input;
463 78 : had_errors_ = false;
464 78 : syntax_identifier_.clear();
465 :
466 : // Note that |file| could be NULL at this point if
467 : // stop_after_syntax_identifier_ is true. So, we conservatively allocate
468 : // SourceCodeInfo on the stack, then swap it into the FileDescriptorProto
469 : // later on.
470 78 : SourceCodeInfo source_code_info;
471 78 : source_code_info_ = &source_code_info;
472 :
473 78 : vector<string> top_doc_comments;
474 156 : if (LookingAtType(io::Tokenizer::TYPE_START)) {
475 : // Advance to first token.
476 : input_->NextWithComments(NULL, &upcoming_detached_comments_,
477 78 : &upcoming_doc_comments_);
478 : }
479 :
480 : {
481 78 : LocationRecorder root_location(this);
482 :
483 234 : if (require_syntax_identifier_ || LookingAt("syntax")) {
484 78 : if (!ParseSyntaxIdentifier(root_location)) {
485 : // Don't attempt to parse the file if we didn't recognize the syntax
486 : // identifier.
487 0 : return false;
488 : }
489 : // Store the syntax into the file.
490 78 : if (file != NULL) file->set_syntax(syntax_identifier_);
491 0 : } else if (!stop_after_syntax_identifier_) {
492 0 : GOOGLE_LOG(WARNING) << "No syntax specified for the proto file. "
493 0 : << "Please use 'syntax = \"proto2\";' or "
494 0 : << "'syntax = \"proto3\";' to specify a syntax "
495 0 : << "version. (Defaulted to proto2 syntax.)";
496 0 : syntax_identifier_ = "proto2";
497 : }
498 :
499 78 : if (stop_after_syntax_identifier_) return !had_errors_;
500 :
501 : // Repeatedly parse statements until we reach the end of the file.
502 847 : while (!AtEnd()) {
503 769 : if (!ParseTopLevelStatement(file, root_location)) {
504 : // This statement failed to parse. Skip it, but keep looping to parse
505 : // other statements.
506 0 : SkipStatement();
507 :
508 0 : if (LookingAt("}")) {
509 0 : AddError("Unmatched \"}\".");
510 : input_->NextWithComments(NULL, &upcoming_detached_comments_,
511 0 : &upcoming_doc_comments_);
512 : }
513 : }
514 78 : }
515 : }
516 :
517 78 : input_ = NULL;
518 78 : source_code_info_ = NULL;
519 78 : source_code_info.Swap(file->mutable_source_code_info());
520 156 : return !had_errors_;
521 : }
522 :
523 78 : bool Parser::ParseSyntaxIdentifier(const LocationRecorder& parent) {
524 : LocationRecorder syntax_location(parent,
525 78 : FileDescriptorProto::kSyntaxFieldNumber);
526 78 : DO(Consume(
527 : "syntax",
528 : "File must begin with a syntax statement, e.g. 'syntax = \"proto2\";'."));
529 78 : DO(Consume("="));
530 78 : io::Tokenizer::Token syntax_token = input_->current();
531 : string syntax;
532 78 : DO(ConsumeString(&syntax, "Expected syntax identifier."));
533 78 : DO(ConsumeEndOfDeclaration(";", &syntax_location));
534 :
535 78 : syntax_identifier_ = syntax;
536 :
537 130 : if (syntax != "proto2" && syntax != "proto3" &&
538 0 : !stop_after_syntax_identifier_) {
539 : AddError(syntax_token.line, syntax_token.column,
540 0 : "Unrecognized syntax identifier \"" + syntax + "\". This parser "
541 0 : "only recognizes \"proto2\" and \"proto3\".");
542 0 : return false;
543 : }
544 :
545 78 : return true;
546 : }
547 :
548 769 : bool Parser::ParseTopLevelStatement(FileDescriptorProto* file,
549 2322 : const LocationRecorder& root_location) {
550 769 : if (TryConsumeEndOfDeclaration(";", NULL)) {
551 : // empty statement; ignore
552 : return true;
553 1532 : } else if (LookingAt("message")) {
554 : LocationRecorder location(root_location,
555 394 : FileDescriptorProto::kMessageTypeFieldNumber, file->message_type_size());
556 394 : return ParseMessageDefinition(file->add_message_type(), location, file);
557 744 : } else if (LookingAt("enum")) {
558 : LocationRecorder location(root_location,
559 53 : FileDescriptorProto::kEnumTypeFieldNumber, file->enum_type_size());
560 53 : return ParseEnumDefinition(file->add_enum_type(), location, file);
561 638 : } else if (LookingAt("service")) {
562 : LocationRecorder location(root_location,
563 34 : FileDescriptorProto::kServiceFieldNumber, file->service_size());
564 34 : return ParseServiceDefinition(file->add_service(), location, file);
565 570 : } else if (LookingAt("extend")) {
566 : LocationRecorder location(root_location,
567 26 : FileDescriptorProto::kExtensionFieldNumber);
568 : return ParseExtend(file->mutable_extension(),
569 : file->mutable_message_type(),
570 : root_location,
571 : FileDescriptorProto::kMessageTypeFieldNumber,
572 26 : location, file);
573 518 : } else if (LookingAt("import")) {
574 : return ParseImport(file->mutable_dependency(),
575 : file->mutable_public_dependency(),
576 : file->mutable_weak_dependency(),
577 60 : root_location, file);
578 398 : } else if (LookingAt("package")) {
579 77 : return ParsePackage(file, root_location, file);
580 244 : } else if (LookingAt("option")) {
581 : LocationRecorder location(root_location,
582 122 : FileDescriptorProto::kOptionsFieldNumber);
583 122 : return ParseOption(file->mutable_options(), location, file,
584 122 : OPTION_STATEMENT);
585 : } else {
586 0 : AddError("Expected top-level statement (e.g. \"message\").");
587 0 : return false;
588 : }
589 : }
590 :
591 : // -------------------------------------------------------------------
592 : // Messages
593 :
594 425 : bool Parser::ParseMessageDefinition(
595 : DescriptorProto* message,
596 : const LocationRecorder& message_location,
597 : const FileDescriptorProto* containing_file) {
598 425 : DO(Consume("message"));
599 : {
600 : LocationRecorder location(message_location,
601 425 : DescriptorProto::kNameFieldNumber);
602 : location.RecordLegacyLocation(
603 425 : message, DescriptorPool::ErrorCollector::NAME);
604 425 : DO(ConsumeIdentifier(message->mutable_name(), "Expected message name."));
605 : }
606 425 : DO(ParseMessageBlock(message, message_location, containing_file));
607 425 : return true;
608 : }
609 :
610 : namespace {
611 :
612 : const int kMaxExtensionRangeSentinel = -1;
613 :
614 26 : bool IsMessageSetWireFormatMessage(const DescriptorProto& message) {
615 52 : const MessageOptions& options = message.options();
616 52 : for (int i = 0; i < options.uninterpreted_option_size(); ++i) {
617 2 : const UninterpretedOption& uninterpreted = options.uninterpreted_option(i);
618 4 : if (uninterpreted.name_size() == 1 &&
619 8 : uninterpreted.name(0).name_part() == "message_set_wire_format" &&
620 2 : uninterpreted.identifier_value() == "true") {
621 : return true;
622 : }
623 : }
624 : return false;
625 : }
626 :
627 : // Modifies any extension ranges that specified 'max' as the end of the
628 : // extension range, and sets them to the type-specific maximum. The actual max
629 : // tag number can only be determined after all options have been parsed.
630 26 : void AdjustExtensionRangesWithMaxEndNumber(DescriptorProto* message) {
631 26 : const bool is_message_set = IsMessageSetWireFormatMessage(*message);
632 : const int max_extension_number = is_message_set ?
633 : kint32max :
634 26 : FieldDescriptor::kMaxNumber + 1;
635 110 : for (int i = 0; i < message->extension_range_size(); ++i) {
636 29 : if (message->extension_range(i).end() == kMaxExtensionRangeSentinel) {
637 24 : message->mutable_extension_range(i)->set_end(max_extension_number);
638 : }
639 : }
640 26 : }
641 :
642 : } // namespace
643 :
644 452 : bool Parser::ParseMessageBlock(DescriptorProto* message,
645 : const LocationRecorder& message_location,
646 : const FileDescriptorProto* containing_file) {
647 452 : DO(ConsumeEndOfDeclaration("{", &message_location));
648 :
649 3303 : while (!TryConsumeEndOfDeclaration("}", NULL)) {
650 2851 : if (AtEnd()) {
651 0 : AddError("Reached end of input in message definition (missing '}').");
652 0 : return false;
653 : }
654 :
655 2851 : if (!ParseMessageStatement(message, message_location, containing_file)) {
656 : // This statement failed to parse. Skip it, but keep looping to parse
657 : // other statements.
658 0 : SkipStatement();
659 : }
660 : }
661 :
662 452 : if (message->extension_range_size() > 0) {
663 26 : AdjustExtensionRangesWithMaxEndNumber(message);
664 : }
665 : return true;
666 : }
667 :
668 2851 : bool Parser::ParseMessageStatement(DescriptorProto* message,
669 : const LocationRecorder& message_location,
670 19387 : const FileDescriptorProto* containing_file) {
671 2851 : if (TryConsumeEndOfDeclaration(";", NULL)) {
672 : // empty statement; ignore
673 : return true;
674 5686 : } else if (LookingAt("message")) {
675 : LocationRecorder location(message_location,
676 : DescriptorProto::kNestedTypeFieldNumber,
677 31 : message->nested_type_size());
678 : return ParseMessageDefinition(message->add_nested_type(), location,
679 31 : containing_file);
680 5624 : } else if (LookingAt("enum")) {
681 : LocationRecorder location(message_location,
682 : DescriptorProto::kEnumTypeFieldNumber,
683 24 : message->enum_type_size());
684 : return ParseEnumDefinition(message->add_enum_type(), location,
685 24 : containing_file);
686 5576 : } else if (LookingAt("extensions")) {
687 : LocationRecorder location(message_location,
688 29 : DescriptorProto::kExtensionRangeFieldNumber);
689 29 : return ParseExtensions(message, location, containing_file);
690 5518 : } else if (LookingAt("reserved")) {
691 2 : return ParseReserved(message, message_location);
692 5514 : } else if (LookingAt("extend")) {
693 : LocationRecorder location(message_location,
694 14 : DescriptorProto::kExtensionFieldNumber);
695 : return ParseExtend(message->mutable_extension(),
696 : message->mutable_nested_type(),
697 : message_location,
698 : DescriptorProto::kNestedTypeFieldNumber,
699 14 : location, containing_file);
700 5486 : } else if (LookingAt("option")) {
701 : LocationRecorder location(message_location,
702 58 : DescriptorProto::kOptionsFieldNumber);
703 58 : return ParseOption(message->mutable_options(), location,
704 58 : containing_file, OPTION_STATEMENT);
705 5370 : } else if (LookingAt("oneof")) {
706 30 : int oneof_index = message->oneof_decl_size();
707 : LocationRecorder oneof_location(message_location,
708 : DescriptorProto::kOneofDeclFieldNumber,
709 30 : oneof_index);
710 :
711 : return ParseOneof(message->add_oneof_decl(), message,
712 : oneof_index, oneof_location, message_location,
713 30 : containing_file);
714 : } else {
715 : LocationRecorder location(message_location,
716 : DescriptorProto::kFieldFieldNumber,
717 2655 : message->field_size());
718 : return ParseMessageField(message->add_field(),
719 : message->mutable_nested_type(),
720 : message_location,
721 : DescriptorProto::kNestedTypeFieldNumber,
722 : location,
723 5310 : containing_file);
724 : }
725 : }
726 :
727 2910 : bool Parser::ParseMessageField(FieldDescriptorProto* field,
728 : RepeatedPtrField<DescriptorProto>* messages,
729 : const LocationRecorder& parent_location,
730 : int location_field_number_for_nested_type,
731 : const LocationRecorder& field_location,
732 : const FileDescriptorProto* containing_file) {
733 : {
734 : LocationRecorder location(field_location,
735 2910 : FieldDescriptorProto::kLabelFieldNumber);
736 : FieldDescriptorProto::Label label;
737 2910 : if (ParseLabel(&label, containing_file)) {
738 2138 : field->set_label(label);
739 3763 : if (label == FieldDescriptorProto::LABEL_OPTIONAL &&
740 1625 : syntax_identifier_ == "proto3") {
741 : AddError(
742 : "Explicit 'optional' labels are disallowed in the Proto3 syntax. "
743 : "To define 'optional' fields in Proto3, simply remove the "
744 0 : "'optional' label, as fields are 'optional' by default.");
745 : }
746 2910 : }
747 : }
748 :
749 : return ParseMessageFieldNoLabel(field, messages, parent_location,
750 : location_field_number_for_nested_type,
751 : field_location,
752 2910 : containing_file);
753 : }
754 :
755 3031 : bool Parser::ParseMessageFieldNoLabel(
756 11224 : FieldDescriptorProto* field,
757 : RepeatedPtrField<DescriptorProto>* messages,
758 : const LocationRecorder& parent_location,
759 : int location_field_number_for_nested_type,
760 : const LocationRecorder& field_location,
761 151 : const FileDescriptorProto* containing_file) {
762 : MapField map_field;
763 : // Parse type.
764 : {
765 3031 : LocationRecorder location(field_location); // add path later
766 3031 : location.RecordLegacyLocation(field, DescriptorPool::ErrorCollector::TYPE);
767 :
768 3031 : bool type_parsed = false;
769 3031 : FieldDescriptorProto::Type type = FieldDescriptorProto::TYPE_INT32;
770 : string type_name;
771 :
772 : // Special case map field. We only treat the field as a map field if the
773 : // field type name starts with the word "map" with a following "<".
774 3031 : if (TryConsume("map")) {
775 248 : if (LookingAt("<")) {
776 124 : map_field.is_map_field = true;
777 : } else {
778 : // False positive
779 0 : type_parsed = true;
780 : type_name = "map";
781 : }
782 : }
783 3031 : if (map_field.is_map_field) {
784 248 : if (field->has_oneof_index()) {
785 0 : AddError("Map fields are not allowed in oneofs.");
786 0 : return false;
787 : }
788 248 : if (field->has_label()) {
789 : AddError(
790 : "Field labels (required/optional/repeated) are not allowed on "
791 0 : "map fields.");
792 0 : return false;
793 : }
794 248 : if (field->has_extendee()) {
795 0 : AddError("Map fields are not allowed to be extensions.");
796 0 : return false;
797 : }
798 : field->set_label(FieldDescriptorProto::LABEL_REPEATED);
799 124 : DO(Consume("<"));
800 124 : DO(ParseType(&map_field.key_type, &map_field.key_type_name));
801 124 : DO(Consume(","));
802 124 : DO(ParseType(&map_field.value_type, &map_field.value_type_name));
803 124 : DO(Consume(">"));
804 : // Defer setting of the type name of the map field until the
805 : // field name is parsed. Add the source location though.
806 124 : location.AddPath(FieldDescriptorProto::kTypeNameFieldNumber);
807 : } else {
808 : // Handle the case where no explicit label is given for a non-map field.
809 6462 : if (!field->has_label() && DefaultToOptionalFields()) {
810 : field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
811 : }
812 5814 : if (!field->has_label()) {
813 0 : AddError("Expected \"required\", \"optional\", or \"repeated\".");
814 : // We can actually reasonably recover here by just assuming the user
815 : // forgot the label altogether.
816 : field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
817 : }
818 :
819 : // Handle the case where the actual type is a message or enum named "map",
820 : // which we already consumed in the code above.
821 2907 : if (!type_parsed) {
822 2907 : DO(ParseType(&type, &type_name));
823 : }
824 2907 : if (type_name.empty()) {
825 2255 : location.AddPath(FieldDescriptorProto::kTypeFieldNumber);
826 2255 : field->set_type(type);
827 : } else {
828 652 : location.AddPath(FieldDescriptorProto::kTypeNameFieldNumber);
829 : field->set_type_name(type_name);
830 : }
831 3031 : }
832 : }
833 :
834 : // Parse name and '='.
835 3031 : io::Tokenizer::Token name_token = input_->current();
836 : {
837 : LocationRecorder location(field_location,
838 3031 : FieldDescriptorProto::kNameFieldNumber);
839 3031 : location.RecordLegacyLocation(field, DescriptorPool::ErrorCollector::NAME);
840 3031 : DO(ConsumeIdentifier(field->mutable_name(), "Expected field name."));
841 : }
842 3031 : DO(Consume("=", "Missing field number."));
843 :
844 : // Parse field number.
845 : {
846 : LocationRecorder location(field_location,
847 3031 : FieldDescriptorProto::kNumberFieldNumber);
848 : location.RecordLegacyLocation(
849 3031 : field, DescriptorPool::ErrorCollector::NUMBER);
850 : int number;
851 3031 : DO(ConsumeInteger(&number, "Expected field number."));
852 6062 : field->set_number(number);
853 : }
854 :
855 : // Parse options.
856 3031 : DO(ParseFieldOptions(field, field_location, containing_file));
857 :
858 : // Deal with groups.
859 10572 : if (field->has_type() && field->type() == FieldDescriptorProto::TYPE_GROUP) {
860 : // Awkward: Since a group declares both a message type and a field, we
861 : // have to create overlapping locations.
862 27 : LocationRecorder group_location(parent_location);
863 27 : group_location.StartAt(field_location);
864 27 : group_location.AddPath(location_field_number_for_nested_type);
865 27 : group_location.AddPath(messages->size());
866 :
867 27 : DescriptorProto* group = messages->Add();
868 27 : group->set_name(field->name());
869 :
870 : // Record name location to match the field name's location.
871 : {
872 : LocationRecorder location(group_location,
873 27 : DescriptorProto::kNameFieldNumber);
874 27 : location.StartAt(name_token);
875 27 : location.EndAt(name_token);
876 : location.RecordLegacyLocation(
877 27 : group, DescriptorPool::ErrorCollector::NAME);
878 : }
879 :
880 : // The field's type_name also comes from the name. Confusing!
881 : {
882 : LocationRecorder location(field_location,
883 27 : FieldDescriptorProto::kTypeNameFieldNumber);
884 27 : location.StartAt(name_token);
885 27 : location.EndAt(name_token);
886 : }
887 :
888 : // As a hack for backwards-compatibility, we force the group name to start
889 : // with a capital letter and lower-case the field name. New code should
890 : // not use groups; it should use nested messages.
891 81 : if (group->name()[0] < 'A' || 'Z' < group->name()[0]) {
892 : AddError(name_token.line, name_token.column,
893 0 : "Group names must start with a capital letter.");
894 : }
895 27 : LowerString(field->mutable_name());
896 :
897 27 : field->set_type_name(group->name());
898 54 : if (LookingAt("{")) {
899 27 : DO(ParseMessageBlock(group, group_location, containing_file));
900 : } else {
901 0 : AddError("Missing group body.");
902 0 : return false;
903 27 : }
904 : } else {
905 3004 : DO(ConsumeEndOfDeclaration(";", &field_location));
906 : }
907 :
908 : // Create a map entry type if this is a map field.
909 3031 : if (map_field.is_map_field) {
910 124 : GenerateMapEntry(map_field, field, messages);
911 : }
912 :
913 3031 : return true;
914 : }
915 :
916 124 : void Parser::GenerateMapEntry(const MapField& map_field,
917 124 : FieldDescriptorProto* field,
918 : RepeatedPtrField<DescriptorProto>* messages) {
919 124 : DescriptorProto* entry = messages->Add();
920 124 : string entry_name = MapEntryName(field->name());
921 : field->set_type_name(entry_name);
922 : entry->set_name(entry_name);
923 124 : entry->mutable_options()->set_map_entry(true);
924 124 : FieldDescriptorProto* key_field = entry->add_field();
925 124 : key_field->set_name("key");
926 : key_field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
927 : key_field->set_number(1);
928 248 : if (map_field.key_type_name.empty()) {
929 124 : key_field->set_type(map_field.key_type);
930 : } else {
931 0 : key_field->set_type_name(map_field.key_type_name);
932 : }
933 124 : FieldDescriptorProto* value_field = entry->add_field();
934 124 : value_field->set_name("value");
935 : value_field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
936 : value_field->set_number(2);
937 248 : if (map_field.value_type_name.empty()) {
938 77 : value_field->set_type(map_field.value_type);
939 : } else {
940 47 : value_field->set_type_name(map_field.value_type_name);
941 : }
942 : // Propagate the "enforce_utf8" option to key and value fields if they
943 : // are strings. This helps simplify the implementation of code generators
944 : // and also reflection-based parsing code.
945 : //
946 : // The following definition:
947 : // message Foo {
948 : // map<string, string> value = 1 [enforce_utf8 = false];
949 : // }
950 : // will be interpreted as:
951 : // message Foo {
952 : // message ValueEntry {
953 : // option map_entry = true;
954 : // string key = 1 [enforce_utf8 = false];
955 : // string value = 2 [enforce_utf8 = false];
956 : // }
957 : // repeated ValueEntry value = 1 [enforce_utf8 = false];
958 : // }
959 : //
960 : // TODO(xiaofeng): Remove this when the "enforce_utf8" option is removed
961 : // from protocol compiler.
962 372 : for (int i = 0; i < field->options().uninterpreted_option_size(); ++i) {
963 : const UninterpretedOption& option =
964 0 : field->options().uninterpreted_option(i);
965 0 : if (option.name_size() == 1 &&
966 0 : option.name(0).name_part() == "enforce_utf8" &&
967 0 : !option.name(0).is_extension()) {
968 0 : if (key_field->type() == FieldDescriptorProto::TYPE_STRING) {
969 : key_field->mutable_options()->add_uninterpreted_option()
970 0 : ->CopyFrom(option);
971 : }
972 0 : if (value_field->type() == FieldDescriptorProto::TYPE_STRING) {
973 : value_field->mutable_options()->add_uninterpreted_option()
974 0 : ->CopyFrom(option);
975 : }
976 : }
977 : }
978 124 : }
979 :
980 3031 : bool Parser::ParseFieldOptions(FieldDescriptorProto* field,
981 : const LocationRecorder& field_location,
982 4405 : const FileDescriptorProto* containing_file) {
983 6062 : if (!LookingAt("[")) return true;
984 :
985 : LocationRecorder location(field_location,
986 1359 : FieldDescriptorProto::kOptionsFieldNumber);
987 :
988 1359 : DO(Consume("["));
989 :
990 : // Parse field options.
991 1374 : do {
992 2748 : if (LookingAt("default")) {
993 : // We intentionally pass field_location rather than location here, since
994 : // the default value is not actually an option.
995 1160 : DO(ParseDefaultAssignment(field, field_location, containing_file));
996 : } else {
997 214 : DO(ParseOption(field->mutable_options(), location,
998 : containing_file, OPTION_ASSIGNMENT));
999 : }
1000 : } while (TryConsume(","));
1001 :
1002 1359 : DO(Consume("]"));
1003 1359 : return true;
1004 : }
1005 :
1006 1160 : bool Parser::ParseDefaultAssignment(
1007 3461 : FieldDescriptorProto* field,
1008 : const LocationRecorder& field_location,
1009 : const FileDescriptorProto* containing_file) {
1010 2320 : if (field->has_default_value()) {
1011 0 : AddError("Already set option \"default\".");
1012 : field->clear_default_value();
1013 : }
1014 :
1015 1160 : DO(Consume("default"));
1016 1160 : DO(Consume("="));
1017 :
1018 : LocationRecorder location(field_location,
1019 1160 : FieldDescriptorProto::kDefaultValueFieldNumber);
1020 : location.RecordLegacyLocation(
1021 1160 : field, DescriptorPool::ErrorCollector::DEFAULT_VALUE);
1022 1160 : string* default_value = field->mutable_default_value();
1023 :
1024 2320 : if (!field->has_type()) {
1025 : // The field has a type name, but we don't know if it is a message or an
1026 : // enum yet. (If it were a primitive type, |field| would have a type set
1027 : // already.) In this case, simply take the current string as the default
1028 : // value; we will catch the error later if it is not a valid enum value.
1029 : // (N.B. that we do not check whether the current token is an identifier:
1030 : // doing so throws strange errors when the user mistypes a primitive
1031 : // typename and we assume it's an enum. E.g.: "optional int foo = 1 [default
1032 : // = 42]". In such a case the fundamental error is really that "int" is not
1033 : // a type, not that "42" is not an identifier. See b/12533582.)
1034 19 : *default_value = input_->current().text;
1035 19 : input_->Next();
1036 : return true;
1037 : }
1038 :
1039 2282 : switch (field->type()) {
1040 : case FieldDescriptorProto::TYPE_INT32:
1041 : case FieldDescriptorProto::TYPE_INT64:
1042 : case FieldDescriptorProto::TYPE_SINT32:
1043 : case FieldDescriptorProto::TYPE_SINT64:
1044 : case FieldDescriptorProto::TYPE_SFIXED32:
1045 : case FieldDescriptorProto::TYPE_SFIXED64: {
1046 36 : uint64 max_value = kint64max;
1047 99 : if (field->type() == FieldDescriptorProto::TYPE_INT32 ||
1048 58 : field->type() == FieldDescriptorProto::TYPE_SINT32 ||
1049 22 : field->type() == FieldDescriptorProto::TYPE_SFIXED32) {
1050 19 : max_value = kint32max;
1051 : }
1052 :
1053 : // These types can be negative.
1054 36 : if (TryConsume("-")) {
1055 14 : default_value->append("-");
1056 : // Two's complement always has one more negative value than positive.
1057 14 : ++max_value;
1058 : }
1059 : // Parse the integer to verify that it is not out-of-range.
1060 : uint64 value;
1061 36 : DO(ConsumeInteger64(max_value, &value,
1062 : "Expected integer for field default value."));
1063 : // And stringify it again.
1064 72 : default_value->append(SimpleItoa(value));
1065 36 : break;
1066 : }
1067 :
1068 : case FieldDescriptorProto::TYPE_UINT32:
1069 : case FieldDescriptorProto::TYPE_UINT64:
1070 : case FieldDescriptorProto::TYPE_FIXED32:
1071 : case FieldDescriptorProto::TYPE_FIXED64: {
1072 22 : uint64 max_value = kuint64max;
1073 38 : if (field->type() == FieldDescriptorProto::TYPE_UINT32 ||
1074 16 : field->type() == FieldDescriptorProto::TYPE_FIXED32) {
1075 11 : max_value = kuint32max;
1076 : }
1077 :
1078 : // Numeric, not negative.
1079 22 : if (TryConsume("-")) {
1080 0 : AddError("Unsigned field can't have negative default value.");
1081 : }
1082 : // Parse the integer to verify that it is not out-of-range.
1083 : uint64 value;
1084 22 : DO(ConsumeInteger64(max_value, &value,
1085 : "Expected integer for field default value."));
1086 : // And stringify it again.
1087 44 : default_value->append(SimpleItoa(value));
1088 22 : break;
1089 : }
1090 :
1091 : case FieldDescriptorProto::TYPE_FLOAT:
1092 : case FieldDescriptorProto::TYPE_DOUBLE:
1093 : // These types can be negative.
1094 23 : if (TryConsume("-")) {
1095 5 : default_value->append("-");
1096 : }
1097 : // Parse the integer because we have to convert hex integers to decimal
1098 : // floats.
1099 : double value;
1100 23 : DO(ConsumeNumber(&value, "Expected number."));
1101 : // And stringify it again.
1102 46 : default_value->append(SimpleDtoa(value));
1103 23 : break;
1104 :
1105 : case FieldDescriptorProto::TYPE_BOOL:
1106 25 : if (TryConsume("true")) {
1107 5 : default_value->assign("true");
1108 20 : } else if (TryConsume("false")) {
1109 20 : default_value->assign("false");
1110 : } else {
1111 0 : AddError("Expected \"true\" or \"false\".");
1112 0 : return false;
1113 : }
1114 : break;
1115 :
1116 : case FieldDescriptorProto::TYPE_STRING:
1117 : // Note: When file opton java_string_check_utf8 is true, if a
1118 : // non-string representation (eg byte[]) is later supported, it must
1119 : // be checked for UTF-8-ness.
1120 1027 : DO(ConsumeString(default_value, "Expected string for field default "
1121 : "value."));
1122 : break;
1123 :
1124 : case FieldDescriptorProto::TYPE_BYTES:
1125 8 : DO(ConsumeString(default_value, "Expected string."));
1126 16 : *default_value = CEscape(*default_value);
1127 8 : break;
1128 :
1129 : case FieldDescriptorProto::TYPE_ENUM:
1130 0 : DO(ConsumeIdentifier(default_value, "Expected enum identifier for field "
1131 : "default value."));
1132 : break;
1133 :
1134 : case FieldDescriptorProto::TYPE_MESSAGE:
1135 : case FieldDescriptorProto::TYPE_GROUP:
1136 0 : AddError("Messages can't have default values.");
1137 0 : return false;
1138 : }
1139 :
1140 1160 : return true;
1141 : }
1142 :
1143 436 : bool Parser::ParseOptionNamePart(UninterpretedOption* uninterpreted_option,
1144 : const LocationRecorder& part_location,
1145 615 : const FileDescriptorProto* containing_file) {
1146 436 : UninterpretedOption::NamePart* name = uninterpreted_option->add_name();
1147 : string identifier; // We parse identifiers into this string.
1148 872 : if (LookingAt("(")) { // This is an extension.
1149 81 : DO(Consume("("));
1150 :
1151 : {
1152 : LocationRecorder location(
1153 81 : part_location, UninterpretedOption::NamePart::kNamePartFieldNumber);
1154 : // An extension name consists of dot-separated identifiers, and may begin
1155 : // with a dot.
1156 162 : if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
1157 77 : DO(ConsumeIdentifier(&identifier, "Expected identifier."));
1158 77 : name->mutable_name_part()->append(identifier);
1159 : }
1160 196 : while (LookingAt(".")) {
1161 17 : DO(Consume("."));
1162 17 : name->mutable_name_part()->append(".");
1163 17 : DO(ConsumeIdentifier(&identifier, "Expected identifier."));
1164 17 : name->mutable_name_part()->append(identifier);
1165 81 : }
1166 : }
1167 :
1168 81 : DO(Consume(")"));
1169 : name->set_is_extension(true);
1170 : } else { // This is a regular field.
1171 : LocationRecorder location(
1172 355 : part_location, UninterpretedOption::NamePart::kNamePartFieldNumber);
1173 355 : DO(ConsumeIdentifier(&identifier, "Expected identifier."));
1174 355 : name->mutable_name_part()->append(identifier);
1175 355 : name->set_is_extension(false);
1176 : }
1177 : return true;
1178 : }
1179 :
1180 80 : bool Parser::ParseUninterpretedBlock(string* value) {
1181 : // Note that enclosing braces are not added to *value.
1182 : // We do NOT use ConsumeEndOfStatement for this brace because it's delimiting
1183 : // an expression, not a block of statements.
1184 9 : DO(Consume("{"));
1185 : int brace_depth = 1;
1186 76 : while (!AtEnd()) {
1187 152 : if (LookingAt("{")) {
1188 5 : brace_depth++;
1189 142 : } else if (LookingAt("}")) {
1190 14 : brace_depth--;
1191 14 : if (brace_depth == 0) {
1192 9 : input_->Next();
1193 9 : return true;
1194 : }
1195 : }
1196 : // TODO(sanjay): Interpret line/column numbers to preserve formatting
1197 67 : if (!value->empty()) value->push_back(' ');
1198 67 : value->append(input_->current().text);
1199 67 : input_->Next();
1200 : }
1201 0 : AddError("Unexpected end of stream while parsing aggregate value.");
1202 0 : return false;
1203 : }
1204 :
1205 : // We don't interpret the option here. Instead we store it in an
1206 : // UninterpretedOption, to be interpreted later.
1207 405 : bool Parser::ParseOption(Message* options,
1208 : const LocationRecorder& options_location,
1209 : const FileDescriptorProto* containing_file,
1210 436 : OptionStyle style) {
1211 : // Create an entry in the uninterpreted_option field.
1212 405 : const FieldDescriptor* uninterpreted_option_field = options->GetDescriptor()->
1213 1215 : FindFieldByName("uninterpreted_option");
1214 0 : GOOGLE_CHECK(uninterpreted_option_field != NULL)
1215 810 : << "No field named \"uninterpreted_option\" in the Options proto.";
1216 :
1217 405 : const Reflection* reflection = options->GetReflection();
1218 :
1219 : LocationRecorder location(
1220 : options_location, uninterpreted_option_field->number(),
1221 810 : reflection->FieldSize(*options, uninterpreted_option_field));
1222 :
1223 405 : if (style == OPTION_STATEMENT) {
1224 188 : DO(Consume("option"));
1225 : }
1226 :
1227 : UninterpretedOption* uninterpreted_option = down_cast<UninterpretedOption*>(
1228 405 : options->GetReflection()->AddMessage(options,
1229 405 : uninterpreted_option_field));
1230 :
1231 : // Parse dot-separated name.
1232 : {
1233 : LocationRecorder name_location(location,
1234 405 : UninterpretedOption::kNameFieldNumber);
1235 : name_location.RecordLegacyLocation(
1236 405 : uninterpreted_option, DescriptorPool::ErrorCollector::OPTION_NAME);
1237 :
1238 : {
1239 : LocationRecorder part_location(name_location,
1240 405 : uninterpreted_option->name_size());
1241 405 : DO(ParseOptionNamePart(uninterpreted_option, part_location,
1242 405 : containing_file));
1243 : }
1244 :
1245 1277 : while (LookingAt(".")) {
1246 31 : DO(Consume("."));
1247 : LocationRecorder part_location(name_location,
1248 31 : uninterpreted_option->name_size());
1249 31 : DO(ParseOptionNamePart(uninterpreted_option, part_location,
1250 : containing_file));
1251 436 : }
1252 : }
1253 :
1254 405 : DO(Consume("="));
1255 :
1256 : {
1257 405 : LocationRecorder value_location(location);
1258 : value_location.RecordLegacyLocation(
1259 405 : uninterpreted_option, DescriptorPool::ErrorCollector::OPTION_VALUE);
1260 :
1261 : // All values are a single token, except for negative numbers, which consist
1262 : // of a single '-' symbol, followed by a positive number.
1263 405 : bool is_negative = TryConsume("-");
1264 :
1265 405 : switch (input_->current().type) {
1266 : case io::Tokenizer::TYPE_START:
1267 0 : GOOGLE_LOG(FATAL) << "Trying to read value before any tokens have been read.";
1268 0 : return false;
1269 :
1270 : case io::Tokenizer::TYPE_END:
1271 0 : AddError("Unexpected end of stream while parsing option value.");
1272 0 : return false;
1273 :
1274 : case io::Tokenizer::TYPE_IDENTIFIER: {
1275 : value_location.AddPath(
1276 273 : UninterpretedOption::kIdentifierValueFieldNumber);
1277 273 : if (is_negative) {
1278 0 : AddError("Invalid '-' symbol before identifier.");
1279 0 : return false;
1280 : }
1281 : string value;
1282 273 : DO(ConsumeIdentifier(&value, "Expected identifier."));
1283 : uninterpreted_option->set_identifier_value(value);
1284 : break;
1285 : }
1286 :
1287 : case io::Tokenizer::TYPE_INTEGER: {
1288 : uint64 value;
1289 : uint64 max_value =
1290 54 : is_negative ? static_cast<uint64>(kint64max) + 1 : kuint64max;
1291 54 : DO(ConsumeInteger64(max_value, &value, "Expected integer."));
1292 54 : if (is_negative) {
1293 : value_location.AddPath(
1294 12 : UninterpretedOption::kNegativeIntValueFieldNumber);
1295 : uninterpreted_option->set_negative_int_value(
1296 12 : -static_cast<int64>(value));
1297 : } else {
1298 : value_location.AddPath(
1299 42 : UninterpretedOption::kPositiveIntValueFieldNumber);
1300 42 : uninterpreted_option->set_positive_int_value(value);
1301 : }
1302 54 : break;
1303 : }
1304 :
1305 : case io::Tokenizer::TYPE_FLOAT: {
1306 2 : value_location.AddPath(UninterpretedOption::kDoubleValueFieldNumber);
1307 : double value;
1308 2 : DO(ConsumeNumber(&value, "Expected number."));
1309 2 : uninterpreted_option->set_double_value(is_negative ? -value : value);
1310 2 : break;
1311 : }
1312 :
1313 : case io::Tokenizer::TYPE_STRING: {
1314 67 : value_location.AddPath(UninterpretedOption::kStringValueFieldNumber);
1315 67 : if (is_negative) {
1316 0 : AddError("Invalid '-' symbol before string.");
1317 0 : return false;
1318 : }
1319 : string value;
1320 67 : DO(ConsumeString(&value, "Expected string."));
1321 : uninterpreted_option->set_string_value(value);
1322 : break;
1323 : }
1324 :
1325 : case io::Tokenizer::TYPE_SYMBOL:
1326 18 : if (LookingAt("{")) {
1327 : value_location.AddPath(
1328 9 : UninterpretedOption::kAggregateValueFieldNumber);
1329 9 : DO(ParseUninterpretedBlock(
1330 : uninterpreted_option->mutable_aggregate_value()));
1331 : } else {
1332 0 : AddError("Expected option value.");
1333 0 : return false;
1334 : }
1335 : break;
1336 405 : }
1337 : }
1338 :
1339 405 : if (style == OPTION_STATEMENT) {
1340 188 : DO(ConsumeEndOfDeclaration(";", &location));
1341 : }
1342 :
1343 405 : return true;
1344 : }
1345 :
1346 29 : bool Parser::ParseExtensions(DescriptorProto* message,
1347 : const LocationRecorder& extensions_location,
1348 : const FileDescriptorProto* containing_file) {
1349 : // Parse the declaration.
1350 29 : DO(Consume("extensions"));
1351 :
1352 29 : do {
1353 : // Note that kExtensionRangeFieldNumber was already pushed by the parent.
1354 : LocationRecorder location(extensions_location,
1355 29 : message->extension_range_size());
1356 :
1357 29 : DescriptorProto::ExtensionRange* range = message->add_extension_range();
1358 : location.RecordLegacyLocation(
1359 29 : range, DescriptorPool::ErrorCollector::NUMBER);
1360 :
1361 : int start, end;
1362 : io::Tokenizer::Token start_token;
1363 :
1364 : {
1365 : LocationRecorder start_location(
1366 29 : location, DescriptorProto::ExtensionRange::kStartFieldNumber);
1367 29 : start_token = input_->current();
1368 29 : DO(ConsumeInteger(&start, "Expected field number range."));
1369 : }
1370 :
1371 29 : if (TryConsume("to")) {
1372 : LocationRecorder end_location(
1373 28 : location, DescriptorProto::ExtensionRange::kEndFieldNumber);
1374 28 : if (TryConsume("max")) {
1375 : // Set to the sentinel value - 1 since we increment the value below.
1376 : // The actual value of the end of the range should be set with
1377 : // AdjustExtensionRangesWithMaxEndNumber.
1378 24 : end = kMaxExtensionRangeSentinel - 1;
1379 : } else {
1380 4 : DO(ConsumeInteger(&end, "Expected integer."));
1381 28 : }
1382 : } else {
1383 : LocationRecorder end_location(
1384 1 : location, DescriptorProto::ExtensionRange::kEndFieldNumber);
1385 1 : end_location.StartAt(start_token);
1386 1 : end_location.EndAt(start_token);
1387 1 : end = start;
1388 : }
1389 :
1390 : // Users like to specify inclusive ranges, but in code we like the end
1391 : // number to be exclusive.
1392 29 : ++end;
1393 :
1394 29 : range->set_start(start);
1395 58 : range->set_end(end);
1396 : } while (TryConsume(","));
1397 :
1398 29 : DO(ConsumeEndOfDeclaration(";", &extensions_location));
1399 29 : return true;
1400 : }
1401 :
1402 : // This is similar to extension range parsing, except that "max" is not
1403 : // supported, and accepts field name literals.
1404 2 : bool Parser::ParseReserved(DescriptorProto* message,
1405 2 : const LocationRecorder& message_location) {
1406 : // Parse the declaration.
1407 2 : DO(Consume("reserved"));
1408 4 : if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
1409 : LocationRecorder location(message_location,
1410 1 : DescriptorProto::kReservedNameFieldNumber);
1411 1 : return ParseReservedNames(message, location);
1412 : } else {
1413 : LocationRecorder location(message_location,
1414 1 : DescriptorProto::kReservedRangeFieldNumber);
1415 1 : return ParseReservedNumbers(message, location);
1416 : }
1417 : }
1418 :
1419 :
1420 1 : bool Parser::ParseReservedNames(DescriptorProto* message,
1421 : const LocationRecorder& parent_location) {
1422 2 : do {
1423 2 : LocationRecorder location(parent_location, message->reserved_name_size());
1424 2 : DO(ConsumeString(message->add_reserved_name(), "Expected field name."));
1425 : } while (TryConsume(","));
1426 1 : DO(ConsumeEndOfDeclaration(";", &parent_location));
1427 1 : return true;
1428 : }
1429 :
1430 1 : bool Parser::ParseReservedNumbers(DescriptorProto* message,
1431 : const LocationRecorder& parent_location) {
1432 1 : bool first = true;
1433 3 : do {
1434 3 : LocationRecorder location(parent_location, message->reserved_range_size());
1435 :
1436 3 : DescriptorProto::ReservedRange* range = message->add_reserved_range();
1437 : int start, end;
1438 : io::Tokenizer::Token start_token;
1439 : {
1440 : LocationRecorder start_location(
1441 3 : location, DescriptorProto::ReservedRange::kStartFieldNumber);
1442 3 : start_token = input_->current();
1443 3 : DO(ConsumeInteger(&start, (first ?
1444 : "Expected field name or number range." :
1445 3 : "Expected field number range.")));
1446 : }
1447 :
1448 3 : if (TryConsume("to")) {
1449 : LocationRecorder end_location(
1450 1 : location, DescriptorProto::ReservedRange::kEndFieldNumber);
1451 1 : DO(ConsumeInteger(&end, "Expected integer."));
1452 : } else {
1453 : LocationRecorder end_location(
1454 2 : location, DescriptorProto::ReservedRange::kEndFieldNumber);
1455 2 : end_location.StartAt(start_token);
1456 2 : end_location.EndAt(start_token);
1457 2 : end = start;
1458 : }
1459 :
1460 : // Users like to specify inclusive ranges, but in code we like the end
1461 : // number to be exclusive.
1462 3 : ++end;
1463 :
1464 3 : range->set_start(start);
1465 3 : range->set_end(end);
1466 6 : first = false;
1467 : } while (TryConsume(","));
1468 :
1469 1 : DO(ConsumeEndOfDeclaration(";", &parent_location));
1470 1 : return true;
1471 : }
1472 :
1473 40 : bool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
1474 : RepeatedPtrField<DescriptorProto>* messages,
1475 : const LocationRecorder& parent_location,
1476 : int location_field_number_for_nested_type,
1477 : const LocationRecorder& extend_location,
1478 : const FileDescriptorProto* containing_file) {
1479 40 : DO(Consume("extend"));
1480 :
1481 : // Parse the extendee type.
1482 40 : io::Tokenizer::Token extendee_start = input_->current();
1483 : string extendee;
1484 40 : DO(ParseUserDefinedType(&extendee));
1485 40 : io::Tokenizer::Token extendee_end = input_->previous();
1486 :
1487 : // Parse the block.
1488 40 : DO(ConsumeEndOfDeclaration("{", &extend_location));
1489 :
1490 : bool is_first = true;
1491 :
1492 255 : do {
1493 255 : if (AtEnd()) {
1494 0 : AddError("Reached end of input in extend definition (missing '}').");
1495 0 : return false;
1496 : }
1497 :
1498 : // Note that kExtensionFieldNumber was already pushed by the parent.
1499 255 : LocationRecorder location(extend_location, extensions->size());
1500 :
1501 255 : FieldDescriptorProto* field = extensions->Add();
1502 :
1503 : {
1504 : LocationRecorder extendee_location(
1505 255 : location, FieldDescriptorProto::kExtendeeFieldNumber);
1506 255 : extendee_location.StartAt(extendee_start);
1507 255 : extendee_location.EndAt(extendee_end);
1508 :
1509 255 : if (is_first) {
1510 : extendee_location.RecordLegacyLocation(
1511 40 : field, DescriptorPool::ErrorCollector::EXTENDEE);
1512 : is_first = false;
1513 255 : }
1514 : }
1515 :
1516 : field->set_extendee(extendee);
1517 :
1518 255 : if (!ParseMessageField(field, messages, parent_location,
1519 : location_field_number_for_nested_type,
1520 : location,
1521 255 : containing_file)) {
1522 : // This statement failed to parse. Skip it, but keep looping to parse
1523 : // other statements.
1524 0 : SkipStatement();
1525 255 : }
1526 255 : } while (!TryConsumeEndOfDeclaration("}", NULL));
1527 :
1528 : return true;
1529 : }
1530 :
1531 30 : bool Parser::ParseOneof(OneofDescriptorProto* oneof_decl,
1532 : DescriptorProto* containing_type,
1533 : int oneof_index,
1534 : const LocationRecorder& oneof_location,
1535 : const LocationRecorder& containing_type_location,
1536 242 : const FileDescriptorProto* containing_file) {
1537 30 : DO(Consume("oneof"));
1538 :
1539 : {
1540 : LocationRecorder name_location(oneof_location,
1541 30 : OneofDescriptorProto::kNameFieldNumber);
1542 30 : DO(ConsumeIdentifier(oneof_decl->mutable_name(), "Expected oneof name."));
1543 : }
1544 :
1545 30 : DO(ConsumeEndOfDeclaration("{", &oneof_location));
1546 :
1547 121 : do {
1548 121 : if (AtEnd()) {
1549 0 : AddError("Reached end of input in oneof definition (missing '}').");
1550 0 : return false;
1551 : }
1552 :
1553 : // Print a nice error if the user accidentally tries to place a label
1554 : // on an individual member of a oneof.
1555 363 : if (LookingAt("required") ||
1556 363 : LookingAt("optional") ||
1557 121 : LookingAt("repeated")) {
1558 : AddError("Fields in oneofs must not have labels (required / optional "
1559 0 : "/ repeated).");
1560 : // We can continue parsing here because we understand what the user
1561 : // meant. The error report will still make parsing fail overall.
1562 0 : input_->Next();
1563 : }
1564 :
1565 : LocationRecorder field_location(containing_type_location,
1566 : DescriptorProto::kFieldFieldNumber,
1567 121 : containing_type->field_size());
1568 :
1569 121 : FieldDescriptorProto* field = containing_type->add_field();
1570 : field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
1571 : field->set_oneof_index(oneof_index);
1572 :
1573 121 : if (!ParseMessageFieldNoLabel(field,
1574 : containing_type->mutable_nested_type(),
1575 : containing_type_location,
1576 : DescriptorProto::kNestedTypeFieldNumber,
1577 : field_location,
1578 121 : containing_file)) {
1579 : // This statement failed to parse. Skip it, but keep looping to parse
1580 : // other statements.
1581 0 : SkipStatement();
1582 121 : }
1583 121 : } while (!TryConsumeEndOfDeclaration("}", NULL));
1584 :
1585 : return true;
1586 : }
1587 :
1588 : // -------------------------------------------------------------------
1589 : // Enums
1590 :
1591 77 : bool Parser::ParseEnumDefinition(EnumDescriptorProto* enum_type,
1592 : const LocationRecorder& enum_location,
1593 : const FileDescriptorProto* containing_file) {
1594 77 : DO(Consume("enum"));
1595 :
1596 : {
1597 : LocationRecorder location(enum_location,
1598 77 : EnumDescriptorProto::kNameFieldNumber);
1599 : location.RecordLegacyLocation(
1600 77 : enum_type, DescriptorPool::ErrorCollector::NAME);
1601 77 : DO(ConsumeIdentifier(enum_type->mutable_name(), "Expected enum name."));
1602 : }
1603 :
1604 77 : DO(ParseEnumBlock(enum_type, enum_location, containing_file));
1605 77 : return true;
1606 : }
1607 :
1608 77 : bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type,
1609 : const LocationRecorder& enum_location,
1610 : const FileDescriptorProto* containing_file) {
1611 77 : DO(ConsumeEndOfDeclaration("{", &enum_location));
1612 :
1613 340 : while (!TryConsumeEndOfDeclaration("}", NULL)) {
1614 263 : if (AtEnd()) {
1615 0 : AddError("Reached end of input in enum definition (missing '}').");
1616 0 : return false;
1617 : }
1618 :
1619 263 : if (!ParseEnumStatement(enum_type, enum_location, containing_file)) {
1620 : // This statement failed to parse. Skip it, but keep looping to parse
1621 : // other statements.
1622 0 : SkipStatement();
1623 : }
1624 : }
1625 :
1626 : return true;
1627 : }
1628 :
1629 263 : bool Parser::ParseEnumStatement(EnumDescriptorProto* enum_type,
1630 : const LocationRecorder& enum_location,
1631 263 : const FileDescriptorProto* containing_file) {
1632 263 : if (TryConsumeEndOfDeclaration(";", NULL)) {
1633 : // empty statement; ignore
1634 : return true;
1635 526 : } else if (LookingAt("option")) {
1636 : LocationRecorder location(enum_location,
1637 4 : EnumDescriptorProto::kOptionsFieldNumber);
1638 4 : return ParseOption(enum_type->mutable_options(), location,
1639 4 : containing_file, OPTION_STATEMENT);
1640 : } else {
1641 : LocationRecorder location(enum_location,
1642 259 : EnumDescriptorProto::kValueFieldNumber, enum_type->value_size());
1643 259 : return ParseEnumConstant(enum_type->add_value(), location, containing_file);
1644 : }
1645 : }
1646 :
1647 259 : bool Parser::ParseEnumConstant(EnumValueDescriptorProto* enum_value,
1648 : const LocationRecorder& enum_value_location,
1649 : const FileDescriptorProto* containing_file) {
1650 : // Parse name.
1651 : {
1652 : LocationRecorder location(enum_value_location,
1653 259 : EnumValueDescriptorProto::kNameFieldNumber);
1654 : location.RecordLegacyLocation(
1655 259 : enum_value, DescriptorPool::ErrorCollector::NAME);
1656 259 : DO(ConsumeIdentifier(enum_value->mutable_name(),
1657 259 : "Expected enum constant name."));
1658 : }
1659 :
1660 259 : DO(Consume("=", "Missing numeric value for enum constant."));
1661 :
1662 : // Parse value.
1663 : {
1664 : LocationRecorder location(
1665 259 : enum_value_location, EnumValueDescriptorProto::kNumberFieldNumber);
1666 : location.RecordLegacyLocation(
1667 259 : enum_value, DescriptorPool::ErrorCollector::NUMBER);
1668 :
1669 : int number;
1670 259 : DO(ConsumeSignedInteger(&number, "Expected integer."));
1671 518 : enum_value->set_number(number);
1672 : }
1673 :
1674 259 : DO(ParseEnumConstantOptions(enum_value, enum_value_location,
1675 : containing_file));
1676 :
1677 259 : DO(ConsumeEndOfDeclaration(";", &enum_value_location));
1678 :
1679 259 : return true;
1680 : }
1681 :
1682 259 : bool Parser::ParseEnumConstantOptions(
1683 : EnumValueDescriptorProto* value,
1684 : const LocationRecorder& enum_value_location,
1685 259 : const FileDescriptorProto* containing_file) {
1686 518 : if (!LookingAt("[")) return true;
1687 :
1688 : LocationRecorder location(
1689 3 : enum_value_location, EnumValueDescriptorProto::kOptionsFieldNumber);
1690 :
1691 3 : DO(Consume("["));
1692 :
1693 3 : do {
1694 3 : DO(ParseOption(value->mutable_options(), location,
1695 : containing_file, OPTION_ASSIGNMENT));
1696 : } while (TryConsume(","));
1697 :
1698 3 : DO(Consume("]"));
1699 3 : return true;
1700 : }
1701 :
1702 : // -------------------------------------------------------------------
1703 : // Services
1704 :
1705 34 : bool Parser::ParseServiceDefinition(
1706 : ServiceDescriptorProto* service,
1707 : const LocationRecorder& service_location,
1708 : const FileDescriptorProto* containing_file) {
1709 34 : DO(Consume("service"));
1710 :
1711 : {
1712 : LocationRecorder location(service_location,
1713 34 : ServiceDescriptorProto::kNameFieldNumber);
1714 : location.RecordLegacyLocation(
1715 34 : service, DescriptorPool::ErrorCollector::NAME);
1716 34 : DO(ConsumeIdentifier(service->mutable_name(), "Expected service name."));
1717 : }
1718 :
1719 34 : DO(ParseServiceBlock(service, service_location, containing_file));
1720 34 : return true;
1721 : }
1722 :
1723 34 : bool Parser::ParseServiceBlock(ServiceDescriptorProto* service,
1724 : const LocationRecorder& service_location,
1725 : const FileDescriptorProto* containing_file) {
1726 34 : DO(ConsumeEndOfDeclaration("{", &service_location));
1727 :
1728 100 : while (!TryConsumeEndOfDeclaration("}", NULL)) {
1729 66 : if (AtEnd()) {
1730 0 : AddError("Reached end of input in service definition (missing '}').");
1731 0 : return false;
1732 : }
1733 :
1734 66 : if (!ParseServiceStatement(service, service_location, containing_file)) {
1735 : // This statement failed to parse. Skip it, but keep looping to parse
1736 : // other statements.
1737 0 : SkipStatement();
1738 : }
1739 : }
1740 :
1741 : return true;
1742 : }
1743 :
1744 66 : bool Parser::ParseServiceStatement(ServiceDescriptorProto* service,
1745 : const LocationRecorder& service_location,
1746 66 : const FileDescriptorProto* containing_file) {
1747 66 : if (TryConsumeEndOfDeclaration(";", NULL)) {
1748 : // empty statement; ignore
1749 : return true;
1750 132 : } else if (LookingAt("option")) {
1751 : LocationRecorder location(
1752 2 : service_location, ServiceDescriptorProto::kOptionsFieldNumber);
1753 2 : return ParseOption(service->mutable_options(), location,
1754 2 : containing_file, OPTION_STATEMENT);
1755 : } else {
1756 : LocationRecorder location(service_location,
1757 64 : ServiceDescriptorProto::kMethodFieldNumber, service->method_size());
1758 64 : return ParseServiceMethod(service->add_method(), location, containing_file);
1759 : }
1760 : }
1761 :
1762 64 : bool Parser::ParseServiceMethod(MethodDescriptorProto* method,
1763 : const LocationRecorder& method_location,
1764 192 : const FileDescriptorProto* containing_file) {
1765 64 : DO(Consume("rpc"));
1766 :
1767 : {
1768 : LocationRecorder location(method_location,
1769 64 : MethodDescriptorProto::kNameFieldNumber);
1770 : location.RecordLegacyLocation(
1771 64 : method, DescriptorPool::ErrorCollector::NAME);
1772 64 : DO(ConsumeIdentifier(method->mutable_name(), "Expected method name."));
1773 : }
1774 :
1775 : // Parse input type.
1776 64 : DO(Consume("("));
1777 : {
1778 128 : if (LookingAt("stream")) {
1779 : LocationRecorder location(
1780 22 : method_location, MethodDescriptorProto::kClientStreamingFieldNumber);
1781 : location.RecordLegacyLocation(
1782 22 : method, DescriptorPool::ErrorCollector::OTHER);
1783 : method->set_client_streaming(true);
1784 22 : DO(Consume("stream"));
1785 :
1786 : }
1787 : LocationRecorder location(method_location,
1788 64 : MethodDescriptorProto::kInputTypeFieldNumber);
1789 : location.RecordLegacyLocation(
1790 64 : method, DescriptorPool::ErrorCollector::INPUT_TYPE);
1791 64 : DO(ParseUserDefinedType(method->mutable_input_type()));
1792 : }
1793 64 : DO(Consume(")"));
1794 :
1795 : // Parse output type.
1796 64 : DO(Consume("returns"));
1797 64 : DO(Consume("("));
1798 : {
1799 128 : if (LookingAt("stream")) {
1800 : LocationRecorder location(
1801 22 : method_location, MethodDescriptorProto::kServerStreamingFieldNumber);
1802 : location.RecordLegacyLocation(
1803 22 : method, DescriptorPool::ErrorCollector::OTHER);
1804 22 : DO(Consume("stream"));
1805 22 : method->set_server_streaming(true);
1806 :
1807 : }
1808 : LocationRecorder location(method_location,
1809 64 : MethodDescriptorProto::kOutputTypeFieldNumber);
1810 : location.RecordLegacyLocation(
1811 64 : method, DescriptorPool::ErrorCollector::OUTPUT_TYPE);
1812 64 : DO(ParseUserDefinedType(method->mutable_output_type()));
1813 : }
1814 64 : DO(Consume(")"));
1815 :
1816 128 : if (LookingAt("{")) {
1817 : // Options!
1818 4 : DO(ParseMethodOptions(method_location, containing_file,
1819 : MethodDescriptorProto::kOptionsFieldNumber,
1820 : method->mutable_options()));
1821 : } else {
1822 60 : DO(ConsumeEndOfDeclaration(";", &method_location));
1823 : }
1824 :
1825 : return true;
1826 : }
1827 :
1828 :
1829 4 : bool Parser::ParseMethodOptions(const LocationRecorder& parent_location,
1830 : const FileDescriptorProto* containing_file,
1831 : const int optionsFieldNumber,
1832 : Message* mutable_options) {
1833 : // Options!
1834 4 : ConsumeEndOfDeclaration("{", &parent_location);
1835 10 : while (!TryConsumeEndOfDeclaration("}", NULL)) {
1836 2 : if (AtEnd()) {
1837 0 : AddError("Reached end of input in method options (missing '}').");
1838 0 : return false;
1839 : }
1840 :
1841 2 : if (TryConsumeEndOfDeclaration(";", NULL)) {
1842 : // empty statement; ignore
1843 : } else {
1844 : LocationRecorder location(parent_location,
1845 2 : optionsFieldNumber);
1846 2 : if (!ParseOption(mutable_options, location,
1847 2 : containing_file, OPTION_STATEMENT)) {
1848 : // This statement failed to parse. Skip it, but keep looping to
1849 : // parse other statements.
1850 0 : SkipStatement();
1851 2 : }
1852 : }
1853 : }
1854 :
1855 : return true;
1856 : }
1857 :
1858 : // -------------------------------------------------------------------
1859 :
1860 2910 : bool Parser::ParseLabel(FieldDescriptorProto::Label* label,
1861 : const FileDescriptorProto* containing_file) {
1862 2910 : if (TryConsume("optional")) {
1863 1625 : *label = FieldDescriptorProto::LABEL_OPTIONAL;
1864 1625 : return true;
1865 1285 : } else if (TryConsume("repeated")) {
1866 498 : *label = FieldDescriptorProto::LABEL_REPEATED;
1867 498 : return true;
1868 787 : } else if (TryConsume("required")) {
1869 15 : *label = FieldDescriptorProto::LABEL_REQUIRED;
1870 15 : return true;
1871 : }
1872 : return false;
1873 : }
1874 :
1875 3155 : bool Parser::ParseType(FieldDescriptorProto::Type* type,
1876 : string* type_name) {
1877 3155 : TypeNameMap::const_iterator iter = kTypeNames.find(input_->current().text);
1878 6310 : if (iter != kTypeNames.end()) {
1879 4912 : *type = iter->second;
1880 2456 : input_->Next();
1881 : } else {
1882 699 : DO(ParseUserDefinedType(type_name));
1883 : }
1884 : return true;
1885 : }
1886 :
1887 867 : bool Parser::ParseUserDefinedType(string* type_name) {
1888 : type_name->clear();
1889 :
1890 867 : TypeNameMap::const_iterator iter = kTypeNames.find(input_->current().text);
1891 1734 : if (iter != kTypeNames.end()) {
1892 : // Note: The only place enum types are allowed is for field types, but
1893 : // if we are parsing a field type then we would not get here because
1894 : // primitives are allowed there as well. So this error message doesn't
1895 : // need to account for enums.
1896 0 : AddError("Expected message type.");
1897 :
1898 : // Pretend to accept this type so that we can go on parsing.
1899 0 : *type_name = input_->current().text;
1900 0 : input_->Next();
1901 : return true;
1902 : }
1903 :
1904 : // A leading "." means the name is fully-qualified.
1905 867 : if (TryConsume(".")) type_name->append(".");
1906 :
1907 : // Consume the first part of the name.
1908 : string identifier;
1909 867 : DO(ConsumeIdentifier(&identifier, "Expected type name."));
1910 867 : type_name->append(identifier);
1911 :
1912 : // Consume more parts.
1913 1281 : while (TryConsume(".")) {
1914 414 : type_name->append(".");
1915 414 : DO(ConsumeIdentifier(&identifier, "Expected identifier."));
1916 414 : type_name->append(identifier);
1917 : }
1918 :
1919 : return true;
1920 : }
1921 :
1922 : // ===================================================================
1923 :
1924 77 : bool Parser::ParsePackage(FileDescriptorProto* file,
1925 : const LocationRecorder& root_location,
1926 : const FileDescriptorProto* containing_file) {
1927 154 : if (file->has_package()) {
1928 0 : AddError("Multiple package definitions.");
1929 : // Don't append the new package to the old one. Just replace it. Not
1930 : // that it really matters since this is an error anyway.
1931 : file->clear_package();
1932 : }
1933 :
1934 77 : DO(Consume("package"));
1935 :
1936 : {
1937 : LocationRecorder location(root_location,
1938 77 : FileDescriptorProto::kPackageFieldNumber);
1939 77 : location.RecordLegacyLocation(file, DescriptorPool::ErrorCollector::NAME);
1940 :
1941 : while (true) {
1942 : string identifier;
1943 162 : DO(ConsumeIdentifier(&identifier, "Expected identifier."));
1944 162 : file->mutable_package()->append(identifier);
1945 162 : if (!TryConsume(".")) break;
1946 85 : file->mutable_package()->append(".");
1947 : }
1948 :
1949 77 : location.EndAt(input_->previous());
1950 :
1951 77 : DO(ConsumeEndOfDeclaration(";", &location));
1952 : }
1953 :
1954 77 : return true;
1955 : }
1956 :
1957 60 : bool Parser::ParseImport(RepeatedPtrField<string>* dependency,
1958 2 : RepeatedField<int32>* public_dependency,
1959 0 : RepeatedField<int32>* weak_dependency,
1960 : const LocationRecorder& root_location,
1961 118 : const FileDescriptorProto* containing_file) {
1962 60 : DO(Consume("import"));
1963 120 : if (LookingAt("public")) {
1964 : LocationRecorder location(
1965 : root_location, FileDescriptorProto::kPublicDependencyFieldNumber,
1966 2 : public_dependency->size());
1967 2 : DO(Consume("public"));
1968 4 : *public_dependency->Add() = dependency->size();
1969 116 : } else if (LookingAt("weak")) {
1970 : LocationRecorder location(
1971 : root_location, FileDescriptorProto::kWeakDependencyFieldNumber,
1972 0 : weak_dependency->size());
1973 0 : DO(Consume("weak"));
1974 0 : *weak_dependency->Add() = dependency->size();
1975 : }
1976 : {
1977 : LocationRecorder location(root_location,
1978 : FileDescriptorProto::kDependencyFieldNumber,
1979 60 : dependency->size());
1980 60 : DO(ConsumeString(dependency->Add(),
1981 : "Expected a string naming the file to import."));
1982 :
1983 60 : location.EndAt(input_->previous());
1984 :
1985 60 : DO(ConsumeEndOfDeclaration(";", &location));
1986 : }
1987 60 : return true;
1988 : }
1989 :
1990 : // ===================================================================
1991 :
1992 34 : SourceLocationTable::SourceLocationTable() {}
1993 34 : SourceLocationTable::~SourceLocationTable() {}
1994 :
1995 0 : bool SourceLocationTable::Find(
1996 : const Message* descriptor,
1997 : DescriptorPool::ErrorCollector::ErrorLocation location,
1998 : int* line, int* column) const {
1999 : const pair<int, int>* result =
2000 0 : FindOrNull(location_map_, std::make_pair(descriptor, location));
2001 0 : if (result == NULL) {
2002 0 : *line = -1;
2003 0 : *column = 0;
2004 0 : return false;
2005 : } else {
2006 0 : *line = result->first;
2007 0 : *column = result->second;
2008 0 : return true;
2009 : }
2010 : }
2011 :
2012 12526 : void SourceLocationTable::Add(
2013 : const Message* descriptor,
2014 : DescriptorPool::ErrorCollector::ErrorLocation location,
2015 : int line, int column) {
2016 25052 : location_map_[std::make_pair(descriptor, location)] =
2017 12526 : std::make_pair(line, column);
2018 12526 : }
2019 :
2020 0 : void SourceLocationTable::Clear() {
2021 0 : location_map_.clear();
2022 0 : }
2023 :
2024 : } // namespace compiler
2025 : } // namespace protobuf
2026 51 : } // namespace google
|