proto: add IsInitialized

Move all checks for required fields into a proto.IsInitialized function.

Initial testing makes me confident that we can provide a fast-path
implementation of IsInitialized which will perform more than
acceptably.  (In the degenerate-but-common case where a message
transitively contains no required fields, this check can be nearly
zero cost.)

Unifying checks into a single function provides consistent behavior
between the wire, text, and json codecs.

Performing the check after decoding eliminates the wire decoder bug
where a split message is incorrectly seen as missing required fields.

Performing the check after decoding also provides consistent and
arguably more correct behavior when the target message was partially
prepopulated.

Change-Id: I9478b7bebb263af00c0d9f66a1f26e31ff553522
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/170787
Reviewed-by: Herbie Ong <herbie@google.com>
diff --git a/proto/decode_test.go b/proto/decode_test.go
index 0a94b8a..dda4db1 100644
--- a/proto/decode_test.go
+++ b/proto/decode_test.go
@@ -944,23 +944,20 @@
 			}),
 		}.Marshal(),
 	},
-	// TODO: Handle this case.
-	/*
-		{
-			desc: "required field in optional message set (split across multiple tags)",
-			decodeTo: []proto.Message{&testpb.TestRequiredForeign{
-				OptionalMessage: &testpb.TestRequired{
-					RequiredField: scalar.Int32(1),
-				},
-			}},
-			wire: pack.Message{
-				pack.Tag{1, pack.BytesType}, pack.LengthPrefix(pack.Message{}),
-				pack.Tag{1, pack.BytesType}, pack.LengthPrefix(pack.Message{
-					pack.Tag{1, pack.VarintType}, pack.Varint(1),
-				}),
-			}.Marshal(),
-		},
-	*/
+	{
+		desc: "required field in optional message set (split across multiple tags)",
+		decodeTo: []proto.Message{&testpb.TestRequiredForeign{
+			OptionalMessage: &testpb.TestRequired{
+				RequiredField: scalar.Int32(1),
+			},
+		}},
+		wire: pack.Message{
+			pack.Tag{1, pack.BytesType}, pack.LengthPrefix(pack.Message{}),
+			pack.Tag{1, pack.BytesType}, pack.LengthPrefix(pack.Message{
+				pack.Tag{1, pack.VarintType}, pack.Varint(1),
+			}),
+		}.Marshal(),
+	},
 	{
 		desc:    "required field in repeated message unset",
 		partial: true,