reflect/prototype: initial commit

Add the prototype package which provides constructors for
protoreflect.{Enum,Message,Extension}Type.

Switch all usages of the internal/prototype equivalent to the new package.
Switch all custom implementions of {Enum,Message}Type to the new package.

Change-Id: Ia9dae6fed4f2b90e55c123627044a7faf098c4b1
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/178438
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/internal/legacy/enum.go b/internal/legacy/enum.go
index d750f1e..d38aa8c 100644
--- a/internal/legacy/enum.go
+++ b/internal/legacy/enum.go
@@ -13,6 +13,7 @@
 	ptype "google.golang.org/protobuf/internal/prototype"
 	pvalue "google.golang.org/protobuf/internal/value"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/reflect/prototype"
 )
 
 // wrapEnum wraps v as a protoreflect.Enum,
@@ -33,16 +34,20 @@
 	}
 
 	// Slow-path: derive enum descriptor and initialize EnumType.
+	var et pref.EnumType
 	var m sync.Map // map[protoreflect.EnumNumber]proto.Enum
 	ed := LoadEnumDesc(t)
-	et := ptype.GoEnum(ed, func(et pref.EnumType, n pref.EnumNumber) pref.Enum {
-		if e, ok := m.Load(n); ok {
-			return e.(pref.Enum)
-		}
-		e := &enumWrapper{num: n, pbTyp: et, goTyp: t}
-		m.Store(n, e)
-		return e
-	})
+	et = &prototype.Enum{
+		EnumDescriptor: ed,
+		NewEnum: func(n pref.EnumNumber) pref.Enum {
+			if e, ok := m.Load(n); ok {
+				return e.(pref.Enum)
+			}
+			e := &enumWrapper{num: n, pbTyp: et, goTyp: t}
+			m.Store(n, e)
+			return e
+		},
+	}
 	if et, ok := enumTypeCache.LoadOrStore(t, et); ok {
 		return et.(pref.EnumType)
 	}