File indexing completed on 2025-01-31 10:12:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef GOOGLE_PROTOBUF_UTIL_FIELD_COMPARATOR_H__
0011 #define GOOGLE_PROTOBUF_UTIL_FIELD_COMPARATOR_H__
0012
0013 #include <cstdint>
0014 #include <string>
0015 #include <vector>
0016
0017 #include "google/protobuf/stubs/common.h"
0018 #include "absl/container/flat_hash_map.h"
0019 #include "google/protobuf/port.h"
0020
0021
0022 #include "google/protobuf/port_def.inc"
0023
0024 namespace google {
0025 namespace protobuf {
0026
0027 class Message;
0028 class EnumValueDescriptor;
0029 class FieldDescriptor;
0030
0031 namespace util {
0032
0033 class FieldContext;
0034 class MessageDifferencer;
0035
0036
0037
0038
0039
0040 class PROTOBUF_EXPORT FieldComparator {
0041 public:
0042 FieldComparator();
0043 FieldComparator(const FieldComparator&) = delete;
0044 FieldComparator& operator=(const FieldComparator&) = delete;
0045 virtual ~FieldComparator();
0046
0047 enum ComparisonResult {
0048 SAME,
0049
0050 DIFFERENT,
0051
0052
0053 RECURSE,
0054
0055
0056
0057 };
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069 virtual ComparisonResult Compare(const Message& message_1,
0070 const Message& message_2,
0071 const FieldDescriptor* field, int index_1,
0072 int index_2,
0073 const util::FieldContext* field_context) = 0;
0074 };
0075
0076
0077
0078
0079 class PROTOBUF_EXPORT SimpleFieldComparator : public FieldComparator {
0080 public:
0081 enum FloatComparison {
0082 EXACT,
0083 APPROXIMATE,
0084
0085
0086
0087
0088 };
0089
0090
0091 SimpleFieldComparator();
0092 SimpleFieldComparator(const SimpleFieldComparator&) = delete;
0093 SimpleFieldComparator& operator=(const SimpleFieldComparator&) = delete;
0094
0095 ~SimpleFieldComparator() override;
0096
0097 void set_float_comparison(FloatComparison float_comparison) {
0098 float_comparison_ = float_comparison;
0099 }
0100
0101 FloatComparison float_comparison() const { return float_comparison_; }
0102
0103
0104
0105
0106 void set_treat_nan_as_equal(bool treat_nan_as_equal) {
0107 treat_nan_as_equal_ = treat_nan_as_equal;
0108 }
0109
0110 bool treat_nan_as_equal() const { return treat_nan_as_equal_; }
0111
0112
0113
0114
0115
0116
0117
0118 void SetFractionAndMargin(const FieldDescriptor* field, double fraction,
0119 double margin);
0120
0121
0122
0123
0124
0125
0126
0127 void SetDefaultFractionAndMargin(double fraction, double margin);
0128
0129 protected:
0130
0131
0132
0133
0134
0135 ComparisonResult SimpleCompare(const Message& message_1,
0136 const Message& message_2,
0137 const FieldDescriptor* field, int index_1,
0138 int index_2,
0139 const util::FieldContext* field_context);
0140
0141
0142
0143
0144 bool CompareWithDifferencer(MessageDifferencer* differencer,
0145 const Message& message1, const Message& message2,
0146 const util::FieldContext* field_context);
0147
0148
0149
0150 ComparisonResult ResultFromBoolean(bool boolean_result) const;
0151
0152 private:
0153
0154 struct Tolerance {
0155 double fraction;
0156 double margin;
0157 Tolerance() : fraction(0.0), margin(0.0) {}
0158 Tolerance(double f, double m) : fraction(f), margin(m) {}
0159 };
0160
0161 friend class MessageDifferencer;
0162
0163
0164
0165
0166 bool CompareBool(const FieldDescriptor& , bool value_1,
0167 bool value_2) {
0168 return value_1 == value_2;
0169 }
0170
0171
0172
0173 bool CompareDouble(const FieldDescriptor& field, double value_1,
0174 double value_2);
0175
0176 bool CompareEnum(const FieldDescriptor& field,
0177 const EnumValueDescriptor* value_1,
0178 const EnumValueDescriptor* value_2);
0179
0180
0181
0182 bool CompareFloat(const FieldDescriptor& field, float value_1, float value_2);
0183
0184 bool CompareInt32(const FieldDescriptor& , int32_t value_1,
0185 int32_t value_2) {
0186 return value_1 == value_2;
0187 }
0188
0189 bool CompareInt64(const FieldDescriptor& , int64_t value_1,
0190 int64_t value_2) {
0191 return value_1 == value_2;
0192 }
0193
0194 bool CompareString(const FieldDescriptor& ,
0195 const std::string& value_1, const std::string& value_2) {
0196 return value_1 == value_2;
0197 }
0198
0199 bool CompareUInt32(const FieldDescriptor& , uint32_t value_1,
0200 uint32_t value_2) {
0201 return value_1 == value_2;
0202 }
0203
0204 bool CompareUInt64(const FieldDescriptor& , uint64_t value_1,
0205 uint64_t value_2) {
0206 return value_1 == value_2;
0207 }
0208
0209
0210
0211
0212 template <typename T>
0213 bool CompareDoubleOrFloat(const FieldDescriptor& field, T value_1, T value_2);
0214
0215 FloatComparison float_comparison_;
0216
0217
0218
0219
0220 bool treat_nan_as_equal_;
0221
0222
0223
0224
0225
0226 bool has_default_tolerance_;
0227
0228
0229
0230 Tolerance default_tolerance_;
0231
0232
0233
0234 absl::flat_hash_map<const FieldDescriptor*, Tolerance> map_tolerance_;
0235 };
0236
0237
0238 class PROTOBUF_EXPORT DefaultFieldComparator final
0239 : public SimpleFieldComparator {
0240 public:
0241 ComparisonResult Compare(const Message& message_1, const Message& message_2,
0242 const FieldDescriptor* field, int index_1,
0243 int index_2,
0244 const util::FieldContext* field_context) override {
0245 return SimpleCompare(message_1, message_2, field, index_1, index_2,
0246 field_context);
0247 }
0248 };
0249
0250 }
0251 }
0252 }
0253
0254 #include "google/protobuf/port_undef.inc"
0255
0256 #endif