Kaynağa Gözat

internal/impl: move legacy files into impl

The internal/legacy package was originally separated out from internal/impl
to avoid a cyclic dependency on descriptor proto. However, the dependency
that legacy has on descriptor has long been dropped such that we can
now merge the two packages together again.

All legacy related logic are in a file with a legacy prefix.

Change-Id: I2424fc0f50721696ad06fa7cebb9bdd0babea13c
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/178542
Reviewed-by: Damien Neil <dneil@google.com>
Joe Tsai 6 yıl önce
ebeveyn
işleme
21ade498bd

+ 17 - 6
internal/impl/export.go → internal/impl/api_export.go

@@ -11,6 +11,7 @@ import (
 	"google.golang.org/protobuf/encoding/prototext"
 	"google.golang.org/protobuf/encoding/prototext"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
 	"google.golang.org/protobuf/reflect/prototype"
 	"google.golang.org/protobuf/reflect/prototype"
+	piface "google.golang.org/protobuf/runtime/protoiface"
 )
 )
 
 
 // Export is a zero-length named type that exists only to export a set of
 // Export is a zero-length named type that exists only to export a set of
@@ -26,7 +27,7 @@ func (Export) EnumOf(e enum) pref.Enum {
 	if ev, ok := e.(pref.Enum); ok {
 	if ev, ok := e.(pref.Enum); ok {
 		return ev
 		return ev
 	}
 	}
-	return legacyWrapper.EnumOf(e)
+	return legacyWrapEnum(reflect.ValueOf(e))
 }
 }
 
 
 // EnumTypeOf returns the protoreflect.EnumType for e.
 // EnumTypeOf returns the protoreflect.EnumType for e.
@@ -39,7 +40,7 @@ func (Export) EnumTypeOf(e enum) pref.EnumType {
 			},
 			},
 		}
 		}
 	}
 	}
-	return legacyWrapper.EnumTypeOf(e)
+	return legacyLoadEnumType(reflect.TypeOf(e))
 }
 }
 
 
 // EnumDescriptorOf returns the protoreflect.EnumDescriptor for e.
 // EnumDescriptorOf returns the protoreflect.EnumDescriptor for e.
@@ -47,7 +48,7 @@ func (Export) EnumDescriptorOf(e enum) pref.EnumDescriptor {
 	if ev, ok := e.(pref.Enum); ok {
 	if ev, ok := e.(pref.Enum); ok {
 		return ev.Descriptor()
 		return ev.Descriptor()
 	}
 	}
-	return legacyWrapper.EnumDescriptorOf(e)
+	return LegacyLoadEnumDesc(reflect.TypeOf(e))
 }
 }
 
 
 // EnumStringOf returns the enum value as a string, either as the name if
 // EnumStringOf returns the enum value as a string, either as the name if
@@ -69,7 +70,7 @@ func (Export) MessageOf(m message) pref.Message {
 	if mv, ok := m.(pref.ProtoMessage); ok {
 	if mv, ok := m.(pref.ProtoMessage); ok {
 		return mv.ProtoReflect()
 		return mv.ProtoReflect()
 	}
 	}
-	return legacyWrapper.MessageOf(m)
+	return legacyWrapMessage(reflect.ValueOf(m)).ProtoReflect()
 }
 }
 
 
 // MessageTypeOf returns the protoreflect.MessageType for m.
 // MessageTypeOf returns the protoreflect.MessageType for m.
@@ -82,7 +83,7 @@ func (Export) MessageTypeOf(m message) pref.MessageType {
 			},
 			},
 		}
 		}
 	}
 	}
-	return legacyWrapper.MessageTypeOf(m)
+	return legacyLoadMessageInfo(reflect.TypeOf(m)).PBType
 }
 }
 
 
 // MessageDescriptorOf returns the protoreflect.MessageDescriptor for m.
 // MessageDescriptorOf returns the protoreflect.MessageDescriptor for m.
@@ -90,7 +91,7 @@ func (Export) MessageDescriptorOf(m message) pref.MessageDescriptor {
 	if mv, ok := m.(pref.ProtoMessage); ok {
 	if mv, ok := m.(pref.ProtoMessage); ok {
 		return mv.ProtoReflect().Descriptor()
 		return mv.ProtoReflect().Descriptor()
 	}
 	}
-	return legacyWrapper.MessageDescriptorOf(m)
+	return LegacyLoadMessageDesc(reflect.TypeOf(m))
 }
 }
 
 
 // MessageStringOf returns the message value as a string,
 // MessageStringOf returns the message value as a string,
@@ -99,3 +100,13 @@ func (Export) MessageStringOf(m pref.ProtoMessage) string {
 	b, _ := prototext.MarshalOptions{AllowPartial: true}.Marshal(m)
 	b, _ := prototext.MarshalOptions{AllowPartial: true}.Marshal(m)
 	return string(b)
 	return string(b)
 }
 }
+
+// ExtensionDescFromType returns the legacy protoiface.ExtensionDescV1 for t.
+func (Export) ExtensionDescFromType(t pref.ExtensionType) *piface.ExtensionDescV1 {
+	return legacyExtensionDescFromType(t)
+}
+
+// ExtensionTypeFromDesc returns the v2 protoreflect.ExtensionType for d.
+func (Export) ExtensionTypeFromDesc(d *piface.ExtensionDescV1) pref.ExtensionType {
+	return legacyExtensionTypeFromDesc(d)
+}

+ 4 - 4
internal/impl/encode_field.go

@@ -82,11 +82,11 @@ func makeMessageFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCode
 	} else {
 	} else {
 		return pointerCoderFuncs{
 		return pointerCoderFuncs{
 			size: func(p pointer, tagsize int, opts marshalOptions) int {
 			size: func(p pointer, tagsize int, opts marshalOptions) int {
-				m := legacyWrapper.MessageOf(p.AsValueOf(ft).Elem().Interface()).Interface()
+				m := legacyWrapMessage(p.AsValueOf(ft).Elem())
 				return sizeMessage(m, tagsize, opts)
 				return sizeMessage(m, tagsize, opts)
 			},
 			},
 			marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
 			marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
-				m := legacyWrapper.MessageOf(p.AsValueOf(ft).Elem().Interface()).Interface()
+				m := legacyWrapMessage(p.AsValueOf(ft).Elem())
 				return appendMessage(b, m, wiretag, opts)
 				return appendMessage(b, m, wiretag, opts)
 			},
 			},
 		}
 		}
@@ -141,11 +141,11 @@ func makeGroupFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderF
 	} else {
 	} else {
 		return pointerCoderFuncs{
 		return pointerCoderFuncs{
 			size: func(p pointer, tagsize int, opts marshalOptions) int {
 			size: func(p pointer, tagsize int, opts marshalOptions) int {
-				m := legacyWrapper.MessageOf(p.AsValueOf(ft).Elem().Interface()).Interface()
+				m := legacyWrapMessage(p.AsValueOf(ft).Elem())
 				return sizeGroup(m, tagsize, opts)
 				return sizeGroup(m, tagsize, opts)
 			},
 			},
 			marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
 			marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
-				m := legacyWrapper.MessageOf(p.AsValueOf(ft).Elem().Interface()).Interface()
+				m := legacyWrapMessage(p.AsValueOf(ft).Elem())
 				return appendGroup(b, m, wiretag, opts)
 				return appendGroup(b, m, wiretag, opts)
 			},
 			},
 		}
 		}

+ 29 - 29
internal/legacy/enum.go → internal/impl/legacy_enum.go

