encoding/jsonpb: add support for unmarshaling Any

Also added json.Decoder.Clone API for unmarshaling Any to look
ahead remaining bytes for @type field.

Change-Id: I2f803743534dfb64f9092d716805b115faa5975a
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/170102
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/encoding/jsonpb/encode_test.go b/encoding/jsonpb/encode_test.go
index e9bf571..005de06 100644
--- a/encoding/jsonpb/encode_test.go
+++ b/encoding/jsonpb/encode_test.go
@@ -1509,7 +1509,7 @@
 		input: &knownpb.Any{},
 		want:  `{}`,
 	}, {
-		desc: "Any",
+		desc: "Any with non-custom message",
 		mo: jsonpb.MarshalOptions{
 			Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
 		},
@@ -1537,7 +1537,7 @@
   }
 }`,
 	}, {
-		desc: "Any without value",
+		desc: "Any with empty embedded message",
 		mo: jsonpb.MarshalOptions{
 			Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
 		},
@@ -1546,11 +1546,9 @@
   "@type": "foo/pb2.Nested"
 }`,
 	}, {
-		desc: "Any without registered type",
-		mo:   jsonpb.MarshalOptions{Resolver: preg.NewTypes()},
-		input: func() proto.Message {
-			return &knownpb.Any{TypeUrl: "foo/pb2.Nested"}
-		}(),
+		desc:    "Any without registered type",
+		mo:      jsonpb.MarshalOptions{Resolver: preg.NewTypes()},
+		input:   &knownpb.Any{TypeUrl: "foo/pb2.Nested"},
 		wantErr: true,
 	}, {
 		desc: "Any with missing required error",
@@ -1578,6 +1576,31 @@
 }`,
 		wantErr: true,
 	}, {
+		desc: "Any with partial required and AllowPartial",
+		mo: jsonpb.MarshalOptions{
+			AllowPartial: true,
+			Resolver:     preg.NewTypes((&pb2.PartialRequired{}).ProtoReflect().Type()),
+		},
+		input: func() proto.Message {
+			m := &pb2.PartialRequired{
+				OptString: scalar.String("embedded inside Any"),
+			}
+			b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
+			// TODO: Marshal may fail due to required field not set at some
+			// point. Need to ignore required not set error here.
+			if err != nil {
+				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
+			}
+			return &knownpb.Any{
+				TypeUrl: string(m.ProtoReflect().Type().FullName()),
+				Value:   b,
+			}
+		}(),
+		want: `{
+  "@type": "pb2.PartialRequired",
+  "optString": "embedded inside Any"
+}`,
+	}, {
 		desc: "Any with invalid UTF8",
 		mo: jsonpb.MarshalOptions{
 			Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
@@ -1672,6 +1695,63 @@
 }`,
 		wantErr: true,
 	}, {
+		desc: "Any with Int64Value",
+		mo: jsonpb.MarshalOptions{
+			Resolver: preg.NewTypes((&knownpb.Int64Value{}).ProtoReflect().Type()),
+		},
+		input: func() proto.Message {
+			m := &knownpb.Int64Value{Value: 42}
+			b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
+			if err != nil {
+				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
+			}
+			return &knownpb.Any{
+				TypeUrl: "google.protobuf.Int64Value",
+				Value:   b,
+			}
+		}(),
+		want: `{
+  "@type": "google.protobuf.Int64Value",
+  "value": "42"
+}`,
+	}, {
+		desc: "Any with Duration",
+		mo: jsonpb.MarshalOptions{
+			Resolver: preg.NewTypes((&knownpb.Duration{}).ProtoReflect().Type()),
+		},
+		input: func() proto.Message {
+			m := &knownpb.Duration{}
+			b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
+			if err != nil {
+				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
+			}
+			return &knownpb.Any{
+				TypeUrl: "type.googleapis.com/google.protobuf.Duration",
+				Value:   b,
+			}
+		}(),
+		want: `{
+  "@type": "type.googleapis.com/google.protobuf.Duration",
+  "value": "0s"
+}`,
+	}, {
+		desc: "Any with empty Value",
+		mo: jsonpb.MarshalOptions{
+			Resolver: preg.NewTypes((&knownpb.Value{}).ProtoReflect().Type()),
+		},
+		input: func() proto.Message {
+			m := &knownpb.Value{}
+			b, err := proto.Marshal(m)
+			if err != nil {
+				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
+			}
+			return &knownpb.Any{
+				TypeUrl: "type.googleapis.com/google.protobuf.Value",
+				Value:   b,
+			}
+		}(),
+		wantErr: true,
+	}, {
 		desc: "Any with Value of StringValue",
 		mo: jsonpb.MarshalOptions{
 			Resolver: preg.NewTypes((&knownpb.Value{}).ProtoReflect().Type()),
@@ -1693,13 +1773,13 @@
 }`,
 		wantErr: true,
 	}, {
-		desc: "Any with empty Value",
+		desc: "Any with Value of NullValue",
 		mo: jsonpb.MarshalOptions{
 			Resolver: preg.NewTypes((&knownpb.Value{}).ProtoReflect().Type()),
 		},
 		input: func() proto.Message {
-			m := &knownpb.Value{}
-			b, err := proto.Marshal(m)
+			m := &knownpb.Value{Kind: &knownpb.Value_NullValue{}}
+			b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
 			if err != nil {
 				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
 			}
@@ -1708,26 +1788,9 @@
 				Value:   b,
 			}
 		}(),
-		wantErr: true,
-	}, {
-		desc: "Any with Duration",
-		mo: jsonpb.MarshalOptions{
-			Resolver: preg.NewTypes((&knownpb.Duration{}).ProtoReflect().Type()),
-		},
-		input: func() proto.Message {
-			m := &knownpb.Duration{}
-			b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
-			if err != nil {
-				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
-			}
-			return &knownpb.Any{
-				TypeUrl: "type.googleapis.com/google.protobuf.Duration",
-				Value:   b,
-			}
-		}(),
 		want: `{
-  "@type": "type.googleapis.com/google.protobuf.Duration",
-  "value": "0s"
+  "@type": "type.googleapis.com/google.protobuf.Value",
+  "value": null
 }`,
 	}, {
 		desc: "Any with Struct",
@@ -1778,6 +1841,22 @@
   }
 }`,
 	}, {
+		desc: "Any with missing type_url",
+		mo: jsonpb.MarshalOptions{
+			Resolver: preg.NewTypes((&knownpb.BoolValue{}).ProtoReflect().Type()),
+		},
+		input: func() proto.Message {
+			m := &knownpb.BoolValue{Value: true}
+			b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
+			if err != nil {
+				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
+			}
+			return &knownpb.Any{
+				Value: b,
+			}
+		}(),
+		wantErr: true,
+	}, {
 		desc: "well known types as field values",
 		mo: jsonpb.MarshalOptions{
 			Resolver: preg.NewTypes((&knownpb.Empty{}).ProtoReflect().Type()),