~ubuntu-branches/ubuntu/oneiric/mozc/oneiric

« back to all changes in this revision

Viewing changes to protobuf/files/src/google/protobuf/compiler/parser.cc

  • Committer: Bazaar Package Importer
  • Author(s): Nobuhiro Iwamatsu
  • Date: 2010-07-14 03:26:47 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100714032647-13qjisj6m8cm8jdx
Tags: 0.12.410.102-1
* New upstream release (Closes: #588971).
  - Add mozc-server, mozc-utils-gui and scim-mozc packages.
* Update debian/rules.
  Add --gypdir option to build_mozc.py.
* Update debian/control.
  - Bumped standards-version to 3.9.0.
  - Update description.
* Add mozc icon (Closes: #588972).
* Add patch which revises issue 18.
  ibus_mozc_issue18.patch
* kFreeBSD build support.
  support_kfreebsd.patch

Show diffs side-by-side

added added

removed removed

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