cmd/protoc-gen-go: correlate v1 ExtensionDesc with v2 ExtensionType

Unfortunately a good amount of code uses pointer comparisons on the
v1 ExtensionDesc to determine exactly which extension field is set,
rather than checking whether the extension descriptor semantically
describes the field that they are interested in.

To preserve this behavior in v1, we need a 1:1 mapping between
a v2 ExtensionType and a specific v1 ExtensionDesc.

Change-Id: I852b3cefb4585bd656e48e5adad6cc28795d02df
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/167759
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/cmd/protoc-gen-go/internal_gengo/main.go b/cmd/protoc-gen-go/internal_gengo/main.go
index c124467..f05ca80 100644
--- a/cmd/protoc-gen-go/internal_gengo/main.go
+++ b/cmd/protoc-gen-go/internal_gengo/main.go
@@ -146,9 +146,7 @@
 	for _, message := range f.allMessages {
 		genMessage(gen, g, f, message)
 	}
-	for _, extension := range f.allExtensions {
-		genExtension(gen, g, f, extension)
-	}
+	genExtensions(gen, g, f)
 
 	genInitFunction(gen, g, f)
 	genFileDescriptor(gen, g, f)
@@ -690,33 +688,58 @@
 	return string(field.Desc.Name()) + ",omitempty"
 }
 
-func genExtension(gen *protogen.Plugin, g *protogen.GeneratedFile, f *fileInfo, extension *protogen.Extension) {
-	// Special case for proto2 message sets: If this extension is extending
-	// proto2.bridge.MessageSet, and its final name component is "message_set_extension",
-	// then drop that last component.
-	//
-	// TODO: This should be implemented in the text formatter rather than the generator.
-	// In addition, the situation for when to apply this special case is implemented
-	// differently in other languages:
-	// https://github.com/google/protobuf/blob/aff10976/src/google/protobuf/text_format.cc#L1560
-	name := extension.Desc.FullName()
-	if n, ok := isExtensionMessageSetElement(extension); ok {
-		name = n
+func genExtensions(gen *protogen.Plugin, g *protogen.GeneratedFile, f *fileInfo) {
+	if len(f.allExtensions) == 0 {
+		return
 	}
 
-	g.P("var ", extensionVar(f.File, extension), " = &", f.protoPackage().Ident("ExtensionDesc"), "{")
-	g.P("ExtendedType: (*", extension.ExtendedType.GoIdent, ")(nil),")
-	goType, pointer := fieldGoType(g, extension)
-	if pointer {
-		goType = "*" + goType
+	g.P("var ", extDecsVarName(f), " = []", f.protoPackage().Ident("ExtensionDesc"), "{")
+	for _, extension := range f.allExtensions {
+		// Special case for proto2 message sets: If this extension is extending
+		// proto2.bridge.MessageSet, and its final name component is "message_set_extension",
+		// then drop that last component.
+		//
+		// TODO: This should be implemented in the text formatter rather than the generator.
+		// In addition, the situation for when to apply this special case is implemented
+		// differently in other languages:
+		// https://github.com/google/protobuf/blob/aff10976/src/google/protobuf/text_format.cc#L1560
+		name := extension.Desc.FullName()
+		if n, ok := isExtensionMessageSetElement(extension); ok {
+			name = n
+		}
+
+		g.P("{")
+		g.P("ExtendedType: (*", extension.ExtendedType.GoIdent, ")(nil),")
+		goType, pointer := fieldGoType(g, extension)
+		if pointer {
+			goType = "*" + goType
+		}
+		g.P("ExtensionType: (", goType, ")(nil),")
+		g.P("Field: ", extension.Desc.Number(), ",")
+		g.P("Name: ", strconv.Quote(string(name)), ",")
+		g.P("Tag: ", strconv.Quote(fieldProtobufTag(extension)), ",")
+		g.P("Filename: ", strconv.Quote(f.Desc.Path()), ",")
+		g.P("},")
 	}
-	g.P("ExtensionType: (", goType, ")(nil),")
-	g.P("Field: ", extension.Desc.Number(), ",")
-	g.P("Name: ", strconv.Quote(string(name)), ",")
-	g.P("Tag: ", strconv.Quote(fieldProtobufTag(extension)), ",")
-	g.P("Filename: ", strconv.Quote(f.Desc.Path()), ",")
 	g.P("}")
-	g.P()
+
+	g.P("var (")
+	for i, extension := range f.allExtensions {
+		ed := extension.Desc
+		targetName := string(ed.ExtendedType().FullName())
+		typeName := ed.Kind().String()
+		switch ed.Kind() {
+		case protoreflect.EnumKind:
+			typeName = string(ed.EnumType().FullName())
+		case protoreflect.MessageKind, protoreflect.GroupKind:
+			typeName = string(ed.MessageType().FullName())
+		}
+		fieldName := string(ed.Name())
+		g.P("// extend ", targetName, " { ", ed.Cardinality().String(), " ", typeName, " ", fieldName, " = ", ed.Number(), "; }")
+		g.P(extensionVar(f.File, extension), " = &", extDecsVarName(f), "[", i, "]")
+		g.P()
+	}
+	g.P(")")
 }
 
 // isExtensionMessageSetELement returns the adjusted name of an extension
diff --git a/cmd/protoc-gen-go/internal_gengo/reflect.go b/cmd/protoc-gen-go/internal_gengo/reflect.go
index 55fb42c..3e5300c 100644
--- a/cmd/protoc-gen-go/internal_gengo/reflect.go
+++ b/cmd/protoc-gen-go/internal_gengo/reflect.go
@@ -167,6 +167,9 @@
 	g.P("RawDescriptor: ", f.descriptorRawVar, ",")
 	g.P("GoTypes: ", goTypesVarName(f), ",")
 	g.P("DependencyIndexes: ", depIdxsVarName(f), ",")
+	if len(f.allExtensions) > 0 {
+		g.P("LegacyExtensions: ", extDecsVarName(f), ",")
+	}
 	if len(f.allEnums) > 0 {
 		g.P("EnumOutputTypes: ", enumTypesVarName(f), ",")
 	}
@@ -187,11 +190,6 @@
 		g.P("}")
 	}
 
-	// Copy the local list of extension types into each global variable.
-	for i, extension := range f.allExtensions {
-		g.P(extensionVar(f.File, extension), ".Type = extensionTypes[", i, "]")
-	}
-
 	// TODO: Add v2 registration and stop v1 registration in genInitFunction.
 
 	// The descriptor proto needs to register the option types with the
@@ -241,6 +239,9 @@
 func messageTypesVarName(f *fileInfo) string {
 	return "xxx_" + f.GoDescriptorIdent.GoName + "_messageTypes"
 }
+func extDecsVarName(f *fileInfo) string {
+	return "xxx_" + f.GoDescriptorIdent.GoName + "_extDescs"
+}
 func initFuncName(f *protogen.File) string {
 	return "xxx_" + f.GoDescriptorIdent.GoName + "_init"
 }
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 0a7f77b..6800c2e 100644
--- a/cmd/protoc-gen-go/testdata/extensions/ext/ext.pb.go
+++ b/cmd/protoc-gen-go/testdata/extensions/ext/ext.pb.go
@@ -375,401 +375,493 @@
 
 var xxx_messageInfo_ExtendingMessage_ExtendingMessageSubmessage proto.InternalMessageInfo
 
-var E_ExtensionBool = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: (*bool)(nil),
-	Field:         101,
-	Name:          "goproto.protoc.extension.ext.extension_bool",
-	Tag:           "varint,101,opt,name=extension_bool",
-	Filename:      "extensions/ext/ext.proto",
+var xxx_File_extensions_ext_ext_proto_extDescs = []proto.ExtensionDesc{
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: (*bool)(nil),
+		Field:         101,
+		Name:          "goproto.protoc.extension.ext.extension_bool",
+		Tag:           "varint,101,opt,name=extension_bool",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: (*Enum)(nil),
+		Field:         102,
+		Name:          "goproto.protoc.extension.ext.extension_enum",
+		Tag:           "varint,102,opt,name=extension_enum,enum=goproto.protoc.extension.ext.Enum",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: (*int32)(nil),
+		Field:         103,
+		Name:          "goproto.protoc.extension.ext.extension_int32",
+		Tag:           "varint,103,opt,name=extension_int32",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: (*int32)(nil),
+		Field:         104,
+		Name:          "goproto.protoc.extension.ext.extension_sint32",
+		Tag:           "zigzag32,104,opt,name=extension_sint32",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: (*uint32)(nil),
+		Field:         105,
+		Name:          "goproto.protoc.extension.ext.extension_uint32",
+		Tag:           "varint,105,opt,name=extension_uint32",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: (*int64)(nil),
+		Field:         106,
+		Name:          "goproto.protoc.extension.ext.extension_int64",
+		Tag:           "varint,106,opt,name=extension_int64",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: (*int64)(nil),
+		Field:         107,
+		Name:          "goproto.protoc.extension.ext.extension_sint64",
+		Tag:           "zigzag64,107,opt,name=extension_sint64",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: (*uint64)(nil),
+		Field:         108,
+		Name:          "goproto.protoc.extension.ext.extension_uint64",
+		Tag:           "varint,108,opt,name=extension_uint64",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: (*int32)(nil),
+		Field:         109,
+		Name:          "goproto.protoc.extension.ext.extension_sfixed32",
+		Tag:           "fixed32,109,opt,name=extension_sfixed32",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: (*uint32)(nil),
+		Field:         110,
+		Name:          "goproto.protoc.extension.ext.extension_fixed32",
+		Tag:           "fixed32,110,opt,name=extension_fixed32",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: (*float32)(nil),
+		Field:         111,
+		Name:          "goproto.protoc.extension.ext.extension_float",
+		Tag:           "fixed32,111,opt,name=extension_float",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: (*int64)(nil),
+		Field:         112,
+		Name:          "goproto.protoc.extension.ext.extension_sfixed64",
+		Tag:           "fixed64,112,opt,name=extension_sfixed64",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: (*uint64)(nil),
+		Field:         113,
+		Name:          "goproto.protoc.extension.ext.extension_fixed64",
+		Tag:           "fixed64,113,opt,name=extension_fixed64",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: (*float64)(nil),
+		Field:         114,
+		Name:          "goproto.protoc.extension.ext.extension_double",
+		Tag:           "fixed64,114,opt,name=extension_double",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: (*string)(nil),
+		Field:         115,
+		Name:          "goproto.protoc.extension.ext.extension_string",
+		Tag:           "bytes,115,opt,name=extension_string",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: ([]byte)(nil),
+		Field:         116,
+		Name:          "goproto.protoc.extension.ext.extension_bytes",
+		Tag:           "bytes,116,opt,name=extension_bytes",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: (*Message)(nil),
+		Field:         117,
+		Name:          "goproto.protoc.extension.ext.extension_Message",
+		Tag:           "bytes,117,opt,name=extension_Message",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: (*Message_M)(nil),
+		Field:         118,
+		Name:          "goproto.protoc.extension.ext.extension_MessageM",
+		Tag:           "bytes,118,opt,name=extension_MessageM",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: (*ExtensionGroup)(nil),
+		Field:         119,
+		Name:          "goproto.protoc.extension.ext.extensiongroup",
+		Tag:           "group,119,opt,name=ExtensionGroup",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: (*extra.ExtraMessage)(nil),
+		Field:         9,
+		Name:          "goproto.protoc.extension.ext.extra_message",
+		Tag:           "bytes,9,opt,name=extra_message",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: ([]bool)(nil),
+		Field:         301,
+		Name:          "goproto.protoc.extension.ext.repeated_x_bool",
+		Tag:           "varint,301,rep,name=repeated_x_bool",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: ([]Enum)(nil),
+		Field:         302,
+		Name:          "goproto.protoc.extension.ext.repeated_x_enum",
+		Tag:           "varint,302,rep,name=repeated_x_enum,enum=goproto.protoc.extension.ext.Enum",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: ([]int32)(nil),
+		Field:         303,
+		Name:          "goproto.protoc.extension.ext.repeated_x_int32",
+		Tag:           "varint,303,rep,name=repeated_x_int32",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: ([]int32)(nil),
+		Field:         304,
+		Name:          "goproto.protoc.extension.ext.repeated_x_sint32",
+		Tag:           "zigzag32,304,rep,name=repeated_x_sint32",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: ([]uint32)(nil),
+		Field:         305,
+		Name:          "goproto.protoc.extension.ext.repeated_x_uint32",
+		Tag:           "varint,305,rep,name=repeated_x_uint32",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: ([]int64)(nil),
+		Field:         306,
+		Name:          "goproto.protoc.extension.ext.repeated_x_int64",
+		Tag:           "varint,306,rep,name=repeated_x_int64",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: ([]int64)(nil),
+		Field:         307,
+		Name:          "goproto.protoc.extension.ext.repeated_x_sint64",
+		Tag:           "zigzag64,307,rep,name=repeated_x_sint64",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: ([]uint64)(nil),
+		Field:         308,
+		Name:          "goproto.protoc.extension.ext.repeated_x_uint64",
+		Tag:           "varint,308,rep,name=repeated_x_uint64",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: ([]int32)(nil),
+		Field:         309,
+		Name:          "goproto.protoc.extension.ext.repeated_x_sfixed32",
+		Tag:           "fixed32,309,rep,name=repeated_x_sfixed32",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: ([]uint32)(nil),
+		Field:         310,
+		Name:          "goproto.protoc.extension.ext.repeated_x_fixed32",
+		Tag:           "fixed32,310,rep,name=repeated_x_fixed32",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: ([]float32)(nil),
+		Field:         311,
+		Name:          "goproto.protoc.extension.ext.repeated_x_float",
+		Tag:           "fixed32,311,rep,name=repeated_x_float",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: ([]int64)(nil),
+		Field:         312,
+		Name:          "goproto.protoc.extension.ext.repeated_x_sfixed64",
+		Tag:           "fixed64,312,rep,name=repeated_x_sfixed64",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: ([]uint64)(nil),
+		Field:         313,
+		Name:          "goproto.protoc.extension.ext.repeated_x_fixed64",
+		Tag:           "fixed64,313,rep,name=repeated_x_fixed64",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: ([]float64)(nil),
+		Field:         314,
+		Name:          "goproto.protoc.extension.ext.repeated_x_double",
+		Tag:           "fixed64,314,rep,name=repeated_x_double",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: ([]string)(nil),
+		Field:         315,
+		Name:          "goproto.protoc.extension.ext.repeated_x_string",
+		Tag:           "bytes,315,rep,name=repeated_x_string",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: ([][]byte)(nil),
+		Field:         316,
+		Name:          "goproto.protoc.extension.ext.repeated_x_bytes",
+		Tag:           "bytes,316,rep,name=repeated_x_bytes",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: ([]*Message)(nil),
+		Field:         317,
+		Name:          "goproto.protoc.extension.ext.repeated_x_Message",
+		Tag:           "bytes,317,rep,name=repeated_x_Message",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: ([]*RepeatedGroup)(nil),
+		Field:         318,
+		Name:          "goproto.protoc.extension.ext.repeatedgroup",
+		Tag:           "group,318,rep,name=RepeatedGroup",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: (*Extendable)(nil),
+		Field:         400,
+		Name:          "goproto.protoc.extension.ext.extendable_field",
+		Tag:           "bytes,400,opt,name=extendable_field",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*Extendable)(nil),
+		ExtensionType: (*string)(nil),
+		Field:         1,
+		Name:          "goproto.protoc.extension.ext.extendable_string_field",
+		Tag:           "bytes,1,opt,name=extendable_string_field",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.MessageSetWireFormatMessage)(nil),
+		ExtensionType: (*MessageSetWireFormatExtension)(nil),
+		Field:         101,
+		Name:          "goproto.protoc.extension.ext.",
+		Tag:           "bytes,101,opt,name=message_set_extension",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: (*string)(nil),
+		Field:         200,
+		Name:          "goproto.protoc.extension.ext.ExtendingMessage.extending_message_string",
+		Tag:           "bytes,200,opt,name=extending_message_string",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.BaseMessage)(nil),
+		ExtensionType: (*ExtendingMessage_ExtendingMessageSubmessage)(nil),
+		Field:         201,
+		Name:          "goproto.protoc.extension.ext.ExtendingMessage.extending_message_submessage",
+		Tag:           "bytes,201,opt,name=extending_message_submessage",
+		Filename:      "extensions/ext/ext.proto",
+	},
+	{
+		ExtendedType:  (*base.MessageSetWireFormatMessage)(nil),
+		ExtensionType: (*MessageSetWireFormatExtension)(nil),
+		Field:         100,
+		Name:          "goproto.protoc.extension.ext.MessageSetWireFormatExtension",
+		Tag:           "bytes,100,opt,name=message_set_extension",
+		Filename:      "extensions/ext/ext.proto",
+	},
 }
