Merge pull request #7576 from jtattermusch/protobuf_buffer_serialization

New Span-based serialization logic (followup for #7351)
pull/7660/head
Jan Tattermusch 5 years ago committed by GitHub
commit 206b973afd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      Makefile.am
  2. 64
      csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
  3. 22
      csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/FieldCodecTest.cs
  4. 65
      csharp/src/AddressBook/Addressbook.cs
  5. 267
      csharp/src/Google.Protobuf.Benchmarks/BenchmarkMessage1Proto3.cs
  6. 22
      csharp/src/Google.Protobuf.Benchmarks/Benchmarks.cs
  7. 6
      csharp/src/Google.Protobuf.Benchmarks/ParseMessagesBenchmark.cs
  8. 43
      csharp/src/Google.Protobuf.Benchmarks/ParseRawPrimitivesBenchmark.cs
  9. 801
      csharp/src/Google.Protobuf.Benchmarks/WrapperBenchmarkMessages.cs
  10. 198
      csharp/src/Google.Protobuf.Benchmarks/WriteMessagesBenchmark.cs
  11. 467
      csharp/src/Google.Protobuf.Benchmarks/WriteRawPrimitivesBenchmark.cs
  12. 125
      csharp/src/Google.Protobuf.Conformance/Conformance.cs
  13. 132
      csharp/src/Google.Protobuf.Test.TestProtos/MapUnittestProto3.cs
  14. 446
      csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto2.cs
  15. 386
      csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto3.cs
  16. 2557
      csharp/src/Google.Protobuf.Test.TestProtos/Unittest.cs
  17. 335
      csharp/src/Google.Protobuf.Test.TestProtos/UnittestCustomOptionsProto3.cs
  18. 17
      csharp/src/Google.Protobuf.Test.TestProtos/UnittestImport.cs
  19. 17
      csharp/src/Google.Protobuf.Test.TestProtos/UnittestImportProto3.cs
  20. 17
      csharp/src/Google.Protobuf.Test.TestProtos/UnittestImportPublic.cs
  21. 17
      csharp/src/Google.Protobuf.Test.TestProtos/UnittestImportPublicProto3.cs
  22. 13
      csharp/src/Google.Protobuf.Test.TestProtos/UnittestIssue6936B.cs
  23. 17
      csharp/src/Google.Protobuf.Test.TestProtos/UnittestIssue6936C.cs
  24. 254
      csharp/src/Google.Protobuf.Test.TestProtos/UnittestIssues.cs
  25. 833
      csharp/src/Google.Protobuf.Test.TestProtos/UnittestProto3.cs
  26. 114
      csharp/src/Google.Protobuf.Test.TestProtos/UnittestProto3Optional.cs
  27. 24
      csharp/src/Google.Protobuf.Test.TestProtos/UnittestSelfreferentialOptions.cs
  28. 218
      csharp/src/Google.Protobuf.Test.TestProtos/UnittestWellKnownTypes.cs
  29. 225
      csharp/src/Google.Protobuf.Test/Buffers/ArrayBufferWriter.cs
  30. 186
      csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
  31. 2
      csharp/src/Google.Protobuf.Test/ExtensionSetTest.cs
  32. 24
      csharp/src/Google.Protobuf.Test/FieldCodecTest.cs
  33. 6
      csharp/src/Google.Protobuf.Test/GeneratedMessageTest.Proto2.cs
  34. 14
      csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs
  35. 101
      csharp/src/Google.Protobuf.Test/LegacyGeneratedCodeTest.cs
  36. 42
      csharp/src/Google.Protobuf.Test/MessageParsingHelpers.cs
  37. 10
      csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
  38. 6
      csharp/src/Google.Protobuf/CodedOutputStream.ComputeSize.cs
  39. 415
      csharp/src/Google.Protobuf/CodedOutputStream.cs
  40. 35
      csharp/src/Google.Protobuf/Collections/MapField.cs
  41. 36
      csharp/src/Google.Protobuf/Collections/RepeatedField.cs
  42. 21
      csharp/src/Google.Protobuf/ExtensionSet.cs
  43. 19
      csharp/src/Google.Protobuf/ExtensionValue.cs
  44. 90
      csharp/src/Google.Protobuf/FieldCodec.cs
  45. 8
      csharp/src/Google.Protobuf/IBufferMessage.cs
  46. 36
      csharp/src/Google.Protobuf/MessageExtensions.cs
  47. 2
      csharp/src/Google.Protobuf/ParserInternalState.cs
  48. 6
      csharp/src/Google.Protobuf/ParsingPrimitives.cs
  49. 794
      csharp/src/Google.Protobuf/Reflection/Descriptor.cs
  50. 6
      csharp/src/Google.Protobuf/UnknownField.cs
  51. 19
      csharp/src/Google.Protobuf/UnknownFieldSet.cs
  52. 21
      csharp/src/Google.Protobuf/WellKnownTypes/Any.cs
  53. 91
      csharp/src/Google.Protobuf/WellKnownTypes/Api.cs
  54. 21
      csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs
  55. 13
      csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs
  56. 14
      csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs
  57. 17
      csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs
  58. 65
      csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs
  59. 21
      csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs
  60. 148
      csharp/src/Google.Protobuf/WellKnownTypes/Type.cs
  61. 153
      csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs
  62. 166
      csharp/src/Google.Protobuf/WriteBufferHelper.cs
  63. 371
      csharp/src/Google.Protobuf/WriteContext.cs
  64. 62
      csharp/src/Google.Protobuf/WriterInternalState.cs
  65. 638
      csharp/src/Google.Protobuf/WritingPrimitives.cs
  66. 112
      csharp/src/Google.Protobuf/WritingPrimitivesMessages.cs
  67. 6
      src/google/protobuf/compiler/csharp/csharp_field_base.cc
  68. 1
      src/google/protobuf/compiler/csharp/csharp_field_base.h
  69. 8
      src/google/protobuf/compiler/csharp/csharp_map_field.cc
  70. 1
      src/google/protobuf/compiler/csharp/csharp_map_field.h
  71. 75
      src/google/protobuf/compiler/csharp/csharp_message.cc
  72. 1
      src/google/protobuf/compiler/csharp/csharp_message.h
  73. 8
      src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc
  74. 1
      src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h
  75. 8
      src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc
  76. 1
      src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h
  77. 8
      src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc
  78. 1
      src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h
  79. 28
      src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc
  80. 2
      src/google/protobuf/compiler/csharp/csharp_wrapper_field.h

@ -96,11 +96,14 @@ csharp_EXTRA_DIST= \
csharp/src/Google.Protobuf.Benchmarks/Program.cs \
csharp/src/Google.Protobuf.Benchmarks/wrapper_benchmark_messages.proto \
csharp/src/Google.Protobuf.Benchmarks/WrapperBenchmarkMessages.cs \
csharp/src/Google.Protobuf.Benchmarks/WriteMessagesBenchmark.cs \
csharp/src/Google.Protobuf.Benchmarks/WriteRawPrimitivesBenchmark.cs \
csharp/src/Google.Protobuf.Conformance/Conformance.cs \
csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.csproj \
csharp/src/Google.Protobuf.Conformance/Program.cs \
csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.csproj \
csharp/src/Google.Protobuf.JsonDump/Program.cs \
csharp/src/Google.Protobuf.Test/Buffers/ArrayBufferWriter.cs \
csharp/src/Google.Protobuf.Test/ByteStringTest.cs \
csharp/src/Google.Protobuf.Test/CodedInputStreamExtensions.cs \
csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs \
@ -259,6 +262,11 @@ csharp_EXTRA_DIST= \
csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs \
csharp/src/Google.Protobuf/WellKnownTypes/WrappersPartial.cs \
csharp/src/Google.Protobuf/WireFormat.cs \
csharp/src/Google.Protobuf/WritingPrimitivesMessages.cs \
csharp/src/Google.Protobuf/WritingPrimitives.cs \
csharp/src/Google.Protobuf/WriterInternalState.cs \
csharp/src/Google.Protobuf/WriteContext.cs \
csharp/src/Google.Protobuf/WriteBufferHelper.cs \
csharp/src/Google.Protobuf/UnknownField.cs \
csharp/src/Google.Protobuf/UnknownFieldSet.cs

@ -211,35 +211,35 @@ namespace Google.Protobuf
[Test]
public void EncodeZigZag32()
{
Assert.AreEqual(0u, CodedOutputStream.EncodeZigZag32(0));
Assert.AreEqual(1u, CodedOutputStream.EncodeZigZag32(-1));
Assert.AreEqual(2u, CodedOutputStream.EncodeZigZag32(1));
Assert.AreEqual(3u, CodedOutputStream.EncodeZigZag32(-2));
Assert.AreEqual(0x7FFFFFFEu, CodedOutputStream.EncodeZigZag32(0x3FFFFFFF));
Assert.AreEqual(0x7FFFFFFFu, CodedOutputStream.EncodeZigZag32(unchecked((int) 0xC0000000)));
Assert.AreEqual(0xFFFFFFFEu, CodedOutputStream.EncodeZigZag32(0x7FFFFFFF));
Assert.AreEqual(0xFFFFFFFFu, CodedOutputStream.EncodeZigZag32(unchecked((int) 0x80000000)));
Assert.AreEqual(0u, WritingPrimitives.EncodeZigZag32(0));
Assert.AreEqual(1u, WritingPrimitives.EncodeZigZag32(-1));
Assert.AreEqual(2u, WritingPrimitives.EncodeZigZag32(1));
Assert.AreEqual(3u, WritingPrimitives.EncodeZigZag32(-2));
Assert.AreEqual(0x7FFFFFFEu, WritingPrimitives.EncodeZigZag32(0x3FFFFFFF));
Assert.AreEqual(0x7FFFFFFFu, WritingPrimitives.EncodeZigZag32(unchecked((int) 0xC0000000)));
Assert.AreEqual(0xFFFFFFFEu, WritingPrimitives.EncodeZigZag32(0x7FFFFFFF));
Assert.AreEqual(0xFFFFFFFFu, WritingPrimitives.EncodeZigZag32(unchecked((int) 0x80000000)));
}
[Test]
public void EncodeZigZag64()
{
Assert.AreEqual(0u, CodedOutputStream.EncodeZigZag64(0));
Assert.AreEqual(1u, CodedOutputStream.EncodeZigZag64(-1));
Assert.AreEqual(2u, CodedOutputStream.EncodeZigZag64(1));
Assert.AreEqual(3u, CodedOutputStream.EncodeZigZag64(-2));
Assert.AreEqual(0u, WritingPrimitives.EncodeZigZag64(0));
Assert.AreEqual(1u, WritingPrimitives.EncodeZigZag64(-1));
Assert.AreEqual(2u, WritingPrimitives.EncodeZigZag64(1));
Assert.AreEqual(3u, WritingPrimitives.EncodeZigZag64(-2));
Assert.AreEqual(0x000000007FFFFFFEuL,
CodedOutputStream.EncodeZigZag64(unchecked((long) 0x000000003FFFFFFFUL)));
WritingPrimitives.EncodeZigZag64(unchecked((long) 0x000000003FFFFFFFUL)));
Assert.AreEqual(0x000000007FFFFFFFuL,
CodedOutputStream.EncodeZigZag64(unchecked((long) 0xFFFFFFFFC0000000UL)));
WritingPrimitives.EncodeZigZag64(unchecked((long) 0xFFFFFFFFC0000000UL)));
Assert.AreEqual(0x00000000FFFFFFFEuL,
CodedOutputStream.EncodeZigZag64(unchecked((long) 0x000000007FFFFFFFUL)));
WritingPrimitives.EncodeZigZag64(unchecked((long) 0x000000007FFFFFFFUL)));
Assert.AreEqual(0x00000000FFFFFFFFuL,
CodedOutputStream.EncodeZigZag64(unchecked((long) 0xFFFFFFFF80000000UL)));
WritingPrimitives.EncodeZigZag64(unchecked((long) 0xFFFFFFFF80000000UL)));
Assert.AreEqual(0xFFFFFFFFFFFFFFFEL,
CodedOutputStream.EncodeZigZag64(unchecked((long) 0x7FFFFFFFFFFFFFFFUL)));
WritingPrimitives.EncodeZigZag64(unchecked((long) 0x7FFFFFFFFFFFFFFFUL)));
Assert.AreEqual(0xFFFFFFFFFFFFFFFFL,
CodedOutputStream.EncodeZigZag64(unchecked((long) 0x8000000000000000UL)));
WritingPrimitives.EncodeZigZag64(unchecked((long) 0x8000000000000000UL)));
}
[Test]
@ -247,26 +247,26 @@ namespace Google.Protobuf
{
// Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1)
// were chosen semi-randomly via keyboard bashing.
Assert.AreEqual(0, ParsingPrimitives.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(0)));
Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(1)));
Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-1)));
Assert.AreEqual(14927, ParsingPrimitives.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(14927)));
Assert.AreEqual(-3612, ParsingPrimitives.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-3612)));
Assert.AreEqual(0, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(0)));
Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(1)));
Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(-1)));
Assert.AreEqual(14927, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(14927)));
Assert.AreEqual(-3612, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(-3612)));
}
[Test]
public void RoundTripZigZag64()
{
Assert.AreEqual(0, ParsingPrimitives.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(0)));
Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(1)));
Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-1)));
Assert.AreEqual(14927, ParsingPrimitives.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(14927)));
Assert.AreEqual(-3612, ParsingPrimitives.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-3612)));
Assert.AreEqual(0, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(0)));
Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(1)));
Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(-1)));
Assert.AreEqual(14927, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(14927)));
Assert.AreEqual(-3612, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(-3612)));
Assert.AreEqual(856912304801416L,
ParsingPrimitives.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(856912304801416L)));
ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(856912304801416L)));
Assert.AreEqual(-75123905439571256L,
ParsingPrimitives.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-75123905439571256L)));
ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(-75123905439571256L)));
}
[Test]
@ -395,7 +395,7 @@ namespace Google.Protobuf
Assert.IsTrue(memoryStream.CanWrite);
using (var cos = new CodedOutputStream(memoryStream))
{
cos.WriteRawByte(0);
cos.WriteRawBytes(new byte[] {0});
Assert.AreEqual(0, memoryStream.Position); // Not flushed yet
}
Assert.AreEqual(1, memoryStream.ToArray().Length); // Flushed data from CodedOutputStream to MemoryStream
@ -409,7 +409,7 @@ namespace Google.Protobuf
Assert.IsTrue(memoryStream.CanWrite);
using (var cos = new CodedOutputStream(memoryStream, true))
{
cos.WriteRawByte(0);
cos.WriteRawBytes(new byte[] {0});
Assert.AreEqual(0, memoryStream.Position); // Not flushed yet
}
Assert.AreEqual(1, memoryStream.Position); // Flushed data from CodedOutputStream to MemoryStream

