PROTOBUF_SYNC_PIPER
pull/7698/head
Joshua Haberman 5 years ago
parent dfab275eca
commit 25755efc4f
  1. 7
      BUILD
  2. 2
      README.md
  3. 64
      csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
  4. 22
      csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/FieldCodecTest.cs
  5. 12
      csharp/install_dotnet_sdk.ps1
  6. 15
      csharp/protos/unittest_issues.proto
  7. 65
      csharp/src/AddressBook/Addressbook.cs
  8. 267
      csharp/src/Google.Protobuf.Benchmarks/BenchmarkMessage1Proto3.cs
  9. 22
      csharp/src/Google.Protobuf.Benchmarks/Benchmarks.cs
  10. 6
      csharp/src/Google.Protobuf.Benchmarks/Google.Protobuf.Benchmarks.csproj
  11. 6
      csharp/src/Google.Protobuf.Benchmarks/ParseMessagesBenchmark.cs
  12. 43
      csharp/src/Google.Protobuf.Benchmarks/ParseRawPrimitivesBenchmark.cs
  13. 801
      csharp/src/Google.Protobuf.Benchmarks/WrapperBenchmarkMessages.cs
  14. 198
      csharp/src/Google.Protobuf.Benchmarks/WriteMessagesBenchmark.cs
  15. 519
      csharp/src/Google.Protobuf.Benchmarks/WriteRawPrimitivesBenchmark.cs
  16. 125
      csharp/src/Google.Protobuf.Conformance/Conformance.cs
  17. 132
      csharp/src/Google.Protobuf.Test.TestProtos/MapUnittestProto3.cs
  18. 446
      csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto2.cs
  19. 394
      csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto3.cs
  20. 2557
      csharp/src/Google.Protobuf.Test.TestProtos/Unittest.cs
  21. 335
      csharp/src/Google.Protobuf.Test.TestProtos/UnittestCustomOptionsProto3.cs
  22. 17
      csharp/src/Google.Protobuf.Test.TestProtos/UnittestImport.cs
  23. 17
      csharp/src/Google.Protobuf.Test.TestProtos/UnittestImportProto3.cs
  24. 17
      csharp/src/Google.Protobuf.Test.TestProtos/UnittestImportPublic.cs
  25. 17
      csharp/src/Google.Protobuf.Test.TestProtos/UnittestImportPublicProto3.cs
  26. 13
      csharp/src/Google.Protobuf.Test.TestProtos/UnittestIssue6936B.cs
  27. 17
      csharp/src/Google.Protobuf.Test.TestProtos/UnittestIssue6936C.cs
  28. 734
      csharp/src/Google.Protobuf.Test.TestProtos/UnittestIssues.cs
  29. 833
      csharp/src/Google.Protobuf.Test.TestProtos/UnittestProto3.cs
  30. 114
      csharp/src/Google.Protobuf.Test.TestProtos/UnittestProto3Optional.cs
  31. 24
      csharp/src/Google.Protobuf.Test.TestProtos/UnittestSelfreferentialOptions.cs
  32. 218
      csharp/src/Google.Protobuf.Test.TestProtos/UnittestWellKnownTypes.cs
  33. 225
      csharp/src/Google.Protobuf.Test/Buffers/ArrayBufferWriter.cs
  34. 186
      csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
  35. 2
      csharp/src/Google.Protobuf.Test/ExtensionSetTest.cs
  36. 24
      csharp/src/Google.Protobuf.Test/FieldCodecTest.cs
  37. 6
      csharp/src/Google.Protobuf.Test/GeneratedMessageTest.Proto2.cs
  38. 14
      csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs
  39. 22
      csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
  40. 38
      csharp/src/Google.Protobuf.Test/JsonParserTest.cs
  41. 101
      csharp/src/Google.Protobuf.Test/LegacyGeneratedCodeTest.cs
  42. 42
      csharp/src/Google.Protobuf.Test/MessageParsingHelpers.cs
  43. 10
      csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
  44. BIN
      csharp/src/Google.Protobuf.Test/testprotos.pb
  45. 6
      csharp/src/Google.Protobuf/CodedOutputStream.ComputeSize.cs
  46. 415
      csharp/src/Google.Protobuf/CodedOutputStream.cs
  47. 35
      csharp/src/Google.Protobuf/Collections/MapField.cs
  48. 36
      csharp/src/Google.Protobuf/Collections/RepeatedField.cs
  49. 21
      csharp/src/Google.Protobuf/ExtensionSet.cs
  50. 19
      csharp/src/Google.Protobuf/ExtensionValue.cs
  51. 90
      csharp/src/Google.Protobuf/FieldCodec.cs
  52. 8
      csharp/src/Google.Protobuf/IBufferMessage.cs
  53. 2
      csharp/src/Google.Protobuf/JsonFormatter.cs
  54. 17
      csharp/src/Google.Protobuf/JsonParser.cs
  55. 36
      csharp/src/Google.Protobuf/MessageExtensions.cs
  56. 2
      csharp/src/Google.Protobuf/ParserInternalState.cs
  57. 6
      csharp/src/Google.Protobuf/ParsingPrimitives.cs
  58. 794
      csharp/src/Google.Protobuf/Reflection/Descriptor.cs
  59. 6
      csharp/src/Google.Protobuf/UnknownField.cs
  60. 19
      csharp/src/Google.Protobuf/UnknownFieldSet.cs
  61. 28
      csharp/src/Google.Protobuf/WellKnownTypes/Any.cs
  62. 91
      csharp/src/Google.Protobuf/WellKnownTypes/Api.cs
  63. 21
      csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs
  64. 13
      csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs
  65. 14
      csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs
  66. 17
      csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs
  67. 65
      csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs
  68. 21
      csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs
  69. 148
      csharp/src/Google.Protobuf/WellKnownTypes/Type.cs
  70. 153
      csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs
  71. 166
      csharp/src/Google.Protobuf/WriteBufferHelper.cs
  72. 371
      csharp/src/Google.Protobuf/WriteContext.cs
  73. 62
      csharp/src/Google.Protobuf/WriterInternalState.cs
  74. 628
      csharp/src/Google.Protobuf/WritingPrimitives.cs
  75. 112
      csharp/src/Google.Protobuf/WritingPrimitivesMessages.cs
  76. 1
      docs/third_party.md
  77. 6
      editors/protobuf-mode.el
  78. 2
      kokoro/linux/dockerfile/test/csharp/Dockerfile
  79. 7
      objectivec/GPBAny.pbobjc.h
  80. 95
      php/ext/google/protobuf2/arena.c
  81. 47
      php/ext/google/protobuf2/arena.h
  82. 602
      php/ext/google/protobuf2/array.c
  83. 61
      php/ext/google/protobuf2/array.h
  84. 46
      php/ext/google/protobuf2/bundled_php.h
  85. 10
      php/ext/google/protobuf2/config.m4
  86. 478
      php/ext/google/protobuf2/convert.c
  87. 73
      php/ext/google/protobuf2/convert.h
  88. 1085
      php/ext/google/protobuf2/def.c
  89. 69
      php/ext/google/protobuf2/def.h
  90. 62
      php/ext/google/protobuf2/make-preload.php
  91. 590
      php/ext/google/protobuf2/map.c
  92. 60
      php/ext/google/protobuf2/map.h
  93. 841
      php/ext/google/protobuf2/message.c
  94. 59
      php/ext/google/protobuf2/message.h
  95. 226
      php/ext/google/protobuf2/names.c
  96. 40
      php/ext/google/protobuf2/names.h
  97. 8077
      php/ext/google/protobuf2/php-upb.c
  98. 3885
      php/ext/google/protobuf2/php-upb.h
  99. 349
      php/ext/google/protobuf2/protobuf.c
  100. 89
      php/ext/google/protobuf2/protobuf.h
  101. Some files were not shown because too many files have changed in this diff Show More

@ -3,7 +3,6 @@
load("@bazel_skylib//rules:common_settings.bzl", "string_flag")
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test", "objc_library", native_cc_proto_library = "cc_proto_library")
load("@rules_proto//proto:defs.bzl", "proto_lang_toolchain", "proto_library")
load("@rules_proto//proto/private:native.bzl", "native_proto_common")
load("@rules_python//python:defs.bzl", "py_library")
load(":cc_proto_blacklist_test.bzl", "cc_proto_blacklist_test")
@ -945,13 +944,9 @@ cc_library(
],
)
# Note: We use `native_proto_common` here because we depend on an implementation-detail of
# `proto_lang_toolchain`, which may not be available on `proto_common`.
reject_blacklisted_files = hasattr(native_proto_common, "proto_lang_toolchain_rejects_files_do_not_use_or_we_will_break_you_without_mercy")
cc_toolchain_blacklisted_protos = [proto + "_proto" for proto in WELL_KNOWN_PROTO_MAP.keys()] if reject_blacklisted_files else [":well_known_protos"]
proto_lang_toolchain(
name = "cc_toolchain",
blacklisted_protos = cc_toolchain_blacklisted_protos,
blacklisted_protos = [proto + "_proto" for proto in WELL_KNOWN_PROTO_MAP.keys()],
command_line = "--cpp_out=$(OUT)",
runtime = ":protobuf",
visibility = ["//visibility:public"],

@ -61,7 +61,7 @@ how to install protobuf runtime for that specific language:
| C# | [csharp](csharp) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-csharp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fcsharp%2Fcontinuous) | | [![Build status](https://ci.appveyor.com/api/projects/status/73ctee6ua4w2ruin?svg=true)](https://ci.appveyor.com/project/protobuf/protobuf)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/windows-csharp-release.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fwindows%2Fcsharp_release%2Fcontinuous) |
| JavaScript | [js](js) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-javascript.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fjavascript%2Fcontinuous) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-javascript.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fjavascript%2Fcontinuous) | |
| Ruby | [ruby](ruby) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-ruby23.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fruby23%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-ruby24.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fruby24%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-ruby25.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fruby25%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-ruby26.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fruby26%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-ruby-release.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fruby_release%2Fcontinuous) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-ruby23.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fruby23%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-ruby24.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fruby24%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-ruby25.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fruby25%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-ruby26.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fruby26%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-ruby-release.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fruby_release%2Fcontinuous) | |
| Go | [golang/protobuf](https://github.com/golang/protobuf) | | | |
| Go | [protocolbuffers/protobuf-go](https://github.com/protocolbuffers/protobuf-go) | | | |
| PHP | [php](php) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-php_all.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fphp_all%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-32-bit.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2F32-bit%2Fcontinuous) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-php5.6_mac.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fphp5.6_mac%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-php7.0_mac.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fphp7.0_mac%2Fcontinuous) | |
| Dart | [dart-lang/protobuf](https://github.com/dart-lang/protobuf) | [![Build Status](https://travis-ci.org/dart-lang/protobuf.svg?branch=master)](https://travis-ci.org/dart-lang/protobuf) | | |

@ -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));

@ -1,5 +1,5 @@
#!/usr/bin/env powershell
# Install dotnet SDK based on the SDK version from global.json
# Install dotnet SDK using the official dotnet-install.ps1 script
Set-StrictMode -Version 2
$ErrorActionPreference = 'Stop'
@ -9,16 +9,12 @@ $ErrorActionPreference = 'Stop'
$InstallScriptUrl = 'https://dot.net/v1/dotnet-install.ps1'
$InstallScriptPath = Join-Path "$env:TEMP" 'dotnet-install.ps1'
$GlobalJsonPath = Join-Path $PSScriptRoot '..' | Join-Path -ChildPath 'global.json'
# Resolve SDK version from global.json file
$GlobalJson = Get-Content -Raw $GlobalJsonPath | ConvertFrom-Json
$SDKVersion = $GlobalJson.sdk.version
# Download install script
Write-Host "Downloading install script: $InstallScriptUrl => $InstallScriptPath"
Invoke-WebRequest -Uri $InstallScriptUrl -OutFile $InstallScriptPath
&$InstallScriptPath -Version $SDKVersion
# Also install dotnet SDK LTS which is required to run some of the tests
# The SDK versions to install should be kept in sync with versions
# installed by kokoro/linux/dockerfile/test/csharp/Dockerfile
&$InstallScriptPath -Version 2.1.802
&$InstallScriptPath -Version 3.1.301

@ -8,6 +8,8 @@ option csharp_namespace = "UnitTest.Issues.TestProtos";
package unittest_issues;
import "google/protobuf/struct.proto";
// Issue 307: when generating doubly-nested types, any references
// should be of the form A.Types.B.Types.C.
message Issue307 {
@ -137,4 +139,15 @@ message OneofMerging {
string text = 1;
Nested nested = 2;
}
}
}
message NullValueOutsideStruct {
oneof value {
string string_value = 1;
google.protobuf.NullValue null_value = 2;
}
}
message NullValueNotInOneof {
google.protobuf.NullValue null_value = 2;
}

@ -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() {

@ -2,15 +2,17 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
<IsPackable>False</IsPackable>
<DebugType>pdbonly</DebugType>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.11.4" />
<PackageReference Include="BenchmarkDotNet" Version="0.12.1" />
<ProjectReference Include="..\Google.Protobuf\Google.Protobuf.csproj" />
</ItemGroup>

@ -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,519 @@
#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);
for (int i = 0; i < values.Length; i++)
{
cos.WriteRawVarint32(values[i]);
}
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);
for (int i = 0; i < values.Length; i++)
{
ctx.WriteUInt32(values[i]);
}
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);
for (int i = 0; i < values.Length; i++)
{
cos.WriteRawVarint64(values[i]);
}
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);
for (int i = 0; i < values.Length; i++)
{
ctx.WriteUInt64(values[i]);
}
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 WriteRawTag_OneByte_WriteContext()
{
const int encodedSize = 1;
var span = new Span<byte>(outputBuffer);
WriteContext.Initialize(ref span, out WriteContext ctx);
for (uint i = 0; i < BytesToWrite / encodedSize; i++)
{
ctx.WriteRawTag(16);
}
ctx.Flush();
ctx.CheckNoSpaceLeft();
}
[Benchmark]
public void WriteRawTag_TwoBytes_WriteContext()
{
const int encodedSize = 2;
var span = new Span<byte>(outputBuffer);
WriteContext.Initialize(ref span, out WriteContext ctx);
for (uint i = 0; i < BytesToWrite / encodedSize; i++)
{
ctx.WriteRawTag(137, 6);
}
ctx.Flush();
ctx.CheckNoSpaceLeft();
}
[Benchmark]
public void WriteRawTag_ThreeBytes_WriteContext()
{
const int encodedSize = 3;
var span = new Span<byte>(outputBuffer);
WriteContext.Initialize(ref span, out WriteContext ctx);
for (uint i = 0; i < BytesToWrite / encodedSize; i++)
{
ctx.WriteRawTag(160, 131, 1);
}
ctx.Flush();
ctx.CheckNoSpaceLeft();
}
[Benchmark]
public void Baseline_WriteContext()
{
var span = new Span<byte>(outputBuffer);
WriteContext.Initialize(ref span, out WriteContext ctx);
ctx.state.position = outputBuffer.Length;
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;

@ -2452,6 +2452,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);
@ -2798,8 +2801,361 @@ 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 (oneofFieldCase_ == OneofFieldOneofCase.OneofNullValue) {
output.WriteRawTag(192, 7);
output.WriteEnum((int) OneofNullValue);
}
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);
}
if (OptionalNullValue != global::Google.Protobuf.WellKnownTypes.NullValue.NullValue) {
output.WriteRawTag(152, 19);
output.WriteEnum((int) OptionalNullValue);
}
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;
@ -5004,6 +5360,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);
@ -5015,7 +5374,25 @@ 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() {
@ -5191,6 +5568,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);
@ -5198,7 +5578,21 @@ 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() {

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() {

@ -24,36 +24,41 @@ namespace UnitTest.Issues.TestProtos {
static UnittestIssuesReflection() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"ChV1bml0dGVzdF9pc3N1ZXMucHJvdG8SD3VuaXR0ZXN0X2lzc3VlcyInCghJ",
"c3N1ZTMwNxobCgpOZXN0ZWRPbmNlGg0KC05lc3RlZFR3aWNlIrABChNOZWdh",
"dGl2ZUVudW1NZXNzYWdlEiwKBXZhbHVlGAEgASgOMh0udW5pdHRlc3RfaXNz",
"dWVzLk5lZ2F0aXZlRW51bRIxCgZ2YWx1ZXMYAiADKA4yHS51bml0dGVzdF9p",
"c3N1ZXMuTmVnYXRpdmVFbnVtQgIQABI4Cg1wYWNrZWRfdmFsdWVzGAMgAygO",
"Mh0udW5pdHRlc3RfaXNzdWVzLk5lZ2F0aXZlRW51bUICEAEiEQoPRGVwcmVj",
"YXRlZENoaWxkIrkCChdEZXByZWNhdGVkRmllbGRzTWVzc2FnZRIaCg5Qcmlt",
"aXRpdmVWYWx1ZRgBIAEoBUICGAESGgoOUHJpbWl0aXZlQXJyYXkYAiADKAVC",
"AhgBEjoKDE1lc3NhZ2VWYWx1ZRgDIAEoCzIgLnVuaXR0ZXN0X2lzc3Vlcy5E",
"ZXByZWNhdGVkQ2hpbGRCAhgBEjoKDE1lc3NhZ2VBcnJheRgEIAMoCzIgLnVu",
"aXR0ZXN0X2lzc3Vlcy5EZXByZWNhdGVkQ2hpbGRCAhgBEjYKCUVudW1WYWx1",
"ZRgFIAEoDjIfLnVuaXR0ZXN0X2lzc3Vlcy5EZXByZWNhdGVkRW51bUICGAES",
"NgoJRW51bUFycmF5GAYgAygOMh8udW5pdHRlc3RfaXNzdWVzLkRlcHJlY2F0",
"ZWRFbnVtQgIYASIZCglJdGVtRmllbGQSDAoEaXRlbRgBIAEoBSJECg1SZXNl",
"cnZlZE5hbWVzEg0KBXR5cGVzGAEgASgFEhIKCmRlc2NyaXB0b3IYAiABKAUa",
"EAoOU29tZU5lc3RlZFR5cGUioAEKFVRlc3RKc29uRmllbGRPcmRlcmluZxIT",
"CgtwbGFpbl9pbnQzMhgEIAEoBRITCglvMV9zdHJpbmcYAiABKAlIABISCghv",
"MV9pbnQzMhgFIAEoBUgAEhQKDHBsYWluX3N0cmluZxgBIAEoCRISCghvMl9p",
"bnQzMhgGIAEoBUgBEhMKCW8yX3N0cmluZxgDIAEoCUgBQgQKAm8xQgQKAm8y",
"IksKDFRlc3RKc29uTmFtZRIMCgRuYW1lGAEgASgJEhkKC2Rlc2NyaXB0aW9u",
"GAIgASgJUgRkZXNjEhIKBGd1aWQYAyABKAlSBGV4aWQifwoMT25lb2ZNZXJn",
"aW5nEg4KBHRleHQYASABKAlIABI2CgZuZXN0ZWQYAiABKAsyJC51bml0dGVz",
"dF9pc3N1ZXMuT25lb2ZNZXJnaW5nLk5lc3RlZEgAGh4KBk5lc3RlZBIJCgF4",
"GAEgASgFEgkKAXkYAiABKAVCBwoFdmFsdWUqVQoMTmVnYXRpdmVFbnVtEhYK",
"Ek5FR0FUSVZFX0VOVU1fWkVSTxAAEhYKCUZpdmVCZWxvdxD7//////////8B",
"EhUKCE1pbnVzT25lEP///////////wEqLgoORGVwcmVjYXRlZEVudW0SEwoP",
"REVQUkVDQVRFRF9aRVJPEAASBwoDb25lEAFCHaoCGlVuaXRUZXN0Lklzc3Vl",
"cy5UZXN0UHJvdG9zYgZwcm90bzM="));
"ChV1bml0dGVzdF9pc3N1ZXMucHJvdG8SD3VuaXR0ZXN0X2lzc3VlcxocZ29v",
"Z2xlL3Byb3RvYnVmL3N0cnVjdC5wcm90byInCghJc3N1ZTMwNxobCgpOZXN0",
"ZWRPbmNlGg0KC05lc3RlZFR3aWNlIrABChNOZWdhdGl2ZUVudW1NZXNzYWdl",
"EiwKBXZhbHVlGAEgASgOMh0udW5pdHRlc3RfaXNzdWVzLk5lZ2F0aXZlRW51",
"bRIxCgZ2YWx1ZXMYAiADKA4yHS51bml0dGVzdF9pc3N1ZXMuTmVnYXRpdmVF",
"bnVtQgIQABI4Cg1wYWNrZWRfdmFsdWVzGAMgAygOMh0udW5pdHRlc3RfaXNz",
"dWVzLk5lZ2F0aXZlRW51bUICEAEiEQoPRGVwcmVjYXRlZENoaWxkIrkCChdE",
"ZXByZWNhdGVkRmllbGRzTWVzc2FnZRIaCg5QcmltaXRpdmVWYWx1ZRgBIAEo",
"BUICGAESGgoOUHJpbWl0aXZlQXJyYXkYAiADKAVCAhgBEjoKDE1lc3NhZ2VW",
"YWx1ZRgDIAEoCzIgLnVuaXR0ZXN0X2lzc3Vlcy5EZXByZWNhdGVkQ2hpbGRC",
"AhgBEjoKDE1lc3NhZ2VBcnJheRgEIAMoCzIgLnVuaXR0ZXN0X2lzc3Vlcy5E",
"ZXByZWNhdGVkQ2hpbGRCAhgBEjYKCUVudW1WYWx1ZRgFIAEoDjIfLnVuaXR0",
"ZXN0X2lzc3Vlcy5EZXByZWNhdGVkRW51bUICGAESNgoJRW51bUFycmF5GAYg",
"AygOMh8udW5pdHRlc3RfaXNzdWVzLkRlcHJlY2F0ZWRFbnVtQgIYASIZCglJ",
"dGVtRmllbGQSDAoEaXRlbRgBIAEoBSJECg1SZXNlcnZlZE5hbWVzEg0KBXR5",
"cGVzGAEgASgFEhIKCmRlc2NyaXB0b3IYAiABKAUaEAoOU29tZU5lc3RlZFR5",
"cGUioAEKFVRlc3RKc29uRmllbGRPcmRlcmluZxITCgtwbGFpbl9pbnQzMhgE",
"IAEoBRITCglvMV9zdHJpbmcYAiABKAlIABISCghvMV9pbnQzMhgFIAEoBUgA",
"EhQKDHBsYWluX3N0cmluZxgBIAEoCRISCghvMl9pbnQzMhgGIAEoBUgBEhMK",
"CW8yX3N0cmluZxgDIAEoCUgBQgQKAm8xQgQKAm8yIksKDFRlc3RKc29uTmFt",
"ZRIMCgRuYW1lGAEgASgJEhkKC2Rlc2NyaXB0aW9uGAIgASgJUgRkZXNjEhIK",
"BGd1aWQYAyABKAlSBGV4aWQifwoMT25lb2ZNZXJnaW5nEg4KBHRleHQYASAB",
"KAlIABI2CgZuZXN0ZWQYAiABKAsyJC51bml0dGVzdF9pc3N1ZXMuT25lb2ZN",
"ZXJnaW5nLk5lc3RlZEgAGh4KBk5lc3RlZBIJCgF4GAEgASgFEgkKAXkYAiAB",
"KAVCBwoFdmFsdWUiawoWTnVsbFZhbHVlT3V0c2lkZVN0cnVjdBIWCgxzdHJp",
"bmdfdmFsdWUYASABKAlIABIwCgpudWxsX3ZhbHVlGAIgASgOMhouZ29vZ2xl",
"LnByb3RvYnVmLk51bGxWYWx1ZUgAQgcKBXZhbHVlIkUKE051bGxWYWx1ZU5v",
"dEluT25lb2YSLgoKbnVsbF92YWx1ZRgCIAEoDjIaLmdvb2dsZS5wcm90b2J1",
"Zi5OdWxsVmFsdWUqVQoMTmVnYXRpdmVFbnVtEhYKEk5FR0FUSVZFX0VOVU1f",
"WkVSTxAAEhYKCUZpdmVCZWxvdxD7//////////8BEhUKCE1pbnVzT25lEP//",
"/////////wEqLgoORGVwcmVjYXRlZEVudW0SEwoPREVQUkVDQVRFRF9aRVJP",
"EAASBwoDb25lEAFCHaoCGlVuaXRUZXN0Lklzc3Vlcy5UZXN0UHJvdG9zYgZw",
"cm90bzM="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.StructReflection.Descriptor, },
new pbr::GeneratedClrTypeInfo(new[] {typeof(global::UnitTest.Issues.TestProtos.NegativeEnum), typeof(global::UnitTest.Issues.TestProtos.DeprecatedEnum), }, null, new pbr::GeneratedClrTypeInfo[] {
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307), global::UnitTest.Issues.TestProtos.Issue307.Parser, null, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce), global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Parser, null, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Types.NestedTwice), global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Types.NestedTwice.Parser, null, null, null, null, null)})}),
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.NegativeEnumMessage), global::UnitTest.Issues.TestProtos.NegativeEnumMessage.Parser, new[]{ "Value", "Values", "PackedValues" }, null, null, null, null),
@ -63,7 +68,9 @@ namespace UnitTest.Issues.TestProtos {
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ReservedNames), global::UnitTest.Issues.TestProtos.ReservedNames.Parser, new[]{ "Types_", "Descriptor_" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ReservedNames.Types.SomeNestedType), global::UnitTest.Issues.TestProtos.ReservedNames.Types.SomeNestedType.Parser, null, null, null, null, null)}),
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.TestJsonFieldOrdering), global::UnitTest.Issues.TestProtos.TestJsonFieldOrdering.Parser, new[]{ "PlainInt32", "O1String", "O1Int32", "PlainString", "O2Int32", "O2String" }, new[]{ "O1", "O2" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.TestJsonName), global::UnitTest.Issues.TestProtos.TestJsonName.Parser, new[]{ "Name", "Description", "Guid" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.OneofMerging), global::UnitTest.Issues.TestProtos.OneofMerging.Parser, new[]{ "Text", "Nested" }, new[]{ "Value" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.OneofMerging.Types.Nested), global::UnitTest.Issues.TestProtos.OneofMerging.Types.Nested.Parser, new[]{ "X", "Y" }, null, null, null, null)})
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.OneofMerging), global::UnitTest.Issues.TestProtos.OneofMerging.Parser, new[]{ "Text", "Nested" }, new[]{ "Value" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.OneofMerging.Types.Nested), global::UnitTest.Issues.TestProtos.OneofMerging.Types.Nested.Parser, new[]{ "X", "Y" }, null, null, null, null)}),
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.NullValueOutsideStruct), global::UnitTest.Issues.TestProtos.NullValueOutsideStruct.Parser, new[]{ "StringValue", "NullValue" }, new[]{ "Value" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.NullValueNotInOneof), global::UnitTest.Issues.TestProtos.NullValueNotInOneof.Parser, new[]{ "NullValue" }, null, null, null, null)
}));
}
#endregion
@ -157,10 +164,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,10 +302,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() {
@ -407,10 +440,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() {
@ -580,6 +626,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 +638,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,10 +812,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() {
@ -957,6 +1035,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 +1056,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 +1303,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 +1313,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 +1489,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 +1503,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 +1674,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 +1967,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,7 +1997,41 @@ 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() {
@ -2092,6 +2286,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,7 +2304,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 (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() {
@ -2330,6 +2549,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 +2563,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 +2775,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 +2789,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() {
@ -2630,6 +2891,419 @@ namespace UnitTest.Issues.TestProtos {
}
public sealed partial class NullValueOutsideStruct : pb::IMessage<NullValueOutsideStruct>
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
, pb::IBufferMessage
#endif
{
private static readonly pb::MessageParser<NullValueOutsideStruct> _parser = new pb::MessageParser<NullValueOutsideStruct>(() => new NullValueOutsideStruct());
private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<NullValueOutsideStruct> Parser { get { return _parser; } }
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[9]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NullValueOutsideStruct() {
OnConstruction();
}
partial void OnConstruction();
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NullValueOutsideStruct(NullValueOutsideStruct other) : this() {
switch (other.ValueCase) {
case ValueOneofCase.StringValue:
StringValue = other.StringValue;
break;
case ValueOneofCase.NullValue:
NullValue = other.NullValue;
break;
}
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NullValueOutsideStruct Clone() {
return new NullValueOutsideStruct(this);
}
/// <summary>Field number for the "string_value" field.</summary>
public const int StringValueFieldNumber = 1;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string StringValue {
get { return valueCase_ == ValueOneofCase.StringValue ? (string) value_ : ""; }
set {
value_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
valueCase_ = ValueOneofCase.StringValue;
}
}
/// <summary>Field number for the "null_value" field.</summary>
public const int NullValueFieldNumber = 2;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.NullValue NullValue {
get { return valueCase_ == ValueOneofCase.NullValue ? (global::Google.Protobuf.WellKnownTypes.NullValue) value_ : global::Google.Protobuf.WellKnownTypes.NullValue.NullValue; }
set {
value_ = value;
valueCase_ = ValueOneofCase.NullValue;
}
}
private object value_;
/// <summary>Enum of possible cases for the "value" oneof.</summary>
public enum ValueOneofCase {
None = 0,
StringValue = 1,
NullValue = 2,
}
private ValueOneofCase valueCase_ = ValueOneofCase.None;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ValueOneofCase ValueCase {
get { return valueCase_; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void ClearValue() {
valueCase_ = ValueOneofCase.None;
value_ = null;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as NullValueOutsideStruct);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(NullValueOutsideStruct other) {
if (ReferenceEquals(other, null)) {
return false;
}
if (ReferenceEquals(other, this)) {
return true;
}
if (StringValue != other.StringValue) return false;
if (NullValue != other.NullValue) return false;
if (ValueCase != other.ValueCase) return false;
return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (valueCase_ == ValueOneofCase.StringValue) hash ^= StringValue.GetHashCode();
if (valueCase_ == ValueOneofCase.NullValue) hash ^= NullValue.GetHashCode();
hash ^= (int) valueCase_;
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
return hash;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
return pb::JsonFormatter.ToDiagnosticString(this);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (valueCase_ == ValueOneofCase.StringValue) {
output.WriteRawTag(10);
output.WriteString(StringValue);
}
if (valueCase_ == ValueOneofCase.NullValue) {
output.WriteRawTag(16);
output.WriteEnum((int) NullValue);
}
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.StringValue) {
output.WriteRawTag(10);
output.WriteString(StringValue);
}
if (valueCase_ == ValueOneofCase.NullValue) {
output.WriteRawTag(16);
output.WriteEnum((int) NullValue);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (valueCase_ == ValueOneofCase.StringValue) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(StringValue);
}
if (valueCase_ == ValueOneofCase.NullValue) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) NullValue);
}
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
return size;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(NullValueOutsideStruct other) {
if (other == null) {
return;
}
switch (other.ValueCase) {
case ValueOneofCase.StringValue:
StringValue = other.StringValue;
break;
case ValueOneofCase.NullValue:
NullValue = other.NullValue;
break;
}
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
input.ReadRawMessage(this);
#else
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
StringValue = input.ReadString();
break;
}
case 16: {
value_ = input.ReadEnum();
valueCase_ = ValueOneofCase.NullValue;
break;
}
}
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
break;
case 10: {
StringValue = input.ReadString();
break;
}
case 16: {
value_ = input.ReadEnum();
valueCase_ = ValueOneofCase.NullValue;
break;
}
}
}
}
#endif
}
public sealed partial class NullValueNotInOneof : pb::IMessage<NullValueNotInOneof>
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
, pb::IBufferMessage
#endif
{
private static readonly pb::MessageParser<NullValueNotInOneof> _parser = new pb::MessageParser<NullValueNotInOneof>(() => new NullValueNotInOneof());
private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<NullValueNotInOneof> Parser { get { return _parser; } }
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[10]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NullValueNotInOneof() {
OnConstruction();
}
partial void OnConstruction();
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NullValueNotInOneof(NullValueNotInOneof other) : this() {
nullValue_ = other.nullValue_;
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NullValueNotInOneof Clone() {
return new NullValueNotInOneof(this);
}
/// <summary>Field number for the "null_value" field.</summary>
public const int NullValueFieldNumber = 2;
private global::Google.Protobuf.WellKnownTypes.NullValue nullValue_ = global::Google.Protobuf.WellKnownTypes.NullValue.NullValue;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.NullValue NullValue {
get { return nullValue_; }
set {
nullValue_ = value;
}
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as NullValueNotInOneof);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(NullValueNotInOneof other) {
if (ReferenceEquals(other, null)) {
return false;
}
if (ReferenceEquals(other, this)) {
return true;
}
if (NullValue != other.NullValue) return false;
return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (NullValue != global::Google.Protobuf.WellKnownTypes.NullValue.NullValue) hash ^= NullValue.GetHashCode();
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
return hash;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
return pb::JsonFormatter.ToDiagnosticString(this);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (NullValue != global::Google.Protobuf.WellKnownTypes.NullValue.NullValue) {
output.WriteRawTag(16);
output.WriteEnum((int) NullValue);
}
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 (NullValue != global::Google.Protobuf.WellKnownTypes.NullValue.NullValue) {
output.WriteRawTag(16);
output.WriteEnum((int) NullValue);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (NullValue != global::Google.Protobuf.WellKnownTypes.NullValue.NullValue) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) NullValue);
}
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
return size;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(NullValueNotInOneof other) {
if (other == null) {
return;
}
if (other.NullValue != global::Google.Protobuf.WellKnownTypes.NullValue.NullValue) {
NullValue = other.NullValue;
}
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
input.ReadRawMessage(this);
#else
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 16: {
NullValue = (global::Google.Protobuf.WellKnownTypes.NullValue) input.ReadEnum();
break;
}
}
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
break;
case 16: {
NullValue = (global::Google.Protobuf.WellKnownTypes.NullValue) input.ReadEnum();
break;
}
}
}
}
#endif
}
#endregion
}

@ -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);

@ -226,6 +226,28 @@ namespace Google.Protobuf
JsonFormatter.Default.Format(new TestMap { MapBoolBool = { { false, true }, { true, false } } }));
}
[Test]
public void NullValueOutsideStruct()
{
var message = new NullValueOutsideStruct { NullValue = NullValue.NullValue };
AssertJson("{ 'nullValue': null }", JsonFormatter.Default.Format(message));
}
[Test]
public void NullValueNotInOneof()
{
var message = new NullValueNotInOneof();
AssertJson("{ }", JsonFormatter.Default.Format(message));
}
[Test]
public void NullValueNotInOneof_FormatDefaults()
{
var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true));
var message = new NullValueNotInOneof();
AssertJson("{ 'nullValue': null }", formatter.Format(message));
}
[TestCase(1.0, "1")]
[TestCase(double.NaN, "'NaN'")]
[TestCase(double.PositiveInfinity, "'Infinity'")]

@ -36,6 +36,7 @@ using Google.Protobuf.WellKnownTypes;
using NUnit.Framework;
using ProtobufTestMessages.Proto2;
using System;
using UnitTest.Issues.TestProtos;
namespace Google.Protobuf
{
@ -974,6 +975,43 @@ namespace Google.Protobuf
Assert.AreEqual(expected, actual);
}
[Test]
public void NullValueOutsideStruct_NullLiteral()
{
string json = "{ \"nullValue\": null }";
var message = NullValueOutsideStruct.Parser.ParseJson(json);
Assert.AreEqual(NullValueOutsideStruct.ValueOneofCase.NullValue, message.ValueCase);
}
[Test]
public void NullValueNotInOneof_NullLiteral()
{
// We'd only normally see this with FormatDefaultValues set to true.
string json = "{ \"nullValue\": null }";
var message = NullValueNotInOneof.Parser.ParseJson(json);
Assert.AreEqual(NullValue.NullValue, message.NullValue);
}
// NullValue used to only be converted to the null literal when part of a struct.
// Otherwise, it would end up as a string "NULL_VALUE" (the name of the enum value).
// We still parse that form, for compatibility.
[Test]
public void NullValueOutsideStruct_Compatibility()
{
string json = "{ \"nullValue\": \"NULL_VALUE\" }";
var message = NullValueOutsideStruct.Parser.ParseJson(json);
Assert.AreEqual(NullValueOutsideStruct.ValueOneofCase.NullValue, message.ValueCase);
}
[Test]
public void NullValueNotInOneof_Compatibility()
{
// We'd only normally see this with FormatDefaultValues set to true.
string json = "{ \"nullValue\": \"NULL_VALUE\" }";
var message = NullValueNotInOneof.Parser.ParseJson(json);
Assert.AreEqual(NullValue.NullValue, message.NullValue);
}
/// <summary>
/// Various tests use strings which have quotes round them for parsing or as the result
/// of formatting, but without those quotes being specified in the tests (for the sake of readability).

@ -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
}

@ -357,7 +357,7 @@ namespace Google.Protobuf
/// <param name="value">The value to write. May be null.</param>
public void WriteValue(TextWriter writer, object value)
{
if (value == null)
if (value == null || value is NullValue)
{
WriteNull(writer);
}

@ -37,6 +37,7 @@ using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
@ -63,6 +64,7 @@ namespace Google.Protobuf
private static readonly Regex DurationRegex = new Regex(@"^(?<sign>-)?(?<int>[0-9]{1,12})(?<subseconds>\.[0-9]{1,9})?s$", FrameworkPortability.CompiledRegexWhereAvailable);
private static readonly int[] SubsecondScalingFactors = { 0, 100000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1 };
private static readonly char[] FieldMaskPathSeparators = new[] { ',' };
private static readonly EnumDescriptor NullValueDescriptor = StructReflection.Descriptor.EnumTypes.Single(ed => ed.ClrType == typeof(NullValue));
private static readonly JsonParser defaultInstance = new JsonParser(Settings.Default);
@ -221,10 +223,11 @@ namespace Google.Protobuf
if (token.Type == JsonToken.TokenType.Null)
{
// Clear the field if we see a null token, unless it's for a singular field of type
// google.protobuf.Value.
// google.protobuf.Value or google.protobuf.NullValue.
// Note: different from Java API, which just ignores it.
// TODO: Bring it more in line? Discuss...
if (field.IsMap || field.IsRepeated || !IsGoogleProtobufValueField(field))
if (field.IsMap || field.IsRepeated ||
!(IsGoogleProtobufValueField(field) || IsGoogleProtobufNullValueField(field)))
{
field.Accessor.Clear(message);
return;
@ -314,6 +317,12 @@ namespace Google.Protobuf
field.MessageType.FullName == Value.Descriptor.FullName;
}
private static bool IsGoogleProtobufNullValueField(FieldDescriptor field)
{
return field.FieldType == FieldType.Enum &&
field.EnumType.FullName == NullValueDescriptor.FullName;
}
private object ParseSingleValue(FieldDescriptor field, JsonTokenizer tokenizer)
{
var token = tokenizer.Next();
@ -325,6 +334,10 @@ namespace Google.Protobuf
{
return Value.ForNull();
}
if (IsGoogleProtobufNullValueField(field))
{
return NullValue.NullValue;
}
return null;
}

@ -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);
}
}

@ -78,10 +78,13 @@ namespace Google.Protobuf.WellKnownTypes {
/// Example 4: Pack and unpack a message in Go
///
/// foo := &amp;pb.Foo{...}
/// any, err := ptypes.MarshalAny(foo)
/// any, err := anypb.New(foo)
/// if err != nil {
/// ...
/// }
/// ...
/// foo := &amp;pb.Foo{}
/// if err := ptypes.UnmarshalAny(any, foo); err != nil {
/// if err := any.UnmarshalTo(foo); err != nil {
/// ...
/// }
///
@ -248,6 +251,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 +265,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() {

@ -324,11 +324,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;

@ -144,6 +144,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);
@ -151,7 +154,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() {
@ -307,6 +324,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);
@ -314,7 +334,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() {
@ -470,6 +504,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);
@ -477,8 +514,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;
@ -633,6 +684,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);
@ -640,8 +694,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;
@ -796,6 +864,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);
@ -803,7 +874,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() {
@ -959,6 +1044,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);
@ -966,7 +1054,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() {
@ -1122,6 +1224,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);
@ -1129,8 +1234,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;
@ -1285,6 +1404,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);
@ -1292,8 +1414,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;
@ -1448,6 +1584,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);
@ -1455,8 +1594,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,628 @@
#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
{
BinaryPrimitives.WriteUInt64LittleEndian(buffer.Slice(state.position), value);
state.position += length;
}
}
[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);
}
}
}
}
}

@ -36,6 +36,7 @@ These are projects we know about implementing Protocol Buffers for other program
* Delphi: http://fundementals.sourceforge.net/dl.html
* Elixir: https://github.com/jeremyong/exprotoc
* Elixir: https://github.com/tony612/protobuf-elixir
* Elixir: https://github.com/ahamez/protox
* Elm: https://github.com/tiziano88/elm-protobuf
* Erlang: https://github.com/tomas-abrahamsson/gpb
* Erlang: http://piqi.org/

@ -216,7 +216,11 @@ Key bindings:
(c-common-init 'protobuf-mode)
(easy-menu-add protobuf-menu)
(c-run-mode-hooks 'c-mode-common-hook 'protobuf-mode-hook)
(c-update-modeline))
(c-update-modeline)
(setq imenu-generic-expression
'(("Message" "^[[:space:]]*message[[:space:]]+\\([[:alnum:]]+\\)" 1)
("Enum" "^[[:space:]]*enum[[:space:]]+\\([[:alnum:]]+\\)" 1)
("Service" "^[[:space:]]*service[[:space:]]+\\([[:alnum:]]+\\)" 1))))
(provide 'protobuf-mode)

@ -29,7 +29,7 @@ RUN apt-get update && apt-get install -y libunwind8 libicu57 && apt-get clean
RUN wget -q https://dot.net/v1/dotnet-install.sh && \
chmod u+x dotnet-install.sh && \
./dotnet-install.sh --version 2.1.802 && \
./dotnet-install.sh --version 3.0.100 && \
./dotnet-install.sh --version 3.1.301 && \
ln -s /root/.dotnet/dotnet /usr/local/bin
RUN wget -q www.nuget.org/NuGet.exe -O /usr/local/bin/nuget.exe

@ -94,10 +94,13 @@ typedef GPB_ENUM(GPBAny_FieldNumber) {
* Example 4: Pack and unpack a message in Go
*
* foo := &pb.Foo{...}
* any, err := ptypes.MarshalAny(foo)
* any, err := anypb.New(foo)
* if err != nil {
* ...
* }
* ...
* foo := &pb.Foo{}
* if err := ptypes.UnmarshalAny(any, foo); err != nil {
* if err := any.UnmarshalTo(foo); err != nil {
* ...
* }
*

@ -0,0 +1,95 @@
// 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.
#include <Zend/zend_API.h>
#include "php-upb.h"
// -----------------------------------------------------------------------------
// Arena
// -----------------------------------------------------------------------------
typedef struct Arena {
zend_object std;
upb_arena* arena;
} Arena;
zend_class_entry *Arena_class_entry;
static zend_object_handlers Arena_object_handlers;
// PHP Object Handlers /////////////////////////////////////////////////////////
static zend_object* Arena_Create(zend_class_entry *class_type) {
Arena *intern = emalloc(sizeof(Arena));
zend_object_std_init(&intern->std, class_type);
intern->std.handlers = &Arena_object_handlers;
intern->arena = upb_arena_new();
// Skip object_properties_init(), we don't allow derived classes.
return &intern->std;
}
static void Arena_Free(zend_object* obj) {
Arena* intern = (Arena*)obj;
upb_arena_free(intern->arena);
zend_object_std_dtor(&intern->std);
}
// C Functions from arena.h ////////////////////////////////////////////////////
void Arena_Init(zval* val) {
ZVAL_OBJ(val, Arena_Create(Arena_class_entry));
}
upb_arena *Arena_Get(zval *val) {
Arena *a = (Arena*)Z_OBJ_P(val);
return a->arena;
}
// -----------------------------------------------------------------------------
// Module init.
// -----------------------------------------------------------------------------
// No public methods.
static const zend_function_entry Arena_methods[] = {
ZEND_FE_END
};
void Arena_ModuleInit() {
zend_class_entry tmp_ce;
INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Internal\\Arena", Arena_methods);
Arena_class_entry = zend_register_internal_class(&tmp_ce);
Arena_class_entry->create_object = Arena_Create;
Arena_class_entry->ce_flags |= ZEND_ACC_FINAL;
memcpy(&Arena_object_handlers, &std_object_handlers,
sizeof(zend_object_handlers));
Arena_object_handlers.free_obj = Arena_Free;
}

@ -0,0 +1,47 @@
// 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.
#ifndef PHP_PROTOBUF_ARENA_H_
#define PHP_PROTOBUF_ARENA_H_
#include <php.h>
#include "php-upb.h"
// Registers the PHP Arena class.
void Arena_ModuleInit();
// Creates and returns a new arena object that wraps a new upb_arena*.
void Arena_Init(zval *val);
// Gets the underlying upb_arena from this arena object.
upb_arena *Arena_Get(zval *arena);
#endif // PHP_PROTOBUF_ARENA_H_

@ -0,0 +1,602 @@
// 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.
#include "array.h"
#include <Zend/zend_API.h>
#include <Zend/zend_interfaces.h>
#include <ext/spl/spl_iterators.h>
// This is not self-contained: it must be after other Zend includes.
#include <Zend/zend_exceptions.h>
#include "arena.h"
#include "convert.h"
#include "def.h"
#include "php-upb.h"
#include "protobuf.h"
static void RepeatedFieldIter_make(zval *val, zval *repeated_field);
// -----------------------------------------------------------------------------
// RepeatedField
// -----------------------------------------------------------------------------
typedef struct {
zend_object std;
zval arena;
upb_array *array;
upb_fieldtype_t type;
const Descriptor* desc; // When values are messages.
} RepeatedField;
zend_class_entry *RepeatedField_class_entry;
static zend_object_handlers RepeatedField_object_handlers;
// PHP Object Handlers /////////////////////////////////////////////////////////
/**
* RepeatedField_create()
*
* PHP class entry function to allocate and initialize a new RepeatedField
* object.
*/
static zend_object* RepeatedField_create(zend_class_entry *class_type) {
RepeatedField *intern = emalloc(sizeof(RepeatedField));
zend_object_std_init(&intern->std, class_type);
intern->std.handlers = &RepeatedField_object_handlers;
Arena_Init(&intern->arena);
intern->array = NULL;
intern->desc = NULL;
// Skip object_properties_init(), we don't allow derived classes.
return &intern->std;
}
/**
* RepeatedField_dtor()
*
* Object handler to destroy a RepeatedField. This releases all resources
* associated with the message. Note that it is possible to access a destroyed
* object from PHP in rare cases.
*/
static void RepeatedField_destructor(zend_object* obj) {
RepeatedField* intern = (RepeatedField*)obj;
ObjCache_Delete(intern->array);
zval_ptr_dtor(&intern->arena);
zend_object_std_dtor(&intern->std);
}
static HashTable *RepeatedField_GetProperties(zval *object TSRMLS_DC) {
return NULL; // We do not have a properties table.
}
static zval *RepeatedField_GetPropertyPtrPtr(zval *object, zval *member,
int type, void **cache_slot) {
return NULL; // We don't offer direct references to our properties.
}
// C Functions from array.h ////////////////////////////////////////////////////
// These are documented in the header file.
void RepeatedField_GetPhpWrapper(zval *val, upb_array *arr,
const upb_fielddef *f, zval *arena) {
if (!arr) {
ZVAL_NULL(val);
return;
}
if (!ObjCache_Get(arr, val)) {
RepeatedField *intern = emalloc(sizeof(RepeatedField));
zend_object_std_init(&intern->std, RepeatedField_class_entry);
intern->std.handlers = &RepeatedField_object_handlers;
ZVAL_COPY(&intern->arena, arena);
intern->array = arr;
intern->type = upb_fielddef_type(f);
intern->desc = Descriptor_GetFromFieldDef(f);
// Skip object_properties_init(), we don't allow derived classes.
ObjCache_Add(intern->array, &intern->std);
ZVAL_OBJ(val, &intern->std);
}
}
upb_array *RepeatedField_GetUpbArray(zval *val, const upb_fielddef *f,
upb_arena *arena) {
if (Z_ISREF_P(val)) {
ZVAL_DEREF(val);
}
if (Z_TYPE_P(val) == IS_ARRAY) {
// Auto-construct, eg. [1, 2, 3] -> upb_array([1, 2, 3]).
upb_array *arr = upb_array_new(arena, upb_fielddef_type(f));
HashTable *table = HASH_OF(val);
HashPosition pos;
upb_fieldtype_t type = upb_fielddef_type(f);
const Descriptor *desc = Descriptor_GetFromFieldDef(f);
zend_hash_internal_pointer_reset_ex(table, &pos);
while (true) {
zval *zv = zend_hash_get_current_data_ex(table, &pos);
upb_msgval val;
if (!zv) return arr;
if (!Convert_PhpToUpbAutoWrap(zv, &val, type, desc, arena)) {
return NULL;
}
upb_array_append(arr, val, arena);
zend_hash_move_forward_ex(table, &pos);
}
} else if (Z_TYPE_P(val) == IS_OBJECT &&
Z_OBJCE_P(val) == RepeatedField_class_entry) {
// Unwrap existing RepeatedField object to get the upb_array* inside.
RepeatedField *intern = (RepeatedField*)Z_OBJ_P(val);
const Descriptor *desc = Descriptor_GetFromFieldDef(f);
if (intern->type != upb_fielddef_type(f) || intern->desc != desc) {
php_error_docref(NULL, E_USER_ERROR,
"Wrong type for this repeated field.");
}
upb_arena_fuse(arena, Arena_Get(&intern->arena));
return intern->array;
} else {
php_error_docref(NULL, E_USER_ERROR, "Must be a repeated field");
return NULL;
}
}
// RepeatedField PHP methods ///////////////////////////////////////////////////
/**
* RepeatedField::__construct()
*
* Constructs an instance of RepeatedField.
* @param long Type of the stored element.
* @param string Message/Enum class.
*/
PHP_METHOD(RepeatedField, __construct) {
RepeatedField *intern = (RepeatedField*)Z_OBJ_P(getThis());
upb_arena *arena = Arena_Get(&intern->arena);
zend_long type;
zend_class_entry* klass = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|C", &type, &klass) != SUCCESS) {
return;
}
intern->type = pbphp_dtype_to_type(type);
intern->desc = Descriptor_GetFromClassEntry(klass);
if (intern->type == UPB_TYPE_MESSAGE && klass == NULL) {
php_error_docref(NULL, E_USER_ERROR,
"Message/enum type must have concrete class.");
return;
}
intern->array = upb_array_new(arena, intern->type);
ObjCache_Add(intern->array, &intern->std);
}
/**
* RepeatedField::append()
*
* Append element to the end of the repeated field.
* @param object The element to be added.
*/
PHP_METHOD(RepeatedField, append) {
RepeatedField *intern = (RepeatedField*)Z_OBJ_P(getThis());
upb_arena *arena = Arena_Get(&intern->arena);
zval *php_val;
upb_msgval msgval;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &php_val) != SUCCESS ||
!Convert_PhpToUpb(php_val, &msgval, intern->type, intern->desc, arena)) {
return;
}
upb_array_append(intern->array, msgval, arena);
}
/**
* RepeatedField::offsetExists()
*
* Implements the ArrayAccess interface. Invoked when PHP code calls:
*
* isset($arr[$idx]);
* empty($arr[$idx]);
*
* @param long The index to be checked.
* @return bool True if the element at the given index exists.
*/
PHP_METHOD(RepeatedField, offsetExists) {
RepeatedField *intern = (RepeatedField*)Z_OBJ_P(getThis());
zend_long index;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) {
return;
}
RETURN_BOOL(index >= 0 && index < upb_array_size(intern->array));
}
/**
* RepeatedField::offsetGet()
*
* Implements the ArrayAccess interface. Invoked when PHP code calls:
*
* $x = $arr[$idx];
*
* @param long The index of the element to be fetched.
* @return object The stored element at given index.
* @exception Invalid type for index.
* @exception Non-existing index.
*/
PHP_METHOD(RepeatedField, offsetGet) {
RepeatedField *intern = (RepeatedField*)Z_OBJ_P(getThis());
zend_long index;
upb_msgval msgval;
zval ret;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) {
return;
}
if (index < 0 || index >= upb_array_size(intern->array)) {
zend_error(E_USER_ERROR, "Element at %ld doesn't exist.\n", index);
return;
}
msgval = upb_array_get(intern->array, index);
Convert_UpbToPhp(msgval, &ret, intern->type, intern->desc, &intern->arena);
RETURN_ZVAL(&ret, 0, 1);
}
/**
* RepeatedField::offsetSet()
*
* Implements the ArrayAccess interface. Invoked when PHP code calls:
*
* $arr[$idx] = $x;
* $arr []= $x; // Append
*
* @param long The index of the element to be assigned.
* @param object The element to be assigned.
* @exception Invalid type for index.
* @exception Non-existing index.
* @exception Incorrect type of the element.
*/
PHP_METHOD(RepeatedField, offsetSet) {
RepeatedField *intern = (RepeatedField*)Z_OBJ_P(getThis());
upb_arena *arena = Arena_Get(&intern->arena);
size_t size = upb_array_size(intern->array);
zval *offset, *val;
int64_t index;
upb_msgval msgval;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &offset, &val) != SUCCESS) {
return;
}
if (Z_TYPE_P(offset) == IS_NULL) {
index = size;
} else if (!Convert_PhpToInt64(offset, &index)) {
return;
}
if (!Convert_PhpToUpb(val, &msgval, intern->type, intern->desc, arena)) {
return;
}
if (index > size) {
zend_error(E_USER_ERROR, "Element at index %ld doesn't exist.\n", index);
} else if (index == size) {
upb_array_append(intern->array, msgval, Arena_Get(&intern->arena));
} else {
upb_array_set(intern->array, index, msgval);
}
}
/**
* RepeatedField::offsetUnset()
*
* Implements the ArrayAccess interface. Invoked when PHP code calls:
*
* unset($arr[$idx]);
*
* @param long The index of the element to be removed.
* @exception Invalid type for index.
* @exception The element to be removed is not at the end of the RepeatedField.
*/
PHP_METHOD(RepeatedField, offsetUnset) {
RepeatedField *intern = (RepeatedField*)Z_OBJ_P(getThis());
zend_long index;
zend_long size = upb_array_size(intern->array);
// Only the element at the end of the array can be removed.
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) != SUCCESS) {
return;
}
if (size == 0 || index != size - 1) {
php_error_docref(NULL, E_USER_ERROR, "Cannot remove element at %ld.\n",
index);
return;
}
upb_array_resize(intern->array, size - 1, Arena_Get(&intern->arena));
}
/**
* RepeatedField::count()
*
* Implements the Countable interface. Invoked when PHP code calls:
*
* $len = count($arr);
* Return the number of stored elements.
* This will also be called for: count($arr)
* @return long The number of stored elements.
*/
PHP_METHOD(RepeatedField, count) {
RepeatedField *intern = (RepeatedField*)Z_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
RETURN_LONG(upb_array_size(intern->array));
}
/**
* RepeatedField::getIterator()
*
* Implements the IteratorAggregate interface. Invoked when PHP code calls:
*
* foreach ($arr) {}
*
* @return object Beginning iterator.
*/
PHP_METHOD(RepeatedField, getIterator) {
zval ret;
RepeatedFieldIter_make(&ret, getThis());
RETURN_ZVAL(&ret, 0, 1);
}
ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetGet, 0, 0, 1)
ZEND_ARG_INFO(0, index)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetSet, 0, 0, 2)
ZEND_ARG_INFO(0, index)
ZEND_ARG_INFO(0, newval)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_void, 0)
ZEND_END_ARG_INFO()
static zend_function_entry repeated_field_methods[] = {
PHP_ME(RepeatedField, __construct, NULL, ZEND_ACC_PUBLIC)
PHP_ME(RepeatedField, append, NULL, ZEND_ACC_PUBLIC)
PHP_ME(RepeatedField, offsetExists, arginfo_offsetGet, ZEND_ACC_PUBLIC)
PHP_ME(RepeatedField, offsetGet, arginfo_offsetGet, ZEND_ACC_PUBLIC)
PHP_ME(RepeatedField, offsetSet, arginfo_offsetSet, ZEND_ACC_PUBLIC)
PHP_ME(RepeatedField, offsetUnset, arginfo_offsetGet, ZEND_ACC_PUBLIC)
PHP_ME(RepeatedField, count, arginfo_void, ZEND_ACC_PUBLIC)
PHP_ME(RepeatedField, getIterator, arginfo_void, ZEND_ACC_PUBLIC)
ZEND_FE_END
};
// -----------------------------------------------------------------------------
// PHP RepeatedFieldIter
// -----------------------------------------------------------------------------
typedef struct {
zend_object std;
zval repeated_field;
zend_long position;
} RepeatedFieldIter;
zend_class_entry *RepeatedFieldIter_class_entry;
static zend_object_handlers repeated_field_iter_object_handlers;
/**
* RepeatedFieldIter_create()
*
* PHP class entry function to allocate and initialize a new RepeatedFieldIter
* object.
*/
zend_object* RepeatedFieldIter_create(zend_class_entry *class_type) {
RepeatedFieldIter *intern = emalloc(sizeof(RepeatedFieldIter));
zend_object_std_init(&intern->std, class_type);
intern->std.handlers = &repeated_field_iter_object_handlers;
ZVAL_NULL(&intern->repeated_field);
intern->position = 0;
// Skip object_properties_init(), we don't allow derived classes.
return &intern->std;
}
/**
* RepeatedFieldIter_dtor()
*
* Object handler to destroy a RepeatedFieldIter. This releases all resources
* associated with the message. Note that it is possible to access a destroyed
* object from PHP in rare cases.
*/
static void RepeatedFieldIter_dtor(zend_object* obj) {
RepeatedFieldIter* intern = (RepeatedFieldIter*)obj;
zval_ptr_dtor(&intern->repeated_field);
zend_object_std_dtor(&intern->std);
}
/**
* RepeatedFieldIter_make()
*
* C function to create a RepeatedFieldIter.
*/
static void RepeatedFieldIter_make(zval *val, zval *repeated_field) {
RepeatedFieldIter *iter;
ZVAL_OBJ(val, RepeatedFieldIter_class_entry->create_object(
RepeatedFieldIter_class_entry));
iter = (RepeatedFieldIter*)Z_OBJ_P(val);
ZVAL_COPY(&iter->repeated_field, repeated_field);
}
/*
* When a user writes:
*
* foreach($arr as $key => $val) {}
*
* PHP's iterator protocol is:
*
* $iter = $arr->getIterator();
* for ($iter->rewind(); $iter->valid(); $iter->next()) {
* $key = $iter->key();
* $val = $iter->current();
* }
*/
/**
* RepeatedFieldIter::rewind()
*
* Implements the Iterator interface. Sets the iterator to the first element.
*/
PHP_METHOD(RepeatedFieldIter, rewind) {
RepeatedFieldIter *intern = (RepeatedFieldIter*)Z_OBJ_P(getThis());
intern->position = 0;
}
/**
* RepeatedFieldIter::current()
*
* Implements the Iterator interface. Returns the current value.
*/
PHP_METHOD(RepeatedFieldIter, current) {
RepeatedFieldIter *intern = (RepeatedFieldIter*)Z_OBJ_P(getThis());
RepeatedField *field = (RepeatedField*)Z_OBJ_P(&intern->repeated_field);
upb_array *array = field->array;
zend_long index = intern->position;
upb_msgval msgval;
zval ret;
if (index < 0 || index >= upb_array_size(array)) {
zend_error(E_USER_ERROR, "Element at %ld doesn't exist.\n", index);
}
msgval = upb_array_get(array, index);
Convert_UpbToPhp(msgval, &ret, field->type, field->desc, &field->arena);
RETURN_ZVAL(&ret, 0, 1);
}
/**
* RepeatedFieldIter::key()
*
* Implements the Iterator interface. Returns the current key.
*/
PHP_METHOD(RepeatedFieldIter, key) {
RepeatedFieldIter *intern = (RepeatedFieldIter*)Z_OBJ_P(getThis());
RETURN_LONG(intern->position);
}
/**
* RepeatedFieldIter::next()
*
* Implements the Iterator interface. Advances to the next element.
*/
PHP_METHOD(RepeatedFieldIter, next) {
RepeatedFieldIter *intern = (RepeatedFieldIter*)Z_OBJ_P(getThis());
++intern->position;
}
/**
* RepeatedFieldIter::valid()
*
* Implements the Iterator interface. Returns true if this is a valid element.
*/
PHP_METHOD(RepeatedFieldIter, valid) {
RepeatedFieldIter *intern = (RepeatedFieldIter*)Z_OBJ_P(getThis());
RepeatedField *field = (RepeatedField*)Z_OBJ_P(&intern->repeated_field);
RETURN_BOOL(intern->position < upb_array_size(field->array));
}
static zend_function_entry repeated_field_iter_methods[] = {
PHP_ME(RepeatedFieldIter, rewind, arginfo_void, ZEND_ACC_PUBLIC)
PHP_ME(RepeatedFieldIter, current, arginfo_void, ZEND_ACC_PUBLIC)
PHP_ME(RepeatedFieldIter, key, arginfo_void, ZEND_ACC_PUBLIC)
PHP_ME(RepeatedFieldIter, next, arginfo_void, ZEND_ACC_PUBLIC)
PHP_ME(RepeatedFieldIter, valid, arginfo_void, ZEND_ACC_PUBLIC)
ZEND_FE_END
};
// -----------------------------------------------------------------------------
// Module init.
// -----------------------------------------------------------------------------
/**
* Array_ModuleInit()
*
* Called when the C extension is loaded to register all types.
*/
void Array_ModuleInit() {
zend_class_entry tmp_ce;
zend_object_handlers *h;
// RepeatedField.
INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Internal\\RepeatedField",
repeated_field_methods);
RepeatedField_class_entry = zend_register_internal_class(&tmp_ce);
zend_class_implements(RepeatedField_class_entry, 3, spl_ce_ArrayAccess,
zend_ce_aggregate, spl_ce_Countable);
RepeatedField_class_entry->ce_flags |= ZEND_ACC_FINAL;
RepeatedField_class_entry->create_object = RepeatedField_create;
h = &RepeatedField_object_handlers;
memcpy(h, &std_object_handlers, sizeof(zend_object_handlers));
h->dtor_obj = RepeatedField_destructor;
h->get_properties = RepeatedField_GetProperties;
h->get_property_ptr_ptr = RepeatedField_GetPropertyPtrPtr;
// RepeatedFieldIter
INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Internal\\RepeatedFieldIter",
repeated_field_iter_methods);
RepeatedFieldIter_class_entry = zend_register_internal_class(&tmp_ce);
zend_class_implements(RepeatedFieldIter_class_entry, 1, zend_ce_iterator);
RepeatedFieldIter_class_entry->ce_flags |= ZEND_ACC_FINAL;
RepeatedFieldIter_class_entry->create_object = RepeatedFieldIter_create;
h = &repeated_field_iter_object_handlers;
memcpy(h, &std_object_handlers, sizeof(zend_object_handlers));
h->dtor_obj = RepeatedFieldIter_dtor;
}

