Merge PR #5491: Protobuf Introduction + Types

This commit is contained in:
Alexander Bezobchuk
2020-01-24 10:32:00 -05:00
committed by GitHub
parent f0912047cd
commit 26d6e49d6a
34 changed files with 2826 additions and 398 deletions
+70
View File
@@ -0,0 +1,70 @@
package codec
import (
"bytes"
"encoding/json"
"fmt"
amino "github.com/tendermint/go-amino"
cryptoamino "github.com/tendermint/tendermint/crypto/encoding/amino"
tmtypes "github.com/tendermint/tendermint/types"
)
// Cdc defines a global generic sealed Amino codec to be used throughout sdk. It
// has all Tendermint crypto and evidence types registered.
//
// TODO: Consider removing this global.
var Cdc *Codec
func init() {
cdc := New()
RegisterCrypto(cdc)
RegisterEvidences(cdc)
Cdc = cdc.Seal()
}
// Codec defines a type alias for an Amino codec.
type Codec = amino.Codec
func New() *Codec {
return amino.NewCodec()
}
// RegisterCrypto registers all crypto dependency types with the provided Amino
// codec.
func RegisterCrypto(cdc *Codec) {
cryptoamino.RegisterAmino(cdc)
}
// RegisterEvidences registers Tendermint evidence types with the provided Amino
// codec.
func RegisterEvidences(cdc *Codec) {
tmtypes.RegisterEvidences(cdc)
}
// MarshalJSONIndent provides a utility for indented JSON encoding of an object
// via an Amino codec. It returns an error if it cannot serialize or indent as
// JSON.
func MarshalJSONIndent(cdc *Codec, obj interface{}) ([]byte, error) {
bz, err := cdc.MarshalJSON(obj)
if err != nil {
return nil, err
}
var out bytes.Buffer
if err = json.Indent(&out, bz, "", " "); err != nil {
return nil, err
}
return out.Bytes(), nil
}
// MustMarshalJSONIndent executes MarshalJSONIndent except it panics upon failure.
func MustMarshalJSONIndent(cdc *Codec, obj interface{}) []byte {
bz, err := MarshalJSONIndent(cdc, obj)
if err != nil {
panic(fmt.Sprintf("failed to marshal JSON: %s", err))
}
return bz
}
+59
View File
@@ -0,0 +1,59 @@
package codec
// AminoCodec defines a codec that utilizes Amino for both binary and JSON
// encoding.
type AminoCodec struct {
amino *Codec
}
func NewAminoCodec(amino *Codec) Marshaler {
return &AminoCodec{amino}
}
func (ac *AminoCodec) MarshalBinaryBare(o ProtoMarshaler) ([]byte, error) {
return ac.amino.MarshalBinaryBare(o)
}
func (ac *AminoCodec) MustMarshalBinaryBare(o ProtoMarshaler) []byte {
return ac.amino.MustMarshalBinaryBare(o)
}
func (ac *AminoCodec) MarshalBinaryLengthPrefixed(o ProtoMarshaler) ([]byte, error) {
return ac.amino.MarshalBinaryLengthPrefixed(o)
}
func (ac *AminoCodec) MustMarshalBinaryLengthPrefixed(o ProtoMarshaler) []byte {
return ac.amino.MustMarshalBinaryLengthPrefixed(o)
}
func (ac *AminoCodec) UnmarshalBinaryBare(bz []byte, ptr ProtoMarshaler) error {
return ac.amino.UnmarshalBinaryBare(bz, ptr)
}
func (ac *AminoCodec) MustUnmarshalBinaryBare(bz []byte, ptr ProtoMarshaler) {
ac.amino.MustUnmarshalBinaryBare(bz, ptr)
}
func (ac *AminoCodec) UnmarshalBinaryLengthPrefixed(bz []byte, ptr ProtoMarshaler) error {
return ac.amino.UnmarshalBinaryLengthPrefixed(bz, ptr)
}
func (ac *AminoCodec) MustUnmarshalBinaryLengthPrefixed(bz []byte, ptr ProtoMarshaler) {
ac.amino.MustUnmarshalBinaryLengthPrefixed(bz, ptr)
}
func (ac *AminoCodec) MarshalJSON(o interface{}) ([]byte, error) { // nolint: stdmethods
return ac.amino.MarshalJSON(o)
}
func (ac *AminoCodec) MustMarshalJSON(o interface{}) []byte {
return ac.amino.MustMarshalJSON(o)
}
func (ac *AminoCodec) UnmarshalJSON(bz []byte, ptr interface{}) error { // nolint: stdmethods
return ac.amino.UnmarshalJSON(bz, ptr)
}
func (ac *AminoCodec) MustUnmarshalJSON(bz []byte, ptr interface{}) {
ac.amino.MustUnmarshalJSON(bz, ptr)
}
+118
View File
@@ -0,0 +1,118 @@
package codec_test
import (
"testing"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/testdata"
"github.com/stretchr/testify/require"
amino "github.com/tendermint/go-amino"
)
func createTestCodec() *amino.Codec {
cdc := amino.NewCodec()
cdc.RegisterInterface((*testdata.Animal)(nil), nil)
cdc.RegisterConcrete(testdata.Dog{}, "testdata/Dog", nil)
cdc.RegisterConcrete(testdata.Cat{}, "testdata/Cat", nil)
return cdc
}
func TestAminoCodec(t *testing.T) {
testCases := []struct {
name string
codec codec.Marshaler
input codec.ProtoMarshaler
recv codec.ProtoMarshaler
marshalErr bool
unmarshalErr bool
}{
{
"valid encoding and decoding",
codec.NewAminoCodec(createTestCodec()),
&testdata.Dog{Name: "rufus"},
&testdata.Dog{},
false,
false,
},
{
"invalid decode type",
codec.NewAminoCodec(createTestCodec()),
&testdata.Dog{Name: "rufus"},
&testdata.Cat{},
false,
true,
},
}
for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
bz, err := tc.codec.MarshalBinaryBare(tc.input)
if tc.marshalErr {
require.Error(t, err)
require.Panics(t, func() { tc.codec.MustMarshalBinaryBare(tc.input) })
} else {
var bz2 []byte
require.NoError(t, err)
require.NotPanics(t, func() { bz2 = tc.codec.MustMarshalBinaryBare(tc.input) })
require.Equal(t, bz, bz2)
err := tc.codec.UnmarshalBinaryBare(bz, tc.recv)
if tc.unmarshalErr {
require.Error(t, err)
require.Panics(t, func() { tc.codec.MustUnmarshalBinaryBare(bz, tc.recv) })
} else {
require.NoError(t, err)
require.NotPanics(t, func() { tc.codec.MustUnmarshalBinaryBare(bz, tc.recv) })
require.Equal(t, tc.input, tc.recv)
}
}
bz, err = tc.codec.MarshalBinaryLengthPrefixed(tc.input)
if tc.marshalErr {
require.Error(t, err)
require.Panics(t, func() { tc.codec.MustMarshalBinaryLengthPrefixed(tc.input) })
} else {
var bz2 []byte
require.NoError(t, err)
require.NotPanics(t, func() { bz2 = tc.codec.MustMarshalBinaryLengthPrefixed(tc.input) })
require.Equal(t, bz, bz2)
err := tc.codec.UnmarshalBinaryLengthPrefixed(bz, tc.recv)
if tc.unmarshalErr {
require.Error(t, err)
require.Panics(t, func() { tc.codec.MustUnmarshalBinaryLengthPrefixed(bz, tc.recv) })
} else {
require.NoError(t, err)
require.NotPanics(t, func() { tc.codec.MustUnmarshalBinaryLengthPrefixed(bz, tc.recv) })
require.Equal(t, tc.input, tc.recv)
}
}
bz, err = tc.codec.MarshalJSON(tc.input)
if tc.marshalErr {
require.Error(t, err)
require.Panics(t, func() { tc.codec.MustMarshalJSON(tc.input) })
} else {
var bz2 []byte
require.NoError(t, err)
require.NotPanics(t, func() { bz2 = tc.codec.MustMarshalJSON(tc.input) })
require.Equal(t, bz, bz2)
err := tc.codec.UnmarshalJSON(bz, tc.recv)
if tc.unmarshalErr {
require.Error(t, err)
require.Panics(t, func() { tc.codec.MustUnmarshalJSON(bz, tc.recv) })
} else {
require.NoError(t, err)
require.NotPanics(t, func() { tc.codec.MustUnmarshalJSON(bz, tc.recv) })
require.Equal(t, tc.input, tc.recv)
}
}
})
}
}
+43 -48
View File
@@ -1,65 +1,60 @@
package codec
import (
"bytes"
"encoding/json"
"fmt"
"encoding/binary"
"io"
amino "github.com/tendermint/go-amino"
cryptoamino "github.com/tendermint/tendermint/crypto/encoding/amino"
tmtypes "github.com/tendermint/tendermint/types"
"github.com/gogo/protobuf/proto"
)
// amino codec to marshal/unmarshal
type Codec = amino.Codec
type (
// Marshaler defines the interface module codecs must implement in order to support
// backwards compatibility with Amino while allowing custom Protobuf-based
// serialization. Note, Amino can still be used without any dependency on
// Protobuf. There are three typical implementations that fulfill this contract:
//
// 1. AminoCodec: Provides full Amino serialization compatibility.
// 2. ProtoCodec: Provides full Protobuf serialization compatibility.
// 3. HybridCodec: Provides Protobuf serialization for binary encoding and Amino
// for JSON encoding.
Marshaler interface {
MarshalBinaryBare(o ProtoMarshaler) ([]byte, error)
MustMarshalBinaryBare(o ProtoMarshaler) []byte
func New() *Codec {
return amino.NewCodec()
}
MarshalBinaryLengthPrefixed(o ProtoMarshaler) ([]byte, error)
MustMarshalBinaryLengthPrefixed(o ProtoMarshaler) []byte
// Register the go-crypto to the codec
func RegisterCrypto(cdc *Codec) {
cryptoamino.RegisterAmino(cdc)
}
UnmarshalBinaryBare(bz []byte, ptr ProtoMarshaler) error
MustUnmarshalBinaryBare(bz []byte, ptr ProtoMarshaler)
// RegisterEvidences registers Tendermint evidence types with the provided codec.
func RegisterEvidences(cdc *Codec) {
tmtypes.RegisterEvidences(cdc)
}
UnmarshalBinaryLengthPrefixed(bz []byte, ptr ProtoMarshaler) error
MustUnmarshalBinaryLengthPrefixed(bz []byte, ptr ProtoMarshaler)
// attempt to make some pretty json
func MarshalJSONIndent(cdc *Codec, obj interface{}) ([]byte, error) {
bz, err := cdc.MarshalJSON(obj)
if err != nil {
return nil, err
MarshalJSON(o interface{}) ([]byte, error) // nolint: stdmethods
MustMarshalJSON(o interface{}) []byte
UnmarshalJSON(bz []byte, ptr interface{}) error // nolint: stdmethods
MustUnmarshalJSON(bz []byte, ptr interface{})
}
var out bytes.Buffer
err = json.Indent(&out, bz, "", " ")
if err != nil {
return nil, err
// ProtoMarshaler defines an interface a type must implement as protocol buffer
// defined message.
ProtoMarshaler interface {
proto.Message // for JSON serialization
Marshal() ([]byte, error)
MarshalTo(data []byte) (n int, err error)
MarshalToSizedBuffer(dAtA []byte) (int, error)
Size() int
Unmarshal(data []byte) error
}
return out.Bytes(), nil
}
)
// MustMarshalJSONIndent executes MarshalJSONIndent except it panics upon failure.
func MustMarshalJSONIndent(cdc *Codec, obj interface{}) []byte {
bz, err := MarshalJSONIndent(cdc, obj)
if err != nil {
panic(fmt.Sprintf("failed to marshal JSON: %s", err))
}
func encodeUvarint(w io.Writer, u uint64) (err error) {
var buf [10]byte
return bz
}
n := binary.PutUvarint(buf[:], u)
_, err = w.Write(buf[0:n])
//__________________________________________________________________
// generic sealed codec to be used throughout sdk
var Cdc *Codec
func init() {
cdc := New()
RegisterCrypto(cdc)
RegisterEvidences(cdc)
Cdc = cdc.Seal()
return err
}
+63
View File
@@ -0,0 +1,63 @@
package codec
// HybridCodec defines a codec that utilizes Protobuf for binary encoding
// and Amino for JSON encoding.
type HybridCodec struct {
proto Marshaler
amino Marshaler
}
func NewHybridCodec(amino *Codec) Marshaler {
return &HybridCodec{
proto: NewProtoCodec(),
amino: NewAminoCodec(amino),
}
}
func (hc *HybridCodec) MarshalBinaryBare(o ProtoMarshaler) ([]byte, error) {
return hc.proto.MarshalBinaryBare(o)
}
func (hc *HybridCodec) MustMarshalBinaryBare(o ProtoMarshaler) []byte {
return hc.proto.MustMarshalBinaryBare(o)
}
func (hc *HybridCodec) MarshalBinaryLengthPrefixed(o ProtoMarshaler) ([]byte, error) {
return hc.proto.MarshalBinaryLengthPrefixed(o)
}
func (hc *HybridCodec) MustMarshalBinaryLengthPrefixed(o ProtoMarshaler) []byte {
return hc.proto.MustMarshalBinaryLengthPrefixed(o)
}
func (hc *HybridCodec) UnmarshalBinaryBare(bz []byte, ptr ProtoMarshaler) error {
return hc.proto.UnmarshalBinaryBare(bz, ptr)
}
func (hc *HybridCodec) MustUnmarshalBinaryBare(bz []byte, ptr ProtoMarshaler) {
hc.proto.MustUnmarshalBinaryBare(bz, ptr)
}
func (hc *HybridCodec) UnmarshalBinaryLengthPrefixed(bz []byte, ptr ProtoMarshaler) error {
return hc.proto.UnmarshalBinaryLengthPrefixed(bz, ptr)
}
func (hc *HybridCodec) MustUnmarshalBinaryLengthPrefixed(bz []byte, ptr ProtoMarshaler) {
hc.proto.MustUnmarshalBinaryLengthPrefixed(bz, ptr)
}
func (hc *HybridCodec) MarshalJSON(o interface{}) ([]byte, error) { // nolint: stdmethods
return hc.amino.MarshalJSON(o)
}
func (hc *HybridCodec) MustMarshalJSON(o interface{}) []byte {
return hc.amino.MustMarshalJSON(o)
}
func (hc *HybridCodec) UnmarshalJSON(bz []byte, ptr interface{}) error { // nolint: stdmethods
return hc.amino.UnmarshalJSON(bz, ptr)
}
func (hc *HybridCodec) MustUnmarshalJSON(bz []byte, ptr interface{}) {
hc.amino.MustUnmarshalJSON(bz, ptr)
}
+107
View File
@@ -0,0 +1,107 @@
package codec_test
import (
"testing"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/testdata"
"github.com/stretchr/testify/require"
)
func TestHybridCodec(t *testing.T) {
testCases := []struct {
name string
codec codec.Marshaler
input codec.ProtoMarshaler
recv codec.ProtoMarshaler
marshalErr bool
unmarshalErr bool
}{
{
"valid encoding and decoding",
codec.NewHybridCodec(createTestCodec()),
&testdata.Dog{Name: "rufus"},
&testdata.Dog{},
false,
false,
},
{
"invalid decode type",
codec.NewHybridCodec(createTestCodec()),
&testdata.Dog{Name: "rufus"},
&testdata.Cat{},
false,
true,
},
}
for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
bz, err := tc.codec.MarshalBinaryBare(tc.input)
if tc.marshalErr {
require.Error(t, err)
require.Panics(t, func() { tc.codec.MustMarshalBinaryBare(tc.input) })
} else {
var bz2 []byte
require.NoError(t, err)
require.NotPanics(t, func() { bz2 = tc.codec.MustMarshalBinaryBare(tc.input) })
require.Equal(t, bz, bz2)
err := tc.codec.UnmarshalBinaryBare(bz, tc.recv)
if tc.unmarshalErr {
require.Error(t, err)
require.Panics(t, func() { tc.codec.MustUnmarshalBinaryBare(bz, tc.recv) })
} else {
require.NoError(t, err)
require.NotPanics(t, func() { tc.codec.MustUnmarshalBinaryBare(bz, tc.recv) })
require.Equal(t, tc.input, tc.recv)
}
}
bz, err = tc.codec.MarshalBinaryLengthPrefixed(tc.input)
if tc.marshalErr {
require.Error(t, err)
require.Panics(t, func() { tc.codec.MustMarshalBinaryLengthPrefixed(tc.input) })
} else {
var bz2 []byte
require.NoError(t, err)
require.NotPanics(t, func() { bz2 = tc.codec.MustMarshalBinaryLengthPrefixed(tc.input) })
require.Equal(t, bz, bz2)
err := tc.codec.UnmarshalBinaryLengthPrefixed(bz, tc.recv)
if tc.unmarshalErr {
require.Error(t, err)
require.Panics(t, func() { tc.codec.MustUnmarshalBinaryLengthPrefixed(bz, tc.recv) })
} else {
require.NoError(t, err)
require.NotPanics(t, func() { tc.codec.MustUnmarshalBinaryLengthPrefixed(bz, tc.recv) })
require.Equal(t, tc.input, tc.recv)
}
}
bz, err = tc.codec.MarshalJSON(tc.input)
if tc.marshalErr {
require.Error(t, err)
require.Panics(t, func() { tc.codec.MustMarshalJSON(tc.input) })
} else {
var bz2 []byte
require.NoError(t, err)
require.NotPanics(t, func() { bz2 = tc.codec.MustMarshalJSON(tc.input) })
require.Equal(t, bz, bz2)
err := tc.codec.UnmarshalJSON(bz, tc.recv)
if tc.unmarshalErr {
require.Error(t, err)
require.Panics(t, func() { tc.codec.MustUnmarshalJSON(bz, tc.recv) })
} else {
require.NoError(t, err)
require.NotPanics(t, func() { tc.codec.MustUnmarshalJSON(bz, tc.recv) })
require.Equal(t, tc.input, tc.recv)
}
}
})
}
}
+130
View File
@@ -0,0 +1,130 @@
package codec
import (
"bytes"
"encoding/binary"
"fmt"
"strings"
"github.com/gogo/protobuf/jsonpb"
)
// ProtoCodec defines a codec that utilizes Protobuf for both binary and JSON
// encoding.
type ProtoCodec struct{}
func NewProtoCodec() Marshaler {
return &ProtoCodec{}
}
func (pc *ProtoCodec) MarshalBinaryBare(o ProtoMarshaler) ([]byte, error) {
return o.Marshal()
}
func (pc *ProtoCodec) MustMarshalBinaryBare(o ProtoMarshaler) []byte {
bz, err := pc.MarshalBinaryBare(o)
if err != nil {
panic(err)
}
return bz
}
func (pc *ProtoCodec) MarshalBinaryLengthPrefixed(o ProtoMarshaler) ([]byte, error) {
bz, err := pc.MarshalBinaryBare(o)
if err != nil {
return nil, err
}
buf := new(bytes.Buffer)
if err := encodeUvarint(buf, uint64(o.Size())); err != nil {
return nil, err
}
if _, err := buf.Write(bz); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
func (pc *ProtoCodec) MustMarshalBinaryLengthPrefixed(o ProtoMarshaler) []byte {
bz, err := pc.MarshalBinaryLengthPrefixed(o)
if err != nil {
panic(err)
}
return bz
}
func (pc *ProtoCodec) UnmarshalBinaryBare(bz []byte, ptr ProtoMarshaler) error {
return ptr.Unmarshal(bz)
}
func (pc *ProtoCodec) MustUnmarshalBinaryBare(bz []byte, ptr ProtoMarshaler) {
if err := pc.UnmarshalBinaryBare(bz, ptr); err != nil {
panic(err)
}
}
func (pc *ProtoCodec) UnmarshalBinaryLengthPrefixed(bz []byte, ptr ProtoMarshaler) error {
size, n := binary.Uvarint(bz)
if n < 0 {
return fmt.Errorf("invalid number of bytes read from length-prefixed encoding: %d", n)
}
if size > uint64(len(bz)-n) {
return fmt.Errorf("not enough bytes to read; want: %v, got: %v", size, len(bz)-n)
} else if size < uint64(len(bz)-n) {
return fmt.Errorf("too many bytes to read; want: %v, got: %v", size, len(bz)-n)
}
bz = bz[n:]
return ptr.Unmarshal(bz)
}
func (pc *ProtoCodec) MustUnmarshalBinaryLengthPrefixed(bz []byte, ptr ProtoMarshaler) {
if err := pc.UnmarshalBinaryLengthPrefixed(bz, ptr); err != nil {
panic(err)
}
}
func (pc *ProtoCodec) MarshalJSON(o interface{}) ([]byte, error) { // nolint: stdmethods
m, ok := o.(ProtoMarshaler)
if !ok {
return nil, fmt.Errorf("cannot protobuf JSON encode unsupported type: %T", o)
}
buf := new(bytes.Buffer)
marshaler := &jsonpb.Marshaler{}
if err := marshaler.Marshal(buf, m); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
func (pc *ProtoCodec) MustMarshalJSON(o interface{}) []byte {
bz, err := pc.MarshalJSON(o)
if err != nil {
panic(err)
}
return bz
}
func (pc *ProtoCodec) UnmarshalJSON(bz []byte, ptr interface{}) error { // nolint: stdmethods
m, ok := ptr.(ProtoMarshaler)
if !ok {
return fmt.Errorf("cannot protobuf JSON decode unsupported type: %T", ptr)
}
return jsonpb.Unmarshal(strings.NewReader(string(bz)), m)
}
func (pc *ProtoCodec) MustUnmarshalJSON(bz []byte, ptr interface{}) {
if err := pc.UnmarshalJSON(bz, ptr); err != nil {
panic(err)
}
}
+107
View File
@@ -0,0 +1,107 @@
package codec_test
import (
"testing"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/testdata"
"github.com/stretchr/testify/require"
)
func TestProtoCodec(t *testing.T) {
testCases := []struct {
name string
codec codec.Marshaler
input codec.ProtoMarshaler
recv codec.ProtoMarshaler
marshalErr bool
unmarshalErr bool
}{
{
"valid encoding and decoding",
codec.NewProtoCodec(),
&testdata.Dog{Name: "rufus"},
&testdata.Dog{},
false,
false,
},
{
"invalid decode type",
codec.NewProtoCodec(),
&testdata.Dog{Name: "rufus"},
&testdata.Cat{},
false,
true,
},
}
for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
bz, err := tc.codec.MarshalBinaryBare(tc.input)
if tc.marshalErr {
require.Error(t, err)
require.Panics(t, func() { tc.codec.MustMarshalBinaryBare(tc.input) })
} else {
var bz2 []byte
require.NoError(t, err)
require.NotPanics(t, func() { bz2 = tc.codec.MustMarshalBinaryBare(tc.input) })
require.Equal(t, bz, bz2)
err := tc.codec.UnmarshalBinaryBare(bz, tc.recv)
if tc.unmarshalErr {
require.Error(t, err)
require.Panics(t, func() { tc.codec.MustUnmarshalBinaryBare(bz, tc.recv) })
} else {
require.NoError(t, err)
require.NotPanics(t, func() { tc.codec.MustUnmarshalBinaryBare(bz, tc.recv) })
require.Equal(t, tc.input, tc.recv)
}
}
bz, err = tc.codec.MarshalBinaryLengthPrefixed(tc.input)
if tc.marshalErr {
require.Error(t, err)
require.Panics(t, func() { tc.codec.MustMarshalBinaryLengthPrefixed(tc.input) })
} else {
var bz2 []byte
require.NoError(t, err)
require.NotPanics(t, func() { bz2 = tc.codec.MustMarshalBinaryLengthPrefixed(tc.input) })
require.Equal(t, bz, bz2)
err := tc.codec.UnmarshalBinaryLengthPrefixed(bz, tc.recv)
if tc.unmarshalErr {
require.Error(t, err)
require.Panics(t, func() { tc.codec.MustUnmarshalBinaryLengthPrefixed(bz, tc.recv) })
} else {
require.NoError(t, err)
require.NotPanics(t, func() { tc.codec.MustUnmarshalBinaryLengthPrefixed(bz, tc.recv) })
require.Equal(t, tc.input, tc.recv)
}
}
bz, err = tc.codec.MarshalJSON(tc.input)
if tc.marshalErr {
require.Error(t, err)
require.Panics(t, func() { tc.codec.MustMarshalJSON(tc.input) })
} else {
var bz2 []byte
require.NoError(t, err)
require.NotPanics(t, func() { bz2 = tc.codec.MustMarshalJSON(tc.input) })
require.Equal(t, bz, bz2)
err := tc.codec.UnmarshalJSON(bz, tc.recv)
if tc.unmarshalErr {
require.Error(t, err)
require.Panics(t, func() { tc.codec.MustUnmarshalJSON(bz, tc.recv) })
} else {
require.NoError(t, err)
require.NotPanics(t, func() { tc.codec.MustUnmarshalJSON(bz, tc.recv) })
require.Equal(t, tc.input, tc.recv)
}
}
})
}
}
+20
View File
@@ -0,0 +1,20 @@
package testdata
// DONTCOVER
// nolint
import (
"fmt"
)
type Animal interface {
Greet() string
}
func (c Cat) Greet() string {
return fmt.Sprintf("Meow, my name is %s", c.Moniker)
}
func (d Dog) Greet() string {
return fmt.Sprintf("Roof, my name is %s", d.Name)
}
+579
View File
@@ -0,0 +1,579 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: codec/testdata/proto.proto
package testdata
import (
fmt "fmt"
proto "github.com/gogo/protobuf/proto"
io "io"
math "math"
math_bits "math/bits"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
type Dog struct {
Size_ string `protobuf:"bytes,1,opt,name=size,proto3" json:"size,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
}
func (m *Dog) Reset() { *m = Dog{} }
func (m *Dog) String() string { return proto.CompactTextString(m) }
func (*Dog) ProtoMessage() {}
func (*Dog) Descriptor() ([]byte, []int) {
return fileDescriptor_ae1353846770e6e2, []int{0}
}
func (m *Dog) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *Dog) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_Dog.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *Dog) XXX_Merge(src proto.Message) {
xxx_messageInfo_Dog.Merge(m, src)
}
func (m *Dog) XXX_Size() int {
return m.Size()
}
func (m *Dog) XXX_DiscardUnknown() {
xxx_messageInfo_Dog.DiscardUnknown(m)
}
var xxx_messageInfo_Dog proto.InternalMessageInfo
func (m *Dog) GetSize_() string {
if m != nil {
return m.Size_
}
return ""
}
func (m *Dog) GetName() string {
if m != nil {
return m.Name
}
return ""
}
type Cat struct {
Moniker string `protobuf:"bytes,1,opt,name=moniker,proto3" json:"moniker,omitempty"`
Lives int32 `protobuf:"varint,2,opt,name=lives,proto3" json:"lives,omitempty"`
}
func (m *Cat) Reset() { *m = Cat{} }
func (m *Cat) String() string { return proto.CompactTextString(m) }
func (*Cat) ProtoMessage() {}
func (*Cat) Descriptor() ([]byte, []int) {
return fileDescriptor_ae1353846770e6e2, []int{1}
}
func (m *Cat) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *Cat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_Cat.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *Cat) XXX_Merge(src proto.Message) {
xxx_messageInfo_Cat.Merge(m, src)
}
func (m *Cat) XXX_Size() int {
return m.Size()
}
func (m *Cat) XXX_DiscardUnknown() {
xxx_messageInfo_Cat.DiscardUnknown(m)
}
var xxx_messageInfo_Cat proto.InternalMessageInfo
func (m *Cat) GetMoniker() string {
if m != nil {
return m.Moniker
}
return ""
}
func (m *Cat) GetLives() int32 {
if m != nil {
return m.Lives
}
return 0
}
func init() {
proto.RegisterType((*Dog)(nil), "cosmos_sdk.codec.v1.Dog")
proto.RegisterType((*Cat)(nil), "cosmos_sdk.codec.v1.Cat")
}
func init() { proto.RegisterFile("codec/testdata/proto.proto", fileDescriptor_ae1353846770e6e2) }
var fileDescriptor_ae1353846770e6e2 = []byte{
// 195 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4a, 0xce, 0x4f, 0x49,
0x4d, 0xd6, 0x2f, 0x49, 0x2d, 0x2e, 0x49, 0x49, 0x2c, 0x49, 0xd4, 0x2f, 0x28, 0xca, 0x2f, 0xc9,
0xd7, 0x03, 0x93, 0x42, 0xc2, 0xc9, 0xf9, 0xc5, 0xb9, 0xf9, 0xc5, 0xf1, 0xc5, 0x29, 0xd9, 0x7a,
0x60, 0x65, 0x7a, 0x65, 0x86, 0x4a, 0xba, 0x5c, 0xcc, 0x2e, 0xf9, 0xe9, 0x42, 0x42, 0x5c, 0x2c,
0xc5, 0x99, 0x55, 0xa9, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0x60, 0x36, 0x48, 0x2c, 0x2f,
0x31, 0x37, 0x55, 0x82, 0x09, 0x22, 0x06, 0x62, 0x2b, 0x99, 0x72, 0x31, 0x3b, 0x27, 0x96, 0x08,
0x49, 0x70, 0xb1, 0xe7, 0xe6, 0xe7, 0x65, 0x66, 0xa7, 0x16, 0x41, 0x75, 0xc0, 0xb8, 0x42, 0x22,
0x5c, 0xac, 0x39, 0x99, 0x65, 0xa9, 0xc5, 0x60, 0x5d, 0xac, 0x41, 0x10, 0x8e, 0x93, 0xeb, 0x89,
0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, 0xe1, 0xb1, 0x1c, 0xc3,
0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31, 0x44, 0x69, 0xa7, 0x67, 0x96, 0x64, 0x94, 0x26,
0xe9, 0x25, 0xe7, 0xe7, 0xea, 0x43, 0xdc, 0x07, 0xa5, 0x74, 0x8b, 0x53, 0xb2, 0xf5, 0x51, 0x7d,
0x93, 0xc4, 0x06, 0xf6, 0x88, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0x64, 0x25, 0x07, 0xc7, 0xe6,
0x00, 0x00, 0x00,
}
func (m *Dog) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Dog) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *Dog) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Name) > 0 {
i -= len(m.Name)
copy(dAtA[i:], m.Name)
i = encodeVarintProto(dAtA, i, uint64(len(m.Name)))
i--
dAtA[i] = 0x12
}
if len(m.Size_) > 0 {
i -= len(m.Size_)
copy(dAtA[i:], m.Size_)
i = encodeVarintProto(dAtA, i, uint64(len(m.Size_)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *Cat) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Cat) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *Cat) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.Lives != 0 {
i = encodeVarintProto(dAtA, i, uint64(m.Lives))
i--
dAtA[i] = 0x10
}
if len(m.Moniker) > 0 {
i -= len(m.Moniker)
copy(dAtA[i:], m.Moniker)
i = encodeVarintProto(dAtA, i, uint64(len(m.Moniker)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func encodeVarintProto(dAtA []byte, offset int, v uint64) int {
offset -= sovProto(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *Dog) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Size_)
if l > 0 {
n += 1 + l + sovProto(uint64(l))
}
l = len(m.Name)
if l > 0 {
n += 1 + l + sovProto(uint64(l))
}
return n
}
func (m *Cat) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Moniker)
if l > 0 {
n += 1 + l + sovProto(uint64(l))
}
if m.Lives != 0 {
n += 1 + sovProto(uint64(m.Lives))
}
return n
}
func sovProto(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozProto(x uint64) (n int) {
return sovProto(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *Dog) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowProto
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Dog: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Dog: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Size_", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowProto
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthProto
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthProto
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Size_ = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowProto
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthProto
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthProto
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Name = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipProto(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthProto
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthProto
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *Cat) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowProto
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Cat: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Cat: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Moniker", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowProto
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthProto
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthProto
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Moniker = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Lives", wireType)
}
m.Lives = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowProto
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Lives |= int32(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipProto(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthProto
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthProto
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipProto(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowProto
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowProto
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowProto
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthProto
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupProto
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthProto
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthProto = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowProto = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupProto = fmt.Errorf("proto: unexpected end of group")
)
+14
View File
@@ -0,0 +1,14 @@
syntax = "proto3";
package cosmos_sdk.codec.v1;
option go_package = "github.com/cosmos/cosmos-sdk/codec/testdata";
message Dog {
string size = 1;
string name = 2;
}
message Cat {
string moniker = 1;
int32 lives = 2;
}