all: unify protoV1.ExtensionDesc and proto.ExtensionType

Change protoV1.ExtensionDesc to directly implement ExtensionType
rather than delegating to one.

Unify the previous types protoiface.ExtensionDescV1 and
filetype.Extension in impl.ExtensionInfo. The protoV1.ExtensionDesc
type becomes an alias to ExtensionInfo.

This gives us:

  - Just one implementation of ExtensionType.
  - Generated foopb.E_Ext vars are canonical ExtensionTypes.
  - Generated foopb.E_Ext vars are also v1.ExtensionDescs for backwards
    compatibility.
  - Conversion between legacy and modern representations happens
    transparently when lazily initializing an ExtensionInfo.

Overall, a simplification for users of generated code, since they can
mostly ignore the ExtensionDesc/ExtentionType distinction and use the
same value in either the old or new API.

This is change 3/5 in a series of commits changing protoV1.ExtensionDesc
to directly implement protoreflect.ExtensionType.

1. [v2] Add protoimpl.ExtensionInfo as an alias for
   protoiface.ExtensionDescV1.

2. [v1] Update references to protoimpl.ExtensionInfo to use
   protoiface.ExtensionInfo.

3. [v2] Create protoimpl.ExtensionInfo (an alias to a new type in
   the impl package) and remove protoiface.ExtensionDescV1.

4. [v1] Remove unneeded explicit conversions between ExtensionDesc and
   ExtensionType (since the former now directly implements the latter).

5. [v2] Remove stub conversion functions.

Change-Id: I96ee890541ec11b2412e1a72c9d7b96e4d7f66b4
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/189563
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/cmd/protoc-gen-go-grpc/testdata/go.mod b/cmd/protoc-gen-go-grpc/testdata/go.mod
index 2b2c716..0879f28 100644
--- a/cmd/protoc-gen-go-grpc/testdata/go.mod
+++ b/cmd/protoc-gen-go-grpc/testdata/go.mod
@@ -1,7 +1,7 @@
 module google.golang.org/protobuf/cmd/protoc-gen-go-grpc/testdata
 
 require (
-	github.com/golang/protobuf v1.2.1-0.20190806214225-7037721e6de0
+	github.com/golang/protobuf v1.2.1-0.20190820204156-2da1b93405dd
 	google.golang.org/grpc v1.19.0
 	google.golang.org/protobuf v1.0.0
 )
diff --git a/cmd/protoc-gen-go/internal_gengo/main.go b/cmd/protoc-gen-go/internal_gengo/main.go
index 9a421e0..c393257 100644
--- a/cmd/protoc-gen-go/internal_gengo/main.go
+++ b/cmd/protoc-gen-go/internal_gengo/main.go
@@ -831,7 +831,7 @@
 		return
 	}
 
-	g.P("var ", extDescsVarName(f), " = []", protoifacePackage.Ident("ExtensionDescV1"), "{")
+	g.P("var ", extensionTypesVarName(f), " = []", protoimplPackage.Ident("ExtensionInfo"), "{")
 	for _, extension := range f.allExtensions {
 		g.P("{")
 		g.P("ExtendedType: (*", extension.Extendee.GoIdent, ")(nil),")
@@ -884,7 +884,7 @@
 			leadingComments = appendDeprecationSuffix(leadingComments,
 				extension.Desc.Options().(*descriptorpb.FieldOptions).GetDeprecated())
 			g.P(leadingComments,
-				extensionVar(f.File, extension), " = &", extDescsVarName(f), "[", allExtensionsByPtr[extension], "]",
+				extensionVar(f.File, extension), " = &", extensionTypesVarName(f), "[", allExtensionsByPtr[extension], "]",
 				trailingComment(extension.Comments.Trailing))
 		}
 		g.P(")")
diff --git a/cmd/protoc-gen-go/internal_gengo/reflect.go b/cmd/protoc-gen-go/internal_gengo/reflect.go
index 3c1c2d5..c453e73 100644
--- a/cmd/protoc-gen-go/internal_gengo/reflect.go
+++ b/cmd/protoc-gen-go/internal_gengo/reflect.go
@@ -219,7 +219,7 @@
 		g.P("MessageInfos: ", messageTypesVarName(f), ",")
 	}
 	if len(f.allExtensions) > 0 {
-		g.P("LegacyExtensions: ", extDescsVarName(f), ",")
+		g.P("ExtensionInfos: ", extensionTypesVarName(f), ",")
 	}
 	g.P("}.Build()")
 	g.P(f.GoDescriptorIdent, " = out.File")
@@ -344,8 +344,8 @@
 func messageTypesVarName(f *fileInfo) string {
 	return fileVarName(f.File, "msgTypes")
 }