@ -0,0 +1,61 @@
// 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.
#ifndef PHP_PROTOBUF_ARRAY_H_
#define PHP_PROTOBUF_ARRAY_H_
#include <php.h>
#include "php-upb.h"
// Registers PHP classes for RepeatedField.
void Array_ModuleInit();
// Gets a upb_array* for the PHP object |val|:
// * If |val| is a RepeatedField object, we first check its type and verify
// that that the elements have the correct type for |f|. If so, we return the
// wrapped upb_array*. We also make sure that this array's arena is fused to
// |arena|, so the returned upb_array is guaranteed to live as long as
// |arena|.
// * If |val| is a PHP Array, we attempt to create a new upb_array using
// |arena| and add all of the PHP elements to it.
//
// If an error occurs, we raise a PHP error and return NULL.
upb_array *RepeatedField_GetUpbArray(zval *val, const upb_fielddef *f, upb_arena *arena);
// Creates a PHP RepeatedField object for the given upb_array* and |f| and
// returns it in |val|. The PHP object will keep a reference to this |arena| to
// ensure the underlying array data stays alive.
//
// If |arr| is NULL, this will return a PHP null object.
void RepeatedField_GetPhpWrapper(zval *val, upb_array *arr,
const upb_fielddef *f, zval *arena);
#endif // PHP_PROTOBUF_ARRAY_H_

@ -0,0 +1,46 @@
// 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.
#ifndef PHP_PROTOBUF_BUNDLED_PHP_H_
#define PHP_PROTOBUF_BUNDLED_PHP_H_
// We embed PHP source code into the binary for things we don't want to
// implement in C. This struct serves as a table of contents for all of
// the embedded files.
typedef struct {
const char *filename;
const char *contents;
} BundledPhp_File;
// An array of all the embedded file structs. This array is terminated with a
// {NULL, NULL} entry.
extern BundledPhp_File *bundled_files;
#endif // PHP_PROTOBUF_BUNDLED_PHP_H_

@ -0,0 +1,10 @@
PHP_ARG_ENABLE(protobuf, whether to enable Protobuf extension, [ --enable-protobuf Enable Protobuf extension])
if test "$PHP_PROTOBUF" != "no"; then
PHP_NEW_EXTENSION(
protobuf,
arena.c array.c bundled_php.c convert.c def.c map.c message.c names.c php-upb.c protobuf.c,
$ext_shared)
fi

