Merge branch 'main' into proper-fix-none-ascii-issue

pull/14253/head
Matt Fowles Kulukundis 11 months ago committed by GitHub
commit cad753e9e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      .bazelrc
  2. 4
      .github/workflows/clear_caches.yml
  3. 32
      .github/workflows/test_cpp.yml
  4. 8
      .github/workflows/test_java.yml
  5. 27
      .github/workflows/test_ruby.yml
  6. 2
      .github/workflows/test_rust.yml
  7. 10
      .github/workflows/test_upb.yml
  8. 88
      BUILD.bazel
  9. 2
      CMakeLists.txt
  10. 5
      WORKSPACE
  11. 2
      bazel/BUILD
  12. 8
      bazel/build_defs.bzl
  13. 1
      bazel/upb_proto_library_internal/cc_library_func.bzl
  14. 19
      benchmarks/BUILD
  15. 111
      benchmarks/benchmark.cc
  16. 2
      build_defs/BUILD.bazel
  17. 1
      build_defs/cpp_opts.bzl
  18. 9
      ci/common.bazelrc
  19. 31
      conformance/BUILD.bazel
  20. 189
      conformance/binary_json_conformance_suite.cc
  21. 1
      conformance/binary_json_conformance_suite.h
  22. 89
      conformance/conformance_rust.rs
  23. 10
      conformance/conformance_rust_overlay_hack.proto
  24. 44
      conformance/failure_list_cpp.txt
  25. 6
      conformance/failure_list_csharp.txt
  26. 33
      conformance/failure_list_java.txt
  27. 33
      conformance/failure_list_jruby.txt
  28. 2
      conformance/failure_list_jruby_ffi.txt
  29. 8
      conformance/failure_list_php_c.txt
  30. 6
      conformance/failure_list_python.txt
  31. 6
      conformance/failure_list_python_cpp.txt
  32. 6
      conformance/failure_list_python_upb.txt
  33. 2
      conformance/failure_list_ruby.txt
  34. 17
      csharp/src/Google.Protobuf.Test/JsonParserTest.cs
  35. BIN
      csharp/src/Google.Protobuf.Test/testprotos.pb
  36. 5
      csharp/src/Google.Protobuf/Google.Protobuf.csproj
  37. 1742
      csharp/src/Google.Protobuf/JsonFormatter.cs
  38. 343
      csharp/src/Google.Protobuf/Reflection/Descriptor.pb.cs
  39. 671
      csharp/src/Google.Protobuf/Reflection/ReflectionUtil.cs
  40. 2
      examples/BUILD.bazel
  41. 120
      java/core/src/main/java/com/google/protobuf/CodedOutputStream.java
  42. 10
      java/core/src/main/java/com/google/protobuf/Descriptors.java
  43. 2
      java/core/src/main/java/com/google/protobuf/GeneratedMessage.java
  44. 40
      java/core/src/main/java/com/google/protobuf/Utf8.java
  45. 75
      java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java
  46. 2
      java/core/src/test/java/com/google/protobuf/Utf8Test.java
  47. 2
      java/internal/testing.bzl
  48. 20
      java/util/src/main/java/com/google/protobuf/util/Durations.java
  49. 21
      java/util/src/main/java/com/google/protobuf/util/ProtoFileUtil.java
  50. 36
      java/util/src/main/java/com/google/protobuf/util/Timestamps.java
  51. 24
      java/util/src/test/java/com/google/protobuf/util/ProtoFileUtilTest.java
  52. 3
      lua/BUILD.bazel
  53. 2
      php/ext/google/protobuf/config.m4
  54. 15
      php/ext/google/protobuf/message.c
  55. 22895
      php/ext/google/protobuf/php-upb.c
  56. 6512
      php/ext/google/protobuf/php-upb.h
  57. 127
      php/tests/GeneratedServiceTest.php
  58. 18
      php/tests/proto/test_service.proto
  59. 13
      php/tests/proto/test_service_namespace.proto
  60. 4
      pkg/BUILD.bazel
  61. 64
      protobuf_release.bzl
  62. 19
      protos/BUILD
  63. 2
      protos/bazel/BUILD
  64. 2
      protos/bazel/upb_cc_proto_library.bzl
  65. 13
      protos/protos.cc
  66. 21
      protos/protos.h
  67. 4
      protos/protos_internal_test.cc
  68. 10
      protos/repeated_field.h
  69. 2
      protos/repeated_field_iterator.h
  70. 6
      protos_generator/BUILD
  71. 2
      protos_generator/gen_accessors.cc
  72. 17
      protos_generator/gen_messages.cc
  73. 3
      protos_generator/tests/BUILD
  74. 14
      protos_generator/tests/test_generated.cc
  75. 6
      protos_generator/tests/test_model.proto
  76. 19
      python/BUILD.bazel
  77. 19
      python/build_targets.bzl
  78. 2
      python/convert.c
  79. 49
      python/descriptor.c
  80. 9
      python/descriptor_pool.c
  81. 7
      python/google/protobuf/descriptor.py
  82. 38
      python/google/protobuf/descriptor_pool.py
  83. 12
      python/google/protobuf/internal/containers.py
  84. 3
      python/google/protobuf/internal/descriptor_test.py
  85. 9
      python/google/protobuf/internal/json_format_test.py
  86. 18
      python/google/protobuf/internal/message_test.py
  87. 9
      python/google/protobuf/internal/python_message.py
  88. 57
      python/google/protobuf/internal/well_known_types.py
  89. 24
      python/google/protobuf/internal/well_known_types_test.py
  90. 5
      python/google/protobuf/message.py
  91. 5
      python/google/protobuf/pyext/descriptor.cc
  92. 105
      python/google/protobuf/pyext/descriptor_pool.cc
  93. 36
      python/google/protobuf/pyext/message.cc
  94. 14
      python/google/protobuf/pyext/message.h
  95. 14
      python/google/protobuf/pyext/repeated_scalar_container.cc
  96. 27
      python/map.c
  97. 4
      python/map.h
  98. 15
      python/pb_unit_tests/BUILD
  99. 7
      python/pb_unit_tests/message_test_wrapper.py
  100. 4
      ruby/.gitignore
  101. Some files were not shown because too many files have changed in this diff Show More

@ -26,3 +26,7 @@ build:ubsan --copt=-fno-sanitize=function --copt=-fno-sanitize=vptr
# TODO: migrate all dependencies from WORKSPACE to MODULE.bazel
# https://github.com/protocolbuffers/protobuf/issues/14313
common --noenable_bzlmod
# Important: this flag ensures that we remain compliant with the C++ layering
# check.
build --features=layering_check

@ -3,7 +3,7 @@ name: Clear expensive caches to prevent unbounded growth
on:
schedule:
# Run every 4 months at 10 AM UTC (2 AM PDT)
- cron: 0 10 1 */4 *
- cron: 0 10 5 */4 *
# manual
workflow_dispatch:
@ -31,5 +31,5 @@ jobs:
- name: Create an empty cache with a single file
run: |
rm -rf .repository-cache
mkdir -p .repository-cache'
mkdir -p .repository-cache
touch .repository-cache/reset_file

@ -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,16 +354,18 @@ 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:
fail-fast: false # Don't cancel all jobs if one fails.
matrix:
include:
- name: MacOS CMake
os: macos-12
flags: -DCMAKE_CXX_STANDARD=14
cache-prefix: macos-cmake
# TODO: investigate and fix
# - name: MacOS CMake
# os: macos-12
# flags: -DCMAKE_CXX_STANDARD=14
# cache-prefix: macos-cmake
- name: Windows CMake
os: windows-2022
flags: >-

@ -20,7 +20,9 @@ jobs:
- name: OpenJDK 8
version: '8'
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/java:8-1fdbb997433cb22c1e49ef75ad374a8d6bb88702
targets: //java/... //java/internal:java_version
# TODO: b/318555165 - enable the layering check. Currently it does
# not work correctly with the toolchain in this Docker image.
targets: //java/... //java/internal:java_version --features=-layering_check
- name: OpenJDK 11
version: '11'
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/java:11-1fdbb997433cb22c1e49ef75ad374a8d6bb88702
@ -63,7 +65,9 @@ jobs:
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/java:8-1fdbb997433cb22c1e49ef75ad374a8d6bb88702
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: java_linux/8
bazel: test --test_output=all //java:linkage_monitor --spawn_strategy=standalone
# TODO: b/318555165 - enable the layering check. Currently it does
# not work correctly with the toolchain in this Docker image.
bazel: test --test_output=all //java:linkage_monitor --spawn_strategy=standalone --features=-layering_check
protobuf-bom:
name: Protobuf Maven BOM

@ -24,9 +24,10 @@ jobs:
#- { name: Ruby 2.7, ruby: ruby-2.7.0, ffi: FFI }
- { name: Ruby 3.0, ruby: ruby-3.0.2 }
- { name: Ruby 3.1, ruby: ruby-3.1.0 }
- { name: Ruby 3.2, ruby: ruby-3.2.0, ffi: NATIVE }
- { name: Ruby 3.2, ruby: ruby-3.2.0 }
- { name: Ruby 3.3, ruby: ruby-3.3.0, ffi: NATIVE }
# TODO Re-enable these once flakes are fixed
#- { name: Ruby 3.2, ruby: ruby-3.2.0, ffi: FFI }
#- { name: Ruby 3.3, ruby: ruby-3.3.0, ffi: FFI }
- { name: JRuby 9.4, ruby: jruby-9.4.3.0, ffi: NATIVE }
- { name: JRuby 9.4, ruby: jruby-9.4.3.0, ffi: FFI }
@ -40,7 +41,7 @@ jobs:
- name: Run tests
uses: protocolbuffers/protobuf-ci/bazel-docker@v2
with:
image: ${{ matrix.image || format('us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:{0}-6.3.0-66964dc8b07b6d1fc73a5cc14e59e84c1c534cea', matrix.ruby) }}
image: ${{ matrix.image || format('us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:{0}-6.3.0-904cad5249547845454998ca3837a34c71fabf96', matrix.ruby) }}
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: ruby_linux/${{ matrix.ruby }}_${{ matrix.bazel }}
bazel: test //ruby/... //ruby/tests:ruby_version --test_env=KOKORO_RUBY_VERSION --test_env=BAZEL=true ${{ matrix.ffi == 'FFI' && '--//ruby:ffi=enabled --test_env=PROTOCOL_BUFFERS_RUBY_IMPLEMENTATION=FFI' || '' }}
@ -67,9 +68,10 @@ jobs:
with:
image: i386/ruby:2.7.3-buster
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
# Pin to Ruby 2.7 compatible bundler version.
command: >-
/bin/bash -cex '
gem install bundler;
gem install bundler -v 2.4.22;
cd /workspace/ruby;
bundle;
PROTOC=/workspace/${{ steps.cross-compile.outputs.protoc }} rake;
@ -98,9 +100,10 @@ jobs:
with:
image: arm64v8/ruby:2.7.3-buster
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
# Pin to Ruby 2.7 compatible bundler version.
command: >-
/bin/bash -cex '
gem install bundler;
gem install bundler -v 2.4.22;
cd /workspace/ruby;
bundle;
PROTOC=/workspace/${{ steps.cross-compile.outputs.protoc }} rake;
@ -120,9 +123,10 @@ jobs:
#- { version: "2.7", ffi: FFI }
- { version: "3.0" }
- { version: "3.1" }
- { version: "3.2", ffi: NATIVE }
- { version: "3.2" }
- { version: "3.3", ffi: NATIVE }
# TODO Re-enable these once flakes are fixed
#- { version: "3.2", ffi: FFI }
#- { version: "3.3", ffi: FFI }
name: MacOS Ruby ${{ matrix.version }}${{ matrix.ffi == 'FFI' && ' FFI' || '' }}
runs-on: macos-12
@ -133,7 +137,7 @@ jobs:
ref: ${{ inputs.safe-checkout }}
- name: Pin Ruby version
uses: ruby/setup-ruby@ee26e27437bde475b19a6bf8cb73c9fa658876a2 # v1.134.0
uses: ruby/setup-ruby@961f85197f92e4842e3cb92a4f97bd8e010cdbaf # v1.165.0
with:
ruby-version: ${{ matrix.version }}
@ -158,8 +162,9 @@ jobs:
- { name: Ruby 2.7, ruby: ruby-2.7.0, ffi: FFI }
- { name: Ruby 3.0, ruby: ruby-3.0.2}
- { name: Ruby 3.1, ruby: ruby-3.1.0}
- { name: Ruby 3.2, ruby: ruby-3.2.0, ffi: NATIVE }
- { name: Ruby 3.2, ruby: ruby-3.2.0, ffi: FFI }
- { name: Ruby 3.2, ruby: ruby-3.2.0}
- { name: Ruby 3.3, ruby: ruby-3.3.0, ffi: NATIVE }
- { name: Ruby 3.3, ruby: ruby-3.3.0, ffi: FFI }
- { name: JRuby 9.4, ruby: jruby-9.4.3.0, ffi: NATIVE }
- { name: JRuby 9.4, ruby: jruby-9.4.3.0, ffi: FFI }
name: Install ${{ matrix.name }}${{ matrix.ffi == 'FFI' && ' FFI' || '' }}
@ -172,7 +177,7 @@ jobs:
- name: Run tests
uses: protocolbuffers/protobuf-ci/bazel-docker@v2
with:
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:${{ matrix.ruby }}-6.3.0-66964dc8b07b6d1fc73a5cc14e59e84c1c534cea
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:${{ matrix.ruby }}-6.3.0-904cad5249547845454998ca3837a34c71fabf96
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: ruby_install/${{ matrix.ruby }}_${{ matrix.bazel }}
bash: >

@ -23,7 +23,7 @@ jobs:
- name: Run tests
uses: protocolbuffers/protobuf-ci/bazel-docker@v2
with:
image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:6.3.0-91a0ac83e968068672bc6001a4d474cfd9a50f1d
image: "us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:7.0.0-a04396cc76704d4b7c722789e9c08df18f47df53"
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: rust_linux
bazel: >-

@ -17,14 +17,14 @@ 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" }
- { name: "FastTable ASAN", flags: "--//upb:fasttable_enabled=true --config=asan", exclude-targets: "-//benchmarks:benchmark -//python/..." }
- { name: "ASAN", flags: "--config=asan -c dbg", exclude-targets: "-//benchmarks:benchmark -//python/..." }
- { name: "UBSAN", flags: "--config=ubsan -c dbg", exclude-targets: "-//benchmarks:benchmark -//python/... -//lua/..." }
- { name: "32-bit", flags: "--copt=-m32 --linkopt=-m32", exclude-targets: "-//benchmarks:benchmark -//python/..." }
# TODO: b/297027295 - Add 32-bit ASAN test
# TODO: Add 32-bit ASAN test
# TODO: Restore the FastTable tests
name: ${{ matrix.config.name }}
runs-on: ubuntu-latest
@ -37,7 +37,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 +81,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 +108,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:

@ -85,6 +85,68 @@ alias(
visibility = ["//visibility:public"],
)
# C++ targets for the well-known types
alias(
name = "any_cc_proto",
actual = "//src/google/protobuf:any_cc_proto",
visibility = ["//visibility:public"],
)
alias(
name = "api_cc_proto",
actual = "//src/google/protobuf:api_cc_proto",
visibility = ["//visibility:public"],
)
alias(
name = "duration_cc_proto",
actual = "//src/google/protobuf:duration_cc_proto",
visibility = ["//visibility:public"],
)
alias(
name = "empty_cc_proto",
actual = "//src/google/protobuf:empty_cc_proto",
visibility = ["//visibility:public"],
)
alias(
name = "field_mask_cc_proto",
actual = "//src/google/protobuf:field_mask_cc_proto",
visibility = ["//visibility:public"],
)
alias(
name = "source_context_cc_proto",
actual = "//src/google/protobuf:source_context_cc_proto",
visibility = ["//visibility:public"],
)
alias(
name = "struct_cc_proto",
actual = "//src/google/protobuf:struct_cc_proto",
visibility = ["//visibility:public"],
)
alias(
name = "timestamp_cc_proto",
actual = "//src/google/protobuf:timestamp_cc_proto",
visibility = ["//visibility:public"],
)
alias(
name = "type_cc_proto",
actual = "//src/google/protobuf:type_cc_proto",
visibility = ["//visibility:public"],
)
alias(
name = "wrappers_cc_proto",
actual = "//src/google/protobuf:wrappers_cc_proto",
visibility = ["//visibility:public"],
)
# Source files: these are aliases to a filegroup, not a `proto_library`.
#
# (This is _probably_ not what you want.)
@ -189,9 +251,16 @@ cc_binary(
# Expose the runtime for the proto_lang_toolchain so that it can also be used in
# a user-defined proto_lang_toolchain.
alias(
name = "protobuf",
actual = "//src/google/protobuf",
visibility = ["//visibility:public"],
)
alias(
name = "protobuf_nowkt",
actual = "//src/google/protobuf:protobuf_nowkt",
deprecation = "Use //:protobuf instead",
visibility = ["//visibility:public"],
)
@ -210,23 +279,6 @@ alias(
visibility = ["//visibility:public"],
)
cc_library(
name = "protobuf",
copts = COPTS,
linkopts = LINK_OPTS,
visibility = ["//visibility:public"],
deps = [
"//src/google/protobuf",
"//src/google/protobuf/compiler:importer",
"//src/google/protobuf/util:delimited_message_util",
"//src/google/protobuf/util:differencer",
"//src/google/protobuf/util:field_mask_util",
"//src/google/protobuf/util:json_util",
"//src/google/protobuf/util:time_util",
"//src/google/protobuf/util:type_resolver_util",
],
)
# This provides just the header files for use in projects that need to build
# shared libraries for dynamic loading. This target is available until Bazel
# adds native support for such use cases.
@ -324,7 +376,7 @@ proto_lang_toolchain(
"//:descriptor_proto",
],
command_line = "--cpp_out=$(OUT)",
runtime = "//src/google/protobuf:protobuf_nowkt",
runtime = "//src/google/protobuf",
visibility = ["//visibility:public"],
)

@ -279,6 +279,8 @@ endif (MSVC)
include_directories(
${ZLIB_INCLUDE_DIRECTORIES}
${protobuf_BINARY_DIR}
# Support #include-ing other top-level directories, i.e. upb_generator.
${protobuf_SOURCE_DIR}
${protobuf_SOURCE_DIR}/src)
set(protobuf_ABSL_PROVIDER "module" CACHE STRING "Provider of absl library")

@ -191,11 +191,6 @@ load("@fuzzing_py_deps//:requirements.bzl", fuzzing_py_deps_install_deps = "inst
fuzzing_py_deps_install_deps()
bind(
name = "python_headers",
actual = "@system_python//:python_headers",
)
http_archive(
name = "rules_rust",
sha256 = "9ecd0f2144f0a24e6bc71ebcc50a1ee5128cedeceb32187004532c9710cb2334",

@ -52,8 +52,8 @@ bzl_library(
],
deps = [
"@bazel_skylib//lib:paths",
"@rules_proto//proto:defs",
"@bazel_tools//tools/cpp:toolchain_utils.bzl",
"@rules_proto//proto:defs",
],
)

@ -31,8 +31,8 @@ _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"],
# # Override default -Oz for release builds on Android.
# "//bazel:android_opt": _DEFAULT_CPPOPTS + ["-O2"],
# end:google_only
"//conditions:default": _DEFAULT_CPPOPTS,
})
@ -41,8 +41,8 @@ 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"],
# # Override default -Oz for release builds on Android.
# "//bazel:android_opt": _DEFAULT_COPTS + ["-O2"],
# end:google_only
"//conditions:default": _DEFAULT_COPTS,
})

@ -14,6 +14,7 @@ load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
def upb_use_cpp_toolchain():
return ["@bazel_tools//tools/cpp:toolchain_type"]
# end:github_only
def cc_library_func(ctx, name, hdrs, srcs, copts, includes, dep_ccinfos):

@ -6,16 +6,16 @@
# https://developers.google.com/open-source/licenses/bsd
load("@rules_python//python:defs.bzl", "py_binary")
# begin:google_only
# load("@rules_cc//cc:defs.bzl", "cc_proto_library")
# end:google_only
load(
"//bazel:upb_proto_library.bzl",
"upb_c_proto_library",
"upb_proto_reflection_library",
)
# begin:google_only
# load("@rules_cc//cc:defs.bzl", "cc_proto_library")
# end:google_only
load(
":build_defs.bzl",
"cc_optimizefor_proto_library",
@ -76,14 +76,19 @@ cc_test(
":benchmark_descriptor_upb_proto",
":benchmark_descriptor_upb_proto_reflection",
"//:protobuf",
"@com_google_googletest//:gtest_main",
"//src/google/protobuf/json",
"//upb:base",
"//upb:base_internal",
"//upb:descriptor_upb_proto",
"//upb:json",
"//upb:mem",
"//upb:reflection",
"//upb:wire",
"//upb/base:internal",
"@com_github_google_benchmark//:benchmark_main",
"@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/log:absl_check",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
],
)

