Update to C# 10 and upgrade code style (#10105)

This commit is contained in:
Erik Mavrinac 2022-06-23 02:05:16 -07:00 committed by GitHub
parent 352444ecd5
commit 9f58ee3f04
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
92 changed files with 782 additions and 1378 deletions

View File

@ -92,6 +92,7 @@ csharp_EXTRA_DIST= \
csharp/src/AddressBook/ListPeople.cs \ csharp/src/AddressBook/ListPeople.cs \
csharp/src/AddressBook/Program.cs \ csharp/src/AddressBook/Program.cs \
csharp/src/AddressBook/SampleUsage.cs \ csharp/src/AddressBook/SampleUsage.cs \
csharp/src/Directory.Build.props \
csharp/src/Google.Protobuf.Benchmarks/BenchmarkDatasetConfig.cs \ csharp/src/Google.Protobuf.Benchmarks/BenchmarkDatasetConfig.cs \
csharp/src/Google.Protobuf.Benchmarks/BenchmarkMessage1Proto3.cs \ csharp/src/Google.Protobuf.Benchmarks/BenchmarkMessage1Proto3.cs \
csharp/src/Google.Protobuf.Benchmarks/Benchmarks.cs \ csharp/src/Google.Protobuf.Benchmarks/Benchmarks.cs \

View File

@ -23,6 +23,7 @@ The runtime library is built as a portable class library, supporting:
- Windows Phone Silverlight 8 - Windows Phone Silverlight 8
- Windows Phone 8.1 - Windows Phone 8.1
- .NET Core - .NET Core
- .NET 5
You should be able to use Protocol Buffers in Visual Studio 2012 and You should be able to use Protocol Buffers in Visual Studio 2012 and
all later versions. This includes all code generated by `protoc`, all later versions. This includes all code generated by `protoc`,
@ -31,15 +32,15 @@ which only uses features from C# 3 and earlier.
Building 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. later.
Although *users* of this project are only expected to have Visual Although *users* of this project are only expected to have Visual
Studio 2012 or later, *developers* of the library are required to Studio 2012 or later, *developers* of the library are required to
have Visual Studio 2017 or later, as the library uses C# 6 features have Visual Studio 2022 or later, as the library uses C# 10 features
in its implementation, as well as the new Visual Studio 2017 csproj in its implementation and runs tests under .NET 6. These features
format. These features have no impact when using the compiled code - have no impact when using the compiled code - they're only relevant
they're only relevant when building the `Google.Protobuf` assembly. when building the `Google.Protobuf` assembly.
In order to run and debug the AddressBook example in the IDE, you must 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 install the optional component, ".Net Core 1.0 - 1.1 development tools

View File

@ -6,6 +6,7 @@
<AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<IsPackable>False</IsPackable> <IsPackable>False</IsPackable>
<LangVersion>8.0</LangVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -107,10 +107,8 @@ namespace Google.Protobuf.Examples.AddressBook
if (File.Exists(args[0])) if (File.Exists(args[0]))
{ {
using (Stream file = File.OpenRead(args[0])) using Stream file = File.OpenRead(args[0]);
{ addressBook = AddressBook.Parser.ParseFrom(file);
addressBook = AddressBook.Parser.ParseFrom(file);
}
} }
else else
{ {

View File

@ -0,0 +1,7 @@
<Project>
<PropertyGroup>
<LangVersion>10.0</LangVersion>
</PropertyGroup>
</Project>

View File

@ -72,16 +72,14 @@ namespace Google.Protobuf.Benchmarks
private static byte[] LoadData(string resource) 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}");
{
throw new ArgumentException($"Unable to load embedded resource {resource}");
}
var copy = new MemoryStream();
stream.CopyTo(copy);
return copy.ToArray();
} }
var copy = new MemoryStream();
stream.CopyTo(copy);
return copy.ToArray();
} }
public override string ToString() => Name; public override string ToString() => Name;

View File

@ -49,10 +49,10 @@ namespace Google.Protobuf.Benchmarks
{ {
const int MaxMessages = 100; const int MaxMessages = 100;
SubTest manyWrapperFieldsTest = new SubTest(CreateManyWrapperFieldsMessage(), ManyWrapperFieldsMessage.Parser, () => new ManyWrapperFieldsMessage(), MaxMessages); private readonly SubTest manyWrapperFieldsTest = new(CreateManyWrapperFieldsMessage(), ManyWrapperFieldsMessage.Parser, () => new ManyWrapperFieldsMessage(), MaxMessages);
SubTest manyPrimitiveFieldsTest = new SubTest(CreateManyPrimitiveFieldsMessage(), ManyPrimitiveFieldsMessage.Parser, () => new ManyPrimitiveFieldsMessage(), MaxMessages); private readonly SubTest manyPrimitiveFieldsTest = new(CreateManyPrimitiveFieldsMessage(), ManyPrimitiveFieldsMessage.Parser, () => new ManyPrimitiveFieldsMessage(), MaxMessages);
SubTest repeatedFieldTest = new SubTest(CreateRepeatedFieldMessage(), GoogleMessage1.Parser, () => new GoogleMessage1(), MaxMessages); private readonly SubTest repeatedFieldTest = new(CreateRepeatedFieldMessage(), GoogleMessage1.Parser, () => new GoogleMessage1(), MaxMessages);
SubTest emptyMessageTest = new SubTest(new Empty(), Empty.Parser, () => new Empty(), MaxMessages); private readonly SubTest emptyMessageTest = new(new Empty(), Empty.Parser, () => new Empty(), MaxMessages);
public IEnumerable<int> MessageCountValues => new[] { 10, 100 }; public IEnumerable<int> MessageCountValues => new[] { 10, 100 };
@ -204,8 +204,8 @@ namespace Google.Protobuf.Benchmarks
private readonly byte[] data; private readonly byte[] data;
private readonly byte[] multipleMessagesData; private readonly byte[] multipleMessagesData;
private ReadOnlySequence<byte> dataSequence; private readonly ReadOnlySequence<byte> dataSequence;
private ReadOnlySequence<byte> multipleMessagesDataSequence; private readonly ReadOnlySequence<byte> multipleMessagesDataSequence;
public SubTest(IMessage message, MessageParser parser, Func<IMessage> factory, int maxMessageCount) public SubTest(IMessage message, MessageParser parser, Func<IMessage> factory, int maxMessageCount)
{ {

View File

@ -418,7 +418,7 @@ namespace Google.Protobuf.Benchmarks
private static byte[] CreateBufferWithRandomData(Random random, int valueCount, int encodedSize, int paddingValueCount) private static byte[] CreateBufferWithRandomData(Random random, int valueCount, int encodedSize, int paddingValueCount)
{ {
int bufferSize = (valueCount + paddingValueCount) * encodedSize; int bufferSize = (valueCount + paddingValueCount) * encodedSize;
byte[] buffer = new byte[bufferSize]; var buffer = new byte[bufferSize];
random.NextBytes(buffer); random.NextBytes(buffer);
return buffer; return buffer;
} }

View File

@ -44,6 +44,4 @@ namespace Google.Protobuf.Benchmarks
BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args); BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
} }
} }
} }

View File

@ -32,10 +32,7 @@
using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Attributes;
using System; using System;
using System.Buffers.Binary;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Buffers;
using System.Text; using System.Text;
namespace Google.Protobuf.Benchmarks namespace Google.Protobuf.Benchmarks

View File

@ -43,7 +43,7 @@ namespace Google.Protobuf.Conformance
/// </summary> /// </summary>
class Program class Program
{ {
private static void Main(string[] args) private static void Main()
{ {
// This way we get the binary streams instead of readers/writers. // This way we get the binary streams instead of readers/writers.
var input = new BinaryReader(Console.OpenStandardInput()); var input = new BinaryReader(Console.OpenStandardInput());
@ -100,32 +100,22 @@ namespace Google.Protobuf.Conformance
return new ConformanceResponse { Skipped = "CSharp doesn't support skipping unknown fields in json parsing." }; return new ConformanceResponse { Skipped = "CSharp doesn't support skipping unknown fields in json parsing." };
} }
var parser = new JsonParser(new JsonParser.Settings(20, typeRegistry)); var parser = new JsonParser(new JsonParser.Settings(20, typeRegistry));
switch (request.MessageType) message = request.MessageType switch
{ {
case "protobuf_test_messages.proto3.TestAllTypesProto3": "protobuf_test_messages.proto3.TestAllTypesProto3" => parser.Parse<ProtobufTestMessages.Proto3.TestAllTypesProto3>(request.JsonPayload),
message = parser.Parse<ProtobufTestMessages.Proto3.TestAllTypesProto3>(request.JsonPayload); "protobuf_test_messages.proto2.TestAllTypesProto2" => parser.Parse<ProtobufTestMessages.Proto2.TestAllTypesProto2>(request.JsonPayload),
break; _ => throw new Exception($" Protobuf request doesn't have specific payload type ({request.MessageType})"),
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})");
}
break; break;
case ConformanceRequest.PayloadOneofCase.ProtobufPayload: case ConformanceRequest.PayloadOneofCase.ProtobufPayload:
switch (request.MessageType) message = request.MessageType switch
{ {
case "protobuf_test_messages.proto3.TestAllTypesProto3": "protobuf_test_messages.proto3.TestAllTypesProto3" => ProtobufTestMessages.Proto3.TestAllTypesProto3.Parser.ParseFrom(request.ProtobufPayload),
message = ProtobufTestMessages.Proto3.TestAllTypesProto3.Parser.ParseFrom(request.ProtobufPayload); "protobuf_test_messages.proto2.TestAllTypesProto2" => ProtobufTestMessages.Proto2.TestAllTypesProto2.Parser
break; .WithExtensionRegistry(proto2ExtensionRegistry)
case "protobuf_test_messages.proto2.TestAllTypesProto2": .ParseFrom(request.ProtobufPayload),
message = ProtobufTestMessages.Proto2.TestAllTypesProto2.Parser _ => throw new Exception($" Protobuf request doesn't have specific payload type ({request.MessageType})"),
.WithExtensionRegistry(proto2ExtensionRegistry) };
.ParseFrom(request.ProtobufPayload);
break;
default:
throw new Exception($" Protobuf request doesn't have specific payload type ({request.MessageType})");
}
break; break;
case ConformanceRequest.PayloadOneofCase.TextPayload: case ConformanceRequest.PayloadOneofCase.TextPayload:
return new ConformanceResponse { Skipped = "CSharp doesn't support text format" }; return new ConformanceResponse { Skipped = "CSharp doesn't support text format" };

View File

@ -7,7 +7,7 @@
--> -->
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>net462;netstandard1.1;netstandard2.0</TargetFrameworks> <TargetFrameworks>net462;netstandard1.1;netstandard2.0</TargetFrameworks>
<LangVersion>3.0</LangVersion> <LangVersion>10.0</LangVersion>
<AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<IsPackable>False</IsPackable> <IsPackable>False</IsPackable>

View File

@ -70,7 +70,7 @@ namespace Google.Protobuf
Assert.IsFalse(b1 != b1); Assert.IsFalse(b1 != b1);
Assert.IsFalse(b1 != b2); Assert.IsFalse(b1 != b2);
Assert.IsTrue(ByteString.Empty == ByteString.Empty); Assert.IsTrue(ByteString.Empty == ByteString.Empty);
#pragma warning disable 1718 #pragma warning restore 1718
Assert.IsTrue(b1 != b3); Assert.IsTrue(b1 != b3);
Assert.IsTrue(b1 != b4); Assert.IsTrue(b1 != b4);
Assert.IsTrue(b1 != null); Assert.IsTrue(b1 != null);
@ -276,12 +276,9 @@ namespace Google.Protobuf
Span<byte> s = stackalloc byte[data.Length]; Span<byte> s = stackalloc byte[data.Length];
data.CopyTo(s); data.CopyTo(s);
using (UnmanagedMemoryManager<byte> manager = new UnmanagedMemoryManager<byte>(s)) using var manager = new UnmanagedMemoryManager<byte>(s);
{ ByteString bs = ByteString.AttachBytes(manager.Memory);
ByteString bs = ByteString.AttachBytes(manager.Memory); Assert.AreEqual("Hello world", bs.ToString(Encoding.UTF8));
Assert.AreEqual("Hello world", bs.ToString(Encoding.UTF8));
}
} }
[Test] [Test]
@ -315,12 +312,9 @@ namespace Google.Protobuf
Span<byte> s = stackalloc byte[data.Length]; Span<byte> s = stackalloc byte[data.Length];
data.CopyTo(s); data.CopyTo(s);
using (UnmanagedMemoryManager<byte> manager = new UnmanagedMemoryManager<byte>(s)) using var manager = new UnmanagedMemoryManager<byte>(s);
{ ByteString bs = ByteString.AttachBytes(manager.Memory);
ByteString bs = ByteString.AttachBytes(manager.Memory); Assert.AreEqual("SGVsbG8gd29ybGQ=", bs.ToBase64());
Assert.AreEqual("SGVsbG8gd29ybGQ=", bs.ToBase64());
}
} }
[Test] [Test]

View File

@ -563,8 +563,8 @@ namespace Google.Protobuf
int groupFieldNumber = Proto2.TestAllTypes.OptionalGroupFieldNumber; int groupFieldNumber = Proto2.TestAllTypes.OptionalGroupFieldNumber;
// write Proto2.TestAllTypes with "optional_group" set, but use wrong EndGroup closing tag // write Proto2.TestAllTypes with "optional_group" set, but use wrong EndGroup closing tag
MemoryStream ms = new MemoryStream(); var ms = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(ms); var output = new CodedOutputStream(ms);
output.WriteTag(WireFormat.MakeTag(groupFieldNumber, WireFormat.WireType.StartGroup)); output.WriteTag(WireFormat.MakeTag(groupFieldNumber, WireFormat.WireType.StartGroup));
output.WriteGroup(new Proto2.TestAllTypes.Types.OptionalGroup { A = 12345 }); output.WriteGroup(new Proto2.TestAllTypes.Types.OptionalGroup { A = 12345 });
// end group with different field number // end group with different field number
@ -578,8 +578,8 @@ namespace Google.Protobuf
[Test] [Test]
public void ReadGroup_UnknownFields_WrongEndGroupTag() public void ReadGroup_UnknownFields_WrongEndGroupTag()
{ {
MemoryStream ms = new MemoryStream(); var ms = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(ms); var output = new CodedOutputStream(ms);
output.WriteTag(WireFormat.MakeTag(14, WireFormat.WireType.StartGroup)); output.WriteTag(WireFormat.MakeTag(14, WireFormat.WireType.StartGroup));
// end group with different field number // end group with different field number
output.WriteTag(WireFormat.MakeTag(15, WireFormat.WireType.EndGroup)); output.WriteTag(WireFormat.MakeTag(15, WireFormat.WireType.EndGroup));
@ -654,7 +654,7 @@ namespace Google.Protobuf
output.Flush(); output.Flush();
ms.Position = 0; ms.Position = 0;
CodedInputStream input = new CodedInputStream(ms); var input = new CodedInputStream(ms);
Assert.AreEqual(tag, input.ReadTag()); Assert.AreEqual(tag, input.ReadTag());
Assert.Throws<InvalidProtocolBufferException>(() => input.ReadBytes()); Assert.Throws<InvalidProtocolBufferException>(() => input.ReadBytes());
@ -694,26 +694,24 @@ namespace Google.Protobuf
[Test] [Test]
public void TestSlowPathAvoidance() public void TestSlowPathAvoidance()
{ {
using (var ms = new MemoryStream()) using var ms = new MemoryStream();
{ var output = new CodedOutputStream(ms);
CodedOutputStream output = new CodedOutputStream(ms); output.WriteTag(1, WireFormat.WireType.LengthDelimited);
output.WriteTag(1, WireFormat.WireType.LengthDelimited); output.WriteBytes(ByteString.CopyFrom(new byte[100]));
output.WriteBytes(ByteString.CopyFrom(new byte[100])); output.WriteTag(2, WireFormat.WireType.LengthDelimited);
output.WriteTag(2, WireFormat.WireType.LengthDelimited); output.WriteBytes(ByteString.CopyFrom(new byte[100]));
output.WriteBytes(ByteString.CopyFrom(new byte[100])); output.Flush();
output.Flush();
ms.Position = 0; ms.Position = 0;
CodedInputStream input = new CodedInputStream(ms, new byte[ms.Length / 2], 0, 0, false); CodedInputStream input = new CodedInputStream(ms, new byte[ms.Length / 2], 0, 0, false);
uint tag = input.ReadTag(); uint tag = input.ReadTag();
Assert.AreEqual(1, WireFormat.GetTagFieldNumber(tag)); Assert.AreEqual(1, WireFormat.GetTagFieldNumber(tag));
Assert.AreEqual(100, input.ReadBytes().Length); Assert.AreEqual(100, input.ReadBytes().Length);
tag = input.ReadTag(); tag = input.ReadTag();
Assert.AreEqual(2, WireFormat.GetTagFieldNumber(tag)); Assert.AreEqual(2, WireFormat.GetTagFieldNumber(tag));
Assert.AreEqual(100, input.ReadBytes().Length); Assert.AreEqual(100, input.ReadBytes().Length);
}
} }
[Test] [Test]
@ -927,13 +925,11 @@ namespace Google.Protobuf
{ {
byte[] serializedMessage = GenerateBigSerializedMessage(); byte[] serializedMessage = GenerateBigSerializedMessage();
// How many of these big messages do we need to take us near our 2GB limit? // 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 // Now make a MemoryStream that will fake a near-2GB stream of messages by returning
// our big serialized message 'count' times. // our big serialized message 'count' times.
using (RepeatingMemoryStream stream = new RepeatingMemoryStream(serializedMessage, count)) using var stream = new RepeatingMemoryStream(serializedMessage, count);
{ Assert.DoesNotThrow(() => TestAllTypes.Parser.ParseFrom(stream));
Assert.DoesNotThrow(()=>TestAllTypes.Parser.ParseFrom(stream));
}
} }
[Test] [Test]
@ -941,17 +937,15 @@ namespace Google.Protobuf
{ {
byte[] serializedMessage = GenerateBigSerializedMessage(); byte[] serializedMessage = GenerateBigSerializedMessage();
// How many of these big messages do we need to take us near our 2GB limit? // 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 // Now add one to take us over the 2GB limit
count++; count++;
// Now make a MemoryStream that will fake a near-2GB stream of messages by returning // Now make a MemoryStream that will fake a near-2GB stream of messages by returning
// our big serialized message 'count' times. // our big serialized message 'count' times.
using (RepeatingMemoryStream stream = new RepeatingMemoryStream(serializedMessage, count)) using var stream = new RepeatingMemoryStream(serializedMessage, count);
{ Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(stream),
Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(stream), "Protocol message was too large. May be malicious. " +
"Protocol message was too large. May be malicious. " + "Use CodedInputStream.SetSizeLimit() to increase the size limit.");
"Use CodedInputStream.SetSizeLimit() to increase the size limit.");
}
} }
/// <returns>A serialized big message</returns> /// <returns>A serialized big message</returns>

View File