@ -0,0 +1,478 @@
// 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.
#include "convert.h"
#include <php.h>
// This is not self-contained: it must be after other Zend includes.
#include <Zend/zend_exceptions.h>
#include "array.h"
#include "map.h"
#include "message.h"
#include "php-upb.h"
#include "protobuf.h"
// -----------------------------------------------------------------------------
// GPBUtil
// -----------------------------------------------------------------------------
static zend_class_entry* GPBUtil_class_entry;
// The implementation of type checking for primitive fields is empty. This is
// because type checking is done when direct assigning message fields (e.g.,
// foo->a = 1). Functions defined here are place holders in generated code for
// pure PHP implementation (c extension and pure PHP share the same generated
// code).
PHP_METHOD(Util, checkInt32) {}
PHP_METHOD(Util, checkUint32) {}
PHP_METHOD(Util, checkInt64) {}
PHP_METHOD(Util, checkUint64) {}
PHP_METHOD(Util, checkEnum) {}
PHP_METHOD(Util, checkFloat) {}
PHP_METHOD(Util, checkDouble) {}
PHP_METHOD(Util, checkBool) {}
PHP_METHOD(Util, checkString) {}
PHP_METHOD(Util, checkBytes) {}
PHP_METHOD(Util, checkMessage) {}
// The result of checkMapField() is assigned, so we need to return the first
// param:
// $arr = GPBUtil::checkMapField($var,
// \Google\Protobuf\Internal\GPBType::INT64,
// \Google\Protobuf\Internal\GPBType::INT32);
PHP_METHOD(Util, checkMapField) {
zval *val, *key_type, *val_type, *klass;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zzz|z", &val, &key_type,
&val_type, &klass) == FAILURE) {
return;
}
RETURN_ZVAL(val, 1, 0);
}
// The result of checkRepeatedField() is assigned, so we need to return the
// first param:
// $arr = GPBUtil::checkRepeatedField(
// $var, \Google\Protobuf\Internal\GPBType::STRING);
PHP_METHOD(Util, checkRepeatedField) {
zval *val, *type, *klass;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz|z", &val, &type, &klass) ==
FAILURE) {
return;
}
RETURN_ZVAL(val, 1, 0);
}
static zend_function_entry util_methods[] = {
PHP_ME(Util, checkInt32, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(Util, checkUint32, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(Util, checkInt64, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(Util, checkUint64, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(Util, checkEnum, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(Util, checkFloat, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(Util, checkDouble, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(Util, checkBool, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(Util, checkString, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(Util, checkBytes, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(Util, checkMessage, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(Util, checkMapField, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(Util, checkRepeatedField, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
ZEND_FE_END
};
// -----------------------------------------------------------------------------
// Conversion functions used from C
// -----------------------------------------------------------------------------
upb_fieldtype_t pbphp_dtype_to_type(upb_descriptortype_t type) {
switch (type) {
#define CASE(descriptor_type, type) \
case UPB_DESCRIPTOR_TYPE_##descriptor_type: \
return UPB_TYPE_##type;
CASE(FLOAT, FLOAT);
CASE(DOUBLE, DOUBLE);
CASE(BOOL, BOOL);
CASE(STRING, STRING);
CASE(BYTES, BYTES);
CASE(MESSAGE, MESSAGE);
CASE(GROUP, MESSAGE);
CASE(ENUM, ENUM);
CASE(INT32, INT32);
CASE(INT64, INT64);
CASE(UINT32, UINT32);
CASE(UINT64, UINT64);
CASE(SINT32, INT32);
CASE(SINT64, INT64);
CASE(FIXED32, UINT32);
CASE(FIXED64, UINT64);
CASE(SFIXED32, INT32);
CASE(SFIXED64, INT64);
#undef CASE
}
zend_error(E_ERROR, "Unknown field type.");
return 0;
}
static bool buftouint64(const char *ptr, const char *end, uint64_t *val) {
uint64_t u64 = 0;
while (ptr < end) {
unsigned ch = (unsigned)(*ptr - '0');
if (ch >= 10) break;
if (u64 > UINT64_MAX / 10 || u64 * 10 > UINT64_MAX - ch) {
return false;
}
u64 *= 10;
u64 += ch;
ptr++;
}
if (ptr != end) {
// In PHP tradition, we allow truncation: "1.1" -> 1.
// But we don't allow 'e', eg. '1.1e2' or any other non-numeric chars.
if (*ptr++ != '.') return false;
for (;ptr < end; ptr++) {
if (*ptr < '0' || *ptr > '9') {
return false;
}
}
}
*val = u64;
return true;
}
static bool buftoint64(const char *ptr, const char *end, int64_t *val) {
bool neg = false;
uint64_t u64;
if (ptr != end && *ptr == '-') {
ptr++;
neg = true;
}
if (!buftouint64(ptr, end, &u64) ||
u64 > (uint64_t)INT64_MAX + neg) {
return false;
}
*val = neg ? -u64 : u64;
return true;
}
static void throw_conversion_exception(const char *to, const zval *zv) {
zval tmp;
ZVAL_COPY(&tmp, zv);
convert_to_string(&tmp);
zend_throw_exception_ex(NULL, 0, "Cannot convert '%s' to %s",
Z_STRVAL_P(&tmp), to);
zval_ptr_dtor(&tmp);
}
bool Convert_PhpToInt64(const zval *php_val, int64_t *i64) {
switch (Z_TYPE_P(php_val)) {
case IS_LONG:
*i64 = Z_LVAL_P(php_val);
return true;
case IS_DOUBLE: {
double dbl = Z_DVAL_P(php_val);
if (dbl > 9223372036854774784.0 || dbl < -9223372036854775808.0) {
zend_throw_exception_ex(NULL, 0, "Out of range");
return false;
}
*i64 = dbl; /* must be guarded, overflow here is UB */
return true;
}
case IS_STRING: {
const char *buf = Z_STRVAL_P(php_val);
// PHP would accept scientific notation here, but we're going to be a
// little more discerning and only accept pure integers.
bool ok = buftoint64(buf, buf + Z_STRLEN_P(php_val), i64);
if (!ok) {
throw_conversion_exception("integer", php_val);
}
return ok;
}
default:
throw_conversion_exception("integer", php_val);
return false;
}
}
static bool to_double(zval *php_val, double *dbl) {
switch (Z_TYPE_P(php_val)) {
case IS_LONG:
*dbl = Z_LVAL_P(php_val);
return true;
case IS_DOUBLE:
*dbl = Z_DVAL_P(php_val);
return true;
case IS_STRING: {
zend_long lval;
switch (is_numeric_string(Z_STRVAL_P(php_val), Z_STRLEN_P(php_val), &lval,
dbl, false)) {
case IS_LONG:
*dbl = lval;
return true;
case IS_DOUBLE:
return true;
default:
goto fail;
}
}
default:
fail:
throw_conversion_exception("double", php_val);
return false;
}
}
static bool to_bool(zval* from, bool* to) {
switch (Z_TYPE_P(from)) {
case IS_TRUE:
*to = true;
return true;
case IS_FALSE:
*to = false;
return true;
case IS_LONG:
*to = (Z_LVAL_P(from) != 0);
return true;
case IS_DOUBLE:
*to = (Z_LVAL_P(from) != 0);
return true;
case IS_STRING:
if (Z_STRLEN_P(from) == 0 ||
(Z_STRLEN_P(from) == 1 && Z_STRVAL_P(from)[0] == '0')) {
*to = false;
} else {
*to = true;
}
return true;
default:
throw_conversion_exception("bool", from);
return false;
}
}
static bool to_string(zval* from) {
if (Z_ISREF_P(from)) {
ZVAL_DEREF(from);
}
switch (Z_TYPE_P(from)) {
case IS_STRING:
return true;
case IS_TRUE:
case IS_FALSE:
case IS_LONG:
case IS_DOUBLE: {
zval tmp;
zend_make_printable_zval(from, &tmp);
ZVAL_COPY_VALUE(from, &tmp);
return true;
}
default:
throw_conversion_exception("string", from);
return false;
}
}
bool Convert_PhpToUpb(zval *php_val, upb_msgval *upb_val, upb_fieldtype_t type,
const Descriptor *desc, upb_arena *arena) {
int64_t i64;
if (Z_ISREF_P(php_val)) {
ZVAL_DEREF(php_val);
}
switch (type) {
case UPB_TYPE_INT64:
return Convert_PhpToInt64(php_val, &upb_val->int64_val);
case UPB_TYPE_INT32:
case UPB_TYPE_ENUM:
if (!Convert_PhpToInt64(php_val, &i64)) {
return false;
}
upb_val->int32_val = i64;
return true;
case UPB_TYPE_UINT64:
if (!Convert_PhpToInt64(php_val, &i64)) {
return false;
}
upb_val->uint64_val = i64;
return true;
case UPB_TYPE_UINT32:
if (!Convert_PhpToInt64(php_val, &i64)) {
return false;
}
upb_val->uint32_val = i64;
return true;
case UPB_TYPE_DOUBLE:
return to_double(php_val, &upb_val->double_val);
case UPB_TYPE_FLOAT:
if (!to_double(php_val, &upb_val->double_val)) return false;
upb_val->float_val = upb_val->double_val;
return true;
case UPB_TYPE_BOOL:
return to_bool(php_val, &upb_val->bool_val);
case UPB_TYPE_STRING:
case UPB_TYPE_BYTES: {
char *ptr;
size_t size;
if (!to_string(php_val)) return false;
size = Z_STRLEN_P(php_val);
// If arena is NULL we reference the input zval.
// The resulting upb_strview will only be value while the zval is alive.
if (arena) {
ptr = upb_arena_malloc(arena, size);
memcpy(ptr, Z_STRVAL_P(php_val), size);
} else {
ptr = Z_STRVAL_P(php_val);
}
upb_val->str_val = upb_strview_make(ptr, size);
return true;
}
case UPB_TYPE_MESSAGE:
PBPHP_ASSERT(desc);
return Message_GetUpbMessage(php_val, desc, arena,
(upb_msg **)&upb_val->msg_val);
}
return false;
}
void Convert_UpbToPhp(upb_msgval upb_val, zval *php_val, upb_fieldtype_t type,
const Descriptor *desc, zval *arena) {
switch (type) {
case UPB_TYPE_INT64:
#if SIZEOF_ZEND_LONG == 8
ZVAL_LONG(php_val, upb_val.int64_val);
#else
{
char buf[20];
int size = sprintf(buf, "%lld", upb_val.int64_val);
ZVAL_NEW_STR(php_val, zend_string_init(buf, size, 0));
}
#endif
break;
case UPB_TYPE_UINT64:
#if SIZEOF_ZEND_LONG == 8
ZVAL_LONG(php_val, upb_val.uint64_val);
#else
{
char buf[20];
int size = sprintf(buf, "%lld", (int64_t)upb_val.uint64_val);
ZVAL_NEW_STR(php_val, zend_string_init(buf, size, 0));
}
#endif
break;
case UPB_TYPE_INT32:
case UPB_TYPE_ENUM:
ZVAL_LONG(php_val, upb_val.int32_val);
break;
case UPB_TYPE_UINT32: {
// Sign-extend for consistency between 32/64-bit builds.
zend_long val = (int32_t)upb_val.uint32_val;
ZVAL_LONG(php_val, val);
break;
}
case UPB_TYPE_DOUBLE:
ZVAL_DOUBLE(php_val, upb_val.double_val);
break;
case UPB_TYPE_FLOAT:
ZVAL_DOUBLE(php_val, upb_val.float_val);
break;
case UPB_TYPE_BOOL:
ZVAL_BOOL(php_val, upb_val.bool_val);
break;
case UPB_TYPE_STRING:
case UPB_TYPE_BYTES: {
upb_strview str = upb_val.str_val;
ZVAL_NEW_STR(php_val, zend_string_init(str.data, str.size, 0));
break;
}
case UPB_TYPE_MESSAGE:
PBPHP_ASSERT(desc);
Message_GetPhpWrapper(php_val, desc, (upb_msg*)upb_val.msg_val, arena);
break;
}
}
bool Convert_PhpToUpbAutoWrap(zval *val, upb_msgval *upb_val,
upb_fieldtype_t type, const Descriptor *desc,
upb_arena *arena) {
const upb_msgdef *subm = desc ? desc->msgdef : NULL;
if (subm && upb_msgdef_iswrapper(subm) && Z_TYPE_P(val) != IS_OBJECT) {
// Assigning a scalar to a wrapper-typed value. We will automatically wrap
// the value, so the user doesn't need to create a FooWrapper(['value': X])
// message manually.
upb_msg *wrapper = upb_msg_new(subm, arena);
const upb_fielddef *val_f = upb_msgdef_itof(subm, 1);
upb_fieldtype_t type_f = upb_fielddef_type(val_f);
upb_msgval msgval;
if (!Convert_PhpToUpb(val, &msgval, type_f, NULL, arena)) return false;
upb_msg_set(wrapper, val_f, msgval, arena);
upb_val->msg_val = wrapper;
return true;
} else {
// Convert_PhpToUpb doesn't auto-construct messages. This means that we only
// allow:
// ['foo_submsg': new Foo(['a' => 1])]
// not:
// ['foo_submsg': ['a' => 1]]
return Convert_PhpToUpb(val, upb_val, type, desc, arena);
}
}
void Convert_ModuleInit(void) {
const char *prefix_name = "TYPE_URL_PREFIX";
zend_class_entry class_type;
INIT_CLASS_ENTRY(class_type, "Google\\Protobuf\\Internal\\GPBUtil",
util_methods);
GPBUtil_class_entry = zend_register_internal_class(&class_type);
zend_declare_class_constant_string(GPBUtil_class_entry, prefix_name,
strlen(prefix_name),
"type.googleapis.com/");
}

@ -0,0 +1,73 @@
// 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.
#ifndef PHP_PROTOBUF_CONVERT_H_
#define PHP_PROTOBUF_CONVERT_H_
#include <php.h>
#include "php-upb.h"
#include "def.h"
upb_fieldtype_t pbphp_dtype_to_type(upb_descriptortype_t type);
// Converts |php_val| to an int64_t. Returns false if the value cannot be
// converted.
bool Convert_PhpToInt64(const zval *php_val, int64_t *i64);
// Converts |php_val| to a upb_msgval according to |type|. If type is
// UPB_TYPE_MESSAGE, then |desc| must be the Descriptor for this message type.
// If type is string, message, or bytes, then |arena| will be used to copy
// string data or fuse this arena to the given message's arena.
bool Convert_PhpToUpb(zval *php_val, upb_msgval *upb_val, upb_fieldtype_t type,
const Descriptor *desc, upb_arena *arena);
// Similar to Convert_PhpToUpb, but supports automatically wrapping the wrapper
// types if a primitive is specified:
//
// 5 -> Int64Wrapper(value=5)
//
// We currently allow this implicit conversion in initializers, but not for
// assignment.
bool Convert_PhpToUpbAutoWrap(zval *val, upb_msgval *upb_val,
upb_fieldtype_t type, const Descriptor *desc,
upb_arena *arena);
// Converts |upb_val| to a PHP zval according to |type|. This may involve
// creating a PHP wrapper object. If type == UPB_TYPE_MESSAGE, then |desc| must
// be the Descriptor for this message type. Any newly created wrapper object
// will reference |arena|.
void Convert_UpbToPhp(upb_msgval upb_val, zval *php_val, upb_fieldtype_t type,
const Descriptor *desc, zval *arena);
// Registers the GPBUtil class.
void Convert_ModuleInit(void);
#endif // PHP_PROTOBUF_CONVERT_H_

File diff suppressed because it is too large Load Diff

@ -0,0 +1,69 @@
// 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.
#ifndef PHP_PROTOBUF_DEF_H_
#define PHP_PROTOBUF_DEF_H_
#include <php.h>
#include "php-upb.h"
// Initializes the Def module, which defines all of the descriptor classes.
void Def_ModuleInit();
// Creates a new DescriptorPool to wrap the given symtab. The DescriptorPool
// takes ownership of the given symtab. If symtab is NULL, the DescriptorPool
// will create an empty symtab instead.
void DescriptorPool_CreateWithSymbolTable(zval *zv, upb_symtab *symtab);
// Given a zval representing a DescriptorPool, steals and returns its symtab,
// which is now owned by the caller.
upb_symtab *DescriptorPool_Steal(zval *zv);
upb_symtab *DescriptorPool_GetSymbolTable();
typedef struct Descriptor {
zend_object std;
const upb_msgdef *msgdef;
zend_class_entry *class_entry;
} Descriptor;
// Gets or creates a PHP Descriptor object for a |ce| and stores it in |val|.
// If this is not a protobuf generated class, |val| will be set to null.
void Descriptor_FromClassEntry(zval *val, zend_class_entry *ce);
// Gets or creates a Descriptor* for the given class entry, upb_msgdef, or
// upb_fielddef. The returned Descriptor* will live for the entire request,
// so no ref is necessary to keep it alive.
Descriptor* Descriptor_GetFromClassEntry(zend_class_entry *ce);
Descriptor* Descriptor_GetFromMessageDef(const upb_msgdef *m);
Descriptor* Descriptor_GetFromFieldDef(const upb_fielddef *f);
#endif // PHP_PROTOBUF_DEF_H_

@ -0,0 +1,62 @@
<?php
$cwd = dirname($argv[0]) . "/../../../src";
chdir($cwd);
$cmd = "grep -r -l 'Generated by the protocol buffer' * | grep 'php$' | grep -v Internal";
$handle = popen($cmd, 'r');
$filenames = explode("\n", stream_get_contents($handle));
array_pop($filenames); // empty string after last '\n'
$filenames[] = "Google/Protobuf/DescriptorPool.php";
$output = "../ext/google/protobuf2/bundled_php.c";
function stripSuffix($str, $suffix) {
return substr($str, 0, strlen($str) - strlen($suffix));
}
function toClassName($filename) {
# Google/Protobuf/BoolValue.php -> Google\\Protobuf\\BoolValue
$ret = stripSuffix($filename, ".php");
return str_replace("/", "\\\\", $ret);
}
function toCSymbolName($filename) {
# Google/Protobuf/BoolValue.php -> Google__Protobuf__BoolValue
$ret = stripSuffix($filename, ".php");
return str_replace("/", "__", $ret);
}
$f = fopen($output, "w");
fwrite($f, "#include \"bundled_php.h\"\n");
fwrite($f, "#include \"stdlib.h\"\n");
foreach ($filenames as $filename) {
print("Reading $filename...\n");
$contents = file_get_contents($filename);
$contents = substr($contents, 5); // Strip <?php
$c_symbol_name = toCSymbolName($filename);
fwrite($f, "static const char {$c_symbol_name}[] = {");
for ($i = 0; $i < strlen($contents); $i++) {
if ($i % 10 == 0) {
fwrite($f, "\n");
}
fprintf($f, " 0x%02x,", ord($contents[$i]));
}
fwrite($f, "0};\n");
}
fwrite($f, "static BundledPhp_File php[] = {\n");
foreach ($filenames as $filename) {
$class_name = toClassName($filename);
$c_symbol_name = toCSymbolName($filename);
fwrite($f, " {\"$class_name\", $c_symbol_name},\n");
}
fwrite($f, " {NULL, NULL}\n");
fwrite($f, "};\n");
fwrite($f, "BundledPhp_File *bundled_files = &php[0];\n");
fclose($f);
print("Wrote $output\n");
?>

@ -0,0 +1,590 @@
// 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.
#include "map.h"
#include <Zend/zend_API.h>
#include <Zend/zend_interfaces.h>
#include <ext/spl/spl_iterators.h>
#include "arena.h"
#include "convert.h"
#include "php-upb.h"
#include "protobuf.h"
static void MapFieldIter_make(zval *val, zval *map_field);
// -----------------------------------------------------------------------------
// MapField
// -----------------------------------------------------------------------------
typedef struct {
zend_object std;
zval arena;
upb_map *map;
upb_fieldtype_t key_type;
upb_fieldtype_t val_type;
const Descriptor* desc; // When values are messages.
} MapField;
zend_class_entry *MapField_class_entry;
static zend_object_handlers MapField_object_handlers;
// PHP Object Handlers /////////////////////////////////////////////////////////
/**
* MapField_create()
*
* PHP class entry function to allocate and initialize a new MapField
* object.
*/
static zend_object* MapField_create(zend_class_entry *class_type) {
MapField *intern = emalloc(sizeof(MapField));
zend_object_std_init(&intern->std, class_type);
intern->std.handlers = &MapField_object_handlers;
Arena_Init(&intern->arena);
intern->map = NULL;
// Skip object_properties_init(), we don't allow derived classes.
return &intern->std;
}
/**
* MapField_dtor()
*
* Object handler to destroy a MapField. This releases all resources
* associated with the message. Note that it is possible to access a destroyed
* object from PHP in rare cases.
*/
static void MapField_destructor(zend_object* obj) {
MapField* intern = (MapField*)obj;
ObjCache_Delete(intern->map);
zval_ptr_dtor(&intern->arena);
zend_object_std_dtor(&intern->std);
}
static zval *Map_GetPropertyPtrPtr(zval *object, zval *member, int type,
void **cache_slot) {
return NULL; // We don't offer direct references to our properties.
}
static HashTable *map_get_properties(zval *object TSRMLS_DC) {
return NULL; // We do not have a properties table.
}
// C Functions from map.h //////////////////////////////////////////////////////
// These are documented in the header file.
void MapField_GetPhpWrapper(zval *val, upb_map *map, const upb_fielddef *f,
zval *arena) {
if (!map) {
ZVAL_NULL(val);
return;
}
if (!ObjCache_Get(map, val)) {
const upb_msgdef *ent = upb_fielddef_msgsubdef(f);
const upb_fielddef *key_f = upb_msgdef_itof(ent, 1);
const upb_fielddef *val_f = upb_msgdef_itof(ent, 2);
MapField *intern = emalloc(sizeof(MapField));
zend_object_std_init(&intern->std, MapField_class_entry);
intern->std.handlers = &MapField_object_handlers;
ZVAL_COPY(&intern->arena, arena);
intern->map = map;
intern->key_type = upb_fielddef_type(key_f);
intern->val_type = upb_fielddef_type(val_f);
intern->desc = Descriptor_GetFromFieldDef(val_f);
// Skip object_properties_init(), we don't allow derived classes.
ObjCache_Add(intern->map, &intern->std);
ZVAL_OBJ(val, &intern->std);
}
}
upb_map *MapField_GetUpbMap(zval *val, const upb_fielddef *f, upb_arena *arena) {
const upb_msgdef *ent = upb_fielddef_msgsubdef(f);
const upb_fielddef *key_f = upb_msgdef_itof(ent, 1);
const upb_fielddef *val_f = upb_msgdef_itof(ent, 2);
upb_fieldtype_t key_type = upb_fielddef_type(key_f);
upb_fieldtype_t val_type = upb_fielddef_type(val_f);
const Descriptor *desc = Descriptor_GetFromFieldDef(val_f);
if (Z_ISREF_P(val)) {
ZVAL_DEREF(val);
}
if (Z_TYPE_P(val) == IS_ARRAY) {
upb_map *map = upb_map_new(arena, key_type, val_type);
HashTable *table = HASH_OF(val);
HashPosition pos;
zend_hash_internal_pointer_reset_ex(table, &pos);
while (true) {
zval php_key;
zval *php_val;
upb_msgval upb_key;
upb_msgval upb_val;
zend_hash_get_current_key_zval_ex(table, &php_key, &pos);
php_val = zend_hash_get_current_data_ex(table, &pos);
if (!php_val) return map;
if (!Convert_PhpToUpb(&php_key, &upb_key, key_type, NULL, arena) ||
!Convert_PhpToUpbAutoWrap(php_val, &upb_val, val_type, desc, arena)) {
return NULL;
}
upb_map_set(map, upb_key, upb_val, arena);
zend_hash_move_forward_ex(table, &pos);
zval_dtor(&php_key);
}
} else if (Z_TYPE_P(val) == IS_OBJECT &&
Z_OBJCE_P(val) == MapField_class_entry) {
MapField *intern = (MapField*)Z_OBJ_P(val);
if (intern->key_type != key_type || intern->val_type != val_type ||
intern->desc != desc) {
php_error_docref(NULL, E_USER_ERROR, "Wrong type for this map field.");
return NULL;
}
upb_arena_fuse(arena, Arena_Get(&intern->arena));
return intern->map;
} else {
php_error_docref(NULL, E_USER_ERROR, "Must be a map");
return NULL;
}
}
// MapField PHP methods ////////////////////////////////////////////////////////
/**
* MapField::__construct()
*
* Constructs an instance of MapField.
* @param long Key type.
* @param long Value type.
* @param string Message/Enum class (message/enum value types only).
*/
PHP_METHOD(MapField, __construct) {
MapField *intern = (MapField*)Z_OBJ_P(getThis());
upb_arena *arena = Arena_Get(&intern->arena);
zend_long key_type, val_type;
zend_class_entry* klass = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll|C", &key_type, &val_type,
&klass) != SUCCESS) {
return;
}
intern->key_type = pbphp_dtype_to_type(key_type);
intern->val_type = pbphp_dtype_to_type(val_type);
intern->desc = Descriptor_GetFromClassEntry(klass);
// Check that the key type is an allowed type.
switch (intern->key_type) {
case UPB_TYPE_INT32:
case UPB_TYPE_INT64:
case UPB_TYPE_UINT32:
case UPB_TYPE_UINT64:
case UPB_TYPE_BOOL:
case UPB_TYPE_STRING:
case UPB_TYPE_BYTES:
// These are OK.
break;
default:
zend_error(E_USER_ERROR, "Invalid key type for map.");
}
if (intern->val_type == UPB_TYPE_MESSAGE && klass == NULL) {
php_error_docref(NULL, E_USER_ERROR,
"Message/enum type must have concrete class.");
return;
}
intern->map = upb_map_new(arena, intern->key_type, intern->val_type);
ObjCache_Add(intern->map, &intern->std);
}
/**
* MapField::offsetExists()
*
* Implements the ArrayAccess interface. Invoked when PHP code calls:
*
* isset($map[$idx]);
* empty($map[$idx]);
*
* @param long The index to be checked.
* @return bool True if the element at the given index exists.
*/
PHP_METHOD(MapField, offsetExists) {
MapField *intern = (MapField*)Z_OBJ_P(getThis());
zval *key;
upb_msgval upb_key;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &key) != SUCCESS ||
!Convert_PhpToUpb(key, &upb_key, intern->key_type, intern->desc, NULL)) {
return;
}
RETURN_BOOL(upb_map_get(intern->map, upb_key, NULL));
}
/**
* MapField::offsetGet()
*
* Implements the ArrayAccess interface. Invoked when PHP code calls:
*
* $x = $map[$idx];
*
* @param long The index of the element to be fetched.
* @return object The stored element at given index.
* @exception Invalid type for index.
* @exception Non-existing index.
*/
PHP_METHOD(MapField, offsetGet) {
MapField *intern = (MapField*)Z_OBJ_P(getThis());
zval *key;
zval ret;
upb_msgval upb_key, upb_val;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &key) != SUCCESS ||
!Convert_PhpToUpb(key, &upb_key, intern->key_type, intern->desc, NULL)) {
return;
}
if (!upb_map_get(intern->map, upb_key, &upb_val)) {
zend_error(E_USER_ERROR, "Given key doesn't exist.");
return;
}
Convert_UpbToPhp(upb_val, &ret, intern->val_type, intern->desc, &intern->arena);
RETURN_ZVAL(&ret, 0, 1);
}
/**
* MapField::offsetSet()
*
* Implements the ArrayAccess interface. Invoked when PHP code calls:
*
* $map[$idx] = $x;
*
* @param long The index of the element to be assigned.
* @param object The element to be assigned.
* @exception Invalid type for index.
* @exception Non-existing index.
* @exception Incorrect type of the element.
*/
PHP_METHOD(MapField, offsetSet) {
MapField *intern = (MapField*)Z_OBJ_P(getThis());
upb_arena *arena = Arena_Get(&intern->arena);
zval *key, *val;
upb_msgval upb_key, upb_val;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &key, &val) != SUCCESS ||
!Convert_PhpToUpb(key, &upb_key, intern->key_type, NULL, NULL) ||
!Convert_PhpToUpb(val, &upb_val, intern->val_type, intern->desc, arena)) {
return;
}
upb_map_set(intern->map, upb_key, upb_val, arena);
}
/**
* MapField::offsetUnset()
*
* Implements the ArrayAccess interface. Invoked when PHP code calls:
*
* unset($map[$idx]);
*
* @param long The index of the element to be removed.
* @exception Invalid type for index.
* @exception The element to be removed is not at the end of the MapField.
*/
PHP_METHOD(MapField, offsetUnset) {
MapField *intern = (MapField*)Z_OBJ_P(getThis());
zval *key;
upb_msgval upb_key;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &key) != SUCCESS ||
!Convert_PhpToUpb(key, &upb_key, intern->key_type, NULL, NULL)) {
return;
}
upb_map_delete(intern->map, upb_key);
}
/**
* MapField::count()
*
* Implements the Countable interface. Invoked when PHP code calls:
*
* $len = count($map);
* Return the number of stored elements.
* This will also be called for: count($map)
* @return long The number of stored elements.
*/
PHP_METHOD(MapField, count) {
MapField *intern = (MapField*)Z_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
RETURN_LONG(upb_map_size(intern->map));
}
/**
* MapField::getIterator()
*
* Implements the IteratorAggregate interface. Invoked when PHP code calls:
*
* foreach ($arr) {}
*
* @return object Beginning iterator.
*/
PHP_METHOD(MapField, getIterator) {
zval ret;
MapFieldIter_make(&ret, getThis());
RETURN_ZVAL(&ret, 0, 1);
}
ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetGet, 0, 0, 1)
ZEND_ARG_INFO(0, index)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetSet, 0, 0, 2)
ZEND_ARG_INFO(0, index)
ZEND_ARG_INFO(0, newval)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_void, 0)
ZEND_END_ARG_INFO()
static zend_function_entry MapField_methods[] = {
PHP_ME(MapField, __construct, NULL, ZEND_ACC_PUBLIC)
PHP_ME(MapField, offsetExists, arginfo_offsetGet, ZEND_ACC_PUBLIC)
PHP_ME(MapField, offsetGet, arginfo_offsetGet, ZEND_ACC_PUBLIC)
PHP_ME(MapField, offsetSet, arginfo_offsetSet, ZEND_ACC_PUBLIC)
PHP_ME(MapField, offsetUnset, arginfo_offsetGet, ZEND_ACC_PUBLIC)
PHP_ME(MapField, count, arginfo_void, ZEND_ACC_PUBLIC)
PHP_ME(MapField, getIterator, arginfo_void, ZEND_ACC_PUBLIC)
ZEND_FE_END
};
// -----------------------------------------------------------------------------
// MapFieldIter
// -----------------------------------------------------------------------------
typedef struct {
zend_object std;
zval map_field;
size_t position;
} MapFieldIter;
zend_class_entry *MapFieldIter_class_entry;
static zend_object_handlers MapFieldIter_object_handlers;
/**
* MapFieldIter_create()
*
* PHP class entry function to allocate and initialize a new MapFieldIter
* object.
*/
zend_object* MapFieldIter_create(zend_class_entry *class_type) {
MapFieldIter *intern = emalloc(sizeof(MapFieldIter));
zend_object_std_init(&intern->std, class_type);
intern->std.handlers = &MapFieldIter_object_handlers;
ZVAL_NULL(&intern->map_field);
intern->position = 0;
// Skip object_properties_init(), we don't allow derived classes.
return &intern->std;
}
/**
* MapFieldIter_dtor()
*
* Object handler to destroy a MapFieldIter. This releases all resources
* associated with the message. Note that it is possible to access a destroyed
* object from PHP in rare cases.
*/
static void map_field_iter_dtor(zend_object* obj) {
MapFieldIter* intern = (MapFieldIter*)obj;
zval_ptr_dtor(&intern->map_field);
zend_object_std_dtor(&intern->std);
}
/**
* MapFieldIter_make()
*
* Function to create a MapFieldIter directly from C.
*/
static void MapFieldIter_make(zval *val, zval *map_field) {
MapFieldIter *iter;
ZVAL_OBJ(val,
MapFieldIter_class_entry->create_object(MapFieldIter_class_entry));
iter = (MapFieldIter*)Z_OBJ_P(val);
ZVAL_COPY(&iter->map_field, map_field);
}
// -----------------------------------------------------------------------------
// PHP MapFieldIter Methods
// -----------------------------------------------------------------------------
/*
* When a user writes:
*
* foreach($arr as $key => $val) {}
*
* PHP translates this into:
*
* $iter = $arr->getIterator();
* for ($iter->rewind(); $iter->valid(); $iter->next()) {
* $key = $iter->key();
* $val = $iter->current();
* }
*/
/**
* MapFieldIter::rewind()
*
* Implements the Iterator interface. Sets the iterator to the first element.
*/
PHP_METHOD(MapFieldIter, rewind) {
MapFieldIter *intern = (MapFieldIter*)Z_OBJ_P(getThis());
MapField *map_field = (MapField*)Z_OBJ_P(&intern->map_field);
intern->position = UPB_MAP_BEGIN;
upb_mapiter_next(map_field->map, &intern->position);
}
/**
* MapFieldIter::current()
*
* Implements the Iterator interface. Returns the current value.
*/
PHP_METHOD(MapFieldIter, current) {
MapFieldIter *intern = (MapFieldIter*)Z_OBJ_P(getThis());
MapField *field = (MapField*)Z_OBJ_P(&intern->map_field);
upb_msgval upb_val = upb_mapiter_value(field->map, intern->position);
zval ret;
Convert_UpbToPhp(upb_val, &ret, field->val_type, field->desc, &field->arena);
RETURN_ZVAL(&ret, 0, 1);
}
/**
* MapFieldIter::key()
*
* Implements the Iterator interface. Returns the current key.
*/
PHP_METHOD(MapFieldIter, key) {
MapFieldIter *intern = (MapFieldIter*)Z_OBJ_P(getThis());
MapField *field = (MapField*)Z_OBJ_P(&intern->map_field);
upb_msgval upb_key = upb_mapiter_key(field->map, intern->position);
zval ret;
Convert_UpbToPhp(upb_key, &ret, field->key_type, NULL, NULL);
RETURN_ZVAL(&ret, 0, 1);
}
/**
* MapFieldIter::next()
*
* Implements the Iterator interface. Advances to the next element.
*/
PHP_METHOD(MapFieldIter, next) {
MapFieldIter *intern = (MapFieldIter*)Z_OBJ_P(getThis());
MapField *field = (MapField*)Z_OBJ_P(&intern->map_field);
upb_mapiter_next(field->map, &intern->position);
}
/**
* MapFieldIter::valid()
*
* Implements the Iterator interface. Returns true if this is a valid element.
*/
PHP_METHOD(MapFieldIter, valid) {
MapFieldIter *intern = (MapFieldIter*)Z_OBJ_P(getThis());
MapField *field = (MapField*)Z_OBJ_P(&intern->map_field);
bool done = upb_mapiter_done(field->map, intern->position);
RETURN_BOOL(!done);
}
static zend_function_entry map_field_iter_methods[] = {
PHP_ME(MapFieldIter, rewind, arginfo_void, ZEND_ACC_PUBLIC)
PHP_ME(MapFieldIter, current, arginfo_void, ZEND_ACC_PUBLIC)
PHP_ME(MapFieldIter, key, arginfo_void, ZEND_ACC_PUBLIC)
PHP_ME(MapFieldIter, next, arginfo_void, ZEND_ACC_PUBLIC)
PHP_ME(MapFieldIter, valid, arginfo_void, ZEND_ACC_PUBLIC)
ZEND_FE_END
};
// -----------------------------------------------------------------------------
// Module init.
// -----------------------------------------------------------------------------
/**
* Map_ModuleInit()
*
* Called when the C extension is loaded to register all types.
*/
void Map_ModuleInit() {
zend_class_entry tmp_ce;
zend_object_handlers *h;
INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Internal\\MapField",
MapField_methods);
MapField_class_entry = zend_register_internal_class(&tmp_ce);
zend_class_implements(MapField_class_entry, 3, spl_ce_ArrayAccess,
zend_ce_aggregate, spl_ce_Countable);
MapField_class_entry->ce_flags |= ZEND_ACC_FINAL;
MapField_class_entry->create_object = MapField_create;
h = &MapField_object_handlers;
memcpy(h, &std_object_handlers, sizeof(zend_object_handlers));
h->dtor_obj = MapField_destructor;
h->get_properties = map_get_properties;
h->get_property_ptr_ptr = Map_GetPropertyPtrPtr;
INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Internal\\MapFieldIter",
map_field_iter_methods);
MapFieldIter_class_entry = zend_register_internal_class(&tmp_ce);
zend_class_implements(MapFieldIter_class_entry, 1, zend_ce_iterator);
MapFieldIter_class_entry->ce_flags |= ZEND_ACC_FINAL;
MapFieldIter_class_entry->ce_flags |= ZEND_ACC_FINAL;
MapFieldIter_class_entry->create_object = MapFieldIter_create;
h = &MapFieldIter_object_handlers;
memcpy(h, &std_object_handlers, sizeof(zend_object_handlers));
h->dtor_obj = map_field_iter_dtor;
}

