Copyright 2017, 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.md file.

package cmpopts

import (
	
	
	
	

	
	
)
IgnoreFields returns an Option that ignores fields of the given names on a single struct type. It respects the names of exported fields that are forwarded due to struct embedding. The struct type is specified by passing in a value of that type. The name may be a dot-delimited string (e.g., "Foo.Bar") to ignore a specific sub-field that is embedded or nested within the parent struct.
func ( interface{},  ...string) cmp.Option {
	 := newStructFilter(, ...)
	return cmp.FilterPath(.filter, cmp.Ignore())
}
IgnoreTypes returns an Option that ignores all values assignable to certain types, which are specified by passing in a value of each type.
func ( ...interface{}) cmp.Option {
	 := newTypeFilter(...)
	return cmp.FilterPath(.filter, cmp.Ignore())
}

type typeFilter []reflect.Type

func ( ...interface{}) ( typeFilter) {
	for ,  := range  {
		 := reflect.TypeOf()
This occurs if someone tries to pass in sync.Locker(nil)
			panic("cannot determine type; consider using IgnoreInterfaces")
		}
		 = append(, )
	}
	return 
}
func ( typeFilter) ( cmp.Path) bool {
	if len() < 1 {
		return false
	}
	 := .Last().Type()
	for ,  := range  {
		if .AssignableTo() {
			return true
		}
	}
	return false
}
IgnoreInterfaces returns an Option that ignores all values or references of values assignable to certain interface types. These interfaces are specified by passing in an anonymous struct with the interface types embedded in it. For example, to ignore sync.Locker, pass in struct{sync.Locker}{}.
func ( interface{}) cmp.Option {
	 := newIfaceFilter()
	return cmp.FilterPath(.filter, cmp.Ignore())
}

type ifaceFilter []reflect.Type

func ( interface{}) ( ifaceFilter) {
	 := reflect.TypeOf()
	if  == nil || .Name() != "" || .Kind() != reflect.Struct {
		panic("input must be an anonymous struct")
	}
	for  := 0;  < .NumField(); ++ {
		 := .Field()
		switch {
		case !.Anonymous:
			panic("struct cannot have named fields")
		case .Type.Kind() != reflect.Interface:
			panic("embedded field must be an interface type")
This matches everything; why would you ever want this?
			panic("cannot ignore empty interface")
		default:
			 = append(, .Type)
		}
	}
	return 
}
func ( ifaceFilter) ( cmp.Path) bool {
	if len() < 1 {
		return false
	}
	 := .Last().Type()
	for ,  := range  {
		if .AssignableTo() {
			return true
		}
		if .Kind() != reflect.Ptr && reflect.PtrTo().AssignableTo() {
			return true
		}
	}
	return false
}
IgnoreUnexported returns an Option that only ignores the immediate unexported fields of a struct, including anonymous fields of unexported types. In particular, unexported fields within the struct's exported fields of struct types, including anonymous fields, will not be ignored unless the type of the field itself is also passed to IgnoreUnexported. Avoid ignoring unexported fields of a type which you do not control (i.e. a type from another repository), as changes to the implementation of such types may change how the comparison behaves. Prefer a custom Comparer instead.
func ( ...interface{}) cmp.Option {
	 := newUnexportedFilter(...)
	return cmp.FilterPath(.filter, cmp.Ignore())
}

type unexportedFilter struct{ m map[reflect.Type]bool }

func ( ...interface{}) unexportedFilter {
	 := unexportedFilter{m: make(map[reflect.Type]bool)}
	for ,  := range  {
		 := reflect.TypeOf()
		if  == nil || .Kind() != reflect.Struct {
			panic(fmt.Sprintf("%T must be a non-pointer struct", ))
		}
		.m[] = true
	}
	return 
}
func ( unexportedFilter) ( cmp.Path) bool {
	,  := .Index(-1).(cmp.StructField)
	if ! {
		return false
	}
	return .m[.Index(-2).Type()] && !isExported(.Name())
}
isExported reports whether the identifier is exported.
func ( string) bool {
	,  := utf8.DecodeRuneInString()
	return unicode.IsUpper()
}
IgnoreSliceElements returns an Option that ignores elements of []V. The discard function must be of the form "func(T) bool" which is used to ignore slice elements of type V, where V is assignable to T. Elements are ignored if the function reports true.
func ( interface{}) cmp.Option {
	 := reflect.ValueOf()
	if !function.IsType(.Type(), function.ValuePredicate) || .IsNil() {
		panic(fmt.Sprintf("invalid discard function: %T", ))
	}
	return cmp.FilterPath(func( cmp.Path) bool {
		,  := .Index(-1).(cmp.SliceIndex)
		if ! {
			return false
		}
		if !.Type().AssignableTo(.Type().In(0)) {
			return false
		}
		,  := .Values()
		if .IsValid() && .Call([]reflect.Value{})[0].Bool() {
			return true
		}
		if .IsValid() && .Call([]reflect.Value{})[0].Bool() {
			return true
		}
		return false
	}, cmp.Ignore())
}
IgnoreMapEntries returns an Option that ignores entries of map[K]V. The discard function must be of the form "func(T, R) bool" which is used to ignore map entries of type K and V, where K and V are assignable to T and R. Entries are ignored if the function reports true.
func ( interface{}) cmp.Option {
	 := reflect.ValueOf()
	if !function.IsType(.Type(), function.KeyValuePredicate) || .IsNil() {
		panic(fmt.Sprintf("invalid discard function: %T", ))
	}
	return cmp.FilterPath(func( cmp.Path) bool {
		,  := .Index(-1).(cmp.MapIndex)
		if ! {
			return false
		}
		if !.Key().Type().AssignableTo(.Type().In(0)) || !.Type().AssignableTo(.Type().In(1)) {
			return false
		}
		 := .Key()
		,  := .Values()
		if .IsValid() && .Call([]reflect.Value{, })[0].Bool() {
			return true
		}
		if .IsValid() && .Call([]reflect.Value{, })[0].Bool() {
			return true
		}
		return false
	}, cmp.Ignore())