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

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

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

Powered by Google App Engine
This is Rietveld 408576698