1 package runtime
2
3 import (
4 "bytes"
5 "encoding/json"
6 "fmt"
7 "io"
8 "reflect"
9 "strconv"
10
11 "google.golang.org/protobuf/encoding/protojson"
12 "google.golang.org/protobuf/proto"
13 )
14
15
16
17
18
19
20
21 type JSONPb struct {
22 protojson.MarshalOptions
23 protojson.UnmarshalOptions
24 }
25
26
27 func (*JSONPb) ContentType(_ interface{}) string {
28 return "application/json"
29 }
30
31
32 func (j *JSONPb) Marshal(v interface{}) ([]byte, error) {
33 if _, ok := v.(proto.Message); !ok {
34 return j.marshalNonProtoField(v)
35 }
36
37 var buf bytes.Buffer
38 if err := j.marshalTo(&buf, v); err != nil {
39 return nil, err
40 }
41 return buf.Bytes(), nil
42 }
43
44 func (j *JSONPb) marshalTo(w io.Writer, v interface{}) error {
45 p, ok := v.(proto.Message)
46 if !ok {
47 buf, err := j.marshalNonProtoField(v)
48 if err != nil {
49 return err
50 }
51 _, err = w.Write(buf)
52 return err
53 }
54 b, err := j.MarshalOptions.Marshal(p)
55 if err != nil {
56 return err
57 }
58
59 _, err = w.Write(b)
60 return err
61 }
62
63 var (
64
65 protoMessageType = reflect.TypeOf((*proto.Message)(nil)).Elem()
66 )
67
68
69
70
71
72
73 func (j *JSONPb) marshalNonProtoField(v interface{}) ([]byte, error) {
74 if v == nil {
75 return []byte("null"), nil
76 }
77 rv := reflect.ValueOf(v)
78 for rv.Kind() == reflect.Ptr {
79 if rv.IsNil() {
80 return []byte("null"), nil
81 }
82 rv = rv.Elem()
83 }
84
85 if rv.Kind() == reflect.Slice {
86 if rv.IsNil() {
87 if j.EmitUnpopulated {
88 return []byte("[]"), nil
89 }
90 return []byte("null"), nil
91 }
92
93 if rv.Type().Elem().Implements(protoMessageType) {
94 var buf bytes.Buffer
95 if err := buf.WriteByte('['); err != nil {
96 return nil, err
97 }
98 for i := 0; i < rv.Len(); i++ {
99 if i != 0 {
100 if err := buf.WriteByte(','); err != nil {
101 return nil, err
102 }
103 }
104 if err := j.marshalTo(&buf, rv.Index(i).Interface().(proto.Message)); err != nil {
105 return nil, err
106 }
107 }
108 if err := buf.WriteByte(']'); err != nil {
109 return nil, err
110 }
111
112 return buf.Bytes(), nil
113 }
114
115 if rv.Type().Elem().Implements(typeProtoEnum) {
116 var buf bytes.Buffer
117 if err := buf.WriteByte('['); err != nil {
118 return nil, err
119 }
120 for i := 0; i < rv.Len(); i++ {
121 if i != 0 {
122 if err := buf.WriteByte(','); err != nil {
123 return nil, err
124 }
125 }
126 var err error
127 if j.UseEnumNumbers {
128 _, err = buf.WriteString(strconv.FormatInt(rv.Index(i).Int(), 10))
129 } else {
130 _, err = buf.WriteString("\"" + rv.Index(i).Interface().(protoEnum).String() + "\"")
131 }
132 if err != nil {
133 return nil, err
134 }
135 }
136 if err := buf.WriteByte(']'); err != nil {
137 return nil, err
138 }
139
140 return buf.Bytes(), nil
141 }
142 }
143
144 if rv.Kind() == reflect.Map {
145 m := make(map[string]*json.RawMessage)
146 for _, k := range rv.MapKeys() {
147 buf, err := j.Marshal(rv.MapIndex(k).Interface())
148 if err != nil {
149 return nil, err
150 }
151 m[fmt.Sprintf("%v", k.Interface())] = (*json.RawMessage)(&buf)
152 }
153 if j.Indent != "" {
154 return json.MarshalIndent(m, "", j.Indent)
155 }
156 return json.Marshal(m)
157 }
158 if enum, ok := rv.Interface().(protoEnum); ok && !j.UseEnumNumbers {
159 return json.Marshal(enum.String())
160 }
161 return json.Marshal(rv.Interface())
162 }
163
164
165 func (j *JSONPb) Unmarshal(data []byte, v interface{}) error {
166 return unmarshalJSONPb(data, j.UnmarshalOptions, v)
167 }
168
169
170 func (j *JSONPb) NewDecoder(r io.Reader) Decoder {
171 d := json.NewDecoder(r)
172 return DecoderWrapper{
173 Decoder: d,
174 UnmarshalOptions: j.UnmarshalOptions,
175 }
176 }
177
178
179
180 type DecoderWrapper struct {
181 *json.Decoder
182 protojson.UnmarshalOptions
183 }
184
185
186
187 func (d DecoderWrapper) Decode(v interface{}) error {
188 return decodeJSONPb(d.Decoder, d.UnmarshalOptions, v)
189 }
190
191
192 func (j *JSONPb) NewEncoder(w io.Writer) Encoder {
193 return EncoderFunc(func(v interface{}) error {
194 if err := j.marshalTo(w, v); err != nil {
195 return err
196 }
197
198
199 _, err := w.Write(j.Delimiter())
200 return err
201 })
202 }
203
204 func unmarshalJSONPb(data []byte, unmarshaler protojson.UnmarshalOptions, v interface{}) error {
205 d := json.NewDecoder(bytes.NewReader(data))
206 return decodeJSONPb(d, unmarshaler, v)
207 }
208
209 func decodeJSONPb(d *json.Decoder, unmarshaler protojson.UnmarshalOptions, v interface{}) error {
210 p, ok := v.(proto.Message)
211 if !ok {
212 return decodeNonProtoField(d, unmarshaler, v)
213 }
214
215
216 var b json.RawMessage
217 if err := d.Decode(&b); err != nil {
218 return err
219 }
220
221 return unmarshaler.Unmarshal([]byte(b), p)
222 }
223
224 func decodeNonProtoField(d *json.Decoder, unmarshaler protojson.UnmarshalOptions, v interface{}) error {
225 rv := reflect.ValueOf(v)
226 if rv.Kind() != reflect.Ptr {
227 return fmt.Errorf("%T is not a pointer", v)
228 }
229 for rv.Kind() == reflect.Ptr {
230 if rv.IsNil() {
231 rv.Set(reflect.New(rv.Type().Elem()))
232 }
233 if rv.Type().ConvertibleTo(typeProtoMessage) {
234
235 var b json.RawMessage
236 if err := d.Decode(&b); err != nil {
237 return err
238 }
239
240 return unmarshaler.Unmarshal([]byte(b), rv.Interface().(proto.Message))
241 }
242 rv = rv.Elem()
243 }
244 if rv.Kind() == reflect.Map {
245 if rv.IsNil() {
246 rv.Set(reflect.MakeMap(rv.Type()))
247 }
248 conv, ok := convFromType[rv.Type().Key().Kind()]
249 if !ok {
250 return fmt.Errorf("unsupported type of map field key: %v", rv.Type().Key())
251 }
252
253 m := make(map[string]*json.RawMessage)
254 if err := d.Decode(&m); err != nil {
255 return err
256 }
257 for k, v := range m {
258 result := conv.Call([]reflect.Value{reflect.ValueOf(k)})
259 if err := result[1].Interface(); err != nil {
260 return err.(error)
261 }
262 bk := result[0]
263 bv := reflect.New(rv.Type().Elem())
264 if v == nil {
265 null := json.RawMessage("null")
266 v = &null
267 }
268 if err := unmarshalJSONPb([]byte(*v), unmarshaler, bv.Interface()); err != nil {
269 return err
270 }
271 rv.SetMapIndex(bk, bv.Elem())
272 }
273 return nil
274 }
275 if rv.Kind() == reflect.Slice {
276 if rv.Type().Elem().Kind() == reflect.Uint8 {
277 var sl []byte
278 if err := d.Decode(&sl); err != nil {
279 return err
280 }
281 if sl != nil {
282 rv.SetBytes(sl)
283 }
284 return nil
285 }
286
287 var sl []json.RawMessage
288 if err := d.Decode(&sl); err != nil {
289 return err
290 }
291 if sl != nil {
292 rv.Set(reflect.MakeSlice(rv.Type(), 0, 0))
293 }
294 for _, item := range sl {
295 bv := reflect.New(rv.Type().Elem())
296 if err := unmarshalJSONPb([]byte(item), unmarshaler, bv.Interface()); err != nil {
297 return err
298 }
299 rv.Set(reflect.Append(rv, bv.Elem()))
300 }
301 return nil
302 }
303 if _, ok := rv.Interface().(protoEnum); ok {
304 var repr interface{}
305 if err := d.Decode(&repr); err != nil {
306 return err
307 }
308 switch v := repr.(type) {
309 case string:
310
311 return fmt.Errorf("unmarshaling of symbolic enum %q not supported: %T", repr, rv.Interface())
312 case float64:
313 rv.Set(reflect.ValueOf(int32(v)).Convert(rv.Type()))
314 return nil
315 default:
316 return fmt.Errorf("cannot assign %#v into Go type %T", repr, rv.Interface())
317 }
318 }
319 return d.Decode(v)
320 }
321
322 type protoEnum interface {
323 fmt.Stringer
324 EnumDescriptor() ([]byte, []int)
325 }
326
327 var typeProtoEnum = reflect.TypeOf((*protoEnum)(nil)).Elem()
328
329 var typeProtoMessage = reflect.TypeOf((*proto.Message)(nil)).Elem()
330
331
332 func (j *JSONPb) Delimiter() []byte {
333 return []byte("\n")
334 }
335
336 var (
337 convFromType = map[reflect.Kind]reflect.Value{
338 reflect.String: reflect.ValueOf(String),
339 reflect.Bool: reflect.ValueOf(Bool),
340 reflect.Float64: reflect.ValueOf(Float64),
341 reflect.Float32: reflect.ValueOf(Float32),
342 reflect.Int64: reflect.ValueOf(Int64),
343 reflect.Int32: reflect.ValueOf(Int32),
344 reflect.Uint64: reflect.ValueOf(Uint64),
345 reflect.Uint32: reflect.ValueOf(Uint32),
346 reflect.Slice: reflect.ValueOf(Bytes),
347 }
348 )
349
View as plain text