@ -94,14 +94,12 @@ namespace Google.Protobuf
if ((value >> 32) == 0) if ((value >> 32) == 0)
{ {
MemoryStream rawOutput = new MemoryStream(); MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = CodedOutputStream output = new CodedOutputStream(rawOutput, bufferSize);
new CodedOutputStream(rawOutput, bufferSize);
output.WriteRawVarint32((uint) value); output.WriteRawVarint32((uint) value);
output.Flush(); output.Flush();
Assert.AreEqual(data, rawOutput.ToArray()); Assert.AreEqual(data, rawOutput.ToArray());
var bufferWriter = new TestArrayBufferWriter<byte>(); var bufferWriter = new TestArrayBufferWriter<byte> { MaxGrowBy = bufferSize };
bufferWriter.MaxGrowBy = bufferSize;
WriteContext.Initialize(bufferWriter, out WriteContext ctx); WriteContext.Initialize(bufferWriter, out WriteContext ctx);
ctx.WriteUInt32((uint) value); ctx.WriteUInt32((uint) value);
ctx.Flush(); ctx.Flush();
@ -115,8 +113,7 @@ namespace Google.Protobuf
output.Flush(); output.Flush();
Assert.AreEqual(data, rawOutput.ToArray()); Assert.AreEqual(data, rawOutput.ToArray());
var bufferWriter = new TestArrayBufferWriter<byte>(); var bufferWriter = new TestArrayBufferWriter<byte> { MaxGrowBy = bufferSize };
bufferWriter.MaxGrowBy = bufferSize;
WriteContext.Initialize(bufferWriter, out WriteContext ctx); WriteContext.Initialize(bufferWriter, out WriteContext ctx);
ctx.WriteUInt64(value); ctx.WriteUInt64(value);
ctx.Flush(); ctx.Flush();
@ -190,8 +187,7 @@ namespace Google.Protobuf
output.Flush(); output.Flush();
Assert.AreEqual(data, rawOutput.ToArray()); Assert.AreEqual(data, rawOutput.ToArray());
var bufferWriter = new TestArrayBufferWriter<byte>(); var bufferWriter = new TestArrayBufferWriter<byte> { MaxGrowBy = bufferSize };
bufferWriter.MaxGrowBy = bufferSize;
WriteContext.Initialize(bufferWriter, out WriteContext ctx); WriteContext.Initialize(bufferWriter, out WriteContext ctx);
ctx.WriteFixed32(value); ctx.WriteFixed32(value);
ctx.Flush(); ctx.Flush();
@ -228,8 +224,7 @@ namespace Google.Protobuf
output.Flush(); output.Flush();
Assert.AreEqual(data, rawOutput.ToArray()); Assert.AreEqual(data, rawOutput.ToArray());
var bufferWriter = new TestArrayBufferWriter<byte>(); var bufferWriter = new TestArrayBufferWriter<byte> { MaxGrowBy = blockSize };
bufferWriter.MaxGrowBy = blockSize;
WriteContext.Initialize(bufferWriter, out WriteContext ctx); WriteContext.Initialize(bufferWriter, out WriteContext ctx);
ctx.WriteFixed64(value); ctx.WriteFixed64(value);
ctx.Flush(); ctx.Flush();
@ -270,8 +265,7 @@ namespace Google.Protobuf
output.Flush(); output.Flush();
Assert.AreEqual(rawBytes, rawOutput.ToArray()); Assert.AreEqual(rawBytes, rawOutput.ToArray());
var bufferWriter = new TestArrayBufferWriter<byte>(); var bufferWriter = new TestArrayBufferWriter<byte> { MaxGrowBy = blockSize };
bufferWriter.MaxGrowBy = blockSize;
message.WriteTo(bufferWriter); message.WriteTo(bufferWriter);
Assert.AreEqual(rawBytes, bufferWriter.WrittenSpan.ToArray()); Assert.AreEqual(rawBytes, bufferWriter.WrittenSpan.ToArray());
} }
@ -383,7 +377,9 @@ namespace Google.Protobuf
{ {
byte[] content = new byte[110]; byte[] content = new byte[110];
for (int i = 0; i < content.Length; i++) for (int i = 0; i < content.Length; i++)
{
content[i] = (byte)i; content[i] = (byte)i;
}
byte[] child = new byte[120]; byte[] child = new byte[120];
{ {

View File

@ -91,10 +91,12 @@ namespace Google.Protobuf.Collections
[Test] [Test]
public void AddPreservesInsertionOrder() public void AddPreservesInsertionOrder()
{ {
var map = new MapField<string, string>(); var map = new MapField<string, string>
map.Add("a", "v1"); {
map.Add("b", "v2"); { "a", "v1" },
map.Add("c", "v3"); { "b", "v2" },
{ "c", "v3" }
};
map.Remove("b"); map.Remove("b");
map.Add("d", "v4"); map.Add("d", "v4");
CollectionAssert.AreEqual(new[] { "a", "c", "d" }, map.Keys); CollectionAssert.AreEqual(new[] { "a", "c", "d" }, map.Keys);
@ -104,13 +106,17 @@ namespace Google.Protobuf.Collections
[Test] [Test]
public void EqualityIsOrderInsensitive() public void EqualityIsOrderInsensitive()
{ {
var map1 = new MapField<string, string>(); var map1 = new MapField<string, string>
map1.Add("a", "v1"); {
map1.Add("b", "v2"); { "a", "v1" },
{ "b", "v2" }
};
var map2 = new MapField<string, string>(); var map2 = new MapField<string, string>
map2.Add("b", "v2"); {
map2.Add("a", "v1"); { "b", "v2" },
{ "a", "v1" }
};
EqualityTester.AssertEquality(map1, map2); EqualityTester.AssertEquality(map1, map2);
} }
@ -118,13 +124,17 @@ namespace Google.Protobuf.Collections
[Test] [Test]
public void EqualityIsKeySensitive() public void EqualityIsKeySensitive()
{ {
var map1 = new MapField<string, string>(); var map1 = new MapField<string, string>
map1.Add("first key", "v1"); {
map1.Add("second key", "v2"); { "first key", "v1" },
{ "second key", "v2" }
};
var map2 = new MapField<string, string>(); var map2 = new MapField<string, string>
map2.Add("third key", "v1"); {
map2.Add("fourth key", "v2"); { "third key", "v1" },
{ "fourth key", "v2" }
};
EqualityTester.AssertInequality(map1, map2); EqualityTester.AssertInequality(map1, map2);
} }
@ -143,13 +153,17 @@ namespace Google.Protobuf.Collections
{ {
// Note: Without some care, it's a little easier than one might // Note: Without some care, it's a little easier than one might
// hope to see hash collisions, but only in some environments... // hope to see hash collisions, but only in some environments...
var map1 = new MapField<string, string>(); var map1 = new MapField<string, string>
map1.Add("a", "first value"); {
map1.Add("b", "second value"); { "a", "first value" },
{ "b", "second value" }
};
var map2 = new MapField<string, string>(); var map2 = new MapField<string, string>
map2.Add("a", "third value"); {
map2.Add("b", "fourth value"); { "a", "third value" },
{ "b", "fourth value" }
};
EqualityTester.AssertInequality(map1, map2); EqualityTester.AssertInequality(map1, map2);
} }
@ -183,8 +197,7 @@ namespace Google.Protobuf.Collections
[Test] [Test]
public void Add_KeyAlreadyExists() public void Add_KeyAlreadyExists()
{ {
var map = new MapField<string, string>(); var map = new MapField<string, string> { { "foo", "bar" } };
map.Add("foo", "bar");
Assert.Throws<ArgumentException>(() => map.Add("foo", "baz")); Assert.Throws<ArgumentException>(() => map.Add("foo", "baz"));
} }
@ -211,8 +224,7 @@ namespace Google.Protobuf.Collections
[Test] [Test]
public void Remove_Key() public void Remove_Key()
{ {
var map = new MapField<string, string>(); var map = new MapField<string, string> { { "foo", "bar" } };
map.Add("foo", "bar");
Assert.AreEqual(1, map.Count); Assert.AreEqual(1, map.Count);
Assert.IsFalse(map.Remove("missing")); Assert.IsFalse(map.Remove("missing"));
Assert.AreEqual(1, map.Count); Assert.AreEqual(1, map.Count);
@ -224,8 +236,7 @@ namespace Google.Protobuf.Collections
[Test] [Test]
public void Remove_Pair() public void Remove_Pair()
{ {
var map = new MapField<string, string>(); var map = new MapField<string, string> { { "foo", "bar" } };
map.Add("foo", "bar");
ICollection<KeyValuePair<string, string>> collection = map; ICollection<KeyValuePair<string, string>> collection = map;
Assert.AreEqual(1, map.Count); Assert.AreEqual(1, map.Count);
Assert.IsFalse(collection.Remove(NewKeyValuePair("wrong key", "bar"))); Assert.IsFalse(collection.Remove(NewKeyValuePair("wrong key", "bar")));
@ -240,8 +251,7 @@ namespace Google.Protobuf.Collections
[Test] [Test]
public void CopyTo_Pair() public void CopyTo_Pair()
{ {
var map = new MapField<string, string>(); var map = new MapField<string, string> { { "foo", "bar" } };
map.Add("foo", "bar");
ICollection<KeyValuePair<string, string>> collection = map; ICollection<KeyValuePair<string, string>> collection = map;
KeyValuePair<string, string>[] array = new KeyValuePair<string, string>[3]; KeyValuePair<string, string>[] array = new KeyValuePair<string, string>[3];
collection.CopyTo(array, 1); collection.CopyTo(array, 1);
@ -270,8 +280,7 @@ namespace Google.Protobuf.Collections
[Test] [Test]
public void Indexer_Set() public void Indexer_Set()
{ {
var map = new MapField<string, string>(); var map = new MapField<string, string> { ["x"] = "y" };
map["x"] = "y";
Assert.AreEqual("y", map["x"]); Assert.AreEqual("y", map["x"]);
map["x"] = "z"; // This won't throw, unlike Add. map["x"] = "z"; // This won't throw, unlike Add.
Assert.AreEqual("z", map["x"]); Assert.AreEqual("z", map["x"]);
@ -357,12 +366,10 @@ namespace Google.Protobuf.Collections
IDictionary dictionary = map; IDictionary dictionary = map;
var array = new DictionaryEntry[3]; var array = new DictionaryEntry[3];
dictionary.CopyTo(array, 1); dictionary.CopyTo(array, 1);
CollectionAssert.AreEqual(new[] { default(DictionaryEntry), new DictionaryEntry("x", "y"), default(DictionaryEntry) }, CollectionAssert.AreEqual(new[] { default, new DictionaryEntry("x", "y"), default }, array);
array);
var objectArray = new object[3]; var objectArray = new object[3];
dictionary.CopyTo(objectArray, 1); dictionary.CopyTo(objectArray, 1);
CollectionAssert.AreEqual(new object[] { null, new DictionaryEntry("x", "y"), null }, CollectionAssert.AreEqual(new object[] { null, new DictionaryEntry("x", "y"), null }, objectArray);
objectArray);
} }
[Test] [Test]
@ -580,8 +587,7 @@ namespace Google.Protobuf.Collections
}; };
Assert.AreEqual("x", map[SampleNaNs.Regular]); Assert.AreEqual("x", map[SampleNaNs.Regular]);
Assert.AreEqual("y", map[SampleNaNs.SignallingFlipped]); Assert.AreEqual("y", map[SampleNaNs.SignallingFlipped]);
string ignored; Assert.False(map.TryGetValue(SampleNaNs.PayloadFlipped, out _));
Assert.False(map.TryGetValue(SampleNaNs.PayloadFlipped, out ignored));
} }
[Test] [Test]

View File

@ -33,7 +33,6 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@ -59,8 +58,7 @@ namespace Google.Protobuf.Collections
[Test] [Test]
public void Add_SingleItem() public void Add_SingleItem()
{ {
var list = new RepeatedField<string>(); var list = new RepeatedField<string> { "foo" };
list.Add("foo");
Assert.AreEqual(1, list.Count); Assert.AreEqual(1, list.Count);
Assert.AreEqual("foo", list[0]); Assert.AreEqual("foo", list[0]);
} }
@ -68,8 +66,7 @@ namespace Google.Protobuf.Collections
[Test] [Test]
public void Add_Sequence() public void Add_Sequence()
{ {
var list = new RepeatedField<string>(); var list = new RepeatedField<string> { new[] { "foo", "bar" } };
list.Add(new[] { "foo", "bar" });
Assert.AreEqual(2, list.Count); Assert.AreEqual(2, list.Count);
Assert.AreEqual("foo", list[0]); Assert.AreEqual("foo", list[0]);
Assert.AreEqual("bar", list[1]); Assert.AreEqual("bar", list[1]);
@ -293,15 +290,13 @@ namespace Google.Protobuf.Collections
public void Enumerator() public void Enumerator()
{ {
var list = new RepeatedField<string> { "first", "second" }; var list = new RepeatedField<string> { "first", "second" };
using (var enumerator = list.GetEnumerator()) using var enumerator = list.GetEnumerator();
{ Assert.IsTrue(enumerator.MoveNext());
Assert.IsTrue(enumerator.MoveNext()); Assert.AreEqual("first", enumerator.Current);
Assert.AreEqual("first", enumerator.Current); Assert.IsTrue(enumerator.MoveNext());
Assert.IsTrue(enumerator.MoveNext()); Assert.AreEqual("second", enumerator.Current);
Assert.AreEqual("second", enumerator.Current); Assert.IsFalse(enumerator.MoveNext());
Assert.IsFalse(enumerator.MoveNext()); Assert.IsFalse(enumerator.MoveNext());
Assert.IsFalse(enumerator.MoveNext());
}
} }
[Test] [Test]

View File

@ -29,6 +29,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion #endregion
using NUnit.Framework; using NUnit.Framework;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;

View File

@ -50,6 +50,5 @@ namespace Google.Protobuf
{ {
AssertIsDeprecated(typeof(TestDeprecatedFields).GetProperty("DeprecatedInt32")); AssertIsDeprecated(typeof(TestDeprecatedFields).GetProperty("DeprecatedInt32"));
} }
} }
} }

View File

@ -1,3 +1,35 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2015 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using System; using System;
using System.Collections; using System.Collections;
using Google.Protobuf.TestProtos.Proto2; using Google.Protobuf.TestProtos.Proto2;
@ -72,7 +104,7 @@ namespace Google.Protobuf
message.SetExtension(OptionalStringExtension, "abcd"); message.SetExtension(OptionalStringExtension, "abcd");
var input = new CodedInputStream(message.ToByteArray()); var input = new CodedInputStream(message.ToByteArray());
input.ExtensionRegistry = new ExtensionRegistry() { OptionalStringExtension }; input.ExtensionRegistry = new ExtensionRegistry { OptionalStringExtension };
input.ReadTag(); // TryMergeFieldFrom expects that a tag was just read and will inspect the LastTag value input.ReadTag(); // TryMergeFieldFrom expects that a tag was just read and will inspect the LastTag value
ExtensionSet<TestAllExtensions> extensionSet = null; ExtensionSet<TestAllExtensions> extensionSet = null;

View File

@ -30,7 +30,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion #endregion
using System.Collections.Generic;
using Google.Protobuf.Collections; using Google.Protobuf.Collections;
using Google.Protobuf.TestProtos; using Google.Protobuf.TestProtos;
using NUnit.Framework; using NUnit.Framework;

View File

@ -1,3 +1,35 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2015 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using Google.Protobuf.TestProtos.Proto2; using Google.Protobuf.TestProtos.Proto2;
using Proto2 = Google.Protobuf.TestProtos.Proto2; using Proto2 = Google.Protobuf.TestProtos.Proto2;
using NUnit.Framework; using NUnit.Framework;
@ -387,11 +419,9 @@ namespace Google.Protobuf
var message = new TestAllExtensions(); var message = new TestAllExtensions();
message.SetExtension(UnittestExtensions.OptionalBoolExtension, true); message.SetExtension(UnittestExtensions.OptionalBoolExtension, true);
byte[] bytes = message.ToByteArray(); byte[] bytes = message.ToByteArray();
using (CodedInputStream input = new CodedInputStream(bytes)) using CodedInputStream input = new CodedInputStream(bytes);
{ var parsed = TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry() { UnittestExtensions.OptionalBoolExtension }).ParseFrom(input);
var parsed = TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry() { UnittestExtensions.OptionalBoolExtension }).ParseFrom(input); Assert.AreEqual(message, parsed);
Assert.AreEqual(message, parsed);
}
} }
} }
} }

View File

@ -33,10 +33,7 @@
using System; using System;
using System.IO; using System.IO;
using Google.Protobuf.TestProtos; using Google.Protobuf.TestProtos;
using Proto2 = Google.Protobuf.TestProtos.Proto2;
using NUnit.Framework; using NUnit.Framework;
using System.Collections;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using Google.Protobuf.WellKnownTypes; using Google.Protobuf.WellKnownTypes;
@ -658,9 +655,11 @@ namespace Google.Protobuf
[Test] [Test]
public void OneofSerialization_NonDefaultValue() public void OneofSerialization_NonDefaultValue()
{ {
var message = new TestAllTypes(); var message = new TestAllTypes
message.OneofString = "this would take a bit of space"; {
message.OneofUint32 = 10; OneofString = "this would take a bit of space",
OneofUint32 = 10
};
var bytes = message.ToByteArray(); var bytes = message.ToByteArray();
Assert.AreEqual(3, bytes.Length); // 2 bytes for the tag + 1 for the value - no string! Assert.AreEqual(3, bytes.Length); // 2 bytes for the tag + 1 for the value - no string!
@ -675,9 +674,11 @@ namespace Google.Protobuf
[Test] [Test]
public void OneofSerialization_DefaultValue() public void OneofSerialization_DefaultValue()
{ {
var message = new TestAllTypes(); var message = new TestAllTypes
message.OneofString = "this would take a bit of space"; {
message.OneofUint32 = 0; // This is the default value for UInt32; normally wouldn't be serialized OneofString = "this would take a bit of space",
OneofUint32 = 0 // This is the default value for UInt32; normally wouldn't be serialized
};
var bytes = message.ToByteArray(); var bytes = message.ToByteArray();
Assert.AreEqual(3, bytes.Length); // 2 bytes for the tag + 1 for the value - it's still serialized Assert.AreEqual(3, bytes.Length); // 2 bytes for the tag + 1 for the value - it's still serialized
@ -746,7 +747,6 @@ namespace Google.Protobuf
[Test] [Test]
public void ExtraEndGroupThrows() public void ExtraEndGroupThrows()
{ {
var message = SampleMessages.CreateFullTestAllTypes();
var stream = new MemoryStream(); var stream = new MemoryStream();
var output = new CodedOutputStream(stream); var output = new CodedOutputStream(stream);

View File

@ -168,8 +168,7 @@ namespace Google.Protobuf
[Test] [Test]
public void WithFormatDefaultValues_DoesNotAffectProto3OptionalFields() public void WithFormatDefaultValues_DoesNotAffectProto3OptionalFields()
{ {
var message = new TestProto3Optional(); var message = new TestProto3Optional { OptionalInt32 = 0 };
message.OptionalInt32 = 0;
var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true)); var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true));
var json = formatter.Format(message); var json = formatter.Format(message);
// The non-optional proto3 fields are formatted, as is the optional-but-specified field. // The non-optional proto3 fields are formatted, as is the optional-but-specified field.
@ -179,8 +178,7 @@ namespace Google.Protobuf
[Test] [Test]
public void WithFormatDefaultValues_DoesNotAffectProto2Fields() public void WithFormatDefaultValues_DoesNotAffectProto2Fields()
{ {
var message = new TestProtos.Proto2.ForeignMessage(); var message = new TestProtos.Proto2.ForeignMessage { C = 0 };
message.C = 0;
var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true)); var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true));
var json = formatter.Format(message); var json = formatter.Format(message);
// The specified field is formatted, but the non-specified field (d) is not. // The specified field is formatted, but the non-specified field (d) is not.

View File

@ -641,7 +641,7 @@ namespace Google.Protobuf
[TestCase("9999-12-31T23:59:59.999999999Z", null)] [TestCase("9999-12-31T23:59:59.999999999Z", null)]
public void Timestamp_Valid(string jsonValue, string expectedFormatted) public void Timestamp_Valid(string jsonValue, string expectedFormatted)
{ {
expectedFormatted = expectedFormatted ?? jsonValue; expectedFormatted ??= jsonValue;
string json = WrapInQuotes(jsonValue); string json = WrapInQuotes(jsonValue);
var parsed = Timestamp.Parser.ParseJson(json); var parsed = Timestamp.Parser.ParseJson(json);
Assert.AreEqual(WrapInQuotes(expectedFormatted), parsed.ToString()); Assert.AreEqual(WrapInQuotes(expectedFormatted), parsed.ToString());
@ -758,7 +758,7 @@ namespace Google.Protobuf
[TestCase("-315576000000s", null)] [TestCase("-315576000000s", null)]
public void Duration_Valid(string jsonValue, string expectedFormatted) public void Duration_Valid(string jsonValue, string expectedFormatted)
{ {
expectedFormatted = expectedFormatted ?? jsonValue; expectedFormatted ??= jsonValue;
string json = WrapInQuotes(jsonValue); string json = WrapInQuotes(jsonValue);
var parsed = Duration.Parser.ParseJson(json); var parsed = Duration.Parser.ParseJson(json);
Assert.AreEqual(WrapInQuotes(expectedFormatted), parsed.ToString()); Assert.AreEqual(WrapInQuotes(expectedFormatted), parsed.ToString());
@ -1066,25 +1066,26 @@ namespace Google.Protobuf
""mapStringNestedMessage"": null ""mapStringNestedMessage"": null
}"; }";
TestAllTypesProto3 message = new TestAllTypesProto3(); var message = new TestAllTypesProto3
{
message.OptionalInt32 = 1; OptionalInt32 = 1,
message.OptionalInt64 = 1; OptionalInt64 = 1,
message.OptionalUint32 = 1; OptionalUint32 = 1,
message.OptionalUint64 = 1; OptionalUint64 = 1,
message.OptionalSint32 = 1; OptionalSint32 = 1,
message.OptionalSint64 = 1; OptionalSint64 = 1,
message.OptionalFixed32 = 1; OptionalFixed32 = 1,
message.OptionalFixed64 = 1; OptionalFixed64 = 1,
message.OptionalSfixed32 = 1; OptionalSfixed32 = 1,
message.OptionalSfixed64 = 1; OptionalSfixed64 = 1,
message.OptionalFloat = 1; OptionalFloat = 1,
message.OptionalDouble = 1; OptionalDouble = 1,
message.OptionalBool = true; OptionalBool = true,
message.OptionalString = "1"; OptionalString = "1",
message.OptionalBytes = ByteString.CopyFrom(new byte[] { 1 }); OptionalBytes = ByteString.CopyFrom(new byte[] { 1 }),
message.OptionalNestedEnum = TestAllTypesProto3.Types.NestedEnum.Bar; OptionalNestedEnum = TestAllTypesProto3.Types.NestedEnum.Bar,
message.OptionalNestedMessage = new TestAllTypesProto3.Types.NestedMessage(); OptionalNestedMessage = new TestAllTypesProto3.Types.NestedMessage()
};
message.RepeatedInt32.Add(1); message.RepeatedInt32.Add(1);
message.RepeatedInt64.Add(1); message.RepeatedInt64.Add(1);
message.RepeatedUint32.Add(1); message.RepeatedUint32.Add(1);

View File

@ -29,6 +29,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion #endregion
using NUnit.Framework; using NUnit.Framework;
using System; using System;
using System.IO; using System.IO;
@ -126,7 +127,7 @@ namespace Google.Protobuf
tokenizer.PushBack(token); tokenizer.PushBack(token);
Assert.AreEqual(0, tokenizer.ObjectDepth); Assert.AreEqual(0, tokenizer.ObjectDepth);
// Read the same token again, and get back to depth 1 // Read the same token again, and get back to depth 1
token = tokenizer.Next(); _ = tokenizer.Next();
Assert.AreEqual(1, tokenizer.ObjectDepth); Assert.AreEqual(1, tokenizer.ObjectDepth);
// Now the same in reverse, with EndObject // Now the same in reverse, with EndObject

View File

@ -29,14 +29,12 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion #endregion
using Google.Protobuf;
using Google.Protobuf.Reflection;
using System.Buffers; using System.Buffers;
using pb = global::Google.Protobuf; using pb = Google.Protobuf;
using pbr = global::Google.Protobuf.Reflection; using pbr = Google.Protobuf.Reflection;
using NUnit.Framework; using NUnit.Framework;
using System.IO; using System.IO;
using System;
using Google.Protobuf.Buffers; using Google.Protobuf.Buffers;
namespace Google.Protobuf namespace Google.Protobuf

View File

@ -136,8 +136,7 @@ namespace Google.Protobuf
// test for different IBufferWriter.GetSpan() segment sizes // test for different IBufferWriter.GetSpan() segment sizes
for (int blockSize = 1; blockSize < 256; blockSize *= 2) for (int blockSize = 1; blockSize < 256; blockSize *= 2)
{ {
var segmentedBufferWriter = new TestArrayBufferWriter<byte>(); var segmentedBufferWriter = new TestArrayBufferWriter<byte> { MaxGrowBy = blockSize };
segmentedBufferWriter.MaxGrowBy = blockSize;
message.WriteTo(segmentedBufferWriter); message.WriteTo(segmentedBufferWriter);
Assert.AreEqual(bytes, segmentedBufferWriter.WrittenSpan.ToArray()); Assert.AreEqual(bytes, segmentedBufferWriter.WrittenSpan.ToArray());
} }

View File

@ -38,7 +38,7 @@ using UnitTest.Issues.TestProtos;
namespace Google.Protobuf.Test namespace Google.Protobuf.Test
{ {
class Proto3OptionalTest public class Proto3OptionalTest
{ {
[Test] [Test]
public void OptionalInt32FieldLifecycle() public void OptionalInt32FieldLifecycle()

View File

@ -33,9 +33,6 @@
using System; using System;
using System.Buffers; using System.Buffers;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Google.Protobuf namespace Google.Protobuf
{ {
@ -50,7 +47,7 @@ namespace Google.Protobuf
if (addEmptySegmentDelimiters) if (addEmptySegmentDelimiters)
{ {
segments.Add(new byte[0]); segments.Add(Array.Empty<byte>());
} }
var currentIndex = 0; var currentIndex = 0;
@ -65,7 +62,7 @@ namespace Google.Protobuf
if (addEmptySegmentDelimiters) if (addEmptySegmentDelimiters)
{ {
segments.Add(new byte[0]); segments.Add(Array.Empty<byte>());
} }
} }

View File

@ -77,43 +77,42 @@ namespace Google.Protobuf
/// <param name="args"></param> /// <param name="args"></param>
/// <param name="workingDirectory"></param> /// <param name="workingDirectory"></param>
private void RunOldCsharpCompilerAndCheckSuccess(string args, string workingDirectory) private void RunOldCsharpCompilerAndCheckSuccess(string args, string workingDirectory)
{ {
using (var process = new Process()) using var process = new Process();
// Get the path to the old C# 5 compiler from .NET framework. This approach is not 100% reliable, but works on most machines.
// Alternative way of getting the framework path is System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory()
// but it only works with the net45 target.
var oldCsharpCompilerPath = Path.Combine(Environment.GetEnvironmentVariable("WINDIR"), "Microsoft.NET", "Framework", "v4.0.30319", "csc.exe");
process.StartInfo.FileName = oldCsharpCompilerPath;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.Arguments = args;
process.StartInfo.WorkingDirectory = workingDirectory;
process.OutputDataReceived += (sender, e) =>
{ {
// Get the path to the old C# 5 compiler from .NET framework. This approach is not 100% reliable, but works on most machines. if (e.Data != null)
// Alternative way of getting the framework path is System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory()
// but it only works with the net45 target.
var oldCsharpCompilerPath = Path.Combine(Environment.GetEnvironmentVariable("WINDIR"), "Microsoft.NET", "Framework", "v4.0.30319", "csc.exe");
process.StartInfo.FileName = oldCsharpCompilerPath;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.Arguments = args;
process.StartInfo.WorkingDirectory = workingDirectory;
process.OutputDataReceived += (sender, e) =>
{ {
if (e.Data != null) Console.WriteLine(e.Data);
{ }
Console.WriteLine(e.Data); };
} process.ErrorDataReceived += (sender, e) =>
}; {
process.ErrorDataReceived += (sender, e) => if (e.Data != null)
{ {
if (e.Data != null) Console.WriteLine(e.Data);
{ }
Console.WriteLine(e.Data); };
}
};
process.Start(); process.Start();
process.BeginErrorReadLine(); process.BeginErrorReadLine();
process.BeginOutputReadLine(); process.BeginOutputReadLine();
process.WaitForExit(); process.WaitForExit();
Assert.AreEqual(0, process.ExitCode); Assert.AreEqual(0, process.ExitCode);
}
} }
} }
} }

View File

@ -31,13 +31,10 @@
#endregion #endregion
using Google.Protobuf.Reflection; using Google.Protobuf.Reflection;
using Google.Protobuf.WellKnownTypes;
using NUnit.Framework; using NUnit.Framework;
using System; using System;
using System.IO;
using System.Linq; using System.Linq;
using UnitTest.Issues.TestProtos; using UnitTest.Issues.TestProtos;
using static Google.Protobuf.WireFormat;
using static UnitTest.Issues.TestProtos.ComplexOptionType2.Types; using static UnitTest.Issues.TestProtos.ComplexOptionType2.Types;
using static UnitTest.Issues.TestProtos.UnittestCustomOptionsProto3Extensions; using static UnitTest.Issues.TestProtos.UnittestCustomOptionsProto3Extensions;
using static UnitTest.Issues.TestProtos.DummyMessageContainingEnum.Types; using static UnitTest.Issues.TestProtos.DummyMessageContainingEnum.Types;
@ -65,7 +62,7 @@ namespace Google.Protobuf.Test.Reflection
} }
else else
{ {
v = default(E); v = default;
return false; return false;
} }
}; };

View File

@ -35,7 +35,6 @@ using NUnit.Framework;
using ProtobufUnittest; using ProtobufUnittest;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using UnitTest.Issues.TestProtos; using UnitTest.Issues.TestProtos;

View File

@ -30,10 +30,8 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion #endregion
using System;
using System.IO; using System.IO;
using Google.Protobuf.TestProtos; using Google.Protobuf.TestProtos;
using Proto2 = Google.Protobuf.TestProtos.Proto2;
using NUnit.Framework; using NUnit.Framework;
namespace Google.Protobuf namespace Google.Protobuf
@ -127,8 +125,7 @@ namespace Google.Protobuf
public void TestClone(IMessage message) public void TestClone(IMessage message)
{ {
var emptyMessage = new TestEmptyMessage(); var emptyMessage = new TestEmptyMessage();
var otherEmptyMessage = new TestEmptyMessage(); TestEmptyMessage otherEmptyMessage = emptyMessage.Clone();
otherEmptyMessage = emptyMessage.Clone();
Assert.AreEqual(emptyMessage.CalculateSize(), otherEmptyMessage.CalculateSize()); Assert.AreEqual(emptyMessage.CalculateSize(), otherEmptyMessage.CalculateSize());
Assert.AreEqual(emptyMessage.ToByteArray(), otherEmptyMessage.ToByteArray()); Assert.AreEqual(emptyMessage.ToByteArray(), otherEmptyMessage.ToByteArray());
@ -169,13 +166,13 @@ namespace Google.Protobuf
byte[] data = message.ToByteArray(); byte[] data = message.ToByteArray();
int fullSize = message.CalculateSize(); int fullSize = message.CalculateSize();
Action<IMessage> assertEmpty = msg => void AssertEmpty(IMessage msg)
{ {
Assert.AreEqual(0, msg.CalculateSize()); Assert.AreEqual(0, msg.CalculateSize());
Assert.AreEqual(goldenEmptyMessage, msg); Assert.AreEqual(goldenEmptyMessage, msg);
}; }
Action<IMessage> assertFull = msg => Assert.AreEqual(fullSize, msg.CalculateSize()); void AssertFull(IMessage msg) => Assert.AreEqual(fullSize, msg.CalculateSize());
// Test the behavior of the parsers with and without discarding, both generic and non-generic. // Test the behavior of the parsers with and without discarding, both generic and non-generic.
MessageParser<TestEmptyMessage> retainingParser1 = TestEmptyMessage.Parser; MessageParser<TestEmptyMessage> retainingParser1 = TestEmptyMessage.Parser;
@ -184,28 +181,28 @@ namespace Google.Protobuf
MessageParser discardingParser2 = retainingParser2.WithDiscardUnknownFields(true); MessageParser discardingParser2 = retainingParser2.WithDiscardUnknownFields(true);
// Test parse from byte[] // Test parse from byte[]
MessageParsingHelpers.AssertReadingMessage(retainingParser1, data, m => assertFull(m)); MessageParsingHelpers.AssertReadingMessage(retainingParser1, data, m => AssertFull(m));
MessageParsingHelpers.AssertReadingMessage(retainingParser2, data, m => assertFull(m)); MessageParsingHelpers.AssertReadingMessage(retainingParser2, data, m => AssertFull(m));
MessageParsingHelpers.AssertReadingMessage(discardingParser1, data, m => assertEmpty(m)); MessageParsingHelpers.AssertReadingMessage(discardingParser1, data, m => AssertEmpty(m));
MessageParsingHelpers.AssertReadingMessage(discardingParser2, data, m => assertEmpty(m)); MessageParsingHelpers.AssertReadingMessage(discardingParser2, data, m => AssertEmpty(m));
// Test parse from byte[] with offset // Test parse from byte[] with offset
assertFull(retainingParser1.ParseFrom(data, 0, data.Length)); AssertFull(retainingParser1.ParseFrom(data, 0, data.Length));
assertFull(retainingParser2.ParseFrom(data, 0, data.Length)); AssertFull(retainingParser2.ParseFrom(data, 0, data.Length));
assertEmpty(discardingParser1.ParseFrom(data, 0, data.Length)); AssertEmpty(discardingParser1.ParseFrom(data, 0, data.Length));
assertEmpty(discardingParser2.ParseFrom(data, 0, data.Length)); AssertEmpty(discardingParser2.ParseFrom(data, 0, data.Length));
// Test parse from CodedInputStream // Test parse from CodedInputStream
assertFull(retainingParser1.ParseFrom(new CodedInputStream(data))); AssertFull(retainingParser1.ParseFrom(new CodedInputStream(data)));
assertFull(retainingParser2.ParseFrom(new CodedInputStream(data))); AssertFull(retainingParser2.ParseFrom(new CodedInputStream(data)));
assertEmpty(discardingParser1.ParseFrom(new CodedInputStream(data))); AssertEmpty(discardingParser1.ParseFrom(new CodedInputStream(data)));
assertEmpty(discardingParser2.ParseFrom(new CodedInputStream(data))); AssertEmpty(discardingParser2.ParseFrom(new CodedInputStream(data)));
// Test parse from Stream // Test parse from Stream
assertFull(retainingParser1.ParseFrom(new MemoryStream(data))); AssertFull(retainingParser1.ParseFrom(new MemoryStream(data)));
assertFull(retainingParser2.ParseFrom(new MemoryStream(data))); AssertFull(retainingParser2.ParseFrom(new MemoryStream(data)));
assertEmpty(discardingParser1.ParseFrom(new MemoryStream(data))); AssertEmpty(discardingParser1.ParseFrom(new MemoryStream(data)));
assertEmpty(discardingParser2.ParseFrom(new MemoryStream(data))); AssertEmpty(discardingParser2.ParseFrom(new MemoryStream(data)));
} }
[Test] [Test]

View File

@ -126,7 +126,6 @@ namespace Google.Protobuf.WellKnownTypes
[TestCase("foobar", "")] [TestCase("foobar", "")]
public void GetTypeName(string typeUrl, string expectedTypeName) public void GetTypeName(string typeUrl, string expectedTypeName)
{ {
var any = new Any { TypeUrl = typeUrl };
Assert.AreEqual(expectedTypeName, Any.GetTypeName(typeUrl)); Assert.AreEqual(expectedTypeName, Any.GetTypeName(typeUrl));
} }

View File

@ -189,7 +189,7 @@ namespace Google.Protobuf
/// <param name="stream">The stream to copy into a ByteString.</param> /// <param name="stream">The stream to copy into a ByteString.</param>
/// <param name="cancellationToken">The cancellation token to use when reading from the stream, if any.</param> /// <param name="cancellationToken">The cancellation token to use when reading from the stream, if any.</param>
/// <returns>A ByteString with content read from the given stream.</returns> /// <returns>A ByteString with content read from the given stream.</returns>
public static Task<ByteString> FromStreamAsync(Stream stream, CancellationToken cancellationToken = default(CancellationToken)) public static Task<ByteString> FromStreamAsync(Stream stream, CancellationToken cancellationToken = default)
{ {
ProtoPreconditions.CheckNotNull(stream, nameof(stream)); ProtoPreconditions.CheckNotNull(stream, nameof(stream));
return ByteStringAsync.FromStreamAsyncCore(stream, cancellationToken); return ByteStringAsync.FromStreamAsyncCore(stream, cancellationToken);
@ -340,7 +340,7 @@ namespace Google.Protobuf
{ {
return true; return true;
} }
if (ReferenceEquals(lhs, null) || ReferenceEquals(rhs, null)) if (lhs is null || rhs is null)
{ {
return false; return false;
} }

View File

@ -32,10 +32,7 @@
using Google.Protobuf.Collections; using Google.Protobuf.Collections;
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security; using System.Security;
namespace Google.Protobuf namespace Google.Protobuf
@ -649,21 +646,6 @@ namespace Google.Protobuf
} }
} }
/// <summary>
/// Called when buffer is empty to read more bytes from the
/// input. If <paramref name="mustSucceed"/> is true, RefillBuffer() guarantees that
/// either there will be at least one byte in the buffer when it returns
/// or it will throw an exception. If <paramref name="mustSucceed"/> is false,
/// RefillBuffer() returns false if no more bytes were available.
/// </summary>
/// <param name="mustSucceed"></param>
/// <returns></returns>
private bool RefillBuffer(bool mustSucceed)
{
var span = new ReadOnlySpan<byte>(buffer);
return state.segmentedBufferHelper.RefillBuffer(ref span, ref state, mustSucceed);
}
/// <summary> /// <summary>
/// Reads a fixed size of bytes from the input. /// Reads a fixed size of bytes from the input.
/// </summary> /// </summary>

