PageRenderTime 161ms CodeModel.GetById 74ms app.highlight 77ms RepoModel.GetById 2ms app.codeStats 0ms

/thirdparty/breakpad/third_party/protobuf/protobuf/src/google/protobuf/text_format.cc

http://github.com/tomahawk-player/tomahawk
C++ | 1285 lines | 944 code | 188 blank | 153 comment | 189 complexity | a95498726f54ca15a5c996add5504582 MD5 | raw file
   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: jschorr@google.com (Joseph Schorr)
  32//  Based on original Protocol Buffers design by
  33//  Sanjay Ghemawat, Jeff Dean, and others.
  34
  35#include <float.h>
  36#include <math.h>
  37#include <stdio.h>
  38#include <stack>
  39#include <limits>
  40#include <vector>
  41
  42#include <google/protobuf/text_format.h>
  43
  44#include <google/protobuf/descriptor.h>
  45#include <google/protobuf/io/coded_stream.h>
  46#include <google/protobuf/io/zero_copy_stream.h>
  47#include <google/protobuf/io/zero_copy_stream_impl.h>
  48#include <google/protobuf/unknown_field_set.h>
  49#include <google/protobuf/descriptor.pb.h>
  50#include <google/protobuf/io/tokenizer.h>
  51#include <google/protobuf/stubs/strutil.h>
  52
  53namespace google {
  54namespace protobuf {
  55
  56string Message::DebugString() const {
  57  string debug_string;
  58
  59  TextFormat::PrintToString(*this, &debug_string);
  60
  61  return debug_string;
  62}
  63
  64string Message::ShortDebugString() const {
  65  string debug_string;
  66
  67  TextFormat::Printer printer;
  68  printer.SetSingleLineMode(true);
  69
  70  printer.PrintToString(*this, &debug_string);
  71  // Single line mode currently might have an extra space at the end.
  72  if (debug_string.size() > 0 &&
  73      debug_string[debug_string.size() - 1] == ' ') {
  74    debug_string.resize(debug_string.size() - 1);
  75  }
  76
  77  return debug_string;
  78}
  79
  80string Message::Utf8DebugString() const {
  81  string debug_string;
  82
  83  TextFormat::Printer printer;
  84  printer.SetUseUtf8StringEscaping(true);
  85
  86  printer.PrintToString(*this, &debug_string);
  87
  88  return debug_string;
  89}
  90
  91void Message::PrintDebugString() const {
  92  printf("%s", DebugString().c_str());
  93}
  94
  95
  96// ===========================================================================
  97// Internal class for parsing an ASCII representation of a Protocol Message.
  98// This class makes use of the Protocol Message compiler's tokenizer found
  99// in //google/protobuf/io/tokenizer.h. Note that class's Parse
 100// method is *not* thread-safe and should only be used in a single thread at
 101// a time.
 102
 103// Makes code slightly more readable.  The meaning of "DO(foo)" is
 104// "Execute foo and fail if it fails.", where failure is indicated by
 105// returning false. Borrowed from parser.cc (Thanks Kenton!).
 106#define DO(STATEMENT) if (STATEMENT) {} else return false
 107
 108class TextFormat::Parser::ParserImpl {
 109 public:
 110
 111  // Determines if repeated values for a non-repeated field are
 112  // permitted, e.g., the string "foo: 1 foo: 2" for a
 113  // required/optional field named "foo".
 114  enum SingularOverwritePolicy {
 115    ALLOW_SINGULAR_OVERWRITES = 0,   // the last value is retained
 116    FORBID_SINGULAR_OVERWRITES = 1,  // an error is issued
 117  };
 118
 119  ParserImpl(const Descriptor* root_message_type,
 120             io::ZeroCopyInputStream* input_stream,
 121             io::ErrorCollector* error_collector,
 122             TextFormat::Finder* finder,
 123             SingularOverwritePolicy singular_overwrite_policy)
 124    : error_collector_(error_collector),
 125      finder_(finder),
 126      tokenizer_error_collector_(this),
 127      tokenizer_(input_stream, &tokenizer_error_collector_),
 128      root_message_type_(root_message_type),
 129      singular_overwrite_policy_(singular_overwrite_policy),
 130      had_errors_(false) {
 131    // For backwards-compatibility with proto1, we need to allow the 'f' suffix
 132    // for floats.
 133    tokenizer_.set_allow_f_after_float(true);
 134
 135    // '#' starts a comment.
 136    tokenizer_.set_comment_style(io::Tokenizer::SH_COMMENT_STYLE);
 137
 138    // Consume the starting token.
 139    tokenizer_.Next();
 140  }
 141  ~ParserImpl() { }
 142
 143  // Parses the ASCII representation specified in input and saves the
 144  // information into the output pointer (a Message). Returns
 145  // false if an error occurs (an error will also be logged to
 146  // GOOGLE_LOG(ERROR)).
 147  bool Parse(Message* output) {
 148    // Consume fields until we cannot do so anymore.
 149    while(true) {
 150      if (LookingAtType(io::Tokenizer::TYPE_END)) {
 151        return !had_errors_;
 152      }
 153
 154      DO(ConsumeField(output));
 155    }
 156  }
 157
 158  bool ParseField(const FieldDescriptor* field, Message* output) {
 159    bool suc;
 160    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
 161      suc = ConsumeFieldMessage(output, output->GetReflection(), field);
 162    } else {
 163      suc = ConsumeFieldValue(output, output->GetReflection(), field);
 164    }
 165    return suc && LookingAtType(io::Tokenizer::TYPE_END);
 166  }
 167
 168  void ReportError(int line, int col, const string& message) {
 169    had_errors_ = true;
 170    if (error_collector_ == NULL) {
 171      if (line >= 0) {
 172        GOOGLE_LOG(ERROR) << "Error parsing text-format "
 173                   << root_message_type_->full_name()
 174                   << ": " << (line + 1) << ":"
 175                   << (col + 1) << ": " << message;
 176      } else {
 177        GOOGLE_LOG(ERROR) << "Error parsing text-format "
 178                   << root_message_type_->full_name()
 179                   << ": " << message;
 180      }
 181    } else {
 182      error_collector_->AddError(line, col, message);
 183    }
 184  }
 185
 186  void ReportWarning(int line, int col, const string& message) {
 187    if (error_collector_ == NULL) {
 188      if (line >= 0) {
 189        GOOGLE_LOG(WARNING) << "Warning parsing text-format "
 190                     << root_message_type_->full_name()
 191                     << ": " << (line + 1) << ":"
 192                     << (col + 1) << ": " << message;
 193      } else {
 194        GOOGLE_LOG(WARNING) << "Warning parsing text-format "
 195                     << root_message_type_->full_name()
 196                     << ": " << message;
 197      }
 198    } else {
 199      error_collector_->AddWarning(line, col, message);
 200    }
 201  }
 202
 203 private:
 204  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserImpl);
 205
 206  // Reports an error with the given message with information indicating
 207  // the position (as derived from the current token).
 208  void ReportError(const string& message) {
 209    ReportError(tokenizer_.current().line, tokenizer_.current().column,
 210                message);
 211  }
 212
 213  // Reports a warning with the given message with information indicating
 214  // the position (as derived from the current token).
 215  void ReportWarning(const string& message) {
 216    ReportWarning(tokenizer_.current().line, tokenizer_.current().column,
 217                  message);
 218  }
 219
 220  // Consumes the specified message with the given starting delimeter.
 221  // This method checks to see that the end delimeter at the conclusion of
 222  // the consumption matches the starting delimeter passed in here.
 223  bool ConsumeMessage(Message* message, const string delimeter) {
 224    while (!LookingAt(">") &&  !LookingAt("}")) {
 225      DO(ConsumeField(message));
 226    }
 227
 228    // Confirm that we have a valid ending delimeter.
 229    DO(Consume(delimeter));
 230
 231    return true;
 232  }
 233
 234  // Consumes the current field (as returned by the tokenizer) on the
 235  // passed in message.
 236  bool ConsumeField(Message* message) {
 237    const Reflection* reflection = message->GetReflection();
 238    const Descriptor* descriptor = message->GetDescriptor();
 239
 240    string field_name;
 241
 242    const FieldDescriptor* field = NULL;
 243
 244    if (TryConsume("[")) {
 245      // Extension.
 246      DO(ConsumeIdentifier(&field_name));
 247      while (TryConsume(".")) {
 248        string part;
 249        DO(ConsumeIdentifier(&part));
 250        field_name += ".";
 251        field_name += part;
 252      }
 253      DO(Consume("]"));
 254
 255      field = (finder_ != NULL
 256               ? finder_->FindExtension(message, field_name)
 257               : reflection->FindKnownExtensionByName(field_name));
 258
 259      if (field == NULL) {
 260        ReportError("Extension \"" + field_name + "\" is not defined or "
 261                    "is not an extension of \"" +
 262                    descriptor->full_name() + "\".");
 263        return false;
 264      }
 265    } else {
 266      DO(ConsumeIdentifier(&field_name));
 267
 268      field = descriptor->FindFieldByName(field_name);
 269      // Group names are expected to be capitalized as they appear in the
 270      // .proto file, which actually matches their type names, not their field
 271      // names.
 272      if (field == NULL) {
 273        string lower_field_name = field_name;
 274        LowerString(&lower_field_name);
 275        field = descriptor->FindFieldByName(lower_field_name);
 276        // If the case-insensitive match worked but the field is NOT a group,
 277        if (field != NULL && field->type() != FieldDescriptor::TYPE_GROUP) {
 278          field = NULL;
 279        }
 280      }
 281      // Again, special-case group names as described above.
 282      if (field != NULL && field->type() == FieldDescriptor::TYPE_GROUP
 283          && field->message_type()->name() != field_name) {
 284        field = NULL;
 285      }
 286
 287      if (field == NULL) {
 288        ReportError("Message type \"" + descriptor->full_name() +
 289                    "\" has no field named \"" + field_name + "\".");
 290        return false;
 291      }
 292    }
 293
 294    // Fail if the field is not repeated and it has already been specified.
 295    if ((singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) &&
 296        !field->is_repeated() && reflection->HasField(*message, field)) {
 297      ReportError("Non-repeated field \"" + field_name +
 298                  "\" is specified multiple times.");
 299      return false;
 300    }
 301
 302    // Perform special handling for embedded message types.
 303    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
 304      // ':' is optional here.
 305      TryConsume(":");
 306      DO(ConsumeFieldMessage(message, reflection, field));
 307    } else {
 308      DO(Consume(":"));
 309      if (field->is_repeated() && TryConsume("[")) {
 310        // Short repeated format, e.g.  "foo: [1, 2, 3]"
 311        while (true) {
 312          DO(ConsumeFieldValue(message, reflection, field));
 313          if (TryConsume("]")) {
 314            break;
 315          }
 316          DO(Consume(","));
 317        }
 318      } else {
 319        DO(ConsumeFieldValue(message, reflection, field));
 320      }
 321    }
 322
 323    // For historical reasons, fields may optionally be separated by commas or
 324    // semicolons.
 325    TryConsume(";") || TryConsume(",");
 326
 327    if (field->options().deprecated()) {
 328      ReportWarning("text format contains deprecated field \""
 329                    + field_name + "\"");
 330    }
 331
 332    return true;
 333  }
 334
 335  bool ConsumeFieldMessage(Message* message,
 336                           const Reflection* reflection,
 337                           const FieldDescriptor* field) {
 338    string delimeter;
 339    if (TryConsume("<")) {
 340      delimeter = ">";
 341    } else {
 342      DO(Consume("{"));
 343      delimeter = "}";
 344    }
 345
 346    if (field->is_repeated()) {
 347      DO(ConsumeMessage(reflection->AddMessage(message, field), delimeter));
 348    } else {
 349      DO(ConsumeMessage(reflection->MutableMessage(message, field),
 350                        delimeter));
 351    }
 352    return true;
 353  }
 354
 355  bool ConsumeFieldValue(Message* message,
 356                         const Reflection* reflection,
 357                         const FieldDescriptor* field) {
 358
 359// Define an easy to use macro for setting fields. This macro checks
 360// to see if the field is repeated (in which case we need to use the Add
 361// methods or not (in which case we need to use the Set methods).
 362#define SET_FIELD(CPPTYPE, VALUE)                                  \
 363        if (field->is_repeated()) {                                \
 364          reflection->Add##CPPTYPE(message, field, VALUE);         \
 365        } else {                                                   \
 366          reflection->Set##CPPTYPE(message, field, VALUE);         \
 367        }                                                          \
 368
 369    switch(field->cpp_type()) {
 370      case FieldDescriptor::CPPTYPE_INT32: {
 371        int64 value;
 372        DO(ConsumeSignedInteger(&value, kint32max));
 373        SET_FIELD(Int32, static_cast<int32>(value));
 374        break;
 375      }
 376
 377      case FieldDescriptor::CPPTYPE_UINT32: {
 378        uint64 value;
 379        DO(ConsumeUnsignedInteger(&value, kuint32max));
 380        SET_FIELD(UInt32, static_cast<uint32>(value));
 381        break;
 382      }
 383
 384      case FieldDescriptor::CPPTYPE_INT64: {
 385        int64 value;
 386        DO(ConsumeSignedInteger(&value, kint64max));
 387        SET_FIELD(Int64, value);
 388        break;
 389      }
 390
 391      case FieldDescriptor::CPPTYPE_UINT64: {
 392        uint64 value;
 393        DO(ConsumeUnsignedInteger(&value, kuint64max));
 394        SET_FIELD(UInt64, value);
 395        break;
 396      }
 397
 398      case FieldDescriptor::CPPTYPE_FLOAT: {
 399        double value;
 400        DO(ConsumeDouble(&value));
 401        SET_FIELD(Float, static_cast<float>(value));
 402        break;
 403      }
 404
 405      case FieldDescriptor::CPPTYPE_DOUBLE: {
 406        double value;
 407        DO(ConsumeDouble(&value));
 408        SET_FIELD(Double, value);
 409        break;
 410      }
 411
 412      case FieldDescriptor::CPPTYPE_STRING: {
 413        string value;
 414        DO(ConsumeString(&value));
 415        SET_FIELD(String, value);
 416        break;
 417      }
 418
 419      case FieldDescriptor::CPPTYPE_BOOL: {
 420        if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
 421          uint64 value;
 422          DO(ConsumeUnsignedInteger(&value, 1));
 423          SET_FIELD(Bool, value);
 424        } else {
 425          string value;
 426          DO(ConsumeIdentifier(&value));
 427          if (value == "true" || value == "t") {
 428            SET_FIELD(Bool, true);
 429          } else if (value == "false" || value == "f") {
 430            SET_FIELD(Bool, false);
 431          } else {
 432            ReportError("Invalid value for boolean field \"" + field->name()
 433                        + "\". Value: \"" + value  + "\".");
 434            return false;
 435          }
 436        }
 437        break;
 438      }
 439
 440      case FieldDescriptor::CPPTYPE_ENUM: {
 441        string value;
 442        const EnumDescriptor* enum_type = field->enum_type();
 443        const EnumValueDescriptor* enum_value = NULL;
 444
 445        if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
 446          DO(ConsumeIdentifier(&value));
 447          // Find the enumeration value.
 448          enum_value = enum_type->FindValueByName(value);
 449
 450        } else if (LookingAt("-") ||
 451                   LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
 452          int64 int_value;
 453          DO(ConsumeSignedInteger(&int_value, kint32max));
 454          value = SimpleItoa(int_value);        // for error reporting
 455          enum_value = enum_type->FindValueByNumber(int_value);
 456        } else {
 457          ReportError("Expected integer or identifier.");
 458          return false;
 459        }
 460
 461        if (enum_value == NULL) {
 462          ReportError("Unknown enumeration value of \"" + value  + "\" for "
 463                      "field \"" + field->name() + "\".");
 464          return false;
 465        }
 466
 467        SET_FIELD(Enum, enum_value);
 468        break;
 469      }
 470
 471      case FieldDescriptor::CPPTYPE_MESSAGE: {
 472        // We should never get here. Put here instead of a default
 473        // so that if new types are added, we get a nice compiler warning.
 474        GOOGLE_LOG(FATAL) << "Reached an unintended state: CPPTYPE_MESSAGE";
 475        break;
 476      }
 477    }
 478#undef SET_FIELD
 479    return true;
 480  }
 481
 482  // Returns true if the current token's text is equal to that specified.
 483  bool LookingAt(const string& text) {
 484    return tokenizer_.current().text == text;
 485  }
 486
 487  // Returns true if the current token's type is equal to that specified.
 488  bool LookingAtType(io::Tokenizer::TokenType token_type) {
 489    return tokenizer_.current().type == token_type;
 490  }
 491
 492  // Consumes an identifier and saves its value in the identifier parameter.
 493  // Returns false if the token is not of type IDENTFIER.
 494  bool ConsumeIdentifier(string* identifier) {
 495    if (!LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
 496      ReportError("Expected identifier.");
 497      return false;
 498    }
 499
 500    *identifier = tokenizer_.current().text;
 501
 502    tokenizer_.Next();
 503    return true;
 504  }
 505
 506  // Consumes a string and saves its value in the text parameter.
 507  // Returns false if the token is not of type STRING.
 508  bool ConsumeString(string* text) {
 509    if (!LookingAtType(io::Tokenizer::TYPE_STRING)) {
 510      ReportError("Expected string.");
 511      return false;
 512    }
 513
 514    text->clear();
 515    while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
 516      io::Tokenizer::ParseStringAppend(tokenizer_.current().text, text);
 517
 518      tokenizer_.Next();
 519    }
 520
 521    return true;
 522  }
 523
 524  // Consumes a uint64 and saves its value in the value parameter.
 525  // Returns false if the token is not of type INTEGER.
 526  bool ConsumeUnsignedInteger(uint64* value, uint64 max_value) {
 527    if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
 528      ReportError("Expected integer.");
 529      return false;
 530    }
 531
 532    if (!io::Tokenizer::ParseInteger(tokenizer_.current().text,
 533                                     max_value, value)) {
 534      ReportError("Integer out of range.");
 535      return false;
 536    }
 537
 538    tokenizer_.Next();
 539    return true;
 540  }
 541
 542  // Consumes an int64 and saves its value in the value parameter.
 543  // Note that since the tokenizer does not support negative numbers,
 544  // we actually may consume an additional token (for the minus sign) in this
 545  // method. Returns false if the token is not an integer
 546  // (signed or otherwise).
 547  bool ConsumeSignedInteger(int64* value, uint64 max_value) {
 548    bool negative = false;
 549
 550    if (TryConsume("-")) {
 551      negative = true;
 552      // Two's complement always allows one more negative integer than
 553      // positive.
 554      ++max_value;
 555    }
 556
 557    uint64 unsigned_value;
 558
 559    DO(ConsumeUnsignedInteger(&unsigned_value, max_value));
 560
 561    *value = static_cast<int64>(unsigned_value);
 562
 563    if (negative) {
 564      *value = -*value;
 565    }
 566
 567    return true;
 568  }
 569
 570  // Consumes a double and saves its value in the value parameter.
 571  // Note that since the tokenizer does not support negative numbers,
 572  // we actually may consume an additional token (for the minus sign) in this
 573  // method. Returns false if the token is not a double
 574  // (signed or otherwise).
 575  bool ConsumeDouble(double* value) {
 576    bool negative = false;
 577
 578    if (TryConsume("-")) {
 579      negative = true;
 580    }
 581
 582    // A double can actually be an integer, according to the tokenizer.
 583    // Therefore, we must check both cases here.
 584    if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
 585      // We have found an integer value for the double.
 586      uint64 integer_value;
 587      DO(ConsumeUnsignedInteger(&integer_value, kuint64max));
 588
 589      *value = static_cast<double>(integer_value);
 590    } else if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) {
 591      // We have found a float value for the double.
 592      *value = io::Tokenizer::ParseFloat(tokenizer_.current().text);
 593
 594      // Mark the current token as consumed.
 595      tokenizer_.Next();
 596    } else if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
 597      string text = tokenizer_.current().text;
 598      LowerString(&text);
 599      if (text == "inf" || text == "infinity") {
 600        *value = std::numeric_limits<double>::infinity();
 601        tokenizer_.Next();
 602      } else if (text == "nan") {
 603        *value = std::numeric_limits<double>::quiet_NaN();
 604        tokenizer_.Next();
 605      } else {
 606        ReportError("Expected double.");
 607        return false;
 608      }
 609    } else {
 610      ReportError("Expected double.");
 611      return false;
 612    }
 613
 614    if (negative) {
 615      *value = -*value;
 616    }
 617
 618    return true;
 619  }
 620
 621  // Consumes a token and confirms that it matches that specified in the
 622  // value parameter. Returns false if the token found does not match that
 623  // which was specified.
 624  bool Consume(const string& value) {
 625    const string& current_value = tokenizer_.current().text;
 626
 627    if (current_value != value) {
 628      ReportError("Expected \"" + value + "\", found \"" + current_value
 629                  + "\".");
 630      return false;
 631    }
 632
 633    tokenizer_.Next();
 634
 635    return true;
 636  }
 637
 638  // Attempts to consume the supplied value. Returns false if a the
 639  // token found does not match the value specified.
 640  bool TryConsume(const string& value) {
 641    if (tokenizer_.current().text == value) {
 642      tokenizer_.Next();
 643      return true;
 644    } else {
 645      return false;
 646    }
 647  }
 648
 649  // An internal instance of the Tokenizer's error collector, used to
 650  // collect any base-level parse errors and feed them to the ParserImpl.
 651  class ParserErrorCollector : public io::ErrorCollector {
 652   public:
 653    explicit ParserErrorCollector(TextFormat::Parser::ParserImpl* parser) :
 654        parser_(parser) { }
 655
 656    virtual ~ParserErrorCollector() { };
 657
 658    virtual void AddError(int line, int column, const string& message) {
 659      parser_->ReportError(line, column, message);
 660    }
 661
 662    virtual void AddWarning(int line, int column, const string& message) {
 663      parser_->ReportWarning(line, column, message);
 664    }
 665
 666   private:
 667    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserErrorCollector);
 668    TextFormat::Parser::ParserImpl* parser_;
 669  };
 670
 671  io::ErrorCollector* error_collector_;
 672  TextFormat::Finder* finder_;
 673  ParserErrorCollector tokenizer_error_collector_;
 674  io::Tokenizer tokenizer_;
 675  const Descriptor* root_message_type_;
 676  SingularOverwritePolicy singular_overwrite_policy_;
 677  bool had_errors_;
 678};
 679
 680#undef DO
 681
 682// ===========================================================================
 683// Internal class for writing text to the io::ZeroCopyOutputStream. Adapted
 684// from the Printer found in //google/protobuf/io/printer.h
 685class TextFormat::Printer::TextGenerator {
 686 public:
 687  explicit TextGenerator(io::ZeroCopyOutputStream* output,
 688                         int initial_indent_level)
 689    : output_(output),
 690      buffer_(NULL),
 691      buffer_size_(0),
 692      at_start_of_line_(true),
 693      failed_(false),
 694      indent_(""),
 695      initial_indent_level_(initial_indent_level) {
 696    indent_.resize(initial_indent_level_ * 2, ' ');
 697  }
 698
 699  ~TextGenerator() {
 700    // Only BackUp() if we're sure we've successfully called Next() at least
 701    // once.
 702    if (buffer_size_ > 0) {
 703      output_->BackUp(buffer_size_);
 704    }
 705  }
 706
 707  // Indent text by two spaces.  After calling Indent(), two spaces will be
 708  // inserted at the beginning of each line of text.  Indent() may be called
 709  // multiple times to produce deeper indents.
 710  void Indent() {
 711    indent_ += "  ";
 712  }
 713
 714  // Reduces the current indent level by two spaces, or crashes if the indent
 715  // level is zero.
 716  void Outdent() {
 717    if (indent_.empty() ||
 718        indent_.size() < initial_indent_level_ * 2) {
 719      GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent().";
 720      return;
 721    }
 722
 723    indent_.resize(indent_.size() - 2);
 724  }
 725
 726  // Print text to the output stream.
 727  void Print(const string& str) {
 728    Print(str.data(), str.size());
 729  }
 730
 731  // Print text to the output stream.
 732  void Print(const char* text) {
 733    Print(text, strlen(text));
 734  }
 735
 736  // Print text to the output stream.
 737  void Print(const char* text, int size) {
 738    int pos = 0;  // The number of bytes we've written so far.
 739
 740    for (int i = 0; i < size; i++) {
 741      if (text[i] == '\n') {
 742        // Saw newline.  If there is more text, we may need to insert an indent
 743        // here.  So, write what we have so far, including the '\n'.
 744        Write(text + pos, i - pos + 1);
 745        pos = i + 1;
 746
 747        // Setting this true will cause the next Write() to insert an indent
 748        // first.
 749        at_start_of_line_ = true;
 750      }
 751    }
 752
 753    // Write the rest.
 754    Write(text + pos, size - pos);
 755  }
 756
 757  // True if any write to the underlying stream failed.  (We don't just
 758  // crash in this case because this is an I/O failure, not a programming
 759  // error.)
 760  bool failed() const { return failed_; }
 761
 762 private:
 763  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextGenerator);
 764
 765  void Write(const char* data, int size) {
 766    if (failed_) return;
 767    if (size == 0) return;
 768
 769    if (at_start_of_line_) {
 770      // Insert an indent.
 771      at_start_of_line_ = false;
 772      Write(indent_.data(), indent_.size());
 773      if (failed_) return;
 774    }
 775
 776    while (size > buffer_size_) {
 777      // Data exceeds space in the buffer.  Copy what we can and request a
 778      // new buffer.
 779      memcpy(buffer_, data, buffer_size_);
 780      data += buffer_size_;
 781      size -= buffer_size_;
 782      void* void_buffer;
 783      failed_ = !output_->Next(&void_buffer, &buffer_size_);
 784      if (failed_) return;
 785      buffer_ = reinterpret_cast<char*>(void_buffer);
 786    }
 787
 788    // Buffer is big enough to receive the data; copy it.
 789    memcpy(buffer_, data, size);
 790    buffer_ += size;
 791    buffer_size_ -= size;
 792  }
 793
 794  io::ZeroCopyOutputStream* const output_;
 795  char* buffer_;
 796  int buffer_size_;
 797  bool at_start_of_line_;
 798  bool failed_;
 799
 800  string indent_;
 801  int initial_indent_level_;
 802};
 803
 804// ===========================================================================
 805
 806TextFormat::Finder::~Finder() {
 807}
 808
 809TextFormat::Parser::Parser()
 810  : error_collector_(NULL),
 811    finder_(NULL),
 812    allow_partial_(false) {
 813}
 814
 815TextFormat::Parser::~Parser() {}
 816
 817bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input,
 818                               Message* output) {
 819  output->Clear();
 820  ParserImpl parser(output->GetDescriptor(), input, error_collector_,
 821                    finder_, ParserImpl::FORBID_SINGULAR_OVERWRITES);
 822  return MergeUsingImpl(input, output, &parser);
 823}
 824
 825bool TextFormat::Parser::ParseFromString(const string& input,
 826                                         Message* output) {
 827  io::ArrayInputStream input_stream(input.data(), input.size());
 828  return Parse(&input_stream, output);
 829}
 830
 831bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input,
 832                               Message* output) {
 833  ParserImpl parser(output->GetDescriptor(), input, error_collector_,
 834                    finder_, ParserImpl::ALLOW_SINGULAR_OVERWRITES);
 835  return MergeUsingImpl(input, output, &parser);
 836}
 837
 838bool TextFormat::Parser::MergeFromString(const string& input,
 839                                         Message* output) {
 840  io::ArrayInputStream input_stream(input.data(), input.size());
 841  return Merge(&input_stream, output);
 842}
 843
 844bool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* input,
 845                                        Message* output,
 846                                        ParserImpl* parser_impl) {
 847  if (!parser_impl->Parse(output)) return false;
 848  if (!allow_partial_ && !output->IsInitialized()) {
 849    vector<string> missing_fields;
 850    output->FindInitializationErrors(&missing_fields);
 851    parser_impl->ReportError(-1, 0, "Message missing required fields: " +
 852                                    JoinStrings(missing_fields, ", "));
 853    return false;
 854  }
 855  return true;
 856}
 857
 858bool TextFormat::Parser::ParseFieldValueFromString(
 859    const string& input,
 860    const FieldDescriptor* field,
 861    Message* output) {
 862  io::ArrayInputStream input_stream(input.data(), input.size());
 863  ParserImpl parser(output->GetDescriptor(), &input_stream, error_collector_,
 864                    finder_, ParserImpl::ALLOW_SINGULAR_OVERWRITES);
 865  return parser.ParseField(field, output);
 866}
 867
 868/* static */ bool TextFormat::Parse(io::ZeroCopyInputStream* input,
 869                                    Message* output) {
 870  return Parser().Parse(input, output);
 871}
 872
 873/* static */ bool TextFormat::Merge(io::ZeroCopyInputStream* input,
 874                                    Message* output) {
 875  return Parser().Merge(input, output);
 876}
 877
 878/* static */ bool TextFormat::ParseFromString(const string& input,
 879                                              Message* output) {
 880  return Parser().ParseFromString(input, output);
 881}
 882
 883/* static */ bool TextFormat::MergeFromString(const string& input,
 884                                              Message* output) {
 885  return Parser().MergeFromString(input, output);
 886}
 887
 888// ===========================================================================
 889
 890TextFormat::Printer::Printer()
 891  : initial_indent_level_(0),
 892    single_line_mode_(false),
 893    use_short_repeated_primitives_(false),
 894    utf8_string_escaping_(false) {}
 895
 896TextFormat::Printer::~Printer() {}
 897
 898bool TextFormat::Printer::PrintToString(const Message& message,
 899                                        string* output) const {
 900  GOOGLE_DCHECK(output) << "output specified is NULL";
 901
 902  output->clear();
 903  io::StringOutputStream output_stream(output);
 904
 905  bool result = Print(message, &output_stream);
 906
 907  return result;
 908}
 909
 910bool TextFormat::Printer::PrintUnknownFieldsToString(
 911    const UnknownFieldSet& unknown_fields,
 912    string* output) const {
 913  GOOGLE_DCHECK(output) << "output specified is NULL";
 914
 915  output->clear();
 916  io::StringOutputStream output_stream(output);
 917  return PrintUnknownFields(unknown_fields, &output_stream);
 918}
 919
 920bool TextFormat::Printer::Print(const Message& message,
 921                                io::ZeroCopyOutputStream* output) const {
 922  TextGenerator generator(output, initial_indent_level_);
 923
 924  Print(message, generator);
 925
 926  // Output false if the generator failed internally.
 927  return !generator.failed();
 928}
 929
 930bool TextFormat::Printer::PrintUnknownFields(
 931    const UnknownFieldSet& unknown_fields,
 932    io::ZeroCopyOutputStream* output) const {
 933  TextGenerator generator(output, initial_indent_level_);
 934
 935  PrintUnknownFields(unknown_fields, generator);
 936
 937  // Output false if the generator failed internally.
 938  return !generator.failed();
 939}
 940
 941void TextFormat::Printer::Print(const Message& message,
 942                                TextGenerator& generator) const {
 943  const Reflection* reflection = message.GetReflection();
 944  vector<const FieldDescriptor*> fields;
 945  reflection->ListFields(message, &fields);
 946  for (int i = 0; i < fields.size(); i++) {
 947    PrintField(message, reflection, fields[i], generator);
 948  }
 949  PrintUnknownFields(reflection->GetUnknownFields(message), generator);
 950}
 951
 952void TextFormat::Printer::PrintFieldValueToString(
 953    const Message& message,
 954    const FieldDescriptor* field,
 955    int index,
 956    string* output) const {
 957
 958  GOOGLE_DCHECK(output) << "output specified is NULL";
 959
 960  output->clear();
 961  io::StringOutputStream output_stream(output);
 962  TextGenerator generator(&output_stream, initial_indent_level_);
 963
 964  PrintFieldValue(message, message.GetReflection(), field, index, generator);
 965}
 966
 967void TextFormat::Printer::PrintField(const Message& message,
 968                                     const Reflection* reflection,
 969                                     const FieldDescriptor* field,
 970                                     TextGenerator& generator) const {
 971  if (use_short_repeated_primitives_ &&
 972      field->is_repeated() &&
 973      field->cpp_type() != FieldDescriptor::CPPTYPE_STRING &&
 974      field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
 975    PrintShortRepeatedField(message, reflection, field, generator);
 976    return;
 977  }
 978
 979  int count = 0;
 980
 981  if (field->is_repeated()) {
 982    count = reflection->FieldSize(message, field);
 983  } else if (reflection->HasField(message, field)) {
 984    count = 1;
 985  }
 986
 987  for (int j = 0; j < count; ++j) {
 988    PrintFieldName(message, reflection, field, generator);
 989
 990    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
 991      if (single_line_mode_) {
 992        generator.Print(" { ");
 993      } else {
 994        generator.Print(" {\n");
 995        generator.Indent();
 996      }
 997    } else {
 998      generator.Print(": ");
 999    }
1000
1001    // Write the field value.
1002    int field_index = j;
1003    if (!field->is_repeated()) {
1004      field_index = -1;
1005    }
1006
1007    PrintFieldValue(message, reflection, field, field_index, generator);
1008
1009    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
1010      if (single_line_mode_) {
1011        generator.Print("} ");
1012      } else {
1013        generator.Outdent();
1014        generator.Print("}\n");
1015      }
1016    } else {
1017      if (single_line_mode_) {
1018        generator.Print(" ");
1019      } else {
1020        generator.Print("\n");
1021      }
1022    }
1023  }
1024}
1025
1026void TextFormat::Printer::PrintShortRepeatedField(
1027    const Message& message,
1028    const Reflection* reflection,
1029    const FieldDescriptor* field,
1030    TextGenerator& generator) const {
1031  // Print primitive repeated field in short form.
1032  PrintFieldName(message, reflection, field, generator);
1033
1034  int size = reflection->FieldSize(message, field);
1035  generator.Print(": [");
1036  for (int i = 0; i < size; i++) {
1037    if (i > 0) generator.Print(", ");
1038    PrintFieldValue(message, reflection, field, i, generator);
1039  }
1040  if (single_line_mode_) {
1041    generator.Print("] ");
1042  } else {
1043    generator.Print("]\n");
1044  }
1045}
1046
1047void TextFormat::Printer::PrintFieldName(const Message& message,
1048                                         const Reflection* reflection,
1049                                         const FieldDescriptor* field,
1050                                         TextGenerator& generator) const {
1051  if (field->is_extension()) {
1052    generator.Print("[");
1053    // We special-case MessageSet elements for compatibility with proto1.
1054    if (field->containing_type()->options().message_set_wire_format()
1055        && field->type() == FieldDescriptor::TYPE_MESSAGE
1056        && field->is_optional()
1057        && field->extension_scope() == field->message_type()) {
1058      generator.Print(field->message_type()->full_name());
1059    } else {
1060      generator.Print(field->full_name());
1061    }
1062    generator.Print("]");
1063  } else {
1064    if (field->type() == FieldDescriptor::TYPE_GROUP) {
1065      // Groups must be serialized with their original capitalization.
1066      generator.Print(field->message_type()->name());
1067    } else {
1068      generator.Print(field->name());
1069    }
1070  }
1071}
1072
1073void TextFormat::Printer::PrintFieldValue(
1074    const Message& message,
1075    const Reflection* reflection,
1076    const FieldDescriptor* field,
1077    int index,
1078    TextGenerator& generator) const {
1079  GOOGLE_DCHECK(field->is_repeated() || (index == -1))
1080      << "Index must be -1 for non-repeated fields";
1081
1082  switch (field->cpp_type()) {
1083#define OUTPUT_FIELD(CPPTYPE, METHOD, TO_STRING)                             \
1084      case FieldDescriptor::CPPTYPE_##CPPTYPE:                               \
1085        generator.Print(TO_STRING(field->is_repeated() ?                     \
1086          reflection->GetRepeated##METHOD(message, field, index) :           \
1087          reflection->Get##METHOD(message, field)));                         \
1088        break;                                                               \
1089
1090      OUTPUT_FIELD( INT32,  Int32, SimpleItoa);
1091      OUTPUT_FIELD( INT64,  Int64, SimpleItoa);
1092      OUTPUT_FIELD(UINT32, UInt32, SimpleItoa);
1093      OUTPUT_FIELD(UINT64, UInt64, SimpleItoa);
1094      OUTPUT_FIELD( FLOAT,  Float, SimpleFtoa);
1095      OUTPUT_FIELD(DOUBLE, Double, SimpleDtoa);
1096#undef OUTPUT_FIELD
1097
1098      case FieldDescriptor::CPPTYPE_STRING: {
1099        string scratch;
1100        const string& value = field->is_repeated() ?
1101            reflection->GetRepeatedStringReference(
1102              message, field, index, &scratch) :
1103            reflection->GetStringReference(message, field, &scratch);
1104
1105        generator.Print("\"");
1106        if (utf8_string_escaping_) {
1107          generator.Print(strings::Utf8SafeCEscape(value));
1108        } else {
1109          generator.Print(CEscape(value));
1110        }
1111        generator.Print("\"");
1112
1113        break;
1114      }
1115
1116      case FieldDescriptor::CPPTYPE_BOOL:
1117        if (field->is_repeated()) {
1118          generator.Print(reflection->GetRepeatedBool(message, field, index)
1119                          ? "true" : "false");
1120        } else {
1121          generator.Print(reflection->GetBool(message, field)
1122                          ? "true" : "false");
1123        }
1124        break;
1125
1126      case FieldDescriptor::CPPTYPE_ENUM:
1127        generator.Print(field->is_repeated() ?
1128          reflection->GetRepeatedEnum(message, field, index)->name() :
1129          reflection->GetEnum(message, field)->name());
1130        break;
1131
1132      case FieldDescriptor::CPPTYPE_MESSAGE:
1133        Print(field->is_repeated() ?
1134                reflection->GetRepeatedMessage(message, field, index) :
1135                reflection->GetMessage(message, field),
1136              generator);
1137        break;
1138  }
1139}
1140
1141/* static */ bool TextFormat::Print(const Message& message,
1142                                    io::ZeroCopyOutputStream* output) {
1143  return Printer().Print(message, output);
1144}
1145
1146/* static */ bool TextFormat::PrintUnknownFields(
1147    const UnknownFieldSet& unknown_fields,
1148    io::ZeroCopyOutputStream* output) {
1149  return Printer().PrintUnknownFields(unknown_fields, output);
1150}
1151
1152/* static */ bool TextFormat::PrintToString(
1153    const Message& message, string* output) {
1154  return Printer().PrintToString(message, output);
1155}
1156
1157/* static */ bool TextFormat::PrintUnknownFieldsToString(
1158    const UnknownFieldSet& unknown_fields, string* output) {
1159  return Printer().PrintUnknownFieldsToString(unknown_fields, output);
1160}
1161
1162/* static */ void TextFormat::PrintFieldValueToString(
1163    const Message& message,
1164    const FieldDescriptor* field,
1165    int index,
1166    string* output) {
1167  return Printer().PrintFieldValueToString(message, field, index, output);
1168}
1169
1170/* static */ bool TextFormat::ParseFieldValueFromString(
1171    const string& input,
1172    const FieldDescriptor* field,
1173    Message* message) {
1174  return Parser().ParseFieldValueFromString(input, field, message);
1175}
1176
1177// Prints an integer as hex with a fixed number of digits dependent on the
1178// integer type.
1179template<typename IntType>
1180static string PaddedHex(IntType value) {
1181  string result;
1182  result.reserve(sizeof(value) * 2);
1183  for (int i = sizeof(value) * 2 - 1; i >= 0; i--) {
1184    result.push_back(int_to_hex_digit(value >> (i*4) & 0x0F));
1185  }
1186  return result;
1187}
1188
1189void TextFormat::Printer::PrintUnknownFields(
1190    const UnknownFieldSet& unknown_fields, TextGenerator& generator) const {
1191  for (int i = 0; i < unknown_fields.field_count(); i++) {
1192    const UnknownField& field = unknown_fields.field(i);
1193    string field_number = SimpleItoa(field.number());
1194
1195    switch (field.type()) {
1196      case UnknownField::TYPE_VARINT:
1197        generator.Print(field_number);
1198        generator.Print(": ");
1199        generator.Print(SimpleItoa(field.varint()));
1200        if (single_line_mode_) {
1201          generator.Print(" ");
1202        } else {
1203          generator.Print("\n");
1204        }
1205        break;
1206      case UnknownField::TYPE_FIXED32: {
1207        generator.Print(field_number);
1208        generator.Print(": 0x");
1209        char buffer[kFastToBufferSize];
1210        generator.Print(FastHex32ToBuffer(field.fixed32(), buffer));
1211        if (single_line_mode_) {
1212          generator.Print(" ");
1213        } else {
1214          generator.Print("\n");
1215        }
1216        break;
1217      }
1218      case UnknownField::TYPE_FIXED64: {
1219        generator.Print(field_number);
1220        generator.Print(": 0x");
1221        char buffer[kFastToBufferSize];
1222        generator.Print(FastHex64ToBuffer(field.fixed64(), buffer));
1223        if (single_line_mode_) {
1224          generator.Print(" ");
1225        } else {
1226          generator.Print("\n");
1227        }
1228        break;
1229      }
1230      case UnknownField::TYPE_LENGTH_DELIMITED: {
1231        generator.Print(field_number);
1232        const string& value = field.length_delimited();
1233        UnknownFieldSet embedded_unknown_fields;
1234        if (!value.empty() && embedded_unknown_fields.ParseFromString(value)) {
1235          // This field is parseable as a Message.
1236          // So it is probably an embedded message.
1237          if (single_line_mode_) {
1238            generator.Print(" { ");
1239          } else {
1240            generator.Print(" {\n");
1241            generator.Indent();
1242          }
1243          PrintUnknownFields(embedded_unknown_fields, generator);
1244          if (single_line_mode_) {
1245            generator.Print("} ");
1246          } else {
1247            generator.Outdent();
1248            generator.Print("}\n");
1249          }
1250        } else {
1251          // This field is not parseable as a Message.
1252          // So it is probably just a plain string.
1253          generator.Print(": \"");
1254          generator.Print(CEscape(value));
1255          generator.Print("\"");
1256          if (single_line_mode_) {
1257            generator.Print(" ");
1258          } else {
1259            generator.Print("\n");
1260          }
1261        }
1262        break;
1263      }
1264      case UnknownField::TYPE_GROUP:
1265        generator.Print(field_number);
1266        if (single_line_mode_) {
1267          generator.Print(" { ");
1268        } else {
1269          generator.Print(" {\n");
1270          generator.Indent();
1271        }
1272        PrintUnknownFields(field.group(), generator);
1273        if (single_line_mode_) {
1274          generator.Print("} ");
1275        } else {
1276          generator.Outdent();
1277          generator.Print("}\n");
1278        }
1279        break;
1280    }
1281  }
1282}
1283
1284}  // namespace protobuf
1285}  // namespace google