@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 // license that can be found in the LICENSE file.
 
 
-package legacy
+package impl
 
 
 import (
 import (
 	"fmt"
 	"fmt"
@@ -16,85 +16,85 @@ import (
 	"google.golang.org/protobuf/reflect/prototype"
 	"google.golang.org/protobuf/reflect/prototype"
 )
 )
 
 
-// wrapEnum wraps v as a protoreflect.Enum,
+// legacyWrapEnum wraps v as a protoreflect.Enum,
 // where v must be a int32 kind and not implement the v2 API already.
 // where v must be a int32 kind and not implement the v2 API already.
-func wrapEnum(v reflect.Value) pref.Enum {
-	et := loadEnumType(v.Type())
+func legacyWrapEnum(v reflect.Value) pref.Enum {
+	et := legacyLoadEnumType(v.Type())
 	return et.New(pref.EnumNumber(v.Int()))
 	return et.New(pref.EnumNumber(v.Int()))
 }
 }
 
 
-var enumTypeCache sync.Map // map[reflect.Type]protoreflect.EnumType
+var legacyEnumTypeCache sync.Map // map[reflect.Type]protoreflect.EnumType
 
 
-// loadEnumType dynamically loads a protoreflect.EnumType for t,
+// legacyLoadEnumType dynamically loads a protoreflect.EnumType for t,
 // where t must be an int32 kind and not implement the v2 API already.
 // where t must be an int32 kind and not implement the v2 API already.
-func loadEnumType(t reflect.Type) pref.EnumType {
+func legacyLoadEnumType(t reflect.Type) pref.EnumType {
 	// Fast-path: check if a EnumType is cached for this concrete type.
 	// Fast-path: check if a EnumType is cached for this concrete type.
-	if et, ok := enumTypeCache.Load(t); ok {
+	if et, ok := legacyEnumTypeCache.Load(t); ok {
 		return et.(pref.EnumType)
 		return et.(pref.EnumType)
 	}
 	}
 
 
 	// Slow-path: derive enum descriptor and initialize EnumType.
 	// Slow-path: derive enum descriptor and initialize EnumType.
 	var et pref.EnumType
 	var et pref.EnumType
 	var m sync.Map // map[protoreflect.EnumNumber]proto.Enum
 	var m sync.Map // map[protoreflect.EnumNumber]proto.Enum
-	ed := LoadEnumDesc(t)
+	ed := LegacyLoadEnumDesc(t)
 	et = &prototype.Enum{
 	et = &prototype.Enum{
 		EnumDescriptor: ed,
 		EnumDescriptor: ed,
 		NewEnum: func(n pref.EnumNumber) pref.Enum {
 		NewEnum: func(n pref.EnumNumber) pref.Enum {
 			if e, ok := m.Load(n); ok {
 			if e, ok := m.Load(n); ok {
 				return e.(pref.Enum)
 				return e.(pref.Enum)
 			}
 			}
-			e := &enumWrapper{num: n, pbTyp: et, goTyp: t}
+			e := &legacyEnumWrapper{num: n, pbTyp: et, goTyp: t}
 			m.Store(n, e)
 			m.Store(n, e)
 			return e
 			return e
 		},
 		},
 	}
 	}
-	if et, ok := enumTypeCache.LoadOrStore(t, et); ok {
+	if et, ok := legacyEnumTypeCache.LoadOrStore(t, et); ok {
 		return et.(pref.EnumType)
 		return et.(pref.EnumType)
 	}
 	}
 	return et
 	return et
 }
 }
 
 
-type enumWrapper struct {
+type legacyEnumWrapper struct {
 	num   pref.EnumNumber
 	num   pref.EnumNumber
 	pbTyp pref.EnumType
 	pbTyp pref.EnumType
 	goTyp reflect.Type
 	goTyp reflect.Type
 }
 }
 
 
 // TODO: Remove this.
 // TODO: Remove this.
-func (e *enumWrapper) Type() pref.EnumType {
+func (e *legacyEnumWrapper) Type() pref.EnumType {
 	return e.pbTyp
 	return e.pbTyp
 }
 }
-func (e *enumWrapper) Descriptor() pref.EnumDescriptor {
+func (e *legacyEnumWrapper) Descriptor() pref.EnumDescriptor {
 	return e.pbTyp.Descriptor()
 	return e.pbTyp.Descriptor()
 }
 }
-func (e *enumWrapper) Number() pref.EnumNumber {
+func (e *legacyEnumWrapper) Number() pref.EnumNumber {
 	return e.num
 	return e.num
 }
 }
-func (e *enumWrapper) ProtoReflect() pref.Enum {
+func (e *legacyEnumWrapper) ProtoReflect() pref.Enum {
 	return e
 	return e
 }
 }
-func (e *enumWrapper) ProtoUnwrap() interface{} {
+func (e *legacyEnumWrapper) ProtoUnwrap() interface{} {
 	v := reflect.New(e.goTyp).Elem()
 	v := reflect.New(e.goTyp).Elem()
 	v.SetInt(int64(e.num))
 	v.SetInt(int64(e.num))
 	return v.Interface()
 	return v.Interface()
 }
 }
 
 
 var (
 var (
-	_ pref.Enum        = (*enumWrapper)(nil)
-	_ pvalue.Unwrapper = (*enumWrapper)(nil)
+	_ pref.Enum        = (*legacyEnumWrapper)(nil)
+	_ pvalue.Unwrapper = (*legacyEnumWrapper)(nil)
 )
 )
 
 
-var enumDescCache sync.Map // map[reflect.Type]protoreflect.EnumDescriptor
+var legacyEnumDescCache sync.Map // map[reflect.Type]protoreflect.EnumDescriptor
 
 
-var enumNumberType = reflect.TypeOf(pref.EnumNumber(0))
+var legacyEnumNumberType = reflect.TypeOf(pref.EnumNumber(0))
 
 
-// LoadEnumDesc returns an EnumDescriptor derived from the Go type,
+// LegacyLoadEnumDesc returns an EnumDescriptor derived from the Go type,
 // which must be an int32 kind and not implement the v2 API already.
 // which must be an int32 kind and not implement the v2 API already.
 //
 //
 // This is exported for testing purposes.
 // This is exported for testing purposes.
-func LoadEnumDesc(t reflect.Type) pref.EnumDescriptor {
+func LegacyLoadEnumDesc(t reflect.Type) pref.EnumDescriptor {
 	// Fast-path: check if an EnumDescriptor is cached for this concrete type.
 	// Fast-path: check if an EnumDescriptor is cached for this concrete type.
-	if ed, ok := enumDescCache.Load(t); ok {
+	if ed, ok := legacyEnumDescCache.Load(t); ok {
 		return ed.(pref.EnumDescriptor)
 		return ed.(pref.EnumDescriptor)
 	}
 	}
 
 
@@ -102,7 +102,7 @@ func LoadEnumDesc(t reflect.Type) pref.EnumDescriptor {
 	if t.Kind() != reflect.Int32 || t.PkgPath() == "" {
 	if t.Kind() != reflect.Int32 || t.PkgPath() == "" {
 		panic(fmt.Sprintf("got %v, want named int32 kind", t))
 		panic(fmt.Sprintf("got %v, want named int32 kind", t))
 	}
 	}
-	if t == enumNumberType {
+	if t == legacyEnumNumberType {
 		panic(fmt.Sprintf("cannot be %v", t))
 		panic(fmt.Sprintf("cannot be %v", t))
 	}
 	}
 
 
@@ -114,7 +114,7 @@ func LoadEnumDesc(t reflect.Type) pref.EnumDescriptor {
 	}
 	}
 	if ed, ok := ev.(enumV1); ok {
 	if ed, ok := ev.(enumV1); ok {
 		b, idxs := ed.EnumDescriptor()
 		b, idxs := ed.EnumDescriptor()
-		fd := loadFileDesc(b)
+		fd := legacyLoadFileDesc(b)
 
 
 		// Derive syntax.
 		// Derive syntax.
 		switch fd.GetSyntax() {
 		switch fd.GetSyntax() {
@@ -125,7 +125,7 @@ func LoadEnumDesc(t reflect.Type) pref.EnumDescriptor {
 		}
 		}
 
 
 		// Derive the full name and correct enum descriptor.
 		// Derive the full name and correct enum descriptor.
-		var ed *enumDescriptorProto
+		var ed *legacyEnumDescriptorProto
 		e.FullName = pref.FullName(fd.GetPackage())
 		e.FullName = pref.FullName(fd.GetPackage())
 		if len(idxs) == 1 {
 		if len(idxs) == 1 {
 			ed = fd.EnumType[idxs[0]]
 			ed = fd.EnumType[idxs[0]]
@@ -160,7 +160,7 @@ func LoadEnumDesc(t reflect.Type) pref.EnumDescriptor {
 		// most operations continue to work. For example, prototext and protojson
 		// most operations continue to work. For example, prototext and protojson
 		// will be unable to parse a message with an enum value by name.
 		// will be unable to parse a message with an enum value by name.
 		e.Syntax = pref.Proto2
 		e.Syntax = pref.Proto2
-		e.FullName = deriveFullName(t)
+		e.FullName = legacyDeriveFullName(t)
 		e.Values = []ptype.EnumValue{{Name: "INVALID", Number: math.MinInt32}}
 		e.Values = []ptype.EnumValue{{Name: "INVALID", Number: math.MinInt32}}
 	}
 	}
 
 
@@ -168,7 +168,7 @@ func LoadEnumDesc(t reflect.Type) pref.EnumDescriptor {
 	if err != nil {
 	if err != nil {
 		panic(err)
 		panic(err)
 	}
 	}
-	if ed, ok := enumDescCache.LoadOrStore(t, ed); ok {
+	if ed, ok := legacyEnumDescCache.LoadOrStore(t, ed); ok {
 		return ed.(pref.EnumDescriptor)
 		return ed.(pref.EnumDescriptor)
 	}
 	}
 	return ed
 	return ed

+ 33 - 33
internal/legacy/extension.go → internal/impl/legacy_extension.go

@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 // license that can be found in the LICENSE file.
 
 
-package legacy
+package impl
 
 
 import (
 import (
 	"fmt"
 	"fmt"
@@ -11,7 +11,6 @@ import (
 
 
 	"google.golang.org/protobuf/internal/descfmt"
 	"google.golang.org/protobuf/internal/descfmt"
 	ptag "google.golang.org/protobuf/internal/encoding/tag"
 	ptag "google.golang.org/protobuf/internal/encoding/tag"
-	pimpl "google.golang.org/protobuf/internal/impl"
 	ptype "google.golang.org/protobuf/internal/prototype"
 	ptype "google.golang.org/protobuf/internal/prototype"
 	pvalue "google.golang.org/protobuf/internal/value"
 	pvalue "google.golang.org/protobuf/internal/value"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
@@ -20,9 +19,9 @@ import (
 	piface "google.golang.org/protobuf/runtime/protoiface"
 	piface "google.golang.org/protobuf/runtime/protoiface"
 )
 )
 
 
-// extensionDescKey is a comparable version of protoiface.ExtensionDescV1
+// legacyExtensionDescKey is a comparable version of protoiface.ExtensionDescV1
 // suitable for use as a key in a map.
 // suitable for use as a key in a map.
-type extensionDescKey struct {
+type legacyExtensionDescKey struct {
 	typeV2        pref.ExtensionType
 	typeV2        pref.ExtensionType
 	extendedType  reflect.Type
 	extendedType  reflect.Type
 	extensionType reflect.Type
 	extensionType reflect.Type
@@ -32,8 +31,8 @@ type extensionDescKey struct {
 	filename      string
 	filename      string
 }
 }
 
 
-func extensionDescKeyOf(d *piface.ExtensionDescV1) extensionDescKey {
-	return extensionDescKey{
+func legacyExtensionDescKeyOf(d *piface.ExtensionDescV1) legacyExtensionDescKey {
+	return legacyExtensionDescKey{
 		d.Type,
 		d.Type,
 		reflect.TypeOf(d.ExtendedType),
 		reflect.TypeOf(d.ExtendedType),
 		reflect.TypeOf(d.ExtensionType),
 		reflect.TypeOf(d.ExtensionType),
@@ -42,13 +41,13 @@ func extensionDescKeyOf(d *piface.ExtensionDescV1) extensionDescKey {
 }
 }
 
 
 var (
 var (
-	extensionTypeCache sync.Map // map[extensionDescKey]protoreflect.ExtensionType
-	extensionDescCache sync.Map // map[protoreflect.ExtensionType]*protoiface.ExtensionDescV1
+	legacyExtensionTypeCache sync.Map // map[legacyExtensionDescKey]protoreflect.ExtensionType
+	legacyExtensionDescCache sync.Map // map[protoreflect.ExtensionType]*protoiface.ExtensionDescV1
 )
 )
 
 
-// extensionDescFromType converts a v2 protoreflect.ExtensionType to a
+// legacyExtensionDescFromType converts a v2 protoreflect.ExtensionType to a
 // protoiface.ExtensionDescV1. The returned ExtensionDesc must not be mutated.
 // protoiface.ExtensionDescV1. The returned ExtensionDesc must not be mutated.
-func extensionDescFromType(xt pref.ExtensionType) *piface.ExtensionDescV1 {
+func legacyExtensionDescFromType(xt pref.ExtensionType) *piface.ExtensionDescV1 {
 	// Fast-path: check whether an extension desc is already nested within.
 	// Fast-path: check whether an extension desc is already nested within.
 	if xt, ok := xt.(interface {
 	if xt, ok := xt.(interface {
 		ProtoLegacyExtensionDesc() *piface.ExtensionDescV1
 		ProtoLegacyExtensionDesc() *piface.ExtensionDescV1
@@ -60,7 +59,7 @@ func extensionDescFromType(xt pref.ExtensionType) *piface.ExtensionDescV1 {
 
 
 	// Fast-path: check the cache for whether this ExtensionType has already
 	// Fast-path: check the cache for whether this ExtensionType has already
 	// been converted to a legacy descriptor.
 	// been converted to a legacy descriptor.
-	if d, ok := extensionDescCache.Load(xt); ok {
+	if d, ok := legacyExtensionDescCache.Load(xt); ok {
 		return d.(*piface.ExtensionDescV1)
 		return d.(*piface.ExtensionDescV1)
 	}
 	}
 
 
@@ -113,7 +112,7 @@ func extensionDescFromType(xt pref.ExtensionType) *piface.ExtensionDescV1 {
 		}
 		}
 		if ed, ok := reflect.Zero(t).Interface().(enumV1); ok && protoPkg == "" {
 		if ed, ok := reflect.Zero(t).Interface().(enumV1); ok && protoPkg == "" {
 			b, _ := ed.EnumDescriptor()
 			b, _ := ed.EnumDescriptor()
-			protoPkg = loadFileDesc(b).GetPackage()
+			protoPkg = legacyLoadFileDesc(b).GetPackage()
 		}
 		}
 
 
 		if protoPkg != "" {
 		if protoPkg != "" {
@@ -137,17 +136,17 @@ func extensionDescFromType(xt pref.ExtensionType) *piface.ExtensionDescV1 {
 		Tag:           ptag.Marshal(xt.Descriptor(), enumName),
 		Tag:           ptag.Marshal(xt.Descriptor(), enumName),
 		Filename:      filename,
 		Filename:      filename,
 	}
 	}
-	if d, ok := extensionDescCache.LoadOrStore(xt, d); ok {
+	if d, ok := legacyExtensionDescCache.LoadOrStore(xt, d); ok {
 		return d.(*piface.ExtensionDescV1)
 		return d.(*piface.ExtensionDescV1)
 	}
 	}
 	return d
 	return d
 }
 }
 
 
-// extensionTypeFromDesc converts a protoiface.ExtensionDescV1 to a
+// legacyExtensionTypeFromDesc converts a protoiface.ExtensionDescV1 to a
 // v2 protoreflect.ExtensionType. The returned descriptor type takes ownership
 // v2 protoreflect.ExtensionType. The returned descriptor type takes ownership
 // of the input extension desc. The input must not be mutated so long as the
 // of the input extension desc. The input must not be mutated so long as the
 // returned type is still in use.
 // returned type is still in use.
-func extensionTypeFromDesc(d *piface.ExtensionDescV1) pref.ExtensionType {
+func legacyExtensionTypeFromDesc(d *piface.ExtensionDescV1) pref.ExtensionType {
 	// Fast-path: check whether an extension type is already nested within.
 	// Fast-path: check whether an extension type is already nested within.
 	if d.Type != nil {
 	if d.Type != nil {
 		return d.Type
 		return d.Type
@@ -155,8 +154,8 @@ func extensionTypeFromDesc(d *piface.ExtensionDescV1) pref.ExtensionType {
 
 
 	// Fast-path: check the cache for whether this ExtensionType has already
 	// Fast-path: check the cache for whether this ExtensionType has already
 	// been converted from a legacy descriptor.
 	// been converted from a legacy descriptor.
-	dk := extensionDescKeyOf(d)
-	if t, ok := extensionTypeCache.Load(dk); ok {
+	dk := legacyExtensionDescKeyOf(d)
+	if t, ok := legacyExtensionTypeCache.Load(dk); ok {
 		return t.(pref.ExtensionType)
 		return t.(pref.ExtensionType)
 	}
 	}
 
 
@@ -177,13 +176,13 @@ func extensionTypeFromDesc(d *piface.ExtensionDescV1) pref.ExtensionType {
 		if e, ok := reflect.Zero(t).Interface().(pref.Enum); ok {
 		if e, ok := reflect.Zero(t).Interface().(pref.Enum); ok {
 			ed = e.Descriptor()
 			ed = e.Descriptor()
 		} else {
 		} else {
-			ed = LoadEnumDesc(t)
+			ed = LegacyLoadEnumDesc(t)
 		}
 		}
 	case pref.MessageKind, pref.GroupKind:
 	case pref.MessageKind, pref.GroupKind:
 		if m, ok := reflect.Zero(t).Interface().(pref.ProtoMessage); ok {
 		if m, ok := reflect.Zero(t).Interface().(pref.ProtoMessage); ok {
 			md = m.ProtoReflect().Descriptor()
 			md = m.ProtoReflect().Descriptor()
 		} else {
 		} else {
-			md = LoadMessageDesc(t)
+			md = LegacyLoadMessageDesc(t)
 		}
 		}
 	}
 	}
 	xd, err := ptype.NewExtension(&ptype.StandaloneExtension{
 	xd, err := ptype.NewExtension(&ptype.StandaloneExtension{
@@ -195,26 +194,27 @@ func extensionTypeFromDesc(d *piface.ExtensionDescV1) pref.ExtensionType {
 		Options:      f.Options,
 		Options:      f.Options,
 		EnumType:     ed,
 		EnumType:     ed,
 		MessageType:  md,
 		MessageType:  md,
-		ExtendedType: pimpl.Export{}.MessageDescriptorOf(d.ExtendedType),
+		ExtendedType: Export{}.MessageDescriptorOf(d.ExtendedType),
 	})
 	})
 	if err != nil {
 	if err != nil {
 		panic(err)
 		panic(err)
 	}
 	}
-	xt := ExtensionTypeOf(xd, t)
+	xt := LegacyExtensionTypeOf(xd, t)
 
 
 	// Cache the conversion for both directions.
 	// Cache the conversion for both directions.
-	extensionDescCache.LoadOrStore(xt, d)
-	if xt, ok := extensionTypeCache.LoadOrStore(dk, xt); ok {
+	legacyExtensionDescCache.LoadOrStore(xt, d)
+	if xt, ok := legacyExtensionTypeCache.LoadOrStore(dk, xt); ok {
 		return xt.(pref.ExtensionType)
 		return xt.(pref.ExtensionType)
 	}
 	}
 	return xt
 	return xt
 }
 }
 
 
-// ExtensionTypeOf returns a protoreflect.ExtensionType where the type of the
-// field is t. The type t must be provided if the field is an enum or message.
+// LegacyExtensionTypeOf returns a protoreflect.ExtensionType where the
+// element type of the field is t. The type t must be provided if the field
+// is an enum or message.
 //
 //
 // This is exported for testing purposes.
 // This is exported for testing purposes.
-func ExtensionTypeOf(xd pref.ExtensionDescriptor, t reflect.Type) pref.ExtensionType {
+func LegacyExtensionTypeOf(xd pref.ExtensionDescriptor, t reflect.Type) pref.ExtensionType {
 	var conv pvalue.Converter
 	var conv pvalue.Converter
 	var isLegacy bool
 	var isLegacy bool
 	xt := &prototype.Extension{ExtensionDescriptor: xd}
 	xt := &prototype.Extension{ExtensionDescriptor: xd}
@@ -234,7 +234,7 @@ func ExtensionTypeOf(xd pref.ExtensionDescriptor, t reflect.Type) pref.Extension
 	}
 	}
 
 
 	// Wrap ExtensionType such that GoType presents the legacy Go type.
 	// Wrap ExtensionType such that GoType presents the legacy Go type.
-	xt2 := &extensionType{ExtensionType: xt}
+	xt2 := &legacyExtensionType{ExtensionType: xt}
 	if xd.Cardinality() != pref.Repeated {
 	if xd.Cardinality() != pref.Repeated {
 		xt2.typ = t
 		xt2.typ = t
 		xt2.new = func() pref.Value {
 		xt2.new = func() pref.Value {
@@ -276,7 +276,7 @@ func ExtensionTypeOf(xd pref.ExtensionDescriptor, t reflect.Type) pref.Extension
 	return xt2
 	return xt2
 }
 }
 
 
-type extensionType struct {
+type legacyExtensionType struct {
 	pref.ExtensionType
 	pref.ExtensionType
 	typ         reflect.Type
 	typ         reflect.Type
 	new         func() pref.Value
 	new         func() pref.Value
@@ -284,8 +284,8 @@ type extensionType struct {
 	interfaceOf func(pref.Value) interface{}
 	interfaceOf func(pref.Value) interface{}
 }
 }
 
 
-func (x *extensionType) GoType() reflect.Type                 { return x.typ }
-func (x *extensionType) New() pref.Value                      { return x.new() }
-func (x *extensionType) ValueOf(v interface{}) pref.Value     { return x.valueOf(v) }
-func (x *extensionType) InterfaceOf(v pref.Value) interface{} { return x.interfaceOf(v) }
-func (x *extensionType) Format(s fmt.State, r rune)           { descfmt.FormatDesc(s, r, x.Descriptor()) }
+func (x *legacyExtensionType) GoType() reflect.Type                 { return x.typ }
+func (x *legacyExtensionType) New() pref.Value                      { return x.new() }
+func (x *legacyExtensionType) ValueOf(v interface{}) pref.Value     { return x.valueOf(v) }
+func (x *legacyExtensionType) InterfaceOf(v pref.Value) interface{} { return x.interfaceOf(v) }
+func (x *legacyExtensionType) Format(s fmt.State, r rune)           { descfmt.FormatDesc(s, r, x.Descriptor()) }

+ 16 - 17
internal/legacy/extension_test.go → internal/impl/legacy_extension_test.go

@@ -2,14 +2,13 @@
 // Use of this source code is governed by a BSD-style
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 // license that can be found in the LICENSE file.
 
 
-package legacy_test
+package impl_test
 
 
 import (
 import (
 	"reflect"
 	"reflect"
 	"testing"
 	"testing"
 
 
 	pimpl "google.golang.org/protobuf/internal/impl"
 	pimpl "google.golang.org/protobuf/internal/impl"
-	plegacy "google.golang.org/protobuf/internal/legacy"
 	ptype "google.golang.org/protobuf/internal/prototype"
 	ptype "google.golang.org/protobuf/internal/prototype"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
 	piface "google.golang.org/protobuf/runtime/protoiface"
 	piface "google.golang.org/protobuf/runtime/protoiface"
@@ -17,15 +16,15 @@ import (
 	proto2_20180125 "google.golang.org/protobuf/internal/testprotos/legacy/proto2.v1.0.0-20180125-92554152"
 	proto2_20180125 "google.golang.org/protobuf/internal/testprotos/legacy/proto2.v1.0.0-20180125-92554152"
 )
 )
 
 
-type legacyTestMessage struct {
+type legacyExtendedMessage struct {
 	XXX_unrecognized       []byte
 	XXX_unrecognized       []byte
 	XXX_InternalExtensions map[int32]pimpl.ExtensionFieldV1
 	XXX_InternalExtensions map[int32]pimpl.ExtensionFieldV1
 }
 }
 
 
-func (*legacyTestMessage) Reset()         {}
-func (*legacyTestMessage) String() string { return "" }
-func (*legacyTestMessage) ProtoMessage()  {}
-func (*legacyTestMessage) ExtensionRangeArray() []piface.ExtensionRangeV1 {
+func (*legacyExtendedMessage) Reset()         {}
+func (*legacyExtendedMessage) String() string { return "" }
+func (*legacyExtendedMessage) ProtoMessage()  {}
+func (*legacyExtendedMessage) ExtensionRangeArray() []piface.ExtensionRangeV1 {
 	return []piface.ExtensionRangeV1{{Start: 10000, End: 20000}}
 	return []piface.ExtensionRangeV1{{Start: 10000, End: 20000}}
 }
 }
 
 
@@ -34,23 +33,23 @@ func mustMakeExtensionType(x *ptype.StandaloneExtension, v interface{}) pref.Ext
 	if err != nil {
 	if err != nil {
 		panic(err)
 		panic(err)
 	}
 	}
-	return plegacy.ExtensionTypeOf(xd, reflect.TypeOf(v))
+	return pimpl.LegacyExtensionTypeOf(xd, reflect.TypeOf(v))
 }
 }
 
 
 var (
 var (
-	parentDesc    = pimpl.Export{}.MessageDescriptorOf((*legacyTestMessage)(nil))
-	messageV1Desc = pimpl.Export{}.MessageDescriptorOf((*proto2_20180125.Message_ChildMessage)(nil))
+	extParentDesc    = pimpl.Export{}.MessageDescriptorOf((*legacyExtendedMessage)(nil))
+	extMessageV1Desc = pimpl.Export{}.MessageDescriptorOf((*proto2_20180125.Message_ChildMessage)(nil))
 
 
 	wantType = mustMakeExtensionType(&ptype.StandaloneExtension{
 	wantType = mustMakeExtensionType(&ptype.StandaloneExtension{
 		FullName:     "fizz.buzz.optional_message_v1",
 		FullName:     "fizz.buzz.optional_message_v1",
 		Number:       10007,
 		Number:       10007,
 		Cardinality:  pref.Optional,
 		Cardinality:  pref.Optional,
 		Kind:         pref.MessageKind,
 		Kind:         pref.MessageKind,
-		MessageType:  messageV1Desc,
-		ExtendedType: parentDesc,
+		MessageType:  extMessageV1Desc,
+		ExtendedType: extParentDesc,
 	}, (*proto2_20180125.Message_ChildMessage)(nil))
 	}, (*proto2_20180125.Message_ChildMessage)(nil))
 	wantDesc = &piface.ExtensionDescV1{
 	wantDesc = &piface.ExtensionDescV1{
-		ExtendedType:  (*legacyTestMessage)(nil),
+		ExtendedType:  (*legacyExtendedMessage)(nil),
 		ExtensionType: (*proto2_20180125.Message_ChildMessage)(nil),
 		ExtensionType: (*proto2_20180125.Message_ChildMessage)(nil),
 		Field:         10007,
 		Field:         10007,
 		Name:          "fizz.buzz.optional_message_v1",
 		Name:          "fizz.buzz.optional_message_v1",
@@ -61,14 +60,14 @@ var (
 func BenchmarkConvert(b *testing.B) {
 func BenchmarkConvert(b *testing.B) {
 	b.ReportAllocs()
 	b.ReportAllocs()
 	for i := 0; i < b.N; i++ {
 	for i := 0; i < b.N; i++ {
-		xd := plegacy.Export{}.ExtensionDescFromType(wantType)
-		gotType := plegacy.Export{}.ExtensionTypeFromDesc(xd)
+		xd := pimpl.Export{}.ExtensionDescFromType(wantType)
+		gotType := pimpl.Export{}.ExtensionTypeFromDesc(xd)
 		if gotType != wantType {
 		if gotType != wantType {
 			b.Fatalf("ExtensionType mismatch: got %p, want %p", gotType, wantType)
 			b.Fatalf("ExtensionType mismatch: got %p, want %p", gotType, wantType)
 		}
 		}
 
 
-		xt := plegacy.Export{}.ExtensionTypeFromDesc(wantDesc)
-		gotDesc := plegacy.Export{}.ExtensionDescFromType(xt)
+		xt := pimpl.Export{}.ExtensionTypeFromDesc(wantDesc)
+		gotDesc := pimpl.Export{}.ExtensionDescFromType(xt)
 		if gotDesc != wantDesc {
 		if gotDesc != wantDesc {
 			b.Fatalf("ExtensionDesc mismatch: got %p, want %p", gotDesc, wantDesc)
 			b.Fatalf("ExtensionDesc mismatch: got %p, want %p", gotDesc, wantDesc)
 		}
 		}

+ 9 - 9
internal/legacy/file.go → internal/impl/legacy_file.go

@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 // license that can be found in the LICENSE file.
 
 
-package legacy
+package impl
 
 
 import (
 import (
 	"bytes"
 	"bytes"
@@ -28,18 +28,18 @@ type (
 	}
 	}
 )
 )
 
 
-var fileDescCache sync.Map // map[*byte]*descriptorpb.FileDescriptorProto
+var legacyFileDescCache sync.Map // map[*byte]*descriptorpb.FileDescriptorProto
 
 
-// loadFileDesc unmarshals b as a compressed FileDescriptorProto message.
+// legacyLoadFileDesc unmarshals b as a compressed FileDescriptorProto message.
 //
 //
 // This assumes that b is immutable and that b does not refer to part of a
 // This assumes that b is immutable and that b does not refer to part of a
 // concatenated series of GZIP files (which would require shenanigans that
 // concatenated series of GZIP files (which would require shenanigans that
 // rely on the concatenation properties of both protobufs and GZIP).
 // rely on the concatenation properties of both protobufs and GZIP).
 // File descriptors generated by protoc-gen-go do not rely on that property.
 // File descriptors generated by protoc-gen-go do not rely on that property.
-func loadFileDesc(b []byte) *fileDescriptorProto {
+func legacyLoadFileDesc(b []byte) *legacyFileDescriptorProto {
 	// Fast-path: check whether we already have a cached file descriptor.
 	// Fast-path: check whether we already have a cached file descriptor.
-	if fd, ok := fileDescCache.Load(&b[0]); ok {
-		return fd.(*fileDescriptorProto)
+	if fd, ok := legacyFileDescCache.Load(&b[0]); ok {
+		return fd.(*legacyFileDescriptorProto)
 	}
 	}
 
 
 	// Slow-path: decompress and unmarshal the file descriptor proto.
 	// Slow-path: decompress and unmarshal the file descriptor proto.
@@ -51,9 +51,9 @@ func loadFileDesc(b []byte) *fileDescriptorProto {
 	if err != nil {
 	if err != nil {
 		panic(err)
 		panic(err)
 	}
 	}
-	fd := parseFileDescProto(b)
-	if fd, ok := fileDescCache.LoadOrStore(&b[0], fd); ok {
-		return fd.(*fileDescriptorProto)
+	fd := legacyParseFileDescProto(b)
+	if fd, ok := legacyFileDescCache.LoadOrStore(&b[0], fd); ok {
+		return fd.(*legacyFileDescriptorProto)
 	}
 	}
 	return fd
 	return fd
 }
 }

+ 106 - 106
internal/legacy/file_test.go → internal/impl/legacy_file_test.go

@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 // license that can be found in the LICENSE file.
 
 
-package legacy_test
+package impl_test
 
 
 import (
 import (
 	"bytes"
 	"bytes"
@@ -11,9 +11,9 @@ import (
 	"reflect"
 	"reflect"
 	"testing"
 	"testing"
 
 
-	cmp "github.com/google/go-cmp/cmp"
-	legacy "google.golang.org/protobuf/internal/legacy"
-	pragma "google.golang.org/protobuf/internal/pragma"
+	"github.com/google/go-cmp/cmp"
+	"google.golang.org/protobuf/internal/impl"
+	"google.golang.org/protobuf/internal/pragma"
 	"google.golang.org/protobuf/proto"
 	"google.golang.org/protobuf/proto"
 	pdesc "google.golang.org/protobuf/reflect/protodesc"
 	pdesc "google.golang.org/protobuf/reflect/protodesc"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
@@ -59,343 +59,343 @@ func TestDescriptor(t *testing.T) {
 
 
 	fileDescP2_20160225 := mustLoadFileDesc(new(proto2_20160225.Message).Descriptor())
 	fileDescP2_20160225 := mustLoadFileDesc(new(proto2_20160225.Message).Descriptor())
 	tests = append(tests, []struct{ got, want pref.Descriptor }{{
 	tests = append(tests, []struct{ got, want pref.Descriptor }{{
-		got:  legacy.LoadEnumDesc(reflect.TypeOf(proto2_20160225.SiblingEnum(0))),
+		got:  impl.LegacyLoadEnumDesc(reflect.TypeOf(proto2_20160225.SiblingEnum(0))),
 		want: fileDescP2_20160225.Enums().ByName("SiblingEnum"),
 		want: fileDescP2_20160225.Enums().ByName("SiblingEnum"),
 	}, {
 	}, {
-		got:  legacy.LoadEnumDesc(reflect.TypeOf(proto2_20160225.Message_ChildEnum(0))),
+		got:  impl.LegacyLoadEnumDesc(reflect.TypeOf(proto2_20160225.Message_ChildEnum(0))),
 		want: fileDescP2_20160225.Messages().ByName("Message").Enums().ByName("ChildEnum"),
 		want: fileDescP2_20160225.Messages().ByName("Message").Enums().ByName("ChildEnum"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160225.SiblingMessage))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160225.SiblingMessage))),
 		want: fileDescP2_20160225.Messages().ByName("SiblingMessage"),
 		want: fileDescP2_20160225.Messages().ByName("SiblingMessage"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_ChildMessage))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_ChildMessage))),
 		want: fileDescP2_20160225.Messages().ByName("Message").Messages().ByName("ChildMessage"),
 		want: fileDescP2_20160225.Messages().ByName("Message").Messages().ByName("ChildMessage"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message))),
 		want: fileDescP2_20160225.Messages().ByName("Message"),
 		want: fileDescP2_20160225.Messages().ByName("Message"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_NamedGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_NamedGroup))),
 		want: fileDescP2_20160225.Messages().ByName("Message").Messages().ByName("NamedGroup"),
 		want: fileDescP2_20160225.Messages().ByName("Message").Messages().ByName("NamedGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_OptionalGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_OptionalGroup))),
 		want: fileDescP2_20160225.Messages().ByName("Message").Messages().ByName("OptionalGroup"),
 		want: fileDescP2_20160225.Messages().ByName("Message").Messages().ByName("OptionalGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_RequiredGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_RequiredGroup))),
 		want: fileDescP2_20160225.Messages().ByName("Message").Messages().ByName("RequiredGroup"),
 		want: fileDescP2_20160225.Messages().ByName("Message").Messages().ByName("RequiredGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_RepeatedGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_RepeatedGroup))),
 		want: fileDescP2_20160225.Messages().ByName("Message").Messages().ByName("RepeatedGroup"),
 		want: fileDescP2_20160225.Messages().ByName("Message").Messages().ByName("RepeatedGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_OneofGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_OneofGroup))),
 		want: fileDescP2_20160225.Messages().ByName("Message").Messages().ByName("OneofGroup"),
 		want: fileDescP2_20160225.Messages().ByName("Message").Messages().ByName("OneofGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_ExtensionOptionalGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_ExtensionOptionalGroup))),
 		want: fileDescP2_20160225.Messages().ByName("Message").Messages().ByName("ExtensionOptionalGroup"),
 		want: fileDescP2_20160225.Messages().ByName("Message").Messages().ByName("ExtensionOptionalGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_ExtensionRepeatedGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_ExtensionRepeatedGroup))),
 		want: fileDescP2_20160225.Messages().ByName("Message").Messages().ByName("ExtensionRepeatedGroup"),
 		want: fileDescP2_20160225.Messages().ByName("Message").Messages().ByName("ExtensionRepeatedGroup"),
 	}}...)
 	}}...)
 
 
 	fileDescP3_20160225 := mustLoadFileDesc(new(proto3_20160225.Message).Descriptor())
 	fileDescP3_20160225 := mustLoadFileDesc(new(proto3_20160225.Message).Descriptor())
 	tests = append(tests, []struct{ got, want pref.Descriptor }{{
 	tests = append(tests, []struct{ got, want pref.Descriptor }{{
-		got:  legacy.LoadEnumDesc(reflect.TypeOf(proto3_20160225.SiblingEnum(0))),
+		got:  impl.LegacyLoadEnumDesc(reflect.TypeOf(proto3_20160225.SiblingEnum(0))),
 		want: fileDescP3_20160225.Enums().ByName("SiblingEnum"),
 		want: fileDescP3_20160225.Enums().ByName("SiblingEnum"),
 	}, {
 	}, {
-		got:  legacy.LoadEnumDesc(reflect.TypeOf(proto3_20160225.Message_ChildEnum(0))),
+		got:  impl.LegacyLoadEnumDesc(reflect.TypeOf(proto3_20160225.Message_ChildEnum(0))),
 		want: fileDescP3_20160225.Messages().ByName("Message").Enums().ByName("ChildEnum"),
 		want: fileDescP3_20160225.Messages().ByName("Message").Enums().ByName("ChildEnum"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20160225.SiblingMessage))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20160225.SiblingMessage))),
 		want: fileDescP3_20160225.Messages().ByName("SiblingMessage"),
 		want: fileDescP3_20160225.Messages().ByName("SiblingMessage"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20160225.Message_ChildMessage))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20160225.Message_ChildMessage))),
 		want: fileDescP3_20160225.Messages().ByName("Message").Messages().ByName("ChildMessage"),
 		want: fileDescP3_20160225.Messages().ByName("Message").Messages().ByName("ChildMessage"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20160225.Message))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20160225.Message))),
 		want: fileDescP3_20160225.Messages().ByName("Message"),
 		want: fileDescP3_20160225.Messages().ByName("Message"),
 	}}...)
 	}}...)
 
 
 	fileDescP2_20160519 := mustLoadFileDesc(new(proto2_20160519.Message).Descriptor())
 	fileDescP2_20160519 := mustLoadFileDesc(new(proto2_20160519.Message).Descriptor())
 	tests = append(tests, []struct{ got, want pref.Descriptor }{{
 	tests = append(tests, []struct{ got, want pref.Descriptor }{{
-		got:  legacy.LoadEnumDesc(reflect.TypeOf(proto2_20160519.SiblingEnum(0))),
+		got:  impl.LegacyLoadEnumDesc(reflect.TypeOf(proto2_20160519.SiblingEnum(0))),
 		want: fileDescP2_20160519.Enums().ByName("SiblingEnum"),
 		want: fileDescP2_20160519.Enums().ByName("SiblingEnum"),
 	}, {
 	}, {
-		got:  legacy.LoadEnumDesc(reflect.TypeOf(proto2_20160519.Message_ChildEnum(0))),
+		got:  impl.LegacyLoadEnumDesc(reflect.TypeOf(proto2_20160519.Message_ChildEnum(0))),
 		want: fileDescP2_20160519.Messages().ByName("Message").Enums().ByName("ChildEnum"),
 		want: fileDescP2_20160519.Messages().ByName("Message").Enums().ByName("ChildEnum"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160519.SiblingMessage))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160519.SiblingMessage))),
 		want: fileDescP2_20160519.Messages().ByName("SiblingMessage"),
 		want: fileDescP2_20160519.Messages().ByName("SiblingMessage"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_ChildMessage))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_ChildMessage))),
 		want: fileDescP2_20160519.Messages().ByName("Message").Messages().ByName("ChildMessage"),
 		want: fileDescP2_20160519.Messages().ByName("Message").Messages().ByName("ChildMessage"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message))),
 		want: fileDescP2_20160519.Messages().ByName("Message"),
 		want: fileDescP2_20160519.Messages().ByName("Message"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_NamedGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_NamedGroup))),
 		want: fileDescP2_20160519.Messages().ByName("Message").Messages().ByName("NamedGroup"),
 		want: fileDescP2_20160519.Messages().ByName("Message").Messages().ByName("NamedGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_OptionalGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_OptionalGroup))),
 		want: fileDescP2_20160519.Messages().ByName("Message").Messages().ByName("OptionalGroup"),
 		want: fileDescP2_20160519.Messages().ByName("Message").Messages().ByName("OptionalGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_RequiredGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_RequiredGroup))),
 		want: fileDescP2_20160519.Messages().ByName("Message").Messages().ByName("RequiredGroup"),
 		want: fileDescP2_20160519.Messages().ByName("Message").Messages().ByName("RequiredGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_RepeatedGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_RepeatedGroup))),
 		want: fileDescP2_20160519.Messages().ByName("Message").Messages().ByName("RepeatedGroup"),
 		want: fileDescP2_20160519.Messages().ByName("Message").Messages().ByName("RepeatedGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_OneofGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_OneofGroup))),
 		want: fileDescP2_20160519.Messages().ByName("Message").Messages().ByName("OneofGroup"),
 		want: fileDescP2_20160519.Messages().ByName("Message").Messages().ByName("OneofGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_ExtensionOptionalGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_ExtensionOptionalGroup))),
 		want: fileDescP2_20160519.Messages().ByName("Message").Messages().ByName("ExtensionOptionalGroup"),
 		want: fileDescP2_20160519.Messages().ByName("Message").Messages().ByName("ExtensionOptionalGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_ExtensionRepeatedGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_ExtensionRepeatedGroup))),
 		want: fileDescP2_20160519.Messages().ByName("Message").Messages().ByName("ExtensionRepeatedGroup"),
 		want: fileDescP2_20160519.Messages().ByName("Message").Messages().ByName("ExtensionRepeatedGroup"),
 	}}...)
 	}}...)
 
 
 	fileDescP3_20160519 := mustLoadFileDesc(new(proto3_20160519.Message).Descriptor())
 	fileDescP3_20160519 := mustLoadFileDesc(new(proto3_20160519.Message).Descriptor())
 	tests = append(tests, []struct{ got, want pref.Descriptor }{{
 	tests = append(tests, []struct{ got, want pref.Descriptor }{{
-		got:  legacy.LoadEnumDesc(reflect.TypeOf(proto3_20160519.SiblingEnum(0))),
+		got:  impl.LegacyLoadEnumDesc(reflect.TypeOf(proto3_20160519.SiblingEnum(0))),
 		want: fileDescP3_20160519.Enums().ByName("SiblingEnum"),
 		want: fileDescP3_20160519.Enums().ByName("SiblingEnum"),
 	}, {
 	}, {
-		got:  legacy.LoadEnumDesc(reflect.TypeOf(proto3_20160519.Message_ChildEnum(0))),
+		got:  impl.LegacyLoadEnumDesc(reflect.TypeOf(proto3_20160519.Message_ChildEnum(0))),
 		want: fileDescP3_20160519.Messages().ByName("Message").Enums().ByName("ChildEnum"),
 		want: fileDescP3_20160519.Messages().ByName("Message").Enums().ByName("ChildEnum"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20160519.SiblingMessage))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20160519.SiblingMessage))),
 		want: fileDescP3_20160519.Messages().ByName("SiblingMessage"),
 		want: fileDescP3_20160519.Messages().ByName("SiblingMessage"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20160519.Message_ChildMessage))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20160519.Message_ChildMessage))),
 		want: fileDescP3_20160519.Messages().ByName("Message").Messages().ByName("ChildMessage"),
 		want: fileDescP3_20160519.Messages().ByName("Message").Messages().ByName("ChildMessage"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20160519.Message))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20160519.Message))),
 		want: fileDescP3_20160519.Messages().ByName("Message"),
 		want: fileDescP3_20160519.Messages().ByName("Message"),
 	}}...)
 	}}...)
 
 
 	fileDescP2_20180125 := mustLoadFileDesc(new(proto2_20180125.Message).Descriptor())
 	fileDescP2_20180125 := mustLoadFileDesc(new(proto2_20180125.Message).Descriptor())
 	tests = append(tests, []struct{ got, want pref.Descriptor }{{
 	tests = append(tests, []struct{ got, want pref.Descriptor }{{
-		got:  legacy.LoadEnumDesc(reflect.TypeOf(proto2_20180125.SiblingEnum(0))),
+		got:  impl.LegacyLoadEnumDesc(reflect.TypeOf(proto2_20180125.SiblingEnum(0))),
 		want: fileDescP2_20180125.Enums().ByName("SiblingEnum"),
 		want: fileDescP2_20180125.Enums().ByName("SiblingEnum"),
 	}, {
 	}, {
-		got:  legacy.LoadEnumDesc(reflect.TypeOf(proto2_20180125.Message_ChildEnum(0))),
+		got:  impl.LegacyLoadEnumDesc(reflect.TypeOf(proto2_20180125.Message_ChildEnum(0))),
 		want: fileDescP2_20180125.Messages().ByName("Message").Enums().ByName("ChildEnum"),
 		want: fileDescP2_20180125.Messages().ByName("Message").Enums().ByName("ChildEnum"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180125.SiblingMessage))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180125.SiblingMessage))),
 		want: fileDescP2_20180125.Messages().ByName("SiblingMessage"),
 		want: fileDescP2_20180125.Messages().ByName("SiblingMessage"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_ChildMessage))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_ChildMessage))),
 		want: fileDescP2_20180125.Messages().ByName("Message").Messages().ByName("ChildMessage"),
 		want: fileDescP2_20180125.Messages().ByName("Message").Messages().ByName("ChildMessage"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message))),
 		want: fileDescP2_20180125.Messages().ByName("Message"),
 		want: fileDescP2_20180125.Messages().ByName("Message"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_NamedGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_NamedGroup))),
 		want: fileDescP2_20180125.Messages().ByName("Message").Messages().ByName("NamedGroup"),
 		want: fileDescP2_20180125.Messages().ByName("Message").Messages().ByName("NamedGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_OptionalGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_OptionalGroup))),
 		want: fileDescP2_20180125.Messages().ByName("Message").Messages().ByName("OptionalGroup"),
 		want: fileDescP2_20180125.Messages().ByName("Message").Messages().ByName("OptionalGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_RequiredGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_RequiredGroup))),
 		want: fileDescP2_20180125.Messages().ByName("Message").Messages().ByName("RequiredGroup"),
 		want: fileDescP2_20180125.Messages().ByName("Message").Messages().ByName("RequiredGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_RepeatedGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_RepeatedGroup))),
 		want: fileDescP2_20180125.Messages().ByName("Message").Messages().ByName("RepeatedGroup"),
 		want: fileDescP2_20180125.Messages().ByName("Message").Messages().ByName("RepeatedGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_OneofGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_OneofGroup))),
 		want: fileDescP2_20180125.Messages().ByName("Message").Messages().ByName("OneofGroup"),
 		want: fileDescP2_20180125.Messages().ByName("Message").Messages().ByName("OneofGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_ExtensionOptionalGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_ExtensionOptionalGroup))),
 		want: fileDescP2_20180125.Messages().ByName("Message").Messages().ByName("ExtensionOptionalGroup"),
 		want: fileDescP2_20180125.Messages().ByName("Message").Messages().ByName("ExtensionOptionalGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_ExtensionRepeatedGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_ExtensionRepeatedGroup))),
 		want: fileDescP2_20180125.Messages().ByName("Message").Messages().ByName("ExtensionRepeatedGroup"),
 		want: fileDescP2_20180125.Messages().ByName("Message").Messages().ByName("ExtensionRepeatedGroup"),
 	}}...)
 	}}...)
 
 
 	fileDescP3_20180125 := mustLoadFileDesc(new(proto3_20180125.Message).Descriptor())
 	fileDescP3_20180125 := mustLoadFileDesc(new(proto3_20180125.Message).Descriptor())
 	tests = append(tests, []struct{ got, want pref.Descriptor }{{
 	tests = append(tests, []struct{ got, want pref.Descriptor }{{
-		got:  legacy.LoadEnumDesc(reflect.TypeOf(proto3_20180125.SiblingEnum(0))),
+		got:  impl.LegacyLoadEnumDesc(reflect.TypeOf(proto3_20180125.SiblingEnum(0))),
 		want: fileDescP3_20180125.Enums().ByName("SiblingEnum"),
 		want: fileDescP3_20180125.Enums().ByName("SiblingEnum"),
 	}, {
 	}, {
-		got:  legacy.LoadEnumDesc(reflect.TypeOf(proto3_20180125.Message_ChildEnum(0))),
+		got:  impl.LegacyLoadEnumDesc(reflect.TypeOf(proto3_20180125.Message_ChildEnum(0))),
 		want: fileDescP3_20180125.Messages().ByName("Message").Enums().ByName("ChildEnum"),
 		want: fileDescP3_20180125.Messages().ByName("Message").Enums().ByName("ChildEnum"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20180125.SiblingMessage))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20180125.SiblingMessage))),
 		want: fileDescP3_20180125.Messages().ByName("SiblingMessage"),
 		want: fileDescP3_20180125.Messages().ByName("SiblingMessage"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20180125.Message_ChildMessage))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20180125.Message_ChildMessage))),
 		want: fileDescP3_20180125.Messages().ByName("Message").Messages().ByName("ChildMessage"),
 		want: fileDescP3_20180125.Messages().ByName("Message").Messages().ByName("ChildMessage"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20180125.Message))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20180125.Message))),
 		want: fileDescP3_20180125.Messages().ByName("Message"),
 		want: fileDescP3_20180125.Messages().ByName("Message"),
 	}}...)
 	}}...)
 
 
 	fileDescP2_20180430 := mustLoadFileDesc(new(proto2_20180430.Message).Descriptor())
 	fileDescP2_20180430 := mustLoadFileDesc(new(proto2_20180430.Message).Descriptor())
 	tests = append(tests, []struct{ got, want pref.Descriptor }{{
 	tests = append(tests, []struct{ got, want pref.Descriptor }{{
-		got:  legacy.LoadEnumDesc(reflect.TypeOf(proto2_20180430.SiblingEnum(0))),
+		got:  impl.LegacyLoadEnumDesc(reflect.TypeOf(proto2_20180430.SiblingEnum(0))),
 		want: fileDescP2_20180430.Enums().ByName("SiblingEnum"),
 		want: fileDescP2_20180430.Enums().ByName("SiblingEnum"),
 	}, {
 	}, {
-		got:  legacy.LoadEnumDesc(reflect.TypeOf(proto2_20180430.Message_ChildEnum(0))),
+		got:  impl.LegacyLoadEnumDesc(reflect.TypeOf(proto2_20180430.Message_ChildEnum(0))),
 		want: fileDescP2_20180430.Messages().ByName("Message").Enums().ByName("ChildEnum"),
 		want: fileDescP2_20180430.Messages().ByName("Message").Enums().ByName("ChildEnum"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180430.SiblingMessage))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180430.SiblingMessage))),
 		want: fileDescP2_20180430.Messages().ByName("SiblingMessage"),
 		want: fileDescP2_20180430.Messages().ByName("SiblingMessage"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_ChildMessage))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_ChildMessage))),
 		want: fileDescP2_20180430.Messages().ByName("Message").Messages().ByName("ChildMessage"),
 		want: fileDescP2_20180430.Messages().ByName("Message").Messages().ByName("ChildMessage"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message))),
 		want: fileDescP2_20180430.Messages().ByName("Message"),
 		want: fileDescP2_20180430.Messages().ByName("Message"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_NamedGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_NamedGroup))),
 		want: fileDescP2_20180430.Messages().ByName("Message").Messages().ByName("NamedGroup"),
 		want: fileDescP2_20180430.Messages().ByName("Message").Messages().ByName("NamedGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_OptionalGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_OptionalGroup))),
 		want: fileDescP2_20180430.Messages().ByName("Message").Messages().ByName("OptionalGroup"),
 		want: fileDescP2_20180430.Messages().ByName("Message").Messages().ByName("OptionalGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_RequiredGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_RequiredGroup))),
 		want: fileDescP2_20180430.Messages().ByName("Message").Messages().ByName("RequiredGroup"),
 		want: fileDescP2_20180430.Messages().ByName("Message").Messages().ByName("RequiredGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_RepeatedGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_RepeatedGroup))),
 		want: fileDescP2_20180430.Messages().ByName("Message").Messages().ByName("RepeatedGroup"),
 		want: fileDescP2_20180430.Messages().ByName("Message").Messages().ByName("RepeatedGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_OneofGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_OneofGroup))),
 		want: fileDescP2_20180430.Messages().ByName("Message").Messages().ByName("OneofGroup"),
 		want: fileDescP2_20180430.Messages().ByName("Message").Messages().ByName("OneofGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_ExtensionOptionalGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_ExtensionOptionalGroup))),
 		want: fileDescP2_20180430.Messages().ByName("Message").Messages().ByName("ExtensionOptionalGroup"),
 		want: fileDescP2_20180430.Messages().ByName("Message").Messages().ByName("ExtensionOptionalGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_ExtensionRepeatedGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_ExtensionRepeatedGroup))),
 		want: fileDescP2_20180430.Messages().ByName("Message").Messages().ByName("ExtensionRepeatedGroup"),
 		want: fileDescP2_20180430.Messages().ByName("Message").Messages().ByName("ExtensionRepeatedGroup"),
 	}}...)
 	}}...)
 
 
 	fileDescP3_20180430 := mustLoadFileDesc(new(proto3_20180430.Message).Descriptor())
 	fileDescP3_20180430 := mustLoadFileDesc(new(proto3_20180430.Message).Descriptor())
 	tests = append(tests, []struct{ got, want pref.Descriptor }{{
 	tests = append(tests, []struct{ got, want pref.Descriptor }{{
-		got:  legacy.LoadEnumDesc(reflect.TypeOf(proto3_20180430.SiblingEnum(0))),
+		got:  impl.LegacyLoadEnumDesc(reflect.TypeOf(proto3_20180430.SiblingEnum(0))),
 		want: fileDescP3_20180430.Enums().ByName("SiblingEnum"),
 		want: fileDescP3_20180430.Enums().ByName("SiblingEnum"),
 	}, {
 	}, {
-		got:  legacy.LoadEnumDesc(reflect.TypeOf(proto3_20180430.Message_ChildEnum(0))),
+		got:  impl.LegacyLoadEnumDesc(reflect.TypeOf(proto3_20180430.Message_ChildEnum(0))),
 		want: fileDescP3_20180430.Messages().ByName("Message").Enums().ByName("ChildEnum"),
 		want: fileDescP3_20180430.Messages().ByName("Message").Enums().ByName("ChildEnum"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20180430.SiblingMessage))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20180430.SiblingMessage))),
 		want: fileDescP3_20180430.Messages().ByName("SiblingMessage"),
 		want: fileDescP3_20180430.Messages().ByName("SiblingMessage"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20180430.Message_ChildMessage))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20180430.Message_ChildMessage))),
 		want: fileDescP3_20180430.Messages().ByName("Message").Messages().ByName("ChildMessage"),
 		want: fileDescP3_20180430.Messages().ByName("Message").Messages().ByName("ChildMessage"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20180430.Message))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20180430.Message))),
 		want: fileDescP3_20180430.Messages().ByName("Message"),
 		want: fileDescP3_20180430.Messages().ByName("Message"),
 	}}...)
 	}}...)
 
 
 	fileDescP2_20180814 := mustLoadFileDesc(new(proto2_20180814.Message).Descriptor())
 	fileDescP2_20180814 := mustLoadFileDesc(new(proto2_20180814.Message).Descriptor())
 	tests = append(tests, []struct{ got, want pref.Descriptor }{{
 	tests = append(tests, []struct{ got, want pref.Descriptor }{{
-		got:  legacy.LoadEnumDesc(reflect.TypeOf(proto2_20180814.SiblingEnum(0))),
+		got:  impl.LegacyLoadEnumDesc(reflect.TypeOf(proto2_20180814.SiblingEnum(0))),
 		want: fileDescP2_20180814.Enums().ByName("SiblingEnum"),
 		want: fileDescP2_20180814.Enums().ByName("SiblingEnum"),
 	}, {
 	}, {
-		got:  legacy.LoadEnumDesc(reflect.TypeOf(proto2_20180814.Message_ChildEnum(0))),
+		got:  impl.LegacyLoadEnumDesc(reflect.TypeOf(proto2_20180814.Message_ChildEnum(0))),
 		want: fileDescP2_20180814.Messages().ByName("Message").Enums().ByName("ChildEnum"),
 		want: fileDescP2_20180814.Messages().ByName("Message").Enums().ByName("ChildEnum"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180814.SiblingMessage))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180814.SiblingMessage))),
 		want: fileDescP2_20180814.Messages().ByName("SiblingMessage"),
 		want: fileDescP2_20180814.Messages().ByName("SiblingMessage"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_ChildMessage))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_ChildMessage))),
 		want: fileDescP2_20180814.Messages().ByName("Message").Messages().ByName("ChildMessage"),
 		want: fileDescP2_20180814.Messages().ByName("Message").Messages().ByName("ChildMessage"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message))),
 		want: fileDescP2_20180814.Messages().ByName("Message"),
 		want: fileDescP2_20180814.Messages().ByName("Message"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_NamedGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_NamedGroup))),
 		want: fileDescP2_20180814.Messages().ByName("Message").Messages().ByName("NamedGroup"),
 		want: fileDescP2_20180814.Messages().ByName("Message").Messages().ByName("NamedGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_OptionalGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_OptionalGroup))),
 		want: fileDescP2_20180814.Messages().ByName("Message").Messages().ByName("OptionalGroup"),
 		want: fileDescP2_20180814.Messages().ByName("Message").Messages().ByName("OptionalGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_RequiredGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_RequiredGroup))),
 		want: fileDescP2_20180814.Messages().ByName("Message").Messages().ByName("RequiredGroup"),
 		want: fileDescP2_20180814.Messages().ByName("Message").Messages().ByName("RequiredGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_RepeatedGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_RepeatedGroup))),
 		want: fileDescP2_20180814.Messages().ByName("Message").Messages().ByName("RepeatedGroup"),
 		want: fileDescP2_20180814.Messages().ByName("Message").Messages().ByName("RepeatedGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_OneofGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_OneofGroup))),
 		want: fileDescP2_20180814.Messages().ByName("Message").Messages().ByName("OneofGroup"),
 		want: fileDescP2_20180814.Messages().ByName("Message").Messages().ByName("OneofGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_ExtensionOptionalGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_ExtensionOptionalGroup))),
 		want: fileDescP2_20180814.Messages().ByName("Message").Messages().ByName("ExtensionOptionalGroup"),
 		want: fileDescP2_20180814.Messages().ByName("Message").Messages().ByName("ExtensionOptionalGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_ExtensionRepeatedGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_ExtensionRepeatedGroup))),
 		want: fileDescP2_20180814.Messages().ByName("Message").Messages().ByName("ExtensionRepeatedGroup"),
 		want: fileDescP2_20180814.Messages().ByName("Message").Messages().ByName("ExtensionRepeatedGroup"),
 	}}...)
 	}}...)
 
 
 	fileDescP3_20180814 := mustLoadFileDesc(new(proto3_20180814.Message).Descriptor())
 	fileDescP3_20180814 := mustLoadFileDesc(new(proto3_20180814.Message).Descriptor())
 	tests = append(tests, []struct{ got, want pref.Descriptor }{{
 	tests = append(tests, []struct{ got, want pref.Descriptor }{{
-		got:  legacy.LoadEnumDesc(reflect.TypeOf(proto3_20180814.SiblingEnum(0))),
+		got:  impl.LegacyLoadEnumDesc(reflect.TypeOf(proto3_20180814.SiblingEnum(0))),
 		want: fileDescP3_20180814.Enums().ByName("SiblingEnum"),
 		want: fileDescP3_20180814.Enums().ByName("SiblingEnum"),
 	}, {
 	}, {
-		got:  legacy.LoadEnumDesc(reflect.TypeOf(proto3_20180814.Message_ChildEnum(0))),
+		got:  impl.LegacyLoadEnumDesc(reflect.TypeOf(proto3_20180814.Message_ChildEnum(0))),
 		want: fileDescP3_20180814.Messages().ByName("Message").Enums().ByName("ChildEnum"),
 		want: fileDescP3_20180814.Messages().ByName("Message").Enums().ByName("ChildEnum"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20180814.SiblingMessage))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20180814.SiblingMessage))),
 		want: fileDescP3_20180814.Messages().ByName("SiblingMessage"),
 		want: fileDescP3_20180814.Messages().ByName("SiblingMessage"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20180814.Message_ChildMessage))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20180814.Message_ChildMessage))),
 		want: fileDescP3_20180814.Messages().ByName("Message").Messages().ByName("ChildMessage"),
 		want: fileDescP3_20180814.Messages().ByName("Message").Messages().ByName("ChildMessage"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20180814.Message))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20180814.Message))),
 		want: fileDescP3_20180814.Messages().ByName("Message"),
 		want: fileDescP3_20180814.Messages().ByName("Message"),
 	}}...)
 	}}...)
 
 
 	fileDescP2_20181126 := mustLoadFileDesc(new(proto2_20181126.Message).Descriptor())
 	fileDescP2_20181126 := mustLoadFileDesc(new(proto2_20181126.Message).Descriptor())
 	tests = append(tests, []struct{ got, want pref.Descriptor }{{
 	tests = append(tests, []struct{ got, want pref.Descriptor }{{
-		got:  legacy.LoadEnumDesc(reflect.TypeOf(proto2_20181126.SiblingEnum(0))),
+		got:  impl.LegacyLoadEnumDesc(reflect.TypeOf(proto2_20181126.SiblingEnum(0))),
 		want: fileDescP2_20181126.Enums().ByName("SiblingEnum"),
 		want: fileDescP2_20181126.Enums().ByName("SiblingEnum"),
 	}, {
 	}, {
-		got:  legacy.LoadEnumDesc(reflect.TypeOf(proto2_20181126.Message_ChildEnum(0))),
+		got:  impl.LegacyLoadEnumDesc(reflect.TypeOf(proto2_20181126.Message_ChildEnum(0))),
 		want: fileDescP2_20181126.Messages().ByName("Message").Enums().ByName("ChildEnum"),
 		want: fileDescP2_20181126.Messages().ByName("Message").Enums().ByName("ChildEnum"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20181126.SiblingMessage))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20181126.SiblingMessage))),
 		want: fileDescP2_20181126.Messages().ByName("SiblingMessage"),
 		want: fileDescP2_20181126.Messages().ByName("SiblingMessage"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_ChildMessage))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_ChildMessage))),
 		want: fileDescP2_20181126.Messages().ByName("Message").Messages().ByName("ChildMessage"),
 		want: fileDescP2_20181126.Messages().ByName("Message").Messages().ByName("ChildMessage"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message))),
 		want: fileDescP2_20181126.Messages().ByName("Message"),
 		want: fileDescP2_20181126.Messages().ByName("Message"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_NamedGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_NamedGroup))),
 		want: fileDescP2_20181126.Messages().ByName("Message").Messages().ByName("NamedGroup"),
 		want: fileDescP2_20181126.Messages().ByName("Message").Messages().ByName("NamedGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_OptionalGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_OptionalGroup))),
 		want: fileDescP2_20181126.Messages().ByName("Message").Messages().ByName("OptionalGroup"),
 		want: fileDescP2_20181126.Messages().ByName("Message").Messages().ByName("OptionalGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_RequiredGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_RequiredGroup))),
 		want: fileDescP2_20181126.Messages().ByName("Message").Messages().ByName("RequiredGroup"),
 		want: fileDescP2_20181126.Messages().ByName("Message").Messages().ByName("RequiredGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_RepeatedGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_RepeatedGroup))),
 		want: fileDescP2_20181126.Messages().ByName("Message").Messages().ByName("RepeatedGroup"),
 		want: fileDescP2_20181126.Messages().ByName("Message").Messages().ByName("RepeatedGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_OneofGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_OneofGroup))),
 		want: fileDescP2_20181126.Messages().ByName("Message").Messages().ByName("OneofGroup"),
 		want: fileDescP2_20181126.Messages().ByName("Message").Messages().ByName("OneofGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_ExtensionOptionalGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_ExtensionOptionalGroup))),
 		want: fileDescP2_20181126.Messages().ByName("Message").Messages().ByName("ExtensionOptionalGroup"),
 		want: fileDescP2_20181126.Messages().ByName("Message").Messages().ByName("ExtensionOptionalGroup"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_ExtensionRepeatedGroup))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_ExtensionRepeatedGroup))),
 		want: fileDescP2_20181126.Messages().ByName("Message").Messages().ByName("ExtensionRepeatedGroup"),
 		want: fileDescP2_20181126.Messages().ByName("Message").Messages().ByName("ExtensionRepeatedGroup"),
 	}}...)
 	}}...)
 
 
 	fileDescP3_20181126 := mustLoadFileDesc(new(proto3_20181126.Message).Descriptor())
 	fileDescP3_20181126 := mustLoadFileDesc(new(proto3_20181126.Message).Descriptor())
 	tests = append(tests, []struct{ got, want pref.Descriptor }{{
 	tests = append(tests, []struct{ got, want pref.Descriptor }{{
-		got:  legacy.LoadEnumDesc(reflect.TypeOf(proto3_20181126.SiblingEnum(0))),
+		got:  impl.LegacyLoadEnumDesc(reflect.TypeOf(proto3_20181126.SiblingEnum(0))),
 		want: fileDescP3_20181126.Enums().ByName("SiblingEnum"),
 		want: fileDescP3_20181126.Enums().ByName("SiblingEnum"),
 	}, {
 	}, {
-		got:  legacy.LoadEnumDesc(reflect.TypeOf(proto3_20181126.Message_ChildEnum(0))),
+		got:  impl.LegacyLoadEnumDesc(reflect.TypeOf(proto3_20181126.Message_ChildEnum(0))),
 		want: fileDescP3_20181126.Messages().ByName("Message").Enums().ByName("ChildEnum"),
 		want: fileDescP3_20181126.Messages().ByName("Message").Enums().ByName("ChildEnum"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20181126.SiblingMessage))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20181126.SiblingMessage))),
 		want: fileDescP3_20181126.Messages().ByName("SiblingMessage"),
 		want: fileDescP3_20181126.Messages().ByName("SiblingMessage"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20181126.Message_ChildMessage))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20181126.Message_ChildMessage))),
 		want: fileDescP3_20181126.Messages().ByName("Message").Messages().ByName("ChildMessage"),
 		want: fileDescP3_20181126.Messages().ByName("Message").Messages().ByName("ChildMessage"),
 	}, {
 	}, {
-		got:  legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20181126.Message))),
+		got:  impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20181126.Message))),
 		want: fileDescP3_20181126.Messages().ByName("Message"),
 		want: fileDescP3_20181126.Messages().ByName("Message"),
 	}}...)
 	}}...)
 
 

