// filterField returns a new Option where opt is only evaluated on paths that // include a specific exported field on a single struct type. // 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 select a // specific sub-field that is embedded or nested within the parent struct. func filterField(typ interface{ … } type structFilter … func newStructFilter(typ interface{ … } func (sf structFilter) filter(p cmp.Path) bool { … } type fieldTree … // insert inserts a sequence of field accesses into the tree. func (ft *fieldTree) insert(cname []string) { … } // matchPrefix reports whether any selector in the fieldTree matches // the start of path p. func (ft fieldTree) matchPrefix(p cmp.Path) bool { … } // canonicalName returns a list of identifiers where any struct field access // through an embedded field is expanded to include the names of the embedded // types themselves. // // For example, suppose field "Foo" is not directly in the parent struct, // but actually from an embedded struct of type "Bar". Then, the canonical name // of "Foo" is actually "Bar.Foo". // // Suppose field "Foo" is not directly in the parent struct, but actually // a field in two different embedded structs of types "Bar" and "Baz". // Then the selector "Foo" causes a panic since it is ambiguous which one it // refers to. The user must specify either "Bar.Foo" or "Baz.Foo". func canonicalName(t reflect.Type, sel string) ([]string, error) { … }