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/proto/size.go b/proto/size.go
index b881653..e2a75b6 100644
--- a/proto/size.go
+++ b/proto/size.go
@@ -54,43 +54,38 @@
 	return size
 }
 
-func sizeField(field protoreflect.FieldDescriptor, value protoreflect.Value) (size int) {
-	num := field.Number()
-	kind := field.Kind()
+func sizeField(fd protoreflect.FieldDescriptor, value protoreflect.Value) (size int) {
+	num := fd.Number()
 	switch {
-	case field.Cardinality() != protoreflect.Repeated:
-		return wire.SizeTag(num) + sizeSingular(num, kind, value)
-	case field.IsMap():
-		return sizeMap(num, kind, field.Message(), value.Map())
-	case field.IsPacked():
-		return sizePacked(num, kind, value.List())
+	case fd.IsList():
+		return sizeList(num, fd, value.List())
+	case fd.IsMap():
+		return sizeMap(num, fd, value.Map())
 	default:
-		return sizeList(num, kind, value.List())
+		return wire.SizeTag(num) + sizeSingular(num, fd.Kind(), value)
 	}
 }
 
-func sizeMap(num wire.Number, kind protoreflect.Kind, mdesc protoreflect.MessageDescriptor, mapv protoreflect.Map) (size int) {
-	keyf := mdesc.Fields().ByNumber(1)
-	valf := mdesc.Fields().ByNumber(2)
-	mapv.Range(func(key protoreflect.MapKey, value protoreflect.Value) bool {
-		size += wire.SizeTag(num)
-		size += wire.SizeBytes(sizeField(keyf, key.Value()) + sizeField(valf, value))
-		return true
-	})
+func sizeList(num wire.Number, fd protoreflect.FieldDescriptor, list protoreflect.List) (size int) {
+	if fd.IsPacked() {
+		content := 0
+		for i, llen := 0, list.Len(); i < llen; i++ {
+			content += sizeSingular(num, fd.Kind(), list.Get(i))
+		}
+		return wire.SizeTag(num) + wire.SizeBytes(content)
+	}
+
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		size += wire.SizeTag(num) + sizeSingular(num, fd.Kind(), list.Get(i))
+	}
 	return size
 }
 
-func sizePacked(num wire.Number, kind protoreflect.Kind, list protoreflect.List) (size int) {
-	content := 0
-	for i, llen := 0, list.Len(); i < llen; i++ {
-		content += sizeSingular(num, kind, list.Get(i))
-	}
-	return wire.SizeTag(num) + wire.SizeBytes(content)
-}
-
-func sizeList(num wire.Number, kind protoreflect.Kind, list protoreflect.List) (size int) {
-	for i, llen := 0, list.Len(); i < llen; i++ {
-		size += wire.SizeTag(num) + sizeSingular(num, kind, list.Get(i))
-	}
+func sizeMap(num wire.Number, fd protoreflect.FieldDescriptor, mapv protoreflect.Map) (size int) {
+	mapv.Range(func(key protoreflect.MapKey, value protoreflect.Value) bool {
+		size += wire.SizeTag(num)
+		size += wire.SizeBytes(sizeField(fd.MapKey(), key.Value()) + sizeField(fd.MapValue(), value))
+		return true
+	})
 	return size
 }