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.md file.

package cmp

import 
valueNode represents a single node within a report, which is a structured representation of the value tree, containing information regarding which nodes are equal or not.
NumSame is the number of leaf nodes that are equal. All descendants are equal only if NumDiff is 0.
NumDiff is the number of leaf nodes that are not equal.
NumIgnored is the number of leaf nodes that are ignored.
NumCompared is the number of leaf nodes that were compared using an Equal method or Comparer function.
NumTransformed is the number of non-leaf nodes that were transformed.
NumChildren is the number of transitive descendants of this node. This counts from zero; thus, leaf nodes have no descendants.
MaxDepth is the maximum depth of the tree. This counts from zero; thus, leaf nodes have a depth of zero.
Records is a list of struct fields, slice elements, or map entries.
	Records []reportRecord // If populated, implies Value is not populated
Value is the result of a transformation, pointer indirect, of type assertion.
	Value *valueNode // If populated, implies Records is not populated
TransformerName is the name of the transformer.
	TransformerName string // If non-empty, implies Value is populated
}
type reportRecord struct {
	Key   reflect.Value // Invalid for slice element
	Value *valueNode
}

func ( *valueNode) ( PathStep) ( *valueNode) {
	,  := .Values()
	 = &valueNode{parent: , Type: .Type(), ValueX: , ValueY: }
	switch s := .(type) {
	case StructField:
		assert(.Value == nil)
		.Records = append(.Records, reportRecord{Key: reflect.ValueOf(.Name()), Value: })
	case SliceIndex:
		assert(.Value == nil)
		.Records = append(.Records, reportRecord{Value: })
	case MapIndex:
		assert(.Value == nil)
		.Records = append(.Records, reportRecord{Key: .Key(), Value: })
	case Indirect:
		assert(.Value == nil && .Records == nil)
		.Value = 
	case TypeAssertion:
		assert(.Value == nil && .Records == nil)
		.Value = 
	case Transform:
		assert(.Value == nil && .Records == nil)
		.Value = 
		.TransformerName = .Name()
		.NumTransformed++
	default:
		assert( == nil) // Must be the root step
	}
	return 
}

func ( *valueNode) ( Result) {
	assert(.MaxDepth == 0) // May only be called on leaf nodes

	if .ByIgnore() {
		.NumIgnored++
	} else {
		if .Equal() {
			.NumSame++
		} else {
			.NumDiff++
		}
	}
	assert(.NumSame+.NumDiff+.NumIgnored == 1)

	if .ByMethod() {
		.NumCompared++
	}
	if .ByFunc() {
		.NumCompared++
	}
	assert(.NumCompared <= 1)
}

func ( *valueNode) () ( *valueNode) {
	if .parent == nil {
		return nil
	}
	 = .parent
	.NumSame += .NumSame
	.NumDiff += .NumDiff
	.NumIgnored += .NumIgnored
	.NumCompared += .NumCompared
	.NumTransformed += .NumTransformed
	.NumChildren += .NumChildren + 1
	if .MaxDepth < .MaxDepth+1 {
		.MaxDepth = .MaxDepth + 1
	}
	return