func (cdc *Codec) encodeReflectJSON(w io.Writer, info *TypeInfo, rv reflect.Value, fopts FieldOptions) (err error) {
	if !rv.IsValid() {
		panic("should not happen")
	}
	if printLog {
		spew.Printf("(E) encodeReflectJSON(info: %v, rv: %#v (%v), fopts: %v)\n",
			info, rv.Interface(), rv.Type(), fopts)
		defer func() {
			fmt.Printf("(E) -> err: %v\n", err)
		}()
	}

	// Dereference value if pointer.
	var isNilPtr bool
	rv, _, isNilPtr = derefPointers(rv)

	// Write null if necessary.
	if isNilPtr {
		err = writeStr(w, `null`)
		return
	}

	// Special case:
	if rv.Type() == timeType {
		// Amino time strips the timezone.
		// NOTE: This must be done before json.Marshaler override below.
		ct := rv.Interface().(time.Time).Round(0).UTC()
		rv = reflect.ValueOf(ct)
	}
	// Handle override if rv implements json.Marshaler.
	if rv.CanAddr() { // Try pointer first.
		if rv.Addr().Type().Implements(jsonMarshalerType) {
			err = invokeMarshalJSON(w, rv.Addr())
			return
		}
	} else if rv.Type().Implements(jsonMarshalerType) {
		err = invokeMarshalJSON(w, rv)
		return
	}

	// Handle override if rv implements json.Marshaler.
	if info.IsAminoMarshaler {
		// First, encode rv into repr instance.
		var rrv, rinfo = reflect.Value{}, (*TypeInfo)(nil)
		rrv, err = toReprObject(rv)
		if err != nil {
			return
		}
		rinfo, err = cdc.getTypeInfo_wlock(info.AminoMarshalReprType)
		if err != nil {
			return
		}
		// Then, encode the repr instance.
		err = cdc.encodeReflectJSON(w, rinfo, rrv, fopts)
		return
	}

	switch info.Type.Kind() {

	//----------------------------------------
	// Complex

	case reflect.Interface:
		return cdc.encodeReflectJSONInterface(w, info, rv, fopts)

	case reflect.Array, reflect.Slice:
		return cdc.encodeReflectJSONList(w, info, rv, fopts)

	case reflect.Struct:
		return cdc.encodeReflectJSONStruct(w, info, rv, fopts)

	case reflect.Map:
		return cdc.encodeReflectJSONMap(w, info, rv, fopts)

	//----------------------------------------
	// Signed, Unsigned

	case reflect.Int64, reflect.Int:
		_, err = fmt.Fprintf(w, `"%d"`, rv.Int()) // JS can't handle int64
		return

	case reflect.Uint64, reflect.Uint:
		_, err = fmt.Fprintf(w, `"%d"`, rv.Uint()) // JS can't handle uint64
		return

	case reflect.Int32, reflect.Int16, reflect.Int8,
		reflect.Uint32, reflect.Uint16, reflect.Uint8:
		return invokeStdlibJSONMarshal(w, rv.Interface())

	//----------------------------------------
	// Misc

	case reflect.Float64, reflect.Float32:
		if !fopts.Unsafe {
			return errors.New("Amino.JSON float* support requires `amino:\"unsafe\"`.")
		}
		fallthrough
	case reflect.Bool, reflect.String:
		return invokeStdlibJSONMarshal(w, rv.Interface())

	//----------------------------------------
	// Default

	default:
		panic(fmt.Sprintf("unsupported type %v", info.Type.Kind()))
	}
}
func (cdc *Codec) encodeReflectJSON(w io.Writer, info *TypeInfo, rv reflect.Value, fopts FieldOptions) (err error) {
	if !rv.IsValid() {
		panic("should not happen")
	}
	if printLog {
		spew.Printf("(E) encodeReflectJSON(info: %v, rv: %#v (%v), fopts: %v)\n",
			info, rv.Interface(), rv.Type(), fopts)
		defer func() {
			fmt.Printf("(E) -> err: %v\n", err)
		}()
	}

	
	var isNilPtr bool
	rv, _, isNilPtr = derefPointers(rv)

	
	if isNilPtr {
		err = writeStr(w, `null`)
		return
	}

	
	if rv.Type() == timeType {
		
		
		ct := rv.Interface().(time.Time).Round(0).UTC()
		rv = reflect.ValueOf(ct)
	}
	
	if rv.CanAddr() { 
		if rv.Addr().Type().Implements(jsonMarshalerType) {
			err = invokeMarshalJSON(w, rv.Addr())
			return
		}
	} else if rv.Type().Implements(jsonMarshalerType) {
		err = invokeMarshalJSON(w, rv)
		return
	}

	
	if info.IsAminoMarshaler {
		
		var rrv, rinfo = reflect.Value{}, (*TypeInfo)(nil)
		rrv, err = toReprObject(rv)
		if err != nil {
			return
		}
		rinfo, err = cdc.getTypeInfo_wlock(info.AminoMarshalReprType)
		if err != nil {
			return
		}
		
		err = cdc.encodeReflectJSON(w, rinfo, rrv, fopts)
		return
	}

	switch info.Type.Kind() {

	
	

	case reflect.Interface:
		return cdc.encodeReflectJSONInterface(w, info, rv, fopts)

	case reflect.Array, reflect.Slice:
		return cdc.encodeReflectJSONList(w, info, rv, fopts)

	case reflect.Struct:
		return cdc.encodeReflectJSONStruct(w, info, rv, fopts)

	case reflect.Map:
		return cdc.encodeReflectJSONMap(w, info, rv, fopts)

	
	

	case reflect.Int64, reflect.Int:
		_, err = fmt.Fprintf(w, `"%d"`, rv.Int()) 
		return

	case reflect.Uint64, reflect.Uint:
		_, err = fmt.Fprintf(w, `"%d"`, rv.Uint()) 
		return

	case reflect.Int32, reflect.Int16, reflect.Int8,
		reflect.Uint32, reflect.Uint16, reflect.Uint8:
		return invokeStdlibJSONMarshal(w, rv.Interface())

	
	

	case reflect.Float64, reflect.Float32:
		if !fopts.Unsafe {
			return errors.New("Amino.JSON float* support requires `amino:\"unsafe\"`.")
		}
		fallthrough
	case reflect.Bool, reflect.String:
		return invokeStdlibJSONMarshal(w, rv.Interface())

	
	

	default:
		panic(fmt.Sprintf("unsupported type %v", info.Type.Kind()))
	}
}
func ( cdc * Codec ) encodeReflectJSON ( w io . Writer , info * TypeInfo , rv reflect . Value , fopts FieldOptions ) ( err error ) { if ! rv . IsValid ( ) { panic ( " " ) } if printLog { spew . Printf ( " \n " , info , rv . Interface ( ) , rv . Type ( ) , fopts ) defer func ( ) { fmt . Printf ( " \n " , err ) } ( ) } // Dereference value if pointer. var isNilPtr bool rv , _ , isNilPtr = derefPointers ( rv ) // Write null if necessary. if isNilPtr { err = writeStr ( w , `null` ) return } // Special case: if rv . Type ( ) == timeType { // Amino time strips the timezone. // NOTE: This must be done before json.Marshaler override below. ct := rv . Interface ( ) . ( time . Time ) . Round ( 0 ) . UTC ( ) rv = reflect . ValueOf ( ct ) } // Handle override if rv implements json.Marshaler. if rv . CanAddr ( ) { // Try pointer first. if rv . Addr ( ) . Type ( ) . Implements ( jsonMarshalerType ) { err = invokeMarshalJSON ( w , rv . Addr ( ) ) return } } else if rv . Type ( ) . Implements ( jsonMarshalerType ) { err = invokeMarshalJSON ( w , rv ) return } // Handle override if rv implements json.Marshaler. if info . IsAminoMarshaler { // First, encode rv into repr instance. var rrv , rinfo = reflect . Value { } , ( * TypeInfo ) ( nil ) rrv , err = toReprObject ( rv ) if err != nil { return } rinfo , err = cdc . getTypeInfo_wlock ( info . AminoMarshalReprType ) if err != nil { return } // Then, encode the repr instance. err = cdc . encodeReflectJSON ( w , rinfo , rrv , fopts ) return } switch info . Type . Kind ( ) { //---------------------------------------- // Complex case reflect . Interface : return cdc . encodeReflectJSONInterface ( w , info , rv , fopts ) case reflect . Array , reflect . Slice : return cdc . encodeReflectJSONList ( w , info , rv , fopts ) case reflect . Struct : return cdc . encodeReflectJSONStruct ( w , info , rv , fopts ) case reflect . Map : return cdc . encodeReflectJSONMap ( w , info , rv , fopts ) //---------------------------------------- // Signed, Unsigned case reflect . Int64 , reflect . Int : _ , err = fmt . Fprintf ( w , `"%d"` , rv . Int ( ) ) // JS can't handle int64 return case reflect . Uint64 , reflect . Uint : _ , err = fmt . Fprintf ( w , `"%d"` , rv . Uint ( ) ) // JS can't handle uint64 return case reflect . Int32 , reflect . Int16 , reflect . Int8 , reflect . Uint32 , reflect . Uint16 , reflect . Uint8 : return invokeStdlibJSONMarshal ( w , rv . Interface ( ) ) //---------------------------------------- // Misc case reflect . Float64 , reflect . Float32 : if ! fopts . Unsafe { return errors . New ( " \" \" " ) } fallthrough case reflect . Bool , reflect . String : return invokeStdlibJSONMarshal ( w , rv . Interface ( ) ) //---------------------------------------- // Default default : panic ( fmt . Sprintf ( " " , info . Type . Kind ( ) ) ) } }
//----------------------------------------
// cdc.encodeReflectJSON
// This is the main entrypoint for encoding all types in json form.  This
// function calls encodeReflectJSON*, and generally those functions should
// only call this one, for the disfix wrapper is only written here.
// NOTE: Unlike encodeReflectBinary, rv may be a pointer.
// CONTRACT: rv is valid.
---------------------------------------- cdc . encodeReflectJSON This is the main entrypoint for encoding all types in json form . This function calls encodeReflectJSON * and generally those functions should only call this one for the disfix wrapper is only written here . NOTE : Unlike encodeReflectBinary rv may be a pointer . CONTRACT : rv is valid .