@ -0,0 +1,60 @@
// 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.
#ifndef PHP_PROTOBUF_MAP_H_
#define PHP_PROTOBUF_MAP_H_
#include <php.h>
#include "php-upb.h"
void Map_ModuleInit();
// Gets a upb_map* for the PHP object |val|:
// * If |val| is a RepeatedField object, we first check its type and verify
// that that the elements have the correct type for |f|. If so, we return the
// wrapped upb_map*. We also make sure that this map's arena is fused to
// |arena|, so the returned upb_map is guaranteed to live as long as
// |arena|.
// * If |val| is a PHP Map, we attempt to create a new upb_map using
// |arena| and add all of the PHP elements to it.
//
// If an error occurs, we raise a PHP error and return NULL.
upb_map *MapField_GetUpbMap(zval *val, const upb_fielddef *f, upb_arena *arena);
// Creates a PHP MapField object for the given upb_map* and |f| and returns it
// in |val|. The PHP object will keep a reference to this |arena| to ensure the
// underlying array data stays alive.
//
// If |map| is NULL, this will return a PHP null object.
void MapField_GetPhpWrapper(zval *val, upb_map *arr, const upb_fielddef *f,
zval *arena);
#endif // PHP_PROTOBUF_MAP_H_

@ -0,0 +1,841 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2014 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.
#include "message.h"
#include <inttypes.h>
#include <php.h>
#include <stdlib.h>
// This is not self-contained: it must be after other Zend includes.
#include <Zend/zend_exceptions.h>
#include "arena.h"
#include "array.h"
#include "convert.h"
#include "def.h"
#include "map.h"
#include "php-upb.h"
#include "protobuf.h"
// -----------------------------------------------------------------------------
// Message
// -----------------------------------------------------------------------------
typedef struct {
zend_object std;
zval arena;
const Descriptor* desc;
upb_msg *msg;
} Message;
zend_class_entry *message_ce;
static zend_object_handlers message_object_handlers;
// PHP Object Handlers /////////////////////////////////////////////////////////
/**
* Message_create()
*
* PHP class entry function to allocate and initialize a new Message object.
*/
static zend_object* Message_create(zend_class_entry *class_type) {
Message *intern = emalloc(sizeof(Message));
// XXX(haberman): verify whether we actually want to take this route.
class_type->default_properties_count = 0;
zend_object_std_init(&intern->std, class_type);
intern->std.handlers = &message_object_handlers;
Arena_Init(&intern->arena);
return &intern->std;
}
/**
* Message_dtor()
*
* Object handler to destroy a Message. This releases all resources associated
* with the message. Note that it is possible to access a destroyed object from
* PHP in rare cases.
*/
static void Message_dtor(zend_object* obj) {
Message* intern = (Message*)obj;
ObjCache_Delete(intern->msg);
zval_dtor(&intern->arena);
zend_object_std_dtor(&intern->std);
}
/**
* get_field()
*
* Helper function to look up a field given a member name (as a string).
*/
static const upb_fielddef *get_field(Message *msg, zval *member) {
const upb_msgdef *m = msg->desc->msgdef;
const upb_fielddef *f =
upb_msgdef_ntof(m, Z_STRVAL_P(member), Z_STRLEN_P(member));
if (!f) {
zend_throw_exception_ex(NULL, 0, "No such property %s.",
ZSTR_VAL(msg->desc->class_entry->name));
}
return f;
}
/**
* Message_read_property()
*
* Object handler for reading a property in PHP. Called when PHP code does:
*
* $x = $message->foobar;
*
* Note that all properties of generated messages are private, so this should
* only be possible to invoke from generated code, which has accessors like:
*
* public function getOptionalInt32()
* {
* return $this->optional_int32;
* }
*
* We lookup the field and return the scalar, RepeatedField, or MapField for
* this field.
*/
static zval *Message_read_property(zval *obj, zval *member, int type,
void **cache_slot, zval *rv) {
Message* intern = (Message*)Z_OBJ_P(obj);
const upb_fielddef *f = get_field(intern, member);
upb_arena *arena = Arena_Get(&intern->arena);
if (!f) return NULL;
if (upb_fielddef_ismap(f)) {
upb_mutmsgval msgval = upb_msg_mutable(intern->msg, f, arena);
MapField_GetPhpWrapper(rv, msgval.map, f, &intern->arena);
} else if (upb_fielddef_isseq(f)) {
upb_mutmsgval msgval = upb_msg_mutable(intern->msg, f, arena);
RepeatedField_GetPhpWrapper(rv, msgval.array, f, &intern->arena);
} else {
upb_msgval msgval = upb_msg_get(intern->msg, f);
const Descriptor *subdesc = Descriptor_GetFromFieldDef(f);
Convert_UpbToPhp(msgval, rv, upb_fielddef_type(f), subdesc, &intern->arena);
}
return rv;
}
/**
* Message_write_property()
*
* Object handler for writing a property in PHP. Called when PHP code does:
*
* $message->foobar = $x;
*
* Note that all properties of generated messages are private, so this should
* only be possible to invoke from generated code, which has accessors like:
*
* public function setOptionalInt32($var)
* {
* GPBUtil::checkInt32($var);
* $this->optional_int32 = $var;
*
* return $this;
* }
*
* The C extension version of checkInt32() doesn't actually check anything, so
* we perform all checking and conversion in this function.
*/
static void Message_write_property(zval *obj, zval *member, zval *val,
void **cache_slot) {
Message* intern = (Message*)Z_OBJ_P(obj);
const upb_fielddef *f = get_field(intern, member);
upb_arena *arena = Arena_Get(&intern->arena);
upb_msgval msgval;
if (!f) return;
if (upb_fielddef_ismap(f)) {
msgval.map_val = MapField_GetUpbMap(val, f, arena);
if (!msgval.map_val) return;
} else if (upb_fielddef_isseq(f)) {
msgval.array_val = RepeatedField_GetUpbArray(val, f, arena);
if (!msgval.array_val) return;
} else {
upb_fieldtype_t type = upb_fielddef_type(f);
const Descriptor *subdesc = Descriptor_GetFromFieldDef(f);
bool ok = Convert_PhpToUpb(val, &msgval, type, subdesc, arena);
if (!ok) return;
}
upb_msg_set(intern->msg, f, msgval, arena);
}
/**
* Message_get_property_ptr_ptr()
*
* Object handler for the get_property_ptr_ptr event in PHP. This returns a
* reference to our internal properties. We don't support this, so we return
* NULL.
*/
static zval *Message_get_property_ptr_ptr(zval *object, zval *member, int type,
void **cache_slot) {
return NULL; // We do not have a properties table.
}
/**
* Message_get_properties()
*
* Object handler for the get_properties event in PHP. This returns a HashTable
* of our internal properties. We don't support this, so we return NULL.
*/
static HashTable* Message_get_properties(zval* object TSRMLS_DC) {
return NULL; // We don't offer direct references to our properties.
}
// C Functions from message.h. /////////////////////////////////////////////////
// These are documented in the header file.
void Message_GetPhpWrapper(zval *val, const Descriptor *desc, upb_msg *msg,
zval *arena) {
if (!msg) {
ZVAL_NULL(val);
return;
}
if (!ObjCache_Get(msg, val)) {
Message *intern = emalloc(sizeof(Message));
// XXX(haberman): verify whether we actually want to take this route.
desc->class_entry->default_properties_count = 0;
zend_object_std_init(&intern->std, desc->class_entry);
intern->std.handlers = &message_object_handlers;
ZVAL_COPY(&intern->arena, arena);
intern->desc = desc;
intern->msg = msg;
ZVAL_OBJ(val, &intern->std);
ObjCache_Add(intern->msg, &intern->std);
}
}
bool Message_GetUpbMessage(zval *val, const Descriptor *desc, upb_arena *arena,
upb_msg **msg) {
PBPHP_ASSERT(desc);
if (Z_ISREF_P(val)) {
ZVAL_DEREF(val);
}
if (Z_TYPE_P(val) == IS_NULL) {
*msg = NULL;
return true;
}
if (Z_TYPE_P(val) == IS_OBJECT &&
instanceof_function(Z_OBJCE_P(val), desc->class_entry)) {
Message *intern = (Message*)Z_OBJ_P(val);
upb_arena_fuse(arena, Arena_Get(&intern->arena));
*msg = intern->msg;
return true;
} else {
zend_throw_exception_ex(NULL, 0, "Given value is not an instance of %s.",
ZSTR_VAL(desc->class_entry->name));
return false;
}
}
// Message PHP methods /////////////////////////////////////////////////////////
/**
* Message_InitFromPhp()
*
* Helper method to handle the initialization of a message from a PHP value, eg.
*
* $m = new TestMessage([
* 'optional_int32' => -42,
* 'optional_bool' => true,
* 'optional_string' => 'a',
* 'optional_enum' => TestEnum::ONE,
* 'optional_message' => new Sub([
* 'a' => 33
* ]),
* 'repeated_int32' => [-42, -52],
* 'repeated_enum' => [TestEnum::ZERO, TestEnum::ONE],
* 'repeated_message' => [new Sub(['a' => 34]),
* new Sub(['a' => 35])],
* 'map_int32_int32' => [-62 => -62],
* 'map_int32_enum' => [1 => TestEnum::ONE],
* 'map_int32_message' => [1 => new Sub(['a' => 36])],
* ]);
*
* The initializer must be an array.
*/
bool Message_InitFromPhp(upb_msg *msg, const upb_msgdef *m, zval *init,
upb_arena *arena) {
HashTable* table = HASH_OF(init);
HashPosition pos;
if (Z_ISREF_P(init)) {
ZVAL_DEREF(init);
}
if (Z_TYPE_P(init) != IS_ARRAY) {
zend_throw_exception_ex(NULL, 0,
"Initializer for a message %s must be an array.",
upb_msgdef_fullname(m));
return false;
}
zend_hash_internal_pointer_reset_ex(table, &pos);
while (true) { // Iterate over key/value pairs.
zval key;
zval *val;
const upb_fielddef *f;
upb_msgval msgval;
zend_hash_get_current_key_zval_ex(table, &key, &pos);
val = zend_hash_get_current_data_ex(table, &pos);
if (!val) return true; // Finished iteration.
if (Z_ISREF_P(val)) {
ZVAL_DEREF(val);
}
f = upb_msgdef_ntof(m, Z_STRVAL_P(&key), Z_STRLEN_P(&key));
if (!f) {
zend_throw_exception_ex(NULL, 0,
"No such field %s", Z_STRVAL_P(&key));
return false;
}
if (upb_fielddef_ismap(f)) {
msgval.map_val = MapField_GetUpbMap(val, f, arena);
if (!msgval.map_val) return false;
} else if (upb_fielddef_isseq(f)) {
msgval.array_val = RepeatedField_GetUpbArray(val, f, arena);
if (!msgval.array_val) return false;
} else {
const Descriptor *desc = Descriptor_GetFromFieldDef(f);
upb_fieldtype_t type = upb_fielddef_type(f);
if (!Convert_PhpToUpbAutoWrap(val, &msgval, type, desc, arena)) {
return false;
}
}
upb_msg_set(msg, f, msgval, arena);
zend_hash_move_forward_ex(table, &pos);
zval_dtor(&key);
}
}
/**
* Message::__construct()
*
* Constructor for Message.
* @param array Map of initial values ['k' = val]
*/
PHP_METHOD(Message, __construct) {
Message* intern = (Message*)Z_OBJ_P(getThis());
const Descriptor* desc = Descriptor_GetFromClassEntry(Z_OBJCE_P(getThis()));
const upb_msgdef *msgdef = desc->msgdef;
upb_arena *arena = Arena_Get(&intern->arena);
zval *init_arr = NULL;
intern->desc = desc;
intern->msg = upb_msg_new(msgdef, arena);
ObjCache_Add(intern->msg, &intern->std);
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|a!", &init_arr) == FAILURE) {
return;
}
if (init_arr) {
Message_InitFromPhp(intern->msg, desc->msgdef, init_arr, arena);
}
}
/**
* Message::discardUnknownFields()
*
* Discards any unknown fields for this message or any submessages.
*/
PHP_METHOD(Message, discardUnknownFields) {
Message* intern = (Message*)Z_OBJ_P(getThis());
upb_msg_discardunknown(intern->msg, intern->desc->msgdef, 64);
}
/**
* Message::clear()
*
* Clears all fields of this message.
*/
PHP_METHOD(Message, clear) {
Message* intern = (Message*)Z_OBJ_P(getThis());
upb_msg_clear(intern->msg, intern->desc->msgdef);
}
/**
* Message::mergeFrom()
*
* Merges from the given message, which must be of the same class as us.
* @param object Message to merge from.
*/
PHP_METHOD(Message, mergeFrom) {
Message* intern = (Message*)Z_OBJ_P(getThis());
Message* from;
upb_arena *arena = Arena_Get(&intern->arena);
const upb_msglayout *l = upb_msgdef_layout(intern->desc->msgdef);
zval* value;
char *pb;
size_t size;
bool ok;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &value,
intern->desc->class_entry) == FAILURE) {
return;
}
from = (Message*)Z_OBJ_P(value);
// Should be guaranteed since we passed the class type to
// zend_parse_parameters().
PBPHP_ASSERT(from->desc == intern->desc);
// TODO(haberman): use a temp arena for this once we can make upb_decode()
// copy strings.
pb = upb_encode(from->msg, l, arena, &size);
if (!pb) {
zend_throw_exception_ex(NULL, 0, "Max nesting exceeded");
return;
}
ok = upb_decode(pb, size, intern->msg, l, arena);
PBPHP_ASSERT(ok);
}
/**
* Message::mergeFromString()
*
* Merges from the given string.
* @param string Binary protobuf data to merge.
*/
PHP_METHOD(Message, mergeFromString) {
Message* intern = (Message*)Z_OBJ_P(getThis());
char *data = NULL;
char *data_copy = NULL;
zend_long data_len;
const upb_msglayout *l = upb_msgdef_layout(intern->desc->msgdef);
upb_arena *arena = Arena_Get(&intern->arena);
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &data, &data_len) ==
FAILURE) {
return;
}
// TODO(haberman): avoid this copy when we can make the decoder copy.
data_copy = upb_arena_malloc(arena, data_len);
memcpy(data_copy, data, data_len);
if (!upb_decode(data_copy, data_len, intern->msg, l, arena)) {
zend_throw_exception_ex(NULL, 0, "Error occurred during parsing");
return;
}
}
/**
* Message::serializeToString()
*
* Serializes this message instance to protobuf data.
* @return string Serialized protobuf data.
*/
PHP_METHOD(Message, serializeToString) {
Message* intern = (Message*)Z_OBJ_P(getThis());
const upb_msglayout *l = upb_msgdef_layout(intern->desc->msgdef);
upb_arena *tmp_arena = upb_arena_new();
char *data;
size_t size;
data = upb_encode(intern->msg, l, tmp_arena, &size);
if (!data) {
zend_throw_exception_ex(NULL, 0, "Error occurred during serialization");
upb_arena_free(tmp_arena);
return;
}
RETVAL_STRINGL(data, size);
upb_arena_free(tmp_arena);
}
/**
* Message::mergeFromJsonString()
*
* Merges the JSON data parsed from the given string.
* @param string Serialized JSON data.
*/
PHP_METHOD(Message, mergeFromJsonString) {
Message* intern = (Message*)Z_OBJ_P(getThis());
char *data = NULL;
char *data_copy = NULL;
zend_long data_len;
upb_arena *arena = Arena_Get(&intern->arena);
upb_status status;
zend_bool ignore_json_unknown = false;
int options = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|b", &data, &data_len,
&ignore_json_unknown) == FAILURE) {
return;
}
// TODO(haberman): avoid this copy when we can make the decoder copy.
data_copy = upb_arena_malloc(arena, data_len + 1);
memcpy(data_copy, data, data_len);
data_copy[data_len] = '\0';
if (ignore_json_unknown) {
options |= UPB_JSONDEC_IGNOREUNKNOWN;
}
upb_status_clear(&status);
if (!upb_json_decode(data_copy, data_len, intern->msg, intern->desc->msgdef,
DescriptorPool_GetSymbolTable(), options, arena,
&status)) {
zend_throw_exception_ex(NULL, 0, "Error occurred during parsing: %s",
upb_status_errmsg(&status));
return;
}
}
/**
* Message::serializeToJsonString()
*
* Serializes this object to JSON.
* @return string Serialized JSON data.
*/
PHP_METHOD(Message, serializeToJsonString) {
Message* intern = (Message*)Z_OBJ_P(getThis());
size_t size;
int options = 0;
char buf[1024];
zend_bool preserve_proto_fieldnames = false;
upb_status status;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b",
&preserve_proto_fieldnames) == FAILURE) {
return;
}
if (preserve_proto_fieldnames) {
options |= UPB_JSONENC_PROTONAMES;
}
upb_status_clear(&status);
size = upb_json_encode(intern->msg, intern->desc->msgdef,
DescriptorPool_GetSymbolTable(), options, buf,
sizeof(buf), &status);
if (!upb_ok(&status)) {
zend_throw_exception_ex(NULL, 0,
"Error occurred during JSON serialization: %s",
upb_status_errmsg(&status));
return;
}
if (size >= sizeof(buf)) {
char *buf2 = malloc(size + 1);
upb_json_encode(intern->msg, intern->desc->msgdef,
DescriptorPool_GetSymbolTable(), options, buf2, size + 1,
&status);
RETVAL_STRINGL(buf2, size);
free(buf2);
} else {
RETVAL_STRINGL(buf, size);
}
}
/**
* Message::readWrapperValue()
*
* Returns an unboxed value for the given field. This is called from generated
* methods for wrapper fields, eg.
*
* public function getDoubleValueUnwrapped()
* {
* return $this->readWrapperValue("double_value");
* }
*
* @return Unwrapped field value or null.
*/
PHP_METHOD(Message, readWrapperValue) {
Message* intern = (Message*)Z_OBJ_P(getThis());
char* member;
const upb_fielddef *f;
zend_long size;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &member, &size) == FAILURE) {
return;
}
f = upb_msgdef_ntof(intern->desc->msgdef, member, size);
if (!f || !upb_msgdef_iswrapper(upb_fielddef_msgsubdef(f))) {
zend_throw_exception_ex(NULL, 0, "Message %s has no field %s",
upb_msgdef_fullname(intern->desc->msgdef), member);
return;
}
if (upb_msg_has(intern->msg, f)) {
const upb_msg *wrapper = upb_msg_get(intern->msg, f).msg_val;
const upb_msgdef *m = upb_fielddef_msgsubdef(f);
const upb_fielddef *val_f = upb_msgdef_itof(m, 1);
const upb_fieldtype_t val_type = upb_fielddef_type(val_f);
upb_msgval msgval = upb_msg_get(wrapper, val_f);
zval ret;
Convert_UpbToPhp(msgval, &ret, val_type, NULL, &intern->arena);
RETURN_ZVAL(&ret, 1, 0);
} else {
RETURN_NULL();
}
}
/**
* Message::writeWrapperValue()
*
* Sets the given wrapper field to the given unboxed value. This is called from
* generated methods for wrapper fields, eg.
*
*
* public function setDoubleValueUnwrapped($var)
* {
* $this->writeWrapperValue("double_value", $var);
* return $this;
* }
*
* @param Unwrapped field value or null.
*/
PHP_METHOD(Message, writeWrapperValue) {
Message* intern = (Message*)Z_OBJ_P(getThis());
upb_arena *arena = Arena_Get(&intern->arena);
char* member;
const upb_fielddef *f;
upb_msgval msgval;
zend_long size;
zval* val;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "sz", &member, &size, &val) ==
FAILURE) {
return;
}
f = upb_msgdef_ntof(intern->desc->msgdef, member, size);
if (!f || !upb_msgdef_iswrapper(upb_fielddef_msgsubdef(f))) {
zend_throw_exception_ex(NULL, 0, "Message %s has no field %s",
upb_msgdef_fullname(intern->desc->msgdef), member);
return;
}
if (Z_ISREF_P(val)) {
ZVAL_DEREF(val);
}
if (Z_TYPE_P(val) == IS_NULL) {
upb_msg_clearfield(intern->msg, f);
} else {
const upb_msgdef *m = upb_fielddef_msgsubdef(f);
const upb_fielddef *val_f = upb_msgdef_itof(m, 1);
upb_fieldtype_t val_type = upb_fielddef_type(val_f);
upb_msg *wrapper;
if (!Convert_PhpToUpb(val, &msgval, val_type, NULL, arena)) {
return; // Error is already set.
}
wrapper = upb_msg_mutable(intern->msg, f, arena).msg;
upb_msg_set(wrapper, val_f, msgval, arena);
}
}
/**
* Message::whichOneof()
*
* Given a oneof name, returns the name of the field that is set for this oneof,
* or otherwise the empty string.
*
* @return string The field name in this oneof that is currently set.
*/
PHP_METHOD(Message, whichOneof) {
Message* intern = (Message*)Z_OBJ_P(getThis());
const upb_oneofdef* oneof;
const upb_fielddef* field;
char* name;
zend_long len;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &len) == FAILURE) {
return;
}
oneof = upb_msgdef_ntoo(intern->desc->msgdef, name, len);
if (!oneof) {
zend_throw_exception_ex(NULL, 0, "Message %s has no oneof %s",
upb_msgdef_fullname(intern->desc->msgdef), name);
return;
}
field = upb_msg_whichoneof(intern->msg, oneof);
RETURN_STRING(field ? upb_fielddef_name(field) : "");
}
/**
* Message::readOneof()
*
* Returns the contents of the given oneof field, given a field number. Called
* from generated code methods such as:
*
* public function getDoubleValueOneof()
* {
* return $this->readOneof(10);
* }
*
* @return object The oneof's field value.
*/
PHP_METHOD(Message, readOneof) {
Message* intern = (Message*)Z_OBJ_P(getThis());
zend_long field_num;
const upb_fielddef* f;
zval ret;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &field_num) == FAILURE) {
return;
}
f = upb_msgdef_itof(intern->desc->msgdef, field_num);
if (!f || !upb_fielddef_realcontainingoneof(f)) {
php_error_docref(NULL, E_USER_ERROR,
"Internal error, no such oneof field %d\n",
(int)field_num);
}
{
upb_msgval msgval = upb_msg_get(intern->msg, f);
const Descriptor *subdesc = Descriptor_GetFromFieldDef(f);
Convert_UpbToPhp(msgval, &ret, upb_fielddef_type(f), subdesc,
&intern->arena);
}
RETURN_ZVAL(&ret, 1, 0);
}
/**
* Message::writeOneof()
*
* Sets the contents of the given oneof field, given a field number. Called
* from generated code methods such as:
*
* public function setDoubleValueOneof($var)
* {
* GPBUtil::checkMessage($var, \Google\Protobuf\DoubleValue::class);
* $this->writeOneof(10, $var);
*
* return $this;
* }
*
* The C extension version of GPBUtil::check*() does nothing, so we perform
* all type checking and conversion here.
*
* @param integer The field number we are setting.
* @param object The field value we want to set.
*/
PHP_METHOD(Message, writeOneof) {
Message* intern = (Message*)Z_OBJ_P(getThis());
zend_long field_num;
const upb_fielddef* f;
upb_arena *arena = Arena_Get(&intern->arena);
upb_msgval msgval;
zval* val;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "lz", &field_num, &val) ==
FAILURE) {
return;
}
f = upb_msgdef_itof(intern->desc->msgdef, field_num);
if (!Convert_PhpToUpb(val, &msgval, upb_fielddef_type(f),
Descriptor_GetFromFieldDef(f), arena)) {
return;
}
upb_msg_set(intern->msg, f, msgval, arena);
}
static zend_function_entry Message_methods[] = {
PHP_ME(Message, clear, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Message, discardUnknownFields, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Message, serializeToString, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Message, mergeFromString, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Message, serializeToJsonString, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Message, mergeFromJsonString, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Message, mergeFrom, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Message, readWrapperValue, NULL, ZEND_ACC_PROTECTED)
PHP_ME(Message, writeWrapperValue, NULL, ZEND_ACC_PROTECTED)
PHP_ME(Message, readOneof, NULL, ZEND_ACC_PROTECTED)
PHP_ME(Message, writeOneof, NULL, ZEND_ACC_PROTECTED)
PHP_ME(Message, whichOneof, NULL, ZEND_ACC_PROTECTED)
PHP_ME(Message, __construct, NULL, ZEND_ACC_PROTECTED)
ZEND_FE_END
};
/**
* Message_ModuleInit()
*
* Called when the C extension is loaded to register all types.
*/
void Message_ModuleInit() {
zend_class_entry tmp_ce;
zend_object_handlers *h = &message_object_handlers;
INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Internal\\Message",
Message_methods);
message_ce = zend_register_internal_class(&tmp_ce);
message_ce->create_object = Message_create;
memcpy(h, &std_object_handlers, sizeof(zend_object_handlers));
h->dtor_obj = Message_dtor;
h->read_property = Message_read_property;
h->write_property = Message_write_property;
h->get_properties = Message_get_properties;
h->get_property_ptr_ptr = Message_get_property_ptr_ptr;
}

