summaryrefslogtreecommitdiffstats
path: root/toolkit/components/protobuf/src/google/protobuf/util/field_comparator.h
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/protobuf/src/google/protobuf/util/field_comparator.h')
-rw-r--r--toolkit/components/protobuf/src/google/protobuf/util/field_comparator.h288
1 files changed, 288 insertions, 0 deletions
diff --git a/toolkit/components/protobuf/src/google/protobuf/util/field_comparator.h b/toolkit/components/protobuf/src/google/protobuf/util/field_comparator.h
new file mode 100644
index 0000000000..5706da357a
--- /dev/null
+++ b/toolkit/components/protobuf/src/google/protobuf/util/field_comparator.h
@@ -0,0 +1,288 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Defines classes for field comparison.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_FIELD_COMPARATOR_H__
+#define GOOGLE_PROTOBUF_UTIL_FIELD_COMPARATOR_H__
+
+
+#include <cstdint>
+#include <map>
+#include <string>
+#include <vector>
+
+#include <google/protobuf/stubs/common.h>
+
+// Must be included last.
+#include <google/protobuf/port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+class Message;
+class EnumValueDescriptor;
+class FieldDescriptor;
+
+namespace util {
+
+class FieldContext;
+class MessageDifferencer;
+
+// Base class specifying the interface for comparing protocol buffer fields.
+// Regular users should consider using or subclassing DefaultFieldComparator
+// rather than this interface.
+// Currently, this does not support comparing unknown fields.
+class PROTOBUF_EXPORT FieldComparator {
+ public:
+ FieldComparator();
+ virtual ~FieldComparator();
+
+ enum ComparisonResult {
+ SAME, // Compared fields are equal. In case of comparing submessages,
+ // user should not recursively compare their contents.
+ DIFFERENT, // Compared fields are different. In case of comparing
+ // submessages, user should not recursively compare their
+ // contents.
+ RECURSE, // Compared submessages need to be compared recursively.
+ // FieldComparator does not specify the semantics of recursive
+ // comparison. This value should not be returned for simple
+ // values.
+ };
+
+ // Compares the values of a field in two protocol buffer messages.
+ // Returns SAME or DIFFERENT for simple values, and SAME, DIFFERENT or RECURSE
+ // for submessages. Returning RECURSE for fields not being submessages is
+ // illegal.
+ // In case the given FieldDescriptor points to a repeated field, the indices
+ // need to be valid. Otherwise they should be ignored.
+ //
+ // FieldContext contains information about the specific instances of the
+ // fields being compared, versus FieldDescriptor which only contains general
+ // type information about the fields.
+ virtual ComparisonResult Compare(const Message& message_1,
+ const Message& message_2,
+ const FieldDescriptor* field, int index_1,
+ int index_2,
+ const util::FieldContext* field_context) = 0;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldComparator);
+};
+
+// Basic implementation of FieldComparator. Supports three modes of floating
+// point value comparison: exact, approximate using MathUtil::AlmostEqual
+// method, and arbitrarily precise using MathUtil::WithinFractionOrMargin.
+class PROTOBUF_EXPORT SimpleFieldComparator : public FieldComparator {
+ public:
+ enum FloatComparison {
+ EXACT, // Floats and doubles are compared exactly.
+ APPROXIMATE, // Floats and doubles are compared using the
+ // MathUtil::AlmostEqual method or
+ // MathUtil::WithinFractionOrMargin method.
+ // TODO(ksroka): Introduce third value to differentiate uses of AlmostEqual
+ // and WithinFractionOrMargin.
+ };
+
+ // Creates new comparator with float comparison set to EXACT.
+ SimpleFieldComparator();
+
+ ~SimpleFieldComparator() override;
+
+ void set_float_comparison(FloatComparison float_comparison) {
+ float_comparison_ = float_comparison;
+ }
+
+ FloatComparison float_comparison() const { return float_comparison_; }
+
+ // Set whether the FieldComparator shall treat floats or doubles that are both
+ // NaN as equal (treat_nan_as_equal = true) or as different
+ // (treat_nan_as_equal = false). Default is treating NaNs always as different.
+ void set_treat_nan_as_equal(bool treat_nan_as_equal) {
+ treat_nan_as_equal_ = treat_nan_as_equal;
+ }
+
+ bool treat_nan_as_equal() const { return treat_nan_as_equal_; }
+
+ // Sets the fraction and margin for the float comparison of a given field.
+ // Uses MathUtil::WithinFractionOrMargin to compare the values.
+ //
+ // REQUIRES: field->cpp_type == FieldDescriptor::CPPTYPE_DOUBLE or
+ // field->cpp_type == FieldDescriptor::CPPTYPE_FLOAT
+ // REQUIRES: float_comparison_ == APPROXIMATE
+ void SetFractionAndMargin(const FieldDescriptor* field, double fraction,
+ double margin);
+
+ // Sets the fraction and margin for the float comparison of all float and
+ // double fields, unless a field has been given a specific setting via
+ // SetFractionAndMargin() above.
+ // Uses MathUtil::WithinFractionOrMargin to compare the values.
+ //
+ // REQUIRES: float_comparison_ == APPROXIMATE
+ void SetDefaultFractionAndMargin(double fraction, double margin);
+
+ protected:
+ // Returns the comparison result for the given field in two messages.
+ //
+ // This function is called directly by DefaultFieldComparator::Compare.
+ // Subclasses can call this function to compare fields they do not need to
+ // handle specially.
+ ComparisonResult SimpleCompare(const Message& message_1,
+ const Message& message_2,
+ const FieldDescriptor* field, int index_1,
+ int index_2,
+ const util::FieldContext* field_context);
+
+ // Compare using the provided message_differencer. For example, a subclass can
+ // use this method to compare some field in a certain way using the same
+ // message_differencer instance and the field context.
+ bool CompareWithDifferencer(MessageDifferencer* differencer,
+ const Message& message1, const Message& message2,
+ const util::FieldContext* field_context);
+
+ // Returns FieldComparator::SAME if boolean_result is true and
+ // FieldComparator::DIFFERENT otherwise.
+ ComparisonResult ResultFromBoolean(bool boolean_result) const;
+
+ private:
+ // Defines the tolerance for floating point comparison (fraction and margin).
+ struct Tolerance {
+ double fraction;
+ double margin;
+ Tolerance() : fraction(0.0), margin(0.0) {}
+ Tolerance(double f, double m) : fraction(f), margin(m) {}
+ };
+
+ // Defines the map to store the tolerances for floating point comparison.
+ typedef std::map<const FieldDescriptor*, Tolerance> ToleranceMap;
+
+ friend class MessageDifferencer;
+ // The following methods get executed when CompareFields is called for the
+ // basic types (instead of submessages). They return true on success. One
+ // can use ResultFromBoolean() to convert that boolean to a ComparisonResult
+ // value.
+ bool CompareBool(const FieldDescriptor& /* unused */, bool value_1,
+ bool value_2) {
+ return value_1 == value_2;
+ }
+
+ // Uses CompareDoubleOrFloat, a helper function used by both CompareDouble and
+ // CompareFloat.
+ bool CompareDouble(const FieldDescriptor& field, double value_1,
+ double value_2);
+
+ bool CompareEnum(const FieldDescriptor& field,
+ const EnumValueDescriptor* value_1,
+ const EnumValueDescriptor* value_2);
+
+ // Uses CompareDoubleOrFloat, a helper function used by both CompareDouble and
+ // CompareFloat.
+ bool CompareFloat(const FieldDescriptor& field, float value_1, float value_2);
+
+ bool CompareInt32(const FieldDescriptor& /* unused */, int32_t value_1,
+ int32_t value_2) {
+ return value_1 == value_2;
+ }
+
+ bool CompareInt64(const FieldDescriptor& /* unused */, int64_t value_1,
+ int64_t value_2) {
+ return value_1 == value_2;
+ }
+
+ bool CompareString(const FieldDescriptor& /* unused */,
+ const std::string& value_1, const std::string& value_2) {
+ return value_1 == value_2;
+ }
+
+ bool CompareUInt32(const FieldDescriptor& /* unused */, uint32_t value_1,
+ uint32_t value_2) {
+ return value_1 == value_2;
+ }
+
+ bool CompareUInt64(const FieldDescriptor& /* unused */, uint64_t value_1,
+ uint64_t value_2) {
+ return value_1 == value_2;
+ }
+
+ // This function is used by CompareDouble and CompareFloat to avoid code
+ // duplication. There are no checks done against types of the values passed,
+ // but it's likely to fail if passed non-numeric arguments.
+ template <typename T>
+ bool CompareDoubleOrFloat(const FieldDescriptor& field, T value_1, T value_2);
+
+ FloatComparison float_comparison_;
+
+ // If true, floats and doubles that are both NaN are considered to be
+ // equal. Otherwise, two floats or doubles that are NaN are considered to be
+ // different.
+ bool treat_nan_as_equal_;
+
+ // True iff default_tolerance_ has been explicitly set.
+ //
+ // If false, then the default tolerance for floats and doubles is that which
+ // is used by MathUtil::AlmostEquals().
+ bool has_default_tolerance_;
+
+ // Default float/double tolerance. Only meaningful if
+ // has_default_tolerance_ == true.
+ Tolerance default_tolerance_;
+
+ // Field-specific float/double tolerances, which override any default for
+ // those particular fields.
+ ToleranceMap map_tolerance_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SimpleFieldComparator);
+};
+
+// Default field comparison: use the basic implementation of FieldComparator.
+#ifdef PROTOBUF_FUTURE_BREAKING_CHANGES
+class PROTOBUF_EXPORT DefaultFieldComparator final
+ : public SimpleFieldComparator
+#else // PROTOBUF_FUTURE_BREAKING_CHANGES
+class PROTOBUF_EXPORT DefaultFieldComparator : public SimpleFieldComparator
+#endif // PROTOBUF_FUTURE_BREAKING_CHANGES
+{
+ public:
+ ComparisonResult Compare(const Message& message_1, const Message& message_2,
+ const FieldDescriptor* field, int index_1,
+ int index_2,
+ const util::FieldContext* field_context) override {
+ return SimpleCompare(message_1, message_2, field, index_1, index_2,
+ field_context);
+ }
+};
+
+} // namespace util
+} // namespace protobuf
+} // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_UTIL_FIELD_COMPARATOR_H__