internal/impl: pass ExtensionTypeDescriptor to extensionMap

The layers freely convert between ExtensionTypeDescriptor (via
ExtensionTypeDescriptor.Type) and ExtensionType (via
ExtensionType.TypeDescriptor()). For certain hot functions , like
(*extensionMap).Has() and (*extensionMap).Get(), this saves a Type() and
TypeDescriptor() pair.

Oddly, the gains are bigger than I expected. This commit is
02-typedesciptor-not-type, it is layered on top of CL 576315
(named 01-cse-hasextension):

    benchstat 00-cse-messageinfo 01-cse-hasextension 02-typedesciptor-not-type
    goarch: amd64
    cpu: AMD Ryzen Threadripper PRO 3995WX 64-Cores
                          │ 00-cse-messageinfo │         01-cse-hasextension         │      02-typedesciptor-not-type      │
                          │       sec/op       │    sec/op     vs base               │   sec/op     vs base                │
    Extension/Has/None-12         103.30n ± 3%    96.73n ± 1%  -6.36% (p=0.000 n=10)   85.54n ± 2%  -17.19% (p=0.000 n=10)
    Extension/Has/Set-12          113.05n ± 3%   107.15n ± 1%  -5.22% (p=0.000 n=10)   97.36n ± 2%  -13.88% (p=0.000 n=10)
    Extension/Get/None-12          182.7n ± 2%    176.3n ± 2%  -3.48% (p=0.000 n=10)   173.3n ± 2%   -5.09% (p=0.000 n=10)
    Extension/Get/Set-12           140.1n ± 2%    138.0n ± 1%  -1.46% (p=0.024 n=10)   135.0n ± 1%   -3.64% (p=0.000 n=10)
    Extension/Set-12               218.6n ± 2%    219.5n ± 1%       ~ (p=0.172 n=10)   210.2n ± 2%   -3.82% (p=0.001 n=10)
    geomean                        145.6n         140.8n       -3.25%                  132.6n        -8.91%

