Skip to content

Commit

Permalink
Update to C# 10 and upgrade code style (#10105)
Browse files Browse the repository at this point in the history
  • Loading branch information
erikmav authored Jun 23, 2022
1 parent 352444e commit 9f58ee3
Show file tree
Hide file tree
Showing 92 changed files with 783 additions and 1,379 deletions.
1 change: 1 addition & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ csharp_EXTRA_DIST= \
csharp/src/AddressBook/ListPeople.cs \
csharp/src/AddressBook/Program.cs \
csharp/src/AddressBook/SampleUsage.cs \
csharp/src/Directory.Build.props \
csharp/src/Google.Protobuf.Benchmarks/BenchmarkDatasetConfig.cs \
csharp/src/Google.Protobuf.Benchmarks/BenchmarkMessage1Proto3.cs \
csharp/src/Google.Protobuf.Benchmarks/Benchmarks.cs \
Expand Down
11 changes: 6 additions & 5 deletions csharp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ The runtime library is built as a portable class library, supporting:
- Windows Phone Silverlight 8
- Windows Phone 8.1
- .NET Core
- .NET 5

You should be able to use Protocol Buffers in Visual Studio 2012 and
all later versions. This includes all code generated by `protoc`,
Expand All @@ -31,15 +32,15 @@ which only uses features from C# 3 and earlier.
Building
========

Open the `src/Google.Protobuf.sln` solution in Visual Studio 2017 or
Open the `src/Google.Protobuf.sln` solution in Visual Studio 2022 or
later.

Although *users* of this project are only expected to have Visual
Studio 2012 or later, *developers* of the library are required to
have Visual Studio 2017 or later, as the library uses C# 6 features
in its implementation, as well as the new Visual Studio 2017 csproj
format. These features have no impact when using the compiled code -
they're only relevant when building the `Google.Protobuf` assembly.
have Visual Studio 2022 or later, as the library uses C# 10 features
in its implementation and runs tests under .NET 6. These features
have no impact when using the compiled code - they're only relevant
when building the `Google.Protobuf` assembly.

In order to run and debug the AddressBook example in the IDE, you must
install the optional component, ".Net Core 1.0 - 1.1 development tools
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<IsPackable>False</IsPackable>
<LangVersion>8.0</LangVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
6 changes: 2 additions & 4 deletions csharp/src/AddressBook/AddPerson.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,8 @@ public static int Main(string[] args)

if (File.Exists(args[0]))
{
using (Stream file = File.OpenRead(args[0]))
{
addressBook = AddressBook.Parser.ParseFrom(file);
}
using Stream file = File.OpenRead(args[0]);
addressBook = AddressBook.Parser.ParseFrom(file);
}
else
{
Expand Down
7 changes: 7 additions & 0 deletions csharp/src/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project>

<PropertyGroup>
<LangVersion>10.0</LangVersion>
</PropertyGroup>

</Project>
14 changes: 6 additions & 8 deletions csharp/src/Google.Protobuf.Benchmarks/BenchmarkDatasetConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,14 @@ public BenchmarkDatasetConfig(string resource, string shortName = null)

private static byte[] LoadData(string resource)
{
using (var stream = typeof(GoogleMessageBenchmark).Assembly.GetManifestResourceStream($"Google.Protobuf.Benchmarks.{resource}"))
using var stream = typeof(GoogleMessageBenchmark).Assembly.GetManifestResourceStream($"Google.Protobuf.Benchmarks.{resource}");
if (stream == null)
{
if (stream == null)
{
throw new ArgumentException($"Unable to load embedded resource {resource}");
}
var copy = new MemoryStream();
stream.CopyTo(copy);
return copy.ToArray();
throw new ArgumentException($"Unable to load embedded resource {resource}");
}
var copy = new MemoryStream();
stream.CopyTo(copy);
return copy.ToArray();
}

public override string ToString() => Name;
Expand Down
12 changes: 6 additions & 6 deletions csharp/src/Google.Protobuf.Benchmarks/ParseMessagesBenchmark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ public class ParseMessagesBenchmark
{
const int MaxMessages = 100;

SubTest manyWrapperFieldsTest = new SubTest(CreateManyWrapperFieldsMessage(), ManyWrapperFieldsMessage.Parser, () => new ManyWrapperFieldsMessage(), MaxMessages);
SubTest manyPrimitiveFieldsTest = new SubTest(CreateManyPrimitiveFieldsMessage(), ManyPrimitiveFieldsMessage.Parser, () => new ManyPrimitiveFieldsMessage(), MaxMessages);
SubTest repeatedFieldTest = new SubTest(CreateRepeatedFieldMessage(), GoogleMessage1.Parser, () => new GoogleMessage1(), MaxMessages);
SubTest emptyMessageTest = new SubTest(new Empty(), Empty.Parser, () => new Empty(), MaxMessages);
private readonly SubTest manyWrapperFieldsTest = new(CreateManyWrapperFieldsMessage(), ManyWrapperFieldsMessage.Parser, () => new ManyWrapperFieldsMessage(), MaxMessages);
private readonly SubTest manyPrimitiveFieldsTest = new(CreateManyPrimitiveFieldsMessage(), ManyPrimitiveFieldsMessage.Parser, () => new ManyPrimitiveFieldsMessage(), MaxMessages);
private readonly SubTest repeatedFieldTest = new(CreateRepeatedFieldMessage(), GoogleMessage1.Parser, () => new GoogleMessage1(), MaxMessages);
private readonly SubTest emptyMessageTest = new(new Empty(), Empty.Parser, () => new Empty(), MaxMessages);

public IEnumerable<int> MessageCountValues => new[] { 10, 100 };

Expand Down Expand Up @@ -204,8 +204,8 @@ private class SubTest
private readonly byte[] data;
private readonly byte[] multipleMessagesData;

private ReadOnlySequence<byte> dataSequence;
private ReadOnlySequence<byte> multipleMessagesDataSequence;
private readonly ReadOnlySequence<byte> dataSequence;
private readonly ReadOnlySequence<byte> multipleMessagesDataSequence;

public SubTest(IMessage message, MessageParser parser, Func<IMessage> factory, int maxMessageCount)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ private static byte[] CreateBufferWithRandomDoubles(Random random, int valueCoun
private static byte[] CreateBufferWithRandomData(Random random, int valueCount, int encodedSize, int paddingValueCount)
{
int bufferSize = (valueCount + paddingValueCount) * encodedSize;
byte[] buffer = new byte[bufferSize];
var buffer = new byte[bufferSize];
random.NextBytes(buffer);
return buffer;
}
Expand Down
2 changes: 0 additions & 2 deletions csharp/src/Google.Protobuf.Benchmarks/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,4 @@ public static void Main(string[] args)
BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
}
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@

using BenchmarkDotNet.Attributes;
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.IO;
using System.Buffers;
using System.Text;

namespace Google.Protobuf.Benchmarks
Expand Down
36 changes: 13 additions & 23 deletions csharp/src/Google.Protobuf.Conformance/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ namespace Google.Protobuf.Conformance
/// </summary>
class Program
{
private static void Main(string[] args)
private static void Main()
{
// This way we get the binary streams instead of readers/writers.
var input = new BinaryReader(Console.OpenStandardInput());
Expand Down Expand Up @@ -100,32 +100,22 @@ private static ConformanceResponse PerformRequest(ConformanceRequest request, Ty
return new ConformanceResponse { Skipped = "CSharp doesn't support skipping unknown fields in json parsing." };
}
var parser = new JsonParser(new JsonParser.Settings(20, typeRegistry));
switch (request.MessageType)
message = request.MessageType switch
{
case "protobuf_test_messages.proto3.TestAllTypesProto3":
message = parser.Parse<ProtobufTestMessages.Proto3.TestAllTypesProto3>(request.JsonPayload);
break;
case "protobuf_test_messages.proto2.TestAllTypesProto2":
message = parser.Parse<ProtobufTestMessages.Proto2.TestAllTypesProto2>(request.JsonPayload);
break;
default:
throw new Exception($" Protobuf request doesn't have specific payload type ({request.MessageType})");
}
"protobuf_test_messages.proto3.TestAllTypesProto3" => parser.Parse<ProtobufTestMessages.Proto3.TestAllTypesProto3>(request.JsonPayload),
"protobuf_test_messages.proto2.TestAllTypesProto2" => parser.Parse<ProtobufTestMessages.Proto2.TestAllTypesProto2>(request.JsonPayload),
_ => throw new Exception($" Protobuf request doesn't have specific payload type ({request.MessageType})"),
};
break;
case ConformanceRequest.PayloadOneofCase.ProtobufPayload:
switch (request.MessageType)
message = request.MessageType switch
{
case "protobuf_test_messages.proto3.TestAllTypesProto3":
message = ProtobufTestMessages.Proto3.TestAllTypesProto3.Parser.ParseFrom(request.ProtobufPayload);
break;
case "protobuf_test_messages.proto2.TestAllTypesProto2":
message = ProtobufTestMessages.Proto2.TestAllTypesProto2.Parser
.WithExtensionRegistry(proto2ExtensionRegistry)
.ParseFrom(request.ProtobufPayload);
break;
default:
throw new Exception($" Protobuf request doesn't have specific payload type ({request.MessageType})");
}
"protobuf_test_messages.proto3.TestAllTypesProto3" => ProtobufTestMessages.Proto3.TestAllTypesProto3.Parser.ParseFrom(request.ProtobufPayload),
"protobuf_test_messages.proto2.TestAllTypesProto2" => ProtobufTestMessages.Proto2.TestAllTypesProto2.Parser
.WithExtensionRegistry(proto2ExtensionRegistry)
.ParseFrom(request.ProtobufPayload),
_ => throw new Exception($" Protobuf request doesn't have specific payload type ({request.MessageType})"),
};
break;
case ConformanceRequest.PayloadOneofCase.TextPayload:
return new ConformanceResponse { Skipped = "CSharp doesn't support text format" };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
-->
<PropertyGroup>
<TargetFrameworks>net462;netstandard1.1;netstandard2.0</TargetFrameworks>
<LangVersion>3.0</LangVersion>
<LangVersion>10.0</LangVersion>
<AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<IsPackable>False</IsPackable>
Expand Down
20 changes: 7 additions & 13 deletions csharp/src/Google.Protobuf.Test/ByteStringTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public void Equality()
Assert.IsFalse(b1 != b1);
Assert.IsFalse(b1 != b2);
Assert.IsTrue(ByteString.Empty == ByteString.Empty);
#pragma warning disable 1718
#pragma warning restore 1718
Assert.IsTrue(b1 != b3);
Assert.IsTrue(b1 != b4);
Assert.IsTrue(b1 != null);
Expand Down Expand Up @@ -276,12 +276,9 @@ public void ToString_Stackalloc()
Span<byte> s = stackalloc byte[data.Length];
data.CopyTo(s);

using (UnmanagedMemoryManager<byte> manager = new UnmanagedMemoryManager<byte>(s))
{
ByteString bs = ByteString.AttachBytes(manager.Memory);

Assert.AreEqual("Hello world", bs.ToString(Encoding.UTF8));
}
using var manager = new UnmanagedMemoryManager<byte>(s);
ByteString bs = ByteString.AttachBytes(manager.Memory);
Assert.AreEqual("Hello world", bs.ToString(Encoding.UTF8));
}

[Test]
Expand Down Expand Up @@ -315,12 +312,9 @@ public void ToBase64_Stackalloc()
Span<byte> s = stackalloc byte[data.Length];
data.CopyTo(s);

using (UnmanagedMemoryManager<byte> manager = new UnmanagedMemoryManager<byte>(s))
{
ByteString bs = ByteString.AttachBytes(manager.Memory);

Assert.AreEqual("SGVsbG8gd29ybGQ=", bs.ToBase64());
}
using var manager = new UnmanagedMemoryManager<byte>(s);
ByteString bs = ByteString.AttachBytes(manager.Memory);
Assert.AreEqual("SGVsbG8gd29ybGQ=", bs.ToBase64());
}

[Test]
Expand Down
62 changes: 28 additions & 34 deletions csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -563,8 +563,8 @@ public void ReadGroup_WrongEndGroupTag()
int groupFieldNumber = Proto2.TestAllTypes.OptionalGroupFieldNumber;

// write Proto2.TestAllTypes with "optional_group" set, but use wrong EndGroup closing tag
MemoryStream ms = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(ms);
var ms = new MemoryStream();
var output = new CodedOutputStream(ms);
output.WriteTag(WireFormat.MakeTag(groupFieldNumber, WireFormat.WireType.StartGroup));
output.WriteGroup(new Proto2.TestAllTypes.Types.OptionalGroup { A = 12345 });
// end group with different field number
Expand All @@ -578,8 +578,8 @@ public void ReadGroup_WrongEndGroupTag()
[Test]
public void ReadGroup_UnknownFields_WrongEndGroupTag()
{
MemoryStream ms = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(ms);
var ms = new MemoryStream();
var output = new CodedOutputStream(ms);
output.WriteTag(WireFormat.MakeTag(14, WireFormat.WireType.StartGroup));
// end group with different field number
output.WriteTag(WireFormat.MakeTag(15, WireFormat.WireType.EndGroup));
Expand Down Expand Up @@ -654,7 +654,7 @@ public void ReadNegativeSizedBytesThrowsInvalidProtocolBufferException()
output.Flush();
ms.Position = 0;

CodedInputStream input = new CodedInputStream(ms);
var input = new CodedInputStream(ms);

Assert.AreEqual(tag, input.ReadTag());
Assert.Throws<InvalidProtocolBufferException>(() => input.ReadBytes());
Expand Down Expand Up @@ -694,26 +694,24 @@ public void TestNegativeEnum()
[Test]
public void TestSlowPathAvoidance()
{
using (var ms = new MemoryStream())
{
CodedOutputStream output = new CodedOutputStream(ms);
output.WriteTag(1, WireFormat.WireType.LengthDelimited);
output.WriteBytes(ByteString.CopyFrom(new byte[100]));
output.WriteTag(2, WireFormat.WireType.LengthDelimited);
output.WriteBytes(ByteString.CopyFrom(new byte[100]));
output.Flush();
using var ms = new MemoryStream();
var output = new CodedOutputStream(ms);
output.WriteTag(1, WireFormat.WireType.LengthDelimited);
output.WriteBytes(ByteString.CopyFrom(new byte[100]));
output.WriteTag(2, WireFormat.WireType.LengthDelimited);
output.WriteBytes(ByteString.CopyFrom(new byte[100]));
output.Flush();

ms.Position = 0;
CodedInputStream input = new CodedInputStream(ms, new byte[ms.Length / 2], 0, 0, false);
ms.Position = 0;
CodedInputStream input = new CodedInputStream(ms, new byte[ms.Length / 2], 0, 0, false);

uint tag = input.ReadTag();
Assert.AreEqual(1, WireFormat.GetTagFieldNumber(tag));
Assert.AreEqual(100, input.ReadBytes().Length);
uint tag = input.ReadTag();
Assert.AreEqual(1, WireFormat.GetTagFieldNumber(tag));
Assert.AreEqual(100, input.ReadBytes().Length);

tag = input.ReadTag();
Assert.AreEqual(2, WireFormat.GetTagFieldNumber(tag));
Assert.AreEqual(100, input.ReadBytes().Length);
}
tag = input.ReadTag();
Assert.AreEqual(2, WireFormat.GetTagFieldNumber(tag));
Assert.AreEqual(100, input.ReadBytes().Length);
}

[Test]
Expand Down Expand Up @@ -927,31 +925,27 @@ public void TestParseMessagesCloseTo2G()
{
byte[] serializedMessage = GenerateBigSerializedMessage();
// How many of these big messages do we need to take us near our 2GB limit?
int count = Int32.MaxValue / serializedMessage.Length;
int count = int.MaxValue / serializedMessage.Length;
// Now make a MemoryStream that will fake a near-2GB stream of messages by returning
// our big serialized message 'count' times.
using (RepeatingMemoryStream stream = new RepeatingMemoryStream(serializedMessage, count))
{
Assert.DoesNotThrow(()=>TestAllTypes.Parser.ParseFrom(stream));
}
using var stream = new RepeatingMemoryStream(serializedMessage, count);
Assert.DoesNotThrow(() => TestAllTypes.Parser.ParseFrom(stream));
}

[Test]
public void TestParseMessagesOver2G()
{
byte[] serializedMessage = GenerateBigSerializedMessage();
// How many of these big messages do we need to take us near our 2GB limit?
int count = Int32.MaxValue / serializedMessage.Length;
int count = int.MaxValue / serializedMessage.Length;
// Now add one to take us over the 2GB limit
count++;
// Now make a MemoryStream that will fake a near-2GB stream of messages by returning
// our big serialized message 'count' times.
using (RepeatingMemoryStream stream = new RepeatingMemoryStream(serializedMessage, count))
{
Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(stream),
"Protocol message was too large. May be malicious. " +
"Use CodedInputStream.SetSizeLimit() to increase the size limit.");
}
using var stream = new RepeatingMemoryStream(serializedMessage, count);
Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(stream),
"Protocol message was too large. May be malicious. " +
"Use CodedInputStream.SetSizeLimit() to increase the size limit.");
}

/// <returns>A serialized big message</returns>
Expand Down
Loading

0 comments on commit 9f58ee3

Please sign in to comment.