+var (
+	// extend goproto.protoc.extension.base.BaseMessage { optional bool extension_bool = 101; }
+	E_ExtensionBool = &xxx_File_extensions_ext_ext_proto_extDescs[0]
 
-var E_ExtensionEnum = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: (*Enum)(nil),
-	Field:         102,
-	Name:          "goproto.protoc.extension.ext.extension_enum",
-	Tag:           "varint,102,opt,name=extension_enum,enum=goproto.protoc.extension.ext.Enum",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { optional goproto.protoc.extension.ext.Enum extension_enum = 102; }
+	E_ExtensionEnum = &xxx_File_extensions_ext_ext_proto_extDescs[1]
 
-var E_ExtensionInt32 = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: (*int32)(nil),
-	Field:         103,
-	Name:          "goproto.protoc.extension.ext.extension_int32",
-	Tag:           "varint,103,opt,name=extension_int32",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { optional int32 extension_int32 = 103; }
+	E_ExtensionInt32 = &xxx_File_extensions_ext_ext_proto_extDescs[2]
 
-var E_ExtensionSint32 = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: (*int32)(nil),
-	Field:         104,
-	Name:          "goproto.protoc.extension.ext.extension_sint32",
-	Tag:           "zigzag32,104,opt,name=extension_sint32",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { optional sint32 extension_sint32 = 104; }
+	E_ExtensionSint32 = &xxx_File_extensions_ext_ext_proto_extDescs[3]
 
-var E_ExtensionUint32 = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: (*uint32)(nil),
-	Field:         105,
-	Name:          "goproto.protoc.extension.ext.extension_uint32",
-	Tag:           "varint,105,opt,name=extension_uint32",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { optional uint32 extension_uint32 = 105; }
+	E_ExtensionUint32 = &xxx_File_extensions_ext_ext_proto_extDescs[4]
 
-var E_ExtensionInt64 = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: (*int64)(nil),
-	Field:         106,
-	Name:          "goproto.protoc.extension.ext.extension_int64",
-	Tag:           "varint,106,opt,name=extension_int64",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { optional int64 extension_int64 = 106; }
+	E_ExtensionInt64 = &xxx_File_extensions_ext_ext_proto_extDescs[5]
 
-var E_ExtensionSint64 = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: (*int64)(nil),
-	Field:         107,
-	Name:          "goproto.protoc.extension.ext.extension_sint64",
-	Tag:           "zigzag64,107,opt,name=extension_sint64",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { optional sint64 extension_sint64 = 107; }
+	E_ExtensionSint64 = &xxx_File_extensions_ext_ext_proto_extDescs[6]
 
-var E_ExtensionUint64 = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: (*uint64)(nil),
-	Field:         108,
-	Name:          "goproto.protoc.extension.ext.extension_uint64",
-	Tag:           "varint,108,opt,name=extension_uint64",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { optional uint64 extension_uint64 = 108; }
+	E_ExtensionUint64 = &xxx_File_extensions_ext_ext_proto_extDescs[7]
 
-var E_ExtensionSfixed32 = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: (*int32)(nil),
-	Field:         109,
-	Name:          "goproto.protoc.extension.ext.extension_sfixed32",
-	Tag:           "fixed32,109,opt,name=extension_sfixed32",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { optional sfixed32 extension_sfixed32 = 109; }
+	E_ExtensionSfixed32 = &xxx_File_extensions_ext_ext_proto_extDescs[8]
 
-var E_ExtensionFixed32 = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: (*uint32)(nil),
-	Field:         110,
-	Name:          "goproto.protoc.extension.ext.extension_fixed32",
-	Tag:           "fixed32,110,opt,name=extension_fixed32",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { optional fixed32 extension_fixed32 = 110; }
+	E_ExtensionFixed32 = &xxx_File_extensions_ext_ext_proto_extDescs[9]
 
-var E_ExtensionFloat = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: (*float32)(nil),
-	Field:         111,
-	Name:          "goproto.protoc.extension.ext.extension_float",
-	Tag:           "fixed32,111,opt,name=extension_float",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { optional float extension_float = 111; }
+	E_ExtensionFloat = &xxx_File_extensions_ext_ext_proto_extDescs[10]
 
-var E_ExtensionSfixed64 = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: (*int64)(nil),
-	Field:         112,
-	Name:          "goproto.protoc.extension.ext.extension_sfixed64",
-	Tag:           "fixed64,112,opt,name=extension_sfixed64",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { optional sfixed64 extension_sfixed64 = 112; }
+	E_ExtensionSfixed64 = &xxx_File_extensions_ext_ext_proto_extDescs[11]
 
-var E_ExtensionFixed64 = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: (*uint64)(nil),
-	Field:         113,
-	Name:          "goproto.protoc.extension.ext.extension_fixed64",
-	Tag:           "fixed64,113,opt,name=extension_fixed64",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { optional fixed64 extension_fixed64 = 113; }
+	E_ExtensionFixed64 = &xxx_File_extensions_ext_ext_proto_extDescs[12]
 
-var E_ExtensionDouble = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: (*float64)(nil),
-	Field:         114,
-	Name:          "goproto.protoc.extension.ext.extension_double",
-	Tag:           "fixed64,114,opt,name=extension_double",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { optional double extension_double = 114; }
+	E_ExtensionDouble = &xxx_File_extensions_ext_ext_proto_extDescs[13]
 
-var E_ExtensionString = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: (*string)(nil),
-	Field:         115,
-	Name:          "goproto.protoc.extension.ext.extension_string",
-	Tag:           "bytes,115,opt,name=extension_string",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { optional string extension_string = 115; }
+	E_ExtensionString = &xxx_File_extensions_ext_ext_proto_extDescs[14]
 
-var E_ExtensionBytes = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: ([]byte)(nil),
-	Field:         116,
-	Name:          "goproto.protoc.extension.ext.extension_bytes",
-	Tag:           "bytes,116,opt,name=extension_bytes",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { optional bytes extension_bytes = 116; }
+	E_ExtensionBytes = &xxx_File_extensions_ext_ext_proto_extDescs[15]
 
-var E_Extension_Message = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: (*Message)(nil),
-	Field:         117,
-	Name:          "goproto.protoc.extension.ext.extension_Message",
-	Tag:           "bytes,117,opt,name=extension_Message",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { optional goproto.protoc.extension.ext.Message extension_Message = 117; }
+	E_Extension_Message = &xxx_File_extensions_ext_ext_proto_extDescs[16]
 
-var E_Extension_MessageM = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: (*Message_M)(nil),
-	Field:         118,
-	Name:          "goproto.protoc.extension.ext.extension_MessageM",
-	Tag:           "bytes,118,opt,name=extension_MessageM",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { optional goproto.protoc.extension.ext.Message.M extension_MessageM = 118; }
+	E_Extension_MessageM = &xxx_File_extensions_ext_ext_proto_extDescs[17]
 
-var E_Extensiongroup = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: (*ExtensionGroup)(nil),
-	Field:         119,
-	Name:          "goproto.protoc.extension.ext.extensiongroup",
-	Tag:           "group,119,opt,name=ExtensionGroup",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { optional goproto.protoc.extension.ext.ExtensionGroup extensiongroup = 119; }
+	E_Extensiongroup = &xxx_File_extensions_ext_ext_proto_extDescs[18]
 
-var E_ExtraMessage = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: (*extra.ExtraMessage)(nil),
-	Field:         9,
-	Name:          "goproto.protoc.extension.ext.extra_message",
-	Tag:           "bytes,9,opt,name=extra_message",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { optional goproto.protoc.extension.extra.ExtraMessage extra_message = 9; }
+	E_ExtraMessage = &xxx_File_extensions_ext_ext_proto_extDescs[19]
 
-var E_RepeatedXBool = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: ([]bool)(nil),
-	Field:         301,
-	Name:          "goproto.protoc.extension.ext.repeated_x_bool",
-	Tag:           "varint,301,rep,name=repeated_x_bool",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { repeated bool repeated_x_bool = 301; }
+	E_RepeatedXBool = &xxx_File_extensions_ext_ext_proto_extDescs[20]
 
-var E_RepeatedXEnum = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: ([]Enum)(nil),
-	Field:         302,
-	Name:          "goproto.protoc.extension.ext.repeated_x_enum",
-	Tag:           "varint,302,rep,name=repeated_x_enum,enum=goproto.protoc.extension.ext.Enum",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { repeated goproto.protoc.extension.ext.Enum repeated_x_enum = 302; }
+	E_RepeatedXEnum = &xxx_File_extensions_ext_ext_proto_extDescs[21]
 
-var E_RepeatedXInt32 = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: ([]int32)(nil),
-	Field:         303,
-	Name:          "goproto.protoc.extension.ext.repeated_x_int32",
-	Tag:           "varint,303,rep,name=repeated_x_int32",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { repeated int32 repeated_x_int32 = 303; }
+	E_RepeatedXInt32 = &xxx_File_extensions_ext_ext_proto_extDescs[22]
 
-var E_RepeatedXSint32 = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: ([]int32)(nil),
-	Field:         304,
-	Name:          "goproto.protoc.extension.ext.repeated_x_sint32",
-	Tag:           "zigzag32,304,rep,name=repeated_x_sint32",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { repeated sint32 repeated_x_sint32 = 304; }
+	E_RepeatedXSint32 = &xxx_File_extensions_ext_ext_proto_extDescs[23]
 
-var E_RepeatedXUint32 = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: ([]uint32)(nil),
-	Field:         305,
-	Name:          "goproto.protoc.extension.ext.repeated_x_uint32",
-	Tag:           "varint,305,rep,name=repeated_x_uint32",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { repeated uint32 repeated_x_uint32 = 305; }
+	E_RepeatedXUint32 = &xxx_File_extensions_ext_ext_proto_extDescs[24]
 
-var E_RepeatedXInt64 = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: ([]int64)(nil),
-	Field:         306,
-	Name:          "goproto.protoc.extension.ext.repeated_x_int64",
-	Tag:           "varint,306,rep,name=repeated_x_int64",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { repeated int64 repeated_x_int64 = 306; }
+	E_RepeatedXInt64 = &xxx_File_extensions_ext_ext_proto_extDescs[25]
 
-var E_RepeatedXSint64 = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: ([]int64)(nil),
-	Field:         307,
-	Name:          "goproto.protoc.extension.ext.repeated_x_sint64",
-	Tag:           "zigzag64,307,rep,name=repeated_x_sint64",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { repeated sint64 repeated_x_sint64 = 307; }
+	E_RepeatedXSint64 = &xxx_File_extensions_ext_ext_proto_extDescs[26]
 
-var E_RepeatedXUint64 = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: ([]uint64)(nil),
-	Field:         308,
-	Name:          "goproto.protoc.extension.ext.repeated_x_uint64",
-	Tag:           "varint,308,rep,name=repeated_x_uint64",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { repeated uint64 repeated_x_uint64 = 308; }
+	E_RepeatedXUint64 = &xxx_File_extensions_ext_ext_proto_extDescs[27]
 
-var E_RepeatedXSfixed32 = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: ([]int32)(nil),
-	Field:         309,
-	Name:          "goproto.protoc.extension.ext.repeated_x_sfixed32",
-	Tag:           "fixed32,309,rep,name=repeated_x_sfixed32",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { repeated sfixed32 repeated_x_sfixed32 = 309; }
+	E_RepeatedXSfixed32 = &xxx_File_extensions_ext_ext_proto_extDescs[28]
 
-var E_RepeatedXFixed32 = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: ([]uint32)(nil),
-	Field:         310,
-	Name:          "goproto.protoc.extension.ext.repeated_x_fixed32",
-	Tag:           "fixed32,310,rep,name=repeated_x_fixed32",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { repeated fixed32 repeated_x_fixed32 = 310; }
+	E_RepeatedXFixed32 = &xxx_File_extensions_ext_ext_proto_extDescs[29]
 
-var E_RepeatedXFloat = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: ([]float32)(nil),
-	Field:         311,
-	Name:          "goproto.protoc.extension.ext.repeated_x_float",
-	Tag:           "fixed32,311,rep,name=repeated_x_float",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { repeated float repeated_x_float = 311; }
+	E_RepeatedXFloat = &xxx_File_extensions_ext_ext_proto_extDescs[30]
 
-var E_RepeatedXSfixed64 = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: ([]int64)(nil),
-	Field:         312,
-	Name:          "goproto.protoc.extension.ext.repeated_x_sfixed64",
-	Tag:           "fixed64,312,rep,name=repeated_x_sfixed64",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { repeated sfixed64 repeated_x_sfixed64 = 312; }
+	E_RepeatedXSfixed64 = &xxx_File_extensions_ext_ext_proto_extDescs[31]
 
-var E_RepeatedXFixed64 = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: ([]uint64)(nil),
-	Field:         313,
-	Name:          "goproto.protoc.extension.ext.repeated_x_fixed64",
-	Tag:           "fixed64,313,rep,name=repeated_x_fixed64",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { repeated fixed64 repeated_x_fixed64 = 313; }
+	E_RepeatedXFixed64 = &xxx_File_extensions_ext_ext_proto_extDescs[32]
 
-var E_RepeatedXDouble = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: ([]float64)(nil),
-	Field:         314,
-	Name:          "goproto.protoc.extension.ext.repeated_x_double",
-	Tag:           "fixed64,314,rep,name=repeated_x_double",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { repeated double repeated_x_double = 314; }
+	E_RepeatedXDouble = &xxx_File_extensions_ext_ext_proto_extDescs[33]
 
-var E_RepeatedXString = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: ([]string)(nil),
-	Field:         315,
-	Name:          "goproto.protoc.extension.ext.repeated_x_string",
-	Tag:           "bytes,315,rep,name=repeated_x_string",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { repeated string repeated_x_string = 315; }
+	E_RepeatedXString = &xxx_File_extensions_ext_ext_proto_extDescs[34]
 
-var E_RepeatedXBytes = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: ([][]byte)(nil),
-	Field:         316,
-	Name:          "goproto.protoc.extension.ext.repeated_x_bytes",
-	Tag:           "bytes,316,rep,name=repeated_x_bytes",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { repeated bytes repeated_x_bytes = 316; }
+	E_RepeatedXBytes = &xxx_File_extensions_ext_ext_proto_extDescs[35]
 
-var E_RepeatedX_Message = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: ([]*Message)(nil),
-	Field:         317,
-	Name:          "goproto.protoc.extension.ext.repeated_x_Message",
-	Tag:           "bytes,317,rep,name=repeated_x_Message",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { repeated goproto.protoc.extension.ext.Message repeated_x_Message = 317; }
+	E_RepeatedX_Message = &xxx_File_extensions_ext_ext_proto_extDescs[36]
 
-var E_Repeatedgroup = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: ([]*RepeatedGroup)(nil),
-	Field:         318,
-	Name:          "goproto.protoc.extension.ext.repeatedgroup",
-	Tag:           "group,318,rep,name=RepeatedGroup",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { repeated goproto.protoc.extension.ext.RepeatedGroup repeatedgroup = 318; }
+	E_Repeatedgroup = &xxx_File_extensions_ext_ext_proto_extDescs[37]
 
-var E_ExtendableField = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: (*Extendable)(nil),
-	Field:         400,
-	Name:          "goproto.protoc.extension.ext.extendable_field",
-	Tag:           "bytes,400,opt,name=extendable_field",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { optional goproto.protoc.extension.ext.Extendable extendable_field = 400; }
+	E_ExtendableField = &xxx_File_extensions_ext_ext_proto_extDescs[38]
 
-var E_ExtendableStringField = &proto.ExtensionDesc{
-	ExtendedType:  (*Extendable)(nil),
-	ExtensionType: (*string)(nil),
-	Field:         1,
-	Name:          "goproto.protoc.extension.ext.extendable_string_field",
-	Tag:           "bytes,1,opt,name=extendable_string_field",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.ext.Extendable { optional string extendable_string_field = 1; }
+	E_ExtendableStringField = &xxx_File_extensions_ext_ext_proto_extDescs[39]
 
-var E_MessageSetExtension = &proto.ExtensionDesc{
-	ExtendedType:  (*base.MessageSetWireFormatMessage)(nil),
-	ExtensionType: (*MessageSetWireFormatExtension)(nil),
-	Field:         101,
-	Name:          "goproto.protoc.extension.ext.",
-	Tag:           "bytes,101,opt,name=message_set_extension",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.MessageSetWireFormatMessage { optional goproto.protoc.extension.ext.MessageSetWireFormatExtension message_set_extension = 101; }
+	E_MessageSetExtension = &xxx_File_extensions_ext_ext_proto_extDescs[40]
 
-var E_ExtendingMessage_ExtendingMessageString = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: (*string)(nil),
-	Field:         200,
-	Name:          "goproto.protoc.extension.ext.ExtendingMessage.extending_message_string",
-	Tag:           "bytes,200,opt,name=extending_message_string",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { optional string extending_message_string = 200; }
+	E_ExtendingMessage_ExtendingMessageString = &xxx_File_extensions_ext_ext_proto_extDescs[41]
 
-var E_ExtendingMessage_ExtendingMessageSubmessage = &proto.ExtensionDesc{
-	ExtendedType:  (*base.BaseMessage)(nil),
-	ExtensionType: (*ExtendingMessage_ExtendingMessageSubmessage)(nil),
-	Field:         201,
-	Name:          "goproto.protoc.extension.ext.ExtendingMessage.extending_message_submessage",
-	Tag:           "bytes,201,opt,name=extending_message_submessage",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.BaseMessage { optional goproto.protoc.extension.ext.ExtendingMessage.ExtendingMessageSubmessage extending_message_submessage = 201; }
+	E_ExtendingMessage_ExtendingMessageSubmessage = &xxx_File_extensions_ext_ext_proto_extDescs[42]
 
-var E_MessageSetWireFormatExtension_MessageSetExtension = &proto.ExtensionDesc{
-	ExtendedType:  (*base.MessageSetWireFormatMessage)(nil),
-	ExtensionType: (*MessageSetWireFormatExtension)(nil),
-	Field:         100,
-	Name:          "goproto.protoc.extension.ext.MessageSetWireFormatExtension",
-	Tag:           "bytes,100,opt,name=message_set_extension",
-	Filename:      "extensions/ext/ext.proto",
-}
+	// extend goproto.protoc.extension.base.MessageSetWireFormatMessage { optional goproto.protoc.extension.ext.MessageSetWireFormatExtension message_set_extension = 100; }
+	E_MessageSetWireFormatExtension_MessageSetExtension = &xxx_File_extensions_ext_ext_proto_extDescs[43]
+)
 
 func init() {
 	proto.RegisterFile("extensions/ext/ext.proto", xxx_File_extensions_ext_ext_proto_rawdesc_gzipped)
@@ -1237,6 +1329,7 @@
 		RawDescriptor:        xxx_File_extensions_ext_ext_proto_rawdesc,
 		GoTypes:              xxx_File_extensions_ext_ext_proto_goTypes,
 		DependencyIndexes:    xxx_File_extensions_ext_ext_proto_depIdxs,
+		LegacyExtensions:     xxx_File_extensions_ext_ext_proto_extDescs,
 		EnumOutputTypes:      xxx_File_extensions_ext_ext_proto_enumTypes,
 		MessageOutputTypes:   messageTypes,
 		ExtensionOutputTypes: extensionTypes,
@@ -1246,50 +1339,6 @@
 		xxx_File_extensions_ext_ext_proto_messageTypes[i].GoType = reflect.TypeOf(messageGoTypes[i])
 		xxx_File_extensions_ext_ext_proto_messageTypes[i].PBType = mt
 	}
-	E_ExtensionBool.Type = extensionTypes[0]
-	E_ExtensionEnum.Type = extensionTypes[1]
-	E_ExtensionInt32.Type = extensionTypes[2]
-	E_ExtensionSint32.Type = extensionTypes[3]
-	E_ExtensionUint32.Type = extensionTypes[4]
-	E_ExtensionInt64.Type = extensionTypes[5]
-	E_ExtensionSint64.Type = extensionTypes[6]
-	E_ExtensionUint64.Type = extensionTypes[7]
-	E_ExtensionSfixed32.Type = extensionTypes[8]
-	E_ExtensionFixed32.Type = extensionTypes[9]
-	E_ExtensionFloat.Type = extensionTypes[10]
-	E_ExtensionSfixed64.Type = extensionTypes[11]
-	E_ExtensionFixed64.Type = extensionTypes[12]
-	E_ExtensionDouble.Type = extensionTypes[13]
-	E_ExtensionString.Type = extensionTypes[14]
-	E_ExtensionBytes.Type = extensionTypes[15]
-	E_Extension_Message.Type = extensionTypes[16]
-	E_Extension_MessageM.Type = extensionTypes[17]
-	E_Extensiongroup.Type = extensionTypes[18]
-	E_ExtraMessage.Type = extensionTypes[19]
-	E_RepeatedXBool.Type = extensionTypes[20]
-	E_RepeatedXEnum.Type = extensionTypes[21]
-	E_RepeatedXInt32.Type = extensionTypes[22]
-	E_RepeatedXSint32.Type = extensionTypes[23]
-	E_RepeatedXUint32.Type = extensionTypes[24]
-	E_RepeatedXInt64.Type = extensionTypes[25]
-	E_RepeatedXSint64.Type = extensionTypes[26]
-	E_RepeatedXUint64.Type = extensionTypes[27]
-	E_RepeatedXSfixed32.Type = extensionTypes[28]
-	E_RepeatedXFixed32.Type = extensionTypes[29]
-	E_RepeatedXFloat.Type = extensionTypes[30]
-	E_RepeatedXSfixed64.Type = extensionTypes[31]
-	E_RepeatedXFixed64.Type = extensionTypes[32]
-	E_RepeatedXDouble.Type = extensionTypes[33]
-	E_RepeatedXString.Type = extensionTypes[34]
-	E_RepeatedXBytes.Type = extensionTypes[35]
-	E_RepeatedX_Message.Type = extensionTypes[36]
-	E_Repeatedgroup.Type = extensionTypes[37]
-	E_ExtendableField.Type = extensionTypes[38]
-	E_ExtendableStringField.Type = extensionTypes[39]
-	E_MessageSetExtension.Type = extensionTypes[40]
-	E_ExtendingMessage_ExtendingMessageString.Type = extensionTypes[41]
-	E_ExtendingMessage_ExtendingMessageSubmessage.Type = extensionTypes[42]
-	E_MessageSetWireFormatExtension_MessageSetExtension.Type = extensionTypes[43]
 	xxx_File_extensions_ext_ext_proto_goTypes = nil
 	xxx_File_extensions_ext_ext_proto_depIdxs = 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 b531130..89b2700 100644
--- a/cmd/protoc-gen-go/testdata/extensions/proto3/ext3.pb.go
+++ b/cmd/protoc-gen-go/testdata/extensions/proto3/ext3.pb.go
@@ -81,311 +81,383 @@
 
 var xxx_messageInfo_Message proto.InternalMessageInfo
 
-var E_ExtensionBool = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: (*bool)(nil),
-	Field:         1001,
-	Name:          "goproto.protoc.extension.proto3.extension_bool",
-	Tag:           "varint,1001,opt,name=extension_bool",
-	Filename:      "extensions/proto3/ext3.proto",
+var xxx_File_extensions_proto3_ext3_proto_extDescs = []proto.ExtensionDesc{
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: (*bool)(nil),
+		Field:         1001,
+		Name:          "goproto.protoc.extension.proto3.extension_bool",
+		Tag:           "varint,1001,opt,name=extension_bool",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: (*Enum)(nil),
+		Field:         1002,
+		Name:          "goproto.protoc.extension.proto3.extension_enum",
+		Tag:           "varint,1002,opt,name=extension_enum,enum=goproto.protoc.extension.proto3.Enum",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: (*int32)(nil),
+		Field:         1003,
+		Name:          "goproto.protoc.extension.proto3.extension_int32",
+		Tag:           "varint,1003,opt,name=extension_int32",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: (*int32)(nil),
+		Field:         1004,
+		Name:          "goproto.protoc.extension.proto3.extension_sint32",
+		Tag:           "zigzag32,1004,opt,name=extension_sint32",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: (*uint32)(nil),
+		Field:         1005,
+		Name:          "goproto.protoc.extension.proto3.extension_uint32",
+		Tag:           "varint,1005,opt,name=extension_uint32",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: (*int64)(nil),
+		Field:         1006,
+		Name:          "goproto.protoc.extension.proto3.extension_int64",
+		Tag:           "varint,1006,opt,name=extension_int64",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: (*int64)(nil),
+		Field:         1007,
+		Name:          "goproto.protoc.extension.proto3.extension_sint64",
+		Tag:           "zigzag64,1007,opt,name=extension_sint64",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: (*uint64)(nil),
+		Field:         1008,
+		Name:          "goproto.protoc.extension.proto3.extension_uint64",
+		Tag:           "varint,1008,opt,name=extension_uint64",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: (*int32)(nil),
+		Field:         1009,
+		Name:          "goproto.protoc.extension.proto3.extension_sfixed32",
+		Tag:           "fixed32,1009,opt,name=extension_sfixed32",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: (*uint32)(nil),
+		Field:         1010,
+		Name:          "goproto.protoc.extension.proto3.extension_fixed32",
+		Tag:           "fixed32,1010,opt,name=extension_fixed32",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: (*float32)(nil),
+		Field:         1011,
+		Name:          "goproto.protoc.extension.proto3.extension_float",
+		Tag:           "fixed32,1011,opt,name=extension_float",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: (*int64)(nil),
+		Field:         1012,
+		Name:          "goproto.protoc.extension.proto3.extension_sfixed64",
+		Tag:           "fixed64,1012,opt,name=extension_sfixed64",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: (*uint64)(nil),
+		Field:         1013,
+		Name:          "goproto.protoc.extension.proto3.extension_fixed64",
+		Tag:           "fixed64,1013,opt,name=extension_fixed64",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: (*float64)(nil),
+		Field:         1014,
+		Name:          "goproto.protoc.extension.proto3.extension_double",
+		Tag:           "fixed64,1014,opt,name=extension_double",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: (*string)(nil),
+		Field:         1015,
+		Name:          "goproto.protoc.extension.proto3.extension_string",
+		Tag:           "bytes,1015,opt,name=extension_string",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: ([]byte)(nil),
+		Field:         1016,
+		Name:          "goproto.protoc.extension.proto3.extension_bytes",
+		Tag:           "bytes,1016,opt,name=extension_bytes",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: (*Message)(nil),
+		Field:         1017,
+		Name:          "goproto.protoc.extension.proto3.extension_Message",
+		Tag:           "bytes,1017,opt,name=extension_Message",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: ([]bool)(nil),
+		Field:         2001,
+		Name:          "goproto.protoc.extension.proto3.repeated_extension_bool",
+		Tag:           "varint,2001,rep,name=repeated_extension_bool",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: ([]Enum)(nil),
+		Field:         2002,
+		Name:          "goproto.protoc.extension.proto3.repeated_extension_enum",
+		Tag:           "varint,2002,rep,name=repeated_extension_enum,enum=goproto.protoc.extension.proto3.Enum",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: ([]int32)(nil),
+		Field:         2003,
+		Name:          "goproto.protoc.extension.proto3.repeated_extension_int32",
+		Tag:           "varint,2003,rep,name=repeated_extension_int32",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: ([]int32)(nil),
+		Field:         2004,
+		Name:          "goproto.protoc.extension.proto3.repeated_extension_sint32",
+		Tag:           "zigzag32,2004,rep,name=repeated_extension_sint32",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: ([]uint32)(nil),
+		Field:         2005,
+		Name:          "goproto.protoc.extension.proto3.repeated_extension_uint32",
+		Tag:           "varint,2005,rep,name=repeated_extension_uint32",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: ([]int64)(nil),
+		Field:         2006,
+		Name:          "goproto.protoc.extension.proto3.repeated_extension_int64",
+		Tag:           "varint,2006,rep,name=repeated_extension_int64",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: ([]int64)(nil),
+		Field:         2007,
+		Name:          "goproto.protoc.extension.proto3.repeated_extension_sint64",
+		Tag:           "zigzag64,2007,rep,name=repeated_extension_sint64",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: ([]uint64)(nil),
+		Field:         2008,
+		Name:          "goproto.protoc.extension.proto3.repeated_extension_uint64",
+		Tag:           "varint,2008,rep,name=repeated_extension_uint64",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: ([]int32)(nil),
+		Field:         2009,
+		Name:          "goproto.protoc.extension.proto3.repeated_extension_sfixed32",
+		Tag:           "fixed32,2009,rep,name=repeated_extension_sfixed32",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: ([]uint32)(nil),
+		Field:         2010,
+		Name:          "goproto.protoc.extension.proto3.repeated_extension_fixed32",
+		Tag:           "fixed32,2010,rep,name=repeated_extension_fixed32",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: ([]float32)(nil),
+		Field:         2011,
+		Name:          "goproto.protoc.extension.proto3.repeated_extension_float",
+		Tag:           "fixed32,2011,rep,name=repeated_extension_float",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: ([]int64)(nil),
+		Field:         2012,
+		Name:          "goproto.protoc.extension.proto3.repeated_extension_sfixed64",
+		Tag:           "fixed64,2012,rep,name=repeated_extension_sfixed64",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: ([]uint64)(nil),
+		Field:         2013,
+		Name:          "goproto.protoc.extension.proto3.repeated_extension_fixed64",
+		Tag:           "fixed64,2013,rep,name=repeated_extension_fixed64",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: ([]float64)(nil),
+		Field:         2014,
+		Name:          "goproto.protoc.extension.proto3.repeated_extension_double",
+		Tag:           "fixed64,2014,rep,name=repeated_extension_double",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: ([]string)(nil),
+		Field:         2015,
+		Name:          "goproto.protoc.extension.proto3.repeated_extension_string",
+		Tag:           "bytes,2015,rep,name=repeated_extension_string",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: ([][]byte)(nil),
+		Field:         2016,
+		Name:          "goproto.protoc.extension.proto3.repeated_extension_bytes",
+		Tag:           "bytes,2016,rep,name=repeated_extension_bytes",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
+	{
+		ExtendedType:  (*descriptor.MessageOptions)(nil),
+		ExtensionType: ([]*Message)(nil),
+		Field:         2017,
+		Name:          "goproto.protoc.extension.proto3.repeated_extension_Message",
+		Tag:           "bytes,2017,rep,name=repeated_extension_Message",
+		Filename:      "extensions/proto3/ext3.proto",
+	},
 }
+var (
+	// extend google.protobuf.MessageOptions { optional bool extension_bool = 1001; }
+	E_ExtensionBool = &xxx_File_extensions_proto3_ext3_proto_extDescs[0]
 
-var E_ExtensionEnum = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: (*Enum)(nil),
-	Field:         1002,
-	Name:          "goproto.protoc.extension.proto3.extension_enum",
-	Tag:           "varint,1002,opt,name=extension_enum,enum=goproto.protoc.extension.proto3.Enum",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { optional goproto.protoc.extension.proto3.Enum extension_enum = 1002; }
+	E_ExtensionEnum = &xxx_File_extensions_proto3_ext3_proto_extDescs[1]
 
-var E_ExtensionInt32 = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: (*int32)(nil),
-	Field:         1003,
-	Name:          "goproto.protoc.extension.proto3.extension_int32",
-	Tag:           "varint,1003,opt,name=extension_int32",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { optional int32 extension_int32 = 1003; }
+	E_ExtensionInt32 = &xxx_File_extensions_proto3_ext3_proto_extDescs[2]
 
-var E_ExtensionSint32 = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: (*int32)(nil),
-	Field:         1004,
-	Name:          "goproto.protoc.extension.proto3.extension_sint32",
-	Tag:           "zigzag32,1004,opt,name=extension_sint32",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { optional sint32 extension_sint32 = 1004; }
+	E_ExtensionSint32 = &xxx_File_extensions_proto3_ext3_proto_extDescs[3]
 
-var E_ExtensionUint32 = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: (*uint32)(nil),
-	Field:         1005,
-	Name:          "goproto.protoc.extension.proto3.extension_uint32",
-	Tag:           "varint,1005,opt,name=extension_uint32",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { optional uint32 extension_uint32 = 1005; }
+	E_ExtensionUint32 = &xxx_File_extensions_proto3_ext3_proto_extDescs[4]
 
-var E_ExtensionInt64 = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: (*int64)(nil),
-	Field:         1006,
-	Name:          "goproto.protoc.extension.proto3.extension_int64",
-	Tag:           "varint,1006,opt,name=extension_int64",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { optional int64 extension_int64 = 1006; }
+	E_ExtensionInt64 = &xxx_File_extensions_proto3_ext3_proto_extDescs[5]
 
-var E_ExtensionSint64 = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: (*int64)(nil),
-	Field:         1007,
-	Name:          "goproto.protoc.extension.proto3.extension_sint64",
-	Tag:           "zigzag64,1007,opt,name=extension_sint64",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { optional sint64 extension_sint64 = 1007; }
+	E_ExtensionSint64 = &xxx_File_extensions_proto3_ext3_proto_extDescs[6]
 
-var E_ExtensionUint64 = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: (*uint64)(nil),
-	Field:         1008,
-	Name:          "goproto.protoc.extension.proto3.extension_uint64",
-	Tag:           "varint,1008,opt,name=extension_uint64",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { optional uint64 extension_uint64 = 1008; }
+	E_ExtensionUint64 = &xxx_File_extensions_proto3_ext3_proto_extDescs[7]
 
-var E_ExtensionSfixed32 = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: (*int32)(nil),
-	Field:         1009,
-	Name:          "goproto.protoc.extension.proto3.extension_sfixed32",
-	Tag:           "fixed32,1009,opt,name=extension_sfixed32",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { optional sfixed32 extension_sfixed32 = 1009; }
+	E_ExtensionSfixed32 = &xxx_File_extensions_proto3_ext3_proto_extDescs[8]
 
-var E_ExtensionFixed32 = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: (*uint32)(nil),
-	Field:         1010,
-	Name:          "goproto.protoc.extension.proto3.extension_fixed32",
-	Tag:           "fixed32,1010,opt,name=extension_fixed32",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { optional fixed32 extension_fixed32 = 1010; }
+	E_ExtensionFixed32 = &xxx_File_extensions_proto3_ext3_proto_extDescs[9]
 
-var E_ExtensionFloat = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: (*float32)(nil),
-	Field:         1011,
-	Name:          "goproto.protoc.extension.proto3.extension_float",
-	Tag:           "fixed32,1011,opt,name=extension_float",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { optional float extension_float = 1011; }
+	E_ExtensionFloat = &xxx_File_extensions_proto3_ext3_proto_extDescs[10]
 
-var E_ExtensionSfixed64 = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: (*int64)(nil),
-	Field:         1012,
-	Name:          "goproto.protoc.extension.proto3.extension_sfixed64",
-	Tag:           "fixed64,1012,opt,name=extension_sfixed64",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { optional sfixed64 extension_sfixed64 = 1012; }
+	E_ExtensionSfixed64 = &xxx_File_extensions_proto3_ext3_proto_extDescs[11]
 
-var E_ExtensionFixed64 = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: (*uint64)(nil),
-	Field:         1013,
-	Name:          "goproto.protoc.extension.proto3.extension_fixed64",
-	Tag:           "fixed64,1013,opt,name=extension_fixed64",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { optional fixed64 extension_fixed64 = 1013; }
+	E_ExtensionFixed64 = &xxx_File_extensions_proto3_ext3_proto_extDescs[12]
 
-var E_ExtensionDouble = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: (*float64)(nil),
-	Field:         1014,
-	Name:          "goproto.protoc.extension.proto3.extension_double",
-	Tag:           "fixed64,1014,opt,name=extension_double",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { optional double extension_double = 1014; }
+	E_ExtensionDouble = &xxx_File_extensions_proto3_ext3_proto_extDescs[13]
 
-var E_ExtensionString = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: (*string)(nil),
-	Field:         1015,
-	Name:          "goproto.protoc.extension.proto3.extension_string",
-	Tag:           "bytes,1015,opt,name=extension_string",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { optional string extension_string = 1015; }
+	E_ExtensionString = &xxx_File_extensions_proto3_ext3_proto_extDescs[14]
 
-var E_ExtensionBytes = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: ([]byte)(nil),
-	Field:         1016,
-	Name:          "goproto.protoc.extension.proto3.extension_bytes",
-	Tag:           "bytes,1016,opt,name=extension_bytes",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { optional bytes extension_bytes = 1016; }
+	E_ExtensionBytes = &xxx_File_extensions_proto3_ext3_proto_extDescs[15]
 
-var E_Extension_Message = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: (*Message)(nil),
-	Field:         1017,
-	Name:          "goproto.protoc.extension.proto3.extension_Message",
-	Tag:           "bytes,1017,opt,name=extension_Message",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { optional goproto.protoc.extension.proto3.Message extension_Message = 1017; }
+	E_Extension_Message = &xxx_File_extensions_proto3_ext3_proto_extDescs[16]
 
-var E_RepeatedExtensionBool = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: ([]bool)(nil),
-	Field:         2001,
-	Name:          "goproto.protoc.extension.proto3.repeated_extension_bool",
-	Tag:           "varint,2001,rep,name=repeated_extension_bool",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { repeated bool repeated_extension_bool = 2001; }
+	E_RepeatedExtensionBool = &xxx_File_extensions_proto3_ext3_proto_extDescs[17]
 
-var E_RepeatedExtensionEnum = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: ([]Enum)(nil),
-	Field:         2002,
-	Name:          "goproto.protoc.extension.proto3.repeated_extension_enum",
-	Tag:           "varint,2002,rep,name=repeated_extension_enum,enum=goproto.protoc.extension.proto3.Enum",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { repeated goproto.protoc.extension.proto3.Enum repeated_extension_enum = 2002; }
+	E_RepeatedExtensionEnum = &xxx_File_extensions_proto3_ext3_proto_extDescs[18]
 
-var E_RepeatedExtensionInt32 = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: ([]int32)(nil),
-	Field:         2003,
-	Name:          "goproto.protoc.extension.proto3.repeated_extension_int32",
-	Tag:           "varint,2003,rep,name=repeated_extension_int32",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { repeated int32 repeated_extension_int32 = 2003; }
+	E_RepeatedExtensionInt32 = &xxx_File_extensions_proto3_ext3_proto_extDescs[19]
 
-var E_RepeatedExtensionSint32 = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: ([]int32)(nil),
-	Field:         2004,
-	Name:          "goproto.protoc.extension.proto3.repeated_extension_sint32",
-	Tag:           "zigzag32,2004,rep,name=repeated_extension_sint32",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { repeated sint32 repeated_extension_sint32 = 2004; }
+	E_RepeatedExtensionSint32 = &xxx_File_extensions_proto3_ext3_proto_extDescs[20]
 
-var E_RepeatedExtensionUint32 = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: ([]uint32)(nil),
-	Field:         2005,
-	Name:          "goproto.protoc.extension.proto3.repeated_extension_uint32",
-	Tag:           "varint,2005,rep,name=repeated_extension_uint32",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { repeated uint32 repeated_extension_uint32 = 2005; }
+	E_RepeatedExtensionUint32 = &xxx_File_extensions_proto3_ext3_proto_extDescs[21]
 
-var E_RepeatedExtensionInt64 = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: ([]int64)(nil),
-	Field:         2006,
-	Name:          "goproto.protoc.extension.proto3.repeated_extension_int64",
-	Tag:           "varint,2006,rep,name=repeated_extension_int64",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { repeated int64 repeated_extension_int64 = 2006; }
+	E_RepeatedExtensionInt64 = &xxx_File_extensions_proto3_ext3_proto_extDescs[22]
 
-var E_RepeatedExtensionSint64 = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: ([]int64)(nil),
-	Field:         2007,
-	Name:          "goproto.protoc.extension.proto3.repeated_extension_sint64",
-	Tag:           "zigzag64,2007,rep,name=repeated_extension_sint64",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { repeated sint64 repeated_extension_sint64 = 2007; }
+	E_RepeatedExtensionSint64 = &xxx_File_extensions_proto3_ext3_proto_extDescs[23]
 
-var E_RepeatedExtensionUint64 = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: ([]uint64)(nil),
-	Field:         2008,
-	Name:          "goproto.protoc.extension.proto3.repeated_extension_uint64",
-	Tag:           "varint,2008,rep,name=repeated_extension_uint64",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { repeated uint64 repeated_extension_uint64 = 2008; }
+	E_RepeatedExtensionUint64 = &xxx_File_extensions_proto3_ext3_proto_extDescs[24]
 
-var E_RepeatedExtensionSfixed32 = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: ([]int32)(nil),
-	Field:         2009,
-	Name:          "goproto.protoc.extension.proto3.repeated_extension_sfixed32",
-	Tag:           "fixed32,2009,rep,name=repeated_extension_sfixed32",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { repeated sfixed32 repeated_extension_sfixed32 = 2009; }
+	E_RepeatedExtensionSfixed32 = &xxx_File_extensions_proto3_ext3_proto_extDescs[25]
 
-var E_RepeatedExtensionFixed32 = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: ([]uint32)(nil),
-	Field:         2010,
-	Name:          "goproto.protoc.extension.proto3.repeated_extension_fixed32",
-	Tag:           "fixed32,2010,rep,name=repeated_extension_fixed32",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { repeated fixed32 repeated_extension_fixed32 = 2010; }
+	E_RepeatedExtensionFixed32 = &xxx_File_extensions_proto3_ext3_proto_extDescs[26]
 
-var E_RepeatedExtensionFloat = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: ([]float32)(nil),
-	Field:         2011,
-	Name:          "goproto.protoc.extension.proto3.repeated_extension_float",
-	Tag:           "fixed32,2011,rep,name=repeated_extension_float",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { repeated float repeated_extension_float = 2011; }
+	E_RepeatedExtensionFloat = &xxx_File_extensions_proto3_ext3_proto_extDescs[27]
 
-var E_RepeatedExtensionSfixed64 = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: ([]int64)(nil),
-	Field:         2012,
-	Name:          "goproto.protoc.extension.proto3.repeated_extension_sfixed64",
-	Tag:           "fixed64,2012,rep,name=repeated_extension_sfixed64",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { repeated sfixed64 repeated_extension_sfixed64 = 2012; }
+	E_RepeatedExtensionSfixed64 = &xxx_File_extensions_proto3_ext3_proto_extDescs[28]
 
-var E_RepeatedExtensionFixed64 = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: ([]uint64)(nil),
-	Field:         2013,
-	Name:          "goproto.protoc.extension.proto3.repeated_extension_fixed64",
-	Tag:           "fixed64,2013,rep,name=repeated_extension_fixed64",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { repeated fixed64 repeated_extension_fixed64 = 2013; }
+	E_RepeatedExtensionFixed64 = &xxx_File_extensions_proto3_ext3_proto_extDescs[29]
 
-var E_RepeatedExtensionDouble = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: ([]float64)(nil),
-	Field:         2014,
-	Name:          "goproto.protoc.extension.proto3.repeated_extension_double",
-	Tag:           "fixed64,2014,rep,name=repeated_extension_double",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { repeated double repeated_extension_double = 2014; }
+	E_RepeatedExtensionDouble = &xxx_File_extensions_proto3_ext3_proto_extDescs[30]
 
-var E_RepeatedExtensionString = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: ([]string)(nil),
-	Field:         2015,
-	Name:          "goproto.protoc.extension.proto3.repeated_extension_string",
-	Tag:           "bytes,2015,rep,name=repeated_extension_string",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { repeated string repeated_extension_string = 2015; }
+	E_RepeatedExtensionString = &xxx_File_extensions_proto3_ext3_proto_extDescs[31]
 
-var E_RepeatedExtensionBytes = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: ([][]byte)(nil),
-	Field:         2016,
-	Name:          "goproto.protoc.extension.proto3.repeated_extension_bytes",
-	Tag:           "bytes,2016,rep,name=repeated_extension_bytes",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { repeated bytes repeated_extension_bytes = 2016; }
+	E_RepeatedExtensionBytes = &xxx_File_extensions_proto3_ext3_proto_extDescs[32]
 
-var E_RepeatedExtension_Message = &proto.ExtensionDesc{
-	ExtendedType:  (*descriptor.MessageOptions)(nil),
-	ExtensionType: ([]*Message)(nil),
-	Field:         2017,
-	Name:          "goproto.protoc.extension.proto3.repeated_extension_Message",
-	Tag:           "bytes,2017,rep,name=repeated_extension_Message",
-	Filename:      "extensions/proto3/ext3.proto",
-}
+	// extend google.protobuf.MessageOptions { repeated goproto.protoc.extension.proto3.Message repeated_extension_Message = 2017; }
+	E_RepeatedExtension_Message = &xxx_File_extensions_proto3_ext3_proto_extDescs[33]
+)
 
 func init() {
 	proto.RegisterFile("extensions/proto3/ext3.proto", xxx_File_extensions_proto3_ext3_proto_rawdesc_gzipped)
@@ -701,6 +773,7 @@
 		RawDescriptor:        xxx_File_extensions_proto3_ext3_proto_rawdesc,
 		GoTypes:              xxx_File_extensions_proto3_ext3_proto_goTypes,
 		DependencyIndexes:    xxx_File_extensions_proto3_ext3_proto_depIdxs,
+		LegacyExtensions:     xxx_File_extensions_proto3_ext3_proto_extDescs,
 		EnumOutputTypes:      xxx_File_extensions_proto3_ext3_proto_enumTypes,
 		MessageOutputTypes:   messageTypes,
 		ExtensionOutputTypes: extensionTypes,
@@ -710,40 +783,6 @@
 		xxx_File_extensions_proto3_ext3_proto_messageTypes[i].GoType = reflect.TypeOf(messageGoTypes[i])
 		xxx_File_extensions_proto3_ext3_proto_messageTypes[i].PBType = mt
 	}
-	E_ExtensionBool.Type = extensionTypes[0]
-	E_ExtensionEnum.Type = extensionTypes[1]
-	E_ExtensionInt32.Type = extensionTypes[2]
-	E_ExtensionSint32.Type = extensionTypes[3]
-	E_ExtensionUint32.Type = extensionTypes[4]
-	E_ExtensionInt64.Type = extensionTypes[5]
-	E_ExtensionSint64.Type = extensionTypes[6]
-	E_ExtensionUint64.Type = extensionTypes[7]
-	E_ExtensionSfixed32.Type = extensionTypes[8]
-	E_ExtensionFixed32.Type = extensionTypes[9]
-	E_ExtensionFloat.Type = extensionTypes[10]
-	E_ExtensionSfixed64.Type = extensionTypes[11]
-	E_ExtensionFixed64.Type = extensionTypes[12]
-	E_ExtensionDouble.Type = extensionTypes[13]
-	E_ExtensionString.Type = extensionTypes[14]
-	E_ExtensionBytes.Type = extensionTypes[15]
-	E_Extension_Message.Type = extensionTypes[16]
-	E_RepeatedExtensionBool.Type = extensionTypes[17]
-	E_RepeatedExtensionEnum.Type = extensionTypes[18]
-	E_RepeatedExtensionInt32.Type = extensionTypes[19]
-	E_RepeatedExtensionSint32.Type = extensionTypes[20]
-	E_RepeatedExtensionUint32.Type = extensionTypes[21]
-	E_RepeatedExtensionInt64.Type = extensionTypes[22]
-	E_RepeatedExtensionSint64.Type = extensionTypes[23]
-	E_RepeatedExtensionUint64.Type = extensionTypes[24]
-	E_RepeatedExtensionSfixed32.Type = extensionTypes[25]
-	E_RepeatedExtensionFixed32.Type = extensionTypes[26]
-	E_RepeatedExtensionFloat.Type = extensionTypes[27]
-	E_RepeatedExtensionSfixed64.Type = extensionTypes[28]
-	E_RepeatedExtensionFixed64.Type = extensionTypes[29]
-	E_RepeatedExtensionDouble.Type = extensionTypes[30]
-	E_RepeatedExtensionString.Type = extensionTypes[31]
-	E_RepeatedExtensionBytes.Type = extensionTypes[32]
-	E_RepeatedExtension_Message.Type = extensionTypes[33]
 	xxx_File_extensions_proto3_ext3_proto_goTypes = nil
 	xxx_File_extensions_proto3_ext3_proto_depIdxs = nil
 }
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 6e24921..b486899 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
@@ -368,14 +368,20 @@
 	}
 }
 
