all: abstract fast-path marshal and unmarshal inputs and outputs
We may want to make changes to the inputs and outputs of the fast-path
functions in the future. For example, we likely want to add the ability
for the fast-path unmarshal to report back whether the unmarshaled
message is known to be initialized.
Change the signatures of these functions to take in and return struct
types which can be extended with whatever fields we want in the future.
Change-Id: Idead360785df730283a4630ea405265b72482e62
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/215719
Reviewed-by: Joe Tsai <joetsai@google.com>
diff --git a/internal/impl/codec_message.go b/internal/impl/codec_message.go
index e487a26..24a87a0 100644
--- a/internal/impl/codec_message.go
+++ b/internal/impl/codec_message.go
@@ -134,9 +134,9 @@
}
mi.needsInitCheck = needsInitCheck(mi.Desc)
- if mi.methods.MarshalAppend == nil && mi.methods.Size == nil {
+ if mi.methods.Marshal == nil && mi.methods.Size == nil {
mi.methods.Flags |= piface.SupportMarshalDeterministic
- mi.methods.MarshalAppend = mi.marshalAppend
+ mi.methods.Marshal = mi.marshal
mi.methods.Size = mi.size
}
if mi.methods.Unmarshal == nil {
diff --git a/internal/impl/decode.go b/internal/impl/decode.go
index 50b0cf1..4d3718f 100644
--- a/internal/impl/decode.go
+++ b/internal/impl/decode.go
@@ -58,15 +58,15 @@
func (o unmarshalOptions) Resolver() preg.ExtensionTypeResolver { return o.resolver }
// unmarshal is protoreflect.Methods.Unmarshal.
-func (mi *MessageInfo) unmarshal(b []byte, m pref.Message, opts piface.UnmarshalOptions) error {
+func (mi *MessageInfo) unmarshal(m pref.Message, in piface.UnmarshalInput) (piface.UnmarshalOutput, error) {
var p pointer
if ms, ok := m.(*messageState); ok {
p = ms.pointer()
} else {
p = m.(*messageReflectWrapper).pointer()
}
- _, err := mi.unmarshalPointer(b, p, 0, newUnmarshalOptions(opts))
- return err
+ _, err := mi.unmarshalPointer(in.Buf, p, 0, newUnmarshalOptions(in.Options))
+ return piface.UnmarshalOutput{}, err
}
// errUnknown is returned during unmarshaling to indicate a parse error that
diff --git a/internal/impl/encode.go b/internal/impl/encode.go
index c793021..306677c 100644
--- a/internal/impl/encode.go
+++ b/internal/impl/encode.go
@@ -101,15 +101,16 @@
return size
}
-// marshalAppend is protoreflect.Methods.MarshalAppend.
-func (mi *MessageInfo) marshalAppend(b []byte, m pref.Message, opts piface.MarshalOptions) ([]byte, error) {
+// marshal is protoreflect.Methods.Marshal.
+func (mi *MessageInfo) marshal(m pref.Message, in piface.MarshalInput) (piface.MarshalOutput, error) {
var p pointer
if ms, ok := m.(*messageState); ok {
p = ms.pointer()
} else {
p = m.(*messageReflectWrapper).pointer()
}
- return mi.marshalAppendPointer(b, p, newMarshalOptions(opts))
+ b, err := mi.marshalAppendPointer(in.Buf, p, newMarshalOptions(in.Options))
+ return piface.MarshalOutput{Buf: b}, err
}
func (mi *MessageInfo) marshalAppendPointer(b []byte, p pointer, opts marshalOptions) ([]byte, error) {
diff --git a/internal/impl/legacy_message.go b/internal/impl/legacy_message.go
index 80220a2..6f08912 100644
--- a/internal/impl/legacy_message.go
+++ b/internal/impl/legacy_message.go
@@ -50,7 +50,7 @@
v := reflect.Zero(t).Interface()
if _, ok := v.(legacyMarshaler); ok {
- mi.methods.MarshalAppend = legacyMarshalAppend
+ mi.methods.Marshal = legacyMarshal
// We have no way to tell whether the type's Marshal method
// supports deterministic serialization or not, but this
@@ -363,8 +363,8 @@
}
var legacyProtoMethods = &piface.Methods{
- MarshalAppend: legacyMarshalAppend,
- Unmarshal: legacyUnmarshal,
+ Marshal: legacyMarshal,
+ Unmarshal: legacyUnmarshal,
// We have no way to tell whether the type's Marshal method
// supports deterministic serialization or not, but this
@@ -373,26 +373,28 @@
Flags: piface.SupportMarshalDeterministic,
}
-func legacyMarshalAppend(b []byte, m protoreflect.Message, opts piface.MarshalOptions) ([]byte, error) {
+func legacyMarshal(m protoreflect.Message, in piface.MarshalInput) (piface.MarshalOutput, error) {
v := m.(unwrapper).protoUnwrap()
marshaler, ok := v.(legacyMarshaler)
if !ok {
- return nil, errors.New("%T does not implement Marshal", v)
+ return piface.MarshalOutput{}, errors.New("%T does not implement Marshal", v)
}
out, err := marshaler.Marshal()
- if b != nil {
- out = append(b, out...)
+ if in.Buf != nil {
+ out = append(in.Buf, out...)
}
- return out, err
+ return piface.MarshalOutput{
+ Buf: out,
+ }, err
}
-func legacyUnmarshal(b []byte, m protoreflect.Message, opts piface.UnmarshalOptions) error {
+func legacyUnmarshal(m protoreflect.Message, in piface.UnmarshalInput) (piface.UnmarshalOutput, error) {
v := m.(unwrapper).protoUnwrap()
unmarshaler, ok := v.(legacyUnmarshaler)
if !ok {
- return errors.New("%T does not implement Marshal", v)
+ return piface.UnmarshalOutput{}, errors.New("%T does not implement Marshal", v)
}
- return unmarshaler.Unmarshal(b)
+ return piface.UnmarshalOutput{}, unmarshaler.Unmarshal(in.Buf)
}
// aberrantMessageType implements MessageType for all types other than pointer-to-struct.