+ 0 - 42
internal/impl/legacy_hook.go

@@ -1,42 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package impl
-
-import (
-	"reflect"
-
-	pvalue "google.golang.org/protobuf/internal/value"
-	pref "google.golang.org/protobuf/reflect/protoreflect"
-	piface "google.golang.org/protobuf/runtime/protoiface"
-)
-
-// TODO: Add a default LegacyWrapper that panics with a more helpful message?
-var legacyWrapper LegacyWrapper
-
-// RegisterLegacyWrapper registers a set of constructor functions that are
-// called when a legacy enum or message is encountered that does not natively
-// support the protobuf reflection APIs.
-func RegisterLegacyWrapper(w LegacyWrapper) {
-	legacyWrapper = w
-}
-
-// LegacyWrapper is a set of wrapper methods that wraps legacy v1 Go types
-// to implement the v2 reflection APIs.
-type LegacyWrapper interface {
-	NewConverter(reflect.Type, pref.Kind) pvalue.Converter
-
-	EnumOf(interface{}) pref.Enum
-	EnumTypeOf(interface{}) pref.EnumType
-	EnumDescriptorOf(interface{}) pref.EnumDescriptor
-
-	MessageOf(interface{}) pref.Message
-	MessageTypeOf(interface{}) pref.MessageType
-	MessageDescriptorOf(interface{}) pref.MessageDescriptor
-
-	// TODO: Remove these eventually.
-	// See the TODOs in internal/impl/legacy_extension.go.
-	ExtensionDescFromType(pref.ExtensionType) *piface.ExtensionDescV1
-	ExtensionTypeFromDesc(*piface.ExtensionDescV1) pref.ExtensionType
-}

