| 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 137cbcee2f7f1f53b04fa262b4e6b0de9da94488..1494ebd78d8ca00550af2afed357a9c2666ea2ee 100644
|
| --- a/third_party/protobuf/src/google/protobuf/text_format.cc
|
| +++ b/third_party/protobuf/src/google/protobuf/text_format.cc
|
| @@ -37,6 +37,7 @@
|
| #include <stdio.h>
|
| #include <stack>
|
| #include <limits>
|
| +#include <vector>
|
|
|
| #include <google/protobuf/text_format.h>
|
|
|
| @@ -118,8 +119,10 @@ class TextFormat::Parser::ParserImpl {
|
| ParserImpl(const Descriptor* root_message_type,
|
| io::ZeroCopyInputStream* input_stream,
|
| io::ErrorCollector* error_collector,
|
| + TextFormat::Finder* finder,
|
| SingularOverwritePolicy singular_overwrite_policy)
|
| : error_collector_(error_collector),
|
| + finder_(finder),
|
| tokenizer_error_collector_(this),
|
| tokenizer_(input_stream, &tokenizer_error_collector_),
|
| root_message_type_(root_message_type),
|
| @@ -249,7 +252,9 @@ class TextFormat::Parser::ParserImpl {
|
| }
|
| DO(Consume("]"));
|
|
|
| - field = reflection->FindKnownExtensionByName(field_name);
|
| + field = (finder_ != NULL
|
| + ? finder_->FindExtension(message, field_name)
|
| + : reflection->FindKnownExtensionByName(field_name));
|
|
|
| if (field == NULL) {
|
| ReportError("Extension \"" + field_name + "\" is not defined or "
|
| @@ -301,9 +306,24 @@ class TextFormat::Parser::ParserImpl {
|
| DO(ConsumeFieldMessage(message, reflection, field));
|
| } else {
|
| DO(Consume(":"));
|
| - DO(ConsumeFieldValue(message, reflection, field));
|
| + if (field->is_repeated() && TryConsume("[")) {
|
| + // Short repeated format, e.g. "foo: [1, 2, 3]"
|
| + while (true) {
|
| + DO(ConsumeFieldValue(message, reflection, field));
|
| + if (TryConsume("]")) {
|
| + break;
|
| + }
|
| + DO(Consume(","));
|
| + }
|
| + } else {
|
| + DO(ConsumeFieldValue(message, reflection, field));
|
| + }
|
| }
|
|
|
| + // For historical reasons, fields may optionally be separated by commas or
|
| + // semicolons.
|
| + TryConsume(";") || TryConsume(",");
|
| +
|
| if (field->options().deprecated()) {
|
| ReportWarning("text format contains deprecated field \""
|
| + field_name + "\"");
|
| @@ -397,29 +417,46 @@ class TextFormat::Parser::ParserImpl {
|
| }
|
|
|
| case FieldDescriptor::CPPTYPE_BOOL: {
|
| - string value;
|
| - DO(ConsumeIdentifier(&value));
|
| -
|
| - if (value == "true") {
|
| - SET_FIELD(Bool, true);
|
| - } else if (value == "false") {
|
| - SET_FIELD(Bool, false);
|
| + if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
|
| + uint64 value;
|
| + DO(ConsumeUnsignedInteger(&value, 1));
|
| + SET_FIELD(Bool, value);
|
| } else {
|
| - ReportError("Invalid value for boolean field \"" + field->name()
|
| - + "\". Value: \"" + value + "\".");
|
| - return false;
|
| + string value;
|
| + DO(ConsumeIdentifier(&value));
|
| + if (value == "true" || value == "t") {
|
| + SET_FIELD(Bool, true);
|
| + } else if (value == "false" || value == "f") {
|
| + SET_FIELD(Bool, false);
|
| + } else {
|
| + ReportError("Invalid value for boolean field \"" + field->name()
|
| + + "\". Value: \"" + value + "\".");
|
| + return false;
|
| + }
|
| }
|
| break;
|
| }
|
|
|
| case FieldDescriptor::CPPTYPE_ENUM: {
|
| string value;
|
| - DO(ConsumeIdentifier(&value));
|
| -
|
| - // Find the enumeration value.
|
| const EnumDescriptor* enum_type = field->enum_type();
|
| - const EnumValueDescriptor* enum_value
|
| - = enum_type->FindValueByName(value);
|
| + const EnumValueDescriptor* enum_value = NULL;
|
| +
|
| + if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
|
| + DO(ConsumeIdentifier(&value));
|
| + // Find the enumeration value.
|
| + enum_value = enum_type->FindValueByName(value);
|
| +
|
| + } else if (LookingAt("-") ||
|
| + LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
|
| + int64 int_value;
|
| + DO(ConsumeSignedInteger(&int_value, kint32max));
|
| + value = SimpleItoa(int_value); // for error reporting
|
| + enum_value = enum_type->FindValueByNumber(int_value);
|
| + } else {
|
| + ReportError("Expected integer or identifier.");
|
| + return false;
|
| + }
|
|
|
| if (enum_value == NULL) {
|
| ReportError("Unknown enumeration value of \"" + value + "\" for "
|
| @@ -632,6 +669,7 @@ class TextFormat::Parser::ParserImpl {
|
| };
|
|
|
| io::ErrorCollector* error_collector_;
|
| + TextFormat::Finder* finder_;
|
| ParserErrorCollector tokenizer_error_collector_;
|
| io::Tokenizer tokenizer_;
|
| const Descriptor* root_message_type_;
|
| @@ -765,9 +803,14 @@ class TextFormat::Printer::TextGenerator {
|
|
|
| // ===========================================================================
|
|
|
| +TextFormat::Finder::~Finder() {
|
| +}
|
| +
|
| TextFormat::Parser::Parser()
|
| : error_collector_(NULL),
|
| - allow_partial_(false) {}
|
| + finder_(NULL),
|
| + allow_partial_(false) {
|
| +}
|
|
|
| TextFormat::Parser::~Parser() {}
|
|
|
| @@ -775,7 +818,7 @@ bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input,
|
| Message* output) {
|
| output->Clear();
|
| ParserImpl parser(output->GetDescriptor(), input, error_collector_,
|
| - ParserImpl::FORBID_SINGULAR_OVERWRITES);
|
| + finder_, ParserImpl::FORBID_SINGULAR_OVERWRITES);
|
| return MergeUsingImpl(input, output, &parser);
|
| }
|
|
|
| @@ -788,7 +831,7 @@ bool TextFormat::Parser::ParseFromString(const string& input,
|
| bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input,
|
| Message* output) {
|
| ParserImpl parser(output->GetDescriptor(), input, error_collector_,
|
| - ParserImpl::ALLOW_SINGULAR_OVERWRITES);
|
| + finder_, ParserImpl::ALLOW_SINGULAR_OVERWRITES);
|
| return MergeUsingImpl(input, output, &parser);
|
| }
|
|
|
| @@ -818,7 +861,7 @@ bool TextFormat::Parser::ParseFieldValueFromString(
|
| Message* output) {
|
| io::ArrayInputStream input_stream(input.data(), input.size());
|
| ParserImpl parser(output->GetDescriptor(), &input_stream, error_collector_,
|
| - ParserImpl::ALLOW_SINGULAR_OVERWRITES);
|
| + finder_, ParserImpl::ALLOW_SINGULAR_OVERWRITES);
|
| return parser.ParseField(field, output);
|
| }
|
|
|
| @@ -853,7 +896,7 @@ TextFormat::Printer::Printer()
|
| TextFormat::Printer::~Printer() {}
|
|
|
| bool TextFormat::Printer::PrintToString(const Message& message,
|
| - string* output) {
|
| + string* output) const {
|
| GOOGLE_DCHECK(output) << "output specified is NULL";
|
|
|
| output->clear();
|
| @@ -866,7 +909,7 @@ bool TextFormat::Printer::PrintToString(const Message& message,
|
|
|
| bool TextFormat::Printer::PrintUnknownFieldsToString(
|
| const UnknownFieldSet& unknown_fields,
|
| - string* output) {
|
| + string* output) const {
|
| GOOGLE_DCHECK(output) << "output specified is NULL";
|
|
|
| output->clear();
|
| @@ -875,7 +918,7 @@ bool TextFormat::Printer::PrintUnknownFieldsToString(
|
| }
|
|
|
| bool TextFormat::Printer::Print(const Message& message,
|
| - io::ZeroCopyOutputStream* output) {
|
| + io::ZeroCopyOutputStream* output) const {
|
| TextGenerator generator(output, initial_indent_level_);
|
|
|
| Print(message, generator);
|
| @@ -886,7 +929,7 @@ bool TextFormat::Printer::Print(const Message& message,
|
|
|
| bool TextFormat::Printer::PrintUnknownFields(
|
| const UnknownFieldSet& unknown_fields,
|
| - io::ZeroCopyOutputStream* output) {
|
| + io::ZeroCopyOutputStream* output) const {
|
| TextGenerator generator(output, initial_indent_level_);
|
|
|
| PrintUnknownFields(unknown_fields, generator);
|
| @@ -896,7 +939,7 @@ bool TextFormat::Printer::PrintUnknownFields(
|
| }
|
|
|
| void TextFormat::Printer::Print(const Message& message,
|
| - TextGenerator& generator) {
|
| + TextGenerator& generator) const {
|
| const Reflection* reflection = message.GetReflection();
|
| vector<const FieldDescriptor*> fields;
|
| reflection->ListFields(message, &fields);
|
| @@ -910,7 +953,7 @@ void TextFormat::Printer::PrintFieldValueToString(
|
| const Message& message,
|
| const FieldDescriptor* field,
|
| int index,
|
| - string* output) {
|
| + string* output) const {
|
|
|
| GOOGLE_DCHECK(output) << "output specified is NULL";
|
|
|
| @@ -924,7 +967,7 @@ void TextFormat::Printer::PrintFieldValueToString(
|
| void TextFormat::Printer::PrintField(const Message& message,
|
| const Reflection* reflection,
|
| const FieldDescriptor* field,
|
| - TextGenerator& generator) {
|
| + TextGenerator& generator) const {
|
| if (use_short_repeated_primitives_ &&
|
| field->is_repeated() &&
|
| field->cpp_type() != FieldDescriptor::CPPTYPE_STRING &&
|
| @@ -980,10 +1023,11 @@ void TextFormat::Printer::PrintField(const Message& message,
|
| }
|
| }
|
|
|
| -void TextFormat::Printer::PrintShortRepeatedField(const Message& message,
|
| - const Reflection* reflection,
|
| - const FieldDescriptor* field,
|
| - TextGenerator& generator) {
|
| +void TextFormat::Printer::PrintShortRepeatedField(
|
| + const Message& message,
|
| + const Reflection* reflection,
|
| + const FieldDescriptor* field,
|
| + TextGenerator& generator) const {
|
| // Print primitive repeated field in short form.
|
| PrintFieldName(message, reflection, field, generator);
|
|
|
| @@ -1003,7 +1047,7 @@ void TextFormat::Printer::PrintShortRepeatedField(const Message& message,
|
| void TextFormat::Printer::PrintFieldName(const Message& message,
|
| const Reflection* reflection,
|
| const FieldDescriptor* field,
|
| - TextGenerator& generator) {
|
| + TextGenerator& generator) const {
|
| if (field->is_extension()) {
|
| generator.Print("[");
|
| // We special-case MessageSet elements for compatibility with proto1.
|
| @@ -1031,7 +1075,7 @@ void TextFormat::Printer::PrintFieldValue(
|
| const Reflection* reflection,
|
| const FieldDescriptor* field,
|
| int index,
|
| - TextGenerator& generator) {
|
| + TextGenerator& generator) const {
|
| GOOGLE_DCHECK(field->is_repeated() || (index == -1))
|
| << "Index must be -1 for non-repeated fields";
|
|
|
| @@ -1143,7 +1187,7 @@ static string PaddedHex(IntType value) {
|
| }
|
|
|
| void TextFormat::Printer::PrintUnknownFields(
|
| - const UnknownFieldSet& unknown_fields, TextGenerator& generator) {
|
| + const UnknownFieldSet& unknown_fields, TextGenerator& generator) const {
|
| for (int i = 0; i < unknown_fields.field_count(); i++) {
|
| const UnknownField& field = unknown_fields.field(i);
|
| string field_number = SimpleItoa(field.number());
|
|
|