/thirdparty/breakpad/third_party/protobuf/protobuf/src/google/protobuf/text_format.cc
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