1
2
3
4
5 package json
6
7 import (
8 "encoding"
9 "errors"
10 "reflect"
11 )
12
13
14 var (
15 jsonMarshalerV1Type = reflect.TypeOf((*MarshalerV1)(nil)).Elem()
16 jsonMarshalerV2Type = reflect.TypeOf((*MarshalerV2)(nil)).Elem()
17 jsonUnmarshalerV1Type = reflect.TypeOf((*UnmarshalerV1)(nil)).Elem()
18 jsonUnmarshalerV2Type = reflect.TypeOf((*UnmarshalerV2)(nil)).Elem()
19 textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
20 textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
21 )
22
23
24
25
26
27
28
29 type MarshalerV1 interface {
30 MarshalJSON() ([]byte, error)
31 }
32
33
34
35
36
37
38
39
40
41
42 type MarshalerV2 interface {
43 MarshalNextJSON(MarshalOptions, *Encoder) error
44
45
46
47 }
48
49
50
51
52
53
54
55
56
57
58
59
60 type UnmarshalerV1 interface {
61 UnmarshalJSON([]byte) error
62 }
63
64
65
66
67
68
69
70
71
72
73
74
75
76 type UnmarshalerV2 interface {
77 UnmarshalNextJSON(UnmarshalOptions, *Decoder) error
78
79
80
81 }
82
83 func makeMethodArshaler(fncs *arshaler, t reflect.Type) *arshaler {
84
85
86
87 if t.Kind() == reflect.Pointer || t.Kind() == reflect.Interface {
88 return fncs
89 }
90
91
92 switch which, needAddr := implementsWhich(t, jsonMarshalerV2Type, jsonMarshalerV1Type, textMarshalerType); which {
93 case jsonMarshalerV2Type:
94 fncs.nonDefault = true
95 fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error {
96 prevDepth, prevLength := enc.tokens.depthLength()
97 err := va.addrWhen(needAddr).Interface().(MarshalerV2).MarshalNextJSON(mo, enc)
98 currDepth, currLength := enc.tokens.depthLength()
99 if (prevDepth != currDepth || prevLength+1 != currLength) && err == nil {
100 err = errors.New("must write exactly one JSON value")
101 }
102 if err != nil {
103 err = wrapSkipFunc(err, "marshal method")
104
105 return &SemanticError{action: "marshal", GoType: t, Err: err}
106 }
107 return nil
108 }
109 case jsonMarshalerV1Type:
110 fncs.nonDefault = true
111 fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error {
112 marshaler := va.addrWhen(needAddr).Interface().(MarshalerV1)
113 val, err := marshaler.MarshalJSON()
114 if err != nil {
115 err = wrapSkipFunc(err, "marshal method")
116
117 return &SemanticError{action: "marshal", GoType: t, Err: err}
118 }
119 if err := enc.WriteValue(val); err != nil {
120
121 return &SemanticError{action: "marshal", JSONKind: RawValue(val).Kind(), GoType: t, Err: err}
122 }
123 return nil
124 }
125 case textMarshalerType:
126 fncs.nonDefault = true
127 fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error {
128 marshaler := va.addrWhen(needAddr).Interface().(encoding.TextMarshaler)
129 s, err := marshaler.MarshalText()
130 if err != nil {
131 err = wrapSkipFunc(err, "marshal method")
132
133 return &SemanticError{action: "marshal", JSONKind: '"', GoType: t, Err: err}
134 }
135 val := enc.UnusedBuffer()
136 val, err = appendString(val, string(s), true, nil)
137 if err != nil {
138 return &SemanticError{action: "marshal", JSONKind: '"', GoType: t, Err: err}
139 }
140 if err := enc.WriteValue(val); err != nil {
141
142 return &SemanticError{action: "marshal", JSONKind: '"', GoType: t, Err: err}
143 }
144 return nil
145 }
146 }
147
148
149 switch which, needAddr := implementsWhich(t, jsonUnmarshalerV2Type, jsonUnmarshalerV1Type, textUnmarshalerType); which {
150 case jsonUnmarshalerV2Type:
151 fncs.nonDefault = true
152 fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error {
153 prevDepth, prevLength := dec.tokens.depthLength()
154 err := va.addrWhen(needAddr).Interface().(UnmarshalerV2).UnmarshalNextJSON(uo, dec)
155 currDepth, currLength := dec.tokens.depthLength()
156 if (prevDepth != currDepth || prevLength+1 != currLength) && err == nil {
157 err = errors.New("must read exactly one JSON value")
158 }
159 if err != nil {
160 err = wrapSkipFunc(err, "unmarshal method")
161
162 return &SemanticError{action: "unmarshal", GoType: t, Err: err}
163 }
164 return nil
165 }
166 case jsonUnmarshalerV1Type:
167 fncs.nonDefault = true
168 fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error {
169 val, err := dec.ReadValue()
170 if err != nil {
171 return err
172 }
173 unmarshaler := va.addrWhen(needAddr).Interface().(UnmarshalerV1)
174 if err := unmarshaler.UnmarshalJSON(val); err != nil {
175 err = wrapSkipFunc(err, "unmarshal method")
176
177 return &SemanticError{action: "unmarshal", JSONKind: val.Kind(), GoType: t, Err: err}
178 }
179 return nil
180 }
181 case textUnmarshalerType:
182 fncs.nonDefault = true
183 fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error {
184 var flags valueFlags
185 val, err := dec.readValue(&flags)
186 if err != nil {
187 return err
188 }
189 if val.Kind() != '"' {
190 err = errors.New("JSON value must be string type")
191 return &SemanticError{action: "unmarshal", JSONKind: val.Kind(), GoType: t, Err: err}
192 }
193 s := unescapeStringMayCopy(val, flags.isVerbatim())
194 unmarshaler := va.addrWhen(needAddr).Interface().(encoding.TextUnmarshaler)
195 if err := unmarshaler.UnmarshalText(s); err != nil {
196 err = wrapSkipFunc(err, "unmarshal method")
197
198 return &SemanticError{action: "unmarshal", JSONKind: val.Kind(), GoType: t, Err: err}
199 }
200 return nil
201 }
202 }
203
204 return fncs
205 }
206
207
208
209
210
211 func implementsWhich(t reflect.Type, ifaceTypes ...reflect.Type) (which reflect.Type, needAddr bool) {
212 for _, ifaceType := range ifaceTypes {
213 switch {
214 case t.Implements(ifaceType):
215 return ifaceType, false
216 case reflect.PointerTo(t).Implements(ifaceType):
217 return ifaceType, true
218 }
219 }
220 return nil, false
221 }
222
223
224 func (va addressableValue) addrWhen(addr bool) reflect.Value {
225 if addr {
226 return va.Addr()
227 }
228 return va.Value
229 }
230
View as plain text