Merge branch 'main' into main
commit
971562ba47
|
@ -30,6 +30,9 @@ jobs:
|
|||
- targets: //pkg/... //src/... @com_google_protobuf_examples//... //third_party/utf8_range/...
|
||||
|
||||
# Override cases with custom images
|
||||
- config: { name: "Bazel7" }
|
||||
image: "us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:7.0.0-a04396cc76704d4b7c722789e9c08df18f47df53"
|
||||
targets: "//src/... //third_party/utf8_range/..."
|
||||
- config: { name: "TCMalloc" }
|
||||
image: "us-docker.pkg.dev/protobuf-build/containers/test/linux/tcmalloc@sha256:bd39119d74b8a3fad4ae335d4cf5294e70384676331b7e19949459fc7a8d8328"
|
||||
targets: "//src/... //third_party/utf8_range/..."
|
||||
|
@ -313,21 +316,32 @@ jobs:
|
|||
fail-fast: false # Don't cancel all jobs if one fails.
|
||||
matrix:
|
||||
include:
|
||||
- name: MacOS
|
||||
- name: MacOS Bazel
|
||||
os: macos-12
|
||||
cache_key: macos-12
|
||||
bazel: test //src/... //third_party/utf8_range/...
|
||||
- name: MacOS Apple Silicon (build only)
|
||||
# TODO Enable these once mac setup is working for Bazel 7
|
||||
#- name: MacOS Bazel 7
|
||||
# os: macos-12
|
||||
# cache_key: macos-12-bazel7
|
||||
# bazel: test //src/... //third_party/utf8_range/...
|
||||
# bazel_version: '7.0.0'
|
||||
- name: MacOS Apple Silicon (build only) Bazel
|
||||
os: macos-12
|
||||
cache_key: macos-12-arm
|
||||
# Current github runners are all Intel based, so just build/compile
|
||||
# for Apple Silicon to detect issues there.
|
||||
bazel: build --cpu=darwin_arm64 //src/... //third_party/utf8_range/...
|
||||
- name: Windows
|
||||
- name: Windows Bazel
|
||||
os: windows-2022
|
||||
cache_key: windows-2022
|
||||
bazel: test //src/... @com_google_protobuf_examples//... --test_tag_filters=-conformance --build_tag_filters=-conformance
|
||||
name: ${{ matrix.name }} Bazel
|
||||
- name: Windows Bazel 7
|
||||
os: windows-2022
|
||||
cache_key: windows-2022-bazel7
|
||||
bazel: test //src/... @com_google_protobuf_examples//... --test_tag_filters=-conformance --build_tag_filters=-conformance
|
||||
bazel_version: '7.0.0'
|
||||
name: ${{ matrix.name }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout pending changes
|
||||
|
@ -340,6 +354,7 @@ jobs:
|
|||
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
|
||||
bazel: ${{ matrix.bazel }}
|
||||
bazel-cache: cpp_${{ matrix.cache_key }}
|
||||
version: ${{ matrix.bazel_version || '6.3.0' }}
|
||||
|
||||
non-linux-cmake:
|
||||
strategy:
|
||||
|
|
|
@ -17,6 +17,7 @@ jobs:
|
|||
fail-fast: false # Don't cancel all jobs if one fails.
|
||||
matrix:
|
||||
config:
|
||||
- { name: "Bazel 7", bazel_version: "7.0.0" }
|
||||
- { name: "Fastbuild" }
|
||||
- { name: "Optimized", flags: "-c opt" }
|
||||
- { name: "FastTable", flags: "--//upb:fasttable_enabled=true" }
|
||||
|
@ -37,7 +38,7 @@ jobs:
|
|||
- name: Run tests
|
||||
uses: protocolbuffers/protobuf-ci/bazel-docker@v2
|
||||
with:
|
||||
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/sanitize@sha256:04cd765285bc52cbbf51d66c8c66d8603579cf0f19cc42df26b09d2c270541fb
|
||||
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/sanitize:${{ matrix.config.bazel_version || '6.3.0' }}-d07b7d649401d147e71e7182d2832cc8344f1f35
|
||||
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
|
||||
bazel-cache: upb-bazel
|
||||
bazel: test --cxxopt=-std=c++17 --host_cxxopt=-std=c++17 //bazel/... //benchmarks/... //lua/... //protos/... //protos_generator/... //python/... //upb/... //upb_generator/... ${{ matrix.config.flags }}
|
||||
|
@ -81,6 +82,7 @@ jobs:
|
|||
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
|
||||
bazel-cache: "upb-bazel-windows"
|
||||
bazel: test --cxxopt=/std:c++17 --host_cxxopt=/std:c++17 //upb/... //upb_generator/... //python/... //protos/... //protos_generator/...
|
||||
version: 6.3.0
|
||||
exclude-targets: -//python:conformance_test -//upb/reflection:def_builder_test
|
||||
|
||||
macos:
|
||||
|
@ -107,6 +109,7 @@ jobs:
|
|||
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
|
||||
bazel-cache: "upb-bazel-macos"
|
||||
bazel: ${{ matrix.config.bazel-command }} --cxxopt=-std=c++17 --host_cxxopt=-std=c++17 ${{ matrix.config.flags }} //bazel/... //benchmarks/... //lua/... //protos/... //protos_generator/... //python/... //upb/... //upb_generator/...
|
||||
version: 6.3.0
|
||||
|
||||
no-python:
|
||||
strategy:
|
||||
|
|
11
bazel/BUILD
11
bazel/BUILD
|
@ -7,6 +7,7 @@
|
|||
|
||||
load("@rules_python//python:defs.bzl", "py_binary")
|
||||
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
|
||||
load("@bazel_skylib//lib:selects.bzl", "selects")
|
||||
|
||||
# begin:google_only
|
||||
# package(default_applicable_licenses = ["//upb:license"])
|
||||
|
@ -14,6 +15,16 @@ load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
|
|||
|
||||
licenses(["notice"])
|
||||
|
||||
# begin:google_only
|
||||
# selects.config_setting_group(
|
||||
# name = "android_opt",
|
||||
# match_all = [
|
||||
# "//tools/cc_target_os:android",
|
||||
# "//tools/compilation_mode:opt",
|
||||
# ],
|
||||
# )
|
||||
# end:google_only
|
||||
|
||||
py_binary(
|
||||
name = "amalgamate",
|
||||
srcs = ["amalgamate.py"],
|
||||
|
|
|
@ -30,12 +30,20 @@ _DEFAULT_COPTS.extend([
|
|||
|
||||
UPB_DEFAULT_CPPOPTS = select({
|
||||
"//upb:windows": [],
|
||||
# begin:google_only
|
||||
# # Override default -Oz for release builds on Android.
|
||||
# "//bazel:android_opt": _DEFAULT_CPPOPTS + ["-O2"],
|
||||
# end:google_only
|
||||
"//conditions:default": _DEFAULT_CPPOPTS,
|
||||
})
|
||||
|
||||
UPB_DEFAULT_COPTS = select({
|
||||
"//upb:windows": [],
|
||||
"//upb:fasttable_enabled_setting": ["-std=gnu99", "-DUPB_ENABLE_FASTTABLE"],
|
||||
# begin:google_only
|
||||
# # Override default -Oz for release builds on Android.
|
||||
# "//bazel:android_opt": _DEFAULT_COPTS + ["-O2"],
|
||||
# end:google_only
|
||||
"//conditions:default": _DEFAULT_COPTS,
|
||||
})
|
||||
|
||||
|
|
|
@ -35,7 +35,6 @@ build:ubsan --copt=-fno-sanitize=function --copt=-fno-sanitize=vptr
|
|||
build --incompatible_check_sharding_support
|
||||
build --incompatible_default_to_explicit_init_py
|
||||
build --incompatible_disable_native_android_rules
|
||||
build --incompatible_disable_runtimes_filegroups
|
||||
build --incompatible_disable_target_provider_fields
|
||||
build --incompatible_disallow_empty_glob
|
||||
build --incompatible_dont_use_javasourceinfoprovider
|
||||
|
@ -66,3 +65,7 @@ build --incompatible_use_host_features
|
|||
# --incompatible_disable_objc_library_transition
|
||||
# --incompatible_fail_on_unknown_attributes
|
||||
# --incompatible_merge_fixed_and_default_shell_env
|
||||
|
||||
# TODO: migrate all dependencies from WORKSPACE to MODULE.bazel
|
||||
# https://github.com/protocolbuffers/protobuf/issues/14313
|
||||
common --noenable_bzlmod
|
|
@ -78,7 +78,10 @@ foreach(_header ${protobuf_HEADERS})
|
|||
elseif (_find_nosrc GREATER -1)
|
||||
set(_from_dir "${protobuf_SOURCE_DIR}")
|
||||
endif()
|
||||
string(REPLACE "${_from_dir}" "" _header ${_header})
|
||||
# On some platforms `_form_dir` ends up being just "protobuf", which can
|
||||
# easily match multiple times in our paths. We force it to only replace
|
||||
# prefixes to avoid this case.
|
||||
string(REGEX REPLACE "^${_from_dir}" "" _header ${_header})
|
||||
get_filename_component(_extract_from "${_from_dir}/${_header}" ABSOLUTE)
|
||||
get_filename_component(_extract_name ${_header} NAME)
|
||||
get_filename_component(_extract_to "${CMAKE_INSTALL_INCLUDEDIR}/${_header}" DIRECTORY)
|
||||
|
|
|
@ -144,7 +144,6 @@ cc_library(
|
|||
includes = ["."],
|
||||
deps = [
|
||||
":conformance_cc_proto",
|
||||
"//src/google/protobuf:descriptor_legacy",
|
||||
"//src/google/protobuf/util:differencer",
|
||||
"//src/google/protobuf/util:json_util",
|
||||
"//src/google/protobuf/util:type_resolver_util",
|
||||
|
@ -329,6 +328,8 @@ objc_library(
|
|||
":conformance_objc_proto",
|
||||
"//:test_messages_proto2_objc_proto",
|
||||
"//:test_messages_proto3_objc_proto",
|
||||
"//src/google/protobuf/editions:test_messages_proto2_editions_objc_proto",
|
||||
"//src/google/protobuf/editions:test_messages_proto3_editions_objc_proto",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#import "Conformance.pbobjc.h"
|
||||
#import "google/protobuf/TestMessagesProto2.pbobjc.h"
|
||||
#import "google/protobuf/TestMessagesProto3.pbobjc.h"
|
||||
#import "google/protobuf/editions/golden/TestMessagesProto2Editions.pbobjc.h"
|
||||
#import "google/protobuf/editions/golden/TestMessagesProto3Editions.pbobjc.h"
|
||||
|
||||
static void Die(NSString *format, ...) __dead2;
|
||||
|
||||
|
@ -49,22 +51,25 @@ static ConformanceResponse *DoTest(ConformanceRequest *request) {
|
|||
break;
|
||||
|
||||
case ConformanceRequest_Payload_OneOfCase_ProtobufPayload: {
|
||||
Class msgClass = nil;
|
||||
if ([request.messageType isEqual:@"protobuf_test_messages.proto3.TestAllTypesProto3"]) {
|
||||
msgClass = [Proto3TestAllTypesProto3 class];
|
||||
} else if ([request.messageType
|
||||
isEqual:@"protobuf_test_messages.proto2.TestAllTypesProto2"]) {
|
||||
msgClass = [Proto2TestAllTypesProto2 class];
|
||||
NSDictionary *mappings = @{
|
||||
@"protobuf_test_messages.proto2.TestAllTypesProto2" : [Proto2TestAllTypesProto2 class],
|
||||
@"protobuf_test_messages.proto3.TestAllTypesProto3" : [Proto3TestAllTypesProto3 class],
|
||||
@"protobuf_test_messages.editions.proto2.TestAllTypesProto2" :
|
||||
[EditionsProto2TestAllTypesProto2 class],
|
||||
@"protobuf_test_messages.editions.proto3.TestAllTypesProto3" :
|
||||
[EditionsProto3TestAllTypesProto3 class],
|
||||
};
|
||||
Class msgClass = mappings[request.messageType];
|
||||
if (msgClass) {
|
||||
NSError *error = nil;
|
||||
testMessage = [msgClass parseFromData:request.protobufPayload error:&error];
|
||||
if (!testMessage) {
|
||||
response.parseError = [NSString stringWithFormat:@"Parse error: %@", error];
|
||||
}
|
||||
} else {
|
||||
response.runtimeError =
|
||||
[NSString stringWithFormat:@"Protobuf request had an unknown message_type: %@",
|
||||
request.messageType];
|
||||
break;
|
||||
}
|
||||
NSError *error = nil;
|
||||
testMessage = [msgClass parseFromData:request.protobufPayload error:&error];
|
||||
if (!testMessage) {
|
||||
response.parseError = [NSString stringWithFormat:@"Parse error: %@", error];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "absl/strings/string_view.h"
|
||||
#include "conformance/conformance.pb.h"
|
||||
#include "conformance/conformance.pb.h"
|
||||
#include "google/protobuf/descriptor_legacy.h"
|
||||
#include "google/protobuf/message.h"
|
||||
#include "google/protobuf/text_format.h"
|
||||
|
||||
|
@ -143,13 +142,12 @@ ConformanceTestSuite::ConformanceRequestSetting::NewTestMessage() const {
|
|||
|
||||
std::string
|
||||
ConformanceTestSuite::ConformanceRequestSetting::GetSyntaxIdentifier() const {
|
||||
switch (FileDescriptorLegacy(prototype_message_.GetDescriptor()->file())
|
||||
.syntax()) {
|
||||
case FileDescriptorLegacy::Syntax::SYNTAX_PROTO3:
|
||||
switch (prototype_message_.GetDescriptor()->file()->edition()) {
|
||||
case Edition::EDITION_PROTO3:
|
||||
return "Proto3";
|
||||
case FileDescriptorLegacy::Syntax::SYNTAX_PROTO2:
|
||||
case Edition::EDITION_PROTO2:
|
||||
return "Proto2";
|
||||
case FileDescriptorLegacy::Syntax::SYNTAX_EDITIONS: {
|
||||
default: {
|
||||
std::string id = "Editions";
|
||||
if (prototype_message_.GetDescriptor()->name() == "TestAllTypesProto2") {
|
||||
absl::StrAppend(&id, "_Proto2");
|
||||
|
@ -159,8 +157,6 @@ ConformanceTestSuite::ConformanceRequestSetting::GetSyntaxIdentifier() const {
|
|||
}
|
||||
return id;
|
||||
}
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#region Copyright notice and license
|
||||
#region Copyright notice and license
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
//
|
||||
|
@ -471,11 +471,11 @@ namespace Google.Protobuf
|
|||
|
||||
// Assume that anything non-bounds-related is covered in the Int32 case
|
||||
[Test]
|
||||
[TestCase("9223372036854775808")]
|
||||
// Theoretical bound would be -9223372036854775809, but when that is parsed to a double
|
||||
// we end up with the exact value of long.MinValue due to lack of precision. The value here
|
||||
// is the "next double down".
|
||||
[TestCase("-9223372036854780000")]
|
||||
// Runtime implementation differences produce different results for values just outside
|
||||
// (long.MinValue, long.MaxValue) which cannot be exactly represented as a double. Use the
|
||||
// next values exactly representable as doubles to ensure consistency.
|
||||
[TestCase("9223372036854777856")]
|
||||
[TestCase("-9223372036854777856")]
|
||||
public void NumberToInt64_Invalid(string jsonValue)
|
||||
{
|
||||
string json = "{ \"singleInt64\": " + jsonValue + "}";
|
||||
|
@ -498,7 +498,10 @@ namespace Google.Protobuf
|
|||
// Assume that anything non-bounds-related is covered in the Int32 case
|
||||
[Test]
|
||||
[TestCase("-1")]
|
||||
[TestCase("18446744073709551616")]
|
||||
// Runtime implementation differences produce different results for values just beyond
|
||||
// ulong.MaxValue which cannot be exactly represented as a double. Use the next value
|
||||
// exactly representable as a double to ensure consistency.
|
||||
[TestCase("18446744073709555712")]
|
||||
public void NumberToUInt64_Invalid(string jsonValue)
|
||||
{
|
||||
string json = "{ \"singleUint64\": " + jsonValue + "}";
|
||||
|
|
Binary file not shown.
|
@ -33,24 +33,25 @@ namespace Google.Protobuf.Compiler {
|
|||
"LnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8SRQoXc291cmNlX2ZpbGVf",
|
||||
"ZGVzY3JpcHRvcnMYESADKAsyJC5nb29nbGUucHJvdG9idWYuRmlsZURlc2Ny",
|
||||
"aXB0b3JQcm90bxI7ChBjb21waWxlcl92ZXJzaW9uGAMgASgLMiEuZ29vZ2xl",
|
||||
"LnByb3RvYnVmLmNvbXBpbGVyLlZlcnNpb24i4AIKFUNvZGVHZW5lcmF0b3JS",
|
||||
"LnByb3RvYnVmLmNvbXBpbGVyLlZlcnNpb24ikgMKFUNvZGVHZW5lcmF0b3JS",
|
||||
"ZXNwb25zZRINCgVlcnJvchgBIAEoCRIaChJzdXBwb3J0ZWRfZmVhdHVyZXMY",
|
||||
"AiABKAQSQgoEZmlsZRgPIAMoCzI0Lmdvb2dsZS5wcm90b2J1Zi5jb21waWxl",
|
||||
"ci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZRp/CgRGaWxlEgwKBG5hbWUY",
|
||||
"ASABKAkSFwoPaW5zZXJ0aW9uX3BvaW50GAIgASgJEg8KB2NvbnRlbnQYDyAB",
|
||||
"KAkSPwoTZ2VuZXJhdGVkX2NvZGVfaW5mbxgQIAEoCzIiLmdvb2dsZS5wcm90",
|
||||
"b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mbyJXCgdGZWF0dXJlEhAKDEZFQVRVUkVf",
|
||||
"Tk9ORRAAEhsKF0ZFQVRVUkVfUFJPVE8zX09QVElPTkFMEAESHQoZRkVBVFVS",
|
||||
"RV9TVVBQT1JUU19FRElUSU9OUxACQnIKHGNvbS5nb29nbGUucHJvdG9idWYu",
|
||||
"Y29tcGlsZXJCDFBsdWdpblByb3Rvc1opZ29vZ2xlLmdvbGFuZy5vcmcvcHJv",
|
||||
"dG9idWYvdHlwZXMvcGx1Z2lucGKqAhhHb29nbGUuUHJvdG9idWYuQ29tcGls",
|
||||
"ZXI="));
|
||||
"AiABKAQSFwoPbWluaW11bV9lZGl0aW9uGAMgASgFEhcKD21heGltdW1fZWRp",
|
||||
"dGlvbhgEIAEoBRJCCgRmaWxlGA8gAygLMjQuZ29vZ2xlLnByb3RvYnVmLmNv",
|
||||
"bXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlGn8KBEZpbGUSDAoE",
|
||||
"bmFtZRgBIAEoCRIXCg9pbnNlcnRpb25fcG9pbnQYAiABKAkSDwoHY29udGVu",
|
||||
"dBgPIAEoCRI/ChNnZW5lcmF0ZWRfY29kZV9pbmZvGBAgASgLMiIuZ29vZ2xl",
|
||||
"LnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvIlcKB0ZlYXR1cmUSEAoMRkVB",
|
||||
"VFVSRV9OT05FEAASGwoXRkVBVFVSRV9QUk9UTzNfT1BUSU9OQUwQARIdChlG",
|
||||
"RUFUVVJFX1NVUFBPUlRTX0VESVRJT05TEAJCcgocY29tLmdvb2dsZS5wcm90",
|
||||
"b2J1Zi5jb21waWxlckIMUGx1Z2luUHJvdG9zWilnb29nbGUuZ29sYW5nLm9y",
|
||||
"Zy9wcm90b2J1Zi90eXBlcy9wbHVnaW5wYqoCGEdvb2dsZS5Qcm90b2J1Zi5D",
|
||||
"b21waWxlcg=="));
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor, },
|
||||
new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Compiler.Version), global::Google.Protobuf.Compiler.Version.Parser, new[]{ "Major", "Minor", "Patch", "Suffix" }, null, null, null, null),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Compiler.CodeGeneratorRequest), global::Google.Protobuf.Compiler.CodeGeneratorRequest.Parser, new[]{ "FileToGenerate", "Parameter", "ProtoFile", "SourceFileDescriptors", "CompilerVersion" }, null, null, null, null),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Compiler.CodeGeneratorResponse), global::Google.Protobuf.Compiler.CodeGeneratorResponse.Parser, new[]{ "Error", "SupportedFeatures", "File" }, null, new[]{ typeof(global::Google.Protobuf.Compiler.CodeGeneratorResponse.Types.Feature) }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Compiler.CodeGeneratorResponse.Types.File), global::Google.Protobuf.Compiler.CodeGeneratorResponse.Types.File.Parser, new[]{ "Name", "InsertionPoint", "Content", "GeneratedCodeInfo" }, null, null, null, null)})
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Compiler.CodeGeneratorResponse), global::Google.Protobuf.Compiler.CodeGeneratorResponse.Parser, new[]{ "Error", "SupportedFeatures", "MinimumEdition", "MaximumEdition", "File" }, null, new[]{ typeof(global::Google.Protobuf.Compiler.CodeGeneratorResponse.Types.Feature) }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Compiler.CodeGeneratorResponse.Types.File), global::Google.Protobuf.Compiler.CodeGeneratorResponse.Types.File.Parser, new[]{ "Name", "InsertionPoint", "Content", "GeneratedCodeInfo" }, null, null, null, null)})
|
||||
}));
|
||||
}
|
||||
#endregion
|
||||
|
@ -836,6 +837,8 @@ namespace Google.Protobuf.Compiler {
|
|||
_hasBits0 = other._hasBits0;
|
||||
error_ = other.error_;
|
||||
supportedFeatures_ = other.supportedFeatures_;
|
||||
minimumEdition_ = other.minimumEdition_;
|
||||
maximumEdition_ = other.maximumEdition_;
|
||||
file_ = other.file_.Clone();
|
||||
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
|
||||
}
|
||||
|
@ -913,6 +916,72 @@ namespace Google.Protobuf.Compiler {
|
|||
_hasBits0 &= ~1;
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "minimum_edition" field.</summary>
|
||||
public const int MinimumEditionFieldNumber = 3;
|
||||
private readonly static int MinimumEditionDefaultValue = 0;
|
||||
|
||||
private int minimumEdition_;
|
||||
/// <summary>
|
||||
/// The minimum edition this plugin supports. This will be treated as an
|
||||
/// Edition enum, but we want to allow unknown values. It should be specified
|
||||
/// according the edition enum value, *not* the edition number. Only takes
|
||||
/// effect for plugins that have FEATURE_SUPPORTS_EDITIONS set.
|
||||
/// </summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public int MinimumEdition {
|
||||
get { if ((_hasBits0 & 2) != 0) { return minimumEdition_; } else { return MinimumEditionDefaultValue; } }
|
||||
set {
|
||||
_hasBits0 |= 2;
|
||||
minimumEdition_ = value;
|
||||
}
|
||||
}
|
||||
/// <summary>Gets whether the "minimum_edition" field is set</summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public bool HasMinimumEdition {
|
||||
get { return (_hasBits0 & 2) != 0; }
|
||||
}
|
||||
/// <summary>Clears the value of the "minimum_edition" field</summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public void ClearMinimumEdition() {
|
||||
_hasBits0 &= ~2;
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "maximum_edition" field.</summary>
|
||||
public const int MaximumEditionFieldNumber = 4;
|
||||
private readonly static int MaximumEditionDefaultValue = 0;
|
||||
|
||||
private int maximumEdition_;
|
||||
/// <summary>
|
||||
/// The maximum edition this plugin supports. This will be treated as an
|
||||
/// Edition enum, but we want to allow unknown values. It should be specified
|
||||
/// according the edition enum value, *not* the edition number. Only takes
|
||||
/// effect for plugins that have FEATURE_SUPPORTS_EDITIONS set.
|
||||
/// </summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public int MaximumEdition {
|
||||
get { if ((_hasBits0 & 4) != 0) { return maximumEdition_; } else { return MaximumEditionDefaultValue; } }
|
||||
set {
|
||||
_hasBits0 |= 4;
|
||||
maximumEdition_ = value;
|
||||
}
|
||||
}
|
||||
/// <summary>Gets whether the "maximum_edition" field is set</summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public bool HasMaximumEdition {
|
||||
get { return (_hasBits0 & 4) != 0; }
|
||||
}
|
||||
/// <summary>Clears the value of the "maximum_edition" field</summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public void ClearMaximumEdition() {
|
||||
_hasBits0 &= ~4;
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "file" field.</summary>
|
||||
public const int FileFieldNumber = 15;
|
||||
private static readonly pb::FieldCodec<global::Google.Protobuf.Compiler.CodeGeneratorResponse.Types.File> _repeated_file_codec
|
||||
|
@ -941,6 +1010,8 @@ namespace Google.Protobuf.Compiler {
|
|||
}
|
||||
if (Error != other.Error) return false;
|
||||
if (SupportedFeatures != other.SupportedFeatures) return false;
|
||||
if (MinimumEdition != other.MinimumEdition) return false;
|
||||
if (MaximumEdition != other.MaximumEdition) return false;
|
||||
if(!file_.Equals(other.file_)) return false;
|
||||
return Equals(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
@ -951,6 +1022,8 @@ namespace Google.Protobuf.Compiler {
|
|||
int hash = 1;
|
||||
if (HasError) hash ^= Error.GetHashCode();
|
||||
if (HasSupportedFeatures) hash ^= SupportedFeatures.GetHashCode();
|
||||
if (HasMinimumEdition) hash ^= MinimumEdition.GetHashCode();
|
||||
if (HasMaximumEdition) hash ^= MaximumEdition.GetHashCode();
|
||||
hash ^= file_.GetHashCode();
|
||||
if (_unknownFields != null) {
|
||||
hash ^= _unknownFields.GetHashCode();
|
||||
|
@ -978,6 +1051,14 @@ namespace Google.Protobuf.Compiler {
|
|||
output.WriteRawTag(16);
|
||||
output.WriteUInt64(SupportedFeatures);
|
||||
}
|
||||
if (HasMinimumEdition) {
|
||||
output.WriteRawTag(24);
|
||||
output.WriteInt32(MinimumEdition);
|
||||
}
|
||||
if (HasMaximumEdition) {
|
||||
output.WriteRawTag(32);
|
||||
output.WriteInt32(MaximumEdition);
|
||||
}
|
||||
file_.WriteTo(output, _repeated_file_codec);
|
||||
if (_unknownFields != null) {
|
||||
_unknownFields.WriteTo(output);
|
||||
|
@ -997,6 +1078,14 @@ namespace Google.Protobuf.Compiler {
|
|||
output.WriteRawTag(16);
|
||||
output.WriteUInt64(SupportedFeatures);
|
||||
}
|
||||
if (HasMinimumEdition) {
|
||||
output.WriteRawTag(24);
|
||||
output.WriteInt32(MinimumEdition);
|
||||
}
|
||||
if (HasMaximumEdition) {
|
||||
output.WriteRawTag(32);
|
||||
output.WriteInt32(MaximumEdition);
|
||||
}
|
||||
file_.WriteTo(ref output, _repeated_file_codec);
|
||||
if (_unknownFields != null) {
|
||||
_unknownFields.WriteTo(ref output);
|
||||
|
@ -1014,6 +1103,12 @@ namespace Google.Protobuf.Compiler {
|
|||
if (HasSupportedFeatures) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeUInt64Size(SupportedFeatures);
|
||||
}
|
||||
if (HasMinimumEdition) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeInt32Size(MinimumEdition);
|
||||
}
|
||||
if (HasMaximumEdition) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeInt32Size(MaximumEdition);
|
||||
}
|
||||
size += file_.CalculateSize(_repeated_file_codec);
|
||||
if (_unknownFields != null) {
|
||||
size += _unknownFields.CalculateSize();
|
||||
|
@ -1033,6 +1128,12 @@ namespace Google.Protobuf.Compiler {
|
|||
if (other.HasSupportedFeatures) {
|
||||
SupportedFeatures = other.SupportedFeatures;
|
||||
}
|
||||
if (other.HasMinimumEdition) {
|
||||
MinimumEdition = other.MinimumEdition;
|
||||
}
|
||||
if (other.HasMaximumEdition) {
|
||||
MaximumEdition = other.MaximumEdition;
|
||||
}
|
||||
file_.Add(other.file_);
|
||||
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
@ -1057,6 +1158,14 @@ namespace Google.Protobuf.Compiler {
|
|||
SupportedFeatures = input.ReadUInt64();
|
||||
break;
|
||||
}
|
||||
case 24: {
|
||||
MinimumEdition = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 32: {
|
||||
MaximumEdition = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 122: {
|
||||
file_.AddEntriesFrom(input, _repeated_file_codec);
|
||||
break;
|
||||
|
@ -1084,6 +1193,14 @@ namespace Google.Protobuf.Compiler {
|
|||
SupportedFeatures = input.ReadUInt64();
|
||||
break;
|
||||
}
|
||||
case 24: {
|
||||
MinimumEdition = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 32: {
|
||||
MaximumEdition = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 122: {
|
||||
file_.AddEntriesFrom(ref input, _repeated_file_codec);
|
||||
break;
|
||||
|
|
|
@ -53,190 +53,190 @@ namespace Google.Protobuf.Reflection {
|
|||
"X25hbWUYCiADKAkaZQoORXh0ZW5zaW9uUmFuZ2USDQoFc3RhcnQYASABKAUS",
|
||||
"CwoDZW5kGAIgASgFEjcKB29wdGlvbnMYAyABKAsyJi5nb29nbGUucHJvdG9i",
|
||||
"dWYuRXh0ZW5zaW9uUmFuZ2VPcHRpb25zGisKDVJlc2VydmVkUmFuZ2USDQoF",
|
||||
"c3RhcnQYASABKAUSCwoDZW5kGAIgASgFIuADChVFeHRlbnNpb25SYW5nZU9w",
|
||||
"c3RhcnQYASABKAUSCwoDZW5kGAIgASgFIuUDChVFeHRlbnNpb25SYW5nZU9w",
|
||||
"dGlvbnMSQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xl",
|
||||
"LnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24STAoLZGVjbGFyYXRpb24Y",
|
||||
"AiADKAsyMi5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmFuZ2VPcHRpb25z",
|
||||
"LkRlY2xhcmF0aW9uQgOIAQISLQoIZmVhdHVyZXMYMiABKAsyGy5nb29nbGUu",
|
||||
"cHJvdG9idWYuRmVhdHVyZVNldBJaCgx2ZXJpZmljYXRpb24YAyABKA4yOC5n",
|
||||
"cHJvdG9idWYuRmVhdHVyZVNldBJfCgx2ZXJpZmljYXRpb24YAyABKA4yOC5n",
|
||||
"b29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmFuZ2VPcHRpb25zLlZlcmlmaWNh",
|
||||
"dGlvblN0YXRlOgpVTlZFUklGSUVEGmgKC0RlY2xhcmF0aW9uEg4KBm51bWJl",
|
||||
"chgBIAEoBRIRCglmdWxsX25hbWUYAiABKAkSDAoEdHlwZRgDIAEoCRIQCghy",
|
||||
"ZXNlcnZlZBgFIAEoCBIQCghyZXBlYXRlZBgGIAEoCEoECAQQBSI0ChFWZXJp",
|
||||
"ZmljYXRpb25TdGF0ZRIPCgtERUNMQVJBVElPThAAEg4KClVOVkVSSUZJRUQQ",
|
||||
"ASoJCOgHEICAgIACItUFChRGaWVsZERlc2NyaXB0b3JQcm90bxIMCgRuYW1l",
|
||||
"GAEgASgJEg4KBm51bWJlchgDIAEoBRI6CgVsYWJlbBgEIAEoDjIrLmdvb2ds",
|
||||
"ZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5MYWJlbBI4CgR0eXBl",
|
||||
"GAUgASgOMiouZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3Rv",
|
||||
"LlR5cGUSEQoJdHlwZV9uYW1lGAYgASgJEhAKCGV4dGVuZGVlGAIgASgJEhUK",
|
||||
"DWRlZmF1bHRfdmFsdWUYByABKAkSEwoLb25lb2ZfaW5kZXgYCSABKAUSEQoJ",
|
||||
"anNvbl9uYW1lGAogASgJEi4KB29wdGlvbnMYCCABKAsyHS5nb29nbGUucHJv",
|
||||
"dG9idWYuRmllbGRPcHRpb25zEhcKD3Byb3RvM19vcHRpb25hbBgRIAEoCCK2",
|
||||
"AgoEVHlwZRIPCgtUWVBFX0RPVUJMRRABEg4KClRZUEVfRkxPQVQQAhIOCgpU",
|
||||
"WVBFX0lOVDY0EAMSDwoLVFlQRV9VSU5UNjQQBBIOCgpUWVBFX0lOVDMyEAUS",
|
||||
"EAoMVFlQRV9GSVhFRDY0EAYSEAoMVFlQRV9GSVhFRDMyEAcSDQoJVFlQRV9C",
|
||||
"T09MEAgSDwoLVFlQRV9TVFJJTkcQCRIOCgpUWVBFX0dST1VQEAoSEAoMVFlQ",
|
||||
"RV9NRVNTQUdFEAsSDgoKVFlQRV9CWVRFUxAMEg8KC1RZUEVfVUlOVDMyEA0S",
|
||||
"DQoJVFlQRV9FTlVNEA4SEQoNVFlQRV9TRklYRUQzMhAPEhEKDVRZUEVfU0ZJ",
|
||||
"WEVENjQQEBIPCgtUWVBFX1NJTlQzMhAREg8KC1RZUEVfU0lOVDY0EBIiQwoF",
|
||||
"TGFiZWwSEgoOTEFCRUxfT1BUSU9OQUwQARISCg5MQUJFTF9SRVBFQVRFRBAD",
|
||||
"EhIKDkxBQkVMX1JFUVVJUkVEEAIiVAoUT25lb2ZEZXNjcmlwdG9yUHJvdG8S",
|
||||
"DAoEbmFtZRgBIAEoCRIuCgdvcHRpb25zGAIgASgLMh0uZ29vZ2xlLnByb3Rv",
|
||||
"YnVmLk9uZW9mT3B0aW9ucyKkAgoTRW51bURlc2NyaXB0b3JQcm90bxIMCgRu",
|
||||
"YW1lGAEgASgJEjgKBXZhbHVlGAIgAygLMikuZ29vZ2xlLnByb3RvYnVmLkVu",
|
||||
"dW1WYWx1ZURlc2NyaXB0b3JQcm90bxItCgdvcHRpb25zGAMgASgLMhwuZ29v",
|
||||
"Z2xlLnByb3RvYnVmLkVudW1PcHRpb25zEk4KDnJlc2VydmVkX3JhbmdlGAQg",
|
||||
"AygLMjYuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8uRW51",
|
||||
"bVJlc2VydmVkUmFuZ2USFQoNcmVzZXJ2ZWRfbmFtZRgFIAMoCRovChFFbnVt",
|
||||
"UmVzZXJ2ZWRSYW5nZRINCgVzdGFydBgBIAEoBRILCgNlbmQYAiABKAUibAoY",
|
||||
"RW51bVZhbHVlRGVzY3JpcHRvclByb3RvEgwKBG5hbWUYASABKAkSDgoGbnVt",
|
||||
"YmVyGAIgASgFEjIKB29wdGlvbnMYAyABKAsyIS5nb29nbGUucHJvdG9idWYu",
|
||||
"RW51bVZhbHVlT3B0aW9ucyKQAQoWU2VydmljZURlc2NyaXB0b3JQcm90bxIM",
|
||||
"CgRuYW1lGAEgASgJEjYKBm1ldGhvZBgCIAMoCzImLmdvb2dsZS5wcm90b2J1",
|
||||
"Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8SMAoHb3B0aW9ucxgDIAEoCzIfLmdv",
|
||||
"b2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucyLBAQoVTWV0aG9kRGVzY3Jp",
|
||||
"cHRvclByb3RvEgwKBG5hbWUYASABKAkSEgoKaW5wdXRfdHlwZRgCIAEoCRIT",
|
||||
"CgtvdXRwdXRfdHlwZRgDIAEoCRIvCgdvcHRpb25zGAQgASgLMh4uZ29vZ2xl",
|
||||
"LnByb3RvYnVmLk1ldGhvZE9wdGlvbnMSHwoQY2xpZW50X3N0cmVhbWluZxgF",
|
||||
"IAEoCDoFZmFsc2USHwoQc2VydmVyX3N0cmVhbWluZxgGIAEoCDoFZmFsc2Ui",
|
||||
"1AYKC0ZpbGVPcHRpb25zEhQKDGphdmFfcGFja2FnZRgBIAEoCRIcChRqYXZh",
|
||||
"X291dGVyX2NsYXNzbmFtZRgIIAEoCRIiChNqYXZhX211bHRpcGxlX2ZpbGVz",
|
||||
"GAogASgIOgVmYWxzZRIpCh1qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFz",
|
||||
"aBgUIAEoCEICGAESJQoWamF2YV9zdHJpbmdfY2hlY2tfdXRmOBgbIAEoCDoF",
|
||||
"ZmFsc2USRgoMb3B0aW1pemVfZm9yGAkgASgOMikuZ29vZ2xlLnByb3RvYnVm",
|
||||
"LkZpbGVPcHRpb25zLk9wdGltaXplTW9kZToFU1BFRUQSEgoKZ29fcGFja2Fn",
|
||||
"ZRgLIAEoCRIiChNjY19nZW5lcmljX3NlcnZpY2VzGBAgASgIOgVmYWxzZRIk",
|
||||
"ChVqYXZhX2dlbmVyaWNfc2VydmljZXMYESABKAg6BWZhbHNlEiIKE3B5X2dl",
|
||||
"bmVyaWNfc2VydmljZXMYEiABKAg6BWZhbHNlEiMKFHBocF9nZW5lcmljX3Nl",
|
||||
"cnZpY2VzGCogASgIOgVmYWxzZRIZCgpkZXByZWNhdGVkGBcgASgIOgVmYWxz",
|
||||
"ZRIeChBjY19lbmFibGVfYXJlbmFzGB8gASgIOgR0cnVlEhkKEW9iamNfY2xh",
|
||||
"c3NfcHJlZml4GCQgASgJEhgKEGNzaGFycF9uYW1lc3BhY2UYJSABKAkSFAoM",
|
||||
"c3dpZnRfcHJlZml4GCcgASgJEhgKEHBocF9jbGFzc19wcmVmaXgYKCABKAkS",
|
||||
"FQoNcGhwX25hbWVzcGFjZRgpIAEoCRIeChZwaHBfbWV0YWRhdGFfbmFtZXNw",
|
||||
"YWNlGCwgASgJEhQKDHJ1YnlfcGFja2FnZRgtIAEoCRItCghmZWF0dXJlcxgy",
|
||||
"IAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0EkMKFHVuaW50ZXJw",
|
||||
"cmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVy",
|
||||
"cHJldGVkT3B0aW9uIjoKDE9wdGltaXplTW9kZRIJCgVTUEVFRBABEg0KCUNP",
|
||||
"REVfU0laRRACEhAKDExJVEVfUlVOVElNRRADKgkI6AcQgICAgAJKBAgmECci",
|
||||
"5wIKDk1lc3NhZ2VPcHRpb25zEiYKF21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0",
|
||||
"GAEgASgIOgVmYWxzZRIuCh9ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vz",
|
||||
"c29yGAIgASgIOgVmYWxzZRIZCgpkZXByZWNhdGVkGAMgASgIOgVmYWxzZRIR",
|
||||
"CgltYXBfZW50cnkYByABKAgSMgomZGVwcmVjYXRlZF9sZWdhY3lfanNvbl9m",
|
||||
"aWVsZF9jb25mbGljdHMYCyABKAhCAhgBEi0KCGZlYXR1cmVzGAwgASgLMhsu",
|
||||
"Z29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXQSQwoUdW5pbnRlcnByZXRlZF9v",
|
||||
"dGlvblN0YXRlOgpVTlZFUklGSUVEQgOIAQIaaAoLRGVjbGFyYXRpb24SDgoG",
|
||||
"bnVtYmVyGAEgASgFEhEKCWZ1bGxfbmFtZRgCIAEoCRIMCgR0eXBlGAMgASgJ",
|
||||
"EhAKCHJlc2VydmVkGAUgASgIEhAKCHJlcGVhdGVkGAYgASgISgQIBBAFIjQK",
|
||||
"EVZlcmlmaWNhdGlvblN0YXRlEg8KC0RFQ0xBUkFUSU9OEAASDgoKVU5WRVJJ",
|
||||
"RklFRBABKgkI6AcQgICAgAIi1QUKFEZpZWxkRGVzY3JpcHRvclByb3RvEgwK",
|
||||
"BG5hbWUYASABKAkSDgoGbnVtYmVyGAMgASgFEjoKBWxhYmVsGAQgASgOMisu",
|
||||
"Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLkxhYmVsEjgK",
|
||||
"BHR5cGUYBSABKA4yKi5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9y",
|
||||
"UHJvdG8uVHlwZRIRCgl0eXBlX25hbWUYBiABKAkSEAoIZXh0ZW5kZWUYAiAB",
|
||||
"KAkSFQoNZGVmYXVsdF92YWx1ZRgHIAEoCRITCgtvbmVvZl9pbmRleBgJIAEo",
|
||||
"BRIRCglqc29uX25hbWUYCiABKAkSLgoHb3B0aW9ucxgIIAEoCzIdLmdvb2ds",
|
||||
"ZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMSFwoPcHJvdG8zX29wdGlvbmFsGBEg",
|
||||
"ASgIIrYCCgRUeXBlEg8KC1RZUEVfRE9VQkxFEAESDgoKVFlQRV9GTE9BVBAC",
|
||||
"Eg4KClRZUEVfSU5UNjQQAxIPCgtUWVBFX1VJTlQ2NBAEEg4KClRZUEVfSU5U",
|
||||
"MzIQBRIQCgxUWVBFX0ZJWEVENjQQBhIQCgxUWVBFX0ZJWEVEMzIQBxINCglU",
|
||||
"WVBFX0JPT0wQCBIPCgtUWVBFX1NUUklORxAJEg4KClRZUEVfR1JPVVAQChIQ",
|
||||
"CgxUWVBFX01FU1NBR0UQCxIOCgpUWVBFX0JZVEVTEAwSDwoLVFlQRV9VSU5U",
|
||||
"MzIQDRINCglUWVBFX0VOVU0QDhIRCg1UWVBFX1NGSVhFRDMyEA8SEQoNVFlQ",
|
||||
"RV9TRklYRUQ2NBAQEg8KC1RZUEVfU0lOVDMyEBESDwoLVFlQRV9TSU5UNjQQ",
|
||||
"EiJDCgVMYWJlbBISCg5MQUJFTF9PUFRJT05BTBABEhIKDkxBQkVMX1JFUEVB",
|
||||
"VEVEEAMSEgoOTEFCRUxfUkVRVUlSRUQQAiJUChRPbmVvZkRlc2NyaXB0b3JQ",
|
||||
"cm90bxIMCgRuYW1lGAEgASgJEi4KB29wdGlvbnMYAiABKAsyHS5nb29nbGUu",
|
||||
"cHJvdG9idWYuT25lb2ZPcHRpb25zIqQCChNFbnVtRGVzY3JpcHRvclByb3Rv",
|
||||
"EgwKBG5hbWUYASABKAkSOAoFdmFsdWUYAiADKAsyKS5nb29nbGUucHJvdG9i",
|
||||
"dWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvEi0KB29wdGlvbnMYAyABKAsy",
|
||||
"HC5nb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMSTgoOcmVzZXJ2ZWRfcmFu",
|
||||
"Z2UYBCADKAsyNi5nb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90",
|
||||
"by5FbnVtUmVzZXJ2ZWRSYW5nZRIVCg1yZXNlcnZlZF9uYW1lGAUgAygJGi8K",
|
||||
"EUVudW1SZXNlcnZlZFJhbmdlEg0KBXN0YXJ0GAEgASgFEgsKA2VuZBgCIAEo",
|
||||
"BSJsChhFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8SDAoEbmFtZRgBIAEoCRIO",
|
||||
"CgZudW1iZXIYAiABKAUSMgoHb3B0aW9ucxgDIAEoCzIhLmdvb2dsZS5wcm90",
|
||||
"b2J1Zi5FbnVtVmFsdWVPcHRpb25zIpABChZTZXJ2aWNlRGVzY3JpcHRvclBy",
|
||||
"b3RvEgwKBG5hbWUYASABKAkSNgoGbWV0aG9kGAIgAygLMiYuZ29vZ2xlLnBy",
|
||||
"b3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90bxIwCgdvcHRpb25zGAMgASgL",
|
||||
"Mh8uZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zIsEBChVNZXRob2RE",
|
||||
"ZXNjcmlwdG9yUHJvdG8SDAoEbmFtZRgBIAEoCRISCgppbnB1dF90eXBlGAIg",
|
||||
"ASgJEhMKC291dHB1dF90eXBlGAMgASgJEi8KB29wdGlvbnMYBCABKAsyHi5n",
|
||||
"b29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucxIfChBjbGllbnRfc3RyZWFt",
|
||||
"aW5nGAUgASgIOgVmYWxzZRIfChBzZXJ2ZXJfc3RyZWFtaW5nGAYgASgIOgVm",
|
||||
"YWxzZSLUBgoLRmlsZU9wdGlvbnMSFAoMamF2YV9wYWNrYWdlGAEgASgJEhwK",
|
||||
"FGphdmFfb3V0ZXJfY2xhc3NuYW1lGAggASgJEiIKE2phdmFfbXVsdGlwbGVf",
|
||||
"ZmlsZXMYCiABKAg6BWZhbHNlEikKHWphdmFfZ2VuZXJhdGVfZXF1YWxzX2Fu",
|
||||
"ZF9oYXNoGBQgASgIQgIYARIlChZqYXZhX3N0cmluZ19jaGVja191dGY4GBsg",
|
||||
"ASgIOgVmYWxzZRJGCgxvcHRpbWl6ZV9mb3IYCSABKA4yKS5nb29nbGUucHJv",
|
||||
"dG9idWYuRmlsZU9wdGlvbnMuT3B0aW1pemVNb2RlOgVTUEVFRBISCgpnb19w",
|
||||
"YWNrYWdlGAsgASgJEiIKE2NjX2dlbmVyaWNfc2VydmljZXMYECABKAg6BWZh",
|
||||
"bHNlEiQKFWphdmFfZ2VuZXJpY19zZXJ2aWNlcxgRIAEoCDoFZmFsc2USIgoT",
|
||||
"cHlfZ2VuZXJpY19zZXJ2aWNlcxgSIAEoCDoFZmFsc2USIwoUcGhwX2dlbmVy",
|
||||
"aWNfc2VydmljZXMYKiABKAg6BWZhbHNlEhkKCmRlcHJlY2F0ZWQYFyABKAg6",
|
||||
"BWZhbHNlEh4KEGNjX2VuYWJsZV9hcmVuYXMYHyABKAg6BHRydWUSGQoRb2Jq",
|
||||
"Y19jbGFzc19wcmVmaXgYJCABKAkSGAoQY3NoYXJwX25hbWVzcGFjZRglIAEo",
|
||||
"CRIUCgxzd2lmdF9wcmVmaXgYJyABKAkSGAoQcGhwX2NsYXNzX3ByZWZpeBgo",
|
||||
"IAEoCRIVCg1waHBfbmFtZXNwYWNlGCkgASgJEh4KFnBocF9tZXRhZGF0YV9u",
|
||||
"YW1lc3BhY2UYLCABKAkSFAoMcnVieV9wYWNrYWdlGC0gASgJEi0KCGZlYXR1",
|
||||
"cmVzGDIgASgLMhsuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXQSQwoUdW5p",
|
||||
"bnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVu",
|
||||
"aW50ZXJwcmV0ZWRPcHRpb24iOgoMT3B0aW1pemVNb2RlEgkKBVNQRUVEEAES",
|
||||
"DQoJQ09ERV9TSVpFEAISEAoMTElURV9SVU5USU1FEAMqCQjoBxCAgICAAkoE",
|
||||
"CCYQJyLnAgoOTWVzc2FnZU9wdGlvbnMSJgoXbWVzc2FnZV9zZXRfd2lyZV9m",
|
||||
"b3JtYXQYASABKAg6BWZhbHNlEi4KH25vX3N0YW5kYXJkX2Rlc2NyaXB0b3Jf",
|
||||
"YWNjZXNzb3IYAiABKAg6BWZhbHNlEhkKCmRlcHJlY2F0ZWQYAyABKAg6BWZh",
|
||||
"bHNlEhEKCW1hcF9lbnRyeRgHIAEoCBIyCiZkZXByZWNhdGVkX2xlZ2FjeV9q",
|
||||
"c29uX2ZpZWxkX2NvbmZsaWN0cxgLIAEoCEICGAESLQoIZmVhdHVyZXMYDCAB",
|
||||
"KAsyGy5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldBJDChR1bmludGVycHJl",
|
||||
"dGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnBy",
|
||||
"ZXRlZE9wdGlvbioJCOgHEICAgIACSgQIBBAFSgQIBRAGSgQIBhAHSgQICBAJ",
|
||||
"SgQICRAKIo0JCgxGaWVsZE9wdGlvbnMSOgoFY3R5cGUYASABKA4yIy5nb29n",
|
||||
"bGUucHJvdG9idWYuRmllbGRPcHRpb25zLkNUeXBlOgZTVFJJTkcSDgoGcGFj",
|
||||
"a2VkGAIgASgIEj8KBmpzdHlwZRgGIAEoDjIkLmdvb2dsZS5wcm90b2J1Zi5G",
|
||||
"aWVsZE9wdGlvbnMuSlNUeXBlOglKU19OT1JNQUwSEwoEbGF6eRgFIAEoCDoF",
|
||||
"ZmFsc2USHgoPdW52ZXJpZmllZF9sYXp5GA8gASgIOgVmYWxzZRIZCgpkZXBy",
|
||||
"ZWNhdGVkGAMgASgIOgVmYWxzZRITCgR3ZWFrGAogASgIOgVmYWxzZRIbCgxk",
|
||||
"ZWJ1Z19yZWRhY3QYECABKAg6BWZhbHNlEkAKCXJldGVudGlvbhgRIAEoDjIt",
|
||||
"Lmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuT3B0aW9uUmV0ZW50aW9u",
|
||||
"Ej8KB3RhcmdldHMYEyADKA4yLi5nb29nbGUucHJvdG9idWYuRmllbGRPcHRp",
|
||||
"b25zLk9wdGlvblRhcmdldFR5cGUSRgoQZWRpdGlvbl9kZWZhdWx0cxgUIAMo",
|
||||
"CzIsLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuRWRpdGlvbkRlZmF1",
|
||||
"bHQSLQoIZmVhdHVyZXMYFSABKAsyGy5nb29nbGUucHJvdG9idWYuRmVhdHVy",
|
||||
"ZVNldBJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUu",
|
||||
"cHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbhpKCg5FZGl0aW9uRGVmYXVs",
|
||||
"dBIpCgdlZGl0aW9uGAMgASgOMhguZ29vZ2xlLnByb3RvYnVmLkVkaXRpb24S",
|
||||
"DQoFdmFsdWUYAiABKAkiLwoFQ1R5cGUSCgoGU1RSSU5HEAASCAoEQ09SRBAB",
|
||||
"EhAKDFNUUklOR19QSUVDRRACIjUKBkpTVHlwZRINCglKU19OT1JNQUwQABIN",
|
||||
"CglKU19TVFJJTkcQARINCglKU19OVU1CRVIQAiJVCg9PcHRpb25SZXRlbnRp",
|
||||
"b24SFQoRUkVURU5USU9OX1VOS05PV04QABIVChFSRVRFTlRJT05fUlVOVElN",
|
||||
"RRABEhQKEFJFVEVOVElPTl9TT1VSQ0UQAiKMAgoQT3B0aW9uVGFyZ2V0VHlw",
|
||||
"ZRIXChNUQVJHRVRfVFlQRV9VTktOT1dOEAASFAoQVEFSR0VUX1RZUEVfRklM",
|
||||
"RRABEh8KG1RBUkdFVF9UWVBFX0VYVEVOU0lPTl9SQU5HRRACEhcKE1RBUkdF",
|
||||
"VF9UWVBFX01FU1NBR0UQAxIVChFUQVJHRVRfVFlQRV9GSUVMRBAEEhUKEVRB",
|
||||
"UkdFVF9UWVBFX09ORU9GEAUSFAoQVEFSR0VUX1RZUEVfRU5VTRAGEhoKFlRB",
|
||||
"UkdFVF9UWVBFX0VOVU1fRU5UUlkQBxIXChNUQVJHRVRfVFlQRV9TRVJWSUNF",
|
||||
"EAgSFgoSVEFSR0VUX1RZUEVfTUVUSE9EEAkqCQjoBxCAgICAAkoECAQQBUoE",
|
||||
"CBIQEyKNAQoMT25lb2ZPcHRpb25zEi0KCGZlYXR1cmVzGAEgASgLMhsuZ29v",
|
||||
"Z2xlLnByb3RvYnVmLkZlYXR1cmVTZXQSQwoUdW5pbnRlcnByZXRlZF9vcHRp",
|
||||
"b24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRp",
|
||||
"b24qCQjoBxCAgICAAiL2AQoLRW51bU9wdGlvbnMSEwoLYWxsb3dfYWxpYXMY",
|
||||
"AiABKAgSGQoKZGVwcmVjYXRlZBgDIAEoCDoFZmFsc2USMgomZGVwcmVjYXRl",
|
||||
"ZF9sZWdhY3lfanNvbl9maWVsZF9jb25mbGljdHMYBiABKAhCAhgBEi0KCGZl",
|
||||
"YXR1cmVzGAcgASgLMhsuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXQSQwoU",
|
||||
"dW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVm",
|
||||
"LlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAkoECAUQBiLJAQoQRW51",
|
||||
"bVZhbHVlT3B0aW9ucxIZCgpkZXByZWNhdGVkGAEgASgIOgVmYWxzZRItCghm",
|
||||
"ZWF0dXJlcxgCIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0EhsK",
|
||||
"DGRlYnVnX3JlZGFjdBgDIAEoCDoFZmFsc2USQwoUdW5pbnRlcnByZXRlZF9v",
|
||||
"cHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRP",
|
||||
"cHRpb24qCQjoBxCAgICAAkoECAQQBUoECAUQBkoECAYQB0oECAgQCUoECAkQ",
|
||||
"CiKNCQoMRmllbGRPcHRpb25zEjoKBWN0eXBlGAEgASgOMiMuZ29vZ2xlLnBy",
|
||||
"b3RvYnVmLkZpZWxkT3B0aW9ucy5DVHlwZToGU1RSSU5HEg4KBnBhY2tlZBgC",
|
||||
"IAEoCBI/CgZqc3R5cGUYBiABKA4yJC5nb29nbGUucHJvdG9idWYuRmllbGRP",
|
||||
"cHRpb25zLkpTVHlwZToJSlNfTk9STUFMEhMKBGxhenkYBSABKAg6BWZhbHNl",
|
||||
"Eh4KD3VudmVyaWZpZWRfbGF6eRgPIAEoCDoFZmFsc2USGQoKZGVwcmVjYXRl",
|
||||
"ZBgDIAEoCDoFZmFsc2USEwoEd2VhaxgKIAEoCDoFZmFsc2USGwoMZGVidWdf",
|
||||
"cmVkYWN0GBAgASgIOgVmYWxzZRJACglyZXRlbnRpb24YESABKA4yLS5nb29n",
|
||||
"bGUucHJvdG9idWYuRmllbGRPcHRpb25zLk9wdGlvblJldGVudGlvbhI/Cgd0",
|
||||
"YXJnZXRzGBMgAygOMi4uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5P",
|
||||
"cHRpb25UYXJnZXRUeXBlEkYKEGVkaXRpb25fZGVmYXVsdHMYFCADKAsyLC5n",
|
||||
"b29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLkVkaXRpb25EZWZhdWx0Ei0K",
|
||||
"CGZlYXR1cmVzGBUgASgLMhsuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXQS",
|
||||
"QwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3Rv",
|
||||
"YnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24aSgoORWRpdGlvbkRlZmF1bHQSKQoH",
|
||||
"ZWRpdGlvbhgDIAEoDjIYLmdvb2dsZS5wcm90b2J1Zi5FZGl0aW9uEg0KBXZh",
|
||||
"bHVlGAIgASgJIi8KBUNUeXBlEgoKBlNUUklORxAAEggKBENPUkQQARIQCgxT",
|
||||
"VFJJTkdfUElFQ0UQAiI1CgZKU1R5cGUSDQoJSlNfTk9STUFMEAASDQoJSlNf",
|
||||
"U1RSSU5HEAESDQoJSlNfTlVNQkVSEAIiVQoPT3B0aW9uUmV0ZW50aW9uEhUK",
|
||||
"EVJFVEVOVElPTl9VTktOT1dOEAASFQoRUkVURU5USU9OX1JVTlRJTUUQARIU",
|
||||
"ChBSRVRFTlRJT05fU09VUkNFEAIijAIKEE9wdGlvblRhcmdldFR5cGUSFwoT",
|
||||
"VEFSR0VUX1RZUEVfVU5LTk9XThAAEhQKEFRBUkdFVF9UWVBFX0ZJTEUQARIf",
|
||||
"ChtUQVJHRVRfVFlQRV9FWFRFTlNJT05fUkFOR0UQAhIXChNUQVJHRVRfVFlQ",
|
||||
"RV9NRVNTQUdFEAMSFQoRVEFSR0VUX1RZUEVfRklFTEQQBBIVChFUQVJHRVRf",
|
||||
"VFlQRV9PTkVPRhAFEhQKEFRBUkdFVF9UWVBFX0VOVU0QBhIaChZUQVJHRVRf",
|
||||
"VFlQRV9FTlVNX0VOVFJZEAcSFwoTVEFSR0VUX1RZUEVfU0VSVklDRRAIEhYK",
|
||||
"ElRBUkdFVF9UWVBFX01FVEhPRBAJKgkI6AcQgICAgAJKBAgEEAVKBAgSEBMi",
|
||||
"jQEKDE9uZW9mT3B0aW9ucxItCghmZWF0dXJlcxgBIAEoCzIbLmdvb2dsZS5w",
|
||||
"cHRpb24qCQjoBxCAgICAAiKqAQoOU2VydmljZU9wdGlvbnMSLQoIZmVhdHVy",
|
||||
"ZXMYIiABKAsyGy5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldBIZCgpkZXBy",
|
||||
"ZWNhdGVkGCEgASgIOgVmYWxzZRJDChR1bmludGVycHJldGVkX29wdGlvbhjn",
|
||||
"ByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbioJ",
|
||||
"COgHEICAgIACItwCCg1NZXRob2RPcHRpb25zEhkKCmRlcHJlY2F0ZWQYISAB",
|
||||
"KAg6BWZhbHNlEl8KEWlkZW1wb3RlbmN5X2xldmVsGCIgASgOMi8uZ29vZ2xl",
|
||||
"LnByb3RvYnVmLk1ldGhvZE9wdGlvbnMuSWRlbXBvdGVuY3lMZXZlbDoTSURF",
|
||||
"TVBPVEVOQ1lfVU5LTk9XThItCghmZWF0dXJlcxgjIAEoCzIbLmdvb2dsZS5w",
|
||||
"cm90b2J1Zi5GZWF0dXJlU2V0EkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcH",
|
||||
"IAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI",
|
||||
"6AcQgICAgAIi9gEKC0VudW1PcHRpb25zEhMKC2FsbG93X2FsaWFzGAIgASgI",
|
||||
"EhkKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNlEjIKJmRlcHJlY2F0ZWRfbGVn",
|
||||
"YWN5X2pzb25fZmllbGRfY29uZmxpY3RzGAYgASgIQgIYARItCghmZWF0dXJl",
|
||||
"cxgHIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0EkMKFHVuaW50",
|
||||
"ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5Vbmlu",
|
||||
"dGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAJKBAgFEAYiyQEKEEVudW1WYWx1",
|
||||
"ZU9wdGlvbnMSGQoKZGVwcmVjYXRlZBgBIAEoCDoFZmFsc2USLQoIZmVhdHVy",
|
||||
"ZXMYAiABKAsyGy5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldBIbCgxkZWJ1",
|
||||
"Z19yZWRhY3QYAyABKAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9u",
|
||||
"GOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9u",
|
||||
"KgkI6AcQgICAgAIiqgEKDlNlcnZpY2VPcHRpb25zEi0KCGZlYXR1cmVzGCIg",
|
||||
"ASgLMhsuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXQSGQoKZGVwcmVjYXRl",
|
||||
"ZBghIAEoCDoFZmFsc2USQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygL",
|
||||
"MiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCA",
|
||||
"gICAAiLcAgoNTWV0aG9kT3B0aW9ucxIZCgpkZXByZWNhdGVkGCEgASgIOgVm",
|
||||
"YWxzZRJfChFpZGVtcG90ZW5jeV9sZXZlbBgiIAEoDjIvLmdvb2dsZS5wcm90",
|
||||
"b2J1Zi5NZXRob2RPcHRpb25zLklkZW1wb3RlbmN5TGV2ZWw6E0lERU1QT1RF",
|
||||
"TkNZX1VOS05PV04SLQoIZmVhdHVyZXMYIyABKAsyGy5nb29nbGUucHJvdG9i",
|
||||
"dWYuRmVhdHVyZVNldBJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsy",
|
||||
"JC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiJQChBJZGVt",
|
||||
"cG90ZW5jeUxldmVsEhcKE0lERU1QT1RFTkNZX1VOS05PV04QABITCg9OT19T",
|
||||
"SURFX0VGRkVDVFMQARIOCgpJREVNUE9URU5UEAIqCQjoBxCAgICAAiKeAgoT",
|
||||
"VW5pbnRlcnByZXRlZE9wdGlvbhI7CgRuYW1lGAIgAygLMi0uZ29vZ2xlLnBy",
|
||||
"b3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQSGAoQaWRlbnRp",
|
||||
"Zmllcl92YWx1ZRgDIAEoCRIaChJwb3NpdGl2ZV9pbnRfdmFsdWUYBCABKAQS",
|
||||
"GgoSbmVnYXRpdmVfaW50X3ZhbHVlGAUgASgDEhQKDGRvdWJsZV92YWx1ZRgG",
|
||||
"IAEoARIUCgxzdHJpbmdfdmFsdWUYByABKAwSFwoPYWdncmVnYXRlX3ZhbHVl",
|
||||
"GAggASgJGjMKCE5hbWVQYXJ0EhEKCW5hbWVfcGFydBgBIAIoCRIUCgxpc19l",
|
||||
"eHRlbnNpb24YAiACKAginQkKCkZlYXR1cmVTZXQSfAoOZmllbGRfcHJlc2Vu",
|
||||
"Y2UYASABKA4yKS5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldC5GaWVsZFBy",
|
||||
"ZXNlbmNlQjmIAQGYAQSYAQGiAQ0SCEVYUExJQ0lUGOYHogENEghJTVBMSUNJ",
|
||||
"VBjnB6IBDRIIRVhQTElDSVQY6AcSXAoJZW51bV90eXBlGAIgASgOMiQuZ29v",
|
||||
"Z2xlLnByb3RvYnVmLkZlYXR1cmVTZXQuRW51bVR5cGVCI4gBAZgBBpgBAaIB",
|
||||
"CxIGQ0xPU0VEGOYHogEJEgRPUEVOGOcHEnsKF3JlcGVhdGVkX2ZpZWxkX2Vu",
|
||||
"Y29kaW5nGAMgASgOMjEuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXQuUmVw",
|
||||
"ZWF0ZWRGaWVsZEVuY29kaW5nQieIAQGYAQSYAQGiAQ0SCEVYUEFOREVEGOYH",
|
||||
"ogELEgZQQUNLRUQY5wcSaAoPdXRmOF92YWxpZGF0aW9uGAQgASgOMiouZ29v",
|
||||
"Z2xlLnByb3RvYnVmLkZlYXR1cmVTZXQuVXRmOFZhbGlkYXRpb25CI4gBAZgB",
|
||||
"BJgBAaIBCRIETk9ORRjmB6IBCxIGVkVSSUZZGOcHEmcKEG1lc3NhZ2VfZW5j",
|
||||
"b2RpbmcYBSABKA4yKy5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldC5NZXNz",
|
||||
"YWdlRW5jb2RpbmdCIIgBAZgBBJgBAaIBFBIPTEVOR1RIX1BSRUZJWEVEGOYH",
|
||||
"EnAKC2pzb25fZm9ybWF0GAYgASgOMiYuZ29vZ2xlLnByb3RvYnVmLkZlYXR1",
|
||||
"cmVTZXQuSnNvbkZvcm1hdEIziAEBmAEDmAEGmAEBogEXEhJMRUdBQ1lfQkVT",
|
||||
"VF9FRkZPUlQY5geiAQoSBUFMTE9XGOcHIlwKDUZpZWxkUHJlc2VuY2USGgoW",
|
||||
"RklFTERfUFJFU0VOQ0VfVU5LTk9XThAAEgwKCEVYUExJQ0lUEAESDAoISU1Q",
|
||||
"TElDSVQQAhITCg9MRUdBQ1lfUkVRVUlSRUQQAyI3CghFbnVtVHlwZRIVChFF",
|
||||
"TlVNX1RZUEVfVU5LTk9XThAAEggKBE9QRU4QARIKCgZDTE9TRUQQAiJWChVS",
|
||||
"ZXBlYXRlZEZpZWxkRW5jb2RpbmcSIwofUkVQRUFURURfRklFTERfRU5DT0RJ",
|
||||
"TkdfVU5LTk9XThAAEgoKBlBBQ0tFRBABEgwKCEVYUEFOREVEEAIiQwoOVXRm",
|
||||
"OFZhbGlkYXRpb24SGwoXVVRGOF9WQUxJREFUSU9OX1VOS05PV04QABIICgRO",
|
||||
"T05FEAESCgoGVkVSSUZZEAIiUwoPTWVzc2FnZUVuY29kaW5nEhwKGE1FU1NB",
|
||||
"R0VfRU5DT0RJTkdfVU5LTk9XThAAEhMKD0xFTkdUSF9QUkVGSVhFRBABEg0K",
|
||||
"CURFTElNSVRFRBACIkgKCkpzb25Gb3JtYXQSFwoTSlNPTl9GT1JNQVRfVU5L",
|
||||
"Tk9XThAAEgkKBUFMTE9XEAESFgoSTEVHQUNZX0JFU1RfRUZGT1JUEAIqBgjo",
|
||||
"BxDpByoGCOkHEOoHKgYIi04QkE5KBgjnBxDoByLAAgoSRmVhdHVyZVNldERl",
|
||||
"ZmF1bHRzEk4KCGRlZmF1bHRzGAEgAygLMjwuZ29vZ2xlLnByb3RvYnVmLkZl",
|
||||
"YXR1cmVTZXREZWZhdWx0cy5GZWF0dXJlU2V0RWRpdGlvbkRlZmF1bHQSMQoP",
|
||||
"bWluaW11bV9lZGl0aW9uGAQgASgOMhguZ29vZ2xlLnByb3RvYnVmLkVkaXRp",
|
||||
"b24SMQoPbWF4aW11bV9lZGl0aW9uGAUgASgOMhguZ29vZ2xlLnByb3RvYnVm",
|
||||
"LkVkaXRpb24adAoYRmVhdHVyZVNldEVkaXRpb25EZWZhdWx0EikKB2VkaXRp",
|
||||
"b24YAyABKA4yGC5nb29nbGUucHJvdG9idWYuRWRpdGlvbhItCghmZWF0dXJl",
|
||||
"cxgCIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0ItUBCg5Tb3Vy",
|
||||
"Y2VDb2RlSW5mbxI6Cghsb2NhdGlvbhgBIAMoCzIoLmdvb2dsZS5wcm90b2J1",
|
||||
"Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbhqGAQoITG9jYXRpb24SEAoEcGF0",
|
||||
"aBgBIAMoBUICEAESEAoEc3BhbhgCIAMoBUICEAESGAoQbGVhZGluZ19jb21t",
|
||||
"ZW50cxgDIAEoCRIZChF0cmFpbGluZ19jb21tZW50cxgEIAEoCRIhChlsZWFk",
|
||||
"aW5nX2RldGFjaGVkX2NvbW1lbnRzGAYgAygJIpwCChFHZW5lcmF0ZWRDb2Rl",
|
||||
"SW5mbxJBCgphbm5vdGF0aW9uGAEgAygLMi0uZ29vZ2xlLnByb3RvYnVmLkdl",
|
||||
"bmVyYXRlZENvZGVJbmZvLkFubm90YXRpb24awwEKCkFubm90YXRpb24SEAoE",
|
||||
"cGF0aBgBIAMoBUICEAESEwoLc291cmNlX2ZpbGUYAiABKAkSDQoFYmVnaW4Y",
|
||||
"AyABKAUSCwoDZW5kGAQgASgFEkgKCHNlbWFudGljGAUgASgOMjYuZ29vZ2xl",
|
||||
"LnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvLkFubm90YXRpb24uU2VtYW50",
|
||||
"aWMiKAoIU2VtYW50aWMSCAoETk9ORRAAEgcKA1NFVBABEgkKBUFMSUFTEAIq",
|
||||
"6gEKB0VkaXRpb24SEwoPRURJVElPTl9VTktOT1dOEAASEwoORURJVElPTl9Q",
|
||||
"Uk9UTzIQ5gcSEwoORURJVElPTl9QUk9UTzMQ5wcSEQoMRURJVElPTl8yMDIz",
|
||||
"EOgHEhcKE0VESVRJT05fMV9URVNUX09OTFkQARIXChNFRElUSU9OXzJfVEVT",
|
||||
"VF9PTkxZEAISHQoXRURJVElPTl85OTk5N19URVNUX09OTFkQnY0GEh0KF0VE",
|
||||
"SVRJT05fOTk5OThfVEVTVF9PTkxZEJ6NBhIdChdFRElUSU9OXzk5OTk5X1RF",
|
||||
"U1RfT05MWRCfjQZCfgoTY29tLmdvb2dsZS5wcm90b2J1ZkIQRGVzY3JpcHRv",
|
||||
"clByb3Rvc0gBWi1nb29nbGUuZ29sYW5nLm9yZy9wcm90b2J1Zi90eXBlcy9k",
|
||||
"ZXNjcmlwdG9ycGL4AQGiAgNHUEKqAhpHb29nbGUuUHJvdG9idWYuUmVmbGVj",
|
||||
"dGlvbg=="));
|
||||
"IAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIlAK",
|
||||
"EElkZW1wb3RlbmN5TGV2ZWwSFwoTSURFTVBPVEVOQ1lfVU5LTk9XThAAEhMK",
|
||||
"D05PX1NJREVfRUZGRUNUUxABEg4KCklERU1QT1RFTlQQAioJCOgHEICAgIAC",
|
||||
"Ip4CChNVbmludGVycHJldGVkT3B0aW9uEjsKBG5hbWUYAiADKAsyLS5nb29n",
|
||||
"bGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydBIYChBp",
|
||||
"ZGVudGlmaWVyX3ZhbHVlGAMgASgJEhoKEnBvc2l0aXZlX2ludF92YWx1ZRgE",
|
||||
"IAEoBBIaChJuZWdhdGl2ZV9pbnRfdmFsdWUYBSABKAMSFAoMZG91YmxlX3Zh",
|
||||
"bHVlGAYgASgBEhQKDHN0cmluZ192YWx1ZRgHIAEoDBIXCg9hZ2dyZWdhdGVf",
|
||||
"dmFsdWUYCCABKAkaMwoITmFtZVBhcnQSEQoJbmFtZV9wYXJ0GAEgAigJEhQK",
|
||||
"DGlzX2V4dGVuc2lvbhgCIAIoCCKdCQoKRmVhdHVyZVNldBJ8Cg5maWVsZF9w",
|
||||
"cmVzZW5jZRgBIAEoDjIpLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0LkZp",
|
||||
"ZWxkUHJlc2VuY2VCOYgBAZgBBJgBAaIBDRIIRVhQTElDSVQY5geiAQ0SCElN",
|
||||
"UExJQ0lUGOcHogENEghFWFBMSUNJVBjoBxJcCgllbnVtX3R5cGUYAiABKA4y",
|
||||
"JC5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldC5FbnVtVHlwZUIjiAEBmAEG",
|
||||
"mAEBogELEgZDTE9TRUQY5geiAQkSBE9QRU4Y5wcSewoXcmVwZWF0ZWRfZmll",
|
||||
"bGRfZW5jb2RpbmcYAyABKA4yMS5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNl",
|
||||
"dC5SZXBlYXRlZEZpZWxkRW5jb2RpbmdCJ4gBAZgBBJgBAaIBDRIIRVhQQU5E",
|
||||
"RUQY5geiAQsSBlBBQ0tFRBjnBxJoCg91dGY4X3ZhbGlkYXRpb24YBCABKA4y",
|
||||
"Ki5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldC5VdGY4VmFsaWRhdGlvbkIj",
|
||||
"iAEBmAEEmAEBogEJEgROT05FGOYHogELEgZWRVJJRlkY5wcSZwoQbWVzc2Fn",
|
||||
"ZV9lbmNvZGluZxgFIAEoDjIrLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0",
|
||||
"Lk1lc3NhZ2VFbmNvZGluZ0IgiAEBmAEEmAEBogEUEg9MRU5HVEhfUFJFRklY",
|
||||
"RUQY5gcScAoLanNvbl9mb3JtYXQYBiABKA4yJi5nb29nbGUucHJvdG9idWYu",
|
||||
"RmVhdHVyZVNldC5Kc29uRm9ybWF0QjOIAQGYAQOYAQaYAQGiARcSEkxFR0FD",
|
||||
"WV9CRVNUX0VGRk9SVBjmB6IBChIFQUxMT1cY5wciXAoNRmllbGRQcmVzZW5j",
|
||||
"ZRIaChZGSUVMRF9QUkVTRU5DRV9VTktOT1dOEAASDAoIRVhQTElDSVQQARIM",
|
||||
"CghJTVBMSUNJVBACEhMKD0xFR0FDWV9SRVFVSVJFRBADIjcKCEVudW1UeXBl",
|
||||
"EhUKEUVOVU1fVFlQRV9VTktOT1dOEAASCAoET1BFThABEgoKBkNMT1NFRBAC",
|
||||
"IlYKFVJlcGVhdGVkRmllbGRFbmNvZGluZxIjCh9SRVBFQVRFRF9GSUVMRF9F",
|
||||
"TkNPRElOR19VTktOT1dOEAASCgoGUEFDS0VEEAESDAoIRVhQQU5ERUQQAiJD",
|
||||
"Cg5VdGY4VmFsaWRhdGlvbhIbChdVVEY4X1ZBTElEQVRJT05fVU5LTk9XThAA",
|
||||
"EgoKBlZFUklGWRACEggKBE5PTkUQAyJTCg9NZXNzYWdlRW5jb2RpbmcSHAoY",
|
||||
"TUVTU0FHRV9FTkNPRElOR19VTktOT1dOEAASEwoPTEVOR1RIX1BSRUZJWEVE",
|
||||
"EAESDQoJREVMSU1JVEVEEAIiSAoKSnNvbkZvcm1hdBIXChNKU09OX0ZPUk1B",
|
||||
"VF9VTktOT1dOEAASCQoFQUxMT1cQARIWChJMRUdBQ1lfQkVTVF9FRkZPUlQQ",
|
||||
"AioGCOgHEOkHKgYI6QcQ6gcqBgiLThCQTkoGCOcHEOgHIsACChJGZWF0dXJl",
|
||||
"U2V0RGVmYXVsdHMSTgoIZGVmYXVsdHMYASADKAsyPC5nb29nbGUucHJvdG9i",
|
||||
"dWYuRmVhdHVyZVNldERlZmF1bHRzLkZlYXR1cmVTZXRFZGl0aW9uRGVmYXVs",
|
||||
"dBIxCg9taW5pbXVtX2VkaXRpb24YBCABKA4yGC5nb29nbGUucHJvdG9idWYu",
|
||||
"RWRpdGlvbhIxCg9tYXhpbXVtX2VkaXRpb24YBSABKA4yGC5nb29nbGUucHJv",
|
||||
"dG9idWYuRWRpdGlvbhp0ChhGZWF0dXJlU2V0RWRpdGlvbkRlZmF1bHQSKQoH",
|
||||
"ZWRpdGlvbhgDIAEoDjIYLmdvb2dsZS5wcm90b2J1Zi5FZGl0aW9uEi0KCGZl",
|
||||
"YXR1cmVzGAIgASgLMhsuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXQi1QEK",
|
||||
"DlNvdXJjZUNvZGVJbmZvEjoKCGxvY2F0aW9uGAEgAygLMiguZ29vZ2xlLnBy",
|
||||
"b3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uGoYBCghMb2NhdGlvbhIQ",
|
||||
"CgRwYXRoGAEgAygFQgIQARIQCgRzcGFuGAIgAygFQgIQARIYChBsZWFkaW5n",
|
||||
"X2NvbW1lbnRzGAMgASgJEhkKEXRyYWlsaW5nX2NvbW1lbnRzGAQgASgJEiEK",
|
||||
"GWxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMYBiADKAkinAIKEUdlbmVyYXRl",
|
||||
"ZENvZGVJbmZvEkEKCmFubm90YXRpb24YASADKAsyLS5nb29nbGUucHJvdG9i",
|
||||
"dWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvbhrDAQoKQW5ub3RhdGlv",
|
||||
"bhIQCgRwYXRoGAEgAygFQgIQARITCgtzb3VyY2VfZmlsZRgCIAEoCRINCgVi",
|
||||
"ZWdpbhgDIAEoBRILCgNlbmQYBCABKAUSSAoIc2VtYW50aWMYBSABKA4yNi5n",
|
||||
"b29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvbi5T",
|
||||
"ZW1hbnRpYyIoCghTZW1hbnRpYxIICgROT05FEAASBwoDU0VUEAESCQoFQUxJ",
|
||||
"QVMQAir/AQoHRWRpdGlvbhITCg9FRElUSU9OX1VOS05PV04QABITCg5FRElU",
|
||||
"SU9OX1BST1RPMhDmBxITCg5FRElUSU9OX1BST1RPMxDnBxIRCgxFRElUSU9O",
|
||||
"XzIwMjMQ6AcSFwoTRURJVElPTl8xX1RFU1RfT05MWRABEhcKE0VESVRJT05f",
|
||||
"Ml9URVNUX09OTFkQAhIdChdFRElUSU9OXzk5OTk3X1RFU1RfT05MWRCdjQYS",
|
||||
"HQoXRURJVElPTl85OTk5OF9URVNUX09OTFkQno0GEh0KF0VESVRJT05fOTk5",
|
||||
"OTlfVEVTVF9PTkxZEJ+NBhITCgtFRElUSU9OX01BWBD/////B0J+ChNjb20u",
|
||||
"Z29vZ2xlLnByb3RvYnVmQhBEZXNjcmlwdG9yUHJvdG9zSAFaLWdvb2dsZS5n",
|
||||
"b2xhbmcub3JnL3Byb3RvYnVmL3R5cGVzL2Rlc2NyaXB0b3JwYvgBAaICA0dQ",
|
||||
"QqoCGkdvb2dsZS5Qcm90b2J1Zi5SZWZsZWN0aW9u"));
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.Reflection.Edition), }, null, new pbr::GeneratedClrTypeInfo[] {
|
||||
|
@ -301,6 +301,12 @@ namespace Google.Protobuf.Reflection {
|
|||
[pbr::OriginalName("EDITION_99997_TEST_ONLY")] _99997TestOnly = 99997,
|
||||
[pbr::OriginalName("EDITION_99998_TEST_ONLY")] _99998TestOnly = 99998,
|
||||
[pbr::OriginalName("EDITION_99999_TEST_ONLY")] _99999TestOnly = 99999,
|
||||
/// <summary>
|
||||
/// Placeholder for specifying unbounded edition support. This should only
|
||||
/// ever be used by plugins that can expect to never require any changes to
|
||||
/// support a new edition.
|
||||
/// </summary>
|
||||
[pbr::OriginalName("EDITION_MAX")] Max = 2147483647,
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -7420,10 +7426,6 @@ namespace Google.Protobuf.Reflection {
|
|||
|
||||
private bool mapEntry_;
|
||||
/// <summary>
|
||||
/// NOTE: Do not set the option in .proto files. Always use the maps syntax
|
||||
/// instead. The option should only be implicitly set by the proto compiler
|
||||
/// parser.
|
||||
///
|
||||
/// Whether the message is an automatically generated map entry type for the
|
||||
/// maps field.
|
||||
///
|
||||
|
@ -7441,6 +7443,10 @@ namespace Google.Protobuf.Reflection {
|
|||
/// use a native map in the target language to hold the keys and values.
|
||||
/// The reflection APIs in such implementations still need to work as
|
||||
/// if the field is a repeated message field.
|
||||
///
|
||||
/// NOTE: Do not set the option in .proto files. Always use the maps syntax
|
||||
/// instead. The option should only be implicitly set by the proto compiler
|
||||
/// parser.
|
||||
/// </summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
|
@ -12256,8 +12262,8 @@ namespace Google.Protobuf.Reflection {
|
|||
|
||||
public enum Utf8Validation {
|
||||
[pbr::OriginalName("UTF8_VALIDATION_UNKNOWN")] Unknown = 0,
|
||||
[pbr::OriginalName("NONE")] None = 1,
|
||||
[pbr::OriginalName("VERIFY")] Verify = 2,
|
||||
[pbr::OriginalName("NONE")] None = 3,
|
||||
}
|
||||
|
||||
public enum MessageEncoding {
|
||||
|
@ -13133,7 +13139,7 @@ namespace Google.Protobuf.Reflection {
|
|||
/// location.
|
||||
///
|
||||
/// Each element is a field number or an index. They form a path from
|
||||
/// the root FileDescriptorProto to the place where the definition occurs.
|
||||
/// the root FileDescriptorProto to the place where the definition appears.
|
||||
/// For example, this path:
|
||||
/// [ 4, 3, 2, 7, 1 ]
|
||||
/// refers to:
|
||||
|
|
|
@ -538,44 +538,4 @@ public abstract class AbstractMessage
|
|||
return (BuilderType) super.mergeFrom(input, extensionRegistry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated from v3.0.0-beta-3+, for compatibility with v2.5.0 and v2.6.1
|
||||
* generated code.
|
||||
*/
|
||||
@Deprecated
|
||||
protected static int hashLong(long n) {
|
||||
return (int) (n ^ (n >>> 32));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated from v3.0.0-beta-3+, for compatibility with v2.5.0 and v2.6.1
|
||||
* generated code.
|
||||
*/
|
||||
@Deprecated
|
||||
protected static int hashBoolean(boolean b) {
|
||||
return b ? 1231 : 1237;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated from v3.0.0-beta-3+, for compatibility with v2.5.0 and v2.6.1
|
||||
* generated code.
|
||||
*/
|
||||
@Deprecated
|
||||
protected static int hashEnum(EnumLite e) {
|
||||
return e.getNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated from v3.0.0-beta-3+, for compatibility with v2.5.0 and v2.6.1
|
||||
* generated code.
|
||||
*/
|
||||
@Deprecated
|
||||
protected static int hashEnumList(List<? extends EnumLite> list) {
|
||||
int hash = 1;
|
||||
for (EnumLite e : list) {
|
||||
hash = 31 * hash + hashEnum(e);
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,9 @@ public abstract class CodedOutputStream extends ByteOutput {
|
|||
/** Used to adapt to the experimental {@link Writer} interface. */
|
||||
CodedOutputStreamWriter wrapper;
|
||||
|
||||
/** @deprecated Use {@link #computeFixed32SizeNoTag(int)} instead. */
|
||||
/**
|
||||
* @deprecated Use {@link #computeFixed32SizeNoTag(int)} instead.
|
||||
*/
|
||||
@Deprecated public static final int LITTLE_ENDIAN_32_SIZE = FIXED32_SIZE;
|
||||
|
||||
/** The buffer size used in {@link #newInstance(OutputStream)}. */
|
||||
|
@ -669,9 +671,8 @@ public abstract class CodedOutputStream extends ByteOutput {
|
|||
}
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a lazily parsed MessageSet
|
||||
* extension field to the stream. For historical reasons, the wire format differs from normal
|
||||
* fields.
|
||||
* Compute the number of bytes that would be needed to encode a lazily parsed MessageSet extension
|
||||
* field to the stream. For historical reasons, the wire format differs from normal fields.
|
||||
*/
|
||||
public static int computeLazyFieldMessageSetExtensionSize(
|
||||
final int fieldNumber, final LazyFieldLite value) {
|
||||
|
@ -692,29 +693,52 @@ public abstract class CodedOutputStream extends ByteOutput {
|
|||
* tag.
|
||||
*/
|
||||
public static int computeInt32SizeNoTag(final int value) {
|
||||
if (value >= 0) {
|
||||
return computeUInt32SizeNoTag(value);
|
||||
} else {
|
||||
// Must sign-extend.
|
||||
return MAX_VARINT_SIZE;
|
||||
}
|
||||
return computeUInt64SizeNoTag((long) value);
|
||||
}
|
||||
|
||||
/** Compute the number of bytes that would be needed to encode a {@code uint32} field. */
|
||||
public static int computeUInt32SizeNoTag(final int value) {
|
||||
if ((value & (~0 << 7)) == 0) {
|
||||
return 1;
|
||||
}
|
||||
if ((value & (~0 << 14)) == 0) {
|
||||
return 2;
|
||||
}
|
||||
if ((value & (~0 << 21)) == 0) {
|
||||
return 3;
|
||||
}
|
||||
if ((value & (~0 << 28)) == 0) {
|
||||
return 4;
|
||||
}
|
||||
return 5;
|
||||
/*
|
||||
This code is ported from the C++ varint implementation.
|
||||
Implementation notes:
|
||||
|
||||
To calcuate varint size, we want to count the number of 7 bit chunks required. Rather than using
|
||||
division by 7 to accomplish this, we use multiplication by 9/64. This has a number of important
|
||||
properties:
|
||||
* It's roughly 1/7.111111. This makes the 0 bits set case have the same value as the 7 bits set
|
||||
case, so offsetting by 1 gives us the correct value we want for integers up to 448 bits.
|
||||
* Multiplying by 9 is special. x * 9 = x << 3 + x, and so this multiplication can be done by a
|
||||
single shifted add on arm (add w0, w0, w0, lsl #3), or a single lea instruction
|
||||
(leal (%rax,%rax,8), %eax)) on x86.
|
||||
* Dividing by 64 is a 6 bit right shift.
|
||||
|
||||
An explicit non-sign-extended right shift is used instead of the more obvious '/ 64' because
|
||||
that actually produces worse code on android arm64 at time of authoring because of sign
|
||||
extension. Rather than
|
||||
lsr w0, w0, #6
|
||||
It would emit:
|
||||
add w16, w0, #0x3f (63)
|
||||
cmp w0, #0x0 (0)
|
||||
csel w0, w16, w0, lt
|
||||
asr w0, w0, #6
|
||||
|
||||
Summarized:
|
||||
floor(((Integer.SIZE - clz) / 7.1111) + 1
|
||||
((Integer.SIZE - clz) * 9) / 64 + 1
|
||||
(((Integer.SIZE - clz) * 9) >>> 6) + 1
|
||||
((Integer.SIZE - clz) * 9 + (1 << 6)) >>> 6
|
||||
(Integer.SIZE * 9 + (1 << 6) - clz * 9) >>> 6
|
||||
(352 - clz * 9) >>> 6
|
||||
on arm:
|
||||
(352 - clz - (clz << 3)) >>> 6
|
||||
on x86:
|
||||
(352 - lea(clz, clz, 8)) >>> 6
|
||||
|
||||
If you make changes here, please validate their compiled output on different architectures and
|
||||
runtimes.
|
||||
*/
|
||||
int clz = Integer.numberOfLeadingZeros(value);
|
||||
return ((Integer.SIZE * 9 + (1 << 6)) - (clz * 9)) >>> 6;
|
||||
}
|
||||
|
||||
/** Compute the number of bytes that would be needed to encode an {@code sint32} field. */
|
||||
|
@ -745,27 +769,9 @@ public abstract class CodedOutputStream extends ByteOutput {
|
|||
* tag.
|
||||
*/
|
||||
public static int computeUInt64SizeNoTag(long value) {
|
||||
// handle two popular special cases up front ...
|
||||
if ((value & (~0L << 7)) == 0L) {
|
||||
return 1;
|
||||
}
|
||||
if (value < 0L) {
|
||||
return 10;
|
||||
}
|
||||
// ... leaving us with 8 remaining, which we can divide and conquer
|
||||
int n = 2;
|
||||
if ((value & (~0L << 35)) != 0L) {
|
||||
n += 4;
|
||||
value >>>= 28;
|
||||
}
|
||||
if ((value & (~0L << 21)) != 0L) {
|
||||
n += 2;
|
||||
value >>>= 14;
|
||||
}
|
||||
if ((value & (~0L << 14)) != 0L) {
|
||||
n += 1;
|
||||
}
|
||||
return n;
|
||||
int clz = Long.numberOfLeadingZeros(value);
|
||||
// See computeUInt32SizeNoTag for explanation
|
||||
return ((Long.SIZE * 9 + (1 << 6)) - (clz * 9)) >>> 6;
|
||||
}
|
||||
|
||||
/** Compute the number of bytes that would be needed to encode an {@code sint64} field. */
|
||||
|
@ -1326,7 +1332,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
|||
buffer[position++] = (byte) value;
|
||||
return;
|
||||
} else {
|
||||
buffer[position++] = (byte) ((value & 0x7F) | 0x80);
|
||||
buffer[position++] = (byte) ((value | 0x80) & 0xFF);
|
||||
value >>>= 7;
|
||||
}
|
||||
}
|
||||
|
@ -1357,7 +1363,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
|||
UnsafeUtil.putByte(buffer, position++, (byte) value);
|
||||
return;
|
||||
} else {
|
||||
UnsafeUtil.putByte(buffer, position++, (byte) (((int) value & 0x7F) | 0x80));
|
||||
UnsafeUtil.putByte(buffer, position++, (byte) (((int) value | 0x80) & 0xFF));
|
||||
value >>>= 7;
|
||||
}
|
||||
}
|
||||
|
@ -1368,7 +1374,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
|||
buffer[position++] = (byte) value;
|
||||
return;
|
||||
} else {
|
||||
buffer[position++] = (byte) (((int) value & 0x7F) | 0x80);
|
||||
buffer[position++] = (byte) (((int) value | 0x80) & 0xFF);
|
||||
value >>>= 7;
|
||||
}
|
||||
}
|
||||
|
@ -1684,7 +1690,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
|||
buffer.put((byte) value);
|
||||
return;
|
||||
} else {
|
||||
buffer.put((byte) ((value & 0x7F) | 0x80));
|
||||
buffer.put((byte) ((value | 0x80) & 0xFF));
|
||||
value >>>= 7;
|
||||
}
|
||||
}
|
||||
|
@ -1710,7 +1716,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
|||
buffer.put((byte) value);
|
||||
return;
|
||||
} else {
|
||||
buffer.put((byte) (((int) value & 0x7F) | 0x80));
|
||||
buffer.put((byte) (((int) value | 0x80) & 0xFF));
|
||||
value >>>= 7;
|
||||
}
|
||||
}
|
||||
|
@ -2015,7 +2021,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
|||
UnsafeUtil.putByte(position++, (byte) value);
|
||||
return;
|
||||
} else {
|
||||
UnsafeUtil.putByte(position++, (byte) ((value & 0x7F) | 0x80));
|
||||
UnsafeUtil.putByte(position++, (byte) ((value | 0x80) & 0xFF));
|
||||
value >>>= 7;
|
||||
}
|
||||
}
|
||||
|
@ -2025,7 +2031,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
|||
UnsafeUtil.putByte(position++, (byte) value);
|
||||
return;
|
||||
} else {
|
||||
UnsafeUtil.putByte(position++, (byte) ((value & 0x7F) | 0x80));
|
||||
UnsafeUtil.putByte(position++, (byte) ((value | 0x80) & 0xFF));
|
||||
value >>>= 7;
|
||||
}
|
||||
}
|
||||
|
@ -2049,7 +2055,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
|||
UnsafeUtil.putByte(position++, (byte) value);
|
||||
return;
|
||||
} else {
|
||||
UnsafeUtil.putByte(position++, (byte) (((int) value & 0x7F) | 0x80));
|
||||
UnsafeUtil.putByte(position++, (byte) (((int) value | 0x80) & 0xFF));
|
||||
value >>>= 7;
|
||||
}
|
||||
}
|
||||
|
@ -2059,7 +2065,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
|||
UnsafeUtil.putByte(position++, (byte) value);
|
||||
return;
|
||||
} else {
|
||||
UnsafeUtil.putByte(position++, (byte) (((int) value & 0x7F) | 0x80));
|
||||
UnsafeUtil.putByte(position++, (byte) (((int) value | 0x80) & 0xFF));
|
||||
value >>>= 7;
|
||||
}
|
||||
}
|
||||
|
@ -2259,7 +2265,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
|||
UnsafeUtil.putByte(buffer, position++, (byte) value);
|
||||
break;
|
||||
} else {
|
||||
UnsafeUtil.putByte(buffer, position++, (byte) ((value & 0x7F) | 0x80));
|
||||
UnsafeUtil.putByte(buffer, position++, (byte) ((value | 0x80) & 0xFF));
|
||||
value >>>= 7;
|
||||
}
|
||||
}
|
||||
|
@ -2272,7 +2278,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
|||
totalBytesWritten++;
|
||||
return;
|
||||
} else {
|
||||
buffer[position++] = (byte) ((value & 0x7F) | 0x80);
|
||||
buffer[position++] = (byte) ((value | 0x80) & 0xFF);
|
||||
totalBytesWritten++;
|
||||
value >>>= 7;
|
||||
}
|
||||
|
@ -2292,7 +2298,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
|||
UnsafeUtil.putByte(buffer, position++, (byte) value);
|
||||
break;
|
||||
} else {
|
||||
UnsafeUtil.putByte(buffer, position++, (byte) (((int) value & 0x7F) | 0x80));
|
||||
UnsafeUtil.putByte(buffer, position++, (byte) (((int) value | 0x80) & 0xFF));
|
||||
value >>>= 7;
|
||||
}
|
||||
}
|
||||
|
@ -2305,7 +2311,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
|||
totalBytesWritten++;
|
||||
return;
|
||||
} else {
|
||||
buffer[position++] = (byte) (((int) value & 0x7F) | 0x80);
|
||||
buffer[position++] = (byte) (((int) value | 0x80) & 0xFF);
|
||||
totalBytesWritten++;
|
||||
value >>>= 7;
|
||||
}
|
||||
|
|
|
@ -140,8 +140,6 @@ public final class Descriptors {
|
|||
}
|
||||
|
||||
/** The syntax of the .proto file. */
|
||||
@Deprecated
|
||||
public
|
||||
enum Syntax {
|
||||
UNKNOWN("unknown"),
|
||||
PROTO2("proto2"),
|
||||
|
@ -156,8 +154,6 @@ public final class Descriptors {
|
|||
}
|
||||
|
||||
/** Get the syntax of the .proto file. */
|
||||
@Deprecated
|
||||
public
|
||||
Syntax getSyntax() {
|
||||
if (Syntax.PROTO3.name.equals(proto.getSyntax())) {
|
||||
return Syntax.PROTO3;
|
||||
|
@ -1273,8 +1269,6 @@ public final class Descriptors {
|
|||
* Returns true if this field was syntactically written with "optional" in the .proto file.
|
||||
* Excludes singular proto3 fields that do not have a label.
|
||||
*/
|
||||
@Deprecated
|
||||
public
|
||||
boolean hasOptionalKeyword() {
|
||||
return isProto3Optional
|
||||
|| (file.getSyntax() == Syntax.PROTO2 && isOptional() && getContainingOneof() == null);
|
||||
|
@ -2843,8 +2837,6 @@ public final class Descriptors {
|
|||
return proto;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public
|
||||
boolean isSynthetic() {
|
||||
return fields.length == 1 && fields[0].isProto3Optional;
|
||||
}
|
||||
|
|
|
@ -1440,7 +1440,7 @@ public abstract class GeneratedMessageLite<
|
|||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException("Unable to find proto buffer class: " + messageClassName, e);
|
||||
} catch (NoSuchFieldException e) {
|
||||
return readResolveFallback();
|
||||
throw new RuntimeException("Unable to find DEFAULT_INSTANCE in " + messageClassName, e);
|
||||
} catch (SecurityException e) {
|
||||
throw new RuntimeException("Unable to call DEFAULT_INSTANCE in " + messageClassName, e);
|
||||
} catch (IllegalAccessException e) {
|
||||
|
@ -1450,33 +1450,6 @@ public abstract class GeneratedMessageLite<
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated from v3.0.0-beta-3+, for compatibility with v2.5.0 and v2.6.1 generated code.
|
||||
*/
|
||||
@Deprecated
|
||||
private Object readResolveFallback() throws ObjectStreamException {
|
||||
try {
|
||||
Class<?> messageClass = resolveMessageClass();
|
||||
java.lang.reflect.Field defaultInstanceField =
|
||||
messageClass.getDeclaredField("defaultInstance");
|
||||
defaultInstanceField.setAccessible(true);
|
||||
MessageLite defaultInstance = (MessageLite) defaultInstanceField.get(null);
|
||||
return defaultInstance.newBuilderForType()
|
||||
.mergeFrom(asBytes)
|
||||
.buildPartial();
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException("Unable to find proto buffer class: " + messageClassName, e);
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new RuntimeException("Unable to find defaultInstance in " + messageClassName, e);
|
||||
} catch (SecurityException e) {
|
||||
throw new RuntimeException("Unable to call defaultInstance in " + messageClassName, e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException("Unable to call parsePartialFrom", e);
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
throw new RuntimeException("Unable to understand proto buffer", e);
|
||||
}
|
||||
}
|
||||
|
||||
private Class<?> resolveMessageClass() throws ClassNotFoundException {
|
||||
return messageClass != null ? messageClass : Class.forName(messageClassName);
|
||||
}
|
||||
|
|
|
@ -2459,11 +2459,7 @@ public abstract class GeneratedMessageV3 extends AbstractMessage implements Seri
|
|||
final String containingOneofCamelCaseName) {
|
||||
isOneofField =
|
||||
descriptor.getRealContainingOneof() != null;
|
||||
hasHasMethod =
|
||||
descriptor.getFile().getSyntax() == FileDescriptor.Syntax.EDITIONS && descriptor.hasPresence()
|
||||
|| descriptor.getFile().getSyntax() == FileDescriptor.Syntax.PROTO2
|
||||
|| descriptor.hasOptionalKeyword()
|
||||
|| (!isOneofField && descriptor.getJavaType() == FieldDescriptor.JavaType.MESSAGE);
|
||||
hasHasMethod = descriptor.hasPresence();
|
||||
ReflectionInvoker reflectionInvoker =
|
||||
new ReflectionInvoker(
|
||||
descriptor,
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
package com.google.protobuf;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Provides the version of this Protobuf Java runtime, and methods for Protobuf Java gencode to
|
||||
* validate that versions are compatible. Fields and methods in this class should be only accessed
|
||||
|
@ -29,6 +31,31 @@ public final class RuntimeVersion {
|
|||
public static final String SUFFIX = "-dev";
|
||||
private static final String VERSION_STRING = versionString(MAJOR, MINOR, PATCH, SUFFIX);
|
||||
|
||||
/**
|
||||
* Validates that the gencode is in the same domain as the runtime.
|
||||
*
|
||||
* <p>This method will be directly called by the google-internal gencode to verify no cross-domain
|
||||
* usages.
|
||||
*
|
||||
* @param gencodeDomain the domain where Protobuf Java code was generated.
|
||||
* @throws ProtobufRuntimeVersionException if gencodeDomain is not the same as DOMAIN.
|
||||
*/
|
||||
public static void validateProtobufGencodeDomain(RuntimeDomain gencodeDomain) {
|
||||
// Check the environmental variable, and temporarily disable validation if it's set to true.
|
||||
String disableFlag = java.lang.System.getenv("TEMORARILY_DISABLE_PROTOBUF_VERSION_CHECK");
|
||||
if ((disableFlag != null && disableFlag.equals("true"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (gencodeDomain != DOMAIN) {
|
||||
throw new ProtobufRuntimeVersionException(
|
||||
String.format(
|
||||
"Mismatched Protobuf Gencode/Runtime domains: gencode %s, runtime %s. Cross-domain"
|
||||
+ " usage of Protobuf is not supported.",
|
||||
gencodeDomain, DOMAIN));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that the gencode version is compatible with this runtime version according to
|
||||
* https://protobuf.dev/support/cross-version-runtime-guarantee/.
|
||||
|
@ -37,7 +64,7 @@ public final class RuntimeVersion {
|
|||
*
|
||||
* <p>This method is only for Protobuf Java gencode; do not call it elsewhere.
|
||||
*
|
||||
* @param domain the domain where Protobuf Java code was generated. Currently ignored.
|
||||
* @param domain the domain where Protobuf Java code was generated.
|
||||
* @param major the major version of Protobuf Java gencode.
|
||||
* @param minor the minor version of Protobuf Java gencode.
|
||||
* @param patch the micro/patch version of Protobuf Java gencode.
|
||||
|
@ -47,18 +74,14 @@ public final class RuntimeVersion {
|
|||
public static void validateProtobufGencodeVersion(
|
||||
RuntimeDomain domain, int major, int minor, int patch, String suffix) {
|
||||
|
||||
// Check the environmental variable, and temporarily disable poison pills if it's set to true.
|
||||
String disableFlag = java.lang.System.getenv("TEMORARILY_DISABLE_PROTOBUF_VERSION_CHECK");
|
||||
if (disableFlag != null && disableFlag.equals("true")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check that version numbers are valid.
|
||||
if (major < 0 || minor < 0 || patch < 0) {
|
||||
throw new ProtobufRuntimeVersionException(
|
||||
"Invalid gencode version: " + versionString(major, minor, patch, suffix));
|
||||
}
|
||||
|
||||
validateProtobufGencodeDomain(domain);
|
||||
|
||||
String gencodeVersionString = versionString(major, minor, patch, suffix);
|
||||
// Check that runtime major version is the same as the gencode major version.
|
||||
if (major != MAJOR) {
|
||||
|
|
|
@ -38,58 +38,6 @@ public final class TextFormat {
|
|||
|
||||
private static final String DEBUG_STRING_SILENT_MARKER = "\t ";
|
||||
|
||||
/**
|
||||
* Outputs a textual representation of the Protocol Message supplied into the parameter output.
|
||||
* (This representation is the new version of the classic "ProtocolPrinter" output from the
|
||||
* original Protocol Buffer system)
|
||||
*
|
||||
* @deprecated Use {@code printer().print(MessageOrBuilder, Appendable)}
|
||||
*/
|
||||
@Deprecated
|
||||
@InlineMe(
|
||||
replacement = "TextFormat.printer().print(message, output)",
|
||||
imports = "com.google.protobuf.TextFormat")
|
||||
public static void print(final MessageOrBuilder message, final Appendable output)
|
||||
throws IOException {
|
||||
printer().print(message, output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a textual representation of {@code fields} to {@code output}.
|
||||
*
|
||||
* @deprecated Use {@code printer().print(UnknownFieldSet, Appendable)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static void print(final UnknownFieldSet fields, final Appendable output)
|
||||
throws IOException {
|
||||
printer().print(fields, output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@code print()}, except that non-ASCII characters are not escaped.
|
||||
*
|
||||
* @deprecated Use {@code printer().escapingNonAscii(false).print(MessageOrBuilder, Appendable)}
|
||||
*/
|
||||
@Deprecated
|
||||
@InlineMe(
|
||||
replacement = "TextFormat.printer().escapingNonAscii(false).print(message, output)",
|
||||
imports = "com.google.protobuf.TextFormat")
|
||||
public static void printUnicode(final MessageOrBuilder message, final Appendable output)
|
||||
throws IOException {
|
||||
printer().escapingNonAscii(false).print(message, output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@code print()}, except that non-ASCII characters are not escaped.
|
||||
*
|
||||
* @deprecated Use {@code printer().escapingNonAscii(false).print(UnknownFieldSet, Appendable)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static void printUnicode(final UnknownFieldSet fields, final Appendable output)
|
||||
throws IOException {
|
||||
printer().escapingNonAscii(false).print(fields, output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a human readable form of this message, useful for debugging and other purposes, with
|
||||
* no newline characters. This is just a trivial wrapper around {@link
|
||||
|
@ -99,130 +47,6 @@ public final class TextFormat {
|
|||
return printer().shortDebugString(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a human readable form of the field, useful for debugging and other purposes, with
|
||||
* no newline characters.
|
||||
*
|
||||
* @deprecated Use {@code printer().shortDebugString(FieldDescriptor, Object)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static String shortDebugString(final FieldDescriptor field, final Object value) {
|
||||
return printer().shortDebugString(field, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a human readable form of the unknown fields, useful for debugging and other
|
||||
* purposes, with no newline characters.
|
||||
*
|
||||
* @deprecated Use {@code printer().shortDebugString(UnknownFieldSet)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static String shortDebugString(final UnknownFieldSet fields) {
|
||||
return printer().shortDebugString(fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@code print()}, but writes directly to a {@code String} and returns it.
|
||||
*
|
||||
* @deprecated Use {@code message.toString()}
|
||||
*/
|
||||
@Deprecated
|
||||
@InlineMe(
|
||||
replacement = "TextFormat.printer().printToString(message)",
|
||||
imports = "com.google.protobuf.TextFormat")
|
||||
public static String printToString(final MessageOrBuilder message) {
|
||||
return printer().printToString(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@code print()}, but writes directly to a {@code String} and returns it.
|
||||
*
|
||||
* @deprecated Use {@link UnknownFieldSet#toString()}
|
||||
*/
|
||||
@Deprecated
|
||||
public static String printToString(final UnknownFieldSet fields) {
|
||||
return printer().printToString(fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@code printToString()}, except that non-ASCII characters in string type fields are not
|
||||
* escaped in backslash+octals.
|
||||
*
|
||||
* @deprecated Use {@code printer().escapingNonAscii(false).printToString(MessageOrBuilder)}
|
||||
*/
|
||||
@Deprecated
|
||||
@InlineMe(
|
||||
replacement = "TextFormat.printer().escapingNonAscii(false).printToString(message)",
|
||||
imports = "com.google.protobuf.TextFormat")
|
||||
public static String printToUnicodeString(final MessageOrBuilder message) {
|
||||
return printer().escapingNonAscii(false).printToString(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@code printToString()}, except that non-ASCII characters in string type fields are
|
||||
* not escaped in backslash+octals.
|
||||
*
|
||||
* @deprecated Use {@code printer().escapingNonAscii(false).printToString(UnknownFieldSet)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static String printToUnicodeString(final UnknownFieldSet fields) {
|
||||
return printer().escapingNonAscii(false).printToString(fields);
|
||||
}
|
||||
|
||||
/** @deprecated Use {@code printer().printField(FieldDescriptor, Object, Appendable)} */
|
||||
@Deprecated
|
||||
public static void printField(
|
||||
final FieldDescriptor field, final Object value, final Appendable output)
|
||||
throws IOException {
|
||||
printer().printField(field, value, output);
|
||||
}
|
||||
|
||||
/** @deprecated Use {@code printer().printFieldToString(FieldDescriptor, Object)} */
|
||||
@Deprecated
|
||||
public static String printFieldToString(final FieldDescriptor field, final Object value) {
|
||||
return printer().printFieldToString(field, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a unicode textual representation of the value of given field value.
|
||||
*
|
||||
* <p>Same as {@code printFieldValue()}, except that non-ASCII characters in string type fields
|
||||
* are not escaped in backslash+octals.
|
||||
*
|
||||
* @deprecated Use {@code printer().escapingNonAscii(false).printFieldValue(FieldDescriptor,
|
||||
* Object, Appendable)}
|
||||
* @param field the descriptor of the field
|
||||
* @param value the value of the field
|
||||
* @param output the output to which to append the formatted value
|
||||
* @throws ClassCastException if the value is not appropriate for the given field descriptor
|
||||
* @throws IOException if there is an exception writing to the output
|
||||
*/
|
||||
@Deprecated
|
||||
public static void printUnicodeFieldValue(
|
||||
final FieldDescriptor field, final Object value, final Appendable output)
|
||||
throws IOException {
|
||||
printer().escapingNonAscii(false).printFieldValue(field, value, output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a textual representation of the value of given field value.
|
||||
*
|
||||
* @deprecated Use {@code printer().printFieldValue(FieldDescriptor, Object, Appendable)}
|
||||
* @param field the descriptor of the field
|
||||
* @param value the value of the field
|
||||
* @param output the output to which to append the formatted value
|
||||
* @throws ClassCastException if the value is not appropriate for the given field descriptor
|
||||
* @throws IOException if there is an exception writing to the output
|
||||
*/
|
||||
@Deprecated
|
||||
@InlineMe(
|
||||
replacement = "TextFormat.printer().printFieldValue(field, value, output)",
|
||||
imports = "com.google.protobuf.TextFormat")
|
||||
public static void printFieldValue(
|
||||
final FieldDescriptor field, final Object value, final Appendable output) throws IOException {
|
||||
printer().printFieldValue(field, value, output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a textual representation of the value of an unknown field.
|
||||
*
|
||||
|
@ -283,16 +107,23 @@ public final class TextFormat {
|
|||
public static final class Printer {
|
||||
|
||||
// Printer instance which escapes non-ASCII characters.
|
||||
private static final Printer DEFAULT = new Printer(true, TypeRegistry.getEmptyTypeRegistry());
|
||||
private static final Printer DEFAULT =
|
||||
new Printer(
|
||||
true, TypeRegistry.getEmptyTypeRegistry(), ExtensionRegistryLite.getEmptyRegistry());
|
||||
|
||||
/** Whether to escape non ASCII characters with backslash and octal. */
|
||||
private final boolean escapeNonAscii;
|
||||
|
||||
private final TypeRegistry typeRegistry;
|
||||
private final ExtensionRegistryLite extensionRegistry;
|
||||
|
||||
private Printer(boolean escapeNonAscii, TypeRegistry typeRegistry) {
|
||||
private Printer(
|
||||
boolean escapeNonAscii,
|
||||
TypeRegistry typeRegistry,
|
||||
ExtensionRegistryLite extensionRegistry) {
|
||||
this.escapeNonAscii = escapeNonAscii;
|
||||
this.typeRegistry = typeRegistry;
|
||||
this.extensionRegistry = extensionRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -305,7 +136,7 @@ public final class TextFormat {
|
|||
* with the escape mode set to the given parameter.
|
||||
*/
|
||||
public Printer escapingNonAscii(boolean escapeNonAscii) {
|
||||
return new Printer(escapeNonAscii, typeRegistry);
|
||||
return new Printer(escapeNonAscii, typeRegistry, extensionRegistry);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -318,7 +149,20 @@ public final class TextFormat {
|
|||
if (this.typeRegistry != TypeRegistry.getEmptyTypeRegistry()) {
|
||||
throw new IllegalArgumentException("Only one typeRegistry is allowed.");
|
||||
}
|
||||
return new Printer(escapeNonAscii, typeRegistry);
|
||||
return new Printer(escapeNonAscii, typeRegistry, extensionRegistry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Printer} using the given extensionRegistry. The new Printer clones all
|
||||
* other configurations from the current {@link Printer}.
|
||||
*
|
||||
* @throws IllegalArgumentException if a registry is already set.
|
||||
*/
|
||||
public Printer usingExtensionRegistry(ExtensionRegistryLite extensionRegistry) {
|
||||
if (this.extensionRegistry != ExtensionRegistryLite.getEmptyRegistry()) {
|
||||
throw new IllegalArgumentException("Only one extensionRegistry is allowed.");
|
||||
}
|
||||
return new Printer(escapeNonAscii, typeRegistry, extensionRegistry);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -377,7 +221,7 @@ public final class TextFormat {
|
|||
return false;
|
||||
}
|
||||
contentBuilder = DynamicMessage.getDefaultInstance(contentType).newBuilderForType();
|
||||
contentBuilder.mergeFrom((ByteString) value);
|
||||
contentBuilder.mergeFrom((ByteString) value, extensionRegistry);
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
// The value of Any is malformed. We cannot print it out nicely, so fallback to printing out
|
||||
// the type_url and value as bytes. Note that we fail open here to be consistent with
|
||||
|
|
|
@ -214,24 +214,24 @@ final class Utf8 {
|
|||
* @throws IllegalArgumentException if {@code sequence} contains ill-formed UTF-16 (unpaired
|
||||
* surrogates)
|
||||
*/
|
||||
static int encodedLength(CharSequence sequence) {
|
||||
static int encodedLength(String string) {
|
||||
// Warning to maintainers: this implementation is highly optimized.
|
||||
int utf16Length = sequence.length();
|
||||
int utf16Length = string.length();
|
||||
int utf8Length = utf16Length;
|
||||
int i = 0;
|
||||
|
||||
// This loop optimizes for pure ASCII.
|
||||
while (i < utf16Length && sequence.charAt(i) < 0x80) {
|
||||
while (i < utf16Length && string.charAt(i) < 0x80) {
|
||||
i++;
|
||||
}
|
||||
|
||||
// This loop optimizes for chars less than 0x800.
|
||||
for (; i < utf16Length; i++) {
|
||||
char c = sequence.charAt(i);
|
||||
char c = string.charAt(i);
|
||||
if (c < 0x800) {
|
||||
utf8Length += ((0x7f - c) >>> 31); // branch free!
|
||||
} else {
|
||||
utf8Length += encodedLengthGeneral(sequence, i);
|
||||
utf8Length += encodedLengthGeneral(string, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -244,11 +244,11 @@ final class Utf8 {
|
|||
return utf8Length;
|
||||
}
|
||||
|
||||
private static int encodedLengthGeneral(CharSequence sequence, int start) {
|
||||
int utf16Length = sequence.length();
|
||||
private static int encodedLengthGeneral(String string, int start) {
|
||||
int utf16Length = string.length();
|
||||
int utf8Length = 0;
|
||||
for (int i = start; i < utf16Length; i++) {
|
||||
char c = sequence.charAt(i);
|
||||
char c = string.charAt(i);
|
||||
if (c < 0x800) {
|
||||
utf8Length += (0x7f - c) >>> 31; // branch free!
|
||||
} else {
|
||||
|
@ -256,7 +256,7 @@ final class Utf8 {
|
|||
// jdk7+: if (Character.isSurrogate(c)) {
|
||||
if (Character.MIN_SURROGATE <= c && c <= Character.MAX_SURROGATE) {
|
||||
// Check that we have a well-formed surrogate pair.
|
||||
int cp = Character.codePointAt(sequence, i);
|
||||
int cp = Character.codePointAt(string, i);
|
||||
if (cp < MIN_SUPPLEMENTARY_CODE_POINT) {
|
||||
throw new UnpairedSurrogateException(i, utf16Length);
|
||||
}
|
||||
|
@ -267,7 +267,7 @@ final class Utf8 {
|
|||
return utf8Length;
|
||||
}
|
||||
|
||||
static int encode(CharSequence in, byte[] out, int offset, int length) {
|
||||
static int encode(String in, byte[] out, int offset, int length) {
|
||||
return processor.encodeUtf8(in, out, offset, length);
|
||||
}
|
||||
// End Guava UTF-8 methods.
|
||||
|
@ -326,9 +326,9 @@ final class Utf8 {
|
|||
*
|
||||
* @param in the source string to be encoded
|
||||
* @param out the target buffer to receive the encoded string.
|
||||
* @see Utf8#encode(CharSequence, byte[], int, int)
|
||||
* @see Utf8#encode(String, byte[], int, int)
|
||||
*/
|
||||
static void encodeUtf8(CharSequence in, ByteBuffer out) {
|
||||
static void encodeUtf8(String in, ByteBuffer out) {
|
||||
processor.encodeUtf8(in, out);
|
||||
}
|
||||
|
||||
|
@ -724,7 +724,7 @@ final class Utf8 {
|
|||
* {@code bytes.length - offset}
|
||||
* @return the new offset, equivalent to {@code offset + Utf8.encodedLength(sequence)}
|
||||
*/
|
||||
abstract int encodeUtf8(CharSequence in, byte[] out, int offset, int length);
|
||||
abstract int encodeUtf8(String in, byte[] out, int offset, int length);
|
||||
|
||||
/**
|
||||
* Encodes an input character sequence ({@code in}) to UTF-8 in the target buffer ({@code out}).
|
||||
|
@ -743,7 +743,7 @@ final class Utf8 {
|
|||
* @throws ArrayIndexOutOfBoundsException if {@code in} encoded in UTF-8 is longer than {@code
|
||||
* out.remaining()}
|
||||
*/
|
||||
final void encodeUtf8(CharSequence in, ByteBuffer out) {
|
||||
final void encodeUtf8(String in, ByteBuffer out) {
|
||||
if (out.hasArray()) {
|
||||
final int offset = out.arrayOffset();
|
||||
int endIndex = Utf8.encode(in, out.array(), offset + out.position(), out.remaining());
|
||||
|
@ -756,13 +756,13 @@ final class Utf8 {
|
|||
}
|
||||
|
||||
/** Encodes the input character sequence to a direct {@link ByteBuffer} instance. */
|
||||
abstract void encodeUtf8Direct(CharSequence in, ByteBuffer out);
|
||||
abstract void encodeUtf8Direct(String in, ByteBuffer out);
|
||||
|
||||
/**
|
||||
* Encodes the input character sequence to a {@link ByteBuffer} instance using the {@link
|
||||
* ByteBuffer} API, rather than potentially faster approaches.
|
||||
*/
|
||||
final void encodeUtf8Default(CharSequence in, ByteBuffer out) {
|
||||
final void encodeUtf8Default(String in, ByteBuffer out) {
|
||||
final int inLength = in.length();
|
||||
int outIx = out.position();
|
||||
int inIx = 0;
|
||||
|
@ -1013,7 +1013,7 @@ final class Utf8 {
|
|||
}
|
||||
|
||||
@Override
|
||||
int encodeUtf8(CharSequence in, byte[] out, int offset, int length) {
|
||||
int encodeUtf8(String in, byte[] out, int offset, int length) {
|
||||
int utf16Length = in.length();
|
||||
int j = offset;
|
||||
int i = 0;
|
||||
|
@ -1065,7 +1065,7 @@ final class Utf8 {
|
|||
}
|
||||
|
||||
@Override
|
||||
void encodeUtf8Direct(CharSequence in, ByteBuffer out) {
|
||||
void encodeUtf8Direct(String in, ByteBuffer out) {
|
||||
// For safe processing, we have to use the ByteBuffer API.
|
||||
encodeUtf8Default(in, out);
|
||||
}
|
||||
|
@ -1442,7 +1442,7 @@ final class Utf8 {
|
|||
}
|
||||
|
||||
@Override
|
||||
int encodeUtf8(final CharSequence in, final byte[] out, final int offset, final int length) {
|
||||
int encodeUtf8(final String in, final byte[] out, final int offset, final int length) {
|
||||
long outIx = offset;
|
||||
final long outLimit = outIx + length;
|
||||
final int inLimit = in.length();
|
||||
|
@ -1503,7 +1503,7 @@ final class Utf8 {
|
|||
}
|
||||
|
||||
@Override
|
||||
void encodeUtf8Direct(CharSequence in, ByteBuffer out) {
|
||||
void encodeUtf8Direct(String in, ByteBuffer out) {
|
||||
final long address = addressOffset(out);
|
||||
long outIx = address + out.position();
|
||||
final long outLimit = address + out.limit();
|
||||
|
|
|
@ -327,6 +327,81 @@ public class CodedOutputStreamTest {
|
|||
.isEqualTo(-75123905439571256L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void computeIntSize() {
|
||||
assertThat(CodedOutputStream.computeUInt32SizeNoTag(0)).isEqualTo(1);
|
||||
assertThat(CodedOutputStream.computeUInt64SizeNoTag(0)).isEqualTo(1);
|
||||
int i;
|
||||
for (i = 0; i < 7; i++) {
|
||||
assertThat(CodedOutputStream.computeInt32SizeNoTag(1 << i)).isEqualTo(1);
|
||||
assertThat(CodedOutputStream.computeUInt32SizeNoTag(1 << i)).isEqualTo(1);
|
||||
assertThat(CodedOutputStream.computeUInt64SizeNoTag(1L << i)).isEqualTo(1);
|
||||
}
|
||||
for (; i < 14; i++) {
|
||||
assertThat(CodedOutputStream.computeInt32SizeNoTag(1 << i)).isEqualTo(2);
|
||||
assertThat(CodedOutputStream.computeUInt32SizeNoTag(1 << i)).isEqualTo(2);
|
||||
assertThat(CodedOutputStream.computeUInt64SizeNoTag(1L << i)).isEqualTo(2);
|
||||
}
|
||||
for (; i < 21; i++) {
|
||||
assertThat(CodedOutputStream.computeInt32SizeNoTag(1 << i)).isEqualTo(3);
|
||||
assertThat(CodedOutputStream.computeUInt32SizeNoTag(1 << i)).isEqualTo(3);
|
||||
assertThat(CodedOutputStream.computeUInt64SizeNoTag(1L << i)).isEqualTo(3);
|
||||
}
|
||||
for (; i < 28; i++) {
|
||||
assertThat(CodedOutputStream.computeInt32SizeNoTag(1 << i)).isEqualTo(4);
|
||||
assertThat(CodedOutputStream.computeUInt32SizeNoTag(1 << i)).isEqualTo(4);
|
||||
assertThat(CodedOutputStream.computeUInt64SizeNoTag(1L << i)).isEqualTo(4);
|
||||
}
|
||||
for (; i < 31; i++) {
|
||||
assertThat(CodedOutputStream.computeInt32SizeNoTag(1 << i)).isEqualTo(5);
|
||||
assertThat(CodedOutputStream.computeUInt32SizeNoTag(1 << i)).isEqualTo(5);
|
||||
assertThat(CodedOutputStream.computeUInt64SizeNoTag(1L << i)).isEqualTo(5);
|
||||
}
|
||||
for (; i < 32; i++) {
|
||||
assertThat(CodedOutputStream.computeInt32SizeNoTag(1 << i)).isEqualTo(10);
|
||||
assertThat(CodedOutputStream.computeUInt32SizeNoTag(1 << i)).isEqualTo(5);
|
||||
assertThat(CodedOutputStream.computeUInt64SizeNoTag(1L << i)).isEqualTo(5);
|
||||
}
|
||||
for (; i < 35; i++) {
|
||||
assertThat(CodedOutputStream.computeUInt64SizeNoTag(1L << i)).isEqualTo(5);
|
||||
}
|
||||
for (; i < 42; i++) {
|
||||
assertThat(CodedOutputStream.computeUInt64SizeNoTag(1L << i)).isEqualTo(6);
|
||||
}
|
||||
for (; i < 49; i++) {
|
||||
assertThat(CodedOutputStream.computeUInt64SizeNoTag(1L << i)).isEqualTo(7);
|
||||
}
|
||||
for (; i < 56; i++) {
|
||||
assertThat(CodedOutputStream.computeUInt64SizeNoTag(1L << i)).isEqualTo(8);
|
||||
}
|
||||
for (; i < 63; i++) {
|
||||
assertThat(CodedOutputStream.computeUInt64SizeNoTag(1L << i)).isEqualTo(9);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void computeTagSize() {
|
||||
assertThat(CodedOutputStream.computeTagSize(0)).isEqualTo(1);
|
||||
int i;
|
||||
for (i = 0; i < 4; i++) {
|
||||
assertThat(CodedOutputStream.computeTagSize(1 << i)).isEqualTo(1);
|
||||
}
|
||||
for (; i < 11; i++) {
|
||||
assertThat(CodedOutputStream.computeTagSize(1 << i)).isEqualTo(2);
|
||||
}
|
||||
for (; i < 18; i++) {
|
||||
assertThat(CodedOutputStream.computeTagSize(1 << i)).isEqualTo(3);
|
||||
}
|
||||
for (; i < 25; i++) {
|
||||
assertThat(CodedOutputStream.computeTagSize(1 << i)).isEqualTo(4);
|
||||
}
|
||||
for (; i < 29; i++) {
|
||||
assertThat(CodedOutputStream.computeTagSize(1 << i)).isEqualTo(5);
|
||||
}
|
||||
// Invalid tags
|
||||
assertThat(CodedOutputStream.computeTagSize((1 << 30) + 1)).isEqualTo(1);
|
||||
}
|
||||
|
||||
/** Tests writing a whole message with every field type. */
|
||||
@Test
|
||||
public void testWriteWholeMessage() throws Exception {
|
||||
|
|
|
@ -24,12 +24,26 @@ public final class RuntimeVersionTest {
|
|||
RuntimeVersion.ProtobufRuntimeVersionException.class,
|
||||
() ->
|
||||
RuntimeVersion.validateProtobufGencodeVersion(
|
||||
RuntimeVersion.DOMAIN,
|
||||
-1,
|
||||
RuntimeVersion.MINOR,
|
||||
RuntimeVersion.PATCH,
|
||||
RuntimeVersion.SUFFIX));
|
||||
assertThat(thrown).hasMessageThat().contains("Invalid gencode version: -1");
|
||||
RuntimeVersion.DOMAIN, 1, -2, -3, ""));
|
||||
assertThat(thrown).hasMessageThat().contains("Invalid gencode version: 1.-2.-3");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void versionValidation_crossDomainDisallowed() {
|
||||
|
||||
RuntimeVersion.RuntimeDomain gencodeDomain = RuntimeVersion.RuntimeDomain.GOOGLE_INTERNAL;
|
||||
RuntimeVersion.ProtobufRuntimeVersionException thrown =
|
||||
assertThrows(
|
||||
RuntimeVersion.ProtobufRuntimeVersionException.class,
|
||||
() -> RuntimeVersion.validateProtobufGencodeDomain(gencodeDomain));
|
||||
assertThat(thrown).hasMessageThat().contains("Mismatched Protobuf Gencode/Runtime domains");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void versionValidation_sameDomainAllowed() {
|
||||
|
||||
RuntimeVersion.RuntimeDomain gencodeDomain = RuntimeVersion.RuntimeDomain.PUBLIC;
|
||||
RuntimeVersion.validateProtobufGencodeDomain(gencodeDomain);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -11,6 +11,7 @@ import static com.google.common.truth.Truth.assertThat;
|
|||
import static com.google.common.truth.Truth.assertWithMessage;
|
||||
import static com.google.protobuf.TestUtil.TEST_REQUIRED_INITIALIZED;
|
||||
import static com.google.protobuf.TestUtil.TEST_REQUIRED_UNINITIALIZED;
|
||||
import static protobuf_unittest.UnittestProto.optionalInt32Extension;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
|
||||
import com.google.protobuf.DescriptorProtos.DescriptorProto;
|
||||
|
@ -623,6 +624,83 @@ public class TextFormatTest {
|
|||
assertThat(actual).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrintAny_anyWithDynamicMessageContainingExtensionTreatedAsUnknown()
|
||||
throws Exception {
|
||||
Descriptor descriptor =
|
||||
createDescriptorForAny(
|
||||
FieldDescriptorProto.newBuilder()
|
||||
.setName("type_url")
|
||||
.setNumber(1)
|
||||
.setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL)
|
||||
.setType(FieldDescriptorProto.Type.TYPE_STRING)
|
||||
.build(),
|
||||
FieldDescriptorProto.newBuilder()
|
||||
.setName("value")
|
||||
.setNumber(2)
|
||||
.setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL)
|
||||
.setType(FieldDescriptorProto.Type.TYPE_BYTES)
|
||||
.build());
|
||||
DynamicMessage testAny =
|
||||
DynamicMessage.newBuilder(descriptor)
|
||||
.setField(
|
||||
descriptor.findFieldByNumber(1),
|
||||
"type.googleapis.com/" + TestAllExtensions.getDescriptor().getFullName())
|
||||
.setField(
|
||||
descriptor.findFieldByNumber(2),
|
||||
TestAllExtensions.newBuilder()
|
||||
.setExtension(optionalInt32Extension, 12345)
|
||||
.build()
|
||||
.toByteString())
|
||||
.build();
|
||||
String actual =
|
||||
TextFormat.printer()
|
||||
.usingTypeRegistry(TypeRegistry.newBuilder().add(TestAllTypes.getDescriptor()).build())
|
||||
.printToString(testAny);
|
||||
String expected = "[type.googleapis.com/protobuf_unittest.TestAllExtensions] {\n 1: 12345\n}\n";
|
||||
assertThat(actual).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrintAny_anyWithDynamicMessageContainingExtensionWithRegistry() throws Exception {
|
||||
Descriptor descriptor =
|
||||
createDescriptorForAny(
|
||||
FieldDescriptorProto.newBuilder()
|
||||
.setName("type_url")
|
||||
.setNumber(1)
|
||||
.setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL)
|
||||
.setType(FieldDescriptorProto.Type.TYPE_STRING)
|
||||
.build(),
|
||||
FieldDescriptorProto.newBuilder()
|
||||
.setName("value")
|
||||
.setNumber(2)
|
||||
.setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL)
|
||||
.setType(FieldDescriptorProto.Type.TYPE_BYTES)
|
||||
.build());
|
||||
DynamicMessage testAny =
|
||||
DynamicMessage.newBuilder(descriptor)
|
||||
.setField(
|
||||
descriptor.findFieldByNumber(1),
|
||||
"type.googleapis.com/" + TestAllExtensions.getDescriptor().getFullName())
|
||||
.setField(
|
||||
descriptor.findFieldByNumber(2),
|
||||
TestAllExtensions.newBuilder()
|
||||
.setExtension(optionalInt32Extension, 12345)
|
||||
.build()
|
||||
.toByteString())
|
||||
.build();
|
||||
String actual =
|
||||
TextFormat.printer()
|
||||
.usingTypeRegistry(TypeRegistry.newBuilder().add(TestAllTypes.getDescriptor()).build())
|
||||
.usingExtensionRegistry(TestUtil.getFullExtensionRegistry())
|
||||
.printToString(testAny);
|
||||
String expected =
|
||||
"[type.googleapis.com/protobuf_unittest.TestAllExtensions] {\n"
|
||||
+ " [protobuf_unittest.optional_int32_extension]: 12345\n"
|
||||
+ "}\n";
|
||||
assertThat(actual).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrintAny_anyFromWithNoValueField() throws Exception {
|
||||
Descriptor descriptor =
|
||||
|
|
|
@ -194,7 +194,7 @@ public class Utf8Test {
|
|||
|
||||
private static byte[] encodeToByteArray(String message, int length, Utf8.Processor processor) {
|
||||
byte[] output = new byte[length];
|
||||
processor.encodeUtf8(message, output, 0, output.length);
|
||||
int unused = processor.encodeUtf8(message, output, 0, output.length);
|
||||
return output;
|
||||
}
|
||||
|
||||
|
|
|
@ -426,13 +426,13 @@ public final class Durations {
|
|||
* Add two durations.
|
||||
*
|
||||
* <!-- MOE:begin_intracomment_strip -->
|
||||
* <p>Do not use this method for new code. Instead, convert to {@link java.time.Duration} using
|
||||
* {@link com.google.protobuf.util.JavaTimeConversions#toJavaDuration}, do the arithmetic there,
|
||||
* and convert back using {@link com.google.protobuf.util.JavaTimeConversions#toProtoDuration}.
|
||||
*
|
||||
* <p>This method will be deprecated once most uses have been eliminated.
|
||||
* @deprecated Do not use this method for new code. Instead, convert to {@link java.time.Duration}
|
||||
* using {@link com.google.protobuf.util.JavaTimeConversions#toJavaDuration}, do the
|
||||
* arithmetic there, and convert back using {@link
|
||||
* com.google.protobuf.util.JavaTimeConversions#toProtoDuration}.
|
||||
* <!-- MOE:end_intracomment_strip -->
|
||||
*/
|
||||
@Deprecated // MOE:strip_line
|
||||
public static Duration add(Duration d1, Duration d2) {
|
||||
checkValid(d1);
|
||||
checkValid(d2);
|
||||
|
@ -444,13 +444,13 @@ public final class Durations {
|
|||
* Subtract a duration from another.
|
||||
*
|
||||
* <!-- MOE:begin_intracomment_strip -->
|
||||
* <p>Do not use this method for new code. Instead, convert to {@link java.time.Duration} using
|
||||
* {@link com.google.protobuf.util.JavaTimeConversions#toJavaDuration}, do the arithmetic there,
|
||||
* and convert back using {@link com.google.protobuf.util.JavaTimeConversions#toProtoDuration}.
|
||||
*
|
||||
* <p>This method will be deprecated once most uses have been eliminated.
|
||||
* @deprecated Do not use this method for new code. Instead, convert to {@link java.time.Duration}
|
||||
* using {@link com.google.protobuf.util.JavaTimeConversions#toJavaDuration}, do the
|
||||
* arithmetic there, and convert back using {@link
|
||||
* com.google.protobuf.util.JavaTimeConversions#toProtoDuration}.
|
||||
* <!-- MOE:end_intracomment_strip -->
|
||||
*/
|
||||
@Deprecated // MOE:strip_line
|
||||
public static Duration subtract(Duration d1, Duration d2) {
|
||||
checkValid(d1);
|
||||
checkValid(d2);
|
||||
|
|
|
@ -431,13 +431,13 @@ public final class Timestamps {
|
|||
* Calculate the difference between two timestamps.
|
||||
*
|
||||
* <!-- MOE:begin_intracomment_strip -->
|
||||
* <p>Do not use this method for new code. Instead, convert to {@link java.time.Instant} using
|
||||
* {@link com.google.protobuf.util.JavaTimeConversions#toJavaInstant}, do the arithmetic there,
|
||||
* and convert back using {@link com.google.protobuf.util.JavaTimeConversions#toProtoDuration}.
|
||||
*
|
||||
* <p>This method will be deprecated once most uses have been eliminated.
|
||||
* @deprecated Do not use this method for new code. Instead, convert to {@link java.time.Instant}
|
||||
* using {@link com.google.protobuf.util.JavaTimeConversions#toJavaInstant}, do the arithmetic
|
||||
* there, and convert back using {@link
|
||||
* com.google.protobuf.util.JavaTimeConversions#toProtoDuration}.
|
||||
* <!-- MOE:end_intracomment_strip -->
|
||||
*/
|
||||
@Deprecated // MOE:strip_line
|
||||
public static Duration between(Timestamp from, Timestamp to) {
|
||||
checkValid(from);
|
||||
checkValid(to);
|
||||
|
@ -450,15 +450,14 @@ public final class Timestamps {
|
|||
* Add a duration to a timestamp.
|
||||
*
|
||||
* <!-- MOE:begin_intracomment_strip -->
|
||||
* <p>Do not use this method for new code. Instead, convert to {@link java.time.Instant} and
|
||||
* {@link java.time.Duration} using {@link
|
||||
* com.google.protobuf.util.JavaTimeConversions#toJavaInstant} and {@link
|
||||
* com.google.protobuf.util.JavaTimeConversions#toJavaDuration}, do the arithmetic there, and
|
||||
* convert back using {@link com.google.protobuf.util.JavaTimeConversions#toProtoTimestamp}.
|
||||
*
|
||||
* <p>This method will be deprecated once most uses have been eliminated.
|
||||
* @deprecated Do not use this method for new code. Instead, convert to {@link java.time.Instant}
|
||||
* and {@link java.time.Duration} using {@link
|
||||
* com.google.protobuf.util.JavaTimeConversions#toJavaInstant} and {@link
|
||||
* com.google.protobuf.util.JavaTimeConversions#toJavaDuration}, do the arithmetic there, and
|
||||
* convert back using {@link com.google.protobuf.util.JavaTimeConversions#toProtoTimestamp}.
|
||||
* <!-- MOE:end_intracomment_strip -->
|
||||
*/
|
||||
@Deprecated // MOE:strip_line
|
||||
public static Timestamp add(Timestamp start, Duration length) {
|
||||
checkValid(start);
|
||||
Durations.checkValid(length);
|
||||
|
@ -471,15 +470,14 @@ public final class Timestamps {
|
|||
* Subtract a duration from a timestamp.
|
||||
*
|
||||
* <!-- MOE:begin_intracomment_strip -->
|
||||
* <p>Do not use this method for new code. Instead, convert to {@link java.time.Instant} and
|
||||
* {@link java.time.Duration} using {@link
|
||||
* com.google.protobuf.util.JavaTimeConversions#toJavaInstant} and {@link
|
||||
* com.google.protobuf.util.JavaTimeConversions#toJavaDuration}, do the arithmetic there, and
|
||||
* convert back using {@link com.google.protobuf.util.JavaTimeConversions#toProtoTimestamp}.
|
||||
*
|
||||
* <p>This method will be deprecated once most uses have been eliminated.
|
||||
* @deprecated Do not use this method for new code. Instead, convert to {@link java.time.Instant}
|
||||
* and {@link java.time.Duration} using {@link
|
||||
* com.google.protobuf.util.JavaTimeConversions#toJavaInstant} and {@link
|
||||
* com.google.protobuf.util.JavaTimeConversions#toJavaDuration}, do the arithmetic there, and
|
||||
* convert back using {@link com.google.protobuf.util.JavaTimeConversions#toProtoTimestamp}.
|
||||
* <!-- MOE:end_intracomment_strip -->
|
||||
*/
|
||||
@Deprecated // MOE:strip_line
|
||||
public static Timestamp subtract(Timestamp start, Duration length) {
|
||||
checkValid(start);
|
||||
Durations.checkValid(length);
|
||||
|
|
|
@ -160,6 +160,7 @@ objc_library(
|
|||
conformance_test(
|
||||
name = "conformance_test",
|
||||
failure_list = "//conformance:failure_list_objc.txt",
|
||||
maximum_edition = "2023",
|
||||
target_compatible_with = ["@platforms//os:macos"],
|
||||
testee = "//conformance:conformance_objc",
|
||||
)
|
||||
|
|
|
@ -168,6 +168,9 @@ GPB_FINAL @interface GPBAny : GPBMessage
|
|||
/** Must be a valid serialized protocol buffer of the above specified type. */
|
||||
@property(nonatomic, readwrite, copy, null_resettable) NSData *value;
|
||||
|
||||
// NOTE: There are some Objective-C specific methods/properties in
|
||||
// GPBWellKnownTypes.h that will likey be useful.
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
// source: google/protobuf/any.proto
|
||||
|
||||
#import "GPBProtocolBuffers_RuntimeSupport.h"
|
||||
#import "GPBWellKnownTypes.h"
|
||||
#import "GPBAny.pbobjc.h"
|
||||
|
||||
#if GOOGLE_PROTOBUF_OBJC_VERSION < 30007
|
||||
|
@ -39,6 +40,13 @@ static GPBFileDescription GPBAnyRoot_FileDescription = {
|
|||
.syntax = GPBFileSyntaxProto3
|
||||
};
|
||||
|
||||
// This is to help make sure that the GPBWellKnownTypes.* categories get linked and
|
||||
// developers do not have to use the `-ObjC` linker flag. More information
|
||||
// here: https://medium.com/ios-os-x-development/categories-in-static-libraries-78e41f8ddb96
|
||||
__attribute__((used)) static NSString* any_importCategories () {
|
||||
return GPBWellKnownTypesErrorDomain;
|
||||
}
|
||||
|
||||
#pragma mark - GPBAny
|
||||
|
||||
@implementation GPBAny
|
||||
|
|
|
@ -123,6 +123,9 @@ GPB_FINAL @interface GPBDuration : GPBMessage
|
|||
**/
|
||||
@property(nonatomic, readwrite) int32_t nanos;
|
||||
|
||||
// NOTE: There are some Objective-C specific methods/properties in
|
||||
// GPBWellKnownTypes.h that will likey be useful.
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
// source: google/protobuf/duration.proto
|
||||
|
||||
#import "GPBProtocolBuffers_RuntimeSupport.h"
|
||||
#import "GPBWellKnownTypes.h"
|
||||
#import "GPBDuration.pbobjc.h"
|
||||
|
||||
#if GOOGLE_PROTOBUF_OBJC_VERSION < 30007
|
||||
|
@ -39,6 +40,13 @@ static GPBFileDescription GPBDurationRoot_FileDescription = {
|
|||
.syntax = GPBFileSyntaxProto3
|
||||
};
|
||||
|
||||
// This is to help make sure that the GPBWellKnownTypes.* categories get linked and
|
||||
// developers do not have to use the `-ObjC` linker flag. More information
|
||||
// here: https://medium.com/ios-os-x-development/categories-in-static-libraries-78e41f8ddb96
|
||||
__attribute__((used)) static NSString* duration_importCategories () {
|
||||
return GPBWellKnownTypesErrorDomain;
|
||||
}
|
||||
|
||||
#pragma mark - GPBDuration
|
||||
|
||||
@implementation GPBDuration
|
||||
|
|
|
@ -152,6 +152,9 @@ GPB_FINAL @interface GPBTimestamp : GPBMessage
|
|||
**/
|
||||
@property(nonatomic, readwrite) int32_t nanos;
|
||||
|
||||
// NOTE: There are some Objective-C specific methods/properties in
|
||||
// GPBWellKnownTypes.h that will likey be useful.
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
// source: google/protobuf/timestamp.proto
|
||||
|
||||
#import "GPBProtocolBuffers_RuntimeSupport.h"
|
||||
#import "GPBWellKnownTypes.h"
|
||||
#import "GPBTimestamp.pbobjc.h"
|
||||
|
||||
#if GOOGLE_PROTOBUF_OBJC_VERSION < 30007
|
||||
|
@ -39,6 +40,13 @@ static GPBFileDescription GPBTimestampRoot_FileDescription = {
|
|||
.syntax = GPBFileSyntaxProto3
|
||||
};
|
||||
|
||||
// This is to help make sure that the GPBWellKnownTypes.* categories get linked and
|
||||
// developers do not have to use the `-ObjC` linker flag. More information
|
||||
// here: https://medium.com/ios-os-x-development/categories-in-static-libraries-78e41f8ddb96
|
||||
__attribute__((used)) static NSString* timestamp_importCategories () {
|
||||
return GPBWellKnownTypesErrorDomain;
|
||||
}
|
||||
|
||||
#pragma mark - GPBTimestamp
|
||||
|
||||
@implementation GPBTimestamp
|
||||
|
|
|
@ -201,6 +201,24 @@ typedef NS_ENUM(NSInteger, GPBWellKnownTypesErrorCode) {
|
|||
*/
|
||||
- (nullable GPBMessage *)unpackMessageClass:(Class)messageClass error:(NSError **)errorPtr;
|
||||
|
||||
/**
|
||||
* Unpacks the serialized message as if it was an instance of the given class.
|
||||
*
|
||||
* @note When checking type_url, the base URL is not checked, only the fully
|
||||
* qualified name.
|
||||
*
|
||||
* @param messageClass The class to use to deserialize the contained message.
|
||||
* @param extensionRegistry The extension registry to use to look up extensions.
|
||||
* @param errorPtr Pointer to an error that will be populated if something
|
||||
* goes wrong.
|
||||
*
|
||||
* @return An instance of the given class populated with the contained data, or
|
||||
* nil on failure.
|
||||
*/
|
||||
- (nullable GPBMessage *)unpackMessageClass:(Class)messageClass
|
||||
extensionRegistry:(nullable id<GPBExtensionRegistry>)extensionRegistry
|
||||
error:(NSError **)errorPtr;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -195,6 +195,12 @@ static NSString *ParseTypeFromURL(NSString *typeURLString) {
|
|||
}
|
||||
|
||||
- (GPBMessage *)unpackMessageClass:(Class)messageClass error:(NSError **)errorPtr {
|
||||
return [self unpackMessageClass:messageClass extensionRegistry:nil error:errorPtr];
|
||||
}
|
||||
|
||||
- (nullable GPBMessage *)unpackMessageClass:(Class)messageClass
|
||||
extensionRegistry:(nullable id<GPBExtensionRegistry>)extensionRegistry
|
||||
error:(NSError **)errorPtr {
|
||||
NSString *fullName = [messageClass descriptor].fullName;
|
||||
if (fullName.length == 0) {
|
||||
if (errorPtr) {
|
||||
|
@ -215,10 +221,7 @@ static NSString *ParseTypeFromURL(NSString *typeURLString) {
|
|||
return nil;
|
||||
}
|
||||
|
||||
// Any is proto3, which means no extensions, so this assumes anything put
|
||||
// within an any also won't need extensions. A second helper could be added
|
||||
// if needed.
|
||||
return [messageClass parseFromData:self.value error:errorPtr];
|
||||
return [messageClass parseFromData:self.value extensionRegistry:extensionRegistry error:errorPtr];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -4,7 +4,7 @@ if test "$PHP_PROTOBUF" != "no"; then
|
|||
|
||||
PHP_NEW_EXTENSION(
|
||||
protobuf,
|
||||
arena.c array.c convert.c def.c map.c message.c names.c php-upb.c protobuf.c third_party/utf8_range/naive.c third_party/utf8_range/range2-neon.c third_party/utf8_range/range2-sse.c,
|
||||
arena.c array.c convert.c def.c map.c message.c names.c php-upb.c protobuf.c third_party/utf8_range/utf8_range.c,
|
||||
$ext_shared, , -std=gnu99 -I@ext_srcdir@/third_party/utf8_range)
|
||||
PHP_ADD_BUILD_DIR($ext_builddir/third_party/utf8_range)
|
||||
|
||||
|
|
|
@ -400,11 +400,8 @@ static zval* Message_get_property_ptr_ptr(zend_object* object,
|
|||
static zend_object* Message_clone_obj(zend_object* object) {
|
||||
Message* intern = (Message*)object;
|
||||
const upb_MiniTable* t = upb_MessageDef_MiniTable(intern->desc->msgdef);
|
||||
upb_Message* clone = upb_Message_New(t, Arena_Get(&intern->arena));
|
||||
|
||||
// TODO: copy unknown fields?
|
||||
// TODO: use official upb msg copy function
|
||||
memcpy(clone, intern->msg, t->size);
|
||||
upb_Message* clone =
|
||||
upb_Message_ShallowClone(intern->msg, t, Arena_Get(&intern->arena));
|
||||
zval ret;
|
||||
Message_GetPhpWrapper(&ret, intern->desc, clone, &intern->arena);
|
||||
return Z_OBJ_P(&ret);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -220,6 +220,7 @@ cc_dist_library(
|
|||
"//src/google/protobuf:lite_test_util",
|
||||
"//src/google/protobuf:test_util",
|
||||
"//src/google/protobuf:test_util2",
|
||||
"//src/google/protobuf:unredacted_debug_format_for_test",
|
||||
"//src/google/protobuf/compiler:annotation_test_util",
|
||||
"//src/google/protobuf/compiler/cpp:unittest_lib",
|
||||
"//src/google/protobuf/io:test_zero_copy_stream",
|
||||
|
|
14
protobuf.bzl
14
protobuf.bzl
|
@ -80,6 +80,7 @@ def _proto_gen_impl(ctx):
|
|||
srcs = ctx.files.srcs
|
||||
langs = ctx.attr.langs or []
|
||||
out_type = ctx.attr.out_type
|
||||
enable_editions = ctx.attr.enable_editions
|
||||
deps = depset(direct = ctx.files.srcs)
|
||||
source_dir = _SourceDir(ctx)
|
||||
gen_dir = _GenDir(ctx).rstrip("/")
|
||||
|
@ -130,6 +131,8 @@ def _proto_gen_impl(ctx):
|
|||
generated_files = []
|
||||
for src in srcs:
|
||||
args = []
|
||||
if enable_editions:
|
||||
args.append("--experimental_editions")
|
||||
|
||||
in_gen_dir = src.root.path == gen_dir
|
||||
if in_gen_dir:
|
||||
|
@ -247,6 +250,7 @@ _proto_gen = rule(
|
|||
attrs = {
|
||||
"srcs": attr.label_list(allow_files = True),
|
||||
"deps": attr.label_list(providers = [ProtoGenInfo]),
|
||||
"enable_editions": attr.bool(),
|
||||
"includes": attr.string_list(),
|
||||
"protoc": attr.label(
|
||||
cfg = "exec",
|
||||
|
@ -406,11 +410,11 @@ def internal_objc_proto_library(
|
|||
includes = ["."],
|
||||
default_runtime = Label("//:protobuf_objc"),
|
||||
protoc = Label("//:protoc"),
|
||||
enable_editions = False,
|
||||
testonly = None,
|
||||
visibility = ["//visibility:public"],
|
||||
**kwargs):
|
||||
"""Bazel rule to create a Objective-C protobuf library from proto source
|
||||
files
|
||||
"""Bazel rule to create a Objective-C protobuf library from proto sources
|
||||
|
||||
NOTE: the rule is only an internal workaround to generate protos. The
|
||||
interface may change and the rule may be removed when bazel has introduced
|
||||
|
@ -423,9 +427,10 @@ def internal_objc_proto_library(
|
|||
outs: a list of expected output files.
|
||||
proto_deps: a list of proto file dependencies that don't have a
|
||||
objc_proto_library rule.
|
||||
include: a string indicating the include path of the .proto files.
|
||||
includes: a string indicating the include path of the .proto files.
|
||||
default_runtime: the Objective-C Protobuf runtime
|
||||
protoc: the label of the protocol compiler to generate the sources.
|
||||
enable_editions: if editions should be enabled while invoking the compiler.
|
||||
testonly: common rule attribute (see:
|
||||
https://bazel.build/reference/be/common-definitions#common-attributes)
|
||||
visibility: the visibility of the generated files.
|
||||
|
@ -440,6 +445,7 @@ def internal_objc_proto_library(
|
|||
testonly = testonly,
|
||||
srcs = proto_deps,
|
||||
protoc = protoc,
|
||||
enable_editions = enable_editions,
|
||||
includes = includes,
|
||||
)
|
||||
full_deps.append(":%s_deps_genproto" % name)
|
||||
|
@ -454,6 +460,7 @@ def internal_objc_proto_library(
|
|||
out_type = "hdrs",
|
||||
includes = includes,
|
||||
protoc = protoc,
|
||||
enable_editions = enable_editions,
|
||||
testonly = testonly,
|
||||
visibility = visibility,
|
||||
tags = ["manual"],
|
||||
|
@ -467,6 +474,7 @@ def internal_objc_proto_library(
|
|||
out_type = "srcs",
|
||||
includes = includes,
|
||||
protoc = protoc,
|
||||
enable_editions = enable_editions,
|
||||
testonly = testonly,
|
||||
visibility = visibility,
|
||||
tags = ["manual"],
|
||||
|
|
|
@ -72,8 +72,8 @@ def protobuf_deps():
|
|||
_github_archive(
|
||||
name = "rules_cc",
|
||||
repo = "https://github.com/bazelbuild/rules_cc",
|
||||
commit = "818289e5613731ae410efb54218a4077fb9dbb03",
|
||||
sha256 = "0adbd6f567291ad526e82c765e15aed33cea5e256eeba129f1501142c2c56610",
|
||||
commit = "c8c38f8c710cbbf834283e4777916b68261b359c", # 0.0.9
|
||||
sha256 = "5f862a44bbd032e1b48ed53c9c211ba2a1da60e10c5baa01c97369c249299ecb",
|
||||
)
|
||||
|
||||
if not native.existing_rule("rules_java"):
|
||||
|
@ -122,8 +122,8 @@ def protobuf_deps():
|
|||
if not native.existing_rule("build_bazel_rules_apple"):
|
||||
http_archive(
|
||||
name = "build_bazel_rules_apple",
|
||||
sha256 = "f94e6dddf74739ef5cb30f000e13a2a613f6ebfa5e63588305a71fce8a8a9911",
|
||||
url = "https://github.com/bazelbuild/rules_apple/releases/download/1.1.3/rules_apple.1.1.3.tar.gz",
|
||||
sha256 = "34c41bfb59cdaea29ac2df5a2fa79e5add609c71bb303b2ebb10985f93fa20e7",
|
||||
url = "https://github.com/bazelbuild/rules_apple/releases/download/3.1.1/rules_apple.3.1.1.tar.gz",
|
||||
)
|
||||
|
||||
if not native.existing_rule("io_bazel_rules_kotlin"):
|
||||
|
|
|
@ -115,7 +115,7 @@ bool HasExtensionOrUnknown(const upb_Message* msg,
|
|||
const upb_MiniTableExtension* eid) {
|
||||
MessageLock msg_lock(msg);
|
||||
return _upb_Message_Getext(msg, eid) != nullptr ||
|
||||
upb_MiniTable_FindUnknown(msg, upb_MiniTableExtension_Number(eid), 0)
|
||||
upb_Message_FindUnknown(msg, upb_MiniTableExtension_Number(eid), 0)
|
||||
.status == kUpb_FindUnknown_Ok;
|
||||
}
|
||||
|
||||
|
|
|
@ -121,7 +121,6 @@ def build_targets(name):
|
|||
deps = [
|
||||
":proto_api",
|
||||
"//:protobuf",
|
||||
"//src/google/protobuf:descriptor_legacy",
|
||||
] + select({
|
||||
"//conditions:default": [],
|
||||
":use_fast_cpp_protos": ["//external:python_headers"],
|
||||
|
|
|
@ -241,7 +241,7 @@ bool PyUpb_PyToUpb(PyObject* obj, const upb_FieldDef* f, upb_MessageValue* val,
|
|||
// Use the object's bytes if they are valid UTF-8.
|
||||
char* ptr;
|
||||
if (PyBytes_AsStringAndSize(obj, &ptr, &size) < 0) return false;
|
||||
if (utf8_range2((const unsigned char*)ptr, size) != 0) {
|
||||
if (!utf8_range_IsValid(ptr, size)) {
|
||||
// Invalid UTF-8. Try to convert the message to a Python Unicode
|
||||
// object, even though we know this will fail, just to get the
|
||||
// idiomatic Python error message.
|
||||
|
|
|
@ -648,18 +648,6 @@ static PyObject* PyUpb_Descriptor_GetOneofsByName(PyObject* _self,
|
|||
return PyUpb_ByNameMap_New(&funcs, self->def, self->pool);
|
||||
}
|
||||
|
||||
static PyObject* PyUpb_Descriptor_GetSyntax(PyObject* self, void* closure) {
|
||||
PyErr_WarnEx(NULL,
|
||||
"descriptor.syntax is deprecated. It will be removed soon. "
|
||||
"Most usages are checking field descriptors. Consider to use "
|
||||
"has_presence, is_packed on field descriptors.",
|
||||
1);
|
||||
const upb_MessageDef* msgdef = PyUpb_Descriptor_GetDef(self);
|
||||
const char* syntax =
|
||||
upb_MessageDef_Syntax(msgdef) == kUpb_Syntax_Proto2 ? "proto2" : "proto3";
|
||||
return PyUnicode_InternFromString(syntax);
|
||||
}
|
||||
|
||||
static PyGetSetDef PyUpb_Descriptor_Getters[] = {
|
||||
{"name", PyUpb_Descriptor_GetName, NULL, "Last name"},
|
||||
{"full_name", PyUpb_Descriptor_GetFullName, NULL, "Full name"},
|
||||
|
@ -694,13 +682,6 @@ static PyGetSetDef PyUpb_Descriptor_Getters[] = {
|
|||
"Containing type"},
|
||||
{"is_extendable", PyUpb_Descriptor_GetIsExtendable, NULL},
|
||||
{"has_options", PyUpb_Descriptor_GetHasOptions, NULL, "Has Options"},
|
||||
// begin:github_only
|
||||
{"syntax", &PyUpb_Descriptor_GetSyntax, NULL, "Syntax"},
|
||||
// end:github_only
|
||||
// begin:google_only
|
||||
// // TODO Use this to open-source syntax deprecation.
|
||||
// {"deprecated_syntax", &PyUpb_Descriptor_GetSyntax, NULL, "Syntax"},
|
||||
// end:google_only
|
||||
{NULL}};
|
||||
|
||||
static PyMethodDef PyUpb_Descriptor_Methods[] = {
|
||||
|
@ -1248,26 +1229,34 @@ static const void* PyUpb_FileDescriptor_NestedLookup(
|
|||
|
||||
static const void* PyUpb_FileDescriptor_LookupMessage(
|
||||
const upb_FileDef* filedef, const char* name) {
|
||||
return PyUpb_FileDescriptor_NestedLookup(
|
||||
const upb_MessageDef* m = PyUpb_FileDescriptor_NestedLookup(
|
||||
filedef, name, (void*)&upb_DefPool_FindMessageByName);
|
||||
if (!m) return NULL;
|
||||
return upb_MessageDef_File(m) == filedef ? m : NULL;
|
||||
}
|
||||
|
||||
static const void* PyUpb_FileDescriptor_LookupEnum(const upb_FileDef* filedef,
|
||||
const char* name) {
|
||||
return PyUpb_FileDescriptor_NestedLookup(filedef, name,
|
||||
(void*)&upb_DefPool_FindEnumByName);
|
||||
const upb_EnumDef* e = PyUpb_FileDescriptor_NestedLookup(
|
||||
filedef, name, (void*)&upb_DefPool_FindEnumByName);
|
||||
if (!e) return NULL;
|
||||
return upb_EnumDef_File(e) == filedef ? e : NULL;
|
||||
}
|
||||
|
||||
static const void* PyUpb_FileDescriptor_LookupExtension(
|
||||
const upb_FileDef* filedef, const char* name) {
|
||||
return PyUpb_FileDescriptor_NestedLookup(
|
||||
const upb_FieldDef* f = PyUpb_FileDescriptor_NestedLookup(
|
||||
filedef, name, (void*)&upb_DefPool_FindExtensionByName);
|
||||
if (!f) return NULL;
|
||||
return upb_FieldDef_File(f) == filedef ? f : NULL;
|
||||
}
|
||||
|
||||
static const void* PyUpb_FileDescriptor_LookupService(
|
||||
const upb_FileDef* filedef, const char* name) {
|
||||
return PyUpb_FileDescriptor_NestedLookup(
|
||||
const upb_ServiceDef* s = PyUpb_FileDescriptor_NestedLookup(
|
||||
filedef, name, (void*)&upb_DefPool_FindServiceByName);
|
||||
if (!s) return NULL;
|
||||
return upb_ServiceDef_File(s) == filedef ? s : NULL;
|
||||
}
|
||||
|
||||
static PyObject* PyUpb_FileDescriptor_GetName(PyUpb_DescriptorBase* self,
|
||||
|
@ -1376,17 +1365,10 @@ static PyObject* PyUpb_FileDescriptor_GetPublicDependencies(PyObject* _self,
|
|||
return PyUpb_GenericSequence_New(&funcs, self->def, self->pool);
|
||||
}
|
||||
|
||||
static PyObject* PyUpb_FileDescriptor_GetSyntax(PyObject* _self,
|
||||
void* closure) {
|
||||
PyErr_WarnEx(NULL,
|
||||
"descriptor.syntax is deprecated. It will be removed soon. "
|
||||
"Most usages are checking field descriptors. Consider to use "
|
||||
"has_presence, is_packed on field descriptors.",
|
||||
1);
|
||||
static PyObject* PyUpb_FileDescriptor_GetEdition(PyObject* _self,
|
||||
void* closure) {
|
||||
PyUpb_DescriptorBase* self = (void*)_self;
|
||||
const char* syntax =
|
||||
upb_FileDef_Syntax(self->def) == kUpb_Syntax_Proto2 ? "proto2" : "proto3";
|
||||
return PyUnicode_FromString(syntax);
|
||||
return PyLong_FromLong(upb_FileDef_Edition(self->def));
|
||||
}
|
||||
|
||||
static PyObject* PyUpb_FileDescriptor_GetHasOptions(PyObject* _self,
|
||||
|
@ -1437,14 +1419,7 @@ static PyGetSetDef PyUpb_FileDescriptor_Getters[] = {
|
|||
{"public_dependencies", PyUpb_FileDescriptor_GetPublicDependencies, NULL,
|
||||
"Dependencies"},
|
||||
{"has_options", PyUpb_FileDescriptor_GetHasOptions, NULL, "Has Options"},
|
||||
// begin:github_only
|
||||
{"syntax", PyUpb_FileDescriptor_GetSyntax, (setter)NULL, "Syntax"},
|
||||
// end:github_only
|
||||
// begin:google_only
|
||||
// // TODO Use this to open-source syntax deprecation.
|
||||
// {"deprecated_syntax", PyUpb_FileDescriptor_GetSyntax, (setter)NULL,
|
||||
// "Syntax"},
|
||||
// end:google_only
|
||||
{"edition", PyUpb_FileDescriptor_GetEdition, (setter)NULL, "Edition"},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
|
|
|
@ -1179,24 +1179,23 @@ class FileDescriptor(DescriptorBase):
|
|||
Attributes:
|
||||
name (str): Name of file, relative to root of source tree.
|
||||
package (str): Name of the package
|
||||
syntax (str): string indicating syntax of the file (can be "proto2" or
|
||||
"proto3")
|
||||
edition (Edition): Enum value indicating edition of the file
|
||||
serialized_pb (bytes): Byte string of serialized
|
||||
:class:`descriptor_pb2.FileDescriptorProto`.
|
||||
dependencies (list[FileDescriptor]): List of other :class:`FileDescriptor`
|
||||
objects this :class:`FileDescriptor` depends on.
|
||||
public_dependencies (list[FileDescriptor]): A subset of
|
||||
:attr:`dependencies`, which were declared as "public".
|
||||
message_types_by_name (dict(str, Descriptor)): Mapping from message names
|
||||
to their :class:`Descriptor`.
|
||||
message_types_by_name (dict(str, Descriptor)): Mapping from message names to
|
||||
their :class:`Descriptor`.
|
||||
enum_types_by_name (dict(str, EnumDescriptor)): Mapping from enum names to
|
||||
their :class:`EnumDescriptor`.
|
||||
extensions_by_name (dict(str, FieldDescriptor)): Mapping from extension
|
||||
names declared at file scope to their :class:`FieldDescriptor`.
|
||||
services_by_name (dict(str, ServiceDescriptor)): Mapping from services'
|
||||
names to their :class:`ServiceDescriptor`.
|
||||
pool (DescriptorPool): The pool this descriptor belongs to. When not
|
||||
passed to the constructor, the global default pool is used.
|
||||
pool (DescriptorPool): The pool this descriptor belongs to. When not passed
|
||||
to the constructor, the global default pool is used.
|
||||
"""
|
||||
|
||||
if _USE_C_DESCRIPTORS:
|
||||
|
@ -1260,7 +1259,6 @@ class FileDescriptor(DescriptorBase):
|
|||
self.message_types_by_name = {}
|
||||
self.name = name
|
||||
self.package = package
|
||||
self._deprecated_syntax = syntax or "proto2"
|
||||
self.serialized_pb = serialized_pb
|
||||
|
||||
self.enum_types_by_name = {}
|
||||
|
@ -1269,15 +1267,6 @@ class FileDescriptor(DescriptorBase):
|
|||
self.dependencies = (dependencies or [])
|
||||
self.public_dependencies = (public_dependencies or [])
|
||||
|
||||
@property
|
||||
def syntax(self):
|
||||
warnings.warn(
|
||||
'descriptor.syntax is deprecated. It will be removed'
|
||||
' soon. Most usages are checking field descriptors. Consider to use'
|
||||
' has_presence, is_packed on field descriptors.'
|
||||
)
|
||||
return self._deprecated_syntax
|
||||
|
||||
def CopyToProto(self, proto):
|
||||
"""Copies this to a descriptor_pb2.FileDescriptorProto.
|
||||
|
||||
|
@ -1290,6 +1279,13 @@ class FileDescriptor(DescriptorBase):
|
|||
def _parent(self):
|
||||
return None
|
||||
|
||||
@property
|
||||
def edition(self):
|
||||
# pylint: disable=g-import-not-at-top
|
||||
from google.protobuf import descriptor_pb2
|
||||
|
||||
return descriptor_pb2.Edition.Value(self._edition)
|
||||
|
||||
|
||||
def _ParseOptions(message, string):
|
||||
"""Parses serialized options.
|
||||
|
|
|
@ -132,6 +132,51 @@ class DescriptorPoolTestBase(object):
|
|||
self.assertRaises(KeyError, self.pool.FindFileContainingSymbol,
|
||||
'google.protobuf.python.internal.Factory1Message.none_field')
|
||||
|
||||
def testCrossFileMessageTypesByName(self):
|
||||
self.assertIs(
|
||||
descriptor_pool_test1_pb2.DescriptorPoolTest1.DESCRIPTOR,
|
||||
descriptor_pool_test1_pb2.DESCRIPTOR.message_types_by_name[
|
||||
'DescriptorPoolTest1'
|
||||
],
|
||||
)
|
||||
with self.assertRaises(KeyError):
|
||||
descriptor_pool_test2_pb2.DESCRIPTOR.message_types_by_name[
|
||||
'DescriptorPoolTest1'
|
||||
]
|
||||
|
||||
def testCrossFileEnumTypesByName(self):
|
||||
self.assertIs(
|
||||
descriptor_pool_test1_pb2.TopLevelEnumTest1.DESCRIPTOR,
|
||||
descriptor_pool_test1_pb2.DESCRIPTOR.enum_types_by_name[
|
||||
'TopLevelEnumTest1'
|
||||
],
|
||||
)
|
||||
with self.assertRaises(KeyError):
|
||||
descriptor_pool_test2_pb2.DESCRIPTOR.enum_types_by_name[
|
||||
'TopLevelEnumTest1'
|
||||
]
|
||||
|
||||
def testCrossFileExtensionsByName(self):
|
||||
self.assertIs(
|
||||
descriptor_pool_test1_pb2.top_level_extension_test1,
|
||||
descriptor_pool_test1_pb2.DESCRIPTOR.extensions_by_name[
|
||||
'top_level_extension_test1'
|
||||
],
|
||||
)
|
||||
with self.assertRaises(KeyError):
|
||||
descriptor_pool_test2_pb2.DESCRIPTOR.extensions_by_name[
|
||||
'top_level_extension_test1'
|
||||
]
|
||||
|
||||
def testCrossFileServicesByName(self):
|
||||
descriptor_pool_test1_pb2.DESCRIPTOR.services_by_name[
|
||||
'DescriporPoolTestService'
|
||||
],
|
||||
with self.assertRaises(KeyError):
|
||||
descriptor_pool_test2_pb2.DESCRIPTOR.services_by_name[
|
||||
'DescriporPoolTestService'
|
||||
]
|
||||
|
||||
def testFindFileContainingSymbolFailure(self):
|
||||
with self.assertRaises(KeyError):
|
||||
self.pool.FindFileContainingSymbol('Does not exist')
|
||||
|
|
|
@ -9,6 +9,17 @@ syntax = "proto2";
|
|||
|
||||
package google.protobuf.python.internal;
|
||||
|
||||
enum TopLevelEnumTest1 {
|
||||
TOP_LEVEL_ENUM_TEST_1_NONE = 0;
|
||||
TOP_LEVEL_ENUM_TEST_1_ONE = 1;
|
||||
}
|
||||
|
||||
extend DescriptorPoolTest1 {
|
||||
optional TopLevelEnumTest1 top_level_extension_test1 = 1000;
|
||||
}
|
||||
|
||||
service DescriporPoolTestService {}
|
||||
|
||||
message DescriptorPoolTest1 {
|
||||
extensions 1000 to max;
|
||||
|
||||
|
@ -63,7 +74,7 @@ message DescriptorPoolTest2 {
|
|||
LAMBDA = 11;
|
||||
MU = 12;
|
||||
|
||||
reserved -1;
|
||||
reserved - 1;
|
||||
reserved 536870913; // 0x20000001
|
||||
}
|
||||
optional NestedEnum nested_enum = 1 [default = MU];
|
||||
|
|
|
@ -539,7 +539,9 @@ class DescriptorTest(unittest.TestCase):
|
|||
self.assertEqual(self.my_file.package, 'protobuf_unittest')
|
||||
self.assertEqual(self.my_file.pool, self.pool)
|
||||
self.assertFalse(self.my_file.has_options)
|
||||
self.assertEqual(self.my_file.syntax, 'proto2')
|
||||
self.assertEqual(
|
||||
self.my_file.edition, descriptor_pb2.Edition.EDITION_PROTO2
|
||||
)
|
||||
file_proto = descriptor_pb2.FileDescriptorProto()
|
||||
self.my_file.CopyToProto(file_proto)
|
||||
self.assertEqual(self.my_file.serialized_pb,
|
||||
|
|
|
@ -1340,6 +1340,17 @@ class Proto2Test(unittest.TestCase):
|
|||
self.assertEqual(False, message.optional_bool)
|
||||
self.assertEqual(0, message.optional_nested_message.bb)
|
||||
|
||||
def testDel(self):
|
||||
msg = unittest_pb2.TestAllTypes()
|
||||
|
||||
# Fields cannot be deleted.
|
||||
with self.assertRaises(AttributeError):
|
||||
del msg.optional_int32
|
||||
with self.assertRaises(AttributeError):
|
||||
del msg.optional_bool
|
||||
with self.assertRaises(AttributeError):
|
||||
del msg.repeated_nested_message
|
||||
|
||||
def testAssignInvalidEnum(self):
|
||||
"""Assigning an invalid enum number is not allowed in proto2."""
|
||||
m = unittest_pb2.TestAllTypes()
|
||||
|
|
|
@ -1385,15 +1385,9 @@ def _Clear(self):
|
|||
|
||||
|
||||
def _UnknownFields(self):
|
||||
warnings.warn(
|
||||
'message.UnknownFields() is deprecated. Please use the add one '
|
||||
'feature unknown_fields.UnknownFieldSet(message) in '
|
||||
'unknown_fields.py instead.'
|
||||
)
|
||||
if self._unknown_field_set is None: # pylint: disable=protected-access
|
||||
# pylint: disable=protected-access
|
||||
self._unknown_field_set = containers.UnknownFieldSet()
|
||||
return self._unknown_field_set # pylint: disable=protected-access
|
||||
raise NotImplementedError('Please use the add-on feaure '
|
||||
'unknown_fields.UnknownFieldSet(message) in '
|
||||
'unknown_fields.py instead.')
|
||||
|
||||
|
||||
def _DiscardUnknownFields(self):
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include "absl/log/absl_check.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "google/protobuf/descriptor.h"
|
||||
#include "google/protobuf/descriptor_legacy.h"
|
||||
#include "google/protobuf/dynamic_message.h"
|
||||
#include "google/protobuf/io/coded_stream.h"
|
||||
#include "google/protobuf/pyext/descriptor_containers.h"
|
||||
|
@ -696,17 +695,6 @@ static PyObject* EnumValueName(PyBaseDescriptor *self, PyObject *args) {
|
|||
return PyString_FromCppString(enum_value->name());
|
||||
}
|
||||
|
||||
static PyObject* GetSyntax(PyBaseDescriptor *self, void *closure) {
|
||||
PyErr_WarnEx(nullptr,
|
||||
"descriptor.syntax is deprecated. It will be removed soon. "
|
||||
"Most usages are checking field descriptors. Consider to use "
|
||||
"has_presence, is_packed on field descriptors.",
|
||||
1);
|
||||
std::string syntax(FileDescriptorLegacy::SyntaxName(
|
||||
FileDescriptorLegacy(_GetDescriptor(self)->file()).syntax()));
|
||||
return PyUnicode_InternFromString(syntax.c_str());
|
||||
}
|
||||
|
||||
static PyGetSetDef Getters[] = {
|
||||
{"name", (getter)GetName, nullptr, "Last name"},
|
||||
{"full_name", (getter)GetFullName, nullptr, "Full name"},
|
||||
|
@ -743,7 +731,6 @@ static PyGetSetDef Getters[] = {
|
|||
{"_options", (getter) nullptr, (setter)SetOptions, "Options"},
|
||||
{"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions,
|
||||
"Serialized Options"},
|
||||
{"syntax", (getter)GetSyntax, (setter) nullptr, "Syntax"},
|
||||
{nullptr},
|
||||
};
|
||||
|
||||
|
@ -1542,15 +1529,8 @@ static int SetSerializedOptions(PyFileDescriptor *self, PyObject *value,
|
|||
return CheckCalledFromGeneratedFile("_serialized_options");
|
||||
}
|
||||
|
||||
static PyObject* GetSyntax(PyFileDescriptor *self, void *closure) {
|
||||
PyErr_WarnEx(nullptr,
|
||||
"descriptor.syntax is deprecated. It will be removed soon. "
|
||||
"Most usages are checking field descriptors. Consider to use "
|
||||
"has_presence, is_packed on field descriptors.",
|
||||
1);
|
||||
std::string syntax(FileDescriptorLegacy::SyntaxName(
|
||||
FileDescriptorLegacy(_GetDescriptor(self)).syntax()));
|
||||
return PyUnicode_InternFromString(syntax.c_str());
|
||||
static PyObject* GetEdition(PyFileDescriptor* self, void* closure) {
|
||||
return PyLong_FromLong(_GetDescriptor(self)->edition());
|
||||
}
|
||||
|
||||
static PyObject* CopyToProto(PyFileDescriptor *self, PyObject *target) {
|
||||
|
@ -1579,7 +1559,7 @@ static PyGetSetDef Getters[] = {
|
|||
{"_options", (getter) nullptr, (setter)SetOptions, "Options"},
|
||||
{"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions,
|
||||
"Serialized Options"},
|
||||
{"syntax", (getter)GetSyntax, (setter) nullptr, "Syntax"},
|
||||
{"edition", (getter)GetEdition, (setter) nullptr, "Edition"},
|
||||
{nullptr},
|
||||
};
|
||||
|
||||
|
|
|
@ -2346,16 +2346,11 @@ static PyObject* GetExtensionDict(CMessage* self, void *closure) {
|
|||
}
|
||||
|
||||
static PyObject* GetUnknownFields(CMessage* self) {
|
||||
PyErr_Warn(nullptr,
|
||||
"message.UnknownFields() is deprecated. Please use the "
|
||||
"add one feature unknown_fields.UnknownFieldSet(message) in "
|
||||
"unknown_fields.py instead.");
|
||||
if (self->unknown_field_set == nullptr) {
|
||||
self->unknown_field_set = unknown_fields::NewPyUnknownFields(self);
|
||||
} else {
|
||||
Py_INCREF(self->unknown_field_set);
|
||||
}
|
||||
return self->unknown_field_set;
|
||||
PyErr_Format(PyExc_NotImplementedError,
|
||||
"Please use the add-on feature "
|
||||
"unknown_fields.UnknownFieldSet(message) in "
|
||||
"unknown_fields.py instead.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static PyGetSetDef Getters[] = {
|
||||
|
|
|
@ -1005,6 +1005,12 @@ __attribute__((flatten)) static PyObject* PyUpb_Message_GetAttr(
|
|||
static int PyUpb_Message_SetAttr(PyObject* _self, PyObject* attr,
|
||||
PyObject* value) {
|
||||
PyUpb_Message* self = (void*)_self;
|
||||
|
||||
if (value == NULL) {
|
||||
PyErr_SetString(PyExc_AttributeError, "Cannot delete field attribute");
|
||||
return -1;
|
||||
}
|
||||
|
||||
const upb_FieldDef* field;
|
||||
if (!PyUpb_Message_LookupName(self, attr, &field, NULL,
|
||||
PyExc_AttributeError)) {
|
||||
|
|
|
@ -8,8 +8,6 @@ pkg/
|
|||
tmp/
|
||||
tests/google/
|
||||
ext/google/protobuf_c/third_party/utf8_range/utf8_range.h
|
||||
ext/google/protobuf_c/third_party/utf8_range/range2-sse.c
|
||||
ext/google/protobuf_c/third_party/utf8_range/range2-neon.c
|
||||
ext/google/protobuf_c/third_party/utf8_range/naive.c
|
||||
ext/google/protobuf_c/third_party/utf8_range/utf8_range.c
|
||||
ext/google/protobuf_c/third_party/utf8_range/LICENSE
|
||||
lib/google/protobuf/*_pb.rb
|
|
@ -115,7 +115,7 @@ $ bazel test //ruby/tests/...
|
|||
To run tests against the FFI implementation:
|
||||
|
||||
```
|
||||
$ bazel test //ruby/tests/... //ruby:ffi=enabled --test_env=PROTOCOL_BUFFERS_RUBY_IMPLEMENTATION=FFI
|
||||
$ bazel test //ruby/tests/... //ruby:ffi_enabled --test_env=PROTOCOL_BUFFERS_RUBY_IMPLEMENTATION=FFI
|
||||
```
|
||||
|
||||
Version Number Scheme
|
||||
|
|
|
@ -75,7 +75,7 @@ task :copy_third_party do
|
|||
# We need utf8_range in-tree.
|
||||
utf8_root = '../third_party/utf8_range'
|
||||
%w[
|
||||
utf8_range.h naive.c range2-neon.c range2-neon.c range2-sse.c LICENSE
|
||||
utf8_range.h utf8_range.c LICENSE
|
||||
].each do |file|
|
||||
FileUtils.cp File.join(utf8_root, file),
|
||||
"ext/google/protobuf_c/third_party/utf8_range"
|
||||
|
|
|
@ -141,7 +141,7 @@ upb_MessageValue Convert_RubyToUpb(VALUE value, const char* name,
|
|||
VALUE utf8 = rb_enc_from_encoding(rb_utf8_encoding());
|
||||
if (rb_obj_class(value) == rb_cSymbol) {
|
||||
value = rb_funcall(value, rb_intern("to_s"), 0);
|
||||
} else if (rb_obj_class(value) != rb_cString) {
|
||||
} else if (!rb_obj_is_kind_of(value, rb_cString)) {
|
||||
rb_raise(cTypeError,
|
||||
"Invalid argument for string field '%s' (given %s).", name,
|
||||
rb_class2name(CLASS_OF(value)));
|
||||
|
|
|
@ -22,7 +22,7 @@ $INCFLAGS += " -I$(srcdir)/third_party/utf8_range"
|
|||
|
||||
$srcs = ["protobuf.c", "convert.c", "defs.c", "message.c",
|
||||
"repeated_field.c", "map.c", "ruby-upb.c", "wrap_memcpy.c",
|
||||
"naive.c", "range2-neon.c", "range2-sse.c", "shared_convert.c",
|
||||
"utf8_range.c", "shared_convert.c",
|
||||
"shared_message.c"]
|
||||
|
||||
create_makefile(ext_name)
|
||||
|
|
|
@ -660,11 +660,8 @@ static VALUE Message_dup(VALUE _self) {
|
|||
Message* self = ruby_to_Message(_self);
|
||||
VALUE new_msg = rb_class_new_instance(0, NULL, CLASS_OF(_self));
|
||||
Message* new_msg_self = ruby_to_Message(new_msg);
|
||||
size_t size = upb_MessageDef_MiniTable(self->msgdef)->size;
|
||||
|
||||
// TODO
|
||||
// TODO
|
||||
memcpy((upb_Message*)new_msg_self->msg, self->msg, size);
|
||||
const upb_MiniTable* m = upb_MessageDef_MiniTable(self->msgdef);
|
||||
upb_Message_ShallowCopy((upb_Message*)new_msg_self->msg, self->msg, m);
|
||||
Arena_fuse(self->arena, Arena_get(new_msg_self->arena));
|
||||
return new_msg;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -74,9 +74,7 @@ begin
|
|||
FFI::Compiler::CompileTask.new 'protobuf_c_ffi' do |c|
|
||||
configure_common_compile_task c
|
||||
# Ruby UPB was already compiled with different flags.
|
||||
c.exclude << "/range2-neon.c"
|
||||
c.exclude << "/range2-sse.c"
|
||||
c.exclude << "/naive.c"
|
||||
c.exclude << "/utf8_range.c"
|
||||
c.exclude << "/ruby-upb.c"
|
||||
end
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ import com.google.protobuf.Descriptors.OneofDescriptor;
|
|||
import com.google.protobuf.DynamicMessage;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import com.google.protobuf.LegacyDescriptorsUtil.LegacyFileDescriptor;
|
||||
import com.google.protobuf.LegacyDescriptorsUtil.LegacyOneofDescriptor;
|
||||
import com.google.protobuf.Message;
|
||||
import com.google.protobuf.UnknownFieldSet;
|
||||
import com.google.protobuf.util.JsonFormat;
|
||||
|
@ -1340,7 +1341,7 @@ public class RubyMessage extends RubyObject {
|
|||
// Keep track of what Oneofs are set
|
||||
if (value.isNil()) {
|
||||
oneofCases.remove(oneofDescriptor);
|
||||
if (!oneofDescriptor.isSynthetic()) {
|
||||
if (!LegacyOneofDescriptor.isSynthetic(oneofDescriptor)) {
|
||||
addValue = false;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -787,4 +787,15 @@ module BasicTest
|
|||
assert_respond_to msg, :has_d?
|
||||
refute msg.has_d?
|
||||
end
|
||||
|
||||
def test_string_subclass
|
||||
str = "hello"
|
||||
myString = Class.new(String)
|
||||
|
||||
m = proto_module::TestMessage.new(
|
||||
optional_string: myString.new(str),
|
||||
)
|
||||
|
||||
assert_equal str, m.optional_string
|
||||
end
|
||||
end
|
||||
|
|
467
rust/cpp.rs
467
rust/cpp.rs
|
@ -7,11 +7,14 @@
|
|||
|
||||
// Rust Protobuf runtime using the C++ kernel.
|
||||
|
||||
use crate::__internal::{Private, RawArena, RawMap, RawMessage, RawRepeatedField};
|
||||
use crate::ProtoStr;
|
||||
use crate::__internal::{Private, PtrAndLen, RawArena, RawMap, RawMessage, RawRepeatedField};
|
||||
use crate::{Mut, ProxiedInRepeated, Repeated, View};
|
||||
use core::fmt::Debug;
|
||||
use paste::paste;
|
||||
use std::alloc::Layout;
|
||||
use std::cell::UnsafeCell;
|
||||
use std::convert::identity;
|
||||
use std::fmt;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem::MaybeUninit;
|
||||
|
@ -139,7 +142,7 @@ impl fmt::Debug for SerializedData {
|
|||
pub type BytesPresentMutData<'msg> = crate::vtable::RawVTableOptionalMutatorData<'msg, [u8]>;
|
||||
pub type BytesAbsentMutData<'msg> = crate::vtable::RawVTableOptionalMutatorData<'msg, [u8]>;
|
||||
pub type InnerBytesMut<'msg> = crate::vtable::RawVTableMutator<'msg, [u8]>;
|
||||
pub type InnerPrimitiveMut<'a, T> = crate::vtable::RawVTableMutator<'a, T>;
|
||||
pub type InnerPrimitiveMut<'msg, T> = crate::vtable::RawVTableMutator<'msg, T>;
|
||||
|
||||
/// The raw contents of every generated message.
|
||||
#[derive(Debug)]
|
||||
|
@ -185,140 +188,104 @@ impl<'msg> MutatorMessageRef<'msg> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn copy_bytes_in_arena_if_needed_by_runtime<'a>(
|
||||
_msg_ref: MutatorMessageRef<'a>,
|
||||
val: &'a [u8],
|
||||
) -> &'a [u8] {
|
||||
pub fn copy_bytes_in_arena_if_needed_by_runtime<'msg>(
|
||||
_msg_ref: MutatorMessageRef<'msg>,
|
||||
val: &'msg [u8],
|
||||
) -> &'msg [u8] {
|
||||
// Nothing to do, the message manages its own string memory for C++.
|
||||
val
|
||||
}
|
||||
|
||||
/// RepeatedField impls delegate out to `extern "C"` functions exposed by
|
||||
/// `cpp_api.h` and store either a RepeatedField* or a RepeatedPtrField*
|
||||
/// depending on the type.
|
||||
/// The raw type-erased pointer version of `RepeatedMut`.
|
||||
///
|
||||
/// Note: even though this type is `Copy`, it should only be copied by
|
||||
/// protobuf internals that can maintain mutation invariants:
|
||||
///
|
||||
/// - No concurrent mutation for any two fields in a message: this means
|
||||
/// mutators cannot be `Send` but are `Sync`.
|
||||
/// - If there are multiple accessible `Mut` to a single message at a time, they
|
||||
/// must be different fields, and not be in the same oneof. As such, a `Mut`
|
||||
/// cannot be `Clone` but *can* reborrow itself with `.as_mut()`, which
|
||||
/// converts `&'b mut Mut<'a, T>` to `Mut<'b, T>`.
|
||||
#[derive(Debug)]
|
||||
pub struct RepeatedField<'msg, T: ?Sized> {
|
||||
inner: RepeatedFieldInner<'msg>,
|
||||
_phantom: PhantomData<&'msg mut T>,
|
||||
}
|
||||
|
||||
/// CPP runtime-specific arguments for initializing a RepeatedField.
|
||||
/// See RepeatedField comment about mutation invariants for when this type can
|
||||
/// be copied.
|
||||
/// Contains a `proto2::RepeatedField*` or `proto2::RepeatedPtrField*`.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct RepeatedFieldInner<'msg> {
|
||||
pub raw: RawRepeatedField,
|
||||
pub _phantom: PhantomData<&'msg ()>,
|
||||
pub struct InnerRepeatedMut<'msg> {
|
||||
pub(crate) raw: RawRepeatedField,
|
||||
_phantom: PhantomData<&'msg ()>,
|
||||
}
|
||||
|
||||
impl<'msg, T: ?Sized> RepeatedField<'msg, T> {
|
||||
pub fn from_inner(_private: Private, inner: RepeatedFieldInner<'msg>) -> Self {
|
||||
RepeatedField { inner, _phantom: PhantomData }
|
||||
impl<'msg> InnerRepeatedMut<'msg> {
|
||||
#[doc(hidden)]
|
||||
pub fn new(_private: Private, raw: RawRepeatedField) -> Self {
|
||||
InnerRepeatedMut { raw, _phantom: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
// These use manual impls instead of derives to avoid unnecessary bounds on `T`.
|
||||
// This problem is referred to as "perfect derive".
|
||||
// https://smallcultfollowing.com/babysteps/blog/2022/04/12/implied-bounds-and-perfect-derive/
|
||||
impl<'msg, T: ?Sized> Copy for RepeatedField<'msg, T> {}
|
||||
impl<'msg, T: ?Sized> Clone for RepeatedField<'msg, T> {
|
||||
fn clone(&self) -> RepeatedField<'msg, T> {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
pub trait RepeatedScalarOps {
|
||||
fn new_repeated_field() -> RawRepeatedField;
|
||||
fn push(f: RawRepeatedField, v: Self);
|
||||
fn len(f: RawRepeatedField) -> usize;
|
||||
fn get(f: RawRepeatedField, i: usize) -> Self;
|
||||
fn set(f: RawRepeatedField, i: usize, v: Self);
|
||||
fn copy_from(src: RawRepeatedField, dst: RawRepeatedField);
|
||||
}
|
||||
|
||||
macro_rules! impl_repeated_scalar_ops {
|
||||
($($t: ty),*) => {
|
||||
paste! { $(
|
||||
macro_rules! impl_repeated_primitives {
|
||||
(@impl $($t:ty => [
|
||||
$new_thunk:ident,
|
||||
$free_thunk:ident,
|
||||
$add_thunk:ident,
|
||||
$size_thunk:ident,
|
||||
$get_thunk:ident,
|
||||
$set_thunk:ident,
|
||||
$clear_thunk:ident,
|
||||
$copy_from_thunk:ident $(,)?
|
||||
]),* $(,)?) => {
|
||||
$(
|
||||
extern "C" {
|
||||
fn [< __pb_rust_RepeatedField_ $t _new >]() -> RawRepeatedField;
|
||||
fn [< __pb_rust_RepeatedField_ $t _add >](f: RawRepeatedField, v: $t);
|
||||
fn [< __pb_rust_RepeatedField_ $t _size >](f: RawRepeatedField) -> usize;
|
||||
fn [< __pb_rust_RepeatedField_ $t _get >](f: RawRepeatedField, i: usize) -> $t;
|
||||
fn [< __pb_rust_RepeatedField_ $t _set >](f: RawRepeatedField, i: usize, v: $t);
|
||||
fn [< __pb_rust_RepeatedField_ $t _copy_from >](src: RawRepeatedField, dst: RawRepeatedField);
|
||||
fn $new_thunk() -> RawRepeatedField;
|
||||
fn $free_thunk(f: RawRepeatedField);
|
||||
fn $add_thunk(f: RawRepeatedField, v: $t);
|
||||
fn $size_thunk(f: RawRepeatedField) -> usize;
|
||||
fn $get_thunk(f: RawRepeatedField, i: usize) -> $t;
|
||||
fn $set_thunk(f: RawRepeatedField, i: usize, v: $t);
|
||||
fn $clear_thunk(f: RawRepeatedField);
|
||||
fn $copy_from_thunk(src: RawRepeatedField, dst: RawRepeatedField);
|
||||
}
|
||||
impl RepeatedScalarOps for $t {
|
||||
fn new_repeated_field() -> RawRepeatedField {
|
||||
unsafe { [< __pb_rust_RepeatedField_ $t _new >]() }
|
||||
|
||||
unsafe impl ProxiedInRepeated for $t {
|
||||
#[allow(dead_code)]
|
||||
fn repeated_new(_: Private) -> Repeated<$t> {
|
||||
unsafe {
|
||||
Repeated::from_inner(InnerRepeatedMut::new(Private, $new_thunk()))
|
||||
}
|
||||
}
|
||||
fn push(f: RawRepeatedField, v: Self) {
|
||||
unsafe { [< __pb_rust_RepeatedField_ $t _add >](f, v) }
|
||||
#[allow(dead_code)]
|
||||
unsafe fn repeated_free(_: Private, f: &mut Repeated<$t>) {
|
||||
unsafe { $free_thunk(f.as_mut().as_raw(Private)) }
|
||||
}
|
||||
fn len(f: RawRepeatedField) -> usize {
|
||||
unsafe { [< __pb_rust_RepeatedField_ $t _size >](f) }
|
||||
fn repeated_len(f: View<Repeated<$t>>) -> usize {
|
||||
unsafe { $size_thunk(f.as_raw(Private)) }
|
||||
}
|
||||
fn get(f: RawRepeatedField, i: usize) -> Self {
|
||||
unsafe { [< __pb_rust_RepeatedField_ $t _get >](f, i) }
|
||||
fn repeated_push(mut f: Mut<Repeated<$t>>, v: View<$t>) {
|
||||
unsafe { $add_thunk(f.as_raw(Private), v) }
|
||||
}
|
||||
fn set(f: RawRepeatedField, i: usize, v: Self) {
|
||||
unsafe { [< __pb_rust_RepeatedField_ $t _set >](f, i, v) }
|
||||
fn repeated_clear(mut f: Mut<Repeated<$t>>) {
|
||||
unsafe { $clear_thunk(f.as_raw(Private)) }
|
||||
}
|
||||
fn copy_from(src: RawRepeatedField, dst: RawRepeatedField) {
|
||||
unsafe { [< __pb_rust_RepeatedField_ $t _copy_from >](src, dst) }
|
||||
unsafe fn repeated_get_unchecked(f: View<Repeated<$t>>, i: usize) -> View<$t> {
|
||||
unsafe { $get_thunk(f.as_raw(Private), i) }
|
||||
}
|
||||
unsafe fn repeated_set_unchecked(mut f: Mut<Repeated<$t>>, i: usize, v: View<$t>) {
|
||||
unsafe { $set_thunk(f.as_raw(Private), i, v) }
|
||||
}
|
||||
fn repeated_copy_from(src: View<Repeated<$t>>, mut dest: Mut<Repeated<$t>>) {
|
||||
unsafe { $copy_from_thunk(src.as_raw(Private), dest.as_raw(Private)) }
|
||||
}
|
||||
}
|
||||
)* }
|
||||
)*
|
||||
};
|
||||
($($t:ty),* $(,)?) => {
|
||||
paste!{
|
||||
impl_repeated_primitives!(@impl $(
|
||||
$t => [
|
||||
[< __pb_rust_RepeatedField_ $t _new >],
|
||||
[< __pb_rust_RepeatedField_ $t _free >],
|
||||
[< __pb_rust_RepeatedField_ $t _add >],
|
||||
[< __pb_rust_RepeatedField_ $t _size >],
|
||||
[< __pb_rust_RepeatedField_ $t _get >],
|
||||
[< __pb_rust_RepeatedField_ $t _set >],
|
||||
[< __pb_rust_RepeatedField_ $t _clear >],
|
||||
[< __pb_rust_RepeatedField_ $t _copy_from >],
|
||||
],
|
||||
)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_repeated_scalar_ops!(i32, u32, i64, u64, f32, f64, bool);
|
||||
|
||||
impl<'msg, T: RepeatedScalarOps> RepeatedField<'msg, T> {
|
||||
#[allow(clippy::new_without_default, dead_code)]
|
||||
/// new() is not currently used in our normal pathways, it is only used
|
||||
/// for testing. Existing `RepeatedField<>`s are owned by, and retrieved
|
||||
/// from, the containing `Message`.
|
||||
pub fn new() -> Self {
|
||||
Self::from_inner(
|
||||
Private,
|
||||
RepeatedFieldInner::<'msg> { raw: T::new_repeated_field(), _phantom: PhantomData },
|
||||
)
|
||||
}
|
||||
pub fn push(&mut self, val: T) {
|
||||
T::push(self.inner.raw, val)
|
||||
}
|
||||
pub fn len(&self) -> usize {
|
||||
T::len(self.inner.raw)
|
||||
}
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
pub fn get(&self, index: usize) -> Option<T> {
|
||||
if index >= self.len() {
|
||||
return None;
|
||||
}
|
||||
Some(T::get(self.inner.raw, index))
|
||||
}
|
||||
pub fn set(&mut self, index: usize, val: T) {
|
||||
if index >= self.len() {
|
||||
return;
|
||||
}
|
||||
T::set(self.inner.raw, index, val)
|
||||
}
|
||||
pub fn copy_from(&mut self, src: &RepeatedField<'_, T>) {
|
||||
T::copy_from(src.inner.raw, self.inner.raw)
|
||||
}
|
||||
}
|
||||
impl_repeated_primitives!(i32, u32, i64, u64, f32, f64, bool);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct MapInner<'msg, K: ?Sized, V: ?Sized> {
|
||||
|
@ -327,9 +294,6 @@ pub struct MapInner<'msg, K: ?Sized, V: ?Sized> {
|
|||
pub _phantom_value: PhantomData<&'msg mut V>,
|
||||
}
|
||||
|
||||
// These use manual impls instead of derives to avoid unnecessary bounds on `K`
|
||||
// and `V`. This problem is referred to as "perfect derive".
|
||||
// https://smallcultfollowing.com/babysteps/blog/2022/04/12/implied-bounds-and-perfect-derive/
|
||||
impl<'msg, K: ?Sized, V: ?Sized> Copy for MapInner<'msg, K, V> {}
|
||||
impl<'msg, K: ?Sized, V: ?Sized> Clone for MapInner<'msg, K, V> {
|
||||
fn clone(&self) -> MapInner<'msg, K, V> {
|
||||
|
@ -337,78 +301,22 @@ impl<'msg, K: ?Sized, V: ?Sized> Clone for MapInner<'msg, K, V> {
|
|||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_scalar_map_values {
|
||||
($kt:ty, $trait:ident for $($t:ty),*) => {
|
||||
paste! { $(
|
||||
extern "C" {
|
||||
fn [< __pb_rust_Map_ $kt _ $t _new >]() -> RawMap;
|
||||
fn [< __pb_rust_Map_ $kt _ $t _clear >](m: RawMap);
|
||||
fn [< __pb_rust_Map_ $kt _ $t _size >](m: RawMap) -> usize;
|
||||
fn [< __pb_rust_Map_ $kt _ $t _insert >](m: RawMap, key: $kt, value: $t);
|
||||
fn [< __pb_rust_Map_ $kt _ $t _get >](m: RawMap, key: $kt, value: *mut $t) -> bool;
|
||||
fn [< __pb_rust_Map_ $kt _ $t _remove >](m: RawMap, key: $kt, value: *mut $t) -> bool;
|
||||
}
|
||||
impl $trait for $t {
|
||||
fn new_map() -> RawMap {
|
||||
unsafe { [< __pb_rust_Map_ $kt _ $t _new >]() }
|
||||
}
|
||||
macro_rules! generate_map_with_key_ops_traits {
|
||||
($($t:ty, $sized_t:ty;)*) => {
|
||||
paste! {
|
||||
$(
|
||||
pub trait [< MapWith $t:camel KeyOps >] {
|
||||
type Value<'msg>: Sized;
|
||||
|
||||
fn clear(m: RawMap) {
|
||||
unsafe { [< __pb_rust_Map_ $kt _ $t _clear >](m) }
|
||||
}
|
||||
|
||||
fn size(m: RawMap) -> usize {
|
||||
unsafe { [< __pb_rust_Map_ $kt _ $t _size >](m) }
|
||||
}
|
||||
|
||||
fn insert(m: RawMap, key: $kt, value: $t) {
|
||||
unsafe { [< __pb_rust_Map_ $kt _ $t _insert >](m, key, value) }
|
||||
}
|
||||
|
||||
fn get(m: RawMap, key: $kt) -> Option<$t> {
|
||||
let mut val: $t = Default::default();
|
||||
let found = unsafe { [< __pb_rust_Map_ $kt _ $t _get >](m, key, &mut val) };
|
||||
if !found {
|
||||
return None;
|
||||
}
|
||||
Some(val)
|
||||
}
|
||||
|
||||
fn remove(m: RawMap, key: $kt) -> Option<$t> {
|
||||
let mut val: $t = Default::default();
|
||||
let removed =
|
||||
unsafe { [< __pb_rust_Map_ $kt _ $t _remove >](m, key, &mut val) };
|
||||
if !removed {
|
||||
return None;
|
||||
}
|
||||
Some(val)
|
||||
}
|
||||
}
|
||||
)* }
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_scalar_maps {
|
||||
($($t:ty),*) => {
|
||||
paste! { $(
|
||||
pub trait [< MapWith $t:camel KeyOps >] : Sync + Send + Copy + Clone + Debug {
|
||||
fn new_map() -> RawMap;
|
||||
fn clear(m: RawMap);
|
||||
fn size(m: RawMap) -> usize;
|
||||
fn insert(m: RawMap, key: $t, value: Self);
|
||||
fn get(m: RawMap, key: $t) -> Option<Self>
|
||||
where
|
||||
Self: Sized;
|
||||
fn remove(m: RawMap, key: $t) -> Option<Self>
|
||||
where
|
||||
Self: Sized;
|
||||
fn insert(m: RawMap, key: $sized_t, value: Self::Value<'_>) -> bool;
|
||||
fn get<'msg>(m: RawMap, key: $sized_t) -> Option<Self::Value<'msg>>;
|
||||
fn remove(m: RawMap, key: $sized_t) -> bool;
|
||||
}
|
||||
|
||||
impl_scalar_map_values!(
|
||||
$t, [< MapWith $t:camel KeyOps >] for i32, u32, f32, f64, bool, u64, i64
|
||||
);
|
||||
|
||||
impl<'msg, V: [< MapWith $t:camel KeyOps >]> Default for MapInner<'msg, $t, V> {
|
||||
impl<'msg, V: [< MapWith $t:camel KeyOps >] + ?Sized> Default for MapInner<'msg, $t, V> {
|
||||
fn default() -> Self {
|
||||
MapInner {
|
||||
raw: V::new_map(),
|
||||
|
@ -418,7 +326,7 @@ macro_rules! impl_scalar_maps {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'msg, V: [< MapWith $t:camel KeyOps >]> MapInner<'msg, $t, V> {
|
||||
impl<'msg, V: [< MapWith $t:camel KeyOps >] + ?Sized> MapInner<'msg, $t, V> {
|
||||
pub fn size(&self) -> usize {
|
||||
V::size(self.raw)
|
||||
}
|
||||
|
@ -427,27 +335,129 @@ macro_rules! impl_scalar_maps {
|
|||
V::clear(self.raw)
|
||||
}
|
||||
|
||||
pub fn get(&self, key: $t) -> Option<V> {
|
||||
pub fn get<'a>(&self, key: $sized_t) -> Option<V::Value<'a>> {
|
||||
V::get(self.raw, key)
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, key: $t) -> Option<V> {
|
||||
pub fn remove(&mut self, key: $sized_t) -> bool {
|
||||
V::remove(self.raw, key)
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, key: $t, value: V) -> bool {
|
||||
pub fn insert(&mut self, key: $sized_t, value: V::Value<'_>) -> bool {
|
||||
V::insert(self.raw, key, value);
|
||||
true
|
||||
}
|
||||
}
|
||||
)* }
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_scalar_maps!(i32, u32, bool, u64, i64);
|
||||
generate_map_with_key_ops_traits!(
|
||||
i32, i32;
|
||||
u32, u32;
|
||||
i64, i64;
|
||||
u64, u64;
|
||||
bool, bool;
|
||||
ProtoStr, &ProtoStr;
|
||||
);
|
||||
|
||||
macro_rules! impl_scalar_map_with_key_op_for_scalar_values {
|
||||
($key_t:ty, $sized_key_t:ty, $ffi_key_t:ty, $to_ffi_key:expr, $trait:ident for $($t:ty, $sized_t:ty, $ffi_t:ty, $to_ffi_value:expr, $from_ffi_value:expr, $zero_val:literal;)*) => {
|
||||
paste! { $(
|
||||
extern "C" {
|
||||
fn [< __pb_rust_Map_ $key_t _ $t _new >]() -> RawMap;
|
||||
fn [< __pb_rust_Map_ $key_t _ $t _clear >](m: RawMap);
|
||||
fn [< __pb_rust_Map_ $key_t _ $t _size >](m: RawMap) -> usize;
|
||||
fn [< __pb_rust_Map_ $key_t _ $t _insert >](m: RawMap, key: $ffi_key_t, value: $ffi_t);
|
||||
fn [< __pb_rust_Map_ $key_t _ $t _get >](m: RawMap, key: $ffi_key_t, value: *mut $ffi_t) -> bool;
|
||||
fn [< __pb_rust_Map_ $key_t _ $t _remove >](m: RawMap, key: $ffi_key_t, value: *mut $ffi_t) -> bool;
|
||||
}
|
||||
impl $trait for $t {
|
||||
type Value<'msg> = $sized_t;
|
||||
|
||||
fn new_map() -> RawMap {
|
||||
unsafe { [< __pb_rust_Map_ $key_t _ $t _new >]() }
|
||||
}
|
||||
|
||||
fn clear(m: RawMap) {
|
||||
unsafe { [< __pb_rust_Map_ $key_t _ $t _clear >](m) }
|
||||
}
|
||||
|
||||
fn size(m: RawMap) -> usize {
|
||||
unsafe { [< __pb_rust_Map_ $key_t _ $t _size >](m) }
|
||||
}
|
||||
|
||||
fn insert(m: RawMap, key: $sized_key_t, value: Self::Value<'_>) -> bool {
|
||||
let ffi_key = $to_ffi_key(key);
|
||||
let ffi_value = $to_ffi_value(value);
|
||||
unsafe { [< __pb_rust_Map_ $key_t _ $t _insert >](m, ffi_key, ffi_value) }
|
||||
true
|
||||
}
|
||||
|
||||
fn get<'msg>(m: RawMap, key: $sized_key_t) -> Option<Self::Value<'msg>> {
|
||||
let ffi_key = $to_ffi_key(key);
|
||||
let mut ffi_value = $to_ffi_value($zero_val);
|
||||
let found = unsafe { [< __pb_rust_Map_ $key_t _ $t _get >](m, ffi_key, &mut ffi_value) };
|
||||
if !found {
|
||||
return None;
|
||||
}
|
||||
Some($from_ffi_value(ffi_value))
|
||||
}
|
||||
|
||||
fn remove(m: RawMap, key: $sized_key_t) -> bool {
|
||||
let ffi_key = $to_ffi_key(key);
|
||||
let mut ffi_value = $to_ffi_value($zero_val);
|
||||
unsafe { [< __pb_rust_Map_ $key_t _ $t _remove >](m, ffi_key, &mut ffi_value) }
|
||||
}
|
||||
}
|
||||
)* }
|
||||
}
|
||||
}
|
||||
|
||||
fn str_to_ptrlen<'msg>(val: impl Into<&'msg ProtoStr>) -> PtrAndLen {
|
||||
val.into().as_bytes().into()
|
||||
}
|
||||
|
||||
fn ptrlen_to_str<'msg>(val: PtrAndLen) -> &'msg ProtoStr {
|
||||
unsafe { ProtoStr::from_utf8_unchecked(val.as_ref()) }
|
||||
}
|
||||
|
||||
macro_rules! impl_map_with_key_ops_for_scalar_values {
|
||||
($($t:ty, $t_sized:ty, $ffi_t:ty, $to_ffi_key:expr;)*) => {
|
||||
paste! {
|
||||
$(
|
||||
impl_scalar_map_with_key_op_for_scalar_values!($t, $t_sized, $ffi_t, $to_ffi_key, [< MapWith $t:camel KeyOps >] for
|
||||
f32, f32, f32, identity, identity, 0f32;
|
||||
f64, f64, f64, identity, identity, 0f64;
|
||||
i32, i32, i32, identity, identity, 0i32;
|
||||
u32, u32, u32, identity, identity, 0u32;
|
||||
i64, i64, i64, identity, identity, 0i64;
|
||||
u64, u64, u64, identity, identity, 0u64;
|
||||
bool, bool, bool, identity, identity, false;
|
||||
ProtoStr, &'msg ProtoStr, PtrAndLen, str_to_ptrlen, ptrlen_to_str, "";
|
||||
);
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_map_with_key_ops_for_scalar_values!(
|
||||
i32, i32, i32, identity;
|
||||
u32, u32, u32, identity;
|
||||
i64, i64, i64, identity;
|
||||
u64, u64, u64, identity;
|
||||
bool, bool, bool, identity;
|
||||
ProtoStr, &ProtoStr, PtrAndLen, str_to_ptrlen;
|
||||
);
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn new_map_inner() -> MapInner<'static, i32, i64> {
|
||||
pub(crate) fn new_map_i32_i64() -> MapInner<'static, i32, i64> {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn new_map_str_str() -> MapInner<'static, ProtoStr, ProtoStr> {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
|
@ -472,29 +482,6 @@ mod tests {
|
|||
assert_that!(&*serialized_data, eq(b"Hello world"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn repeated_field() {
|
||||
let mut r = RepeatedField::<i32>::new();
|
||||
assert_that!(r.len(), eq(0));
|
||||
r.push(32);
|
||||
assert_that!(r.get(0), eq(Some(32)));
|
||||
|
||||
let mut r = RepeatedField::<u32>::new();
|
||||
assert_that!(r.len(), eq(0));
|
||||
r.push(32);
|
||||
assert_that!(r.get(0), eq(Some(32)));
|
||||
|
||||
let mut r = RepeatedField::<f64>::new();
|
||||
assert_that!(r.len(), eq(0));
|
||||
r.push(0.1234f64);
|
||||
assert_that!(r.get(0), eq(Some(0.1234)));
|
||||
|
||||
let mut r = RepeatedField::<bool>::new();
|
||||
assert_that!(r.len(), eq(0));
|
||||
r.push(true);
|
||||
assert_that!(r.get(0), eq(Some(true)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn i32_i32_map() {
|
||||
let mut map: MapInner<'_, i32, i32> = Default::default();
|
||||
|
@ -505,9 +492,9 @@ mod tests {
|
|||
assert_that!(map.get(3), eq(None));
|
||||
assert_that!(map.size(), eq(1));
|
||||
|
||||
assert_that!(map.remove(1), eq(Some(2)));
|
||||
assert_that!(map.remove(1), eq(true));
|
||||
assert_that!(map.size(), eq(0));
|
||||
assert_that!(map.remove(1), eq(None));
|
||||
assert_that!(map.remove(1), eq(false));
|
||||
|
||||
assert_that!(map.insert(4, 5), eq(true));
|
||||
assert_that!(map.insert(6, 7), eq(true));
|
||||
|
@ -525,13 +512,61 @@ mod tests {
|
|||
assert_that!(map.get(3), eq(None));
|
||||
assert_that!(map.size(), eq(1));
|
||||
|
||||
assert_that!(map.remove(1), eq(Some(2.5)));
|
||||
assert_that!(map.remove(1), eq(true));
|
||||
assert_that!(map.size(), eq(0));
|
||||
assert_that!(map.remove(1), eq(None));
|
||||
assert_that!(map.remove(1), eq(false));
|
||||
|
||||
assert_that!(map.insert(4, 5.1), eq(true));
|
||||
assert_that!(map.insert(6, 7.2), eq(true));
|
||||
map.clear();
|
||||
assert_that!(map.size(), eq(0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn str_str_map() {
|
||||
let mut map = MapInner::<'_, ProtoStr, ProtoStr>::default();
|
||||
assert_that!(map.size(), eq(0));
|
||||
|
||||
map.insert("fizz".into(), "buzz".into());
|
||||
assert_that!(map.size(), eq(1));
|
||||
assert_that!(map.remove("fizz".into()), eq(true));
|
||||
map.clear();
|
||||
assert_that!(map.size(), eq(0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn u64_str_map() {
|
||||
let mut map = MapInner::<'_, u64, ProtoStr>::default();
|
||||
assert_that!(map.size(), eq(0));
|
||||
|
||||
map.insert(1, "fizz".into());
|
||||
map.insert(2, "buzz".into());
|
||||
assert_that!(map.size(), eq(2));
|
||||
assert_that!(map.remove(1), eq(true));
|
||||
assert_that!(map.get(1), eq(None));
|
||||
map.clear();
|
||||
assert_that!(map.size(), eq(0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_all_maps_can_be_constructed() {
|
||||
macro_rules! gen_proto_values {
|
||||
($key_t:ty, $($value_t:ty),*) => {
|
||||
$(
|
||||
let map = MapInner::<'_, $key_t, $value_t>::default();
|
||||
assert_that!(map.size(), eq(0));
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! gen_proto_keys {
|
||||
($($key_t:ty),*) => {
|
||||
$(
|
||||
gen_proto_values!($key_t, f32, f64, i32, u32, i64, bool, ProtoStr);
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
gen_proto_keys!(i32, u32, i64, u64, bool, ProtoStr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ cc_library(
|
|||
],
|
||||
deps = [
|
||||
":rust_alloc_for_cpp_api", # buildcleaner: keep
|
||||
"@com_google_absl//absl/strings:string_view",
|
||||
"//:protobuf_nowkt",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
#include "rust/cpp_kernel/cpp_api.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "google/protobuf/map.h"
|
||||
#include "google/protobuf/repeated_field.h"
|
||||
|
||||
|
@ -7,6 +12,10 @@ extern "C" {
|
|||
google::protobuf::RepeatedField<ty>* __pb_rust_RepeatedField_##rust_ty##_new() { \
|
||||
return new google::protobuf::RepeatedField<ty>(); \
|
||||
} \
|
||||
void __pb_rust_RepeatedField_##rust_ty##_free( \
|
||||
google::protobuf::RepeatedField<ty>* r) { \
|
||||
delete r; \
|
||||
} \
|
||||
void __pb_rust_RepeatedField_##rust_ty##_add(google::protobuf::RepeatedField<ty>* r, \
|
||||
ty val) { \
|
||||
r->Add(val); \
|
||||
|
@ -26,6 +35,10 @@ extern "C" {
|
|||
void __pb_rust_RepeatedField_##rust_ty##_copy_from( \
|
||||
google::protobuf::RepeatedField<ty> const& src, google::protobuf::RepeatedField<ty>& dst) { \
|
||||
dst.CopyFrom(src); \
|
||||
} \
|
||||
void __pb_rust_RepeatedField_##rust_ty##_clear( \
|
||||
google::protobuf::RepeatedField<ty>* r) { \
|
||||
r->Clear(); \
|
||||
}
|
||||
|
||||
expose_repeated_field_methods(int32_t, i32);
|
||||
|
@ -38,59 +51,74 @@ expose_repeated_field_methods(int64_t, i64);
|
|||
|
||||
#undef expose_repeated_field_methods
|
||||
|
||||
#define expose_scalar_map_methods(key_ty, rust_key_ty, value_ty, \
|
||||
rust_value_ty) \
|
||||
google::protobuf::Map<key_ty, value_ty>* \
|
||||
__pb_rust_Map_##rust_key_ty##_##rust_value_ty##_new() { \
|
||||
return new google::protobuf::Map<key_ty, value_ty>(); \
|
||||
} \
|
||||
void __pb_rust_Map_##rust_key_ty##_##rust_value_ty##_clear( \
|
||||
google::protobuf::Map<key_ty, value_ty>* m) { \
|
||||
m->clear(); \
|
||||
} \
|
||||
size_t __pb_rust_Map_##rust_key_ty##_##rust_value_ty##_size( \
|
||||
google::protobuf::Map<key_ty, value_ty>* m) { \
|
||||
return m->size(); \
|
||||
} \
|
||||
void __pb_rust_Map_##rust_key_ty##_##rust_value_ty##_insert( \
|
||||
google::protobuf::Map<key_ty, value_ty>* m, key_ty key, value_ty val) { \
|
||||
(*m)[key] = val; \
|
||||
} \
|
||||
bool __pb_rust_Map_##rust_key_ty##_##rust_value_ty##_get( \
|
||||
google::protobuf::Map<key_ty, value_ty>* m, key_ty key, value_ty* value) { \
|
||||
auto it = m->find(key); \
|
||||
if (it == m->end()) { \
|
||||
return false; \
|
||||
} \
|
||||
*value = it->second; \
|
||||
return true; \
|
||||
} \
|
||||
bool __pb_rust_Map_##rust_key_ty##_##rust_value_ty##_remove( \
|
||||
google::protobuf::Map<key_ty, value_ty>* m, key_ty key, value_ty* value) { \
|
||||
auto it = m->find(key); \
|
||||
if (it == m->end()) { \
|
||||
return false; \
|
||||
} else { \
|
||||
*value = it->second; \
|
||||
m->erase(it); \
|
||||
return true; \
|
||||
} \
|
||||
#define expose_scalar_map_methods(key_ty, rust_key_ty, ffi_key_ty, to_cpp_key, \
|
||||
value_ty, rust_value_ty, ffi_value_ty, \
|
||||
to_cpp_value, to_ffi_value) \
|
||||
google::protobuf::Map<key_ty, value_ty>* \
|
||||
__pb_rust_Map_##rust_key_ty##_##rust_value_ty##_new() { \
|
||||
return new google::protobuf::Map<key_ty, value_ty>(); \
|
||||
} \
|
||||
void __pb_rust_Map_##rust_key_ty##_##rust_value_ty##_clear( \
|
||||
google::protobuf::Map<key_ty, value_ty>* m) { \
|
||||
m->clear(); \
|
||||
} \
|
||||
size_t __pb_rust_Map_##rust_key_ty##_##rust_value_ty##_size( \
|
||||
google::protobuf::Map<key_ty, value_ty>* m) { \
|
||||
return m->size(); \
|
||||
} \
|
||||
void __pb_rust_Map_##rust_key_ty##_##rust_value_ty##_insert( \
|
||||
google::protobuf::Map<key_ty, value_ty>* m, ffi_key_ty key, ffi_value_ty value) { \
|
||||
auto cpp_key = to_cpp_key; \
|
||||
auto cpp_value = to_cpp_value; \
|
||||
(*m)[cpp_key] = cpp_value; \
|
||||
} \
|
||||
bool __pb_rust_Map_##rust_key_ty##_##rust_value_ty##_get( \
|
||||
google::protobuf::Map<key_ty, value_ty>* m, ffi_key_ty key, ffi_value_ty* value) { \
|
||||
auto cpp_key = to_cpp_key; \
|
||||
auto it = m->find(cpp_key); \
|
||||
if (it == m->end()) { \
|
||||
return false; \
|
||||
} \
|
||||
auto& cpp_value = it->second; \
|
||||
*value = to_ffi_value; \
|
||||
return true; \
|
||||
} \
|
||||
bool __pb_rust_Map_##rust_key_ty##_##rust_value_ty##_remove( \
|
||||
google::protobuf::Map<key_ty, value_ty>* m, ffi_key_ty key, ffi_value_ty* value) { \
|
||||
auto cpp_key = to_cpp_key; \
|
||||
auto num_removed = m->erase(cpp_key); \
|
||||
return num_removed > 0; \
|
||||
}
|
||||
|
||||
#define expose_scalar_map_methods_for_key_type(key_ty, rust_key_ty) \
|
||||
expose_scalar_map_methods(key_ty, rust_key_ty, int32_t, i32); \
|
||||
expose_scalar_map_methods(key_ty, rust_key_ty, uint32_t, u32); \
|
||||
expose_scalar_map_methods(key_ty, rust_key_ty, float, f32); \
|
||||
expose_scalar_map_methods(key_ty, rust_key_ty, double, f64); \
|
||||
expose_scalar_map_methods(key_ty, rust_key_ty, bool, bool); \
|
||||
expose_scalar_map_methods(key_ty, rust_key_ty, uint64_t, u64); \
|
||||
expose_scalar_map_methods(key_ty, rust_key_ty, int64_t, i64);
|
||||
#define expose_scalar_map_methods_for_key_type(key_ty, rust_key_ty, \
|
||||
ffi_key_ty, to_cpp_key) \
|
||||
expose_scalar_map_methods(key_ty, rust_key_ty, ffi_key_ty, to_cpp_key, \
|
||||
int32_t, i32, int32_t, value, cpp_value); \
|
||||
expose_scalar_map_methods(key_ty, rust_key_ty, ffi_key_ty, to_cpp_key, \
|
||||
uint32_t, u32, uint32_t, value, cpp_value); \
|
||||
expose_scalar_map_methods(key_ty, rust_key_ty, ffi_key_ty, to_cpp_key, \
|
||||
float, f32, float, value, cpp_value); \
|
||||
expose_scalar_map_methods(key_ty, rust_key_ty, ffi_key_ty, to_cpp_key, \
|
||||
double, f64, double, value, cpp_value); \
|
||||
expose_scalar_map_methods(key_ty, rust_key_ty, ffi_key_ty, to_cpp_key, bool, \
|
||||
bool, bool, value, cpp_value); \
|
||||
expose_scalar_map_methods(key_ty, rust_key_ty, ffi_key_ty, to_cpp_key, \
|
||||
uint64_t, u64, uint64_t, value, cpp_value); \
|
||||
expose_scalar_map_methods(key_ty, rust_key_ty, ffi_key_ty, to_cpp_key, \
|
||||
int64_t, i64, int64_t, value, cpp_value); \
|
||||
expose_scalar_map_methods( \
|
||||
key_ty, rust_key_ty, ffi_key_ty, to_cpp_key, std::string, ProtoStr, \
|
||||
google::protobuf::rust_internal::PtrAndLen, std::string(value.ptr, value.len), \
|
||||
google::protobuf::rust_internal::PtrAndLen(cpp_value.data(), cpp_value.size()));
|
||||
|
||||
expose_scalar_map_methods_for_key_type(int32_t, i32);
|
||||
expose_scalar_map_methods_for_key_type(uint32_t, u32);
|
||||
expose_scalar_map_methods_for_key_type(bool, bool);
|
||||
expose_scalar_map_methods_for_key_type(uint64_t, u64);
|
||||
expose_scalar_map_methods_for_key_type(int64_t, i64);
|
||||
expose_scalar_map_methods_for_key_type(int32_t, i32, int32_t, key);
|
||||
expose_scalar_map_methods_for_key_type(uint32_t, u32, uint32_t, key);
|
||||
expose_scalar_map_methods_for_key_type(bool, bool, bool, key);
|
||||
expose_scalar_map_methods_for_key_type(uint64_t, u64, uint64_t, key);
|
||||
expose_scalar_map_methods_for_key_type(int64_t, i64, int64_t, key);
|
||||
expose_scalar_map_methods_for_key_type(std::string, ProtoStr,
|
||||
google::protobuf::rust_internal::PtrAndLen,
|
||||
std::string(key.ptr, key.len));
|
||||
|
||||
#undef expose_scalar_map_methods
|
||||
#undef expose_map_methods
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
pub use crate::vtable::{
|
||||
new_vtable_field_entry, BytesMutVTable, BytesOptionalMutVTable, PrimitiveOptionalMutVTable,
|
||||
PrimitiveVTable, RawVTableMutator,
|
||||
PrimitiveVTable, PrimitiveWithRawVTable, RawVTableMutator,
|
||||
};
|
||||
use std::ptr::NonNull;
|
||||
use std::slice;
|
||||
|
|
253
rust/map.rs
253
rust/map.rs
|
@ -6,32 +6,38 @@
|
|||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
use crate::{
|
||||
Mut, MutProxy, Proxied, SettableValue, View, ViewProxy,
|
||||
Mut, MutProxy, ProtoStr, Proxied, SettableValue, View, ViewProxy,
|
||||
__internal::Private,
|
||||
__runtime::{
|
||||
MapInner, MapWithBoolKeyOps, MapWithI32KeyOps, MapWithI64KeyOps, MapWithU32KeyOps,
|
||||
MapWithU64KeyOps,
|
||||
MapInner, MapWithBoolKeyOps, MapWithI32KeyOps, MapWithI64KeyOps, MapWithProtoStrKeyOps,
|
||||
MapWithU32KeyOps, MapWithU64KeyOps,
|
||||
},
|
||||
};
|
||||
use paste::paste;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(transparent)]
|
||||
pub struct MapView<'a, K: ?Sized, V: ?Sized> {
|
||||
inner: MapInner<'a, K, V>,
|
||||
pub struct MapView<'msg, K: ?Sized, V: ?Sized> {
|
||||
inner: MapInner<'msg, K, V>,
|
||||
}
|
||||
|
||||
impl<'a, K: ?Sized, V: ?Sized> MapView<'a, K, V> {
|
||||
pub fn from_inner(_private: Private, inner: MapInner<'a, K, V>) -> Self {
|
||||
impl<'msg, K: ?Sized, V: ?Sized> MapView<'msg, K, V> {
|
||||
pub fn from_inner(_private: Private, inner: MapInner<'msg, K, V>) -> Self {
|
||||
Self { inner }
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<'a, K: ?Sized, V: ?Sized> Sync for MapView<'a, K, V> {}
|
||||
unsafe impl<'a, K: ?Sized, V: ?Sized> Send for MapView<'a, K, V> {}
|
||||
impl<'msg, K: ?Sized, V: ?Sized> Copy for MapView<'msg, K, V> {}
|
||||
impl<'msg, K: ?Sized, V: ?Sized> Clone for MapView<'msg, K, V> {
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K: ?Sized, V: ?Sized> std::fmt::Debug for MapView<'a, K, V> {
|
||||
unsafe impl<'msg, K: ?Sized, V: ?Sized> Sync for MapView<'msg, K, V> {}
|
||||
unsafe impl<'msg, K: ?Sized, V: ?Sized> Send for MapView<'msg, K, V> {}
|
||||
|
||||
impl<'msg, K: ?Sized, V: ?Sized> std::fmt::Debug for MapView<'msg, K, V> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_tuple("MapView")
|
||||
.field(&std::any::type_name::<K>())
|
||||
|
@ -40,28 +46,36 @@ impl<'a, K: ?Sized, V: ?Sized> std::fmt::Debug for MapView<'a, K, V> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[repr(transparent)]
|
||||
pub struct MapMut<'a, K: ?Sized, V: ?Sized> {
|
||||
inner: MapInner<'a, K, V>,
|
||||
pub struct MapMut<'msg, K: ?Sized, V: ?Sized> {
|
||||
inner: MapInner<'msg, K, V>,
|
||||
}
|
||||
|
||||
impl<'a, K: ?Sized, V: ?Sized> MapMut<'a, K, V> {
|
||||
pub fn from_inner(_private: Private, inner: MapInner<'a, K, V>) -> Self {
|
||||
impl<'msg, K: ?Sized, V: ?Sized> MapMut<'msg, K, V> {
|
||||
pub fn from_inner(_private: Private, inner: MapInner<'msg, K, V>) -> Self {
|
||||
Self { inner }
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<'a, K: ?Sized, V: ?Sized> Sync for MapMut<'a, K, V> {}
|
||||
unsafe impl<'msg, K: ?Sized, V: ?Sized> Sync for MapMut<'msg, K, V> {}
|
||||
|
||||
impl<'a, K: ?Sized, V: ?Sized> std::ops::Deref for MapMut<'a, K, V> {
|
||||
type Target = MapView<'a, K, V>;
|
||||
impl<'msg, K: ?Sized, V: ?Sized> std::fmt::Debug for MapMut<'msg, K, V> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_tuple("MapMut")
|
||||
.field(&std::any::type_name::<K>())
|
||||
.field(&std::any::type_name::<V>())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'msg, K: ?Sized, V: ?Sized> std::ops::Deref for MapMut<'msg, K, V> {
|
||||
type Target = MapView<'msg, K, V>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
// SAFETY:
|
||||
// - `Map{View,Mut}<'a, T>` are both `#[repr(transparent)]` over `MapInner<'a,
|
||||
// T>`.
|
||||
// - `Map{View,Mut}<'msg, T>` are both `#[repr(transparent)]` over
|
||||
// `MapInner<'msg, T>`.
|
||||
// - `MapInner` is a type alias for `NonNull`.
|
||||
unsafe { &*(self as *const Self as *const MapView<'a, K, V>) }
|
||||
unsafe { &*(self as *const Self as *const MapView<'msg, K, V>) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,64 +83,79 @@ impl<'a, K: ?Sized, V: ?Sized> std::ops::Deref for MapMut<'a, K, V> {
|
|||
// `MapView` (`View<'_, Map>>) and `MapMut` (Mut<'_, Map>).
|
||||
pub struct Map<K: ?Sized, V: ?Sized>(PhantomData<K>, PhantomData<V>);
|
||||
|
||||
macro_rules! impl_proxied_for_map_keys {
|
||||
($(key_type $t:ty;)*) => {
|
||||
paste! { $(
|
||||
impl<V: [< MapWith $t:camel KeyOps >] + Proxied + ?Sized> Proxied for Map<$t, V>{
|
||||
type View<'msg> = MapView<'msg, $t, V> where V: 'msg;
|
||||
type Mut<'msg> = MapMut<'msg, $t, V> where V: 'msg;
|
||||
}
|
||||
|
||||
impl<'msg, V: [< MapWith $t:camel KeyOps >] + Proxied + ?Sized + 'msg> SettableValue<Map<$t, V>> for MapView<'msg, $t, V> {
|
||||
fn set_on<'b>(self, _private: Private, mut mutator: Mut<'b, Map<$t, V>>)
|
||||
where
|
||||
Map<$t, V>: 'b {
|
||||
mutator.copy_from(self);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'msg, V: [< MapWith $t:camel KeyOps >] + Proxied + ?Sized + 'msg> ViewProxy<'msg> for MapView<'msg, $t, V> {
|
||||
type Proxied = Map<$t, V>;
|
||||
|
||||
fn as_view(&self) -> View<'_, Self::Proxied> {
|
||||
*self
|
||||
}
|
||||
|
||||
fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied>
|
||||
where 'msg: 'shorter,
|
||||
{
|
||||
MapView { inner: self.inner }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'msg, V: [< MapWith $t:camel KeyOps >] + Proxied + ?Sized + 'msg> ViewProxy<'msg> for MapMut<'msg, $t, V> {
|
||||
type Proxied = Map<$t, V>;
|
||||
|
||||
fn as_view(&self) -> View<'_, Self::Proxied> {
|
||||
**self
|
||||
}
|
||||
|
||||
fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied>
|
||||
where 'msg: 'shorter,
|
||||
{
|
||||
*self.into_mut::<'shorter>()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'msg, V: [< MapWith $t:camel KeyOps >] + Proxied + ?Sized + 'msg> MutProxy<'msg> for MapMut<'msg, $t, V> {
|
||||
fn as_mut(&mut self) -> Mut<'_, Self::Proxied> {
|
||||
MapMut { inner: self.inner }
|
||||
}
|
||||
|
||||
fn into_mut<'shorter>(self) -> Mut<'shorter, Self::Proxied>
|
||||
where 'msg: 'shorter,
|
||||
{
|
||||
MapMut { inner: self.inner }
|
||||
}
|
||||
}
|
||||
)* }
|
||||
}
|
||||
}
|
||||
|
||||
impl_proxied_for_map_keys!(
|
||||
key_type i32;
|
||||
key_type u32;
|
||||
key_type i64;
|
||||
key_type u64;
|
||||
key_type bool;
|
||||
key_type ProtoStr;
|
||||
);
|
||||
|
||||
macro_rules! impl_scalar_map_keys {
|
||||
($(key_type $t:ty;)*) => {
|
||||
paste! { $(
|
||||
impl<V: [< MapWith $t:camel KeyOps >]> Proxied for Map<$t, V>{
|
||||
type View<'a> = MapView<'a, $t, V> where V: 'a;
|
||||
type Mut<'a> = MapMut<'a, $t, V> where V: 'a;
|
||||
}
|
||||
|
||||
impl<'a, V: [< MapWith $t:camel KeyOps >]> SettableValue<Map<$t, V>> for MapView<'a, $t, V> {
|
||||
fn set_on<'b>(self, _private: Private, mut mutator: Mut<'b, Map<$t, V>>)
|
||||
where
|
||||
Map<$t, V>: 'b {
|
||||
mutator.copy_from(self);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, V: [< MapWith $t:camel KeyOps >]> ViewProxy<'a> for MapView<'a, $t, V> {
|
||||
type Proxied = Map<$t, V>;
|
||||
|
||||
fn as_view(&self) -> View<'_, Self::Proxied> {
|
||||
*self
|
||||
}
|
||||
|
||||
fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied>
|
||||
where 'a: 'shorter,
|
||||
{
|
||||
MapView { inner: self.inner }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, V: [< MapWith $t:camel KeyOps >]> ViewProxy<'a> for MapMut<'a, $t, V> {
|
||||
type Proxied = Map<$t, V>;
|
||||
|
||||
fn as_view(&self) -> View<'_, Self::Proxied> {
|
||||
**self
|
||||
}
|
||||
|
||||
fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied>
|
||||
where 'a: 'shorter,
|
||||
{
|
||||
*self.into_mut::<'shorter>()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, V: [< MapWith $t:camel KeyOps >]> MutProxy<'a> for MapMut<'a, $t, V> {
|
||||
fn as_mut(&mut self) -> Mut<'_, Self::Proxied> {
|
||||
MapMut { inner: self.inner }
|
||||
}
|
||||
|
||||
fn into_mut<'shorter>(self) -> Mut<'shorter, Self::Proxied>
|
||||
where 'a: 'shorter,
|
||||
{
|
||||
MapMut { inner: self.inner }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, V: [< MapWith $t:camel KeyOps >]> MapView<'a, $t, V> {
|
||||
pub fn get(&self, key: $t) -> Option<V> {
|
||||
impl<'msg, V: [< MapWith $t:camel KeyOps >] + Proxied + ?Sized + 'msg> MapView<'msg, $t, V> {
|
||||
pub fn get<'b>(&self, key: $t) -> Option<V::Value<'b>> {
|
||||
self.inner.get(key)
|
||||
}
|
||||
|
||||
|
@ -139,12 +168,12 @@ macro_rules! impl_scalar_map_keys {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, V: [< MapWith $t:camel KeyOps >]> MapMut<'a, $t, V> {
|
||||
pub fn insert(&mut self, key: $t, value: V) -> bool {
|
||||
impl<'msg, V: [< MapWith $t:camel KeyOps >] + Proxied + ?Sized + 'msg> MapMut<'msg, $t, V> {
|
||||
pub fn insert(&mut self, key: $t, value: V::Value<'_>) -> bool {
|
||||
self.inner.insert(key, value)
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, key: $t) -> Option<V> {
|
||||
pub fn remove<'b>(&mut self, key: $t) -> bool {
|
||||
self.inner.remove(key)
|
||||
}
|
||||
|
||||
|
@ -168,15 +197,47 @@ impl_scalar_map_keys!(
|
|||
key_type bool;
|
||||
);
|
||||
|
||||
impl<'msg, V: MapWithProtoStrKeyOps + Proxied + ?Sized + 'msg> MapView<'msg, ProtoStr, V> {
|
||||
pub fn get(&self, key: impl Into<&'msg ProtoStr>) -> Option<V::Value<'_>> {
|
||||
self.inner.get(key.into())
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.inner.size()
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'msg, V: MapWithProtoStrKeyOps + Proxied + ?Sized + 'msg> MapMut<'msg, ProtoStr, V> {
|
||||
pub fn insert(&mut self, key: impl Into<&'msg ProtoStr>, value: V::Value<'_>) -> bool {
|
||||
self.inner.insert(key.into(), value)
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, key: impl Into<&'msg ProtoStr>) -> bool {
|
||||
self.inner.remove(key.into())
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
self.inner.clear()
|
||||
}
|
||||
|
||||
pub fn copy_from(&mut self, _src: MapView<'_, ProtoStr, V>) {
|
||||
todo!("implement b/28530933");
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::__runtime::new_map_inner;
|
||||
use crate::__runtime::{new_map_i32_i64, new_map_str_str};
|
||||
use googletest::prelude::*;
|
||||
|
||||
#[test]
|
||||
fn test_proxied() {
|
||||
let mut map_mut = MapMut::from_inner(Private, new_map_inner());
|
||||
fn test_proxied_scalar() {
|
||||
let mut map_mut = MapMut::from_inner(Private, new_map_i32_i64());
|
||||
map_mut.insert(1, 2);
|
||||
let map_view_1 = map_mut.as_view();
|
||||
assert_that!(map_view_1.len(), eq(1));
|
||||
|
@ -197,9 +258,33 @@ mod tests {
|
|||
assert_that!(map_view_4.is_empty(), eq(false));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_proxied_str() {
|
||||
let mut map_mut = MapMut::from_inner(Private, new_map_str_str());
|
||||
map_mut.insert("a", "b".into());
|
||||
|
||||
let map_view_1 = map_mut.as_view();
|
||||
assert_that!(map_view_1.len(), eq(1));
|
||||
assert_that!(map_view_1.get("a").unwrap(), eq("b"));
|
||||
|
||||
map_mut.insert("c", "d".into());
|
||||
|
||||
let map_view_2 = map_mut.into_view();
|
||||
assert_that!(map_view_2.len(), eq(2));
|
||||
assert_that!(map_view_2.get("c").unwrap(), eq("d"));
|
||||
|
||||
{
|
||||
let map_view_3 = map_view_2.as_view();
|
||||
assert_that!(map_view_3.is_empty(), eq(false));
|
||||
}
|
||||
|
||||
let map_view_4 = map_view_2.into_view();
|
||||
assert_that!(map_view_4.is_empty(), eq(false));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dbg() {
|
||||
let mut map_view = MapView::from_inner(Private, new_map_inner());
|
||||
let map_view = MapView::from_inner(Private, new_map_i32_i64());
|
||||
assert_that!(format!("{:?}", map_view), eq("MapView(\"i32\", \"i64\")"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ impl<T> From<Optional<T>> for Option<T> {
|
|||
|
||||
/// A mutable view into the value of an optional field, which may be set or
|
||||
/// unset.
|
||||
pub type FieldEntry<'a, T> = Optional<PresentField<'a, T>, AbsentField<'a, T>>;
|
||||
pub type FieldEntry<'msg, T> = Optional<PresentField<'msg, T>, AbsentField<'msg, T>>;
|
||||
|
||||
/// Methods for `_mut()` accessors of optional types.
|
||||
///
|
||||
|
@ -285,11 +285,11 @@ where
|
|||
|
||||
/// A field mutator capable of setting that is statically known to point to a
|
||||
/// non-set field.
|
||||
pub struct AbsentField<'a, T>
|
||||
pub struct AbsentField<'msg, T>
|
||||
where
|
||||
T: ProxiedWithPresence + ?Sized + 'a,
|
||||
T: ProxiedWithPresence + ?Sized + 'msg,
|
||||
{
|
||||
pub(crate) inner: T::AbsentMutData<'a>,
|
||||
pub(crate) inner: T::AbsentMutData<'msg>,
|
||||
}
|
||||
|
||||
impl<'msg, T: ProxiedWithPresence + ?Sized + 'msg> Debug for AbsentField<'msg, T> {
|
||||
|
@ -432,10 +432,10 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
fn make_field_entry<'a>(
|
||||
msg: &'a mut MyMessage,
|
||||
vtable: &'a ProxyVtable,
|
||||
) -> FieldEntry<'a, VtableProxied> {
|
||||
fn make_field_entry<'msg>(
|
||||
msg: &'msg mut MyMessage,
|
||||
vtable: &'msg ProxyVtable,
|
||||
) -> FieldEntry<'msg, VtableProxied> {
|
||||
if (vtable.has)(&*msg) {
|
||||
Optional::Set(PresentField::from_inner(Private, VtableProxiedMut { msg, vtable }))
|
||||
} else {
|
||||
|
@ -494,8 +494,8 @@ mod tests {
|
|||
struct VtableProxied;
|
||||
|
||||
impl Proxied for VtableProxied {
|
||||
type View<'a> = VtableProxiedView;
|
||||
type Mut<'a> = VtableProxiedMut<'a>;
|
||||
type View<'msg> = VtableProxiedView;
|
||||
type Mut<'msg> = VtableProxiedMut<'msg>;
|
||||
}
|
||||
|
||||
impl ProxiedWithPresence for VtableProxied {
|
||||
|
@ -503,19 +503,19 @@ mod tests {
|
|||
// `Mut` in layout. Other types/runtimes could require otherwise, e.g. `Mut`
|
||||
// could be defined to only have get/set functions in its vtable, and not
|
||||
// has/clear.
|
||||
type PresentMutData<'a> = VtableProxiedMut<'a>;
|
||||
type AbsentMutData<'a> = VtableProxiedMut<'a>;
|
||||
type PresentMutData<'msg> = VtableProxiedMut<'msg>;
|
||||
type AbsentMutData<'msg> = VtableProxiedMut<'msg>;
|
||||
|
||||
fn clear_present_field<'a>(
|
||||
present_mutator: Self::PresentMutData<'a>,
|
||||
) -> Self::AbsentMutData<'a> {
|
||||
fn clear_present_field<'msg>(
|
||||
present_mutator: Self::PresentMutData<'msg>,
|
||||
) -> Self::AbsentMutData<'msg> {
|
||||
(present_mutator.vtable.clear)(&mut *present_mutator.msg);
|
||||
present_mutator
|
||||
}
|
||||
|
||||
fn set_absent_to_default<'a>(
|
||||
absent_mutator: Self::AbsentMutData<'a>,
|
||||
) -> Self::PresentMutData<'a> {
|
||||
fn set_absent_to_default<'msg>(
|
||||
absent_mutator: Self::AbsentMutData<'msg>,
|
||||
) -> Self::PresentMutData<'msg> {
|
||||
SettableValue::<VtableProxied>::set_on_absent(
|
||||
absent_mutator.as_view().val(),
|
||||
Private,
|
||||
|
@ -539,28 +539,28 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ViewProxy<'a> for VtableProxiedView {
|
||||
impl<'msg> ViewProxy<'msg> for VtableProxiedView {
|
||||
type Proxied = VtableProxied;
|
||||
|
||||
fn as_view(&self) -> View<'a, VtableProxied> {
|
||||
fn as_view(&self) -> View<'msg, VtableProxied> {
|
||||
*self
|
||||
}
|
||||
|
||||
fn into_view<'shorter>(self) -> View<'shorter, VtableProxied>
|
||||
where
|
||||
'a: 'shorter,
|
||||
'msg: 'shorter,
|
||||
{
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct VtableProxiedMut<'a> {
|
||||
msg: &'a mut MyMessage,
|
||||
vtable: &'a ProxyVtable,
|
||||
struct VtableProxiedMut<'msg> {
|
||||
msg: &'msg mut MyMessage,
|
||||
vtable: &'msg ProxyVtable,
|
||||
}
|
||||
|
||||
impl<'a> ViewProxy<'a> for VtableProxiedMut<'a> {
|
||||
impl<'msg> ViewProxy<'msg> for VtableProxiedMut<'msg> {
|
||||
type Proxied = VtableProxied;
|
||||
|
||||
fn as_view(&self) -> View<'_, VtableProxied> {
|
||||
|
@ -569,55 +569,55 @@ mod tests {
|
|||
|
||||
fn into_view<'shorter>(self) -> View<'shorter, VtableProxied>
|
||||
where
|
||||
'a: 'shorter,
|
||||
'msg: 'shorter,
|
||||
{
|
||||
VtableProxiedView::read(self.msg, self.vtable)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> MutProxy<'a> for VtableProxiedMut<'a> {
|
||||
impl<'msg> MutProxy<'msg> for VtableProxiedMut<'msg> {
|
||||
fn as_mut(&mut self) -> Mut<'_, VtableProxied> {
|
||||
VtableProxiedMut { msg: self.msg, vtable: self.vtable }
|
||||
}
|
||||
|
||||
fn into_mut<'shorter>(self) -> Mut<'shorter, VtableProxied>
|
||||
where
|
||||
'a: 'shorter,
|
||||
'msg: 'shorter,
|
||||
{
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl SettableValue<VtableProxied> for View<'_, VtableProxied> {
|
||||
fn set_on<'a>(self, _private: Private, mutator: Mut<'a, VtableProxied>)
|
||||
fn set_on<'msg>(self, _private: Private, mutator: Mut<'msg, VtableProxied>)
|
||||
where
|
||||
VtableProxied: 'a,
|
||||
VtableProxied: 'msg,
|
||||
{
|
||||
SettableValue::<VtableProxied>::set_on(self.val(), Private, mutator)
|
||||
}
|
||||
|
||||
fn set_on_absent<'a>(
|
||||
fn set_on_absent<'msg>(
|
||||
self,
|
||||
_private: Private,
|
||||
absent_mutator: <VtableProxied as ProxiedWithPresence>::AbsentMutData<'a>,
|
||||
) -> <VtableProxied as ProxiedWithPresence>::PresentMutData<'a> {
|
||||
absent_mutator: <VtableProxied as ProxiedWithPresence>::AbsentMutData<'msg>,
|
||||
) -> <VtableProxied as ProxiedWithPresence>::PresentMutData<'msg> {
|
||||
SettableValue::<VtableProxied>::set_on_absent(self.val(), Private, absent_mutator)
|
||||
}
|
||||
}
|
||||
|
||||
impl SettableValue<VtableProxied> for i32 {
|
||||
fn set_on<'a>(self, _private: Private, mutator: Mut<'a, VtableProxied>)
|
||||
fn set_on<'msg>(self, _private: Private, mutator: Mut<'msg, VtableProxied>)
|
||||
where
|
||||
VtableProxied: 'a,
|
||||
VtableProxied: 'msg,
|
||||
{
|
||||
(mutator.vtable.set)(mutator.msg, self)
|
||||
}
|
||||
|
||||
fn set_on_absent<'a>(
|
||||
fn set_on_absent<'msg>(
|
||||
self,
|
||||
_private: Private,
|
||||
absent_mutator: <VtableProxied as ProxiedWithPresence>::AbsentMutData<'a>,
|
||||
) -> <VtableProxied as ProxiedWithPresence>::PresentMutData<'a> {
|
||||
absent_mutator: <VtableProxied as ProxiedWithPresence>::AbsentMutData<'msg>,
|
||||
) -> <VtableProxied as ProxiedWithPresence>::PresentMutData<'msg> {
|
||||
(absent_mutator.vtable.set)(absent_mutator.msg, self);
|
||||
absent_mutator
|
||||
}
|
||||
|
|
|
@ -5,156 +5,116 @@
|
|||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
use crate::__internal::Private;
|
||||
use crate::__runtime::InnerPrimitiveMut;
|
||||
use crate::repeated::RepeatedMut;
|
||||
use crate::vtable::{
|
||||
PrimitiveOptionalMutVTable, PrimitiveVTable, ProxiedWithRawOptionalVTable,
|
||||
ProxiedWithRawVTable, RawVTableOptionalMutatorData,
|
||||
};
|
||||
use crate::vtable::{PrimitiveWithRawVTable, ProxiedWithRawVTable, RawVTableOptionalMutatorData};
|
||||
use crate::{Mut, MutProxy, Proxied, ProxiedWithPresence, SettableValue, View, ViewProxy};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SingularPrimitiveMut<'a, T: ProxiedWithRawVTable> {
|
||||
inner: InnerPrimitiveMut<'a, T>,
|
||||
/// A mutator for a primitive (numeric or enum) value of `T`.
|
||||
///
|
||||
/// This type is `protobuf::Mut<'msg, T>`.
|
||||
pub struct PrimitiveMut<'msg, T> {
|
||||
inner: InnerPrimitiveMut<'msg, T>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum PrimitiveMut<'a, T: ProxiedWithRawVTable> {
|
||||
Singular(SingularPrimitiveMut<'a, T>),
|
||||
Repeated(RepeatedMut<'a, T>, usize),
|
||||
}
|
||||
|
||||
impl<'a, T: ProxiedWithRawVTable> PrimitiveMut<'a, T> {
|
||||
#[doc(hidden)]
|
||||
pub fn from_singular(_private: Private, inner: InnerPrimitiveMut<'a, T>) -> Self {
|
||||
PrimitiveMut::Singular(SingularPrimitiveMut::from_inner(_private, inner))
|
||||
impl<'msg, T> Debug for PrimitiveMut<'msg, T>
|
||||
where
|
||||
T: PrimitiveWithRawVTable,
|
||||
{
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("PrimitiveMut").field("inner", &self.inner).finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ProxiedWithRawVTable> SingularPrimitiveMut<'a, T> {
|
||||
impl<'msg, T> PrimitiveMut<'msg, T> {
|
||||
/// # Safety
|
||||
/// `inner` must be valid and non-aliased for `T` for `'msg`
|
||||
#[doc(hidden)]
|
||||
pub fn from_inner(_private: Private, inner: InnerPrimitiveMut<'a, T>) -> Self {
|
||||
pub unsafe fn from_inner(_private: Private, inner: InnerPrimitiveMut<'msg, T>) -> Self {
|
||||
Self { inner }
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<'a, T: ProxiedWithRawVTable> Sync for SingularPrimitiveMut<'a, T> {}
|
||||
// SAFETY: all `T` that can perform mutations don't mutate through a shared
|
||||
// reference.
|
||||
unsafe impl<'msg, T> Sync for PrimitiveMut<'msg, T> {}
|
||||
|
||||
impl<'msg, T> PrimitiveMut<'msg, T>
|
||||
where
|
||||
T: PrimitiveWithRawVTable,
|
||||
{
|
||||
pub fn get(&self) -> View<'_, T> {
|
||||
T::make_view(Private, self.inner)
|
||||
}
|
||||
|
||||
pub fn set(&mut self, val: impl SettableValue<T>) {
|
||||
MutProxy::set(self, val)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'msg, T> ViewProxy<'msg> for PrimitiveMut<'msg, T>
|
||||
where
|
||||
T: PrimitiveWithRawVTable,
|
||||
{
|
||||
type Proxied = T;
|
||||
|
||||
fn as_view(&self) -> View<'_, Self::Proxied> {
|
||||
self.get()
|
||||
}
|
||||
|
||||
fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied> {
|
||||
self.get()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'msg, T> MutProxy<'msg> for PrimitiveMut<'msg, T>
|
||||
where
|
||||
T: PrimitiveWithRawVTable,
|
||||
{
|
||||
fn as_mut(&mut self) -> Mut<'_, Self::Proxied> {
|
||||
PrimitiveMut { inner: self.inner }
|
||||
}
|
||||
|
||||
fn into_mut<'shorter>(self) -> Mut<'shorter, Self::Proxied>
|
||||
where
|
||||
'msg: 'shorter,
|
||||
{
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_singular_primitives {
|
||||
($($t:ty),*) => {
|
||||
$(
|
||||
impl Proxied for $t {
|
||||
type View<'a> = $t;
|
||||
type Mut<'a> = PrimitiveMut<'a, $t>;
|
||||
}
|
||||
impl Proxied for $t {
|
||||
type View<'msg> = $t;
|
||||
type Mut<'msg> = PrimitiveMut<'msg, $t>;
|
||||
}
|
||||
|
||||
impl<'a> ViewProxy<'a> for $t {
|
||||
type Proxied = $t;
|
||||
impl<'msg> ViewProxy<'msg> for $t {
|
||||
type Proxied = $t;
|
||||
|
||||
fn as_view(&self) -> View<'_, Self::Proxied> {
|
||||
*self
|
||||
}
|
||||
|
||||
fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied> {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> PrimitiveMut<'a, $t> {
|
||||
pub fn get(&self) -> View<'_, $t> {
|
||||
match self {
|
||||
PrimitiveMut::Singular(s) => {
|
||||
s.get()
|
||||
}
|
||||
PrimitiveMut::Repeated(r, i) => {
|
||||
r.get().get(*i).unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set(&mut self, val: impl SettableValue<$t>) {
|
||||
val.set_on(Private, self.as_mut());
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
// The default value for a boolean field is false and 0 for numerical types. It
|
||||
// matches the Rust default values for corresponding types. Let's use this fact.
|
||||
SettableValue::<$t>::set_on(<$t>::default(), Private, MutProxy::as_mut(self));
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ViewProxy<'a> for PrimitiveMut<'a, $t> {
|
||||
type Proxied = $t;
|
||||
|
||||
fn as_view(&self) -> View<'_, Self::Proxied> {
|
||||
self.get()
|
||||
}
|
||||
|
||||
fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied> {
|
||||
self.get()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> MutProxy<'a> for PrimitiveMut<'a, $t> {
|
||||
fn as_mut(&mut self) -> Mut<'_, Self::Proxied> {
|
||||
match self {
|
||||
PrimitiveMut::Singular(s) => {
|
||||
PrimitiveMut::Singular(s.as_mut())
|
||||
}
|
||||
PrimitiveMut::Repeated(r, i) => {
|
||||
PrimitiveMut::Repeated(r.as_mut(), *i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn into_mut<'shorter>(self) -> Mut<'shorter, Self::Proxied>
|
||||
where 'a: 'shorter,
|
||||
{
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl SettableValue<$t> for $t {
|
||||
fn set_on<'a>(self, _private: Private, mutator: Mut<'a, $t>) where $t: 'a {
|
||||
match mutator {
|
||||
PrimitiveMut::Singular(s) => {
|
||||
unsafe { (s.inner).set(self) };
|
||||
}
|
||||
PrimitiveMut::Repeated(mut r, i) => {
|
||||
r.set(i, self);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SingularPrimitiveMut<'a, $t> {
|
||||
pub fn get(&self) -> $t {
|
||||
self.inner.get()
|
||||
}
|
||||
pub fn as_mut(&mut self) -> SingularPrimitiveMut<'_, $t> {
|
||||
SingularPrimitiveMut::from_inner(Private, self.inner)
|
||||
}
|
||||
}
|
||||
|
||||
impl ProxiedWithRawVTable for $t {
|
||||
type VTable = PrimitiveVTable<$t>;
|
||||
|
||||
fn make_view(
|
||||
_private: Private,
|
||||
mut_inner: InnerPrimitiveMut<'_, Self>
|
||||
) -> View<'_, Self> {
|
||||
mut_inner.get()
|
||||
fn as_view(&self) -> View<'_, Self::Proxied> {
|
||||
*self
|
||||
}
|
||||
|
||||
fn make_mut(_private: Private, inner: InnerPrimitiveMut<'_, Self>) -> Mut<'_, Self> {
|
||||
PrimitiveMut::Singular(SingularPrimitiveMut::from_inner(Private, inner))
|
||||
fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied> {
|
||||
self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ProxiedWithPresence for $t {
|
||||
type PresentMutData<'a> = RawVTableOptionalMutatorData<'a, $t>;
|
||||
type AbsentMutData<'a> = RawVTableOptionalMutatorData<'a, $t>;
|
||||
impl SettableValue<$t> for $t {
|
||||
fn set_on<'msg>(self, _private: Private, mutator: Mut<'msg, $t>) where $t: 'msg {
|
||||
// SAFETY: the raw mutator is valid for `'msg` as enforced by `Mut`
|
||||
unsafe { mutator.inner.set(self) }
|
||||
}
|
||||
}
|
||||
|
||||
impl ProxiedWithPresence for $t {
|
||||
type PresentMutData<'msg> = RawVTableOptionalMutatorData<'msg, $t>;
|
||||
type AbsentMutData<'msg> = RawVTableOptionalMutatorData<'msg, $t>;
|
||||
|
||||
fn clear_present_field(
|
||||
present_mutator: Self::PresentMutData<'_>,
|
||||
|
@ -167,18 +127,11 @@ macro_rules! impl_singular_primitives {
|
|||
) -> Self::PresentMutData<'_> {
|
||||
absent_mutator.set_absent_to_default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ProxiedWithRawOptionalVTable for $t {
|
||||
type OptionalVTable = PrimitiveOptionalMutVTable<$t>;
|
||||
impl PrimitiveWithRawVTable for $t {}
|
||||
|
||||
fn upcast_vtable(
|
||||
_private: Private,
|
||||
optional_vtable: &'static Self::OptionalVTable,
|
||||
) -> &'static Self::VTable {
|
||||
&optional_vtable.base
|
||||
}
|
||||
}
|
||||
// ProxiedInRepeated is implemented in {cpp,upb}.rs
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
|
140
rust/proxied.rs
140
rust/proxied.rs
|
@ -44,7 +44,9 @@
|
|||
//! implemented the concept of "proxy" types. Proxy types are a reference-like
|
||||
//! indirection between the user and the internal memory representation.
|
||||
|
||||
use crate::RepeatedMut;
|
||||
use crate::__internal::Private;
|
||||
use crate::repeated::ProxiedInRepeated;
|
||||
use std::fmt::Debug;
|
||||
use std::marker::{Send, Sync};
|
||||
|
||||
|
@ -55,47 +57,47 @@ use std::marker::{Send, Sync};
|
|||
///
|
||||
/// All Protobuf field types implement `Proxied`.
|
||||
pub trait Proxied {
|
||||
/// The proxy type that provides shared access to a `T`, like a `&'a T`.
|
||||
/// The proxy type that provides shared access to a `T`, like a `&'msg T`.
|
||||
///
|
||||
/// Most code should use the type alias [`View`].
|
||||
type View<'a>: ViewProxy<'a, Proxied = Self> + Copy + Send + SettableValue<Self>
|
||||
type View<'msg>: ViewProxy<'msg, Proxied = Self> + Copy + Send + SettableValue<Self>
|
||||
where
|
||||
Self: 'a;
|
||||
Self: 'msg;
|
||||
|
||||
/// The proxy type that provides exclusive mutable access to a `T`, like a
|
||||
/// `&'a mut T`.
|
||||
/// `&'msg mut T`.
|
||||
///
|
||||
/// Most code should use the type alias [`Mut`].
|
||||
type Mut<'a>: MutProxy<'a, Proxied = Self>
|
||||
type Mut<'msg>: MutProxy<'msg, Proxied = Self>
|
||||
where
|
||||
Self: 'a;
|
||||
Self: 'msg;
|
||||
}
|
||||
|
||||
/// A proxy type that provides shared access to a `T`, like a `&'a T`.
|
||||
/// A proxy type that provides shared access to a `T`, like a `&'msg T`.
|
||||
///
|
||||
/// This is more concise than fully spelling the associated type.
|
||||
#[allow(dead_code)]
|
||||
pub type View<'a, T> = <T as Proxied>::View<'a>;
|
||||
pub type View<'msg, T> = <T as Proxied>::View<'msg>;
|
||||
|
||||
/// A proxy type that provides exclusive mutable access to a `T`, like a
|
||||
/// `&'a mut T`.
|
||||
/// `&'msg mut T`.
|
||||
///
|
||||
/// This is more concise than fully spelling the associated type.
|
||||
#[allow(dead_code)]
|
||||
pub type Mut<'a, T> = <T as Proxied>::Mut<'a>;
|
||||
pub type Mut<'msg, T> = <T as Proxied>::Mut<'msg>;
|
||||
|
||||
/// Declares conversion operations common to all views.
|
||||
///
|
||||
/// This trait is intentionally made non-object-safe to prevent a potential
|
||||
/// future incompatible change.
|
||||
pub trait ViewProxy<'a>: 'a + Sized + Sync + Unpin + Sized + Debug {
|
||||
type Proxied: 'a + Proxied + ?Sized;
|
||||
pub trait ViewProxy<'msg>: 'msg + Sized + Sync + Unpin + Sized + Debug {
|
||||
type Proxied: 'msg + Proxied + ?Sized;
|
||||
|
||||
/// Converts a borrow into a `View` with the lifetime of that borrow.
|
||||
///
|
||||
/// In non-generic code we don't need to use `as_view` because the proxy
|
||||
/// types are covariant over `'a`. However, generic code conservatively
|
||||
/// treats `'a` as [invariant], therefore we need to call
|
||||
/// types are covariant over `'msg`. However, generic code conservatively
|
||||
/// treats `'msg` as [invariant], therefore we need to call
|
||||
/// `as_view` to explicitly perform the operation that in concrete code
|
||||
/// coercion would perform implicitly.
|
||||
///
|
||||
|
@ -115,8 +117,8 @@ pub trait ViewProxy<'a>: 'a + Sized + Sync + Unpin + Sized + Debug {
|
|||
/// Converts into a `View` with a potentially shorter lifetime.
|
||||
///
|
||||
/// In non-generic code we don't need to use `into_view` because the proxy
|
||||
/// types are covariant over `'a`. However, generic code conservatively
|
||||
/// treats `'a` as [invariant], therefore we need to call
|
||||
/// types are covariant over `'msg`. However, generic code conservatively
|
||||
/// treats `'msg` as [invariant], therefore we need to call
|
||||
/// `into_view` to explicitly perform the operation that in concrete
|
||||
/// code coercion would perform implicitly.
|
||||
///
|
||||
|
@ -139,14 +141,14 @@ pub trait ViewProxy<'a>: 'a + Sized + Sync + Unpin + Sized + Debug {
|
|||
/// [invariant]: https://doc.rust-lang.org/nomicon/subtyping.html#variance
|
||||
fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied>
|
||||
where
|
||||
'a: 'shorter;
|
||||
'msg: 'shorter;
|
||||
}
|
||||
|
||||
/// Declares operations common to all mutators.
|
||||
///
|
||||
/// This trait is intentionally made non-object-safe to prevent a potential
|
||||
/// future incompatible change.
|
||||
pub trait MutProxy<'a>: ViewProxy<'a> {
|
||||
pub trait MutProxy<'msg>: ViewProxy<'msg> {
|
||||
/// Gets an immutable view of this field. This is shorthand for `as_view`.
|
||||
///
|
||||
/// This provides a shorter lifetime than `into_view` but can also be called
|
||||
|
@ -181,8 +183,8 @@ pub trait MutProxy<'a>: ViewProxy<'a> {
|
|||
/// Converts into a `Mut` with a potentially shorter lifetime.
|
||||
///
|
||||
/// In non-generic code we don't need to use `into_mut` because the proxy
|
||||
/// types are covariant over `'a`. However, generic code conservatively
|
||||
/// treats `'a` as [invariant], therefore we need to call
|
||||
/// types are covariant over `'msg`. However, generic code conservatively
|
||||
/// treats `'msg` as [invariant], therefore we need to call
|
||||
/// `into_mut` to explicitly perform the operation that in concrete code
|
||||
/// coercion would perform implicitly.
|
||||
///
|
||||
|
@ -202,34 +204,31 @@ pub trait MutProxy<'a>: ViewProxy<'a> {
|
|||
/// [invariant]: https://doc.rust-lang.org/nomicon/subtyping.html#variance
|
||||
fn into_mut<'shorter>(self) -> Mut<'shorter, Self::Proxied>
|
||||
where
|
||||
'a: 'shorter;
|
||||
'msg: 'shorter;
|
||||
}
|
||||
|
||||
// TODO: move this to `optional.rs` as it's only used for optionals
|
||||
/// `Proxied` types that can be optionally set or unset.
|
||||
///
|
||||
/// All scalar and message types implement `ProxiedWithPresence`, while repeated
|
||||
/// types don't.
|
||||
pub trait ProxiedWithPresence: Proxied {
|
||||
/// The data necessary to store a present field mutator proxying `Self`.
|
||||
/// This is the contents of `PresentField<'a, Self>`.
|
||||
type PresentMutData<'a>: MutProxy<'a, Proxied = Self>;
|
||||
/// This is the contents of `PresentField<'msg, Self>`.
|
||||
type PresentMutData<'msg>: MutProxy<'msg, Proxied = Self>;
|
||||
|
||||
/// The data necessary to store an absent field mutator proxying `Self`.
|
||||
/// This is the contents of `AbsentField<'a, Self>`.
|
||||
type AbsentMutData<'a>: ViewProxy<'a, Proxied = Self>;
|
||||
/// This is the contents of `AbsentField<'msg, Self>`.
|
||||
type AbsentMutData<'msg>: ViewProxy<'msg, Proxied = Self>;
|
||||
|
||||
/// Clears a present field.
|
||||
fn clear_present_field<'a>(
|
||||
present_mutator: Self::PresentMutData<'a>,
|
||||
) -> Self::AbsentMutData<'a>;
|
||||
fn clear_present_field(present_mutator: Self::PresentMutData<'_>) -> Self::AbsentMutData<'_>;
|
||||
|
||||
/// Sets an absent field to its default value.
|
||||
///
|
||||
/// This can be more efficient than setting with a default value, e.g.
|
||||
/// a default submessage could share resources with the parent message.
|
||||
fn set_absent_to_default<'a>(
|
||||
absent_mutator: Self::AbsentMutData<'a>,
|
||||
) -> Self::PresentMutData<'a>;
|
||||
fn set_absent_to_default(absent_mutator: Self::AbsentMutData<'_>) -> Self::PresentMutData<'_>;
|
||||
}
|
||||
|
||||
/// Values that can be used to set a field of `T`.
|
||||
|
@ -237,20 +236,20 @@ pub trait SettableValue<T>: Sized
|
|||
where
|
||||
T: Proxied + ?Sized,
|
||||
{
|
||||
/// Consumes `self` to set the given mutator to its value.
|
||||
/// Consumes `self` to set the given mutator to the value of `self`.
|
||||
#[doc(hidden)]
|
||||
fn set_on<'a>(self, _private: Private, mutator: Mut<'a, T>)
|
||||
fn set_on<'msg>(self, _private: Private, mutator: Mut<'msg, T>)
|
||||
where
|
||||
T: 'a;
|
||||
T: 'msg;
|
||||
|
||||
/// Consumes `self` and `absent_mutator` to set the given empty field to
|
||||
/// a value.
|
||||
/// the value of `self`.
|
||||
#[doc(hidden)]
|
||||
fn set_on_absent<'a>(
|
||||
fn set_on_absent(
|
||||
self,
|
||||
_private: Private,
|
||||
absent_mutator: T::AbsentMutData<'a>,
|
||||
) -> T::PresentMutData<'a>
|
||||
absent_mutator: T::AbsentMutData<'_>,
|
||||
) -> T::PresentMutData<'_>
|
||||
where
|
||||
T: ProxiedWithPresence,
|
||||
{
|
||||
|
@ -260,7 +259,7 @@ where
|
|||
}
|
||||
|
||||
/// Consumes `self` and `present_mutator` to set the given present field
|
||||
/// to a value.
|
||||
/// to the value of `self`.
|
||||
#[doc(hidden)]
|
||||
fn set_on_present(self, _private: Private, mut present_mutator: T::PresentMutData<'_>)
|
||||
where
|
||||
|
@ -268,6 +267,23 @@ where
|
|||
{
|
||||
self.set_on(Private, present_mutator.as_mut())
|
||||
}
|
||||
|
||||
/// Consumes `self` and `repeated_mutator` to set the value at the
|
||||
/// given index to the value of `self`.
|
||||
///
|
||||
/// # Safety
|
||||
/// `index` must be less than `repeated_mutator.len()`
|
||||
#[doc(hidden)]
|
||||
unsafe fn set_on_repeated_unchecked(
|
||||
self,
|
||||
_private: Private,
|
||||
mut _repeated_mutator: RepeatedMut<T>,
|
||||
_index: usize,
|
||||
) where
|
||||
T: ProxiedInRepeated,
|
||||
{
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -291,13 +307,13 @@ mod tests {
|
|||
}
|
||||
|
||||
impl Proxied for MyProxied {
|
||||
type View<'a> = MyProxiedView<'a>;
|
||||
type Mut<'a> = MyProxiedMut<'a>;
|
||||
type View<'msg> = MyProxiedView<'msg>;
|
||||
type Mut<'msg> = MyProxiedMut<'msg>;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
struct MyProxiedView<'a> {
|
||||
my_proxied_ref: &'a MyProxied,
|
||||
struct MyProxiedView<'msg> {
|
||||
my_proxied_ref: &'msg MyProxied,
|
||||
}
|
||||
|
||||
impl MyProxiedView<'_> {
|
||||
|
@ -306,27 +322,27 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ViewProxy<'a> for MyProxiedView<'a> {
|
||||
impl<'msg> ViewProxy<'msg> for MyProxiedView<'msg> {
|
||||
type Proxied = MyProxied;
|
||||
|
||||
fn as_view(&self) -> View<'a, MyProxied> {
|
||||
fn as_view(&self) -> View<'msg, MyProxied> {
|
||||
*self
|
||||
}
|
||||
|
||||
fn into_view<'shorter>(self) -> View<'shorter, MyProxied>
|
||||
where
|
||||
'a: 'shorter,
|
||||
'msg: 'shorter,
|
||||
{
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct MyProxiedMut<'a> {
|
||||
my_proxied_ref: &'a mut MyProxied,
|
||||
struct MyProxiedMut<'msg> {
|
||||
my_proxied_ref: &'msg mut MyProxied,
|
||||
}
|
||||
|
||||
impl<'a> ViewProxy<'a> for MyProxiedMut<'a> {
|
||||
impl<'msg> ViewProxy<'msg> for MyProxiedMut<'msg> {
|
||||
type Proxied = MyProxied;
|
||||
|
||||
fn as_view(&self) -> View<'_, MyProxied> {
|
||||
|
@ -334,56 +350,56 @@ mod tests {
|
|||
}
|
||||
fn into_view<'shorter>(self) -> View<'shorter, MyProxied>
|
||||
where
|
||||
'a: 'shorter,
|
||||
'msg: 'shorter,
|
||||
{
|
||||
MyProxiedView { my_proxied_ref: self.my_proxied_ref }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> MutProxy<'a> for MyProxiedMut<'a> {
|
||||
impl<'msg> MutProxy<'msg> for MyProxiedMut<'msg> {
|
||||
fn as_mut(&mut self) -> Mut<'_, MyProxied> {
|
||||
MyProxiedMut { my_proxied_ref: self.my_proxied_ref }
|
||||
}
|
||||
|
||||
fn into_mut<'shorter>(self) -> Mut<'shorter, MyProxied>
|
||||
where
|
||||
'a: 'shorter,
|
||||
'msg: 'shorter,
|
||||
{
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl SettableValue<MyProxied> for MyProxiedView<'_> {
|
||||
fn set_on<'a>(self, _private: Private, mutator: Mut<'a, MyProxied>)
|
||||
fn set_on<'msg>(self, _private: Private, mutator: Mut<'msg, MyProxied>)
|
||||
where
|
||||
MyProxied: 'a,
|
||||
MyProxied: 'msg,
|
||||
{
|
||||
mutator.my_proxied_ref.val = self.my_proxied_ref.val.clone();
|
||||
}
|
||||
}
|
||||
|
||||
impl SettableValue<MyProxied> for String {
|
||||
fn set_on<'a>(self, _private: Private, mutator: Mut<'a, MyProxied>)
|
||||
fn set_on<'msg>(self, _private: Private, mutator: Mut<'msg, MyProxied>)
|
||||
where
|
||||
MyProxied: 'a,
|
||||
MyProxied: 'msg,
|
||||
{
|
||||
mutator.my_proxied_ref.val = self;
|
||||
}
|
||||
}
|
||||
|
||||
impl SettableValue<MyProxied> for &'_ str {
|
||||
fn set_on<'a>(self, _private: Private, mutator: Mut<'a, MyProxied>)
|
||||
fn set_on<'msg>(self, _private: Private, mutator: Mut<'msg, MyProxied>)
|
||||
where
|
||||
MyProxied: 'a,
|
||||
MyProxied: 'msg,
|
||||
{
|
||||
mutator.my_proxied_ref.val.replace_range(.., self);
|
||||
}
|
||||
}
|
||||
|
||||
impl SettableValue<MyProxied> for Cow<'_, str> {
|
||||
fn set_on<'a>(self, _private: Private, mutator: Mut<'a, MyProxied>)
|
||||
fn set_on<'msg>(self, _private: Private, mutator: Mut<'msg, MyProxied>)
|
||||
where
|
||||
MyProxied: 'a,
|
||||
MyProxied: 'msg,
|
||||
{
|
||||
match self {
|
||||
Cow::Owned(x) => <String as SettableValue<MyProxied>>::set_on(x, Private, mutator),
|
||||
|
@ -413,7 +429,7 @@ mod tests {
|
|||
assert_eq!(my_proxied.val, "Hello indeed");
|
||||
}
|
||||
|
||||
fn reborrow_mut_into_view<'a>(x: Mut<'a, MyProxied>) -> View<'a, MyProxied> {
|
||||
fn reborrow_mut_into_view<'msg>(x: Mut<'msg, MyProxied>) -> View<'msg, MyProxied> {
|
||||
// x.as_view() fails to compile with:
|
||||
// `ERROR: attempt to return function-local borrowed content`
|
||||
x.into_view() // OK: we return the same lifetime as we got in.
|
||||
|
@ -425,7 +441,7 @@ mod tests {
|
|||
reborrow_mut_into_view(my_proxied.as_mut());
|
||||
}
|
||||
|
||||
fn require_unified_lifetimes<'a>(_x: Mut<'a, MyProxied>, _y: View<'a, MyProxied>) {}
|
||||
fn require_unified_lifetimes<'msg>(_x: Mut<'msg, MyProxied>, _y: View<'msg, MyProxied>) {}
|
||||
|
||||
#[test]
|
||||
fn test_require_unified_lifetimes() {
|
||||
|
|
575
rust/repeated.rs
575
rust/repeated.rs
|
@ -5,231 +5,424 @@
|
|||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
use std::fmt::{self, Debug};
|
||||
use std::iter;
|
||||
/// Repeated scalar fields are implemented around the runtime-specific
|
||||
/// `RepeatedField` struct. `RepeatedField` stores an opaque pointer to the
|
||||
/// runtime-specific representation of a repeated scalar (`upb_Array*` on upb,
|
||||
/// and `RepeatedField<T>*` on cpp).
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::Deref;
|
||||
|
||||
use crate::{
|
||||
Mut, MutProxy, Proxied, SettableValue, View, ViewProxy,
|
||||
__internal::{Private, RawRepeatedField},
|
||||
__runtime::{RepeatedField, RepeatedFieldInner},
|
||||
primitive::PrimitiveMut,
|
||||
vtable::ProxiedWithRawVTable,
|
||||
__runtime::InnerRepeatedMut,
|
||||
};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct RepeatedFieldRef<'a> {
|
||||
pub repeated_field: RawRepeatedField,
|
||||
pub _phantom: PhantomData<&'a mut ()>,
|
||||
}
|
||||
|
||||
unsafe impl<'a> Send for RepeatedFieldRef<'a> {}
|
||||
unsafe impl<'a> Sync for RepeatedFieldRef<'a> {}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
/// Views the elements in a `repeated` field of `T`.
|
||||
#[repr(transparent)]
|
||||
pub struct RepeatedView<'a, T: ?Sized> {
|
||||
inner: RepeatedField<'a, T>,
|
||||
pub struct RepeatedView<'msg, T: ?Sized> {
|
||||
// This does not need to carry an arena in upb, so it can be just the raw repeated field
|
||||
raw: RawRepeatedField,
|
||||
_phantom: PhantomData<&'msg T>,
|
||||
}
|
||||
|
||||
unsafe impl<'a, T: ProxiedWithRawVTable> Sync for RepeatedView<'a, T> {}
|
||||
unsafe impl<'a, T: ProxiedWithRawVTable> Send for RepeatedView<'a, T> {}
|
||||
|
||||
impl<'msg, T: ?Sized> RepeatedView<'msg, T> {
|
||||
pub fn from_inner(_private: Private, inner: RepeatedFieldInner<'msg>) -> Self {
|
||||
Self { inner: RepeatedField::<'msg>::from_inner(_private, inner) }
|
||||
impl<'msg, T: ?Sized> Copy for RepeatedView<'msg, T> {}
|
||||
impl<'msg, T: ?Sized> Clone for RepeatedView<'msg, T> {
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RepeatedFieldIter<'a, T> {
|
||||
inner: RepeatedField<'a, T>,
|
||||
current_index: usize,
|
||||
}
|
||||
unsafe impl<'msg, T: ?Sized> Sync for RepeatedView<'msg, T> {}
|
||||
unsafe impl<'msg, T: ?Sized> Send for RepeatedView<'msg, T> {}
|
||||
|
||||
impl<'a, T> std::fmt::Debug for RepeatedView<'a, T> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_tuple("RepeatedView").finish()
|
||||
impl<'msg, T: ?Sized> Debug for RepeatedView<'msg, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("RepeatedView").field("raw", &self.raw).finish()
|
||||
}
|
||||
}
|
||||
|
||||
/// Mutates the elements in a `repeated` field of `T`.
|
||||
#[repr(transparent)]
|
||||
#[derive(Debug)]
|
||||
pub struct RepeatedMut<'a, T: ?Sized> {
|
||||
inner: RepeatedField<'a, T>,
|
||||
pub struct RepeatedMut<'msg, T: ?Sized> {
|
||||
pub(crate) inner: InnerRepeatedMut<'msg>,
|
||||
_phantom: PhantomData<&'msg mut T>,
|
||||
}
|
||||
|
||||
unsafe impl<'a, T: ProxiedWithRawVTable> Sync for RepeatedMut<'a, T> {}
|
||||
unsafe impl<'msg, T: ?Sized> Sync for RepeatedMut<'msg, T> {}
|
||||
|
||||
impl<'msg, T: ?Sized> RepeatedMut<'msg, T> {
|
||||
pub fn from_inner(_private: Private, inner: RepeatedFieldInner<'msg>) -> Self {
|
||||
Self { inner: RepeatedField::from_inner(_private, inner) }
|
||||
}
|
||||
pub fn as_mut(&self) -> RepeatedMut<'_, T> {
|
||||
Self { inner: self.inner }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> std::ops::Deref for RepeatedMut<'a, T> {
|
||||
type Target = RepeatedView<'a, T>;
|
||||
impl<'msg, T: ?Sized> Deref for RepeatedMut<'msg, T> {
|
||||
type Target = RepeatedView<'msg, T>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
// SAFETY:
|
||||
// - `Repeated{View,Mut}<'a, T>` are both `#[repr(transparent)]` over
|
||||
// `RepeatedField<'a, T>`.
|
||||
// - `Repeated{View,Mut}<'msg, T>` are both `#[repr(transparent)]` over
|
||||
// `RepeatedField<'msg, T>`.
|
||||
// - `Repeated{View,Mut}<'msg, T>` are both `#[repr(transparent)]` over
|
||||
// `RepeatedField<'msg, T>`.
|
||||
// - `RepeatedField` is a type alias for `NonNull`.
|
||||
unsafe { &*(self as *const Self as *const RepeatedView<'a, T>) }
|
||||
unsafe { &*(self as *const Self as *const RepeatedView<'msg, T>) }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RepeatedFieldIterMut<'a, T> {
|
||||
inner: RepeatedMut<'a, T>,
|
||||
impl<'msg, T: ?Sized> Debug for RepeatedMut<'msg, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("RepeatedMut").field("raw", &self.raw).finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'msg, T> RepeatedView<'msg, T>
|
||||
where
|
||||
T: ProxiedInRepeated + ?Sized + 'msg,
|
||||
{
|
||||
#[doc(hidden)]
|
||||
pub fn as_raw(&self, _private: Private) -> RawRepeatedField {
|
||||
self.raw
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
/// - `inner` must be valid to read from for `'msg`
|
||||
#[doc(hidden)]
|
||||
pub unsafe fn from_raw(_private: Private, raw: RawRepeatedField) -> Self {
|
||||
Self { raw, _phantom: PhantomData }
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
T::repeated_len(*self)
|
||||
}
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
pub fn get(self, index: usize) -> Option<View<'msg, T>> {
|
||||
if index >= self.len() {
|
||||
return None;
|
||||
}
|
||||
// SAFETY: `index` has been checked to be in-bounds
|
||||
Some(unsafe { T::repeated_get_unchecked(self, index) })
|
||||
}
|
||||
pub fn iter(self) -> RepeatedIter<'msg, T> {
|
||||
self.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'msg, T> RepeatedMut<'msg, T>
|
||||
where
|
||||
T: ProxiedInRepeated + ?Sized + 'msg,
|
||||
{
|
||||
/// # Safety
|
||||
/// - `inner` must be valid to read and write from for `'msg`
|
||||
/// - There must be no aliasing references or mutations on the same
|
||||
/// underlying object.
|
||||
#[doc(hidden)]
|
||||
pub unsafe fn from_inner(_private: Private, inner: InnerRepeatedMut<'msg>) -> Self {
|
||||
Self { inner, _phantom: PhantomData }
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn as_raw(&mut self, _private: Private) -> RawRepeatedField {
|
||||
self.inner.raw
|
||||
}
|
||||
|
||||
/// Appends `val` to the end of the repeated field.
|
||||
pub fn push(&mut self, val: View<T>) {
|
||||
T::repeated_push(self.as_mut(), val);
|
||||
}
|
||||
|
||||
/// Sets the value at `index` to the value `val`.
|
||||
///
|
||||
/// # Panics
|
||||
/// Panics if `index >= len`
|
||||
pub fn set(&mut self, index: usize, val: View<T>) {
|
||||
let len = self.len();
|
||||
if index >= len {
|
||||
panic!("index {index} >= repeated len {len}");
|
||||
}
|
||||
// SAFETY: `index` has been checked to be in-bounds.
|
||||
unsafe { T::repeated_set_unchecked(self.as_mut(), index, val) }
|
||||
}
|
||||
|
||||
/// Returns the value at `index`.
|
||||
// This is defined as an inherent function to prevent `MutProxy::get` from being
|
||||
// preferred over `RepeatedView::get`. The former gets priority as it does
|
||||
// not require a deref.
|
||||
pub fn get(&self, index: usize) -> Option<View<T>> {
|
||||
self.as_view().get(index)
|
||||
}
|
||||
|
||||
/// Copies from the `src` repeated field into this one.
|
||||
///
|
||||
/// Also provided by [`MutProxy::set`].
|
||||
pub fn copy_from(&mut self, src: RepeatedView<'_, T>) {
|
||||
T::repeated_copy_from(src, self.as_mut())
|
||||
}
|
||||
|
||||
/// Clears the repeated field.
|
||||
pub fn clear(&mut self) {
|
||||
T::repeated_clear(self.as_mut())
|
||||
}
|
||||
}
|
||||
|
||||
/// Types that can appear in a `Repeated<T>`.
|
||||
///
|
||||
/// This trait is implemented by generated code to communicate how the proxied
|
||||
/// type can be manipulated for a repeated field.
|
||||
///
|
||||
/// Scalars and messages implement `ProxiedInRepeated`.
|
||||
///
|
||||
/// # Safety
|
||||
/// - It must be sound to call `*_unchecked*(x)` with an `index` less than
|
||||
/// `repeated_len(x)`.
|
||||
pub unsafe trait ProxiedInRepeated: Proxied {
|
||||
/// Constructs a new owned `Repeated` field.
|
||||
#[doc(hidden)]
|
||||
fn repeated_new(_private: Private) -> Repeated<Self> {
|
||||
unimplemented!("not required")
|
||||
}
|
||||
|
||||
/// Frees the repeated field in-place, for use in `Drop`.
|
||||
///
|
||||
/// # Safety
|
||||
/// - After `repeated_free`, no other methods on the input are safe to call.
|
||||
#[doc(hidden)]
|
||||
unsafe fn repeated_free(_private: Private, _repeated: &mut Repeated<Self>) {
|
||||
unimplemented!("not required")
|
||||
}
|
||||
|
||||
/// Gets the length of the repeated field.
|
||||
fn repeated_len(repeated: View<Repeated<Self>>) -> usize;
|
||||
|
||||
/// Appends a new element to the end of the repeated field.
|
||||
fn repeated_push(repeated: Mut<Repeated<Self>>, val: View<Self>);
|
||||
|
||||
/// Clears the repeated field of elements.
|
||||
fn repeated_clear(repeated: Mut<Repeated<Self>>);
|
||||
|
||||
/// # Safety
|
||||
/// `index` must be less than `Self::repeated_len(repeated)`
|
||||
unsafe fn repeated_get_unchecked(repeated: View<Repeated<Self>>, index: usize) -> View<Self>;
|
||||
|
||||
/// # Safety
|
||||
/// `index` must be less than `Self::repeated_len(repeated)`
|
||||
unsafe fn repeated_set_unchecked(repeated: Mut<Repeated<Self>>, index: usize, val: View<Self>);
|
||||
|
||||
/// Copies the values in the `src` repeated field into `dest`.
|
||||
fn repeated_copy_from(src: View<Repeated<Self>>, dest: Mut<Repeated<Self>>);
|
||||
}
|
||||
|
||||
/// An iterator over the values inside of a [`View<Repeated<T>>`](RepeatedView).
|
||||
pub struct RepeatedIter<'msg, T: ?Sized> {
|
||||
view: RepeatedView<'msg, T>,
|
||||
current_index: usize,
|
||||
}
|
||||
|
||||
pub struct Repeated<T>(PhantomData<T>);
|
||||
|
||||
macro_rules! impl_repeated_primitives {
|
||||
($($t:ty),*) => {
|
||||
$(
|
||||
impl Proxied for Repeated<$t> {
|
||||
type View<'a> = RepeatedView<'a, $t>;
|
||||
type Mut<'a> = RepeatedMut<'a, $t>;
|
||||
}
|
||||
|
||||
impl<'a> ViewProxy<'a> for RepeatedView<'a, $t> {
|
||||
type Proxied = Repeated<$t>;
|
||||
|
||||
fn as_view(&self) -> View<'_, Self::Proxied> {
|
||||
*self
|
||||
}
|
||||
|
||||
fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied>
|
||||
where 'a: 'shorter,
|
||||
{
|
||||
RepeatedView { inner: self.inner }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ViewProxy<'a> for RepeatedMut<'a, $t> {
|
||||
type Proxied = Repeated<$t>;
|
||||
|
||||
fn as_view(&self) -> View<'_, Self::Proxied> {
|
||||
**self
|
||||
}
|
||||
|
||||
fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied>
|
||||
where 'a: 'shorter,
|
||||
{
|
||||
*self.into_mut::<'shorter>()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> MutProxy<'a> for RepeatedMut<'a, $t> {
|
||||
fn as_mut(&mut self) -> Mut<'_, Self::Proxied> {
|
||||
RepeatedMut { inner: self.inner }
|
||||
}
|
||||
|
||||
fn into_mut<'shorter>(self) -> Mut<'shorter, Self::Proxied>
|
||||
where 'a: 'shorter,
|
||||
{
|
||||
RepeatedMut { inner: self.inner }
|
||||
}
|
||||
}
|
||||
|
||||
impl <'a> SettableValue<Repeated<$t>> for RepeatedView<'a, $t> {
|
||||
fn set_on<'b> (self, _private: Private, mut mutator: Mut<'b, Repeated<$t>>)
|
||||
where
|
||||
Repeated<$t>: 'b {
|
||||
mutator.copy_from(self);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> RepeatedView<'a, $t> {
|
||||
pub fn len(&self) -> usize {
|
||||
self.inner.len()
|
||||
}
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
pub fn get(&self, index: usize) -> Option<$t> {
|
||||
self.inner.get(index)
|
||||
}
|
||||
pub fn iter(&self) -> RepeatedFieldIter<'_, $t> {
|
||||
(*self).into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> RepeatedMut<'a, $t> {
|
||||
pub fn push(&mut self, val: $t) {
|
||||
self.inner.push(val)
|
||||
}
|
||||
pub fn set(&mut self, index: usize, val: $t) {
|
||||
self.inner.set(index, val)
|
||||
}
|
||||
pub fn get_mut(&mut self, index: usize) -> Option<Mut<'_, $t>> {
|
||||
if index >= self.len() {
|
||||
return None;
|
||||
}
|
||||
Some(PrimitiveMut::Repeated(self.as_mut(), index))
|
||||
}
|
||||
pub fn iter(&self) -> RepeatedFieldIter<'_, $t> {
|
||||
self.as_view().into_iter()
|
||||
}
|
||||
pub fn iter_mut(&mut self) -> RepeatedFieldIterMut<'_, $t> {
|
||||
self.as_mut().into_iter()
|
||||
}
|
||||
pub fn copy_from(&mut self, src: RepeatedView<'_, $t>) {
|
||||
self.inner.copy_from(&src.inner);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> std::iter::Iterator for RepeatedFieldIter<'a, $t> {
|
||||
type Item = $t;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let val = self.inner.get(self.current_index);
|
||||
if val.is_some() {
|
||||
self.current_index += 1;
|
||||
}
|
||||
val
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> std::iter::IntoIterator for RepeatedView<'a, $t> {
|
||||
type Item = $t;
|
||||
type IntoIter = RepeatedFieldIter<'a, $t>;
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
RepeatedFieldIter { inner: self.inner, current_index: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
impl <'a> std::iter::Iterator for RepeatedFieldIterMut<'a, $t> {
|
||||
type Item = Mut<'a, $t>;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.current_index >= self.inner.len() {
|
||||
return None;
|
||||
}
|
||||
let elem = PrimitiveMut::Repeated(
|
||||
// While this appears to allow mutable aliasing
|
||||
// (multiple `Self::Item`s can co-exist), each `Item`
|
||||
// only references a specific unique index.
|
||||
RepeatedMut{ inner: self.inner.inner },
|
||||
self.current_index,
|
||||
);
|
||||
self.current_index += 1;
|
||||
Some(elem)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> std::iter::IntoIterator for RepeatedMut<'a, $t> {
|
||||
type Item = Mut<'a, $t>;
|
||||
type IntoIter = RepeatedFieldIterMut<'a, $t>;
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
RepeatedFieldIterMut { inner: self, current_index: 0 }
|
||||
}
|
||||
}
|
||||
)*
|
||||
impl<'msg, T: ?Sized> Debug for RepeatedIter<'msg, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("RepeatedIter")
|
||||
.field("view", &self.view)
|
||||
.field("current_index", &self.current_index)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl_repeated_primitives!(i32, u32, bool, f32, f64, i64, u64);
|
||||
/// An iterator over the mutators inside of a [`Mut<Repeated<T>>`](RepeatedMut).
|
||||
pub struct RepeatedIterMut<'msg, T: ?Sized> {
|
||||
mutator: RepeatedMut<'msg, T>,
|
||||
current_index: usize,
|
||||
}
|
||||
|
||||
impl<'msg, T: ?Sized> Debug for RepeatedIterMut<'msg, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("RepeatedIterMut")
|
||||
.field("mutator", &self.mutator)
|
||||
.field("current_index", &self.current_index)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
/// A `repeated` field of `T`, used as the owned target for `Proxied`.
|
||||
///
|
||||
/// Users will generally write [`View<Repeated<T>>`](RepeatedView) or
|
||||
/// [`Mut<Repeated<T>>`](RepeatedMut) to access the repeated elements
|
||||
pub struct Repeated<T: ?Sized + ProxiedInRepeated> {
|
||||
inner: InnerRepeatedMut<'static>,
|
||||
_phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T: ?Sized + ProxiedInRepeated> Repeated<T> {
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn new() -> Self {
|
||||
T::repeated_new(Private)
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn from_inner(inner: InnerRepeatedMut<'static>) -> Self {
|
||||
Self { inner, _phantom: PhantomData }
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn inner(&mut self) -> InnerRepeatedMut<'static> {
|
||||
self.inner
|
||||
}
|
||||
|
||||
pub(crate) fn as_mut(&mut self) -> RepeatedMut<'_, T> {
|
||||
RepeatedMut { inner: self.inner, _phantom: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized + ProxiedInRepeated> Drop for Repeated<T> {
|
||||
fn drop(&mut self) {
|
||||
// SAFETY: only called once
|
||||
unsafe { T::repeated_free(Private, self) }
|
||||
}
|
||||
}
|
||||
|
||||
// SAFETY: `Repeated` does not allow for shared mutability.
|
||||
unsafe impl<T: ProxiedInRepeated> Sync for Repeated<T> {}
|
||||
|
||||
impl<T> Proxied for Repeated<T>
|
||||
where
|
||||
T: ProxiedInRepeated + ?Sized,
|
||||
{
|
||||
type View<'msg> = RepeatedView<'msg, T> where Repeated<T>: 'msg;
|
||||
type Mut<'msg> = RepeatedMut<'msg, T> where Repeated<T>: 'msg;
|
||||
}
|
||||
|
||||
impl<'msg, T> ViewProxy<'msg> for RepeatedView<'msg, T>
|
||||
where
|
||||
T: ProxiedInRepeated + ?Sized + 'msg,
|
||||
{
|
||||
type Proxied = Repeated<T>;
|
||||
|
||||
fn as_view(&self) -> View<'_, Self::Proxied> {
|
||||
*self
|
||||
}
|
||||
|
||||
fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied>
|
||||
where
|
||||
'msg: 'shorter,
|
||||
{
|
||||
RepeatedView { raw: self.raw, _phantom: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'msg, T> ViewProxy<'msg> for RepeatedMut<'msg, T>
|
||||
where
|
||||
T: ProxiedInRepeated + ?Sized + 'msg,
|
||||
{
|
||||
type Proxied = Repeated<T>;
|
||||
|
||||
fn as_view(&self) -> View<'_, Self::Proxied> {
|
||||
**self
|
||||
}
|
||||
|
||||
fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied>
|
||||
where
|
||||
'msg: 'shorter,
|
||||
{
|
||||
*self.into_mut::<'shorter>()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'msg, T> MutProxy<'msg> for RepeatedMut<'msg, T>
|
||||
where
|
||||
T: ProxiedInRepeated + ?Sized + 'msg,
|
||||
{
|
||||
fn as_mut(&mut self) -> Mut<'_, Self::Proxied> {
|
||||
RepeatedMut { inner: self.inner, _phantom: PhantomData }
|
||||
}
|
||||
|
||||
fn into_mut<'shorter>(self) -> Mut<'shorter, Self::Proxied>
|
||||
where
|
||||
'msg: 'shorter,
|
||||
{
|
||||
RepeatedMut { inner: self.inner, _phantom: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'msg, T> SettableValue<Repeated<T>> for RepeatedView<'msg, T>
|
||||
where
|
||||
T: ProxiedInRepeated + ?Sized + 'msg,
|
||||
{
|
||||
fn set_on<'b>(self, _private: Private, mutator: Mut<'b, Repeated<T>>)
|
||||
where
|
||||
Repeated<T>: 'b,
|
||||
{
|
||||
T::repeated_copy_from(self, mutator)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: impl ExactSizeIterator
|
||||
impl<'msg, T> iter::Iterator for RepeatedIter<'msg, T>
|
||||
where
|
||||
T: ProxiedInRepeated + ?Sized + 'msg,
|
||||
{
|
||||
type Item = View<'msg, T>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let val = self.view.get(self.current_index);
|
||||
if val.is_some() {
|
||||
self.current_index += 1;
|
||||
}
|
||||
val
|
||||
}
|
||||
}
|
||||
|
||||
impl<'msg, T> iter::IntoIterator for RepeatedView<'msg, T>
|
||||
where
|
||||
T: ProxiedInRepeated + ?Sized + 'msg,
|
||||
{
|
||||
type Item = View<'msg, T>;
|
||||
type IntoIter = RepeatedIter<'msg, T>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
RepeatedIter { view: self, current_index: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use googletest::prelude::*;
|
||||
|
||||
#[test]
|
||||
fn test_primitive_repeated() {
|
||||
macro_rules! primitive_repeated_tests {
|
||||
($($t:ty => [$($vals:expr),* $(,)?]),* $(,)?) => {
|
||||
$({
|
||||
// Constructs a new, owned, `Repeated`, only used for tests.
|
||||
let mut r = Repeated::<$t>::new();
|
||||
let mut r = r.as_mut();
|
||||
assert_that!(r.len(), eq(0));
|
||||
assert!(r.iter().next().is_none(), "starts with empty iter");
|
||||
assert!(r.iter().next().is_none(), "starts with empty mut iter");
|
||||
assert!(r.is_empty(), "starts is_empty");
|
||||
|
||||
let mut expected_len = 0usize;
|
||||
$(
|
||||
let val: View<$t> = $vals;
|
||||
r.push(val);
|
||||
assert_that!(r.get(expected_len), eq(Some(val)));
|
||||
expected_len += 1;
|
||||
assert_that!(r.len(), eq(expected_len));
|
||||
|
||||
)*
|
||||
assert_that!(
|
||||
r.iter().collect::<Vec<$t>>(), elements_are![$(eq($vals)),*]);
|
||||
r.set(0, <$t as Default>::default());
|
||||
assert_that!(r.get(0).expect("elem 0"), eq(<$t as Default>::default()));
|
||||
|
||||
r.clear();
|
||||
assert!(r.is_empty(), "is_empty after clear");
|
||||
assert!(r.iter().next().is_none(), "iter empty after clear");
|
||||
assert!(r.into_iter().next().is_none(), "mut iter empty after clear");
|
||||
})*
|
||||
}
|
||||
}
|
||||
primitive_repeated_tests!(
|
||||
u32 => [1,2,3],
|
||||
i32 => [1,2],
|
||||
f64 => [10.0, 0.1234f64],
|
||||
bool => [false, true, true, false],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,17 +13,22 @@
|
|||
|
||||
use std::fmt;
|
||||
|
||||
// There are a number of manual `Debug` and similar impls instead of using their
|
||||
// derives, in order to to avoid unnecessary bounds on a generic `T`.
|
||||
// This problem is referred to as "perfect derive".
|
||||
// https://smallcultfollowing.com/babysteps/blog/2022/04/12/implied-bounds-and-perfect-derive/
|
||||
|
||||
/// Everything in `__public` is re-exported in `protobuf.rs`.
|
||||
/// These are the items protobuf users can access directly.
|
||||
#[doc(hidden)]
|
||||
pub mod __public {
|
||||
pub use crate::map::{MapMut, MapView};
|
||||
pub use crate::map::{Map, MapMut, MapView};
|
||||
pub use crate::optional::{AbsentField, FieldEntry, Optional, PresentField};
|
||||
pub use crate::primitive::{PrimitiveMut, SingularPrimitiveMut};
|
||||
pub use crate::primitive::PrimitiveMut;
|
||||
pub use crate::proxied::{
|
||||
Mut, MutProxy, Proxied, ProxiedWithPresence, SettableValue, View, ViewProxy,
|
||||
};
|
||||
pub use crate::repeated::{RepeatedFieldRef, RepeatedMut, RepeatedView};
|
||||
pub use crate::repeated::{ProxiedInRepeated, Repeated, RepeatedMut, RepeatedView};
|
||||
pub use crate::string::{BytesMut, ProtoStr, ProtoStrMut};
|
||||
}
|
||||
pub use __public::*;
|
||||
|
|
|
@ -128,15 +128,11 @@ impl ProxiedWithPresence for [u8] {
|
|||
type PresentMutData<'msg> = BytesPresentMutData<'msg>;
|
||||
type AbsentMutData<'msg> = BytesAbsentMutData<'msg>;
|
||||
|
||||
fn clear_present_field<'a>(
|
||||
present_mutator: Self::PresentMutData<'a>,
|
||||
) -> Self::AbsentMutData<'a> {
|
||||
fn clear_present_field(present_mutator: Self::PresentMutData<'_>) -> Self::AbsentMutData<'_> {
|
||||
present_mutator.clear()
|
||||
}
|
||||
|
||||
fn set_absent_to_default<'a>(
|
||||
absent_mutator: Self::AbsentMutData<'a>,
|
||||
) -> Self::PresentMutData<'a> {
|
||||
fn set_absent_to_default(absent_mutator: Self::AbsentMutData<'_>) -> Self::PresentMutData<'_> {
|
||||
absent_mutator.set_absent_to_default()
|
||||
}
|
||||
}
|
||||
|
@ -185,9 +181,9 @@ impl<'msg> MutProxy<'msg> for BytesMut<'msg> {
|
|||
}
|
||||
|
||||
impl SettableValue<[u8]> for &'_ [u8] {
|
||||
fn set_on<'a>(self, _private: Private, mutator: Mut<'a, [u8]>)
|
||||
fn set_on<'msg>(self, _private: Private, mutator: Mut<'msg, [u8]>)
|
||||
where
|
||||
[u8]: 'a,
|
||||
[u8]: 'msg,
|
||||
{
|
||||
// SAFETY: this is a `bytes` field with no restriction on UTF-8.
|
||||
unsafe { mutator.inner.set(self) }
|
||||
|
|
|
@ -74,7 +74,7 @@ rust_proto_library(
|
|||
name = "unittest_proto3_optional_rust_proto",
|
||||
testonly = True,
|
||||
visibility = [
|
||||
"//rust/test/shared:__subpackages__",
|
||||
"//visibility:private", # Only private by automation, not intent. Owner may accept CLs adding visibility. See go/scheuklappen#explicit-private.
|
||||
],
|
||||
deps = [
|
||||
UNITTEST_PROTO3_OPTIONAL_TARGET,
|
||||
|
@ -84,20 +84,14 @@ rust_proto_library(
|
|||
rust_cc_proto_library(
|
||||
name = "unittest_proto3_optional_cc_rust_proto",
|
||||
testonly = True,
|
||||
visibility = [
|
||||
"//rust/test/cpp:__subpackages__",
|
||||
"//rust/test/shared:__subpackages__",
|
||||
],
|
||||
visibility = ["//rust/test/shared:__subpackages__"],
|
||||
deps = [UNITTEST_PROTO3_OPTIONAL_CC_TARGET],
|
||||
)
|
||||
|
||||
rust_upb_proto_library(
|
||||
name = "unittest_proto3_optional_upb_rust_proto",
|
||||
testonly = True,
|
||||
visibility = [
|
||||
"//rust/test/cpp:__subpackages__",
|
||||
"//rust/test/shared:__subpackages__",
|
||||
],
|
||||
visibility = ["//rust/test/shared:__subpackages__"],
|
||||
deps = [UNITTEST_PROTO3_OPTIONAL_TARGET],
|
||||
)
|
||||
|
||||
|
@ -180,6 +174,32 @@ rust_upb_proto_library(
|
|||
deps = [":dots_in_package_proto"],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "edition2023_proto",
|
||||
testonly = True,
|
||||
srcs = ["edition2023.proto"],
|
||||
)
|
||||
|
||||
cc_proto_library(
|
||||
name = "edition2023_cc_proto",
|
||||
testonly = True,
|
||||
deps = [":edition2023_proto"],
|
||||
)
|
||||
|
||||
rust_cc_proto_library(
|
||||
name = "edition2023_cc_rust_proto",
|
||||
testonly = True,
|
||||
visibility = ["//rust/test/shared:__subpackages__"],
|
||||
deps = [":edition2023_cc_proto"],
|
||||
)
|
||||
|
||||
rust_upb_proto_library(
|
||||
name = "edition2023_upb_rust_proto",
|
||||
testonly = True,
|
||||
visibility = ["//rust/test/shared:__subpackages__"],
|
||||
deps = [":edition2023_proto"],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "no_package_import_proto",
|
||||
testonly = True,
|
||||
|
|
|
@ -40,9 +40,9 @@ fn mutate_message_in_cpp() {
|
|||
}
|
||||
|
||||
let mut msg2 = TestAllTypes::new();
|
||||
msg2.optional_int64_set(Some(42));
|
||||
msg2.optional_int64_mut().set(42);
|
||||
msg2.optional_bytes_mut().set(b"something mysterious");
|
||||
msg2.optional_bool_set(Some(false));
|
||||
msg2.optional_bool_mut().set(false);
|
||||
|
||||
proto_assert_eq!(msg1, msg2);
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ fn mutate_message_in_cpp() {
|
|||
#[test]
|
||||
fn deserialize_in_rust() {
|
||||
let mut msg1 = TestAllTypes::new();
|
||||
msg1.optional_int64_set(Some(-1));
|
||||
msg1.optional_int64_mut().set(-1);
|
||||
msg1.optional_bytes_mut().set(b"some cool data I guess");
|
||||
let serialized =
|
||||
unsafe { SerializeTestAllTypes(msg1.__unstable_cpp_repr_grant_permission_to_break()) };
|
||||
|
@ -63,7 +63,7 @@ fn deserialize_in_rust() {
|
|||
#[test]
|
||||
fn deserialize_in_cpp() {
|
||||
let mut msg1 = TestAllTypes::new();
|
||||
msg1.optional_int64_set(Some(-1));
|
||||
msg1.optional_int64_mut().set(-1);
|
||||
msg1.optional_bytes_mut().set(b"some cool data I guess");
|
||||
let data = msg1.serialize();
|
||||
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
edition = "2023";
|
||||
|
||||
package test;
|
||||
|
||||
message EditionsMessage {
|
||||
int32 plain_field = 1;
|
||||
int32 implicit_presence_field = 2 [features.field_presence = IMPLICIT];
|
||||
}
|
|
@ -11,6 +11,10 @@ package nest;
|
|||
|
||||
message Outer {
|
||||
message Inner {
|
||||
message InnerSubMsg {
|
||||
optional bool flag = 1;
|
||||
}
|
||||
|
||||
optional double double = 1;
|
||||
optional float float = 2;
|
||||
optional int32 int32 = 3;
|
||||
|
@ -26,6 +30,7 @@ message Outer {
|
|||
optional bool bool = 13;
|
||||
optional string string = 14;
|
||||
optional bytes bytes = 15;
|
||||
optional InnerSubMsg innersubmsg = 16;
|
||||
|
||||
message SuperInner {
|
||||
message DuperInner {
|
||||
|
@ -40,4 +45,15 @@ message Outer {
|
|||
optional Inner inner = 1;
|
||||
optional .nest.Outer.Inner.SuperInner.DuperInner.EvenMoreInner
|
||||
.CantBelieveItsSoInner deep = 2;
|
||||
|
||||
optional NotInside notinside = 3;
|
||||
}
|
||||
|
||||
message NotInside {
|
||||
optional int32 num = 1;
|
||||
}
|
||||
|
||||
message Recursive {
|
||||
optional Recursive rec = 1;
|
||||
optional int32 num = 2;
|
||||
}
|
||||
|
|
|
@ -68,6 +68,32 @@ rust_test(
|
|||
],
|
||||
)
|
||||
|
||||
rust_test(
|
||||
name = "edition2023_cpp_test",
|
||||
srcs = ["edition2023_test.rs"],
|
||||
tags = [
|
||||
# TODO: Enable testing on arm once we support sanitizers for Rust on Arm.
|
||||
"not_build:arm",
|
||||
],
|
||||
deps = [
|
||||
"@crate_index//:googletest",
|
||||
"//rust/test:edition2023_cc_rust_proto",
|
||||
],
|
||||
)
|
||||
|
||||
rust_test(
|
||||
name = "edition2023_upb_test",
|
||||
srcs = ["edition2023_test.rs"],
|
||||
tags = [
|
||||
# TODO: Enable testing on arm once we support sanitizers for Rust on Arm.
|
||||
"not_build:arm",
|
||||
],
|
||||
deps = [
|
||||
"@crate_index//:googletest",
|
||||
"//rust/test:edition2023_upb_rust_proto",
|
||||
],
|
||||
)
|
||||
|
||||
rust_test(
|
||||
name = "package_cpp_test",
|
||||
srcs = ["package_test.rs"],
|
||||
|
@ -280,6 +306,46 @@ rust_test(
|
|||
],
|
||||
)
|
||||
|
||||
rust_test(
|
||||
name = "accessors_repeated_cpp_test",
|
||||
srcs = ["accessors_repeated_test.rs"],
|
||||
aliases = {
|
||||
"//rust:protobuf_cpp": "protobuf",
|
||||
},
|
||||
proc_macro_deps = [
|
||||
"@crate_index//:paste",
|
||||
],
|
||||
tags = [
|
||||
# TODO: Enable testing on arm once we support sanitizers for Rust on Arm.
|
||||
"not_build:arm",
|
||||
],
|
||||
deps = [
|
||||
"@crate_index//:googletest",
|
||||
"//rust:protobuf_cpp",
|
||||
"//rust/test:unittest_cc_rust_proto",
|
||||
],
|
||||
)
|
||||
|
||||
rust_test(
|
||||
name = "accessors_repeated_upb_test",
|
||||
srcs = ["accessors_repeated_test.rs"],
|
||||
aliases = {
|
||||
"//rust:protobuf_upb": "protobuf",
|
||||
},
|
||||
proc_macro_deps = [
|
||||
"@crate_index//:paste",
|
||||
],
|
||||
tags = [
|
||||
# TODO: Enable testing on arm once we support sanitizers for Rust on Arm.
|
||||
"not_build:arm",
|
||||
],
|
||||
deps = [
|
||||
"@crate_index//:googletest",
|
||||
"//rust:protobuf_upb",
|
||||
"//rust/test:unittest_upb_rust_proto",
|
||||
],
|
||||
)
|
||||
|
||||
rust_test(
|
||||
name = "accessors_map_cpp_test",
|
||||
srcs = ["accessors_map_test.rs"],
|
||||
|
|
|
@ -41,3 +41,15 @@ generate_map_primitives_tests!(
|
|||
(i32, f64, int32, double),
|
||||
(bool, bool, bool, bool)
|
||||
);
|
||||
|
||||
#[test]
|
||||
fn test_string_maps() {
|
||||
let mut msg = TestMap::new();
|
||||
msg.map_string_string_mut().insert("hello", "world".into());
|
||||
msg.map_string_string_mut().insert("fizz", "buzz".into());
|
||||
assert_that!(msg.map_string_string().len(), eq(2));
|
||||
assert_that!(msg.map_string_string().get("fizz").unwrap(), eq("buzz"));
|
||||
assert_that!(msg.map_string_string().get("not found"), eq(None));
|
||||
msg.map_string_string_mut().clear();
|
||||
assert_that!(msg.map_string_string().len(), eq(0));
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ fn test_fixed32_accessors() {
|
|||
assert_that!(msg.optional_fixed32_mut().get(), eq(42));
|
||||
assert_that!(msg.optional_fixed32(), eq(42));
|
||||
|
||||
msg.optional_fixed32_mut().clear();
|
||||
msg.optional_fixed32_mut().set(u32::default());
|
||||
assert_that!(msg.optional_fixed32(), eq(0));
|
||||
assert_that!(msg.optional_fixed32_mut().get(), eq(0));
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ fn test_bool_accessors() {
|
|||
assert_that!(msg.optional_bool(), eq(true));
|
||||
assert_that!(msg.optional_bool_mut().get(), eq(true));
|
||||
|
||||
msg.optional_bool_mut().clear();
|
||||
msg.optional_bool_mut().set(bool::default());
|
||||
assert_that!(msg.optional_bool(), eq(false));
|
||||
assert_that!(msg.optional_bool_mut().get(), eq(false));
|
||||
}
|
||||
|
@ -191,11 +191,11 @@ fn test_oneof_accessors() {
|
|||
let mut msg = TestAllTypes::new();
|
||||
assert_that!(msg.oneof_field(), matches_pattern!(not_set(_)));
|
||||
|
||||
msg.oneof_uint32_set(Some(7));
|
||||
msg.oneof_uint32_mut().set(7);
|
||||
assert_that!(msg.oneof_uint32_opt(), eq(Optional::Set(7)));
|
||||
assert_that!(msg.oneof_field(), matches_pattern!(OneofUint32(eq(7))));
|
||||
|
||||
msg.oneof_uint32_set(None);
|
||||
msg.oneof_uint32_mut().clear();
|
||||
assert_that!(msg.oneof_uint32_opt(), eq(Optional::Unset(0)));
|
||||
assert_that!(msg.oneof_field(), matches_pattern!(not_set(_)));
|
||||
|
||||
|
@ -209,7 +209,7 @@ fn test_oneof_accessors() {
|
|||
// eq(Optional::Unset(_))); assert_that!(msg.oneof_field(),
|
||||
// matches_pattern!(OneofNestedMessage(_)));
|
||||
|
||||
msg.oneof_uint32_set(Some(7));
|
||||
msg.oneof_uint32_mut().set(7);
|
||||
msg.oneof_bytes_mut().set(b"123");
|
||||
assert_that!(msg.oneof_uint32_opt(), eq(Optional::Unset(0)));
|
||||
assert_that!(msg.oneof_field(), matches_pattern!(OneofBytes(eq(b"123"))));
|
||||
|
@ -225,7 +225,7 @@ fn test_oneof_mut_accessors() {
|
|||
let mut msg = TestAllTypes::new();
|
||||
assert_that!(msg.oneof_field_mut(), matches_pattern!(not_set(_)));
|
||||
|
||||
msg.oneof_uint32_set(Some(7));
|
||||
msg.oneof_uint32_mut().set(7);
|
||||
|
||||
match msg.oneof_field_mut() {
|
||||
OneofUint32(mut v) => {
|
||||
|
@ -244,10 +244,10 @@ fn test_oneof_mut_accessors() {
|
|||
matches_pattern!(TestAllTypes_::OneofField::OneofUint32(eq(8)))
|
||||
);
|
||||
|
||||
msg.oneof_uint32_set(None);
|
||||
msg.oneof_uint32_mut().clear();
|
||||
assert_that!(msg.oneof_field_mut(), matches_pattern!(not_set(_)));
|
||||
|
||||
msg.oneof_uint32_set(Some(7));
|
||||
msg.oneof_uint32_mut().set(7);
|
||||
msg.oneof_bytes_mut().set(b"123");
|
||||
assert_that!(msg.oneof_field_mut(), matches_pattern!(OneofBytes(_)));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2023 Google LLC. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
use googletest::prelude::*;
|
||||
use paste::paste;
|
||||
use unittest_proto::proto2_unittest::TestAllTypes;
|
||||
|
||||
macro_rules! generate_repeated_numeric_test {
|
||||
($(($t: ty, $field: ident)),*) => {
|
||||
paste! { $(
|
||||
#[test]
|
||||
fn [< test_repeated_ $field _accessors >]() {
|
||||
let mut msg = TestAllTypes::new();
|
||||
assert_that!(msg.[< repeated_ $field >]().len(), eq(0));
|
||||
assert_that!(msg.[<repeated_ $field >]().get(0), none());
|
||||
|
||||
let mut mutator = msg.[<repeated_ $field _mut >]();
|
||||
mutator.push(1 as $t);
|
||||
assert_that!(mutator.len(), eq(1));
|
||||
assert_that!(mutator.get(0), some(eq(1 as $t)));
|
||||
mutator.set(0, 2 as $t);
|
||||
assert_that!(mutator.get(0), some(eq(2 as $t)));
|
||||
mutator.push(1 as $t);
|
||||
|
||||
mutator.push(3 as $t);
|
||||
mutator.set(2, 4 as $t);
|
||||
assert_that!(mutator.get(2), some(eq(4 as $t)));
|
||||
mutator.set(2, 0 as $t);
|
||||
|
||||
assert_that!(
|
||||
mutator.iter().collect::<Vec<_>>(),
|
||||
eq(vec![2 as $t, 1 as $t, 0 as $t])
|
||||
);
|
||||
assert_that!(
|
||||
(*mutator).into_iter().collect::<Vec<_>>(),
|
||||
eq(vec![2 as $t, 1 as $t, 0 as $t])
|
||||
);
|
||||
|
||||
for i in 0..mutator.len() {
|
||||
mutator.set(i, 0 as $t);
|
||||
}
|
||||
assert_that!(
|
||||
msg.[<repeated_ $field _mut >]().iter().all(|v| v == (0 as $t)),
|
||||
eq(true)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn [< test_repeated_ $field _set >]() {
|
||||
let mut msg = TestAllTypes::new();
|
||||
let mut mutator = msg.[<repeated_ $field _mut>]();
|
||||
let mut msg2 = TestAllTypes::new();
|
||||
let mut mutator2 = msg2.[<repeated_ $field _mut>]();
|
||||
for i in 0..5 {
|
||||
mutator2.push(i as $t);
|
||||
}
|
||||
protobuf::MutProxy::set(&mut mutator, *mutator2);
|
||||
|
||||
assert_that!(
|
||||
mutator.iter().collect::<Vec<_>>(),
|
||||
eq(mutator2.iter().collect::<Vec<_>>())
|
||||
);
|
||||
}
|
||||
)* }
|
||||
};
|
||||
}
|
||||
|
||||
generate_repeated_numeric_test!(
|
||||
(i32, int32),
|
||||
(u32, uint32),
|
||||
(i64, int64),
|
||||
(u64, uint64),
|
||||
(f32, float),
|
||||
(f64, double)
|
||||
);
|
||||
|
||||
#[test]
|
||||
fn test_repeated_bool_accessors() {
|
||||
let mut msg = TestAllTypes::new();
|
||||
assert_that!(msg.repeated_bool().len(), eq(0));
|
||||
assert_that!(msg.repeated_bool().get(0), none());
|
||||
|
||||
let mut mutator = msg.repeated_bool_mut();
|
||||
mutator.push(true);
|
||||
assert_that!(mutator.len(), eq(1));
|
||||
assert_that!(mutator.get(0), some(eq(true)));
|
||||
mutator.set(0, false);
|
||||
assert_that!(mutator.get(0), some(eq(false)));
|
||||
mutator.push(true);
|
||||
|
||||
mutator.push(false);
|
||||
mutator.set(2, true);
|
||||
assert_that!(mutator.get(2), some(eq(true)));
|
||||
mutator.set(2, false);
|
||||
assert_that!(mutator.get(2), some(eq(false)));
|
||||
|
||||
assert_that!(mutator.iter().collect::<Vec<_>>(), eq(vec![false, true, false]));
|
||||
assert_that!((*mutator).into_iter().collect::<Vec<_>>(), eq(vec![false, true, false]));
|
||||
|
||||
for i in 0..mutator.len() {
|
||||
mutator.set(i, false);
|
||||
}
|
||||
assert_that!(msg.repeated_bool().iter().all(|v| v), eq(false));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_repeated_bool_set() {
|
||||
let mut msg = TestAllTypes::new();
|
||||
let mut mutator = msg.repeated_bool_mut();
|
||||
let mut msg2 = TestAllTypes::new();
|
||||
let mut mutator2 = msg2.repeated_bool_mut();
|
||||
for _ in 0..5 {
|
||||
mutator2.push(true);
|
||||
}
|
||||
protobuf::MutProxy::set(&mut mutator, *mutator2);
|
||||
|
||||
assert_that!(mutator.iter().collect::<Vec<_>>(), eq(mutator2.iter().collect::<Vec<_>>()));
|
||||
}
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
use googletest::prelude::*;
|
||||
use matchers::{is_set, is_unset};
|
||||
use paste::paste;
|
||||
use protobuf::Optional;
|
||||
use unittest_proto::proto2_unittest::{TestAllTypes, TestAllTypes_};
|
||||
|
||||
|
@ -34,6 +33,8 @@ fn test_default_accessors() {
|
|||
default_bool(): eq(true),
|
||||
})
|
||||
);
|
||||
assert_that!(msg.default_string(), eq("hello"));
|
||||
assert_that!(msg.default_bytes(), eq("world".as_bytes()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -42,11 +43,11 @@ fn test_optional_fixed32_accessors() {
|
|||
assert_that!(msg.optional_fixed32_opt(), eq(Optional::Unset(0)));
|
||||
assert_that!(msg.optional_fixed32(), eq(0));
|
||||
|
||||
msg.optional_fixed32_set(Some(99));
|
||||
msg.optional_fixed32_mut().set(99);
|
||||
assert_that!(msg.optional_fixed32_opt(), eq(Optional::Set(99)));
|
||||
assert_that!(msg.optional_fixed32(), eq(99));
|
||||
|
||||
msg.optional_fixed32_set(None);
|
||||
msg.optional_fixed32_mut().clear();
|
||||
assert_that!(msg.optional_fixed32_opt(), eq(Optional::Unset(0)));
|
||||
assert_that!(msg.optional_fixed32(), eq(0));
|
||||
}
|
||||
|
@ -84,11 +85,11 @@ fn test_optional_fixed64_accessors() {
|
|||
assert_that!(msg.optional_fixed64_opt(), eq(Optional::Unset(0)));
|
||||
assert_that!(msg.optional_fixed64(), eq(0));
|
||||
|
||||
msg.optional_fixed64_set(Some(2000));
|
||||
msg.optional_fixed64_mut().set(2000);
|
||||
assert_that!(msg.optional_fixed64_opt(), eq(Optional::Set(2000)));
|
||||
assert_that!(msg.optional_fixed64(), eq(2000));
|
||||
|
||||
msg.optional_fixed64_set(None);
|
||||
msg.optional_fixed64_mut().clear();
|
||||
assert_that!(msg.optional_fixed64_opt(), eq(Optional::Unset(0)));
|
||||
assert_that!(msg.optional_fixed64(), eq(0));
|
||||
}
|
||||
|
@ -126,11 +127,11 @@ fn test_optional_int32_accessors() {
|
|||
assert_that!(msg.optional_int32_opt(), eq(Optional::Unset(0)));
|
||||
assert_that!(msg.optional_int32(), eq(0));
|
||||
|
||||
msg.optional_int32_set(Some(1));
|
||||
msg.optional_int32_mut().set(1);
|
||||
assert_that!(msg.optional_int32_opt(), eq(Optional::Set(1)));
|
||||
assert_that!(msg.optional_int32(), eq(1));
|
||||
|
||||
msg.optional_int32_set(None);
|
||||
msg.optional_int32_mut().clear();
|
||||
assert_that!(msg.optional_int32_opt(), eq(Optional::Unset(0)));
|
||||
assert_that!(msg.optional_int32(), eq(0));
|
||||
}
|
||||
|
@ -168,11 +169,11 @@ fn test_optional_int64_accessors() {
|
|||
assert_that!(msg.optional_int64_opt(), eq(Optional::Unset(0)));
|
||||
assert_that!(msg.optional_int64(), eq(0));
|
||||
|
||||
msg.optional_int64_set(Some(42));
|
||||
msg.optional_int64_mut().set(42);
|
||||
assert_that!(msg.optional_int64_opt(), eq(Optional::Set(42)));
|
||||
assert_that!(msg.optional_int64(), eq(42));
|
||||
|
||||
msg.optional_int64_set(None);
|
||||
msg.optional_int64_mut().clear();
|
||||
assert_that!(msg.optional_int64_opt(), eq(Optional::Unset(0)));
|
||||
assert_that!(msg.optional_int64(), eq(0));
|
||||
}
|
||||
|
@ -210,11 +211,11 @@ fn test_optional_sint32_accessors() {
|
|||
assert_that!(msg.optional_sint32_opt(), eq(Optional::Unset(0)));
|
||||
assert_that!(msg.optional_sint32(), eq(0));
|
||||
|
||||
msg.optional_sint32_set(Some(-22));
|
||||
msg.optional_sint32_mut().set(-22);
|
||||
assert_that!(msg.optional_sint32_opt(), eq(Optional::Set(-22)));
|
||||
assert_that!(msg.optional_sint32(), eq(-22));
|
||||
|
||||
msg.optional_sint32_set(None);
|
||||
msg.optional_sint32_mut().clear();
|
||||
assert_that!(msg.optional_sint32_opt(), eq(Optional::Unset(0)));
|
||||
assert_that!(msg.optional_sint32(), eq(0));
|
||||
}
|
||||
|
@ -252,11 +253,11 @@ fn test_optional_sint64_accessors() {
|
|||
assert_that!(msg.optional_sint64_opt(), eq(Optional::Unset(0)));
|
||||
assert_that!(msg.optional_sint64(), eq(0));
|
||||
|
||||
msg.optional_sint64_set(Some(7000));
|
||||
msg.optional_sint64_mut().set(7000);
|
||||
assert_that!(msg.optional_sint64_opt(), eq(Optional::Set(7000)));
|
||||
assert_that!(msg.optional_sint64(), eq(7000));
|
||||
|
||||
msg.optional_sint64_set(None);
|
||||
msg.optional_sint64_mut().clear();
|
||||
assert_that!(msg.optional_sint64_opt(), eq(Optional::Unset(0)));
|
||||
assert_that!(msg.optional_sint64(), eq(0));
|
||||
}
|
||||
|
@ -294,11 +295,11 @@ fn test_optional_uint32_accessors() {
|
|||
assert_that!(msg.optional_uint32_opt(), eq(Optional::Unset(0)));
|
||||
assert_that!(msg.optional_uint32(), eq(0));
|
||||
|
||||
msg.optional_uint32_set(Some(9001));
|
||||
msg.optional_uint32_mut().set(9001);
|
||||
assert_that!(msg.optional_uint32_opt(), eq(Optional::Set(9001)));
|
||||
assert_that!(msg.optional_uint32(), eq(9001));
|
||||
|
||||
msg.optional_uint32_set(None);
|
||||
msg.optional_uint32_mut().clear();
|
||||
assert_that!(msg.optional_uint32_opt(), eq(Optional::Unset(0)));
|
||||
assert_that!(msg.optional_uint32(), eq(0));
|
||||
}
|
||||
|
@ -336,11 +337,11 @@ fn test_optional_uint64_accessors() {
|
|||
assert_that!(msg.optional_uint64_opt(), eq(Optional::Unset(0)));
|
||||
assert_that!(msg.optional_uint64(), eq(0));
|
||||
|
||||
msg.optional_uint64_set(Some(42));
|
||||
msg.optional_uint64_mut().set(42);
|
||||
assert_that!(msg.optional_uint64_opt(), eq(Optional::Set(42)));
|
||||
assert_that!(msg.optional_uint64(), eq(42));
|
||||
|
||||
msg.optional_uint64_set(None);
|
||||
msg.optional_uint64_mut().clear();
|
||||
assert_that!(msg.optional_uint64_opt(), eq(Optional::Unset(0)));
|
||||
assert_that!(msg.optional_uint64(), eq(0));
|
||||
}
|
||||
|
@ -378,11 +379,11 @@ fn test_optional_float_accessors() {
|
|||
assert_that!(msg.optional_float_opt(), eq(Optional::Unset(0.0)));
|
||||
assert_that!(msg.optional_float(), eq(0.0));
|
||||
|
||||
msg.optional_float_set(Some(std::f32::consts::PI));
|
||||
msg.optional_float_mut().set(std::f32::consts::PI);
|
||||
assert_that!(msg.optional_float_opt(), eq(Optional::Set(std::f32::consts::PI)));
|
||||
assert_that!(msg.optional_float(), eq(std::f32::consts::PI));
|
||||
|
||||
msg.optional_float_set(None);
|
||||
msg.optional_float_mut().clear();
|
||||
assert_that!(msg.optional_float_opt(), eq(Optional::Unset(0.0)));
|
||||
assert_that!(msg.optional_float(), eq(0.0));
|
||||
}
|
||||
|
@ -420,11 +421,11 @@ fn test_optional_double_accessors() {
|
|||
assert_that!(msg.optional_double_opt(), eq(Optional::Unset(0.0)));
|
||||
assert_that!(msg.optional_double(), eq(0.0));
|
||||
|
||||
msg.optional_double_set(Some(-10.99));
|
||||
msg.optional_double_mut().set(-10.99);
|
||||
assert_that!(msg.optional_double_opt(), eq(Optional::Set(-10.99)));
|
||||
assert_that!(msg.optional_double(), eq(-10.99));
|
||||
|
||||
msg.optional_double_set(None);
|
||||
msg.optional_double_mut().clear();
|
||||
assert_that!(msg.optional_double_opt(), eq(Optional::Unset(0.0)));
|
||||
assert_that!(msg.optional_double(), eq(0.0));
|
||||
}
|
||||
|
@ -461,10 +462,10 @@ fn test_optional_bool_accessors() {
|
|||
let mut msg = TestAllTypes::new();
|
||||
assert_that!(msg.optional_bool_opt(), eq(Optional::Unset(false)));
|
||||
|
||||
msg.optional_bool_set(Some(true));
|
||||
msg.optional_bool_mut().set(true);
|
||||
assert_that!(msg.optional_bool_opt(), eq(Optional::Set(true)));
|
||||
|
||||
msg.optional_bool_set(None);
|
||||
msg.optional_bool_mut().clear();
|
||||
assert_that!(msg.optional_bool_opt(), eq(Optional::Unset(false)));
|
||||
}
|
||||
|
||||
|
@ -686,15 +687,15 @@ fn test_oneof_accessors() {
|
|||
let mut msg = TestAllTypes::new();
|
||||
assert_that!(msg.oneof_field(), matches_pattern!(not_set(_)));
|
||||
|
||||
msg.oneof_uint32_set(Some(7));
|
||||
msg.oneof_uint32_mut().set(7);
|
||||
assert_that!(msg.oneof_uint32_opt(), eq(Optional::Set(7)));
|
||||
assert_that!(msg.oneof_field(), matches_pattern!(OneofUint32(eq(7))));
|
||||
|
||||
msg.oneof_uint32_set(None);
|
||||
msg.oneof_uint32_mut().clear();
|
||||
assert_that!(msg.oneof_uint32_opt(), eq(Optional::Unset(0)));
|
||||
assert_that!(msg.oneof_field(), matches_pattern!(not_set(_)));
|
||||
|
||||
msg.oneof_uint32_set(Some(7));
|
||||
msg.oneof_uint32_mut().set(7);
|
||||
msg.oneof_bytes_mut().set(b"123");
|
||||
assert_that!(msg.oneof_uint32_opt(), eq(Optional::Unset(0)));
|
||||
|
||||
|
@ -708,7 +709,7 @@ fn test_oneof_mut_accessors() {
|
|||
let mut msg = TestAllTypes::new();
|
||||
assert_that!(msg.oneof_field_mut(), matches_pattern!(not_set(_)));
|
||||
|
||||
msg.oneof_uint32_set(Some(7));
|
||||
msg.oneof_uint32_mut().set(7);
|
||||
|
||||
match msg.oneof_field_mut() {
|
||||
OneofUint32(mut v) => {
|
||||
|
@ -727,127 +728,10 @@ fn test_oneof_mut_accessors() {
|
|||
matches_pattern!(TestAllTypes_::OneofField::OneofUint32(eq(8)))
|
||||
);
|
||||
|
||||
msg.oneof_uint32_set(None);
|
||||
msg.oneof_uint32_mut().clear();
|
||||
assert_that!(msg.oneof_field_mut(), matches_pattern!(not_set(_)));
|
||||
|
||||
msg.oneof_uint32_set(Some(7));
|
||||
msg.oneof_uint32_mut().set(7);
|
||||
msg.oneof_bytes_mut().set(b"123");
|
||||
assert_that!(msg.oneof_field_mut(), matches_pattern!(OneofBytes(_)));
|
||||
}
|
||||
|
||||
macro_rules! generate_repeated_numeric_test {
|
||||
($(($t: ty, $field: ident)),*) => {
|
||||
paste! { $(
|
||||
#[test]
|
||||
fn [< test_repeated_ $field _accessors >]() {
|
||||
let mut msg = TestAllTypes::new();
|
||||
assert_that!(msg.[< repeated_ $field >]().len(), eq(0));
|
||||
assert_that!(msg.[<repeated_ $field >]().get(0), none());
|
||||
|
||||
let mut mutator = msg.[<repeated_ $field _mut >]();
|
||||
mutator.push(1 as $t);
|
||||
assert_that!(mutator.len(), eq(1));
|
||||
assert_that!(mutator.get(0), some(eq(1 as $t)));
|
||||
mutator.set(0, 2 as $t);
|
||||
assert_that!(mutator.get(0), some(eq(2 as $t)));
|
||||
mutator.push(1 as $t);
|
||||
|
||||
mutator.push(3 as $t);
|
||||
assert_that!(mutator.get_mut(2).is_some(), eq(true));
|
||||
let mut mut_elem = mutator.get_mut(2).unwrap();
|
||||
mut_elem.set(4 as $t);
|
||||
assert_that!(mut_elem.get(), eq(4 as $t));
|
||||
mut_elem.clear();
|
||||
assert_that!(mut_elem.get(), eq(0 as $t));
|
||||
|
||||
assert_that!(
|
||||
mutator.iter().collect::<Vec<_>>(),
|
||||
eq(vec![2 as $t, 1 as $t, 0 as $t])
|
||||
);
|
||||
assert_that!(
|
||||
(*mutator).into_iter().collect::<Vec<_>>(),
|
||||
eq(vec![2 as $t, 1 as $t, 0 as $t])
|
||||
);
|
||||
|
||||
for mut mutable_elem in msg.[<repeated_ $field _mut >]() {
|
||||
mutable_elem.set(0 as $t);
|
||||
}
|
||||
assert_that!(
|
||||
msg.[<repeated_ $field _mut >]().iter().all(|v| v == (0 as $t)),
|
||||
eq(true)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn [< test_repeated_ $field _set >]() {
|
||||
let mut msg = TestAllTypes::new();
|
||||
let mut mutator = msg.[<repeated_ $field _mut>]();
|
||||
let mut msg2 = TestAllTypes::new();
|
||||
let mut mutator2 = msg2.[<repeated_ $field _mut>]();
|
||||
for i in 0..5 {
|
||||
mutator2.push(i as $t);
|
||||
}
|
||||
protobuf::MutProxy::set(&mut mutator, *mutator2);
|
||||
|
||||
assert_that!(
|
||||
mutator.iter().collect::<Vec<_>>(),
|
||||
eq(mutator2.iter().collect::<Vec<_>>())
|
||||
);
|
||||
}
|
||||
)* }
|
||||
};
|
||||
}
|
||||
|
||||
generate_repeated_numeric_test!(
|
||||
(i32, int32),
|
||||
(u32, uint32),
|
||||
(i64, int64),
|
||||
(u64, uint64),
|
||||
(f32, float),
|
||||
(f64, double)
|
||||
);
|
||||
|
||||
#[test]
|
||||
fn test_repeated_bool_accessors() {
|
||||
let mut msg = TestAllTypes::new();
|
||||
assert_that!(msg.repeated_bool().len(), eq(0));
|
||||
assert_that!(msg.repeated_bool().get(0), none());
|
||||
|
||||
let mut mutator = msg.repeated_bool_mut();
|
||||
mutator.push(true);
|
||||
assert_that!(mutator.len(), eq(1));
|
||||
assert_that!(mutator.get(0), some(eq(true)));
|
||||
mutator.set(0, false);
|
||||
assert_that!(mutator.get(0), some(eq(false)));
|
||||
mutator.push(true);
|
||||
|
||||
mutator.push(false);
|
||||
assert_that!(mutator.get_mut(2), pat!(Some(_)));
|
||||
let mut mut_elem = mutator.get_mut(2).unwrap();
|
||||
mut_elem.set(true);
|
||||
assert_that!(mut_elem.get(), eq(true));
|
||||
mut_elem.clear();
|
||||
assert_that!(mut_elem.get(), eq(false));
|
||||
|
||||
assert_that!(mutator.iter().collect::<Vec<_>>(), eq(vec![false, true, false]));
|
||||
assert_that!((*mutator).into_iter().collect::<Vec<_>>(), eq(vec![false, true, false]));
|
||||
|
||||
for mut mutable_elem in msg.repeated_bool_mut() {
|
||||
mutable_elem.set(false);
|
||||
}
|
||||
assert_that!(msg.repeated_bool().iter().all(|v| v), eq(false));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_repeated_bool_set() {
|
||||
let mut msg = TestAllTypes::new();
|
||||
let mut mutator = msg.repeated_bool_mut();
|
||||
let mut msg2 = TestAllTypes::new();
|
||||
let mut mutator2 = msg2.repeated_bool_mut();
|
||||
for _ in 0..5 {
|
||||
mutator2.push(true);
|
||||
}
|
||||
protobuf::MutProxy::set(&mut mutator, *mutator2);
|
||||
|
||||
assert_that!(mutator.iter().collect::<Vec<_>>(), eq(mutator2.iter().collect::<Vec<_>>()));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2023 Google LLC. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
use googletest::prelude::*;
|
||||
|
||||
// Tests that an proto file that declares edition="2023" works. Note that this
|
||||
// is _not_ a test for Rust Edition 2023 (which doesn't exist) but instead
|
||||
// Protobuf Edition 2023 (which exists).
|
||||
|
||||
#[test]
|
||||
fn check_edition2023_works() {
|
||||
let mut msg = edition2023_proto::test::EditionsMessage::new();
|
||||
|
||||
// plain_field supports presence.
|
||||
assert_that!(msg.plain_field_mut().or_default().get(), eq(0));
|
||||
|
||||
// implicit presence fields' _mut() skips FieldEntry.
|
||||
assert_that!(msg.implicit_presence_field_mut().get(), eq(0));
|
||||
}
|
|
@ -11,8 +11,8 @@ use unittest_proto::proto2_unittest::TestAllTypes;
|
|||
#[test]
|
||||
fn serialize_deserialize_message() {
|
||||
let mut msg = TestAllTypes::new();
|
||||
msg.optional_int64_set(Some(42));
|
||||
msg.optional_bool_set(Some(true));
|
||||
msg.optional_int64_mut().set(42);
|
||||
msg.optional_bool_mut().set(true);
|
||||
msg.optional_bytes_mut().set(b"serialize deserialize test");
|
||||
|
||||
let serialized = msg.serialize();
|
||||
|
|
|
@ -10,6 +10,16 @@ use nested_proto::nest::Outer;
|
|||
use nested_proto::nest::Outer_::InnerMut;
|
||||
use nested_proto::nest::Outer_::InnerView;
|
||||
|
||||
#[test]
|
||||
fn test_deeply_nested_definition() {
|
||||
let deep = nested_proto::nest::Outer_::Inner_::SuperInner_::DuperInner_::EvenMoreInner_
|
||||
::CantBelieveItsSoInner::new();
|
||||
assert_that!(deep.num(), eq(0));
|
||||
|
||||
let outer_msg = Outer::new();
|
||||
assert_that!(outer_msg.deep().num(), eq(0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nested_views() {
|
||||
let outer_msg = Outer::new();
|
||||
|
@ -29,37 +39,80 @@ fn test_nested_views() {
|
|||
assert_that!(inner_msg.bool(), eq(false));
|
||||
assert_that!(*inner_msg.string().as_bytes(), empty());
|
||||
assert_that!(*inner_msg.bytes(), empty());
|
||||
assert_that!(inner_msg.innersubmsg().flag(), eq(false));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nested_muts() {
|
||||
// TODO: add actual mutation logic, this just peeks at InnerMut at
|
||||
// the moment
|
||||
// Covers the setting of a mut and the following assertion
|
||||
// confirming the new value. Replacement example:
|
||||
// old:
|
||||
// inner_msg.double_mut().set(543.21);
|
||||
// assert_that!(inner_msg.double_mut().get(), eq(543.21));
|
||||
// new:
|
||||
// set_and_test_mut!(inner_msg => double_mut, 543.21);
|
||||
macro_rules! set_and_test_mut {
|
||||
( $a:expr => $($target_mut:ident, $val:literal;)* ) => {
|
||||
$(
|
||||
$a.$target_mut().set($val);
|
||||
assert_that!($a.$target_mut().get(), eq($val));
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
let mut outer_msg = Outer::new();
|
||||
let inner_msg: InnerMut<'_> = outer_msg.inner_mut();
|
||||
assert_that!(inner_msg.double(), eq(0.0));
|
||||
assert_that!(inner_msg.float(), eq(0.0));
|
||||
assert_that!(inner_msg.int32(), eq(0));
|
||||
assert_that!(inner_msg.int64(), eq(0));
|
||||
assert_that!(inner_msg.uint32(), eq(0));
|
||||
assert_that!(inner_msg.uint64(), eq(0));
|
||||
assert_that!(inner_msg.sint32(), eq(0));
|
||||
assert_that!(inner_msg.sint64(), eq(0));
|
||||
assert_that!(inner_msg.fixed32(), eq(0));
|
||||
assert_that!(inner_msg.fixed64(), eq(0));
|
||||
assert_that!(inner_msg.sfixed32(), eq(0));
|
||||
assert_that!(inner_msg.sfixed64(), eq(0));
|
||||
assert_that!(inner_msg.bool(), eq(false));
|
||||
assert_that!(*inner_msg.string().as_bytes(), empty());
|
||||
assert_that!(*inner_msg.bytes(), empty());
|
||||
assert_that!(
|
||||
inner_msg,
|
||||
matches_pattern!(InnerMut{
|
||||
float(): eq(0.0),
|
||||
double(): eq(0.0),
|
||||
int32(): eq(0),
|
||||
int64(): eq(0),
|
||||
uint32(): eq(0),
|
||||
uint64(): eq(0),
|
||||
sint32(): eq(0),
|
||||
sint64(): eq(0),
|
||||
fixed32(): eq(0),
|
||||
fixed64(): eq(0),
|
||||
sfixed32(): eq(0),
|
||||
sfixed64(): eq(0),
|
||||
bool(): eq(false)
|
||||
})
|
||||
);
|
||||
assert_that!(inner_msg.string_mut().get(), eq(""));
|
||||
assert_that!(inner_msg.bytes_mut().get(), eq(b""));
|
||||
|
||||
set_and_test_mut!(inner_msg =>
|
||||
double_mut, 543.21;
|
||||
float_mut, 1.23;
|
||||
int32_mut, 12;
|
||||
int64_mut, 42;
|
||||
uint32_mut, 13;
|
||||
uint64_mut, 5000;
|
||||
sint32_mut, -2;
|
||||
sint64_mut, 322;
|
||||
fixed32_mut, 77;
|
||||
fixed64_mut, 999;
|
||||
bool_mut, true;
|
||||
string_mut, "hi";
|
||||
bytes_mut, b"bye";
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_deeply_nested_definition() {
|
||||
let deep = nested_proto::nest::Outer_::Inner_::SuperInner_::DuperInner_::EvenMoreInner_
|
||||
::CantBelieveItsSoInner::new();
|
||||
assert_eq!(deep.num(), 0);
|
||||
|
||||
let outer_msg = Outer::new();
|
||||
assert_eq!(outer_msg.deep().num(), 0);
|
||||
fn test_msg_from_outside() {
|
||||
// let's make sure that we're not just working for messages nested inside
|
||||
// messages, messages from without and within should work
|
||||
let outer = nested_proto::nest::Outer::new();
|
||||
assert_that!(outer.notinside().num(), eq(0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_recursive_msg() {
|
||||
let rec = nested_proto::nest::Recursive::new();
|
||||
assert_that!(rec.num(), eq(0));
|
||||
assert_that!(rec.rec().num(), eq(0));
|
||||
assert_that!(rec.rec().rec().num(), eq(0)); // turtles all the way down...
|
||||
assert_that!(rec.rec().rec().rec().num(), eq(0)); // ... ad infinitum
|
||||
}
|
||||
|
|
496
rust/upb.rs
496
rust/upb.rs
|
@ -7,19 +7,22 @@
|
|||
|
||||
//! UPB FFI wrapper code for use by Rust Protobuf.
|
||||
|
||||
use crate::ProtoStr;
|
||||
use crate::__internal::{Private, PtrAndLen, RawArena, RawMap, RawMessage, RawRepeatedField};
|
||||
use crate::{Mut, ProxiedInRepeated, Repeated, RepeatedMut, RepeatedView, View, ViewProxy};
|
||||
use core::fmt::Debug;
|
||||
use paste::paste;
|
||||
use std::alloc;
|
||||
use std::alloc::Layout;
|
||||
use std::cell::UnsafeCell;
|
||||
use std::ffi::c_int;
|
||||
use std::fmt;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem::{size_of, MaybeUninit};
|
||||
use std::ops::Deref;
|
||||
use std::ptr::{self, NonNull};
|
||||
use std::slice;
|
||||
use std::sync::Once;
|
||||
use std::sync::{Once, OnceLock};
|
||||
|
||||
/// See `upb/port/def.inc`.
|
||||
const UPB_MALLOC_ALIGN: usize = 8;
|
||||
|
@ -216,7 +219,7 @@ impl fmt::Debug for SerializedData {
|
|||
pub type BytesPresentMutData<'msg> = crate::vtable::RawVTableOptionalMutatorData<'msg, [u8]>;
|
||||
pub type BytesAbsentMutData<'msg> = crate::vtable::RawVTableOptionalMutatorData<'msg, [u8]>;
|
||||
pub type InnerBytesMut<'msg> = crate::vtable::RawVTableMutator<'msg, [u8]>;
|
||||
pub type InnerPrimitiveMut<'a, T> = crate::vtable::RawVTableMutator<'a, T>;
|
||||
pub type InnerPrimitiveMut<'msg, T> = crate::vtable::RawVTableMutator<'msg, T>;
|
||||
|
||||
/// The raw contents of every generated message.
|
||||
#[derive(Debug)]
|
||||
|
@ -276,10 +279,10 @@ impl<'msg> MutatorMessageRef<'msg> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn copy_bytes_in_arena_if_needed_by_runtime<'a>(
|
||||
msg_ref: MutatorMessageRef<'a>,
|
||||
val: &'a [u8],
|
||||
) -> &'a [u8] {
|
||||
pub fn copy_bytes_in_arena_if_needed_by_runtime<'msg>(
|
||||
msg_ref: MutatorMessageRef<'msg>,
|
||||
val: &'msg [u8],
|
||||
) -> &'msg [u8] {
|
||||
// SAFETY: the alignment of `[u8]` is less than `UPB_MALLOC_ALIGN`.
|
||||
let new_alloc = unsafe { msg_ref.arena.alloc(Layout::for_value(val)) };
|
||||
debug_assert_eq!(new_alloc.len(), val.len());
|
||||
|
@ -294,40 +297,28 @@ pub fn copy_bytes_in_arena_if_needed_by_runtime<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
/// RepeatedFieldInner contains a `upb_Array*` as well as a reference to an
|
||||
/// `Arena`, most likely that of the containing `Message`. upb requires an Arena
|
||||
/// to perform mutations on a repeated field.
|
||||
/// The raw type-erased pointer version of `RepeatedMut`.
|
||||
///
|
||||
/// Contains a `upb_Array*` as well as `RawArena`, most likely that of the
|
||||
/// containing message. upb requires a `RawArena` to perform mutations on
|
||||
/// a repeated field.
|
||||
///
|
||||
/// An owned `Repeated` stores a `InnerRepeatedMut<'static>` and manages the
|
||||
/// contained `RawArena`.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct RepeatedFieldInner<'msg> {
|
||||
pub raw: RawRepeatedField,
|
||||
pub arena: &'msg Arena,
|
||||
pub struct InnerRepeatedMut<'msg> {
|
||||
pub(crate) raw: RawRepeatedField,
|
||||
// Storing a `RawArena` instead of `&Arena` allows this to be used for
|
||||
// both `RepeatedMut<T>` and `Repeated<T>`.
|
||||
arena: RawArena,
|
||||
_phantom: PhantomData<&'msg Arena>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RepeatedField<'msg, T: ?Sized> {
|
||||
inner: RepeatedFieldInner<'msg>,
|
||||
_phantom: PhantomData<&'msg mut T>,
|
||||
}
|
||||
|
||||
// These use manual impls instead of derives to avoid unnecessary bounds on `T`.
|
||||
// This problem is referred to as "perfect derive".
|
||||
// https://smallcultfollowing.com/babysteps/blog/2022/04/12/implied-bounds-and-perfect-derive/
|
||||
impl<'msg, T: ?Sized> Copy for RepeatedField<'msg, T> {}
|
||||
impl<'msg, T: ?Sized> Clone for RepeatedField<'msg, T> {
|
||||
fn clone(&self) -> RepeatedField<'msg, T> {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'msg, T: ?Sized> RepeatedField<'msg, T> {
|
||||
pub fn len(&self) -> usize {
|
||||
unsafe { upb_Array_Size(self.inner.raw) }
|
||||
}
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
pub fn from_inner(_private: Private, inner: RepeatedFieldInner<'msg>) -> Self {
|
||||
Self { inner, _phantom: PhantomData }
|
||||
impl<'msg> InnerRepeatedMut<'msg> {
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::needless_pass_by_ref_mut)] // Sound construction requires mutable access.
|
||||
pub fn new(_private: Private, raw: RawRepeatedField, arena: &'msg Arena) -> Self {
|
||||
InnerRepeatedMut { raw, arena: arena.raw(), _phantom: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -366,7 +357,6 @@ pub enum UpbCType {
|
|||
}
|
||||
|
||||
extern "C" {
|
||||
#[allow(dead_code)]
|
||||
fn upb_Array_New(a: RawArena, r#type: std::ffi::c_int) -> RawRepeatedField;
|
||||
fn upb_Array_Size(arr: RawRepeatedField) -> usize;
|
||||
fn upb_Array_Set(arr: RawRepeatedField, i: usize, val: upb_MessageValue);
|
||||
|
@ -378,56 +368,65 @@ extern "C" {
|
|||
}
|
||||
|
||||
macro_rules! impl_repeated_primitives {
|
||||
($(($rs_type:ty, $ufield:ident, $upb_tag:expr)),*) => {
|
||||
($(($t:ty, $ufield:ident, $upb_tag:expr)),* $(,)?) => {
|
||||
$(
|
||||
impl<'msg> RepeatedField<'msg, $rs_type> {
|
||||
unsafe impl ProxiedInRepeated for $t {
|
||||
#[allow(dead_code)]
|
||||
fn new(arena: &'msg Arena) -> Self {
|
||||
Self {
|
||||
inner: RepeatedFieldInner {
|
||||
raw: unsafe { upb_Array_New(arena.raw, $upb_tag as std::ffi::c_int) },
|
||||
arena,
|
||||
},
|
||||
_phantom: PhantomData,
|
||||
fn repeated_new(_: Private) -> Repeated<$t> {
|
||||
let arena = Arena::new();
|
||||
let raw_arena = arena.raw();
|
||||
std::mem::forget(arena);
|
||||
unsafe {
|
||||
Repeated::from_inner(InnerRepeatedMut {
|
||||
raw: upb_Array_New(raw_arena, $upb_tag as c_int),
|
||||
arena: raw_arena,
|
||||
_phantom: PhantomData,
|
||||
})
|
||||
}
|
||||
}
|
||||
pub fn push(&mut self, val: $rs_type) {
|
||||
unsafe { upb_Array_Append(
|
||||
self.inner.raw,
|
||||
upb_MessageValue { $ufield: val },
|
||||
self.inner.arena.raw(),
|
||||
) }
|
||||
}
|
||||
pub fn get(&self, i: usize) -> Option<$rs_type> {
|
||||
if i >= self.len() {
|
||||
None
|
||||
} else {
|
||||
unsafe { Some(upb_Array_Get(self.inner.raw, i).$ufield) }
|
||||
#[allow(dead_code)]
|
||||
unsafe fn repeated_free(_: Private, f: &mut Repeated<$t>) {
|
||||
// Freeing the array itself is handled by `Arena::Drop`
|
||||
// SAFETY:
|
||||
// - `f.raw_arena()` is a live `upb_Arena*` as
|
||||
// - This function is only called once for `f`
|
||||
unsafe {
|
||||
upb_Arena_Free(f.inner().arena);
|
||||
}
|
||||
}
|
||||
pub fn set(&self, i: usize, val: $rs_type) {
|
||||
if i >= self.len() {
|
||||
return;
|
||||
}
|
||||
unsafe { upb_Array_Set(
|
||||
self.inner.raw,
|
||||
i,
|
||||
upb_MessageValue { $ufield: val },
|
||||
) }
|
||||
fn repeated_len(f: View<Repeated<$t>>) -> usize {
|
||||
unsafe { upb_Array_Size(f.as_raw(Private)) }
|
||||
}
|
||||
pub fn copy_from(&mut self, src: &RepeatedField<'_, $rs_type>) {
|
||||
fn repeated_push(mut f: Mut<Repeated<$t>>, v: View<$t>) {
|
||||
unsafe {
|
||||
upb_Array_Append(
|
||||
f.as_raw(Private),
|
||||
upb_MessageValue { $ufield: v },
|
||||
f.raw_arena(Private))
|
||||
}
|
||||
}
|
||||
fn repeated_clear(mut f: Mut<Repeated<$t>>) {
|
||||
unsafe { upb_Array_Resize(f.as_raw(Private), 0, f.raw_arena(Private)); }
|
||||
}
|
||||
unsafe fn repeated_get_unchecked(f: View<Repeated<$t>>, i: usize) -> View<$t> {
|
||||
unsafe { upb_Array_Get(f.as_raw(Private), i).$ufield }
|
||||
}
|
||||
unsafe fn repeated_set_unchecked(mut f: Mut<Repeated<$t>>, i: usize, v: View<$t>) {
|
||||
unsafe { upb_Array_Set(f.as_raw(Private), i, upb_MessageValue { $ufield: v }) }
|
||||
}
|
||||
fn repeated_copy_from(src: View<Repeated<$t>>, mut dest: Mut<Repeated<$t>>) {
|
||||
// SAFETY:
|
||||
// - `upb_Array_Resize` is unsafe but assumed to be always sound to call.
|
||||
// - `copy_nonoverlapping` is unsafe but here we guarantee that both pointers
|
||||
// are valid, the pointers are `#[repr(u8)]`, and the size is correct.
|
||||
unsafe {
|
||||
if (!upb_Array_Resize(self.inner.raw, src.len(), self.inner.arena.raw())) {
|
||||
if (!upb_Array_Resize(dest.as_raw(Private), src.len(), dest.inner.arena)) {
|
||||
panic!("upb_Array_Resize failed.");
|
||||
}
|
||||
ptr::copy_nonoverlapping(
|
||||
upb_Array_DataPtr(src.inner.raw).cast::<u8>(),
|
||||
upb_Array_MutableDataPtr(self.inner.raw).cast::<u8>(),
|
||||
size_of::<$rs_type>() * src.len());
|
||||
upb_Array_DataPtr(src.as_raw(Private)).cast::<u8>(),
|
||||
upb_Array_MutableDataPtr(dest.as_raw(Private)).cast::<u8>(),
|
||||
size_of::<$t>() * src.len());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -435,6 +434,14 @@ macro_rules! impl_repeated_primitives {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'msg, T: ?Sized> RepeatedMut<'msg, T> {
|
||||
// Returns a `RawArena` which is live for at least `'msg`
|
||||
#[doc(hidden)]
|
||||
pub fn raw_arena(&self, _private: Private) -> RawArena {
|
||||
self.inner.arena
|
||||
}
|
||||
}
|
||||
|
||||
impl_repeated_primitives!(
|
||||
(bool, bool_val, UpbCType::Bool),
|
||||
(f32, float_val, UpbCType::Float),
|
||||
|
@ -442,29 +449,28 @@ impl_repeated_primitives!(
|
|||
(i32, int32_val, UpbCType::Int32),
|
||||
(u32, uint32_val, UpbCType::UInt32),
|
||||
(i64, int64_val, UpbCType::Int64),
|
||||
(u64, uint64_val, UpbCType::UInt64)
|
||||
(u64, uint64_val, UpbCType::UInt64),
|
||||
);
|
||||
|
||||
/// Returns a static thread-local empty RepeatedFieldInner for use in a
|
||||
/// RepeatedView.
|
||||
///
|
||||
/// # Safety
|
||||
/// The returned array must never be mutated.
|
||||
///
|
||||
/// TODO: Split RepeatedFieldInner into mut and const variants to
|
||||
/// enforce safety. The returned array must never be mutated.
|
||||
pub unsafe fn empty_array() -> RepeatedFieldInner<'static> {
|
||||
// TODO: Consider creating empty array in C.
|
||||
fn new_repeated_field_inner() -> RepeatedFieldInner<'static> {
|
||||
let arena = Box::leak::<'static>(Box::new(Arena::new()));
|
||||
// Provide `i32` as a placeholder type.
|
||||
RepeatedField::<'static, i32>::new(arena).inner
|
||||
}
|
||||
thread_local! {
|
||||
static REPEATED_FIELD: RepeatedFieldInner<'static> = new_repeated_field_inner();
|
||||
}
|
||||
/// Returns a static empty RepeatedView.
|
||||
pub fn empty_array<T: ?Sized + ProxiedInRepeated>() -> RepeatedView<'static, T> {
|
||||
// TODO: Consider creating a static empty array in C.
|
||||
|
||||
REPEATED_FIELD.with(|inner| *inner)
|
||||
// Use `i32` for a shared empty repeated for all repeated types on a thread.
|
||||
static EMPTY_REPEATED_VIEW: OnceLock<RepeatedView<'static, i32>> = OnceLock::new();
|
||||
|
||||
// SAFETY:
|
||||
// - Because the repeated is never mutated, the repeated type is unused and
|
||||
// therefore valid for `T`.
|
||||
// - The view is leaked for `'static`.
|
||||
unsafe {
|
||||
RepeatedView::from_raw(
|
||||
Private,
|
||||
EMPTY_REPEATED_VIEW
|
||||
.get_or_init(|| Box::leak(Box::new(Repeated::new())).as_mut().into_view())
|
||||
.as_raw(Private),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a static thread-local empty MapInner for use in a
|
||||
|
@ -502,9 +508,6 @@ pub struct MapInner<'msg, K: ?Sized, V: ?Sized> {
|
|||
pub _phantom_value: PhantomData<&'msg mut V>,
|
||||
}
|
||||
|
||||
// These use manual impls instead of derives to avoid unnecessary bounds on `K`
|
||||
// and `V`. This problem is referred to as "perfect derive".
|
||||
// https://smallcultfollowing.com/babysteps/blog/2022/04/12/implied-bounds-and-perfect-derive/
|
||||
impl<'msg, K: ?Sized, V: ?Sized> Copy for MapInner<'msg, K, V> {}
|
||||
impl<'msg, K: ?Sized, V: ?Sized> Clone for MapInner<'msg, K, V> {
|
||||
fn clone(&self) -> MapInner<'msg, K, V> {
|
||||
|
@ -512,86 +515,27 @@ impl<'msg, K: ?Sized, V: ?Sized> Clone for MapInner<'msg, K, V> {
|
|||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_scalar_map_for_key_type {
|
||||
($key_t:ty, $key_ufield:ident, $key_upb_tag:expr, $trait:ident for $($t:ty, $ufield:ident, $upb_tag:expr, $zero_val:literal;)*) => {
|
||||
paste! { $(
|
||||
impl $trait for $t {
|
||||
fn new_map(a: RawArena) -> RawMap {
|
||||
unsafe { upb_Map_New(a, $key_upb_tag, $upb_tag) }
|
||||
}
|
||||
macro_rules! generate_map_key_ops_traits {
|
||||
($($t:ty, $sized_t:ty;)*) => {
|
||||
paste! {
|
||||
$(
|
||||
pub trait [< MapWith $t:camel KeyOps >] {
|
||||
type Value<'msg>: Sized;
|
||||
|
||||
fn clear(m: RawMap) {
|
||||
unsafe { upb_Map_Clear(m) }
|
||||
}
|
||||
|
||||
fn size(m: RawMap) -> usize {
|
||||
unsafe { upb_Map_Size(m) }
|
||||
}
|
||||
|
||||
fn insert(m: RawMap, a: RawArena, key: $key_t, value: $t) -> bool {
|
||||
unsafe {
|
||||
upb_Map_Set(
|
||||
m,
|
||||
upb_MessageValue { $key_ufield: key },
|
||||
upb_MessageValue { $ufield: value},
|
||||
a
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn get(m: RawMap, key: $key_t) -> Option<$t> {
|
||||
let mut val = upb_MessageValue { $ufield: $zero_val };
|
||||
let found = unsafe {
|
||||
upb_Map_Get(m, upb_MessageValue { $key_ufield: key }, &mut val)
|
||||
};
|
||||
if !found {
|
||||
return None;
|
||||
}
|
||||
Some(unsafe { val.$ufield })
|
||||
}
|
||||
|
||||
fn remove(m: RawMap, key: $key_t) -> Option<$t> {
|
||||
let mut val = upb_MessageValue { $ufield: $zero_val };
|
||||
let removed = unsafe {
|
||||
upb_Map_Delete(m, upb_MessageValue { $key_ufield: key }, &mut val)
|
||||
};
|
||||
if !removed {
|
||||
return None;
|
||||
}
|
||||
Some(unsafe { val.$ufield })
|
||||
}
|
||||
}
|
||||
)* }
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_scalar_map_for_key_types {
|
||||
($($t:ty, $ufield:ident, $upb_tag:expr;)*) => {
|
||||
paste! { $(
|
||||
pub trait [< MapWith $t:camel KeyOps >] : Sync + Send + Copy + Clone + Debug {
|
||||
fn new_map(a: RawArena) -> RawMap;
|
||||
fn clear(m: RawMap);
|
||||
fn size(m: RawMap) -> usize;
|
||||
fn insert(m: RawMap, a: RawArena, key: $t, value: Self) -> bool;
|
||||
fn get(m: RawMap, key: $t) -> Option<Self>
|
||||
where
|
||||
Self: Sized;
|
||||
fn remove(m: RawMap, key: $t) -> Option<Self>
|
||||
where
|
||||
Self: Sized;
|
||||
fn clear(m: RawMap) {
|
||||
unsafe { upb_Map_Clear(m) }
|
||||
}
|
||||
fn size(m: RawMap) -> usize {
|
||||
unsafe { upb_Map_Size(m) }
|
||||
}
|
||||
fn insert(m: RawMap, a: RawArena, key: $sized_t, value: Self::Value<'_>) -> bool;
|
||||
fn get<'msg>(m: RawMap, key: $sized_t) -> Option<Self::Value<'msg>>;
|
||||
fn remove(m: RawMap, key: $sized_t) -> bool;
|
||||
}
|
||||
|
||||
impl_scalar_map_for_key_type!($t, $ufield, $upb_tag, [< MapWith $t:camel KeyOps >] for
|
||||
f32, float_val, UpbCType::Float, 0f32;
|
||||
f64, double_val, UpbCType::Double, 0f64;
|
||||
i32, int32_val, UpbCType::Int32, 0i32;
|
||||
u32, uint32_val, UpbCType::UInt32, 0u32;
|
||||
i64, int64_val, UpbCType::Int64, 0i64;
|
||||
u64, uint64_val, UpbCType::UInt64, 0u64;
|
||||
bool, bool_val, UpbCType::Bool, false;
|
||||
);
|
||||
impl<'msg, V: [< MapWith $t:camel KeyOps >] + ?Sized> MapInner<'msg, $t, V> {
|
||||
|
||||
impl<'msg, V: [< MapWith $t:camel KeyOps >]> MapInner<'msg, $t, V> {
|
||||
pub fn new(arena: &'msg mut Arena) -> Self {
|
||||
MapInner {
|
||||
raw: V::new_map(arena.raw()),
|
||||
|
@ -609,28 +553,121 @@ macro_rules! impl_scalar_map_for_key_types {
|
|||
V::clear(self.raw)
|
||||
}
|
||||
|
||||
pub fn get(&self, key: $t) -> Option<V> {
|
||||
pub fn get<'a>(&self, key: $sized_t) -> Option<V::Value<'a>> {
|
||||
V::get(self.raw, key)
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, key: $t) -> Option<V> {
|
||||
pub fn remove(&mut self, key: $sized_t) -> bool {
|
||||
V::remove(self.raw, key)
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, key: $t, value: V) -> bool {
|
||||
pub fn insert(&mut self, key: $sized_t, value: V::Value<'_>) -> bool {
|
||||
V::insert(self.raw, self.arena.raw(), key, value)
|
||||
}
|
||||
}
|
||||
)* }
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_scalar_map_for_key_types!(
|
||||
i32, int32_val, UpbCType::Int32;
|
||||
u32, uint32_val, UpbCType::UInt32;
|
||||
i64, int64_val, UpbCType::Int64;
|
||||
u64, uint64_val, UpbCType::UInt64;
|
||||
bool, bool_val, UpbCType::Bool;
|
||||
generate_map_key_ops_traits!(
|
||||
i32, i32;
|
||||
u32, u32;
|
||||
i64, i64;
|
||||
u64, u64;
|
||||
bool, bool;
|
||||
ProtoStr, &ProtoStr;
|
||||
);
|
||||
|
||||
macro_rules! impl_scalar_map_key_op_for_scalar_values {
|
||||
($key_t:ty, $key_msg_val:expr, $key_upb_tag:expr, $trait:ident for $($t:ty, $sized_t:ty, $msg_val:expr, $from_msg_val:expr, $upb_tag:expr, $zero_val:literal;)*) => {
|
||||
$(
|
||||
impl $trait for $t {
|
||||
type Value<'msg> = $sized_t;
|
||||
|
||||
fn new_map(a: RawArena) -> RawMap {
|
||||
unsafe { upb_Map_New(a, $key_upb_tag, $upb_tag) }
|
||||
}
|
||||
|
||||
fn insert(m: RawMap, a: RawArena, key: $key_t, value: Self::Value<'_>) -> bool {
|
||||
unsafe {
|
||||
upb_Map_Set(
|
||||
m,
|
||||
$key_msg_val(key),
|
||||
$msg_val(value),
|
||||
a
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn get<'msg>(m: RawMap, key: $key_t) -> Option<Self::Value<'msg>> {
|
||||
let mut val = $msg_val($zero_val);
|
||||
let found = unsafe {
|
||||
upb_Map_Get(m, $key_msg_val(key), &mut val)
|
||||
};
|
||||
if !found {
|
||||
return None;
|
||||
}
|
||||
Some($from_msg_val(val))
|
||||
}
|
||||
|
||||
fn remove(m: RawMap, key: $key_t) -> bool {
|
||||
let mut val = $msg_val($zero_val);
|
||||
unsafe {
|
||||
upb_Map_Delete(m, $key_msg_val(key), &mut val)
|
||||
}
|
||||
}
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! scalar_to_msg {
|
||||
($ufield:ident) => {
|
||||
|val| upb_MessageValue { $ufield: val }
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! scalar_from_msg {
|
||||
($ufield:ident) => {
|
||||
|msg: upb_MessageValue| unsafe { msg.$ufield }
|
||||
};
|
||||
}
|
||||
|
||||
fn str_to_msg<'msg>(val: impl Into<&'msg ProtoStr>) -> upb_MessageValue {
|
||||
upb_MessageValue { str_val: val.into().as_bytes().into() }
|
||||
}
|
||||
|
||||
fn msg_to_str<'msg>(msg: upb_MessageValue) -> &'msg ProtoStr {
|
||||
unsafe { ProtoStr::from_utf8_unchecked(msg.str_val.as_ref()) }
|
||||
}
|
||||
|
||||
macro_rules! impl_map_key_ops_for_scalar_values {
|
||||
($($t:ty, $t_sized:ty, $key_msg_val:expr, $upb_tag:expr;)*) => {
|
||||
paste! {
|
||||
$(
|
||||
impl_scalar_map_key_op_for_scalar_values!($t_sized, $key_msg_val, $upb_tag, [< MapWith $t:camel KeyOps >] for
|
||||
f32, f32, scalar_to_msg!(float_val), scalar_from_msg!(float_val), UpbCType::Float, 0f32;
|
||||
f64, f64, scalar_to_msg!(double_val), scalar_from_msg!(double_val), UpbCType::Double, 0f64;
|
||||
i32, i32, scalar_to_msg!(int32_val), scalar_from_msg!(int32_val), UpbCType::Int32, 0i32;
|
||||
u32, u32, scalar_to_msg!(uint32_val), scalar_from_msg!(uint32_val), UpbCType::UInt32, 0u32;
|
||||
i64, i64, scalar_to_msg!(int64_val), scalar_from_msg!(int64_val), UpbCType::Int64, 0i64;
|
||||
u64, u64, scalar_to_msg!(uint64_val), scalar_from_msg!(uint64_val), UpbCType::UInt64, 0u64;
|
||||
bool, bool, scalar_to_msg!(bool_val), scalar_from_msg!(bool_val), UpbCType::Bool, false;
|
||||
ProtoStr, &'msg ProtoStr, str_to_msg, msg_to_str, UpbCType::String, "";
|
||||
);
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_map_key_ops_for_scalar_values!(
|
||||
i32, i32, scalar_to_msg!(int32_val), UpbCType::Int32;
|
||||
u32, u32, scalar_to_msg!(uint32_val), UpbCType::UInt32;
|
||||
i64, i64, scalar_to_msg!(int64_val), UpbCType::Int64;
|
||||
u64, u64, scalar_to_msg!(uint64_val), UpbCType::UInt64;
|
||||
bool, bool, scalar_to_msg!(bool_val), UpbCType::Bool;
|
||||
ProtoStr, &ProtoStr, |val: &ProtoStr| upb_MessageValue { str_val: val.as_bytes().into() }, UpbCType::String;
|
||||
);
|
||||
|
||||
extern "C" {
|
||||
|
@ -652,11 +689,17 @@ extern "C" {
|
|||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn new_map_inner() -> MapInner<'static, i32, i64> {
|
||||
pub(crate) fn new_map_i32_i64() -> MapInner<'static, i32, i64> {
|
||||
let arena = Box::leak::<'static>(Box::new(Arena::new()));
|
||||
MapInner::<'static, i32, i64>::new(arena)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn new_map_str_str() -> MapInner<'static, ProtoStr, ProtoStr> {
|
||||
let arena = Box::leak::<'static>(Box::new(Arena::new()));
|
||||
MapInner::<'static, ProtoStr, ProtoStr>::new(arena)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -684,37 +727,6 @@ mod tests {
|
|||
assert_that!(&*serialized_data, eq(b"Hello world"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn i32_array() {
|
||||
let arena = Arena::new();
|
||||
let mut arr = RepeatedField::<i32>::new(&arena);
|
||||
assert_that!(arr.len(), eq(0));
|
||||
arr.push(1);
|
||||
assert_that!(arr.get(0), eq(Some(1)));
|
||||
assert_that!(arr.len(), eq(1));
|
||||
arr.set(0, 3);
|
||||
assert_that!(arr.get(0), eq(Some(3)));
|
||||
for i in 0..2048 {
|
||||
arr.push(i);
|
||||
assert_that!(arr.get(arr.len() - 1), eq(Some(i)));
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn u32_array() {
|
||||
let mut arena = Arena::new();
|
||||
let mut arr = RepeatedField::<u32>::new(&mut arena);
|
||||
assert_that!(arr.len(), eq(0));
|
||||
arr.push(1);
|
||||
assert_that!(arr.get(0), eq(Some(1)));
|
||||
assert_that!(arr.len(), eq(1));
|
||||
arr.set(0, 3);
|
||||
assert_that!(arr.get(0), eq(Some(3)));
|
||||
for i in 0..2048 {
|
||||
arr.push(i);
|
||||
assert_that!(arr.get(arr.len() - 1), eq(Some(i)));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn i32_i32_map() {
|
||||
let mut arena = Arena::new();
|
||||
|
@ -726,9 +738,9 @@ mod tests {
|
|||
assert_that!(map.get(3), eq(None));
|
||||
assert_that!(map.size(), eq(1));
|
||||
|
||||
assert_that!(map.remove(1), eq(Some(2)));
|
||||
assert_that!(map.remove(1), eq(true));
|
||||
assert_that!(map.size(), eq(0));
|
||||
assert_that!(map.remove(1), eq(None));
|
||||
assert_that!(map.remove(1), eq(false));
|
||||
|
||||
assert_that!(map.insert(4, 5), eq(true));
|
||||
assert_that!(map.insert(6, 7), eq(true));
|
||||
|
@ -747,13 +759,63 @@ mod tests {
|
|||
assert_that!(map.get(3), eq(None));
|
||||
assert_that!(map.size(), eq(1));
|
||||
|
||||
assert_that!(map.remove(1), eq(Some(2.5)));
|
||||
assert_that!(map.remove(1), eq(true));
|
||||
assert_that!(map.size(), eq(0));
|
||||
assert_that!(map.remove(1), eq(None));
|
||||
assert_that!(map.remove(1), eq(false));
|
||||
|
||||
assert_that!(map.insert(4, 5.1), eq(true));
|
||||
assert_that!(map.insert(6, 7.2), eq(true));
|
||||
map.clear();
|
||||
assert_that!(map.size(), eq(0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn str_str_map() {
|
||||
let mut arena = Arena::new();
|
||||
let mut map = MapInner::<'_, ProtoStr, ProtoStr>::new(&mut arena);
|
||||
assert_that!(map.size(), eq(0));
|
||||
|
||||
map.insert("fizz".into(), "buzz".into());
|
||||
assert_that!(map.size(), eq(1));
|
||||
assert_that!(map.remove("fizz".into()), eq(true));
|
||||
map.clear();
|
||||
assert_that!(map.size(), eq(0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn u64_str_map() {
|
||||
let mut arena = Arena::new();
|
||||
let mut map = MapInner::<'_, u64, ProtoStr>::new(&mut arena);
|
||||
assert_that!(map.size(), eq(0));
|
||||
|
||||
map.insert(1, "fizz".into());
|
||||
map.insert(2, "buzz".into());
|
||||
assert_that!(map.size(), eq(2));
|
||||
assert_that!(map.remove(1), eq(true));
|
||||
map.clear();
|
||||
assert_that!(map.size(), eq(0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_all_maps_can_be_constructed() {
|
||||
macro_rules! gen_proto_values {
|
||||
($key_t:ty, $($value_t:ty),*) => {
|
||||
let mut arena = Arena::new();
|
||||
$(
|
||||
let map = MapInner::<'_, $key_t, $value_t>::new(&mut arena);
|
||||
assert_that!(map.size(), eq(0));
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! gen_proto_keys {
|
||||
($($key_t:ty),*) => {
|
||||
$(
|
||||
gen_proto_values!($key_t, f32, f64, i32, u32, i64, bool, ProtoStr);
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
gen_proto_keys!(i32, u32, i64, u64, bool, ProtoStr);
|
||||
}
|
||||
}
|
||||
|
|
226
rust/vtable.rs
226
rust/vtable.rs
|
@ -6,12 +6,16 @@
|
|||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
use crate::__internal::{Private, PtrAndLen, RawMessage};
|
||||
use crate::__runtime::{copy_bytes_in_arena_if_needed_by_runtime, MutatorMessageRef};
|
||||
use crate::__runtime::{
|
||||
copy_bytes_in_arena_if_needed_by_runtime, InnerPrimitiveMut, MutatorMessageRef,
|
||||
};
|
||||
use crate::{
|
||||
AbsentField, FieldEntry, Mut, MutProxy, Optional, PresentField, Proxied, ProxiedWithPresence,
|
||||
View, ViewProxy,
|
||||
AbsentField, FieldEntry, Mut, MutProxy, Optional, PresentField, PrimitiveMut, Proxied,
|
||||
ProxiedWithPresence, View, ViewProxy,
|
||||
};
|
||||
use std::fmt::{self, Debug};
|
||||
use std::marker::PhantomData;
|
||||
use std::ptr::NonNull;
|
||||
|
||||
/// A proxied type that can use a vtable to provide get/set access for a
|
||||
/// present field.
|
||||
|
@ -65,7 +69,8 @@ where
|
|||
AbsentMutData<'msg> = RawVTableOptionalMutatorData<'msg, T>,
|
||||
>,
|
||||
{
|
||||
let data = RawVTableOptionalMutatorData { msg_ref, vtable: optional_vtable };
|
||||
// SAFETY: safe as promised by the caller of the function
|
||||
let data = unsafe { RawVTableOptionalMutatorData::new(Private, msg_ref, optional_vtable) };
|
||||
if is_set {
|
||||
Optional::Set(PresentField::from_inner(Private, data))
|
||||
} else {
|
||||
|
@ -87,26 +92,29 @@ where
|
|||
///
|
||||
/// [`RawVTableOptionalMutatorData`] is similar, but also includes the
|
||||
/// capability to has/clear.
|
||||
pub struct RawVTableMutator<'msg, T: ProxiedWithRawVTable + ?Sized> {
|
||||
pub struct RawVTableMutator<'msg, T: ?Sized> {
|
||||
msg_ref: MutatorMessageRef<'msg>,
|
||||
vtable: &'static T::VTable,
|
||||
/// Stores `&'static <T as ProxiedWithRawVTable>::Vtable`
|
||||
/// as a type-erased pointer to avoid a bound on the struct.
|
||||
vtable: NonNull<()>,
|
||||
_phantom: PhantomData<&'msg T>,
|
||||
}
|
||||
|
||||
// These use manual impls instead of derives to avoid unnecessary bounds on `T`.
|
||||
// This problem is referred to as "perfect derive".
|
||||
// https://smallcultfollowing.com/babysteps/blog/2022/04/12/implied-bounds-and-perfect-derive/
|
||||
impl<'msg, T: ProxiedWithRawVTable + ?Sized> Clone for RawVTableMutator<'msg, T> {
|
||||
impl<'msg, T: ?Sized> Clone for RawVTableMutator<'msg, T> {
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
impl<'msg, T: ProxiedWithRawVTable + ?Sized> Copy for RawVTableMutator<'msg, T> {}
|
||||
impl<'msg, T: ?Sized> Copy for RawVTableMutator<'msg, T> {}
|
||||
|
||||
impl<'msg, T: ProxiedWithRawVTable + ?Sized> Debug for RawVTableMutator<'msg, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("RawVTableMutator")
|
||||
.field("msg_ref", &self.msg_ref)
|
||||
.field("vtable", &self.vtable)
|
||||
.field("vtable", self.vtable())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
@ -123,7 +131,12 @@ impl<'msg, T: ProxiedWithRawVTable + ?Sized> RawVTableMutator<'msg, T> {
|
|||
msg_ref: MutatorMessageRef<'msg>,
|
||||
vtable: &'static T::VTable,
|
||||
) -> Self {
|
||||
RawVTableMutator { msg_ref, vtable }
|
||||
RawVTableMutator { msg_ref, vtable: NonNull::from(vtable).cast(), _phantom: PhantomData }
|
||||
}
|
||||
|
||||
fn vtable(self) -> &'static T::VTable {
|
||||
// SAFETY: This was cast from `&'static T::VTable`.
|
||||
unsafe { self.vtable.cast().as_ref() }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,30 +149,27 @@ impl<'msg, T: ProxiedWithRawVTable + ?Sized> RawVTableMutator<'msg, T> {
|
|||
///
|
||||
/// This has the same representation for "present" and "absent" data;
|
||||
/// differences like default values are obviated by the vtable.
|
||||
pub struct RawVTableOptionalMutatorData<'msg, T: ProxiedWithRawOptionalVTable + ?Sized> {
|
||||
pub struct RawVTableOptionalMutatorData<'msg, T: ?Sized> {
|
||||
msg_ref: MutatorMessageRef<'msg>,
|
||||
vtable: &'static T::OptionalVTable,
|
||||
/// Stores `&'static <T as ProxiedWithRawOptionalVTable>::Vtable`
|
||||
/// as a type-erased pointer to avoid a bound on the struct.
|
||||
optional_vtable: NonNull<()>,
|
||||
_phantom: PhantomData<&'msg T>,
|
||||
}
|
||||
|
||||
unsafe impl<'msg, T: ProxiedWithRawOptionalVTable + ?Sized> Sync
|
||||
for RawVTableOptionalMutatorData<'msg, T>
|
||||
{
|
||||
}
|
||||
// SAFETY: all `T` that can perform mutations don't mutate through a shared
|
||||
// reference.
|
||||
unsafe impl<'msg, T: ?Sized> Sync for RawVTableOptionalMutatorData<'msg, T> {}
|
||||
|
||||
// These use manual impls instead of derives to avoid unnecessary bounds on `T`.
|
||||
// This problem is referred to as "perfect derive".
|
||||
// https://smallcultfollowing.com/babysteps/blog/2022/04/12/implied-bounds-and-perfect-derive/
|
||||
impl<'msg, T: ProxiedWithRawOptionalVTable + ?Sized> Clone
|
||||
for RawVTableOptionalMutatorData<'msg, T>
|
||||
{
|
||||
impl<'msg, T: ?Sized> Clone for RawVTableOptionalMutatorData<'msg, T> {
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
impl<'msg, T: ProxiedWithRawOptionalVTable + ?Sized> Copy
|
||||
for RawVTableOptionalMutatorData<'msg, T>
|
||||
{
|
||||
}
|
||||
impl<'msg, T: ?Sized> Copy for RawVTableOptionalMutatorData<'msg, T> {}
|
||||
|
||||
impl<'msg, T: ProxiedWithRawOptionalVTable + ?Sized> Debug
|
||||
for RawVTableOptionalMutatorData<'msg, T>
|
||||
|
@ -167,7 +177,7 @@ impl<'msg, T: ProxiedWithRawOptionalVTable + ?Sized> Debug
|
|||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("RawVTableOptionalMutatorData")
|
||||
.field("msg_ref", &self.msg_ref)
|
||||
.field("vtable", &self.vtable)
|
||||
.field("vtable", self.optional_vtable())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
@ -184,11 +194,23 @@ impl<'msg, T: ProxiedWithRawOptionalVTable + ?Sized> RawVTableOptionalMutatorDat
|
|||
msg_ref: MutatorMessageRef<'msg>,
|
||||
vtable: &'static T::OptionalVTable,
|
||||
) -> Self {
|
||||
Self { msg_ref, vtable }
|
||||
Self { msg_ref, optional_vtable: NonNull::from(vtable).cast(), _phantom: PhantomData }
|
||||
}
|
||||
|
||||
fn optional_vtable(self) -> &'static T::OptionalVTable {
|
||||
// SAFETY: This was cast from `&'static T::OptionalVTable` in `new`.
|
||||
unsafe { self.optional_vtable.cast().as_ref() }
|
||||
}
|
||||
|
||||
fn into_raw_mut(self) -> RawVTableMutator<'msg, T> {
|
||||
RawVTableMutator { msg_ref: self.msg_ref, vtable: T::upcast_vtable(Private, self.vtable) }
|
||||
// SAFETY: the safety requirements have been met by the caller of `new`.
|
||||
unsafe {
|
||||
RawVTableMutator::new(
|
||||
Private,
|
||||
self.msg_ref,
|
||||
T::upcast_vtable(Private, self.optional_vtable()),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -291,32 +313,6 @@ impl<T> PrimitiveOptionalMutVTable<T> {
|
|||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_raw_vtable_mutator_get_set {
|
||||
($($t:ty),*) => {
|
||||
$(
|
||||
impl RawVTableMutator<'_, $t> {
|
||||
pub(crate) fn get(self) -> $t {
|
||||
// SAFETY:
|
||||
// - `msg_ref` is valid for the lifetime of `RawVTableMutator` as promised by the
|
||||
// caller of `new`.
|
||||
unsafe { (self.vtable.getter)(self.msg_ref.msg()) }
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
/// - `msg_ref` must be valid for the lifetime of `RawVTableMutator`.
|
||||
pub(crate) unsafe fn set(self, val: $t) {
|
||||
// SAFETY:
|
||||
// - `msg_ref` is valid for the lifetime of `RawVTableMutator` as promised by the
|
||||
// caller of `new`.
|
||||
unsafe { (self.vtable.setter)(self.msg_ref.msg(), val) }
|
||||
}
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
impl_raw_vtable_mutator_get_set!(bool, f32, f64, i32, i64, u32, u64);
|
||||
|
||||
/// A generic thunk vtable for mutating a present `bytes` or `string` field.
|
||||
#[doc(hidden)]
|
||||
#[derive(Debug)]
|
||||
|
@ -366,7 +362,7 @@ impl<'msg> RawVTableMutator<'msg, [u8]> {
|
|||
// - `msg_ref` is valid for `'msg` as promised by the caller of `new`.
|
||||
// - The caller of `BytesMutVTable` promised that the returned `PtrAndLen` is
|
||||
// valid for `'msg`.
|
||||
unsafe { (self.vtable.getter)(self.msg_ref.msg()).as_ref() }
|
||||
unsafe { (self.vtable().getter)(self.msg_ref.msg()).as_ref() }
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
|
@ -377,7 +373,7 @@ impl<'msg> RawVTableMutator<'msg, [u8]> {
|
|||
let val = copy_bytes_in_arena_if_needed_by_runtime(self.msg_ref, val);
|
||||
// SAFETY:
|
||||
// - `msg_ref` is valid for `'msg` as promised by the caller of `new`.
|
||||
unsafe { (self.vtable.setter)(self.msg_ref.msg(), val.into()) }
|
||||
unsafe { (self.vtable().setter)(self.msg_ref.msg(), val.into()) }
|
||||
}
|
||||
|
||||
pub(crate) fn truncate(&self, len: usize) {
|
||||
|
@ -397,7 +393,7 @@ impl<'msg> RawVTableOptionalMutatorData<'msg, [u8]> {
|
|||
pub(crate) fn set_absent_to_default(self) -> Self {
|
||||
// SAFETY: The default value is UTF-8 if required by the
|
||||
// runtime as promised by the caller of `BytesOptionalMutVTable::new`.
|
||||
unsafe { self.set(self.vtable.default) }
|
||||
unsafe { self.set(self.optional_vtable().default) }
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
|
@ -407,7 +403,7 @@ impl<'msg> RawVTableOptionalMutatorData<'msg, [u8]> {
|
|||
let val = copy_bytes_in_arena_if_needed_by_runtime(self.msg_ref, val);
|
||||
// SAFETY:
|
||||
// - `msg_ref` is valid for `'msg` as promised by the caller.
|
||||
unsafe { (self.vtable.base.setter)(self.msg_ref.msg(), val.into()) }
|
||||
unsafe { (self.optional_vtable().base.setter)(self.msg_ref.msg(), val.into()) }
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -416,40 +412,96 @@ impl<'msg> RawVTableOptionalMutatorData<'msg, [u8]> {
|
|||
// - `msg_ref` is valid for `'msg` as promised by the caller.
|
||||
// - The caller of `new` promised that the returned `PtrAndLen` is valid for
|
||||
// `'msg`.
|
||||
unsafe { (self.vtable.clearer)(self.msg_ref.msg()) }
|
||||
unsafe { (self.optional_vtable().clearer)(self.msg_ref.msg()) }
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_raw_vtable_optional_mutator_data {
|
||||
($($t:ty),*) => {
|
||||
$(
|
||||
impl<'msg> RawVTableOptionalMutatorData<'msg, $t> {
|
||||
pub(crate) fn set_absent_to_default(self) -> Self {
|
||||
// SAFETY:
|
||||
// - `msg_ref` is valid for the lifetime of `RawVTableOptionalMutatorData` as
|
||||
// promised by the caller of `new`.
|
||||
self.set(self.vtable.default)
|
||||
}
|
||||
|
||||
pub(crate) fn set(self, val: $t) -> Self {
|
||||
// SAFETY:
|
||||
// - `msg_ref` is valid for the lifetime of `RawVTableOptionalMutatorData` as
|
||||
// promised by the caller of `new`.
|
||||
unsafe { (self.vtable.base.setter)(self.msg_ref.msg(), val.into()) }
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn clear(self) -> Self {
|
||||
// SAFETY:
|
||||
// - `msg_ref` is valid for the lifetime of `RawVTableOptionalMutatorData` as
|
||||
// promised by the caller of `new`.
|
||||
unsafe { (self.vtable.clearer)(self.msg_ref.msg()) }
|
||||
self
|
||||
}
|
||||
}
|
||||
)*
|
||||
}
|
||||
/// Primitive types using a vtable for message access that are trivial to copy
|
||||
/// and have a `'static` lifetime.
|
||||
///
|
||||
/// Implementing this trait automatically implements `ProxiedWithRawVTable`,
|
||||
/// `ProxiedWithRawOptionalVTable`, and get/set/clear methods on
|
||||
/// `RawVTableMutator` and `RawVTableOptionalMutatorData` that use the vtable.
|
||||
///
|
||||
/// It doesn't implement `Proxied`, `ViewProxy`, `SettableValue` or
|
||||
/// `ProxiedWithPresence` for `Self` to avoid future conflicting blanket impls
|
||||
/// on those traits.
|
||||
pub trait PrimitiveWithRawVTable:
|
||||
Copy
|
||||
+ Debug
|
||||
+ 'static
|
||||
+ ProxiedWithPresence
|
||||
+ Sync
|
||||
+ Send
|
||||
+ for<'msg> Proxied<View<'msg> = Self, Mut<'msg> = PrimitiveMut<'msg, Self>>
|
||||
{
|
||||
}
|
||||
|
||||
impl_raw_vtable_optional_mutator_data!(bool, f32, f64, i32, i64, u32, u64);
|
||||
impl<T: PrimitiveWithRawVTable> ProxiedWithRawVTable for T {
|
||||
type VTable = PrimitiveVTable<T>;
|
||||
|
||||
fn make_view(_private: Private, mut_inner: InnerPrimitiveMut<'_, Self>) -> Self {
|
||||
mut_inner.get()
|
||||
}
|
||||
|
||||
fn make_mut(_private: Private, inner: InnerPrimitiveMut<'_, Self>) -> PrimitiveMut<'_, Self> {
|
||||
// SAFETY: `inner` is valid for the necessary lifetime and `T` as promised by
|
||||
// the caller of `InnerPrimitiveMut::new`.
|
||||
unsafe { PrimitiveMut::from_inner(Private, inner) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PrimitiveWithRawVTable> ProxiedWithRawOptionalVTable for T {
|
||||
type OptionalVTable = PrimitiveOptionalMutVTable<T>;
|
||||
|
||||
fn upcast_vtable(
|
||||
_private: Private,
|
||||
optional_vtable: &'static Self::OptionalVTable,
|
||||
) -> &'static Self::VTable {
|
||||
&optional_vtable.base
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PrimitiveWithRawVTable> RawVTableMutator<'_, T> {
|
||||
pub(crate) fn get(self) -> T {
|
||||
// SAFETY:
|
||||
// - `msg_ref` is valid for the lifetime of `RawVTableMutator` as promised by
|
||||
// the caller of `new`.
|
||||
unsafe { (self.vtable().getter)(self.msg_ref.msg()) }
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
/// - `msg_ref` must be valid for the lifetime of `RawVTableMutator`.
|
||||
pub(crate) unsafe fn set(self, val: T) {
|
||||
// SAFETY:
|
||||
// - `msg_ref` is valid for the lifetime of `RawVTableMutator` as promised by
|
||||
// the caller of `new`.
|
||||
unsafe { (self.vtable().setter)(self.msg_ref.msg(), val) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'msg, T: PrimitiveWithRawVTable> RawVTableOptionalMutatorData<'msg, T> {
|
||||
pub(crate) fn set_absent_to_default(self) -> Self {
|
||||
// SAFETY:
|
||||
// - `msg_ref` is valid for the lifetime of `RawVTableOptionalMutatorData` as
|
||||
// promised by the caller of `new`.
|
||||
self.set(self.optional_vtable().default)
|
||||
}
|
||||
|
||||
pub(crate) fn set(self, val: T) -> Self {
|
||||
// SAFETY:
|
||||
// - `msg_ref` is valid for the lifetime of `RawVTableOptionalMutatorData` as
|
||||
// promised by the caller of `new`.
|
||||
unsafe { (self.optional_vtable().base.setter)(self.msg_ref.msg(), val) }
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn clear(self) -> Self {
|
||||
// SAFETY:
|
||||
// - `msg_ref` is valid for the lifetime of `RawVTableOptionalMutatorData` as
|
||||
// promised by the caller of `new`.
|
||||
unsafe { (self.optional_vtable().clearer)(self.msg_ref.msg()) }
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,7 +116,6 @@ set(libprotobuf_hdrs
|
|||
${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor.h
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor.pb.h
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor_database.h
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor_legacy.h
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor_lite.h
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor_visitor.h
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/dynamic_message.h
|
||||
|
@ -287,7 +286,6 @@ set(libprotobuf_lite_hdrs
|
|||
|
||||
# @//pkg:protoc
|
||||
set(libprotoc_srcs
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/allowlists/editions.cc
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/allowlists/empty_package.cc
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/allowlists/open_enum.cc
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/code_generator.cc
|
||||
|
@ -651,6 +649,7 @@ set(test_util_srcs
|
|||
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/annotation_test_util.cc
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/reflection_tester.cc
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/test_util.cc
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/unredacted_debug_format_for_test.cc
|
||||
)
|
||||
|
||||
# @//pkg:test_util
|
||||
|
@ -666,6 +665,7 @@ set(test_util_hdrs
|
|||
${protobuf_SOURCE_DIR}/src/google/protobuf/reflection_tester.h
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/test_util.h
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/test_util.inc
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/unredacted_debug_format_for_test.h
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/wire_format_unittest.inc
|
||||
)
|
||||
|
||||
|
@ -708,6 +708,8 @@ set(protobuf_test_files
|
|||
${protobuf_SOURCE_DIR}/src/google/protobuf/string_block_test.cc
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/text_format_unittest.cc
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/unknown_field_set_unittest.cc
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/unredacted_debug_format_for_test.cc
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/unredacted_debug_format_for_test_test.cc
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/varint_shuffle_test.cc
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/well_known_types_unittest.cc
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/wire_format_unittest.cc
|
||||
|
@ -795,6 +797,7 @@ set(compiler_test_files
|
|||
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/names_unittest.cc
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/text_format_decode_data_unittest.cc
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/parser_unittest.cc
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/php/generator_unittest.cc
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/plugin_unittest.cc
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/retention_unittest.cc
|
||||
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc
|
||||
|
|
|
@ -486,7 +486,6 @@ cc_library(
|
|||
"descriptor.h",
|
||||
"descriptor.pb.h",
|
||||
"descriptor_database.h",
|
||||
"descriptor_legacy.h",
|
||||
"descriptor_visitor.h",
|
||||
"dynamic_message.h",
|
||||
"feature_resolver.h",
|
||||
|
@ -581,20 +580,6 @@ cc_library(
|
|||
strip_include_prefix = "/src",
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "descriptor_legacy",
|
||||
hdrs = ["descriptor_legacy.h"],
|
||||
copts = COPTS,
|
||||
linkopts = LINK_OPTS,
|
||||
strip_include_prefix = "/src",
|
||||
visibility = ["//:__subpackages__"],
|
||||
deps = [
|
||||
":port_def",
|
||||
":protobuf_nowkt",
|
||||
"@com_google_absl//absl/strings",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "descriptor_visitor",
|
||||
hdrs = ["descriptor_visitor.h"],
|
||||
|
@ -1044,7 +1029,6 @@ cc_test(
|
|||
}),
|
||||
deps = [
|
||||
":cc_test_protos",
|
||||
":descriptor_legacy",
|
||||
":protobuf",
|
||||
":test_textproto",
|
||||
"//src/google/protobuf/compiler:importer",
|
||||
|
@ -1340,7 +1324,6 @@ cc_test(
|
|||
}),
|
||||
deps = [
|
||||
":cc_test_protos",
|
||||
":descriptor_legacy",
|
||||
":protobuf",
|
||||
":test_util",
|
||||
"//src/google/protobuf/stubs",
|
||||
|
@ -1570,6 +1553,30 @@ cc_test(
|
|||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "unredacted_debug_format_for_test",
|
||||
testonly = True,
|
||||
srcs = ["unredacted_debug_format_for_test.cc"],
|
||||
hdrs = ["unredacted_debug_format_for_test.h"],
|
||||
strip_include_prefix = "/src",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":protobuf",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "unredacted_debug_format_for_test_test",
|
||||
srcs = ["unredacted_debug_format_for_test_test.cc"],
|
||||
deps = [
|
||||
":cc_lite_test_protos",
|
||||
":cc_test_protos",
|
||||
":protobuf",
|
||||
":unredacted_debug_format_for_test",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
################################################################################
|
||||
# Helper targets for Kotlin tests
|
||||
################################################################################
|
||||
|
|
|
@ -124,9 +124,6 @@ const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fany_2eproto =
|
|||
PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_google_2fprotobuf_2fany_2eproto_getter() {
|
||||
return &descriptor_table_google_2fprotobuf_2fany_2eproto;
|
||||
}
|
||||
// Force running AddDescriptors() at dynamic initialization time.
|
||||
PROTOBUF_ATTRIBUTE_INIT_PRIORITY2
|
||||
static ::_pbi::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fany_2eproto(&descriptor_table_google_2fprotobuf_2fany_2eproto);
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
// ===================================================================
|
||||
|
@ -198,12 +195,15 @@ inline void Any::SharedDtor() {
|
|||
|
||||
const ::google::protobuf::MessageLite::ClassData*
|
||||
Any::GetClassData() const {
|
||||
PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData
|
||||
_data_ = {
|
||||
Any::MergeImpl,
|
||||
nullptr, // OnDemandRegisterArenaDtor
|
||||
&::google::protobuf::Message::kDescriptorMethods,
|
||||
PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::
|
||||
ClassDataFull _data_ = {
|
||||
{
|
||||
nullptr, // OnDemandRegisterArenaDtor
|
||||
PROTOBUF_FIELD_OFFSET(Any, _impl_._cached_size_),
|
||||
false,
|
||||
},
|
||||
&Any::MergeImpl,
|
||||
&Any::kDescriptorMethods,
|
||||
};
|
||||
return &_data_;
|
||||
}
|
||||
|
@ -360,9 +360,9 @@ void Any::InternalSwap(Any* PROTOBUF_RESTRICT other) {
|
|||
}
|
||||
|
||||
::google::protobuf::Metadata Any::GetMetadata() const {
|
||||
return ::_pbi::AssignDescriptors(
|
||||
&descriptor_table_google_2fprotobuf_2fany_2eproto_getter, &descriptor_table_google_2fprotobuf_2fany_2eproto_once,
|
||||
file_level_metadata_google_2fprotobuf_2fany_2eproto[0]);
|
||||
return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fany_2eproto_getter,
|
||||
&descriptor_table_google_2fprotobuf_2fany_2eproto_once,
|
||||
file_level_metadata_google_2fprotobuf_2fany_2eproto[0]);
|
||||
}
|
||||
// @@protoc_insertion_point(namespace_scope)
|
||||
} // namespace protobuf
|
||||
|
@ -375,4 +375,8 @@ namespace protobuf {
|
|||
#if defined(__llvm__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif // __llvm__
|
||||
PROTOBUF_ATTRIBUTE_INIT_PRIORITY2
|
||||
static ::std::false_type _static_init_ PROTOBUF_UNUSED =
|
||||
(::_pbi::AddDescriptors(&descriptor_table_google_2fprotobuf_2fany_2eproto),
|
||||
::std::false_type{});
|
||||
#include "google/protobuf/port_undef.inc"
|
||||
|
|
|
@ -238,9 +238,6 @@ const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fapi_2eproto =
|
|||
PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_google_2fprotobuf_2fapi_2eproto_getter() {
|
||||
return &descriptor_table_google_2fprotobuf_2fapi_2eproto;
|
||||
}
|
||||
// Force running AddDescriptors() at dynamic initialization time.
|
||||
PROTOBUF_ATTRIBUTE_INIT_PRIORITY2
|
||||
static ::_pbi::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fapi_2eproto(&descriptor_table_google_2fprotobuf_2fapi_2eproto);
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
// ===================================================================
|
||||
|
@ -328,12 +325,15 @@ inline void Api::SharedDtor() {
|
|||
|
||||
const ::google::protobuf::MessageLite::ClassData*
|
||||
Api::GetClassData() const {
|
||||
PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData
|
||||
_data_ = {
|
||||
Api::MergeImpl,
|
||||
nullptr, // OnDemandRegisterArenaDtor
|
||||
&::google::protobuf::Message::kDescriptorMethods,
|
||||
PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::
|
||||
ClassDataFull _data_ = {
|
||||
{
|
||||
nullptr, // OnDemandRegisterArenaDtor
|
||||
PROTOBUF_FIELD_OFFSET(Api, _impl_._cached_size_),
|
||||
false,
|
||||
},
|
||||
&Api::MergeImpl,
|
||||
&Api::kDescriptorMethods,
|
||||
};
|
||||
return &_data_;
|
||||
}
|
||||
|
@ -637,9 +637,9 @@ void Api::InternalSwap(Api* PROTOBUF_RESTRICT other) {
|
|||
}
|
||||
|
||||
::google::protobuf::Metadata Api::GetMetadata() const {
|
||||
return ::_pbi::AssignDescriptors(
|
||||
&descriptor_table_google_2fprotobuf_2fapi_2eproto_getter, &descriptor_table_google_2fprotobuf_2fapi_2eproto_once,
|
||||
file_level_metadata_google_2fprotobuf_2fapi_2eproto[0]);
|
||||
return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fapi_2eproto_getter,
|
||||
&descriptor_table_google_2fprotobuf_2fapi_2eproto_once,
|
||||
file_level_metadata_google_2fprotobuf_2fapi_2eproto[0]);
|
||||
}
|
||||
// ===================================================================
|
||||
|
||||
|
@ -717,12 +717,15 @@ inline void Method::SharedDtor() {
|
|||
|
||||
const ::google::protobuf::MessageLite::ClassData*
|
||||
Method::GetClassData() const {
|
||||
PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData
|
||||
_data_ = {
|
||||
Method::MergeImpl,
|
||||
nullptr, // OnDemandRegisterArenaDtor
|
||||
&::google::protobuf::Message::kDescriptorMethods,
|
||||
PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::
|
||||
ClassDataFull _data_ = {
|
||||
{
|
||||
nullptr, // OnDemandRegisterArenaDtor
|
||||
PROTOBUF_FIELD_OFFSET(Method, _impl_._cached_size_),
|
||||
false,
|
||||
},
|
||||
&Method::MergeImpl,
|
||||
&Method::kDescriptorMethods,
|
||||
};
|
||||
return &_data_;
|
||||
}
|
||||
|
@ -1006,9 +1009,9 @@ void Method::InternalSwap(Method* PROTOBUF_RESTRICT other) {
|
|||
}
|
||||
|
||||
::google::protobuf::Metadata Method::GetMetadata() const {
|
||||
return ::_pbi::AssignDescriptors(
|
||||
&descriptor_table_google_2fprotobuf_2fapi_2eproto_getter, &descriptor_table_google_2fprotobuf_2fapi_2eproto_once,
|
||||
file_level_metadata_google_2fprotobuf_2fapi_2eproto[1]);
|
||||
return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fapi_2eproto_getter,
|
||||
&descriptor_table_google_2fprotobuf_2fapi_2eproto_once,
|
||||
file_level_metadata_google_2fprotobuf_2fapi_2eproto[1]);
|
||||
}
|
||||
// ===================================================================
|
||||
|
||||
|
@ -1064,12 +1067,15 @@ inline void Mixin::SharedDtor() {
|
|||
|
||||
const ::google::protobuf::MessageLite::ClassData*
|
||||
Mixin::GetClassData() const {
|
||||
PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData
|
||||
_data_ = {
|
||||
Mixin::MergeImpl,
|
||||
nullptr, // OnDemandRegisterArenaDtor
|
||||
&::google::protobuf::Message::kDescriptorMethods,
|
||||
PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::
|
||||
ClassDataFull _data_ = {
|
||||
{
|
||||
nullptr, // OnDemandRegisterArenaDtor
|
||||
PROTOBUF_FIELD_OFFSET(Mixin, _impl_._cached_size_),
|
||||
false,
|
||||
},
|
||||
&Mixin::MergeImpl,
|
||||
&Mixin::kDescriptorMethods,
|
||||
};
|
||||
return &_data_;
|
||||
}
|
||||
|
@ -1229,9 +1235,9 @@ void Mixin::InternalSwap(Mixin* PROTOBUF_RESTRICT other) {
|
|||
}
|
||||
|
||||
::google::protobuf::Metadata Mixin::GetMetadata() const {
|
||||
return ::_pbi::AssignDescriptors(
|
||||
&descriptor_table_google_2fprotobuf_2fapi_2eproto_getter, &descriptor_table_google_2fprotobuf_2fapi_2eproto_once,
|
||||
file_level_metadata_google_2fprotobuf_2fapi_2eproto[2]);
|
||||
return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fapi_2eproto_getter,
|
||||
&descriptor_table_google_2fprotobuf_2fapi_2eproto_once,
|
||||
file_level_metadata_google_2fprotobuf_2fapi_2eproto[2]);
|
||||
}
|
||||
// @@protoc_insertion_point(namespace_scope)
|
||||
} // namespace protobuf
|
||||
|
@ -1241,4 +1247,8 @@ namespace protobuf {
|
|||
} // namespace protobuf
|
||||
} // namespace google
|
||||
// @@protoc_insertion_point(global_scope)
|
||||
PROTOBUF_ATTRIBUTE_INIT_PRIORITY2
|
||||
static ::std::false_type _static_init_ PROTOBUF_UNUSED =
|
||||
(::_pbi::AddDescriptors(&descriptor_table_google_2fprotobuf_2fapi_2eproto),
|
||||
::std::false_type{});
|
||||
#include "google/protobuf/port_undef.inc"
|
||||
|
|
|
@ -405,16 +405,15 @@ class PROTOBUF_EXPORT Method final : public ::google::protobuf::Message
|
|||
public:
|
||||
void clear_options() ;
|
||||
::google::protobuf::Option* mutable_options(int index);
|
||||
::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
|
||||
mutable_options();
|
||||
::google::protobuf::RepeatedPtrField<::google::protobuf::Option>* mutable_options();
|
||||
|
||||
private:
|
||||
const ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>& _internal_options() const;
|
||||
::google::protobuf::RepeatedPtrField<::google::protobuf::Option>* _internal_mutable_options();
|
||||
public:
|
||||
const ::google::protobuf::Option& options(int index) const;
|
||||
::google::protobuf::Option* add_options();
|
||||
const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
|
||||
options() const;
|
||||
const ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>& options() const;
|
||||
// string name = 1;
|
||||
void clear_name() ;
|
||||
const std::string& name() const;
|
||||
|
@ -670,16 +669,15 @@ class PROTOBUF_EXPORT Api final : public ::google::protobuf::Message
|
|||
public:
|
||||
void clear_methods() ;
|
||||
::google::protobuf::Method* mutable_methods(int index);
|
||||
::google::protobuf::RepeatedPtrField< ::google::protobuf::Method >*
|
||||
mutable_methods();
|
||||
::google::protobuf::RepeatedPtrField<::google::protobuf::Method>* mutable_methods();
|
||||
|
||||
private:
|
||||
const ::google::protobuf::RepeatedPtrField<::google::protobuf::Method>& _internal_methods() const;
|
||||
::google::protobuf::RepeatedPtrField<::google::protobuf::Method>* _internal_mutable_methods();
|
||||
public:
|
||||
const ::google::protobuf::Method& methods(int index) const;
|
||||
::google::protobuf::Method* add_methods();
|
||||
const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Method >&
|
||||
methods() const;
|
||||
const ::google::protobuf::RepeatedPtrField<::google::protobuf::Method>& methods() const;
|
||||
// repeated .google.protobuf.Option options = 3;
|
||||
int options_size() const;
|
||||
private:
|
||||
|
@ -688,16 +686,15 @@ class PROTOBUF_EXPORT Api final : public ::google::protobuf::Message
|
|||
public:
|
||||
void clear_options() ;
|
||||
::google::protobuf::Option* mutable_options(int index);
|
||||
::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
|
||||
mutable_options();
|
||||
::google::protobuf::RepeatedPtrField<::google::protobuf::Option>* mutable_options();
|
||||
|
||||
private:
|
||||
const ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>& _internal_options() const;
|
||||
::google::protobuf::RepeatedPtrField<::google::protobuf::Option>* _internal_mutable_options();
|
||||
public:
|
||||
const ::google::protobuf::Option& options(int index) const;
|
||||
::google::protobuf::Option* add_options();
|
||||
const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
|
||||
options() const;
|
||||
const ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>& options() const;
|
||||
// repeated .google.protobuf.Mixin mixins = 6;
|
||||
int mixins_size() const;
|
||||
private:
|
||||
|
@ -706,16 +703,15 @@ class PROTOBUF_EXPORT Api final : public ::google::protobuf::Message
|
|||
public:
|
||||
void clear_mixins() ;
|
||||
::google::protobuf::Mixin* mutable_mixins(int index);
|
||||
::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin >*
|
||||
mutable_mixins();
|
||||
::google::protobuf::RepeatedPtrField<::google::protobuf::Mixin>* mutable_mixins();
|
||||
|
||||
private:
|
||||
const ::google::protobuf::RepeatedPtrField<::google::protobuf::Mixin>& _internal_mixins() const;
|
||||
::google::protobuf::RepeatedPtrField<::google::protobuf::Mixin>* _internal_mutable_mixins();
|
||||
public:
|
||||
const ::google::protobuf::Mixin& mixins(int index) const;
|
||||
::google::protobuf::Mixin* add_mixins();
|
||||
const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin >&
|
||||
mixins() const;
|
||||
const ::google::protobuf::RepeatedPtrField<::google::protobuf::Mixin>& mixins() const;
|
||||
// string name = 1;
|
||||
void clear_name() ;
|
||||
const std::string& name() const;
|
||||
|
|
|
@ -953,20 +953,6 @@ TEST(ArenaTest, AddAllocatedWithReflection) {
|
|||
}
|
||||
|
||||
TEST(ArenaTest, RepeatedPtrFieldAddClearedTest) {
|
||||
#ifndef PROTOBUF_FUTURE_REMOVE_CLEARED_API
|
||||
{
|
||||
PROTOBUF_IGNORE_DEPRECATION_START
|
||||
RepeatedPtrField<TestAllTypes> repeated_field;
|
||||
EXPECT_TRUE(repeated_field.empty());
|
||||
EXPECT_EQ(0, repeated_field.size());
|
||||
// Ownership is passed to repeated_field.
|
||||
TestAllTypes* cleared = new TestAllTypes();
|
||||
repeated_field.AddCleared(cleared);
|
||||
EXPECT_TRUE(repeated_field.empty());
|
||||
EXPECT_EQ(0, repeated_field.size());
|
||||
PROTOBUF_IGNORE_DEPRECATION_STOP
|
||||
}
|
||||
#endif // !PROTOBUF_FUTURE_REMOVE_CLEARED_API
|
||||
{
|
||||
RepeatedPtrField<TestAllTypes> repeated_field;
|
||||
EXPECT_TRUE(repeated_field.empty());
|
||||
|
|
|
@ -72,5 +72,5 @@ option objc_class_prefix = "GPB";
|
|||
message MessageSet {
|
||||
option message_set_wire_format = true;
|
||||
|
||||
extensions 4 to max;
|
||||
extensions 4 to max [verification = UNVERIFIED];
|
||||
}
|
||||
|
|
|
@ -133,7 +133,6 @@ cc_library(
|
|||
":code_generator",
|
||||
":importer",
|
||||
":retention",
|
||||
"//src/google/protobuf:descriptor_legacy",
|
||||
"//src/google/protobuf:protobuf_nowkt",
|
||||
"//src/google/protobuf/compiler/allowlists",
|
||||
"@com_google_absl//absl/algorithm",
|
||||
|
@ -279,7 +278,6 @@ cc_library(
|
|||
deps = [
|
||||
":code_generator",
|
||||
"//src/google/protobuf:cc_test_protos",
|
||||
"//src/google/protobuf:descriptor_legacy",
|
||||
"//src/google/protobuf:descriptor_visitor",
|
||||
"//src/google/protobuf/io",
|
||||
"//src/google/protobuf/stubs",
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue