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


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:25