package json import ( "bytes" "encoding/json" "errors" "fmt" "reflect" ) // Unmarshal unmarshals JSON into the given value, using Amino-compatible JSON encoding (strings // for 64-bit numbers, and type wrappers for registered types). func Unmarshal(bz []byte, v interface{}) error { return decode(bz, v) } func decode(bz []byte, v interface{}) error { if len(bz) == 0 { return errors.New("cannot decode empty bytes") } rv := reflect.ValueOf(v) if rv.Kind() != reflect.Ptr { return errors.New("must decode into a pointer") } rv = rv.Elem() // If this is a registered type, defer to interface decoder regardless of whether the input is // an interface or a bare value. This retains Amino's behavior, but is inconsistent with // behavior in structs where an interface field will get the type wrapper while a bare value // field will not. if typeRegistry.name(rv.Type()) != "" { return decodeReflectInterface(bz, rv) } return decodeReflect(bz, rv) } func decodeReflect(bz []byte, rv reflect.Value) error { if !rv.CanAddr() { return errors.New("value is not addressable") } // Handle null for slices, interfaces, and pointers if bytes.Equal(bz, []byte("null")) { rv.Set(reflect.Zero(rv.Type())) return nil } // Dereference-and-construct pointers, to handle nested pointers. for rv.Kind() == reflect.Ptr { if rv.IsNil() { rv.Set(reflect.New(rv.Type().Elem())) } rv = rv.Elem() } // Times must be UTC and end with Z if rv.Type() == timeType { switch { case len(bz) < 2 || bz[0] != '"' || bz[len(bz)-1] != '"': return fmt.Errorf("JSON time must be an RFC3339 string, but got %q", bz) case bz[len(bz)-2] != 'Z': return fmt.Errorf("JSON time must be UTC and end with 'Z', but got %q", bz) } } // If value implements json.Umarshaler, call it. if rv.Addr().Type().Implements(jsonUnmarshalerType) { return rv.Addr().Interface().(json.Unmarshaler).UnmarshalJSON(bz) } switch rv.Type().Kind() { // Decode complex types recursively. case reflect.Slice, reflect.Array: return decodeReflectList(bz, rv) case reflect.Map: return decodeReflectMap(bz, rv) case reflect.Struct: return decodeReflectStruct(bz, rv) case reflect.Interface: return decodeReflectInterface(bz, rv) // For 64-bit integers, unwrap expected string and defer to stdlib for integer decoding. case reflect.Int64, reflect.Int, reflect.Uint64, reflect.Uint: if bz[0] != '"' || bz[len(bz)-1] != '"' { return fmt.Errorf("invalid 64-bit integer encoding %q, expected string", string(bz)) } bz = bz[1 : len(bz)-1] fallthrough // Anything else we defer to the stdlib. default: return decodeStdlib(bz, rv) } } func decodeReflectList(bz []byte, rv reflect.Value) error { if !rv.CanAddr() { return errors.New("list value is not addressable") } switch rv.Type().Elem().Kind() { // Decode base64-encoded bytes using stdlib decoder, via byte slice for arrays. case reflect.Uint8: if rv.Type().Kind() == reflect.Array { var buf []byte if err := json.Unmarshal(bz, &buf); err != nil { return err } if len(buf) != rv.Len() { return fmt.Errorf("got %v bytes, expected %v", len(buf), rv.Len()) } reflect.Copy(rv, reflect.ValueOf(buf)) } else if err := decodeStdlib(bz, rv); err != nil { return err } // Decode anything else into a raw JSON slice, and decode values recursively. default: var rawSlice []json.RawMessage if err := json.Unmarshal(bz, &rawSlice); err != nil { return err } if rv.Type().Kind() == reflect.Slice { rv.Set(reflect.MakeSlice(reflect.SliceOf(rv.Type().Elem()), len(rawSlice), len(rawSlice))) } if rv.Len() != len(rawSlice) { // arrays of wrong size return fmt.Errorf("got list of %v elements, expected %v", len(rawSlice), rv.Len()) } for i, bz := range rawSlice { if err := decodeReflect(bz, rv.Index(i)); err != nil { return err } } } // Replace empty slices with nil slices, for Amino compatibility if rv.Type().Kind() == reflect.Slice && rv.Len() == 0 { rv.Set(reflect.Zero(rv.Type())) } return nil } func decodeReflectMap(bz []byte, rv reflect.Value) error { if !rv.CanAddr() { return errors.New("map value is not addressable") } // Decode into a raw JSON map, using string keys. rawMap := make(map[string]json.RawMessage) if err := json.Unmarshal(bz, &rawMap); err != nil { return err } if rv.Type().Key().Kind() != reflect.String { return fmt.Errorf("map keys must be strings, got %v", rv.Type().Key().String()) } // Recursively decode values. rv.Set(reflect.MakeMapWithSize(rv.Type(), len(rawMap))) for key, bz := range rawMap { value := reflect.New(rv.Type().Elem()).Elem() if err := decodeReflect(bz, value); err != nil { return err } rv.SetMapIndex(reflect.ValueOf(key), value) } return nil } func decodeReflectStruct(bz []byte, rv reflect.Value) error { if !rv.CanAddr() { return errors.New("struct value is not addressable") } sInfo := makeStructInfo(rv.Type()) // Decode raw JSON values into a string-keyed map. rawMap := make(map[string]json.RawMessage) if err := json.Unmarshal(bz, &rawMap); err != nil { return err } for i, fInfo := range sInfo.fields { if !fInfo.hidden { frv := rv.Field(i) bz := rawMap[fInfo.jsonName] if len(bz) > 0 { if err := decodeReflect(bz, frv); err != nil { return err } } else if !fInfo.omitEmpty { frv.Set(reflect.Zero(frv.Type())) } } } return nil } func decodeReflectInterface(bz []byte, rv reflect.Value) error { if !rv.CanAddr() { return errors.New("interface value not addressable") } // Decode the interface wrapper. wrapper := interfaceWrapper{} if err := json.Unmarshal(bz, &wrapper); err != nil { return err } if wrapper.Type == "" { return errors.New("interface type cannot be empty") } if len(wrapper.Value) == 0 { return errors.New("interface value cannot be empty") } // Dereference-and-construct pointers, to handle nested pointers. for rv.Kind() == reflect.Ptr { if rv.IsNil() { rv.Set(reflect.New(rv.Type().Elem())) } rv = rv.Elem() } // Look up the interface type, and construct a concrete value. rt, returnPtr := typeRegistry.lookup(wrapper.Type) if rt == nil { return fmt.Errorf("unknown type %q", wrapper.Type) } cptr := reflect.New(rt) crv := cptr.Elem() if err := decodeReflect(wrapper.Value, crv); err != nil { return err } // This makes sure interface implementations with pointer receivers (e.g. func (c *Car)) are // constructed as pointers behind the interface. The types must be registered as pointers with // RegisterType(). if rv.Type().Kind() == reflect.Interface && returnPtr { if !cptr.Type().AssignableTo(rv.Type()) { return fmt.Errorf("invalid type %q for this value", wrapper.Type) } rv.Set(cptr) } else { if !crv.Type().AssignableTo(rv.Type()) { return fmt.Errorf("invalid type %q for this value", wrapper.Type) } rv.Set(crv) } return nil } func decodeStdlib(bz []byte, rv reflect.Value) error { if !rv.CanAddr() && rv.Kind() != reflect.Ptr { return errors.New("value must be addressable or pointer") } // Make sure we are unmarshaling into a pointer. target := rv if rv.Kind() != reflect.Ptr { target = reflect.New(rv.Type()) } if err := json.Unmarshal(bz, target.Interface()); err != nil { return err } rv.Set(target.Elem()) return nil } type interfaceWrapper struct { Type string `json:"type"` Value json.RawMessage `json:"value"` }