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

.NET: Add nullable annotations to Protobuf library #9801

Closed
wants to merge 9 commits into from
Closed
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
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
8 changes: 4 additions & 4 deletions csharp/src/AddressBook/AddPerson.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,13 @@ private static Person PromptForAddress(TextReader input, TextWriter output)
Person person = new Person();

output.Write("Enter person ID: ");
person.Id = int.Parse(input.ReadLine());
person.Id = int.Parse(input.ReadLine() ?? string.Empty);

output.Write("Enter name: ");
person.Name = input.ReadLine();

output.Write("Enter email address (blank for none): ");
string email = input.ReadLine();
string email = input.ReadLine() ?? string.Empty;
if (email.Length > 0)
{
person.Email = email;
Expand All @@ -60,7 +60,7 @@ private static Person PromptForAddress(TextReader input, TextWriter output)
while (true)
{
output.Write("Enter a phone number (or leave blank to finish): ");
string number = input.ReadLine();
string number = input.ReadLine() ?? string.Empty;
if (number.Length == 0)
{
break;
Expand All @@ -69,7 +69,7 @@ private static Person PromptForAddress(TextReader input, TextWriter output)
Person.Types.PhoneNumber phoneNumber = new Person.Types.PhoneNumber { Number = number };

output.Write("Is this a mobile, home, or work phone? ");
String type = input.ReadLine();
String type = input.ReadLine() ?? string.Empty;
switch (type)
{
case "mobile":
Expand Down
60 changes: 60 additions & 0 deletions csharp/src/Backup/Google.Protobuf.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26114.2
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AddressBook", "AddressBook\AddressBook.csproj", "{AFB63919-1E05-43B4-802A-8FB8C9B2F463}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Google.Protobuf", "Google.Protobuf\Google.Protobuf.csproj", "{9B576380-726D-4142-8238-60A43AB0E35A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Google.Protobuf.Test", "Google.Protobuf.Test\Google.Protobuf.Test.csproj", "{580EB013-D3C7-4578-B845-015F4A3B0591}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Google.Protobuf.Conformance", "Google.Protobuf.Conformance\Google.Protobuf.Conformance.csproj", "{DDDC055B-E185-4181-BAB0-072F0F984569}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Google.Protobuf.JsonDump", "Google.Protobuf.JsonDump\Google.Protobuf.JsonDump.csproj", "{9695E08F-9829-497D-B95C-B38F28D48690}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf.Benchmarks", "Google.Protobuf.Benchmarks\Google.Protobuf.Benchmarks.csproj", "{D25E4804-4DEA-45AB-9F8C-BA4DBD8E5A07}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf.Test.TestProtos", "Google.Protobuf.Test.TestProtos\Google.Protobuf.Test.TestProtos.csproj", "{ADF24BEB-A318-4530-8448-356B72B820EA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{AFB63919-1E05-43B4-802A-8FB8C9B2F463}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AFB63919-1E05-43B4-802A-8FB8C9B2F463}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AFB63919-1E05-43B4-802A-8FB8C9B2F463}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AFB63919-1E05-43B4-802A-8FB8C9B2F463}.Release|Any CPU.Build.0 = Release|Any CPU
{9B576380-726D-4142-8238-60A43AB0E35A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9B576380-726D-4142-8238-60A43AB0E35A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9B576380-726D-4142-8238-60A43AB0E35A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9B576380-726D-4142-8238-60A43AB0E35A}.Release|Any CPU.Build.0 = Release|Any CPU
{580EB013-D3C7-4578-B845-015F4A3B0591}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{580EB013-D3C7-4578-B845-015F4A3B0591}.Debug|Any CPU.Build.0 = Debug|Any CPU
{580EB013-D3C7-4578-B845-015F4A3B0591}.Release|Any CPU.ActiveCfg = Release|Any CPU
{580EB013-D3C7-4578-B845-015F4A3B0591}.Release|Any CPU.Build.0 = Release|Any CPU
{DDDC055B-E185-4181-BAB0-072F0F984569}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DDDC055B-E185-4181-BAB0-072F0F984569}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DDDC055B-E185-4181-BAB0-072F0F984569}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DDDC055B-E185-4181-BAB0-072F0F984569}.Release|Any CPU.Build.0 = Release|Any CPU
{9695E08F-9829-497D-B95C-B38F28D48690}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9695E08F-9829-497D-B95C-B38F28D48690}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9695E08F-9829-497D-B95C-B38F28D48690}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9695E08F-9829-497D-B95C-B38F28D48690}.Release|Any CPU.Build.0 = Release|Any CPU
{D25E4804-4DEA-45AB-9F8C-BA4DBD8E5A07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D25E4804-4DEA-45AB-9F8C-BA4DBD8E5A07}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D25E4804-4DEA-45AB-9F8C-BA4DBD8E5A07}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D25E4804-4DEA-45AB-9F8C-BA4DBD8E5A07}.Release|Any CPU.Build.0 = Release|Any CPU
{ADF24BEB-A318-4530-8448-356B72B820EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ADF24BEB-A318-4530-8448-356B72B820EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ADF24BEB-A318-4530-8448-356B72B820EA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ADF24BEB-A318-4530-8448-356B72B820EA}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7B06C87B-83E1-4F5F-A0DD-6E9AFAC03DAC}
EndGlobalSection
EndGlobal
11 changes: 11 additions & 0 deletions csharp/src/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project>

