// Contains checks whether the underlying value (which must be of type struct, map, // string, array or slice) contains of another Value (e. g. used to check // whether a struct contains of a specific field or a map contains a specific key). // // Example: // AsValue("Hello, World!").Contains(AsValue("World")) == true func (v *Value) Contains(other *Value) bool { switch v.getResolvedValue().Kind() { case reflect.Struct: fieldValue := v.getResolvedValue().FieldByName(other.String()) return fieldValue.IsValid() case reflect.Map: var mapValue reflect.Value switch other.Interface().(type) { case int: mapValue = v.getResolvedValue().MapIndex(other.getResolvedValue()) case string: mapValue = v.getResolvedValue().MapIndex(other.getResolvedValue()) default: logf("Value.Contains() does not support lookup type '%s'\n", other.getResolvedValue().Kind().String()) return false } return mapValue.IsValid() case reflect.String: return strings.Contains(v.getResolvedValue().String(), other.String()) case reflect.Slice, reflect.Array: for i := 0; i < v.getResolvedValue().Len(); i++ { item := v.getResolvedValue().Index(i) if other.Interface() == item.Interface() { return true } } return false default: logf("Value.Contains() not available for type: %s\n", v.getResolvedValue().Kind().String()) return false } }
func (q *Query) findPopulatePath(path string) { parts := strings.Split(path, ".") resultVal := reflect.ValueOf(q.parentStruct).Elem() var refVal reflect.Value partsLen := len(parts) for i := 0; i < partsLen; i++ { elem := parts[i] if i == 0 { refVal = resultVal.FieldByName(elem) structTag, _ := resultVal.Type().FieldByName(elem) q.popSchema = structTag.Tag.Get(q.z.modelTag) } else if i == partsLen-1 { structTag, _ := refVal.Type().FieldByName(elem) q.popSchema = structTag.Tag.Get(q.z.modelTag) refVal = refVal.FieldByName(elem) } else { //refVal = handleSlice(refVal, elem, path) refVal = refVal.FieldByName(elem) } if !refVal.IsValid() { panic("field `" + elem + "` not found in populate path `" + path + "`") } } if refVal.Kind() == reflect.Slice { q.isSlice = true } q.populateField = refVal.Interface() }
// printValue is like printArg but starts with a reflect value, not an interface{} value. func (p *pp) printValue(value reflect.Value, verb rune, plus, goSyntax bool, depth int) (wasString bool) { if !value.IsValid() { if verb == 'T' || verb == 'v' { p.buf.Write(nilAngleBytes) } else { p.badVerb(verb) } return false } // Special processing considerations. // %T (the value's type) and %p (its address) are special; we always do them first. switch verb { case 'T': p.printArg(value.Type().String(), 's', false, false, 0) return false case 'p': p.fmtPointer(value, verb, goSyntax) return false } // Handle values with special methods. // Call always, even when arg == nil, because handleMethods clears p.fmt.plus for us. p.arg = nil // Make sure it's cleared, for safety. if value.CanInterface() { p.arg = value.Interface() } if isString, handled := p.handleMethods(verb, plus, goSyntax, depth); handled { return isString } return p.printReflectValue(value, verb, plus, goSyntax, depth) }
// bypassCanInterface returns a version of v that // bypasses the CanInterface check. func bypassCanInterface(v reflect.Value) reflect.Value { if !v.IsValid() || v.CanInterface() { return v } *flagField(&v) &^= flagRO return v }
// apply replaces each AST field x in val with f(x), returning val. // To avoid extra conversions, f operates on the reflect.Value form. func apply(f func(reflect.Value) reflect.Value, val reflect.Value) reflect.Value { if !val.IsValid() { return reflect.Value{} } // *ast.Objects introduce cycles and are likely incorrect after // rewrite; don't follow them but replace with nil instead if val.Type() == objectPtrType { return objectPtrNil } // similarly for scopes: they are likely incorrect after a rewrite; // replace them with nil if val.Type() == scopePtrType { return scopePtrNil } switch v := reflect.Indirect(val); v.Kind() { case reflect.Slice: for i := 0; i < v.Len(); i++ { e := v.Index(i) setValue(e, f(e)) } case reflect.Struct: for i := 0; i < v.NumField(); i++ { e := v.Field(i) setValue(e, f(e)) } case reflect.Interface: e := v.Elem() setValue(v, f(e)) } return val }
func (d *decoder) sequence(n *node, out reflect.Value) (good bool) { l := len(n.children) var iface reflect.Value switch out.Kind() { case reflect.Slice: out.Set(reflect.MakeSlice(out.Type(), l, l)) case reflect.Interface: // No type hints. Will have to use a generic sequence. iface = out out = settableValueOf(make([]interface{}, l)) default: d.terror(n, yaml_SEQ_TAG, out) return false } et := out.Type().Elem() j := 0 for i := 0; i < l; i++ { e := reflect.New(et).Elem() if ok := d.unmarshal(n.children[i], e); ok { out.Index(j).Set(e) j++ } } out.Set(out.Slice(0, j)) if iface.IsValid() { iface.Set(out) } return true }
// decodeValue decodes the data stream representing a value and stores it in val. func (dec *Decoder) decodeValue(wireId typeId, val reflect.Value) { defer catchError(&dec.err) // If the value is nil, it means we should just ignore this item. if !val.IsValid() { dec.decodeIgnoredValue(wireId) return } // Dereference down to the underlying type. ut := userType(val.Type()) base := ut.base var enginePtr **decEngine enginePtr, dec.err = dec.getDecEnginePtr(wireId, ut) if dec.err != nil { return } engine := *enginePtr if st := base; st.Kind() == reflect.Struct && ut.externalDec == 0 { if engine.numInstr == 0 && st.NumField() > 0 && len(dec.wireType[wireId].StructT.Field) > 0 { name := base.Name() errorf("type mismatch: no fields matched compiling decoder for %s", name) } dec.decodeStruct(engine, ut, unsafeAddr(val), ut.indir) } else { dec.decodeSingle(engine, ut, unsafeAddr(val)) } }
func (d *Decoder) decodeNull(v reflect.Value) error { if v.IsValid() && v.CanSet() { v.Set(reflect.Zero(v.Type())) } return nil }
func hydrateValue(v reflect.Value, component *token) error { if !v.IsValid() || v.Kind() != reflect.Ptr { return utils.NewError(hydrateValue, "unmarshal target must be a valid pointer", v, nil) } // handle any encodable properties if encoder, isprop := v.Interface().(properties.CanEncodeName); isprop { if name, err := encoder.EncodeICalName(); err != nil { return utils.NewError(hydrateValue, "unable to lookup property name", v, err) } else if properties, found := component.properties[name]; !found || len(properties) == 0 { return utils.NewError(hydrateValue, "no matching propery values found for "+string(name), v, nil) } else if len(properties) > 1 { return utils.NewError(hydrateValue, "more than one property value matches single property interface", v, nil) } else { return hydrateProperty(v, properties[0]) } } // handle components vkind := dereferencePointerValue(v).Kind() if tag, err := extractTagFromValue(v); err != nil { return utils.NewError(hydrateValue, "unable to extract component tag", v, err) } else if components, found := component.components[tag]; !found || len(components) == 0 { msg := fmt.Sprintf("unable to find matching component for %s", tag) return utils.NewError(hydrateValue, msg, v, nil) } else if vkind == reflect.Array || vkind == reflect.Slice { return hydrateComponents(v, components) } else if len(components) > 1 { return utils.NewError(hydrateValue, "non-array interface provided but more than one component found!", v, nil) } else { return hydrateComponent(v, components[0]) } }
func valiadateCopyField(f reflect.StructField, sfv, dfv reflect.Value) error { // check dst field is exists, if not valid move on if !dfv.IsValid() { return fmt.Errorf("Field: '%v', does not exists in dst", f.Name) } // check kind of src and dst, if doesn't match move on if (sfv.Kind() != dfv.Kind()) && !isInterface(dfv) { return fmt.Errorf("Field: '%v', src [%v] & dst [%v] kind didn't match", f.Name, sfv.Kind(), dfv.Kind(), ) } // check type of src and dst, if doesn't match move on sfvt := deepTypeOf(sfv) dfvt := deepTypeOf(dfv) if (sfvt != dfvt) && !isInterface(dfv) { return fmt.Errorf("Field: '%v', src [%v] & dst [%v] type didn't match", f.Name, sfvt, dfvt, ) } return nil }
func (d *Decoder) parse(rv reflect.Value) { if !rv.IsValid() { // skip ahead since we cannot store d.valueInterface() return } anchor := string(d.event.anchor) switch d.event.event_type { case yaml_SEQUENCE_START_EVENT: d.begin_anchor(anchor) d.sequence(rv) d.end_anchor(anchor) case yaml_MAPPING_START_EVENT: d.begin_anchor(anchor) d.mapping(rv) d.end_anchor(anchor) case yaml_SCALAR_EVENT: d.begin_anchor(anchor) d.scalar(rv) d.end_anchor(anchor) case yaml_ALIAS_EVENT: d.alias(rv) case yaml_DOCUMENT_END_EVENT: default: d.error(&UnexpectedEventError{ Value: string(d.event.value), EventType: d.event.event_type, At: d.event.start_mark, }) } }
func (d *decoder) sequence(n *node, out reflect.Value) (good bool) { if set := d.setter("!!seq", &out, &good); set != nil { defer set() } var iface reflect.Value if out.Kind() == reflect.Interface { // No type hints. Will have to use a generic sequence. iface = out out = settableValueOf(make([]interface{}, 0)) } if out.Kind() != reflect.Slice { return false } et := out.Type().Elem() l := len(n.children) for i := 0; i < l; i++ { e := reflect.New(et).Elem() if ok := d.unmarshal(n.children[i], e); ok { out.Set(reflect.Append(out, e)) } } if iface.IsValid() { iface.Set(out) } return true }
// tomlArrayType returns the element type of a TOML array. The type returned // may be nil if it cannot be determined (e.g., a nil slice or a zero length // slize). This function may also panic if it finds a type that cannot be // expressed in TOML (such as nil elements, heterogeneous arrays or directly // nested arrays of tables). func tomlArrayType(rv reflect.Value) tomlType { if isNil(rv) || !rv.IsValid() || rv.Len() == 0 { return nil } firstType := tomlTypeOfGo(rv.Index(0)) if firstType == nil { encPanic(errArrayNilElement) } rvlen := rv.Len() for i := 1; i < rvlen; i++ { elem := rv.Index(i) switch elemType := tomlTypeOfGo(elem); { case elemType == nil: encPanic(errArrayNilElement) case !typeEqual(firstType, elemType): encPanic(errArrayMixedElementTypes) } } // If we have a nested array, then we must make sure that the nested // array contains ONLY primitives. // This checks arbitrarily nested arrays. if typeEqual(firstType, tomlArray) || typeEqual(firstType, tomlArrayHash) { nest := tomlArrayType(eindirect(rv.Index(0))) if typeEqual(nest, tomlHash) || typeEqual(nest, tomlArrayHash) { encPanic(errArrayNoTable) } } return firstType }
// evalCall executes a function or method call. If it's a method, fun already has the receiver bound, so // it looks just like a function call. The arg list, if non-nil, includes (in the manner of the shell), arg[0] // as the function itself. func (s *state) evalCall(dot, fun reflect.Value, node parse.Node, name string, args []parse.Node, final reflect.Value) reflect.Value { if args != nil { args = args[1:] // Zeroth arg is function name/node; not passed to function. } typ := fun.Type() numIn := len(args) if final.IsValid() { numIn++ } numFixed := len(args) if typ.IsVariadic() { numFixed = typ.NumIn() - 1 // last arg is the variadic one. if numIn < numFixed { s.errorf("wrong number of args for %s: want at least %d got %d", name, typ.NumIn()-1, len(args)) } } else if numIn < typ.NumIn()-1 || !typ.IsVariadic() && numIn != typ.NumIn() { s.errorf("wrong number of args for %s: want %d got %d", name, typ.NumIn(), len(args)) } if !goodFunc(typ) { // TODO: This could still be a confusing error; maybe goodFunc should provide info. s.errorf("can't call method/function %q with %d results", name, typ.NumOut()) } // Build the arg list. argv := make([]reflect.Value, numIn) // Args must be evaluated. Fixed args first. i := 0 for ; i < numFixed && i < len(args); i++ { argv[i] = s.evalArg(dot, typ.In(i), args[i]) } // Now the ... args. if typ.IsVariadic() { argType := typ.In(typ.NumIn() - 1).Elem() // Argument is a slice. for ; i < len(args); i++ { argv[i] = s.evalArg(dot, argType, args[i]) } } // Add final value if necessary. if final.IsValid() { t := typ.In(typ.NumIn() - 1) if typ.IsVariadic() { if numIn-1 < numFixed { // The added final argument corresponds to a fixed parameter of the function. // Validate against the type of the actual parameter. t = typ.In(numIn - 1) } else { // The added final argument corresponds to the variadic part. // Validate against the type of the elements of the variadic slice. t = t.Elem() } } argv[i] = s.validateType(final, t) } result := fun.Call(argv) // If we have an error that is not nil, stop execution and return that error to the caller. if len(result) == 2 && !result[1].IsNil() { s.at(node) s.errorf("error calling %s: %s", name, result[1].Interface().(error)) } return result[0] }
// evalField evaluates an expression like (.Field) or (.Field arg1 arg2). // The 'final' argument represents the return value from the preceding // value of the pipeline, if any. func (s *state) evalField(dot reflect.Value, fieldName string, node parse.Node, args []parse.Node, final, receiver reflect.Value) reflect.Value { if !receiver.IsValid() { return zero } typ := receiver.Type() receiver, _ = indirect(receiver) // Unless it's an interface, need to get to a value of type *T to guarantee // we see all methods of T and *T. ptr := receiver if ptr.Kind() != reflect.Interface && ptr.CanAddr() { ptr = ptr.Addr() } if method := ptr.MethodByName(fieldName); method.IsValid() { return s.evalCall(dot, method, node, fieldName, args, final) } hasArgs := len(args) > 1 || final.IsValid() // It's not a method; must be a field of a struct or an element of a map. The receiver must not be nil. receiver, isNil := indirect(receiver) if isNil { s.errorf("nil pointer evaluating %s.%s", typ, fieldName) } switch receiver.Kind() { case reflect.Struct: tField, ok := receiver.Type().FieldByName(fieldName) if ok { field := receiver.FieldByIndex(tField.Index) if tField.PkgPath != "" { // field is unexported s.errorf("%s is an unexported field of struct type %s", fieldName, typ) } // If it's a function, we must call it. if hasArgs { s.errorf("%s has arguments but cannot be invoked as function", fieldName) } return field } s.errorf("%s is not a field of struct type %s", fieldName, typ) case reflect.Map: // If it's a map, attempt to use the field name as a key. nameVal := reflect.ValueOf(fieldName) if nameVal.Type().AssignableTo(receiver.Type().Key()) { if hasArgs { s.errorf("%s is not a method but has arguments", fieldName) } result := receiver.MapIndex(nameVal) if !result.IsValid() { switch s.tmpl.option.missingKey { case mapInvalid: // Just use the invalid value. case mapZeroValue: result = reflect.Zero(receiver.Type().Elem()) case mapError: s.errorf("map has no entry for key %q", fieldName) } } return result } } s.errorf("can't evaluate field %s in type %s", fieldName, typ) panic("not reached") }
func valueEncoder(v reflect.Value) encoderFunc { if !v.IsValid() { return invalidValueEncoder } t := v.Type() return typeEncoder(t, v) }
// validateType guarantees that the value is valid and assignable to the type. func (s *state) validateType(value reflect.Value, typ reflect.Type) reflect.Value { if !value.IsValid() { if typ == nil || canBeNil(typ) { // An untyped nil interface{}. Accept as a proper nil value. return reflect.Zero(typ) } s.errorf("invalid value; expected %s", typ) } if typ != nil && !value.Type().AssignableTo(typ) { if value.Kind() == reflect.Interface && !value.IsNil() { value = value.Elem() if value.Type().AssignableTo(typ) { return value } // fallthrough } // Does one dereference or indirection work? We could do more, as we // do with method receivers, but that gets messy and method receivers // are much more constrained, so it makes more sense there than here. // Besides, one is almost always all you need. switch { case value.Kind() == reflect.Ptr && value.Type().Elem().AssignableTo(typ): value = value.Elem() if !value.IsValid() { s.errorf("dereference of nil pointer of type %s", typ) } case reflect.PtrTo(value.Type()).AssignableTo(typ) && value.CanAddr(): value = value.Addr() default: s.errorf("wrong type for value; expected %s; got %s", typ, value.Type()) } } return value }
// Add adds a new process with a given name to the network. // It returns true on success or panics and returns false on error. func (n *Graph) Add(c interface{}, name string) bool { // Check if passed interface is a valid pointer to struct v := reflect.ValueOf(c) if v.Kind() != reflect.Ptr || v.IsNil() { panic("flow.Graph.Add() argument is not a valid pointer") return false } v = v.Elem() if v.Kind() != reflect.Struct { panic("flow.Graph.Add() argument is not a valid pointer to struct") return false } // Set the link to self in the proccess so that it could use it var vNet reflect.Value vCom := v.FieldByName("Component") if vCom.IsValid() && vCom.Type().Name() == "Component" { vNet = vCom.FieldByName("Net") } else { vGraph := v.FieldByName("Graph") if vGraph.IsValid() && vGraph.Type().Name() == "Graph" { vNet = vGraph.FieldByName("Net") } } if vNet.IsValid() && vNet.CanSet() { vNet.Set(reflect.ValueOf(n)) } // Add to the map of processes n.procs[name] = c return true }
func (scope *Scope) getPrimaryKey() string { var indirectValue reflect.Value indirectValue = reflect.Indirect(reflect.ValueOf(scope.Value)) if indirectValue.Kind() == reflect.Slice { indirectValue = reflect.New(indirectValue.Type().Elem()).Elem() } if !indirectValue.IsValid() { return "id" } scopeTyp := indirectValue.Type() for i := 0; i < scopeTyp.NumField(); i++ { fieldStruct := scopeTyp.Field(i) if !ast.IsExported(fieldStruct.Name) { continue } // if primaryKey tag found, return column name if fieldStruct.Tag.Get("primaryKey") != "" { return ToSnake(fieldStruct.Name) } } //If primaryKey tag not found, fallback to id return "id" }
func (n *Graph) getPort(procName, portName string, extractFromPM func(portMapper, string) reflect.Value) (reflect.Value, error) { proc, found := n.procs[procName] var port reflect.Value if !found { return port, errors.New("name '" + procName + "' not found") } v := reflect.ValueOf(proc).Elem() if !v.CanSet() { return port, errors.New(procName + " is not settable") } var net reflect.Value if v.Type().Name() == "Graph" { net = v } else { net = v.FieldByName("Graph") } if net.IsValid() { // Port is a net if pm, isPm := net.Addr().Interface().(portMapper); isPm { port = extractFromPM(pm, portName) } } else { // Port is a proc port = v.FieldByName(portName) } return port, nil }
func (scan *Scan) ScanToStruct(rows *sql.Rows, record reflect.Value) error { columns, err := rows.Columns() if err != nil { return err } values := make([]interface{}, len(columns)) for i, column := range columns { var field reflect.Value fieldName := scan.SQLColumnDict[column] if scan.ToPointers { field = record.Elem().FieldByName(fieldName) } else { field = record.FieldByName(fieldName) } if field.IsValid() { values[i] = field.Addr().Interface() } else { values[i] = &values[i] } } return rows.Scan(values...) }
func valueHeader(v reflect.Value) (h *reflect.SliceHeader) { if v.IsValid() { size := int(v.Type().Size()) h = &reflect.SliceHeader{v.UnsafeAddr(), size, size} } return }
func unflattenValue(v reflect.Value, t reflect.Type) reflect.Value { // When t is an Interface, we can't do much, since we don't know the // original (unflattened) type of the value placed in v, so we just nop it. if t.Kind() == reflect.Interface { return v } // v can be invalid, if it holds the nil value for pointer type if !v.IsValid() { return v } // Make sure v is indeed flat if v.Kind() == reflect.Ptr { panic("unflattening non-flat value") } // Add a *, one at a time for t.Kind() == reflect.Ptr { if v.CanAddr() { v = v.Addr() } else { pw := reflect.New(v.Type()) pw.Elem().Set(v) v = pw } t = t.Elem() } return v }
func assertValid(vObj reflect.Value) error { if !vObj.IsValid() { return nil } if obj, ok := vObj.Interface().(interface { AssertValid() error }); ok && !(vObj.Kind() == reflect.Ptr && vObj.IsNil()) { if err := obj.AssertValid(); err != nil { return err } } switch vObj.Kind() { case reflect.Ptr: return assertValid(vObj.Elem()) case reflect.Struct: return assertStructValid(vObj) case reflect.Slice: for i := 0; i < vObj.Len(); i++ { if err := assertValid(vObj.Index(i)); err != nil { return err } } } return nil }
func (q *queryParser) parseValue(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error { value = elemOf(value) // no need to handle zero values if !value.IsValid() { return nil } t := tag.Get("type") if t == "" { switch value.Kind() { case reflect.Struct: t = "structure" case reflect.Slice: t = "list" case reflect.Map: t = "map" } } switch t { case "structure": return q.parseStruct(v, value, prefix) case "list": return q.parseList(v, value, prefix, tag) case "map": return q.parseMap(v, value, prefix, tag) default: return q.parseScalar(v, value, prefix, tag) } }
// value decodes a JSON value from d.data[d.off:] into the value. // it updates d.off to point past the decoded value. func (d *decodeState) value(v reflect.Value) { if !v.IsValid() { _, rest, err := nextValue(d.data[d.off:], &d.nextscan) if err != nil { d.error(err) } d.off = len(d.data) - len(rest) // d.scan thinks we're still at the beginning of the item. // Feed in an empty string - the shortest, simplest value - // so that it knows we got to the end of the value. if d.scan.redo { // rewind. d.scan.redo = false d.scan.step = stateBeginValue } d.scan.step(&d.scan, '"') d.scan.step(&d.scan, '"') return } switch op := d.scanWhile(scanSkipSpace); op { default: d.error(errPhase) case scanBeginArray: d.array(v) case scanBeginObject: d.object(v) case scanBeginLiteral: d.literal(v) } }
func convertType(v reflect.Value) (*string, error) { v = reflect.Indirect(v) if !v.IsValid() { return nil, nil } var str string switch value := v.Interface().(type) { case string: str = value case []byte: str = base64.StdEncoding.EncodeToString(value) case bool: str = strconv.FormatBool(value) case int64: str = strconv.FormatInt(value, 10) case float64: str = strconv.FormatFloat(value, 'f', -1, 64) case time.Time: str = value.UTC().Format(RFC822) default: err := fmt.Errorf("Unsupported value for param %v (%s)", v.Interface(), v.Type()) return nil, err } return &str, nil }
// isTrue reports whether the value is 'true', in the sense of not the zero of its type, // and whether the value has a meaningful truth value. func isTrue(val reflect.Value) (truth, ok bool) { if !val.IsValid() { // Something like var x interface{}, never set. It's a form of nil. return false, true } switch val.Kind() { case reflect.Array, reflect.Map, reflect.Slice, reflect.String: truth = val.Len() > 0 case reflect.Bool: truth = val.Bool() case reflect.Complex64, reflect.Complex128: truth = val.Complex() != 0 case reflect.Chan, reflect.Func, reflect.Ptr, reflect.Interface: truth = !val.IsNil() case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: truth = val.Int() != 0 case reflect.Float32, reflect.Float64: truth = val.Float() != 0 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: truth = val.Uint() != 0 case reflect.Struct: truth = true // Struct values are always true. default: return } return truth, true }
func ReturnWhenSet(a, k interface{}) interface{} { av, isNil := indirect(reflect.ValueOf(a)) if isNil { return "" } var avv reflect.Value switch av.Kind() { case reflect.Array, reflect.Slice: index, ok := k.(int) if ok && av.Len() > index { avv = av.Index(index) } case reflect.Map: kv := reflect.ValueOf(k) if kv.Type().AssignableTo(av.Type().Key()) { avv = av.MapIndex(kv) } } if avv.IsValid() { switch avv.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return avv.Int() case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: return avv.Uint() case reflect.Float32, reflect.Float64: return avv.Float() case reflect.String: return avv.String() } } return "" }
// validateType guarantees that the value is valid and assignable to the type. func (s *state) validateType(value reflect.Value, typ reflect.Type) reflect.Value { if !value.IsValid() { switch typ.Kind() { case reflect.Interface, reflect.Ptr, reflect.Chan, reflect.Map, reflect.Slice, reflect.Func: // An untyped nil interface{}. Accept as a proper nil value. // TODO: Can we delete the other types in this list? Should we? value = reflect.Zero(typ) default: s.errorf("invalid value; expected %s", typ) } } if !value.Type().AssignableTo(typ) { // Does one dereference or indirection work? We could do more, as we // do with method receivers, but that gets messy and method receivers // are much more constrained, so it makes more sense there than here. // Besides, one is almost always all you need. switch { case value.Kind() == reflect.Ptr && value.Type().Elem().AssignableTo(typ): value = value.Elem() case reflect.PtrTo(value.Type()).AssignableTo(typ) && value.CanAddr(): value = value.Addr() default: s.errorf("wrong type for value; expected %s; got %s", typ, value.Type()) } } return value }