@ -7,23 +7,32 @@
#include <benchmark/benchmark.h>
#include <stdint.h>
#include <string.h>
#include <string>
#include <vector>
#include "google/ads/googleads/v13/services/google_ads_service.upbdefs.h"
#include "google/protobuf/descriptor.pb.h"
#include "absl/container/flat_hash_set.h"
#include "absl/log/absl_check.h"
#include "google/protobuf/dynamic_message.h"
#include "google/protobuf/json/json.h"
#include "benchmarks/descriptor.pb.h"
#include "benchmarks/descriptor.upb.h"
#include "benchmarks/descriptor.upbdefs.h"
#include "benchmarks/descriptor_sv.pb.h"
#include "upb/base/internal/log2.h"
#include "upb/base/upcast.h"
#include "upb/json/decode.h"
#include "upb/json/encode.h"
#include "upb/mem/arena.h"
#include "upb/reflection/def.hpp"
#include "upb/wire/decode.h"
upb_StringView descriptor = benchmarks_descriptor_proto_upbdefinit.descriptor;
upb_StringView descriptor =
benchmarks_descriptor_proto_upbdefinit.descriptor;
namespace protobuf = ::google::protobuf;
// A buffer big enough to parse descriptor.proto without going to heap.
@ -341,9 +350,7 @@ static void BM_SerializeDescriptor_Proto2(benchmark::State& state) {
}
BENCHMARK(BM_SerializeDescriptor_Proto2);
static void BM_SerializeDescriptor_Upb(benchmark::State& state) {
int64_t total = 0;
upb_Arena* arena = upb_Arena_New();
static upb_benchmark_FileDescriptorProto* UpbParseDescriptor(upb_Arena* arena) {
upb_benchmark_FileDescriptorProto* set =
upb_benchmark_FileDescriptorProto_parse(descriptor.data, descriptor.size,
arena);
@ -351,6 +358,13 @@ static void BM_SerializeDescriptor_Upb(benchmark::State& state) {
printf("Failed to parse.\n");
exit(1);
}
return set;
}
static void BM_SerializeDescriptor_Upb(benchmark::State& state) {
int64_t total = 0;
upb_Arena* arena = upb_Arena_New();
upb_benchmark_FileDescriptorProto* set = UpbParseDescriptor(arena);
for (auto _ : state) {
upb_Arena* enc_arena = upb_Arena_Init(buf, sizeof(buf), nullptr);
size_t size;
@ -365,3 +379,92 @@ static void BM_SerializeDescriptor_Upb(benchmark::State& state) {
state.SetBytesProcessed(total);
}
BENCHMARK(BM_SerializeDescriptor_Upb);
static absl::string_view UpbJsonEncode(upb_benchmark_FileDescriptorProto* proto,
const upb_MessageDef* md,
upb_Arena* arena) {
size_t size =
upb_JsonEncode(UPB_UPCAST(proto), md, nullptr, 0, nullptr, 0, nullptr);
char* buf = reinterpret_cast<char*>(upb_Arena_Malloc(arena, size + 1));
upb_JsonEncode(UPB_UPCAST(proto), md, nullptr, 0, buf, size, nullptr);
return absl::string_view(buf, size);
}
static void BM_JsonParse_Upb(benchmark::State& state) {
upb_Arena* arena = upb_Arena_New();
upb_benchmark_FileDescriptorProto* set =
upb_benchmark_FileDescriptorProto_parse(descriptor.data, descriptor.size,
arena);
if (!set) {
printf("Failed to parse.\n");
exit(1);
}
upb::DefPool defpool;
const upb_MessageDef* md =
upb_benchmark_FileDescriptorProto_getmsgdef(defpool.ptr());
auto json = UpbJsonEncode(set, md, arena);
for (auto _ : state) {
upb_Arena* arena = upb_Arena_New();
upb_benchmark_FileDescriptorProto* proto =
upb_benchmark_FileDescriptorProto_new(arena);
upb_JsonDecode(json.data(), json.size(), UPB_UPCAST(proto), md,
defpool.ptr(), 0, arena, nullptr);
upb_Arena_Free(arena);
}
state.SetBytesProcessed(state.iterations() * json.size());
}
BENCHMARK(BM_JsonParse_Upb);
static void BM_JsonParse_Proto2(benchmark::State& state) {
protobuf::FileDescriptorProto proto;
absl::string_view input(descriptor.data, descriptor.size);
proto.ParseFromString(input);
std::string json;
ABSL_CHECK_OK(google::protobuf::json::MessageToJsonString(proto, &json));
for (auto _ : state) {
protobuf::FileDescriptorProto proto;
ABSL_CHECK_OK(google::protobuf::json::JsonStringToMessage(json, &proto));
}
state.SetBytesProcessed(state.iterations() * json.size());
}
BENCHMARK(BM_JsonParse_Proto2);
static void BM_JsonSerialize_Upb(benchmark::State& state) {
upb_Arena* arena = upb_Arena_New();
upb_benchmark_FileDescriptorProto* set =
upb_benchmark_FileDescriptorProto_parse(descriptor.data, descriptor.size,
arena);
ABSL_CHECK(set != nullptr);
upb::DefPool defpool;
const upb_MessageDef* md =
upb_benchmark_FileDescriptorProto_getmsgdef(defpool.ptr());
auto json = UpbJsonEncode(set, md, arena);
std::string json_str;
json_str.resize(json.size());
for (auto _ : state) {
// This isn't a fully fair comparison, as it assumes we already know the
// correct size of the buffer. In practice, we usually need to run the
// encoder twice, once to discover the size of the buffer.
upb_JsonEncode(UPB_UPCAST(set), md, nullptr, 0, json_str.data(),
json_str.size(), nullptr);
}
state.SetBytesProcessed(state.iterations() * json.size());
}
BENCHMARK(BM_JsonSerialize_Upb);
static void BM_JsonSerialize_Proto2(benchmark::State& state) {
protobuf::FileDescriptorProto proto;
absl::string_view input(descriptor.data, descriptor.size);
proto.ParseFromString(input);
std::string json;
for (auto _ : state) {
json.clear();
ABSL_CHECK_OK(google::protobuf::json::MessageToJsonString(proto, &json));
}
state.SetBytesProcessed(state.iterations() * json.size());
}
BENCHMARK(BM_JsonSerialize_Proto2);

@ -38,7 +38,7 @@ config_setting(
config_setting(
name = "config_android",
values = {
"crosstool_top": "//external:android/crosstool",
"crosstool_top": "@platforms//os:android",
},
)

@ -15,6 +15,7 @@ COPTS = select({
"/wd4506", # no definition for inline function 'function'
"/wd4800", # 'type' : forcing value to bool 'true' or 'false' (performance warning)
"/wd4996", # The compiler encountered a deprecated declaration.
"/utf-8", # Set source and execution character sets to UTF-8
],
"//conditions:default": [
"-DHAVE_ZLIB",

@ -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,11 @@ 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
# Important: this flag ensures that we remain compliant with the C++ layering
# check.
build --features=layering_check

@ -1,16 +1,16 @@
# Conformance testing for Protobuf.
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_proto_library", "objc_library")
load("@rules_ruby//ruby:defs.bzl", "ruby_binary")
load("//ruby:defs.bzl", "internal_ruby_proto_library")
load("//:protobuf.bzl", "internal_csharp_proto_library", "internal_objc_proto_library", "internal_php_proto_library", "internal_py_proto_library")
load("//build_defs:internal_shell.bzl", "inline_sh_binary")
load(
"@rules_pkg//:mappings.bzl",
"pkg_filegroup",
"pkg_files",
"strip_prefix",
)
load("@rules_ruby//ruby:defs.bzl", "ruby_binary")
load("//:protobuf.bzl", "internal_csharp_proto_library", "internal_objc_proto_library", "internal_php_proto_library", "internal_py_proto_library")
load("//build_defs:internal_shell.bzl", "inline_sh_binary")
load("//ruby:defs.bzl", "internal_ruby_proto_library")
exports_files([
"bazel_conformance_test_runner.sh",
@ -144,9 +144,15 @@ cc_library(
includes = ["."],
deps = [
":conformance_cc_proto",
"//src/google/protobuf",
"//src/google/protobuf:protobuf_lite",
"//src/google/protobuf/util:differencer",
"//src/google/protobuf/util:json_util",
"//src/google/protobuf/util:type_resolver_util",
"@com_google_absl//absl/container:btree",
"@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/log:absl_check",
"@com_google_absl//absl/log:absl_log",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/strings:str_format",
],
@ -158,13 +164,21 @@ cc_library(
srcs = ["binary_json_conformance_suite.cc"],
hdrs = ["binary_json_conformance_suite.h"],
deps = [
":conformance_cc_proto",
":conformance_test",
":test_messages_proto2_proto_cc",
":test_messages_proto3_proto_cc",
"//src/google/protobuf",
"//src/google/protobuf:protobuf_lite",
"//src/google/protobuf/editions:test_messages_proto2_editions_cc_proto",
"//src/google/protobuf/editions:test_messages_proto3_editions_cc_proto",
"//src/google/protobuf/json",
"//src/google/protobuf/util:type_resolver_util",
"@com_google_absl//absl/log:absl_check",
"@com_google_absl//absl/log:absl_log",
"@com_google_absl//absl/log:die_if_null",
"@com_google_absl//absl/status",
"@com_google_absl//absl/strings",
"@jsoncpp",
],
)
@ -178,6 +192,7 @@ cc_library(
":conformance_test",
":test_messages_proto2_proto_cc",
":test_messages_proto3_proto_cc",
"//src/google/protobuf",
"//src/google/protobuf/editions:test_messages_proto2_editions_cc_proto",
"//src/google/protobuf/editions:test_messages_proto3_editions_cc_proto",
"@com_google_absl//absl/log:absl_log",
@ -209,8 +224,16 @@ cc_binary(
"//:protobuf",
"//:test_messages_proto2_cc_proto",
"//:test_messages_proto3_cc_proto",
"//src/google/protobuf",
"//src/google/protobuf:port",
"//src/google/protobuf:protobuf_lite",
"//src/google/protobuf/editions:test_messages_proto2_editions_cc_proto",
"//src/google/protobuf/editions:test_messages_proto3_editions_cc_proto",
"//src/google/protobuf/stubs",
"//src/google/protobuf/util:json_util",
"//src/google/protobuf/util:type_resolver_util",
"@com_google_absl//absl/log:absl_check",
"@com_google_absl//absl/log:absl_log",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
],

@ -453,17 +453,15 @@ void BinaryAndJsonConformanceSuiteImpl<MessageType>::RunValidProtobufTest(
const std::string& equivalent_text_format) {
MessageType prototype;
ConformanceRequestSetting setting1(
ConformanceRequestSetting binary_to_binary(
level, conformance::PROTOBUF, conformance::PROTOBUF,
conformance::BINARY_TEST, prototype, test_name, input_protobuf);
suite_.RunValidInputTest(setting1, equivalent_text_format);
suite_.RunValidInputTest(binary_to_binary, equivalent_text_format);
if (run_proto3_tests_) {
ConformanceRequestSetting setting2(
level, conformance::PROTOBUF, conformance::JSON,
conformance::BINARY_TEST, prototype, test_name, input_protobuf);
suite_.RunValidInputTest(setting2, equivalent_text_format);
}
ConformanceRequestSetting binary_to_json(
level, conformance::PROTOBUF, conformance::JSON, conformance::BINARY_TEST,
prototype, test_name, input_protobuf);
suite_.RunValidInputTest(binary_to_json, equivalent_text_format);
}
template <typename MessageType>
@ -1673,79 +1671,69 @@ void BinaryAndJsonConformanceSuiteImpl<MessageType>::
template <typename MessageType>
void BinaryAndJsonConformanceSuiteImpl<MessageType>::RunJsonTests() {
if (!run_proto3_tests_) {
RunValidJsonTestWithValidator(
"StoresDefaultPrimitive", REQUIRED,
R"({
"FieldName13": 0
})",
[](const Json::Value& value) { return value.isMember("FieldName13"); });
std::vector<const FieldDescriptor*> extensions;
MessageType::GetDescriptor()->file()->pool()->FindAllExtensions(
MessageType::GetDescriptor(), &extensions);
RunValidJsonTestWithValidator("FieldNameExtension", RECOMMENDED,
absl::Substitute(R"({
"[$0]": 1
})",
extensions[0]->full_name()),
[&](const Json::Value& value) {
return value.isMember(absl::StrCat(
"[", extensions[0]->full_name(), "]"));
});
return;
}
RunValidJsonTest("HelloWorld", REQUIRED,
"{\"optionalString\":\"Hello, World!\"}",
"optional_string: 'Hello, World!'");
// NOTE: The spec for JSON support is still being sorted out, these may not
// all be correct.
RunJsonTestsForFieldNameConvention();
RunJsonTestsForNonRepeatedTypes();
RunJsonTestsForRepeatedTypes();
RunJsonTestsForNullTypes();
RunJsonTestsForWrapperTypes();
RunJsonTestsForFieldMask();
RunJsonTestsForStruct();
RunJsonTestsForValue();
RunJsonTestsForAny();
if (run_proto3_tests_) {
RunJsonTestsForWrapperTypes();
RunJsonTestsForFieldMask();
RunJsonTestsForStruct();
RunJsonTestsForValue();
RunJsonTestsForAny();
} else {
// Currently Proto2 only, but should also be run on Proto3-optional.
RunJsonTestsForStoresDefaultPrimitive();
}
RunJsonTestsForUnknownEnumStringValues();
RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonNumber", REQUIRED,
R"({
"unknown": 1
})",
"");
R"({"unknown": 1})", "");
RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonString", REQUIRED,
R"({
"unknown": "a"
})",
"");
R"({"unknown": "a"})", "");
RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonTrue", REQUIRED,
R"({
"unknown": true
})",
"");
R"({"unknown": true})", "");
RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonFalse", REQUIRED,
R"({
"unknown": false
})",
"");
R"({"unknown": false})", "");
RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonNull", REQUIRED,
R"({
"unknown": null
})",
"");
R"({"unknown": null})", "");
RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonObject", REQUIRED,
R"({
"unknown": {"a": 1}
})",
"");
R"({"unknown": {"a": 1}})", "");
ExpectParseFailureForJson("RejectTopLevelNull", REQUIRED, "null");
}
template <typename MessageType>
void BinaryAndJsonConformanceSuiteImpl<
MessageType>::RunJsonTestsForStoresDefaultPrimitive() {
RunValidJsonTestWithValidator(
"StoresDefaultPrimitive", REQUIRED,
R"({
"FieldName13": 0
})",
[](const Json::Value& value) { return value.isMember("FieldName13"); });
std::vector<const FieldDescriptor*> extensions;
MessageType::GetDescriptor()->file()->pool()->FindAllExtensions(
MessageType::GetDescriptor(), &extensions);
RunValidJsonTestWithValidator("FieldNameExtension", RECOMMENDED,
absl::Substitute(R"({
"[$0]": 1
})",
extensions[0]->full_name()),
[&](const Json::Value& value) {
return value.isMember(absl::StrCat(
"[", extensions[0]->full_name(), "]"));
});
}
template <typename MessageType>
void BinaryAndJsonConformanceSuiteImpl<
MessageType>::RunJsonTestsForUnknownEnumStringValues() {
@ -2011,12 +1999,14 @@ void BinaryAndJsonConformanceSuiteImpl<
value.isMember("fieldName15") && value.isMember("fieldName16") &&
value.isMember("fieldName17") && value.isMember("FieldName18");
});
RunValidJsonTestWithValidator(
"SkipsDefaultPrimitive", REQUIRED,
R"({
"FieldName13": 0
})",
[](const Json::Value& value) { return !value.isMember("FieldName13"); });
if (run_proto3_tests_) {
RunValidJsonTestWithValidator("SkipsDefaultPrimitive", REQUIRED,
R"({"FieldName13": 0})",
[](const Json::Value& value) {
return !value.isMember("FieldName13");
});
}
}
template <typename MessageType>
@ -2273,19 +2263,23 @@ void BinaryAndJsonConformanceSuiteImpl<
// Enum fields.
RunValidJsonTest("EnumField", REQUIRED, R"({"optionalNestedEnum": "FOO"})",
"optional_nested_enum: FOO");
// Enum fields with alias
RunValidJsonTest("EnumFieldWithAlias", REQUIRED,
R"({"optionalAliasedEnum": "ALIAS_BAZ"})",
"optional_aliased_enum: ALIAS_BAZ");
RunValidJsonTest("EnumFieldWithAliasUseAlias", REQUIRED,
R"({"optionalAliasedEnum": "MOO"})",
"optional_aliased_enum: ALIAS_BAZ");
RunValidJsonTest("EnumFieldWithAliasLowerCase", REQUIRED,
R"({"optionalAliasedEnum": "moo"})",
"optional_aliased_enum: ALIAS_BAZ");
RunValidJsonTest("EnumFieldWithAliasDifferentCase", REQUIRED,
R"({"optionalAliasedEnum": "bAz"})",
"optional_aliased_enum: ALIAS_BAZ");
if (run_proto3_tests_) {
RunValidJsonTest("EnumFieldWithAlias", REQUIRED,
R"({"optionalAliasedEnum": "ALIAS_BAZ"})",
"optional_aliased_enum: ALIAS_BAZ");
RunValidJsonTest("EnumFieldWithAliasUseAlias", REQUIRED,
R"({"optionalAliasedEnum": "MOO"})",
"optional_aliased_enum: ALIAS_BAZ");
RunValidJsonTest("EnumFieldWithAliasLowerCase", REQUIRED,
R"({"optionalAliasedEnum": "moo"})",
"optional_aliased_enum: ALIAS_BAZ");
RunValidJsonTest("EnumFieldWithAliasDifferentCase", REQUIRED,
R"({"optionalAliasedEnum": "bAz"})",
"optional_aliased_enum: ALIAS_BAZ");
}
// Enum values must be represented as strings.
ExpectParseFailureForJson("EnumFieldNotQuoted", REQUIRED,
R"({"optionalNestedEnum": FOO})");
@ -2294,13 +2288,16 @@ void BinaryAndJsonConformanceSuiteImpl<
R"({"optionalNestedEnum": 0})", "optional_nested_enum: FOO");
RunValidJsonTest("EnumFieldNumericValueNonZero", REQUIRED,
R"({"optionalNestedEnum": 1})", "optional_nested_enum: BAR");
// Unknown enum values are represented as numeric values.
RunValidJsonTestWithValidator(
"EnumFieldUnknownValue", REQUIRED, R"({"optionalNestedEnum": 123})",
[](const Json::Value& value) {
return value["optionalNestedEnum"].type() == Json::intValue &&
value["optionalNestedEnum"].asInt() == 123;
});
if (run_proto3_tests_) {
// Unknown enum values are represented as numeric values.
RunValidJsonTestWithValidator(
"EnumFieldUnknownValue", REQUIRED, R"({"optionalNestedEnum": 123})",
[](const Json::Value& value) {
return value["optionalNestedEnum"].type() == Json::intValue &&
value["optionalNestedEnum"].asInt() == 123;
});
}
// String fields.
RunValidJsonTest("StringField", REQUIRED,
@ -3002,18 +2999,18 @@ void BinaryAndJsonConformanceSuiteImpl<MessageType>::RunJsonTestsForValue() {
}
]
)");
RunValidJsonTestWithValidator(
"NullValueInOtherOneofOldFormat", RECOMMENDED,
R"({"oneofNullValue": "NULL_VALUE"})", [](const Json::Value& value) {
return (value.isMember("oneofNullValue") &&
value["oneofNullValue"].isNull());
});
RunValidJsonTestWithValidator(
"NullValueInOtherOneofNewFormat", RECOMMENDED,
R"({"oneofNullValue": null})", [](const Json::Value& value) {
return (value.isMember("oneofNullValue") &&
value["oneofNullValue"].isNull());
});
RunValidJsonTestWithValidator("NullValueInOtherOneofOldFormat", RECOMMENDED,
R"({"oneofNullValue": "NULL_VALUE"})",
[](const Json::Value& value) {
return (value.isMember("oneofNullValue") &&
value["oneofNullValue"].isNull());
});
RunValidJsonTestWithValidator("NullValueInOtherOneofNewFormat", RECOMMENDED,
R"({"oneofNullValue": null})",
[](const Json::Value& value) {
return (value.isMember("oneofNullValue") &&
value["oneofNullValue"].isNull());
});
RunValidJsonTestWithValidator(
"NullValueInNormalMessage", RECOMMENDED, R"({"optionalNullValue": null})",
[](const Json::Value& value) { return value.empty(); });

