| OLD | NEW |
| 1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
| 2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
| 3 // https://developers.google.com/protocol-buffers/ | 3 // https://developers.google.com/protocol-buffers/ |
| 4 // | 4 // |
| 5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
| 6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
| 7 // met: | 7 // met: |
| 8 // | 8 // |
| 9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
| 10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 void TextFormat::ParseInfoTree::RecordLocation( | 147 void TextFormat::ParseInfoTree::RecordLocation( |
| 148 const FieldDescriptor* field, | 148 const FieldDescriptor* field, |
| 149 TextFormat::ParseLocation location) { | 149 TextFormat::ParseLocation location) { |
| 150 locations_[field].push_back(location); | 150 locations_[field].push_back(location); |
| 151 } | 151 } |
| 152 | 152 |
| 153 TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::CreateNested( | 153 TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::CreateNested( |
| 154 const FieldDescriptor* field) { | 154 const FieldDescriptor* field) { |
| 155 // Owned by us in the map. | 155 // Owned by us in the map. |
| 156 TextFormat::ParseInfoTree* instance = new TextFormat::ParseInfoTree(); | 156 TextFormat::ParseInfoTree* instance = new TextFormat::ParseInfoTree(); |
| 157 std::vector<TextFormat::ParseInfoTree*>* trees = &nested_[field]; | 157 vector<TextFormat::ParseInfoTree*>* trees = &nested_[field]; |
| 158 GOOGLE_CHECK(trees); | 158 GOOGLE_CHECK(trees); |
| 159 trees->push_back(instance); | 159 trees->push_back(instance); |
| 160 return instance; | 160 return instance; |
| 161 } | 161 } |
| 162 | 162 |
| 163 void CheckFieldIndex(const FieldDescriptor* field, int index) { | 163 void CheckFieldIndex(const FieldDescriptor* field, int index) { |
| 164 if (field == NULL) { return; } | 164 if (field == NULL) { return; } |
| 165 | 165 |
| 166 if (field->is_repeated() && index == -1) { | 166 if (field->is_repeated() && index == -1) { |
| 167 GOOGLE_LOG(DFATAL) << "Index must be in range of repeated field values. " | 167 GOOGLE_LOG(DFATAL) << "Index must be in range of repeated field values. " |
| 168 << "Field: " << field->name(); | 168 << "Field: " << field->name(); |
| 169 } else if (!field->is_repeated() && index != -1) { | 169 } else if (!field->is_repeated() && index != -1) { |
| 170 GOOGLE_LOG(DFATAL) << "Index must be -1 for singular fields." | 170 GOOGLE_LOG(DFATAL) << "Index must be -1 for singular fields." |
| 171 << "Field: " << field->name(); | 171 << "Field: " << field->name(); |
| 172 } | 172 } |
| 173 } | 173 } |
| 174 | 174 |
| 175 TextFormat::ParseLocation TextFormat::ParseInfoTree::GetLocation( | 175 TextFormat::ParseLocation TextFormat::ParseInfoTree::GetLocation( |
| 176 const FieldDescriptor* field, int index) const { | 176 const FieldDescriptor* field, int index) const { |
| 177 CheckFieldIndex(field, index); | 177 CheckFieldIndex(field, index); |
| 178 if (index == -1) { index = 0; } | 178 if (index == -1) { index = 0; } |
| 179 | 179 |
| 180 const std::vector<TextFormat::ParseLocation>* locations = | 180 const vector<TextFormat::ParseLocation>* locations = |
| 181 FindOrNull(locations_, field); | 181 FindOrNull(locations_, field); |
| 182 if (locations == NULL || index >= locations->size()) { | 182 if (locations == NULL || index >= locations->size()) { |
| 183 return TextFormat::ParseLocation(); | 183 return TextFormat::ParseLocation(); |
| 184 } | 184 } |
| 185 | 185 |
| 186 return (*locations)[index]; | 186 return (*locations)[index]; |
| 187 } | 187 } |
| 188 | 188 |
| 189 TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::GetTreeForNested( | 189 TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::GetTreeForNested( |
| 190 const FieldDescriptor* field, int index) const { | 190 const FieldDescriptor* field, int index) const { |
| 191 CheckFieldIndex(field, index); | 191 CheckFieldIndex(field, index); |
| 192 if (index == -1) { index = 0; } | 192 if (index == -1) { index = 0; } |
| 193 | 193 |
| 194 const std::vector<TextFormat::ParseInfoTree*>* trees = | 194 const vector<TextFormat::ParseInfoTree*>* trees = FindOrNull(nested_, field); |
| 195 FindOrNull(nested_, field); | |
| 196 if (trees == NULL || index >= trees->size()) { | 195 if (trees == NULL || index >= trees->size()) { |
| 197 return NULL; | 196 return NULL; |
| 198 } | 197 } |
| 199 | 198 |
| 200 return (*trees)[index]; | 199 return (*trees)[index]; |
| 201 } | 200 } |
| 202 | 201 |
| 203 | 202 |
| 204 // =========================================================================== | 203 // =========================================================================== |
| 205 // Internal class for parsing an ASCII representation of a Protocol Message. | 204 // Internal class for parsing an ASCII representation of a Protocol Message. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 228 ParserImpl(const Descriptor* root_message_type, | 227 ParserImpl(const Descriptor* root_message_type, |
| 229 io::ZeroCopyInputStream* input_stream, | 228 io::ZeroCopyInputStream* input_stream, |
| 230 io::ErrorCollector* error_collector, | 229 io::ErrorCollector* error_collector, |
| 231 TextFormat::Finder* finder, | 230 TextFormat::Finder* finder, |
| 232 ParseInfoTree* parse_info_tree, | 231 ParseInfoTree* parse_info_tree, |
| 233 SingularOverwritePolicy singular_overwrite_policy, | 232 SingularOverwritePolicy singular_overwrite_policy, |
| 234 bool allow_case_insensitive_field, | 233 bool allow_case_insensitive_field, |
| 235 bool allow_unknown_field, | 234 bool allow_unknown_field, |
| 236 bool allow_unknown_enum, | 235 bool allow_unknown_enum, |
| 237 bool allow_field_number, | 236 bool allow_field_number, |
| 238 bool allow_relaxed_whitespace, | 237 bool allow_relaxed_whitespace) |
| 239 bool allow_partial) | |
| 240 : error_collector_(error_collector), | 238 : error_collector_(error_collector), |
| 241 finder_(finder), | 239 finder_(finder), |
| 242 parse_info_tree_(parse_info_tree), | 240 parse_info_tree_(parse_info_tree), |
| 243 tokenizer_error_collector_(this), | 241 tokenizer_error_collector_(this), |
| 244 tokenizer_(input_stream, &tokenizer_error_collector_), | 242 tokenizer_(input_stream, &tokenizer_error_collector_), |
| 245 root_message_type_(root_message_type), | 243 root_message_type_(root_message_type), |
| 246 singular_overwrite_policy_(singular_overwrite_policy), | 244 singular_overwrite_policy_(singular_overwrite_policy), |
| 247 allow_case_insensitive_field_(allow_case_insensitive_field), | 245 allow_case_insensitive_field_(allow_case_insensitive_field), |
| 248 allow_unknown_field_(allow_unknown_field), | 246 allow_unknown_field_(allow_unknown_field), |
| 249 allow_unknown_enum_(allow_unknown_enum), | 247 allow_unknown_enum_(allow_unknown_enum), |
| 250 allow_field_number_(allow_field_number), | 248 allow_field_number_(allow_field_number), |
| 251 allow_partial_(allow_partial), | |
| 252 had_errors_(false) { | 249 had_errors_(false) { |
| 253 // For backwards-compatibility with proto1, we need to allow the 'f' suffix | 250 // For backwards-compatibility with proto1, we need to allow the 'f' suffix |
| 254 // for floats. | 251 // for floats. |
| 255 tokenizer_.set_allow_f_after_float(true); | 252 tokenizer_.set_allow_f_after_float(true); |
| 256 | 253 |
| 257 // '#' starts a comment. | 254 // '#' starts a comment. |
| 258 tokenizer_.set_comment_style(io::Tokenizer::SH_COMMENT_STYLE); | 255 tokenizer_.set_comment_style(io::Tokenizer::SH_COMMENT_STYLE); |
| 259 | 256 |
| 260 if (allow_relaxed_whitespace) { | 257 if (allow_relaxed_whitespace) { |
| 261 tokenizer_.set_require_space_after_number(false); | 258 tokenizer_.set_require_space_after_number(false); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 &any_value_field) && | 384 &any_value_field) && |
| 388 TryConsume("[")) { | 385 TryConsume("[")) { |
| 389 string full_type_name, prefix; | 386 string full_type_name, prefix; |
| 390 DO(ConsumeAnyTypeUrl(&full_type_name, &prefix)); | 387 DO(ConsumeAnyTypeUrl(&full_type_name, &prefix)); |
| 391 DO(Consume("]")); | 388 DO(Consume("]")); |
| 392 TryConsume(":"); // ':' is optional between message labels and values. | 389 TryConsume(":"); // ':' is optional between message labels and values. |
| 393 string serialized_value; | 390 string serialized_value; |
| 394 DO(ConsumeAnyValue(full_type_name, | 391 DO(ConsumeAnyValue(full_type_name, |
| 395 message->GetDescriptor()->file()->pool(), | 392 message->GetDescriptor()->file()->pool(), |
| 396 &serialized_value)); | 393 &serialized_value)); |
| 397 if (singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) { | |
| 398 // Fail if any_type_url_field has already been specified. | |
| 399 if ((!any_type_url_field->is_repeated() && | |
| 400 reflection->HasField(*message, any_type_url_field)) || | |
| 401 (!any_value_field->is_repeated() && | |
| 402 reflection->HasField(*message, any_value_field))) { | |
| 403 ReportError("Non-repeated Any specified multiple times."); | |
| 404 return false; | |
| 405 } | |
| 406 } | |
| 407 reflection->SetString( | 394 reflection->SetString( |
| 408 message, any_type_url_field, | 395 message, any_type_url_field, |
| 409 string(prefix + full_type_name)); | 396 string(prefix + full_type_name)); |
| 410 reflection->SetString(message, any_value_field, serialized_value); | 397 reflection->SetString(message, any_value_field, serialized_value); |
| 411 return true; | 398 return true; |
| 412 } | 399 } |
| 413 if (TryConsume("[")) { | 400 if (TryConsume("[")) { |
| 414 // Extension. | 401 // Extension. |
| 415 DO(ConsumeFullTypeName(&field_name)); | 402 DO(ConsumeFullTypeName(&field_name)); |
| 416 DO(Consume("]")); | 403 DO(Consume("]")); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 512 ReportError("Field \"" + field_name + "\" is specified along with " | 499 ReportError("Field \"" + field_name + "\" is specified along with " |
| 513 "field \"" + other_field->name() + "\", another member " | 500 "field \"" + other_field->name() + "\", another member " |
| 514 "of oneof \"" + oneof->name() + "\"."); | 501 "of oneof \"" + oneof->name() + "\"."); |
| 515 return false; | 502 return false; |
| 516 } | 503 } |
| 517 } | 504 } |
| 518 | 505 |
| 519 // Perform special handling for embedded message types. | 506 // Perform special handling for embedded message types. |
| 520 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { | 507 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { |
| 521 // ':' is optional here. | 508 // ':' is optional here. |
| 522 bool consumed_semicolon = TryConsume(":"); | 509 TryConsume(":"); |
| 523 if (consumed_semicolon && field->options().weak() && LookingAtType(io::Tok
enizer::TYPE_STRING)) { | |
| 524 // we are getting a bytes string for a weak field. | |
| 525 string tmp; | |
| 526 DO(ConsumeString(&tmp)); | |
| 527 reflection->MutableMessage(message, field)->ParseFromString(tmp); | |
| 528 goto label_skip_parsing; | |
| 529 } | |
| 530 } else { | 510 } else { |
| 531 // ':' is required here. | 511 // ':' is required here. |
| 532 DO(Consume(":")); | 512 DO(Consume(":")); |
| 533 } | 513 } |
| 534 | 514 |
| 535 if (field->is_repeated() && TryConsume("[")) { | 515 if (field->is_repeated() && TryConsume("[")) { |
| 536 // Short repeated format, e.g. "foo: [1, 2, 3]". | 516 // Short repeated format, e.g. "foo: [1, 2, 3]" |
| 537 if (!TryConsume("]")) { | 517 while (true) { |
| 538 // "foo: []" is treated as empty. | 518 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { |
| 539 while (true) { | 519 // Perform special handling for embedded message types. |
| 540 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { | 520 DO(ConsumeFieldMessage(message, reflection, field)); |
| 541 // Perform special handling for embedded message types. | 521 } else { |
| 542 DO(ConsumeFieldMessage(message, reflection, field)); | 522 DO(ConsumeFieldValue(message, reflection, field)); |
| 543 } else { | |
| 544 DO(ConsumeFieldValue(message, reflection, field)); | |
| 545 } | |
| 546 if (TryConsume("]")) { | |
| 547 break; | |
| 548 } | |
| 549 DO(Consume(",")); | |
| 550 } | 523 } |
| 524 if (TryConsume("]")) { |
| 525 break; |
| 526 } |
| 527 DO(Consume(",")); |
| 551 } | 528 } |
| 552 } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { | 529 } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { |
| 553 DO(ConsumeFieldMessage(message, reflection, field)); | 530 DO(ConsumeFieldMessage(message, reflection, field)); |
| 554 } else { | 531 } else { |
| 555 DO(ConsumeFieldValue(message, reflection, field)); | 532 DO(ConsumeFieldValue(message, reflection, field)); |
| 556 } | 533 } |
| 557 label_skip_parsing: | 534 |
| 558 // For historical reasons, fields may optionally be separated by commas or | 535 // For historical reasons, fields may optionally be separated by commas or |
| 559 // semicolons. | 536 // semicolons. |
| 560 TryConsume(";") || TryConsume(","); | 537 TryConsume(";") || TryConsume(","); |
| 561 | 538 |
| 562 if (field->options().deprecated()) { | 539 if (field->options().deprecated()) { |
| 563 ReportWarning("text format contains deprecated field \"" | 540 ReportWarning("text format contains deprecated field \"" |
| 564 + field_name + "\""); | 541 + field_name + "\""); |
| 565 } | 542 } |
| 566 | 543 |
| 567 // If a parse info tree exists, add the location for the parsed | 544 // If a parse info tree exists, add the location for the parsed |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 734 // Find the enumeration value. | 711 // Find the enumeration value. |
| 735 enum_value = enum_type->FindValueByName(value); | 712 enum_value = enum_type->FindValueByName(value); |
| 736 | 713 |
| 737 } else if (LookingAt("-") || | 714 } else if (LookingAt("-") || |
| 738 LookingAtType(io::Tokenizer::TYPE_INTEGER)) { | 715 LookingAtType(io::Tokenizer::TYPE_INTEGER)) { |
| 739 int64 int_value; | 716 int64 int_value; |
| 740 DO(ConsumeSignedInteger(&int_value, kint32max)); | 717 DO(ConsumeSignedInteger(&int_value, kint32max)); |
| 741 value = SimpleItoa(int_value); // for error reporting | 718 value = SimpleItoa(int_value); // for error reporting |
| 742 enum_value = enum_type->FindValueByNumber(int_value); | 719 enum_value = enum_type->FindValueByNumber(int_value); |
| 743 } else { | 720 } else { |
| 744 ReportError("Expected integer or identifier, got: " + | 721 ReportError("Expected integer or identifier."); |
| 745 tokenizer_.current().text); | |
| 746 return false; | 722 return false; |
| 747 } | 723 } |
| 748 | 724 |
| 749 if (enum_value == NULL) { | 725 if (enum_value == NULL) { |
| 750 if (!allow_unknown_enum_) { | 726 if (!allow_unknown_enum_) { |
| 751 ReportError("Unknown enumeration value of \"" + value + "\" for " | 727 ReportError("Unknown enumeration value of \"" + value + "\" for " |
| 752 "field \"" + field->name() + "\"."); | 728 "field \"" + field->name() + "\"."); |
| 753 return false; | 729 return false; |
| 754 } else { | 730 } else { |
| 755 ReportWarning("Unknown enumeration value of \"" + value + "\" for " | 731 ReportWarning("Unknown enumeration value of \"" + value + "\" for " |
| (...skipping 17 matching lines...) Expand all Loading... |
| 773 return true; | 749 return true; |
| 774 } | 750 } |
| 775 | 751 |
| 776 bool SkipFieldValue() { | 752 bool SkipFieldValue() { |
| 777 if (LookingAtType(io::Tokenizer::TYPE_STRING)) { | 753 if (LookingAtType(io::Tokenizer::TYPE_STRING)) { |
| 778 while (LookingAtType(io::Tokenizer::TYPE_STRING)) { | 754 while (LookingAtType(io::Tokenizer::TYPE_STRING)) { |
| 779 tokenizer_.Next(); | 755 tokenizer_.Next(); |
| 780 } | 756 } |
| 781 return true; | 757 return true; |
| 782 } | 758 } |
| 783 if (TryConsume("[")) { | |
| 784 while (true) { | |
| 785 if (!LookingAt("{") && !LookingAt("<")) { | |
| 786 DO(SkipFieldValue()); | |
| 787 } else { | |
| 788 DO(SkipFieldMessage()); | |
| 789 } | |
| 790 if (TryConsume("]")) { | |
| 791 break; | |
| 792 } | |
| 793 DO(Consume(",")); | |
| 794 } | |
| 795 return true; | |
| 796 } | |
| 797 // Possible field values other than string: | 759 // Possible field values other than string: |
| 798 // 12345 => TYPE_INTEGER | 760 // 12345 => TYPE_INTEGER |
| 799 // -12345 => TYPE_SYMBOL + TYPE_INTEGER | 761 // -12345 => TYPE_SYMBOL + TYPE_INTEGER |
| 800 // 1.2345 => TYPE_FLOAT | 762 // 1.2345 => TYPE_FLOAT |
| 801 // -1.2345 => TYPE_SYMBOL + TYPE_FLOAT | 763 // -1.2345 => TYPE_SYMBOL + TYPE_FLOAT |
| 802 // inf => TYPE_IDENTIFIER | 764 // inf => TYPE_IDENTIFIER |
| 803 // -inf => TYPE_SYMBOL + TYPE_IDENTIFIER | 765 // -inf => TYPE_SYMBOL + TYPE_IDENTIFIER |
| 804 // TYPE_INTEGER => TYPE_IDENTIFIER | 766 // TYPE_INTEGER => TYPE_IDENTIFIER |
| 805 // Divides them into two group, one with TYPE_SYMBOL | 767 // Divides them into two group, one with TYPE_SYMBOL |
| 806 // and the other without: | 768 // and the other without: |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 862 | 824 |
| 863 // If allow_field_numer_ or allow_unknown_field_ is true, we should able | 825 // If allow_field_numer_ or allow_unknown_field_ is true, we should able |
| 864 // to parse integer identifiers. | 826 // to parse integer identifiers. |
| 865 if ((allow_field_number_ || allow_unknown_field_) | 827 if ((allow_field_number_ || allow_unknown_field_) |
| 866 && LookingAtType(io::Tokenizer::TYPE_INTEGER)) { | 828 && LookingAtType(io::Tokenizer::TYPE_INTEGER)) { |
| 867 *identifier = tokenizer_.current().text; | 829 *identifier = tokenizer_.current().text; |
| 868 tokenizer_.Next(); | 830 tokenizer_.Next(); |
| 869 return true; | 831 return true; |
| 870 } | 832 } |
| 871 | 833 |
| 872 ReportError("Expected identifier, got: " + tokenizer_.current().text); | 834 ReportError("Expected identifier."); |
| 873 return false; | 835 return false; |
| 874 } | 836 } |
| 875 | 837 |
| 876 // Consume a string of form "<id1>.<id2>....<idN>". | 838 // Consume a string of form "<id1>.<id2>....<idN>". |
| 877 bool ConsumeFullTypeName(string* name) { | 839 bool ConsumeFullTypeName(string* name) { |
| 878 DO(ConsumeIdentifier(name)); | 840 DO(ConsumeIdentifier(name)); |
| 879 while (TryConsume(".")) { | 841 while (TryConsume(".")) { |
| 880 string part; | 842 string part; |
| 881 DO(ConsumeIdentifier(&part)); | 843 DO(ConsumeIdentifier(&part)); |
| 882 *name += "."; | 844 *name += "."; |
| 883 *name += part; | 845 *name += part; |
| 884 } | 846 } |
| 885 return true; | 847 return true; |
| 886 } | 848 } |
| 887 | 849 |
| 888 // Consumes a string and saves its value in the text parameter. | 850 // Consumes a string and saves its value in the text parameter. |
| 889 // Returns false if the token is not of type STRING. | 851 // Returns false if the token is not of type STRING. |
| 890 bool ConsumeString(string* text) { | 852 bool ConsumeString(string* text) { |
| 891 if (!LookingAtType(io::Tokenizer::TYPE_STRING)) { | 853 if (!LookingAtType(io::Tokenizer::TYPE_STRING)) { |
| 892 ReportError("Expected string, got: " + tokenizer_.current().text); | 854 ReportError("Expected string."); |
| 893 return false; | 855 return false; |
| 894 } | 856 } |
| 895 | 857 |
| 896 text->clear(); | 858 text->clear(); |
| 897 while (LookingAtType(io::Tokenizer::TYPE_STRING)) { | 859 while (LookingAtType(io::Tokenizer::TYPE_STRING)) { |
| 898 io::Tokenizer::ParseStringAppend(tokenizer_.current().text, text); | 860 io::Tokenizer::ParseStringAppend(tokenizer_.current().text, text); |
| 899 | 861 |
| 900 tokenizer_.Next(); | 862 tokenizer_.Next(); |
| 901 } | 863 } |
| 902 | 864 |
| 903 return true; | 865 return true; |
| 904 } | 866 } |
| 905 | 867 |
| 906 // Consumes a uint64 and saves its value in the value parameter. | 868 // Consumes a uint64 and saves its value in the value parameter. |
| 907 // Returns false if the token is not of type INTEGER. | 869 // Returns false if the token is not of type INTEGER. |
| 908 bool ConsumeUnsignedInteger(uint64* value, uint64 max_value) { | 870 bool ConsumeUnsignedInteger(uint64* value, uint64 max_value) { |
| 909 if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) { | 871 if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) { |
| 910 ReportError("Expected integer, got: " + tokenizer_.current().text); | 872 ReportError("Expected integer."); |
| 911 return false; | 873 return false; |
| 912 } | 874 } |
| 913 | 875 |
| 914 if (!io::Tokenizer::ParseInteger(tokenizer_.current().text, | 876 if (!io::Tokenizer::ParseInteger(tokenizer_.current().text, |
| 915 max_value, value)) { | 877 max_value, value)) { |
| 916 ReportError("Integer out of range (" + tokenizer_.current().text + ")"); | 878 ReportError("Integer out of range."); |
| 917 return false; | 879 return false; |
| 918 } | 880 } |
| 919 | 881 |
| 920 tokenizer_.Next(); | 882 tokenizer_.Next(); |
| 921 return true; | 883 return true; |
| 922 } | 884 } |
| 923 | 885 |
| 924 // Consumes an int64 and saves its value in the value parameter. | 886 // Consumes an int64 and saves its value in the value parameter. |
| 925 // Note that since the tokenizer does not support negative numbers, | 887 // Note that since the tokenizer does not support negative numbers, |
| 926 // we actually may consume an additional token (for the minus sign) in this | 888 // we actually may consume an additional token (for the minus sign) in this |
| 927 // method. Returns false if the token is not an integer | 889 // method. Returns false if the token is not an integer |
| 928 // (signed or otherwise). | 890 // (signed or otherwise). |
| 929 bool ConsumeSignedInteger(int64* value, uint64 max_value) { | 891 bool ConsumeSignedInteger(int64* value, uint64 max_value) { |
| 930 bool negative = false; | 892 bool negative = false; |
| 931 | 893 |
| 932 if (TryConsume("-")) { | 894 if (TryConsume("-")) { |
| 933 negative = true; | 895 negative = true; |
| 934 // Two's complement always allows one more negative integer than | 896 // Two's complement always allows one more negative integer than |
| 935 // positive. | 897 // positive. |
| 936 ++max_value; | 898 ++max_value; |
| 937 } | 899 } |
| 938 | 900 |
| 939 uint64 unsigned_value; | 901 uint64 unsigned_value; |
| 940 | 902 |
| 941 DO(ConsumeUnsignedInteger(&unsigned_value, max_value)); | 903 DO(ConsumeUnsignedInteger(&unsigned_value, max_value)); |
| 942 | 904 |
| 905 *value = static_cast<int64>(unsigned_value); |
| 906 |
| 943 if (negative) { | 907 if (negative) { |
| 944 if ((static_cast<uint64>(kint64max) + 1) == unsigned_value) { | 908 *value = -*value; |
| 945 *value = kint64min; | |
| 946 } else { | |
| 947 *value = -static_cast<int64>(unsigned_value); | |
| 948 } | |
| 949 } else { | |
| 950 *value = static_cast<int64>(unsigned_value); | |
| 951 } | 909 } |
| 952 | 910 |
| 953 return true; | 911 return true; |
| 954 } | 912 } |
| 955 | 913 |
| 956 // Consumes a uint64 and saves its value in the value parameter. | 914 // Consumes a uint64 and saves its value in the value parameter. |
| 957 // Accepts decimal numbers only, rejects hex or oct numbers. | 915 // Accepts decimal numbers only, rejects hex or oct numbers. |
| 958 bool ConsumeUnsignedDecimalInteger(uint64* value, uint64 max_value) { | 916 bool ConsumeUnsignedDecimalInteger(uint64* value, uint64 max_value) { |
| 959 if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) { | 917 if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) { |
| 960 ReportError("Expected integer, got: " + tokenizer_.current().text); | 918 ReportError("Expected integer."); |
| 961 return false; | 919 return false; |
| 962 } | 920 } |
| 963 | 921 |
| 964 const string& text = tokenizer_.current().text; | 922 const string& text = tokenizer_.current().text; |
| 965 if (IsHexNumber(text) || IsOctNumber(text)) { | 923 if (IsHexNumber(text) || IsOctNumber(text)) { |
| 966 ReportError("Expect a decimal number, got: " + text); | 924 ReportError("Expect a decimal number."); |
| 967 return false; | 925 return false; |
| 968 } | 926 } |
| 969 | 927 |
| 970 if (!io::Tokenizer::ParseInteger(text, max_value, value)) { | 928 if (!io::Tokenizer::ParseInteger(text, max_value, value)) { |
| 971 ReportError("Integer out of range (" + text + ")"); | 929 ReportError("Integer out of range."); |
| 972 return false; | 930 return false; |
| 973 } | 931 } |
| 974 | 932 |
| 975 tokenizer_.Next(); | 933 tokenizer_.Next(); |
| 976 return true; | 934 return true; |
| 977 } | 935 } |
| 978 | 936 |
| 979 // Consumes a double and saves its value in the value parameter. | 937 // Consumes a double and saves its value in the value parameter. |
| 980 // Note that since the tokenizer does not support negative numbers, | 938 // Note that since the tokenizer does not support negative numbers, |
| 981 // we actually may consume an additional token (for the minus sign) in this | 939 // we actually may consume an additional token (for the minus sign) in this |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1006 string text = tokenizer_.current().text; | 964 string text = tokenizer_.current().text; |
| 1007 LowerString(&text); | 965 LowerString(&text); |
| 1008 if (text == "inf" || | 966 if (text == "inf" || |
| 1009 text == "infinity") { | 967 text == "infinity") { |
| 1010 *value = std::numeric_limits<double>::infinity(); | 968 *value = std::numeric_limits<double>::infinity(); |
| 1011 tokenizer_.Next(); | 969 tokenizer_.Next(); |
| 1012 } else if (text == "nan") { | 970 } else if (text == "nan") { |
| 1013 *value = std::numeric_limits<double>::quiet_NaN(); | 971 *value = std::numeric_limits<double>::quiet_NaN(); |
| 1014 tokenizer_.Next(); | 972 tokenizer_.Next(); |
| 1015 } else { | 973 } else { |
| 1016 ReportError("Expected double, got: " + text); | 974 ReportError("Expected double."); |
| 1017 return false; | 975 return false; |
| 1018 } | 976 } |
| 1019 } else { | 977 } else { |
| 1020 ReportError("Expected double, got: " + tokenizer_.current().text); | 978 ReportError("Expected double."); |
| 1021 return false; | 979 return false; |
| 1022 } | 980 } |
| 1023 | 981 |
| 1024 if (negative) { | 982 if (negative) { |
| 1025 *value = -*value; | 983 *value = -*value; |
| 1026 } | 984 } |
| 1027 | 985 |
| 1028 return true; | 986 return true; |
| 1029 } | 987 } |
| 1030 | 988 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1068 DynamicMessageFactory factory; | 1026 DynamicMessageFactory factory; |
| 1069 const Message* value_prototype = factory.GetPrototype(value_descriptor); | 1027 const Message* value_prototype = factory.GetPrototype(value_descriptor); |
| 1070 if (value_prototype == NULL) { | 1028 if (value_prototype == NULL) { |
| 1071 return false; | 1029 return false; |
| 1072 } | 1030 } |
| 1073 google::protobuf::scoped_ptr<Message> value(value_prototype->New()); | 1031 google::protobuf::scoped_ptr<Message> value(value_prototype->New()); |
| 1074 string sub_delimiter; | 1032 string sub_delimiter; |
| 1075 DO(ConsumeMessageDelimiter(&sub_delimiter)); | 1033 DO(ConsumeMessageDelimiter(&sub_delimiter)); |
| 1076 DO(ConsumeMessage(value.get(), sub_delimiter)); | 1034 DO(ConsumeMessage(value.get(), sub_delimiter)); |
| 1077 | 1035 |
| 1078 if (allow_partial_) { | 1036 value->AppendToString(serialized_value); |
| 1079 value->AppendPartialToString(serialized_value); | |
| 1080 } else { | |
| 1081 if (!value->IsInitialized()) { | |
| 1082 ReportError( | |
| 1083 "Value of type \"" + full_type_name + | |
| 1084 "\" stored in google.protobuf.Any has missing required fields"); | |
| 1085 return false; | |
| 1086 } | |
| 1087 value->AppendToString(serialized_value); | |
| 1088 } | |
| 1089 return true; | 1037 return true; |
| 1090 } | 1038 } |
| 1091 | 1039 |
| 1092 // Consumes a token and confirms that it matches that specified in the | 1040 // Consumes a token and confirms that it matches that specified in the |
| 1093 // value parameter. Returns false if the token found does not match that | 1041 // value parameter. Returns false if the token found does not match that |
| 1094 // which was specified. | 1042 // which was specified. |
| 1095 bool Consume(const string& value) { | 1043 bool Consume(const string& value) { |
| 1096 const string& current_value = tokenizer_.current().text; | 1044 const string& current_value = tokenizer_.current().text; |
| 1097 | 1045 |
| 1098 if (current_value != value) { | 1046 if (current_value != value) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1143 TextFormat::Finder* finder_; | 1091 TextFormat::Finder* finder_; |
| 1144 ParseInfoTree* parse_info_tree_; | 1092 ParseInfoTree* parse_info_tree_; |
| 1145 ParserErrorCollector tokenizer_error_collector_; | 1093 ParserErrorCollector tokenizer_error_collector_; |
| 1146 io::Tokenizer tokenizer_; | 1094 io::Tokenizer tokenizer_; |
| 1147 const Descriptor* root_message_type_; | 1095 const Descriptor* root_message_type_; |
| 1148 SingularOverwritePolicy singular_overwrite_policy_; | 1096 SingularOverwritePolicy singular_overwrite_policy_; |
| 1149 const bool allow_case_insensitive_field_; | 1097 const bool allow_case_insensitive_field_; |
| 1150 const bool allow_unknown_field_; | 1098 const bool allow_unknown_field_; |
| 1151 const bool allow_unknown_enum_; | 1099 const bool allow_unknown_enum_; |
| 1152 const bool allow_field_number_; | 1100 const bool allow_field_number_; |
| 1153 const bool allow_partial_; | |
| 1154 bool had_errors_; | 1101 bool had_errors_; |
| 1155 }; | 1102 }; |
| 1156 | 1103 |
| 1157 #undef DO | 1104 #undef DO |
| 1158 | 1105 |
| 1159 // =========================================================================== | 1106 // =========================================================================== |
| 1160 // Internal class for writing text to the io::ZeroCopyOutputStream. Adapted | 1107 // Internal class for writing text to the io::ZeroCopyOutputStream. Adapted |
| 1161 // from the Printer found in //google/protobuf/io/printer.h | 1108 // from the Printer found in //google/protobuf/io/printer.h |
| 1162 class TextFormat::Printer::TextGenerator { | 1109 class TextFormat::Printer::TextGenerator { |
| 1163 public: | 1110 public: |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1305 ParserImpl::SingularOverwritePolicy overwrites_policy = | 1252 ParserImpl::SingularOverwritePolicy overwrites_policy = |
| 1306 allow_singular_overwrites_ | 1253 allow_singular_overwrites_ |
| 1307 ? ParserImpl::ALLOW_SINGULAR_OVERWRITES | 1254 ? ParserImpl::ALLOW_SINGULAR_OVERWRITES |
| 1308 : ParserImpl::FORBID_SINGULAR_OVERWRITES; | 1255 : ParserImpl::FORBID_SINGULAR_OVERWRITES; |
| 1309 | 1256 |
| 1310 ParserImpl parser(output->GetDescriptor(), input, error_collector_, | 1257 ParserImpl parser(output->GetDescriptor(), input, error_collector_, |
| 1311 finder_, parse_info_tree_, | 1258 finder_, parse_info_tree_, |
| 1312 overwrites_policy, | 1259 overwrites_policy, |
| 1313 allow_case_insensitive_field_, allow_unknown_field_, | 1260 allow_case_insensitive_field_, allow_unknown_field_, |
| 1314 allow_unknown_enum_, allow_field_number_, | 1261 allow_unknown_enum_, allow_field_number_, |
| 1315 allow_relaxed_whitespace_, allow_partial_); | 1262 allow_relaxed_whitespace_); |
| 1316 return MergeUsingImpl(input, output, &parser); | 1263 return MergeUsingImpl(input, output, &parser); |
| 1317 } | 1264 } |
| 1318 | 1265 |
| 1319 bool TextFormat::Parser::ParseFromString(const string& input, | 1266 bool TextFormat::Parser::ParseFromString(const string& input, |
| 1320 Message* output) { | 1267 Message* output) { |
| 1321 io::ArrayInputStream input_stream(input.data(), input.size()); | 1268 io::ArrayInputStream input_stream(input.data(), input.size()); |
| 1322 return Parse(&input_stream, output); | 1269 return Parse(&input_stream, output); |
| 1323 } | 1270 } |
| 1324 | 1271 |
| 1325 bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input, | 1272 bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input, |
| 1326 Message* output) { | 1273 Message* output) { |
| 1327 ParserImpl parser(output->GetDescriptor(), input, error_collector_, | 1274 ParserImpl parser(output->GetDescriptor(), input, error_collector_, |
| 1328 finder_, parse_info_tree_, | 1275 finder_, parse_info_tree_, |
| 1329 ParserImpl::ALLOW_SINGULAR_OVERWRITES, | 1276 ParserImpl::ALLOW_SINGULAR_OVERWRITES, |
| 1330 allow_case_insensitive_field_, allow_unknown_field_, | 1277 allow_case_insensitive_field_, allow_unknown_field_, |
| 1331 allow_unknown_enum_, allow_field_number_, | 1278 allow_unknown_enum_, allow_field_number_, |
| 1332 allow_relaxed_whitespace_, allow_partial_); | 1279 allow_relaxed_whitespace_); |
| 1333 return MergeUsingImpl(input, output, &parser); | 1280 return MergeUsingImpl(input, output, &parser); |
| 1334 } | 1281 } |
| 1335 | 1282 |
| 1336 bool TextFormat::Parser::MergeFromString(const string& input, | 1283 bool TextFormat::Parser::MergeFromString(const string& input, |
| 1337 Message* output) { | 1284 Message* output) { |
| 1338 io::ArrayInputStream input_stream(input.data(), input.size()); | 1285 io::ArrayInputStream input_stream(input.data(), input.size()); |
| 1339 return Merge(&input_stream, output); | 1286 return Merge(&input_stream, output); |
| 1340 } | 1287 } |
| 1341 | 1288 |
| 1342 bool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* /* input */, | 1289 bool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* /* input */, |
| 1343 Message* output, | 1290 Message* output, |
| 1344 ParserImpl* parser_impl) { | 1291 ParserImpl* parser_impl) { |
| 1345 if (!parser_impl->Parse(output)) return false; | 1292 if (!parser_impl->Parse(output)) return false; |
| 1346 if (!allow_partial_ && !output->IsInitialized()) { | 1293 if (!allow_partial_ && !output->IsInitialized()) { |
| 1347 std::vector<string> missing_fields; | 1294 vector<string> missing_fields; |
| 1348 output->FindInitializationErrors(&missing_fields); | 1295 output->FindInitializationErrors(&missing_fields); |
| 1349 parser_impl->ReportError(-1, 0, "Message missing required fields: " + | 1296 parser_impl->ReportError(-1, 0, "Message missing required fields: " + |
| 1350 Join(missing_fields, ", ")); | 1297 Join(missing_fields, ", ")); |
| 1351 return false; | 1298 return false; |
| 1352 } | 1299 } |
| 1353 return true; | 1300 return true; |
| 1354 } | 1301 } |
| 1355 | 1302 |
| 1356 bool TextFormat::Parser::ParseFieldValueFromString( | 1303 bool TextFormat::Parser::ParseFieldValueFromString( |
| 1357 const string& input, | 1304 const string& input, |
| 1358 const FieldDescriptor* field, | 1305 const FieldDescriptor* field, |
| 1359 Message* output) { | 1306 Message* output) { |
| 1360 io::ArrayInputStream input_stream(input.data(), input.size()); | 1307 io::ArrayInputStream input_stream(input.data(), input.size()); |
| 1361 ParserImpl parser(output->GetDescriptor(), &input_stream, error_collector_, | 1308 ParserImpl parser(output->GetDescriptor(), &input_stream, error_collector_, |
| 1362 finder_, parse_info_tree_, | 1309 finder_, parse_info_tree_, |
| 1363 ParserImpl::ALLOW_SINGULAR_OVERWRITES, | 1310 ParserImpl::ALLOW_SINGULAR_OVERWRITES, |
| 1364 allow_case_insensitive_field_, allow_unknown_field_, | 1311 allow_case_insensitive_field_, allow_unknown_field_, |
| 1365 allow_unknown_enum_, allow_field_number_, | 1312 allow_unknown_enum_, allow_field_number_, |
| 1366 allow_relaxed_whitespace_, allow_partial_); | 1313 allow_relaxed_whitespace_); |
| 1367 return parser.ParseField(field, output); | 1314 return parser.ParseField(field, output); |
| 1368 } | 1315 } |
| 1369 | 1316 |
| 1370 /* static */ bool TextFormat::Parse(io::ZeroCopyInputStream* input, | 1317 /* static */ bool TextFormat::Parse(io::ZeroCopyInputStream* input, |
| 1371 Message* output) { | 1318 Message* output) { |
| 1372 return Parser().Parse(input, output); | 1319 return Parser().Parse(input, output); |
| 1373 } | 1320 } |
| 1374 | 1321 |
| 1375 /* static */ bool TextFormat::Merge(io::ZeroCopyInputStream* input, | 1322 /* static */ bool TextFormat::Merge(io::ZeroCopyInputStream* input, |
| 1376 Message* output) { | 1323 Message* output) { |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1611 } | 1558 } |
| 1612 | 1559 |
| 1613 void TextFormat::Printer::Print(const Message& message, | 1560 void TextFormat::Printer::Print(const Message& message, |
| 1614 TextGenerator& generator) const { | 1561 TextGenerator& generator) const { |
| 1615 const Descriptor* descriptor = message.GetDescriptor(); | 1562 const Descriptor* descriptor = message.GetDescriptor(); |
| 1616 const Reflection* reflection = message.GetReflection(); | 1563 const Reflection* reflection = message.GetReflection(); |
| 1617 if (descriptor->full_name() == internal::kAnyFullTypeName && expand_any_ && | 1564 if (descriptor->full_name() == internal::kAnyFullTypeName && expand_any_ && |
| 1618 PrintAny(message, generator)) { | 1565 PrintAny(message, generator)) { |
| 1619 return; | 1566 return; |
| 1620 } | 1567 } |
| 1621 std::vector<const FieldDescriptor*> fields; | 1568 vector<const FieldDescriptor*> fields; |
| 1622 reflection->ListFields(message, &fields); | 1569 reflection->ListFields(message, &fields); |
| 1623 if (print_message_fields_in_index_order_) { | 1570 if (print_message_fields_in_index_order_) { |
| 1624 std::sort(fields.begin(), fields.end(), FieldIndexSorter()); | 1571 std::sort(fields.begin(), fields.end(), FieldIndexSorter()); |
| 1625 } | 1572 } |
| 1626 for (int i = 0; i < fields.size(); i++) { | 1573 for (int i = 0; i < fields.size(); i++) { |
| 1627 PrintField(message, reflection, fields[i], generator); | 1574 PrintField(message, reflection, fields[i], generator); |
| 1628 } | 1575 } |
| 1629 if (!hide_unknown_fields_) { | 1576 if (!hide_unknown_fields_) { |
| 1630 PrintUnknownFields(reflection->GetUnknownFields(message), generator); | 1577 PrintUnknownFields(reflection->GetUnknownFields(message), generator); |
| 1631 } | 1578 } |
| (...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2019 generator.Outdent(); | 1966 generator.Outdent(); |
| 2020 generator.Print("}\n"); | 1967 generator.Print("}\n"); |
| 2021 } | 1968 } |
| 2022 break; | 1969 break; |
| 2023 } | 1970 } |
| 2024 } | 1971 } |
| 2025 } | 1972 } |
| 2026 | 1973 |
| 2027 } // namespace protobuf | 1974 } // namespace protobuf |
| 2028 } // namespace google | 1975 } // namespace google |
| OLD | NEW |