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  }