diff --git a/csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs b/csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs
index c05cb0853fc8c..771f1f41ba39e 100644
--- a/csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs
+++ b/csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs
@@ -30,8 +30,11 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
+using Google.Protobuf.Reflection;
using Google.Protobuf.TestProtos;
using NUnit.Framework;
+using System.Linq;
+using UnitTest.Issues.TestProtos;
namespace Google.Protobuf.WellKnownTypes
{
@@ -148,10 +151,34 @@ public void IsWrongType()
Assert.False(any.Is(TestOneof.Descriptor));
}
+ [Test]
public void IsRightType()
{
var any = Any.Pack(SampleMessages.CreateFullTestAllTypes());
Assert.True(any.Is(TestAllTypes.Descriptor));
}
+
+ [Test]
+ public void Unpack_TypeRegistry()
+ {
+ var messages = new IMessage[]
+ {
+ SampleMessages.CreateFullTestAllTypes(),
+ new TestWellKnownTypes { BoolField = true },
+ new MoreString { Data = { "x" } },
+ new MoreBytes { Data = ByteString.CopyFromUtf8("xyz") },
+ new ReservedNames { Descriptor_ = 10 }
+ };
+ var anyMessages = messages.Select(Any.Pack);
+
+ // The type registry handles the first four of the packed messages, but not the final one.
+ var registry = TypeRegistry.FromFiles(
+ UnittestWellKnownTypesReflection.Descriptor,
+ UnittestProto3Reflection.Descriptor);
+ var unpacked = anyMessages.Select(any => any.Unpack(registry)).ToList();
+ var expected = (IMessage[]) messages.Clone();
+ expected[4] = null;
+ Assert.AreEqual(expected, unpacked);
+ }
}
}
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs b/csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs
index 5e7b6d5a1ee57..cbb08d8b02f0d 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs
@@ -120,6 +120,26 @@ public bool Is(MessageDescriptor descriptor)
return true;
}
+ ///
+ /// Attempts to unpack the content of this Any message into one of the message types
+ /// in the given type registry, based on the type URL.
+ ///
+ /// The type registry to consult for messages.
+ /// The unpacked message, or null if no matching message was found.
+ public IMessage Unpack(TypeRegistry registry)
+ {
+ string typeName = GetTypeName(TypeUrl);
+ MessageDescriptor descriptor = registry.Find(typeName);
+ if (descriptor == null)
+ {
+ return null;
+ }
+
+ var message = descriptor.Parser.CreateTemplate();
+ message.MergeFrom(Value);
+ return message;
+ }
+
///
/// Packs the specified message into an Any message using a type URL prefix of "type.googleapis.com".
///