Equality between map message fields.
| 874 | |
| 875 | // Equality between map message fields. |
| 876 | absl::StatusOr<bool> MapFieldEquals( |
| 877 | const Message& lhs, const FieldDescriptor* absl_nonnull lhs_field, |
| 878 | const Message& rhs, const FieldDescriptor* absl_nonnull rhs_field) { |
| 879 | ABSL_DCHECK(lhs_field->is_map()); |
| 880 | ABSL_DCHECK_EQ(lhs_field->containing_type(), lhs.GetDescriptor()); |
| 881 | ABSL_DCHECK(rhs_field->is_map()); |
| 882 | ABSL_DCHECK_EQ(rhs_field->containing_type(), rhs.GetDescriptor()); |
| 883 | const auto* lhs_entry = lhs_field->message_type(); |
| 884 | const auto* lhs_entry_key_field = lhs_entry->map_key(); |
| 885 | const auto* lhs_entry_value_field = lhs_entry->map_value(); |
| 886 | const auto* rhs_entry = rhs_field->message_type(); |
| 887 | const auto* rhs_entry_key_field = rhs_entry->map_key(); |
| 888 | const auto* rhs_entry_value_field = rhs_entry->map_value(); |
| 889 | // Perform cheap test which checks whether the left and right can even be |
| 890 | // compared for equality. |
| 891 | if (lhs_field != rhs_field && |
| 892 | ((GetEquatableFieldCategory(lhs_entry_key_field) & |
| 893 | GetEquatableFieldCategory(rhs_entry_key_field)) == |
| 894 | EquatableCategory::kNone || |
| 895 | (GetEquatableFieldCategory(lhs_entry_value_field) & |
| 896 | GetEquatableFieldCategory(rhs_entry_value_field)) == |
| 897 | EquatableCategory::kNone)) { |
| 898 | // Short-circuit. |
| 899 | return false; |
| 900 | } |
| 901 | const auto* lhs_reflection = lhs.GetReflection(); |
| 902 | const auto* rhs_reflection = rhs.GetReflection(); |
| 903 | if (MapSize(*lhs_reflection, lhs, *lhs_field) != |
| 904 | MapSize(*rhs_reflection, rhs, *rhs_field)) { |
| 905 | return false; |
| 906 | } |
| 907 | auto lhs_begin = ConstMapBegin(*lhs_reflection, lhs, *lhs_field); |
| 908 | const auto lhs_end = ConstMapEnd(*lhs_reflection, lhs, *lhs_field); |
| 909 | Unique<Message> lhs_unpacked; |
| 910 | EquatableValue lhs_value; |
| 911 | Unique<Message> rhs_unpacked; |
| 912 | EquatableValue rhs_value; |
| 913 | google::protobuf::MapKey rhs_map_key; |
| 914 | google::protobuf::MapValueConstRef rhs_map_value; |
| 915 | for (; lhs_begin != lhs_end; ++lhs_begin) { |
| 916 | if (!CoalesceMapKey(lhs_begin.GetKey(), rhs_entry_key_field->cpp_type(), |
| 917 | &rhs_map_key)) { |
| 918 | return false; |
| 919 | } |
| 920 | if (!LookupMapValue(*rhs_reflection, rhs, *rhs_field, rhs_map_key, |
| 921 | &rhs_map_value)) { |
| 922 | return false; |
| 923 | } |
| 924 | CEL_ASSIGN_OR_RETURN(lhs_value, |
| 925 | MapValueAsEquatableValue( |
| 926 | &arena_, pool_, factory_, lhs_reflection_, |
| 927 | lhs_begin.GetValueRef(), lhs_entry_value_field, |
| 928 | lhs_scratch_, lhs_unpacked)); |
| 929 | CEL_ASSIGN_OR_RETURN( |
| 930 | rhs_value, |
| 931 | MapValueAsEquatableValue(&arena_, pool_, factory_, rhs_reflection_, |
| 932 | rhs_map_value, rhs_entry_value_field, |
| 933 | rhs_scratch_, rhs_unpacked)); |
nothing calls this directly
no test coverage detected