View File

@ -30,11 +30,9 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion #endregion
using Google.Protobuf.Collections;
using System; using System;
using System.IO; using System.IO;
using System.Security; using System.Security;
using System.Text;
namespace Google.Protobuf namespace Google.Protobuf
{ {

View File

@ -31,7 +31,6 @@
#endregion #endregion
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace Google.Protobuf.Collections namespace Google.Protobuf.Collections
{ {

View File

@ -31,9 +31,7 @@
#endregion #endregion
using Google.Protobuf.Compatibility; using Google.Protobuf.Compatibility;
using Google.Protobuf.Reflection;
using System; using System;
using System.Buffers;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@ -74,9 +72,8 @@ namespace Google.Protobuf.Collections
private static readonly EqualityComparer<TKey> KeyEqualityComparer = ProtobufEqualityComparers.GetEqualityComparer<TKey>(); private static readonly EqualityComparer<TKey> KeyEqualityComparer = ProtobufEqualityComparers.GetEqualityComparer<TKey>();
// TODO: Don't create the map/list until we have an entry. (Assume many maps will be empty.) // TODO: Don't create the map/list until we have an entry. (Assume many maps will be empty.)
private readonly Dictionary<TKey, LinkedListNode<KeyValuePair<TKey, TValue>>> map = private readonly Dictionary<TKey, LinkedListNode<KeyValuePair<TKey, TValue>>> map = new(KeyEqualityComparer);
new Dictionary<TKey, LinkedListNode<KeyValuePair<TKey, TValue>>>(KeyEqualityComparer); private readonly LinkedList<KeyValuePair<TKey, TValue>> list = new();
private readonly LinkedList<KeyValuePair<TKey, TValue>> list = new LinkedList<KeyValuePair<TKey, TValue>>();
/// <summary> /// <summary>
/// Creates a deep clone of this object. /// Creates a deep clone of this object.
@ -144,8 +141,7 @@ namespace Google.Protobuf.Collections
public bool Remove(TKey key) public bool Remove(TKey key)
{ {
ProtoPreconditions.CheckNotNullUnconstrained(key, nameof(key)); ProtoPreconditions.CheckNotNullUnconstrained(key, nameof(key));
LinkedListNode<KeyValuePair<TKey, TValue>> node; if (map.TryGetValue(key, out LinkedListNode<KeyValuePair<TKey, TValue>> node))
if (map.TryGetValue(key, out node))
{ {
map.Remove(key); map.Remove(key);
node.List.Remove(node); node.List.Remove(node);
@ -167,15 +163,14 @@ namespace Google.Protobuf.Collections
/// <returns><c>true</c> if the map contains an element with the specified key; otherwise, <c>false</c>.</returns> /// <returns><c>true</c> if the map contains an element with the specified key; otherwise, <c>false</c>.</returns>
public bool TryGetValue(TKey key, out TValue value) public bool TryGetValue(TKey key, out TValue value)
{ {
LinkedListNode<KeyValuePair<TKey, TValue>> node; if (map.TryGetValue(key, out LinkedListNode<KeyValuePair<TKey, TValue>> node))
if (map.TryGetValue(key, out node))
{ {
value = node.Value.Value; value = node.Value.Value;
return true; return true;
} }
else else
{ {
value = default(TValue); value = default;
return false; return false;
} }
} }
@ -192,8 +187,7 @@ namespace Google.Protobuf.Collections
get get
{ {
ProtoPreconditions.CheckNotNullUnconstrained(key, nameof(key)); ProtoPreconditions.CheckNotNullUnconstrained(key, nameof(key));
TValue value; if (TryGetValue(key, out TValue value))
if (TryGetValue(key, out value))
{ {
return value; return value;
} }
@ -207,9 +201,8 @@ namespace Google.Protobuf.Collections
{ {
ProtoPreconditions.CheckNotNullUnconstrained(value, nameof(value)); ProtoPreconditions.CheckNotNullUnconstrained(value, nameof(value));
} }
LinkedListNode<KeyValuePair<TKey, TValue>> node;
var pair = new KeyValuePair<TKey, TValue>(key, value); var pair = new KeyValuePair<TKey, TValue>(key, value);
if (map.TryGetValue(key, out node)) if (map.TryGetValue(key, out LinkedListNode<KeyValuePair<TKey, TValue>> node))
{ {
node.Value = pair; node.Value = pair;
} }
@ -224,12 +217,12 @@ namespace Google.Protobuf.Collections
/// <summary> /// <summary>
/// Gets a collection containing the keys in the map. /// Gets a collection containing the keys in the map.
/// </summary> /// </summary>
public ICollection<TKey> Keys { get { return new MapView<TKey>(this, pair => pair.Key, ContainsKey); } } public ICollection<TKey> Keys => new MapView<TKey>(this, pair => pair.Key, ContainsKey);
/// <summary> /// <summary>
/// Gets a collection containing the values in the map. /// Gets a collection containing the values in the map.
/// </summary> /// </summary>
public ICollection<TValue> Values { get { return new MapView<TValue>(this, pair => pair.Value, ContainsValue); } } public ICollection<TValue> Values => new MapView<TValue>(this, pair => pair.Value, ContainsValue);
/// <summary> /// <summary>
/// Adds the specified entries to the map. The keys and values are not automatically cloned. /// Adds the specified entries to the map. The keys and values are not automatically cloned.
@ -250,10 +243,7 @@ namespace Google.Protobuf.Collections
/// <returns> /// <returns>
/// An enumerator that can be used to iterate through the collection. /// An enumerator that can be used to iterate through the collection.
/// </returns> /// </returns>
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() => list.GetEnumerator();
{
return list.GetEnumerator();
}
/// <summary> /// <summary>
/// Returns an enumerator that iterates through a collection. /// Returns an enumerator that iterates through a collection.
@ -261,19 +251,13 @@ namespace Google.Protobuf.Collections
/// <returns> /// <returns>
/// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection. /// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.
/// </returns> /// </returns>
IEnumerator IEnumerable.GetEnumerator() IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
{
return GetEnumerator();
}
/// <summary> /// <summary>
/// Adds the specified item to the map. /// Adds the specified item to the map.
/// </summary> /// </summary>
/// <param name="item">The item to add to the map.</param> /// <param name="item">The item to add to the map.</param>
void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item) void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item) => Add(item.Key, item.Value);
{
Add(item.Key, item.Value);
}
/// <summary> /// <summary>
/// Removes all items from the map. /// Removes all items from the map.
@ -289,21 +273,16 @@ namespace Google.Protobuf.Collections
/// </summary> /// </summary>
/// <param name="item">The key/value pair to find.</param> /// <param name="item">The key/value pair to find.</param>
/// <returns></returns> /// <returns></returns>
bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item) bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item) =>
{ TryGetValue(item.Key, out TValue value) && ValueEqualityComparer.Equals(item.Value, value);
TValue value;
return TryGetValue(item.Key, out value) && ValueEqualityComparer.Equals(item.Value, value);
}
/// <summary> /// <summary>
/// Copies the key/value pairs in this map to an array. /// Copies the key/value pairs in this map to an array.
/// </summary> /// </summary>
/// <param name="array">The array to copy the entries into.</param> /// <param name="array">The array to copy the entries into.</param>
/// <param name="arrayIndex">The index of the array at which to start copying values.</param> /// <param name="arrayIndex">The index of the array at which to start copying values.</param>
void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) =>
{
list.CopyTo(array, arrayIndex); list.CopyTo(array, arrayIndex);
}
/// <summary> /// <summary>
/// Removes the specified key/value pair from the map. /// Removes the specified key/value pair from the map.
@ -317,8 +296,7 @@ namespace Google.Protobuf.Collections
{ {
throw new ArgumentException("Key is null", nameof(item)); throw new ArgumentException("Key is null", nameof(item));
} }
LinkedListNode<KeyValuePair<TKey, TValue>> node; if (map.TryGetValue(item.Key, out LinkedListNode<KeyValuePair<TKey, TValue>> node) &&
if (map.TryGetValue(item.Key, out node) &&
EqualityComparer<TValue>.Default.Equals(item.Value, node.Value.Value)) EqualityComparer<TValue>.Default.Equals(item.Value, node.Value.Value))
{ {
map.Remove(item.Key); map.Remove(item.Key);
@ -334,12 +312,12 @@ namespace Google.Protobuf.Collections
/// <summary> /// <summary>
/// Gets the number of elements contained in the map. /// Gets the number of elements contained in the map.
/// </summary> /// </summary>
public int Count { get { return list.Count; } } public int Count => list.Count;
/// <summary> /// <summary>
/// Gets a value indicating whether the map is read-only. /// Gets a value indicating whether the map is read-only.
/// </summary> /// </summary>
public bool IsReadOnly { get { return false; } } public bool IsReadOnly => false;
/// <summary> /// <summary>
/// Determines whether the specified <see cref="System.Object" />, is equal to this instance. /// Determines whether the specified <see cref="System.Object" />, is equal to this instance.
@ -348,10 +326,7 @@ namespace Google.Protobuf.Collections
/// <returns> /// <returns>
/// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>. /// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.
/// </returns> /// </returns>
public override bool Equals(object other) public override bool Equals(object other) => Equals(other as MapField<TKey, TValue>);
{
return Equals(other as MapField<TKey, TValue>);
}
/// <summary> /// <summary>
/// Returns a hash code for this instance. /// Returns a hash code for this instance.
@ -396,8 +371,7 @@ namespace Google.Protobuf.Collections
var valueComparer = ValueEqualityComparer; var valueComparer = ValueEqualityComparer;
foreach (var pair in this) foreach (var pair in this)
{ {
TValue value; if (!other.TryGetValue(pair.Key, out TValue value))
if (!other.TryGetValue(pair.Key, out value))
{ {
return false; return false;
} }
@ -529,33 +503,20 @@ namespace Google.Protobuf.Collections
} }
#region IDictionary explicit interface implementation #region IDictionary explicit interface implementation
void IDictionary.Add(object key, object value)
{
Add((TKey)key, (TValue)value);
}
bool IDictionary.Contains(object key) void IDictionary.Add(object key, object value) => Add((TKey)key, (TValue)value);
{
if (!(key is TKey))
{
return false;
}
return ContainsKey((TKey)key);
}
IDictionaryEnumerator IDictionary.GetEnumerator() bool IDictionary.Contains(object key) => key is TKey k && ContainsKey(k);
{
return new DictionaryEnumerator(GetEnumerator()); IDictionaryEnumerator IDictionary.GetEnumerator() => new DictionaryEnumerator(GetEnumerator());
}
void IDictionary.Remove(object key) void IDictionary.Remove(object key)
{ {
ProtoPreconditions.CheckNotNull(key, nameof(key)); ProtoPreconditions.CheckNotNull(key, nameof(key));
if (!(key is TKey)) if (key is TKey k)
{ {
return; Remove(k);
} }
Remove((TKey)key);
} }
void ICollection.CopyTo(Array array, int index) void ICollection.CopyTo(Array array, int index)
@ -565,28 +526,27 @@ namespace Google.Protobuf.Collections
temp.CopyTo(array, index); temp.CopyTo(array, index);
} }
bool IDictionary.IsFixedSize { get { return false; } } bool IDictionary.IsFixedSize => false;
ICollection IDictionary.Keys { get { return (ICollection)Keys; } } ICollection IDictionary.Keys => (ICollection)Keys;
ICollection IDictionary.Values { get { return (ICollection)Values; } } ICollection IDictionary.Values => (ICollection)Values;
bool ICollection.IsSynchronized { get { return false; } } bool ICollection.IsSynchronized => false;
object ICollection.SyncRoot { get { return this; } } object ICollection.SyncRoot => this;
object IDictionary.this[object key] object IDictionary.this[object key]
{ {
get get
{ {
ProtoPreconditions.CheckNotNull(key, nameof(key)); ProtoPreconditions.CheckNotNull(key, nameof(key));
if (!(key is TKey)) if (key is TKey k)
{ {
return null; TryGetValue(k, out TValue value);
return value;
} }
TValue value; return null;
TryGetValue((TKey)key, out value);
return value;
} }
set set
@ -610,20 +570,14 @@ namespace Google.Protobuf.Collections
this.enumerator = enumerator; this.enumerator = enumerator;
} }
public bool MoveNext() public bool MoveNext() => enumerator.MoveNext();
{
return enumerator.MoveNext();
}
public void Reset() public void Reset() => enumerator.Reset();
{
enumerator.Reset();
}
public object Current { get { return Entry; } } public object Current => Entry;
public DictionaryEntry Entry { get { return new DictionaryEntry(Key, Value); } } public DictionaryEntry Entry => new DictionaryEntry(Key, Value);
public object Key { get { return enumerator.Current.Key; } } public object Key => enumerator.Current.Key;
public object Value { get { return enumerator.Current.Value; } } public object Value => enumerator.Current.Value;
} }
/// <summary> /// <summary>
@ -682,28 +636,19 @@ namespace Google.Protobuf.Collections
this.containsCheck = containsCheck; this.containsCheck = containsCheck;
} }
public int Count { get { return parent.Count; } } public int Count => parent.Count;
public bool IsReadOnly { get { return true; } } public bool IsReadOnly => true;
public bool IsSynchronized { get { return false; } } public bool IsSynchronized => false;
public object SyncRoot { get { return parent; } } public object SyncRoot => parent;
public void Add(T item) public void Add(T item) => throw new NotSupportedException();
{
throw new NotSupportedException();
}
public void Clear() public void Clear() => throw new NotSupportedException();
{
throw new NotSupportedException();
}
public bool Contains(T item) public bool Contains(T item) => containsCheck(item);
{
return containsCheck(item);
}
public void CopyTo(T[] array, int arrayIndex) public void CopyTo(T[] array, int arrayIndex)
{ {
@ -726,15 +671,9 @@ namespace Google.Protobuf.Collections
return parent.list.Select(projection).GetEnumerator(); return parent.list.Select(projection).GetEnumerator();
} }
public bool Remove(T item) public bool Remove(T item) => throw new NotSupportedException();
{
throw new NotSupportedException();
}
IEnumerator IEnumerable.GetEnumerator() IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
{
return GetEnumerator();
}
public void CopyTo(Array array, int index) public void CopyTo(Array array, int index)
{ {

View File

@ -35,7 +35,6 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Security; using System.Security;
using System.Threading;
namespace Google.Protobuf.Collections namespace Google.Protobuf.Collections
{ {
@ -74,8 +73,7 @@ namespace Google.Protobuf.Collections
if (array != EmptyArray) if (array != EmptyArray)
{ {
clone.array = (T[])array.Clone(); clone.array = (T[])array.Clone();
IDeepCloneable<T>[] cloneableArray = clone.array as IDeepCloneable<T>[]; if (clone.array is IDeepCloneable<T>[] cloneableArray)
if (cloneableArray != null)
{ {
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
@ -349,10 +347,7 @@ namespace Google.Protobuf.Collections
/// </summary> /// </summary>
/// <param name="item">The item to find.</param> /// <param name="item">The item to find.</param>
/// <returns><c>true</c> if this collection contains the given item; <c>false</c> otherwise.</returns> /// <returns><c>true</c> if this collection contains the given item; <c>false</c> otherwise.</returns>
public bool Contains(T item) public bool Contains(T item) => IndexOf(item) != -1;
{
return IndexOf(item) != -1;
}
/// <summary> /// <summary>
/// Copies this collection to the given array. /// Copies this collection to the given array.
@ -378,7 +373,7 @@ namespace Google.Protobuf.Collections
} }
Array.Copy(array, index + 1, array, index, count - index - 1); Array.Copy(array, index + 1, array, index, count - index - 1);
count--; count--;
array[count] = default(T); array[count] = default;
return true; return true;
} }
@ -402,8 +397,7 @@ namespace Google.Protobuf.Collections
// Optimization 1: If the collection we're adding is already a RepeatedField<T>, // Optimization 1: If the collection we're adding is already a RepeatedField<T>,
// we know the values are valid. // we know the values are valid.
var otherRepeatedField = values as RepeatedField<T>; if (values is RepeatedField<T> otherRepeatedField)
if (otherRepeatedField != null)
{ {
EnsureSize(count + otherRepeatedField.count); EnsureSize(count + otherRepeatedField.count);
Array.Copy(otherRepeatedField.array, 0, array, count, otherRepeatedField.count); Array.Copy(otherRepeatedField.array, 0, array, count, otherRepeatedField.count);
@ -413,8 +407,7 @@ namespace Google.Protobuf.Collections
// Optimization 2: The collection is an ICollection, so we can expand // Optimization 2: The collection is an ICollection, so we can expand
// just once and ask the collection to copy itself into the array. // just once and ask the collection to copy itself into the array.
var collection = values as ICollection; if (values is ICollection collection)
if (collection != null)
{ {
var extraCount = collection.Count; var extraCount = collection.Count;
// For reference types and nullable value types, we need to check that there are no nulls // For reference types and nullable value types, we need to check that there are no nulls
@ -484,21 +477,15 @@ namespace Google.Protobuf.Collections
/// <returns> /// <returns>
/// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>. /// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.
/// </returns> /// </returns>
public override bool Equals(object obj) public override bool Equals(object obj) => Equals(obj as RepeatedField<T>);
{
return Equals(obj as RepeatedField<T>);
}
/// <summary> /// <summary>
/// Returns an enumerator that iterates through a collection. /// Returns an enumerator that iterates through a collection.
/// </summary> /// </summary>
/// <returns> /// <returns>
/// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection. /// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.
/// </returns> /// </returns>
IEnumerator IEnumerable.GetEnumerator() IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
{
return GetEnumerator();
}
/// <summary> /// <summary>
/// Returns a hash code for this instance. /// Returns a hash code for this instance.
@ -523,7 +510,7 @@ namespace Google.Protobuf.Collections
/// <returns><c>true</c> if <paramref name="other"/> refers to an equal repeated field; <c>false</c> otherwise.</returns> /// <returns><c>true</c> if <paramref name="other"/> refers to an equal repeated field; <c>false</c> otherwise.</returns>
public bool Equals(RepeatedField<T> other) public bool Equals(RepeatedField<T> other)
{ {
if (ReferenceEquals(other, null)) if (other is null)
{ {
return false; return false;
} }
@ -596,7 +583,7 @@ namespace Google.Protobuf.Collections
} }
Array.Copy(array, index + 1, array, index, count - index - 1); Array.Copy(array, index + 1, array, index, count - index - 1);
count--; count--;
array[count] = default(T); array[count] = default;
} }
/// <summary> /// <summary>
@ -642,10 +629,7 @@ namespace Google.Protobuf.Collections
#region Explicit interface implementation for IList and ICollection. #region Explicit interface implementation for IList and ICollection.
bool IList.IsFixedSize => false; bool IList.IsFixedSize => false;
void ICollection.CopyTo(Array array, int index) void ICollection.CopyTo(Array array, int index) => Array.Copy(this.array, 0, array, index, count);
{
Array.Copy(this.array, 0, array, index, count);
}
bool ICollection.IsSynchronized => false; bool ICollection.IsSynchronized => false;
@ -653,8 +637,8 @@ namespace Google.Protobuf.Collections
object IList.this[int index] object IList.this[int index]
{ {
get { return this[index]; } get => this[index];
set { this[index] = (T)value; } set => this[index] = (T)value;
} }
int IList.Add(object value) int IList.Add(object value)
@ -663,32 +647,18 @@ namespace Google.Protobuf.Collections
return count - 1; return count - 1;
} }
bool IList.Contains(object value) bool IList.Contains(object value) => (value is T t && Contains(t));
{
return (value is T && Contains((T)value));
}
int IList.IndexOf(object value) int IList.IndexOf(object value) => (value is T t) ? IndexOf(t) : -1;
{
if (!(value is T))
{
return -1;
}
return IndexOf((T)value);
}
void IList.Insert(int index, object value) void IList.Insert(int index, object value) => Insert(index, (T) value);
{
Insert(index, (T) value);
}
void IList.Remove(object value) void IList.Remove(object value)
{ {
if (!(value is T)) if (value is T t)
{ {
return; Remove(t);
} }
Remove((T)value);
} }
#endregion #endregion
} }

View File

@ -77,7 +77,7 @@ namespace Google.Protobuf
this.codec = codec; this.codec = codec;
} }
internal TValue DefaultValue => codec != null ? codec.DefaultValue : default(TValue); internal TValue DefaultValue => codec != null ? codec.DefaultValue : default;
internal override Type TargetType => typeof(TTarget); internal override Type TargetType => typeof(TTarget);

View File

@ -55,7 +55,7 @@ namespace Google.Protobuf
internal static ExtensionComparer Instance = new ExtensionComparer(); internal static ExtensionComparer Instance = new ExtensionComparer();
} }
private IDictionary<ObjectIntPair<Type>, Extension> extensions; private readonly IDictionary<ObjectIntPair<Type>, Extension> extensions;
/// <summary> /// <summary>
/// Creates a new empty extension registry /// Creates a new empty extension registry

