github.com/annwntech/go-micro/v2@v2.9.5/codec/jsonpb/jsonpb.go (about)

     1  // Package jsonpb provides a json codec
     2  package jsonpb
     3  
     4  import (
     5  	"bytes"
     6  	"io"
     7  	"io/ioutil"
     8  
     9  	// nolint: staticcheck
    10  	oldjsonpb "github.com/golang/protobuf/jsonpb"
    11  	// nolint: staticcheck
    12  	"github.com/annwntech/go-micro/v2/codec"
    13  	bytesCodec "github.com/annwntech/go-micro/v2/codec/bytes"
    14  	oldproto "github.com/golang/protobuf/proto"
    15  	jsonpb "google.golang.org/protobuf/encoding/protojson"
    16  	"google.golang.org/protobuf/proto"
    17  )
    18  
    19  var (
    20  	JsonpbMarshaler = jsonpb.MarshalOptions{
    21  		UseEnumNumbers:  false,
    22  		EmitUnpopulated: false,
    23  		UseProtoNames:   true,
    24  		AllowPartial:    false,
    25  	}
    26  
    27  	JsonpbUnmarshaler = jsonpb.UnmarshalOptions{
    28  		DiscardUnknown: false,
    29  		AllowPartial:   false,
    30  	}
    31  
    32  	OldJsonpbMarshaler = oldjsonpb.Marshaler{
    33  		OrigName:     true,
    34  		EmitDefaults: false,
    35  	}
    36  
    37  	OldJsonpbUnmarshaler = oldjsonpb.Unmarshaler{
    38  		AllowUnknownFields: false,
    39  	}
    40  )
    41  
    42  type jsonpbCodec struct {
    43  	Conn io.ReadWriteCloser
    44  }
    45  
    46  func (c *jsonpbCodec) Marshal(v interface{}) ([]byte, error) {
    47  	switch m := v.(type) {
    48  	case nil:
    49  		return nil, nil
    50  	case *bytesCodec.Frame:
    51  		return m.Data, nil
    52  	case proto.Message:
    53  		return JsonpbMarshaler.Marshal(m)
    54  	case oldproto.Message:
    55  		buf, err := OldJsonpbMarshaler.MarshalToString(m)
    56  		return []byte(buf), err
    57  	}
    58  	return nil, codec.ErrInvalidMessage
    59  }
    60  
    61  func (c *jsonpbCodec) Unmarshal(d []byte, v interface{}) error {
    62  	if d == nil {
    63  		return nil
    64  	}
    65  	switch m := v.(type) {
    66  	case nil:
    67  		return nil
    68  	case *bytesCodec.Frame:
    69  		m.Data = d
    70  		return nil
    71  	case proto.Message:
    72  		return JsonpbUnmarshaler.Unmarshal(d, m)
    73  	case oldproto.Message:
    74  		return OldJsonpbUnmarshaler.Unmarshal(bytes.NewReader(d), m)
    75  	}
    76  	return codec.ErrInvalidMessage
    77  }
    78  func (c *jsonpbCodec) ReadHeader(m *codec.Message, t codec.MessageType) error {
    79  	return nil
    80  }
    81  
    82  func (c *jsonpbCodec) ReadBody(b interface{}) error {
    83  	switch m := b.(type) {
    84  	case nil:
    85  		return nil
    86  	case *bytesCodec.Frame:
    87  		buf, err := ioutil.ReadAll(c.Conn)
    88  		if err != nil {
    89  			return err
    90  		}
    91  		m.Data = buf
    92  		return nil
    93  	case oldproto.Message:
    94  		return OldJsonpbUnmarshaler.Unmarshal(c.Conn, m)
    95  	case proto.Message:
    96  		buf, err := ioutil.ReadAll(c.Conn)
    97  		if err != nil {
    98  			return err
    99  		}
   100  		return JsonpbUnmarshaler.Unmarshal(buf, m)
   101  	}
   102  	return codec.ErrInvalidMessage
   103  }
   104  
   105  func (c *jsonpbCodec) Write(m *codec.Message, b interface{}) error {
   106  	switch m := b.(type) {
   107  	case nil:
   108  		return nil
   109  	case *bytesCodec.Frame:
   110  		_, err := c.Conn.Write(m.Data)
   111  		return err
   112  	case oldproto.Message:
   113  		return OldJsonpbMarshaler.Marshal(c.Conn, m)
   114  	case proto.Message:
   115  		buf, err := JsonpbMarshaler.Marshal(m)
   116  		if err != nil {
   117  			return err
   118  		}
   119  		_, err = c.Conn.Write(buf)
   120  		return err
   121  	}
   122  	return codec.ErrInvalidMessage
   123  }
   124  
   125  func (c *jsonpbCodec) Close() error {
   126  	return c.Conn.Close()
   127  }
   128  
   129  func (c *jsonpbCodec) String() string {
   130  	return "jsonpb"
   131  }
   132  
   133  func NewCodec(c io.ReadWriteCloser) codec.Codec {
   134  	return &jsonpbCodec{
   135  		Conn: c,
   136  	}
   137  }