reflect/protoreflect: add helper methods to FieldDescriptor

Added API:
	FieldDescriptor.IsExtension
	FieldDescriptor.IsList
	FieldDescriptor.MapKey
	FieldDescriptor.MapValue
	FieldDescriptor.ContainingOneof
	FieldDescriptor.ContainingMessage

Deprecated API (to be removed in subsequent CL):
	FieldDescriptor.Oneof
	FieldDescriptor.Extendee

These methods help cleanup several common usage patterns.

Change-Id: I9a3ffabc2edb2173c536509b22f330f98bba7cf3
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/176977
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/internal/impl/legacy_extension.go b/internal/impl/legacy_extension.go
index a0ae3f0..7a8fea7 100644
--- a/internal/impl/legacy_extension.go
+++ b/internal/impl/legacy_extension.go
@@ -64,7 +64,7 @@
 	}
 	t := extensionTypeFromDesc(x.Desc)
 	d := t.Descriptor()
-	if d.Cardinality() == pref.Repeated {
+	if d.IsList() {
 		return t.ValueOf(x.Value).List().Len() > 0
 	}
 	return true
@@ -105,7 +105,7 @@
 	}
 	t := extensionTypeFromDesc(x.Desc)
 	d := t.Descriptor()
-	if d.Cardinality() == pref.Repeated {
+	if d.IsList() {
 		t.ValueOf(x.Value).List().Truncate(0)
 		return
 	}
@@ -153,7 +153,7 @@
 
 func (p legacyExtensionTypes) Register(t pref.ExtensionType) {
 	d := t.Descriptor()
-	if p.mi.PBType.Descriptor().FullName() != d.Extendee().FullName() {
+	if p.mi.PBType.Descriptor().FullName() != d.ContainingMessage().FullName() {
 		panic("extended type mismatch")
 	}
 	if !p.mi.PBType.Descriptor().ExtensionRanges().Has(d.Number()) {
@@ -164,7 +164,7 @@
 		panic("extension descriptor already registered")
 	}
 	x.Desc = extensionDescFromType(t)
-	if d.Cardinality() == pref.Repeated {
+	if d.IsList() {
 		// If the field is repeated, initialize the entry with an empty list
 		// so that future Get operations can return a mutable and concrete list.
 		x.Value = t.InterfaceOf(t.New())
@@ -178,7 +178,7 @@
 		return
 	}
 	x := p.x.Get(d.Number())
-	if d.Cardinality() == pref.Repeated {
+	if d.IsList() {
 		// Treat an empty repeated field as unpopulated.
 		v := reflect.ValueOf(x.Value)
 		if x.Value == nil || v.IsNil() || v.Elem().Len() == 0 {
diff --git a/internal/impl/legacy_test.go b/internal/impl/legacy_test.go
index 28ab672..d5d4e54 100644
--- a/internal/impl/legacy_test.go
+++ b/internal/impl/legacy_test.go
@@ -685,7 +685,7 @@
 								// Ignore New since it a constructor.
 							case "Options":
 								// Ignore descriptor options since protos are not cmperable.
-							case "Oneof", "Extendee", "Enum", "Message":
+							case "ContainingOneof", "ContainingMessage", "Enum", "Message":
 								// Avoid descending into a dependency to avoid a cycle.
 								// Just record the full name if available.
 								//
@@ -694,6 +694,8 @@
 								if !v.IsNil() {
 									out[name] = v.Interface().(pref.Descriptor).FullName()
 								}
+							case "Oneof", "Extendee":
+								// TODO: Remove this.
 							default:
 								out[name] = m.Call(nil)[0].Interface()
 							}
diff --git a/internal/impl/message.go b/internal/impl/message.go
index 5c2ae28..a98e7bb 100644
--- a/internal/impl/message.go
+++ b/internal/impl/message.go
@@ -118,11 +118,11 @@
 		fs := si.fieldsByNumber[fd.Number()]
 		var fi fieldInfo
 		switch {
-		case fd.Oneof() != nil:
-			fi = fieldInfoForOneof(fd, si.oneofsByName[fd.Oneof().Name()], si.oneofWrappersByNumber[fd.Number()])
+		case fd.ContainingOneof() != nil:
+			fi = fieldInfoForOneof(fd, si.oneofsByName[fd.ContainingOneof().Name()], si.oneofWrappersByNumber[fd.Number()])
 		case fd.IsMap():
 			fi = fieldInfoForMap(fd, fs)
-		case fd.Cardinality() == pref.Repeated:
+		case fd.IsList():
 			fi = fieldInfoForList(fd, fs)
 		case fd.Kind() == pref.MessageKind || fd.Kind() == pref.GroupKind:
 			fi = fieldInfoForMessage(fd, fs)
diff --git a/internal/impl/message_field.go b/internal/impl/message_field.go
index 8cd82fe..10405d0 100644
--- a/internal/impl/message_field.go
+++ b/internal/impl/message_field.go
@@ -90,8 +90,8 @@
 	if ft.Kind() != reflect.Map {
 		panic(fmt.Sprintf("invalid type: got %v, want map kind", ft))
 	}
-	keyConv := pvalue.NewLegacyConverter(ft.Key(), fd.Message().Fields().ByNumber(1).Kind(), legacyWrapper)
-	valConv := pvalue.NewLegacyConverter(ft.Elem(), fd.Message().Fields().ByNumber(2).Kind(), legacyWrapper)
+	keyConv := pvalue.NewLegacyConverter(ft.Key(), fd.MapKey().Kind(), legacyWrapper)
+	valConv := pvalue.NewLegacyConverter(ft.Elem(), fd.MapValue().Kind(), legacyWrapper)
 	fieldOffset := offsetOf(fs)
 	// TODO: Implement unsafe fast path?
 	return fieldInfo{