1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format
2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc.  All rights reserved.
3fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// http://code.google.com/p/protobuf/
4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Redistribution and use in source and binary forms, with or without
6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// modification, are permitted provided that the following conditions are
7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// met:
8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Redistributions of source code must retain the above copyright
10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// notice, this list of conditions and the following disclaimer.
11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Redistributions in binary form must reproduce the above
12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// copyright notice, this list of conditions and the following disclaimer
13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in the documentation and/or other materials provided with the
14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// distribution.
15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Neither the name of Google Inc. nor the names of its
16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// contributors may be used to endorse or promote products derived from
17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this software without specific prior written permission.
18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Author: kenton@google.com (Kenton Varda)
32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//  Based on original Protocol Buffers design by
33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//  Sanjay Ghemawat, Jeff Dean, and others.
34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Recursive descent FTW.
36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <float.h>
38d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#include <google/protobuf/stubs/hash.h>
39d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#include <limits>
40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/parser.h>
43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/descriptor.h>
44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/descriptor.pb.h>
45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/wire_format.h>
46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/tokenizer.h>
47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/common.h>
48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/strutil.h>
49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/map-util.h>
50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google {
52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf {
53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace compiler {
54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleusing internal::WireFormat;
56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace {
58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilletypedef hash_map<string, FieldDescriptorProto::Type> TypeNameMap;
60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTypeNameMap MakeTypeNameTable() {
62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  TypeNameMap result;
63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  result["double"  ] = FieldDescriptorProto::TYPE_DOUBLE;
65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  result["float"   ] = FieldDescriptorProto::TYPE_FLOAT;
66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  result["uint64"  ] = FieldDescriptorProto::TYPE_UINT64;
67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  result["fixed64" ] = FieldDescriptorProto::TYPE_FIXED64;
68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  result["fixed32" ] = FieldDescriptorProto::TYPE_FIXED32;
69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  result["bool"    ] = FieldDescriptorProto::TYPE_BOOL;
70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  result["string"  ] = FieldDescriptorProto::TYPE_STRING;
71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  result["group"   ] = FieldDescriptorProto::TYPE_GROUP;
72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  result["bytes"   ] = FieldDescriptorProto::TYPE_BYTES;
74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  result["uint32"  ] = FieldDescriptorProto::TYPE_UINT32;
75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  result["sfixed32"] = FieldDescriptorProto::TYPE_SFIXED32;
76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  result["sfixed64"] = FieldDescriptorProto::TYPE_SFIXED64;
77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  result["int32"   ] = FieldDescriptorProto::TYPE_INT32;
78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  result["int64"   ] = FieldDescriptorProto::TYPE_INT64;
79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  result["sint32"  ] = FieldDescriptorProto::TYPE_SINT32;
80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  result["sint64"  ] = FieldDescriptorProto::TYPE_SINT64;
81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return result;
83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst TypeNameMap kTypeNames = MakeTypeNameTable();
86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // anonymous namespace
88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Makes code slightly more readable.  The meaning of "DO(foo)" is
90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "Execute foo and fail if it fails.", where failure is indicated by
91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// returning false.
92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define DO(STATEMENT) if (STATEMENT) {} else return false
93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ===================================================================
95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleParser::Parser()
97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  : input_(NULL),
98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    error_collector_(NULL),
99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    source_location_table_(NULL),
100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    had_errors_(false),
101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    require_syntax_identifier_(false),
102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    stop_after_syntax_identifier_(false) {
103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleParser::~Parser() {
106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ===================================================================
109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline bool Parser::LookingAt(const char* text) {
111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return input_->current().text == text;
112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline bool Parser::LookingAtType(io::Tokenizer::TokenType token_type) {
115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return input_->current().type == token_type;
116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline bool Parser::AtEnd() {
119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return LookingAtType(io::Tokenizer::TYPE_END);
120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::TryConsume(const char* text) {
123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (LookingAt(text)) {
124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    input_->Next();
125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::Consume(const char* text, const char* error) {
132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (TryConsume(text)) {
133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    AddError(error);
136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::Consume(const char* text) {
141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (TryConsume(text)) {
142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    AddError("Expected \"" + string(text) + "\".");
145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ConsumeIdentifier(string* output, const char* error) {
150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    *output = input_->current().text;
152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    input_->Next();
153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    AddError(error);
156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ConsumeInteger(int* output, const char* error) {
161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    uint64 value = 0;
163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!io::Tokenizer::ParseInteger(input_->current().text,
164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                     kint32max, &value)) {
165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      AddError("Integer out of range.");
166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // We still return true because we did, in fact, parse an integer.
167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    *output = value;
169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    input_->Next();
170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    AddError(error);
173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ConsumeInteger64(uint64 max_value, uint64* output,
178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                              const char* error) {
179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!io::Tokenizer::ParseInteger(input_->current().text, max_value,
181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                     output)) {
182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      AddError("Integer out of range.");
183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // We still return true because we did, in fact, parse an integer.
184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      *output = 0;
185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    input_->Next();
187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    AddError(error);
190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ConsumeNumber(double* output, const char* error) {
195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) {
196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    *output = io::Tokenizer::ParseFloat(input_->current().text);
197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    input_->Next();
198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Also accept integers.
201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    uint64 value = 0;
202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!io::Tokenizer::ParseInteger(input_->current().text,
203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                     kuint64max, &value)) {
204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      AddError("Integer out of range.");
205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // We still return true because we did, in fact, parse a number.
206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    *output = value;
208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    input_->Next();
209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
210d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  } else if (LookingAt("inf")) {
211d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    *output = numeric_limits<double>::infinity();
212d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    input_->Next();
213d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    return true;
214d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  } else if (LookingAt("nan")) {
215d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    *output = numeric_limits<double>::quiet_NaN();
216d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    input_->Next();
217d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    return true;
218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    AddError(error);
220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ConsumeString(string* output, const char* error) {
225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    io::Tokenizer::ParseString(input_->current().text, output);
227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    input_->Next();
228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Allow C++ like concatenation of adjacent string tokens.
229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      io::Tokenizer::ParseStringAppend(input_->current().text, output);
231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      input_->Next();
232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    AddError(error);
236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// -------------------------------------------------------------------
241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Parser::AddError(int line, int column, const string& error) {
243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (error_collector_ != NULL) {
244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    error_collector_->AddError(line, column, error);
245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  had_errors_ = true;
247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Parser::AddError(const string& error) {
250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  AddError(input_->current().line, input_->current().column, error);
251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Parser::RecordLocation(
254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const Message* descriptor,
255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    DescriptorPool::ErrorCollector::ErrorLocation location,
256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    int line, int column) {
257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (source_location_table_ != NULL) {
258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    source_location_table_->Add(descriptor, location, line, column);
259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Parser::RecordLocation(
263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const Message* descriptor,
264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    DescriptorPool::ErrorCollector::ErrorLocation location) {
265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  RecordLocation(descriptor, location,
266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                 input_->current().line, input_->current().column);
267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// -------------------------------------------------------------------
270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Parser::SkipStatement() {
272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  while (true) {
273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (AtEnd()) {
274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return;
275fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) {
276fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (TryConsume(";")) {
277fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return;
278fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      } else if (TryConsume("{")) {
279fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        SkipRestOfBlock();
280fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return;
281fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      } else if (LookingAt("}")) {
282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return;
283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
284fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
285fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    input_->Next();
286fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
288fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Parser::SkipRestOfBlock() {
290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  while (true) {
291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (AtEnd()) {
292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return;
293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) {
294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (TryConsume("}")) {
295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return;
296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      } else if (TryConsume("{")) {
297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        SkipRestOfBlock();
298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    input_->Next();
301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ===================================================================
305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) {
307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  input_ = input;
308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  had_errors_ = false;
309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  syntax_identifier_.clear();
310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (LookingAtType(io::Tokenizer::TYPE_START)) {
312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Advance to first token.
313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    input_->Next();
314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (require_syntax_identifier_ || LookingAt("syntax")) {
317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!ParseSyntaxIdentifier()) {
318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Don't attempt to parse the file if we didn't recognize the syntax
319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // identifier.
320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return false;
321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else if (!stop_after_syntax_identifier_) {
323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    syntax_identifier_ = "proto2";
324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (stop_after_syntax_identifier_) return !had_errors_;
327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Repeatedly parse statements until we reach the end of the file.
329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  while (!AtEnd()) {
330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!ParseTopLevelStatement(file)) {
331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // This statement failed to parse.  Skip it, but keep looping to parse
332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // other statements.
333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      SkipStatement();
334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (LookingAt("}")) {
336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        AddError("Unmatched \"}\".");
337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        input_->Next();
338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
342fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  input_ = NULL;
343fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return !had_errors_;
344fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
345fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
346fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ParseSyntaxIdentifier() {
347fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume("syntax", "File must begin with 'syntax = \"proto2\";'."));
348fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume("="));
349fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  io::Tokenizer::Token syntax_token = input_->current();
350fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string syntax;
351fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(ConsumeString(&syntax, "Expected syntax identifier."));
352fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume(";"));
353fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
354fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  syntax_identifier_ = syntax;
355fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
356fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (syntax != "proto2" && !stop_after_syntax_identifier_) {
357fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    AddError(syntax_token.line, syntax_token.column,
358fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "Unrecognized syntax identifier \"" + syntax + "\".  This parser "
359fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "only recognizes \"proto2\".");
360fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
361fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
362fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
363fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
364fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
365fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
366fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ParseTopLevelStatement(FileDescriptorProto* file) {
367fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (TryConsume(";")) {
368fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // empty statement; ignore
369fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
370fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else if (LookingAt("message")) {
371fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return ParseMessageDefinition(file->add_message_type());
372fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else if (LookingAt("enum")) {
373fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return ParseEnumDefinition(file->add_enum_type());
374fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else if (LookingAt("service")) {
375fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return ParseServiceDefinition(file->add_service());
376fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else if (LookingAt("extend")) {
377fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return ParseExtend(file->mutable_extension(),
378fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                       file->mutable_message_type());
379fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else if (LookingAt("import")) {
380fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return ParseImport(file->add_dependency());
381fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else if (LookingAt("package")) {
382fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return ParsePackage(file);
383fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else if (LookingAt("option")) {
384fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return ParseOption(file->mutable_options());
385fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
386fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    AddError("Expected top-level statement (e.g. \"message\").");
387fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
388fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
389fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
390fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
391fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// -------------------------------------------------------------------
392fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Messages
393fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
394fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ParseMessageDefinition(DescriptorProto* message) {
395fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume("message"));
396fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  RecordLocation(message, DescriptorPool::ErrorCollector::NAME);
397fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(ConsumeIdentifier(message->mutable_name(), "Expected message name."));
398fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(ParseMessageBlock(message));
399fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
400fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
401fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
402fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ParseMessageBlock(DescriptorProto* message) {
403fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume("{"));
404fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
405fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  while (!TryConsume("}")) {
406fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (AtEnd()) {
407fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      AddError("Reached end of input in message definition (missing '}').");
408fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return false;
409fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
410fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
411fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!ParseMessageStatement(message)) {
412fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // This statement failed to parse.  Skip it, but keep looping to parse
413fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // other statements.
414fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      SkipStatement();
415fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
416fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
417fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
418fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
419fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
420fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
421fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ParseMessageStatement(DescriptorProto* message) {
422fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (TryConsume(";")) {
423fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // empty statement; ignore
424fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
425fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else if (LookingAt("message")) {
426fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return ParseMessageDefinition(message->add_nested_type());
427fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else if (LookingAt("enum")) {
428fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return ParseEnumDefinition(message->add_enum_type());
429fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else if (LookingAt("extensions")) {
430fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return ParseExtensions(message);
431fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else if (LookingAt("extend")) {
432fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return ParseExtend(message->mutable_extension(),
433fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                       message->mutable_nested_type());
434fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else if (LookingAt("option")) {
435fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return ParseOption(message->mutable_options());
436fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
437fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return ParseMessageField(message->add_field(),
438fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                             message->mutable_nested_type());
439fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
440fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
441fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
442fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ParseMessageField(FieldDescriptorProto* field,
443fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                               RepeatedPtrField<DescriptorProto>* messages) {
444fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Parse label and type.
445fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  FieldDescriptorProto::Label label;
446fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(ParseLabel(&label));
447fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  field->set_label(label);
448fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
449fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  RecordLocation(field, DescriptorPool::ErrorCollector::TYPE);
450fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  FieldDescriptorProto::Type type = FieldDescriptorProto::TYPE_INT32;
451fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string type_name;
452fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(ParseType(&type, &type_name));
453fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (type_name.empty()) {
454fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    field->set_type(type);
455fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
456fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    field->set_type_name(type_name);
457fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
458fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
459fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Parse name and '='.
460fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  RecordLocation(field, DescriptorPool::ErrorCollector::NAME);
461fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  io::Tokenizer::Token name_token = input_->current();
462fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(ConsumeIdentifier(field->mutable_name(), "Expected field name."));
463fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume("=", "Missing field number."));
464fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
465fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Parse field number.
466fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  RecordLocation(field, DescriptorPool::ErrorCollector::NUMBER);
467fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  int number;
468fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(ConsumeInteger(&number, "Expected field number."));
469fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  field->set_number(number);
470fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
471fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Parse options.
472fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(ParseFieldOptions(field));
473fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
474fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Deal with groups.
475fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (type_name.empty() && type == FieldDescriptorProto::TYPE_GROUP) {
476fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    DescriptorProto* group = messages->Add();
477fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    group->set_name(field->name());
478fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Record name location to match the field name's location.
479fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    RecordLocation(group, DescriptorPool::ErrorCollector::NAME,
480fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                   name_token.line, name_token.column);
481fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
482fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // As a hack for backwards-compatibility, we force the group name to start
483fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // with a capital letter and lower-case the field name.  New code should
484fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // not use groups; it should use nested messages.
485fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (group->name()[0] < 'A' || 'Z' < group->name()[0]) {
486fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      AddError(name_token.line, name_token.column,
487fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "Group names must start with a capital letter.");
488fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
489fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    LowerString(field->mutable_name());
490fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
491fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    field->set_type_name(group->name());
492fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (LookingAt("{")) {
493fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      DO(ParseMessageBlock(group));
494fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
495fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      AddError("Missing group body.");
496fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return false;
497fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
498fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
499fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    DO(Consume(";"));
500fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
501fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
502fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
503fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
504fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
505fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ParseFieldOptions(FieldDescriptorProto* field) {
506fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (!TryConsume("[")) return true;
507fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
508fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Parse field options.
509fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  do {
510fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (LookingAt("default")) {
511fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      DO(ParseDefaultAssignment(field));
512fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
513fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      DO(ParseOptionAssignment(field->mutable_options()));
514fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
515fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } while (TryConsume(","));
516fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
517fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume("]"));
518fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
519fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
520fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
521fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ParseDefaultAssignment(FieldDescriptorProto* field) {
522fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (field->has_default_value()) {
523fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    AddError("Already set option \"default\".");
524fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    field->clear_default_value();
525fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
526fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
527fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume("default"));
528fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume("="));
529fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
530fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  RecordLocation(field, DescriptorPool::ErrorCollector::DEFAULT_VALUE);
531fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string* default_value = field->mutable_default_value();
532fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
533fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (!field->has_type()) {
534fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // The field has a type name, but we don't know if it is a message or an
535fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // enum yet.  Assume an enum for now.
536fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    DO(ConsumeIdentifier(default_value, "Expected identifier."));
537fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
538fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
539fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
540fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  switch (field->type()) {
541fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptorProto::TYPE_INT32:
542fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptorProto::TYPE_INT64:
543fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptorProto::TYPE_SINT32:
544fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptorProto::TYPE_SINT64:
545fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptorProto::TYPE_SFIXED32:
546fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptorProto::TYPE_SFIXED64: {
547fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      uint64 max_value = kint64max;
548fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (field->type() == FieldDescriptorProto::TYPE_INT32 ||
549fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          field->type() == FieldDescriptorProto::TYPE_SINT32 ||
550fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          field->type() == FieldDescriptorProto::TYPE_SFIXED32) {
551fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        max_value = kint32max;
552fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
553fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
554fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // These types can be negative.
555fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (TryConsume("-")) {
556fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        default_value->append("-");
557fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        // Two's complement always has one more negative value than positive.
558fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        ++max_value;
559fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
560fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Parse the integer to verify that it is not out-of-range.
561fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      uint64 value;
562fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      DO(ConsumeInteger64(max_value, &value, "Expected integer."));
563fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // And stringify it again.
564fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      default_value->append(SimpleItoa(value));
565fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      break;
566fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
567fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
568fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptorProto::TYPE_UINT32:
569fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptorProto::TYPE_UINT64:
570fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptorProto::TYPE_FIXED32:
571fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptorProto::TYPE_FIXED64: {
572fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      uint64 max_value = kuint64max;
573fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (field->type() == FieldDescriptorProto::TYPE_UINT32 ||
574fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          field->type() == FieldDescriptorProto::TYPE_FIXED32) {
575fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        max_value = kuint32max;
576fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
577fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
578fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Numeric, not negative.
579fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (TryConsume("-")) {
580fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        AddError("Unsigned field can't have negative default value.");
581fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
582fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Parse the integer to verify that it is not out-of-range.
583fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      uint64 value;
584fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      DO(ConsumeInteger64(max_value, &value, "Expected integer."));
585fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // And stringify it again.
586fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      default_value->append(SimpleItoa(value));
587fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      break;
588fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
589fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
590fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptorProto::TYPE_FLOAT:
591fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptorProto::TYPE_DOUBLE:
592fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // These types can be negative.
593fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (TryConsume("-")) {
594fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        default_value->append("-");
595fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
596fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Parse the integer because we have to convert hex integers to decimal
597fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // floats.
598fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      double value;
599fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      DO(ConsumeNumber(&value, "Expected number."));
600fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // And stringify it again.
601fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      default_value->append(SimpleDtoa(value));
602fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      break;
603fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
604fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptorProto::TYPE_BOOL:
605fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (TryConsume("true")) {
606fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        default_value->assign("true");
607fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      } else if (TryConsume("false")) {
608fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        default_value->assign("false");
609fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      } else {
610fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        AddError("Expected \"true\" or \"false\".");
611fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return false;
612fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
613fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      break;
614fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
615fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptorProto::TYPE_STRING:
616fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      DO(ConsumeString(default_value, "Expected string."));
617fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      break;
618fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
619fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptorProto::TYPE_BYTES:
620fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      DO(ConsumeString(default_value, "Expected string."));
621fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      *default_value = CEscape(*default_value);
622fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      break;
623fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
624fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptorProto::TYPE_ENUM:
625fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      DO(ConsumeIdentifier(default_value, "Expected identifier."));
626fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      break;
627fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
628fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptorProto::TYPE_MESSAGE:
629fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptorProto::TYPE_GROUP:
630fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      AddError("Messages can't have default values.");
631fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return false;
632fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
633fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
634fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
635fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
636fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
637fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ParseOptionNamePart(UninterpretedOption* uninterpreted_option) {
638fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  UninterpretedOption::NamePart* name = uninterpreted_option->add_name();
639fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string identifier;  // We parse identifiers into this string.
640fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (LookingAt("(")) {  // This is an extension.
641fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    DO(Consume("("));
642fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // An extension name consists of dot-separated identifiers, and may begin
643fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // with a dot.
644fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
645fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      DO(ConsumeIdentifier(&identifier, "Expected identifier."));
646fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      name->mutable_name_part()->append(identifier);
647fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
648fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    while (LookingAt(".")) {
649fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      DO(Consume("."));
650fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      name->mutable_name_part()->append(".");
651fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      DO(ConsumeIdentifier(&identifier, "Expected identifier."));
652fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      name->mutable_name_part()->append(identifier);
653fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
654fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    DO(Consume(")"));
655fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    name->set_is_extension(true);
656fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {  // This is a regular field.
657fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    DO(ConsumeIdentifier(&identifier, "Expected identifier."));
658fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    name->mutable_name_part()->append(identifier);
659fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    name->set_is_extension(false);
660fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
661fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
662fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
663fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
664fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// We don't interpret the option here. Instead we store it in an
665fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// UninterpretedOption, to be interpreted later.
666fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ParseOptionAssignment(Message* options) {
667fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Create an entry in the uninterpreted_option field.
668fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const FieldDescriptor* uninterpreted_option_field = options->GetDescriptor()->
669fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      FindFieldByName("uninterpreted_option");
670fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_CHECK(uninterpreted_option_field != NULL)
671fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      << "No field named \"uninterpreted_option\" in the Options proto.";
672fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
673fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  UninterpretedOption* uninterpreted_option = down_cast<UninterpretedOption*>(
674fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      options->GetReflection()->AddMessage(options,
675fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                           uninterpreted_option_field));
676fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
677fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Parse dot-separated name.
678fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  RecordLocation(uninterpreted_option,
679fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                 DescriptorPool::ErrorCollector::OPTION_NAME);
680fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
681fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(ParseOptionNamePart(uninterpreted_option));
682fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
683fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  while (LookingAt(".")) {
684fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    DO(Consume("."));
685fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    DO(ParseOptionNamePart(uninterpreted_option));
686fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
687fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
688fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume("="));
689fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
690fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  RecordLocation(uninterpreted_option,
691fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                 DescriptorPool::ErrorCollector::OPTION_VALUE);
692fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
693fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // All values are a single token, except for negative numbers, which consist
694fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // of a single '-' symbol, followed by a positive number.
695fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  bool is_negative = TryConsume("-");
696fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
697fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  switch (input_->current().type) {
698fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case io::Tokenizer::TYPE_START:
699fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      GOOGLE_LOG(FATAL) << "Trying to read value before any tokens have been read.";
700fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return false;
701fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
702fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case io::Tokenizer::TYPE_END:
703fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      AddError("Unexpected end of stream while parsing option value.");
704fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return false;
705fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
706fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case io::Tokenizer::TYPE_IDENTIFIER: {
707fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (is_negative) {
708fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        AddError("Invalid '-' symbol before identifier.");
709fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return false;
710fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
711fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      string value;
712fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      DO(ConsumeIdentifier(&value, "Expected identifier."));
713fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      uninterpreted_option->set_identifier_value(value);
714fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      break;
715fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
716fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
717fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case io::Tokenizer::TYPE_INTEGER: {
718fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      uint64 value;
719fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      uint64 max_value =
720fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          is_negative ? static_cast<uint64>(kint64max) + 1 : kuint64max;
721fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      DO(ConsumeInteger64(max_value, &value, "Expected integer."));
722fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (is_negative) {
723fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        uninterpreted_option->set_negative_int_value(-value);
724fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      } else {
725fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        uninterpreted_option->set_positive_int_value(value);
726fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
727fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      break;
728fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
729fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
730fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case io::Tokenizer::TYPE_FLOAT: {
731fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      double value;
732fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      DO(ConsumeNumber(&value, "Expected number."));
733fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      uninterpreted_option->set_double_value(is_negative ? -value : value);
734fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      break;
735fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
736fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
737fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case io::Tokenizer::TYPE_STRING: {
738fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (is_negative) {
739fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        AddError("Invalid '-' symbol before string.");
740fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return false;
741fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
742fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      string value;
743fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      DO(ConsumeString(&value, "Expected string."));
744fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      uninterpreted_option->set_string_value(value);
745fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      break;
746fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
747fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
748fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case io::Tokenizer::TYPE_SYMBOL:
749fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      AddError("Expected option value.");
750fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return false;
751fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
752fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
753fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
754fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
755fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
756fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ParseExtensions(DescriptorProto* message) {
757fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Parse the declaration.
758fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume("extensions"));
759fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
760fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  do {
761fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    DescriptorProto::ExtensionRange* range = message->add_extension_range();
762fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    RecordLocation(range, DescriptorPool::ErrorCollector::NUMBER);
763fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
764fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    int start, end;
765fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    DO(ConsumeInteger(&start, "Expected field number range."));
766fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
767fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (TryConsume("to")) {
768fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (TryConsume("max")) {
769fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        end = FieldDescriptor::kMaxNumber;
770fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      } else {
771fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        DO(ConsumeInteger(&end, "Expected integer."));
772fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
773fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
774fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      end = start;
775fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
776fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
777fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Users like to specify inclusive ranges, but in code we like the end
778fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // number to be exclusive.
779fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    ++end;
780fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
781fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    range->set_start(start);
782fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    range->set_end(end);
783fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } while (TryConsume(","));
784fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
785fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume(";"));
786fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
787fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
788fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
789fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
790fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                         RepeatedPtrField<DescriptorProto>* messages) {
791fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume("extend"));
792fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
793fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // We expect to see at least one extension field defined in the extend block.
794fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // We need to create it now so we can record the extendee's location.
795fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  FieldDescriptorProto* first_field = extensions->Add();
796fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
797fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Parse the extendee type.
798fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  RecordLocation(first_field, DescriptorPool::ErrorCollector::EXTENDEE);
799fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(ParseUserDefinedType(first_field->mutable_extendee()));
800fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
801fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Parse the block.
802fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume("{"));
803fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
804fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  bool is_first = true;
805fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
806fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  do {
807fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (AtEnd()) {
808fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      AddError("Reached end of input in extend definition (missing '}').");
809fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return false;
810fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
811fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
812fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    FieldDescriptorProto* field;
813fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (is_first) {
814fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      field = first_field;
815fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      is_first = false;
816fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
817fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      field = extensions->Add();
818fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      field->set_extendee(first_field->extendee());
819fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
820fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
821fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!ParseMessageField(field, messages)) {
822fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // This statement failed to parse.  Skip it, but keep looping to parse
823fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // other statements.
824fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      SkipStatement();
825fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
826fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } while(!TryConsume("}"));
827fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
828fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
829fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
830fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
831fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// -------------------------------------------------------------------
832fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Enums
833fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
834fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ParseEnumDefinition(EnumDescriptorProto* enum_type) {
835fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume("enum"));
836fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  RecordLocation(enum_type, DescriptorPool::ErrorCollector::NAME);
837fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(ConsumeIdentifier(enum_type->mutable_name(), "Expected enum name."));
838fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(ParseEnumBlock(enum_type));
839fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
840fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
841fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
842fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type) {
843fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume("{"));
844fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
845fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  while (!TryConsume("}")) {
846fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (AtEnd()) {
847fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      AddError("Reached end of input in enum definition (missing '}').");
848fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return false;
849fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
850fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
851fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!ParseEnumStatement(enum_type)) {
852fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // This statement failed to parse.  Skip it, but keep looping to parse
853fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // other statements.
854fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      SkipStatement();
855fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
856fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
857fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
858fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
859fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
860fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
861fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ParseEnumStatement(EnumDescriptorProto* enum_type) {
862fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (TryConsume(";")) {
863fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // empty statement; ignore
864fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
865fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else if (LookingAt("option")) {
866fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return ParseOption(enum_type->mutable_options());
867fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
868fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return ParseEnumConstant(enum_type->add_value());
869fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
870fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
871fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
872fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ParseEnumConstant(EnumValueDescriptorProto* enum_value) {
873fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  RecordLocation(enum_value, DescriptorPool::ErrorCollector::NAME);
874fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(ConsumeIdentifier(enum_value->mutable_name(),
875fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                       "Expected enum constant name."));
876fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume("=", "Missing numeric value for enum constant."));
877fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
878fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  bool is_negative = TryConsume("-");
879fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  int number;
880fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(ConsumeInteger(&number, "Expected integer."));
881fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (is_negative) number *= -1;
882fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  enum_value->set_number(number);
883fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
884fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(ParseEnumConstantOptions(enum_value));
885fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
886fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume(";"));
887fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
888fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
889fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
890fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
891fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ParseEnumConstantOptions(EnumValueDescriptorProto* value) {
892fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (!TryConsume("[")) return true;
893fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
894fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  do {
895fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    DO(ParseOptionAssignment(value->mutable_options()));
896fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } while (TryConsume(","));
897fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
898fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume("]"));
899fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
900fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
901fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
902fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// -------------------------------------------------------------------
903fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Services
904fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
905fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ParseServiceDefinition(ServiceDescriptorProto* service) {
906fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume("service"));
907fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  RecordLocation(service, DescriptorPool::ErrorCollector::NAME);
908fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(ConsumeIdentifier(service->mutable_name(), "Expected service name."));
909fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(ParseServiceBlock(service));
910fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
911fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
912fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
913fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ParseServiceBlock(ServiceDescriptorProto* service) {
914fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume("{"));
915fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
916fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  while (!TryConsume("}")) {
917fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (AtEnd()) {
918fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      AddError("Reached end of input in service definition (missing '}').");
919fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return false;
920fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
921fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
922fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!ParseServiceStatement(service)) {
923fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // This statement failed to parse.  Skip it, but keep looping to parse
924fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // other statements.
925fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      SkipStatement();
926fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
927fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
928fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
929fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
930fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
931fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
932fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ParseServiceStatement(ServiceDescriptorProto* service) {
933fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (TryConsume(";")) {
934fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // empty statement; ignore
935fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
936fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else if (LookingAt("option")) {
937fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return ParseOption(service->mutable_options());
938fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
939fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return ParseServiceMethod(service->add_method());
940fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
941fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
942fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
943fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ParseServiceMethod(MethodDescriptorProto* method) {
944fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume("rpc"));
945fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  RecordLocation(method, DescriptorPool::ErrorCollector::NAME);
946fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(ConsumeIdentifier(method->mutable_name(), "Expected method name."));
947fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
948fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Parse input type.
949fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume("("));
950fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  RecordLocation(method, DescriptorPool::ErrorCollector::INPUT_TYPE);
951fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(ParseUserDefinedType(method->mutable_input_type()));
952fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume(")"));
953fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
954fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Parse output type.
955fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume("returns"));
956fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume("("));
957fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  RecordLocation(method, DescriptorPool::ErrorCollector::OUTPUT_TYPE);
958fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(ParseUserDefinedType(method->mutable_output_type()));
959fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume(")"));
960fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
961fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (TryConsume("{")) {
962fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Options!
963fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    while (!TryConsume("}")) {
964fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (AtEnd()) {
965fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        AddError("Reached end of input in method options (missing '}').");
966fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return false;
967fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
968fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
969fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (TryConsume(";")) {
970fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        // empty statement; ignore
971fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      } else {
972fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        if (!ParseOption(method->mutable_options())) {
973fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          // This statement failed to parse.  Skip it, but keep looping to
974fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          // parse other statements.
975fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          SkipStatement();
976fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        }
977fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
978fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
979fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
980fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    DO(Consume(";"));
981fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
982fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
983fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
984fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
985fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
986fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// -------------------------------------------------------------------
987fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
988fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ParseLabel(FieldDescriptorProto::Label* label) {
989fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (TryConsume("optional")) {
990fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    *label = FieldDescriptorProto::LABEL_OPTIONAL;
991fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
992fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else if (TryConsume("repeated")) {
993fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    *label = FieldDescriptorProto::LABEL_REPEATED;
994fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
995fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else if (TryConsume("required")) {
996fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    *label = FieldDescriptorProto::LABEL_REQUIRED;
997fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
998fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
999fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    AddError("Expected \"required\", \"optional\", or \"repeated\".");
1000fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // We can actually reasonably recover here by just assuming the user
1001fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // forgot the label altogether.
1002fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    *label = FieldDescriptorProto::LABEL_OPTIONAL;
1003fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
1004fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1005fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1006fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1007fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ParseType(FieldDescriptorProto::Type* type,
1008fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                       string* type_name) {
1009fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  TypeNameMap::const_iterator iter = kTypeNames.find(input_->current().text);
1010fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (iter != kTypeNames.end()) {
1011fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    *type = iter->second;
1012fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    input_->Next();
1013fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
1014fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    DO(ParseUserDefinedType(type_name));
1015fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1016fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
1017fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1018fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1019fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ParseUserDefinedType(string* type_name) {
1020fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  type_name->clear();
1021fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1022fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  TypeNameMap::const_iterator iter = kTypeNames.find(input_->current().text);
1023fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (iter != kTypeNames.end()) {
1024fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Note:  The only place enum types are allowed is for field types, but
1025fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    //   if we are parsing a field type then we would not get here because
1026fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    //   primitives are allowed there as well.  So this error message doesn't
1027fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    //   need to account for enums.
1028fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    AddError("Expected message type.");
1029fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1030fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Pretend to accept this type so that we can go on parsing.
1031fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    *type_name = input_->current().text;
1032fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    input_->Next();
1033fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
1034fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1035fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1036fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // A leading "." means the name is fully-qualified.
1037fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (TryConsume(".")) type_name->append(".");
1038fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1039fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Consume the first part of the name.
1040fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string identifier;
1041fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(ConsumeIdentifier(&identifier, "Expected type name."));
1042fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  type_name->append(identifier);
1043fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1044fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Consume more parts.
1045fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  while (TryConsume(".")) {
1046fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    type_name->append(".");
1047fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    DO(ConsumeIdentifier(&identifier, "Expected identifier."));
1048fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    type_name->append(identifier);
1049fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1050fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1051fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
1052fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1053fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1054fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ===================================================================
1055fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1056fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ParsePackage(FileDescriptorProto* file) {
1057fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (file->has_package()) {
1058fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    AddError("Multiple package definitions.");
1059fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Don't append the new package to the old one.  Just replace it.  Not
1060fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // that it really matters since this is an error anyway.
1061fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    file->clear_package();
1062fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1063fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1064fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume("package"));
1065fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1066fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  RecordLocation(file, DescriptorPool::ErrorCollector::NAME);
1067fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1068fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  while (true) {
1069fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    string identifier;
1070fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    DO(ConsumeIdentifier(&identifier, "Expected identifier."));
1071fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    file->mutable_package()->append(identifier);
1072fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!TryConsume(".")) break;
1073fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    file->mutable_package()->append(".");
1074fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1075fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1076fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume(";"));
1077fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
1078fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1079fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1080fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ParseImport(string* import_filename) {
1081fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume("import"));
1082fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(ConsumeString(import_filename,
1083fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "Expected a string naming the file to import."));
1084fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume(";"));
1085fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
1086fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1087fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1088fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Parser::ParseOption(Message* options) {
1089fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume("option"));
1090fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(ParseOptionAssignment(options));
1091fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  DO(Consume(";"));
1092fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
1093fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1094fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1095fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ===================================================================
1096fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1097fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleSourceLocationTable::SourceLocationTable() {}
1098fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleSourceLocationTable::~SourceLocationTable() {}
1099fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool SourceLocationTable::Find(
1101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const Message* descriptor,
1102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    DescriptorPool::ErrorCollector::ErrorLocation location,
1103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    int* line, int* column) const {
1104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const pair<int, int>* result =
1105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    FindOrNull(location_map_, make_pair(descriptor, location));
1106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (result == NULL) {
1107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    *line   = -1;
1108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    *column = 0;
1109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
1110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
1111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    *line   = result->first;
1112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    *column = result->second;
1113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
1114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid SourceLocationTable::Add(
1118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const Message* descriptor,
1119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    DescriptorPool::ErrorCollector::ErrorLocation location,
1120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    int line, int column) {
1121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  location_map_[make_pair(descriptor, location)] = make_pair(line, column);
1122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid SourceLocationTable::Clear() {
1125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  location_map_.clear();
1126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace compiler
1129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace protobuf
1130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace google
1131