ADD: added new version of protobuf
This commit is contained in:
@@ -14,7 +14,4 @@ tab_width = 4
|
||||
# New line preferences
|
||||
end_of_line = lf
|
||||
insert_final_newline = false
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.cs]
|
||||
csharp_space_after_cast = true
|
||||
trim_trailing_whitespace = true
|
||||
1
libs/protobuf/csharp/.gitignore
vendored
1
libs/protobuf/csharp/.gitignore
vendored
@@ -18,7 +18,6 @@ lib/NUnit
|
||||
# Untracked files
|
||||
#
|
||||
.vs
|
||||
.cr
|
||||
*.user
|
||||
*.suo
|
||||
*.nupkg
|
||||
|
||||
@@ -3,87 +3,14 @@
|
||||
# See also code generation logic under /src/google/protobuf/compiler/csharp.
|
||||
|
||||
load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix")
|
||||
load("//:protobuf.bzl", "internal_csharp_proto_library")
|
||||
load("//build_defs:internal_shell.bzl", "inline_sh_test")
|
||||
load("//conformance:defs.bzl", "conformance_test")
|
||||
|
||||
################################################################################
|
||||
# Tests
|
||||
################################################################################
|
||||
|
||||
conformance_test(
|
||||
name = "conformance_test",
|
||||
failure_list = "//conformance:failure_list_csharp.txt",
|
||||
testee = "//conformance:conformance_csharp",
|
||||
text_format_failure_list = "//conformance:text_format_failure_list_csharp.txt",
|
||||
)
|
||||
|
||||
################################################################################
|
||||
# CSharp Runtime
|
||||
################################################################################
|
||||
|
||||
filegroup(
|
||||
name = "srcs",
|
||||
pkg_files(
|
||||
name = "dist_files",
|
||||
srcs = glob([
|
||||
"keys/*",
|
||||
"protos/*",
|
||||
"src/**/*.cs*", # .cs and .csproj
|
||||
], exclude = [
|
||||
# Exclude generated files.
|
||||
"src/*/obj/**/*"
|
||||
]) + [
|
||||
"src/Directory.Build.props",
|
||||
"src/Google.Protobuf.Test/testprotos.pb",
|
||||
"src/Google.Protobuf.sln",
|
||||
],
|
||||
visibility = [
|
||||
"//csharp:__subpackages__",
|
||||
"//conformance:__subpackages__"
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "wkt_cs_srcs",
|
||||
srcs = [
|
||||
"src/Google.Protobuf/Reflection/Descriptor.cs",
|
||||
"src/Google.Protobuf/WellKnownTypes/Any.cs",
|
||||
"src/Google.Protobuf/WellKnownTypes/Api.cs",
|
||||
"src/Google.Protobuf/WellKnownTypes/Duration.cs",
|
||||
"src/Google.Protobuf/WellKnownTypes/Empty.cs",
|
||||
"src/Google.Protobuf/WellKnownTypes/FieldMask.cs",
|
||||
"src/Google.Protobuf/WellKnownTypes/SourceContext.cs",
|
||||
"src/Google.Protobuf/WellKnownTypes/Struct.cs",
|
||||
"src/Google.Protobuf/WellKnownTypes/Timestamp.cs",
|
||||
"src/Google.Protobuf/WellKnownTypes/Type.cs",
|
||||
"src/Google.Protobuf/WellKnownTypes/Wrappers.cs",
|
||||
],
|
||||
visibility = ["//src/google/protobuf/compiler/csharp:__pkg__"],
|
||||
)
|
||||
|
||||
inline_sh_test(
|
||||
name = "tests",
|
||||
srcs = [
|
||||
":srcs",
|
||||
"src/Google.Protobuf.sln",
|
||||
"//csharp/src/Google.Protobuf.Conformance:srcs",
|
||||
],
|
||||
cmd = """
|
||||
pushd `dirname $(location src/Google.Protobuf.sln)`/..
|
||||
dotnet restore src/Google.Protobuf.sln
|
||||
dotnet build -c Release src/Google.Protobuf.sln
|
||||
dotnet test -c Release -f netcoreapp3.1 src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
|
||||
popd
|
||||
""",
|
||||
)
|
||||
|
||||
################################################################################
|
||||
# Distribution files
|
||||
################################################################################
|
||||
|
||||
pkg_files(
|
||||
name = "dist_files",
|
||||
srcs = [
|
||||
":srcs",
|
||||
".editorconfig",
|
||||
".gitignore",
|
||||
"BUILD.bazel",
|
||||
@@ -93,20 +20,15 @@ pkg_files(
|
||||
"NuGet.Config",
|
||||
"README.md",
|
||||
"build_packages.bat",
|
||||
"build_release.sh",
|
||||
"build_tools.sh",
|
||||
"buildall.bat",
|
||||
"buildall.sh",
|
||||
"generate_protos.sh",
|
||||
"install_dotnet_sdk.ps1",
|
||||
"//csharp/src/Google.Protobuf.Conformance:dist_files",
|
||||
"src/Google.Protobuf.Benchmarks/wrapper_benchmark_messages.proto",
|
||||
"src/Google.Protobuf.Test/testprotos.pb",
|
||||
"src/Google.Protobuf.sln",
|
||||
],
|
||||
strip_prefix = strip_prefix.from_root(""),
|
||||
visibility = ["//pkg:__pkg__"],
|
||||
)
|
||||
|
||||
sh_binary(
|
||||
name = "release",
|
||||
srcs = ["build_release.sh"],
|
||||
args = ["$(location build_release.sh)"],
|
||||
)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<title>Google Protocol Buffers tools</title>
|
||||
<summary>Tools for Protocol Buffers - Google's data interchange format.</summary>
|
||||
<description>See project site for more info.</description>
|
||||
<version>3.21.8</version>
|
||||
<version>3.21.12</version>
|
||||
<authors>Google Inc.</authors>
|
||||
<owners>protobuf-packages</owners>
|
||||
<licenseUrl>https://github.com/protocolbuffers/protobuf/blob/main/LICENSE</licenseUrl>
|
||||
|
||||
@@ -16,32 +16,36 @@ To generate C# files from your `.proto` files, invoke `protoc` with the
|
||||
Supported platforms
|
||||
===================
|
||||
|
||||
The runtime library is built as a class library, supporting targets of:
|
||||
The runtime library is built as a portable class library, supporting:
|
||||
|
||||
- .NET 4.5+ (`net45`)
|
||||
- .NET Standard 1.1 and 2.0 (`netstandard1.1` and `netstandard2.0`)
|
||||
- .NET 5+ (`net50`)
|
||||
- .NET 4.5
|
||||
- Windows 8
|
||||
- Windows Phone Silverlight 8
|
||||
- Windows Phone 8.1
|
||||
- .NET Core
|
||||
|
||||
You should be able to use Protocol Buffers in Visual Studio 2012 and
|
||||
all later versions. This includes all code generated by `protoc`,
|
||||
which only uses features from C# 3 and earlier. When compiling generated
|
||||
code with old compilers (before C# 7.2) you need to define the
|
||||
`GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE` symbol in your project
|
||||
so that the generated classes don't implement `IBufferMessage`, which uses
|
||||
`ref struct` types.
|
||||
which only uses features from C# 3 and earlier.
|
||||
|
||||
Building
|
||||
========
|
||||
|
||||
Open the `src/Google.Protobuf.sln` solution in Visual Studio 2022 or
|
||||
Open the `src/Google.Protobuf.sln` solution in Visual Studio 2017 or
|
||||
later.
|
||||
|
||||
Although *users* of this project are only expected to have Visual
|
||||
Studio 2012 or later, *developers* of the library are required to
|
||||
have Visual Studio 2022 or later, as the library uses C# 10 features
|
||||
in its implementation and runs tests under .NET 6. These features
|
||||
have no impact when using the compiled code - they're only relevant
|
||||
when building the `Google.Protobuf` assembly.
|
||||
have Visual Studio 2017 or later, as the library uses C# 6 features
|
||||
in its implementation, as well as the new Visual Studio 2017 csproj
|
||||
format. These features have no impact when using the compiled code -
|
||||
they're only relevant when building the `Google.Protobuf` assembly.
|
||||
|
||||
In order to run and debug the AddressBook example in the IDE, you must
|
||||
install the optional component, ".Net Core 1.0 - 1.1 development tools
|
||||
for Web" (as it's labelled in current versions of the VS2017
|
||||
installer), above and beyond the main .NET Core cross-platform
|
||||
development feature.
|
||||
|
||||
Testing
|
||||
=======
|
||||
@@ -52,11 +56,20 @@ run using the Visual Studio Test Explorer or `dotnet test`.
|
||||
.NET 3.5
|
||||
========
|
||||
|
||||
We don't support .NET 3.5. It *used* to be feasible to build this library
|
||||
targeting .NET 3.5, but a number of changes requiring newer runtime/framework
|
||||
features have been added over time. While it would no doubt be *possible* to
|
||||
rework the current implementation to allow most of the functionality to be built
|
||||
in .NET 3.5, this would create an undue maintenance burden.
|
||||
We don't officially support .NET 3.5. However, there has been some effort
|
||||
to make enabling .NET 3.5 support relatively painless in case you require it.
|
||||
There's no guarantee that this will continue in the future, so rely on .NET
|
||||
3.5 support at your peril.
|
||||
|
||||
To enable .NET 3.5 support, you must edit the `TargetFrameworks` elements of
|
||||
[src/Google.Protobuf/Google.Protobuf.csproj](src/Google.Protobuf/Google.Protobuf.csproj)
|
||||
(and [src/Google.Protobuf.Test/Google.Protobuf.Test.csproj](src/Google.Protobuf.Test/Google.Protobuf.Test.csproj)
|
||||
if you want to run the unit tests):
|
||||
|
||||
Open the .csproj file in a text editor and simply add `net35` to the list of
|
||||
target frameworks, noting that the `TargetFrameworks` element appears twice in
|
||||
the file (once in the first `PropertyGroup` element, and again in the second
|
||||
`PropertyGroup` element, i.e., the one with the conditional).
|
||||
|
||||
History of C# protobufs
|
||||
=======================
|
||||
@@ -68,9 +81,9 @@ and maintained by Google. All the development will be done in open, under this r
|
||||
|
||||
The previous project differs from this project in a number of ways:
|
||||
|
||||
- The old code only supported proto2; the new code initially only supported
|
||||
- The old code only supported proto2; the new code only supports
|
||||
proto3 (so no unknown fields, no required/optional distinction, no
|
||||
extensions); since then proto2 support has been added
|
||||
extensions)
|
||||
- The old code was based on immutable message types and builders for
|
||||
them
|
||||
- The old code did not support maps or `oneof`
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd $(dirname $(readlink $BASH_SOURCE))
|
||||
|
||||
# Disable some unwanted dotnet options
|
||||
set DOTNET_SKIP_FIRST_TIME_EXPERIENCE=true
|
||||
set DOTNET_CLI_TELEMETRY_OPTOUT=true
|
||||
|
||||
# Builds Google.Protobuf NuGet packages
|
||||
dotnet restore -s /lib/csharp/ src/Google.Protobuf/Google.Protobuf.csproj
|
||||
dotnet pack --no-restore -c Release src/Google.Protobuf.sln -p:ContinuousIntegrationBuild=true
|
||||
@@ -1,16 +0,0 @@
|
||||
load("//build_defs:internal_shell.bzl", "inline_sh_test")
|
||||
|
||||
# Run csharp compatibility test between 3.0.0 and the current version.
|
||||
inline_sh_test(
|
||||
name = "tests",
|
||||
srcs = ["test.sh"],
|
||||
tools = ["//:protoc"],
|
||||
deps = glob([
|
||||
"src/**/*.cs*", # .cs and .csproj
|
||||
"protos/**/*.proto",
|
||||
]) + [
|
||||
"//csharp:srcs",
|
||||
"//:well_known_protos",
|
||||
],
|
||||
cmd = "$(location test.sh) 3.0.0 $(rootpath //:protoc)"
|
||||
)
|
||||
@@ -6,7 +6,6 @@
|
||||
<AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<IsPackable>False</IsPackable>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -27,8 +27,6 @@ function run_test() {
|
||||
|
||||
set -ex
|
||||
|
||||
PROTOC=$(realpath ${2:-../../../bazel-bin/protoc})
|
||||
|
||||
# Change to the script's directory.
|
||||
cd $(dirname $0)
|
||||
|
||||
@@ -47,7 +45,7 @@ OLD_VERSION_PROTOC=https://repo1.maven.org/maven2/com/google/protobuf/protoc/$OL
|
||||
echo "Running compatibility tests with $OLD_VERSION"
|
||||
|
||||
# Check protoc
|
||||
[ -f $PROTOC ] || {
|
||||
[ -f ../../../src/protoc ] || {
|
||||
echo "[ERROR]: Please build protoc first."
|
||||
exit 1
|
||||
}
|
||||
@@ -70,12 +68,12 @@ run_test "./old_protoc" "./old_protoc"
|
||||
# Test A.2:
|
||||
# proto set 1: use new version
|
||||
# proto set 2 which may import protos in set 1: use old version
|
||||
run_test "$PROTOC" "./old_protoc"
|
||||
run_test "../../../src/protoc" "./old_protoc"
|
||||
|
||||
# Test A.3:
|
||||
# proto set 1: use old version
|
||||
# proto set 2 which may import protos in set 1: use new version
|
||||
run_test "./old_protoc" "$PROTOC"
|
||||
run_test "./old_protoc" "../../../src/protoc"
|
||||
|
||||
rm old_protoc
|
||||
rm keys -r
|
||||
|
||||
@@ -11,19 +11,17 @@ pushd $(dirname $0)/..
|
||||
# Protocol buffer compiler to use. If the PROTOC variable is set,
|
||||
# use that. Otherwise, probe for expected locations under both
|
||||
# Windows and Unix.
|
||||
PROTOC_LOCATIONS=(
|
||||
"bazel-bin/protoc"
|
||||
"solution/Debug/protoc.exe"
|
||||
"cmake/build/Debug/protoc.exe"
|
||||
"cmake/build/Release/protoc.exe"
|
||||
)
|
||||
if [ -z "$PROTOC" ]; then
|
||||
for protoc in "${PROTOC_LOCATIONS[@]}"; do
|
||||
if [ -x "$protoc" ]; then
|
||||
PROTOC="$protoc"
|
||||
fi
|
||||
done
|
||||
if [ -z "$PROTOC" ]; then
|
||||
# TODO(jonskeet): Use an array and a for loop instead?
|
||||
if [ -x solution/Debug/protoc.exe ]; then
|
||||
PROTOC=solution/Debug/protoc.exe
|
||||
elif [ -x cmake/build/Debug/protoc.exe ]; then
|
||||
PROTOC=cmake/build/Debug/protoc.exe
|
||||
elif [ -x cmake/build/Release/protoc.exe ]; then
|
||||
PROTOC=cmake/build/Release/protoc.exe
|
||||
elif [ -x src/protoc ]; then
|
||||
PROTOC=src/protoc
|
||||
else
|
||||
echo "Unable to find protocol buffer compiler."
|
||||
exit 1
|
||||
fi
|
||||
@@ -42,8 +40,7 @@ $PROTOC -Isrc --csharp_out=csharp/src/Google.Protobuf \
|
||||
src/google/protobuf/struct.proto \
|
||||
src/google/protobuf/timestamp.proto \
|
||||
src/google/protobuf/type.proto \
|
||||
src/google/protobuf/wrappers.proto \
|
||||
src/google/protobuf/compiler/plugin.proto
|
||||
src/google/protobuf/wrappers.proto
|
||||
|
||||
# Test protos
|
||||
# Note that this deliberately does *not* include old_extensions1.proto
|
||||
@@ -76,3 +73,17 @@ $PROTOC -Isrc -Icsharp/protos \
|
||||
# AddressBook sample protos
|
||||
$PROTOC -Iexamples -Isrc --csharp_out=csharp/src/AddressBook \
|
||||
examples/addressbook.proto
|
||||
|
||||
$PROTOC -Iconformance -Isrc --csharp_out=csharp/src/Google.Protobuf.Conformance \
|
||||
conformance/conformance.proto
|
||||
|
||||
# Benchmark protos
|
||||
$PROTOC -Ibenchmarks \
|
||||
benchmarks/datasets/google_message1/proto3/*.proto \
|
||||
benchmarks/benchmarks.proto \
|
||||
--csharp_out=csharp/src/Google.Protobuf.Benchmarks
|
||||
|
||||
# C# only benchmark protos
|
||||
$PROTOC -Isrc -Icsharp/src/Google.Protobuf.Benchmarks \
|
||||
csharp/src/Google.Protobuf.Benchmarks/*.proto \
|
||||
--csharp_out=csharp/src/Google.Protobuf.Benchmarks
|
||||
|
||||
@@ -59,12 +59,10 @@ message NegativeEnumMessage {
|
||||
// Decorate fields with [deprecated=true] as [System.Obsolete]
|
||||
|
||||
message DeprecatedChild {
|
||||
option deprecated = true;
|
||||
}
|
||||
|
||||
enum DeprecatedEnum {
|
||||
option deprecated = true;
|
||||
DEPRECATED_ZERO = 0 [deprecated = true];
|
||||
DEPRECATED_ZERO = 0;
|
||||
one = 1;
|
||||
}
|
||||
|
||||
@@ -171,20 +169,4 @@ message OneofWithNoneName {
|
||||
string x = 1;
|
||||
string y = 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Issue 8810
|
||||
message DisambiguateCommonMembers {
|
||||
int32 disambiguate_common_members = 1;
|
||||
int32 types = 2;
|
||||
int32 descriptor = 3;
|
||||
int32 equals = 4;
|
||||
int32 to_string = 5;
|
||||
int32 get_hash_code = 6;
|
||||
int32 write_to = 7;
|
||||
int32 clone = 8;
|
||||
int32 calculate_size = 9;
|
||||
int32 merge_from = 10;
|
||||
int32 on_construction = 11;
|
||||
int32 parser = 12;
|
||||
}
|
||||
}
|
||||
@@ -107,8 +107,10 @@ namespace Google.Protobuf.Examples.AddressBook
|
||||
|
||||
if (File.Exists(args[0]))
|
||||
{
|
||||
using Stream file = File.OpenRead(args[0]);
|
||||
addressBook = AddressBook.Parser.ParseFrom(file);
|
||||
using (Stream file = File.OpenRead(args[0]))
|
||||
{
|
||||
addressBook = AddressBook.Parser.ParseFrom(file);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
<Project>
|
||||
|
||||
<PropertyGroup>
|
||||
<LangVersion>10.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,89 @@
|
||||
#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 Benchmarks;
|
||||
using Google.Protobuf.Reflection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Google.Protobuf.Benchmarks
|
||||
{
|
||||
/// <summary>
|
||||
/// The configuration for a single serialization test, loaded from a dataset.
|
||||
/// </summary>
|
||||
public class BenchmarkDatasetConfig
|
||||
{
|
||||
private static readonly Dictionary<string, MessageParser> parsersByMessageName =
|
||||
typeof(GoogleMessageBenchmark).Assembly.GetTypes()
|
||||
.Where(t => typeof(IMessage).IsAssignableFrom(t))
|
||||
.ToDictionary(
|
||||
t => ((MessageDescriptor) t.GetProperty("Descriptor", BindingFlags.Static | BindingFlags.Public).GetValue(null)).FullName,
|
||||
t => ((MessageParser) t.GetProperty("Parser", BindingFlags.Static | BindingFlags.Public).GetValue(null)));
|
||||
|
||||
public MessageParser Parser { get; }
|
||||
public List<byte[]> Payloads { get; }
|
||||
public string Name { get; }
|
||||
|
||||
public BenchmarkDatasetConfig(string resource, string shortName = null)
|
||||
{
|
||||
var data = LoadData(resource);
|
||||
var dataset = BenchmarkDataset.Parser.ParseFrom(data);
|
||||
|
||||
if (!parsersByMessageName.TryGetValue(dataset.MessageName, out var parser))
|
||||
{
|
||||
throw new ArgumentException($"No parser for message {dataset.MessageName} in this assembly");
|
||||
}
|
||||
Parser = parser;
|
||||
Payloads = new List<byte[]>(dataset.Payload.Select(p => p.ToByteArray()));
|
||||
Name = shortName ?? dataset.Name;
|
||||
}
|
||||
|
||||
private static byte[] LoadData(string resource)
|
||||
{
|
||||
using (var stream = typeof(GoogleMessageBenchmark).Assembly.GetManifestResourceStream($"Google.Protobuf.Benchmarks.{resource}"))
|
||||
{
|
||||
if (stream == null)
|
||||
{
|
||||
throw new ArgumentException($"Unable to load embedded resource {resource}");
|
||||
}
|
||||
var copy = new MemoryStream();
|
||||
stream.CopyTo(copy);
|
||||
return copy.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString() => Name;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,325 @@
|
||||
// <auto-generated>
|
||||
// Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
// source: benchmarks.proto
|
||||
// </auto-generated>
|
||||
#pragma warning disable 1591, 0612, 3021, 8981
|
||||
#region Designer generated code
|
||||
|
||||
using pb = global::Google.Protobuf;
|
||||
using pbc = global::Google.Protobuf.Collections;
|
||||
using pbr = global::Google.Protobuf.Reflection;
|
||||
using scg = global::System.Collections.Generic;
|
||||
namespace Benchmarks {
|
||||
|
||||
/// <summary>Holder for reflection information generated from benchmarks.proto</summary>
|
||||
public static partial class BenchmarksReflection {
|
||||
|
||||
#region Descriptor
|
||||
/// <summary>File descriptor for benchmarks.proto</summary>
|
||||
public static pbr::FileDescriptor Descriptor {
|
||||
get { return descriptor; }
|
||||
}
|
||||
private static pbr::FileDescriptor descriptor;
|
||||
|
||||
static BenchmarksReflection() {
|
||||
byte[] descriptorData = global::System.Convert.FromBase64String(
|
||||
string.Concat(
|
||||
"ChBiZW5jaG1hcmtzLnByb3RvEgpiZW5jaG1hcmtzIkcKEEJlbmNobWFya0Rh",
|
||||
"dGFzZXQSDAoEbmFtZRgBIAEoCRIUCgxtZXNzYWdlX25hbWUYAiABKAkSDwoH",
|
||||
"cGF5bG9hZBgDIAMoDEIgCh5jb20uZ29vZ2xlLnByb3RvYnVmLmJlbmNobWFy",
|
||||
"a3NiBnByb3RvMw=="));
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::Benchmarks.BenchmarkDataset), global::Benchmarks.BenchmarkDataset.Parser, new[]{ "Name", "MessageName", "Payload" }, null, null, null, null)
|
||||
}));
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
#region Messages
|
||||
public sealed partial class BenchmarkDataset : pb::IMessage<BenchmarkDataset>
|
||||
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
|
||||
, pb::IBufferMessage
|
||||
#endif
|
||||
{
|
||||
private static readonly pb::MessageParser<BenchmarkDataset> _parser = new pb::MessageParser<BenchmarkDataset>(() => new BenchmarkDataset());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public static pb::MessageParser<BenchmarkDataset> Parser { get { return _parser; } }
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public static pbr::MessageDescriptor Descriptor {
|
||||
get { return global::Benchmarks.BenchmarksReflection.Descriptor.MessageTypes[0]; }
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
pbr::MessageDescriptor pb::IMessage.Descriptor {
|
||||
get { return Descriptor; }
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public BenchmarkDataset() {
|
||||
OnConstruction();
|
||||
}
|
||||
|
||||
partial void OnConstruction();
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public BenchmarkDataset(BenchmarkDataset other) : this() {
|
||||
name_ = other.name_;
|
||||
messageName_ = other.messageName_;
|
||||
payload_ = other.payload_.Clone();
|
||||
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public BenchmarkDataset Clone() {
|
||||
return new BenchmarkDataset(this);
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "name" field.</summary>
|
||||
public const int NameFieldNumber = 1;
|
||||
private string name_ = "";
|
||||
/// <summary>
|
||||
/// Name of the benchmark dataset. This should be unique across all datasets.
|
||||
/// Should only contain word characters: [a-zA-Z0-9_]
|
||||
/// </summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public string Name {
|
||||
get { return name_; }
|
||||
set {
|
||||
name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "message_name" field.</summary>
|
||||
public const int MessageNameFieldNumber = 2;
|
||||
private string messageName_ = "";
|
||||
/// <summary>
|
||||
/// Fully-qualified name of the protobuf message for this dataset.
|
||||
/// It will be one of the messages defined benchmark_messages_proto2.proto
|
||||
/// or benchmark_messages_proto3.proto.
|
||||
///
|
||||
/// Implementations that do not support reflection can implement this with
|
||||
/// an explicit "if/else" chain that lists every known message defined
|
||||
/// in those files.
|
||||
/// </summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public string MessageName {
|
||||
get { return messageName_; }
|
||||
set {
|
||||
messageName_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "payload" field.</summary>
|
||||
public const int PayloadFieldNumber = 3;
|
||||
private static readonly pb::FieldCodec<pb::ByteString> _repeated_payload_codec
|
||||
= pb::FieldCodec.ForBytes(26);
|
||||
private readonly pbc::RepeatedField<pb::ByteString> payload_ = new pbc::RepeatedField<pb::ByteString>();
|
||||
/// <summary>
|
||||
/// The payload(s) for this dataset. They should be parsed or serialized
|
||||
/// in sequence, in a loop, ie.
|
||||
///
|
||||
/// while (!benchmarkDone) { // Benchmark runner decides when to exit.
|
||||
/// for (i = 0; i < benchmark.payload.length; i++) {
|
||||
/// parse(benchmark.payload[i])
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// This is intended to let datasets include a variety of data to provide
|
||||
/// potentially more realistic results than just parsing the same message
|
||||
/// over and over. A single message parsed repeatedly could yield unusually
|
||||
/// good branch prediction performance.
|
||||
/// </summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public pbc::RepeatedField<pb::ByteString> Payload {
|
||||
get { return payload_; }
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public override bool Equals(object other) {
|
||||
return Equals(other as BenchmarkDataset);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public bool Equals(BenchmarkDataset other) {
|
||||
if (ReferenceEquals(other, null)) {
|
||||
return false;
|
||||
}
|
||||
if (ReferenceEquals(other, this)) {
|
||||
return true;
|
||||
}
|
||||
if (Name != other.Name) return false;
|
||||
if (MessageName != other.MessageName) return false;
|
||||
if(!payload_.Equals(other.payload_)) return false;
|
||||
return Equals(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public override int GetHashCode() {
|
||||
int hash = 1;
|
||||
if (Name.Length != 0) hash ^= Name.GetHashCode();
|
||||
if (MessageName.Length != 0) hash ^= MessageName.GetHashCode();
|
||||
hash ^= payload_.GetHashCode();
|
||||
if (_unknownFields != null) {
|
||||
hash ^= _unknownFields.GetHashCode();
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public override string ToString() {
|
||||
return pb::JsonFormatter.ToDiagnosticString(this);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
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);
|
||||
}
|
||||
if (MessageName.Length != 0) {
|
||||
output.WriteRawTag(18);
|
||||
output.WriteString(MessageName);
|
||||
}
|
||||
payload_.WriteTo(output, _repeated_payload_codec);
|
||||
if (_unknownFields != null) {
|
||||
_unknownFields.WriteTo(output);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
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]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public int CalculateSize() {
|
||||
int size = 0;
|
||||
if (Name.Length != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
|
||||
}
|
||||
if (MessageName.Length != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeStringSize(MessageName);
|
||||
}
|
||||
size += payload_.CalculateSize(_repeated_payload_codec);
|
||||
if (_unknownFields != null) {
|
||||
size += _unknownFields.CalculateSize();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public void MergeFrom(BenchmarkDataset other) {
|
||||
if (other == null) {
|
||||
return;
|
||||
}
|
||||
if (other.Name.Length != 0) {
|
||||
Name = other.Name;
|
||||
}
|
||||
if (other.MessageName.Length != 0) {
|
||||
MessageName = other.MessageName;
|
||||
}
|
||||
payload_.Add(other.payload_);
|
||||
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
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: {
|
||||
Name = input.ReadString();
|
||||
break;
|
||||
}
|
||||
case 18: {
|
||||
MessageName = input.ReadString();
|
||||
break;
|
||||
}
|
||||
case 26: {
|
||||
payload_.AddEntriesFrom(input, _repeated_payload_codec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
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: {
|
||||
Name = input.ReadString();
|
||||
break;
|
||||
}
|
||||
case 18: {
|
||||
MessageName = input.ReadString();
|
||||
break;
|
||||
}
|
||||
case 26: {
|
||||
payload_.AddEntriesFrom(ref input, _repeated_payload_codec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
#endregion Designer generated code
|
||||
@@ -0,0 +1,72 @@
|
||||
#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;
|
||||
|
||||
namespace Google.Protobuf.Benchmarks
|
||||
{
|
||||
/// <summary>
|
||||
/// Benchmarks using ByteString.
|
||||
/// </summary>
|
||||
[MemoryDiagnoser]
|
||||
public class ByteStringBenchmark
|
||||
{
|
||||
private const int Zero = 0;
|
||||
private const int Kilobyte = 1024;
|
||||
private const int _128Kilobytes = 1024 * 128;
|
||||
private const int Megabyte = 1024 * 1024;
|
||||
private const int _10Megabytes = 1024 * 1024 * 10;
|
||||
|
||||
byte[] byteBuffer;
|
||||
|
||||
[GlobalSetup]
|
||||
public void GlobalSetup()
|
||||
{
|
||||
byteBuffer = new byte[PayloadSize];
|
||||
}
|
||||
|
||||
[Params(Zero, Kilobyte, _128Kilobytes, Megabyte, _10Megabytes)]
|
||||
public int PayloadSize { get; set; }
|
||||
|
||||
[Benchmark]
|
||||
public ByteString CopyFrom()
|
||||
{
|
||||
return ByteString.CopyFrom(byteBuffer);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public ByteString UnsafeWrap()
|
||||
{
|
||||
return UnsafeByteOperations.UnsafeWrap(byteBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<IsPackable>False</IsPackable>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Google.Protobuf.Test\ReadOnlySequenceFactory.cs" Link="ReadOnlySequenceFactory.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
|
||||
<ProjectReference Include="..\Google.Protobuf\Google.Protobuf.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="..\..\..\benchmarks\datasets\google_message1\proto3\dataset.google_message1_proto3.pb" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,124 @@
|
||||
#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.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Google.Protobuf.Benchmarks
|
||||
{
|
||||
/// <summary>
|
||||
/// Benchmark for serializing and deserializing of standard datasets that are also
|
||||
/// measured by benchmarks in other languages.
|
||||
/// Over time we may wish to test the various different approaches to serialization and deserialization separately.
|
||||
/// See https://github.com/protocolbuffers/protobuf/blob/main/benchmarks/README.md
|
||||
/// See https://github.com/protocolbuffers/protobuf/blob/main/docs/performance.md
|
||||
/// </summary>
|
||||
[MemoryDiagnoser]
|
||||
public class GoogleMessageBenchmark
|
||||
{
|
||||
/// <summary>
|
||||
/// All the datasets to be tested. Add more datasets to the array as they're available.
|
||||
/// (When C# supports proto2, this will increase significantly.)
|
||||
/// </summary>
|
||||
public static BenchmarkDatasetConfig[] DatasetConfigurations => new[]
|
||||
{
|
||||
// short name is specified to make results table more readable
|
||||
new BenchmarkDatasetConfig("dataset.google_message1_proto3.pb", "goog_msg1_proto3")
|
||||
};
|
||||
|
||||
[ParamsSource(nameof(DatasetConfigurations))]
|
||||
public BenchmarkDatasetConfig Dataset { get; set; }
|
||||
|
||||
private MessageParser parser;
|
||||
/// <summary>
|
||||
/// Each data set can contain multiple messages in a single file.
|
||||
/// Each "write" operation should write each message in turn, and each "parse"
|
||||
/// operation should parse each message in turn.
|
||||
/// </summary>
|
||||
private List<SubTest> subTests;
|
||||
|
||||
[GlobalSetup]
|
||||
public void GlobalSetup()
|
||||
{
|
||||
parser = Dataset.Parser;
|
||||
subTests = Dataset.Payloads.Select(p => new SubTest(p, parser.ParseFrom(p))).ToList();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void WriteToStream() => subTests.ForEach(item => item.WriteToStream());
|
||||
|
||||
[Benchmark]
|
||||
public void ToByteArray() => subTests.ForEach(item => item.ToByteArray());
|
||||
|
||||
[Benchmark]
|
||||
public void ParseFromByteArray() => subTests.ForEach(item => item.ParseFromByteArray(parser));
|
||||
|
||||
[Benchmark]
|
||||
public void ParseFromStream() => subTests.ForEach(item => item.ParseFromStream(parser));
|
||||
|
||||
private class SubTest
|
||||
{
|
||||
private readonly Stream destinationStream;
|
||||
private readonly Stream sourceStream;
|
||||
private readonly byte[] data;
|
||||
private readonly IMessage message;
|
||||
|
||||
public SubTest(byte[] data, IMessage message)
|
||||
{
|
||||
destinationStream = new MemoryStream(data.Length);
|
||||
sourceStream = new MemoryStream(data);
|
||||
this.data = data;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public void Reset() => destinationStream.Position = 0;
|
||||
|
||||
public void WriteToStream()
|
||||
{
|
||||
destinationStream.Position = 0;
|
||||
message.WriteTo(destinationStream);
|
||||
}
|
||||
|
||||
public void ToByteArray() => message.ToByteArray();
|
||||
|
||||
public void ParseFromByteArray(MessageParser parser) => parser.ParseFrom(data);
|
||||
|
||||
public void ParseFromStream(MessageParser parser)
|
||||
{
|
||||
sourceStream.Position = 0;
|
||||
parser.ParseFrom(sourceStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,258 @@
|
||||
#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;
|
||||
using Benchmarks.Proto3;
|
||||
|
||||
namespace Google.Protobuf.Benchmarks
|
||||
{
|
||||
/// <summary>
|
||||
/// Benchmark that tests parsing performance for various messages.
|
||||
/// </summary>
|
||||
[MemoryDiagnoser]
|
||||
public class ParseMessagesBenchmark
|
||||
{
|
||||
const int MaxMessages = 100;
|
||||
|
||||
SubTest manyWrapperFieldsTest = new SubTest(CreateManyWrapperFieldsMessage(), ManyWrapperFieldsMessage.Parser, () => new ManyWrapperFieldsMessage(), MaxMessages);
|
||||
SubTest manyPrimitiveFieldsTest = new SubTest(CreateManyPrimitiveFieldsMessage(), ManyPrimitiveFieldsMessage.Parser, () => new ManyPrimitiveFieldsMessage(), MaxMessages);
|
||||
SubTest repeatedFieldTest = new SubTest(CreateRepeatedFieldMessage(), GoogleMessage1.Parser, () => new GoogleMessage1(), MaxMessages);
|
||||
SubTest emptyMessageTest = new SubTest(new Empty(), Empty.Parser, () => new Empty(), MaxMessages);
|
||||
|
||||
public IEnumerable<int> MessageCountValues => new[] { 10, 100 };
|
||||
|
||||
[GlobalSetup]
|
||||
public void GlobalSetup()
|
||||
{
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public IMessage ManyWrapperFieldsMessage_ParseFromByteArray()
|
||||
{
|
||||
return manyWrapperFieldsTest.ParseFromByteArray();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public IMessage ManyWrapperFieldsMessage_ParseFromReadOnlySequence()
|
||||
{
|
||||
return manyWrapperFieldsTest.ParseFromReadOnlySequence();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public IMessage ManyPrimitiveFieldsMessage_ParseFromByteArray()
|
||||
{
|
||||
return manyPrimitiveFieldsTest.ParseFromByteArray();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public IMessage ManyPrimitiveFieldsMessage_ParseFromReadOnlySequence()
|
||||
{
|
||||
return manyPrimitiveFieldsTest.ParseFromReadOnlySequence();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public IMessage RepeatedFieldMessage_ParseFromByteArray()
|
||||
{
|
||||
return repeatedFieldTest.ParseFromByteArray();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public IMessage RepeatedFieldMessage_ParseFromReadOnlySequence()
|
||||
{
|
||||
return repeatedFieldTest.ParseFromReadOnlySequence();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public IMessage EmptyMessage_ParseFromByteArray()
|
||||
{
|
||||
return emptyMessageTest.ParseFromByteArray();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public IMessage EmptyMessage_ParseFromReadOnlySequence()
|
||||
{
|
||||
return emptyMessageTest.ParseFromReadOnlySequence();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[ArgumentsSource(nameof(MessageCountValues))]
|
||||
public void ManyWrapperFieldsMessage_ParseDelimitedMessagesFromByteArray(int messageCount)
|
||||
{
|
||||
manyWrapperFieldsTest.ParseDelimitedMessagesFromByteArray(messageCount);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[ArgumentsSource(nameof(MessageCountValues))]
|
||||
public void ManyWrapperFieldsMessage_ParseDelimitedMessagesFromReadOnlySequence(int messageCount)
|
||||
{
|
||||
manyWrapperFieldsTest.ParseDelimitedMessagesFromReadOnlySequence(messageCount);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[ArgumentsSource(nameof(MessageCountValues))]
|
||||
public void ManyPrimitiveFieldsMessage_ParseDelimitedMessagesFromByteArray(int messageCount)
|
||||
{
|
||||
manyPrimitiveFieldsTest.ParseDelimitedMessagesFromByteArray(messageCount);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[ArgumentsSource(nameof(MessageCountValues))]
|
||||
public void ManyPrimitiveFieldsMessage_ParseDelimitedMessagesFromReadOnlySequence(int messageCount)
|
||||
{
|
||||
manyPrimitiveFieldsTest.ParseDelimitedMessagesFromReadOnlySequence(messageCount);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[ArgumentsSource(nameof(MessageCountValues))]
|
||||
public void RepeatedFieldMessage_ParseDelimitedMessagesFromByteArray(int messageCount)
|
||||
{
|
||||
repeatedFieldTest.ParseDelimitedMessagesFromByteArray(messageCount);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[ArgumentsSource(nameof(MessageCountValues))]
|
||||
public void RepeatedFieldMessage_ParseDelimitedMessagesFromReadOnlySequence(int messageCount)
|
||||
{
|
||||
repeatedFieldTest.ParseDelimitedMessagesFromReadOnlySequence(messageCount);
|
||||
}
|
||||
|
||||
public static ManyWrapperFieldsMessage CreateManyWrapperFieldsMessage()
|
||||
{
|
||||
// Example data match data of an internal benchmarks
|
||||
return new ManyWrapperFieldsMessage()
|
||||
{
|
||||
Int64Field19 = 123,
|
||||
Int64Field37 = 1000032,
|
||||
Int64Field26 = 3453524500,
|
||||
DoubleField79 = 1.2,
|
||||
DoubleField25 = 234,
|
||||
DoubleField9 = 123.3,
|
||||
DoubleField28 = 23,
|
||||
DoubleField7 = 234,
|
||||
DoubleField50 = 2.45
|
||||
};
|
||||
}
|
||||
|
||||
public static ManyPrimitiveFieldsMessage CreateManyPrimitiveFieldsMessage()
|
||||
{
|
||||
// Example data match data of an internal benchmarks
|
||||
return new ManyPrimitiveFieldsMessage()
|
||||
{
|
||||
Int64Field19 = 123,
|
||||
Int64Field37 = 1000032,
|
||||
Int64Field26 = 3453524500,
|
||||
DoubleField79 = 1.2,
|
||||
DoubleField25 = 234,
|
||||
DoubleField9 = 123.3,
|
||||
DoubleField28 = 23,
|
||||
DoubleField7 = 234,
|
||||
DoubleField50 = 2.45
|
||||
};
|
||||
}
|
||||
|
||||
public static GoogleMessage1 CreateRepeatedFieldMessage()
|
||||
{
|
||||
// Message with a repeated fixed length item collection
|
||||
var message = new GoogleMessage1();
|
||||
for (ulong i = 0; i < 1000; i++)
|
||||
{
|
||||
message.Field5.Add(i);
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
private class SubTest
|
||||
{
|
||||
private readonly IMessage message;
|
||||
private readonly MessageParser parser;
|
||||
private readonly Func<IMessage> factory;
|
||||
private readonly byte[] data;
|
||||
private readonly byte[] multipleMessagesData;
|
||||
|
||||
private ReadOnlySequence<byte> dataSequence;
|
||||
private ReadOnlySequence<byte> multipleMessagesDataSequence;
|
||||
|
||||
public SubTest(IMessage message, MessageParser parser, Func<IMessage> factory, int maxMessageCount)
|
||||
{
|
||||
this.message = message;
|
||||
this.parser = parser;
|
||||
this.factory = factory;
|
||||
this.data = message.ToByteArray();
|
||||
this.multipleMessagesData = CreateBufferWithMultipleMessages(message, maxMessageCount);
|
||||
this.dataSequence = new ReadOnlySequence<byte>(this.data);
|
||||
this.multipleMessagesDataSequence = new ReadOnlySequence<byte>(this.multipleMessagesData);
|
||||
}
|
||||
|
||||
public IMessage ParseFromByteArray() => parser.ParseFrom(data);
|
||||
|
||||
public IMessage ParseFromReadOnlySequence() => parser.ParseFrom(dataSequence);
|
||||
|
||||
public void ParseDelimitedMessagesFromByteArray(int messageCount)
|
||||
{
|
||||
var input = new CodedInputStream(multipleMessagesData);
|
||||
for (int i = 0; i < messageCount; i++)
|
||||
{
|
||||
var msg = factory();
|
||||
input.ReadMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
public void ParseDelimitedMessagesFromReadOnlySequence(int messageCount)
|
||||
{
|
||||
ParseContext.Initialize(multipleMessagesDataSequence, out ParseContext ctx);
|
||||
for (int i = 0; i < messageCount; i++)
|
||||
{
|
||||
var msg = factory();
|
||||
ctx.ReadMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] CreateBufferWithMultipleMessages(IMessage msg, int msgCount)
|
||||
{
|
||||
var ms = new MemoryStream();
|
||||
var cos = new CodedOutputStream(ms);
|
||||
for (int i = 0; i < msgCount; i++)
|
||||
{
|
||||
cos.WriteMessage(msg);
|
||||
}
|
||||
cos.Flush();
|
||||
return ms.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,536 @@
|
||||
#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;
|
||||
|
||||
namespace Google.Protobuf.Benchmarks
|
||||
{
|
||||
/// <summary>
|
||||
/// Benchmarks throughput when parsing raw primitives.
|
||||
/// </summary>
|
||||
[MemoryDiagnoser]
|
||||
public class ParseRawPrimitivesBenchmark
|
||||
{
|
||||
// key is the encodedSize of varint values
|
||||
Dictionary<int, byte[]> varintInputBuffers;
|
||||
|
||||
byte[] doubleInputBuffer;
|
||||
byte[] floatInputBuffer;
|
||||
byte[] fixedIntInputBuffer;
|
||||
|
||||
// key is the encodedSize of string values
|
||||
Dictionary<int, byte[]> stringInputBuffers;
|
||||
Dictionary<int, ReadOnlySequence<byte>> stringInputBuffersSegmented;
|
||||
|
||||
Random random = new Random(417384220); // random but deterministic seed
|
||||
|
||||
public IEnumerable<int> StringEncodedSizes => new[] { 1, 4, 10, 105, 10080 };
|
||||
public IEnumerable<int> StringSegmentedEncodedSizes => new[] { 105, 10080 };
|
||||
|
||||
[GlobalSetup]
|
||||
public void GlobalSetup()
|
||||
{
|
||||
// add some extra values that we won't read just to make sure we are far enough from the end of the buffer
|
||||
// which allows the parser fastpath to always kick in.
|
||||
const int paddingValueCount = 100;
|
||||
|
||||
varintInputBuffers = new Dictionary<int, byte[]>();
|
||||
for (int encodedSize = 1; encodedSize <= 10; encodedSize++)
|
||||
{
|
||||
byte[] buffer = CreateBufferWithRandomVarints(random, BytesToParse / encodedSize, encodedSize, paddingValueCount);
|
||||
varintInputBuffers.Add(encodedSize, buffer);
|
||||
}
|
||||
|
||||
doubleInputBuffer = CreateBufferWithRandomDoubles(random, BytesToParse / sizeof(double), paddingValueCount);
|
||||
floatInputBuffer = CreateBufferWithRandomFloats(random, BytesToParse / sizeof(float), paddingValueCount);
|
||||
fixedIntInputBuffer = CreateBufferWithRandomData(random, BytesToParse / sizeof(long), sizeof(long), paddingValueCount);
|
||||
|
||||
stringInputBuffers = new Dictionary<int, byte[]>();
|
||||
foreach (var encodedSize in StringEncodedSizes)
|
||||
{
|
||||
byte[] buffer = CreateBufferWithStrings(BytesToParse / encodedSize, encodedSize, encodedSize < 10 ? 10 : 1 );
|
||||
stringInputBuffers.Add(encodedSize, buffer);
|
||||
}
|
||||
|
||||
stringInputBuffersSegmented = new Dictionary<int, ReadOnlySequence<byte>>();
|
||||
foreach (var encodedSize in StringSegmentedEncodedSizes)
|
||||
{
|
||||
byte[] buffer = CreateBufferWithStrings(BytesToParse / encodedSize, encodedSize, encodedSize < 10 ? 10 : 1);
|
||||
stringInputBuffersSegmented.Add(encodedSize, ReadOnlySequenceFactory.CreateWithContent(buffer, segmentSize: 128, addEmptySegmentDelimiters: false));
|
||||
}
|
||||
}
|
||||
|
||||
// Total number of bytes that each benchmark will parse.
|
||||
// Measuring the time taken to parse 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 BytesToParse { get; set; }
|
||||
|
||||
[Benchmark]
|
||||
[Arguments(1)]
|
||||
[Arguments(2)]
|
||||
[Arguments(3)]
|
||||
[Arguments(4)]
|
||||
[Arguments(5)]
|
||||
public int ParseRawVarint32_CodedInputStream(int encodedSize)
|
||||
{
|
||||
CodedInputStream cis = new CodedInputStream(varintInputBuffers[encodedSize]);
|
||||
int sum = 0;
|
||||
for (int i = 0; i < BytesToParse / encodedSize; i++)
|
||||
{
|
||||
sum += cis.ReadInt32();
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[Arguments(1)]
|
||||
[Arguments(2)]
|
||||
[Arguments(3)]
|
||||
[Arguments(4)]
|
||||
[Arguments(5)]
|
||||
public int ParseRawVarint32_ParseContext(int encodedSize)
|
||||
{
|
||||
InitializeParseContext(varintInputBuffers[encodedSize], out ParseContext ctx);
|
||||
int sum = 0;
|
||||
for (int i = 0; i < BytesToParse / encodedSize; i++)
|
||||
{
|
||||
sum += ctx.ReadInt32();
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[Arguments(1)]
|
||||
[Arguments(2)]
|
||||
[Arguments(3)]
|
||||
[Arguments(4)]
|
||||
[Arguments(5)]
|
||||
[Arguments(6)]
|
||||
[Arguments(7)]
|
||||
[Arguments(8)]
|
||||
[Arguments(9)]
|
||||
[Arguments(10)]
|
||||
public long ParseRawVarint64_CodedInputStream(int encodedSize)
|
||||
{
|
||||
CodedInputStream cis = new CodedInputStream(varintInputBuffers[encodedSize]);
|
||||
long sum = 0;
|
||||
for (int i = 0; i < BytesToParse / encodedSize; i++)
|
||||
{
|
||||
sum += cis.ReadInt64();
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[Arguments(1)]
|
||||
[Arguments(2)]
|
||||
[Arguments(3)]
|
||||
[Arguments(4)]
|
||||
[Arguments(5)]
|
||||
[Arguments(6)]
|
||||
[Arguments(7)]
|
||||
[Arguments(8)]
|
||||
[Arguments(9)]
|
||||
[Arguments(10)]
|
||||
public long ParseRawVarint64_ParseContext(int encodedSize)
|
||||
{
|
||||
InitializeParseContext(varintInputBuffers[encodedSize], out ParseContext ctx);
|
||||
long sum = 0;
|
||||
for (int i = 0; i < BytesToParse / encodedSize; i++)
|
||||
{
|
||||
sum += ctx.ReadInt64();
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public uint ParseFixed32_CodedInputStream()
|
||||
{
|
||||
const int encodedSize = sizeof(uint);
|
||||
CodedInputStream cis = new CodedInputStream(fixedIntInputBuffer);
|
||||
uint sum = 0;
|
||||
for (uint i = 0; i < BytesToParse / encodedSize; i++)
|
||||
{
|
||||
sum += cis.ReadFixed32();
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public uint ParseFixed32_ParseContext()
|
||||
{
|
||||
const int encodedSize = sizeof(uint);
|
||||
InitializeParseContext(fixedIntInputBuffer, out ParseContext ctx);
|
||||
uint sum = 0;
|
||||
for (uint i = 0; i < BytesToParse / encodedSize; i++)
|
||||
{
|
||||
sum += ctx.ReadFixed32();
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public ulong ParseFixed64_CodedInputStream()
|
||||
{
|
||||
const int encodedSize = sizeof(ulong);
|
||||
CodedInputStream cis = new CodedInputStream(fixedIntInputBuffer);
|
||||
ulong sum = 0;
|
||||
for (int i = 0; i < BytesToParse / encodedSize; i++)
|
||||
{
|
||||
sum += cis.ReadFixed64();
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public ulong ParseFixed64_ParseContext()
|
||||
{
|
||||
const int encodedSize = sizeof(ulong);
|
||||
InitializeParseContext(fixedIntInputBuffer, out ParseContext ctx);
|
||||
ulong sum = 0;
|
||||
for (int i = 0; i < BytesToParse / encodedSize; i++)
|
||||
{
|
||||
sum += ctx.ReadFixed64();
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public float ParseRawFloat_CodedInputStream()
|
||||
{
|
||||
const int encodedSize = sizeof(float);
|
||||
CodedInputStream cis = new CodedInputStream(floatInputBuffer);
|
||||
float sum = 0;
|
||||
for (int i = 0; i < BytesToParse / encodedSize; i++)
|
||||
{
|
||||
sum += cis.ReadFloat();
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public float ParseRawFloat_ParseContext()
|
||||
{
|
||||
const int encodedSize = sizeof(float);
|
||||
InitializeParseContext(floatInputBuffer, out ParseContext ctx);
|
||||
float sum = 0;
|
||||
for (int i = 0; i < BytesToParse / encodedSize; i++)
|
||||
{
|
||||
sum += ctx.ReadFloat();
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public double ParseRawDouble_CodedInputStream()
|
||||
{
|
||||
const int encodedSize = sizeof(double);
|
||||
CodedInputStream cis = new CodedInputStream(doubleInputBuffer);
|
||||
double sum = 0;
|
||||
for (int i = 0; i < BytesToParse / encodedSize; i++)
|
||||
{
|
||||
sum += cis.ReadDouble();
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public double ParseRawDouble_ParseContext()
|
||||
{
|
||||
const int encodedSize = sizeof(double);
|
||||
InitializeParseContext(doubleInputBuffer, out ParseContext ctx);
|
||||
double sum = 0;
|
||||
for (int i = 0; i < BytesToParse / encodedSize; i++)
|
||||
{
|
||||
sum += ctx.ReadDouble();
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[ArgumentsSource(nameof(StringEncodedSizes))]
|
||||
public int ParseString_CodedInputStream(int encodedSize)
|
||||
{
|
||||
CodedInputStream cis = new CodedInputStream(stringInputBuffers[encodedSize]);
|
||||
int sum = 0;
|
||||
for (int i = 0; i < BytesToParse / encodedSize; i++)
|
||||
{
|
||||
sum += cis.ReadString().Length;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[ArgumentsSource(nameof(StringEncodedSizes))]
|
||||
public int ParseString_ParseContext(int encodedSize)
|
||||
{
|
||||
InitializeParseContext(stringInputBuffers[encodedSize], out ParseContext ctx);
|
||||
int sum = 0;
|
||||
for (int i = 0; i < BytesToParse / encodedSize; i++)
|
||||
{
|
||||
sum += ctx.ReadString().Length;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[ArgumentsSource(nameof(StringSegmentedEncodedSizes))]
|
||||
public int ParseString_ParseContext_MultipleSegments(int encodedSize)
|
||||
{
|
||||
InitializeParseContext(stringInputBuffersSegmented[encodedSize], out ParseContext ctx);
|
||||
int sum = 0;
|
||||
for (int i = 0; i < BytesToParse / encodedSize; i++)
|
||||
{
|
||||
sum += ctx.ReadString().Length;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[ArgumentsSource(nameof(StringEncodedSizes))]
|
||||
public int ParseBytes_CodedInputStream(int encodedSize)
|
||||
{
|
||||
CodedInputStream cis = new CodedInputStream(stringInputBuffers[encodedSize]);
|
||||
int sum = 0;
|
||||
for (int i = 0; i < BytesToParse / encodedSize; i++)
|
||||
{
|
||||
sum += cis.ReadBytes().Length;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[ArgumentsSource(nameof(StringEncodedSizes))]
|
||||
public int ParseBytes_ParseContext(int encodedSize)
|
||||
{
|
||||
InitializeParseContext(stringInputBuffers[encodedSize], out ParseContext ctx);
|
||||
int sum = 0;
|
||||
for (int i = 0; i < BytesToParse / encodedSize; i++)
|
||||
{
|
||||
sum += ctx.ReadBytes().Length;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[ArgumentsSource(nameof(StringSegmentedEncodedSizes))]
|
||||
public int ParseBytes_ParseContext_MultipleSegments(int encodedSize)
|
||||
{
|
||||
InitializeParseContext(stringInputBuffersSegmented[encodedSize], out ParseContext ctx);
|
||||
int sum = 0;
|
||||
for (int i = 0; i < BytesToParse / encodedSize; i++)
|
||||
{
|
||||
sum += ctx.ReadBytes().Length;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
private static void InitializeParseContext(byte[] buffer, out ParseContext ctx)
|
||||
{
|
||||
ParseContext.Initialize(new ReadOnlySequence<byte>(buffer), out ctx);
|
||||
}
|
||||
|
||||
private static void InitializeParseContext(ReadOnlySequence<byte> buffer, out ParseContext ctx)
|
||||
{
|
||||
ParseContext.Initialize(buffer, out ctx);
|
||||
}
|
||||
|
||||
private static byte[] CreateBufferWithRandomVarints(Random random, int valueCount, int encodedSize, int paddingValueCount)
|
||||
{
|
||||
MemoryStream ms = new MemoryStream();
|
||||
CodedOutputStream cos = new CodedOutputStream(ms);
|
||||
for (int i = 0; i < valueCount + paddingValueCount; i++)
|
||||
{
|
||||
cos.WriteUInt64(RandomUnsignedVarint(random, encodedSize, false));
|
||||
}
|
||||
cos.Flush();
|
||||
var buffer = ms.ToArray();
|
||||
|
||||
if (buffer.Length != encodedSize * (valueCount + paddingValueCount))
|
||||
{
|
||||
throw new InvalidOperationException($"Unexpected output buffer length {buffer.Length}");
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
private static byte[] CreateBufferWithRandomFloats(Random random, int valueCount, int paddingValueCount)
|
||||
{
|
||||
MemoryStream ms = new MemoryStream();
|
||||
CodedOutputStream cos = new CodedOutputStream(ms);
|
||||
for (int i = 0; i < valueCount + paddingValueCount; i++)
|
||||
{
|
||||
cos.WriteFloat((float)random.NextDouble());
|
||||
}
|
||||
cos.Flush();
|
||||
var buffer = ms.ToArray();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
private static byte[] CreateBufferWithRandomDoubles(Random random, int valueCount, int paddingValueCount)
|
||||
{
|
||||
MemoryStream ms = new MemoryStream();
|
||||
CodedOutputStream cos = new CodedOutputStream(ms);
|
||||
for (int i = 0; i < valueCount + paddingValueCount; i++)
|
||||
{
|
||||
cos.WriteDouble(random.NextDouble());
|
||||
}
|
||||
cos.Flush();
|
||||
var buffer = ms.ToArray();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
private static byte[] CreateBufferWithRandomData(Random random, int valueCount, int encodedSize, int paddingValueCount)
|
||||
{
|
||||
int bufferSize = (valueCount + paddingValueCount) * encodedSize;
|
||||
byte[] buffer = new byte[bufferSize];
|
||||
random.NextBytes(buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a random value that will take exactly "encodedSize" bytes when varint-encoded.
|
||||
/// </summary>
|
||||
public static ulong RandomUnsignedVarint(Random random, int encodedSize, bool fitsIn32Bits)
|
||||
{
|
||||
Span<byte> randomBytesBuffer = stackalloc byte[8];
|
||||
|
||||
if (encodedSize < 1 || encodedSize > 10 || (fitsIn32Bits && encodedSize > 5))
|
||||
{
|
||||
throw new ArgumentException("Illegal encodedSize value requested", nameof(encodedSize));
|
||||
}
|
||||
const int bitsPerByte = 7;
|
||||
|
||||
ulong result = 0;
|
||||
while (true)
|
||||
{
|
||||
random.NextBytes(randomBytesBuffer);
|
||||
ulong randomValue = BinaryPrimitives.ReadUInt64LittleEndian(randomBytesBuffer);
|
||||
|
||||
// only use the number of random bits we need
|
||||
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)
|
||||
result |= ulong.MaxValue;
|
||||
break;
|
||||
}
|
||||
|
||||
// some random values won't require the full "encodedSize" bytes, check that at least
|
||||
// one of the top 7 bits is set. Retrying is fine since it only happens rarely
|
||||
if (encodedSize == 1 || (result & (0x7FUL << ((encodedSize - 1) * bitsPerByte))) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static byte[] CreateBufferWithStrings(int valueCount, int encodedSize, int paddingValueCount)
|
||||
{
|
||||
var str = CreateStringWithEncodedSize(encodedSize);
|
||||
|
||||
MemoryStream ms = new MemoryStream();
|
||||
CodedOutputStream cos = new CodedOutputStream(ms);
|
||||
for (int i = 0; i < valueCount + paddingValueCount; i++)
|
||||
{
|
||||
cos.WriteString(str);
|
||||
}
|
||||
cos.Flush();
|
||||
var buffer = ms.ToArray();
|
||||
|
||||
if (buffer.Length != encodedSize * (valueCount + paddingValueCount))
|
||||
{
|
||||
throw new InvalidOperationException($"Unexpected output buffer length {buffer.Length}");
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static string CreateStringWithEncodedSize(int encodedSize)
|
||||
{
|
||||
var str = new string('a', encodedSize);
|
||||
while (CodedOutputStream.ComputeStringSize(str) > encodedSize)
|
||||
{
|
||||
str = str.Substring(1);
|
||||
}
|
||||
|
||||
if (CodedOutputStream.ComputeStringSize(str) != encodedSize)
|
||||
{
|
||||
throw new InvalidOperationException($"Generated string with wrong encodedSize");
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#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.Running;
|
||||
|
||||
namespace Google.Protobuf.Benchmarks
|
||||
{
|
||||
class Program
|
||||
{
|
||||
// typical usage: dotnet run -c Release -f netcoreapp3.1
|
||||
// (this can profile both .net core and .net framework; for some reason
|
||||
// if you start from "-f net461", it goes horribly wrong)
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package google.protobuf.benchmarks;
|
||||
|
||||
import "google/protobuf/wrappers.proto";
|
||||
|
||||
// a message that has a large number of wrapper fields
|
||||
// obfuscated version of an internal message
|
||||
message ManyWrapperFieldsMessage {
|
||||
google.protobuf.DoubleValue double_field_95 = 95;
|
||||
google.protobuf.DoubleValue double_field_1 = 1;
|
||||
google.protobuf.DoubleValue double_field_79 = 79;
|
||||
google.protobuf.Int64Value int64_field_2 = 2;
|
||||
google.protobuf.DoubleValue double_field_96 = 96;
|
||||
google.protobuf.Int64Value int64_field_3 = 3;
|
||||
google.protobuf.Int64Value int64_field_4 = 4;
|
||||
google.protobuf.DoubleValue double_field_97 = 97;
|
||||
google.protobuf.DoubleValue double_field_65 = 65;
|
||||
google.protobuf.DoubleValue double_field_66 = 66;
|
||||
google.protobuf.DoubleValue double_field_7 = 7;
|
||||
google.protobuf.DoubleValue double_field_62 = 62;
|
||||
google.protobuf.DoubleValue double_field_118 = 118;
|
||||
google.protobuf.DoubleValue double_field_119 = 119;
|
||||
google.protobuf.DoubleValue double_field_67 = 67;
|
||||
google.protobuf.DoubleValue double_field_120 = 120;
|
||||
google.protobuf.DoubleValue double_field_121 = 121;
|
||||
google.protobuf.DoubleValue double_field_122 = 122;
|
||||
google.protobuf.DoubleValue double_field_123 = 123;
|
||||
google.protobuf.DoubleValue double_field_124 = 124;
|
||||
google.protobuf.DoubleValue double_field_8 = 8;
|
||||
google.protobuf.DoubleValue double_field_9 = 9;
|
||||
google.protobuf.DoubleValue double_field_98 = 98;
|
||||
google.protobuf.DoubleValue double_field_10 = 10;
|
||||
google.protobuf.DoubleValue double_field_11 = 11;
|
||||
google.protobuf.DoubleValue double_field_99 = 99;
|
||||
google.protobuf.DoubleValue double_field_84 = 84;
|
||||
google.protobuf.DoubleValue double_field_14 = 14;
|
||||
google.protobuf.DoubleValue double_field_77 = 77;
|
||||
google.protobuf.DoubleValue double_field_15 = 15;
|
||||
google.protobuf.Int64Value int64_field_19 = 19;
|
||||
google.protobuf.Int64Value int64_field_115 = 115;
|
||||
google.protobuf.DoubleValue double_field_116 = 116;
|
||||
google.protobuf.Int64Value int64_field_117 = 117;
|
||||
google.protobuf.DoubleValue double_field_20 = 20;
|
||||
google.protobuf.DoubleValue double_field_21 = 21;
|
||||
google.protobuf.StringValue string_field_73 = 73;
|
||||
google.protobuf.StringValue string_field_74 = 74;
|
||||
google.protobuf.DoubleValue double_field_22 = 22;
|
||||
google.protobuf.DoubleValue double_field_69 = 69;
|
||||
google.protobuf.DoubleValue double_field_70 = 70;
|
||||
google.protobuf.DoubleValue double_field_71 = 71;
|
||||
google.protobuf.DoubleValue double_field_72 = 72;
|
||||
google.protobuf.DoubleValue double_field_25 = 25;
|
||||
google.protobuf.Int64Value int64_field_26 = 26;
|
||||
google.protobuf.DoubleValue double_field_68 = 68;
|
||||
google.protobuf.DoubleValue double_field_28 = 28;
|
||||
google.protobuf.DoubleValue double_field_106 = 106;
|
||||
google.protobuf.DoubleValue double_field_29 = 29;
|
||||
google.protobuf.DoubleValue double_field_30 = 30;
|
||||
google.protobuf.DoubleValue double_field_101 = 101;
|
||||
google.protobuf.DoubleValue double_field_102 = 102;
|
||||
google.protobuf.DoubleValue double_field_103 = 103;
|
||||
google.protobuf.DoubleValue double_field_104 = 104;
|
||||
google.protobuf.DoubleValue double_field_105 = 105;
|
||||
google.protobuf.DoubleValue double_field_31 = 31;
|
||||
google.protobuf.Int64Value int64_field_32 = 32;
|
||||
google.protobuf.DoubleValue double_field_75 = 75;
|
||||
google.protobuf.DoubleValue double_field_129 = 129;
|
||||
int32 enum_field_80 = 80;
|
||||
int32 enum_field_81 = 81;
|
||||
google.protobuf.Int64Value int64_field_82 = 82;
|
||||
int32 enum_field_83 = 83;
|
||||
google.protobuf.Int64Value int64_field_85 = 85;
|
||||
google.protobuf.Int64Value int64_field_86 = 86;
|
||||
google.protobuf.Int64Value int64_field_87 = 87;
|
||||
google.protobuf.Int64Value int64_field_125 = 125;
|
||||
google.protobuf.Int64Value int64_field_37 = 37;
|
||||
google.protobuf.DoubleValue double_field_38 = 38;
|
||||
google.protobuf.Int64Value interactions = 39;
|
||||
repeated int32 repeated_int_field_100 = 100;
|
||||
google.protobuf.DoubleValue double_field_40 = 40;
|
||||
google.protobuf.Int64Value int64_field_41 = 41;
|
||||
google.protobuf.Int64Value int64_field_126 = 126;
|
||||
google.protobuf.Int64Value int64_field_127 = 127;
|
||||
google.protobuf.DoubleValue double_field_128 = 128;
|
||||
google.protobuf.DoubleValue double_field_109 = 109;
|
||||
google.protobuf.Int64Value int64_field_110 = 110;
|
||||
google.protobuf.DoubleValue double_field_111 = 111;
|
||||
google.protobuf.Int64Value int64_field_112 = 112;
|
||||
google.protobuf.DoubleValue double_field_113 = 113;
|
||||
google.protobuf.Int64Value int64_field_114 = 114;
|
||||
google.protobuf.DoubleValue double_field_42 = 42;
|
||||
google.protobuf.Int64Value int64_field_43 = 43;
|
||||
google.protobuf.Int64Value int64_field_44 = 44;
|
||||
google.protobuf.DoubleValue double_field_45 = 45;
|
||||
google.protobuf.DoubleValue double_field_46 = 46;
|
||||
google.protobuf.DoubleValue double_field_78 = 78;
|
||||
google.protobuf.DoubleValue double_field_88 = 88;
|
||||
google.protobuf.DoubleValue double_field_47 = 47;
|
||||
google.protobuf.DoubleValue double_field_89 = 89;
|
||||
google.protobuf.DoubleValue double_field_48 = 48;
|
||||
google.protobuf.DoubleValue double_field_49 = 49;
|
||||
google.protobuf.DoubleValue double_field_50 = 50;
|
||||
google.protobuf.DoubleValue double_field_90 = 90;
|
||||
google.protobuf.DoubleValue double_field_51 = 51;
|
||||
google.protobuf.DoubleValue double_field_91 = 91;
|
||||
google.protobuf.DoubleValue double_field_92 = 92;
|
||||
google.protobuf.Int64Value int64_field_107 = 107;
|
||||
google.protobuf.DoubleValue double_field_93 = 93;
|
||||
google.protobuf.DoubleValue double_field_108 = 108;
|
||||
google.protobuf.DoubleValue double_field_52 = 52;
|
||||
google.protobuf.DoubleValue double_field_53 = 53;
|
||||
google.protobuf.DoubleValue double_field_94 = 94;
|
||||
google.protobuf.DoubleValue double_field_54 = 54;
|
||||
google.protobuf.DoubleValue double_field_55 = 55;
|
||||
google.protobuf.DoubleValue double_field_56 = 56;
|
||||
google.protobuf.DoubleValue double_field_57 = 57;
|
||||
google.protobuf.DoubleValue double_field_58 = 58;
|
||||
google.protobuf.Int64Value int64_field_59 = 59;
|
||||
google.protobuf.Int64Value int64_field_60 = 60;
|
||||
}
|
||||
|
||||
// same as ManyWrapperFieldsMessages, but with primitive fields
|
||||
// for comparison.
|
||||
message ManyPrimitiveFieldsMessage {
|
||||
double double_field_95 = 95;
|
||||
double double_field_1 = 1;
|
||||
double double_field_79 = 79;
|
||||
int64 int64_field_2 = 2;
|
||||
double double_field_96 = 96;
|
||||
int64 int64_field_3 = 3;
|
||||
int64 int64_field_4 = 4;
|
||||
double double_field_97 = 97;
|
||||
double double_field_65 = 65;
|
||||
double double_field_66 = 66;
|
||||
double double_field_7 = 7;
|
||||
double double_field_62 = 62;
|
||||
double double_field_118 = 118;
|
||||
double double_field_119 = 119;
|
||||
double double_field_67 = 67;
|
||||
double double_field_120 = 120;
|
||||
double double_field_121 = 121;
|
||||
double double_field_122 = 122;
|
||||
double double_field_123 = 123;
|
||||
double double_field_124 = 124;
|
||||
double double_field_8 = 8;
|
||||
double double_field_9 = 9;
|
||||
double double_field_98 = 98;
|
||||
double double_field_10 = 10;
|
||||
double double_field_11 = 11;
|
||||
double double_field_99 = 99;
|
||||
double double_field_84 = 84;
|
||||
double double_field_14 = 14;
|
||||
double double_field_77 = 77;
|
||||
double double_field_15 = 15;
|
||||
int64 int64_field_19 = 19;
|
||||
int64 int64_field_115 = 115;
|
||||
double double_field_116 = 116;
|
||||
int64 int64_field_117 = 117;
|
||||
double double_field_20 = 20;
|
||||
double double_field_21 = 21;
|
||||
string string_field_73 = 73;
|
||||
string string_field_74 = 74;
|
||||
double double_field_22 = 22;
|
||||
double double_field_69 = 69;
|
||||
double double_field_70 = 70;
|
||||
double double_field_71 = 71;
|
||||
double double_field_72 = 72;
|
||||
double double_field_25 = 25;
|
||||
int64 int64_field_26 = 26;
|
||||
double double_field_68 = 68;
|
||||
double double_field_28 = 28;
|
||||
double double_field_106 = 106;
|
||||
double double_field_29 = 29;
|
||||
double double_field_30 = 30;
|
||||
double double_field_101 = 101;
|
||||
double double_field_102 = 102;
|
||||
double double_field_103 = 103;
|
||||
double double_field_104 = 104;
|
||||
double double_field_105 = 105;
|
||||
double double_field_31 = 31;
|
||||
int64 int64_field_32 = 32;
|
||||
double double_field_75 = 75;
|
||||
double double_field_129 = 129;
|
||||
int32 enum_field_80 = 80;
|
||||
int32 enum_field_81 = 81;
|
||||
int64 int64_field_82 = 82;
|
||||
int32 enum_field_83 = 83;
|
||||
int64 int64_field_85 = 85;
|
||||
int64 int64_field_86 = 86;
|
||||
int64 int64_field_87 = 87;
|
||||
int64 int64_field_125 = 125;
|
||||
int64 int64_field_37 = 37;
|
||||
double double_field_38 = 38;
|
||||
int64 interactions = 39;
|
||||
repeated int32 repeated_int_field_100 = 100;
|
||||
double double_field_40 = 40;
|
||||
int64 int64_field_41 = 41;
|
||||
int64 int64_field_126 = 126;
|
||||
int64 int64_field_127 = 127;
|
||||
double double_field_128 = 128;
|
||||
double double_field_109 = 109;
|
||||
int64 int64_field_110 = 110;
|
||||
double double_field_111 = 111;
|
||||
int64 int64_field_112 = 112;
|
||||
double double_field_113 = 113;
|
||||
int64 int64_field_114 = 114;
|
||||
double double_field_42 = 42;
|
||||
int64 int64_field_43 = 43;
|
||||
int64 int64_field_44 = 44;
|
||||
double double_field_45 = 45;
|
||||
double double_field_46 = 46;
|
||||
double double_field_78 = 78;
|
||||
double double_field_88 = 88;
|
||||
double double_field_47 = 47;
|
||||
double double_field_89 = 89;
|
||||
double double_field_48 = 48;
|
||||
double double_field_49 = 49;
|
||||
double double_field_50 = 50;
|
||||
double double_field_90 = 90;
|
||||
double double_field_51 = 51;
|
||||
double double_field_91 = 91;
|
||||
double double_field_92 = 92;
|
||||
int64 int64_field_107 = 107;
|
||||
double double_field_93 = 93;
|
||||
double double_field_108 = 108;
|
||||
double double_field_52 = 52;
|
||||
double double_field_53 = 53;
|
||||
double double_field_94 = 94;
|
||||
double double_field_54 = 54;
|
||||
double double_field_55 = 55;
|
||||
double double_field_56 = 56;
|
||||
double double_field_57 = 57;
|
||||
double double_field_58 = 58;
|
||||
int64 int64_field_59 = 59;
|
||||
int64 int64_field_60 = 60;
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
load("//build_defs:internal_shell.bzl", "inline_sh_binary")
|
||||
load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix")
|
||||
|
||||
inline_sh_binary(
|
||||
name = "build_conformance_test",
|
||||
srcs = ["Google.Protobuf.Conformance.csproj"],
|
||||
cmd = "dotnet build -c Release $(SRCS)",
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
CONFORMANCE_DEPS = [
|
||||
"Google.Protobuf.dll",
|
||||
"Google.Protobuf.Conformance.deps.json",
|
||||
"Google.Protobuf.Conformance.pdb",
|
||||
"Google.Protobuf.Conformance.runtimeconfig.json",
|
||||
"Google.Protobuf.Test.dll",
|
||||
"Google.Protobuf.Test.TestProtos.dll",
|
||||
"Microsoft.TestPlatform.CommunicationUtilities.dll",
|
||||
"Microsoft.TestPlatform.CoreUtilities.dll",
|
||||
"Microsoft.TestPlatform.CrossPlatEngine.dll",
|
||||
"Microsoft.TestPlatform.PlatformAbstractions.dll",
|
||||
"Microsoft.TestPlatform.Utilities.dll",
|
||||
"Microsoft.VisualStudio.CodeCoverage.Shim.dll",
|
||||
"Microsoft.VisualStudio.TestPlatform.Common.dll",
|
||||
"Microsoft.VisualStudio.TestPlatform.ObjectModel.dll",
|
||||
"NUnit3.TestAdapter.dll",
|
||||
"Newtonsoft.Json.dll",
|
||||
"NuGet.Frameworks.dll",
|
||||
"nunit.engine.api.dll",
|
||||
"nunit.engine.core.dll",
|
||||
"nunit.engine.dll",
|
||||
"nunit.framework.dll",
|
||||
"testcentric.engine.metadata.dll",
|
||||
"testhost.dll",
|
||||
]
|
||||
|
||||
filegroup(
|
||||
name = "srcs",
|
||||
srcs = [
|
||||
"Conformance.cs",
|
||||
"Program.cs",
|
||||
"Google.Protobuf.Conformance.csproj",
|
||||
],
|
||||
visibility = [
|
||||
"//csharp:__subpackages__",
|
||||
],
|
||||
)
|
||||
|
||||
genrule(
|
||||
name = "package_conformance_test",
|
||||
srcs = [
|
||||
"Program.cs",
|
||||
"Google.Protobuf.Conformance.csproj",
|
||||
"//conformance:conformance_csharp_proto",
|
||||
"//csharp:srcs",
|
||||
],
|
||||
visibility = ["//visibility:private"],
|
||||
tools = [":build_conformance_test"],
|
||||
outs = CONFORMANCE_DEPS + ["Google.Protobuf.Conformance.dll"],
|
||||
cmd = """
|
||||
SRCDIR=$$(dirname $(location :Program.cs))
|
||||
cp $(location //conformance:conformance_csharp_proto) $$SRCDIR
|
||||
DOTNET_CLI_HOME=/tmp ./$(location :build_conformance_test)
|
||||
cp -r $$SRCDIR/bin/Release/netcoreapp3.1/* $(RULEDIR)
|
||||
""",
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "conformance_dll",
|
||||
srcs = ["Google.Protobuf.Conformance.dll"],
|
||||
data = [":package_conformance_test"],
|
||||
visibility = ["//conformance:__subpackages__"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "conformance_runfiles",
|
||||
srcs = CONFORMANCE_DEPS,
|
||||
data = [":package_conformance_test"],
|
||||
visibility = ["//conformance:__subpackages__"],
|
||||
)
|
||||
|
||||
################################################################################
|
||||
# Distribution files
|
||||
################################################################################
|
||||
|
||||
pkg_files(
|
||||
name = "dist_files",
|
||||
srcs = [
|
||||
"BUILD.bazel",
|
||||
"Google.Protobuf.Conformance.csproj",
|
||||
"Conformance.cs",
|
||||
"Program.cs",
|
||||
],
|
||||
strip_prefix = strip_prefix.from_root(""),
|
||||
visibility = ["//csharp:__pkg__"],
|
||||
)
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace Google.Protobuf.Conformance
|
||||
/// </summary>
|
||||
class Program
|
||||
{
|
||||
private static void Main()
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
// This way we get the binary streams instead of readers/writers.
|
||||
var input = new BinaryReader(Console.OpenStandardInput());
|
||||
@@ -100,22 +100,32 @@ namespace Google.Protobuf.Conformance
|
||||
return new ConformanceResponse { Skipped = "CSharp doesn't support skipping unknown fields in json parsing." };
|
||||
}
|
||||
var parser = new JsonParser(new JsonParser.Settings(20, typeRegistry));
|
||||
message = request.MessageType switch
|
||||
switch (request.MessageType)
|
||||
{
|
||||
"protobuf_test_messages.proto3.TestAllTypesProto3" => parser.Parse<ProtobufTestMessages.Proto3.TestAllTypesProto3>(request.JsonPayload),
|
||||
"protobuf_test_messages.proto2.TestAllTypesProto2" => parser.Parse<ProtobufTestMessages.Proto2.TestAllTypesProto2>(request.JsonPayload),
|
||||
_ => throw new Exception($" Protobuf request doesn't have specific payload type ({request.MessageType})"),
|
||||
};
|
||||
case "protobuf_test_messages.proto3.TestAllTypesProto3":
|
||||
message = parser.Parse<ProtobufTestMessages.Proto3.TestAllTypesProto3>(request.JsonPayload);
|
||||
break;
|
||||
case "protobuf_test_messages.proto2.TestAllTypesProto2":
|
||||
message = parser.Parse<ProtobufTestMessages.Proto2.TestAllTypesProto2>(request.JsonPayload);
|
||||
break;
|
||||
default:
|
||||
throw new Exception($" Protobuf request doesn't have specific payload type ({request.MessageType})");
|
||||
}
|
||||
break;
|
||||
case ConformanceRequest.PayloadOneofCase.ProtobufPayload:
|
||||
message = request.MessageType switch
|
||||
switch (request.MessageType)
|
||||
{
|
||||
"protobuf_test_messages.proto3.TestAllTypesProto3" => ProtobufTestMessages.Proto3.TestAllTypesProto3.Parser.ParseFrom(request.ProtobufPayload),
|
||||
"protobuf_test_messages.proto2.TestAllTypesProto2" => ProtobufTestMessages.Proto2.TestAllTypesProto2.Parser
|
||||
.WithExtensionRegistry(proto2ExtensionRegistry)
|
||||
.ParseFrom(request.ProtobufPayload),
|
||||
_ => throw new Exception($" Protobuf request doesn't have specific payload type ({request.MessageType})"),
|
||||
};
|
||||
case "protobuf_test_messages.proto3.TestAllTypesProto3":
|
||||
message = ProtobufTestMessages.Proto3.TestAllTypesProto3.Parser.ParseFrom(request.ProtobufPayload);
|
||||
break;
|
||||
case "protobuf_test_messages.proto2.TestAllTypesProto2":
|
||||
message = ProtobufTestMessages.Proto2.TestAllTypesProto2.Parser
|
||||
.WithExtensionRegistry(proto2ExtensionRegistry)
|
||||
.ParseFrom(request.ProtobufPayload);
|
||||
break;
|
||||
default:
|
||||
throw new Exception($" Protobuf request doesn't have specific payload type ({request.MessageType})");
|
||||
}
|
||||
break;
|
||||
case ConformanceRequest.PayloadOneofCase.TextPayload:
|
||||
return new ConformanceResponse { Skipped = "CSharp doesn't support text format" };
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
-->
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net462;netstandard1.1;netstandard2.0</TargetFrameworks>
|
||||
<LangVersion>10.0</LangVersion>
|
||||
<LangVersion>3.0</LangVersion>
|
||||
<AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<IsPackable>False</IsPackable>
|
||||
|
||||
@@ -580,23 +580,23 @@ namespace Google.Protobuf.TestProtos {
|
||||
if (other == null) {
|
||||
return;
|
||||
}
|
||||
mapInt32Int32_.MergeFrom(other.mapInt32Int32_);
|
||||
mapInt64Int64_.MergeFrom(other.mapInt64Int64_);
|
||||
mapUint32Uint32_.MergeFrom(other.mapUint32Uint32_);
|
||||
mapUint64Uint64_.MergeFrom(other.mapUint64Uint64_);
|
||||
mapSint32Sint32_.MergeFrom(other.mapSint32Sint32_);
|
||||
mapSint64Sint64_.MergeFrom(other.mapSint64Sint64_);
|
||||
mapFixed32Fixed32_.MergeFrom(other.mapFixed32Fixed32_);
|
||||
mapFixed64Fixed64_.MergeFrom(other.mapFixed64Fixed64_);
|
||||
mapSfixed32Sfixed32_.MergeFrom(other.mapSfixed32Sfixed32_);
|
||||
mapSfixed64Sfixed64_.MergeFrom(other.mapSfixed64Sfixed64_);
|
||||
mapInt32Float_.MergeFrom(other.mapInt32Float_);
|
||||
mapInt32Double_.MergeFrom(other.mapInt32Double_);
|
||||
mapBoolBool_.MergeFrom(other.mapBoolBool_);
|
||||
mapStringString_.MergeFrom(other.mapStringString_);
|
||||
mapInt32Bytes_.MergeFrom(other.mapInt32Bytes_);
|
||||
mapInt32Enum_.MergeFrom(other.mapInt32Enum_);
|
||||
mapInt32ForeignMessage_.MergeFrom(other.mapInt32ForeignMessage_);
|
||||
mapInt32Int32_.Add(other.mapInt32Int32_);
|
||||
mapInt64Int64_.Add(other.mapInt64Int64_);
|
||||
mapUint32Uint32_.Add(other.mapUint32Uint32_);
|
||||
mapUint64Uint64_.Add(other.mapUint64Uint64_);
|
||||
mapSint32Sint32_.Add(other.mapSint32Sint32_);
|
||||
mapSint64Sint64_.Add(other.mapSint64Sint64_);
|
||||
mapFixed32Fixed32_.Add(other.mapFixed32Fixed32_);
|
||||
mapFixed64Fixed64_.Add(other.mapFixed64Fixed64_);
|
||||
mapSfixed32Sfixed32_.Add(other.mapSfixed32Sfixed32_);
|
||||
mapSfixed64Sfixed64_.Add(other.mapSfixed64Sfixed64_);
|
||||
mapInt32Float_.Add(other.mapInt32Float_);
|
||||
mapInt32Double_.Add(other.mapInt32Double_);
|
||||
mapBoolBool_.Add(other.mapBoolBool_);
|
||||
mapStringString_.Add(other.mapStringString_);
|
||||
mapInt32Bytes_.Add(other.mapInt32Bytes_);
|
||||
mapInt32Enum_.Add(other.mapInt32Enum_);
|
||||
mapInt32ForeignMessage_.Add(other.mapInt32ForeignMessage_);
|
||||
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
@@ -1100,7 +1100,7 @@ namespace Google.Protobuf.TestProtos {
|
||||
if (other == null) {
|
||||
return;
|
||||
}
|
||||
mapInt32Message_.MergeFrom(other.mapInt32Message_);
|
||||
mapInt32Message_.Add(other.mapInt32Message_);
|
||||
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
@@ -1298,8 +1298,8 @@ namespace Google.Protobuf.TestProtos {
|
||||
if (other == null) {
|
||||
return;
|
||||
}
|
||||
map1_.MergeFrom(other.map1_);
|
||||
map2_.MergeFrom(other.map2_);
|
||||
map1_.Add(other.map1_);
|
||||
map2_.Add(other.map2_);
|
||||
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
@@ -1723,21 +1723,21 @@ namespace Google.Protobuf.TestProtos {
|
||||
if (other == null) {
|
||||
return;
|
||||
}
|
||||
mapInt32Int32_.MergeFrom(other.mapInt32Int32_);
|
||||
mapInt64Int64_.MergeFrom(other.mapInt64Int64_);
|
||||
mapUint32Uint32_.MergeFrom(other.mapUint32Uint32_);
|
||||
mapUint64Uint64_.MergeFrom(other.mapUint64Uint64_);
|
||||
mapSint32Sint32_.MergeFrom(other.mapSint32Sint32_);
|
||||
mapSint64Sint64_.MergeFrom(other.mapSint64Sint64_);
|
||||
mapFixed32Fixed32_.MergeFrom(other.mapFixed32Fixed32_);
|
||||
mapFixed64Fixed64_.MergeFrom(other.mapFixed64Fixed64_);
|
||||
mapSfixed32Sfixed32_.MergeFrom(other.mapSfixed32Sfixed32_);
|
||||
mapSfixed64Sfixed64_.MergeFrom(other.mapSfixed64Sfixed64_);
|
||||
mapInt32Float_.MergeFrom(other.mapInt32Float_);
|
||||
mapInt32Double_.MergeFrom(other.mapInt32Double_);
|
||||
mapBoolBool_.MergeFrom(other.mapBoolBool_);
|
||||
mapInt32Enum_.MergeFrom(other.mapInt32Enum_);
|
||||
mapInt32ForeignMessage_.MergeFrom(other.mapInt32ForeignMessage_);
|
||||
mapInt32Int32_.Add(other.mapInt32Int32_);
|
||||
mapInt64Int64_.Add(other.mapInt64Int64_);
|
||||
mapUint32Uint32_.Add(other.mapUint32Uint32_);
|
||||
mapUint64Uint64_.Add(other.mapUint64Uint64_);
|
||||
mapSint32Sint32_.Add(other.mapSint32Sint32_);
|
||||
mapSint64Sint64_.Add(other.mapSint64Sint64_);
|
||||
mapFixed32Fixed32_.Add(other.mapFixed32Fixed32_);
|
||||
mapFixed64Fixed64_.Add(other.mapFixed64Fixed64_);
|
||||
mapSfixed32Sfixed32_.Add(other.mapSfixed32Sfixed32_);
|
||||
mapSfixed64Sfixed64_.Add(other.mapSfixed64Sfixed64_);
|
||||
mapInt32Float_.Add(other.mapInt32Float_);
|
||||
mapInt32Double_.Add(other.mapInt32Double_);
|
||||
mapBoolBool_.Add(other.mapBoolBool_);
|
||||
mapInt32Enum_.Add(other.mapInt32Enum_);
|
||||
mapInt32ForeignMessage_.Add(other.mapInt32ForeignMessage_);
|
||||
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
@@ -2031,7 +2031,7 @@ namespace Google.Protobuf.TestProtos {
|
||||
if (other == null) {
|
||||
return;
|
||||
}
|
||||
type_.MergeFrom(other.type_);
|
||||
type_.Add(other.type_);
|
||||
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
@@ -2224,7 +2224,7 @@ namespace Google.Protobuf.TestProtos {
|
||||
if (other == null) {
|
||||
return;
|
||||
}
|
||||
entry_.MergeFrom(other.entry_);
|
||||
entry_.Add(other.entry_);
|
||||
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
|
||||
@@ -213,14 +213,12 @@ namespace ProtobufTestMessages.Proto2 {
|
||||
"dGlvbmFsX2Jvb2wY7gcgASgIEhcKDnJlcGVhdGVkX2ludDMyGPMHIAMoBRoa",
|
||||
"Cg1PcHRpb25hbEdyb3VwEgkKAWEYASABKAUiFgoUTnVsbEh5cG90aGVzaXNQ",
|
||||
"cm90bzIiLwoORW51bU9ubHlQcm90bzIiHQoEQm9vbBIKCgZrRmFsc2UQABIJ",
|
||||
"CgVrVHJ1ZRABIh8KD09uZVN0cmluZ1Byb3RvMhIMCgRkYXRhGAEgASgJIkYK",
|
||||
"EVByb3RvV2l0aEtleXdvcmRzEg4KBmlubGluZRgBIAEoBRIPCgdjb25jZXB0",
|
||||
"GAIgASgJEhAKCHJlcXVpcmVzGAMgAygJKkYKEUZvcmVpZ25FbnVtUHJvdG8y",
|
||||
"Eg8KC0ZPUkVJR05fRk9PEAASDwoLRk9SRUlHTl9CQVIQARIPCgtGT1JFSUdO",
|
||||
"X0JBWhACOkoKD2V4dGVuc2lvbl9pbnQzMhIxLnByb3RvYnVmX3Rlc3RfbWVz",
|
||||
"c2FnZXMucHJvdG8yLlRlc3RBbGxUeXBlc1Byb3RvMhh4IAEoBUI4Cihjb20u",
|
||||
"Z29vZ2xlLnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMucHJvdG8ySAH4AQGiAgZQ",
|
||||
"cm90bzI="));
|
||||
"CgVrVHJ1ZRABIh8KD09uZVN0cmluZ1Byb3RvMhIMCgRkYXRhGAEgASgJKkYK",
|
||||
"EUZvcmVpZ25FbnVtUHJvdG8yEg8KC0ZPUkVJR05fRk9PEAASDwoLRk9SRUlH",
|
||||
"Tl9CQVIQARIPCgtGT1JFSUdOX0JBWhACOkoKD2V4dGVuc2lvbl9pbnQzMhIx",
|
||||
"LnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMucHJvdG8yLlRlc3RBbGxUeXBlc1By",
|
||||
"b3RvMhh4IAEoBUIvCihjb20uZ29vZ2xlLnByb3RvYnVmX3Rlc3RfbWVzc2Fn",
|
||||
"ZXMucHJvdG8ySAH4AQE="));
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedClrTypeInfo(new[] {typeof(global::ProtobufTestMessages.Proto2.ForeignEnumProto2), }, new pb::Extension[] { TestMessagesProto2Extensions.ExtensionInt32 }, new pbr::GeneratedClrTypeInfo[] {
|
||||
@@ -233,8 +231,7 @@ namespace ProtobufTestMessages.Proto2 {
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.UnknownToTestAllTypes), global::ProtobufTestMessages.Proto2.UnknownToTestAllTypes.Parser, new[]{ "OptionalInt32", "OptionalString", "NestedMessage", "OptionalGroup", "OptionalBool", "RepeatedInt32" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.UnknownToTestAllTypes.Types.OptionalGroup), global::ProtobufTestMessages.Proto2.UnknownToTestAllTypes.Types.OptionalGroup.Parser, new[]{ "A" }, null, null, null, null)}),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.NullHypothesisProto2), global::ProtobufTestMessages.Proto2.NullHypothesisProto2.Parser, null, null, null, null, null),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.EnumOnlyProto2), global::ProtobufTestMessages.Proto2.EnumOnlyProto2.Parser, null, null, new[]{ typeof(global::ProtobufTestMessages.Proto2.EnumOnlyProto2.Types.Bool) }, null, null),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.OneStringProto2), global::ProtobufTestMessages.Proto2.OneStringProto2.Parser, new[]{ "Data" }, null, null, null, null),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.ProtoWithKeywords), global::ProtobufTestMessages.Proto2.ProtoWithKeywords.Parser, new[]{ "Inline", "Concept", "Requires" }, null, null, null, null)
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.OneStringProto2), global::ProtobufTestMessages.Proto2.OneStringProto2.Parser, new[]{ "Data" }, null, null, null, null)
|
||||
}));
|
||||
}
|
||||
#endregion
|
||||
@@ -4345,25 +4342,25 @@ namespace ProtobufTestMessages.Proto2 {
|
||||
unpackedDouble_.Add(other.unpackedDouble_);
|
||||
unpackedBool_.Add(other.unpackedBool_);
|
||||
unpackedNestedEnum_.Add(other.unpackedNestedEnum_);
|
||||
mapInt32Int32_.MergeFrom(other.mapInt32Int32_);
|
||||
mapInt64Int64_.MergeFrom(other.mapInt64Int64_);
|
||||
mapUint32Uint32_.MergeFrom(other.mapUint32Uint32_);
|
||||
mapUint64Uint64_.MergeFrom(other.mapUint64Uint64_);
|
||||
mapSint32Sint32_.MergeFrom(other.mapSint32Sint32_);
|
||||
mapSint64Sint64_.MergeFrom(other.mapSint64Sint64_);
|
||||
mapFixed32Fixed32_.MergeFrom(other.mapFixed32Fixed32_);
|
||||
mapFixed64Fixed64_.MergeFrom(other.mapFixed64Fixed64_);
|
||||
mapSfixed32Sfixed32_.MergeFrom(other.mapSfixed32Sfixed32_);
|
||||
mapSfixed64Sfixed64_.MergeFrom(other.mapSfixed64Sfixed64_);
|
||||
mapInt32Float_.MergeFrom(other.mapInt32Float_);
|
||||
mapInt32Double_.MergeFrom(other.mapInt32Double_);
|
||||
mapBoolBool_.MergeFrom(other.mapBoolBool_);
|
||||
mapStringString_.MergeFrom(other.mapStringString_);
|
||||
mapStringBytes_.MergeFrom(other.mapStringBytes_);
|
||||
mapStringNestedMessage_.MergeFrom(other.mapStringNestedMessage_);
|
||||
mapStringForeignMessage_.MergeFrom(other.mapStringForeignMessage_);
|
||||
mapStringNestedEnum_.MergeFrom(other.mapStringNestedEnum_);
|
||||
mapStringForeignEnum_.MergeFrom(other.mapStringForeignEnum_);
|
||||
mapInt32Int32_.Add(other.mapInt32Int32_);
|
||||
mapInt64Int64_.Add(other.mapInt64Int64_);
|
||||
mapUint32Uint32_.Add(other.mapUint32Uint32_);
|
||||
mapUint64Uint64_.Add(other.mapUint64Uint64_);
|
||||
mapSint32Sint32_.Add(other.mapSint32Sint32_);
|
||||
mapSint64Sint64_.Add(other.mapSint64Sint64_);
|
||||
mapFixed32Fixed32_.Add(other.mapFixed32Fixed32_);
|
||||
mapFixed64Fixed64_.Add(other.mapFixed64Fixed64_);
|
||||
mapSfixed32Sfixed32_.Add(other.mapSfixed32Sfixed32_);
|
||||
mapSfixed64Sfixed64_.Add(other.mapSfixed64Sfixed64_);
|
||||
mapInt32Float_.Add(other.mapInt32Float_);
|
||||
mapInt32Double_.Add(other.mapInt32Double_);
|
||||
mapBoolBool_.Add(other.mapBoolBool_);
|
||||
mapStringString_.Add(other.mapStringString_);
|
||||
mapStringBytes_.Add(other.mapStringBytes_);
|
||||
mapStringNestedMessage_.Add(other.mapStringNestedMessage_);
|
||||
mapStringForeignMessage_.Add(other.mapStringForeignMessage_);
|
||||
mapStringNestedEnum_.Add(other.mapStringNestedEnum_);
|
||||
mapStringForeignEnum_.Add(other.mapStringForeignEnum_);
|
||||
if (other.HasData) {
|
||||
if (!HasData) {
|
||||
Data = new global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.Data();
|
||||
@@ -8303,289 +8300,6 @@ namespace ProtobufTestMessages.Proto2 {
|
||||
|
||||
}
|
||||
|
||||
public sealed partial class ProtoWithKeywords : pb::IMessage<ProtoWithKeywords>
|
||||
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
|
||||
, pb::IBufferMessage
|
||||
#endif
|
||||
{
|
||||
private static readonly pb::MessageParser<ProtoWithKeywords> _parser = new pb::MessageParser<ProtoWithKeywords>(() => new ProtoWithKeywords());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
private int _hasBits0;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public static pb::MessageParser<ProtoWithKeywords> Parser { get { return _parser; } }
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public static pbr::MessageDescriptor Descriptor {
|
||||
get { return global::ProtobufTestMessages.Proto2.TestMessagesProto2Reflection.Descriptor.MessageTypes[6]; }
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
pbr::MessageDescriptor pb::IMessage.Descriptor {
|
||||
get { return Descriptor; }
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public ProtoWithKeywords() {
|
||||
OnConstruction();
|
||||
}
|
||||
|
||||
partial void OnConstruction();
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public ProtoWithKeywords(ProtoWithKeywords other) : this() {
|
||||
_hasBits0 = other._hasBits0;
|
||||
inline_ = other.inline_;
|
||||
concept_ = other.concept_;
|
||||
requires_ = other.requires_.Clone();
|
||||
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public ProtoWithKeywords Clone() {
|
||||
return new ProtoWithKeywords(this);
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "inline" field.</summary>
|
||||
public const int InlineFieldNumber = 1;
|
||||
private readonly static int InlineDefaultValue = 0;
|
||||
|
||||
private int inline_;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public int Inline {
|
||||
get { if ((_hasBits0 & 1) != 0) { return inline_; } else { return InlineDefaultValue; } }
|
||||
set {
|
||||
_hasBits0 |= 1;
|
||||
inline_ = value;
|
||||
}
|
||||
}
|
||||
/// <summary>Gets whether the "inline" field is set</summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public bool HasInline {
|
||||
get { return (_hasBits0 & 1) != 0; }
|
||||
}
|
||||
/// <summary>Clears the value of the "inline" field</summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public void ClearInline() {
|
||||
_hasBits0 &= ~1;
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "concept" field.</summary>
|
||||
public const int ConceptFieldNumber = 2;
|
||||
private readonly static string ConceptDefaultValue = "";
|
||||
|
||||
private string concept_;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public string Concept {
|
||||
get { return concept_ ?? ConceptDefaultValue; }
|
||||
set {
|
||||
concept_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
|
||||
}
|
||||
}
|
||||
/// <summary>Gets whether the "concept" field is set</summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public bool HasConcept {
|
||||
get { return concept_ != null; }
|
||||
}
|
||||
/// <summary>Clears the value of the "concept" field</summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public void ClearConcept() {
|
||||
concept_ = null;
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "requires" field.</summary>
|
||||
public const int RequiresFieldNumber = 3;
|
||||
private static readonly pb::FieldCodec<string> _repeated_requires_codec
|
||||
= pb::FieldCodec.ForString(26);
|
||||
private readonly pbc::RepeatedField<string> requires_ = new pbc::RepeatedField<string>();
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public pbc::RepeatedField<string> Requires {
|
||||
get { return requires_; }
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public override bool Equals(object other) {
|
||||
return Equals(other as ProtoWithKeywords);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public bool Equals(ProtoWithKeywords other) {
|
||||
if (ReferenceEquals(other, null)) {
|
||||
return false;
|
||||
}
|
||||
if (ReferenceEquals(other, this)) {
|
||||
return true;
|
||||
}
|
||||
if (Inline != other.Inline) return false;
|
||||
if (Concept != other.Concept) return false;
|
||||
if(!requires_.Equals(other.requires_)) return false;
|
||||
return Equals(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public override int GetHashCode() {
|
||||
int hash = 1;
|
||||
if (HasInline) hash ^= Inline.GetHashCode();
|
||||
if (HasConcept) hash ^= Concept.GetHashCode();
|
||||
hash ^= requires_.GetHashCode();
|
||||
if (_unknownFields != null) {
|
||||
hash ^= _unknownFields.GetHashCode();
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public override string ToString() {
|
||||
return pb::JsonFormatter.ToDiagnosticString(this);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public void WriteTo(pb::CodedOutputStream output) {
|
||||
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
|
||||
output.WriteRawMessage(this);
|
||||
#else
|
||||
if (HasInline) {
|
||||
output.WriteRawTag(8);
|
||||
output.WriteInt32(Inline);
|
||||
}
|
||||
if (HasConcept) {
|
||||
output.WriteRawTag(18);
|
||||
output.WriteString(Concept);
|
||||
}
|
||||
requires_.WriteTo(output, _repeated_requires_codec);
|
||||
if (_unknownFields != null) {
|
||||
_unknownFields.WriteTo(output);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
|
||||
if (HasInline) {
|
||||
output.WriteRawTag(8);
|
||||
output.WriteInt32(Inline);
|
||||
}
|
||||
if (HasConcept) {
|
||||
output.WriteRawTag(18);
|
||||
output.WriteString(Concept);
|
||||
}
|
||||
requires_.WriteTo(ref output, _repeated_requires_codec);
|
||||
if (_unknownFields != null) {
|
||||
_unknownFields.WriteTo(ref output);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public int CalculateSize() {
|
||||
int size = 0;
|
||||
if (HasInline) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeInt32Size(Inline);
|
||||
}
|
||||
if (HasConcept) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeStringSize(Concept);
|
||||
}
|
||||
size += requires_.CalculateSize(_repeated_requires_codec);
|
||||
if (_unknownFields != null) {
|
||||
size += _unknownFields.CalculateSize();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public void MergeFrom(ProtoWithKeywords other) {
|
||||
if (other == null) {
|
||||
return;
|
||||
}
|
||||
if (other.HasInline) {
|
||||
Inline = other.Inline;
|
||||
}
|
||||
if (other.HasConcept) {
|
||||
Concept = other.Concept;
|
||||
}
|
||||
requires_.Add(other.requires_);
|
||||
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
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 8: {
|
||||
Inline = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 18: {
|
||||
Concept = input.ReadString();
|
||||
break;
|
||||
}
|
||||
case 26: {
|
||||
requires_.AddEntriesFrom(input, _repeated_requires_codec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
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 8: {
|
||||
Inline = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 18: {
|
||||
Concept = input.ReadString();
|
||||
break;
|
||||
}
|
||||
case 26: {
|
||||
requires_.AddEntriesFrom(ref input, _repeated_requires_codec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
@@ -3753,25 +3753,25 @@ namespace ProtobufTestMessages.Proto3 {
|
||||
unpackedDouble_.Add(other.unpackedDouble_);
|
||||
unpackedBool_.Add(other.unpackedBool_);
|
||||
unpackedNestedEnum_.Add(other.unpackedNestedEnum_);
|
||||
mapInt32Int32_.MergeFrom(other.mapInt32Int32_);
|
||||
mapInt64Int64_.MergeFrom(other.mapInt64Int64_);
|
||||
mapUint32Uint32_.MergeFrom(other.mapUint32Uint32_);
|
||||
mapUint64Uint64_.MergeFrom(other.mapUint64Uint64_);
|
||||
mapSint32Sint32_.MergeFrom(other.mapSint32Sint32_);
|
||||
mapSint64Sint64_.MergeFrom(other.mapSint64Sint64_);
|
||||
mapFixed32Fixed32_.MergeFrom(other.mapFixed32Fixed32_);
|
||||
mapFixed64Fixed64_.MergeFrom(other.mapFixed64Fixed64_);
|
||||
mapSfixed32Sfixed32_.MergeFrom(other.mapSfixed32Sfixed32_);
|
||||
mapSfixed64Sfixed64_.MergeFrom(other.mapSfixed64Sfixed64_);
|
||||
mapInt32Float_.MergeFrom(other.mapInt32Float_);
|
||||
mapInt32Double_.MergeFrom(other.mapInt32Double_);
|
||||
mapBoolBool_.MergeFrom(other.mapBoolBool_);
|
||||
mapStringString_.MergeFrom(other.mapStringString_);
|
||||
mapStringBytes_.MergeFrom(other.mapStringBytes_);
|
||||
mapStringNestedMessage_.MergeFrom(other.mapStringNestedMessage_);
|
||||
mapStringForeignMessage_.MergeFrom(other.mapStringForeignMessage_);
|
||||
mapStringNestedEnum_.MergeFrom(other.mapStringNestedEnum_);
|
||||
mapStringForeignEnum_.MergeFrom(other.mapStringForeignEnum_);
|
||||
mapInt32Int32_.Add(other.mapInt32Int32_);
|
||||
mapInt64Int64_.Add(other.mapInt64Int64_);
|
||||
mapUint32Uint32_.Add(other.mapUint32Uint32_);
|
||||
mapUint64Uint64_.Add(other.mapUint64Uint64_);
|
||||
mapSint32Sint32_.Add(other.mapSint32Sint32_);
|
||||
mapSint64Sint64_.Add(other.mapSint64Sint64_);
|
||||
mapFixed32Fixed32_.Add(other.mapFixed32Fixed32_);
|
||||
mapFixed64Fixed64_.Add(other.mapFixed64Fixed64_);
|
||||
mapSfixed32Sfixed32_.Add(other.mapSfixed32Sfixed32_);
|
||||
mapSfixed64Sfixed64_.Add(other.mapSfixed64Sfixed64_);
|
||||
mapInt32Float_.Add(other.mapInt32Float_);
|
||||
mapInt32Double_.Add(other.mapInt32Double_);
|
||||
mapBoolBool_.Add(other.mapBoolBool_);
|
||||
mapStringString_.Add(other.mapStringString_);
|
||||
mapStringBytes_.Add(other.mapStringBytes_);
|
||||
mapStringNestedMessage_.Add(other.mapStringNestedMessage_);
|
||||
mapStringForeignMessage_.Add(other.mapStringForeignMessage_);
|
||||
mapStringNestedEnum_.Add(other.mapStringNestedEnum_);
|
||||
mapStringForeignEnum_.Add(other.mapStringForeignEnum_);
|
||||
if (other.optionalBoolWrapper_ != null) {
|
||||
if (optionalBoolWrapper_ == null || other.OptionalBoolWrapper != false) {
|
||||
OptionalBoolWrapper = other.OptionalBoolWrapper;
|
||||
|
||||
@@ -24112,7 +24112,7 @@ namespace Google.Protobuf.TestProtos.Proto2 {
|
||||
if (other == null) {
|
||||
return;
|
||||
}
|
||||
foo_.MergeFrom(other.foo_);
|
||||
foo_.Add(other.foo_);
|
||||
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
@@ -30708,7 +30708,7 @@ namespace Google.Protobuf.TestProtos.Proto2 {
|
||||
}
|
||||
OptionalGroup.MergeFrom(other.OptionalGroup);
|
||||
}
|
||||
stringStringMap_.MergeFrom(other.stringStringMap_);
|
||||
stringStringMap_.Add(other.stringStringMap_);
|
||||
switch (other.OneofFieldCase) {
|
||||
case OneofFieldOneofCase.OneofUint32:
|
||||
OneofUint32 = other.OneofUint32;
|
||||
|
||||
@@ -30,44 +30,37 @@ namespace UnitTest.Issues.TestProtos {
|
||||
"EiwKBXZhbHVlGAEgASgOMh0udW5pdHRlc3RfaXNzdWVzLk5lZ2F0aXZlRW51",
|
||||
"bRIxCgZ2YWx1ZXMYAiADKA4yHS51bml0dGVzdF9pc3N1ZXMuTmVnYXRpdmVF",
|
||||
"bnVtQgIQABI4Cg1wYWNrZWRfdmFsdWVzGAMgAygOMh0udW5pdHRlc3RfaXNz",
|
||||
"dWVzLk5lZ2F0aXZlRW51bUICEAEiFQoPRGVwcmVjYXRlZENoaWxkOgIYASK5",
|
||||
"AgoXRGVwcmVjYXRlZEZpZWxkc01lc3NhZ2USGgoOUHJpbWl0aXZlVmFsdWUY",
|
||||
"ASABKAVCAhgBEhoKDlByaW1pdGl2ZUFycmF5GAIgAygFQgIYARI6CgxNZXNz",
|
||||
"YWdlVmFsdWUYAyABKAsyIC51bml0dGVzdF9pc3N1ZXMuRGVwcmVjYXRlZENo",
|
||||
"aWxkQgIYARI6CgxNZXNzYWdlQXJyYXkYBCADKAsyIC51bml0dGVzdF9pc3N1",
|
||||
"ZXMuRGVwcmVjYXRlZENoaWxkQgIYARI2CglFbnVtVmFsdWUYBSABKA4yHy51",
|
||||
"bml0dGVzdF9pc3N1ZXMuRGVwcmVjYXRlZEVudW1CAhgBEjYKCUVudW1BcnJh",
|
||||
"eRgGIAMoDjIfLnVuaXR0ZXN0X2lzc3Vlcy5EZXByZWNhdGVkRW51bUICGAEi",
|
||||
"GQoJSXRlbUZpZWxkEgwKBGl0ZW0YASABKAUiRAoNUmVzZXJ2ZWROYW1lcxIN",
|
||||
"CgV0eXBlcxgBIAEoBRISCgpkZXNjcmlwdG9yGAIgASgFGhAKDlNvbWVOZXN0",
|
||||
"ZWRUeXBlIqABChVUZXN0SnNvbkZpZWxkT3JkZXJpbmcSEwoLcGxhaW5faW50",
|
||||
"MzIYBCABKAUSEwoJbzFfc3RyaW5nGAIgASgJSAASEgoIbzFfaW50MzIYBSAB",
|
||||
"KAVIABIUCgxwbGFpbl9zdHJpbmcYASABKAkSEgoIbzJfaW50MzIYBiABKAVI",
|
||||
"ARITCglvMl9zdHJpbmcYAyABKAlIAUIECgJvMUIECgJvMiJLCgxUZXN0SnNv",
|
||||
"bk5hbWUSDAoEbmFtZRgBIAEoCRIZCgtkZXNjcmlwdGlvbhgCIAEoCVIEZGVz",
|
||||
"YxISCgRndWlkGAMgASgJUgRleGlkIn8KDE9uZW9mTWVyZ2luZxIOCgR0ZXh0",
|
||||
"GAEgASgJSAASNgoGbmVzdGVkGAIgASgLMiQudW5pdHRlc3RfaXNzdWVzLk9u",
|
||||
"ZW9mTWVyZ2luZy5OZXN0ZWRIABoeCgZOZXN0ZWQSCQoBeBgBIAEoBRIJCgF5",
|
||||
"GAIgASgFQgcKBXZhbHVlImsKFk51bGxWYWx1ZU91dHNpZGVTdHJ1Y3QSFgoM",
|
||||
"c3RyaW5nX3ZhbHVlGAEgASgJSAASMAoKbnVsbF92YWx1ZRgCIAEoDjIaLmdv",
|
||||
"b2dsZS5wcm90b2J1Zi5OdWxsVmFsdWVIAEIHCgV2YWx1ZSJFChNOdWxsVmFs",
|
||||
"dWVOb3RJbk9uZW9mEi4KCm51bGxfdmFsdWUYAiABKA4yGi5nb29nbGUucHJv",
|
||||
"dG9idWYuTnVsbFZhbHVlImAKF01peGVkUmVndWxhckFuZE9wdGlvbmFsEhUK",
|
||||
"DXJlZ3VsYXJfZmllbGQYASABKAkSGwoOb3B0aW9uYWxfZmllbGQYAiABKAlI",
|
||||
"AIgBAUIRCg9fb3B0aW9uYWxfZmllbGQiOQoST25lb2ZXaXRoTm9uZUZpZWxk",
|
||||
"EgsKAXgYASABKAlIABIOCgRub25lGAIgASgJSABCBgoEdGVzdCI1ChFPbmVv",
|
||||
"ZldpdGhOb25lTmFtZRILCgF4GAEgASgJSAASCwoBeRgCIAEoCUgAQgYKBG5v",
|
||||
"bmUikwIKGURpc2FtYmlndWF0ZUNvbW1vbk1lbWJlcnMSIwobZGlzYW1iaWd1",
|
||||
"YXRlX2NvbW1vbl9tZW1iZXJzGAEgASgFEg0KBXR5cGVzGAIgASgFEhIKCmRl",
|
||||
"c2NyaXB0b3IYAyABKAUSDgoGZXF1YWxzGAQgASgFEhEKCXRvX3N0cmluZxgF",
|
||||
"IAEoBRIVCg1nZXRfaGFzaF9jb2RlGAYgASgFEhAKCHdyaXRlX3RvGAcgASgF",
|
||||
"Eg0KBWNsb25lGAggASgFEhYKDmNhbGN1bGF0ZV9zaXplGAkgASgFEhIKCm1l",
|
||||
"cmdlX2Zyb20YCiABKAUSFwoPb25fY29uc3RydWN0aW9uGAsgASgFEg4KBnBh",
|
||||
"cnNlchgMIAEoBSpVCgxOZWdhdGl2ZUVudW0SFgoSTkVHQVRJVkVfRU5VTV9a",
|
||||
"RVJPEAASFgoJRml2ZUJlbG93EPv//////////wESFQoITWludXNPbmUQ////",
|
||||
"////////ASo2Cg5EZXByZWNhdGVkRW51bRIXCg9ERVBSRUNBVEVEX1pFUk8Q",
|
||||
"ABoCCAESBwoDb25lEAEaAhgBQh2qAhpVbml0VGVzdC5Jc3N1ZXMuVGVzdFBy",
|
||||
"b3Rvc2IGcHJvdG8z"));
|
||||
"dWVzLk5lZ2F0aXZlRW51bUICEAEiEQoPRGVwcmVjYXRlZENoaWxkIrkCChdE",
|
||||
"ZXByZWNhdGVkRmllbGRzTWVzc2FnZRIaCg5QcmltaXRpdmVWYWx1ZRgBIAEo",
|
||||
"BUICGAESGgoOUHJpbWl0aXZlQXJyYXkYAiADKAVCAhgBEjoKDE1lc3NhZ2VW",
|
||||
"YWx1ZRgDIAEoCzIgLnVuaXR0ZXN0X2lzc3Vlcy5EZXByZWNhdGVkQ2hpbGRC",
|
||||
"AhgBEjoKDE1lc3NhZ2VBcnJheRgEIAMoCzIgLnVuaXR0ZXN0X2lzc3Vlcy5E",
|
||||
"ZXByZWNhdGVkQ2hpbGRCAhgBEjYKCUVudW1WYWx1ZRgFIAEoDjIfLnVuaXR0",
|
||||
"ZXN0X2lzc3Vlcy5EZXByZWNhdGVkRW51bUICGAESNgoJRW51bUFycmF5GAYg",
|
||||
"AygOMh8udW5pdHRlc3RfaXNzdWVzLkRlcHJlY2F0ZWRFbnVtQgIYASIZCglJ",
|
||||
"dGVtRmllbGQSDAoEaXRlbRgBIAEoBSJECg1SZXNlcnZlZE5hbWVzEg0KBXR5",
|
||||
"cGVzGAEgASgFEhIKCmRlc2NyaXB0b3IYAiABKAUaEAoOU29tZU5lc3RlZFR5",
|
||||
"cGUioAEKFVRlc3RKc29uRmllbGRPcmRlcmluZxITCgtwbGFpbl9pbnQzMhgE",
|
||||
"IAEoBRITCglvMV9zdHJpbmcYAiABKAlIABISCghvMV9pbnQzMhgFIAEoBUgA",
|
||||
"EhQKDHBsYWluX3N0cmluZxgBIAEoCRISCghvMl9pbnQzMhgGIAEoBUgBEhMK",
|
||||
"CW8yX3N0cmluZxgDIAEoCUgBQgQKAm8xQgQKAm8yIksKDFRlc3RKc29uTmFt",
|
||||
"ZRIMCgRuYW1lGAEgASgJEhkKC2Rlc2NyaXB0aW9uGAIgASgJUgRkZXNjEhIK",
|
||||
"BGd1aWQYAyABKAlSBGV4aWQifwoMT25lb2ZNZXJnaW5nEg4KBHRleHQYASAB",
|
||||
"KAlIABI2CgZuZXN0ZWQYAiABKAsyJC51bml0dGVzdF9pc3N1ZXMuT25lb2ZN",
|
||||
"ZXJnaW5nLk5lc3RlZEgAGh4KBk5lc3RlZBIJCgF4GAEgASgFEgkKAXkYAiAB",
|
||||
"KAVCBwoFdmFsdWUiawoWTnVsbFZhbHVlT3V0c2lkZVN0cnVjdBIWCgxzdHJp",
|
||||
"bmdfdmFsdWUYASABKAlIABIwCgpudWxsX3ZhbHVlGAIgASgOMhouZ29vZ2xl",
|
||||
"LnByb3RvYnVmLk51bGxWYWx1ZUgAQgcKBXZhbHVlIkUKE051bGxWYWx1ZU5v",
|
||||
"dEluT25lb2YSLgoKbnVsbF92YWx1ZRgCIAEoDjIaLmdvb2dsZS5wcm90b2J1",
|
||||
"Zi5OdWxsVmFsdWUiYAoXTWl4ZWRSZWd1bGFyQW5kT3B0aW9uYWwSFQoNcmVn",
|
||||
"dWxhcl9maWVsZBgBIAEoCRIbCg5vcHRpb25hbF9maWVsZBgCIAEoCUgAiAEB",
|
||||
"QhEKD19vcHRpb25hbF9maWVsZCI5ChJPbmVvZldpdGhOb25lRmllbGQSCwoB",
|
||||
"eBgBIAEoCUgAEg4KBG5vbmUYAiABKAlIAEIGCgR0ZXN0IjUKEU9uZW9mV2l0",
|
||||
"aE5vbmVOYW1lEgsKAXgYASABKAlIABILCgF5GAIgASgJSABCBgoEbm9uZSpV",
|
||||
"CgxOZWdhdGl2ZUVudW0SFgoSTkVHQVRJVkVfRU5VTV9aRVJPEAASFgoJRml2",
|
||||
"ZUJlbG93EPv//////////wESFQoITWludXNPbmUQ////////////ASouCg5E",
|
||||
"ZXByZWNhdGVkRW51bRITCg9ERVBSRUNBVEVEX1pFUk8QABIHCgNvbmUQAUId",
|
||||
"qgIaVW5pdFRlc3QuSXNzdWVzLlRlc3RQcm90b3NiBnByb3RvMw=="));
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
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[] {
|
||||
@@ -84,8 +77,7 @@ namespace UnitTest.Issues.TestProtos {
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.NullValueNotInOneof), global::UnitTest.Issues.TestProtos.NullValueNotInOneof.Parser, new[]{ "NullValue" }, null, null, null, null),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.MixedRegularAndOptional), global::UnitTest.Issues.TestProtos.MixedRegularAndOptional.Parser, new[]{ "RegularField", "OptionalField" }, new[]{ "OptionalField" }, null, null, null),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.OneofWithNoneField), global::UnitTest.Issues.TestProtos.OneofWithNoneField.Parser, new[]{ "X", "None" }, new[]{ "Test" }, null, null, null),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.OneofWithNoneName), global::UnitTest.Issues.TestProtos.OneofWithNoneName.Parser, new[]{ "X", "Y" }, new[]{ "None" }, null, null, null),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.DisambiguateCommonMembers), global::UnitTest.Issues.TestProtos.DisambiguateCommonMembers.Parser, new[]{ "DisambiguateCommonMembers_", "Types_", "Descriptor_", "Equals_", "ToString_", "GetHashCode_", "WriteTo_", "Clone_", "CalculateSize_", "MergeFrom_", "OnConstruction_", "Parser_" }, null, null, null, null)
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.OneofWithNoneName), global::UnitTest.Issues.TestProtos.OneofWithNoneName.Parser, new[]{ "X", "Y" }, new[]{ "None" }, null, null, null)
|
||||
}));
|
||||
}
|
||||
#endregion
|
||||
@@ -98,9 +90,7 @@ namespace UnitTest.Issues.TestProtos {
|
||||
[pbr::OriginalName("MinusOne")] MinusOne = -1,
|
||||
}
|
||||
|
||||
[global::System.ObsoleteAttribute]
|
||||
public enum DeprecatedEnum {
|
||||
[global::System.ObsoleteAttribute]
|
||||
[pbr::OriginalName("DEPRECATED_ZERO")] DeprecatedZero = 0,
|
||||
[pbr::OriginalName("one")] One = 1,
|
||||
}
|
||||
@@ -829,7 +819,6 @@ namespace UnitTest.Issues.TestProtos {
|
||||
|
||||
}
|
||||
|
||||
[global::System.ObsoleteAttribute]
|
||||
public sealed partial class DeprecatedChild : pb::IMessage<DeprecatedChild>
|
||||
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
|
||||
, pb::IBufferMessage
|
||||
@@ -4358,605 +4347,6 @@ namespace UnitTest.Issues.TestProtos {
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Issue 8810
|
||||
/// </summary>
|
||||
public sealed partial class DisambiguateCommonMembers : pb::IMessage<DisambiguateCommonMembers>
|
||||
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
|
||||
, pb::IBufferMessage
|
||||
#endif
|
||||
{
|
||||
private static readonly pb::MessageParser<DisambiguateCommonMembers> _parser = new pb::MessageParser<DisambiguateCommonMembers>(() => new DisambiguateCommonMembers());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public static pb::MessageParser<DisambiguateCommonMembers> Parser { get { return _parser; } }
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public static pbr::MessageDescriptor Descriptor {
|
||||
get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[14]; }
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
pbr::MessageDescriptor pb::IMessage.Descriptor {
|
||||
get { return Descriptor; }
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public DisambiguateCommonMembers() {
|
||||
OnConstruction();
|
||||
}
|
||||
|
||||
partial void OnConstruction();
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public DisambiguateCommonMembers(DisambiguateCommonMembers other) : this() {
|
||||
disambiguateCommonMembers_ = other.disambiguateCommonMembers_;
|
||||
types_ = other.types_;
|
||||
descriptor_ = other.descriptor_;
|
||||
equals_ = other.equals_;
|
||||
toString_ = other.toString_;
|
||||
getHashCode_ = other.getHashCode_;
|
||||
writeTo_ = other.writeTo_;
|
||||
clone_ = other.clone_;
|
||||
calculateSize_ = other.calculateSize_;
|
||||
mergeFrom_ = other.mergeFrom_;
|
||||
onConstruction_ = other.onConstruction_;
|
||||
parser_ = other.parser_;
|
||||
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public DisambiguateCommonMembers Clone() {
|
||||
return new DisambiguateCommonMembers(this);
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "disambiguate_common_members" field.</summary>
|
||||
public const int DisambiguateCommonMembers_FieldNumber = 1;
|
||||
private int disambiguateCommonMembers_;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public int DisambiguateCommonMembers_ {
|
||||
get { return disambiguateCommonMembers_; }
|
||||
set {
|
||||
disambiguateCommonMembers_ = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "types" field.</summary>
|
||||
public const int Types_FieldNumber = 2;
|
||||
private int types_;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public int Types_ {
|
||||
get { return types_; }
|
||||
set {
|
||||
types_ = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "descriptor" field.</summary>
|
||||
public const int Descriptor_FieldNumber = 3;
|
||||
private int descriptor_;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public int Descriptor_ {
|
||||
get { return descriptor_; }
|
||||
set {
|
||||
descriptor_ = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "equals" field.</summary>
|
||||
public const int Equals_FieldNumber = 4;
|
||||
private int equals_;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public int Equals_ {
|
||||
get { return equals_; }
|
||||
set {
|
||||
equals_ = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "to_string" field.</summary>
|
||||
public const int ToString_FieldNumber = 5;
|
||||
private int toString_;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public int ToString_ {
|
||||
get { return toString_; }
|
||||
set {
|
||||
toString_ = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "get_hash_code" field.</summary>
|
||||
public const int GetHashCode_FieldNumber = 6;
|
||||
private int getHashCode_;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public int GetHashCode_ {
|
||||
get { return getHashCode_; }
|
||||
set {
|
||||
getHashCode_ = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "write_to" field.</summary>
|
||||
public const int WriteTo_FieldNumber = 7;
|
||||
private int writeTo_;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public int WriteTo_ {
|
||||
get { return writeTo_; }
|
||||
set {
|
||||
writeTo_ = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "clone" field.</summary>
|
||||
public const int Clone_FieldNumber = 8;
|
||||
private int clone_;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public int Clone_ {
|
||||
get { return clone_; }
|
||||
set {
|
||||
clone_ = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "calculate_size" field.</summary>
|
||||
public const int CalculateSize_FieldNumber = 9;
|
||||
private int calculateSize_;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public int CalculateSize_ {
|
||||
get { return calculateSize_; }
|
||||
set {
|
||||
calculateSize_ = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "merge_from" field.</summary>
|
||||
public const int MergeFrom_FieldNumber = 10;
|
||||
private int mergeFrom_;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public int MergeFrom_ {
|
||||
get { return mergeFrom_; }
|
||||
set {
|
||||
mergeFrom_ = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "on_construction" field.</summary>
|
||||
public const int OnConstruction_FieldNumber = 11;
|
||||
private int onConstruction_;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public int OnConstruction_ {
|
||||
get { return onConstruction_; }
|
||||
set {
|
||||
onConstruction_ = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "parser" field.</summary>
|
||||
public const int Parser_FieldNumber = 12;
|
||||
private int parser_;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public int Parser_ {
|
||||
get { return parser_; }
|
||||
set {
|
||||
parser_ = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public override bool Equals(object other) {
|
||||
return Equals(other as DisambiguateCommonMembers);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public bool Equals(DisambiguateCommonMembers other) {
|
||||
if (ReferenceEquals(other, null)) {
|
||||
return false;
|
||||
}
|
||||
if (ReferenceEquals(other, this)) {
|
||||
return true;
|
||||
}
|
||||
if (DisambiguateCommonMembers_ != other.DisambiguateCommonMembers_) return false;
|
||||
if (Types_ != other.Types_) return false;
|
||||
if (Descriptor_ != other.Descriptor_) return false;
|
||||
if (Equals_ != other.Equals_) return false;
|
||||
if (ToString_ != other.ToString_) return false;
|
||||
if (GetHashCode_ != other.GetHashCode_) return false;
|
||||
if (WriteTo_ != other.WriteTo_) return false;
|
||||
if (Clone_ != other.Clone_) return false;
|
||||
if (CalculateSize_ != other.CalculateSize_) return false;
|
||||
if (MergeFrom_ != other.MergeFrom_) return false;
|
||||
if (OnConstruction_ != other.OnConstruction_) return false;
|
||||
if (Parser_ != other.Parser_) return false;
|
||||
return Equals(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public override int GetHashCode() {
|
||||
int hash = 1;
|
||||
if (DisambiguateCommonMembers_ != 0) hash ^= DisambiguateCommonMembers_.GetHashCode();
|
||||
if (Types_ != 0) hash ^= Types_.GetHashCode();
|
||||
if (Descriptor_ != 0) hash ^= Descriptor_.GetHashCode();
|
||||
if (Equals_ != 0) hash ^= Equals_.GetHashCode();
|
||||
if (ToString_ != 0) hash ^= ToString_.GetHashCode();
|
||||
if (GetHashCode_ != 0) hash ^= GetHashCode_.GetHashCode();
|
||||
if (WriteTo_ != 0) hash ^= WriteTo_.GetHashCode();
|
||||
if (Clone_ != 0) hash ^= Clone_.GetHashCode();
|
||||
if (CalculateSize_ != 0) hash ^= CalculateSize_.GetHashCode();
|
||||
if (MergeFrom_ != 0) hash ^= MergeFrom_.GetHashCode();
|
||||
if (OnConstruction_ != 0) hash ^= OnConstruction_.GetHashCode();
|
||||
if (Parser_ != 0) hash ^= Parser_.GetHashCode();
|
||||
if (_unknownFields != null) {
|
||||
hash ^= _unknownFields.GetHashCode();
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public override string ToString() {
|
||||
return pb::JsonFormatter.ToDiagnosticString(this);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public void WriteTo(pb::CodedOutputStream output) {
|
||||
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
|
||||
output.WriteRawMessage(this);
|
||||
#else
|
||||
if (DisambiguateCommonMembers_ != 0) {
|
||||
output.WriteRawTag(8);
|
||||
output.WriteInt32(DisambiguateCommonMembers_);
|
||||
}
|
||||
if (Types_ != 0) {
|
||||
output.WriteRawTag(16);
|
||||
output.WriteInt32(Types_);
|
||||
}
|
||||
if (Descriptor_ != 0) {
|
||||
output.WriteRawTag(24);
|
||||
output.WriteInt32(Descriptor_);
|
||||
}
|
||||
if (Equals_ != 0) {
|
||||
output.WriteRawTag(32);
|
||||
output.WriteInt32(Equals_);
|
||||
}
|
||||
if (ToString_ != 0) {
|
||||
output.WriteRawTag(40);
|
||||
output.WriteInt32(ToString_);
|
||||
}
|
||||
if (GetHashCode_ != 0) {
|
||||
output.WriteRawTag(48);
|
||||
output.WriteInt32(GetHashCode_);
|
||||
}
|
||||
if (WriteTo_ != 0) {
|
||||
output.WriteRawTag(56);
|
||||
output.WriteInt32(WriteTo_);
|
||||
}
|
||||
if (Clone_ != 0) {
|
||||
output.WriteRawTag(64);
|
||||
output.WriteInt32(Clone_);
|
||||
}
|
||||
if (CalculateSize_ != 0) {
|
||||
output.WriteRawTag(72);
|
||||
output.WriteInt32(CalculateSize_);
|
||||
}
|
||||
if (MergeFrom_ != 0) {
|
||||
output.WriteRawTag(80);
|
||||
output.WriteInt32(MergeFrom_);
|
||||
}
|
||||
if (OnConstruction_ != 0) {
|
||||
output.WriteRawTag(88);
|
||||
output.WriteInt32(OnConstruction_);
|
||||
}
|
||||
if (Parser_ != 0) {
|
||||
output.WriteRawTag(96);
|
||||
output.WriteInt32(Parser_);
|
||||
}
|
||||
if (_unknownFields != null) {
|
||||
_unknownFields.WriteTo(output);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
|
||||
if (DisambiguateCommonMembers_ != 0) {
|
||||
output.WriteRawTag(8);
|
||||
output.WriteInt32(DisambiguateCommonMembers_);
|
||||
}
|
||||
if (Types_ != 0) {
|
||||
output.WriteRawTag(16);
|
||||
output.WriteInt32(Types_);
|
||||
}
|
||||
if (Descriptor_ != 0) {
|
||||
output.WriteRawTag(24);
|
||||
output.WriteInt32(Descriptor_);
|
||||
}
|
||||
if (Equals_ != 0) {
|
||||
output.WriteRawTag(32);
|
||||
output.WriteInt32(Equals_);
|
||||
}
|
||||
if (ToString_ != 0) {
|
||||
output.WriteRawTag(40);
|
||||
output.WriteInt32(ToString_);
|
||||
}
|
||||
if (GetHashCode_ != 0) {
|
||||
output.WriteRawTag(48);
|
||||
output.WriteInt32(GetHashCode_);
|
||||
}
|
||||
if (WriteTo_ != 0) {
|
||||
output.WriteRawTag(56);
|
||||
output.WriteInt32(WriteTo_);
|
||||
}
|
||||
if (Clone_ != 0) {
|
||||
output.WriteRawTag(64);
|
||||
output.WriteInt32(Clone_);
|
||||
}
|
||||
if (CalculateSize_ != 0) {
|
||||
output.WriteRawTag(72);
|
||||
output.WriteInt32(CalculateSize_);
|
||||
}
|
||||
if (MergeFrom_ != 0) {
|
||||
output.WriteRawTag(80);
|
||||
output.WriteInt32(MergeFrom_);
|
||||
}
|
||||
if (OnConstruction_ != 0) {
|
||||
output.WriteRawTag(88);
|
||||
output.WriteInt32(OnConstruction_);
|
||||
}
|
||||
if (Parser_ != 0) {
|
||||
output.WriteRawTag(96);
|
||||
output.WriteInt32(Parser_);
|
||||
}
|
||||
if (_unknownFields != null) {
|
||||
_unknownFields.WriteTo(ref output);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public int CalculateSize() {
|
||||
int size = 0;
|
||||
if (DisambiguateCommonMembers_ != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeInt32Size(DisambiguateCommonMembers_);
|
||||
}
|
||||
if (Types_ != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeInt32Size(Types_);
|
||||
}
|
||||
if (Descriptor_ != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeInt32Size(Descriptor_);
|
||||
}
|
||||
if (Equals_ != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeInt32Size(Equals_);
|
||||
}
|
||||
if (ToString_ != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeInt32Size(ToString_);
|
||||
}
|
||||
if (GetHashCode_ != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeInt32Size(GetHashCode_);
|
||||
}
|
||||
if (WriteTo_ != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeInt32Size(WriteTo_);
|
||||
}
|
||||
if (Clone_ != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeInt32Size(Clone_);
|
||||
}
|
||||
if (CalculateSize_ != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeInt32Size(CalculateSize_);
|
||||
}
|
||||
if (MergeFrom_ != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeInt32Size(MergeFrom_);
|
||||
}
|
||||
if (OnConstruction_ != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeInt32Size(OnConstruction_);
|
||||
}
|
||||
if (Parser_ != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeInt32Size(Parser_);
|
||||
}
|
||||
if (_unknownFields != null) {
|
||||
size += _unknownFields.CalculateSize();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public void MergeFrom(DisambiguateCommonMembers other) {
|
||||
if (other == null) {
|
||||
return;
|
||||
}
|
||||
if (other.DisambiguateCommonMembers_ != 0) {
|
||||
DisambiguateCommonMembers_ = other.DisambiguateCommonMembers_;
|
||||
}
|
||||
if (other.Types_ != 0) {
|
||||
Types_ = other.Types_;
|
||||
}
|
||||
if (other.Descriptor_ != 0) {
|
||||
Descriptor_ = other.Descriptor_;
|
||||
}
|
||||
if (other.Equals_ != 0) {
|
||||
Equals_ = other.Equals_;
|
||||
}
|
||||
if (other.ToString_ != 0) {
|
||||
ToString_ = other.ToString_;
|
||||
}
|
||||
if (other.GetHashCode_ != 0) {
|
||||
GetHashCode_ = other.GetHashCode_;
|
||||
}
|
||||
if (other.WriteTo_ != 0) {
|
||||
WriteTo_ = other.WriteTo_;
|
||||
}
|
||||
if (other.Clone_ != 0) {
|
||||
Clone_ = other.Clone_;
|
||||
}
|
||||
if (other.CalculateSize_ != 0) {
|
||||
CalculateSize_ = other.CalculateSize_;
|
||||
}
|
||||
if (other.MergeFrom_ != 0) {
|
||||
MergeFrom_ = other.MergeFrom_;
|
||||
}
|
||||
if (other.OnConstruction_ != 0) {
|
||||
OnConstruction_ = other.OnConstruction_;
|
||||
}
|
||||
if (other.Parser_ != 0) {
|
||||
Parser_ = other.Parser_;
|
||||
}
|
||||
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
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 8: {
|
||||
DisambiguateCommonMembers_ = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 16: {
|
||||
Types_ = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 24: {
|
||||
Descriptor_ = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 32: {
|
||||
Equals_ = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 40: {
|
||||
ToString_ = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 48: {
|
||||
GetHashCode_ = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 56: {
|
||||
WriteTo_ = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 64: {
|
||||
Clone_ = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 72: {
|
||||
CalculateSize_ = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 80: {
|
||||
MergeFrom_ = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 88: {
|
||||
OnConstruction_ = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 96: {
|
||||
Parser_ = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
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 8: {
|
||||
DisambiguateCommonMembers_ = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 16: {
|
||||
Types_ = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 24: {
|
||||
Descriptor_ = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 32: {
|
||||
Equals_ = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 40: {
|
||||
ToString_ = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 48: {
|
||||
GetHashCode_ = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 56: {
|
||||
WriteTo_ = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 64: {
|
||||
Clone_ = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 72: {
|
||||
CalculateSize_ = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 80: {
|
||||
MergeFrom_ = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 88: {
|
||||
OnConstruction_ = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 96: {
|
||||
Parser_ = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
@@ -3258,24 +3258,24 @@ namespace Google.Protobuf.TestProtos {
|
||||
if (other == null) {
|
||||
return;
|
||||
}
|
||||
anyField_.MergeFrom(other.anyField_);
|
||||
apiField_.MergeFrom(other.apiField_);
|
||||
durationField_.MergeFrom(other.durationField_);
|
||||
emptyField_.MergeFrom(other.emptyField_);
|
||||
fieldMaskField_.MergeFrom(other.fieldMaskField_);
|
||||
sourceContextField_.MergeFrom(other.sourceContextField_);
|
||||
structField_.MergeFrom(other.structField_);
|
||||
timestampField_.MergeFrom(other.timestampField_);
|
||||
typeField_.MergeFrom(other.typeField_);
|
||||
doubleField_.MergeFrom(other.doubleField_);
|
||||
floatField_.MergeFrom(other.floatField_);
|
||||
int64Field_.MergeFrom(other.int64Field_);
|
||||
uint64Field_.MergeFrom(other.uint64Field_);
|
||||
int32Field_.MergeFrom(other.int32Field_);
|
||||
uint32Field_.MergeFrom(other.uint32Field_);
|
||||
boolField_.MergeFrom(other.boolField_);
|
||||
stringField_.MergeFrom(other.stringField_);
|
||||
bytesField_.MergeFrom(other.bytesField_);
|
||||
anyField_.Add(other.anyField_);
|
||||
apiField_.Add(other.apiField_);
|
||||
durationField_.Add(other.durationField_);
|
||||
emptyField_.Add(other.emptyField_);
|
||||
fieldMaskField_.Add(other.fieldMaskField_);
|
||||
sourceContextField_.Add(other.sourceContextField_);
|
||||
structField_.Add(other.structField_);
|
||||
timestampField_.Add(other.timestampField_);
|
||||
typeField_.Add(other.typeField_);
|
||||
doubleField_.Add(other.doubleField_);
|
||||
floatField_.Add(other.floatField_);
|
||||
int64Field_.Add(other.int64Field_);
|
||||
uint64Field_.Add(other.uint64Field_);
|
||||
int32Field_.Add(other.int32Field_);
|
||||
uint32Field_.Add(other.uint32Field_);
|
||||
boolField_.Add(other.boolField_);
|
||||
stringField_.Add(other.stringField_);
|
||||
bytesField_.Add(other.bytesField_);
|
||||
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,9 @@ using System.Buffers;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Runtime.CompilerServices;
|
||||
#if !NET35
|
||||
using System.Threading.Tasks;
|
||||
#endif
|
||||
|
||||
namespace Google.Protobuf
|
||||
{
|
||||
@@ -70,7 +72,7 @@ namespace Google.Protobuf
|
||||
Assert.IsFalse(b1 != b1);
|
||||
Assert.IsFalse(b1 != b2);
|
||||
Assert.IsTrue(ByteString.Empty == ByteString.Empty);
|
||||
#pragma warning restore 1718
|
||||
#pragma warning disable 1718
|
||||
Assert.IsTrue(b1 != b3);
|
||||
Assert.IsTrue(b1 != b4);
|
||||
Assert.IsTrue(b1 != null);
|
||||
@@ -276,9 +278,12 @@ namespace Google.Protobuf
|
||||
Span<byte> s = stackalloc byte[data.Length];
|
||||
data.CopyTo(s);
|
||||
|
||||
using var manager = new UnmanagedMemoryManager<byte>(s);
|
||||
ByteString bs = ByteString.AttachBytes(manager.Memory);
|
||||
Assert.AreEqual("Hello world", bs.ToString(Encoding.UTF8));
|
||||
using (UnmanagedMemoryManager<byte> manager = new UnmanagedMemoryManager<byte>(s))
|
||||
{
|
||||
ByteString bs = ByteString.AttachBytes(manager.Memory);
|
||||
|
||||
Assert.AreEqual("Hello world", bs.ToString(Encoding.UTF8));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -312,9 +317,12 @@ namespace Google.Protobuf
|
||||
Span<byte> s = stackalloc byte[data.Length];
|
||||
data.CopyTo(s);
|
||||
|
||||
using var manager = new UnmanagedMemoryManager<byte>(s);
|
||||
ByteString bs = ByteString.AttachBytes(manager.Memory);
|
||||
Assert.AreEqual("SGVsbG8gd29ybGQ=", bs.ToBase64());
|
||||
using (UnmanagedMemoryManager<byte> manager = new UnmanagedMemoryManager<byte>(s))
|
||||
{
|
||||
ByteString bs = ByteString.AttachBytes(manager.Memory);
|
||||
|
||||
Assert.AreEqual("SGVsbG8gd29ybGQ=", bs.ToBase64());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -341,6 +349,7 @@ namespace Google.Protobuf
|
||||
Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
|
||||
}
|
||||
|
||||
#if !NET35
|
||||
[Test]
|
||||
public async Task FromStreamAsync_Seekable()
|
||||
{
|
||||
@@ -364,6 +373,7 @@ namespace Google.Protobuf
|
||||
ByteString expected = ByteString.CopyFrom(2, 3, 4);
|
||||
Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
|
||||
}
|
||||
#endif
|
||||
|
||||
[Test]
|
||||
public void GetHashCode_Regression()
|
||||
|
||||
@@ -563,8 +563,8 @@ namespace Google.Protobuf
|
||||
int groupFieldNumber = Proto2.TestAllTypes.OptionalGroupFieldNumber;
|
||||
|
||||
// write Proto2.TestAllTypes with "optional_group" set, but use wrong EndGroup closing tag
|
||||
var ms = new MemoryStream();
|
||||
var output = new CodedOutputStream(ms);
|
||||
MemoryStream ms = new MemoryStream();
|
||||
CodedOutputStream output = new CodedOutputStream(ms);
|
||||
output.WriteTag(WireFormat.MakeTag(groupFieldNumber, WireFormat.WireType.StartGroup));
|
||||
output.WriteGroup(new Proto2.TestAllTypes.Types.OptionalGroup { A = 12345 });
|
||||
// end group with different field number
|
||||
@@ -578,8 +578,8 @@ namespace Google.Protobuf
|
||||
[Test]
|
||||
public void ReadGroup_UnknownFields_WrongEndGroupTag()
|
||||
{
|
||||
var ms = new MemoryStream();
|
||||
var output = new CodedOutputStream(ms);
|
||||
MemoryStream ms = new MemoryStream();
|
||||
CodedOutputStream output = new CodedOutputStream(ms);
|
||||
output.WriteTag(WireFormat.MakeTag(14, WireFormat.WireType.StartGroup));
|
||||
// end group with different field number
|
||||
output.WriteTag(WireFormat.MakeTag(15, WireFormat.WireType.EndGroup));
|
||||
@@ -654,7 +654,7 @@ namespace Google.Protobuf
|
||||
output.Flush();
|
||||
ms.Position = 0;
|
||||
|
||||
var input = new CodedInputStream(ms);
|
||||
CodedInputStream input = new CodedInputStream(ms);
|
||||
|
||||
Assert.AreEqual(tag, input.ReadTag());
|
||||
Assert.Throws<InvalidProtocolBufferException>(() => input.ReadBytes());
|
||||
@@ -694,24 +694,26 @@ namespace Google.Protobuf
|
||||
[Test]
|
||||
public void TestSlowPathAvoidance()
|
||||
{
|
||||
using var ms = new MemoryStream();
|
||||
var output = new CodedOutputStream(ms);
|
||||
output.WriteTag(1, WireFormat.WireType.LengthDelimited);
|
||||
output.WriteBytes(ByteString.CopyFrom(new byte[100]));
|
||||
output.WriteTag(2, WireFormat.WireType.LengthDelimited);
|
||||
output.WriteBytes(ByteString.CopyFrom(new byte[100]));
|
||||
output.Flush();
|
||||
using (var ms = new MemoryStream())
|
||||
{
|
||||
CodedOutputStream output = new CodedOutputStream(ms);
|
||||
output.WriteTag(1, WireFormat.WireType.LengthDelimited);
|
||||
output.WriteBytes(ByteString.CopyFrom(new byte[100]));
|
||||
output.WriteTag(2, WireFormat.WireType.LengthDelimited);
|
||||
output.WriteBytes(ByteString.CopyFrom(new byte[100]));
|
||||
output.Flush();
|
||||
|
||||
ms.Position = 0;
|
||||
CodedInputStream input = new CodedInputStream(ms, new byte[ms.Length / 2], 0, 0, false);
|
||||
ms.Position = 0;
|
||||
CodedInputStream input = new CodedInputStream(ms, new byte[ms.Length / 2], 0, 0, false);
|
||||
|
||||
uint tag = input.ReadTag();
|
||||
Assert.AreEqual(1, WireFormat.GetTagFieldNumber(tag));
|
||||
Assert.AreEqual(100, input.ReadBytes().Length);
|
||||
uint tag = input.ReadTag();
|
||||
Assert.AreEqual(1, WireFormat.GetTagFieldNumber(tag));
|
||||
Assert.AreEqual(100, input.ReadBytes().Length);
|
||||
|
||||
tag = input.ReadTag();
|
||||
Assert.AreEqual(2, WireFormat.GetTagFieldNumber(tag));
|
||||
Assert.AreEqual(100, input.ReadBytes().Length);
|
||||
tag = input.ReadTag();
|
||||
Assert.AreEqual(2, WireFormat.GetTagFieldNumber(tag));
|
||||
Assert.AreEqual(100, input.ReadBytes().Length);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -925,11 +927,13 @@ namespace Google.Protobuf
|
||||
{
|
||||
byte[] serializedMessage = GenerateBigSerializedMessage();
|
||||
// How many of these big messages do we need to take us near our 2GB limit?
|
||||
int count = int.MaxValue / serializedMessage.Length;
|
||||
int count = Int32.MaxValue / serializedMessage.Length;
|
||||
// Now make a MemoryStream that will fake a near-2GB stream of messages by returning
|
||||
// our big serialized message 'count' times.
|
||||
using var stream = new RepeatingMemoryStream(serializedMessage, count);
|
||||
Assert.DoesNotThrow(() => TestAllTypes.Parser.ParseFrom(stream));
|
||||
using (RepeatingMemoryStream stream = new RepeatingMemoryStream(serializedMessage, count))
|
||||
{
|
||||
Assert.DoesNotThrow(()=>TestAllTypes.Parser.ParseFrom(stream));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -937,15 +941,17 @@ namespace Google.Protobuf
|
||||
{
|
||||
byte[] serializedMessage = GenerateBigSerializedMessage();
|
||||
// How many of these big messages do we need to take us near our 2GB limit?
|
||||
int count = int.MaxValue / serializedMessage.Length;
|
||||
int count = Int32.MaxValue / serializedMessage.Length;
|
||||
// Now add one to take us over the 2GB limit
|
||||
count++;
|
||||
// Now make a MemoryStream that will fake a near-2GB stream of messages by returning
|
||||
// our big serialized message 'count' times.
|
||||
using var stream = new RepeatingMemoryStream(serializedMessage, count);
|
||||
Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(stream),
|
||||
"Protocol message was too large. May be malicious. " +
|
||||
"Use CodedInputStream.SetSizeLimit() to increase the size limit.");
|
||||
using (RepeatingMemoryStream stream = new RepeatingMemoryStream(serializedMessage, count))
|
||||
{
|
||||
Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(stream),
|
||||
"Protocol message was too large. May be malicious. " +
|
||||
"Use CodedInputStream.SetSizeLimit() to increase the size limit.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <returns>A serialized big message</returns>
|
||||
|
||||
@@ -94,12 +94,14 @@ namespace Google.Protobuf
|
||||
if ((value >> 32) == 0)
|
||||
{
|
||||
MemoryStream rawOutput = new MemoryStream();
|
||||
CodedOutputStream output = new CodedOutputStream(rawOutput, bufferSize);
|
||||
CodedOutputStream output =
|
||||
new CodedOutputStream(rawOutput, bufferSize);
|
||||
output.WriteRawVarint32((uint) value);
|
||||
output.Flush();
|
||||
Assert.AreEqual(data, rawOutput.ToArray());
|
||||
|
||||
var bufferWriter = new TestArrayBufferWriter<byte> { MaxGrowBy = bufferSize };
|
||||
var bufferWriter = new TestArrayBufferWriter<byte>();
|
||||
bufferWriter.MaxGrowBy = bufferSize;
|
||||
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
|
||||
ctx.WriteUInt32((uint) value);
|
||||
ctx.Flush();
|
||||
@@ -113,7 +115,8 @@ namespace Google.Protobuf
|
||||
output.Flush();
|
||||
Assert.AreEqual(data, rawOutput.ToArray());
|
||||
|
||||
var bufferWriter = new TestArrayBufferWriter<byte> { MaxGrowBy = bufferSize };
|
||||
var bufferWriter = new TestArrayBufferWriter<byte>();
|
||||
bufferWriter.MaxGrowBy = bufferSize;
|
||||
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
|
||||
ctx.WriteUInt64(value);
|
||||
ctx.Flush();
|
||||
@@ -187,7 +190,8 @@ namespace Google.Protobuf
|
||||
output.Flush();
|
||||
Assert.AreEqual(data, rawOutput.ToArray());
|
||||
|
||||
var bufferWriter = new TestArrayBufferWriter<byte> { MaxGrowBy = bufferSize };
|
||||
var bufferWriter = new TestArrayBufferWriter<byte>();
|
||||
bufferWriter.MaxGrowBy = bufferSize;
|
||||
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
|
||||
ctx.WriteFixed32(value);
|
||||
ctx.Flush();
|
||||
@@ -224,7 +228,8 @@ namespace Google.Protobuf
|
||||
output.Flush();
|
||||
Assert.AreEqual(data, rawOutput.ToArray());
|
||||
|
||||
var bufferWriter = new TestArrayBufferWriter<byte> { MaxGrowBy = blockSize };
|
||||
var bufferWriter = new TestArrayBufferWriter<byte>();
|
||||
bufferWriter.MaxGrowBy = blockSize;
|
||||
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
|
||||
ctx.WriteFixed64(value);
|
||||
ctx.Flush();
|
||||
@@ -265,7 +270,8 @@ namespace Google.Protobuf
|
||||
output.Flush();
|
||||
Assert.AreEqual(rawBytes, rawOutput.ToArray());
|
||||
|
||||
var bufferWriter = new TestArrayBufferWriter<byte> { MaxGrowBy = blockSize };
|
||||
var bufferWriter = new TestArrayBufferWriter<byte>();
|
||||
bufferWriter.MaxGrowBy = blockSize;
|
||||
message.WriteTo(bufferWriter);
|
||||
Assert.AreEqual(rawBytes, bufferWriter.WrittenSpan.ToArray());
|
||||
}
|
||||
@@ -377,9 +383,7 @@ namespace Google.Protobuf
|
||||
{
|
||||
byte[] content = new byte[110];
|
||||
for (int i = 0; i < content.Length; i++)
|
||||
{
|
||||
content[i] = (byte)i;
|
||||
}
|
||||
|
||||
byte[] child = new byte[120];
|
||||
{
|
||||
|
||||
@@ -91,12 +91,10 @@ namespace Google.Protobuf.Collections
|
||||
[Test]
|
||||
public void AddPreservesInsertionOrder()
|
||||
{
|
||||
var map = new MapField<string, string>
|
||||
{
|
||||
{ "a", "v1" },
|
||||
{ "b", "v2" },
|
||||
{ "c", "v3" }
|
||||
};
|
||||
var map = new MapField<string, string>();
|
||||
map.Add("a", "v1");
|
||||
map.Add("b", "v2");
|
||||
map.Add("c", "v3");
|
||||
map.Remove("b");
|
||||
map.Add("d", "v4");
|
||||
CollectionAssert.AreEqual(new[] { "a", "c", "d" }, map.Keys);
|
||||
@@ -106,17 +104,13 @@ namespace Google.Protobuf.Collections
|
||||
[Test]
|
||||
public void EqualityIsOrderInsensitive()
|
||||
{
|
||||
var map1 = new MapField<string, string>
|
||||
{
|
||||
{ "a", "v1" },
|
||||
{ "b", "v2" }
|
||||
};
|
||||
var map1 = new MapField<string, string>();
|
||||
map1.Add("a", "v1");
|
||||
map1.Add("b", "v2");
|
||||
|
||||
var map2 = new MapField<string, string>
|
||||
{
|
||||
{ "b", "v2" },
|
||||
{ "a", "v1" }
|
||||
};
|
||||
var map2 = new MapField<string, string>();
|
||||
map2.Add("b", "v2");
|
||||
map2.Add("a", "v1");
|
||||
|
||||
EqualityTester.AssertEquality(map1, map2);
|
||||
}
|
||||
@@ -124,17 +118,13 @@ namespace Google.Protobuf.Collections
|
||||
[Test]
|
||||
public void EqualityIsKeySensitive()
|
||||
{
|
||||
var map1 = new MapField<string, string>
|
||||
{
|
||||
{ "first key", "v1" },
|
||||
{ "second key", "v2" }
|
||||
};
|
||||
var map1 = new MapField<string, string>();
|
||||
map1.Add("first key", "v1");
|
||||
map1.Add("second key", "v2");
|
||||
|
||||
var map2 = new MapField<string, string>
|
||||
{
|
||||
{ "third key", "v1" },
|
||||
{ "fourth key", "v2" }
|
||||
};
|
||||
var map2 = new MapField<string, string>();
|
||||
map2.Add("third key", "v1");
|
||||
map2.Add("fourth key", "v2");
|
||||
|
||||
EqualityTester.AssertInequality(map1, map2);
|
||||
}
|
||||
@@ -153,17 +143,13 @@ namespace Google.Protobuf.Collections
|
||||
{
|
||||
// Note: Without some care, it's a little easier than one might
|
||||
// hope to see hash collisions, but only in some environments...
|
||||
var map1 = new MapField<string, string>
|
||||
{
|
||||
{ "a", "first value" },
|
||||
{ "b", "second value" }
|
||||
};
|
||||
var map1 = new MapField<string, string>();
|
||||
map1.Add("a", "first value");
|
||||
map1.Add("b", "second value");
|
||||
|
||||
var map2 = new MapField<string, string>
|
||||
{
|
||||
{ "a", "third value" },
|
||||
{ "b", "fourth value" }
|
||||
};
|
||||
var map2 = new MapField<string, string>();
|
||||
map2.Add("a", "third value");
|
||||
map2.Add("b", "fourth value");
|
||||
|
||||
EqualityTester.AssertInequality(map1, map2);
|
||||
}
|
||||
@@ -197,7 +183,8 @@ namespace Google.Protobuf.Collections
|
||||
[Test]
|
||||
public void Add_KeyAlreadyExists()
|
||||
{
|
||||
var map = new MapField<string, string> { { "foo", "bar" } };
|
||||
var map = new MapField<string, string>();
|
||||
map.Add("foo", "bar");
|
||||
Assert.Throws<ArgumentException>(() => map.Add("foo", "baz"));
|
||||
}
|
||||
|
||||
@@ -224,7 +211,8 @@ namespace Google.Protobuf.Collections
|
||||
[Test]
|
||||
public void Remove_Key()
|
||||
{
|
||||
var map = new MapField<string, string> { { "foo", "bar" } };
|
||||
var map = new MapField<string, string>();
|
||||
map.Add("foo", "bar");
|
||||
Assert.AreEqual(1, map.Count);
|
||||
Assert.IsFalse(map.Remove("missing"));
|
||||
Assert.AreEqual(1, map.Count);
|
||||
@@ -236,7 +224,8 @@ namespace Google.Protobuf.Collections
|
||||
[Test]
|
||||
public void Remove_Pair()
|
||||
{
|
||||
var map = new MapField<string, string> { { "foo", "bar" } };
|
||||
var map = new MapField<string, string>();
|
||||
map.Add("foo", "bar");
|
||||
ICollection<KeyValuePair<string, string>> collection = map;
|
||||
Assert.AreEqual(1, map.Count);
|
||||
Assert.IsFalse(collection.Remove(NewKeyValuePair("wrong key", "bar")));
|
||||
@@ -251,7 +240,8 @@ namespace Google.Protobuf.Collections
|
||||
[Test]
|
||||
public void CopyTo_Pair()
|
||||
{
|
||||
var map = new MapField<string, string> { { "foo", "bar" } };
|
||||
var map = new MapField<string, string>();
|
||||
map.Add("foo", "bar");
|
||||
ICollection<KeyValuePair<string, string>> collection = map;
|
||||
KeyValuePair<string, string>[] array = new KeyValuePair<string, string>[3];
|
||||
collection.CopyTo(array, 1);
|
||||
@@ -280,7 +270,8 @@ namespace Google.Protobuf.Collections
|
||||
[Test]
|
||||
public void Indexer_Set()
|
||||
{
|
||||
var map = new MapField<string, string> { ["x"] = "y" };
|
||||
var map = new MapField<string, string>();
|
||||
map["x"] = "y";
|
||||
Assert.AreEqual("y", map["x"]);
|
||||
map["x"] = "z"; // This won't throw, unlike Add.
|
||||
Assert.AreEqual("z", map["x"]);
|
||||
@@ -366,10 +357,12 @@ namespace Google.Protobuf.Collections
|
||||
IDictionary dictionary = map;
|
||||
var array = new DictionaryEntry[3];
|
||||
dictionary.CopyTo(array, 1);
|
||||
CollectionAssert.AreEqual(new[] { default, new DictionaryEntry("x", "y"), default }, array);
|
||||
CollectionAssert.AreEqual(new[] { default(DictionaryEntry), new DictionaryEntry("x", "y"), default(DictionaryEntry) },
|
||||
array);
|
||||
var objectArray = new object[3];
|
||||
dictionary.CopyTo(objectArray, 1);
|
||||
CollectionAssert.AreEqual(new object[] { null, new DictionaryEntry("x", "y"), null }, objectArray);
|
||||
CollectionAssert.AreEqual(new object[] { null, new DictionaryEntry("x", "y"), null },
|
||||
objectArray);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -587,7 +580,8 @@ namespace Google.Protobuf.Collections
|
||||
};
|
||||
Assert.AreEqual("x", map[SampleNaNs.Regular]);
|
||||
Assert.AreEqual("y", map[SampleNaNs.SignallingFlipped]);
|
||||
Assert.False(map.TryGetValue(SampleNaNs.PayloadFlipped, out _));
|
||||
string ignored;
|
||||
Assert.False(map.TryGetValue(SampleNaNs.PayloadFlipped, out ignored));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -641,6 +635,7 @@ namespace Google.Protobuf.Collections
|
||||
Assert.IsTrue(input.IsAtEnd);
|
||||
}
|
||||
|
||||
#if !NET35
|
||||
[Test]
|
||||
public void IDictionaryKeys_Equals_IReadOnlyDictionaryKeys()
|
||||
{
|
||||
@@ -654,6 +649,7 @@ namespace Google.Protobuf.Collections
|
||||
var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
|
||||
CollectionAssert.AreEquivalent(((IDictionary<string, string>)map).Values, ((IReadOnlyDictionary<string, string>)map).Values);
|
||||
}
|
||||
#endif
|
||||
|
||||
private static KeyValuePair<TKey, TValue> NewKeyValuePair<TKey, TValue>(TKey key, TValue value)
|
||||
{
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -58,7 +59,8 @@ namespace Google.Protobuf.Collections
|
||||
[Test]
|
||||
public void Add_SingleItem()
|
||||
{
|
||||
var list = new RepeatedField<string> { "foo" };
|
||||
var list = new RepeatedField<string>();
|
||||
list.Add("foo");
|
||||
Assert.AreEqual(1, list.Count);
|
||||
Assert.AreEqual("foo", list[0]);
|
||||
}
|
||||
@@ -66,7 +68,8 @@ namespace Google.Protobuf.Collections
|
||||
[Test]
|
||||
public void Add_Sequence()
|
||||
{
|
||||
var list = new RepeatedField<string> { new[] { "foo", "bar" } };
|
||||
var list = new RepeatedField<string>();
|
||||
list.Add(new[] { "foo", "bar" });
|
||||
Assert.AreEqual(2, list.Count);
|
||||
Assert.AreEqual("foo", list[0]);
|
||||
Assert.AreEqual("bar", list[1]);
|
||||
@@ -290,13 +293,15 @@ namespace Google.Protobuf.Collections
|
||||
public void Enumerator()
|
||||
{
|
||||
var list = new RepeatedField<string> { "first", "second" };
|
||||
using var enumerator = list.GetEnumerator();
|
||||
Assert.IsTrue(enumerator.MoveNext());
|
||||
Assert.AreEqual("first", enumerator.Current);
|
||||
Assert.IsTrue(enumerator.MoveNext());
|
||||
Assert.AreEqual("second", enumerator.Current);
|
||||
Assert.IsFalse(enumerator.MoveNext());
|
||||
Assert.IsFalse(enumerator.MoveNext());
|
||||
using (var enumerator = list.GetEnumerator())
|
||||
{
|
||||
Assert.IsTrue(enumerator.MoveNext());
|
||||
Assert.AreEqual("first", enumerator.Current);
|
||||
Assert.IsTrue(enumerator.MoveNext());
|
||||
Assert.AreEqual("second", enumerator.Current);
|
||||
Assert.IsFalse(enumerator.MoveNext());
|
||||
Assert.IsFalse(enumerator.MoveNext());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -888,17 +893,5 @@ namespace Google.Protobuf.Collections
|
||||
Assert.DoesNotThrow(() => list.Capacity = 0, "Can set Capacity to 0");
|
||||
Assert.AreEqual(0, list.Capacity);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Clear_CapacityUnaffected()
|
||||
{
|
||||
var list = new RepeatedField<int> { 1 };
|
||||
Assert.AreEqual(1, list.Count);
|
||||
Assert.AreEqual(8, list.Capacity);
|
||||
|
||||
list.Clear();
|
||||
Assert.AreEqual(0, list.Count);
|
||||
Assert.AreEqual(8, list.Capacity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
#region Copyright notice and license
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2015 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#endregion
|
||||
|
||||
#if NET35
|
||||
using System;
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
using Google.Protobuf.Compatibility;
|
||||
|
||||
namespace Google.Protobuf.Test.Compatibility
|
||||
{
|
||||
public class StreamExtensionsTest
|
||||
{
|
||||
[Test]
|
||||
public void CopyToNullArgument()
|
||||
{
|
||||
var memoryStream = new MemoryStream();
|
||||
Assert.Throws<ArgumentNullException>(() => memoryStream.CopyTo(null));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopyToTest()
|
||||
{
|
||||
byte[] bytesToStream = new byte[] { 0x31, 0x08, 0xFF, 0x00 };
|
||||
Stream source = new MemoryStream(bytesToStream);
|
||||
Stream destination = new MemoryStream((int)source.Length);
|
||||
source.CopyTo(destination);
|
||||
destination.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
Assert.AreEqual(0x31, destination.ReadByte());
|
||||
Assert.AreEqual(0x08, destination.ReadByte());
|
||||
Assert.AreEqual(0xFF, destination.ReadByte());
|
||||
Assert.AreEqual(0x00, destination.ReadByte());
|
||||
Assert.AreEqual(-1, destination.ReadByte());
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -29,12 +29,12 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#endregion
|
||||
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
#if !NET35
|
||||
namespace Google.Protobuf.Compatibility
|
||||
{
|
||||
public class TypeExtensionsTest
|
||||
@@ -114,3 +114,4 @@ namespace Google.Protobuf.Compatibility
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -34,9 +34,7 @@ using System;
|
||||
using System.Reflection;
|
||||
using Google.Protobuf.TestProtos;
|
||||
using NUnit.Framework;
|
||||
using UnitTest.Issues.TestProtos;
|
||||
|
||||
#pragma warning disable CS0612 // Type or member is obsolete
|
||||
namespace Google.Protobuf
|
||||
{
|
||||
public class DeprecatedMemberTest
|
||||
@@ -48,20 +46,10 @@ namespace Google.Protobuf
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDepreatedPrimitiveValue() =>
|
||||
AssertIsDeprecated(typeof(TestDeprecatedFields).GetProperty(nameof(TestDeprecatedFields.DeprecatedInt32)));
|
||||
public void TestDepreatedPrimitiveValue()
|
||||
{
|
||||
AssertIsDeprecated(typeof(TestDeprecatedFields).GetProperty("DeprecatedInt32"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDeprecatedMessage() =>
|
||||
AssertIsDeprecated(typeof(DeprecatedChild));
|
||||
|
||||
[Test]
|
||||
public void TestDeprecatedEnum() =>
|
||||
AssertIsDeprecated(typeof(DeprecatedEnum));
|
||||
|
||||
[Test]
|
||||
public void TestDeprecatedEnumValue() =>
|
||||
AssertIsDeprecated(typeof(DeprecatedEnum).GetField(nameof(DeprecatedEnum.DeprecatedZero)));
|
||||
}
|
||||
}
|
||||
#pragma warning restore CS0612 // Type or member is obsolete
|
||||
|
||||
@@ -1,35 +1,3 @@
|
||||
#region Copyright notice and license
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2015 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Google.Protobuf.TestProtos.Proto2;
|
||||
@@ -104,7 +72,7 @@ namespace Google.Protobuf
|
||||
message.SetExtension(OptionalStringExtension, "abcd");
|
||||
|
||||
var input = new CodedInputStream(message.ToByteArray());
|
||||
input.ExtensionRegistry = new ExtensionRegistry { OptionalStringExtension };
|
||||
input.ExtensionRegistry = new ExtensionRegistry() { OptionalStringExtension };
|
||||
input.ReadTag(); // TryMergeFieldFrom expects that a tag was just read and will inspect the LastTag value
|
||||
|
||||
ExtensionSet<TestAllExtensions> extensionSet = null;
|
||||
|
||||
@@ -169,6 +169,7 @@ namespace Google.Protobuf
|
||||
// WriteTagAndValue ignores default values
|
||||
var stream = new MemoryStream();
|
||||
CodedOutputStream codedOutput;
|
||||
#if !NET35
|
||||
codedOutput = new CodedOutputStream(stream);
|
||||
codec.WriteTagAndValue(codedOutput, codec.DefaultValue);
|
||||
codedOutput.Flush();
|
||||
@@ -178,6 +179,7 @@ namespace Google.Protobuf
|
||||
{
|
||||
Assert.AreEqual(default(T), codec.DefaultValue);
|
||||
}
|
||||
#endif
|
||||
|
||||
// The plain ValueWriter/ValueReader delegates don't.
|
||||
if (codec.DefaultValue != null) // This part isn't appropriate for message types.
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Google.Protobuf.Collections;
|
||||
using Google.Protobuf.TestProtos;
|
||||
using NUnit.Framework;
|
||||
@@ -431,89 +432,5 @@ namespace Google.Protobuf
|
||||
Assert.IsNotNull(destination.Payload);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MergeWrapperFieldsWithNonNullFieldsInSource()
|
||||
{
|
||||
// Instantiate a destination with wrapper-based field types.
|
||||
var destination = new TestWellKnownTypes()
|
||||
{
|
||||
StringField = "Hello",
|
||||
Int32Field = 12,
|
||||
Int64Field = 24,
|
||||
BoolField = true,
|
||||
};
|
||||
|
||||
// Set up a targeted update.
|
||||
var source = new TestWellKnownTypes()
|
||||
{
|
||||
StringField = "Hi",
|
||||
Int64Field = 240
|
||||
};
|
||||
|
||||
Merge(new FieldMaskTree().AddFieldPath("string_field").AddFieldPath("int64_field"),
|
||||
source,
|
||||
destination,
|
||||
new FieldMask.MergeOptions(),
|
||||
false);
|
||||
|
||||
// Make sure the targeted fields changed.
|
||||
Assert.AreEqual("Hi", destination.StringField);
|
||||
Assert.AreEqual(240, destination.Int64Field);
|
||||
|
||||
// Prove that non-targeted fields stay intact...
|
||||
Assert.AreEqual(12, destination.Int32Field);
|
||||
Assert.IsTrue(destination.BoolField);
|
||||
|
||||
// ...including default values which were not explicitly set in the destination object.
|
||||
Assert.IsNull(destination.FloatField);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase(false, "Hello", 24)]
|
||||
[TestCase(true, null, null)]
|
||||
public void MergeWrapperFieldsWithNullFieldsInSource(
|
||||
bool replaceMessageFields,
|
||||
string expectedStringValue,
|
||||
long? expectedInt64Value)
|
||||
{
|
||||
// Instantiate a destination with wrapper-based field types.
|
||||
var destination = new TestWellKnownTypes()
|
||||
{
|
||||
StringField = "Hello",
|
||||
Int32Field = 12,
|
||||
Int64Field = 24,
|
||||
BoolField = true,
|
||||
};
|
||||
|
||||
// Set up a targeted update with null valued fields.
|
||||
var source = new TestWellKnownTypes()
|
||||
{
|
||||
StringField = null,
|
||||
Int64Field = null
|
||||
};
|
||||
|
||||
Merge(new FieldMaskTree().AddFieldPath("string_field").AddFieldPath("int64_field"),
|
||||
source,
|
||||
destination,
|
||||
new FieldMask.MergeOptions()
|
||||
{
|
||||
ReplaceMessageFields = replaceMessageFields
|
||||
},
|
||||
false);
|
||||
|
||||
// Make sure the targeted fields changed according to our expectations, depending on the value of ReplaceMessageFields.
|
||||
// When ReplaceMessageFields is false, the null values are not applied to the destination, because, although wrapped types
|
||||
// are semantically primitives, FieldMaskTree.Merge still treats them as message types in order to maintain consistency with other Protobuf
|
||||
// libraries such as Java and C++.
|
||||
Assert.AreEqual(expectedStringValue, destination.StringField);
|
||||
Assert.AreEqual(expectedInt64Value, destination.Int64Field);
|
||||
|
||||
// Prove that non-targeted fields stay intact...
|
||||
Assert.AreEqual(12, destination.Int32Field);
|
||||
Assert.IsTrue(destination.BoolField);
|
||||
|
||||
// ...including default values which were not explicitly set in the destination object.
|
||||
Assert.IsNull(destination.FloatField);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +1,3 @@
|
||||
#region Copyright notice and license
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2015 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#endregion
|
||||
|
||||
using Google.Protobuf.TestProtos.Proto2;
|
||||
using Proto2 = Google.Protobuf.TestProtos.Proto2;
|
||||
using NUnit.Framework;
|
||||
@@ -419,9 +387,11 @@ namespace Google.Protobuf
|
||||
var message = new TestAllExtensions();
|
||||
message.SetExtension(UnittestExtensions.OptionalBoolExtension, true);
|
||||
byte[] bytes = message.ToByteArray();
|
||||
using CodedInputStream input = new CodedInputStream(bytes);
|
||||
var parsed = TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry() { UnittestExtensions.OptionalBoolExtension }).ParseFrom(input);
|
||||
Assert.AreEqual(message, parsed);
|
||||
using (CodedInputStream input = new CodedInputStream(bytes))
|
||||
{
|
||||
var parsed = TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry() { UnittestExtensions.OptionalBoolExtension }).ParseFrom(input);
|
||||
Assert.AreEqual(message, parsed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,10 +33,12 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Google.Protobuf.TestProtos;
|
||||
using Proto2 = Google.Protobuf.TestProtos.Proto2;
|
||||
using NUnit.Framework;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
using Google.Protobuf.Collections;
|
||||
|
||||
namespace Google.Protobuf
|
||||
{
|
||||
@@ -656,11 +658,9 @@ namespace Google.Protobuf
|
||||
[Test]
|
||||
public void OneofSerialization_NonDefaultValue()
|
||||
{
|
||||
var message = new TestAllTypes
|
||||
{
|
||||
OneofString = "this would take a bit of space",
|
||||
OneofUint32 = 10
|
||||
};
|
||||
var message = new TestAllTypes();
|
||||
message.OneofString = "this would take a bit of space";
|
||||
message.OneofUint32 = 10;
|
||||
var bytes = message.ToByteArray();
|
||||
Assert.AreEqual(3, bytes.Length); // 2 bytes for the tag + 1 for the value - no string!
|
||||
|
||||
@@ -675,11 +675,9 @@ namespace Google.Protobuf
|
||||
[Test]
|
||||
public void OneofSerialization_DefaultValue()
|
||||
{
|
||||
var message = new TestAllTypes
|
||||
{
|
||||
OneofString = "this would take a bit of space",
|
||||
OneofUint32 = 0 // This is the default value for UInt32; normally wouldn't be serialized
|
||||
};
|
||||
var message = new TestAllTypes();
|
||||
message.OneofString = "this would take a bit of space";
|
||||
message.OneofUint32 = 0; // This is the default value for UInt32; normally wouldn't be serialized
|
||||
var bytes = message.ToByteArray();
|
||||
Assert.AreEqual(3, bytes.Length); // 2 bytes for the tag + 1 for the value - it's still serialized
|
||||
|
||||
@@ -748,6 +746,7 @@ namespace Google.Protobuf
|
||||
[Test]
|
||||
public void ExtraEndGroupThrows()
|
||||
{
|
||||
var message = SampleMessages.CreateFullTestAllTypes();
|
||||
var stream = new MemoryStream();
|
||||
var output = new CodedOutputStream(stream);
|
||||
|
||||
@@ -796,44 +795,5 @@ namespace Google.Protobuf
|
||||
EqualityTester.AssertInequality(message1, message2);
|
||||
EqualityTester.AssertEquality(message1, message3);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase(false)]
|
||||
[TestCase(true)]
|
||||
public void MapFieldMerging(bool direct)
|
||||
{
|
||||
var message1 = new TestMap
|
||||
{
|
||||
MapStringString =
|
||||
{
|
||||
{ "x1", "y1" },
|
||||
{ "common", "message1" }
|
||||
}
|
||||
};
|
||||
var message2 = new TestMap
|
||||
{
|
||||
MapStringString =
|
||||
{
|
||||
{ "x2", "y2" },
|
||||
{ "common", "message2" }
|
||||
}
|
||||
};
|
||||
if (direct)
|
||||
{
|
||||
message1.MergeFrom(message2);
|
||||
}
|
||||
else
|
||||
{
|
||||
message1.MergeFrom(message2.ToByteArray());
|
||||
}
|
||||
|
||||
var expected = new MapField<string, string>
|
||||
{
|
||||
{ "x1", "y1" },
|
||||
{ "x2", "y2" },
|
||||
{ "common", "message2" }
|
||||
};
|
||||
Assert.AreEqual(expected, message1.MapStringString);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
#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 Google.Protobuf.Reflection;
|
||||
using NUnit.Framework;
|
||||
|
||||
// For WrapInQuotes
|
||||
|
||||
namespace Google.Protobuf
|
||||
{
|
||||
public class JsonFormatterSettingsTest
|
||||
{
|
||||
[Test]
|
||||
public void WithIndentation()
|
||||
{
|
||||
var settings = JsonFormatter.Settings.Default.WithIndentation("\t");
|
||||
Assert.AreEqual("\t", settings.Indentation);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WithTypeRegistry()
|
||||
{
|
||||
var typeRegistry = TypeRegistry.Empty;
|
||||
var settings = JsonFormatter.Settings.Default.WithTypeRegistry(typeRegistry);
|
||||
Assert.AreEqual(typeRegistry, settings.TypeRegistry);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WithFormatDefaultValues()
|
||||
{
|
||||
var settingsWith = JsonFormatter.Settings.Default.WithFormatDefaultValues(true);
|
||||
Assert.AreEqual(true, settingsWith.FormatDefaultValues);
|
||||
|
||||
var settingsWithout = JsonFormatter.Settings.Default.WithFormatDefaultValues(false);
|
||||
Assert.AreEqual(false, settingsWithout.FormatDefaultValues);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WithFormatEnumsAsIntegers()
|
||||
{
|
||||
var settingsWith = JsonFormatter.Settings.Default.WithFormatEnumsAsIntegers(true);
|
||||
Assert.AreEqual(true, settingsWith.FormatEnumsAsIntegers);
|
||||
|
||||
var settingsWithout = JsonFormatter.Settings.Default.WithFormatEnumsAsIntegers(false);
|
||||
Assert.AreEqual(false, settingsWithout.FormatEnumsAsIntegers);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WithMethodsPreserveExistingSettings()
|
||||
{
|
||||
var typeRegistry = TypeRegistry.Empty;
|
||||
var baseSettings = JsonFormatter.Settings.Default
|
||||
.WithIndentation("\t")
|
||||
.WithFormatDefaultValues(true)
|
||||
.WithFormatEnumsAsIntegers(true)
|
||||
.WithTypeRegistry(typeRegistry)
|
||||
.WithPreserveProtoFieldNames(true);
|
||||
|
||||
var settings1 = baseSettings.WithIndentation("\t");
|
||||
var settings2 = baseSettings.WithFormatDefaultValues(true);
|
||||
var settings3 = baseSettings.WithFormatEnumsAsIntegers(true);
|
||||
var settings4 = baseSettings.WithTypeRegistry(typeRegistry);
|
||||
var settings5 = baseSettings.WithPreserveProtoFieldNames(true);
|
||||
|
||||
AssertAreEqual(baseSettings, settings1);
|
||||
AssertAreEqual(baseSettings, settings2);
|
||||
AssertAreEqual(baseSettings, settings3);
|
||||
AssertAreEqual(baseSettings, settings4);
|
||||
AssertAreEqual(baseSettings, settings5);
|
||||
}
|
||||
|
||||
private static void AssertAreEqual(JsonFormatter.Settings settings, JsonFormatter.Settings other)
|
||||
{
|
||||
Assert.AreEqual(settings.Indentation, other.Indentation);
|
||||
Assert.AreEqual(settings.FormatDefaultValues, other.FormatDefaultValues);
|
||||
Assert.AreEqual(settings.FormatEnumsAsIntegers, other.FormatEnumsAsIntegers);
|
||||
Assert.AreEqual(settings.TypeRegistry, other.TypeRegistry);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -168,7 +168,8 @@ namespace Google.Protobuf
|
||||
[Test]
|
||||
public void WithFormatDefaultValues_DoesNotAffectProto3OptionalFields()
|
||||
{
|
||||
var message = new TestProto3Optional { OptionalInt32 = 0 };
|
||||
var message = new TestProto3Optional();
|
||||
message.OptionalInt32 = 0;
|
||||
var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true));
|
||||
var json = formatter.Format(message);
|
||||
// The non-optional proto3 fields are formatted, as is the optional-but-specified field.
|
||||
@@ -178,7 +179,8 @@ namespace Google.Protobuf
|
||||
[Test]
|
||||
public void WithFormatDefaultValues_DoesNotAffectProto2Fields()
|
||||
{
|
||||
var message = new TestProtos.Proto2.ForeignMessage { C = 0 };
|
||||
var message = new TestProtos.Proto2.ForeignMessage();
|
||||
message.C = 0;
|
||||
var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true));
|
||||
var json = formatter.Format(message);
|
||||
// The specified field is formatted, but the non-specified field (d) is not.
|
||||
@@ -674,200 +676,6 @@ namespace Google.Protobuf
|
||||
AssertWriteValue(value, "[ 1, 2, 3 ]");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WriteValueWithIndentation_EmptyMessage()
|
||||
{
|
||||
var value = new TestEmptyMessage();
|
||||
|
||||
AssertWriteValue(value, "{}", JsonFormatter.Settings.Default.WithIndentation());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WriteValueWithIndentation_NestedTestAllTypes()
|
||||
{
|
||||
var value = new NestedTestAllTypes
|
||||
{
|
||||
Payload = new TestAllTypes
|
||||
{
|
||||
SingleBool = true,
|
||||
SingleInt32 = 100,
|
||||
SingleString = "multiple fields",
|
||||
RepeatedString = { "string1", "string2" },
|
||||
},
|
||||
Child = new NestedTestAllTypes
|
||||
{
|
||||
Payload = new TestAllTypes
|
||||
{
|
||||
SingleString = "single field",
|
||||
},
|
||||
},
|
||||
RepeatedChild =
|
||||
{
|
||||
new NestedTestAllTypes { Payload = new TestAllTypes { SingleString = "child 1", RepeatedString = { "string" } } },
|
||||
new NestedTestAllTypes { Payload = new TestAllTypes { SingleString = "child 2" } },
|
||||
},
|
||||
};
|
||||
|
||||
const string expectedJson = @"
|
||||
{
|
||||
'child': {
|
||||
'payload': {
|
||||
'singleString': 'single field'
|
||||
}
|
||||
},
|
||||
'payload': {
|
||||
'singleInt32': 100,
|
||||
'singleBool': true,
|
||||
'singleString': 'multiple fields',
|
||||
'repeatedString': [
|
||||
'string1',
|
||||
'string2'
|
||||
]
|
||||
},
|
||||
'repeatedChild': [
|
||||
{
|
||||
'payload': {
|
||||
'singleString': 'child 1',
|
||||
'repeatedString': [
|
||||
'string'
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
'payload': {
|
||||
'singleString': 'child 2'
|
||||
}
|
||||
}
|
||||
]
|
||||
}";
|
||||
AssertWriteValue(value, expectedJson, JsonFormatter.Settings.Default.WithIndentation());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WriteValueWithIndentation_WellKnownTypes()
|
||||
{
|
||||
var value = new TestWellKnownTypes
|
||||
{
|
||||
StructField = new Struct
|
||||
{
|
||||
Fields =
|
||||
{
|
||||
{ "string", Value.ForString("foo") },
|
||||
{ "numbers", Value.ForList(Value.ForNumber(1), Value.ForNumber(2), Value.ForNumber(3)) },
|
||||
{ "emptyList", Value.ForList() },
|
||||
{ "emptyStruct", Value.ForStruct(new Struct()) },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const string expectedJson = @"
|
||||
{
|
||||
'structField': {
|
||||
'string': 'foo',
|
||||
'numbers': [
|
||||
1,
|
||||
2,
|
||||
3
|
||||
],
|
||||
'emptyList': [],
|
||||
'emptyStruct': {}
|
||||
}
|
||||
}";
|
||||
AssertWriteValue(value, expectedJson, JsonFormatter.Settings.Default.WithIndentation());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WriteValueWithIndentation_StructSingleField()
|
||||
{
|
||||
var value = new Struct { Fields = { { "structField1", Value.ForString("structFieldValue1") } } };
|
||||
|
||||
const string expectedJson = @"
|
||||
{
|
||||
'structField1': 'structFieldValue1'
|
||||
}";
|
||||
AssertWriteValue(value, expectedJson, JsonFormatter.Settings.Default.WithIndentation());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WriteValueWithIndentation_StructMultipleFields()
|
||||
{
|
||||
var value = new Struct
|
||||
{
|
||||
Fields =
|
||||
{
|
||||
{ "structField1", Value.ForString("structFieldValue1") },
|
||||
{ "structField2", Value.ForString("structFieldValue2") },
|
||||
{ "structField3", Value.ForString("structFieldValue3") },
|
||||
},
|
||||
};
|
||||
|
||||
const string expectedJson = @"
|
||||
{
|
||||
'structField1': 'structFieldValue1',
|
||||
'structField2': 'structFieldValue2',
|
||||
'structField3': 'structFieldValue3'
|
||||
}";
|
||||
AssertWriteValue(value, expectedJson, JsonFormatter.Settings.Default.WithIndentation());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FormatWithIndentation_EmbeddedMessage()
|
||||
{
|
||||
var value = new TestAllTypes { SingleInt32 = 100, SingleInt64 = 3210987654321L };
|
||||
var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithIndentation());
|
||||
var valueJson = formatter.Format(value, indentationLevel: 1);
|
||||
|
||||
var actualJson = $@"
|
||||
{{
|
||||
""data"": {valueJson}
|
||||
}}";
|
||||
const string expectedJson = @"
|
||||
{
|
||||
'data': {
|
||||
'singleInt32': 100,
|
||||
'singleInt64': '3210987654321'
|
||||
}
|
||||
}";
|
||||
AssertJson(expectedJson, actualJson.Trim());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WriteValueWithIndentation_Map()
|
||||
{
|
||||
var value = new TestMap
|
||||
{
|
||||
MapStringString =
|
||||
{
|
||||
{ "key1", "value1" },
|
||||
{ "key2", "value2" },
|
||||
},
|
||||
};
|
||||
|
||||
const string expectedJson = @"
|
||||
{
|
||||
'mapStringString': {
|
||||
'key1': 'value1',
|
||||
'key2': 'value2'
|
||||
}
|
||||
}";
|
||||
|
||||
AssertWriteValue(value, expectedJson, JsonFormatter.Settings.Default.WithIndentation());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WriteValueWithIndentation_List()
|
||||
{
|
||||
var value = new RepeatedField<int> { 1, 2, 3 };
|
||||
AssertWriteValue(value, "[\n 1,\n 2,\n 3\n]", JsonFormatter.Settings.Default.WithIndentation());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WriteValueWithIndentation_CustomIndentation()
|
||||
{
|
||||
var value = new RepeatedField<int> { 1, 2, 3 };
|
||||
AssertWriteValue(value, "[\n\t1,\n\t2,\n\t3\n]", JsonFormatter.Settings.Default.WithIndentation("\t"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Proto2_DefaultValuesWritten()
|
||||
{
|
||||
@@ -877,7 +685,7 @@ namespace Google.Protobuf
|
||||
|
||||
private static void AssertWriteValue(object value, string expectedJson, JsonFormatter.Settings settings = null)
|
||||
{
|
||||
var writer = new StringWriter { NewLine = "\n" };
|
||||
var writer = new StringWriter();
|
||||
new JsonFormatter(settings ?? JsonFormatter.Settings.Default).WriteValue(writer, value);
|
||||
string actual = writer.ToString();
|
||||
AssertJson(expectedJson, actual);
|
||||
@@ -885,17 +693,13 @@ namespace Google.Protobuf
|
||||
|
||||
/// <summary>
|
||||
/// Checks that the actual JSON is the same as the expected JSON - but after replacing
|
||||
/// all apostrophes in the expected JSON with double quotes, trimming leading whitespace and normalizing new lines.
|
||||
/// This basically makes the tests easier to read.
|
||||
/// all apostrophes in the expected JSON with double quotes. This basically makes the tests easier
|
||||
/// to read.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Line endings are normalized because indented JSON strings are generated with system-specific line endings,
|
||||
/// while line endings in the test cases are hard-coded, but may be converted during source checkout, depending
|
||||
/// on git settings, causing unpredictability in the test results otherwise.</remarks>
|
||||
private static void AssertJson(string expectedJsonWithApostrophes, string actualJson)
|
||||
{
|
||||
var expectedJson = expectedJsonWithApostrophes.Replace("'", "\"").Replace("\r\n", "\n").TrimStart();
|
||||
Assert.AreEqual(expectedJson, actualJson.Replace("\r\n", "\n"));
|
||||
var expectedJson = expectedJsonWithApostrophes.Replace("'", "\"");
|
||||
Assert.AreEqual(expectedJson, actualJson);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -576,10 +576,6 @@ namespace Google.Protobuf
|
||||
[TestCase("-3.402823e38", -3.402823e38f)]
|
||||
[TestCase("1.5e1", 15f)]
|
||||
[TestCase("15e-1", 1.5f)]
|
||||
[TestCase("3.4028235e38", float.MaxValue)]
|
||||
[TestCase("-3.4028235e38", float.MinValue)]
|
||||
[TestCase("3.4028235e+38", float.MaxValue)]
|
||||
[TestCase("-3.4028235e+38", float.MinValue)]
|
||||
public void NumberToFloat_Valid(string jsonValue, float expectedParsedValue)
|
||||
{
|
||||
string json = "{ \"singleFloat\": " + jsonValue + "}";
|
||||
@@ -588,10 +584,8 @@ namespace Google.Protobuf
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("3.4028236e38", typeof(InvalidProtocolBufferException))]
|
||||
[TestCase("-3.4028236e38", typeof(InvalidProtocolBufferException))]
|
||||
[TestCase("3.4028236e+38", typeof(InvalidProtocolBufferException))]
|
||||
[TestCase("-3.4028236e+38", typeof(InvalidProtocolBufferException))]
|
||||
[TestCase("3.402824e38", typeof(InvalidProtocolBufferException))]
|
||||
[TestCase("-3.402824e38", typeof(InvalidProtocolBufferException))]
|
||||
[TestCase("1,0", typeof(InvalidJsonException))]
|
||||
[TestCase("1.0.0", typeof(InvalidJsonException))]
|
||||
[TestCase("+1", typeof(InvalidJsonException))]
|
||||
@@ -647,7 +641,7 @@ namespace Google.Protobuf
|
||||
[TestCase("9999-12-31T23:59:59.999999999Z", null)]
|
||||
public void Timestamp_Valid(string jsonValue, string expectedFormatted)
|
||||
{
|
||||
expectedFormatted ??= jsonValue;
|
||||
expectedFormatted = expectedFormatted ?? jsonValue;
|
||||
string json = WrapInQuotes(jsonValue);
|
||||
var parsed = Timestamp.Parser.ParseJson(json);
|
||||
Assert.AreEqual(WrapInQuotes(expectedFormatted), parsed.ToString());
|
||||
@@ -764,7 +758,7 @@ namespace Google.Protobuf
|
||||
[TestCase("-315576000000s", null)]
|
||||
public void Duration_Valid(string jsonValue, string expectedFormatted)
|
||||
{
|
||||
expectedFormatted ??= jsonValue;
|
||||
expectedFormatted = expectedFormatted ?? jsonValue;
|
||||
string json = WrapInQuotes(jsonValue);
|
||||
var parsed = Duration.Parser.ParseJson(json);
|
||||
Assert.AreEqual(WrapInQuotes(expectedFormatted), parsed.ToString());
|
||||
@@ -1072,26 +1066,25 @@ namespace Google.Protobuf
|
||||
""mapStringNestedMessage"": null
|
||||
}";
|
||||
|
||||
var message = new TestAllTypesProto3
|
||||
{
|
||||
OptionalInt32 = 1,
|
||||
OptionalInt64 = 1,
|
||||
OptionalUint32 = 1,
|
||||
OptionalUint64 = 1,
|
||||
OptionalSint32 = 1,
|
||||
OptionalSint64 = 1,
|
||||
OptionalFixed32 = 1,
|
||||
OptionalFixed64 = 1,
|
||||
OptionalSfixed32 = 1,
|
||||
OptionalSfixed64 = 1,
|
||||
OptionalFloat = 1,
|
||||
OptionalDouble = 1,
|
||||
OptionalBool = true,
|
||||
OptionalString = "1",
|
||||
OptionalBytes = ByteString.CopyFrom(new byte[] { 1 }),
|
||||
OptionalNestedEnum = TestAllTypesProto3.Types.NestedEnum.Bar,
|
||||
OptionalNestedMessage = new TestAllTypesProto3.Types.NestedMessage()
|
||||
};
|
||||
TestAllTypesProto3 message = new TestAllTypesProto3();
|
||||
|
||||
message.OptionalInt32 = 1;
|
||||
message.OptionalInt64 = 1;
|
||||
message.OptionalUint32 = 1;
|
||||
message.OptionalUint64 = 1;
|
||||
message.OptionalSint32 = 1;
|
||||
message.OptionalSint64 = 1;
|
||||
message.OptionalFixed32 = 1;
|
||||
message.OptionalFixed64 = 1;
|
||||
message.OptionalSfixed32 = 1;
|
||||
message.OptionalSfixed64 = 1;
|
||||
message.OptionalFloat = 1;
|
||||
message.OptionalDouble = 1;
|
||||
message.OptionalBool = true;
|
||||
message.OptionalString = "1";
|
||||
message.OptionalBytes = ByteString.CopyFrom(new byte[] { 1 });
|
||||
message.OptionalNestedEnum = TestAllTypesProto3.Types.NestedEnum.Bar;
|
||||
message.OptionalNestedMessage = new TestAllTypesProto3.Types.NestedMessage();
|
||||
message.RepeatedInt32.Add(1);
|
||||
message.RepeatedInt64.Add(1);
|
||||
message.RepeatedUint32.Add(1);
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#endregion
|
||||
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.IO;
|
||||
@@ -127,7 +126,7 @@ namespace Google.Protobuf
|
||||
tokenizer.PushBack(token);
|
||||
Assert.AreEqual(0, tokenizer.ObjectDepth);
|
||||
// Read the same token again, and get back to depth 1
|
||||
_ = tokenizer.Next();
|
||||
token = tokenizer.Next();
|
||||
Assert.AreEqual(1, tokenizer.ObjectDepth);
|
||||
|
||||
// Now the same in reverse, with EndObject
|
||||
|
||||
@@ -29,12 +29,14 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#endregion
|
||||
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.Reflection;
|
||||
using System.Buffers;
|
||||
using pb = Google.Protobuf;
|
||||
using pbr = Google.Protobuf.Reflection;
|
||||
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
|
||||
|
||||
@@ -136,7 +136,8 @@ namespace Google.Protobuf
|
||||
// test for different IBufferWriter.GetSpan() segment sizes
|
||||
for (int blockSize = 1; blockSize < 256; blockSize *= 2)
|
||||
{
|
||||
var segmentedBufferWriter = new TestArrayBufferWriter<byte> { MaxGrowBy = blockSize };
|
||||
var segmentedBufferWriter = new TestArrayBufferWriter<byte>();
|
||||
segmentedBufferWriter.MaxGrowBy = blockSize;
|
||||
message.WriteTo(segmentedBufferWriter);
|
||||
Assert.AreEqual(bytes, segmentedBufferWriter.WrittenSpan.ToArray());
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ using UnitTest.Issues.TestProtos;
|
||||
|
||||
namespace Google.Protobuf.Test
|
||||
{
|
||||
public class Proto3OptionalTest
|
||||
class Proto3OptionalTest
|
||||
{
|
||||
[Test]
|
||||
public void OptionalInt32FieldLifecycle()
|
||||
|
||||
@@ -33,6 +33,9 @@
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Google.Protobuf
|
||||
{
|
||||
@@ -47,7 +50,7 @@ namespace Google.Protobuf
|
||||
|
||||
if (addEmptySegmentDelimiters)
|
||||
{
|
||||
segments.Add(Array.Empty<byte>());
|
||||
segments.Add(new byte[0]);
|
||||
}
|
||||
|
||||
var currentIndex = 0;
|
||||
@@ -62,7 +65,7 @@ namespace Google.Protobuf
|
||||
|
||||
if (addEmptySegmentDelimiters)
|
||||
{
|
||||
segments.Add(Array.Empty<byte>());
|
||||
segments.Add(new byte[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -77,42 +77,43 @@ namespace Google.Protobuf
|
||||
/// <param name="args"></param>
|
||||
/// <param name="workingDirectory"></param>
|
||||
private void RunOldCsharpCompilerAndCheckSuccess(string args, string workingDirectory)
|
||||
{
|
||||
using var process = new Process();
|
||||
|
||||
// Get the path to the old C# 5 compiler from .NET framework. This approach is not 100% reliable, but works on most machines.
|
||||
// Alternative way of getting the framework path is System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory()
|
||||
// but it only works with the net45 target.
|
||||
var oldCsharpCompilerPath = Path.Combine(Environment.GetEnvironmentVariable("WINDIR"), "Microsoft.NET", "Framework", "v4.0.30319", "csc.exe");
|
||||
process.StartInfo.FileName = oldCsharpCompilerPath;
|
||||
process.StartInfo.RedirectStandardOutput = true;
|
||||
process.StartInfo.RedirectStandardError = true;
|
||||
process.StartInfo.UseShellExecute = false;
|
||||
process.StartInfo.Arguments = args;
|
||||
process.StartInfo.WorkingDirectory = workingDirectory;
|
||||
|
||||
process.OutputDataReceived += (sender, e) =>
|
||||
{
|
||||
using (var process = new Process())
|
||||
{
|
||||
if (e.Data != null)
|
||||
// Get the path to the old C# 5 compiler from .NET framework. This approach is not 100% reliable, but works on most machines.
|
||||
// Alternative way of getting the framework path is System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory()
|
||||
// but it only works with the net45 target.
|
||||
var oldCsharpCompilerPath = Path.Combine(Environment.GetEnvironmentVariable("WINDIR"), "Microsoft.NET", "Framework", "v4.0.30319", "csc.exe");
|
||||
process.StartInfo.FileName = oldCsharpCompilerPath;
|
||||
process.StartInfo.RedirectStandardOutput = true;
|
||||
process.StartInfo.RedirectStandardError = true;
|
||||
process.StartInfo.UseShellExecute = false;
|
||||
process.StartInfo.Arguments = args;
|
||||
process.StartInfo.WorkingDirectory = workingDirectory;
|
||||
|
||||
process.OutputDataReceived += (sender, e) =>
|
||||
{
|
||||
Console.WriteLine(e.Data);
|
||||
}
|
||||
};
|
||||
process.ErrorDataReceived += (sender, e) =>
|
||||
{
|
||||
if (e.Data != null)
|
||||
if (e.Data != null)
|
||||
{
|
||||
Console.WriteLine(e.Data);
|
||||
}
|
||||
};
|
||||
process.ErrorDataReceived += (sender, e) =>
|
||||
{
|
||||
Console.WriteLine(e.Data);
|
||||
}
|
||||
};
|
||||
if (e.Data != null)
|
||||
{
|
||||
Console.WriteLine(e.Data);
|
||||
}
|
||||
};
|
||||
|
||||
process.Start();
|
||||
process.Start();
|
||||
|
||||
process.BeginErrorReadLine();
|
||||
process.BeginOutputReadLine();
|
||||
process.BeginErrorReadLine();
|
||||
process.BeginOutputReadLine();
|
||||
|
||||
process.WaitForExit();
|
||||
Assert.AreEqual(0, process.ExitCode);
|
||||
process.WaitForExit();
|
||||
Assert.AreEqual(0, process.ExitCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,10 +31,13 @@
|
||||
#endregion
|
||||
|
||||
using Google.Protobuf.Reflection;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnitTest.Issues.TestProtos;
|
||||
using static Google.Protobuf.WireFormat;
|
||||
using static UnitTest.Issues.TestProtos.ComplexOptionType2.Types;
|
||||
using static UnitTest.Issues.TestProtos.UnittestCustomOptionsProto3Extensions;
|
||||
using static UnitTest.Issues.TestProtos.DummyMessageContainingEnum.Types;
|
||||
@@ -62,7 +65,7 @@ namespace Google.Protobuf.Test.Reflection
|
||||
}
|
||||
else
|
||||
{
|
||||
v = default;
|
||||
v = default(E);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -35,6 +35,7 @@ using NUnit.Framework;
|
||||
using ProtobufUnittest;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnitTest.Issues.TestProtos;
|
||||
|
||||
|
||||
@@ -30,8 +30,10 @@
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Google.Protobuf.TestProtos;
|
||||
using Proto2 = Google.Protobuf.TestProtos.Proto2;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Google.Protobuf
|
||||
@@ -125,7 +127,8 @@ namespace Google.Protobuf
|
||||
public void TestClone(IMessage message)
|
||||
{
|
||||
var emptyMessage = new TestEmptyMessage();
|
||||
TestEmptyMessage otherEmptyMessage = emptyMessage.Clone();
|
||||
var otherEmptyMessage = new TestEmptyMessage();
|
||||
otherEmptyMessage = emptyMessage.Clone();
|
||||
Assert.AreEqual(emptyMessage.CalculateSize(), otherEmptyMessage.CalculateSize());
|
||||
Assert.AreEqual(emptyMessage.ToByteArray(), otherEmptyMessage.ToByteArray());
|
||||
|
||||
@@ -166,13 +169,13 @@ namespace Google.Protobuf
|
||||
byte[] data = message.ToByteArray();
|
||||
int fullSize = message.CalculateSize();
|
||||
|
||||
void AssertEmpty(IMessage msg)
|
||||
Action<IMessage> assertEmpty = msg =>
|
||||
{
|
||||
Assert.AreEqual(0, msg.CalculateSize());
|
||||
Assert.AreEqual(goldenEmptyMessage, msg);
|
||||
}
|
||||
};
|
||||
|
||||
void AssertFull(IMessage msg) => Assert.AreEqual(fullSize, msg.CalculateSize());
|
||||
Action<IMessage> assertFull = msg => Assert.AreEqual(fullSize, msg.CalculateSize());
|
||||
|
||||
// Test the behavior of the parsers with and without discarding, both generic and non-generic.
|
||||
MessageParser<TestEmptyMessage> retainingParser1 = TestEmptyMessage.Parser;
|
||||
@@ -181,28 +184,28 @@ namespace Google.Protobuf
|
||||
MessageParser discardingParser2 = retainingParser2.WithDiscardUnknownFields(true);
|
||||
|
||||
// Test parse from byte[]
|
||||
MessageParsingHelpers.AssertReadingMessage(retainingParser1, data, m => AssertFull(m));
|
||||
MessageParsingHelpers.AssertReadingMessage(retainingParser2, data, m => AssertFull(m));
|
||||
MessageParsingHelpers.AssertReadingMessage(discardingParser1, data, m => AssertEmpty(m));
|
||||
MessageParsingHelpers.AssertReadingMessage(discardingParser2, data, m => AssertEmpty(m));
|
||||
MessageParsingHelpers.AssertReadingMessage(retainingParser1, data, m => assertFull(m));
|
||||
MessageParsingHelpers.AssertReadingMessage(retainingParser2, data, m => assertFull(m));
|
||||
MessageParsingHelpers.AssertReadingMessage(discardingParser1, data, m => assertEmpty(m));
|
||||
MessageParsingHelpers.AssertReadingMessage(discardingParser2, data, m => assertEmpty(m));
|
||||
|
||||
// Test parse from byte[] with offset
|
||||
AssertFull(retainingParser1.ParseFrom(data, 0, data.Length));
|
||||
AssertFull(retainingParser2.ParseFrom(data, 0, data.Length));
|
||||
AssertEmpty(discardingParser1.ParseFrom(data, 0, data.Length));
|
||||
AssertEmpty(discardingParser2.ParseFrom(data, 0, data.Length));
|
||||
assertFull(retainingParser1.ParseFrom(data, 0, data.Length));
|
||||
assertFull(retainingParser2.ParseFrom(data, 0, data.Length));
|
||||
assertEmpty(discardingParser1.ParseFrom(data, 0, data.Length));
|
||||
assertEmpty(discardingParser2.ParseFrom(data, 0, data.Length));
|
||||
|
||||
// Test parse from CodedInputStream
|
||||
AssertFull(retainingParser1.ParseFrom(new CodedInputStream(data)));
|
||||
AssertFull(retainingParser2.ParseFrom(new CodedInputStream(data)));
|
||||
AssertEmpty(discardingParser1.ParseFrom(new CodedInputStream(data)));
|
||||
AssertEmpty(discardingParser2.ParseFrom(new CodedInputStream(data)));
|
||||
assertFull(retainingParser1.ParseFrom(new CodedInputStream(data)));
|
||||
assertFull(retainingParser2.ParseFrom(new CodedInputStream(data)));
|
||||
assertEmpty(discardingParser1.ParseFrom(new CodedInputStream(data)));
|
||||
assertEmpty(discardingParser2.ParseFrom(new CodedInputStream(data)));
|
||||
|
||||
// Test parse from Stream
|
||||
AssertFull(retainingParser1.ParseFrom(new MemoryStream(data)));
|
||||
AssertFull(retainingParser2.ParseFrom(new MemoryStream(data)));
|
||||
AssertEmpty(discardingParser1.ParseFrom(new MemoryStream(data)));
|
||||
AssertEmpty(discardingParser2.ParseFrom(new MemoryStream(data)));
|
||||
assertFull(retainingParser1.ParseFrom(new MemoryStream(data)));
|
||||
assertFull(retainingParser2.ParseFrom(new MemoryStream(data)));
|
||||
assertEmpty(discardingParser1.ParseFrom(new MemoryStream(data)));
|
||||
assertEmpty(discardingParser2.ParseFrom(new MemoryStream(data)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -30,11 +30,8 @@
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#endregion
|
||||
|
||||
using Google.Protobuf.Reflection;
|
||||
using Google.Protobuf.TestProtos;
|
||||
using NUnit.Framework;
|
||||
using System.Linq;
|
||||
using UnitTest.Issues.TestProtos;
|
||||
|
||||
namespace Google.Protobuf.WellKnownTypes
|
||||
{
|
||||
@@ -126,6 +123,7 @@ namespace Google.Protobuf.WellKnownTypes
|
||||
[TestCase("foobar", "")]
|
||||
public void GetTypeName(string typeUrl, string expectedTypeName)
|
||||
{
|
||||
var any = new Any { TypeUrl = typeUrl };
|
||||
Assert.AreEqual(expectedTypeName, Any.GetTypeName(typeUrl));
|
||||
}
|
||||
|
||||
@@ -150,34 +148,10 @@ namespace Google.Protobuf.WellKnownTypes
|
||||
Assert.False(any.Is(TestOneof.Descriptor));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsRightType()
|
||||
{
|
||||
var any = Any.Pack(SampleMessages.CreateFullTestAllTypes());
|
||||
Assert.True(any.Is(TestAllTypes.Descriptor));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Unpack_TypeRegistry()
|
||||
{
|
||||
var messages = new IMessage[]
|
||||
{
|
||||
SampleMessages.CreateFullTestAllTypes(),
|
||||
new TestWellKnownTypes { BoolField = true },
|
||||
new MoreString { Data = { "x" } },
|
||||
new MoreBytes { Data = ByteString.CopyFromUtf8("xyz") },
|
||||
new ReservedNames { Descriptor_ = 10 }
|
||||
};
|
||||
var anyMessages = messages.Select(Any.Pack);
|
||||
|
||||
// The type registry handles the first four of the packed messages, but not the final one.
|
||||
var registry = TypeRegistry.FromFiles(
|
||||
UnittestWellKnownTypesReflection.Descriptor,
|
||||
UnittestProto3Reflection.Descriptor);
|
||||
var unpacked = anyMessages.Select(any => any.Unpack(registry)).ToList();
|
||||
var expected = (IMessage[]) messages.Clone();
|
||||
expected[4] = null;
|
||||
Assert.AreEqual(expected, unpacked);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,38 +128,5 @@ namespace Google.Protobuf.WellKnownTypes
|
||||
var duration = new Duration { Seconds = 1, Nanos = -1 };
|
||||
Assert.AreEqual("{ \"@warning\": \"Invalid Duration\", \"seconds\": \"1\", \"nanos\": -1 }", duration.ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Comparability()
|
||||
{
|
||||
Duration[] durationsInExpectedSortOrder =
|
||||
{
|
||||
null,
|
||||
new Duration { Seconds = -10, Nanos = -10 },
|
||||
new Duration { Seconds = -10, Nanos = -1 },
|
||||
new Duration { Seconds = -1, Nanos = -10 },
|
||||
new Duration { Seconds = -1, Nanos = -1 },
|
||||
new Duration(),
|
||||
new Duration { Seconds = 1, Nanos = 1 },
|
||||
new Duration { Seconds = 1, Nanos = 10 },
|
||||
new Duration { Seconds = 10, Nanos = 1 },
|
||||
new Duration { Seconds = 10, Nanos = 10 }
|
||||
};
|
||||
|
||||
for (int i = 0; i < durationsInExpectedSortOrder.Length; i++)
|
||||
{
|
||||
var target = durationsInExpectedSortOrder[i];
|
||||
if (target is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (int j = 0; j < durationsInExpectedSortOrder.Length; j++)
|
||||
{
|
||||
var expectedResult = Math.Sign(i - j);
|
||||
var actualResult = target.CompareTo(durationsInExpectedSortOrder[j]);
|
||||
Assert.AreEqual(expectedResult, actualResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -12,6 +12,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Google.Protobuf.Conformance
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Google.Protobuf.JsonDump", "Google.Protobuf.JsonDump\Google.Protobuf.JsonDump.csproj", "{9695E08F-9829-497D-B95C-B38F28D48690}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf.Benchmarks", "Google.Protobuf.Benchmarks\Google.Protobuf.Benchmarks.csproj", "{D25E4804-4DEA-45AB-9F8C-BA4DBD8E5A07}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf.Test.TestProtos", "Google.Protobuf.Test.TestProtos\Google.Protobuf.Test.TestProtos.csproj", "{ADF24BEB-A318-4530-8448-356B72B820EA}"
|
||||
EndProject
|
||||
Global
|
||||
@@ -40,6 +42,10 @@ Global
|
||||
{9695E08F-9829-497D-B95C-B38F28D48690}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9695E08F-9829-497D-B95C-B38F28D48690}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9695E08F-9829-497D-B95C-B38F28D48690}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D25E4804-4DEA-45AB-9F8C-BA4DBD8E5A07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D25E4804-4DEA-45AB-9F8C-BA4DBD8E5A07}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D25E4804-4DEA-45AB-9F8C-BA4DBD8E5A07}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D25E4804-4DEA-45AB-9F8C-BA4DBD8E5A07}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{ADF24BEB-A318-4530-8448-356B72B820EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{ADF24BEB-A318-4530-8448-356B72B820EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{ADF24BEB-A318-4530-8448-356B72B820EA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
||||
@@ -37,8 +37,13 @@ using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
#if !NET35
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
#endif
|
||||
#if NET35
|
||||
using Google.Protobuf.Compatibility;
|
||||
#endif
|
||||
|
||||
namespace Google.Protobuf
|
||||
{
|
||||
@@ -181,6 +186,7 @@ namespace Google.Protobuf
|
||||
return AttachBytes(bytes);
|
||||
}
|
||||
|
||||
#if !NET35
|
||||
/// <summary>
|
||||
/// Constructs a <see cref="ByteString"/> from data in the given stream, asynchronously.
|
||||
/// </summary>
|
||||
@@ -189,11 +195,12 @@ namespace Google.Protobuf
|
||||
/// <param name="stream">The stream to copy into a ByteString.</param>
|
||||
/// <param name="cancellationToken">The cancellation token to use when reading from the stream, if any.</param>
|
||||
/// <returns>A ByteString with content read from the given stream.</returns>
|
||||
public static Task<ByteString> FromStreamAsync(Stream stream, CancellationToken cancellationToken = default)
|
||||
public static Task<ByteString> FromStreamAsync(Stream stream, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
ProtoPreconditions.CheckNotNull(stream, nameof(stream));
|
||||
return ByteStringAsync.FromStreamAsyncCore(stream, cancellationToken);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a <see cref="ByteString" /> from the given array. The contents
|
||||
@@ -340,7 +347,7 @@ namespace Google.Protobuf
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (lhs is null || rhs is null)
|
||||
if (ReferenceEquals(lhs, null) || ReferenceEquals(rhs, null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ namespace Google.Protobuf
|
||||
/// </summary>
|
||||
internal static class ByteStringAsync
|
||||
{
|
||||
#if !NET35
|
||||
internal static async Task<ByteString> FromStreamAsyncCore(Stream stream, CancellationToken cancellationToken)
|
||||
{
|
||||
int capacity = stream.CanSeek ? checked((int)(stream.Length - stream.Position)) : 0;
|
||||
@@ -58,5 +59,6 @@ namespace Google.Protobuf
|
||||
#endif
|
||||
return ByteString.AttachBytes(bytes);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,10 @@
|
||||
|
||||
using Google.Protobuf.Collections;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
|
||||
namespace Google.Protobuf
|
||||
@@ -646,6 +649,21 @@ namespace Google.Protobuf
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when buffer is empty to read more bytes from the
|
||||
/// input. If <paramref name="mustSucceed"/> is true, RefillBuffer() guarantees that
|
||||
/// either there will be at least one byte in the buffer when it returns
|
||||
/// or it will throw an exception. If <paramref name="mustSucceed"/> is false,
|
||||
/// RefillBuffer() returns false if no more bytes were available.
|
||||
/// </summary>
|
||||
/// <param name="mustSucceed"></param>
|
||||
/// <returns></returns>
|
||||
private bool RefillBuffer(bool mustSucceed)
|
||||
{
|
||||
var span = new ReadOnlySpan<byte>(buffer);
|
||||
return state.segmentedBufferHelper.RefillBuffer(ref span, ref state, mustSucceed);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a fixed size of bytes from the input.
|
||||
/// </summary>
|
||||
|
||||
@@ -30,9 +30,11 @@
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#endregion
|
||||
|
||||
using Google.Protobuf.Collections;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
|
||||
namespace Google.Protobuf
|
||||
{
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace Google.Protobuf.Collections
|
||||
{
|
||||
|
||||
@@ -31,7 +31,9 @@
|
||||
#endregion
|
||||
|
||||
using Google.Protobuf.Compatibility;
|
||||
using Google.Protobuf.Reflection;
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
@@ -66,14 +68,18 @@ namespace Google.Protobuf.Collections
|
||||
/// in future versions.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public sealed class MapField<TKey, TValue> : IDeepCloneable<MapField<TKey, TValue>>, IDictionary<TKey, TValue>, IEquatable<MapField<TKey, TValue>>, IDictionary, IReadOnlyDictionary<TKey, TValue>
|
||||
public sealed class MapField<TKey, TValue> : IDeepCloneable<MapField<TKey, TValue>>, IDictionary<TKey, TValue>, IEquatable<MapField<TKey, TValue>>, IDictionary
|
||||
#if !NET35
|
||||
, IReadOnlyDictionary<TKey, TValue>
|
||||
#endif
|
||||
{
|
||||
private static readonly EqualityComparer<TValue> ValueEqualityComparer = ProtobufEqualityComparers.GetEqualityComparer<TValue>();
|
||||
private static readonly EqualityComparer<TKey> KeyEqualityComparer = ProtobufEqualityComparers.GetEqualityComparer<TKey>();
|
||||
|
||||
// TODO: Don't create the map/list until we have an entry. (Assume many maps will be empty.)
|
||||
private readonly Dictionary<TKey, LinkedListNode<KeyValuePair<TKey, TValue>>> map = new(KeyEqualityComparer);
|
||||
private readonly LinkedList<KeyValuePair<TKey, TValue>> list = new();
|
||||
private readonly Dictionary<TKey, LinkedListNode<KeyValuePair<TKey, TValue>>> map =
|
||||
new Dictionary<TKey, LinkedListNode<KeyValuePair<TKey, TValue>>>(KeyEqualityComparer);
|
||||
private readonly LinkedList<KeyValuePair<TKey, TValue>> list = new LinkedList<KeyValuePair<TKey, TValue>>();
|
||||
|
||||
/// <summary>
|
||||
/// Creates a deep clone of this object.
|
||||
@@ -141,7 +147,8 @@ namespace Google.Protobuf.Collections
|
||||
public bool Remove(TKey key)
|
||||
{
|
||||
ProtoPreconditions.CheckNotNullUnconstrained(key, nameof(key));
|
||||
if (map.TryGetValue(key, out LinkedListNode<KeyValuePair<TKey, TValue>> node))
|
||||
LinkedListNode<KeyValuePair<TKey, TValue>> node;
|
||||
if (map.TryGetValue(key, out node))
|
||||
{
|
||||
map.Remove(key);
|
||||
node.List.Remove(node);
|
||||
@@ -163,14 +170,15 @@ namespace Google.Protobuf.Collections
|
||||
/// <returns><c>true</c> if the map contains an element with the specified key; otherwise, <c>false</c>.</returns>
|
||||
public bool TryGetValue(TKey key, out TValue value)
|
||||
{
|
||||
if (map.TryGetValue(key, out LinkedListNode<KeyValuePair<TKey, TValue>> node))
|
||||
LinkedListNode<KeyValuePair<TKey, TValue>> node;
|
||||
if (map.TryGetValue(key, out node))
|
||||
{
|
||||
value = node.Value.Value;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = default;
|
||||
value = default(TValue);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -187,7 +195,8 @@ namespace Google.Protobuf.Collections
|
||||
get
|
||||
{
|
||||
ProtoPreconditions.CheckNotNullUnconstrained(key, nameof(key));
|
||||
if (TryGetValue(key, out TValue value))
|
||||
TValue value;
|
||||
if (TryGetValue(key, out value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
@@ -201,8 +210,9 @@ namespace Google.Protobuf.Collections
|
||||
{
|
||||
ProtoPreconditions.CheckNotNullUnconstrained(value, nameof(value));
|
||||
}
|
||||
LinkedListNode<KeyValuePair<TKey, TValue>> node;
|
||||
var pair = new KeyValuePair<TKey, TValue>(key, value);
|
||||
if (map.TryGetValue(key, out LinkedListNode<KeyValuePair<TKey, TValue>> node))
|
||||
if (map.TryGetValue(key, out node))
|
||||
{
|
||||
node.Value = pair;
|
||||
}
|
||||
@@ -217,12 +227,12 @@ namespace Google.Protobuf.Collections
|
||||
/// <summary>
|
||||
/// Gets a collection containing the keys in the map.
|
||||
/// </summary>
|
||||
public ICollection<TKey> Keys => new MapView<TKey>(this, pair => pair.Key, ContainsKey);
|
||||
public ICollection<TKey> Keys { get { return new MapView<TKey>(this, pair => pair.Key, ContainsKey); } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection containing the values in the map.
|
||||
/// </summary>
|
||||
public ICollection<TValue> Values => new MapView<TValue>(this, pair => pair.Value, ContainsValue);
|
||||
public ICollection<TValue> Values { get { return new MapView<TValue>(this, pair => pair.Value, ContainsValue); } }
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified entries to the map. The keys and values are not automatically cloned.
|
||||
@@ -237,28 +247,16 @@ namespace Google.Protobuf.Collections
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified entries to the map, replacing any existing entries with the same keys.
|
||||
/// The keys and values are not automatically cloned.
|
||||
/// </summary>
|
||||
/// <remarks>This method primarily exists to be called from MergeFrom methods in generated classes for messages.</remarks>
|
||||
/// <param name="entries">The entries to add to the map.</param>
|
||||
public void MergeFrom(IDictionary<TKey, TValue> entries)
|
||||
{
|
||||
ProtoPreconditions.CheckNotNull(entries, nameof(entries));
|
||||
foreach (var pair in entries)
|
||||
{
|
||||
this[pair.Key] = pair.Value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enumerator that iterates through the collection.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An enumerator that can be used to iterate through the collection.
|
||||
/// </returns>
|
||||
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() => list.GetEnumerator();
|
||||
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
|
||||
{
|
||||
return list.GetEnumerator();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enumerator that iterates through a collection.
|
||||
@@ -266,13 +264,19 @@ namespace Google.Protobuf.Collections
|
||||
/// <returns>
|
||||
/// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.
|
||||
/// </returns>
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified item to the map.
|
||||
/// </summary>
|
||||
/// <param name="item">The item to add to the map.</param>
|
||||
void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item) => Add(item.Key, item.Value);
|
||||
void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
|
||||
{
|
||||
Add(item.Key, item.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all items from the map.
|
||||
@@ -288,16 +292,21 @@ namespace Google.Protobuf.Collections
|
||||
/// </summary>
|
||||
/// <param name="item">The key/value pair to find.</param>
|
||||
/// <returns></returns>
|
||||
bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item) =>
|
||||
TryGetValue(item.Key, out TValue value) && ValueEqualityComparer.Equals(item.Value, value);
|
||||
bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
|
||||
{
|
||||
TValue value;
|
||||
return TryGetValue(item.Key, out value) && ValueEqualityComparer.Equals(item.Value, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies the key/value pairs in this map to an array.
|
||||
/// </summary>
|
||||
/// <param name="array">The array to copy the entries into.</param>
|
||||
/// <param name="arrayIndex">The index of the array at which to start copying values.</param>
|
||||
void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) =>
|
||||
void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
|
||||
{
|
||||
list.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the specified key/value pair from the map.
|
||||
@@ -311,7 +320,8 @@ namespace Google.Protobuf.Collections
|
||||
{
|
||||
throw new ArgumentException("Key is null", nameof(item));
|
||||
}
|
||||
if (map.TryGetValue(item.Key, out LinkedListNode<KeyValuePair<TKey, TValue>> node) &&
|
||||
LinkedListNode<KeyValuePair<TKey, TValue>> node;
|
||||
if (map.TryGetValue(item.Key, out node) &&
|
||||
EqualityComparer<TValue>.Default.Equals(item.Value, node.Value.Value))
|
||||
{
|
||||
map.Remove(item.Key);
|
||||
@@ -327,12 +337,12 @@ namespace Google.Protobuf.Collections
|
||||
/// <summary>
|
||||
/// Gets the number of elements contained in the map.
|
||||
/// </summary>
|
||||
public int Count => list.Count;
|
||||
public int Count { get { return list.Count; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the map is read-only.
|
||||
/// </summary>
|
||||
public bool IsReadOnly => false;
|
||||
public bool IsReadOnly { get { return false; } }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="System.Object" />, is equal to this instance.
|
||||
@@ -341,7 +351,10 @@ namespace Google.Protobuf.Collections
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public override bool Equals(object other) => Equals(other as MapField<TKey, TValue>);
|
||||
public override bool Equals(object other)
|
||||
{
|
||||
return Equals(other as MapField<TKey, TValue>);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a hash code for this instance.
|
||||
@@ -386,7 +399,8 @@ namespace Google.Protobuf.Collections
|
||||
var valueComparer = ValueEqualityComparer;
|
||||
foreach (var pair in this)
|
||||
{
|
||||
if (!other.TryGetValue(pair.Key, out TValue value))
|
||||
TValue value;
|
||||
if (!other.TryGetValue(pair.Key, out value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -518,20 +532,33 @@ namespace Google.Protobuf.Collections
|
||||
}
|
||||
|
||||
#region IDictionary explicit interface implementation
|
||||
void IDictionary.Add(object key, object value)
|
||||
{
|
||||
Add((TKey)key, (TValue)value);
|
||||
}
|
||||
|
||||
void IDictionary.Add(object key, object value) => Add((TKey)key, (TValue)value);
|
||||
bool IDictionary.Contains(object key)
|
||||
{
|
||||
if (!(key is TKey))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return ContainsKey((TKey)key);
|
||||
}
|
||||
|
||||
bool IDictionary.Contains(object key) => key is TKey k && ContainsKey(k);
|
||||
|
||||
IDictionaryEnumerator IDictionary.GetEnumerator() => new DictionaryEnumerator(GetEnumerator());
|
||||
IDictionaryEnumerator IDictionary.GetEnumerator()
|
||||
{
|
||||
return new DictionaryEnumerator(GetEnumerator());
|
||||
}
|
||||
|
||||
void IDictionary.Remove(object key)
|
||||
{
|
||||
ProtoPreconditions.CheckNotNull(key, nameof(key));
|
||||
if (key is TKey k)
|
||||
if (!(key is TKey))
|
||||
{
|
||||
Remove(k);
|
||||
return;
|
||||
}
|
||||
Remove((TKey)key);
|
||||
}
|
||||
|
||||
void ICollection.CopyTo(Array array, int index)
|
||||
@@ -541,27 +568,28 @@ namespace Google.Protobuf.Collections
|
||||
temp.CopyTo(array, index);
|
||||
}
|
||||
|
||||
bool IDictionary.IsFixedSize => false;
|
||||
bool IDictionary.IsFixedSize { get { return false; } }
|
||||
|
||||
ICollection IDictionary.Keys => (ICollection)Keys;
|
||||
ICollection IDictionary.Keys { get { return (ICollection)Keys; } }
|
||||
|
||||
ICollection IDictionary.Values => (ICollection)Values;
|
||||
ICollection IDictionary.Values { get { return (ICollection)Values; } }
|
||||
|
||||
bool ICollection.IsSynchronized => false;
|
||||
bool ICollection.IsSynchronized { get { return false; } }
|
||||
|
||||
object ICollection.SyncRoot => this;
|
||||
object ICollection.SyncRoot { get { return this; } }
|
||||
|
||||
object IDictionary.this[object key]
|
||||
{
|
||||
get
|
||||
{
|
||||
ProtoPreconditions.CheckNotNull(key, nameof(key));
|
||||
if (key is TKey k)
|
||||
if (!(key is TKey))
|
||||
{
|
||||
TryGetValue(k, out TValue value);
|
||||
return value;
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
TValue value;
|
||||
TryGetValue((TKey)key, out value);
|
||||
return value;
|
||||
}
|
||||
|
||||
set
|
||||
@@ -572,8 +600,11 @@ namespace Google.Protobuf.Collections
|
||||
#endregion
|
||||
|
||||
#region IReadOnlyDictionary explicit interface implementation
|
||||
#if !NET35
|
||||
IEnumerable<TKey> IReadOnlyDictionary<TKey, TValue>.Keys => Keys;
|
||||
|
||||
IEnumerable<TValue> IReadOnlyDictionary<TKey, TValue>.Values => Values;
|
||||
#endif
|
||||
#endregion
|
||||
|
||||
private class DictionaryEnumerator : IDictionaryEnumerator
|
||||
@@ -585,14 +616,20 @@ namespace Google.Protobuf.Collections
|
||||
this.enumerator = enumerator;
|
||||
}
|
||||
|
||||
public bool MoveNext() => enumerator.MoveNext();
|
||||
public bool MoveNext()
|
||||
{
|
||||
return enumerator.MoveNext();
|
||||
}
|
||||
|
||||
public void Reset() => enumerator.Reset();
|
||||
public void Reset()
|
||||
{
|
||||
enumerator.Reset();
|
||||
}
|
||||
|
||||
public object Current => Entry;
|
||||
public DictionaryEntry Entry => new DictionaryEntry(Key, Value);
|
||||
public object Key => enumerator.Current.Key;
|
||||
public object Value => enumerator.Current.Value;
|
||||
public object Current { get { return Entry; } }
|
||||
public DictionaryEntry Entry { get { return new DictionaryEntry(Key, Value); } }
|
||||
public object Key { get { return enumerator.Current.Key; } }
|
||||
public object Value { get { return enumerator.Current.Value; } }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -651,19 +688,28 @@ namespace Google.Protobuf.Collections
|
||||
this.containsCheck = containsCheck;
|
||||
}
|
||||
|
||||
public int Count => parent.Count;
|
||||
public int Count { get { return parent.Count; } }
|
||||
|
||||
public bool IsReadOnly => true;
|
||||
public bool IsReadOnly { get { return true; } }
|
||||
|
||||
public bool IsSynchronized => false;
|
||||
public bool IsSynchronized { get { return false; } }
|
||||
|
||||
public object SyncRoot => parent;
|
||||
public object SyncRoot { get { return parent; } }
|
||||
|
||||
public void Add(T item) => throw new NotSupportedException();
|
||||
public void Add(T item)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public void Clear() => throw new NotSupportedException();
|
||||
public void Clear()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public bool Contains(T item) => containsCheck(item);
|
||||
public bool Contains(T item)
|
||||
{
|
||||
return containsCheck(item);
|
||||
}
|
||||
|
||||
public void CopyTo(T[] array, int arrayIndex)
|
||||
{
|
||||
@@ -686,9 +732,15 @@ namespace Google.Protobuf.Collections
|
||||
return parent.list.Select(projection).GetEnumerator();
|
||||
}
|
||||
|
||||
public bool Remove(T item) => throw new NotSupportedException();
|
||||
public bool Remove(T item)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public void CopyTo(Array array, int index)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
#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.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Google.Protobuf.Collections
|
||||
{
|
||||
/// <summary>
|
||||
/// Read-only wrapper around another dictionary.
|
||||
/// </summary>
|
||||
internal sealed class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
|
||||
{
|
||||
private readonly IDictionary<TKey, TValue> wrapped;
|
||||
|
||||
public ReadOnlyDictionary(IDictionary<TKey, TValue> wrapped)
|
||||
{
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
public void Add(TKey key, TValue value)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
public bool ContainsKey(TKey key)
|
||||
{
|
||||
return wrapped.ContainsKey(key);
|
||||
}
|
||||
|
||||
public ICollection<TKey> Keys
|
||||
{
|
||||
get { return wrapped.Keys; }
|
||||
}
|
||||
|
||||
public bool Remove(TKey key)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
public bool TryGetValue(TKey key, out TValue value)
|
||||
{
|
||||
return wrapped.TryGetValue(key, out value);
|
||||
}
|
||||
|
||||
public ICollection<TValue> Values
|
||||
{
|
||||
get { return wrapped.Values; }
|
||||
}
|
||||
|
||||
public TValue this[TKey key]
|
||||
{
|
||||
get { return wrapped[key]; }
|
||||
set { throw new InvalidOperationException(); }
|
||||
}
|
||||
|
||||
public void Add(KeyValuePair<TKey, TValue> item)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
public bool Contains(KeyValuePair<TKey, TValue> item)
|
||||
{
|
||||
return wrapped.Contains(item);
|
||||
}
|
||||
|
||||
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
|
||||
{
|
||||
wrapped.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return wrapped.Count; }
|
||||
}
|
||||
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public bool Remove(KeyValuePair<TKey, TValue> item)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
|
||||
{
|
||||
return wrapped.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable) wrapped).GetEnumerator();
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return wrapped.Equals(obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return wrapped.GetHashCode();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return wrapped.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,7 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
using System.Threading;
|
||||
|
||||
namespace Google.Protobuf.Collections
|
||||
{
|
||||
@@ -47,7 +48,10 @@ namespace Google.Protobuf.Collections
|
||||
/// supported by Protocol Buffers but nor does it guarantee that all operations will work in such cases.
|
||||
/// </remarks>
|
||||
/// <typeparam name="T">The element type of the repeated field.</typeparam>
|
||||
public sealed class RepeatedField<T> : IList<T>, IList, IDeepCloneable<RepeatedField<T>>, IEquatable<RepeatedField<T>>, IReadOnlyList<T>
|
||||
public sealed class RepeatedField<T> : IList<T>, IList, IDeepCloneable<RepeatedField<T>>, IEquatable<RepeatedField<T>>
|
||||
#if !NET35
|
||||
, IReadOnlyList<T>
|
||||
#endif
|
||||
{
|
||||
private static readonly EqualityComparer<T> EqualityComparer = ProtobufEqualityComparers.GetEqualityComparer<T>();
|
||||
private static readonly T[] EmptyArray = new T[0];
|
||||
@@ -73,7 +77,8 @@ namespace Google.Protobuf.Collections
|
||||
if (array != EmptyArray)
|
||||
{
|
||||
clone.array = (T[])array.Clone();
|
||||
if (clone.array is IDeepCloneable<T>[] cloneableArray)
|
||||
IDeepCloneable<T>[] cloneableArray = clone.array as IDeepCloneable<T>[];
|
||||
if (cloneableArray != null)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
@@ -279,9 +284,8 @@ namespace Google.Protobuf.Collections
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the capacity of the RepeatedField's internal array.
|
||||
/// When set, the internal array is reallocated to the given capacity.
|
||||
/// <exception cref="ArgumentOutOfRangeException">The new value is less than <see cref="Count"/>.</exception>
|
||||
/// Gets and sets the capacity of the RepeatedField's internal array. WHen set, the internal array is reallocated to the given capacity.
|
||||
/// <exception cref="ArgumentOutOfRangeException">The new value is less than Count -or- when Count is less than 0.</exception>
|
||||
/// </summary>
|
||||
public int Capacity
|
||||
{
|
||||
@@ -339,10 +343,7 @@ namespace Google.Protobuf.Collections
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
// Clear the content of the array (so that any objects it referred to can be garbage collected)
|
||||
// but keep the capacity the same. This allows large repeated fields to be reused without
|
||||
// array reallocation.
|
||||
Array.Clear(array, 0, count);
|
||||
array = EmptyArray;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
@@ -351,7 +352,10 @@ namespace Google.Protobuf.Collections
|
||||
/// </summary>
|
||||
/// <param name="item">The item to find.</param>
|
||||
/// <returns><c>true</c> if this collection contains the given item; <c>false</c> otherwise.</returns>
|
||||
public bool Contains(T item) => IndexOf(item) != -1;
|
||||
public bool Contains(T item)
|
||||
{
|
||||
return IndexOf(item) != -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies this collection to the given array.
|
||||
@@ -377,7 +381,7 @@ namespace Google.Protobuf.Collections
|
||||
}
|
||||
Array.Copy(array, index + 1, array, index, count - index - 1);
|
||||
count--;
|
||||
array[count] = default;
|
||||
array[count] = default(T);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -401,7 +405,8 @@ namespace Google.Protobuf.Collections
|
||||
|
||||
// Optimization 1: If the collection we're adding is already a RepeatedField<T>,
|
||||
// we know the values are valid.
|
||||
if (values is RepeatedField<T> otherRepeatedField)
|
||||
var otherRepeatedField = values as RepeatedField<T>;
|
||||
if (otherRepeatedField != null)
|
||||
{
|
||||
EnsureSize(count + otherRepeatedField.count);
|
||||
Array.Copy(otherRepeatedField.array, 0, array, count, otherRepeatedField.count);
|
||||
@@ -411,7 +416,8 @@ namespace Google.Protobuf.Collections
|
||||
|
||||
// Optimization 2: The collection is an ICollection, so we can expand
|
||||
// just once and ask the collection to copy itself into the array.
|
||||
if (values is ICollection collection)
|
||||
var collection = values as ICollection;
|
||||
if (collection != null)
|
||||
{
|
||||
var extraCount = collection.Count;
|
||||
// For reference types and nullable value types, we need to check that there are no nulls
|
||||
@@ -481,15 +487,21 @@ namespace Google.Protobuf.Collections
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public override bool Equals(object obj) => Equals(obj as RepeatedField<T>);
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return Equals(obj as RepeatedField<T>);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enumerator that iterates through a collection.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.
|
||||
/// </returns>
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a hash code for this instance.
|
||||
@@ -514,7 +526,7 @@ namespace Google.Protobuf.Collections
|
||||
/// <returns><c>true</c> if <paramref name="other"/> refers to an equal repeated field; <c>false</c> otherwise.</returns>
|
||||
public bool Equals(RepeatedField<T> other)
|
||||
{
|
||||
if (other is null)
|
||||
if (ReferenceEquals(other, null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -587,7 +599,7 @@ namespace Google.Protobuf.Collections
|
||||
}
|
||||
Array.Copy(array, index + 1, array, index, count - index - 1);
|
||||
count--;
|
||||
array[count] = default;
|
||||
array[count] = default(T);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -633,7 +645,10 @@ namespace Google.Protobuf.Collections
|
||||
#region Explicit interface implementation for IList and ICollection.
|
||||
bool IList.IsFixedSize => false;
|
||||
|
||||
void ICollection.CopyTo(Array array, int index) => Array.Copy(this.array, 0, array, index, count);
|
||||
void ICollection.CopyTo(Array array, int index)
|
||||
{
|
||||
Array.Copy(this.array, 0, array, index, count);
|
||||
}
|
||||
|
||||
bool ICollection.IsSynchronized => false;
|
||||
|
||||
@@ -641,8 +656,8 @@ namespace Google.Protobuf.Collections
|
||||
|
||||
object IList.this[int index]
|
||||
{
|
||||
get => this[index];
|
||||
set => this[index] = (T)value;
|
||||
get { return this[index]; }
|
||||
set { this[index] = (T)value; }
|
||||
}
|
||||
|
||||
int IList.Add(object value)
|
||||
@@ -651,18 +666,32 @@ namespace Google.Protobuf.Collections
|
||||
return count - 1;
|
||||
}
|
||||
|
||||
bool IList.Contains(object value) => (value is T t && Contains(t));
|
||||
bool IList.Contains(object value)
|
||||
{
|
||||
return (value is T && Contains((T)value));
|
||||
}
|
||||
|
||||
int IList.IndexOf(object value) => (value is T t) ? IndexOf(t) : -1;
|
||||
int IList.IndexOf(object value)
|
||||
{
|
||||
if (!(value is T))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return IndexOf((T)value);
|
||||
}
|
||||
|
||||
void IList.Insert(int index, object value) => Insert(index, (T) value);
|
||||
void IList.Insert(int index, object value)
|
||||
{
|
||||
Insert(index, (T) value);
|
||||
}
|
||||
|
||||
void IList.Remove(object value)
|
||||
{
|
||||
if (value is T t)
|
||||
if (!(value is T))
|
||||
{
|
||||
Remove(t);
|
||||
return;
|
||||
}
|
||||
Remove((T)value);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright notice and license
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2022 Google Inc. All rights reserved.
|
||||
// Copyright 2017 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
@@ -30,34 +30,18 @@
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#endregion
|
||||
|
||||
using NUnit.Framework;
|
||||
#if NET35
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Google.Protobuf.Test;
|
||||
|
||||
internal class ParsingPrimitivesTest
|
||||
namespace Google.Protobuf.Compatibility
|
||||
{
|
||||
// Note: test cases use integers rather than bytes as they're easier
|
||||
// to specify in attributes.
|
||||
|
||||
[Test]
|
||||
[TestCase("\ufffd", 255)]
|
||||
[TestCase("A\ufffd", 65, 255)]
|
||||
[TestCase("A\ufffd\ufffdB", 65, 255, 255, 66)]
|
||||
// Overlong form of "space"
|
||||
[TestCase("\ufffd\ufffd", 0xc0, 0xa0)]
|
||||
public void ReadRawString_NonUtf8(string expectedText, params int[] bytes)
|
||||
// .NET Core (at least netstandard1.0) doesn't have Delegate.CreateDelegate, and .NET 3.5 doesn't have
|
||||
// MethodInfo.CreateDelegate. Proxy from one to the other on .NET 3.5...
|
||||
internal static class MethodInfoExtensions
|
||||
{
|
||||
var context = CreateContext(bytes);
|
||||
string text = ParsingPrimitives.ReadRawString(ref context.buffer, ref context.state, bytes.Length);
|
||||
Assert.AreEqual(expectedText, text);
|
||||
}
|
||||
|
||||
private static ParseContext CreateContext(int[] bytes)
|
||||
{
|
||||
byte[] actualBytes = bytes.Select(b => (byte) b).ToArray();
|
||||
ParseContext.Initialize(actualBytes.AsSpan(), out var context);
|
||||
return context;
|
||||
internal static Delegate CreateDelegate(this MethodInfo method, Type type) =>
|
||||
Delegate.CreateDelegate(type, method);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -47,7 +47,11 @@ namespace Google.Protobuf.Compatibility
|
||||
/// </summary>
|
||||
internal static MethodInfo GetGetMethod(this PropertyInfo target)
|
||||
{
|
||||
#if NET35
|
||||
var method = target.GetGetMethod();
|
||||
#else
|
||||
var method = target.GetMethod;
|
||||
#endif
|
||||
return method != null && method.IsPublic ? method : null;
|
||||
}
|
||||
|
||||
@@ -57,7 +61,11 @@ namespace Google.Protobuf.Compatibility
|
||||
/// </summary>
|
||||
internal static MethodInfo GetSetMethod(this PropertyInfo target)
|
||||
{
|
||||
#if NET35
|
||||
var method = target.GetSetMethod();
|
||||
#else
|
||||
var method = target.SetMethod;
|
||||
#endif
|
||||
return method != null && method.IsPublic ? method : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright notice and license
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2022 Google Inc. All rights reserved.
|
||||
// Copyright 2015 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
@@ -30,32 +30,37 @@
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#endregion
|
||||
|
||||
using NUnit.Framework;
|
||||
#if NET35
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.IO;
|
||||
|
||||
namespace Google.Protobuf.Test;
|
||||
|
||||
internal class WritingPrimitivesTest
|
||||
namespace Google.Protobuf.Compatibility
|
||||
{
|
||||
[Test]
|
||||
public void WriteRawString_IllFormedUnicodeString()
|
||||
/// <summary>
|
||||
/// Extension methods for <see cref="Stream"/> in order to provide
|
||||
/// backwards compatibility with .NET 3.5
|
||||
/// </summary>
|
||||
public static class StreamExtensions
|
||||
{
|
||||
// See https://codeblog.jonskeet.uk/2014/11/07/when-is-a-string-not-a-string/
|
||||
char c1 = '\u0058';
|
||||
char c2 = '\ud800';
|
||||
char c3 = '\u0059';
|
||||
string text = new string(new[] { c1, c2, c3 });
|
||||
Span<byte> buffer = new byte[10];
|
||||
WriteContext.Initialize(ref buffer, out var context);
|
||||
WritingPrimitives.WriteString(ref context.buffer, ref context.state, text);
|
||||
// 81920 seems to be the default buffer size used in .NET 4.5.1
|
||||
private const int BUFFER_SIZE = 81920;
|
||||
|
||||
// The high surrogate is written out in a "raw" form, surrounded by the ASCII
|
||||
// characters.
|
||||
byte[] expectedBytes = { 0x5, 0x58, 0xef, 0xbf, 0xbd, 0x59 };
|
||||
Assert.AreEqual(expectedBytes, buffer.Slice(0, context.state.position).ToArray());
|
||||
/// <summary>
|
||||
/// Write the contents of the current stream to the destination stream
|
||||
/// </summary>
|
||||
public static void CopyTo(this Stream source, Stream destination)
|
||||
{
|
||||
if (destination == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(destination));
|
||||
}
|
||||
|
||||
byte[] buffer = new byte[BUFFER_SIZE];
|
||||
int numBytesRead;
|
||||
while ((numBytesRead = source.Read(buffer, 0, buffer.Length)) > 0) {
|
||||
destination.Write(buffer, 0, numBytesRead);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -34,6 +34,7 @@ using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Reflection;
|
||||
|
||||
#if !NET35
|
||||
namespace Google.Protobuf.Compatibility
|
||||
{
|
||||
/// <summary>
|
||||
@@ -111,3 +112,4 @@ namespace Google.Protobuf.Compatibility
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -77,7 +77,7 @@ namespace Google.Protobuf
|
||||
this.codec = codec;
|
||||
}
|
||||
|
||||
internal TValue DefaultValue => codec != null ? codec.DefaultValue : default;
|
||||
internal TValue DefaultValue => codec != null ? codec.DefaultValue : default(TValue);
|
||||
|
||||
internal override Type TargetType => typeof(TTarget);
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace Google.Protobuf
|
||||
|
||||
internal static ExtensionComparer Instance = new ExtensionComparer();
|
||||
}
|
||||
private readonly IDictionary<ObjectIntPair<Type>, Extension> extensions;
|
||||
private IDictionary<ObjectIntPair<Type>, Extension> extensions;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new empty extension registry
|
||||
|
||||
@@ -61,7 +61,8 @@ namespace Google.Protobuf
|
||||
/// </summary>
|
||||
public static TValue Get<TTarget, TValue>(ref ExtensionSet<TTarget> set, Extension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget>
|
||||
{
|
||||
if (TryGetValue(ref set, extension, out IExtensionValue value))
|
||||
IExtensionValue value;
|
||||
if (TryGetValue(ref set, extension, out value))
|
||||
{
|
||||
// The stored ExtensionValue can be a different type to what is being requested.
|
||||
// This happens when the same extension proto is compiled in different assemblies.
|
||||
@@ -97,7 +98,7 @@ namespace Google.Protobuf
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
return extension.DefaultValue;
|
||||
}
|
||||
@@ -108,7 +109,8 @@ namespace Google.Protobuf
|
||||
/// </summary>
|
||||
public static RepeatedField<TValue> Get<TTarget, TValue>(ref ExtensionSet<TTarget> set, RepeatedExtension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget>
|
||||
{
|
||||
if (TryGetValue(ref set, extension, out IExtensionValue value))
|
||||
IExtensionValue value;
|
||||
if (TryGetValue(ref set, extension, out value))
|
||||
{
|
||||
if (value is RepeatedExtensionValue<TValue> extensionValue)
|
||||
{
|
||||
@@ -130,7 +132,7 @@ namespace Google.Protobuf
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -191,7 +193,8 @@ namespace Google.Protobuf
|
||||
/// </summary>
|
||||
public static bool Has<TTarget, TValue>(ref ExtensionSet<TTarget> set, Extension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget>
|
||||
{
|
||||
return TryGetValue(ref set, extension, out IExtensionValue _);
|
||||
IExtensionValue value;
|
||||
return TryGetValue(ref set, extension, out value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -249,18 +252,20 @@ namespace Google.Protobuf
|
||||
/// </summary>
|
||||
public static bool TryMergeFieldFrom<TTarget>(ref ExtensionSet<TTarget> set, ref ParseContext ctx) where TTarget : IExtendableMessage<TTarget>
|
||||
{
|
||||
Extension extension;
|
||||
int lastFieldNumber = WireFormat.GetTagFieldNumber(ctx.LastTag);
|
||||
|
||||
if (set != null && set.ValuesByNumber.TryGetValue(lastFieldNumber, out IExtensionValue extensionValue))
|
||||
IExtensionValue extensionValue;
|
||||
if (set != null && set.ValuesByNumber.TryGetValue(lastFieldNumber, out extensionValue))
|
||||
{
|
||||
extensionValue.MergeFrom(ref ctx);
|
||||
return true;
|
||||
}
|
||||
else if (ctx.ExtensionRegistry != null && ctx.ExtensionRegistry.ContainsInputField(ctx.LastTag, typeof(TTarget), out Extension extension))
|
||||
else if (ctx.ExtensionRegistry != null && ctx.ExtensionRegistry.ContainsInputField(ctx.LastTag, typeof(TTarget), out extension))
|
||||
{
|
||||
IExtensionValue value = extension.CreateValue();
|
||||
value.MergeFrom(ref ctx);
|
||||
set ??= new ExtensionSet<TTarget>();
|
||||
set = (set ?? new ExtensionSet<TTarget>());
|
||||
set.ValuesByNumber.Add(extension.FieldNumber, value);
|
||||
return true;
|
||||
}
|
||||
@@ -285,7 +290,8 @@ namespace Google.Protobuf
|
||||
}
|
||||
foreach (var pair in second.ValuesByNumber)
|
||||
{
|
||||
if (first.ValuesByNumber.TryGetValue(pair.Key, out IExtensionValue value))
|
||||
IExtensionValue value;
|
||||
if (first.ValuesByNumber.TryGetValue(pair.Key, out value))
|
||||
{
|
||||
value.MergeFrom(pair.Value);
|
||||
}
|
||||
@@ -359,7 +365,8 @@ namespace Google.Protobuf
|
||||
}
|
||||
foreach (var pair in ValuesByNumber)
|
||||
{
|
||||
if (!otherSet.ValuesByNumber.TryGetValue(pair.Key, out IExtensionValue secondValue))
|
||||
IExtensionValue secondValue;
|
||||
if (!otherSet.ValuesByNumber.TryGetValue(pair.Key, out secondValue))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
using Google.Protobuf.Collections;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Google.Protobuf
|
||||
{
|
||||
@@ -49,7 +50,7 @@ namespace Google.Protobuf
|
||||
internal sealed class ExtensionValue<T> : IExtensionValue
|
||||
{
|
||||
private T field;
|
||||
private readonly FieldCodec<T> codec;
|
||||
private FieldCodec<T> codec;
|
||||
|
||||
internal ExtensionValue(FieldCodec<T> codec)
|
||||
{
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#endregion
|
||||
|
||||
using Google.Protobuf.Collections;
|
||||
using Google.Protobuf.Compatibility;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -50,105 +51,150 @@ namespace Google.Protobuf
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<string> ForString(uint tag) => ForString(tag, "");
|
||||
public static FieldCodec<string> ForString(uint tag)
|
||||
{
|
||||
return FieldCodec.ForString(tag, "");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for a bytes field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<ByteString> ForBytes(uint tag) => ForBytes(tag, ByteString.Empty);
|
||||
public static FieldCodec<ByteString> ForBytes(uint tag)
|
||||
{
|
||||
return FieldCodec.ForBytes(tag, ByteString.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for a bool field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<bool> ForBool(uint tag) => ForBool(tag, false);
|
||||
public static FieldCodec<bool> ForBool(uint tag)
|
||||
{
|
||||
return FieldCodec.ForBool(tag, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for an int32 field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<int> ForInt32(uint tag) => ForInt32(tag, 0);
|
||||
public static FieldCodec<int> ForInt32(uint tag)
|
||||
{
|
||||
return FieldCodec.ForInt32(tag, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for an sint32 field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<int> ForSInt32(uint tag) => ForSInt32(tag, 0);
|
||||
public static FieldCodec<int> ForSInt32(uint tag)
|
||||
{
|
||||
return FieldCodec.ForSInt32(tag, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for a fixed32 field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<uint> ForFixed32(uint tag) => ForFixed32(tag, 0);
|
||||
public static FieldCodec<uint> ForFixed32(uint tag)
|
||||
{
|
||||
return FieldCodec.ForFixed32(tag, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for an sfixed32 field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<int> ForSFixed32(uint tag) => ForSFixed32(tag, 0);
|
||||
public static FieldCodec<int> ForSFixed32(uint tag)
|
||||
{
|
||||
return FieldCodec.ForSFixed32(tag, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for a uint32 field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<uint> ForUInt32(uint tag) => ForUInt32(tag, 0);
|
||||
public static FieldCodec<uint> ForUInt32(uint tag)
|
||||
{
|
||||
return FieldCodec.ForUInt32(tag, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for an int64 field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<long> ForInt64(uint tag) => ForInt64(tag, 0);
|
||||
public static FieldCodec<long> ForInt64(uint tag)
|
||||
{
|
||||
return FieldCodec.ForInt64(tag, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for an sint64 field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<long> ForSInt64(uint tag) => ForSInt64(tag, 0);
|
||||
public static FieldCodec<long> ForSInt64(uint tag)
|
||||
{
|
||||
return FieldCodec.ForSInt64(tag, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for a fixed64 field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<ulong> ForFixed64(uint tag) => ForFixed64(tag, 0);
|
||||
public static FieldCodec<ulong> ForFixed64(uint tag)
|
||||
{
|
||||
return FieldCodec.ForFixed64(tag, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for an sfixed64 field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<long> ForSFixed64(uint tag) => ForSFixed64(tag, 0);
|
||||
public static FieldCodec<long> ForSFixed64(uint tag)
|
||||
{
|
||||
return FieldCodec.ForSFixed64(tag, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for a uint64 field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<ulong> ForUInt64(uint tag) => ForUInt64(tag, 0);
|
||||
public static FieldCodec<ulong> ForUInt64(uint tag)
|
||||
{
|
||||
return FieldCodec.ForUInt64(tag, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for a float field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<float> ForFloat(uint tag) => ForFloat(tag, 0);
|
||||
public static FieldCodec<float> ForFloat(uint tag)
|
||||
{
|
||||
return FieldCodec.ForFloat(tag, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for a double field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<double> ForDouble(uint tag) => ForDouble(tag, 0);
|
||||
public static FieldCodec<double> ForDouble(uint tag)
|
||||
{
|
||||
return FieldCodec.ForDouble(tag, 0);
|
||||
}
|
||||
|
||||
// Enums are tricky. We can probably use expression trees to build these delegates automatically,
|
||||
// but it's easy to generate the code for it.
|
||||
@@ -160,8 +206,10 @@ namespace Google.Protobuf
|
||||
/// <param name="toInt32">A conversion function from <see cref="Int32"/> to the enum type.</param>
|
||||
/// <param name="fromInt32">A conversion function from the enum type to <see cref="Int32"/>.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<T> ForEnum<T>(uint tag, Func<T, int> toInt32, Func<int, T> fromInt32) =>
|
||||
ForEnum(tag, toInt32, fromInt32, default);
|
||||
public static FieldCodec<T> ForEnum<T>(uint tag, Func<T, int> toInt32, Func<int, T> fromInt32)
|
||||
{
|
||||
return FieldCodec.ForEnum(tag, toInt32, fromInt32, default(T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for a string field with the given tag.
|
||||
@@ -517,7 +565,8 @@ namespace Google.Protobuf
|
||||
/// </summary>
|
||||
internal static FieldCodec<T> GetCodec<T>()
|
||||
{
|
||||
if (!Codecs.TryGetValue(typeof(T), out object value))
|
||||
object value;
|
||||
if (!Codecs.TryGetValue(typeof(T), out value))
|
||||
{
|
||||
throw new InvalidOperationException("Invalid type argument requested for wrapper codec: " + typeof(T));
|
||||
}
|
||||
@@ -526,7 +575,8 @@ namespace Google.Protobuf
|
||||
|
||||
internal static ValueReader<T?> GetReader<T>() where T : struct
|
||||
{
|
||||
if (!Readers.TryGetValue(typeof(T), out object value))
|
||||
object value;
|
||||
if (!Readers.TryGetValue(typeof(T), out value))
|
||||
{
|
||||
throw new InvalidOperationException("Invalid type argument requested for wrapper reader: " + typeof(T));
|
||||
}
|
||||
|
||||
@@ -120,7 +120,8 @@ namespace Google.Protobuf
|
||||
return this;
|
||||
}
|
||||
|
||||
if (!node.Children.TryGetValue(part, out Node childNode))
|
||||
Node childNode;
|
||||
if (!node.Children.TryGetValue(part, out childNode))
|
||||
{
|
||||
createNewBranch = true;
|
||||
childNode = new Node();
|
||||
@@ -332,24 +333,15 @@ namespace Google.Protobuf
|
||||
{
|
||||
if (sourceField != null)
|
||||
{
|
||||
// Well-known wrapper types are represented as nullable primitive types, so we do not "merge" them.
|
||||
// Instead, any non-null value just overwrites the previous value directly.
|
||||
if (field.MessageType.IsWrapperType)
|
||||
var sourceByteString = ((IMessage)sourceField).ToByteString();
|
||||
var destinationValue = (IMessage)field.Accessor.GetValue(destination);
|
||||
if (destinationValue != null)
|
||||
{
|
||||
field.Accessor.SetValue(destination, sourceField);
|
||||
destinationValue.MergeFrom(sourceByteString);
|
||||
}
|
||||
else
|
||||
{
|
||||
var sourceByteString = ((IMessage)sourceField).ToByteString();
|
||||
var destinationValue = (IMessage)field.Accessor.GetValue(destination);
|
||||
if (destinationValue != null)
|
||||
{
|
||||
destinationValue.MergeFrom(sourceByteString);
|
||||
}
|
||||
else
|
||||
{
|
||||
field.Accessor.SetValue(destination, field.MessageType.Parser.ParseFrom(sourceByteString));
|
||||
}
|
||||
field.Accessor.SetValue(destination, field.MessageType.Parser.ParseFrom(sourceByteString));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<!-- If you update this, update the .csproj in the Docker file as well -->
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>C# runtime library for Protocol Buffers - Google's data interchange format.</Description>
|
||||
<Copyright>Copyright 2015, Google Inc.</Copyright>
|
||||
<AssemblyTitle>Google Protocol Buffers</AssemblyTitle>
|
||||
<VersionPrefix>3.21.8</VersionPrefix>
|
||||
<LangVersion>10.0</LangVersion>
|
||||
<VersionPrefix>3.21.12</VersionPrefix>
|
||||
<!-- C# 7.2 is required for Span/BufferWriter/ReadOnlySequence -->
|
||||
<LangVersion>7.2</LangVersion>
|
||||
<Authors>Google Inc.</Authors>
|
||||
<TargetFrameworks>netstandard1.1;netstandard2.0;net45;net50</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
|
||||
@@ -136,5 +136,5 @@ namespace Google.Protobuf
|
||||
{
|
||||
return new InvalidProtocolBufferException("Message was missing required fields");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,13 +62,9 @@ namespace Google.Protobuf
|
||||
internal const string AnyTypeUrlField = "@type";
|
||||
internal const string AnyDiagnosticValueField = "@value";
|
||||
internal const string AnyWellKnownTypeValueField = "value";
|
||||
private const string TypeUrlPrefix = "type.googleapis.com";
|
||||
private const string NameValueSeparator = ": ";
|
||||
private const string ValueSeparator = ", ";
|
||||
private const string MultilineValueSeparator = ",";
|
||||
private const char ObjectOpenBracket = '{';
|
||||
private const char ObjectCloseBracket = '}';
|
||||
private const char ListBracketOpen = '[';
|
||||
private const char ListBracketClose = ']';
|
||||
private const string PropertySeparator = ", ";
|
||||
|
||||
/// <summary>
|
||||
/// Returns a formatter using the default settings.
|
||||
@@ -145,26 +141,11 @@ namespace Google.Protobuf
|
||||
/// Formats the specified message as JSON.
|
||||
/// </summary>
|
||||
/// <param name="message">The message to format.</param>
|
||||
/// <remarks>This method delegates to <c>Format(IMessage, int)</c> with <c>indentationLevel = 0</c>.</remarks>
|
||||
/// <returns>The formatted message.</returns>
|
||||
public string Format(IMessage message) => Format(message, indentationLevel: 0);
|
||||
|
||||
/// <summary>
|
||||
/// Formats the specified message as JSON.
|
||||
/// </summary>
|
||||
/// <param name="message">The message to format.</param>
|
||||
/// <param name="indentationLevel">Indentation level to start at.</param>
|
||||
/// <remarks>To keep consistent indentation when embedding a message inside another JSON string, set <paramref name="indentationLevel"/>. E.g:
|
||||
/// <code>
|
||||
/// var response = $@"{{
|
||||
/// ""data"": { Format(message, indentationLevel: 1) }
|
||||
/// }}"</code>
|
||||
/// </remarks>
|
||||
/// <returns>The formatted message.</returns>
|
||||
public string Format(IMessage message, int indentationLevel)
|
||||
public string Format(IMessage message)
|
||||
{
|
||||
var writer = new StringWriter();
|
||||
Format(message, writer, indentationLevel);
|
||||
Format(message, writer);
|
||||
return writer.ToString();
|
||||
}
|
||||
|
||||
@@ -173,29 +154,19 @@ namespace Google.Protobuf
|
||||
/// </summary>
|
||||
/// <param name="message">The message to format.</param>
|
||||
/// <param name="writer">The TextWriter to write the formatted message to.</param>
|
||||
/// <remarks>This method delegates to <c>Format(IMessage, TextWriter, int)</c> with <c>indentationLevel = 0</c>.</remarks>
|
||||
/// <returns>The formatted message.</returns>
|
||||
public void Format(IMessage message, TextWriter writer) => Format(message, writer, indentationLevel: 0);
|
||||
|
||||
/// <summary>
|
||||
/// Formats the specified message as JSON. When <see cref="Settings.Indentation"/> is not null, start indenting at the specified <paramref name="indentationLevel"/>.
|
||||
/// </summary>
|
||||
/// <param name="message">The message to format.</param>
|
||||
/// <param name="writer">The TextWriter to write the formatted message to.</param>
|
||||
/// <param name="indentationLevel">Indentation level to start at.</param>
|
||||
/// <remarks>To keep consistent indentation when embedding a message inside another JSON string, set <paramref name="indentationLevel"/>.</remarks>
|
||||
public void Format(IMessage message, TextWriter writer, int indentationLevel)
|
||||
public void Format(IMessage message, TextWriter writer)
|
||||
{
|
||||
ProtoPreconditions.CheckNotNull(message, nameof(message));
|
||||
ProtoPreconditions.CheckNotNull(writer, nameof(writer));
|
||||
|
||||
if (message.Descriptor.IsWellKnownType)
|
||||
{
|
||||
WriteWellKnownTypeValue(writer, message.Descriptor, message, indentationLevel);
|
||||
WriteWellKnownTypeValue(writer, message.Descriptor, message);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteMessage(writer, message, indentationLevel);
|
||||
WriteMessage(writer, message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,7 +193,7 @@ namespace Google.Protobuf
|
||||
return diagnosticFormatter.Format(message);
|
||||
}
|
||||
|
||||
private void WriteMessage(TextWriter writer, IMessage message, int indentationLevel)
|
||||
private void WriteMessage(TextWriter writer, IMessage message)
|
||||
{
|
||||
if (message == null)
|
||||
{
|
||||
@@ -231,19 +202,19 @@ namespace Google.Protobuf
|
||||
}
|
||||
if (DiagnosticOnly)
|
||||
{
|
||||
if (message is ICustomDiagnosticMessage customDiagnosticMessage)
|
||||
ICustomDiagnosticMessage customDiagnosticMessage = message as ICustomDiagnosticMessage;
|
||||
if (customDiagnosticMessage != null)
|
||||
{
|
||||
writer.Write(customDiagnosticMessage.ToDiagnosticString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
WriteBracketOpen(writer, ObjectOpenBracket);
|
||||
bool writtenFields = WriteMessageFields(writer, message, false, indentationLevel + 1);
|
||||
WriteBracketClose(writer, ObjectCloseBracket, writtenFields, indentationLevel);
|
||||
writer.Write("{ ");
|
||||
bool writtenFields = WriteMessageFields(writer, message, false);
|
||||
writer.Write(writtenFields ? " }" : "}");
|
||||
}
|
||||
|
||||
private bool WriteMessageFields(TextWriter writer, IMessage message, bool assumeFirstFieldWritten, int indentationLevel)
|
||||
private bool WriteMessageFields(TextWriter writer, IMessage message, bool assumeFirstFieldWritten)
|
||||
{
|
||||
var fields = message.Descriptor.Fields;
|
||||
bool first = !assumeFirstFieldWritten;
|
||||
@@ -257,8 +228,10 @@ namespace Google.Protobuf
|
||||
continue;
|
||||
}
|
||||
|
||||
MaybeWriteValueSeparator(writer, first);
|
||||
MaybeWriteValueWhitespace(writer, indentationLevel);
|
||||
if (!first)
|
||||
{
|
||||
writer.Write(PropertySeparator);
|
||||
}
|
||||
|
||||
if (settings.PreserveProtoFieldNames)
|
||||
{
|
||||
@@ -269,23 +242,13 @@ namespace Google.Protobuf
|
||||
WriteString(writer, accessor.Descriptor.JsonName);
|
||||
}
|
||||
writer.Write(NameValueSeparator);
|
||||
WriteValue(writer, value, indentationLevel);
|
||||
WriteValue(writer, value);
|
||||
|
||||
first = false;
|
||||
}
|
||||
return !first;
|
||||
}
|
||||
|
||||
private void MaybeWriteValueSeparator(TextWriter writer, bool first)
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
writer.Write(settings.Indentation == null ? ValueSeparator : MultilineValueSeparator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether or not a field value should be serialized according to the field,
|
||||
/// its value in the message, and the settings of this formatter.
|
||||
@@ -357,20 +320,39 @@ namespace Google.Protobuf
|
||||
IList list = (IList) value;
|
||||
return list.Count == 0;
|
||||
}
|
||||
return descriptor.FieldType switch
|
||||
switch (descriptor.FieldType)
|
||||
{
|
||||
FieldType.Bool => (bool) value == false,
|
||||
FieldType.Bytes => (ByteString) value == ByteString.Empty,
|
||||
FieldType.String => (string) value == "",
|
||||
FieldType.Double => (double) value == 0.0,
|
||||
FieldType.SInt32 or FieldType.Int32 or FieldType.SFixed32 or FieldType.Enum => (int) value == 0,
|
||||
FieldType.Fixed32 or FieldType.UInt32 => (uint) value == 0,
|
||||
FieldType.Fixed64 or FieldType.UInt64 => (ulong) value == 0,
|
||||
FieldType.SFixed64 or FieldType.Int64 or FieldType.SInt64 => (long) value == 0,
|
||||
FieldType.Float => (float) value == 0f,
|
||||
FieldType.Message or FieldType.Group => value == null,
|
||||
_ => throw new ArgumentException("Invalid field type"),
|
||||
};
|
||||
case FieldType.Bool:
|
||||
return (bool) value == false;
|
||||
case FieldType.Bytes:
|
||||
return (ByteString) value == ByteString.Empty;
|
||||
case FieldType.String:
|
||||
return (string) value == "";
|
||||
case FieldType.Double:
|
||||
return (double) value == 0.0;
|
||||
case FieldType.SInt32:
|
||||
case FieldType.Int32:
|
||||
case FieldType.SFixed32:
|
||||
case FieldType.Enum:
|
||||
return (int) value == 0;
|
||||
case FieldType.Fixed32:
|
||||
case FieldType.UInt32:
|
||||
return (uint) value == 0;
|
||||
case FieldType.Fixed64:
|
||||
case FieldType.UInt64:
|
||||
return (ulong) value == 0;
|
||||
case FieldType.SFixed64:
|
||||
case FieldType.Int64:
|
||||
case FieldType.SInt64:
|
||||
return (long) value == 0;
|
||||
case FieldType.Float:
|
||||
return (float) value == 0f;
|
||||
case FieldType.Message:
|
||||
case FieldType.Group: // Never expect to get this, but...
|
||||
return value == null;
|
||||
default:
|
||||
throw new ArgumentException("Invalid field type");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -381,46 +363,34 @@ namespace Google.Protobuf
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer to write the value to. Must not be null.</param>
|
||||
/// <param name="value">The value to write. May be null.</param>
|
||||
/// <remarks>Delegates to <c>WriteValue(TextWriter, object, int)</c> with <c>indentationLevel = 0</c>.</remarks>
|
||||
public void WriteValue(TextWriter writer, object value) => WriteValue(writer, value, 0);
|
||||
|
||||
/// <summary>
|
||||
/// Writes a single value to the given writer as JSON. Only types understood by
|
||||
/// Protocol Buffers can be written in this way. This method is only exposed for
|
||||
/// advanced use cases; most users should be using <see cref="Format(IMessage)"/>
|
||||
/// or <see cref="Format(IMessage, TextWriter)"/>.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer to write the value to. Must not be null.</param>
|
||||
/// <param name="value">The value to write. May be null.</param>
|
||||
/// <param name="indentationLevel">The current indentationLevel. Not used when <see cref="Settings.Indentation"/> is null.</param>
|
||||
public void WriteValue(TextWriter writer, object value, int indentationLevel)
|
||||
public void WriteValue(TextWriter writer, object value)
|
||||
{
|
||||
if (value == null || value is NullValue)
|
||||
{
|
||||
WriteNull(writer);
|
||||
}
|
||||
else if (value is bool b)
|
||||
else if (value is bool)
|
||||
{
|
||||
writer.Write(b ? "true" : "false");
|
||||
writer.Write((bool)value ? "true" : "false");
|
||||
}
|
||||
else if (value is ByteString byteString)
|
||||
else if (value is ByteString)
|
||||
{
|
||||
// Nothing in Base64 needs escaping
|
||||
writer.Write('"');
|
||||
writer.Write(byteString.ToBase64());
|
||||
writer.Write(((ByteString)value).ToBase64());
|
||||
writer.Write('"');
|
||||
}
|
||||
else if (value is string str)
|
||||
else if (value is string)
|
||||
{
|
||||
WriteString(writer, str);
|
||||
WriteString(writer, (string)value);
|
||||
}
|
||||
else if (value is IDictionary dictionary)
|
||||
else if (value is IDictionary)
|
||||
{
|
||||
WriteDictionary(writer, dictionary, indentationLevel);
|
||||
WriteDictionary(writer, (IDictionary)value);
|
||||
}
|
||||
else if (value is IList list)
|
||||
else if (value is IList)
|
||||
{
|
||||
WriteList(writer, list, indentationLevel);
|
||||
WriteList(writer, (IList)value);
|
||||
}
|
||||
else if (value is int || value is uint)
|
||||
{
|
||||
@@ -467,9 +437,9 @@ namespace Google.Protobuf
|
||||
writer.Write(text);
|
||||
}
|
||||
}
|
||||
else if (value is IMessage message)
|
||||
else if (value is IMessage)
|
||||
{
|
||||
Format(message, writer, indentationLevel);
|
||||
Format((IMessage)value, writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -483,7 +453,7 @@ namespace Google.Protobuf
|
||||
/// values are using the embedded well-known types, in order to allow for dynamic messages
|
||||
/// in the future.
|
||||
/// </summary>
|
||||
private void WriteWellKnownTypeValue(TextWriter writer, MessageDescriptor descriptor, object value, int indentationLevel)
|
||||
private void WriteWellKnownTypeValue(TextWriter writer, MessageDescriptor descriptor, object value)
|
||||
{
|
||||
// Currently, we can never actually get here, because null values are always handled by the caller. But if we *could*,
|
||||
// this would do the right thing.
|
||||
@@ -499,8 +469,9 @@ namespace Google.Protobuf
|
||||
// WriteValue will do the right thing.)
|
||||
if (descriptor.IsWrapperType)
|
||||
{
|
||||
if (value is IMessage message)
|
||||
if (value is IMessage)
|
||||
{
|
||||
var message = (IMessage) value;
|
||||
value = message.Descriptor.Fields[WrappersReflection.WrapperValueFieldNumber].Accessor.GetValue(message);
|
||||
}
|
||||
WriteValue(writer, value);
|
||||
@@ -523,26 +494,26 @@ namespace Google.Protobuf
|
||||
}
|
||||
if (descriptor.FullName == Struct.Descriptor.FullName)
|
||||
{
|
||||
WriteStruct(writer, (IMessage)value, indentationLevel);
|
||||
WriteStruct(writer, (IMessage)value);
|
||||
return;
|
||||
}
|
||||
if (descriptor.FullName == ListValue.Descriptor.FullName)
|
||||
{
|
||||
var fieldAccessor = descriptor.Fields[ListValue.ValuesFieldNumber].Accessor;
|
||||
WriteList(writer, (IList)fieldAccessor.GetValue((IMessage)value), indentationLevel);
|
||||
WriteList(writer, (IList)fieldAccessor.GetValue((IMessage)value));
|
||||
return;
|
||||
}
|
||||
if (descriptor.FullName == Value.Descriptor.FullName)
|
||||
{
|
||||
WriteStructFieldValue(writer, (IMessage)value, indentationLevel);
|
||||
WriteStructFieldValue(writer, (IMessage)value);
|
||||
return;
|
||||
}
|
||||
if (descriptor.FullName == Any.Descriptor.FullName)
|
||||
{
|
||||
WriteAny(writer, (IMessage)value, indentationLevel);
|
||||
WriteAny(writer, (IMessage)value);
|
||||
return;
|
||||
}
|
||||
WriteMessage(writer, (IMessage)value, indentationLevel);
|
||||
WriteMessage(writer, (IMessage)value);
|
||||
}
|
||||
|
||||
private void WriteTimestamp(TextWriter writer, IMessage value)
|
||||
@@ -570,7 +541,7 @@ namespace Google.Protobuf
|
||||
writer.Write(FieldMask.ToJson(paths, DiagnosticOnly));
|
||||
}
|
||||
|
||||
private void WriteAny(TextWriter writer, IMessage value, int indentationLevel)
|
||||
private void WriteAny(TextWriter writer, IMessage value)
|
||||
{
|
||||
if (DiagnosticOnly)
|
||||
{
|
||||
@@ -587,23 +558,23 @@ namespace Google.Protobuf
|
||||
throw new InvalidOperationException($"Type registry has no descriptor for type name '{typeName}'");
|
||||
}
|
||||
IMessage message = descriptor.Parser.ParseFrom(data);
|
||||
WriteBracketOpen(writer, ObjectOpenBracket);
|
||||
writer.Write("{ ");
|
||||
WriteString(writer, AnyTypeUrlField);
|
||||
writer.Write(NameValueSeparator);
|
||||
WriteString(writer, typeUrl);
|
||||
|
||||
if (descriptor.IsWellKnownType)
|
||||
{
|
||||
writer.Write(ValueSeparator);
|
||||
writer.Write(PropertySeparator);
|
||||
WriteString(writer, AnyWellKnownTypeValueField);
|
||||
writer.Write(NameValueSeparator);
|
||||
WriteWellKnownTypeValue(writer, descriptor, message, indentationLevel);
|
||||
WriteWellKnownTypeValue(writer, descriptor, message);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteMessageFields(writer, message, true, indentationLevel);
|
||||
WriteMessageFields(writer, message, true);
|
||||
}
|
||||
WriteBracketClose(writer, ObjectCloseBracket, true, indentationLevel);
|
||||
writer.Write(" }");
|
||||
}
|
||||
|
||||
private void WriteDiagnosticOnlyAny(TextWriter writer, IMessage value)
|
||||
@@ -614,7 +585,7 @@ namespace Google.Protobuf
|
||||
WriteString(writer, AnyTypeUrlField);
|
||||
writer.Write(NameValueSeparator);
|
||||
WriteString(writer, typeUrl);
|
||||
writer.Write(ValueSeparator);
|
||||
writer.Write(PropertySeparator);
|
||||
WriteString(writer, AnyDiagnosticValueField);
|
||||
writer.Write(NameValueSeparator);
|
||||
writer.Write('"');
|
||||
@@ -623,9 +594,9 @@ namespace Google.Protobuf
|
||||
writer.Write(" }");
|
||||
}
|
||||
|
||||
private void WriteStruct(TextWriter writer, IMessage message, int indentationLevel)
|
||||
private void WriteStruct(TextWriter writer, IMessage message)
|
||||
{
|
||||
WriteBracketOpen(writer, ObjectOpenBracket);
|
||||
writer.Write("{ ");
|
||||
IDictionary fields = (IDictionary) message.Descriptor.Fields[Struct.FieldsFieldNumber].Accessor.GetValue(message);
|
||||
bool first = true;
|
||||
foreach (DictionaryEntry entry in fields)
|
||||
@@ -637,17 +608,19 @@ namespace Google.Protobuf
|
||||
throw new InvalidOperationException("Struct fields cannot have an empty key or a null value.");
|
||||
}
|
||||
|
||||
MaybeWriteValueSeparator(writer, first);
|
||||
MaybeWriteValueWhitespace(writer, indentationLevel + 1);
|
||||
if (!first)
|
||||
{
|
||||
writer.Write(PropertySeparator);
|
||||
}
|
||||
WriteString(writer, key);
|
||||
writer.Write(NameValueSeparator);
|
||||
WriteStructFieldValue(writer, value, indentationLevel + 1);
|
||||
WriteStructFieldValue(writer, value);
|
||||
first = false;
|
||||
}
|
||||
WriteBracketClose(writer, ObjectCloseBracket, !first, indentationLevel);
|
||||
writer.Write(first ? "}" : " }");
|
||||
}
|
||||
|
||||
private void WriteStructFieldValue(TextWriter writer, IMessage message, int indentationLevel)
|
||||
private void WriteStructFieldValue(TextWriter writer, IMessage message)
|
||||
{
|
||||
var specifiedField = message.Descriptor.Oneofs[0].Accessor.GetCaseFieldDescriptor(message);
|
||||
if (specifiedField == null)
|
||||
@@ -668,7 +641,7 @@ namespace Google.Protobuf
|
||||
case Value.ListValueFieldNumber:
|
||||
// Structs and ListValues are nested messages, and already well-known types.
|
||||
var nestedMessage = (IMessage) specifiedField.Accessor.GetValue(message);
|
||||
WriteWellKnownTypeValue(writer, nestedMessage.Descriptor, nestedMessage, indentationLevel);
|
||||
WriteWellKnownTypeValue(writer, nestedMessage.Descriptor, nestedMessage);
|
||||
return;
|
||||
case Value.NullValueFieldNumber:
|
||||
WriteNull(writer);
|
||||
@@ -678,40 +651,43 @@ namespace Google.Protobuf
|
||||
}
|
||||
}
|
||||
|
||||
internal void WriteList(TextWriter writer, IList list, int indentationLevel = 0)
|
||||
internal void WriteList(TextWriter writer, IList list)
|
||||
{
|
||||
WriteBracketOpen(writer, ListBracketOpen);
|
||||
|
||||
writer.Write("[ ");
|
||||
bool first = true;
|
||||
foreach (var value in list)
|
||||
{
|
||||
MaybeWriteValueSeparator(writer, first);
|
||||
MaybeWriteValueWhitespace(writer, indentationLevel + 1);
|
||||
WriteValue(writer, value, indentationLevel + 1);
|
||||
if (!first)
|
||||
{
|
||||
writer.Write(PropertySeparator);
|
||||
}
|
||||
WriteValue(writer, value);
|
||||
first = false;
|
||||
}
|
||||
|
||||
WriteBracketClose(writer, ListBracketClose, !first, indentationLevel);
|
||||
writer.Write(first ? "]" : " ]");
|
||||
}
|
||||
|
||||
internal void WriteDictionary(TextWriter writer, IDictionary dictionary, int indentationLevel = 0)
|
||||
internal void WriteDictionary(TextWriter writer, IDictionary dictionary)
|
||||
{
|
||||
WriteBracketOpen(writer, ObjectOpenBracket);
|
||||
|
||||
writer.Write("{ ");
|
||||
bool first = true;
|
||||
// This will box each pair. Could use IDictionaryEnumerator, but that's ugly in terms of disposal.
|
||||
foreach (DictionaryEntry pair in dictionary)
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
writer.Write(PropertySeparator);
|
||||
}
|
||||
string keyText;
|
||||
if (pair.Key is string s)
|
||||
if (pair.Key is string)
|
||||
{
|
||||
keyText = s;
|
||||
keyText = (string) pair.Key;
|
||||
}
|
||||
else if (pair.Key is bool b)
|
||||
else if (pair.Key is bool)
|
||||
{
|
||||
keyText = b ? "true" : "false";
|
||||
keyText = (bool) pair.Key ? "true" : "false";
|
||||
}
|
||||
else if (pair.Key is int || pair.Key is uint || pair.Key is long || pair.Key is ulong)
|
||||
else if (pair.Key is int || pair.Key is uint | pair.Key is long || pair.Key is ulong)
|
||||
{
|
||||
keyText = ((IFormattable) pair.Key).ToString("d", CultureInfo.InvariantCulture);
|
||||
}
|
||||
@@ -723,16 +699,12 @@ namespace Google.Protobuf
|
||||
}
|
||||
throw new ArgumentException("Unhandled dictionary key type: " + pair.Key.GetType());
|
||||
}
|
||||
|
||||
MaybeWriteValueSeparator(writer, first);
|
||||
MaybeWriteValueWhitespace(writer, indentationLevel + 1);
|
||||
WriteString(writer, keyText);
|
||||
writer.Write(NameValueSeparator);
|
||||
WriteValue(writer, pair.Value);
|
||||
first = false;
|
||||
}
|
||||
|
||||
WriteBracketClose(writer, ObjectCloseBracket, !first, indentationLevel);
|
||||
writer.Write(first ? "}" : " }");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -816,49 +788,6 @@ namespace Google.Protobuf
|
||||
writer.Write(Hex[(c >> 0) & 0xf]);
|
||||
}
|
||||
|
||||
private void WriteBracketOpen(TextWriter writer, char openChar)
|
||||
{
|
||||
writer.Write(openChar);
|
||||
if (settings.Indentation == null)
|
||||
{
|
||||
writer.Write(' ');
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteBracketClose(TextWriter writer, char closeChar, bool hasFields, int indentationLevel)
|
||||
{
|
||||
if (hasFields)
|
||||
{
|
||||
if (settings.Indentation != null)
|
||||
{
|
||||
writer.WriteLine();
|
||||
WriteIndentation(writer, indentationLevel);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write(" ");
|
||||
}
|
||||
}
|
||||
|
||||
writer.Write(closeChar);
|
||||
}
|
||||
|
||||
private void MaybeWriteValueWhitespace(TextWriter writer, int indentationLevel)
|
||||
{
|
||||
if (settings.Indentation != null) {
|
||||
writer.WriteLine();
|
||||
WriteIndentation(writer, indentationLevel);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteIndentation(TextWriter writer, int indentationLevel)
|
||||
{
|
||||
for (int i = 0; i < indentationLevel; i++)
|
||||
{
|
||||
writer.Write(settings.Indentation);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Settings controlling JSON formatting.
|
||||
/// </summary>
|
||||
@@ -899,10 +828,6 @@ namespace Google.Protobuf
|
||||
/// </summary>
|
||||
public bool PreserveProtoFieldNames { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indentation string, used for formatting. Setting null disables indentation.
|
||||
/// </summary>
|
||||
public string Indentation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="Settings"/> object with the specified formatting of default values
|
||||
@@ -930,54 +855,40 @@ namespace Google.Protobuf
|
||||
/// <param name="typeRegistry">The <see cref="TypeRegistry"/> to use when formatting <see cref="Any"/> messages. TypeRegistry.Empty will be used if it is null.</param>
|
||||
/// <param name="formatEnumsAsIntegers"><c>true</c> to format the enums as integers; <c>false</c> to format enums as enum names.</param>
|
||||
/// <param name="preserveProtoFieldNames"><c>true</c> to preserve proto field names; <c>false</c> to convert them to lowerCamelCase.</param>
|
||||
/// <param name="indentation">The indentation string to use for multi-line formatting. <c>null</c> to disable multi-line format.</param>
|
||||
private Settings(bool formatDefaultValues,
|
||||
TypeRegistry typeRegistry,
|
||||
bool formatEnumsAsIntegers,
|
||||
bool preserveProtoFieldNames,
|
||||
string indentation = null)
|
||||
bool preserveProtoFieldNames)
|
||||
{
|
||||
FormatDefaultValues = formatDefaultValues;
|
||||
TypeRegistry = typeRegistry ?? TypeRegistry.Empty;
|
||||
FormatEnumsAsIntegers = formatEnumsAsIntegers;
|
||||
PreserveProtoFieldNames = preserveProtoFieldNames;
|
||||
Indentation = indentation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="Settings"/> object with the specified formatting of default values and the current settings.
|
||||
/// </summary>
|
||||
/// <param name="formatDefaultValues"><c>true</c> if default values (0, empty strings etc) should be formatted; <c>false</c> otherwise.</param>
|
||||
public Settings WithFormatDefaultValues(bool formatDefaultValues) => new Settings(formatDefaultValues, TypeRegistry, FormatEnumsAsIntegers, PreserveProtoFieldNames, Indentation);
|
||||
public Settings WithFormatDefaultValues(bool formatDefaultValues) => new Settings(formatDefaultValues, TypeRegistry, FormatEnumsAsIntegers, PreserveProtoFieldNames);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="Settings"/> object with the specified type registry and the current settings.
|
||||
/// </summary>
|
||||
/// <param name="typeRegistry">The <see cref="TypeRegistry"/> to use when formatting <see cref="Any"/> messages.</param>
|
||||
public Settings WithTypeRegistry(TypeRegistry typeRegistry) => new Settings(FormatDefaultValues, typeRegistry, FormatEnumsAsIntegers, PreserveProtoFieldNames, Indentation);
|
||||
public Settings WithTypeRegistry(TypeRegistry typeRegistry) => new Settings(FormatDefaultValues, typeRegistry, FormatEnumsAsIntegers, PreserveProtoFieldNames);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="Settings"/> object with the specified enums formatting option and the current settings.
|
||||
/// </summary>
|
||||
/// <param name="formatEnumsAsIntegers"><c>true</c> to format the enums as integers; <c>false</c> to format enums as enum names.</param>
|
||||
public Settings WithFormatEnumsAsIntegers(bool formatEnumsAsIntegers) => new Settings(FormatDefaultValues, TypeRegistry, formatEnumsAsIntegers, PreserveProtoFieldNames, Indentation);
|
||||
public Settings WithFormatEnumsAsIntegers(bool formatEnumsAsIntegers) => new Settings(FormatDefaultValues, TypeRegistry, formatEnumsAsIntegers, PreserveProtoFieldNames);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="Settings"/> object with the specified field name formatting option and the current settings.
|
||||
/// </summary>
|
||||
/// <param name="preserveProtoFieldNames"><c>true</c> to preserve proto field names; <c>false</c> to convert them to lowerCamelCase.</param>
|
||||
public Settings WithPreserveProtoFieldNames(bool preserveProtoFieldNames) => new Settings(FormatDefaultValues, TypeRegistry, FormatEnumsAsIntegers, preserveProtoFieldNames, Indentation);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="Settings"/> object with the specified indentation and the current settings.
|
||||
/// </summary>
|
||||
/// <param name="indentation">The string to output for each level of indentation (nesting). The default is two spaces per level. Use null to disable indentation entirely.</param>
|
||||
/// <remarks>A non-null value for <see cref="Indentation"/> will insert additional line-breaks to the JSON output.
|
||||
/// Each line will contain either a single value, or braces. The default line-break is determined by <see cref="Environment.NewLine"/>,
|
||||
/// which is <c>"\n"</c> on Unix platforms, and <c>"\r\n"</c> on Windows. If <see cref="JsonFormatter"/> seems to produce empty lines,
|
||||
/// you need to pass a <see cref="TextWriter"/> that uses a <c>"\n"</c> newline. See <see cref="JsonFormatter.Format(Google.Protobuf.IMessage, TextWriter)"/>.
|
||||
/// </remarks>
|
||||
public Settings WithIndentation(string indentation = " ") => new Settings(FormatDefaultValues, TypeRegistry, FormatEnumsAsIntegers, PreserveProtoFieldNames, indentation);
|
||||
public Settings WithPreserveProtoFieldNames(bool preserveProtoFieldNames) => new Settings(FormatDefaultValues, TypeRegistry, FormatEnumsAsIntegers, preserveProtoFieldNames);
|
||||
}
|
||||
|
||||
// Effectively a cache of mapping from enum values to the original name as specified in the proto file,
|
||||
@@ -1005,8 +916,9 @@ namespace Google.Protobuf
|
||||
}
|
||||
}
|
||||
|
||||
string originalName;
|
||||
// If this returns false, originalName will be null, which is what we want.
|
||||
nameMapping.TryGetValue(value, out string originalName);
|
||||
nameMapping.TryGetValue(value, out originalName);
|
||||
return originalName;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,8 @@ namespace Google.Protobuf
|
||||
|
||||
// TODO: Consider introducing a class containing parse state of the parser, tokenizer and depth. That would simplify these handlers
|
||||
// and the signatures of various methods.
|
||||
private static readonly Dictionary<string, Action<JsonParser, IMessage, JsonTokenizer>> WellKnownTypeHandlers = new()
|
||||
private static readonly Dictionary<string, Action<JsonParser, IMessage, JsonTokenizer>>
|
||||
WellKnownTypeHandlers = new Dictionary<string, Action<JsonParser, IMessage, JsonTokenizer>>
|
||||
{
|
||||
{ Timestamp.Descriptor.FullName, (parser, message, tokenizer) => MergeTimestamp(message, tokenizer.Next()) },
|
||||
{ Duration.Descriptor.FullName, (parser, message, tokenizer) => MergeDuration(message, tokenizer.Next()) },
|
||||
@@ -155,7 +156,8 @@ namespace Google.Protobuf
|
||||
}
|
||||
if (message.Descriptor.IsWellKnownType)
|
||||
{
|
||||
if (WellKnownTypeHandlers.TryGetValue(message.Descriptor.FullName, out Action<JsonParser, IMessage, JsonTokenizer> handler))
|
||||
Action<JsonParser, IMessage, JsonTokenizer> handler;
|
||||
if (WellKnownTypeHandlers.TryGetValue(message.Descriptor.FullName, out handler))
|
||||
{
|
||||
handler(this, message, tokenizer);
|
||||
return;
|
||||
@@ -185,7 +187,8 @@ namespace Google.Protobuf
|
||||
throw new InvalidOperationException("Unexpected token type " + token.Type);
|
||||
}
|
||||
string name = token.StringValue;
|
||||
if (jsonFieldMap.TryGetValue(name, out FieldDescriptor field))
|
||||
FieldDescriptor field;
|
||||
if (jsonFieldMap.TryGetValue(name, out field))
|
||||
{
|
||||
if (field.ContainingOneof != null)
|
||||
{
|
||||
@@ -300,7 +303,11 @@ namespace Google.Protobuf
|
||||
}
|
||||
object key = ParseMapKey(keyField, token.StringValue);
|
||||
object value = ParseSingleValue(valueField, tokenizer);
|
||||
dictionary[key] = value ?? throw new InvalidProtocolBufferException("Map values must not be null");
|
||||
if (value == null)
|
||||
{
|
||||
throw new InvalidProtocolBufferException("Map values must not be null");
|
||||
}
|
||||
dictionary[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -642,15 +649,19 @@ namespace Google.Protobuf
|
||||
{
|
||||
return float.NaN;
|
||||
}
|
||||
float converted = (float) value;
|
||||
// If the value is out of range of float, the cast representation will be infinite.
|
||||
// If the original value was infinite as well, that's fine - we'll return the 32-bit
|
||||
// version (with the correct sign).
|
||||
if (float.IsInfinity(converted) && !double.IsInfinity(value))
|
||||
if (value > float.MaxValue || value < float.MinValue)
|
||||
{
|
||||
if (double.IsPositiveInfinity(value))
|
||||
{
|
||||
return float.PositiveInfinity;
|
||||
}
|
||||
if (double.IsNegativeInfinity(value))
|
||||
{
|
||||
return float.NegativeInfinity;
|
||||
}
|
||||
throw new InvalidProtocolBufferException($"Value out of range: {value}");
|
||||
}
|
||||
return converted;
|
||||
return (float) value;
|
||||
case FieldType.Enum:
|
||||
CheckInteger(value);
|
||||
// Just return it as an int, and let the CLR convert it.
|
||||
@@ -842,7 +853,7 @@ namespace Google.Protobuf
|
||||
if (secondsToAdd < 0 && nanosToAdd > 0)
|
||||
{
|
||||
secondsToAdd++;
|
||||
nanosToAdd -= Duration.NanosecondsPerSecond;
|
||||
nanosToAdd = nanosToAdd - Duration.NanosecondsPerSecond;
|
||||
}
|
||||
if (secondsToAdd != 0 || nanosToAdd != 0)
|
||||
{
|
||||
@@ -1038,20 +1049,23 @@ namespace Google.Protobuf
|
||||
/// when unknown fields are encountered.
|
||||
/// </summary>
|
||||
/// <param name="ignoreUnknownFields"><c>true</c> if unknown fields should be ignored when parsing; <c>false</c> to throw an exception.</param>
|
||||
public Settings WithIgnoreUnknownFields(bool ignoreUnknownFields) => new(RecursionLimit, TypeRegistry, ignoreUnknownFields);
|
||||
public Settings WithIgnoreUnknownFields(bool ignoreUnknownFields) =>
|
||||
new Settings(RecursionLimit, TypeRegistry, ignoreUnknownFields);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="Settings"/> object based on this one, but with the specified recursion limit.
|
||||
/// </summary>
|
||||
/// <param name="recursionLimit">The new recursion limit.</param>
|
||||
public Settings WithRecursionLimit(int recursionLimit) => new(recursionLimit, TypeRegistry, IgnoreUnknownFields);
|
||||
public Settings WithRecursionLimit(int recursionLimit) =>
|
||||
new Settings(recursionLimit, TypeRegistry, IgnoreUnknownFields);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="Settings"/> object based on this one, but with the specified type registry.
|
||||
/// </summary>
|
||||
/// <param name="typeRegistry">The new type registry. Must not be null.</param>
|
||||
public Settings WithTypeRegistry(TypeRegistry typeRegistry) =>
|
||||
new(RecursionLimit,
|
||||
new Settings(
|
||||
RecursionLimit,
|
||||
ProtoPreconditions.CheckNotNull(typeRegistry, nameof(typeRegistry)),
|
||||
IgnoreUnknownFields);
|
||||
}
|
||||
|
||||
@@ -36,14 +36,24 @@ namespace Google.Protobuf
|
||||
{
|
||||
internal sealed class JsonToken : IEquatable<JsonToken>
|
||||
{
|
||||
internal static JsonToken Null { get; } = new JsonToken(TokenType.Null);
|
||||
internal static JsonToken False { get; } = new JsonToken(TokenType.False);
|
||||
internal static JsonToken True { get; } = new JsonToken(TokenType.True);
|
||||
internal static JsonToken StartObject { get; } = new JsonToken(TokenType.StartObject);
|
||||
internal static JsonToken EndObject { get; } = new JsonToken(TokenType.EndObject);
|
||||
internal static JsonToken StartArray { get; } = new JsonToken(TokenType.StartArray);
|
||||
internal static JsonToken EndArray { get; } = new JsonToken(TokenType.EndArray);
|
||||
internal static JsonToken EndDocument { get; } = new JsonToken(TokenType.EndDocument);
|
||||
// Tokens with no value can be reused.
|
||||
private static readonly JsonToken _true = new JsonToken(TokenType.True);
|
||||
private static readonly JsonToken _false = new JsonToken(TokenType.False);
|
||||
private static readonly JsonToken _null = new JsonToken(TokenType.Null);
|
||||
private static readonly JsonToken startObject = new JsonToken(TokenType.StartObject);
|
||||
private static readonly JsonToken endObject = new JsonToken(TokenType.EndObject);
|
||||
private static readonly JsonToken startArray = new JsonToken(TokenType.StartArray);
|
||||
private static readonly JsonToken endArray = new JsonToken(TokenType.EndArray);
|
||||
private static readonly JsonToken endDocument = new JsonToken(TokenType.EndDocument);
|
||||
|
||||
internal static JsonToken Null { get { return _null; } }
|
||||
internal static JsonToken False { get { return _false; } }
|
||||
internal static JsonToken True { get { return _true; } }
|
||||
internal static JsonToken StartObject{ get { return startObject; } }
|
||||
internal static JsonToken EndObject { get { return endObject; } }
|
||||
internal static JsonToken StartArray { get { return startArray; } }
|
||||
internal static JsonToken EndArray { get { return endArray; } }
|
||||
internal static JsonToken EndDocument { get { return endDocument; } }
|
||||
|
||||
internal static JsonToken Name(string name)
|
||||
{
|
||||
@@ -84,9 +94,9 @@ namespace Google.Protobuf
|
||||
private readonly string stringValue;
|
||||
private readonly double numberValue;
|
||||
|
||||
internal TokenType Type => type;
|
||||
internal string StringValue => stringValue;
|
||||
internal double NumberValue => numberValue;
|
||||
internal TokenType Type { get { return type; } }
|
||||
internal string StringValue { get { return stringValue; } }
|
||||
internal double NumberValue { get { return numberValue; } }
|
||||
|
||||
private JsonToken(TokenType type, string stringValue = null, double numberValue = 0)
|
||||
{
|
||||
@@ -95,7 +105,10 @@ namespace Google.Protobuf
|
||||
this.numberValue = numberValue;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj) => Equals(obj as JsonToken);
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return Equals(obj as JsonToken);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
@@ -111,26 +124,38 @@ namespace Google.Protobuf
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return type switch
|
||||
switch (type)
|
||||
{
|
||||
TokenType.Null => "null",
|
||||
TokenType.True => "true",
|
||||
TokenType.False => "false",
|
||||
TokenType.Name => $"name ({stringValue})",
|
||||
TokenType.StringValue => $"value ({stringValue})",
|
||||
TokenType.Number => $"number ({numberValue})",
|
||||
TokenType.StartObject => "start-object",
|
||||
TokenType.EndObject => "end-object",
|
||||
TokenType.StartArray => "start-array",
|
||||
TokenType.EndArray => "end-array",
|
||||
TokenType.EndDocument => "end-document",
|
||||
_ => throw new InvalidOperationException($"Token is of unknown type {type}"),
|
||||
};
|
||||
case TokenType.Null:
|
||||
return "null";
|
||||
case TokenType.True:
|
||||
return "true";
|
||||
case TokenType.False:
|
||||
return "false";
|
||||
case TokenType.Name:
|
||||
return "name (" + stringValue + ")";
|
||||
case TokenType.StringValue:
|
||||
return "value (" + stringValue + ")";
|
||||
case TokenType.Number:
|
||||
return "number (" + numberValue + ")";
|
||||
case TokenType.StartObject:
|
||||
return "start-object";
|
||||
case TokenType.EndObject:
|
||||
return "end-object";
|
||||
case TokenType.StartArray:
|
||||
return "start-array";
|
||||
case TokenType.EndArray:
|
||||
return "end-array";
|
||||
case TokenType.EndDocument:
|
||||
return "end-document";
|
||||
default:
|
||||
throw new InvalidOperationException("Token is of unknown type " + type);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Equals(JsonToken other)
|
||||
{
|
||||
if (other is null)
|
||||
if (ReferenceEquals(other, null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
@@ -363,19 +362,29 @@ namespace Google.Protobuf
|
||||
private char ReadEscapedCharacter()
|
||||
{
|
||||
char c = reader.ReadOrFail("Unexpected end of text while reading character escape sequence");
|
||||
return c switch
|
||||
switch (c)
|
||||
{
|
||||
'n' => '\n',
|
||||
'\\' => '\\',
|
||||
'b' => '\b',
|
||||
'f' => '\f',
|
||||
'r' => '\r',
|
||||
't' => '\t',
|
||||
'"' => '"',
|
||||
'/' => '/',
|
||||
'u' => ReadUnicodeEscape(),
|
||||
_ => throw reader.CreateException(string.Format(CultureInfo.InvariantCulture, "Invalid character in character escape sequence: U+{0:x4}", (int)c)),
|
||||
};
|
||||
case 'n':
|
||||
return '\n';
|
||||
case '\\':
|
||||
return '\\';
|
||||
case 'b':
|
||||
return '\b';
|
||||
case 'f':
|
||||
return '\f';
|
||||
case 'r':
|
||||
return '\r';
|
||||
case 't':
|
||||
return '\t';
|
||||
case '"':
|
||||
return '"';
|
||||
case '/':
|
||||
return '/';
|
||||
case 'u':
|
||||
return ReadUnicodeEscape();
|
||||
default:
|
||||
throw reader.CreateException(string.Format(CultureInfo.InvariantCulture, "Invalid character in character escape sequence: U+{0:x4}", (int) c));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -489,7 +498,8 @@ namespace Google.Protobuf
|
||||
throw reader.CreateException("Invalid numeric literal");
|
||||
}
|
||||
builder.Append(first);
|
||||
char? next = ConsumeDigits(builder, out int digitCount);
|
||||
int digitCount;
|
||||
char? next = ConsumeDigits(builder, out digitCount);
|
||||
if (first == '0' && digitCount != 0)
|
||||
{
|
||||
throw reader.CreateException("Invalid numeric literal: leading 0 for non-zero value.");
|
||||
@@ -500,7 +510,8 @@ namespace Google.Protobuf
|
||||
private char? ReadFrac(StringBuilder builder)
|
||||
{
|
||||
builder.Append('.'); // Already consumed this
|
||||
char? next = ConsumeDigits(builder, out int digitCount);
|
||||
int digitCount;
|
||||
char? next = ConsumeDigits(builder, out digitCount);
|
||||
if (digitCount == 0)
|
||||
{
|
||||
throw reader.CreateException("Invalid numeric literal: fraction with no trailing digits");
|
||||
@@ -524,7 +535,8 @@ namespace Google.Protobuf
|
||||
{
|
||||
reader.PushBack(next.Value);
|
||||
}
|
||||
next = ConsumeDigits(builder, out int digitCount);
|
||||
int digitCount;
|
||||
next = ConsumeDigits(builder, out digitCount);
|
||||
if (digitCount == 0)
|
||||
{
|
||||
throw reader.CreateException("Invalid numeric literal: exponent without value");
|
||||
@@ -579,13 +591,20 @@ namespace Google.Protobuf
|
||||
{
|
||||
containerStack.Pop();
|
||||
var parent = containerStack.Peek();
|
||||
state = parent switch
|
||||
switch (parent)
|
||||
{
|
||||
ContainerType.Object => State.ObjectAfterProperty,
|
||||
ContainerType.Array => State.ArrayAfterValue,
|
||||
ContainerType.Document => State.ExpectedEndOfDocument,
|
||||
_ => throw new InvalidOperationException("Unexpected container type: " + parent),
|
||||
};
|
||||
case ContainerType.Object:
|
||||
state = State.ObjectAfterProperty;
|
||||
break;
|
||||
case ContainerType.Array:
|
||||
state = State.ArrayAfterValue;
|
||||
break;
|
||||
case ContainerType.Document:
|
||||
state = State.ExpectedEndOfDocument;
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException("Unexpected container type: " + parent);
|
||||
}
|
||||
}
|
||||
|
||||
private enum ContainerType
|
||||
|
||||
@@ -51,20 +51,34 @@ namespace Google.Protobuf
|
||||
bytesLeft = size;
|
||||
}
|
||||
|
||||
public override bool CanRead => true;
|
||||
public override bool CanSeek => false;
|
||||
public override bool CanWrite => false;
|
||||
public override bool CanRead
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool CanSeek
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public override bool CanWrite
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
}
|
||||
|
||||
public override long Length => throw new NotSupportedException();
|
||||
public override long Length
|
||||
{
|
||||
get { throw new NotSupportedException(); }
|
||||
}
|
||||
|
||||
public override long Position
|
||||
{
|
||||
get => throw new NotSupportedException();
|
||||
set => throw new NotSupportedException();
|
||||
get { throw new NotSupportedException(); }
|
||||
set { throw new NotSupportedException(); }
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
@@ -78,10 +92,19 @@ namespace Google.Protobuf
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void SetLength(long value) => throw new NotSupportedException();
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException();
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace Google.Protobuf
|
||||
/// <returns>The message data as a byte array.</returns>
|
||||
public static byte[] ToByteArray(this IMessage message)
|
||||
{
|
||||
ProtoPreconditions.CheckNotNull(message, nameof(message));
|
||||
ProtoPreconditions.CheckNotNull(message, "message");
|
||||
byte[] result = new byte[message.CalculateSize()];
|
||||
CodedOutputStream output = new CodedOutputStream(result);
|
||||
message.WriteTo(output);
|
||||
@@ -122,8 +122,8 @@ namespace Google.Protobuf
|
||||
/// <param name="output">The stream to write to.</param>
|
||||
public static void WriteTo(this IMessage message, Stream output)
|
||||
{
|
||||
ProtoPreconditions.CheckNotNull(message, nameof(message));
|
||||
ProtoPreconditions.CheckNotNull(output, nameof(output));
|
||||
ProtoPreconditions.CheckNotNull(message, "message");
|
||||
ProtoPreconditions.CheckNotNull(output, "output");
|
||||
CodedOutputStream codedOutput = new CodedOutputStream(output);
|
||||
message.WriteTo(codedOutput);
|
||||
codedOutput.Flush();
|
||||
@@ -136,8 +136,8 @@ namespace Google.Protobuf
|
||||
/// <param name="output">The output stream to write to.</param>
|
||||
public static void WriteDelimitedTo(this IMessage message, Stream output)
|
||||
{
|
||||
ProtoPreconditions.CheckNotNull(message, nameof(message));
|
||||
ProtoPreconditions.CheckNotNull(output, nameof(output));
|
||||
ProtoPreconditions.CheckNotNull(message, "message");
|
||||
ProtoPreconditions.CheckNotNull(output, "output");
|
||||
CodedOutputStream codedOutput = new CodedOutputStream(output);
|
||||
codedOutput.WriteLength(message.CalculateSize());
|
||||
message.WriteTo(codedOutput);
|
||||
@@ -151,7 +151,7 @@ namespace Google.Protobuf
|
||||
/// <returns>The message data as a byte string.</returns>
|
||||
public static ByteString ToByteString(this IMessage message)
|
||||
{
|
||||
ProtoPreconditions.CheckNotNull(message, nameof(message));
|
||||
ProtoPreconditions.CheckNotNull(message, "message");
|
||||
return ByteString.AttachBytes(message.ToByteArray());
|
||||
}
|
||||
|
||||
@@ -251,34 +251,30 @@ namespace Google.Protobuf
|
||||
// Implementations allowing unknown fields to be discarded.
|
||||
internal static void MergeFrom(this IMessage message, byte[] data, bool discardUnknownFields, ExtensionRegistry registry)
|
||||
{
|
||||
ProtoPreconditions.CheckNotNull(message, nameof(message));
|
||||
ProtoPreconditions.CheckNotNull(data, nameof(data));
|
||||
CodedInputStream input = new CodedInputStream(data)
|
||||
{
|
||||
DiscardUnknownFields = discardUnknownFields,
|
||||
ExtensionRegistry = registry
|
||||
};
|
||||
ProtoPreconditions.CheckNotNull(message, "message");
|
||||
ProtoPreconditions.CheckNotNull(data, "data");
|
||||
CodedInputStream input = new CodedInputStream(data);
|
||||
input.DiscardUnknownFields = discardUnknownFields;
|
||||
input.ExtensionRegistry = registry;
|
||||
message.MergeFrom(input);
|
||||
input.CheckReadEndOfStreamTag();
|
||||
}
|
||||
|
||||
internal static void MergeFrom(this IMessage message, byte[] data, int offset, int length, bool discardUnknownFields, ExtensionRegistry registry)
|
||||
{
|
||||
ProtoPreconditions.CheckNotNull(message, nameof(message));
|
||||
ProtoPreconditions.CheckNotNull(data, nameof(data));
|
||||
CodedInputStream input = new CodedInputStream(data, offset, length)
|
||||
{
|
||||
DiscardUnknownFields = discardUnknownFields,
|
||||
ExtensionRegistry = registry
|
||||
};
|
||||
ProtoPreconditions.CheckNotNull(message, "message");
|
||||
ProtoPreconditions.CheckNotNull(data, "data");
|
||||
CodedInputStream input = new CodedInputStream(data, offset, length);
|
||||
input.DiscardUnknownFields = discardUnknownFields;
|
||||
input.ExtensionRegistry = registry;
|
||||
message.MergeFrom(input);
|
||||
input.CheckReadEndOfStreamTag();
|
||||
}
|
||||
|
||||
internal static void MergeFrom(this IMessage message, ByteString data, bool discardUnknownFields, ExtensionRegistry registry)
|
||||
{
|
||||
ProtoPreconditions.CheckNotNull(message, nameof(message));
|
||||
ProtoPreconditions.CheckNotNull(data, nameof(data));
|
||||
ProtoPreconditions.CheckNotNull(message, "message");
|
||||
ProtoPreconditions.CheckNotNull(data, "data");
|
||||
CodedInputStream input = data.CreateCodedInput();
|
||||
input.DiscardUnknownFields = discardUnknownFields;
|
||||
input.ExtensionRegistry = registry;
|
||||
@@ -288,13 +284,11 @@ namespace Google.Protobuf
|
||||
|
||||
internal static void MergeFrom(this IMessage message, Stream input, bool discardUnknownFields, ExtensionRegistry registry)
|
||||
{
|
||||
ProtoPreconditions.CheckNotNull(message, nameof(message));
|
||||
ProtoPreconditions.CheckNotNull(input, nameof(input));
|
||||
CodedInputStream codedInput = new CodedInputStream(input)
|
||||
{
|
||||
DiscardUnknownFields = discardUnknownFields,
|
||||
ExtensionRegistry = registry
|
||||
};
|
||||
ProtoPreconditions.CheckNotNull(message, "message");
|
||||
ProtoPreconditions.CheckNotNull(input, "input");
|
||||
CodedInputStream codedInput = new CodedInputStream(input);
|
||||
codedInput.DiscardUnknownFields = discardUnknownFields;
|
||||
codedInput.ExtensionRegistry = registry;
|
||||
message.MergeFrom(codedInput);
|
||||
codedInput.CheckReadEndOfStreamTag();
|
||||
}
|
||||
@@ -321,8 +315,8 @@ namespace Google.Protobuf
|
||||
|
||||
internal static void MergeDelimitedFrom(this IMessage message, Stream input, bool discardUnknownFields, ExtensionRegistry registry)
|
||||
{
|
||||
ProtoPreconditions.CheckNotNull(message, nameof(message));
|
||||
ProtoPreconditions.CheckNotNull(input, nameof(input));
|
||||
ProtoPreconditions.CheckNotNull(message, "message");
|
||||
ProtoPreconditions.CheckNotNull(input, "input");
|
||||
int size = (int) CodedInputStream.ReadRawVarint32(input);
|
||||
Stream limitedStream = new LimitedInputStream(input, size);
|
||||
MergeFrom(message, limitedStream, discardUnknownFields, registry);
|
||||
|
||||
@@ -43,8 +43,9 @@ namespace Google.Protobuf
|
||||
/// </summary>
|
||||
public class MessageParser
|
||||
{
|
||||
private readonly Func<IMessage> factory;
|
||||
private protected bool DiscardUnknownFields { get; }
|
||||
private Func<IMessage> factory;
|
||||
// TODO: When we use a C# 7.1 compiler, make this private protected.
|
||||
internal bool DiscardUnknownFields { get; }
|
||||
|
||||
internal ExtensionRegistry Extensions { get; }
|
||||
|
||||
@@ -171,10 +172,6 @@ namespace Google.Protobuf
|
||||
/// <summary>
|
||||
/// Parses a message from the given JSON.
|
||||
/// </summary>
|
||||
/// <remarks>This method always uses the default JSON parser; it is not affected by <see cref="WithDiscardUnknownFields(bool)"/>.
|
||||
/// To ignore unknown fields when parsing JSON, create a <see cref="JsonParser"/> using a <see cref="JsonParser.Settings"/>
|
||||
/// with <see cref="JsonParser.Settings.IgnoreUnknownFields"/> set to true and call <see cref="JsonParser.Parse{T}(string)"/> directly.
|
||||
/// </remarks>
|
||||
/// <param name="json">The JSON to parse.</param>
|
||||
/// <returns>The parsed message.</returns>
|
||||
/// <exception cref="InvalidJsonException">The JSON does not comply with RFC 7159</exception>
|
||||
@@ -207,9 +204,6 @@ namespace Google.Protobuf
|
||||
/// <summary>
|
||||
/// Creates a new message parser which optionally discards unknown fields when parsing.
|
||||
/// </summary>
|
||||
/// <remarks>Note that this does not affect the behavior of <see cref="ParseJson(string)"/>
|
||||
/// at all. To ignore unknown fields when parsing JSON, create a <see cref="JsonParser"/> using a <see cref="JsonParser.Settings"/>
|
||||
/// with <see cref="JsonParser.Settings.IgnoreUnknownFields"/> set to true and call <see cref="JsonParser.Parse{T}(string)"/> directly.</remarks>
|
||||
/// <param name="discardUnknownFields">Whether or not to discard unknown fields when parsing.</param>
|
||||
/// <returns>A newly configured message parser.</returns>
|
||||
public MessageParser WithDiscardUnknownFields(bool discardUnknownFields) =>
|
||||
|
||||
@@ -23,7 +23,14 @@ namespace Google.Protobuf
|
||||
&& number == other.number;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj) => obj is ObjectIntPair<T> pair && Equals(pair);
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is ObjectIntPair<T>)
|
||||
{
|
||||
return Equals((ObjectIntPair<T>)obj);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
|
||||
@@ -32,8 +32,14 @@
|
||||
|
||||
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
|
||||
{
|
||||
@@ -47,7 +53,7 @@ namespace Google.Protobuf
|
||||
public ref struct ParseContext
|
||||
{
|
||||
internal const int DefaultRecursionLimit = 100;
|
||||
internal const int DefaultSizeLimit = int.MaxValue;
|
||||
internal const int DefaultSizeLimit = Int32.MaxValue;
|
||||
|
||||
internal ReadOnlySpan<byte> buffer;
|
||||
internal ParserInternalState state;
|
||||
@@ -121,15 +127,14 @@ namespace Google.Protobuf
|
||||
/// Returns the last tag read, or 0 if no tags have been read or we've read beyond
|
||||
/// the end of the input.
|
||||
/// </summary>
|
||||
internal uint LastTag => state.lastTag;
|
||||
internal uint LastTag { get { return state.lastTag; } }
|
||||
|
||||
/// <summary>
|
||||
/// Internal-only property; when set to true, unknown fields will be discarded while parsing.
|
||||
/// </summary>
|
||||
internal bool DiscardUnknownFields
|
||||
{
|
||||
get => state.DiscardUnknownFields;
|
||||
set => state.DiscardUnknownFields = value;
|
||||
internal bool DiscardUnknownFields {
|
||||
get { return state.DiscardUnknownFields; }
|
||||
set { state.DiscardUnknownFields = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -137,8 +142,8 @@ namespace Google.Protobuf
|
||||
/// </summary>
|
||||
internal ExtensionRegistry ExtensionRegistry
|
||||
{
|
||||
get => state.ExtensionRegistry;
|
||||
set => state.ExtensionRegistry = value;
|
||||
get { return state.ExtensionRegistry; }
|
||||
set { state.ExtensionRegistry = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -151,85 +156,125 @@ namespace Google.Protobuf
|
||||
/// </remarks>
|
||||
/// <returns>The next field tag, or 0 for end of input. (0 is never a valid tag.)</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public uint ReadTag() => ParsingPrimitives.ParseTag(ref buffer, ref state);
|
||||
public uint ReadTag()
|
||||
{
|
||||
return ParsingPrimitives.ParseTag(ref buffer, ref state);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a double field from the input.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public double ReadDouble() => ParsingPrimitives.ParseDouble(ref buffer, ref state);
|
||||
public double ReadDouble()
|
||||
{
|
||||
return ParsingPrimitives.ParseDouble(ref buffer, ref state);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a float field from the input.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public float ReadFloat() => ParsingPrimitives.ParseFloat(ref buffer, ref state);
|
||||
public float ReadFloat()
|
||||
{
|
||||
return ParsingPrimitives.ParseFloat(ref buffer, ref state);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a uint64 field from the input.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ulong ReadUInt64() => ParsingPrimitives.ParseRawVarint64(ref buffer, ref state);
|
||||
public ulong ReadUInt64()
|
||||
{
|
||||
return ParsingPrimitives.ParseRawVarint64(ref buffer, ref state);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads an int64 field from the input.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public long ReadInt64() => (long)ParsingPrimitives.ParseRawVarint64(ref buffer, ref state);
|
||||
public long ReadInt64()
|
||||
{
|
||||
return (long)ParsingPrimitives.ParseRawVarint64(ref buffer, ref state);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads an int32 field from the input.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public int ReadInt32() => (int)ParsingPrimitives.ParseRawVarint32(ref buffer, ref state);
|
||||
public int ReadInt32()
|
||||
{
|
||||
return (int)ParsingPrimitives.ParseRawVarint32(ref buffer, ref state);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a fixed64 field from the input.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ulong ReadFixed64() => ParsingPrimitives.ParseRawLittleEndian64(ref buffer, ref state);
|
||||
public ulong ReadFixed64()
|
||||
{
|
||||
return ParsingPrimitives.ParseRawLittleEndian64(ref buffer, ref state);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a fixed32 field from the input.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public uint ReadFixed32() => ParsingPrimitives.ParseRawLittleEndian32(ref buffer, ref state);
|
||||
public uint ReadFixed32()
|
||||
{
|
||||
return ParsingPrimitives.ParseRawLittleEndian32(ref buffer, ref state);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a bool field from the input.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool ReadBool() => ParsingPrimitives.ParseRawVarint64(ref buffer, ref state) != 0;
|
||||
|
||||
public bool ReadBool()
|
||||
{
|
||||
return ParsingPrimitives.ParseRawVarint64(ref buffer, ref state) != 0;
|
||||
}
|
||||
/// <summary>
|
||||
/// Reads a string field from the input.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public string ReadString() => ParsingPrimitives.ReadString(ref buffer, ref state);
|
||||
public string ReadString()
|
||||
{
|
||||
return ParsingPrimitives.ReadString(ref buffer, ref state);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads an embedded message field value from the input.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void ReadMessage(IMessage message) => ParsingPrimitivesMessages.ReadMessage(ref this, message);
|
||||
public void ReadMessage(IMessage message)
|
||||
{
|
||||
ParsingPrimitivesMessages.ReadMessage(ref this, message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads an embedded group field from the input.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void ReadGroup(IMessage message) => ParsingPrimitivesMessages.ReadGroup(ref this, message);
|
||||
public void ReadGroup(IMessage message)
|
||||
{
|
||||
ParsingPrimitivesMessages.ReadGroup(ref this, message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a bytes field value from the input.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ByteString ReadBytes() => ParsingPrimitives.ReadBytes(ref buffer, ref state);
|
||||
|
||||
public ByteString ReadBytes()
|
||||
{
|
||||
return ParsingPrimitives.ReadBytes(ref buffer, ref state);
|
||||
}
|
||||
/// <summary>
|
||||
/// Reads a uint32 field value from the input.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public uint ReadUInt32() => ParsingPrimitives.ParseRawVarint32(ref buffer, ref state);
|
||||
public uint ReadUInt32()
|
||||
{
|
||||
return ParsingPrimitives.ParseRawVarint32(ref buffer, ref state);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads an enum field value from the input.
|
||||
@@ -245,25 +290,37 @@ namespace Google.Protobuf
|
||||
/// Reads an sfixed32 field value from the input.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public int ReadSFixed32() => (int)ParsingPrimitives.ParseRawLittleEndian32(ref buffer, ref state);
|
||||
public int ReadSFixed32()
|
||||
{
|
||||
return (int)ParsingPrimitives.ParseRawLittleEndian32(ref buffer, ref state);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads an sfixed64 field value from the input.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public long ReadSFixed64() => (long)ParsingPrimitives.ParseRawLittleEndian64(ref buffer, ref state);
|
||||
public long ReadSFixed64()
|
||||
{
|
||||
return (long)ParsingPrimitives.ParseRawLittleEndian64(ref buffer, ref state);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads an sint32 field value from the input.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public int ReadSInt32() => ParsingPrimitives.DecodeZigZag32(ParsingPrimitives.ParseRawVarint32(ref buffer, ref state));
|
||||
public int ReadSInt32()
|
||||
{
|
||||
return ParsingPrimitives.DecodeZigZag32(ParsingPrimitives.ParseRawVarint32(ref buffer, ref state));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads an sint64 field value from the input.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public long ReadSInt64() => ParsingPrimitives.DecodeZigZag64(ParsingPrimitives.ParseRawVarint64(ref buffer, ref state));
|
||||
public long ReadSInt64()
|
||||
{
|
||||
return ParsingPrimitives.DecodeZigZag64(ParsingPrimitives.ParseRawVarint64(ref buffer, ref state));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a length for length-delimited data.
|
||||
@@ -273,7 +330,10 @@ namespace Google.Protobuf
|
||||
/// to make the calling code clearer.
|
||||
/// </remarks>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public int ReadLength() => (int)ParsingPrimitives.ParseRawVarint32(ref buffer, ref state);
|
||||
public int ReadLength()
|
||||
{
|
||||
return (int)ParsingPrimitives.ParseRawVarint32(ref buffer, ref state);
|
||||
}
|
||||
|
||||
internal void CopyStateTo(CodedInputStream input)
|
||||
{
|
||||
|
||||
@@ -30,8 +30,20 @@
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Buffers.Binary;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using Google.Protobuf.Collections;
|
||||
|
||||
namespace Google.Protobuf
|
||||
{
|
||||
|
||||
// warning: this is a mutable struct, so it needs to be only passed as a ref!
|
||||
internal struct ParserInternalState
|
||||
{
|
||||
|
||||
@@ -34,10 +34,13 @@ using System;
|
||||
using System.Buffers;
|
||||
using System.Buffers.Binary;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using Google.Protobuf.Collections;
|
||||
|
||||
namespace Google.Protobuf
|
||||
{
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Security;
|
||||
using Google.Protobuf.Collections;
|
||||
|
||||
|
||||
@@ -31,7 +31,15 @@
|
||||
#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
|
||||
{
|
||||
|
||||
@@ -47,3 +47,10 @@ using System.Security;
|
||||
"981207041fd5b2da3b498346fcfcd94910d52f25537c4a43ce3fbe17dc7d43e6cbdb4d8f1242dc" +
|
||||
"b6bd9b5906be74da8daa7d7280f97130f318a16c07baf118839b156299a48522f9fae2371c9665" +
|
||||
"c5ae9cb6")]
|
||||
|
||||
[assembly: InternalsVisibleTo("Google.Protobuf.Benchmarks, PublicKey=" +
|
||||
"002400000480000094000000060200000024000052534131000400000100010025800fbcfc63a1" +
|
||||
"7c66b303aae80b03a6beaa176bb6bef883be436f2a1579edd80ce23edf151a1f4ced97af83abcd" +
|
||||
"981207041fd5b2da3b498346fcfcd94910d52f25537c4a43ce3fbe17dc7d43e6cbdb4d8f1242dc" +
|
||||
"b6bd9b5906be74da8daa7d7280f97130f318a16c07baf118839b156299a48522f9fae2371c9665" +
|
||||
"c5ae9cb6")]
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#endregion
|
||||
|
||||
using Google.Protobuf.Collections;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
@@ -225,21 +226,24 @@ namespace Google.Protobuf.Reflection
|
||||
{
|
||||
if (values == null)
|
||||
{
|
||||
value = default;
|
||||
value = default(T);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (values.TryGetValue(field, out IExtensionValue extensionValue))
|
||||
IExtensionValue extensionValue;
|
||||
if (values.TryGetValue(field, out extensionValue))
|
||||
{
|
||||
if (extensionValue is ExtensionValue<T> single)
|
||||
if (extensionValue is ExtensionValue<T>)
|
||||
{
|
||||
ExtensionValue<T> single = extensionValue as ExtensionValue<T>;
|
||||
ByteString bytes = single.GetValue().ToByteString();
|
||||
value = new T();
|
||||
value.MergeFrom(bytes);
|
||||
return true;
|
||||
}
|
||||
else if (extensionValue is RepeatedExtensionValue<T> repeated)
|
||||
else if (extensionValue is RepeatedExtensionValue<T>)
|
||||
{
|
||||
RepeatedExtensionValue<T> repeated = extensionValue as RepeatedExtensionValue<T>;
|
||||
value = repeated.GetValue()
|
||||
.Select(v => v.ToByteString())
|
||||
.Aggregate(new T(), (t, b) =>
|
||||
@@ -260,19 +264,22 @@ namespace Google.Protobuf.Reflection
|
||||
{
|
||||
if (values == null)
|
||||
{
|
||||
value = default;
|
||||
value = default(T);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (values.TryGetValue(field, out IExtensionValue extensionValue))
|
||||
IExtensionValue extensionValue;
|
||||
if (values.TryGetValue(field, out extensionValue))
|
||||
{
|
||||
if (extensionValue is ExtensionValue<T> single)
|
||||
if (extensionValue is ExtensionValue<T>)
|
||||
{
|
||||
ExtensionValue<T> single = extensionValue as ExtensionValue<T>;
|
||||
value = single.GetValue();
|
||||
return true;
|
||||
}
|
||||
else if (extensionValue is RepeatedExtensionValue<T> repeated)
|
||||
else if (extensionValue is RepeatedExtensionValue<T>)
|
||||
{
|
||||
RepeatedExtensionValue<T> repeated = extensionValue as RepeatedExtensionValue<T>;
|
||||
if (repeated.GetValue().Count != 0)
|
||||
{
|
||||
RepeatedField<T> repeatedField = repeated.GetValue();
|
||||
@@ -310,7 +317,7 @@ namespace Google.Protobuf.Reflection
|
||||
}
|
||||
}
|
||||
|
||||
value = default;
|
||||
value = default(T);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user