-var E_ExtensionField = &proto.ExtensionDesc{
-	ExtendedType:  (*M)(nil),
-	ExtensionType: (*string)(nil),
-	Field:         100,
-	Name:          "goproto.protoc.import_public.sub.extension_field",
-	Tag:           "bytes,100,opt,name=extension_field",
-	Filename:      "import_public/sub/a.proto",
+var xxx_File_import_public_sub_a_proto_extDescs = []proto.ExtensionDesc{
+	{
+		ExtendedType:  (*M)(nil),
+		ExtensionType: (*string)(nil),
+		Field:         100,
+		Name:          "goproto.protoc.import_public.sub.extension_field",
+		Tag:           "bytes,100,opt,name=extension_field",
+		Filename:      "import_public/sub/a.proto",
+	},
 }
+var (
+	// extend goproto.protoc.import_public.sub.M { optional string extension_field = 100; }
+	E_ExtensionField = &xxx_File_import_public_sub_a_proto_extDescs[0]
+)
 
 func init() {
 	proto.RegisterFile("import_public/sub/a.proto", xxx_File_import_public_sub_a_proto_rawdesc_gzipped)
@@ -470,6 +476,7 @@
 		RawDescriptor:        xxx_File_import_public_sub_a_proto_rawdesc,
 		GoTypes:              xxx_File_import_public_sub_a_proto_goTypes,
 		DependencyIndexes:    xxx_File_import_public_sub_a_proto_depIdxs,
+		LegacyExtensions:     xxx_File_import_public_sub_a_proto_extDescs,
 		EnumOutputTypes:      xxx_File_import_public_sub_a_proto_enumTypes,
 		MessageOutputTypes:   messageTypes,
 		ExtensionOutputTypes: extensionTypes,
@@ -479,7 +486,6 @@
 		xxx_File_import_public_sub_a_proto_messageTypes[i].GoType = reflect.TypeOf(messageGoTypes[i])
 		xxx_File_import_public_sub_a_proto_messageTypes[i].PBType = mt
 	}
-	E_ExtensionField.Type = extensionTypes[0]
 	xxx_File_import_public_sub_a_proto_goTypes = nil
 	xxx_File_import_public_sub_a_proto_depIdxs = nil
 }