@ -0,0 +1,59 @@
// 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.
#ifndef PHP_PROTOBUF_MESSAGE_H_
#define PHP_PROTOBUF_MESSAGE_H_
#include <stdbool.h>
#include "def.h"
// Registers the PHP Message class.
void Message_ModuleInit();
// Gets a upb_msg* for the PHP object |val|, which must either be a Message
// object or 'null'. Returns true and stores the message in |msg| if the
// conversion succeeded (we can't return upb_msg* because null->NULL is a valid
// conversion). Returns false and raises a PHP error if this isn't a Message
// object or null, or if the Message object doesn't match this Descriptor.
//
// The given |arena| will be fused to this message's arena.
bool Message_GetUpbMessage(zval *val, const Descriptor *desc, upb_arena *arena,
upb_msg **msg);
// Gets or creates a PHP Message object to wrap the given upb_msg* and |desc|
// and returns it in |val|. The PHP object will keep a reference to this |arena|
// to ensure the underlying message data stays alive.
//
// If |msg| is NULL, this will return a PHP null.
void Message_GetPhpWrapper(zval *val, const Descriptor *desc, upb_msg *msg,
zval *arena);
#endif // PHP_PROTOBUF_MESSAGE_H_

@ -0,0 +1,226 @@
// 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.
#include "names.h"
#include <stdlib.h>
#include "protobuf.h"
/* stringsink *****************************************************************/
typedef struct {
char *ptr;
size_t len, size;
} stringsink;
static size_t stringsink_string(stringsink *sink, const char *ptr, size_t len) {
size_t new_size = sink->size;
while (sink->len + len > new_size) {
new_size *= 2;
}
if (new_size != sink->size) {
sink->ptr = realloc(sink->ptr, new_size);
sink->size = new_size;
}
memcpy(sink->ptr + sink->len, ptr, len);
sink->len += len;
return len;
}
static void stringsink_init(stringsink *sink) {
sink->size = 32;
sink->ptr = malloc(sink->size);
PBPHP_ASSERT(sink->ptr != NULL);
sink->len = 0;
}
static void stringsink_uninit(stringsink *sink) { free(sink->ptr); }
/* def name -> classname ******************************************************/
const char *const kReservedNames[] = {
"abstract", "and", "array", "as", "break",
"callable", "case", "catch", "class", "clone",
"const", "continue", "declare", "default", "die",
"do", "echo", "else", "elseif", "empty",
"enddeclare", "endfor", "endforeach", "endif", "endswitch",
"endwhile", "eval", "exit", "extends", "final",
"for", "foreach", "function", "global", "goto",
"if", "implements", "include", "include_once", "instanceof",
"insteadof", "interface", "isset", "list", "namespace",
"new", "or", "print", "private", "protected",
"public", "require", "require_once", "return", "static",
"switch", "throw", "trait", "try", "unset",
"use", "var", "while", "xor", "int",
"float", "bool", "string", "true", "false",
"null", "void", "iterable", NULL};
bool is_reserved_name(const char* name) {
int i;
for (i = 0; kReservedNames[i]; i++) {
if (strcmp(kReservedNames[i], name) == 0) {
return true;
}
}
return false;
}
static char nolocale_tolower(char ch) {
if (ch >= 'A' && ch <= 'Z') {
return ch - ('A' - 'a');
} else {
return ch;
}
}
static char nolocale_toupper(char ch) {
if (ch >= 'a' && ch <= 'z') {
return ch - ('a' - 'A');
} else {
return ch;
}
}
static bool is_reserved(const char *segment, int length) {
bool result;
char* lower = calloc(1, length + 1);
memcpy(lower, segment, length);
int i = 0;
while(lower[i]) {
lower[i] = nolocale_tolower(lower[i]);
i++;
}
lower[length] = 0;
result = is_reserved_name(lower);
free(lower);
return result;
}
static void fill_prefix(const char *segment, int length,
const char *prefix_given,
const char *package_name,
stringsink *classname) {
if (prefix_given != NULL && strcmp(prefix_given, "") != 0) {
stringsink_string(classname, prefix_given, strlen(prefix_given));
} else {
if (is_reserved(segment, length)) {
if (package_name != NULL &&
strcmp("google.protobuf", package_name) == 0) {
stringsink_string(classname, "GPB", 3);
} else {
stringsink_string(classname, "PB", 2);
}
}
}
}
static void fill_segment(const char *segment, int length,
stringsink *classname, bool use_camel) {
if (use_camel && (segment[0] < 'A' || segment[0] > 'Z')) {
char first = nolocale_toupper(segment[0]);
stringsink_string(classname, &first, 1);
stringsink_string(classname, segment + 1, length - 1);
} else {
stringsink_string(classname, segment, length);
}
}
static void fill_namespace(const char *package, const char *php_namespace,
stringsink *classname) {
if (php_namespace != NULL) {
if (strlen(php_namespace) != 0) {
stringsink_string(classname, php_namespace, strlen(php_namespace));
stringsink_string(classname, "\\", 1);
}
} else if (package != NULL) {
int i = 0, j = 0;
size_t package_len = strlen(package);
while (i < package_len) {
j = i;
while (j < package_len && package[j] != '.') {
j++;
}
fill_prefix(package + i, j - i, "", package, classname);
fill_segment(package + i, j - i, classname, true);
stringsink_string(classname, "\\", 1);
i = j + 1;
}
}
}
static void fill_classname(const char *fullname,
const char *package,
const char *prefix,
stringsink *classname) {
int classname_start = 0;
if (package != NULL) {
size_t package_len = strlen(package);
classname_start = package_len == 0 ? 0 : package_len + 1;
}
size_t fullname_len = strlen(fullname);
int i = classname_start, j;
while (i < fullname_len) {
j = i;
while (j < fullname_len && fullname[j] != '.') {
j++;
}
fill_prefix(fullname + i, j - i, prefix, package, classname);
fill_segment(fullname + i, j - i, classname, false);
if (j != fullname_len) {
stringsink_string(classname, "\\", 1);
}
i = j + 1;
}
}
char *GetPhpClassname(const upb_filedef *file, const char *fullname) {
// Prepend '.' to package name to make it absolute. In the 5 additional
// bytes allocated, one for '.', one for trailing 0, and 3 for 'GPB' if
// given message is google.protobuf.Empty.
const char *package = upb_filedef_package(file);
const char *php_namespace = upb_filedef_phpnamespace(file);
const char *prefix = upb_filedef_phpprefix(file);
char *ret;
stringsink namesink;
stringsink_init(&namesink);
fill_namespace(package, php_namespace, &namesink);
fill_classname(fullname, package, prefix, &namesink);
stringsink_string(&namesink, "\0", 1);
ret = strdup(namesink.ptr);
stringsink_uninit(&namesink);
return ret;
}

