internal/impl: omit isInit func when not needed

When generating the fast-path functions for a message, group, repeated
message, or repeated group field, check to see if the field message type
requires initialization checks. If not, leave the isInit func unset.

This permits the fast-path isInitialized to skip over these fields
entirely.

Change-Id: Icb5c380077d2216c4215bb0ebc16408e905aaece
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/214179
Reviewed-by: Joe Tsai <joetsai@google.com>
diff --git a/internal/impl/codec_field.go b/internal/impl/codec_field.go
index 366034c..3f3957c 100644
--- a/internal/impl/codec_field.go
+++ b/internal/impl/codec_field.go
@@ -164,7 +164,7 @@
 
 func makeMessageFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
 	if mi := getMessageInfo(ft); mi != nil {
-		return pointerCoderFuncs{
+		funcs := pointerCoderFuncs{
 			size: func(p pointer, tagsize int, opts marshalOptions) int {
 				return sizeMessageInfo(p, mi, tagsize, opts)
 			},
@@ -174,10 +174,13 @@
 			unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (int, error) {
 				return consumeMessageInfo(b, p, mi, wtyp, opts)
 			},
-			isInit: func(p pointer) error {
-				return mi.isInitializedPointer(p.Elem())
-			},
 		}
+		if needsInitCheck(mi.Desc) {
+			funcs.isInit = func(p pointer) error {
+				return mi.isInitializedPointer(p.Elem())
+			}
+		}
+		return funcs
 	} else {
 		return pointerCoderFuncs{
 			size: func(p pointer, tagsize int, opts marshalOptions) int {
@@ -308,7 +311,7 @@
 func makeGroupFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
 	num := fd.Number()
 	if mi := getMessageInfo(ft); mi != nil {
-		return pointerCoderFuncs{
+		funcs := pointerCoderFuncs{
 			size: func(p pointer, tagsize int, opts marshalOptions) int {
 				return sizeGroupType(p, mi, tagsize, opts)
 			},
@@ -318,10 +321,13 @@
 			unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (int, error) {
 				return consumeGroupType(b, p, mi, num, wtyp, opts)
 			},
-			isInit: func(p pointer) error {
-				return mi.isInitializedPointer(p.Elem())
-			},
 		}
+		if needsInitCheck(mi.Desc) {
+			funcs.isInit = func(p pointer) error {
+				return mi.isInitializedPointer(p.Elem())
+			}
+		}
+		return funcs
 	} else {
 		return pointerCoderFuncs{
 			size: func(p pointer, tagsize int, opts marshalOptions) int {
@@ -392,7 +398,7 @@
 
 func makeMessageSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
 	if mi := getMessageInfo(ft); mi != nil {
-		return pointerCoderFuncs{
+		funcs := pointerCoderFuncs{
 			size: func(p pointer, tagsize int, opts marshalOptions) int {
 				return sizeMessageSliceInfo(p, mi, tagsize, opts)
 			},
@@ -402,10 +408,13 @@
 			unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (int, error) {
 				return consumeMessageSliceInfo(b, p, mi, wtyp, opts)
 			},
-			isInit: func(p pointer) error {
-				return isInitMessageSliceInfo(p, mi)
-			},
 		}
+		if needsInitCheck(mi.Desc) {
+			funcs.isInit = func(p pointer) error {
+				return isInitMessageSliceInfo(p, mi)
+			}
+		}
+		return funcs
 	}
 	return pointerCoderFuncs{
 		size: func(p pointer, tagsize int, opts marshalOptions) int {
@@ -644,7 +653,7 @@
 func makeGroupSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
 	num := fd.Number()
 	if mi := getMessageInfo(ft); mi != nil {
-		return pointerCoderFuncs{
+		funcs := pointerCoderFuncs{
 			size: func(p pointer, tagsize int, opts marshalOptions) int {
 				return sizeGroupSliceInfo(p, mi, tagsize, opts)
 			},
@@ -654,10 +663,13 @@
 			unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (int, error) {
 				return consumeGroupSliceInfo(b, p, num, wtyp, mi, opts)
 			},
-			isInit: func(p pointer) error {
-				return isInitMessageSliceInfo(p, mi)
-			},
 		}
+		if needsInitCheck(mi.Desc) {
+			funcs.isInit = func(p pointer) error {
+				return isInitMessageSliceInfo(p, mi)
+			}
+		}
+		return funcs
 	}
 	return pointerCoderFuncs{
 		size: func(p pointer, tagsize int, opts marshalOptions) int {