1
// Protocol Buffers - Google's data interchange format
2
// Copyright 2008 Google Inc. All rights reserved.
3
// http://code.google.com/p/protobuf/
5
// Redistribution and use in source and binary forms, with or without
6
// modification, are permitted provided that the following conditions are
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
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.
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.
31
// Author: kenton@google.com (Kenton Varda)
32
// Based on original Protocol Buffers design by
33
// Sanjay Ghemawat, Jeff Dean, and others.
35
// Recursive descent FTW.
38
#include <google/protobuf/stubs/hash.h>
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/common.h>
48
#include <google/protobuf/stubs/strutil.h>
49
#include <google/protobuf/stubs/map-util.h>
55
using internal::WireFormat;
59
typedef hash_map<string, FieldDescriptorProto::Type> TypeNameMap;
61
TypeNameMap MakeTypeNameTable() {
64
result["double" ] = FieldDescriptorProto::TYPE_DOUBLE;
65
result["float" ] = FieldDescriptorProto::TYPE_FLOAT;
66
result["uint64" ] = FieldDescriptorProto::TYPE_UINT64;
67
result["fixed64" ] = FieldDescriptorProto::TYPE_FIXED64;
68
result["fixed32" ] = FieldDescriptorProto::TYPE_FIXED32;
69
result["bool" ] = FieldDescriptorProto::TYPE_BOOL;
70
result["string" ] = FieldDescriptorProto::TYPE_STRING;
71
result["group" ] = FieldDescriptorProto::TYPE_GROUP;
73
result["bytes" ] = FieldDescriptorProto::TYPE_BYTES;
74
result["uint32" ] = FieldDescriptorProto::TYPE_UINT32;
75
result["sfixed32"] = FieldDescriptorProto::TYPE_SFIXED32;
76
result["sfixed64"] = FieldDescriptorProto::TYPE_SFIXED64;
77
result["int32" ] = FieldDescriptorProto::TYPE_INT32;
78
result["int64" ] = FieldDescriptorProto::TYPE_INT64;
79
result["sint32" ] = FieldDescriptorProto::TYPE_SINT32;
80
result["sint64" ] = FieldDescriptorProto::TYPE_SINT64;
85
const TypeNameMap kTypeNames = MakeTypeNameTable();
87
} // anonymous namespace
89
// Makes code slightly more readable. The meaning of "DO(foo)" is
90
// "Execute foo and fail if it fails.", where failure is indicated by
92
#define DO(STATEMENT) if (STATEMENT) {} else return false
94
// ===================================================================
98
error_collector_(NULL),
99
source_location_table_(NULL),
101
require_syntax_identifier_(false),
102
stop_after_syntax_identifier_(false) {
108
// ===================================================================
110
inline bool Parser::LookingAt(const char* text) {
111
return input_->current().text == text;
114
inline bool Parser::LookingAtType(io::Tokenizer::TokenType token_type) {
115
return input_->current().type == token_type;
118
inline bool Parser::AtEnd() {
119
return LookingAtType(io::Tokenizer::TYPE_END);
122
bool Parser::TryConsume(const char* text) {
123
if (LookingAt(text)) {
131
bool Parser::Consume(const char* text, const char* error) {
132
if (TryConsume(text)) {
140
bool Parser::Consume(const char* text) {
141
if (TryConsume(text)) {
144
AddError("Expected \"" + string(text) + "\".");
149
bool Parser::ConsumeIdentifier(string* output, const char* error) {
150
if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
151
*output = input_->current().text;
160
bool Parser::ConsumeInteger(int* output, const char* error) {
161
if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
163
if (!io::Tokenizer::ParseInteger(input_->current().text,
164
kint32max, &value)) {
165
AddError("Integer out of range.");
166
// We still return true because we did, in fact, parse an integer.
177
bool Parser::ConsumeInteger64(uint64 max_value, uint64* output,
179
if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
180
if (!io::Tokenizer::ParseInteger(input_->current().text, max_value,
182
AddError("Integer out of range.");
183
// We still return true because we did, in fact, parse an integer.
194
bool Parser::ConsumeNumber(double* output, const char* error) {
195
if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) {
196
*output = io::Tokenizer::ParseFloat(input_->current().text);
199
} else if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
200
// Also accept integers.
202
if (!io::Tokenizer::ParseInteger(input_->current().text,
203
kuint64max, &value)) {
204
AddError("Integer out of range.");
205
// We still return true because we did, in fact, parse a number.
210
} else if (LookingAt("inf")) {
211
*output = numeric_limits<double>::infinity();
214
} else if (LookingAt("nan")) {
215
*output = numeric_limits<double>::quiet_NaN();
224
bool Parser::ConsumeString(string* output, const char* error) {
225
if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
226
io::Tokenizer::ParseString(input_->current().text, output);
228
// Allow C++ like concatenation of adjacent string tokens.
229
while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
230
io::Tokenizer::ParseStringAppend(input_->current().text, output);
240
// -------------------------------------------------------------------
242
void Parser::AddError(int line, int column, const string& error) {
243
if (error_collector_ != NULL) {
244
error_collector_->AddError(line, column, error);
249
void Parser::AddError(const string& error) {
250
AddError(input_->current().line, input_->current().column, error);
253
void Parser::RecordLocation(
254
const Message* descriptor,
255
DescriptorPool::ErrorCollector::ErrorLocation location,
256
int line, int column) {
257
if (source_location_table_ != NULL) {
258
source_location_table_->Add(descriptor, location, line, column);
262
void Parser::RecordLocation(
263
const Message* descriptor,
264
DescriptorPool::ErrorCollector::ErrorLocation location) {
265
RecordLocation(descriptor, location,
266
input_->current().line, input_->current().column);
269
// -------------------------------------------------------------------
271
void Parser::SkipStatement() {
275
} else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) {
276
if (TryConsume(";")) {
278
} else if (TryConsume("{")) {
281
} else if (LookingAt("}")) {
289
void Parser::SkipRestOfBlock() {
293
} else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) {
294
if (TryConsume("}")) {
296
} else if (TryConsume("{")) {
304
// ===================================================================
306
bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) {
309
syntax_identifier_.clear();
311
if (LookingAtType(io::Tokenizer::TYPE_START)) {
312
// Advance to first token.
316
if (require_syntax_identifier_ || LookingAt("syntax")) {
317
if (!ParseSyntaxIdentifier()) {
318
// Don't attempt to parse the file if we didn't recognize the syntax
322
} else if (!stop_after_syntax_identifier_) {
323
syntax_identifier_ = "proto2";
326
if (stop_after_syntax_identifier_) return !had_errors_;
328
// Repeatedly parse statements until we reach the end of the file.
330
if (!ParseTopLevelStatement(file)) {
331
// This statement failed to parse. Skip it, but keep looping to parse
335
if (LookingAt("}")) {
336
AddError("Unmatched \"}\".");
346
bool Parser::ParseSyntaxIdentifier() {
347
DO(Consume("syntax", "File must begin with 'syntax = \"proto2\";'."));
349
io::Tokenizer::Token syntax_token = input_->current();
351
DO(ConsumeString(&syntax, "Expected syntax identifier."));
354
syntax_identifier_ = syntax;
356
if (syntax != "proto2" && !stop_after_syntax_identifier_) {
357
AddError(syntax_token.line, syntax_token.column,
358
"Unrecognized syntax identifier \"" + syntax + "\". This parser "
359
"only recognizes \"proto2\".");
366
bool Parser::ParseTopLevelStatement(FileDescriptorProto* file) {
367
if (TryConsume(";")) {
368
// empty statement; ignore
370
} else if (LookingAt("message")) {
371
return ParseMessageDefinition(file->add_message_type());
372
} else if (LookingAt("enum")) {
373
return ParseEnumDefinition(file->add_enum_type());
374
} else if (LookingAt("service")) {
375
return ParseServiceDefinition(file->add_service());
376
} else if (LookingAt("extend")) {
377
return ParseExtend(file->mutable_extension(),
378
file->mutable_message_type());
379
} else if (LookingAt("import")) {
380
return ParseImport(file->add_dependency());
381
} else if (LookingAt("package")) {
382
return ParsePackage(file);
383
} else if (LookingAt("option")) {
384
return ParseOption(file->mutable_options());
386
AddError("Expected top-level statement (e.g. \"message\").");
391
// -------------------------------------------------------------------
394
bool Parser::ParseMessageDefinition(DescriptorProto* message) {
395
DO(Consume("message"));
396
RecordLocation(message, DescriptorPool::ErrorCollector::NAME);
397
DO(ConsumeIdentifier(message->mutable_name(), "Expected message name."));
398
DO(ParseMessageBlock(message));
402
bool Parser::ParseMessageBlock(DescriptorProto* message) {
405
while (!TryConsume("}")) {
407
AddError("Reached end of input in message definition (missing '}').");
411
if (!ParseMessageStatement(message)) {
412
// This statement failed to parse. Skip it, but keep looping to parse
421
bool Parser::ParseMessageStatement(DescriptorProto* message) {
422
if (TryConsume(";")) {
423
// empty statement; ignore
425
} else if (LookingAt("message")) {
426
return ParseMessageDefinition(message->add_nested_type());
427
} else if (LookingAt("enum")) {
428
return ParseEnumDefinition(message->add_enum_type());
429
} else if (LookingAt("extensions")) {
430
return ParseExtensions(message);
431
} else if (LookingAt("extend")) {
432
return ParseExtend(message->mutable_extension(),
433
message->mutable_nested_type());
434
} else if (LookingAt("option")) {
435
return ParseOption(message->mutable_options());
437
return ParseMessageField(message->add_field(),
438
message->mutable_nested_type());
442
bool Parser::ParseMessageField(FieldDescriptorProto* field,
443
RepeatedPtrField<DescriptorProto>* messages) {
444
// Parse label and type.
445
FieldDescriptorProto::Label label;
446
DO(ParseLabel(&label));
447
field->set_label(label);
449
RecordLocation(field, DescriptorPool::ErrorCollector::TYPE);
450
FieldDescriptorProto::Type type = FieldDescriptorProto::TYPE_INT32;
452
DO(ParseType(&type, &type_name));
453
if (type_name.empty()) {
454
field->set_type(type);
456
field->set_type_name(type_name);
459
// Parse name and '='.
460
RecordLocation(field, DescriptorPool::ErrorCollector::NAME);
461
io::Tokenizer::Token name_token = input_->current();
462
DO(ConsumeIdentifier(field->mutable_name(), "Expected field name."));
463
DO(Consume("=", "Missing field number."));
465
// Parse field number.
466
RecordLocation(field, DescriptorPool::ErrorCollector::NUMBER);
468
DO(ConsumeInteger(&number, "Expected field number."));
469
field->set_number(number);
472
DO(ParseFieldOptions(field));
475
if (type_name.empty() && type == FieldDescriptorProto::TYPE_GROUP) {
476
DescriptorProto* group = messages->Add();
477
group->set_name(field->name());
478
// Record name location to match the field name's location.
479
RecordLocation(group, DescriptorPool::ErrorCollector::NAME,
480
name_token.line, name_token.column);
482
// As a hack for backwards-compatibility, we force the group name to start
483
// with a capital letter and lower-case the field name. New code should
484
// not use groups; it should use nested messages.
485
if (group->name()[0] < 'A' || 'Z' < group->name()[0]) {
486
AddError(name_token.line, name_token.column,
487
"Group names must start with a capital letter.");
489
LowerString(field->mutable_name());
491
field->set_type_name(group->name());
492
if (LookingAt("{")) {
493
DO(ParseMessageBlock(group));
495
AddError("Missing group body.");
505
bool Parser::ParseFieldOptions(FieldDescriptorProto* field) {
506
if (!TryConsume("[")) return true;
508
// Parse field options.
510
if (LookingAt("default")) {
511
DO(ParseDefaultAssignment(field));
513
DO(ParseOptionAssignment(field->mutable_options()));
515
} while (TryConsume(","));
521
bool Parser::ParseDefaultAssignment(FieldDescriptorProto* field) {
522
if (field->has_default_value()) {
523
AddError("Already set option \"default\".");
524
field->clear_default_value();
527
DO(Consume("default"));
530
RecordLocation(field, DescriptorPool::ErrorCollector::DEFAULT_VALUE);
531
string* default_value = field->mutable_default_value();
533
if (!field->has_type()) {
534
// The field has a type name, but we don't know if it is a message or an
535
// enum yet. Assume an enum for now.
536
DO(ConsumeIdentifier(default_value, "Expected identifier."));
540
switch (field->type()) {
541
case FieldDescriptorProto::TYPE_INT32:
542
case FieldDescriptorProto::TYPE_INT64:
543
case FieldDescriptorProto::TYPE_SINT32:
544
case FieldDescriptorProto::TYPE_SINT64:
545
case FieldDescriptorProto::TYPE_SFIXED32:
546
case FieldDescriptorProto::TYPE_SFIXED64: {
547
uint64 max_value = kint64max;
548
if (field->type() == FieldDescriptorProto::TYPE_INT32 ||
549
field->type() == FieldDescriptorProto::TYPE_SINT32 ||
550
field->type() == FieldDescriptorProto::TYPE_SFIXED32) {
551
max_value = kint32max;
554
// These types can be negative.
555
if (TryConsume("-")) {
556
default_value->append("-");
557
// Two's complement always has one more negative value than positive.
560
// Parse the integer to verify that it is not out-of-range.
562
DO(ConsumeInteger64(max_value, &value, "Expected integer."));
563
// And stringify it again.
564
default_value->append(SimpleItoa(value));
568
case FieldDescriptorProto::TYPE_UINT32:
569
case FieldDescriptorProto::TYPE_UINT64:
570
case FieldDescriptorProto::TYPE_FIXED32:
571
case FieldDescriptorProto::TYPE_FIXED64: {
572
uint64 max_value = kuint64max;
573
if (field->type() == FieldDescriptorProto::TYPE_UINT32 ||
574
field->type() == FieldDescriptorProto::TYPE_FIXED32) {
575
max_value = kuint32max;
578
// Numeric, not negative.
579
if (TryConsume("-")) {
580
AddError("Unsigned field can't have negative default value.");
582
// Parse the integer to verify that it is not out-of-range.
584
DO(ConsumeInteger64(max_value, &value, "Expected integer."));
585
// And stringify it again.
586
default_value->append(SimpleItoa(value));
590
case FieldDescriptorProto::TYPE_FLOAT:
591
case FieldDescriptorProto::TYPE_DOUBLE:
592
// These types can be negative.
593
if (TryConsume("-")) {
594
default_value->append("-");
596
// Parse the integer because we have to convert hex integers to decimal
599
DO(ConsumeNumber(&value, "Expected number."));
600
// And stringify it again.
601
default_value->append(SimpleDtoa(value));
604
case FieldDescriptorProto::TYPE_BOOL:
605
if (TryConsume("true")) {
606
default_value->assign("true");
607
} else if (TryConsume("false")) {
608
default_value->assign("false");
610
AddError("Expected \"true\" or \"false\".");
615
case FieldDescriptorProto::TYPE_STRING:
616
DO(ConsumeString(default_value, "Expected string."));
619
case FieldDescriptorProto::TYPE_BYTES:
620
DO(ConsumeString(default_value, "Expected string."));
621
*default_value = CEscape(*default_value);
624
case FieldDescriptorProto::TYPE_ENUM:
625
DO(ConsumeIdentifier(default_value, "Expected identifier."));
628
case FieldDescriptorProto::TYPE_MESSAGE:
629
case FieldDescriptorProto::TYPE_GROUP:
630
AddError("Messages can't have default values.");
637
bool Parser::ParseOptionNamePart(UninterpretedOption* uninterpreted_option) {
638
UninterpretedOption::NamePart* name = uninterpreted_option->add_name();
639
string identifier; // We parse identifiers into this string.
640
if (LookingAt("(")) { // This is an extension.
642
// An extension name consists of dot-separated identifiers, and may begin
644
if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
645
DO(ConsumeIdentifier(&identifier, "Expected identifier."));
646
name->mutable_name_part()->append(identifier);
648
while (LookingAt(".")) {
650
name->mutable_name_part()->append(".");
651
DO(ConsumeIdentifier(&identifier, "Expected identifier."));
652
name->mutable_name_part()->append(identifier);
655
name->set_is_extension(true);
656
} else { // This is a regular field.
657
DO(ConsumeIdentifier(&identifier, "Expected identifier."));
658
name->mutable_name_part()->append(identifier);
659
name->set_is_extension(false);
664
// We don't interpret the option here. Instead we store it in an
665
// UninterpretedOption, to be interpreted later.
666
bool Parser::ParseOptionAssignment(Message* options) {
667
// Create an entry in the uninterpreted_option field.
668
const FieldDescriptor* uninterpreted_option_field = options->GetDescriptor()->
669
FindFieldByName("uninterpreted_option");
670
GOOGLE_CHECK(uninterpreted_option_field != NULL)
671
<< "No field named \"uninterpreted_option\" in the Options proto.";
673
UninterpretedOption* uninterpreted_option = down_cast<UninterpretedOption*>(
674
options->GetReflection()->AddMessage(options,
675
uninterpreted_option_field));
677
// Parse dot-separated name.
678
RecordLocation(uninterpreted_option,
679
DescriptorPool::ErrorCollector::OPTION_NAME);
681
DO(ParseOptionNamePart(uninterpreted_option));
683
while (LookingAt(".")) {
685
DO(ParseOptionNamePart(uninterpreted_option));
690
RecordLocation(uninterpreted_option,
691
DescriptorPool::ErrorCollector::OPTION_VALUE);
693
// All values are a single token, except for negative numbers, which consist
694
// of a single '-' symbol, followed by a positive number.
695
bool is_negative = TryConsume("-");
697
switch (input_->current().type) {
698
case io::Tokenizer::TYPE_START:
699
GOOGLE_LOG(FATAL) << "Trying to read value before any tokens have been read.";
702
case io::Tokenizer::TYPE_END:
703
AddError("Unexpected end of stream while parsing option value.");
706
case io::Tokenizer::TYPE_IDENTIFIER: {
708
AddError("Invalid '-' symbol before identifier.");
712
DO(ConsumeIdentifier(&value, "Expected identifier."));
713
uninterpreted_option->set_identifier_value(value);
717
case io::Tokenizer::TYPE_INTEGER: {
720
is_negative ? static_cast<uint64>(kint64max) + 1 : kuint64max;
721
DO(ConsumeInteger64(max_value, &value, "Expected integer."));
723
uninterpreted_option->set_negative_int_value(
724
-static_cast<int64>(value));
726
uninterpreted_option->set_positive_int_value(value);
731
case io::Tokenizer::TYPE_FLOAT: {
733
DO(ConsumeNumber(&value, "Expected number."));
734
uninterpreted_option->set_double_value(is_negative ? -value : value);
738
case io::Tokenizer::TYPE_STRING: {
740
AddError("Invalid '-' symbol before string.");
744
DO(ConsumeString(&value, "Expected string."));
745
uninterpreted_option->set_string_value(value);
749
case io::Tokenizer::TYPE_SYMBOL:
750
AddError("Expected option value.");
757
bool Parser::ParseExtensions(DescriptorProto* message) {
758
// Parse the declaration.
759
DO(Consume("extensions"));
762
DescriptorProto::ExtensionRange* range = message->add_extension_range();
763
RecordLocation(range, DescriptorPool::ErrorCollector::NUMBER);
766
DO(ConsumeInteger(&start, "Expected field number range."));
768
if (TryConsume("to")) {
769
if (TryConsume("max")) {
770
end = FieldDescriptor::kMaxNumber;
772
DO(ConsumeInteger(&end, "Expected integer."));
778
// Users like to specify inclusive ranges, but in code we like the end
779
// number to be exclusive.
782
range->set_start(start);
784
} while (TryConsume(","));
790
bool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
791
RepeatedPtrField<DescriptorProto>* messages) {
792
DO(Consume("extend"));
794
// We expect to see at least one extension field defined in the extend block.
795
// We need to create it now so we can record the extendee's location.
796
FieldDescriptorProto* first_field = extensions->Add();
798
// Parse the extendee type.
799
RecordLocation(first_field, DescriptorPool::ErrorCollector::EXTENDEE);
800
DO(ParseUserDefinedType(first_field->mutable_extendee()));
805
bool is_first = true;
809
AddError("Reached end of input in extend definition (missing '}').");
813
FieldDescriptorProto* field;
818
field = extensions->Add();
819
field->set_extendee(first_field->extendee());
822
if (!ParseMessageField(field, messages)) {
823
// This statement failed to parse. Skip it, but keep looping to parse
827
} while(!TryConsume("}"));
832
// -------------------------------------------------------------------
835
bool Parser::ParseEnumDefinition(EnumDescriptorProto* enum_type) {
837
RecordLocation(enum_type, DescriptorPool::ErrorCollector::NAME);
838
DO(ConsumeIdentifier(enum_type->mutable_name(), "Expected enum name."));
839
DO(ParseEnumBlock(enum_type));
843
bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type) {
846
while (!TryConsume("}")) {
848
AddError("Reached end of input in enum definition (missing '}').");
852
if (!ParseEnumStatement(enum_type)) {
853
// This statement failed to parse. Skip it, but keep looping to parse
862
bool Parser::ParseEnumStatement(EnumDescriptorProto* enum_type) {
863
if (TryConsume(";")) {
864
// empty statement; ignore
866
} else if (LookingAt("option")) {
867
return ParseOption(enum_type->mutable_options());
869
return ParseEnumConstant(enum_type->add_value());
873
bool Parser::ParseEnumConstant(EnumValueDescriptorProto* enum_value) {
874
RecordLocation(enum_value, DescriptorPool::ErrorCollector::NAME);
875
DO(ConsumeIdentifier(enum_value->mutable_name(),
876
"Expected enum constant name."));
877
DO(Consume("=", "Missing numeric value for enum constant."));
879
bool is_negative = TryConsume("-");
881
DO(ConsumeInteger(&number, "Expected integer."));
882
if (is_negative) number *= -1;
883
enum_value->set_number(number);
885
DO(ParseEnumConstantOptions(enum_value));
892
bool Parser::ParseEnumConstantOptions(EnumValueDescriptorProto* value) {
893
if (!TryConsume("[")) return true;
896
DO(ParseOptionAssignment(value->mutable_options()));
897
} while (TryConsume(","));
903
// -------------------------------------------------------------------
906
bool Parser::ParseServiceDefinition(ServiceDescriptorProto* service) {
907
DO(Consume("service"));
908
RecordLocation(service, DescriptorPool::ErrorCollector::NAME);
909
DO(ConsumeIdentifier(service->mutable_name(), "Expected service name."));
910
DO(ParseServiceBlock(service));
914
bool Parser::ParseServiceBlock(ServiceDescriptorProto* service) {
917
while (!TryConsume("}")) {
919
AddError("Reached end of input in service definition (missing '}').");
923
if (!ParseServiceStatement(service)) {
924
// This statement failed to parse. Skip it, but keep looping to parse
933
bool Parser::ParseServiceStatement(ServiceDescriptorProto* service) {
934
if (TryConsume(";")) {
935
// empty statement; ignore
937
} else if (LookingAt("option")) {
938
return ParseOption(service->mutable_options());
940
return ParseServiceMethod(service->add_method());
944
bool Parser::ParseServiceMethod(MethodDescriptorProto* method) {
946
RecordLocation(method, DescriptorPool::ErrorCollector::NAME);
947
DO(ConsumeIdentifier(method->mutable_name(), "Expected method name."));
951
RecordLocation(method, DescriptorPool::ErrorCollector::INPUT_TYPE);
952
DO(ParseUserDefinedType(method->mutable_input_type()));
955
// Parse output type.
956
DO(Consume("returns"));
958
RecordLocation(method, DescriptorPool::ErrorCollector::OUTPUT_TYPE);
959
DO(ParseUserDefinedType(method->mutable_output_type()));
962
if (TryConsume("{")) {
964
while (!TryConsume("}")) {
966
AddError("Reached end of input in method options (missing '}').");
970
if (TryConsume(";")) {
971
// empty statement; ignore
973
if (!ParseOption(method->mutable_options())) {
974
// This statement failed to parse. Skip it, but keep looping to
975
// parse other statements.
987
// -------------------------------------------------------------------
989
bool Parser::ParseLabel(FieldDescriptorProto::Label* label) {
990
if (TryConsume("optional")) {
991
*label = FieldDescriptorProto::LABEL_OPTIONAL;
993
} else if (TryConsume("repeated")) {
994
*label = FieldDescriptorProto::LABEL_REPEATED;
996
} else if (TryConsume("required")) {
997
*label = FieldDescriptorProto::LABEL_REQUIRED;
1000
AddError("Expected \"required\", \"optional\", or \"repeated\".");
1001
// We can actually reasonably recover here by just assuming the user
1002
// forgot the label altogether.
1003
*label = FieldDescriptorProto::LABEL_OPTIONAL;
1008
bool Parser::ParseType(FieldDescriptorProto::Type* type,
1009
string* type_name) {
1010
TypeNameMap::const_iterator iter = kTypeNames.find(input_->current().text);
1011
if (iter != kTypeNames.end()) {
1012
*type = iter->second;
1015
DO(ParseUserDefinedType(type_name));
1020
bool Parser::ParseUserDefinedType(string* type_name) {
1023
TypeNameMap::const_iterator iter = kTypeNames.find(input_->current().text);
1024
if (iter != kTypeNames.end()) {
1025
// Note: The only place enum types are allowed is for field types, but
1026
// if we are parsing a field type then we would not get here because
1027
// primitives are allowed there as well. So this error message doesn't
1028
// need to account for enums.
1029
AddError("Expected message type.");
1031
// Pretend to accept this type so that we can go on parsing.
1032
*type_name = input_->current().text;
1037
// A leading "." means the name is fully-qualified.
1038
if (TryConsume(".")) type_name->append(".");
1040
// Consume the first part of the name.
1042
DO(ConsumeIdentifier(&identifier, "Expected type name."));
1043
type_name->append(identifier);
1045
// Consume more parts.
1046
while (TryConsume(".")) {
1047
type_name->append(".");
1048
DO(ConsumeIdentifier(&identifier, "Expected identifier."));
1049
type_name->append(identifier);
1055
// ===================================================================
1057
bool Parser::ParsePackage(FileDescriptorProto* file) {
1058
if (file->has_package()) {
1059
AddError("Multiple package definitions.");
1060
// Don't append the new package to the old one. Just replace it. Not
1061
// that it really matters since this is an error anyway.
1062
file->clear_package();
1065
DO(Consume("package"));
1067
RecordLocation(file, DescriptorPool::ErrorCollector::NAME);
1071
DO(ConsumeIdentifier(&identifier, "Expected identifier."));
1072
file->mutable_package()->append(identifier);
1073
if (!TryConsume(".")) break;
1074
file->mutable_package()->append(".");
1081
bool Parser::ParseImport(string* import_filename) {
1082
DO(Consume("import"));
1083
DO(ConsumeString(import_filename,
1084
"Expected a string naming the file to import."));
1089
bool Parser::ParseOption(Message* options) {
1090
DO(Consume("option"));
1091
DO(ParseOptionAssignment(options));
1096
// ===================================================================
1098
SourceLocationTable::SourceLocationTable() {}
1099
SourceLocationTable::~SourceLocationTable() {}
1101
bool SourceLocationTable::Find(
1102
const Message* descriptor,
1103
DescriptorPool::ErrorCollector::ErrorLocation location,
1104
int* line, int* column) const {
1105
const pair<int, int>* result =
1106
FindOrNull(location_map_, make_pair(descriptor, location));
1107
if (result == NULL) {
1112
*line = result->first;
1113
*column = result->second;
1118
void SourceLocationTable::Add(
1119
const Message* descriptor,
1120
DescriptorPool::ErrorCollector::ErrorLocation location,
1121
int line, int column) {
1122
location_map_[make_pair(descriptor, location)] = make_pair(line, column);
1125
void SourceLocationTable::Clear() {
1126
location_map_.clear();
1129
} // namespace compiler
1130
} // namespace protobuf
1131
} // namespace google