func checkResourceTypes()

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
}