in pkg/cloud/api/check.go [105:150]
func checkResourceTypes(p Path, t reflect.Type) error {
// valid_type => basic | ...
if isBasicT(t) {
return nil
}
switch t.Kind() {
case reflect.Pointer:
if err := checkResourceTypes(p, t.Elem()); err != nil {
return err
}
case reflect.Struct:
// struct => {all fields are valid_type}
for i := 0; i < t.NumField(); i++ {
tf := t.Field(i)
if err := checkResourceTypes(p.Field(tf.Name), tf.Type); err != nil {
return err
}
}
case reflect.Slice:
// slice => {elements => valid_type}
if err := checkResourceTypes(p.Index(0), t.Elem()); err != nil {
return err
}
case reflect.Map:
// map => key is basic type; value is valid_type
if !isBasicT(t.Key()) {
return fmt.Errorf("map key must be basic type %s: %v", p.Pointer(), t)
}
// Supported value types.
if !isBasicT(t.Elem()) {
switch t.Elem().Kind() {
case reflect.Slice, reflect.Struct:
default:
return fmt.Errorf("unsupported value type %s: %v", p, t)
}
// Use "x" as the placeholder for the map key in the Path for debugging
// output purposes.
if err := checkResourceTypes(p.MapIndex("x"), t.Elem()); err != nil {
return err
}
}
default:
return fmt.Errorf("unsupported type %s: %v", p, t)
}
return nil
}