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