<PropertyGroup>
<!-- C# 7.3+ is required for Span/BufferWriter/ReadOnlySequence -->
<!-- v10 is compatible with Visual Studio 2022+ -->
<LangVersion>10.0</LangVersion>

<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,14 @@ public class BenchmarkDatasetConfig
typeof(GoogleMessageBenchmark).Assembly.GetTypes()
.Where(t => typeof(IMessage).IsAssignableFrom(t))
.ToDictionary(
t => ((MessageDescriptor) t.GetProperty("Descriptor", BindingFlags.Static | BindingFlags.Public).GetValue(null)).FullName,
t => ((MessageParser) t.GetProperty("Parser", BindingFlags.Static | BindingFlags.Public).GetValue(null)));
t => ((MessageDescriptor) t.GetProperty("Descriptor", BindingFlags.Static | BindingFlags.Public)!.GetValue(null)!).FullName,
t => ((MessageParser) t.GetProperty("Parser", BindingFlags.Static | BindingFlags.Public)!.GetValue(null)!));

public MessageParser Parser { get; }
public List<byte[]> Payloads { get; }
public string Name { get; }

public BenchmarkDatasetConfig(string resource, string shortName = null)
public BenchmarkDatasetConfig(string resource, string? shortName = null)
{
var data = LoadData(resource);
var dataset = BenchmarkDataset.Parser.ParseFrom(data);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@

using BenchmarkDotNet.Attributes;

#nullable disable

namespace Google.Protobuf.Benchmarks
{
/// <summary>
Expand Down Expand Up @@ -60,7 +62,7 @@ public void GlobalSetup()
[Benchmark]
public ByteString CopyFrom()
{
return ByteString.CopyFrom(byteBuffer);
return ByteString.CopyFrom(byteBuffer!);
}

[Benchmark]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,34 +58,34 @@ public class GoogleMessageBenchmark
};

[ParamsSource(nameof(DatasetConfigurations))]
public BenchmarkDatasetConfig Dataset { get; set; }
public BenchmarkDatasetConfig? Dataset { get; set; }

private MessageParser parser;
private MessageParser? parser;
/// <summary>
/// Each data set can contain multiple messages in a single file.
/// Each "write" operation should write each message in turn, and each "parse"
/// operation should parse each message in turn.
/// </summary>
private List<SubTest> subTests;
private List<SubTest>? subTests;

[GlobalSetup]
public void GlobalSetup()
{
parser = Dataset.Parser;
parser = Dataset!.Parser;
subTests = Dataset.Payloads.Select(p => new SubTest(p, parser.ParseFrom(p))).ToList();
}

[Benchmark]
public void WriteToStream() => subTests.ForEach(item => item.WriteToStream());
public void WriteToStream() => subTests!.ForEach(item => item.WriteToStream());

[Benchmark]
public void ToByteArray() => subTests.ForEach(item => item.ToByteArray());
public void ToByteArray() => subTests!.ForEach(item => item.ToByteArray());

[Benchmark]
public void ParseFromByteArray() => subTests.ForEach(item => item.ParseFromByteArray(parser));
public void ParseFromByteArray() => subTests!.ForEach(item => item.ParseFromByteArray(parser!));

[Benchmark]
public void ParseFromStream() => subTests.ForEach(item => item.ParseFromStream(parser));
public void ParseFromStream() => subTests!.ForEach(item => item.ParseFromStream(parser!));

private class SubTest
{
Expand Down
Loading