1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.
3 // http://code.google.com/p/protobuf/
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
17 // Author: kenton@google.com (Kenton Varda)
18 // Based on original Protocol Buffers design by
19 // Sanjay Ghemawat, Jeff Dean, and others.
21 // Recursive descent FTW.
23 #include <google/protobuf/stubs/hash.h>
27 #include <google/protobuf/compiler/parser.h>
28 #include <google/protobuf/descriptor.h>
29 #include <google/protobuf/descriptor.pb.h>
30 #include <google/protobuf/wire_format.h>
31 #include <google/protobuf/io/tokenizer.h>
32 #include <google/protobuf/stubs/common.h>
33 #include <google/protobuf/stubs/strutil.h>
34 #include <google/protobuf/stubs/map-util.h>
40 using internal::WireFormat
;
44 typedef hash_map
<string
, FieldDescriptorProto::Type
> TypeNameMap
;
46 TypeNameMap
MakeTypeNameTable() {
49 result
["double" ] = FieldDescriptorProto::TYPE_DOUBLE
;
50 result
["float" ] = FieldDescriptorProto::TYPE_FLOAT
;
51 result
["uint64" ] = FieldDescriptorProto::TYPE_UINT64
;
52 result
["fixed64" ] = FieldDescriptorProto::TYPE_FIXED64
;
53 result
["fixed32" ] = FieldDescriptorProto::TYPE_FIXED32
;
54 result
["bool" ] = FieldDescriptorProto::TYPE_BOOL
;
55 result
["string" ] = FieldDescriptorProto::TYPE_STRING
;
56 result
["group" ] = FieldDescriptorProto::TYPE_GROUP
;
58 result
["bytes" ] = FieldDescriptorProto::TYPE_BYTES
;
59 result
["uint32" ] = FieldDescriptorProto::TYPE_UINT32
;
60 result
["sfixed32"] = FieldDescriptorProto::TYPE_SFIXED32
;
61 result
["sfixed64"] = FieldDescriptorProto::TYPE_SFIXED64
;
62 result
["int32" ] = FieldDescriptorProto::TYPE_INT32
;
63 result
["int64" ] = FieldDescriptorProto::TYPE_INT64
;
64 result
["sint32" ] = FieldDescriptorProto::TYPE_SINT32
;
65 result
["sint64" ] = FieldDescriptorProto::TYPE_SINT64
;
70 const TypeNameMap kTypeNames
= MakeTypeNameTable();
72 } // anonymous namespace
74 // Makes code slightly more readable. The meaning of "DO(foo)" is
75 // "Execute foo and fail if it fails.", where failure is indicated by
77 #define DO(STATEMENT) if (STATEMENT) {} else return false
79 // ===================================================================
83 error_collector_(NULL
),
84 source_location_table_(NULL
),
86 require_syntax_identifier_(false) {
92 // ===================================================================
94 inline bool Parser::LookingAt(const char* text
) {
95 return input_
->current().text
== text
;
98 inline bool Parser::LookingAtType(io::Tokenizer::TokenType token_type
) {
99 return input_
->current().type
== token_type
;
102 inline bool Parser::AtEnd() {
103 return LookingAtType(io::Tokenizer::TYPE_END
);
106 bool Parser::TryConsume(const char* text
) {
107 if (LookingAt(text
)) {
115 bool Parser::Consume(const char* text
, const char* error
) {
116 if (TryConsume(text
)) {
124 bool Parser::Consume(const char* text
) {
125 if (TryConsume(text
)) {
128 AddError("Expected \"" + string(text
) + "\".");
133 bool Parser::ConsumeIdentifier(string
* output
, const char* error
) {
134 if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER
)) {
135 *output
= input_
->current().text
;
144 bool Parser::ConsumeInteger(int* output
, const char* error
) {
145 if (LookingAtType(io::Tokenizer::TYPE_INTEGER
)) {
147 if (!io::Tokenizer::ParseInteger(input_
->current().text
,
148 kint32max
, &value
)) {
149 AddError("Integer out of range.");
150 // We still return true because we did, in fact, parse an integer.
161 bool Parser::ConsumeInteger64(uint64 max_value
, uint64
* output
,
163 if (LookingAtType(io::Tokenizer::TYPE_INTEGER
)) {
164 if (!io::Tokenizer::ParseInteger(input_
->current().text
, max_value
,
166 AddError("Integer out of range.");
167 // We still return true because we did, in fact, parse an integer.
178 bool Parser::ConsumeNumber(double* output
, const char* error
) {
179 if (LookingAtType(io::Tokenizer::TYPE_FLOAT
)) {
180 *output
= io::Tokenizer::ParseFloat(input_
->current().text
);
183 } else if (LookingAtType(io::Tokenizer::TYPE_INTEGER
)) {
184 // Also accept integers.
186 if (!io::Tokenizer::ParseInteger(input_
->current().text
,
187 kuint64max
, &value
)) {
188 AddError("Integer out of range.");
189 // We still return true because we did, in fact, parse a number.
200 bool Parser::ConsumeString(string
* output
, const char* error
) {
201 if (LookingAtType(io::Tokenizer::TYPE_STRING
)) {
202 io::Tokenizer::ParseString(input_
->current().text
, output
);
211 // -------------------------------------------------------------------
213 void Parser::AddError(int line
, int column
, const string
& error
) {
214 if (error_collector_
!= NULL
) {
215 error_collector_
->AddError(line
, column
, error
);
220 void Parser::AddError(const string
& error
) {
221 AddError(input_
->current().line
, input_
->current().column
, error
);
224 void Parser::RecordLocation(
225 const Message
* descriptor
,
226 DescriptorPool::ErrorCollector::ErrorLocation location
,
227 int line
, int column
) {
228 if (source_location_table_
!= NULL
) {
229 source_location_table_
->Add(descriptor
, location
, line
, column
);
233 void Parser::RecordLocation(
234 const Message
* descriptor
,
235 DescriptorPool::ErrorCollector::ErrorLocation location
) {
236 RecordLocation(descriptor
, location
,
237 input_
->current().line
, input_
->current().column
);
240 // -------------------------------------------------------------------
242 void Parser::SkipStatement() {
246 } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL
)) {
247 if (TryConsume(";")) {
249 } else if (TryConsume("{")) {
252 } else if (LookingAt("}")) {
260 void Parser::SkipRestOfBlock() {
264 } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL
)) {
265 if (TryConsume("}")) {
267 } else if (TryConsume("{")) {
275 // ===================================================================
277 bool Parser::Parse(io::Tokenizer
* input
, FileDescriptorProto
* file
) {
280 syntax_identifier_
.clear();
282 if (LookingAtType(io::Tokenizer::TYPE_START
)) {
283 // Advance to first token.
287 if (require_syntax_identifier_
|| LookingAt("syntax")) {
288 if (!ParseSyntaxIdentifier()) {
289 // Don't attempt to parse the file if we didn't recognize the syntax
294 syntax_identifier_
= "proto2";
297 // Repeatedly parse statemetns until we reach the end of the file.
299 if (!ParseTopLevelStatement(file
)) {
300 // This statement failed to parse. Skip it, but keep looping to parse
304 if (LookingAt("}")) {
305 AddError("Unmatched \"}\".");
315 bool Parser::ParseSyntaxIdentifier() {
316 DO(Consume("syntax", "File must begin with 'syntax = \"proto2\";'."));
318 io::Tokenizer::Token syntax_token
= input_
->current();
320 DO(ConsumeString(&syntax
, "Expected syntax identifier."));
323 syntax_identifier_
= syntax
;
325 if (syntax
!= "proto2") {
326 AddError(syntax_token
.line
, syntax_token
.column
,
327 "Unrecognized syntax identifier \"" + syntax
+ "\". This parser "
328 "only recognizes \"proto2\".");
335 bool Parser::ParseTopLevelStatement(FileDescriptorProto
* file
) {
336 if (TryConsume(";")) {
337 // empty statement; ignore
339 } else if (LookingAt("message")) {
340 return ParseMessageDefinition(file
->add_message_type());
341 } else if (LookingAt("enum")) {
342 return ParseEnumDefinition(file
->add_enum_type());
343 } else if (LookingAt("service")) {
344 return ParseServiceDefinition(file
->add_service());
345 } else if (LookingAt("extend")) {
346 return ParseExtend(file
->mutable_extension(),
347 file
->mutable_message_type());
348 } else if (LookingAt("import")) {
349 return ParseImport(file
->add_dependency());
350 } else if (LookingAt("package")) {
351 return ParsePackage(file
);
352 } else if (LookingAt("option")) {
353 return ParseOption(file
->mutable_options());
355 AddError("Expected top-level statement (e.g. \"message\").");
360 // -------------------------------------------------------------------
363 bool Parser::ParseMessageDefinition(DescriptorProto
* message
) {
364 DO(Consume("message"));
365 RecordLocation(message
, DescriptorPool::ErrorCollector::NAME
);
366 DO(ConsumeIdentifier(message
->mutable_name(), "Expected message name."));
367 DO(ParseMessageBlock(message
));
371 bool Parser::ParseMessageBlock(DescriptorProto
* message
) {
374 while (!TryConsume("}")) {
376 AddError("Reached end of input in message definition (missing '}').");
380 if (!ParseMessageStatement(message
)) {
381 // This statement failed to parse. Skip it, but keep looping to parse
390 bool Parser::ParseMessageStatement(DescriptorProto
* message
) {
391 if (TryConsume(";")) {
392 // empty statement; ignore
394 } else if (LookingAt("message")) {
395 return ParseMessageDefinition(message
->add_nested_type());
396 } else if (LookingAt("enum")) {
397 return ParseEnumDefinition(message
->add_enum_type());
398 } else if (LookingAt("extensions")) {
399 return ParseExtensions(message
);
400 } else if (LookingAt("extend")) {
401 return ParseExtend(message
->mutable_extension(),
402 message
->mutable_nested_type());
403 } else if (LookingAt("option")) {
404 return ParseOption(message
->mutable_options());
406 return ParseMessageField(message
->add_field(),
407 message
->mutable_nested_type());
411 bool Parser::ParseMessageField(FieldDescriptorProto
* field
,
412 RepeatedPtrField
<DescriptorProto
>* messages
) {
413 // Parse label and type.
414 FieldDescriptorProto::Label label
;
415 DO(ParseLabel(&label
));
416 field
->set_label(label
);
418 RecordLocation(field
, DescriptorPool::ErrorCollector::TYPE
);
419 FieldDescriptorProto::Type type
= FieldDescriptorProto::TYPE_INT32
;
421 DO(ParseType(&type
, &type_name
));
422 if (type_name
.empty()) {
423 field
->set_type(type
);
425 field
->set_type_name(type_name
);
428 // Parse name and '='.
429 RecordLocation(field
, DescriptorPool::ErrorCollector::NAME
);
430 io::Tokenizer::Token name_token
= input_
->current();
431 DO(ConsumeIdentifier(field
->mutable_name(), "Expected field name."));
432 DO(Consume("=", "Missing field number."));
434 // Parse field number.
435 RecordLocation(field
, DescriptorPool::ErrorCollector::NUMBER
);
437 DO(ConsumeInteger(&number
, "Expected field number."));
438 field
->set_number(number
);
441 DO(ParseFieldOptions(field
));
444 if (type_name
.empty() && type
== FieldDescriptorProto::TYPE_GROUP
) {
445 DescriptorProto
* group
= messages
->Add();
446 group
->set_name(field
->name());
447 // Record name location to match the field name's location.
448 RecordLocation(group
, DescriptorPool::ErrorCollector::NAME
,
449 name_token
.line
, name_token
.column
);
451 // As a hack for backwards-compatibility, we force the group name to start
452 // with a capital letter and lower-case the field name. New code should
453 // not use groups; it should use nested messages.
454 if (group
->name()[0] < 'A' || 'Z' < group
->name()[0]) {
455 AddError(name_token
.line
, name_token
.column
,
456 "Group names must start with a capital letter.");
458 LowerString(field
->mutable_name());
460 field
->set_type_name(group
->name());
461 if (LookingAt("{")) {
462 DO(ParseMessageBlock(group
));
464 AddError("Missing group body.");
474 bool Parser::ParseFieldOptions(FieldDescriptorProto
* field
) {
475 if (!TryConsume("[")) return true;
477 // Parse field options.
479 if (LookingAt("default")) {
480 DO(ParseDefaultAssignment(field
));
482 DO(ParseOptionAssignment(field
->mutable_options()));
484 } while (TryConsume(","));
490 bool Parser::ParseDefaultAssignment(FieldDescriptorProto
* field
) {
491 if (field
->has_default_value()) {
492 AddError("Already set option \"default\".");
493 field
->clear_default_value();
496 DO(Consume("default"));
499 RecordLocation(field
, DescriptorPool::ErrorCollector::DEFAULT_VALUE
);
500 string
* default_value
= field
->mutable_default_value();
502 if (!field
->has_type()) {
503 // The field has a type name, but we don't know if it is a message or an
504 // enum yet. Assume an enum for now.
505 DO(ConsumeIdentifier(default_value
, "Expected identifier."));
509 switch (field
->type()) {
510 case FieldDescriptorProto::TYPE_INT32
:
511 case FieldDescriptorProto::TYPE_INT64
:
512 case FieldDescriptorProto::TYPE_SINT32
:
513 case FieldDescriptorProto::TYPE_SINT64
:
514 case FieldDescriptorProto::TYPE_SFIXED32
:
515 case FieldDescriptorProto::TYPE_SFIXED64
: {
516 uint64 max_value
= kint64max
;
517 if (field
->type() == FieldDescriptorProto::TYPE_INT32
||
518 field
->type() == FieldDescriptorProto::TYPE_SINT32
||
519 field
->type() == FieldDescriptorProto::TYPE_SFIXED32
) {
520 max_value
= kint32max
;
523 // These types can be negative.
524 if (TryConsume("-")) {
525 default_value
->append("-");
526 // Two's complement always has one more negative value than positive.
529 // Parse the integer to verify that it is not out-of-range.
531 DO(ConsumeInteger64(max_value
, &value
, "Expected integer."));
532 // And stringify it again.
533 default_value
->append(SimpleItoa(value
));
537 case FieldDescriptorProto::TYPE_UINT32
:
538 case FieldDescriptorProto::TYPE_UINT64
:
539 case FieldDescriptorProto::TYPE_FIXED32
:
540 case FieldDescriptorProto::TYPE_FIXED64
: {
541 uint64 max_value
= kuint64max
;
542 if (field
->type() == FieldDescriptorProto::TYPE_UINT32
||
543 field
->type() == FieldDescriptorProto::TYPE_FIXED32
) {
544 max_value
= kuint32max
;
547 // Numeric, not negative.
548 if (TryConsume("-")) {
549 AddError("Unsigned field can't have negative default value.");
551 // Parse the integer to verify that it is not out-of-range.
553 DO(ConsumeInteger64(max_value
, &value
, "Expected integer."));
554 // And stringify it again.
555 default_value
->append(SimpleItoa(value
));
559 case FieldDescriptorProto::TYPE_FLOAT
:
560 case FieldDescriptorProto::TYPE_DOUBLE
:
561 // These types can be negative.
562 if (TryConsume("-")) {
563 default_value
->append("-");
565 // Parse the integer because we have to convert hex integers to decimal
568 DO(ConsumeNumber(&value
, "Expected number."));
569 // And stringify it again.
570 default_value
->append(SimpleDtoa(value
));
573 case FieldDescriptorProto::TYPE_BOOL
:
574 if (TryConsume("true")) {
575 default_value
->assign("true");
576 } else if (TryConsume("false")) {
577 default_value
->assign("false");
579 AddError("Expected \"true\" or \"false\".");
584 case FieldDescriptorProto::TYPE_STRING
:
585 DO(ConsumeString(default_value
, "Expected string."));
588 case FieldDescriptorProto::TYPE_BYTES
:
589 DO(ConsumeString(default_value
, "Expected string."));
590 *default_value
= CEscape(*default_value
);
593 case FieldDescriptorProto::TYPE_ENUM
:
594 DO(ConsumeIdentifier(default_value
, "Expected identifier."));
597 case FieldDescriptorProto::TYPE_MESSAGE
:
598 case FieldDescriptorProto::TYPE_GROUP
:
599 AddError("Messages can't have default values.");
606 bool Parser::ParseOptionAssignment(Message
* options
) {
607 Message::Reflection
* reflection
= options
->GetReflection();
608 const Descriptor
* descriptor
= options
->GetDescriptor();
612 int line
= input_
->current().line
;
613 int column
= input_
->current().column
;
614 DO(ConsumeIdentifier(&name
, "Expected option name."));
617 const FieldDescriptor
* field
= descriptor
->FindFieldByName(name
);
619 AddError(line
, column
, "Unknown option: " + name
);
622 if (field
->is_repeated()) {
623 AddError(line
, column
, "Not implemented: repeated options.");
626 if (reflection
->HasField(field
)) {
627 AddError(line
, column
, "Option \"" + name
+ "\" was already set.");
631 // Are we trying to assign a member of a message?
632 if (LookingAt(".")) {
633 if (field
->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE
) {
634 AddError("Option \"" + name
+ "\" is an atomic type, not a message.");
639 // This field is a message/group. The user must identify a field within
641 return ParseOptionAssignment(reflection
->MutableMessage(field
));
646 // Parse the option value.
647 switch (field
->cpp_type()) {
648 case FieldDescriptor::CPPTYPE_INT32
: {
650 bool is_negative
= TryConsume("-");
651 uint64 max_value
= kint32max
;
652 if (is_negative
) ++max_value
;
653 DO(ConsumeInteger64(max_value
, &value
, "Expected integer."));
654 reflection
->SetInt32(field
, is_negative
? -value
: value
);
658 case FieldDescriptor::CPPTYPE_INT64
: {
660 bool is_negative
= TryConsume("-");
661 uint64 max_value
= kint64max
;
662 if (is_negative
) ++max_value
;
663 DO(ConsumeInteger64(max_value
, &value
, "Expected integer."));
664 reflection
->SetInt64(field
, is_negative
? -value
: value
);
668 case FieldDescriptor::CPPTYPE_UINT32
: {
670 DO(ConsumeInteger64(kuint32max
, &value
, "Expected integer."));
671 reflection
->SetUInt32(field
, value
);
675 case FieldDescriptor::CPPTYPE_UINT64
: {
677 DO(ConsumeInteger64(kuint64max
, &value
, "Expected integer."));
678 reflection
->SetUInt64(field
, value
);
682 case FieldDescriptor::CPPTYPE_DOUBLE
: {
684 bool is_negative
= TryConsume("-");
685 DO(ConsumeNumber(&value
, "Expected number."));
686 reflection
->SetDouble(field
, is_negative
? -value
: value
);
690 case FieldDescriptor::CPPTYPE_FLOAT
: {
692 bool is_negative
= TryConsume("-");
693 DO(ConsumeNumber(&value
, "Expected number."));
694 reflection
->SetFloat(field
, is_negative
? -value
: value
);
698 case FieldDescriptor::CPPTYPE_BOOL
:
699 if (TryConsume("true")) {
700 reflection
->SetBool(field
, true);
701 } else if (TryConsume("false")) {
702 reflection
->SetBool(field
, false);
704 AddError("Expected \"true\" or \"false\".");
709 case FieldDescriptor::CPPTYPE_ENUM
: {
711 int value_line
= input_
->current().line
;
712 int value_column
= input_
->current().column
;
713 DO(ConsumeIdentifier(&value_name
, "Expected enum value."));
714 const EnumValueDescriptor
* value
=
715 field
->enum_type()->FindValueByName(value_name
);
717 AddError(value_line
, value_column
,
718 "Enum type \"" + field
->enum_type()->full_name() + "\" has no value "
719 "named \"" + value_name
+ "\".");
722 reflection
->SetEnum(field
, value
);
726 case FieldDescriptor::CPPTYPE_STRING
: {
728 DO(ConsumeString(&value
, "Expected string."));
729 reflection
->SetString(field
, value
);
733 case FieldDescriptor::CPPTYPE_MESSAGE
: {
734 // TODO(kenton): Allow use of protocol buffer text format here?
735 AddError("\"" + name
+ "\" is a message. To set fields within it, use "
736 "syntax like \"" + name
+ ".foo = value\".");
745 bool Parser::ParseExtensions(DescriptorProto
* message
) {
746 // Parse the declaration.
747 DO(Consume("extensions"));
750 DescriptorProto::ExtensionRange
* range
= message
->add_extension_range();
751 RecordLocation(range
, DescriptorPool::ErrorCollector::NUMBER
);
754 DO(ConsumeInteger(&start
, "Expected field number range."));
756 if (TryConsume("to")) {
757 if (TryConsume("max")) {
758 end
= FieldDescriptor::kMaxNumber
;
760 DO(ConsumeInteger(&end
, "Expected integer."));
766 // Users like to specify inclusive ranges, but in code we like the end
767 // number to be exclusive.
770 range
->set_start(start
);
772 } while (TryConsume(","));
778 bool Parser::ParseExtend(RepeatedPtrField
<FieldDescriptorProto
>* extensions
,
779 RepeatedPtrField
<DescriptorProto
>* messages
) {
780 DO(Consume("extend"));
782 // We expect to see at least one extension field defined in the extend block.
783 // We need to create it now so we can record the extendee's location.
784 FieldDescriptorProto
* first_field
= extensions
->Add();
786 // Parse the extendee type.
787 RecordLocation(first_field
, DescriptorPool::ErrorCollector::EXTENDEE
);
788 DO(ParseUserDefinedType(first_field
->mutable_extendee()));
793 bool is_first
= true;
797 AddError("Reached end of input in extend definition (missing '}').");
801 FieldDescriptorProto
* field
;
806 field
= extensions
->Add();
807 field
->set_extendee(first_field
->extendee());
810 if (!ParseMessageField(field
, messages
)) {
811 // This statement failed to parse. Skip it, but keep looping to parse
815 } while(!TryConsume("}"));
820 // -------------------------------------------------------------------
823 bool Parser::ParseEnumDefinition(EnumDescriptorProto
* enum_type
) {
825 RecordLocation(enum_type
, DescriptorPool::ErrorCollector::NAME
);
826 DO(ConsumeIdentifier(enum_type
->mutable_name(), "Expected enum name."));
827 DO(ParseEnumBlock(enum_type
));
831 bool Parser::ParseEnumBlock(EnumDescriptorProto
* enum_type
) {
834 while (!TryConsume("}")) {
836 AddError("Reached end of input in enum definition (missing '}').");
840 if (!ParseEnumStatement(enum_type
)) {
841 // This statement failed to parse. Skip it, but keep looping to parse
850 bool Parser::ParseEnumStatement(EnumDescriptorProto
* enum_type
) {
851 if (TryConsume(";")) {
852 // empty statement; ignore
854 } else if (LookingAt("option")) {
855 return ParseOption(enum_type
->mutable_options());
857 return ParseEnumConstant(enum_type
->add_value());
861 bool Parser::ParseEnumConstant(EnumValueDescriptorProto
* enum_value
) {
862 RecordLocation(enum_value
, DescriptorPool::ErrorCollector::NAME
);
863 DO(ConsumeIdentifier(enum_value
->mutable_name(),
864 "Expected enum constant name."));
865 DO(Consume("=", "Missing numeric value for enum constant."));
867 bool is_negative
= TryConsume("-");
869 DO(ConsumeInteger(&number
, "Expected integer."));
870 if (is_negative
) number
*= -1;
871 enum_value
->set_number(number
);
873 // TODO(kenton): Options for enum values?
880 // -------------------------------------------------------------------
883 bool Parser::ParseServiceDefinition(ServiceDescriptorProto
* service
) {
884 DO(Consume("service"));
885 RecordLocation(service
, DescriptorPool::ErrorCollector::NAME
);
886 DO(ConsumeIdentifier(service
->mutable_name(), "Expected service name."));
887 DO(ParseServiceBlock(service
));
891 bool Parser::ParseServiceBlock(ServiceDescriptorProto
* service
) {
894 while (!TryConsume("}")) {
896 AddError("Reached end of input in service definition (missing '}').");
900 if (!ParseServiceStatement(service
)) {
901 // This statement failed to parse. Skip it, but keep looping to parse
910 bool Parser::ParseServiceStatement(ServiceDescriptorProto
* service
) {
911 if (TryConsume(";")) {
912 // empty statement; ignore
914 } else if (LookingAt("option")) {
915 return ParseOption(service
->mutable_options());
917 return ParseServiceMethod(service
->add_method());
921 bool Parser::ParseServiceMethod(MethodDescriptorProto
* method
) {
923 RecordLocation(method
, DescriptorPool::ErrorCollector::NAME
);
924 DO(ConsumeIdentifier(method
->mutable_name(), "Expected method name."));
928 RecordLocation(method
, DescriptorPool::ErrorCollector::INPUT_TYPE
);
929 DO(ParseUserDefinedType(method
->mutable_input_type()));
932 // Parse output type.
933 DO(Consume("returns"));
935 RecordLocation(method
, DescriptorPool::ErrorCollector::OUTPUT_TYPE
);
936 DO(ParseUserDefinedType(method
->mutable_output_type()));
939 if (TryConsume("{")) {
941 while (!TryConsume("}")) {
943 AddError("Reached end of input in method options (missing '}').");
947 if (TryConsume(";")) {
948 // empty statement; ignore
950 if (!ParseOption(method
->mutable_options())) {
951 // This statement failed to parse. Skip it, but keep looping to
952 // parse other statements.
964 // -------------------------------------------------------------------
966 bool Parser::ParseLabel(FieldDescriptorProto::Label
* label
) {
967 if (TryConsume("optional")) {
968 *label
= FieldDescriptorProto::LABEL_OPTIONAL
;
970 } else if (TryConsume("repeated")) {
971 *label
= FieldDescriptorProto::LABEL_REPEATED
;
973 } else if (TryConsume("required")) {
974 *label
= FieldDescriptorProto::LABEL_REQUIRED
;
977 AddError("Expected \"required\", \"optional\", or \"repeated\".");
978 // We can actually reasonably recover here by just assuming the user
979 // forgot the label altogether.
980 *label
= FieldDescriptorProto::LABEL_OPTIONAL
;
985 bool Parser::ParseType(FieldDescriptorProto::Type
* type
,
987 TypeNameMap::const_iterator iter
= kTypeNames
.find(input_
->current().text
);
988 if (iter
!= kTypeNames
.end()) {
989 *type
= iter
->second
;
992 DO(ParseUserDefinedType(type_name
));
997 bool Parser::ParseUserDefinedType(string
* type_name
) {
1000 TypeNameMap::const_iterator iter
= kTypeNames
.find(input_
->current().text
);
1001 if (iter
!= kTypeNames
.end()) {
1002 // Note: The only place enum types are allowed is for field types, but
1003 // if we are parsing a field type then we would not get here because
1004 // primitives are allowed there as well. So this error message doesn't
1005 // need to account for enums.
1006 AddError("Expected message type.");
1008 // Pretend to accept this type so that we can go on parsing.
1009 *type_name
= input_
->current().text
;
1014 // A leading "." means the name is fully-qualified.
1015 if (TryConsume(".")) type_name
->append(".");
1017 // Consume the first part of the name.
1019 DO(ConsumeIdentifier(&identifier
, "Expected type name."));
1020 type_name
->append(identifier
);
1022 // Consume more parts.
1023 while (TryConsume(".")) {
1024 type_name
->append(".");
1025 DO(ConsumeIdentifier(&identifier
, "Expected identifier."));
1026 type_name
->append(identifier
);
1032 // ===================================================================
1034 bool Parser::ParsePackage(FileDescriptorProto
* file
) {
1035 if (file
->has_package()) {
1036 AddError("Multiple package definitions.");
1039 DO(Consume("package"));
1041 RecordLocation(file
, DescriptorPool::ErrorCollector::NAME
);
1045 DO(ConsumeIdentifier(&identifier
, "Expected identifier."));
1046 file
->mutable_package()->append(identifier
);
1047 if (!TryConsume(".")) break;
1048 file
->mutable_package()->append(".");
1055 bool Parser::ParseImport(string
* import_filename
) {
1056 DO(Consume("import"));
1057 DO(ConsumeString(import_filename
,
1058 "Expected a string naming the file to import."));
1063 bool Parser::ParseOption(Message
* options
) {
1064 DO(Consume("option"));
1065 DO(ParseOptionAssignment(options
));
1070 // ===================================================================
1072 SourceLocationTable::SourceLocationTable() {}
1073 SourceLocationTable::~SourceLocationTable() {}
1075 bool SourceLocationTable::Find(
1076 const Message
* descriptor
,
1077 DescriptorPool::ErrorCollector::ErrorLocation location
,
1078 int* line
, int* column
) const {
1079 const pair
<int, int>* result
=
1080 FindOrNull(location_map_
, make_pair(descriptor
, location
));
1081 if (result
== NULL
) {
1086 *line
= result
->first
;
1087 *column
= result
->second
;
1092 void SourceLocationTable::Add(
1093 const Message
* descriptor
,
1094 DescriptorPool::ErrorCollector::ErrorLocation location
,
1095 int line
, int column
) {
1096 location_map_
[make_pair(descriptor
, location
)] = make_pair(line
, column
);
1099 void SourceLocationTable::Clear() {
1100 location_map_
.clear();
1103 } // namespace compiler
1104 } // namespace protobuf
1105 } // namespace google