PROTOBUF_SYNC_PIPER
pull/10162/head^2
theodorerose 2 years ago
parent ae41e72dd3
commit 628a7e6fa4
  1. 29
      CHANGES.txt
  2. 2
      Protobuf.podspec
  3. 5
      csharp/.editorconfig
  4. 2
      csharp/Google.Protobuf.Tools.nuspec
  5. 11
      csharp/README.md
  6. 1
      csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
  7. 6
      csharp/src/AddressBook/AddPerson.cs
  8. 7
      csharp/src/Directory.Build.props
  9. 14
      csharp/src/Google.Protobuf.Benchmarks/BenchmarkDatasetConfig.cs
  10. 12
      csharp/src/Google.Protobuf.Benchmarks/ParseMessagesBenchmark.cs
  11. 2
      csharp/src/Google.Protobuf.Benchmarks/ParseRawPrimitivesBenchmark.cs
  12. 2
      csharp/src/Google.Protobuf.Benchmarks/Program.cs
  13. 3
      csharp/src/Google.Protobuf.Benchmarks/WriteRawPrimitivesBenchmark.cs
  14. 36
      csharp/src/Google.Protobuf.Conformance/Program.cs
  15. 2
      csharp/src/Google.Protobuf.Test.TestProtos/Google.Protobuf.Test.TestProtos.csproj
  16. 20
      csharp/src/Google.Protobuf.Test/ByteStringTest.cs
  17. 62
      csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs
  18. 20
      csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
  19. 82
      csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs
  20. 23
      csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs
  21. 1
      csharp/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs
  22. 1
      csharp/src/Google.Protobuf.Test/DeprecatedMemberTest.cs
  23. 34
      csharp/src/Google.Protobuf.Test/ExtensionSetTest.cs
  24. 1
      csharp/src/Google.Protobuf.Test/FieldMaskTreeTest.cs
  25. 40
      csharp/src/Google.Protobuf.Test/GeneratedMessageTest.Proto2.cs
  26. 20
      csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs
  27. 6
      csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
  28. 43
      csharp/src/Google.Protobuf.Test/JsonParserTest.cs
  29. 3
      csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs
  30. 8
      csharp/src/Google.Protobuf.Test/LegacyGeneratedCodeTest.cs
  31. 3
      csharp/src/Google.Protobuf.Test/MessageParsingHelpers.cs
  32. 2
      csharp/src/Google.Protobuf.Test/Proto3OptionalTest.cs
  33. 7
      csharp/src/Google.Protobuf.Test/ReadOnlySequenceFactory.cs
  34. 61
      csharp/src/Google.Protobuf.Test/RefStructCompatibilityTest.cs
  35. 5
      csharp/src/Google.Protobuf.Test/Reflection/CustomOptionsTest.cs
  36. 1
      csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs
  37. 43
      csharp/src/Google.Protobuf.Test/UnknownFieldSetTest.cs
  38. 1
      csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs
  39. 4
      csharp/src/Google.Protobuf/ByteString.cs
  40. 18
      csharp/src/Google.Protobuf/CodedInputStream.cs
  41. 2
      csharp/src/Google.Protobuf/CodedOutputStream.cs
  42. 1
      csharp/src/Google.Protobuf/Collections/Lists.cs
  43. 161
      csharp/src/Google.Protobuf/Collections/MapField.cs
  44. 66
      csharp/src/Google.Protobuf/Collections/RepeatedField.cs
  45. 2
      csharp/src/Google.Protobuf/Extension.cs
  46. 2
      csharp/src/Google.Protobuf/ExtensionRegistry.cs
  47. 27
      csharp/src/Google.Protobuf/ExtensionSet.cs
  48. 3
      csharp/src/Google.Protobuf/ExtensionValue.cs
  49. 88
      csharp/src/Google.Protobuf/FieldCodec.cs
  50. 3
      csharp/src/Google.Protobuf/FieldMaskTree.cs
  51. 2
      csharp/src/Google.Protobuf/Google.Protobuf.csproj
  52. 2
      csharp/src/Google.Protobuf/InvalidProtocolBufferException.cs
  53. 91
      csharp/src/Google.Protobuf/JsonFormatter.cs
  54. 26
      csharp/src/Google.Protobuf/JsonParser.cs
  55. 79
      csharp/src/Google.Protobuf/JsonToken.cs
  56. 63
      csharp/src/Google.Protobuf/JsonTokenizer.cs
  57. 41
      csharp/src/Google.Protobuf/LimitedInputStream.cs
  58. 56
      csharp/src/Google.Protobuf/MessageExtensions.cs
  59. 5
      csharp/src/Google.Protobuf/MessageParser.cs
  60. 9
      csharp/src/Google.Protobuf/ObjectIntPair.cs
  61. 118
      csharp/src/Google.Protobuf/ParseContext.cs
  62. 12
      csharp/src/Google.Protobuf/ParserInternalState.cs
  63. 3
      csharp/src/Google.Protobuf/ParsingPrimitives.cs
  64. 2
      csharp/src/Google.Protobuf/ParsingPrimitivesMessages.cs
  65. 8
      csharp/src/Google.Protobuf/ParsingPrimitivesWrappers.cs
  66. 25
      csharp/src/Google.Protobuf/Reflection/CustomOptions.cs
  67. 2
      csharp/src/Google.Protobuf/Reflection/DescriptorDeclaration.cs
  68. 35
      csharp/src/Google.Protobuf/Reflection/DescriptorPool.cs
  69. 21
      csharp/src/Google.Protobuf/Reflection/DescriptorValidationException.cs
  70. 43
      csharp/src/Google.Protobuf/Reflection/EnumDescriptor.cs
  71. 15
      csharp/src/Google.Protobuf/Reflection/EnumValueDescriptor.cs
  72. 3
      csharp/src/Google.Protobuf/Reflection/ExtensionCollection.cs
  73. 5
      csharp/src/Google.Protobuf/Reflection/FieldAccessorBase.cs
  74. 69
      csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs
  75. 34
      csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs
  76. 3
      csharp/src/Google.Protobuf/Reflection/GeneratedClrTypeInfo.cs
  77. 22
      csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs
  78. 32
      csharp/src/Google.Protobuf/Reflection/MethodDescriptor.cs
  79. 1
      csharp/src/Google.Protobuf/Reflection/OriginalNameAttribute.cs
  80. 27
      csharp/src/Google.Protobuf/Reflection/PackageDescriptor.cs
  81. 40
      csharp/src/Google.Protobuf/Reflection/ReflectionUtil.cs
  82. 1
      csharp/src/Google.Protobuf/Reflection/RepeatedFieldAccessor.cs
  83. 39
      csharp/src/Google.Protobuf/Reflection/ServiceDescriptor.cs
  84. 52
      csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs
  85. 4
      csharp/src/Google.Protobuf/Reflection/TypeRegistry.cs
  86. 15
      csharp/src/Google.Protobuf/UnknownField.cs
  87. 11
      csharp/src/Google.Protobuf/UnknownFieldSet.cs
  88. 2
      csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs
  89. 14
      csharp/src/Google.Protobuf/WellKnownTypes/TimestampPartial.cs
  90. 6
      csharp/src/Google.Protobuf/WellKnownTypes/ValuePartial.cs
  91. 1
      csharp/src/Google.Protobuf/WriteBufferHelper.cs
  92. 146
      csharp/src/Google.Protobuf/WriteContext.cs
  93. 12
      csharp/src/Google.Protobuf/WriterInternalState.cs
  94. 1
      csharp/src/Google.Protobuf/WritingPrimitives.cs
  95. 2
      csharp/src/Google.Protobuf/WritingPrimitivesMessages.cs
  96. 6
      java/README.md
  97. 2
      java/bom/pom.xml
  98. 2
      java/core/pom.xml
  99. 2
      java/kotlin-lite/pom.xml
  100. 2
      java/kotlin/pom.xml
  101. Some files were not shown because too many files have changed in this diff Show More

