func (d *decoder) decodeInterface(name string, o *hcl.Object, result reflect.Value) error { var set reflect.Value redecode := true switch o.Type { case hcl.ValueTypeObject: // If we're at the root or we're directly within a slice, then we // decode objects into map[string]interface{}, otherwise we decode // them into lists. if len(d.stack) == 0 || d.stack[len(d.stack)-1] == reflect.Slice { var temp map[string]interface{} tempVal := reflect.ValueOf(temp) result := reflect.MakeMap( reflect.MapOf( reflect.TypeOf(""), tempVal.Type().Elem())) set = result } else { var temp []map[string]interface{} tempVal := reflect.ValueOf(temp) result := reflect.MakeSlice( reflect.SliceOf(tempVal.Type().Elem()), 0, int(o.Len())) set = result } case hcl.ValueTypeList: var temp []interface{} tempVal := reflect.ValueOf(temp) result := reflect.MakeSlice( reflect.SliceOf(tempVal.Type().Elem()), 0, 0) set = result case hcl.ValueTypeBool: var result bool set = reflect.Indirect(reflect.New(reflect.TypeOf(result))) case hcl.ValueTypeFloat: var result float64 set = reflect.Indirect(reflect.New(reflect.TypeOf(result))) case hcl.ValueTypeInt: var result int set = reflect.Indirect(reflect.New(reflect.TypeOf(result))) case hcl.ValueTypeString: set = reflect.Indirect(reflect.New(reflect.TypeOf(""))) default: return fmt.Errorf( "%s: cannot decode into interface: %T", name, o) } // Set the result to what its supposed to be, then reset // result so we don't reflect into this method anymore. result.Set(set) if redecode { // Revisit the node so that we can use the newly instantiated // thing and populate it. if err := d.decode(name, o, result); err != nil { return err } } return nil }