github.com/cockroachdb/cockroachdb-parser@v0.23.3-0.20240213214944-911057d40c9a/pkg/util/reflect.go (about) 1 // Copyright 2016 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package util 12 13 import "reflect" 14 15 // EqualPtrFields uses reflection to check two "mirror" structures for matching pointer fields that 16 // point to the same object. Used to verify cloning/deep copy functions. 17 // 18 // Returns the names of equal pointer fields. 19 func EqualPtrFields(src, dst reflect.Value, prefix string) []string { 20 t := dst.Type() 21 if t.Kind() != reflect.Struct { 22 return nil 23 } 24 if srcType := src.Type(); srcType != t { 25 return nil 26 } 27 var res []string 28 for i := 0; i < t.NumField(); i++ { 29 srcF, dstF := src.Field(i), dst.Field(i) 30 switch f := t.Field(i); f.Type.Kind() { 31 case reflect.Ptr: 32 if srcF.Interface() == dstF.Interface() { 33 res = append(res, prefix+f.Name) 34 } 35 case reflect.Slice: 36 if srcF.Pointer() == dstF.Pointer() { 37 res = append(res, prefix+f.Name) 38 } 39 l := dstF.Len() 40 if srcLen := srcF.Len(); srcLen < l { 41 l = srcLen 42 } 43 for i := 0; i < l; i++ { 44 res = append(res, EqualPtrFields(srcF.Index(i), dstF.Index(i), f.Name+".")...) 45 } 46 case reflect.Struct: 47 res = append(res, EqualPtrFields(srcF, dstF, f.Name+".")...) 48 } 49 } 50 return res 51 }