From 5a76e633ea9b5adb215e93fdc11e1c0c08b3fc74 Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Thu, 17 Nov 2016 16:48:38 -0800 Subject: Integrated internal changes from Google --- src/google/protobuf/util/field_comparator.h | 2 - src/google/protobuf/util/field_comparator_test.cc | 16 +-- src/google/protobuf/util/field_mask_util.cc | 31 +++-- src/google/protobuf/util/field_mask_util.h | 16 ++- src/google/protobuf/util/field_mask_util_test.cc | 21 +++ src/google/protobuf/util/internal/datapiece.cc | 40 ++++-- .../util/internal/default_value_objectwriter.cc | 8 +- .../util/internal/default_value_objectwriter.h | 9 +- .../protobuf/util/internal/field_mask_utility.cc | 2 +- .../protobuf/util/internal/json_stream_parser.cc | 9 +- .../protobuf/util/internal/json_stream_parser.h | 3 + .../util/internal/json_stream_parser_test.cc | 29 ++-- src/google/protobuf/util/internal/proto_writer.cc | 2 +- .../util/internal/protostream_objectsource.cc | 24 ++-- .../util/internal/protostream_objectsource.h | 3 + .../util/internal/protostream_objectsource_test.cc | 7 +- .../util/internal/protostream_objectwriter_test.cc | 20 +-- src/google/protobuf/util/internal/type_info.cc | 20 +-- .../util/internal/type_info_test_helper.cc | 6 +- .../protobuf/util/internal/type_info_test_helper.h | 2 +- src/google/protobuf/util/internal/utility.cc | 8 +- src/google/protobuf/util/json_util_test.cc | 8 +- src/google/protobuf/util/message_differencer.cc | 151 +++++++++++---------- src/google/protobuf/util/message_differencer.h | 1 - .../protobuf/util/message_differencer_unittest.cc | 65 ++++----- src/google/protobuf/util/type_resolver_util.cc | 56 +++----- 26 files changed, 312 insertions(+), 247 deletions(-) (limited to 'src/google/protobuf/util') diff --git a/src/google/protobuf/util/field_comparator.h b/src/google/protobuf/util/field_comparator.h index 3c70a314..ad560ebc 100644 --- a/src/google/protobuf/util/field_comparator.h +++ b/src/google/protobuf/util/field_comparator.h @@ -30,8 +30,6 @@ // Defines classes for field comparison. -// Author: ksroka@google.com (Krzysztof Sroka) - #ifndef GOOGLE_PROTOBUF_UTIL_FIELD_COMPARATOR_H__ #define GOOGLE_PROTOBUF_UTIL_FIELD_COMPARATOR_H__ diff --git a/src/google/protobuf/util/field_comparator_test.cc b/src/google/protobuf/util/field_comparator_test.cc index 6fd631d8..249b8d54 100644 --- a/src/google/protobuf/util/field_comparator_test.cc +++ b/src/google/protobuf/util/field_comparator_test.cc @@ -365,10 +365,10 @@ TEST_F(DefaultFieldComparatorTest, // +inf should be equal even though they are not technically within margin or // fraction. - message_1_.set_optional_float(numeric_limits::infinity()); - message_2_.set_optional_float(numeric_limits::infinity()); - message_1_.set_optional_double(numeric_limits::infinity()); - message_2_.set_optional_double(numeric_limits::infinity()); + message_1_.set_optional_float(std::numeric_limits::infinity()); + message_2_.set_optional_float(std::numeric_limits::infinity()); + message_1_.set_optional_double(std::numeric_limits::infinity()); + message_2_.set_optional_double(std::numeric_limits::infinity()); comparator_.SetFractionAndMargin(field_float, 0.0, 0.0); comparator_.SetFractionAndMargin(field_double, 0.0, 0.0); EXPECT_EQ(FieldComparator::SAME, @@ -380,10 +380,10 @@ TEST_F(DefaultFieldComparatorTest, // -inf should be equal even though they are not technically within margin or // fraction. - message_1_.set_optional_float(-numeric_limits::infinity()); - message_2_.set_optional_float(-numeric_limits::infinity()); - message_1_.set_optional_double(-numeric_limits::infinity()); - message_2_.set_optional_double(-numeric_limits::infinity()); + message_1_.set_optional_float(-std::numeric_limits::infinity()); + message_2_.set_optional_float(-std::numeric_limits::infinity()); + message_1_.set_optional_double(-std::numeric_limits::infinity()); + message_2_.set_optional_double(-std::numeric_limits::infinity()); comparator_.SetFractionAndMargin(field_float, 0.0, 0.0); comparator_.SetFractionAndMargin(field_double, 0.0, 0.0); EXPECT_EQ(FieldComparator::SAME, diff --git a/src/google/protobuf/util/field_mask_util.cc b/src/google/protobuf/util/field_mask_util.cc index 9dfcbd72..07550e6d 100644 --- a/src/google/protobuf/util/field_mask_util.cc +++ b/src/google/protobuf/util/field_mask_util.cc @@ -45,7 +45,7 @@ string FieldMaskUtil::ToString(const FieldMask& mask) { void FieldMaskUtil::FromString(StringPiece str, FieldMask* out) { out->Clear(); - vector paths = Split(str, ","); + std::vector paths = Split(str, ","); for (int i = 0; i < paths.size(); ++i) { if (paths[i].empty()) continue; out->add_paths(paths[i]); @@ -116,7 +116,7 @@ bool FieldMaskUtil::ToJsonString(const FieldMask& mask, string* out) { bool FieldMaskUtil::FromJsonString(StringPiece str, FieldMask* out) { out->Clear(); - vector paths = Split(str, ","); + std::vector paths = Split(str, ","); for (int i = 0; i < paths.size(); ++i) { if (paths[i].empty()) continue; string snakecase_path; @@ -128,9 +128,13 @@ bool FieldMaskUtil::FromJsonString(StringPiece str, FieldMask* out) { return true; } -bool FieldMaskUtil::InternalIsValidPath(const Descriptor* descriptor, - StringPiece path) { - vector parts = Split(path, "."); +bool FieldMaskUtil::GetFieldDescriptors( + const Descriptor* descriptor, StringPiece path, + std::vector* field_descriptors) { + if (field_descriptors != NULL) { + field_descriptors->clear(); + } + std::vector parts = Split(path, "."); for (int i = 0; i < parts.size(); ++i) { const string& field_name = parts[i]; if (descriptor == NULL) { @@ -140,6 +144,9 @@ bool FieldMaskUtil::InternalIsValidPath(const Descriptor* descriptor, if (field == NULL) { return false; } + if (field_descriptors != NULL) { + field_descriptors->push_back(field); + } if (!field->is_repeated() && field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { descriptor = field->message_type(); @@ -216,14 +223,14 @@ class FieldMaskTree { ~Node() { ClearChildren(); } void ClearChildren() { - for (map::iterator it = children.begin(); + for (std::map::iterator it = children.begin(); it != children.end(); ++it) { delete it->second; } children.clear(); } - map children; + std::map children; private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Node); @@ -274,7 +281,7 @@ void FieldMaskTree::MergeToFieldMask(const string& prefix, const Node* node, out->add_paths(prefix); return; } - for (map::const_iterator it = node->children.begin(); + for (std::map::const_iterator it = node->children.begin(); it != node->children.end(); ++it) { string current_path = prefix.empty() ? it->first : prefix + "." + it->first; MergeToFieldMask(current_path, it->second, out); @@ -282,7 +289,7 @@ void FieldMaskTree::MergeToFieldMask(const string& prefix, const Node* node, } void FieldMaskTree::AddPath(const string& path) { - vector parts = Split(path, "."); + std::vector parts = Split(path, "."); if (parts.empty()) { return; } @@ -309,7 +316,7 @@ void FieldMaskTree::AddPath(const string& path) { } void FieldMaskTree::IntersectPath(const string& path, FieldMaskTree* out) { - vector parts = Split(path, "."); + std::vector parts = Split(path, "."); if (parts.empty()) { return; } @@ -339,7 +346,7 @@ void FieldMaskTree::MergeLeafNodesToTree(const string& prefix, const Node* node, if (node->children.empty()) { out->AddPath(prefix); } - for (map::const_iterator it = node->children.begin(); + for (std::map::const_iterator it = node->children.begin(); it != node->children.end(); ++it) { string current_path = prefix.empty() ? it->first : prefix + "." + it->first; MergeLeafNodesToTree(current_path, it->second, out); @@ -353,7 +360,7 @@ void FieldMaskTree::MergeMessage(const Node* node, const Message& source, const Reflection* source_reflection = source.GetReflection(); const Reflection* destination_reflection = destination->GetReflection(); const Descriptor* descriptor = source.GetDescriptor(); - for (map::const_iterator it = node->children.begin(); + for (std::map::const_iterator it = node->children.begin(); it != node->children.end(); ++it) { const string& field_name = it->first; const Node* child = it->second; diff --git a/src/google/protobuf/util/field_mask_util.h b/src/google/protobuf/util/field_mask_util.h index 396c9aea..ab1f2e94 100644 --- a/src/google/protobuf/util/field_mask_util.h +++ b/src/google/protobuf/util/field_mask_util.h @@ -59,17 +59,26 @@ class LIBPROTOBUF_EXPORT FieldMaskUtil { static bool ToJsonString(const FieldMask& mask, string* out); static bool FromJsonString(StringPiece str, FieldMask* out); + // Get the descriptors of the fields which the given path from the message + // descriptor traverses, if field_descriptors is not null. + // Return false if the path is not valid, and the content of field_descriptors + // is unspecified. + static bool GetFieldDescriptors( + const Descriptor* descriptor, StringPiece path, + std::vector* field_descriptors); + // Checks whether the given path is valid for type T. template static bool IsValidPath(StringPiece path) { - return InternalIsValidPath(T::descriptor(), path); + return GetFieldDescriptors(T::descriptor(), path, NULL); } // Checks whether the given FieldMask is valid for type T. template static bool IsValidFieldMask(const FieldMask& mask) { for (int i = 0; i < mask.paths_size(); ++i) { - if (!InternalIsValidPath(T::descriptor(), mask.paths(i))) return false; + if (!GetFieldDescriptors(T::descriptor(), mask.paths(i), NULL)) + return false; } return true; } @@ -149,9 +158,6 @@ class LIBPROTOBUF_EXPORT FieldMaskUtil { // successfully. static bool CamelCaseToSnakeCase(StringPiece input, string* output); - static bool InternalIsValidPath(const Descriptor* descriptor, - StringPiece path); - static void InternalGetFieldMaskForAllFields(const Descriptor* descriptor, FieldMask* out); }; diff --git a/src/google/protobuf/util/field_mask_util_test.cc b/src/google/protobuf/util/field_mask_util_test.cc index 43fb7905..f952786f 100644 --- a/src/google/protobuf/util/field_mask_util_test.cc +++ b/src/google/protobuf/util/field_mask_util_test.cc @@ -159,6 +159,27 @@ TEST(FieldMaskUtilTest, JsonStringFormat) { EXPECT_EQ("baz_quz", mask.paths(1)); } +TEST(FieldMaskUtilTest, GetFieldDescriptors) { + std::vector field_descriptors; + EXPECT_TRUE(FieldMaskUtil::GetFieldDescriptors( + TestAllTypes::descriptor(), "optional_int32", &field_descriptors)); + EXPECT_EQ(1, field_descriptors.size()); + EXPECT_EQ("optional_int32", field_descriptors[0]->name()); + EXPECT_FALSE(FieldMaskUtil::GetFieldDescriptors( + TestAllTypes::descriptor(), "optional_nonexist", NULL)); + EXPECT_TRUE(FieldMaskUtil::GetFieldDescriptors(TestAllTypes::descriptor(), + "optional_nested_message.bb", + &field_descriptors)); + EXPECT_EQ(2, field_descriptors.size()); + EXPECT_EQ("optional_nested_message", field_descriptors[0]->name()); + EXPECT_EQ("bb", field_descriptors[1]->name()); + EXPECT_FALSE(FieldMaskUtil::GetFieldDescriptors( + TestAllTypes::descriptor(), "optional_nested_message.nonexist", NULL)); + // FieldMask cannot be used to specify sub-fields of a repeated message. + EXPECT_FALSE(FieldMaskUtil::GetFieldDescriptors( + TestAllTypes::descriptor(), "repeated_nested_message.bb", NULL)); +} + TEST(FieldMaskUtilTest, TestIsVaildPath) { EXPECT_TRUE(FieldMaskUtil::IsValidPath("optional_int32")); EXPECT_FALSE(FieldMaskUtil::IsValidPath("optional_nonexist")); diff --git a/src/google/protobuf/util/internal/datapiece.cc b/src/google/protobuf/util/internal/datapiece.cc index eeb55c6b..213c2c40 100644 --- a/src/google/protobuf/util/internal/datapiece.cc +++ b/src/google/protobuf/util/internal/datapiece.cc @@ -94,19 +94,24 @@ StatusOr FloatingPointToIntConvertAndCheck(From before) { } // For conversion between double and float only. -template -StatusOr FloatingPointConvertAndCheck(From before) { - if (MathLimits::IsNaN(before)) { - return std::numeric_limits::quiet_NaN(); - } +StatusOr FloatToDouble(float before) { + // Casting float to double should just work as double has more precision + // than float. + return static_cast(before); +} - To after = static_cast(before); - if (MathUtil::AlmostEquals(after, before)) { - return after; +StatusOr DoubleToFloat(double before) { + if (MathLimits::IsNaN(before)) { + return std::numeric_limits::quiet_NaN(); + } else if (!MathLimits::IsFinite(before)) { + // Converting a double +inf/-inf to float should just work. + return static_cast(before); + } else if (before > std::numeric_limits::max() || + before < -std::numeric_limits::max()) { + // Double value outside of the range of float. + return InvalidArgument(DoubleAsString(before)); } else { - return InvalidArgument(::google::protobuf::internal::is_same::value - ? DoubleAsString(before) - : FloatAsString(before)); + return static_cast(before); } } @@ -162,20 +167,27 @@ StatusOr DataPiece::ToUint64() const { StatusOr DataPiece::ToDouble() const { if (type_ == TYPE_FLOAT) { - return FloatingPointConvertAndCheck(float_); + return FloatToDouble(float_); } if (type_ == TYPE_STRING) { if (str_ == "Infinity") return std::numeric_limits::infinity(); if (str_ == "-Infinity") return -std::numeric_limits::infinity(); if (str_ == "NaN") return std::numeric_limits::quiet_NaN(); - return StringToNumber(safe_strtod); + StatusOr value = StringToNumber(safe_strtod); + if (value.ok() && !MathLimits::IsFinite(value.ValueOrDie())) { + // safe_strtod converts out-of-range values to +inf/-inf, but we want + // to report them as errors. + return InvalidArgument(StrCat("\"", str_, "\"")); + } else { + return value; + } } return GenericConvert(); } StatusOr DataPiece::ToFloat() const { if (type_ == TYPE_DOUBLE) { - return FloatingPointConvertAndCheck(double_); + return DoubleToFloat(double_); } if (type_ == TYPE_STRING) { if (str_ == "Infinity") return std::numeric_limits::infinity(); diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.cc b/src/google/protobuf/util/internal/default_value_objectwriter.cc index ac1ed9ab..1772219a 100644 --- a/src/google/protobuf/util/internal/default_value_objectwriter.cc +++ b/src/google/protobuf/util/internal/default_value_objectwriter.cc @@ -190,7 +190,7 @@ void DefaultValueObjectWriter::RegisterFieldScrubCallBack( DefaultValueObjectWriter::Node::Node( const string& name, const google::protobuf::Type* type, NodeKind kind, - const DataPiece& data, bool is_placeholder, const vector& path, + const DataPiece& data, bool is_placeholder, const std::vector& path, bool suppress_empty_list, FieldScrubCallBack* field_scrub_callback) : name_(name), type_(type), @@ -310,7 +310,7 @@ void DefaultValueObjectWriter::Node::PopulateChildren( // This code is checking if the field to be added to the tree should be // scrubbed or not by calling the field_scrub_callback_ callback function. - vector path; + std::vector path; if (!path_.empty()) { path.insert(path.begin(), path_.begin(), path_.end()); } @@ -466,7 +466,7 @@ DataPiece DefaultValueObjectWriter::CreateDefaultDataPieceForField( DefaultValueObjectWriter* DefaultValueObjectWriter::StartObject( StringPiece name) { if (current_ == NULL) { - vector path; + std::vector path; root_.reset(new Node(name.ToString(), &type_, OBJECT, DataPiece::NullData(), false, path, suppress_empty_list_, field_scrub_callback_.get())); @@ -514,7 +514,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::EndObject() { DefaultValueObjectWriter* DefaultValueObjectWriter::StartList( StringPiece name) { if (current_ == NULL) { - vector path; + std::vector path; root_.reset(new Node(name.ToString(), &type_, LIST, DataPiece::NullData(), false, path, suppress_empty_list_, field_scrub_callback_.get())); diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.h b/src/google/protobuf/util/internal/default_value_objectwriter.h index 5f3b25f3..dc4551c9 100644 --- a/src/google/protobuf/util/internal/default_value_objectwriter.h +++ b/src/google/protobuf/util/internal/default_value_objectwriter.h @@ -139,8 +139,9 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter { class LIBPROTOBUF_EXPORT Node { public: Node(const string& name, const google::protobuf::Type* type, NodeKind kind, - const DataPiece& data, bool is_placeholder, const vector& path, - bool suppress_empty_list, FieldScrubCallBack* field_scrub_callback); + const DataPiece& data, bool is_placeholder, + const std::vector& path, bool suppress_empty_list, + FieldScrubCallBack* field_scrub_callback); virtual ~Node() { for (int i = 0; i < children_.size(); ++i) { delete children_[i]; @@ -166,7 +167,7 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter { // Accessors const string& name() const { return name_; } - const vector& path() const { return path_; } + const std::vector& path() const { return path_; } const google::protobuf::Type* type() const { return type_; } @@ -255,7 +256,7 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter { // google::protobuf::Type of the root message type. const google::protobuf::Type& type_; // Holds copies of strings passed to RenderString. - vector string_values_; + std::vector string_values_; // The current Node. Owned by its parents. Node* current_; diff --git a/src/google/protobuf/util/internal/field_mask_utility.cc b/src/google/protobuf/util/internal/field_mask_utility.cc index f0e8fc88..53b90fb0 100644 --- a/src/google/protobuf/util/internal/field_mask_utility.cc +++ b/src/google/protobuf/util/internal/field_mask_utility.cc @@ -112,7 +112,7 @@ string ConvertFieldMaskPath(const StringPiece path, util::Status DecodeCompactFieldMaskPaths(StringPiece paths, PathSinkCallback path_sink) { - stack prefix; + std::stack prefix; int length = paths.length(); int previous_position = 0; bool in_map_key = false; diff --git a/src/google/protobuf/util/internal/json_stream_parser.cc b/src/google/protobuf/util/internal/json_stream_parser.cc index a8d48eff..2af4ad90 100644 --- a/src/google/protobuf/util/internal/json_stream_parser.cc +++ b/src/google/protobuf/util/internal/json_stream_parser.cc @@ -45,6 +45,8 @@ #include #include #include +#include + namespace google { namespace protobuf { @@ -108,7 +110,8 @@ JsonStreamParser::JsonStreamParser(ObjectWriter* ow) string_open_(0), chunk_storage_(), coerce_to_utf8_(false), - allow_empty_null_(false) { + allow_empty_null_(false), + loose_float_number_conversion_(false) { // Initialize the stack with a single value to be parsed. stack_.push(VALUE); } @@ -532,6 +535,10 @@ util::Status JsonStreamParser::ParseNumberHelper(NumberResult* result) { if (!safe_strtod(number, &result->double_val)) { return ReportFailure("Unable to parse number."); } + if (!loose_float_number_conversion_ && + !MathLimits::IsFinite(result->double_val)) { + return ReportFailure("Number exceeds the range of double."); + } result->type = NumberResult::DOUBLE; p_.remove_prefix(index); return util::Status::OK; diff --git a/src/google/protobuf/util/internal/json_stream_parser.h b/src/google/protobuf/util/internal/json_stream_parser.h index 78b35cc2..6b9d46ee 100644 --- a/src/google/protobuf/util/internal/json_stream_parser.h +++ b/src/google/protobuf/util/internal/json_stream_parser.h @@ -255,6 +255,9 @@ class LIBPROTOBUF_EXPORT JsonStreamParser { // value. bool allow_empty_null_; + // Whether allows out-of-range floating point numbers or reject them. + bool loose_float_number_conversion_; + GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(JsonStreamParser); }; diff --git a/src/google/protobuf/util/internal/json_stream_parser_test.cc b/src/google/protobuf/util/internal/json_stream_parser_test.cc index eaa7e045..ca71ff24 100644 --- a/src/google/protobuf/util/internal/json_stream_parser_test.cc +++ b/src/google/protobuf/util/internal/json_stream_parser_test.cc @@ -89,7 +89,8 @@ class JsonStreamParserTest : public ::testing::Test { virtual ~JsonStreamParserTest() {} util::Status RunTest(StringPiece json, int split, bool coerce_utf8 = false, - bool allow_empty_null = false) { + bool allow_empty_null = false, + bool loose_float_number_conversion = false) { JsonStreamParser parser(&mock_); // Special case for split == length, test parsing one character at a time. @@ -120,9 +121,10 @@ class JsonStreamParserTest : public ::testing::Test { } void DoTest(StringPiece json, int split, bool coerce_utf8 = false, - bool allow_empty_null = false) { - util::Status result = - RunTest(json, split, coerce_utf8, allow_empty_null); + bool allow_empty_null = false, + bool loose_float_number_conversion = false) { + util::Status result = RunTest(json, split, coerce_utf8, allow_empty_null, + loose_float_number_conversion); if (!result.ok()) { GOOGLE_LOG(WARNING) << result; } @@ -142,7 +144,7 @@ class JsonStreamParserTest : public ::testing::Test { #ifndef _MSC_VER // TODO(xiaofeng): We have to disable InSequence check for MSVC because it // causes stack overflow due to its use of a linked list that is desctructed - // recursively. + // recursively. ::testing::InSequence in_sequence_; #endif // !_MSC_VER MockObjectWriter mock_; @@ -322,8 +324,7 @@ TEST_F(JsonStreamParserTest, ObjectKeyTypes) { // - array containing primitive values (true, false, null, num, string) TEST_F(JsonStreamParserTest, ArrayPrimitiveValues) { - StringPiece str = - "[true, false, null, 'one', \"two\"]"; + StringPiece str = "[true, false, null, 'one', \"two\"]"; for (int i = 0; i <= str.length(); ++i) { ow_.StartList("") ->RenderBool("", true) @@ -710,17 +711,19 @@ TEST_F(JsonStreamParserTest, NegativeNumberTooBig) { } } -/* -TODO(sven): Fail parsing when parsing a double that is too large. - TEST_F(JsonStreamParserTest, DoubleTooBig) { - StringPiece str = "[184464073709551232321616.45]"; + StringPiece str = "[1.89769e+308]"; for (int i = 0; i <= str.length(); ++i) { ow_.StartList(""); - DoErrorTest(str, i, "Unable to parse number"); + DoErrorTest(str, i, "Number exceeds the range of double."); + } + str = "[-1.89769e+308]"; + for (int i = 0; i <= str.length(); ++i) { + ow_.StartList(""); + DoErrorTest(str, i, "Number exceeds the range of double."); } } -*/ + // invalid bare backslash. TEST_F(JsonStreamParserTest, UnfinishedEscape) { diff --git a/src/google/protobuf/util/internal/proto_writer.cc b/src/google/protobuf/util/internal/proto_writer.cc index 4dcf4c3b..8bebf2ab 100644 --- a/src/google/protobuf/util/internal/proto_writer.cc +++ b/src/google/protobuf/util/internal/proto_writer.cc @@ -354,7 +354,7 @@ ProtoWriter::ProtoElement* ProtoWriter::ProtoElement::pop() { if (!proto3_) { // Calls the registered error listener for any required field(s) not yet // seen. - for (set::iterator it = + for (std::set::iterator it = required_fields_.begin(); it != required_fields_.end(); ++it) { ow_->MissingField((*it)->name()); diff --git a/src/google/protobuf/util/internal/protostream_objectsource.cc b/src/google/protobuf/util/internal/protostream_objectsource.cc index 150f3cf1..554757d0 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource.cc +++ b/src/google/protobuf/util/internal/protostream_objectsource.cc @@ -85,7 +85,7 @@ const google::protobuf::EnumValue* FindEnumValueByNumber( const google::protobuf::Enum& tech_enum, int number); // Utility function to format nanos. -const string FormatNanos(uint32 nanos); +const string FormatNanos(uint32 nanos, bool with_trailing_zeros); StatusOr MapKeyDefaultValueAsString( const google::protobuf::Field& field) { @@ -122,7 +122,8 @@ ProtoStreamObjectSource::ProtoStreamObjectSource( use_lower_camel_for_enums_(false), recursion_depth_(0), max_recursion_depth_(kDefaultMaxRecursionDepth), - render_unknown_fields_(false) { + render_unknown_fields_(false), + add_trailing_zeros_for_timestamp_and_duration_(false) { GOOGLE_LOG_IF(DFATAL, stream == NULL) << "Input stream is NULL."; } @@ -136,7 +137,8 @@ ProtoStreamObjectSource::ProtoStreamObjectSource( use_lower_camel_for_enums_(false), recursion_depth_(0), max_recursion_depth_(kDefaultMaxRecursionDepth), - render_unknown_fields_(false) { + render_unknown_fields_(false), + add_trailing_zeros_for_timestamp_and_duration_(false) { GOOGLE_LOG_IF(DFATAL, stream == NULL) << "Input stream is NULL."; } @@ -318,7 +320,7 @@ Status ProtoStreamObjectSource::RenderPacked( Status ProtoStreamObjectSource::RenderTimestamp( const ProtoStreamObjectSource* os, const google::protobuf::Type& type, StringPiece field_name, ObjectWriter* ow) { - pair p = os->ReadSecondsAndNanos(type); + std::pair p = os->ReadSecondsAndNanos(type); int64 seconds = p.first; int32 nanos = p.second; if (seconds > kTimestampMaxSeconds || seconds < kTimestampMinSeconds) { @@ -342,7 +344,7 @@ Status ProtoStreamObjectSource::RenderTimestamp( Status ProtoStreamObjectSource::RenderDuration( const ProtoStreamObjectSource* os, const google::protobuf::Type& type, StringPiece field_name, ObjectWriter* ow) { - pair p = os->ReadSecondsAndNanos(type); + std::pair p = os->ReadSecondsAndNanos(type); int64 seconds = p.first; int32 nanos = p.second; if (seconds > kDurationMaxSeconds || seconds < kDurationMinSeconds) { @@ -372,8 +374,10 @@ Status ProtoStreamObjectSource::RenderDuration( sign = "-"; nanos = -nanos; } - string formatted_duration = StringPrintf("%s%lld%ss", sign.c_str(), seconds, - FormatNanos(nanos).c_str()); + string formatted_duration = StringPrintf( + "%s%lld%ss", sign.c_str(), seconds, + FormatNanos(nanos, os->add_trailing_zeros_for_timestamp_and_duration_) + .c_str()); ow->RenderString(field_name, formatted_duration); return Status::OK; } @@ -1103,8 +1107,10 @@ const google::protobuf::EnumValue* FindEnumValueByNumber( // TODO(skarvaje): Look into optimizing this by not doing computation on // double. -const string FormatNanos(uint32 nanos) { - if (nanos == 0) return ""; +const string FormatNanos(uint32 nanos, bool with_trailing_zeros) { + if (nanos == 0) { + return with_trailing_zeros ? ".000" : ""; + } const char* format = (nanos % 1000 != 0) ? "%.9f" : (nanos % 1000000 != 0) ? "%.6f" : "%.3f"; diff --git a/src/google/protobuf/util/internal/protostream_objectsource.h b/src/google/protobuf/util/internal/protostream_objectsource.h index adecfbd3..88ca652b 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource.h +++ b/src/google/protobuf/util/internal/protostream_objectsource.h @@ -294,6 +294,9 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource { // Whether to render unknown fields. bool render_unknown_fields_; + // Whether to add trailing zeros for timestamp and duration. + bool add_trailing_zeros_for_timestamp_and_duration_; + GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(ProtoStreamObjectSource); }; diff --git a/src/google/protobuf/util/internal/protostream_objectsource_test.cc b/src/google/protobuf/util/internal/protostream_objectsource_test.cc index cac28a06..bf29c17a 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource_test.cc +++ b/src/google/protobuf/util/internal/protostream_objectsource_test.cc @@ -101,7 +101,8 @@ class ProtostreamObjectSourceTest : helper_(GetParam()), mock_(), ow_(&mock_), - use_lower_camel_for_enums_(false) { + use_lower_camel_for_enums_(false), + add_trailing_zeros_(false) { helper_.ResetTypeInfo(Book::descriptor(), Proto3Message::descriptor()); } @@ -269,11 +270,14 @@ class ProtostreamObjectSourceTest void UseLowerCamelForEnums() { use_lower_camel_for_enums_ = true; } + void AddTrailingZeros() { add_trailing_zeros_ = true; } + testing::TypeInfoTestHelper helper_; ::testing::NiceMock mock_; ExpectingObjectWriter ow_; bool use_lower_camel_for_enums_; + bool add_trailing_zeros_; }; INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest, @@ -1023,6 +1027,7 @@ TEST_P(ProtostreamObjectSourceTimestampTest, TimestampDurationDefaultValue) { DoTest(out, TimestampDuration::descriptor()); } + } // namespace converter } // namespace util } // namespace protobuf diff --git a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc index e7b38520..a9b15e68 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc +++ b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc @@ -113,13 +113,13 @@ class BaseProtoStreamObjectWriterTest listener_(), output_(new GrowingArrayByteSink(1000)), ow_() { - vector descriptors; + std::vector descriptors; descriptors.push_back(descriptor); ResetTypeInfo(descriptors); } explicit BaseProtoStreamObjectWriterTest( - vector descriptors) + std::vector descriptors) : helper_(GetParam()), listener_(), output_(new GrowingArrayByteSink(1000)), @@ -127,7 +127,7 @@ class BaseProtoStreamObjectWriterTest ResetTypeInfo(descriptors); } - void ResetTypeInfo(vector descriptors) { + void ResetTypeInfo(std::vector descriptors) { GOOGLE_CHECK(!descriptors.empty()) << "Must have at least one descriptor!"; helper_.ResetTypeInfo(descriptors); ow_.reset(helper_.NewProtoWriter(GetTypeUrl(descriptors[0]), output_.get(), @@ -135,7 +135,7 @@ class BaseProtoStreamObjectWriterTest } void ResetTypeInfo(const Descriptor* descriptor) { - vector descriptors; + std::vector descriptors; descriptors.push_back(descriptor); ResetTypeInfo(descriptors); } @@ -1078,7 +1078,7 @@ class ProtoStreamObjectWriterTimestampDurationTest : public BaseProtoStreamObjectWriterTest { protected: ProtoStreamObjectWriterTimestampDurationTest() { - vector descriptors; + std::vector descriptors; descriptors.push_back(TimestampDuration::descriptor()); descriptors.push_back(google::protobuf::Timestamp::descriptor()); descriptors.push_back(google::protobuf::Duration::descriptor()); @@ -1473,7 +1473,7 @@ class ProtoStreamObjectWriterStructTest // Resets ProtoWriter with current set of options and other state. void ResetProtoWriter() { - vector descriptors; + std::vector descriptors; descriptors.push_back(StructType::descriptor()); descriptors.push_back(google::protobuf::Struct::descriptor()); ResetTypeInfo(descriptors); @@ -1664,7 +1664,7 @@ TEST_P(ProtoStreamObjectWriterMapTest, RepeatedMapKeyTest) { class ProtoStreamObjectWriterAnyTest : public BaseProtoStreamObjectWriterTest { protected: ProtoStreamObjectWriterAnyTest() { - vector descriptors; + std::vector descriptors; descriptors.push_back(AnyOut::descriptor()); descriptors.push_back(Book::descriptor()); descriptors.push_back(google::protobuf::Any::descriptor()); @@ -2308,7 +2308,7 @@ class ProtoStreamObjectWriterFieldMaskTest : public BaseProtoStreamObjectWriterTest { protected: ProtoStreamObjectWriterFieldMaskTest() { - vector descriptors; + std::vector descriptors; descriptors.push_back(FieldMaskTest::descriptor()); descriptors.push_back(google::protobuf::FieldMask::descriptor()); ResetTypeInfo(descriptors); @@ -2560,7 +2560,7 @@ class ProtoStreamObjectWriterWrappersTest : public BaseProtoStreamObjectWriterTest { protected: ProtoStreamObjectWriterWrappersTest() { - vector descriptors; + std::vector descriptors; descriptors.push_back(Int32Wrapper::descriptor()); descriptors.push_back(google::protobuf::Int32Value::descriptor()); ResetTypeInfo(descriptors); @@ -2583,7 +2583,7 @@ class ProtoStreamObjectWriterOneOfsTest : public BaseProtoStreamObjectWriterTest { protected: ProtoStreamObjectWriterOneOfsTest() { - vector descriptors; + std::vector descriptors; descriptors.push_back(OneOfsRequest::descriptor()); descriptors.push_back(google::protobuf::Struct::descriptor()); ResetTypeInfo(descriptors); diff --git a/src/google/protobuf/util/internal/type_info.cc b/src/google/protobuf/util/internal/type_info.cc index 00a8ee7a..17d58475 100644 --- a/src/google/protobuf/util/internal/type_info.cc +++ b/src/google/protobuf/util/internal/type_info.cc @@ -60,7 +60,8 @@ class TypeInfoForTypeResolver : public TypeInfo { virtual util::StatusOr ResolveTypeUrl( StringPiece type_url) const { - map::iterator it = cached_types_.find(type_url); + std::map::iterator it = + cached_types_.find(type_url); if (it != cached_types_.end()) { return it->second; } @@ -85,7 +86,8 @@ class TypeInfoForTypeResolver : public TypeInfo { virtual const google::protobuf::Enum* GetEnumByTypeUrl( StringPiece type_url) const { - map::iterator it = cached_enums_.find(type_url); + std::map::iterator it = + cached_enums_.find(type_url); if (it != cached_enums_.end()) { return it->second.ok() ? it->second.ValueOrDie() : NULL; } @@ -123,8 +125,8 @@ class TypeInfoForTypeResolver : public TypeInfo { typedef util::StatusOr StatusOrEnum; template - static void DeleteCachedTypes(map* cached_types) { - for (typename map::iterator it = cached_types->begin(); + static void DeleteCachedTypes(std::map* cached_types) { + for (typename std::map::iterator it = cached_types->begin(); it != cached_types->end(); ++it) { if (it->second.ok()) { delete it->second.ValueOrDie(); @@ -151,13 +153,13 @@ class TypeInfoForTypeResolver : public TypeInfo { // Stores string values that will be referenced by StringPieces in // cached_types_, cached_enums_ and camel_case_name_table_. - mutable set string_storage_; + mutable std::set string_storage_; - mutable map cached_types_; - mutable map cached_enums_; + mutable std::map cached_types_; + mutable std::map cached_enums_; - mutable set indexed_types_; - mutable map camel_case_name_table_; + mutable std::set indexed_types_; + mutable std::map camel_case_name_table_; }; } // namespace diff --git a/src/google/protobuf/util/internal/type_info_test_helper.cc b/src/google/protobuf/util/internal/type_info_test_helper.cc index 49e18ed0..737ba9e4 100644 --- a/src/google/protobuf/util/internal/type_info_test_helper.cc +++ b/src/google/protobuf/util/internal/type_info_test_helper.cc @@ -55,7 +55,7 @@ namespace testing { void TypeInfoTestHelper::ResetTypeInfo( - const vector& descriptors) { + const std::vector& descriptors) { switch (type_) { case USE_TYPE_RESOLVER: { const DescriptorPool* pool = descriptors[0]->file()->pool(); @@ -73,14 +73,14 @@ void TypeInfoTestHelper::ResetTypeInfo( } void TypeInfoTestHelper::ResetTypeInfo(const Descriptor* descriptor) { - vector descriptors; + std::vector descriptors; descriptors.push_back(descriptor); ResetTypeInfo(descriptors); } void TypeInfoTestHelper::ResetTypeInfo(const Descriptor* descriptor1, const Descriptor* descriptor2) { - vector descriptors; + std::vector descriptors; descriptors.push_back(descriptor1); descriptors.push_back(descriptor2); ResetTypeInfo(descriptors); diff --git a/src/google/protobuf/util/internal/type_info_test_helper.h b/src/google/protobuf/util/internal/type_info_test_helper.h index 1a279849..1a196715 100644 --- a/src/google/protobuf/util/internal/type_info_test_helper.h +++ b/src/google/protobuf/util/internal/type_info_test_helper.h @@ -64,7 +64,7 @@ class TypeInfoTestHelper { explicit TypeInfoTestHelper(TypeInfoSource type) : type_(type) {} // Creates a TypeInfo object for the given set of descriptors. - void ResetTypeInfo(const vector& descriptors); + void ResetTypeInfo(const std::vector& descriptors); // Convinent overloads. void ResetTypeInfo(const Descriptor* descriptor); diff --git a/src/google/protobuf/util/internal/utility.cc b/src/google/protobuf/util/internal/utility.cc index 9aab3481..d74c3f3a 100644 --- a/src/google/protobuf/util/internal/utility.cc +++ b/src/google/protobuf/util/internal/utility.cc @@ -30,6 +30,8 @@ #include +#include + #include #include #include @@ -41,8 +43,6 @@ #include #include -#include - namespace google { namespace protobuf { namespace util { @@ -324,7 +324,7 @@ string ToSnakeCase(StringPiece input) { return result; } -set* well_known_types_ = NULL; +std::set* well_known_types_ = NULL; GOOGLE_PROTOBUF_DECLARE_ONCE(well_known_types_init_); const char* well_known_types_name_array_[] = { "google.protobuf.Timestamp", "google.protobuf.Duration", @@ -337,7 +337,7 @@ const char* well_known_types_name_array_[] = { void DeleteWellKnownTypes() { delete well_known_types_; } void InitWellKnownTypes() { - well_known_types_ = new set; + well_known_types_ = new std::set; for (int i = 0; i < GOOGLE_ARRAYSIZE(well_known_types_name_array_); ++i) { well_known_types_->insert(well_known_types_name_array_[i]); } diff --git a/src/google/protobuf/util/json_util_test.cc b/src/google/protobuf/util/json_util_test.cc index 24ff5fd6..3ce779c9 100644 --- a/src/google/protobuf/util/json_util_test.cc +++ b/src/google/protobuf/util/json_util_test.cc @@ -251,11 +251,11 @@ TEST_F(JsonUtilTest, TestDynamicMessage) { EXPECT_EQ(ToJson(generated, options), ToJson(*message, options)); } -typedef pair Segment; +typedef std::pair Segment; // A ZeroCopyOutputStream that writes to multiple buffers. class SegmentedZeroCopyOutputStream : public io::ZeroCopyOutputStream { public: - explicit SegmentedZeroCopyOutputStream(list segments) + explicit SegmentedZeroCopyOutputStream(std::list segments) : segments_(segments), last_segment_(static_cast(NULL), 0), byte_count_(0) {} virtual bool Next(void** buffer, int* length) { @@ -281,7 +281,7 @@ class SegmentedZeroCopyOutputStream : public io::ZeroCopyOutputStream { virtual int64 ByteCount() const { return byte_count_; } private: - list segments_; + std::list segments_; Segment last_segment_; int64 byte_count_; }; @@ -299,7 +299,7 @@ TEST(ZeroCopyStreamByteSinkTest, TestAllInputOutputPatterns) { for (int split_pattern = 0; split_pattern < (1 << (kOutputBufferLength - 1)); split_pattern += kSkippedPatternCount) { // Split the buffer into small segments according to the split_pattern. - list segments; + std::list segments; int segment_start = 0; for (int i = 0; i < kOutputBufferLength - 1; ++i) { if (split_pattern & (1 << i)) { diff --git a/src/google/protobuf/util/message_differencer.cc b/src/google/protobuf/util/message_differencer.cc index 328b40d8..203d8388 100644 --- a/src/google/protobuf/util/message_differencer.cc +++ b/src/google/protobuf/util/message_differencer.cc @@ -73,7 +73,7 @@ class MessageDifferencer::MultipleFieldsMapKeyComparator public: MultipleFieldsMapKeyComparator( MessageDifferencer* message_differencer, - const vector >& key_field_paths) + const std::vector >& key_field_paths) : message_differencer_(message_differencer), key_field_paths_(key_field_paths) { GOOGLE_CHECK(!key_field_paths_.empty()); @@ -85,14 +85,14 @@ class MessageDifferencer::MultipleFieldsMapKeyComparator MessageDifferencer* message_differencer, const FieldDescriptor* key) : message_differencer_(message_differencer) { - vector key_field_path; + std::vector key_field_path; key_field_path.push_back(key); key_field_paths_.push_back(key_field_path); } virtual bool IsMatch( const Message& message1, const Message& message2, - const vector& parent_fields) const { + const std::vector& parent_fields) const { for (int i = 0; i < key_field_paths_.size(); ++i) { if (!IsMatchInternal(message1, message2, parent_fields, key_field_paths_[i], 0)) { @@ -105,11 +105,11 @@ class MessageDifferencer::MultipleFieldsMapKeyComparator bool IsMatchInternal( const Message& message1, const Message& message2, - const vector& parent_fields, - const vector& key_field_path, + const std::vector& parent_fields, + const std::vector& key_field_path, int path_index) const { const FieldDescriptor* field = key_field_path[path_index]; - vector current_parent_fields(parent_fields); + std::vector current_parent_fields(parent_fields); if (path_index == key_field_path.size() - 1) { if (field->is_repeated()) { if (!message_differencer_->CompareRepeatedField( @@ -146,7 +146,7 @@ class MessageDifferencer::MultipleFieldsMapKeyComparator } } MessageDifferencer* message_differencer_; - vector > key_field_paths_; + std::vector > key_field_paths_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MultipleFieldsMapKeyComparator); }; @@ -283,10 +283,10 @@ void MessageDifferencer::TreatAsMap(const FieldDescriptor* field, void MessageDifferencer::TreatAsMapWithMultipleFieldsAsKey( const FieldDescriptor* field, - const vector& key_fields) { - vector > key_field_paths; + const std::vector& key_fields) { + std::vector > key_field_paths; for (int i = 0; i < key_fields.size(); ++i) { - vector key_field_path; + std::vector key_field_path; key_field_path.push_back(key_fields[i]); key_field_paths.push_back(key_field_path); } @@ -295,14 +295,15 @@ void MessageDifferencer::TreatAsMapWithMultipleFieldsAsKey( void MessageDifferencer::TreatAsMapWithMultipleFieldPathsAsKey( const FieldDescriptor* field, - const vector >& key_field_paths) { + const std::vector >& key_field_paths) { GOOGLE_CHECK(field->is_repeated()) << "Field must be repeated: " << field->full_name(); GOOGLE_CHECK_EQ(FieldDescriptor::CPPTYPE_MESSAGE, field->cpp_type()) << "Field has to be message type. Field name is: " << field->full_name(); for (int i = 0; i < key_field_paths.size(); ++i) { - const vector& key_field_path = key_field_paths[i]; + const std::vector& key_field_path = + key_field_paths[i]; for (int j = 0; j < key_field_path.size(); ++j) { const FieldDescriptor* parent_field = j == 0 ? field : key_field_path[j - 1]; @@ -390,7 +391,7 @@ bool MessageDifferencer::FieldBefore(const FieldDescriptor* field1, bool MessageDifferencer::Compare(const Message& message1, const Message& message2) { - vector parent_fields; + std::vector parent_fields; bool result = false; @@ -411,20 +412,20 @@ bool MessageDifferencer::Compare(const Message& message1, bool MessageDifferencer::CompareWithFields( const Message& message1, const Message& message2, - const vector& message1_fields_arg, - const vector& message2_fields_arg) { + const std::vector& message1_fields_arg, + const std::vector& message2_fields_arg) { if (message1.GetDescriptor() != message2.GetDescriptor()) { GOOGLE_LOG(DFATAL) << "Comparison between two messages with different " << "descriptors."; return false; } - vector parent_fields; + std::vector parent_fields; bool result = false; - vector message1_fields(message1_fields_arg); - vector message2_fields(message2_fields_arg); + std::vector message1_fields(message1_fields_arg); + std::vector message2_fields(message2_fields_arg); std::sort(message1_fields.begin(), message1_fields.end(), FieldBefore); std::sort(message2_fields.begin(), message2_fields.end(), FieldBefore); @@ -451,7 +452,7 @@ bool MessageDifferencer::CompareWithFields( bool MessageDifferencer::Compare( const Message& message1, const Message& message2, - vector* parent_fields) { + std::vector* parent_fields) { const Descriptor* descriptor1 = message1.GetDescriptor(); const Descriptor* descriptor2 = message2.GetDescriptor(); if (descriptor1 != descriptor2) { @@ -473,10 +474,10 @@ bool MessageDifferencer::Compare( const Reflection* reflection2 = message2.GetReflection(); // Retrieve all the set fields, including extensions. - vector message1_fields; + std::vector message1_fields; message1_fields.reserve(1 + message1.GetDescriptor()->field_count()); - vector message2_fields; + std::vector message2_fields; message2_fields.reserve(1 + message2.GetDescriptor()->field_count()); reflection1->ListFields(message1, &message1_fields); @@ -514,15 +515,15 @@ bool MessageDifferencer::Compare( bool MessageDifferencer::CompareRequestedFieldsUsingSettings( const Message& message1, const Message& message2, - const vector& message1_fields, - const vector& message2_fields, - vector* parent_fields) { + const std::vector& message1_fields, + const std::vector& message2_fields, + std::vector* parent_fields) { if (scope_ == FULL) { if (message_field_comparison_ == EQUIVALENT) { // We need to merge the field lists of both messages (i.e. // we are merely checking for a difference in field values, // rather than the addition or deletion of fields). - vector fields_union; + std::vector fields_union; CombineFields(message1_fields, FULL, message2_fields, FULL, &fields_union); return CompareWithFieldsInternal(message1, message2, fields_union, @@ -544,7 +545,7 @@ bool MessageDifferencer::CompareRequestedFieldsUsingSettings( // but only the intersection for message2. This way, any fields // only present in message2 will be ignored, but any fields only // present in message1 will be marked as a difference. - vector fields_intersection; + std::vector fields_intersection; CombineFields(message1_fields, PARTIAL, message2_fields, PARTIAL, &fields_intersection); return CompareWithFieldsInternal(message1, message2, message1_fields, @@ -554,11 +555,11 @@ bool MessageDifferencer::CompareRequestedFieldsUsingSettings( } void MessageDifferencer::CombineFields( - const vector& fields1, + const std::vector& fields1, Scope fields1_scope, - const vector& fields2, + const std::vector& fields2, Scope fields2_scope, - vector* combined_fields) { + std::vector* combined_fields) { int index1 = 0; int index2 = 0; @@ -588,9 +589,9 @@ void MessageDifferencer::CombineFields( bool MessageDifferencer::CompareWithFieldsInternal( const Message& message1, const Message& message2, - const vector& message1_fields, - const vector& message2_fields, - vector* parent_fields) { + const std::vector& message1_fields, + const std::vector& message2_fields, + std::vector* parent_fields) { bool isDifferent = false; int field_index1 = 0; int field_index2 = 0; @@ -746,13 +747,12 @@ bool MessageDifferencer::CompareWithFieldsInternal( return !isDifferent; } -bool MessageDifferencer::IsMatch(const FieldDescriptor* repeated_field, - const MapKeyComparator* key_comparator, - const Message* message1, - const Message* message2, - const vector& parent_fields, - int index1, int index2) { - vector current_parent_fields(parent_fields); +bool MessageDifferencer::IsMatch( + const FieldDescriptor* repeated_field, + const MapKeyComparator* key_comparator, const Message* message1, + const Message* message2, const std::vector& parent_fields, + int index1, int index2) { + std::vector current_parent_fields(parent_fields); if (repeated_field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { return CompareFieldValueUsingParentFields( *message1, *message2, repeated_field, index1, index2, @@ -792,7 +792,7 @@ bool MessageDifferencer::CompareRepeatedField( const Message& message1, const Message& message2, const FieldDescriptor* repeated_field, - vector* parent_fields) { + std::vector* parent_fields) { // the input FieldDescriptor is guaranteed to be repeated field. const Reflection* reflection1 = message1.GetReflection(); const Reflection* reflection2 = message2.GetReflection(); @@ -813,8 +813,8 @@ bool MessageDifferencer::CompareRepeatedField( // These two list are used for store the index of the correspondent // element in peer repeated field. - vector match_list1; - vector match_list2; + std::vector match_list1; + std::vector match_list2; // Try to match indices of the repeated fields. Return false if match fails // and there's no detailed report needed. @@ -899,7 +899,7 @@ bool MessageDifferencer::CompareFieldValue(const Message& message1, bool MessageDifferencer::CompareFieldValueUsingParentFields( const Message& message1, const Message& message2, const FieldDescriptor* field, int index1, int index2, - vector* parent_fields) { + std::vector* parent_fields) { FieldContext field_context(parent_fields); FieldComparator::ComparisonResult result = GetFieldComparisonResult( message1, message2, field, index1, index2, &field_context); @@ -938,7 +938,7 @@ bool MessageDifferencer::CompareFieldValueUsingParentFields( } bool MessageDifferencer::CheckPathChanged( - const vector& field_path) { + const std::vector& field_path) { for (int i = 0; i < field_path.size(); ++i) { if (field_path[i].index != field_path[i].new_index) return true; } @@ -962,7 +962,7 @@ bool MessageDifferencer::IsIgnored( const Message& message1, const Message& message2, const FieldDescriptor* field, - const vector& parent_fields) { + const std::vector& parent_fields) { if (ignored_fields_.find(field) != ignored_fields_.end()) { return true; } @@ -977,7 +977,8 @@ bool MessageDifferencer::IsIgnored( bool MessageDifferencer::IsUnknownFieldIgnored( const Message& message1, const Message& message2, - const SpecificField& field, const vector& parent_fields) { + const SpecificField& field, + const std::vector& parent_fields) { for (int i = 0; i < ignore_criteria_.size(); ++i) { if (ignore_criteria_[i]->IsUnknownFieldIgnored(message1, message2, field, parent_fields)) { @@ -999,7 +1000,7 @@ const MessageDifferencer::MapKeyComparator* MessageDifferencer namespace { -typedef pair IndexUnknownFieldPair; +typedef std::pair IndexUnknownFieldPair; struct UnknownFieldOrdering { inline bool operator()(const IndexUnknownFieldPair& a, @@ -1050,7 +1051,7 @@ bool MessageDifferencer::CompareUnknownFields( const Message& message1, const Message& message2, const google::protobuf::UnknownFieldSet& unknown_field_set1, const google::protobuf::UnknownFieldSet& unknown_field_set2, - vector* parent_field) { + std::vector* parent_field) { // Ignore unknown fields in EQUIVALENT mode. if (message_field_comparison_ == EQUIVALENT) return true; @@ -1066,8 +1067,8 @@ bool MessageDifferencer::CompareUnknownFields( // two sets -- that is, differing values for the same tag. We use // IndexUnknownFieldPairs to keep track of the field's original index for // reporting purposes. - vector fields1; // unknown_field_set1, sorted - vector fields2; // unknown_field_set2, sorted + std::vector fields1; // unknown_field_set1, sorted + std::vector fields2; // unknown_field_set2, sorted fields1.reserve(unknown_field_set1.field_count()); fields2.reserve(unknown_field_set2.field_count()); @@ -1270,7 +1271,7 @@ class MaximumMatcher { // the x-th node on the right side is matched to y-th node on the left side. // match_list1[i] == -1 means the node is not matched. Same with match_list2. MaximumMatcher(int count1, int count2, NodeMatchCallback* callback, - vector* match_list1, vector* match_list2); + std::vector* match_list1, std::vector* match_list2); // Find a maximum match and return the number of matched node pairs. // If early_return is true, this method will return 0 immediately when it // finds that not all nodes on the left side can be matched. @@ -1282,21 +1283,21 @@ class MaximumMatcher { // Find an argumenting path starting from the node v on the left side. If a // path can be found, update match_list2_ to reflect the path and return // true. - bool FindArgumentPathDFS(int v, vector* visited); + bool FindArgumentPathDFS(int v, std::vector* visited); int count1_; int count2_; google::protobuf::scoped_ptr match_callback_; - map, bool> cached_match_results_; - vector* match_list1_; - vector* match_list2_; + std::map, bool> cached_match_results_; + std::vector* match_list1_; + std::vector* match_list2_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MaximumMatcher); }; MaximumMatcher::MaximumMatcher(int count1, int count2, NodeMatchCallback* callback, - vector* match_list1, - vector* match_list2) + std::vector* match_list1, + std::vector* match_list2) : count1_(count1), count2_(count2), match_callback_(callback), match_list1_(match_list1), match_list2_(match_list2) { match_list1_->assign(count1, -1); @@ -1306,7 +1307,7 @@ MaximumMatcher::MaximumMatcher(int count1, int count2, int MaximumMatcher::FindMaximumMatch(bool early_return) { int result = 0; for (int i = 0; i < count1_; ++i) { - vector visited(count1_); + std::vector visited(count1_); if (FindArgumentPathDFS(i, &visited)) { ++result; } else if (early_return) { @@ -1324,8 +1325,9 @@ int MaximumMatcher::FindMaximumMatch(bool early_return) { } bool MaximumMatcher::Match(int left, int right) { - pair p(left, right); - map, bool>::iterator it = cached_match_results_.find(p); + std::pair p(left, right); + std::map, bool>::iterator it = + cached_match_results_.find(p); if (it != cached_match_results_.end()) { return it->second; } @@ -1333,7 +1335,7 @@ bool MaximumMatcher::Match(int left, int right) { return cached_match_results_[p]; } -bool MaximumMatcher::FindArgumentPathDFS(int v, vector* visited) { +bool MaximumMatcher::FindArgumentPathDFS(int v, std::vector* visited) { (*visited)[v] = true; // We try to match those un-matched nodes on the right side first. This is // the step that the navie greedy matching algorithm uses. In the best cases @@ -1369,9 +1371,9 @@ bool MessageDifferencer::MatchRepeatedFieldIndices( const Message& message1, const Message& message2, const FieldDescriptor* repeated_field, - const vector& parent_fields, - vector* match_list1, - vector* match_list2) { + const std::vector& parent_fields, + std::vector* match_list1, + std::vector* match_list2) { const int count1 = message1.GetReflection()->FieldSize(message1, repeated_field); const int count2 = @@ -1392,7 +1394,8 @@ bool MessageDifferencer::MatchRepeatedFieldIndices( // doesn't necessarily imply Compare(b, c). Therefore a naive greedy // algorithm will fail to find a maximum matching. // Here we use the argumenting path algorithm. - MaximumMatcher::NodeMatchCallback* callback = NewPermanentCallback( + MaximumMatcher::NodeMatchCallback* callback = + NewPermanentCallback( this, &MessageDifferencer::IsMatch, repeated_field, key_comparator, &message1, &message2, parent_fields); @@ -1485,7 +1488,7 @@ MessageDifferencer::StreamReporter::~StreamReporter() { } void MessageDifferencer::StreamReporter::PrintPath( - const vector& field_path, bool left_side) { + const std::vector& field_path, bool left_side) { for (int i = 0; i < field_path.size(); ++i) { if (i > 0) { printer_->Print("."); @@ -1514,7 +1517,7 @@ void MessageDifferencer::StreamReporter::PrintPath( void MessageDifferencer:: StreamReporter::PrintValue(const Message& message, - const vector& field_path, + const std::vector& field_path, bool left_side) { const SpecificField& specific_field = field_path.back(); const FieldDescriptor* field = specific_field.field; @@ -1587,7 +1590,7 @@ void MessageDifferencer::StreamReporter::Print(const string& str) { void MessageDifferencer::StreamReporter::ReportAdded( const Message& message1, const Message& message2, - const vector& field_path) { + const std::vector& field_path) { printer_->Print("added: "); PrintPath(field_path, false); printer_->Print(": "); @@ -1598,7 +1601,7 @@ void MessageDifferencer::StreamReporter::ReportAdded( void MessageDifferencer::StreamReporter::ReportDeleted( const Message& message1, const Message& message2, - const vector& field_path) { + const std::vector& field_path) { printer_->Print("deleted: "); PrintPath(field_path, true); printer_->Print(": "); @@ -1609,7 +1612,7 @@ void MessageDifferencer::StreamReporter::ReportDeleted( void MessageDifferencer::StreamReporter::ReportModified( const Message& message1, const Message& message2, - const vector& field_path) { + const std::vector& field_path) { if (!report_modified_aggregates_ && field_path.back().field == NULL) { if (field_path.back().unknown_field_type == UnknownField::TYPE_GROUP) { // Any changes to the subfields have already been printed. @@ -1639,7 +1642,7 @@ void MessageDifferencer::StreamReporter::ReportModified( void MessageDifferencer::StreamReporter::ReportMoved( const Message& message1, const Message& message2, - const vector& field_path) { + const std::vector& field_path) { printer_->Print("moved: "); PrintPath(field_path, true); printer_->Print(" -> "); @@ -1652,7 +1655,7 @@ void MessageDifferencer::StreamReporter::ReportMoved( void MessageDifferencer::StreamReporter::ReportMatched( const Message& message1, const Message& message2, - const vector& field_path) { + const std::vector& field_path) { printer_->Print("matched: "); PrintPath(field_path, true); if (CheckPathChanged(field_path)) { @@ -1667,7 +1670,7 @@ void MessageDifferencer::StreamReporter::ReportMatched( void MessageDifferencer::StreamReporter::ReportIgnored( const Message& message1, const Message& message2, - const vector& field_path) { + const std::vector& field_path) { printer_->Print("ignored: "); PrintPath(field_path, true); if (CheckPathChanged(field_path)) { @@ -1679,7 +1682,7 @@ void MessageDifferencer::StreamReporter::ReportIgnored( void MessageDifferencer::StreamReporter::ReportUnknownFieldIgnored( const Message& message1, const Message& message2, - const vector& field_path) { + const std::vector& field_path) { printer_->Print("ignored: "); PrintPath(field_path, true); if (CheckPathChanged(field_path)) { diff --git a/src/google/protobuf/util/message_differencer.h b/src/google/protobuf/util/message_differencer.h index fde37cf9..d99223cb 100644 --- a/src/google/protobuf/util/message_differencer.h +++ b/src/google/protobuf/util/message_differencer.h @@ -821,7 +821,6 @@ class LIBPROTOBUF_EXPORT MessageDifferencer { FieldSet ignored_fields_; - bool compare_unknown_fields_; bool report_matches_; string* output_string_; diff --git a/src/google/protobuf/util/message_differencer_unittest.cc b/src/google/protobuf/util/message_differencer_unittest.cc index ed43c512..30b27dba 100755 --- a/src/google/protobuf/util/message_differencer_unittest.cc +++ b/src/google/protobuf/util/message_differencer_unittest.cc @@ -66,7 +66,7 @@ namespace { const FieldDescriptor* GetFieldDescriptor( const Message& message, const string& field_name) { - vector field_path = + std::vector field_path = Split(field_name, ".", true); const Descriptor* descriptor = message.GetDescriptor(); const FieldDescriptor* field = NULL; @@ -790,8 +790,8 @@ TEST(MessageDifferencerTest, SpecifiedFieldsEqualityAllTest) { TestUtil::SetAllFields(&msg1); TestUtil::SetAllFields(&msg2); - vector fields1; - vector fields2; + std::vector fields1; + std::vector fields2; msg1.GetReflection()->ListFields(msg1, &fields1); msg2.GetReflection()->ListFields(msg2, &fields2); @@ -805,8 +805,8 @@ TEST(MessageDifferencerTest, SpecifiedFieldsInequalityAllTest) { TestUtil::SetAllFields(&msg1); - vector fields1; - vector fields2; + std::vector fields1; + std::vector fields2; msg1.GetReflection()->ListFields(msg1, &fields1); msg2.GetReflection()->ListFields(msg2, &fields2); @@ -820,7 +820,7 @@ TEST(MessageDifferencerTest, SpecifiedFieldsEmptyListAlwaysSucceeds) { TestUtil::SetAllFields(&msg1); - vector empty_fields; + std::vector empty_fields; util::MessageDifferencer differencer; EXPECT_TRUE(differencer.CompareWithFields(msg1, msg2, @@ -835,7 +835,7 @@ TEST(MessageDifferencerTest, SpecifiedFieldsCompareWithSelf) { unittest::TestAllTypes msg1; TestUtil::SetAllFields(&msg1); - vector fields; + std::vector fields; msg1.GetReflection()->ListFields(msg1, &fields); util::MessageDifferencer differencer; @@ -843,7 +843,7 @@ TEST(MessageDifferencerTest, SpecifiedFieldsCompareWithSelf) { { // Compare with a subset of fields. - vector compare_fields; + std::vector compare_fields; for (int i = 0; i < fields.size(); ++i) { if (i % 2 == 0) { compare_fields.push_back(fields[i]); @@ -856,8 +856,8 @@ TEST(MessageDifferencerTest, SpecifiedFieldsCompareWithSelf) { // Specify a different set of fields to compare, even though we're using the // same message. This should fail, since we are explicitly saying that the // set of fields are different. - vector compare_fields1; - vector compare_fields2; + std::vector compare_fields1; + std::vector compare_fields2; for (int i = 0; i < fields.size(); ++i) { if (i % 2 == 0) { compare_fields1.push_back(fields[i]); @@ -880,8 +880,8 @@ TEST(MessageDifferencerTest, SpecifiedFieldsEqualityAllShuffledTest) { TestUtil::SetAllFields(&msg1); TestUtil::SetAllFields(&msg2); - vector fields1; - vector fields2; + std::vector fields1; + std::vector fields2; msg1.GetReflection()->ListFields(msg1, &fields1); msg2.GetReflection()->ListFields(msg2, &fields2); @@ -899,10 +899,10 @@ TEST(MessageDifferencerTest, SpecifiedFieldsSubsetEqualityTest) { TestUtil::SetAllFields(&msg1); TestUtil::SetAllFields(&msg2); - vector fields1; + std::vector fields1; msg1.GetReflection()->ListFields(msg1, &fields1); - vector compare_fields; + std::vector compare_fields; // Only compare the field descriptors with even indices. for (int i = 0; i < fields1.size(); ++i) { if (i % 2 == 0) { @@ -925,11 +925,11 @@ TEST(MessageDifferencerTest, TestUtil::SetAllFields(&msg1); TestUtil::SetAllFields(&msg2); - vector fields1; + std::vector fields1; const Reflection* reflection = msg1.GetReflection(); reflection->ListFields(msg1, &fields1); - vector compare_fields; + std::vector compare_fields; // Only compare the field descriptors with even indices. for (int i = 0; i < fields1.size(); ++i) { if (i % 2 == 0) { @@ -954,10 +954,10 @@ TEST(MessageDifferencerTest, SpecifiedFieldsDetectsDifferencesTest) { TestUtil::SetAllFields(&msg2); TestUtil::ModifyRepeatedFields(&msg2); - vector fields1; + std::vector fields1; msg1.GetReflection()->ListFields(msg1, &fields1); - vector compare_fields; + std::vector compare_fields; // Only compare the repeated field descriptors. for (int i = 0; i < fields1.size(); ++i) { if (fields1[i]->is_repeated()) { @@ -977,8 +977,8 @@ TEST(MessageDifferencerTest, SpecifiedFieldsEquivalenceAllTest) { TestUtil::SetAllFields(&msg1); TestUtil::SetAllFields(&msg2); - vector fields1; - vector fields2; + std::vector fields1; + std::vector fields2; msg1.GetReflection()->ListFields(msg1, &fields1); msg2.GetReflection()->ListFields(msg2, &fields2); @@ -1011,8 +1011,8 @@ TEST(MessageDifferencerTest, // actually doing something. msg2.set_optional_uint64(23); - vector fields1; - vector fields2; + std::vector fields1; + std::vector fields2; fields1.push_back(optional_int32_desc); fields1.push_back(default_int64_desc); @@ -1286,7 +1286,7 @@ TEST(MessageDifferencerTest, RepeatedFieldMapTest_MultipleFieldsAsKey) { util::MessageDifferencer differencer; differencer.TreatAsSet(GetFieldDescriptor(msg1, "item.ra")); EXPECT_FALSE(differencer.Compare(msg1, msg2)); - vector key_fields; + std::vector key_fields; key_fields.push_back(GetFieldDescriptor(msg1, "item.a")); key_fields.push_back(GetFieldDescriptor(msg1, "item.ra")); differencer.TreatAsMapWithMultipleFieldsAsKey( @@ -1363,11 +1363,11 @@ TEST(MessageDifferencerTest, RepeatedFieldMapTest_MultipleFieldPathsAsKey) { util::MessageDifferencer differencer; differencer.TreatAsSet(GetFieldDescriptor(msg1, "item.m.rc")); EXPECT_FALSE(differencer.Compare(msg1, msg2)); - vector > key_field_paths; - vector key_field_path1; + std::vector > key_field_paths; + std::vector key_field_path1; key_field_path1.push_back(GetFieldDescriptor(msg1, "item.m")); key_field_path1.push_back(GetFieldDescriptor(msg1, "item.m.a")); - vector key_field_path2; + std::vector key_field_path2; key_field_path2.push_back(GetFieldDescriptor(msg1, "item.m")); key_field_path2.push_back(GetFieldDescriptor(msg1, "item.m.rc")); key_field_paths.push_back(key_field_path1); @@ -1413,7 +1413,7 @@ TEST(MessageDifferencerTest, RepeatedFieldMapTest_IgnoredKeyFields) { item->set_b("world"); // Compare util::MessageDifferencer differencer; - vector key_fields; + std::vector key_fields; key_fields.push_back(GetFieldDescriptor(msg1, "item.a")); key_fields.push_back(GetFieldDescriptor(msg1, "item.ra")); differencer.TreatAsMapWithMultipleFieldsAsKey( @@ -1457,7 +1457,8 @@ class TestIgnorer : public util::MessageDifferencer::IgnoreCriteria { virtual bool IsIgnored( const Message& message1, const Message& message2, const FieldDescriptor* field, - const vector& parent_fields) { + const std::vector& + parent_fields) { string name = ""; for (int i = 0; i < parent_fields.size(); ++i) { name += parent_fields[i].field->name() + "."; @@ -1502,7 +1503,7 @@ class ValueProductMapKeyComparator typedef util::MessageDifferencer::SpecificField SpecificField; virtual bool IsMatch( const Message &message1, const Message &message2, - const vector& parent_fields) const { + const std::vector& parent_fields) const { const Reflection* reflection1 = message1.GetReflection(); const Reflection* reflection2 = message2.GetReflection(); // FieldDescriptor for item.ra @@ -1863,7 +1864,7 @@ TEST(MessageDifferencerTest, IgnoreField_TrumpsCompareWithFields) { const FieldDescriptor* c = GetFieldDescriptor(msg1, "c"); const FieldDescriptor* rc = GetFieldDescriptor(msg1, "rc"); - vector fields; + std::vector fields; fields.push_back(c); fields.push_back(rc); @@ -1899,12 +1900,12 @@ class ParentSavingFieldComparator : public util::FieldComparator { } } - vector parent_fields() { + std::vector parent_fields() { return parent_fields_; } private: - vector parent_fields_; + std::vector parent_fields_; }; // Tests if MessageDifferencer sends the parent fields in the FieldContext diff --git a/src/google/protobuf/util/type_resolver_util.cc b/src/google/protobuf/util/type_resolver_util.cc index 96393903..febaa41f 100644 --- a/src/google/protobuf/util/type_resolver_util.cc +++ b/src/google/protobuf/util/type_resolver_util.cc @@ -54,17 +54,6 @@ using util::Status; using util::error::INVALID_ARGUMENT; using util::error::NOT_FOUND; -bool SplitTypeUrl(const string& type_url, string* url_prefix, - string* message_name) { - size_t pos = type_url.find_last_of("/"); - if (pos == string::npos) { - return false; - } - *url_prefix = type_url.substr(0, pos); - *message_name = type_url.substr(pos + 1); - return true; -} - class DescriptorPoolTypeResolver : public TypeResolver { public: DescriptorPoolTypeResolver(const string& url_prefix, @@ -72,38 +61,27 @@ class DescriptorPoolTypeResolver : public TypeResolver { : url_prefix_(url_prefix), pool_(pool) {} Status ResolveMessageType(const string& type_url, Type* type) { - string url_prefix, message_name; - if (!SplitTypeUrl(type_url, &url_prefix, &message_name) || - url_prefix != url_prefix_) { - return Status(INVALID_ARGUMENT, - StrCat("Invalid type URL, type URLs must be of the form '", - url_prefix_, "/', got: ", type_url)); + string type_name; + Status status = ParseTypeUrl(type_url, &type_name); + if (!status.ok()) { + return status; } - if (url_prefix != url_prefix_) { - return Status(INVALID_ARGUMENT, - "Cannot resolve types from URL: " + url_prefix); - } - const Descriptor* descriptor = pool_->FindMessageTypeByName(message_name); + + const Descriptor* descriptor = pool_->FindMessageTypeByName(type_name); if (descriptor == NULL) { - return Status(NOT_FOUND, - "Invalid type URL, unknown type: " + message_name); + return Status(NOT_FOUND, "Invalid type URL, unknown type: " + type_name); } ConvertDescriptor(descriptor, type); return Status(); } Status ResolveEnumType(const string& type_url, Enum* enum_type) { - string url_prefix, type_name; - if (!SplitTypeUrl(type_url, &url_prefix, &type_name) || - url_prefix != url_prefix_) { - return Status(INVALID_ARGUMENT, - StrCat("Invalid type URL, type URLs must be of the form '", - url_prefix_, "/', got: ", type_url)); - } - if (url_prefix != url_prefix_) { - return Status(INVALID_ARGUMENT, - "Cannot resolve types from URL: " + url_prefix); + string type_name; + Status status = ParseTypeUrl(type_url, &type_name); + if (!status.ok()) { + return status; } + const EnumDescriptor* descriptor = pool_->FindEnumTypeByName(type_name); if (descriptor == NULL) { return Status(NOT_FOUND, "Invalid type URL, unknown type: " + type_name); @@ -203,6 +181,16 @@ class DescriptorPoolTypeResolver : public TypeResolver { return url_prefix_ + "/" + descriptor->full_name(); } + Status ParseTypeUrl(const string& type_url, string* type_name) { + if (type_url.substr(0, url_prefix_.size() + 1) != url_prefix_ + "/") { + return Status(INVALID_ARGUMENT, + StrCat("Invalid type URL, type URLs must be of the form '", + url_prefix_, "/', got: ", type_url)); + } + *type_name = type_url.substr(url_prefix_.size() + 1); + return Status(); + } + string DefaultValueAsString(const FieldDescriptor* descriptor) { switch (descriptor->cpp_type()) { case FieldDescriptor::CPPTYPE_INT32: -- cgit v1.2.3