+ 39 - 38
internal/legacy/message.go → internal/impl/legacy_message.go

@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 // license that can be found in the LICENSE file.
 
 
-package legacy
+package impl
 
 
 import (
 import (
 	"fmt"
 	"fmt"
@@ -12,32 +12,31 @@ import (
 	"unicode"
 	"unicode"
 
 
 	ptag "google.golang.org/protobuf/internal/encoding/tag"
 	ptag "google.golang.org/protobuf/internal/encoding/tag"
-	pimpl "google.golang.org/protobuf/internal/impl"
 	ptype "google.golang.org/protobuf/internal/prototype"
 	ptype "google.golang.org/protobuf/internal/prototype"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
 	"google.golang.org/protobuf/reflect/prototype"
 	"google.golang.org/protobuf/reflect/prototype"
 )
 )
 
 
-// wrapMessage wraps v as a protoreflect.ProtoMessage,
+// legacyWrapMessage wraps v as a protoreflect.ProtoMessage,
 // where v must be a *struct kind and not implement the v2 API already.
 // where v must be a *struct kind and not implement the v2 API already.
-func wrapMessage(v reflect.Value) pref.ProtoMessage {
-	mt := loadMessageInfo(v.Type())
+func legacyWrapMessage(v reflect.Value) pref.ProtoMessage {
+	mt := legacyLoadMessageInfo(v.Type())
 	return mt.MessageOf(v.Interface()).Interface()
 	return mt.MessageOf(v.Interface()).Interface()
 }
 }
 
 
-var messageTypeCache sync.Map // map[reflect.Type]*MessageInfo
+var legacyMessageTypeCache sync.Map // map[reflect.Type]*MessageInfo
 
 
-// loadMessageInfo dynamically loads a *MessageInfo for t,
+// legacyLoadMessageInfo dynamically loads a *MessageInfo for t,
 // where t must be a *struct kind and not implement the v2 API already.
 // where t must be a *struct kind and not implement the v2 API already.
-func loadMessageInfo(t reflect.Type) *pimpl.MessageInfo {
+func legacyLoadMessageInfo(t reflect.Type) *MessageInfo {
 	// Fast-path: check if a MessageInfo is cached for this concrete type.
 	// Fast-path: check if a MessageInfo is cached for this concrete type.
-	if mt, ok := messageTypeCache.Load(t); ok {
-		return mt.(*pimpl.MessageInfo)
+	if mt, ok := legacyMessageTypeCache.Load(t); ok {
+		return mt.(*MessageInfo)
 	}
 	}
 
 
 	// Slow-path: derive message descriptor and initialize MessageInfo.
 	// Slow-path: derive message descriptor and initialize MessageInfo.
-	md := LoadMessageDesc(t)
-	mt := new(pimpl.MessageInfo)
+	md := LegacyLoadMessageDesc(t)
+	mt := new(MessageInfo)
 	mt.GoType = t
 	mt.GoType = t
 	mt.PBType = &prototype.Message{
 	mt.PBType = &prototype.Message{
 		MessageDescriptor: md,
 		MessageDescriptor: md,
@@ -45,32 +44,34 @@ func loadMessageInfo(t reflect.Type) *pimpl.MessageInfo {
 			return mt.MessageOf(reflect.New(t.Elem()).Interface())
 			return mt.MessageOf(reflect.New(t.Elem()).Interface())
 		},
 		},
 	}
 	}
-	if mt, ok := messageTypeCache.LoadOrStore(t, mt); ok {
-		return mt.(*pimpl.MessageInfo)
+	if mt, ok := legacyMessageTypeCache.LoadOrStore(t, mt); ok {
+		return mt.(*MessageInfo)
 	}
 	}
 	return mt
 	return mt
 }
 }
 
 