diff --git a/encoding/testprotos/pb2/test.pb.go b/encoding/testprotos/pb2/test.pb.go
index 68dc422..5b02880 100644
--- a/encoding/testprotos/pb2/test.pb.go
+++ b/encoding/testprotos/pb2/test.pb.go
@@ -1409,176 +1409,218 @@
 	return 0
 }
 
-var E_OptExtBool = &proto.ExtensionDesc{
-	ExtendedType:  (*Extensions)(nil),
-	ExtensionType: (*bool)(nil),
-	Field:         21,
-	Name:          "pb2.opt_ext_bool",
-	Tag:           "varint,21,opt,name=opt_ext_bool",
-	Filename:      "pb2/test.proto",
+var xxx_File_pb2_test_proto_extDescs = []proto.ExtensionDesc{
+	{
+		ExtendedType:  (*Extensions)(nil),
+		ExtensionType: (*bool)(nil),
+		Field:         21,
+		Name:          "pb2.opt_ext_bool",
+		Tag:           "varint,21,opt,name=opt_ext_bool",
+		Filename:      "pb2/test.proto",
+	},
+	{
+		ExtendedType:  (*Extensions)(nil),
+		ExtensionType: (*string)(nil),
+		Field:         22,
+		Name:          "pb2.opt_ext_string",
+		Tag:           "bytes,22,opt,name=opt_ext_string",
+		Filename:      "pb2/test.proto",
+	},
+	{
+		ExtendedType:  (*Extensions)(nil),
+		ExtensionType: (*Enum)(nil),
+		Field:         23,
+		Name:          "pb2.opt_ext_enum",
+		Tag:           "varint,23,opt,name=opt_ext_enum,enum=pb2.Enum",
+		Filename:      "pb2/test.proto",
+	},
+	{
+		ExtendedType:  (*Extensions)(nil),
+		ExtensionType: (*Nested)(nil),
+		Field:         24,
+		Name:          "pb2.opt_ext_nested",
+		Tag:           "bytes,24,opt,name=opt_ext_nested",
+		Filename:      "pb2/test.proto",
+	},
+	{
+		ExtendedType:  (*Extensions)(nil),
+		ExtensionType: ([]uint32)(nil),
+		Field:         31,
+		Name:          "pb2.rpt_ext_fixed32",
+		Tag:           "fixed32,31,rep,name=rpt_ext_fixed32",
+		Filename:      "pb2/test.proto",
+	},
+	{
+		ExtendedType:  (*Extensions)(nil),
+		ExtensionType: ([]Enum)(nil),
+		Field:         32,
+		Name:          "pb2.rpt_ext_enum",
+		Tag:           "varint,32,rep,name=rpt_ext_enum,enum=pb2.Enum",
+		Filename:      "pb2/test.proto",
+	},
+	{
+		ExtendedType:  (*Extensions)(nil),
+		ExtensionType: ([]*Nested)(nil),
+		Field:         33,
+		Name:          "pb2.rpt_ext_nested",
+		Tag:           "bytes,33,rep,name=rpt_ext_nested",
+		Filename:      "pb2/test.proto",
+	},
+	{
+		ExtendedType:  (*MessageSet)(nil),
+		ExtensionType: (*FakeMessageSetExtension)(nil),
+		Field:         50,
+		Name:          "pb2.",
+		Tag:           "bytes,50,opt,name=message_set_extension",
+		Filename:      "pb2/test.proto",
+	},
+	{
+		ExtendedType:  (*Extensions)(nil),
+		ExtensionType: (*bool)(nil),
+		Field:         51,
+		Name:          "pb2.ExtensionsContainer.opt_ext_bool",
+		Tag:           "varint,51,opt,name=opt_ext_bool",
+		Filename:      "pb2/test.proto",
+	},
+	{
+		ExtendedType:  (*Extensions)(nil),
+		ExtensionType: (*string)(nil),
+		Field:         52,
+		Name:          "pb2.ExtensionsContainer.opt_ext_string",
+		Tag:           "bytes,52,opt,name=opt_ext_string",
+		Filename:      "pb2/test.proto",
+	},
+	{
+		ExtendedType:  (*Extensions)(nil),
+		ExtensionType: (*Enum)(nil),
+		Field:         53,
+		Name:          "pb2.ExtensionsContainer.opt_ext_enum",
+		Tag:           "varint,53,opt,name=opt_ext_enum,enum=pb2.Enum",
+		Filename:      "pb2/test.proto",
+	},
+	{
+		ExtendedType:  (*Extensions)(nil),
+		ExtensionType: (*Nested)(nil),
+		Field:         54,
+		Name:          "pb2.ExtensionsContainer.opt_ext_nested",
+		Tag:           "bytes,54,opt,name=opt_ext_nested",
+		Filename:      "pb2/test.proto",
+	},
+	{
+		ExtendedType:  (*Extensions)(nil),
+		ExtensionType: ([]string)(nil),
+		Field:         61,
+		Name:          "pb2.ExtensionsContainer.rpt_ext_string",
+		Tag:           "bytes,61,rep,name=rpt_ext_string",
+		Filename:      "pb2/test.proto",
+	},
+	{
+		ExtendedType:  (*Extensions)(nil),
+		ExtensionType: ([]Enum)(nil),
+		Field:         62,
+		Name:          "pb2.ExtensionsContainer.rpt_ext_enum",
+		Tag:           "varint,62,rep,name=rpt_ext_enum,enum=pb2.Enum",
+		Filename:      "pb2/test.proto",
+	},
+	{
+		ExtendedType:  (*Extensions)(nil),
+		ExtensionType: ([]*Nested)(nil),
+		Field:         63,
+		Name:          "pb2.ExtensionsContainer.rpt_ext_nested",
+		Tag:           "bytes,63,rep,name=rpt_ext_nested",
+		Filename:      "pb2/test.proto",
+	},
+	{
+		ExtendedType:  (*MessageSet)(nil),
+		ExtensionType: (*MessageSetExtension)(nil),
+		Field:         10,
+		Name:          "pb2.MessageSetExtension",
+		Tag:           "bytes,10,opt,name=message_set_extension",
+		Filename:      "pb2/test.proto",
+	},
+	{
+		ExtendedType:  (*MessageSet)(nil),
+		ExtensionType: (*MessageSetExtension)(nil),
+		Field:         20,
+		Name:          "pb2.MessageSetExtension.not_message_set_extension",
+		Tag:           "bytes,20,opt,name=not_message_set_extension",
+		Filename:      "pb2/test.proto",
+	},
+	{
+		ExtendedType:  (*MessageSet)(nil),
+		ExtensionType: (*Nested)(nil),
+		Field:         30,
+		Name:          "pb2.MessageSetExtension.ext_nested",
+		Tag:           "bytes,30,opt,name=ext_nested",
+		Filename:      "pb2/test.proto",
+	},
+	{
+		ExtendedType:  (*FakeMessageSet)(nil),
+		ExtensionType: (*FakeMessageSetExtension)(nil),
+		Field:         10,
+		Name:          "pb2.FakeMessageSetExtension.message_set_extension",
+		Tag:           "bytes,10,opt,name=message_set_extension",
+		Filename:      "pb2/test.proto",
+	},
 }
+var (
+	// extend pb2.Extensions { optional bool opt_ext_bool = 21; }
+	E_OptExtBool = &xxx_File_pb2_test_proto_extDescs[0]
 
-var E_OptExtString = &proto.ExtensionDesc{
-	ExtendedType:  (*Extensions)(nil),
-	ExtensionType: (*string)(nil),
-	Field:         22,
-	Name:          "pb2.opt_ext_string",
-	Tag:           "bytes,22,opt,name=opt_ext_string",
-	Filename:      "pb2/test.proto",
-}
+	// extend pb2.Extensions { optional string opt_ext_string = 22; }
+	E_OptExtString = &xxx_File_pb2_test_proto_extDescs[1]
 
-var E_OptExtEnum = &proto.ExtensionDesc{
-	ExtendedType:  (*Extensions)(nil),
-	ExtensionType: (*Enum)(nil),
-	Field:         23,
-	Name:          "pb2.opt_ext_enum",
-	Tag:           "varint,23,opt,name=opt_ext_enum,enum=pb2.Enum",
-	Filename:      "pb2/test.proto",
-}
+	// extend pb2.Extensions { optional pb2.Enum opt_ext_enum = 23; }
+	E_OptExtEnum = &xxx_File_pb2_test_proto_extDescs[2]
 
-var E_OptExtNested = &proto.ExtensionDesc{
-	ExtendedType:  (*Extensions)(nil),
-	ExtensionType: (*Nested)(nil),
-	Field:         24,
-	Name:          "pb2.opt_ext_nested",
-	Tag:           "bytes,24,opt,name=opt_ext_nested",
-	Filename:      "pb2/test.proto",
-}
+	// extend pb2.Extensions { optional pb2.Nested opt_ext_nested = 24; }
+	E_OptExtNested = &xxx_File_pb2_test_proto_extDescs[3]
 
-var E_RptExtFixed32 = &proto.ExtensionDesc{
-	ExtendedType:  (*Extensions)(nil),
-	ExtensionType: ([]uint32)(nil),
-	Field:         31,
-	Name:          "pb2.rpt_ext_fixed32",
-	Tag:           "fixed32,31,rep,name=rpt_ext_fixed32",
-	Filename:      "pb2/test.proto",
-}
+	// extend pb2.Extensions { repeated fixed32 rpt_ext_fixed32 = 31; }
+	E_RptExtFixed32 = &xxx_File_pb2_test_proto_extDescs[4]
 
-var E_RptExtEnum = &proto.ExtensionDesc{
-	ExtendedType:  (*Extensions)(nil),
-	ExtensionType: ([]Enum)(nil),
-	Field:         32,
-	Name:          "pb2.rpt_ext_enum",
-	Tag:           "varint,32,rep,name=rpt_ext_enum,enum=pb2.Enum",
-	Filename:      "pb2/test.proto",
-}
+	// extend pb2.Extensions { repeated pb2.Enum rpt_ext_enum = 32; }
+	E_RptExtEnum = &xxx_File_pb2_test_proto_extDescs[5]
 
-var E_RptExtNested = &proto.ExtensionDesc{
-	ExtendedType:  (*Extensions)(nil),
-	ExtensionType: ([]*Nested)(nil),
-	Field:         33,
-	Name:          "pb2.rpt_ext_nested",
-	Tag:           "bytes,33,rep,name=rpt_ext_nested",
-	Filename:      "pb2/test.proto",
-}
+	// extend pb2.Extensions { repeated pb2.Nested rpt_ext_nested = 33; }
+	E_RptExtNested = &xxx_File_pb2_test_proto_extDescs[6]
 
-var E_MessageSetExtension = &proto.ExtensionDesc{
-	ExtendedType:  (*MessageSet)(nil),
-	ExtensionType: (*FakeMessageSetExtension)(nil),
-	Field:         50,
-	Name:          "pb2.",
-	Tag:           "bytes,50,opt,name=message_set_extension",
-	Filename:      "pb2/test.proto",
-}
+	// extend pb2.MessageSet { optional pb2.FakeMessageSetExtension message_set_extension = 50; }
+	E_MessageSetExtension = &xxx_File_pb2_test_proto_extDescs[7]
 
-var E_ExtensionsContainer_OptExtBool = &proto.ExtensionDesc{
-	ExtendedType:  (*Extensions)(nil),
-	ExtensionType: (*bool)(nil),
-	Field:         51,
-	Name:          "pb2.ExtensionsContainer.opt_ext_bool",
-	Tag:           "varint,51,opt,name=opt_ext_bool",
-	Filename:      "pb2/test.proto",
-}
+	// extend pb2.Extensions { optional bool opt_ext_bool = 51; }
+	E_ExtensionsContainer_OptExtBool = &xxx_File_pb2_test_proto_extDescs[8]
 
-var E_ExtensionsContainer_OptExtString = &proto.ExtensionDesc{
-	ExtendedType:  (*Extensions)(nil),
-	ExtensionType: (*string)(nil),
-	Field:         52,
-	Name:          "pb2.ExtensionsContainer.opt_ext_string",
-	Tag:           "bytes,52,opt,name=opt_ext_string",
-	Filename:      "pb2/test.proto",
-}
+	// extend pb2.Extensions { optional string opt_ext_string = 52; }
+	E_ExtensionsContainer_OptExtString = &xxx_File_pb2_test_proto_extDescs[9]
 
-var E_ExtensionsContainer_OptExtEnum = &proto.ExtensionDesc{
-	ExtendedType:  (*Extensions)(nil),
-	ExtensionType: (*Enum)(nil),
-	Field:         53,
-	Name:          "pb2.ExtensionsContainer.opt_ext_enum",
-	Tag:           "varint,53,opt,name=opt_ext_enum,enum=pb2.Enum",
-	Filename:      "pb2/test.proto",
-}
+	// extend pb2.Extensions { optional pb2.Enum opt_ext_enum = 53; }
+	E_ExtensionsContainer_OptExtEnum = &xxx_File_pb2_test_proto_extDescs[10]
 
-var E_ExtensionsContainer_OptExtNested = &proto.ExtensionDesc{
-	ExtendedType:  (*Extensions)(nil),
-	ExtensionType: (*Nested)(nil),
-	Field:         54,
-	Name:          "pb2.ExtensionsContainer.opt_ext_nested",
-	Tag:           "bytes,54,opt,name=opt_ext_nested",
-	Filename:      "pb2/test.proto",
-}
+	// extend pb2.Extensions { optional pb2.Nested opt_ext_nested = 54; }
+	E_ExtensionsContainer_OptExtNested = &xxx_File_pb2_test_proto_extDescs[11]
 
-var E_ExtensionsContainer_RptExtString = &proto.ExtensionDesc{
-	ExtendedType:  (*Extensions)(nil),
-	ExtensionType: ([]string)(nil),
-	Field:         61,
-	Name:          "pb2.ExtensionsContainer.rpt_ext_string",
-	Tag:           "bytes,61,rep,name=rpt_ext_string",
-	Filename:      "pb2/test.proto",
-}
+	// extend pb2.Extensions { repeated string rpt_ext_string = 61; }
+	E_ExtensionsContainer_RptExtString = &xxx_File_pb2_test_proto_extDescs[12]
 
-var E_ExtensionsContainer_RptExtEnum = &proto.ExtensionDesc{
-	ExtendedType:  (*Extensions)(nil),
-	ExtensionType: ([]Enum)(nil),
-	Field:         62,
-	Name:          "pb2.ExtensionsContainer.rpt_ext_enum",
-	Tag:           "varint,62,rep,name=rpt_ext_enum,enum=pb2.Enum",
-	Filename:      "pb2/test.proto",
-}
+	// extend pb2.Extensions { repeated pb2.Enum rpt_ext_enum = 62; }
+	E_ExtensionsContainer_RptExtEnum = &xxx_File_pb2_test_proto_extDescs[13]
 
-var E_ExtensionsContainer_RptExtNested = &proto.ExtensionDesc{
-	ExtendedType:  (*Extensions)(nil),
-	ExtensionType: ([]*Nested)(nil),
-	Field:         63,
-	Name:          "pb2.ExtensionsContainer.rpt_ext_nested",
-	Tag:           "bytes,63,rep,name=rpt_ext_nested",
-	Filename:      "pb2/test.proto",
-}
+	// extend pb2.Extensions { repeated pb2.Nested rpt_ext_nested = 63; }
+	E_ExtensionsContainer_RptExtNested = &xxx_File_pb2_test_proto_extDescs[14]
 
-var E_MessageSetExtension_MessageSetExtension = &proto.ExtensionDesc{
-	ExtendedType:  (*MessageSet)(nil),
-	ExtensionType: (*MessageSetExtension)(nil),
-	Field:         10,
-	Name:          "pb2.MessageSetExtension",
-	Tag:           "bytes,10,opt,name=message_set_extension",
-	Filename:      "pb2/test.proto",
-}
+	// extend pb2.MessageSet { optional pb2.MessageSetExtension message_set_extension = 10; }
+	E_MessageSetExtension_MessageSetExtension = &xxx_File_pb2_test_proto_extDescs[15]
 
-var E_MessageSetExtension_NotMessageSetExtension = &proto.ExtensionDesc{
-	ExtendedType:  (*MessageSet)(nil),
-	ExtensionType: (*MessageSetExtension)(nil),
-	Field:         20,
-	Name:          "pb2.MessageSetExtension.not_message_set_extension",
-	Tag:           "bytes,20,opt,name=not_message_set_extension",
-	Filename:      "pb2/test.proto",
-}
+	// extend pb2.MessageSet { optional pb2.MessageSetExtension not_message_set_extension = 20; }
+	E_MessageSetExtension_NotMessageSetExtension = &xxx_File_pb2_test_proto_extDescs[16]
 
-var E_MessageSetExtension_ExtNested = &proto.ExtensionDesc{
-	ExtendedType:  (*MessageSet)(nil),
-	ExtensionType: (*Nested)(nil),
-	Field:         30,
-	Name:          "pb2.MessageSetExtension.ext_nested",
-	Tag:           "bytes,30,opt,name=ext_nested",
-	Filename:      "pb2/test.proto",
-}
+	// extend pb2.MessageSet { optional pb2.Nested ext_nested = 30; }
+	E_MessageSetExtension_ExtNested = &xxx_File_pb2_test_proto_extDescs[17]
 
-var E_FakeMessageSetExtension_MessageSetExtension = &proto.ExtensionDesc{
-	ExtendedType:  (*FakeMessageSet)(nil),
-	ExtensionType: (*FakeMessageSetExtension)(nil),
-	Field:         10,
-	Name:          "pb2.FakeMessageSetExtension.message_set_extension",
-	Tag:           "bytes,10,opt,name=message_set_extension",
-	Filename:      "pb2/test.proto",
-}
+	// extend pb2.FakeMessageSet { optional pb2.FakeMessageSetExtension message_set_extension = 10; }
+	E_FakeMessageSetExtension_MessageSetExtension = &xxx_File_pb2_test_proto_extDescs[18]
+)
 
 func init() {
 	proto.RegisterFile("pb2/test.proto", xxx_File_pb2_test_proto_rawdesc_gzipped)
@@ -2078,6 +2120,7 @@
 		RawDescriptor:        xxx_File_pb2_test_proto_rawdesc,
 		GoTypes:              xxx_File_pb2_test_proto_goTypes,
 		DependencyIndexes:    xxx_File_pb2_test_proto_depIdxs,
+		LegacyExtensions:     xxx_File_pb2_test_proto_extDescs,
 		EnumOutputTypes:      xxx_File_pb2_test_proto_enumTypes,
 		MessageOutputTypes:   messageTypes,
 		ExtensionOutputTypes: extensionTypes,
@@ -2087,25 +2130,6 @@
 		xxx_File_pb2_test_proto_messageTypes[i].GoType = reflect.TypeOf(messageGoTypes[i])
 		xxx_File_pb2_test_proto_messageTypes[i].PBType = mt
 	}
-	E_OptExtBool.Type = extensionTypes[0]
-	E_OptExtString.Type = extensionTypes[1]
-	E_OptExtEnum.Type = extensionTypes[2]
-	E_OptExtNested.Type = extensionTypes[3]
-	E_RptExtFixed32.Type = extensionTypes[4]
-	E_RptExtEnum.Type = extensionTypes[5]
-	E_RptExtNested.Type = extensionTypes[6]
-	E_MessageSetExtension.Type = extensionTypes[7]
-	E_ExtensionsContainer_OptExtBool.Type = extensionTypes[8]
-	E_ExtensionsContainer_OptExtString.Type = extensionTypes[9]
-	E_ExtensionsContainer_OptExtEnum.Type = extensionTypes[10]
-	E_ExtensionsContainer_OptExtNested.Type = extensionTypes[11]
-	E_ExtensionsContainer_RptExtString.Type = extensionTypes[12]
-	E_ExtensionsContainer_RptExtEnum.Type = extensionTypes[13]
-	E_ExtensionsContainer_RptExtNested.Type = extensionTypes[14]
-	E_MessageSetExtension_MessageSetExtension.Type = extensionTypes[15]
-	E_MessageSetExtension_NotMessageSetExtension.Type = extensionTypes[16]
-	E_MessageSetExtension_ExtNested.Type = extensionTypes[17]
-	E_FakeMessageSetExtension_MessageSetExtension.Type = extensionTypes[18]
 	xxx_File_pb2_test_proto_goTypes = nil
 	xxx_File_pb2_test_proto_depIdxs = nil
 }
