all: remove {Enum,Message,Extension}Type.GoType methods

These methods are difficult or impossible to use correctly; types
created by the dynamicpb package, for example, all have the same GoType.

Fixes golang/protobuf#938

Change-Id: I33d4ef381579ff18569b11df501d0ba7f38a6b5c
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/199060
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/internal/impl/enum.go b/internal/impl/enum.go
index eceff8a..8c1eab4 100644
--- a/internal/impl/enum.go
+++ b/internal/impl/enum.go
@@ -18,5 +18,4 @@
 func (t *EnumInfo) New(n pref.EnumNumber) pref.Enum {
 	return reflect.ValueOf(n).Convert(t.GoReflectType).Interface().(pref.Enum)
 }
-func (t *EnumInfo) GoType() reflect.Type            { return t.GoReflectType }
 func (t *EnumInfo) Descriptor() pref.EnumDescriptor { return t.Desc }
diff --git a/internal/impl/enum_test.go b/internal/impl/enum_test.go
index d122a6c..7e04500 100644
--- a/internal/impl/enum_test.go
+++ b/internal/impl/enum_test.go
@@ -5,7 +5,6 @@
 package impl_test
 
 import (
-	"reflect"
 	"testing"
 
 	pref "google.golang.org/protobuf/reflect/protoreflect"
@@ -15,9 +14,6 @@
 
 func TestEnum(t *testing.T) {
 	et := testpb.ForeignEnum_FOREIGN_FOO.Type()
-	if got, want := et.GoType(), reflect.TypeOf(testpb.ForeignEnum_FOREIGN_FOO); got != want {
-		t.Errorf("testpb.ForeignEnum_FOREIGN_FOO.Type().GoType() = %v, want %v", got, want)
-	}
 	if got, want := et.New(pref.EnumNumber(testpb.ForeignEnum_FOREIGN_FOO)), pref.Enum(testpb.ForeignEnum_FOREIGN_FOO); got != want {
 		t.Errorf("testpb.ForeignEnum_FOREIGN_FOO.Type().New() = %[1]T(%[1]v), want %[2]T(%[2]v)", got, want)
 	}
diff --git a/internal/impl/extension.go b/internal/impl/extension.go
index 723bdb0..541f4a7 100644
--- a/internal/impl/extension.go
+++ b/internal/impl/extension.go
@@ -46,16 +46,12 @@
 	// Deprecated: Use the ExtendedType method instead.
 	ExtendedType piface.MessageV1
 
-	// ExtensionType is zero value of the extension type.
+	// ExtensionType is the zero value of the extension type.
 	//
-	// For historical reasons, reflect.TypeOf(ExtensionType) and Type.GoType
-	// may not be identical:
-	//	* for scalars (except []byte), where ExtensionType uses *T,
-	//	while Type.GoType uses T.
-	//	* for repeated fields, where ExtensionType uses []T,
-	//	while Type.GoType uses *[]T.
+	// For historical reasons, reflect.TypeOf(ExtensionType) and the
+	// type returned by InterfaceOf may not be identical.
 	//
-	// Deprecated: Use the GoType method instead.
+	// Deprecated: Use InterfaceOf(xt.Zero()) instead.
 	ExtensionType interface{}
 
 	// Field is the field number of the extension.
@@ -110,10 +106,6 @@
 func (xi *ExtensionInfo) IsValidInterface(v interface{}) bool {
 	return xi.lazyInit().IsValidGo(reflect.ValueOf(v))
 }
-func (xi *ExtensionInfo) GoType() reflect.Type {
-	xi.lazyInit()
-	return xi.goType
-}
 func (xi *ExtensionInfo) TypeDescriptor() pref.ExtensionTypeDescriptor {
 	if atomic.LoadUint32(&xi.init) < extensionInfoDescInit {
 		xi.lazyInitSlow()
diff --git a/internal/impl/legacy_enum.go b/internal/impl/legacy_enum.go
index c92eadf..b4d26ef 100644
--- a/internal/impl/legacy_enum.go
+++ b/internal/impl/legacy_enum.go
@@ -76,9 +76,6 @@
 	t.m.Store(n, e)
 	return e
 }
-func (t *legacyEnumType) GoType() reflect.Type {
-	return t.goType
-}
 func (t *legacyEnumType) Descriptor() pref.EnumDescriptor {
 	return t.desc
 }
diff --git a/internal/impl/legacy_test.go b/internal/impl/legacy_test.go
index 46d8c36..f55c0d3 100644
--- a/internal/impl/legacy_test.go
+++ b/internal/impl/legacy_test.go
@@ -473,7 +473,6 @@
 				xt := xt
 				go func() { xt.New() }()
 				go func() { xt.Zero() }()
-				go func() { xt.GoType() }()
 				go func() { xt.TypeDescriptor() }()
 			}
 
@@ -527,7 +526,6 @@
 				cmp.Transformer("", func(xt pref.ExtensionType) map[string]interface{} {
 					return map[string]interface{}{
 						"Descriptor": xt.TypeDescriptor(),
-						"GoType":     xt.GoType(),
 					}
 				}),
 				cmp.Transformer("", func(v pref.Value) interface{} {
diff --git a/internal/impl/message.go b/internal/impl/message.go
index 2e35c51..fe8f039 100644
--- a/internal/impl/message.go
+++ b/internal/impl/message.go
@@ -198,9 +198,6 @@
 	return si
 }
 
-func (mi *MessageInfo) GoType() reflect.Type {
-	return mi.GoReflectType
-}
 func (mi *MessageInfo) New() protoreflect.Message {
 	return mi.MessageOf(reflect.New(mi.GoReflectType.Elem()).Interface())
 }
diff --git a/internal/impl/message_reflect_test.go b/internal/impl/message_reflect_test.go
index 6148d4d..9026e6e 100644
--- a/internal/impl/message_reflect_test.go
+++ b/internal/impl/message_reflect_test.go
@@ -940,7 +940,6 @@
 func (e EnumProto2) Type() pref.EnumType             { return e }
 func (e EnumProto2) Enum() *EnumProto2               { return &e }
 func (e EnumProto2) Number() pref.EnumNumber         { return pref.EnumNumber(e) }
-func (t EnumProto2) GoType() reflect.Type            { return reflect.TypeOf(t) }
 func (t EnumProto2) New(n pref.EnumNumber) pref.Enum { return EnumProto2(n) }
 
 type EnumProto3 int32
@@ -954,7 +953,6 @@
 func (e EnumProto3) Type() pref.EnumType             { return e }
 func (e EnumProto3) Enum() *EnumProto3               { return &e }
 func (e EnumProto3) Number() pref.EnumNumber         { return pref.EnumNumber(e) }
-func (t EnumProto3) GoType() reflect.Type            { return reflect.TypeOf(t) }
 func (t EnumProto3) New(n pref.EnumNumber) pref.Enum { return EnumProto3(n) }
 
 type EnumMessages struct {
diff --git a/internal/testprotos/irregular/irregular.go b/internal/testprotos/irregular/irregular.go
index b328edb..69220ba 100644
--- a/internal/testprotos/irregular/irregular.go
+++ b/internal/testprotos/irregular/irregular.go
@@ -5,8 +5,6 @@
 package irregular
 
 import (
-	"reflect"
-
 	"google.golang.org/protobuf/encoding/prototext"
 	"google.golang.org/protobuf/reflect/protodesc"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
@@ -27,7 +25,6 @@
 func (m *message) Type() pref.MessageType             { return m }
 func (m *message) New() pref.Message                  { return &message{} }
 func (m *message) Zero() pref.Message                 { return (*message)(nil) }
-func (m *message) GoType() reflect.Type               { return reflect.TypeOf(&message{}) }
 func (m *message) Interface() pref.ProtoMessage       { return (*IrregularMessage)(m) }
 
 var fieldDescS = fileDesc.Messages().Get(0).Fields().Get(0)
diff --git a/reflect/protoreflect/type.go b/reflect/protoreflect/type.go
index 223599a..7e59798 100644
--- a/reflect/protoreflect/type.go
+++ b/reflect/protoreflect/type.go
@@ -4,8 +4,6 @@
 
 package protoreflect
 
-import "reflect"
-
 // Descriptor provides a set of accessors that are common to every descriptor.
 // Each descriptor type wraps the equivalent google.protobuf.XXXDescriptorProto,
 // but provides efficient lookup and immutability.
@@ -235,11 +233,6 @@
 	// Zero returns an immutable empty message.
 	Zero() Message
 
-	// GoType returns the Go type of the allocated message.
-	//
-	// Invariant: t.GoType() == reflect.TypeOf(t.New().Interface())
-	GoType() reflect.Type
-
 	// Descriptor returns the message descriptor.
 	//
 	// Invariant: t.Descriptor() == t.New().Descriptor()
@@ -455,12 +448,6 @@
 	// For composite types, this returns an empty, immutable message, list, or map.
 	Zero() Value
 
-	// GoType returns the Go type of the field value.
-	//
-	// Invariants:
-	//	t.GoType() == reflect.TypeOf(t.InterfaceOf(t.New()))
-	GoType() reflect.Type
-
 	// TypeDescriptor returns the extension type descriptor.
 	TypeDescriptor() ExtensionTypeDescriptor
 
@@ -517,11 +504,6 @@
 	// New returns an instance of this enum type with its value set to n.
 	New(n EnumNumber) Enum
 
-	// GoType returns the Go type of the enum value.
-	//
-	// Invariants: t.GoType() == reflect.TypeOf(t.New(0))
-	GoType() reflect.Type
-
 	// Descriptor returns the enum descriptor.
 	//
 	// Invariant: t.Descriptor() == t.New(0).Descriptor()
diff --git a/reflect/protoregistry/registry.go b/reflect/protoregistry/registry.go
index cba713f..4689f6b 100644
--- a/reflect/protoregistry/registry.go
+++ b/reflect/protoregistry/registry.go
@@ -18,7 +18,6 @@
 import (
 	"fmt"
 	"log"
-	"reflect"
 	"strings"
 	"sync"
 
@@ -361,17 +360,8 @@
 	}
 }
 
-// Type is an interface satisfied by protoreflect.EnumType,
-// protoreflect.MessageType, or protoreflect.ExtensionType.
-type Type interface {
-	GoType() reflect.Type
-}
-
-var (
-	_ Type = protoreflect.EnumType(nil)
-	_ Type = protoreflect.MessageType(nil)
-	_ Type = protoreflect.ExtensionType(nil)
-)
+// A Type is a protoreflect.EnumType, protoreflect.MessageType, or protoreflect.ExtensionType.
+type Type interface{}
 
 // MessageTypeResolver is an interface for looking up messages.
 //
diff --git a/reflect/protoregistry/registry_test.go b/reflect/protoregistry/registry_test.go
index cd54f67e..8d70243 100644
--- a/reflect/protoregistry/registry_test.go
+++ b/reflect/protoregistry/registry_test.go
@@ -539,28 +539,32 @@
 		}
 	})
 
-	fullName := func(t preg.Type) pref.FullName {
-		switch t := t.(type) {
-		case pref.EnumType:
-			return t.Descriptor().FullName()
-		case pref.MessageType:
-			return t.Descriptor().FullName()
-		case pref.ExtensionType:
-			return t.TypeDescriptor().FullName()
-		default:
-			panic("invalid type")
-		}
+	sortTypes := cmp.Options{
+		cmpopts.SortSlices(func(x, y pref.EnumType) bool {
+			return x.Descriptor().FullName() < y.Descriptor().FullName()
+		}),
+		cmpopts.SortSlices(func(x, y pref.MessageType) bool {
+			return x.Descriptor().FullName() < y.Descriptor().FullName()
+		}),
+		cmpopts.SortSlices(func(x, y pref.ExtensionType) bool {
+			return x.TypeDescriptor().FullName() < y.TypeDescriptor().FullName()
+		}),
 	}
-	sortTypes := cmpopts.SortSlices(func(x, y preg.Type) bool {
-		return fullName(x) < fullName(y)
-	})
-	compare := cmp.Comparer(func(x, y preg.Type) bool {
-		return x == y
-	})
+	compare := cmp.Options{
+		cmp.Comparer(func(x, y pref.EnumType) bool {
+			return x == y
+		}),
+		cmp.Comparer(func(x, y pref.ExtensionType) bool {
+			return x == y
+		}),
+		cmp.Comparer(func(x, y pref.MessageType) bool {
+			return x == y
+		}),
+	}
 
 	t.Run("RangeEnums", func(t *testing.T) {
-		want := []preg.Type{et1}
-		var got []preg.Type
+		want := []pref.EnumType{et1}
+		var got []pref.EnumType
 		var gotCnt int
 		wantCnt := registry.NumEnums()
 		registry.RangeEnums(func(et pref.EnumType) bool {
@@ -578,8 +582,8 @@
 	})
 
 	t.Run("RangeMessages", func(t *testing.T) {
-		want := []preg.Type{mt1}
-		var got []preg.Type
+		want := []pref.MessageType{mt1}
+		var got []pref.MessageType
 		var gotCnt int
 		wantCnt := registry.NumMessages()
 		registry.RangeMessages(func(mt pref.MessageType) bool {
@@ -597,8 +601,8 @@
 	})
 
 	t.Run("RangeExtensions", func(t *testing.T) {
-		want := []preg.Type{xt1, xt2}
-		var got []preg.Type
+		want := []pref.ExtensionType{xt1, xt2}
+		var got []pref.ExtensionType
 		var gotCnt int
 		wantCnt := registry.NumExtensions()
 		registry.RangeExtensions(func(xt pref.ExtensionType) bool {
@@ -616,8 +620,8 @@
 	})
 
 	t.Run("RangeExtensionsByMessage", func(t *testing.T) {
-		want := []preg.Type{xt1, xt2}
-		var got []preg.Type
+		want := []pref.ExtensionType{xt1, xt2}
+		var got []pref.ExtensionType
 		var gotCnt int
 		wantCnt := registry.NumExtensionsByMessage("testprotos.Message1")
 		registry.RangeExtensionsByMessage("testprotos.Message1", func(xt pref.ExtensionType) bool {
diff --git a/types/dynamicpb/dynamic.go b/types/dynamicpb/dynamic.go
index 48d1830..036a92c 100644
--- a/types/dynamicpb/dynamic.go
+++ b/types/dynamicpb/dynamic.go
@@ -7,7 +7,6 @@
 
 import (
 	"math"
-	"reflect"
 
 	"google.golang.org/protobuf/internal/errors"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
@@ -285,7 +284,6 @@
 
 func (mt messageType) New() pref.Message                  { return NewMessage(mt.desc) }
 func (mt messageType) Zero() pref.Message                 { return NewMessage(mt.desc) }
-func (mt messageType) GoType() reflect.Type               { return reflect.TypeOf((*Message)(nil)) }
 func (mt messageType) Descriptor() pref.MessageDescriptor { return mt.desc }
 
 type emptyList struct {
@@ -559,10 +557,6 @@
 	}
 }
 
-func (xt extensionType) GoType() reflect.Type {
-	return reflect.TypeOf(xt.InterfaceOf(xt.New()))
-}
-
 func (xt extensionType) TypeDescriptor() pref.ExtensionTypeDescriptor {
 	return xt.desc
 }