reflect/protoreflect: add Descriptor specific methods

Added methods:
	Enum.Descriptor
	Message.Descriptor
	EnumType.Descriptor
	MessageType.Descriptor
	ExtensionType.Descriptor
	Message.New

All functionality is switched over to use those methods instead of
implicitly relying on the fact that {Enum,Message}Type implicitly
implement the associated descriptor interface.

This CL does not yet remove {Enum,Message}.Type or prevent
{Enum,Message,Extension}Type from implementating a descriptor.
That is a subsequent CL.

The Message.New method is also added to replace functionality
that will be lost when the Type methods are removed.

Change-Id: I7fefde1673bbd40bfdac489aca05cec9a6c98eb1
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/174918
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Herbie Ong <herbie@google.com>
diff --git a/internal/fileinit/desc_lazy.go b/internal/fileinit/desc_lazy.go
index be3ebeb..7382d80 100644
--- a/internal/fileinit/desc_lazy.go
+++ b/internal/fileinit/desc_lazy.go
@@ -116,6 +116,7 @@
 		case pref.Optional:
 			switch xd.lazy.kind {
 			case pref.EnumKind:
+				et := pimpl.Export{}.EnumTypeOf(reflect.Zero(typ).Interface())
 				xd.lazy.typ = typ
 				xd.lazy.new = func() pref.Value {
 					return xd.lazy.defVal.get()
@@ -125,12 +126,13 @@
 					return pref.ValueOf(ev.Number())
 				}
 				xd.lazy.interfaceOf = func(pv pref.Value) interface{} {
-					return xd.lazy.enumType.New(pv.Enum())
+					return et.New(pv.Enum())
 				}
 			case pref.MessageKind, pref.GroupKind:
+				mt := pimpl.Export{}.MessageTypeOf(reflect.Zero(typ).Interface())
 				xd.lazy.typ = typ
 				xd.lazy.new = func() pref.Value {
-					return pref.ValueOf(xd.lazy.messageType.New())
+					return pref.ValueOf(mt.New())
 				}
 				xd.lazy.valueOf = func(v interface{}) pref.Value {
 					mv := v.(pref.ProtoMessage).ProtoReflect()
@@ -171,9 +173,9 @@
 		// Resolve extension field dependency.
 		switch xd.lazy.kind {
 		case pref.EnumKind:
-			xd.lazy.enumType = file.popEnumDependency().(pref.EnumType)
+			xd.lazy.enumType = file.popEnumDependency()
 		case pref.MessageKind, pref.GroupKind:
-			xd.lazy.messageType = file.popMessageDependency().(pref.MessageType)
+			xd.lazy.messageType = file.popMessageDependency()
 		}
 		xd.lazy.defVal.lazyInit(xd.lazy.kind, file.enumValuesOf(xd.lazy.enumType))
 	}
@@ -241,7 +243,7 @@
 	if depIdx < len(fd.allEnums)+len(fd.allMessages) {
 		return &fd.allEnums[depIdx]
 	} else {
-		return pimpl.Export{}.EnumTypeOf(fd.GoTypes[depIdx])
+		return pimpl.Export{}.EnumDescriptorOf(fd.GoTypes[depIdx])
 	}
 }
 
@@ -250,7 +252,7 @@
 	if depIdx < len(fd.allEnums)+len(fd.allMessages) {
 		return fd.allMessages[depIdx-len(fd.allEnums)].asDesc()
 	} else {
-		return pimpl.Export{}.MessageTypeOf(fd.GoTypes[depIdx])
+		return pimpl.Export{}.MessageDescriptorOf(fd.GoTypes[depIdx])
 	}
 }