-func extDescsVarName(f *fileInfo) string {
-	return fileVarName(f.File, "extDescs")
+func extensionTypesVarName(f *fileInfo) string {
+	return fileVarName(f.File, "extTypes")
 }
 func initFuncName(f *protogen.File) string {
 	return fileVarName(f, "init")
diff --git a/cmd/protoc-gen-go/testdata/comments/comments.pb.go b/cmd/protoc-gen-go/testdata/comments/comments.pb.go
index b83cd3e..3c23def 100644
--- a/cmd/protoc-gen-go/testdata/comments/comments.pb.go
+++ b/cmd/protoc-gen-go/testdata/comments/comments.pb.go
@@ -330,7 +330,7 @@
 	return file_comments_comments_proto_rawDescGZIP(), []int{1, 1}
 }
 
-var file_comments_comments_proto_extDescs = []protoiface.ExtensionDescV1{
+var file_comments_comments_proto_extTypes = []protoimpl.ExtensionInfo{
 	{
 		ExtendedType:  (*Message1)(nil),
 		ExtensionType: (*Message1)(nil),
@@ -346,7 +346,7 @@
 	// COMMENT: Extension.Leading
 	//
 	// optional goproto.protoc.comments.Message1 extension = 100;
-	E_Extension = &file_comments_comments_proto_extDescs[0] // COMMENT: Extension.Trailing
+	E_Extension = &file_comments_comments_proto_extTypes[0] // COMMENT: Extension.Trailing
 )
 
 var File_comments_comments_proto protoreflect.FileDescriptor
@@ -511,7 +511,7 @@
 		DependencyIndexes: file_comments_comments_proto_depIdxs,
 		EnumInfos:         file_comments_comments_proto_enumTypes,
 		MessageInfos:      file_comments_comments_proto_msgTypes,
-		LegacyExtensions:  file_comments_comments_proto_extDescs,
+		ExtensionInfos:    file_comments_comments_proto_extTypes,
 	}.Build()
 	File_comments_comments_proto = out.File
 	file_comments_comments_proto_rawDesc = nil
diff --git a/cmd/protoc-gen-go/testdata/extensions/ext/ext.pb.go b/cmd/protoc-gen-go/testdata/extensions/ext/ext.pb.go
index 7e6a477..a357004 100644
--- a/cmd/protoc-gen-go/testdata/extensions/ext/ext.pb.go
+++ b/cmd/protoc-gen-go/testdata/extensions/ext/ext.pb.go
@@ -374,7 +374,7 @@
 	return file_extensions_ext_ext_proto_rawDescGZIP(), []int{2, 0}
 }
 
-var file_extensions_ext_ext_proto_extDescs = []protoiface.ExtensionDescV1{
+var file_extensions_ext_ext_proto_extTypes = []protoimpl.ExtensionInfo{
 	{
 		ExtendedType:  (*base.BaseMessage)(nil),
 		ExtensionType: (*bool)(nil),
@@ -732,101 +732,101 @@
 // Extension fields to base.BaseMessage.
 var (
 	// optional bool extension_bool = 101;
-	E_ExtensionBool = &file_extensions_ext_ext_proto_extDescs[0]
+	E_ExtensionBool = &file_extensions_ext_ext_proto_extTypes[0]
 	// optional goproto.protoc.extension.ext.Enum extension_enum = 102;
-	E_ExtensionEnum = &file_extensions_ext_ext_proto_extDescs[1]
+	E_ExtensionEnum = &file_extensions_ext_ext_proto_extTypes[1]
 	// optional int32 extension_int32 = 103;
-	E_ExtensionInt32 = &file_extensions_ext_ext_proto_extDescs[2]
+	E_ExtensionInt32 = &file_extensions_ext_ext_proto_extTypes[2]
 	// optional sint32 extension_sint32 = 104;
-	E_ExtensionSint32 = &file_extensions_ext_ext_proto_extDescs[3]
+	E_ExtensionSint32 = &file_extensions_ext_ext_proto_extTypes[3]
 	// optional uint32 extension_uint32 = 105;
-	E_ExtensionUint32 = &file_extensions_ext_ext_proto_extDescs[4]
+	E_ExtensionUint32 = &file_extensions_ext_ext_proto_extTypes[4]
 	// optional int64 extension_int64 = 106;
-	E_ExtensionInt64 = &file_extensions_ext_ext_proto_extDescs[5]
+	E_ExtensionInt64 = &file_extensions_ext_ext_proto_extTypes[5]
 	// optional sint64 extension_sint64 = 107;
-	E_ExtensionSint64 = &file_extensions_ext_ext_proto_extDescs[6]
+	E_ExtensionSint64 = &file_extensions_ext_ext_proto_extTypes[6]
 	// optional uint64 extension_uint64 = 108;
-	E_ExtensionUint64 = &file_extensions_ext_ext_proto_extDescs[7]
+	E_ExtensionUint64 = &file_extensions_ext_ext_proto_extTypes[7]
 	// optional sfixed32 extension_sfixed32 = 109;
-	E_ExtensionSfixed32 = &file_extensions_ext_ext_proto_extDescs[8]
+	E_ExtensionSfixed32 = &file_extensions_ext_ext_proto_extTypes[8]
 	// optional fixed32 extension_fixed32 = 110;
-	E_ExtensionFixed32 = &file_extensions_ext_ext_proto_extDescs[9]
+	E_ExtensionFixed32 = &file_extensions_ext_ext_proto_extTypes[9]
 	// optional float extension_float = 111;
-	E_ExtensionFloat = &file_extensions_ext_ext_proto_extDescs[10]
+	E_ExtensionFloat = &file_extensions_ext_ext_proto_extTypes[10]
 	// optional sfixed64 extension_sfixed64 = 112;
-	E_ExtensionSfixed64 = &file_extensions_ext_ext_proto_extDescs[11]
+	E_ExtensionSfixed64 = &file_extensions_ext_ext_proto_extTypes[11]
 	// optional fixed64 extension_fixed64 = 113;
-	E_ExtensionFixed64 = &file_extensions_ext_ext_proto_extDescs[12]
+	E_ExtensionFixed64 = &file_extensions_ext_ext_proto_extTypes[12]
 	// optional double extension_double = 114;
-	E_ExtensionDouble = &file_extensions_ext_ext_proto_extDescs[13]
+	E_ExtensionDouble = &file_extensions_ext_ext_proto_extTypes[13]
 	// optional string extension_string = 115;
-	E_ExtensionString = &file_extensions_ext_ext_proto_extDescs[14]
+	E_ExtensionString = &file_extensions_ext_ext_proto_extTypes[14]
 	// optional bytes extension_bytes = 116;
-	E_ExtensionBytes = &file_extensions_ext_ext_proto_extDescs[15]
+	E_ExtensionBytes = &file_extensions_ext_ext_proto_extTypes[15]
 	// optional goproto.protoc.extension.ext.Message extension_Message = 117;
-	E_Extension_Message = &file_extensions_ext_ext_proto_extDescs[16]
+	E_Extension_Message = &file_extensions_ext_ext_proto_extTypes[16]
 	// optional goproto.protoc.extension.ext.Message.M extension_MessageM = 118;
-	E_Extension_MessageM = &file_extensions_ext_ext_proto_extDescs[17]
+	E_Extension_MessageM = &file_extensions_ext_ext_proto_extTypes[17]
 	// optional goproto.protoc.extension.ext.ExtensionGroup extensiongroup = 119;
-	E_Extensiongroup = &file_extensions_ext_ext_proto_extDescs[18]
+	E_Extensiongroup = &file_extensions_ext_ext_proto_extTypes[18]
 	// optional goproto.protoc.extension.extra.ExtraMessage extra_message = 9;
-	E_ExtraMessage = &file_extensions_ext_ext_proto_extDescs[19]
+	E_ExtraMessage = &file_extensions_ext_ext_proto_extTypes[19]
 	// repeated bool repeated_x_bool = 301;
-	E_RepeatedXBool = &file_extensions_ext_ext_proto_extDescs[20]
+	E_RepeatedXBool = &file_extensions_ext_ext_proto_extTypes[20]
 	// repeated goproto.protoc.extension.ext.Enum repeated_x_enum = 302;
-	E_RepeatedXEnum = &file_extensions_ext_ext_proto_extDescs[21]
+	E_RepeatedXEnum = &file_extensions_ext_ext_proto_extTypes[21]
 	// repeated int32 repeated_x_int32 = 303;
-	E_RepeatedXInt32 = &file_extensions_ext_ext_proto_extDescs[22]
+	E_RepeatedXInt32 = &file_extensions_ext_ext_proto_extTypes[22]
 	// repeated sint32 repeated_x_sint32 = 304;
-	E_RepeatedXSint32 = &file_extensions_ext_ext_proto_extDescs[23]
+	E_RepeatedXSint32 = &file_extensions_ext_ext_proto_extTypes[23]
 	// repeated uint32 repeated_x_uint32 = 305;
-	E_RepeatedXUint32 = &file_extensions_ext_ext_proto_extDescs[24]
+	E_RepeatedXUint32 = &file_extensions_ext_ext_proto_extTypes[24]
 	// repeated int64 repeated_x_int64 = 306;
-	E_RepeatedXInt64 = &file_extensions_ext_ext_proto_extDescs[25]
+	E_RepeatedXInt64 = &file_extensions_ext_ext_proto_extTypes[25]
 	// repeated sint64 repeated_x_sint64 = 307;
-	E_RepeatedXSint64 = &file_extensions_ext_ext_proto_extDescs[26]
+	E_RepeatedXSint64 = &file_extensions_ext_ext_proto_extTypes[26]
 	// repeated uint64 repeated_x_uint64 = 308;
-	E_RepeatedXUint64 = &file_extensions_ext_ext_proto_extDescs[27]
+	E_RepeatedXUint64 = &file_extensions_ext_ext_proto_extTypes[27]
 	// repeated sfixed32 repeated_x_sfixed32 = 309;
-	E_RepeatedXSfixed32 = &file_extensions_ext_ext_proto_extDescs[28]
+	E_RepeatedXSfixed32 = &file_extensions_ext_ext_proto_extTypes[28]
 	// repeated fixed32 repeated_x_fixed32 = 310;
-	E_RepeatedXFixed32 = &file_extensions_ext_ext_proto_extDescs[29]
+	E_RepeatedXFixed32 = &file_extensions_ext_ext_proto_extTypes[29]
 	// repeated float repeated_x_float = 311;
-	E_RepeatedXFloat = &file_extensions_ext_ext_proto_extDescs[30]
+	E_RepeatedXFloat = &file_extensions_ext_ext_proto_extTypes[30]
 	// repeated sfixed64 repeated_x_sfixed64 = 312;
-	E_RepeatedXSfixed64 = &file_extensions_ext_ext_proto_extDescs[31]
+	E_RepeatedXSfixed64 = &file_extensions_ext_ext_proto_extTypes[31]
 	// repeated fixed64 repeated_x_fixed64 = 313;
-	E_RepeatedXFixed64 = &file_extensions_ext_ext_proto_extDescs[32]
+	E_RepeatedXFixed64 = &file_extensions_ext_ext_proto_extTypes[32]
 	// repeated double repeated_x_double = 314;
-	E_RepeatedXDouble = &file_extensions_ext_ext_proto_extDescs[33]
+	E_RepeatedXDouble = &file_extensions_ext_ext_proto_extTypes[33]
 	// repeated string repeated_x_string = 315;
-	E_RepeatedXString = &file_extensions_ext_ext_proto_extDescs[34]
+	E_RepeatedXString = &file_extensions_ext_ext_proto_extTypes[34]
 	// repeated bytes repeated_x_bytes = 316;
-	E_RepeatedXBytes = &file_extensions_ext_ext_proto_extDescs[35]
+	E_RepeatedXBytes = &file_extensions_ext_ext_proto_extTypes[35]
 	// repeated goproto.protoc.extension.ext.Message repeated_x_Message = 317;
-	E_RepeatedX_Message = &file_extensions_ext_ext_proto_extDescs[36]
+	E_RepeatedX_Message = &file_extensions_ext_ext_proto_extTypes[36]
 	// repeated goproto.protoc.extension.ext.RepeatedGroup repeatedgroup = 318;
-	E_Repeatedgroup = &file_extensions_ext_ext_proto_extDescs[37]
+	E_Repeatedgroup = &file_extensions_ext_ext_proto_extTypes[37]
 	// optional goproto.protoc.extension.ext.Extendable extendable_field = 400;
-	E_ExtendableField = &file_extensions_ext_ext_proto_extDescs[38]
+	E_ExtendableField = &file_extensions_ext_ext_proto_extTypes[38]
 	// optional string extending_message_string = 200;
-	E_ExtendingMessage_ExtendingMessageString = &file_extensions_ext_ext_proto_extDescs[41]
+	E_ExtendingMessage_ExtendingMessageString = &file_extensions_ext_ext_proto_extTypes[41]
 	// optional goproto.protoc.extension.ext.ExtendingMessage.ExtendingMessageSubmessage extending_message_submessage = 201;
-	E_ExtendingMessage_ExtendingMessageSubmessage = &file_extensions_ext_ext_proto_extDescs[42]
+	E_ExtendingMessage_ExtendingMessageSubmessage = &file_extensions_ext_ext_proto_extTypes[42]
 )
 
 // Extension fields to Extendable.
 var (
 	// optional string extendable_string_field = 1;
-	E_ExtendableStringField = &file_extensions_ext_ext_proto_extDescs[39]
+	E_ExtendableStringField = &file_extensions_ext_ext_proto_extTypes[39]
 )
 
 // Extension fields to base.MessageSetWireFormatMessage.
 var (
 	// optional goproto.protoc.extension.ext.MessageSetWireFormatExtension message_set_extension = 101;
-	E_MessageSetExtension = &file_extensions_ext_ext_proto_extDescs[40]
+	E_MessageSetExtension = &file_extensions_ext_ext_proto_extTypes[40]
 	// optional goproto.protoc.extension.ext.MessageSetWireFormatExtension message_set_extension = 100;
-	E_MessageSetWireFormatExtension_MessageSetExtension = &file_extensions_ext_ext_proto_extDescs[43]
+	E_MessageSetWireFormatExtension_MessageSetExtension = &file_extensions_ext_ext_proto_extTypes[43]
 )
 
 var File_extensions_ext_ext_proto protoreflect.FileDescriptor
@@ -1358,7 +1358,7 @@
 		DependencyIndexes: file_extensions_ext_ext_proto_depIdxs,
 		EnumInfos:         file_extensions_ext_ext_proto_enumTypes,
 		MessageInfos:      file_extensions_ext_ext_proto_msgTypes,
-		LegacyExtensions:  file_extensions_ext_ext_proto_extDescs,
+		ExtensionInfos:    file_extensions_ext_ext_proto_extTypes,
 	}.Build()
 	File_extensions_ext_ext_proto = out.File
 	file_extensions_ext_ext_proto_rawDesc = nil
diff --git a/cmd/protoc-gen-go/testdata/extensions/proto3/ext3.pb.go b/cmd/protoc-gen-go/testdata/extensions/proto3/ext3.pb.go
index 6243cd7..b21730c 100644
--- a/cmd/protoc-gen-go/testdata/extensions/proto3/ext3.pb.go
+++ b/cmd/protoc-gen-go/testdata/extensions/proto3/ext3.pb.go
@@ -9,7 +9,6 @@
 
 import (
 	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
-	protoiface "google.golang.org/protobuf/runtime/protoiface"
 	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
 	descriptorpb "google.golang.org/protobuf/types/descriptorpb"
 	reflect "reflect"
@@ -92,7 +91,7 @@
 	return file_extensions_proto3_ext3_proto_rawDescGZIP(), []int{0}
 }
 
-var file_extensions_proto3_ext3_proto_extDescs = []protoiface.ExtensionDescV1{
+var file_extensions_proto3_ext3_proto_extTypes = []protoimpl.ExtensionInfo{
 	{
 		ExtendedType:  (*descriptorpb.MessageOptions)(nil),
 		ExtensionType: (*bool)(nil),
@@ -370,73 +369,73 @@
 // Extension fields to descriptorpb.MessageOptions.
 var (
 	// optional bool extension_bool = 1001;
-	E_ExtensionBool = &file_extensions_proto3_ext3_proto_extDescs[0]
+	E_ExtensionBool = &file_extensions_proto3_ext3_proto_extTypes[0]
 	// optional goproto.protoc.extension.proto3.Enum extension_enum = 1002;
-	E_ExtensionEnum = &file_extensions_proto3_ext3_proto_extDescs[1]
+	E_ExtensionEnum = &file_extensions_proto3_ext3_proto_extTypes[1]
 	// optional int32 extension_int32 = 1003;
-	E_ExtensionInt32 = &file_extensions_proto3_ext3_proto_extDescs[2]
+	E_ExtensionInt32 = &file_extensions_proto3_ext3_proto_extTypes[2]
 	// optional sint32 extension_sint32 = 1004;
-	E_ExtensionSint32 = &file_extensions_proto3_ext3_proto_extDescs[3]
+	E_ExtensionSint32 = &file_extensions_proto3_ext3_proto_extTypes[3]
 	// optional uint32 extension_uint32 = 1005;
-	E_ExtensionUint32 = &file_extensions_proto3_ext3_proto_extDescs[4]
+	E_ExtensionUint32 = &file_extensions_proto3_ext3_proto_extTypes[4]
 	// optional int64 extension_int64 = 1006;
-	E_ExtensionInt64 = &file_extensions_proto3_ext3_proto_extDescs[5]
+	E_ExtensionInt64 = &file_extensions_proto3_ext3_proto_extTypes[5]
 	// optional sint64 extension_sint64 = 1007;
-	E_ExtensionSint64 = &file_extensions_proto3_ext3_proto_extDescs[6]
+	E_ExtensionSint64 = &file_extensions_proto3_ext3_proto_extTypes[6]
 	// optional uint64 extension_uint64 = 1008;
-	E_ExtensionUint64 = &file_extensions_proto3_ext3_proto_extDescs[7]
+	E_ExtensionUint64 = &file_extensions_proto3_ext3_proto_extTypes[7]
 	// optional sfixed32 extension_sfixed32 = 1009;
-	E_ExtensionSfixed32 = &file_extensions_proto3_ext3_proto_extDescs[8]
+	E_ExtensionSfixed32 = &file_extensions_proto3_ext3_proto_extTypes[8]
 	// optional fixed32 extension_fixed32 = 1010;
-	E_ExtensionFixed32 = &file_extensions_proto3_ext3_proto_extDescs[9]
+	E_ExtensionFixed32 = &file_extensions_proto3_ext3_proto_extTypes[9]
 	// optional float extension_float = 1011;
-	E_ExtensionFloat = &file_extensions_proto3_ext3_proto_extDescs[10]
+	E_ExtensionFloat = &file_extensions_proto3_ext3_proto_extTypes[10]
 	// optional sfixed64 extension_sfixed64 = 1012;
-	E_ExtensionSfixed64 = &file_extensions_proto3_ext3_proto_extDescs[11]
+	E_ExtensionSfixed64 = &file_extensions_proto3_ext3_proto_extTypes[11]
 	// optional fixed64 extension_fixed64 = 1013;
-	E_ExtensionFixed64 = &file_extensions_proto3_ext3_proto_extDescs[12]
+	E_ExtensionFixed64 = &file_extensions_proto3_ext3_proto_extTypes[12]
 	// optional double extension_double = 1014;
-	E_ExtensionDouble = &file_extensions_proto3_ext3_proto_extDescs[13]
+	E_ExtensionDouble = &file_extensions_proto3_ext3_proto_extTypes[13]
 	// optional string extension_string = 1015;
-	E_ExtensionString = &file_extensions_proto3_ext3_proto_extDescs[14]
+	E_ExtensionString = &file_extensions_proto3_ext3_proto_extTypes[14]
 	// optional bytes extension_bytes = 1016;
-	E_ExtensionBytes = &file_extensions_proto3_ext3_proto_extDescs[15]
+	E_ExtensionBytes = &file_extensions_proto3_ext3_proto_extTypes[15]
 	// optional goproto.protoc.extension.proto3.Message extension_Message = 1017;
-	E_Extension_Message = &file_extensions_proto3_ext3_proto_extDescs[16]
+	E_Extension_Message = &file_extensions_proto3_ext3_proto_extTypes[16]
 	// repeated bool repeated_extension_bool = 2001;
-	E_RepeatedExtensionBool = &file_extensions_proto3_ext3_proto_extDescs[17]
+	E_RepeatedExtensionBool = &file_extensions_proto3_ext3_proto_extTypes[17]
 	// repeated goproto.protoc.extension.proto3.Enum repeated_extension_enum = 2002;
-	E_RepeatedExtensionEnum = &file_extensions_proto3_ext3_proto_extDescs[18]
+	E_RepeatedExtensionEnum = &file_extensions_proto3_ext3_proto_extTypes[18]
 	// repeated int32 repeated_extension_int32 = 2003;
-	E_RepeatedExtensionInt32 = &file_extensions_proto3_ext3_proto_extDescs[19]
+	E_RepeatedExtensionInt32 = &file_extensions_proto3_ext3_proto_extTypes[19]
 	// repeated sint32 repeated_extension_sint32 = 2004;
-	E_RepeatedExtensionSint32 = &file_extensions_proto3_ext3_proto_extDescs[20]
+	E_RepeatedExtensionSint32 = &file_extensions_proto3_ext3_proto_extTypes[20]
 	// repeated uint32 repeated_extension_uint32 = 2005;
-	E_RepeatedExtensionUint32 = &file_extensions_proto3_ext3_proto_extDescs[21]
+	E_RepeatedExtensionUint32 = &file_extensions_proto3_ext3_proto_extTypes[21]
 	// repeated int64 repeated_extension_int64 = 2006;
-	E_RepeatedExtensionInt64 = &file_extensions_proto3_ext3_proto_extDescs[22]
+	E_RepeatedExtensionInt64 = &file_extensions_proto3_ext3_proto_extTypes[22]
 	// repeated sint64 repeated_extension_sint64 = 2007;
-	E_RepeatedExtensionSint64 = &file_extensions_proto3_ext3_proto_extDescs[23]
+	E_RepeatedExtensionSint64 = &file_extensions_proto3_ext3_proto_extTypes[23]
 	// repeated uint64 repeated_extension_uint64 = 2008;
-	E_RepeatedExtensionUint64 = &file_extensions_proto3_ext3_proto_extDescs[24]
+	E_RepeatedExtensionUint64 = &file_extensions_proto3_ext3_proto_extTypes[24]
 	// repeated sfixed32 repeated_extension_sfixed32 = 2009;
-	E_RepeatedExtensionSfixed32 = &file_extensions_proto3_ext3_proto_extDescs[25]
+	E_RepeatedExtensionSfixed32 = &file_extensions_proto3_ext3_proto_extTypes[25]
 	// repeated fixed32 repeated_extension_fixed32 = 2010;
-	E_RepeatedExtensionFixed32 = &file_extensions_proto3_ext3_proto_extDescs[26]
+	E_RepeatedExtensionFixed32 = &file_extensions_proto3_ext3_proto_extTypes[26]
 	// repeated float repeated_extension_float = 2011;
-	E_RepeatedExtensionFloat = &file_extensions_proto3_ext3_proto_extDescs[27]
+	E_RepeatedExtensionFloat = &file_extensions_proto3_ext3_proto_extTypes[27]
 	// repeated sfixed64 repeated_extension_sfixed64 = 2012;
-	E_RepeatedExtensionSfixed64 = &file_extensions_proto3_ext3_proto_extDescs[28]
+	E_RepeatedExtensionSfixed64 = &file_extensions_proto3_ext3_proto_extTypes[28]
 	// repeated fixed64 repeated_extension_fixed64 = 2013;
-	E_RepeatedExtensionFixed64 = &file_extensions_proto3_ext3_proto_extDescs[29]
+	E_RepeatedExtensionFixed64 = &file_extensions_proto3_ext3_proto_extTypes[29]
 	// repeated double repeated_extension_double = 2014;
-	E_RepeatedExtensionDouble = &file_extensions_proto3_ext3_proto_extDescs[30]
+	E_RepeatedExtensionDouble = &file_extensions_proto3_ext3_proto_extTypes[30]
 	// repeated string repeated_extension_string = 2015;
-	E_RepeatedExtensionString = &file_extensions_proto3_ext3_proto_extDescs[31]
+	E_RepeatedExtensionString = &file_extensions_proto3_ext3_proto_extTypes[31]
 	// repeated bytes repeated_extension_bytes = 2016;
-	E_RepeatedExtensionBytes = &file_extensions_proto3_ext3_proto_extDescs[32]
+	E_RepeatedExtensionBytes = &file_extensions_proto3_ext3_proto_extTypes[32]
 	// repeated goproto.protoc.extension.proto3.Message repeated_extension_Message = 2017;
-	E_RepeatedExtension_Message = &file_extensions_proto3_ext3_proto_extDescs[33]
+	E_RepeatedExtension_Message = &file_extensions_proto3_ext3_proto_extTypes[33]
 )
 
 var File_extensions_proto3_ext3_proto protoreflect.FileDescriptor
@@ -747,7 +746,7 @@
 		DependencyIndexes: file_extensions_proto3_ext3_proto_depIdxs,
 		EnumInfos:         file_extensions_proto3_ext3_proto_enumTypes,
 		MessageInfos:      file_extensions_proto3_ext3_proto_msgTypes,
-		LegacyExtensions:  file_extensions_proto3_ext3_proto_extDescs,
+		ExtensionInfos:    file_extensions_proto3_ext3_proto_extTypes,
 	}.Build()
 	File_extensions_proto3_ext3_proto = out.File
 	file_extensions_proto3_ext3_proto_rawDesc = nil
diff --git a/cmd/protoc-gen-go/testdata/go.mod b/cmd/protoc-gen-go/testdata/go.mod
index 2413632..94d6dd1 100644
--- a/cmd/protoc-gen-go/testdata/go.mod
+++ b/cmd/protoc-gen-go/testdata/go.mod
@@ -1,7 +1,7 @@
 module google.golang.org/protobuf/cmd/protoc-gen-go/testdata
 
 require (
-	github.com/golang/protobuf v1.2.1-0.20190806214225-7037721e6de0
+	github.com/golang/protobuf v1.2.1-0.20190820204156-2da1b93405dd
 	google.golang.org/protobuf v1.0.0
 )
 
diff --git a/cmd/protoc-gen-go/testdata/import_public/sub/a.pb.go b/cmd/protoc-gen-go/testdata/import_public/sub/a.pb.go
index dd85474..ec0b448 100644
--- a/cmd/protoc-gen-go/testdata/import_public/sub/a.pb.go
+++ b/cmd/protoc-gen-go/testdata/import_public/sub/a.pb.go
@@ -384,7 +384,7 @@
 
 func (*M_Submessage_SubmessageOneofInt64) isM_Submessage_SubmessageOneofField() {}
 
-var file_import_public_sub_a_proto_extDescs = []protoiface.ExtensionDescV1{
+var file_import_public_sub_a_proto_extTypes = []protoimpl.ExtensionInfo{
 	{
 		ExtendedType:  (*M)(nil),
 		ExtensionType: (*string)(nil),
@@ -398,7 +398,7 @@
 // Extension fields to M.
 var (
 	// optional string extension_field = 100;
-	E_ExtensionField = &file_import_public_sub_a_proto_extDescs[0]
+	E_ExtensionField = &file_import_public_sub_a_proto_extTypes[0]
 )
 
 var File_import_public_sub_a_proto protoreflect.FileDescriptor
@@ -540,7 +540,7 @@
 		DependencyIndexes: file_import_public_sub_a_proto_depIdxs,
 		EnumInfos:         file_import_public_sub_a_proto_enumTypes,
 		MessageInfos:      file_import_public_sub_a_proto_msgTypes,
-		LegacyExtensions:  file_import_public_sub_a_proto_extDescs,
+		ExtensionInfos:    file_import_public_sub_a_proto_extTypes,
 	}.Build()
 	File_import_public_sub_a_proto = out.File
 	file_import_public_sub_a_proto_rawDesc = nil
diff --git a/encoding/testprotos/pb2/test.pb.go b/encoding/testprotos/pb2/test.pb.go
index 1925bc4..2565c02 100644
--- a/encoding/testprotos/pb2/test.pb.go
+++ b/encoding/testprotos/pb2/test.pb.go
@@ -1442,7 +1442,7 @@
 	return 0
 }
 
-var file_pb2_test_proto_extDescs = []protoiface.ExtensionDescV1{
+var file_pb2_test_proto_extTypes = []protoimpl.ExtensionInfo{
 	{
 		ExtendedType:  (*Extensions)(nil),
 		ExtensionType: (*bool)(nil),
@@ -1616,55 +1616,55 @@
 // Extension fields to Extensions.
 var (
 	// optional bool opt_ext_bool = 21;
-	E_OptExtBool = &file_pb2_test_proto_extDescs[0]
+	E_OptExtBool = &file_pb2_test_proto_extTypes[0]
 	// optional string opt_ext_string = 22;
-	E_OptExtString = &file_pb2_test_proto_extDescs[1]
+	E_OptExtString = &file_pb2_test_proto_extTypes[1]
 	// optional pb2.Enum opt_ext_enum = 23;
-	E_OptExtEnum = &file_pb2_test_proto_extDescs[2]
+	E_OptExtEnum = &file_pb2_test_proto_extTypes[2]
 	// optional pb2.Nested opt_ext_nested = 24;
-	E_OptExtNested = &file_pb2_test_proto_extDescs[3]
+	E_OptExtNested = &file_pb2_test_proto_extTypes[3]
 	// optional pb2.PartialRequired opt_ext_partial = 25;
-	E_OptExtPartial = &file_pb2_test_proto_extDescs[4]
+	E_OptExtPartial = &file_pb2_test_proto_extTypes[4]
 	// repeated fixed32 rpt_ext_fixed32 = 31;
-	E_RptExtFixed32 = &file_pb2_test_proto_extDescs[5]
+	E_RptExtFixed32 = &file_pb2_test_proto_extTypes[5]
 	// repeated pb2.Enum rpt_ext_enum = 32;
-	E_RptExtEnum = &file_pb2_test_proto_extDescs[6]
+	E_RptExtEnum = &file_pb2_test_proto_extTypes[6]
 	// repeated pb2.Nested rpt_ext_nested = 33;
-	E_RptExtNested = &file_pb2_test_proto_extDescs[7]
+	E_RptExtNested = &file_pb2_test_proto_extTypes[7]
 	// optional bool opt_ext_bool = 51;
-	E_ExtensionsContainer_OptExtBool = &file_pb2_test_proto_extDescs[9]
+	E_ExtensionsContainer_OptExtBool = &file_pb2_test_proto_extTypes[9]
 	// optional string opt_ext_string = 52;
-	E_ExtensionsContainer_OptExtString = &file_pb2_test_proto_extDescs[10]
+	E_ExtensionsContainer_OptExtString = &file_pb2_test_proto_extTypes[10]
 	// optional pb2.Enum opt_ext_enum = 53;
-	E_ExtensionsContainer_OptExtEnum = &file_pb2_test_proto_extDescs[11]
+	E_ExtensionsContainer_OptExtEnum = &file_pb2_test_proto_extTypes[11]
 	// optional pb2.Nested opt_ext_nested = 54;
-	E_ExtensionsContainer_OptExtNested = &file_pb2_test_proto_extDescs[12]
+	E_ExtensionsContainer_OptExtNested = &file_pb2_test_proto_extTypes[12]
 	// optional pb2.PartialRequired opt_ext_partial = 55;
-	E_ExtensionsContainer_OptExtPartial = &file_pb2_test_proto_extDescs[13]
+	E_ExtensionsContainer_OptExtPartial = &file_pb2_test_proto_extTypes[13]
 	// repeated string rpt_ext_string = 61;
-	E_ExtensionsContainer_RptExtString = &file_pb2_test_proto_extDescs[14]
+	E_ExtensionsContainer_RptExtString = &file_pb2_test_proto_extTypes[14]
 	// repeated pb2.Enum rpt_ext_enum = 62;
-	E_ExtensionsContainer_RptExtEnum = &file_pb2_test_proto_extDescs[15]
+	E_ExtensionsContainer_RptExtEnum = &file_pb2_test_proto_extTypes[15]
 	// repeated pb2.Nested rpt_ext_nested = 63;
-	E_ExtensionsContainer_RptExtNested = &file_pb2_test_proto_extDescs[16]
+	E_ExtensionsContainer_RptExtNested = &file_pb2_test_proto_extTypes[16]
 )
 
 // Extension fields to MessageSet.
 var (
 	// optional pb2.FakeMessageSetExtension message_set_extension = 50;
-	E_MessageSetExtension = &file_pb2_test_proto_extDescs[8]
+	E_MessageSetExtension = &file_pb2_test_proto_extTypes[8]
 	// optional pb2.MessageSetExtension message_set_extension = 10;
-	E_MessageSetExtension_MessageSetExtension = &file_pb2_test_proto_extDescs[17]
+	E_MessageSetExtension_MessageSetExtension = &file_pb2_test_proto_extTypes[17]
 	// optional pb2.MessageSetExtension not_message_set_extension = 20;
-	E_MessageSetExtension_NotMessageSetExtension = &file_pb2_test_proto_extDescs[18]
+	E_MessageSetExtension_NotMessageSetExtension = &file_pb2_test_proto_extTypes[18]
 	// optional pb2.Nested ext_nested = 30;
-	E_MessageSetExtension_ExtNested = &file_pb2_test_proto_extDescs[19]
+	E_MessageSetExtension_ExtNested = &file_pb2_test_proto_extTypes[19]
 )
 
 // Extension fields to FakeMessageSet.
 var (
 	// optional pb2.FakeMessageSetExtension message_set_extension = 10;
-	E_FakeMessageSetExtension_MessageSetExtension = &file_pb2_test_proto_extDescs[20]
+	E_FakeMessageSetExtension_MessageSetExtension = &file_pb2_test_proto_extTypes[20]
 )
 
 var File_pb2_test_proto protoreflect.FileDescriptor
@@ -2406,7 +2406,7 @@
 		DependencyIndexes: file_pb2_test_proto_depIdxs,
 		EnumInfos:         file_pb2_test_proto_enumTypes,
 		MessageInfos:      file_pb2_test_proto_msgTypes,
-		LegacyExtensions:  file_pb2_test_proto_extDescs,
+		ExtensionInfos:    file_pb2_test_proto_extTypes,
 	}.Build()
 	File_pb2_test_proto = out.File
 	file_pb2_test_proto_rawDesc = nil
diff --git a/go.mod b/go.mod
index c29b074..9c4be5c 100644
--- a/go.mod
+++ b/go.mod
@@ -3,6 +3,6 @@
 go 1.9
 
 require (
-	github.com/golang/protobuf v1.2.1-0.20190806214225-7037721e6de0
+	github.com/golang/protobuf v1.2.1-0.20190820204156-2da1b93405dd
 	github.com/google/go-cmp v0.3.0
 )
diff --git a/go.sum b/go.sum
index de16d81..aa8565c 100644
--- a/go.sum
+++ b/go.sum
@@ -8,6 +8,8 @@
 github.com/golang/protobuf v1.2.1-0.20190620192300-1ee46dfd80dd/go.mod h1:+CMAsi9jpYf/wAltLUKlg++CWXqxCJyD8iLDbQONsJs=
 github.com/golang/protobuf v1.2.1-0.20190806214225-7037721e6de0 h1:a3hJDGxxWRbPxfOMiV6aG8pb0I+8RdgICRdXjXjiKzY=
 github.com/golang/protobuf v1.2.1-0.20190806214225-7037721e6de0/go.mod h1:tDQPRlaHYu9yt1wPgdx85inRiLvUCuJZXsYjC0mwc1c=
+github.com/golang/protobuf v1.2.1-0.20190820204156-2da1b93405dd h1:KtPU12Q37ryZW+7L97q/3GAhHtFXRjEkulcRj4dnSvA=
+github.com/golang/protobuf v1.2.1-0.20190820204156-2da1b93405dd/go.mod h1:x87I3ou7ehf/yR6iQ88MkyDogdxXN04TELJ7HVy7V7I=
 github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 google.golang.org/protobuf v0.0.0-20190514172829-e89e6244e0e8/go.mod h1:791zQGC15vDqjpmPRn1uGPu5oHy/Jzw/Q1n5JsgIIcY=
@@ -19,3 +21,4 @@
 google.golang.org/protobuf v0.0.0-20190617175724-bd7b7a9e0c26/go.mod h1:+FOB8T5/Yw4ywwdyeun9/KlDeuwFYBkNQ+kVuwj9C94=
 google.golang.org/protobuf v0.0.0-20190620020611-d888139e7b59/go.mod h1:of3pt14Y+dOxz2tBOHXEoapPpKFC15/0zWhPAddkfsU=
 google.golang.org/protobuf v0.0.0-20190717230113-f647c82cc3c7/go.mod h1:yGm7aNHn9Bp1NIvj6+CVUkcJshu+Usshfd3A+YxEuI8=
+google.golang.org/protobuf v0.0.0-20190820203659-c0f8c0a24ece/go.mod h1:tRqhEyKwbKqwt5CQZAuOtj09RfhLNklDOhndhYA9blU=
diff --git a/internal/filetype/build.go b/internal/filetype/build.go
index 0237dea..965ff27 100644
--- a/internal/filetype/build.go
+++ b/internal/filetype/build.go
@@ -8,14 +8,12 @@
 
 import (
 	"reflect"
-	"sync"
 
 	"google.golang.org/protobuf/internal/descopts"
 	fdesc "google.golang.org/protobuf/internal/filedesc"
 	pimpl "google.golang.org/protobuf/internal/impl"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
 	preg "google.golang.org/protobuf/reflect/protoregistry"
-	piface "google.golang.org/protobuf/runtime/protoiface"
 )
 
 // Builder constructs type descriptors from a raw file descriptor
@@ -101,13 +99,11 @@
 	// EnumInfos is a list of enum infos in "flattened ordering".
 	EnumInfos []EnumInfo
 
-	// LegacyExtensions is a list of legacy extensions in "flattened ordering".
-	// If provided, the pointer to the v1 ExtensionDesc will be stored into the
-	// associated v2 ExtensionType and accessible via a pseudo-internal API.
-	// Also, the v2 ExtensionType will be stored into each v1 ExtensionDesc.
+	// ExtensionInfos is a list of extension infos in "flattened ordering".
+	// Each element is initialized and registered with the protoregistry package.
 	//
 	// Requirement: len(LegacyExtensions) == len(Build.Extensions)
-	LegacyExtensions []piface.ExtensionDescV1
+	ExtensionInfos []pimpl.ExtensionInfo
 
 	// TypeRegistry is the registry to register each type descriptor.
 	// If nil, it uses protoregistry.GlobalTypes.
@@ -158,7 +154,7 @@
 
 	// Process messages.
 	messageGoTypes := tb.GoTypes[len(fbOut.Enums):][:len(fbOut.Messages)]
-	if tb.MessageInfos != nil && len(tb.MessageInfos) != len(fbOut.Messages) {
+	if len(tb.MessageInfos) != len(fbOut.Messages) {
 		panic("mismatching message lengths")
 	}
 	if len(fbOut.Messages) > 0 {
@@ -167,10 +163,8 @@
 				continue // skip map entry
 			}
 
-			if tb.MessageInfos != nil {
-				tb.MessageInfos[i].GoReflectType = reflect.TypeOf(messageGoTypes[i])
-				tb.MessageInfos[i].Desc = &fbOut.Messages[i]
-			}
+			tb.MessageInfos[i].GoReflectType = reflect.TypeOf(messageGoTypes[i])
+			tb.MessageInfos[i].Desc = &fbOut.Messages[i]
 
 			// Register message types.
 			if err := tb.TypeRegistry.Register(&tb.MessageInfos[i]); err != nil {
@@ -207,49 +201,33 @@
 	}
 
 	// Process extensions.
-	if tb.LegacyExtensions != nil && len(tb.LegacyExtensions) != len(fbOut.Extensions) {
+	if len(tb.ExtensionInfos) != len(fbOut.Extensions) {
 		panic("mismatching extension lengths")
 	}
-	if len(fbOut.Extensions) > 0 {
-		var depIdx int32
-		extensions := make([]Extension, len(fbOut.Extensions))
-		for i := range fbOut.Extensions {
-			// For enum and message kinds, determine the referent Go type so
-			// that we can construct their constructors.
-			const listExtDeps = 2
-			var goType reflect.Type
-			switch fbOut.Extensions[i].L1.Kind {
-			case pref.EnumKind:
-				j := depIdxs.Get(tb.DependencyIndexes, listExtDeps, depIdx)
-				goType = reflect.TypeOf(tb.GoTypes[j])
-				depIdx++
-			case pref.MessageKind, pref.GroupKind:
-				j := depIdxs.Get(tb.DependencyIndexes, listExtDeps, depIdx)
-				goType = reflect.TypeOf(tb.GoTypes[j])
-				depIdx++
-			default:
-				goType = goTypeForPBKind[fbOut.Extensions[i].L1.Kind]
-			}
+	var depIdx int32
+	for i := range fbOut.Extensions {
+		// For enum and message kinds, determine the referent Go type so
+		// that we can construct their constructors.
+		const listExtDeps = 2
+		var goType reflect.Type
+		switch fbOut.Extensions[i].L1.Kind {
+		case pref.EnumKind:
+			j := depIdxs.Get(tb.DependencyIndexes, listExtDeps, depIdx)
+			goType = reflect.TypeOf(tb.GoTypes[j])
+			depIdx++
+		case pref.MessageKind, pref.GroupKind:
+			j := depIdxs.Get(tb.DependencyIndexes, listExtDeps, depIdx)
+			goType = reflect.TypeOf(tb.GoTypes[j])
+			depIdx++
+		default:
+			goType = goTypeForPBKind[fbOut.Extensions[i].L1.Kind]
+		}
 
-			extensions[i] = Extension{
-				desc:   &fbOut.Extensions[i],
-				goType: goType,
-			}
-			extensions[i].tdesc = extensionTypeDescriptor{
-				ExtensionDescriptor: &fbOut.Extensions[i],
-				typ:                 &extensions[i],
-			}
+		pimpl.InitExtensionInfo(&tb.ExtensionInfos[i], &fbOut.Extensions[i], goType)
 
-			// Keep v1 and v2 extensions in sync.
-			if tb.LegacyExtensions != nil {
-				extensions[i].legacyDesc = &tb.LegacyExtensions[i]
-				tb.LegacyExtensions[i].Type = &extensions[i]
-			}
-
-			// Register extension types.
-			if err := tb.TypeRegistry.Register(&extensions[i]); err != nil {
-				panic(err)
-			}
+		// Register extension types.
+		if err := tb.TypeRegistry.Register(&tb.ExtensionInfos[i]); err != nil {
+			panic(err)
 		}
 	}
 
@@ -328,54 +306,3 @@
 		return reflect.New(t.Elem()).Interface().(pref.ProtoMessage).ProtoReflect()
 	}
 }
-
-type Extension struct {
-	desc       pref.ExtensionDescriptor
-	tdesc      extensionTypeDescriptor
-	legacyDesc *piface.ExtensionDescV1
-
-	once   sync.Once
-	goType reflect.Type
-	conv   pimpl.Converter
-}
-
-func (t *Extension) New() pref.Value  { return t.lazyInit().New() }
-func (t *Extension) Zero() pref.Value { return t.lazyInit().Zero() }
-func (t *Extension) ValueOf(v interface{}) pref.Value {
-	return t.lazyInit().PBValueOf(reflect.ValueOf(v))
-}
-func (t *Extension) InterfaceOf(v pref.Value) interface{} {
-	return t.lazyInit().GoValueOf(v).Interface()
-}
-func (t *Extension) GoType() reflect.Type {
-	t.lazyInit()
-	return t.goType
-}
-func (t *Extension) Descriptor() pref.ExtensionTypeDescriptor { return &t.tdesc }
-
-// ProtoLegacyExtensionDesc is a pseudo-internal API for allowing the v1 code
-// to be able to retrieve a v1 ExtensionDesc.
-//
-// WARNING: This method is exempt from the compatibility promise and may be
-// removed in the future without warning.
-func (x *Extension) ProtoLegacyExtensionDesc() *piface.ExtensionDescV1 {
-	return x.legacyDesc
-}
-
-func (t *Extension) lazyInit() pimpl.Converter {
-	t.once.Do(func() {
-		if t.desc.Cardinality() == pref.Repeated {
-			t.goType = reflect.PtrTo(reflect.SliceOf(t.goType))
-		}
-		t.conv = pimpl.NewConverter(t.goType, t.desc)
-	})
-	return t.conv
-}
-
-type extensionTypeDescriptor struct {
-	pref.ExtensionDescriptor
-	typ pref.ExtensionType
-}
-
-func (t *extensionTypeDescriptor) Type() pref.ExtensionType             { return t.typ }
-func (t *extensionTypeDescriptor) Descriptor() pref.ExtensionDescriptor { return t.ExtensionDescriptor }
diff --git a/internal/impl/api_export.go b/internal/impl/api_export.go
index a149612..41f7b7e 100644
--- a/internal/impl/api_export.go
+++ b/internal/impl/api_export.go
@@ -10,7 +10,6 @@
 
 	"google.golang.org/protobuf/encoding/prototext"
 	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
@@ -90,12 +89,14 @@
 	return string(b)
 }
 
-// ExtensionDescFromType returns the legacy protoiface.ExtensionDescV1 for t.
-func (Export) ExtensionDescFromType(t pref.ExtensionType) *piface.ExtensionDescV1 {
+// ExtensionDescFromType returns the legacy protoV1.ExtensionDesc for t.
+func (Export) ExtensionDescFromType(t pref.ExtensionType) *ExtensionInfo {
 	return legacyExtensionDescFromType(t)
 }
 
 // ExtensionTypeFromDesc returns the v2 protoreflect.ExtensionType for d.
-func (Export) ExtensionTypeFromDesc(d *piface.ExtensionDescV1) pref.ExtensionType {
-	return legacyExtensionTypeFromDesc(d)
+//
+// TODO: Remove after updating v1 to no longer call this.
+func (Export) ExtensionTypeFromDesc(d *ExtensionInfo) pref.ExtensionType {
+	return d
 }
diff --git a/internal/impl/extension.go b/internal/impl/extension.go
new file mode 100644
index 0000000..e7083e5
--- /dev/null
+++ b/internal/impl/extension.go
@@ -0,0 +1,172 @@
+// 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 impl
+
+import (
+	"reflect"
+	"sync"
+	"sync/atomic"
+
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+	piface "google.golang.org/protobuf/runtime/protoiface"
+)
+
+// ExtensionInfo implements ExtensionType.
+//
+// This type contains a number of exported fields for legacy compatibility.
+// The only non-deprecated use of this type is through the methods of the
+// ExtensionType interface.
+type ExtensionInfo struct {
+	// An ExtensionInfo may exist in several stages of initialization.
+	//
+	// extensionInfoUninitialized: Some or all of the legacy exported
+	// fields may be set, but none of the unexported fields have been
+	// initialized. This is the starting state for an ExtensionInfo
+	// in legacy generated code.
+	//
+	// extensionInfoDescInit: The desc and tdesc fields have been
+	// set, but the descriptor is not otherwise initialized. Legacy
+	// exported fields may or may not be set. This is the starting state
+	// for an ExtensionInfo in new generated code. Calling the Descriptor
+	// method will not trigger lazy initialization, although any other
+	// method will.
+	//
+	// extensionInfoFullInit: The ExtensionInfo is fully initialized.
+	// This state is only entered after lazy initialization is complete.
+	init uint32
+	mu   sync.Mutex
+
+	desc   pref.ExtensionDescriptor
+	tdesc  extensionTypeDescriptor
+	goType reflect.Type
+	conv   Converter
+
+	// TODO: Remove after updating v2 to not set this.
+	Type interface{}
+
+	// ExtendedType is a typed nil-pointer to the parent message type that
+	// is being extended. It is possible for this to be unpopulated in v2
+	// since the message may no longer implement the MessageV1 interface.
+	//
+	// Deprecated: Use the ExtendedType method instead.
+	ExtendedType piface.MessageV1
+
+	// ExtensionType is zero value of the extension type.
+	//
+	// For historical reasons, reflect.TypeOf(ExtensionType) and Type.GoType
+	// may not be identical:
+	//	* for scalars (except []byte), where ExtensionType uses *T,
+	//	while Type.GoType uses T.
+	//	* for repeated fields, where ExtensionType uses []T,
+	//	while Type.GoType uses *[]T.
+	//
+	// Deprecated: Use the GoType method instead.
+	ExtensionType interface{}
+
+	// Field is the field number of the extension.
+	//
+	// Deprecated: Use the Descriptor().Number method instead.
+	Field int32
+
+	// Name is the fully qualified name of extension.
+	//
+	// Deprecated: Use the Descriptor().FullName method instead.
+	Name string
+
+	// Tag is the protobuf struct tag used in the v1 API.
+	//
+	// Deprecated: Do not use.
+	Tag string
+
+	// Filename is the proto filename in which the extension is defined.
+	//
+	// Deprecated: Use Descriptor().ParentFile().Path() instead.
+	Filename string
+}
+
+// Stages of initialization: See the ExtensionInfo.init field.
+const (
+	extensionInfoUninitialized = 0
+	extensionInfoDescInit      = 1
+	extensionInfoFullInit      = 2
+)
+
+func InitExtensionInfo(xi *ExtensionInfo, xd pref.ExtensionDescriptor, goType reflect.Type) {
+	if xi.desc != nil {
+		return
+	}
+	xi.desc = xd
+	xi.goType = goType
+
+	xi.tdesc.ExtensionDescriptor = xi.desc
+	xi.tdesc.xi = xi
+	xi.init = extensionInfoDescInit
+}
+
+func (xi *ExtensionInfo) New() pref.Value {
+	return xi.lazyInit().New()
+}
+func (xi *ExtensionInfo) Zero() pref.Value {
+	return xi.lazyInit().Zero()
+}
+func (xi *ExtensionInfo) ValueOf(v interface{}) pref.Value {
+	return xi.lazyInit().PBValueOf(reflect.ValueOf(v))
+}
+func (xi *ExtensionInfo) InterfaceOf(v pref.Value) interface{} {
+	return xi.lazyInit().GoValueOf(v).Interface()
+}
+func (xi *ExtensionInfo) GoType() reflect.Type {
+	xi.lazyInit()
+	return xi.goType
+}
+func (xi *ExtensionInfo) Descriptor() pref.ExtensionTypeDescriptor {
+	if atomic.LoadUint32(&xi.init) == extensionInfoUninitialized {
+		xi.lazyInitSlow()
+	}
+	return &xi.tdesc
+}
+
+func (xi *ExtensionInfo) lazyInit() Converter {
+	if atomic.LoadUint32(&xi.init) != extensionInfoFullInit {
+		xi.lazyInitSlow()
+	}
+	return xi.conv
+}
+
+func (xi *ExtensionInfo) lazyInitSlow() {
+	xi.mu.Lock()
+	defer xi.mu.Unlock()
+
+	if xi.init == extensionInfoFullInit {
+		return
+	}
+	atomic.StoreUint32(&xi.init, extensionInfoFullInit)
+
+	if xi.desc == nil {
+		xi.initFromLegacy()
+	} else if xi.desc.Cardinality() == pref.Repeated {
+		// Cardinality is initialized lazily, so we defer consulting it until here.
+		xi.goType = reflect.PtrTo(reflect.SliceOf(xi.goType))
+	}
+	xi.conv = NewConverter(xi.goType, xi.desc)
+	xi.tdesc.ExtensionDescriptor = xi.desc
+	xi.tdesc.xi = xi
+
+	if xi.ExtensionType == nil {
+		xi.initToLegacy()
+	}
+}
+
+type extensionTypeDescriptor struct {
+	pref.ExtensionDescriptor
+	xi *ExtensionInfo
+}
+
+func (xtd *extensionTypeDescriptor) Type() pref.ExtensionType {
+	return xtd.xi
+}
+func (xtd *extensionTypeDescriptor) Descriptor() pref.ExtensionDescriptor {
+	return xtd.ExtensionDescriptor
+}
diff --git a/internal/impl/legacy_extension.go b/internal/impl/legacy_extension.go
index 2da4d71..4622484 100644
--- a/internal/impl/legacy_extension.go
+++ b/internal/impl/legacy_extension.go
@@ -15,52 +15,38 @@
 	piface "google.golang.org/protobuf/runtime/protoiface"
 )
 
-// legacyExtensionDescKey is a comparable version of protoiface.ExtensionDescV1
-// suitable for use as a key in a map.
-type legacyExtensionDescKey struct {
-	typeV2        pref.ExtensionType
-	extendedType  reflect.Type
-	extensionType reflect.Type
-	field         int32
-	name          string
-	tag           string
-	filename      string
-}
+var legacyExtensionInfoCache sync.Map // map[protoreflect.ExtensionType]*ExtensionInfo
 
-func legacyExtensionDescKeyOf(d *piface.ExtensionDescV1) legacyExtensionDescKey {
-	return legacyExtensionDescKey{
-		d.Type,
-		reflect.TypeOf(d.ExtendedType),
-		reflect.TypeOf(d.ExtensionType),
-		d.Field, d.Name, d.Tag, d.Filename,
-	}
-}
-
-var (
-	legacyExtensionTypeCache sync.Map // map[legacyExtensionDescKey]protoreflect.ExtensionType
-	legacyExtensionDescCache sync.Map // map[protoreflect.ExtensionType]*protoiface.ExtensionDescV1
-)
-
-// legacyExtensionDescFromType converts a v2 protoreflect.ExtensionType to a
-// protoiface.ExtensionDescV1. The returned ExtensionDesc must not be mutated.
-func legacyExtensionDescFromType(xt pref.ExtensionType) *piface.ExtensionDescV1 {
-	// Fast-path: check whether an extension desc is already nested within.
-	if xt, ok := xt.(interface {
-		ProtoLegacyExtensionDesc() *piface.ExtensionDescV1
-	}); ok {
-		if d := xt.ProtoLegacyExtensionDesc(); d != nil {
-			return d
-		}
+// legacyExtensionDescFromType converts a protoreflect.ExtensionType to an
+// ExtensionInfo. The returned ExtensionInfo must not be mutated.
+func legacyExtensionDescFromType(xt pref.ExtensionType) *ExtensionInfo {
+	// Fast-path: check whether this is an ExtensionInfo.
+	if xt, ok := xt.(*ExtensionInfo); ok {
+		return xt
 	}
 
 	// Fast-path: check the cache for whether this ExtensionType has already
-	// been converted to a legacy descriptor.
-	if d, ok := legacyExtensionDescCache.Load(xt); ok {
-		return d.(*piface.ExtensionDescV1)
+	// been converted to an ExtensionInfo.
+	if d, ok := legacyExtensionInfoCache.Load(xt); ok {
+		return d.(*ExtensionInfo)
 	}
 
-	// Determine the parent type if possible.
-	xd := xt.Descriptor()
+	tt := xt.GoType()
+	if xt.Descriptor().Cardinality() == pref.Repeated {
+		tt = tt.Elem().Elem()
+	}
+	xi := &ExtensionInfo{}
+	InitExtensionInfo(xi, xt.Descriptor().Descriptor(), tt)
+	xi.lazyInit() // populate legacy fields
+
+	if xi, ok := legacyExtensionInfoCache.LoadOrStore(xt, xi); ok {
+		return xi.(*ExtensionInfo)
+	}
+	return xi
+}
+
+func (xi *ExtensionInfo) initToLegacy() {
+	xd := xi.desc
 	var parent piface.MessageV1
 	messageName := xd.ContainingMessage().FullName()
 	if mt, _ := preg.GlobalTypes.FindMessageByName(messageName); mt != nil {
@@ -80,7 +66,7 @@
 
 	// Determine the v1 extension type, which is unfortunately not the same as
 	// the v2 ExtensionType.GoType.
-	extType := xt.GoType()
+	extType := xi.goType
 	switch extType.Kind() {
 	case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String:
 		extType = reflect.PtrTo(extType) // T -> *T for singular scalar fields
@@ -123,43 +109,21 @@
 		filename = fd.Path()
 	}
 
-	// Construct and return a ExtensionDescV1.
-	d := &piface.ExtensionDescV1{
-		Type:          xt,
-		ExtendedType:  parent,
-		ExtensionType: reflect.Zero(extType).Interface(),
-		Field:         int32(xd.Number()),
-		Name:          string(xd.FullName()),
-		Tag:           ptag.Marshal(xd, enumName),
-		Filename:      filename,
-	}
-	if d, ok := legacyExtensionDescCache.LoadOrStore(xt, d); ok {
-		return d.(*piface.ExtensionDescV1)
-	}
-	return d
+	xi.ExtendedType = parent
+	xi.ExtensionType = reflect.Zero(extType).Interface()
+	xi.Field = int32(xd.Number())
+	xi.Name = string(xd.FullName())
+	xi.Tag = ptag.Marshal(xd, enumName)
+	xi.Filename = filename
 }
 
-// legacyExtensionTypeFromDesc converts a protoiface.ExtensionDescV1 to a
-// v2 protoreflect.ExtensionType. The returned descriptor type takes ownership
-// of the input extension desc. The input must not be mutated so long as the
-// returned type is still in use.
-func legacyExtensionTypeFromDesc(d *piface.ExtensionDescV1) pref.ExtensionType {
-	// Fast-path: check whether an extension type is already nested within.
-	if d.Type != nil {
-		return d.Type
-	}
-
-	// Fast-path: check the cache for whether this ExtensionType has already
-	// been converted from a legacy descriptor.
-	dk := legacyExtensionDescKeyOf(d)
-	if t, ok := legacyExtensionTypeCache.Load(dk); ok {
-		return t.(pref.ExtensionType)
-	}
-
+// initFromLegacy initializes an ExtensionInfo from
+// the contents of the deprecated exported fields of the type.
+func (xi *ExtensionInfo) initFromLegacy() {
 	// Resolve enum or message dependencies.
 	var ed pref.EnumDescriptor
 	var md pref.MessageDescriptor
-	t := reflect.TypeOf(d.ExtensionType)
+	t := reflect.TypeOf(xi.ExtensionType)
 	isOptional := t.Kind() == reflect.Ptr && t.Elem().Kind() != reflect.Struct
 	isRepeated := t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8
 	if isOptional || isRepeated {
@@ -181,70 +145,27 @@
 	if ed != nil {
 		evs = ed.Values()
 	}
-	fd := ptag.Unmarshal(d.Tag, t, evs).(*filedesc.Field)
+	fd := ptag.Unmarshal(xi.Tag, t, evs).(*filedesc.Field)
 
 	// Construct a v2 ExtensionType.
 	xd := &filedesc.Extension{L2: new(filedesc.ExtensionL2)}
 	xd.L0.ParentFile = filedesc.SurrogateProto2
-	xd.L0.FullName = pref.FullName(d.Name)
-	xd.L1.Number = pref.FieldNumber(d.Field)
+	xd.L0.FullName = pref.FullName(xi.Name)
+	xd.L1.Number = pref.FieldNumber(xi.Field)
 	xd.L2.Cardinality = fd.L1.Cardinality
 	xd.L1.Kind = fd.L1.Kind
 	xd.L2.IsPacked = fd.L1.IsPacked
 	xd.L2.Default = fd.L1.Default
-	xd.L1.Extendee = Export{}.MessageDescriptorOf(d.ExtendedType)
+	xd.L1.Extendee = Export{}.MessageDescriptorOf(xi.ExtendedType)
 	xd.L2.Enum = ed
 	xd.L2.Message = md
-	tt := reflect.TypeOf(d.ExtensionType)
+	tt := reflect.TypeOf(xi.ExtensionType)
 	if isOptional {
 		tt = tt.Elem()
 	} else if isRepeated {
 		tt = reflect.PtrTo(tt)
 	}
-	xt := LegacyExtensionTypeOf(xd, tt)
 
-	// Cache the conversion for both directions.
-	legacyExtensionDescCache.LoadOrStore(xt, d)
-	if xt, ok := legacyExtensionTypeCache.LoadOrStore(dk, xt); ok {
-		return xt.(pref.ExtensionType)
-	}
-	return xt
+	xi.desc = xd
+	xi.goType = tt
 }
-
-// LegacyExtensionTypeOf returns a protoreflect.ExtensionType where the
-// element type of the field is t.
-//
-// This is exported for testing purposes.
-func LegacyExtensionTypeOf(xd pref.ExtensionDescriptor, t reflect.Type) pref.ExtensionType {
-	xt := &legacyExtensionType{
-		typ:  t,
-		conv: NewConverter(t, xd),
-	}
-	xt.desc = &extDesc{xd, xt}
-	return xt
-}
-
-type legacyExtensionType struct {
-	desc pref.ExtensionTypeDescriptor
-	typ  reflect.Type
-	conv Converter
-}
-
-func (x *legacyExtensionType) GoType() reflect.Type { return x.typ }
-func (x *legacyExtensionType) New() pref.Value      { return x.conv.New() }
-func (x *legacyExtensionType) Zero() pref.Value     { return x.conv.Zero() }
-func (x *legacyExtensionType) ValueOf(v interface{}) pref.Value {
-	return x.conv.PBValueOf(reflect.ValueOf(v))
-}
-func (x *legacyExtensionType) InterfaceOf(v pref.Value) interface{} {
-	return x.conv.GoValueOf(v).Interface()
-}
-func (x *legacyExtensionType) Descriptor() pref.ExtensionTypeDescriptor { return x.desc }
-
-type extDesc struct {
-	pref.ExtensionDescriptor
-	xt *legacyExtensionType
-}
-
-func (t *extDesc) Type() pref.ExtensionType             { return t.xt }
-func (t *extDesc) Descriptor() pref.ExtensionDescriptor { return t.ExtensionDescriptor }
diff --git a/internal/impl/legacy_test.go b/internal/impl/legacy_test.go
index 63b084d..e306e6b 100644
--- a/internal/impl/legacy_test.go
+++ b/internal/impl/legacy_test.go
@@ -59,7 +59,9 @@
 func mustMakeExtensionType(fileDesc, extDesc string, t reflect.Type, r pdesc.Resolver) pref.ExtensionType {
 	s := fmt.Sprintf(`name:"test.proto" syntax:"proto2" %s extension:[{%s}]`, fileDesc, extDesc)
 	xd := mustMakeFileDesc(s, r).Extensions().Get(0)
-	return pimpl.LegacyExtensionTypeOf(xd, t)
+	xi := &pimpl.ExtensionInfo{}
+	pimpl.InitExtensionInfo(xi, xd, t)
+	return xi
 }
 
 func mustMakeFileDesc(s string, r pdesc.Resolver) pref.FileDescriptor {
@@ -141,56 +143,56 @@
 		mustMakeExtensionType(
 			`package:"fizz.buzz" dependency:"legacy.proto"`,
 			`name:"repeated_bool" number:10010 label:LABEL_REPEATED type:TYPE_BOOL extendee:".LegacyTestMessage"`,
-			reflect.TypeOf((*[]bool)(nil)), depReg,
+			reflect.TypeOf(false), depReg,
 		),
 		mustMakeExtensionType(
 			`package:"fizz.buzz" dependency:"legacy.proto"`,
 			`name:"repeated_int32" number:10011 label:LABEL_REPEATED type:TYPE_INT32 extendee:".LegacyTestMessage"`,
-			reflect.TypeOf((*[]int32)(nil)), depReg,
+			reflect.TypeOf(int32(0)), depReg,
 		),
 		mustMakeExtensionType(
 			`package:"fizz.buzz" dependency:"legacy.proto"`,
 			`name:"repeated_uint32" number:10012 label:LABEL_REPEATED type:TYPE_UINT32 extendee:".LegacyTestMessage"`,
-			reflect.TypeOf((*[]uint32)(nil)), depReg,
+			reflect.TypeOf(uint32(0)), depReg,
 		),
 		mustMakeExtensionType(
 			`package:"fizz.buzz" dependency:"legacy.proto"`,
 			`name:"repeated_float" number:10013 label:LABEL_REPEATED type:TYPE_FLOAT extendee:".LegacyTestMessage"`,
-			reflect.TypeOf((*[]float32)(nil)), depReg,
+			reflect.TypeOf(float32(0)), depReg,
 		),
 		mustMakeExtensionType(
 			`package:"fizz.buzz" dependency:"legacy.proto"`,
 			`name:"repeated_string" number:10014 label:LABEL_REPEATED type:TYPE_STRING extendee:".LegacyTestMessage"`,
-			reflect.TypeOf((*[]string)(nil)), depReg,
+			reflect.TypeOf(""), depReg,
 		),
 		mustMakeExtensionType(
 			`package:"fizz.buzz" dependency:"legacy.proto"`,
 			`name:"repeated_bytes" number:10015 label:LABEL_REPEATED type:TYPE_BYTES extendee:".LegacyTestMessage"`,
-			reflect.TypeOf((*[][]byte)(nil)), depReg,
+			reflect.TypeOf(([]byte)(nil)), depReg,
 		),
 		mustMakeExtensionType(
 			`package:"fizz.buzz" dependency:["legacy.proto", "proto2.v1.0.0-20180125-92554152/test.proto"]`,
 			`name:"repeated_enum_v1" number:10016 label:LABEL_REPEATED type:TYPE_ENUM type_name:".google.golang.org.proto2_20180125.Message.ChildEnum" extendee:".LegacyTestMessage"`,
-			reflect.TypeOf((*[]proto2_20180125.Message_ChildEnum)(nil)), depReg,
+			reflect.TypeOf(proto2_20180125.Message_ChildEnum(0)), depReg,
 		),
 		mustMakeExtensionType(
 			`package:"fizz.buzz" dependency:["legacy.proto", "proto2.v1.0.0-20180125-92554152/test.proto"]`,
 			`name:"repeated_message_v1" number:10017 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".google.golang.org.proto2_20180125.Message.ChildMessage" extendee:".LegacyTestMessage"`,
-			reflect.TypeOf((*[]*proto2_20180125.Message_ChildMessage)(nil)), depReg,
+			reflect.TypeOf((*proto2_20180125.Message_ChildMessage)(nil)), depReg,
 		),
 		mustMakeExtensionType(
 			`package:"fizz.buzz" dependency:["legacy.proto", "enum2.proto"]`,
 			`name:"repeated_enum_v2" number:10018 label:LABEL_REPEATED type:TYPE_ENUM type_name:".EnumProto2" extendee:".LegacyTestMessage"`,
-			reflect.TypeOf((*[]EnumProto2)(nil)), depReg,
+			reflect.TypeOf(EnumProto2(0)), depReg,
 		),
 		mustMakeExtensionType(
 			`package:"fizz.buzz" dependency:["legacy.proto", "enum-messages.proto"]`,
 			`name:"repeated_message_v2" number:10019 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".EnumMessages" extendee:".LegacyTestMessage"`,
-			reflect.TypeOf((*[](*EnumMessages))(nil)), depReg,
+			reflect.TypeOf((*EnumMessages)(nil)), depReg,
 		),
 	}
 
-	extensionDescs = []*piface.ExtensionDescV1{{
+	extensionDescs = []*pimpl.ExtensionInfo{{
 		ExtendedType:  (*LegacyTestMessage)(nil),
 		ExtensionType: (*bool)(nil),
 		Field:         10000,
@@ -463,7 +465,7 @@
 
 			wantType := extensionTypes[i]
 			wantDesc := extensionDescs[i]
-			gotType := pimpl.Export{}.ExtensionTypeFromDesc(wantDesc)
+			gotType := (pref.ExtensionType)(wantDesc)
 			gotDesc := pimpl.Export{}.ExtensionDescFromType(wantType)
 
 			// TODO: We need a test package to compare descriptors.
@@ -528,7 +530,8 @@
 			}
 
 			opts = cmp.Options{
-				cmpopts.IgnoreFields(piface.ExtensionDescV1{}, "Type"),
+				cmpopts.IgnoreFields(pimpl.ExtensionInfo{}, "ExtensionType"),
+				cmpopts.IgnoreUnexported(pimpl.ExtensionInfo{}),
 			}
 			if diff := cmp.Diff(wantDesc, gotDesc, opts); diff != "" {
 				t.Errorf("ExtensionDesc mismatch (-want, +got):\n%v", diff)
diff --git a/internal/testprotos/benchmarks/datasets/google_message3/benchmark_message3.pb.go b/internal/testprotos/benchmarks/datasets/google_message3/benchmark_message3.pb.go
index 9c2c056..36bd4aa 100644
--- a/internal/testprotos/benchmarks/datasets/google_message3/benchmark_message3.pb.go
+++ b/internal/testprotos/benchmarks/datasets/google_message3/benchmark_message3.pb.go
@@ -3479,7 +3479,7 @@
 	return 0
 }
 
-var file_datasets_google_message3_benchmark_message3_proto_extDescs = []protoiface.ExtensionDescV1{
+var file_datasets_google_message3_benchmark_message3_proto_extTypes = []protoimpl.ExtensionInfo{
 	{
 		ExtendedType:  (*Message16945)(nil),
 		ExtensionType: (*string)(nil),
@@ -4101,171 +4101,171 @@
 // Extension fields to Message16945.
 var (
 	// optional string field17026 = 472;
-	E_Field17026 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[0]
+	E_Field17026 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[0]
 	// repeated string field17027 = 818;
-	E_Field17027 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[1]
+	E_Field17027 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[1]
 	// optional benchmarks.google_message3.Message0 field17031 = 215;
-	E_Field17031 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[2]
+	E_Field17031 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[2]
 	// repeated benchmarks.google_message3.Message0 field17032 = 292;
-	E_Field17032 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[3]
+	E_Field17032 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[3]
 	// repeated benchmarks.google_message3.Message0 field17038 = 234;
-	E_Field17038 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[4]
+	E_Field17038 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[4]
 	// repeated benchmarks.google_message3.Message0 field17039 = 235;
-	E_Field17039 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[5]
+	E_Field17039 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[5]
 	// optional benchmarks.google_message3.Message0 field17042 = 246;
-	E_Field17042 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[6]
+	E_Field17042 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[6]
 	// optional string field17043 = 224;
-	E_Field17043 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[7]
+	E_Field17043 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[7]
 	// optional string field17044 = 225;
-	E_Field17044 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[8]
+	E_Field17044 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[8]
 	// repeated string field17048 = 63;
-	E_Field17048 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[9]
+	E_Field17048 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[9]
 	// repeated string field17049 = 64;
-	E_Field17049 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[10]
+	E_Field17049 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[10]
 	// repeated benchmarks.google_message3.Message0 field17052 = 233;
-	E_Field17052 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[11]
+	E_Field17052 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[11]
 	// repeated benchmarks.google_message3.Message0 field17053 = 66;
-	E_Field17053 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[12]
+	E_Field17053 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[12]
 	// repeated string field17056 = 275;
-	E_Field17056 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[13]
+	E_Field17056 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[13]
 	// optional string field17057 = 226;
-	E_Field17057 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[14]
+	E_Field17057 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[14]
 	// repeated benchmarks.google_message3.Message0 field17060 = 27;
-	E_Field17060 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[15]
+	E_Field17060 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[15]
 	// repeated string field17073 = 75;
-	E_Field17073 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[16]
+	E_Field17073 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[16]
 	// repeated benchmarks.google_message3.Message0 field17076 = 77;
-	E_Field17076 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[17]
+	E_Field17076 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[17]
 	// repeated string field17078 = 296;
-	E_Field17078 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[18]
+	E_Field17078 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[18]
 	// repeated benchmarks.google_message3.Message0 field17082 = 160;
-	E_Field17082 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[19]
+	E_Field17082 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[19]
 	// repeated benchmarks.google_message3.Message0 field17091 = 585;
-	E_Field17091 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[20]
+	E_Field17091 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[20]
 	// repeated benchmarks.google_message3.Message0 field17098 = 987;
-	E_Field17098 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[21]
+	E_Field17098 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[21]
 	// repeated benchmarks.google_message3.Message0 field17101 = 157;
-	E_Field17101 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[22]
+	E_Field17101 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[22]
 	// repeated string field17102 = 158;
-	E_Field17102 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[23]
+	E_Field17102 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[23]
 	// repeated string field17107 = 166;
-	E_Field17107 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[24]
+	E_Field17107 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[24]
 	// repeated string field17133 = 567;
-	E_Field17133 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[25]
+	E_Field17133 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[25]
 	// repeated string field17134 = 572;
-	E_Field17134 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[26]
+	E_Field17134 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[26]
 	// repeated string field17160 = 49;
-	E_Field17160 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[27]
+	E_Field17160 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[27]
 	// repeated string field17168 = 32;
-	E_Field17168 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[28]
+	E_Field17168 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[28]
 	// repeated string field17170 = 34;
-	E_Field17170 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[29]
+	E_Field17170 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[29]
 	// repeated benchmarks.google_message3.Message0 field17172 = 509;
-	E_Field17172 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[30]
+	E_Field17172 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[30]
 	// repeated string field17174 = 39;
-	E_Field17174 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[31]
+	E_Field17174 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[31]
 	// repeated benchmarks.google_message3.Message0 field17175 = 40;
-	E_Field17175 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[32]
+	E_Field17175 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[32]
 	// repeated benchmarks.google_message3.Message0 field17178 = 511;
-	E_Field17178 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[33]
+	E_Field17178 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[33]
 	// repeated benchmarks.google_message3.Message0 field17185 = 50;
-	E_Field17185 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[34]
+	E_Field17185 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[34]
 	// repeated int32 field17207 = 1081;
-	E_Field17207 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[35]
+	E_Field17207 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[35]
 	// repeated benchmarks.google_message3.Message0 field17238 = 184;
-	E_Field17238 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[36]
+	E_Field17238 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[36]
 	// repeated benchmarks.google_message3.Message0 field17289 = 177;
-	E_Field17289 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[37]
+	E_Field17289 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[37]
 	// repeated benchmarks.google_message3.Message0 field17290 = 178;
-	E_Field17290 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[38]
+	E_Field17290 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[38]
 	// repeated benchmarks.google_message3.Message0 field17296 = 474;
-	E_Field17296 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[39]
+	E_Field17296 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[39]
 	// repeated string field17298 = 44;
-	E_Field17298 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[40]
+	E_Field17298 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[40]
 	// repeated benchmarks.google_message3.Message0 field17301 = 47;
-	E_Field17301 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[41]
+	E_Field17301 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[41]
 	// optional benchmarks.google_message3.Message0 field17412 = 21;
-	E_Field17412 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[42]
+	E_Field17412 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[42]
 	// repeated benchmarks.google_message3.Message0 field17438 = 132;
-	E_Field17438 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[43]
+	E_Field17438 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[43]
 	// repeated benchmarks.google_message3.Message0 field17458 = 512;
-	E_Field17458 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[44]
+	E_Field17458 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[44]
 	// repeated string field17460 = 560;
-	E_Field17460 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[45]
+	E_Field17460 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[45]
 	// repeated string field17466 = 552;
-	E_Field17466 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[46]
+	E_Field17466 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[46]
 	// repeated benchmarks.google_message3.Message0 field17617 = 1080;
-	E_Field17617 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[47]
+	E_Field17617 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[47]
 	// repeated int32 field17618 = 1084;
-	E_Field17618 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[48]
+	E_Field17618 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[48]
 )
 
 // Extension fields to Message0.
 var (
 	// optional benchmarks.google_message3.Message1327 field1373 = 23104162;
-	E_Message1327_Field1373 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[49]
+	E_Message1327_Field1373 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[49]
 	// optional benchmarks.google_message3.Message3672 field3737 = 3144435;
-	E_Message3672_Field3737 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[50]
+	E_Message3672_Field3737 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[50]
 	// optional benchmarks.google_message3.Message3804 field3825 = 59241828;
-	E_Message3804_Field3825 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[51]
+	E_Message3804_Field3825 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[51]
 	// optional benchmarks.google_message3.Message6849 field6911 = 107558455;
-	E_Message6849_Field6911 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[52]
+	E_Message6849_Field6911 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[52]
 	// optional benchmarks.google_message3.Message6866 field6974 = 22259060;
-	E_Message6866_Field6974 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[53]
+	E_Message6866_Field6974 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[53]
 	// optional benchmarks.google_message3.Message6870 field6992 = 90034652;
-	E_Message6870_Field6992 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[54]
+	E_Message6870_Field6992 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[54]
 	// optional benchmarks.google_message3.Message7651 field7730 = 55876009;
-	E_Message7651_Field7730 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[55]
+	E_Message7651_Field7730 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[55]
 	// optional benchmarks.google_message3.Message7864 field7872 = 44542730;
-	E_Message7864_Field7872 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[56]
+	E_Message7864_Field7872 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[56]
 	// optional benchmarks.google_message3.Message7929 field7962 = 53392238;
-	E_Message7929_Field7962 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[57]
+	E_Message7929_Field7962 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[57]
 	// optional benchmarks.google_message3.Message8508 field8534 = 3811804;
-	E_Message8508_Field8534 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[58]
+	E_Message8508_Field8534 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[58]
 	// optional benchmarks.google_message3.Message9122 field9134 = 120398939;
-	E_Message9122_Field9134 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[59]
+	E_Message9122_Field9134 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[59]
 	// optional benchmarks.google_message3.Message10177 field10271 = 26801105;
-	E_Message10177_Field10271 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[60]
+	E_Message10177_Field10271 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[60]
 	// optional benchmarks.google_message3.Message11990 field12031 = 21265426;
-	E_Message11990_Field12031 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[64]
+	E_Message11990_Field12031 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[64]
 	// optional benchmarks.google_message3.Message12691 field12716 = 28426536;
-	E_Message12691_Field12716 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[65]
+	E_Message12691_Field12716 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[65]
 	// optional benchmarks.google_message3.Message12870 field12899 = 5447656;
-	E_Message12870_Field12899 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[66]
+	E_Message12870_Field12899 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[66]
 	// optional benchmarks.google_message3.Message16507 field16542 = 5569941;
-	E_Message16507_Field16542 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[68]
+	E_Message16507_Field16542 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[68]
 	// optional benchmarks.google_message3.Message16564 field16569 = 25830030;
-	E_Message16564_Field16569 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[69]
+	E_Message16564_Field16569 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[69]
 	// optional benchmarks.google_message3.Message16661 field16673 = 31274398;
-	E_Message16661_Field16673 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[70]
+	E_Message16661_Field16673 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[70]
 	// optional benchmarks.google_message3.Message16746 field16810 = 28406765;
-	E_Message16746_Field16810 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[71]
+	E_Message16746_Field16810 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[71]
 	// optional benchmarks.google_message3.Message17786 field18176 = 11823055;
-	E_Message17786_Field18176 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[72]
+	E_Message17786_Field18176 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[72]
 	// optional benchmarks.google_message3.Message24404 field24685 = 9129287;
-	E_Message24404_Field24685 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[74]
+	E_Message24404_Field24685 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[74]
 	// optional benchmarks.google_message3.Message27300 field27304 = 24956467;
-	E_Message27300_Field27304 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[75]
+	E_Message27300_Field27304 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[75]
 	// optional benchmarks.google_message3.Message27453 field27482 = 8086204;
-	E_Message27453_Field27482 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[76]
+	E_Message27453_Field27482 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[76]
 )
 
 // Extension fields to Message10155.
 var (
 	// optional benchmarks.google_message3.Message10278 field10289 = 29374161;
-	E_Message10278_Field10289 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[61]
+	E_Message10278_Field10289 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[61]
 	// optional benchmarks.google_message3.Message10323 field10361 = 27922524;
-	E_Message10323_Field10361 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[62]
+	E_Message10323_Field10361 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[62]
 	// optional benchmarks.google_message3.Message10324 field10364 = 27832297;
-	E_Message10324_Field10364 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[63]
+	E_Message10324_Field10364 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[63]
 	// optional benchmarks.google_message3.Message22857 field22875 = 67799715;
-	E_Message22857_Field22875 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[73]
+	E_Message22857_Field22875 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[73]
 )
 
 // Extension fields to Message13145.
 var (
 	// optional benchmarks.google_message3.Message13154 field13166 = 47301086;
-	E_Message13154_Field13166 = &file_datasets_google_message3_benchmark_message3_proto_extDescs[67]
+	E_Message13154_Field13166 = &file_datasets_google_message3_benchmark_message3_proto_extTypes[67]
 )
 
 var File_datasets_google_message3_benchmark_message3_proto protoreflect.FileDescriptor
@@ -6548,7 +6548,7 @@
 		GoTypes:           file_datasets_google_message3_benchmark_message3_proto_goTypes,
 		DependencyIndexes: file_datasets_google_message3_benchmark_message3_proto_depIdxs,
 		MessageInfos:      file_datasets_google_message3_benchmark_message3_proto_msgTypes,
-		LegacyExtensions:  file_datasets_google_message3_benchmark_message3_proto_extDescs,
+		ExtensionInfos:    file_datasets_google_message3_benchmark_message3_proto_extTypes,
 	}.Build()
 	File_datasets_google_message3_benchmark_message3_proto = out.File
 	file_datasets_google_message3_benchmark_message3_proto_rawDesc = nil
diff --git a/internal/testprotos/benchmarks/datasets/google_message3/benchmark_message3_1.pb.go b/internal/testprotos/benchmarks/datasets/google_message3/benchmark_message3_1.pb.go
index 5501358..2edd5ba 100644
--- a/internal/testprotos/benchmarks/datasets/google_message3/benchmark_message3_1.pb.go
+++ b/internal/testprotos/benchmarks/datasets/google_message3/benchmark_message3_1.pb.go
@@ -6023,7 +6023,7 @@
 	return nil
 }
 
-var file_datasets_google_message3_benchmark_message3_1_proto_extDescs = []protoiface.ExtensionDescV1{
+var file_datasets_google_message3_benchmark_message3_1_proto_extTypes = []protoimpl.ExtensionInfo{
 	{
 		ExtendedType:  (*Message0)(nil),
 		ExtensionType: (*Message34390)(nil),
@@ -6077,17 +6077,17 @@
 // Extension fields to Message0.
 var (
 	// optional benchmarks.google_message3.Message34390 field34453 = 92144610;
-	E_Message34390_Field34453 = &file_datasets_google_message3_benchmark_message3_1_proto_extDescs[0]
+	E_Message34390_Field34453 = &file_datasets_google_message3_benchmark_message3_1_proto_extTypes[0]
 	// optional benchmarks.google_message3.Message34624 field34685 = 18178548;
-	E_Message34624_Field34685 = &file_datasets_google_message3_benchmark_message3_1_proto_extDescs[1]
+	E_Message34624_Field34685 = &file_datasets_google_message3_benchmark_message3_1_proto_extTypes[1]
 	// optional benchmarks.google_message3.Message34791 field34807 = 6330340;
-	E_Message34791_Field34807 = &file_datasets_google_message3_benchmark_message3_1_proto_extDescs[2]
+	E_Message34791_Field34807 = &file_datasets_google_message3_benchmark_message3_1_proto_extTypes[2]
 	// optional benchmarks.google_message3.Message35483 field35505 = 7913554;
-	E_Message35483_Field35505 = &file_datasets_google_message3_benchmark_message3_1_proto_extDescs[3]
+	E_Message35483_Field35505 = &file_datasets_google_message3_benchmark_message3_1_proto_extTypes[3]
 	// optional benchmarks.google_message3.Message35807 field35818 = 3803299;
-	E_Message35807_Field35818 = &file_datasets_google_message3_benchmark_message3_1_proto_extDescs[4]
+	E_Message35807_Field35818 = &file_datasets_google_message3_benchmark_message3_1_proto_extTypes[4]
 	// optional benchmarks.google_message3.Message16945 field17025 = 22068132;
-	E_Message16945_Field17025 = &file_datasets_google_message3_benchmark_message3_1_proto_extDescs[5]
+	E_Message16945_Field17025 = &file_datasets_google_message3_benchmark_message3_1_proto_extTypes[5]
 )
 
 var File_datasets_google_message3_benchmark_message3_1_proto protoreflect.FileDescriptor
@@ -8872,7 +8872,7 @@
 		GoTypes:           file_datasets_google_message3_benchmark_message3_1_proto_goTypes,
 		DependencyIndexes: file_datasets_google_message3_benchmark_message3_1_proto_depIdxs,
 		MessageInfos:      file_datasets_google_message3_benchmark_message3_1_proto_msgTypes,
-		LegacyExtensions:  file_datasets_google_message3_benchmark_message3_1_proto_extDescs,
+		ExtensionInfos:    file_datasets_google_message3_benchmark_message3_1_proto_extTypes,
 	}.Build()
 	File_datasets_google_message3_benchmark_message3_1_proto = out.File
 	file_datasets_google_message3_benchmark_message3_1_proto_rawDesc = nil
diff --git a/internal/testprotos/benchmarks/datasets/google_message3/benchmark_message3_2.pb.go b/internal/testprotos/benchmarks/datasets/google_message3/benchmark_message3_2.pb.go
index 2c9e1cf..893fd8c 100644
--- a/internal/testprotos/benchmarks/datasets/google_message3/benchmark_message3_2.pb.go
+++ b/internal/testprotos/benchmarks/datasets/google_message3/benchmark_message3_2.pb.go
@@ -4317,7 +4317,7 @@
 	return 0
 }
 
-var file_datasets_google_message3_benchmark_message3_2_proto_extDescs = []protoiface.ExtensionDescV1{
+var file_datasets_google_message3_benchmark_message3_2_proto_extTypes = []protoimpl.ExtensionInfo{
 	{
 		ExtendedType:  (*Message0)(nil),
 		ExtensionType: (*Message34621)(nil),
@@ -4331,7 +4331,7 @@
 // Extension fields to Message0.
 var (
 	// optional benchmarks.google_message3.Message34621 field34669 = 17562023;
-	E_Message34621_Field34669 = &file_datasets_google_message3_benchmark_message3_2_proto_extDescs[0]
+	E_Message34621_Field34669 = &file_datasets_google_message3_benchmark_message3_2_proto_extTypes[0]
 )
 
 var File_datasets_google_message3_benchmark_message3_2_proto protoreflect.FileDescriptor
@@ -6148,7 +6148,7 @@
 		GoTypes:           file_datasets_google_message3_benchmark_message3_2_proto_goTypes,
 		DependencyIndexes: file_datasets_google_message3_benchmark_message3_2_proto_depIdxs,
 		MessageInfos:      file_datasets_google_message3_benchmark_message3_2_proto_msgTypes,
-		LegacyExtensions:  file_datasets_google_message3_benchmark_message3_2_proto_extDescs,
+		ExtensionInfos:    file_datasets_google_message3_benchmark_message3_2_proto_extTypes,
 	}.Build()
 	File_datasets_google_message3_benchmark_message3_2_proto = out.File
 	file_datasets_google_message3_benchmark_message3_2_proto_rawDesc = nil
diff --git a/internal/testprotos/benchmarks/datasets/google_message3/benchmark_message3_4.pb.go b/internal/testprotos/benchmarks/datasets/google_message3/benchmark_message3_4.pb.go
index 11cc5cf..eb31d78 100644
--- a/internal/testprotos/benchmarks/datasets/google_message3/benchmark_message3_4.pb.go
+++ b/internal/testprotos/benchmarks/datasets/google_message3/benchmark_message3_4.pb.go
@@ -4430,7 +4430,7 @@
 	return file_datasets_google_message3_benchmark_message3_4_proto_rawDescGZIP(), []int{20, 1}
 }
 
-var file_datasets_google_message3_benchmark_message3_4_proto_extDescs = []protoiface.ExtensionDescV1{
+var file_datasets_google_message3_benchmark_message3_4_proto_extTypes = []protoimpl.ExtensionInfo{
 	{
 		ExtendedType:  (*Message0)(nil),
 		ExtensionType: (*Message33958)(nil),
@@ -4460,19 +4460,19 @@
 // Extension fields to Message0.
 var (
 	// optional benchmarks.google_message3.Message33958 field33981 = 10747482;
-	E_Message33958_Field33981 = &file_datasets_google_message3_benchmark_message3_4_proto_extDescs[0]
+	E_Message33958_Field33981 = &file_datasets_google_message3_benchmark_message3_4_proto_extTypes[0]
 )
 
 // Extension fields to Message8301.
 var (
 	// optional benchmarks.google_message3.Message8454 field8469 = 66;
-	E_Message8454_Field8469 = &file_datasets_google_message3_benchmark_message3_4_proto_extDescs[1]
+	E_Message8454_Field8469 = &file_datasets_google_message3_benchmark_message3_4_proto_extTypes[1]
 )
 
 // Extension fields to Message8302.
 var (
 	// optional benchmarks.google_message3.Message8455 field8474 = 66;
-	E_Message8455_Field8474 = &file_datasets_google_message3_benchmark_message3_4_proto_extDescs[2]
+	E_Message8455_Field8474 = &file_datasets_google_message3_benchmark_message3_4_proto_extTypes[2]
 )
 
 var File_datasets_google_message3_benchmark_message3_4_proto protoreflect.FileDescriptor
@@ -6410,7 +6410,7 @@
 		GoTypes:           file_datasets_google_message3_benchmark_message3_4_proto_goTypes,
 		DependencyIndexes: file_datasets_google_message3_benchmark_message3_4_proto_depIdxs,
 		MessageInfos:      file_datasets_google_message3_benchmark_message3_4_proto_msgTypes,
-		LegacyExtensions:  file_datasets_google_message3_benchmark_message3_4_proto_extDescs,
+		ExtensionInfos:    file_datasets_google_message3_benchmark_message3_4_proto_extTypes,
 	}.Build()
 	File_datasets_google_message3_benchmark_message3_4_proto = out.File
 	file_datasets_google_message3_benchmark_message3_4_proto_rawDesc = nil
diff --git a/internal/testprotos/conformance/test_messages_proto2.pb.go b/internal/testprotos/conformance/test_messages_proto2.pb.go
index 60b7614..ac17ced 100644
--- a/internal/testprotos/conformance/test_messages_proto2.pb.go
+++ b/internal/testprotos/conformance/test_messages_proto2.pb.go
@@ -1407,7 +1407,7 @@
 	return 0
 }
 
-var file_google_protobuf_test_messages_proto2_proto_extDescs = []protoiface.ExtensionDescV1{
+var file_google_protobuf_test_messages_proto2_proto_extTypes = []protoimpl.ExtensionInfo{
 	{
 		ExtendedType:  (*TestAllTypesProto2)(nil),
 		ExtensionType: (*int32)(nil),
@@ -1437,15 +1437,15 @@
 // Extension fields to TestAllTypesProto2.
 var (
 	// optional int32 extension_int32 = 120;
-	E_ExtensionInt32 = &file_google_protobuf_test_messages_proto2_proto_extDescs[0]
+	E_ExtensionInt32 = &file_google_protobuf_test_messages_proto2_proto_extTypes[0]
 )
 
 // Extension fields to TestAllTypesProto2_MessageSetCorrect.
 var (
 	// optional protobuf_test_messages.proto2.TestAllTypesProto2.MessageSetCorrectExtension1 message_set_extension = 1547769;
-	E_TestAllTypesProto2_MessageSetCorrectExtension1_MessageSetExtension = &file_google_protobuf_test_messages_proto2_proto_extDescs[1]
+	E_TestAllTypesProto2_MessageSetCorrectExtension1_MessageSetExtension = &file_google_protobuf_test_messages_proto2_proto_extTypes[1]
 	// optional protobuf_test_messages.proto2.TestAllTypesProto2.MessageSetCorrectExtension2 message_set_extension = 4135312;
-	E_TestAllTypesProto2_MessageSetCorrectExtension2_MessageSetExtension = &file_google_protobuf_test_messages_proto2_proto_extDescs[2]
+	E_TestAllTypesProto2_MessageSetCorrectExtension2_MessageSetExtension = &file_google_protobuf_test_messages_proto2_proto_extTypes[2]
 )
 
 var File_google_protobuf_test_messages_proto2_proto protoreflect.FileDescriptor
@@ -2262,7 +2262,7 @@
 		DependencyIndexes: file_google_protobuf_test_messages_proto2_proto_depIdxs,
 		EnumInfos:         file_google_protobuf_test_messages_proto2_proto_enumTypes,
 		MessageInfos:      file_google_protobuf_test_messages_proto2_proto_msgTypes,
-		LegacyExtensions:  file_google_protobuf_test_messages_proto2_proto_extDescs,
+		ExtensionInfos:    file_google_protobuf_test_messages_proto2_proto_extTypes,
 	}.Build()
 	File_google_protobuf_test_messages_proto2_proto = out.File
 	file_google_protobuf_test_messages_proto2_proto_rawDesc = nil
diff --git a/internal/testprotos/messageset/msetextpb/msetextpb.pb.go b/internal/testprotos/messageset/msetextpb/msetextpb.pb.go
index 24e07bd..1f3e452 100644
--- a/internal/testprotos/messageset/msetextpb/msetextpb.pb.go
+++ b/internal/testprotos/messageset/msetextpb/msetextpb.pb.go
@@ -10,7 +10,6 @@
 import (
 	messagesetpb "google.golang.org/protobuf/internal/testprotos/messageset/messagesetpb"
 	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
-	protoiface "google.golang.org/protobuf/runtime/protoiface"
 	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
 	reflect "reflect"
 	sync "sync"
@@ -108,7 +107,7 @@
 	return 0
 }
 
-var file_messageset_msetextpb_msetextpb_proto_extDescs = []protoiface.ExtensionDescV1{
+var file_messageset_msetextpb_msetextpb_proto_extTypes = []protoimpl.ExtensionInfo{
 	{
 		ExtendedType:  (*messagesetpb.MessageSet)(nil),
 		ExtensionType: (*Ext1)(nil),
@@ -130,9 +129,9 @@
 // Extension fields to messagesetpb.MessageSet.
 var (
 	// optional goproto.proto.messageset.Ext1 message_set_extension = 1000;
-	E_Ext1_MessageSetExtension = &file_messageset_msetextpb_msetextpb_proto_extDescs[0]
+	E_Ext1_MessageSetExtension = &file_messageset_msetextpb_msetextpb_proto_extTypes[0]
 	// optional goproto.proto.messageset.Ext2 message_set_extension = 1001;
-	E_Ext2_MessageSetExtension = &file_messageset_msetextpb_msetextpb_proto_extDescs[1]
+	E_Ext2_MessageSetExtension = &file_messageset_msetextpb_msetextpb_proto_extTypes[1]
 )
 
 var File_messageset_msetextpb_msetextpb_proto protoreflect.FileDescriptor
@@ -248,7 +247,7 @@
 		GoTypes:           file_messageset_msetextpb_msetextpb_proto_goTypes,
 		DependencyIndexes: file_messageset_msetextpb_msetextpb_proto_depIdxs,
 		MessageInfos:      file_messageset_msetextpb_msetextpb_proto_msgTypes,
-		LegacyExtensions:  file_messageset_msetextpb_msetextpb_proto_extDescs,
+		ExtensionInfos:    file_messageset_msetextpb_msetextpb_proto_extTypes,
 	}.Build()
 	File_messageset_msetextpb_msetextpb_proto = out.File
 	file_messageset_msetextpb_msetextpb_proto_rawDesc = nil
diff --git a/internal/testprotos/test/ext.pb.go b/internal/testprotos/test/ext.pb.go
index 6fc92a1..fe3f48d 100644
--- a/internal/testprotos/test/ext.pb.go
+++ b/internal/testprotos/test/ext.pb.go
@@ -9,13 +9,12 @@
 
 import (
 	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
-	protoiface "google.golang.org/protobuf/runtime/protoiface"
 	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
 	reflect "reflect"
 	sync "sync"
 )
 
-var file_test_ext_proto_extDescs = []protoiface.ExtensionDescV1{
+var file_test_ext_proto_extTypes = []protoimpl.ExtensionInfo{
 	{
 		ExtendedType:  (*TestAllExtensions)(nil),
 		ExtensionType: (*int32)(nil),
@@ -29,7 +28,7 @@
 // Extension fields to TestAllExtensions.
 var (
 	// optional int32 foreign_int32_extension = 2000;
-	E_ForeignInt32Extension = &file_test_ext_proto_extDescs[0]
+	E_ForeignInt32Extension = &file_test_ext_proto_extTypes[0]
 )
 
 var File_test_ext_proto protoreflect.FileDescriptor
@@ -92,7 +91,7 @@
 		},
 		GoTypes:           file_test_ext_proto_goTypes,
 		DependencyIndexes: file_test_ext_proto_depIdxs,
-		LegacyExtensions:  file_test_ext_proto_extDescs,
+		ExtensionInfos:    file_test_ext_proto_extTypes,
 	}.Build()
 	File_test_ext_proto = out.File
 	file_test_ext_proto_rawDesc = nil
diff --git a/internal/testprotos/test/test.pb.go b/internal/testprotos/test/test.pb.go
index c6ffb21..dc0b124 100644
--- a/internal/testprotos/test/test.pb.go
+++ b/internal/testprotos/test/test.pb.go
@@ -2383,7 +2383,7 @@
 	return 0
 }
 
-var file_test_test_proto_extDescs = []protoiface.ExtensionDescV1{
+var file_test_test_proto_extTypes = []protoimpl.ExtensionInfo{
 	{
 		ExtendedType:  (*TestAllExtensions)(nil),
 		ExtensionType: (*int32)(nil),
@@ -3045,177 +3045,177 @@
 // Extension fields to TestAllExtensions.
 var (
 	// optional int32 optional_int32_extension = 1;
-	E_OptionalInt32Extension = &file_test_test_proto_extDescs[0]
+	E_OptionalInt32Extension = &file_test_test_proto_extTypes[0]
 	// optional int64 optional_int64_extension = 2;
-	E_OptionalInt64Extension = &file_test_test_proto_extDescs[1]
+	E_OptionalInt64Extension = &file_test_test_proto_extTypes[1]
 	// optional uint32 optional_uint32_extension = 3;
-	E_OptionalUint32Extension = &file_test_test_proto_extDescs[2]
+	E_OptionalUint32Extension = &file_test_test_proto_extTypes[2]
 	// optional uint64 optional_uint64_extension = 4;
-	E_OptionalUint64Extension = &file_test_test_proto_extDescs[3]
+	E_OptionalUint64Extension = &file_test_test_proto_extTypes[3]
 	// optional sint32 optional_sint32_extension = 5;
-	E_OptionalSint32Extension = &file_test_test_proto_extDescs[4]
+	E_OptionalSint32Extension = &file_test_test_proto_extTypes[4]
 	// optional sint64 optional_sint64_extension = 6;
-	E_OptionalSint64Extension = &file_test_test_proto_extDescs[5]
+	E_OptionalSint64Extension = &file_test_test_proto_extTypes[5]
 	// optional fixed32 optional_fixed32_extension = 7;
-	E_OptionalFixed32Extension = &file_test_test_proto_extDescs[6]
+	E_OptionalFixed32Extension = &file_test_test_proto_extTypes[6]
 	// optional fixed64 optional_fixed64_extension = 8;
-	E_OptionalFixed64Extension = &file_test_test_proto_extDescs[7]
+	E_OptionalFixed64Extension = &file_test_test_proto_extTypes[7]
 	// optional sfixed32 optional_sfixed32_extension = 9;
-	E_OptionalSfixed32Extension = &file_test_test_proto_extDescs[8]
+	E_OptionalSfixed32Extension = &file_test_test_proto_extTypes[8]
 	// optional sfixed64 optional_sfixed64_extension = 10;
-	E_OptionalSfixed64Extension = &file_test_test_proto_extDescs[9]
+	E_OptionalSfixed64Extension = &file_test_test_proto_extTypes[9]
 	// optional float optional_float_extension = 11;
-	E_OptionalFloatExtension = &file_test_test_proto_extDescs[10]
+	E_OptionalFloatExtension = &file_test_test_proto_extTypes[10]
 	// optional double optional_double_extension = 12;
-	E_OptionalDoubleExtension = &file_test_test_proto_extDescs[11]
+	E_OptionalDoubleExtension = &file_test_test_proto_extTypes[11]
 	// optional bool optional_bool_extension = 13;
-	E_OptionalBoolExtension = &file_test_test_proto_extDescs[12]
+	E_OptionalBoolExtension = &file_test_test_proto_extTypes[12]
 	// optional string optional_string_extension = 14;
-	E_OptionalStringExtension = &file_test_test_proto_extDescs[13]
+	E_OptionalStringExtension = &file_test_test_proto_extTypes[13]
 	// optional bytes optional_bytes_extension = 15;
-	E_OptionalBytesExtension = &file_test_test_proto_extDescs[14]
+	E_OptionalBytesExtension = &file_test_test_proto_extTypes[14]
 	// optional goproto.proto.test.OptionalGroup_extension optionalgroup_extension = 16;
-	E_OptionalgroupExtension = &file_test_test_proto_extDescs[15]
+	E_OptionalgroupExtension = &file_test_test_proto_extTypes[15]
 	// optional goproto.proto.test.TestAllTypes.NestedMessage optional_nested_message_extension = 18;
-	E_OptionalNestedMessageExtension = &file_test_test_proto_extDescs[16]
+	E_OptionalNestedMessageExtension = &file_test_test_proto_extTypes[16]
 	// optional goproto.proto.test.TestAllTypes.NestedEnum optional_nested_enum_extension = 21;
-	E_OptionalNestedEnumExtension = &file_test_test_proto_extDescs[17]
+	E_OptionalNestedEnumExtension = &file_test_test_proto_extTypes[17]
 	// repeated int32 repeated_int32_extension = 31;
-	E_RepeatedInt32Extension = &file_test_test_proto_extDescs[18]
+	E_RepeatedInt32Extension = &file_test_test_proto_extTypes[18]
 	// repeated int64 repeated_int64_extension = 32;
-	E_RepeatedInt64Extension = &file_test_test_proto_extDescs[19]
+	E_RepeatedInt64Extension = &file_test_test_proto_extTypes[19]
 	// repeated uint32 repeated_uint32_extension = 33;
-	E_RepeatedUint32Extension = &file_test_test_proto_extDescs[20]
+	E_RepeatedUint32Extension = &file_test_test_proto_extTypes[20]
 	// repeated uint64 repeated_uint64_extension = 34;
-	E_RepeatedUint64Extension = &file_test_test_proto_extDescs[21]
+	E_RepeatedUint64Extension = &file_test_test_proto_extTypes[21]
 	// repeated sint32 repeated_sint32_extension = 35;
-	E_RepeatedSint32Extension = &file_test_test_proto_extDescs[22]
+	E_RepeatedSint32Extension = &file_test_test_proto_extTypes[22]
 	// repeated sint64 repeated_sint64_extension = 36;
-	E_RepeatedSint64Extension = &file_test_test_proto_extDescs[23]
+	E_RepeatedSint64Extension = &file_test_test_proto_extTypes[23]
 	// repeated fixed32 repeated_fixed32_extension = 37;
-	E_RepeatedFixed32Extension = &file_test_test_proto_extDescs[24]
+	E_RepeatedFixed32Extension = &file_test_test_proto_extTypes[24]
 	// repeated fixed64 repeated_fixed64_extension = 38;
-	E_RepeatedFixed64Extension = &file_test_test_proto_extDescs[25]
+	E_RepeatedFixed64Extension = &file_test_test_proto_extTypes[25]
 	// repeated sfixed32 repeated_sfixed32_extension = 39;
-	E_RepeatedSfixed32Extension = &file_test_test_proto_extDescs[26]
+	E_RepeatedSfixed32Extension = &file_test_test_proto_extTypes[26]
 	// repeated sfixed64 repeated_sfixed64_extension = 40;
-	E_RepeatedSfixed64Extension = &file_test_test_proto_extDescs[27]
+	E_RepeatedSfixed64Extension = &file_test_test_proto_extTypes[27]
 	// repeated float repeated_float_extension = 41;
-	E_RepeatedFloatExtension = &file_test_test_proto_extDescs[28]
+	E_RepeatedFloatExtension = &file_test_test_proto_extTypes[28]
 	// repeated double repeated_double_extension = 42;
-	E_RepeatedDoubleExtension = &file_test_test_proto_extDescs[29]
+	E_RepeatedDoubleExtension = &file_test_test_proto_extTypes[29]
 	// repeated bool repeated_bool_extension = 43;
-	E_RepeatedBoolExtension = &file_test_test_proto_extDescs[30]
+	E_RepeatedBoolExtension = &file_test_test_proto_extTypes[30]
 	// repeated string repeated_string_extension = 44;
-	E_RepeatedStringExtension = &file_test_test_proto_extDescs[31]
+	E_RepeatedStringExtension = &file_test_test_proto_extTypes[31]
 	// repeated bytes repeated_bytes_extension = 45;
-	E_RepeatedBytesExtension = &file_test_test_proto_extDescs[32]
+	E_RepeatedBytesExtension = &file_test_test_proto_extTypes[32]
 	// repeated goproto.proto.test.RepeatedGroup_extension repeatedgroup_extension = 46;
-	E_RepeatedgroupExtension = &file_test_test_proto_extDescs[33]
+	E_RepeatedgroupExtension = &file_test_test_proto_extTypes[33]
 	// repeated goproto.proto.test.TestAllTypes.NestedMessage repeated_nested_message_extension = 48;
-	E_RepeatedNestedMessageExtension = &file_test_test_proto_extDescs[34]
+	E_RepeatedNestedMessageExtension = &file_test_test_proto_extTypes[34]
 	// repeated goproto.proto.test.TestAllTypes.NestedEnum repeated_nested_enum_extension = 51;
-	E_RepeatedNestedEnumExtension = &file_test_test_proto_extDescs[35]
+	E_RepeatedNestedEnumExtension = &file_test_test_proto_extTypes[35]
 	// optional int32 default_int32_extension = 81;
-	E_DefaultInt32Extension = &file_test_test_proto_extDescs[36]
+	E_DefaultInt32Extension = &file_test_test_proto_extTypes[36]
 	// optional int64 default_int64_extension = 82;
-	E_DefaultInt64Extension = &file_test_test_proto_extDescs[37]
+	E_DefaultInt64Extension = &file_test_test_proto_extTypes[37]
 	// optional uint32 default_uint32_extension = 83;
-	E_DefaultUint32Extension = &file_test_test_proto_extDescs[38]
+	E_DefaultUint32Extension = &file_test_test_proto_extTypes[38]
 	// optional uint64 default_uint64_extension = 84;
-	E_DefaultUint64Extension = &file_test_test_proto_extDescs[39]
+	E_DefaultUint64Extension = &file_test_test_proto_extTypes[39]
 	// optional sint32 default_sint32_extension = 85;
-	E_DefaultSint32Extension = &file_test_test_proto_extDescs[40]
+	E_DefaultSint32Extension = &file_test_test_proto_extTypes[40]
 	// optional sint64 default_sint64_extension = 86;
-	E_DefaultSint64Extension = &file_test_test_proto_extDescs[41]
+	E_DefaultSint64Extension = &file_test_test_proto_extTypes[41]
 	// optional fixed32 default_fixed32_extension = 87;
-	E_DefaultFixed32Extension = &file_test_test_proto_extDescs[42]
+	E_DefaultFixed32Extension = &file_test_test_proto_extTypes[42]
 	// optional fixed64 default_fixed64_extension = 88;
-	E_DefaultFixed64Extension = &file_test_test_proto_extDescs[43]
+	E_DefaultFixed64Extension = &file_test_test_proto_extTypes[43]
 	// optional sfixed32 default_sfixed32_extension = 89;
-	E_DefaultSfixed32Extension = &file_test_test_proto_extDescs[44]
+	E_DefaultSfixed32Extension = &file_test_test_proto_extTypes[44]
 	// optional sfixed64 default_sfixed64_extension = 80;
-	E_DefaultSfixed64Extension = &file_test_test_proto_extDescs[45]
+	E_DefaultSfixed64Extension = &file_test_test_proto_extTypes[45]
 	// optional float default_float_extension = 91;
-	E_DefaultFloatExtension = &file_test_test_proto_extDescs[46]
+	E_DefaultFloatExtension = &file_test_test_proto_extTypes[46]
 	// optional double default_double_extension = 92;
-	E_DefaultDoubleExtension = &file_test_test_proto_extDescs[47]
+	E_DefaultDoubleExtension = &file_test_test_proto_extTypes[47]
 	// optional bool default_bool_extension = 93;
-	E_DefaultBoolExtension = &file_test_test_proto_extDescs[48]
+	E_DefaultBoolExtension = &file_test_test_proto_extTypes[48]
 	// optional string default_string_extension = 94;
-	E_DefaultStringExtension = &file_test_test_proto_extDescs[49]
+	E_DefaultStringExtension = &file_test_test_proto_extTypes[49]
 	// optional bytes default_bytes_extension = 95;
-	E_DefaultBytesExtension = &file_test_test_proto_extDescs[50]
+	E_DefaultBytesExtension = &file_test_test_proto_extTypes[50]
 	// optional string nested_string_extension = 1003;
-	E_TestNestedExtension_NestedStringExtension = &file_test_test_proto_extDescs[79]
+	E_TestNestedExtension_NestedStringExtension = &file_test_test_proto_extTypes[79]
 	// optional goproto.proto.test.TestRequired single = 1000;
-	E_TestRequired_Single = &file_test_test_proto_extDescs[80]
+	E_TestRequired_Single = &file_test_test_proto_extTypes[80]
 	// repeated goproto.proto.test.TestRequired multi = 1001;
-	E_TestRequired_Multi = &file_test_test_proto_extDescs[81]
+	E_TestRequired_Multi = &file_test_test_proto_extTypes[81]
 )
 
 // Extension fields to TestPackedExtensions.
 var (
 	// repeated int32 packed_int32_extension = 90;
-	E_PackedInt32Extension = &file_test_test_proto_extDescs[51]
+	E_PackedInt32Extension = &file_test_test_proto_extTypes[51]
 	// repeated int64 packed_int64_extension = 91;
-	E_PackedInt64Extension = &file_test_test_proto_extDescs[52]
+	E_PackedInt64Extension = &file_test_test_proto_extTypes[52]
 	// repeated uint32 packed_uint32_extension = 92;
-	E_PackedUint32Extension = &file_test_test_proto_extDescs[53]
+	E_PackedUint32Extension = &file_test_test_proto_extTypes[53]
 	// repeated uint64 packed_uint64_extension = 93;
-	E_PackedUint64Extension = &file_test_test_proto_extDescs[54]
+	E_PackedUint64Extension = &file_test_test_proto_extTypes[54]
 	// repeated sint32 packed_sint32_extension = 94;
-	E_PackedSint32Extension = &file_test_test_proto_extDescs[55]
+	E_PackedSint32Extension = &file_test_test_proto_extTypes[55]
 	// repeated sint64 packed_sint64_extension = 95;
-	E_PackedSint64Extension = &file_test_test_proto_extDescs[56]
+	E_PackedSint64Extension = &file_test_test_proto_extTypes[56]
 	// repeated fixed32 packed_fixed32_extension = 96;
-	E_PackedFixed32Extension = &file_test_test_proto_extDescs[57]
+	E_PackedFixed32Extension = &file_test_test_proto_extTypes[57]
 	// repeated fixed64 packed_fixed64_extension = 97;
-	E_PackedFixed64Extension = &file_test_test_proto_extDescs[58]
+	E_PackedFixed64Extension = &file_test_test_proto_extTypes[58]
 	// repeated sfixed32 packed_sfixed32_extension = 98;
-	E_PackedSfixed32Extension = &file_test_test_proto_extDescs[59]
+	E_PackedSfixed32Extension = &file_test_test_proto_extTypes[59]
 	// repeated sfixed64 packed_sfixed64_extension = 99;
-	E_PackedSfixed64Extension = &file_test_test_proto_extDescs[60]
+	E_PackedSfixed64Extension = &file_test_test_proto_extTypes[60]
 	// repeated float packed_float_extension = 100;
-	E_PackedFloatExtension = &file_test_test_proto_extDescs[61]
+	E_PackedFloatExtension = &file_test_test_proto_extTypes[61]
 	// repeated double packed_double_extension = 101;
-	E_PackedDoubleExtension = &file_test_test_proto_extDescs[62]
+	E_PackedDoubleExtension = &file_test_test_proto_extTypes[62]
 	// repeated bool packed_bool_extension = 102;
-	E_PackedBoolExtension = &file_test_test_proto_extDescs[63]
+	E_PackedBoolExtension = &file_test_test_proto_extTypes[63]
 	// repeated goproto.proto.test.ForeignEnum packed_enum_extension = 103;
-	E_PackedEnumExtension = &file_test_test_proto_extDescs[64]
+	E_PackedEnumExtension = &file_test_test_proto_extTypes[64]
 )
 
 // Extension fields to TestUnpackedExtensions.
 var (
 	// repeated int32 unpacked_int32_extension = 90;
-	E_UnpackedInt32Extension = &file_test_test_proto_extDescs[65]
+	E_UnpackedInt32Extension = &file_test_test_proto_extTypes[65]
 	// repeated int64 unpacked_int64_extension = 91;
-	E_UnpackedInt64Extension = &file_test_test_proto_extDescs[66]
+	E_UnpackedInt64Extension = &file_test_test_proto_extTypes[66]
 	// repeated uint32 unpacked_uint32_extension = 92;
-	E_UnpackedUint32Extension = &file_test_test_proto_extDescs[67]
+	E_UnpackedUint32Extension = &file_test_test_proto_extTypes[67]
 	// repeated uint64 unpacked_uint64_extension = 93;
-	E_UnpackedUint64Extension = &file_test_test_proto_extDescs[68]
+	E_UnpackedUint64Extension = &file_test_test_proto_extTypes[68]
 	// repeated sint32 unpacked_sint32_extension = 94;
-	E_UnpackedSint32Extension = &file_test_test_proto_extDescs[69]
+	E_UnpackedSint32Extension = &file_test_test_proto_extTypes[69]
 	// repeated sint64 unpacked_sint64_extension = 95;
-	E_UnpackedSint64Extension = &file_test_test_proto_extDescs[70]
+	E_UnpackedSint64Extension = &file_test_test_proto_extTypes[70]
 	// repeated fixed32 unpacked_fixed32_extension = 96;
-	E_UnpackedFixed32Extension = &file_test_test_proto_extDescs[71]
+	E_UnpackedFixed32Extension = &file_test_test_proto_extTypes[71]
 	// repeated fixed64 unpacked_fixed64_extension = 97;
-	E_UnpackedFixed64Extension = &file_test_test_proto_extDescs[72]
+	E_UnpackedFixed64Extension = &file_test_test_proto_extTypes[72]
 	// repeated sfixed32 unpacked_sfixed32_extension = 98;
-	E_UnpackedSfixed32Extension = &file_test_test_proto_extDescs[73]
+	E_UnpackedSfixed32Extension = &file_test_test_proto_extTypes[73]
 	// repeated sfixed64 unpacked_sfixed64_extension = 99;
-	E_UnpackedSfixed64Extension = &file_test_test_proto_extDescs[74]
+	E_UnpackedSfixed64Extension = &file_test_test_proto_extTypes[74]
 	// repeated float unpacked_float_extension = 100;
-	E_UnpackedFloatExtension = &file_test_test_proto_extDescs[75]
+	E_UnpackedFloatExtension = &file_test_test_proto_extTypes[75]
 	// repeated double unpacked_double_extension = 101;
-	E_UnpackedDoubleExtension = &file_test_test_proto_extDescs[76]
+	E_UnpackedDoubleExtension = &file_test_test_proto_extTypes[76]
 	// repeated bool unpacked_bool_extension = 102;
-	E_UnpackedBoolExtension = &file_test_test_proto_extDescs[77]
+	E_UnpackedBoolExtension = &file_test_test_proto_extTypes[77]
 	// repeated goproto.proto.test.ForeignEnum unpacked_enum_extension = 103;
-	E_UnpackedEnumExtension = &file_test_test_proto_extDescs[78]
+	E_UnpackedEnumExtension = &file_test_test_proto_extTypes[78]
 )
 
 var File_test_test_proto protoreflect.FileDescriptor
@@ -4986,7 +4986,7 @@
 		DependencyIndexes: file_test_test_proto_depIdxs,
 		EnumInfos:         file_test_test_proto_enumTypes,
 		MessageInfos:      file_test_test_proto_msgTypes,
-		LegacyExtensions:  file_test_test_proto_extDescs,
+		ExtensionInfos:    file_test_test_proto_extTypes,
 	}.Build()
 	File_test_test_proto = out.File
 	file_test_test_proto_rawDesc = nil
diff --git a/proto/decode_test.go b/proto/decode_test.go
index 3d7d6b6..e296fc2 100644
--- a/proto/decode_test.go
+++ b/proto/decode_test.go
@@ -16,7 +16,6 @@
 	"google.golang.org/protobuf/proto"
 	"google.golang.org/protobuf/reflect/protodesc"
 	"google.golang.org/protobuf/reflect/protoreflect"
-	"google.golang.org/protobuf/runtime/protoiface"
 	"google.golang.org/protobuf/runtime/protoimpl"
 
 	legacypb "google.golang.org/protobuf/internal/testprotos/legacy"
@@ -1679,7 +1678,7 @@
 	}
 }
 
-func extend(desc *protoiface.ExtensionDescV1, value interface{}) buildOpt {
+func extend(desc protoreflect.ExtensionType, value interface{}) buildOpt {
 	// TODO: Should ExtensionType.ValueOf accept []T instead of *[]T?
 	t := reflect.TypeOf(value)
 	if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 {
diff --git a/proto/merge_test.go b/proto/merge_test.go
index a0ec571..d94dfb8 100644
--- a/proto/merge_test.go
+++ b/proto/merge_test.go
@@ -274,33 +274,33 @@
 		desc: "merge extension fields",
 		dst: func() proto.Message {
 			m := new(testpb.TestAllExtensions)
-			proto.SetExtension(m, testpb.E_OptionalInt32Extension.Type, int32(32))
-			proto.SetExtension(m, testpb.E_OptionalNestedMessageExtension.Type,
+			proto.SetExtension(m, testpb.E_OptionalInt32Extension, int32(32))
+			proto.SetExtension(m, testpb.E_OptionalNestedMessageExtension,
 				&testpb.TestAllTypes_NestedMessage{
 					A: proto.Int32(50),
 				},
 			)
-			proto.SetExtension(m, testpb.E_RepeatedFixed32Extension.Type, &[]uint32{1, 2, 3})
+			proto.SetExtension(m, testpb.E_RepeatedFixed32Extension, &[]uint32{1, 2, 3})
 			return m
 		}(),
 		src: func() proto.Message {
 			m := new(testpb.TestAllExtensions)
-			proto.SetExtension(m, testpb.E_OptionalInt64Extension.Type, int64(64))
-			proto.SetExtension(m, testpb.E_OptionalNestedMessageExtension.Type,
+			proto.SetExtension(m, testpb.E_OptionalInt64Extension, int64(64))
+			proto.SetExtension(m, testpb.E_OptionalNestedMessageExtension,
 				&testpb.TestAllTypes_NestedMessage{
 					Corecursive: &testpb.TestAllTypes{
 						OptionalInt64: proto.Int64(1000),
 					},
 				},
 			)
-			proto.SetExtension(m, testpb.E_RepeatedFixed32Extension.Type, &[]uint32{4, 5, 6})
+			proto.SetExtension(m, testpb.E_RepeatedFixed32Extension, &[]uint32{4, 5, 6})
 			return m
 		}(),
 		want: func() proto.Message {
 			m := new(testpb.TestAllExtensions)
-			proto.SetExtension(m, testpb.E_OptionalInt32Extension.Type, int32(32))
-			proto.SetExtension(m, testpb.E_OptionalInt64Extension.Type, int64(64))
-			proto.SetExtension(m, testpb.E_OptionalNestedMessageExtension.Type,
+			proto.SetExtension(m, testpb.E_OptionalInt32Extension, int32(32))
+			proto.SetExtension(m, testpb.E_OptionalInt64Extension, int64(64))
+			proto.SetExtension(m, testpb.E_OptionalNestedMessageExtension,
 				&testpb.TestAllTypes_NestedMessage{
 					A: proto.Int32(50),
 					Corecursive: &testpb.TestAllTypes{
@@ -308,7 +308,7 @@
 					},
 				},
 			)
-			proto.SetExtension(m, testpb.E_RepeatedFixed32Extension.Type, &[]uint32{1, 2, 3, 4, 5, 6})
+			proto.SetExtension(m, testpb.E_RepeatedFixed32Extension, &[]uint32{1, 2, 3, 4, 5, 6})
 			return m
 		}(),
 	}, {
diff --git a/reflect/protoregistry/registry_test.go b/reflect/protoregistry/registry_test.go
index 1572b63..a52bf97 100644
--- a/reflect/protoregistry/registry_test.go
+++ b/reflect/protoregistry/registry_test.go
@@ -323,8 +323,8 @@
 func TestTypes(t *testing.T) {
 	mt1 := pimpl.Export{}.MessageTypeOf(&testpb.Message1{})
 	et1 := pimpl.Export{}.EnumTypeOf(testpb.Enum1_ONE)
-	xt1 := testpb.E_StringField.Type
-	xt2 := testpb.E_Message4_MessageField.Type
+	xt1 := testpb.E_StringField
+	xt2 := testpb.E_Message4_MessageField
 	registry := new(preg.Types)
 	if err := registry.Register(mt1, et1, xt1, xt2); err != nil {
 		t.Fatalf("registry.Register() returns unexpected error: %v", err)
diff --git a/reflect/protoregistry/testprotos/test.pb.go b/reflect/protoregistry/testprotos/test.pb.go
index c9f59a5..d4f9d12 100644
--- a/reflect/protoregistry/testprotos/test.pb.go
+++ b/reflect/protoregistry/testprotos/test.pb.go
@@ -327,7 +327,7 @@
 	return false
 }
 
-var file_test_proto_extDescs = []protoiface.ExtensionDescV1{
+var file_test_proto_extTypes = []protoimpl.ExtensionInfo{
 	{
 		ExtendedType:  (*Message1)(nil),
 		ExtensionType: (*string)(nil),
@@ -381,17 +381,17 @@
 // Extension fields to Message1.
 var (
 	// optional string string_field = 11;
-	E_StringField = &file_test_proto_extDescs[0]
+	E_StringField = &file_test_proto_extTypes[0]
 	// optional testprotos.Enum1 enum_field = 12;
-	E_EnumField = &file_test_proto_extDescs[1]
+	E_EnumField = &file_test_proto_extTypes[1]
 	// optional testprotos.Message2 message_field = 13;
-	E_MessageField = &file_test_proto_extDescs[2]
+	E_MessageField = &file_test_proto_extTypes[2]
 	// optional testprotos.Message2 message_field = 21;
-	E_Message4_MessageField = &file_test_proto_extDescs[3]
+	E_Message4_MessageField = &file_test_proto_extTypes[3]
 	// optional testprotos.Enum1 enum_field = 22;
-	E_Message4_EnumField = &file_test_proto_extDescs[4]
+	E_Message4_EnumField = &file_test_proto_extTypes[4]
 	// optional string string_field = 23;
-	E_Message4_StringField = &file_test_proto_extDescs[5]
+	E_Message4_StringField = &file_test_proto_extTypes[5]
 )
 
 var File_test_proto protoreflect.FileDescriptor
@@ -552,7 +552,7 @@
 		DependencyIndexes: file_test_proto_depIdxs,
 		EnumInfos:         file_test_proto_enumTypes,
 		MessageInfos:      file_test_proto_msgTypes,
-		LegacyExtensions:  file_test_proto_extDescs,
+		ExtensionInfos:    file_test_proto_extTypes,
 	}.Build()
 	File_test_proto = out.File
 	file_test_proto_rawDesc = nil
diff --git a/runtime/protoiface/legacy.go b/runtime/protoiface/legacy.go
index d7acb33..c587276 100644
--- a/runtime/protoiface/legacy.go
+++ b/runtime/protoiface/legacy.go
@@ -4,12 +4,6 @@
 
 package protoiface
 
-import (
-	"reflect"
-
-	"google.golang.org/protobuf/reflect/protoreflect"
-)
-
 type MessageV1 interface {
 	Reset()
 	String() string
@@ -19,78 +13,3 @@
 type ExtensionRangeV1 struct {
 	Start, End int32 // both inclusive
 }
-
-type ExtensionDescV1 struct {
-	// Type is the descriptor type for the extension field using the v2 API.
-	// If populated, the information in this field takes precedence over
-	// all other fields in ExtensionDescV1.
-	Type protoreflect.ExtensionType
-
-	// ExtendedType is a typed nil-pointer to the parent message type that
-	// is being extended. It is possible for this to be unpopulated in v2
-	// since the message may no longer implement the MessageV1 interface.
-	//
-	// Deprecated: Use Type.ExtendedType instead.
-	ExtendedType MessageV1
-
-	// ExtensionType is zero value of the extension type.
-	//
-	// For historical reasons, reflect.TypeOf(ExtensionType) and Type.GoType
-	// may not be identical:
-	//	* for scalars (except []byte), where ExtensionType uses *T,
-	//	while Type.GoType uses T.
-	//	* for repeated fields, where ExtensionType uses []T,
-	//	while Type.GoType uses *[]T.
-	//
-	// Deprecated: Use Type.GoType instead.
-	ExtensionType interface{}
-
-	// Field is the field number of the extension.
-	//
-	// Deprecated: Use Type.Number instead.
-	Field int32
-
-	// Name is the fully qualified name of extension.
-	//
-	// Deprecated: Use Type.FullName instead.
-	Name string
-
-	// Tag is the protobuf struct tag used in the v1 API.
-	//
-	// Deprecated: Do not use.
-	Tag string
-
-	// Filename is the proto filename in which the extension is defined.
-	//
-	// Deprecated: Use Type.Parent to ascend to the top-most parent and use
-	// protoreflect.FileDescriptor.Path.
-	Filename string
-}
-
-func (e ExtensionDescV1) getType() protoreflect.ExtensionType {
-	if e.Type != nil {
-		return e.Type
-	}
-	// All ExtensionDescV1 instances in generated code should have
-	// an Type field initialized at init time, so this case only
-	// occurs for non-standard generated code and hand-written
-	// ExtensionDescs.
-	panic(`proto: ExtensionDesc.Type is not set.
-
-This error probably indicates that you are trying to use a non-standard
-"github.com/golang/protobuf/proto".ExtensionDesc with the
-"google.golang.org/golang/protobuf" API. Use a protoreflect.ExtensionType
-instead.
-`)
-}
-
-func (e ExtensionDescV1) New() protoreflect.Value  { return e.getType().New() }
-func (e ExtensionDescV1) Zero() protoreflect.Value { return e.getType().Zero() }
-func (e ExtensionDescV1) GoType() reflect.Type     { return e.getType().GoType() }
-func (e ExtensionDescV1) Descriptor() protoreflect.ExtensionTypeDescriptor {
-	return e.getType().Descriptor()
-}
-func (e ExtensionDescV1) ValueOf(x interface{}) protoreflect.Value { return e.getType().ValueOf(x) }
-func (e ExtensionDescV1) InterfaceOf(x protoreflect.Value) interface{} {
-	return e.getType().InterfaceOf(x)
-}
diff --git a/runtime/protoimpl/impl.go b/runtime/protoimpl/impl.go
index f58b569..aff6570 100644
--- a/runtime/protoimpl/impl.go
+++ b/runtime/protoimpl/impl.go
@@ -15,7 +15,6 @@
 	"google.golang.org/protobuf/internal/filedesc"
 	"google.golang.org/protobuf/internal/filetype"
 	"google.golang.org/protobuf/internal/impl"
-	"google.golang.org/protobuf/runtime/protoiface"
 )
 
 // UnsafeEnabled specifies whether package unsafe can be used.
@@ -29,7 +28,7 @@
 	// Types used by generated code to implement EnumType, MessageType, and ExtensionType.
 	EnumInfo      = filetype.EnumInfo
 	MessageInfo   = impl.MessageInfo
-	ExtensionInfo = protoiface.ExtensionDescV1
+	ExtensionInfo = impl.ExtensionInfo
 
 	// Types embedded in generated messages.
 	MessageState     = impl.MessageState