message_differencer.h
Go to the documentation of this file.
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // Author: jschorr@google.com (Joseph Schorr)
32 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others.
34 //
35 // This file defines static methods and classes for comparing Protocol
36 // Messages.
37 //
38 // Aug. 2008: Added Unknown Fields Comparison for messages.
39 // Aug. 2009: Added different options to compare repeated fields.
40 // Apr. 2010: Moved field comparison to FieldComparator.
41 
42 #ifndef GOOGLE_PROTOBUF_UTIL_MESSAGE_DIFFERENCER_H__
43 #define GOOGLE_PROTOBUF_UTIL_MESSAGE_DIFFERENCER_H__
44 
45 #include <functional>
46 #include <map>
47 #include <set>
48 #include <string>
49 #include <vector>
50 
51 #include <google/protobuf/descriptor.h> // FieldDescriptor
52 #include <google/protobuf/message.h> // Message
55 
56 // Always include as last one, otherwise it can break compilation
57 #include <google/protobuf/port_def.inc>
58 
59 namespace google {
60 namespace protobuf {
61 
62 class DynamicMessageFactory;
63 class FieldDescriptor;
64 
65 namespace io {
66 class ZeroCopyOutputStream;
67 class Printer;
68 } // namespace io
69 
70 namespace util {
71 
72 class DefaultFieldComparator;
73 class FieldContext; // declared below MessageDifferencer
74 
75 // Defines a collection of field descriptors.
76 // In case of internal google codebase we are using absl::FixedArray instead
77 // of vector. It significantly speeds up proto comparison (by ~30%) by
78 // reducing the number of malloc/free operations
79 typedef std::vector<const FieldDescriptor*> FieldDescriptorArray;
80 
81 // A basic differencer that can be used to determine
82 // the differences between two specified Protocol Messages. If any differences
83 // are found, the Compare method will return false, and any differencer reporter
84 // specified via ReportDifferencesTo will have its reporting methods called (see
85 // below for implementation of the report). Based off of the original
86 // ProtocolDifferencer implementation in //net/proto/protocol-differencer.h
87 // (Thanks Todd!).
88 //
89 // MessageDifferencer REQUIRES that compared messages be the same type, defined
90 // as messages that share the same descriptor. If not, the behavior of this
91 // class is undefined.
92 //
93 // People disagree on what MessageDifferencer should do when asked to compare
94 // messages with different descriptors. Some people think it should always
95 // return false. Others expect it to try to look for similar fields and
96 // compare them anyway -- especially if the descriptors happen to be identical.
97 // If we chose either of these behaviors, some set of people would find it
98 // surprising, and could end up writing code expecting the other behavior
99 // without realizing their error. Therefore, we forbid that usage.
100 //
101 // This class is implemented based on the proto2 reflection. The performance
102 // should be good enough for normal usages. However, for places where the
103 // performance is extremely sensitive, there are several alternatives:
104 // - Comparing serialized string
105 // Downside: false negatives (there are messages that are the same but their
106 // serialized strings are different).
107 // - Equals code generator by compiler plugin (net/proto2/contrib/equals_plugin)
108 // Downside: more generated code; maintenance overhead for the additional rule
109 // (must be in sync with the original proto_library).
110 //
111 // Note on handling of google.protobuf.Any: MessageDifferencer automatically
112 // unpacks Any::value into a Message and compares its individual fields.
113 // Messages encoded in a repeated Any cannot be compared using TreatAsMap.
114 //
115 //
116 // Note on thread-safety: MessageDifferencer is *not* thread-safe. You need to
117 // guard it with a lock to use the same MessageDifferencer instance from
118 // multiple threads. Note that it's fine to call static comparison methods
119 // (like MessageDifferencer::Equals) concurrently.
120 class PROTOBUF_EXPORT MessageDifferencer {
121  public:
122  // Determines whether the supplied messages are equal. Equality is defined as
123  // all fields within the two messages being set to the same value. Primitive
124  // fields and strings are compared by value while embedded messages/groups
125  // are compared as if via a recursive call. Use Compare() with IgnoreField()
126  // if some fields should be ignored in the comparison. Use Compare() with
127  // TreatAsSet() if there are repeated fields where ordering does not matter.
128  //
129  // This method REQUIRES that the two messages have the same
130  // Descriptor (message1.GetDescriptor() == message2.GetDescriptor()).
131  static bool Equals(const Message& message1, const Message& message2);
132 
133  // Determines whether the supplied messages are equivalent. Equivalency is
134  // defined as all fields within the two messages having the same value. This
135  // differs from the Equals method above in that fields with default values
136  // are considered set to said value automatically. For details on how default
137  // values are defined for each field type, see:
138  // https://developers.google.com/protocol-buffers/docs/proto?csw=1#optional.
139  // Also, Equivalent() ignores unknown fields. Use IgnoreField() and Compare()
140  // if some fields should be ignored in the comparison.
141  //
142  // This method REQUIRES that the two messages have the same
143  // Descriptor (message1.GetDescriptor() == message2.GetDescriptor()).
144  static bool Equivalent(const Message& message1, const Message& message2);
145 
146  // Determines whether the supplied messages are approximately equal.
147  // Approximate equality is defined as all fields within the two messages
148  // being approximately equal. Primitive (non-float) fields and strings are
149  // compared by value, floats are compared using MathUtil::AlmostEquals() and
150  // embedded messages/groups are compared as if via a recursive call. Use
151  // IgnoreField() and Compare() if some fields should be ignored in the
152  // comparison.
153  //
154  // This method REQUIRES that the two messages have the same
155  // Descriptor (message1.GetDescriptor() == message2.GetDescriptor()).
156  static bool ApproximatelyEquals(const Message& message1,
157  const Message& message2);
158 
159  // Determines whether the supplied messages are approximately equivalent.
160  // Approximate equivalency is defined as all fields within the two messages
161  // being approximately equivalent. As in
162  // MessageDifferencer::ApproximatelyEquals, primitive (non-float) fields and
163  // strings are compared by value, floats are compared using
164  // MathUtil::AlmostEquals() and embedded messages/groups are compared as if
165  // via a recursive call. However, fields with default values are considered
166  // set to said value, as per MessageDiffencer::Equivalent. Use IgnoreField()
167  // and Compare() if some fields should be ignored in the comparison.
168  //
169  // This method REQUIRES that the two messages have the same
170  // Descriptor (message1.GetDescriptor() == message2.GetDescriptor()).
171  static bool ApproximatelyEquivalent(const Message& message1,
172  const Message& message2);
173 
174  // Identifies an individual field in a message instance. Used for field_path,
175  // below.
176  struct SpecificField {
177  // For known fields, "field" is filled in and "unknown_field_number" is -1.
178  // For unknown fields, "field" is NULL, "unknown_field_number" is the field
179  // number, and "unknown_field_type" is its type.
183 
184  // If this a repeated field, "index" is the index within it. For unknown
185  // fields, this is the index of the field among all unknown fields of the
186  // same field number and type.
187  int index;
188 
189  // If "field" is a repeated field which is being treated as a map or
190  // a set (see TreatAsMap() and TreatAsSet(), below), new_index indicates
191  // the index the position to which the element has moved. If the element
192  // has not moved, "new_index" will have the same value as "index".
194 
195  // For unknown fields, these are the pointers to the UnknownFieldSet
196  // containing the unknown fields. In certain cases (e.g. proto1's
197  // MessageSet, or nested groups of unknown fields), these may differ from
198  // the messages' internal UnknownFieldSets.
201 
202  // For unknown fields, these are the index of the field within the
203  // UnknownFieldSets. One or the other will be -1 when
204  // reporting an addition or deletion.
207 
209  : field(NULL),
210  unknown_field_number(-1),
211  index(-1),
212  new_index(-1),
213  unknown_field_set1(NULL),
214  unknown_field_set2(NULL),
215  unknown_field_index1(-1),
216  unknown_field_index2(-1) {}
217  };
218 
219  // Abstract base class from which all MessageDifferencer
220  // reporters derive. The five Report* methods below will be called when
221  // a field has been added, deleted, modified, moved, or matched. The third
222  // argument is a vector of FieldDescriptor pointers which describes the chain
223  // of fields that was taken to find the current field. For example, for a
224  // field found in an embedded message, the vector will contain two
225  // FieldDescriptors. The first will be the field of the embedded message
226  // itself and the second will be the actual field in the embedded message
227  // that was added/deleted/modified.
228  class PROTOBUF_EXPORT Reporter {
229  public:
230  Reporter();
231  virtual ~Reporter();
232 
233  // Reports that a field has been added into Message2.
234  virtual void ReportAdded(const Message& message1, const Message& message2,
235  const std::vector<SpecificField>& field_path) = 0;
236 
237  // Reports that a field has been deleted from Message1.
238  virtual void ReportDeleted(
239  const Message& message1, const Message& message2,
240  const std::vector<SpecificField>& field_path) = 0;
241 
242  // Reports that the value of a field has been modified.
243  virtual void ReportModified(
244  const Message& message1, const Message& message2,
245  const std::vector<SpecificField>& field_path) = 0;
246 
247  // Reports that a repeated field has been moved to another location. This
248  // only applies when using TreatAsSet or TreatAsMap() -- see below. Also
249  // note that for any given field, ReportModified and ReportMoved are
250  // mutually exclusive. If a field has been both moved and modified, then
251  // only ReportModified will be called.
252  virtual void ReportMoved(
253  const Message& /* message1 */, const Message& /* message2 */,
254  const std::vector<SpecificField>& /* field_path */) {}
255 
256  // Reports that two fields match. Useful for doing side-by-side diffs.
257  // This function is mutually exclusive with ReportModified and ReportMoved.
258  // Note that you must call set_report_matches(true) before calling Compare
259  // to make use of this function.
260  virtual void ReportMatched(
261  const Message& /* message1 */, const Message& /* message2 */,
262  const std::vector<SpecificField>& /* field_path */) {}
263 
264  // Reports that two fields would have been compared, but the
265  // comparison has been skipped because the field was marked as
266  // 'ignored' using IgnoreField(). This function is mutually
267  // exclusive with all the other Report() functions.
268  //
269  // The contract of ReportIgnored is slightly different than the
270  // other Report() functions, in that |field_path.back().index| is
271  // always equal to -1, even if the last field is repeated. This is
272  // because while the other Report() functions indicate where in a
273  // repeated field the action (Addition, Deletion, etc...)
274  // happened, when a repeated field is 'ignored', the differencer
275  // simply calls ReportIgnored on the repeated field as a whole and
276  // moves on without looking at its individual elements.
277  //
278  // Furthermore, ReportIgnored() does not indicate whether the
279  // fields were in fact equal or not, as Compare() does not inspect
280  // these fields at all. It is up to the Reporter to decide whether
281  // the fields are equal or not (perhaps with a second call to
282  // Compare()), if it cares.
283  virtual void ReportIgnored(
284  const Message& /* message1 */, const Message& /* message2 */,
285  const std::vector<SpecificField>& /* field_path */) {}
286 
287  // Report that an unknown field is ignored. (see comment above).
288  // Note this is a different function since the last SpecificField in field
289  // path has a null field. This could break existing Reporter.
291  const Message& /* message1 */, const Message& /* message2 */,
292  const std::vector<SpecificField>& /* field_path */) {}
293 
294  private:
296  };
297 
298  // MapKeyComparator is used to determine if two elements have the same key
299  // when comparing elements of a repeated field as a map.
300  class PROTOBUF_EXPORT MapKeyComparator {
301  public:
303  virtual ~MapKeyComparator();
304 
305  virtual bool IsMatch(
306  const Message& /* message1 */, const Message& /* message2 */,
307  const std::vector<SpecificField>& /* parent_fields */) const {
308  GOOGLE_CHECK(false) << "IsMatch() is not implemented.";
309  return false;
310  }
311 
312  private:
314  };
315 
316  // Abstract base class from which all IgnoreCriteria derive.
317  // By adding IgnoreCriteria more complex ignore logic can be implemented.
318  // IgnoreCriteria are registed with AddIgnoreCriteria. For each compared
319  // field IsIgnored is called on each added IgnoreCriteria until one returns
320  // true or all return false.
321  // IsIgnored is called for fields where at least one side has a value.
322  class PROTOBUF_EXPORT IgnoreCriteria {
323  public:
324  IgnoreCriteria();
325  virtual ~IgnoreCriteria();
326 
327  // Returns true if the field should be ignored.
328  virtual bool IsIgnored(
329  const Message& /* message1 */, const Message& /* message2 */,
330  const FieldDescriptor* /* field */,
331  const std::vector<SpecificField>& /* parent_fields */) = 0;
332 
333  // Returns true if the unknown field should be ignored.
334  // Note: This will be called for unknown fields as well in which case
335  // field.field will be null.
336  virtual bool IsUnknownFieldIgnored(
337  const Message& /* message1 */, const Message& /* message2 */,
338  const SpecificField& /* field */,
339  const std::vector<SpecificField>& /* parent_fields */) {
340  return false;
341  }
342  };
343 
344  // To add a Reporter, construct default here, then use ReportDifferencesTo or
345  // ReportDifferencesToString.
346  explicit MessageDifferencer();
347 
349 
351  EQUAL, // Fields must be present in both messages
352  // for the messages to be considered the same.
353  EQUIVALENT, // Fields with default values are considered set
354  // for comparison purposes even if not explicitly
355  // set in the messages themselves. Unknown fields
356  // are ignored.
357  };
358 
359  enum Scope {
360  FULL, // All fields of both messages are considered in the comparison.
361  PARTIAL // Only fields present in the first message are considered; fields
362  // set only in the second message will be skipped during
363  // comparison.
364  };
365 
366  // DEPRECATED. Use FieldComparator::FloatComparison instead.
368  EXACT, // Floats and doubles are compared exactly.
369  APPROXIMATE // Floats and doubles are compared using the
370  // MathUtil::AlmostEquals method.
371  };
372 
374  AS_LIST, // Repeated fields are compared in order. Differing values at
375  // the same index are reported using ReportModified(). If the
376  // repeated fields have different numbers of elements, the
377  // unpaired elements are reported using ReportAdded() or
378  // ReportDeleted().
379  AS_SET, // Treat all the repeated fields as sets.
380  // See TreatAsSet(), as below.
381  AS_SMART_LIST, // Similar to AS_SET, but preserve the order and find the
382  // longest matching sequence from the first matching
383  // element. To use an optimal solution, call
384  // SetMatchIndicesForSmartListCallback() to pass it in.
385  AS_SMART_SET, // Similar to AS_SET, but match elements with fewest diffs.
386  };
387 
388  // The elements of the given repeated field will be treated as a set for
389  // diffing purposes, so different orderings of the same elements will be
390  // considered equal. Elements which are present on both sides of the
391  // comparison but which have changed position will be reported with
392  // ReportMoved(). Elements which only exist on one side or the other are
393  // reported with ReportAdded() and ReportDeleted() regardless of their
394  // positions. ReportModified() is never used for this repeated field. If
395  // the only differences between the compared messages is that some fields
396  // have been moved, then the comparison returns true.
397  //
398  // Note that despite the name of this method, this is really
399  // comparison as multisets: if one side of the comparison has a duplicate
400  // in the repeated field but the other side doesn't, this will count as
401  // a mismatch.
402  //
403  // If the scope of comparison is set to PARTIAL, then in addition to what's
404  // above, extra values added to repeated fields of the second message will
405  // not cause the comparison to fail.
406  //
407  // Note that set comparison is currently O(k * n^2) (where n is the total
408  // number of elements, and k is the average size of each element). In theory
409  // it could be made O(n * k) with a more complex hashing implementation. Feel
410  // free to contribute one if the current implementation is too slow for you.
411  // If partial matching is also enabled, the time complexity will be O(k * n^2
412  // + n^3) in which n^3 is the time complexity of the maximum matching
413  // algorithm.
414  //
415  // REQUIRES: field->is_repeated() and field not registered with TreatAsList
416  void TreatAsSet(const FieldDescriptor* field);
417  void TreatAsSmartSet(const FieldDescriptor* field);
418 
419  // The elements of the given repeated field will be treated as a list for
420  // diffing purposes, so different orderings of the same elements will NOT be
421  // considered equal.
422  //
423  // REQUIRED: field->is_repeated() and field not registered with TreatAsSet
424  void TreatAsList(const FieldDescriptor* field);
425  // Note that the complexity is similar to treating as SET.
426  void TreatAsSmartList(const FieldDescriptor* field);
427 
428  // The elements of the given repeated field will be treated as a map for
429  // diffing purposes, with |key| being the map key. Thus, elements with the
430  // same key will be compared even if they do not appear at the same index.
431  // Differences are reported similarly to TreatAsSet(), except that
432  // ReportModified() is used to report elements with the same key but
433  // different values. Note that if an element is both moved and modified,
434  // only ReportModified() will be called. As with TreatAsSet, if the only
435  // differences between the compared messages is that some fields have been
436  // moved, then the comparison returns true. See TreatAsSet for notes on
437  // performance.
438  //
439  // REQUIRES: field->is_repeated()
440  // REQUIRES: field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE
441  // REQUIRES: key->containing_type() == field->message_type()
442  void TreatAsMap(const FieldDescriptor* field, const FieldDescriptor* key);
443  // Same as TreatAsMap except that this method will use multiple fields as
444  // the key in comparison. All specified fields in 'key_fields' should be
445  // present in the compared elements. Two elements will be treated as having
446  // the same key iff they have the same value for every specified field. There
447  // are two steps in the comparison process. The first one is key matching.
448  // Every element from one message will be compared to every element from
449  // the other message. Only fields in 'key_fields' are compared in this step
450  // to decide if two elements have the same key. The second step is value
451  // comparison. Those pairs of elements with the same key (with equal value
452  // for every field in 'key_fields') will be compared in this step.
453  // Time complexity of the first step is O(s * m * n ^ 2) where s is the
454  // average size of the fields specified in 'key_fields', m is the number of
455  // fields in 'key_fields' and n is the number of elements. If partial
456  // matching is enabled, an extra O(n^3) will be incured by the maximum
457  // matching algorithm. The second step is O(k * n) where k is the average
458  // size of each element.
459  void TreatAsMapWithMultipleFieldsAsKey(
460  const FieldDescriptor* field,
461  const std::vector<const FieldDescriptor*>& key_fields);
462  // Same as TreatAsMapWithMultipleFieldsAsKey, except that each of the field
463  // do not necessarily need to be a direct subfield. Each element in
464  // key_field_paths indicate a path from the message being compared, listing
465  // successive subfield to reach the key field.
466  //
467  // REQUIRES:
468  // for key_field_path in key_field_paths:
469  // key_field_path[0]->containing_type() == field->message_type()
470  // for i in [0, key_field_path.size() - 1):
471  // key_field_path[i+1]->containing_type() ==
472  // key_field_path[i]->message_type()
473  // key_field_path[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE
474  // !key_field_path[i]->is_repeated()
475  void TreatAsMapWithMultipleFieldPathsAsKey(
476  const FieldDescriptor* field,
477  const std::vector<std::vector<const FieldDescriptor*> >& key_field_paths);
478 
479  // Uses a custom MapKeyComparator to determine if two elements have the same
480  // key when comparing a repeated field as a map.
481  // The caller is responsible to delete the key_comparator.
482  // This method varies from TreatAsMapWithMultipleFieldsAsKey only in the
483  // first key matching step. Rather than comparing some specified fields, it
484  // will invoke the IsMatch method of the given 'key_comparator' to decide if
485  // two elements have the same key.
486  void TreatAsMapUsingKeyComparator(const FieldDescriptor* field,
487  const MapKeyComparator* key_comparator);
488 
489  // Initiates and returns a new instance of MultipleFieldsMapKeyComparator.
490  MapKeyComparator* CreateMultipleFieldsMapKeyComparator(
491  const std::vector<std::vector<const FieldDescriptor*> >& key_field_paths);
492 
493  // Add a custom ignore criteria that is evaluated in addition to the
494  // ignored fields added with IgnoreField.
495  // Takes ownership of ignore_criteria.
496  void AddIgnoreCriteria(IgnoreCriteria* ignore_criteria);
497 
498  // Indicates that any field with the given descriptor should be
499  // ignored for the purposes of comparing two messages. This applies
500  // to fields nested in the message structure as well as top level
501  // ones. When the MessageDifferencer encounters an ignored field,
502  // ReportIgnored is called on the reporter, if one is specified.
503  //
504  // The only place where the field's 'ignored' status is not applied is when
505  // it is being used as a key in a field passed to TreatAsMap or is one of
506  // the fields passed to TreatAsMapWithMultipleFieldsAsKey.
507  // In this case it is compared in key matching but after that it's ignored
508  // in value comparison.
509  void IgnoreField(const FieldDescriptor* field);
510 
511  // Sets the field comparator used to determine differences between protocol
512  // buffer fields. By default it's set to a DefaultFieldComparator instance.
513  // MessageDifferencer doesn't take ownership over the passed object.
514  // Note that this method must be called before Compare for the comparator to
515  // be used.
516  void set_field_comparator(FieldComparator* comparator);
517 
518  // DEPRECATED. Pass a DefaultFieldComparator instance instead.
519  // Sets the fraction and margin for the float comparison of a given field.
520  // Uses MathUtil::WithinFractionOrMargin to compare the values.
521  // NOTE: this method does nothing if differencer's field comparator has been
522  // set to a custom object.
523  //
524  // REQUIRES: field->cpp_type == FieldDescriptor::CPPTYPE_DOUBLE or
525  // field->cpp_type == FieldDescriptor::CPPTYPE_FLOAT
526  // REQUIRES: float_comparison_ == APPROXIMATE
527  void SetFractionAndMargin(const FieldDescriptor* field, double fraction,
528  double margin);
529 
530  // Sets the type of comparison (as defined in the MessageFieldComparison
531  // enumeration above) that is used by this differencer when determining how
532  // to compare fields in messages.
533  void set_message_field_comparison(MessageFieldComparison comparison);
534 
535  // Tells the differencer whether or not to report matches. This method must
536  // be called before Compare. The default for a new differencer is false.
537  void set_report_matches(bool report_matches) {
538  report_matches_ = report_matches;
539  }
540 
541  // Tells the differencer whether or not to report moves (in a set or map
542  // repeated field). This method must be called before Compare. The default for
543  // a new differencer is true.
544  void set_report_moves(bool report_moves) { report_moves_ = report_moves; }
545 
546  // Tells the differencer whether or not to report ignored values. This method
547  // must be called before Compare. The default for a new differencer is true.
548  void set_report_ignores(bool report_ignores) {
549  report_ignores_ = report_ignores;
550  }
551 
552  // Sets the scope of the comparison (as defined in the Scope enumeration
553  // above) that is used by this differencer when determining which fields to
554  // compare between the messages.
555  void set_scope(Scope scope);
556 
557  // Returns the current scope used by this differencer.
558  Scope scope();
559 
560  // DEPRECATED. Pass a DefaultFieldComparator instance instead.
561  // Sets the type of comparison (as defined in the FloatComparison enumeration
562  // above) that is used by this differencer when comparing float (and double)
563  // fields in messages.
564  // NOTE: this method does nothing if differencer's field comparator has been
565  // set to a custom object.
566  void set_float_comparison(FloatComparison comparison);
567 
568  // Sets the type of comparison for repeated field (as defined in the
569  // RepeatedFieldComparison enumeration above) that is used by this
570  // differencer when compare repeated fields in messages.
571  void set_repeated_field_comparison(RepeatedFieldComparison comparison);
572 
573  // Compares the two specified messages, returning true if they are the same,
574  // false otherwise. If this method returns false, any changes between the
575  // two messages will be reported if a Reporter was specified via
576  // ReportDifferencesTo (see also ReportDifferencesToString).
577  //
578  // This method REQUIRES that the two messages have the same
579  // Descriptor (message1.GetDescriptor() == message2.GetDescriptor()).
580  bool Compare(const Message& message1, const Message& message2);
581 
582  // Same as above, except comparing only the list of fields specified by the
583  // two vectors of FieldDescriptors.
584  bool CompareWithFields(
585  const Message& message1, const Message& message2,
586  const std::vector<const FieldDescriptor*>& message1_fields,
587  const std::vector<const FieldDescriptor*>& message2_fields);
588 
589  // Automatically creates a reporter that will output the differences
590  // found (if any) to the specified output string pointer. Note that this
591  // method must be called before Compare.
592  void ReportDifferencesToString(std::string* output);
593 
594  // Tells the MessageDifferencer to report differences via the specified
595  // reporter. Note that this method must be called before Compare for
596  // the reporter to be used. It is the responsibility of the caller to delete
597  // this object.
598  // If the provided pointer equals NULL, the MessageDifferencer stops reporting
599  // differences to any previously set reporters or output strings.
600  void ReportDifferencesTo(Reporter* reporter);
601 
602  // An implementation of the MessageDifferencer Reporter that outputs
603  // any differences found in human-readable form to the supplied
604  // ZeroCopyOutputStream or Printer. If a printer is used, the delimiter
605  // *must* be '$'.
606  //
607  // WARNING: this reporter does not necessarily flush its output until it is
608  // destroyed. As a result, it is not safe to assume the output is valid or
609  // complete until after you destroy the reporter. For example, if you use a
610  // StreamReporter to write to a StringOutputStream, the target string may
611  // contain uninitialized data until the reporter is destroyed.
612  class PROTOBUF_EXPORT StreamReporter : public Reporter {
613  public:
615  explicit StreamReporter(io::Printer* printer); // delimiter '$'
616  ~StreamReporter() override;
617 
618  // When set to true, the stream reporter will also output aggregates nodes
619  // (i.e. messages and groups) whose subfields have been modified. When
620  // false, will only report the individual subfields. Defaults to false.
621  void set_report_modified_aggregates(bool report) {
622  report_modified_aggregates_ = report;
623  }
624 
625  // The following are implementations of the methods described above.
626 
627  void ReportAdded(const Message& message1, const Message& message2,
628  const std::vector<SpecificField>& field_path) override;
629 
630  void ReportDeleted(const Message& message1, const Message& message2,
631  const std::vector<SpecificField>& field_path) override;
632 
633  void ReportModified(const Message& message1, const Message& message2,
634  const std::vector<SpecificField>& field_path) override;
635 
636  void ReportMoved(const Message& message1, const Message& message2,
637  const std::vector<SpecificField>& field_path) override;
638 
639  void ReportMatched(const Message& message1, const Message& message2,
640  const std::vector<SpecificField>& field_path) override;
641 
642  void ReportIgnored(const Message& message1, const Message& message2,
643  const std::vector<SpecificField>& field_path) override;
644 
645  void ReportUnknownFieldIgnored(
646  const Message& message1, const Message& message2,
647  const std::vector<SpecificField>& field_path) override;
648 
649  protected:
650  // Prints the specified path of fields to the buffer. message is used to
651  // print map keys.
652  virtual void PrintPath(const std::vector<SpecificField>& field_path,
653  bool left_side, const Message& message);
654 
655  // Prints the specified path of fields to the buffer.
656  virtual void PrintPath(const std::vector<SpecificField>& field_path,
657  bool left_side);
658 
659  // Prints the value of fields to the buffer. left_side is true if the
660  // given message is from the left side of the comparison, false if it
661  // was the right. This is relevant only to decide whether to follow
662  // unknown_field_index1 or unknown_field_index2 when an unknown field
663  // is encountered in field_path.
664  virtual void PrintValue(const Message& message,
665  const std::vector<SpecificField>& field_path,
666  bool left_side);
667 
668  // Prints the specified path of unknown fields to the buffer.
669  virtual void PrintUnknownFieldValue(const UnknownField* unknown_field);
670 
671  // Just print a string
672  void Print(const std::string& str);
673 
674  private:
678 
680  };
681 
682  private:
684 
685  // A MapKeyComparator to be used in TreatAsMapUsingKeyComparator.
686  // Implementation of this class needs to do field value comparison which
687  // relies on some private methods of MessageDifferencer. That's why this
688  // class is declared as a nested class of MessageDifferencer.
690 
691  // A MapKeyComparator for use with map_entries.
692  class PROTOBUF_EXPORT MapEntryKeyComparator : public MapKeyComparator {
693  public:
694  explicit MapEntryKeyComparator(MessageDifferencer* message_differencer);
695  bool IsMatch(
696  const Message& message1, const Message& message2,
697  const std::vector<SpecificField>& parent_fields) const override;
698 
699  private:
701  };
702 
703  // Returns true if field1's number() is less than field2's.
704  static bool FieldBefore(const FieldDescriptor* field1,
705  const FieldDescriptor* field2);
706 
707  // Retrieve all the set fields, including extensions.
708  FieldDescriptorArray RetrieveFields(const Message& message,
709  bool base_message);
710 
711  // Combine the two lists of fields into the combined_fields output vector.
712  // All fields present in both lists will always be included in the combined
713  // list. Fields only present in one of the lists will only appear in the
714  // combined list if the corresponding fields_scope option is set to FULL.
715  FieldDescriptorArray CombineFields(const FieldDescriptorArray& fields1,
716  Scope fields1_scope,
717  const FieldDescriptorArray& fields2,
718  Scope fields2_scope);
719 
720  // Internal version of the Compare method which performs the actual
721  // comparison. The parent_fields vector is a vector containing field
722  // descriptors of all fields accessed to get to this comparison operation
723  // (i.e. if the current message is an embedded message, the parent_fields
724  // vector will contain the field that has this embedded message).
725  bool Compare(const Message& message1, const Message& message2,
726  std::vector<SpecificField>* parent_fields);
727 
728  // Compares all the unknown fields in two messages.
729  bool CompareUnknownFields(const Message& message1, const Message& message2,
730  const UnknownFieldSet&, const UnknownFieldSet&,
731  std::vector<SpecificField>* parent_fields);
732 
733  // Compares the specified messages for the requested field lists. The field
734  // lists are modified depending on comparison settings, and then passed to
735  // CompareWithFieldsInternal.
736  bool CompareRequestedFieldsUsingSettings(
737  const Message& message1, const Message& message2,
738  const FieldDescriptorArray& message1_fields,
739  const FieldDescriptorArray& message2_fields,
740  std::vector<SpecificField>* parent_fields);
741 
742  // Compares the specified messages with the specified field lists.
743  bool CompareWithFieldsInternal(const Message& message1,
744  const Message& message2,
745  const FieldDescriptorArray& message1_fields,
746  const FieldDescriptorArray& message2_fields,
747  std::vector<SpecificField>* parent_fields);
748 
749  // Compares the repeated fields, and report the error.
750  bool CompareRepeatedField(const Message& message1, const Message& message2,
751  const FieldDescriptor* field,
752  std::vector<SpecificField>* parent_fields);
753 
754  // Shorthand for CompareFieldValueUsingParentFields with NULL parent_fields.
755  bool CompareFieldValue(const Message& message1, const Message& message2,
756  const FieldDescriptor* field, int index1, int index2);
757 
758  // Compares the specified field on the two messages, returning
759  // true if they are the same, false otherwise. For repeated fields,
760  // this method only compares the value in the specified index. This method
761  // uses Compare functions to recurse into submessages.
762  // The parent_fields vector is used in calls to a Reporter instance calls.
763  // It can be NULL, in which case the MessageDifferencer will create new
764  // list of parent messages if it needs to recursively compare the given field.
765  // To avoid confusing users you should not set it to NULL unless you modified
766  // Reporter to handle the change of parent_fields correctly.
767  bool CompareFieldValueUsingParentFields(
768  const Message& message1, const Message& message2,
769  const FieldDescriptor* field, int index1, int index2,
770  std::vector<SpecificField>* parent_fields);
771 
772  // Compares the specified field on the two messages, returning comparison
773  // result, as returned by appropriate FieldComparator.
774  FieldComparator::ComparisonResult GetFieldComparisonResult(
775  const Message& message1, const Message& message2,
776  const FieldDescriptor* field, int index1, int index2,
777  const FieldContext* field_context);
778 
779  // Check if the two elements in the repeated field are match to each other.
780  // if the key_comprator is NULL, this function returns true when the two
781  // elements are equal.
782  bool IsMatch(const FieldDescriptor* repeated_field,
783  const MapKeyComparator* key_comparator, const Message* message1,
784  const Message* message2,
785  const std::vector<SpecificField>& parent_fields,
786  Reporter* reporter, int index1, int index2);
787 
788  // Returns true when this repeated field has been configured to be treated
789  // as a Set / SmartSet / SmartList.
790  bool IsTreatedAsSet(const FieldDescriptor* field);
791  bool IsTreatedAsSmartSet(const FieldDescriptor* field);
792 
793  bool IsTreatedAsSmartList(const FieldDescriptor* field);
794  // When treating as SMART_LIST, it uses MatchIndicesPostProcessorForSmartList
795  // by default to find the longest matching sequence from the first matching
796  // element. The callback takes two vectors showing the matching indices from
797  // the other vector, where -1 means an unmatch.
798  void SetMatchIndicesForSmartListCallback(
799  std::function<void(std::vector<int>*, std::vector<int>*)> callback);
800 
801  // Returns true when this repeated field is to be compared as a subset, ie.
802  // has been configured to be treated as a set or map and scope is set to
803  // PARTIAL.
804  bool IsTreatedAsSubset(const FieldDescriptor* field);
805 
806  // Returns true if this field is to be ignored when this
807  // MessageDifferencer compares messages.
808  bool IsIgnored(const Message& message1, const Message& message2,
809  const FieldDescriptor* field,
810  const std::vector<SpecificField>& parent_fields);
811 
812  // Returns true if this unknown field is to be ignored when this
813  // MessageDifferencer compares messages.
814  bool IsUnknownFieldIgnored(const Message& message1, const Message& message2,
815  const SpecificField& field,
816  const std::vector<SpecificField>& parent_fields);
817 
818  // Returns MapKeyComparator* when this field has been configured to be treated
819  // as a map or its is_map() return true. If not, returns NULL.
820  const MapKeyComparator* GetMapKeyComparator(
821  const FieldDescriptor* field) const;
822 
823  // Attempts to match indices of a repeated field, so that the contained values
824  // match. Clears output vectors and sets their values to indices of paired
825  // messages, ie. if message1[0] matches message2[1], then match_list1[0] == 1
826  // and match_list2[1] == 0. The unmatched indices are indicated by -1.
827  // Assumes the repeated field is not treated as a simple list.
828  // This method returns false if the match failed. However, it doesn't mean
829  // that the comparison succeeds when this method returns true (you need to
830  // double-check in this case).
831  bool MatchRepeatedFieldIndices(
832  const Message& message1, const Message& message2,
834  const MapKeyComparator* key_comparator,
835  const std::vector<SpecificField>& parent_fields,
836  std::vector<int>* match_list1, std::vector<int>* match_list2);
837 
838  // If "any" is of type google.protobuf.Any, extract its payload using
839  // DynamicMessageFactory and store in "data".
840  bool UnpackAny(const Message& any, std::unique_ptr<Message>* data);
841 
842  // Checks if index is equal to new_index in all the specific fields.
843  static bool CheckPathChanged(const std::vector<SpecificField>& parent_fields);
844 
845  // CHECKs that the given repeated field can be compared according to
846  // new_comparison.
847  void CheckRepeatedFieldComparisons(
848  const FieldDescriptor* field,
849  const RepeatedFieldComparison& new_comparison);
850 
851  // Defines a map between field descriptors and their MapKeyComparators.
852  // Used for repeated fields when they are configured as TreatAsMap.
853  typedef std::map<const FieldDescriptor*, const MapKeyComparator*>
855 
856  // Defines a set to store field descriptors. Used for repeated fields when
857  // they are configured as TreatAsSet.
858  typedef std::set<const FieldDescriptor*> FieldSet;
859  typedef std::map<const FieldDescriptor*, RepeatedFieldComparison> FieldMap;
860 
867 
869  // Keeps track of MapKeyComparators that are created within
870  // MessageDifferencer. These MapKeyComparators should be deleted
871  // before MessageDifferencer is destroyed.
872  // When TreatAsMap or TreatAsMapWithMultipleFieldsAsKey is called, we don't
873  // store the supplied FieldDescriptors directly. Instead, a new
874  // MapKeyComparator is created for comparison purpose.
875  std::vector<MapKeyComparator*> owned_key_comparators_;
878  std::vector<IgnoreCriteria*> ignore_criteria_;
879  // Reused multiple times in RetrieveFields to avoid extra allocations
880  std::vector<const FieldDescriptor*> tmp_message_fields_;
881 
883 
887 
889 
890  // Callback to post-process the matched indices to support SMART_LIST.
891  std::function<void(std::vector<int>*, std::vector<int>*)>
893 
894  std::unique_ptr<DynamicMessageFactory> dynamic_message_factory_;
896 };
897 
898 // This class provides extra information to the FieldComparator::Compare
899 // function.
900 class PROTOBUF_EXPORT FieldContext {
901  public:
902  explicit FieldContext(
903  std::vector<MessageDifferencer::SpecificField>* parent_fields)
904  : parent_fields_(parent_fields) {}
905 
906  std::vector<MessageDifferencer::SpecificField>* parent_fields() const {
907  return parent_fields_;
908  }
909 
910  private:
911  std::vector<MessageDifferencer::SpecificField>* parent_fields_;
912 };
913 
914 } // namespace util
915 } // namespace protobuf
916 } // namespace google
917 
918 #include <google/protobuf/port_undef.inc>
919 
920 #endif // GOOGLE_PROTOBUF_UTIL_MESSAGE_DIFFERENCER_H__
google::protobuf::util::MessageDifferencer::scope_
Scope scope_
Definition: message_differencer.h:865
google::protobuf::util::MessageDifferencer::set_report_matches
void set_report_matches(bool report_matches)
Definition: message_differencer.h:537
google::protobuf::util::MessageDifferencer::report_matches_
bool report_matches_
Definition: message_differencer.h:884
google::protobuf::FieldDescriptor
Definition: src/google/protobuf/descriptor.h:515
google::protobuf::util::MessageDifferencer
Definition: message_differencer.h:120
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS
#define GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeName)
Definition: macros.h:40
google::protobuf::util::MessageDifferencer::map_entry_key_comparator_
MapEntryKeyComparator map_entry_key_comparator_
Definition: message_differencer.h:877
google::protobuf::util::MessageDifferencer::Scope
Scope
Definition: message_differencer.h:359
google::protobuf::util::MessageDifferencer::field_comparator_
FieldComparator * field_comparator_
Definition: message_differencer.h:863
NULL
NULL
Definition: test_security_zap.cpp:405
google::protobuf::util::MessageDifferencer::MultipleFieldsMapKeyComparator
Definition: message_differencer.cc:107
google::protobuf::util::MessageDifferencer::dynamic_message_factory_
std::unique_ptr< DynamicMessageFactory > dynamic_message_factory_
Definition: message_differencer.h:894
testing::gtest_printers_test::Print
std::string Print(const T &value)
Definition: googletest-printers-test.cc:233
google::protobuf::util::MessageDifferencer::StreamReporter::printer_
io::Printer * printer_
Definition: message_differencer.h:675
google::protobuf::util::MessageDifferencer::Reporter::ReportMatched
virtual void ReportMatched(const Message &, const Message &, const std::vector< SpecificField > &)
Definition: message_differencer.h:260
google::protobuf::util::FieldComparator
Definition: field_comparator.h:60
google::protobuf::util::MessageDifferencer::Reporter
Definition: message_differencer.h:228
google::protobuf::UnknownField
Definition: unknown_field_set.h:223
google::protobuf::util::MessageDifferencer::report_ignores_
bool report_ignores_
Definition: message_differencer.h:886
google::protobuf::util::MessageDifferencer::SpecificField::unknown_field_set1
const UnknownFieldSet * unknown_field_set1
Definition: message_differencer.h:199
string
GLsizei const GLchar *const * string
Definition: glcorearb.h:3083
google::protobuf::util::MessageDifferencer::MapKeyComparator::IsMatch
virtual bool IsMatch(const Message &, const Message &, const std::vector< SpecificField > &) const
Definition: message_differencer.h:305
google::protobuf::util::MessageDifferencer::match_indices_for_smart_list_callback_
std::function< void(std::vector< int > *, std::vector< int > *)> match_indices_for_smart_list_callback_
Definition: message_differencer.h:892
google::protobuf::util::MessageDifferencer::set_report_ignores
void set_report_ignores(bool report_ignores)
Definition: message_differencer.h:548
google::protobuf::util::MessageDifferencer::SpecificField::unknown_field_index1
int unknown_field_index1
Definition: message_differencer.h:205
google::protobuf::util::MessageDifferencer::repeated_field_comparison_
RepeatedFieldComparison repeated_field_comparison_
Definition: message_differencer.h:866
google::protobuf::util::FieldContext
Definition: message_differencer.h:900
google::protobuf::util::MessageDifferencer::EXACT
@ EXACT
Definition: message_differencer.h:368
google::protobuf::util::MessageDifferencer::FieldSet
std::set< const FieldDescriptor * > FieldSet
Definition: message_differencer.h:858
FieldDescriptor
Definition: ruby/ext/google/protobuf_c/protobuf.h:129
google::protobuf::util::MessageDifferencer::SpecificField
Definition: message_differencer.h:176
google::protobuf::util::MessageDifferencer::MessageFieldComparison
MessageFieldComparison
Definition: message_differencer.h:350
google::protobuf::util::MessageDifferencer::AS_SMART_LIST
@ AS_SMART_LIST
Definition: message_differencer.h:381
google::protobuf::util::MessageDifferencer::RepeatedFieldComparison
RepeatedFieldComparison
Definition: message_differencer.h:373
repeated_field
PHP_PROTO_OBJECT_FREE_END PHP_PROTO_OBJECT_DTOR_END intern repeated_field
Definition: array.c:486
unknown_field_set.h
google::protobuf::util::MessageDifferencer::IgnoreCriteria::IsUnknownFieldIgnored
virtual bool IsUnknownFieldIgnored(const Message &, const Message &, const SpecificField &, const std::vector< SpecificField > &)
Definition: message_differencer.h:336
google::protobuf::util::MessageDifferencer::repeated_field_comparisons_
FieldMap repeated_field_comparisons_
Definition: message_differencer.h:868
google::protobuf::util::MessageDifferencer::MapEntryKeyComparator
Definition: message_differencer.h:692
update_failure_list.str
str
Definition: update_failure_list.py:41
google::protobuf::util::MessageDifferencer::AS_SET
@ AS_SET
Definition: message_differencer.h:379
google::protobuf::util::MessageDifferencer::output_string_
std::string * output_string_
Definition: message_differencer.h:888
message.h
google::protobuf::util::MessageDifferencer::SpecificField::unknown_field_index2
int unknown_field_index2
Definition: message_differencer.h:206
google::protobuf::util::MessageDifferencer::StreamReporter::set_report_modified_aggregates
void set_report_modified_aggregates(bool report)
Definition: message_differencer.h:621
google::protobuf::util::MessageDifferencer::AS_LIST
@ AS_LIST
Definition: message_differencer.h:374
google::protobuf::util::FieldContext::parent_fields
std::vector< MessageDifferencer::SpecificField > * parent_fields() const
Definition: message_differencer.h:906
google::protobuf::util::MessageDifferencer::StreamReporter::report_modified_aggregates_
bool report_modified_aggregates_
Definition: message_differencer.h:677
google::protobuf::util::MessageDifferencer::EQUIVALENT
@ EQUIVALENT
Definition: message_differencer.h:353
field
const FieldDescriptor * field
Definition: parser_unittest.cc:2694
google::protobuf::util::MessageDifferencer::SpecificField::unknown_field_set2
const UnknownFieldSet * unknown_field_set2
Definition: message_differencer.h:200
key
const SETUP_TEARDOWN_TESTCONTEXT char * key
Definition: test_wss_transport.cpp:10
google::protobuf::util::MessageDifferencer::MapKeyComparator
Definition: message_differencer.h:300
GOOGLE_CHECK
#define GOOGLE_CHECK(EXPRESSION)
Definition: logging.h:153
google::protobuf::io::Printer
Definition: printer.h:181
google::protobuf::util::MessageDifferencer::ignore_criteria_
std::vector< IgnoreCriteria * > ignore_criteria_
Definition: message_differencer.h:878
google::protobuf::util::MessageDifferencer::SpecificField::new_index
int new_index
Definition: message_differencer.h:193
void
typedef void(APIENTRY *GLDEBUGPROCARB)(GLenum source
google::protobuf::util::MessageDifferencer::FloatComparison
FloatComparison
Definition: message_differencer.h:367
google::protobuf::util::MessageDifferencer::Reporter::ReportUnknownFieldIgnored
virtual void ReportUnknownFieldIgnored(const Message &, const Message &, const std::vector< SpecificField > &)
Definition: message_differencer.h:290
google::protobuf::util::MessageDifferencer::StreamReporter
Definition: message_differencer.h:612
google::protobuf::util::MessageDifferencer::message_field_comparison_
MessageFieldComparison message_field_comparison_
Definition: message_differencer.h:864
google::protobuf::Message
Definition: src/google/protobuf/message.h:205
google::protobuf::util::MessageDifferencer::report_moves_
bool report_moves_
Definition: message_differencer.h:885
google::protobuf::util::MessageDifferencer::reporter_
Reporter * reporter_
Definition: message_differencer.h:861
google::protobuf::util::MessageDifferencer::map_field_key_comparator_
FieldKeyComparatorMap map_field_key_comparator_
Definition: message_differencer.h:876
google::protobuf::util::MessageDifferencer::SpecificField::unknown_field_number
int unknown_field_number
Definition: message_differencer.h:181
google::protobuf::util::FieldDescriptorArray
std::vector< const FieldDescriptor * > FieldDescriptorArray
Definition: message_differencer.h:73
PrintValue
::std::string PrintValue(const T &value)
Definition: googletest-param-test-test.cc:69
google::protobuf::util::MessageDifferencer::AS_SMART_SET
@ AS_SMART_SET
Definition: message_differencer.h:385
google::protobuf::util::MessageDifferencer::StreamReporter::delete_printer_
bool delete_printer_
Definition: message_differencer.h:676
google::protobuf::util::MessageDifferencer::Reporter::ReportMoved
virtual void ReportMoved(const Message &, const Message &, const std::vector< SpecificField > &)
Definition: message_differencer.h:252
field_comparator.h
google::protobuf::UnknownFieldSet
Definition: unknown_field_set.h:86
google::protobuf::io::ZeroCopyOutputStream
Definition: zero_copy_stream.h:183
google::protobuf::util::MessageDifferencer::SpecificField::unknown_field_type
UnknownField::Type unknown_field_type
Definition: message_differencer.h:182
google::protobuf::util::MessageDifferencer::IgnoreCriteria
Definition: message_differencer.h:322
google::protobuf::util::MessageDifferencer::FieldKeyComparatorMap
std::map< const FieldDescriptor *, const MapKeyComparator * > FieldKeyComparatorMap
Definition: message_differencer.h:854
descriptor.h
google::protobuf::util::MessageDifferencer::MapEntryKeyComparator::message_differencer_
MessageDifferencer * message_differencer_
Definition: message_differencer.h:700
google::protobuf::util::MessageDifferencer::default_field_comparator_
DefaultFieldComparator default_field_comparator_
Definition: message_differencer.h:862
google::protobuf::util::MessageDifferencer::Reporter::ReportIgnored
virtual void ReportIgnored(const Message &, const Message &, const std::vector< SpecificField > &)
Definition: message_differencer.h:283
google::protobuf::util::FieldComparator::ComparisonResult
ComparisonResult
Definition: field_comparator.h:65
google::protobuf::util::MessageDifferencer::EQUAL
@ EQUAL
Definition: message_differencer.h:351
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: glcorearb.h:2879
google::protobuf::util::MessageDifferencer::SpecificField::SpecificField
SpecificField()
Definition: message_differencer.h:208
google::protobuf::util::FieldContext::FieldContext
FieldContext(std::vector< MessageDifferencer::SpecificField > *parent_fields)
Definition: message_differencer.h:902
google::protobuf::util::MessageDifferencer::FieldMap
std::map< const FieldDescriptor *, RepeatedFieldComparison > FieldMap
Definition: message_differencer.h:859
google::protobuf::util::FieldContext::parent_fields_
std::vector< MessageDifferencer::SpecificField > * parent_fields_
Definition: message_differencer.h:911
google::protobuf::util::MessageDifferencer::tmp_message_fields_
std::vector< const FieldDescriptor * > tmp_message_fields_
Definition: message_differencer.h:880
google::protobuf::util::MessageDifferencer::set_report_moves
void set_report_moves(bool report_moves)
Definition: message_differencer.h:544
google::protobuf::util::MessageDifferencer::SpecificField::index
int index
Definition: message_differencer.h:187
google::protobuf::util::DefaultFieldComparator
Definition: field_comparator.h:100
google::protobuf::util::MessageDifferencer::owned_key_comparators_
std::vector< MapKeyComparator * > owned_key_comparators_
Definition: message_differencer.h:875
output
const upb_json_parsermethod const upb_symtab upb_sink * output
Definition: ruby/ext/google/protobuf_c/upb.h:10503
index
GLuint index
Definition: glcorearb.h:3055
google
Definition: data_proto2_to_proto3_util.h:11
message
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: glcorearb.h:2695
google::protobuf::util::MessageDifferencer::ignored_fields_
FieldSet ignored_fields_
Definition: message_differencer.h:882
google::protobuf::util::MessageDifferencer::SpecificField::field
const FieldDescriptor * field
Definition: message_differencer.h:180
google::protobuf::util::MessageDifferencer::FULL
@ FULL
Definition: message_differencer.h:360
parent_fields_
std::vector< util::MessageDifferencer::SpecificField > parent_fields_
Definition: message_differencer_unittest.cc:2291
google::protobuf::UnknownField::Type
Type
Definition: unknown_field_set.h:225


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:56