mirror of
https://github.com/protocolbuffers/protobuf-go.git
synced 2025-01-26 18:35:25 +00:00
all: consistently treat nil message interface as an empty read-only message
To assist users in migrating from github.com/golang/protobuf to google.golang.org/protobuf, make it such that functiionality like proto.Marshal doesn't panic on nil interfaces. Similar to how the new implementation treats a typed nil message as an empty message, we treat a nil interface as being equivalent to an "untyped" empty message. Change-Id: Ic037f386f855b122f732b34d370e524b7c0d76f1 Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/228837 Reviewed-by: Damien Neil <dneil@google.com>
This commit is contained in:
parent
d8bc21f7e1
commit
8cfc14f022
@ -116,6 +116,12 @@ func (o MarshalOptions) Marshal(m proto.Message) ([]byte, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Treat nil message interface as an empty message,
|
||||
// in which case the output in an empty JSON object.
|
||||
if m == nil {
|
||||
return []byte("{}"), nil
|
||||
}
|
||||
|
||||
enc := encoder{internalEnc, o}
|
||||
if err := enc.marshalMessage(m.ProtoReflect()); err != nil {
|
||||
return nil, err
|
||||
|
@ -106,6 +106,12 @@ func (o MarshalOptions) Marshal(m proto.Message) ([]byte, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Treat nil message interface as an empty message,
|
||||
// in which case there is nothing to output.
|
||||
if m == nil {
|
||||
return []byte{}, nil
|
||||
}
|
||||
|
||||
enc := encoder{internalEnc, o}
|
||||
err = enc.marshalMessage(m.ProtoReflect(), false)
|
||||
if err != nil {
|
||||
|
@ -12,6 +12,12 @@ import (
|
||||
|
||||
// CheckInitialized returns an error if any required fields in m are not set.
|
||||
func CheckInitialized(m Message) error {
|
||||
// Treat a nil message interface as an "untyped" empty message,
|
||||
// which we assume to have no required fields.
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return checkInitialized(m.ProtoReflect())
|
||||
}
|
||||
|
||||
|
@ -74,12 +74,22 @@ type MarshalOptions struct {
|
||||
|
||||
// Marshal returns the wire-format encoding of m.
|
||||
func Marshal(m Message) ([]byte, error) {
|
||||
// Treat nil message interface as an empty message; nothing to output.
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
out, err := MarshalOptions{}.marshal(nil, m.ProtoReflect())
|
||||
return out.Buf, err
|
||||
}
|
||||
|
||||
// Marshal returns the wire-format encoding of m.
|
||||
func (o MarshalOptions) Marshal(m Message) ([]byte, error) {
|
||||
// Treat nil message interface as an empty message; nothing to output.
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
out, err := o.marshal(nil, m.ProtoReflect())
|
||||
return out.Buf, err
|
||||
}
|
||||
@ -87,6 +97,11 @@ func (o MarshalOptions) Marshal(m Message) ([]byte, error) {
|
||||
// MarshalAppend appends the wire-format encoding of m to b,
|
||||
// returning the result.
|
||||
func (o MarshalOptions) MarshalAppend(b []byte, m Message) ([]byte, error) {
|
||||
// Treat nil message interface as an empty message; nothing to append.
|
||||
if m == nil {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
out, err := o.marshal(b, m.ProtoReflect())
|
||||
return out.Buf, err
|
||||
}
|
||||
|
@ -21,6 +21,9 @@ import (
|
||||
// It is semantically equivalent to unmarshaling the encoded form of src
|
||||
// into dst with the UnmarshalOptions.Merge option specified.
|
||||
func Merge(dst, src Message) {
|
||||
// TODO: Should nil src be treated as semantically equivalent to a
|
||||
// untyped, read-only, empty message? What about a nil dst?
|
||||
|
||||
dstMsg, srcMsg := dst.ProtoReflect(), src.ProtoReflect()
|
||||
if dstMsg.Descriptor() != srcMsg.Descriptor() {
|
||||
panic("descriptor mismatch")
|
||||
|
@ -27,14 +27,12 @@ func TestNil(t *testing.T) {
|
||||
}{{
|
||||
label: "Size",
|
||||
test: func() { proto.Size(nil) },
|
||||
panic: true,
|
||||
}, {
|
||||
label: "Size",
|
||||
test: func() { proto.Size(nilMsg) },
|
||||
}, {
|
||||
label: "Marshal",
|
||||
test: func() { proto.Marshal(nil) },
|
||||
panic: true,
|
||||
}, {
|
||||
label: "Marshal",
|
||||
test: func() { proto.Marshal(nilMsg) },
|
||||
|
@ -18,6 +18,11 @@ func Size(m Message) int {
|
||||
|
||||
// Size returns the size in bytes of the wire-format encoding of m.
|
||||
func (o MarshalOptions) Size(m Message) int {
|
||||
// Treat a nil message interface as an empty message; nothing to output.
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
return sizeMessage(m.ProtoReflect())
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user