Code refactoring for bpa operator
[icn.git] / cmd / bpa-operator / vendor / github.com / grpc-ecosystem / grpc-gateway / runtime / marshal_jsonpb.go
1 package runtime
2
3 import (
4         "bytes"
5         "encoding/json"
6         "fmt"
7         "io"
8         "reflect"
9
10         "github.com/golang/protobuf/jsonpb"
11         "github.com/golang/protobuf/proto"
12 )
13
14 // JSONPb is a Marshaler which marshals/unmarshals into/from JSON
15 // with the "github.com/golang/protobuf/jsonpb".
16 // It supports fully functionality of protobuf unlike JSONBuiltin.
17 //
18 // The NewDecoder method returns a DecoderWrapper, so the underlying
19 // *json.Decoder methods can be used.
20 type JSONPb jsonpb.Marshaler
21
22 // ContentType always returns "application/json".
23 func (*JSONPb) ContentType() string {
24         return "application/json"
25 }
26
27 // Marshal marshals "v" into JSON.
28 func (j *JSONPb) Marshal(v interface{}) ([]byte, error) {
29         if _, ok := v.(proto.Message); !ok {
30                 return j.marshalNonProtoField(v)
31         }
32
33         var buf bytes.Buffer
34         if err := j.marshalTo(&buf, v); err != nil {
35                 return nil, err
36         }
37         return buf.Bytes(), nil
38 }
39
40 func (j *JSONPb) marshalTo(w io.Writer, v interface{}) error {
41         p, ok := v.(proto.Message)
42         if !ok {
43                 buf, err := j.marshalNonProtoField(v)
44                 if err != nil {
45                         return err
46                 }
47                 _, err = w.Write(buf)
48                 return err
49         }
50         return (*jsonpb.Marshaler)(j).Marshal(w, p)
51 }
52
53 var (
54         // protoMessageType is stored to prevent constant lookup of the same type at runtime.
55         protoMessageType = reflect.TypeOf((*proto.Message)(nil)).Elem()
56 )
57
58 // marshalNonProto marshals a non-message field of a protobuf message.
59 // This function does not correctly marshals arbitrary data structure into JSON,
60 // but it is only capable of marshaling non-message field values of protobuf,
61 // i.e. primitive types, enums; pointers to primitives or enums; maps from
62 // integer/string types to primitives/enums/pointers to messages.
63 func (j *JSONPb) marshalNonProtoField(v interface{}) ([]byte, error) {
64         if v == nil {
65                 return []byte("null"), nil
66         }
67         rv := reflect.ValueOf(v)
68         for rv.Kind() == reflect.Ptr {
69                 if rv.IsNil() {
70                         return []byte("null"), nil
71                 }
72                 rv = rv.Elem()
73         }
74
75         if rv.Kind() == reflect.Slice {
76                 if rv.IsNil() {
77                         if j.EmitDefaults {
78                                 return []byte("[]"), nil
79                         }
80                         return []byte("null"), nil
81                 }
82
83                 if rv.Type().Elem().Implements(protoMessageType) {
84                         var buf bytes.Buffer
85                         err := buf.WriteByte('[')
86                         if err != nil {
87                                 return nil, err
88                         }
89                         for i := 0; i < rv.Len(); i++ {
90                                 if i != 0 {
91                                         err = buf.WriteByte(',')
92                                         if err != nil {
93                                                 return nil, err
94                                         }
95                                 }
96                                 if err = (*jsonpb.Marshaler)(j).Marshal(&buf, rv.Index(i).Interface().(proto.Message)); err != nil {
97                                         return nil, err
98                                 }
99                         }
100                         err = buf.WriteByte(']')
101                         if err != nil {
102                                 return nil, err
103                         }
104
105                         return buf.Bytes(), nil
106                 }
107         }
108
109         if rv.Kind() == reflect.Map {
110                 m := make(map[string]*json.RawMessage)
111                 for _, k := range rv.MapKeys() {
112                         buf, err := j.Marshal(rv.MapIndex(k).Interface())
113                         if err != nil {
114                                 return nil, err
115                         }
116                         m[fmt.Sprintf("%v", k.Interface())] = (*json.RawMessage)(&buf)
117                 }
118                 if j.Indent != "" {
119                         return json.MarshalIndent(m, "", j.Indent)
120                 }
121                 return json.Marshal(m)
122         }
123         if enum, ok := rv.Interface().(protoEnum); ok && !j.EnumsAsInts {
124                 return json.Marshal(enum.String())
125         }
126         return json.Marshal(rv.Interface())
127 }
128
129 // Unmarshal unmarshals JSON "data" into "v"
130 func (j *JSONPb) Unmarshal(data []byte, v interface{}) error {
131         return unmarshalJSONPb(data, v)
132 }
133
134 // NewDecoder returns a Decoder which reads JSON stream from "r".
135 func (j *JSONPb) NewDecoder(r io.Reader) Decoder {
136         d := json.NewDecoder(r)
137         return DecoderWrapper{Decoder: d}
138 }
139
140 // DecoderWrapper is a wrapper around a *json.Decoder that adds
141 // support for protos to the Decode method.
142 type DecoderWrapper struct {
143         *json.Decoder
144 }
145
146 // Decode wraps the embedded decoder's Decode method to support
147 // protos using a jsonpb.Unmarshaler.
148 func (d DecoderWrapper) Decode(v interface{}) error {
149         return decodeJSONPb(d.Decoder, v)
150 }
151
152 // NewEncoder returns an Encoder which writes JSON stream into "w".
153 func (j *JSONPb) NewEncoder(w io.Writer) Encoder {
154         return EncoderFunc(func(v interface{}) error { return j.marshalTo(w, v) })
155 }
156
157 func unmarshalJSONPb(data []byte, v interface{}) error {
158         d := json.NewDecoder(bytes.NewReader(data))
159         return decodeJSONPb(d, v)
160 }
161
162 func decodeJSONPb(d *json.Decoder, v interface{}) error {
163         p, ok := v.(proto.Message)
164         if !ok {
165                 return decodeNonProtoField(d, v)
166         }
167         unmarshaler := &jsonpb.Unmarshaler{AllowUnknownFields: true}
168         return unmarshaler.UnmarshalNext(d, p)
169 }
170
171 func decodeNonProtoField(d *json.Decoder, v interface{}) error {
172         rv := reflect.ValueOf(v)
173         if rv.Kind() != reflect.Ptr {
174                 return fmt.Errorf("%T is not a pointer", v)
175         }
176         for rv.Kind() == reflect.Ptr {
177                 if rv.IsNil() {
178                         rv.Set(reflect.New(rv.Type().Elem()))
179                 }
180                 if rv.Type().ConvertibleTo(typeProtoMessage) {
181                         unmarshaler := &jsonpb.Unmarshaler{AllowUnknownFields: true}
182                         return unmarshaler.UnmarshalNext(d, rv.Interface().(proto.Message))
183                 }
184                 rv = rv.Elem()
185         }
186         if rv.Kind() == reflect.Map {
187                 if rv.IsNil() {
188                         rv.Set(reflect.MakeMap(rv.Type()))
189                 }
190                 conv, ok := convFromType[rv.Type().Key().Kind()]
191                 if !ok {
192                         return fmt.Errorf("unsupported type of map field key: %v", rv.Type().Key())
193                 }
194
195                 m := make(map[string]*json.RawMessage)
196                 if err := d.Decode(&m); err != nil {
197                         return err
198                 }
199                 for k, v := range m {
200                         result := conv.Call([]reflect.Value{reflect.ValueOf(k)})
201                         if err := result[1].Interface(); err != nil {
202                                 return err.(error)
203                         }
204                         bk := result[0]
205                         bv := reflect.New(rv.Type().Elem())
206                         if err := unmarshalJSONPb([]byte(*v), bv.Interface()); err != nil {
207                                 return err
208                         }
209                         rv.SetMapIndex(bk, bv.Elem())
210                 }
211                 return nil
212         }
213         if _, ok := rv.Interface().(protoEnum); ok {
214                 var repr interface{}
215                 if err := d.Decode(&repr); err != nil {
216                         return err
217                 }
218                 switch repr.(type) {
219                 case string:
220                         // TODO(yugui) Should use proto.StructProperties?
221                         return fmt.Errorf("unmarshaling of symbolic enum %q not supported: %T", repr, rv.Interface())
222                 case float64:
223                         rv.Set(reflect.ValueOf(int32(repr.(float64))).Convert(rv.Type()))
224                         return nil
225                 default:
226                         return fmt.Errorf("cannot assign %#v into Go type %T", repr, rv.Interface())
227                 }
228         }
229         return d.Decode(v)
230 }
231
232 type protoEnum interface {
233         fmt.Stringer
234         EnumDescriptor() ([]byte, []int)
235 }
236
237 var typeProtoMessage = reflect.TypeOf((*proto.Message)(nil)).Elem()
238
239 // Delimiter for newline encoded JSON streams.
240 func (j *JSONPb) Delimiter() []byte {
241         return []byte("\n")
242 }