// writeExtensions writes all the extensions in pv. // pv is assumed to be a pointer to a protocol message struct that is extendable. func writeExtensions(w *textWriter, pv reflect.Value) error { emap := extensionMaps[pv.Type().Elem()] ep := pv.Interface().(extendableProto) // Order the extensions by ID. // This isn't strictly necessary, but it will give us // canonical output, which will also make testing easier. var m map[int32]Extension if em, ok := ep.(extensionsMap); ok { m = em.ExtensionMap() } else if em, ok := ep.(extensionsBytes); ok { eb := em.GetExtensions() var err error m, err = BytesToExtensionsMap(*eb) if err != nil { return err } } ids := make([]int32, 0, len(m)) for id := range m { ids = append(ids, id) } sort.Sort(int32Slice(ids)) for _, extNum := range ids { ext := m[extNum] var desc *ExtensionDesc if emap != nil { desc = emap[extNum] } if desc == nil { // Unknown extension. if err := writeUnknownStruct(w, ext.enc); err != nil { return err } continue } pb, err := GetExtension(ep, desc) if err != nil { return fmt.Errorf("failed getting extension: %v", err) } // Repeated extensions will appear as a slice. if !desc.repeated() { if err := writeExtension(w, desc.Name, pb); err != nil { return err } } else { v := reflect.ValueOf(pb) for i := 0; i < v.Len(); i++ { if err := writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil { return err } } } } return nil }
// for insert and update // If already assigned, then just ignore tag func GetValQuoteStr(val reflect.Value) (string, error) { switch val.Kind() { case reflect.Bool: boolStr := "N" if val.Bool() { boolStr = "Y" } return boolStr, nil case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return strconv.FormatInt(val.Int(), 10), nil case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return strconv.FormatUint(val.Uint(), 10), nil case reflect.Float32, reflect.Float64: return strconv.FormatFloat(val.Float(), 'f', -1, 64), nil case reflect.String: return QuoteStr(val.String()), nil case reflect.Slice: //[]byte if val.Type().Elem().Name() != "uint8" { return "", fmt.Errorf("GetValQuoteStr> slicetype is not []byte: %v", val.Interface()) } return QuoteStr(string(val.Interface().([]byte))), nil default: return "", fmt.Errorf("GetValQuoteStr> reflect.Value is not a string/int/uint/float/bool/[]byte!\nval: %v", val) } return "", nil }
func isZero(v reflect.Value) bool { switch v.Kind() { case reflect.String: return len(v.String()) == 0 case reflect.Interface, reflect.Ptr: return v.IsNil() case reflect.Slice: return v.Len() == 0 case reflect.Map: return v.Len() == 0 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return v.Int() == 0 case reflect.Float32, reflect.Float64: return v.Float() == 0 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return v.Uint() == 0 case reflect.Bool: return !v.Bool() case reflect.Struct: vt := v.Type() for i := v.NumField() - 1; i >= 0; i-- { if vt.Field(i).PkgPath != "" { continue // Private field } if !isZero(v.Field(i)) { return false } } return true } return false }
func (par *parserParser) ParseValue(ctx *parseContext, valueOf reflect.Value, location int, err *Error) int { var v Parser if par.ptr { v = valueOf.Addr().Interface().(Parser) } else { if valueOf.Kind() == reflect.Ptr { valueOf = reflect.New(valueOf.Type().Elem()) } v = valueOf.Interface().(Parser) } l, e := v.ParseValue(ctx.str, location) if e != nil { switch ev := e.(type) { case Error: err.Location = ev.Location err.Message = ev.Message err.Str = ev.Str return -1 } err.Location = location err.Message = e.Error() return -1 } location = l if location > len(ctx.str) { panic("Invalid parser") } return location }
// validateStruct will validate the struct value's fields. If the structure has // nested types those types will be validated also. func (v *validator) validateStruct(value reflect.Value, path string) { prefix := "." if path == "" { prefix = "" } for i := 0; i < value.Type().NumField(); i++ { f := value.Type().Field(i) if strings.ToLower(f.Name[0:1]) == f.Name[0:1] { continue } fvalue := value.FieldByName(f.Name) notset := false if f.Tag.Get("required") != "" { switch fvalue.Kind() { case reflect.Ptr, reflect.Slice, reflect.Map: if fvalue.IsNil() { notset = true } default: if !fvalue.IsValid() { notset = true } } } if notset { msg := "missing required parameter: " + path + prefix + f.Name v.errors = append(v.errors, msg) } else { v.validateAny(fvalue, path+prefix+f.Name) } } }
func (d *commonDialect) SqlTag(value reflect.Value, size int) string { switch value.Kind() { case reflect.Bool: return "BOOLEAN" case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uintptr: return "INTEGER" case reflect.Int64, reflect.Uint64: return "BIGINT" case reflect.Float32, reflect.Float64: return "FLOAT" case reflect.String: if size > 0 && size < 65532 { return fmt.Sprintf("VARCHAR(%d)", size) } else { return "VARCHAR(65532)" } case reflect.Struct: if value.Type() == timeType { return "TIMESTAMP" } default: if _, ok := value.Interface().([]byte); ok { if size > 0 && size < 65532 { return fmt.Sprintf("BINARY(%d)", size) } else { return "BINARY(65532)" } } } panic(fmt.Sprintf("invalid sql type %s (%s) for commonDialect", value.Type().Name(), value.Kind().String())) }
// 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) }
func (p *Decoder) unmarshalDictionary(pval *plistValue, val reflect.Value) { typ := val.Type() switch val.Kind() { case reflect.Struct: tinfo, err := getTypeInfo(typ) if err != nil { panic(err) } subvalues := pval.value.(*dictionary).m for _, finfo := range tinfo.fields { p.unmarshal(subvalues[finfo.name], finfo.value(val)) } case reflect.Map: if val.IsNil() { val.Set(reflect.MakeMap(typ)) } subvalues := pval.value.(*dictionary).m for k, sval := range subvalues { keyv := reflect.ValueOf(k).Convert(typ.Key()) mapElem := val.MapIndex(keyv) if !mapElem.IsValid() { mapElem = reflect.New(typ.Elem()).Elem() } p.unmarshal(sval, mapElem) val.SetMapIndex(keyv, mapElem) } default: panic(&incompatibleDecodeTypeError{typ, pval.kind}) } }
func (p *Decoder) unmarshalLaxString(s string, val reflect.Value) { switch val.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: i := mustParseInt(s, 10, 64) val.SetInt(i) return case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: i := mustParseUint(s, 10, 64) val.SetUint(i) return case reflect.Float32, reflect.Float64: f := mustParseFloat(s, 64) val.SetFloat(f) return case reflect.Bool: b := mustParseBool(s) val.SetBool(b) return case reflect.Struct: if val.Type() == timeType { t, err := time.Parse(textPlistTimeLayout, s) if err != nil { panic(err) } val.Set(reflect.ValueOf(t.In(time.UTC))) return } fallthrough default: panic(&incompatibleDecodeTypeError{val.Type(), String}) } }
func (e *Encoder) encode(v reflect.Value, dst map[string][]string) error { var opts string var value string t := v.Type() for i := 0; i < v.NumField(); i++ { tag := t.Field(i).Tag.Get(e.TagID) name := tag if idx := strings.Index(tag, ","); idx != -1 { name = tag[:idx] opts = tag[idx+1:] } if name == "-" { continue } encFunc, recurse := encoder(v.Field(i).Type()) if recurse { e.encode(v.Field(i), dst) continue } value = encFunc(v.Field(i)) if value == "" && strings.Contains(opts, "omitempty") { continue } dst[name] = []string{value} } return nil }
func (p *Decoder) unmarshalArray(pval *plistValue, val reflect.Value) { subvalues := pval.value.([]*plistValue) var n int if val.Kind() == reflect.Slice { // Slice of element values. // Grow slice. cnt := len(subvalues) + val.Len() if cnt >= val.Cap() { ncap := 2 * cnt if ncap < 4 { ncap = 4 } new := reflect.MakeSlice(val.Type(), val.Len(), ncap) reflect.Copy(new, val) val.Set(new) } n = val.Len() val.SetLen(cnt) } else if val.Kind() == reflect.Array { if len(subvalues) > val.Cap() { panic(fmt.Errorf("plist: attempted to unmarshal %d values into an array of size %d", len(subvalues), val.Cap())) } } else { panic(&incompatibleDecodeTypeError{val.Type(), pval.kind}) } // Recur to read element into slice. for _, sval := range subvalues { p.unmarshal(sval, val.Index(n)) n++ } return }
func (q *queryParser) parseScalar(v url.Values, r reflect.Value, name string, tag reflect.StructTag) error { switch value := r.Interface().(type) { case string: v.Set(name, value) case []byte: if !r.IsNil() { v.Set(name, base64.StdEncoding.EncodeToString(value)) } case bool: v.Set(name, strconv.FormatBool(value)) case int64: v.Set(name, strconv.FormatInt(value, 10)) case int: v.Set(name, strconv.Itoa(value)) case float64: v.Set(name, strconv.FormatFloat(value, 'f', -1, 64)) case float32: v.Set(name, strconv.FormatFloat(float64(value), 'f', -1, 32)) case time.Time: const ISO8601UTC = "2006-01-02T15:04:05Z" v.Set(name, value.UTC().Format(ISO8601UTC)) default: return fmt.Errorf("unsupported value for param %s: %v (%s)", name, r.Interface(), r.Type().Name()) } return nil }
func (p *untypedParamBinder) setSliceFieldValue(target reflect.Value, defaultValue interface{}, data []string) error { if len(data) == 0 && p.parameter.Required && p.parameter.Default == nil { return errors.Required(p.Name, p.parameter.In) } defVal := reflect.Zero(target.Type()) if defaultValue != nil { defVal = reflect.ValueOf(defaultValue) } if len(data) == 0 { target.Set(defVal) return nil } sz := len(data) value := reflect.MakeSlice(reflect.SliceOf(target.Type().Elem()), sz, sz) for i := 0; i < sz; i++ { if err := p.setFieldValue(value.Index(i), nil, data[i]); err != nil { return err } } target.Set(value) return nil }
// 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 (mssql) SqlTag(value reflect.Value, size int, autoIncrease bool) string { switch value.Kind() { case reflect.Bool: return "bit" case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uintptr: if autoIncrease { return "int IDENTITY(1,1)" } return "int" case reflect.Int64, reflect.Uint64: if autoIncrease { return "bigint IDENTITY(1,1)" } return "bigint" case reflect.Float32, reflect.Float64: return "float" case reflect.String: if size > 0 && size < 65532 { return fmt.Sprintf("nvarchar(%d)", size) } return "text" case reflect.Struct: if _, ok := value.Interface().(time.Time); ok { return "datetime2" } default: if _, ok := value.Interface().([]byte); ok { if size > 0 && size < 65532 { return fmt.Sprintf("varchar(%d)", size) } return "text" } } panic(fmt.Sprintf("invalid sql type %s (%s) for mssql", value.Type().Name(), value.Kind().String())) }
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() }
// IsZero returns true when the value is a zero for the type func isZero(data reflect.Value) bool { if !data.CanInterface() { return true } tpe := data.Type() return reflect.DeepEqual(data.Interface(), reflect.Zero(tpe).Interface()) }
func isZero(v reflect.Value) bool { switch v.Kind() { case reflect.Func, reflect.Map, reflect.Slice: return v.IsNil() case reflect.Array: z := true for i := 0; i < v.Len(); i++ { z = z && isZero(v.Index(i)) } return z case reflect.Struct: if v.Type() == reflect.TypeOf(t) { if v.Interface().(time.Time).IsZero() { return true } return false } z := true for i := 0; i < v.NumField(); i++ { z = z && isZero(v.Field(i)) } return z } // Compare other types directly: z := reflect.Zero(v.Type()) return v.Interface() == z.Interface() }
func setValue(dstVal reflect.Value, src interface{}) { if dstVal.Kind() == reflect.Ptr { dstVal = reflect.Indirect(dstVal) } srcVal := reflect.ValueOf(src) if !srcVal.IsValid() { // src is literal nil if dstVal.CanAddr() { // Convert to pointer so that pointer's value can be nil'ed // dstVal = dstVal.Addr() } dstVal.Set(reflect.Zero(dstVal.Type())) } else if srcVal.Kind() == reflect.Ptr { if srcVal.IsNil() { srcVal = reflect.Zero(dstVal.Type()) } else { srcVal = reflect.ValueOf(src).Elem() } dstVal.Set(srcVal) } else { dstVal.Set(srcVal) } }
// Evaluate interfaces and pointers looking for a value that can look up the name, via a // struct field, method, or map key, and return the result of the lookup. func (t *Template) lookup(st *state, v reflect.Value, name string) reflect.Value { for v != nil { typ := v.Type() if n := v.Type().NumMethod(); n > 0 { for i := 0; i < n; i++ { m := typ.Method(i) mtyp := m.Type if m.Name == name && mtyp.NumIn() == 1 && mtyp.NumOut() == 1 { if !isExported(name) { t.execError(st, t.linenum, "name not exported: %s in type %s", name, st.data.Type()) } return v.Method(i).Call(nil)[0] } } } switch av := v.(type) { case *reflect.PtrValue: v = av.Elem() case *reflect.InterfaceValue: v = av.Elem() case *reflect.StructValue: if !isExported(name) { t.execError(st, t.linenum, "name not exported: %s in type %s", name, st.data.Type()) } return av.FieldByName(name) case *reflect.MapValue: return av.Elem(reflect.NewValue(name)) default: return nil } } return v }
// See if name is a method of the value at some level of indirection. // The return values are the result of the call (which may be nil if // there's trouble) and whether a method of the right name exists with // any signature. func callMethod(data reflect.Value, name string) (result reflect.Value, found bool) { found = false // Method set depends on pointerness, and the value may be arbitrarily // indirect. Simplest approach is to walk down the pointer chain and // see if we can find the method at each step. // Most steps will see NumMethod() == 0. for { typ := data.Type() if nMethod := data.Type().NumMethod(); nMethod > 0 { for i := 0; i < nMethod; i++ { method := typ.Method(i) if method.Name == name { found = true // we found the name regardless // does receiver type match? (pointerness might be off) if typ == method.Type.In(0) { return call(data, method), found } } } } if nd := data; nd.Kind() == reflect.Ptr { data = nd.Elem() } else { break } } return }
func (g *Group) scanSubGroupHandler(realval reflect.Value, sfield *reflect.StructField) (bool, error) { mtag := newMultiTag(string(sfield.Tag)) if err := mtag.Parse(); err != nil { return true, err } subgroup := mtag.Get("group") if len(subgroup) != 0 { ptrval := reflect.NewAt(realval.Type(), unsafe.Pointer(realval.UnsafeAddr())) description := mtag.Get("description") group, err := g.AddGroup(subgroup, description, ptrval.Interface()) if err != nil { return true, err } group.Namespace = mtag.Get("namespace") group.Hidden = mtag.Get("hidden") != "" return true, nil } return false, nil }
func (par *intParser) ParseValue(ctx *parseContext, valueOf reflect.Value, location int, err *Error) int { if valueOf.Type().Bits() == 32 && location < len(ctx.str) && ctx.str[location] == '\'' { location++ r, location := ctx.parseUnicodeValue(location, err) if location < 0 { return location } if location >= len(ctx.str) || ctx.str[location] != '\'' { err.Message = "Waiting for closing quote in unicode character" err.Location = location return -1 } location++ valueOf.SetInt(int64(r)) return location } r, l := ctx.parseInt64(location, uint(valueOf.Type().Bits()), err) if l < 0 { return l } valueOf.SetInt(r) return l }
func decodeMapStringInterface(d *decodeState, kind int, v reflect.Value) { if kind != kindDocument { d.saveErrorAndSkip(kind, v.Type()) } if v.IsNil() { v.Set(reflect.MakeMap(v.Type())) } var m map[string]interface{} switch mm := v.Interface().(type) { case map[string]interface{}: m = mm case M: m = (map[string]interface{})(mm) } offset := d.beginDoc() for { kind, name := d.scanKindName() if kind == 0 { break } if kind == kindNull { continue } m[string(name)] = d.decodeValueInterface(kind) } d.endDoc(offset) }
func GetColVals(val reflect.Value, cols []string) (values []string, err error) { typ := val.Type() // if not struct, then must just have one column. if val.Kind() != reflect.Struct && len(cols) != 1 { return nil, fmt.Errorf("GetColVals> If not a struct(%s), must have one column: %v", val.Kind(), cols) } values = make([]string, len(cols)) for i, col := range cols { var fieldVal reflect.Value if val.Kind() == reflect.Struct { fieldIndex := getFieldIndexByName(typ, col) if fieldIndex[0] < 0 { return nil, fmt.Errorf("GetColVals> Can't found struct field(column): '%s'\n", col) } fieldVal = val.FieldByIndex(fieldIndex) } else { fieldVal = val } if values[i], err = GetValQuoteStr(fieldVal); err != nil { return } } return }
func decodeMap(d *decodeState, kind int, v reflect.Value) { t := v.Type() if t.Key().Kind() != reflect.String || kind != kindDocument { d.saveErrorAndSkip(kind, t) return } if v.IsNil() { v.Set(reflect.MakeMap(t)) } subv := reflect.New(t.Elem()).Elem() offset := d.beginDoc() for { kind, name := d.scanKindName() if kind == 0 { break } if kind == kindNull { continue } subv.Set(reflect.Zero(t.Elem())) d.decodeValue(kind, subv) v.SetMapIndex(reflect.ValueOf(string(name)), subv) } d.endDoc(offset) }
// EncodeValue transmits the data item represented by the reflection value, // guaranteeing that all necessary type information has been transmitted first. func (enc *Encoder) EncodeValue(value reflect.Value) os.Error { // Make sure we're single-threaded through here, so multiple // goroutines can share an encoder. enc.mutex.Lock() defer enc.mutex.Unlock() enc.err = nil rt, _ := indirect(value.Type()) // Sanity check only: encoder should never come in with data present. if enc.state.b.Len() > 0 || enc.countState.b.Len() > 0 { enc.err = os.ErrorString("encoder: buffer not empty") return enc.err } enc.sendTypeDescriptor(rt) if enc.err != nil { return enc.err } // Encode the object. err := enc.encode(enc.state.b, value) if err != nil { enc.setError(err) } else { enc.send() } return enc.err }
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 }
func evalStarExpr(ctx *Ctx, starExpr *StarExpr, env *Env) (*reflect.Value, bool, error) { // return nil, false, errors.New("Star expressions not done yet") var cexpr Expr var errs []error if cexpr, errs = CheckExpr(ctx, starExpr.X, env); len(errs) != 0 { for _, cerr := range errs { fmt.Printf("%v\n", cerr) } return nil, false, errors.New("Something wrong checking * expression") } xs, _, err := EvalExpr(ctx, cexpr, env) if err != nil { return nil, false, err } else if xs == nil { // XXX temporary error until typed evaluation of nil return nil, false, errors.New("Cannot dereferece nil type") } var x reflect.Value if x, err = expectSingleValue(ctx, *xs, starExpr.X); err != nil { return nil, false, err } switch x.Type().Kind() { case reflect.Interface, reflect.Ptr: val := x.Elem() return &val, true, nil default: return nil, true, ErrInvalidIndirect{x.Type()} } }
func visitStruct(val reflect.Value, visitor structVisitor) error { if val.Kind() != reflect.Ptr { return errNoPointer } val = reflect.Indirect(val) if val.Kind() != reflect.Struct { return errNoStruct } typ := val.Type() for ii := 0; ii < typ.NumField(); ii++ { field := typ.Field(ii) fieldVal := val.Field(ii) ptr := fieldVal.Addr().Interface() name := defaultFieldName(field.Name) var help string if n := field.Tag.Get("name"); n != "" { name = n } if h := field.Tag.Get("help"); h != "" { help = h } if name == "" { return fmt.Errorf("no name provided for field %s in type %s", field.Name, typ) } if err := visitor(name, help, &field, fieldVal, ptr); err != nil { return err } } return nil }