Skip to content

Commit

Permalink
Add support for MarshalAppend
Browse files Browse the repository at this point in the history
Expose the more efficient `MarshalAppend` method added in v1.31 of the
protobuf runtime.
  • Loading branch information
akshayjshah committed Jun 30, 2023
1 parent 786bee0 commit 52a5a81
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 11 deletions.
14 changes: 9 additions & 5 deletions binary.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,26 @@ func (b *binaryCodec) Unmarshal(binary []byte, msg any) error {
}

func (b *binaryCodec) Marshal(msg any) ([]byte, error) {
return b.marshalBinary(msg, false /* stable */)
return b.marshalBinary(nil, msg, false /* stable */)
}

func (b *binaryCodec) MarshalStable(msg any) ([]byte, error) {
return b.marshalBinary(msg, true /* stable */)
return b.marshalBinary(nil, msg, true /* stable */)
}

func (b *binaryCodec) marshalBinary(msg any, stable bool) ([]byte, error) {
func (b *binaryCodec) MarshalAppend(dst []byte, msg any) ([]byte, error) {
return b.marshalBinary(dst, msg, false /* stable */)
}

func (b *binaryCodec) marshalBinary(dst []byte, msg any, stable bool) ([]byte, error) {
pm, ok := msg.(proto.Message)
if !ok {
return nil, errNotProto(msg)
}
if stable {
return b.stable.Marshal(pm)
return b.stable.MarshalAppend(dst, pm)
}
return b.marshal.Marshal(pm)
return b.marshal.MarshalAppend(dst, pm)
}

type vtBinaryCodec struct {
Expand Down
7 changes: 7 additions & 0 deletions binary_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ func TestBinaryMarshal(t *testing.T) {
attest.True(t, bytes.Equal(out, again), attest.Sprint("MarshalStable produced unstable output"))
}
})
t.Run("append", func(t *testing.T) {
out, err := codec.MarshalAppend(make([]byte, 0, 128), dict)
attest.Ok(t, err)
roundtrip := &structpb.Struct{}
attest.Ok(t, proto.Unmarshal(out, roundtrip))
attest.Equal(t, roundtrip, dict, attest.Cmp(protocmp.Transform()))
})
t.Run("not protobuf", func(t *testing.T) {
_, err := codec.Marshal(struct{}{})
attest.Error(t, err)
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.19
require (
github.com/bufbuild/connect-go v1.7.0
go.akshayshah.org/attest v1.0.0
google.golang.org/protobuf v1.30.0
google.golang.org/protobuf v1.31.0
)

require (
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
14 changes: 9 additions & 5 deletions json.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,7 @@ func (j *jsonCodec) Unmarshal(binary []byte, msg any) error {
}

func (j *jsonCodec) Marshal(msg any) ([]byte, error) {
pm, ok := msg.(proto.Message)
if !ok {
return nil, errNotProto(msg)
}
return j.marshal.Marshal(pm)
return j.MarshalAppend(nil, msg)
}

func (j *jsonCodec) MarshalStable(message any) ([]byte, error) {
Expand All @@ -62,3 +58,11 @@ func (j *jsonCodec) MarshalStable(message any) ([]byte, error) {
}
return compacted.Bytes(), nil
}

func (j *jsonCodec) MarshalAppend(dst []byte, msg any) ([]byte, error) {
pm, ok := msg.(proto.Message)
if !ok {
return nil, errNotProto(msg)
}
return j.marshal.MarshalAppend(dst, pm)
}
5 changes: 5 additions & 0 deletions json_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ func TestJSONMarshal(t *testing.T) {
attest.Ok(t, err)
attest.Equal(t, string(out), `{"name":"Foo"}`)
})
t.Run("append", func(t *testing.T) {
out, err := codec.MarshalAppend(make([]byte, 0, 100), enum)
attest.Ok(t, err)
attest.Subsequence(t, string(out), "\n\t")
})
t.Run("not protobuf", func(t *testing.T) {
_, err := codec.Marshal(struct{}{})
attest.Error(t, err)
Expand Down

0 comments on commit 52a5a81

Please sign in to comment.