-var messageDescLock sync.Mutex
-var messageDescCache sync.Map // map[reflect.Type]protoreflect.MessageDescriptor
+var (
+	legacyMessageDescLock  sync.Mutex
+	legacyMessageDescCache sync.Map // map[reflect.Type]protoreflect.MessageDescriptor
+)
 
 
-// LoadMessageDesc returns an MessageDescriptor derived from the Go type,
+// LegacyLoadMessageDesc returns an MessageDescriptor derived from the Go type,
 // which must be a *struct kind and not implement the v2 API already.
 // which must be a *struct kind and not implement the v2 API already.
 //
 //
 // This is exported for testing purposes.
 // This is exported for testing purposes.
-func LoadMessageDesc(t reflect.Type) pref.MessageDescriptor {
-	return messageDescSet{}.Load(t)
+func LegacyLoadMessageDesc(t reflect.Type) pref.MessageDescriptor {
+	return legacyMessageDescSet{}.Load(t)
 }
 }
 
 
-type messageDescSet struct {
+type legacyMessageDescSet struct {
 	visited map[reflect.Type]*ptype.StandaloneMessage
 	visited map[reflect.Type]*ptype.StandaloneMessage
 	descs   []*ptype.StandaloneMessage
 	descs   []*ptype.StandaloneMessage
 	types   []reflect.Type
 	types   []reflect.Type
 }
 }
 
 
-func (ms messageDescSet) Load(t reflect.Type) pref.MessageDescriptor {
+func (ms legacyMessageDescSet) Load(t reflect.Type) pref.MessageDescriptor {
 	// Fast-path: check if a MessageDescriptor is cached for this concrete type.
 	// Fast-path: check if a MessageDescriptor is cached for this concrete type.
-	if mi, ok := messageDescCache.Load(t); ok {
+	if mi, ok := legacyMessageDescCache.Load(t); ok {
 		return mi.(pref.MessageDescriptor)
 		return mi.(pref.MessageDescriptor)
 	}
 	}
 
 
@@ -79,9 +80,9 @@ func (ms messageDescSet) Load(t reflect.Type) pref.MessageDescriptor {
 	// Hold a global lock during message creation to ensure that each Go type
 	// Hold a global lock during message creation to ensure that each Go type
 	// maps to exactly one MessageDescriptor. After obtaining the lock, we must
 	// maps to exactly one MessageDescriptor. After obtaining the lock, we must
 	// check again whether the message has already been handled.
 	// check again whether the message has already been handled.
-	messageDescLock.Lock()
-	defer messageDescLock.Unlock()
-	if mi, ok := messageDescCache.Load(t); ok {
+	legacyMessageDescLock.Lock()
+	defer legacyMessageDescLock.Unlock()
+	if mi, ok := legacyMessageDescCache.Load(t); ok {
 		return mi.(pref.MessageDescriptor)
 		return mi.(pref.MessageDescriptor)
 	}
 	}
 
 
@@ -101,13 +102,13 @@ func (ms messageDescSet) Load(t reflect.Type) pref.MessageDescriptor {
 		// pseudo-messages (has a descriptor, but no generated Go type).
 		// pseudo-messages (has a descriptor, but no generated Go type).
 		// Avoid caching these fake messages.
 		// Avoid caching these fake messages.
 		if t := ms.types[i]; t.Kind() != reflect.Map {
 		if t := ms.types[i]; t.Kind() != reflect.Map {
-			messageDescCache.Store(t, md)
+			legacyMessageDescCache.Store(t, md)
 		}
 		}
 	}
 	}
 	return mds[0]
 	return mds[0]
 }
 }
 
 
