cmp/report_compare.go
func (opts formatOptions) FormatDiff(v *valueNode) textNode {
	// Check whether we have specialized formatting for this node.
	// This is not necessary, but helpful for producing more readable outputs.
	if opts.CanFormatDiffSlice(v) {
		return opts.FormatDiffSlice(v)
	}

	// For leaf nodes, format the value based on the reflect.Values alone.
	if v.MaxDepth == 0 {
		switch opts.DiffMode {
		case diffUnknown, diffIdentical:
			// Format Equal.
			if v.NumDiff == 0 {
				outx := opts.FormatValue(v.ValueX, visitedPointers{})
				outy := opts.FormatValue(v.ValueY, visitedPointers{})
				if v.NumIgnored > 0 && v.NumSame == 0 {
					return textEllipsis
				} else if outx.Len() < outy.Len() {
					return outx
				} else {
					return outy
				}
			}

			// Format unequal.
			assert(opts.DiffMode == diffUnknown)
			var list textList
			outx := opts.WithTypeMode(elideType).FormatValue(v.ValueX, visitedPointers{})
			outy := opts.WithTypeMode(elideType).FormatValue(v.ValueY, visitedPointers{})
			if outx != nil {
				list = append(list, textRecord{Diff: '-', Value: outx})
			}
			if outy != nil {
				list = append(list, textRecord{Diff: '+', Value: outy})
			}
			return opts.WithTypeMode(emitType).FormatType(v.Type, list)
		case diffRemoved:
			return opts.FormatValue(v.ValueX, visitedPointers{})
		case diffInserted:
			return opts.FormatValue(v.ValueY, visitedPointers{})
		default:
			panic("invalid diff mode")
		}
	}

	// Descend into the child value node.
	if v.TransformerName != "" {
		out := opts.WithTypeMode(emitType).FormatDiff(v.Value)
		out = textWrap{"Inverse(" + v.TransformerName + ", ", out, ")"}
		return opts.FormatType(v.Type, out)
	} else {
		switch k := v.Type.Kind(); k {
		case reflect.Struct, reflect.Array, reflect.Slice, reflect.Map:
			return opts.FormatType(v.Type, opts.formatDiffList(v.Records, k))
		case reflect.Ptr:
			return textWrap{"&", opts.FormatDiff(v.Value), ""}
		case reflect.Interface:
			return opts.WithTypeMode(emitType).FormatDiff(v.Value)
		default:
			panic(fmt.Sprintf("%v cannot have children", k))
		}
	}
}
func (opts formatOptions) FormatDiff(v *valueNode) textNode {
	// Check whether we have specialized formatting for this node.
	// This is not necessary, but helpful for producing more readable outputs.
	if opts.CanFormatDiffSlice(v) {
		return opts.FormatDiffSlice(v)
	}

	// For leaf nodes, format the value based on the reflect.Values alone.
	if v.MaxDepth == 0 {
		switch opts.DiffMode {
		case diffUnknown, diffIdentical:
			// Format Equal.
			if v.NumDiff == 0 {
				outx := opts.FormatValue(v.ValueX, visitedPointers{})
				outy := opts.FormatValue(v.ValueY, visitedPointers{})
				if v.NumIgnored > 0 && v.NumSame == 0 {
					return textEllipsis
				} else if outx.Len() < outy.Len() {
					return outx
				} else {
					return outy
				}
			}

			// Format unequal.
			assert(opts.DiffMode == diffUnknown)
			var list textList
			outx := opts.WithTypeMode(elideType).FormatValue(v.ValueX, visitedPointers{})
			outy := opts.WithTypeMode(elideType).FormatValue(v.ValueY, visitedPointers{})
			if outx != nil {
				list = append(list, textRecord{Diff: '-', Value: outx})
			}
			if outy != nil {
				list = append(list, textRecord{Diff: '+', Value: outy})
			}
			return opts.WithTypeMode(emitType).FormatType(v.Type, list)
		case diffRemoved:
			return opts.FormatValue(v.ValueX, visitedPointers{})
		case diffInserted:
			return opts.FormatValue(v.ValueY, visitedPointers{})
		default:
			panic("invalid diff mode")
		}
	}

	// Descend into the child value node.
	if v.TransformerName != "" {
		out := opts.WithTypeMode(emitType).FormatDiff(v.Value)
		out = textWrap{"Inverse(" + v.TransformerName + ", ", out, ")"}
		return opts.FormatType(v.Type, out)
	} else {
		switch k := v.Type.Kind(); k {
		case reflect.Struct, reflect.Array, reflect.Slice, reflect.Map:
			return opts.FormatType(v.Type, opts.formatDiffList(v.Records, k))
		case reflect.Ptr:
			return textWrap{"&", opts.FormatDiff(v.Value), ""}
		case reflect.Interface:
			return opts.WithTypeMode(emitType).FormatDiff(v.Value)
		default:
			panic(fmt.Sprintf("%v cannot have children", k))
		}
	}
}
// FormatDiff converts a valueNode tree into a textNode tree, where the later
// is a textual representation of the differences detected in the former.