@ -1,22 +1,29 @@
Unreleased version
2022-06-27 Unreleased version
* Handle reflection for message splitting.
* make metadata fields lazy.
* Extend visibility of plugin library to upb
* Modernize conformance_cpp.cc.
* Don't request 64-byte alignment unless the toolchain supports it.
2022-06-27 version 21.2 (C++/Java/Python/PHP/Objective-C/C#/Ruby)
C++
* ArenaString improvements (fix alignment issue)
PHP
* API changes for OneOf (#10102)
2022-05-27 version 21.1 (C++/Java/Python/PHP/Objective-C/C#/Ruby)
C++
* cmake: Revert "Fix cmake install targets (#9822)" (#10060)
* cmake: Revert "Fix cmake install targets (#9822)" (#10060)
* Remove Abseil dependency from CMake build (#10056)
Python
* Update python wheel metadata with more information incl. required python version (#10058)
* Fix segmentation fault when instantiating field via repeated field assignment (#10066)
2022-05-25 version 21.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby)
C++
@ -1110,11 +1117,11 @@ mistakenly tagged at the wrong commit.
2020-02-14 version 3.11.4 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
C#
* Fix latest ArgumentException for C# extensions (#7188)
* Enforce recursion depth checking for unknown fields (#7210)
Ruby
* Fix wrappers with a zero value (#7195)
* Fix JSON serialization of 0/empty-valued wrapper types (#7198)
@ -1127,13 +1134,13 @@ mistakenly tagged at the wrong commit.
PHP
* Refactored ulong to zend_ulong for php7.4 compatibility (#7147)
* Call register_class before getClass from desc to fix segfault (#7077)
2019-12-10 version 3.11.2 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
PHP
* Make c extension portable for php 7.4 (#6968)
2019-12-02 version 3.11.1 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
@ -1209,7 +1216,7 @@ mistakenly tagged at the wrong commit.
* Support 32 bit values for ProtoStreamObjectWriter to Struct.
* Removed the internal-only header coded_stream_inl.h and the internal-only methods defined there.
* Enforced no SWIG wrapping of descriptor_database.h (other headers already had this restriction).
* Implementation of the equivalent of the MOMI parser for serialization. This removes one of the two serialization routines, by making the fast array serialization routine completely general. SerializeToCodedStream can now be implemented in terms of the much much faster array serialization. The array serialization regresses slightly, but when array serialization is not possible this wins big.
* Implementation of the equivalent of the MOMI parser for serialization. This removes one of the two serialization routines, by making the fast array serialization routine completely general. SerializeToCodedStream can now be implemented in terms of the much much faster array serialization. The array serialization regresses slightly, but when array serialization is not possible this wins big.
* Do not convert unknown field name to snake case to accurately report error.
* Fix a UBSAN warnings. (#6333)
* Add podspec for C++ (#6404)
@ -1243,7 +1250,7 @@ mistakenly tagged at the wrong commit.
* Change the parameter types of binaryReaderFn in ExtensionFieldBinaryInfo to (number, ?, ?).
* Create dates.ts and time_of_days.ts to mirror Java versions. This is a near-identical conversion of c.g.type.util.{Dates,TimeOfDays} respectively.
* Migrate moneys to TypeScript.
PHP
* Fix incorrect leap day for Timestamp (#6696)
* Initialize well known type values (#6713)
@ -1257,7 +1264,7 @@ mistakenly tagged at the wrong commit.
* Optimization for layout_init() (#6547)
* Fix for GC of Ruby map frames. (#6533)
* Fixed leap year handling by reworking upb_mktime() -> upb_timegm(). (#6695)
Objective C
* Remove OSReadLittle* due to alignment requirements (#6678)
* Don't use unions and instead use memcpy for the type swaps. (#6672)

@ -5,7 +5,7 @@
# dependent projects use the :git notation to refer to the library.
Pod::Spec.new do |s|
s.name = 'Protobuf'
s.version = '3.21.1'
s.version = '3.21.2'
s.summary = 'Protocol Buffers v.3 runtime library for Objective-C.'
s.homepage = 'https://github.com/protocolbuffers/protobuf'
s.license = 'BSD-3-Clause'

@ -14,4 +14,7 @@ tab_width = 4
# New line preferences
end_of_line = lf
insert_final_newline = false
trim_trailing_whitespace = true
trim_trailing_whitespace = true
[*.cs]
csharp_space_after_cast = true

@ -5,7 +5,7 @@
<title>Google Protocol Buffers tools</title>
<summary>Tools for Protocol Buffers - Google's data interchange format.</summary>
<description>See project site for more info.</description>
<version>3.21.1</version>
<version>3.21.2</version>
<authors>Google Inc.</authors>
<owners>protobuf-packages</owners>
<licenseUrl>https://github.com/protocolbuffers/protobuf/blob/main/LICENSE</licenseUrl>

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

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

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

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

@ -72,16 +72,14 @@ namespace Google.Protobuf.Benchmarks
private static byte[] LoadData(string resource)
{
using (var stream = typeof(GoogleMessageBenchmark).Assembly.GetManifestResourceStream($"Google.Protobuf.Benchmarks.{resource}"))
using var stream = typeof(GoogleMessageBenchmark).Assembly.GetManifestResourceStream($"Google.Protobuf.Benchmarks.{resource}");
if (stream == null)
{
if (stream == null)
{
throw new ArgumentException($"Unable to load embedded resource {resource}");
}
var copy = new MemoryStream();
stream.CopyTo(copy);
return copy.ToArray();
throw new ArgumentException($"Unable to load embedded resource {resource}");
}
var copy = new MemoryStream();
stream.CopyTo(copy);
return copy.ToArray();
}
public override string ToString() => Name;

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

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

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

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

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

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

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

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

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

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

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

@ -29,6 +29,7 @@
// (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 NUnit.Framework;
using System;
using System.Collections.Generic;

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

@ -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.Collections;
using Google.Protobuf.TestProtos.Proto2;
@ -72,7 +104,7 @@ namespace Google.Protobuf
message.SetExtension(OptionalStringExtension, "abcd");
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
ExtensionSet<TestAllExtensions> extensionSet = null;

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

@ -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 Proto2 = Google.Protobuf.TestProtos.Proto2;
using NUnit.Framework;
@ -387,11 +419,9 @@ namespace Google.Protobuf
var message = new TestAllExtensions();
message.SetExtension(UnittestExtensions.OptionalBoolExtension, true);
byte[] bytes = message.ToByteArray();
using (CodedInputStream input = new CodedInputStream(bytes))
{
var parsed = TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry() { UnittestExtensions.OptionalBoolExtension }).ParseFrom(input);
Assert.AreEqual(message, parsed);
}
using CodedInputStream input = new CodedInputStream(bytes);
var parsed = TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry() { UnittestExtensions.OptionalBoolExtension }).ParseFrom(input);
Assert.AreEqual(message, parsed);
}
}
}

@ -33,10 +33,7 @@
using System;
using System.IO;
using Google.Protobuf.TestProtos;
using Proto2 = Google.Protobuf.TestProtos.Proto2;
using NUnit.Framework;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Google.Protobuf.WellKnownTypes;
@ -658,9 +655,11 @@ namespace Google.Protobuf
[Test]
public void OneofSerialization_NonDefaultValue()
{
var message = new TestAllTypes();
message.OneofString = "this would take a bit of space";
message.OneofUint32 = 10;
var message = new TestAllTypes
{
OneofString = "this would take a bit of space",
OneofUint32 = 10
};
var bytes = message.ToByteArray();
Assert.AreEqual(3, bytes.Length); // 2 bytes for the tag + 1 for the value - no string!
@ -675,9 +674,11 @@ namespace Google.Protobuf
[Test]
public void OneofSerialization_DefaultValue()
{
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
var message = new TestAllTypes
{
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();
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]
public void ExtraEndGroupThrows()
{
var message = SampleMessages.CreateFullTestAllTypes();
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);

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

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

@ -29,6 +29,7 @@
// (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 NUnit.Framework;
using System;
using System.IO;
@ -126,7 +127,7 @@ namespace Google.Protobuf
tokenizer.PushBack(token);
Assert.AreEqual(0, tokenizer.ObjectDepth);
// Read the same token again, and get back to depth 1
token = tokenizer.Next();
_ = tokenizer.Next();
Assert.AreEqual(1, tokenizer.ObjectDepth);
// Now the same in reverse, with EndObject

@ -29,14 +29,12 @@
// (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;
using Google.Protobuf.Reflection;
using System.Buffers;
using pb = global::Google.Protobuf;
using pbr = global::Google.Protobuf.Reflection;
using pb = Google.Protobuf;
using pbr = Google.Protobuf.Reflection;
using NUnit.Framework;
using System.IO;
using System;
using Google.Protobuf.Buffers;
namespace Google.Protobuf

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

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

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

@ -77,43 +77,42 @@ namespace Google.Protobuf
/// <param name="args"></param>
/// <param name="workingDirectory"></param>
private void RunOldCsharpCompilerAndCheckSuccess(string args, string workingDirectory)
{
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;
{
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) =>
process.OutputDataReceived += (sender, e) =>
{
if (e.Data != null)
{
if (e.Data != null)
{
Console.WriteLine(e.Data);
}
};
process.ErrorDataReceived += (sender, e) =>
Console.WriteLine(e.Data);
}
};
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.BeginOutputReadLine();
process.BeginErrorReadLine();
process.BeginOutputReadLine();
process.WaitForExit();
Assert.AreEqual(0, process.ExitCode);
}
process.WaitForExit();
Assert.AreEqual(0, process.ExitCode);
}
}
}

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

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

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

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

@ -189,7 +189,7 @@ namespace Google.Protobuf
/// <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>
/// <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));
return ByteStringAsync.FromStreamAsyncCore(stream, cancellationToken);
@ -340,7 +340,7 @@ namespace Google.Protobuf
{
return true;
}
if (ReferenceEquals(lhs, null) || ReferenceEquals(rhs, null))
if (lhs is null || rhs is null)
{
return false;
}

@ -32,10 +32,7 @@
using Google.Protobuf.Collections;
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
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>
/// Reads a fixed size of bytes from the input.
/// </summary>

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

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

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

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

@ -77,7 +77,7 @@ namespace Google.Protobuf
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);

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

@ -61,8 +61,7 @@ namespace Google.Protobuf
/// </summary>
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 value))
if (TryGetValue(ref set, extension, out IExtensionValue value))
{
// 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.
@ -98,7 +97,7 @@ namespace Google.Protobuf
}
}
}
else
else
{
return extension.DefaultValue;
}
@ -109,8 +108,7 @@ namespace Google.Protobuf
/// </summary>
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 value))
if (TryGetValue(ref set, extension, out IExtensionValue value))
{
if (value is RepeatedExtensionValue<TValue> extensionValue)
{
@ -132,7 +130,7 @@ namespace Google.Protobuf
}
}
}
else
else
{
return null;
}
@ -193,8 +191,7 @@ namespace Google.Protobuf
/// </summary>
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 value);
return TryGetValue(ref set, extension, out IExtensionValue _);
}
/// <summary>
@ -252,20 +249,18 @@ namespace Google.Protobuf
/// </summary>
public static bool TryMergeFieldFrom<TTarget>(ref ExtensionSet<TTarget> set, ref ParseContext ctx) where TTarget : IExtendableMessage<TTarget>
{
Extension extension;
int lastFieldNumber = WireFormat.GetTagFieldNumber(ctx.LastTag);
IExtensionValue extensionValue;
if (set != null && set.ValuesByNumber.TryGetValue(lastFieldNumber, out extensionValue))
if (set != null && set.ValuesByNumber.TryGetValue(lastFieldNumber, out IExtensionValue extensionValue))
{
extensionValue.MergeFrom(ref ctx);
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();
value.MergeFrom(ref ctx);
set = (set ?? new ExtensionSet<TTarget>());
set ??= new ExtensionSet<TTarget>();
set.ValuesByNumber.Add(extension.FieldNumber, value);
return true;
}
@ -290,8 +285,7 @@ namespace Google.Protobuf
}
foreach (var pair in second.ValuesByNumber)
{
IExtensionValue value;
if (first.ValuesByNumber.TryGetValue(pair.Key, out value))
if (first.ValuesByNumber.TryGetValue(pair.Key, out IExtensionValue value))
{
value.MergeFrom(pair.Value);
}
@ -365,8 +359,7 @@ namespace Google.Protobuf
}
foreach (var pair in ValuesByNumber)
{
IExtensionValue secondValue;
if (!otherSet.ValuesByNumber.TryGetValue(pair.Key, out secondValue))
if (!otherSet.ValuesByNumber.TryGetValue(pair.Key, out IExtensionValue secondValue))
{
return false;
}

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

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

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

@ -4,7 +4,7 @@
<Description>C# runtime library for Protocol Buffers - Google's data interchange format.</Description>
<Copyright>Copyright 2015, Google Inc.</Copyright>
<AssemblyTitle>Google Protocol Buffers</AssemblyTitle>
<VersionPrefix>3.21.1</VersionPrefix>
<VersionPrefix>3.21.2</VersionPrefix>
<!-- C# 7.2 is required for Span/BufferWriter/ReadOnlySequence -->
<LangVersion>7.2</LangVersion>
<Authors>Google Inc.</Authors>

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

@ -62,7 +62,6 @@ namespace Google.Protobuf
internal const string AnyTypeUrlField = "@type";
internal const string AnyDiagnosticValueField = "@value";
internal const string AnyWellKnownTypeValueField = "value";
private const string TypeUrlPrefix = "type.googleapis.com";
private const string NameValueSeparator = ": ";
private const string PropertySeparator = ", ";
@ -202,8 +201,7 @@ namespace Google.Protobuf
}
if (DiagnosticOnly)
{
ICustomDiagnosticMessage customDiagnosticMessage = message as ICustomDiagnosticMessage;
if (customDiagnosticMessage != null)
if (message is ICustomDiagnosticMessage customDiagnosticMessage)
{
writer.Write(customDiagnosticMessage.ToDiagnosticString());
return;
@ -320,39 +318,20 @@ namespace Google.Protobuf
IList list = (IList) value;
return list.Count == 0;
}
switch (descriptor.FieldType)
{
case FieldType.Bool:
return (bool) value == false;
case FieldType.Bytes:
return (ByteString) value == ByteString.Empty;
case FieldType.String:
return (string) value == "";
case FieldType.Double:
return (double) value == 0.0;
case FieldType.SInt32:
case FieldType.Int32:
case FieldType.SFixed32:
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");
}
return descriptor.FieldType switch
{
FieldType.Bool => (bool) value == false,
FieldType.Bytes => (ByteString) value == ByteString.Empty,
FieldType.String => (string) value == "",
FieldType.Double => (double) value == 0.0,
FieldType.SInt32 or FieldType.Int32 or FieldType.SFixed32 or FieldType.Enum => (int) value == 0,
FieldType.Fixed32 or FieldType.UInt32 => (uint) value == 0,
FieldType.Fixed64 or FieldType.UInt64 => (ulong) value == 0,
FieldType.SFixed64 or FieldType.Int64 or FieldType.SInt64 => (long) value == 0,
FieldType.Float => (float) value == 0f,
FieldType.Message or FieldType.Group => value == null,
_ => throw new ArgumentException("Invalid field type"),
};
}
/// <summary>
@ -369,28 +348,28 @@ namespace Google.Protobuf
{
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
writer.Write('"');
writer.Write(((ByteString)value).ToBase64());
writer.Write(byteString.ToBase64());
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)
{
@ -437,9 +416,9 @@ namespace Google.Protobuf
writer.Write(text);
}
}
else if (value is IMessage)
else if (value is IMessage message)
{
Format((IMessage)value, writer);
Format(message, writer);
}
else
{
@ -469,9 +448,8 @@ namespace Google.Protobuf
// WriteValue will do the right thing.)
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);
}
WriteValue(writer, value);
@ -679,15 +657,15 @@ namespace Google.Protobuf
writer.Write(PropertySeparator);
}
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);
}
@ -916,9 +894,8 @@ namespace Google.Protobuf
}
}
string originalName;
// 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;
}

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

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

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

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

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

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

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

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

