Skip to content

Commit e50461d

Browse files
committed
Pack/Unpack implementation for Any.
We still need the JSON representation, which relies on something like a DescriptorPool to fetch message types from based on the type URL. That will come a bit later. (The DescriptorPool comment in this commit is just a note which will prove useful if we use DescriptorPool itself.)
1 parent 4cb0edd commit e50461d

File tree

6 files changed

+151
-0
lines changed

6 files changed

+151
-0
lines changed

Makefile.am

+2
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ csharp_EXTRA_DIST= \
9595
csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs \
9696
csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs \
9797
csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs \
98+
csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs \
9899
csharp/src/Google.Protobuf.Test/WellKnownTypes/DurationTest.cs \
99100
csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs \
100101
csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs \
@@ -149,6 +150,7 @@ csharp_EXTRA_DIST= \
149150
csharp/src/Google.Protobuf/Reflection/ServiceDescriptor.cs \
150151
csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs \
151152
csharp/src/Google.Protobuf/WellKnownTypes/Any.cs \
153+
csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs \
152154
csharp/src/Google.Protobuf/WellKnownTypes/Api.cs \
153155
csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs \
154156
csharp/src/Google.Protobuf/WellKnownTypes/DurationPartial.cs \

csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
<Compile Include="Properties\AssemblyInfo.cs" />
110110
<Compile Include="TestCornerCases.cs" />
111111
<Compile Include="TestProtos\UnittestWellKnownTypes.cs" />
112+
<Compile Include="WellKnownTypes\AnyTest.cs" />
112113
<Compile Include="WellKnownTypes\DurationTest.cs" />
113114
<Compile Include="WellKnownTypes\TimestampTest.cs" />
114115
<Compile Include="WellKnownTypes\WrappersTest.cs" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#region Copyright notice and license
2+
// Protocol Buffers - Google's data interchange format
3+
// Copyright 2015 Google Inc. All rights reserved.
4+
// https://developers.google.com/protocol-buffers/
5+
//
6+
// Redistribution and use in source and binary forms, with or without
7+
// modification, are permitted provided that the following conditions are
8+
// met:
9+
//
10+
// * Redistributions of source code must retain the above copyright
11+
// notice, this list of conditions and the following disclaimer.
12+
// * Redistributions in binary form must reproduce the above
13+
// copyright notice, this list of conditions and the following disclaimer
14+
// in the documentation and/or other materials provided with the
15+
// distribution.
16+
// * Neither the name of Google Inc. nor the names of its
17+
// contributors may be used to endorse or promote products derived from
18+
// this software without specific prior written permission.
19+
//
20+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22+
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23+
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24+
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25+
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26+
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27+
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28+
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31+
#endregion
32+
33+
using Google.Protobuf.TestProtos;
34+
using NUnit.Framework;
35+
36+
namespace Google.Protobuf.WellKnownTypes
37+
{
38+
public class AnyTest
39+
{
40+
[Test]
41+
public void Pack()
42+
{
43+
var message = SampleMessages.CreateFullTestAllTypes();
44+
var any = Any.Pack(message);
45+
Assert.AreEqual("type.googleapis.com/protobuf_unittest.TestAllTypes", any.TypeUrl);
46+
Assert.AreEqual(message.CalculateSize(), any.Value.Length);
47+
}
48+
49+
[Test]
50+
public void Unpack_WrongType()
51+
{
52+
var message = SampleMessages.CreateFullTestAllTypes();
53+
var any = Any.Pack(message);
54+
Assert.Throws<InvalidProtocolBufferException>(() => any.Unpack<TestOneof>());
55+
}
56+
57+
[Test]
58+
public void Unpack_Success()
59+
{
60+
var message = SampleMessages.CreateFullTestAllTypes();
61+
var any = Any.Pack(message);
62+
var unpacked = any.Unpack<TestAllTypes>();
63+
Assert.AreEqual(message, unpacked);
64+
}
65+
}
66+
}

