Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

package proto

import (
	
	
	

	
	pref 
)
Equal reports whether two messages are equal. If two messages marshal to the same bytes under deterministic serialization, then Equal is guaranteed to report true. Two messages are equal if they belong to the same message descriptor, have the same set of populated known and extension field values, and the same set of unknown fields values. If either of the top-level messages are invalid, then Equal reports true only if both are invalid. Scalar values are compared with the equivalent of the == operator in Go, except bytes values which are compared using bytes.Equal and floating point values which specially treat NaNs as equal. Message values are compared by recursively calling Equal. Lists are equal if each element value is also equal. Maps are equal if they have the same set of keys, where the pair of values for each key is also equal.
func (,  Message) bool {
	if  == nil ||  == nil {
		return  == nil &&  == nil
	}
	 := .ProtoReflect()
	 := .ProtoReflect()
	if .IsValid() != .IsValid() {
		return false
	}
	return equalMessage(, )
}
equalMessage compares two messages.
func (,  pref.Message) bool {
	if .Descriptor() != .Descriptor() {
		return false
	}

	 := 0
	 := true
	.Range(func( pref.FieldDescriptor,  pref.Value) bool {
		++
		 := .Get()
		 = .Has() && equalField(, , )
		return 
	})
	if ! {
		return false
	}
	 := 0
	.Range(func( pref.FieldDescriptor,  pref.Value) bool {
		++
		return true
	})
	if  !=  {
		return false
	}

	return equalUnknown(.GetUnknown(), .GetUnknown())
}
equalField compares two fields.
func ( pref.FieldDescriptor, ,  pref.Value) bool {
	switch {
	case .IsList():
		return equalList(, .List(), .List())
	case .IsMap():
		return equalMap(, .Map(), .Map())
	default:
		return equalValue(, , )
	}
}
equalMap compares two maps.
func ( pref.FieldDescriptor, ,  pref.Map) bool {
	if .Len() != .Len() {
		return false
	}
	 := true
	.Range(func( pref.MapKey,  pref.Value) bool {
		 := .Get()
		 = .Has() && equalValue(.MapValue(), , )
		return 
	})
	return 
}
equalList compares two lists.
func ( pref.FieldDescriptor, ,  pref.List) bool {
	if .Len() != .Len() {
		return false
	}
	for  := .Len() - 1;  >= 0; -- {
		if !equalValue(, .Get(), .Get()) {
			return false
		}
	}
	return true
}
equalValue compares two singular values.
func ( pref.FieldDescriptor, ,  pref.Value) bool {
	switch {
	case .Message() != nil:
		return equalMessage(.Message(), .Message())
	case .Kind() == pref.BytesKind:
		return bytes.Equal(.Bytes(), .Bytes())
	case .Kind() == pref.FloatKind, .Kind() == pref.DoubleKind:
		 := .Float()
		 := .Float()
		if math.IsNaN() || math.IsNaN() {
			return math.IsNaN() && math.IsNaN()
		}
		return  == 
	default:
		return .Interface() == .Interface()
	}
}
equalUnknown compares unknown fields by direct comparison on the raw bytes of each individual field number.
func (,  pref.RawFields) bool {
	if len() != len() {
		return false
	}
	if bytes.Equal([]byte(), []byte()) {
		return true
	}

	 := make(map[pref.FieldNumber]pref.RawFields)
	 := make(map[pref.FieldNumber]pref.RawFields)
	for len() > 0 {
		, ,  := protowire.ConsumeField()
		[] = append([], [:]...)
		 = [:]
	}
	for len() > 0 {
		, ,  := protowire.ConsumeField()
		[] = append([], [:]...)
		 = [:]
	}
	return reflect.DeepEqual(, )