@ -30,20 +30,8 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#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
{
// warning: this is a mutable struct, so it needs to be only passed as a ref!
internal struct ParserInternalState
{

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

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

@ -31,15 +31,7 @@
#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
{

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

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

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

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

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

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

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

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

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

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

@ -29,6 +29,7 @@
// (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.Diagnostics.CodeAnalysis;
@ -57,7 +58,7 @@ namespace Google.Protobuf.Reflection
/// Irrelevant for file descriptors; the CLR type for the message for message descriptors.
/// </summary>
[DynamicallyAccessedMembers(MessageAccessibility)]
public Type ClrType { get; private set; }
public Type ClrType { get; }
/// <summary>
/// Irrelevant for file descriptors; the parser for message descriptors.

@ -130,20 +130,14 @@ namespace Google.Protobuf.Reflection
/// </summary>
public override string Name => Proto.Name;
internal override IReadOnlyList<DescriptorBase> GetNestedDescriptorListForField(int fieldNumber)
{
switch (fieldNumber)
internal override IReadOnlyList<DescriptorBase> GetNestedDescriptorListForField(int fieldNumber) =>
fieldNumber switch
{
case DescriptorProto.FieldFieldNumber:
return (IReadOnlyList<DescriptorBase>) fieldsInDeclarationOrder;
case DescriptorProto.NestedTypeFieldNumber:
return (IReadOnlyList<DescriptorBase>) NestedTypes;
case DescriptorProto.EnumTypeFieldNumber:
return (IReadOnlyList<DescriptorBase>) EnumTypes;
default:
return null;
}
}
DescriptorProto.FieldFieldNumber => (IReadOnlyList<DescriptorBase>)fieldsInDeclarationOrder,
DescriptorProto.NestedTypeFieldNumber => (IReadOnlyList<DescriptorBase>)NestedTypes,
DescriptorProto.EnumTypeFieldNumber => (IReadOnlyList<DescriptorBase>)EnumTypes,
_ => null,
};
internal DescriptorProto Proto { get; }
@ -272,7 +266,7 @@ namespace Google.Protobuf.Reflection
/// </summary>
/// <param name="name">The unqualified name of the field (e.g. "foo").</param>
/// <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>
/// Finds a field by field number.

@ -40,35 +40,31 @@ namespace Google.Protobuf.Reflection
/// </summary>
public sealed class MethodDescriptor : DescriptorBase
{
private readonly MethodDescriptorProto proto;
private readonly ServiceDescriptor service;
private MessageDescriptor inputType;
private MessageDescriptor outputType;
/// <value>
/// The service this method belongs to.
/// </value>
public ServiceDescriptor Service { get { return service; } }
public ServiceDescriptor Service { get; }
/// <value>
/// The method's input type.
/// </value>
public MessageDescriptor InputType { get { return inputType; } }
public MessageDescriptor InputType { get; private set; }
/// <value>
/// The method's input type.
/// </value>
public MessageDescriptor OutputType { get { return outputType; } }
public MessageDescriptor OutputType { get; private set; }
/// <value>
/// Indicates if client streams multiple requests.
/// </value>
public bool IsClientStreaming { get { return proto.ClientStreaming; } }
public bool IsClientStreaming => Proto.ClientStreaming;
/// <value>
/// Indicates if server streams multiple responses.
/// </value>
public bool IsServerStreaming { get { return proto.ServerStreaming; } }
public bool IsServerStreaming => Proto.ServerStreaming;
/// <summary>
/// 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)
{
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>
@ -107,12 +103,12 @@ namespace Google.Protobuf.Reflection
ServiceDescriptor parent, int index)
: base(file, parent.FullName + "." + proto.Name, index)
{
this.proto = proto;
service = parent;
Proto = proto;
Service = parent;
file.DescriptorPool.AddSymbol(this);
}
internal MethodDescriptorProto Proto { get { return proto; } }
internal MethodDescriptorProto Proto { get; private set; }
/// <summary>
/// Returns a clone of the underlying <see cref="MethodDescriptorProto"/> describing this method.
@ -125,23 +121,23 @@ namespace Google.Protobuf.Reflection
/// <summary>
/// The brief name of the descriptor's target.
/// </summary>
public override string Name { get { return proto.Name; } }
public override string Name => Proto.Name;
internal void CrossLink()
{
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.");
}
inputType = (MessageDescriptor) lookup;
InputType = inpoutType;
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.");
}
outputType = (MessageDescriptor) lookup;
OutputType = outputType;
}
}
}

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