diff --git a/encoding/textpb/encode_test.go b/encoding/textpb/encode_test.go
index f119ce9..3430fc5 100644
--- a/encoding/textpb/encode_test.go
+++ b/encoding/textpb/encode_test.go
@@ -17,7 +17,6 @@
 	"github.com/golang/protobuf/v2/internal/encoding/pack"
 	"github.com/golang/protobuf/v2/internal/encoding/wire"
 	"github.com/golang/protobuf/v2/internal/impl"
-	"github.com/golang/protobuf/v2/internal/legacy"
 	"github.com/golang/protobuf/v2/internal/scalar"
 	"github.com/golang/protobuf/v2/proto"
 	preg "github.com/golang/protobuf/v2/reflect/protoregistry"
@@ -52,14 +51,13 @@
 }
 
 func setExtension(m proto.Message, xd *protoapi.ExtensionDesc, val interface{}) {
-	xt := legacy.Export{}.ExtensionTypeFromDesc(xd)
 	knownFields := m.ProtoReflect().KnownFields()
 	extTypes := knownFields.ExtensionTypes()
-	extTypes.Register(xt)
+	extTypes.Register(xd.Type)
 	if val == nil {
 		return
 	}
-	pval := xt.ValueOf(val)
+	pval := xd.Type.ValueOf(val)
 	knownFields.Set(wire.Number(xd.Field), pval)
 }
 