-func (ms *messageDescSet) processMessage(t reflect.Type) pref.MessageDescriptor {
+func (ms *legacyMessageDescSet) processMessage(t reflect.Type) pref.MessageDescriptor {
 	// Fast-path: Obtain a placeholder if the message is already processed.
 	// Fast-path: Obtain a placeholder if the message is already processed.
 	if m, ok := ms.visited[t]; ok {
 	if m, ok := ms.visited[t]; ok {
 		return ptype.PlaceholderMessage(m.FullName)
 		return ptype.PlaceholderMessage(m.FullName)
@@ -126,7 +127,7 @@ func (ms *messageDescSet) processMessage(t reflect.Type) pref.MessageDescriptor
 	}
 	}
 	if md, ok := mv.(messageV1); ok {
 	if md, ok := mv.(messageV1); ok {
 		b, idxs := md.Descriptor()
 		b, idxs := md.Descriptor()
-		fd := loadFileDesc(b)
+		fd := legacyLoadFileDesc(b)
 
 
 		// Derive syntax.
 		// Derive syntax.
 		switch fd.GetSyntax() {
 		switch fd.GetSyntax() {
@@ -148,7 +149,7 @@ func (ms *messageDescSet) processMessage(t reflect.Type) pref.MessageDescriptor
 		// obtain the full name is through the registry. However, this is
 		// obtain the full name is through the registry. However, this is
 		// unreliable as some generated messages register with a fork of
 		// unreliable as some generated messages register with a fork of
 		// golang/protobuf, so the registry may not have this information.
 		// golang/protobuf, so the registry may not have this information.
-		m.FullName = deriveFullName(t.Elem())
+		m.FullName = legacyDeriveFullName(t.Elem())
 		m.Syntax = pref.Proto2
 		m.Syntax = pref.Proto2
 
 
 		// Try to determine if the message is using proto3 by checking scalars.
 		// Try to determine if the message is using proto3 by checking scalars.
@@ -223,7 +224,7 @@ func (ms *messageDescSet) processMessage(t reflect.Type) pref.MessageDescriptor
 	return ptype.PlaceholderMessage(m.FullName)
 	return ptype.PlaceholderMessage(m.FullName)
 }
 }
 
 
-func (ms *messageDescSet) parseField(tag, tagKey, tagVal string, goType reflect.Type, parent *ptype.StandaloneMessage) ptype.Field {
+func (ms *legacyMessageDescSet) parseField(tag, tagKey, tagVal string, goType reflect.Type, parent *ptype.StandaloneMessage) ptype.Field {
 	t := goType
 	t := goType
 	isOptional := t.Kind() == reflect.Ptr && t.Elem().Kind() != reflect.Struct
 	isOptional := t.Kind() == reflect.Ptr && t.Elem().Kind() != reflect.Struct
 	isRepeated := t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8
 	isRepeated := t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8
@@ -237,7 +238,7 @@ func (ms *messageDescSet) parseField(tag, tagKey, tagVal string, goType reflect.
 		if ev, ok := reflect.Zero(t).Interface().(pref.Enum); ok {
 		if ev, ok := reflect.Zero(t).Interface().(pref.Enum); ok {
 			f.EnumType = ev.Descriptor()
 			f.EnumType = ev.Descriptor()
 		} else {
 		} else {
-			f.EnumType = LoadEnumDesc(t)
+			f.EnumType = LegacyLoadEnumDesc(t)
 		}
 		}
 	}
 	}
 	if f.MessageType == nil && (f.Kind == pref.MessageKind || f.Kind == pref.GroupKind) {
 	if f.MessageType == nil && (f.Kind == pref.MessageKind || f.Kind == pref.GroupKind) {
@@ -246,7 +247,7 @@ func (ms *messageDescSet) parseField(tag, tagKey, tagVal string, goType reflect.
 		} else if t.Kind() == reflect.Map {
 		} else if t.Kind() == reflect.Map {
 			m := &ptype.StandaloneMessage{
 			m := &ptype.StandaloneMessage{
 				Syntax:     parent.Syntax,
 				Syntax:     parent.Syntax,
-				FullName:   parent.FullName.Append(mapEntryName(f.Name)),
+				FullName:   parent.FullName.Append(legacyMapEntryName(f.Name)),
 				IsMapEntry: true,
 				IsMapEntry: true,
 				Fields: []ptype.Field{
 				Fields: []ptype.Field{
 					ms.parseField(tagKey, "", "", t.Key(), nil),
 					ms.parseField(tagKey, "", "", t.Key(), nil),
@@ -255,7 +256,7 @@ func (ms *messageDescSet) parseField(tag, tagKey, tagVal string, goType reflect.
 			}
 			}
 			ms.visit(m, t)
 			ms.visit(m, t)
 			f.MessageType = ptype.PlaceholderMessage(m.FullName)
 			f.MessageType = ptype.PlaceholderMessage(m.FullName)
-		} else if mv, ok := messageDescCache.Load(t); ok {
+		} else if mv, ok := legacyMessageDescCache.Load(t); ok {
 			f.MessageType = mv.(pref.MessageDescriptor)
 			f.MessageType = mv.(pref.MessageDescriptor)
 		} else {
 		} else {
 			f.MessageType = ms.processMessage(t)
 			f.MessageType = ms.processMessage(t)
@@ -264,7 +265,7 @@ func (ms *messageDescSet) parseField(tag, tagKey, tagVal string, goType reflect.
 	return f
 	return f
 }
 }
 
 
-func (ms *messageDescSet) visit(m *ptype.StandaloneMessage, t reflect.Type) {
+func (ms *legacyMessageDescSet) visit(m *ptype.StandaloneMessage, t reflect.Type) {
 	if ms.visited == nil {
 	if ms.visited == nil {
 		ms.visited = make(map[reflect.Type]*ptype.StandaloneMessage)
 		ms.visited = make(map[reflect.Type]*ptype.StandaloneMessage)
 	}
 	}
@@ -275,10 +276,10 @@ func (ms *messageDescSet) visit(m *ptype.StandaloneMessage, t reflect.Type) {
 	ms.types = append(ms.types, t)
 	ms.types = append(ms.types, t)
 }
 }
 
 
-// deriveFullName derives a fully qualified protobuf name for the given Go type
+// legacyDeriveFullName derives a fully qualified protobuf name for the given Go type
 // The provided name is not guaranteed to be stable nor universally unique.
 // The provided name is not guaranteed to be stable nor universally unique.
 // It should be sufficiently unique within a program.
 // It should be sufficiently unique within a program.
-func deriveFullName(t reflect.Type) pref.FullName {
+func legacyDeriveFullName(t reflect.Type) pref.FullName {
 	sanitize := func(r rune) rune {
 	sanitize := func(r rune) rune {
 		switch {
 		switch {
 		case r == '/':
 		case r == '/':
@@ -304,9 +305,9 @@ func deriveFullName(t reflect.Type) pref.FullName {
 	return pref.FullName(strings.Join(ss, "."))
 	return pref.FullName(strings.Join(ss, "."))
 }
 }
 
 
-// mapEntryName derives the message name for a map field of a given name.
+// legacyMapEntryName derives the message name for a map field of a given name.
 // This is identical to MapEntryName from parser.cc in the protoc source.
 // This is identical to MapEntryName from parser.cc in the protoc source.
-func mapEntryName(s pref.Name) pref.Name {
+func legacyMapEntryName(s pref.Name) pref.Name {
 	var b []byte
 	var b []byte
 	nextUpper := true
 	nextUpper := true
 	for i := 0; i < len(s); i++ {
 	for i := 0; i < len(s); i++ {

+ 40 - 40
internal/legacy/parse.go → internal/impl/legacy_parse.go

@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 // license that can be found in the LICENSE file.
 
 
-package legacy
+package impl
 
 
 import (
 import (
 	"google.golang.org/protobuf/internal/encoding/wire"
 	"google.golang.org/protobuf/internal/encoding/wire"
@@ -14,21 +14,21 @@ import (
 //
 //
 // TODO: Consider unifying this with the parser in fileinit.
 // TODO: Consider unifying this with the parser in fileinit.
 
 
-type fileDescriptorProto struct {
+type legacyFileDescriptorProto struct {
 	Syntax      string
 	Syntax      string
 	Package     string
 	Package     string
-	EnumType    []*enumDescriptorProto
-	MessageType []*descriptorProto
+	EnumType    []*legacyEnumDescriptorProto
+	MessageType []*legacyDescriptorProto
 }
 }
 
 
-func (fd fileDescriptorProto) GetSyntax() string  { return fd.Syntax }
-func (fd fileDescriptorProto) GetPackage() string { return fd.Package }
+func (fd legacyFileDescriptorProto) GetSyntax() string  { return fd.Syntax }
+func (fd legacyFileDescriptorProto) GetPackage() string { return fd.Package }
 
 
-func parseFileDescProto(b []byte) *fileDescriptorProto {
-	fd := &fileDescriptorProto{}
+func legacyParseFileDescProto(b []byte) *legacyFileDescriptorProto {
+	fd := &legacyFileDescriptorProto{}
 	for len(b) > 0 {
 	for len(b) > 0 {
 		num, typ, n := wire.ConsumeTag(b)
 		num, typ, n := wire.ConsumeTag(b)
-		parseCheck(n)
+		legacyParseCheck(n)
 		b = b[n:]
 		b = b[n:]
 		switch typ {
 		switch typ {
 		case wire.BytesType:
 		case wire.BytesType:
@@ -40,37 +40,37 @@ func parseFileDescProto(b []byte) *fileDescriptorProto {
 			case fieldnum.FileDescriptorProto_Package:
 			case fieldnum.FileDescriptorProto_Package:
 				fd.Package = string(v)
 				fd.Package = string(v)
 			case fieldnum.FileDescriptorProto_EnumType:
 			case fieldnum.FileDescriptorProto_EnumType:
-				fd.EnumType = append(fd.EnumType, parseEnumDescProto(v))
+				fd.EnumType = append(fd.EnumType, legacyParseEnumDescProto(v))
 			case fieldnum.FileDescriptorProto_MessageType:
 			case fieldnum.FileDescriptorProto_MessageType:
 				fd.MessageType = append(fd.MessageType, parseDescProto(v))
 				fd.MessageType = append(fd.MessageType, parseDescProto(v))
 			}
 			}
 		default:
 		default:
 			n := wire.ConsumeFieldValue(num, typ, b)
 			n := wire.ConsumeFieldValue(num, typ, b)
-			parseCheck(n)
+			legacyParseCheck(n)
 			b = b[n:]
 			b = b[n:]
 		}
 		}
 	}
 	}
 	return fd
 	return fd
 }
 }
 
 
-type descriptorProto struct {
+type legacyDescriptorProto struct {
 	Name       string
 	Name       string
-	NestedType []*descriptorProto
-	EnumType   []*enumDescriptorProto
+	NestedType []*legacyDescriptorProto
+	EnumType   []*legacyEnumDescriptorProto
 }
 }
 
 
-func (md descriptorProto) GetName() string { return md.Name }
+func (md legacyDescriptorProto) GetName() string { return md.Name }
 
 
-func parseDescProto(b []byte) *descriptorProto {
-	md := &descriptorProto{}
+func parseDescProto(b []byte) *legacyDescriptorProto {
+	md := &legacyDescriptorProto{}
 	for len(b) > 0 {
 	for len(b) > 0 {
 		num, typ, n := wire.ConsumeTag(b)
 		num, typ, n := wire.ConsumeTag(b)
-		parseCheck(n)
+		legacyParseCheck(n)
 		b = b[n:]
 		b = b[n:]
 		switch typ {
 		switch typ {
 		case wire.BytesType:
 		case wire.BytesType:
 			v, n := wire.ConsumeBytes(b)
 			v, n := wire.ConsumeBytes(b)
-			parseCheck(n)
+			legacyParseCheck(n)
 			b = b[n:]
 			b = b[n:]
 			switch num {
 			switch num {
 			case fieldnum.DescriptorProto_Name:
 			case fieldnum.DescriptorProto_Name:
@@ -78,68 +78,68 @@ func parseDescProto(b []byte) *descriptorProto {
 			case fieldnum.DescriptorProto_NestedType:
 			case fieldnum.DescriptorProto_NestedType:
 				md.NestedType = append(md.NestedType, parseDescProto(v))
 				md.NestedType = append(md.NestedType, parseDescProto(v))
 			case fieldnum.DescriptorProto_EnumType:
 			case fieldnum.DescriptorProto_EnumType:
-				md.EnumType = append(md.EnumType, parseEnumDescProto(v))
+				md.EnumType = append(md.EnumType, legacyParseEnumDescProto(v))
 			}
 			}
 		default:
 		default:
 			n := wire.ConsumeFieldValue(num, typ, b)
 			n := wire.ConsumeFieldValue(num, typ, b)
-			parseCheck(n)
+			legacyParseCheck(n)
 			b = b[n:]
 			b = b[n:]
 		}
 		}
 	}
 	}
 	return md
 	return md
 }
 }
 
 
-type enumDescriptorProto struct {
+type legacyEnumDescriptorProto struct {
 	Name  string
 	Name  string
-	Value []*enumValueDescriptorProto
+	Value []*legacyEnumValueDescriptorProto
 }
 }
 
 
-func (ed enumDescriptorProto) GetName() string { return ed.Name }
+func (ed legacyEnumDescriptorProto) GetName() string { return ed.Name }
 
 
-func parseEnumDescProto(b []byte) *enumDescriptorProto {
-	ed := &enumDescriptorProto{}
+func legacyParseEnumDescProto(b []byte) *legacyEnumDescriptorProto {
+	ed := &legacyEnumDescriptorProto{}
 	for len(b) > 0 {
 	for len(b) > 0 {
 		num, typ, n := wire.ConsumeTag(b)
 		num, typ, n := wire.ConsumeTag(b)
-		parseCheck(n)
+		legacyParseCheck(n)
 		b = b[n:]
 		b = b[n:]
 		switch typ {
 		switch typ {
 		case wire.BytesType:
 		case wire.BytesType:
 			v, n := wire.ConsumeBytes(b)
 			v, n := wire.ConsumeBytes(b)
-			parseCheck(n)
+			legacyParseCheck(n)
 			b = b[n:]
 			b = b[n:]
 			switch num {
 			switch num {
 			case fieldnum.EnumDescriptorProto_Name:
 			case fieldnum.EnumDescriptorProto_Name:
 				ed.Name = string(v)
 				ed.Name = string(v)
 			case fieldnum.EnumDescriptorProto_Value:
 			case fieldnum.EnumDescriptorProto_Value:
-				ed.Value = append(ed.Value, parseEnumValueDescProto(v))
+				ed.Value = append(ed.Value, legacyParseEnumValueDescProto(v))
 			}
 			}
 		default:
 		default:
 			n := wire.ConsumeFieldValue(num, typ, b)
 			n := wire.ConsumeFieldValue(num, typ, b)
-			parseCheck(n)
+			legacyParseCheck(n)
 			b = b[n:]
 			b = b[n:]
 		}
 		}
 	}
 	}
 	return ed
 	return ed
 }
 }
 
 
-type enumValueDescriptorProto struct {
+type legacyEnumValueDescriptorProto struct {
 	Name   string
 	Name   string
 	Number int32
 	Number int32
 }
 }
 
 
-func (ed enumValueDescriptorProto) GetName() string  { return ed.Name }
-func (ed enumValueDescriptorProto) GetNumber() int32 { return ed.Number }
+func (ed legacyEnumValueDescriptorProto) GetName() string  { return ed.Name }
+func (ed legacyEnumValueDescriptorProto) GetNumber() int32 { return ed.Number }
 
 
-func parseEnumValueDescProto(b []byte) *enumValueDescriptorProto {
-	vd := &enumValueDescriptorProto{}
+func legacyParseEnumValueDescProto(b []byte) *legacyEnumValueDescriptorProto {
+	vd := &legacyEnumValueDescriptorProto{}
 	for len(b) > 0 {
 	for len(b) > 0 {
 		num, typ, n := wire.ConsumeTag(b)
 		num, typ, n := wire.ConsumeTag(b)
-		parseCheck(n)
+		legacyParseCheck(n)
 		b = b[n:]
 		b = b[n:]
 		switch typ {
 		switch typ {
 		case wire.VarintType:
 		case wire.VarintType:
 			v, n := wire.ConsumeVarint(b)
 			v, n := wire.ConsumeVarint(b)
-			parseCheck(n)
+			legacyParseCheck(n)
 			b = b[n:]
 			b = b[n:]
 			switch num {
 			switch num {
 			case fieldnum.EnumValueDescriptorProto_Number:
 			case fieldnum.EnumValueDescriptorProto_Number:
@@ -147,7 +147,7 @@ func parseEnumValueDescProto(b []byte) *enumValueDescriptorProto {
 			}
 			}
 		case wire.BytesType:
 		case wire.BytesType:
 			v, n := wire.ConsumeBytes(b)
 			v, n := wire.ConsumeBytes(b)
-			parseCheck(n)
+			legacyParseCheck(n)
 			b = b[n:]
 			b = b[n:]
 			switch num {
 			switch num {
 			case fieldnum.EnumDescriptorProto_Name:
 			case fieldnum.EnumDescriptorProto_Name:
@@ -155,14 +155,14 @@ func parseEnumValueDescProto(b []byte) *enumValueDescriptorProto {
 			}
 			}
 		default:
 		default:
 			n := wire.ConsumeFieldValue(num, typ, b)
 			n := wire.ConsumeFieldValue(num, typ, b)
-			parseCheck(n)
+			legacyParseCheck(n)
 			b = b[n:]
 			b = b[n:]
 		}
 		}
 	}
 	}
 	return vd
 	return vd
 }
 }
 
 
-func parseCheck(n int) {
+func legacyParseCheck(n int) {
 	if n < 0 {
 	if n < 0 {
 		panic(wire.ParseError(n))
 		panic(wire.ParseError(n))
 	}
 	}

+ 121 - 44
internal/impl/legacy_test.go

@@ -8,13 +8,13 @@ import (
 	"bytes"
 	"bytes"
 	"math"
 	"math"
 	"reflect"
 	"reflect"
+	"sync"
 	"testing"
 	"testing"
 
 
 	cmp "github.com/google/go-cmp/cmp"
 	cmp "github.com/google/go-cmp/cmp"
 	cmpopts "github.com/google/go-cmp/cmp/cmpopts"
 	cmpopts "github.com/google/go-cmp/cmp/cmpopts"
 	pack "google.golang.org/protobuf/internal/encoding/pack"
 	pack "google.golang.org/protobuf/internal/encoding/pack"
 	pimpl "google.golang.org/protobuf/internal/impl"
 	pimpl "google.golang.org/protobuf/internal/impl"
-	plegacy "google.golang.org/protobuf/internal/legacy"
 	pragma "google.golang.org/protobuf/internal/pragma"
 	pragma "google.golang.org/protobuf/internal/pragma"
 	ptype "google.golang.org/protobuf/internal/prototype"
 	ptype "google.golang.org/protobuf/internal/prototype"
 	scalar "google.golang.org/protobuf/internal/scalar"
 	scalar "google.golang.org/protobuf/internal/scalar"
@@ -172,20 +172,12 @@ func TestLegacyUnknown(t *testing.T) {
 	}
 	}
 }
 }
 
 
-func mustMakeExtensionType(x *ptype.StandaloneExtension, v interface{}) pref.ExtensionType {
-	xd, err := ptype.NewExtension(x)
-	if err != nil {
-		panic(xd)
-	}
-	return plegacy.ExtensionTypeOf(xd, reflect.TypeOf(v))
-}
-
 var (
 var (
-	parentDesc    = pimpl.Export{}.MessageDescriptorOf((*legacyTestMessage)(nil))
-	enumV1Desc    = pimpl.Export{}.EnumDescriptorOf(proto2_20180125.Message_ChildEnum(0))
-	messageV1Desc = pimpl.Export{}.MessageDescriptorOf((*proto2_20180125.Message_ChildMessage)(nil))
-	enumV2Desc    = enumProto2Type.Descriptor()
-	messageV2Desc = enumMessagesType.PBType.Descriptor()
+	testParentDesc    = pimpl.Export{}.MessageDescriptorOf((*legacyTestMessage)(nil))
+	testEnumV1Desc    = pimpl.Export{}.EnumDescriptorOf(proto2_20180125.Message_ChildEnum(0))
+	testMessageV1Desc = pimpl.Export{}.MessageDescriptorOf((*proto2_20180125.Message_ChildMessage)(nil))
+	testEnumV2Desc    = enumProto2Type.Descriptor()
+	testMessageV2Desc = enumMessagesType.PBType.Descriptor()
 
 
 	extensionTypes = []pref.ExtensionType{
 	extensionTypes = []pref.ExtensionType{
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 		mustMakeExtensionType(&ptype.StandaloneExtension{
@@ -194,7 +186,7 @@ var (
 			Cardinality:  pref.Optional,
 			Cardinality:  pref.Optional,
 			Kind:         pref.BoolKind,
 			Kind:         pref.BoolKind,
 			Default:      pref.ValueOf(true),
 			Default:      pref.ValueOf(true),
-			ExtendedType: parentDesc,
+			ExtendedType: testParentDesc,
 		}, nil),
 		}, nil),
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 			FullName:     "fizz.buzz.optional_int32",
 			FullName:     "fizz.buzz.optional_int32",
@@ -202,7 +194,7 @@ var (
 			Cardinality:  pref.Optional,
 			Cardinality:  pref.Optional,
 			Kind:         pref.Int32Kind,
 			Kind:         pref.Int32Kind,
 			Default:      pref.ValueOf(int32(-12345)),
 			Default:      pref.ValueOf(int32(-12345)),
-			ExtendedType: parentDesc,
+			ExtendedType: testParentDesc,
 		}, nil),
 		}, nil),
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 			FullName:     "fizz.buzz.optional_uint32",
 			FullName:     "fizz.buzz.optional_uint32",
@@ -210,7 +202,7 @@ var (
 			Cardinality:  pref.Optional,
 			Cardinality:  pref.Optional,
 			Kind:         pref.Uint32Kind,
 			Kind:         pref.Uint32Kind,
 			Default:      pref.ValueOf(uint32(3200)),
 			Default:      pref.ValueOf(uint32(3200)),
-			ExtendedType: parentDesc,
+			ExtendedType: testParentDesc,
 		}, nil),
 		}, nil),
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 			FullName:     "fizz.buzz.optional_float",
 			FullName:     "fizz.buzz.optional_float",
@@ -218,7 +210,7 @@ var (
 			Cardinality:  pref.Optional,
 			Cardinality:  pref.Optional,
 			Kind:         pref.FloatKind,
 			Kind:         pref.FloatKind,
 			Default:      pref.ValueOf(float32(3.14159)),
 			Default:      pref.ValueOf(float32(3.14159)),
-			ExtendedType: parentDesc,
+			ExtendedType: testParentDesc,
 		}, nil),
 		}, nil),
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 			FullName:     "fizz.buzz.optional_string",
 			FullName:     "fizz.buzz.optional_string",
@@ -226,7 +218,7 @@ var (
 			Cardinality:  pref.Optional,
 			Cardinality:  pref.Optional,
 			Kind:         pref.StringKind,
 			Kind:         pref.StringKind,
 			Default:      pref.ValueOf(string("hello, \"world!\"\n")),
 			Default:      pref.ValueOf(string("hello, \"world!\"\n")),
-			ExtendedType: parentDesc,
+			ExtendedType: testParentDesc,
 		}, nil),
 		}, nil),
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 			FullName:     "fizz.buzz.optional_bytes",
 			FullName:     "fizz.buzz.optional_bytes",
@@ -234,7 +226,7 @@ var (
 			Cardinality:  pref.Optional,
 			Cardinality:  pref.Optional,
 			Kind:         pref.BytesKind,
 			Kind:         pref.BytesKind,
 			Default:      pref.ValueOf([]byte("dead\xde\xad\xbe\xefbeef")),
 			Default:      pref.ValueOf([]byte("dead\xde\xad\xbe\xefbeef")),
-			ExtendedType: parentDesc,
+			ExtendedType: testParentDesc,
 		}, nil),
 		}, nil),
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 			FullName:     "fizz.buzz.optional_enum_v1",
 			FullName:     "fizz.buzz.optional_enum_v1",
@@ -242,16 +234,16 @@ var (
 			Cardinality:  pref.Optional,
 			Cardinality:  pref.Optional,
 			Kind:         pref.EnumKind,
 			Kind:         pref.EnumKind,
 			Default:      pref.ValueOf(pref.EnumNumber(0)),
 			Default:      pref.ValueOf(pref.EnumNumber(0)),
-			EnumType:     enumV1Desc,
-			ExtendedType: parentDesc,
+			EnumType:     testEnumV1Desc,
+			ExtendedType: testParentDesc,
 		}, proto2_20180125.Message_ChildEnum(0)),
 		}, proto2_20180125.Message_ChildEnum(0)),
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 			FullName:     "fizz.buzz.optional_message_v1",
 			FullName:     "fizz.buzz.optional_message_v1",
 			Number:       10007,
 			Number:       10007,
 			Cardinality:  pref.Optional,
 			Cardinality:  pref.Optional,
 			Kind:         pref.MessageKind,
 			Kind:         pref.MessageKind,
-			MessageType:  messageV1Desc,
-			ExtendedType: parentDesc,
+			MessageType:  testMessageV1Desc,
+			ExtendedType: testParentDesc,
 		}, (*proto2_20180125.Message_ChildMessage)(nil)),
 		}, (*proto2_20180125.Message_ChildMessage)(nil)),
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 			FullName:     "fizz.buzz.optional_enum_v2",
 			FullName:     "fizz.buzz.optional_enum_v2",
@@ -259,90 +251,90 @@ var (
 			Cardinality:  pref.Optional,
 			Cardinality:  pref.Optional,
 			Kind:         pref.EnumKind,
 			Kind:         pref.EnumKind,
 			Default:      pref.ValueOf(pref.EnumNumber(57005)),
 			Default:      pref.ValueOf(pref.EnumNumber(57005)),
-			EnumType:     enumV2Desc,
-			ExtendedType: parentDesc,
+			EnumType:     testEnumV2Desc,
+			ExtendedType: testParentDesc,
 		}, EnumProto2(0)),
 		}, EnumProto2(0)),
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 			FullName:     "fizz.buzz.optional_message_v2",
 			FullName:     "fizz.buzz.optional_message_v2",
 			Number:       10009,
 			Number:       10009,
 			Cardinality:  pref.Optional,
 			Cardinality:  pref.Optional,
 			Kind:         pref.MessageKind,
 			Kind:         pref.MessageKind,
-			MessageType:  messageV2Desc,
-			ExtendedType: parentDesc,
+			MessageType:  testMessageV2Desc,
+			ExtendedType: testParentDesc,
 		}, (*EnumMessages)(nil)),
 		}, (*EnumMessages)(nil)),
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 			FullName:     "fizz.buzz.repeated_bool",
 			FullName:     "fizz.buzz.repeated_bool",
 			Number:       10010,
 			Number:       10010,
 			Cardinality:  pref.Repeated,
 			Cardinality:  pref.Repeated,
 			Kind:         pref.BoolKind,
 			Kind:         pref.BoolKind,
