internal/impl: better fast-path init checks for extensions

Unknown extensions are initialized.

Valid extensions with no isInit func are initialized.

Change-Id: I2975c7ef85d2b777eca467d3b1861d20de8e24fc
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/216960
Reviewed-by: Joe Tsai <joetsai@google.com>
diff --git a/internal/impl/decode.go b/internal/impl/decode.go
index 48f7ca5..290fc41 100644
--- a/internal/impl/decode.go
+++ b/internal/impl/decode.go
@@ -140,6 +140,9 @@
 			}
 			var o unmarshalOutput
 			o, err = mi.unmarshalExtension(b, num, wtyp, *exts, opts)
+			if err != nil {
+				break
+			}
 			n = o.n
 			if !o.initialized {
 				initialized = false
@@ -213,6 +216,9 @@
 	if err != nil {
 		return out, err
 	}
+	if xi.funcs.isInit == nil {
+		out.initialized = true
+	}
 	x.Set(xt, v)
 	exts[int32(num)] = x
 	return out, nil
diff --git a/proto/testmessages_test.go b/proto/testmessages_test.go
index d7f5523..aed622d 100644
--- a/proto/testmessages_test.go
+++ b/proto/testmessages_test.go
@@ -32,7 +32,8 @@
 
 var testValidMessages = []testProto{
 	{
-		desc: "basic scalar types",
+		desc:          "basic scalar types",
+		checkFastInit: true,
 		decodeTo: []proto.Message{&testpb.TestAllTypes{
 			OptionalInt32:      proto.Int32(1001),
 			OptionalInt64:      proto.Int64(1002),
@@ -1106,7 +1107,8 @@
 	// considers equivalent to those of the v1 decoder. Figure out if
 	// that's a problem or not.
 	{
-		desc: "unknown fields",
+		desc:          "unknown fields",
+		checkFastInit: true,
 		decodeTo: []proto.Message{build(
 			&testpb.TestAllTypes{},
 			unknown(pack.Message{
@@ -1117,6 +1119,11 @@
 			unknown(pack.Message{
 				pack.Tag{100000, pack.VarintType}, pack.Varint(1),
 			}.Marshal()),
+		), build(
+			&testpb.TestAllExtensions{},
+			unknown(pack.Message{
+				pack.Tag{100000, pack.VarintType}, pack.Varint(1),
+			}.Marshal()),
 		)},
 		wire: pack.Message{
 			pack.Tag{100000, pack.VarintType}, pack.Varint(1),