internal/impl: pass *coderFieldInfo into fast-path functions

Refactor the fast-path size, marshal, unmarshal, and isinit functions to
take the *coderFieldInfo for the field as input.

This replaces a number of closures capturing field-specific information
with functions taking that information as an explicit parameter.

Change-Id: I8cb39701265edb7b673f6f04a0152d5f4dbb4d5d
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/218937
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/internal/impl/codec_message.go b/internal/impl/codec_message.go
index 24a87a0..cd4ebe6 100644
--- a/internal/impl/codec_message.go
+++ b/internal/impl/codec_message.go
@@ -35,13 +35,15 @@
 
 type coderFieldInfo struct {
 	funcs      pointerCoderFuncs // fast-path per-field functions
-	validation validationInfo    // information used by message validation
-	num        pref.FieldNumber  // field number
-	offset     offset            // struct field offset
-	wiretag    uint64            // field tag (number + wire type)
-	tagsize    int               // size of the varint-encoded tag
-	isPointer  bool              // true if IsNil may be called on the struct field
-	isRequired bool              // true if field is required
+	mi         *MessageInfo      // field's message
+	ft         reflect.Type
+	validation validationInfo   // information used by message validation
+	num        pref.FieldNumber // field number
+	offset     offset           // struct field offset
+	wiretag    uint64           // field tag (number + wire type)
+	tagsize    int              // size of the varint-encoded tag
+	isPointer  bool             // true if IsNil may be called on the struct field
+	isRequired bool             // true if field is required
 }
 
 func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) {
@@ -67,6 +69,7 @@
 		}
 		var fieldOffset offset
 		var funcs pointerCoderFuncs
+		var childMessage *MessageInfo
 		switch {
 		case fd.ContainingOneof() != nil:
 			fieldOffset = offsetOf(fs, mi.Exporter)
@@ -75,14 +78,16 @@
 			funcs = makeWeakMessageFieldCoder(fd)
 		default:
 			fieldOffset = offsetOf(fs, mi.Exporter)
-			funcs = fieldCoder(fd, ft)
+			childMessage, funcs = fieldCoder(fd, ft)
 		}
 		cf := &coderFieldInfo{
 			num:        fd.Number(),
 			offset:     fieldOffset,
 			wiretag:    wiretag,
+			ft:         ft,
 			tagsize:    wire.SizeVarint(wiretag),
 			funcs:      funcs,
+			mi:         childMessage,
 			validation: newFieldValidationInfo(mi, si, fd, ft),
 			isPointer: (fd.Cardinality() == pref.Repeated ||
 				fd.Kind() == pref.MessageKind ||