diff --git a/internal/fileinit/desc.go b/internal/fileinit/desc.go
index 8c49f3c..550cae1 100644
--- a/internal/fileinit/desc.go
+++ b/internal/fileinit/desc.go
@@ -13,6 +13,7 @@
 	"reflect"
 	"sync"
 
+	papi "github.com/golang/protobuf/protoapi"
 	pragma "github.com/golang/protobuf/v2/internal/pragma"
 	ptype "github.com/golang/protobuf/v2/internal/prototype"
 	pfmt "github.com/golang/protobuf/v2/internal/typefmt"
@@ -95,6 +96,13 @@
 	// TODO: Provide a list of extension types for options extensions.
 	// OptionDependencies []pref.ExtensionType
 
+	// LegacyExtensions are a list of legacy extension descriptors.
+	// 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.
+	// If non-nil, len(LegacyExtensions) must equal len(ExtensionOutputTypes).
+	LegacyExtensions []papi.ExtensionDesc
+
 	// EnumOutputTypes is where Init stores all initialized enum types
 	// in "flattened ordering".
 	EnumOutputTypes []pref.EnumType
@@ -116,6 +124,13 @@
 func (fb FileBuilder) Init() pref.FileDescriptor {
 	fd := newFileDesc(fb)
 
+	if fb.LegacyExtensions != nil {
+		for i := range fd.allExtensions {
+			fd.allExtensions[i].legacyDesc = &fb.LegacyExtensions[i]
+			fb.LegacyExtensions[i].Type = &fd.allExtensions[i]
+		}
+	}
+
 	for i := range fd.allEnums {
 		fb.EnumOutputTypes[i] = &fd.allEnums[i]
 	}
@@ -341,6 +356,8 @@
 		number       pref.FieldNumber
 		extendedType pref.MessageDescriptor
 
+		legacyDesc *papi.ExtensionDesc
+
 		lazy *extensionLazy // protected by fileDesc.once
 	}
 	extensionLazy struct {
@@ -397,6 +414,10 @@
 	return xd.lazy
 }
 
+// ProtoLegacyExtensionDesc is a pseudo-internal API for allowing the v1 code
+// to be able to retrieve a v1 ExtensionDesc.
+func (xd *extensionDesc) ProtoLegacyExtensionDesc() *papi.ExtensionDesc { return xd.legacyDesc }
+
 type (
 	serviceDesc struct {
 		baseDesc
diff --git a/internal/impl/legacy_extension.go b/internal/impl/legacy_extension.go
index ff464dc..83d5e99 100644
--- a/internal/impl/legacy_extension.go
+++ b/internal/impl/legacy_extension.go
@@ -163,7 +163,7 @@
 	if x.Desc != nil {
 		panic("extension descriptor already registered")
 	}
-	x.Desc = legacyWrapper.ExtensionDescFromType(t)
+	x.Desc = extensionDescFromType(t)
 	if t.Cardinality() == pref.Repeated {
 		// If the field is repeated, initialize the entry with an empty list
 		// so that future Get operations can return a mutable and concrete list.
@@ -225,6 +225,15 @@
 	})
 }
 