View File

@ -61,8 +61,7 @@ namespace Google.Protobuf
/// </summary> /// </summary>
public static TValue Get<TTarget, TValue>(ref ExtensionSet<TTarget> set, Extension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget> public static TValue Get<TTarget, TValue>(ref ExtensionSet<TTarget> set, Extension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget>
{ {
IExtensionValue value; if (TryGetValue(ref set, extension, out IExtensionValue value))
if (TryGetValue(ref set, extension, out value))
{ {
// The stored ExtensionValue can be a different type to what is being requested. // The stored ExtensionValue can be a different type to what is being requested.
// This happens when the same extension proto is compiled in different assemblies. // This happens when the same extension proto is compiled in different assemblies.
@ -98,7 +97,7 @@ namespace Google.Protobuf
} }
} }
} }
else else
{ {
return extension.DefaultValue; return extension.DefaultValue;
} }
@ -109,8 +108,7 @@ namespace Google.Protobuf
/// </summary> /// </summary>
public static RepeatedField<TValue> Get<TTarget, TValue>(ref ExtensionSet<TTarget> set, RepeatedExtension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget> public static RepeatedField<TValue> Get<TTarget, TValue>(ref ExtensionSet<TTarget> set, RepeatedExtension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget>
{ {
IExtensionValue value; if (TryGetValue(ref set, extension, out IExtensionValue value))
if (TryGetValue(ref set, extension, out value))
{ {
if (value is RepeatedExtensionValue<TValue> extensionValue) if (value is RepeatedExtensionValue<TValue> extensionValue)
{ {
@ -132,7 +130,7 @@ namespace Google.Protobuf
} }
} }
} }
else else
{ {
return null; return null;
} }
@ -193,8 +191,7 @@ namespace Google.Protobuf
/// </summary> /// </summary>
public static bool Has<TTarget, TValue>(ref ExtensionSet<TTarget> set, Extension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget> public static bool Has<TTarget, TValue>(ref ExtensionSet<TTarget> set, Extension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget>
{ {
IExtensionValue value; return TryGetValue(ref set, extension, out IExtensionValue _);
return TryGetValue(ref set, extension, out value);
} }
/// <summary> /// <summary>
@ -252,20 +249,18 @@ namespace Google.Protobuf
/// </summary> /// </summary>
public static bool TryMergeFieldFrom<TTarget>(ref ExtensionSet<TTarget> set, ref ParseContext ctx) where TTarget : IExtendableMessage<TTarget> public static bool TryMergeFieldFrom<TTarget>(ref ExtensionSet<TTarget> set, ref ParseContext ctx) where TTarget : IExtendableMessage<TTarget>
{ {
Extension extension;
int lastFieldNumber = WireFormat.GetTagFieldNumber(ctx.LastTag); int lastFieldNumber = WireFormat.GetTagFieldNumber(ctx.LastTag);
IExtensionValue extensionValue; if (set != null && set.ValuesByNumber.TryGetValue(lastFieldNumber, out IExtensionValue extensionValue))
if (set != null && set.ValuesByNumber.TryGetValue(lastFieldNumber, out extensionValue))
{ {
extensionValue.MergeFrom(ref ctx); extensionValue.MergeFrom(ref ctx);
return true; return true;
} }
else if (ctx.ExtensionRegistry != null && ctx.ExtensionRegistry.ContainsInputField(ctx.LastTag, typeof(TTarget), out extension)) else if (ctx.ExtensionRegistry != null && ctx.ExtensionRegistry.ContainsInputField(ctx.LastTag, typeof(TTarget), out Extension extension))
{ {
IExtensionValue value = extension.CreateValue(); IExtensionValue value = extension.CreateValue();
value.MergeFrom(ref ctx); value.MergeFrom(ref ctx);
set = (set ?? new ExtensionSet<TTarget>()); set ??= new ExtensionSet<TTarget>();
set.ValuesByNumber.Add(extension.FieldNumber, value); set.ValuesByNumber.Add(extension.FieldNumber, value);
return true; return true;
} }
@ -290,8 +285,7 @@ namespace Google.Protobuf
} }
foreach (var pair in second.ValuesByNumber) foreach (var pair in second.ValuesByNumber)
{ {
IExtensionValue value; if (first.ValuesByNumber.TryGetValue(pair.Key, out IExtensionValue value))
if (first.ValuesByNumber.TryGetValue(pair.Key, out value))
{ {
value.MergeFrom(pair.Value); value.MergeFrom(pair.Value);
} }
@ -365,8 +359,7 @@ namespace Google.Protobuf
} }
foreach (var pair in ValuesByNumber) foreach (var pair in ValuesByNumber)
{ {
IExtensionValue secondValue; if (!otherSet.ValuesByNumber.TryGetValue(pair.Key, out IExtensionValue secondValue))
if (!otherSet.ValuesByNumber.TryGetValue(pair.Key, out secondValue))
{ {
return false; return false;
} }

View File

@ -32,7 +32,6 @@
using Google.Protobuf.Collections; using Google.Protobuf.Collections;
using System; using System;
using System.Linq;
namespace Google.Protobuf namespace Google.Protobuf
{ {
@ -50,7 +49,7 @@ namespace Google.Protobuf
internal sealed class ExtensionValue<T> : IExtensionValue internal sealed class ExtensionValue<T> : IExtensionValue
{ {
private T field; private T field;
private FieldCodec<T> codec; private readonly FieldCodec<T> codec;
internal ExtensionValue(FieldCodec<T> codec) internal ExtensionValue(FieldCodec<T> codec)
{ {

View File

@ -31,7 +31,6 @@
#endregion #endregion
using Google.Protobuf.Collections; using Google.Protobuf.Collections;
using Google.Protobuf.Compatibility;
using Google.Protobuf.WellKnownTypes; using Google.Protobuf.WellKnownTypes;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -51,150 +50,105 @@ namespace Google.Protobuf
/// </summary> /// </summary>
/// <param name="tag">The tag.</param> /// <param name="tag">The tag.</param>
/// <returns>A codec for the given tag.</returns> /// <returns>A codec for the given tag.</returns>
public static FieldCodec<string> ForString(uint tag) public static FieldCodec<string> ForString(uint tag) => ForString(tag, "");
{
return FieldCodec.ForString(tag, "");
}
/// <summary> /// <summary>
/// Retrieves a codec suitable for a bytes field with the given tag. /// Retrieves a codec suitable for a bytes field with the given tag.
/// </summary> /// </summary>
/// <param name="tag">The tag.</param> /// <param name="tag">The tag.</param>
/// <returns>A codec for the given tag.</returns> /// <returns>A codec for the given tag.</returns>
public static FieldCodec<ByteString> ForBytes(uint tag) public static FieldCodec<ByteString> ForBytes(uint tag) => ForBytes(tag, ByteString.Empty);
{
return FieldCodec.ForBytes(tag, ByteString.Empty);
}
/// <summary> /// <summary>
/// Retrieves a codec suitable for a bool field with the given tag. /// Retrieves a codec suitable for a bool field with the given tag.
/// </summary> /// </summary>
/// <param name="tag">The tag.</param> /// <param name="tag">The tag.</param>
/// <returns>A codec for the given tag.</returns> /// <returns>A codec for the given tag.</returns>
public static FieldCodec<bool> ForBool(uint tag) public static FieldCodec<bool> ForBool(uint tag) => ForBool(tag, false);
{
return FieldCodec.ForBool(tag, false);
}
/// <summary> /// <summary>
/// Retrieves a codec suitable for an int32 field with the given tag. /// Retrieves a codec suitable for an int32 field with the given tag.
/// </summary> /// </summary>
/// <param name="tag">The tag.</param> /// <param name="tag">The tag.</param>
/// <returns>A codec for the given tag.</returns> /// <returns>A codec for the given tag.</returns>
public static FieldCodec<int> ForInt32(uint tag) public static FieldCodec<int> ForInt32(uint tag) => ForInt32(tag, 0);
{
return FieldCodec.ForInt32(tag, 0);
}
/// <summary> /// <summary>
/// Retrieves a codec suitable for an sint32 field with the given tag. /// Retrieves a codec suitable for an sint32 field with the given tag.
/// </summary> /// </summary>
/// <param name="tag">The tag.</param> /// <param name="tag">The tag.</param>
/// <returns>A codec for the given tag.</returns> /// <returns>A codec for the given tag.</returns>
public static FieldCodec<int> ForSInt32(uint tag) public static FieldCodec<int> ForSInt32(uint tag) => ForSInt32(tag, 0);
{
return FieldCodec.ForSInt32(tag, 0);
}
/// <summary> /// <summary>
/// Retrieves a codec suitable for a fixed32 field with the given tag. /// Retrieves a codec suitable for a fixed32 field with the given tag.
/// </summary> /// </summary>
/// <param name="tag">The tag.</param> /// <param name="tag">The tag.</param>
/// <returns>A codec for the given tag.</returns> /// <returns>A codec for the given tag.</returns>
public static FieldCodec<uint> ForFixed32(uint tag) public static FieldCodec<uint> ForFixed32(uint tag) => ForFixed32(tag, 0);
{
return FieldCodec.ForFixed32(tag, 0);
}
/// <summary> /// <summary>
/// Retrieves a codec suitable for an sfixed32 field with the given tag. /// Retrieves a codec suitable for an sfixed32 field with the given tag.
/// </summary> /// </summary>
/// <param name="tag">The tag.</param> /// <param name="tag">The tag.</param>
/// <returns>A codec for the given tag.</returns> /// <returns>A codec for the given tag.</returns>
public static FieldCodec<int> ForSFixed32(uint tag) public static FieldCodec<int> ForSFixed32(uint tag) => ForSFixed32(tag, 0);
{
return FieldCodec.ForSFixed32(tag, 0);
}
/// <summary> /// <summary>
/// Retrieves a codec suitable for a uint32 field with the given tag. /// Retrieves a codec suitable for a uint32 field with the given tag.
/// </summary> /// </summary>
/// <param name="tag">The tag.</param> /// <param name="tag">The tag.</param>
/// <returns>A codec for the given tag.</returns> /// <returns>A codec for the given tag.</returns>
public static FieldCodec<uint> ForUInt32(uint tag) public static FieldCodec<uint> ForUInt32(uint tag) => ForUInt32(tag, 0);
{
return FieldCodec.ForUInt32(tag, 0);
}
/// <summary> /// <summary>
/// Retrieves a codec suitable for an int64 field with the given tag. /// Retrieves a codec suitable for an int64 field with the given tag.
/// </summary> /// </summary>
/// <param name="tag">The tag.</param> /// <param name="tag">The tag.</param>
/// <returns>A codec for the given tag.</returns> /// <returns>A codec for the given tag.</returns>
public static FieldCodec<long> ForInt64(uint tag) public static FieldCodec<long> ForInt64(uint tag) => ForInt64(tag, 0);
{
return FieldCodec.ForInt64(tag, 0);
}
/// <summary> /// <summary>
/// Retrieves a codec suitable for an sint64 field with the given tag. /// Retrieves a codec suitable for an sint64 field with the given tag.
/// </summary> /// </summary>
/// <param name="tag">The tag.</param> /// <param name="tag">The tag.</param>
/// <returns>A codec for the given tag.</returns> /// <returns>A codec for the given tag.</returns>
public static FieldCodec<long> ForSInt64(uint tag) public static FieldCodec<long> ForSInt64(uint tag) => ForSInt64(tag, 0);
{
return FieldCodec.ForSInt64(tag, 0);
}
/// <summary> /// <summary>
/// Retrieves a codec suitable for a fixed64 field with the given tag. /// Retrieves a codec suitable for a fixed64 field with the given tag.
/// </summary> /// </summary>
/// <param name="tag">The tag.</param> /// <param name="tag">The tag.</param>
/// <returns>A codec for the given tag.</returns> /// <returns>A codec for the given tag.</returns>
public static FieldCodec<ulong> ForFixed64(uint tag) public static FieldCodec<ulong> ForFixed64(uint tag) => ForFixed64(tag, 0);
{
return FieldCodec.ForFixed64(tag, 0);
}
/// <summary> /// <summary>
/// Retrieves a codec suitable for an sfixed64 field with the given tag. /// Retrieves a codec suitable for an sfixed64 field with the given tag.
/// </summary> /// </summary>
/// <param name="tag">The tag.</param> /// <param name="tag">The tag.</param>
/// <returns>A codec for the given tag.</returns> /// <returns>A codec for the given tag.</returns>
public static FieldCodec<long> ForSFixed64(uint tag) public static FieldCodec<long> ForSFixed64(uint tag) => ForSFixed64(tag, 0);
{
return FieldCodec.ForSFixed64(tag, 0);
}
/// <summary> /// <summary>
/// Retrieves a codec suitable for a uint64 field with the given tag. /// Retrieves a codec suitable for a uint64 field with the given tag.
/// </summary> /// </summary>
/// <param name="tag">The tag.</param> /// <param name="tag">The tag.</param>
/// <returns>A codec for the given tag.</returns> /// <returns>A codec for the given tag.</returns>
public static FieldCodec<ulong> ForUInt64(uint tag) public static FieldCodec<ulong> ForUInt64(uint tag) => ForUInt64(tag, 0);
{
return FieldCodec.ForUInt64(tag, 0);
}
/// <summary> /// <summary>
/// Retrieves a codec suitable for a float field with the given tag. /// Retrieves a codec suitable for a float field with the given tag.
/// </summary> /// </summary>
/// <param name="tag">The tag.</param> /// <param name="tag">The tag.</param>
/// <returns>A codec for the given tag.</returns> /// <returns>A codec for the given tag.</returns>
public static FieldCodec<float> ForFloat(uint tag) public static FieldCodec<float> ForFloat(uint tag) => ForFloat(tag, 0);
{
return FieldCodec.ForFloat(tag, 0);
}
/// <summary> /// <summary>
/// Retrieves a codec suitable for a double field with the given tag. /// Retrieves a codec suitable for a double field with the given tag.
/// </summary> /// </summary>
/// <param name="tag">The tag.</param> /// <param name="tag">The tag.</param>
/// <returns>A codec for the given tag.</returns> /// <returns>A codec for the given tag.</returns>
public static FieldCodec<double> ForDouble(uint tag) public static FieldCodec<double> ForDouble(uint tag) => ForDouble(tag, 0);
{
return FieldCodec.ForDouble(tag, 0);
}
// Enums are tricky. We can probably use expression trees to build these delegates automatically, // Enums are tricky. We can probably use expression trees to build these delegates automatically,
// but it's easy to generate the code for it. // but it's easy to generate the code for it.
@ -206,10 +160,8 @@ namespace Google.Protobuf
/// <param name="toInt32">A conversion function from <see cref="Int32"/> to the enum type.</param> /// <param name="toInt32">A conversion function from <see cref="Int32"/> to the enum type.</param>
/// <param name="fromInt32">A conversion function from the enum type to <see cref="Int32"/>.</param> /// <param name="fromInt32">A conversion function from the enum type to <see cref="Int32"/>.</param>
/// <returns>A codec for the given tag.</returns> /// <returns>A codec for the given tag.</returns>
public static FieldCodec<T> ForEnum<T>(uint tag, Func<T, int> toInt32, Func<int, T> fromInt32) public static FieldCodec<T> ForEnum<T>(uint tag, Func<T, int> toInt32, Func<int, T> fromInt32) =>
{ ForEnum(tag, toInt32, fromInt32, default);
return FieldCodec.ForEnum(tag, toInt32, fromInt32, default(T));
}
/// <summary> /// <summary>
/// Retrieves a codec suitable for a string field with the given tag. /// Retrieves a codec suitable for a string field with the given tag.
@ -565,8 +517,7 @@ namespace Google.Protobuf
/// </summary> /// </summary>
internal static FieldCodec<T> GetCodec<T>() internal static FieldCodec<T> GetCodec<T>()
{ {
object value; if (!Codecs.TryGetValue(typeof(T), out object value))
if (!Codecs.TryGetValue(typeof(T), out value))
{ {
throw new InvalidOperationException("Invalid type argument requested for wrapper codec: " + typeof(T)); throw new InvalidOperationException("Invalid type argument requested for wrapper codec: " + typeof(T));
} }
@ -575,8 +526,7 @@ namespace Google.Protobuf
internal static ValueReader<T?> GetReader<T>() where T : struct internal static ValueReader<T?> GetReader<T>() where T : struct
{ {
object value; if (!Readers.TryGetValue(typeof(T), out object value))
if (!Readers.TryGetValue(typeof(T), out value))
{ {
throw new InvalidOperationException("Invalid type argument requested for wrapper reader: " + typeof(T)); throw new InvalidOperationException("Invalid type argument requested for wrapper reader: " + typeof(T));
} }

View File

@ -120,8 +120,7 @@ namespace Google.Protobuf
return this; return this;
} }
Node childNode; if (!node.Children.TryGetValue(part, out Node childNode))
if (!node.Children.TryGetValue(part, out childNode))
{ {
createNewBranch = true; createNewBranch = true;
childNode = new Node(); childNode = new Node();

View File

@ -5,8 +5,7 @@
<Copyright>Copyright 2015, Google Inc.</Copyright> <Copyright>Copyright 2015, Google Inc.</Copyright>
<AssemblyTitle>Google Protocol Buffers</AssemblyTitle> <AssemblyTitle>Google Protocol Buffers</AssemblyTitle>
<VersionPrefix>3.21.1</VersionPrefix> <VersionPrefix>3.21.1</VersionPrefix>
<!-- C# 7.2 is required for Span/BufferWriter/ReadOnlySequence --> <LangVersion>10.0</LangVersion>
<LangVersion>7.2</LangVersion>
<Authors>Google Inc.</Authors> <Authors>Google Inc.</Authors>
<TargetFrameworks>netstandard1.1;netstandard2.0;net45;net50</TargetFrameworks> <TargetFrameworks>netstandard1.1;netstandard2.0;net45;net50</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>

View File

@ -136,5 +136,5 @@ namespace Google.Protobuf
{ {
return new InvalidProtocolBufferException("Message was missing required fields"); return new InvalidProtocolBufferException("Message was missing required fields");
} }
} }
} }

View File

@ -62,7 +62,6 @@ namespace Google.Protobuf
internal const string AnyTypeUrlField = "@type"; internal const string AnyTypeUrlField = "@type";
internal const string AnyDiagnosticValueField = "@value"; internal const string AnyDiagnosticValueField = "@value";
internal const string AnyWellKnownTypeValueField = "value"; internal const string AnyWellKnownTypeValueField = "value";
private const string TypeUrlPrefix = "type.googleapis.com";
private const string NameValueSeparator = ": "; private const string NameValueSeparator = ": ";
private const string PropertySeparator = ", "; private const string PropertySeparator = ", ";
@ -202,8 +201,7 @@ namespace Google.Protobuf
} }
if (DiagnosticOnly) if (DiagnosticOnly)
{ {
ICustomDiagnosticMessage customDiagnosticMessage = message as ICustomDiagnosticMessage; if (message is ICustomDiagnosticMessage customDiagnosticMessage)
if (customDiagnosticMessage != null)
{ {
writer.Write(customDiagnosticMessage.ToDiagnosticString()); writer.Write(customDiagnosticMessage.ToDiagnosticString());
return; return;
@ -320,39 +318,20 @@ namespace Google.Protobuf
IList list = (IList) value; IList list = (IList) value;
return list.Count == 0; return list.Count == 0;
} }
switch (descriptor.FieldType) return descriptor.FieldType switch
{ {
case FieldType.Bool: FieldType.Bool => (bool) value == false,
return (bool) value == false; FieldType.Bytes => (ByteString) value == ByteString.Empty,
case FieldType.Bytes: FieldType.String => (string) value == "",
return (ByteString) value == ByteString.Empty; FieldType.Double => (double) value == 0.0,
case FieldType.String: FieldType.SInt32 or FieldType.Int32 or FieldType.SFixed32 or FieldType.Enum => (int) value == 0,
return (string) value == ""; FieldType.Fixed32 or FieldType.UInt32 => (uint) value == 0,
case FieldType.Double: FieldType.Fixed64 or FieldType.UInt64 => (ulong) value == 0,
return (double) value == 0.0; FieldType.SFixed64 or FieldType.Int64 or FieldType.SInt64 => (long) value == 0,
case FieldType.SInt32: FieldType.Float => (float) value == 0f,
case FieldType.Int32: FieldType.Message or FieldType.Group => value == null,
case FieldType.SFixed32: _ => throw new ArgumentException("Invalid field type"),
case FieldType.Enum: };
return (int) value == 0;
case FieldType.Fixed32:
case FieldType.UInt32:
return (uint) value == 0;
case FieldType.Fixed64:
case FieldType.UInt64:
return (ulong) value == 0;
case FieldType.SFixed64:
case FieldType.Int64:
case FieldType.SInt64:
return (long) value == 0;
case FieldType.Float:
return (float) value == 0f;
case FieldType.Message:
case FieldType.Group: // Never expect to get this, but...
return value == null;
default:
throw new ArgumentException("Invalid field type");
}
} }
/// <summary> /// <summary>
@ -369,28 +348,28 @@ namespace Google.Protobuf
{ {
WriteNull(writer); WriteNull(writer);
} }
else if (value is bool) else if (value is bool b)
{ {
writer.Write((bool)value ? "true" : "false"); writer.Write(b ? "true" : "false");
} }
else if (value is ByteString) else if (value is ByteString byteString)
{ {
// Nothing in Base64 needs escaping // Nothing in Base64 needs escaping
writer.Write('"'); writer.Write('"');
writer.Write(((ByteString)value).ToBase64()); writer.Write(byteString.ToBase64());
writer.Write('"'); writer.Write('"');
} }
else if (value is string) else if (value is string str)
{ {
WriteString(writer, (string)value); WriteString(writer, str);
} }
else if (value is IDictionary) else if (value is IDictionary dictionary)
{ {
WriteDictionary(writer, (IDictionary)value); WriteDictionary(writer, dictionary);
} }
else if (value is IList) else if (value is IList list)
{ {
WriteList(writer, (IList)value); WriteList(writer, list);
} }
else if (value is int || value is uint) else if (value is int || value is uint)
{ {
@ -437,9 +416,9 @@ namespace Google.Protobuf
writer.Write(text); writer.Write(text);
} }
} }
else if (value is IMessage) else if (value is IMessage message)
{ {
Format((IMessage)value, writer); Format(message, writer);
} }
else else
{ {
@ -469,9 +448,8 @@ namespace Google.Protobuf
// WriteValue will do the right thing.) // WriteValue will do the right thing.)
if (descriptor.IsWrapperType) if (descriptor.IsWrapperType)
{ {
if (value is IMessage) if (value is IMessage message)
{ {
var message = (IMessage) value;
value = message.Descriptor.Fields[WrappersReflection.WrapperValueFieldNumber].Accessor.GetValue(message); value = message.Descriptor.Fields[WrappersReflection.WrapperValueFieldNumber].Accessor.GetValue(message);
} }
WriteValue(writer, value); WriteValue(writer, value);
@ -679,15 +657,15 @@ namespace Google.Protobuf
writer.Write(PropertySeparator); writer.Write(PropertySeparator);
} }
string keyText; string keyText;
if (pair.Key is string) if (pair.Key is string s)
{ {
keyText = (string) pair.Key; keyText = s;
} }
else if (pair.Key is bool) else if (pair.Key is bool b)
{ {
keyText = (bool) pair.Key ? "true" : "false"; keyText = b ? "true" : "false";
} }
else if (pair.Key is int || pair.Key is uint | pair.Key is long || pair.Key is ulong) else if (pair.Key is int || pair.Key is uint || pair.Key is long || pair.Key is ulong)
{ {
keyText = ((IFormattable) pair.Key).ToString("d", CultureInfo.InvariantCulture); keyText = ((IFormattable) pair.Key).ToString("d", CultureInfo.InvariantCulture);
} }
@ -916,9 +894,8 @@ namespace Google.Protobuf
} }
} }
string originalName;
// If this returns false, originalName will be null, which is what we want. // If this returns false, originalName will be null, which is what we want.
nameMapping.TryGetValue(value, out originalName); nameMapping.TryGetValue(value, out string originalName);
return originalName; return originalName;
} }

View File

@ -70,8 +70,7 @@ namespace Google.Protobuf
// TODO: Consider introducing a class containing parse state of the parser, tokenizer and depth. That would simplify these handlers // TODO: Consider introducing a class containing parse state of the parser, tokenizer and depth. That would simplify these handlers
// and the signatures of various methods. // and the signatures of various methods.
private static readonly Dictionary<string, Action<JsonParser, IMessage, JsonTokenizer>> private static readonly Dictionary<string, Action<JsonParser, IMessage, JsonTokenizer>> WellKnownTypeHandlers = new()
WellKnownTypeHandlers = new Dictionary<string, Action<JsonParser, IMessage, JsonTokenizer>>
{ {
{ Timestamp.Descriptor.FullName, (parser, message, tokenizer) => MergeTimestamp(message, tokenizer.Next()) }, { Timestamp.Descriptor.FullName, (parser, message, tokenizer) => MergeTimestamp(message, tokenizer.Next()) },
{ Duration.Descriptor.FullName, (parser, message, tokenizer) => MergeDuration(message, tokenizer.Next()) }, { Duration.Descriptor.FullName, (parser, message, tokenizer) => MergeDuration(message, tokenizer.Next()) },
@ -156,8 +155,7 @@ namespace Google.Protobuf
} }
if (message.Descriptor.IsWellKnownType) if (message.Descriptor.IsWellKnownType)
{ {
Action<JsonParser, IMessage, JsonTokenizer> handler; if (WellKnownTypeHandlers.TryGetValue(message.Descriptor.FullName, out Action<JsonParser, IMessage, JsonTokenizer> handler))
if (WellKnownTypeHandlers.TryGetValue(message.Descriptor.FullName, out handler))
{ {
handler(this, message, tokenizer); handler(this, message, tokenizer);
return; return;
@ -187,8 +185,7 @@ namespace Google.Protobuf
throw new InvalidOperationException("Unexpected token type " + token.Type); throw new InvalidOperationException("Unexpected token type " + token.Type);
} }
string name = token.StringValue; string name = token.StringValue;
FieldDescriptor field; if (jsonFieldMap.TryGetValue(name, out FieldDescriptor field))
if (jsonFieldMap.TryGetValue(name, out field))
{ {
if (field.ContainingOneof != null) if (field.ContainingOneof != null)
{ {
@ -303,11 +300,7 @@ namespace Google.Protobuf
} }
object key = ParseMapKey(keyField, token.StringValue); object key = ParseMapKey(keyField, token.StringValue);
object value = ParseSingleValue(valueField, tokenizer); object value = ParseSingleValue(valueField, tokenizer);
if (value == null) dictionary[key] = value ?? throw new InvalidProtocolBufferException("Map values must not be null");
{
throw new InvalidProtocolBufferException("Map values must not be null");
}
dictionary[key] = value;
} }
} }
@ -853,7 +846,7 @@ namespace Google.Protobuf
if (secondsToAdd < 0 && nanosToAdd > 0) if (secondsToAdd < 0 && nanosToAdd > 0)
{ {
secondsToAdd++; secondsToAdd++;
nanosToAdd = nanosToAdd - Duration.NanosecondsPerSecond; nanosToAdd -= Duration.NanosecondsPerSecond;
} }
if (secondsToAdd != 0 || nanosToAdd != 0) if (secondsToAdd != 0 || nanosToAdd != 0)
{ {
@ -1049,23 +1042,20 @@ namespace Google.Protobuf
/// when unknown fields are encountered. /// when unknown fields are encountered.
/// </summary> /// </summary>
/// <param name="ignoreUnknownFields"><c>true</c> if unknown fields should be ignored when parsing; <c>false</c> to throw an exception.</param> /// <param name="ignoreUnknownFields"><c>true</c> if unknown fields should be ignored when parsing; <c>false</c> to throw an exception.</param>
public Settings WithIgnoreUnknownFields(bool ignoreUnknownFields) => public Settings WithIgnoreUnknownFields(bool ignoreUnknownFields) => new(RecursionLimit, TypeRegistry, ignoreUnknownFields);
new Settings(RecursionLimit, TypeRegistry, ignoreUnknownFields);
/// <summary> /// <summary>
/// Creates a new <see cref="Settings"/> object based on this one, but with the specified recursion limit. /// Creates a new <see cref="Settings"/> object based on this one, but with the specified recursion limit.
/// </summary> /// </summary>
/// <param name="recursionLimit">The new recursion limit.</param> /// <param name="recursionLimit">The new recursion limit.</param>
public Settings WithRecursionLimit(int recursionLimit) => public Settings WithRecursionLimit(int recursionLimit) => new(recursionLimit, TypeRegistry, IgnoreUnknownFields);
new Settings(recursionLimit, TypeRegistry, IgnoreUnknownFields);
/// <summary> /// <summary>
/// Creates a new <see cref="Settings"/> object based on this one, but with the specified type registry. /// Creates a new <see cref="Settings"/> object based on this one, but with the specified type registry.
/// </summary> /// </summary>
/// <param name="typeRegistry">The new type registry. Must not be null.</param> /// <param name="typeRegistry">The new type registry. Must not be null.</param>
public Settings WithTypeRegistry(TypeRegistry typeRegistry) => public Settings WithTypeRegistry(TypeRegistry typeRegistry) =>
new Settings( new(RecursionLimit,
RecursionLimit,
ProtoPreconditions.CheckNotNull(typeRegistry, nameof(typeRegistry)), ProtoPreconditions.CheckNotNull(typeRegistry, nameof(typeRegistry)),
IgnoreUnknownFields); IgnoreUnknownFields);
} }

View File

@ -36,24 +36,14 @@ namespace Google.Protobuf
{ {
internal sealed class JsonToken : IEquatable<JsonToken> internal sealed class JsonToken : IEquatable<JsonToken>
{ {
// Tokens with no value can be reused. internal static JsonToken Null { get; } = new JsonToken(TokenType.Null);
private static readonly JsonToken _true = new JsonToken(TokenType.True); internal static JsonToken False { get; } = new JsonToken(TokenType.False);
private static readonly JsonToken _false = new JsonToken(TokenType.False); internal static JsonToken True { get; } = new JsonToken(TokenType.True);
private static readonly JsonToken _null = new JsonToken(TokenType.Null); internal static JsonToken StartObject { get; } = new JsonToken(TokenType.StartObject);
private static readonly JsonToken startObject = new JsonToken(TokenType.StartObject); internal static JsonToken EndObject { get; } = new JsonToken(TokenType.EndObject);
private static readonly JsonToken endObject = new JsonToken(TokenType.EndObject); internal static JsonToken StartArray { get; } = new JsonToken(TokenType.StartArray);
private static readonly JsonToken startArray = new JsonToken(TokenType.StartArray); internal static JsonToken EndArray { get; } = new JsonToken(TokenType.EndArray);
private static readonly JsonToken endArray = new JsonToken(TokenType.EndArray); internal static JsonToken EndDocument { get; } = new JsonToken(TokenType.EndDocument);
private static readonly JsonToken endDocument = new JsonToken(TokenType.EndDocument);
internal static JsonToken Null { get { return _null; } }
internal static JsonToken False { get { return _false; } }
internal static JsonToken True { get { return _true; } }
internal static JsonToken StartObject{ get { return startObject; } }
internal static JsonToken EndObject { get { return endObject; } }
internal static JsonToken StartArray { get { return startArray; } }
internal static JsonToken EndArray { get { return endArray; } }
internal static JsonToken EndDocument { get { return endDocument; } }
internal static JsonToken Name(string name) internal static JsonToken Name(string name)
{ {
@ -94,9 +84,9 @@ namespace Google.Protobuf
private readonly string stringValue; private readonly string stringValue;
private readonly double numberValue; private readonly double numberValue;
internal TokenType Type { get { return type; } } internal TokenType Type => type;
internal string StringValue { get { return stringValue; } } internal string StringValue => stringValue;
internal double NumberValue { get { return numberValue; } } internal double NumberValue => numberValue;
private JsonToken(TokenType type, string stringValue = null, double numberValue = 0) private JsonToken(TokenType type, string stringValue = null, double numberValue = 0)
{ {
@ -105,10 +95,7 @@ namespace Google.Protobuf
this.numberValue = numberValue; this.numberValue = numberValue;
} }
public override bool Equals(object obj) public override bool Equals(object obj) => Equals(obj as JsonToken);
{
return Equals(obj as JsonToken);
}
public override int GetHashCode() public override int GetHashCode()
{ {
@ -124,38 +111,26 @@ namespace Google.Protobuf
public override string ToString() public override string ToString()
{ {
switch (type) return type switch
{ {
case TokenType.Null: TokenType.Null => "null",
return "null"; TokenType.True => "true",
case TokenType.True: TokenType.False => "false",
return "true"; TokenType.Name => $"name ({stringValue})",
case TokenType.False: TokenType.StringValue => $"value ({stringValue})",
return "false"; TokenType.Number => $"number ({numberValue})",
case TokenType.Name: TokenType.StartObject => "start-object",
return "name (" + stringValue + ")"; TokenType.EndObject => "end-object",
case TokenType.StringValue: TokenType.StartArray => "start-array",
return "value (" + stringValue + ")"; TokenType.EndArray => "end-array",
case TokenType.Number: TokenType.EndDocument => "end-document",
return "number (" + numberValue + ")"; _ => throw new InvalidOperationException($"Token is of unknown type {type}"),
case TokenType.StartObject: };
return "start-object";
case TokenType.EndObject:
return "end-object";
case TokenType.StartArray:
return "start-array";
case TokenType.EndArray:
return "end-array";
case TokenType.EndDocument:
return "end-document";
default:
throw new InvalidOperationException("Token is of unknown type " + type);
}
} }
public bool Equals(JsonToken other) public bool Equals(JsonToken other)
{ {
if (ReferenceEquals(other, null)) if (other is null)
{ {
return false; return false;
} }

View File

@ -29,6 +29,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion #endregion
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
@ -362,29 +363,19 @@ namespace Google.Protobuf
private char ReadEscapedCharacter() private char ReadEscapedCharacter()
{ {
char c = reader.ReadOrFail("Unexpected end of text while reading character escape sequence"); char c = reader.ReadOrFail("Unexpected end of text while reading character escape sequence");
switch (c) return c switch
{ {
case 'n': 'n' => '\n',
return '\n'; '\\' => '\\',
case '\\': 'b' => '\b',
return '\\'; 'f' => '\f',
case 'b': 'r' => '\r',
return '\b'; 't' => '\t',
case 'f': '"' => '"',
return '\f'; '/' => '/',
case 'r': 'u' => ReadUnicodeEscape(),
return '\r'; _ => throw reader.CreateException(string.Format(CultureInfo.InvariantCulture, "Invalid character in character escape sequence: U+{0:x4}", (int)c)),
case 't': };
return '\t';
case '"':
return '"';
case '/':
return '/';
case 'u':
return ReadUnicodeEscape();
default:
throw reader.CreateException(string.Format(CultureInfo.InvariantCulture, "Invalid character in character escape sequence: U+{0:x4}", (int) c));
}
} }
/// <summary> /// <summary>
@ -498,8 +489,7 @@ namespace Google.Protobuf
throw reader.CreateException("Invalid numeric literal"); throw reader.CreateException("Invalid numeric literal");
} }
builder.Append(first); builder.Append(first);
int digitCount; char? next = ConsumeDigits(builder, out int digitCount);
char? next = ConsumeDigits(builder, out digitCount);
if (first == '0' && digitCount != 0) if (first == '0' && digitCount != 0)
{ {
throw reader.CreateException("Invalid numeric literal: leading 0 for non-zero value."); throw reader.CreateException("Invalid numeric literal: leading 0 for non-zero value.");
@ -510,8 +500,7 @@ namespace Google.Protobuf
private char? ReadFrac(StringBuilder builder) private char? ReadFrac(StringBuilder builder)
{ {
builder.Append('.'); // Already consumed this builder.Append('.'); // Already consumed this
int digitCount; char? next = ConsumeDigits(builder, out int digitCount);
char? next = ConsumeDigits(builder, out digitCount);
if (digitCount == 0) if (digitCount == 0)
{ {
throw reader.CreateException("Invalid numeric literal: fraction with no trailing digits"); throw reader.CreateException("Invalid numeric literal: fraction with no trailing digits");
@ -535,8 +524,7 @@ namespace Google.Protobuf
{ {
reader.PushBack(next.Value); reader.PushBack(next.Value);
} }
int digitCount; next = ConsumeDigits(builder, out int digitCount);
next = ConsumeDigits(builder, out digitCount);
if (digitCount == 0) if (digitCount == 0)
{ {
throw reader.CreateException("Invalid numeric literal: exponent without value"); throw reader.CreateException("Invalid numeric literal: exponent without value");
@ -591,20 +579,13 @@ namespace Google.Protobuf
{ {
containerStack.Pop(); containerStack.Pop();
var parent = containerStack.Peek(); var parent = containerStack.Peek();
switch (parent) state = parent switch
{ {
case ContainerType.Object: ContainerType.Object => State.ObjectAfterProperty,
state = State.ObjectAfterProperty; ContainerType.Array => State.ArrayAfterValue,
break; ContainerType.Document => State.ExpectedEndOfDocument,
case ContainerType.Array: _ => throw new InvalidOperationException("Unexpected container type: " + parent),
state = State.ArrayAfterValue; };
break;
case ContainerType.Document:
state = State.ExpectedEndOfDocument;
break;
default:
throw new InvalidOperationException("Unexpected container type: " + parent);
}
} }
private enum ContainerType private enum ContainerType

View File

@ -51,34 +51,20 @@ namespace Google.Protobuf
bytesLeft = size; bytesLeft = size;
} }
public override bool CanRead public override bool CanRead => true;
{ public override bool CanSeek => false;
get { return true; } public override bool CanWrite => false;
}
public override bool CanSeek
{
get { return false; }
}
public override bool CanWrite
{
get { return false; }
}
public override void Flush() public override void Flush()
{ {
} }
public override long Length public override long Length => throw new NotSupportedException();
{
get { throw new NotSupportedException(); }
}
public override long Position public override long Position
{ {
get { throw new NotSupportedException(); } get => throw new NotSupportedException();
set { throw new NotSupportedException(); } set => throw new NotSupportedException();
} }
public override int Read(byte[] buffer, int offset, int count) public override int Read(byte[] buffer, int offset, int count)
@ -92,19 +78,10 @@ namespace Google.Protobuf
return 0; return 0;
} }
public override long Seek(long offset, SeekOrigin origin) public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();
{
throw new NotSupportedException();
}
public override void SetLength(long value) public override void SetLength(long value) => throw new NotSupportedException();
{
throw new NotSupportedException();
}
public override void Write(byte[] buffer, int offset, int count) public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException();
{
throw new NotSupportedException();
}
} }
} }

View File

@ -107,7 +107,7 @@ namespace Google.Protobuf
/// <returns>The message data as a byte array.</returns> /// <returns>The message data as a byte array.</returns>
public static byte[] ToByteArray(this IMessage message) public static byte[] ToByteArray(this IMessage message)
{ {
ProtoPreconditions.CheckNotNull(message, "message"); ProtoPreconditions.CheckNotNull(message, nameof(message));
byte[] result = new byte[message.CalculateSize()]; byte[] result = new byte[message.CalculateSize()];
CodedOutputStream output = new CodedOutputStream(result); CodedOutputStream output = new CodedOutputStream(result);
message.WriteTo(output); message.WriteTo(output);
@ -122,8 +122,8 @@ namespace Google.Protobuf
/// <param name="output">The stream to write to.</param> /// <param name="output">The stream to write to.</param>
public static void WriteTo(this IMessage message, Stream output) public static void WriteTo(this IMessage message, Stream output)
{ {
ProtoPreconditions.CheckNotNull(message, "message"); ProtoPreconditions.CheckNotNull(message, nameof(message));
ProtoPreconditions.CheckNotNull(output, "output"); ProtoPreconditions.CheckNotNull(output, nameof(output));
CodedOutputStream codedOutput = new CodedOutputStream(output); CodedOutputStream codedOutput = new CodedOutputStream(output);
message.WriteTo(codedOutput); message.WriteTo(codedOutput);
codedOutput.Flush(); codedOutput.Flush();
@ -136,8 +136,8 @@ namespace Google.Protobuf
/// <param name="output">The output stream to write to.</param> /// <param name="output">The output stream to write to.</param>
public static void WriteDelimitedTo(this IMessage message, Stream output) public static void WriteDelimitedTo(this IMessage message, Stream output)
{ {
ProtoPreconditions.CheckNotNull(message, "message"); ProtoPreconditions.CheckNotNull(message, nameof(message));
ProtoPreconditions.CheckNotNull(output, "output"); ProtoPreconditions.CheckNotNull(output, nameof(output));
CodedOutputStream codedOutput = new CodedOutputStream(output); CodedOutputStream codedOutput = new CodedOutputStream(output);
codedOutput.WriteLength(message.CalculateSize()); codedOutput.WriteLength(message.CalculateSize());
message.WriteTo(codedOutput); message.WriteTo(codedOutput);
@ -151,7 +151,7 @@ namespace Google.Protobuf
/// <returns>The message data as a byte string.</returns> /// <returns>The message data as a byte string.</returns>
public static ByteString ToByteString(this IMessage message) public static ByteString ToByteString(this IMessage message)
{ {
ProtoPreconditions.CheckNotNull(message, "message"); ProtoPreconditions.CheckNotNull(message, nameof(message));
return ByteString.AttachBytes(message.ToByteArray()); return ByteString.AttachBytes(message.ToByteArray());
} }
@ -251,30 +251,34 @@ namespace Google.Protobuf
// Implementations allowing unknown fields to be discarded. // Implementations allowing unknown fields to be discarded.
internal static void MergeFrom(this IMessage message, byte[] data, bool discardUnknownFields, ExtensionRegistry registry) internal static void MergeFrom(this IMessage message, byte[] data, bool discardUnknownFields, ExtensionRegistry registry)
{ {
ProtoPreconditions.CheckNotNull(message, "message"); ProtoPreconditions.CheckNotNull(message, nameof(message));
ProtoPreconditions.CheckNotNull(data, "data"); ProtoPreconditions.CheckNotNull(data, nameof(data));
CodedInputStream input = new CodedInputStream(data); CodedInputStream input = new CodedInputStream(data)
input.DiscardUnknownFields = discardUnknownFields; {
input.ExtensionRegistry = registry; DiscardUnknownFields = discardUnknownFields,
ExtensionRegistry = registry
};
message.MergeFrom(input); message.MergeFrom(input);
input.CheckReadEndOfStreamTag(); input.CheckReadEndOfStreamTag();
} }
internal static void MergeFrom(this IMessage message, byte[] data, int offset, int length, bool discardUnknownFields, ExtensionRegistry registry) internal static void MergeFrom(this IMessage message, byte[] data, int offset, int length, bool discardUnknownFields, ExtensionRegistry registry)
{ {
ProtoPreconditions.CheckNotNull(message, "message"); ProtoPreconditions.CheckNotNull(message, nameof(message));
ProtoPreconditions.CheckNotNull(data, "data"); ProtoPreconditions.CheckNotNull(data, nameof(data));
CodedInputStream input = new CodedInputStream(data, offset, length); CodedInputStream input = new CodedInputStream(data, offset, length)
input.DiscardUnknownFields = discardUnknownFields; {
input.ExtensionRegistry = registry; DiscardUnknownFields = discardUnknownFields,
ExtensionRegistry = registry
};
message.MergeFrom(input); message.MergeFrom(input);
input.CheckReadEndOfStreamTag(); input.CheckReadEndOfStreamTag();
} }
internal static void MergeFrom(this IMessage message, ByteString data, bool discardUnknownFields, ExtensionRegistry registry) internal static void MergeFrom(this IMessage message, ByteString data, bool discardUnknownFields, ExtensionRegistry registry)
{ {
ProtoPreconditions.CheckNotNull(message, "message"); ProtoPreconditions.CheckNotNull(message, nameof(message));
ProtoPreconditions.CheckNotNull(data, "data"); ProtoPreconditions.CheckNotNull(data, nameof(data));
CodedInputStream input = data.CreateCodedInput(); CodedInputStream input = data.CreateCodedInput();
input.DiscardUnknownFields = discardUnknownFields; input.DiscardUnknownFields = discardUnknownFields;
input.ExtensionRegistry = registry; input.ExtensionRegistry = registry;
@ -284,11 +288,13 @@ namespace Google.Protobuf
internal static void MergeFrom(this IMessage message, Stream input, bool discardUnknownFields, ExtensionRegistry registry) internal static void MergeFrom(this IMessage message, Stream input, bool discardUnknownFields, ExtensionRegistry registry)
{ {
ProtoPreconditions.CheckNotNull(message, "message"); ProtoPreconditions.CheckNotNull(message, nameof(message));
ProtoPreconditions.CheckNotNull(input, "input"); ProtoPreconditions.CheckNotNull(input, nameof(input));
CodedInputStream codedInput = new CodedInputStream(input); CodedInputStream codedInput = new CodedInputStream(input)
codedInput.DiscardUnknownFields = discardUnknownFields; {
codedInput.ExtensionRegistry = registry; DiscardUnknownFields = discardUnknownFields,
ExtensionRegistry = registry
};
message.MergeFrom(codedInput); message.MergeFrom(codedInput);
codedInput.CheckReadEndOfStreamTag(); codedInput.CheckReadEndOfStreamTag();
} }
@ -315,8 +321,8 @@ namespace Google.Protobuf
internal static void MergeDelimitedFrom(this IMessage message, Stream input, bool discardUnknownFields, ExtensionRegistry registry) internal static void MergeDelimitedFrom(this IMessage message, Stream input, bool discardUnknownFields, ExtensionRegistry registry)
{ {
ProtoPreconditions.CheckNotNull(message, "message"); ProtoPreconditions.CheckNotNull(message, nameof(message));
ProtoPreconditions.CheckNotNull(input, "input"); ProtoPreconditions.CheckNotNull(input, nameof(input));
int size = (int) CodedInputStream.ReadRawVarint32(input); int size = (int) CodedInputStream.ReadRawVarint32(input);
Stream limitedStream = new LimitedInputStream(input, size); Stream limitedStream = new LimitedInputStream(input, size);
MergeFrom(message, limitedStream, discardUnknownFields, registry); MergeFrom(message, limitedStream, discardUnknownFields, registry);

View File

@ -43,9 +43,8 @@ namespace Google.Protobuf
/// </summary> /// </summary>
public class MessageParser public class MessageParser
{ {
private Func<IMessage> factory; private readonly Func<IMessage> factory;
// TODO: When we use a C# 7.1 compiler, make this private protected. private protected bool DiscardUnknownFields { get; }
internal bool DiscardUnknownFields { get; }
internal ExtensionRegistry Extensions { get; } internal ExtensionRegistry Extensions { get; }

View File

@ -23,14 +23,7 @@ namespace Google.Protobuf
&& number == other.number; && number == other.number;
} }
public override bool Equals(object obj) public override bool Equals(object obj) => obj is ObjectIntPair<T> pair && Equals(pair);
{
if (obj is ObjectIntPair<T>)
{
return Equals((ObjectIntPair<T>)obj);
}
return false;
}
public override int GetHashCode() public override int GetHashCode()
{ {

View File

@ -32,14 +32,8 @@
using System; using System;
using System.Buffers; using System.Buffers;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security; using System.Security;
using System.Text;
using Google.Protobuf.Collections;
namespace Google.Protobuf namespace Google.Protobuf
{ {
@ -53,7 +47,7 @@ namespace Google.Protobuf
public ref struct ParseContext public ref struct ParseContext
{ {
internal const int DefaultRecursionLimit = 100; internal const int DefaultRecursionLimit = 100;
internal const int DefaultSizeLimit = Int32.MaxValue; internal const int DefaultSizeLimit = int.MaxValue;
internal ReadOnlySpan<byte> buffer; internal ReadOnlySpan<byte> buffer;
internal ParserInternalState state; internal ParserInternalState state;
@ -127,14 +121,15 @@ namespace Google.Protobuf
/// Returns the last tag read, or 0 if no tags have been read or we've read beyond /// Returns the last tag read, or 0 if no tags have been read or we've read beyond
/// the end of the input. /// the end of the input.
/// </summary> /// </summary>
internal uint LastTag { get { return state.lastTag; } } internal uint LastTag => state.lastTag;
/// <summary> /// <summary>
/// Internal-only property; when set to true, unknown fields will be discarded while parsing. /// Internal-only property; when set to true, unknown fields will be discarded while parsing.
/// </summary> /// </summary>
internal bool DiscardUnknownFields { internal bool DiscardUnknownFields
get { return state.DiscardUnknownFields; } {
set { state.DiscardUnknownFields = value; } get => state.DiscardUnknownFields;
set => state.DiscardUnknownFields = value;
} }
/// <summary> /// <summary>
@ -142,8 +137,8 @@ namespace Google.Protobuf
/// </summary> /// </summary>
internal ExtensionRegistry ExtensionRegistry internal ExtensionRegistry ExtensionRegistry
{ {
get { return state.ExtensionRegistry; } get => state.ExtensionRegistry;
set { state.ExtensionRegistry = value; } set => state.ExtensionRegistry = value;
} }
/// <summary> /// <summary>
@ -156,125 +151,85 @@ namespace Google.Protobuf
/// </remarks> /// </remarks>
/// <returns>The next field tag, or 0 for end of input. (0 is never a valid tag.)</returns> /// <returns>The next field tag, or 0 for end of input. (0 is never a valid tag.)</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public uint ReadTag() public uint ReadTag() => ParsingPrimitives.ParseTag(ref buffer, ref state);
{
return ParsingPrimitives.ParseTag(ref buffer, ref state);
}
/// <summary> /// <summary>
/// Reads a double field from the input. /// Reads a double field from the input.
/// </summary> /// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public double ReadDouble() public double ReadDouble() => ParsingPrimitives.ParseDouble(ref buffer, ref state);
{
return ParsingPrimitives.ParseDouble(ref buffer, ref state);
}
/// <summary> /// <summary>
/// Reads a float field from the input. /// Reads a float field from the input.
/// </summary> /// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public float ReadFloat() public float ReadFloat() => ParsingPrimitives.ParseFloat(ref buffer, ref state);
{
return ParsingPrimitives.ParseFloat(ref buffer, ref state);
}
/// <summary> /// <summary>
/// Reads a uint64 field from the input. /// Reads a uint64 field from the input.
/// </summary> /// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public ulong ReadUInt64() public ulong ReadUInt64() => ParsingPrimitives.ParseRawVarint64(ref buffer, ref state);
{
return ParsingPrimitives.ParseRawVarint64(ref buffer, ref state);
}
/// <summary> /// <summary>
/// Reads an int64 field from the input. /// Reads an int64 field from the input.
/// </summary> /// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public long ReadInt64() public long ReadInt64() => (long)ParsingPrimitives.ParseRawVarint64(ref buffer, ref state);
{
return (long)ParsingPrimitives.ParseRawVarint64(ref buffer, ref state);
}
/// <summary> /// <summary>
/// Reads an int32 field from the input. /// Reads an int32 field from the input.
/// </summary> /// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public int ReadInt32() public int ReadInt32() => (int)ParsingPrimitives.ParseRawVarint32(ref buffer, ref state);
{
return (int)ParsingPrimitives.ParseRawVarint32(ref buffer, ref state);
}
/// <summary> /// <summary>
/// Reads a fixed64 field from the input. /// Reads a fixed64 field from the input.
/// </summary> /// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public ulong ReadFixed64() public ulong ReadFixed64() => ParsingPrimitives.ParseRawLittleEndian64(ref buffer, ref state);
{
return ParsingPrimitives.ParseRawLittleEndian64(ref buffer, ref state);
}
/// <summary> /// <summary>
/// Reads a fixed32 field from the input. /// Reads a fixed32 field from the input.
/// </summary> /// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public uint ReadFixed32() public uint ReadFixed32() => ParsingPrimitives.ParseRawLittleEndian32(ref buffer, ref state);
{
return ParsingPrimitives.ParseRawLittleEndian32(ref buffer, ref state);
}
/// <summary> /// <summary>
/// Reads a bool field from the input. /// Reads a bool field from the input.
/// </summary> /// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool ReadBool() public bool ReadBool() => ParsingPrimitives.ParseRawVarint64(ref buffer, ref state) != 0;
{
return ParsingPrimitives.ParseRawVarint64(ref buffer, ref state) != 0;
}
/// <summary> /// <summary>
/// Reads a string field from the input. /// Reads a string field from the input.
/// </summary> /// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public string ReadString() public string ReadString() => ParsingPrimitives.ReadString(ref buffer, ref state);
{
return ParsingPrimitives.ReadString(ref buffer, ref state);
}
/// <summary> /// <summary>
/// Reads an embedded message field value from the input. /// Reads an embedded message field value from the input.
/// </summary> /// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadMessage(IMessage message) public void ReadMessage(IMessage message) => ParsingPrimitivesMessages.ReadMessage(ref this, message);
{
ParsingPrimitivesMessages.ReadMessage(ref this, message);
}
/// <summary> /// <summary>
/// Reads an embedded group field from the input. /// Reads an embedded group field from the input.
/// </summary> /// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadGroup(IMessage message) public void ReadGroup(IMessage message) => ParsingPrimitivesMessages.ReadGroup(ref this, message);
{
ParsingPrimitivesMessages.ReadGroup(ref this, message);
}
/// <summary> /// <summary>
/// Reads a bytes field value from the input. /// Reads a bytes field value from the input.
/// </summary> /// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public ByteString ReadBytes() public ByteString ReadBytes() => ParsingPrimitives.ReadBytes(ref buffer, ref state);
{
return ParsingPrimitives.ReadBytes(ref buffer, ref state);
}
/// <summary> /// <summary>
/// Reads a uint32 field value from the input. /// Reads a uint32 field value from the input.
/// </summary> /// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public uint ReadUInt32() public uint ReadUInt32() => ParsingPrimitives.ParseRawVarint32(ref buffer, ref state);
{
return ParsingPrimitives.ParseRawVarint32(ref buffer, ref state);
}
/// <summary> /// <summary>
/// Reads an enum field value from the input. /// Reads an enum field value from the input.
@ -290,37 +245,25 @@ namespace Google.Protobuf
/// Reads an sfixed32 field value from the input. /// Reads an sfixed32 field value from the input.
/// </summary> /// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public int ReadSFixed32() public int ReadSFixed32() => (int)ParsingPrimitives.ParseRawLittleEndian32(ref buffer, ref state);
{
return (int)ParsingPrimitives.ParseRawLittleEndian32(ref buffer, ref state);
}
/// <summary> /// <summary>
/// Reads an sfixed64 field value from the input. /// Reads an sfixed64 field value from the input.
/// </summary> /// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public long ReadSFixed64() public long ReadSFixed64() => (long)ParsingPrimitives.ParseRawLittleEndian64(ref buffer, ref state);
{
return (long)ParsingPrimitives.ParseRawLittleEndian64(ref buffer, ref state);
}
/// <summary> /// <summary>
/// Reads an sint32 field value from the input. /// Reads an sint32 field value from the input.
/// </summary> /// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public int ReadSInt32() public int ReadSInt32() => ParsingPrimitives.DecodeZigZag32(ParsingPrimitives.ParseRawVarint32(ref buffer, ref state));
{
return ParsingPrimitives.DecodeZigZag32(ParsingPrimitives.ParseRawVarint32(ref buffer, ref state));
}
/// <summary> /// <summary>
/// Reads an sint64 field value from the input. /// Reads an sint64 field value from the input.
/// </summary> /// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public long ReadSInt64() public long ReadSInt64() => ParsingPrimitives.DecodeZigZag64(ParsingPrimitives.ParseRawVarint64(ref buffer, ref state));
{
return ParsingPrimitives.DecodeZigZag64(ParsingPrimitives.ParseRawVarint64(ref buffer, ref state));
}
/// <summary> /// <summary>
/// Reads a length for length-delimited data. /// Reads a length for length-delimited data.
@ -330,10 +273,7 @@ namespace Google.Protobuf
/// to make the calling code clearer. /// to make the calling code clearer.
/// </remarks> /// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public int ReadLength() public int ReadLength() => (int)ParsingPrimitives.ParseRawVarint32(ref buffer, ref state);
{
return (int)ParsingPrimitives.ParseRawVarint32(ref buffer, ref state);
}
internal void CopyStateTo(CodedInputStream input) internal void CopyStateTo(CodedInputStream input)
{ {

View File

@ -30,20 +30,8 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion #endregion
using System;
using System.Buffers;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using Google.Protobuf.Collections;
namespace Google.Protobuf namespace Google.Protobuf
{ {
// warning: this is a mutable struct, so it needs to be only passed as a ref! // warning: this is a mutable struct, so it needs to be only passed as a ref!
internal struct ParserInternalState internal struct ParserInternalState
{ {

View File

@ -34,13 +34,10 @@ using System;
using System.Buffers; using System.Buffers;
using System.Buffers.Binary; using System.Buffers.Binary;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Security; using System.Security;
using System.Text;
using Google.Protobuf.Collections;
namespace Google.Protobuf namespace Google.Protobuf
{ {

View File

@ -33,8 +33,6 @@
using System; using System;
using System.Buffers; using System.Buffers;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
using System.Security; using System.Security;
using Google.Protobuf.Collections; using Google.Protobuf.Collections;

View File

@ -31,15 +31,7 @@
#endregion #endregion
using System; using System;
using System.Buffers;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security; using System.Security;
using System.Text;
using Google.Protobuf.Collections;
namespace Google.Protobuf namespace Google.Protobuf
{ {

View File

@ -31,7 +31,6 @@
#endregion #endregion
using Google.Protobuf.Collections; using Google.Protobuf.Collections;
using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
@ -226,24 +225,21 @@ namespace Google.Protobuf.Reflection
{ {
if (values == null) if (values == null)
{ {
value = default(T); value = default;
return false; return false;
} }
IExtensionValue extensionValue; if (values.TryGetValue(field, out IExtensionValue extensionValue))
if (values.TryGetValue(field, out extensionValue))
{ {
if (extensionValue is ExtensionValue<T>) if (extensionValue is ExtensionValue<T> single)
{ {
ExtensionValue<T> single = extensionValue as ExtensionValue<T>;
ByteString bytes = single.GetValue().ToByteString(); ByteString bytes = single.GetValue().ToByteString();
value = new T(); value = new T();
value.MergeFrom(bytes); value.MergeFrom(bytes);
return true; return true;
} }
else if (extensionValue is RepeatedExtensionValue<T>) else if (extensionValue is RepeatedExtensionValue<T> repeated)
{ {
RepeatedExtensionValue<T> repeated = extensionValue as RepeatedExtensionValue<T>;
value = repeated.GetValue() value = repeated.GetValue()
.Select(v => v.ToByteString()) .Select(v => v.ToByteString())
.Aggregate(new T(), (t, b) => .Aggregate(new T(), (t, b) =>
@ -264,22 +260,19 @@ namespace Google.Protobuf.Reflection
{ {
if (values == null) if (values == null)
{ {
value = default(T); value = default;
return false; return false;
} }
IExtensionValue extensionValue; if (values.TryGetValue(field, out IExtensionValue extensionValue))
if (values.TryGetValue(field, out extensionValue))
{ {
if (extensionValue is ExtensionValue<T>) if (extensionValue is ExtensionValue<T> single)
{ {
ExtensionValue<T> single = extensionValue as ExtensionValue<T>;
value = single.GetValue(); value = single.GetValue();
return true; return true;
} }
else if (extensionValue is RepeatedExtensionValue<T>) else if (extensionValue is RepeatedExtensionValue<T> repeated)
{ {
RepeatedExtensionValue<T> repeated = extensionValue as RepeatedExtensionValue<T>;
if (repeated.GetValue().Count != 0) if (repeated.GetValue().Count != 0)
{ {
RepeatedField<T> repeatedField = repeated.GetValue(); RepeatedField<T> repeatedField = repeated.GetValue();
@ -317,7 +310,7 @@ namespace Google.Protobuf.Reflection
} }
} }
value = default(T); value = default;
return false; return false;
} }
} }

View File

@ -30,11 +30,9 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion #endregion
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Text;
using static Google.Protobuf.Reflection.SourceCodeInfo.Types; using static Google.Protobuf.Reflection.SourceCodeInfo.Types;
namespace Google.Protobuf.Reflection namespace Google.Protobuf.Reflection

View File

@ -51,12 +51,11 @@ namespace Google.Protobuf.Reflection
private readonly IDictionary<ObjectIntPair<IDescriptor>, EnumValueDescriptor> enumValuesByNumber = private readonly IDictionary<ObjectIntPair<IDescriptor>, EnumValueDescriptor> enumValuesByNumber =
new Dictionary<ObjectIntPair<IDescriptor>, EnumValueDescriptor>(); new Dictionary<ObjectIntPair<IDescriptor>, EnumValueDescriptor>();
private readonly HashSet<FileDescriptor> dependencies; private readonly HashSet<FileDescriptor> dependencies = new HashSet<FileDescriptor>();
internal DescriptorPool(IEnumerable<FileDescriptor> dependencyFiles) internal DescriptorPool(IEnumerable<FileDescriptor> dependencyFiles)
{ {
dependencies = new HashSet<FileDescriptor>(); foreach (FileDescriptor dependencyFile in dependencyFiles)
foreach (var dependencyFile in dependencyFiles)
{ {
dependencies.Add(dependencyFile); dependencies.Add(dependencyFile);
ImportPublicDependencies(dependencyFile); ImportPublicDependencies(dependencyFile);
@ -88,10 +87,8 @@ namespace Google.Protobuf.Reflection
/// or null if the symbol doesn't exist or has the wrong type</returns> /// or null if the symbol doesn't exist or has the wrong type</returns>
internal T FindSymbol<T>(string fullName) where T : class internal T FindSymbol<T>(string fullName) where T : class
{ {
IDescriptor result; descriptorsByName.TryGetValue(fullName, out IDescriptor result);
descriptorsByName.TryGetValue(fullName, out result); if (result is T descriptor)
T descriptor = result as T;
if (descriptor != null)
{ {
return descriptor; return descriptor;
} }
@ -131,10 +128,9 @@ namespace Google.Protobuf.Reflection
name = fullName; name = fullName;
} }
IDescriptor old; if (descriptorsByName.TryGetValue(fullName, out IDescriptor old))
if (descriptorsByName.TryGetValue(fullName, out old))
{ {
if (!(old is PackageDescriptor)) if (old is not PackageDescriptor)
{ {
throw new DescriptorValidationException(file, throw new DescriptorValidationException(file,
"\"" + name + "\"" + name +
@ -153,10 +149,9 @@ namespace Google.Protobuf.Reflection
internal void AddSymbol(IDescriptor descriptor) internal void AddSymbol(IDescriptor descriptor)
{ {
ValidateSymbolName(descriptor); ValidateSymbolName(descriptor);
String fullName = descriptor.FullName; string fullName = descriptor.FullName;
IDescriptor old; if (descriptorsByName.TryGetValue(fullName, out IDescriptor old))
if (descriptorsByName.TryGetValue(fullName, out old))
{ {
int dotPos = fullName.LastIndexOf('.'); int dotPos = fullName.LastIndexOf('.');
string message; string message;
@ -181,8 +176,7 @@ namespace Google.Protobuf.Reflection
descriptorsByName[fullName] = descriptor; descriptorsByName[fullName] = descriptor;
} }
private static readonly Regex ValidationRegex = new Regex("^[_A-Za-z][_A-Za-z0-9]*$", private static readonly Regex ValidationRegex = new Regex("^[_A-Za-z][_A-Za-z0-9]*$", FrameworkPortability.CompiledRegexWhereAvailable);
FrameworkPortability.CompiledRegexWhereAvailable);
/// <summary> /// <summary>
/// Verifies that the descriptor's name is valid (i.e. it contains /// Verifies that the descriptor's name is valid (i.e. it contains
@ -191,7 +185,7 @@ namespace Google.Protobuf.Reflection
/// <param name="descriptor"></param> /// <param name="descriptor"></param>
private static void ValidateSymbolName(IDescriptor descriptor) private static void ValidateSymbolName(IDescriptor descriptor)
{ {
if (descriptor.Name == "") if (descriptor.Name.Length == 0)
{ {
throw new DescriptorValidationException(descriptor, "Missing name."); throw new DescriptorValidationException(descriptor, "Missing name.");
} }
@ -208,15 +202,13 @@ namespace Google.Protobuf.Reflection
/// </summary> /// </summary>
internal FieldDescriptor FindFieldByNumber(MessageDescriptor messageDescriptor, int number) internal FieldDescriptor FindFieldByNumber(MessageDescriptor messageDescriptor, int number)
{ {
FieldDescriptor ret; fieldsByNumber.TryGetValue(new ObjectIntPair<IDescriptor>(messageDescriptor, number), out FieldDescriptor ret);
fieldsByNumber.TryGetValue(new ObjectIntPair<IDescriptor>(messageDescriptor, number), out ret);
return ret; return ret;
} }
internal EnumValueDescriptor FindEnumValueByNumber(EnumDescriptor enumDescriptor, int number) internal EnumValueDescriptor FindEnumValueByNumber(EnumDescriptor enumDescriptor, int number)
{ {
EnumValueDescriptor ret; enumValuesByNumber.TryGetValue(new ObjectIntPair<IDescriptor>(enumDescriptor, number), out EnumValueDescriptor ret);
enumValuesByNumber.TryGetValue(new ObjectIntPair<IDescriptor>(enumDescriptor, number), out ret);
return ret; return ret;
} }
@ -229,8 +221,7 @@ namespace Google.Protobuf.Reflection
{ {
// for extensions, we use the extended type, otherwise we use the containing type // for extensions, we use the extended type, otherwise we use the containing type
ObjectIntPair<IDescriptor> key = new ObjectIntPair<IDescriptor>(field.Proto.HasExtendee ? field.ExtendeeType : field.ContainingType, field.FieldNumber); ObjectIntPair<IDescriptor> key = new ObjectIntPair<IDescriptor>(field.Proto.HasExtendee ? field.ExtendeeType : field.ContainingType, field.FieldNumber);
FieldDescriptor old; if (fieldsByNumber.TryGetValue(key, out FieldDescriptor old))
if (fieldsByNumber.TryGetValue(key, out old))
{ {
throw new DescriptorValidationException(field, "Field number " + field.FieldNumber + throw new DescriptorValidationException(field, "Field number " + field.FieldNumber +
"has already been used in \"" + "has already been used in \"" +

View File

@ -40,25 +40,16 @@ namespace Google.Protobuf.Reflection
/// </summary> /// </summary>
public sealed class DescriptorValidationException : Exception public sealed class DescriptorValidationException : Exception
{ {
private readonly String name;
private readonly string description;
/// <value> /// <value>
/// The full name of the descriptor where the error occurred. /// The full name of the descriptor where the error occurred.
/// </value> /// </value>
public String ProblemSymbolName public string ProblemSymbolName { get; }
{
get { return name; }
}
/// <value> /// <value>
/// A human-readable description of the error. (The Message property /// A human-readable description of the error. (The Message property
/// is made up of the descriptor's name and this description.) /// is made up of the descriptor's name and this description.)
/// </value> /// </value>
public string Description public string Description { get; }
{
get { return description; }
}
internal DescriptorValidationException(IDescriptor problemDescriptor, string description) : internal DescriptorValidationException(IDescriptor problemDescriptor, string description) :
base(problemDescriptor.FullName + ": " + description) base(problemDescriptor.FullName + ": " + description)
@ -66,15 +57,15 @@ namespace Google.Protobuf.Reflection
// Note that problemDescriptor may be partially uninitialized, so we // Note that problemDescriptor may be partially uninitialized, so we
// don't want to expose it directly to the user. So, we only provide // don't want to expose it directly to the user. So, we only provide
// the name and the original proto. // the name and the original proto.
name = problemDescriptor.FullName; ProblemSymbolName = problemDescriptor.FullName;
this.description = description; Description = description;
} }
internal DescriptorValidationException(IDescriptor problemDescriptor, string description, Exception cause) : internal DescriptorValidationException(IDescriptor problemDescriptor, string description, Exception cause) :
base(problemDescriptor.FullName + ": " + description, cause) base(problemDescriptor.FullName + ": " + description, cause)
{ {
name = problemDescriptor.FullName; ProblemSymbolName = problemDescriptor.FullName;
this.description = description; Description = description;
} }
} }
} }

View File

@ -41,17 +41,12 @@ namespace Google.Protobuf.Reflection
/// </summary> /// </summary>
public sealed class EnumDescriptor : DescriptorBase public sealed class EnumDescriptor : DescriptorBase
{ {
private readonly EnumDescriptorProto proto;
private readonly MessageDescriptor containingType;
private readonly IList<EnumValueDescriptor> values;
private readonly Type clrType;
internal EnumDescriptor(EnumDescriptorProto proto, FileDescriptor file, MessageDescriptor parent, int index, Type clrType) internal EnumDescriptor(EnumDescriptorProto proto, FileDescriptor file, MessageDescriptor parent, int index, Type clrType)
: base(file, file.ComputeFullName(parent, proto.Name), index) : base(file, file.ComputeFullName(parent, proto.Name), index)
{ {
this.proto = proto; Proto = proto;
this.clrType = clrType; ClrType = clrType;
containingType = parent; ContainingType = parent;
if (proto.Value.Count == 0) if (proto.Value.Count == 0)
{ {
@ -60,13 +55,13 @@ namespace Google.Protobuf.Reflection
throw new DescriptorValidationException(this, "Enums must contain at least one value."); throw new DescriptorValidationException(this, "Enums must contain at least one value.");
} }
values = DescriptorUtil.ConvertAndMakeReadOnly(proto.Value, Values = DescriptorUtil.ConvertAndMakeReadOnly(proto.Value,
(value, i) => new EnumValueDescriptor(value, file, this, i)); (value, i) => new EnumValueDescriptor(value, file, this, i));
File.DescriptorPool.AddSymbol(this); File.DescriptorPool.AddSymbol(this);
} }
internal EnumDescriptorProto Proto { get { return proto; } } internal EnumDescriptorProto Proto { get; }
/// <summary> /// <summary>
/// Returns a clone of the underlying <see cref="EnumDescriptorProto"/> describing this enum. /// Returns a clone of the underlying <see cref="EnumDescriptorProto"/> describing this enum.
@ -79,39 +74,29 @@ namespace Google.Protobuf.Reflection
/// <summary> /// <summary>
/// The brief name of the descriptor's target. /// The brief name of the descriptor's target.
/// </summary> /// </summary>
public override string Name { get { return proto.Name; } } public override string Name => Proto.Name;
internal override IReadOnlyList<DescriptorBase> GetNestedDescriptorListForField(int fieldNumber) internal override IReadOnlyList<DescriptorBase> GetNestedDescriptorListForField(int fieldNumber) =>
{ fieldNumber switch
switch (fieldNumber)
{ {
case EnumDescriptorProto.ValueFieldNumber: EnumDescriptorProto.ValueFieldNumber => (IReadOnlyList<DescriptorBase>)Values,
return (IReadOnlyList<DescriptorBase>) Values; _ => null,
default: };
return null;
}
}
/// <summary> /// <summary>
/// The CLR type for this enum. For generated code, this will be a CLR enum type. /// The CLR type for this enum. For generated code, this will be a CLR enum type.
/// </summary> /// </summary>
public Type ClrType { get { return clrType; } } public Type ClrType { get; }
/// <value> /// <value>
/// If this is a nested type, get the outer descriptor, otherwise null. /// If this is a nested type, get the outer descriptor, otherwise null.
/// </value> /// </value>
public MessageDescriptor ContainingType public MessageDescriptor ContainingType { get; }
{
get { return containingType; }
}
/// <value> /// <value>
/// An unmodifiable list of defined value descriptors for this enum. /// An unmodifiable list of defined value descriptors for this enum.
/// </value> /// </value>
public IList<EnumValueDescriptor> Values public IList<EnumValueDescriptor> Values { get; }
{
get { return values; }
}
/// <summary> /// <summary>
/// Finds an enum value by number. If multiple enum values have the /// Finds an enum value by number. If multiple enum values have the

View File

@ -40,20 +40,17 @@ namespace Google.Protobuf.Reflection
/// </summary> /// </summary>
public sealed class EnumValueDescriptor : DescriptorBase public sealed class EnumValueDescriptor : DescriptorBase
{ {
private readonly EnumDescriptor enumDescriptor;
private readonly EnumValueDescriptorProto proto;
internal EnumValueDescriptor(EnumValueDescriptorProto proto, FileDescriptor file, internal EnumValueDescriptor(EnumValueDescriptorProto proto, FileDescriptor file,
EnumDescriptor parent, int index) EnumDescriptor parent, int index)
: base(file, parent.FullName + "." + proto.Name, index) : base(file, parent.FullName + "." + proto.Name, index)
{ {
this.proto = proto; Proto = proto;
enumDescriptor = parent; EnumDescriptor = parent;
file.DescriptorPool.AddSymbol(this); file.DescriptorPool.AddSymbol(this);
file.DescriptorPool.AddEnumValueByNumber(this); file.DescriptorPool.AddEnumValueByNumber(this);
} }
internal EnumValueDescriptorProto Proto { get { return proto; } } internal EnumValueDescriptorProto Proto { get; }
/// <summary> /// <summary>
/// Returns a clone of the underlying <see cref="EnumValueDescriptorProto"/> describing this enum value. /// Returns a clone of the underlying <see cref="EnumValueDescriptorProto"/> describing this enum value.
@ -66,17 +63,17 @@ namespace Google.Protobuf.Reflection
/// <summary> /// <summary>
/// Returns the name of the enum value described by this object. /// Returns the name of the enum value described by this object.
/// </summary> /// </summary>
public override string Name { get { return proto.Name; } } public override string Name => Proto.Name;
/// <summary> /// <summary>
/// Returns the number associated with this enum value. /// Returns the number associated with this enum value.
/// </summary> /// </summary>
public int Number { get { return Proto.Number; } } public int Number => Proto.Number;
/// <summary> /// <summary>
/// Returns the enum descriptor that this value is part of. /// Returns the enum descriptor that this value is part of.
/// </summary> /// </summary>
public EnumDescriptor EnumDescriptor { get { return enumDescriptor; } } public EnumDescriptor EnumDescriptor { get; }
/// <summary> /// <summary>
/// The (possibly empty) set of custom options for this enum value. /// The (possibly empty) set of custom options for this enum value.

View File

@ -107,8 +107,7 @@ namespace Google.Protobuf.Reflection
{ {
descriptor.CrossLink(); descriptor.CrossLink();
IList<FieldDescriptor> list; if (!declarationOrder.TryGetValue(descriptor.ExtendeeType, out IList<FieldDescriptor> list))
if (!declarationOrder.TryGetValue(descriptor.ExtendeeType, out list))
{ {
list = new List<FieldDescriptor>(); list = new List<FieldDescriptor>();
declarationOrder.Add(descriptor.ExtendeeType, list); declarationOrder.Add(descriptor.ExtendeeType, list);

View File

@ -42,15 +42,14 @@ namespace Google.Protobuf.Reflection
internal abstract class FieldAccessorBase : IFieldAccessor internal abstract class FieldAccessorBase : IFieldAccessor
{ {
private readonly Func<IMessage, object> getValueDelegate; private readonly Func<IMessage, object> getValueDelegate;
private readonly FieldDescriptor descriptor;
internal FieldAccessorBase(PropertyInfo property, FieldDescriptor descriptor) internal FieldAccessorBase(PropertyInfo property, FieldDescriptor descriptor)
{ {
this.descriptor = descriptor; Descriptor = descriptor;
getValueDelegate = ReflectionUtil.CreateFuncIMessageObject(property.GetGetMethod()); getValueDelegate = ReflectionUtil.CreateFuncIMessageObject(property.GetGetMethod());
} }
public FieldDescriptor Descriptor { get { return descriptor; } } public FieldDescriptor Descriptor { get; }
public object GetValue(IMessage message) public object GetValue(IMessage message)
{ {

View File

@ -176,47 +176,28 @@ namespace Google.Protobuf.Reflection
/// </summary> /// </summary>
private static FieldType GetFieldTypeFromProtoType(FieldDescriptorProto.Types.Type type) private static FieldType GetFieldTypeFromProtoType(FieldDescriptorProto.Types.Type type)
{ {
switch (type) return type switch
{ {
case FieldDescriptorProto.Types.Type.Double: FieldDescriptorProto.Types.Type.Double => FieldType.Double,
return FieldType.Double; FieldDescriptorProto.Types.Type.Float => FieldType.Float,
case FieldDescriptorProto.Types.Type.Float: FieldDescriptorProto.Types.Type.Int64 => FieldType.Int64,
return FieldType.Float; FieldDescriptorProto.Types.Type.Uint64 => FieldType.UInt64,
case FieldDescriptorProto.Types.Type.Int64: FieldDescriptorProto.Types.Type.Int32 => FieldType.Int32,
return FieldType.Int64; FieldDescriptorProto.Types.Type.Fixed64 => FieldType.Fixed64,
case FieldDescriptorProto.Types.Type.Uint64: FieldDescriptorProto.Types.Type.Fixed32 => FieldType.Fixed32,
return FieldType.UInt64; FieldDescriptorProto.Types.Type.Bool => FieldType.Bool,
case FieldDescriptorProto.Types.Type.Int32: FieldDescriptorProto.Types.Type.String => FieldType.String,
return FieldType.Int32; FieldDescriptorProto.Types.Type.Group => FieldType.Group,
case FieldDescriptorProto.Types.Type.Fixed64: FieldDescriptorProto.Types.Type.Message => FieldType.Message,
return FieldType.Fixed64; FieldDescriptorProto.Types.Type.Bytes => FieldType.Bytes,
case FieldDescriptorProto.Types.Type.Fixed32: FieldDescriptorProto.Types.Type.Uint32 => FieldType.UInt32,
return FieldType.Fixed32; FieldDescriptorProto.Types.Type.Enum => FieldType.Enum,
case FieldDescriptorProto.Types.Type.Bool: FieldDescriptorProto.Types.Type.Sfixed32 => FieldType.SFixed32,
return FieldType.Bool; FieldDescriptorProto.Types.Type.Sfixed64 => FieldType.SFixed64,
case FieldDescriptorProto.Types.Type.String: FieldDescriptorProto.Types.Type.Sint32 => FieldType.SInt32,
return FieldType.String; FieldDescriptorProto.Types.Type.Sint64 => FieldType.SInt64,
case FieldDescriptorProto.Types.Type.Group: _ => throw new ArgumentException("Invalid type specified"),
return FieldType.Group; };
case FieldDescriptorProto.Types.Type.Message:
return FieldType.Message;
case FieldDescriptorProto.Types.Type.Bytes:
return FieldType.Bytes;
case FieldDescriptorProto.Types.Type.Uint32:
return FieldType.UInt32;
case FieldDescriptorProto.Types.Type.Enum:
return FieldType.Enum;
case FieldDescriptorProto.Types.Type.Sfixed32:
return FieldType.SFixed32;
case FieldDescriptorProto.Types.Type.Sfixed64:
return FieldType.SFixed64;
case FieldDescriptorProto.Types.Type.Sint32:
return FieldType.SInt32;
case FieldDescriptorProto.Types.Type.Sint64:
return FieldType.SInt64;
default:
throw new ArgumentException("Invalid type specified");
}
} }
/// <summary> /// <summary>
@ -391,11 +372,11 @@ namespace Google.Protobuf.Reflection
if (fieldType == FieldType.Message || fieldType == FieldType.Group) if (fieldType == FieldType.Message || fieldType == FieldType.Group)
{ {
if (!(typeDescriptor is MessageDescriptor)) if (typeDescriptor is not MessageDescriptor m)
{ {
throw new DescriptorValidationException(this, $"\"{Proto.TypeName}\" is not a message type."); throw new DescriptorValidationException(this, $"\"{Proto.TypeName}\" is not a message type.");
} }
messageType = (MessageDescriptor) typeDescriptor; messageType = m;
if (Proto.HasDefaultValue) if (Proto.HasDefaultValue)
{ {
@ -404,11 +385,11 @@ namespace Google.Protobuf.Reflection
} }
else if (fieldType == FieldType.Enum) else if (fieldType == FieldType.Enum)
{ {
if (!(typeDescriptor is EnumDescriptor)) if (typeDescriptor is not EnumDescriptor e)
{ {
throw new DescriptorValidationException(this, $"\"{Proto.TypeName}\" is not an enum type."); throw new DescriptorValidationException(this, $"\"{Proto.TypeName}\" is not an enum type.");
} }
enumType = (EnumDescriptor) typeDescriptor; enumType = e;
} }
else else
{ {

View File

@ -35,7 +35,6 @@ using Google.Protobuf.WellKnownTypes;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using static Google.Protobuf.Reflection.SourceCodeInfo.Types; using static Google.Protobuf.Reflection.SourceCodeInfo.Types;
@ -173,25 +172,18 @@ namespace Google.Protobuf.Reflection
return list[index]; return list[index];
} }
private IReadOnlyList<DescriptorBase> GetNestedDescriptorListForField(int fieldNumber) private IReadOnlyList<DescriptorBase> GetNestedDescriptorListForField(int fieldNumber) =>
{ fieldNumber switch
switch (fieldNumber)
{ {
case FileDescriptorProto.ServiceFieldNumber: FileDescriptorProto.ServiceFieldNumber => (IReadOnlyList<DescriptorBase>)Services,
return (IReadOnlyList<DescriptorBase>) Services; FileDescriptorProto.MessageTypeFieldNumber => (IReadOnlyList<DescriptorBase>)MessageTypes,
case FileDescriptorProto.MessageTypeFieldNumber: FileDescriptorProto.EnumTypeFieldNumber => (IReadOnlyList<DescriptorBase>)EnumTypes,
return (IReadOnlyList<DescriptorBase>) MessageTypes; _ => null,
case FileDescriptorProto.EnumTypeFieldNumber: };
return (IReadOnlyList<DescriptorBase>) EnumTypes;
default:
return null;
}
}
internal DescriptorDeclaration GetDeclaration(IDescriptor descriptor) internal DescriptorDeclaration GetDeclaration(IDescriptor descriptor)
{ {
DescriptorDeclaration declaration; declarations.Value.TryGetValue(descriptor, out DescriptorDeclaration declaration);
declarations.Value.TryGetValue(descriptor, out declaration);
return declaration; return declaration;
} }
@ -227,8 +219,7 @@ namespace Google.Protobuf.Reflection
throw new DescriptorValidationException(@this, "Invalid public dependency index."); throw new DescriptorValidationException(@this, "Invalid public dependency index.");
} }
string name = proto.Dependency[index]; string name = proto.Dependency[index];
FileDescriptor file; if (!nameToFileMap.TryGetValue(name, out FileDescriptor file))
if (!nameToFileMap.TryGetValue(name, out file))
{ {
if (!allowUnknownDependencies) if (!allowUnknownDependencies)
{ {
@ -332,7 +323,7 @@ namespace Google.Protobuf.Reflection
/// <param name="name">The unqualified type name to look for.</param> /// <param name="name">The unqualified type name to look for.</param>
/// <typeparam name="T">The type of descriptor to look for</typeparam> /// <typeparam name="T">The type of descriptor to look for</typeparam>
/// <returns>The type's descriptor, or null if not found.</returns> /// <returns>The type's descriptor, or null if not found.</returns>
public T FindTypeByName<T>(String name) public T FindTypeByName<T>(string name)
where T : class, IDescriptor where T : class, IDescriptor
{ {
// Don't allow looking up nested types. This will make optimization // Don't allow looking up nested types. This will make optimization
@ -507,8 +498,7 @@ namespace Google.Protobuf.Reflection
var dependencies = new List<FileDescriptor>(); var dependencies = new List<FileDescriptor>();
foreach (var dependencyName in proto.Dependency) foreach (var dependencyName in proto.Dependency)
{ {
FileDescriptor dependency; if (!descriptorsByName.TryGetValue(dependencyName, out FileDescriptor dependency))
if (!descriptorsByName.TryGetValue(dependencyName, out dependency))
{ {
throw new ArgumentException($"Dependency missing: {dependencyName}"); throw new ArgumentException($"Dependency missing: {dependencyName}");
} }
@ -565,7 +555,7 @@ namespace Google.Protobuf.Reflection
/// <value> /// <value>
/// The file descriptor for <c>descriptor.proto</c>. /// The file descriptor for <c>descriptor.proto</c>.
/// </value> /// </value>
public static FileDescriptor DescriptorProtoFileDescriptor { get { return DescriptorReflection.Descriptor; } } public static FileDescriptor DescriptorProtoFileDescriptor => DescriptorReflection.Descriptor;
/// <summary> /// <summary>
/// The (possibly empty) set of custom options for this file. /// The (possibly empty) set of custom options for this file.

View File

@ -29,6 +29,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion #endregion
using System; using System;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
@ -57,7 +58,7 @@ namespace Google.Protobuf.Reflection
/// Irrelevant for file descriptors; the CLR type for the message for message descriptors. /// Irrelevant for file descriptors; the CLR type for the message for message descriptors.
/// </summary> /// </summary>
[DynamicallyAccessedMembers(MessageAccessibility)] [DynamicallyAccessedMembers(MessageAccessibility)]
public Type ClrType { get; private set; } public Type ClrType { get; }
/// <summary> /// <summary>
/// Irrelevant for file descriptors; the parser for message descriptors. /// Irrelevant for file descriptors; the parser for message descriptors.

View File

@ -130,20 +130,14 @@ namespace Google.Protobuf.Reflection
/// </summary> /// </summary>
public override string Name => Proto.Name; public override string Name => Proto.Name;
internal override IReadOnlyList<DescriptorBase> GetNestedDescriptorListForField(int fieldNumber) internal override IReadOnlyList<DescriptorBase> GetNestedDescriptorListForField(int fieldNumber) =>
{ fieldNumber switch
switch (fieldNumber)
{ {
case DescriptorProto.FieldFieldNumber: DescriptorProto.FieldFieldNumber => (IReadOnlyList<DescriptorBase>)fieldsInDeclarationOrder,
return (IReadOnlyList<DescriptorBase>) fieldsInDeclarationOrder; DescriptorProto.NestedTypeFieldNumber => (IReadOnlyList<DescriptorBase>)NestedTypes,
case DescriptorProto.NestedTypeFieldNumber: DescriptorProto.EnumTypeFieldNumber => (IReadOnlyList<DescriptorBase>)EnumTypes,
return (IReadOnlyList<DescriptorBase>) NestedTypes; _ => null,
case DescriptorProto.EnumTypeFieldNumber: };
return (IReadOnlyList<DescriptorBase>) EnumTypes;
default:
return null;
}
}
internal DescriptorProto Proto { get; } internal DescriptorProto Proto { get; }
@ -272,7 +266,7 @@ namespace Google.Protobuf.Reflection
/// </summary> /// </summary>
/// <param name="name">The unqualified name of the field (e.g. "foo").</param> /// <param name="name">The unqualified name of the field (e.g. "foo").</param>
/// <returns>The field's descriptor, or null if not found.</returns> /// <returns>The field's descriptor, or null if not found.</returns>
public FieldDescriptor FindFieldByName(String name) => File.DescriptorPool.FindSymbol<FieldDescriptor>(FullName + "." + name); public FieldDescriptor FindFieldByName(string name) => File.DescriptorPool.FindSymbol<FieldDescriptor>(FullName + "." + name);
/// <summary> /// <summary>
/// Finds a field by field number. /// Finds a field by field number.

View File

@ -40,35 +40,31 @@ namespace Google.Protobuf.Reflection
/// </summary> /// </summary>
public sealed class MethodDescriptor : DescriptorBase public sealed class MethodDescriptor : DescriptorBase
{ {
private readonly MethodDescriptorProto proto;
private readonly ServiceDescriptor service;
private MessageDescriptor inputType;
private MessageDescriptor outputType;
/// <value> /// <value>
/// The service this method belongs to. /// The service this method belongs to.
/// </value> /// </value>
public ServiceDescriptor Service { get { return service; } } public ServiceDescriptor Service { get; }
/// <value> /// <value>
/// The method's input type. /// The method's input type.
/// </value> /// </value>
public MessageDescriptor InputType { get { return inputType; } } public MessageDescriptor InputType { get; private set; }
/// <value> /// <value>
/// The method's input type. /// The method's input type.
/// </value> /// </value>
public MessageDescriptor OutputType { get { return outputType; } } public MessageDescriptor OutputType { get; private set; }
/// <value> /// <value>
/// Indicates if client streams multiple requests. /// Indicates if client streams multiple requests.
/// </value> /// </value>
public bool IsClientStreaming { get { return proto.ClientStreaming; } } public bool IsClientStreaming => Proto.ClientStreaming;
/// <value> /// <value>
/// Indicates if server streams multiple responses. /// Indicates if server streams multiple responses.
/// </value> /// </value>
public bool IsServerStreaming { get { return proto.ServerStreaming; } } public bool IsServerStreaming => Proto.ServerStreaming;
/// <summary> /// <summary>
/// The (possibly empty) set of custom options for this method. /// The (possibly empty) set of custom options for this method.
@ -91,7 +87,7 @@ namespace Google.Protobuf.Reflection
public T GetOption<T>(Extension<MethodOptions, T> extension) public T GetOption<T>(Extension<MethodOptions, T> extension)
{ {
var value = Proto.Options.GetExtension(extension); var value = Proto.Options.GetExtension(extension);
return value is IDeepCloneable<T> ? (value as IDeepCloneable<T>).Clone() : value; return value is IDeepCloneable<T> c ? c.Clone() : value;
} }
/// <summary> /// <summary>
@ -107,12 +103,12 @@ namespace Google.Protobuf.Reflection
ServiceDescriptor parent, int index) ServiceDescriptor parent, int index)
: base(file, parent.FullName + "." + proto.Name, index) : base(file, parent.FullName + "." + proto.Name, index)
{ {
this.proto = proto; Proto = proto;
service = parent; Service = parent;
file.DescriptorPool.AddSymbol(this); file.DescriptorPool.AddSymbol(this);
} }
internal MethodDescriptorProto Proto { get { return proto; } } internal MethodDescriptorProto Proto { get; private set; }
/// <summary> /// <summary>
/// Returns a clone of the underlying <see cref="MethodDescriptorProto"/> describing this method. /// Returns a clone of the underlying <see cref="MethodDescriptorProto"/> describing this method.
@ -125,23 +121,23 @@ namespace Google.Protobuf.Reflection
/// <summary> /// <summary>
/// The brief name of the descriptor's target. /// The brief name of the descriptor's target.
/// </summary> /// </summary>
public override string Name { get { return proto.Name; } } public override string Name => Proto.Name;
internal void CrossLink() internal void CrossLink()
{ {
IDescriptor lookup = File.DescriptorPool.LookupSymbol(Proto.InputType, this); IDescriptor lookup = File.DescriptorPool.LookupSymbol(Proto.InputType, this);
if (!(lookup is MessageDescriptor)) if (lookup is not MessageDescriptor inpoutType)
{ {
throw new DescriptorValidationException(this, "\"" + Proto.InputType + "\" is not a message type."); throw new DescriptorValidationException(this, "\"" + Proto.InputType + "\" is not a message type.");
} }
inputType = (MessageDescriptor) lookup; InputType = inpoutType;
lookup = File.DescriptorPool.LookupSymbol(Proto.OutputType, this); lookup = File.DescriptorPool.LookupSymbol(Proto.OutputType, this);
if (!(lookup is MessageDescriptor)) if (lookup is not MessageDescriptor outputType)
{ {
throw new DescriptorValidationException(this, "\"" + Proto.OutputType + "\" is not a message type."); throw new DescriptorValidationException(this, "\"" + Proto.OutputType + "\" is not a message type.");
} }
outputType = (MessageDescriptor) lookup; OutputType = outputType;
} }
} }
} }

View File

@ -60,6 +60,5 @@ namespace Google.Protobuf.Reflection
Name = ProtoPreconditions.CheckNotNull(name, nameof(name)); Name = ProtoPreconditions.CheckNotNull(name, nameof(name));
PreferredAlias = true; PreferredAlias = true;
} }
} }
} }

View File

@ -39,30 +39,15 @@ namespace Google.Protobuf.Reflection
/// </summary> /// </summary>
internal sealed class PackageDescriptor : IDescriptor internal sealed class PackageDescriptor : IDescriptor
{ {
private readonly string name;
private readonly string fullName;
private readonly FileDescriptor file;
internal PackageDescriptor(string name, string fullName, FileDescriptor file) internal PackageDescriptor(string name, string fullName, FileDescriptor file)
{ {
this.file = file; File = file;
this.fullName = fullName; FullName = fullName;
this.name = name; Name = name;
} }
public string Name public string Name { get; }
{ public string FullName { get; }
get { return name; } public FileDescriptor File { get; }
}
public string FullName
{
get { return fullName; }
}
public FileDescriptor File
{
get { return file; }
}
} }
} }

View File

@ -221,20 +221,18 @@ namespace Google.Protobuf.Reflection
public object GetExtension(IMessage message) public object GetExtension(IMessage message)
{ {
if (!(message is T1)) if (message is not T1 extensionMessage)
{ {
throw new InvalidCastException("Cannot access extension on message that isn't IExtensionMessage"); throw new InvalidCastException("Cannot access extension on message that isn't IExtensionMessage");
} }
T1 extensionMessage = (T1)message; if (extension is Extension<T1, T3> ext13)
if (extension is Extension<T1, T3>)
{ {
return extensionMessage.GetExtension(extension as Extension<T1, T3>); return extensionMessage.GetExtension(ext13);
} }
else if (extension is RepeatedExtension<T1, T3>) else if (extension is RepeatedExtension<T1, T3> repeatedExt13)
{ {
return extensionMessage.GetOrInitializeExtension(extension as RepeatedExtension<T1, T3>); return extensionMessage.GetOrInitializeExtension(repeatedExt13);
} }
else else
{ {
@ -244,16 +242,14 @@ namespace Google.Protobuf.Reflection
public bool HasExtension(IMessage message) public bool HasExtension(IMessage message)
{ {
if (!(message is T1)) if (message is not T1 extensionMessage)
{ {
throw new InvalidCastException("Cannot access extension on message that isn't IExtensionMessage"); throw new InvalidCastException("Cannot access extension on message that isn't IExtensionMessage");
} }
T1 extensionMessage = (T1)message; if (extension is Extension<T1, T3> ext13)
if (extension is Extension<T1, T3>)
{ {
return extensionMessage.HasExtension(extension as Extension<T1, T3>); return extensionMessage.HasExtension(ext13);
} }
else if (extension is RepeatedExtension<T1, T3>) else if (extension is RepeatedExtension<T1, T3>)
{ {
@ -267,16 +263,14 @@ namespace Google.Protobuf.Reflection
public void SetExtension(IMessage message, object value) public void SetExtension(IMessage message, object value)
{ {
if (!(message is T1)) if (message is not T1 extensionMessage)
{ {
throw new InvalidCastException("Cannot access extension on message that isn't IExtensionMessage"); throw new InvalidCastException("Cannot access extension on message that isn't IExtensionMessage");
} }
T1 extensionMessage = (T1)message; if (extension is Extension<T1, T3> ext13)
if (extension is Extension<T1, T3>)
{ {
extensionMessage.SetExtension(extension as Extension<T1, T3>, (T3)value); extensionMessage.SetExtension(ext13, (T3)value);
} }
else if (extension is RepeatedExtension<T1, T3>) else if (extension is RepeatedExtension<T1, T3>)
{ {
@ -290,20 +284,18 @@ namespace Google.Protobuf.Reflection
public void ClearExtension(IMessage message) public void ClearExtension(IMessage message)
{ {
if (!(message is T1)) if (message is not T1 extensionMessage)
{ {
throw new InvalidCastException("Cannot access extension on message that isn't IExtensionMessage"); throw new InvalidCastException("Cannot access extension on message that isn't IExtensionMessage");
} }
T1 extensionMessage = (T1)message; if (extension is Extension<T1, T3> ext13)
if (extension is Extension<T1, T3>)
{ {
extensionMessage.ClearExtension(extension as Extension<T1, T3>); extensionMessage.ClearExtension(ext13);
} }
else if (extension is RepeatedExtension<T1, T3>) else if (extension is RepeatedExtension<T1, T3> repeatedExt13)
{ {
extensionMessage.GetExtension(extension as RepeatedExtension<T1, T3>).Clear(); extensionMessage.GetExtension(repeatedExt13).Clear();
} }
else else
{ {

View File

@ -60,6 +60,5 @@ namespace Google.Protobuf.Reflection
{ {
throw new InvalidOperationException("SetValue is not implemented for repeated fields"); throw new InvalidOperationException("SetValue is not implemented for repeated fields");
} }
} }
} }

View File

@ -33,7 +33,6 @@
using Google.Protobuf.Collections; using Google.Protobuf.Collections;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace Google.Protobuf.Reflection namespace Google.Protobuf.Reflection
{ {
@ -42,14 +41,11 @@ namespace Google.Protobuf.Reflection
/// </summary> /// </summary>
public sealed class ServiceDescriptor : DescriptorBase public sealed class ServiceDescriptor : DescriptorBase
{ {
private readonly ServiceDescriptorProto proto;
private readonly IList<MethodDescriptor> methods;
internal ServiceDescriptor(ServiceDescriptorProto proto, FileDescriptor file, int index) internal ServiceDescriptor(ServiceDescriptorProto proto, FileDescriptor file, int index)
: base(file, file.ComputeFullName(null, proto.Name), index) : base(file, file.ComputeFullName(null, proto.Name), index)
{ {
this.proto = proto; Proto = proto;
methods = DescriptorUtil.ConvertAndMakeReadOnly(proto.Method, Methods = DescriptorUtil.ConvertAndMakeReadOnly(proto.Method,
(method, i) => new MethodDescriptor(method, file, this, i)); (method, i) => new MethodDescriptor(method, file, this, i));
file.DescriptorPool.AddSymbol(this); file.DescriptorPool.AddSymbol(this);
@ -58,20 +54,16 @@ namespace Google.Protobuf.Reflection
/// <summary> /// <summary>
/// The brief name of the descriptor's target. /// The brief name of the descriptor's target.
/// </summary> /// </summary>
public override string Name { get { return proto.Name; } } public override string Name => Proto.Name;
internal override IReadOnlyList<DescriptorBase> GetNestedDescriptorListForField(int fieldNumber) internal override IReadOnlyList<DescriptorBase> GetNestedDescriptorListForField(int fieldNumber) =>
{ fieldNumber switch
switch (fieldNumber)
{ {
case ServiceDescriptorProto.MethodFieldNumber: ServiceDescriptorProto.MethodFieldNumber => (IReadOnlyList<DescriptorBase>)Methods,
return (IReadOnlyList<DescriptorBase>) methods; _ => null,
default: };
return null;
}
}
internal ServiceDescriptorProto Proto { get { return proto; } } internal ServiceDescriptorProto Proto { get; }
/// <summary> /// <summary>
/// Returns a clone of the underlying <see cref="ServiceDescriptorProto"/> describing this service. /// Returns a clone of the underlying <see cref="ServiceDescriptorProto"/> describing this service.
@ -84,20 +76,15 @@ namespace Google.Protobuf.Reflection
/// <value> /// <value>
/// An unmodifiable list of methods in this service. /// An unmodifiable list of methods in this service.
/// </value> /// </value>
public IList<MethodDescriptor> Methods public IList<MethodDescriptor> Methods { get; }
{
get { return methods; }
}
/// <summary> /// <summary>
/// Finds a method by name. /// Finds a method by name.
/// </summary> /// </summary>
/// <param name="name">The unqualified name of the method (e.g. "Foo").</param> /// <param name="name">The unqualified name of the method (e.g. "Foo").</param>
/// <returns>The method's descriptor, or null if not found.</returns> /// <returns>The method's descriptor, or null if not found.</returns>
public MethodDescriptor FindMethodByName(String name) public MethodDescriptor FindMethodByName(string name) =>
{ File.DescriptorPool.FindSymbol<MethodDescriptor>(FullName + "." + name);
return File.DescriptorPool.FindSymbol<MethodDescriptor>(FullName + "." + name);
}
/// <summary> /// <summary>
/// The (possibly empty) set of custom options for this service. /// The (possibly empty) set of custom options for this service.
@ -134,7 +121,7 @@ namespace Google.Protobuf.Reflection
internal void CrossLink() internal void CrossLink()
{ {
foreach (MethodDescriptor method in methods) foreach (MethodDescriptor method in Methods)
{ {
method.CrossLink(); method.CrossLink();
} }

View File

@ -31,7 +31,6 @@
#endregion #endregion
using System; using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Reflection; using System.Reflection;
using Google.Protobuf.Compatibility; using Google.Protobuf.Compatibility;
@ -108,7 +107,7 @@ namespace Google.Protobuf.Reflection
// Primitive proto3 fields without the optional keyword, which aren't in oneofs. // Primitive proto3 fields without the optional keyword, which aren't in oneofs.
else else
{ {
hasDelegate = message => { throw new InvalidOperationException("Presence is not implemented for this field"); }; hasDelegate = message => throw new InvalidOperationException("Presence is not implemented for this field");
// While presence isn't supported, clearing still is; it's just setting to a default value. // While presence isn't supported, clearing still is; it's just setting to a default value.
object defaultValue = GetDefaultValue(descriptor); object defaultValue = GetDefaultValue(descriptor);
@ -116,42 +115,21 @@ namespace Google.Protobuf.Reflection
} }
} }
private static object GetDefaultValue(FieldDescriptor descriptor) private static object GetDefaultValue(FieldDescriptor descriptor) =>
{ descriptor.FieldType switch
switch (descriptor.FieldType)
{ {
case FieldType.Bool: FieldType.Bool => false,
return false; FieldType.Bytes => ByteString.Empty,
case FieldType.Bytes: FieldType.String => "",
return ByteString.Empty; FieldType.Double => 0.0,
case FieldType.String: FieldType.SInt32 or FieldType.Int32 or FieldType.SFixed32 or FieldType.Enum => 0,
return ""; FieldType.Fixed32 or FieldType.UInt32 => (uint)0,
case FieldType.Double: FieldType.Fixed64 or FieldType.UInt64 => 0UL,
return 0.0; FieldType.SFixed64 or FieldType.Int64 or FieldType.SInt64 => 0L,
case FieldType.SInt32: FieldType.Float => 0f,
case FieldType.Int32: FieldType.Message or FieldType.Group => null,
case FieldType.SFixed32: _ => throw new ArgumentException("Invalid field type"),
case FieldType.Enum: };
return 0;
case FieldType.Fixed32:
case FieldType.UInt32:
return (uint)0;
case FieldType.Fixed64:
case FieldType.UInt64:
return 0UL;
case FieldType.SFixed64:
case FieldType.Int64:
case FieldType.SInt64:
return 0L;
case FieldType.Float:
return 0f;
case FieldType.Message:
case FieldType.Group: // Never expect to get this, but...
return null;
default:
throw new ArgumentException("Invalid field type");
}
}
public override void Clear(IMessage message) => clearDelegate(message); public override void Clear(IMessage message) => clearDelegate(message);
public override bool HasValue(IMessage message) => hasDelegate(message); public override bool HasValue(IMessage message) => hasDelegate(message);

View File

@ -29,6 +29,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion #endregion
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -60,9 +61,8 @@ namespace Google.Protobuf.Reflection
/// if there is no such message descriptor.</returns> /// if there is no such message descriptor.</returns>
public MessageDescriptor Find(string fullName) public MessageDescriptor Find(string fullName)
{ {
MessageDescriptor ret;
// Ignore the return value as ret will end up with the right value either way. // Ignore the return value as ret will end up with the right value either way.
fullNameToMessageMap.TryGetValue(fullName, out ret); fullNameToMessageMap.TryGetValue(fullName, out MessageDescriptor ret);
return ret; return ret;
} }

View File

@ -30,9 +30,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion #endregion
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using Google.Protobuf.Collections; using Google.Protobuf.Collections;
namespace Google.Protobuf namespace Google.Protobuf
@ -73,13 +71,12 @@ namespace Google.Protobuf
{ {
return true; return true;
} }
UnknownField otherField = other as UnknownField; return other is UnknownField otherField
return otherField != null && Lists.Equals(varintList, otherField.varintList)
&& Lists.Equals(varintList, otherField.varintList) && Lists.Equals(fixed32List, otherField.fixed32List)
&& Lists.Equals(fixed32List, otherField.fixed32List) && Lists.Equals(fixed64List, otherField.fixed64List)
&& Lists.Equals(fixed64List, otherField.fixed64List) && Lists.Equals(lengthDelimitedList, otherField.lengthDelimitedList)
&& Lists.Equals(lengthDelimitedList, otherField.lengthDelimitedList) && Lists.Equals(groupList, otherField.groupList);
&& Lists.Equals(groupList, otherField.groupList);
} }
/// <summary> /// <summary>

View File

@ -32,9 +32,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Security; using System.Security;
using Google.Protobuf.Reflection;
namespace Google.Protobuf namespace Google.Protobuf
{ {
@ -49,14 +47,13 @@ namespace Google.Protobuf
/// </summary> /// </summary>
public sealed partial class UnknownFieldSet public sealed partial class UnknownFieldSet
{ {
private readonly IDictionary<int, UnknownField> fields; private readonly IDictionary<int, UnknownField> fields = new Dictionary<int, UnknownField>();
/// <summary> /// <summary>
/// Creates a new UnknownFieldSet. /// Creates a new UnknownFieldSet.
/// </summary> /// </summary>
internal UnknownFieldSet() internal UnknownFieldSet()
{ {
this.fields = new Dictionary<int, UnknownField>();
} }
/// <summary> /// <summary>
@ -125,8 +122,7 @@ namespace Google.Protobuf
} }
foreach (KeyValuePair<int, UnknownField> leftEntry in fields) foreach (KeyValuePair<int, UnknownField> leftEntry in fields)
{ {
UnknownField rightValue; if (!otherFields.TryGetValue(leftEntry.Key, out UnknownField rightValue))
if (!otherFields.TryGetValue(leftEntry.Key, out rightValue))
{ {
return false; return false;
} }
@ -170,8 +166,7 @@ namespace Google.Protobuf
return null; return null;
} }
UnknownField existing; if (fields.TryGetValue(number, out UnknownField existing))
if (fields.TryGetValue(number, out existing))
{ {
return existing; return existing;
} }

View File

@ -112,7 +112,7 @@ namespace Google.Protobuf.WellKnownTypes
T target = new T(); T target = new T();
if (GetTypeName(TypeUrl) != target.Descriptor.FullName) if (GetTypeName(TypeUrl) != target.Descriptor.FullName)
{ {
result = default(T); // Can't use null as there's no class constraint, but this always *will* be null in real usage. result = default; // Can't use null as there's no class constraint, but this always *will* be null in real usage.
return false; return false;
} }
target.MergeFrom(Value); target.MergeFrom(Value);

View File

@ -59,8 +59,8 @@ namespace Google.Protobuf.WellKnownTypes
/// <returns>The difference between the two specified timestamps.</returns> /// <returns>The difference between the two specified timestamps.</returns>
public static Duration operator -(Timestamp lhs, Timestamp rhs) public static Duration operator -(Timestamp lhs, Timestamp rhs)
{ {
ProtoPreconditions.CheckNotNull(lhs, "lhs"); ProtoPreconditions.CheckNotNull(lhs, nameof(lhs));
ProtoPreconditions.CheckNotNull(rhs, "rhs"); ProtoPreconditions.CheckNotNull(rhs, nameof(rhs));
checked checked
{ {
return Duration.Normalize(lhs.Seconds - rhs.Seconds, lhs.Nanos - rhs.Nanos); return Duration.Normalize(lhs.Seconds - rhs.Seconds, lhs.Nanos - rhs.Nanos);
@ -75,8 +75,8 @@ namespace Google.Protobuf.WellKnownTypes
/// <returns>The result of adding the duration to the timestamp.</returns> /// <returns>The result of adding the duration to the timestamp.</returns>
public static Timestamp operator +(Timestamp lhs, Duration rhs) public static Timestamp operator +(Timestamp lhs, Duration rhs)
{ {
ProtoPreconditions.CheckNotNull(lhs, "lhs"); ProtoPreconditions.CheckNotNull(lhs, nameof(lhs));
ProtoPreconditions.CheckNotNull(rhs, "rhs"); ProtoPreconditions.CheckNotNull(rhs, nameof(rhs));
checked checked
{ {
return Normalize(lhs.Seconds + rhs.Seconds, lhs.Nanos + rhs.Nanos); return Normalize(lhs.Seconds + rhs.Seconds, lhs.Nanos + rhs.Nanos);
@ -91,8 +91,8 @@ namespace Google.Protobuf.WellKnownTypes
/// <returns>The result of subtracting the duration from the timestamp.</returns> /// <returns>The result of subtracting the duration from the timestamp.</returns>
public static Timestamp operator -(Timestamp lhs, Duration rhs) public static Timestamp operator -(Timestamp lhs, Duration rhs)
{ {
ProtoPreconditions.CheckNotNull(lhs, "lhs"); ProtoPreconditions.CheckNotNull(lhs, nameof(lhs));
ProtoPreconditions.CheckNotNull(rhs, "rhs"); ProtoPreconditions.CheckNotNull(rhs, nameof(rhs));
checked checked
{ {
return Normalize(lhs.Seconds - rhs.Seconds, lhs.Nanos - rhs.Nanos); return Normalize(lhs.Seconds - rhs.Seconds, lhs.Nanos - rhs.Nanos);
@ -308,7 +308,7 @@ namespace Google.Protobuf.WellKnownTypes
/// <returns>true if the two timestamps refer to the same nanosecond</returns> /// <returns>true if the two timestamps refer to the same nanosecond</returns>
public static bool operator ==(Timestamp a, Timestamp b) public static bool operator ==(Timestamp a, Timestamp b)
{ {
return ReferenceEquals(a, b) || (ReferenceEquals(a, null) ? (ReferenceEquals(b, null) ? true : false) : a.Equals(b)); return ReferenceEquals(a, b) || (a is null ? (b is null) : a.Equals(b));
} }
/// <summary> /// <summary>

View File

@ -41,7 +41,7 @@ namespace Google.Protobuf.WellKnownTypes
/// <returns>A newly-created Value message with the given value.</returns> /// <returns>A newly-created Value message with the given value.</returns>
public static Value ForString(string value) public static Value ForString(string value)
{ {
ProtoPreconditions.CheckNotNull(value, "value"); ProtoPreconditions.CheckNotNull(value, nameof(value));
return new Value { StringValue = value }; return new Value { StringValue = value };
} }
@ -81,7 +81,7 @@ namespace Google.Protobuf.WellKnownTypes
/// <returns>A newly-created Value message an initial list value.</returns> /// <returns>A newly-created Value message an initial list value.</returns>
public static Value ForList(params Value[] values) public static Value ForList(params Value[] values)
{ {
ProtoPreconditions.CheckNotNull(values, "values"); ProtoPreconditions.CheckNotNull(values, nameof(values));
return new Value { ListValue = new ListValue { Values = { values } } }; return new Value { ListValue = new ListValue { Values = { values } } };
} }
@ -92,7 +92,7 @@ namespace Google.Protobuf.WellKnownTypes
/// <returns>A newly-created Value message an initial struct value.</returns> /// <returns>A newly-created Value message an initial struct value.</returns>
public static Value ForStruct(Struct value) public static Value ForStruct(Struct value)
{ {
ProtoPreconditions.CheckNotNull(value, "value"); ProtoPreconditions.CheckNotNull(value, nameof(value));
return new Value { StructValue = value }; return new Value { StructValue = value };
} }
} }

View File

@ -32,7 +32,6 @@
using System; using System;
using System.Buffers; using System.Buffers;
using System.IO;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Security; using System.Security;

View File

@ -32,14 +32,8 @@
using System; using System;
using System.Buffers; using System.Buffers;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security; using System.Security;
using System.Text;
using Google.Protobuf.Collections;
namespace Google.Protobuf namespace Google.Protobuf
{ {
@ -101,166 +95,112 @@ namespace Google.Protobuf
/// Writes a double field value, without a tag. /// Writes a double field value, without a tag.
/// </summary> /// </summary>
/// <param name="value">The value to write</param> /// <param name="value">The value to write</param>
public void WriteDouble(double value) public void WriteDouble(double value) => WritingPrimitives.WriteDouble(ref buffer, ref state, value);
{
WritingPrimitives.WriteDouble(ref buffer, ref state, value);
}
/// <summary> /// <summary>
/// Writes a float field value, without a tag. /// Writes a float field value, without a tag.
/// </summary> /// </summary>
/// <param name="value">The value to write</param> /// <param name="value">The value to write</param>
public void WriteFloat(float value) public void WriteFloat(float value) => WritingPrimitives.WriteFloat(ref buffer, ref state, value);
{
WritingPrimitives.WriteFloat(ref buffer, ref state, value);
}
/// <summary> /// <summary>
/// Writes a uint64 field value, without a tag. /// Writes a uint64 field value, without a tag.
/// </summary> /// </summary>
/// <param name="value">The value to write</param> /// <param name="value">The value to write</param>
public void WriteUInt64(ulong value) public void WriteUInt64(ulong value) => WritingPrimitives.WriteUInt64(ref buffer, ref state, value);
{
WritingPrimitives.WriteUInt64(ref buffer, ref state, value);
}
/// <summary> /// <summary>
/// Writes an int64 field value, without a tag. /// Writes an int64 field value, without a tag.
/// </summary> /// </summary>
/// <param name="value">The value to write</param> /// <param name="value">The value to write</param>
public void WriteInt64(long value) public void WriteInt64(long value) => WritingPrimitives.WriteInt64(ref buffer, ref state, value);
{
WritingPrimitives.WriteInt64(ref buffer, ref state, value);
}
/// <summary> /// <summary>
/// Writes an int32 field value, without a tag. /// Writes an int32 field value, without a tag.
/// </summary> /// </summary>
/// <param name="value">The value to write</param> /// <param name="value">The value to write</param>
public void WriteInt32(int value) public void WriteInt32(int value) => WritingPrimitives.WriteInt32(ref buffer, ref state, value);
{
WritingPrimitives.WriteInt32(ref buffer, ref state, value);
}
/// <summary> /// <summary>
/// Writes a fixed64 field value, without a tag. /// Writes a fixed64 field value, without a tag.
/// </summary> /// </summary>
/// <param name="value">The value to write</param> /// <param name="value">The value to write</param>
public void WriteFixed64(ulong value) public void WriteFixed64(ulong value) => WritingPrimitives.WriteFixed64(ref buffer, ref state, value);
{
WritingPrimitives.WriteFixed64(ref buffer, ref state, value);
}
/// <summary> /// <summary>
/// Writes a fixed32 field value, without a tag. /// Writes a fixed32 field value, without a tag.
/// </summary> /// </summary>
/// <param name="value">The value to write</param> /// <param name="value">The value to write</param>
public void WriteFixed32(uint value) public void WriteFixed32(uint value) => WritingPrimitives.WriteFixed32(ref buffer, ref state, value);
{
WritingPrimitives.WriteFixed32(ref buffer, ref state, value);
}
/// <summary> /// <summary>
/// Writes a bool field value, without a tag. /// Writes a bool field value, without a tag.
/// </summary> /// </summary>
/// <param name="value">The value to write</param> /// <param name="value">The value to write</param>
public void WriteBool(bool value) public void WriteBool(bool value) => WritingPrimitives.WriteBool(ref buffer, ref state, value);
{
WritingPrimitives.WriteBool(ref buffer, ref state, value);
}
/// <summary> /// <summary>
/// Writes a string field value, without a tag. /// Writes a string field value, without a tag.
/// The data is length-prefixed. /// The data is length-prefixed.
/// </summary> /// </summary>
/// <param name="value">The value to write</param> /// <param name="value">The value to write</param>
public void WriteString(string value) public void WriteString(string value) => WritingPrimitives.WriteString(ref buffer, ref state, value);
{
WritingPrimitives.WriteString(ref buffer, ref state, value);
}
/// <summary> /// <summary>
/// Writes a message, without a tag. /// Writes a message, without a tag.
/// The data is length-prefixed. /// The data is length-prefixed.
/// </summary> /// </summary>
/// <param name="value">The value to write</param> /// <param name="value">The value to write</param>
public void WriteMessage(IMessage value) public void WriteMessage(IMessage value) => WritingPrimitivesMessages.WriteMessage(ref this, value);
{
WritingPrimitivesMessages.WriteMessage(ref this, value);
}
/// <summary> /// <summary>
/// Writes a group, without a tag, to the stream. /// Writes a group, without a tag, to the stream.
/// </summary> /// </summary>
/// <param name="value">The value to write</param> /// <param name="value">The value to write</param>
public void WriteGroup(IMessage value) public void WriteGroup(IMessage value) => WritingPrimitivesMessages.WriteGroup(ref this, value);
{
WritingPrimitivesMessages.WriteGroup(ref this, value);
}
/// <summary> /// <summary>
/// Write a byte string, without a tag, to the stream. /// Write a byte string, without a tag, to the stream.
/// The data is length-prefixed. /// The data is length-prefixed.
/// </summary> /// </summary>
/// <param name="value">The value to write</param> /// <param name="value">The value to write</param>
public void WriteBytes(ByteString value) public void WriteBytes(ByteString value) => WritingPrimitives.WriteBytes(ref buffer, ref state, value);
{
WritingPrimitives.WriteBytes(ref buffer, ref state, value);
}
/// <summary> /// <summary>
/// Writes a uint32 value, without a tag. /// Writes a uint32 value, without a tag.
/// </summary> /// </summary>
/// <param name="value">The value to write</param> /// <param name="value">The value to write</param>
public void WriteUInt32(uint value) public void WriteUInt32(uint value) => WritingPrimitives.WriteUInt32(ref buffer, ref state, value);
{
WritingPrimitives.WriteUInt32(ref buffer, ref state, value);
}
/// <summary> /// <summary>
/// Writes an enum value, without a tag. /// Writes an enum value, without a tag.
/// </summary> /// </summary>
/// <param name="value">The value to write</param> /// <param name="value">The value to write</param>
public void WriteEnum(int value) public void WriteEnum(int value) => WritingPrimitives.WriteEnum(ref buffer, ref state, value);
{
WritingPrimitives.WriteEnum(ref buffer, ref state, value);
}
/// <summary> /// <summary>
/// Writes an sfixed32 value, without a tag. /// Writes an sfixed32 value, without a tag.
/// </summary> /// </summary>
/// <param name="value">The value to write.</param> /// <param name="value">The value to write.</param>
public void WriteSFixed32(int value) public void WriteSFixed32(int value) => WritingPrimitives.WriteSFixed32(ref buffer, ref state, value);
{
WritingPrimitives.WriteSFixed32(ref buffer, ref state, value);
}
/// <summary> /// <summary>
/// Writes an sfixed64 value, without a tag. /// Writes an sfixed64 value, without a tag.
/// </summary> /// </summary>
/// <param name="value">The value to write</param> /// <param name="value">The value to write</param>
public void WriteSFixed64(long value) public void WriteSFixed64(long value) => WritingPrimitives.WriteSFixed64(ref buffer, ref state, value);
{
WritingPrimitives.WriteSFixed64(ref buffer, ref state, value);
}
/// <summary> /// <summary>
/// Writes an sint32 value, without a tag. /// Writes an sint32 value, without a tag.
/// </summary> /// </summary>
/// <param name="value">The value to write</param> /// <param name="value">The value to write</param>
public void WriteSInt32(int value) public void WriteSInt32(int value) => WritingPrimitives.WriteSInt32(ref buffer, ref state, value);
{
WritingPrimitives.WriteSInt32(ref buffer, ref state, value);
}
/// <summary> /// <summary>
/// Writes an sint64 value, without a tag. /// Writes an sint64 value, without a tag.
/// </summary> /// </summary>
/// <param name="value">The value to write</param> /// <param name="value">The value to write</param>
public void WriteSInt64(long value) public void WriteSInt64(long value) => WritingPrimitives.WriteSInt64(ref buffer, ref state, value);
{
WritingPrimitives.WriteSInt64(ref buffer, ref state, value);
}
/// <summary> /// <summary>
/// Writes a length (in bytes) for length-delimited data. /// Writes a length (in bytes) for length-delimited data.
@ -269,48 +209,33 @@ namespace Google.Protobuf
/// This method simply writes a rawint, but exists for clarity in calling code. /// This method simply writes a rawint, but exists for clarity in calling code.
/// </remarks> /// </remarks>
/// <param name="length">Length value, in bytes.</param> /// <param name="length">Length value, in bytes.</param>
public void WriteLength(int length) public void WriteLength(int length) => WritingPrimitives.WriteLength(ref buffer, ref state, length);
{
WritingPrimitives.WriteLength(ref buffer, ref state, length);
}
/// <summary> /// <summary>
/// Encodes and writes a tag. /// Encodes and writes a tag.
/// </summary> /// </summary>
/// <param name="fieldNumber">The number of the field to write the tag for</param> /// <param name="fieldNumber">The number of the field to write the tag for</param>
/// <param name="type">The wire format type of the tag to write</param> /// <param name="type">The wire format type of the tag to write</param>
public void WriteTag(int fieldNumber, WireFormat.WireType type) public void WriteTag(int fieldNumber, WireFormat.WireType type) => WritingPrimitives.WriteTag(ref buffer, ref state, fieldNumber, type);
{
WritingPrimitives.WriteTag(ref buffer, ref state, fieldNumber, type);
}
/// <summary> /// <summary>
/// Writes an already-encoded tag. /// Writes an already-encoded tag.
/// </summary> /// </summary>
/// <param name="tag">The encoded tag</param> /// <param name="tag">The encoded tag</param>
public void WriteTag(uint tag) public void WriteTag(uint tag) => WritingPrimitives.WriteTag(ref buffer, ref state, tag);
{
WritingPrimitives.WriteTag(ref buffer, ref state, tag);
}
/// <summary> /// <summary>
/// Writes the given single-byte tag. /// Writes the given single-byte tag.
/// </summary> /// </summary>
/// <param name="b1">The encoded tag</param> /// <param name="b1">The encoded tag</param>
public void WriteRawTag(byte b1) public void WriteRawTag(byte b1) => WritingPrimitives.WriteRawTag(ref buffer, ref state, b1);
{
WritingPrimitives.WriteRawTag(ref buffer, ref state, b1);
}
/// <summary> /// <summary>
/// Writes the given two-byte tag. /// Writes the given two-byte tag.
/// </summary> /// </summary>
/// <param name="b1">The first byte of the encoded tag</param> /// <param name="b1">The first byte of the encoded tag</param>
/// <param name="b2">The second byte of the encoded tag</param> /// <param name="b2">The second byte of the encoded tag</param>
public void WriteRawTag(byte b1, byte b2) public void WriteRawTag(byte b1, byte b2) => WritingPrimitives.WriteRawTag(ref buffer, ref state, b1, b2);
{
WritingPrimitives.WriteRawTag(ref buffer, ref state, b1, b2);
}
/// <summary> /// <summary>
/// Writes the given three-byte tag. /// Writes the given three-byte tag.
@ -318,10 +243,7 @@ namespace Google.Protobuf
/// <param name="b1">The first byte of the encoded tag</param> /// <param name="b1">The first byte of the encoded tag</param>
/// <param name="b2">The second byte of the encoded tag</param> /// <param name="b2">The second byte of the encoded tag</param>
/// <param name="b3">The third byte of the encoded tag</param> /// <param name="b3">The third byte of the encoded tag</param>
public void WriteRawTag(byte b1, byte b2, byte b3) public void WriteRawTag(byte b1, byte b2, byte b3) => WritingPrimitives.WriteRawTag(ref buffer, ref state, b1, b2, b3);
{
WritingPrimitives.WriteRawTag(ref buffer, ref state, b1, b2, b3);
}
/// <summary> /// <summary>
/// Writes the given four-byte tag. /// Writes the given four-byte tag.
@ -330,10 +252,7 @@ namespace Google.Protobuf
/// <param name="b2">The second byte of the encoded tag</param> /// <param name="b2">The second byte of the encoded tag</param>
/// <param name="b3">The third byte of the encoded tag</param> /// <param name="b3">The third byte of the encoded tag</param>
/// <param name="b4">The fourth byte of the encoded tag</param> /// <param name="b4">The fourth byte of the encoded tag</param>
public void WriteRawTag(byte b1, byte b2, byte b3, byte b4) public void WriteRawTag(byte b1, byte b2, byte b3, byte b4) => WritingPrimitives.WriteRawTag(ref buffer, ref state, b1, b2, b3, b4);
{
WritingPrimitives.WriteRawTag(ref buffer, ref state, b1, b2, b3, b4);
}
/// <summary> /// <summary>
/// Writes the given five-byte tag. /// Writes the given five-byte tag.
@ -343,20 +262,11 @@ namespace Google.Protobuf
/// <param name="b3">The third byte of the encoded tag</param> /// <param name="b3">The third byte of the encoded tag</param>
/// <param name="b4">The fourth byte of the encoded tag</param> /// <param name="b4">The fourth byte of the encoded tag</param>
/// <param name="b5">The fifth byte of the encoded tag</param> /// <param name="b5">The fifth byte of the encoded tag</param>
public void WriteRawTag(byte b1, byte b2, byte b3, byte b4, byte b5) public void WriteRawTag(byte b1, byte b2, byte b3, byte b4, byte b5) => WritingPrimitives.WriteRawTag(ref buffer, ref state, b1, b2, b3, b4, b5);
{
WritingPrimitives.WriteRawTag(ref buffer, ref state, b1, b2, b3, b4, b5);
}
internal void Flush() internal void Flush() => WriteBufferHelper.Flush(ref buffer, ref state);
{
WriteBufferHelper.Flush(ref buffer, ref state);
}
internal void CheckNoSpaceLeft() internal void CheckNoSpaceLeft() => WriteBufferHelper.CheckNoSpaceLeft(ref state);
{
WriteBufferHelper.CheckNoSpaceLeft(ref state);
}
internal void CopyStateTo(CodedOutputStream output) internal void CopyStateTo(CodedOutputStream output)
{ {

View File

@ -30,20 +30,8 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion #endregion
using System;
using System.Buffers;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using Google.Protobuf.Collections;
namespace Google.Protobuf namespace Google.Protobuf
{ {
// warning: this is a mutable struct, so it needs to be only passed as a ref! // warning: this is a mutable struct, so it needs to be only passed as a ref!
internal struct WriterInternalState internal struct WriterInternalState
{ {

View File

@ -32,7 +32,6 @@
using System; using System;
using System.Buffers.Binary; using System.Buffers.Binary;
using System.Diagnostics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
#if GOOGLE_PROTOBUF_SIMD #if GOOGLE_PROTOBUF_SIMD

View File

@ -30,9 +30,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion #endregion
using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices.ComTypes;
using System.Security; using System.Security;
namespace Google.Protobuf namespace Google.Protobuf