1*1c12ee1eSDan Willemsen// Copyright 2019 The Go Authors. All rights reserved. 2*1c12ee1eSDan Willemsen// Use of this source code is governed by a BSD-style 3*1c12ee1eSDan Willemsen// license that can be found in the LICENSE file. 4*1c12ee1eSDan Willemsen 5*1c12ee1eSDan Willemsenpackage proto 6*1c12ee1eSDan Willemsen 7*1c12ee1eSDan Willemsenimport ( 8*1c12ee1eSDan Willemsen "reflect" 9*1c12ee1eSDan Willemsen 10*1c12ee1eSDan Willemsen "google.golang.org/protobuf/reflect/protoreflect" 11*1c12ee1eSDan Willemsen) 12*1c12ee1eSDan Willemsen 13*1c12ee1eSDan Willemsen// Equal reports whether two messages are equal, 14*1c12ee1eSDan Willemsen// by recursively comparing the fields of the message. 15*1c12ee1eSDan Willemsen// 16*1c12ee1eSDan Willemsen// - Bytes fields are equal if they contain identical bytes. 17*1c12ee1eSDan Willemsen// Empty bytes (regardless of nil-ness) are considered equal. 18*1c12ee1eSDan Willemsen// 19*1c12ee1eSDan Willemsen// - Floating-point fields are equal if they contain the same value. 20*1c12ee1eSDan Willemsen// Unlike the == operator, a NaN is equal to another NaN. 21*1c12ee1eSDan Willemsen// 22*1c12ee1eSDan Willemsen// - Other scalar fields are equal if they contain the same value. 23*1c12ee1eSDan Willemsen// 24*1c12ee1eSDan Willemsen// - Message fields are equal if they have 25*1c12ee1eSDan Willemsen// the same set of populated known and extension field values, and 26*1c12ee1eSDan Willemsen// the same set of unknown fields values. 27*1c12ee1eSDan Willemsen// 28*1c12ee1eSDan Willemsen// - Lists are equal if they are the same length and 29*1c12ee1eSDan Willemsen// each corresponding element is equal. 30*1c12ee1eSDan Willemsen// 31*1c12ee1eSDan Willemsen// - Maps are equal if they have the same set of keys and 32*1c12ee1eSDan Willemsen// the corresponding value for each key is equal. 33*1c12ee1eSDan Willemsen// 34*1c12ee1eSDan Willemsen// An invalid message is not equal to a valid message. 35*1c12ee1eSDan Willemsen// An invalid message is only equal to another invalid message of the 36*1c12ee1eSDan Willemsen// same type. An invalid message often corresponds to a nil pointer 37*1c12ee1eSDan Willemsen// of the concrete message type. For example, (*pb.M)(nil) is not equal 38*1c12ee1eSDan Willemsen// to &pb.M{}. 39*1c12ee1eSDan Willemsen// If two valid messages marshal to the same bytes under deterministic 40*1c12ee1eSDan Willemsen// serialization, then Equal is guaranteed to report true. 41*1c12ee1eSDan Willemsenfunc Equal(x, y Message) bool { 42*1c12ee1eSDan Willemsen if x == nil || y == nil { 43*1c12ee1eSDan Willemsen return x == nil && y == nil 44*1c12ee1eSDan Willemsen } 45*1c12ee1eSDan Willemsen if reflect.TypeOf(x).Kind() == reflect.Ptr && x == y { 46*1c12ee1eSDan Willemsen // Avoid an expensive comparison if both inputs are identical pointers. 47*1c12ee1eSDan Willemsen return true 48*1c12ee1eSDan Willemsen } 49*1c12ee1eSDan Willemsen mx := x.ProtoReflect() 50*1c12ee1eSDan Willemsen my := y.ProtoReflect() 51*1c12ee1eSDan Willemsen if mx.IsValid() != my.IsValid() { 52*1c12ee1eSDan Willemsen return false 53*1c12ee1eSDan Willemsen } 54*1c12ee1eSDan Willemsen vx := protoreflect.ValueOfMessage(mx) 55*1c12ee1eSDan Willemsen vy := protoreflect.ValueOfMessage(my) 56*1c12ee1eSDan Willemsen return vx.Equal(vy) 57*1c12ee1eSDan Willemsen} 58