+func extensionDescFromType(typ pref.ExtensionType) *papi.ExtensionDesc {
+	if xt, ok := typ.(interface{ ProtoLegacyExtensionDesc() *papi.ExtensionDesc }); ok {
+		if desc := xt.ProtoLegacyExtensionDesc(); desc != nil {
+			return desc
+		}
+	}
+	return legacyWrapper.ExtensionDescFromType(typ)
+}
+
 func extensionTypeFromDesc(desc *papi.ExtensionDesc) pref.ExtensionType {
 	if desc.Type != nil {
 		return desc.Type
diff --git a/internal/legacy/extension.go b/internal/legacy/extension.go
index 1626702..839d597 100644
--- a/internal/legacy/extension.go
+++ b/internal/legacy/extension.go
@@ -47,6 +47,13 @@
 // extensionDescFromType converts a v2 protoreflect.ExtensionType to a
 // v1 protoapi.ExtensionDesc. The returned ExtensionDesc must not be mutated.
 func extensionDescFromType(t pref.ExtensionType) *papi.ExtensionDesc {
+	// Fast-path: check whether an extension desc is already nested within.
+	if t, ok := t.(interface{ ProtoLegacyExtensionDesc() *papi.ExtensionDesc }); ok {
+		if d := t.ProtoLegacyExtensionDesc(); d != nil {
+			return d
+		}
+	}
+
 	// Fast-path: check the cache for whether this ExtensionType has already
 	// been converted to a legacy descriptor.
 	if d, ok := extensionDescCache.Load(t); ok {
diff --git a/internal/testprotos/test/ext.pb.go b/internal/testprotos/test/ext.pb.go
index 0ceed42..a1fce7e 100644
--- a/internal/testprotos/test/ext.pb.go
+++ b/internal/testprotos/test/ext.pb.go
@@ -16,14 +16,20 @@
 // proto package needs to be updated.
 const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
-var E_ForeignInt32Extension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: (*int32)(nil),
-	Field:         2000,
-	Name:          "goproto.proto.test.foreign_int32_extension",
-	Tag:           "varint,2000,opt,name=foreign_int32_extension",
-	Filename:      "test/ext.proto",
+var xxx_File_test_ext_proto_extDescs = []proto.ExtensionDesc{
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: (*int32)(nil),
+		Field:         2000,
+		Name:          "goproto.proto.test.foreign_int32_extension",
+		Tag:           "varint,2000,opt,name=foreign_int32_extension",
+		Filename:      "test/ext.proto",
+	},
 }
+var (
+	// extend goproto.proto.test.TestAllExtensions { optional int32 foreign_int32_extension = 2000; }
+	E_ForeignInt32Extension = &xxx_File_test_ext_proto_extDescs[0]
+)
 
 func init() {
 	proto.RegisterFile("test/ext.proto", xxx_File_test_ext_proto_rawdesc_gzipped)
@@ -71,9 +77,9 @@
 		RawDescriptor:        xxx_File_test_ext_proto_rawdesc,
 		GoTypes:              xxx_File_test_ext_proto_goTypes,
 		DependencyIndexes:    xxx_File_test_ext_proto_depIdxs,
+		LegacyExtensions:     xxx_File_test_ext_proto_extDescs,
 		ExtensionOutputTypes: extensionTypes,
 	}.Init()
-	E_ForeignInt32Extension.Type = extensionTypes[0]
 	xxx_File_test_ext_proto_goTypes = nil
 	xxx_File_test_ext_proto_depIdxs = nil
 }
diff --git a/internal/testprotos/test/test.pb.go b/internal/testprotos/test/test.pb.go
index 4a6f9ed..0e6f681 100644
--- a/internal/testprotos/test/test.pb.go
+++ b/internal/testprotos/test/test.pb.go
@@ -1567,338 +1567,416 @@
 	return 0
 }
 
-var E_OptionalInt32Extension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: (*int32)(nil),
-	Field:         1,
-	Name:          "goproto.proto.test.optional_int32_extension",
-	Tag:           "varint,1,opt,name=optional_int32_extension",
-	Filename:      "test/test.proto",
+var xxx_File_test_test_proto_extDescs = []proto.ExtensionDesc{
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: (*int32)(nil),
+		Field:         1,
+		Name:          "goproto.proto.test.optional_int32_extension",
+		Tag:           "varint,1,opt,name=optional_int32_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: (*int64)(nil),
+		Field:         2,
+		Name:          "goproto.proto.test.optional_int64_extension",
+		Tag:           "varint,2,opt,name=optional_int64_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: (*uint32)(nil),
+		Field:         3,
+		Name:          "goproto.proto.test.optional_uint32_extension",
+		Tag:           "varint,3,opt,name=optional_uint32_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: (*uint64)(nil),
+		Field:         4,
+		Name:          "goproto.proto.test.optional_uint64_extension",
+		Tag:           "varint,4,opt,name=optional_uint64_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: (*int32)(nil),
+		Field:         5,
+		Name:          "goproto.proto.test.optional_sint32_extension",
+		Tag:           "zigzag32,5,opt,name=optional_sint32_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: (*int64)(nil),
+		Field:         6,
+		Name:          "goproto.proto.test.optional_sint64_extension",
+		Tag:           "zigzag64,6,opt,name=optional_sint64_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: (*uint32)(nil),
+		Field:         7,
+		Name:          "goproto.proto.test.optional_fixed32_extension",
+		Tag:           "fixed32,7,opt,name=optional_fixed32_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: (*uint64)(nil),
+		Field:         8,
+		Name:          "goproto.proto.test.optional_fixed64_extension",
+		Tag:           "fixed64,8,opt,name=optional_fixed64_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: (*int32)(nil),
+		Field:         9,
+		Name:          "goproto.proto.test.optional_sfixed32_extension",
+		Tag:           "fixed32,9,opt,name=optional_sfixed32_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: (*int64)(nil),
+		Field:         10,
+		Name:          "goproto.proto.test.optional_sfixed64_extension",
+		Tag:           "fixed64,10,opt,name=optional_sfixed64_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: (*float32)(nil),
+		Field:         11,
+		Name:          "goproto.proto.test.optional_float_extension",
+		Tag:           "fixed32,11,opt,name=optional_float_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: (*float64)(nil),
+		Field:         12,
+		Name:          "goproto.proto.test.optional_double_extension",
+		Tag:           "fixed64,12,opt,name=optional_double_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: (*bool)(nil),
+		Field:         13,
+		Name:          "goproto.proto.test.optional_bool_extension",
+		Tag:           "varint,13,opt,name=optional_bool_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: (*string)(nil),
+		Field:         14,
+		Name:          "goproto.proto.test.optional_string_extension",
+		Tag:           "bytes,14,opt,name=optional_string_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: ([]byte)(nil),
+		Field:         15,
+		Name:          "goproto.proto.test.optional_bytes_extension",
+		Tag:           "bytes,15,opt,name=optional_bytes_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: (*OptionalGroupExtension)(nil),
+		Field:         16,
+		Name:          "goproto.proto.test.optionalgroup_extension",
+		Tag:           "group,16,opt,name=OptionalGroup_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: (*TestAllTypes_NestedMessage)(nil),
+		Field:         18,
+		Name:          "goproto.proto.test.optional_nested_message_extension",
+		Tag:           "bytes,18,opt,name=optional_nested_message_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: (*TestAllTypes_NestedEnum)(nil),
+		Field:         21,
+		Name:          "goproto.proto.test.optional_nested_enum_extension",
+		Tag:           "varint,21,opt,name=optional_nested_enum_extension,enum=goproto.proto.test.TestAllTypes_NestedEnum",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: ([]int32)(nil),
+		Field:         31,
+		Name:          "goproto.proto.test.repeated_int32_extension",
+		Tag:           "varint,31,rep,name=repeated_int32_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: ([]int64)(nil),
+		Field:         32,
+		Name:          "goproto.proto.test.repeated_int64_extension",
+		Tag:           "varint,32,rep,name=repeated_int64_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: ([]uint32)(nil),
+		Field:         33,
+		Name:          "goproto.proto.test.repeated_uint32_extension",
+		Tag:           "varint,33,rep,name=repeated_uint32_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: ([]uint64)(nil),
+		Field:         34,
+		Name:          "goproto.proto.test.repeated_uint64_extension",
+		Tag:           "varint,34,rep,name=repeated_uint64_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: ([]int32)(nil),
+		Field:         35,
+		Name:          "goproto.proto.test.repeated_sint32_extension",
+		Tag:           "zigzag32,35,rep,name=repeated_sint32_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: ([]int64)(nil),
+		Field:         36,
+		Name:          "goproto.proto.test.repeated_sint64_extension",
+		Tag:           "zigzag64,36,rep,name=repeated_sint64_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: ([]uint32)(nil),
+		Field:         37,
+		Name:          "goproto.proto.test.repeated_fixed32_extension",
+		Tag:           "fixed32,37,rep,name=repeated_fixed32_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: ([]uint64)(nil),
+		Field:         38,
+		Name:          "goproto.proto.test.repeated_fixed64_extension",
+		Tag:           "fixed64,38,rep,name=repeated_fixed64_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: ([]int32)(nil),
+		Field:         39,
+		Name:          "goproto.proto.test.repeated_sfixed32_extension",
+		Tag:           "fixed32,39,rep,name=repeated_sfixed32_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: ([]int64)(nil),
+		Field:         40,
+		Name:          "goproto.proto.test.repeated_sfixed64_extension",
+		Tag:           "fixed64,40,rep,name=repeated_sfixed64_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: ([]float32)(nil),
+		Field:         41,
+		Name:          "goproto.proto.test.repeated_float_extension",
+		Tag:           "fixed32,41,rep,name=repeated_float_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: ([]float64)(nil),
+		Field:         42,
+		Name:          "goproto.proto.test.repeated_double_extension",
+		Tag:           "fixed64,42,rep,name=repeated_double_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: ([]bool)(nil),
+		Field:         43,
+		Name:          "goproto.proto.test.repeated_bool_extension",
+		Tag:           "varint,43,rep,name=repeated_bool_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: ([]string)(nil),
+		Field:         44,
+		Name:          "goproto.proto.test.repeated_string_extension",
+		Tag:           "bytes,44,rep,name=repeated_string_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: ([][]byte)(nil),
+		Field:         45,
+		Name:          "goproto.proto.test.repeated_bytes_extension",
+		Tag:           "bytes,45,rep,name=repeated_bytes_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: ([]*RepeatedGroupExtension)(nil),
+		Field:         46,
+		Name:          "goproto.proto.test.repeatedgroup_extension",
+		Tag:           "group,46,rep,name=RepeatedGroup_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: ([]*TestAllTypes_NestedMessage)(nil),
+		Field:         48,
+		Name:          "goproto.proto.test.repeated_nested_message_extension",
+		Tag:           "bytes,48,rep,name=repeated_nested_message_extension",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: ([]TestAllTypes_NestedEnum)(nil),
+		Field:         51,
+		Name:          "goproto.proto.test.repeated_nested_enum_extension",
+		Tag:           "varint,51,rep,name=repeated_nested_enum_extension,enum=goproto.proto.test.TestAllTypes_NestedEnum",
+		Filename:      "test/test.proto",
+	},
+	{
+		ExtendedType:  (*TestAllExtensions)(nil),
+		ExtensionType: (*string)(nil),
+		Field:         1003,
+		Name:          "goproto.proto.test.TestNestedExtension.nested_string_extension",
+		Tag:           "bytes,1003,opt,name=nested_string_extension",
+		Filename:      "test/test.proto",
+	},
 }
+var (
+	// extend goproto.proto.test.TestAllExtensions { optional int32 optional_int32_extension = 1; }
+	E_OptionalInt32Extension = &xxx_File_test_test_proto_extDescs[0]
 
-var E_OptionalInt64Extension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: (*int64)(nil),
-	Field:         2,
-	Name:          "goproto.proto.test.optional_int64_extension",
-	Tag:           "varint,2,opt,name=optional_int64_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { optional int64 optional_int64_extension = 2; }
+	E_OptionalInt64Extension = &xxx_File_test_test_proto_extDescs[1]
 
-var E_OptionalUint32Extension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: (*uint32)(nil),
-	Field:         3,
-	Name:          "goproto.proto.test.optional_uint32_extension",
-	Tag:           "varint,3,opt,name=optional_uint32_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { optional uint32 optional_uint32_extension = 3; }
+	E_OptionalUint32Extension = &xxx_File_test_test_proto_extDescs[2]
 
-var E_OptionalUint64Extension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: (*uint64)(nil),
-	Field:         4,
-	Name:          "goproto.proto.test.optional_uint64_extension",
-	Tag:           "varint,4,opt,name=optional_uint64_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { optional uint64 optional_uint64_extension = 4; }
+	E_OptionalUint64Extension = &xxx_File_test_test_proto_extDescs[3]
 
-var E_OptionalSint32Extension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: (*int32)(nil),
-	Field:         5,
-	Name:          "goproto.proto.test.optional_sint32_extension",
-	Tag:           "zigzag32,5,opt,name=optional_sint32_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { optional sint32 optional_sint32_extension = 5; }
+	E_OptionalSint32Extension = &xxx_File_test_test_proto_extDescs[4]
 
-var E_OptionalSint64Extension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: (*int64)(nil),
-	Field:         6,
-	Name:          "goproto.proto.test.optional_sint64_extension",
-	Tag:           "zigzag64,6,opt,name=optional_sint64_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { optional sint64 optional_sint64_extension = 6; }
+	E_OptionalSint64Extension = &xxx_File_test_test_proto_extDescs[5]
 
-var E_OptionalFixed32Extension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: (*uint32)(nil),
-	Field:         7,
-	Name:          "goproto.proto.test.optional_fixed32_extension",
-	Tag:           "fixed32,7,opt,name=optional_fixed32_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { optional fixed32 optional_fixed32_extension = 7; }
+	E_OptionalFixed32Extension = &xxx_File_test_test_proto_extDescs[6]
 
-var E_OptionalFixed64Extension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: (*uint64)(nil),
-	Field:         8,
-	Name:          "goproto.proto.test.optional_fixed64_extension",
-	Tag:           "fixed64,8,opt,name=optional_fixed64_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { optional fixed64 optional_fixed64_extension = 8; }
+	E_OptionalFixed64Extension = &xxx_File_test_test_proto_extDescs[7]
 
-var E_OptionalSfixed32Extension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: (*int32)(nil),
-	Field:         9,
-	Name:          "goproto.proto.test.optional_sfixed32_extension",
-	Tag:           "fixed32,9,opt,name=optional_sfixed32_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { optional sfixed32 optional_sfixed32_extension = 9; }
+	E_OptionalSfixed32Extension = &xxx_File_test_test_proto_extDescs[8]
 
-var E_OptionalSfixed64Extension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: (*int64)(nil),
-	Field:         10,
-	Name:          "goproto.proto.test.optional_sfixed64_extension",
-	Tag:           "fixed64,10,opt,name=optional_sfixed64_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { optional sfixed64 optional_sfixed64_extension = 10; }
+	E_OptionalSfixed64Extension = &xxx_File_test_test_proto_extDescs[9]
 
-var E_OptionalFloatExtension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: (*float32)(nil),
-	Field:         11,
-	Name:          "goproto.proto.test.optional_float_extension",
-	Tag:           "fixed32,11,opt,name=optional_float_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { optional float optional_float_extension = 11; }
+	E_OptionalFloatExtension = &xxx_File_test_test_proto_extDescs[10]
 
-var E_OptionalDoubleExtension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: (*float64)(nil),
-	Field:         12,
-	Name:          "goproto.proto.test.optional_double_extension",
-	Tag:           "fixed64,12,opt,name=optional_double_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { optional double optional_double_extension = 12; }
+	E_OptionalDoubleExtension = &xxx_File_test_test_proto_extDescs[11]
 
-var E_OptionalBoolExtension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: (*bool)(nil),
-	Field:         13,
-	Name:          "goproto.proto.test.optional_bool_extension",
-	Tag:           "varint,13,opt,name=optional_bool_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { optional bool optional_bool_extension = 13; }
+	E_OptionalBoolExtension = &xxx_File_test_test_proto_extDescs[12]
 
-var E_OptionalStringExtension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: (*string)(nil),
-	Field:         14,
-	Name:          "goproto.proto.test.optional_string_extension",
-	Tag:           "bytes,14,opt,name=optional_string_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { optional string optional_string_extension = 14; }
+	E_OptionalStringExtension = &xxx_File_test_test_proto_extDescs[13]
 
-var E_OptionalBytesExtension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: ([]byte)(nil),
-	Field:         15,
-	Name:          "goproto.proto.test.optional_bytes_extension",
-	Tag:           "bytes,15,opt,name=optional_bytes_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { optional bytes optional_bytes_extension = 15; }
+	E_OptionalBytesExtension = &xxx_File_test_test_proto_extDescs[14]
 
-var E_OptionalgroupExtension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: (*OptionalGroupExtension)(nil),
-	Field:         16,
-	Name:          "goproto.proto.test.optionalgroup_extension",
-	Tag:           "group,16,opt,name=OptionalGroup_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { optional goproto.proto.test.OptionalGroup_extension optionalgroup_extension = 16; }
+	E_OptionalgroupExtension = &xxx_File_test_test_proto_extDescs[15]
 
-var E_OptionalNestedMessageExtension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: (*TestAllTypes_NestedMessage)(nil),
-	Field:         18,
-	Name:          "goproto.proto.test.optional_nested_message_extension",
-	Tag:           "bytes,18,opt,name=optional_nested_message_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { optional goproto.proto.test.TestAllTypes.NestedMessage optional_nested_message_extension = 18; }
+	E_OptionalNestedMessageExtension = &xxx_File_test_test_proto_extDescs[16]
 
-var E_OptionalNestedEnumExtension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: (*TestAllTypes_NestedEnum)(nil),
-	Field:         21,
-	Name:          "goproto.proto.test.optional_nested_enum_extension",
-	Tag:           "varint,21,opt,name=optional_nested_enum_extension,enum=goproto.proto.test.TestAllTypes_NestedEnum",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { optional goproto.proto.test.TestAllTypes.NestedEnum optional_nested_enum_extension = 21; }
+	E_OptionalNestedEnumExtension = &xxx_File_test_test_proto_extDescs[17]
 
-var E_RepeatedInt32Extension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: ([]int32)(nil),
-	Field:         31,
-	Name:          "goproto.proto.test.repeated_int32_extension",
-	Tag:           "varint,31,rep,name=repeated_int32_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { repeated int32 repeated_int32_extension = 31; }
+	E_RepeatedInt32Extension = &xxx_File_test_test_proto_extDescs[18]
 
-var E_RepeatedInt64Extension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: ([]int64)(nil),
-	Field:         32,
-	Name:          "goproto.proto.test.repeated_int64_extension",
-	Tag:           "varint,32,rep,name=repeated_int64_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { repeated int64 repeated_int64_extension = 32; }
+	E_RepeatedInt64Extension = &xxx_File_test_test_proto_extDescs[19]
 
-var E_RepeatedUint32Extension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: ([]uint32)(nil),
-	Field:         33,
-	Name:          "goproto.proto.test.repeated_uint32_extension",
-	Tag:           "varint,33,rep,name=repeated_uint32_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { repeated uint32 repeated_uint32_extension = 33; }
+	E_RepeatedUint32Extension = &xxx_File_test_test_proto_extDescs[20]
 
-var E_RepeatedUint64Extension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: ([]uint64)(nil),
-	Field:         34,
-	Name:          "goproto.proto.test.repeated_uint64_extension",
-	Tag:           "varint,34,rep,name=repeated_uint64_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { repeated uint64 repeated_uint64_extension = 34; }
+	E_RepeatedUint64Extension = &xxx_File_test_test_proto_extDescs[21]
 
-var E_RepeatedSint32Extension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: ([]int32)(nil),
-	Field:         35,
-	Name:          "goproto.proto.test.repeated_sint32_extension",
-	Tag:           "zigzag32,35,rep,name=repeated_sint32_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { repeated sint32 repeated_sint32_extension = 35; }
+	E_RepeatedSint32Extension = &xxx_File_test_test_proto_extDescs[22]
 
-var E_RepeatedSint64Extension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: ([]int64)(nil),
-	Field:         36,
-	Name:          "goproto.proto.test.repeated_sint64_extension",
-	Tag:           "zigzag64,36,rep,name=repeated_sint64_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { repeated sint64 repeated_sint64_extension = 36; }
+	E_RepeatedSint64Extension = &xxx_File_test_test_proto_extDescs[23]
 
-var E_RepeatedFixed32Extension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: ([]uint32)(nil),
-	Field:         37,
-	Name:          "goproto.proto.test.repeated_fixed32_extension",
-	Tag:           "fixed32,37,rep,name=repeated_fixed32_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { repeated fixed32 repeated_fixed32_extension = 37; }
+	E_RepeatedFixed32Extension = &xxx_File_test_test_proto_extDescs[24]
 
-var E_RepeatedFixed64Extension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: ([]uint64)(nil),
-	Field:         38,
-	Name:          "goproto.proto.test.repeated_fixed64_extension",
-	Tag:           "fixed64,38,rep,name=repeated_fixed64_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { repeated fixed64 repeated_fixed64_extension = 38; }
+	E_RepeatedFixed64Extension = &xxx_File_test_test_proto_extDescs[25]
 
-var E_RepeatedSfixed32Extension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: ([]int32)(nil),
-	Field:         39,
-	Name:          "goproto.proto.test.repeated_sfixed32_extension",
-	Tag:           "fixed32,39,rep,name=repeated_sfixed32_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { repeated sfixed32 repeated_sfixed32_extension = 39; }
+	E_RepeatedSfixed32Extension = &xxx_File_test_test_proto_extDescs[26]
 
-var E_RepeatedSfixed64Extension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: ([]int64)(nil),
-	Field:         40,
-	Name:          "goproto.proto.test.repeated_sfixed64_extension",
-	Tag:           "fixed64,40,rep,name=repeated_sfixed64_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { repeated sfixed64 repeated_sfixed64_extension = 40; }
+	E_RepeatedSfixed64Extension = &xxx_File_test_test_proto_extDescs[27]
 
-var E_RepeatedFloatExtension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: ([]float32)(nil),
-	Field:         41,
-	Name:          "goproto.proto.test.repeated_float_extension",
-	Tag:           "fixed32,41,rep,name=repeated_float_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { repeated float repeated_float_extension = 41; }
+	E_RepeatedFloatExtension = &xxx_File_test_test_proto_extDescs[28]
 
-var E_RepeatedDoubleExtension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: ([]float64)(nil),
-	Field:         42,
-	Name:          "goproto.proto.test.repeated_double_extension",
-	Tag:           "fixed64,42,rep,name=repeated_double_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { repeated double repeated_double_extension = 42; }
+	E_RepeatedDoubleExtension = &xxx_File_test_test_proto_extDescs[29]
 
-var E_RepeatedBoolExtension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: ([]bool)(nil),
-	Field:         43,
-	Name:          "goproto.proto.test.repeated_bool_extension",
-	Tag:           "varint,43,rep,name=repeated_bool_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { repeated bool repeated_bool_extension = 43; }
+	E_RepeatedBoolExtension = &xxx_File_test_test_proto_extDescs[30]
 
-var E_RepeatedStringExtension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: ([]string)(nil),
-	Field:         44,
-	Name:          "goproto.proto.test.repeated_string_extension",
-	Tag:           "bytes,44,rep,name=repeated_string_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { repeated string repeated_string_extension = 44; }
+	E_RepeatedStringExtension = &xxx_File_test_test_proto_extDescs[31]
 
-var E_RepeatedBytesExtension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: ([][]byte)(nil),
-	Field:         45,
-	Name:          "goproto.proto.test.repeated_bytes_extension",
-	Tag:           "bytes,45,rep,name=repeated_bytes_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { repeated bytes repeated_bytes_extension = 45; }
+	E_RepeatedBytesExtension = &xxx_File_test_test_proto_extDescs[32]
 
-var E_RepeatedgroupExtension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: ([]*RepeatedGroupExtension)(nil),
-	Field:         46,
-	Name:          "goproto.proto.test.repeatedgroup_extension",
-	Tag:           "group,46,rep,name=RepeatedGroup_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { repeated goproto.proto.test.RepeatedGroup_extension repeatedgroup_extension = 46; }
+	E_RepeatedgroupExtension = &xxx_File_test_test_proto_extDescs[33]
 
-var E_RepeatedNestedMessageExtension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: ([]*TestAllTypes_NestedMessage)(nil),
-	Field:         48,
-	Name:          "goproto.proto.test.repeated_nested_message_extension",
-	Tag:           "bytes,48,rep,name=repeated_nested_message_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { repeated goproto.proto.test.TestAllTypes.NestedMessage repeated_nested_message_extension = 48; }
+	E_RepeatedNestedMessageExtension = &xxx_File_test_test_proto_extDescs[34]
 
-var E_RepeatedNestedEnumExtension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: ([]TestAllTypes_NestedEnum)(nil),
-	Field:         51,
-	Name:          "goproto.proto.test.repeated_nested_enum_extension",
-	Tag:           "varint,51,rep,name=repeated_nested_enum_extension,enum=goproto.proto.test.TestAllTypes_NestedEnum",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { repeated goproto.proto.test.TestAllTypes.NestedEnum repeated_nested_enum_extension = 51; }
+	E_RepeatedNestedEnumExtension = &xxx_File_test_test_proto_extDescs[35]
 
-var E_TestNestedExtension_NestedStringExtension = &proto.ExtensionDesc{
-	ExtendedType:  (*TestAllExtensions)(nil),
-	ExtensionType: (*string)(nil),
-	Field:         1003,
-	Name:          "goproto.proto.test.TestNestedExtension.nested_string_extension",
-	Tag:           "bytes,1003,opt,name=nested_string_extension",
-	Filename:      "test/test.proto",
-}
+	// extend goproto.proto.test.TestAllExtensions { optional string nested_string_extension = 1003; }
+	E_TestNestedExtension_NestedStringExtension = &xxx_File_test_test_proto_extDescs[36]
+)
 
 func init() {
 	proto.RegisterFile("test/test.proto", xxx_File_test_test_proto_rawdesc_gzipped)
@@ -2884,6 +2962,7 @@
 		RawDescriptor:        xxx_File_test_test_proto_rawdesc,
 		GoTypes:              xxx_File_test_test_proto_goTypes,
 		DependencyIndexes:    xxx_File_test_test_proto_depIdxs,
+		LegacyExtensions:     xxx_File_test_test_proto_extDescs,
 		EnumOutputTypes:      xxx_File_test_test_proto_enumTypes,
 		MessageOutputTypes:   messageTypes,
 		ExtensionOutputTypes: extensionTypes,
@@ -2893,43 +2972,6 @@
 		xxx_File_test_test_proto_messageTypes[i].GoType = reflect.TypeOf(messageGoTypes[i])
 		xxx_File_test_test_proto_messageTypes[i].PBType = mt
 	}