@ -39,30 +39,15 @@ namespace Google.Protobuf.Reflection
/// </summary>
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)
{
this.file = file;
this.fullName = fullName;
this.name = name;
File = file;
FullName = fullName;
Name = name;
}
public string Name
{
get { return name; }
}
public string FullName
{
get { return fullName; }
}
public FileDescriptor File
{
get { return file; }
}
public string Name { get; }
public string FullName { get; }
public FileDescriptor File { get; }
}
}

@ -221,20 +221,18 @@ namespace Google.Protobuf.Reflection
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");
}
T1 extensionMessage = (T1)message;
if (extension is Extension<T1, T3>)
if (extension is Extension<T1, T3> ext13)
{
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
{
@ -244,16 +242,14 @@ namespace Google.Protobuf.Reflection
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");
}
T1 extensionMessage = (T1)message;
if (extension is Extension<T1, T3>)
if (extension is Extension<T1, T3> ext13)
{
return extensionMessage.HasExtension(extension as Extension<T1, T3>);
return extensionMessage.HasExtension(ext13);
}
else if (extension is RepeatedExtension<T1, T3>)
{
@ -267,16 +263,14 @@ namespace Google.Protobuf.Reflection
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");
}
T1 extensionMessage = (T1)message;
if (extension is Extension<T1, T3>)
if (extension is Extension<T1, T3> ext13)
{
extensionMessage.SetExtension(extension as Extension<T1, T3>, (T3)value);
extensionMessage.SetExtension(ext13, (T3)value);
}
else if (extension is RepeatedExtension<T1, T3>)
{
@ -290,20 +284,18 @@ namespace Google.Protobuf.Reflection
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");
}
T1 extensionMessage = (T1)message;
if (extension is Extension<T1, T3>)
if (extension is Extension<T1, T3> ext13)
{
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
{

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

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

@ -31,7 +31,6 @@
#endregion
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using Google.Protobuf.Compatibility;
@ -108,7 +107,7 @@ namespace Google.Protobuf.Reflection
// Primitive proto3 fields without the optional keyword, which aren't in oneofs.
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.
object defaultValue = GetDefaultValue(descriptor);
@ -116,42 +115,21 @@ namespace Google.Protobuf.Reflection
}
}
private static object GetDefaultValue(FieldDescriptor descriptor)
{
switch (descriptor.FieldType)
private static object GetDefaultValue(FieldDescriptor descriptor) =>
descriptor.FieldType switch
{
case FieldType.Bool:
return false;
case FieldType.Bytes:
return ByteString.Empty;
case FieldType.String:
return "";
case FieldType.Double:
return 0.0;
case FieldType.SInt32:
case FieldType.Int32:
case FieldType.SFixed32:
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");
}
}
FieldType.Bool => false,
FieldType.Bytes => ByteString.Empty,
FieldType.String => "",
FieldType.Double => 0.0,
FieldType.SInt32 or FieldType.Int32 or FieldType.SFixed32 or FieldType.Enum => 0,
FieldType.Fixed32 or FieldType.UInt32 => (uint)0,
FieldType.Fixed64 or FieldType.UInt64 => 0UL,
FieldType.SFixed64 or FieldType.Int64 or FieldType.SInt64 => 0L,
FieldType.Float => 0f,
FieldType.Message or FieldType.Group => null,
_ => throw new ArgumentException("Invalid field type"),
};
public override void Clear(IMessage message) => clearDelegate(message);
public override bool HasValue(IMessage message) => hasDelegate(message);