csharp/src/Google.Protobuf/Google.Protobuf.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
<Compile Include="Reflection\SingleFieldAccessor.cs" />
119119
<Compile Include="Preconditions.cs" />
120120
<Compile Include="WellKnownTypes\Any.cs" />
121+
<Compile Include="WellKnownTypes\AnyPartial.cs" />
121122
<Compile Include="WellKnownTypes\Api.cs" />
122123
<Compile Include="WellKnownTypes\Duration.cs" />
123124
<Compile Include="WellKnownTypes\DurationPartial.cs" />

csharp/src/Google.Protobuf/Reflection/DescriptorPool.cs

+2
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ internal T FindSymbol<T>(string fullName) where T : class
9696
return descriptor;
9797
}
9898

99+
// dependencies contains direct dependencies and any *public* dependencies
100+
// of those dependencies (transitively)... so we don't need to recurse here.
99101
foreach (FileDescriptor dependency in dependencies)
100102
{
101103
dependency.DescriptorPool.descriptorsByName.TryGetValue(fullName, out result);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#region Copyright notice and license
2+
// Protocol Buffers - Google's data interchange format
3+
// Copyright 2015 Google Inc. All rights reserved.
4+
// https://developers.google.com/protocol-buffers/
5+
//
6+
// Redistribution and use in source and binary forms, with or without
7+
// modification, are permitted provided that the following conditions are
8+
// met:
9+
//
10+
// * Redistributions of source code must retain the above copyright
11+
// notice, this list of conditions and the following disclaimer.
12+
// * Redistributions in binary form must reproduce the above
13+
// copyright notice, this list of conditions and the following disclaimer
14+
// in the documentation and/or other materials provided with the
15+
// distribution.
16+
// * Neither the name of Google Inc. nor the names of its
17+
// contributors may be used to endorse or promote products derived from
18+
// this software without specific prior written permission.
19+
//
20+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22+
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23+
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24+
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25+
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26+
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27+
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28+
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31+
#endregion
32+
33+
using Google.Protobuf.Reflection;
34+
35+
namespace Google.Protobuf.WellKnownTypes
36+
{
37+
public partial class Any
38+
{
39+
// This could be moved to MessageDescriptor if we wanted to, but keeping it here means
40+
// all the Any-specific code is in the same place.
41+
private static string GetTypeUrl(MessageDescriptor descriptor)
42+
{
43+
return "type.googleapis.com/" + descriptor.FullName;
44+
}
45+
46+
/// <summary>
47+
/// Unpacks the content of this Any message into the target message type,
48+
/// which must match the type URL within this Any message.
49+
/// </summary>
50+
/// <typeparam name="T">The type of message to unpack the content into.</typeparam>
51+
/// <returns>The unpacked message.</returns>
52+
/// <exception cref="InvalidProtocolBufferException">The target message type doesn't match the type URL in this message</exception>
53+
public T Unpack<T>() where T : IMessage, new()
54+
{
55+
// Note: this doesn't perform as well is it might. We could take a MessageParser<T> in an alternative overload,
56+
// which would be expected to perform slightly better... although the difference is likely to be negligible.
57+
T target = new T();
58+
string targetTypeUrl = GetTypeUrl(target.Descriptor);
59+
if (TypeUrl != targetTypeUrl)
60+
{
61+
throw new InvalidProtocolBufferException(string.Format("Type url for {0} is {1}; Any message's type url is {2}",
62+
target.Descriptor.Name, targetTypeUrl, TypeUrl));
63+
}
64+
target.MergeFrom(Value);
65+
return target;
66+
}
67+
68+
/// <summary>
69+
/// Packs the specified message into an Any message.
70+
/// </summary>
71+
/// <param name="message">The message to pack.</param>
72+
/// <returns>An Any message with the content and type URL of <paramref name="message"/>.</returns>
73+
public static Any Pack(IMessage message)
74+
{
75+
Preconditions.CheckNotNull(message, "message");
76+
return new Any { TypeUrl = GetTypeUrl(message.Descriptor), Value = message.ToByteString() };
77+
}
78+
}
79+
}

0 commit comments

Comments
 (0)