Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(115)

Unified Diff: third_party/protobuf/src/google/protobuf/text_format.cc

Issue 2495533002: third_party/protobuf: Update to HEAD (83d681ee2c) (Closed)
Patch Set: Make chrome settings proto generated file a component Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/protobuf/src/google/protobuf/text_format.cc
diff --git a/third_party/protobuf/src/google/protobuf/text_format.cc b/third_party/protobuf/src/google/protobuf/text_format.cc
index c0dfd53fd7b0c7360f3fada07cc23207f36723e9..e3d908ecddea85e5d51636a41e0147de81825c18 100644
--- a/third_party/protobuf/src/google/protobuf/text_format.cc
+++ b/third_party/protobuf/src/google/protobuf/text_format.cc
@@ -154,7 +154,7 @@ TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::CreateNested(
const FieldDescriptor* field) {
// Owned by us in the map.
TextFormat::ParseInfoTree* instance = new TextFormat::ParseInfoTree();
- vector<TextFormat::ParseInfoTree*>* trees = &nested_[field];
+ std::vector<TextFormat::ParseInfoTree*>* trees = &nested_[field];
GOOGLE_CHECK(trees);
trees->push_back(instance);
return instance;
@@ -177,7 +177,7 @@ TextFormat::ParseLocation TextFormat::ParseInfoTree::GetLocation(
CheckFieldIndex(field, index);
if (index == -1) { index = 0; }
- const vector<TextFormat::ParseLocation>* locations =
+ const std::vector<TextFormat::ParseLocation>* locations =
FindOrNull(locations_, field);
if (locations == NULL || index >= locations->size()) {
return TextFormat::ParseLocation();
@@ -191,7 +191,8 @@ TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::GetTreeForNested(
CheckFieldIndex(field, index);
if (index == -1) { index = 0; }
- const vector<TextFormat::ParseInfoTree*>* trees = FindOrNull(nested_, field);
+ const std::vector<TextFormat::ParseInfoTree*>* trees =
+ FindOrNull(nested_, field);
if (trees == NULL || index >= trees->size()) {
return NULL;
}
@@ -234,7 +235,8 @@ class TextFormat::Parser::ParserImpl {
bool allow_unknown_field,
bool allow_unknown_enum,
bool allow_field_number,
- bool allow_relaxed_whitespace)
+ bool allow_relaxed_whitespace,
+ bool allow_partial)
: error_collector_(error_collector),
finder_(finder),
parse_info_tree_(parse_info_tree),
@@ -246,6 +248,7 @@ class TextFormat::Parser::ParserImpl {
allow_unknown_field_(allow_unknown_field),
allow_unknown_enum_(allow_unknown_enum),
allow_field_number_(allow_field_number),
+ allow_partial_(allow_partial),
had_errors_(false) {
// For backwards-compatibility with proto1, we need to allow the 'f' suffix
// for floats.
@@ -391,6 +394,16 @@ class TextFormat::Parser::ParserImpl {
DO(ConsumeAnyValue(full_type_name,
message->GetDescriptor()->file()->pool(),
&serialized_value));
+ if (singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) {
+ // Fail if any_type_url_field has already been specified.
+ if ((!any_type_url_field->is_repeated() &&
+ reflection->HasField(*message, any_type_url_field)) ||
+ (!any_value_field->is_repeated() &&
+ reflection->HasField(*message, any_value_field))) {
+ ReportError("Non-repeated Any specified multiple times.");
+ return false;
+ }
+ }
reflection->SetString(
message, any_type_url_field,
string(prefix + full_type_name));
@@ -506,32 +519,42 @@ class TextFormat::Parser::ParserImpl {
// Perform special handling for embedded message types.
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
// ':' is optional here.
- TryConsume(":");
+ bool consumed_semicolon = TryConsume(":");
+ if (consumed_semicolon && field->options().weak() && LookingAtType(io::Tokenizer::TYPE_STRING)) {
+ // we are getting a bytes string for a weak field.
+ string tmp;
+ DO(ConsumeString(&tmp));
+ reflection->MutableMessage(message, field)->ParseFromString(tmp);
+ goto label_skip_parsing;
+ }
} else {
// ':' is required here.
DO(Consume(":"));
}
if (field->is_repeated() && TryConsume("[")) {
- // Short repeated format, e.g. "foo: [1, 2, 3]"
- while (true) {
- if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- // Perform special handling for embedded message types.
- DO(ConsumeFieldMessage(message, reflection, field));
- } else {
- DO(ConsumeFieldValue(message, reflection, field));
- }
- if (TryConsume("]")) {
- break;
+ // Short repeated format, e.g. "foo: [1, 2, 3]".
+ if (!TryConsume("]")) {
+ // "foo: []" is treated as empty.
+ while (true) {
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ // Perform special handling for embedded message types.
+ DO(ConsumeFieldMessage(message, reflection, field));
+ } else {
+ DO(ConsumeFieldValue(message, reflection, field));
+ }
+ if (TryConsume("]")) {
+ break;
+ }
+ DO(Consume(","));
}
- DO(Consume(","));
}
} else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
DO(ConsumeFieldMessage(message, reflection, field));
} else {
DO(ConsumeFieldValue(message, reflection, field));
}
-
+label_skip_parsing:
// For historical reasons, fields may optionally be separated by commas or
// semicolons.
TryConsume(";") || TryConsume(",");
@@ -718,7 +741,8 @@ class TextFormat::Parser::ParserImpl {
value = SimpleItoa(int_value); // for error reporting
enum_value = enum_type->FindValueByNumber(int_value);
} else {
- ReportError("Expected integer or identifier.");
+ ReportError("Expected integer or identifier, got: " +
+ tokenizer_.current().text);
return false;
}
@@ -756,6 +780,20 @@ class TextFormat::Parser::ParserImpl {
}
return true;
}
+ if (TryConsume("[")) {
+ while (true) {
+ if (!LookingAt("{") && !LookingAt("<")) {
+ DO(SkipFieldValue());
+ } else {
+ DO(SkipFieldMessage());
+ }
+ if (TryConsume("]")) {
+ break;
+ }
+ DO(Consume(","));
+ }
+ return true;
+ }
// Possible field values other than string:
// 12345 => TYPE_INTEGER
// -12345 => TYPE_SYMBOL + TYPE_INTEGER
@@ -831,7 +869,7 @@ class TextFormat::Parser::ParserImpl {
return true;
}
- ReportError("Expected identifier.");
+ ReportError("Expected identifier, got: " + tokenizer_.current().text);
return false;
}
@@ -851,7 +889,7 @@ class TextFormat::Parser::ParserImpl {
// Returns false if the token is not of type STRING.
bool ConsumeString(string* text) {
if (!LookingAtType(io::Tokenizer::TYPE_STRING)) {
- ReportError("Expected string.");
+ ReportError("Expected string, got: " + tokenizer_.current().text);
return false;
}
@@ -869,13 +907,13 @@ class TextFormat::Parser::ParserImpl {
// Returns false if the token is not of type INTEGER.
bool ConsumeUnsignedInteger(uint64* value, uint64 max_value) {
if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
- ReportError("Expected integer.");
+ ReportError("Expected integer, got: " + tokenizer_.current().text);
return false;
}
if (!io::Tokenizer::ParseInteger(tokenizer_.current().text,
max_value, value)) {
- ReportError("Integer out of range.");
+ ReportError("Integer out of range (" + tokenizer_.current().text + ")");
return false;
}
@@ -902,10 +940,14 @@ class TextFormat::Parser::ParserImpl {
DO(ConsumeUnsignedInteger(&unsigned_value, max_value));
- *value = static_cast<int64>(unsigned_value);
-
if (negative) {
- *value = -*value;
+ if ((static_cast<uint64>(kint64max) + 1) == unsigned_value) {
+ *value = kint64min;
+ } else {
+ *value = -static_cast<int64>(unsigned_value);
+ }
+ } else {
+ *value = static_cast<int64>(unsigned_value);
}
return true;
@@ -915,18 +957,18 @@ class TextFormat::Parser::ParserImpl {
// Accepts decimal numbers only, rejects hex or oct numbers.
bool ConsumeUnsignedDecimalInteger(uint64* value, uint64 max_value) {
if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
- ReportError("Expected integer.");
+ ReportError("Expected integer, got: " + tokenizer_.current().text);
return false;
}
const string& text = tokenizer_.current().text;
if (IsHexNumber(text) || IsOctNumber(text)) {
- ReportError("Expect a decimal number.");
+ ReportError("Expect a decimal number, got: " + text);
return false;
}
if (!io::Tokenizer::ParseInteger(text, max_value, value)) {
- ReportError("Integer out of range.");
+ ReportError("Integer out of range (" + text + ")");
return false;
}
@@ -971,11 +1013,11 @@ class TextFormat::Parser::ParserImpl {
*value = std::numeric_limits<double>::quiet_NaN();
tokenizer_.Next();
} else {
- ReportError("Expected double.");
+ ReportError("Expected double, got: " + text);
return false;
}
} else {
- ReportError("Expected double.");
+ ReportError("Expected double, got: " + tokenizer_.current().text);
return false;
}
@@ -1033,7 +1075,17 @@ class TextFormat::Parser::ParserImpl {
DO(ConsumeMessageDelimiter(&sub_delimiter));
DO(ConsumeMessage(value.get(), sub_delimiter));
- value->AppendToString(serialized_value);
+ if (allow_partial_) {
+ value->AppendPartialToString(serialized_value);
+ } else {
+ if (!value->IsInitialized()) {
+ ReportError(
+ "Value of type \"" + full_type_name +
+ "\" stored in google.protobuf.Any has missing required fields");
+ return false;
+ }
+ value->AppendToString(serialized_value);
+ }
return true;
}
@@ -1098,6 +1150,7 @@ class TextFormat::Parser::ParserImpl {
const bool allow_unknown_field_;
const bool allow_unknown_enum_;
const bool allow_field_number_;
+ const bool allow_partial_;
bool had_errors_;
};
@@ -1259,7 +1312,7 @@ bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input,
overwrites_policy,
allow_case_insensitive_field_, allow_unknown_field_,
allow_unknown_enum_, allow_field_number_,
- allow_relaxed_whitespace_);
+ allow_relaxed_whitespace_, allow_partial_);
return MergeUsingImpl(input, output, &parser);
}
@@ -1276,7 +1329,7 @@ bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input,
ParserImpl::ALLOW_SINGULAR_OVERWRITES,
allow_case_insensitive_field_, allow_unknown_field_,
allow_unknown_enum_, allow_field_number_,
- allow_relaxed_whitespace_);
+ allow_relaxed_whitespace_, allow_partial_);
return MergeUsingImpl(input, output, &parser);
}
@@ -1291,7 +1344,7 @@ bool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* /* input */,
ParserImpl* parser_impl) {
if (!parser_impl->Parse(output)) return false;
if (!allow_partial_ && !output->IsInitialized()) {
- vector<string> missing_fields;
+ std::vector<string> missing_fields;
output->FindInitializationErrors(&missing_fields);
parser_impl->ReportError(-1, 0, "Message missing required fields: " +
Join(missing_fields, ", "));
@@ -1310,7 +1363,7 @@ bool TextFormat::Parser::ParseFieldValueFromString(
ParserImpl::ALLOW_SINGULAR_OVERWRITES,
allow_case_insensitive_field_, allow_unknown_field_,
allow_unknown_enum_, allow_field_number_,
- allow_relaxed_whitespace_);
+ allow_relaxed_whitespace_, allow_partial_);
return parser.ParseField(field, output);
}
@@ -1565,7 +1618,7 @@ void TextFormat::Printer::Print(const Message& message,
PrintAny(message, generator)) {
return;
}
- vector<const FieldDescriptor*> fields;
+ std::vector<const FieldDescriptor*> fields;
reflection->ListFields(message, &fields);
if (print_message_fields_in_index_order_) {
std::sort(fields.begin(), fields.end(), FieldIndexSorter());

Powered by Google App Engine
This is Rietveld 408576698