@ -124,7 +124,16 @@ namespace Google.Protobuf
{
var stream = new MemoryStream();
var codedOutput = new CodedOutputStream(stream);
codec.ValueWriter(codedOutput, sampleValue);
WriteContext.Initialize(codedOutput, out WriteContext ctx);
try
{
// only write the value using the codec
codec.ValueWriter(ref ctx, sampleValue);
}
finally
{
ctx.CopyStateTo(codedOutput);
}
codedOutput.Flush();
stream.Position = 0;
var codedInput = new CodedInputStream(stream);
@ -172,7 +181,16 @@ namespace Google.Protobuf
if (codec.DefaultValue != null) // This part isn't appropriate for message types.
{
codedOutput = new CodedOutputStream(stream);
codec.ValueWriter(codedOutput, codec.DefaultValue);
WriteContext.Initialize(codedOutput, out WriteContext ctx);
try
{
// only write the value using the codec
codec.ValueWriter(ref ctx, codec.DefaultValue);
}
finally
{
ctx.CopyStateTo(codedOutput);
}
codedOutput.Flush();
Assert.AreNotEqual(0, stream.Position);
Assert.AreEqual(stream.Position, codec.ValueSizeCalculator(codec.DefaultValue));

@ -190,6 +190,9 @@ namespace Google.Protobuf.Examples.AddressBook {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Name.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Name);
@ -210,8 +213,35 @@ namespace Google.Protobuf.Examples.AddressBook {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Name);
}
if (Id != 0) {
output.WriteRawTag(16);
output.WriteInt32(Id);
}
if (Email.Length != 0) {
output.WriteRawTag(26);
output.WriteString(Email);
}
phones_.WriteTo(ref output, _repeated_phones_codec);
if (lastUpdated_ != null) {
output.WriteRawTag(42);
output.WriteMessage(LastUpdated);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -441,6 +471,9 @@ namespace Google.Protobuf.Examples.AddressBook {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Number.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Number);
@ -452,8 +485,26 @@ namespace Google.Protobuf.Examples.AddressBook {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Number.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Number);
}
if (Type != global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType.Mobile) {
output.WriteRawTag(16);
output.WriteEnum((int) Type);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -621,12 +672,26 @@ namespace Google.Protobuf.Examples.AddressBook {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
people_.WriteTo(output, _repeated_people_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
people_.WriteTo(ref output, _repeated_people_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;

@ -706,6 +706,9 @@ namespace Benchmarks.Proto3 {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Field1.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Field1);
@ -870,7 +873,178 @@ namespace Benchmarks.Proto3 {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Field1.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Field1);
}
if (Field2 != 0) {
output.WriteRawTag(16);
output.WriteInt32(Field2);
}
if (Field3 != 0) {
output.WriteRawTag(24);
output.WriteInt32(Field3);
}
if (Field4.Length != 0) {
output.WriteRawTag(34);
output.WriteString(Field4);
}
field5_.WriteTo(ref output, _repeated_field5_codec);
if (Field6 != 0) {
output.WriteRawTag(48);
output.WriteInt32(Field6);
}
if (Field7.Length != 0) {
output.WriteRawTag(58);
output.WriteString(Field7);
}
if (Field9.Length != 0) {
output.WriteRawTag(74);
output.WriteString(Field9);
}
if (Field12 != false) {
output.WriteRawTag(96);
output.WriteBool(Field12);
}
if (Field13 != false) {
output.WriteRawTag(104);
output.WriteBool(Field13);
}
if (Field14 != false) {
output.WriteRawTag(112);
output.WriteBool(Field14);
}
if (field15_ != null) {
output.WriteRawTag(122);
output.WriteMessage(Field15);
}
if (Field16 != 0) {
output.WriteRawTag(128, 1);
output.WriteInt32(Field16);
}
if (Field17 != false) {
output.WriteRawTag(136, 1);
output.WriteBool(Field17);
}
if (Field18.Length != 0) {
output.WriteRawTag(146, 1);
output.WriteString(Field18);
}
if (Field22 != 0L) {
output.WriteRawTag(176, 1);
output.WriteInt64(Field22);
}
if (Field23 != 0) {
output.WriteRawTag(184, 1);
output.WriteInt32(Field23);
}
if (Field24 != false) {
output.WriteRawTag(192, 1);
output.WriteBool(Field24);
}
if (Field25 != 0) {
output.WriteRawTag(200, 1);
output.WriteInt32(Field25);
}
if (Field29 != 0) {
output.WriteRawTag(232, 1);
output.WriteInt32(Field29);
}
if (Field30 != false) {
output.WriteRawTag(240, 1);
output.WriteBool(Field30);
}
if (Field59 != false) {
output.WriteRawTag(216, 3);
output.WriteBool(Field59);
}
if (Field60 != 0) {
output.WriteRawTag(224, 3);
output.WriteInt32(Field60);
}
if (Field67 != 0) {
output.WriteRawTag(152, 4);
output.WriteInt32(Field67);
}
if (Field68 != 0) {
output.WriteRawTag(160, 4);
output.WriteInt32(Field68);
}
if (Field78 != false) {
output.WriteRawTag(240, 4);
output.WriteBool(Field78);
}
if (Field80 != false) {
output.WriteRawTag(128, 5);
output.WriteBool(Field80);
}
if (Field81 != false) {
output.WriteRawTag(136, 5);
output.WriteBool(Field81);
}
if (Field100 != 0) {
output.WriteRawTag(160, 6);
output.WriteInt32(Field100);
}
if (Field101 != 0) {
output.WriteRawTag(168, 6);
output.WriteInt32(Field101);
}
if (Field102.Length != 0) {
output.WriteRawTag(178, 6);
output.WriteString(Field102);
}
if (Field103.Length != 0) {
output.WriteRawTag(186, 6);
output.WriteString(Field103);
}
if (Field104 != 0) {
output.WriteRawTag(192, 6);
output.WriteInt32(Field104);
}
if (Field128 != 0) {
output.WriteRawTag(128, 8);
output.WriteInt32(Field128);
}
if (Field129.Length != 0) {
output.WriteRawTag(138, 8);
output.WriteString(Field129);
}
if (Field130 != 0) {
output.WriteRawTag(144, 8);
output.WriteInt32(Field130);
}
if (Field131 != 0) {
output.WriteRawTag(152, 8);
output.WriteInt32(Field131);
}
if (Field150 != 0) {
output.WriteRawTag(176, 9);
output.WriteInt32(Field150);
}
if (Field271 != 0) {
output.WriteRawTag(248, 16);
output.WriteInt32(Field271);
}
if (Field272 != 0) {
output.WriteRawTag(128, 17);
output.WriteInt32(Field272);
}
if (Field280 != 0) {
output.WriteRawTag(192, 17);
output.WriteInt32(Field280);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -1851,6 +2025,9 @@ namespace Benchmarks.Proto3 {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Field1 != 0) {
output.WriteRawTag(8);
output.WriteInt32(Field1);
@ -1934,7 +2111,97 @@ namespace Benchmarks.Proto3 {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Field1 != 0) {
output.WriteRawTag(8);
output.WriteInt32(Field1);
}
if (Field2 != 0) {
output.WriteRawTag(16);
output.WriteInt32(Field2);
}
if (Field3 != 0) {
output.WriteRawTag(24);
output.WriteInt32(Field3);
}
if (Field12 != false) {
output.WriteRawTag(96);
output.WriteBool(Field12);
}
if (Field13 != 0L) {
output.WriteRawTag(104);
output.WriteInt64(Field13);
}
if (Field14 != 0L) {
output.WriteRawTag(112);
output.WriteInt64(Field14);
}
if (Field15.Length != 0) {
output.WriteRawTag(122);
output.WriteString(Field15);
}
if (Field16 != 0) {
output.WriteRawTag(128, 1);
output.WriteInt32(Field16);
}
if (Field19 != 0) {
output.WriteRawTag(152, 1);
output.WriteInt32(Field19);
}
if (Field20 != false) {
output.WriteRawTag(160, 1);
output.WriteBool(Field20);
}
if (Field21 != 0UL) {
output.WriteRawTag(169, 1);
output.WriteFixed64(Field21);
}
if (Field22 != 0) {
output.WriteRawTag(176, 1);
output.WriteInt32(Field22);
}
if (Field23 != false) {
output.WriteRawTag(184, 1);
output.WriteBool(Field23);
}
if (Field28 != false) {
output.WriteRawTag(224, 1);
output.WriteBool(Field28);
}
if (Field203 != 0) {
output.WriteRawTag(221, 12);
output.WriteFixed32(Field203);
}
if (Field204 != 0) {
output.WriteRawTag(224, 12);
output.WriteInt32(Field204);
}
if (Field205.Length != 0) {
output.WriteRawTag(234, 12);
output.WriteString(Field205);
}
if (Field206 != false) {
output.WriteRawTag(240, 12);
output.WriteBool(Field206);
}
if (Field207 != 0UL) {
output.WriteRawTag(248, 12);
output.WriteUInt64(Field207);
}
if (Field300 != 0UL) {
output.WriteRawTag(224, 18);
output.WriteUInt64(Field300);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {

@ -176,6 +176,9 @@ namespace Benchmarks {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Name.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Name);
@ -188,7 +191,26 @@ namespace Benchmarks {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Name);
}
if (MessageName.Length != 0) {
output.WriteRawTag(18);
output.WriteString(MessageName);
}
payload_.WriteTo(ref output, _repeated_payload_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {

@ -151,7 +151,7 @@ namespace Google.Protobuf.Benchmarks
repeatedFieldTest.ParseDelimitedMessagesFromReadOnlySequence(messageCount);
}
private static ManyWrapperFieldsMessage CreateManyWrapperFieldsMessage()
public static ManyWrapperFieldsMessage CreateManyWrapperFieldsMessage()
{
// Example data match data of an internal benchmarks
return new ManyWrapperFieldsMessage()
@ -168,7 +168,7 @@ namespace Google.Protobuf.Benchmarks
};
}
private static ManyPrimitiveFieldsMessage CreateManyPrimitiveFieldsMessage()
public static ManyPrimitiveFieldsMessage CreateManyPrimitiveFieldsMessage()
{
// Example data match data of an internal benchmarks
return new ManyPrimitiveFieldsMessage()
@ -185,7 +185,7 @@ namespace Google.Protobuf.Benchmarks
};
}
private static GoogleMessage1 CreateRepeatedFieldMessage()
public static GoogleMessage1 CreateRepeatedFieldMessage()
{
// Message with a repeated fixed length item collection
var message = new GoogleMessage1();

@ -337,7 +337,7 @@ namespace Google.Protobuf.Benchmarks
CodedOutputStream cos = new CodedOutputStream(ms);
for (int i = 0; i < valueCount + paddingValueCount; i++)
{
cos.WriteUInt64(RandomUnsignedVarint(random, encodedSize));
cos.WriteUInt64(RandomUnsignedVarint(random, encodedSize, false));
}
cos.Flush();
var buffer = ms.ToArray();
@ -386,11 +386,11 @@ namespace Google.Protobuf.Benchmarks
/// <summary>
/// Generate a random value that will take exactly "encodedSize" bytes when varint-encoded.
/// </summary>
private static ulong RandomUnsignedVarint(Random random, int encodedSize)
public static ulong RandomUnsignedVarint(Random random, int encodedSize, bool fitsIn32Bits)
{
Span<byte> randomBytesBuffer = stackalloc byte[8];
if (encodedSize < 1 || encodedSize > 10)
if (encodedSize < 1 || encodedSize > 10 || (fitsIn32Bits && encodedSize > 5))
{
throw new ArgumentException("Illegal encodedSize value requested", nameof(encodedSize));
}
@ -406,6 +406,12 @@ namespace Google.Protobuf.Benchmarks
ulong bitmask = encodedSize < 10 ? ((1UL << (encodedSize * bitsPerByte)) - 1) : ulong.MaxValue;
result = randomValue & bitmask;
if (fitsIn32Bits)
{
// make sure the resulting value is representable by a uint.
result &= uint.MaxValue;
}
if (encodedSize == 10)
{
// for 10-byte values the highest bit always needs to be set (7*9=63)
@ -443,7 +449,7 @@ namespace Google.Protobuf.Benchmarks
return buffer;
}
private static string CreateStringWithEncodedSize(int encodedSize)
public static string CreateStringWithEncodedSize(int encodedSize)
{
var str = new string('a', encodedSize);
while (CodedOutputStream.ComputeStringSize(str) > encodedSize)
@ -457,5 +463,34 @@ namespace Google.Protobuf.Benchmarks
}
return str;
}
public static string CreateNonAsciiStringWithEncodedSize(int encodedSize)
{
if (encodedSize < 3)
{
throw new ArgumentException("Illegal encoded size for a string with non-ascii chars.");
}
var twoByteChar = '\u00DC'; // U-umlaut, UTF8 encoding has 2 bytes
var str = new string(twoByteChar, encodedSize / 2);
while (CodedOutputStream.ComputeStringSize(str) > encodedSize)
{
str = str.Substring(1);
}
// add padding of ascii characters to reach the desired encoded size.
while (CodedOutputStream.ComputeStringSize(str) < encodedSize)
{
str += 'a';
}
// Note that for a few specific encodedSize values, it might be impossible to generate
// the string with the desired encodedSize using the algorithm above. For testing purposes, checking that
// the encoded size we got is actually correct is good enough.
if (CodedOutputStream.ComputeStringSize(str) != encodedSize)
{
throw new InvalidOperationException($"Generated string with wrong encodedSize");
}
return str;
}
}
}

@ -2073,6 +2073,9 @@ namespace Google.Protobuf.Benchmarks {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (doubleField1_ != null) {
_single_doubleField1_codec.WriteTagAndValue(output, DoubleField1);
}
@ -2410,7 +2413,351 @@ namespace Google.Protobuf.Benchmarks {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (doubleField1_ != null) {
_single_doubleField1_codec.WriteTagAndValue(ref output, DoubleField1);
}
if (int64Field2_ != null) {
_single_int64Field2_codec.WriteTagAndValue(ref output, Int64Field2);
}
if (int64Field3_ != null) {
_single_int64Field3_codec.WriteTagAndValue(ref output, Int64Field3);
}
if (int64Field4_ != null) {
_single_int64Field4_codec.WriteTagAndValue(ref output, Int64Field4);
}
if (doubleField7_ != null) {
_single_doubleField7_codec.WriteTagAndValue(ref output, DoubleField7);
}
if (doubleField8_ != null) {
_single_doubleField8_codec.WriteTagAndValue(ref output, DoubleField8);
}
if (doubleField9_ != null) {
_single_doubleField9_codec.WriteTagAndValue(ref output, DoubleField9);
}
if (doubleField10_ != null) {
_single_doubleField10_codec.WriteTagAndValue(ref output, DoubleField10);
}
if (doubleField11_ != null) {
_single_doubleField11_codec.WriteTagAndValue(ref output, DoubleField11);
}
if (doubleField14_ != null) {
_single_doubleField14_codec.WriteTagAndValue(ref output, DoubleField14);
}
if (doubleField15_ != null) {
_single_doubleField15_codec.WriteTagAndValue(ref output, DoubleField15);
}
if (int64Field19_ != null) {
_single_int64Field19_codec.WriteTagAndValue(ref output, Int64Field19);
}
if (doubleField20_ != null) {
_single_doubleField20_codec.WriteTagAndValue(ref output, DoubleField20);
}
if (doubleField21_ != null) {
_single_doubleField21_codec.WriteTagAndValue(ref output, DoubleField21);
}
if (doubleField22_ != null) {
_single_doubleField22_codec.WriteTagAndValue(ref output, DoubleField22);
}
if (doubleField25_ != null) {
_single_doubleField25_codec.WriteTagAndValue(ref output, DoubleField25);
}
if (int64Field26_ != null) {
_single_int64Field26_codec.WriteTagAndValue(ref output, Int64Field26);
}
if (doubleField28_ != null) {
_single_doubleField28_codec.WriteTagAndValue(ref output, DoubleField28);
}
if (doubleField29_ != null) {
_single_doubleField29_codec.WriteTagAndValue(ref output, DoubleField29);
}
if (doubleField30_ != null) {
_single_doubleField30_codec.WriteTagAndValue(ref output, DoubleField30);
}
if (doubleField31_ != null) {
_single_doubleField31_codec.WriteTagAndValue(ref output, DoubleField31);
}
if (int64Field32_ != null) {
_single_int64Field32_codec.WriteTagAndValue(ref output, Int64Field32);
}
if (int64Field37_ != null) {
_single_int64Field37_codec.WriteTagAndValue(ref output, Int64Field37);
}
if (doubleField38_ != null) {
_single_doubleField38_codec.WriteTagAndValue(ref output, DoubleField38);
}
if (interactions_ != null) {
_single_interactions_codec.WriteTagAndValue(ref output, Interactions);
}
if (doubleField40_ != null) {
_single_doubleField40_codec.WriteTagAndValue(ref output, DoubleField40);
}
if (int64Field41_ != null) {
_single_int64Field41_codec.WriteTagAndValue(ref output, Int64Field41);
}
if (doubleField42_ != null) {
_single_doubleField42_codec.WriteTagAndValue(ref output, DoubleField42);
}
if (int64Field43_ != null) {
_single_int64Field43_codec.WriteTagAndValue(ref output, Int64Field43);
}
if (int64Field44_ != null) {
_single_int64Field44_codec.WriteTagAndValue(ref output, Int64Field44);
}
if (doubleField45_ != null) {
_single_doubleField45_codec.WriteTagAndValue(ref output, DoubleField45);
}
if (doubleField46_ != null) {
_single_doubleField46_codec.WriteTagAndValue(ref output, DoubleField46);
}
if (doubleField47_ != null) {
_single_doubleField47_codec.WriteTagAndValue(ref output, DoubleField47);
}
if (doubleField48_ != null) {
_single_doubleField48_codec.WriteTagAndValue(ref output, DoubleField48);
}
if (doubleField49_ != null) {
_single_doubleField49_codec.WriteTagAndValue(ref output, DoubleField49);
}
if (doubleField50_ != null) {
_single_doubleField50_codec.WriteTagAndValue(ref output, DoubleField50);
}
if (doubleField51_ != null) {
_single_doubleField51_codec.WriteTagAndValue(ref output, DoubleField51);
}
if (doubleField52_ != null) {
_single_doubleField52_codec.WriteTagAndValue(ref output, DoubleField52);
}
if (doubleField53_ != null) {
_single_doubleField53_codec.WriteTagAndValue(ref output, DoubleField53);
}
if (doubleField54_ != null) {
_single_doubleField54_codec.WriteTagAndValue(ref output, DoubleField54);
}
if (doubleField55_ != null) {
_single_doubleField55_codec.WriteTagAndValue(ref output, DoubleField55);
}
if (doubleField56_ != null) {
_single_doubleField56_codec.WriteTagAndValue(ref output, DoubleField56);
}
if (doubleField57_ != null) {
_single_doubleField57_codec.WriteTagAndValue(ref output, DoubleField57);
}
if (doubleField58_ != null) {
_single_doubleField58_codec.WriteTagAndValue(ref output, DoubleField58);
}
if (int64Field59_ != null) {
_single_int64Field59_codec.WriteTagAndValue(ref output, Int64Field59);
}
if (int64Field60_ != null) {
_single_int64Field60_codec.WriteTagAndValue(ref output, Int64Field60);
}
if (doubleField62_ != null) {
_single_doubleField62_codec.WriteTagAndValue(ref output, DoubleField62);
}
if (doubleField65_ != null) {
_single_doubleField65_codec.WriteTagAndValue(ref output, DoubleField65);
}
if (doubleField66_ != null) {
_single_doubleField66_codec.WriteTagAndValue(ref output, DoubleField66);
}
if (doubleField67_ != null) {
_single_doubleField67_codec.WriteTagAndValue(ref output, DoubleField67);
}
if (doubleField68_ != null) {
_single_doubleField68_codec.WriteTagAndValue(ref output, DoubleField68);
}
if (doubleField69_ != null) {
_single_doubleField69_codec.WriteTagAndValue(ref output, DoubleField69);
}
if (doubleField70_ != null) {
_single_doubleField70_codec.WriteTagAndValue(ref output, DoubleField70);
}
if (doubleField71_ != null) {
_single_doubleField71_codec.WriteTagAndValue(ref output, DoubleField71);
}
if (doubleField72_ != null) {
_single_doubleField72_codec.WriteTagAndValue(ref output, DoubleField72);
}
if (stringField73_ != null) {
_single_stringField73_codec.WriteTagAndValue(ref output, StringField73);
}
if (stringField74_ != null) {
_single_stringField74_codec.WriteTagAndValue(ref output, StringField74);
}
if (doubleField75_ != null) {
_single_doubleField75_codec.WriteTagAndValue(ref output, DoubleField75);
}
if (doubleField77_ != null) {
_single_doubleField77_codec.WriteTagAndValue(ref output, DoubleField77);
}
if (doubleField78_ != null) {
_single_doubleField78_codec.WriteTagAndValue(ref output, DoubleField78);
}
if (doubleField79_ != null) {
_single_doubleField79_codec.WriteTagAndValue(ref output, DoubleField79);
}
if (EnumField80 != 0) {
output.WriteRawTag(128, 5);
output.WriteInt32(EnumField80);
}
if (EnumField81 != 0) {
output.WriteRawTag(136, 5);
output.WriteInt32(EnumField81);
}
if (int64Field82_ != null) {
_single_int64Field82_codec.WriteTagAndValue(ref output, Int64Field82);
}
if (EnumField83 != 0) {
output.WriteRawTag(152, 5);
output.WriteInt32(EnumField83);
}
if (doubleField84_ != null) {
_single_doubleField84_codec.WriteTagAndValue(ref output, DoubleField84);
}
if (int64Field85_ != null) {
_single_int64Field85_codec.WriteTagAndValue(ref output, Int64Field85);
}
if (int64Field86_ != null) {
_single_int64Field86_codec.WriteTagAndValue(ref output, Int64Field86);
}
if (int64Field87_ != null) {
_single_int64Field87_codec.WriteTagAndValue(ref output, Int64Field87);
}
if (doubleField88_ != null) {
_single_doubleField88_codec.WriteTagAndValue(ref output, DoubleField88);
}
if (doubleField89_ != null) {
_single_doubleField89_codec.WriteTagAndValue(ref output, DoubleField89);
}
if (doubleField90_ != null) {
_single_doubleField90_codec.WriteTagAndValue(ref output, DoubleField90);
}
if (doubleField91_ != null) {
_single_doubleField91_codec.WriteTagAndValue(ref output, DoubleField91);
}
if (doubleField92_ != null) {
_single_doubleField92_codec.WriteTagAndValue(ref output, DoubleField92);
}
if (doubleField93_ != null) {
_single_doubleField93_codec.WriteTagAndValue(ref output, DoubleField93);
}
if (doubleField94_ != null) {
_single_doubleField94_codec.WriteTagAndValue(ref output, DoubleField94);
}
if (doubleField95_ != null) {
_single_doubleField95_codec.WriteTagAndValue(ref output, DoubleField95);
}
if (doubleField96_ != null) {
_single_doubleField96_codec.WriteTagAndValue(ref output, DoubleField96);
}
if (doubleField97_ != null) {
_single_doubleField97_codec.WriteTagAndValue(ref output, DoubleField97);
}
if (doubleField98_ != null) {
_single_doubleField98_codec.WriteTagAndValue(ref output, DoubleField98);
}
if (doubleField99_ != null) {
_single_doubleField99_codec.WriteTagAndValue(ref output, DoubleField99);
}
repeatedIntField100_.WriteTo(ref output, _repeated_repeatedIntField100_codec);
if (doubleField101_ != null) {
_single_doubleField101_codec.WriteTagAndValue(ref output, DoubleField101);
}
if (doubleField102_ != null) {
_single_doubleField102_codec.WriteTagAndValue(ref output, DoubleField102);
}
if (doubleField103_ != null) {
_single_doubleField103_codec.WriteTagAndValue(ref output, DoubleField103);
}
if (doubleField104_ != null) {
_single_doubleField104_codec.WriteTagAndValue(ref output, DoubleField104);
}
if (doubleField105_ != null) {
_single_doubleField105_codec.WriteTagAndValue(ref output, DoubleField105);
}
if (doubleField106_ != null) {
_single_doubleField106_codec.WriteTagAndValue(ref output, DoubleField106);
}
if (int64Field107_ != null) {
_single_int64Field107_codec.WriteTagAndValue(ref output, Int64Field107);
}
if (doubleField108_ != null) {
_single_doubleField108_codec.WriteTagAndValue(ref output, DoubleField108);
}
if (doubleField109_ != null) {
_single_doubleField109_codec.WriteTagAndValue(ref output, DoubleField109);
}
if (int64Field110_ != null) {
_single_int64Field110_codec.WriteTagAndValue(ref output, Int64Field110);
}
if (doubleField111_ != null) {
_single_doubleField111_codec.WriteTagAndValue(ref output, DoubleField111);
}
if (int64Field112_ != null) {
_single_int64Field112_codec.WriteTagAndValue(ref output, Int64Field112);
}
if (doubleField113_ != null) {
_single_doubleField113_codec.WriteTagAndValue(ref output, DoubleField113);
}
if (int64Field114_ != null) {
_single_int64Field114_codec.WriteTagAndValue(ref output, Int64Field114);
}
if (int64Field115_ != null) {
_single_int64Field115_codec.WriteTagAndValue(ref output, Int64Field115);
}
if (doubleField116_ != null) {
_single_doubleField116_codec.WriteTagAndValue(ref output, DoubleField116);
}
if (int64Field117_ != null) {
_single_int64Field117_codec.WriteTagAndValue(ref output, Int64Field117);
}
if (doubleField118_ != null) {
_single_doubleField118_codec.WriteTagAndValue(ref output, DoubleField118);
}
if (doubleField119_ != null) {
_single_doubleField119_codec.WriteTagAndValue(ref output, DoubleField119);
}
if (doubleField120_ != null) {
_single_doubleField120_codec.WriteTagAndValue(ref output, DoubleField120);
}
if (doubleField121_ != null) {
_single_doubleField121_codec.WriteTagAndValue(ref output, DoubleField121);
}
if (doubleField122_ != null) {
_single_doubleField122_codec.WriteTagAndValue(ref output, DoubleField122);
}
if (doubleField123_ != null) {
_single_doubleField123_codec.WriteTagAndValue(ref output, DoubleField123);
}
if (doubleField124_ != null) {
_single_doubleField124_codec.WriteTagAndValue(ref output, DoubleField124);
}
if (int64Field125_ != null) {
_single_int64Field125_codec.WriteTagAndValue(ref output, Int64Field125);
}
if (int64Field126_ != null) {
_single_int64Field126_codec.WriteTagAndValue(ref output, Int64Field126);
}
if (int64Field127_ != null) {
_single_int64Field127_codec.WriteTagAndValue(ref output, Int64Field127);
}
if (doubleField128_ != null) {
_single_doubleField128_codec.WriteTagAndValue(ref output, DoubleField128);
}
if (doubleField129_ != null) {
_single_doubleField129_codec.WriteTagAndValue(ref output, DoubleField129);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -6495,6 +6842,9 @@ namespace Google.Protobuf.Benchmarks {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (DoubleField1 != 0D) {
output.WriteRawTag(9);
output.WriteDouble(DoubleField1);
@ -6939,8 +7289,459 @@ namespace Google.Protobuf.Benchmarks {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (DoubleField1 != 0D) {
output.WriteRawTag(9);
output.WriteDouble(DoubleField1);
}
if (Int64Field2 != 0L) {
output.WriteRawTag(16);
output.WriteInt64(Int64Field2);
}
if (Int64Field3 != 0L) {
output.WriteRawTag(24);
output.WriteInt64(Int64Field3);
}
if (Int64Field4 != 0L) {
output.WriteRawTag(32);
output.WriteInt64(Int64Field4);
}
if (DoubleField7 != 0D) {
output.WriteRawTag(57);
output.WriteDouble(DoubleField7);
}
if (DoubleField8 != 0D) {
output.WriteRawTag(65);
output.WriteDouble(DoubleField8);
}
if (DoubleField9 != 0D) {
output.WriteRawTag(73);
output.WriteDouble(DoubleField9);
}
if (DoubleField10 != 0D) {
output.WriteRawTag(81);
output.WriteDouble(DoubleField10);
}
if (DoubleField11 != 0D) {
output.WriteRawTag(89);
output.WriteDouble(DoubleField11);
}
if (DoubleField14 != 0D) {
output.WriteRawTag(113);
output.WriteDouble(DoubleField14);
}
if (DoubleField15 != 0D) {
output.WriteRawTag(121);
output.WriteDouble(DoubleField15);
}
if (Int64Field19 != 0L) {
output.WriteRawTag(152, 1);
output.WriteInt64(Int64Field19);
}
if (DoubleField20 != 0D) {
output.WriteRawTag(161, 1);
output.WriteDouble(DoubleField20);
}
if (DoubleField21 != 0D) {
output.WriteRawTag(169, 1);
output.WriteDouble(DoubleField21);
}
if (DoubleField22 != 0D) {
output.WriteRawTag(177, 1);
output.WriteDouble(DoubleField22);
}
if (DoubleField25 != 0D) {
output.WriteRawTag(201, 1);
output.WriteDouble(DoubleField25);
}
if (Int64Field26 != 0L) {
output.WriteRawTag(208, 1);
output.WriteInt64(Int64Field26);
}
if (DoubleField28 != 0D) {
output.WriteRawTag(225, 1);
output.WriteDouble(DoubleField28);
}
if (DoubleField29 != 0D) {
output.WriteRawTag(233, 1);
output.WriteDouble(DoubleField29);
}
if (DoubleField30 != 0D) {
output.WriteRawTag(241, 1);
output.WriteDouble(DoubleField30);
}
if (DoubleField31 != 0D) {
output.WriteRawTag(249, 1);
output.WriteDouble(DoubleField31);
}
if (Int64Field32 != 0L) {
output.WriteRawTag(128, 2);
output.WriteInt64(Int64Field32);
}
if (Int64Field37 != 0L) {
output.WriteRawTag(168, 2);
output.WriteInt64(Int64Field37);
}
if (DoubleField38 != 0D) {
output.WriteRawTag(177, 2);
output.WriteDouble(DoubleField38);
}
if (Interactions != 0L) {
output.WriteRawTag(184, 2);
output.WriteInt64(Interactions);
}
if (DoubleField40 != 0D) {
output.WriteRawTag(193, 2);
output.WriteDouble(DoubleField40);
}
if (Int64Field41 != 0L) {
output.WriteRawTag(200, 2);
output.WriteInt64(Int64Field41);
}
if (DoubleField42 != 0D) {
output.WriteRawTag(209, 2);
output.WriteDouble(DoubleField42);
}
if (Int64Field43 != 0L) {
output.WriteRawTag(216, 2);
output.WriteInt64(Int64Field43);
}
if (Int64Field44 != 0L) {
output.WriteRawTag(224, 2);
output.WriteInt64(Int64Field44);
}
if (DoubleField45 != 0D) {
output.WriteRawTag(233, 2);
output.WriteDouble(DoubleField45);
}
if (DoubleField46 != 0D) {
output.WriteRawTag(241, 2);
output.WriteDouble(DoubleField46);
}
if (DoubleField47 != 0D) {
output.WriteRawTag(249, 2);
output.WriteDouble(DoubleField47);
}
if (DoubleField48 != 0D) {
output.WriteRawTag(129, 3);
output.WriteDouble(DoubleField48);
}
if (DoubleField49 != 0D) {
output.WriteRawTag(137, 3);
output.WriteDouble(DoubleField49);
}
if (DoubleField50 != 0D) {
output.WriteRawTag(145, 3);
output.WriteDouble(DoubleField50);
}
if (DoubleField51 != 0D) {
output.WriteRawTag(153, 3);
output.WriteDouble(DoubleField51);
}
if (DoubleField52 != 0D) {
output.WriteRawTag(161, 3);
output.WriteDouble(DoubleField52);
}
if (DoubleField53 != 0D) {
output.WriteRawTag(169, 3);
output.WriteDouble(DoubleField53);
}
if (DoubleField54 != 0D) {
output.WriteRawTag(177, 3);
output.WriteDouble(DoubleField54);
}
if (DoubleField55 != 0D) {
output.WriteRawTag(185, 3);
output.WriteDouble(DoubleField55);
}
if (DoubleField56 != 0D) {
output.WriteRawTag(193, 3);
output.WriteDouble(DoubleField56);
}
if (DoubleField57 != 0D) {
output.WriteRawTag(201, 3);
output.WriteDouble(DoubleField57);
}
if (DoubleField58 != 0D) {
output.WriteRawTag(209, 3);
output.WriteDouble(DoubleField58);
}
if (Int64Field59 != 0L) {
output.WriteRawTag(216, 3);
output.WriteInt64(Int64Field59);
}
if (Int64Field60 != 0L) {
output.WriteRawTag(224, 3);
output.WriteInt64(Int64Field60);
}
if (DoubleField62 != 0D) {
output.WriteRawTag(241, 3);
output.WriteDouble(DoubleField62);
}
if (DoubleField65 != 0D) {
output.WriteRawTag(137, 4);
output.WriteDouble(DoubleField65);
}
if (DoubleField66 != 0D) {
output.WriteRawTag(145, 4);
output.WriteDouble(DoubleField66);
}
if (DoubleField67 != 0D) {
output.WriteRawTag(153, 4);
output.WriteDouble(DoubleField67);
}
if (DoubleField68 != 0D) {
output.WriteRawTag(161, 4);
output.WriteDouble(DoubleField68);
}
if (DoubleField69 != 0D) {
output.WriteRawTag(169, 4);
output.WriteDouble(DoubleField69);
}
if (DoubleField70 != 0D) {
output.WriteRawTag(177, 4);
output.WriteDouble(DoubleField70);
}
if (DoubleField71 != 0D) {
output.WriteRawTag(185, 4);
output.WriteDouble(DoubleField71);
}
if (DoubleField72 != 0D) {
output.WriteRawTag(193, 4);
output.WriteDouble(DoubleField72);
}
if (StringField73.Length != 0) {
output.WriteRawTag(202, 4);
output.WriteString(StringField73);
}
if (StringField74.Length != 0) {
output.WriteRawTag(210, 4);
output.WriteString(StringField74);
}
if (DoubleField75 != 0D) {
output.WriteRawTag(217, 4);
output.WriteDouble(DoubleField75);
}
if (DoubleField77 != 0D) {
output.WriteRawTag(233, 4);
output.WriteDouble(DoubleField77);
}
if (DoubleField78 != 0D) {
output.WriteRawTag(241, 4);
output.WriteDouble(DoubleField78);
}
if (DoubleField79 != 0D) {
output.WriteRawTag(249, 4);
output.WriteDouble(DoubleField79);
}
if (EnumField80 != 0) {
output.WriteRawTag(128, 5);
output.WriteInt32(EnumField80);
}
if (EnumField81 != 0) {
output.WriteRawTag(136, 5);
output.WriteInt32(EnumField81);
}
if (Int64Field82 != 0L) {
output.WriteRawTag(144, 5);
output.WriteInt64(Int64Field82);
}
if (EnumField83 != 0) {
output.WriteRawTag(152, 5);
output.WriteInt32(EnumField83);
}
if (DoubleField84 != 0D) {
output.WriteRawTag(161, 5);
output.WriteDouble(DoubleField84);
}
if (Int64Field85 != 0L) {
output.WriteRawTag(168, 5);
output.WriteInt64(Int64Field85);
}
if (Int64Field86 != 0L) {
output.WriteRawTag(176, 5);
output.WriteInt64(Int64Field86);
}
if (Int64Field87 != 0L) {
output.WriteRawTag(184, 5);
output.WriteInt64(Int64Field87);
}
if (DoubleField88 != 0D) {
output.WriteRawTag(193, 5);
output.WriteDouble(DoubleField88);
}
if (DoubleField89 != 0D) {
output.WriteRawTag(201, 5);
output.WriteDouble(DoubleField89);
}
if (DoubleField90 != 0D) {
output.WriteRawTag(209, 5);
output.WriteDouble(DoubleField90);
}
if (DoubleField91 != 0D) {
output.WriteRawTag(217, 5);
output.WriteDouble(DoubleField91);
}
if (DoubleField92 != 0D) {
output.WriteRawTag(225, 5);
output.WriteDouble(DoubleField92);
}
if (DoubleField93 != 0D) {
output.WriteRawTag(233, 5);
output.WriteDouble(DoubleField93);
}
if (DoubleField94 != 0D) {
output.WriteRawTag(241, 5);
output.WriteDouble(DoubleField94);
}
if (DoubleField95 != 0D) {
output.WriteRawTag(249, 5);
output.WriteDouble(DoubleField95);
}
if (DoubleField96 != 0D) {
output.WriteRawTag(129, 6);
output.WriteDouble(DoubleField96);
}
if (DoubleField97 != 0D) {
output.WriteRawTag(137, 6);
output.WriteDouble(DoubleField97);
}
if (DoubleField98 != 0D) {
output.WriteRawTag(145, 6);
output.WriteDouble(DoubleField98);
}
if (DoubleField99 != 0D) {
output.WriteRawTag(153, 6);
output.WriteDouble(DoubleField99);
}
repeatedIntField100_.WriteTo(ref output, _repeated_repeatedIntField100_codec);
if (DoubleField101 != 0D) {
output.WriteRawTag(169, 6);
output.WriteDouble(DoubleField101);
}
if (DoubleField102 != 0D) {
output.WriteRawTag(177, 6);
output.WriteDouble(DoubleField102);
}
if (DoubleField103 != 0D) {
output.WriteRawTag(185, 6);
output.WriteDouble(DoubleField103);
}
if (DoubleField104 != 0D) {
output.WriteRawTag(193, 6);
output.WriteDouble(DoubleField104);
}
if (DoubleField105 != 0D) {
output.WriteRawTag(201, 6);
output.WriteDouble(DoubleField105);
}
if (DoubleField106 != 0D) {
output.WriteRawTag(209, 6);
output.WriteDouble(DoubleField106);
}
if (Int64Field107 != 0L) {
output.WriteRawTag(216, 6);
output.WriteInt64(Int64Field107);
}
if (DoubleField108 != 0D) {
output.WriteRawTag(225, 6);
output.WriteDouble(DoubleField108);
}
if (DoubleField109 != 0D) {
output.WriteRawTag(233, 6);
output.WriteDouble(DoubleField109);
}
if (Int64Field110 != 0L) {
output.WriteRawTag(240, 6);
output.WriteInt64(Int64Field110);
}
if (DoubleField111 != 0D) {
output.WriteRawTag(249, 6);
output.WriteDouble(DoubleField111);
}
if (Int64Field112 != 0L) {
output.WriteRawTag(128, 7);
output.WriteInt64(Int64Field112);
}
if (DoubleField113 != 0D) {
output.WriteRawTag(137, 7);
output.WriteDouble(DoubleField113);
}
if (Int64Field114 != 0L) {
output.WriteRawTag(144, 7);
output.WriteInt64(Int64Field114);
}
if (Int64Field115 != 0L) {
output.WriteRawTag(152, 7);
output.WriteInt64(Int64Field115);
}
if (DoubleField116 != 0D) {
output.WriteRawTag(161, 7);
output.WriteDouble(DoubleField116);
}
if (Int64Field117 != 0L) {
output.WriteRawTag(168, 7);
output.WriteInt64(Int64Field117);
}
if (DoubleField118 != 0D) {
output.WriteRawTag(177, 7);
output.WriteDouble(DoubleField118);
}
if (DoubleField119 != 0D) {
output.WriteRawTag(185, 7);
output.WriteDouble(DoubleField119);
}
if (DoubleField120 != 0D) {
output.WriteRawTag(193, 7);
output.WriteDouble(DoubleField120);
}
if (DoubleField121 != 0D) {
output.WriteRawTag(201, 7);
output.WriteDouble(DoubleField121);
}
if (DoubleField122 != 0D) {
output.WriteRawTag(209, 7);
output.WriteDouble(DoubleField122);
}
if (DoubleField123 != 0D) {
output.WriteRawTag(217, 7);
output.WriteDouble(DoubleField123);
}
if (DoubleField124 != 0D) {
output.WriteRawTag(225, 7);
output.WriteDouble(DoubleField124);
}
if (Int64Field125 != 0L) {
output.WriteRawTag(232, 7);
output.WriteInt64(Int64Field125);
}
if (Int64Field126 != 0L) {
output.WriteRawTag(240, 7);
output.WriteInt64(Int64Field126);
}
if (Int64Field127 != 0L) {
output.WriteRawTag(248, 7);
output.WriteInt64(Int64Field127);
}
if (DoubleField128 != 0D) {
output.WriteRawTag(129, 8);
output.WriteDouble(DoubleField128);
}
if (DoubleField129 != 0D) {
output.WriteRawTag(137, 8);
output.WriteDouble(DoubleField129);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;

@ -0,0 +1,198 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2019 Google Inc. All rights reserved.
// https://github.com/protocolbuffers/protobuf
//
// 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 BenchmarkDotNet.Attributes;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Buffers;
using Google.Protobuf.WellKnownTypes;
namespace Google.Protobuf.Benchmarks
{
/// <summary>
/// Benchmark that tests writing performance for various messages.
/// </summary>
[MemoryDiagnoser]
public class WriteMessagesBenchmark
{
const int MaxMessages = 100;
SubTest manyWrapperFieldsTest = new SubTest(ParseMessagesBenchmark.CreateManyWrapperFieldsMessage(), MaxMessages);
SubTest manyPrimitiveFieldsTest = new SubTest(ParseMessagesBenchmark.CreateManyPrimitiveFieldsMessage(), MaxMessages);
SubTest emptyMessageTest = new SubTest(new Empty(), MaxMessages);
public IEnumerable<int> MessageCountValues => new[] { 10, 100 };
[GlobalSetup]
public void GlobalSetup()
{
}
[Benchmark]
public byte[] ManyWrapperFieldsMessage_ToByteArray()
{
return manyWrapperFieldsTest.ToByteArray();
}
[Benchmark]
public byte[] ManyWrapperFieldsMessage_WriteToCodedOutputStream()
{
return manyWrapperFieldsTest.WriteToCodedOutputStream_PreAllocatedBuffer();
}
[Benchmark]
public byte[] ManyWrapperFieldsMessage_WriteToSpan()
{
return manyWrapperFieldsTest.WriteToSpan_PreAllocatedBuffer();
}
[Benchmark]
public byte[] ManyPrimitiveFieldsMessage_ToByteArray()
{
return manyPrimitiveFieldsTest.ToByteArray();
}
[Benchmark]
public byte[] ManyPrimitiveFieldsMessage_WriteToCodedOutputStream()
{
return manyPrimitiveFieldsTest.WriteToCodedOutputStream_PreAllocatedBuffer();
}
[Benchmark]
public byte[] ManyPrimitiveFieldsMessage_WriteToSpan()
{
return manyPrimitiveFieldsTest.WriteToSpan_PreAllocatedBuffer();
}
[Benchmark]
public byte[] EmptyMessage_ToByteArray()
{
return emptyMessageTest.ToByteArray();
}
[Benchmark]
public byte[] EmptyMessage_WriteToCodedOutputStream()
{
return emptyMessageTest.WriteToCodedOutputStream_PreAllocatedBuffer();
}
[Benchmark]
public byte[] EmptyMessage_WriteToSpan()
{
return emptyMessageTest.WriteToSpan_PreAllocatedBuffer();
}
[Benchmark]
[ArgumentsSource(nameof(MessageCountValues))]
public void ManyWrapperFieldsMessage_WriteDelimitedMessagesToCodedOutputStream(int messageCount)
{
manyWrapperFieldsTest.WriteDelimitedMessagesToCodedOutputStream_PreAllocatedBuffer(messageCount);
}
[Benchmark]
[ArgumentsSource(nameof(MessageCountValues))]
public void ManyWrapperFieldsMessage_WriteDelimitedMessagesToSpan(int messageCount)
{
manyWrapperFieldsTest.WriteDelimitedMessagesToSpan_PreAllocatedBuffer(messageCount);
}
[Benchmark]
[ArgumentsSource(nameof(MessageCountValues))]
public void ManyPrimitiveFieldsMessage_WriteDelimitedMessagesToCodedOutputStream(int messageCount)
{
manyPrimitiveFieldsTest.WriteDelimitedMessagesToCodedOutputStream_PreAllocatedBuffer(messageCount);
}
[Benchmark]
[ArgumentsSource(nameof(MessageCountValues))]
public void ManyPrimitiveFieldsMessage_WriteDelimitedMessagesToSpan(int messageCount)
{
manyPrimitiveFieldsTest.WriteDelimitedMessagesToSpan_PreAllocatedBuffer(messageCount);
}
private class SubTest
{
private readonly IMessage message;
private readonly byte[] outputBuffer;
private readonly byte[] multipleMessagesOutputBuffer;
public SubTest(IMessage message, int maxMessageCount)
{
this.message = message;
int messageSize = message.CalculateSize();
this.outputBuffer = new byte[messageSize];
this.multipleMessagesOutputBuffer = new byte[maxMessageCount * (messageSize + CodedOutputStream.ComputeLengthSize(messageSize))];
}
public byte[] ToByteArray() => message.ToByteArray();
public byte[] WriteToCodedOutputStream_PreAllocatedBuffer()
{
var cos = new CodedOutputStream(outputBuffer); // use pre-existing output buffer
message.WriteTo(cos);
return outputBuffer;
}
public byte[] WriteToSpan_PreAllocatedBuffer()
{
var span = new Span<byte>(outputBuffer); // use pre-existing output buffer
message.WriteTo(span);
return outputBuffer;
}
public byte[] WriteDelimitedMessagesToCodedOutputStream_PreAllocatedBuffer(int messageCount)
{
var cos = new CodedOutputStream(multipleMessagesOutputBuffer); // use pre-existing output buffer
for (int i = 0; i < messageCount; i++)
{
cos.WriteMessage(message);
}
return multipleMessagesOutputBuffer;
}
public byte[] WriteDelimitedMessagesToSpan_PreAllocatedBuffer(int messageCount)
{
var span = new Span<byte>(multipleMessagesOutputBuffer); // use pre-existing output buffer
WriteContext.Initialize(ref span, out WriteContext ctx);
for (int i = 0; i < messageCount; i++)
{
ctx.WriteMessage(message);
}
return multipleMessagesOutputBuffer;
}
}
}
}

@ -0,0 +1,467 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2019 Google Inc. All rights reserved.
// https://github.com/protocolbuffers/protobuf
//
// 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 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
{
/// <summary>
/// Benchmarks throughput when writing raw primitives.
/// </summary>
[MemoryDiagnoser]
public class WriteRawPrimitivesBenchmark
{
// key is the encodedSize of varint values
Dictionary<int, uint[]> varint32Values;
Dictionary<int, ulong[]> varint64Values;
double[] doubleValues;
float[] floatValues;
// key is the encodedSize of string values
Dictionary<int, string[]> stringValues;
// key is the encodedSize of string values
Dictionary<int, string[]> nonAsciiStringValues;
// key is the encodedSize of string values
Dictionary<int, ByteString[]> byteStringValues;
// the buffer to which all the data will be written
byte[] outputBuffer;
Random random = new Random(417384220); // random but deterministic seed
public IEnumerable<int> StringEncodedSizes => new[] { 1, 4, 10, 105, 10080 };
public IEnumerable<int> NonAsciiStringEncodedSizes => new[] { 4, 10, 105, 10080 };
[GlobalSetup]
public void GlobalSetup()
{
outputBuffer = new byte[BytesToWrite];
varint32Values = new Dictionary<int, uint[]>();
varint64Values = new Dictionary<int, ulong[]>();
for (int encodedSize = 1; encodedSize <= 10; encodedSize++)
{
if (encodedSize <= 5)
{
varint32Values.Add(encodedSize, CreateRandomVarints32(random, BytesToWrite / encodedSize, encodedSize));
}
varint64Values.Add(encodedSize, CreateRandomVarints64(random, BytesToWrite / encodedSize, encodedSize));
}
doubleValues = CreateRandomDoubles(random, BytesToWrite / sizeof(double));
floatValues = CreateRandomFloats(random, BytesToWrite / sizeof(float));
stringValues = new Dictionary<int, string[]>();
byteStringValues = new Dictionary<int, ByteString[]>();
foreach(var encodedSize in StringEncodedSizes)
{
stringValues.Add(encodedSize, CreateStrings(BytesToWrite / encodedSize, encodedSize));
byteStringValues.Add(encodedSize, CreateByteStrings(BytesToWrite / encodedSize, encodedSize));
}
nonAsciiStringValues = new Dictionary<int, string[]>();
foreach(var encodedSize in NonAsciiStringEncodedSizes)
{
nonAsciiStringValues.Add(encodedSize, CreateNonAsciiStrings(BytesToWrite / encodedSize, encodedSize));
}
}
// Total number of bytes that each benchmark will write.
// Measuring the time taken to write buffer of given size makes it easier to compare parsing speed for different
// types and makes it easy to calculate the througput (in MB/s)
// 10800 bytes is chosen because it is divisible by all possible encoded sizes for all primitive types {1..10}
[Params(10080)]
public int BytesToWrite { get; set; }
[Benchmark]
[Arguments(1)]
[Arguments(2)]
[Arguments(3)]
[Arguments(4)]
[Arguments(5)]
public void WriteRawVarint32_CodedOutputStream(int encodedSize)
{
var values = varint32Values[encodedSize];
var cos = new CodedOutputStream(outputBuffer);
foreach (var value in values)
{
cos.WriteRawVarint32(value);
}
cos.Flush();
cos.CheckNoSpaceLeft();
}
[Benchmark]
[Arguments(1)]
[Arguments(2)]
[Arguments(3)]
[Arguments(4)]
[Arguments(5)]
public void WriteRawVarint32_WriteContext(int encodedSize)
{
var values = varint32Values[encodedSize];
var span = new Span<byte>(outputBuffer);
WriteContext.Initialize(ref span, out WriteContext ctx);
foreach (var value in values)
{
ctx.WriteUInt32(value);
}
ctx.Flush();
ctx.CheckNoSpaceLeft();
}
[Benchmark]
[Arguments(1)]
[Arguments(2)]
[Arguments(3)]
[Arguments(4)]
[Arguments(5)]
[Arguments(6)]
[Arguments(7)]
[Arguments(8)]
[Arguments(9)]
[Arguments(10)]
public void WriteRawVarint64_CodedOutputStream(int encodedSize)
{
var values = varint64Values[encodedSize];
var cos = new CodedOutputStream(outputBuffer);
foreach (var value in values)
{
cos.WriteRawVarint64(value);
}
cos.Flush();
cos.CheckNoSpaceLeft();
}
[Benchmark]
[Arguments(1)]
[Arguments(2)]
[Arguments(3)]
[Arguments(4)]
[Arguments(5)]
[Arguments(6)]
[Arguments(7)]
[Arguments(8)]
[Arguments(9)]
[Arguments(10)]
public void WriteRawVarint64_WriteContext(int encodedSize)
{
var values = varint64Values[encodedSize];
var span = new Span<byte>(outputBuffer);
WriteContext.Initialize(ref span, out WriteContext ctx);
foreach (var value in values)
{
ctx.WriteUInt64(value);
}
ctx.Flush();
ctx.CheckNoSpaceLeft();
}
[Benchmark]
public void WriteFixed32_CodedOutputStream()
{
const int encodedSize = sizeof(uint);
var cos = new CodedOutputStream(outputBuffer);
for(int i = 0; i < BytesToWrite / encodedSize; i++)
{
cos.WriteFixed32(12345);
}
cos.Flush();
cos.CheckNoSpaceLeft();
}
[Benchmark]
public void WriteFixed32_WriteContext()
{
const int encodedSize = sizeof(uint);
var span = new Span<byte>(outputBuffer);
WriteContext.Initialize(ref span, out WriteContext ctx);
for (uint i = 0; i < BytesToWrite / encodedSize; i++)
{
ctx.WriteFixed32(12345);
}
ctx.Flush();
ctx.CheckNoSpaceLeft();
}
[Benchmark]
public void WriteFixed64_CodedOutputStream()
{
const int encodedSize = sizeof(ulong);
var cos = new CodedOutputStream(outputBuffer);
for(int i = 0; i < BytesToWrite / encodedSize; i++)
{
cos.WriteFixed64(123456789);
}
cos.Flush();
cos.CheckNoSpaceLeft();
}
[Benchmark]
public void WriteFixed64_WriteContext()
{
const int encodedSize = sizeof(ulong);
var span = new Span<byte>(outputBuffer);
WriteContext.Initialize(ref span, out WriteContext ctx);
for (uint i = 0; i < BytesToWrite / encodedSize; i++)
{
ctx.WriteFixed64(123456789);
}
ctx.Flush();
ctx.CheckNoSpaceLeft();
}
[Benchmark]
public void WriteRawFloat_CodedOutputStream()
{
var cos = new CodedOutputStream(outputBuffer);
foreach (var value in floatValues)
{
cos.WriteFloat(value);
}
cos.Flush();
cos.CheckNoSpaceLeft();
}
[Benchmark]
public void WriteRawFloat_WriteContext()
{
var span = new Span<byte>(outputBuffer);
WriteContext.Initialize(ref span, out WriteContext ctx);
foreach (var value in floatValues)
{
ctx.WriteFloat(value);
}
ctx.Flush();
ctx.CheckNoSpaceLeft();
}
[Benchmark]
public void WriteRawDouble_CodedOutputStream()
{
var cos = new CodedOutputStream(outputBuffer);
foreach (var value in doubleValues)
{
cos.WriteDouble(value);
}
cos.Flush();
cos.CheckNoSpaceLeft();
}
[Benchmark]
public void WriteRawDouble_WriteContext()
{
var span = new Span<byte>(outputBuffer);
WriteContext.Initialize(ref span, out WriteContext ctx);
foreach (var value in doubleValues)
{
ctx.WriteDouble(value);
}
ctx.Flush();
ctx.CheckNoSpaceLeft();
}
[Benchmark]
[ArgumentsSource(nameof(StringEncodedSizes))]
public void WriteString_CodedOutputStream(int encodedSize)
{
var values = stringValues[encodedSize];
var cos = new CodedOutputStream(outputBuffer);
foreach (var value in values)
{
cos.WriteString(value);
}
cos.Flush();
cos.CheckNoSpaceLeft();
}
[Benchmark]
[ArgumentsSource(nameof(StringEncodedSizes))]
public void WriteString_WriteContext(int encodedSize)
{
var values = stringValues[encodedSize];
var span = new Span<byte>(outputBuffer);
WriteContext.Initialize(ref span, out WriteContext ctx);
foreach (var value in values)
{
ctx.WriteString(value);
}
ctx.Flush();
ctx.CheckNoSpaceLeft();
}
[Benchmark]
[ArgumentsSource(nameof(NonAsciiStringEncodedSizes))]
public void WriteNonAsciiString_CodedOutputStream(int encodedSize)
{
var values = nonAsciiStringValues[encodedSize];
var cos = new CodedOutputStream(outputBuffer);
foreach (var value in values)
{
cos.WriteString(value);
}
cos.Flush();
cos.CheckNoSpaceLeft();
}
[Benchmark]
[ArgumentsSource(nameof(NonAsciiStringEncodedSizes))]
public void WriteNonAsciiString_WriteContext(int encodedSize)
{
var values = nonAsciiStringValues[encodedSize];
var span = new Span<byte>(outputBuffer);
WriteContext.Initialize(ref span, out WriteContext ctx);
foreach (var value in values)
{
ctx.WriteString(value);
}
ctx.Flush();
ctx.CheckNoSpaceLeft();
}
[Benchmark]
[ArgumentsSource(nameof(StringEncodedSizes))]
public void WriteBytes_CodedOutputStream(int encodedSize)
{
var values = byteStringValues[encodedSize];
var cos = new CodedOutputStream(outputBuffer);
foreach (var value in values)
{
cos.WriteBytes(value);
}
cos.Flush();
cos.CheckNoSpaceLeft();
}
[Benchmark]
[ArgumentsSource(nameof(StringEncodedSizes))]
public void WriteBytes_WriteContext(int encodedSize)
{
var values = byteStringValues[encodedSize];
var span = new Span<byte>(outputBuffer);
WriteContext.Initialize(ref span, out WriteContext ctx);
foreach (var value in values)
{
ctx.WriteBytes(value);
}
ctx.Flush();
ctx.CheckNoSpaceLeft();
}
private static uint[] CreateRandomVarints32(Random random, int valueCount, int encodedSize)
{
var result = new uint[valueCount];
for (int i = 0; i < valueCount; i++)
{
result[i] = (uint) ParseRawPrimitivesBenchmark.RandomUnsignedVarint(random, encodedSize, true);
}
return result;
}
private static ulong[] CreateRandomVarints64(Random random, int valueCount, int encodedSize)
{
var result = new ulong[valueCount];
for (int i = 0; i < valueCount; i++)
{
result[i] = ParseRawPrimitivesBenchmark.RandomUnsignedVarint(random, encodedSize, false);
}
return result;
}
private static float[] CreateRandomFloats(Random random, int valueCount)
{
var result = new float[valueCount];
for (int i = 0; i < valueCount; i++)
{
result[i] = (float)random.NextDouble();
}
return result;
}
private static double[] CreateRandomDoubles(Random random, int valueCount)
{
var result = new double[valueCount];
for (int i = 0; i < valueCount; i++)
{
result[i] = random.NextDouble();
}
return result;
}
private static string[] CreateStrings(int valueCount, int encodedSize)
{
var str = ParseRawPrimitivesBenchmark.CreateStringWithEncodedSize(encodedSize);
var result = new string[valueCount];
for (int i = 0; i < valueCount; i++)
{
result[i] = str;
}
return result;
}
private static string[] CreateNonAsciiStrings(int valueCount, int encodedSize)
{
var str = ParseRawPrimitivesBenchmark.CreateNonAsciiStringWithEncodedSize(encodedSize);
var result = new string[valueCount];
for (int i = 0; i < valueCount; i++)
{
result[i] = str;
}
return result;
}
private static ByteString[] CreateByteStrings(int valueCount, int encodedSize)
{
var str = ParseRawPrimitivesBenchmark.CreateStringWithEncodedSize(encodedSize);
var result = new ByteString[valueCount];
for (int i = 0; i < valueCount; i++)
{
result[i] = ByteString.CopyFrom(Encoding.UTF8.GetBytes(str));
}
return result;
}
}
}

@ -189,11 +189,25 @@ namespace Conformance {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
failure_.WriteTo(output, _repeated_failure_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
failure_.WriteTo(ref output, _repeated_failure_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -513,6 +527,9 @@ namespace Conformance {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (payloadCase_ == PayloadOneofCase.ProtobufPayload) {
output.WriteRawTag(10);
output.WriteBytes(ProtobufPayload);
@ -552,7 +569,53 @@ namespace Conformance {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (payloadCase_ == PayloadOneofCase.ProtobufPayload) {
output.WriteRawTag(10);
output.WriteBytes(ProtobufPayload);
}
if (payloadCase_ == PayloadOneofCase.JsonPayload) {
output.WriteRawTag(18);
output.WriteString(JsonPayload);
}
if (RequestedOutputFormat != global::Conformance.WireFormat.Unspecified) {
output.WriteRawTag(24);
output.WriteEnum((int) RequestedOutputFormat);
}
if (MessageType.Length != 0) {
output.WriteRawTag(34);
output.WriteString(MessageType);
}
if (TestCategory != global::Conformance.TestCategory.UnspecifiedTest) {
output.WriteRawTag(40);
output.WriteEnum((int) TestCategory);
}
if (jspbEncodingOptions_ != null) {
output.WriteRawTag(50);
output.WriteMessage(JspbEncodingOptions);
}
if (payloadCase_ == PayloadOneofCase.JspbPayload) {
output.WriteRawTag(58);
output.WriteString(JspbPayload);
}
if (payloadCase_ == PayloadOneofCase.TextPayload) {
output.WriteRawTag(66);
output.WriteString(TextPayload);
}
if (PrintUnknownFields != false) {
output.WriteRawTag(72);
output.WriteBool(PrintUnknownFields);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -1009,6 +1072,9 @@ namespace Conformance {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (resultCase_ == ResultOneofCase.ParseError) {
output.WriteRawTag(10);
output.WriteString(ParseError);
@ -1044,7 +1110,49 @@ namespace Conformance {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (resultCase_ == ResultOneofCase.ParseError) {
output.WriteRawTag(10);
output.WriteString(ParseError);
}
if (resultCase_ == ResultOneofCase.RuntimeError) {
output.WriteRawTag(18);
output.WriteString(RuntimeError);
}
if (resultCase_ == ResultOneofCase.ProtobufPayload) {
output.WriteRawTag(26);
output.WriteBytes(ProtobufPayload);
}
if (resultCase_ == ResultOneofCase.JsonPayload) {
output.WriteRawTag(34);
output.WriteString(JsonPayload);
}
if (resultCase_ == ResultOneofCase.Skipped) {
output.WriteRawTag(42);
output.WriteString(Skipped);
}
if (resultCase_ == ResultOneofCase.SerializeError) {
output.WriteRawTag(50);
output.WriteString(SerializeError);
}
if (resultCase_ == ResultOneofCase.JspbPayload) {
output.WriteRawTag(58);
output.WriteString(JspbPayload);
}
if (resultCase_ == ResultOneofCase.TextPayload) {
output.WriteRawTag(66);
output.WriteString(TextPayload);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -1299,6 +1407,9 @@ namespace Conformance {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (UseJspbArrayAnyFormat != false) {
output.WriteRawTag(8);
output.WriteBool(UseJspbArrayAnyFormat);
@ -1306,7 +1417,21 @@ namespace Conformance {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (UseJspbArrayAnyFormat != false) {
output.WriteRawTag(8);
output.WriteBool(UseJspbArrayAnyFormat);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {

@ -466,6 +466,9 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
mapInt32Int32_.WriteTo(output, _map_mapInt32Int32_codec);
mapInt64Int64_.WriteTo(output, _map_mapInt64Int64_codec);
mapUint32Uint32_.WriteTo(output, _map_mapUint32Uint32_codec);
@ -486,7 +489,34 @@ namespace Google.Protobuf.TestProtos {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
mapInt32Int32_.WriteTo(ref output, _map_mapInt32Int32_codec);
mapInt64Int64_.WriteTo(ref output, _map_mapInt64Int64_codec);
mapUint32Uint32_.WriteTo(ref output, _map_mapUint32Uint32_codec);
mapUint64Uint64_.WriteTo(ref output, _map_mapUint64Uint64_codec);
mapSint32Sint32_.WriteTo(ref output, _map_mapSint32Sint32_codec);
mapSint64Sint64_.WriteTo(ref output, _map_mapSint64Sint64_codec);
mapFixed32Fixed32_.WriteTo(ref output, _map_mapFixed32Fixed32_codec);
mapFixed64Fixed64_.WriteTo(ref output, _map_mapFixed64Fixed64_codec);
mapSfixed32Sfixed32_.WriteTo(ref output, _map_mapSfixed32Sfixed32_codec);
mapSfixed64Sfixed64_.WriteTo(ref output, _map_mapSfixed64Sfixed64_codec);
mapInt32Float_.WriteTo(ref output, _map_mapInt32Float_codec);
mapInt32Double_.WriteTo(ref output, _map_mapInt32Double_codec);
mapBoolBool_.WriteTo(ref output, _map_mapBoolBool_codec);
mapStringString_.WriteTo(ref output, _map_mapStringString_codec);
mapInt32Bytes_.WriteTo(ref output, _map_mapInt32Bytes_codec);
mapInt32Enum_.WriteTo(ref output, _map_mapInt32Enum_codec);
mapInt32ForeignMessage_.WriteTo(ref output, _map_mapInt32ForeignMessage_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -790,6 +820,9 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (testMap_ != null) {
output.WriteRawTag(10);
output.WriteMessage(TestMap);
@ -797,8 +830,22 @@ namespace Google.Protobuf.TestProtos {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (testMap_ != null) {
output.WriteRawTag(10);
output.WriteMessage(TestMap);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -953,11 +1000,25 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
mapInt32Message_.WriteTo(output, _map_mapInt32Message_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
mapInt32Message_.WriteTo(ref output, _map_mapInt32Message_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -1116,12 +1177,27 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
map1_.WriteTo(output, _map_map1_codec);
map2_.WriteTo(output, _map_map2_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
map1_.WriteTo(ref output, _map_map1_codec);
map2_.WriteTo(ref output, _map_map2_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -1456,6 +1532,9 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
mapInt32Int32_.WriteTo(output, _map_mapInt32Int32_codec);
mapInt64Int64_.WriteTo(output, _map_mapInt64Int64_codec);
mapUint32Uint32_.WriteTo(output, _map_mapUint32Uint32_codec);
@ -1474,8 +1553,33 @@ namespace Google.Protobuf.TestProtos {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
mapInt32Int32_.WriteTo(ref output, _map_mapInt32Int32_codec);
mapInt64Int64_.WriteTo(ref output, _map_mapInt64Int64_codec);
mapUint32Uint32_.WriteTo(ref output, _map_mapUint32Uint32_codec);
mapUint64Uint64_.WriteTo(ref output, _map_mapUint64Uint64_codec);
mapSint32Sint32_.WriteTo(ref output, _map_mapSint32Sint32_codec);
mapSint64Sint64_.WriteTo(ref output, _map_mapSint64Sint64_codec);
mapFixed32Fixed32_.WriteTo(ref output, _map_mapFixed32Fixed32_codec);
mapFixed64Fixed64_.WriteTo(ref output, _map_mapFixed64Fixed64_codec);
mapSfixed32Sfixed32_.WriteTo(ref output, _map_mapSfixed32Sfixed32_codec);
mapSfixed64Sfixed64_.WriteTo(ref output, _map_mapSfixed64Sfixed64_codec);
mapInt32Float_.WriteTo(ref output, _map_mapInt32Float_codec);
mapInt32Double_.WriteTo(ref output, _map_mapInt32Double_codec);
mapBoolBool_.WriteTo(ref output, _map_mapBoolBool_codec);
mapInt32Enum_.WriteTo(ref output, _map_mapInt32Enum_codec);
mapInt32ForeignMessage_.WriteTo(ref output, _map_mapInt32ForeignMessage_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -1761,12 +1865,26 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
type_.WriteTo(output, _map_type_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
type_.WriteTo(ref output, _map_type_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -1922,12 +2040,26 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
entry_.WriteTo(output, _map_entry_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
entry_.WriteTo(ref output, _map_entry_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;

@ -2561,6 +2561,9 @@ namespace ProtobufTestMessages.Proto2 {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (HasOptionalInt32) {
output.WriteRawTag(8);
output.WriteInt32(OptionalInt32);
@ -2836,7 +2839,289 @@ namespace ProtobufTestMessages.Proto2 {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (HasOptionalInt32) {
output.WriteRawTag(8);
output.WriteInt32(OptionalInt32);
}
if (HasOptionalInt64) {
output.WriteRawTag(16);
output.WriteInt64(OptionalInt64);
}
if (HasOptionalUint32) {
output.WriteRawTag(24);
output.WriteUInt32(OptionalUint32);
}
if (HasOptionalUint64) {
output.WriteRawTag(32);
output.WriteUInt64(OptionalUint64);
}
if (HasOptionalSint32) {
output.WriteRawTag(40);
output.WriteSInt32(OptionalSint32);
}
if (HasOptionalSint64) {
output.WriteRawTag(48);
output.WriteSInt64(OptionalSint64);
}
if (HasOptionalFixed32) {
output.WriteRawTag(61);
output.WriteFixed32(OptionalFixed32);
}
if (HasOptionalFixed64) {
output.WriteRawTag(65);
output.WriteFixed64(OptionalFixed64);
}
if (HasOptionalSfixed32) {
output.WriteRawTag(77);
output.WriteSFixed32(OptionalSfixed32);
}
if (HasOptionalSfixed64) {
output.WriteRawTag(81);
output.WriteSFixed64(OptionalSfixed64);
}
if (HasOptionalFloat) {
output.WriteRawTag(93);
output.WriteFloat(OptionalFloat);
}
if (HasOptionalDouble) {
output.WriteRawTag(97);
output.WriteDouble(OptionalDouble);
}
if (HasOptionalBool) {
output.WriteRawTag(104);
output.WriteBool(OptionalBool);
}
if (HasOptionalString) {
output.WriteRawTag(114);
output.WriteString(OptionalString);
}
if (HasOptionalBytes) {
output.WriteRawTag(122);
output.WriteBytes(OptionalBytes);
}
if (optionalNestedMessage_ != null) {
output.WriteRawTag(146, 1);
output.WriteMessage(OptionalNestedMessage);
}
if (optionalForeignMessage_ != null) {
output.WriteRawTag(154, 1);
output.WriteMessage(OptionalForeignMessage);
}
if (HasOptionalNestedEnum) {
output.WriteRawTag(168, 1);
output.WriteEnum((int) OptionalNestedEnum);
}
if (HasOptionalForeignEnum) {
output.WriteRawTag(176, 1);
output.WriteEnum((int) OptionalForeignEnum);
}
if (HasOptionalStringPiece) {
output.WriteRawTag(194, 1);
output.WriteString(OptionalStringPiece);
}
if (HasOptionalCord) {
output.WriteRawTag(202, 1);
output.WriteString(OptionalCord);
}
if (recursiveMessage_ != null) {
output.WriteRawTag(218, 1);
output.WriteMessage(RecursiveMessage);
}
repeatedInt32_.WriteTo(ref output, _repeated_repeatedInt32_codec);
repeatedInt64_.WriteTo(ref output, _repeated_repeatedInt64_codec);
repeatedUint32_.WriteTo(ref output, _repeated_repeatedUint32_codec);
repeatedUint64_.WriteTo(ref output, _repeated_repeatedUint64_codec);
repeatedSint32_.WriteTo(ref output, _repeated_repeatedSint32_codec);
repeatedSint64_.WriteTo(ref output, _repeated_repeatedSint64_codec);
repeatedFixed32_.WriteTo(ref output, _repeated_repeatedFixed32_codec);
repeatedFixed64_.WriteTo(ref output, _repeated_repeatedFixed64_codec);
repeatedSfixed32_.WriteTo(ref output, _repeated_repeatedSfixed32_codec);
repeatedSfixed64_.WriteTo(ref output, _repeated_repeatedSfixed64_codec);
repeatedFloat_.WriteTo(ref output, _repeated_repeatedFloat_codec);
repeatedDouble_.WriteTo(ref output, _repeated_repeatedDouble_codec);
repeatedBool_.WriteTo(ref output, _repeated_repeatedBool_codec);
repeatedString_.WriteTo(ref output, _repeated_repeatedString_codec);
repeatedBytes_.WriteTo(ref output, _repeated_repeatedBytes_codec);
repeatedNestedMessage_.WriteTo(ref output, _repeated_repeatedNestedMessage_codec);
repeatedForeignMessage_.WriteTo(ref output, _repeated_repeatedForeignMessage_codec);
repeatedNestedEnum_.WriteTo(ref output, _repeated_repeatedNestedEnum_codec);
repeatedForeignEnum_.WriteTo(ref output, _repeated_repeatedForeignEnum_codec);
repeatedStringPiece_.WriteTo(ref output, _repeated_repeatedStringPiece_codec);
repeatedCord_.WriteTo(ref output, _repeated_repeatedCord_codec);
mapInt32Int32_.WriteTo(ref output, _map_mapInt32Int32_codec);
mapInt64Int64_.WriteTo(ref output, _map_mapInt64Int64_codec);
mapUint32Uint32_.WriteTo(ref output, _map_mapUint32Uint32_codec);
mapUint64Uint64_.WriteTo(ref output, _map_mapUint64Uint64_codec);
mapSint32Sint32_.WriteTo(ref output, _map_mapSint32Sint32_codec);
mapSint64Sint64_.WriteTo(ref output, _map_mapSint64Sint64_codec);
mapFixed32Fixed32_.WriteTo(ref output, _map_mapFixed32Fixed32_codec);
mapFixed64Fixed64_.WriteTo(ref output, _map_mapFixed64Fixed64_codec);
mapSfixed32Sfixed32_.WriteTo(ref output, _map_mapSfixed32Sfixed32_codec);
mapSfixed64Sfixed64_.WriteTo(ref output, _map_mapSfixed64Sfixed64_codec);
mapInt32Float_.WriteTo(ref output, _map_mapInt32Float_codec);
mapInt32Double_.WriteTo(ref output, _map_mapInt32Double_codec);
mapBoolBool_.WriteTo(ref output, _map_mapBoolBool_codec);
mapStringString_.WriteTo(ref output, _map_mapStringString_codec);
mapStringBytes_.WriteTo(ref output, _map_mapStringBytes_codec);
mapStringNestedMessage_.WriteTo(ref output, _map_mapStringNestedMessage_codec);
mapStringForeignMessage_.WriteTo(ref output, _map_mapStringForeignMessage_codec);
mapStringNestedEnum_.WriteTo(ref output, _map_mapStringNestedEnum_codec);
mapStringForeignEnum_.WriteTo(ref output, _map_mapStringForeignEnum_codec);
packedInt32_.WriteTo(ref output, _repeated_packedInt32_codec);
packedInt64_.WriteTo(ref output, _repeated_packedInt64_codec);
packedUint32_.WriteTo(ref output, _repeated_packedUint32_codec);
packedUint64_.WriteTo(ref output, _repeated_packedUint64_codec);
packedSint32_.WriteTo(ref output, _repeated_packedSint32_codec);
packedSint64_.WriteTo(ref output, _repeated_packedSint64_codec);
packedFixed32_.WriteTo(ref output, _repeated_packedFixed32_codec);
packedFixed64_.WriteTo(ref output, _repeated_packedFixed64_codec);
packedSfixed32_.WriteTo(ref output, _repeated_packedSfixed32_codec);
packedSfixed64_.WriteTo(ref output, _repeated_packedSfixed64_codec);
packedFloat_.WriteTo(ref output, _repeated_packedFloat_codec);
packedDouble_.WriteTo(ref output, _repeated_packedDouble_codec);
packedBool_.WriteTo(ref output, _repeated_packedBool_codec);
packedNestedEnum_.WriteTo(ref output, _repeated_packedNestedEnum_codec);
unpackedInt32_.WriteTo(ref output, _repeated_unpackedInt32_codec);
unpackedInt64_.WriteTo(ref output, _repeated_unpackedInt64_codec);
unpackedUint32_.WriteTo(ref output, _repeated_unpackedUint32_codec);
unpackedUint64_.WriteTo(ref output, _repeated_unpackedUint64_codec);
unpackedSint32_.WriteTo(ref output, _repeated_unpackedSint32_codec);
unpackedSint64_.WriteTo(ref output, _repeated_unpackedSint64_codec);
unpackedFixed32_.WriteTo(ref output, _repeated_unpackedFixed32_codec);
unpackedFixed64_.WriteTo(ref output, _repeated_unpackedFixed64_codec);
unpackedSfixed32_.WriteTo(ref output, _repeated_unpackedSfixed32_codec);
unpackedSfixed64_.WriteTo(ref output, _repeated_unpackedSfixed64_codec);
unpackedFloat_.WriteTo(ref output, _repeated_unpackedFloat_codec);
unpackedDouble_.WriteTo(ref output, _repeated_unpackedDouble_codec);
unpackedBool_.WriteTo(ref output, _repeated_unpackedBool_codec);
unpackedNestedEnum_.WriteTo(ref output, _repeated_unpackedNestedEnum_codec);
if (HasOneofUint32) {
output.WriteRawTag(248, 6);
output.WriteUInt32(OneofUint32);
}
if (oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage) {
output.WriteRawTag(130, 7);
output.WriteMessage(OneofNestedMessage);
}
if (HasOneofString) {
output.WriteRawTag(138, 7);
output.WriteString(OneofString);
}
if (HasOneofBytes) {
output.WriteRawTag(146, 7);
output.WriteBytes(OneofBytes);
}
if (HasOneofBool) {
output.WriteRawTag(152, 7);
output.WriteBool(OneofBool);
}
if (HasOneofUint64) {
output.WriteRawTag(160, 7);
output.WriteUInt64(OneofUint64);
}
if (HasOneofFloat) {
output.WriteRawTag(173, 7);
output.WriteFloat(OneofFloat);
}
if (HasOneofDouble) {
output.WriteRawTag(177, 7);
output.WriteDouble(OneofDouble);
}
if (HasOneofEnum) {
output.WriteRawTag(184, 7);
output.WriteEnum((int) OneofEnum);
}
if (HasData) {
output.WriteRawTag(203, 12);
output.WriteGroup(Data);
output.WriteRawTag(204, 12);
}
if (HasFieldname1) {
output.WriteRawTag(136, 25);
output.WriteInt32(Fieldname1);
}
if (HasFieldName2) {
output.WriteRawTag(144, 25);
output.WriteInt32(FieldName2);
}
if (HasFieldName3) {
output.WriteRawTag(152, 25);
output.WriteInt32(FieldName3);
}
if (HasFieldName4) {
output.WriteRawTag(160, 25);
output.WriteInt32(FieldName4);
}
if (HasField0Name5) {
output.WriteRawTag(168, 25);
output.WriteInt32(Field0Name5);
}
if (HasField0Name6) {
output.WriteRawTag(176, 25);
output.WriteInt32(Field0Name6);
}
if (HasFieldName7) {
output.WriteRawTag(184, 25);
output.WriteInt32(FieldName7);
}
if (HasFieldName8) {
output.WriteRawTag(192, 25);
output.WriteInt32(FieldName8);
}
if (HasFieldName9) {
output.WriteRawTag(200, 25);
output.WriteInt32(FieldName9);
}
if (HasFieldName10) {
output.WriteRawTag(208, 25);
output.WriteInt32(FieldName10);
}
if (HasFIELDNAME11) {
output.WriteRawTag(216, 25);
output.WriteInt32(FIELDNAME11);
}
if (HasFIELDName12) {
output.WriteRawTag(224, 25);
output.WriteInt32(FIELDName12);
}
if (HasFieldName13) {
output.WriteRawTag(232, 25);
output.WriteInt32(FieldName13);
}
if (HasFieldName14) {
output.WriteRawTag(240, 25);
output.WriteInt32(FieldName14);
}
if (HasFieldName15) {
output.WriteRawTag(248, 25);
output.WriteInt32(FieldName15);
}
if (HasFieldName16) {
output.WriteRawTag(128, 26);
output.WriteInt32(FieldName16);
}
if (HasFieldName17) {
output.WriteRawTag(136, 26);
output.WriteInt32(FieldName17);
}
if (HasFieldName18) {
output.WriteRawTag(144, 26);
output.WriteInt32(FieldName18);
}
if (_extensions != null) {
_extensions.WriteTo(ref output);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -4561,6 +4846,9 @@ namespace ProtobufTestMessages.Proto2 {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (HasA) {
output.WriteRawTag(8);
output.WriteInt32(A);
@ -4572,8 +4860,26 @@ namespace ProtobufTestMessages.Proto2 {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (HasA) {
output.WriteRawTag(8);
output.WriteInt32(A);
}
if (corecursive_ != null) {
output.WriteRawTag(18);
output.WriteMessage(Corecursive);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -4788,6 +5094,9 @@ namespace ProtobufTestMessages.Proto2 {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (HasGroupInt32) {
output.WriteRawTag(208, 12);
output.WriteInt32(GroupInt32);
@ -4799,8 +5108,26 @@ namespace ProtobufTestMessages.Proto2 {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (HasGroupInt32) {
output.WriteRawTag(208, 12);
output.WriteInt32(GroupInt32);
}
if (HasGroupUint32) {
output.WriteRawTag(216, 12);
output.WriteUInt32(GroupUint32);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -4963,13 +5290,29 @@ namespace ProtobufTestMessages.Proto2 {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (_extensions != null) {
_extensions.WriteTo(output);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (_extensions != null) {
_extensions.WriteTo(ref output);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -5145,6 +5488,9 @@ namespace ProtobufTestMessages.Proto2 {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (HasStr) {
output.WriteRawTag(202, 1);
output.WriteString(Str);
@ -5152,7 +5498,21 @@ namespace ProtobufTestMessages.Proto2 {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (HasStr) {
output.WriteRawTag(202, 1);
output.WriteString(Str);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -5324,6 +5684,9 @@ namespace ProtobufTestMessages.Proto2 {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (HasI) {
output.WriteRawTag(72);
output.WriteInt32(I);
@ -5331,7 +5694,21 @@ namespace ProtobufTestMessages.Proto2 {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (HasI) {
output.WriteRawTag(72);
output.WriteInt32(I);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -5508,6 +5885,9 @@ namespace ProtobufTestMessages.Proto2 {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (HasC) {
output.WriteRawTag(8);
output.WriteInt32(C);
@ -5515,7 +5895,21 @@ namespace ProtobufTestMessages.Proto2 {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (HasC) {
output.WriteRawTag(8);
output.WriteInt32(C);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -5782,6 +6176,9 @@ namespace ProtobufTestMessages.Proto2 {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (HasOptionalInt32) {
output.WriteRawTag(200, 62);
output.WriteInt32(OptionalInt32);
@ -5807,8 +6204,40 @@ namespace ProtobufTestMessages.Proto2 {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (HasOptionalInt32) {
output.WriteRawTag(200, 62);
output.WriteInt32(OptionalInt32);
}
if (HasOptionalString) {
output.WriteRawTag(210, 62);
output.WriteString(OptionalString);
}
if (nestedMessage_ != null) {
output.WriteRawTag(218, 62);
output.WriteMessage(NestedMessage);
}
if (HasOptionalGroup) {
output.WriteRawTag(227, 62);
output.WriteGroup(OptionalGroup);
output.WriteRawTag(228, 62);
}
if (HasOptionalBool) {
output.WriteRawTag(240, 62);
output.WriteBool(OptionalBool);
}
repeatedInt32_.WriteTo(ref output, _repeated_repeatedInt32_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -6058,6 +6487,9 @@ namespace ProtobufTestMessages.Proto2 {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (HasA) {
output.WriteRawTag(8);
output.WriteInt32(A);
@ -6065,8 +6497,22 @@ namespace ProtobufTestMessages.Proto2 {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (HasA) {
output.WriteRawTag(8);
output.WriteInt32(A);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;

@ -2419,6 +2419,9 @@ namespace ProtobufTestMessages.Proto3 {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (OptionalInt32 != 0) {
output.WriteRawTag(8);
output.WriteInt32(OptionalInt32);
@ -2757,8 +2760,353 @@ namespace ProtobufTestMessages.Proto3 {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (OptionalInt32 != 0) {
output.WriteRawTag(8);
output.WriteInt32(OptionalInt32);
}
if (OptionalInt64 != 0L) {
output.WriteRawTag(16);
output.WriteInt64(OptionalInt64);
}
if (OptionalUint32 != 0) {
output.WriteRawTag(24);
output.WriteUInt32(OptionalUint32);
}
if (OptionalUint64 != 0UL) {
output.WriteRawTag(32);
output.WriteUInt64(OptionalUint64);
}
if (OptionalSint32 != 0) {
output.WriteRawTag(40);
output.WriteSInt32(OptionalSint32);
}
if (OptionalSint64 != 0L) {
output.WriteRawTag(48);
output.WriteSInt64(OptionalSint64);
}
if (OptionalFixed32 != 0) {
output.WriteRawTag(61);
output.WriteFixed32(OptionalFixed32);
}
if (OptionalFixed64 != 0UL) {
output.WriteRawTag(65);
output.WriteFixed64(OptionalFixed64);
}
if (OptionalSfixed32 != 0) {
output.WriteRawTag(77);
output.WriteSFixed32(OptionalSfixed32);
}
if (OptionalSfixed64 != 0L) {
output.WriteRawTag(81);
output.WriteSFixed64(OptionalSfixed64);
}
if (OptionalFloat != 0F) {
output.WriteRawTag(93);
output.WriteFloat(OptionalFloat);
}
if (OptionalDouble != 0D) {
output.WriteRawTag(97);
output.WriteDouble(OptionalDouble);
}
if (OptionalBool != false) {
output.WriteRawTag(104);
output.WriteBool(OptionalBool);
}
if (OptionalString.Length != 0) {
output.WriteRawTag(114);
output.WriteString(OptionalString);
}
if (OptionalBytes.Length != 0) {
output.WriteRawTag(122);
output.WriteBytes(OptionalBytes);
}
if (optionalNestedMessage_ != null) {
output.WriteRawTag(146, 1);
output.WriteMessage(OptionalNestedMessage);
}
if (optionalForeignMessage_ != null) {
output.WriteRawTag(154, 1);
output.WriteMessage(OptionalForeignMessage);
}
if (OptionalNestedEnum != global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedEnum.Foo) {
output.WriteRawTag(168, 1);
output.WriteEnum((int) OptionalNestedEnum);
}
if (OptionalForeignEnum != global::ProtobufTestMessages.Proto3.ForeignEnum.ForeignFoo) {
output.WriteRawTag(176, 1);
output.WriteEnum((int) OptionalForeignEnum);
}
if (OptionalAliasedEnum != global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.AliasedEnum.AliasFoo) {
output.WriteRawTag(184, 1);
output.WriteEnum((int) OptionalAliasedEnum);
}
if (OptionalStringPiece.Length != 0) {
output.WriteRawTag(194, 1);
output.WriteString(OptionalStringPiece);
}
if (OptionalCord.Length != 0) {
output.WriteRawTag(202, 1);
output.WriteString(OptionalCord);
}
if (recursiveMessage_ != null) {
output.WriteRawTag(218, 1);
output.WriteMessage(RecursiveMessage);
}
repeatedInt32_.WriteTo(ref output, _repeated_repeatedInt32_codec);
repeatedInt64_.WriteTo(ref output, _repeated_repeatedInt64_codec);
repeatedUint32_.WriteTo(ref output, _repeated_repeatedUint32_codec);
repeatedUint64_.WriteTo(ref output, _repeated_repeatedUint64_codec);
repeatedSint32_.WriteTo(ref output, _repeated_repeatedSint32_codec);
repeatedSint64_.WriteTo(ref output, _repeated_repeatedSint64_codec);
repeatedFixed32_.WriteTo(ref output, _repeated_repeatedFixed32_codec);
repeatedFixed64_.WriteTo(ref output, _repeated_repeatedFixed64_codec);
repeatedSfixed32_.WriteTo(ref output, _repeated_repeatedSfixed32_codec);
repeatedSfixed64_.WriteTo(ref output, _repeated_repeatedSfixed64_codec);
repeatedFloat_.WriteTo(ref output, _repeated_repeatedFloat_codec);
repeatedDouble_.WriteTo(ref output, _repeated_repeatedDouble_codec);
repeatedBool_.WriteTo(ref output, _repeated_repeatedBool_codec);
repeatedString_.WriteTo(ref output, _repeated_repeatedString_codec);
repeatedBytes_.WriteTo(ref output, _repeated_repeatedBytes_codec);
repeatedNestedMessage_.WriteTo(ref output, _repeated_repeatedNestedMessage_codec);
repeatedForeignMessage_.WriteTo(ref output, _repeated_repeatedForeignMessage_codec);
repeatedNestedEnum_.WriteTo(ref output, _repeated_repeatedNestedEnum_codec);
repeatedForeignEnum_.WriteTo(ref output, _repeated_repeatedForeignEnum_codec);
repeatedStringPiece_.WriteTo(ref output, _repeated_repeatedStringPiece_codec);
repeatedCord_.WriteTo(ref output, _repeated_repeatedCord_codec);
mapInt32Int32_.WriteTo(ref output, _map_mapInt32Int32_codec);
mapInt64Int64_.WriteTo(ref output, _map_mapInt64Int64_codec);
mapUint32Uint32_.WriteTo(ref output, _map_mapUint32Uint32_codec);
mapUint64Uint64_.WriteTo(ref output, _map_mapUint64Uint64_codec);
mapSint32Sint32_.WriteTo(ref output, _map_mapSint32Sint32_codec);
mapSint64Sint64_.WriteTo(ref output, _map_mapSint64Sint64_codec);
mapFixed32Fixed32_.WriteTo(ref output, _map_mapFixed32Fixed32_codec);
mapFixed64Fixed64_.WriteTo(ref output, _map_mapFixed64Fixed64_codec);
mapSfixed32Sfixed32_.WriteTo(ref output, _map_mapSfixed32Sfixed32_codec);
mapSfixed64Sfixed64_.WriteTo(ref output, _map_mapSfixed64Sfixed64_codec);
mapInt32Float_.WriteTo(ref output, _map_mapInt32Float_codec);
mapInt32Double_.WriteTo(ref output, _map_mapInt32Double_codec);
mapBoolBool_.WriteTo(ref output, _map_mapBoolBool_codec);
mapStringString_.WriteTo(ref output, _map_mapStringString_codec);
mapStringBytes_.WriteTo(ref output, _map_mapStringBytes_codec);
mapStringNestedMessage_.WriteTo(ref output, _map_mapStringNestedMessage_codec);
mapStringForeignMessage_.WriteTo(ref output, _map_mapStringForeignMessage_codec);
mapStringNestedEnum_.WriteTo(ref output, _map_mapStringNestedEnum_codec);
mapStringForeignEnum_.WriteTo(ref output, _map_mapStringForeignEnum_codec);
packedInt32_.WriteTo(ref output, _repeated_packedInt32_codec);
packedInt64_.WriteTo(ref output, _repeated_packedInt64_codec);
packedUint32_.WriteTo(ref output, _repeated_packedUint32_codec);
packedUint64_.WriteTo(ref output, _repeated_packedUint64_codec);
packedSint32_.WriteTo(ref output, _repeated_packedSint32_codec);
packedSint64_.WriteTo(ref output, _repeated_packedSint64_codec);
packedFixed32_.WriteTo(ref output, _repeated_packedFixed32_codec);
packedFixed64_.WriteTo(ref output, _repeated_packedFixed64_codec);
packedSfixed32_.WriteTo(ref output, _repeated_packedSfixed32_codec);
packedSfixed64_.WriteTo(ref output, _repeated_packedSfixed64_codec);
packedFloat_.WriteTo(ref output, _repeated_packedFloat_codec);
packedDouble_.WriteTo(ref output, _repeated_packedDouble_codec);
packedBool_.WriteTo(ref output, _repeated_packedBool_codec);
packedNestedEnum_.WriteTo(ref output, _repeated_packedNestedEnum_codec);
unpackedInt32_.WriteTo(ref output, _repeated_unpackedInt32_codec);
unpackedInt64_.WriteTo(ref output, _repeated_unpackedInt64_codec);
unpackedUint32_.WriteTo(ref output, _repeated_unpackedUint32_codec);
unpackedUint64_.WriteTo(ref output, _repeated_unpackedUint64_codec);
unpackedSint32_.WriteTo(ref output, _repeated_unpackedSint32_codec);
unpackedSint64_.WriteTo(ref output, _repeated_unpackedSint64_codec);
unpackedFixed32_.WriteTo(ref output, _repeated_unpackedFixed32_codec);
unpackedFixed64_.WriteTo(ref output, _repeated_unpackedFixed64_codec);
unpackedSfixed32_.WriteTo(ref output, _repeated_unpackedSfixed32_codec);
unpackedSfixed64_.WriteTo(ref output, _repeated_unpackedSfixed64_codec);
unpackedFloat_.WriteTo(ref output, _repeated_unpackedFloat_codec);
unpackedDouble_.WriteTo(ref output, _repeated_unpackedDouble_codec);
unpackedBool_.WriteTo(ref output, _repeated_unpackedBool_codec);
unpackedNestedEnum_.WriteTo(ref output, _repeated_unpackedNestedEnum_codec);
if (oneofFieldCase_ == OneofFieldOneofCase.OneofUint32) {
output.WriteRawTag(248, 6);
output.WriteUInt32(OneofUint32);
}
if (oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage) {
output.WriteRawTag(130, 7);
output.WriteMessage(OneofNestedMessage);
}
if (oneofFieldCase_ == OneofFieldOneofCase.OneofString) {
output.WriteRawTag(138, 7);
output.WriteString(OneofString);
}
if (oneofFieldCase_ == OneofFieldOneofCase.OneofBytes) {
output.WriteRawTag(146, 7);
output.WriteBytes(OneofBytes);
}
if (oneofFieldCase_ == OneofFieldOneofCase.OneofBool) {
output.WriteRawTag(152, 7);
output.WriteBool(OneofBool);
}
if (oneofFieldCase_ == OneofFieldOneofCase.OneofUint64) {
output.WriteRawTag(160, 7);
output.WriteUInt64(OneofUint64);
}
if (oneofFieldCase_ == OneofFieldOneofCase.OneofFloat) {
output.WriteRawTag(173, 7);
output.WriteFloat(OneofFloat);
}
if (oneofFieldCase_ == OneofFieldOneofCase.OneofDouble) {
output.WriteRawTag(177, 7);
output.WriteDouble(OneofDouble);
}
if (oneofFieldCase_ == OneofFieldOneofCase.OneofEnum) {
output.WriteRawTag(184, 7);
output.WriteEnum((int) OneofEnum);
}
if (optionalBoolWrapper_ != null) {
_single_optionalBoolWrapper_codec.WriteTagAndValue(ref output, OptionalBoolWrapper);
}
if (optionalInt32Wrapper_ != null) {
_single_optionalInt32Wrapper_codec.WriteTagAndValue(ref output, OptionalInt32Wrapper);
}
if (optionalInt64Wrapper_ != null) {
_single_optionalInt64Wrapper_codec.WriteTagAndValue(ref output, OptionalInt64Wrapper);
}
if (optionalUint32Wrapper_ != null) {
_single_optionalUint32Wrapper_codec.WriteTagAndValue(ref output, OptionalUint32Wrapper);
}
if (optionalUint64Wrapper_ != null) {
_single_optionalUint64Wrapper_codec.WriteTagAndValue(ref output, OptionalUint64Wrapper);
}
if (optionalFloatWrapper_ != null) {
_single_optionalFloatWrapper_codec.WriteTagAndValue(ref output, OptionalFloatWrapper);
}
if (optionalDoubleWrapper_ != null) {
_single_optionalDoubleWrapper_codec.WriteTagAndValue(ref output, OptionalDoubleWrapper);
}
if (optionalStringWrapper_ != null) {
_single_optionalStringWrapper_codec.WriteTagAndValue(ref output, OptionalStringWrapper);
}
if (optionalBytesWrapper_ != null) {
_single_optionalBytesWrapper_codec.WriteTagAndValue(ref output, OptionalBytesWrapper);
}
repeatedBoolWrapper_.WriteTo(ref output, _repeated_repeatedBoolWrapper_codec);
repeatedInt32Wrapper_.WriteTo(ref output, _repeated_repeatedInt32Wrapper_codec);
repeatedInt64Wrapper_.WriteTo(ref output, _repeated_repeatedInt64Wrapper_codec);
repeatedUint32Wrapper_.WriteTo(ref output, _repeated_repeatedUint32Wrapper_codec);
repeatedUint64Wrapper_.WriteTo(ref output, _repeated_repeatedUint64Wrapper_codec);
repeatedFloatWrapper_.WriteTo(ref output, _repeated_repeatedFloatWrapper_codec);
repeatedDoubleWrapper_.WriteTo(ref output, _repeated_repeatedDoubleWrapper_codec);
repeatedStringWrapper_.WriteTo(ref output, _repeated_repeatedStringWrapper_codec);
repeatedBytesWrapper_.WriteTo(ref output, _repeated_repeatedBytesWrapper_codec);
if (optionalDuration_ != null) {
output.WriteRawTag(234, 18);
output.WriteMessage(OptionalDuration);
}
if (optionalTimestamp_ != null) {
output.WriteRawTag(242, 18);
output.WriteMessage(OptionalTimestamp);
}
if (optionalFieldMask_ != null) {
output.WriteRawTag(250, 18);
output.WriteMessage(OptionalFieldMask);
}
if (optionalStruct_ != null) {
output.WriteRawTag(130, 19);
output.WriteMessage(OptionalStruct);
}
if (optionalAny_ != null) {
output.WriteRawTag(138, 19);
output.WriteMessage(OptionalAny);
}
if (optionalValue_ != null) {
output.WriteRawTag(146, 19);
output.WriteMessage(OptionalValue);
}
repeatedDuration_.WriteTo(ref output, _repeated_repeatedDuration_codec);
repeatedTimestamp_.WriteTo(ref output, _repeated_repeatedTimestamp_codec);
repeatedFieldmask_.WriteTo(ref output, _repeated_repeatedFieldmask_codec);
repeatedAny_.WriteTo(ref output, _repeated_repeatedAny_codec);
repeatedValue_.WriteTo(ref output, _repeated_repeatedValue_codec);
repeatedListValue_.WriteTo(ref output, _repeated_repeatedListValue_codec);
repeatedStruct_.WriteTo(ref output, _repeated_repeatedStruct_codec);
if (Fieldname1 != 0) {
output.WriteRawTag(136, 25);
output.WriteInt32(Fieldname1);
}
if (FieldName2 != 0) {
output.WriteRawTag(144, 25);
output.WriteInt32(FieldName2);
}
if (FieldName3 != 0) {
output.WriteRawTag(152, 25);
output.WriteInt32(FieldName3);
}
if (FieldName4 != 0) {
output.WriteRawTag(160, 25);
output.WriteInt32(FieldName4);
}
if (Field0Name5 != 0) {
output.WriteRawTag(168, 25);
output.WriteInt32(Field0Name5);
}
if (Field0Name6 != 0) {
output.WriteRawTag(176, 25);
output.WriteInt32(Field0Name6);
}
if (FieldName7 != 0) {
output.WriteRawTag(184, 25);
output.WriteInt32(FieldName7);
}
if (FieldName8 != 0) {
output.WriteRawTag(192, 25);
output.WriteInt32(FieldName8);
}
if (FieldName9 != 0) {
output.WriteRawTag(200, 25);
output.WriteInt32(FieldName9);
}
if (FieldName10 != 0) {
output.WriteRawTag(208, 25);
output.WriteInt32(FieldName10);
}
if (FIELDNAME11 != 0) {
output.WriteRawTag(216, 25);
output.WriteInt32(FIELDNAME11);
}
if (FIELDName12 != 0) {
output.WriteRawTag(224, 25);
output.WriteInt32(FIELDName12);
}
if (FieldName13 != 0) {
output.WriteRawTag(232, 25);
output.WriteInt32(FieldName13);
}
if (FieldName14 != 0) {
output.WriteRawTag(240, 25);
output.WriteInt32(FieldName14);
}
if (FieldName15 != 0) {
output.WriteRawTag(248, 25);
output.WriteInt32(FieldName15);
}
if (FieldName16 != 0) {
output.WriteRawTag(128, 26);
output.WriteInt32(FieldName16);
}
if (FieldName17 != 0) {
output.WriteRawTag(136, 26);
output.WriteInt32(FieldName17);
}
if (FieldName18 != 0) {
output.WriteRawTag(144, 26);
output.WriteInt32(FieldName18);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -4933,6 +5281,9 @@ namespace ProtobufTestMessages.Proto3 {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (A != 0) {
output.WriteRawTag(8);
output.WriteInt32(A);
@ -4944,8 +5295,26 @@ namespace ProtobufTestMessages.Proto3 {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (A != 0) {
output.WriteRawTag(8);
output.WriteInt32(A);
}
if (corecursive_ != null) {
output.WriteRawTag(18);
output.WriteMessage(Corecursive);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -5120,6 +5489,9 @@ namespace ProtobufTestMessages.Proto3 {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (C != 0) {
output.WriteRawTag(8);
output.WriteInt32(C);
@ -5127,8 +5499,22 @@ namespace ProtobufTestMessages.Proto3 {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (C != 0) {
output.WriteRawTag(8);
output.WriteInt32(C);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;

File diff suppressed because it is too large Load Diff

@ -379,6 +379,9 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Field1.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Field1);
@ -390,7 +393,25 @@ namespace UnitTest.Issues.TestProtos {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Field1.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Field1);
}
if (anOneofCase_ == AnOneofOneofCase.OneofField) {
output.WriteRawTag(16);
output.WriteInt32(OneofField);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -558,11 +579,24 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -681,10 +715,23 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -804,11 +851,24 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -927,10 +987,23 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -1050,10 +1123,23 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -1186,11 +1272,24 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -1309,10 +1408,23 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -1432,11 +1544,24 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -1555,11 +1680,24 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -1678,11 +1816,24 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -1801,10 +1952,23 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -1979,6 +2143,9 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Foo != 0) {
output.WriteRawTag(8);
output.WriteInt32(Foo);
@ -1995,7 +2162,30 @@ namespace UnitTest.Issues.TestProtos {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Foo != 0) {
output.WriteRawTag(8);
output.WriteInt32(Foo);
}
if (Foo2 != 0) {
output.WriteRawTag(16);
output.WriteInt32(Foo2);
}
if (Foo3 != 0) {
output.WriteRawTag(24);
output.WriteInt32(Foo3);
}
foo4_.WriteTo(ref output, _repeated_foo4_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -2224,6 +2414,9 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (bar_ != null) {
output.WriteRawTag(10);
output.WriteMessage(Bar);
@ -2240,7 +2433,30 @@ namespace UnitTest.Issues.TestProtos {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (bar_ != null) {
output.WriteRawTag(10);
output.WriteMessage(Bar);
}
if (Baz != 0) {
output.WriteRawTag(16);
output.WriteInt32(Baz);
}
if (fred_ != null) {
output.WriteRawTag(26);
output.WriteMessage(Fred);
}
barney_.WriteTo(ref output, _repeated_barney_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -2446,6 +2662,9 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Waldo != 0) {
output.WriteRawTag(8);
output.WriteInt32(Waldo);
@ -2453,8 +2672,22 @@ namespace UnitTest.Issues.TestProtos {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Waldo != 0) {
output.WriteRawTag(8);
output.WriteInt32(Waldo);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -2615,6 +2848,9 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Qux != 0) {
output.WriteRawTag(8);
output.WriteInt32(Qux);
@ -2622,8 +2858,22 @@ namespace UnitTest.Issues.TestProtos {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Qux != 0) {
output.WriteRawTag(8);
output.WriteInt32(Qux);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -2759,11 +3009,24 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -2930,6 +3193,9 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (I != 0) {
output.WriteRawTag(8);
output.WriteInt32(I);
@ -2945,7 +3211,29 @@ namespace UnitTest.Issues.TestProtos {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (I != 0) {
output.WriteRawTag(8);
output.WriteInt32(I);
}
if (S.Length != 0) {
output.WriteRawTag(18);
output.WriteString(S);
}
if (sub_ != null) {
output.WriteRawTag(26);
output.WriteMessage(Sub);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -3130,6 +3418,9 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Fieldname != 0) {
output.WriteRawTag(8);
output.WriteInt32(Fieldname);
@ -3137,8 +3428,22 @@ namespace UnitTest.Issues.TestProtos {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Fieldname != 0) {
output.WriteRawTag(8);
output.WriteInt32(Fieldname);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -3274,11 +3579,24 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -3418,6 +3736,9 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (NestedField != 0) {
output.WriteRawTag(8);
output.WriteInt32(NestedField);
@ -3425,7 +3746,21 @@ namespace UnitTest.Issues.TestProtos {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (NestedField != 0) {
output.WriteRawTag(8);
output.WriteInt32(NestedField);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {

@ -157,6 +157,9 @@ namespace Google.Protobuf.TestProtos.Proto2 {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (HasD) {
output.WriteRawTag(8);
output.WriteInt32(D);
@ -164,7 +167,21 @@ namespace Google.Protobuf.TestProtos.Proto2 {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (HasD) {
output.WriteRawTag(8);
output.WriteInt32(D);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {

@ -133,6 +133,9 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (D != 0) {
output.WriteRawTag(8);
output.WriteInt32(D);
@ -140,7 +143,21 @@ namespace Google.Protobuf.TestProtos {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (D != 0) {
output.WriteRawTag(8);
output.WriteInt32(D);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {

@ -135,6 +135,9 @@ namespace Google.Protobuf.TestProtos.Proto2 {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (HasE) {
output.WriteRawTag(8);
output.WriteInt32(E);
@ -142,7 +145,21 @@ namespace Google.Protobuf.TestProtos.Proto2 {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (HasE) {
output.WriteRawTag(8);
output.WriteInt32(E);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {

@ -121,6 +121,9 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (E != 0) {
output.WriteRawTag(8);
output.WriteInt32(E);
@ -128,7 +131,21 @@ namespace Google.Protobuf.TestProtos {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (E != 0) {
output.WriteRawTag(8);
output.WriteInt32(E);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {

@ -106,10 +106,23 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {

@ -122,6 +122,9 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (foo_ != null) {
output.WriteRawTag(10);
output.WriteMessage(Foo);
@ -129,7 +132,21 @@ namespace UnitTest.Issues.TestProtos {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (foo_ != null) {
output.WriteRawTag(10);
output.WriteMessage(Foo);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {

@ -157,10 +157,23 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -282,11 +295,24 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -407,11 +433,24 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -580,6 +619,9 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Value != global::UnitTest.Issues.TestProtos.NegativeEnum.Zero) {
output.WriteRawTag(8);
output.WriteEnum((int) Value);
@ -589,7 +631,23 @@ namespace UnitTest.Issues.TestProtos {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Value != global::UnitTest.Issues.TestProtos.NegativeEnum.Zero) {
output.WriteRawTag(8);
output.WriteEnum((int) Value);
}
values_.WriteTo(ref output, _repeated_values_codec);
packedValues_.WriteTo(ref output, _repeated_packedValues_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -747,11 +805,24 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -957,6 +1028,9 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (PrimitiveValue != 0) {
output.WriteRawTag(8);
output.WriteInt32(PrimitiveValue);
@ -975,7 +1049,32 @@ namespace UnitTest.Issues.TestProtos {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (PrimitiveValue != 0) {
output.WriteRawTag(8);
output.WriteInt32(PrimitiveValue);
}
primitiveArray_.WriteTo(ref output, _repeated_primitiveArray_codec);
if (messageValue_ != null) {
output.WriteRawTag(26);
output.WriteMessage(MessageValue);
}
messageArray_.WriteTo(ref output, _repeated_messageArray_codec);
if (EnumValue != global::UnitTest.Issues.TestProtos.DeprecatedEnum.DeprecatedZero) {
output.WriteRawTag(40);
output.WriteEnum((int) EnumValue);
}
enumArray_.WriteTo(ref output, _repeated_enumArray_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -1197,6 +1296,9 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Item != 0) {
output.WriteRawTag(8);
output.WriteInt32(Item);
@ -1204,7 +1306,21 @@ namespace UnitTest.Issues.TestProtos {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Item != 0) {
output.WriteRawTag(8);
output.WriteInt32(Item);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -1366,6 +1482,9 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Types_ != 0) {
output.WriteRawTag(8);
output.WriteInt32(Types_);
@ -1377,7 +1496,25 @@ namespace UnitTest.Issues.TestProtos {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Types_ != 0) {
output.WriteRawTag(8);
output.WriteInt32(Types_);
}
if (Descriptor_ != 0) {
output.WriteRawTag(16);
output.WriteInt32(Descriptor_);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -1530,10 +1667,23 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -1810,6 +1960,9 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (PlainString.Length != 0) {
output.WriteRawTag(10);
output.WriteString(PlainString);
@ -1837,8 +1990,42 @@ namespace UnitTest.Issues.TestProtos {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (PlainString.Length != 0) {
output.WriteRawTag(10);
output.WriteString(PlainString);
}
if (o1Case_ == O1OneofCase.O1String) {
output.WriteRawTag(18);
output.WriteString(O1String);
}
if (o2Case_ == O2OneofCase.O2String) {
output.WriteRawTag(26);
output.WriteString(O2String);
}
if (PlainInt32 != 0) {
output.WriteRawTag(32);
output.WriteInt32(PlainInt32);
}
if (o1Case_ == O1OneofCase.O1Int32) {
output.WriteRawTag(40);
output.WriteInt32(O1Int32);
}
if (o2Case_ == O2OneofCase.O2Int32) {
output.WriteRawTag(48);
output.WriteInt32(O2Int32);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -2092,6 +2279,9 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Name.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Name);
@ -2107,8 +2297,30 @@ namespace UnitTest.Issues.TestProtos {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Name);
}
if (Description.Length != 0) {
output.WriteRawTag(18);
output.WriteString(Description);
}
if (Guid.Length != 0) {
output.WriteRawTag(26);
output.WriteString(Guid);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -2330,6 +2542,9 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (valueCase_ == ValueOneofCase.Text) {
output.WriteRawTag(10);
output.WriteString(Text);
@ -2341,7 +2556,25 @@ namespace UnitTest.Issues.TestProtos {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (valueCase_ == ValueOneofCase.Text) {
output.WriteRawTag(10);
output.WriteString(Text);
}
if (valueCase_ == ValueOneofCase.Nested) {
output.WriteRawTag(18);
output.WriteMessage(Nested);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -2535,6 +2768,9 @@ namespace UnitTest.Issues.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (X != 0) {
output.WriteRawTag(8);
output.WriteInt32(X);
@ -2546,7 +2782,25 @@ namespace UnitTest.Issues.TestProtos {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (X != 0) {
output.WriteRawTag(8);
output.WriteInt32(X);
}
if (Y != 0) {
output.WriteRawTag(16);
output.WriteInt32(Y);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {

@ -622,6 +622,9 @@ namespace ProtobufUnittest {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (HasOptionalInt32) {
output.WriteRawTag(8);
output.WriteInt32(OptionalInt32);
@ -709,7 +712,101 @@ namespace ProtobufUnittest {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (HasOptionalInt32) {
output.WriteRawTag(8);
output.WriteInt32(OptionalInt32);
}
if (HasOptionalInt64) {
output.WriteRawTag(16);
output.WriteInt64(OptionalInt64);
}
if (HasOptionalUint32) {
output.WriteRawTag(24);
output.WriteUInt32(OptionalUint32);
}
if (HasOptionalUint64) {
output.WriteRawTag(32);
output.WriteUInt64(OptionalUint64);
}
if (HasOptionalSint32) {
output.WriteRawTag(40);
output.WriteSInt32(OptionalSint32);
}
if (HasOptionalSint64) {
output.WriteRawTag(48);
output.WriteSInt64(OptionalSint64);
}
if (HasOptionalFixed32) {
output.WriteRawTag(61);
output.WriteFixed32(OptionalFixed32);
}
if (HasOptionalFixed64) {
output.WriteRawTag(65);
output.WriteFixed64(OptionalFixed64);
}
if (HasOptionalSfixed32) {
output.WriteRawTag(77);
output.WriteSFixed32(OptionalSfixed32);
}
if (HasOptionalSfixed64) {
output.WriteRawTag(81);
output.WriteSFixed64(OptionalSfixed64);
}
if (HasOptionalFloat) {
output.WriteRawTag(93);
output.WriteFloat(OptionalFloat);
}
if (HasOptionalDouble) {
output.WriteRawTag(97);
output.WriteDouble(OptionalDouble);
}
if (HasOptionalBool) {
output.WriteRawTag(104);
output.WriteBool(OptionalBool);
}
if (HasOptionalString) {
output.WriteRawTag(114);
output.WriteString(OptionalString);
}
if (HasOptionalBytes) {
output.WriteRawTag(122);
output.WriteBytes(OptionalBytes);
}
if (HasOptionalCord) {
output.WriteRawTag(130, 1);
output.WriteString(OptionalCord);
}
if (optionalNestedMessage_ != null) {
output.WriteRawTag(146, 1);
output.WriteMessage(OptionalNestedMessage);
}
if (lazyNestedMessage_ != null) {
output.WriteRawTag(154, 1);
output.WriteMessage(LazyNestedMessage);
}
if (HasOptionalNestedEnum) {
output.WriteRawTag(168, 1);
output.WriteEnum((int) OptionalNestedEnum);
}
if (SingularInt32 != 0) {
output.WriteRawTag(176, 1);
output.WriteInt32(SingularInt32);
}
if (SingularInt64 != 0L) {
output.WriteRawTag(184, 1);
output.WriteInt64(SingularInt64);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -1186,6 +1283,9 @@ namespace ProtobufUnittest {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (HasBb) {
output.WriteRawTag(8);
output.WriteInt32(Bb);
@ -1193,8 +1293,22 @@ namespace ProtobufUnittest {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (HasBb) {
output.WriteRawTag(8);
output.WriteInt32(Bb);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;

@ -203,6 +203,9 @@ namespace UnitTest.Issues.TestProtos.SelfreferentialOptions {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (HasIntOpt) {
output.WriteRawTag(8);
output.WriteInt32(IntOpt);
@ -217,7 +220,28 @@ namespace UnitTest.Issues.TestProtos.SelfreferentialOptions {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (HasIntOpt) {
output.WriteRawTag(8);
output.WriteInt32(IntOpt);
}
if (HasFoo) {
output.WriteRawTag(16);
output.WriteInt32(Foo);
}
if (_extensions != null) {
_extensions.WriteTo(ref output);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {

@ -535,6 +535,9 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (anyField_ != null) {
output.WriteRawTag(10);
output.WriteMessage(AnyField);
@ -605,7 +608,84 @@ namespace Google.Protobuf.TestProtos {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (anyField_ != null) {
output.WriteRawTag(10);
output.WriteMessage(AnyField);
}
if (apiField_ != null) {
output.WriteRawTag(18);
output.WriteMessage(ApiField);
}
if (durationField_ != null) {
output.WriteRawTag(26);
output.WriteMessage(DurationField);
}
if (emptyField_ != null) {
output.WriteRawTag(34);
output.WriteMessage(EmptyField);
}
if (fieldMaskField_ != null) {
output.WriteRawTag(42);
output.WriteMessage(FieldMaskField);
}
if (sourceContextField_ != null) {
output.WriteRawTag(50);
output.WriteMessage(SourceContextField);
}
if (structField_ != null) {
output.WriteRawTag(58);
output.WriteMessage(StructField);
}
if (timestampField_ != null) {
output.WriteRawTag(66);
output.WriteMessage(TimestampField);
}
if (typeField_ != null) {
output.WriteRawTag(74);
output.WriteMessage(TypeField);
}
if (doubleField_ != null) {
_single_doubleField_codec.WriteTagAndValue(ref output, DoubleField);
}
if (floatField_ != null) {
_single_floatField_codec.WriteTagAndValue(ref output, FloatField);
}
if (int64Field_ != null) {
_single_int64Field_codec.WriteTagAndValue(ref output, Int64Field);
}
if (uint64Field_ != null) {
_single_uint64Field_codec.WriteTagAndValue(ref output, Uint64Field);
}
if (int32Field_ != null) {
_single_int32Field_codec.WriteTagAndValue(ref output, Int32Field);
}
if (uint32Field_ != null) {
_single_uint32Field_codec.WriteTagAndValue(ref output, Uint32Field);
}
if (boolField_ != null) {
_single_boolField_codec.WriteTagAndValue(ref output, BoolField);
}
if (stringField_ != null) {
_single_stringField_codec.WriteTagAndValue(ref output, StringField);
}
if (bytesField_ != null) {
_single_bytesField_codec.WriteTagAndValue(ref output, BytesField);
}
if (valueField_ != null) {
output.WriteRawTag(154, 1);
output.WriteMessage(ValueField);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -1393,6 +1473,9 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
anyField_.WriteTo(output, _repeated_anyField_codec);
apiField_.WriteTo(output, _repeated_apiField_codec);
durationField_.WriteTo(output, _repeated_durationField_codec);
@ -1414,7 +1497,35 @@ namespace Google.Protobuf.TestProtos {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
anyField_.WriteTo(ref output, _repeated_anyField_codec);
apiField_.WriteTo(ref output, _repeated_apiField_codec);
durationField_.WriteTo(ref output, _repeated_durationField_codec);
emptyField_.WriteTo(ref output, _repeated_emptyField_codec);
fieldMaskField_.WriteTo(ref output, _repeated_fieldMaskField_codec);
sourceContextField_.WriteTo(ref output, _repeated_sourceContextField_codec);
structField_.WriteTo(ref output, _repeated_structField_codec);
timestampField_.WriteTo(ref output, _repeated_timestampField_codec);
typeField_.WriteTo(ref output, _repeated_typeField_codec);
doubleField_.WriteTo(ref output, _repeated_doubleField_codec);
floatField_.WriteTo(ref output, _repeated_floatField_codec);
int64Field_.WriteTo(ref output, _repeated_int64Field_codec);
uint64Field_.WriteTo(ref output, _repeated_uint64Field_codec);
int32Field_.WriteTo(ref output, _repeated_int32Field_codec);
uint32Field_.WriteTo(ref output, _repeated_uint32Field_codec);
boolField_.WriteTo(ref output, _repeated_boolField_codec);
stringField_.WriteTo(ref output, _repeated_stringField_codec);
bytesField_.WriteTo(ref output, _repeated_bytesField_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -2051,6 +2162,9 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (oneofFieldCase_ == OneofFieldOneofCase.AnyField) {
output.WriteRawTag(10);
output.WriteMessage(AnyField);
@ -2117,7 +2231,80 @@ namespace Google.Protobuf.TestProtos {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (oneofFieldCase_ == OneofFieldOneofCase.AnyField) {
output.WriteRawTag(10);
output.WriteMessage(AnyField);
}
if (oneofFieldCase_ == OneofFieldOneofCase.ApiField) {
output.WriteRawTag(18);
output.WriteMessage(ApiField);
}
if (oneofFieldCase_ == OneofFieldOneofCase.DurationField) {
output.WriteRawTag(26);
output.WriteMessage(DurationField);
}
if (oneofFieldCase_ == OneofFieldOneofCase.EmptyField) {
output.WriteRawTag(34);
output.WriteMessage(EmptyField);
}
if (oneofFieldCase_ == OneofFieldOneofCase.FieldMaskField) {
output.WriteRawTag(42);
output.WriteMessage(FieldMaskField);
}
if (oneofFieldCase_ == OneofFieldOneofCase.SourceContextField) {
output.WriteRawTag(50);
output.WriteMessage(SourceContextField);
}
if (oneofFieldCase_ == OneofFieldOneofCase.StructField) {
output.WriteRawTag(58);
output.WriteMessage(StructField);
}
if (oneofFieldCase_ == OneofFieldOneofCase.TimestampField) {
output.WriteRawTag(66);
output.WriteMessage(TimestampField);
}
if (oneofFieldCase_ == OneofFieldOneofCase.TypeField) {
output.WriteRawTag(74);
output.WriteMessage(TypeField);
}
if (oneofFieldCase_ == OneofFieldOneofCase.DoubleField) {
_oneof_doubleField_codec.WriteTagAndValue(ref output, (double?) oneofField_);
}
if (oneofFieldCase_ == OneofFieldOneofCase.FloatField) {
_oneof_floatField_codec.WriteTagAndValue(ref output, (float?) oneofField_);
}
if (oneofFieldCase_ == OneofFieldOneofCase.Int64Field) {
_oneof_int64Field_codec.WriteTagAndValue(ref output, (long?) oneofField_);
}
if (oneofFieldCase_ == OneofFieldOneofCase.Uint64Field) {
_oneof_uint64Field_codec.WriteTagAndValue(ref output, (ulong?) oneofField_);
}
if (oneofFieldCase_ == OneofFieldOneofCase.Int32Field) {
_oneof_int32Field_codec.WriteTagAndValue(ref output, (int?) oneofField_);
}
if (oneofFieldCase_ == OneofFieldOneofCase.Uint32Field) {
_oneof_uint32Field_codec.WriteTagAndValue(ref output, (uint?) oneofField_);
}
if (oneofFieldCase_ == OneofFieldOneofCase.BoolField) {
_oneof_boolField_codec.WriteTagAndValue(ref output, (bool?) oneofField_);
}
if (oneofFieldCase_ == OneofFieldOneofCase.StringField) {
_oneof_stringField_codec.WriteTagAndValue(ref output, (string) oneofField_);
}
if (oneofFieldCase_ == OneofFieldOneofCase.BytesField) {
_oneof_bytesField_codec.WriteTagAndValue(ref output, (pb::ByteString) oneofField_);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -2848,6 +3035,9 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
anyField_.WriteTo(output, _map_anyField_codec);
apiField_.WriteTo(output, _map_apiField_codec);
durationField_.WriteTo(output, _map_durationField_codec);
@ -2869,8 +3059,36 @@ namespace Google.Protobuf.TestProtos {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
anyField_.WriteTo(ref output, _map_anyField_codec);
apiField_.WriteTo(ref output, _map_apiField_codec);
durationField_.WriteTo(ref output, _map_durationField_codec);
emptyField_.WriteTo(ref output, _map_emptyField_codec);
fieldMaskField_.WriteTo(ref output, _map_fieldMaskField_codec);
sourceContextField_.WriteTo(ref output, _map_sourceContextField_codec);
structField_.WriteTo(ref output, _map_structField_codec);
timestampField_.WriteTo(ref output, _map_timestampField_codec);
typeField_.WriteTo(ref output, _map_typeField_codec);
doubleField_.WriteTo(ref output, _map_doubleField_codec);
floatField_.WriteTo(ref output, _map_floatField_codec);
int64Field_.WriteTo(ref output, _map_int64Field_codec);
uint64Field_.WriteTo(ref output, _map_uint64Field_codec);
int32Field_.WriteTo(ref output, _map_int32Field_codec);
uint32Field_.WriteTo(ref output, _map_uint32Field_codec);
boolField_.WriteTo(ref output, _map_boolField_codec);
stringField_.WriteTo(ref output, _map_stringField_codec);
bytesField_.WriteTo(ref output, _map_bytesField_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;

@ -0,0 +1,225 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 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.Buffers;
using System.Diagnostics;
namespace Google.Protobuf.Buffers
{
/// <summary>
/// Represents a heap-based, array-backed output sink into which <typeparam name="T"/> data can be written.
///
/// ArrayBufferWriter is originally from corefx, and has been contributed to Protobuf
/// https://github.com/dotnet/runtime/blob/071da4c41aa808c949a773b92dca6f88de9d11f3/src/libraries/Common/src/System/Buffers/ArrayBufferWriter.cs
/// </summary>
internal sealed class ArrayBufferWriter<T> : IBufferWriter<T>
{
private T[] _buffer;
private int _index;
private const int DefaultInitialBufferSize = 256;
/// <summary>
/// Creates an instance of an <see cref="ArrayBufferWriter{T}"/>, in which data can be written to,
/// with the default initial capacity.
/// </summary>
public ArrayBufferWriter()
{
_buffer = new T[0];
_index = 0;
}
/// <summary>
/// Userful for testing writing to buffer writer with a lot of small segments.
/// If set, it limits the max number of bytes by which the buffer grows by at once.
/// </summary>
public int? MaxGrowBy { get; set; }
/// <summary>
/// Creates an instance of an <see cref="ArrayBufferWriter{T}"/>, in which data can be written to,
/// with an initial capacity specified.
/// </summary>
/// <param name="initialCapacity">The minimum capacity with which to initialize the underlying buffer.</param>
/// <exception cref="ArgumentException">
/// Thrown when <paramref name="initialCapacity"/> is not positive (i.e. less than or equal to 0).
/// </exception>
public ArrayBufferWriter(int initialCapacity)
{
if (initialCapacity <= 0)
throw new ArgumentException(nameof(initialCapacity));
_buffer = new T[initialCapacity];
_index = 0;
}
/// <summary>
/// Returns the data written to the underlying buffer so far, as a <see cref="ReadOnlyMemory{T}"/>.
/// </summary>
public ReadOnlyMemory<T> WrittenMemory => _buffer.AsMemory(0, _index);
/// <summary>
/// Returns the data written to the underlying buffer so far, as a <see cref="ReadOnlySpan{T}"/>.
/// </summary>
public ReadOnlySpan<T> WrittenSpan => _buffer.AsSpan(0, _index);
/// <summary>
/// Returns the amount of data written to the underlying buffer so far.
/// </summary>
public int WrittenCount => _index;
/// <summary>
/// Returns the total amount of space within the underlying buffer.
/// </summary>
public int Capacity => _buffer.Length;
/// <summary>
/// Returns the amount of space available that can still be written into without forcing the underlying buffer to grow.
/// </summary>
public int FreeCapacity => _buffer.Length - _index;
/// <summary>
/// Clears the data written to the underlying buffer.
/// </summary>
/// <remarks>
/// You must clear the <see cref="ArrayBufferWriter{T}"/> before trying to re-use it.
/// </remarks>
public void Clear()
{
Debug.Assert(_buffer.Length >= _index);
_buffer.AsSpan(0, _index).Clear();
_index = 0;
}
/// <summary>
/// Notifies <see cref="IBufferWriter{T}"/> that <paramref name="count"/> amount of data was written to the output <see cref="Span{T}"/>/<see cref="Memory{T}"/>
/// </summary>
/// <exception cref="ArgumentException">
/// Thrown when <paramref name="count"/> is negative.
/// </exception>
/// <exception cref="InvalidOperationException">
/// Thrown when attempting to advance past the end of the underlying buffer.
/// </exception>
/// <remarks>
/// You must request a new buffer after calling Advance to continue writing more data and cannot write to a previously acquired buffer.
/// </remarks>
public void Advance(int count)
{
if (count < 0)
throw new ArgumentException(nameof(count));
if (_index > _buffer.Length - count)
throw new InvalidOperationException("Advanced past capacity.");
_index += count;
}
/// <summary>
/// Returns a <see cref="Memory{T}"/> to write to that is at least the requested length (specified by <paramref name="sizeHint"/>).
/// If no <paramref name="sizeHint"/> is provided (or it's equal to <code>0</code>), some non-empty buffer is returned.
/// </summary>
/// <exception cref="ArgumentException">
/// Thrown when <paramref name="sizeHint"/> is negative.
/// </exception>
/// <remarks>
/// This will never return an empty <see cref="Memory{T}"/>.
/// </remarks>
/// <remarks>
/// There is no guarantee that successive calls will return the same buffer or the same-sized buffer.
/// </remarks>
/// <remarks>
/// You must request a new buffer after calling Advance to continue writing more data and cannot write to a previously acquired buffer.
/// </remarks>
public Memory<T> GetMemory(int sizeHint = 0)
{
CheckAndResizeBuffer(sizeHint);
Debug.Assert(_buffer.Length > _index);
return _buffer.AsMemory(_index);
}
/// <summary>
/// Returns a <see cref="Span{T}"/> to write to that is at least the requested length (specified by <paramref name="sizeHint"/>).
/// If no <paramref name="sizeHint"/> is provided (or it's equal to <code>0</code>), some non-empty buffer is returned.
/// </summary>
/// <exception cref="ArgumentException">
/// Thrown when <paramref name="sizeHint"/> is negative.
/// </exception>
/// <remarks>
/// This will never return an empty <see cref="Span{T}"/>.
/// </remarks>
/// <remarks>
/// There is no guarantee that successive calls will return the same buffer or the same-sized buffer.
/// </remarks>
/// <remarks>
/// You must request a new buffer after calling Advance to continue writing more data and cannot write to a previously acquired buffer.
/// </remarks>
public Span<T> GetSpan(int sizeHint = 0)
{
CheckAndResizeBuffer(sizeHint);
Debug.Assert(_buffer.Length > _index);
return _buffer.AsSpan(_index);
}
private void CheckAndResizeBuffer(int sizeHint)
{
if (sizeHint < 0)
throw new ArgumentException(nameof(sizeHint));
if (sizeHint == 0)
{
sizeHint = 1;
}
if (sizeHint > FreeCapacity)
{
int growBy = Math.Max(sizeHint, _buffer.Length);
if (_buffer.Length == 0)
{
growBy = Math.Max(growBy, DefaultInitialBufferSize);
}
// enable tests that write to small buffer segments
if (MaxGrowBy.HasValue && growBy > MaxGrowBy.Value)
{
growBy = MaxGrowBy.Value;
}
int newSize = checked(_buffer.Length + growBy);
Array.Resize(ref _buffer, newSize);
}
Debug.Assert(FreeCapacity > 0 && FreeCapacity >= sizeHint);
}
}
}

@ -33,6 +33,7 @@
using System;
using System.IO;
using Google.Protobuf.TestProtos;
using Google.Protobuf.Buffers;
using NUnit.Framework;
namespace Google.Protobuf
@ -48,22 +49,39 @@ namespace Google.Protobuf
// Only do 32-bit write if the value fits in 32 bits.
if ((value >> 32) == 0)
{
// CodedOutputStream
MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(rawOutput);
output.WriteRawVarint32((uint) value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
// IBufferWriter
var bufferWriter = new ArrayBufferWriter<byte>();
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
ctx.WriteUInt32((uint) value);
ctx.Flush();
Assert.AreEqual(data, bufferWriter.WrittenSpan.ToArray());
// Also try computing size.
Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint32Size((uint) value));
}
{
// CodedOutputStream
MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(rawOutput);
output.WriteRawVarint64(value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
// IBufferWriter
var bufferWriter = new ArrayBufferWriter<byte>();
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
ctx.WriteUInt64(value);
ctx.Flush();
Assert.AreEqual(data, bufferWriter.WrittenSpan.ToArray());
// Also try computing size.
Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint64Size(value));
}
@ -80,6 +98,13 @@ namespace Google.Protobuf
output.WriteRawVarint32((uint) value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
var bufferWriter = new ArrayBufferWriter<byte>();
bufferWriter.MaxGrowBy = bufferSize;
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
ctx.WriteUInt32((uint) value);
ctx.Flush();
Assert.AreEqual(data, bufferWriter.WrittenSpan.ToArray());
}
{
@ -88,7 +113,15 @@ namespace Google.Protobuf
output.WriteRawVarint64(value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
var bufferWriter = new ArrayBufferWriter<byte>();
bufferWriter.MaxGrowBy = bufferSize;
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
ctx.WriteUInt64(value);
ctx.Flush();
Assert.AreEqual(data, bufferWriter.WrittenSpan.ToArray());
}
}
}
@ -133,20 +166,35 @@ namespace Google.Protobuf
/// </summary>
private static void AssertWriteLittleEndian32(byte[] data, uint value)
{
MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(rawOutput);
output.WriteRawLittleEndian32(value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
{
var rawOutput = new MemoryStream();
var output = new CodedOutputStream(rawOutput);
output.WriteRawLittleEndian32(value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
var bufferWriter = new ArrayBufferWriter<byte>();
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
ctx.WriteFixed32(value);
ctx.Flush();
Assert.AreEqual(data, bufferWriter.WrittenSpan.ToArray());
}
// Try different buffer sizes.
for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2)
{
rawOutput = new MemoryStream();
output = new CodedOutputStream(rawOutput, bufferSize);
var rawOutput = new MemoryStream();
var output = new CodedOutputStream(rawOutput, bufferSize);
output.WriteRawLittleEndian32(value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
var bufferWriter = new ArrayBufferWriter<byte>();
bufferWriter.MaxGrowBy = bufferSize;
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
ctx.WriteFixed32(value);
ctx.Flush();
Assert.AreEqual(data, bufferWriter.WrittenSpan.ToArray());
}
}
@ -156,20 +204,35 @@ namespace Google.Protobuf
/// </summary>
private static void AssertWriteLittleEndian64(byte[] data, ulong value)
{
MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(rawOutput);
output.WriteRawLittleEndian64(value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
{
var rawOutput = new MemoryStream();
var output = new CodedOutputStream(rawOutput);
output.WriteRawLittleEndian64(value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
var bufferWriter = new ArrayBufferWriter<byte>();
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
ctx.WriteFixed64(value);
ctx.Flush();
Assert.AreEqual(data, bufferWriter.WrittenSpan.ToArray());
}
// Try different block sizes.
for (int blockSize = 1; blockSize <= 16; blockSize *= 2)
{
rawOutput = new MemoryStream();
output = new CodedOutputStream(rawOutput, blockSize);
var rawOutput = new MemoryStream();
var output = new CodedOutputStream(rawOutput, blockSize);
output.WriteRawLittleEndian64(value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
var bufferWriter = new ArrayBufferWriter<byte>();
bufferWriter.MaxGrowBy = blockSize;
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
ctx.WriteFixed64(value);
ctx.Flush();
Assert.AreEqual(data, bufferWriter.WrittenSpan.ToArray());
}
}
@ -205,41 +268,72 @@ namespace Google.Protobuf
message.WriteTo(output);
output.Flush();
Assert.AreEqual(rawBytes, rawOutput.ToArray());
var bufferWriter = new ArrayBufferWriter<byte>();
bufferWriter.MaxGrowBy = blockSize;
message.WriteTo(bufferWriter);
Assert.AreEqual(rawBytes, bufferWriter.WrittenSpan.ToArray());
}
}
[Test]
public void WriteContext_WritesWithFlushes()
{
TestAllTypes message = SampleMessages.CreateFullTestAllTypes();
MemoryStream expectedOutput = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(expectedOutput);
output.WriteMessage(message);
output.Flush();
byte[] expectedBytes1 = expectedOutput.ToArray();
output.WriteMessage(message);
output.Flush();
byte[] expectedBytes2 = expectedOutput.ToArray();
var bufferWriter = new ArrayBufferWriter<byte>();
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
ctx.WriteMessage(message);
ctx.Flush();
Assert.AreEqual(expectedBytes1, bufferWriter.WrittenSpan.ToArray());
ctx.WriteMessage(message);
ctx.Flush();
Assert.AreEqual(expectedBytes2, bufferWriter.WrittenSpan.ToArray());
}
[Test]
public void EncodeZigZag32()
{
Assert.AreEqual(0u, CodedOutputStream.EncodeZigZag32(0));
Assert.AreEqual(1u, CodedOutputStream.EncodeZigZag32(-1));
Assert.AreEqual(2u, CodedOutputStream.EncodeZigZag32(1));
Assert.AreEqual(3u, CodedOutputStream.EncodeZigZag32(-2));
Assert.AreEqual(0x7FFFFFFEu, CodedOutputStream.EncodeZigZag32(0x3FFFFFFF));
Assert.AreEqual(0x7FFFFFFFu, CodedOutputStream.EncodeZigZag32(unchecked((int) 0xC0000000)));
Assert.AreEqual(0xFFFFFFFEu, CodedOutputStream.EncodeZigZag32(0x7FFFFFFF));
Assert.AreEqual(0xFFFFFFFFu, CodedOutputStream.EncodeZigZag32(unchecked((int) 0x80000000)));
Assert.AreEqual(0u, WritingPrimitives.EncodeZigZag32(0));
Assert.AreEqual(1u, WritingPrimitives.EncodeZigZag32(-1));
Assert.AreEqual(2u, WritingPrimitives.EncodeZigZag32(1));
Assert.AreEqual(3u, WritingPrimitives.EncodeZigZag32(-2));
Assert.AreEqual(0x7FFFFFFEu, WritingPrimitives.EncodeZigZag32(0x3FFFFFFF));
Assert.AreEqual(0x7FFFFFFFu, WritingPrimitives.EncodeZigZag32(unchecked((int) 0xC0000000)));
Assert.AreEqual(0xFFFFFFFEu, WritingPrimitives.EncodeZigZag32(0x7FFFFFFF));
Assert.AreEqual(0xFFFFFFFFu, WritingPrimitives.EncodeZigZag32(unchecked((int) 0x80000000)));
}
[Test]
public void EncodeZigZag64()
{
Assert.AreEqual(0u, CodedOutputStream.EncodeZigZag64(0));
Assert.AreEqual(1u, CodedOutputStream.EncodeZigZag64(-1));
Assert.AreEqual(2u, CodedOutputStream.EncodeZigZag64(1));
Assert.AreEqual(3u, CodedOutputStream.EncodeZigZag64(-2));
Assert.AreEqual(0u, WritingPrimitives.EncodeZigZag64(0));
Assert.AreEqual(1u, WritingPrimitives.EncodeZigZag64(-1));
Assert.AreEqual(2u, WritingPrimitives.EncodeZigZag64(1));
Assert.AreEqual(3u, WritingPrimitives.EncodeZigZag64(-2));
Assert.AreEqual(0x000000007FFFFFFEuL,
CodedOutputStream.EncodeZigZag64(unchecked((long) 0x000000003FFFFFFFUL)));
WritingPrimitives.EncodeZigZag64(unchecked((long) 0x000000003FFFFFFFUL)));
Assert.AreEqual(0x000000007FFFFFFFuL,
CodedOutputStream.EncodeZigZag64(unchecked((long) 0xFFFFFFFFC0000000UL)));
WritingPrimitives.EncodeZigZag64(unchecked((long) 0xFFFFFFFFC0000000UL)));
Assert.AreEqual(0x00000000FFFFFFFEuL,
CodedOutputStream.EncodeZigZag64(unchecked((long) 0x000000007FFFFFFFUL)));
WritingPrimitives.EncodeZigZag64(unchecked((long) 0x000000007FFFFFFFUL)));
Assert.AreEqual(0x00000000FFFFFFFFuL,
CodedOutputStream.EncodeZigZag64(unchecked((long) 0xFFFFFFFF80000000UL)));
WritingPrimitives.EncodeZigZag64(unchecked((long) 0xFFFFFFFF80000000UL)));
Assert.AreEqual(0xFFFFFFFFFFFFFFFEL,
CodedOutputStream.EncodeZigZag64(unchecked((long) 0x7FFFFFFFFFFFFFFFUL)));
WritingPrimitives.EncodeZigZag64(unchecked((long) 0x7FFFFFFFFFFFFFFFUL)));
Assert.AreEqual(0xFFFFFFFFFFFFFFFFL,
CodedOutputStream.EncodeZigZag64(unchecked((long) 0x8000000000000000UL)));
WritingPrimitives.EncodeZigZag64(unchecked((long) 0x8000000000000000UL)));
}
[Test]
@ -247,26 +341,26 @@ namespace Google.Protobuf
{
// Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1)
// were chosen semi-randomly via keyboard bashing.
Assert.AreEqual(0, ParsingPrimitives.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(0)));
Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(1)));
Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-1)));
Assert.AreEqual(14927, ParsingPrimitives.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(14927)));
Assert.AreEqual(-3612, ParsingPrimitives.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-3612)));
Assert.AreEqual(0, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(0)));
Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(1)));
Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(-1)));
Assert.AreEqual(14927, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(14927)));
Assert.AreEqual(-3612, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(-3612)));
}
[Test]
public void RoundTripZigZag64()
{
Assert.AreEqual(0, ParsingPrimitives.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(0)));
Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(1)));
Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-1)));
Assert.AreEqual(14927, ParsingPrimitives.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(14927)));
Assert.AreEqual(-3612, ParsingPrimitives.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-3612)));
Assert.AreEqual(0, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(0)));
Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(1)));
Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(-1)));
Assert.AreEqual(14927, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(14927)));
Assert.AreEqual(-3612, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(-3612)));
Assert.AreEqual(856912304801416L,
ParsingPrimitives.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(856912304801416L)));
ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(856912304801416L)));
Assert.AreEqual(-75123905439571256L,
ParsingPrimitives.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-75123905439571256L)));
ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(-75123905439571256L)));
}
[Test]
@ -395,7 +489,7 @@ namespace Google.Protobuf
Assert.IsTrue(memoryStream.CanWrite);
using (var cos = new CodedOutputStream(memoryStream))
{
cos.WriteRawByte(0);
cos.WriteRawBytes(new byte[] {0});
Assert.AreEqual(0, memoryStream.Position); // Not flushed yet
}
Assert.AreEqual(1, memoryStream.ToArray().Length); // Flushed data from CodedOutputStream to MemoryStream
@ -409,7 +503,7 @@ namespace Google.Protobuf
Assert.IsTrue(memoryStream.CanWrite);
using (var cos = new CodedOutputStream(memoryStream, true))
{
cos.WriteRawByte(0);
cos.WriteRawBytes(new byte[] {0});
Assert.AreEqual(0, memoryStream.Position); // Not flushed yet
}
Assert.AreEqual(1, memoryStream.Position); // Flushed data from CodedOutputStream to MemoryStream

@ -34,6 +34,8 @@ namespace Google.Protobuf
message.SetExtension(OptionalBoolExtension, true);
var serialized = message.ToByteArray();
MessageParsingHelpers.AssertWritingMessage(message);
MessageParsingHelpers.AssertReadingMessage(
TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry() { OptionalBoolExtension }),
serialized,

@ -124,7 +124,17 @@ namespace Google.Protobuf
{
var stream = new MemoryStream();
var codedOutput = new CodedOutputStream(stream);
codec.ValueWriter(codedOutput, sampleValue);
WriteContext.Initialize(codedOutput, out WriteContext ctx);
try
{
// only write the value using the codec
codec.ValueWriter(ref ctx, sampleValue);
}
finally
{
ctx.CopyStateTo(codedOutput);
}
codedOutput.Flush();
stream.Position = 0;
var codedInput = new CodedInputStream(stream);
@ -175,7 +185,17 @@ namespace Google.Protobuf
if (codec.DefaultValue != null) // This part isn't appropriate for message types.
{
codedOutput = new CodedOutputStream(stream);
codec.ValueWriter(codedOutput, codec.DefaultValue);
WriteContext.Initialize(codedOutput, out WriteContext ctx);
try
{
// only write the value using the codec
codec.ValueWriter(ref ctx, codec.DefaultValue);
}
finally
{
ctx.CopyStateTo(codedOutput);
}
codedOutput.Flush();
Assert.AreNotEqual(0, stream.Position);
Assert.AreEqual(stream.Position, codec.ValueSizeCalculator(codec.DefaultValue));

@ -344,6 +344,8 @@ namespace Google.Protobuf
}
};
MessageParsingHelpers.AssertWritingMessage(message);
MessageParsingHelpers.AssertRoundtrip(Proto2.TestAllTypes.Parser, message);
}
@ -359,6 +361,8 @@ namespace Google.Protobuf
new RepeatedGroup_extension { A = 30 }
});
MessageParsingHelpers.AssertWritingMessage(message);
MessageParsingHelpers.AssertRoundtrip(
TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry() { UnittestExtensions.OptionalGroupExtension, UnittestExtensions.RepeatedGroupExtension }),
message);
@ -370,6 +374,8 @@ namespace Google.Protobuf
var message = new TestGroupExtension();
message.SetExtension(TestNestedExtension.Extensions.OptionalGroupExtension, new TestNestedExtension.Types.OptionalGroup_extension { A = 10 });
MessageParsingHelpers.AssertWritingMessage(message);
MessageParsingHelpers.AssertRoundtrip(
TestGroupExtension.Parser.WithExtensionRegistry(new ExtensionRegistry() { TestNestedExtension.Extensions.OptionalGroupExtension }),
message);

@ -132,6 +132,8 @@ namespace Google.Protobuf
byte[] bytes = message.ToByteArray();
Assert.AreEqual(0, bytes.Length);
MessageParsingHelpers.AssertWritingMessage(message);
MessageParsingHelpers.AssertRoundtrip(TestAllTypes.Parser, message);
}
@ -164,7 +166,7 @@ namespace Google.Protobuf
SingleUint64 = ulong.MaxValue
};
byte[] bytes = message.ToByteArray();
MessageParsingHelpers.AssertWritingMessage(message);
MessageParsingHelpers.AssertRoundtrip(TestAllTypes.Parser, message);
}
@ -198,7 +200,7 @@ namespace Google.Protobuf
RepeatedUint64 = { ulong.MaxValue, uint.MinValue }
};
byte[] bytes = message.ToByteArray();
MessageParsingHelpers.AssertWritingMessage(message);
MessageParsingHelpers.AssertRoundtrip(TestAllTypes.Parser, message);
}
@ -230,7 +232,7 @@ namespace Google.Protobuf
}
};
byte[] bytes = message.ToByteArray();
MessageParsingHelpers.AssertWritingMessage(message);
MessageParsingHelpers.AssertRoundtrip(TestMap.Parser, message);
}
@ -246,6 +248,8 @@ namespace Google.Protobuf
byte[] bytes = message.ToByteArray();
Assert.AreEqual(2, bytes.Length); // Tag for field entry (1 byte), length of entry (0; 1 byte)
MessageParsingHelpers.AssertWritingMessage(message);
MessageParsingHelpers.AssertReadingMessage(
TestMap.Parser,
bytes,
@ -660,6 +664,8 @@ namespace Google.Protobuf
var bytes = message.ToByteArray();
Assert.AreEqual(3, bytes.Length); // 2 bytes for the tag + 1 for the value - no string!
MessageParsingHelpers.AssertWritingMessage(message);
MessageParsingHelpers.AssertRoundtrip(TestAllTypes.Parser, message, parsedMessage =>
{
Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, parsedMessage.OneofFieldCase);
@ -675,6 +681,8 @@ namespace Google.Protobuf
var bytes = message.ToByteArray();
Assert.AreEqual(3, bytes.Length); // 2 bytes for the tag + 1 for the value - it's still serialized
MessageParsingHelpers.AssertWritingMessage(message);
MessageParsingHelpers.AssertRoundtrip(TestAllTypes.Parser, message, parsedMessage =>
{
Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, parsedMessage.OneofFieldCase);

@ -35,7 +35,9 @@ using System.Buffers;
using pb = global::Google.Protobuf;
using pbr = global::Google.Protobuf.Reflection;
using NUnit.Framework;
using System.IO;
using System;
using Google.Protobuf.Buffers;
namespace Google.Protobuf
{
@ -46,14 +48,14 @@ namespace Google.Protobuf
{
var message = new ParseContextEnabledMessageB
{
A = new LegacyGeneratedCodeMessageA
{
Bb = new ParseContextEnabledMessageB { OptionalInt32 = 12345 }
},
OptionalInt32 = 6789
A = new LegacyGeneratedCodeMessageA
{
Bb = new ParseContextEnabledMessageB { OptionalInt32 = 12345 }
},
OptionalInt32 = 6789
};
var data = message.ToByteArray();
// when parsing started using CodedInputStream and a message with legacy generated code
// is encountered somewhere in the parse tree, we still need to be able to use its
// MergeFrom(CodedInputStream) method to parse correctly.
@ -71,11 +73,11 @@ namespace Google.Protobuf
{
var message = new ParseContextEnabledMessageB
{
A = new LegacyGeneratedCodeMessageA
{
Bb = new ParseContextEnabledMessageB { OptionalInt32 = 12345 }
},
OptionalInt32 = 6789
A = new LegacyGeneratedCodeMessageA
{
Bb = new ParseContextEnabledMessageB { OptionalInt32 = 12345 }
},
OptionalInt32 = 6789
};
var data = message.ToByteArray();
@ -86,13 +88,65 @@ namespace Google.Protobuf
// code up to date.
var exception = Assert.Throws<InvalidProtocolBufferException>(() =>
{
ParseContext.Initialize(new ReadOnlySequence<byte>(data), out ParseContext parseCtx);
var parsed = new ParseContextEnabledMessageB();
ParsingPrimitivesMessages.ReadRawMessage(ref parseCtx, parsed);
ParseContext.Initialize(new ReadOnlySequence<byte>(data), out ParseContext parseCtx);
var parsed = new ParseContextEnabledMessageB();
ParsingPrimitivesMessages.ReadRawMessage(ref parseCtx, parsed);
});
Assert.AreEqual($"Message {typeof(LegacyGeneratedCodeMessageA).Name} doesn't provide the generated method that enables ParseContext-based parsing. You might need to regenerate the generated protobuf code.", exception.Message);
}
[Test]
public void IntermixingOfNewAndLegacyGeneratedCodeWorksWithCodedOutputStream()
{
// when serialization started using CodedOutputStream and a message with legacy generated code
// is encountered somewhere in the parse tree, we still need to be able to use its
// WriteTo(CodedOutputStream) method to serialize correctly.
var ms = new MemoryStream();
var codedOutput = new CodedOutputStream(ms);
var message = new ParseContextEnabledMessageB
{
A = new LegacyGeneratedCodeMessageA
{
Bb = new ParseContextEnabledMessageB { OptionalInt32 = 12345 }
},
OptionalInt32 = 6789
};
message.WriteTo(codedOutput);
codedOutput.Flush();
var codedInput = new CodedInputStream(ms.ToArray());
var parsed = new ParseContextEnabledMessageB();
codedInput.ReadRawMessage(parsed);
Assert.IsTrue(codedInput.IsAtEnd);
Assert.AreEqual(12345, parsed.A.Bb.OptionalInt32);
Assert.AreEqual(6789, parsed.OptionalInt32);
}
[Test]
public void LegacyGeneratedCodeThrowsWithIBufferWriter()
{
// if serialization started using IBufferWriter and we don't have a CodedOutputStream
// instance at hand, we cannot fall back to the legacy WriteTo(CodedOutputStream)
// method and serializatin will fail. As a consequence, one can only use serialization
// to IBufferWriter if all the messages in the parsing tree have their generated
// code up to date.
var message = new ParseContextEnabledMessageB
{
A = new LegacyGeneratedCodeMessageA
{
Bb = new ParseContextEnabledMessageB { OptionalInt32 = 12345 }
},
OptionalInt32 = 6789
};
var exception = Assert.Throws<InvalidProtocolBufferException>(() =>
{
WriteContext.Initialize(new ArrayBufferWriter<byte>(), out WriteContext writeCtx);
((IBufferMessage)message).InternalWriteTo(ref writeCtx);
});
Assert.AreEqual($"Message {typeof(LegacyGeneratedCodeMessageA).Name} doesn't provide the generated method that enables WriteContext-based serialization. You might need to regenerate the generated protobuf code.", exception.Message);
}
// hand-modified version of a generated message that only provides the legacy
// MergeFrom(CodedInputStream) method and doesn't implement IBufferMessage.
private sealed partial class LegacyGeneratedCodeMessageA : pb::IMessage {
@ -178,18 +232,27 @@ namespace Google.Protobuf
}
public void WriteTo(pb::CodedOutputStream output) {
if (a_ != null) {
output.WriteRawMessage(this);
}
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output)
{
if (a_ != null)
{
output.WriteRawTag(10);
output.WriteMessage(A);
}
if (OptionalInt32 != 0) {
if (OptionalInt32 != 0)
{
output.WriteRawTag(16);
output.WriteInt32(OptionalInt32);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
if (_unknownFields != null)
{
_unknownFields.WriteTo(ref output);
}
}
public int CalculateSize() {
int size = 0;
if (a_ != null) {

@ -33,6 +33,7 @@
using NUnit.Framework;
using System;
using System.Buffers;
using Google.Protobuf.Buffers;
namespace Google.Protobuf
{
@ -81,6 +82,11 @@ namespace Google.Protobuf
{
var bytes = message.ToByteArray();
// also serialize using IBufferWriter and check it leads to the same data
var bufferWriter = new ArrayBufferWriter<byte>();
message.WriteTo(bufferWriter);
Assert.AreEqual(bytes, bufferWriter.WrittenSpan.ToArray(), "Both serialization approaches need to result in the same data.");
// Load content as single segment
var parsedBuffer = parser.ParseFrom(new ReadOnlySequence<byte>(bytes));
Assert.AreEqual(message, parsedBuffer);
@ -96,5 +102,41 @@ namespace Google.Protobuf
Assert.AreEqual(message, parsedStream);
additionalAssert?.Invoke(parsedStream);
}
public static void AssertWritingMessage(IMessage message)
{
// serialize using CodedOutputStream
var bytes = message.ToByteArray();
int messageSize = message.CalculateSize();
Assert.AreEqual(message.CalculateSize(), bytes.Length);
// serialize using IBufferWriter and check it leads to the same output
var bufferWriter = new ArrayBufferWriter<byte>();
message.WriteTo(bufferWriter);
Assert.AreEqual(bytes, bufferWriter.WrittenSpan.ToArray());
// serialize into a single span and check it leads to the same output
var singleSpan = new Span<byte>(new byte[messageSize]);
message.WriteTo(singleSpan);
Assert.AreEqual(bytes, singleSpan.ToArray());
// test for different IBufferWriter.GetSpan() segment sizes
for (int blockSize = 1; blockSize < 256; blockSize *= 2)
{
var segmentedBufferWriter = new ArrayBufferWriter<byte>();
segmentedBufferWriter.MaxGrowBy = blockSize;
message.WriteTo(segmentedBufferWriter);
Assert.AreEqual(bytes, segmentedBufferWriter.WrittenSpan.ToArray());
}
// if the full message is small enough, try serializing directly into stack-allocated buffer
if (bytes.Length <= 256)
{
Span<byte> stackAllocBuffer = stackalloc byte[bytes.Length];
message.WriteTo(stackAllocBuffer);
Assert.AreEqual(bytes, stackAllocBuffer.ToArray());
}
}
}
}

@ -71,6 +71,8 @@ namespace Google.Protobuf.WellKnownTypes
Uint64Field = 4
};
MessageParsingHelpers.AssertWritingMessage(message);
MessageParsingHelpers.AssertRoundtrip(TestWellKnownTypes.Parser, message, parsed =>
{
Assert.AreEqual("x", parsed.StringField);
@ -101,6 +103,8 @@ namespace Google.Protobuf.WellKnownTypes
Uint64Field = 0
};
MessageParsingHelpers.AssertWritingMessage(message);
MessageParsingHelpers.AssertRoundtrip(TestWellKnownTypes.Parser, message, parsed =>
{
Assert.AreEqual("", parsed.StringField);
@ -144,6 +148,8 @@ namespace Google.Protobuf.WellKnownTypes
// Just to test a single value for sanity...
Assert.AreEqual("Second", message.StringField[1]);
MessageParsingHelpers.AssertWritingMessage(message);
MessageParsingHelpers.AssertRoundtrip(RepeatedWellKnownTypes.Parser, message);
}
@ -169,6 +175,8 @@ namespace Google.Protobuf.WellKnownTypes
var message = new RepeatedWellKnownTypes { Int32Field = { 5, 0 } };
var actualBytes = message.ToByteArray();
Assert.AreEqual(expectedBytes, actualBytes);
MessageParsingHelpers.AssertWritingMessage(message);
}
[Test]
@ -196,6 +204,8 @@ namespace Google.Protobuf.WellKnownTypes
// Just to test a single value for sanity...
Assert.AreEqual("Second", message.StringField[12]);
MessageParsingHelpers.AssertWritingMessage(message);
MessageParsingHelpers.AssertRoundtrip(MapWellKnownTypes.Parser, message);
}

@ -132,7 +132,7 @@ namespace Google.Protobuf
/// </summary>
public static int ComputeStringSize(String value)
{
int byteArraySize = Utf8Encoding.GetByteCount(value);
int byteArraySize = WritingPrimitives.Utf8Encoding.GetByteCount(value);
return ComputeLengthSize(byteArraySize) + byteArraySize;
}
@ -208,7 +208,7 @@ namespace Google.Protobuf
/// </summary>
public static int ComputeSInt32Size(int value)
{
return ComputeRawVarint32Size(EncodeZigZag32(value));
return ComputeRawVarint32Size(WritingPrimitives.EncodeZigZag32(value));
}
/// <summary>
@ -217,7 +217,7 @@ namespace Google.Protobuf
/// </summary>
public static int ComputeSInt64Size(long value)
{
return ComputeRawVarint64Size(EncodeZigZag64(value));
return ComputeRawVarint64Size(WritingPrimitives.EncodeZigZag64(value));
}
/// <summary>

@ -33,6 +33,7 @@
using Google.Protobuf.Collections;
using System;
using System.IO;
using System.Security;
using System.Text;
namespace Google.Protobuf
@ -55,11 +56,9 @@ namespace Google.Protobuf
/// and <c>MapField&lt;TKey, TValue&gt;</c> to serialize such fields.
/// </para>
/// </remarks>
[SecuritySafeCritical]
public sealed partial class CodedOutputStream : IDisposable
{
// "Local" copy of Encoding.UTF8, for efficiency. (Yes, it makes a difference.)
internal static readonly Encoding Utf8Encoding = Encoding.UTF8;
/// <summary>
/// The buffer size used by CreateInstance(Stream).
/// </summary>
@ -67,8 +66,8 @@ namespace Google.Protobuf
private readonly bool leaveOpen;
private readonly byte[] buffer;
private readonly int limit;
private int position;
private WriterInternalState state;
private readonly Stream output;
#region Construction
@ -90,8 +89,9 @@ namespace Google.Protobuf
{
this.output = null;
this.buffer = ProtoPreconditions.CheckNotNull(buffer, nameof(buffer));
this.position = offset;
this.limit = offset + length;
this.state.position = offset;
this.state.limit = offset + length;
WriteBufferHelper.Initialize(this, out this.state.writeBufferHelper);
leaveOpen = true; // Simple way of avoiding trying to dispose of a null reference
}
@ -99,8 +99,9 @@ namespace Google.Protobuf
{
this.output = ProtoPreconditions.CheckNotNull(output, nameof(output));
this.buffer = buffer;
this.position = 0;
this.limit = buffer.Length;
this.state.position = 0;
this.state.limit = buffer.Length;
WriteBufferHelper.Initialize(this, out this.state.writeBufferHelper);
this.leaveOpen = leaveOpen;
}
@ -155,9 +156,9 @@ namespace Google.Protobuf
{
if (output != null)
{
return output.Position + position;
return output.Position + state.position;
}
return position;
return state.position;
}
}
@ -169,7 +170,8 @@ namespace Google.Protobuf
/// <param name="value">The value to write</param>
public void WriteDouble(double value)
{
WriteRawLittleEndian64((ulong)BitConverter.DoubleToInt64Bits(value));
var span = new Span<byte>(buffer);
WritingPrimitives.WriteDouble(ref span, ref state, value);
}
/// <summary>
@ -178,23 +180,8 @@ namespace Google.Protobuf
/// <param name="value">The value to write</param>
public void WriteFloat(float value)
{
byte[] rawBytes = BitConverter.GetBytes(value);
if (!BitConverter.IsLittleEndian)
{
ByteArray.Reverse(rawBytes);
}
if (limit - position >= 4)
{
buffer[position++] = rawBytes[0];
buffer[position++] = rawBytes[1];
buffer[position++] = rawBytes[2];
buffer[position++] = rawBytes[3];
}
else
{
WriteRawBytes(rawBytes, 0, 4);
}
var span = new Span<byte>(buffer);
WritingPrimitives.WriteFloat(ref span, ref state, value);
}
/// <summary>
@ -203,7 +190,8 @@ namespace Google.Protobuf
/// <param name="value">The value to write</param>
public void WriteUInt64(ulong value)
{
WriteRawVarint64(value);
var span = new Span<byte>(buffer);
WritingPrimitives.WriteUInt64(ref span, ref state, value);
}
/// <summary>
@ -212,7 +200,8 @@ namespace Google.Protobuf
/// <param name="value">The value to write</param>
public void WriteInt64(long value)
{
WriteRawVarint64((ulong) value);
var span = new Span<byte>(buffer);
WritingPrimitives.WriteInt64(ref span, ref state, value);
}
/// <summary>
@ -221,15 +210,8 @@ namespace Google.Protobuf
/// <param name="value">The value to write</param>
public void WriteInt32(int value)
{
if (value >= 0)
{
WriteRawVarint32((uint) value);
}
else
{
// Must sign-extend.
WriteRawVarint64((ulong) value);
}
var span = new Span<byte>(buffer);
WritingPrimitives.WriteInt32(ref span, ref state, value);
}
/// <summary>
@ -238,7 +220,8 @@ namespace Google.Protobuf
/// <param name="value">The value to write</param>
public void WriteFixed64(ulong value)
{
WriteRawLittleEndian64(value);
var span = new Span<byte>(buffer);
WritingPrimitives.WriteFixed64(ref span, ref state, value);
}
/// <summary>
@ -247,7 +230,8 @@ namespace Google.Protobuf
/// <param name="value">The value to write</param>
public void WriteFixed32(uint value)
{
WriteRawLittleEndian32(value);
var span = new Span<byte>(buffer);
WritingPrimitives.WriteFixed32(ref span, ref state, value);
}
/// <summary>
@ -256,7 +240,8 @@ namespace Google.Protobuf
/// <param name="value">The value to write</param>
public void WriteBool(bool value)
{
WriteRawByte(value ? (byte) 1 : (byte) 0);
var span = new Span<byte>(buffer);
WritingPrimitives.WriteBool(ref span, ref state, value);
}
/// <summary>
@ -266,41 +251,52 @@ namespace Google.Protobuf
/// <param name="value">The value to write</param>
public void WriteString(string value)
{
// Optimise the case where we have enough space to write
// the string directly to the buffer, which should be common.
int length = Utf8Encoding.GetByteCount(value);
WriteLength(length);
if (limit - position >= length)
var span = new Span<byte>(buffer);
WritingPrimitives.WriteString(ref span, ref state, value);
}
/// <summary>
/// Writes a message, without a tag, to the stream.
/// The data is length-prefixed.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteMessage(IMessage value)
{
// TODO(jtattermusch): if the message doesn't implement IBufferMessage (and thus does not provide the InternalWriteTo method),
// what we're doing here works fine, but could be more efficient.
// For now, this inefficiency is fine, considering this is only a backward-compatibility scenario (and regenerating the code fixes it).
var span = new Span<byte>(buffer);
WriteContext.Initialize(ref span, ref state, out WriteContext ctx);
try
{
if (length == value.Length) // Must be all ASCII...
{
for (int i = 0; i < length; i++)
{
buffer[position + i] = (byte)value[i];
}
}
else
{
Utf8Encoding.GetBytes(value, 0, value.Length, buffer, position);
}
position += length;
WritingPrimitivesMessages.WriteMessage(ref ctx, value);
}
else
finally
{
byte[] bytes = Utf8Encoding.GetBytes(value);
WriteRawBytes(bytes);
ctx.CopyStateTo(this);
}
}
/// <summary>
/// Writes a message, without a tag, to the stream.
/// The data is length-prefixed.
/// Only the message data is written, without a length-delimiter.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteMessage(IMessage value)
{
WriteLength(value.CalculateSize());
value.WriteTo(this);
public void WriteRawMessage(IMessage value)
{
// TODO(jtattermusch): if the message doesn't implement IBufferMessage (and thus does not provide the InternalWriteTo method),
// what we're doing here works fine, but could be more efficient.
// For now, this inefficiency is fine, considering this is only a backward-compatibility scenario (and regenerating the code fixes it).
var span = new Span<byte>(buffer);
WriteContext.Initialize(ref span, ref state, out WriteContext ctx);
try
{
WritingPrimitivesMessages.WriteRawMessage(ref ctx, value);
}
finally
{
ctx.CopyStateTo(this);
}
}
/// <summary>
@ -309,7 +305,16 @@ namespace Google.Protobuf
/// <param name="value">The value to write</param>
public void WriteGroup(IMessage value)
{
value.WriteTo(this);
var span = new Span<byte>(buffer);
WriteContext.Initialize(ref span, ref state, out WriteContext ctx);
try
{
WritingPrimitivesMessages.WriteGroup(ref ctx, value);
}
finally
{
ctx.CopyStateTo(this);
}
}
/// <summary>
@ -319,8 +324,8 @@ namespace Google.Protobuf
/// <param name="value">The value to write</param>
public void WriteBytes(ByteString value)
{
WriteLength(value.Length);
value.WriteRawBytesTo(this);
var span = new Span<byte>(buffer);
WritingPrimitives.WriteBytes(ref span, ref state, value);
}
/// <summary>
@ -329,7 +334,8 @@ namespace Google.Protobuf
/// <param name="value">The value to write</param>
public void WriteUInt32(uint value)
{
WriteRawVarint32(value);
var span = new Span<byte>(buffer);
WritingPrimitives.WriteUInt32(ref span, ref state, value);
}
/// <summary>
@ -338,7 +344,8 @@ namespace Google.Protobuf
/// <param name="value">The value to write</param>
public void WriteEnum(int value)
{
WriteInt32(value);
var span = new Span<byte>(buffer);
WritingPrimitives.WriteEnum(ref span, ref state, value);
}
/// <summary>
@ -347,7 +354,8 @@ namespace Google.Protobuf
/// <param name="value">The value to write.</param>
public void WriteSFixed32(int value)
{
WriteRawLittleEndian32((uint) value);
var span = new Span<byte>(buffer);
WritingPrimitives.WriteSFixed32(ref span, ref state, value);
}
/// <summary>
@ -356,7 +364,8 @@ namespace Google.Protobuf
/// <param name="value">The value to write</param>
public void WriteSFixed64(long value)
{
WriteRawLittleEndian64((ulong) value);
var span = new Span<byte>(buffer);
WritingPrimitives.WriteSFixed64(ref span, ref state, value);
}
/// <summary>
@ -365,7 +374,8 @@ namespace Google.Protobuf
/// <param name="value">The value to write</param>
public void WriteSInt32(int value)
{
WriteRawVarint32(EncodeZigZag32(value));
var span = new Span<byte>(buffer);
WritingPrimitives.WriteSInt32(ref span, ref state, value);
}
/// <summary>
@ -374,7 +384,8 @@ namespace Google.Protobuf
/// <param name="value">The value to write</param>
public void WriteSInt64(long value)
{
WriteRawVarint64(EncodeZigZag64(value));
var span = new Span<byte>(buffer);
WritingPrimitives.WriteSInt64(ref span, ref state, value);
}
/// <summary>
@ -386,7 +397,8 @@ namespace Google.Protobuf
/// <param name="length">Length value, in bytes.</param>
public void WriteLength(int length)
{
WriteRawVarint32((uint) length);
var span = new Span<byte>(buffer);
WritingPrimitives.WriteLength(ref span, ref state, length);
}
#endregion
@ -399,7 +411,8 @@ namespace Google.Protobuf
/// <param name="type">The wire format type of the tag to write</param>
public void WriteTag(int fieldNumber, WireFormat.WireType type)
{
WriteRawVarint32(WireFormat.MakeTag(fieldNumber, type));
var span = new Span<byte>(buffer);
WritingPrimitives.WriteTag(ref span, ref state, fieldNumber, type);
}
/// <summary>
@ -408,7 +421,8 @@ namespace Google.Protobuf
/// <param name="tag">The encoded tag</param>
public void WriteTag(uint tag)
{
WriteRawVarint32(tag);
var span = new Span<byte>(buffer);
WritingPrimitives.WriteTag(ref span, ref state, tag);
}
/// <summary>
@ -417,7 +431,8 @@ namespace Google.Protobuf
/// <param name="b1">The encoded tag</param>
public void WriteRawTag(byte b1)
{
WriteRawByte(b1);
var span = new Span<byte>(buffer);
WritingPrimitives.WriteRawTag(ref span, ref state, b1);
}
/// <summary>
@ -427,8 +442,8 @@ namespace Google.Protobuf
/// <param name="b2">The second byte of the encoded tag</param>
public void WriteRawTag(byte b1, byte b2)
{
WriteRawByte(b1);
WriteRawByte(b2);
var span = new Span<byte>(buffer);
WritingPrimitives.WriteRawTag(ref span, ref state, b1, b2);
}
/// <summary>
@ -439,9 +454,8 @@ namespace Google.Protobuf
/// <param name="b3">The third byte of the encoded tag</param>
public void WriteRawTag(byte b1, byte b2, byte b3)
{
WriteRawByte(b1);
WriteRawByte(b2);
WriteRawByte(b3);
var span = new Span<byte>(buffer);
WritingPrimitives.WriteRawTag(ref span, ref state, b1, b2, b3);
}
/// <summary>
@ -453,10 +467,8 @@ namespace Google.Protobuf
/// <param name="b4">The fourth byte of the encoded tag</param>
public void WriteRawTag(byte b1, byte b2, byte b3, byte b4)
{
WriteRawByte(b1);
WriteRawByte(b2);
WriteRawByte(b3);
WriteRawByte(b4);
var span = new Span<byte>(buffer);
WritingPrimitives.WriteRawTag(ref span, ref state, b1, b2, b3, b4);
}
/// <summary>
@ -469,15 +481,13 @@ namespace Google.Protobuf
/// <param name="b5">The fifth byte of the encoded tag</param>
public void WriteRawTag(byte b1, byte b2, byte b3, byte b4, byte b5)
{
WriteRawByte(b1);
WriteRawByte(b2);
WriteRawByte(b3);
WriteRawByte(b4);
WriteRawByte(b5);
var span = new Span<byte>(buffer);
WritingPrimitives.WriteRawTag(ref span, ref state, b1, b2, b3, b4, b5);
}
#endregion
#region Underlying writing primitives
/// <summary>
/// Writes a 32 bit value as a varint. The fast route is taken when
/// there's enough buffer space left to whizz through without checking
@ -485,112 +495,26 @@ namespace Google.Protobuf
/// </summary>
internal void WriteRawVarint32(uint value)
{
// Optimize for the common case of a single byte value
if (value < 128 && position < limit)
{
buffer[position++] = (byte)value;
return;
}
while (value > 127 && position < limit)
{
buffer[position++] = (byte) ((value & 0x7F) | 0x80);
value >>= 7;
}
while (value > 127)
{
WriteRawByte((byte) ((value & 0x7F) | 0x80));
value >>= 7;
}
if (position < limit)
{
buffer[position++] = (byte) value;
}
else
{
WriteRawByte((byte) value);
}
var span = new Span<byte>(buffer);
WritingPrimitives.WriteRawVarint32(ref span, ref state, value);
}
internal void WriteRawVarint64(ulong value)
{
while (value > 127 && position < limit)
{
buffer[position++] = (byte) ((value & 0x7F) | 0x80);
value >>= 7;
}
while (value > 127)
{
WriteRawByte((byte) ((value & 0x7F) | 0x80));
value >>= 7;
}
if (position < limit)
{
buffer[position++] = (byte) value;
}
else
{
WriteRawByte((byte) value);
}
var span = new Span<byte>(buffer);
WritingPrimitives.WriteRawVarint64(ref span, ref state, value);
}
internal void WriteRawLittleEndian32(uint value)
{
if (position + 4 > limit)
{
WriteRawByte((byte) value);
WriteRawByte((byte) (value >> 8));
WriteRawByte((byte) (value >> 16));
WriteRawByte((byte) (value >> 24));
}
else
{
buffer[position++] = ((byte) value);
buffer[position++] = ((byte) (value >> 8));
buffer[position++] = ((byte) (value >> 16));
buffer[position++] = ((byte) (value >> 24));
}
var span = new Span<byte>(buffer);
WritingPrimitives.WriteRawLittleEndian32(ref span, ref state, value);
}
internal void WriteRawLittleEndian64(ulong value)
{
if (position + 8 > limit)
{
WriteRawByte((byte) value);
WriteRawByte((byte) (value >> 8));
WriteRawByte((byte) (value >> 16));
WriteRawByte((byte) (value >> 24));
WriteRawByte((byte) (value >> 32));
WriteRawByte((byte) (value >> 40));
WriteRawByte((byte) (value >> 48));
WriteRawByte((byte) (value >> 56));
}
else
{
buffer[position++] = ((byte) value);
buffer[position++] = ((byte) (value >> 8));
buffer[position++] = ((byte) (value >> 16));
buffer[position++] = ((byte) (value >> 24));
buffer[position++] = ((byte) (value >> 32));
buffer[position++] = ((byte) (value >> 40));
buffer[position++] = ((byte) (value >> 48));
buffer[position++] = ((byte) (value >> 56));
}
}
internal void WriteRawByte(byte value)
{
if (position == limit)
{
RefreshBuffer();
}
buffer[position++] = value;
}
internal void WriteRawByte(uint value)
{
WriteRawByte((byte) value);
var span = new Span<byte>(buffer);
WritingPrimitives.WriteRawLittleEndian64(ref span, ref state, value);
}
/// <summary>
@ -606,85 +530,12 @@ namespace Google.Protobuf
/// </summary>
internal void WriteRawBytes(byte[] value, int offset, int length)
{
if (limit - position >= length)
{
ByteArray.Copy(value, offset, buffer, position, length);
// We have room in the current buffer.
position += length;
}
else
{
// Write extends past current buffer. Fill the rest of this buffer and
// flush.
int bytesWritten = limit - position;
ByteArray.Copy(value, offset, buffer, position, bytesWritten);
offset += bytesWritten;
length -= bytesWritten;
position = limit;
RefreshBuffer();
// Now deal with the rest.
// Since we have an output stream, this is our buffer
// and buffer offset == 0
if (length <= limit)
{
// Fits in new buffer.
ByteArray.Copy(value, offset, buffer, 0, length);
position = length;
}
else
{
// Write is very big. Let's do it all at once.
output.Write(value, offset, length);
}
}
var span = new Span<byte>(buffer);
WritingPrimitives.WriteRawBytes(ref span, ref state, value, offset, length);
}
#endregion
/// <summary>
/// Encode a 32-bit value with ZigZag encoding.
/// </summary>
/// <remarks>
/// ZigZag encodes signed integers into values that can be efficiently
/// encoded with varint. (Otherwise, negative values must be
/// sign-extended to 64 bits to be varint encoded, thus always taking
/// 10 bytes on the wire.)
/// </remarks>
internal static uint EncodeZigZag32(int n)
{
// Note: the right-shift must be arithmetic
return (uint) ((n << 1) ^ (n >> 31));
}
/// <summary>
/// Encode a 64-bit value with ZigZag encoding.
/// </summary>
/// <remarks>
/// ZigZag encodes signed integers into values that can be efficiently
/// encoded with varint. (Otherwise, negative values must be
/// sign-extended to 64 bits to be varint encoded, thus always taking
/// 10 bytes on the wire.)
/// </remarks>
internal static ulong EncodeZigZag64(long n)
{
return (ulong) ((n << 1) ^ (n >> 63));
}
private void RefreshBuffer()
{
if (output == null)
{
// We're writing to a single buffer.
throw new OutOfSpaceException();
}
// Since we have an output stream, this is our buffer
// and buffer offset == 0
output.Write(buffer, 0, position);
position = 0;
}
/// <summary>
/// Indicates that a CodedOutputStream wrapping a flat byte array
/// ran out of space.
@ -726,45 +577,31 @@ namespace Google.Protobuf
/// </summary>
public void Flush()
{
if (output != null)
{
RefreshBuffer();
}
var span = new Span<byte>(buffer);
WriteBufferHelper.Flush(ref span, ref state);
}
/// <summary>
/// Verifies that SpaceLeft returns zero. It's common to create a byte array
/// that is exactly big enough to hold a message, then write to it with
/// a CodedOutputStream. Calling CheckNoSpaceLeft after writing verifies that
/// the message was actually as big as expected, which can help bugs.
/// the message was actually as big as expected, which can help finding bugs.
/// </summary>
public void CheckNoSpaceLeft()
{
if (SpaceLeft != 0)
{
throw new InvalidOperationException("Did not write as much data as expected.");
}
WriteBufferHelper.CheckNoSpaceLeft(ref state);
}
/// <summary>
/// If writing to a flat array, returns the space left in the array. Otherwise,
/// throws an InvalidOperationException.
/// </summary>
public int SpaceLeft
{
get
{
if (output == null)
{
return limit - position;
}
else
{
throw new InvalidOperationException(
"SpaceLeft can only be called on CodedOutputStreams that are " +
"writing to a flat array.");
}
}
}
public int SpaceLeft => WriteBufferHelper.GetSpaceLeft(ref state);
internal byte[] InternalBuffer => buffer;
internal Stream InternalOutputStream => output;
internal ref WriterInternalState InternalState => ref state;
}
}

@ -464,14 +464,34 @@ namespace Google.Protobuf.Collections
/// <param name="output">The output stream to write to.</param>
/// <param name="codec">The codec to use for each entry.</param>
public void WriteTo(CodedOutputStream output, Codec codec)
{
WriteContext.Initialize(output, out WriteContext ctx);
try
{
WriteTo(ref ctx, codec);
}
finally
{
ctx.CopyStateTo(output);
}
}
/// <summary>
/// Writes the contents of this map to the given write context, using the specified codec
/// to encode each entry.
/// </summary>
/// <param name="ctx">The write context to write to.</param>
/// <param name="codec">The codec to use for each entry.</param>
[SecuritySafeCritical]
public void WriteTo(ref WriteContext ctx, Codec codec)
{
var message = new Codec.MessageAdapter(codec);
foreach (var entry in list)
{
message.Key = entry.Key;
message.Value = entry.Value;
output.WriteTag(codec.MapTag);
output.WriteMessage(message);
ctx.WriteTag(codec.MapTag);
ctx.WriteMessage(message);
}
}
@ -711,8 +731,15 @@ namespace Google.Protobuf.Collections
public void WriteTo(CodedOutputStream output)
{
codec.keyCodec.WriteTagAndValue(output, Key);
codec.valueCodec.WriteTagAndValue(output, Value);
// Message adapter is an internal class and we know that all the writing will happen via InternalWriteTo.
throw new NotImplementedException();
}
[SecuritySafeCritical]
public void InternalWriteTo(ref WriteContext ctx)
{
codec.keyCodec.WriteTagAndValue(ref ctx, Key);
codec.valueCodec.WriteTagAndValue(ref ctx, Value);
}
public int CalculateSize()

@ -189,7 +189,7 @@ namespace Google.Protobuf.Collections
/// Calculates the size of this collection based on the given codec.
/// </summary>
/// <param name="codec">The codec to use when encoding each field.</param>
/// <returns>The number of bytes that would be written to a <see cref="CodedOutputStream"/> by <see cref="WriteTo"/>,
/// <returns>The number of bytes that would be written to an output by one of the <c>WriteTo</c> methods,
/// using the same codec.</returns>
public int CalculateSize(FieldCodec<T> codec)
{
@ -247,6 +247,26 @@ namespace Google.Protobuf.Collections
/// <param name="output">The output stream to write to.</param>
/// <param name="codec">The codec to use when encoding each value.</param>
public void WriteTo(CodedOutputStream output, FieldCodec<T> codec)
{
WriteContext.Initialize(output, out WriteContext ctx);
try
{
WriteTo(ref ctx, codec);
}
finally
{
ctx.CopyStateTo(output);
}
}
/// <summary>
/// Writes the contents of this collection to the given write context,
/// encoding each value using the specified codec.
/// </summary>
/// <param name="ctx">The write context to write to.</param>
/// <param name="codec">The codec to use when encoding each value.</param>
[SecuritySafeCritical]
public void WriteTo(ref WriteContext ctx, FieldCodec<T> codec)
{
if (count == 0)
{
@ -257,12 +277,12 @@ namespace Google.Protobuf.Collections
if (codec.PackedRepeatedField)
{
// Packed primitive type
uint size = (uint)CalculatePackedDataSize(codec);
output.WriteTag(tag);
output.WriteRawVarint32(size);
int size = CalculatePackedDataSize(codec);
ctx.WriteTag(tag);
ctx.WriteLength(size);
for (int i = 0; i < count; i++)
{
writer(output, array[i]);
writer(ref ctx, array[i]);
}
}
else
@ -271,11 +291,11 @@ namespace Google.Protobuf.Collections
// Can't use codec.WriteTagAndValue, as that omits default values.
for (int i = 0; i < count; i++)
{
output.WriteTag(tag);
writer(output, array[i]);
ctx.WriteTag(tag);
writer(ref ctx, array[i]);
if (codec.EndTag != 0)
{
output.WriteTag(codec.EndTag);
ctx.WriteTag(codec.EndTag);
}
}
}

@ -34,6 +34,7 @@ using Google.Protobuf.Collections;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security;
namespace Google.Protobuf
{
@ -343,10 +344,28 @@ namespace Google.Protobuf
/// Writes the extension values in this set to the output stream
/// </summary>
public void WriteTo(CodedOutputStream stream)
{
WriteContext.Initialize(stream, out WriteContext ctx);
try
{
WriteTo(ref ctx);
}
finally
{
ctx.CopyStateTo(stream);
}
}
/// <summary>
/// Writes the extension values in this set to the write context
/// </summary>
[SecuritySafeCritical]
public void WriteTo(ref WriteContext ctx)
{
foreach (var value in ValuesByNumber.Values)
{
value.WriteTo(stream);
value.WriteTo(ref ctx);
}
}

@ -41,7 +41,7 @@ namespace Google.Protobuf
void MergeFrom(ref ParseContext ctx);
void MergeFrom(IExtensionValue value);
void WriteTo(CodedOutputStream output);
void WriteTo(ref WriteContext ctx);
int CalculateSize();
bool IsInitialized();
}
@ -106,13 +106,13 @@ namespace Google.Protobuf
}
}
public void WriteTo(CodedOutputStream output)
public void WriteTo(ref WriteContext ctx)
{
output.WriteTag(codec.Tag);
codec.ValueWriter(output, field);
ctx.WriteTag(codec.Tag);
codec.ValueWriter(ref ctx, field);
if (codec.EndTag != 0)
{
output.WriteTag(codec.EndTag);
ctx.WriteTag(codec.EndTag);
}
}
@ -181,11 +181,6 @@ namespace Google.Protobuf
}
}
public void MergeFrom(CodedInputStream input)
{
field.AddEntriesFrom(input, codec);
}
public void MergeFrom(ref ParseContext ctx)
{
field.AddEntriesFrom(ref ctx, codec);
@ -199,9 +194,9 @@ namespace Google.Protobuf
}
}
public void WriteTo(CodedOutputStream output)
public void WriteTo(ref WriteContext ctx)
{
field.WriteTo(output, codec);
field.WriteTo(ref ctx, codec);
}
public RepeatedField<T> GetValue() => field;

@ -219,7 +219,7 @@ namespace Google.Protobuf
/// <returns>A codec for the given tag.</returns>
public static FieldCodec<string> ForString(uint tag, string defaultValue)
{
return new FieldCodec<string>((ref ParseContext ctx) => ctx.ReadString(), (output, value) => output.WriteString(value), CodedOutputStream.ComputeStringSize, tag, defaultValue);
return new FieldCodec<string>((ref ParseContext ctx) => ctx.ReadString(), (ref WriteContext ctx, string value) => ctx.WriteString(value), CodedOutputStream.ComputeStringSize, tag, defaultValue);
}
/// <summary>
@ -230,7 +230,7 @@ namespace Google.Protobuf
/// <returns>A codec for the given tag.</returns>
public static FieldCodec<ByteString> ForBytes(uint tag, ByteString defaultValue)
{
return new FieldCodec<ByteString>((ref ParseContext ctx) => ctx.ReadBytes(), (output, value) => output.WriteBytes(value), CodedOutputStream.ComputeBytesSize, tag, defaultValue);
return new FieldCodec<ByteString>((ref ParseContext ctx) => ctx.ReadBytes(), (ref WriteContext ctx, ByteString value) => ctx.WriteBytes(value), CodedOutputStream.ComputeBytesSize, tag, defaultValue);
}
/// <summary>
@ -241,7 +241,7 @@ namespace Google.Protobuf
/// <returns>A codec for the given tag.</returns>
public static FieldCodec<bool> ForBool(uint tag, bool defaultValue)
{
return new FieldCodec<bool>((ref ParseContext ctx) => ctx.ReadBool(), (output, value) => output.WriteBool(value), CodedOutputStream.BoolSize, tag, defaultValue);
return new FieldCodec<bool>((ref ParseContext ctx) => ctx.ReadBool(), (ref WriteContext ctx, bool value) => ctx.WriteBool(value), CodedOutputStream.BoolSize, tag, defaultValue);
}
/// <summary>
@ -252,7 +252,7 @@ namespace Google.Protobuf
/// <returns>A codec for the given tag.</returns>
public static FieldCodec<int> ForInt32(uint tag, int defaultValue)
{
return new FieldCodec<int>((ref ParseContext ctx) => ctx.ReadInt32(), (output, value) => output.WriteInt32(value), CodedOutputStream.ComputeInt32Size, tag, defaultValue);
return new FieldCodec<int>((ref ParseContext ctx) => ctx.ReadInt32(), (ref WriteContext output, int value) => output.WriteInt32(value), CodedOutputStream.ComputeInt32Size, tag, defaultValue);
}
/// <summary>
@ -263,7 +263,7 @@ namespace Google.Protobuf
/// <returns>A codec for the given tag.</returns>
public static FieldCodec<int> ForSInt32(uint tag, int defaultValue)
{
return new FieldCodec<int>((ref ParseContext ctx) => ctx.ReadSInt32(), (output, value) => output.WriteSInt32(value), CodedOutputStream.ComputeSInt32Size, tag, defaultValue);
return new FieldCodec<int>((ref ParseContext ctx) => ctx.ReadSInt32(), (ref WriteContext output, int value) => output.WriteSInt32(value), CodedOutputStream.ComputeSInt32Size, tag, defaultValue);
}
/// <summary>
@ -274,7 +274,7 @@ namespace Google.Protobuf
/// <returns>A codec for the given tag.</returns>
public static FieldCodec<uint> ForFixed32(uint tag, uint defaultValue)
{
return new FieldCodec<uint>((ref ParseContext ctx) => ctx.ReadFixed32(), (output, value) => output.WriteFixed32(value), 4, tag, defaultValue);
return new FieldCodec<uint>((ref ParseContext ctx) => ctx.ReadFixed32(), (ref WriteContext output, uint value) => output.WriteFixed32(value), 4, tag, defaultValue);
}
/// <summary>
@ -285,7 +285,7 @@ namespace Google.Protobuf
/// <returns>A codec for the given tag.</returns>
public static FieldCodec<int> ForSFixed32(uint tag, int defaultValue)
{
return new FieldCodec<int>((ref ParseContext ctx) => ctx.ReadSFixed32(), (output, value) => output.WriteSFixed32(value), 4, tag, defaultValue);
return new FieldCodec<int>((ref ParseContext ctx) => ctx.ReadSFixed32(), (ref WriteContext output, int value) => output.WriteSFixed32(value), 4, tag, defaultValue);
}
/// <summary>
@ -296,7 +296,7 @@ namespace Google.Protobuf
/// <returns>A codec for the given tag.</returns>
public static FieldCodec<uint> ForUInt32(uint tag, uint defaultValue)
{
return new FieldCodec<uint>((ref ParseContext ctx) => ctx.ReadUInt32(), (output, value) => output.WriteUInt32(value), CodedOutputStream.ComputeUInt32Size, tag, defaultValue);
return new FieldCodec<uint>((ref ParseContext ctx) => ctx.ReadUInt32(), (ref WriteContext output, uint value) => output.WriteUInt32(value), CodedOutputStream.ComputeUInt32Size, tag, defaultValue);
}
/// <summary>
@ -307,7 +307,7 @@ namespace Google.Protobuf
/// <returns>A codec for the given tag.</returns>
public static FieldCodec<long> ForInt64(uint tag, long defaultValue)
{
return new FieldCodec<long>((ref ParseContext ctx) => ctx.ReadInt64(), (output, value) => output.WriteInt64(value), CodedOutputStream.ComputeInt64Size, tag, defaultValue);
return new FieldCodec<long>((ref ParseContext ctx) => ctx.ReadInt64(), (ref WriteContext output, long value) => output.WriteInt64(value), CodedOutputStream.ComputeInt64Size, tag, defaultValue);
}
/// <summary>
@ -318,7 +318,7 @@ namespace Google.Protobuf
/// <returns>A codec for the given tag.</returns>
public static FieldCodec<long> ForSInt64(uint tag, long defaultValue)
{
return new FieldCodec<long>((ref ParseContext ctx) => ctx.ReadSInt64(), (output, value) => output.WriteSInt64(value), CodedOutputStream.ComputeSInt64Size, tag, defaultValue);
return new FieldCodec<long>((ref ParseContext ctx) => ctx.ReadSInt64(), (ref WriteContext output, long value) => output.WriteSInt64(value), CodedOutputStream.ComputeSInt64Size, tag, defaultValue);
}
/// <summary>
@ -329,7 +329,7 @@ namespace Google.Protobuf
/// <returns>A codec for the given tag.</returns>
public static FieldCodec<ulong> ForFixed64(uint tag, ulong defaultValue)
{
return new FieldCodec<ulong>((ref ParseContext ctx) => ctx.ReadFixed64(), (output, value) => output.WriteFixed64(value), 8, tag, defaultValue);
return new FieldCodec<ulong>((ref ParseContext ctx) => ctx.ReadFixed64(), (ref WriteContext output, ulong value) => output.WriteFixed64(value), 8, tag, defaultValue);
}
/// <summary>
@ -340,7 +340,7 @@ namespace Google.Protobuf
/// <returns>A codec for the given tag.</returns>
public static FieldCodec<long> ForSFixed64(uint tag, long defaultValue)
{
return new FieldCodec<long>((ref ParseContext ctx) => ctx.ReadSFixed64(), (output, value) => output.WriteSFixed64(value), 8, tag, defaultValue);
return new FieldCodec<long>((ref ParseContext ctx) => ctx.ReadSFixed64(), (ref WriteContext output, long value) => output.WriteSFixed64(value), 8, tag, defaultValue);
}
/// <summary>
@ -351,7 +351,7 @@ namespace Google.Protobuf
/// <returns>A codec for the given tag.</returns>
public static FieldCodec<ulong> ForUInt64(uint tag, ulong defaultValue)
{
return new FieldCodec<ulong>((ref ParseContext ctx) => ctx.ReadUInt64(), (output, value) => output.WriteUInt64(value), CodedOutputStream.ComputeUInt64Size, tag, defaultValue);
return new FieldCodec<ulong>((ref ParseContext ctx) => ctx.ReadUInt64(), (ref WriteContext output, ulong value) => output.WriteUInt64(value), CodedOutputStream.ComputeUInt64Size, tag, defaultValue);
}
/// <summary>
@ -362,7 +362,7 @@ namespace Google.Protobuf
/// <returns>A codec for the given tag.</returns>
public static FieldCodec<float> ForFloat(uint tag, float defaultValue)
{
return new FieldCodec<float>((ref ParseContext ctx) => ctx.ReadFloat(), (output, value) => output.WriteFloat(value), CodedOutputStream.FloatSize, tag, defaultValue);
return new FieldCodec<float>((ref ParseContext ctx) => ctx.ReadFloat(), (ref WriteContext output, float value) => output.WriteFloat(value), CodedOutputStream.FloatSize, tag, defaultValue);
}
/// <summary>
@ -373,7 +373,7 @@ namespace Google.Protobuf
/// <returns>A codec for the given tag.</returns>
public static FieldCodec<double> ForDouble(uint tag, double defaultValue)
{
return new FieldCodec<double>((ref ParseContext ctx) => ctx.ReadDouble(), (output, value) => output.WriteDouble(value), CodedOutputStream.DoubleSize, tag, defaultValue);
return new FieldCodec<double>((ref ParseContext ctx) => ctx.ReadDouble(), (ref WriteContext output, double value) => output.WriteDouble(value), CodedOutputStream.DoubleSize, tag, defaultValue);
}
// Enums are tricky. We can probably use expression trees to build these delegates automatically,
@ -391,7 +391,7 @@ namespace Google.Protobuf
{
return new FieldCodec<T>((ref ParseContext ctx) => fromInt32(
ctx.ReadEnum()),
(output, value) => output.WriteEnum(toInt32(value)),
(ref WriteContext output, T value) => output.WriteEnum(toInt32(value)),
value => CodedOutputStream.ComputeEnumSize(toInt32(value)), tag, defaultValue);
}
@ -410,7 +410,7 @@ namespace Google.Protobuf
ctx.ReadMessage(message);
return message;
},
(output, value) => output.WriteMessage(value),
(ref WriteContext output, T value) => output.WriteMessage(value),
(ref ParseContext ctx, ref T v) =>
{
if (v == null)
@ -455,7 +455,7 @@ namespace Google.Protobuf
ctx.ReadGroup(message);
return message;
},
(output, value) => output.WriteGroup(value),
(ref WriteContext output, T value) => output.WriteGroup(value),
(ref ParseContext ctx, ref T v) =>
{
if (v == null)
@ -492,7 +492,7 @@ namespace Google.Protobuf
var nestedCodec = WrapperCodecs.GetCodec<T>();
return new FieldCodec<T>(
(ref ParseContext ctx) => WrapperCodecs.Read<T>(ref ctx, nestedCodec),
(output, value) => WrapperCodecs.Write<T>(output, value, nestedCodec),
(ref WriteContext output, T value) => WrapperCodecs.Write<T>(ref output, value, nestedCodec),
(ref ParseContext ctx, ref T v) => v = WrapperCodecs.Read<T>(ref ctx, nestedCodec),
(ref T v, T v2) => { v = v2; return v == null; },
value => WrapperCodecs.CalculateSize<T>(value, nestedCodec),
@ -509,7 +509,7 @@ namespace Google.Protobuf
var nestedCodec = WrapperCodecs.GetCodec<T>();
return new FieldCodec<T?>(
WrapperCodecs.GetReader<T>(),
(output, value) => WrapperCodecs.Write<T>(output, value.Value, nestedCodec),
(ref WriteContext output, T? value) => WrapperCodecs.Write<T>(ref output, value.Value, nestedCodec),
(ref ParseContext ctx, ref T? v) => v = WrapperCodecs.Read<T>(ref ctx, nestedCodec),
(ref T? v, T? v2) => { if (v2.HasValue) { v = v2; } return v.HasValue; },
value => value == null ? 0 : WrapperCodecs.CalculateSize<T>(value.Value, nestedCodec),
@ -616,10 +616,10 @@ namespace Google.Protobuf
return value;
}
internal static void Write<T>(CodedOutputStream output, T value, FieldCodec<T> codec)
internal static void Write<T>(ref WriteContext ctx, T value, FieldCodec<T> codec)
{
output.WriteLength(codec.CalculateSizeWithTag(value));
codec.WriteTagAndValue(output, value);
ctx.WriteLength(codec.CalculateSizeWithTag(value));
codec.WriteTagAndValue(ref ctx, value);
}
internal static int CalculateSize<T>(T value, FieldCodec<T> codec)
@ -631,6 +631,7 @@ namespace Google.Protobuf
}
internal delegate TValue ValueReader<out TValue>(ref ParseContext ctx);
internal delegate void ValueWriter<T>(ref WriteContext ctx, T value);
/// <summary>
/// <para>
@ -685,7 +686,7 @@ namespace Google.Protobuf
/// <summary>
/// Returns a delegate to write a value (unconditionally) to a coded output stream.
/// </summary>
internal Action<CodedOutputStream, T> ValueWriter { get; }
internal ValueWriter<T> ValueWriter { get; }
/// <summary>
/// Returns the size calculator for just a value.
@ -744,7 +745,7 @@ namespace Google.Protobuf
internal FieldCodec(
ValueReader<T> reader,
Action<CodedOutputStream, T> writer,
ValueWriter<T> writer,
int fixedSize,
uint tag,
T defaultValue) : this(reader, writer, _ => fixedSize, tag, defaultValue)
@ -754,7 +755,7 @@ namespace Google.Protobuf
internal FieldCodec(
ValueReader<T> reader,
Action<CodedOutputStream, T> writer,
ValueWriter<T> writer,
Func<T, int> sizeCalculator,
uint tag,
T defaultValue) : this(reader, writer, (ref ParseContext ctx, ref T v) => v = reader(ref ctx), (ref T v, T v2) => { v = v2; return true; }, sizeCalculator, tag, 0, defaultValue)
@ -763,7 +764,7 @@ namespace Google.Protobuf
internal FieldCodec(
ValueReader<T> reader,
Action<CodedOutputStream, T> writer,
ValueWriter<T> writer,
InputMerger inputMerger,
ValuesMerger valuesMerger,
Func<T, int> sizeCalculator,
@ -774,7 +775,7 @@ namespace Google.Protobuf
internal FieldCodec(
ValueReader<T> reader,
Action<CodedOutputStream, T> writer,
ValueWriter<T> writer,
InputMerger inputMerger,
ValuesMerger valuesMerger,
Func<T, int> sizeCalculator,
@ -802,14 +803,41 @@ namespace Google.Protobuf
/// Write a tag and the given value, *if* the value is not the default.
/// </summary>
public void WriteTagAndValue(CodedOutputStream output, T value)
{
WriteContext.Initialize(output, out WriteContext ctx);
try
{
WriteTagAndValue(ref ctx, value);
}
finally
{
ctx.CopyStateTo(output);
}
//if (!IsDefault(value))
//{
// output.WriteTag(Tag);
// ValueWriter(output, value);
// if (EndTag != 0)
// {
// output.WriteTag(EndTag);
// }
//}
}
/// <summary>
/// Write a tag and the given value, *if* the value is not the default.
/// </summary>
public void WriteTagAndValue(ref WriteContext ctx, T value)
{
if (!IsDefault(value))
{
output.WriteTag(Tag);
ValueWriter(output, value);
ctx.WriteTag(Tag);
ValueWriter(ref ctx, value);
if (EndTag != 0)
{
output.WriteTag(EndTag);
ctx.WriteTag(EndTag);
}
}
}

@ -35,7 +35,7 @@ namespace Google.Protobuf
#if GOOGLE_PROTOBUF_SUPPORT_SYSTEM_MEMORY
/// <summary>
/// Interface for a Protocol Buffers message, supporting
/// parsing from <see cref="ParseContext"/>.
/// parsing from <see cref="ParseContext"/> and writing to <see cref="WriteContext"/>.
/// </summary>
public interface IBufferMessage : IMessage
{
@ -44,6 +44,12 @@ namespace Google.Protobuf
/// Users should never invoke this method directly.
/// </summary>
void InternalMergeFrom(ref ParseContext ctx);
/// <summary>
/// Internal implementation of writing this message to a given write context.
/// Users should never invoke this method directly.
/// </summary>
void InternalWriteTo(ref WriteContext ctx);
}
#endif
}

@ -33,6 +33,7 @@
using Google.Protobuf.Reflection;
using System.Buffers;
using System.Collections;
using System;
using System.IO;
using System.Linq;
using System.Security;
@ -129,7 +130,7 @@ namespace Google.Protobuf
ProtoPreconditions.CheckNotNull(message, "message");
ProtoPreconditions.CheckNotNull(output, "output");
CodedOutputStream codedOutput = new CodedOutputStream(output);
codedOutput.WriteRawVarint32((uint)message.CalculateSize());
codedOutput.WriteLength(message.CalculateSize());
message.WriteTo(codedOutput);
codedOutput.Flush();
}
@ -145,6 +146,39 @@ namespace Google.Protobuf
return ByteString.AttachBytes(message.ToByteArray());
}
/// <summary>
/// Writes the given message data to the given buffer writer in protobuf encoding.
/// </summary>
/// <param name="message">The message to write to the stream.</param>
/// <param name="output">The stream to write to.</param>
[SecuritySafeCritical]
public static void WriteTo(this IMessage message, IBufferWriter<byte> output)
{
ProtoPreconditions.CheckNotNull(message, nameof(message));
ProtoPreconditions.CheckNotNull(output, nameof(output));
WriteContext.Initialize(output, out WriteContext ctx);
WritingPrimitivesMessages.WriteRawMessage(ref ctx, message);
ctx.Flush();
}
/// <summary>
/// Writes the given message data to the given span in protobuf encoding.
/// The size of the destination span needs to fit the serialized size
/// of the message exactly, otherwise an exception is thrown.
/// </summary>
/// <param name="message">The message to write to the stream.</param>
/// <param name="output">The span to write to. Size must match size of the message exactly.</param>
[SecuritySafeCritical]
public static void WriteTo(this IMessage message, Span<byte> output)
{
ProtoPreconditions.CheckNotNull(message, nameof(message));
WriteContext.Initialize(ref output, out WriteContext ctx);
WritingPrimitivesMessages.WriteRawMessage(ref ctx, message);
ctx.CheckNoSpaceLeft();
}
/// <summary>
/// Checks if all required fields in a message have values set. For proto3 messages, this returns true
/// </summary>

@ -47,7 +47,7 @@ namespace Google.Protobuf
// warning: this is a mutable struct, so it needs to be only passed as a ref!
internal struct ParserInternalState
{
// NOTE: the Span representing the current buffer is kept separate so that this doesn't have to be a ref struct and so it can live
// NOTE: the Span representing the current buffer is kept separate so that this doesn't have to be a ref struct and so it can
// be included in CodedInputStream's internal state
/// <summary>

@ -629,7 +629,7 @@ namespace Google.Protobuf
{
fixed (byte* sourceBytes = &MemoryMarshal.GetReference(data))
{
value = CodedOutputStream.Utf8Encoding.GetString(sourceBytes, length);
value = WritingPrimitives.Utf8Encoding.GetString(sourceBytes, length);
}
}
@ -638,7 +638,7 @@ namespace Google.Protobuf
}
#endif
var decoder = CodedOutputStream.Utf8Encoding.GetDecoder();
var decoder = WritingPrimitives.Utf8Encoding.GetDecoder();
// TODO: even if GOOGLE_PROTOBUF_SUPPORT_FAST_STRING is not supported,
// we could still create a string efficiently by using Utf8Encoding.GetString(byte[] bytes, int index, int count)
@ -649,7 +649,7 @@ namespace Google.Protobuf
// creating a string from that array might be more efficient than creating a string from the copied bytes.
// Slow path: Build a byte array first then copy it.
return CodedOutputStream.Utf8Encoding.GetString(ReadRawBytes(ref buffer, ref state, length), 0, length);
return WritingPrimitives.Utf8Encoding.GetString(ReadRawBytes(ref buffer, ref state, length), 0, length);
}
[SecuritySafeCritical]

File diff suppressed because it is too large Load Diff

@ -101,8 +101,8 @@ namespace Google.Protobuf
/// <paramref name="output"/>
/// </summary>
/// <param name="fieldNumber">The unknown field number.</param>
/// <param name="output">The CodedOutputStream to write to.</param>
internal void WriteTo(int fieldNumber, CodedOutputStream output)
/// <param name="output">The write context to write to.</param>
internal void WriteTo(int fieldNumber, ref WriteContext output)
{
if (varintList != null)
{
@ -141,7 +141,7 @@ namespace Google.Protobuf
foreach (UnknownFieldSet value in groupList)
{
output.WriteTag(fieldNumber, WireFormat.WireType.StartGroup);
value.WriteTo(output);
value.WriteTo(ref output);
output.WriteTag(fieldNumber, WireFormat.WireType.EndGroup);
}
}

@ -71,10 +71,27 @@ namespace Google.Protobuf
/// Serializes the set and writes it to <paramref name="output"/>.
/// </summary>
public void WriteTo(CodedOutputStream output)
{
WriteContext.Initialize(output, out WriteContext ctx);
try
{
WriteTo(ref ctx);
}
finally
{
ctx.CopyStateTo(output);
}
}
/// <summary>
/// Serializes the set and writes it to <paramref name="ctx"/>.
/// </summary>
[SecuritySafeCritical]
public void WriteTo(ref WriteContext ctx)
{
foreach (KeyValuePair<int, UnknownField> entry in fields)
{
entry.Value.WriteTo(entry.Key, output);
entry.Value.WriteTo(entry.Key, ref ctx);
}
}

@ -248,6 +248,9 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (TypeUrl.Length != 0) {
output.WriteRawTag(10);
output.WriteString(TypeUrl);
@ -259,7 +262,25 @@ namespace Google.Protobuf.WellKnownTypes {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (TypeUrl.Length != 0) {
output.WriteRawTag(10);
output.WriteString(TypeUrl);
}
if (Value.Length != 0) {
output.WriteRawTag(18);
output.WriteBytes(Value);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {

@ -269,6 +269,9 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Name.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Name);
@ -291,8 +294,37 @@ namespace Google.Protobuf.WellKnownTypes {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Name);
}
methods_.WriteTo(ref output, _repeated_methods_codec);
options_.WriteTo(ref output, _repeated_options_codec);
if (Version.Length != 0) {
output.WriteRawTag(34);
output.WriteString(Version);
}
if (sourceContext_ != null) {
output.WriteRawTag(42);
output.WriteMessage(SourceContext);
}
mixins_.WriteTo(ref output, _repeated_mixins_codec);
if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.Proto2) {
output.WriteRawTag(56);
output.WriteEnum((int) Syntax);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -627,6 +659,9 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Name.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Name);
@ -655,7 +690,42 @@ namespace Google.Protobuf.WellKnownTypes {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Name);
}
if (RequestTypeUrl.Length != 0) {
output.WriteRawTag(18);
output.WriteString(RequestTypeUrl);
}
if (RequestStreaming != false) {
output.WriteRawTag(24);
output.WriteBool(RequestStreaming);
}
if (ResponseTypeUrl.Length != 0) {
output.WriteRawTag(34);
output.WriteString(ResponseTypeUrl);
}
if (ResponseStreaming != false) {
output.WriteRawTag(40);
output.WriteBool(ResponseStreaming);
}
options_.WriteTo(ref output, _repeated_options_codec);
if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.Proto2) {
output.WriteRawTag(56);
output.WriteEnum((int) Syntax);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -984,6 +1054,9 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Name.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Name);
@ -995,8 +1068,26 @@ namespace Google.Protobuf.WellKnownTypes {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Name);
}
if (Root.Length != 0) {
output.WriteRawTag(18);
output.WriteString(Root);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;

@ -210,6 +210,9 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Seconds != 0L) {
output.WriteRawTag(8);
output.WriteInt64(Seconds);
@ -221,7 +224,25 @@ namespace Google.Protobuf.WellKnownTypes {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Seconds != 0L) {
output.WriteRawTag(8);
output.WriteInt64(Seconds);
}
if (Nanos != 0) {
output.WriteRawTag(16);
output.WriteInt32(Nanos);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {

@ -119,10 +119,23 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {

@ -325,11 +325,25 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
paths_.WriteTo(output, _repeated_paths_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
paths_.WriteTo(ref output, _repeated_paths_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {

@ -131,6 +131,9 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (FileName.Length != 0) {
output.WriteRawTag(10);
output.WriteString(FileName);
@ -138,7 +141,21 @@ namespace Google.Protobuf.WellKnownTypes {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (FileName.Length != 0) {
output.WriteRawTag(10);
output.WriteString(FileName);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {

@ -162,11 +162,25 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
fields_.WriteTo(output, _map_fields_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
fields_.WriteTo(ref output, _map_fields_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -446,6 +460,9 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (kindCase_ == KindOneofCase.NullValue) {
output.WriteRawTag(8);
output.WriteEnum((int) NullValue);
@ -473,7 +490,41 @@ namespace Google.Protobuf.WellKnownTypes {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (kindCase_ == KindOneofCase.NullValue) {
output.WriteRawTag(8);
output.WriteEnum((int) NullValue);
}
if (kindCase_ == KindOneofCase.NumberValue) {
output.WriteRawTag(17);
output.WriteDouble(NumberValue);
}
if (kindCase_ == KindOneofCase.StringValue) {
output.WriteRawTag(26);
output.WriteString(StringValue);
}
if (kindCase_ == KindOneofCase.BoolValue) {
output.WriteRawTag(32);
output.WriteBool(BoolValue);
}
if (kindCase_ == KindOneofCase.StructValue) {
output.WriteRawTag(42);
output.WriteMessage(StructValue);
}
if (kindCase_ == KindOneofCase.ListValue) {
output.WriteRawTag(50);
output.WriteMessage(ListValue);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -729,12 +780,26 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
values_.WriteTo(output, _repeated_values_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
values_.WriteTo(ref output, _repeated_values_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;

@ -231,6 +231,9 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Seconds != 0L) {
output.WriteRawTag(8);
output.WriteInt64(Seconds);
@ -242,7 +245,25 @@ namespace Google.Protobuf.WellKnownTypes {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Seconds != 0L) {
output.WriteRawTag(8);
output.WriteInt64(Seconds);
}
if (Nanos != 0) {
output.WriteRawTag(16);
output.WriteInt32(Nanos);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {

@ -262,6 +262,9 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Name.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Name);
@ -280,7 +283,32 @@ namespace Google.Protobuf.WellKnownTypes {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Name);
}
fields_.WriteTo(ref output, _repeated_fields_codec);
oneofs_.WriteTo(ref output, _repeated_oneofs_codec);
options_.WriteTo(ref output, _repeated_options_codec);
if (sourceContext_ != null) {
output.WriteRawTag(42);
output.WriteMessage(SourceContext);
}
if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.Proto2) {
output.WriteRawTag(48);
output.WriteEnum((int) Syntax);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -655,6 +683,9 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Kind != global::Google.Protobuf.WellKnownTypes.Field.Types.Kind.TypeUnknown) {
output.WriteRawTag(8);
output.WriteEnum((int) Kind);
@ -695,7 +726,54 @@ namespace Google.Protobuf.WellKnownTypes {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Kind != global::Google.Protobuf.WellKnownTypes.Field.Types.Kind.TypeUnknown) {
output.WriteRawTag(8);
output.WriteEnum((int) Kind);
}
if (Cardinality != global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality.Unknown) {
output.WriteRawTag(16);
output.WriteEnum((int) Cardinality);
}
if (Number != 0) {
output.WriteRawTag(24);
output.WriteInt32(Number);
}
if (Name.Length != 0) {
output.WriteRawTag(34);
output.WriteString(Name);
}
if (TypeUrl.Length != 0) {
output.WriteRawTag(50);
output.WriteString(TypeUrl);
}
if (OneofIndex != 0) {
output.WriteRawTag(56);
output.WriteInt32(OneofIndex);
}
if (Packed != false) {
output.WriteRawTag(64);
output.WriteBool(Packed);
}
options_.WriteTo(ref output, _repeated_options_codec);
if (JsonName.Length != 0) {
output.WriteRawTag(82);
output.WriteString(JsonName);
}
if (DefaultValue.Length != 0) {
output.WriteRawTag(90);
output.WriteString(DefaultValue);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -1148,6 +1226,9 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Name.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Name);
@ -1165,7 +1246,31 @@ namespace Google.Protobuf.WellKnownTypes {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Name);
}
enumvalue_.WriteTo(ref output, _repeated_enumvalue_codec);
options_.WriteTo(ref output, _repeated_options_codec);
if (sourceContext_ != null) {
output.WriteRawTag(34);
output.WriteMessage(SourceContext);
}
if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.Proto2) {
output.WriteRawTag(40);
output.WriteEnum((int) Syntax);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -1409,6 +1514,9 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Name.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Name);
@ -1421,8 +1529,27 @@ namespace Google.Protobuf.WellKnownTypes {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Name);
}
if (Number != 0) {
output.WriteRawTag(16);
output.WriteInt32(Number);
}
options_.WriteTo(ref output, _repeated_options_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -1623,6 +1750,9 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Name.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Name);
@ -1634,8 +1764,26 @@ namespace Google.Protobuf.WellKnownTypes {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Name);
}
if (value_ != null) {
output.WriteRawTag(18);
output.WriteMessage(Value);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;

@ -143,6 +143,9 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Value != 0D) {
output.WriteRawTag(9);
output.WriteDouble(Value);
@ -150,7 +153,21 @@ namespace Google.Protobuf.WellKnownTypes {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Value != 0D) {
output.WriteRawTag(9);
output.WriteDouble(Value);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -306,6 +323,9 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Value != 0F) {
output.WriteRawTag(13);
output.WriteFloat(Value);
@ -313,7 +333,21 @@ namespace Google.Protobuf.WellKnownTypes {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Value != 0F) {
output.WriteRawTag(13);
output.WriteFloat(Value);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -469,6 +503,9 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Value != 0L) {
output.WriteRawTag(8);
output.WriteInt64(Value);
@ -476,8 +513,22 @@ namespace Google.Protobuf.WellKnownTypes {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Value != 0L) {
output.WriteRawTag(8);
output.WriteInt64(Value);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -632,6 +683,9 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Value != 0UL) {
output.WriteRawTag(8);
output.WriteUInt64(Value);
@ -639,8 +693,22 @@ namespace Google.Protobuf.WellKnownTypes {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Value != 0UL) {
output.WriteRawTag(8);
output.WriteUInt64(Value);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -795,6 +863,9 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Value != 0) {
output.WriteRawTag(8);
output.WriteInt32(Value);
@ -802,7 +873,21 @@ namespace Google.Protobuf.WellKnownTypes {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Value != 0) {
output.WriteRawTag(8);
output.WriteInt32(Value);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -958,6 +1043,9 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Value != 0) {
output.WriteRawTag(8);
output.WriteUInt32(Value);
@ -965,7 +1053,21 @@ namespace Google.Protobuf.WellKnownTypes {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Value != 0) {
output.WriteRawTag(8);
output.WriteUInt32(Value);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
@ -1121,6 +1223,9 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Value != false) {
output.WriteRawTag(8);
output.WriteBool(Value);
@ -1128,8 +1233,22 @@ namespace Google.Protobuf.WellKnownTypes {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Value != false) {
output.WriteRawTag(8);
output.WriteBool(Value);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -1284,6 +1403,9 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Value.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Value);
@ -1291,8 +1413,22 @@ namespace Google.Protobuf.WellKnownTypes {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Value.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Value);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
@ -1447,6 +1583,9 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Value.Length != 0) {
output.WriteRawTag(10);
output.WriteBytes(Value);
@ -1454,8 +1593,22 @@ namespace Google.Protobuf.WellKnownTypes {
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Value.Length != 0) {
output.WriteRawTag(10);
output.WriteBytes(Value);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;

@ -0,0 +1,166 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 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.Buffers;
using System.IO;
using System.Runtime.CompilerServices;
using System.Security;
namespace Google.Protobuf
{
/// <summary>
/// Abstraction for writing to a steam / IBufferWriter
/// </summary>
[SecuritySafeCritical]
internal struct WriteBufferHelper
{
private IBufferWriter<byte> bufferWriter;
private CodedOutputStream codedOutputStream;
public CodedOutputStream CodedOutputStream => codedOutputStream;
/// <summary>
/// Initialize an instance with a coded output stream.
/// This approach is faster than using a constructor because the instance to initialize is passed by reference
/// and we can write directly into it without copying.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Initialize(CodedOutputStream codedOutputStream, out WriteBufferHelper instance)
{
instance.bufferWriter = null;
instance.codedOutputStream = codedOutputStream;
}
/// <summary>
/// Initialize an instance with a buffer writer.
/// This approach is faster than using a constructor because the instance to initialize is passed by reference
/// and we can write directly into it without copying.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Initialize(IBufferWriter<byte> bufferWriter, out WriteBufferHelper instance, out Span<byte> buffer)
{
instance.bufferWriter = bufferWriter;
instance.codedOutputStream = null;
buffer = default; // TODO: initialize the initial buffer so that the first write is not via slowpath.
}
/// <summary>
/// Initialize an instance with a buffer represented by a single span (i.e. buffer cannot be refreshed)
/// This approach is faster than using a constructor because the instance to initialize is passed by reference
/// and we can write directly into it without copying.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void InitializeNonRefreshable(out WriteBufferHelper instance)
{
instance.bufferWriter = null;
instance.codedOutputStream = null;
}
/// <summary>
/// Verifies that SpaceLeft returns zero.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CheckNoSpaceLeft(ref WriterInternalState state)
{
if (GetSpaceLeft(ref state) != 0)
{
throw new InvalidOperationException("Did not write as much data as expected.");
}
}
/// <summary>
/// If writing to a flat array, returns the space left in the array. Otherwise,
/// throws an InvalidOperationException.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int GetSpaceLeft(ref WriterInternalState state)
{
if (state.writeBufferHelper.codedOutputStream?.InternalOutputStream == null && state.writeBufferHelper.bufferWriter == null)
{
return state.limit - state.position;
}
else
{
throw new InvalidOperationException(
"SpaceLeft can only be called on CodedOutputStreams that are " +
"writing to a flat array or when writing to a single span.");
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static void RefreshBuffer(ref Span<byte> buffer, ref WriterInternalState state)
{
if (state.writeBufferHelper.codedOutputStream?.InternalOutputStream != null)
{
// because we're using coded output stream, we know that "buffer" and codedOutputStream.InternalBuffer are identical.
state.writeBufferHelper.codedOutputStream.InternalOutputStream.Write(state.writeBufferHelper.codedOutputStream.InternalBuffer, 0, state.position);
// reset position, limit stays the same because we are reusing the codedOutputStream's internal buffer.
state.position = 0;
}
else if (state.writeBufferHelper.bufferWriter != null)
{
// commit the bytes and get a new buffer to write to.
state.writeBufferHelper.bufferWriter.Advance(state.position);
state.position = 0;
buffer = state.writeBufferHelper.bufferWriter.GetSpan();
state.limit = buffer.Length;
}
else
{
// We're writing to a single buffer.
throw new CodedOutputStream.OutOfSpaceException();
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Flush(ref Span<byte> buffer, ref WriterInternalState state)
{
if (state.writeBufferHelper.codedOutputStream?.InternalOutputStream != null)
{
// because we're using coded output stream, we know that "buffer" and codedOutputStream.InternalBuffer are identical.
state.writeBufferHelper.codedOutputStream.InternalOutputStream.Write(state.writeBufferHelper.codedOutputStream.InternalBuffer, 0, state.position);
state.position = 0;
}
else if (state.writeBufferHelper.bufferWriter != null)
{
// calling Advance invalidates the current buffer and we must not continue writing to it,
// so we set the current buffer to point to an empty Span. If any subsequent writes happen,
// the first subsequent write will trigger refresing of the buffer.
state.writeBufferHelper.bufferWriter.Advance(state.position);
state.position = 0;
state.limit = 0;
buffer = default; // invalidate the current buffer
}
}
}
}

@ -0,0 +1,371 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 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.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
{
/// <summary>
/// An opaque struct that represents the current serialization state and is passed along
/// as the serialization proceeds.
/// All the public methods are intended to be invoked only by the generated code,
/// users should never invoke them directly.
/// </summary>
[SecuritySafeCritical]
public ref struct WriteContext
{
internal Span<byte> buffer;
internal WriterInternalState state;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void Initialize(ref Span<byte> buffer, ref WriterInternalState state, out WriteContext ctx)
{
ctx.buffer = buffer;
ctx.state = state;
}
/// <summary>
/// Creates a WriteContext instance from CodedOutputStream.
/// WARNING: internally this copies the CodedOutputStream's state, so after done with the WriteContext,
/// the CodedOutputStream's state needs to be updated.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void Initialize(CodedOutputStream output, out WriteContext ctx)
{
ctx.buffer = new Span<byte>(output.InternalBuffer);
// ideally we would use a reference to the original state, but that doesn't seem possible
// so we just copy the struct that holds the state. We will need to later store the state back
// into CodedOutputStream if we want to keep it usable.
ctx.state = output.InternalState;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void Initialize(IBufferWriter<byte> output, out WriteContext ctx)
{
ctx.buffer = default;
ctx.state = default;
WriteBufferHelper.Initialize(output, out ctx.state.writeBufferHelper, out ctx.buffer);
ctx.state.limit = ctx.buffer.Length;
ctx.state.position = 0;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void Initialize(ref Span<byte> buffer, out WriteContext ctx)
{
ctx.buffer = buffer;
ctx.state = default;
ctx.state.limit = ctx.buffer.Length;
ctx.state.position = 0;
WriteBufferHelper.InitializeNonRefreshable(out ctx.state.writeBufferHelper);
}
/// <summary>
/// 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);
}
/// <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);
}
/// <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);
}
/// <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);
}
/// <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);
}
/// <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);
}
/// <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);
}
/// <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);
}
/// <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);
}
/// <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);
}
/// <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);
}
/// <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);
}
/// <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);
}
/// <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);
}
/// <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);
}
/// <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);
}
/// <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);
}
/// <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);
}
/// <summary>
/// Writes a length (in bytes) for length-delimited data.
/// </summary>
/// <remarks>
/// 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);
}
/// <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);
}
/// <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);
}
/// <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);
}
/// <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);
}
/// <summary>
/// Writes the given three-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>
/// <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);
}
/// <summary>
/// Writes the given four-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>
/// <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);
}
/// <summary>
/// Writes the given five-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>
/// <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);
}
internal void Flush()
{
WriteBufferHelper.Flush(ref buffer, ref state);
}
internal void CheckNoSpaceLeft()
{
WriteBufferHelper.CheckNoSpaceLeft(ref state);
}
internal void CopyStateTo(CodedOutputStream output)
{
output.InternalState = state;
}
internal void LoadStateFrom(CodedOutputStream output)
{
state = output.InternalState;
}
}
}

@ -0,0 +1,62 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 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.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
{
// NOTE: the Span representing the current buffer is kept separate so that this doesn't have to be a ref struct and so it can
// be included in CodedOutputStream's internal state
internal int limit; // the size of the current buffer
internal int position; // position in the current buffer
internal WriteBufferHelper writeBufferHelper;
// If non-null, the top level parse method was started with given coded output stream as an argument
// which also means we can potentially fallback to calling WriteTo(CodedOutputStream cos) if needed.
internal CodedOutputStream CodedOutputStream => writeBufferHelper.CodedOutputStream;
}
}

@ -0,0 +1,638 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 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.Buffers.Binary;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
namespace Google.Protobuf
{
/// <summary>
/// Primitives for encoding protobuf wire format.
/// </summary>
[SecuritySafeCritical]
internal static class WritingPrimitives
{
// "Local" copy of Encoding.UTF8, for efficiency. (Yes, it makes a difference.)
internal static readonly Encoding Utf8Encoding = Encoding.UTF8;
#region Writing of values (not including tags)
/// <summary>
/// Writes a double field value, without a tag, to the stream.
/// </summary>
public static void WriteDouble(ref Span<byte> buffer, ref WriterInternalState state, double value)
{
WriteRawLittleEndian64(ref buffer, ref state, (ulong)BitConverter.DoubleToInt64Bits(value));
}
/// <summary>
/// Writes a float field value, without a tag, to the stream.
/// </summary>
public static unsafe void WriteFloat(ref Span<byte> buffer, ref WriterInternalState state, float value)
{
const int length = sizeof(float);
if (buffer.Length - state.position >= length)
{
// if there's enough space in the buffer, write the float directly into the buffer
var floatSpan = buffer.Slice(state.position, length);
Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(floatSpan), value);
if (!BitConverter.IsLittleEndian)
{
floatSpan.Reverse();
}
state.position += length;
}
else
{
WriteFloatSlowPath(ref buffer, ref state, value);
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static unsafe void WriteFloatSlowPath(ref Span<byte> buffer, ref WriterInternalState state, float value)
{
const int length = sizeof(float);
// TODO(jtattermusch): deduplicate the code. Populating the span is the same as for the fastpath.
Span<byte> floatSpan = stackalloc byte[length];
Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(floatSpan), value);
if (!BitConverter.IsLittleEndian)
{
floatSpan.Reverse();
}
WriteRawByte(ref buffer, ref state, floatSpan[0]);
WriteRawByte(ref buffer, ref state, floatSpan[1]);
WriteRawByte(ref buffer, ref state, floatSpan[2]);
WriteRawByte(ref buffer, ref state, floatSpan[3]);
}
/// <summary>
/// Writes a uint64 field value, without a tag, to the stream.
/// </summary>
public static void WriteUInt64(ref Span<byte> buffer, ref WriterInternalState state, ulong value)
{
WriteRawVarint64(ref buffer, ref state, value);
}
/// <summary>
/// Writes an int64 field value, without a tag, to the stream.
/// </summary>
public static void WriteInt64(ref Span<byte> buffer, ref WriterInternalState state, long value)
{
WriteRawVarint64(ref buffer, ref state, (ulong)value);
}
/// <summary>
/// Writes an int32 field value, without a tag, to the stream.
/// </summary>
public static void WriteInt32(ref Span<byte> buffer, ref WriterInternalState state, int value)
{
if (value >= 0)
{
WriteRawVarint32(ref buffer, ref state, (uint)value);
}
else
{
// Must sign-extend.
WriteRawVarint64(ref buffer, ref state, (ulong)value);
}
}
/// <summary>
/// Writes a fixed64 field value, without a tag, to the stream.
/// </summary>
public static void WriteFixed64(ref Span<byte> buffer, ref WriterInternalState state, ulong value)
{
WriteRawLittleEndian64(ref buffer, ref state, value);
}
/// <summary>
/// Writes a fixed32 field value, without a tag, to the stream.
/// </summary>
public static void WriteFixed32(ref Span<byte> buffer, ref WriterInternalState state, uint value)
{
WriteRawLittleEndian32(ref buffer, ref state, value);
}
/// <summary>
/// Writes a bool field value, without a tag, to the stream.
/// </summary>
public static void WriteBool(ref Span<byte> buffer, ref WriterInternalState state, bool value)
{
WriteRawByte(ref buffer, ref state, value ? (byte)1 : (byte)0);
}
/// <summary>
/// Writes a string field value, without a tag, to the stream.
/// The data is length-prefixed.
/// </summary>
public static void WriteString(ref Span<byte> buffer, ref WriterInternalState state, string value)
{
// Optimise the case where we have enough space to write
// the string directly to the buffer, which should be common.
int length = Utf8Encoding.GetByteCount(value);
WriteLength(ref buffer, ref state, length);
if (buffer.Length - state.position >= length)
{
if (length == value.Length) // Must be all ASCII...
{
for (int i = 0; i < length; i++)
{
buffer[state.position + i] = (byte)value[i];
}
state.position += length;
}
else
{
#if NETSTANDARD1_1
// slowpath when Encoding.GetBytes(Char*, Int32, Byte*, Int32) is not available
byte[] bytes = Utf8Encoding.GetBytes(value);
WriteRawBytes(ref buffer, ref state, bytes);
#else
ReadOnlySpan<char> source = value.AsSpan();
int bytesUsed;
unsafe
{
fixed (char* sourceChars = &MemoryMarshal.GetReference(source))
fixed (byte* destinationBytes = &MemoryMarshal.GetReference(buffer.Slice(state.position)))
{
bytesUsed = Utf8Encoding.GetBytes(sourceChars, source.Length, destinationBytes, buffer.Length);
}
}
state.position += bytesUsed;
#endif
}
}
else
{
// Opportunity for future optimization:
// Large strings that don't fit into the current buffer segment
// can probably be optimized by using Utf8Encoding.GetEncoder()
// but more benchmarks would need to be added as evidence.
byte[] bytes = Utf8Encoding.GetBytes(value);
WriteRawBytes(ref buffer, ref state, bytes);
}
}
/// <summary>
/// Write a byte string, without a tag, to the stream.
/// The data is length-prefixed.
/// </summary>
public static void WriteBytes(ref Span<byte> buffer, ref WriterInternalState state, ByteString value)
{
WriteLength(ref buffer, ref state, value.Length);
WriteRawBytes(ref buffer, ref state, value.Span);
}
/// <summary>
/// Writes a uint32 value, without a tag, to the stream.
/// </summary>
public static void WriteUInt32(ref Span<byte> buffer, ref WriterInternalState state, uint value)
{
WriteRawVarint32(ref buffer, ref state, value);
}
/// <summary>
/// Writes an enum value, without a tag, to the stream.
/// </summary>
public static void WriteEnum(ref Span<byte> buffer, ref WriterInternalState state, int value)
{
WriteInt32(ref buffer, ref state, value);
}
/// <summary>
/// Writes an sfixed32 value, without a tag, to the stream.
/// </summary>
public static void WriteSFixed32(ref Span<byte> buffer, ref WriterInternalState state, int value)
{
WriteRawLittleEndian32(ref buffer, ref state, (uint)value);
}
/// <summary>
/// Writes an sfixed64 value, without a tag, to the stream.
/// </summary>
public static void WriteSFixed64(ref Span<byte> buffer, ref WriterInternalState state, long value)
{
WriteRawLittleEndian64(ref buffer, ref state, (ulong)value);
}
/// <summary>
/// Writes an sint32 value, without a tag, to the stream.
/// </summary>
public static void WriteSInt32(ref Span<byte> buffer, ref WriterInternalState state, int value)
{
WriteRawVarint32(ref buffer, ref state, EncodeZigZag32(value));
}
/// <summary>
/// Writes an sint64 value, without a tag, to the stream.
/// </summary>
public static void WriteSInt64(ref Span<byte> buffer, ref WriterInternalState state, long value)
{
WriteRawVarint64(ref buffer, ref state, EncodeZigZag64(value));
}
/// <summary>
/// Writes a length (in bytes) for length-delimited data.
/// </summary>
/// <remarks>
/// This method simply writes a rawint, but exists for clarity in calling code.
/// </remarks>
public static void WriteLength(ref Span<byte> buffer, ref WriterInternalState state, int length)
{
WriteRawVarint32(ref buffer, ref state, (uint)length);
}
#endregion
#region Writing primitives
/// <summary>
/// Writes a 32 bit value as a varint. The fast route is taken when
/// there's enough buffer space left to whizz through without checking
/// for each byte; otherwise, we resort to calling WriteRawByte each time.
/// </summary>
public static void WriteRawVarint32(ref Span<byte> buffer, ref WriterInternalState state, uint value)
{
// Optimize for the common case of a single byte value
if (value < 128 && state.position < buffer.Length)
{
buffer[state.position++] = (byte)value;
return;
}
// Fast path when capacity is available
while (state.position < buffer.Length)
{
if (value > 127)
{
buffer[state.position++] = (byte)((value & 0x7F) | 0x80);
value >>= 7;
}
else
{
buffer[state.position++] = (byte)value;
return;
}
}
while (value > 127)
{
WriteRawByte(ref buffer, ref state, (byte)((value & 0x7F) | 0x80));
value >>= 7;
}
WriteRawByte(ref buffer, ref state, (byte)value);
}
public static void WriteRawVarint64(ref Span<byte> buffer, ref WriterInternalState state, ulong value)
{
// Optimize for the common case of a single byte value
if (value < 128 && state.position < buffer.Length)
{
buffer[state.position++] = (byte)value;
return;
}
// Fast path when capacity is available
while (state.position < buffer.Length)
{
if (value > 127)
{
buffer[state.position++] = (byte)((value & 0x7F) | 0x80);
value >>= 7;
}
else
{
buffer[state.position++] = (byte)value;
return;
}
}
while (value > 127)
{
WriteRawByte(ref buffer, ref state, (byte)((value & 0x7F) | 0x80));
value >>= 7;
}
WriteRawByte(ref buffer, ref state, (byte)value);
}
public static void WriteRawLittleEndian32(ref Span<byte> buffer, ref WriterInternalState state, uint value)
{
const int length = sizeof(uint);
if (state.position + length > buffer.Length)
{
WriteRawLittleEndian32SlowPath(ref buffer, ref state, value);
}
else
{
BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(state.position), value);
state.position += length;
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void WriteRawLittleEndian32SlowPath(ref Span<byte> buffer, ref WriterInternalState state, uint value)
{
WriteRawByte(ref buffer, ref state, (byte)value);
WriteRawByte(ref buffer, ref state, (byte)(value >> 8));
WriteRawByte(ref buffer, ref state, (byte)(value >> 16));
WriteRawByte(ref buffer, ref state, (byte)(value >> 24));
}
public static void WriteRawLittleEndian64(ref Span<byte> buffer, ref WriterInternalState state, ulong value)
{
const int length = sizeof(ulong);
if (state.position + length > buffer.Length)
{
WriteRawLittleEndian64SlowPath(ref buffer, ref state, value);
}
else
{
// TODO(jtattermusch): According to the benchmarks, writing byte-by-byte is actually faster
// than using BinaryPrimitives.WriteUInt64LittleEndian.
// This is strange especially because WriteUInt32LittleEndian seems to be much faster
// in terms of throughput.
buffer[state.position++] = ((byte)value);
buffer[state.position++] = ((byte)(value >> 8));
buffer[state.position++] = ((byte)(value >> 16));
buffer[state.position++] = ((byte)(value >> 24));
buffer[state.position++] = ((byte)(value >> 32));
buffer[state.position++] = ((byte)(value >> 40));
buffer[state.position++] = ((byte)(value >> 48));
buffer[state.position++] = ((byte)(value >> 56));
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static void WriteRawLittleEndian64SlowPath(ref Span<byte> buffer, ref WriterInternalState state, ulong value)
{
WriteRawByte(ref buffer, ref state, (byte)value);
WriteRawByte(ref buffer, ref state, (byte)(value >> 8));
WriteRawByte(ref buffer, ref state, (byte)(value >> 16));
WriteRawByte(ref buffer, ref state, (byte)(value >> 24));
WriteRawByte(ref buffer, ref state, (byte)(value >> 32));
WriteRawByte(ref buffer, ref state, (byte)(value >> 40));
WriteRawByte(ref buffer, ref state, (byte)(value >> 48));
WriteRawByte(ref buffer, ref state, (byte)(value >> 56));
}
private static void WriteRawByte(ref Span<byte> buffer, ref WriterInternalState state, byte value)
{
if (state.position == buffer.Length)
{
WriteBufferHelper.RefreshBuffer(ref buffer, ref state);
}
buffer[state.position++] = value;
}
/// <summary>
/// Writes out an array of bytes.
/// </summary>
public static void WriteRawBytes(ref Span<byte> buffer, ref WriterInternalState state, byte[] value)
{
WriteRawBytes(ref buffer, ref state, new ReadOnlySpan<byte>(value));
}
/// <summary>
/// Writes out part of an array of bytes.
/// </summary>
public static void WriteRawBytes(ref Span<byte> buffer, ref WriterInternalState state, byte[] value, int offset, int length)
{
WriteRawBytes(ref buffer, ref state, new ReadOnlySpan<byte>(value, offset, length));
}
/// <summary>
/// Writes out part of an array of bytes.
/// </summary>
public static void WriteRawBytes(ref Span<byte> buffer, ref WriterInternalState state, ReadOnlySpan<byte> value)
{
if (buffer.Length - state.position >= value.Length)
{
// We have room in the current buffer.
value.CopyTo(buffer.Slice(state.position, value.Length));
state.position += value.Length;
}
else
{
// When writing to a CodedOutputStream backed by a Stream, we could avoid
// copying the data twice (first copying to the current buffer and
// and later writing from the current buffer to the underlying Stream)
// in some circumstances by writing the data directly to the underlying Stream.
// Current this is not being done to avoid specialcasing the code for
// CodedOutputStream vs IBufferWriter<byte>.
int bytesWritten = 0;
while (buffer.Length - state.position < value.Length - bytesWritten)
{
int length = buffer.Length - state.position;
value.Slice(bytesWritten, length).CopyTo(buffer.Slice(state.position, length));
bytesWritten += length;
state.position += length;
WriteBufferHelper.RefreshBuffer(ref buffer, ref state);
}
// copy the remaining data
int remainderLength = value.Length - bytesWritten;
value.Slice(bytesWritten, remainderLength).CopyTo(buffer.Slice(state.position, remainderLength));
state.position += remainderLength;
}
}
#endregion
#region Raw tag writing
/// <summary>
/// Encodes and writes a tag.
/// </summary>
public static void WriteTag(ref Span<byte> buffer, ref WriterInternalState state, int fieldNumber, WireFormat.WireType type)
{
WriteRawVarint32(ref buffer, ref state, WireFormat.MakeTag(fieldNumber, type));
}
/// <summary>
/// Writes an already-encoded tag.
/// </summary>
public static void WriteTag(ref Span<byte> buffer, ref WriterInternalState state, uint tag)
{
WriteRawVarint32(ref buffer, ref state, tag);
}
/// <summary>
/// Writes the given single-byte tag directly to the stream.
/// </summary>
public static void WriteRawTag(ref Span<byte> buffer, ref WriterInternalState state, byte b1)
{
WriteRawByte(ref buffer, ref state, b1);
}
/// <summary>
/// Writes the given two-byte tag directly to the stream.
/// </summary>
public static void WriteRawTag(ref Span<byte> buffer, ref WriterInternalState state, byte b1, byte b2)
{
if (state.position + 2 > buffer.Length)
{
WriteRawTagSlowPath(ref buffer, ref state, b1, b2);
}
else
{
buffer[state.position++] = b1;
buffer[state.position++] = b2;
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void WriteRawTagSlowPath(ref Span<byte> buffer, ref WriterInternalState state, byte b1, byte b2)
{
WriteRawByte(ref buffer, ref state, b1);
WriteRawByte(ref buffer, ref state, b2);
}
/// <summary>
/// Writes the given three-byte tag directly to the stream.
/// </summary>
public static void WriteRawTag(ref Span<byte> buffer, ref WriterInternalState state, byte b1, byte b2, byte b3)
{
if (state.position + 3 > buffer.Length)
{
WriteRawTagSlowPath(ref buffer, ref state, b1, b2, b3);
}
else
{
buffer[state.position++] = b1;
buffer[state.position++] = b2;
buffer[state.position++] = b3;
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void WriteRawTagSlowPath(ref Span<byte> buffer, ref WriterInternalState state, byte b1, byte b2, byte b3)
{
WriteRawByte(ref buffer, ref state, b1);
WriteRawByte(ref buffer, ref state, b2);
WriteRawByte(ref buffer, ref state, b3);
}
/// <summary>
/// Writes the given four-byte tag directly to the stream.
/// </summary>
public static void WriteRawTag(ref Span<byte> buffer, ref WriterInternalState state, byte b1, byte b2, byte b3, byte b4)
{
if (state.position + 4 > buffer.Length)
{
WriteRawTagSlowPath(ref buffer, ref state, b1, b2, b3, b4);
}
else
{
buffer[state.position++] = b1;
buffer[state.position++] = b2;
buffer[state.position++] = b3;
buffer[state.position++] = b4;
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void WriteRawTagSlowPath(ref Span<byte> buffer, ref WriterInternalState state, byte b1, byte b2, byte b3, byte b4)
{
WriteRawByte(ref buffer, ref state, b1);
WriteRawByte(ref buffer, ref state, b2);
WriteRawByte(ref buffer, ref state, b3);
WriteRawByte(ref buffer, ref state, b4);
}
/// <summary>
/// Writes the given five-byte tag directly to the stream.
/// </summary>
public static void WriteRawTag(ref Span<byte> buffer, ref WriterInternalState state, byte b1, byte b2, byte b3, byte b4, byte b5)
{
if (state.position + 5 > buffer.Length)
{
WriteRawTagSlowPath(ref buffer, ref state, b1, b2, b3, b4, b5);
}
else
{
buffer[state.position++] = b1;
buffer[state.position++] = b2;
buffer[state.position++] = b3;
buffer[state.position++] = b4;
buffer[state.position++] = b5;
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void WriteRawTagSlowPath(ref Span<byte> buffer, ref WriterInternalState state, byte b1, byte b2, byte b3, byte b4, byte b5)
{
WriteRawByte(ref buffer, ref state, b1);
WriteRawByte(ref buffer, ref state, b2);
WriteRawByte(ref buffer, ref state, b3);
WriteRawByte(ref buffer, ref state, b4);
WriteRawByte(ref buffer, ref state, b5);
}
#endregion
/// <summary>
/// Encode a 32-bit value with ZigZag encoding.
/// </summary>
/// <remarks>
/// ZigZag encodes signed integers into values that can be efficiently
/// encoded with varint. (Otherwise, negative values must be
/// sign-extended to 64 bits to be varint encoded, thus always taking
/// 10 bytes on the wire.)
/// </remarks>
public static uint EncodeZigZag32(int n)
{
// Note: the right-shift must be arithmetic
return (uint)((n << 1) ^ (n >> 31));
}
/// <summary>
/// Encode a 64-bit value with ZigZag encoding.
/// </summary>
/// <remarks>
/// ZigZag encodes signed integers into values that can be efficiently
/// encoded with varint. (Otherwise, negative values must be
/// sign-extended to 64 bits to be varint encoded, thus always taking
/// 10 bytes on the wire.)
/// </remarks>
public static ulong EncodeZigZag64(long n)
{
return (ulong)((n << 1) ^ (n >> 63));
}
}
}

@ -0,0 +1,112 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 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.Runtime.CompilerServices;
using System.Runtime.InteropServices.ComTypes;
using System.Security;
namespace Google.Protobuf
{
/// <summary>
/// Writing messages / groups.
/// </summary>
[SecuritySafeCritical]
internal static class WritingPrimitivesMessages
{
/// <summary>
/// Writes a message, without a tag.
/// The data is length-prefixed.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void WriteMessage(ref WriteContext ctx, IMessage value)
{
WritingPrimitives.WriteLength(ref ctx.buffer, ref ctx.state, value.CalculateSize());
WriteRawMessage(ref ctx, value);
}
/// <summary>
/// Writes a group, without a tag.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void WriteGroup(ref WriteContext ctx, IMessage value)
{
WriteRawMessage(ref ctx, value);
}
/// <summary>
/// Writes a message, without a tag.
/// Message will be written without a length prefix.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void WriteRawMessage(ref WriteContext ctx, IMessage message)
{
if (message is IBufferMessage bufferMessage)
{
bufferMessage.InternalWriteTo(ref ctx);
}
else
{
// If we reached here, it means we've ran into a nested message with older generated code
// which doesn't provide the InternalWriteTo method that takes a WriteContext.
// With a slight performance overhead, we can still serialize this message just fine,
// but we need to find the original CodedOutputStream instance that initiated this
// serialization process and make sure its internal state is up to date.
// Note that this performance overhead is not very high (basically copying contents of a struct)
// and it will only be incurred in case the application mixes older and newer generated code.
// Regenerating the code from .proto files will remove this overhead because it will
// generate the InternalWriteTo method we need.
if (ctx.state.CodedOutputStream == null)
{
// This can only happen when the serialization started without providing a CodedOutputStream instance
// (e.g. WriteContext was created directly from a IBufferWriter).
// That also means that one of the new parsing APIs was used at the top level
// and in such case it is reasonable to require that all the nested message provide
// up-to-date generated code with WriteContext support (and fail otherwise).
throw new InvalidProtocolBufferException($"Message {message.GetType().Name} doesn't provide the generated method that enables WriteContext-based serialization. You might need to regenerate the generated protobuf code.");
}
ctx.CopyStateTo(ctx.state.CodedOutputStream);
try
{
// fallback parse using the CodedOutputStream that started current serialization tree
message.WriteTo(ctx.state.CodedOutputStream);
}
finally
{
ctx.LoadStateFrom(ctx.state.CodedOutputStream);
}
}
}
}
}

@ -167,6 +167,12 @@ void FieldGeneratorBase::GenerateParsingCode(io::Printer* printer, bool use_pars
GenerateParsingCode(printer);
}
void FieldGeneratorBase::GenerateSerializationCode(io::Printer* printer, bool use_write_context) {
// for some field types the value of "use_write_context" doesn't matter,
// so we fallback to the default implementation.
GenerateSerializationCode(printer);
}
void FieldGeneratorBase::AddDeprecatedFlag(io::Printer* printer) {
if (descriptor_->options().deprecated()) {
printer->Print("[global::System.ObsoleteAttribute]\n");

@ -63,6 +63,7 @@ class FieldGeneratorBase : public SourceGeneratorBase {
virtual void GenerateParsingCode(io::Printer* printer) = 0;
virtual void GenerateParsingCode(io::Printer* printer, bool use_parse_context);
virtual void GenerateSerializationCode(io::Printer* printer) = 0;
virtual void GenerateSerializationCode(io::Printer* printer, bool use_write_context);
virtual void GenerateSerializedSizeCode(io::Printer* printer) = 0;
virtual void WriteHash(io::Printer* printer) = 0;

@ -106,9 +106,15 @@ void MapFieldGenerator::GenerateParsingCode(io::Printer* printer, bool use_parse
}
void MapFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
GenerateSerializationCode(printer, true);
}
void MapFieldGenerator::GenerateSerializationCode(io::Printer* printer, bool use_write_context) {
printer->Print(
variables_,
"$name$_.WriteTo(output, _map_$name$_codec);\n");
use_write_context
? "$name$_.WriteTo(ref output, _map_$name$_codec);\n"
: "$name$_.WriteTo(output, _map_$name$_codec);\n");
}
void MapFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {

@ -58,6 +58,7 @@ class MapFieldGenerator : public FieldGeneratorBase {
virtual void GenerateParsingCode(io::Printer* printer);
virtual void GenerateParsingCode(io::Printer* printer, bool use_parse_context);
virtual void GenerateSerializationCode(io::Printer* printer);
virtual void GenerateSerializationCode(io::Printer* printer, bool use_write_context);
virtual void GenerateSerializedSizeCode(io::Printer* printer);
virtual void WriteHash(io::Printer* printer);

@ -520,34 +520,26 @@ void MessageGenerator::GenerateMessageSerializationMethods(io::Printer* printer)
WriteGeneratedCodeAttributes(printer);
printer->Print(
"public void WriteTo(pb::CodedOutputStream output) {\n");
printer->Print("#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE\n");
printer->Indent();
printer->Print("output.WriteRawMessage(this);\n");
printer->Outdent();
printer->Print("#else\n");
printer->Indent();
GenerateWriteToBody(printer, false);
printer->Outdent();
printer->Print("#endif\n");
printer->Print("}\n\n");
// Serialize all the fields
for (int i = 0; i < fields_by_number().size(); i++) {
std::unique_ptr<FieldGeneratorBase> generator(
CreateFieldGeneratorInternal(fields_by_number()[i]));
generator->GenerateSerializationCode(printer);
}
if (has_extension_ranges_) {
// Serialize extensions
printer->Print(
"if (_extensions != null) {\n"
" _extensions.WriteTo(output);\n"
"}\n");
}
// Serialize unknown fields
printer->Print(
"if (_unknownFields != null) {\n"
" _unknownFields.WriteTo(output);\n"
"}\n");
// TODO(jonskeet): Memoize size of frozen messages?
printer->Print("#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE\n");
WriteGeneratedCodeAttributes(printer);
printer->Print("void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {\n");
printer->Indent();
GenerateWriteToBody(printer, true);
printer->Outdent();
printer->Print(
"}\n"
"\n");
printer->Print("}\n");
printer->Print("#endif\n\n");
WriteGeneratedCodeAttributes(printer);
printer->Print(
"public int CalculateSize() {\n");
@ -576,6 +568,39 @@ void MessageGenerator::GenerateMessageSerializationMethods(io::Printer* printer)
printer->Print("}\n\n");
}
void MessageGenerator::GenerateWriteToBody(io::Printer* printer, bool use_write_context) {
// Serialize all the fields
for (int i = 0; i < fields_by_number().size(); i++) {
std::unique_ptr<FieldGeneratorBase> generator(
CreateFieldGeneratorInternal(fields_by_number()[i]));
generator->GenerateSerializationCode(printer, use_write_context);
}
if (has_extension_ranges_) {
// Serialize extensions
printer->Print(
use_write_context
? "if (_extensions != null) {\n"
" _extensions.WriteTo(ref output);\n"
"}\n"
: "if (_extensions != null) {\n"
" _extensions.WriteTo(output);\n"
"}\n");
}
// Serialize unknown fields
printer->Print(
use_write_context
? "if (_unknownFields != null) {\n"
" _unknownFields.WriteTo(ref output);\n"
"}\n"
: "if (_unknownFields != null) {\n"
" _unknownFields.WriteTo(output);\n"
"}\n");
// TODO(jonskeet): Memoize size of frozen messages?
}
void MessageGenerator::GenerateMergingMethods(io::Printer* printer) {
// Note: These are separate from GenerateMessageSerializationMethods()
// because they need to be generated even for messages that are optimized

@ -66,6 +66,7 @@ class MessageGenerator : public SourceGeneratorBase {
bool has_extension_ranges_;
void GenerateMessageSerializationMethods(io::Printer* printer);
void GenerateWriteToBody(io::Printer* printer, bool use_write_context);
void GenerateMergingMethods(io::Printer* printer);
void GenerateMainParseLoop(io::Printer* printer, bool use_parse_context);

@ -90,9 +90,15 @@ void RepeatedEnumFieldGenerator::GenerateParsingCode(io::Printer* printer, bool
}
void RepeatedEnumFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
GenerateSerializationCode(printer, true);
}
void RepeatedEnumFieldGenerator::GenerateSerializationCode(io::Printer* printer, bool use_write_context) {
printer->Print(
variables_,
"$name$_.WriteTo(output, _repeated_$name$_codec);\n");
use_write_context
? "$name$_.WriteTo(ref output, _repeated_$name$_codec);\n"
: "$name$_.WriteTo(output, _repeated_$name$_codec);\n");
}
void RepeatedEnumFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {

@ -61,6 +61,7 @@ class RepeatedEnumFieldGenerator : public FieldGeneratorBase {
virtual void GenerateParsingCode(io::Printer* printer);
virtual void GenerateParsingCode(io::Printer* printer, bool use_parse_context);
virtual void GenerateSerializationCode(io::Printer* printer);
virtual void GenerateSerializationCode(io::Printer* printer, bool use_write_context);
virtual void GenerateSerializedSizeCode(io::Printer* printer);
virtual void GenerateExtensionCode(io::Printer* printer);

@ -105,9 +105,15 @@ void RepeatedMessageFieldGenerator::GenerateParsingCode(io::Printer* printer, bo
}
void RepeatedMessageFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
GenerateSerializationCode(printer, true);
}
void RepeatedMessageFieldGenerator::GenerateSerializationCode(io::Printer* printer, bool use_write_context) {
printer->Print(
variables_,
"$name$_.WriteTo(output, _repeated_$name$_codec);\n");
use_write_context
? "$name$_.WriteTo(ref output, _repeated_$name$_codec);\n"
: "$name$_.WriteTo(output, _repeated_$name$_codec);\n");
}
void RepeatedMessageFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {

@ -61,6 +61,7 @@ class RepeatedMessageFieldGenerator : public FieldGeneratorBase {
virtual void GenerateParsingCode(io::Printer* printer);
virtual void GenerateParsingCode(io::Printer* printer, bool use_parse_context);
virtual void GenerateSerializationCode(io::Printer* printer);
virtual void GenerateSerializationCode(io::Printer* printer, bool use_write_context);
virtual void GenerateSerializedSizeCode(io::Printer* printer);
virtual void GenerateExtensionCode(io::Printer* printer);

@ -90,9 +90,15 @@ void RepeatedPrimitiveFieldGenerator::GenerateParsingCode(io::Printer* printer,
}
void RepeatedPrimitiveFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
GenerateSerializationCode(printer, true);
}
void RepeatedPrimitiveFieldGenerator::GenerateSerializationCode(io::Printer* printer, bool use_write_context) {
printer->Print(
variables_,
"$name$_.WriteTo(output, _repeated_$name$_codec);\n");
use_write_context
? "$name$_.WriteTo(ref output, _repeated_$name$_codec);\n"
: "$name$_.WriteTo(output, _repeated_$name$_codec);\n");
}
void RepeatedPrimitiveFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {

@ -57,6 +57,7 @@ class RepeatedPrimitiveFieldGenerator : public FieldGeneratorBase {
virtual void GenerateParsingCode(io::Printer* printer);
virtual void GenerateParsingCode(io::Printer* printer, bool use_parse_context);
virtual void GenerateSerializationCode(io::Printer* printer);
virtual void GenerateSerializationCode(io::Printer* printer, bool use_write_context);
virtual void GenerateSerializedSizeCode(io::Printer* printer);
virtual void GenerateExtensionCode(io::Printer* printer);

@ -132,11 +132,19 @@ void WrapperFieldGenerator::GenerateParsingCode(io::Printer* printer, bool use_p
}
void WrapperFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
GenerateSerializationCode(printer, true);
}
void WrapperFieldGenerator::GenerateSerializationCode(io::Printer* printer, bool use_write_context) {
printer->Print(
variables_,
"if ($has_property_check$) {\n"
" _single_$name$_codec.WriteTagAndValue(output, $property_name$);\n"
"}\n");
use_write_context
? "if ($has_property_check$) {\n"
" _single_$name$_codec.WriteTagAndValue(ref output, $property_name$);\n"
"}\n"
: "if ($has_property_check$) {\n"
" _single_$name$_codec.WriteTagAndValue(output, $property_name$);\n"
"}\n");
}
void WrapperFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
@ -269,12 +277,20 @@ void WrapperOneofFieldGenerator::GenerateParsingCode(io::Printer* printer, bool
}
void WrapperOneofFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
GenerateSerializationCode(printer, true);
}
void WrapperOneofFieldGenerator::GenerateSerializationCode(io::Printer* printer, bool use_write_context) {
// TODO: I suspect this is wrong...
printer->Print(
variables_,
"if ($has_property_check$) {\n"
" _oneof_$name$_codec.WriteTagAndValue(output, ($type_name$) $oneof_name$_);\n"
"}\n");
use_write_context
? "if ($has_property_check$) {\n"
" _oneof_$name$_codec.WriteTagAndValue(ref output, ($type_name$) $oneof_name$_);\n"
"}\n"
: "if ($has_property_check$) {\n"
" _oneof_$name$_codec.WriteTagAndValue(output, ($type_name$) $oneof_name$_);\n"
"}\n");
}
void WrapperOneofFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {

@ -60,6 +60,7 @@ class WrapperFieldGenerator : public FieldGeneratorBase {
virtual void GenerateParsingCode(io::Printer* printer);
virtual void GenerateParsingCode(io::Printer* printer, bool use_parse_context);
virtual void GenerateSerializationCode(io::Printer* printer);
virtual void GenerateSerializationCode(io::Printer* printer, bool use_write_context);
virtual void GenerateSerializedSizeCode(io::Printer* printer);
virtual void GenerateExtensionCode(io::Printer* printer);
@ -86,6 +87,7 @@ class WrapperOneofFieldGenerator : public WrapperFieldGenerator {
virtual void GenerateParsingCode(io::Printer* printer);
virtual void GenerateParsingCode(io::Printer* printer, bool use_parse_context);
virtual void GenerateSerializationCode(io::Printer* printer);
virtual void GenerateSerializationCode(io::Printer* printer, bool use_write_context);
virtual void GenerateSerializedSizeCode(io::Printer* printer);
};

Loading…
Cancel
Save