57 #include <google/protobuf/port_def.inc>
77 const std::vector<google::protobuf::util::MessageDifferencer::SpecificField>&
78 field_path)
override {
85 const std::vector<google::protobuf::util::MessageDifferencer::SpecificField>&
86 field_path)
override {
93 const std::vector<google::protobuf::util::MessageDifferencer::SpecificField>&
94 field_path)
override {
112 const std::vector<std::vector<const FieldDescriptor*> >& key_field_paths)
123 std::vector<const FieldDescriptor*> key_field_path;
124 key_field_path.push_back(
key);
128 const std::vector<SpecificField>& parent_fields)
const override {
141 const std::vector<SpecificField>& parent_fields,
142 const std::vector<const FieldDescriptor*>& key_field_path,
143 int path_index)
const {
145 std::vector<SpecificField> current_parent_fields(parent_fields);
146 if (path_index == key_field_path.size() - 1) {
147 if (
field->is_repeated()) {
149 message1, message2,
field, ¤t_parent_fields)) {
154 message1, message2,
field, -1, -1, ¤t_parent_fields)) {
164 if (!has_field1 && !has_field2) {
167 if (has_field1 != has_field2) {
172 current_parent_fields.push_back(specific_field);
175 current_parent_fields, key_field_path,
190 std::vector<int>* match_list1, std::vector<int>* match_list2) {
191 int last_matched_index = -1;
192 for (
int i = 0;
i < match_list1->size(); ++
i) {
193 if (match_list1->at(
i) < 0) {
196 if (last_matched_index < 0 || match_list1->at(
i) > last_matched_index) {
197 last_matched_index = match_list1->at(
i);
199 match_list2->at(match_list1->at(
i)) = -1;
200 match_list1->at(
i) = -1;
207 : message_differencer_(message_differencer) {}
211 const std::vector<SpecificField>& parent_fields)
const {
217 const bool treat_as_set =
218 (message_differencer_->scope() ==
PARTIAL &&
220 message_differencer_->IsIgnored(message1, message2,
key, parent_fields);
222 std::vector<SpecificField> current_parent_fields(parent_fields);
224 return message_differencer_->Compare(message1, message2,
225 ¤t_parent_fields);
227 return message_differencer_->CompareFieldValueUsingParentFields(
228 message1, message2,
key, -1, -1, ¤t_parent_fields);
235 return differencer.
Compare(message1, message2);
243 return differencer.
Compare(message1, message2);
251 return differencer.
Compare(message1, message2);
260 return differencer.
Compare(message1, message2);
289 GOOGLE_CHECK(comparator) <<
"Field comparator can't be NULL.";
317 <<
"Field must be repeated: " <<
field->full_name();
320 <<
"Cannot treat this repeated field as both MAP and " << new_comparison
322 <<
" comparison. Field name is: " <<
field->full_name();
326 <<
"Cannot treat the same field as both "
328 <<
". Field name is: " <<
field->full_name();
342 std::function<
void(std::vector<int>*, std::vector<int>*)> callback) {
359 <<
"Field has to be message type. Field name is: " <<
field->full_name();
362 <<
" must be a direct subfield within the repeated field "
363 <<
field->full_name() <<
", not " <<
key->containing_type()->full_name();
366 <<
"Cannot treat the same field as both "
368 <<
" and MAP. Field name is: " <<
field->full_name();
377 const std::vector<const FieldDescriptor*>& key_fields) {
378 std::vector<std::vector<const FieldDescriptor*> > key_field_paths;
379 for (
int i = 0;
i < key_fields.size(); ++
i) {
380 std::vector<const FieldDescriptor*> key_field_path;
381 key_field_path.push_back(key_fields[
i]);
382 key_field_paths.push_back(key_field_path);
389 const std::vector<std::vector<const FieldDescriptor*> >& key_field_paths) {
391 <<
"Field must be repeated: " <<
field->full_name();
393 <<
"Field has to be message type. Field name is: " <<
field->full_name();
394 for (
int i = 0;
i < key_field_paths.size(); ++
i) {
395 const std::vector<const FieldDescriptor*>& key_field_path =
397 for (
int j = 0; j < key_field_path.size(); ++j) {
399 j == 0 ?
field : key_field_path[j - 1];
403 <<
" must be a direct subfield within the field: "
407 << parent_field->
full_name() <<
" has to be of type message.";
409 << parent_field->
full_name() <<
" cannot be a repeated field.";
415 <<
"Cannot treat the same field as both "
417 <<
" and MAP. Field name is: " <<
field->full_name();
427 <<
"Field must be repeated: " <<
field->full_name();
430 <<
"Cannot treat the same field as both "
432 <<
" and MAP. Field name is: " <<
field->full_name();
445 double fraction,
double margin) {
470 if (field1 ==
NULL) {
474 if (field2 ==
NULL) {
484 std::vector<SpecificField> parent_fields;
493 result =
Compare(message1, message2, &parent_fields);
496 result =
Compare(message1, message2, &parent_fields);
504 const std::vector<const FieldDescriptor*>& message1_fields_arg,
505 const std::vector<const FieldDescriptor*>& message2_fields_arg) {
507 GOOGLE_LOG(DFATAL) <<
"Comparison between two messages with different "
512 std::vector<SpecificField> parent_fields;
519 std::copy(message1_fields_arg.cbegin(), message1_fields_arg.cend(),
520 message1_fields.begin());
521 std::copy(message2_fields_arg.cbegin(), message2_fields_arg.cend(),
522 message2_fields.begin());
525 message1_fields[message1_fields_arg.size()] =
nullptr;
526 message2_fields[message2_fields_arg.size()] =
nullptr;
528 std::sort(message1_fields.begin(), message1_fields.end(),
FieldBefore);
529 std::sort(message2_fields.begin(), message2_fields.end(),
FieldBefore);
537 message1, message2, message1_fields, message2_fields, &parent_fields);
541 message1, message2, message1_fields, message2_fields, &parent_fields);
549 std::vector<SpecificField>* parent_fields) {
552 if (descriptor1 != descriptor2) {
553 GOOGLE_LOG(DFATAL) <<
"Comparison between two messages with different "
554 <<
"descriptors. " << descriptor1->
full_name() <<
" vs "
560 std::unique_ptr<Message> data1;
561 std::unique_ptr<Message> data2;
564 if (data1->GetDescriptor() != data2->GetDescriptor()) {
567 return Compare(*data1, *data2, parent_fields);
573 bool unknown_compare_result =
true;
581 *unknown_field_set2, parent_fields)) {
585 unknown_compare_result =
false;
594 message1_fields, message2_fields,
595 parent_fields) && unknown_compare_result;
626 return message_fields;
633 std::vector<SpecificField>* parent_fields) {
642 fields_union, parent_fields);
646 message2_fields, parent_fields);
654 message1_fields, parent_fields);
663 fields_intersection, parent_fields);
676 while (index1 < fields1.size() && index2 < fields2.size()) {
681 if (fields1_scope ==
FULL) {
686 if (fields2_scope ==
FULL) {
702 return combined_fields;
709 std::vector<SpecificField>* parent_fields) {
710 bool isDifferent =
false;
711 int field_index1 = 0;
712 int field_index2 = 0;
722 if (field1 ==
NULL && field2 ==
NULL) {
729 if (
IsIgnored(message1, message2, field1, *parent_fields)) {
734 specific_field.
field = field1;
736 parent_fields->push_back(specific_field);
740 parent_fields->pop_back();
747 assert(field1 !=
NULL);
749 ? reflection1->
FieldSize(message1, field1)
754 specific_field.
field = field1;
757 parent_fields->push_back(specific_field);
759 parent_fields->pop_back();
771 if (
IsIgnored(message1, message2, field2, *parent_fields)) {
776 specific_field.
field = field2;
778 parent_fields->push_back(specific_field);
782 parent_fields->pop_back();
790 ? reflection2->
FieldSize(message2, field2)
795 specific_field.
field = field2;
799 parent_fields->push_back(specific_field);
801 parent_fields->pop_back();
815 if (
IsIgnored(message1, message2, field1, *parent_fields)) {
819 specific_field.
field = field1;
821 parent_fields->push_back(specific_field);
825 parent_fields->pop_back();
833 bool fieldDifferent =
false;
834 assert(field1 !=
NULL);
838 if (fieldDifferent) {
844 message1, message2, field1, -1, -1, parent_fields);
854 specific_field.
field = field1;
855 parent_fields->push_back(specific_field);
856 if (fieldDifferent) {
862 parent_fields->pop_back();
876 const Message* message2,
const std::vector<SpecificField>& parent_fields,
877 Reporter* reporter,
int index1,
int index2) {
878 std::vector<SpecificField> current_parent_fields(parent_fields);
882 ¤t_parent_fields);
892 if (key_comparator ==
NULL) {
895 ¤t_parent_fields);
905 specific_field.
index = index1;
907 current_parent_fields.push_back(specific_field);
908 match = key_comparator->
IsMatch(m1, m2, current_parent_fields);
919 std::vector<SpecificField>* parent_fields) {
930 if (count1 != count2 &&
reporter_ ==
NULL && !treated_as_subset) {
940 std::vector<int> match_list1;
941 std::vector<int> match_list2;
945 bool simple_list = key_comparator ==
nullptr &&
955 key_comparator, *parent_fields, &match_list1,
962 bool fieldDifferent =
false;
968 int next_unmatched_index = 0;
969 for (
int i = 0;
i < count1;
i++) {
970 if (simple_list &&
i >= count2) {
973 if (!simple_list && match_list1[
i] == -1) {
977 parent_fields->push_back(specific_field);
979 parent_fields->pop_back();
980 fieldDifferent =
true;
987 for (
int j = next_unmatched_index; j < match_list1[
i]; ++j) {
990 specific_field.
index = j;
992 parent_fields->push_back(specific_field);
994 parent_fields->pop_back();
995 fieldDifferent =
true;
1000 specific_field.
index =
i;
1005 next_unmatched_index = match_list1[
i] + 1;
1017 parent_fields->push_back(specific_field);
1019 parent_fields->pop_back();
1020 fieldDifferent =
true;
1024 parent_fields->push_back(specific_field);
1026 parent_fields->pop_back();
1028 parent_fields->push_back(specific_field);
1030 parent_fields->pop_back();
1035 for (
int i = 0;
i < count2; ++
i) {
1036 if (!simple_list && match_list2[
i] != -1)
continue;
1037 if (simple_list &&
i < count1)
continue;
1038 if (!treated_as_subset) {
1039 fieldDifferent =
true;
1043 specific_field.
index =
i;
1045 parent_fields->push_back(specific_field);
1047 parent_fields->pop_back();
1050 for (
int i = 0;
i < count1; ++
i) {
1051 if (!simple_list && match_list1[
i] != -1)
continue;
1052 if (simple_list &&
i < count2)
continue;
1054 specific_field.
index =
i;
1055 parent_fields->push_back(specific_field);
1057 parent_fields->pop_back();
1058 fieldDifferent =
true;
1060 return !fieldDifferent;
1066 int index1,
int index2) {
1074 std::vector<SpecificField>* parent_fields) {
1077 message1, message2,
field, index1, index2, &field_context);
1086 field->is_repeated()
1090 field->is_repeated()
1095 if (parent_fields !=
NULL) {
1099 specific_field.
index = index1;
1101 parent_fields->push_back(specific_field);
1102 const bool compare_result =
Compare(m1, m2, parent_fields);
1103 parent_fields->pop_back();
1104 return compare_result;
1115 const std::vector<SpecificField>& field_path) {
1116 for (
int i = 0;
i < field_path.size(); ++
i) {
1118 if (field_path[
i].
field !=
NULL && field_path[
i].
field->is_map())
continue;
1119 if (field_path[
i].
index != field_path[
i].new_index)
return true;
1125 if (!
field->is_repeated())
return false;
1134 if (!
field->is_repeated())
return false;
1143 if (!
field->is_repeated())
return false;
1159 const std::vector<SpecificField>& parent_fields) {
1175 const std::vector<SpecificField>& parent_fields) {
1188 FieldKeyComparatorMap::const_iterator
it =
1193 if (
field->is_map()) {
1203 typedef std::pair<int, const UnknownField*> IndexUnknownFieldPair;
1205 struct UnknownFieldOrdering {
1206 inline bool operator()(
const IndexUnknownFieldPair&
a,
1207 const IndexUnknownFieldPair&
b)
const {
1208 if (
a.second->number() <
b.second->number())
return true;
1209 if (
a.second->number() >
b.second->number())
return false;
1210 return a.second->type() <
b.second->type();
1217 std::unique_ptr<Message>*
data) {
1243 if (!(*data)->ParseFromString(serialized_value)) {
1254 std::vector<SpecificField>* parent_field) {
1258 if (unknown_field_set1.
empty() && unknown_field_set2.
empty()) {
1262 bool is_different =
false;
1270 std::vector<IndexUnknownFieldPair> fields1;
1271 std::vector<IndexUnknownFieldPair> fields2;
1272 fields1.reserve(unknown_field_set1.
field_count());
1273 fields2.reserve(unknown_field_set2.
field_count());
1276 fields1.push_back(std::make_pair(
i, &unknown_field_set1.
field(
i)));
1279 fields2.push_back(std::make_pair(
i, &unknown_field_set2.
field(
i)));
1282 UnknownFieldOrdering is_before;
1283 std::stable_sort(fields1.begin(), fields1.end(), is_before);
1284 std::stable_sort(fields2.begin(), fields2.end(), is_before);
1292 int current_repeated_start1 = 0;
1293 int current_repeated_start2 = 0;
1299 while (index1 < fields1.size() || index2 < fields2.size()) {
1313 if (index2 == fields2.size() ||
1314 (index1 < fields1.size() &&
1315 is_before(fields1[index1], fields2[index2]))) {
1317 change_type = DELETION;
1318 focus_field = fields1[index1].second;
1319 }
else if (index1 == fields1.size() ||
1320 is_before(fields2[index2], fields1[index1])) {
1327 change_type = ADDITION;
1328 focus_field = fields2[index2].second;
1331 change_type = MODIFICATION;
1332 focus_field = fields1[index1].second;
1334 switch (focus_field->
type()) {
1336 match = fields1[index1].second->varint() ==
1337 fields2[index2].second->varint();
1340 match = fields1[index1].second->fixed32() ==
1341 fields2[index2].second->fixed32();
1344 match = fields1[index1].second->fixed64() ==
1345 fields2[index2].second->fixed64();
1348 match = fields1[index1].second->length_delimited() ==
1349 fields2[index2].second->length_delimited();
1353 change_type = COMPARE_GROUPS;
1356 if (match && change_type != COMPARE_GROUPS) {
1357 change_type = NO_CHANGE;
1361 if (current_repeated ==
NULL ||
1363 focus_field->
type() != current_repeated->
type()) {
1365 current_repeated = focus_field;
1366 current_repeated_start1 = index1;
1367 current_repeated_start2 = index2;
1385 if (change_type != ADDITION) {
1388 if (change_type != DELETION) {
1393 if (change_type == ADDITION) {
1394 specific_field.
index = index2 - current_repeated_start2;
1395 specific_field.
new_index = index2 - current_repeated_start2;
1397 specific_field.
index = index1 - current_repeated_start1;
1398 specific_field.
new_index = index2 - current_repeated_start2;
1404 parent_field->push_back(specific_field);
1406 parent_field->pop_back();
1411 if (change_type == ADDITION || change_type == DELETION ||
1412 change_type == MODIFICATION) {
1417 is_different =
true;
1420 parent_field->push_back(specific_field);
1422 switch (change_type) {
1436 case COMPARE_GROUPS:
1438 message1, message2, fields1[index1].second->group(),
1439 fields2[index2].second->group(), parent_field)) {
1441 is_different =
true;
1455 parent_field->pop_back();
1458 return !is_different;
1464 class MaximumMatcher {
1477 MaximumMatcher(
int count1,
int count2, NodeMatchCallback* callback,
1478 std::vector<int>* match_list1, std::vector<int>* match_list2);
1482 int FindMaximumMatch(
bool early_return);
1487 bool Match(
int left,
int right);
1491 bool FindArgumentPathDFS(
int v, std::vector<bool>* visited);
1502 MaximumMatcher::MaximumMatcher(
int count1,
int count2,
1503 NodeMatchCallback* callback,
1504 std::vector<int>* match_list1,
1505 std::vector<int>* match_list2)
1512 int MaximumMatcher::FindMaximumMatch(
bool early_return) {
1515 std::vector<bool> visited(
count1_);
1516 if (FindArgumentPathDFS(
i, &visited)) {
1518 }
else if (early_return) {
1526 (*match_list1_)[(*match_list2_)[
i]] =
i;
1532 bool MaximumMatcher::Match(
int left,
int right) {
1533 std::pair<int, int>
p(
left, right);
1534 std::map<std::pair<int, int>,
bool>::iterator
it =
1543 bool MaximumMatcher::FindArgumentPathDFS(
int v, std::vector<bool>* visited) {
1544 (*visited)[
v] =
true;
1551 int matched = (*match_list2_)[
i];
1552 if (matched == -1 && Match(
v,
i)) {
1553 (*match_list2_)[
i] =
v;
1562 int matched = (*match_list2_)[
i];
1563 if (matched != -1 && Match(
v,
i)) {
1564 if (!(*visited)[matched] && FindArgumentPathDFS(matched, visited)) {
1565 (*match_list2_)[
i] =
v;
1575 bool MessageDifferencer::MatchRepeatedFieldIndices(
1579 const std::vector<SpecificField>& parent_fields,
1580 std::vector<int>* match_list1, std::vector<int>* match_list2) {
1585 const bool is_treated_as_smart_set = IsTreatedAsSmartSet(
repeated_field);
1587 match_list1->assign(count1, -1);
1588 match_list2->assign(count2, -1);
1596 std::vector<int32> num_diffs_list1;
1597 if (is_treated_as_smart_set) {
1598 num_diffs_list1.assign(count1,
kint32max);
1601 bool success =
true;
1603 if (scope_ == PARTIAL) {
1609 this, &MessageDifferencer::IsMatch,
repeated_field, key_comparator,
1610 &message1, &message2, parent_fields,
nullptr);
1611 MaximumMatcher matcher(count1, count2, callback, match_list1, match_list2);
1614 bool early_return = (reporter ==
nullptr);
1615 int match_count = matcher.FindMaximumMatch(early_return);
1616 if (match_count != count1 && early_return)
return false;
1617 success = success && (match_count == count1);
1619 int start_offset = 0;
1624 start_offset = std::min(count1, count2);
1625 for (
int i = 0;
i < count1 &&
i < count2;
i++) {
1626 if (IsMatch(
repeated_field, key_comparator, &message1, &message2,
1627 parent_fields,
nullptr,
i,
i)) {
1628 match_list1->at(
i) =
i;
1629 match_list2->at(
i) =
i;
1636 for (
int i = start_offset;
i < count1; ++
i) {
1641 for (
int j = start_offset; j < count2; j++) {
1642 if (match_list2->at(j) != -1) {
1643 if (!is_treated_as_smart_set || num_diffs_list1[
i] == 0 ||
1644 num_diffs_list1[match_list2->at(j)] == 0) {
1649 if (is_treated_as_smart_set) {
1650 num_diffs_reporter.
Reset();
1651 match = IsMatch(
repeated_field, key_comparator, &message1, &message2,
1652 parent_fields, &num_diffs_reporter,
i, j);
1654 match = IsMatch(
repeated_field, key_comparator, &message1, &message2,
1655 parent_fields,
nullptr,
i, j);
1658 if (is_treated_as_smart_set) {
1660 num_diffs_list1[
i] = 0;
1662 FieldDescriptor::CPPTYPE_MESSAGE) {
1665 if (num_diffs < num_diffs_list1[
i]) {
1668 if (match_list2->at(j) == -1 ||
1669 num_diffs < num_diffs_list1[match_list2->at(j)]) {
1670 num_diffs_list1[
i] = num_diffs;
1679 if (!is_treated_as_smart_set || num_diffs_list1[
i] == 0) {
1685 match = (matched_j != -1);
1687 if (is_treated_as_smart_set && match_list2->at(matched_j) != -1) {
1689 match_list1->at(match_list2->at(matched_j)) = -1;
1692 match_list1->at(
i) = matched_j;
1693 match_list2->at(matched_j) =
i;
1695 if (!match && reporter ==
nullptr)
return false;
1696 success = success && match;
1701 match_indices_for_smart_list_callback_(match_list1, match_list2);
1704 reporter_ = reporter;
1715 : &default_field_comparator_;
1716 return comparator->
Compare(message1, message2,
field, index1, index2,
1722 MessageDifferencer::Reporter::Reporter() {}
1723 MessageDifferencer::Reporter::~Reporter() {}
1727 MessageDifferencer::MapKeyComparator::MapKeyComparator() {}
1728 MessageDifferencer::MapKeyComparator::~MapKeyComparator() {}
1732 MessageDifferencer::IgnoreCriteria::IgnoreCriteria() {}
1733 MessageDifferencer::IgnoreCriteria::~IgnoreCriteria() {}
1739 MessageDifferencer::StreamReporter::StreamReporter(
1741 : printer_(new io::Printer(
output,
'$')),
1742 delete_printer_(
true),
1743 report_modified_aggregates_(
false) {}
1746 : printer_(printer),
1747 delete_printer_(
false),
1748 report_modified_aggregates_(
false) {}
1751 if (delete_printer_)
delete printer_;
1755 const std::vector<SpecificField>& field_path,
bool left_side) {
1756 for (
int i = 0;
i < field_path.size(); ++
i) {
1758 printer_->Print(
".");
1765 printer_->Print(
"($name$)",
"name", specific_field.
field->
full_name());
1767 printer_->PrintRaw(specific_field.
field->
name());
1776 if (left_side && specific_field.
index >= 0) {
1777 printer_->Print(
"[$name$]",
"name",
StrCat(specific_field.
index));
1779 if (!left_side && specific_field.
new_index >= 0) {
1780 printer_->Print(
"[$name$]",
"name",
1787 const std::vector<SpecificField>& field_path,
bool left_side,
1789 PrintPath(field_path, left_side);
1793 const Message&
message,
const std::vector<SpecificField>& field_path,
1802 const Message& field_message =
1803 field->is_repeated()
1808 printer_->Print(
"{ }");
1810 printer_->Print(
"{ $name$ }",
"name",
output);
1814 printer_->PrintRaw(
output);
1823 PrintUnknownFieldValue(unknown_field);
1829 GOOGLE_CHECK(unknown_field !=
NULL) <<
" Cannot print NULL unknown_field.";
1832 switch (unknown_field->
type()) {
1855 printer_->PrintRaw(
output);
1859 printer_->Print(
str.c_str());
1864 const std::vector<SpecificField>& field_path) {
1865 printer_->Print(
"added: ");
1866 PrintPath(field_path,
false, message2);
1867 printer_->Print(
": ");
1869 printer_->Print(
"\n");
1874 const std::vector<SpecificField>& field_path) {
1875 printer_->Print(
"deleted: ");
1876 PrintPath(field_path,
true, message1);
1877 printer_->Print(
": ");
1879 printer_->Print(
"\n");
1884 const std::vector<SpecificField>& field_path) {
1885 if (!report_modified_aggregates_ && field_path.back().field ==
NULL) {
1890 }
else if (!report_modified_aggregates_) {
1891 if (field_path.back().field->cpp_type() ==
1898 printer_->Print(
"modified: ");
1899 PrintPath(field_path,
true, message1);
1901 printer_->Print(
" -> ");
1902 PrintPath(field_path,
false, message2);
1904 printer_->Print(
": ");
1906 printer_->Print(
" -> ");
1908 printer_->Print(
"\n");
1913 const std::vector<SpecificField>& field_path) {
1914 printer_->Print(
"moved: ");
1915 PrintPath(field_path,
true, message1);
1916 printer_->Print(
" -> ");
1917 PrintPath(field_path,
false, message2);
1918 printer_->Print(
" : ");
1920 printer_->Print(
"\n");
1925 const std::vector<SpecificField>& field_path) {
1926 printer_->Print(
"matched: ");
1927 PrintPath(field_path,
true, message1);
1929 printer_->Print(
" -> ");
1930 PrintPath(field_path,
false, message2);
1932 printer_->Print(
" : ");
1934 printer_->Print(
"\n");
1939 const std::vector<SpecificField>& field_path) {
1940 printer_->Print(
"ignored: ");
1941 PrintPath(field_path,
true, message1);
1943 printer_->Print(
" -> ");
1944 PrintPath(field_path,
false, message2);
1946 printer_->Print(
"\n");
1951 const std::vector<SpecificField>& field_path) {
1952 printer_->Print(
"ignored: ");
1953 PrintPath(field_path,
true, message1);
1955 printer_->Print(
" -> ");
1956 PrintPath(field_path,
false, message2);
1958 printer_->Print(
"\n");
1963 const std::vector<std::vector<const FieldDescriptor*> >& key_field_paths) {