@ -0,0 +1,40 @@
// 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.
#ifndef PHP_PROTOBUF_NAMES_H_
#define PHP_PROTOBUF_NAMES_H_
#include "php-upb.h"
// Translates a protobuf symbol name (eg. foo.bar.Baz) into a PHP class name
// (eg. \Foo\Bar\Baz).
char *GetPhpClassname(const upb_filedef *file, const char *fullname);
#endif // PHP_PROTOBUF_NAMES_H_

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,349 @@
// 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.
#include "protobuf.h"
#include <php.h>
#include <Zend/zend_interfaces.h>
#include "arena.h"
#include "array.h"
#include "bundled_php.h"
#include "convert.h"
#include "def.h"
#include "map.h"
#include "message.h"
#include "names.h"
// -----------------------------------------------------------------------------
// Module "globals"
// -----------------------------------------------------------------------------
// Despite the name, module "globals" are really thread-locals:
// * PROTOBUF_G(var) accesses the thread-local variable for 'var'. Either:
// * PROTOBUF_G(var) -> protobuf_globals.var (Non-ZTS / non-thread-safe)
// * PROTOBUF_G(var) -> <Zend magic> (ZTS / thread-safe builds)
#define PROTOBUF_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(protobuf, v)
ZEND_BEGIN_MODULE_GLOBALS(protobuf)
// Set by the user to make the descriptor pool persist between requests.
zend_bool keep_descriptor_pool_after_request;
// Currently we make the generated pool a "global", which means that if a user
// does explicitly create threads within their request, the other threads will
// get different results from DescriptorPool::getGeneratedPool(). We require
// that all descriptors are loaded from the main thread.
zval generated_pool;
// A upb_symtab that we are saving for the next request so that we don't have
// to rebuild it from scratch. When keep_descriptor_pool_after_request==true,
// we steal the upb_symtab from the global DescriptorPool object just before
// destroying it.
upb_symtab *saved_symtab;
// Object cache (see interface in protobuf.h).
HashTable object_cache;
// Name cache (see interface in protobuf.h).
HashTable name_msg_cache;
HashTable name_enum_cache;
ZEND_END_MODULE_GLOBALS(protobuf)
ZEND_DECLARE_MODULE_GLOBALS(protobuf)
const zval *get_generated_pool() {
return &PROTOBUF_G(generated_pool);
}
// This is a PHP extension (not a Zend extension). What follows is a summary of
// a PHP extension's lifetime and when various handlers are called.
//
// * PHP_GINIT_FUNCTION(protobuf) / PHP_GSHUTDOWN_FUNCTION(protobuf)
// are the constructor/destructor for the globals. The sequence over the
// course of a process lifetime is:
//
// # Process startup
// GINIT(<Main Thread Globals>)
// MINIT
//
// foreach request:
// RINIT
// # Request is processed here.
// RSHUTDOWN
//
// foreach thread:
// GINIT(<This Thread Globals>)
// # Code for the thread runs here.
// GSHUTDOWN(<This Thread Globals>)
//
// # Process Shutdown
// #
// # These should be running per the docs, but I have not been able to
// # actually get the process-wide shutdown functions to run.
// #
// # MSHUTDOWN
// # GSHUTDOWN(<Main Thread Globals>)
//
// * Threads can be created either explicitly by the user, inside a request,
// or implicitly by the runtime, to process multiple requests concurrently.
// If the latter is being used, then the "foreach thread" block above
// actually looks like this:
//
// foreach thread:
// GINIT(<This Thread Globals>)
// # A non-main thread will only receive requests when using a threaded
// # MPM with Apache
// foreach request:
// RINIT
// # Request is processed here.
// RSHUTDOWN
// GSHUTDOWN(<This Thread Globals>)
//
// That said, it appears that few people use threads with PHP:
// * The pthread package documented at
// https://www.php.net/manual/en/class.thread.php nas not been released
// since 2016, and the current release fails to compile against any PHP
// newer than 7.0.33.
// * The GitHub master branch supports 7.2+, but this has not been released
// to PECL.
// * Its owner has disavowed it as "broken by design" and "in an untenable
// position for the future": https://github.com/krakjoe/pthreads/issues/929
// * The only way to use PHP with requests in different threads is to use the
// Apache 2 mod_php with the "worker" MPM. But this is explicitly
// discouraged by the documentation: https://serverfault.com/a/231660
static PHP_GSHUTDOWN_FUNCTION(protobuf) {
if (protobuf_globals->saved_symtab) {
upb_symtab_free(protobuf_globals->saved_symtab);
}
}
static PHP_GINIT_FUNCTION(protobuf) {
ZVAL_NULL(&protobuf_globals->generated_pool);
protobuf_globals->saved_symtab = NULL;
}
/**
* PHP_RINIT_FUNCTION(protobuf)
*
* This function is run at the beginning of processing each request.
*/
static PHP_RINIT_FUNCTION(protobuf) {
// Create the global generated pool.
// Reuse the symtab (if any) left to us by the last request.
upb_symtab *symtab = PROTOBUF_G(saved_symtab);
DescriptorPool_CreateWithSymbolTable(&PROTOBUF_G(generated_pool), symtab);
// Set up autoloader for bundled sources.
zend_eval_string("spl_autoload_register('protobuf_internal_loadbundled');",
NULL, "autoload_register.php");
zend_hash_init(&PROTOBUF_G(object_cache), 64, NULL, NULL, 0);
zend_hash_init(&PROTOBUF_G(name_msg_cache), 64, NULL, NULL, 0);
zend_hash_init(&PROTOBUF_G(name_enum_cache), 64, NULL, NULL, 0);
return SUCCESS;
}
/**
* PHP_RSHUTDOWN_FUNCTION(protobuf)
*
* This function is run at the end of processing each request.
*/
static PHP_RSHUTDOWN_FUNCTION(protobuf) {
// Preserve the symtab if requested.
if (PROTOBUF_G(keep_descriptor_pool_after_request)) {
zval *zv = &PROTOBUF_G(generated_pool);
PROTOBUF_G(saved_symtab) = DescriptorPool_Steal(zv);
}
zval_dtor(&PROTOBUF_G(generated_pool));
zend_hash_destroy(&PROTOBUF_G(object_cache));
zend_hash_destroy(&PROTOBUF_G(name_msg_cache));
zend_hash_destroy(&PROTOBUF_G(name_enum_cache));
return SUCCESS;
}
// -----------------------------------------------------------------------------
// Bundled PHP sources
// -----------------------------------------------------------------------------
// We bundle PHP sources for well-known types into the C extension. There is no
// need to implement these in C.
static PHP_FUNCTION(protobuf_internal_loadbundled) {
char *name = NULL;
zend_long size;
BundledPhp_File *file;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &size) != SUCCESS) {
return;
}
for (file = bundled_files; file->filename; file++) {
if (strcmp(file->filename, name) == 0) {
zend_eval_string((char*)file->contents, NULL, (char*)file->filename);
return;
}
}
}
ZEND_BEGIN_ARG_INFO_EX(arginfo_load_bundled_source, 0, 0, 1)
ZEND_ARG_INFO(0, class_name)
ZEND_END_ARG_INFO()
// -----------------------------------------------------------------------------
// Object Cache.
// -----------------------------------------------------------------------------
void ObjCache_Add(const void *upb_obj, zend_object *php_obj) {
zend_ulong k = (zend_ulong)upb_obj;
zend_hash_index_add_ptr(&PROTOBUF_G(object_cache), k, php_obj);
}
void ObjCache_Delete(const void *upb_obj) {
if (upb_obj) {
zend_ulong k = (zend_ulong)upb_obj;
int ret = zend_hash_index_del(&PROTOBUF_G(object_cache), k);
PBPHP_ASSERT(ret == SUCCESS);
}
}
bool ObjCache_Get(const void *upb_obj, zval *val) {
zend_ulong k = (zend_ulong)upb_obj;
zend_object *obj = zend_hash_index_find_ptr(&PROTOBUF_G(object_cache), k);
if (obj) {
GC_ADDREF(obj);
ZVAL_OBJ(val, obj);
return true;
} else {
ZVAL_NULL(val);
return false;
}
}
// -----------------------------------------------------------------------------
// Name Cache.
// -----------------------------------------------------------------------------
void NameMap_AddMessage(const upb_msgdef *m) {
char *k = GetPhpClassname(upb_msgdef_file(m), upb_msgdef_fullname(m));
zend_hash_str_add_ptr(&PROTOBUF_G(name_msg_cache), k, strlen(k), (void*)m);
free(k);
}
void NameMap_AddEnum(const upb_enumdef *e) {
char *k = GetPhpClassname(upb_enumdef_file(e), upb_enumdef_fullname(e));
zend_hash_str_add_ptr(&PROTOBUF_G(name_enum_cache), k, strlen(k), (void*)e);
free(k);
}
const upb_msgdef *NameMap_GetMessage(zend_class_entry *ce) {
const upb_msgdef *ret =
zend_hash_find_ptr(&PROTOBUF_G(name_msg_cache), ce->name);
if (!ret && ce->create_object) {
zval tmp;
zval zv;
ZVAL_OBJ(&tmp, ce->create_object(ce));
zend_call_method_with_0_params(&tmp, ce, NULL, "__construct", &zv);
zval_ptr_dtor(&tmp);
zval_ptr_dtor(&zv);
ret = zend_hash_find_ptr(&PROTOBUF_G(name_msg_cache), ce->name);
}
return ret;
}
const upb_enumdef *NameMap_GetEnum(zend_class_entry *ce) {
const upb_enumdef *ret =
zend_hash_find_ptr(&PROTOBUF_G(name_enum_cache), ce->name);
return ret;
}
// -----------------------------------------------------------------------------
// Module init.
// -----------------------------------------------------------------------------
zend_function_entry protobuf_functions[] = {
PHP_FE(protobuf_internal_loadbundled, arginfo_load_bundled_source)
ZEND_FE_END
};
static const zend_module_dep protobuf_deps[] = {
ZEND_MOD_OPTIONAL("date")
ZEND_MOD_END
};
PHP_INI_BEGIN()
STD_PHP_INI_ENTRY("protobuf.keep_descriptor_pool_after_request", "0",
PHP_INI_SYSTEM, OnUpdateBool,
keep_descriptor_pool_after_request, zend_protobuf_globals,
protobuf_globals)
PHP_INI_END()
static PHP_MINIT_FUNCTION(protobuf) {
REGISTER_INI_ENTRIES();
Arena_ModuleInit();
Array_ModuleInit();
Convert_ModuleInit();
Def_ModuleInit();
Map_ModuleInit();
Message_ModuleInit();
return SUCCESS;
}
static PHP_MSHUTDOWN_FUNCTION(protobuf) {
return SUCCESS;
}
zend_module_entry protobuf_module_entry = {
STANDARD_MODULE_HEADER_EX,
NULL,
protobuf_deps,
"protobuf", // extension name
protobuf_functions, // function list
PHP_MINIT(protobuf), // process startup
PHP_MSHUTDOWN(protobuf), // process shutdown
PHP_RINIT(protobuf), // request shutdown
PHP_RSHUTDOWN(protobuf), // request shutdown
NULL, // extension info
"3.13.0", // extension version
PHP_MODULE_GLOBALS(protobuf), // globals descriptor
PHP_GINIT(protobuf), // globals ctor
PHP_GSHUTDOWN(protobuf), // globals dtor
NULL, // post deactivate
STANDARD_MODULE_PROPERTIES_EX
};
ZEND_GET_MODULE(protobuf)

@ -0,0 +1,89 @@
// 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.
#ifndef PHP_PROTOBUF_H_
#define PHP_PROTOBUF_H_
#include <php.h>
#include <stdbool.h>
#include "php-upb.h"
const zval *get_generated_pool();
#if PHP_VERSION_ID < 70300
#define GC_ADDREF(h) ++GC_REFCOUNT(h)
#define GC_DELREF(h) --GC_REFCOUNT(h)
#endif
// ptr -> PHP object cache. This is a weak map that caches lazily-created
// wrapper objects around upb types:
// * upb_msg* -> Message
// * upb_array* -> RepeatedField
// * upb_map*, -> MapField
// * upb_msgdef* -> Descriptor
// * upb_enumdef* -> EnumDescriptor
// * zend_class_entry* -> Descriptor
//
// Each wrapped object should add itself to the map when it is constructed, and
// remove itself from the map when it is destroyed. This is how we ensure that
// the map only contains live objects. The map is weak so it does not actually
// take references to the cached objects.
void ObjCache_Add(const void *key, zend_object *php_obj);
void ObjCache_Delete(const void *key);
bool ObjCache_Get(const void *key, zval *val);
// PHP class name map. This is necessary because the pb_name->php_class_name
// transformation is non-reversible, so when we need to look up a msgdef or
// enumdef by PHP class, we can't turn the class name into a pb_name.
// * php_class_name -> upb_msgdef*
// * php_class_name -> upb_enumdef*
void NameMap_AddMessage(const upb_msgdef *m);
void NameMap_AddEnum(const upb_enumdef *m);
const upb_msgdef *NameMap_GetMessage(zend_class_entry *ce);
const upb_enumdef *NameMap_GetEnum(zend_class_entry *ce);
// We need our own assert() because PHP takes control of NDEBUG in its headers.
#ifdef PBPHP_ENABLE_ASSERTS
#define PBPHP_ASSERT(x) \
do { \
if (!(x)) { \
fprintf(stderr, "Assertion failure at %s:%d %s", __FILE__, __LINE__, \
#x); \
abort(); \
} \
} while (false)
#else
#define PBPHP_ASSERT(x) \
do { \
} while (false && (x))
#endif
#endif // PHP_PROTOBUF_H_

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

Loading…
Cancel
Save