-			ExtendedType: parentDesc,
+			ExtendedType: testParentDesc,
 		}, nil),
 		}, nil),
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 			FullName:     "fizz.buzz.repeated_int32",
 			FullName:     "fizz.buzz.repeated_int32",
 			Number:       10011,
 			Number:       10011,
 			Cardinality:  pref.Repeated,
 			Cardinality:  pref.Repeated,
 			Kind:         pref.Int32Kind,
 			Kind:         pref.Int32Kind,
-			ExtendedType: parentDesc,
+			ExtendedType: testParentDesc,
 		}, nil),
 		}, nil),
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 			FullName:     "fizz.buzz.repeated_uint32",
 			FullName:     "fizz.buzz.repeated_uint32",
 			Number:       10012,
 			Number:       10012,
 			Cardinality:  pref.Repeated,
 			Cardinality:  pref.Repeated,
 			Kind:         pref.Uint32Kind,
 			Kind:         pref.Uint32Kind,
-			ExtendedType: parentDesc,
+			ExtendedType: testParentDesc,
 		}, nil),
 		}, nil),
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 			FullName:     "fizz.buzz.repeated_float",
 			FullName:     "fizz.buzz.repeated_float",
 			Number:       10013,
 			Number:       10013,
 			Cardinality:  pref.Repeated,
 			Cardinality:  pref.Repeated,
 			Kind:         pref.FloatKind,
 			Kind:         pref.FloatKind,
-			ExtendedType: parentDesc,
+			ExtendedType: testParentDesc,
 		}, nil),
 		}, nil),
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 			FullName:     "fizz.buzz.repeated_string",
 			FullName:     "fizz.buzz.repeated_string",
 			Number:       10014,
 			Number:       10014,
 			Cardinality:  pref.Repeated,
 			Cardinality:  pref.Repeated,
 			Kind:         pref.StringKind,
 			Kind:         pref.StringKind,
-			ExtendedType: parentDesc,
+			ExtendedType: testParentDesc,
 		}, nil),
 		}, nil),
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 			FullName:     "fizz.buzz.repeated_bytes",
 			FullName:     "fizz.buzz.repeated_bytes",
 			Number:       10015,
 			Number:       10015,
 			Cardinality:  pref.Repeated,
 			Cardinality:  pref.Repeated,
 			Kind:         pref.BytesKind,
 			Kind:         pref.BytesKind,
-			ExtendedType: parentDesc,
+			ExtendedType: testParentDesc,
 		}, nil),
 		}, nil),
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 			FullName:     "fizz.buzz.repeated_enum_v1",
 			FullName:     "fizz.buzz.repeated_enum_v1",
 			Number:       10016,
 			Number:       10016,
 			Cardinality:  pref.Repeated,
 			Cardinality:  pref.Repeated,
 			Kind:         pref.EnumKind,
 			Kind:         pref.EnumKind,
-			EnumType:     enumV1Desc,
-			ExtendedType: parentDesc,
+			EnumType:     testEnumV1Desc,
+			ExtendedType: testParentDesc,
 		}, proto2_20180125.Message_ChildEnum(0)),
 		}, proto2_20180125.Message_ChildEnum(0)),
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 			FullName:     "fizz.buzz.repeated_message_v1",
 			FullName:     "fizz.buzz.repeated_message_v1",
 			Number:       10017,
 			Number:       10017,
 			Cardinality:  pref.Repeated,
 			Cardinality:  pref.Repeated,
 			Kind:         pref.MessageKind,
 			Kind:         pref.MessageKind,
-			MessageType:  messageV1Desc,
-			ExtendedType: parentDesc,
+			MessageType:  testMessageV1Desc,
+			ExtendedType: testParentDesc,
 		}, (*proto2_20180125.Message_ChildMessage)(nil)),
 		}, (*proto2_20180125.Message_ChildMessage)(nil)),
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 			FullName:     "fizz.buzz.repeated_enum_v2",
 			FullName:     "fizz.buzz.repeated_enum_v2",
 			Number:       10018,
 			Number:       10018,
 			Cardinality:  pref.Repeated,
 			Cardinality:  pref.Repeated,
 			Kind:         pref.EnumKind,
 			Kind:         pref.EnumKind,
-			EnumType:     enumV2Desc,
-			ExtendedType: parentDesc,
+			EnumType:     testEnumV2Desc,
+			ExtendedType: testParentDesc,
 		}, EnumProto2(0)),
 		}, EnumProto2(0)),
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 		mustMakeExtensionType(&ptype.StandaloneExtension{
 			FullName:     "fizz.buzz.repeated_message_v2",
 			FullName:     "fizz.buzz.repeated_message_v2",
 			Number:       10019,
 			Number:       10019,
 			Cardinality:  pref.Repeated,
 			Cardinality:  pref.Repeated,
 			Kind:         pref.MessageKind,
 			Kind:         pref.MessageKind,
-			MessageType:  messageV2Desc,
-			ExtendedType: parentDesc,
+			MessageType:  testMessageV2Desc,
+			ExtendedType: testParentDesc,
 		}, (*EnumMessages)(nil)),
 		}, (*EnumMessages)(nil)),
 	}
 	}
 
 
@@ -646,8 +638,8 @@ func TestExtensionConvert(t *testing.T) {
 
 
 			wantType := extensionTypes[i]
 			wantType := extensionTypes[i]
 			wantDesc := extensionDescs[i]
 			wantDesc := extensionDescs[i]
-			gotType := plegacy.Export{}.ExtensionTypeFromDesc(wantDesc)
-			gotDesc := plegacy.Export{}.ExtensionDescFromType(wantType)
+			gotType := pimpl.Export{}.ExtensionTypeFromDesc(wantDesc)
+			gotDesc := pimpl.Export{}.ExtensionDescFromType(wantType)
 
 
 			// TODO: We need a test package to compare descriptors.
 			// TODO: We need a test package to compare descriptors.
 			type list interface {
 			type list interface {
@@ -720,3 +712,88 @@ func TestExtensionConvert(t *testing.T) {
 		})
 		})
 	}
 	}
 }
 }
+
+type (
+	MessageA struct {
+		A1 *MessageA `protobuf:"bytes,1,req,name=a1"`
+		A2 *MessageB `protobuf:"bytes,2,req,name=a2"`
+		A3 Enum      `protobuf:"varint,3,opt,name=a3,enum=legacy.Enum"`
+	}
+	MessageB struct {
+		B1 *MessageA `protobuf:"bytes,1,req,name=b1"`
+		B2 *MessageB `protobuf:"bytes,2,req,name=b2"`
+		B3 Enum      `protobuf:"varint,3,opt,name=b3,enum=legacy.Enum"`
+	}
+	Enum int32
+)
+
+// TestConcurrentInit tests that concurrent wrapping of multiple legacy types
+// results in the exact same descriptor being created.
+func TestConcurrentInit(t *testing.T) {
+	const numParallel = 5
+	var messageATypes [numParallel]pref.MessageType
+	var messageBTypes [numParallel]pref.MessageType
+	var enumDescs [numParallel]pref.EnumDescriptor
+
+	// Concurrently load message and enum types.
+	var wg sync.WaitGroup
+	for i := 0; i < numParallel; i++ {
+		i := i
+		wg.Add(3)
+		go func() {
+			defer wg.Done()
+			messageATypes[i] = pimpl.Export{}.MessageTypeOf((*MessageA)(nil))
+		}()
+		go func() {
+			defer wg.Done()
+			messageBTypes[i] = pimpl.Export{}.MessageTypeOf((*MessageB)(nil))
+		}()
+		go func() {
+			defer wg.Done()
+			enumDescs[i] = pimpl.Export{}.EnumDescriptorOf(Enum(0))
+		}()
+	}
+	wg.Wait()
+
+	var (
+		wantMTA = messageATypes[0]
+		wantMDA = messageATypes[0].Descriptor().Fields().ByNumber(1).Message()
+		wantMTB = messageBTypes[0]
+		wantMDB = messageBTypes[0].Descriptor().Fields().ByNumber(2).Message()
+		wantED  = messageATypes[0].Descriptor().Fields().ByNumber(3).Enum()
+	)
+
+	for _, gotMT := range messageATypes[1:] {
+		if gotMT != wantMTA {
+			t.Error("MessageType(MessageA) mismatch")
+		}
+		if gotMDA := gotMT.Descriptor().Fields().ByNumber(1).Message(); gotMDA != wantMDA {
+			t.Error("MessageDescriptor(MessageA) mismatch")
+		}
+		if gotMDB := gotMT.Descriptor().Fields().ByNumber(2).Message(); gotMDB != wantMDB {
+			t.Error("MessageDescriptor(MessageB) mismatch")
+		}
+		if gotED := gotMT.Descriptor().Fields().ByNumber(3).Enum(); gotED != wantED {
+			t.Error("EnumDescriptor(Enum) mismatch")
+		}
+	}
+	for _, gotMT := range messageBTypes[1:] {
+		if gotMT != wantMTB {
+			t.Error("MessageType(MessageB) mismatch")
+		}
+		if gotMDA := gotMT.Descriptor().Fields().ByNumber(1).Message(); gotMDA != wantMDA {
+			t.Error("MessageDescriptor(MessageA) mismatch")
+		}
+		if gotMDB := gotMT.Descriptor().Fields().ByNumber(2).Message(); gotMDB != wantMDB {
+			t.Error("MessageDescriptor(MessageB) mismatch")
+		}
+		if gotED := gotMT.Descriptor().Fields().ByNumber(3).Enum(); gotED != wantED {
+			t.Error("EnumDescriptor(Enum) mismatch")
+		}
+	}
+	for _, gotED := range enumDescs[1:] {
+		if gotED != wantED {
+			t.Error("EnumType(Enum) mismatch")
+		}
+	}
+}

+ 54 - 10
internal/impl/message_field.go

