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