in pkg/cloud/api/visit.go [86:153]
func visitImpl(p Path, v reflect.Value, a acceptor) error {
switch {
case isBasicV(v):
if _, err := a.onBasic(p, v); err != nil {
return err
}
case v.Type().Kind() == reflect.Pointer:
descend, err := a.onPointer(p, v)
if err != nil {
return err
}
if !v.IsZero() && descend {
err := visitImpl(p.Pointer(), v.Elem(), a)
if err != nil {
return err
}
}
case v.Type().Kind() == reflect.Struct:
descend, err := a.onStruct(p, v)
if err != nil {
return err
}
if descend {
for i := 0; i < v.NumField(); i++ {
fv := v.Field(i)
ft := v.Type().Field(i)
if err := visitImpl(p.Field(ft.Name), fv, a); err != nil {
return err
}
}
}
case v.Type().Kind() == reflect.Slice:
descend, err := a.onSlice(p, v)
if err != nil {
return err
}
if descend {
for i := 0; i < v.Len(); i++ {
sv := v.Index(i)
if err := visitImpl(p.Index(i), sv, a); err != nil {
return err
}
}
}
case v.Type().Kind() == reflect.Map:
descend, err := a.onMap(p, v)
if err != nil {
return err
}
if descend {
for _, mk := range v.MapKeys() {
mv := v.MapIndex(mk)
// Create a temporary setable map
// value for cases where visitImpl
// wants to mutate the value in the
// map. This slightly inefficient for
// read-only operations.
setableMV := reflect.New(mv.Type()).Elem()
setableMV.Set(mv)
if err := visitImpl(p.MapIndex(mk), setableMV, a); err != nil {
return err
}
v.SetMapIndex(mk, setableMV)
}
}
}
return nil
}