-	E_OptionalInt32Extension.Type = extensionTypes[0]
-	E_OptionalInt64Extension.Type = extensionTypes[1]
-	E_OptionalUint32Extension.Type = extensionTypes[2]
-	E_OptionalUint64Extension.Type = extensionTypes[3]
-	E_OptionalSint32Extension.Type = extensionTypes[4]
-	E_OptionalSint64Extension.Type = extensionTypes[5]
-	E_OptionalFixed32Extension.Type = extensionTypes[6]
-	E_OptionalFixed64Extension.Type = extensionTypes[7]
-	E_OptionalSfixed32Extension.Type = extensionTypes[8]
-	E_OptionalSfixed64Extension.Type = extensionTypes[9]
-	E_OptionalFloatExtension.Type = extensionTypes[10]
-	E_OptionalDoubleExtension.Type = extensionTypes[11]
-	E_OptionalBoolExtension.Type = extensionTypes[12]
-	E_OptionalStringExtension.Type = extensionTypes[13]
-	E_OptionalBytesExtension.Type = extensionTypes[14]
-	E_OptionalgroupExtension.Type = extensionTypes[15]
-	E_OptionalNestedMessageExtension.Type = extensionTypes[16]
-	E_OptionalNestedEnumExtension.Type = extensionTypes[17]
-	E_RepeatedInt32Extension.Type = extensionTypes[18]
-	E_RepeatedInt64Extension.Type = extensionTypes[19]
-	E_RepeatedUint32Extension.Type = extensionTypes[20]
-	E_RepeatedUint64Extension.Type = extensionTypes[21]
-	E_RepeatedSint32Extension.Type = extensionTypes[22]
-	E_RepeatedSint64Extension.Type = extensionTypes[23]
-	E_RepeatedFixed32Extension.Type = extensionTypes[24]
-	E_RepeatedFixed64Extension.Type = extensionTypes[25]
-	E_RepeatedSfixed32Extension.Type = extensionTypes[26]
-	E_RepeatedSfixed64Extension.Type = extensionTypes[27]
-	E_RepeatedFloatExtension.Type = extensionTypes[28]
-	E_RepeatedDoubleExtension.Type = extensionTypes[29]
-	E_RepeatedBoolExtension.Type = extensionTypes[30]
-	E_RepeatedStringExtension.Type = extensionTypes[31]
-	E_RepeatedBytesExtension.Type = extensionTypes[32]
-	E_RepeatedgroupExtension.Type = extensionTypes[33]
-	E_RepeatedNestedMessageExtension.Type = extensionTypes[34]
-	E_RepeatedNestedEnumExtension.Type = extensionTypes[35]
-	E_TestNestedExtension_NestedStringExtension.Type = extensionTypes[36]
 	xxx_File_test_test_proto_goTypes = nil
 	xxx_File_test_test_proto_depIdxs = nil
 }
diff --git a/reflect/protoregistry/testprotos/test.pb.go b/reflect/protoregistry/testprotos/test.pb.go
index d13e90c..2303213 100644
--- a/reflect/protoregistry/testprotos/test.pb.go
+++ b/reflect/protoregistry/testprotos/test.pb.go
@@ -302,59 +302,75 @@
 	return false
 }
 
-var E_StringField = &proto.ExtensionDesc{
-	ExtendedType:  (*Message1)(nil),
-	ExtensionType: (*string)(nil),
-	Field:         11,
-	Name:          "testprotos.string_field",
-	Tag:           "bytes,11,opt,name=string_field",
-	Filename:      "test.proto",
+var xxx_File_test_proto_extDescs = []proto.ExtensionDesc{
+	{
+		ExtendedType:  (*Message1)(nil),
+		ExtensionType: (*string)(nil),
+		Field:         11,
+		Name:          "testprotos.string_field",
+		Tag:           "bytes,11,opt,name=string_field",
+		Filename:      "test.proto",
+	},
+	{
+		ExtendedType:  (*Message1)(nil),
+		ExtensionType: (*Enum1)(nil),
+		Field:         12,
+		Name:          "testprotos.enum_field",
+		Tag:           "varint,12,opt,name=enum_field,enum=testprotos.Enum1",
+		Filename:      "test.proto",
+	},
+	{
+		ExtendedType:  (*Message1)(nil),
+		ExtensionType: (*Message2)(nil),
+		Field:         13,
+		Name:          "testprotos.message_field",
+		Tag:           "bytes,13,opt,name=message_field",
+		Filename:      "test.proto",
+	},
+	{
+		ExtendedType:  (*Message1)(nil),
+		ExtensionType: (*Message2)(nil),
+		Field:         21,
+		Name:          "testprotos.Message4.message_field",
+		Tag:           "bytes,21,opt,name=message_field",
+		Filename:      "test.proto",
+	},
+	{
+		ExtendedType:  (*Message1)(nil),
+		ExtensionType: (*Enum1)(nil),
+		Field:         22,
+		Name:          "testprotos.Message4.enum_field",
+		Tag:           "varint,22,opt,name=enum_field,enum=testprotos.Enum1",
+		Filename:      "test.proto",
+	},
+	{
+		ExtendedType:  (*Message1)(nil),
+		ExtensionType: (*string)(nil),
+		Field:         23,
+		Name:          "testprotos.Message4.string_field",
+		Tag:           "bytes,23,opt,name=string_field",
+		Filename:      "test.proto",
+	},
 }
+var (
+	// extend testprotos.Message1 { optional string string_field = 11; }
+	E_StringField = &xxx_File_test_proto_extDescs[0]
 
-var E_EnumField = &proto.ExtensionDesc{
-	ExtendedType:  (*Message1)(nil),
-	ExtensionType: (*Enum1)(nil),
-	Field:         12,
-	Name:          "testprotos.enum_field",
-	Tag:           "varint,12,opt,name=enum_field,enum=testprotos.Enum1",
-	Filename:      "test.proto",
-}
+	// extend testprotos.Message1 { optional testprotos.Enum1 enum_field = 12; }
+	E_EnumField = &xxx_File_test_proto_extDescs[1]
 
-var E_MessageField = &proto.ExtensionDesc{
-	ExtendedType:  (*Message1)(nil),
-	ExtensionType: (*Message2)(nil),
-	Field:         13,
-	Name:          "testprotos.message_field",
-	Tag:           "bytes,13,opt,name=message_field",
-	Filename:      "test.proto",
-}
+	// extend testprotos.Message1 { optional testprotos.Message2 message_field = 13; }
+	E_MessageField = &xxx_File_test_proto_extDescs[2]
 
-var E_Message4_MessageField = &proto.ExtensionDesc{
-	ExtendedType:  (*Message1)(nil),
-	ExtensionType: (*Message2)(nil),
-	Field:         21,
-	Name:          "testprotos.Message4.message_field",
-	Tag:           "bytes,21,opt,name=message_field",
-	Filename:      "test.proto",
-}
+	// extend testprotos.Message1 { optional testprotos.Message2 message_field = 21; }
+	E_Message4_MessageField = &xxx_File_test_proto_extDescs[3]
 
-var E_Message4_EnumField = &proto.ExtensionDesc{
-	ExtendedType:  (*Message1)(nil),
-	ExtensionType: (*Enum1)(nil),
-	Field:         22,
-	Name:          "testprotos.Message4.enum_field",
-	Tag:           "varint,22,opt,name=enum_field,enum=testprotos.Enum1",
-	Filename:      "test.proto",
-}
+	// extend testprotos.Message1 { optional testprotos.Enum1 enum_field = 22; }
+	E_Message4_EnumField = &xxx_File_test_proto_extDescs[4]
 
-var E_Message4_StringField = &proto.ExtensionDesc{
-	ExtendedType:  (*Message1)(nil),
-	ExtensionType: (*string)(nil),
-	Field:         23,
-	Name:          "testprotos.Message4.string_field",
-	Tag:           "bytes,23,opt,name=string_field",
-	Filename:      "test.proto",
-}
+	// extend testprotos.Message1 { optional string string_field = 23; }
+	E_Message4_StringField = &xxx_File_test_proto_extDescs[5]
+)
 
 func init() {
 	proto.RegisterFile("test.proto", xxx_File_test_proto_rawdesc_gzipped)
@@ -459,6 +475,7 @@
 		RawDescriptor:        xxx_File_test_proto_rawdesc,
 		GoTypes:              xxx_File_test_proto_goTypes,
 		DependencyIndexes:    xxx_File_test_proto_depIdxs,
+		LegacyExtensions:     xxx_File_test_proto_extDescs,
 		EnumOutputTypes:      xxx_File_test_proto_enumTypes,
 		MessageOutputTypes:   messageTypes,
 		ExtensionOutputTypes: extensionTypes,
@@ -468,12 +485,6 @@
 		xxx_File_test_proto_messageTypes[i].GoType = reflect.TypeOf(messageGoTypes[i])
 		xxx_File_test_proto_messageTypes[i].PBType = mt
 	}
-	E_StringField.Type = extensionTypes[0]
-	E_EnumField.Type = extensionTypes[1]
-	E_MessageField.Type = extensionTypes[2]
-	E_Message4_MessageField.Type = extensionTypes[3]
-	E_Message4_EnumField.Type = extensionTypes[4]
-	E_Message4_StringField.Type = extensionTypes[5]
 	xxx_File_test_proto_goTypes = nil
 	xxx_File_test_proto_depIdxs = nil
 }