internal/impl: handle extremely old messages

At some point in time, protoc-gen-go actually emitted an XXX_OneofFuncs
with a different signature. Adjust the logic for handling XXX_OneofFuncs
to not assume that the return arguments are in a specific order.

Change-Id: Idd9c09231c4129c655d4a635bb1ae094896a1ff4
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/226980
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/internal/impl/legacy_message.go b/internal/impl/legacy_message.go
index a723569..06c68e1 100644
--- a/internal/impl/legacy_message.go
+++ b/internal/impl/legacy_message.go
@@ -195,16 +195,15 @@
 
 	// Obtain a list of oneof wrapper types.
 	var oneofWrappers []reflect.Type
-	if fn, ok := t.MethodByName("XXX_OneofFuncs"); ok {
-		vs := fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))})[3]
-		for _, v := range vs.Interface().([]interface{}) {
-			oneofWrappers = append(oneofWrappers, reflect.TypeOf(v))
-		}
-	}
-	if fn, ok := t.MethodByName("XXX_OneofWrappers"); ok {
-		vs := fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))})[0]
-		for _, v := range vs.Interface().([]interface{}) {
-			oneofWrappers = append(oneofWrappers, reflect.TypeOf(v))
+	for _, method := range []string{"XXX_OneofFuncs", "XXX_OneofWrappers"} {
+		if fn, ok := t.MethodByName(method); ok {
+			for _, v := range fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))}) {
+				if vs, ok := v.Interface().([]interface{}); ok {
+					for _, v := range vs {
+						oneofWrappers = append(oneofWrappers, reflect.TypeOf(v))
+					}
+				}
+			}
 		}
 	}