Change-Id: If9c67c680ca57b5d93f863bb1c72f3e5031ed18c
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/576316
Reviewed-by: Michael Stapelberg <stapelberg@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Nicolas Hillegeer <aktau@google.com>
diff --git a/internal/cmd/generate-types/impl.go b/internal/cmd/generate-types/impl.go
index 2d33777..13d510d 100644
--- a/internal/cmd/generate-types/impl.go
+++ b/internal/cmd/generate-types/impl.go
@@ -783,55 +783,55 @@
 func (m *{{.}}) Has(fd protoreflect.FieldDescriptor) bool {
 	mi := m.messageInfo()
 	mi.init()
-	if fi, xt := mi.checkField(fd); fi != nil {
+	if fi, xd := mi.checkField(fd); fi != nil {
 		return fi.has(m.pointer())
 	} else {
-		return mi.extensionMap(m.pointer()).Has(xt)
+		return mi.extensionMap(m.pointer()).Has(xd)
 	}
 }
 func (m *{{.}}) Clear(fd protoreflect.FieldDescriptor) {
 	mi := m.messageInfo()
 	mi.init()
-	if fi, xt := mi.checkField(fd); fi != nil {
+	if fi, xd := mi.checkField(fd); fi != nil {
 		fi.clear(m.pointer())
 	} else {
-		mi.extensionMap(m.pointer()).Clear(xt)
+		mi.extensionMap(m.pointer()).Clear(xd)
 	}
 }
 func (m *{{.}}) Get(fd protoreflect.FieldDescriptor) protoreflect.Value {
 	mi := m.messageInfo()
 	mi.init()
-	if fi, xt := mi.checkField(fd); fi != nil {
+	if fi, xd := mi.checkField(fd); fi != nil {
 		return fi.get(m.pointer())
 	} else {
-		return mi.extensionMap(m.pointer()).Get(xt)
+		return mi.extensionMap(m.pointer()).Get(xd)
 	}
 }
 func (m *{{.}}) Set(fd protoreflect.FieldDescriptor, v protoreflect.Value) {
 	mi := m.messageInfo()
 	mi.init()
-	if fi, xt := mi.checkField(fd); fi != nil {
+	if fi, xd := mi.checkField(fd); fi != nil {
 		fi.set(m.pointer(), v)
 	} else {
-		mi.extensionMap(m.pointer()).Set(xt, v)
+		mi.extensionMap(m.pointer()).Set(xd, v)
 	}
 }
 func (m *{{.}}) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value {
 	mi := m.messageInfo()
 	mi.init()
-	if fi, xt := mi.checkField(fd); fi != nil {
+	if fi, xd := mi.checkField(fd); fi != nil {
 		return fi.mutable(m.pointer())
 	} else {
-		return mi.extensionMap(m.pointer()).Mutable(xt)
+		return mi.extensionMap(m.pointer()).Mutable(xd)
 	}
 }
 func (m *{{.}}) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value {
 	mi := m.messageInfo()
 	mi.init()
-	if fi, xt := mi.checkField(fd); fi != nil {
+	if fi, xd := mi.checkField(fd); fi != nil {
 		return fi.newField()
 	} else {
-		return xt.New()
+		return xd.Type().New()
 	}
 }
 func (m *{{.}}) WhichOneof(od protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
diff --git a/internal/impl/message_reflect.go b/internal/impl/message_reflect.go
index c138f4a..a6f0dbd 100644
--- a/internal/impl/message_reflect.go
+++ b/internal/impl/message_reflect.go
@@ -247,11 +247,10 @@
 		}
 	}
 }
-func (m *extensionMap) Has(xt protoreflect.ExtensionType) (ok bool) {
+func (m *extensionMap) Has(xd protoreflect.ExtensionTypeDescriptor) (ok bool) {
 	if m == nil {
 		return false
 	}
-	xd := xt.TypeDescriptor()
 	x, ok := (*m)[int32(xd.Number())]
 	if !ok {
 		return false
@@ -264,20 +263,19 @@
 	}
 	return true
 }
-func (m *extensionMap) Clear(xt protoreflect.ExtensionType) {
-	delete(*m, int32(xt.TypeDescriptor().Number()))
+func (m *extensionMap) Clear(xd protoreflect.ExtensionTypeDescriptor) {
+	delete(*m, int32(xd.Number()))
 }
-func (m *extensionMap) Get(xt protoreflect.ExtensionType) protoreflect.Value {
-	xd := xt.TypeDescriptor()
+func (m *extensionMap) Get(xd protoreflect.ExtensionTypeDescriptor) protoreflect.Value {
 	if m != nil {
 		if x, ok := (*m)[int32(xd.Number())]; ok {
 			return x.Value()
 		}
 	}
-	return xt.Zero()
+	return xd.Type().Zero()
 }
-func (m *extensionMap) Set(xt protoreflect.ExtensionType, v protoreflect.Value) {
-	xd := xt.TypeDescriptor()
+func (m *extensionMap) Set(xd protoreflect.ExtensionTypeDescriptor, v protoreflect.Value) {
+	xt := xd.Type()
 	isValid := true
 	switch {
 	case !xt.IsValidValue(v):
@@ -290,7 +288,7 @@
 		isValid = v.Message().IsValid()
 	}
 	if !isValid {
-		panic(fmt.Sprintf("%v: assigning invalid value", xt.TypeDescriptor().FullName()))
+		panic(fmt.Sprintf("%v: assigning invalid value", xd.FullName()))
 	}
 
 	if *m == nil {
@@ -300,16 +298,15 @@
 	x.Set(xt, v)
 	(*m)[int32(xd.Number())] = x
 }
-func (m *extensionMap) Mutable(xt protoreflect.ExtensionType) protoreflect.Value {
-	xd := xt.TypeDescriptor()
+func (m *extensionMap) Mutable(xd protoreflect.ExtensionTypeDescriptor) protoreflect.Value {
 	if xd.Kind() != protoreflect.MessageKind && xd.Kind() != protoreflect.GroupKind && !xd.IsList() && !xd.IsMap() {
 		panic("invalid Mutable on field with non-composite type")
 	}
 	if x, ok := (*m)[int32(xd.Number())]; ok {
 		return x.Value()
 	}
-	v := xt.New()
-	m.Set(xt, v)
+	v := xd.Type().New()
+	m.Set(xd, v)
 	return v
 }
 
@@ -426,7 +423,7 @@
 
 // checkField verifies that the provided field descriptor is valid.
 // Exactly one of the returned values is populated.
-func (mi *MessageInfo) checkField(fd protoreflect.FieldDescriptor) (*fieldInfo, protoreflect.ExtensionType) {
+func (mi *MessageInfo) checkField(fd protoreflect.FieldDescriptor) (*fieldInfo, protoreflect.ExtensionTypeDescriptor) {
 	var fi *fieldInfo
 	if n := fd.Number(); 0 < n && int(n) < len(mi.denseFields) {
 		fi = mi.denseFields[n]
@@ -455,7 +452,7 @@
 		if !ok {
 			panic(fmt.Sprintf("extension %v does not implement protoreflect.ExtensionTypeDescriptor", fd.FullName()))
 		}
-		return nil, xtd.Type()
+		return nil, xtd
 	}
 	panic(fmt.Sprintf("field %v is invalid", fd.FullName()))
 }
diff --git a/internal/impl/message_reflect_gen.go b/internal/impl/message_reflect_gen.go
index b10033e..29ba6bd 100644
--- a/internal/impl/message_reflect_gen.go
+++ b/internal/impl/message_reflect_gen.go
@@ -66,55 +66,55 @@
 func (m *messageState) Has(fd protoreflect.FieldDescriptor) bool {
 	mi := m.messageInfo()
 	mi.init()
-	if fi, xt := mi.checkField(fd); fi != nil {
+	if fi, xd := mi.checkField(fd); fi != nil {
 		return fi.has(m.pointer())
 	} else {
-		return mi.extensionMap(m.pointer()).Has(xt)
+		return mi.extensionMap(m.pointer()).Has(xd)
 	}
 }
 func (m *messageState) Clear(fd protoreflect.FieldDescriptor) {
 	mi := m.messageInfo()
 	mi.init()
-	if fi, xt := mi.checkField(fd); fi != nil {
+	if fi, xd := mi.checkField(fd); fi != nil {
 		fi.clear(m.pointer())
 	} else {
-		mi.extensionMap(m.pointer()).Clear(xt)
+		mi.extensionMap(m.pointer()).Clear(xd)
 	}
 }
 func (m *messageState) Get(fd protoreflect.FieldDescriptor) protoreflect.Value {
 	mi := m.messageInfo()
 	mi.init()
-	if fi, xt := mi.checkField(fd); fi != nil {
+	if fi, xd := mi.checkField(fd); fi != nil {
 		return fi.get(m.pointer())
 	} else {
-		return mi.extensionMap(m.pointer()).Get(xt)
+		return mi.extensionMap(m.pointer()).Get(xd)
 	}
 }
 func (m *messageState) Set(fd protoreflect.FieldDescriptor, v protoreflect.Value) {
 	mi := m.messageInfo()
 	mi.init()
-	if fi, xt := mi.checkField(fd); fi != nil {
+	if fi, xd := mi.checkField(fd); fi != nil {
 		fi.set(m.pointer(), v)
 	} else {
-		mi.extensionMap(m.pointer()).Set(xt, v)
+		mi.extensionMap(m.pointer()).Set(xd, v)
 	}
 }
 func (m *messageState) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value {
 	mi := m.messageInfo()
 	mi.init()
-	if fi, xt := mi.checkField(fd); fi != nil {
+	if fi, xd := mi.checkField(fd); fi != nil {
 		return fi.mutable(m.pointer())
 	} else {
-		return mi.extensionMap(m.pointer()).Mutable(xt)
+		return mi.extensionMap(m.pointer()).Mutable(xd)
 	}
 }
 func (m *messageState) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value {
 	mi := m.messageInfo()
 	mi.init()
-	if fi, xt := mi.checkField(fd); fi != nil {
+	if fi, xd := mi.checkField(fd); fi != nil {
 		return fi.newField()
 	} else {
-		return xt.New()
+		return xd.Type().New()
 	}
 }
 func (m *messageState) WhichOneof(od protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
@@ -197,55 +197,55 @@
 func (m *messageReflectWrapper) Has(fd protoreflect.FieldDescriptor) bool {
 	mi := m.messageInfo()
 	mi.init()
-	if fi, xt := mi.checkField(fd); fi != nil {
+	if fi, xd := mi.checkField(fd); fi != nil {
 		return fi.has(m.pointer())
 	} else {
-		return mi.extensionMap(m.pointer()).Has(xt)
+		return mi.extensionMap(m.pointer()).Has(xd)
 	}
 }
 func (m *messageReflectWrapper) Clear(fd protoreflect.FieldDescriptor) {
 	mi := m.messageInfo()
 	mi.init()
-	if fi, xt := mi.checkField(fd); fi != nil {
+	if fi, xd := mi.checkField(fd); fi != nil {
 		fi.clear(m.pointer())
 	} else {
-		mi.extensionMap(m.pointer()).Clear(xt)
+		mi.extensionMap(m.pointer()).Clear(xd)
 	}
 }
 func (m *messageReflectWrapper) Get(fd protoreflect.FieldDescriptor) protoreflect.Value {
 	mi := m.messageInfo()
 	mi.init()
-	if fi, xt := mi.checkField(fd); fi != nil {
+	if fi, xd := mi.checkField(fd); fi != nil {
 		return fi.get(m.pointer())
 	} else {
-		return mi.extensionMap(m.pointer()).Get(xt)
+		return mi.extensionMap(m.pointer()).Get(xd)
 	}
 }
 func (m *messageReflectWrapper) Set(fd protoreflect.FieldDescriptor, v protoreflect.Value) {
 	mi := m.messageInfo()
 	mi.init()
-	if fi, xt := mi.checkField(fd); fi != nil {
+	if fi, xd := mi.checkField(fd); fi != nil {
 		fi.set(m.pointer(), v)
 	} else {
-		mi.extensionMap(m.pointer()).Set(xt, v)
+		mi.extensionMap(m.pointer()).Set(xd, v)
 	}
 }
 func (m *messageReflectWrapper) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value {
 	mi := m.messageInfo()
 	mi.init()
-	if fi, xt := mi.checkField(fd); fi != nil {
+	if fi, xd := mi.checkField(fd); fi != nil {
 		return fi.mutable(m.pointer())
 	} else {
-		return mi.extensionMap(m.pointer()).Mutable(xt)
+		return mi.extensionMap(m.pointer()).Mutable(xd)
 	}
 }
 func (m *messageReflectWrapper) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value {
 	mi := m.messageInfo()
 	mi.init()
-	if fi, xt := mi.checkField(fd); fi != nil {
+	if fi, xd := mi.checkField(fd); fi != nil {
 		return fi.newField()
 	} else {
-		return xt.New()
+		return xd.Type().New()
 	}
 }
 func (m *messageReflectWrapper) WhichOneof(od protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {