Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to C# 10 and upgrade code style #10105

Merged
merged 2 commits into from
Jun 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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>
erikmav marked this conversation as resolved.
Show resolved Hide resolved
</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>
erikmav marked this conversation as resolved.
Show resolved Hide resolved

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

</Project>
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
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