OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / tendermint / go-wire / reflect.go
1 package wire
2
3 import (
4         "encoding/hex"
5         "encoding/json"
6         "errors"
7         "io"
8         "reflect"
9         "strings"
10         "sync"
11         "time"
12
13         cmn "github.com/tendermint/tmlibs/common"
14 )
15
16 type TypeInfo struct {
17         Type reflect.Type // The type
18
19         // If Type is kind reflect.Interface, is registered
20         IsRegisteredInterface bool
21         ByteToType            map[byte]reflect.Type
22         TypeToByte            map[reflect.Type]byte
23
24         // If Type is kind reflect.Struct
25         Fields []StructFieldInfo
26         Unwrap bool // if struct has only one field and its an anonymous interface
27 }
28
29 type Options struct {
30         JSONName      string      // (JSON) Corresponding JSON field name. (override with `json=""`)
31         JSONOmitEmpty bool        // (JSON) Omit field if value is empty
32         Varint        bool        // (Binary) Use length-prefixed encoding for (u)int64
33         Unsafe        bool        // (JSON/Binary) Explicitly enable support for floats or maps
34         ZeroValue     interface{} // Prototype zero object
35 }
36
37 func getOptionsFromField(field reflect.StructField) (skip bool, opts Options) {
38         jsonTag := field.Tag.Get("json")
39         binTag := field.Tag.Get("binary")
40         wireTag := field.Tag.Get("wire")
41         if jsonTag == "-" {
42                 skip = true
43                 return
44         }
45         jsonTagParts := strings.Split(jsonTag, ",")
46         if jsonTagParts[0] == "" {
47                 opts.JSONName = field.Name
48         } else {
49                 opts.JSONName = jsonTagParts[0]
50         }
51         if len(jsonTagParts) > 1 {
52                 if jsonTagParts[1] == "omitempty" {
53                         opts.JSONOmitEmpty = true
54                 }
55         }
56         if binTag == "varint" { // TODO: extend
57                 opts.Varint = true
58         }
59         if wireTag == "unsafe" {
60                 opts.Unsafe = true
61         }
62         opts.ZeroValue = reflect.Zero(field.Type).Interface()
63         return
64 }
65
66 type StructFieldInfo struct {
67         Index   int          // Struct field index
68         Type    reflect.Type // Struct field type
69         Options              // Encoding options
70 }
71
72 func (info StructFieldInfo) unpack() (int, reflect.Type, Options) {
73         return info.Index, info.Type, info.Options
74 }
75
76 // e.g. If o is struct{Foo}{}, return is the Foo reflection type.
77 func GetTypeFromStructDeclaration(o interface{}) reflect.Type {
78         rt := reflect.TypeOf(o)
79         if rt.NumField() != 1 {
80                 cmn.PanicSanity("Unexpected number of fields in struct-wrapped declaration of type")
81         }
82         return rt.Field(0).Type
83 }
84
85 // Predeclaration of common types
86 var (
87         timeType = GetTypeFromStructDeclaration(struct{ time.Time }{})
88 )
89
90 const (
91         RFC3339Millis = "2006-01-02T15:04:05.000Z" // forced microseconds
92 )
93
94 // NOTE: do not access typeInfos directly, but call GetTypeInfo()
95 var typeInfosMtx sync.RWMutex
96 var typeInfos = map[reflect.Type]*TypeInfo{}
97
98 func GetTypeInfo(rt reflect.Type) *TypeInfo {
99         typeInfosMtx.RLock()
100         info := typeInfos[rt]
101         typeInfosMtx.RUnlock()
102         if info == nil {
103                 info = MakeTypeInfo(rt)
104                 typeInfosMtx.Lock()
105                 typeInfos[rt] = info
106                 typeInfosMtx.Unlock()
107         }
108         return info
109 }
110
111 // For use with the RegisterInterface declaration
112 type ConcreteType struct {
113         O    interface{}
114         Byte byte
115 }
116
117 // This function should be used to register the receiving interface that will
118 // be used to decode an underlying concrete type. The interface MUST be embedded
119 // in a struct, and the interface MUST be the only field and it MUST be exported.
120 // For example:
121 //      RegisterInterface(struct{ Animal }{}, ConcreteType{&foo, 0x01})
122 func RegisterInterface(o interface{}, ctypes ...ConcreteType) *TypeInfo {
123         it := GetTypeFromStructDeclaration(o)
124         if it.Kind() != reflect.Interface {
125                 cmn.PanicSanity("RegisterInterface expects an interface")
126         }
127         toType := make(map[byte]reflect.Type, 0)
128         toByte := make(map[reflect.Type]byte, 0)
129         for _, ctype := range ctypes {
130                 crt := reflect.TypeOf(ctype.O)
131                 typeByte := ctype.Byte
132                 if typeByte == 0x00 {
133                         cmn.PanicSanity(cmn.Fmt("Byte of 0x00 is reserved for nil (%v)", ctype))
134                 }
135                 if toType[typeByte] != nil {
136                         cmn.PanicSanity(cmn.Fmt("Duplicate Byte for type %v and %v", ctype, toType[typeByte]))
137                 }
138                 toType[typeByte] = crt
139                 toByte[crt] = typeByte
140         }
141         typeInfo := &TypeInfo{
142                 Type: it,
143                 IsRegisteredInterface: true,
144                 ByteToType:            toType,
145                 TypeToByte:            toByte,
146         }
147         typeInfos[it] = typeInfo
148         return typeInfo
149 }
150
151 func MakeTypeInfo(rt reflect.Type) *TypeInfo {
152         info := &TypeInfo{Type: rt}
153
154         // If struct, register field name options
155         if rt.Kind() == reflect.Struct {
156                 numFields := rt.NumField()
157                 structFields := []StructFieldInfo{}
158                 for i := 0; i < numFields; i++ {
159                         field := rt.Field(i)
160                         if field.PkgPath != "" {
161                                 continue
162                         }
163                         skip, opts := getOptionsFromField(field)
164                         if skip {
165                                 continue
166                         }
167                         structFields = append(structFields, StructFieldInfo{
168                                 Index:   i,
169                                 Type:    field.Type,
170                                 Options: opts,
171                         })
172                 }
173                 info.Fields = structFields
174
175                 // Maybe type is a wrapper.
176                 if len(structFields) == 1 {
177                         jsonName := rt.Field(structFields[0].Index).Tag.Get("json")
178                         if jsonName == "unwrap" {
179                                 info.Unwrap = true
180                         }
181                 }
182         }
183
184         return info
185 }
186
187 // Contract: Caller must ensure that rt is supported
188 // (e.g. is recursively composed of supported native types, and structs and slices.)
189 func readReflectBinary(rv reflect.Value, rt reflect.Type, opts Options, r io.Reader, lmt int, n *int, err *error) {
190
191         // Get typeInfo
192         typeInfo := GetTypeInfo(rt)
193
194         if rt.Kind() == reflect.Interface {
195                 if !typeInfo.IsRegisteredInterface {
196                         // There's no way we can read such a thing.
197                         *err = errors.New(cmn.Fmt("Cannot read unregistered interface type %v", rt))
198                         return
199                 }
200                 typeByte := ReadByte(r, n, err)
201                 if *err != nil {
202                         return
203                 }
204                 if typeByte == 0x00 {
205                         return // nil
206                 }
207                 crt, ok := typeInfo.ByteToType[typeByte]
208                 if !ok {
209                         *err = errors.New(cmn.Fmt("Unexpected type byte %X for type %v", typeByte, rt))
210                         return
211                 }
212                 if crt.Kind() == reflect.Ptr {
213                         crt = crt.Elem()
214                         crv := reflect.New(crt)
215                         readReflectBinary(crv.Elem(), crt, opts, r, lmt, n, err)
216                         rv.Set(crv) // NOTE: orig rv is ignored.
217                 } else {
218                         crv := reflect.New(crt).Elem()
219                         readReflectBinary(crv, crt, opts, r, lmt, n, err)
220                         rv.Set(crv) // NOTE: orig rv is ignored.
221                 }
222                 return
223         }
224
225         if rt.Kind() == reflect.Ptr {
226                 typeByte := ReadByte(r, n, err)
227                 if *err != nil {
228                         return
229                 }
230                 if typeByte == 0x00 {
231                         return // nil
232                 } else if typeByte != 0x01 {
233                         *err = errors.New(cmn.Fmt("Unexpected type byte %X for ptr of untyped thing", typeByte))
234                         return
235                 }
236                 // Create new if rv is nil.
237                 if rv.IsNil() {
238                         newRv := reflect.New(rt.Elem())
239                         rv.Set(newRv)
240                         rv = newRv
241                 }
242                 // Dereference pointer
243                 rv, rt = rv.Elem(), rt.Elem()
244                 typeInfo = GetTypeInfo(rt)
245                 // continue...
246         }
247
248         switch rt.Kind() {
249         case reflect.Array:
250                 elemRt := rt.Elem()
251                 length := rt.Len()
252                 if elemRt.Kind() == reflect.Uint8 {
253                         // Special case: Bytearrays
254                         buf := make([]byte, length)
255                         ReadFull(buf, r, n, err)
256                         if *err != nil {
257                                 return
258                         }
259                         //log.Info("Read bytearray", "bytes", buf, "n", *n)
260                         reflect.Copy(rv, reflect.ValueOf(buf))
261                 } else {
262                         for i := 0; i < length; i++ {
263                                 elemRv := rv.Index(i)
264                                 readReflectBinary(elemRv, elemRt, opts, r, lmt, n, err)
265                                 if *err != nil {
266                                         return
267                                 }
268                                 if lmt != 0 && lmt < *n {
269                                         *err = ErrBinaryReadOverflow
270                                         return
271                                 }
272                         }
273                         //log.Info("Read x-array", "x", elemRt, "length", length, "n", *n)
274                 }
275
276         case reflect.Slice:
277                 elemRt := rt.Elem()
278                 if elemRt.Kind() == reflect.Uint8 {
279                         // Special case: Byteslices
280                         byteslice := ReadByteSlice(r, lmt, n, err)
281                         //log.Info("Read byteslice", "bytes", byteslice, "n", *n)
282                         rv.Set(reflect.ValueOf(byteslice))
283                 } else {
284                         var sliceRv reflect.Value
285                         // Read length
286                         length := ReadVarint(r, n, err)
287                         //log.Info("Read slice", "length", length, "n", *n)
288                         sliceRv = reflect.MakeSlice(rt, 0, 0)
289                         // read one ReadSliceChunkSize at a time and append
290                         for i := 0; i*ReadSliceChunkSize < length; i++ {
291                                 l := cmn.MinInt(ReadSliceChunkSize, length-i*ReadSliceChunkSize)
292                                 tmpSliceRv := reflect.MakeSlice(rt, l, l)
293                                 for j := 0; j < l; j++ {
294                                         elemRv := tmpSliceRv.Index(j)
295                                         readReflectBinary(elemRv, elemRt, opts, r, lmt, n, err)
296                                         if *err != nil {
297                                                 return
298                                         }
299                                         if lmt != 0 && lmt < *n {
300                                                 *err = ErrBinaryReadOverflow
301                                                 return
302                                         }
303                                 }
304                                 sliceRv = reflect.AppendSlice(sliceRv, tmpSliceRv)
305                         }
306
307                         rv.Set(sliceRv)
308                 }
309
310         case reflect.Struct:
311                 if rt == timeType {
312                         // Special case: time.Time
313                         t := ReadTime(r, n, err)
314                         //log.Info("Read time", "t", t, "n", *n)
315                         rv.Set(reflect.ValueOf(t))
316                 } else {
317                         for _, fieldInfo := range typeInfo.Fields {
318                                 fieldIdx, fieldType, opts := fieldInfo.unpack()
319                                 fieldRv := rv.Field(fieldIdx)
320                                 readReflectBinary(fieldRv, fieldType, opts, r, lmt, n, err)
321                         }
322                 }
323
324         case reflect.String:
325                 str := ReadString(r, lmt, n, err)
326                 //log.Info("Read string", "str", str, "n", *n)
327                 rv.SetString(str)
328
329         case reflect.Int64:
330                 if opts.Varint {
331                         num := ReadVarint(r, n, err)
332                         //log.Info("Read num", "num", num, "n", *n)
333                         rv.SetInt(int64(num))
334                 } else {
335                         num := ReadInt64(r, n, err)
336                         //log.Info("Read num", "num", num, "n", *n)
337                         rv.SetInt(int64(num))
338                 }
339
340         case reflect.Int32:
341                 num := ReadUint32(r, n, err)
342                 //log.Info("Read num", "num", num, "n", *n)
343                 rv.SetInt(int64(num))
344
345         case reflect.Int16:
346                 num := ReadUint16(r, n, err)
347                 //log.Info("Read num", "num", num, "n", *n)
348                 rv.SetInt(int64(num))
349
350         case reflect.Int8:
351                 num := ReadUint8(r, n, err)
352                 //log.Info("Read num", "num", num, "n", *n)
353                 rv.SetInt(int64(num))
354
355         case reflect.Int:
356                 num := ReadVarint(r, n, err)
357                 //log.Info("Read num", "num", num, "n", *n)
358                 rv.SetInt(int64(num))
359
360         case reflect.Uint64:
361                 if opts.Varint {
362                         num := ReadVarint(r, n, err)
363                         //log.Info("Read num", "num", num, "n", *n)
364                         rv.SetUint(uint64(num))
365                 } else {
366                         num := ReadUint64(r, n, err)
367                         //log.Info("Read num", "num", num, "n", *n)
368                         rv.SetUint(uint64(num))
369                 }
370
371         case reflect.Uint32:
372                 num := ReadUint32(r, n, err)
373                 //log.Info("Read num", "num", num, "n", *n)
374                 rv.SetUint(uint64(num))
375
376         case reflect.Uint16:
377                 num := ReadUint16(r, n, err)
378                 //log.Info("Read num", "num", num, "n", *n)
379                 rv.SetUint(uint64(num))
380
381         case reflect.Uint8:
382                 num := ReadUint8(r, n, err)
383                 //log.Info("Read num", "num", num, "n", *n)
384                 rv.SetUint(uint64(num))
385
386         case reflect.Uint:
387                 num := ReadVarint(r, n, err)
388                 //log.Info("Read num", "num", num, "n", *n)
389                 rv.SetUint(uint64(num))
390
391         case reflect.Bool:
392                 num := ReadUint8(r, n, err)
393                 //log.Info("Read bool", "bool", num, "n", *n)
394                 rv.SetBool(num > 0)
395
396         case reflect.Float64:
397                 if !opts.Unsafe {
398                         *err = errors.New("Wire float* support requires `wire:\"unsafe\"`")
399                         return
400                 }
401                 num := ReadFloat64(r, n, err)
402                 //log.Info("Read num", "num", num, "n", *n)
403                 rv.SetFloat(float64(num))
404
405         case reflect.Float32:
406                 if !opts.Unsafe {
407                         *err = errors.New("Wire float* support requires `wire:\"unsafe\"`")
408                         return
409                 }
410                 num := ReadFloat32(r, n, err)
411                 //log.Info("Read num", "num", num, "n", *n)
412                 rv.SetFloat(float64(num))
413
414         default:
415                 cmn.PanicSanity(cmn.Fmt("Unknown field type %v", rt.Kind()))
416         }
417 }
418
419 // rv: the reflection value of the thing to write
420 // rt: the type of rv as declared in the container, not necessarily rv.Type().
421 func writeReflectBinary(rv reflect.Value, rt reflect.Type, opts Options, w io.Writer, n *int, err *error) {
422
423         // Get typeInfo
424         typeInfo := GetTypeInfo(rt)
425
426         if rt.Kind() == reflect.Interface {
427                 if rv.IsNil() {
428                         WriteByte(0x00, w, n, err)
429                         return
430                 }
431                 crv := rv.Elem()  // concrete reflection value
432                 crt := crv.Type() // concrete reflection type
433                 if typeInfo.IsRegisteredInterface {
434                         // See if the crt is registered.
435                         // If so, we're more restrictive.
436                         typeByte, ok := typeInfo.TypeToByte[crt]
437                         if !ok {
438                                 switch crt.Kind() {
439                                 case reflect.Ptr:
440                                         *err = errors.New(cmn.Fmt("Unexpected pointer type %v for registered interface %v. "+
441                                                 "Was it registered as a value receiver rather than as a pointer receiver?", crt, rt.Name()))
442                                 case reflect.Struct:
443                                         *err = errors.New(cmn.Fmt("Unexpected struct type %v for registered interface %v. "+
444                                                 "Was it registered as a pointer receiver rather than as a value receiver?", crt, rt.Name()))
445                                 default:
446                                         *err = errors.New(cmn.Fmt("Unexpected type %v for registered interface %v. "+
447                                                 "If this is intentional, please register it.", crt, rt.Name()))
448                                 }
449                                 return
450                         }
451                         if crt.Kind() == reflect.Ptr {
452                                 crv, crt = crv.Elem(), crt.Elem()
453                                 if !crv.IsValid() {
454                                         *err = errors.New(cmn.Fmt("Unexpected nil-pointer of type %v for registered interface %v. "+
455                                                 "For compatibility with other languages, nil-pointer interface values are forbidden.", crt, rt.Name()))
456                                         return
457                                 }
458                         }
459                         WriteByte(typeByte, w, n, err)
460                         writeReflectBinary(crv, crt, opts, w, n, err)
461                 } else {
462                         // We support writing unregistered interfaces for convenience.
463                         writeReflectBinary(crv, crt, opts, w, n, err)
464                 }
465                 return
466         }
467
468         if rt.Kind() == reflect.Ptr {
469                 // Dereference pointer
470                 rv, rt = rv.Elem(), rt.Elem()
471                 typeInfo = GetTypeInfo(rt)
472                 if !rv.IsValid() {
473                         WriteByte(0x00, w, n, err)
474                         return
475                 } else {
476                         WriteByte(0x01, w, n, err)
477                         // continue...
478                 }
479         }
480
481         // All other types
482         switch rt.Kind() {
483         case reflect.Array:
484                 elemRt := rt.Elem()
485                 length := rt.Len()
486                 if elemRt.Kind() == reflect.Uint8 {
487                         // Special case: Bytearrays
488                         if rv.CanAddr() {
489                                 byteslice := rv.Slice(0, length).Bytes()
490                                 WriteTo(byteslice, w, n, err)
491
492                         } else {
493                                 buf := make([]byte, length)
494                                 reflect.Copy(reflect.ValueOf(buf), rv) // XXX: looks expensive!
495                                 WriteTo(buf, w, n, err)
496                         }
497                 } else {
498                         // Write elems
499                         for i := 0; i < length; i++ {
500                                 elemRv := rv.Index(i)
501                                 writeReflectBinary(elemRv, elemRt, opts, w, n, err)
502                         }
503                 }
504
505         case reflect.Slice:
506                 elemRt := rt.Elem()
507                 if elemRt.Kind() == reflect.Uint8 {
508                         // Special case: Byteslices
509                         byteslice := rv.Bytes()
510                         WriteByteSlice(byteslice, w, n, err)
511                 } else {
512                         // Write length
513                         length := rv.Len()
514                         WriteVarint(length, w, n, err)
515                         // Write elems
516                         for i := 0; i < length; i++ {
517                                 elemRv := rv.Index(i)
518                                 writeReflectBinary(elemRv, elemRt, opts, w, n, err)
519                         }
520                 }
521
522         case reflect.Struct:
523                 if rt == timeType {
524                         // Special case: time.Time
525                         WriteTime(rv.Interface().(time.Time), w, n, err)
526                 } else {
527                         for _, fieldInfo := range typeInfo.Fields {
528                                 fieldIdx, fieldType, opts := fieldInfo.unpack()
529                                 fieldRv := rv.Field(fieldIdx)
530                                 writeReflectBinary(fieldRv, fieldType, opts, w, n, err)
531                         }
532                 }
533
534         case reflect.String:
535                 WriteString(rv.String(), w, n, err)
536
537         case reflect.Int64:
538                 if opts.Varint {
539                         WriteVarint(int(rv.Int()), w, n, err)
540                 } else {
541                         WriteInt64(rv.Int(), w, n, err)
542                 }
543
544         case reflect.Int32:
545                 WriteInt32(int32(rv.Int()), w, n, err)
546
547         case reflect.Int16:
548                 WriteInt16(int16(rv.Int()), w, n, err)
549
550         case reflect.Int8:
551                 WriteInt8(int8(rv.Int()), w, n, err)
552
553         case reflect.Int:
554                 WriteVarint(int(rv.Int()), w, n, err)
555
556         case reflect.Uint64:
557                 if opts.Varint {
558                         WriteUvarint(uint(rv.Uint()), w, n, err)
559                 } else {
560                         WriteUint64(rv.Uint(), w, n, err)
561                 }
562
563         case reflect.Uint32:
564                 WriteUint32(uint32(rv.Uint()), w, n, err)
565
566         case reflect.Uint16:
567                 WriteUint16(uint16(rv.Uint()), w, n, err)
568
569         case reflect.Uint8:
570                 WriteUint8(uint8(rv.Uint()), w, n, err)
571
572         case reflect.Uint:
573                 WriteUvarint(uint(rv.Uint()), w, n, err)
574
575         case reflect.Bool:
576                 if rv.Bool() {
577                         WriteUint8(uint8(1), w, n, err)
578                 } else {
579                         WriteUint8(uint8(0), w, n, err)
580                 }
581
582         case reflect.Float64:
583                 if !opts.Unsafe {
584                         *err = errors.New("Wire float* support requires `wire:\"unsafe\"`")
585                         return
586                 }
587                 WriteFloat64(rv.Float(), w, n, err)
588
589         case reflect.Float32:
590                 if !opts.Unsafe {
591                         *err = errors.New("Wire float* support requires `wire:\"unsafe\"`")
592                         return
593                 }
594                 WriteFloat32(float32(rv.Float()), w, n, err)
595
596         default:
597                 cmn.PanicSanity(cmn.Fmt("Unknown field type %v", rt.Kind()))
598         }
599 }
600
601 //-----------------------------------------------------------------------------
602
603 func readByteJSON(o interface{}) (typeByte byte, rest interface{}, err error) {
604         oSlice, ok := o.([]interface{})
605         if !ok {
606                 err = errors.New(cmn.Fmt("Expected type [Byte,?] but got type %v", reflect.TypeOf(o)))
607                 return
608         }
609         if len(oSlice) != 2 {
610                 err = errors.New(cmn.Fmt("Expected [Byte,?] len 2 but got len %v", len(oSlice)))
611                 return
612         }
613         typeByte_, ok := oSlice[0].(float64)
614         typeByte = byte(typeByte_)
615         rest = oSlice[1]
616         return
617 }
618
619 // Contract: Caller must ensure that rt is supported
620 // (e.g. is recursively composed of supported native types, and structs and slices.)
621 // rv and rt refer to the object we're unmarhsaling into, whereas o is the result of naiive json unmarshal (map[string]interface{})
622 func readReflectJSON(rv reflect.Value, rt reflect.Type, opts Options, o interface{}, err *error) {
623
624         // Get typeInfo
625         typeInfo := GetTypeInfo(rt)
626
627         if rt.Kind() == reflect.Interface {
628                 if !typeInfo.IsRegisteredInterface {
629                         // There's no way we can read such a thing.
630                         *err = errors.New(cmn.Fmt("Cannot read unregistered interface type %v", rt))
631                         return
632                 }
633                 if o == nil {
634                         return // nil
635                 }
636                 typeByte, rest, err_ := readByteJSON(o)
637                 if err_ != nil {
638                         *err = err_
639                         return
640                 }
641                 crt, ok := typeInfo.ByteToType[typeByte]
642                 if !ok {
643                         *err = errors.New(cmn.Fmt("Byte %X not registered for interface %v", typeByte, rt))
644                         return
645                 }
646                 if crt.Kind() == reflect.Ptr {
647                         crt = crt.Elem()
648                         crv := reflect.New(crt)
649                         readReflectJSON(crv.Elem(), crt, opts, rest, err)
650                         rv.Set(crv) // NOTE: orig rv is ignored.
651                 } else {
652                         crv := reflect.New(crt).Elem()
653                         readReflectJSON(crv, crt, opts, rest, err)
654                         rv.Set(crv) // NOTE: orig rv is ignored.
655                 }
656                 return
657         }
658
659         if rt.Kind() == reflect.Ptr {
660                 if o == nil {
661                         return // nil
662                 }
663                 // Create new struct if rv is nil.
664                 if rv.IsNil() {
665                         newRv := reflect.New(rt.Elem())
666                         rv.Set(newRv)
667                         rv = newRv
668                 }
669                 // Dereference pointer
670                 rv, rt = rv.Elem(), rt.Elem()
671                 typeInfo = GetTypeInfo(rt)
672                 // continue...
673         }
674
675         switch rt.Kind() {
676         case reflect.Array:
677                 elemRt := rt.Elem()
678                 length := rt.Len()
679                 if elemRt.Kind() == reflect.Uint8 {
680                         // Special case: Bytearrays
681                         oString, ok := o.(string)
682                         if !ok {
683                                 *err = errors.New(cmn.Fmt("Expected string but got type %v", reflect.TypeOf(o)))
684                                 return
685                         }
686                         buf, err_ := hex.DecodeString(oString)
687                         if err_ != nil {
688                                 *err = err_
689                                 return
690                         }
691                         if len(buf) != length {
692                                 *err = errors.New(cmn.Fmt("Expected bytearray of length %v but got %v", length, len(buf)))
693                                 return
694                         }
695                         //log.Info("Read bytearray", "bytes", buf)
696                         reflect.Copy(rv, reflect.ValueOf(buf))
697                 } else {
698                         oSlice, ok := o.([]interface{})
699                         if !ok {
700                                 *err = errors.New(cmn.Fmt("Expected array of %v but got type %v", rt, reflect.TypeOf(o)))
701                                 return
702                         }
703                         if len(oSlice) != length {
704                                 *err = errors.New(cmn.Fmt("Expected array of length %v but got %v", length, len(oSlice)))
705                                 return
706                         }
707                         for i := 0; i < length; i++ {
708                                 elemRv := rv.Index(i)
709                                 readReflectJSON(elemRv, elemRt, opts, oSlice[i], err)
710                         }
711                         //log.Info("Read x-array", "x", elemRt, "length", length)
712                 }
713
714         case reflect.Slice:
715                 elemRt := rt.Elem()
716                 if elemRt.Kind() == reflect.Uint8 {
717                         // Special case: Byteslices
718                         oString, ok := o.(string)
719                         if !ok {
720                                 *err = errors.New(cmn.Fmt("Expected string but got type %v", reflect.TypeOf(o)))
721                                 return
722                         }
723                         byteslice, err_ := hex.DecodeString(oString)
724                         if err_ != nil {
725                                 *err = err_
726                                 return
727                         }
728                         //log.Info("Read byteslice", "bytes", byteslice)
729                         rv.Set(reflect.ValueOf(byteslice))
730                 } else {
731                         // Read length
732                         oSlice, ok := o.([]interface{})
733                         if !ok {
734                                 *err = errors.New(cmn.Fmt("Expected array of %v but got type %v", rt, reflect.TypeOf(o)))
735                                 return
736                         }
737                         length := len(oSlice)
738                         //log.Info("Read slice", "length", length)
739                         sliceRv := reflect.MakeSlice(rt, length, length)
740                         // Read elems
741                         for i := 0; i < length; i++ {
742                                 elemRv := sliceRv.Index(i)
743                                 readReflectJSON(elemRv, elemRt, opts, oSlice[i], err)
744                         }
745                         rv.Set(sliceRv)
746                 }
747
748         case reflect.Struct:
749                 if rt == timeType {
750                         // Special case: time.Time
751                         str, ok := o.(string)
752                         if !ok {
753                                 *err = errors.New(cmn.Fmt("Expected string but got type %v", reflect.TypeOf(o)))
754                                 return
755                         }
756                         // try three ways, seconds, milliseconds, or microseconds...
757                         t, err_ := time.Parse(time.RFC3339Nano, str)
758                         if err_ != nil {
759                                 *err = err_
760                                 return
761                         }
762                         rv.Set(reflect.ValueOf(t))
763                 } else {
764                         if typeInfo.Unwrap {
765                                 fieldIdx, fieldType, opts := typeInfo.Fields[0].unpack()
766                                 fieldRv := rv.Field(fieldIdx)
767                                 readReflectJSON(fieldRv, fieldType, opts, o, err)
768                         } else {
769                                 oMap, ok := o.(map[string]interface{})
770                                 if !ok {
771                                         *err = errors.New(cmn.Fmt("Expected map but got type %v", reflect.TypeOf(o)))
772                                         return
773                                 }
774                                 // TODO: ensure that all fields are set?
775                                 // TODO: disallow unknown oMap fields?
776                                 for _, fieldInfo := range typeInfo.Fields {
777                                         fieldIdx, fieldType, opts := fieldInfo.unpack()
778                                         value, ok := oMap[opts.JSONName]
779                                         if !ok {
780                                                 continue // Skip missing fields.
781                                         }
782                                         fieldRv := rv.Field(fieldIdx)
783                                         readReflectJSON(fieldRv, fieldType, opts, value, err)
784                                 }
785                         }
786                 }
787
788         case reflect.String:
789                 str, ok := o.(string)
790                 if !ok {
791                         *err = errors.New(cmn.Fmt("Expected string but got type %v", reflect.TypeOf(o)))
792                         return
793                 }
794                 //log.Info("Read string", "str", str)
795                 rv.SetString(str)
796
797         case reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8, reflect.Int:
798                 num, ok := o.(float64)
799                 if !ok {
800                         *err = errors.New(cmn.Fmt("Expected numeric but got type %v", reflect.TypeOf(o)))
801                         return
802                 }
803                 //log.Info("Read num", "num", num)
804                 rv.SetInt(int64(num))
805
806         case reflect.Uint64, reflect.Uint32, reflect.Uint16, reflect.Uint8, reflect.Uint:
807                 num, ok := o.(float64)
808                 if !ok {
809                         *err = errors.New(cmn.Fmt("Expected numeric but got type %v", reflect.TypeOf(o)))
810                         return
811                 }
812                 if num < 0 {
813                         *err = errors.New(cmn.Fmt("Expected unsigned numeric but got %v", num))
814                         return
815                 }
816                 //log.Info("Read num", "num", num)
817                 rv.SetUint(uint64(num))
818
819         case reflect.Float64, reflect.Float32:
820                 if !opts.Unsafe {
821                         *err = errors.New("Wire float* support requires `wire:\"unsafe\"`")
822                         return
823                 }
824                 num, ok := o.(float64)
825                 if !ok {
826                         *err = errors.New(cmn.Fmt("Expected numeric but got type %v", reflect.TypeOf(o)))
827                         return
828                 }
829                 //log.Info("Read num", "num", num)
830                 rv.SetFloat(num)
831
832         case reflect.Bool:
833                 bl, ok := o.(bool)
834                 if !ok {
835                         *err = errors.New(cmn.Fmt("Expected boolean but got type %v", reflect.TypeOf(o)))
836                         return
837                 }
838                 //log.Info("Read boolean", "boolean", bl)
839                 rv.SetBool(bl)
840
841         default:
842                 cmn.PanicSanity(cmn.Fmt("Unknown field type %v", rt.Kind()))
843         }
844 }
845
846 func writeReflectJSON(rv reflect.Value, rt reflect.Type, opts Options, w io.Writer, n *int, err *error) {
847         //log.Info(cmn.Fmt("writeReflectJSON(%v, %v, %v, %v, %v)", rv, rt, w, n, err))
848
849         // Get typeInfo
850         typeInfo := GetTypeInfo(rt)
851
852         if rt.Kind() == reflect.Interface {
853                 if rv.IsNil() {
854                         WriteTo([]byte("null"), w, n, err)
855                         return
856                 }
857                 crv := rv.Elem()  // concrete reflection value
858                 crt := crv.Type() // concrete reflection type
859                 if typeInfo.IsRegisteredInterface {
860                         // See if the crt is registered.
861                         // If so, we're more restrictive.
862                         typeByte, ok := typeInfo.TypeToByte[crt]
863                         if !ok {
864                                 switch crt.Kind() {
865                                 case reflect.Ptr:
866                                         *err = errors.New(cmn.Fmt("Unexpected pointer type %v for registered interface %v. "+
867                                                 "Was it registered as a value receiver rather than as a pointer receiver?", crt, rt.Name()))
868                                 case reflect.Struct:
869                                         *err = errors.New(cmn.Fmt("Unexpected struct type %v for registered interface %v. "+
870                                                 "Was it registered as a pointer receiver rather than as a value receiver?", crt, rt.Name()))
871                                 default:
872                                         *err = errors.New(cmn.Fmt("Unexpected type %v for registered interface %v. "+
873                                                 "If this is intentional, please register it.", crt, rt.Name()))
874                                 }
875                                 return
876                         }
877                         if crt.Kind() == reflect.Ptr {
878                                 crv, crt = crv.Elem(), crt.Elem()
879                                 if !crv.IsValid() {
880                                         *err = errors.New(cmn.Fmt("Unexpected nil-pointer of type %v for registered interface %v. "+
881                                                 "For compatibility with other languages, nil-pointer interface values are forbidden.", crt, rt.Name()))
882                                         return
883                                 }
884                         }
885                         WriteTo([]byte(cmn.Fmt("[%v,", typeByte)), w, n, err)
886                         writeReflectJSON(crv, crt, opts, w, n, err)
887                         WriteTo([]byte("]"), w, n, err)
888                 } else {
889                         // We support writing unregistered interfaces for convenience.
890                         writeReflectJSON(crv, crt, opts, w, n, err)
891                 }
892                 return
893         }
894
895         if rt.Kind() == reflect.Ptr {
896                 // Dereference pointer
897                 rv, rt = rv.Elem(), rt.Elem()
898                 typeInfo = GetTypeInfo(rt)
899                 if !rv.IsValid() {
900                         // For better compatibility with other languages,
901                         // as far as tendermint/wire is concerned,
902                         // pointers to nil values are the same as nil.
903                         WriteTo([]byte("null"), w, n, err)
904                         return
905                 }
906                 // continue...
907         }
908
909         // All other types
910         switch rt.Kind() {
911         case reflect.Array:
912                 elemRt := rt.Elem()
913                 length := rt.Len()
914                 if elemRt.Kind() == reflect.Uint8 {
915                         // Special case: Bytearray
916                         bytearray := reflect.ValueOf(make([]byte, length))
917                         reflect.Copy(bytearray, rv)
918                         WriteTo([]byte(cmn.Fmt("\"%X\"", bytearray.Interface())), w, n, err)
919                 } else {
920                         WriteTo([]byte("["), w, n, err)
921                         // Write elems
922                         for i := 0; i < length; i++ {
923                                 elemRv := rv.Index(i)
924                                 writeReflectJSON(elemRv, elemRt, opts, w, n, err)
925                                 if i < length-1 {
926                                         WriteTo([]byte(","), w, n, err)
927                                 }
928                         }
929                         WriteTo([]byte("]"), w, n, err)
930                 }
931
932         case reflect.Slice:
933                 elemRt := rt.Elem()
934                 if elemRt.Kind() == reflect.Uint8 {
935                         // Special case: Byteslices
936                         byteslice := rv.Bytes()
937                         WriteTo([]byte(cmn.Fmt("\"%X\"", byteslice)), w, n, err)
938                 } else {
939                         WriteTo([]byte("["), w, n, err)
940                         // Write elems
941                         length := rv.Len()
942                         for i := 0; i < length; i++ {
943                                 elemRv := rv.Index(i)
944                                 writeReflectJSON(elemRv, elemRt, opts, w, n, err)
945                                 if i < length-1 {
946                                         WriteTo([]byte(","), w, n, err)
947                                 }
948                         }
949                         WriteTo([]byte("]"), w, n, err)
950                 }
951
952         case reflect.Struct:
953                 if rt == timeType {
954                         // Special case: time.Time
955                         t := rv.Interface().(time.Time).UTC()
956                         str := t.Format(RFC3339Millis)
957                         jsonBytes, err_ := json.Marshal(str)
958                         if err_ != nil {
959                                 *err = err_
960                                 return
961                         }
962                         WriteTo(jsonBytes, w, n, err)
963                 } else {
964                         if typeInfo.Unwrap {
965                                 fieldIdx, fieldType, opts := typeInfo.Fields[0].unpack()
966                                 fieldRv := rv.Field(fieldIdx)
967                                 writeReflectJSON(fieldRv, fieldType, opts, w, n, err)
968                         } else {
969                                 WriteTo([]byte("{"), w, n, err)
970                                 wroteField := false
971                                 for _, fieldInfo := range typeInfo.Fields {
972                                         fieldIdx, fieldType, opts := fieldInfo.unpack()
973                                         fieldRv := rv.Field(fieldIdx)
974                                         if opts.JSONOmitEmpty && isEmpty(fieldType, fieldRv, opts) { // Skip zero value if omitempty
975                                                 continue
976                                         }
977                                         if wroteField {
978                                                 WriteTo([]byte(","), w, n, err)
979                                         } else {
980                                                 wroteField = true
981                                         }
982                                         WriteTo([]byte(cmn.Fmt("\"%v\":", opts.JSONName)), w, n, err)
983                                         writeReflectJSON(fieldRv, fieldType, opts, w, n, err)
984                                 }
985                                 WriteTo([]byte("}"), w, n, err)
986                         }
987                 }
988
989         case reflect.String:
990                 fallthrough
991         case reflect.Uint64, reflect.Uint32, reflect.Uint16, reflect.Uint8, reflect.Uint:
992                 fallthrough
993         case reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8, reflect.Int:
994                 fallthrough
995         case reflect.Bool:
996                 jsonBytes, err_ := json.Marshal(rv.Interface())
997                 if err_ != nil {
998                         *err = err_
999                         return
1000                 }
1001                 WriteTo(jsonBytes, w, n, err)
1002
1003         case reflect.Float64, reflect.Float32:
1004                 if !opts.Unsafe {
1005                         *err = errors.New("Wire float* support requires `wire:\"unsafe\"`")
1006                         return
1007                 }
1008                 jsonBytes, err_ := json.Marshal(rv.Interface())
1009                 if err_ != nil {
1010                         *err = err_
1011                         return
1012                 }
1013                 WriteTo(jsonBytes, w, n, err)
1014
1015         default:
1016                 cmn.PanicSanity(cmn.Fmt("Unknown field type %v", rt.Kind()))
1017         }
1018
1019 }
1020
1021 func isEmpty(rt reflect.Type, rv reflect.Value, opts Options) bool {
1022         if rt.Comparable() {
1023                 // if its comparable we can check directly
1024                 if rv.Interface() == opts.ZeroValue {
1025                         return true
1026                 }
1027                 return false
1028         } else {
1029                 // TODO: A faster alternative might be to call writeReflectJSON
1030                 // onto a buffer and check if its "{}" or not.
1031                 switch rt.Kind() {
1032                 case reflect.Struct:
1033                         // check fields
1034                         typeInfo := GetTypeInfo(rt)
1035                         for _, fieldInfo := range typeInfo.Fields {
1036                                 fieldIdx, fieldType, opts := fieldInfo.unpack()
1037                                 fieldRv := rv.Field(fieldIdx)
1038                                 if !isEmpty(fieldType, fieldRv, opts) { // Skip zero value if omitempty
1039                                         return false
1040                                 }
1041                         }
1042                         return true
1043
1044                 default:
1045                         if rv.Len() == 0 {
1046                                 return true
1047                         }
1048                         return false
1049                 }
1050         }
1051         return false
1052 }