internal/impl: handle irregular messages implementing proto.Message
When encountering a type that does not have a MessageInfo, don't assume
that it's a legacy message that doesn't implement proto.Message. Add a
set of test messages exercising this case (panics prior to the
internal/impl change).
Change-Id: Ic1ec5ecfbe92278fbef44284ff52a0e0622a158c
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/182477
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/internal/impl/encode_field.go b/internal/impl/encode_field.go
index 53a8eda..a6580ce 100644
--- a/internal/impl/encode_field.go
+++ b/internal/impl/encode_field.go
@@ -82,11 +82,11 @@
} else {
return pointerCoderFuncs{
size: func(p pointer, tagsize int, opts marshalOptions) int {
- m := legacyWrapMessage(p.AsValueOf(ft).Elem())
+ m := asMessage(p.AsValueOf(ft).Elem())
return sizeMessage(m, tagsize, opts)
},
marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
- m := legacyWrapMessage(p.AsValueOf(ft).Elem())
+ m := asMessage(p.AsValueOf(ft).Elem())
return appendMessage(b, m, wiretag, opts)
},
}
@@ -141,11 +141,11 @@
} else {
return pointerCoderFuncs{
size: func(p pointer, tagsize int, opts marshalOptions) int {
- m := legacyWrapMessage(p.AsValueOf(ft).Elem())
+ m := asMessage(p.AsValueOf(ft).Elem())
return sizeGroup(m, tagsize, opts)
},
marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
- m := legacyWrapMessage(p.AsValueOf(ft).Elem())
+ m := asMessage(p.AsValueOf(ft).Elem())
return appendGroup(b, m, wiretag, opts)
},
}
@@ -492,3 +492,10 @@
size: sizeStringIfaceValidateUTF8,
marshal: appendStringIfaceValidateUTF8,
}
+
+func asMessage(v reflect.Value) pref.ProtoMessage {
+ if m, ok := v.Interface().(pref.ProtoMessage); ok {
+ return m
+ }
+ return legacyWrapMessage(v)
+}