summaryrefslogtreecommitdiff
path: root/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_jsonpb.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_jsonpb.go')
-rw-r--r--vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_jsonpb.go349
1 files changed, 0 insertions, 349 deletions
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_jsonpb.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_jsonpb.go
deleted file mode 100644
index 8376d1e0e..000000000
--- a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_jsonpb.go
+++ /dev/null
@@ -1,349 +0,0 @@
-package runtime
-
-import (
- "bytes"
- "encoding/json"
- "fmt"
- "io"
- "reflect"
- "strconv"
-
- "google.golang.org/protobuf/encoding/protojson"
- "google.golang.org/protobuf/proto"
-)
-
-// JSONPb is a Marshaler which marshals/unmarshals into/from JSON
-// with the "google.golang.org/protobuf/encoding/protojson" marshaler.
-// It supports the full functionality of protobuf unlike JSONBuiltin.
-//
-// The NewDecoder method returns a DecoderWrapper, so the underlying
-// *json.Decoder methods can be used.
-type JSONPb struct {
- protojson.MarshalOptions
- protojson.UnmarshalOptions
-}
-
-// ContentType always returns "application/json".
-func (*JSONPb) ContentType(_ interface{}) string {
- return "application/json"
-}
-
-// Marshal marshals "v" into JSON.
-func (j *JSONPb) Marshal(v interface{}) ([]byte, error) {
- var buf bytes.Buffer
- if err := j.marshalTo(&buf, v); err != nil {
- return nil, err
- }
- return buf.Bytes(), nil
-}
-
-func (j *JSONPb) marshalTo(w io.Writer, v interface{}) error {
- p, ok := v.(proto.Message)
- if !ok {
- buf, err := j.marshalNonProtoField(v)
- if err != nil {
- return err
- }
- if j.Indent != "" {
- b := &bytes.Buffer{}
- if err := json.Indent(b, buf, "", j.Indent); err != nil {
- return err
- }
- buf = b.Bytes()
- }
- _, err = w.Write(buf)
- return err
- }
-
- b, err := j.MarshalOptions.Marshal(p)
- if err != nil {
- return err
- }
-
- _, err = w.Write(b)
- return err
-}
-
-var (
- // protoMessageType is stored to prevent constant lookup of the same type at runtime.
- protoMessageType = reflect.TypeOf((*proto.Message)(nil)).Elem()
-)
-
-// marshalNonProto marshals a non-message field of a protobuf message.
-// This function does not correctly marshal arbitrary data structures into JSON,
-// it is only capable of marshaling non-message field values of protobuf,
-// i.e. primitive types, enums; pointers to primitives or enums; maps from
-// integer/string types to primitives/enums/pointers to messages.
-func (j *JSONPb) marshalNonProtoField(v interface{}) ([]byte, error) {
- if v == nil {
- return []byte("null"), nil
- }
- rv := reflect.ValueOf(v)
- for rv.Kind() == reflect.Ptr {
- if rv.IsNil() {
- return []byte("null"), nil
- }
- rv = rv.Elem()
- }
-
- if rv.Kind() == reflect.Slice {
- if rv.IsNil() {
- if j.EmitUnpopulated {
- return []byte("[]"), nil
- }
- return []byte("null"), nil
- }
-
- if rv.Type().Elem().Implements(protoMessageType) {
- var buf bytes.Buffer
- if err := buf.WriteByte('['); err != nil {
- return nil, err
- }
- for i := 0; i < rv.Len(); i++ {
- if i != 0 {
- if err := buf.WriteByte(','); err != nil {
- return nil, err
- }
- }
- if err := j.marshalTo(&buf, rv.Index(i).Interface().(proto.Message)); err != nil {
- return nil, err
- }
- }
- if err := buf.WriteByte(']'); err != nil {
- return nil, err
- }
-
- return buf.Bytes(), nil
- }
-
- if rv.Type().Elem().Implements(typeProtoEnum) {
- var buf bytes.Buffer
- if err := buf.WriteByte('['); err != nil {
- return nil, err
- }
- for i := 0; i < rv.Len(); i++ {
- if i != 0 {
- if err := buf.WriteByte(','); err != nil {
- return nil, err
- }
- }
- var err error
- if j.UseEnumNumbers {
- _, err = buf.WriteString(strconv.FormatInt(rv.Index(i).Int(), 10))
- } else {
- _, err = buf.WriteString("\"" + rv.Index(i).Interface().(protoEnum).String() + "\"")
- }
- if err != nil {
- return nil, err
- }
- }
- if err := buf.WriteByte(']'); err != nil {
- return nil, err
- }
-
- return buf.Bytes(), nil
- }
- }
-
- if rv.Kind() == reflect.Map {
- m := make(map[string]*json.RawMessage)
- for _, k := range rv.MapKeys() {
- buf, err := j.Marshal(rv.MapIndex(k).Interface())
- if err != nil {
- return nil, err
- }
- m[fmt.Sprintf("%v", k.Interface())] = (*json.RawMessage)(&buf)
- }
- return json.Marshal(m)
- }
- if enum, ok := rv.Interface().(protoEnum); ok && !j.UseEnumNumbers {
- return json.Marshal(enum.String())
- }
- return json.Marshal(rv.Interface())
-}
-
-// Unmarshal unmarshals JSON "data" into "v"
-func (j *JSONPb) Unmarshal(data []byte, v interface{}) error {
- return unmarshalJSONPb(data, j.UnmarshalOptions, v)
-}
-
-// NewDecoder returns a Decoder which reads JSON stream from "r".
-func (j *JSONPb) NewDecoder(r io.Reader) Decoder {
- d := json.NewDecoder(r)
- return DecoderWrapper{
- Decoder: d,
- UnmarshalOptions: j.UnmarshalOptions,
- }
-}
-
-// DecoderWrapper is a wrapper around a *json.Decoder that adds
-// support for protos to the Decode method.
-type DecoderWrapper struct {
- *json.Decoder
- protojson.UnmarshalOptions
-}
-
-// Decode wraps the embedded decoder's Decode method to support
-// protos using a jsonpb.Unmarshaler.
-func (d DecoderWrapper) Decode(v interface{}) error {
- return decodeJSONPb(d.Decoder, d.UnmarshalOptions, v)
-}
-
-// NewEncoder returns an Encoder which writes JSON stream into "w".
-func (j *JSONPb) NewEncoder(w io.Writer) Encoder {
- return EncoderFunc(func(v interface{}) error {
- if err := j.marshalTo(w, v); err != nil {
- return err
- }
- // mimic json.Encoder by adding a newline (makes output
- // easier to read when it contains multiple encoded items)
- _, err := w.Write(j.Delimiter())
- return err
- })
-}
-
-func unmarshalJSONPb(data []byte, unmarshaler protojson.UnmarshalOptions, v interface{}) error {
- d := json.NewDecoder(bytes.NewReader(data))
- return decodeJSONPb(d, unmarshaler, v)
-}
-
-func decodeJSONPb(d *json.Decoder, unmarshaler protojson.UnmarshalOptions, v interface{}) error {
- p, ok := v.(proto.Message)
- if !ok {
- return decodeNonProtoField(d, unmarshaler, v)
- }
-
- // Decode into bytes for marshalling
- var b json.RawMessage
- if err := d.Decode(&b); err != nil {
- return err
- }
-
- return unmarshaler.Unmarshal([]byte(b), p)
-}
-
-func decodeNonProtoField(d *json.Decoder, unmarshaler protojson.UnmarshalOptions, v interface{}) error {
- rv := reflect.ValueOf(v)
- if rv.Kind() != reflect.Ptr {
- return fmt.Errorf("%T is not a pointer", v)
- }
- for rv.Kind() == reflect.Ptr {
- if rv.IsNil() {
- rv.Set(reflect.New(rv.Type().Elem()))
- }
- if rv.Type().ConvertibleTo(typeProtoMessage) {
- // Decode into bytes for marshalling
- var b json.RawMessage
- if err := d.Decode(&b); err != nil {
- return err
- }
-
- return unmarshaler.Unmarshal([]byte(b), rv.Interface().(proto.Message))
- }
- rv = rv.Elem()
- }
- if rv.Kind() == reflect.Map {
- if rv.IsNil() {
- rv.Set(reflect.MakeMap(rv.Type()))
- }
- conv, ok := convFromType[rv.Type().Key().Kind()]
- if !ok {
- return fmt.Errorf("unsupported type of map field key: %v", rv.Type().Key())
- }
-
- m := make(map[string]*json.RawMessage)
- if err := d.Decode(&m); err != nil {
- return err
- }
- for k, v := range m {
- result := conv.Call([]reflect.Value{reflect.ValueOf(k)})
- if err := result[1].Interface(); err != nil {
- return err.(error)
- }
- bk := result[0]
- bv := reflect.New(rv.Type().Elem())
- if v == nil {
- null := json.RawMessage("null")
- v = &null
- }
- if err := unmarshalJSONPb([]byte(*v), unmarshaler, bv.Interface()); err != nil {
- return err
- }
- rv.SetMapIndex(bk, bv.Elem())
- }
- return nil
- }
- if rv.Kind() == reflect.Slice {
- if rv.Type().Elem().Kind() == reflect.Uint8 {
- var sl []byte
- if err := d.Decode(&sl); err != nil {
- return err
- }
- if sl != nil {
- rv.SetBytes(sl)
- }
- return nil
- }
-
- var sl []json.RawMessage
- if err := d.Decode(&sl); err != nil {
- return err
- }
- if sl != nil {
- rv.Set(reflect.MakeSlice(rv.Type(), 0, 0))
- }
- for _, item := range sl {
- bv := reflect.New(rv.Type().Elem())
- if err := unmarshalJSONPb([]byte(item), unmarshaler, bv.Interface()); err != nil {
- return err
- }
- rv.Set(reflect.Append(rv, bv.Elem()))
- }
- return nil
- }
- if _, ok := rv.Interface().(protoEnum); ok {
- var repr interface{}
- if err := d.Decode(&repr); err != nil {
- return err
- }
- switch v := repr.(type) {
- case string:
- // TODO(yugui) Should use proto.StructProperties?
- return fmt.Errorf("unmarshaling of symbolic enum %q not supported: %T", repr, rv.Interface())
- case float64:
- rv.Set(reflect.ValueOf(int32(v)).Convert(rv.Type()))
- return nil
- default:
- return fmt.Errorf("cannot assign %#v into Go type %T", repr, rv.Interface())
- }
- }
- return d.Decode(v)
-}
-
-type protoEnum interface {
- fmt.Stringer
- EnumDescriptor() ([]byte, []int)
-}
-
-var typeProtoEnum = reflect.TypeOf((*protoEnum)(nil)).Elem()
-
-var typeProtoMessage = reflect.TypeOf((*proto.Message)(nil)).Elem()
-
-// Delimiter for newline encoded JSON streams.
-func (j *JSONPb) Delimiter() []byte {
- return []byte("\n")
-}
-
-var (
- convFromType = map[reflect.Kind]reflect.Value{
- reflect.String: reflect.ValueOf(String),
- reflect.Bool: reflect.ValueOf(Bool),
- reflect.Float64: reflect.ValueOf(Float64),
- reflect.Float32: reflect.ValueOf(Float32),
- reflect.Int64: reflect.ValueOf(Int64),
- reflect.Int32: reflect.ValueOf(Int32),
- reflect.Uint64: reflect.ValueOf(Uint64),
- reflect.Uint32: reflect.ValueOf(Uint32),
- reflect.Slice: reflect.ValueOf(Bytes),
- }
-)