@ -63,6 +63,7 @@ class BinaryAndJsonConformanceSuiteImpl {
void RunBinaryPerformanceTests();
void RunJsonPerformanceTests();
void RunJsonTests();
void RunJsonTestsForStoresDefaultPrimitive();
void RunJsonTestsForFieldNameConvention();
void RunJsonTestsForNonRepeatedTypes();
void RunJsonTestsForRepeatedTypes();

@ -5,6 +5,7 @@
// https://developers.google.com/open-source/licenses/bsd
use conformance_proto::conformance::{ConformanceRequest, ConformanceResponse};
use conformance_rust_overlay_hack_proto::conformance::ConformanceRequestRustOverlayHack;
#[cfg(cpp_kernel)]
use protobuf_cpp as kernel;
@ -16,6 +17,9 @@ use kernel::Optional::{Set, Unset};
use std::io::{self, ErrorKind, Read, Write};
use test_messages_proto2::protobuf_test_messages::proto2::TestAllTypesProto2;
use test_messages_proto2_editions_proto::protobuf_test_messages::editions::proto2::TestAllTypesProto2 as EditionsTestAllTypesProto2;
use test_messages_proto3::protobuf_test_messages::proto3::TestAllTypesProto3;
use test_messages_proto3_editions_proto::protobuf_test_messages::editions::proto3::TestAllTypesProto3 as EditionsTestAllTypesProto3;
/// Returns Some(i32) if a binary read can succeed from stdin.
/// Returns None if we have reached an EOF.
@ -36,13 +40,21 @@ fn read_little_endian_i32_from_stdin() -> Option<i32> {
/// Returns None if we have hit an EOF that suggests the test suite is complete.
/// Panics in any other case (e.g. an EOF in a place that would imply a
/// programmer error in the conformance test suite).
fn read_request_from_stdin() -> Option<ConformanceRequest> {
fn read_request_from_stdin() -> Option<(ConformanceRequest, ConformanceRequestRustOverlayHack)> {
let msg_len = read_little_endian_i32_from_stdin()?;
let mut serialized = vec![0_u8; msg_len as usize];
io::stdin().read_exact(&mut serialized).unwrap();
let mut req = ConformanceRequest::new();
req.deserialize(&serialized).unwrap();
Some(req)
// TODO: b/318373255 - Since enum accessors aren't available yet, we parse an
// overlay with int32 field instead of an enum so that we can check if the
// requested output is binary or not. This will be deleted once enum
// accessors are supported.
let mut req_overlay_hack = ConformanceRequestRustOverlayHack::new();
req_overlay_hack.deserialize(&serialized).unwrap();
Some((req, req_overlay_hack))
}
fn write_response_to_stdout(resp: &ConformanceResponse) {
@ -54,21 +66,19 @@ fn write_response_to_stdout(resp: &ConformanceResponse) {
handle.flush().unwrap();
}
fn do_test(req: &ConformanceRequest) -> ConformanceResponse {
fn do_test(
req: &ConformanceRequest,
req_overlay_hack: &ConformanceRequestRustOverlayHack,
) -> ConformanceResponse {
let mut resp = ConformanceResponse::new();
let message_type = req.message_type();
let is_proto2 = match message_type.as_bytes() {
b"protobuf_test_messages.proto2.TestAllTypesProto2" => true,
b"protobuf_test_messages.proto3.TestAllTypesProto3" => false,
_ => panic!("unexpected msg type {message_type}"),
};
// Enums aren't supported yet (and not in scope for v0.6) so we can't perform
// this check yet.
// TODO: b/318373255 - Use the enum once its supported.
// if req.requested_output_format() != WireFormat.PROTOBUF {
// resp.skipped_mut().set("only wire format output implemented")
// }
if req_overlay_hack.requested_output_format() != 1 {
resp.skipped_mut().set("only wire format output implemented");
return resp;
}
let bytes = match req.protobuf_payload_opt() {
Unset(_) => {
@ -78,25 +88,50 @@ fn do_test(req: &ConformanceRequest) -> ConformanceResponse {
Set(bytes) => bytes,
};
if is_proto2 {
let mut proto = TestAllTypesProto2::new();
if let Err(_) = proto.deserialize(bytes) {
resp.parse_error_mut().set("failed to parse bytes");
return resp;
let serialized = match message_type.as_bytes() {
b"protobuf_test_messages.proto2.TestAllTypesProto2" => {
let mut proto = TestAllTypesProto2::new();
if let Err(_) = proto.deserialize(bytes) {
resp.parse_error_mut().set("failed to parse bytes");
return resp;
}
proto.serialize()
}
let serialized = proto.serialize(); // Note: serialize() is infallible in Rust api.
resp.protobuf_payload_mut().set(serialized.as_ref());
return resp;
} else {
resp.skipped_mut().set("only proto2 supported");
return resp;
}
b"protobuf_test_messages.proto3.TestAllTypesProto3" => {
let mut proto = TestAllTypesProto3::new();
if let Err(_) = proto.deserialize(bytes) {
resp.parse_error_mut().set("failed to parse bytes");
return resp;
}
proto.serialize()
}
b"protobuf_test_messages.editions.proto2.TestAllTypesProto2" => {
let mut proto = EditionsTestAllTypesProto2::new();
if let Err(_) = proto.deserialize(bytes) {
resp.parse_error_mut().set("failed to parse bytes");
return resp;
}
proto.serialize()
}
b"protobuf_test_messages.editions.proto3.TestAllTypesProto3" => {
let mut proto = EditionsTestAllTypesProto3::new();
if let Err(_) = proto.deserialize(bytes) {
resp.parse_error_mut().set("failed to parse bytes");
return resp;
}
proto.serialize()
}
_ => panic!("unexpected msg type {message_type}"),
};
resp.protobuf_payload_mut().set(serialized);
return resp;
}
fn main() {
let mut total_runs = 0;
while let Some(req) = read_request_from_stdin() {
let resp = do_test(&req);
while let Some((req, req_overlay_hack)) = read_request_from_stdin() {
let resp = do_test(&req, &req_overlay_hack);
write_response_to_stdout(&resp);
total_runs += 1;
}

@ -0,0 +1,10 @@
syntax = "proto3";
package conformance;
// Temporary hack to allow the Rust conformance test to read the requested
// output format as an int32. This will be removed once enums accessors are
// supported. b/318373255
message ConformanceRequestRustOverlayHack {
int32 requested_output_format = 3;
}

@ -61,3 +61,47 @@ Recommended.Proto3.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace
Recommended.Editions_Proto3.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace
Recommended.Proto2.JsonInput.FieldNameExtension.Validator
Recommended.Editions_Proto2.JsonInput.FieldNameExtension.Validator
Recommended.Editions_Proto2.JsonInput.BoolFieldDoubleQuotedFalse
Recommended.Editions_Proto2.JsonInput.BoolFieldDoubleQuotedTrue
Recommended.Editions_Proto2.JsonInput.FieldNameDuplicate
Recommended.Editions_Proto2.JsonInput.FieldNameDuplicateDifferentCasing1
Recommended.Editions_Proto2.JsonInput.FieldNameDuplicateDifferentCasing2
Recommended.Editions_Proto2.JsonInput.FieldNameNotQuoted
Recommended.Editions_Proto2.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput
Recommended.Editions_Proto2.JsonInput.MapFieldValueIsNull
Recommended.Editions_Proto2.JsonInput.RepeatedFieldMessageElementIsNull
Recommended.Editions_Proto2.JsonInput.RepeatedFieldPrimitiveElementIsNull
Recommended.Editions_Proto2.JsonInput.RepeatedFieldTrailingComma
Recommended.Editions_Proto2.JsonInput.RepeatedFieldTrailingCommaWithNewlines
Recommended.Editions_Proto2.JsonInput.RepeatedFieldTrailingCommaWithSpace
Recommended.Editions_Proto2.JsonInput.RepeatedFieldTrailingCommaWithSpaceCommaSpace
Recommended.Editions_Proto2.JsonInput.StringFieldSingleQuoteBoth
Recommended.Editions_Proto2.JsonInput.StringFieldSingleQuoteKey
Recommended.Editions_Proto2.JsonInput.StringFieldSingleQuoteValue
Recommended.Editions_Proto2.JsonInput.StringFieldUppercaseEscapeLetter
Recommended.Editions_Proto2.JsonInput.TrailingCommaInAnObject
Recommended.Editions_Proto2.JsonInput.TrailingCommaInAnObjectWithNewlines
Recommended.Editions_Proto2.JsonInput.TrailingCommaInAnObjectWithSpace
Recommended.Editions_Proto2.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace
Recommended.Proto2.JsonInput.BoolFieldDoubleQuotedFalse
Recommended.Proto2.JsonInput.BoolFieldDoubleQuotedTrue
Recommended.Proto2.JsonInput.FieldNameDuplicate
Recommended.Proto2.JsonInput.FieldNameDuplicateDifferentCasing1
Recommended.Proto2.JsonInput.FieldNameDuplicateDifferentCasing2
Recommended.Proto2.JsonInput.FieldNameNotQuoted
Recommended.Proto2.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput
Recommended.Proto2.JsonInput.MapFieldValueIsNull
Recommended.Proto2.JsonInput.RepeatedFieldMessageElementIsNull
Recommended.Proto2.JsonInput.RepeatedFieldPrimitiveElementIsNull
Recommended.Proto2.JsonInput.RepeatedFieldTrailingComma
Recommended.Proto2.JsonInput.RepeatedFieldTrailingCommaWithNewlines
Recommended.Proto2.JsonInput.RepeatedFieldTrailingCommaWithSpace
Recommended.Proto2.JsonInput.RepeatedFieldTrailingCommaWithSpaceCommaSpace
Recommended.Proto2.JsonInput.StringFieldSingleQuoteBoth
Recommended.Proto2.JsonInput.StringFieldSingleQuoteKey
Recommended.Proto2.JsonInput.StringFieldSingleQuoteValue
Recommended.Proto2.JsonInput.StringFieldUppercaseEscapeLetter
Recommended.Proto2.JsonInput.TrailingCommaInAnObject
Recommended.Proto2.JsonInput.TrailingCommaInAnObjectWithNewlines
Recommended.Proto2.JsonInput.TrailingCommaInAnObjectWithSpace
Recommended.Proto2.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace

@ -1,6 +1,12 @@
Recommended.Proto2.JsonInput.FieldNameExtension.Validator
Recommended.Proto2.JsonInput.BytesFieldBase64Url.JsonOutput
Recommended.Proto2.JsonInput.BytesFieldBase64Url.ProtobufOutput
Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput
Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput
Required.Proto2.JsonInput.OneofFieldNullFirst.JsonOutput
Required.Proto2.JsonInput.OneofFieldNullFirst.ProtobufOutput
Required.Proto2.JsonInput.OneofFieldNullSecond.JsonOutput
Required.Proto2.JsonInput.OneofFieldNullSecond.ProtobufOutput
Required.Proto3.JsonInput.OneofFieldNullFirst.JsonOutput
Required.Proto3.JsonInput.OneofFieldNullFirst.ProtobufOutput
Required.Proto3.JsonInput.OneofFieldNullSecond.JsonOutput

@ -42,3 +42,36 @@ Required.Proto3.JsonInput.Int32FieldPlusSign
Required.Proto3.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool
Required.Proto3.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
Required.Proto3.JsonInput.StringFieldNotAString
Recommended.Proto2.JsonInput.BoolFieldAllCapitalFalse
Recommended.Proto2.JsonInput.BoolFieldAllCapitalTrue
Recommended.Proto2.JsonInput.BoolFieldCamelCaseFalse
Recommended.Proto2.JsonInput.BoolFieldCamelCaseTrue
Recommended.Proto2.JsonInput.BoolFieldDoubleQuotedFalse
Recommended.Proto2.JsonInput.BoolFieldDoubleQuotedTrue
Recommended.Proto2.JsonInput.BoolMapFieldKeyNotQuoted
Recommended.Proto2.JsonInput.DoubleFieldInfinityNotQuoted
Recommended.Proto2.JsonInput.DoubleFieldNanNotQuoted
Recommended.Proto2.JsonInput.DoubleFieldNegativeInfinityNotQuoted
Recommended.Proto2.JsonInput.FieldNameDuplicate
Recommended.Proto2.JsonInput.FieldNameNotQuoted
Recommended.Proto2.JsonInput.FloatFieldInfinityNotQuoted
Recommended.Proto2.JsonInput.FloatFieldNanNotQuoted
Recommended.Proto2.JsonInput.FloatFieldNegativeInfinityNotQuoted
Recommended.Proto2.JsonInput.Int32MapFieldKeyNotQuoted
Recommended.Proto2.JsonInput.Int64MapFieldKeyNotQuoted
Recommended.Proto2.JsonInput.JsonWithComments
Recommended.Proto2.JsonInput.StringFieldSingleQuoteBoth
Recommended.Proto2.JsonInput.StringFieldSingleQuoteKey
Recommended.Proto2.JsonInput.StringFieldSingleQuoteValue
Recommended.Proto2.JsonInput.StringFieldSurrogateInWrongOrder
Recommended.Proto2.JsonInput.StringFieldUnpairedHighSurrogate
Recommended.Proto2.JsonInput.StringFieldUnpairedLowSurrogate
Recommended.Proto2.JsonInput.Uint32MapFieldKeyNotQuoted
Recommended.Proto2.JsonInput.Uint64MapFieldKeyNotQuoted
Required.Proto2.JsonInput.EnumFieldNotQuoted
Required.Proto2.JsonInput.Int32FieldLeadingZero
Required.Proto2.JsonInput.Int32FieldNegativeWithLeadingZero
Required.Proto2.JsonInput.Int32FieldPlusSign
Required.Proto2.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool
Required.Proto2.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
Required.Proto2.JsonInput.StringFieldNotAString

@ -1,7 +1,33 @@
Recommended.Proto3.FieldMaskNumbersDontRoundTrip.JsonOutput
Recommended.Proto3.FieldMaskPathsDontRoundTrip.JsonOutput
Recommended.Proto3.FieldMaskTooManyUnderscore.JsonOutput
Recommended.Proto2.JsonInput.BoolFieldAllCapitalFalse
Recommended.Proto2.JsonInput.BoolFieldAllCapitalTrue
Recommended.Proto2.JsonInput.BoolFieldCamelCaseFalse
Recommended.Proto2.JsonInput.BoolFieldCamelCaseTrue
Recommended.Proto2.JsonInput.BoolFieldDoubleQuotedFalse
Recommended.Proto2.JsonInput.BoolFieldDoubleQuotedTrue
Recommended.Proto2.JsonInput.BoolMapFieldKeyNotQuoted
Recommended.Proto2.JsonInput.DoubleFieldInfinityNotQuoted
Recommended.Proto2.JsonInput.DoubleFieldNanNotQuoted
Recommended.Proto2.JsonInput.DoubleFieldNegativeInfinityNotQuoted
Recommended.Proto2.JsonInput.FieldNameDuplicate
Recommended.Proto2.JsonInput.FieldNameExtension.Validator
Recommended.Proto2.JsonInput.FieldNameNotQuoted
Recommended.Proto2.JsonInput.FloatFieldInfinityNotQuoted
Recommended.Proto2.JsonInput.FloatFieldNanNotQuoted
Recommended.Proto2.JsonInput.FloatFieldNegativeInfinityNotQuoted
Recommended.Proto2.JsonInput.Int32MapFieldKeyNotQuoted
Recommended.Proto2.JsonInput.Int64MapFieldKeyNotQuoted
Recommended.Proto2.JsonInput.JsonWithComments
Recommended.Proto2.JsonInput.StringFieldSingleQuoteBoth
Recommended.Proto2.JsonInput.StringFieldSingleQuoteKey
Recommended.Proto2.JsonInput.StringFieldSingleQuoteValue
Recommended.Proto2.JsonInput.StringFieldSurrogateInWrongOrder
Recommended.Proto2.JsonInput.StringFieldUnpairedHighSurrogate
Recommended.Proto2.JsonInput.StringFieldUnpairedLowSurrogate
Recommended.Proto2.JsonInput.Uint32MapFieldKeyNotQuoted
Recommended.Proto2.JsonInput.Uint64MapFieldKeyNotQuoted
Recommended.Proto3.JsonInput.BoolFieldAllCapitalFalse
Recommended.Proto3.JsonInput.BoolFieldAllCapitalTrue
Recommended.Proto3.JsonInput.BoolFieldCamelCaseFalse
@ -29,6 +55,13 @@ Recommended.Proto3.JsonInput.StringFieldUnpairedHighSurrogate
Recommended.Proto3.JsonInput.StringFieldUnpairedLowSurrogate
Recommended.Proto3.JsonInput.Uint32MapFieldKeyNotQuoted
Recommended.Proto3.JsonInput.Uint64MapFieldKeyNotQuoted
Required.Proto2.JsonInput.EnumFieldNotQuoted
Required.Proto2.JsonInput.Int32FieldLeadingZero
Required.Proto2.JsonInput.Int32FieldNegativeWithLeadingZero
Required.Proto2.JsonInput.Int32FieldPlusSign
Required.Proto2.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool
Required.Proto2.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
Required.Proto2.JsonInput.StringFieldNotAString
Required.Proto3.JsonInput.EnumFieldNotQuoted
Required.Proto3.JsonInput.Int32FieldLeadingZero
Required.Proto3.JsonInput.Int32FieldNegativeWithLeadingZero

@ -1,2 +0,0 @@
Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput
Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.ProtobufOutput

@ -1,4 +1,8 @@
Recommended.Proto2.JsonInput.FieldNameExtension.Validator
Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput
Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.ProtobufOutput
Required.Proto2.JsonInput.BoolFieldFalse.JsonOutput
Required.Proto2.JsonInput.BoolFieldFalse.ProtobufOutput
Required.Proto2.JsonInput.EnumField.JsonOutput
Required.Proto2.JsonInput.EnumField.ProtobufOutput
Required.Proto2.JsonInput.EnumFieldNumericValueZero.JsonOutput
Required.Proto2.JsonInput.EnumFieldNumericValueZero.ProtobufOutput
Required.Proto2.JsonInput.StoresDefaultPrimitive.Validator

@ -4,3 +4,9 @@ Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.Protobu
Recommended.Editions_Proto3.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput
Recommended.Editions_Proto3.JsonInput.IgnoreUnknownEnumStringValueInOptionalField.ProtobufOutput
Recommended.Editions_Proto3.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.ProtobufOutput
Recommended.Editions_Proto2.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput
Recommended.Editions_Proto2.JsonInput.IgnoreUnknownEnumStringValueInOptionalField.ProtobufOutput
Recommended.Editions_Proto2.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.ProtobufOutput
Recommended.Proto2.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput
Recommended.Proto2.JsonInput.IgnoreUnknownEnumStringValueInOptionalField.ProtobufOutput
Recommended.Proto2.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.ProtobufOutput

@ -12,3 +12,9 @@ Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.Protobu
Recommended.Editions_Proto3.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput
Recommended.Editions_Proto3.JsonInput.IgnoreUnknownEnumStringValueInOptionalField.ProtobufOutput
Recommended.Editions_Proto3.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.ProtobufOutput
Recommended.Editions_Proto2.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput
Recommended.Editions_Proto2.JsonInput.IgnoreUnknownEnumStringValueInOptionalField.ProtobufOutput
Recommended.Editions_Proto2.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.ProtobufOutput
Recommended.Proto2.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput
Recommended.Proto2.JsonInput.IgnoreUnknownEnumStringValueInOptionalField.ProtobufOutput
Recommended.Proto2.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.ProtobufOutput

@ -4,3 +4,9 @@ Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.Protobu
Recommended.Editions_Proto3.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput
Recommended.Editions_Proto3.JsonInput.IgnoreUnknownEnumStringValueInOptionalField.ProtobufOutput
Recommended.Editions_Proto3.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.ProtobufOutput
Recommended.Proto2.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput
Recommended.Proto2.JsonInput.IgnoreUnknownEnumStringValueInOptionalField.ProtobufOutput
Recommended.Proto2.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.ProtobufOutput
Recommended.Editions_Proto2.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput
Recommended.Editions_Proto2.JsonInput.IgnoreUnknownEnumStringValueInOptionalField.ProtobufOutput
Recommended.Editions_Proto2.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.ProtobufOutput

@ -1,2 +0,0 @@
Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput
Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.ProtobufOutput

@ -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 + "}";

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<!-- If you update this, update the .csproj in the Docker file as well -->
<PropertyGroup>
@ -23,6 +23,9 @@
<!-- Include PDB in the built .nupkg -->
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
<IsTrimmable>true</IsTrimmable>
<!-- Disable warnings about AOT and trimming features on older targets, e.g. netstandard2.0.
For now, continue to apply these features to these targets because some packages don't have a target that supports them -->
<NoWarn>$(NoWarn);NETSDK1195;NETSDK1210</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">

File diff suppressed because it is too large Load Diff

@ -99,7 +99,7 @@ namespace Google.Protobuf.Reflection {
"ASgJEhMKC291dHB1dF90eXBlGAMgASgJEi8KB29wdGlvbnMYBCABKAsyHi5n",
"b29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucxIfChBjbGllbnRfc3RyZWFt",
"aW5nGAUgASgIOgVmYWxzZRIfChBzZXJ2ZXJfc3RyZWFtaW5nGAYgASgIOgVm",
"YWxzZSLUBgoLRmlsZU9wdGlvbnMSFAoMamF2YV9wYWNrYWdlGAEgASgJEhwK",
"YWxzZSK1BgoLRmlsZU9wdGlvbnMSFAoMamF2YV9wYWNrYWdlGAEgASgJEhwK",
"FGphdmFfb3V0ZXJfY2xhc3NuYW1lGAggASgJEiIKE2phdmFfbXVsdGlwbGVf",
"ZmlsZXMYCiABKAg6BWZhbHNlEikKHWphdmFfZ2VuZXJhdGVfZXF1YWxzX2Fu",
"ZF9oYXNoGBQgASgIQgIYARIlChZqYXZhX3N0cmluZ19jaGVja191dGY4GBsg",
@ -107,136 +107,136 @@ namespace Google.Protobuf.Reflection {
"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",
"cHRpb24qCQjoBxCAgICAAiKqAQoOU2VydmljZU9wdGlvbnMSLQoIZmVhdHVy",
"ZXMYIiABKAsyGy5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldBIZCgpkZXBy",
"ZWNhdGVkGCEgASgIOgVmYWxzZRJDChR1bmludGVycHJldGVkX29wdGlvbhjn",
"ByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbioJ",
"COgHEICAgIACItwCCg1NZXRob2RPcHRpb25zEhkKCmRlcHJlY2F0ZWQYISAB",
"KAg6BWZhbHNlEl8KEWlkZW1wb3RlbmN5X2xldmVsGCIgASgOMi8uZ29vZ2xl",
"LnByb3RvYnVmLk1ldGhvZE9wdGlvbnMuSWRlbXBvdGVuY3lMZXZlbDoTSURF",
"TVBPVEVOQ1lfVU5LTk9XThItCghmZWF0dXJlcxgjIAEoCzIbLmdvb2dsZS5w",
"cHlfZ2VuZXJpY19zZXJ2aWNlcxgSIAEoCDoFZmFsc2USGQoKZGVwcmVjYXRl",
"ZBgXIAEoCDoFZmFsc2USHgoQY2NfZW5hYmxlX2FyZW5hcxgfIAEoCDoEdHJ1",
"ZRIZChFvYmpjX2NsYXNzX3ByZWZpeBgkIAEoCRIYChBjc2hhcnBfbmFtZXNw",
"YWNlGCUgASgJEhQKDHN3aWZ0X3ByZWZpeBgnIAEoCRIYChBwaHBfY2xhc3Nf",
"cHJlZml4GCggASgJEhUKDXBocF9uYW1lc3BhY2UYKSABKAkSHgoWcGhwX21l",
"dGFkYXRhX25hbWVzcGFjZRgsIAEoCRIUCgxydWJ5X3BhY2thZ2UYLSABKAkS",
"LQoIZmVhdHVyZXMYMiABKAsyGy5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNl",
"dBJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJv",
"dG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiI6CgxPcHRpbWl6ZU1vZGUSCQoF",
"U1BFRUQQARINCglDT0RFX1NJWkUQAhIQCgxMSVRFX1JVTlRJTUUQAyoJCOgH",
"EICAgIACSgQIKhArSgQIJhAnIucCCg5NZXNzYWdlT3B0aW9ucxImChdtZXNz",
"YWdlX3NldF93aXJlX2Zvcm1hdBgBIAEoCDoFZmFsc2USLgofbm9fc3RhbmRh",
"cmRfZGVzY3JpcHRvcl9hY2Nlc3NvchgCIAEoCDoFZmFsc2USGQoKZGVwcmVj",
"YXRlZBgDIAEoCDoFZmFsc2USEQoJbWFwX2VudHJ5GAcgASgIEjIKJmRlcHJl",
"Y2F0ZWRfbGVnYWN5X2pzb25fZmllbGRfY29uZmxpY3RzGAsgASgIQgIYARIt",
"CghmZWF0dXJlcxgMIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0",
"EkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90",
"b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAJKBAgEEAVKBAgF",
"EAZKBAgGEAdKBAgIEAlKBAgJEAoijQkKDEZpZWxkT3B0aW9ucxI6CgVjdHlw",
"ZRgBIAEoDjIjLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuQ1R5cGU6",
"BlNUUklORxIOCgZwYWNrZWQYAiABKAgSPwoGanN0eXBlGAYgASgOMiQuZ29v",
"Z2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5KU1R5cGU6CUpTX05PUk1BTBIT",
"CgRsYXp5GAUgASgIOgVmYWxzZRIeCg91bnZlcmlmaWVkX2xhenkYDyABKAg6",
"BWZhbHNlEhkKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNlEhMKBHdlYWsYCiAB",
"KAg6BWZhbHNlEhsKDGRlYnVnX3JlZGFjdBgQIAEoCDoFZmFsc2USQAoJcmV0",
"ZW50aW9uGBEgASgOMi0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5P",
"cHRpb25SZXRlbnRpb24SPwoHdGFyZ2V0cxgTIAMoDjIuLmdvb2dsZS5wcm90",
"b2J1Zi5GaWVsZE9wdGlvbnMuT3B0aW9uVGFyZ2V0VHlwZRJGChBlZGl0aW9u",
"X2RlZmF1bHRzGBQgAygLMiwuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9u",
"cy5FZGl0aW9uRGVmYXVsdBItCghmZWF0dXJlcxgVIAEoCzIbLmdvb2dsZS5w",
"cm90b2J1Zi5GZWF0dXJlU2V0EkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcH",
"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"));
"IAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uGkoK",
"DkVkaXRpb25EZWZhdWx0EikKB2VkaXRpb24YAyABKA4yGC5nb29nbGUucHJv",
"dG9idWYuRWRpdGlvbhINCgV2YWx1ZRgCIAEoCSIvCgVDVHlwZRIKCgZTVFJJ",
"TkcQABIICgRDT1JEEAESEAoMU1RSSU5HX1BJRUNFEAIiNQoGSlNUeXBlEg0K",
"CUpTX05PUk1BTBAAEg0KCUpTX1NUUklORxABEg0KCUpTX05VTUJFUhACIlUK",
"D09wdGlvblJldGVudGlvbhIVChFSRVRFTlRJT05fVU5LTk9XThAAEhUKEVJF",
"VEVOVElPTl9SVU5USU1FEAESFAoQUkVURU5USU9OX1NPVVJDRRACIowCChBP",
"cHRpb25UYXJnZXRUeXBlEhcKE1RBUkdFVF9UWVBFX1VOS05PV04QABIUChBU",
"QVJHRVRfVFlQRV9GSUxFEAESHwobVEFSR0VUX1RZUEVfRVhURU5TSU9OX1JB",
"TkdFEAISFwoTVEFSR0VUX1RZUEVfTUVTU0FHRRADEhUKEVRBUkdFVF9UWVBF",
"X0ZJRUxEEAQSFQoRVEFSR0VUX1RZUEVfT05FT0YQBRIUChBUQVJHRVRfVFlQ",
"RV9FTlVNEAYSGgoWVEFSR0VUX1RZUEVfRU5VTV9FTlRSWRAHEhcKE1RBUkdF",
"VF9UWVBFX1NFUlZJQ0UQCBIWChJUQVJHRVRfVFlQRV9NRVRIT0QQCSoJCOgH",
"EICAgIACSgQIBBAFSgQIEhATIo0BCgxPbmVvZk9wdGlvbnMSLQoIZmVhdHVy",
"ZXMYASABKAsyGy5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldBJDChR1bmlu",
"dGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5p",
"bnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACIvYBCgtFbnVtT3B0aW9ucxIT",
"CgthbGxvd19hbGlhcxgCIAEoCBIZCgpkZXByZWNhdGVkGAMgASgIOgVmYWxz",
"ZRIyCiZkZXByZWNhdGVkX2xlZ2FjeV9qc29uX2ZpZWxkX2NvbmZsaWN0cxgG",
"IAEoCEICGAESLQoIZmVhdHVyZXMYByABKAsyGy5nb29nbGUucHJvdG9idWYu",
"RmVhdHVyZVNldBJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5n",
"b29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIAC",
"SgQIBRAGIskBChBFbnVtVmFsdWVPcHRpb25zEhkKCmRlcHJlY2F0ZWQYASAB",
"KAg6BWZhbHNlEi0KCGZlYXR1cmVzGAIgASgLMhsuZ29vZ2xlLnByb3RvYnVm",
"LkZlYXR1cmVTZXQSGwoMZGVidWdfcmVkYWN0GAMgASgIOgVmYWxzZRJDChR1",
"bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYu",
"VW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACIqoBCg5TZXJ2aWNlT3B0",
"aW9ucxItCghmZWF0dXJlcxgiIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0",
"dXJlU2V0EhkKCmRlcHJlY2F0ZWQYISABKAg6BWZhbHNlEkMKFHVuaW50ZXJw",
"cmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVy",
"cHJldGVkT3B0aW9uKgkI6AcQgICAgAIi3AIKDU1ldGhvZE9wdGlvbnMSGQoK",
"ZGVwcmVjYXRlZBghIAEoCDoFZmFsc2USXwoRaWRlbXBvdGVuY3lfbGV2ZWwY",
"IiABKA4yLy5nb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucy5JZGVtcG90",
"ZW5jeUxldmVsOhNJREVNUE9URU5DWV9VTktOT1dOEi0KCGZlYXR1cmVzGCMg",
"ASgLMhsuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXQSQwoUdW5pbnRlcnBy",
"ZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJw",
"cmV0ZWRPcHRpb24iUAoQSWRlbXBvdGVuY3lMZXZlbBIXChNJREVNUE9URU5D",
"WV9VTktOT1dOEAASEwoPTk9fU0lERV9FRkZFQ1RTEAESDgoKSURFTVBPVEVO",
"VBACKgkI6AcQgICAgAIingIKE1VuaW50ZXJwcmV0ZWRPcHRpb24SOwoEbmFt",
"ZRgCIAMoCzItLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9u",
"Lk5hbWVQYXJ0EhgKEGlkZW50aWZpZXJfdmFsdWUYAyABKAkSGgoScG9zaXRp",
"dmVfaW50X3ZhbHVlGAQgASgEEhoKEm5lZ2F0aXZlX2ludF92YWx1ZRgFIAEo",
"AxIUCgxkb3VibGVfdmFsdWUYBiABKAESFAoMc3RyaW5nX3ZhbHVlGAcgASgM",
"EhcKD2FnZ3JlZ2F0ZV92YWx1ZRgIIAEoCRozCghOYW1lUGFydBIRCgluYW1l",
"X3BhcnQYASACKAkSFAoMaXNfZXh0ZW5zaW9uGAIgAigIIp0JCgpGZWF0dXJl",
"U2V0EnwKDmZpZWxkX3ByZXNlbmNlGAEgASgOMikuZ29vZ2xlLnByb3RvYnVm",
"LkZlYXR1cmVTZXQuRmllbGRQcmVzZW5jZUI5iAEBmAEEmAEBogENEghFWFBM",
"SUNJVBjmB6IBDRIISU1QTElDSVQY5weiAQ0SCEVYUExJQ0lUGOgHElwKCWVu",
"dW1fdHlwZRgCIAEoDjIkLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0LkVu",
"dW1UeXBlQiOIAQGYAQaYAQGiAQsSBkNMT1NFRBjmB6IBCRIET1BFThjnBxJ7",
"ChdyZXBlYXRlZF9maWVsZF9lbmNvZGluZxgDIAEoDjIxLmdvb2dsZS5wcm90",
"b2J1Zi5GZWF0dXJlU2V0LlJlcGVhdGVkRmllbGRFbmNvZGluZ0IniAEBmAEE",
"mAEBogENEghFWFBBTkRFRBjmB6IBCxIGUEFDS0VEGOcHEmgKD3V0ZjhfdmFs",
"aWRhdGlvbhgEIAEoDjIqLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0LlV0",
"ZjhWYWxpZGF0aW9uQiOIAQGYAQSYAQGiAQkSBE5PTkUY5geiAQsSBlZFUklG",
"WRjnBxJnChBtZXNzYWdlX2VuY29kaW5nGAUgASgOMisuZ29vZ2xlLnByb3Rv",
"YnVmLkZlYXR1cmVTZXQuTWVzc2FnZUVuY29kaW5nQiCIAQGYAQSYAQGiARQS",
"D0xFTkdUSF9QUkVGSVhFRBjmBxJwCgtqc29uX2Zvcm1hdBgGIAEoDjImLmdv",
"b2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0Lkpzb25Gb3JtYXRCM4gBAZgBA5gB",
"BpgBAaIBFxISTEVHQUNZX0JFU1RfRUZGT1JUGOYHogEKEgVBTExPVxjnByJc",
"Cg1GaWVsZFByZXNlbmNlEhoKFkZJRUxEX1BSRVNFTkNFX1VOS05PV04QABIM",
"CghFWFBMSUNJVBABEgwKCElNUExJQ0lUEAISEwoPTEVHQUNZX1JFUVVJUkVE",
"EAMiNwoIRW51bVR5cGUSFQoRRU5VTV9UWVBFX1VOS05PV04QABIICgRPUEVO",
"EAESCgoGQ0xPU0VEEAIiVgoVUmVwZWF0ZWRGaWVsZEVuY29kaW5nEiMKH1JF",
"UEVBVEVEX0ZJRUxEX0VOQ09ESU5HX1VOS05PV04QABIKCgZQQUNLRUQQARIM",
"CghFWFBBTkRFRBACIkMKDlV0ZjhWYWxpZGF0aW9uEhsKF1VURjhfVkFMSURB",
"VElPTl9VTktOT1dOEAASCgoGVkVSSUZZEAISCAoETk9ORRADIlMKD01lc3Nh",
"Z2VFbmNvZGluZxIcChhNRVNTQUdFX0VOQ09ESU5HX1VOS05PV04QABITCg9M",
"RU5HVEhfUFJFRklYRUQQARINCglERUxJTUlURUQQAiJICgpKc29uRm9ybWF0",
"EhcKE0pTT05fRk9STUFUX1VOS05PV04QABIJCgVBTExPVxABEhYKEkxFR0FD",
"WV9CRVNUX0VGRk9SVBACKgYI6AcQ6QcqBgjpBxDqByoGCItOEJBOSgYI5wcQ",
"6AciwAIKEkZlYXR1cmVTZXREZWZhdWx0cxJOCghkZWZhdWx0cxgBIAMoCzI8",
"Lmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0RGVmYXVsdHMuRmVhdHVyZVNl",
"dEVkaXRpb25EZWZhdWx0EjEKD21pbmltdW1fZWRpdGlvbhgEIAEoDjIYLmdv",
"b2dsZS5wcm90b2J1Zi5FZGl0aW9uEjEKD21heGltdW1fZWRpdGlvbhgFIAEo",
"DjIYLmdvb2dsZS5wcm90b2J1Zi5FZGl0aW9uGnQKGEZlYXR1cmVTZXRFZGl0",
"aW9uRGVmYXVsdBIpCgdlZGl0aW9uGAMgASgOMhguZ29vZ2xlLnByb3RvYnVm",
"LkVkaXRpb24SLQoIZmVhdHVyZXMYAiABKAsyGy5nb29nbGUucHJvdG9idWYu",
"RmVhdHVyZVNldCLVAQoOU291cmNlQ29kZUluZm8SOgoIbG9jYXRpb24YASAD",
"KAsyKC5nb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24a",
"hgEKCExvY2F0aW9uEhAKBHBhdGgYASADKAVCAhABEhAKBHNwYW4YAiADKAVC",
"AhABEhgKEGxlYWRpbmdfY29tbWVudHMYAyABKAkSGQoRdHJhaWxpbmdfY29t",
"bWVudHMYBCABKAkSIQoZbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cxgGIAMo",
"CSKcAgoRR2VuZXJhdGVkQ29kZUluZm8SQQoKYW5ub3RhdGlvbhgBIAMoCzIt",
"Lmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9u",
"GsMBCgpBbm5vdGF0aW9uEhAKBHBhdGgYASADKAVCAhABEhMKC3NvdXJjZV9m",
"aWxlGAIgASgJEg0KBWJlZ2luGAMgASgFEgsKA2VuZBgEIAEoBRJICghzZW1h",
"bnRpYxgFIAEoDjI2Lmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5m",
"by5Bbm5vdGF0aW9uLlNlbWFudGljIigKCFNlbWFudGljEggKBE5PTkUQABIH",
"CgNTRVQQARIJCgVBTElBUxACKpICCgdFZGl0aW9uEhMKD0VESVRJT05fVU5L",
"Tk9XThAAEhMKDkVESVRJT05fUFJPVE8yEOYHEhMKDkVESVRJT05fUFJPVE8z",
"EOcHEhEKDEVESVRJT05fMjAyMxDoBxIRCgxFRElUSU9OXzIwMjQQ6QcSFwoT",
"RURJVElPTl8xX1RFU1RfT05MWRABEhcKE0VESVRJT05fMl9URVNUX09OTFkQ",
"AhIdChdFRElUSU9OXzk5OTk3X1RFU1RfT05MWRCdjQYSHQoXRURJVElPTl85",
"OTk5OF9URVNUX09OTFkQno0GEh0KF0VESVRJT05fOTk5OTlfVEVTVF9PTkxZ",
"EJ+NBhITCgtFRElUSU9OX01BWBD/////B0J+ChNjb20uZ29vZ2xlLnByb3Rv",
"YnVmQhBEZXNjcmlwdG9yUHJvdG9zSAFaLWdvb2dsZS5nb2xhbmcub3JnL3By",
"b3RvYnVmL3R5cGVzL2Rlc2NyaXB0b3JwYvgBAaICA0dQQqoCGkdvb2dsZS5Q",
"cm90b2J1Zi5SZWZsZWN0aW9u"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.Reflection.Edition), }, null, new pbr::GeneratedClrTypeInfo[] {
@ -251,7 +251,7 @@ namespace Google.Protobuf.Reflection {
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumValueDescriptorProto), global::Google.Protobuf.Reflection.EnumValueDescriptorProto.Parser, new[]{ "Name", "Number", "Options" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.ServiceDescriptorProto), global::Google.Protobuf.Reflection.ServiceDescriptorProto.Parser, new[]{ "Name", "Method", "Options" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MethodDescriptorProto), global::Google.Protobuf.Reflection.MethodDescriptorProto.Parser, new[]{ "Name", "InputType", "OutputType", "Options", "ClientStreaming", "ServerStreaming" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileOptions), global::Google.Protobuf.Reflection.FileOptions.Parser, new[]{ "JavaPackage", "JavaOuterClassname", "JavaMultipleFiles", "JavaGenerateEqualsAndHash", "JavaStringCheckUtf8", "OptimizeFor", "GoPackage", "CcGenericServices", "JavaGenericServices", "PyGenericServices", "PhpGenericServices", "Deprecated", "CcEnableArenas", "ObjcClassPrefix", "CsharpNamespace", "SwiftPrefix", "PhpClassPrefix", "PhpNamespace", "PhpMetadataNamespace", "RubyPackage", "Features", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode) }, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileOptions), global::Google.Protobuf.Reflection.FileOptions.Parser, new[]{ "JavaPackage", "JavaOuterClassname", "JavaMultipleFiles", "JavaGenerateEqualsAndHash", "JavaStringCheckUtf8", "OptimizeFor", "GoPackage", "CcGenericServices", "JavaGenericServices", "PyGenericServices", "Deprecated", "CcEnableArenas", "ObjcClassPrefix", "CsharpNamespace", "SwiftPrefix", "PhpClassPrefix", "PhpNamespace", "PhpMetadataNamespace", "RubyPackage", "Features", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode) }, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MessageOptions), global::Google.Protobuf.Reflection.MessageOptions.Parser, new[]{ "MessageSetWireFormat", "NoStandardDescriptorAccessor", "Deprecated", "MapEntry", "DeprecatedLegacyJsonFieldConflicts", "Features", "UninterpretedOption" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FieldOptions), global::Google.Protobuf.Reflection.FieldOptions.Parser, new[]{ "Ctype", "Packed", "Jstype", "Lazy", "UnverifiedLazy", "Deprecated", "Weak", "DebugRedact", "Retention", "Targets", "EditionDefaults", "Features", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.CType), typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.JSType), typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.OptionRetention), typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.OptionTargetType) }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.EditionDefault), global::Google.Protobuf.Reflection.FieldOptions.Types.EditionDefault.Parser, new[]{ "Edition", "Value" }, null, null, null, null)}),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.OneofOptions), global::Google.Protobuf.Reflection.OneofOptions.Parser, new[]{ "Features", "UninterpretedOption" }, null, null, null, null),
@ -292,6 +292,7 @@ namespace Google.Protobuf.Reflection {
/// comparison.
/// </summary>
[pbr::OriginalName("EDITION_2023")] _2023 = 1000,
[pbr::OriginalName("EDITION_2024")] _2024 = 1001,
/// <summary>
/// Placeholder editions for testing feature resolution. These should not be
/// used or relyed on outside of tests.
@ -5870,7 +5871,6 @@ namespace Google.Protobuf.Reflection {
ccGenericServices_ = other.ccGenericServices_;
javaGenericServices_ = other.javaGenericServices_;
pyGenericServices_ = other.pyGenericServices_;
phpGenericServices_ = other.phpGenericServices_;
deprecated_ = other.deprecated_;
ccEnableArenas_ = other.ccEnableArenas_;
objcClassPrefix_ = other.objcClassPrefix_;
@ -6213,33 +6213,6 @@ namespace Google.Protobuf.Reflection {
_hasBits0 &= ~16;
}
/// <summary>Field number for the "php_generic_services" field.</summary>
public const int PhpGenericServicesFieldNumber = 42;
private readonly static bool PhpGenericServicesDefaultValue = false;
private bool phpGenericServices_;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public bool PhpGenericServices {
get { if ((_hasBits0 & 512) != 0) { return phpGenericServices_; } else { return PhpGenericServicesDefaultValue; } }
set {
_hasBits0 |= 512;
phpGenericServices_ = value;
}
}
/// <summary>Gets whether the "php_generic_services" field is set</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public bool HasPhpGenericServices {
get { return (_hasBits0 & 512) != 0; }
}
/// <summary>Clears the value of the "php_generic_services" field</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public void ClearPhpGenericServices() {
_hasBits0 &= ~512;
}
/// <summary>Field number for the "deprecated" field.</summary>
public const int DeprecatedFieldNumber = 23;
private readonly static bool DeprecatedDefaultValue = false;
@ -6573,7 +6546,6 @@ namespace Google.Protobuf.Reflection {
if (CcGenericServices != other.CcGenericServices) return false;
if (JavaGenericServices != other.JavaGenericServices) return false;
if (PyGenericServices != other.PyGenericServices) return false;
if (PhpGenericServices != other.PhpGenericServices) return false;
if (Deprecated != other.Deprecated) return false;
if (CcEnableArenas != other.CcEnableArenas) return false;
if (ObjcClassPrefix != other.ObjcClassPrefix) return false;
@ -6605,7 +6577,6 @@ namespace Google.Protobuf.Reflection {
if (HasCcGenericServices) hash ^= CcGenericServices.GetHashCode();
if (HasJavaGenericServices) hash ^= JavaGenericServices.GetHashCode();
if (HasPyGenericServices) hash ^= PyGenericServices.GetHashCode();
if (HasPhpGenericServices) hash ^= PhpGenericServices.GetHashCode();
if (HasDeprecated) hash ^= Deprecated.GetHashCode();
if (HasCcEnableArenas) hash ^= CcEnableArenas.GetHashCode();
if (HasObjcClassPrefix) hash ^= ObjcClassPrefix.GetHashCode();
@ -6706,10 +6677,6 @@ namespace Google.Protobuf.Reflection {
output.WriteRawTag(202, 2);
output.WriteString(PhpNamespace);
}
if (HasPhpGenericServices) {
output.WriteRawTag(208, 2);
output.WriteBool(PhpGenericServices);
}
if (HasPhpMetadataNamespace) {
output.WriteRawTag(226, 2);
output.WriteString(PhpMetadataNamespace);
@ -6804,10 +6771,6 @@ namespace Google.Protobuf.Reflection {
output.WriteRawTag(202, 2);
output.WriteString(PhpNamespace);
}
if (HasPhpGenericServices) {
output.WriteRawTag(208, 2);
output.WriteBool(PhpGenericServices);
}
if (HasPhpMetadataNamespace) {
output.WriteRawTag(226, 2);
output.WriteString(PhpMetadataNamespace);
@ -6864,9 +6827,6 @@ namespace Google.Protobuf.Reflection {
if (HasPyGenericServices) {
size += 2 + 1;
}
if (HasPhpGenericServices) {
size += 2 + 1;
}
if (HasDeprecated) {
size += 2 + 1;
}
@ -6943,9 +6903,6 @@ namespace Google.Protobuf.Reflection {
if (other.HasPyGenericServices) {
PyGenericServices = other.PyGenericServices;
}
if (other.HasPhpGenericServices) {
PhpGenericServices = other.PhpGenericServices;
}
if (other.HasDeprecated) {
Deprecated = other.Deprecated;
}
@ -7066,10 +7023,6 @@ namespace Google.Protobuf.Reflection {
PhpNamespace = input.ReadString();
break;
}
case 336: {
PhpGenericServices = input.ReadBool();
break;
}
case 354: {
PhpMetadataNamespace = input.ReadString();
break;
@ -7174,10 +7127,6 @@ namespace Google.Protobuf.Reflection {
PhpNamespace = input.ReadString();
break;
}
case 336: {
PhpGenericServices = input.ReadBool();
break;
}
case 354: {
PhpMetadataNamespace = input.ReadString();
break;
@ -7426,10 +7375,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.
///
@ -7447,6 +7392,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)]
@ -8055,19 +8004,11 @@ namespace Google.Protobuf.Reflection {
/// call from multiple threads concurrently, while non-const methods continue
/// to require exclusive access.
///
/// Note that implementations may choose not to check required fields within
/// a lazy sub-message. That is, calling IsInitialized() on the outer message
/// may return true even if the inner message has missing required fields.
/// This is necessary because otherwise the inner message would have to be
/// parsed in order to perform the check, defeating the purpose of lazy
/// parsing. An implementation which chooses not to check required fields
/// must be consistent about it. That is, for any particular sub-message, the
/// implementation must either *always* check its required fields, or *never*
/// check its required fields, regardless of whether or not the message has
/// been parsed.
///
/// As of May 2022, lazy verifies the contents of the byte stream during
/// parsing. An invalid byte stream will cause the overall parsing to fail.
/// Note that lazy message fields are still eagerly verified to check
/// ill-formed wireformat or missing required fields. Calling IsInitialized()
/// on the outer message would fail if the inner message has missing required
/// fields. Failed verification would result in parsing failure (except when
/// uninitialized messages are acceptable).
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
@ -13139,7 +13080,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:

@ -13,378 +13,363 @@ using System.Reflection;
using System.Runtime.CompilerServices;
using Google.Protobuf.Compatibility;
namespace Google.Protobuf.Reflection
{
namespace Google.Protobuf.Reflection {
/// <summary>
/// The methods in this class are somewhat evil, and should not be tampered with lightly.
/// Basically they allow the creation of relatively weakly typed delegates from MethodInfos
/// which are more strongly typed. They do this by creating an appropriate strongly typed
/// delegate from the MethodInfo, and then calling that within an anonymous method.
/// Mind-bending stuff (at least to your humble narrator) but the resulting delegates are
/// very fast compared with calling Invoke later on.
/// </summary>
internal static class ReflectionUtil {
static ReflectionUtil() {
ForceInitialize<string>(); // Handles all reference types
ForceInitialize<int>();
ForceInitialize<long>();
ForceInitialize<uint>();
ForceInitialize<ulong>();
ForceInitialize<float>();
ForceInitialize<double>();
ForceInitialize<bool>();
ForceInitialize < int ? > ();
ForceInitialize < long ? > ();
ForceInitialize < uint ? > ();
ForceInitialize < ulong ? > ();
ForceInitialize < float ? > ();
ForceInitialize < double ? > ();
ForceInitialize < bool ? > ();
ForceInitialize<SampleEnum>();
SampleEnumMethod();
}
internal static void ForceInitialize<T>() => new ReflectionHelper<IMessage, T>();
/// <summary>
/// The methods in this class are somewhat evil, and should not be tampered with lightly.
/// Basically they allow the creation of relatively weakly typed delegates from MethodInfos
/// which are more strongly typed. They do this by creating an appropriate strongly typed
/// delegate from the MethodInfo, and then calling that within an anonymous method.
/// Mind-bending stuff (at least to your humble narrator) but the resulting delegates are
/// very fast compared with calling Invoke later on.
/// Empty Type[] used when calling GetProperty to force property instead of indexer fetching.
/// </summary>
internal static class ReflectionUtil
{
static ReflectionUtil()
{
ForceInitialize<string>(); // Handles all reference types
ForceInitialize<int>();
ForceInitialize<long>();
ForceInitialize<uint>();
ForceInitialize<ulong>();
ForceInitialize<float>();
ForceInitialize<double>();
ForceInitialize<bool>();
ForceInitialize<int?>();
ForceInitialize<long?>();
ForceInitialize<uint?>();
ForceInitialize<ulong?>();
ForceInitialize<float?>();
ForceInitialize<double?>();
ForceInitialize<bool?>();
ForceInitialize<SampleEnum>();
SampleEnumMethod();
}
internal static readonly Type[] EmptyTypes = new Type[0];
/// <summary>
/// Creates a delegate which will cast the argument to the type that declares the method,
/// call the method on it, then convert the result to object.
/// </summary>
/// <param name="method">The method to create a delegate for, which must be declared in an
/// IMessage implementation.</param>
internal static Func<IMessage, object> CreateFuncIMessageObject(MethodInfo method) =>
GetReflectionHelper(method.DeclaringType, method.ReturnType)
.CreateFuncIMessageObject(method);
/// <summary>
/// Creates a delegate which will cast the argument to the type that declares the method,
/// call the method on it, then convert the result to the specified type. The method is expected
/// to actually return an enum (because of where we're calling it - for oneof cases). Sometimes
/// that means we need some extra work to perform conversions.
/// </summary>
/// <param name="method">The method to create a delegate for, which must be declared in an
/// IMessage implementation.</param>
internal static Func<IMessage, int> CreateFuncIMessageInt32(MethodInfo method) =>
GetReflectionHelper(method.DeclaringType, method.ReturnType)
.CreateFuncIMessageInt32(method);
/// <summary>
/// Creates a delegate which will execute the given method after casting the first argument to
/// the type that declares the method, and the second argument to the first parameter type of
/// the method.
/// </summary>
/// <param name="method">The method to create a delegate for, which must be declared in an
/// IMessage implementation.</param>
internal static Action<IMessage, object> CreateActionIMessageObject(MethodInfo method) =>
GetReflectionHelper(method.DeclaringType, method.GetParameters()[0].ParameterType)
.CreateActionIMessageObject(method);
internal static void ForceInitialize<T>() => new ReflectionHelper<IMessage, T>();
/// <summary>
/// Empty Type[] used when calling GetProperty to force property instead of indexer fetching.
/// </summary>
internal static readonly Type[] EmptyTypes = new Type[0];
/// <summary>
/// Creates a delegate which will cast the argument to the type that declares the method,
/// call the method on it, then convert the result to object.
/// </summary>
/// <param name="method">The method to create a delegate for, which must be declared in an IMessage
/// implementation.</param>
internal static Func<IMessage, object> CreateFuncIMessageObject(MethodInfo method) =>
GetReflectionHelper(method.DeclaringType, method.ReturnType).CreateFuncIMessageObject(method);
/// <summary>
/// Creates a delegate which will cast the argument to the type that declares the method,
/// call the method on it, then convert the result to the specified type. The method is expected
/// to actually return an enum (because of where we're calling it - for oneof cases). Sometimes that
/// means we need some extra work to perform conversions.
/// </summary>
/// <param name="method">The method to create a delegate for, which must be declared in an IMessage
/// implementation.</param>
internal static Func<IMessage, int> CreateFuncIMessageInt32(MethodInfo method) =>
GetReflectionHelper(method.DeclaringType, method.ReturnType).CreateFuncIMessageInt32(method);
/// <summary>
/// Creates a delegate which will execute the given method after casting the first argument to
/// the type that declares the method, and the second argument to the first parameter type of the method.
/// </summary>
/// <param name="method">The method to create a delegate for, which must be declared in an IMessage
/// implementation.</param>
internal static Action<IMessage, object> CreateActionIMessageObject(MethodInfo method) =>
GetReflectionHelper(method.DeclaringType, method.GetParameters()[0].ParameterType).CreateActionIMessageObject(method);
/// <summary>
/// Creates a delegate which will execute the given method after casting the first argument to
/// type that declares the method.
/// </summary>
/// <param name="method">The method to create a delegate for, which must be declared in an IMessage
/// implementation.</param>
internal static Action<IMessage> CreateActionIMessage(MethodInfo method) =>
GetReflectionHelper(method.DeclaringType, typeof(object)).CreateActionIMessage(method);
internal static Func<IMessage, bool> CreateFuncIMessageBool(MethodInfo method) =>
GetReflectionHelper(method.DeclaringType, method.ReturnType).CreateFuncIMessageBool(method);
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Type parameter members are preserved with DynamicallyAccessedMembers on GeneratedClrTypeInfo.ctor clrType parameter.")]
[UnconditionalSuppressMessage("AotAnalysis", "IL3050:RequiresDynamicCode", Justification = "Type definition is explicitly specified and type argument is always a message type.")]
internal static Func<IMessage, bool> CreateIsInitializedCaller([DynamicallyAccessedMembers(GeneratedClrTypeInfo.MessageAccessibility)]Type msg) =>
((IExtensionSetReflector)Activator.CreateInstance(typeof(ExtensionSetReflector<>).MakeGenericType(msg))).CreateIsInitializedCaller();
/// <summary>
/// Creates a delegate which will execute the given method after casting the first argument to
/// the type that declares the method, and the second argument to the first parameter type of the method.
/// </summary>
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Type parameter members are preserved with DynamicallyAccessedMembers on GeneratedClrTypeInfo.ctor clrType parameter.")]
internal static IExtensionReflectionHelper CreateExtensionHelper(Extension extension)
{
/// <summary>
/// Creates a delegate which will execute the given method after casting the first argument to
/// type that declares the method.
/// </summary>
/// <param name="method">The method to create a delegate for, which must be declared in an
/// IMessage implementation.</param>
internal static Action<IMessage> CreateActionIMessage(MethodInfo method) =>
GetReflectionHelper(method.DeclaringType, typeof(object)).CreateActionIMessage(method);
internal static Func<IMessage, bool> CreateFuncIMessageBool(MethodInfo method) =>
GetReflectionHelper(method.DeclaringType, method.ReturnType).CreateFuncIMessageBool(method);
[UnconditionalSuppressMessage(
"Trimming", "IL2026",
Justification =
"Type parameter members are preserved with DynamicallyAccessedMembers on GeneratedClrTypeInfo.ctor clrType parameter.")]
[UnconditionalSuppressMessage(
"AotAnalysis", "IL3050:RequiresDynamicCode",
Justification =
"Type definition is explicitly specified and type argument is always a message type.")]
internal static Func<IMessage, bool> CreateIsInitializedCaller([
DynamicallyAccessedMembers(GeneratedClrTypeInfo.MessageAccessibility)
] Type msg) => ((IExtensionSetReflector)Activator
.CreateInstance(typeof(ExtensionSetReflector<>).MakeGenericType(msg)))
.CreateIsInitializedCaller();
/// <summary>
/// Creates a delegate which will execute the given method after casting the first argument to
/// the type that declares the method, and the second argument to the first parameter type of
/// the method.
/// </summary>
[UnconditionalSuppressMessage(
"Trimming", "IL2026",
Justification =
"Type parameter members are preserved with DynamicallyAccessedMembers on GeneratedClrTypeInfo.ctor clrType parameter.")]
[UnconditionalSuppressMessage("AOT", "IL3050",
Justification = "Dynamic code won't call Type.MakeGenericType.")]
internal static IExtensionReflectionHelper CreateExtensionHelper(Extension extension) {
#if NET5_0_OR_GREATER
if (!RuntimeFeature.IsDynamicCodeSupported)
{
// Using extensions with reflection is not supported with AOT.
// This helper is created when descriptors are populated. Delay throwing error until an app
// uses IFieldAccessor with an extension field.
return new AotExtensionReflectionHelper();
}
if (!RuntimeFeature.IsDynamicCodeSupported) {
// Using extensions with reflection is not supported with AOT.
// This helper is created when descriptors are populated. Delay throwing error until an app
// uses IFieldAccessor with an extension field.
return new AotExtensionReflectionHelper();
}
#endif
var t1 = extension.TargetType;
var t3 = extension.GetType().GenericTypeArguments[1];
return (IExtensionReflectionHelper) Activator.CreateInstance(typeof(ExtensionReflectionHelper<,>).MakeGenericType(t1, t3), extension);
}
var t1 = extension.TargetType;
var t3 = extension.GetType().GenericTypeArguments[1];
return (IExtensionReflectionHelper)Activator.CreateInstance(
typeof(ExtensionReflectionHelper<, >).MakeGenericType(t1, t3), extension);
}
/// <summary>
/// Creates a reflection helper for the given type arguments. Currently these are created on demand
/// rather than cached; this will be "busy" when initially loading a message's descriptor, but after that
/// they can be garbage collected. We could cache them by type if that proves to be important, but creating
/// an object is pretty cheap.
/// </summary>
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Type parameter members are preserved with DynamicallyAccessedMembers on GeneratedClrTypeInfo.ctor clrType parameter.")]
private static IReflectionHelper GetReflectionHelper(Type t1, Type t2)
{
/// <summary>
/// Creates a reflection helper for the given type arguments. Currently these are created on
/// demand rather than cached; this will be "busy" when initially loading a message's
/// descriptor, but after that they can be garbage collected. We could cache them by type if
/// that proves to be important, but creating an object is pretty cheap.
/// </summary>
[UnconditionalSuppressMessage(
"Trimming", "IL2026",
Justification =
"Type parameter members are preserved with DynamicallyAccessedMembers on GeneratedClrTypeInfo.ctor clrType parameter.")]
[UnconditionalSuppressMessage("AOT", "IL3050",
Justification = "Dynamic code won't call Type.MakeGenericType.")]
private static IReflectionHelper GetReflectionHelper(Type t1, Type t2) {
#if NET5_0_OR_GREATER
if (!RuntimeFeature.IsDynamicCodeSupported)
{
return new AotReflectionHelper();
}
if (!RuntimeFeature.IsDynamicCodeSupported) {
return new AotReflectionHelper();
}
#endif
return (IReflectionHelper) Activator.CreateInstance(typeof(ReflectionHelper<,>).MakeGenericType(t1, t2));
}
return (IReflectionHelper)Activator.CreateInstance(
typeof(ReflectionHelper<, >).MakeGenericType(t1, t2));
}
// Non-generic interface allowing us to use an instance of ReflectionHelper<T1, T2> without statically
// knowing the types involved.
private interface IReflectionHelper
{
Func<IMessage, int> CreateFuncIMessageInt32(MethodInfo method);
Action<IMessage> CreateActionIMessage(MethodInfo method);
Func<IMessage, object> CreateFuncIMessageObject(MethodInfo method);
Action<IMessage, object> CreateActionIMessageObject(MethodInfo method);
Func<IMessage, bool> CreateFuncIMessageBool(MethodInfo method);
}
// Non-generic interface allowing us to use an instance of ReflectionHelper<T1, T2> without
// statically knowing the types involved.
private interface IReflectionHelper {
Func<IMessage, int> CreateFuncIMessageInt32(MethodInfo method);
Action<IMessage> CreateActionIMessage(MethodInfo method);
Func<IMessage, object> CreateFuncIMessageObject(MethodInfo method);
Action<IMessage, object> CreateActionIMessageObject(MethodInfo method);
Func<IMessage, bool> CreateFuncIMessageBool(MethodInfo method);
}
internal interface IExtensionReflectionHelper {
object GetExtension(IMessage message);
void SetExtension(IMessage message, object value);
bool HasExtension(IMessage message);
void ClearExtension(IMessage message);
}
internal interface IExtensionReflectionHelper
{
object GetExtension(IMessage message);
void SetExtension(IMessage message, object value);
bool HasExtension(IMessage message);
void ClearExtension(IMessage message);
private interface IExtensionSetReflector {
Func<IMessage, bool> CreateIsInitializedCaller();
}
private sealed class ReflectionHelper<T1, T2> : IReflectionHelper {
public Func<IMessage, int> CreateFuncIMessageInt32(MethodInfo method) {
// On pleasant runtimes, we can create a Func<int> from a method returning
// an enum based on an int. That's the fast path.
if (CanConvertEnumFuncToInt32Func) {
var del = (Func<T1, int>)method.CreateDelegate(typeof(Func<T1, int>));
return message => del((T1)message);
} else {
// On some runtimes (e.g. old Mono) the return type has to be exactly correct,
// so we go via boxing. Reflection is already fairly inefficient, and this is
// only used for one-of case checking, fortunately.
var del = (Func<T1, T2>)method.CreateDelegate(typeof(Func<T1, T2>));
return message => (int)(object)del((T1)message);
}
}
public Action<IMessage> CreateActionIMessage(MethodInfo method) {
var del = (Action<T1>)method.CreateDelegate(typeof(Action<T1>));
return message => del((T1)message);
}
public Func<IMessage, object> CreateFuncIMessageObject(MethodInfo method) {
var del = (Func<T1, T2>)method.CreateDelegate(typeof(Func<T1, T2>));
return message => del((T1)message);
}
public Action<IMessage, object> CreateActionIMessageObject(MethodInfo method) {
var del = (Action<T1, T2>)method.CreateDelegate(typeof(Action<T1, T2>));
return (message, arg) => del((T1)message, (T2)arg);
}
public Func<IMessage, bool> CreateFuncIMessageBool(MethodInfo method) {
var del = (Func<T1, bool>)method.CreateDelegate(typeof(Func<T1, bool>));
return message => del((T1)message);
}
}
private sealed class ExtensionReflectionHelper<T1, T3> : IExtensionReflectionHelper
where T1 : IExtendableMessage<T1> {
private readonly Extension extension;
private interface IExtensionSetReflector
{
Func<IMessage, bool> CreateIsInitializedCaller();
public ExtensionReflectionHelper(Extension extension) {
this.extension = extension;
}
public object GetExtension(IMessage message) {
if (message is not T1 extensionMessage) {
throw new InvalidCastException(
"Cannot access extension on message that isn't IExtensionMessage");
}
private sealed class ReflectionHelper<T1, T2> : IReflectionHelper
{
public Func<IMessage, int> CreateFuncIMessageInt32(MethodInfo method)
{
// On pleasant runtimes, we can create a Func<int> from a method returning
// an enum based on an int. That's the fast path.
if (CanConvertEnumFuncToInt32Func)
{
var del = (Func<T1, int>) method.CreateDelegate(typeof(Func<T1, int>));
return message => del((T1) message);
}
else
{
// On some runtimes (e.g. old Mono) the return type has to be exactly correct,
// so we go via boxing. Reflection is already fairly inefficient, and this is
// only used for one-of case checking, fortunately.
var del = (Func<T1, T2>) method.CreateDelegate(typeof(Func<T1, T2>));
return message => (int) (object) del((T1) message);
}
}
public Action<IMessage> CreateActionIMessage(MethodInfo method)
{
var del = (Action<T1>) method.CreateDelegate(typeof(Action<T1>));
return message => del((T1) message);
}
public Func<IMessage, object> CreateFuncIMessageObject(MethodInfo method)
{
var del = (Func<T1, T2>) method.CreateDelegate(typeof(Func<T1, T2>));
return message => del((T1) message);
}
public Action<IMessage, object> CreateActionIMessageObject(MethodInfo method)
{
var del = (Action<T1, T2>) method.CreateDelegate(typeof(Action<T1, T2>));
return (message, arg) => del((T1) message, (T2) arg);
}
public Func<IMessage, bool> CreateFuncIMessageBool(MethodInfo method)
{
var del = (Func<T1, bool>)method.CreateDelegate(typeof(Func<T1, bool>));
return message => del((T1)message);
}
if (extension is Extension<T1, T3> ext13) {
return extensionMessage.GetExtension(ext13);
} else if (extension is RepeatedExtension<T1, T3> repeatedExt13) {
return extensionMessage.GetOrInitializeExtension(repeatedExt13);
} else {
throw new InvalidCastException(
"The provided extension is not a valid extension identifier type");
}
}
private sealed class ExtensionReflectionHelper<T1, T3> : IExtensionReflectionHelper
where T1 : IExtendableMessage<T1>
{
private readonly Extension extension;
public ExtensionReflectionHelper(Extension extension)
{
this.extension = extension;
}
public object GetExtension(IMessage message)
{
if (message is not T1 extensionMessage)
{
throw new InvalidCastException("Cannot access extension on message that isn't IExtensionMessage");
}
if (extension is Extension<T1, T3> ext13)
{
return extensionMessage.GetExtension(ext13);
}
else if (extension is RepeatedExtension<T1, T3> repeatedExt13)
{
return extensionMessage.GetOrInitializeExtension(repeatedExt13);
}
else
{
throw new InvalidCastException("The provided extension is not a valid extension identifier type");
}
}
public bool HasExtension(IMessage message)
{
if (message is not T1 extensionMessage)
{
throw new InvalidCastException("Cannot access extension on message that isn't IExtensionMessage");
}
if (extension is Extension<T1, T3> ext13)
{
return extensionMessage.HasExtension(ext13);
}
else if (extension is RepeatedExtension<T1, T3>)
{
throw new InvalidOperationException("HasValue is not implemented for repeated extensions");
}
else
{
throw new InvalidCastException("The provided extension is not a valid extension identifier type");
}
}
public void SetExtension(IMessage message, object value)
{
if (message is not T1 extensionMessage)
{
throw new InvalidCastException("Cannot access extension on message that isn't IExtensionMessage");
}
if (extension is Extension<T1, T3> ext13)
{
extensionMessage.SetExtension(ext13, (T3)value);
}
else if (extension is RepeatedExtension<T1, T3>)
{
throw new InvalidOperationException("SetValue is not implemented for repeated extensions");
}
else
{
throw new InvalidCastException("The provided extension is not a valid extension identifier type");
}
}
public void ClearExtension(IMessage message)
{
if (message is not T1 extensionMessage)
{
throw new InvalidCastException("Cannot access extension on message that isn't IExtensionMessage");
}
if (extension is Extension<T1, T3> ext13)
{
extensionMessage.ClearExtension(ext13);
}
else if (extension is RepeatedExtension<T1, T3> repeatedExt13)
{
extensionMessage.GetExtension(repeatedExt13).Clear();
}
else
{
throw new InvalidCastException("The provided extension is not a valid extension identifier type");
}
}
public bool HasExtension(IMessage message) {
if (message is not T1 extensionMessage) {
throw new InvalidCastException(
"Cannot access extension on message that isn't IExtensionMessage");
}
#if NET5_0_OR_GREATER
/// <summary>
/// This helper is compatible with .NET Native AOT.
/// MakeGenericType doesn't work when a type argument is a value type in AOT.
/// MethodInfo.Invoke is used instead of compiled expressions because it's faster in AOT.
/// </summary>
private sealed class AotReflectionHelper : IReflectionHelper
{
private static readonly object[] EmptyObjectArray = new object[0];
public Action<IMessage> CreateActionIMessage(MethodInfo method) => message => method.Invoke(message, EmptyObjectArray);
public Action<IMessage, object> CreateActionIMessageObject(MethodInfo method) => (message, arg) => method.Invoke(message, new object[] { arg });
public Func<IMessage, bool> CreateFuncIMessageBool(MethodInfo method) => message => (bool) method.Invoke(message, EmptyObjectArray);
public Func<IMessage, int> CreateFuncIMessageInt32(MethodInfo method) => message => (int) method.Invoke(message, EmptyObjectArray);
public Func<IMessage, object> CreateFuncIMessageObject(MethodInfo method) => message => method.Invoke(message, EmptyObjectArray);
if (extension is Extension<T1, T3> ext13) {
return extensionMessage.HasExtension(ext13);
} else if (extension is RepeatedExtension<T1, T3>) {
throw new InvalidOperationException(
"HasValue is not implemented for repeated extensions");
} else {
throw new InvalidCastException(
"The provided extension is not a valid extension identifier type");
}
}
/// <summary>
/// Reflection with extensions isn't supported because IExtendableMessage members are used to get values.
/// Can't use reflection to invoke those methods because they have a generic argument.
/// MakeGenericMethod can't be used because it will break whenever the extension type is a value type.
/// This could be made to work if there were non-generic methods available for getting and setting extension values.
/// </summary>
private sealed class AotExtensionReflectionHelper : IExtensionReflectionHelper
{
private const string Message = "Extensions reflection is not supported with AOT.";
public object GetExtension(IMessage message) => throw new NotSupportedException(Message);
public bool HasExtension(IMessage message) => throw new NotSupportedException(Message);
public void SetExtension(IMessage message, object value) => throw new NotSupportedException(Message);
public void ClearExtension(IMessage message) => throw new NotSupportedException(Message);
public void SetExtension(IMessage message, object value) {
if (message is not T1 extensionMessage) {
throw new InvalidCastException(
"Cannot access extension on message that isn't IExtensionMessage");
}
#endif
private sealed class ExtensionSetReflector<
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)]
T1> : IExtensionSetReflector where T1 : IExtendableMessage<T1>
{
public Func<IMessage, bool> CreateIsInitializedCaller()
{
var prop = typeof(T1).GetTypeInfo().GetDeclaredProperty("_Extensions");
var getFunc = (Func<T1, ExtensionSet<T1>>)prop.GetMethod.CreateDelegate(typeof(Func<T1, ExtensionSet<T1>>));
var initializedFunc = (Func<ExtensionSet<T1>, bool>)
typeof(ExtensionSet<T1>)
.GetTypeInfo()
.GetDeclaredMethod("IsInitialized")
.CreateDelegate(typeof(Func<ExtensionSet<T1>, bool>));
return (m) => {
var set = getFunc((T1)m);
return set == null || initializedFunc(set);
};
}
if (extension is Extension<T1, T3> ext13) {
extensionMessage.SetExtension(ext13, (T3)value);
} else if (extension is RepeatedExtension<T1, T3>) {
throw new InvalidOperationException(
"SetValue is not implemented for repeated extensions");
} else {
throw new InvalidCastException(
"The provided extension is not a valid extension identifier type");
}
}
// Runtime compatibility checking code - see ReflectionHelper<T1, T2>.CreateFuncIMessageInt32 for
// details about why we're doing this.
// Deliberately not inside the generic type. We only want to check this once.
private static bool CanConvertEnumFuncToInt32Func { get; } = CheckCanConvertEnumFuncToInt32Func();
private static bool CheckCanConvertEnumFuncToInt32Func()
{
try
{
// Try to do the conversion using reflection, so we can see whether it's supported.
MethodInfo method = typeof(ReflectionUtil).GetMethod(nameof(SampleEnumMethod));
// If this passes, we're in a reasonable runtime.
method.CreateDelegate(typeof(Func<int>));
return true;
}
catch (ArgumentException)
{
return false;
}
public void ClearExtension(IMessage message) {
if (message is not T1 extensionMessage) {
throw new InvalidCastException(
"Cannot access extension on message that isn't IExtensionMessage");
}
public enum SampleEnum
{
X
if (extension is Extension<T1, T3> ext13) {
extensionMessage.ClearExtension(ext13);
} else if (extension is RepeatedExtension<T1, T3> repeatedExt13) {
extensionMessage.GetExtension(repeatedExt13).Clear();
} else {
throw new InvalidCastException(
"The provided extension is not a valid extension identifier type");
}
}
}
// Public to make the reflection simpler.
public static SampleEnum SampleEnumMethod() => SampleEnum.X;
#if NET5_0_OR_GREATER
/// <summary>
/// This helper is compatible with .NET Native AOT.
/// MakeGenericType doesn't work when a type argument is a value type in AOT.
/// MethodInfo.Invoke is used instead of compiled expressions because it's faster in AOT.
/// </summary>
private sealed class AotReflectionHelper : IReflectionHelper {
private static readonly object[] EmptyObjectArray = new object[0];
public Action<IMessage> CreateActionIMessage(MethodInfo method) => message =>
method.Invoke(message, EmptyObjectArray);
public Action<IMessage, object> CreateActionIMessageObject(MethodInfo method) =>
(message, arg) => method.Invoke(message, new object[] { arg });
public Func<IMessage, bool> CreateFuncIMessageBool(MethodInfo method) => message =>
(bool)method.Invoke(message, EmptyObjectArray);
public Func<IMessage, int> CreateFuncIMessageInt32(MethodInfo method) => message =>
(int)method.Invoke(message, EmptyObjectArray);
public Func<IMessage, object> CreateFuncIMessageObject(MethodInfo method) => message =>
method.Invoke(message, EmptyObjectArray);
}
/// <summary>
/// Reflection with extensions isn't supported because IExtendableMessage members are used to
/// get values. Can't use reflection to invoke those methods because they have a generic
/// argument. MakeGenericMethod can't be used because it will break whenever the extension type
/// is a value type. This could be made to work if there were non-generic methods available for
/// getting and setting extension values.
/// </summary>
private sealed class AotExtensionReflectionHelper : IExtensionReflectionHelper {
private const string Message = "Extensions reflection is not supported with AOT.";
public object GetExtension(IMessage message) => throw new NotSupportedException(Message);
public bool HasExtension(IMessage message) => throw new NotSupportedException(Message);
public void SetExtension(IMessage message,
object value) => throw new NotSupportedException(Message);
public void ClearExtension(IMessage message) => throw new NotSupportedException(Message);
}
#endif
private sealed class ExtensionSetReflector<[DynamicallyAccessedMembers(
DynamicallyAccessedMemberTypes.PublicProperties |
DynamicallyAccessedMemberTypes.NonPublicProperties)] T1> : IExtensionSetReflector
where T1 : IExtendableMessage<T1> {
public Func<IMessage, bool> CreateIsInitializedCaller() {
var prop = typeof(T1).GetTypeInfo().GetDeclaredProperty("_Extensions");
var getFunc = (Func<T1, ExtensionSet<T1>>)prop.GetMethod.CreateDelegate(
typeof(Func<T1, ExtensionSet<T1>>));
var initializedFunc = (Func<ExtensionSet<T1>, bool>)typeof(ExtensionSet<T1>)
.GetTypeInfo()
.GetDeclaredMethod("IsInitialized")
.CreateDelegate(typeof(Func<ExtensionSet<T1>, bool>));
return (m) => {
var set = getFunc((T1)m);
return set == null || initializedFunc(set);
};
}
}
// Runtime compatibility checking code - see ReflectionHelper<T1, T2>.CreateFuncIMessageInt32
// for details about why we're doing this.
// Deliberately not inside the generic type. We only want to check this once.
private static bool CanConvertEnumFuncToInt32Func { get; } =
CheckCanConvertEnumFuncToInt32Func();
private static bool CheckCanConvertEnumFuncToInt32Func() {
try {
// Try to do the conversion using reflection, so we can see whether it's supported.
MethodInfo method = typeof(ReflectionUtil).GetMethod(nameof(SampleEnumMethod));
// If this passes, we're in a reasonable runtime.
method.CreateDelegate(typeof(Func<int>));
return true;
} catch (ArgumentException) {
return false;
}
}
public enum SampleEnum { X }
// Public to make the reflection simpler.
public static SampleEnum SampleEnumMethod() => SampleEnum.X;
}
}

@ -39,6 +39,7 @@ cc_binary(
deps = [
":addressbook_cc_proto",
"@com_google_protobuf//:protobuf",
"@com_google_protobuf//src/google/protobuf/util:time_util",
],
)
@ -48,6 +49,7 @@ cc_binary(
deps = [
":addressbook_cc_proto",
"@com_google_protobuf//:protobuf",
"@com_google_protobuf//src/google/protobuf/util:time_util",
],
)

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

@ -164,18 +164,10 @@ public final class Descriptors {
}
/** Get the edition of the .proto file. */
public Edition getEdition() {
Edition getEdition() {
return proto.getEdition();
}
/** Gets the name of the edition as specified in the .proto file. */
public String getEditionName() {
if (proto.getEdition().equals(Edition.EDITION_UNKNOWN)) {
return "";
}
return proto.getEdition().name().substring("EDITION_".length());
}
public void copyHeadingTo(FileDescriptorProto.Builder protoBuilder) {
protoBuilder.setName(getName()).setSyntax(getSyntax().name);
if (!getPackage().isEmpty()) {

@ -1613,7 +1613,7 @@ public abstract class GeneratedMessage extends AbstractMessage implements Serial
protected FieldDescriptor loadDescriptor() {
try {
Class clazz = singularType.getClassLoader().loadClass(descriptorOuterClass);
FileDescriptor file = (FileDescriptor) clazz.getField("descriptor").get(null);
FileDescriptor file = (FileDescriptor) clazz.getMethod("getDescriptor").invoke(null);
return file.findExtensionByName(extensionName);
} catch (Exception e) {
throw new RuntimeException(

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

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

@ -52,7 +52,7 @@ def junit_tests(name, srcs, data = [], deps = [], package_name = "com.google.pro
if test_prefix:
test_name = "%s%s" % (test_prefix, test_name)
test_names = test_names + [test_name]
suite_name = prefix + '_' + test_name
suite_name = prefix + "_" + test_name
_gen_suite(
name = suite_name,
srcs = [src],

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

@ -0,0 +1,21 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. 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
package com.google.protobuf.util;
import com.google.protobuf.DescriptorProtos.Edition;
/** Utility helper functions to work with {@link com.google.protobuf.FileDescriptorProto}. */
public final class ProtoFileUtil {
private ProtoFileUtil() {}
/** Converts an Edition to its string representation as specified in ".proto" file. */
public static String getEditionString(Edition edition) {
return edition.toString().substring("EDITION_".length());
}
}

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

@ -0,0 +1,24 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. 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
package com.google.protobuf.util;
import static com.google.common.truth.Truth.assertThat;
import com.google.protobuf.DescriptorProtos.Edition;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Unit tests for {@link ProtoFileUtil}. */
@RunWith(JUnit4.class)
public class ProtoFileUtilTest {
@Test
public void testGetEditionFromString() throws Exception {
assertThat(ProtoFileUtil.getEditionString(Edition.EDITION_2023)).isEqualTo("2023");
}
}

@ -32,6 +32,7 @@ cc_library(
deps = [
"//upb:json",
"//upb:message",
"//upb:port",
"//upb:reflection",
"//upb:text",
"@lua//:liblua",
@ -44,7 +45,9 @@ cc_binary(
copts = UPB_DEFAULT_CPPOPTS,
visibility = ["//visibility:public"],
deps = [
"//src/google/protobuf",
"//src/google/protobuf/compiler:code_generator",
"//src/google/protobuf/io:printer",
"@com_google_absl//absl/strings",
],
)

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

@ -682,7 +682,6 @@ PHP_METHOD(Message, mergeFrom) {
PHP_METHOD(Message, mergeFromString) {
Message* intern = (Message*)Z_OBJ_P(getThis());
char* data = NULL;
char* data_copy = NULL;
zend_long data_len;
const upb_MiniTable* l = upb_MessageDef_MiniTable(intern->desc->msgdef);
upb_Arena* arena = Arena_Get(&intern->arena);
@ -692,11 +691,7 @@ PHP_METHOD(Message, mergeFromString) {
return;
}
// TODO: avoid this copy when we can make the decoder copy.
data_copy = upb_Arena_Malloc(arena, data_len);
memcpy(data_copy, data, data_len);
if (upb_Decode(data_copy, data_len, intern->msg, l, NULL, 0, arena) !=
if (upb_Decode(data, data_len, intern->msg, l, NULL, 0, arena) !=
kUpb_DecodeStatus_Ok) {
zend_throw_exception_ex(NULL, 0, "Error occurred during parsing");
return;
@ -739,7 +734,6 @@ PHP_METHOD(Message, serializeToString) {
PHP_METHOD(Message, mergeFromJsonString) {
Message* intern = (Message*)Z_OBJ_P(getThis());
char* data = NULL;
char* data_copy = NULL;
zend_long data_len;
upb_Arena* arena = Arena_Get(&intern->arena);
upb_Status status;
@ -751,17 +745,12 @@ PHP_METHOD(Message, mergeFromJsonString) {
return;
}
// TODO: avoid this copy when we can make the decoder copy.
data_copy = upb_Arena_Malloc(arena, data_len + 1);
memcpy(data_copy, data, data_len);
data_copy[data_len] = '\0';
if (ignore_json_unknown) {
options |= upb_JsonDecode_IgnoreUnknown;
}
upb_Status_Clear(&status);
if (!upb_JsonDecode(data_copy, data_len, intern->msg, intern->desc->msgdef,
if (!upb_JsonDecode(data, data_len, intern->msg, intern->desc->msgdef,
DescriptorPool_GetSymbolTable(), options, arena,
&status)) {
zend_throw_exception_ex(NULL, 0, "Error occurred during parsing: %s",

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,127 +0,0 @@
<?php
require_once('test_base.php');
require_once('test_util.php');
use Google\Protobuf\Internal\RepeatedField;
use Google\Protobuf\Internal\MapField;
use Google\Protobuf\Internal\GPBType;
use Foo\Greeter;
use Foo\HelloRequest;
use Foo\HelloReply;
class GeneratedServiceTest extends TestBase
{
/**
* @var \ReflectionClass
*/
private $serviceClass;
/**
* @var \ReflectionClass
*/
private $namespacedServiceClass;
/**
* @var array
*/
private $methodNames = [
'sayHello',
'sayHelloAgain'
];
/**
* Avoid calling setUp, which has void return type (not avalialbe in php7.0).
*
* @before
*/
public function setUpTest()
{
$this->serviceClass = new ReflectionClass('Foo\GreeterInterface');
$this->namespacedServiceClass = new ReflectionClass('Bar\OtherGreeterInterface');
}
public function testIsInterface()
{
$this->assertTrue($this->serviceClass->isInterface());
}
public function testPhpDocForClass()
{
$this->assertStringContains(
'foo.Greeter', $this->serviceClass->getDocComment());
}
public function testPhpDocForNamespacedClass()
{
$this->assertStringContains(
'foo.OtherGreeter', $this->namespacedServiceClass->getDocComment());
}
public function testServiceMethodsAreGenerated()
{
$this->assertCount(
count($this->methodNames), $this->serviceClass->getMethods());
foreach ($this->methodNames as $methodName) {
$this->assertTrue($this->serviceClass->hasMethod($methodName));
}
}
public function testPhpDocForServiceMethod()
{
foreach ($this->methodNames as $methodName) {
$docComment =
$this->serviceClass->getMethod($methodName)->getDocComment();
$this->assertStringContains($methodName, $docComment);
$this->assertStringContains(
'@param \Foo\HelloRequest $request', $docComment);
$this->assertStringContains(
'@return \Foo\HelloReply', $docComment);
}
}
public function testPhpDocForServiceMethodInNamespacedClass()
{
foreach ($this->methodNames as $methodName) {
$docComment =
$this->namespacedServiceClass->getMethod(
$methodName)->getDocComment();
$this->assertStringContains($methodName, $docComment);
$this->assertStringContains(
'@param \Foo\HelloRequest $request', $docComment);
$this->assertStringContains(
'@return \Foo\HelloReply', $docComment);
}
}
public function testParamForServiceMethod()
{
foreach ($this->methodNames as $methodName) {
$method = $this->serviceClass->getMethod($methodName);
$this->assertCount(1, $method->getParameters());
$param = $method->getParameters()[0];
$this->assertFalse($param->isOptional());
$this->assertSame('request', $param->getName());
// ReflectionParameter::getType only exists in PHP 7+, so get the
// type from __toString
$this->assertStringContains(
'Foo\HelloRequest $request', (string) $param);
}
}
public function testParamForServiceMethodInNamespacedClass()
{
foreach ($this->methodNames as $methodName) {
$method = $this->serviceClass->getMethod($methodName);
$this->assertCount(1, $method->getParameters());
$param = $method->getParameters()[0];
$this->assertFalse($param->isOptional());
$this->assertSame('request', $param->getName());
// ReflectionParameter::getType only exists in PHP 7+, so get the
// type from __toString
$this->assertStringContains(
'Foo\HelloRequest $request', (string) $param);
}
}
}

@ -1,18 +0,0 @@
syntax = "proto3";
package foo;
option php_generic_services = true;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}

@ -1,13 +0,0 @@
syntax = "proto3";
import "proto/test_service.proto";
package foo;
option php_generic_services = true;
option php_namespace = "Bar";
service OtherGreeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
}

@ -1,9 +1,9 @@
load("@rules_pkg//:pkg.bzl", "pkg_zip")
load(
"@rules_pkg//:mappings.bzl",
"pkg_attributes",
"pkg_files",
)
load("@rules_pkg//:pkg.bzl", "pkg_zip")
load("//:protobuf_release.bzl", "package_naming")
load(":build_systems.bzl", "gen_file_lists")
load(":cc_dist_library.bzl", "cc_dist_library")
@ -163,9 +163,9 @@ cc_dist_library(
}),
tags = ["manual"],
deps = [
"//src/google/protobuf",
"//src/google/protobuf:arena_align",
"//src/google/protobuf:cmake_wkt_cc_proto",
"//src/google/protobuf:protobuf_nowkt",
"//src/google/protobuf/compiler:importer",
"//src/google/protobuf/json",
"//src/google/protobuf/util:delimited_message_util",

@ -7,44 +7,42 @@ load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
load(":protobuf_version.bzl", "PROTOC_VERSION")
def _package_naming_impl(ctx):
values = {}
values["version"] = PROTOC_VERSION
# infer from the current cpp toolchain.
toolchain = find_cpp_toolchain(ctx)
cpu = toolchain.cpu
system_name = toolchain.target_gnu_system_name
# rename cpus to match what we want artifacts to be
if cpu == "systemz":
cpu = "s390_64"
elif cpu == "aarch64":
cpu = "aarch_64"
elif cpu == "ppc64":
cpu = "ppcle_64"
# use the system name to determine the os and then create platform names
if "apple" in system_name:
values["platform"] = "osx-" + cpu
elif "linux" in system_name:
values["platform"] = "linux-" + cpu
elif "mingw" in system_name:
if cpu == "x86_64":
values["platform"] = "win64"
values = {}
values["version"] = PROTOC_VERSION
# infer from the current cpp toolchain.
toolchain = find_cpp_toolchain(ctx)
cpu = toolchain.cpu
system_name = toolchain.target_gnu_system_name
# rename cpus to match what we want artifacts to be
if cpu == "systemz":
cpu = "s390_64"
elif cpu == "aarch64":
cpu = "aarch_64"
elif cpu == "ppc64":
cpu = "ppcle_64"
# use the system name to determine the os and then create platform names
if "apple" in system_name:
values["platform"] = "osx-" + cpu
elif "linux" in system_name:
values["platform"] = "linux-" + cpu
elif "mingw" in system_name:
if cpu == "x86_64":
values["platform"] = "win64"
else:
values["platform"] = "win32"
else:
values["platform"] = "win32"
else:
values["platform"] = "unknown"
return PackageVariablesInfo(values = values)
values["platform"] = "unknown"
return PackageVariablesInfo(values = values)
package_naming = rule(
implementation = _package_naming_impl,
implementation = _package_naming_impl,
attrs = {
# Necessary data dependency for find_cpp_toolchain.
"_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")),
# Necessary data dependency for find_cpp_toolchain.
"_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")),
},
toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
incompatible_use_toolchain_transition = True,
)

@ -35,7 +35,6 @@ cc_library(
"//upb:mem",
"//upb:message",
"//upb:message_copy",
"//upb:message_types",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/strings",
],
@ -55,14 +54,13 @@ cc_library(
":protos_extension_lock",
"//upb:base",
"//upb:mem",
"//upb:message_accessors_internal",
"//upb:message",
"//upb:message_copy",
"//upb:message_internal",
"//upb:message_promote",
"//upb:message_types",
"//upb:mini_table",
"//upb:wire",
"//upb:wire_types",
"//upb:wire_reader",
"//upb/message:internal",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/strings",
@ -132,10 +130,11 @@ cc_test(
copts = UPB_DEFAULT_CPPOPTS,
deps = [
":protos_internal",
"@com_google_googletest//:gtest_main",
"//upb:mem",
"//protos_generator/tests:test_model_upb_cc_proto",
"//protos_generator/tests:test_model_upb_proto",
"//upb:mem",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
],
)
@ -150,6 +149,7 @@ cc_test(
srcs = ["repeated_field_iterator_test.cc"],
deps = [
":repeated_field",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
],
)
@ -158,12 +158,13 @@ cc_test(
name = "protos_extension_lock_test",
srcs = ["protos_extension_lock_test.cc"],
deps = [
"@com_google_googletest//:gtest_main",
"//upb:mem",
"//protos",
"//protos:protos_extension_lock",
"//protos_generator/tests:test_model_upb_cc_proto",
"//upb:mem",
"@com_google_absl//absl/hash",
"@com_google_absl//absl/log:absl_check",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
],
)

@ -18,8 +18,8 @@ bzl_library(
srcs = ["upb_cc_proto_library.bzl"],
visibility = ["//visibility:public"],
deps = [
"@bazel_skylib//lib:paths",
"//bazel:upb_proto_library_bzl",
"@bazel_skylib//lib:paths",
"@bazel_tools//tools/cpp:toolchain_utils.bzl",
],
)

@ -22,6 +22,7 @@ load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
def use_cpp_toolchain():
return ["@bazel_tools//tools/cpp:toolchain_type"]
# end:github_only
# Generic support code #########################################################
@ -267,7 +268,6 @@ _upb_cc_proto_library_aspect = aspect(
attr_aspects = ["deps"],
fragments = ["cpp"],
toolchains = use_cpp_toolchain(),
incompatible_use_toolchain_transition = True,
)
upb_cc_proto_library = rule(

@ -18,8 +18,8 @@
#include "upb/mem/arena.h"
#include "upb/message/copy.h"
#include "upb/message/internal/extension.h"
#include "upb/message/message.h"
#include "upb/message/promote.h"
#include "upb/message/types.h"
#include "upb/mini_table/extension.h"
#include "upb/mini_table/extension_registry.h"
#include "upb/mini_table/message.h"
@ -119,10 +119,11 @@ bool HasExtensionOrUnknown(const upb_Message* msg,
.status == kUpb_FindUnknown_Ok;
}
const upb_Message_Extension* GetOrPromoteExtension(
upb_Message* msg, const upb_MiniTableExtension* eid, upb_Arena* arena) {
const upb_Extension* GetOrPromoteExtension(upb_Message* msg,
const upb_MiniTableExtension* eid,
upb_Arena* arena) {
MessageLock msg_lock(msg);
const upb_Message_Extension* ext = _upb_Message_Getext(msg, eid);
const upb_Extension* ext = _upb_Message_Getext(msg, eid);
if (ext == nullptr) {
upb_GetExtension_Status ext_status = upb_MiniTable_GetOrPromoteExtension(
(upb_Message*)msg, eid, 0, arena, &ext);
@ -162,7 +163,7 @@ upb_Message* DeepClone(const upb_Message* source,
absl::Status MoveExtension(upb_Message* message, upb_Arena* message_arena,
const upb_MiniTableExtension* ext,
upb_Message* extension, upb_Arena* extension_arena) {
upb_Message_Extension* msg_ext =
upb_Extension* msg_ext =
_upb_Message_GetOrCreateExtension(message, ext, message_arena);
if (!msg_ext) {
return MessageAllocationError();
@ -183,7 +184,7 @@ absl::Status MoveExtension(upb_Message* message, upb_Arena* message_arena,
absl::Status SetExtension(upb_Message* message, upb_Arena* message_arena,
const upb_MiniTableExtension* ext,
const upb_Message* extension) {
upb_Message_Extension* msg_ext =
upb_Extension* msg_ext =
_upb_Message_GetOrCreateExtension(message, ext, message_arena);
if (!msg_ext) {
return MessageAllocationError();

@ -72,7 +72,7 @@ class Ptr final {
#endif
private:
Ptr(void* msg, upb_Arena* arena) : p_(msg, arena) {} // NOLINT
Ptr(upb_Message* msg, upb_Arena* arena) : p_(msg, arena) {} // NOLINT
friend class Ptr<const T>;
friend typename T::Access;
@ -132,11 +132,11 @@ struct PrivateAccess {
return message->msg();
}
template <typename T>
static auto Proxy(void* p, upb_Arena* arena) {
static auto Proxy(upb_Message* p, upb_Arena* arena) {
return typename T::Proxy(p, arena);
}
template <typename T>
static auto CProxy(const void* p, upb_Arena* arena) {
static auto CProxy(const upb_Message* p, upb_Arena* arena) {
return typename T::CProxy(p, arena);
}
};
@ -152,7 +152,7 @@ T CreateMessage() {
}
template <typename T>
typename T::Proxy CreateMessageProxy(void* msg, upb_Arena* arena) {
typename T::Proxy CreateMessageProxy(upb_Message* msg, upb_Arena* arena) {
return typename T::Proxy(msg, arena);
}
@ -223,8 +223,9 @@ absl::StatusOr<absl::string_view> Serialize(const upb_Message* message,
bool HasExtensionOrUnknown(const upb_Message* msg,
const upb_MiniTableExtension* eid);
const upb_Message_Extension* GetOrPromoteExtension(
upb_Message* msg, const upb_MiniTableExtension* eid, upb_Arena* arena);
const upb_Extension* GetOrPromoteExtension(upb_Message* msg,
const upb_MiniTableExtension* eid,
upb_Arena* arena);
void DeepCopy(upb_Message* target, const upb_Message* source,
const upb_MiniTable* mini_table, upb_Arena* arena);
@ -344,8 +345,8 @@ void ClearExtension(
Ptr<T> message,
const ::protos::internal::ExtensionIdentifier<Extendee, Extension>& id) {
static_assert(!std::is_const_v<T>, "");
_upb_Message_ClearExtensionField(internal::GetInternalMsg(message),
id.mini_table_ext());
upb_Message_ClearExtension(internal::GetInternalMsg(message),
id.mini_table_ext());
}
template <typename T, typename Extendee, typename Extension,
@ -409,7 +410,7 @@ absl::StatusOr<Ptr<const Extension>> GetExtension(
Ptr<T> message,
const ::protos::internal::ExtensionIdentifier<Extendee, Extension>& id) {
// TODO: Fix const correctness issues.
const upb_Message_Extension* ext = ::protos::internal::GetOrPromoteExtension(
const upb_Extension* ext = ::protos::internal::GetOrPromoteExtension(
const_cast<upb_Message*>(internal::GetInternalMsg(message)),
id.mini_table_ext(), ::protos::internal::GetArena(message));
if (!ext) {
@ -417,7 +418,7 @@ absl::StatusOr<Ptr<const Extension>> GetExtension(
upb_MiniTableExtension_Number(id.mini_table_ext()));
}
return Ptr<const Extension>(::protos::internal::CreateMessage<Extension>(
ext->data.ptr, ::protos::internal::GetArena(message)));
(upb_Message*)ext->data.ptr, ::protos::internal::GetArena(message)));
}
template <typename T, typename Extendee, typename Extension,

@ -26,8 +26,8 @@ TEST(CppGeneratedCode, InternalMoveMessage) {
protos_generator_test_TestModel_set_int_value_with_default(message, 123);
// Move ownership.
TestModel model =
protos::internal::MoveMessage<TestModel>(message, source_arena);
TestModel model = protos::internal::MoveMessage<TestModel>(
(upb_Message*)message, source_arena);
// Now that we have moved ownership, free original arena.
upb_Arena_Free(source_arena);
EXPECT_EQ(model.int_value_with_default(), 123);

@ -22,7 +22,7 @@
#include "upb/mem/arena.h"
#include "upb/message/array.h"
#include "upb/message/copy.h"
#include "upb/message/types.h"
#include "upb/message/message.h"
namespace protos {
namespace internal {
@ -136,9 +136,11 @@ class RepeatedFieldProxy
}
iterator begin() const {
return iterator({static_cast<upb_Message**>(
const_cast<void*>(upb_Array_DataPtr(this->arr_))),
this->arena_});
return iterator(
{static_cast<upb_Message**>(
this->arr_ ? const_cast<void*>(upb_Array_DataPtr(this->arr_))
: nullptr),
this->arena_});
}
iterator end() const { return begin() + this->size(); }
reverse_iterator rbegin() const { return reverse_iterator(end()); }

@ -18,7 +18,7 @@
#include "upb/base/string_view.h"
#include "upb/mem/arena.h"
#include "upb/message/array.h"
#include "upb/message/types.h"
#include "upb/message/message.h"
namespace protos {
namespace internal {

@ -56,12 +56,12 @@ cc_library(
":names",
":output",
"//:protobuf",
"@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/strings",
"//upb_generator:common",
"//upb_generator:file_layout",
"//upb_generator:keywords",
"//upb_generator:names",
"@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/strings",
],
)
@ -72,6 +72,7 @@ cc_library(
visibility = ["//visibility:private"],
deps = [
"//:protobuf",
"//src/google/protobuf/io",
"@com_google_absl//absl/log:absl_log",
"@com_google_absl//absl/strings",
],
@ -96,6 +97,7 @@ cc_library(
visibility = ["//visibility:private"],
deps = [
":output",
"//src/google/protobuf",
"//upb_generator:keywords",
],
)

@ -325,7 +325,7 @@ void WriteMapAccessorDefinitions(const protobuf::Descriptor* message,
$5* msg_value;
$7bool success = $4_$9_get(msg_, $8, &msg_value);
if (success) {
return ::protos::internal::CreateMessage<$6>(msg_value, arena_);
return ::protos::internal::CreateMessage<$6>(UPB_UPCAST(msg_value), arena_);
}
return absl::NotFoundError("");
}

@ -181,8 +181,8 @@ void WriteModelPublicDeclaration(
output(
R"cc(
private:
const void* msg() const { return msg_; }
void* msg() { return msg_; }
const upb_Message* msg() const { return UPB_UPCAST(msg_); }
upb_Message* msg() { return UPB_UPCAST(msg_); }
$0(upb_Message* msg, upb_Arena* arena) : $0Access() {
msg_ = ($1*)msg;
@ -242,9 +242,10 @@ void WriteModelProxyDeclaration(const protobuf::Descriptor* descriptor,
output(
R"cc(
private:
void* msg() const { return msg_; }
upb_Message* msg() const { return UPB_UPCAST(msg_); }
$0Proxy(void* msg, upb_Arena* arena) : internal::$0Access(($1*)msg, arena) {}
$0Proxy(upb_Message* msg, upb_Arena* arena)
: internal::$0Access(($1*)msg, arena) {}
friend $0::Proxy(::protos::CreateMessage<$0>(::protos::Arena& arena));
friend $0::Proxy(::protos::internal::CreateMessageProxy<$0>(
upb_Message*, upb_Arena*));
@ -295,9 +296,9 @@ void WriteModelCProxyDeclaration(const protobuf::Descriptor* descriptor,
R"cc(
private:
using AsNonConst = $0Proxy;
const void* msg() const { return msg_; }
const upb_Message* msg() const { return UPB_UPCAST(msg_); }
$0CProxy(const void* msg, upb_Arena* arena)
$0CProxy(const upb_Message* msg, upb_Arena* arena)
: internal::$0Access(($1*)msg, arena){};
friend struct ::protos::internal::PrivateAccess;
friend class RepeatedFieldProxy;
@ -340,7 +341,7 @@ void WriteMessageImplementation(
}
$0::$0(const $0& from) : $0Access() {
arena_ = owned_arena_.ptr();
msg_ = ($1*)::protos::internal::DeepClone(from.msg_, &$2, arena_);
msg_ = ($1*)::protos::internal::DeepClone(UPB_UPCAST(from.msg_), &$2, arena_);
}
$0::$0(const CProxy& from) : $0Access() {
arena_ = owned_arena_.ptr();
@ -354,7 +355,7 @@ void WriteMessageImplementation(
}
$0& $0::operator=(const $3& from) {
arena_ = owned_arena_.ptr();
msg_ = ($1*)::protos::internal::DeepClone(from.msg_, &$2, arena_);
msg_ = ($1*)::protos::internal::DeepClone(UPB_UPCAST(from.msg_), &$2, arena_);
return *this;
}
$0& $0::operator=(const CProxy& from) {

@ -124,12 +124,13 @@ cc_test(
copts = UPB_DEFAULT_CPPOPTS,
deps = [
# begin:google_only
# ":legacy_name_test_proto",
# ":legacy_name_test_proto",
# end:google_only
":no_package_upb_cc_proto",
":test_model_upb_cc_proto",
":test_model_upb_proto",
":naming_conflict_upb_cc_proto",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
"@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/strings",

@ -5,6 +5,7 @@
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
#include <iterator>
#include <limits>
#include <memory>
#include <string>
@ -571,6 +572,19 @@ TEST(CppGeneratedCode, RepeatedFieldProxyForMessages) {
EXPECT_EQ(test_model.mutable_child_models()->size(), 0);
}
TEST(CppGeneratedCode, EmptyRepeatedFieldProxyForMessages) {
::protos::Arena arena;
auto test_model = ::protos::CreateMessage<TestModel>(arena);
EXPECT_EQ(0, test_model.child_models().size());
ChildModel1 child1;
child1.set_child_str1(kTestStr1);
EXPECT_EQ(test_model.child_models().size(), 0);
EXPECT_EQ(std::distance(test_model.child_models().begin(),
test_model.child_models().end()),
0);
}
TEST(CppGeneratedCode, RepeatedFieldProxyForMessagesIndexOperator) {
::protos::Arena arena;
auto test_model = ::protos::CreateMessage<TestModel>(arena);

@ -100,7 +100,8 @@ message TestModel {
optional string doc_id = 241;
optional bool set_doc_id = 242;
extensions 10000 to max;
extensions 10000 to max
[verification = UNVERIFIED];
}
// Old version with fewer fields to test backward/forward compatibility.
@ -146,7 +147,8 @@ extend TestModel {
}
message TestAnnotation {
extensions 10000 to max;
extensions 10000 to max
[verification = UNVERIFIED];
}
message TestMessageHasEnum {

@ -13,6 +13,7 @@ load("//bazel:build_defs.bzl", "UPB_DEFAULT_COPTS")
# begin:github_only
load("@rules_pkg//:mappings.bzl", "pkg_files")
load("//python:build_targets.bzl", "build_targets")
build_targets(name = "python")
# end:github_only
@ -20,7 +21,7 @@ licenses(["notice"])
package(
# begin:google_only
# default_applicable_licenses = ["//upb:license"],
# default_applicable_licenses = ["//upb:license"],
# end:google_only
default_visibility = ["//python/dist:__pkg__"],
)
@ -136,10 +137,10 @@ selects.config_setting_group(
# begin:github_only
_message_target_compatible_with = {
"@platforms//os:windows": ["@platforms//:incompatible"],
"@system_python//:none": ["@platforms//:incompatible"],
"@system_python//:unsupported": ["@platforms//:incompatible"],
"//conditions:default": [],
"@platforms//os:windows": ["@platforms//:incompatible"],
"@system_python//:none": ["@platforms//:incompatible"],
"@system_python//:unsupported": ["@platforms//:incompatible"],
"//conditions:default": [],
}
# end:github_only
@ -176,7 +177,7 @@ filegroup(
"unknown_fields.h",
],
# begin:google_only
# compatible_with = ["//buildenv/target:non_prod"],
# compatible_with = ["//buildenv/target:non_prod"],
# end:google_only
)
@ -190,19 +191,19 @@ py_extension(
],
target_compatible_with = select(_message_target_compatible_with),
deps = [
"//third_party/utf8_range",
"//upb:base",
"//upb:descriptor_upb_proto_reflection",
"//upb:eps_copy_input_stream",
"//upb:hash",
"//upb:message",
"//upb:message_copy",
"//upb:port",
"//upb:reflection",
"//upb:text",
"//upb:wire_reader",
"//upb:wire_types",
"//upb/hash",
"//upb/util:compare",
"//upb/util:def_to_proto",
"//upb/util:required_fields",
"//third_party/utf8_range",
],
)

@ -85,7 +85,7 @@ def build_targets(name):
],
deps = select({
"//conditions:default": [],
":use_fast_cpp_protos": ["//external:python_headers"],
":use_fast_cpp_protos": ["@system_python//:python_headers"],
}),
)
@ -120,10 +120,21 @@ def build_targets(name):
],
deps = [
":proto_api",
"//:protobuf",
"//src/google/protobuf",
"//src/google/protobuf:port",
"//src/google/protobuf:protobuf_lite",
"//src/google/protobuf/io",
"//src/google/protobuf/io:tokenizer",
"//src/google/protobuf/stubs:lite",
"//src/google/protobuf/util:differencer",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/log:absl_check",
"@com_google_absl//absl/log:absl_log",
"@com_google_absl//absl/status",
"@com_google_absl//absl/strings",
] + select({
"//conditions:default": [],
":use_fast_cpp_protos": ["//external:python_headers"],
":use_fast_cpp_protos": ["@system_python//:python_headers"],
}),
)
@ -387,7 +398,7 @@ def build_targets(name):
hdrs = ["google/protobuf/proto_api.h"],
visibility = ["//visibility:public"],
deps = [
"//external:python_headers",
"@system_python//: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.

@ -12,6 +12,7 @@
#include "python/descriptor_pool.h"
#include "python/message.h"
#include "python/protobuf.h"
#include "upb/base/upcast.h"
#include "upb/reflection/def.h"
#include "upb/util/def_to_proto.h"
@ -391,7 +392,7 @@ static PyObject* PyUpb_Descriptor_GetOneofs(PyObject* _self, void* closure) {
static PyObject* PyUpb_Descriptor_GetOptions(PyObject* _self, PyObject* args) {
PyUpb_DescriptorBase* self = (void*)_self;
return PyUpb_DescriptorBase_GetOptions(
&self->options, upb_MessageDef_Options(self->def),
&self->options, UPB_UPCAST(upb_MessageDef_Options(self->def)),
&google__protobuf__MessageOptions_msg_init,
PYUPB_DESCRIPTOR_PROTO_PACKAGE ".MessageOptions");
}
@ -399,7 +400,7 @@ static PyObject* PyUpb_Descriptor_GetOptions(PyObject* _self, PyObject* args) {
static PyObject* PyUpb_Descriptor_GetFeatures(PyObject* _self, PyObject* args) {
PyUpb_DescriptorBase* self = (void*)_self;
return PyUpb_DescriptorBase_GetFeatures(
&self->features, upb_MessageDef_ResolvedFeatures(self->def));
&self->features, UPB_UPCAST(upb_MessageDef_ResolvedFeatures(self->def)));
}
static PyObject* PyUpb_Descriptor_CopyToProto(PyObject* _self,
@ -700,10 +701,10 @@ static PyType_Slot PyUpb_Descriptor_Slots[] = {
{0, NULL}};
static PyType_Spec PyUpb_Descriptor_Spec = {
PYUPB_MODULE_NAME ".Descriptor", // tp_name
sizeof(PyUpb_DescriptorBase), // tp_basicsize
0, // tp_itemsize
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags
PYUPB_MODULE_NAME ".Descriptor", // tp_name
sizeof(PyUpb_DescriptorBase), // tp_basicsize
0, // tp_itemsize
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags
PyUpb_Descriptor_Slots,
};
@ -809,7 +810,7 @@ static PyObject* PyUpb_EnumDescriptor_GetOptions(PyObject* _self,
PyObject* args) {
PyUpb_DescriptorBase* self = (void*)_self;
return PyUpb_DescriptorBase_GetOptions(
&self->options, upb_EnumDef_Options(self->def),
&self->options, UPB_UPCAST(upb_EnumDef_Options(self->def)),
&google__protobuf__EnumOptions_msg_init,
PYUPB_DESCRIPTOR_PROTO_PACKAGE ".EnumOptions");
}
@ -818,7 +819,7 @@ static PyObject* PyUpb_EnumDescriptor_GetFeatures(PyObject* _self,
PyObject* args) {
PyUpb_DescriptorBase* self = (void*)_self;
return PyUpb_DescriptorBase_GetFeatures(
&self->features, upb_EnumDef_ResolvedFeatures(self->def));
&self->features, UPB_UPCAST(upb_EnumDef_ResolvedFeatures(self->def)));
}
static PyObject* PyUpb_EnumDescriptor_CopyToProto(PyObject* _self,
@ -908,7 +909,7 @@ static PyObject* PyUpb_EnumValueDescriptor_GetOptions(PyObject* _self,
PyObject* args) {
PyUpb_DescriptorBase* self = (void*)_self;
return PyUpb_DescriptorBase_GetOptions(
&self->options, upb_EnumValueDef_Options(self->def),
&self->options, UPB_UPCAST(upb_EnumValueDef_Options(self->def)),
&google__protobuf__EnumValueOptions_msg_init,
PYUPB_DESCRIPTOR_PROTO_PACKAGE ".EnumValueOptions");
}
@ -917,7 +918,8 @@ static PyObject* PyUpb_EnumValueDescriptor_GetFeatures(PyObject* _self,
PyObject* args) {
PyUpb_DescriptorBase* self = (void*)_self;
return PyUpb_DescriptorBase_GetFeatures(
&self->features, upb_EnumValueDef_ResolvedFeatures(self->def));
&self->features,
UPB_UPCAST(upb_EnumValueDef_ResolvedFeatures(self->def)));
}
static PyGetSetDef PyUpb_EnumValueDescriptor_Getters[] = {
@ -1121,7 +1123,7 @@ static PyObject* PyUpb_FieldDescriptor_GetOptions(PyObject* _self,
PyObject* args) {
PyUpb_DescriptorBase* self = (void*)_self;
return PyUpb_DescriptorBase_GetOptions(
&self->options, upb_FieldDef_Options(self->def),
&self->options, UPB_UPCAST(upb_FieldDef_Options(self->def)),
&google__protobuf__FieldOptions_msg_init,
PYUPB_DESCRIPTOR_PROTO_PACKAGE ".FieldOptions");
}
@ -1130,7 +1132,7 @@ static PyObject* PyUpb_FieldDescriptor_GetFeatures(PyObject* _self,
PyObject* args) {
PyUpb_DescriptorBase* self = (void*)_self;
return PyUpb_DescriptorBase_GetFeatures(
&self->features, upb_FieldDef_ResolvedFeatures(self->def));
&self->features, UPB_UPCAST(upb_FieldDef_ResolvedFeatures(self->def)));
}
static PyGetSetDef PyUpb_FieldDescriptor_Getters[] = {
@ -1365,12 +1367,6 @@ static PyObject* PyUpb_FileDescriptor_GetPublicDependencies(PyObject* _self,
return PyUpb_GenericSequence_New(&funcs, self->def, self->pool);
}
static PyObject* PyUpb_FileDescriptor_GetEdition(PyObject* _self,
void* closure) {
PyUpb_DescriptorBase* self = (void*)_self;
return PyLong_FromLong(upb_FileDef_Edition(self->def));
}
static PyObject* PyUpb_FileDescriptor_GetHasOptions(PyObject* _self,
void* closure) {
PyUpb_DescriptorBase* self = (void*)_self;
@ -1381,7 +1377,7 @@ static PyObject* PyUpb_FileDescriptor_GetOptions(PyObject* _self,
PyObject* args) {
PyUpb_DescriptorBase* self = (void*)_self;
return PyUpb_DescriptorBase_GetOptions(
&self->options, upb_FileDef_Options(self->def),
&self->options, UPB_UPCAST(upb_FileDef_Options(self->def)),
&google__protobuf__FileOptions_msg_init,
PYUPB_DESCRIPTOR_PROTO_PACKAGE ".FileOptions");
}
@ -1390,7 +1386,7 @@ static PyObject* PyUpb_FileDescriptor_GetFeatures(PyObject* _self,
PyObject* args) {
PyUpb_DescriptorBase* self = (void*)_self;
return PyUpb_DescriptorBase_GetFeatures(
&self->features, upb_FileDef_ResolvedFeatures(self->def));
&self->features, UPB_UPCAST(upb_FileDef_ResolvedFeatures(self->def)));
}
static PyObject* PyUpb_FileDescriptor_CopyToProto(PyObject* _self,
@ -1419,7 +1415,6 @@ static PyGetSetDef PyUpb_FileDescriptor_Getters[] = {
{"public_dependencies", PyUpb_FileDescriptor_GetPublicDependencies, NULL,
"Dependencies"},
{"has_options", PyUpb_FileDescriptor_GetHasOptions, NULL, "Has Options"},
{"edition", PyUpb_FileDescriptor_GetEdition, (setter)NULL, "Edition"},
{NULL},
};
@ -1515,7 +1510,7 @@ static PyObject* PyUpb_MethodDescriptor_GetOptions(PyObject* _self,
PyObject* args) {
PyUpb_DescriptorBase* self = (void*)_self;
return PyUpb_DescriptorBase_GetOptions(
&self->options, upb_MethodDef_Options(self->def),
&self->options, UPB_UPCAST(upb_MethodDef_Options(self->def)),
&google__protobuf__MethodOptions_msg_init,
PYUPB_DESCRIPTOR_PROTO_PACKAGE ".MethodOptions");
}
@ -1524,7 +1519,7 @@ static PyObject* PyUpb_MethodDescriptor_GetFeatures(PyObject* _self,
PyObject* args) {
PyUpb_DescriptorBase* self = (void*)_self;
return PyUpb_DescriptorBase_GetFeatures(
&self->features, upb_MethodDef_ResolvedFeatures(self->def));
&self->features, UPB_UPCAST(upb_MethodDef_ResolvedFeatures(self->def)));
}
static PyObject* PyUpb_MethodDescriptor_CopyToProto(PyObject* _self,
@ -1632,7 +1627,7 @@ static PyObject* PyUpb_OneofDescriptor_GetOptions(PyObject* _self,
PyObject* args) {
PyUpb_DescriptorBase* self = (void*)_self;
return PyUpb_DescriptorBase_GetOptions(
&self->options, upb_OneofDef_Options(self->def),
&self->options, UPB_UPCAST(upb_OneofDef_Options(self->def)),
&google__protobuf__OneofOptions_msg_init,
PYUPB_DESCRIPTOR_PROTO_PACKAGE ".OneofOptions");
}
@ -1641,7 +1636,7 @@ static PyObject* PyUpb_OneofDescriptor_GetFeatures(PyObject* _self,
PyObject* args) {
PyUpb_DescriptorBase* self = (void*)_self;
return PyUpb_DescriptorBase_GetFeatures(
&self->features, upb_OneofDef_ResolvedFeatures(self->def));
&self->features, UPB_UPCAST(upb_OneofDef_ResolvedFeatures(self->def)));
}
static PyGetSetDef PyUpb_OneofDescriptor_Getters[] = {
@ -1742,7 +1737,7 @@ static PyObject* PyUpb_ServiceDescriptor_GetOptions(PyObject* _self,
PyObject* args) {
PyUpb_DescriptorBase* self = (void*)_self;
return PyUpb_DescriptorBase_GetOptions(
&self->options, upb_ServiceDef_Options(self->def),
&self->options, UPB_UPCAST(upb_ServiceDef_Options(self->def)),
&google__protobuf__ServiceOptions_msg_init,
PYUPB_DESCRIPTOR_PROTO_PACKAGE ".ServiceOptions");
}
@ -1751,7 +1746,7 @@ static PyObject* PyUpb_ServiceDescriptor_GetFeatures(PyObject* _self,
PyObject* args) {
PyUpb_DescriptorBase* self = (void*)_self;
return PyUpb_DescriptorBase_GetFeatures(
&self->features, upb_ServiceDef_ResolvedFeatures(self->def));
&self->features, UPB_UPCAST(upb_ServiceDef_ResolvedFeatures(self->def)));
}
static PyObject* PyUpb_ServiceDescriptor_CopyToProto(PyObject* _self,

@ -12,6 +12,7 @@
#include "python/descriptor.h"
#include "python/message.h"
#include "python/protobuf.h"
#include "upb/base/upcast.h"
#include "upb/reflection/def.h"
#include "upb/util/def_to_proto.h"
@ -147,8 +148,7 @@ bool PyUpb_DescriptorPool_CheckNoDatabase(PyObject* _self) { return true; }
static bool PyUpb_DescriptorPool_LoadDependentFiles(
PyUpb_DescriptorPool* self, google_protobuf_FileDescriptorProto* proto) {
size_t n;
const upb_StringView* deps =
google_protobuf_FileDescriptorProto_dependency(proto, &n);
const upb_StringView* deps = google_protobuf_FileDescriptorProto_dependency(proto, &n);
for (size_t i = 0; i < n; i++) {
const upb_FileDef* dep = upb_DefPool_FindFileByNameWithSize(
self->symtab, deps[i].data, deps[i].size);
@ -191,14 +191,13 @@ static PyObject* PyUpb_DescriptorPool_DoAddSerializedFile(
if (file) {
// If the existing file is equal to the new file, then silently ignore the
// duplicate add.
google_protobuf_FileDescriptorProto* existing =
upb_FileDef_ToProto(file, arena);
google_protobuf_FileDescriptorProto* existing = upb_FileDef_ToProto(file, arena);
if (!existing) {
PyErr_SetNone(PyExc_MemoryError);
goto done;
}
const upb_MessageDef* m = PyUpb_DescriptorPool_GetFileProtoDef();
if (upb_Message_IsEqual(proto, existing, m)) {
if (upb_Message_IsEqual(UPB_UPCAST(proto), UPB_UPCAST(existing), m)) {
result = PyUpb_FileDescriptor_Get(file);
goto done;
}

@ -1279,13 +1279,6 @@ 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.

@ -47,22 +47,6 @@ from google.protobuf.internal import python_message
_USE_C_DESCRIPTORS = descriptor._USE_C_DESCRIPTORS # pylint: disable=protected-access
def _Deprecated(func):
"""Mark functions as deprecated."""
def NewFunc(*args, **kwargs):
warnings.warn(
'Call to deprecated function %s(). Note: Do add unlinked descriptors '
'to descriptor_pool is wrong. Please use Add() or AddSerializedFile() '
'instead. This function will be removed soon.' % func.__name__,
category=DeprecationWarning)
return func(*args, **kwargs)
NewFunc.__name__ = func.__name__
NewFunc.__doc__ = func.__doc__
NewFunc.__dict__.update(func.__dict__)
return NewFunc
def _NormalizeFullyQualifiedName(name):
"""Remove leading period from fully-qualified type name.
@ -207,12 +191,6 @@ class DescriptorPool(object):
file_desc.serialized_pb = serialized_file_desc_proto
return file_desc
# Add Descriptor to descriptor pool is deprecated. Please use Add()
# or AddSerializedFile() to add a FileDescriptorProto instead.
@_Deprecated
def AddDescriptor(self, desc):
self._AddDescriptor(desc)
# Never call this method. It is for internal usage only.
def _AddDescriptor(self, desc):
"""Adds a Descriptor to the pool, non-recursively.
@ -267,12 +245,6 @@ class DescriptorPool(object):
self._top_enum_values[full_name] = enum_value
self._AddFileDescriptor(enum_desc.file)
# Add ServiceDescriptor to descriptor pool is deprecated. Please use Add()
# or AddSerializedFile() to add a FileDescriptorProto instead.
@_Deprecated
def AddServiceDescriptor(self, service_desc):
self._AddServiceDescriptor(service_desc)
# Never call this method. It is for internal usage only.
def _AddServiceDescriptor(self, service_desc):
"""Adds a ServiceDescriptor to the pool.
@ -288,12 +260,6 @@ class DescriptorPool(object):
service_desc.file.name)
self._service_descriptors[service_desc.full_name] = service_desc
# Add ExtensionDescriptor to descriptor pool is deprecated. Please use Add()
# or AddSerializedFile() to add a FileDescriptorProto instead.
@_Deprecated
def AddExtensionDescriptor(self, extension):
self._AddExtensionDescriptor(extension)
# Never call this method. It is for internal usage only.
def _AddExtensionDescriptor(self, extension):
"""Adds a FieldDescriptor describing an extension to the pool.
@ -343,10 +309,6 @@ class DescriptorPool(object):
python_message._AttachFieldHelpers(
extension.containing_type._concrete_class, extension)
@_Deprecated
def AddFileDescriptor(self, file_desc):
self._InternalAddFileDescriptor(file_desc)
# Never call this method. It is for internal usage only.
def _InternalAddFileDescriptor(self, file_desc):
"""Adds a FileDescriptor to the pool, non-recursively.

@ -136,17 +136,7 @@ class RepeatedScalarFieldContainer(BaseContainer[_T], MutableSequence[_T]):
def extend(self, elem_seq: Iterable[_T]) -> None:
"""Extends by appending the given iterable. Similar to list.extend()."""
# TODO: Change OSS to raise error too
if elem_seq is None:
return
try:
elem_seq_iter = iter(elem_seq)
except TypeError:
if not elem_seq:
warnings.warn('Value is not iterable. Please remove the wrong '
'usage. This will be changed to raise TypeError soon.')
return
raise
elem_seq_iter = iter(elem_seq)
new_values = [self._type_checker.CheckValue(elem) for elem in elem_seq_iter]
if new_values:
self._values.extend(new_values)

@ -539,9 +539,6 @@ 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.edition, descriptor_pb2.Edition.EDITION_PROTO2
)
file_proto = descriptor_pb2.FileDescriptorProto()
self.my_file.CopyToProto(file_proto)
self.assertEqual(self.my_file.serialized_pb,

@ -1060,7 +1060,14 @@ class JsonFormatTest(JsonFormatBase):
json_format.Parse, text, message)
# Time bigger than maximum time.
message.value.seconds = 253402300800
self.assertRaisesRegex(OverflowError, 'date value out of range',
self.assertRaisesRegex(json_format.SerializeToJsonError,
'Timestamp is not valid',
json_format.MessageToJson, message)
# Nanos smaller than 0
message.value.seconds = 0
message.value.nanos = -1
self.assertRaisesRegex(json_format.SerializeToJsonError,
'Timestamp is not valid',
json_format.MessageToJson, message)
# Lower case t does not accept.
text = '{"value": "0001-01-01t00:00:00Z"}'

@ -1012,6 +1012,12 @@ class MessageTest(unittest.TestCase):
m = message_module.TestAllTypes()
self.assertSequenceEqual([], m.repeated_int32)
for falsy_value in MessageTest.FALSY_VALUES:
with self.assertRaises(TypeError) as context:
m.repeated_int32.extend(falsy_value)
self.assertIn('iterable', str(context.exception))
self.assertSequenceEqual([], m.repeated_int32)
for empty_value in MessageTest.EMPTY_VALUES:
m.repeated_int32.extend(empty_value)
self.assertSequenceEqual([], m.repeated_int32)
@ -1021,6 +1027,12 @@ class MessageTest(unittest.TestCase):
m = message_module.TestAllTypes()
self.assertSequenceEqual([], m.repeated_float)
for falsy_value in MessageTest.FALSY_VALUES:
with self.assertRaises(TypeError) as context:
m.repeated_float.extend(falsy_value)
self.assertIn('iterable', str(context.exception))
self.assertSequenceEqual([], m.repeated_float)
for empty_value in MessageTest.EMPTY_VALUES:
m.repeated_float.extend(empty_value)
self.assertSequenceEqual([], m.repeated_float)
@ -1030,6 +1042,12 @@ class MessageTest(unittest.TestCase):
m = message_module.TestAllTypes()
self.assertSequenceEqual([], m.repeated_string)
for falsy_value in MessageTest.FALSY_VALUES:
with self.assertRaises(TypeError) as context:
m.repeated_string.extend(falsy_value)
self.assertIn('iterable', str(context.exception))
self.assertSequenceEqual([], m.repeated_string)
for empty_value in MessageTest.EMPTY_VALUES:
m.repeated_string.extend(empty_value)
self.assertSequenceEqual([], m.repeated_string)

@ -779,15 +779,6 @@ def _AddPropertiesForExtensions(descriptor, cls):
pool = descriptor.file.pool
def _AddStaticMethods(cls):
# TODO: This probably needs to be thread-safe(?)
def RegisterExtension(field_descriptor):
field_descriptor.containing_type = cls.DESCRIPTOR
# TODO: Use cls.MESSAGE_FACTORY.pool when available.
# pylint: disable=protected-access
cls.DESCRIPTOR.file.pool._AddExtensionDescriptor(field_descriptor)
_AttachFieldHelpers(cls, field_descriptor)
cls.RegisterExtension = staticmethod(RegisterExtension)
def FromString(s):
message = cls()
message.MergeFromString(s)

@ -20,6 +20,7 @@ __author__ = 'jieluo@google.com (Jie Luo)'
import calendar
import collections.abc
import datetime
import warnings
from google.protobuf.internal import field_mask
@ -33,6 +34,8 @@ _MILLIS_PER_SECOND = 1000
_MICROS_PER_SECOND = 1000000
_SECONDS_PER_DAY = 24 * 3600
_DURATION_SECONDS_MAX = 315576000000
_TIMESTAMP_SECONDS_MIN = -62135596800
_TIMESTAMP_SECONDS_MAX = 253402300799
_EPOCH_DATETIME_NAIVE = datetime.datetime(1970, 1, 1, tzinfo=None)
_EPOCH_DATETIME_AWARE = _EPOCH_DATETIME_NAIVE.replace(
@ -85,10 +88,10 @@ class Timestamp(object):
and uses 3, 6 or 9 fractional digits as required to represent the
exact time. Example of the return format: '1972-01-01T10:00:20.021Z'
"""
nanos = self.nanos % _NANOS_PER_SECOND
total_sec = self.seconds + (self.nanos - nanos) // _NANOS_PER_SECOND
seconds = total_sec % _SECONDS_PER_DAY
days = (total_sec - seconds) // _SECONDS_PER_DAY
_CheckTimestampValid(self.seconds, self.nanos)
nanos = self.nanos
seconds = self.seconds % _SECONDS_PER_DAY
days = (self.seconds - seconds) // _SECONDS_PER_DAY
dt = datetime.datetime(1970, 1, 1) + datetime.timedelta(days, seconds)
result = dt.isoformat()
@ -166,6 +169,7 @@ class Timestamp(object):
else:
seconds += (int(timezone[1:pos])*60+int(timezone[pos+1:]))*60
# Set seconds and nanos
_CheckTimestampValid(seconds, nanos)
self.seconds = int(seconds)
self.nanos = int(nanos)
@ -175,39 +179,53 @@ class Timestamp(object):
def ToNanoseconds(self):
"""Converts Timestamp to nanoseconds since epoch."""
_CheckTimestampValid(self.seconds, self.nanos)
return self.seconds * _NANOS_PER_SECOND + self.nanos
def ToMicroseconds(self):
"""Converts Timestamp to microseconds since epoch."""
_CheckTimestampValid(self.seconds, self.nanos)
return (self.seconds * _MICROS_PER_SECOND +
self.nanos // _NANOS_PER_MICROSECOND)
def ToMilliseconds(self):
"""Converts Timestamp to milliseconds since epoch."""
_CheckTimestampValid(self.seconds, self.nanos)
return (self.seconds * _MILLIS_PER_SECOND +
self.nanos // _NANOS_PER_MILLISECOND)
def ToSeconds(self):
"""Converts Timestamp to seconds since epoch."""
_CheckTimestampValid(self.seconds, self.nanos)
return self.seconds
def FromNanoseconds(self, nanos):
"""Converts nanoseconds since epoch to Timestamp."""
self.seconds = nanos // _NANOS_PER_SECOND
self.nanos = nanos % _NANOS_PER_SECOND
seconds = nanos // _NANOS_PER_SECOND
nanos = nanos % _NANOS_PER_SECOND
_CheckTimestampValid(seconds, nanos)
self.seconds = seconds
self.nanos = nanos
def FromMicroseconds(self, micros):
"""Converts microseconds since epoch to Timestamp."""
self.seconds = micros // _MICROS_PER_SECOND
self.nanos = (micros % _MICROS_PER_SECOND) * _NANOS_PER_MICROSECOND
seconds = micros // _MICROS_PER_SECOND
nanos = (micros % _MICROS_PER_SECOND) * _NANOS_PER_MICROSECOND
_CheckTimestampValid(seconds, nanos)
self.seconds = seconds
self.nanos = nanos
def FromMilliseconds(self, millis):
"""Converts milliseconds since epoch to Timestamp."""
self.seconds = millis // _MILLIS_PER_SECOND
self.nanos = (millis % _MILLIS_PER_SECOND) * _NANOS_PER_MILLISECOND
seconds = millis // _MILLIS_PER_SECOND
nanos = (millis % _MILLIS_PER_SECOND) * _NANOS_PER_MILLISECOND
_CheckTimestampValid(seconds, nanos)
self.seconds = seconds
self.nanos = nanos
def FromSeconds(self, seconds):
"""Converts seconds since epoch to Timestamp."""
_CheckTimestampValid(seconds, 0)
self.seconds = seconds
self.nanos = 0
@ -229,6 +247,7 @@ class Timestamp(object):
# https://github.com/python/cpython/issues/109849) or full range (on some
# platforms, see https://github.com/python/cpython/issues/110042) of
# datetime.
_CheckTimestampValid(self.seconds, self.nanos)
delta = datetime.timedelta(
seconds=self.seconds,
microseconds=_RoundTowardZero(self.nanos, _NANOS_PER_MICROSECOND),
@ -252,8 +271,22 @@ class Timestamp(object):
# manipulated into a long value of seconds. During the conversion from
# struct_time to long, the source date in UTC, and so it follows that the
# correct transformation is calendar.timegm()
self.seconds = calendar.timegm(dt.utctimetuple())
self.nanos = dt.microsecond * _NANOS_PER_MICROSECOND
seconds = calendar.timegm(dt.utctimetuple())
nanos = dt.microsecond * _NANOS_PER_MICROSECOND
_CheckTimestampValid(seconds, nanos)
self.seconds = seconds
self.nanos = nanos
def _CheckTimestampValid(seconds, nanos):
if seconds < _TIMESTAMP_SECONDS_MIN or seconds > _TIMESTAMP_SECONDS_MAX:
raise ValueError(
'Timestamp is not valid: Seconds {0} must be in range '
'[-62135596800, 253402300799].'.format(seconds))
if nanos < 0 or nanos >= _NANOS_PER_SECOND:
raise ValueError(
'Timestamp is not valid: Nanos {} must be in a range '
'[0, 999999].'.format(nanos))
class Duration(object):

@ -352,27 +352,15 @@ class TimeUtilTest(TimeUtilTestBase):
)
def testNanosOneSecond(self):
# TODO: b/301980950 - Test error behavior instead once ToDatetime validates
# that nanos are in expected range.
tz = _TZ_PACIFIC
ts = timestamp_pb2.Timestamp(nanos=1_000_000_000)
self.assertEqual(ts.ToDatetime(), datetime.datetime(1970, 1, 1, 0, 0, 1))
self.assertEqual(
ts.ToDatetime(tz), datetime.datetime(1969, 12, 31, 16, 0, 1, tzinfo=tz)
)
self.assertRaisesRegex(ValueError, 'Timestamp is not valid',
ts.ToDatetime)
def testNanosNegativeOneSecond(self):
# TODO: b/301980950 - Test error behavior instead once ToDatetime validates
# that nanos are in expected range.
tz = _TZ_PACIFIC
ts = timestamp_pb2.Timestamp(nanos=-1_000_000_000)
self.assertEqual(
ts.ToDatetime(), datetime.datetime(1969, 12, 31, 23, 59, 59)
)
self.assertEqual(
ts.ToDatetime(tz),
datetime.datetime(1969, 12, 31, 15, 59, 59, tzinfo=tz),
)
self.assertRaisesRegex(ValueError, 'Timestamp is not valid',
ts.ToDatetime)
def testTimedeltaConversion(self):
message = duration_pb2.Duration()
@ -421,8 +409,10 @@ class TimeUtilTest(TimeUtilTestBase):
self.assertRaisesRegex(ValueError, 'year (0 )?is out of range',
message.FromJsonString, '0000-01-01T00:00:00Z')
message.seconds = 253402300800
self.assertRaisesRegex(OverflowError, 'date value out of range',
self.assertRaisesRegex(ValueError, 'Timestamp is not valid',
message.ToJsonString)
self.assertRaisesRegex(ValueError, 'Timestamp is not valid',
message.FromSeconds, -62135596801)
def testInvalidDuration(self):
message = duration_pb2.Duration()

@ -340,11 +340,6 @@ class Message(object):
def FromString(cls, s):
raise NotImplementedError
# TODO: Remove it in OSS
@staticmethod
def RegisterExtension(field_descriptor):
raise NotImplementedError
def _SetListener(self, message_listener):
"""Internal method used by the protocol message implementation.
Clients should not call this directly.

@ -1529,10 +1529,6 @@ static int SetSerializedOptions(PyFileDescriptor *self, PyObject *value,
return CheckCalledFromGeneratedFile("_serialized_options");
}
static PyObject* GetEdition(PyFileDescriptor* self, void* closure) {
return PyLong_FromLong(_GetDescriptor(self)->edition());
}
static PyObject* CopyToProto(PyFileDescriptor *self, PyObject *target) {
return CopyToPythonProto<FileDescriptorProto>(_GetDescriptor(self), target);
}
@ -1559,7 +1555,6 @@ static PyGetSetDef Getters[] = {
{"_options", (getter) nullptr, (setter)SetOptions, "Options"},
{"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions,
"Serialized Options"},
{"edition", (getter)GetEdition, (setter) nullptr, "Edition"},
{nullptr},
};

@ -482,100 +482,6 @@ static PyObject* FindAllExtensions(PyObject* self, PyObject* arg) {
return result.release();
}
// These functions should not exist -- the only valid way to create
// descriptors is to call Add() or AddSerializedFile().
// But these AddDescriptor() functions were created in Python and some people
// call them, so we support them for now for compatibility.
// However we do check that the existing descriptor already exists in the pool,
// which appears to always be true for existing calls -- but then why do people
// call a function that will just be a no-op?
// TODO: Need to investigate further.
static PyObject* AddFileDescriptor(PyObject* self, PyObject* descriptor) {
const FileDescriptor* file_descriptor =
PyFileDescriptor_AsDescriptor(descriptor);
if (!file_descriptor) {
return nullptr;
}
if (file_descriptor !=
reinterpret_cast<PyDescriptorPool*>(self)->pool->FindFileByName(
file_descriptor->name())) {
PyErr_Format(PyExc_ValueError,
"The file descriptor %s does not belong to this pool",
file_descriptor->name().c_str());
return nullptr;
}
Py_RETURN_NONE;
}
static PyObject* AddDescriptor(PyObject* self, PyObject* descriptor) {
const Descriptor* message_descriptor =
PyMessageDescriptor_AsDescriptor(descriptor);
if (!message_descriptor) {
return nullptr;
}
if (message_descriptor !=
reinterpret_cast<PyDescriptorPool*>(self)->pool->FindMessageTypeByName(
message_descriptor->full_name())) {
PyErr_Format(PyExc_ValueError,
"The message descriptor %s does not belong to this pool",
message_descriptor->full_name().c_str());
return nullptr;
}
Py_RETURN_NONE;
}
static PyObject* AddEnumDescriptor(PyObject* self, PyObject* descriptor) {
const EnumDescriptor* enum_descriptor =
PyEnumDescriptor_AsDescriptor(descriptor);
if (!enum_descriptor) {
return nullptr;
}
if (enum_descriptor !=
reinterpret_cast<PyDescriptorPool*>(self)->pool->FindEnumTypeByName(
enum_descriptor->full_name())) {
PyErr_Format(PyExc_ValueError,
"The enum descriptor %s does not belong to this pool",
enum_descriptor->full_name().c_str());
return nullptr;
}
Py_RETURN_NONE;
}
static PyObject* AddExtensionDescriptor(PyObject* self, PyObject* descriptor) {
const FieldDescriptor* extension_descriptor =
PyFieldDescriptor_AsDescriptor(descriptor);
if (!extension_descriptor) {
return nullptr;
}
if (extension_descriptor !=
reinterpret_cast<PyDescriptorPool*>(self)->pool->FindExtensionByName(
extension_descriptor->full_name())) {
PyErr_Format(PyExc_ValueError,
"The extension descriptor %s does not belong to this pool",
extension_descriptor->full_name().c_str());
return nullptr;
}
Py_RETURN_NONE;
}
static PyObject* AddServiceDescriptor(PyObject* self, PyObject* descriptor) {
const ServiceDescriptor* service_descriptor =
PyServiceDescriptor_AsDescriptor(descriptor);
if (!service_descriptor) {
return nullptr;
}
if (service_descriptor !=
reinterpret_cast<PyDescriptorPool*>(self)->pool->FindServiceByName(
service_descriptor->full_name())) {
PyErr_Format(PyExc_ValueError,
"The service descriptor %s does not belong to this pool",
service_descriptor->full_name().c_str());
return nullptr;
}
Py_RETURN_NONE;
}
// The code below loads new Descriptors from a serialized FileDescriptorProto.
static PyObject* AddSerializedFile(PyObject* pself, PyObject* serialized_pb) {
PyDescriptorPool* self = reinterpret_cast<PyDescriptorPool*>(pself);
@ -689,17 +595,6 @@ static PyMethodDef Methods[] = {
{"SetFeatureSetDefaults", SetFeatureSetDefaults, METH_O,
"Sets the default feature mappings used during the build."},
{"AddFileDescriptor", AddFileDescriptor, METH_O,
"No-op. Add() must have been called before."},
{"AddDescriptor", AddDescriptor, METH_O,
"No-op. Add() must have been called before."},
{"AddEnumDescriptor", AddEnumDescriptor, METH_O,
"No-op. Add() must have been called before."},
{"AddExtensionDescriptor", AddExtensionDescriptor, METH_O,
"No-op. Add() must have been called before."},
{"AddServiceDescriptor", AddServiceDescriptor, METH_O,
"No-op. Add() must have been called before."},
{"FindFileByName", FindFileByName, METH_O,
"Searches for a file descriptor by its .proto name."},
{"FindMessageTypeByName", FindMessageByName, METH_O,

@ -532,10 +532,10 @@ bool CheckAndGetInteger(PyObject* arg, T* value) {
// These are referenced by repeated_scalar_container, and must
// be explicitly instantiated.
template bool CheckAndGetInteger<int32>(PyObject*, int32*);
template bool CheckAndGetInteger<int64>(PyObject*, int64*);
template bool CheckAndGetInteger<uint32>(PyObject*, uint32*);
template bool CheckAndGetInteger<uint64>(PyObject*, uint64*);
template bool CheckAndGetInteger<int32_t>(PyObject*, int32_t*);
template bool CheckAndGetInteger<int64_t>(PyObject*, int64_t*);
template bool CheckAndGetInteger<uint32_t>(PyObject*, uint32_t*);
template bool CheckAndGetInteger<uint64_t>(PyObject*, uint64_t*);
bool CheckAndGetDouble(PyObject* arg, double* value) {
*value = PyFloat_AsDouble(arg);
@ -1855,32 +1855,6 @@ static PyObject* ByteSize(CMessage* self, PyObject* args) {
return PyLong_FromLong(self->message->ByteSizeLong());
}
PyObject* RegisterExtension(PyObject* cls, PyObject* extension_handle) {
const FieldDescriptor* descriptor =
GetExtensionDescriptor(extension_handle);
if (descriptor == nullptr) {
return nullptr;
}
if (!PyObject_TypeCheck(cls, CMessageClass_Type)) {
PyErr_Format(PyExc_TypeError, "Expected a message class, got %s",
cls->ob_type->tp_name);
return nullptr;
}
CMessageClass *message_class = reinterpret_cast<CMessageClass*>(cls);
if (message_class == nullptr) {
return nullptr;
}
// If the extension was already registered, check that it is the same.
const FieldDescriptor* existing_extension =
message_class->py_message_factory->pool->pool->FindExtensionByNumber(
descriptor->containing_type(), descriptor->number());
if (existing_extension != nullptr && existing_extension != descriptor) {
PyErr_SetString(PyExc_ValueError, "Double registration of Extensions");
return nullptr;
}
Py_RETURN_NONE;
}
static PyObject* SetInParent(CMessage* self, PyObject* args) {
AssureWritable(self);
Py_RETURN_NONE;
@ -2391,8 +2365,6 @@ static PyMethodDef Methods[] = {
"Merges a serialized message into the current message."},
{"ParseFromString", (PyCFunction)ParseFromString, METH_O,
"Parses a serialized message into the current message."},
{"RegisterExtension", (PyCFunction)RegisterExtension, METH_O | METH_CLASS,
"Registers an extension with the current message."},
{"SerializePartialToString", (PyCFunction)SerializePartialToString,
METH_VARARGS | METH_KEYWORDS,
"Serializes the message to a string, even if it isn't initialized."},

@ -19,8 +19,6 @@
#include <string>
#include <unordered_map>
#include "google/protobuf/stubs/common.h"
namespace google {
namespace protobuf {
@ -229,10 +227,6 @@ int InitAttributes(CMessage* self, PyObject* args, PyObject* kwargs);
PyObject* MergeFrom(CMessage* self, PyObject* arg);
// This method does not do anything beyond checking that no other extension
// has been registered with the same field number on this class.
PyObject* RegisterExtension(PyObject* cls, PyObject* extension_handle);
// Get a field from a message.
PyObject* GetFieldValue(CMessage* self,
const FieldDescriptor* field_descriptor);
@ -342,10 +336,10 @@ bool InitProto2MessageModule(PyObject *m);
// These are referenced by repeated_scalar_container, and must
// be explicitly instantiated.
extern template bool CheckAndGetInteger<int32>(PyObject*, int32*);
extern template bool CheckAndGetInteger<int64>(PyObject*, int64*);
extern template bool CheckAndGetInteger<uint32>(PyObject*, uint32*);
extern template bool CheckAndGetInteger<uint64>(PyObject*, uint64*);
extern template bool CheckAndGetInteger<int32_t>(PyObject*, int32_t*);
extern template bool CheckAndGetInteger<int64_t>(PyObject*, int64_t*);
extern template bool CheckAndGetInteger<uint32_t>(PyObject*, uint32_t*);
extern template bool CheckAndGetInteger<uint64_t>(PyObject*, uint64_t*);
} // namespace python
} // namespace protobuf

@ -443,20 +443,6 @@ static int AssSubscript(PyObject* pself, PyObject* slice, PyObject* value) {
PyObject* Extend(RepeatedScalarContainer* self, PyObject* value) {
cmessage::AssureWritable(self->parent);
// TODO: Remove this in OSS
if (value == Py_None) {
PyErr_Warn(nullptr,
"Value is not iterable. Please remove the wrong usage."
" This will be changed to raise TypeError soon.");
Py_RETURN_NONE;
}
if ((Py_TYPE(value)->tp_as_sequence == nullptr) && PyObject_Not(value)) {
PyErr_Warn(nullptr,
"Value is not iterable. Please remove the wrong usage."
" This will be changed to raise TypeError soon.");
Py_RETURN_NONE;
}
ScopedPyObjectPtr iter(PyObject_GetIter(value));
if (iter == nullptr) {
PyErr_SetString(PyExc_TypeError, "Value must be iterable");

@ -62,7 +62,7 @@ static void PyUpb_MapContainer_Dealloc(void* _self) {
PyUpb_Dealloc(_self);
}
PyTypeObject* PyUpb_MapContainer_GetClass(const upb_FieldDef* f) {
static PyTypeObject* PyUpb_MapContainer_GetClass(const upb_FieldDef* f) {
assert(upb_FieldDef_IsMap(f));
PyUpb_ModuleState* state = PyUpb_ModuleState_Get();
const upb_FieldDef* val =
@ -130,9 +130,9 @@ upb_Map* PyUpb_MapContainer_EnsureReified(PyObject* _self) {
return map;
}
bool PyUpb_MapContainer_Set(PyUpb_MapContainer* self, upb_Map* map,
upb_MessageValue key, upb_MessageValue val,
upb_Arena* arena) {
static bool PyUpb_MapContainer_Set(PyUpb_MapContainer* self, upb_Map* map,
upb_MessageValue key, upb_MessageValue val,
upb_Arena* arena) {
switch (upb_Map_Insert(map, key, val, arena)) {
case kUpb_MapInsertStatus_Inserted:
return true;
@ -146,8 +146,9 @@ bool PyUpb_MapContainer_Set(PyUpb_MapContainer* self, upb_Map* map,
return false; // Unreachable, silence compiler warning.
}
int PyUpb_MapContainer_AssignSubscript(PyObject* _self, PyObject* key,
PyObject* val) {
// Assigns `self[key] = val` for the map `self`.
static int PyUpb_MapContainer_AssignSubscript(PyObject* _self, PyObject* key,
PyObject* val) {
PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self;
upb_Map* map = PyUpb_MapContainer_EnsureReified(_self);
const upb_FieldDef* f = PyUpb_MapContainer_GetField(self);
@ -170,7 +171,7 @@ int PyUpb_MapContainer_AssignSubscript(PyObject* _self, PyObject* key,
return 0;
}
PyObject* PyUpb_MapContainer_Subscript(PyObject* _self, PyObject* key) {
static PyObject* PyUpb_MapContainer_Subscript(PyObject* _self, PyObject* key) {
PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self;
upb_Map* map = PyUpb_MapContainer_GetIfReified(self);
const upb_FieldDef* f = PyUpb_MapContainer_GetField(self);
@ -183,7 +184,7 @@ PyObject* PyUpb_MapContainer_Subscript(PyObject* _self, PyObject* key) {
map = PyUpb_MapContainer_EnsureReified(_self);
upb_Arena* arena = PyUpb_Arena_Get(self->arena);
if (upb_FieldDef_IsSubMessage(val_f)) {
const upb_Message* m = upb_FieldDef_MessageSubDef(val_f);
const upb_MessageDef* m = upb_FieldDef_MessageSubDef(val_f);
const upb_MiniTable* layout = upb_MessageDef_MiniTable(m);
u_val.msg_val = upb_Message_New(layout, arena);
} else {
@ -194,7 +195,7 @@ PyObject* PyUpb_MapContainer_Subscript(PyObject* _self, PyObject* key) {
return PyUpb_UpbToPy(u_val, val_f, self->arena);
}
PyObject* PyUpb_MapContainer_Contains(PyObject* _self, PyObject* key) {
static PyObject* PyUpb_MapContainer_Contains(PyObject* _self, PyObject* key) {
PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self;
upb_Map* map = PyUpb_MapContainer_GetIfReified(self);
if (!map) Py_RETURN_FALSE;
@ -210,7 +211,7 @@ PyObject* PyUpb_MapContainer_Contains(PyObject* _self, PyObject* key) {
}
}
PyObject* PyUpb_MapContainer_Clear(PyObject* _self, PyObject* key) {
static PyObject* PyUpb_MapContainer_Clear(PyObject* _self, PyObject* key) {
upb_Map* map = PyUpb_MapContainer_EnsureReified(_self);
upb_Map_Clear(map);
Py_RETURN_NONE;
@ -252,13 +253,13 @@ static PyObject* PyUpb_MapContainer_GetEntryClass(PyObject* _self,
return PyUpb_Descriptor_GetClass(entry_m);
}
Py_ssize_t PyUpb_MapContainer_Length(PyObject* _self) {
static Py_ssize_t PyUpb_MapContainer_Length(PyObject* _self) {
PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self;
upb_Map* map = PyUpb_MapContainer_GetIfReified(self);
return map ? upb_Map_Size(map) : 0;
}
PyUpb_MapContainer* PyUpb_MapContainer_Check(PyObject* _self) {
static PyUpb_MapContainer* PyUpb_MapContainer_Check(PyObject* _self) {
PyUpb_ModuleState* state = PyUpb_ModuleState_Get();
if (!PyObject_TypeCheck(_self, state->message_map_container_type) &&
!PyObject_TypeCheck(_self, state->scalar_map_container_type)) {
@ -444,7 +445,7 @@ static void PyUpb_MapIterator_Dealloc(void* _self) {
PyUpb_Dealloc(_self);
}
PyObject* PyUpb_MapIterator_IterNext(PyObject* _self) {
static PyObject* PyUpb_MapIterator_IterNext(PyObject* _self) {
PyUpb_MapIterator* self = (PyUpb_MapIterator*)_self;
if (self->version != self->map->version) {
return PyErr_Format(PyExc_RuntimeError, "Map modified during iteration.");

@ -33,10 +33,6 @@ void PyUpb_MapContainer_Reify(PyObject* self, upb_Map* map);
// Reifies this map object if it is not already reified.
upb_Map* PyUpb_MapContainer_EnsureReified(PyObject* self);
// Assigns `self[key] = val` for the map `self`.
int PyUpb_MapContainer_AssignSubscript(PyObject* self, PyObject* key,
PyObject* val);
// Invalidates any existing iterators for the map `obj`.
void PyUpb_MapContainer_Invalidate(PyObject* obj);

@ -6,6 +6,7 @@
# https://developers.google.com/open-source/licenses/bsd
load(":pyproto_test_wrapper.bzl", "pyproto_test_wrapper")
# begin:github_only
load("@pip_deps//:requirements.bzl", "requirement")
# end:github_only
@ -39,15 +40,15 @@ py_test(
name = "numpy_test",
srcs = ["numpy_test_wrapper.py"],
main = "numpy_test_wrapper.py",
deps = [
requirement("numpy"),
"//python/google/protobuf/internal/numpy:numpy_test",
"//python:_message",
],
target_compatible_with = select({
"@system_python//:supported": [],
"//conditions:default": ["@platforms//:incompatible"],
"@system_python//:supported": [],
"//conditions:default": ["@platforms//:incompatible"],
}),
deps = [
requirement("numpy"),
"//python:_message",
"//python/google/protobuf/internal/numpy:numpy_test",
],
)
# end:github_only

@ -31,13 +31,6 @@
from google.protobuf.internal.message_test import *
import unittest
MessageTest.testExtendFloatWithNothing_proto2.__unittest_skip__ = True
MessageTest.testExtendFloatWithNothing_proto3.__unittest_skip__ = True
MessageTest.testExtendInt32WithNothing_proto2.__unittest_skip__ = True
MessageTest.testExtendInt32WithNothing_proto3.__unittest_skip__ = True
MessageTest.testExtendStringWithNothing_proto2.__unittest_skip__ = True
MessageTest.testExtendStringWithNothing_proto3.__unittest_skip__ = True
# Python/C++ customizes the C++ TextFormat to always print trailing ".0" for
# floats. upb doesn't do this, it matches C++ TextFormat.
MessageTest.testFloatPrinting_proto2.__unittest_expecting_failure__ = True

4
ruby/.gitignore vendored

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

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

Loading…
Cancel
Save