encoding/textpb: unmarshal Any

Also fix marshaling Any in expanded form to contain the correct type_url
value.

Change-Id: I4b467e74bb1d73255effd9cc4cfff9cf4558940f
Reviewed-on: https://go-review.googlesource.com/c/156342
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/encoding/textpb/encode_test.go b/encoding/textpb/encode_test.go
index 9871e75..15a5492 100644
--- a/encoding/textpb/encode_test.go
+++ b/encoding/textpb/encode_test.go
@@ -67,6 +67,10 @@
 	knownFields.Set(wire.Number(xd.Field), pval)
 }
 
+func wrapAnyPB(any *anypb.Any) proto.Message {
+	return impl.Export{}.MessageOf(any).Interface()
+}
+
 // dhex decodes a hex-string and returns the bytes and panics if s is invalid.
 func dhex(s string) []byte {
 	b, err := hex.DecodeString(s)
@@ -980,8 +984,10 @@
 		   `,
 		*/
 	}, {
-		desc: "google.protobuf.Any message not expanded",
-		mo:   textpb.MarshalOptions{Resolver: preg.NewTypes()},
+		desc: "Any message not expanded",
+		mo: textpb.MarshalOptions{
+			Resolver: preg.NewTypes(),
+		},
 		input: func() proto.Message {
 			m := &pb2.Nested{
 				OptString: scalar.String("embedded inside Any"),
@@ -994,21 +1000,19 @@
 			if err != nil {
 				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
 			}
-			return impl.Export{}.MessageOf(&anypb.Any{
-				TypeUrl: string(m.ProtoReflect().Type().FullName()),
+			return wrapAnyPB(&anypb.Any{
+				TypeUrl: "pb2.Nested",
 				Value:   b,
-			}).Interface()
+			})
 		}(),
 		want: `type_url: "pb2.Nested"
 value: "\n\x13embedded inside Any\x12\x0b\n\tinception"
 `,
 	}, {
-		desc: "google.protobuf.Any message expanded",
-		mo: func() textpb.MarshalOptions {
-			m := &pb2.Nested{}
-			resolver := preg.NewTypes(m.ProtoReflect().Type())
-			return textpb.MarshalOptions{Resolver: resolver}
-		}(),
+		desc: "Any message expanded",
+		mo: textpb.MarshalOptions{
+			Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
+		},
 		input: func() proto.Message {
 			m := &pb2.Nested{
 				OptString: scalar.String("embedded inside Any"),
@@ -1021,12 +1025,12 @@
 			if err != nil {
 				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
 			}
-			return impl.Export{}.MessageOf(&anypb.Any{
-				TypeUrl: string(m.ProtoReflect().Type().FullName()),
+			return wrapAnyPB(&anypb.Any{
+				TypeUrl: "foo/pb2.Nested",
 				Value:   b,
-			}).Interface()
+			})
 		}(),
-		want: `[pb2.Nested]: {
+		want: `[foo/pb2.Nested]: {
   opt_string: "embedded inside Any"
   opt_nested: {
     opt_string: "inception"
@@ -1034,12 +1038,10 @@
 }
 `,
 	}, {
-		desc: "google.protobuf.Any message expanded with missing required error",
-		mo: func() textpb.MarshalOptions {
-			m := &pb2.PartialRequired{}
-			resolver := preg.NewTypes(m.ProtoReflect().Type())
-			return textpb.MarshalOptions{Resolver: resolver}
-		}(),
+		desc: "Any message expanded with missing required error",
+		mo: textpb.MarshalOptions{
+			Resolver: preg.NewTypes((&pb2.PartialRequired{}).ProtoReflect().Type()),
+		},
 		input: func() proto.Message {
 			m := &pb2.PartialRequired{
 				OptString: scalar.String("embedded inside Any"),
@@ -1050,10 +1052,10 @@
 			if _, ok := err.(*protoV1.RequiredNotSetError); !ok {
 				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
 			}
-			return impl.Export{}.MessageOf(&anypb.Any{
+			return wrapAnyPB(&anypb.Any{
 				TypeUrl: string(m.ProtoReflect().Type().FullName()),
 				Value:   b,
-			}).Interface()
+			})
 		}(),
 		want: `[pb2.PartialRequired]: {
   opt_string: "embedded inside Any"
@@ -1061,84 +1063,17 @@
 `,
 		wantErr: true,
 	}, {
-		desc: "google.protobuf.Any message with invalid value",
-		mo: func() textpb.MarshalOptions {
-			m := &pb2.Nested{}
-			resolver := preg.NewTypes(m.ProtoReflect().Type())
-			return textpb.MarshalOptions{Resolver: resolver}
-		}(),
-		input: func() proto.Message {
-			m := &pb2.Nested{}
-			return impl.Export{}.MessageOf(&anypb.Any{
-				TypeUrl: string(m.ProtoReflect().Type().FullName()),
-				Value:   dhex("80"),
-			}).Interface()
-		}(),
-		want: `type_url: "pb2.Nested"
+		desc: "Any message with invalid value",
+		mo: textpb.MarshalOptions{
+			Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
+		},
+		input: wrapAnyPB(&anypb.Any{
+			TypeUrl: "foo/pb2.Nested",
+			Value:   dhex("80"),
+		}),
+		want: `type_url: "foo/pb2.Nested"
 value: "\x80"
 `,
-	}, {
-		desc: "google.protobuf.Any field",
-		mo:   textpb.MarshalOptions{Resolver: preg.NewTypes()},
-		input: func() proto.Message {
-			m := &pb2.Nested{
-				OptString: scalar.String("embedded inside Any"),
-				OptNested: &pb2.Nested{
-					OptString: scalar.String("inception"),
-				},
-			}
-			// TODO: Switch to V2 marshal when ready.
-			b, err := protoV1.Marshal(m)
-			if err != nil {
-				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
-			}
-			return &pb2.KnownTypes{
-				OptAny: &anypb.Any{
-					TypeUrl: string(m.ProtoReflect().Type().FullName()),
-					Value:   b,
-				},
-			}
-		}(),
-		want: `opt_any: {
-  type_url: "pb2.Nested"
-  value: "\n\x13embedded inside Any\x12\x0b\n\tinception"
-}
-`,
-	}, {
-		desc: "google.protobuf.Any field expanded using given types registry",
-		mo: func() textpb.MarshalOptions {
-			m := &pb2.Nested{}
-			resolver := preg.NewTypes(m.ProtoReflect().Type())
-			return textpb.MarshalOptions{Resolver: resolver}
-		}(),
-		input: func() proto.Message {
-			m := &pb2.Nested{
-				OptString: scalar.String("embedded inside Any"),
-				OptNested: &pb2.Nested{
-					OptString: scalar.String("inception"),
-				},
-			}
-			// TODO: Switch to V2 marshal when ready.
-			b, err := protoV1.Marshal(m)
-			if err != nil {
-				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
-			}
-			return &pb2.KnownTypes{
-				OptAny: &anypb.Any{
-					TypeUrl: string(m.ProtoReflect().Type().FullName()),
-					Value:   b,
-				},
-			}
-		}(),
-		want: `opt_any: {
-  [pb2.Nested]: {
-    opt_string: "embedded inside Any"
-    opt_nested: {
-      opt_string: "inception"
-    }
-  }
-}
-`,
 	}}
 
 	for _, tt := range tests {