internal/impl: support legacy Merger interface

Change-Id: I796be0bb1bb40605073228446364f3a2f1073ef1
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/219557
Reviewed-by: Joe Tsai <joetsai@google.com>
diff --git a/internal/impl/legacy_message.go b/internal/impl/legacy_message.go
index 29daccb..ebfe18a 100644
--- a/internal/impl/legacy_message.go
+++ b/internal/impl/legacy_message.go
@@ -17,6 +17,7 @@
 	"google.golang.org/protobuf/internal/strs"
 	"google.golang.org/protobuf/reflect/protoreflect"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/runtime/protoiface"
 	piface "google.golang.org/protobuf/runtime/protoiface"
 )
 
@@ -61,6 +62,9 @@
 	if _, ok := v.(legacyUnmarshaler); ok {
 		mi.methods.Unmarshal = legacyUnmarshal
 	}
+	if _, ok := v.(legacyMerger); ok {
+		mi.methods.Merge = legacyMerge
+	}
 
 	if mi, ok := legacyMessageTypeCache.LoadOrStore(t, mi); ok {
 		return mi.(*MessageInfo)
@@ -362,9 +366,15 @@
 	Unmarshal([]byte) error
 }
 
+// legacyMerger is the proto.Merger interface superseded by protoiface.Methoder.
+type legacyMerger interface {
+	Merge(protoiface.MessageV1)
+}
+
 var legacyProtoMethods = &piface.Methods{
 	Marshal:   legacyMarshal,
 	Unmarshal: legacyUnmarshal,
+	Merge:     legacyMerge,
 
 	// We have no way to tell whether the type's Marshal method
 	// supports deterministic serialization or not, but this
@@ -397,6 +407,16 @@
 	return piface.UnmarshalOutput{}, unmarshaler.Unmarshal(in.Buf)
 }
 
+func legacyMerge(dst, src pref.Message, in piface.MergeInput, opts piface.MergeOptions) piface.MergeOutput {
+	dstv := dst.(unwrapper).protoUnwrap()
+	merger, ok := dstv.(legacyMerger)
+	if !ok {
+		return piface.MergeOutput{}
+	}
+	merger.Merge(Export{}.ProtoMessageV1Of(src))
+	return piface.MergeOutput{Merged: true}
+}
+
 // aberrantMessageType implements MessageType for all types other than pointer-to-struct.
 type aberrantMessageType struct {
 	t reflect.Type