@ -29,6 +29,7 @@
// (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.Collections.Generic;
using System.Linq;
@ -60,9 +61,8 @@ namespace Google.Protobuf.Reflection
/// if there is no such message descriptor.</returns>
public MessageDescriptor Find(string fullName)
{
MessageDescriptor ret;
// 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;
}

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

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

@ -112,7 +112,7 @@ namespace Google.Protobuf.WellKnownTypes
T target = new T();
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;
}
target.MergeFrom(Value);

@ -59,8 +59,8 @@ namespace Google.Protobuf.WellKnownTypes
/// <returns>The difference between the two specified timestamps.</returns>
public static Duration operator -(Timestamp lhs, Timestamp rhs)
{
ProtoPreconditions.CheckNotNull(lhs, "lhs");
ProtoPreconditions.CheckNotNull(rhs, "rhs");
ProtoPreconditions.CheckNotNull(lhs, nameof(lhs));
ProtoPreconditions.CheckNotNull(rhs, nameof(rhs));
checked
{
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>
public static Timestamp operator +(Timestamp lhs, Duration rhs)
{
ProtoPreconditions.CheckNotNull(lhs, "lhs");
ProtoPreconditions.CheckNotNull(rhs, "rhs");
ProtoPreconditions.CheckNotNull(lhs, nameof(lhs));
ProtoPreconditions.CheckNotNull(rhs, nameof(rhs));
checked
{
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>
public static Timestamp operator -(Timestamp lhs, Duration rhs)
{
ProtoPreconditions.CheckNotNull(lhs, "lhs");
ProtoPreconditions.CheckNotNull(rhs, "rhs");
ProtoPreconditions.CheckNotNull(lhs, nameof(lhs));
ProtoPreconditions.CheckNotNull(rhs, nameof(rhs));
checked
{
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>
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>

@ -41,7 +41,7 @@ namespace Google.Protobuf.WellKnownTypes
/// <returns>A newly-created Value message with the given value.</returns>
public static Value ForString(string value)
{
ProtoPreconditions.CheckNotNull(value, "value");
ProtoPreconditions.CheckNotNull(value, nameof(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>
public static Value ForList(params Value[] values)
{
ProtoPreconditions.CheckNotNull(values, "values");
ProtoPreconditions.CheckNotNull(values, nameof(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>
public static Value ForStruct(Struct value)
{
ProtoPreconditions.CheckNotNull(value, "value");
ProtoPreconditions.CheckNotNull(value, nameof(value));
return new Value { StructValue = value };
}
}

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

@ -32,14 +32,8 @@
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
{
@ -101,166 +95,112 @@ namespace Google.Protobuf
/// Writes a double field value, without a tag.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteDouble(double value)
{
WritingPrimitives.WriteDouble(ref buffer, ref state, value);
}
public void WriteDouble(double value) => WritingPrimitives.WriteDouble(ref buffer, ref state, value);
/// <summary>
/// Writes a float field value, without a tag.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteFloat(float value)
{
WritingPrimitives.WriteFloat(ref buffer, ref state, value);
}
public void WriteFloat(float value) => WritingPrimitives.WriteFloat(ref buffer, ref state, value);
/// <summary>
/// Writes a uint64 field value, without a tag.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteUInt64(ulong value)
{
WritingPrimitives.WriteUInt64(ref buffer, ref state, value);
}
public void WriteUInt64(ulong value) => WritingPrimitives.WriteUInt64(ref buffer, ref state, value);
/// <summary>
/// Writes an int64 field value, without a tag.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteInt64(long value)
{
WritingPrimitives.WriteInt64(ref buffer, ref state, value);
}
public void WriteInt64(long value) => WritingPrimitives.WriteInt64(ref buffer, ref state, value);
/// <summary>
/// Writes an int32 field value, without a tag.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteInt32(int value)
{
WritingPrimitives.WriteInt32(ref buffer, ref state, value);
}
public void WriteInt32(int value) => WritingPrimitives.WriteInt32(ref buffer, ref state, value);
/// <summary>
/// Writes a fixed64 field value, without a tag.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteFixed64(ulong value)
{
WritingPrimitives.WriteFixed64(ref buffer, ref state, value);
}
public void WriteFixed64(ulong value) => WritingPrimitives.WriteFixed64(ref buffer, ref state, value);
/// <summary>
/// Writes a fixed32 field value, without a tag.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteFixed32(uint value)
{
WritingPrimitives.WriteFixed32(ref buffer, ref state, value);
}
public void WriteFixed32(uint value) => WritingPrimitives.WriteFixed32(ref buffer, ref state, value);
/// <summary>
/// Writes a bool field value, without a tag.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteBool(bool value)
{
WritingPrimitives.WriteBool(ref buffer, ref state, value);
}
public void WriteBool(bool value) => WritingPrimitives.WriteBool(ref buffer, ref state, value);
/// <summary>
/// Writes a string field value, without a tag.
/// The data is length-prefixed.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteString(string value)
{
WritingPrimitives.WriteString(ref buffer, ref state, value);
}
public void WriteString(string value) => WritingPrimitives.WriteString(ref buffer, ref state, value);
/// <summary>
/// Writes a message, without a tag.
/// The data is length-prefixed.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteMessage(IMessage value)
{
WritingPrimitivesMessages.WriteMessage(ref this, value);
}
public void WriteMessage(IMessage value) => WritingPrimitivesMessages.WriteMessage(ref this, value);
/// <summary>
/// Writes a group, without a tag, to the stream.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteGroup(IMessage value)
{
WritingPrimitivesMessages.WriteGroup(ref this, value);
}
public void WriteGroup(IMessage value) => WritingPrimitivesMessages.WriteGroup(ref this, value);
/// <summary>
/// Write a byte string, without a tag, to the stream.
/// The data is length-prefixed.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteBytes(ByteString value)
{
WritingPrimitives.WriteBytes(ref buffer, ref state, value);
}
public void WriteBytes(ByteString value) => WritingPrimitives.WriteBytes(ref buffer, ref state, value);
/// <summary>
/// Writes a uint32 value, without a tag.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteUInt32(uint value)
{
WritingPrimitives.WriteUInt32(ref buffer, ref state, value);
}
public void WriteUInt32(uint value) => WritingPrimitives.WriteUInt32(ref buffer, ref state, value);
/// <summary>
/// Writes an enum value, without a tag.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteEnum(int value)
{
WritingPrimitives.WriteEnum(ref buffer, ref state, value);
}
public void WriteEnum(int value) => WritingPrimitives.WriteEnum(ref buffer, ref state, value);
/// <summary>
/// Writes an sfixed32 value, without a tag.
/// </summary>
/// <param name="value">The value to write.</param>
public void WriteSFixed32(int value)
{
WritingPrimitives.WriteSFixed32(ref buffer, ref state, value);
}
public void WriteSFixed32(int value) => WritingPrimitives.WriteSFixed32(ref buffer, ref state, value);
/// <summary>
/// Writes an sfixed64 value, without a tag.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteSFixed64(long value)
{
WritingPrimitives.WriteSFixed64(ref buffer, ref state, value);
}
public void WriteSFixed64(long value) => WritingPrimitives.WriteSFixed64(ref buffer, ref state, value);
/// <summary>
/// Writes an sint32 value, without a tag.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteSInt32(int value)
{
WritingPrimitives.WriteSInt32(ref buffer, ref state, value);
}
public void WriteSInt32(int value) => WritingPrimitives.WriteSInt32(ref buffer, ref state, value);
/// <summary>
/// Writes an sint64 value, without a tag.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteSInt64(long value)
{
WritingPrimitives.WriteSInt64(ref buffer, ref state, value);
}
public void WriteSInt64(long value) => WritingPrimitives.WriteSInt64(ref buffer, ref state, value);
/// <summary>
/// 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.
/// </remarks>
/// <param name="length">Length value, in bytes.</param>
public void WriteLength(int length)
{
WritingPrimitives.WriteLength(ref buffer, ref state, length);
}
public void WriteLength(int length) => WritingPrimitives.WriteLength(ref buffer, ref state, length);
/// <summary>
/// Encodes and writes a tag.
/// </summary>
/// <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>
public void WriteTag(int fieldNumber, WireFormat.WireType type)
{
WritingPrimitives.WriteTag(ref buffer, ref state, fieldNumber, type);
}
public void WriteTag(int fieldNumber, WireFormat.WireType type) => WritingPrimitives.WriteTag(ref buffer, ref state, fieldNumber, type);
/// <summary>
/// Writes an already-encoded tag.
/// </summary>
/// <param name="tag">The encoded tag</param>
public void WriteTag(uint tag)
{
WritingPrimitives.WriteTag(ref buffer, ref state, tag);
}
public void WriteTag(uint tag) => WritingPrimitives.WriteTag(ref buffer, ref state, tag);
/// <summary>
/// Writes the given single-byte tag.
/// </summary>
/// <param name="b1">The encoded tag</param>
public void WriteRawTag(byte b1)
{
WritingPrimitives.WriteRawTag(ref buffer, ref state, b1);
}
public void WriteRawTag(byte b1) => WritingPrimitives.WriteRawTag(ref buffer, ref state, b1);
/// <summary>
/// Writes the given two-byte tag.
/// </summary>
/// <param name="b1">The first byte of the encoded tag</param>
/// <param name="b2">The second byte of the encoded tag</param>
public void WriteRawTag(byte b1, byte b2)
{
WritingPrimitives.WriteRawTag(ref buffer, ref state, b1, b2);
}
public void WriteRawTag(byte b1, byte b2) => WritingPrimitives.WriteRawTag(ref buffer, ref state, b1, b2);
/// <summary>
/// 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="b2">The second 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)
{
WritingPrimitives.WriteRawTag(ref buffer, ref state, b1, b2, b3);
}
public void WriteRawTag(byte b1, byte b2, byte b3) => WritingPrimitives.WriteRawTag(ref buffer, ref state, b1, b2, b3);
/// <summary>
/// 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="b3">The third 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)
{
WritingPrimitives.WriteRawTag(ref buffer, ref state, b1, b2, b3, b4);
}
public void WriteRawTag(byte b1, byte b2, byte b3, byte b4) => WritingPrimitives.WriteRawTag(ref buffer, ref state, b1, b2, b3, b4);
/// <summary>
/// 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="b4">The fourth 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)
{
WritingPrimitives.WriteRawTag(ref buffer, ref state, b1, b2, b3, b4, 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);
internal void Flush()
{
WriteBufferHelper.Flush(ref buffer, ref state);
}
internal void Flush() => WriteBufferHelper.Flush(ref buffer, ref state);
internal void CheckNoSpaceLeft()
{
WriteBufferHelper.CheckNoSpaceLeft(ref state);
}
internal void CheckNoSpaceLeft() => WriteBufferHelper.CheckNoSpaceLeft(ref state);
internal void CopyStateTo(CodedOutputStream output)
{

@ -30,20 +30,8 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#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
{
// warning: this is a mutable struct, so it needs to be only passed as a ref!
internal struct WriterInternalState
{

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

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

@ -23,7 +23,7 @@ If you are using Maven, use the following:
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.21.1</version>
<version>3.21.2</version>
</dependency>
```
@ -37,7 +37,7 @@ protobuf-java-util package:
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>3.21.1</version>
<version>3.21.2</version>
</dependency>
```
@ -45,7 +45,7 @@ protobuf-java-util package:
If you are using Gradle, add the following to your `build.gradle` file's dependencies:
```
implementation 'com.google.protobuf:protobuf-java:3.21.1'
implementation 'com.google.protobuf:protobuf-java:3.21.2'
```
Again, be sure to check that the version number matches (or is newer than) the version number of protoc that you are using.

@ -4,7 +4,7 @@
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-bom</artifactId>
<version>3.21.1</version>
<version>3.21.2</version>
<packaging>pom</packaging>
<name>Protocol Buffers [BOM]</name>

@ -4,7 +4,7 @@
<parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-parent</artifactId>
<version>3.21.1</version>
<version>3.21.2</version>
</parent>
<artifactId>protobuf-java</artifactId>

@ -4,7 +4,7 @@
<parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-parent</artifactId>
<version>3.21.1</version>
<version>3.21.2</version>
</parent>
<artifactId>protobuf-kotlin-lite</artifactId>

@ -4,7 +4,7 @@
<parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-parent</artifactId>
<version>3.21.1</version>
<version>3.21.2</version>
</parent>
<artifactId>protobuf-kotlin</artifactId>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save