package cmp
import (
)
const (
pointerDelimPrefix = "⟪"
pointerDelimSuffix = "⟫"
)
func ( value.Pointer, bool) string {
:= .Uintptr()
if flags.Deterministic {
= 0xdeadf00f
}
if {
return pointerDelimPrefix + formatHex(uint64()) + pointerDelimSuffix
}
return formatHex(uint64())
}
type pointerReferences [][2]value.Pointer
func ( *pointerReferences) (, reflect.Value, diffMode, bool) ( [2]value.Pointer) {
if && .IsValid() {
= .Addr()
}
if && .IsValid() {
= .Addr()
}
switch {
case diffUnknown, diffIdentical:
= [2]value.Pointer{value.PointerOf(), value.PointerOf()}
case diffRemoved:
= [2]value.Pointer{value.PointerOf(), value.Pointer{}}
case diffInserted:
= [2]value.Pointer{value.Pointer{}, value.PointerOf()}
}
* = append(*, )
return
}
func ( *pointerReferences) ( reflect.Value) ( value.Pointer, bool) {
= value.PointerOf()
for , := range * {
if == [0] || == [1] {
return , true
}
}
* = append(*, [2]value.Pointer{, })
return , false
}
func ( *pointerReferences) () {
* = (*)[:len(*)-1]
}
type trunkReferences struct{ pp [2]value.Pointer }
type trunkReference struct{ p value.Pointer }
type leafReference struct{ p value.Pointer }
func ( [2]value.Pointer, textNode) textNode {
switch {
case [0].IsNil():
return &textWrap{Value: , Metadata: trunkReference{[1]}}
case [1].IsNil():
return &textWrap{Value: , Metadata: trunkReference{[0]}}
case [0] == [1]:
return &textWrap{Value: , Metadata: trunkReference{[0]}}
default:
return &textWrap{Value: , Metadata: trunkReferences{}}
}
}
func ( value.Pointer, bool, textNode) textNode {
var string
if {
= formatPointer(, true)
}
return &textWrap{Prefix: , Value: , Metadata: trunkReference{}}
}
func ( value.Pointer, bool) textNode {
:= &textWrap{Prefix: "(", Value: textEllipsis, Suffix: ")"}
var string
if {
= formatPointer(, true)
}
return &textWrap{Prefix: , Value: , Metadata: leafReference{}}
}
func ( textNode) {
var func(textNode, func(textNode))
= func( textNode, func(textNode)) {
()
switch s := .(type) {
case *textWrap:
(.Value, )
case textList:
for , := range {
(.Value, )
}
}
}
var , []*textWrap
(, func( textNode) {
if , := .(*textWrap); {
switch .Metadata.(type) {
case leafReference:
= append(, )
case trunkReference, trunkReferences:
= append(, )
}
}
})
if len() == 0 {
return
}
:= make(map[value.Pointer]bool)
for , := range {
[.Metadata.(leafReference).p] = true
}
:= make(map[value.Pointer]value.Pointer)
:= func( value.Pointer) {
if ![].IsNil() {
[[]] = value.Pointer{}
}
[] = value.Pointer{}
}
for , := range {
switch p := .Metadata.(type) {
case trunkReference:
(.p)
case trunkReferences:
, := [.pp[0]]
, := [.pp[1]]
switch {
case ! && !:
[.pp[0]] = .pp[1]
[.pp[1]] = .pp[0]
case && && == .pp[1] && == .pp[0]:
default:
(.pp[0])
(.pp[1])
}
}
}
var uint
:= make(map[value.Pointer]uint)
:= func() uint {
:=
++
return
}
for , := range {
switch p := .Metadata.(type) {
case trunkReference:
if := [.p]; {
, := [.p]
if ! {
= ()
[.p] =
}
.Prefix = updateReferencePrefix(.Prefix, formatReference())
}
case trunkReferences:
:= [.pp[0]]
:= [.pp[1]]
if || {
, := [.pp[0]]
, := [.pp[1]]
:= [.pp[0]] == .pp[1] && [.pp[1]] == .pp[0]
if {
var uint
assert( == )
if {
assert( == )
=
} else {
= ()
[.pp[0]] =
[.pp[1]] =
}
.Prefix = updateReferencePrefix(.Prefix, formatReference())
} else {
if && ! {
= ()
[.pp[0]] =
}
if && ! {
= ()
[.pp[1]] =
}
switch {
case && :
.Prefix = updateReferencePrefix(.Prefix, formatReference()+","+formatReference())
case :
.Prefix = updateReferencePrefix(.Prefix, formatReference())
case :
.Prefix = updateReferencePrefix(.Prefix, formatReference())
}
}
}
}
}
for , := range {
if , := [.Metadata.(leafReference).p]; {
.Prefix = updateReferencePrefix(.Prefix, formatReference())
}
}
}
func ( uint) string {
return fmt.Sprintf("ref#%d", )
}
func (, string) string {
if == "" {
return pointerDelimPrefix + + pointerDelimSuffix
}
:= strings.TrimPrefix(, pointerDelimPrefix)
return pointerDelimPrefix + + ": " +
}