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

Side by Side Diff: third_party/protobuf/src/google/protobuf/util/message_differencer.cc

Issue 2600753002: Reverts third_party/protobuf: Update to HEAD (f52e188fe4) (Closed)
Patch Set: Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Protocol Buffers - Google's data interchange format 1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved. 2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/ 3 // https://developers.google.com/protocol-buffers/
4 // 4 //
5 // Redistribution and use in source and binary forms, with or without 5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are 6 // modification, are permitted provided that the following conditions are
7 // met: 7 // met:
8 // 8 //
9 // * Redistributions of source code must retain the above copyright 9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer. 10 // notice, this list of conditions and the following disclaimer.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 // When comparing a repeated field as map, MultipleFieldMapKeyComparator can 66 // When comparing a repeated field as map, MultipleFieldMapKeyComparator can
67 // be used to specify multiple fields as key for key comparison. 67 // be used to specify multiple fields as key for key comparison.
68 // Two elements of a repeated field will be regarded as having the same key 68 // Two elements of a repeated field will be regarded as having the same key
69 // iff they have the same value for every specified key field. 69 // iff they have the same value for every specified key field.
70 // Note that you can also specify only one field as key. 70 // Note that you can also specify only one field as key.
71 class MessageDifferencer::MultipleFieldsMapKeyComparator 71 class MessageDifferencer::MultipleFieldsMapKeyComparator
72 : public MessageDifferencer::MapKeyComparator { 72 : public MessageDifferencer::MapKeyComparator {
73 public: 73 public:
74 MultipleFieldsMapKeyComparator( 74 MultipleFieldsMapKeyComparator(
75 MessageDifferencer* message_differencer, 75 MessageDifferencer* message_differencer,
76 const std::vector<std::vector<const FieldDescriptor*> >& key_field_paths) 76 const vector<vector<const FieldDescriptor*> >& key_field_paths)
77 : message_differencer_(message_differencer), 77 : message_differencer_(message_differencer),
78 key_field_paths_(key_field_paths) { 78 key_field_paths_(key_field_paths) {
79 GOOGLE_CHECK(!key_field_paths_.empty()); 79 GOOGLE_CHECK(!key_field_paths_.empty());
80 for (int i = 0; i < key_field_paths_.size(); ++i) { 80 for (int i = 0; i < key_field_paths_.size(); ++i) {
81 GOOGLE_CHECK(!key_field_paths_[i].empty()); 81 GOOGLE_CHECK(!key_field_paths_[i].empty());
82 } 82 }
83 } 83 }
84 MultipleFieldsMapKeyComparator( 84 MultipleFieldsMapKeyComparator(
85 MessageDifferencer* message_differencer, 85 MessageDifferencer* message_differencer,
86 const FieldDescriptor* key) 86 const FieldDescriptor* key)
87 : message_differencer_(message_differencer) { 87 : message_differencer_(message_differencer) {
88 std::vector<const FieldDescriptor*> key_field_path; 88 vector<const FieldDescriptor*> key_field_path;
89 key_field_path.push_back(key); 89 key_field_path.push_back(key);
90 key_field_paths_.push_back(key_field_path); 90 key_field_paths_.push_back(key_field_path);
91 } 91 }
92 virtual bool IsMatch( 92 virtual bool IsMatch(
93 const Message& message1, 93 const Message& message1,
94 const Message& message2, 94 const Message& message2,
95 const std::vector<SpecificField>& parent_fields) const { 95 const vector<SpecificField>& parent_fields) const {
96 for (int i = 0; i < key_field_paths_.size(); ++i) { 96 for (int i = 0; i < key_field_paths_.size(); ++i) {
97 if (!IsMatchInternal(message1, message2, parent_fields, 97 if (!IsMatchInternal(message1, message2, parent_fields,
98 key_field_paths_[i], 0)) { 98 key_field_paths_[i], 0)) {
99 return false; 99 return false;
100 } 100 }
101 } 101 }
102 return true; 102 return true;
103 } 103 }
104 private: 104 private:
105 bool IsMatchInternal( 105 bool IsMatchInternal(
106 const Message& message1, 106 const Message& message1,
107 const Message& message2, 107 const Message& message2,
108 const std::vector<SpecificField>& parent_fields, 108 const vector<SpecificField>& parent_fields,
109 const std::vector<const FieldDescriptor*>& key_field_path, 109 const vector<const FieldDescriptor*>& key_field_path,
110 int path_index) const { 110 int path_index) const {
111 const FieldDescriptor* field = key_field_path[path_index]; 111 const FieldDescriptor* field = key_field_path[path_index];
112 std::vector<SpecificField> current_parent_fields(parent_fields); 112 vector<SpecificField> current_parent_fields(parent_fields);
113 if (path_index == key_field_path.size() - 1) { 113 if (path_index == key_field_path.size() - 1) {
114 if (field->is_repeated()) { 114 if (field->is_repeated()) {
115 if (!message_differencer_->CompareRepeatedField( 115 if (!message_differencer_->CompareRepeatedField(
116 message1, message2, field, &current_parent_fields)) { 116 message1, message2, field, &current_parent_fields)) {
117 return false; 117 return false;
118 } 118 }
119 } else { 119 } else {
120 if (!message_differencer_->CompareFieldValueUsingParentFields( 120 if (!message_differencer_->CompareFieldValueUsingParentFields(
121 message1, message2, field, -1, -1, &current_parent_fields)) { 121 message1, message2, field, -1, -1, &current_parent_fields)) {
122 return false; 122 return false;
(...skipping 16 matching lines...) Expand all
139 current_parent_fields.push_back(specific_field); 139 current_parent_fields.push_back(specific_field);
140 return IsMatchInternal( 140 return IsMatchInternal(
141 reflection1->GetMessage(message1, field), 141 reflection1->GetMessage(message1, field),
142 reflection2->GetMessage(message2, field), 142 reflection2->GetMessage(message2, field),
143 current_parent_fields, 143 current_parent_fields,
144 key_field_path, 144 key_field_path,
145 path_index + 1); 145 path_index + 1);
146 } 146 }
147 } 147 }
148 MessageDifferencer* message_differencer_; 148 MessageDifferencer* message_differencer_;
149 std::vector<std::vector<const FieldDescriptor*> > key_field_paths_; 149 vector<vector<const FieldDescriptor*> > key_field_paths_;
150 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MultipleFieldsMapKeyComparator); 150 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MultipleFieldsMapKeyComparator);
151 }; 151 };
152 152
153 bool MessageDifferencer::Equals(const Message& message1, 153 bool MessageDifferencer::Equals(const Message& message1,
154 const Message& message2) { 154 const Message& message2) {
155 MessageDifferencer differencer; 155 MessageDifferencer differencer;
156 156
157 return differencer.Compare(message1, message2); 157 return differencer.Compare(message1, message2);
158 } 158 }
159 159
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 << "Cannot treat this repeated field as both Map and List for " 276 << "Cannot treat this repeated field as both Map and List for "
277 << "comparison."; 277 << "comparison.";
278 MapKeyComparator* key_comparator = 278 MapKeyComparator* key_comparator =
279 new MultipleFieldsMapKeyComparator(this, key); 279 new MultipleFieldsMapKeyComparator(this, key);
280 owned_key_comparators_.push_back(key_comparator); 280 owned_key_comparators_.push_back(key_comparator);
281 map_field_key_comparator_[field] = key_comparator; 281 map_field_key_comparator_[field] = key_comparator;
282 } 282 }
283 283
284 void MessageDifferencer::TreatAsMapWithMultipleFieldsAsKey( 284 void MessageDifferencer::TreatAsMapWithMultipleFieldsAsKey(
285 const FieldDescriptor* field, 285 const FieldDescriptor* field,
286 const std::vector<const FieldDescriptor*>& key_fields) { 286 const vector<const FieldDescriptor*>& key_fields) {
287 std::vector<std::vector<const FieldDescriptor*> > key_field_paths; 287 vector<vector<const FieldDescriptor*> > key_field_paths;
288 for (int i = 0; i < key_fields.size(); ++i) { 288 for (int i = 0; i < key_fields.size(); ++i) {
289 std::vector<const FieldDescriptor*> key_field_path; 289 vector<const FieldDescriptor*> key_field_path;
290 key_field_path.push_back(key_fields[i]); 290 key_field_path.push_back(key_fields[i]);
291 key_field_paths.push_back(key_field_path); 291 key_field_paths.push_back(key_field_path);
292 } 292 }
293 TreatAsMapWithMultipleFieldPathsAsKey(field, key_field_paths); 293 TreatAsMapWithMultipleFieldPathsAsKey(field, key_field_paths);
294 } 294 }
295 295
296 void MessageDifferencer::TreatAsMapWithMultipleFieldPathsAsKey( 296 void MessageDifferencer::TreatAsMapWithMultipleFieldPathsAsKey(
297 const FieldDescriptor* field, 297 const FieldDescriptor* field,
298 const std::vector<std::vector<const FieldDescriptor*> >& key_field_paths) { 298 const vector<vector<const FieldDescriptor*> >& key_field_paths) {
299 GOOGLE_CHECK(field->is_repeated()) << "Field must be repeated: " 299 GOOGLE_CHECK(field->is_repeated()) << "Field must be repeated: "
300 << field->full_name(); 300 << field->full_name();
301 GOOGLE_CHECK_EQ(FieldDescriptor::CPPTYPE_MESSAGE, field->cpp_type()) 301 GOOGLE_CHECK_EQ(FieldDescriptor::CPPTYPE_MESSAGE, field->cpp_type())
302 << "Field has to be message type. Field name is: " 302 << "Field has to be message type. Field name is: "
303 << field->full_name(); 303 << field->full_name();
304 for (int i = 0; i < key_field_paths.size(); ++i) { 304 for (int i = 0; i < key_field_paths.size(); ++i) {
305 const std::vector<const FieldDescriptor*>& key_field_path = 305 const vector<const FieldDescriptor*>& key_field_path = key_field_paths[i];
306 key_field_paths[i];
307 for (int j = 0; j < key_field_path.size(); ++j) { 306 for (int j = 0; j < key_field_path.size(); ++j) {
308 const FieldDescriptor* parent_field = 307 const FieldDescriptor* parent_field =
309 j == 0 ? field : key_field_path[j - 1]; 308 j == 0 ? field : key_field_path[j - 1];
310 const FieldDescriptor* child_field = key_field_path[j]; 309 const FieldDescriptor* child_field = key_field_path[j];
311 GOOGLE_CHECK(child_field->containing_type() == parent_field->message_type( )) 310 GOOGLE_CHECK(child_field->containing_type() == parent_field->message_type( ))
312 << child_field->full_name() 311 << child_field->full_name()
313 << " must be a direct subfield within the field: " 312 << " must be a direct subfield within the field: "
314 << parent_field->full_name(); 313 << parent_field->full_name();
315 if (j != 0) { 314 if (j != 0) {
316 GOOGLE_CHECK_EQ(FieldDescriptor::CPPTYPE_MESSAGE, parent_field->cpp_type ()) 315 GOOGLE_CHECK_EQ(FieldDescriptor::CPPTYPE_MESSAGE, parent_field->cpp_type ())
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 if (field2 == NULL) { 383 if (field2 == NULL) {
385 return true; 384 return true;
386 } 385 }
387 386
388 // Always order fields by their tag number 387 // Always order fields by their tag number
389 return (field1->number() < field2->number()); 388 return (field1->number() < field2->number());
390 } 389 }
391 390
392 bool MessageDifferencer::Compare(const Message& message1, 391 bool MessageDifferencer::Compare(const Message& message1,
393 const Message& message2) { 392 const Message& message2) {
394 std::vector<SpecificField> parent_fields; 393 vector<SpecificField> parent_fields;
395 394
396 bool result = false; 395 bool result = false;
397 396
398 // Setup the internal reporter if need be. 397 // Setup the internal reporter if need be.
399 if (output_string_) { 398 if (output_string_) {
400 io::StringOutputStream output_stream(output_string_); 399 io::StringOutputStream output_stream(output_string_);
401 StreamReporter reporter(&output_stream); 400 StreamReporter reporter(&output_stream);
402 reporter_ = &reporter; 401 reporter_ = &reporter;
403 result = Compare(message1, message2, &parent_fields); 402 result = Compare(message1, message2, &parent_fields);
404 reporter_ = NULL; 403 reporter_ = NULL;
405 } else { 404 } else {
406 result = Compare(message1, message2, &parent_fields); 405 result = Compare(message1, message2, &parent_fields);
407 } 406 }
408 407
409 return result; 408 return result;
410 } 409 }
411 410
412 bool MessageDifferencer::CompareWithFields( 411 bool MessageDifferencer::CompareWithFields(
413 const Message& message1, 412 const Message& message1,
414 const Message& message2, 413 const Message& message2,
415 const std::vector<const FieldDescriptor*>& message1_fields_arg, 414 const vector<const FieldDescriptor*>& message1_fields_arg,
416 const std::vector<const FieldDescriptor*>& message2_fields_arg) { 415 const vector<const FieldDescriptor*>& message2_fields_arg) {
417 if (message1.GetDescriptor() != message2.GetDescriptor()) { 416 if (message1.GetDescriptor() != message2.GetDescriptor()) {
418 GOOGLE_LOG(DFATAL) << "Comparison between two messages with different " 417 GOOGLE_LOG(DFATAL) << "Comparison between two messages with different "
419 << "descriptors."; 418 << "descriptors.";
420 return false; 419 return false;
421 } 420 }
422 421
423 std::vector<SpecificField> parent_fields; 422 vector<SpecificField> parent_fields;
424 423
425 bool result = false; 424 bool result = false;
426 425
427 std::vector<const FieldDescriptor*> message1_fields(message1_fields_arg); 426 vector<const FieldDescriptor*> message1_fields(message1_fields_arg);
428 std::vector<const FieldDescriptor*> message2_fields(message2_fields_arg); 427 vector<const FieldDescriptor*> message2_fields(message2_fields_arg);
429 428
430 std::sort(message1_fields.begin(), message1_fields.end(), FieldBefore); 429 std::sort(message1_fields.begin(), message1_fields.end(), FieldBefore);
431 std::sort(message2_fields.begin(), message2_fields.end(), FieldBefore); 430 std::sort(message2_fields.begin(), message2_fields.end(), FieldBefore);
432 // Append NULL sentinel values. 431 // Append NULL sentinel values.
433 message1_fields.push_back(NULL); 432 message1_fields.push_back(NULL);
434 message2_fields.push_back(NULL); 433 message2_fields.push_back(NULL);
435 434
436 // Setup the internal reporter if need be. 435 // Setup the internal reporter if need be.
437 if (output_string_) { 436 if (output_string_) {
438 io::StringOutputStream output_stream(output_string_); 437 io::StringOutputStream output_stream(output_string_);
439 StreamReporter reporter(&output_stream); 438 StreamReporter reporter(&output_stream);
440 reporter_ = &reporter; 439 reporter_ = &reporter;
441 result = CompareRequestedFieldsUsingSettings( 440 result = CompareRequestedFieldsUsingSettings(
442 message1, message2, message1_fields, message2_fields, &parent_fields); 441 message1, message2, message1_fields, message2_fields, &parent_fields);
443 reporter_ = NULL; 442 reporter_ = NULL;
444 } else { 443 } else {
445 result = CompareRequestedFieldsUsingSettings( 444 result = CompareRequestedFieldsUsingSettings(
446 message1, message2, message1_fields, message2_fields, &parent_fields); 445 message1, message2, message1_fields, message2_fields, &parent_fields);
447 } 446 }
448 447
449 return result; 448 return result;
450 } 449 }
451 450
452 bool MessageDifferencer::Compare( 451 bool MessageDifferencer::Compare(
453 const Message& message1, 452 const Message& message1,
454 const Message& message2, 453 const Message& message2,
455 std::vector<SpecificField>* parent_fields) { 454 vector<SpecificField>* parent_fields) {
456 const Descriptor* descriptor1 = message1.GetDescriptor(); 455 const Descriptor* descriptor1 = message1.GetDescriptor();
457 const Descriptor* descriptor2 = message2.GetDescriptor(); 456 const Descriptor* descriptor2 = message2.GetDescriptor();
458 if (descriptor1 != descriptor2) { 457 if (descriptor1 != descriptor2) {
459 GOOGLE_LOG(DFATAL) << "Comparison between two messages with different " 458 GOOGLE_LOG(DFATAL) << "Comparison between two messages with different "
460 << "descriptors. " 459 << "descriptors. "
461 << descriptor1->full_name() << " vs " 460 << descriptor1->full_name() << " vs "
462 << descriptor2->full_name(); 461 << descriptor2->full_name();
463 return false; 462 return false;
464 } 463 }
465 // Expand google.protobuf.Any payload if possible. 464 // Expand google.protobuf.Any payload if possible.
466 if (descriptor1->full_name() == internal::kAnyFullTypeName) { 465 if (descriptor1->full_name() == internal::kAnyFullTypeName) {
467 google::protobuf::scoped_ptr<Message> data1; 466 google::protobuf::scoped_ptr<Message> data1;
468 google::protobuf::scoped_ptr<Message> data2; 467 google::protobuf::scoped_ptr<Message> data2;
469 if (UnpackAny(message1, &data1) && UnpackAny(message2, &data2)) { 468 if (UnpackAny(message1, &data1) && UnpackAny(message2, &data2)) {
470 return Compare(*data1, *data2, parent_fields); 469 return Compare(*data1, *data2, parent_fields);
471 } 470 }
472 } 471 }
473 const Reflection* reflection1 = message1.GetReflection(); 472 const Reflection* reflection1 = message1.GetReflection();
474 const Reflection* reflection2 = message2.GetReflection(); 473 const Reflection* reflection2 = message2.GetReflection();
475 474
476 // Retrieve all the set fields, including extensions. 475 // Retrieve all the set fields, including extensions.
477 std::vector<const FieldDescriptor*> message1_fields; 476 vector<const FieldDescriptor*> message1_fields;
478 message1_fields.reserve(1 + message1.GetDescriptor()->field_count()); 477 vector<const FieldDescriptor*> message2_fields;
479
480 std::vector<const FieldDescriptor*> message2_fields;
481 message2_fields.reserve(1 + message2.GetDescriptor()->field_count());
482 478
483 reflection1->ListFields(message1, &message1_fields); 479 reflection1->ListFields(message1, &message1_fields);
484 reflection2->ListFields(message2, &message2_fields); 480 reflection2->ListFields(message2, &message2_fields);
485 481
486 // Add sentinel values to deal with the 482 // Add sentinel values to deal with the
487 // case where the number of the fields in 483 // case where the number of the fields in
488 // each list are different. 484 // each list are different.
489 message1_fields.push_back(NULL); 485 message1_fields.push_back(NULL);
490 message2_fields.push_back(NULL); 486 message2_fields.push_back(NULL);
491 487
(...skipping 16 matching lines...) Expand all
508 504
509 return CompareRequestedFieldsUsingSettings( 505 return CompareRequestedFieldsUsingSettings(
510 message1, message2, 506 message1, message2,
511 message1_fields, message2_fields, 507 message1_fields, message2_fields,
512 parent_fields) && unknown_compare_result; 508 parent_fields) && unknown_compare_result;
513 } 509 }
514 510
515 bool MessageDifferencer::CompareRequestedFieldsUsingSettings( 511 bool MessageDifferencer::CompareRequestedFieldsUsingSettings(
516 const Message& message1, 512 const Message& message1,
517 const Message& message2, 513 const Message& message2,
518 const std::vector<const FieldDescriptor*>& message1_fields, 514 const vector<const FieldDescriptor*>& message1_fields,
519 const std::vector<const FieldDescriptor*>& message2_fields, 515 const vector<const FieldDescriptor*>& message2_fields,
520 std::vector<SpecificField>* parent_fields) { 516 vector<SpecificField>* parent_fields) {
521 if (scope_ == FULL) { 517 if (scope_ == FULL) {
522 if (message_field_comparison_ == EQUIVALENT) { 518 if (message_field_comparison_ == EQUIVALENT) {
523 // We need to merge the field lists of both messages (i.e. 519 // We need to merge the field lists of both messages (i.e.
524 // we are merely checking for a difference in field values, 520 // we are merely checking for a difference in field values,
525 // rather than the addition or deletion of fields). 521 // rather than the addition or deletion of fields).
526 std::vector<const FieldDescriptor*> fields_union; 522 vector<const FieldDescriptor*> fields_union;
527 CombineFields(message1_fields, FULL, message2_fields, FULL, 523 CombineFields(message1_fields, FULL, message2_fields, FULL,
528 &fields_union); 524 &fields_union);
529 return CompareWithFieldsInternal(message1, message2, fields_union, 525 return CompareWithFieldsInternal(message1, message2, fields_union,
530 fields_union, parent_fields); 526 fields_union, parent_fields);
531 } else { 527 } else {
532 // Simple equality comparison, use the unaltered field lists. 528 // Simple equality comparison, use the unaltered field lists.
533 return CompareWithFieldsInternal(message1, message2, message1_fields, 529 return CompareWithFieldsInternal(message1, message2, message1_fields,
534 message2_fields, parent_fields); 530 message2_fields, parent_fields);
535 } 531 }
536 } else { 532 } else {
537 if (message_field_comparison_ == EQUIVALENT) { 533 if (message_field_comparison_ == EQUIVALENT) {
538 // We use the list of fields for message1 for both messages when 534 // We use the list of fields for message1 for both messages when
539 // comparing. This way, extra fields in message2 are ignored, 535 // comparing. This way, extra fields in message2 are ignored,
540 // and missing fields in message2 use their default value. 536 // and missing fields in message2 use their default value.
541 return CompareWithFieldsInternal(message1, message2, message1_fields, 537 return CompareWithFieldsInternal(message1, message2, message1_fields,
542 message1_fields, parent_fields); 538 message1_fields, parent_fields);
543 } else { 539 } else {
544 // We need to consider the full list of fields for message1 540 // We need to consider the full list of fields for message1
545 // but only the intersection for message2. This way, any fields 541 // but only the intersection for message2. This way, any fields
546 // only present in message2 will be ignored, but any fields only 542 // only present in message2 will be ignored, but any fields only
547 // present in message1 will be marked as a difference. 543 // present in message1 will be marked as a difference.
548 std::vector<const FieldDescriptor*> fields_intersection; 544 vector<const FieldDescriptor*> fields_intersection;
549 CombineFields(message1_fields, PARTIAL, message2_fields, PARTIAL, 545 CombineFields(message1_fields, PARTIAL, message2_fields, PARTIAL,
550 &fields_intersection); 546 &fields_intersection);
551 return CompareWithFieldsInternal(message1, message2, message1_fields, 547 return CompareWithFieldsInternal(message1, message2, message1_fields,
552 fields_intersection, parent_fields); 548 fields_intersection, parent_fields);
553 } 549 }
554 } 550 }
555 } 551 }
556 552
557 void MessageDifferencer::CombineFields( 553 void MessageDifferencer::CombineFields(
558 const std::vector<const FieldDescriptor*>& fields1, 554 const vector<const FieldDescriptor*>& fields1,
559 Scope fields1_scope, 555 Scope fields1_scope,
560 const std::vector<const FieldDescriptor*>& fields2, 556 const vector<const FieldDescriptor*>& fields2,
561 Scope fields2_scope, 557 Scope fields2_scope,
562 std::vector<const FieldDescriptor*>* combined_fields) { 558 vector<const FieldDescriptor*>* combined_fields) {
563 559
564 int index1 = 0; 560 int index1 = 0;
565 int index2 = 0; 561 int index2 = 0;
566 562
567 while (index1 < fields1.size() && index2 < fields2.size()) { 563 while (index1 < fields1.size() && index2 < fields2.size()) {
568 const FieldDescriptor* field1 = fields1[index1]; 564 const FieldDescriptor* field1 = fields1[index1];
569 const FieldDescriptor* field2 = fields2[index2]; 565 const FieldDescriptor* field2 = fields2[index2];
570 566
571 if (FieldBefore(field1, field2)) { 567 if (FieldBefore(field1, field2)) {
572 if (fields1_scope == FULL) { 568 if (fields1_scope == FULL) {
573 combined_fields->push_back(fields1[index1]); 569 combined_fields->push_back(fields1[index1]);
574 } 570 }
575 ++index1; 571 ++index1;
576 } else if (FieldBefore(field2, field1)) { 572 } else if (FieldBefore(field2, field1)) {
577 if (fields2_scope == FULL) { 573 if (fields2_scope == FULL) {
578 combined_fields->push_back(fields2[index2]); 574 combined_fields->push_back(fields2[index2]);
579 } 575 }
580 ++index2; 576 ++index2;
581 } else { 577 } else {
582 combined_fields->push_back(fields1[index1]); 578 combined_fields->push_back(fields1[index1]);
583 ++index1; 579 ++index1;
584 ++index2; 580 ++index2;
585 } 581 }
586 } 582 }
587 } 583 }
588 584
589 bool MessageDifferencer::CompareWithFieldsInternal( 585 bool MessageDifferencer::CompareWithFieldsInternal(
590 const Message& message1, 586 const Message& message1,
591 const Message& message2, 587 const Message& message2,
592 const std::vector<const FieldDescriptor*>& message1_fields, 588 const vector<const FieldDescriptor*>& message1_fields,
593 const std::vector<const FieldDescriptor*>& message2_fields, 589 const vector<const FieldDescriptor*>& message2_fields,
594 std::vector<SpecificField>* parent_fields) { 590 vector<SpecificField>* parent_fields) {
595 bool isDifferent = false; 591 bool isDifferent = false;
596 int field_index1 = 0; 592 int field_index1 = 0;
597 int field_index2 = 0; 593 int field_index2 = 0;
598 594
599 const Reflection* reflection1 = message1.GetReflection(); 595 const Reflection* reflection1 = message1.GetReflection();
600 const Reflection* reflection2 = message2.GetReflection(); 596 const Reflection* reflection2 = message2.GetReflection();
601 597
602 while (true) { 598 while (true) {
603 const FieldDescriptor* field1 = message1_fields[field_index1]; 599 const FieldDescriptor* field1 = message1_fields[field_index1];
604 const FieldDescriptor* field2 = message2_fields[field_index2]; 600 const FieldDescriptor* field2 = message2_fields[field_index2];
(...skipping 15 matching lines...) Expand all
620 616
621 parent_fields->push_back(specific_field); 617 parent_fields->push_back(specific_field);
622 reporter_->ReportIgnored(message1, message2, *parent_fields); 618 reporter_->ReportIgnored(message1, message2, *parent_fields);
623 parent_fields->pop_back(); 619 parent_fields->pop_back();
624 } 620 }
625 ++field_index1; 621 ++field_index1;
626 continue; 622 continue;
627 } 623 }
628 624
629 if (reporter_ != NULL) { 625 if (reporter_ != NULL) {
630 assert(field1 != NULL);
631 int count = field1->is_repeated() ? 626 int count = field1->is_repeated() ?
632 reflection1->FieldSize(message1, field1) : 1; 627 reflection1->FieldSize(message1, field1) : 1;
633 628
634 for (int i = 0; i < count; ++i) { 629 for (int i = 0; i < count; ++i) {
635 SpecificField specific_field; 630 SpecificField specific_field;
636 specific_field.field = field1; 631 specific_field.field = field1;
637 specific_field.index = field1->is_repeated() ? i : -1; 632 specific_field.index = field1->is_repeated() ? i : -1;
638 633
639 parent_fields->push_back(specific_field); 634 parent_fields->push_back(specific_field);
640 reporter_->ReportDeleted(message1, message2, *parent_fields); 635 reporter_->ReportDeleted(message1, message2, *parent_fields);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 reporter_->ReportIgnored(message1, message2, *parent_fields); 696 reporter_->ReportIgnored(message1, message2, *parent_fields);
702 parent_fields->pop_back(); 697 parent_fields->pop_back();
703 } 698 }
704 699
705 ++field_index1; 700 ++field_index1;
706 ++field_index2; 701 ++field_index2;
707 continue; 702 continue;
708 } 703 }
709 704
710 bool fieldDifferent = false; 705 bool fieldDifferent = false;
711 assert(field1 != NULL);
712 if (field1->is_repeated()) { 706 if (field1->is_repeated()) {
713 fieldDifferent = !CompareRepeatedField(message1, message2, field1, 707 fieldDifferent = !CompareRepeatedField(message1, message2, field1,
714 parent_fields); 708 parent_fields);
715 if (fieldDifferent) { 709 if (fieldDifferent) {
716 if (reporter_ == NULL) return false; 710 if (reporter_ == NULL) return false;
717 isDifferent = true; 711 isDifferent = true;
718 } 712 }
719 } else { 713 } else {
720 fieldDifferent = !CompareFieldValueUsingParentFields( 714 fieldDifferent = !CompareFieldValueUsingParentFields(
721 message1, message2, field1, -1, -1, parent_fields); 715 message1, message2, field1, -1, -1, parent_fields);
(...skipping 18 matching lines...) Expand all
740 } 734 }
741 } 735 }
742 // Increment the field indicies. 736 // Increment the field indicies.
743 ++field_index1; 737 ++field_index1;
744 ++field_index2; 738 ++field_index2;
745 } 739 }
746 740
747 return !isDifferent; 741 return !isDifferent;
748 } 742 }
749 743
750 bool MessageDifferencer::IsMatch( 744 bool MessageDifferencer::IsMatch(const FieldDescriptor* repeated_field,
751 const FieldDescriptor* repeated_field, 745 const MapKeyComparator* key_comparator,
752 const MapKeyComparator* key_comparator, const Message* message1, 746 const Message* message1,
753 const Message* message2, const std::vector<SpecificField>& parent_fields, 747 const Message* message2,
754 int index1, int index2) { 748 const vector<SpecificField>& parent_fields,
755 std::vector<SpecificField> current_parent_fields(parent_fields); 749 int index1, int index2) {
750 vector<SpecificField> current_parent_fields(parent_fields);
756 if (repeated_field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { 751 if (repeated_field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
757 return CompareFieldValueUsingParentFields( 752 return CompareFieldValueUsingParentFields(
758 *message1, *message2, repeated_field, index1, index2, 753 *message1, *message2, repeated_field, index1, index2,
759 &current_parent_fields); 754 &current_parent_fields);
760 } 755 }
761 // Back up the Reporter and output_string_. They will be reset in the 756 // Back up the Reporter and output_string_. They will be reset in the
762 // following code. 757 // following code.
763 Reporter* backup_reporter = reporter_; 758 Reporter* backup_reporter = reporter_;
764 string* output_string = output_string_; 759 string* output_string = output_string_;
765 reporter_ = NULL; 760 reporter_ = NULL;
(...skipping 19 matching lines...) Expand all
785 780
786 reporter_ = backup_reporter; 781 reporter_ = backup_reporter;
787 output_string_ = output_string; 782 output_string_ = output_string;
788 return match; 783 return match;
789 } 784 }
790 785
791 bool MessageDifferencer::CompareRepeatedField( 786 bool MessageDifferencer::CompareRepeatedField(
792 const Message& message1, 787 const Message& message1,
793 const Message& message2, 788 const Message& message2,
794 const FieldDescriptor* repeated_field, 789 const FieldDescriptor* repeated_field,
795 std::vector<SpecificField>* parent_fields) { 790 vector<SpecificField>* parent_fields) {
796 // the input FieldDescriptor is guaranteed to be repeated field. 791 // the input FieldDescriptor is guaranteed to be repeated field.
797 const Reflection* reflection1 = message1.GetReflection(); 792 const Reflection* reflection1 = message1.GetReflection();
798 const Reflection* reflection2 = message2.GetReflection(); 793 const Reflection* reflection2 = message2.GetReflection();
799 const int count1 = reflection1->FieldSize(message1, repeated_field); 794 const int count1 = reflection1->FieldSize(message1, repeated_field);
800 const int count2 = reflection2->FieldSize(message2, repeated_field); 795 const int count2 = reflection2->FieldSize(message2, repeated_field);
801 const bool treated_as_subset = IsTreatedAsSubset(repeated_field); 796 const bool treated_as_subset = IsTreatedAsSubset(repeated_field);
802 797
803 // If the field is not treated as subset and no detailed reports is needed, 798 // If the field is not treated as subset and no detailed reports is needed,
804 // we do a quick check on the number of the elements to avoid unnecessary 799 // we do a quick check on the number of the elements to avoid unnecessary
805 // comparison. 800 // comparison.
806 if (count1 != count2 && reporter_ == NULL && !treated_as_subset) { 801 if (count1 != count2 && reporter_ == NULL && !treated_as_subset) {
807 return false; 802 return false;
808 } 803 }
809 // A match can never be found if message1 has more items than message2. 804 // A match can never be found if message1 has more items than message2.
810 if (count1 > count2 && reporter_ == NULL) { 805 if (count1 > count2 && reporter_ == NULL) {
811 return false; 806 return false;
812 } 807 }
813 808
814 // These two list are used for store the index of the correspondent 809 // These two list are used for store the index of the correspondent
815 // element in peer repeated field. 810 // element in peer repeated field.
816 std::vector<int> match_list1; 811 vector<int> match_list1;
817 std::vector<int> match_list2; 812 vector<int> match_list2;
818 813
819 // Try to match indices of the repeated fields. Return false if match fails 814 // Try to match indices of the repeated fields. Return false if match fails
820 // and there's no detailed report needed. 815 // and there's no detailed report needed.
821 if (!MatchRepeatedFieldIndices(message1, message2, repeated_field, 816 if (!MatchRepeatedFieldIndices(message1, message2, repeated_field,
822 *parent_fields, &match_list1, &match_list2) && 817 *parent_fields, &match_list1, &match_list2) &&
823 reporter_ == NULL) { 818 reporter_ == NULL) {
824 return false; 819 return false;
825 } 820 }
826 821
827 bool fieldDifferent = false; 822 bool fieldDifferent = false;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
870 if (reporter_ == NULL) continue; 865 if (reporter_ == NULL) continue;
871 specific_field.index = i; 866 specific_field.index = i;
872 specific_field.new_index = i; 867 specific_field.new_index = i;
873 parent_fields->push_back(specific_field); 868 parent_fields->push_back(specific_field);
874 reporter_->ReportAdded(message1, message2, *parent_fields); 869 reporter_->ReportAdded(message1, message2, *parent_fields);
875 parent_fields->pop_back(); 870 parent_fields->pop_back();
876 } 871 }
877 872
878 for (int i = 0; i < count1; ++i) { 873 for (int i = 0; i < count1; ++i) {
879 if (match_list1[i] != -1) continue; 874 if (match_list1[i] != -1) continue;
880 assert(reporter_ != NULL);
881 specific_field.index = i; 875 specific_field.index = i;
882 parent_fields->push_back(specific_field); 876 parent_fields->push_back(specific_field);
883 reporter_->ReportDeleted(message1, message2, *parent_fields); 877 reporter_->ReportDeleted(message1, message2, *parent_fields);
884 parent_fields->pop_back(); 878 parent_fields->pop_back();
885 fieldDifferent = true; 879 fieldDifferent = true;
886 } 880 }
887 return !fieldDifferent; 881 return !fieldDifferent;
888 } 882 }
889 883
890 bool MessageDifferencer::CompareFieldValue(const Message& message1, 884 bool MessageDifferencer::CompareFieldValue(const Message& message1,
891 const Message& message2, 885 const Message& message2,
892 const FieldDescriptor* field, 886 const FieldDescriptor* field,
893 int index1, 887 int index1,
894 int index2) { 888 int index2) {
895 return CompareFieldValueUsingParentFields(message1, message2, field, index1, 889 return CompareFieldValueUsingParentFields(message1, message2, field, index1,
896 index2, NULL); 890 index2, NULL);
897 } 891 }
898 892
899 bool MessageDifferencer::CompareFieldValueUsingParentFields( 893 bool MessageDifferencer::CompareFieldValueUsingParentFields(
900 const Message& message1, const Message& message2, 894 const Message& message1, const Message& message2,
901 const FieldDescriptor* field, int index1, int index2, 895 const FieldDescriptor* field, int index1, int index2,
902 std::vector<SpecificField>* parent_fields) { 896 vector<SpecificField>* parent_fields) {
903 FieldContext field_context(parent_fields); 897 FieldContext field_context(parent_fields);
904 FieldComparator::ComparisonResult result = GetFieldComparisonResult( 898 FieldComparator::ComparisonResult result = GetFieldComparisonResult(
905 message1, message2, field, index1, index2, &field_context); 899 message1, message2, field, index1, index2, &field_context);
906 900
907 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && 901 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
908 result == FieldComparator::RECURSE) { 902 result == FieldComparator::RECURSE) {
909 // Get the nested messages and compare them using one of the Compare 903 // Get the nested messages and compare them using one of the Compare
910 // methods. 904 // methods.
911 const Reflection* reflection1 = message1.GetReflection(); 905 const Reflection* reflection1 = message1.GetReflection();
912 const Reflection* reflection2 = message2.GetReflection(); 906 const Reflection* reflection2 = message2.GetReflection();
(...skipping 18 matching lines...) Expand all
931 } else { 925 } else {
932 // Recreates parent_fields as if m1 and m2 had no parents. 926 // Recreates parent_fields as if m1 and m2 had no parents.
933 return Compare(m1, m2); 927 return Compare(m1, m2);
934 } 928 }
935 } else { 929 } else {
936 return (result == FieldComparator::SAME); 930 return (result == FieldComparator::SAME);
937 } 931 }
938 } 932 }
939 933
940 bool MessageDifferencer::CheckPathChanged( 934 bool MessageDifferencer::CheckPathChanged(
941 const std::vector<SpecificField>& field_path) { 935 const vector<SpecificField>& field_path) {
942 for (int i = 0; i < field_path.size(); ++i) { 936 for (int i = 0; i < field_path.size(); ++i) {
943 if (field_path[i].index != field_path[i].new_index) return true; 937 if (field_path[i].index != field_path[i].new_index) return true;
944 } 938 }
945 return false; 939 return false;
946 } 940 }
947 941
948 bool MessageDifferencer::IsTreatedAsSet(const FieldDescriptor* field) { 942 bool MessageDifferencer::IsTreatedAsSet(const FieldDescriptor* field) {
949 if (!field->is_repeated()) return false; 943 if (!field->is_repeated()) return false;
950 if (field->is_map()) return true; 944 if (field->is_map()) return true;
951 if (repeated_field_comparison_ == AS_SET) 945 if (repeated_field_comparison_ == AS_SET)
952 return list_fields_.find(field) == list_fields_.end(); 946 return list_fields_.find(field) == list_fields_.end();
953 return (set_fields_.find(field) != set_fields_.end()); 947 return (set_fields_.find(field) != set_fields_.end());
954 } 948 }
955 949
956 bool MessageDifferencer::IsTreatedAsSubset(const FieldDescriptor* field) { 950 bool MessageDifferencer::IsTreatedAsSubset(const FieldDescriptor* field) {
957 return scope_ == PARTIAL && 951 return scope_ == PARTIAL &&
958 (IsTreatedAsSet(field) || GetMapKeyComparator(field) != NULL); 952 (IsTreatedAsSet(field) || GetMapKeyComparator(field) != NULL);
959 } 953 }
960 954
961 bool MessageDifferencer::IsIgnored( 955 bool MessageDifferencer::IsIgnored(
962 const Message& message1, 956 const Message& message1,
963 const Message& message2, 957 const Message& message2,
964 const FieldDescriptor* field, 958 const FieldDescriptor* field,
965 const std::vector<SpecificField>& parent_fields) { 959 const vector<SpecificField>& parent_fields) {
966 if (ignored_fields_.find(field) != ignored_fields_.end()) { 960 if (ignored_fields_.find(field) != ignored_fields_.end()) {
967 return true; 961 return true;
968 } 962 }
969 for (int i = 0; i < ignore_criteria_.size(); ++i) { 963 for (int i = 0; i < ignore_criteria_.size(); ++i) {
970 if (ignore_criteria_[i]->IsIgnored(message1, message2, field, 964 if (ignore_criteria_[i]->IsIgnored(message1, message2, field,
971 parent_fields)) { 965 parent_fields)) {
972 return true; 966 return true;
973 } 967 }
974 } 968 }
975 return false; 969 return false;
976 } 970 }
977 971
978 bool MessageDifferencer::IsUnknownFieldIgnored( 972 bool MessageDifferencer::IsUnknownFieldIgnored(
979 const Message& message1, const Message& message2, 973 const Message& message1, const Message& message2,
980 const SpecificField& field, 974 const SpecificField& field, const vector<SpecificField>& parent_fields) {
981 const std::vector<SpecificField>& parent_fields) {
982 for (int i = 0; i < ignore_criteria_.size(); ++i) { 975 for (int i = 0; i < ignore_criteria_.size(); ++i) {
983 if (ignore_criteria_[i]->IsUnknownFieldIgnored(message1, message2, field, 976 if (ignore_criteria_[i]->IsUnknownFieldIgnored(message1, message2, field,
984 parent_fields)) { 977 parent_fields)) {
985 return true; 978 return true;
986 } 979 }
987 } 980 }
988 return false; 981 return false;
989 } 982 }
990 983
991 const MessageDifferencer::MapKeyComparator* MessageDifferencer 984 const MessageDifferencer::MapKeyComparator* MessageDifferencer
992 ::GetMapKeyComparator(const FieldDescriptor* field) { 985 ::GetMapKeyComparator(const FieldDescriptor* field) {
993 if (!field->is_repeated()) return NULL; 986 if (!field->is_repeated()) return NULL;
994 if (map_field_key_comparator_.find(field) != 987 if (map_field_key_comparator_.find(field) !=
995 map_field_key_comparator_.end()) { 988 map_field_key_comparator_.end()) {
996 return map_field_key_comparator_[field]; 989 return map_field_key_comparator_[field];
997 } 990 }
998 return NULL; 991 return NULL;
999 } 992 }
1000 993
1001 namespace { 994 namespace {
1002 995
1003 typedef std::pair<int, const UnknownField*> IndexUnknownFieldPair; 996 typedef pair<int, const UnknownField*> IndexUnknownFieldPair;
1004 997
1005 struct UnknownFieldOrdering { 998 struct UnknownFieldOrdering {
1006 inline bool operator()(const IndexUnknownFieldPair& a, 999 inline bool operator()(const IndexUnknownFieldPair& a,
1007 const IndexUnknownFieldPair& b) const { 1000 const IndexUnknownFieldPair& b) const {
1008 if (a.second->number() < b.second->number()) return true; 1001 if (a.second->number() < b.second->number()) return true;
1009 if (a.second->number() > b.second->number()) return false; 1002 if (a.second->number() > b.second->number()) return false;
1010 return a.second->type() < b.second->type(); 1003 return a.second->type() < b.second->type();
1011 } 1004 }
1012 }; 1005 };
1013 1006
(...skipping 30 matching lines...) Expand all
1044 GOOGLE_DLOG(ERROR) << "Failed to parse value for " << full_type_name; 1037 GOOGLE_DLOG(ERROR) << "Failed to parse value for " << full_type_name;
1045 return false; 1038 return false;
1046 } 1039 }
1047 return true; 1040 return true;
1048 } 1041 }
1049 1042
1050 bool MessageDifferencer::CompareUnknownFields( 1043 bool MessageDifferencer::CompareUnknownFields(
1051 const Message& message1, const Message& message2, 1044 const Message& message1, const Message& message2,
1052 const google::protobuf::UnknownFieldSet& unknown_field_set1, 1045 const google::protobuf::UnknownFieldSet& unknown_field_set1,
1053 const google::protobuf::UnknownFieldSet& unknown_field_set2, 1046 const google::protobuf::UnknownFieldSet& unknown_field_set2,
1054 std::vector<SpecificField>* parent_field) { 1047 vector<SpecificField>* parent_field) {
1055 // Ignore unknown fields in EQUIVALENT mode. 1048 // Ignore unknown fields in EQUIVALENT mode.
1056 if (message_field_comparison_ == EQUIVALENT) return true; 1049 if (message_field_comparison_ == EQUIVALENT) return true;
1057 1050
1058 if (unknown_field_set1.empty() && unknown_field_set2.empty()) { 1051 if (unknown_field_set1.empty() && unknown_field_set2.empty()) {
1059 return true; 1052 return true;
1060 } 1053 }
1061 1054
1062 bool is_different = false; 1055 bool is_different = false;
1063 1056
1064 // We first sort the unknown fields by field number and type (in other words, 1057 // We first sort the unknown fields by field number and type (in other words,
1065 // in tag order), making sure to preserve ordering of values with the same 1058 // in tag order), making sure to preserve ordering of values with the same
1066 // tag. This allows us to report only meaningful differences between the 1059 // tag. This allows us to report only meaningful differences between the
1067 // two sets -- that is, differing values for the same tag. We use 1060 // two sets -- that is, differing values for the same tag. We use
1068 // IndexUnknownFieldPairs to keep track of the field's original index for 1061 // IndexUnknownFieldPairs to keep track of the field's original index for
1069 // reporting purposes. 1062 // reporting purposes.
1070 std::vector<IndexUnknownFieldPair> fields1; // unknown_field_set1, sorted 1063 vector<IndexUnknownFieldPair> fields1; // unknown_field_set1, sorted
1071 std::vector<IndexUnknownFieldPair> fields2; // unknown_field_set2, sorted 1064 vector<IndexUnknownFieldPair> fields2; // unknown_field_set2, sorted
1072 fields1.reserve(unknown_field_set1.field_count()); 1065 fields1.reserve(unknown_field_set1.field_count());
1073 fields2.reserve(unknown_field_set2.field_count()); 1066 fields2.reserve(unknown_field_set2.field_count());
1074 1067
1075 for (int i = 0; i < unknown_field_set1.field_count(); i++) { 1068 for (int i = 0; i < unknown_field_set1.field_count(); i++) {
1076 fields1.push_back(std::make_pair(i, &unknown_field_set1.field(i))); 1069 fields1.push_back(std::make_pair(i, &unknown_field_set1.field(i)));
1077 } 1070 }
1078 for (int i = 0; i < unknown_field_set2.field_count(); i++) { 1071 for (int i = 0; i < unknown_field_set2.field_count(); i++) {
1079 fields2.push_back(std::make_pair(i, &unknown_field_set2.field(i))); 1072 fields2.push_back(std::make_pair(i, &unknown_field_set2.field(i)));
1080 } 1073 }
1081 1074
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
1264 // determine whether a node on the left side of the bipartial graph matches 1257 // determine whether a node on the left side of the bipartial graph matches
1265 // a node on the right side. count1 is the number of nodes on the left side 1258 // a node on the right side. count1 is the number of nodes on the left side
1266 // of the graph and count2 to is the number of nodes on the right side. 1259 // of the graph and count2 to is the number of nodes on the right side.
1267 // Every node is referred to using 0-based indices. 1260 // Every node is referred to using 0-based indices.
1268 // If a maximum match is found, the result will be stored in match_list1 and 1261 // If a maximum match is found, the result will be stored in match_list1 and
1269 // match_list2. match_list1[i] == j means the i-th node on the left side is 1262 // match_list2. match_list1[i] == j means the i-th node on the left side is
1270 // matched to the j-th node on the right side and match_list2[x] == y means 1263 // matched to the j-th node on the right side and match_list2[x] == y means
1271 // the x-th node on the right side is matched to y-th node on the left side. 1264 // the x-th node on the right side is matched to y-th node on the left side.
1272 // match_list1[i] == -1 means the node is not matched. Same with match_list2. 1265 // match_list1[i] == -1 means the node is not matched. Same with match_list2.
1273 MaximumMatcher(int count1, int count2, NodeMatchCallback* callback, 1266 MaximumMatcher(int count1, int count2, NodeMatchCallback* callback,
1274 std::vector<int>* match_list1, std::vector<int>* match_list2); 1267 vector<int>* match_list1, vector<int>* match_list2);
1275 // Find a maximum match and return the number of matched node pairs. 1268 // Find a maximum match and return the number of matched node pairs.
1276 // If early_return is true, this method will return 0 immediately when it 1269 // If early_return is true, this method will return 0 immediately when it
1277 // finds that not all nodes on the left side can be matched. 1270 // finds that not all nodes on the left side can be matched.
1278 int FindMaximumMatch(bool early_return); 1271 int FindMaximumMatch(bool early_return);
1279 private: 1272 private:
1280 // Determines whether the node on the left side of the bipartial graph 1273 // Determines whether the node on the left side of the bipartial graph
1281 // matches the one on the right side. 1274 // matches the one on the right side.
1282 bool Match(int left, int right); 1275 bool Match(int left, int right);
1283 // Find an argumenting path starting from the node v on the left side. If a 1276 // Find an argumenting path starting from the node v on the left side. If a
1284 // path can be found, update match_list2_ to reflect the path and return 1277 // path can be found, update match_list2_ to reflect the path and return
1285 // true. 1278 // true.
1286 bool FindArgumentPathDFS(int v, std::vector<bool>* visited); 1279 bool FindArgumentPathDFS(int v, vector<bool>* visited);
1287 1280
1288 int count1_; 1281 int count1_;
1289 int count2_; 1282 int count2_;
1290 google::protobuf::scoped_ptr<NodeMatchCallback> match_callback_; 1283 google::protobuf::scoped_ptr<NodeMatchCallback> match_callback_;
1291 std::map<std::pair<int, int>, bool> cached_match_results_; 1284 map<pair<int, int>, bool> cached_match_results_;
1292 std::vector<int>* match_list1_; 1285 vector<int>* match_list1_;
1293 std::vector<int>* match_list2_; 1286 vector<int>* match_list2_;
1294 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MaximumMatcher); 1287 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MaximumMatcher);
1295 }; 1288 };
1296 1289
1297 MaximumMatcher::MaximumMatcher(int count1, int count2, 1290 MaximumMatcher::MaximumMatcher(int count1, int count2,
1298 NodeMatchCallback* callback, 1291 NodeMatchCallback* callback,
1299 std::vector<int>* match_list1, 1292 vector<int>* match_list1,
1300 std::vector<int>* match_list2) 1293 vector<int>* match_list2)
1301 : count1_(count1), count2_(count2), match_callback_(callback), 1294 : count1_(count1), count2_(count2), match_callback_(callback),
1302 match_list1_(match_list1), match_list2_(match_list2) { 1295 match_list1_(match_list1), match_list2_(match_list2) {
1303 match_list1_->assign(count1, -1); 1296 match_list1_->assign(count1, -1);
1304 match_list2_->assign(count2, -1); 1297 match_list2_->assign(count2, -1);
1305 } 1298 }
1306 1299
1307 int MaximumMatcher::FindMaximumMatch(bool early_return) { 1300 int MaximumMatcher::FindMaximumMatch(bool early_return) {
1308 int result = 0; 1301 int result = 0;
1309 for (int i = 0; i < count1_; ++i) { 1302 for (int i = 0; i < count1_; ++i) {
1310 std::vector<bool> visited(count1_); 1303 vector<bool> visited(count1_);
1311 if (FindArgumentPathDFS(i, &visited)) { 1304 if (FindArgumentPathDFS(i, &visited)) {
1312 ++result; 1305 ++result;
1313 } else if (early_return) { 1306 } else if (early_return) {
1314 return 0; 1307 return 0;
1315 } 1308 }
1316 } 1309 }
1317 // Backfill match_list1_ as we only filled match_list2_ when finding 1310 // Backfill match_list1_ as we only filled match_list2_ when finding
1318 // argumenting pathes. 1311 // argumenting pathes.
1319 for (int i = 0; i < count2_; ++i) { 1312 for (int i = 0; i < count2_; ++i) {
1320 if ((*match_list2_)[i] != -1) { 1313 if ((*match_list2_)[i] != -1) {
1321 (*match_list1_)[(*match_list2_)[i]] = i; 1314 (*match_list1_)[(*match_list2_)[i]] = i;
1322 } 1315 }
1323 } 1316 }
1324 return result; 1317 return result;
1325 } 1318 }
1326 1319
1327 bool MaximumMatcher::Match(int left, int right) { 1320 bool MaximumMatcher::Match(int left, int right) {
1328 std::pair<int, int> p(left, right); 1321 pair<int, int> p(left, right);
1329 std::map<std::pair<int, int>, bool>::iterator it = 1322 map<pair<int, int>, bool>::iterator it = cached_match_results_.find(p);
1330 cached_match_results_.find(p);
1331 if (it != cached_match_results_.end()) { 1323 if (it != cached_match_results_.end()) {
1332 return it->second; 1324 return it->second;
1333 } 1325 }
1334 cached_match_results_[p] = match_callback_->Run(left, right); 1326 cached_match_results_[p] = match_callback_->Run(left, right);
1335 return cached_match_results_[p]; 1327 return cached_match_results_[p];
1336 } 1328 }
1337 1329
1338 bool MaximumMatcher::FindArgumentPathDFS(int v, std::vector<bool>* visited) { 1330 bool MaximumMatcher::FindArgumentPathDFS(int v, vector<bool>* visited) {
1339 (*visited)[v] = true; 1331 (*visited)[v] = true;
1340 // We try to match those un-matched nodes on the right side first. This is 1332 // We try to match those un-matched nodes on the right side first. This is
1341 // the step that the navie greedy matching algorithm uses. In the best cases 1333 // the step that the navie greedy matching algorithm uses. In the best cases
1342 // where the greedy algorithm can find a maximum matching, we will always 1334 // where the greedy algorithm can find a maximum matching, we will always
1343 // find a match in this step and the performance will be identical to the 1335 // find a match in this step and the performance will be identical to the
1344 // greedy algorithm. 1336 // greedy algorithm.
1345 for (int i = 0; i < count2_; ++i) { 1337 for (int i = 0; i < count2_; ++i) {
1346 int matched = (*match_list2_)[i]; 1338 int matched = (*match_list2_)[i];
1347 if (matched == -1 && Match(v, i)) { 1339 if (matched == -1 && Match(v, i)) {
1348 (*match_list2_)[i] = v; 1340 (*match_list2_)[i] = v;
(...skipping 15 matching lines...) Expand all
1364 } 1356 }
1365 return false; 1357 return false;
1366 } 1358 }
1367 1359
1368 } // namespace 1360 } // namespace
1369 1361
1370 bool MessageDifferencer::MatchRepeatedFieldIndices( 1362 bool MessageDifferencer::MatchRepeatedFieldIndices(
1371 const Message& message1, 1363 const Message& message1,
1372 const Message& message2, 1364 const Message& message2,
1373 const FieldDescriptor* repeated_field, 1365 const FieldDescriptor* repeated_field,
1374 const std::vector<SpecificField>& parent_fields, 1366 const vector<SpecificField>& parent_fields,
1375 std::vector<int>* match_list1, 1367 vector<int>* match_list1,
1376 std::vector<int>* match_list2) { 1368 vector<int>* match_list2) {
1377 const int count1 = 1369 const int count1 =
1378 message1.GetReflection()->FieldSize(message1, repeated_field); 1370 message1.GetReflection()->FieldSize(message1, repeated_field);
1379 const int count2 = 1371 const int count2 =
1380 message2.GetReflection()->FieldSize(message2, repeated_field); 1372 message2.GetReflection()->FieldSize(message2, repeated_field);
1381 const MapKeyComparator* key_comparator = GetMapKeyComparator(repeated_field); 1373 const MapKeyComparator* key_comparator = GetMapKeyComparator(repeated_field);
1382 1374
1383 match_list1->assign(count1, -1); 1375 match_list1->assign(count1, -1);
1384 match_list2->assign(count2, -1); 1376 match_list2->assign(count2, -1);
1385 1377
1386 SpecificField specific_field; 1378 SpecificField specific_field;
1387 specific_field.field = repeated_field; 1379 specific_field.field = repeated_field;
1388 1380
1389 bool success = true; 1381 bool success = true;
1390 // Find potential match if this is a special repeated field. 1382 // Find potential match if this is a special repeated field.
1391 if (key_comparator != NULL || IsTreatedAsSet(repeated_field)) { 1383 if (key_comparator != NULL || IsTreatedAsSet(repeated_field)) {
1392 if (scope_ == PARTIAL) { 1384 if (scope_ == PARTIAL) {
1393 // When partial matching is enabled, Compare(a, b) && Compare(a, c) 1385 // When partial matching is enabled, Compare(a, b) && Compare(a, c)
1394 // doesn't necessarily imply Compare(b, c). Therefore a naive greedy 1386 // doesn't neccessarily imply Compare(b, c). Therefore a naive greedy
1395 // algorithm will fail to find a maximum matching. 1387 // algorithm will fail to find a maximum matching.
1396 // Here we use the argumenting path algorithm. 1388 // Here we use the argumenting path algorithm.
1397 MaximumMatcher::NodeMatchCallback* callback = 1389 MaximumMatcher::NodeMatchCallback* callback =
1398 NewPermanentCallback( 1390 ::google::protobuf::internal::NewPermanentCallback(
1399 this, &MessageDifferencer::IsMatch, 1391 this, &MessageDifferencer::IsMatch,
1400 repeated_field, key_comparator, 1392 repeated_field, key_comparator,
1401 &message1, &message2, parent_fields); 1393 &message1, &message2, parent_fields);
1402 MaximumMatcher matcher(count1, count2, callback, match_list1, 1394 MaximumMatcher matcher(count1, count2, callback, match_list1,
1403 match_list2); 1395 match_list2);
1404 // If diff info is not needed, we should end the matching process as 1396 // If diff info is not needed, we should end the matching process as
1405 // soon as possible if not all items can be matched. 1397 // soon as possible if not all items can be matched.
1406 bool early_return = (reporter_ == NULL); 1398 bool early_return = (reporter_ == NULL);
1407 int match_count = matcher.FindMaximumMatch(early_return); 1399 int match_count = matcher.FindMaximumMatch(early_return);
1408 if (match_count != count1 && reporter_ == NULL) return false; 1400 if (match_count != count1 && reporter_ == NULL) return false;
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1481 MessageDifferencer::StreamReporter::StreamReporter( 1473 MessageDifferencer::StreamReporter::StreamReporter(
1482 io::Printer* printer) : printer_(printer), 1474 io::Printer* printer) : printer_(printer),
1483 delete_printer_(false), 1475 delete_printer_(false),
1484 report_modified_aggregates_(false) { } 1476 report_modified_aggregates_(false) { }
1485 1477
1486 MessageDifferencer::StreamReporter::~StreamReporter() { 1478 MessageDifferencer::StreamReporter::~StreamReporter() {
1487 if (delete_printer_) delete printer_; 1479 if (delete_printer_) delete printer_;
1488 } 1480 }
1489 1481
1490 void MessageDifferencer::StreamReporter::PrintPath( 1482 void MessageDifferencer::StreamReporter::PrintPath(
1491 const std::vector<SpecificField>& field_path, bool left_side) { 1483 const vector<SpecificField>& field_path, bool left_side) {
1492 for (int i = 0; i < field_path.size(); ++i) { 1484 for (int i = 0; i < field_path.size(); ++i) {
1493 if (i > 0) { 1485 if (i > 0) {
1494 printer_->Print("."); 1486 printer_->Print(".");
1495 } 1487 }
1496 1488
1497 SpecificField specific_field = field_path[i]; 1489 SpecificField specific_field = field_path[i];
1498 1490
1499 if (specific_field.field != NULL) { 1491 if (specific_field.field != NULL) {
1500 if (specific_field.field->is_extension()) { 1492 if (specific_field.field->is_extension()) {
1501 printer_->Print("($name$)", "name", 1493 printer_->Print("($name$)", "name",
1502 specific_field.field->full_name()); 1494 specific_field.field->full_name());
1503 } else { 1495 } else {
1504 printer_->PrintRaw(specific_field.field->name()); 1496 printer_->PrintRaw(specific_field.field->name());
1505 } 1497 }
1506 } else { 1498 } else {
1507 printer_->PrintRaw(SimpleItoa(specific_field.unknown_field_number)); 1499 printer_->PrintRaw(SimpleItoa(specific_field.unknown_field_number));
1508 } 1500 }
1509 if (left_side && specific_field.index >= 0) { 1501 if (left_side && specific_field.index >= 0) {
1510 printer_->Print("[$name$]", "name", SimpleItoa(specific_field.index)); 1502 printer_->Print("[$name$]", "name", SimpleItoa(specific_field.index));
1511 } 1503 }
1512 if (!left_side && specific_field.new_index >= 0) { 1504 if (!left_side && specific_field.new_index >= 0) {
1513 printer_->Print("[$name$]", "name", SimpleItoa(specific_field.new_index)); 1505 printer_->Print("[$name$]", "name", SimpleItoa(specific_field.new_index));
1514 } 1506 }
1515 } 1507 }
1516 } 1508 }
1517 1509
1518 void MessageDifferencer:: 1510 void MessageDifferencer::
1519 StreamReporter::PrintValue(const Message& message, 1511 StreamReporter::PrintValue(const Message& message,
1520 const std::vector<SpecificField>& field_path, 1512 const vector<SpecificField>& field_path,
1521 bool left_side) { 1513 bool left_side) {
1522 const SpecificField& specific_field = field_path.back(); 1514 const SpecificField& specific_field = field_path.back();
1523 const FieldDescriptor* field = specific_field.field; 1515 const FieldDescriptor* field = specific_field.field;
1524 if (field != NULL) { 1516 if (field != NULL) {
1525 string output; 1517 string output;
1526 int index = left_side ? specific_field.index : specific_field.new_index; 1518 int index = left_side ? specific_field.index : specific_field.new_index;
1527 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 1519 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
1528 const Reflection* reflection = message.GetReflection(); 1520 const Reflection* reflection = message.GetReflection();
1529 const Message& field_message = field->is_repeated() ? 1521 const Message& field_message = field->is_repeated() ?
1530 reflection->GetRepeatedMessage(message, field, index) : 1522 reflection->GetRepeatedMessage(message, field, index) :
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1583 printer_->PrintRaw(output); 1575 printer_->PrintRaw(output);
1584 } 1576 }
1585 1577
1586 void MessageDifferencer::StreamReporter::Print(const string& str) { 1578 void MessageDifferencer::StreamReporter::Print(const string& str) {
1587 printer_->Print(str.c_str()); 1579 printer_->Print(str.c_str());
1588 } 1580 }
1589 1581
1590 void MessageDifferencer::StreamReporter::ReportAdded( 1582 void MessageDifferencer::StreamReporter::ReportAdded(
1591 const Message& message1, 1583 const Message& message1,
1592 const Message& message2, 1584 const Message& message2,
1593 const std::vector<SpecificField>& field_path) { 1585 const vector<SpecificField>& field_path) {
1594 printer_->Print("added: "); 1586 printer_->Print("added: ");
1595 PrintPath(field_path, false); 1587 PrintPath(field_path, false);
1596 printer_->Print(": "); 1588 printer_->Print(": ");
1597 PrintValue(message2, field_path, false); 1589 PrintValue(message2, field_path, false);
1598 printer_->Print("\n"); // Print for newlines. 1590 printer_->Print("\n"); // Print for newlines.
1599 } 1591 }
1600 1592
1601 void MessageDifferencer::StreamReporter::ReportDeleted( 1593 void MessageDifferencer::StreamReporter::ReportDeleted(
1602 const Message& message1, 1594 const Message& message1,
1603 const Message& message2, 1595 const Message& message2,
1604 const std::vector<SpecificField>& field_path) { 1596 const vector<SpecificField>& field_path) {
1605 printer_->Print("deleted: "); 1597 printer_->Print("deleted: ");
1606 PrintPath(field_path, true); 1598 PrintPath(field_path, true);
1607 printer_->Print(": "); 1599 printer_->Print(": ");
1608 PrintValue(message1, field_path, true); 1600 PrintValue(message1, field_path, true);
1609 printer_->Print("\n"); // Print for newlines 1601 printer_->Print("\n"); // Print for newlines
1610 } 1602 }
1611 1603
1612 void MessageDifferencer::StreamReporter::ReportModified( 1604 void MessageDifferencer::StreamReporter::ReportModified(
1613 const Message& message1, 1605 const Message& message1,
1614 const Message& message2, 1606 const Message& message2,
1615 const std::vector<SpecificField>& field_path) { 1607 const vector<SpecificField>& field_path) {
1616 if (!report_modified_aggregates_ && field_path.back().field == NULL) { 1608 if (!report_modified_aggregates_ && field_path.back().field == NULL) {
1617 if (field_path.back().unknown_field_type == UnknownField::TYPE_GROUP) { 1609 if (field_path.back().unknown_field_type == UnknownField::TYPE_GROUP) {
1618 // Any changes to the subfields have already been printed. 1610 // Any changes to the subfields have already been printed.
1619 return; 1611 return;
1620 } 1612 }
1621 } else if (!report_modified_aggregates_) { 1613 } else if (!report_modified_aggregates_) {
1622 if (field_path.back().field->cpp_type() == 1614 if (field_path.back().field->cpp_type() ==
1623 FieldDescriptor::CPPTYPE_MESSAGE) { 1615 FieldDescriptor::CPPTYPE_MESSAGE) {
1624 // Any changes to the subfields have already been printed. 1616 // Any changes to the subfields have already been printed.
1625 return; 1617 return;
1626 } 1618 }
1627 } 1619 }
1628 1620
1629 printer_->Print("modified: "); 1621 printer_->Print("modified: ");
1630 PrintPath(field_path, true); 1622 PrintPath(field_path, true);
1631 if (CheckPathChanged(field_path)) { 1623 if (CheckPathChanged(field_path)) {
1632 printer_->Print(" -> "); 1624 printer_->Print(" -> ");
1633 PrintPath(field_path, false); 1625 PrintPath(field_path, false);
1634 } 1626 }
1635 printer_->Print(": "); 1627 printer_->Print(": ");
1636 PrintValue(message1, field_path, true); 1628 PrintValue(message1, field_path, true);
1637 printer_->Print(" -> "); 1629 printer_->Print(" -> ");
1638 PrintValue(message2, field_path, false); 1630 PrintValue(message2, field_path, false);
1639 printer_->Print("\n"); // Print for newlines. 1631 printer_->Print("\n"); // Print for newlines.
1640 } 1632 }
1641 1633
1642 void MessageDifferencer::StreamReporter::ReportMoved( 1634 void MessageDifferencer::StreamReporter::ReportMoved(
1643 const Message& message1, 1635 const Message& message1,
1644 const Message& message2, 1636 const Message& message2,
1645 const std::vector<SpecificField>& field_path) { 1637 const vector<SpecificField>& field_path) {
1646 printer_->Print("moved: "); 1638 printer_->Print("moved: ");
1647 PrintPath(field_path, true); 1639 PrintPath(field_path, true);
1648 printer_->Print(" -> "); 1640 printer_->Print(" -> ");
1649 PrintPath(field_path, false); 1641 PrintPath(field_path, false);
1650 printer_->Print(" : "); 1642 printer_->Print(" : ");
1651 PrintValue(message1, field_path, true); 1643 PrintValue(message1, field_path, true);
1652 printer_->Print("\n"); // Print for newlines. 1644 printer_->Print("\n"); // Print for newlines.
1653 } 1645 }
1654 1646
1655 void MessageDifferencer::StreamReporter::ReportMatched( 1647 void MessageDifferencer::StreamReporter::ReportMatched(
1656 const Message& message1, 1648 const Message& message1,
1657 const Message& message2, 1649 const Message& message2,
1658 const std::vector<SpecificField>& field_path) { 1650 const vector<SpecificField>& field_path) {
1659 printer_->Print("matched: "); 1651 printer_->Print("matched: ");
1660 PrintPath(field_path, true); 1652 PrintPath(field_path, true);
1661 if (CheckPathChanged(field_path)) { 1653 if (CheckPathChanged(field_path)) {
1662 printer_->Print(" -> "); 1654 printer_->Print(" -> ");
1663 PrintPath(field_path, false); 1655 PrintPath(field_path, false);
1664 } 1656 }
1665 printer_->Print(" : "); 1657 printer_->Print(" : ");
1666 PrintValue(message1, field_path, true); 1658 PrintValue(message1, field_path, true);
1667 printer_->Print("\n"); // Print for newlines. 1659 printer_->Print("\n"); // Print for newlines.
1668 } 1660 }
1669 1661
1670 void MessageDifferencer::StreamReporter::ReportIgnored( 1662 void MessageDifferencer::StreamReporter::ReportIgnored(
1671 const Message& message1, 1663 const Message& message1,
1672 const Message& message2, 1664 const Message& message2,
1673 const std::vector<SpecificField>& field_path) { 1665 const vector<SpecificField>& field_path) {
1674 printer_->Print("ignored: "); 1666 printer_->Print("ignored: ");
1675 PrintPath(field_path, true); 1667 PrintPath(field_path, true);
1676 if (CheckPathChanged(field_path)) { 1668 if (CheckPathChanged(field_path)) {
1677 printer_->Print(" -> "); 1669 printer_->Print(" -> ");
1678 PrintPath(field_path, false); 1670 PrintPath(field_path, false);
1679 } 1671 }
1680 printer_->Print("\n"); // Print for newlines. 1672 printer_->Print("\n"); // Print for newlines.
1681 } 1673 }
1682 1674
1683 void MessageDifferencer::StreamReporter::ReportUnknownFieldIgnored( 1675 void MessageDifferencer::StreamReporter::ReportUnknownFieldIgnored(
1684 const Message& message1, const Message& message2, 1676 const Message& message1, const Message& message2,
1685 const std::vector<SpecificField>& field_path) { 1677 const vector<SpecificField>& field_path) {
1686 printer_->Print("ignored: "); 1678 printer_->Print("ignored: ");
1687 PrintPath(field_path, true); 1679 PrintPath(field_path, true);
1688 if (CheckPathChanged(field_path)) { 1680 if (CheckPathChanged(field_path)) {
1689 printer_->Print(" -> "); 1681 printer_->Print(" -> ");
1690 PrintPath(field_path, false); 1682 PrintPath(field_path, false);
1691 } 1683 }
1692 printer_->Print("\n"); // Print for newlines. 1684 printer_->Print("\n"); // Print for newlines.
1693 } 1685 }
1694 1686
1695 } // namespace util 1687 } // namespace util
1696 } // namespace protobuf 1688 } // namespace protobuf
1697 } // namespace google 1689 } // namespace google
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698