@@ -12,6 +12,7 @@ import (
 	"google.golang.org/protobuf/internal/encoding/wire"
 	"google.golang.org/protobuf/internal/encoding/wire"
 	pvalue "google.golang.org/protobuf/internal/value"
 	pvalue "google.golang.org/protobuf/internal/value"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
+	piface "google.golang.org/protobuf/runtime/protoiface"
 )
 )
 
 
 type fieldInfo struct {
 type fieldInfo struct {
@@ -42,7 +43,7 @@ func fieldInfoForOneof(fd pref.FieldDescriptor, fs reflect.StructField, ot refle
 	if !reflect.PtrTo(ot).Implements(ft) {
 	if !reflect.PtrTo(ot).Implements(ft) {
 		panic(fmt.Sprintf("invalid type: %v does not implement %v", ot, ft))
 		panic(fmt.Sprintf("invalid type: %v does not implement %v", ot, ft))
 	}
 	}
-	conv := newConverter(ot.Field(0).Type, fd.Kind())
+	conv, _ := newConverter(ot.Field(0).Type, fd.Kind())
 	fieldOffset := offsetOf(fs)
 	fieldOffset := offsetOf(fs)
 	// TODO: Implement unsafe fast path?
 	// TODO: Implement unsafe fast path?
 	return fieldInfo{
 	return fieldInfo{
@@ -97,8 +98,8 @@ func fieldInfoForMap(fd pref.FieldDescriptor, fs reflect.StructField) fieldInfo
 	if ft.Kind() != reflect.Map {
 	if ft.Kind() != reflect.Map {
 		panic(fmt.Sprintf("invalid type: got %v, want map kind", ft))
 		panic(fmt.Sprintf("invalid type: got %v, want map kind", ft))
 	}
 	}
-	keyConv := newConverter(ft.Key(), fd.MapKey().Kind())
-	valConv := newConverter(ft.Elem(), fd.MapValue().Kind())
+	keyConv, _ := newConverter(ft.Key(), fd.MapKey().Kind())
+	valConv, _ := newConverter(ft.Elem(), fd.MapValue().Kind())
 	wiretag := wire.EncodeTag(fd.Number(), wireTypes[fd.Kind()])
 	wiretag := wire.EncodeTag(fd.Number(), wireTypes[fd.Kind()])
 	fieldOffset := offsetOf(fs)
 	fieldOffset := offsetOf(fs)
 	// TODO: Implement unsafe fast path?
 	// TODO: Implement unsafe fast path?
@@ -139,7 +140,7 @@ func fieldInfoForList(fd pref.FieldDescriptor, fs reflect.StructField) fieldInfo
 	if ft.Kind() != reflect.Slice {
 	if ft.Kind() != reflect.Slice {
 		panic(fmt.Sprintf("invalid type: got %v, want slice kind", ft))
 		panic(fmt.Sprintf("invalid type: got %v, want slice kind", ft))
 	}
 	}
-	conv := newConverter(ft.Elem(), fd.Kind())
+	conv, _ := newConverter(ft.Elem(), fd.Kind())
 	var wiretag uint64
 	var wiretag uint64
 	if !fd.IsPacked() {
 	if !fd.IsPacked() {
 		wiretag = wire.EncodeTag(fd.Number(), wireTypes[fd.Kind()])
 		wiretag = wire.EncodeTag(fd.Number(), wireTypes[fd.Kind()])
@@ -194,7 +195,7 @@ func fieldInfoForScalar(fd pref.FieldDescriptor, fs reflect.StructField) fieldIn
 			ft = ft.Elem()
 			ft = ft.Elem()
 		}
 		}
 	}
 	}
-	conv := newConverter(ft, fd.Kind())
+	conv, _ := newConverter(ft, fd.Kind())
 	fieldOffset := offsetOf(fs)
 	fieldOffset := offsetOf(fs)
 	wiretag := wire.EncodeTag(fd.Number(), wireTypes[fd.Kind()])
 	wiretag := wire.EncodeTag(fd.Number(), wireTypes[fd.Kind()])
 	// TODO: Implement unsafe fast path?
 	// TODO: Implement unsafe fast path?
@@ -264,7 +265,7 @@ func fieldInfoForScalar(fd pref.FieldDescriptor, fs reflect.StructField) fieldIn
 
 
 func fieldInfoForMessage(fd pref.FieldDescriptor, fs reflect.StructField) fieldInfo {
 func fieldInfoForMessage(fd pref.FieldDescriptor, fs reflect.StructField) fieldInfo {
 	ft := fs.Type
 	ft := fs.Type
-	conv := newConverter(ft, fd.Kind())
+	conv, _ := newConverter(ft, fd.Kind())
 	fieldOffset := offsetOf(fs)
 	fieldOffset := offsetOf(fs)
 	// TODO: Implement unsafe fast path?
 	// TODO: Implement unsafe fast path?
 	wiretag := wire.EncodeTag(fd.Number(), wireTypes[fd.Kind()])
 	wiretag := wire.EncodeTag(fd.Number(), wireTypes[fd.Kind()])
@@ -338,9 +339,52 @@ func makeOneofInfo(od pref.OneofDescriptor, fs reflect.StructField, wrappersByTy
 	}
 	}
 }
 }
 
 
-func newConverter(t reflect.Type, k pref.Kind) pvalue.Converter {
-	if legacyWrapper != nil {
-		return legacyWrapper.NewConverter(t, k)
+var (
+	enumIfaceV2    = reflect.TypeOf((*pref.Enum)(nil)).Elem()
+	messageIfaceV1 = reflect.TypeOf((*piface.MessageV1)(nil)).Elem()
+	messageIfaceV2 = reflect.TypeOf((*pref.ProtoMessage)(nil)).Elem()
+)
+
+func newConverter(t reflect.Type, k pref.Kind) (conv pvalue.Converter, isLegacy bool) {
+	switch k {
+	case pref.EnumKind:
+		if t.Kind() == reflect.Int32 && !t.Implements(enumIfaceV2) {
+			return pvalue.Converter{
+				PBValueOf: func(v reflect.Value) pref.Value {
+					if v.Type() != t {
+						panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), t))
+					}
+					return pref.ValueOf(pref.EnumNumber(v.Int()))
+				},
+				GoValueOf: func(v pref.Value) reflect.Value {
+					return reflect.ValueOf(v.Enum()).Convert(t)
+				},
+				NewEnum: func(n pref.EnumNumber) pref.Enum {
+					return legacyWrapEnum(reflect.ValueOf(n).Convert(t))
+				},
+			}, true
+		}
+	case pref.MessageKind, pref.GroupKind:
+		if t.Kind() == reflect.Ptr && t.Implements(messageIfaceV1) && !t.Implements(messageIfaceV2) {
+			return pvalue.Converter{
+				PBValueOf: func(v reflect.Value) pref.Value {
+					if v.Type() != t {
+						panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), t))
+					}
+					return pref.ValueOf(Export{}.MessageOf(v.Interface()))
+				},
+				GoValueOf: func(v pref.Value) reflect.Value {
+					rv := reflect.ValueOf(v.Message().(pvalue.Unwrapper).ProtoUnwrap())
+					if rv.Type() != t {
+						panic(fmt.Sprintf("invalid type: got %v, want %v", rv.Type(), t))
+					}
+					return rv
+				},
+				NewMessage: func() pref.Message {
+					return legacyWrapMessage(reflect.New(t.Elem())).ProtoReflect()
+				},
+			}, true
+		}
 	}
 	}
-	return pvalue.NewConverter(t, k)
+	return pvalue.NewConverter(t, k), false
 }
 }

+ 2 - 2
internal/impl/message_field_extension.go

@@ -231,14 +231,14 @@ func extensionDescFromType(typ pref.ExtensionType) *piface.ExtensionDescV1 {
 			return desc
 			return desc
 		}
 		}
 	}
 	}
-	return legacyWrapper.ExtensionDescFromType(typ)
+	return Export{}.ExtensionDescFromType(typ)
 }
 }
 
 
 func extensionTypeFromDesc(desc *piface.ExtensionDescV1) pref.ExtensionType {
 func extensionTypeFromDesc(desc *piface.ExtensionDescV1) pref.ExtensionType {
 	if desc.Type != nil {
 	if desc.Type != nil {
 		return desc.Type
 		return desc.Type
 	}
 	}
-	return legacyWrapper.ExtensionTypeFromDesc(desc)
+	return Export{}.ExtensionTypeFromDesc(desc)
 }
 }
 
 
 type ExtensionFieldV1 struct {
 type ExtensionFieldV1 struct {

+ 0 - 110
internal/legacy/export.go

@@ -1,110 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package legacy
-
-import (
-	"fmt"
-	"reflect"
-
-	pimpl "google.golang.org/protobuf/internal/impl"
-	pvalue "google.golang.org/protobuf/internal/value"
-	pref "google.golang.org/protobuf/reflect/protoreflect"
-	piface "google.golang.org/protobuf/runtime/protoiface"
-)
-
-// Export is a zero-length named type that exists only to export a set of
-// functions that we do not want to appear in godoc.
-type Export struct{}
-
-func (Export) EnumOf(e interface{}) pref.Enum {
-	return wrapEnum(reflect.ValueOf(e))
-}
-
-func (Export) EnumTypeOf(e interface{}) pref.EnumType {
-	return loadEnumType(reflect.TypeOf(e))
-}
-
-func (Export) EnumDescriptorOf(e interface{}) pref.EnumDescriptor {
-	return LoadEnumDesc(reflect.TypeOf(e))
-}
-
-func (Export) MessageOf(m interface{}) pref.Message {
-	return wrapMessage(reflect.ValueOf(m)).ProtoReflect()
-}
-
-func (Export) MessageTypeOf(m interface{}) pref.MessageType {
-	return loadMessageInfo(reflect.TypeOf(m)).PBType
-}
-
-func (Export) MessageDescriptorOf(m interface{}) pref.MessageDescriptor {
-	return LoadMessageDesc(reflect.TypeOf(m))
-}
-
-func (Export) ExtensionDescFromType(t pref.ExtensionType) *piface.ExtensionDescV1 {
-	return extensionDescFromType(t)
-}
-
-func (Export) ExtensionTypeFromDesc(d *piface.ExtensionDescV1) pref.ExtensionType {
-	return extensionTypeFromDesc(d)
-}
-
-var (
-	enumIfaceV2    = reflect.TypeOf((*pref.Enum)(nil)).Elem()
-	messageIfaceV1 = reflect.TypeOf((*piface.MessageV1)(nil)).Elem()
-	messageIfaceV2 = reflect.TypeOf((*pref.ProtoMessage)(nil)).Elem()
-)
-
-func (Export) NewConverter(t reflect.Type, k pref.Kind) pvalue.Converter {
-	c, _ := newConverter(t, k)
-	return c
-}
-
-func newConverter(t reflect.Type, k pref.Kind) (pvalue.Converter, bool) {
-	switch k {
-	case pref.EnumKind:
-		if t.Kind() == reflect.Int32 && !t.Implements(enumIfaceV2) {
-			return pvalue.Converter{
-				PBValueOf: func(v reflect.Value) pref.Value {
-					if v.Type() != t {
-						panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), t))
-					}
-					return pref.ValueOf(pref.EnumNumber(v.Int()))
-				},
-				GoValueOf: func(v pref.Value) reflect.Value {
-					return reflect.ValueOf(v.Enum()).Convert(t)
-				},
-				NewEnum: func(n pref.EnumNumber) pref.Enum {
-					return wrapEnum(reflect.ValueOf(n).Convert(t))
-				},
-			}, true
-		}
-	case pref.MessageKind, pref.GroupKind:
-		if t.Kind() == reflect.Ptr && t.Implements(messageIfaceV1) && !t.Implements(messageIfaceV2) {
-			return pvalue.Converter{
-				PBValueOf: func(v reflect.Value) pref.Value {
-					if v.Type() != t {
-						panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), t))
-					}
-					return pref.ValueOf(Export{}.MessageOf(v.Interface()))
-				},
-				GoValueOf: func(v pref.Value) reflect.Value {
-					rv := reflect.ValueOf(v.Message().(pvalue.Unwrapper).ProtoUnwrap())
-					if rv.Type() != t {
-						panic(fmt.Sprintf("invalid type: got %v, want %v", rv.Type(), t))
-					}
-					return rv
-				},
-				NewMessage: func() pref.Message {
-					return wrapMessage(reflect.New(t.Elem())).ProtoReflect()
-				},
-			}, true
-		}
-	}
-	return pvalue.NewConverter(t, k), false
-}
-
-func init() {
-	pimpl.RegisterLegacyWrapper(Export{})
-}

+ 0 - 97
internal/legacy/legacy_test.go

@@ -1,97 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package legacy
-
-import (
-	"sync"
-	"testing"
-
-	"google.golang.org/protobuf/reflect/protoreflect"
-)
-
-type (
-	MessageA struct {
-		A1 *MessageA `protobuf:"bytes,1,req,name=a1"`
-		A2 *MessageB `protobuf:"bytes,2,req,name=a2"`
-		A3 Enum      `protobuf:"varint,3,opt,name=a3,enum=legacy.Enum"`
-	}
-	MessageB struct {
-		B1 *MessageA `protobuf:"bytes,1,req,name=b1"`
-		B2 *MessageB `protobuf:"bytes,2,req,name=b2"`
-		B3 Enum      `protobuf:"varint,3,opt,name=b3,enum=legacy.Enum"`
-	}
-	Enum int32
-)
-
-// TestConcurrentInit tests that concurrent wrapping of multiple legacy types
-// results in the exact same descriptor being created.
-func TestConcurrentInit(t *testing.T) {
-	const numParallel = 5
-	var messageATypes [numParallel]protoreflect.MessageType
-	var messageBTypes [numParallel]protoreflect.MessageType
-	var enumDescs [numParallel]protoreflect.EnumDescriptor
-
-	// Concurrently load message and enum types.
-	var wg sync.WaitGroup
-	for i := 0; i < numParallel; i++ {
-		i := i
-		wg.Add(3)
-		go func() {
-			defer wg.Done()
-			messageATypes[i] = Export{}.MessageTypeOf((*MessageA)(nil))
-		}()
-		go func() {
-			defer wg.Done()
-			messageBTypes[i] = Export{}.MessageTypeOf((*MessageB)(nil))
-		}()
-		go func() {
-			defer wg.Done()
-			enumDescs[i] = Export{}.EnumDescriptorOf(Enum(0))
-		}()
-	}
-	wg.Wait()
-
-	var (
-		wantMTA = messageATypes[0]
-		wantMDA = messageATypes[0].Descriptor().Fields().ByNumber(1).Message()
-		wantMTB = messageBTypes[0]
-		wantMDB = messageBTypes[0].Descriptor().Fields().ByNumber(2).Message()
-		wantED  = messageATypes[0].Descriptor().Fields().ByNumber(3).Enum()
-	)
-
-	for _, gotMT := range messageATypes[1:] {
-		if gotMT != wantMTA {
-			t.Error("MessageType(MessageA) mismatch")
-		}
-		if gotMDA := gotMT.Descriptor().Fields().ByNumber(1).Message(); gotMDA != wantMDA {
-			t.Error("MessageDescriptor(MessageA) mismatch")
-		}
-		if gotMDB := gotMT.Descriptor().Fields().ByNumber(2).Message(); gotMDB != wantMDB {
-			t.Error("MessageDescriptor(MessageB) mismatch")
-		}
-		if gotED := gotMT.Descriptor().Fields().ByNumber(3).Enum(); gotED != wantED {
-			t.Error("EnumDescriptor(Enum) mismatch")
-		}
-	}
-	for _, gotMT := range messageBTypes[1:] {
-		if gotMT != wantMTB {
-			t.Error("MessageType(MessageB) mismatch")
-		}
-		if gotMDA := gotMT.Descriptor().Fields().ByNumber(1).Message(); gotMDA != wantMDA {
-			t.Error("MessageDescriptor(MessageA) mismatch")
-		}
-		if gotMDB := gotMT.Descriptor().Fields().ByNumber(2).Message(); gotMDB != wantMDB {
-			t.Error("MessageDescriptor(MessageB) mismatch")
-		}
-		if gotED := gotMT.Descriptor().Fields().ByNumber(3).Enum(); gotED != wantED {
-			t.Error("EnumDescriptor(Enum) mismatch")
-		}
-	}
-	for _, gotED := range enumDescs[1:] {
-		if gotED != wantED {
-			t.Error("EnumType(Enum) mismatch")
-		}
-	}
-}

+ 5 - 9
runtime/protolegacy/legacy.go

@@ -2,15 +2,11 @@
 // Use of this source code is governed by a BSD-style
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 // license that can be found in the LICENSE file.
 
 
-// Package protolegacy contains the default implementation for messages
-// generated by protoc-gen-go.
-//
-// WARNING: This package should only ever be imported by the v1 proto package.
-// The compatibility agreement covers nothing except for functionality needed
-// to provide v1 interoperability. Breakages that occur due to unauthorized
-// usages of this package are not the author's responsibility.
+// Deprecated: Do not use.
 package protolegacy
 package protolegacy
 
 
-import "google.golang.org/protobuf/internal/legacy"
+// TODO: Remove this.
 
 
-var X legacy.Export
+import "google.golang.org/protobuf/internal/impl"
+
+var X impl.Export