Skip to content

Commit eebea1b

Browse files
committed
Add support for Well Known Types
1 parent 3677b77 commit eebea1b

5 files changed

Lines changed: 157 additions & 2 deletions

src/Protobuf.System.Text.Json/ProtobufConverter.cs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
using System.Text.Json.Serialization;
44
using Google.Protobuf;
55
using Google.Protobuf.Reflection;
6+
using Google.Protobuf.WellKnownTypes;
67
using Protobuf.System.Text.Json.InternalConverters;
8+
using Type = System.Type;
79

810
namespace Protobuf.System.Text.Json;
911

@@ -167,8 +169,24 @@ private Type GetFieldType(FieldDescriptor fieldDescriptor, Dictionary<string, Ty
167169
return typeof(bool);
168170
case FieldType.String:
169171
return typeof(string);
170-
case FieldType.Message when fieldDescriptor.MessageType.ClrType != null:
171-
return fieldDescriptor.MessageType.ClrType;
172+
case FieldType.Message when fieldDescriptor.MessageType.ClrType is { } clrType:
173+
if (clrType == typeof(DoubleValue))
174+
return typeof(double?);
175+
if (clrType == typeof(FloatValue))
176+
return typeof(float?);
177+
if (clrType == typeof(Int64Value))
178+
return typeof(long?);
179+
if (clrType == typeof(UInt64Value))
180+
return typeof(ulong?);
181+
if (clrType == typeof(Int32Value))
182+
return typeof(int?);
183+
if (clrType == typeof(UInt32Value))
184+
return typeof(uint?);
185+
if (clrType == typeof(BoolValue))
186+
return typeof(bool?);
187+
if (clrType == typeof(StringValue))
188+
return typeof(string);
189+
return clrType;
172190
case FieldType.Enum when fieldDescriptor.IsRepeated:
173191
var fieldType = propertyTypeLookup[fieldDescriptor.PropertyName];
174192
return fieldType.GenericTypeArguments[0];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"doubleValue": null,
3+
"floatValue": null,
4+
"int64Value": null,
5+
"uint64Value": null,
6+
"int32Value": null,
7+
"uint32Value": null,
8+
"boolValue": null,
9+
"stringValue": null
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"doubleValue": 1.7976931348623157E+308,
3+
"floatValue": 3.4028235E+38,
4+
"int64Value": 9223372036854775807,
5+
"uint64Value": 18446744073709551615,
6+
"int32Value": 2147483647,
7+
"uint32Value": 4294967295,
8+
"boolValue": true,
9+
"stringValue": "some_string_value"
10+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
using System.Text.Json;
2+
using System.Text.Json.Protobuf.Tests;
3+
using System.Text.Json.Serialization;
4+
using Protobuf.System.Text.Json.Tests.Utils;
5+
using Shouldly;
6+
using SmartAnalyzers.ApprovalTestsExtensions;
7+
using Xunit;
8+
9+
namespace Protobuf.System.Text.Json.Tests;
10+
11+
public class MessageWithWellKnownTypesTests
12+
{
13+
[Fact]
14+
public void Should_serialize_message_with_well_known_types_when_values_are_set()
15+
{
16+
// Arrange
17+
var msg = new MessageWithWellKnownTypes
18+
{
19+
DoubleValue = double.MaxValue,
20+
FloatValue = float.MaxValue,
21+
Int64Value = long.MaxValue,
22+
Uint64Value = ulong.MaxValue,
23+
Int32Value = int.MaxValue,
24+
Uint32Value = uint.MaxValue,
25+
BoolValue = true,
26+
StringValue = "some_string_value",
27+
};
28+
var jsonSerializerOptions = TestHelper.CreateJsonSerializerOptions();
29+
30+
// Act
31+
var serialized = JsonSerializer.Serialize(msg, jsonSerializerOptions);
32+
33+
// Assert
34+
var approver = new ExplicitApprover();
35+
approver.VerifyJson(serialized);
36+
}
37+
38+
[Fact]
39+
public void Should_serialize_message_with_well_known_types_when_values_are_not_set()
40+
{
41+
// Arrange
42+
var msg = new MessageWithWellKnownTypes();
43+
var jsonSerializerOptions = TestHelper.CreateJsonSerializerOptions();
44+
jsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.Never;
45+
46+
// Act
47+
var serialized = JsonSerializer.Serialize(msg, jsonSerializerOptions);
48+
49+
// Assert
50+
var approver = new ExplicitApprover();
51+
approver.VerifyJson(serialized);
52+
}
53+
54+
[Fact]
55+
public void Should_serialize_and_deserialize_message_with_well_known_types_when_values_are_set()
56+
{
57+
// Arrange
58+
var msg = new MessageWithWellKnownTypes
59+
{
60+
DoubleValue = double.MaxValue,
61+
FloatValue = float.MaxValue,
62+
Int64Value = long.MaxValue,
63+
Uint64Value = ulong.MaxValue,
64+
Int32Value = int.MaxValue,
65+
Uint32Value = uint.MaxValue,
66+
BoolValue = true,
67+
StringValue = "some_string_value"
68+
};
69+
var jsonSerializerOptions = TestHelper.CreateJsonSerializerOptions();
70+
var serialized = JsonSerializer.Serialize(msg, jsonSerializerOptions);
71+
72+
// Act
73+
var deserialized = JsonSerializer.Deserialize<MessageWithWellKnownTypes>(serialized, jsonSerializerOptions);
74+
75+
76+
// Assert
77+
deserialized.ShouldBe(msg);
78+
}
79+
80+
[Fact]
81+
public void Should_serialize_and_deserialize_message_with_well_known_types_when_values_are_not_set()
82+
{
83+
// Arrange
84+
var msg = new MessageWithWellKnownTypes();
85+
var jsonSerializerOptions = TestHelper.CreateJsonSerializerOptions();
86+
var serialized = JsonSerializer.Serialize(msg, jsonSerializerOptions);
87+
88+
// Act
89+
var deserialized = JsonSerializer.Deserialize<MessageWithWellKnownTypes>(serialized, jsonSerializerOptions);
90+
91+
// Assert
92+
deserialized.ShouldBe(msg);
93+
}
94+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
syntax = "proto3";
2+
3+
option csharp_namespace = "System.Text.Json.Protobuf.Tests";
4+
5+
import "google/protobuf/wrappers.proto";
6+
7+
message MessageWithWellKnownTypes {
8+
google.protobuf.DoubleValue double_value = 1;
9+
10+
google.protobuf.FloatValue float_value = 2;
11+
12+
google.protobuf.Int64Value int_64_value = 3;
13+
14+
google.protobuf.UInt64Value uint_64_value = 4;
15+
16+
google.protobuf.Int32Value int_32_Value = 5;
17+
18+
google.protobuf.UInt32Value uint_32_Value = 6;
19+
20+
google.protobuf.BoolValue bool_value = 7;
21+
22+
google.protobuf.StringValue string_value = 8;
23+
}

0 commit comments

Comments
 (0)