OLD | NEW |
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 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 // itself and the second will be the actual field in the embedded message | 214 // itself and the second will be the actual field in the embedded message |
215 // that was added/deleted/modified. | 215 // that was added/deleted/modified. |
216 class LIBPROTOBUF_EXPORT Reporter { | 216 class LIBPROTOBUF_EXPORT Reporter { |
217 public: | 217 public: |
218 Reporter(); | 218 Reporter(); |
219 virtual ~Reporter(); | 219 virtual ~Reporter(); |
220 | 220 |
221 // Reports that a field has been added into Message2. | 221 // Reports that a field has been added into Message2. |
222 virtual void ReportAdded( | 222 virtual void ReportAdded( |
223 const Message& message1, const Message& message2, | 223 const Message& message1, const Message& message2, |
224 const std::vector<SpecificField>& field_path) = 0; | 224 const vector<SpecificField>& field_path) = 0; |
225 | 225 |
226 // Reports that a field has been deleted from Message1. | 226 // Reports that a field has been deleted from Message1. |
227 virtual void ReportDeleted( | 227 virtual void ReportDeleted( |
228 const Message& message1, | 228 const Message& message1, |
229 const Message& message2, | 229 const Message& message2, |
230 const std::vector<SpecificField>& field_path) = 0; | 230 const vector<SpecificField>& field_path) = 0; |
231 | 231 |
232 // Reports that the value of a field has been modified. | 232 // Reports that the value of a field has been modified. |
233 virtual void ReportModified( | 233 virtual void ReportModified( |
234 const Message& message1, | 234 const Message& message1, |
235 const Message& message2, | 235 const Message& message2, |
236 const std::vector<SpecificField>& field_path) = 0; | 236 const vector<SpecificField>& field_path) = 0; |
237 | 237 |
238 // Reports that a repeated field has been moved to another location. This | 238 // Reports that a repeated field has been moved to another location. This |
239 // only applies when using TreatAsSet or TreatAsMap() -- see below. Also | 239 // only applies when using TreatAsSet or TreatAsMap() -- see below. Also |
240 // note that for any given field, ReportModified and ReportMoved are | 240 // note that for any given field, ReportModified and ReportMoved are |
241 // mutually exclusive. If a field has been both moved and modified, then | 241 // mutually exclusive. If a field has been both moved and modified, then |
242 // only ReportModified will be called. | 242 // only ReportModified will be called. |
243 virtual void ReportMoved( | 243 virtual void ReportMoved( |
244 const Message& message1, | 244 const Message& message1, |
245 const Message& message2, | 245 const Message& message2, |
246 const std::vector<SpecificField>& field_path) { } | 246 const vector<SpecificField>& field_path) { } |
247 | 247 |
248 // Reports that two fields match. Useful for doing side-by-side diffs. | 248 // Reports that two fields match. Useful for doing side-by-side diffs. |
249 // This function is mutually exclusive with ReportModified and ReportMoved. | 249 // This function is mutually exclusive with ReportModified and ReportMoved. |
250 // Note that you must call set_report_matches(true) before calling Compare | 250 // Note that you must call set_report_matches(true) before calling Compare |
251 // to make use of this function. | 251 // to make use of this function. |
252 virtual void ReportMatched( | 252 virtual void ReportMatched( |
253 const Message& message1, | 253 const Message& message1, |
254 const Message& message2, | 254 const Message& message2, |
255 const std::vector<SpecificField>& field_path) { } | 255 const vector<SpecificField>& field_path) { } |
256 | 256 |
257 // Reports that two fields would have been compared, but the | 257 // Reports that two fields would have been compared, but the |
258 // comparison has been skipped because the field was marked as | 258 // comparison has been skipped because the field was marked as |
259 // 'ignored' using IgnoreField(). This function is mutually | 259 // 'ignored' using IgnoreField(). This function is mutually |
260 // exclusive with all the other Report() functions. | 260 // exclusive with all the other Report() functions. |
261 // | 261 // |
262 // The contract of ReportIgnored is slightly different than the | 262 // The contract of ReportIgnored is slightly different than the |
263 // other Report() functions, in that |field_path.back().index| is | 263 // other Report() functions, in that |field_path.back().index| is |
264 // always equal to -1, even if the last field is repeated. This is | 264 // always equal to -1, even if the last field is repeated. This is |
265 // because while the other Report() functions indicate where in a | 265 // because while the other Report() functions indicate where in a |
266 // repeated field the action (Addition, Deletion, etc...) | 266 // repeated field the action (Addition, Deletion, etc...) |
267 // happened, when a repeated field is 'ignored', the differencer | 267 // happened, when a repeated field is 'ignored', the differencer |
268 // simply calls ReportIgnored on the repeated field as a whole and | 268 // simply calls ReportIgnored on the repeated field as a whole and |
269 // moves on without looking at its individual elements. | 269 // moves on without looking at its individual elements. |
270 // | 270 // |
271 // Furthermore, ReportIgnored() does not indicate whether the | 271 // Furthermore, ReportIgnored() does not indicate whether the |
272 // fields were in fact equal or not, as Compare() does not inspect | 272 // fields were in fact equal or not, as Compare() does not inspect |
273 // these fields at all. It is up to the Reporter to decide whether | 273 // these fields at all. It is up to the Reporter to decide whether |
274 // the fields are equal or not (perhaps with a second call to | 274 // the fields are equal or not (perhaps with a second call to |
275 // Compare()), if it cares. | 275 // Compare()), if it cares. |
276 virtual void ReportIgnored( | 276 virtual void ReportIgnored( |
277 const Message& message1, | 277 const Message& message1, |
278 const Message& message2, | 278 const Message& message2, |
279 const std::vector<SpecificField>& field_path) { } | 279 const vector<SpecificField>& field_path) { } |
280 | 280 |
281 // Report that an unknown field is ignored. (see comment above). | 281 // Report that an unkown field is ignored. (see comment above). |
282 // Note this is a different function since the last SpecificField in field | 282 // Note this is a different function since the last SpecificField in field |
283 // path has a null field. This could break existing Reporter. | 283 // path has a null field. This could break existing Reporter. |
284 virtual void ReportUnknownFieldIgnored( | 284 virtual void ReportUnknownFieldIgnored( |
285 const Message& message1, const Message& message2, | 285 const Message& message1, const Message& message2, |
286 const std::vector<SpecificField>& field_path) {} | 286 const vector<SpecificField>& field_path) {} |
287 | 287 |
288 private: | 288 private: |
289 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Reporter); | 289 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Reporter); |
290 }; | 290 }; |
291 | 291 |
292 // MapKeyComparator is used to determine if two elements have the same key | 292 // MapKeyComparator is used to determine if two elements have the same key |
293 // when comparing elements of a repeated field as a map. | 293 // when comparing elements of a repeated field as a map. |
294 class LIBPROTOBUF_EXPORT MapKeyComparator { | 294 class LIBPROTOBUF_EXPORT MapKeyComparator { |
295 public: | 295 public: |
296 MapKeyComparator(); | 296 MapKeyComparator(); |
297 virtual ~MapKeyComparator(); | 297 virtual ~MapKeyComparator(); |
298 | 298 |
299 virtual bool IsMatch( | 299 virtual bool IsMatch(const Message& message1, |
300 const Message& message1, | 300 const Message& message2, |
301 const Message& message2, | 301 const vector<SpecificField>& parent_fields) const { |
302 const std::vector<SpecificField>& parent_fields) const { | |
303 GOOGLE_CHECK(false) << "IsMatch() is not implemented."; | 302 GOOGLE_CHECK(false) << "IsMatch() is not implemented."; |
304 return false; | 303 return false; |
305 } | 304 } |
306 | 305 |
307 private: | 306 private: |
308 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapKeyComparator); | 307 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapKeyComparator); |
309 }; | 308 }; |
310 | 309 |
311 // Abstract base class from which all IgnoreCriteria derive. | 310 // Abstract base class from which all IgnoreCriteria derive. |
312 // By adding IgnoreCriteria more complex ignore logic can be implemented. | 311 // By adding IgnoreCriteria more complex ignore logic can be implemented. |
313 // IgnoreCriteria are registed with AddIgnoreCriteria. For each compared | 312 // IgnoreCriteria are registed with AddIgnoreCriteria. For each compared |
314 // field IsIgnored is called on each added IgnoreCriteria until one returns | 313 // field IsIgnored is called on each added IgnoreCriteria until one returns |
315 // true or all return false. | 314 // true or all return false. |
316 // IsIgnored is called for fields where at least one side has a value. | 315 // IsIgnored is called for fields where at least one side has a value. |
317 class LIBPROTOBUF_EXPORT IgnoreCriteria { | 316 class LIBPROTOBUF_EXPORT IgnoreCriteria { |
318 public: | 317 public: |
319 IgnoreCriteria(); | 318 IgnoreCriteria(); |
320 virtual ~IgnoreCriteria(); | 319 virtual ~IgnoreCriteria(); |
321 | 320 |
322 // Returns true if the field should be ignored. | 321 // Returns true if the field should be ignored. |
323 virtual bool IsIgnored( | 322 virtual bool IsIgnored( |
324 const Message& message1, | 323 const Message& message1, |
325 const Message& message2, | 324 const Message& message2, |
326 const FieldDescriptor* field, | 325 const FieldDescriptor* field, |
327 const std::vector<SpecificField>& parent_fields) = 0; | 326 const vector<SpecificField>& parent_fields) = 0; |
328 | 327 |
329 // Returns true if the unknown field should be ignored. | 328 // Returns true if the unknown field should be ignored. |
330 // Note: This will be called for unknown fields as well in which case | 329 // Note: This will be called for unknown fields as well in which case |
331 // field.field will be null. | 330 // field.field will be null. |
332 virtual bool IsUnknownFieldIgnored( | 331 virtual bool IsUnknownFieldIgnored( |
333 const Message& message1, const Message& message2, | 332 const Message& message1, const Message& message2, |
334 const SpecificField& field, | 333 const SpecificField& field, |
335 const std::vector<SpecificField>& parent_fields) { | 334 const vector<SpecificField>& parent_fields) { |
336 return false; | 335 return false; |
337 } | 336 } |
338 }; | 337 }; |
339 | 338 |
340 // To add a Reporter, construct default here, then use ReportDifferencesTo or | 339 // To add a Reporter, construct default here, then use ReportDifferencesTo or |
341 // ReportDifferencesToString. | 340 // ReportDifferencesToString. |
342 explicit MessageDifferencer(); | 341 explicit MessageDifferencer(); |
343 | 342 |
344 ~MessageDifferencer(); | 343 ~MessageDifferencer(); |
345 | 344 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 // comparison. Those pairs of elements with the same key (with equal value | 433 // comparison. Those pairs of elements with the same key (with equal value |
435 // for every field in 'key_fields') will be compared in this step. | 434 // for every field in 'key_fields') will be compared in this step. |
436 // Time complexity of the first step is O(s * m * n ^ 2) where s is the | 435 // Time complexity of the first step is O(s * m * n ^ 2) where s is the |
437 // average size of the fields specified in 'key_fields', m is the number of | 436 // average size of the fields specified in 'key_fields', m is the number of |
438 // fields in 'key_fields' and n is the number of elements. If partial | 437 // fields in 'key_fields' and n is the number of elements. If partial |
439 // matching is enabled, an extra O(n^3) will be incured by the maximum | 438 // matching is enabled, an extra O(n^3) will be incured by the maximum |
440 // matching algorithm. The second step is O(k * n) where k is the average | 439 // matching algorithm. The second step is O(k * n) where k is the average |
441 // size of each element. | 440 // size of each element. |
442 void TreatAsMapWithMultipleFieldsAsKey( | 441 void TreatAsMapWithMultipleFieldsAsKey( |
443 const FieldDescriptor* field, | 442 const FieldDescriptor* field, |
444 const std::vector<const FieldDescriptor*>& key_fields); | 443 const vector<const FieldDescriptor*>& key_fields); |
445 // Same as TreatAsMapWithMultipleFieldsAsKey, except that each of the field | 444 // Same as TreatAsMapWithMultipleFieldsAsKey, except that each of the field |
446 // do not necessarily need to be a direct subfield. Each element in | 445 // do not necessarily need to be a direct subfield. Each element in |
447 // key_field_paths indicate a path from the message being compared, listing | 446 // key_field_paths indicate a path from the message being compared, listing |
448 // successive subfield to reach the key field. | 447 // successive subfield to reach the key field. |
449 // | 448 // |
450 // REQUIRES: | 449 // REQUIRES: |
451 // for key_field_path in key_field_paths: | 450 // for key_field_path in key_field_paths: |
452 // key_field_path[0]->containing_type() == field->message_type() | 451 // key_field_path[0]->containing_type() == field->message_type() |
453 // for i in [0, key_field_path.size() - 1): | 452 // for i in [0, key_field_path.size() - 1): |
454 // key_field_path[i+1]->containing_type() == | 453 // key_field_path[i+1]->containing_type() == |
455 // key_field_path[i]->message_type() | 454 // key_field_path[i]->message_type() |
456 // key_field_path[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE | 455 // key_field_path[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE |
457 // !key_field_path[i]->is_repeated() | 456 // !key_field_path[i]->is_repeated() |
458 void TreatAsMapWithMultipleFieldPathsAsKey( | 457 void TreatAsMapWithMultipleFieldPathsAsKey( |
459 const FieldDescriptor* field, | 458 const FieldDescriptor* field, |
460 const std::vector<std::vector<const FieldDescriptor*> >& key_field_paths); | 459 const vector<vector<const FieldDescriptor*> >& key_field_paths); |
461 | 460 |
462 // Uses a custom MapKeyComparator to determine if two elements have the same | 461 // Uses a custom MapKeyComparator to determine if two elements have the same |
463 // key when comparing a repeated field as a map. | 462 // key when comparing a repeated field as a map. |
464 // The caller is responsible to delete the key_comparator. | 463 // The caller is responsible to delete the key_comparator. |
465 // This method varies from TreatAsMapWithMultipleFieldsAsKey only in the | 464 // This method varies from TreatAsMapWithMultipleFieldsAsKey only in the |
466 // first key matching step. Rather than comparing some specified fields, it | 465 // first key matching step. Rather than comparing some specified fields, it |
467 // will invoke the IsMatch method of the given 'key_comparator' to decide if | 466 // will invoke the IsMatch method of the given 'key_comparator' to decide if |
468 // two elements have the same key. | 467 // two elements have the same key. |
469 void TreatAsMapUsingKeyComparator( | 468 void TreatAsMapUsingKeyComparator( |
470 const FieldDescriptor* field, | 469 const FieldDescriptor* field, |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
543 // false otherwise. If this method returns false, any changes between the | 542 // false otherwise. If this method returns false, any changes between the |
544 // two messages will be reported if a Reporter was specified via | 543 // two messages will be reported if a Reporter was specified via |
545 // ReportDifferencesTo (see also ReportDifferencesToString). | 544 // ReportDifferencesTo (see also ReportDifferencesToString). |
546 // | 545 // |
547 // This method REQUIRES that the two messages have the same | 546 // This method REQUIRES that the two messages have the same |
548 // Descriptor (message1.GetDescriptor() == message2.GetDescriptor()). | 547 // Descriptor (message1.GetDescriptor() == message2.GetDescriptor()). |
549 bool Compare(const Message& message1, const Message& message2); | 548 bool Compare(const Message& message1, const Message& message2); |
550 | 549 |
551 // Same as above, except comparing only the list of fields specified by the | 550 // Same as above, except comparing only the list of fields specified by the |
552 // two vectors of FieldDescriptors. | 551 // two vectors of FieldDescriptors. |
553 bool CompareWithFields( | 552 bool CompareWithFields(const Message& message1, const Message& message2, |
554 const Message& message1, const Message& message2, | 553 const vector<const FieldDescriptor*>& message1_fields, |
555 const std::vector<const FieldDescriptor*>& message1_fields, | 554 const vector<const FieldDescriptor*>& message2_fields); |
556 const std::vector<const FieldDescriptor*>& message2_fields); | |
557 | 555 |
558 // Automatically creates a reporter that will output the differences | 556 // Automatically creates a reporter that will output the differences |
559 // found (if any) to the specified output string pointer. Note that this | 557 // found (if any) to the specified output string pointer. Note that this |
560 // method must be called before Compare. | 558 // method must be called before Compare. |
561 void ReportDifferencesToString(string* output); | 559 void ReportDifferencesToString(string* output); |
562 | 560 |
563 // Tells the MessageDifferencer to report differences via the specified | 561 // Tells the MessageDifferencer to report differences via the specified |
564 // reporter. Note that this method must be called before Compare for | 562 // reporter. Note that this method must be called before Compare for |
565 // the reporter to be used. It is the responsibility of the caller to delete | 563 // the reporter to be used. It is the responsibility of the caller to delete |
566 // this object. | 564 // this object. |
567 // If the provided pointer equals NULL, the MessageDifferencer stops reporting | 565 // If the provided pointer equals NULL, the MessageDifferencer stops reporting |
568 // differences to any previously set reporters or output strings. | 566 // differences to any previously set reporters or output strings. |
569 void ReportDifferencesTo(Reporter* reporter); | 567 void ReportDifferencesTo(Reporter* reporter); |
570 | 568 |
571 // An implementation of the MessageDifferencer Reporter that outputs | 569 // An implementation of the MessageDifferencer Reporter that outputs |
572 // any differences found in human-readable form to the supplied | 570 // any differences found in human-readable form to the supplied |
573 // ZeroCopyOutputStream or Printer. If a printer is used, the delimiter | 571 // ZeroCopyOutputStream or Printer. If a printer is used, the delimiter |
574 // *must* be '$'. | 572 // *must* be '$'. |
575 // | |
576 // WARNING: this reporter does not necessarily flush its output until it is | |
577 // destroyed. As a result, it is not safe to assume the output is valid or | |
578 // complete until after you destroy the reporter. For example, if you use a | |
579 // StreamReporter to write to a StringOutputStream, the target string may | |
580 // contain uninitialized data until the reporter is destroyed. | |
581 class LIBPROTOBUF_EXPORT StreamReporter : public Reporter { | 573 class LIBPROTOBUF_EXPORT StreamReporter : public Reporter { |
582 public: | 574 public: |
583 explicit StreamReporter(io::ZeroCopyOutputStream* output); | 575 explicit StreamReporter(io::ZeroCopyOutputStream* output); |
584 explicit StreamReporter(io::Printer* printer); // delimiter '$' | 576 explicit StreamReporter(io::Printer* printer); // delimiter '$' |
585 virtual ~StreamReporter(); | 577 virtual ~StreamReporter(); |
586 | 578 |
587 // When set to true, the stream reporter will also output aggregates nodes | 579 // When set to true, the stream reporter will also output aggregates nodes |
588 // (i.e. messages and groups) whose subfields have been modified. When | 580 // (i.e. messages and groups) whose subfields have been modified. When |
589 // false, will only report the individual subfields. Defaults to false. | 581 // false, will only report the individual subfields. Defaults to false. |
590 void set_report_modified_aggregates(bool report) { | 582 void set_report_modified_aggregates(bool report) { |
591 report_modified_aggregates_ = report; | 583 report_modified_aggregates_ = report; |
592 } | 584 } |
593 | 585 |
594 // The following are implementations of the methods described above. | 586 // The following are implementations of the methods described above. |
595 virtual void ReportAdded(const Message& message1, const Message& message2, | 587 virtual void ReportAdded(const Message& message1, const Message& message2, |
596 const std::vector<SpecificField>& field_path); | 588 const vector<SpecificField>& field_path); |
597 | 589 |
598 virtual void ReportDeleted(const Message& message1, | 590 virtual void ReportDeleted(const Message& message1, |
599 const Message& message2, | 591 const Message& message2, |
600 const std::vector<SpecificField>& field_path); | 592 const vector<SpecificField>& field_path); |
601 | 593 |
602 virtual void ReportModified(const Message& message1, | 594 virtual void ReportModified(const Message& message1, |
603 const Message& message2, | 595 const Message& message2, |
604 const std::vector<SpecificField>& field_path); | 596 const vector<SpecificField>& field_path); |
605 | 597 |
606 virtual void ReportMoved(const Message& message1, | 598 virtual void ReportMoved(const Message& message1, |
607 const Message& message2, | 599 const Message& message2, |
608 const std::vector<SpecificField>& field_path); | 600 const vector<SpecificField>& field_path); |
609 | 601 |
610 virtual void ReportMatched(const Message& message1, | 602 virtual void ReportMatched(const Message& message1, |
611 const Message& message2, | 603 const Message& message2, |
612 const std::vector<SpecificField>& field_path); | 604 const vector<SpecificField>& field_path); |
613 | 605 |
614 virtual void ReportIgnored(const Message& message1, | 606 virtual void ReportIgnored(const Message& message1, |
615 const Message& message2, | 607 const Message& message2, |
616 const std::vector<SpecificField>& field_path); | 608 const vector<SpecificField>& field_path); |
617 | 609 |
618 virtual void ReportUnknownFieldIgnored( | 610 virtual void ReportUnknownFieldIgnored( |
619 const Message& message1, const Message& message2, | 611 const Message& message1, const Message& message2, |
620 const std::vector<SpecificField>& field_path); | 612 const vector<SpecificField>& field_path); |
621 | 613 |
622 protected: | 614 protected: |
623 // Prints the specified path of fields to the buffer. | 615 // Prints the specified path of fields to the buffer. |
624 virtual void PrintPath(const std::vector<SpecificField>& field_path, | 616 virtual void PrintPath(const vector<SpecificField>& field_path, |
625 bool left_side); | 617 bool left_side); |
626 | 618 |
627 // Prints the value of fields to the buffer. left_side is true if the | 619 // Prints the value of fields to the buffer. left_side is true if the |
628 // given message is from the left side of the comparison, false if it | 620 // given message is from the left side of the comparison, false if it |
629 // was the right. This is relevant only to decide whether to follow | 621 // was the right. This is relevant only to decide whether to follow |
630 // unknown_field_index1 or unknown_field_index2 when an unknown field | 622 // unknown_field_index1 or unknown_field_index2 when an unknown field |
631 // is encountered in field_path. | 623 // is encountered in field_path. |
632 virtual void PrintValue(const Message& message, | 624 virtual void PrintValue(const Message& message, |
633 const std::vector<SpecificField>& field_path, | 625 const vector<SpecificField>& field_path, |
634 bool left_side); | 626 bool left_side); |
635 | 627 |
636 // Prints the specified path of unknown fields to the buffer. | 628 // Prints the specified path of unknown fields to the buffer. |
637 virtual void PrintUnknownFieldValue(const UnknownField* unknown_field); | 629 virtual void PrintUnknownFieldValue(const UnknownField* unknown_field); |
638 | 630 |
639 // Just print a string | 631 // Just print a string |
640 void Print(const string& str); | 632 void Print(const string& str); |
641 | 633 |
642 private: | 634 private: |
643 io::Printer* printer_; | 635 io::Printer* printer_; |
(...skipping 10 matching lines...) Expand all Loading... |
654 // class is declared as a nested class of MessageDifferencer. | 646 // class is declared as a nested class of MessageDifferencer. |
655 class MultipleFieldsMapKeyComparator; | 647 class MultipleFieldsMapKeyComparator; |
656 // Returns true if field1's number() is less than field2's. | 648 // Returns true if field1's number() is less than field2's. |
657 static bool FieldBefore(const FieldDescriptor* field1, | 649 static bool FieldBefore(const FieldDescriptor* field1, |
658 const FieldDescriptor* field2); | 650 const FieldDescriptor* field2); |
659 | 651 |
660 // Combine the two lists of fields into the combined_fields output vector. | 652 // Combine the two lists of fields into the combined_fields output vector. |
661 // All fields present in both lists will always be included in the combined | 653 // All fields present in both lists will always be included in the combined |
662 // list. Fields only present in one of the lists will only appear in the | 654 // list. Fields only present in one of the lists will only appear in the |
663 // combined list if the corresponding fields_scope option is set to FULL. | 655 // combined list if the corresponding fields_scope option is set to FULL. |
664 void CombineFields(const std::vector<const FieldDescriptor*>& fields1, | 656 void CombineFields(const vector<const FieldDescriptor*>& fields1, |
665 Scope fields1_scope, | 657 Scope fields1_scope, |
666 const std::vector<const FieldDescriptor*>& fields2, | 658 const vector<const FieldDescriptor*>& fields2, |
667 Scope fields2_scope, | 659 Scope fields2_scope, |
668 std::vector<const FieldDescriptor*>* combined_fields); | 660 vector<const FieldDescriptor*>* combined_fields); |
669 | 661 |
670 // Internal version of the Compare method which performs the actual | 662 // Internal version of the Compare method which performs the actual |
671 // comparison. The parent_fields vector is a vector containing field | 663 // comparison. The parent_fields vector is a vector containing field |
672 // descriptors of all fields accessed to get to this comparison operation | 664 // descriptors of all fields accessed to get to this comparison operation |
673 // (i.e. if the current message is an embedded message, the parent_fields | 665 // (i.e. if the current message is an embedded message, the parent_fields |
674 // vector will contain the field that has this embedded message). | 666 // vector will contain the field that has this embedded message). |
675 bool Compare(const Message& message1, const Message& message2, | 667 bool Compare(const Message& message1, const Message& message2, |
676 std::vector<SpecificField>* parent_fields); | 668 vector<SpecificField>* parent_fields); |
677 | 669 |
678 // Compares all the unknown fields in two messages. | 670 // Compares all the unknown fields in two messages. |
679 bool CompareUnknownFields(const Message& message1, const Message& message2, | 671 bool CompareUnknownFields(const Message& message1, const Message& message2, |
680 const google::protobuf::UnknownFieldSet&, | 672 const google::protobuf::UnknownFieldSet&, |
681 const google::protobuf::UnknownFieldSet&, | 673 const google::protobuf::UnknownFieldSet&, |
682 std::vector<SpecificField>* parent_fields); | 674 vector<SpecificField>* parent_fields); |
683 | 675 |
684 // Compares the specified messages for the requested field lists. The field | 676 // Compares the specified messages for the requested field lists. The field |
685 // lists are modified depending on comparison settings, and then passed to | 677 // lists are modified depending on comparison settings, and then passed to |
686 // CompareWithFieldsInternal. | 678 // CompareWithFieldsInternal. |
687 bool CompareRequestedFieldsUsingSettings( | 679 bool CompareRequestedFieldsUsingSettings( |
688 const Message& message1, const Message& message2, | 680 const Message& message1, const Message& message2, |
689 const std::vector<const FieldDescriptor*>& message1_fields, | 681 const vector<const FieldDescriptor*>& message1_fields, |
690 const std::vector<const FieldDescriptor*>& message2_fields, | 682 const vector<const FieldDescriptor*>& message2_fields, |
691 std::vector<SpecificField>* parent_fields); | 683 vector<SpecificField>* parent_fields); |
692 | 684 |
693 // Compares the specified messages with the specified field lists. | 685 // Compares the specified messages with the specified field lists. |
694 bool CompareWithFieldsInternal( | 686 bool CompareWithFieldsInternal( |
695 const Message& message1, const Message& message2, | 687 const Message& message1, const Message& message2, |
696 const std::vector<const FieldDescriptor*>& message1_fields, | 688 const vector<const FieldDescriptor*>& message1_fields, |
697 const std::vector<const FieldDescriptor*>& message2_fields, | 689 const vector<const FieldDescriptor*>& message2_fields, |
698 std::vector<SpecificField>* parent_fields); | 690 vector<SpecificField>* parent_fields); |
699 | 691 |
700 // Compares the repeated fields, and report the error. | 692 // Compares the repeated fields, and report the error. |
701 bool CompareRepeatedField(const Message& message1, const Message& message2, | 693 bool CompareRepeatedField(const Message& message1, const Message& message2, |
702 const FieldDescriptor* field, | 694 const FieldDescriptor* field, |
703 std::vector<SpecificField>* parent_fields); | 695 vector<SpecificField>* parent_fields); |
704 | 696 |
705 // Shorthand for CompareFieldValueUsingParentFields with NULL parent_fields. | 697 // Shorthand for CompareFieldValueUsingParentFields with NULL parent_fields. |
706 bool CompareFieldValue(const Message& message1, | 698 bool CompareFieldValue(const Message& message1, |
707 const Message& message2, | 699 const Message& message2, |
708 const FieldDescriptor* field, | 700 const FieldDescriptor* field, |
709 int index1, | 701 int index1, |
710 int index2); | 702 int index2); |
711 | 703 |
712 // Compares the specified field on the two messages, returning | 704 // Compares the specified field on the two messages, returning |
713 // true if they are the same, false otherwise. For repeated fields, | 705 // true if they are the same, false otherwise. For repeated fields, |
714 // this method only compares the value in the specified index. This method | 706 // this method only compares the value in the specified index. This method |
715 // uses Compare functions to recurse into submessages. | 707 // uses Compare functions to recurse into submessages. |
716 // The parent_fields vector is used in calls to a Reporter instance calls. | 708 // The parent_fields vector is used in calls to a Reporter instance calls. |
717 // It can be NULL, in which case the MessageDifferencer will create new | 709 // It can be NULL, in which case the MessageDifferencer will create new |
718 // list of parent messages if it needs to recursively compare the given field. | 710 // list of parent messages if it needs to recursively compare the given field. |
719 // To avoid confusing users you should not set it to NULL unless you modified | 711 // To avoid confusing users you should not set it to NULL unless you modified |
720 // Reporter to handle the change of parent_fields correctly. | 712 // Reporter to handle the change of parent_fields correctly. |
721 bool CompareFieldValueUsingParentFields( | 713 bool CompareFieldValueUsingParentFields(const Message& message1, |
722 const Message& message1, | 714 const Message& message2, |
723 const Message& message2, | 715 const FieldDescriptor* field, |
724 const FieldDescriptor* field, | 716 int index1, |
725 int index1, | 717 int index2, |
726 int index2, | 718 vector<SpecificField>* parent_fields); |
727 std::vector<SpecificField>* parent_fields); | |
728 | 719 |
729 // Compares the specified field on the two messages, returning comparison | 720 // Compares the specified field on the two messages, returning comparison |
730 // result, as returned by appropriate FieldComparator. | 721 // result, as returned by appropriate FieldComparator. |
731 FieldComparator::ComparisonResult GetFieldComparisonResult( | 722 FieldComparator::ComparisonResult GetFieldComparisonResult( |
732 const Message& message1, const Message& message2, | 723 const Message& message1, const Message& message2, |
733 const FieldDescriptor* field, int index1, int index2, | 724 const FieldDescriptor* field, int index1, int index2, |
734 const FieldContext* field_context); | 725 const FieldContext* field_context); |
735 | 726 |
736 // Check if the two elements in the repeated field are match to each other. | 727 // Check if the two elements in the repeated field are match to each other. |
737 // if the key_comprator is NULL, this function returns true when the two | 728 // if the key_comprator is NULL, this function returns true when the two |
738 // elements are equal. | 729 // elements are equal. |
739 bool IsMatch(const FieldDescriptor* repeated_field, | 730 bool IsMatch(const FieldDescriptor* repeated_field, |
740 const MapKeyComparator* key_comparator, | 731 const MapKeyComparator* key_comparator, |
741 const Message* message1, const Message* message2, | 732 const Message* message1, const Message* message2, |
742 const std::vector<SpecificField>& parent_fields, | 733 const vector<SpecificField>& parent_fields, |
743 int index1, int index2); | 734 int index1, int index2); |
744 | 735 |
745 // Returns true when this repeated field has been configured to be treated | 736 // Returns true when this repeated field has been configured to be treated |
746 // as a set. | 737 // as a set. |
747 bool IsTreatedAsSet(const FieldDescriptor* field); | 738 bool IsTreatedAsSet(const FieldDescriptor* field); |
748 | 739 |
749 // Returns true when this repeated field is to be compared as a subset, ie. | 740 // Returns true when this repeated field is to be compared as a subset, ie. |
750 // has been configured to be treated as a set or map and scope is set to | 741 // has been configured to be treated as a set or map and scope is set to |
751 // PARTIAL. | 742 // PARTIAL. |
752 bool IsTreatedAsSubset(const FieldDescriptor* field); | 743 bool IsTreatedAsSubset(const FieldDescriptor* field); |
753 | 744 |
754 // Returns true if this field is to be ignored when this | 745 // Returns true if this field is to be ignored when this |
755 // MessageDifferencer compares messages. | 746 // MessageDifferencer compares messages. |
756 bool IsIgnored( | 747 bool IsIgnored( |
757 const Message& message1, | 748 const Message& message1, |
758 const Message& message2, | 749 const Message& message2, |
759 const FieldDescriptor* field, | 750 const FieldDescriptor* field, |
760 const std::vector<SpecificField>& parent_fields); | 751 const vector<SpecificField>& parent_fields); |
761 | 752 |
762 // Returns true if this unknown field is to be ignored when this | 753 // Returns true if this unknown field is to be ignored when this |
763 // MessageDifferencer compares messages. | 754 // MessageDifferencer compares messages. |
764 bool IsUnknownFieldIgnored(const Message& message1, const Message& message2, | 755 bool IsUnknownFieldIgnored(const Message& message1, const Message& message2, |
765 const SpecificField& field, | 756 const SpecificField& field, |
766 const std::vector<SpecificField>& parent_fields); | 757 const vector<SpecificField>& parent_fields); |
767 | 758 |
768 // Returns MapKeyComparator* when this field has been configured to | 759 // Returns MapKeyComparator* when this field has been configured to |
769 // be treated as a map. If not, returns NULL. | 760 // be treated as a map. If not, returns NULL. |
770 const MapKeyComparator* GetMapKeyComparator(const FieldDescriptor* field); | 761 const MapKeyComparator* GetMapKeyComparator(const FieldDescriptor* field); |
771 | 762 |
772 // Attempts to match indices of a repeated field, so that the contained values | 763 // Attempts to match indices of a repeated field, so that the contained values |
773 // match. Clears output vectors and sets their values to indices of paired | 764 // match. Clears output vectors and sets their values to indices of paired |
774 // messages, ie. if message1[0] matches message2[1], then match_list1[0] == 1 | 765 // messages, ie. if message1[0] matches message2[1], then match_list1[0] == 1 |
775 // and match_list2[1] == 0. The unmatched indices are indicated by -1. | 766 // and match_list2[1] == 0. The unmatched indices are indicated by -1. |
776 // This method returns false if the match failed. However, it doesn't mean | 767 // This method returns false if the match failed. However, it doesn't mean |
777 // that the comparison succeeds when this method returns true (you need to | 768 // that the comparison succeeds when this method returns true (you need to |
778 // double-check in this case). | 769 // double-check in this case). |
779 bool MatchRepeatedFieldIndices( | 770 bool MatchRepeatedFieldIndices(const Message& message1, |
780 const Message& message1, | 771 const Message& message2, |
781 const Message& message2, | 772 const FieldDescriptor* repeated_field, |
782 const FieldDescriptor* repeated_field, | 773 const vector<SpecificField>& parent_fields, |
783 const std::vector<SpecificField>& parent_fields, | 774 vector<int>* match_list1, |
784 std::vector<int>* match_list1, | 775 vector<int>* match_list2); |
785 std::vector<int>* match_list2); | |
786 | 776 |
787 // If "any" is of type google.protobuf.Any, extract its payload using | 777 // If "any" is of type google.protobuf.Any, extract its payload using |
788 // DynamicMessageFactory and store in "data". | 778 // DynamicMessageFactory and store in "data". |
789 bool UnpackAny(const Message& any, google::protobuf::scoped_ptr<Message>* data
); | 779 bool UnpackAny(const Message& any, google::protobuf::scoped_ptr<Message>* data
); |
790 | 780 |
791 // Checks if index is equal to new_index in all the specific fields. | 781 // Checks if index is equal to new_index in all the specific fields. |
792 static bool CheckPathChanged(const std::vector<SpecificField>& parent_fields); | 782 static bool CheckPathChanged(const vector<SpecificField>& parent_fields); |
793 | 783 |
794 // Defines a map between field descriptors and their MapKeyComparators. | 784 // Defines a map between field descriptors and their MapKeyComparators. |
795 // Used for repeated fields when they are configured as TreatAsMap. | 785 // Used for repeated fields when they are configured as TreatAsMap. |
796 typedef std::map<const FieldDescriptor*, | 786 typedef map<const FieldDescriptor*, |
797 const MapKeyComparator*> FieldKeyComparatorMap; | 787 const MapKeyComparator*> FieldKeyComparatorMap; |
798 | 788 |
799 // Defines a set to store field descriptors. Used for repeated fields when | 789 // Defines a set to store field descriptors. Used for repeated fields when |
800 // they are configured as TreatAsSet. | 790 // they are configured as TreatAsSet. |
801 typedef std::set<const FieldDescriptor*> FieldSet; | 791 typedef set<const FieldDescriptor*> FieldSet; |
802 | 792 |
803 Reporter* reporter_; | 793 Reporter* reporter_; |
804 DefaultFieldComparator default_field_comparator_; | 794 DefaultFieldComparator default_field_comparator_; |
805 FieldComparator* field_comparator_; | 795 FieldComparator* field_comparator_; |
806 MessageFieldComparison message_field_comparison_; | 796 MessageFieldComparison message_field_comparison_; |
807 Scope scope_; | 797 Scope scope_; |
808 RepeatedFieldComparison repeated_field_comparison_; | 798 RepeatedFieldComparison repeated_field_comparison_; |
809 | 799 |
810 FieldSet set_fields_; | 800 FieldSet set_fields_; |
811 FieldSet list_fields_; | 801 FieldSet list_fields_; |
812 // Keeps track of MapKeyComparators that are created within | 802 // Keeps track of MapKeyComparators that are created within |
813 // MessageDifferencer. These MapKeyComparators should be deleted | 803 // MessageDifferencer. These MapKeyComparators should be deleted |
814 // before MessageDifferencer is destroyed. | 804 // before MessageDifferencer is destroyed. |
815 // When TreatAsMap or TreatAsMapWithMultipleFieldsAsKey is called, we don't | 805 // When TreatAsMap or TreatAsMapWithMultipleFieldsAsKey is called, we don't |
816 // store the supplied FieldDescriptors directly. Instead, a new | 806 // store the supplied FieldDescriptors directly. Instead, a new |
817 // MapKeyComparator is created for comparison purpose. | 807 // MapKeyComparator is created for comparison purpose. |
818 std::vector<MapKeyComparator*> owned_key_comparators_; | 808 vector<MapKeyComparator*> owned_key_comparators_; |
819 FieldKeyComparatorMap map_field_key_comparator_; | 809 FieldKeyComparatorMap map_field_key_comparator_; |
820 std::vector<IgnoreCriteria*> ignore_criteria_; | 810 vector<IgnoreCriteria*> ignore_criteria_; |
821 | 811 |
822 FieldSet ignored_fields_; | 812 FieldSet ignored_fields_; |
823 | 813 |
| 814 bool compare_unknown_fields_; |
824 bool report_matches_; | 815 bool report_matches_; |
825 | 816 |
826 string* output_string_; | 817 string* output_string_; |
827 | 818 |
828 google::protobuf::scoped_ptr<DynamicMessageFactory> dynamic_message_factory_; | 819 google::protobuf::scoped_ptr<DynamicMessageFactory> dynamic_message_factory_; |
829 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageDifferencer); | 820 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageDifferencer); |
830 }; | 821 }; |
831 | 822 |
832 // This class provides extra information to the FieldComparator::Compare | 823 // This class provides extra information to the FieldComparator::Compare |
833 // function. | 824 // function. |
834 class LIBPROTOBUF_EXPORT FieldContext { | 825 class LIBPROTOBUF_EXPORT FieldContext { |
835 public: | 826 public: |
836 explicit FieldContext( | 827 explicit FieldContext( |
837 std::vector<MessageDifferencer::SpecificField>* parent_fields) | 828 vector<MessageDifferencer::SpecificField>* parent_fields) |
838 : parent_fields_(parent_fields) {} | 829 : parent_fields_(parent_fields) {} |
839 | 830 |
840 std::vector<MessageDifferencer::SpecificField>* parent_fields() const { | 831 vector<MessageDifferencer::SpecificField>* parent_fields() const { |
841 return parent_fields_; | 832 return parent_fields_; |
842 } | 833 } |
843 | 834 |
844 private: | 835 private: |
845 std::vector<MessageDifferencer::SpecificField>* parent_fields_; | 836 vector<MessageDifferencer::SpecificField>* parent_fields_; |
846 }; | 837 }; |
847 | 838 |
848 } | 839 } |
849 } | 840 } |
850 | 841 |
851 } // namespace google | 842 } // namespace google |
852 #endif // GOOGLE_PROTOBUF_UTIL_MESSAGE_DIFFERENCER_H__ | 843 #endif // GOOGLE_PROTOBUF_UTIL_MESSAGE_DIFFERENCER_H__ |
OLD | NEW |