aboutsummaryrefslogtreecommitdiff
path: root/src/google/protobuf/util/message_differencer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/google/protobuf/util/message_differencer.cc')
-rw-r--r--src/google/protobuf/util/message_differencer.cc67
1 files changed, 41 insertions, 26 deletions
diff --git a/src/google/protobuf/util/message_differencer.cc b/src/google/protobuf/util/message_differencer.cc
index 9842f64c..8a09400b 100644
--- a/src/google/protobuf/util/message_differencer.cc
+++ b/src/google/protobuf/util/message_differencer.cc
@@ -31,10 +31,6 @@
// Author: jschorr@google.com (Joseph Schorr)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
-//
-// This file defines static methods and classes for comparing Protocol
-// Messages (see //google/protobuf/util/message_differencer.h for more
-// information).
#include <google/protobuf/util/message_differencer.h>
@@ -56,6 +52,7 @@
#include <google/protobuf/util/field_comparator.h>
#include <google/protobuf/stubs/strutil.h>
+
namespace google {
namespace protobuf {
@@ -87,10 +84,8 @@ class MessageDifferencer::MultipleFieldsMapKeyComparator
key_field_path.push_back(key);
key_field_paths_.push_back(key_field_path);
}
- virtual bool IsMatch(
- const Message& message1,
- const Message& message2,
- const std::vector<SpecificField>& parent_fields) const {
+ bool IsMatch(const Message& message1, const Message& message2,
+ const std::vector<SpecificField>& parent_fields) const override {
for (int i = 0; i < key_field_paths_.size(); ++i) {
if (!IsMatchInternal(message1, message2, parent_fields,
key_field_paths_[i], 0)) {
@@ -99,6 +94,7 @@ class MessageDifferencer::MultipleFieldsMapKeyComparator
}
return true;
}
+
private:
bool IsMatchInternal(
const Message& message1,
@@ -218,6 +214,7 @@ MessageDifferencer::MessageDifferencer()
map_entry_key_comparator_(this),
report_matches_(false),
report_moves_(true),
+ report_ignores_(true),
output_string_(NULL) {}
MessageDifferencer::~MessageDifferencer() {
@@ -533,9 +530,9 @@ bool MessageDifferencer::Compare(
bool unknown_compare_result = true;
// Ignore unknown fields in EQUIVALENT mode
if (message_field_comparison_ != EQUIVALENT) {
- const google::protobuf::UnknownFieldSet* unknown_field_set1 =
+ const UnknownFieldSet* unknown_field_set1 =
&reflection1->GetUnknownFields(message1);
- const google::protobuf::UnknownFieldSet* unknown_field_set2 =
+ const UnknownFieldSet* unknown_field_set2 =
&reflection2->GetUnknownFields(message2);
if (!CompareUnknownFields(message1, message2,
*unknown_field_set1, *unknown_field_set2,
@@ -660,7 +657,9 @@ bool MessageDifferencer::CompareWithFieldsInternal(
specific_field.field = field1;
parent_fields->push_back(specific_field);
- reporter_->ReportIgnored(message1, message2, *parent_fields);
+ if (report_ignores_) {
+ reporter_->ReportIgnored(message1, message2, *parent_fields);
+ }
parent_fields->pop_back();
}
++field_index1;
@@ -699,7 +698,9 @@ bool MessageDifferencer::CompareWithFieldsInternal(
specific_field.field = field2;
parent_fields->push_back(specific_field);
- reporter_->ReportIgnored(message1, message2, *parent_fields);
+ if (report_ignores_) {
+ reporter_->ReportIgnored(message1, message2, *parent_fields);
+ }
parent_fields->pop_back();
}
++field_index2;
@@ -739,7 +740,9 @@ bool MessageDifferencer::CompareWithFieldsInternal(
specific_field.field = field1;
parent_fields->push_back(specific_field);
- reporter_->ReportIgnored(message1, message2, *parent_fields);
+ if (report_ignores_) {
+ reporter_->ReportIgnored(message1, message2, *parent_fields);
+ }
parent_fields->pop_back();
}
@@ -1078,7 +1081,7 @@ bool MessageDifferencer::UnpackAny(const Message& any,
return false;
}
- const google::protobuf::Descriptor* desc =
+ const Descriptor* desc =
any.GetDescriptor()->file()->pool()->FindMessageTypeByName(
full_type_name);
if (desc == NULL) {
@@ -1100,8 +1103,8 @@ bool MessageDifferencer::UnpackAny(const Message& any,
bool MessageDifferencer::CompareUnknownFields(
const Message& message1, const Message& message2,
- const google::protobuf::UnknownFieldSet& unknown_field_set1,
- const google::protobuf::UnknownFieldSet& unknown_field_set2,
+ const UnknownFieldSet& unknown_field_set1,
+ const UnknownFieldSet& unknown_field_set2,
std::vector<SpecificField>* parent_field) {
// Ignore unknown fields in EQUIVALENT mode.
if (message_field_comparison_ == EQUIVALENT) return true;
@@ -1434,6 +1437,13 @@ bool MessageDifferencer::MatchRepeatedFieldIndices(
match_list1->assign(count1, -1);
match_list2->assign(count2, -1);
+ // Ensure that we don't report differences during the matching process. Since
+ // field comparators could potentially use this message differencer object to
+ // perform further comparisons, turn off reporting here and re-enable it
+ // before returning.
+ Reporter* reporter = reporter_;
+ reporter_ = NULL;
+
bool success = true;
// Find potential match if this is a special repeated field.
if (key_comparator != NULL || IsTreatedAsSet(repeated_field)) {
@@ -1451,9 +1461,9 @@ bool MessageDifferencer::MatchRepeatedFieldIndices(
match_list2);
// If diff info is not needed, we should end the matching process as
// soon as possible if not all items can be matched.
- bool early_return = (reporter_ == NULL);
+ bool early_return = (reporter == NULL);
int match_count = matcher.FindMaximumMatch(early_return);
- if (match_count != count1 && reporter_ == NULL) return false;
+ if (match_count != count1 && reporter == NULL) return false;
success = success && (match_count == count1);
} else {
int start_offset = 0;
@@ -1488,7 +1498,7 @@ bool MessageDifferencer::MatchRepeatedFieldIndices(
break;
}
}
- if (!match && reporter_ == NULL) return false;
+ if (!match && reporter == NULL) return false;
success = success && match;
}
}
@@ -1500,6 +1510,8 @@ bool MessageDifferencer::MatchRepeatedFieldIndices(
}
}
+ reporter_ = reporter;
+
return success;
}
@@ -1567,13 +1579,16 @@ void MessageDifferencer::StreamReporter::PrintPath(
continue;
}
} else {
- printer_->PrintRaw(SimpleItoa(specific_field.unknown_field_number));
+ printer_->PrintRaw(
+ SimpleItoa(specific_field.unknown_field_number));
}
if (left_side && specific_field.index >= 0) {
- printer_->Print("[$name$]", "name", SimpleItoa(specific_field.index));
+ printer_->Print("[$name$]", "name",
+ SimpleItoa(specific_field.index));
}
if (!left_side && specific_field.new_index >= 0) {
- printer_->Print("[$name$]", "name", SimpleItoa(specific_field.new_index));
+ printer_->Print("[$name$]", "name",
+ SimpleItoa(specific_field.new_index));
}
}
}
@@ -1631,12 +1646,12 @@ StreamReporter::PrintUnknownFieldValue(const UnknownField* unknown_field) {
output = SimpleItoa(unknown_field->varint());
break;
case UnknownField::TYPE_FIXED32:
- output = StrCat("0x", strings::Hex(unknown_field->fixed32(),
- strings::ZERO_PAD_8));
+ output = StrCat(
+ "0x", strings::Hex(unknown_field->fixed32(), strings::ZERO_PAD_8));
break;
case UnknownField::TYPE_FIXED64:
- output = StrCat("0x", strings::Hex(unknown_field->fixed64(),
- strings::ZERO_PAD_16));
+ output = StrCat(
+ "0x", strings::Hex(unknown_field->fixed64(), strings::ZERO_PAD_16));
break;
case UnknownField::TYPE_LENGTH_DELIMITED:
output = StringPrintf("\"%s\"",