Merge branch 'master' into server-builder

pull/23182/head
Karthik Ravi Shankar 4 years ago
commit 31e6b69c8e
  1. 2
      .github/ISSUE_TEMPLATE/bug_report.md
  2. 2
      .github/ISSUE_TEMPLATE/cleanup_request.md
  3. 2
      .github/ISSUE_TEMPLATE/feature_request.md
  4. 2
      .github/ISSUE_TEMPLATE/question.md
  5. 2
      .github/pull_request_template.md
  6. 5
      BUILD
  7. 4
      BUILD.gn
  8. 85
      CMakeLists.txt
  9. 130
      Makefile
  10. 33
      build_autogenerated.yaml
  11. 2
      build_config.rb
  12. 2
      build_handwritten.yaml
  13. 2
      config.m4
  14. 2
      config.w32
  15. 2
      doc/PROTOCOL-WEB.md
  16. 10
      doc/core/combiner-explainer.md
  17. 2
      doc/core/epoll-polling-engine.md
  18. 2
      doc/core/grpc-client-server-polling-engine-usage.md
  19. 2
      doc/core/grpc-cq.md
  20. 6
      doc/core/moving-to-c++.md
  21. 2
      doc/environment_variables.md
  22. 2
      doc/fork_support.md
  23. 40
      doc/grpc_xds_features.md
  24. 1
      doc/health-checking.md
  25. 26
      doc/http2-interop-test-descriptions.md
  26. 2
      doc/internationalization.md
  27. 10
      doc/interop-test-descriptions.md
  28. 2
      doc/keepalive.md
  29. 4
      doc/python/server_reflection.md
  30. 4
      doc/python/sphinx/grpc.rst
  31. 8
      doc/security_audit.md
  32. 2
      doc/unit_testing.md
  33. 4
      doc/versioning.md
  34. 44
      doc/xds-test-descriptions.md
  35. 4
      examples/cpp/README.md
  36. 2
      examples/cpp/helloworld/README.md
  37. 2
      examples/cpp/route_guide/README.md
  38. 2
      examples/csharp/Helloworld/README.md
  39. 4
      examples/csharp/HelloworldLegacyCsproj/README.md
  40. 2
      examples/csharp/RouteGuide/README.md
  41. 2
      examples/node/README.md
  42. 2
      examples/node/dynamic_codegen/route_guide/README.md
  43. 2
      examples/node/static_codegen/route_guide/README.md
  44. 2
      examples/objective-c/auth_sample/README.md
  45. 2
      examples/objective-c/helloworld/README.md
  46. 2
      examples/objective-c/route_guide/README.md
  47. 2
      examples/php/README.md
  48. 2
      examples/php/route_guide/README.md
  49. 2
      examples/python/README.md
  50. 2
      examples/python/helloworld/README.md
  51. 2
      examples/python/metadata/README.md
  52. 2
      examples/python/multiplex/README.md
  53. 2
      examples/python/route_guide/README.md
  54. 2
      examples/ruby/README.md
  55. 2
      examples/ruby/route_guide/README.md
  56. 3
      gRPC-C++.podspec
  57. 4
      gRPC-Core.podspec
  58. 3
      grpc.gemspec
  59. 6
      grpc.gyp
  60. 6
      include/grpc/impl/codegen/grpc_types.h
  61. 25
      include/grpc/impl/codegen/port_platform.h
  62. 545
      include/grpcpp/impl/codegen/client_callback_impl.h
  63. 18
      include/grpcpp/impl/codegen/server_context_impl.h
  64. 3
      package.xml
  65. 4
      requirements.bazel.txt
  66. 2
      requirements.txt
  67. 4
      setup.py
  68. 5
      src/compiler/objective_c_plugin.cc
  69. 588
      src/core/ext/filters/client_channel/client_channel.cc
  70. 62
      src/core/ext/filters/client_channel/config_selector.cc
  71. 91
      src/core/ext/filters/client_channel/config_selector.h
  72. 61
      src/core/ext/filters/client_channel/resolving_lb_policy.cc
  73. 57
      src/core/ext/filters/client_channel/resolving_lb_policy.h
  74. 142
      src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc
  75. 7
      src/core/ext/filters/client_channel/xds/xds_api.cc
  76. 3
      src/core/ext/filters/http/http_filters_plugin.cc
  77. 92
      src/core/ext/filters/http/message_compress/message_decompress_filter.cc
  78. 4
      src/core/ext/filters/http/message_compress/message_decompress_filter.h
  79. 106
      src/core/ext/filters/message_size/message_size_filter.cc
  80. 6
      src/core/ext/filters/message_size/message_size_filter.h
  81. 724
      src/core/ext/transport/chttp2/server/chttp2_server.cc
  82. 8
      src/core/ext/transport/chttp2/server/chttp2_server.h
  83. 2
      src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc
  84. 2
      src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc
  85. 3
      src/core/ext/transport/chttp2/transport/chttp2_transport.cc
  86. 7
      src/core/ext/transport/chttp2/transport/internal.h
  87. 4
      src/core/ext/transport/chttp2/transport/writing.cc
  88. 43
      src/core/ext/transport/cronet/transport/cronet_transport.cc
  89. 3
      src/core/ext/transport/inproc/inproc_transport.cc
  90. 173
      src/core/ext/upb-generated/envoy/config/rbac/v2/rbac.upb.c
  91. 615
      src/core/ext/upb-generated/envoy/config/rbac/v2/rbac.upb.h
  92. 33
      src/core/ext/upb-generated/envoy/type/matcher/path.upb.c
  93. 72
      src/core/ext/upb-generated/envoy/type/matcher/path.upb.h
  94. 234
      src/core/ext/upb-generated/google/api/expr/v1alpha1/syntax.upb.c
  95. 760
      src/core/ext/upb-generated/google/api/expr/v1alpha1/syntax.upb.h
  96. 13
      src/core/lib/iomgr/port.h
  97. 8
      src/core/lib/iomgr/resource_quota.cc
  98. 2
      src/core/lib/security/security_connector/security_connector.cc
  99. 2
      src/core/lib/security/security_connector/security_connector.h
  100. 16
      src/core/lib/surface/call.cc
  101. Some files were not shown because too many files have changed in this diff Show More

@ -2,7 +2,7 @@
name: Report a bug
about: Create a report to help us improve
labels: kind/bug, priority/P2
assignees: veblush
assignees: nicolasnoble
---

@ -2,7 +2,7 @@
name: Request a cleanup
about: Suggest a cleanup in our repository
labels: kind/internal cleanup, priority/P2
assignees: donnadionne
assignees: nicolasnoble
---

@ -2,7 +2,7 @@
name: Request a feature
about: Suggest an idea for this project
labels: kind/enhancement, priority/P2
assignees: donnadionne
assignees: nicolasnoble
---

@ -2,7 +2,7 @@
name: Ask a question
about: Ask a question
labels: kind/question, priority/P3
assignees: donnadionne
assignees: nicolasnoble
---

@ -8,4 +8,4 @@ If you know who should review your pull request, please remove the mentioning be
-->
@donnadionne
@nicolasnoble

@ -124,6 +124,7 @@ GRPC_SECURE_PUBLIC_HDRS = [
# TODO(ctiller): layer grpc atop grpc_unsecure, layer grpc++ atop grpc++_unsecure
GRPCXX_SRCS = [
"src/cpp/client/channel_cc.cc",
"src/cpp/client/client_callback.cc",
"src/cpp/client/client_context.cc",
"src/cpp/client/client_interceptor.cc",
"src/cpp/client/create_channel.cc",
@ -1026,6 +1027,7 @@ grpc_cc_library(
"src/core/ext/filters/client_channel/client_channel_channelz.cc",
"src/core/ext/filters/client_channel/client_channel_factory.cc",
"src/core/ext/filters/client_channel/client_channel_plugin.cc",
"src/core/ext/filters/client_channel/config_selector.cc",
"src/core/ext/filters/client_channel/global_subchannel_pool.cc",
"src/core/ext/filters/client_channel/health/health_check_client.cc",
"src/core/ext/filters/client_channel/http_connect_handshaker.cc",
@ -1043,6 +1045,7 @@ grpc_cc_library(
"src/core/ext/filters/client_channel/retry_throttle.cc",
"src/core/ext/filters/client_channel/server_address.cc",
"src/core/ext/filters/client_channel/service_config.cc",
"src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc",
"src/core/ext/filters/client_channel/service_config_parser.cc",
"src/core/ext/filters/client_channel/subchannel.cc",
"src/core/ext/filters/client_channel/subchannel_pool_interface.cc",
@ -1053,6 +1056,7 @@ grpc_cc_library(
"src/core/ext/filters/client_channel/client_channel.h",
"src/core/ext/filters/client_channel/client_channel_channelz.h",
"src/core/ext/filters/client_channel/client_channel_factory.h",
"src/core/ext/filters/client_channel/config_selector.h",
"src/core/ext/filters/client_channel/connector.h",
"src/core/ext/filters/client_channel/global_subchannel_pool.h",
"src/core/ext/filters/client_channel/health/health_check_client.h",
@ -1183,6 +1187,7 @@ grpc_cc_library(
language = "c++",
deps = [
"grpc_base",
"grpc_message_size_filter",
],
)

@ -211,6 +211,8 @@ config("grpc_config") {
"src/core/ext/filters/client_channel/client_channel_factory.cc",
"src/core/ext/filters/client_channel/client_channel_factory.h",
"src/core/ext/filters/client_channel/client_channel_plugin.cc",
"src/core/ext/filters/client_channel/config_selector.cc",
"src/core/ext/filters/client_channel/config_selector.h",
"src/core/ext/filters/client_channel/connector.h",
"src/core/ext/filters/client_channel/global_subchannel_pool.cc",
"src/core/ext/filters/client_channel/global_subchannel_pool.h",
@ -293,6 +295,7 @@ config("grpc_config") {
"src/core/ext/filters/client_channel/service_config.cc",
"src/core/ext/filters/client_channel/service_config.h",
"src/core/ext/filters/client_channel/service_config_call_data.h",
"src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc",
"src/core/ext/filters/client_channel/service_config_parser.cc",
"src/core/ext/filters/client_channel/service_config_parser.h",
"src/core/ext/filters/client_channel/subchannel.cc",
@ -1219,6 +1222,7 @@ config("grpc_config") {
"include/grpcpp/support/time.h",
"include/grpcpp/support/validate_service_config.h",
"src/cpp/client/channel_cc.cc",
"src/cpp/client/client_callback.cc",
"src/cpp/client/client_context.cc",
"src/cpp/client/client_interceptor.cc",
"src/cpp/client/create_channel.cc",

@ -26,8 +26,8 @@ cmake_minimum_required(VERSION 3.5.1)
set(PACKAGE_NAME "grpc")
set(PACKAGE_VERSION "1.31.0-dev")
set(gRPC_CORE_VERSION "10.0.0")
set(gRPC_CORE_SOVERSION "10")
set(gRPC_CORE_VERSION "11.0.0")
set(gRPC_CORE_SOVERSION "11")
set(gRPC_CPP_VERSION "1.31.0-dev")
set(gRPC_CPP_SOVERSION "1")
set(gRPC_CSHARP_VERSION "2.31.0-dev")
@ -569,7 +569,6 @@ if(gRPC_BUILD_TESTS)
add_dependencies(buildtests_c secure_endpoint_test)
add_dependencies(buildtests_c security_connector_test)
add_dependencies(buildtests_c sequential_connectivity_test)
add_dependencies(buildtests_c server_chttp2_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c server_ssl_test)
endif()
@ -793,6 +792,7 @@ if(gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx server_builder_with_socket_mutator_test)
endif()
add_dependencies(buildtests_cxx server_chttp2_test)
add_dependencies(buildtests_cxx server_context_test_spouse_test)
add_dependencies(buildtests_cxx server_early_return_test)
add_dependencies(buildtests_cxx server_interceptors_end2end_test)
@ -1328,6 +1328,7 @@ add_library(grpc
src/core/ext/filters/client_channel/client_channel_channelz.cc
src/core/ext/filters/client_channel/client_channel_factory.cc
src/core/ext/filters/client_channel/client_channel_plugin.cc
src/core/ext/filters/client_channel/config_selector.cc
src/core/ext/filters/client_channel/global_subchannel_pool.cc
src/core/ext/filters/client_channel/health/health_check_client.cc
src/core/ext/filters/client_channel/http_connect_handshaker.cc
@ -1375,6 +1376,7 @@ add_library(grpc
src/core/ext/filters/client_channel/retry_throttle.cc
src/core/ext/filters/client_channel/server_address.cc
src/core/ext/filters/client_channel/service_config.cc
src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc
src/core/ext/filters/client_channel/service_config_parser.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_pool_interface.cc
@ -1999,6 +2001,7 @@ add_library(grpc_unsecure
src/core/ext/filters/client_channel/client_channel_channelz.cc
src/core/ext/filters/client_channel/client_channel_factory.cc
src/core/ext/filters/client_channel/client_channel_plugin.cc
src/core/ext/filters/client_channel/config_selector.cc
src/core/ext/filters/client_channel/global_subchannel_pool.cc
src/core/ext/filters/client_channel/health/health_check_client.cc
src/core/ext/filters/client_channel/http_connect_handshaker.cc
@ -2046,6 +2049,7 @@ add_library(grpc_unsecure
src/core/ext/filters/client_channel/retry_throttle.cc
src/core/ext/filters/client_channel/server_address.cc
src/core/ext/filters/client_channel/service_config.cc
src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc
src/core/ext/filters/client_channel/service_config_parser.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_pool_interface.cc
@ -2482,6 +2486,7 @@ endif()
add_library(grpc++
src/cpp/client/channel_cc.cc
src/cpp/client/client_callback.cc
src/cpp/client/client_context.cc
src/cpp/client/client_interceptor.cc
src/cpp/client/create_channel.cc
@ -3182,6 +3187,7 @@ endif()
add_library(grpc++_unsecure
src/cpp/client/channel_cc.cc
src/cpp/client/client_callback.cc
src/cpp/client/client_context.cc
src/cpp/client/client_interceptor.cc
src/cpp/client/create_channel.cc
@ -6826,35 +6832,6 @@ target_link_libraries(sequential_connectivity_test
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(server_chttp2_test
test/core/surface/server_chttp2_test.cc
)
target_include_directories(server_chttp2_test
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
${_gRPC_SSL_INCLUDE_DIR}
${_gRPC_UPB_GENERATED_DIR}
${_gRPC_UPB_GRPC_GENERATED_DIR}
${_gRPC_UPB_INCLUDE_DIR}
${_gRPC_ZLIB_INCLUDE_DIR}
)
target_link_libraries(server_chttp2_test
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
gpr
address_sorting
upb
)
endif()
if(gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
@ -13000,6 +12977,44 @@ endif()
endif()
if(gRPC_BUILD_TESTS)
add_executable(server_chttp2_test
test/core/surface/server_chttp2_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(server_chttp2_test
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
${_gRPC_SSL_INCLUDE_DIR}
${_gRPC_UPB_GENERATED_DIR}
${_gRPC_UPB_GRPC_GENERATED_DIR}
${_gRPC_UPB_INCLUDE_DIR}
${_gRPC_ZLIB_INCLUDE_DIR}
third_party/googletest/googletest/include
third_party/googletest/googletest
third_party/googletest/googlemock/include
third_party/googletest/googlemock
${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(server_chttp2_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
gpr
address_sorting
upb
${_gRPC_GFLAGS_LIBRARIES}
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(server_context_test_spouse_test
test/cpp/test/server_context_test_spouse_test.cc
third_party/googletest/googletest/src/gtest-all.cc
@ -15122,7 +15137,7 @@ include(CMakePackageConfigHelpers)
configure_file(cmake/gRPCConfig.cmake.in
gRPCConfig.cmake @ONLY)
write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/gRPCConfigVersion.cmake
VERSION ${PACKAGE_VERSION}
VERSION ${gRPC_CPP_VERSION}
COMPATIBILITY AnyNewerVersion)
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/gRPCConfig.cmake
@ -15189,7 +15204,7 @@ generate_pkgconfig(
generate_pkgconfig(
"gRPC++"
"C++ wrapper for gRPC"
"${PACKAGE_VERSION}"
"${gRPC_CPP_VERSION}"
"grpc"
"-lgrpc++ -labsl_bad_optional_access -labsl_str_format_internal -labsl_time -labsl_time_zone -labsl_civil_time -labsl_strings -labsl_strings_internal -labsl_throw_delegate -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_raw_logging_internal -labsl_log_severity -labsl_dynamic_annotations"
""
@ -15199,7 +15214,7 @@ generate_pkgconfig(
generate_pkgconfig(
"gRPC++ unsecure"
"C++ wrapper for gRPC without SSL"
"${PACKAGE_VERSION}"
"${gRPC_CPP_VERSION}"
"grpc_unsecure"
"-lgrpc++_unsecure -labsl_bad_optional_access -labsl_str_format_internal -labsl_time -labsl_time_zone -labsl_civil_time -labsl_strings -labsl_strings_internal -labsl_throw_delegate -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_raw_logging_internal -labsl_log_severity -labsl_dynamic_annotations"
""

@ -469,7 +469,7 @@ E = @echo
Q = @
endif
CORE_VERSION = 10.0.0
CORE_VERSION = 11.0.0
CPP_VERSION = 1.31.0-dev
CSHARP_VERSION = 2.31.0-dev
@ -519,7 +519,7 @@ SHARED_EXT_CORE = dll
SHARED_EXT_CPP = dll
SHARED_EXT_CSHARP = dll
SHARED_PREFIX =
SHARED_VERSION_CORE = -10
SHARED_VERSION_CORE = -11
SHARED_VERSION_CPP = -1
SHARED_VERSION_CSHARP = -2
else ifeq ($(SYSTEM),Darwin)
@ -1112,7 +1112,6 @@ secure_channel_create_test: $(BINDIR)/$(CONFIG)/secure_channel_create_test
secure_endpoint_test: $(BINDIR)/$(CONFIG)/secure_endpoint_test
security_connector_test: $(BINDIR)/$(CONFIG)/security_connector_test
sequential_connectivity_test: $(BINDIR)/$(CONFIG)/sequential_connectivity_test
server_chttp2_test: $(BINDIR)/$(CONFIG)/server_chttp2_test
server_ssl_test: $(BINDIR)/$(CONFIG)/server_ssl_test
server_test: $(BINDIR)/$(CONFIG)/server_test
slice_buffer_test: $(BINDIR)/$(CONFIG)/slice_buffer_test
@ -1269,6 +1268,7 @@ secure_auth_context_test: $(BINDIR)/$(CONFIG)/secure_auth_context_test
server_builder_plugin_test: $(BINDIR)/$(CONFIG)/server_builder_plugin_test
server_builder_test: $(BINDIR)/$(CONFIG)/server_builder_test
server_builder_with_socket_mutator_test: $(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test
server_chttp2_test: $(BINDIR)/$(CONFIG)/server_chttp2_test
server_context_test_spouse_test: $(BINDIR)/$(CONFIG)/server_context_test_spouse_test
server_early_return_test: $(BINDIR)/$(CONFIG)/server_early_return_test
server_fuzzer: $(BINDIR)/$(CONFIG)/server_fuzzer
@ -1487,7 +1487,6 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/secure_endpoint_test \
$(BINDIR)/$(CONFIG)/security_connector_test \
$(BINDIR)/$(CONFIG)/sequential_connectivity_test \
$(BINDIR)/$(CONFIG)/server_chttp2_test \
$(BINDIR)/$(CONFIG)/server_ssl_test \
$(BINDIR)/$(CONFIG)/server_test \
$(BINDIR)/$(CONFIG)/slice_buffer_test \
@ -1631,6 +1630,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/server_builder_plugin_test \
$(BINDIR)/$(CONFIG)/server_builder_test \
$(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test \
$(BINDIR)/$(CONFIG)/server_chttp2_test \
$(BINDIR)/$(CONFIG)/server_context_test_spouse_test \
$(BINDIR)/$(CONFIG)/server_early_return_test \
$(BINDIR)/$(CONFIG)/server_interceptors_end2end_test \
@ -1788,6 +1788,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/server_builder_plugin_test \
$(BINDIR)/$(CONFIG)/server_builder_test \
$(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test \
$(BINDIR)/$(CONFIG)/server_chttp2_test \
$(BINDIR)/$(CONFIG)/server_context_test_spouse_test \
$(BINDIR)/$(CONFIG)/server_early_return_test \
$(BINDIR)/$(CONFIG)/server_interceptors_end2end_test \
@ -2043,8 +2044,6 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/secure_endpoint_test || ( echo test secure_endpoint_test failed ; exit 1 )
$(E) "[RUN] Testing security_connector_test"
$(Q) $(BINDIR)/$(CONFIG)/security_connector_test || ( echo test security_connector_test failed ; exit 1 )
$(E) "[RUN] Testing server_chttp2_test"
$(Q) $(BINDIR)/$(CONFIG)/server_chttp2_test || ( echo test server_chttp2_test failed ; exit 1 )
$(E) "[RUN] Testing server_ssl_test"
$(Q) $(BINDIR)/$(CONFIG)/server_ssl_test || ( echo test server_ssl_test failed ; exit 1 )
$(E) "[RUN] Testing server_test"
@ -2299,6 +2298,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/server_builder_test || ( echo test server_builder_test failed ; exit 1 )
$(E) "[RUN] Testing server_builder_with_socket_mutator_test"
$(Q) $(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test || ( echo test server_builder_with_socket_mutator_test failed ; exit 1 )
$(E) "[RUN] Testing server_chttp2_test"
$(Q) $(BINDIR)/$(CONFIG)/server_chttp2_test || ( echo test server_chttp2_test failed ; exit 1 )
$(E) "[RUN] Testing server_context_test_spouse_test"
$(Q) $(BINDIR)/$(CONFIG)/server_context_test_spouse_test || ( echo test server_context_test_spouse_test failed ; exit 1 )
$(E) "[RUN] Testing server_early_return_test"
@ -3042,7 +3043,7 @@ install-shared_c: shared_c strip-shared_c install-pkg-config_c
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE)-dll.a $(prefix)/lib/libaddress_sorting.a
else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libaddress_sorting.so.10
$(Q) ln -sf $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libaddress_sorting.so.11
$(Q) ln -sf $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libaddress_sorting.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)"
@ -3051,7 +3052,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE)-dll.a $(prefix)/lib/libgpr.a
else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgpr.so.10
$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgpr.so.11
$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgpr.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)"
@ -3060,7 +3061,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE)-dll.a $(prefix)/lib/libgrpc.a
else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc.so.10
$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc.so.11
$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)"
@ -3069,7 +3070,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE)-dll.a $(prefix)/lib/libgrpc_csharp_ext.a
else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_csharp_ext.so.10
$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_csharp_ext.so.11
$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_csharp_ext.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)"
@ -3078,7 +3079,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE)-dll.a $(prefix)/lib/libgrpc_unsecure.a
else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_unsecure.so.10
$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_unsecure.so.11
$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_unsecure.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)"
@ -3087,7 +3088,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libupb$(SHARED_VERSION_CORE)-dll.a $(prefix)/lib/libupb.a
else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libupb.so.10
$(Q) ln -sf $(SHARED_PREFIX)upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libupb.so.11
$(Q) ln -sf $(SHARED_PREFIX)upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libupb.so
endif
ifneq ($(SYSTEM),MINGW32)
@ -3248,8 +3249,8 @@ $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE):
ifeq ($(SYSTEM),Darwin)
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBADDRESS_SORTING_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
else
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libaddress_sorting.so.10 -o $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBADDRESS_SORTING_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).so.10
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libaddress_sorting.so.11 -o $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBADDRESS_SORTING_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).so.11
$(Q) ln -sf $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).so
endif
endif
@ -3610,8 +3611,8 @@ $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGPR_OB
ifeq ($(SYSTEM),Darwin)
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
else
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgpr.so.10 -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so.10
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgpr.so.11 -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so.11
$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so
endif
endif
@ -3630,6 +3631,7 @@ LIBGRPC_SRC = \
src/core/ext/filters/client_channel/client_channel_channelz.cc \
src/core/ext/filters/client_channel/client_channel_factory.cc \
src/core/ext/filters/client_channel/client_channel_plugin.cc \
src/core/ext/filters/client_channel/config_selector.cc \
src/core/ext/filters/client_channel/global_subchannel_pool.cc \
src/core/ext/filters/client_channel/health/health_check_client.cc \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \
@ -3677,6 +3679,7 @@ LIBGRPC_SRC = \
src/core/ext/filters/client_channel/retry_throttle.cc \
src/core/ext/filters/client_channel/server_address.cc \
src/core/ext/filters/client_channel/service_config.cc \
src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc \
src/core/ext/filters/client_channel/service_config_parser.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_pool_interface.cc \
@ -4092,8 +4095,8 @@ $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_
ifeq ($(SYSTEM),Darwin)
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) -lgpr -laddress_sorting -lupb
else
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc.so.10 -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) -lgpr -laddress_sorting -lupb
$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so.10
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc.so.11 -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) -lgpr -laddress_sorting -lupb
$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so.11
$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so
endif
endif
@ -4149,8 +4152,8 @@ $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE):
ifeq ($(SYSTEM),Darwin)
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CSHARP_EXT_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) -lgrpc -lgpr -laddress_sorting -lupb
else
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_csharp_ext.so.10 -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CSHARP_EXT_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) -lgrpc -lgpr -laddress_sorting -lupb
$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).so.10
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_csharp_ext.so.11 -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CSHARP_EXT_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) -lgrpc -lgpr -laddress_sorting -lupb
$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).so.11
$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).so
endif
endif
@ -4275,6 +4278,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/filters/client_channel/client_channel_channelz.cc \
src/core/ext/filters/client_channel/client_channel_factory.cc \
src/core/ext/filters/client_channel/client_channel_plugin.cc \
src/core/ext/filters/client_channel/config_selector.cc \
src/core/ext/filters/client_channel/global_subchannel_pool.cc \
src/core/ext/filters/client_channel/health/health_check_client.cc \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \
@ -4322,6 +4326,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/filters/client_channel/retry_throttle.cc \
src/core/ext/filters/client_channel/server_address.cc \
src/core/ext/filters/client_channel/service_config.cc \
src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc \
src/core/ext/filters/client_channel/service_config_parser.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_pool_interface.cc \
@ -4650,8 +4655,8 @@ $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $
ifeq ($(SYSTEM),Darwin)
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) -lgpr -laddress_sorting -lupb
else
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_unsecure.so.10 -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) -lgpr -laddress_sorting -lupb
$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so.10
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_unsecure.so.11 -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) -lgpr -laddress_sorting -lupb
$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so.11
$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so
endif
endif
@ -4717,6 +4722,7 @@ $(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/helpers.o: $(GENDIR)/src/proto/grpc
LIBGRPC++_SRC = \
src/cpp/client/channel_cc.cc \
src/cpp/client/client_callback.cc \
src/cpp/client/client_context.cc \
src/cpp/client/client_interceptor.cc \
src/cpp/client/create_channel.cc \
@ -5422,6 +5428,7 @@ endif
LIBGRPC++_UNSECURE_SRC = \
src/cpp/client/channel_cc.cc \
src/cpp/client/client_callback.cc \
src/cpp/client/client_context.cc \
src/cpp/client/client_interceptor.cc \
src/cpp/client/create_channel.cc \
@ -6269,8 +6276,8 @@ $(LIBDIR)/$(CONFIG)/libupb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBUPB_OB
ifeq ($(SYSTEM),Darwin)
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libupb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBUPB_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
else
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libupb.so.10 -o $(LIBDIR)/$(CONFIG)/libupb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBUPB_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libupb$(SHARED_VERSION_CORE).so.10
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libupb.so.11 -o $(LIBDIR)/$(CONFIG)/libupb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBUPB_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libupb$(SHARED_VERSION_CORE).so.11
$(Q) ln -sf $(SHARED_PREFIX)upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libupb$(SHARED_VERSION_CORE).so
endif
endif
@ -10052,38 +10059,6 @@ endif
endif
SERVER_CHTTP2_TEST_SRC = \
test/core/surface/server_chttp2_test.cc \
SERVER_CHTTP2_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SERVER_CHTTP2_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/server_chttp2_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/server_chttp2_test: $(SERVER_CHTTP2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(SERVER_CHTTP2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/server_chttp2_test
endif
$(OBJDIR)/$(CONFIG)/test/core/surface/server_chttp2_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a
deps_server_chttp2_test: $(SERVER_CHTTP2_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(SERVER_CHTTP2_TEST_OBJS:.o=.dep)
endif
endif
SERVER_SSL_TEST_SRC = \
test/core/handshake/server_ssl.cc \
test/core/handshake/server_ssl_common.cc \
@ -17219,6 +17194,49 @@ endif
$(OBJDIR)/$(CONFIG)/test/cpp/server/server_builder_with_socket_mutator_test.o: $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
SERVER_CHTTP2_TEST_SRC = \
test/core/surface/server_chttp2_test.cc \
SERVER_CHTTP2_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SERVER_CHTTP2_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/server_chttp2_test: openssl_dep_error
else
ifeq ($(NO_PROTOBUF),true)
# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/server_chttp2_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/server_chttp2_test: $(PROTOBUF_DEP) $(SERVER_CHTTP2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(SERVER_CHTTP2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_chttp2_test
endif
endif
$(OBJDIR)/$(CONFIG)/test/core/surface/server_chttp2_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a
deps_server_chttp2_test: $(SERVER_CHTTP2_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(SERVER_CHTTP2_TEST_OBJS:.o=.dep)
endif
endif
SERVER_CONTEXT_TEST_SPOUSE_TEST_SRC = \
test/cpp/test/server_context_test_spouse_test.cc \

@ -377,6 +377,7 @@ libs:
- src/core/ext/filters/client_channel/client_channel.h
- src/core/ext/filters/client_channel/client_channel_channelz.h
- src/core/ext/filters/client_channel/client_channel_factory.h
- src/core/ext/filters/client_channel/config_selector.h
- src/core/ext/filters/client_channel/connector.h
- src/core/ext/filters/client_channel/global_subchannel_pool.h
- src/core/ext/filters/client_channel/health/health_check_client.h
@ -746,6 +747,7 @@ libs:
- src/core/ext/filters/client_channel/client_channel_channelz.cc
- src/core/ext/filters/client_channel/client_channel_factory.cc
- src/core/ext/filters/client_channel/client_channel_plugin.cc
- src/core/ext/filters/client_channel/config_selector.cc
- src/core/ext/filters/client_channel/global_subchannel_pool.cc
- src/core/ext/filters/client_channel/health/health_check_client.cc
- src/core/ext/filters/client_channel/http_connect_handshaker.cc
@ -793,6 +795,7 @@ libs:
- src/core/ext/filters/client_channel/retry_throttle.cc
- src/core/ext/filters/client_channel/server_address.cc
- src/core/ext/filters/client_channel/service_config.cc
- src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc
- src/core/ext/filters/client_channel/service_config_parser.cc
- src/core/ext/filters/client_channel/subchannel.cc
- src/core/ext/filters/client_channel/subchannel_pool_interface.cc
@ -1300,6 +1303,7 @@ libs:
- src/core/ext/filters/client_channel/client_channel.h
- src/core/ext/filters/client_channel/client_channel_channelz.h
- src/core/ext/filters/client_channel/client_channel_factory.h
- src/core/ext/filters/client_channel/config_selector.h
- src/core/ext/filters/client_channel/connector.h
- src/core/ext/filters/client_channel/global_subchannel_pool.h
- src/core/ext/filters/client_channel/health/health_check_client.h
@ -1605,6 +1609,7 @@ libs:
- src/core/ext/filters/client_channel/client_channel_channelz.cc
- src/core/ext/filters/client_channel/client_channel_factory.cc
- src/core/ext/filters/client_channel/client_channel_plugin.cc
- src/core/ext/filters/client_channel/config_selector.cc
- src/core/ext/filters/client_channel/global_subchannel_pool.cc
- src/core/ext/filters/client_channel/health/health_check_client.cc
- src/core/ext/filters/client_channel/http_connect_handshaker.cc
@ -1652,6 +1657,7 @@ libs:
- src/core/ext/filters/client_channel/retry_throttle.cc
- src/core/ext/filters/client_channel/server_address.cc
- src/core/ext/filters/client_channel/service_config.cc
- src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc
- src/core/ext/filters/client_channel/service_config_parser.cc
- src/core/ext/filters/client_channel/subchannel.cc
- src/core/ext/filters/client_channel/subchannel_pool_interface.cc
@ -2203,6 +2209,7 @@ libs:
- src/cpp/thread_manager/thread_manager.h
src:
- src/cpp/client/channel_cc.cc
- src/cpp/client/client_callback.cc
- src/cpp/client/client_context.cc
- src/cpp/client/client_interceptor.cc
- src/cpp/client/create_channel.cc
@ -2592,6 +2599,7 @@ libs:
- src/cpp/thread_manager/thread_manager.h
src:
- src/cpp/client/channel_cc.cc
- src/cpp/client/client_callback.cc
- src/cpp/client/client_context.cc
- src/cpp/client/client_interceptor.cc
- src/cpp/client/create_channel.cc
@ -4134,18 +4142,6 @@ targets:
- gpr
- address_sorting
- upb
- name: server_chttp2_test
build: test
language: c
headers: []
src:
- test/core/surface/server_chttp2_test.cc
deps:
- grpc_test_util
- grpc
- gpr
- address_sorting
- upb
- name: server_ssl_test
build: test
language: c
@ -6930,6 +6926,19 @@ targets:
- linux
- posix
- mac
- name: server_chttp2_test
gtest: true
build: test
language: c++
headers: []
src:
- test/core/surface/server_chttp2_test.cc
deps:
- grpc_test_util
- grpc
- gpr
- address_sorting
- upb
- name: server_context_test_spouse_test
gtest: true
build: test

@ -13,5 +13,5 @@
# limitations under the License.
module GrpcBuildConfig
CORE_WINDOWS_DLL = '/tmp/libs/opt/grpc-10.dll'
CORE_WINDOWS_DLL = '/tmp/libs/opt/grpc-11.dll'
end

@ -12,7 +12,7 @@ settings:
'#08': Use "-preN" suffixes to identify pre-release versions
'#09': Per-language overrides are possible with (eg) ruby_version tag here
'#10': See the expand_version.py for all the quirks here
core_version: 10.0.0
core_version: 11.0.0
csharp_major_version: 2
g_stands_for: galore
version: 1.31.0-dev

@ -45,6 +45,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/filters/client_channel/client_channel_channelz.cc \
src/core/ext/filters/client_channel/client_channel_factory.cc \
src/core/ext/filters/client_channel/client_channel_plugin.cc \
src/core/ext/filters/client_channel/config_selector.cc \
src/core/ext/filters/client_channel/global_subchannel_pool.cc \
src/core/ext/filters/client_channel/health/health_check_client.cc \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \
@ -92,6 +93,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/filters/client_channel/retry_throttle.cc \
src/core/ext/filters/client_channel/server_address.cc \
src/core/ext/filters/client_channel/service_config.cc \
src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc \
src/core/ext/filters/client_channel/service_config_parser.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_pool_interface.cc \

@ -14,6 +14,7 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\filters\\client_channel\\client_channel_channelz.cc " +
"src\\core\\ext\\filters\\client_channel\\client_channel_factory.cc " +
"src\\core\\ext\\filters\\client_channel\\client_channel_plugin.cc " +
"src\\core\\ext\\filters\\client_channel\\config_selector.cc " +
"src\\core\\ext\\filters\\client_channel\\global_subchannel_pool.cc " +
"src\\core\\ext\\filters\\client_channel\\health\\health_check_client.cc " +
"src\\core\\ext\\filters\\client_channel\\http_connect_handshaker.cc " +
@ -61,6 +62,7 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\filters\\client_channel\\retry_throttle.cc " +
"src\\core\\ext\\filters\\client_channel\\server_address.cc " +
"src\\core\\ext\\filters\\client_channel\\service_config.cc " +
"src\\core\\ext\\filters\\client_channel\\service_config_channel_arg_filter.cc " +
"src\\core\\ext\\filters\\client_channel\\service_config_parser.cc " +
"src\\core\\ext\\filters\\client_channel\\subchannel.cc " +
"src\\core\\ext\\filters\\client_channel\\subchannel_pool_interface.cc " +

@ -17,7 +17,7 @@ with the protocol details specified in the
For the gRPC-Web protocol, we have decided on the following design goals:
* adopt the same framing as “application/grpc” whenever possible
* decouple from HTTP/2 framing which is not, and will never, be directly
* decouple from HTTP/2 framing which is not, and will never be, directly
exposed by browsers
* support text streams (e.g. base64) in order to provide cross-browser
support (e.g. IE-10)

@ -41,9 +41,9 @@ Instead, get a new property:
class combiner {
mpscq q; // multi-producer single-consumer queue can be made non-blocking
state s; // is it empty or executing
run(f) {
if (q.push(f)) {
if (q.push(f)) {
// q.push returns true if it's the first thing
while (q.pop(&f)) { // modulo some extra work to avoid races
f();
@ -73,9 +73,9 @@ class combiner {
mpscq q; // multi-producer single-consumer queue can be made non-blocking
state s; // is it empty or executing
queue finally; // you can only do run_finally when you are already running something from the combiner
run(f) {
if (q.push(f)) {
if (q.push(f)) {
// q.push returns true if it's the first thing
loop:
while (q.pop(&f)) { // modulo some extra work to avoid races
@ -127,7 +127,7 @@ tries to spray events onto as many threads as possible to get as much concurrenc
So `offload` really does:
```
```
workqueue.run(continue_from_while_loop);
break;
```

@ -104,7 +104,7 @@ void grpc_use_signal(int signal_num)
If the calling application does not provide a signal number, then the gRPC library will relegate to using a model similar to the current implementation (where every thread does a blocking `poll()` on its `wakeup_fd` and the `epoll_fd`). The function` psi_wait() `in figure 2 implements this logic.
**>> **(**NOTE**: Or alternatively, we can implement a turnstile polling (i.e having only one thread calling `epoll_wait()` on the epoll set at any time - which all other threads call poll on their `wakeup_fds`)
**>> **(**NOTE**: Or alternatively, we can implement a turnstile polling (i.e having only one thread calling `epoll_wait()` on the epoll set at any time - which all other threads call poll on their `wakeup_fds`)
in case of not getting a signal number from the applications.

@ -7,7 +7,7 @@ This document talks about how polling engine is used in gRPC core (both on clien
## gRPC client
### Relation between Call, Channel (sub-channels), Completion queue, `grpc_pollset`
### Relation between Call, Channel (sub-channels), Completion queue, `grpc_pollset`
- A gRPC Call is tied to a channel (more specifically a sub-channel) and a completion queue for the lifetime of the call.
- Once a _sub-channel_ is picked for the call, the file-descriptor (socket fd in case of TCP channels) is added to the pollset corresponding to call's completion queue. (Recall that as per [grpc-cq](grpc-cq.md), a completion queue has a pollset by default)

@ -61,4 +61,4 @@ grpc_cq_end_op(cq, tag) {
}
```

@ -11,7 +11,7 @@ gRPC core was originally written in C89 for several reasons
support, etc). Over time, this was changed to C99 as all relevant
compilers in active use came to support C99 effectively.
gRPC started allowing to use C++ with a couple of exceptions not to
gRPC started allowing to use C++ with a couple of exceptions not to
have C++ library linked such as `libstdc++.so`.
(For more detail, see the [proposal](https://github.com/grpc/proposal/blob/master/L6-core-allow-cpp.md))
@ -25,12 +25,12 @@ C++ compatible with
## Constraints
- Most of features available in C++11 are allowed to use but there are some exceptions
- Most of features available in C++11 are allowed to use but there are some exceptions
because gRPC should support old systems.
- Should be built with gcc 4.8, clang 3.3, and Visual C++ 2015.
- Should be run on Linux system with libstdc++ 6.0.9 to support
[manylinux1](https://www.python.org/dev/peps/pep-0513).
- This would limit us not to use modern C++11 standard library such as `filesystem`.
- This would limit us not to use modern C++11 standard library such as `filesystem`.
You can easily see whether PR is free from this issue by checking the result of
`Artifact Build Linux` test.
- `thread_local` is not allowed to use on Apple's products because their old OSes

@ -73,7 +73,7 @@ some configuration as environment variables that can be set.
completion queue
- pick_first - traces the pick first load balancing policy
- plugin_credentials - traces plugin credentials
- pollable_refcount - traces reference counting of 'pollable' objects (only
- pollable_refcount - traces reference counting of 'pollable' objects (only
in DEBUG)
- priority_lb - traces priority LB policy
- resource_quota - trace resource quota objects internals

@ -25,7 +25,7 @@ A regression was noted in cases where users are doing fork/exec. This
was due to ```pthread_atfork()``` handler that was added in 1.7 to partially
support forking in gRPC. A deadlock can happen when pthread_atfork
handler is running, and an application thread is calling into gRPC.
We have provided a workaround for this issue by allowing users to turn
We have provided a workaround for this issue by allowing users to turn
off the handler using env flag ```GRPC_ENABLE_FORK_SUPPORT=False```.
This should be set whenever a user expects to always call exec
immediately following fork. It will disable the fork handlers.

@ -0,0 +1,40 @@
# xDS Features in gRPC
This document lists the [xDS](https://github.com/envoyproxy/data-plane-api/tree/master/envoy/api/v2)
features supported in various gRPC language implementations and versions.
Note that a gRPC client will simply ignore the configuration of a feature it
does not support. The gRPC client does not generate a log
to indicate that some configuration was ignored. It is impractical to generate
a log and keep it up-to-date because xDS has a large number of APIs that gRPC
does not support and the APIs keep evolving too. We recommend reading the
[first gRFC](https://github.com/grpc/proposal/blob/master/A27-xds-global-load-balancing.md)
on xDS support in gRPC to understand the design philosophy.
The EDS policy will *not* support
[overprovisioning](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/overprovisioning),
which is different from Envoy. Envoy takes the overprovisioning into
account in both [locality-weighted load balancing](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/locality_weight)
and [priority failover](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/priority),
but gRPC assumes that the xDS server will update it to redirect traffic
when this kind of graceful failover is needed. gRPC will send the
[`envoy.lb.does_not_support_overprovisioning` client
feature](https://github.com/envoyproxy/envoy/pull/10136) to the xDS
server to tell the xDS server that it will not perform graceful failover;
xDS server implementations may use this to decide whether to perform
graceful failover themselves.
The EDS policy will not support per-endpoint stats; it will report only
per-locality stats.
An [`lb_endpoint`](https://github.com/envoyproxy/envoy/blob/12a4bc430eaf440ceb0d11286cfbd4c16b79cdd1/api/envoy/api/v2/endpoint/endpoint_components.proto#L72)
is ignored if the `health_status` is not HEALTHY or UNKNOWN.
The optional `load_balancing_weight` is always ignored.
Initially, only `google_default` channel creds will be supported
to authenticate with the xDS server.
Features | gRFCs | [C++, Python,<br> Ruby, PHP, C#](https://github.com/grpc/grpc/releases) | [Java](https://github.com/grpc/grpc-java/releases) | [Go](https://github.com/grpc/grpc-go/releases)
---------|--------|--------------|------|------
**xDS Infrastructure in gRPC client channel:**<br>LDS->RDS->CDS->EDS flow,<br>ADS stream, | [A27](https://github.com/grpc/proposal/blob/master/A27-xds-global-load-balancing.md) | v1.30.0 | v1.30.0 | v1.30.0 |
**Load Balancing:**<br>Virtual host matching,<br>Only default path ("" or "/") matching,<br>Priority-based weighted round-robin locality picking,<br>Round-robin endpoint picking within locality,<br>Cluster route action,<br>Client-side Load reporting via [LRS](https://github.com/envoyproxy/data-plane-api/blob/master/envoy/service/load_stats/v2/lrs.proto)| [A27](https://github.com/grpc/proposal/blob/master/A27-xds-global-load-balancing.md) | v1.30.0 | v1.30.0 | v1.30.0 |

@ -37,6 +37,7 @@ message HealthCheckResponse {
UNKNOWN = 0;
SERVING = 1;
NOT_SERVING = 2;
SERVICE_UNKNOWN = 3; // Used only by the Watch method.
}
ServingStatus status = 1;
}

@ -8,7 +8,7 @@ Server
------
The code for the custom http2 server can be found
[here](https://github.com/grpc/grpc/tree/master/test/http2_test).
It is responsible for handling requests and sending responses, and also for
It is responsible for handling requests and sending responses, and also for
fulfilling the behavior of each particular test case.
Server should accept these arguments:
@ -51,7 +51,7 @@ the user application having to do a thing.
Client Procedure:
1. Client sends two UnaryCall requests (and sleeps for 1 second in-between).
TODO: resolve [9300](https://github.com/grpc/grpc/issues/9300) and remove the 1 second sleep
```
{
response_size: 314159
@ -78,7 +78,7 @@ RST_STREAM immediately after sending headers to the client.
Procedure:
1. Client sends UnaryCall with:
```
{
response_size: 314159
@ -93,7 +93,7 @@ Client asserts:
Server Procedure:
1. Server sends a RST_STREAM with error code 0 after sending headers to the client.
*At the moment the error code and message returned are not standardized throughout all
languages. Those checks will be added once all client languages behave the same way. [#9142](https://github.com/grpc/grpc/issues/9142) is in flight.*
@ -104,7 +104,7 @@ RST_STREAM halfway through sending data to the client.
Procedure:
1. Client sends UnaryCall with:
```
{
response_size: 314159
@ -118,7 +118,7 @@ Client asserts:
* Call was not successful.
Server Procedure:
1. Server sends a RST_STREAM with error code 0 after sending half of
1. Server sends a RST_STREAM with error code 0 after sending half of
the requested data to the client.
### rst_after_data
@ -128,7 +128,7 @@ RST_STREAM after sending all of the data to the client.
Procedure:
1. Client sends UnaryCall with:
```
{
response_size: 314159
@ -156,7 +156,7 @@ server.
Procedure:
1. Client sends UnaryCall with:
```
{
response_size: 314159
@ -165,16 +165,16 @@ Procedure:
}
}
```
Client asserts:
* call was successful.
* response payload body is 314159 bytes in size.
Server Procedure:
1. Server tracks the number of outstanding pings (i.e. +1 when it sends a ping, and -1
1. Server tracks the number of outstanding pings (i.e. +1 when it sends a ping, and -1
when it receives an ack from the client).
2. Server sends pings before and after sending headers, also before and after sending data.
Server Asserts:
* Number of outstanding pings is 0 when the connection is lost.
@ -185,10 +185,10 @@ This test verifies that the client observes the MAX_CONCURRENT_STREAMS limit set
Client Procedure:
1. Client sends initial UnaryCall to allow the server to update its MAX_CONCURRENT_STREAMS settings.
2. Client concurrently sends 10 UnaryCalls.
Client Asserts:
* All UnaryCalls were successful, and had the correct type and payload size.
Server Procedure:
1. Sets MAX_CONCURRENT_STREAMS to one after the connection is made.

@ -1,7 +1,7 @@
gRPC Internationalization
=========================
As a universal RPC framework, gRPC needs to be fully usable within/across different international environments.
As a universal RPC framework, gRPC needs to be fully usable within/across different international environments.
This document describes gRPC API and behavior specifics when used in a non-english environment.
## API Concepts

@ -1007,21 +1007,21 @@ languages. Therefore they are not part of our interop matrix.
#### rpc_soak
The client performs many large_unary RPCs in sequence over the same channel.
The client performs many large_unary RPCs in sequence over the same channel.
The number of RPCs is configured by the experimental flag, `soak_iterations`.
#### channel_soak
The client performs many large_unary RPCs in sequence. Before each RPC, it
tears down and rebuilds the channel. The number of RPCs is configured by
The client performs many large_unary RPCs in sequence. Before each RPC, it
tears down and rebuilds the channel. The number of RPCs is configured by
the experimental flag, `soak_iterations`.
This tests puts stress on several gRPC components; the resolver, the load
This tests puts stress on several gRPC components; the resolver, the load
balancer, and the RPC hotpath.
#### long_lived_channel
The client performs a number of large_unary RPCs over a single long-lived
The client performs a number of large_unary RPCs over a single long-lived
channel with a fixed but configurable interval between each RPC.
### TODO Tests

@ -14,7 +14,7 @@ The keepalive ping is controlled by two important channel arguments -
The above two channel arguments should be sufficient for most users, but the following arguments can also be useful in certain use cases.
* **GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS**
* This channel argument if set to 1 (0 : false; 1 : true), allows keepalive pings to be sent even if there are no calls in flight.
* This channel argument if set to 1 (0 : false; 1 : true), allows keepalive pings to be sent even if there are no calls in flight.
* **GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA**
* This channel argument controls the maximum number of pings that can be sent when there is no data/header frame to be sent. GRPC Core will not continue sending pings if we run over the limit. Setting it to 0 allows sending pings without such a restriction.
* **GRPC_ARG_HTTP2_MIN_SENT_PING_INTERVAL_WITHOUT_DATA_MS**

@ -6,7 +6,7 @@ and more examples how to use server reflection.
## Enable server reflection in Python servers
gRPC Python Server Reflection is an add-on library. To use it, first install
gRPC Python Server Reflection is an add-on library. To use it, first install
the [grpcio-reflection] PyPI package into your project.
Note that with Python you need to manually register the service
@ -29,7 +29,7 @@ def serve():
server.start()
```
Please see [greeter_server_with_reflection.py] in the examples directory for the full
Please see [greeter_server_with_reflection.py] in the examples directory for the full
example, which extends the gRPC [Python `Greeter` example] on a reflection-enabled server.
After starting the server, you can verify that the server reflection

@ -6,8 +6,8 @@ gRPC
Tutorial
--------
If you want to see gRPC in action first, visit the `Python Quickstart <https://grpc.io/docs/quickstart/python.html>`_.
Or, if you would like dive in with more extensive usage of gRPC Python, check `gRPC Basics - Python <https://grpc.io/docs/tutorials/basic/python.html>`_ out.
If you want to see gRPC in action first, visit the `Python Quickstart <https://grpc.io/docs/languages/python/quickstart>`_.
Or, if you would like dive in with more extensive usage of gRPC Python, check `gRPC Basics - Python <https://grpc.io/docs/languages/python/basics>`_ out.
Example

@ -1,6 +1,6 @@
# gRPC Security Audit
A third-party security audit of gRPC C++ stack was performed by [Cure53](https://cure53.de) in October 2019. The full report can be found [here](https://github.com/grpc/grpc/tree/master/doc/grpc_security_audit.pdf).
A third-party security audit of gRPC C++ stack was performed by [Cure53](https://cure53.de) in October 2019. The full report can be found [here](https://github.com/grpc/grpc/tree/master/doc/grpc_security_audit.pdf).
# Addressing grpc_security_audit
@ -21,7 +21,7 @@ Below is a list of alternatives that gRPC team considered.
### Alternative #1: Rewrite gpr_free to take void\*\*
One solution is to change the API of `gpr_free` so that it automatically nulls the given pointer after freeing it.
One solution is to change the API of `gpr_free` so that it automatically nulls the given pointer after freeing it.
```
gpr_free (void** ptr) {
@ -30,7 +30,7 @@ gpr_free (void** ptr) {
}
```
This defensive programming pattern would help protect gRPC from the potential exploits and latent dangling pointer bugs mentioned in the security report.
This defensive programming pattern would help protect gRPC from the potential exploits and latent dangling pointer bugs mentioned in the security report.
However, performance would be a significant concern as we are now unconditionally adding a store to every gpr_free call, and there are potentially hundreds of these per RPC. At the RPC layer, this can add up to prohibitive costs.
@ -61,7 +61,7 @@ Because of performance and maintainability concerns, GRP-01-002 will be addresse
## GRP-01-003 Calls to malloc suffer from potential integer overflows
The vulnerability, as defined by the report, is that calls to `gpr_malloc` in the C-core codebase may suffer from potential integer overflow in cases where we multiply the array element size by the size of the array. The penetration testers did not identify a concrete place where this occurred, but rather emphasized that the coding pattern itself had potential to lead to vulnerabilities. The report’s suggested solution for GRP-01-003 was to create a `calloc(size_t nmemb, size_t size)` wrapper that contains integer overflow checks.
However, gRPC team firmly believes that gRPC Core should only use integer overflow checks in the places where they’re needed; for example, any place where remote input influences the input to `gpr_malloc` in an unverified way. This is because bounds-checking is very expensive at the RPC layer.
However, gRPC team firmly believes that gRPC Core should only use integer overflow checks in the places where they’re needed; for example, any place where remote input influences the input to `gpr_malloc` in an unverified way. This is because bounds-checking is very expensive at the RPC layer.
Determining exactly where bounds-checking is needed requires an audit of tracing each `gpr_malloc` (or `gpr_realloc` or `gpr_zalloc`) call up the stack to determine if the sufficient bounds-checking was performed. This kind of audit, done manually, is fairly expensive engineer-wise.

@ -75,7 +75,7 @@ grpc_proto_library(
```
By adding such a flag now a header file `echo_mock.grpc.pb.h` containing the mocked stub will also be generated.
By adding such a flag now a header file `echo_mock.grpc.pb.h` containing the mocked stub will also be generated.
This header file can then be included in test files along with a gmock dependency.

@ -3,7 +3,7 @@
## Versioning Overview
All gRPC implementations use a three-part version number (`vX.Y.Z`) and follow [semantic versioning](https://semver.org/), which defines the semantics of major, minor and patch components of the version number. In addition to that, gRPC versions evolve according to these rules:
- **Major version bumps** only happen on rare occasions. In order to qualify for a major version bump, certain criteria described later in this document need to be met. Most importantly, a major version increase must not break wire compatibility with other gRPC implementations so that existing gRPC libraries remain fully interoperable.
- **Major version bumps** only happen on rare occasions. In order to qualify for a major version bump, certain criteria described later in this document need to be met. Most importantly, a major version increase must not break wire compatibility with other gRPC implementations so that existing gRPC libraries remain fully interoperable.
- **Minor version bumps** happen approx. every 6 weeks as part of the normal release cycle as defined by the gRPC release process. A new release branch named vMAJOR.MINOR.PATCH) is cut every 6 weeks based on the [release schedule](https://github.com/grpc/grpc/blob/master/doc/grpc_release_schedule.md).
- **Patch version bump** corresponds to bugfixes done on release branch.
@ -24,7 +24,7 @@ There are also a few extra rules regarding adding new gRPC implementations (e.g.
To avoid user confusion and simplify reasoning, the gRPC releases in different languages try to stay synchronized in terms of major and minor version (all languages follow the same release schedule). Nevertheless, because we also strictly follow semantic versioning, there are circumstances in which a gRPC implementation needs to break the version synchronicity and do a major version bump independently of other languages.
### Situations when it's ok to do a major version bump
- **change forced by the language ecosystem:** when the language itself or its standard libraries that we depend on make a breaking change (something which is out of our control), reacting with updating gRPC APIs may be the only adequate response.
- **change forced by the language ecosystem:** when the language itself or its standard libraries that we depend on make a breaking change (something which is out of our control), reacting with updating gRPC APIs may be the only adequate response.
- **voluntary change:** Even in non-forced situations, there might be circumstances in which a breaking API change makes sense and represents a net win, but as a rule of thumb breaking changes are very disruptive for users, cause user fragmentation and incur high maintenance costs. Therefore, breaking API changes should be very rare events that need to be considered with extreme care and the bar for accepting such changes is intentionally set very high.
Example scenarios where a breaking API change might be adequate:
- fixing a security problem which requires changes to API (need to consider the non-breaking alternatives first)

@ -90,7 +90,7 @@ This test verifies that every backend receives traffic.
Client parameters:
1. --num_channels=1
1. --qps=10
1. --qps=100
1. --fail_on_failed_rpc=true
Load balancer configuration:
@ -109,7 +109,7 @@ robin policy.
Client parameters:
1. --num_channels=1
1. --qps=10
1. --qps=100
1. --fail_on_failed_rpc=true
Load balancer configuration:
@ -129,7 +129,7 @@ of backends that is stopped and then resumed.
Client parameters:
1. --num_channels=1
1. --qps=10
1. --qps=100
Load balancer configuration:
@ -161,7 +161,7 @@ all backends in the primary locality fail.
Client parameters:
1. --num_channels=1
1. --qps=10
1. --qps=100
Load balancer configuration:
@ -197,7 +197,7 @@ changes to this test case.
Client parameters:
1. --num_channels=1
1. --qps=10
1. --qps=100
Load balancer configuration:
@ -224,7 +224,7 @@ same zone receive traffic.
Client parameters:
1. --num_channels=1
1. --qps=10
1. --qps=100
1. --fail_on_failed_rpc=true
Load balancer configuration:
@ -249,7 +249,7 @@ after removal of another instance group in the same zone.
Client parameters:
1. --num_channels=1
1. --qps=10
1. --qps=100
Load balancer configuration:
@ -273,7 +273,7 @@ to the new backends.
Client parameters:
1. --num_channels=1
1. --qps=10
1. --qps=100
1. --fail_on_failed_rpc=true
Load balancer configuration:
@ -291,3 +291,31 @@ Test driver asserts:
1. All RPCs are directed to the new backend service.
### traffic_splitting
This test verifies that the traffic will be distributed between backend
services with the correct weights when route action is set to weighted
backend services.
Client parameters:
1. --num_channels=1
1. --qps=100
Load balancer configuration:
1. One MIG with one backend
Assert:
1. Once all backends receive at least one RPC, the following 1000 RPCs are
all sent to MIG_a.
The test driver adds a new MIG with 1 backend, and changes the route action
to weighted backend services with {a: 20, b: 80}.
Assert:
1. Once all backends receive at least one RPC, the following 1000 RPCs are
distributed across the 2 backends as a: 20, b: 80.

@ -7,7 +7,7 @@
For information about the other examples in this directory, see their respective
README files.
[gRPC Basics]: https://grpc.io/docs/tutorials/basic/cpp
[gRPC Basics]: https://grpc.io/docs/languages/cpp/basics
[Hello World]: helloworld
[Quick Start]: https://grpc.io/docs/quickstart/cpp
[Quick Start]: https://grpc.io/docs/languages/cpp/quickstart
[Route Guide]: route_guide

@ -3,4 +3,4 @@
You can find a complete set of instructions for building gRPC and running the
Hello World app in the [C++ Quick Start][].
[C++ Quick Start]: https://grpc.io/docs/quickstart/cpp
[C++ Quick Start]: https://grpc.io/docs/languages/cpp/quickstart

@ -3,4 +3,4 @@
The files in this folder are the samples used in [gRPC Basics: C++][],
a detailed tutorial for using gRPC in C++.
[gRPC Basics: C++]:https://grpc.io/docs/tutorials/basic/cpp
[gRPC Basics: C++]:https://grpc.io/docs/languages/cpp/basics

@ -36,4 +36,4 @@ Tutorial
You can find a more detailed tutorial about Grpc in [gRPC Basics: C#][]
[helloworld.proto]:../../protos/helloworld.proto
[gRPC Basics: C#]:https://grpc.io/docs/tutorials/basic/csharp.html
[gRPC Basics: C#]:https://grpc.io/docs/languages/csharp/basics

@ -40,7 +40,7 @@ download all of the NuGet dependencies of gRPC.
Using these IDEs, a workaround is as follows:
* Obtain a nuget executable for your platform and update it with
`nuget update -self`.
`nuget update -self`.
* Navigate to this directory and run `nuget restore`.
* Now that packages have been restored into their proper package folder, build the solution from your IDE.
@ -71,4 +71,4 @@ Tutorial
You can find a more detailed tutorial in [gRPC Basics: C#][]
[helloworld.proto]:../../protos/helloworld.proto
[gRPC Basics: C#]:https://grpc.io/docs/tutorials/basic/csharp.html
[gRPC Basics: C#]:https://grpc.io/docs/languages/csharp/basics

@ -3,4 +3,4 @@
The files in this folder are the samples used in [gRPC Basics: C#][],
a detailed tutorial for using gRPC in C#.
[gRPC Basics: C#]:https://grpc.io/docs/tutorials/basic/csharp.html
[gRPC Basics: C#]:https://grpc.io/docs/languages/csharp/basics

@ -47,4 +47,4 @@ TUTORIAL
You can find a more detailed tutorial in [gRPC Basics: Node.js][]
[Install gRPC Node]:../../src/node
[gRPC Basics: Node.js]:https://grpc.io/docs/tutorials/basic/node.html
[gRPC Basics: Node.js]:https://grpc.io/docs/languages/node/basics

@ -2,4 +2,4 @@
The files in this folder are the samples used in [gRPC Basics: Node.js][], a detailed tutorial for using gRPC in Node.js.
[gRPC Basics: Node.js]:https://grpc.io/docs/tutorials/basic/node.html
[gRPC Basics: Node.js]:https://grpc.io/docs/languages/node/basics

@ -2,4 +2,4 @@
The files in this folder are the samples used in [gRPC Basics: Node.js][], a detailed tutorial for using gRPC in Node.js.
[gRPC Basics: Node.js]:https://grpc.io/docs/tutorials/basic/node.html
[gRPC Basics: Node.js]:https://grpc.io/docs/languages/node/basics

@ -1,3 +1,3 @@
# OAuth2 on gRPC: Objective-C
This is the supporting code for the tutorial "[OAuth2 on gRPC: Objective-C](https://grpc.io/docs/tutorials/auth/oauth2-objective-c.html)."
This is the supporting code for the tutorial "[OAuth2 on gRPC: Objective-C](https://grpc.io/docs/languages/objective-c/oauth2)."

@ -104,4 +104,4 @@ $ bazel run :HelloWorld --ios_simulator_version='<runtime>' --ios_sumlator_devic
## Tutorial
You can find a more detailed tutorial in [gRPC Basics: Objective-C](https://grpc.io/docs/tutorials/basic/objective-c.html).
You can find a more detailed tutorial in [gRPC Basics: Objective-C](https://grpc.io/docs/languages/objective-c/basics).

@ -1,4 +1,4 @@
# gRPC Basics: Objective-C
This is the supporting code for the tutorial "[gRPC Basics: Objective-C](https://grpc.io/docs/tutorials/basic/objective-c.html)."
This is the supporting code for the tutorial "[gRPC Basics: Objective-C](https://grpc.io/docs/languages/objective-c/basics)."

@ -53,4 +53,4 @@ This requires `php` >= 5.5, `pecl`, `composer`
You can find a more detailed tutorial in [gRPC Basics: PHP][]
[Node]:https://github.com/grpc/grpc/tree/master/examples/node
[gRPC Basics: PHP]:https://grpc.io/docs/tutorials/basic/php.html
[gRPC Basics: PHP]:https://grpc.io/docs/languages/php/basics

@ -3,4 +3,4 @@
The files in this folder are the samples used in [gRPC Basics: PHP][],
a detailed tutorial for using gRPC in PHP.
[gRPC Basics: PHP]:https://grpc.io/docs/tutorials/basic/php.html
[gRPC Basics: PHP]:https://grpc.io/docs/languages/php/basics

@ -1 +1 @@
[This code's documentation lives on the grpc.io site.](https://grpc.io/docs/quickstart/python.html)
[This code's documentation lives on the grpc.io site.](https://grpc.io/docs/languages/python/quickstart)

@ -1 +1 @@
[This code's documentation lives on the grpc.io site.](https://grpc.io/docs/quickstart/python.html)
[This code's documentation lives on the grpc.io site.](https://grpc.io/docs/languages/python/quickstart)

@ -2,5 +2,5 @@ An example showing how to add custom HTTP2 headers (or [metadata](https://grpc.i
HTTP2 supports initial headers and trailing headers, which gRPC utilizes both of them ([learn more](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md)).
More complete documentation lives at [grpc.io](https://grpc.io/docs/tutorials/basic/python.html).
More complete documentation lives at [grpc.io](https://grpc.io/docs/languages/python/basics).
For API reference please see [API](https://grpc.io/grpc/python/grpc.html).

@ -1,3 +1,3 @@
An example showing two stubs sharing a channel and two servicers sharing a server.
More complete documentation lives at [grpc.io](https://grpc.io/docs/tutorials/basic/python.html).
More complete documentation lives at [grpc.io](https://grpc.io/docs/languages/python/basics).

@ -1 +1 @@
[This code's documentation lives on the grpc.io site.](https://grpc.io/docs/tutorials/basic/python.html)
[This code's documentation lives on the grpc.io site.](https://grpc.io/docs/languages/python/basics)

@ -60,4 +60,4 @@ You can find a more detailed tutorial in [gRPC Basics: Ruby][]
[helloworld.proto]:../protos/helloworld.proto
[RVM]:https://www.rvm.io/
[Install gRPC ruby]:../../src/ruby#installation
[gRPC Basics: Ruby]:https://grpc.io/docs/tutorials/basic/ruby.html
[gRPC Basics: Ruby]:https://grpc.io/docs/languages/ruby/basics

@ -3,4 +3,4 @@
The files in this folder are the samples used in [gRPC Basics: Ruby][],
a detailed tutorial for using gRPC in Ruby.
[gRPC Basics: Ruby]:https://grpc.io/docs/tutorials/basic/ruby.html
[gRPC Basics: Ruby]:https://grpc.io/docs/languages/ruby/basics

@ -226,6 +226,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/client_channel.h',
'src/core/ext/filters/client_channel/client_channel_channelz.h',
'src/core/ext/filters/client_channel/client_channel_factory.h',
'src/core/ext/filters/client_channel/config_selector.h',
'src/core/ext/filters/client_channel/connector.h',
'src/core/ext/filters/client_channel/global_subchannel_pool.h',
'src/core/ext/filters/client_channel/health/health_check_client.h',
@ -615,6 +616,7 @@ Pod::Spec.new do |s|
'src/core/tsi/transport_security_grpc.h',
'src/core/tsi/transport_security_interface.h',
'src/cpp/client/channel_cc.cc',
'src/cpp/client/client_callback.cc',
'src/cpp/client/client_context.cc',
'src/cpp/client/client_interceptor.cc',
'src/cpp/client/create_channel.cc',
@ -685,6 +687,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/client_channel.h',
'src/core/ext/filters/client_channel/client_channel_channelz.h',
'src/core/ext/filters/client_channel/client_channel_factory.h',
'src/core/ext/filters/client_channel/config_selector.h',
'src/core/ext/filters/client_channel/connector.h',
'src/core/ext/filters/client_channel/global_subchannel_pool.h',
'src/core/ext/filters/client_channel/health/health_check_client.h',

@ -195,6 +195,8 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/client_channel_factory.cc',
'src/core/ext/filters/client_channel/client_channel_factory.h',
'src/core/ext/filters/client_channel/client_channel_plugin.cc',
'src/core/ext/filters/client_channel/config_selector.cc',
'src/core/ext/filters/client_channel/config_selector.h',
'src/core/ext/filters/client_channel/connector.h',
'src/core/ext/filters/client_channel/global_subchannel_pool.cc',
'src/core/ext/filters/client_channel/global_subchannel_pool.h',
@ -277,6 +279,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/service_config.cc',
'src/core/ext/filters/client_channel/service_config.h',
'src/core/ext/filters/client_channel/service_config_call_data.h',
'src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc',
'src/core/ext/filters/client_channel/service_config_parser.cc',
'src/core/ext/filters/client_channel/service_config_parser.h',
'src/core/ext/filters/client_channel/subchannel.cc',
@ -1051,6 +1054,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/client_channel.h',
'src/core/ext/filters/client_channel/client_channel_channelz.h',
'src/core/ext/filters/client_channel/client_channel_factory.h',
'src/core/ext/filters/client_channel/config_selector.h',
'src/core/ext/filters/client_channel/connector.h',
'src/core/ext/filters/client_channel/global_subchannel_pool.h',
'src/core/ext/filters/client_channel/health/health_check_client.h',

@ -117,6 +117,8 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/client_channel_factory.cc )
s.files += %w( src/core/ext/filters/client_channel/client_channel_factory.h )
s.files += %w( src/core/ext/filters/client_channel/client_channel_plugin.cc )
s.files += %w( src/core/ext/filters/client_channel/config_selector.cc )
s.files += %w( src/core/ext/filters/client_channel/config_selector.h )
s.files += %w( src/core/ext/filters/client_channel/connector.h )
s.files += %w( src/core/ext/filters/client_channel/global_subchannel_pool.cc )
s.files += %w( src/core/ext/filters/client_channel/global_subchannel_pool.h )
@ -199,6 +201,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/service_config.cc )
s.files += %w( src/core/ext/filters/client_channel/service_config.h )
s.files += %w( src/core/ext/filters/client_channel/service_config_call_data.h )
s.files += %w( src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc )
s.files += %w( src/core/ext/filters/client_channel/service_config_parser.cc )
s.files += %w( src/core/ext/filters/client_channel/service_config_parser.h )
s.files += %w( src/core/ext/filters/client_channel/subchannel.cc )

@ -440,6 +440,7 @@
'src/core/ext/filters/client_channel/client_channel_channelz.cc',
'src/core/ext/filters/client_channel/client_channel_factory.cc',
'src/core/ext/filters/client_channel/client_channel_plugin.cc',
'src/core/ext/filters/client_channel/config_selector.cc',
'src/core/ext/filters/client_channel/global_subchannel_pool.cc',
'src/core/ext/filters/client_channel/health/health_check_client.cc',
'src/core/ext/filters/client_channel/http_connect_handshaker.cc',
@ -487,6 +488,7 @@
'src/core/ext/filters/client_channel/retry_throttle.cc',
'src/core/ext/filters/client_channel/server_address.cc',
'src/core/ext/filters/client_channel/service_config.cc',
'src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc',
'src/core/ext/filters/client_channel/service_config_parser.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_pool_interface.cc',
@ -947,6 +949,7 @@
'src/core/ext/filters/client_channel/client_channel_channelz.cc',
'src/core/ext/filters/client_channel/client_channel_factory.cc',
'src/core/ext/filters/client_channel/client_channel_plugin.cc',
'src/core/ext/filters/client_channel/config_selector.cc',
'src/core/ext/filters/client_channel/global_subchannel_pool.cc',
'src/core/ext/filters/client_channel/health/health_check_client.cc',
'src/core/ext/filters/client_channel/http_connect_handshaker.cc',
@ -994,6 +997,7 @@
'src/core/ext/filters/client_channel/retry_throttle.cc',
'src/core/ext/filters/client_channel/server_address.cc',
'src/core/ext/filters/client_channel/service_config.cc',
'src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc',
'src/core/ext/filters/client_channel/service_config_parser.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_pool_interface.cc',
@ -1313,6 +1317,7 @@
],
'sources': [
'src/cpp/client/channel_cc.cc',
'src/cpp/client/client_callback.cc',
'src/cpp/client/client_context.cc',
'src/cpp/client/client_interceptor.cc',
'src/cpp/client/create_channel.cc',
@ -1464,6 +1469,7 @@
],
'sources': [
'src/cpp/client/channel_cc.cc',
'src/cpp/client/client_callback.cc',
'src/cpp/client/client_context.cc',
'src/cpp/client/client_interceptor.cc',
'src/cpp/client/create_channel.cc',

@ -674,8 +674,10 @@ typedef struct grpc_op {
const char** error_string;
} recv_status_on_client;
struct grpc_op_recv_close_on_server {
/** out argument, set to 1 if the call failed in any way (seen as a
cancellation on the server), or 0 if the call succeeded */
/** out argument, set to 1 if the call failed at the server for
a reason other than a non-OK status (cancel, deadline
exceeded, network failure, etc.), 0 otherwise (RPC processing ran to
completion and was able to provide any status from the server) */
int* cancelled;
} recv_close_on_server;
} data;

@ -112,31 +112,6 @@
#define GPR_WINDOWS_ATOMIC 1
#define GPR_MSVC_TLS 1
#endif
#elif defined(GPR_MANYLINUX1)
// TODO(atash): manylinux1 is just another __linux__ but with ancient
// libraries; it should be integrated with the `__linux__` definitions below.
#define GPR_PLATFORM_STRING "manylinux"
#define GPR_POSIX_CRASH_HANDLER 1
#define GPR_CPU_POSIX 1
#define GPR_GCC_ATOMIC 1
#define GPR_GCC_TLS 1
#define GPR_LINUX 1
#define GPR_LINUX_LOG 1
#define GPR_SUPPORT_CHANNELS_FROM_FD 1
#define GPR_LINUX_ENV 1
#define GPR_POSIX_TMPFILE 1
#define GPR_POSIX_STRING 1
#define GPR_POSIX_SUBPROCESS 1
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_HAS_PTHREAD_H 1
#define GPR_GETPID_IN_UNISTD_H 1
#ifdef _LP64
#define GPR_ARCH_64 1
#else /* _LP64 */
#define GPR_ARCH_32 1
#endif /* _LP64 */
#include <linux/version.h>
#elif defined(ANDROID) || defined(__ANDROID__)
#define GPR_PLATFORM_STRING "android"
#define GPR_ANDROID 1

@ -101,6 +101,29 @@ class CallbackUnaryCallImpl {
call.PerformOps(ops);
}
};
// Base class for public API classes.
class ClientReactor {
public:
/// Called by the library when all operations associated with this RPC have
/// completed and all Holds have been removed. OnDone provides the RPC status
/// outcome for both successful and failed RPCs. If it is never called on an
/// RPC, it indicates an application-level problem (like failure to remove a
/// hold).
///
/// \param[in] s The status outcome of this RPC
virtual void OnDone(const ::grpc::Status& /*s*/) = 0;
/// InternalScheduleOnDone is not part of the API and is not meant to be
/// overridden. It is virtual to allow successful builds for certain bazel
/// build users that only want to depend on gRPC codegen headers and not the
/// full library (although this is not a generally-supported option). Although
/// the virtual call is slower than a direct call, this function is
/// heavyweight and the cost of the virtual call is not much in comparison.
/// This function may be removed or devirtualized in the future.
virtual void InternalScheduleOnDone(::grpc::Status s);
};
} // namespace internal
// Forward declarations
@ -189,7 +212,7 @@ class ClientCallbackUnary {
/// \a ClientBidiReactor is the interface for a bidirectional streaming RPC.
template <class Request, class Response>
class ClientBidiReactor {
class ClientBidiReactor : public internal::ClientReactor {
public:
virtual ~ClientBidiReactor() {}
@ -282,7 +305,7 @@ class ClientBidiReactor {
/// (like failure to remove a hold).
///
/// \param[in] s The status outcome of this RPC
virtual void OnDone(const ::grpc::Status& /*s*/) {}
void OnDone(const ::grpc::Status& /*s*/) override {}
/// Notifies the application that a read of initial metadata from the
/// server is done. If the application chooses not to implement this method,
@ -327,7 +350,7 @@ class ClientBidiReactor {
/// \a ClientReadReactor is the interface for a server-streaming RPC.
/// All public methods behave as in ClientBidiReactor.
template <class Response>
class ClientReadReactor {
class ClientReadReactor : public internal::ClientReactor {
public:
virtual ~ClientReadReactor() {}
@ -341,7 +364,7 @@ class ClientReadReactor {
}
void RemoveHold() { reader_->RemoveHold(); }
virtual void OnDone(const ::grpc::Status& /*s*/) {}
void OnDone(const ::grpc::Status& /*s*/) override {}
virtual void OnReadInitialMetadataDone(bool /*ok*/) {}
virtual void OnReadDone(bool /*ok*/) {}
@ -354,7 +377,7 @@ class ClientReadReactor {
/// \a ClientWriteReactor is the interface for a client-streaming RPC.
/// All public methods behave as in ClientBidiReactor.
template <class Request>
class ClientWriteReactor {
class ClientWriteReactor : public internal::ClientReactor {
public:
virtual ~ClientWriteReactor() {}
@ -377,7 +400,7 @@ class ClientWriteReactor {
}
void RemoveHold() { writer_->RemoveHold(); }
virtual void OnDone(const ::grpc::Status& /*s*/) {}
void OnDone(const ::grpc::Status& /*s*/) override {}
virtual void OnReadInitialMetadataDone(bool /*ok*/) {}
virtual void OnWriteDone(bool /*ok*/) {}
virtual void OnWritesDoneDone(bool /*ok*/) {}
@ -385,6 +408,7 @@ class ClientWriteReactor {
private:
friend class ClientCallbackWriter<Request>;
void BindWriter(ClientCallbackWriter<Request>* writer) { writer_ = writer; }
ClientCallbackWriter<Request>* writer_;
};
@ -399,12 +423,12 @@ class ClientWriteReactor {
/// call (that is part of the unary call itself) and there is no reactor object
/// being created as a result of this call, we keep a consistent 2-phase
/// initiation API among all the reactor flavors.
class ClientUnaryReactor {
class ClientUnaryReactor : public internal::ClientReactor {
public:
virtual ~ClientUnaryReactor() {}
void StartCall() { call_->StartCall(); }
virtual void OnDone(const ::grpc::Status& /*s*/) {}
void OnDone(const ::grpc::Status& /*s*/) override {}
virtual void OnReadInitialMetadataDone(bool /*ok*/) {}
private:
@ -444,93 +468,56 @@ class ClientCallbackReaderWriterImpl
// there are no tests catching the compiler warning.
static void operator delete(void*, void*) { GPR_CODEGEN_ASSERT(false); }
void MaybeFinish() {
if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub(
1, std::memory_order_acq_rel) == 1)) {
::grpc::Status s = std::move(finish_status_);
auto* reactor = reactor_;
auto* call = call_.call();
this->~ClientCallbackReaderWriterImpl();
::grpc::g_core_codegen_interface->grpc_call_unref(call);
reactor->OnDone(s);
}
}
void StartCall() override {
// This call initiates two batches, plus any backlog, each with a callback
// 1. Send initial metadata (unless corked) + recv initial metadata
// 2. Any read backlog
// 3. Any write backlog
// 4. Recv trailing metadata, on_completion callback
started_ = true;
start_tag_.Set(call_.call(),
[this](bool ok) {
reactor_->OnReadInitialMetadataDone(ok);
MaybeFinish();
},
&start_ops_, /*can_inline=*/false);
// 4. Recv trailing metadata (unless corked)
if (!start_corked_) {
start_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
context_->initial_metadata_flags());
}
start_ops_.RecvInitialMetadata(context_);
start_ops_.set_core_cq_tag(&start_tag_);
call_.PerformOps(&start_ops_);
// Also set up the read and write tags so that they don't have to be set up
// each time
write_tag_.Set(call_.call(),
[this](bool ok) {
reactor_->OnWriteDone(ok);
MaybeFinish();
},
&write_ops_, /*can_inline=*/false);
write_ops_.set_core_cq_tag(&write_tag_);
read_tag_.Set(call_.call(),
[this](bool ok) {
reactor_->OnReadDone(ok);
MaybeFinish();
},
&read_ops_, /*can_inline=*/false);
read_ops_.set_core_cq_tag(&read_tag_);
if (read_ops_at_start_) {
call_.PerformOps(&read_ops_);
}
if (write_ops_at_start_) {
call_.PerformOps(&write_ops_);
}
call_.PerformOps(&start_ops_);
if (writes_done_ops_at_start_) {
call_.PerformOps(&writes_done_ops_);
{
grpc::internal::MutexLock lock(&start_mu_);
if (backlog_.read_ops) {
call_.PerformOps(&read_ops_);
}
if (backlog_.write_ops) {
call_.PerformOps(&write_ops_);
}
if (backlog_.writes_done_ops) {
call_.PerformOps(&writes_done_ops_);
}
call_.PerformOps(&finish_ops_);
// The last thing in this critical section is to set started_ so that it
// can be used lock-free as well.
started_.store(true, std::memory_order_release);
}
finish_tag_.Set(call_.call(), [this](bool /*ok*/) { MaybeFinish(); },
&finish_ops_, /*can_inline=*/false);
finish_ops_.ClientRecvStatus(context_, &finish_status_);
finish_ops_.set_core_cq_tag(&finish_tag_);
call_.PerformOps(&finish_ops_);
// MaybeFinish outside the lock to make sure that destruction of this object
// doesn't take place while holding the lock (which would cause the lock to
// be released after destruction)
this->MaybeFinish(/*from_reaction=*/false);
}
void Read(Response* msg) override {
read_ops_.RecvMessage(msg);
callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
if (started_) {
call_.PerformOps(&read_ops_);
} else {
read_ops_at_start_ = true;
if (GPR_UNLIKELY(!started_.load(std::memory_order_acquire))) {
grpc::internal::MutexLock lock(&start_mu_);
if (GPR_LIKELY(!started_.load(std::memory_order_relaxed))) {
backlog_.read_ops = true;
return;
}
}
call_.PerformOps(&read_ops_);
}
void Write(const Request* msg, ::grpc::WriteOptions options) override {
if (start_corked_) {
write_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
context_->initial_metadata_flags());
start_corked_ = false;
}
if (options.is_last_message()) {
options.set_buffer_hint();
write_ops_.ClientSendClose();
@ -538,38 +525,50 @@ class ClientCallbackReaderWriterImpl
// TODO(vjpai): don't assert
GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg, options).ok());
callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
if (started_) {
call_.PerformOps(&write_ops_);
} else {
write_ops_at_start_ = true;
if (GPR_UNLIKELY(corked_write_needed_)) {
write_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
context_->initial_metadata_flags());
corked_write_needed_ = false;
}
if (GPR_UNLIKELY(!started_.load(std::memory_order_acquire))) {
grpc::internal::MutexLock lock(&start_mu_);
if (GPR_LIKELY(!started_.load(std::memory_order_relaxed))) {
backlog_.write_ops = true;
return;
}
}
call_.PerformOps(&write_ops_);
}
void WritesDone() override {
if (start_corked_) {
writes_done_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
context_->initial_metadata_flags());
start_corked_ = false;
}
writes_done_ops_.ClientSendClose();
writes_done_tag_.Set(call_.call(),
[this](bool ok) {
reactor_->OnWritesDoneDone(ok);
MaybeFinish();
MaybeFinish(/*from_reaction=*/true);
},
&writes_done_ops_, /*can_inline=*/false);
writes_done_ops_.set_core_cq_tag(&writes_done_tag_);
callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
if (started_) {
call_.PerformOps(&writes_done_ops_);
} else {
writes_done_ops_at_start_ = true;
if (GPR_UNLIKELY(corked_write_needed_)) {
writes_done_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
context_->initial_metadata_flags());
corked_write_needed_ = false;
}
if (GPR_UNLIKELY(!started_.load(std::memory_order_acquire))) {
grpc::internal::MutexLock lock(&start_mu_);
if (GPR_LIKELY(!started_.load(std::memory_order_relaxed))) {
backlog_.writes_done_ops = true;
return;
}
}
call_.PerformOps(&writes_done_ops_);
}
void AddHold(int holds) override {
callbacks_outstanding_.fetch_add(holds, std::memory_order_relaxed);
}
void RemoveHold() override { MaybeFinish(); }
void RemoveHold() override { MaybeFinish(/*from_reaction=*/false); }
private:
friend class ClientCallbackReaderWriterFactory<Request, Response>;
@ -580,8 +579,66 @@ class ClientCallbackReaderWriterImpl
: context_(context),
call_(call),
reactor_(reactor),
start_corked_(context_->initial_metadata_corked_) {
start_corked_(context_->initial_metadata_corked_),
corked_write_needed_(start_corked_) {
this->BindReactor(reactor);
// Set up the unchanging parts of the start, read, and write tags and ops.
start_tag_.Set(call_.call(),
[this](bool ok) {
reactor_->OnReadInitialMetadataDone(ok);
MaybeFinish(/*from_reaction=*/true);
},
&start_ops_, /*can_inline=*/false);
start_ops_.RecvInitialMetadata(context_);
start_ops_.set_core_cq_tag(&start_tag_);
write_tag_.Set(call_.call(),
[this](bool ok) {
reactor_->OnWriteDone(ok);
MaybeFinish(/*from_reaction=*/true);
},
&write_ops_, /*can_inline=*/false);
write_ops_.set_core_cq_tag(&write_tag_);
read_tag_.Set(call_.call(),
[this](bool ok) {
reactor_->OnReadDone(ok);
MaybeFinish(/*from_reaction=*/true);
},
&read_ops_, /*can_inline=*/false);
read_ops_.set_core_cq_tag(&read_tag_);
// Also set up the Finish tag and op set.
finish_tag_.Set(
call_.call(),
[this](bool /*ok*/) { MaybeFinish(/*from_reaction=*/true); },
&finish_ops_,
/*can_inline=*/false);
finish_ops_.ClientRecvStatus(context_, &finish_status_);
finish_ops_.set_core_cq_tag(&finish_tag_);
}
// MaybeFinish can be called from reactions or from user-initiated operations
// like StartCall or RemoveHold. If this is the last operation or hold on this
// object, it will invoke the OnDone reaction. If MaybeFinish was called from
// a reaction, it can call OnDone directly. If not, it would need to schedule
// OnDone onto an executor thread to avoid the possibility of deadlocking with
// any locks in the user code that invoked it.
void MaybeFinish(bool from_reaction) {
if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub(
1, std::memory_order_acq_rel) == 1)) {
::grpc::Status s = std::move(finish_status_);
auto* reactor = reactor_;
auto* call = call_.call();
this->~ClientCallbackReaderWriterImpl();
::grpc::g_core_codegen_interface->grpc_call_unref(call);
if (GPR_LIKELY(from_reaction)) {
reactor->OnDone(s);
} else {
reactor->InternalScheduleOnDone(std::move(s));
}
}
}
::grpc_impl::ClientContext* const context_;
@ -592,7 +649,9 @@ class ClientCallbackReaderWriterImpl
grpc::internal::CallOpRecvInitialMetadata>
start_ops_;
grpc::internal::CallbackWithSuccessTag start_tag_;
bool start_corked_;
const bool start_corked_;
bool corked_write_needed_; // no lock needed since only accessed in
// Write/WritesDone which cannot be concurrent
grpc::internal::CallOpSet<grpc::internal::CallOpClientRecvStatus> finish_ops_;
grpc::internal::CallbackWithSuccessTag finish_tag_;
@ -603,22 +662,27 @@ class ClientCallbackReaderWriterImpl
grpc::internal::CallOpClientSendClose>
write_ops_;
grpc::internal::CallbackWithSuccessTag write_tag_;
bool write_ops_at_start_{false};
grpc::internal::CallOpSet<grpc::internal::CallOpSendInitialMetadata,
grpc::internal::CallOpClientSendClose>
writes_done_ops_;
grpc::internal::CallbackWithSuccessTag writes_done_tag_;
bool writes_done_ops_at_start_{false};
grpc::internal::CallOpSet<grpc::internal::CallOpRecvMessage<Response>>
read_ops_;
grpc::internal::CallbackWithSuccessTag read_tag_;
bool read_ops_at_start_{false};
// Minimum of 2 callbacks to pre-register for start and finish
std::atomic<intptr_t> callbacks_outstanding_{2};
bool started_{false};
struct StartCallBacklog {
bool write_ops = false;
bool writes_done_ops = false;
bool read_ops = false;
};
StartCallBacklog backlog_ /* GUARDED_BY(start_mu_) */;
// Minimum of 3 callbacks to pre-register for start ops, StartCall, and finish
std::atomic<intptr_t> callbacks_outstanding_{3};
std::atomic_bool started_{false};
grpc::internal::Mutex start_mu_;
};
template <class Request, class Response>
@ -654,29 +718,16 @@ class ClientCallbackReaderImpl : public ClientCallbackReader<Response> {
// there are no tests catching the compiler warning.
static void operator delete(void*, void*) { GPR_CODEGEN_ASSERT(false); }
void MaybeFinish() {
if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub(
1, std::memory_order_acq_rel) == 1)) {
::grpc::Status s = std::move(finish_status_);
auto* reactor = reactor_;
auto* call = call_.call();
this->~ClientCallbackReaderImpl();
::grpc::g_core_codegen_interface->grpc_call_unref(call);
reactor->OnDone(s);
}
}
void StartCall() override {
// This call initiates two batches, plus any backlog, each with a callback
// 1. Send initial metadata (unless corked) + recv initial metadata
// 2. Any backlog
// 3. Recv trailing metadata, on_completion callback
started_ = true;
// 3. Recv trailing metadata
start_tag_.Set(call_.call(),
[this](bool ok) {
reactor_->OnReadInitialMetadataDone(ok);
MaybeFinish();
MaybeFinish(/*from_reaction=*/true);
},
&start_ops_, /*can_inline=*/false);
start_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
@ -689,16 +740,23 @@ class ClientCallbackReaderImpl : public ClientCallbackReader<Response> {
read_tag_.Set(call_.call(),
[this](bool ok) {
reactor_->OnReadDone(ok);
MaybeFinish();
MaybeFinish(/*from_reaction=*/true);
},
&read_ops_, /*can_inline=*/false);
read_ops_.set_core_cq_tag(&read_tag_);
if (read_ops_at_start_) {
call_.PerformOps(&read_ops_);
{
grpc::internal::MutexLock lock(&start_mu_);
if (backlog_.read_ops) {
call_.PerformOps(&read_ops_);
}
started_.store(true, std::memory_order_release);
}
finish_tag_.Set(call_.call(), [this](bool /*ok*/) { MaybeFinish(); },
&finish_ops_, /*can_inline=*/false);
finish_tag_.Set(
call_.call(),
[this](bool /*ok*/) { MaybeFinish(/*from_reaction=*/true); },
&finish_ops_, /*can_inline=*/false);
finish_ops_.ClientRecvStatus(context_, &finish_status_);
finish_ops_.set_core_cq_tag(&finish_tag_);
call_.PerformOps(&finish_ops_);
@ -707,17 +765,20 @@ class ClientCallbackReaderImpl : public ClientCallbackReader<Response> {
void Read(Response* msg) override {
read_ops_.RecvMessage(msg);
callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
if (started_) {
call_.PerformOps(&read_ops_);
} else {
read_ops_at_start_ = true;
if (GPR_UNLIKELY(!started_.load(std::memory_order_acquire))) {
grpc::internal::MutexLock lock(&start_mu_);
if (GPR_LIKELY(!started_.load(std::memory_order_relaxed))) {
backlog_.read_ops = true;
return;
}
}
call_.PerformOps(&read_ops_);
}
void AddHold(int holds) override {
callbacks_outstanding_.fetch_add(holds, std::memory_order_relaxed);
}
void RemoveHold() override { MaybeFinish(); }
void RemoveHold() override { MaybeFinish(/*from_reaction=*/false); }
private:
friend class ClientCallbackReaderFactory<Response>;
@ -734,6 +795,23 @@ class ClientCallbackReaderImpl : public ClientCallbackReader<Response> {
start_ops_.ClientSendClose();
}
// MaybeFinish behaves as in ClientCallbackReaderWriterImpl.
void MaybeFinish(bool from_reaction) {
if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub(
1, std::memory_order_acq_rel) == 1)) {
::grpc::Status s = std::move(finish_status_);
auto* reactor = reactor_;
auto* call = call_.call();
this->~ClientCallbackReaderImpl();
::grpc::g_core_codegen_interface->grpc_call_unref(call);
if (GPR_LIKELY(from_reaction)) {
reactor->OnDone(s);
} else {
reactor->InternalScheduleOnDone(std::move(s));
}
}
}
::grpc_impl::ClientContext* const context_;
grpc::internal::Call call_;
ClientReadReactor<Response>* const reactor_;
@ -752,11 +830,16 @@ class ClientCallbackReaderImpl : public ClientCallbackReader<Response> {
grpc::internal::CallOpSet<grpc::internal::CallOpRecvMessage<Response>>
read_ops_;
grpc::internal::CallbackWithSuccessTag read_tag_;
bool read_ops_at_start_{false};
struct StartCallBacklog {
bool read_ops = false;
};
StartCallBacklog backlog_ /* GUARDED_BY(start_mu_) */;
// Minimum of 2 callbacks to pre-register for start and finish
std::atomic<intptr_t> callbacks_outstanding_{2};
bool started_{false};
std::atomic_bool started_{false};
grpc::internal::Mutex start_mu_;
};
template <class Response>
@ -793,110 +876,94 @@ class ClientCallbackWriterImpl : public ClientCallbackWriter<Request> {
// there are no tests catching the compiler warning.
static void operator delete(void*, void*) { GPR_CODEGEN_ASSERT(false); }
void MaybeFinish() {
if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub(
1, std::memory_order_acq_rel) == 1)) {
::grpc::Status s = std::move(finish_status_);
auto* reactor = reactor_;
auto* call = call_.call();
this->~ClientCallbackWriterImpl();
::grpc::g_core_codegen_interface->grpc_call_unref(call);
reactor->OnDone(s);
}
}
void StartCall() override {
// This call initiates two batches, plus any backlog, each with a callback
// 1. Send initial metadata (unless corked) + recv initial metadata
// 2. Any backlog
// 3. Recv trailing metadata, on_completion callback
started_ = true;
// 3. Recv trailing metadata
start_tag_.Set(call_.call(),
[this](bool ok) {
reactor_->OnReadInitialMetadataDone(ok);
MaybeFinish();
},
&start_ops_, /*can_inline=*/false);
if (!start_corked_) {
start_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
context_->initial_metadata_flags());
}
start_ops_.RecvInitialMetadata(context_);
start_ops_.set_core_cq_tag(&start_tag_);
call_.PerformOps(&start_ops_);
// Also set up the read and write tags so that they don't have to be set up
// each time
write_tag_.Set(call_.call(),
[this](bool ok) {
reactor_->OnWriteDone(ok);
MaybeFinish();
},
&write_ops_, /*can_inline=*/false);
write_ops_.set_core_cq_tag(&write_tag_);
if (write_ops_at_start_) {
call_.PerformOps(&write_ops_);
{
grpc::internal::MutexLock lock(&start_mu_);
if (backlog_.write_ops) {
call_.PerformOps(&write_ops_);
}
if (backlog_.writes_done_ops) {
call_.PerformOps(&writes_done_ops_);
}
call_.PerformOps(&finish_ops_);
// The last thing in this critical section is to set started_ so that it
// can be used lock-free as well.
started_.store(true, std::memory_order_release);
}
if (writes_done_ops_at_start_) {
call_.PerformOps(&writes_done_ops_);
}
finish_tag_.Set(call_.call(), [this](bool /*ok*/) { MaybeFinish(); },
&finish_ops_, /*can_inline=*/false);
finish_ops_.ClientRecvStatus(context_, &finish_status_);
finish_ops_.set_core_cq_tag(&finish_tag_);
call_.PerformOps(&finish_ops_);
// MaybeFinish outside the lock to make sure that destruction of this object
// doesn't take place while holding the lock (which would cause the lock to
// be released after destruction)
this->MaybeFinish(/*from_reaction=*/false);
}
void Write(const Request* msg, ::grpc::WriteOptions options) override {
if (start_corked_) {
write_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
context_->initial_metadata_flags());
start_corked_ = false;
}
if (options.is_last_message()) {
if (GPR_UNLIKELY(options.is_last_message())) {
options.set_buffer_hint();
write_ops_.ClientSendClose();
}
// TODO(vjpai): don't assert
GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg, options).ok());
callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
if (started_) {
call_.PerformOps(&write_ops_);
} else {
write_ops_at_start_ = true;
if (GPR_UNLIKELY(corked_write_needed_)) {
write_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
context_->initial_metadata_flags());
corked_write_needed_ = false;
}
if (GPR_UNLIKELY(!started_.load(std::memory_order_acquire))) {
grpc::internal::MutexLock lock(&start_mu_);
if (GPR_LIKELY(!started_.load(std::memory_order_relaxed))) {
backlog_.write_ops = true;
return;
}
}
call_.PerformOps(&write_ops_);
}
void WritesDone() override {
if (start_corked_) {
writes_done_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
context_->initial_metadata_flags());
start_corked_ = false;
}
writes_done_ops_.ClientSendClose();
writes_done_tag_.Set(call_.call(),
[this](bool ok) {
reactor_->OnWritesDoneDone(ok);
MaybeFinish();
MaybeFinish(/*from_reaction=*/true);
},
&writes_done_ops_, /*can_inline=*/false);
writes_done_ops_.set_core_cq_tag(&writes_done_tag_);
callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed);
if (started_) {
call_.PerformOps(&writes_done_ops_);
} else {
writes_done_ops_at_start_ = true;
if (GPR_UNLIKELY(corked_write_needed_)) {
writes_done_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
context_->initial_metadata_flags());
corked_write_needed_ = false;
}
if (GPR_UNLIKELY(!started_.load(std::memory_order_acquire))) {
grpc::internal::MutexLock lock(&start_mu_);
if (GPR_LIKELY(!started_.load(std::memory_order_relaxed))) {
backlog_.writes_done_ops = true;
return;
}
}
call_.PerformOps(&writes_done_ops_);
}
void AddHold(int holds) override {
callbacks_outstanding_.fetch_add(holds, std::memory_order_relaxed);
}
void RemoveHold() override { MaybeFinish(); }
void RemoveHold() override { MaybeFinish(/*from_reaction=*/false); }
private:
friend class ClientCallbackWriterFactory<Request>;
@ -909,10 +976,55 @@ class ClientCallbackWriterImpl : public ClientCallbackWriter<Request> {
: context_(context),
call_(call),
reactor_(reactor),
start_corked_(context_->initial_metadata_corked_) {
start_corked_(context_->initial_metadata_corked_),
corked_write_needed_(start_corked_) {
this->BindReactor(reactor);
// Set up the unchanging parts of the start and write tags and ops.
start_tag_.Set(call_.call(),
[this](bool ok) {
reactor_->OnReadInitialMetadataDone(ok);
MaybeFinish(/*from_reaction=*/true);
},
&start_ops_, /*can_inline=*/false);
start_ops_.RecvInitialMetadata(context_);
start_ops_.set_core_cq_tag(&start_tag_);
write_tag_.Set(call_.call(),
[this](bool ok) {
reactor_->OnWriteDone(ok);
MaybeFinish(/*from_reaction=*/true);
},
&write_ops_, /*can_inline=*/false);
write_ops_.set_core_cq_tag(&write_tag_);
// Also set up the Finish tag and op set.
finish_ops_.RecvMessage(response);
finish_ops_.AllowNoMessage();
finish_tag_.Set(
call_.call(),
[this](bool /*ok*/) { MaybeFinish(/*from_reaction=*/true); },
&finish_ops_,
/*can_inline=*/false);
finish_ops_.ClientRecvStatus(context_, &finish_status_);
finish_ops_.set_core_cq_tag(&finish_tag_);
}
// MaybeFinish behaves as in ClientCallbackReaderWriterImpl.
void MaybeFinish(bool from_reaction) {
if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub(
1, std::memory_order_acq_rel) == 1)) {
::grpc::Status s = std::move(finish_status_);
auto* reactor = reactor_;
auto* call = call_.call();
this->~ClientCallbackWriterImpl();
::grpc::g_core_codegen_interface->grpc_call_unref(call);
if (GPR_LIKELY(from_reaction)) {
reactor->OnDone(s);
} else {
reactor->InternalScheduleOnDone(std::move(s));
}
}
}
::grpc_impl::ClientContext* const context_;
@ -923,7 +1035,9 @@ class ClientCallbackWriterImpl : public ClientCallbackWriter<Request> {
grpc::internal::CallOpRecvInitialMetadata>
start_ops_;
grpc::internal::CallbackWithSuccessTag start_tag_;
bool start_corked_;
const bool start_corked_;
bool corked_write_needed_; // no lock needed since only accessed in
// Write/WritesDone which cannot be concurrent
grpc::internal::CallOpSet<grpc::internal::CallOpGenericRecvMessage,
grpc::internal::CallOpClientRecvStatus>
@ -936,17 +1050,22 @@ class ClientCallbackWriterImpl : public ClientCallbackWriter<Request> {
grpc::internal::CallOpClientSendClose>
write_ops_;
grpc::internal::CallbackWithSuccessTag write_tag_;
bool write_ops_at_start_{false};
grpc::internal::CallOpSet<grpc::internal::CallOpSendInitialMetadata,
grpc::internal::CallOpClientSendClose>
writes_done_ops_;
grpc::internal::CallbackWithSuccessTag writes_done_tag_;
bool writes_done_ops_at_start_{false};
// Minimum of 2 callbacks to pre-register for start and finish
std::atomic<intptr_t> callbacks_outstanding_{2};
bool started_{false};
struct StartCallBacklog {
bool write_ops = false;
bool writes_done_ops = false;
};
StartCallBacklog backlog_ /* GUARDED_BY(start_mu_) */;
// Minimum of 3 callbacks to pre-register for start ops, StartCall, and finish
std::atomic<intptr_t> callbacks_outstanding_{3};
std::atomic_bool started_{false};
grpc::internal::Mutex start_mu_;
};
template <class Request>
@ -985,7 +1104,6 @@ class ClientCallbackUnaryImpl final : public ClientCallbackUnary {
// This call initiates two batches, each with a callback
// 1. Send initial metadata + write + writes done + recv initial metadata
// 2. Read message, recv trailing metadata
started_ = true;
start_tag_.Set(call_.call(),
[this](bool ok) {
@ -1000,24 +1118,13 @@ class ClientCallbackUnaryImpl final : public ClientCallbackUnary {
call_.PerformOps(&start_ops_);
finish_tag_.Set(call_.call(), [this](bool /*ok*/) { MaybeFinish(); },
&finish_ops_, /*can_inline=*/false);
&finish_ops_,
/*can_inline=*/false);
finish_ops_.ClientRecvStatus(context_, &finish_status_);
finish_ops_.set_core_cq_tag(&finish_tag_);
call_.PerformOps(&finish_ops_);
}
void MaybeFinish() {
if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub(
1, std::memory_order_acq_rel) == 1)) {
::grpc::Status s = std::move(finish_status_);
auto* reactor = reactor_;
auto* call = call_.call();
this->~ClientCallbackUnaryImpl();
::grpc::g_core_codegen_interface->grpc_call_unref(call);
reactor->OnDone(s);
}
}
private:
friend class ClientCallbackUnaryFactory;
@ -1034,6 +1141,21 @@ class ClientCallbackUnaryImpl final : public ClientCallbackUnary {
finish_ops_.AllowNoMessage();
}
// In the unary case, MaybeFinish is only ever invoked from a
// library-initiated reaction, so it will just directly call OnDone if this is
// the last reaction for this RPC.
void MaybeFinish() {
if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub(
1, std::memory_order_acq_rel) == 1)) {
::grpc::Status s = std::move(finish_status_);
auto* reactor = reactor_;
auto* call = call_.call();
this->~ClientCallbackUnaryImpl();
::grpc::g_core_codegen_interface->grpc_call_unref(call);
reactor->OnDone(s);
}
}
::grpc_impl::ClientContext* const context_;
grpc::internal::Call call_;
ClientUnaryReactor* const reactor_;
@ -1053,7 +1175,6 @@ class ClientCallbackUnaryImpl final : public ClientCallbackUnary {
// This call will have 2 callbacks: start and finish
std::atomic<intptr_t> callbacks_outstanding_{2};
bool started_{false};
};
class ClientCallbackUnaryFactory {

@ -174,6 +174,14 @@ class ServerContextBase {
/// ASCII-Value -> 1*( %x20-%x7E ) ; space and printable ASCII
void AddTrailingMetadata(const grpc::string& key, const grpc::string& value);
/// Return whether this RPC failed before the server could provide its status
/// back to the client. This could be because of explicit API cancellation
/// from the client-side or server-side, because of deadline exceeded, network
/// connection reset, HTTP/2 parameter configuration (e.g., max message size,
/// max connection age), etc. It does NOT include failure due to a non-OK
/// status return from the server application's request handler, including
/// Status::CANCELLED.
///
/// IsCancelled is always safe to call when using sync or callback API.
/// When using async API, it is only safe to call IsCancelled after
/// the AsyncNotifyWhenDone tag has been delivered. Thread-safe.
@ -181,10 +189,9 @@ class ServerContextBase {
/// Cancel the Call from the server. This is a best-effort API and
/// depending on when it is called, the RPC may still appear successful to
/// the client.
/// For example, if TryCancel() is called on a separate thread, it might race
/// with the server handler which might return success to the client before
/// TryCancel() was even started by the thread.
/// the client. For example, if TryCancel() is called on a separate thread, it
/// might race with the server handler which might return success to the
/// client before TryCancel() was even started by the thread.
///
/// It is the caller's responsibility to prevent such races and ensure that if
/// TryCancel() is called, the serverhandler must return Status::CANCELLED.
@ -192,6 +199,9 @@ class ServerContextBase {
/// error status code, it is ok to not return Status::CANCELLED even if
/// TryCancel() was called.
///
/// For reasons such as the above, it is generally preferred to explicitly
/// finish an RPC by returning Status::CANCELLED rather than using TryCancel.
///
/// Note that TryCancel() does not change any of the tags that are pending
/// on the completion queue. All pending tags will still be delivered
/// (though their ok result may reflect the effect of cancellation).

@ -97,6 +97,8 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_factory.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_factory.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_plugin.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/config_selector.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/config_selector.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/connector.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/global_subchannel_pool.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/global_subchannel_pool.h" role="src" />
@ -179,6 +181,7 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/service_config.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/service_config.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/service_config_call_data.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/service_config_parser.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/service_config_parser.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel.cc" role="src" />

@ -2,11 +2,11 @@
coverage>=4.0
cython>=0.29.8
enum34>=1.0.4
protobuf>=3.5.0.post1
protobuf>=3.5.0.post1, < 4.0dev
six>=1.10
wheel>=0.29
futures>=2.2.0
google-auth>=1.0.0
google-auth>=1.17.2
oauth2client==4.1.0
requests>=2.14.2
urllib3>=1.23

@ -2,6 +2,6 @@
coverage>=4.0
cython>=0.29.8
enum34>=1.0.4
protobuf>=3.5.0.post1
protobuf>=3.5.0.post1, < 4.0dev
six>=1.10
wheel>=0.29

@ -355,6 +355,9 @@ INSTALL_REQUIRES = (
"futures>=2.2.0; python_version<'3.2'",
"enum34>=1.0.4; python_version<'3.4'",
)
EXTRAS_REQUIRES = {
'protobuf': 'grpcio-tools>={version}'.format(version=grpc_version.VERSION),
}
SETUP_REQUIRES = INSTALL_REQUIRES + (
'Sphinx~=1.8.1',
@ -417,6 +420,7 @@ setuptools.setup(
package_dir=PACKAGE_DIRECTORIES,
package_data=PACKAGE_DATA,
install_requires=INSTALL_REQUIRES,
extras_require=EXTRAS_REQUIRES,
setup_requires=SETUP_REQUIRES,
cmdclass=COMMAND_CLASS,
)

@ -52,15 +52,16 @@ inline ::grpc::string ImportProtoHeaders(
::grpc::string base_name = header;
grpc_generator::StripPrefix(&base_name, "google/protobuf/");
::grpc::string file_name = "GPB" + base_name;
// create the import code snippet
::grpc::string framework_header =
::grpc::string(ProtobufLibraryFrameworkName) + "/" + base_name;
::grpc::string(ProtobufLibraryFrameworkName) + "/" + file_name;
static const ::grpc::string kFrameworkImportsCondition =
"GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS";
return PreprocIfElse(kFrameworkImportsCondition,
indent + SystemImport(framework_header),
indent + LocalImport(header));
indent + LocalImport(file_name));
}
} // namespace

@ -40,6 +40,7 @@
#include "src/core/ext/filters/client_channel/backend_metric.h"
#include "src/core/ext/filters/client_channel/backup_poller.h"
#include "src/core/ext/filters/client_channel/config_selector.h"
#include "src/core/ext/filters/client_channel/global_subchannel_pool.h"
#include "src/core/ext/filters/client_channel/http_connect_handshaker.h"
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
@ -149,12 +150,16 @@ class ChannelData {
bool received_service_config_data() const {
return received_service_config_data_;
}
grpc_error* resolver_transient_failure_error() const {
return resolver_transient_failure_error_;
}
RefCountedPtr<ServerRetryThrottleData> retry_throttle_data() const {
return retry_throttle_data_;
}
RefCountedPtr<ServiceConfig> service_config() const {
return service_config_;
}
ConfigSelector* config_selector() const { return config_selector_.get(); }
WorkSerializer* work_serializer() const { return work_serializer_.get(); }
RefCountedPtr<ConnectedSubchannel> GetConnectedSubchannelInDataPlane(
@ -234,6 +239,29 @@ class ChannelData {
Atomic<bool> done_{false};
};
class ChannelConfigHelper
: public ResolvingLoadBalancingPolicy::ChannelConfigHelper {
public:
explicit ChannelConfigHelper(ChannelData* chand) : chand_(chand) {}
ApplyServiceConfigResult ApplyServiceConfig(
const Resolver::Result& result) override;
void ApplyConfigSelector(
bool service_config_changed,
RefCountedPtr<ConfigSelector> config_selector) override;
void ResolverTransientFailure(grpc_error* error) override;
private:
static void ProcessLbPolicy(
const Resolver::Result& resolver_result,
const internal::ClientChannelGlobalParsedConfig* parsed_service_config,
RefCountedPtr<LoadBalancingPolicy::Config>* lb_policy_config);
ChannelData* chand_;
};
ChannelData(grpc_channel_element_args* args, grpc_error** error);
~ChannelData();
@ -241,30 +269,20 @@ class ChannelData {
grpc_connectivity_state state, const char* reason,
std::unique_ptr<LoadBalancingPolicy::SubchannelPicker> picker);
void UpdateServiceConfigLocked(
RefCountedPtr<ServerRetryThrottleData> retry_throttle_data,
RefCountedPtr<ServiceConfig> service_config);
void UpdateServiceConfigInDataPlaneLocked(
bool service_config_changed,
RefCountedPtr<ConfigSelector> config_selector);
void CreateResolvingLoadBalancingPolicyLocked();
void DestroyResolvingLoadBalancingPolicyLocked();
static bool ProcessResolverResultLocked(
void* arg, const Resolver::Result& result,
RefCountedPtr<LoadBalancingPolicy::Config>* lb_policy_config,
grpc_error** service_config_error, bool* no_valid_service_config);
grpc_error* DoPingLocked(grpc_transport_op* op);
void StartTransportOpLocked(grpc_transport_op* op);
void TryToConnectLocked();
void ProcessLbPolicy(
const Resolver::Result& resolver_result,
const internal::ClientChannelGlobalParsedConfig* parsed_service_config,
RefCountedPtr<LoadBalancingPolicy::Config>* lb_policy_config);
//
// Fields set at construction and never modified.
//
@ -278,6 +296,7 @@ class ChannelData {
grpc_core::UniquePtr<char> server_name_;
grpc_core::UniquePtr<char> target_uri_;
channelz::ChannelNode* channelz_node_;
ChannelConfigHelper channel_config_helper_;
//
// Fields used in the data plane. Guarded by data_plane_mu.
@ -286,9 +305,11 @@ class ChannelData {
std::unique_ptr<LoadBalancingPolicy::SubchannelPicker> picker_;
QueuedPick* queued_picks_ = nullptr; // Linked list of queued picks.
// Data from service config.
grpc_error* resolver_transient_failure_error_ = GRPC_ERROR_NONE;
bool received_service_config_data_ = false;
RefCountedPtr<ServerRetryThrottleData> retry_throttle_data_;
RefCountedPtr<ServiceConfig> service_config_;
RefCountedPtr<ConfigSelector> config_selector_;
//
// Fields used in the control plane. Guarded by work_serializer.
@ -300,6 +321,7 @@ class ChannelData {
ConnectivityStateTracker state_tracker_;
grpc_core::UniquePtr<char> health_check_service_name_;
RefCountedPtr<ServiceConfig> saved_service_config_;
RefCountedPtr<ConfigSelector> saved_config_selector_;
bool received_first_resolver_result_ = false;
// The number of SubchannelWrapper instances referencing a given Subchannel.
std::map<Subchannel*, int> subchannel_refcount_map_;
@ -352,9 +374,6 @@ class CallData {
RefCountedPtr<SubchannelCall> subchannel_call() { return subchannel_call_; }
// Invoked by channel for queued picks once resolver results are available.
void MaybeApplyServiceConfigToCallLocked(grpc_call_element* elem);
// Invoked by channel for queued picks when the picker is updated.
static void PickSubchannel(void* arg, grpc_error* error);
@ -742,13 +761,17 @@ class CallData {
void CreateSubchannelCall(grpc_call_element* elem);
// Invoked when a pick is completed, on both success or failure.
static void PickDone(void* arg, grpc_error* error);
// Removes the call from the channel's list of queued picks.
void RemoveCallFromQueuedPicksLocked(grpc_call_element* elem);
// Adds the call to the channel's list of queued picks.
void AddCallToQueuedPicksLocked(grpc_call_element* elem);
// Removes the call from the channel's list of queued picks if present.
void MaybeRemoveCallFromQueuedPicksLocked(grpc_call_element* elem);
// Adds the call to the channel's list of queued picks if not already present.
void MaybeAddCallToQueuedPicksLocked(grpc_call_element* elem);
// Applies service config to the call. Must be invoked once we know
// that the resolver has returned results to the channel.
void ApplyServiceConfigToCallLocked(grpc_call_element* elem);
// If an error is returned, the error indicates the status with which
// the call should be failed.
grpc_error* ApplyServiceConfigToCallLocked(
grpc_call_element* elem, grpc_metadata_batch* initial_metadata);
void MaybeInvokeConfigSelectorCommitCallback();
// State for handling deadlines.
// The code in deadline_filter.c requires this to be the first field.
@ -769,6 +792,7 @@ class CallData {
RefCountedPtr<ServerRetryThrottleData> retry_throttle_data_;
const ClientChannelMethodParsedConfig* method_params_ = nullptr;
std::map<const char*, absl::string_view> call_attributes_;
std::function<void()> on_call_committed_;
RefCountedPtr<SubchannelCall> subchannel_call_;
@ -1335,6 +1359,180 @@ class ChannelData::ClientChannelControlHelper
ChannelData* chand_;
};
//
// ChannelData::ChannelConfigHelper
//
// Synchronous callback from ResolvingLoadBalancingPolicy to process a
// resolver result update.
ChannelData::ChannelConfigHelper::ApplyServiceConfigResult
ChannelData::ChannelConfigHelper::ApplyServiceConfig(
const Resolver::Result& result) {
ApplyServiceConfigResult service_config_result;
RefCountedPtr<ServiceConfig> service_config;
// If resolver did not return a service config or returned an invalid service
// config, we need a fallback service config.
if (result.service_config_error != GRPC_ERROR_NONE) {
// If the service config was invalid, then fallback to the saved service
// config. If there is no saved config either, use the default service
// config.
if (chand_->saved_service_config_ != nullptr) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
gpr_log(GPR_INFO,
"chand=%p: resolver returned invalid service config. "
"Continuing to use previous service config.",
chand_);
}
service_config = chand_->saved_service_config_;
} else if (chand_->default_service_config_ != nullptr) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
gpr_log(GPR_INFO,
"chand=%p: resolver returned invalid service config. Using "
"default service config provided by client API.",
chand_);
}
service_config = chand_->default_service_config_;
}
} else if (result.service_config == nullptr) {
if (chand_->default_service_config_ != nullptr) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
gpr_log(GPR_INFO,
"chand=%p: resolver returned no service config. Using default "
"service config provided by client API.",
chand_);
}
service_config = chand_->default_service_config_;
}
} else {
service_config = result.service_config;
}
service_config_result.service_config_error =
GRPC_ERROR_REF(result.service_config_error);
if (service_config == nullptr &&
result.service_config_error != GRPC_ERROR_NONE) {
service_config_result.no_valid_service_config = true;
return service_config_result;
}
// Process service config.
grpc_core::UniquePtr<char> service_config_json;
const internal::ClientChannelGlobalParsedConfig* parsed_service_config =
nullptr;
if (service_config != nullptr) {
parsed_service_config =
static_cast<const internal::ClientChannelGlobalParsedConfig*>(
service_config->GetGlobalParsedConfig(
internal::ClientChannelServiceConfigParser::ParserIndex()));
}
// Check if the config has changed.
service_config_result.service_config_changed =
((service_config == nullptr) !=
(chand_->saved_service_config_ == nullptr)) ||
(service_config != nullptr &&
service_config->json_string() !=
chand_->saved_service_config_->json_string());
if (service_config_result.service_config_changed) {
service_config_json.reset(gpr_strdup(
service_config != nullptr ? service_config->json_string().c_str()
: ""));
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
gpr_log(GPR_INFO,
"chand=%p: resolver returned updated service config: \"%s\"",
chand_, service_config_json.get());
}
// Save health check service name.
if (service_config != nullptr) {
chand_->health_check_service_name_.reset(
gpr_strdup(parsed_service_config->health_check_service_name()));
} else {
chand_->health_check_service_name_.reset();
}
// Update health check service name used by existing subchannel wrappers.
for (auto* subchannel_wrapper : chand_->subchannel_wrappers_) {
subchannel_wrapper->UpdateHealthCheckServiceName(
grpc_core::UniquePtr<char>(
gpr_strdup(chand_->health_check_service_name_.get())));
}
// Save service config.
chand_->saved_service_config_ = std::move(service_config);
}
// Find LB policy config.
ProcessLbPolicy(result, parsed_service_config,
&service_config_result.lb_policy_config);
grpc_core::UniquePtr<char> lb_policy_name(
gpr_strdup((service_config_result.lb_policy_config)->name()));
// Swap out the data used by GetChannelInfo().
{
MutexLock lock(&chand_->info_mu_);
chand_->info_lb_policy_name_ = std::move(lb_policy_name);
if (service_config_json != nullptr) {
chand_->info_service_config_json_ = std::move(service_config_json);
}
}
// Return results.
return service_config_result;
}
void ChannelData::ChannelConfigHelper::ApplyConfigSelector(
bool service_config_changed,
RefCountedPtr<ConfigSelector> config_selector) {
chand_->UpdateServiceConfigInDataPlaneLocked(service_config_changed,
std::move(config_selector));
}
void ChannelData::ChannelConfigHelper::ResolverTransientFailure(
grpc_error* error) {
MutexLock lock(&chand_->data_plane_mu_);
GRPC_ERROR_UNREF(chand_->resolver_transient_failure_error_);
chand_->resolver_transient_failure_error_ = error;
}
void ChannelData::ChannelConfigHelper::ProcessLbPolicy(
const Resolver::Result& resolver_result,
const internal::ClientChannelGlobalParsedConfig* parsed_service_config,
RefCountedPtr<LoadBalancingPolicy::Config>* lb_policy_config) {
// Prefer the LB policy config found in the service config.
if (parsed_service_config != nullptr &&
parsed_service_config->parsed_lb_config() != nullptr) {
*lb_policy_config = parsed_service_config->parsed_lb_config();
return;
}
// Try the deprecated LB policy name from the service config.
// If not, try the setting from channel args.
const char* policy_name = nullptr;
if (parsed_service_config != nullptr &&
!parsed_service_config->parsed_deprecated_lb_policy().empty()) {
policy_name = parsed_service_config->parsed_deprecated_lb_policy().c_str();
} else {
const grpc_arg* channel_arg =
grpc_channel_args_find(resolver_result.args, GRPC_ARG_LB_POLICY_NAME);
policy_name = grpc_channel_arg_get_string(channel_arg);
}
// Use pick_first if nothing was specified and we didn't select grpclb
// above.
if (policy_name == nullptr) policy_name = "pick_first";
// Now that we have the policy name, construct an empty config for it.
Json config_json = Json::Array{Json::Object{
{policy_name, Json::Object{}},
}};
grpc_error* parse_error = GRPC_ERROR_NONE;
*lb_policy_config = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(
config_json, &parse_error);
// The policy name came from one of three places:
// - The deprecated loadBalancingPolicy field in the service config,
// in which case the code in ClientChannelServiceConfigParser
// already verified that the policy does not require a config.
// - One of the hard-coded values here, all of which are known to not
// require a config.
// - A channel arg, in which case the application did something that
// is a misuse of our API.
// In the first two cases, these assertions will always be true. In
// the last case, this is probably fine for now.
// TODO(roth): If the last case becomes a problem, add better error
// handling here.
GPR_ASSERT(*lb_policy_config != nullptr);
GPR_ASSERT(parse_error == GRPC_ERROR_NONE);
}
//
// ChannelData implementation
//
@ -1393,6 +1591,7 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error)
client_channel_factory_(
ClientChannelFactory::GetFromChannelArgs(args->channel_args)),
channelz_node_(GetChannelzNode(args->channel_args)),
channel_config_helper_(this),
work_serializer_(std::make_shared<WorkSerializer>()),
interested_parties_(grpc_pollset_set_create()),
subchannel_pool_(GetSubchannelPool(args->channel_args)),
@ -1461,6 +1660,7 @@ ChannelData::~ChannelData() {
}
DestroyResolvingLoadBalancingPolicyLocked();
grpc_channel_args_destroy(channel_args_);
GRPC_ERROR_UNREF(resolver_transient_failure_error_);
// Stop backup polling.
grpc_client_channel_stop_backup_polling(interested_parties_);
grpc_pollset_set_destroy(interested_parties_);
@ -1475,6 +1675,7 @@ void ChannelData::UpdateStateAndPickerLocked(
if (picker_ == nullptr) {
health_check_service_name_.reset();
saved_service_config_.reset();
saved_config_selector_.reset();
received_first_resolver_result_ = false;
}
// Update connectivity state.
@ -1497,9 +1698,11 @@ void ChannelData::UpdateStateAndPickerLocked(
// - refs to subchannel wrappers in the keys of pending_subchannel_updates_
// - ref stored in retry_throttle_data_
// - ref stored in service_config_
// - ref stored in config_selector_
// - ownership of the existing picker in picker_
RefCountedPtr<ServerRetryThrottleData> retry_throttle_data_to_unref;
RefCountedPtr<ServiceConfig> service_config_to_unref;
RefCountedPtr<ConfigSelector> config_selector_to_unref;
{
MutexLock lock(&data_plane_mu_);
// Handle subchannel updates.
@ -1524,6 +1727,7 @@ void ChannelData::UpdateStateAndPickerLocked(
// Note: We save the objects to unref until after the lock is released.
retry_throttle_data_to_unref = std::move(retry_throttle_data_);
service_config_to_unref = std::move(service_config_);
config_selector_to_unref = std::move(config_selector_);
}
// Re-process queued picks.
for (QueuedPick* pick = queued_picks_; pick != nullptr; pick = pick->next) {
@ -1540,24 +1744,72 @@ void ChannelData::UpdateStateAndPickerLocked(
pending_subchannel_updates_.clear();
}
void ChannelData::UpdateServiceConfigLocked(
RefCountedPtr<ServerRetryThrottleData> retry_throttle_data,
RefCountedPtr<ServiceConfig> service_config) {
void ChannelData::UpdateServiceConfigInDataPlaneLocked(
bool service_config_changed,
RefCountedPtr<ConfigSelector> config_selector) {
// Check if ConfigSelector has changed.
const bool config_selector_changed =
saved_config_selector_ != config_selector;
saved_config_selector_ = config_selector;
// We want to set the service config at least once, even if the
// resolver does not return a config, because that ensures that we
// disable retries if they are not enabled in the service config.
// TODO(roth): Consider removing the received_first_resolver_result_ check
// when we implement transparent retries.
if (!service_config_changed && !config_selector_changed &&
received_first_resolver_result_) {
return;
}
received_first_resolver_result_ = true;
// Get retry throttle data from service config.
RefCountedPtr<ServerRetryThrottleData> retry_throttle_data;
if (saved_service_config_ != nullptr) {
const internal::ClientChannelGlobalParsedConfig* parsed_service_config =
static_cast<const internal::ClientChannelGlobalParsedConfig*>(
saved_service_config_->GetGlobalParsedConfig(
internal::ClientChannelServiceConfigParser::ParserIndex()));
if (parsed_service_config != nullptr) {
absl::optional<internal::ClientChannelGlobalParsedConfig::RetryThrottling>
retry_throttle_config = parsed_service_config->retry_throttling();
if (retry_throttle_config.has_value()) {
retry_throttle_data =
internal::ServerRetryThrottleMap::GetDataForServer(
server_name_.get(),
retry_throttle_config.value().max_milli_tokens,
retry_throttle_config.value().milli_token_ratio);
}
}
}
// Create default config selector if not provided by resolver.
if (config_selector == nullptr) {
config_selector =
MakeRefCounted<DefaultConfigSelector>(saved_service_config_);
}
// Grab data plane lock to update service config.
//
// We defer unreffing the old values (and deallocating memory) until
// after releasing the lock to keep the critical section small.
RefCountedPtr<ServiceConfig> service_config_to_unref = saved_service_config_;
RefCountedPtr<ConfigSelector> config_selector_to_unref =
std::move(config_selector);
{
MutexLock lock(&data_plane_mu_);
GRPC_ERROR_UNREF(resolver_transient_failure_error_);
resolver_transient_failure_error_ = GRPC_ERROR_NONE;
// Update service config.
received_service_config_data_ = true;
// Old values will be unreffed after lock is released.
retry_throttle_data_.swap(retry_throttle_data);
service_config_.swap(service_config);
// Apply service config to queued picks.
service_config_.swap(service_config_to_unref);
config_selector_.swap(config_selector_to_unref);
// Re-process queued picks.
for (QueuedPick* pick = queued_picks_; pick != nullptr; pick = pick->next) {
CallData* calld = static_cast<CallData*>(pick->elem->call_data);
calld->MaybeApplyServiceConfigToCallLocked(pick->elem);
grpc_call_element* elem = pick->elem;
CallData* calld = static_cast<CallData*>(elem->call_data);
grpc_error* error = GRPC_ERROR_NONE;
if (calld->PickSubchannelLocked(elem, &error)) {
calld->AsyncPickDone(elem, error);
}
}
}
// Old values will be unreffed after lock is released when they go out
@ -1574,7 +1826,7 @@ void ChannelData::CreateResolvingLoadBalancingPolicyLocked() {
grpc_core::UniquePtr<char> target_uri(gpr_strdup(target_uri_.get()));
resolving_lb_policy_.reset(new ResolvingLoadBalancingPolicy(
std::move(lb_args), &grpc_client_channel_routing_trace,
std::move(target_uri), ProcessResolverResultLocked, this));
std::move(target_uri), &channel_config_helper_));
grpc_pollset_set_add_pollset_set(resolving_lb_policy_->interested_parties(),
interested_parties_);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
@ -1591,180 +1843,6 @@ void ChannelData::DestroyResolvingLoadBalancingPolicyLocked() {
}
}
void ChannelData::ProcessLbPolicy(
const Resolver::Result& resolver_result,
const internal::ClientChannelGlobalParsedConfig* parsed_service_config,
RefCountedPtr<LoadBalancingPolicy::Config>* lb_policy_config) {
// Prefer the LB policy config found in the service config.
if (parsed_service_config != nullptr &&
parsed_service_config->parsed_lb_config() != nullptr) {
*lb_policy_config = parsed_service_config->parsed_lb_config();
return;
}
// Try the deprecated LB policy name from the service config.
// If not, try the setting from channel args.
const char* policy_name = nullptr;
if (parsed_service_config != nullptr &&
!parsed_service_config->parsed_deprecated_lb_policy().empty()) {
policy_name = parsed_service_config->parsed_deprecated_lb_policy().c_str();
} else {
const grpc_arg* channel_arg =
grpc_channel_args_find(resolver_result.args, GRPC_ARG_LB_POLICY_NAME);
policy_name = grpc_channel_arg_get_string(channel_arg);
}
// Use pick_first if nothing was specified and we didn't select grpclb
// above.
if (policy_name == nullptr) policy_name = "pick_first";
// Now that we have the policy name, construct an empty config for it.
Json config_json = Json::Array{Json::Object{
{policy_name, Json::Object{}},
}};
grpc_error* parse_error = GRPC_ERROR_NONE;
*lb_policy_config = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(
config_json, &parse_error);
// The policy name came from one of three places:
// - The deprecated loadBalancingPolicy field in the service config,
// in which case the code in ClientChannelServiceConfigParser
// already verified that the policy does not require a config.
// - One of the hard-coded values here, all of which are known to not
// require a config.
// - A channel arg, in which case the application did something that
// is a misuse of our API.
// In the first two cases, these assertions will always be true. In
// the last case, this is probably fine for now.
// TODO(roth): If the last case becomes a problem, add better error
// handling here.
GPR_ASSERT(*lb_policy_config != nullptr);
GPR_ASSERT(parse_error == GRPC_ERROR_NONE);
}
// Synchronous callback from ResolvingLoadBalancingPolicy to process a
// resolver result update.
bool ChannelData::ProcessResolverResultLocked(
void* arg, const Resolver::Result& result,
RefCountedPtr<LoadBalancingPolicy::Config>* lb_policy_config,
grpc_error** service_config_error, bool* no_valid_service_config) {
ChannelData* chand = static_cast<ChannelData*>(arg);
RefCountedPtr<ServiceConfig> service_config;
// If resolver did not return a service config or returned an invalid service
// config, we need a fallback service config.
if (result.service_config_error != GRPC_ERROR_NONE) {
// If the service config was invalid, then fallback to the saved service
// config. If there is no saved config either, use the default service
// config.
if (chand->saved_service_config_ != nullptr) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
gpr_log(GPR_INFO,
"chand=%p: resolver returned invalid service config. "
"Continuing to use previous service config.",
chand);
}
service_config = chand->saved_service_config_;
} else if (chand->default_service_config_ != nullptr) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
gpr_log(GPR_INFO,
"chand=%p: resolver returned invalid service config. Using "
"default service config provided by client API.",
chand);
}
service_config = chand->default_service_config_;
}
} else if (result.service_config == nullptr) {
if (chand->default_service_config_ != nullptr) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
gpr_log(GPR_INFO,
"chand=%p: resolver returned no service config. Using default "
"service config provided by client API.",
chand);
}
service_config = chand->default_service_config_;
}
} else {
service_config = result.service_config;
}
*service_config_error = GRPC_ERROR_REF(result.service_config_error);
if (service_config == nullptr &&
result.service_config_error != GRPC_ERROR_NONE) {
*no_valid_service_config = true;
return false;
}
// Process service config.
grpc_core::UniquePtr<char> service_config_json;
const internal::ClientChannelGlobalParsedConfig* parsed_service_config =
nullptr;
if (service_config != nullptr) {
parsed_service_config =
static_cast<const internal::ClientChannelGlobalParsedConfig*>(
service_config->GetGlobalParsedConfig(
internal::ClientChannelServiceConfigParser::ParserIndex()));
}
// Check if the config has changed.
const bool service_config_changed =
((service_config == nullptr) !=
(chand->saved_service_config_ == nullptr)) ||
(service_config != nullptr &&
service_config->json_string() !=
chand->saved_service_config_->json_string());
if (service_config_changed) {
service_config_json.reset(gpr_strdup(
service_config != nullptr ? service_config->json_string().c_str()
: ""));
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
gpr_log(GPR_INFO,
"chand=%p: resolver returned updated service config: \"%s\"",
chand, service_config_json.get());
}
// Save health check service name.
if (service_config != nullptr) {
chand->health_check_service_name_.reset(
gpr_strdup(parsed_service_config->health_check_service_name()));
} else {
chand->health_check_service_name_.reset();
}
// Update health check service name used by existing subchannel wrappers.
for (auto* subchannel_wrapper : chand->subchannel_wrappers_) {
subchannel_wrapper->UpdateHealthCheckServiceName(
grpc_core::UniquePtr<char>(
gpr_strdup(chand->health_check_service_name_.get())));
}
// Save service config.
chand->saved_service_config_ = std::move(service_config);
}
// We want to set the service config at least once. This should not really be
// needed, but we are doing it as a defensive approach. This can be removed,
// if we feel it is unnecessary.
if (service_config_changed || !chand->received_first_resolver_result_) {
chand->received_first_resolver_result_ = true;
RefCountedPtr<ServerRetryThrottleData> retry_throttle_data;
if (parsed_service_config != nullptr) {
absl::optional<internal::ClientChannelGlobalParsedConfig::RetryThrottling>
retry_throttle_config = parsed_service_config->retry_throttling();
if (retry_throttle_config.has_value()) {
retry_throttle_data =
internal::ServerRetryThrottleMap::GetDataForServer(
chand->server_name_.get(),
retry_throttle_config.value().max_milli_tokens,
retry_throttle_config.value().milli_token_ratio);
}
}
chand->UpdateServiceConfigLocked(std::move(retry_throttle_data),
chand->saved_service_config_);
}
chand->ProcessLbPolicy(result, parsed_service_config, lb_policy_config);
grpc_core::UniquePtr<char> lb_policy_name(
gpr_strdup((*lb_policy_config)->name()));
// Swap out the data used by GetChannelInfo().
{
MutexLock lock(&chand->info_mu_);
chand->info_lb_policy_name_ = std::move(lb_policy_name);
if (service_config_json != nullptr) {
chand->info_service_config_json_ = std::move(service_config_json);
}
}
// Return results.
return service_config_changed;
}
grpc_error* ChannelData::DoPingLocked(grpc_transport_op* op) {
if (state_tracker_.state() != GRPC_CHANNEL_READY) {
return GRPC_ERROR_CREATE_FROM_STATIC_STRING("channel not connected");
@ -2807,6 +2885,7 @@ void CallData::RecvInitialMetadataReady(void* arg, grpc_error* error) {
}
// Received valid initial metadata, so commit the call.
calld->RetryCommit(elem, retry_state);
calld->MaybeInvokeConfigSelectorCommitCallback();
// Invoke the callback to return the result to the surface.
// Manually invoking a callback function; it does not take ownership of error.
calld->InvokeRecvInitialMetadataCallback(batch_data, error);
@ -2893,6 +2972,7 @@ void CallData::RecvMessageReady(void* arg, grpc_error* error) {
}
// Received a valid message, so commit the call.
calld->RetryCommit(elem, retry_state);
calld->MaybeInvokeConfigSelectorCommitCallback();
// Invoke the callback to return the result to the surface.
// Manually invoking a callback function; it does not take ownership of error.
calld->InvokeRecvMessageCallback(batch_data, error);
@ -3094,6 +3174,7 @@ void CallData::RecvTrailingMetadataReady(void* arg, grpc_error* error) {
}
// Not retrying, so commit the call.
calld->RetryCommit(elem, retry_state);
calld->MaybeInvokeConfigSelectorCommitCallback();
// Run any necessary closures.
calld->RunClosuresForCompletedCall(batch_data, GRPC_ERROR_REF(error));
}
@ -3716,7 +3797,7 @@ class CallData::QueuedPickCanceller {
}
if (calld->pick_canceller_ == self && error != GRPC_ERROR_NONE) {
// Remove pick from list of queued picks.
calld->RemoveCallFromQueuedPicksLocked(self->elem_);
calld->MaybeRemoveCallFromQueuedPicksLocked(self->elem_);
// Fail pending batches on the call.
calld->PendingBatchesFail(self->elem_, GRPC_ERROR_REF(error),
YieldCallCombinerIfPendingBatchesFound);
@ -3729,7 +3810,8 @@ class CallData::QueuedPickCanceller {
grpc_closure closure_;
};
void CallData::RemoveCallFromQueuedPicksLocked(grpc_call_element* elem) {
void CallData::MaybeRemoveCallFromQueuedPicksLocked(grpc_call_element* elem) {
if (!pick_queued_) return;
auto* chand = static_cast<ChannelData*>(elem->channel_data);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
gpr_log(GPR_INFO, "chand=%p calld=%p: removing from queued picks list",
@ -3741,7 +3823,8 @@ void CallData::RemoveCallFromQueuedPicksLocked(grpc_call_element* elem) {
pick_canceller_ = nullptr;
}
void CallData::AddCallToQueuedPicksLocked(grpc_call_element* elem) {
void CallData::MaybeAddCallToQueuedPicksLocked(grpc_call_element* elem) {
if (pick_queued_) return;
auto* chand = static_cast<ChannelData*>(elem->channel_data);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
gpr_log(GPR_INFO, "chand=%p calld=%p: adding to queued picks list", chand,
@ -3754,23 +3837,29 @@ void CallData::AddCallToQueuedPicksLocked(grpc_call_element* elem) {
pick_canceller_ = new QueuedPickCanceller(elem);
}
void CallData::ApplyServiceConfigToCallLocked(grpc_call_element* elem) {
grpc_error* CallData::ApplyServiceConfigToCallLocked(
grpc_call_element* elem, grpc_metadata_batch* initial_metadata) {
ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
gpr_log(GPR_INFO, "chand=%p calld=%p: applying service config to call",
chand, this);
}
ConfigSelector* config_selector = chand->config_selector();
auto service_config = chand->service_config();
if (service_config != nullptr) {
// Use the ConfigSelector to determine the config for the call.
ConfigSelector::CallConfig call_config =
config_selector->GetCallConfig({&path_, initial_metadata});
if (call_config.error != GRPC_ERROR_NONE) return call_config.error;
call_attributes_ = std::move(call_config.call_attributes);
on_call_committed_ = std::move(call_config.on_call_committed);
// Create a ServiceConfigCallData for the call. This stores a ref to the
// ServiceConfig and caches the right set of parsed configs to use for
// the call. The MethodConfig will store itself in the call context,
// so that it can be accessed by filters in the subchannel, and it
// will be cleaned up when the call ends.
const auto* method_params_vector =
service_config->GetMethodParsedConfigVector(path_);
auto* service_config_call_data = arena_->New<ServiceConfigCallData>(
std::move(service_config), method_params_vector, call_context_);
std::move(service_config), call_config.method_configs, call_context_);
// Apply our own method params to the call.
method_params_ = static_cast<ClientChannelMethodParsedConfig*>(
service_config_call_data->GetMethodParsedConfig(
@ -3812,16 +3901,13 @@ void CallData::ApplyServiceConfigToCallLocked(grpc_call_element* elem) {
if (method_params_ == nullptr || method_params_->retry_policy() == nullptr) {
enable_retries_ = false;
}
return GRPC_ERROR_NONE;
}
void CallData::MaybeApplyServiceConfigToCallLocked(grpc_call_element* elem) {
ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
// Apply service config data to the call only once, and only if the
// channel has the data available.
if (GPR_LIKELY(chand->received_service_config_data() &&
!service_config_applied_)) {
service_config_applied_ = true;
ApplyServiceConfigToCallLocked(elem);
void CallData::MaybeInvokeConfigSelectorCommitCallback() {
if (on_call_committed_ != nullptr) {
on_call_committed_();
on_call_committed_ = nullptr;
}
}
@ -3882,11 +3968,45 @@ bool CallData::PickSubchannelLocked(grpc_call_element* elem,
GRPC_ERROR_NONE);
// Queue the pick, so that it will be attempted once the channel
// becomes connected.
AddCallToQueuedPicksLocked(elem);
MaybeAddCallToQueuedPicksLocked(elem);
return false;
}
grpc_metadata_batch* initial_metadata_batch =
seen_send_initial_metadata_
? &send_initial_metadata_
: pending_batches_[0]
.batch->payload->send_initial_metadata.send_initial_metadata;
// Grab initial metadata flags so that we can check later if the call has
// wait_for_ready enabled.
const uint32_t send_initial_metadata_flags =
seen_send_initial_metadata_ ? send_initial_metadata_flags_
: pending_batches_[0]
.batch->payload->send_initial_metadata
.send_initial_metadata_flags;
// Avoid picking if we haven't yet received service config data.
if (GPR_UNLIKELY(!chand->received_service_config_data())) {
// If the resolver returned transient failure before returning the
// first service config, fail any non-wait_for_ready calls.
grpc_error* resolver_error = chand->resolver_transient_failure_error();
if (resolver_error != GRPC_ERROR_NONE &&
(send_initial_metadata_flags & GRPC_INITIAL_METADATA_WAIT_FOR_READY) ==
0) {
MaybeRemoveCallFromQueuedPicksLocked(elem);
*error = GRPC_ERROR_REF(resolver_error);
return true;
}
// Either the resolver has not yet returned a result, or it has
// returned transient failure but the call is wait_for_ready. In
// either case, queue the call.
MaybeAddCallToQueuedPicksLocked(elem);
return false;
}
// Apply service config to call if needed.
MaybeApplyServiceConfigToCallLocked(elem);
// Apply service config to call if not yet applied.
if (GPR_LIKELY(!service_config_applied_)) {
service_config_applied_ = true;
*error = ApplyServiceConfigToCallLocked(elem, initial_metadata_batch);
if (*error != GRPC_ERROR_NONE) return true;
}
// If this is a retry, use the send_initial_metadata payload that
// we've cached; otherwise, use the pending batch. The
// send_initial_metadata batch will be the first pending batch in the
@ -3899,20 +4019,8 @@ bool CallData::PickSubchannelLocked(grpc_call_element* elem,
// attempt) to the LB policy instead the one from the parent channel.
LoadBalancingPolicy::PickArgs pick_args;
pick_args.call_state = &lb_call_state_;
Metadata initial_metadata(
this,
seen_send_initial_metadata_
? &send_initial_metadata_
: pending_batches_[0]
.batch->payload->send_initial_metadata.send_initial_metadata);
Metadata initial_metadata(this, initial_metadata_batch);
pick_args.initial_metadata = &initial_metadata;
// Grab initial metadata flags so that we can check later if the call has
// wait_for_ready enabled.
const uint32_t send_initial_metadata_flags =
seen_send_initial_metadata_ ? send_initial_metadata_flags_
: pending_batches_[0]
.batch->payload->send_initial_metadata
.send_initial_metadata_flags;
// Attempt pick.
auto result = chand->picker()->Pick(pick_args);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
@ -3927,7 +4035,8 @@ bool CallData::PickSubchannelLocked(grpc_call_element* elem,
grpc_error* disconnect_error = chand->disconnect_error();
if (disconnect_error != GRPC_ERROR_NONE) {
GRPC_ERROR_UNREF(result.error);
if (pick_queued_) RemoveCallFromQueuedPicksLocked(elem);
MaybeRemoveCallFromQueuedPicksLocked(elem);
MaybeInvokeConfigSelectorCommitCallback();
*error = GRPC_ERROR_REF(disconnect_error);
return true;
}
@ -3948,8 +4057,9 @@ bool CallData::PickSubchannelLocked(grpc_call_element* elem,
"Failed to pick subchannel", &result.error, 1);
GRPC_ERROR_UNREF(result.error);
*error = new_error;
MaybeInvokeConfigSelectorCommitCallback();
}
if (pick_queued_) RemoveCallFromQueuedPicksLocked(elem);
MaybeRemoveCallFromQueuedPicksLocked(elem);
return !retried;
}
// If wait_for_ready is true, then queue to retry when we get a new
@ -3958,22 +4068,24 @@ bool CallData::PickSubchannelLocked(grpc_call_element* elem,
}
// Fallthrough
case LoadBalancingPolicy::PickResult::PICK_QUEUE:
if (!pick_queued_) AddCallToQueuedPicksLocked(elem);
MaybeAddCallToQueuedPicksLocked(elem);
return false;
default: // PICK_COMPLETE
if (pick_queued_) RemoveCallFromQueuedPicksLocked(elem);
MaybeRemoveCallFromQueuedPicksLocked(elem);
// Handle drops.
if (GPR_UNLIKELY(result.subchannel == nullptr)) {
result.error = grpc_error_set_int(
GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Call dropped by load balancing policy"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
MaybeInvokeConfigSelectorCommitCallback();
} else {
// Grab a ref to the connected subchannel while we're still
// holding the data plane mutex.
connected_subchannel_ =
chand->GetConnectedSubchannelInDataPlane(result.subchannel.get());
GPR_ASSERT(connected_subchannel_ != nullptr);
if (retry_committed_) MaybeInvokeConfigSelectorCommitCallback();
}
lb_recv_trailing_metadata_ready_ = result.recv_trailing_metadata_ready;
*error = result.error;

@ -0,0 +1,62 @@
//
// Copyright 2020 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include <grpc/support/port_platform.h>
#include "src/core/ext/filters/client_channel/config_selector.h"
#include "src/core/lib/channel/channel_args.h"
// Channel arg key for ConfigSelector.
#define GRPC_ARG_CONFIG_SELECTOR "grpc.internal.config_selector"
namespace grpc_core {
namespace {
void* ConfigSelectorArgCopy(void* p) {
ConfigSelector* config_selector = static_cast<ConfigSelector*>(p);
config_selector->Ref().release();
return p;
}
void ConfigSelectorArgDestroy(void* p) {
ConfigSelector* config_selector = static_cast<ConfigSelector*>(p);
config_selector->Unref();
}
int ConfigSelectorArgCmp(void* p, void* q) { return GPR_ICMP(p, q); }
const grpc_arg_pointer_vtable kChannelArgVtable = {
ConfigSelectorArgCopy, ConfigSelectorArgDestroy, ConfigSelectorArgCmp};
} // namespace
grpc_arg ConfigSelector::MakeChannelArg() const {
return grpc_channel_arg_pointer_create(
const_cast<char*>(GRPC_ARG_CONFIG_SELECTOR),
const_cast<ConfigSelector*>(this), &kChannelArgVtable);
}
RefCountedPtr<ConfigSelector> ConfigSelector::GetFromChannelArgs(
const grpc_channel_args& args) {
ConfigSelector* config_selector =
grpc_channel_args_find_pointer<ConfigSelector>(&args,
GRPC_ARG_CONFIG_SELECTOR);
return config_selector != nullptr ? config_selector->Ref() : nullptr;
}
} // namespace grpc_core

@ -0,0 +1,91 @@
//
// Copyright 2020 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CONFIG_SELECTOR_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CONFIG_SELECTOR_H
#include <grpc/support/port_platform.h>
#include <functional>
#include <map>
#include "absl/strings/string_view.h"
#include <grpc/impl/codegen/grpc_types.h>
#include <grpc/impl/codegen/slice.h>
#include "src/core/ext/filters/client_channel/service_config.h"
#include "src/core/ext/filters/client_channel/service_config_parser.h"
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/transport/metadata_batch.h"
namespace grpc_core {
// Internal API used to allow resolver implementations to override
// MethodConfig and provide input to LB policies on a per-call basis.
class ConfigSelector : public RefCounted<ConfigSelector> {
public:
struct GetCallConfigArgs {
grpc_slice* path;
grpc_metadata_batch* initial_metadata;
};
struct CallConfig {
// Can be set to indicate the call should be failed.
grpc_error* error = GRPC_ERROR_NONE;
// The per-method parsed configs that will be passed to
// ServiceConfigCallData.
const ServiceConfigParser::ParsedConfigVector* method_configs = nullptr;
// Call attributes that will be accessible to LB policy implementations.
std::map<const char*, absl::string_view> call_attributes;
// A callback that, if set, will be invoked when the call is
// committed (i.e., when we know that we will never again need to
// ask the picker for a subchannel for this call).
std::function<void()> on_call_committed;
};
virtual ~ConfigSelector() = default;
virtual CallConfig GetCallConfig(GetCallConfigArgs args) = 0;
grpc_arg MakeChannelArg() const;
static RefCountedPtr<ConfigSelector> GetFromChannelArgs(
const grpc_channel_args& args);
};
// Default ConfigSelector that gets the MethodConfig from the service config.
class DefaultConfigSelector : public ConfigSelector {
public:
explicit DefaultConfigSelector(RefCountedPtr<ServiceConfig> service_config)
: service_config_(std::move(service_config)) {}
CallConfig GetCallConfig(GetCallConfigArgs args) override {
CallConfig call_config;
if (service_config_ != nullptr) {
call_config.method_configs =
service_config_->GetMethodParsedConfigVector(*args.path);
}
return call_config;
}
private:
RefCountedPtr<ServiceConfig> service_config_;
};
} // namespace grpc_core
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CONFIG_SELECTOR_H */

@ -145,14 +145,12 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper
ResolvingLoadBalancingPolicy::ResolvingLoadBalancingPolicy(
Args args, TraceFlag* tracer, grpc_core::UniquePtr<char> target_uri,
ProcessResolverResultCallback process_resolver_result,
void* process_resolver_result_user_data)
ChannelConfigHelper* helper)
: LoadBalancingPolicy(std::move(args)),
tracer_(tracer),
target_uri_(std::move(target_uri)),
process_resolver_result_(process_resolver_result),
process_resolver_result_user_data_(process_resolver_result_user_data) {
GPR_ASSERT(process_resolver_result != nullptr);
helper_(helper) {
GPR_ASSERT(helper_ != nullptr);
resolver_ = ResolverRegistry::CreateResolver(
target_uri_.get(), args.args, interested_parties(), work_serializer(),
absl::make_unique<ResolverResultHandler>(Ref()));
@ -214,6 +212,7 @@ void ResolvingLoadBalancingPolicy::OnResolverError(grpc_error* error) {
if (lb_policy_ == nullptr) {
grpc_error* state_error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"Resolver transient failure", &error, 1);
helper_->ResolverTransientFailure(GRPC_ERROR_REF(state_error));
channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE,
absl::make_unique<TransientFailurePicker>(state_error));
@ -304,45 +303,51 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked(
TraceStringVector trace_strings;
const bool resolution_contains_addresses = result.addresses.size() > 0;
// Process the resolver result.
RefCountedPtr<LoadBalancingPolicy::Config> lb_policy_config;
bool service_config_changed = false;
std::string service_config_error_string;
if (process_resolver_result_ != nullptr) {
grpc_error* service_config_error = GRPC_ERROR_NONE;
bool no_valid_service_config = false;
service_config_changed = process_resolver_result_(
process_resolver_result_user_data_, result, &lb_policy_config,
&service_config_error, &no_valid_service_config);
if (service_config_error != GRPC_ERROR_NONE) {
service_config_error_string = grpc_error_string(service_config_error);
if (no_valid_service_config) {
ChannelConfigHelper::ApplyServiceConfigResult service_config_result;
if (helper_ != nullptr) {
service_config_result = helper_->ApplyServiceConfig(result);
if (service_config_result.service_config_error != GRPC_ERROR_NONE) {
if (service_config_result.no_valid_service_config) {
// We received an invalid service config and we don't have a
// fallback service config.
OnResolverError(service_config_error);
} else {
GRPC_ERROR_UNREF(service_config_error);
OnResolverError(service_config_result.service_config_error);
service_config_result.service_config_error = GRPC_ERROR_NONE;
}
}
} else {
lb_policy_config = child_lb_config_;
service_config_result.lb_policy_config = child_lb_config_;
}
if (lb_policy_config != nullptr) {
// Create or update LB policy, as needed.
CreateOrUpdateLbPolicyLocked(std::move(lb_policy_config),
std::move(result));
// Before we send the args to the LB policy, grab the ConfigSelector for
// later use.
RefCountedPtr<ConfigSelector> config_selector =
ConfigSelector::GetFromChannelArgs(*result.args);
// Create or update LB policy, as needed.
if (service_config_result.lb_policy_config != nullptr) {
CreateOrUpdateLbPolicyLocked(
std::move(service_config_result.lb_policy_config), std::move(result));
}
// Apply ConfigSelector to channel.
// This needs to happen after the LB policy has been updated, since
// the ConfigSelector may need the LB policy to know about new
// destinations before it can send RPCs to those destinations.
if (helper_ != nullptr) {
helper_->ApplyConfigSelector(service_config_result.service_config_changed,
std::move(config_selector));
}
// Add channel trace event.
if (service_config_changed) {
if (service_config_result.service_config_changed) {
// TODO(ncteisen): might be worth somehow including a snippet of the
// config in the trace, at the risk of bloating the trace logs.
trace_strings.push_back("Service config changed");
}
if (!service_config_error_string.empty()) {
trace_strings.push_back(service_config_error_string.c_str());
if (service_config_result.service_config_error != GRPC_ERROR_NONE) {
trace_strings.push_back(
grpc_error_string(service_config_result.service_config_error));
}
MaybeAddTraceMessagesForAddressChangesLocked(resolution_contains_addresses,
&trace_strings);
ConcatenateAndAddChannelTraceLocked(trace_strings);
GRPC_ERROR_UNREF(service_config_result.service_config_error);
}
} // namespace grpc_core

@ -23,6 +23,7 @@
#include "absl/container/inlined_vector.h"
#include "src/core/ext/filters/client_channel/config_selector.h"
#include "src/core/ext/filters/client_channel/lb_policy.h"
#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#include "src/core/ext/filters/client_channel/resolver.h"
@ -52,22 +53,37 @@ namespace grpc_core {
// child LB policy and config to use.
class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy {
public:
// Synchronous callback that takes the resolver result and sets
// lb_policy_config to point to the right data.
// Returns true if the service config has changed since the last result.
// If the returned no_valid_service_config is true, that means that we
// don't have a valid service config to use, and we should set the channel
// to be in TRANSIENT_FAILURE.
typedef bool (*ProcessResolverResultCallback)(
void* user_data, const Resolver::Result& result,
RefCountedPtr<LoadBalancingPolicy::Config>* lb_policy_config,
grpc_error** service_config_error, bool* no_valid_service_config);
// If error is set when this returns, then construction failed, and
// the caller may not use the new object.
ResolvingLoadBalancingPolicy(
Args args, TraceFlag* tracer, grpc_core::UniquePtr<char> target_uri,
ProcessResolverResultCallback process_resolver_result,
void* process_resolver_result_user_data);
class ChannelConfigHelper {
public:
struct ApplyServiceConfigResult {
// Set to true if the service config has changed since the last result.
bool service_config_changed = false;
// Set to true if we don't have a valid service config to use.
// This tells the ResolvingLoadBalancingPolicy to put the channel
// into TRANSIENT_FAILURE.
bool no_valid_service_config = false;
// A service config parsing error occurred.
grpc_error* service_config_error = GRPC_ERROR_NONE;
// The LB policy config to use.
RefCountedPtr<LoadBalancingPolicy::Config> lb_policy_config;
};
// Applies the service config to the channel.
virtual ApplyServiceConfigResult ApplyServiceConfig(
const Resolver::Result& result) = 0;
// Applies the ConfigSelector to the channel.
virtual void ApplyConfigSelector(
bool service_config_changed,
RefCountedPtr<ConfigSelector> config_selector) = 0;
// Indicates a resolver transient failure.
virtual void ResolverTransientFailure(grpc_error* error) = 0;
};
ResolvingLoadBalancingPolicy(Args args, TraceFlag* tracer,
grpc_core::UniquePtr<char> target_uri,
ChannelConfigHelper* helper);
virtual const char* name() const override { return "resolving_lb"; }
@ -105,15 +121,16 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy {
// Passed in from caller at construction time.
TraceFlag* tracer_;
grpc_core::UniquePtr<char> target_uri_;
ProcessResolverResultCallback process_resolver_result_ = nullptr;
void* process_resolver_result_user_data_ = nullptr;
grpc_core::UniquePtr<char> child_policy_name_;
RefCountedPtr<LoadBalancingPolicy::Config> child_lb_config_;
ChannelConfigHelper* helper_;
// Resolver and associated state.
OrphanablePtr<Resolver> resolver_;
bool previous_resolution_contained_addresses_ = false;
// Determined by resolver results.
grpc_core::UniquePtr<char> child_policy_name_;
RefCountedPtr<LoadBalancingPolicy::Config> child_lb_config_;
// Child LB policy.
OrphanablePtr<LoadBalancingPolicy> lb_policy_;
};

@ -0,0 +1,142 @@
//
// Copyright 2020 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// This filter reads GRPC_ARG_SERVICE_CONFIG and populates ServiceConfigCallData
// in the call context per call for direct channels.
#include <grpc/support/port_platform.h>
#include "src/core/ext/filters/client_channel/service_config_call_data.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/channel/channel_stack_builder.h"
#include "src/core/lib/surface/channel_init.h"
namespace grpc_core {
namespace {
class ServiceConfigChannelArgChannelData {
public:
explicit ServiceConfigChannelArgChannelData(
const grpc_channel_element_args* args) {
const char* service_config_str = grpc_channel_args_find_string(
args->channel_args, GRPC_ARG_SERVICE_CONFIG);
if (service_config_str != nullptr) {
grpc_error* service_config_error = GRPC_ERROR_NONE;
auto service_config =
ServiceConfig::Create(service_config_str, &service_config_error);
if (service_config_error == GRPC_ERROR_NONE) {
service_config_ = std::move(service_config);
} else {
gpr_log(GPR_ERROR, "%s", grpc_error_string(service_config_error));
}
GRPC_ERROR_UNREF(service_config_error);
}
}
RefCountedPtr<ServiceConfig> service_config() const {
return service_config_;
}
private:
RefCountedPtr<ServiceConfig> service_config_;
};
class ServiceConfigChannelArgCallData {
public:
ServiceConfigChannelArgCallData(grpc_call_element* elem,
const grpc_call_element_args* args) {
ServiceConfigChannelArgChannelData* chand =
static_cast<ServiceConfigChannelArgChannelData*>(elem->channel_data);
RefCountedPtr<ServiceConfig> service_config = chand->service_config();
if (service_config != nullptr) {
GPR_DEBUG_ASSERT(args->context != nullptr);
const auto* method_params_vector =
service_config->GetMethodParsedConfigVector(args->path);
args->arena->New<ServiceConfigCallData>(
std::move(service_config), method_params_vector, args->context);
}
}
};
grpc_error* ServiceConfigChannelArgInitCallElem(
grpc_call_element* elem, const grpc_call_element_args* args) {
ServiceConfigChannelArgCallData* calld =
static_cast<ServiceConfigChannelArgCallData*>(elem->call_data);
new (calld) ServiceConfigChannelArgCallData(elem, args);
return GRPC_ERROR_NONE;
}
void ServiceConfigChannelArgDestroyCallElem(
grpc_call_element* elem, const grpc_call_final_info* /* final_info */,
grpc_closure* /* then_schedule_closure */) {
ServiceConfigChannelArgCallData* calld =
static_cast<ServiceConfigChannelArgCallData*>(elem->call_data);
calld->~ServiceConfigChannelArgCallData();
}
grpc_error* ServiceConfigChannelArgInitChannelElem(
grpc_channel_element* elem, grpc_channel_element_args* args) {
ServiceConfigChannelArgChannelData* chand =
static_cast<ServiceConfigChannelArgChannelData*>(elem->channel_data);
new (chand) ServiceConfigChannelArgChannelData(args);
return GRPC_ERROR_NONE;
}
void ServiceConfigChannelArgDestroyChannelElem(grpc_channel_element* elem) {
ServiceConfigChannelArgChannelData* chand =
static_cast<ServiceConfigChannelArgChannelData*>(elem->channel_data);
chand->~ServiceConfigChannelArgChannelData();
}
const grpc_channel_filter ServiceConfigChannelArgFilter = {
grpc_call_next_op,
grpc_channel_next_op,
sizeof(ServiceConfigChannelArgCallData),
ServiceConfigChannelArgInitCallElem,
grpc_call_stack_ignore_set_pollset_or_pollset_set,
ServiceConfigChannelArgDestroyCallElem,
sizeof(ServiceConfigChannelArgChannelData),
ServiceConfigChannelArgInitChannelElem,
ServiceConfigChannelArgDestroyChannelElem,
grpc_channel_next_get_info,
"service_config_channel_arg"};
bool maybe_add_service_config_channel_arg_filter(
grpc_channel_stack_builder* builder, void* /* arg */) {
const grpc_channel_args* channel_args =
grpc_channel_stack_builder_get_channel_arguments(builder);
if (grpc_channel_args_want_minimal_stack(channel_args) ||
grpc_channel_args_find_string(channel_args, GRPC_ARG_SERVICE_CONFIG) ==
nullptr) {
return true;
}
return grpc_channel_stack_builder_prepend_filter(
builder, &ServiceConfigChannelArgFilter, nullptr, nullptr);
}
} // namespace
} // namespace grpc_core
void grpc_service_config_channel_arg_filter_init(void) {
grpc_channel_init_register_stage(
GRPC_CLIENT_DIRECT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
grpc_core::maybe_add_service_config_channel_arg_filter, nullptr);
}
void grpc_service_config_channel_arg_filter_shutdown(void) {}

@ -1081,6 +1081,13 @@ grpc_error* RouteConfigParse(
const envoy_api_v2_route_Route* route = routes[i];
const envoy_api_v2_route_RouteMatch* match =
envoy_api_v2_route_Route_match(route);
const google_protobuf_BoolValue* case_sensitive =
envoy_api_v2_route_RouteMatch_case_sensitive(match);
if (case_sensitive != nullptr &&
!google_protobuf_BoolValue_value(case_sensitive)) {
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"case_sensitive if set must be set to true.");
}
XdsApi::RdsUpdate::RdsRoute rds_route;
if (envoy_api_v2_route_RouteMatch_has_prefix(match)) {
upb_strview prefix = envoy_api_v2_route_RouteMatch_prefix(match);

@ -38,7 +38,8 @@ static optional_filter compress_filter = {
&grpc_message_compress_filter, GRPC_ARG_ENABLE_PER_MESSAGE_COMPRESSION};
static optional_filter decompress_filter = {
&grpc_message_decompress_filter, GRPC_ARG_ENABLE_PER_MESSAGE_DECOMPRESSION};
&grpc_core::MessageDecompressFilter,
GRPC_ARG_ENABLE_PER_MESSAGE_DECOMPRESSION};
static bool is_building_http_like_transport(
grpc_channel_stack_builder* builder) {

@ -18,6 +18,8 @@
#include <grpc/support/port_platform.h>
#include "src/core/ext/filters/http/message_compress/message_decompress_filter.h"
#include <assert.h>
#include <string.h>
@ -27,7 +29,8 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/ext/filters/http/message_compress/message_decompress_filter.h"
#include "absl/strings/str_format.h"
#include "src/core/ext/filters/message_size/message_size_filter.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/compression/algorithm_metadata.h"
#include "src/core/lib/compression/compression_args.h"
@ -37,14 +40,25 @@
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
namespace grpc_core {
namespace {
class ChannelData {};
class ChannelData {
public:
explicit ChannelData(const grpc_channel_element_args* args)
: max_recv_size_(GetMaxRecvSizeFromChannelArgs(args->channel_args)) {}
int max_recv_size() const { return max_recv_size_; }
private:
int max_recv_size_;
};
class CallData {
public:
explicit CallData(const grpc_call_element_args& args)
: call_combiner_(args.call_combiner) {
CallData(const grpc_call_element_args& args, const ChannelData* chand)
: call_combiner_(args.call_combiner),
max_recv_message_length_(chand->max_recv_size()) {
// Initialize state for recv_initial_metadata_ready callback
GRPC_CLOSURE_INIT(&on_recv_initial_metadata_ready_,
OnRecvInitialMetadataReady, this,
@ -59,6 +73,13 @@ class CallData {
GRPC_CLOSURE_INIT(&on_recv_trailing_metadata_ready_,
OnRecvTrailingMetadataReady, this,
grpc_schedule_on_exec_ctx);
const MessageSizeParsedConfig* limits =
MessageSizeParsedConfig::GetFromCallContext(args.context);
if (limits != nullptr && limits->limits().max_recv_size >= 0 &&
(limits->limits().max_recv_size < max_recv_message_length_ ||
max_recv_message_length_ < 0)) {
max_recv_message_length_ = limits->limits().max_recv_size;
}
}
~CallData() { grpc_slice_buffer_destroy_internal(&recv_slices_); }
@ -82,7 +103,7 @@ class CallData {
void MaybeResumeOnRecvTrailingMetadataReady();
static void OnRecvTrailingMetadataReady(void* arg, grpc_error* error);
grpc_core::CallCombiner* call_combiner_;
CallCombiner* call_combiner_;
// Overall error for the call
grpc_error* error_ = GRPC_ERROR_NONE;
// Fields for handling recv_initial_metadata_ready callback
@ -91,17 +112,18 @@ class CallData {
grpc_metadata_batch* recv_initial_metadata_ = nullptr;
// Fields for handling recv_message_ready callback
bool seen_recv_message_ready_ = false;
int max_recv_message_length_;
grpc_message_compression_algorithm algorithm_ = GRPC_MESSAGE_COMPRESS_NONE;
grpc_closure on_recv_message_ready_;
grpc_closure* original_recv_message_ready_ = nullptr;
grpc_closure on_recv_message_next_done_;
grpc_core::OrphanablePtr<grpc_core::ByteStream>* recv_message_ = nullptr;
OrphanablePtr<ByteStream>* recv_message_ = nullptr;
// recv_slices_ holds the slices read from the original recv_message stream.
// It is initialized during construction and reset when a new stream is
// created using it.
grpc_slice_buffer recv_slices_;
std::aligned_storage<sizeof(grpc_core::SliceBufferByteStream),
alignof(grpc_core::SliceBufferByteStream)>::type
std::aligned_storage<sizeof(SliceBufferByteStream),
alignof(SliceBufferByteStream)>::type
recv_replacement_stream_;
// Fields for handling recv_trailing_metadata_ready callback
bool seen_recv_trailing_metadata_ready_ = false;
@ -139,7 +161,7 @@ void CallData::OnRecvInitialMetadataReady(void* arg, grpc_error* error) {
calld->MaybeResumeOnRecvTrailingMetadataReady();
grpc_closure* closure = calld->original_recv_initial_metadata_ready_;
calld->original_recv_initial_metadata_ready_ = nullptr;
grpc_core::Closure::Run(DEBUG_LOCATION, closure, GRPC_ERROR_REF(error));
Closure::Run(DEBUG_LOCATION, closure, GRPC_ERROR_REF(error));
}
void CallData::MaybeResumeOnRecvMessageReady() {
@ -170,6 +192,19 @@ void CallData::OnRecvMessageReady(void* arg, grpc_error* error) {
0) {
return calld->ContinueRecvMessageReadyCallback(GRPC_ERROR_NONE);
}
if (calld->max_recv_message_length_ >= 0 &&
(*calld->recv_message_)->length() >
static_cast<uint32_t>(calld->max_recv_message_length_)) {
std::string message_string = absl::StrFormat(
"Received message larger than max (%u vs. %d)",
(*calld->recv_message_)->length(), calld->max_recv_message_length_);
GPR_DEBUG_ASSERT(calld->error_ == GRPC_ERROR_NONE);
calld->error_ = grpc_error_set_int(
GRPC_ERROR_CREATE_FROM_COPIED_STRING(message_string.c_str()),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED);
return calld->ContinueRecvMessageReadyCallback(
GRPC_ERROR_REF(calld->error_));
}
grpc_slice_buffer_destroy_internal(&calld->recv_slices_);
grpc_slice_buffer_init(&calld->recv_slices_);
return calld->ContinueReadingRecvMessage();
@ -241,9 +276,9 @@ void CallData::FinishRecvMessage() {
// Initializing recv_replacement_stream_ with decompressed_slices removes
// all the slices from decompressed_slices leaving it empty.
new (&recv_replacement_stream_)
grpc_core::SliceBufferByteStream(&decompressed_slices, recv_flags);
recv_message_->reset(reinterpret_cast<grpc_core::SliceBufferByteStream*>(
&recv_replacement_stream_));
SliceBufferByteStream(&decompressed_slices, recv_flags);
recv_message_->reset(
reinterpret_cast<SliceBufferByteStream*>(&recv_replacement_stream_));
recv_message_ = nullptr;
}
ContinueRecvMessageReadyCallback(GRPC_ERROR_REF(error_));
@ -254,7 +289,7 @@ void CallData::ContinueRecvMessageReadyCallback(grpc_error* error) {
// The surface will clean up the receiving stream if there is an error.
grpc_closure* closure = original_recv_message_ready_;
original_recv_message_ready_ = nullptr;
grpc_core::Closure::Run(DEBUG_LOCATION, closure, error);
Closure::Run(DEBUG_LOCATION, closure, error);
}
void CallData::MaybeResumeOnRecvTrailingMetadataReady() {
@ -283,7 +318,7 @@ void CallData::OnRecvTrailingMetadataReady(void* arg, grpc_error* error) {
calld->error_ = GRPC_ERROR_NONE;
grpc_closure* closure = calld->original_recv_trailing_metadata_ready_;
calld->original_recv_trailing_metadata_ready_ = nullptr;
grpc_core::Closure::Run(DEBUG_LOCATION, closure, error);
Closure::Run(DEBUG_LOCATION, closure, error);
}
void CallData::DecompressStartTransportStreamOpBatch(
@ -322,37 +357,44 @@ void DecompressStartTransportStreamOpBatch(
calld->DecompressStartTransportStreamOpBatch(elem, batch);
}
static grpc_error* DecompressInitCallElem(grpc_call_element* elem,
const grpc_call_element_args* args) {
new (elem->call_data) CallData(*args);
grpc_error* DecompressInitCallElem(grpc_call_element* elem,
const grpc_call_element_args* args) {
ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
new (elem->call_data) CallData(*args, chand);
return GRPC_ERROR_NONE;
}
static void DecompressDestroyCallElem(
grpc_call_element* elem, const grpc_call_final_info* /*final_info*/,
grpc_closure* /*ignored*/) {
void DecompressDestroyCallElem(grpc_call_element* elem,
const grpc_call_final_info* /*final_info*/,
grpc_closure* /*ignored*/) {
CallData* calld = static_cast<CallData*>(elem->call_data);
calld->~CallData();
}
static grpc_error* DecompressInitChannelElem(
grpc_channel_element* /*elem*/, grpc_channel_element_args* /*args*/) {
grpc_error* DecompressInitChannelElem(grpc_channel_element* elem,
grpc_channel_element_args* args) {
ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
new (chand) ChannelData(args);
return GRPC_ERROR_NONE;
}
void DecompressDestroyChannelElem(grpc_channel_element* /*elem*/) {}
void DecompressDestroyChannelElem(grpc_channel_element* elem) {
ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
chand->~ChannelData();
}
} // namespace
const grpc_channel_filter grpc_message_decompress_filter = {
const grpc_channel_filter MessageDecompressFilter = {
DecompressStartTransportStreamOpBatch,
grpc_channel_next_op,
sizeof(CallData),
DecompressInitCallElem,
grpc_call_stack_ignore_set_pollset_or_pollset_set,
DecompressDestroyCallElem,
0, // sizeof(ChannelData)
sizeof(ChannelData),
DecompressInitChannelElem,
DecompressDestroyChannelElem,
grpc_channel_next_get_info,
"message_decompress"};
} // namespace grpc_core

@ -23,7 +23,9 @@
#include "src/core/lib/channel/channel_stack.h"
extern const grpc_channel_filter grpc_message_decompress_filter;
namespace grpc_core {
extern const grpc_channel_filter MessageDecompressFilter;
} // namespace grpc_core
#endif /* GRPC_CORE_EXT_FILTERS_HTTP_MESSAGE_COMPRESS_MESSAGE_DECOMPRESS_FILTER_H \
*/

@ -45,6 +45,25 @@ namespace {
size_t g_message_size_parser_index;
} // namespace
//
// MessageSizeParsedConfig
//
const MessageSizeParsedConfig* MessageSizeParsedConfig::GetFromCallContext(
const grpc_call_context_element* context) {
if (context == nullptr) return nullptr;
auto* svc_cfg_call_data = static_cast<ServiceConfigCallData*>(
context[GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA].value);
if (svc_cfg_call_data == nullptr) return nullptr;
return static_cast<const MessageSizeParsedConfig*>(
svc_cfg_call_data->GetMethodParsedConfig(
MessageSizeParser::ParserIndex()));
}
//
// MessageSizeParser
//
std::unique_ptr<ServiceConfigParser::ParsedConfig>
MessageSizeParser::ParsePerMethodParams(const Json& json, grpc_error** error) {
GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
@ -97,12 +116,26 @@ void MessageSizeParser::Register() {
}
size_t MessageSizeParser::ParserIndex() { return g_message_size_parser_index; }
int GetMaxRecvSizeFromChannelArgs(const grpc_channel_args* args) {
if (grpc_channel_args_want_minimal_stack(args)) return -1;
return grpc_channel_args_find_integer(
args, GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH,
{GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH, -1, INT_MAX});
}
int GetMaxSendSizeFromChannelArgs(const grpc_channel_args* args) {
if (grpc_channel_args_want_minimal_stack(args)) return -1;
return grpc_channel_args_find_integer(
args, GRPC_ARG_MAX_SEND_MESSAGE_LENGTH,
{GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH, -1, INT_MAX});
}
} // namespace grpc_core
namespace {
struct channel_data {
grpc_core::MessageSizeParsedConfig::message_size_limits limits;
grpc_core::RefCountedPtr<grpc_core::ServiceConfig> svc_cfg;
};
struct call_data {
@ -118,24 +151,8 @@ struct call_data {
// Note: Per-method config is only available on the client, so we
// apply the max request size to the send limit and the max response
// size to the receive limit.
const grpc_core::MessageSizeParsedConfig* limits = nullptr;
grpc_core::ServiceConfigCallData* svc_cfg_call_data = nullptr;
if (args.context != nullptr) {
svc_cfg_call_data = static_cast<grpc_core::ServiceConfigCallData*>(
args.context[GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA].value);
}
if (svc_cfg_call_data != nullptr) {
limits = static_cast<const grpc_core::MessageSizeParsedConfig*>(
svc_cfg_call_data->GetMethodParsedConfig(
grpc_core::MessageSizeParser::ParserIndex()));
} else if (chand.svc_cfg != nullptr) {
const auto* objs_vector =
chand.svc_cfg->GetMethodParsedConfigVector(args.path);
if (objs_vector != nullptr) {
limits = static_cast<const grpc_core::MessageSizeParsedConfig*>(
(*objs_vector)[grpc_core::MessageSizeParser::ParserIndex()].get());
}
}
const grpc_core::MessageSizeParsedConfig* limits =
grpc_core::MessageSizeParsedConfig::GetFromCallContext(args.context);
if (limits != nullptr) {
if (limits->limits().max_send_size >= 0 &&
(limits->limits().max_send_size < this->limits.max_send_size ||
@ -288,35 +305,11 @@ static void message_size_destroy_call_elem(
calld->~call_data();
}
static int default_size(const grpc_channel_args* args,
int without_minimal_stack) {
if (grpc_channel_args_want_minimal_stack(args)) {
return -1;
}
return without_minimal_stack;
}
grpc_core::MessageSizeParsedConfig::message_size_limits get_message_size_limits(
const grpc_channel_args* channel_args) {
grpc_core::MessageSizeParsedConfig::message_size_limits lim;
lim.max_send_size =
default_size(channel_args, GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH);
lim.max_recv_size =
default_size(channel_args, GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH);
for (size_t i = 0; i < channel_args->num_args; ++i) {
if (strcmp(channel_args->args[i].key, GRPC_ARG_MAX_SEND_MESSAGE_LENGTH) ==
0) {
const grpc_integer_options options = {lim.max_send_size, -1, INT_MAX};
lim.max_send_size =
grpc_channel_arg_get_integer(&channel_args->args[i], options);
}
if (strcmp(channel_args->args[i].key,
GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH) == 0) {
const grpc_integer_options options = {lim.max_recv_size, -1, INT_MAX};
lim.max_recv_size =
grpc_channel_arg_get_integer(&channel_args->args[i], options);
}
}
lim.max_send_size = grpc_core::GetMaxSendSizeFromChannelArgs(channel_args);
lim.max_recv_size = grpc_core::GetMaxRecvSizeFromChannelArgs(channel_args);
return lim;
}
@ -327,26 +320,6 @@ static grpc_error* message_size_init_channel_elem(
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
new (chand) channel_data();
chand->limits = get_message_size_limits(args->channel_args);
// TODO(yashykt): We only need to read GRPC_ARG_SERVICE_CONFIG in the case of
// direct channels. (Service config is otherwise stored in the call_context by
// client_channel filter.) If we ever need a second filter that also needs to
// parse GRPC_ARG_SERVICE_CONFIG, we should refactor this code and add a
// separate filter that reads GRPC_ARG_SERVICE_CONFIG and saves the parsed
// config in the call_context.
const grpc_arg* channel_arg =
grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVICE_CONFIG);
const char* service_config_str = grpc_channel_arg_get_string(channel_arg);
if (service_config_str != nullptr) {
grpc_error* service_config_error = GRPC_ERROR_NONE;
auto svc_cfg = grpc_core::ServiceConfig::Create(service_config_str,
&service_config_error);
if (service_config_error == GRPC_ERROR_NONE) {
chand->svc_cfg = std::move(svc_cfg);
} else {
gpr_log(GPR_ERROR, "%s", grpc_error_string(service_config_error));
}
GRPC_ERROR_UNREF(service_config_error);
}
return GRPC_ERROR_NONE;
}
@ -387,6 +360,9 @@ static bool maybe_add_message_size_filter(grpc_channel_stack_builder* builder,
void* /*arg*/) {
const grpc_channel_args* channel_args =
grpc_channel_stack_builder_get_channel_arguments(builder);
if (grpc_channel_args_want_minimal_stack(channel_args)) {
return true;
}
bool enable = false;
grpc_core::MessageSizeParsedConfig::message_size_limits lim =
get_message_size_limits(channel_args);

@ -40,6 +40,9 @@ class MessageSizeParsedConfig : public ServiceConfigParser::ParsedConfig {
const message_size_limits& limits() const { return limits_; }
static const MessageSizeParsedConfig* GetFromCallContext(
const grpc_call_context_element* context);
private:
message_size_limits limits_;
};
@ -54,6 +57,9 @@ class MessageSizeParser : public ServiceConfigParser::Parser {
static size_t ParserIndex();
};
int GetMaxRecvSizeFromChannelArgs(const grpc_channel_args* args);
int GetMaxSendSizeFromChannelArgs(const grpc_channel_args* args);
} // namespace grpc_core
#endif /* GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_FILTER_H */

@ -39,6 +39,8 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/handshaker.h"
#include "src/core/lib/channel/handshaker_registry.h"
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/resource_quota.h"
@ -47,405 +49,439 @@
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/server.h"
struct server_state {
grpc_server* server;
grpc_tcp_server* tcp_server;
grpc_channel_args* args;
gpr_mu mu;
bool shutdown;
grpc_closure tcp_server_shutdown_complete;
grpc_closure* server_destroy_listener_done;
grpc_core::HandshakeManager* pending_handshake_mgrs;
grpc_core::RefCountedPtr<grpc_core::channelz::ListenSocketNode>
channelz_listen_socket;
};
namespace grpc_core {
namespace {
class Chttp2ServerListener : public ServerListenerInterface {
public:
static grpc_error* Create(grpc_server* server, const char* addr,
grpc_channel_args* args, int* port_num);
static grpc_error* CreateWithAcceptor(grpc_server* server, const char* name,
grpc_channel_args* args);
// Do not instantiate directly. Use one of the factory methods above.
Chttp2ServerListener(grpc_server* server, grpc_channel_args* args);
~Chttp2ServerListener();
void Start(grpc_server* server, grpc_pollset** pollsets,
size_t npollsets) override;
channelz::ListenSocketNode* channelz_listen_socket_node() const override {
return channelz_listen_socket_.get();
}
void SetOnDestroyDone(grpc_closure* on_destroy_done) override;
void Orphan() override;
private:
class ConnectionState : public RefCounted<ConnectionState> {
public:
ConnectionState(Chttp2ServerListener* listener,
grpc_pollset* accepting_pollset,
grpc_tcp_server_acceptor* acceptor,
RefCountedPtr<HandshakeManager> handshake_mgr,
grpc_channel_args* args, grpc_endpoint* endpoint);
~ConnectionState();
private:
static void OnTimeout(void* arg, grpc_error* error);
static void OnReceiveSettings(void* arg, grpc_error* error);
static void OnHandshakeDone(void* arg, grpc_error* error);
struct server_connection_state {
gpr_refcount refs;
server_state* svr_state;
grpc_pollset* accepting_pollset;
grpc_tcp_server_acceptor* acceptor;
grpc_core::RefCountedPtr<grpc_core::HandshakeManager> handshake_mgr;
// State for enforcing handshake timeout on receiving HTTP/2 settings.
grpc_chttp2_transport* transport;
grpc_millis deadline;
grpc_timer timer;
grpc_closure on_timeout;
grpc_closure on_receive_settings;
grpc_pollset_set* interested_parties;
Chttp2ServerListener* const listener_;
grpc_pollset* const accepting_pollset_;
grpc_tcp_server_acceptor* const acceptor_;
RefCountedPtr<HandshakeManager> handshake_mgr_;
// State for enforcing handshake timeout on receiving HTTP/2 settings.
grpc_chttp2_transport* transport_ = nullptr;
grpc_millis deadline_;
grpc_timer timer_;
grpc_closure on_timeout_;
grpc_closure on_receive_settings_;
grpc_pollset_set* const interested_parties_;
};
static void OnAccept(void* arg, grpc_endpoint* tcp,
grpc_pollset* accepting_pollset,
grpc_tcp_server_acceptor* acceptor);
RefCountedPtr<HandshakeManager> CreateHandshakeManager();
static void TcpServerShutdownComplete(void* arg, grpc_error* error);
static void DestroyListener(grpc_server* /*server*/, void* arg,
grpc_closure* destroy_done);
grpc_server* const server_;
grpc_channel_args* const args_;
grpc_tcp_server* tcp_server_;
Mutex mu_;
bool shutdown_ = true;
grpc_closure tcp_server_shutdown_complete_;
grpc_closure* on_destroy_done_ = nullptr;
HandshakeManager* pending_handshake_mgrs_ = nullptr;
RefCountedPtr<channelz::ListenSocketNode> channelz_listen_socket_;
};
static void server_connection_state_unref(
server_connection_state* connection_state) {
if (gpr_unref(&connection_state->refs)) {
if (connection_state->transport != nullptr) {
GRPC_CHTTP2_UNREF_TRANSPORT(connection_state->transport,
"receive settings timeout");
}
grpc_pollset_set_del_pollset(connection_state->interested_parties,
connection_state->accepting_pollset);
grpc_pollset_set_destroy(connection_state->interested_parties);
gpr_free(connection_state);
//
// Chttp2ServerListener::ConnectionState
//
grpc_millis GetConnectionDeadline(const grpc_channel_args* args) {
int timeout_ms =
grpc_channel_args_find_integer(args, GRPC_ARG_SERVER_HANDSHAKE_TIMEOUT_MS,
{120 * GPR_MS_PER_SEC, 1, INT_MAX});
return ExecCtx::Get()->Now() + timeout_ms;
}
Chttp2ServerListener::ConnectionState::ConnectionState(
Chttp2ServerListener* listener, grpc_pollset* accepting_pollset,
grpc_tcp_server_acceptor* acceptor,
RefCountedPtr<HandshakeManager> handshake_mgr, grpc_channel_args* args,
grpc_endpoint* endpoint)
: listener_(listener),
accepting_pollset_(accepting_pollset),
acceptor_(acceptor),
handshake_mgr_(std::move(handshake_mgr)),
deadline_(GetConnectionDeadline(args)),
interested_parties_(grpc_pollset_set_create()) {
grpc_pollset_set_add_pollset(interested_parties_, accepting_pollset_);
HandshakerRegistry::AddHandshakers(HANDSHAKER_SERVER, args,
interested_parties_, handshake_mgr_.get());
handshake_mgr_->DoHandshake(endpoint, args, deadline_, acceptor_,
OnHandshakeDone, this);
}
Chttp2ServerListener::ConnectionState::~ConnectionState() {
if (transport_ != nullptr) {
GRPC_CHTTP2_UNREF_TRANSPORT(transport_, "receive settings timeout");
}
grpc_pollset_set_del_pollset(interested_parties_, accepting_pollset_);
grpc_pollset_set_destroy(interested_parties_);
}
static void on_timeout(void* arg, grpc_error* error) {
server_connection_state* connection_state =
static_cast<server_connection_state*>(arg);
void Chttp2ServerListener::ConnectionState::OnTimeout(void* arg,
grpc_error* error) {
ConnectionState* self = static_cast<ConnectionState*>(arg);
// Note that we may be called with GRPC_ERROR_NONE when the timer fires
// or with an error indicating that the timer system is being shut down.
if (error != GRPC_ERROR_CANCELLED) {
grpc_transport_op* op = grpc_make_transport_op(nullptr);
op->disconnect_with_error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Did not receive HTTP/2 settings before handshake timeout");
grpc_transport_perform_op(&connection_state->transport->base, op);
grpc_transport_perform_op(&self->transport_->base, op);
}
server_connection_state_unref(connection_state);
self->Unref();
}
static void on_receive_settings(void* arg, grpc_error* error) {
server_connection_state* connection_state =
static_cast<server_connection_state*>(arg);
void Chttp2ServerListener::ConnectionState::OnReceiveSettings(
void* arg, grpc_error* error) {
ConnectionState* self = static_cast<ConnectionState*>(arg);
if (error == GRPC_ERROR_NONE) {
grpc_timer_cancel(&connection_state->timer);
grpc_timer_cancel(&self->timer_);
}
server_connection_state_unref(connection_state);
self->Unref();
}
static void on_handshake_done(void* arg, grpc_error* error) {
auto* args = static_cast<grpc_core::HandshakerArgs*>(arg);
server_connection_state* connection_state =
static_cast<server_connection_state*>(args->user_data);
gpr_mu_lock(&connection_state->svr_state->mu);
grpc_resource_user* resource_user = grpc_server_get_default_resource_user(
connection_state->svr_state->server);
if (error != GRPC_ERROR_NONE || connection_state->svr_state->shutdown) {
const char* error_str = grpc_error_string(error);
gpr_log(GPR_DEBUG, "Handshaking failed: %s", error_str);
grpc_resource_user* resource_user = grpc_server_get_default_resource_user(
connection_state->svr_state->server);
if (resource_user != nullptr) {
grpc_resource_user_free(resource_user, GRPC_RESOURCE_QUOTA_CHANNEL_SIZE);
}
if (error == GRPC_ERROR_NONE && args->endpoint != nullptr) {
// We were shut down after handshaking completed successfully, so
// destroy the endpoint here.
// TODO(ctiller): It is currently necessary to shutdown endpoints
// before destroying them, even if we know that there are no
// pending read/write callbacks. This should be fixed, at which
// point this can be removed.
grpc_endpoint_shutdown(args->endpoint, GRPC_ERROR_NONE);
grpc_endpoint_destroy(args->endpoint);
grpc_channel_args_destroy(args->args);
grpc_slice_buffer_destroy_internal(args->read_buffer);
gpr_free(args->read_buffer);
}
} else {
// If the handshaking succeeded but there is no endpoint, then the
// handshaker may have handed off the connection to some external
// code, so we can just clean up here without creating a transport.
if (args->endpoint != nullptr) {
grpc_transport* transport = grpc_create_chttp2_transport(
args->args, args->endpoint, false, resource_user);
grpc_server_setup_transport(
connection_state->svr_state->server, transport,
connection_state->accepting_pollset, args->args,
grpc_chttp2_transport_get_socket_node(transport), resource_user);
// Use notify_on_receive_settings callback to enforce the
// handshake deadline.
connection_state->transport =
reinterpret_cast<grpc_chttp2_transport*>(transport);
gpr_ref(&connection_state->refs);
GRPC_CLOSURE_INIT(&connection_state->on_receive_settings,
on_receive_settings, connection_state,
grpc_schedule_on_exec_ctx);
grpc_chttp2_transport_start_reading(
transport, args->read_buffer, &connection_state->on_receive_settings);
grpc_channel_args_destroy(args->args);
gpr_ref(&connection_state->refs);
GRPC_CHTTP2_REF_TRANSPORT((grpc_chttp2_transport*)transport,
"receive settings timeout");
GRPC_CLOSURE_INIT(&connection_state->on_timeout, on_timeout,
connection_state, grpc_schedule_on_exec_ctx);
grpc_timer_init(&connection_state->timer, connection_state->deadline,
&connection_state->on_timeout);
} else {
void Chttp2ServerListener::ConnectionState::OnHandshakeDone(void* arg,
grpc_error* error) {
auto* args = static_cast<HandshakerArgs*>(arg);
ConnectionState* self = static_cast<ConnectionState*>(args->user_data);
{
MutexLock lock(&self->listener_->mu_);
grpc_resource_user* resource_user =
grpc_server_get_default_resource_user(self->listener_->server_);
if (error != GRPC_ERROR_NONE || self->listener_->shutdown_) {
const char* error_str = grpc_error_string(error);
gpr_log(GPR_DEBUG, "Handshaking failed: %s", error_str);
grpc_resource_user* resource_user =
grpc_server_get_default_resource_user(self->listener_->server_);
if (resource_user != nullptr) {
grpc_resource_user_free(resource_user,
GRPC_RESOURCE_QUOTA_CHANNEL_SIZE);
}
if (error == GRPC_ERROR_NONE && args->endpoint != nullptr) {
// We were shut down after handshaking completed successfully, so
// destroy the endpoint here.
// TODO(ctiller): It is currently necessary to shutdown endpoints
// before destroying them, even if we know that there are no
// pending read/write callbacks. This should be fixed, at which
// point this can be removed.
grpc_endpoint_shutdown(args->endpoint, GRPC_ERROR_NONE);
grpc_endpoint_destroy(args->endpoint);
grpc_channel_args_destroy(args->args);
grpc_slice_buffer_destroy_internal(args->read_buffer);
gpr_free(args->read_buffer);
}
} else {
// If the handshaking succeeded but there is no endpoint, then the
// handshaker may have handed off the connection to some external
// code, so we can just clean up here without creating a transport.
if (args->endpoint != nullptr) {
grpc_transport* transport = grpc_create_chttp2_transport(
args->args, args->endpoint, false, resource_user);
grpc_server_setup_transport(
self->listener_->server_, transport, self->accepting_pollset_,
args->args, grpc_chttp2_transport_get_socket_node(transport),
resource_user);
// Use notify_on_receive_settings callback to enforce the
// handshake deadline.
// Note: The reinterpret_cast<>s here are safe, because
// grpc_chttp2_transport is a C-style extension of
// grpc_transport, so this is morally equivalent of a
// static_cast<> to a derived class.
// TODO(roth): Change to static_cast<> when we C++-ify the
// transport API.
self->transport_ = reinterpret_cast<grpc_chttp2_transport*>(transport);
self->Ref().release(); // Held by OnReceiveSettings().
GRPC_CLOSURE_INIT(&self->on_receive_settings_, OnReceiveSettings, self,
grpc_schedule_on_exec_ctx);
grpc_chttp2_transport_start_reading(transport, args->read_buffer,
&self->on_receive_settings_);
grpc_channel_args_destroy(args->args);
self->Ref().release(); // Held by OnTimeout().
GRPC_CHTTP2_REF_TRANSPORT(
reinterpret_cast<grpc_chttp2_transport*>(transport),
"receive settings timeout");
GRPC_CLOSURE_INIT(&self->on_timeout_, OnTimeout, self,
grpc_schedule_on_exec_ctx);
grpc_timer_init(&self->timer_, self->deadline_, &self->on_timeout_);
} else {
if (resource_user != nullptr) {
grpc_resource_user_free(resource_user,
GRPC_RESOURCE_QUOTA_CHANNEL_SIZE);
}
}
}
self->handshake_mgr_->RemoveFromPendingMgrList(
&self->listener_->pending_handshake_mgrs_);
}
connection_state->handshake_mgr->RemoveFromPendingMgrList(
&connection_state->svr_state->pending_handshake_mgrs);
gpr_mu_unlock(&connection_state->svr_state->mu);
connection_state->handshake_mgr.reset();
gpr_free(connection_state->acceptor);
grpc_tcp_server_unref(connection_state->svr_state->tcp_server);
server_connection_state_unref(connection_state);
self->handshake_mgr_.reset();
gpr_free(self->acceptor_);
grpc_tcp_server_unref(self->listener_->tcp_server_);
self->Unref();
}
static void on_accept(void* arg, grpc_endpoint* tcp,
grpc_pollset* accepting_pollset,
grpc_tcp_server_acceptor* acceptor) {
server_state* state = static_cast<server_state*>(arg);
gpr_mu_lock(&state->mu);
if (state->shutdown) {
gpr_mu_unlock(&state->mu);
grpc_endpoint_shutdown(tcp, GRPC_ERROR_NONE);
grpc_endpoint_destroy(tcp);
gpr_free(acceptor);
return;
//
// Chttp2ServerListener
//
grpc_error* Chttp2ServerListener::Create(grpc_server* server, const char* addr,
grpc_channel_args* args,
int* port_num) {
std::vector<grpc_error*> error_list;
grpc_resolved_addresses* resolved = nullptr;
Chttp2ServerListener* listener = nullptr;
// The bulk of this method is inside of a lambda to make cleanup
// easier without using goto.
grpc_error* error = [&]() {
*port_num = -1;
/* resolve address */
grpc_error* error = grpc_blocking_resolve_address(addr, "https", &resolved);
if (error != GRPC_ERROR_NONE) return error;
// Create Chttp2ServerListener.
listener = new Chttp2ServerListener(server, args);
error = grpc_tcp_server_create(&listener->tcp_server_shutdown_complete_,
args, &listener->tcp_server_);
if (error != GRPC_ERROR_NONE) return error;
for (size_t i = 0; i < resolved->naddrs; i++) {
int port_temp;
error = grpc_tcp_server_add_port(listener->tcp_server_,
&resolved->addrs[i], &port_temp);
if (error != GRPC_ERROR_NONE) {
error_list.push_back(error);
} else {
if (*port_num == -1) {
*port_num = port_temp;
} else {
GPR_ASSERT(*port_num == port_temp);
}
}
}
if (error_list.size() == resolved->naddrs) {
std::string msg =
absl::StrFormat("No address added out of total %" PRIuPTR " resolved",
resolved->naddrs);
return GRPC_ERROR_CREATE_REFERENCING_FROM_COPIED_STRING(
msg.c_str(), error_list.data(), error_list.size());
} else if (!error_list.empty()) {
std::string msg = absl::StrFormat(
"Only %" PRIuPTR " addresses added out of total %" PRIuPTR
" resolved",
resolved->naddrs - error_list.size(), resolved->naddrs);
error = GRPC_ERROR_CREATE_REFERENCING_FROM_COPIED_STRING(
msg.c_str(), error_list.data(), error_list.size());
gpr_log(GPR_INFO, "WARNING: %s", grpc_error_string(error));
GRPC_ERROR_UNREF(error);
/* we managed to bind some addresses: continue */
}
// Create channelz node.
if (grpc_channel_args_find_bool(args, GRPC_ARG_ENABLE_CHANNELZ,
GRPC_ENABLE_CHANNELZ_DEFAULT)) {
listener->channelz_listen_socket_ =
MakeRefCounted<channelz::ListenSocketNode>(
addr, absl::StrFormat("chttp2 listener %s", addr));
}
/* Register with the server only upon success */
grpc_server_add_listener(server,
OrphanablePtr<ServerListenerInterface>(listener));
return GRPC_ERROR_NONE;
}();
if (resolved != nullptr) {
grpc_resolved_addresses_destroy(resolved);
}
if (error != GRPC_ERROR_NONE) {
if (listener != nullptr) {
if (listener->tcp_server_ != nullptr) {
grpc_tcp_server_unref(listener->tcp_server_);
} else {
delete listener;
}
} else {
grpc_channel_args_destroy(args);
}
*port_num = 0;
}
for (grpc_error* error : error_list) {
GRPC_ERROR_UNREF(error);
}
return error;
}
grpc_error* Chttp2ServerListener::CreateWithAcceptor(grpc_server* server,
const char* name,
grpc_channel_args* args) {
Chttp2ServerListener* listener = new Chttp2ServerListener(server, args);
grpc_error* error = grpc_tcp_server_create(
&listener->tcp_server_shutdown_complete_, args, &listener->tcp_server_);
if (error != GRPC_ERROR_NONE) {
delete listener;
return error;
}
// TODO(yangg) channelz
TcpServerFdHandler** arg_val =
grpc_channel_args_find_pointer<TcpServerFdHandler*>(args, name);
*arg_val = grpc_tcp_server_create_fd_handler(listener->tcp_server_);
grpc_server_add_listener(server,
OrphanablePtr<ServerListenerInterface>(listener));
return GRPC_ERROR_NONE;
}
Chttp2ServerListener::Chttp2ServerListener(grpc_server* server,
grpc_channel_args* args)
: server_(server), args_(args) {
GRPC_CLOSURE_INIT(&tcp_server_shutdown_complete_, TcpServerShutdownComplete,
this, grpc_schedule_on_exec_ctx);
}
Chttp2ServerListener::~Chttp2ServerListener() {
grpc_channel_args_destroy(args_);
}
/* Server callback: start listening on our ports */
void Chttp2ServerListener::Start(grpc_server* /*server*/,
grpc_pollset** pollsets,
size_t pollset_count) {
{
MutexLock lock(&mu_);
shutdown_ = false;
}
grpc_tcp_server_start(tcp_server_, pollsets, pollset_count, OnAccept, this);
}
void Chttp2ServerListener::SetOnDestroyDone(grpc_closure* on_destroy_done) {
MutexLock lock(&mu_);
on_destroy_done_ = on_destroy_done;
}
RefCountedPtr<HandshakeManager> Chttp2ServerListener::CreateHandshakeManager() {
MutexLock lock(&mu_);
if (shutdown_) return nullptr;
grpc_resource_user* resource_user =
grpc_server_get_default_resource_user(state->server);
grpc_server_get_default_resource_user(server_);
if (resource_user != nullptr &&
!grpc_resource_user_safe_alloc(resource_user,
GRPC_RESOURCE_QUOTA_CHANNEL_SIZE)) {
gpr_log(
GPR_ERROR,
"Memory quota exhausted, rejecting the connection, no handshaking.");
gpr_mu_unlock(&state->mu);
gpr_log(GPR_ERROR,
"Memory quota exhausted, rejecting connection, no handshaking.");
return nullptr;
}
auto handshake_mgr = MakeRefCounted<HandshakeManager>();
handshake_mgr->AddToPendingMgrList(&pending_handshake_mgrs_);
grpc_tcp_server_ref(tcp_server_); // Ref held by ConnectionState.
return handshake_mgr;
}
void Chttp2ServerListener::OnAccept(void* arg, grpc_endpoint* tcp,
grpc_pollset* accepting_pollset,
grpc_tcp_server_acceptor* acceptor) {
Chttp2ServerListener* self = static_cast<Chttp2ServerListener*>(arg);
RefCountedPtr<HandshakeManager> handshake_mgr =
self->CreateHandshakeManager();
if (handshake_mgr == nullptr) {
grpc_endpoint_shutdown(tcp, GRPC_ERROR_NONE);
grpc_endpoint_destroy(tcp);
gpr_free(acceptor);
return;
}
auto handshake_mgr = grpc_core::MakeRefCounted<grpc_core::HandshakeManager>();
handshake_mgr->AddToPendingMgrList(&state->pending_handshake_mgrs);
grpc_tcp_server_ref(state->tcp_server);
gpr_mu_unlock(&state->mu);
server_connection_state* connection_state =
static_cast<server_connection_state*>(
gpr_zalloc(sizeof(*connection_state)));
gpr_ref_init(&connection_state->refs, 1);
connection_state->svr_state = state;
connection_state->accepting_pollset = accepting_pollset;
connection_state->acceptor = acceptor;
connection_state->handshake_mgr = handshake_mgr;
connection_state->interested_parties = grpc_pollset_set_create();
grpc_pollset_set_add_pollset(connection_state->interested_parties,
connection_state->accepting_pollset);
grpc_core::HandshakerRegistry::AddHandshakers(
grpc_core::HANDSHAKER_SERVER, state->args,
connection_state->interested_parties,
connection_state->handshake_mgr.get());
const grpc_arg* timeout_arg =
grpc_channel_args_find(state->args, GRPC_ARG_SERVER_HANDSHAKE_TIMEOUT_MS);
connection_state->deadline =
grpc_core::ExecCtx::Get()->Now() +
grpc_channel_arg_get_integer(timeout_arg,
{120 * GPR_MS_PER_SEC, 1, INT_MAX});
connection_state->handshake_mgr->DoHandshake(
tcp, state->args, connection_state->deadline, acceptor, on_handshake_done,
connection_state);
}
/* Server callback: start listening on our ports */
static void server_start_listener(grpc_server* /*server*/, void* arg,
grpc_pollset** pollsets,
size_t pollset_count) {
server_state* state = static_cast<server_state*>(arg);
gpr_mu_lock(&state->mu);
state->shutdown = false;
gpr_mu_unlock(&state->mu);
grpc_tcp_server_start(state->tcp_server, pollsets, pollset_count, on_accept,
state);
// Deletes itself when done.
new ConnectionState(self, accepting_pollset, acceptor,
std::move(handshake_mgr), self->args_, tcp);
}
static void tcp_server_shutdown_complete(void* arg, grpc_error* error) {
server_state* state = static_cast<server_state*>(arg);
void Chttp2ServerListener::TcpServerShutdownComplete(void* arg,
grpc_error* error) {
Chttp2ServerListener* self = static_cast<Chttp2ServerListener*>(arg);
/* ensure all threads have unlocked */
gpr_mu_lock(&state->mu);
grpc_closure* destroy_done = state->server_destroy_listener_done;
GPR_ASSERT(state->shutdown);
if (state->pending_handshake_mgrs != nullptr) {
state->pending_handshake_mgrs->ShutdownAllPending(GRPC_ERROR_REF(error));
grpc_closure* destroy_done = nullptr;
{
MutexLock lock(&self->mu_);
destroy_done = self->on_destroy_done_;
GPR_ASSERT(self->shutdown_);
if (self->pending_handshake_mgrs_ != nullptr) {
self->pending_handshake_mgrs_->ShutdownAllPending(GRPC_ERROR_REF(error));
}
self->channelz_listen_socket_.reset();
}
state->channelz_listen_socket.reset();
gpr_mu_unlock(&state->mu);
// Flush queued work before destroying handshaker factory, since that
// may do a synchronous unref.
grpc_core::ExecCtx::Get()->Flush();
ExecCtx::Get()->Flush();
if (destroy_done != nullptr) {
grpc_core::ExecCtx::Run(DEBUG_LOCATION, destroy_done,
GRPC_ERROR_REF(error));
grpc_core::ExecCtx::Get()->Flush();
ExecCtx::Run(DEBUG_LOCATION, destroy_done, GRPC_ERROR_REF(error));
ExecCtx::Get()->Flush();
}
grpc_channel_args_destroy(state->args);
gpr_mu_destroy(&state->mu);
gpr_free(state);
delete self;
}
/* Server callback: destroy the tcp listener (so we don't generate further
callbacks) */
static void server_destroy_listener(grpc_server* /*server*/, void* arg,
grpc_closure* destroy_done) {
server_state* state = static_cast<server_state*>(arg);
gpr_mu_lock(&state->mu);
state->shutdown = true;
state->server_destroy_listener_done = destroy_done;
grpc_tcp_server* tcp_server = state->tcp_server;
gpr_mu_unlock(&state->mu);
void Chttp2ServerListener::Orphan() {
grpc_tcp_server* tcp_server;
{
MutexLock lock(&mu_);
shutdown_ = true;
tcp_server = tcp_server_;
}
grpc_tcp_server_shutdown_listeners(tcp_server);
grpc_tcp_server_unref(tcp_server);
}
static grpc_error* chttp2_server_add_acceptor(grpc_server* server,
const char* name,
grpc_channel_args* args) {
grpc_tcp_server* tcp_server = nullptr;
grpc_error* err = GRPC_ERROR_NONE;
server_state* state = nullptr;
const grpc_arg* arg = nullptr;
grpc_core::TcpServerFdHandler** arg_val = nullptr;
state = static_cast<server_state*>(gpr_zalloc(sizeof(*state)));
GRPC_CLOSURE_INIT(&state->tcp_server_shutdown_complete,
tcp_server_shutdown_complete, state,
grpc_schedule_on_exec_ctx);
err = grpc_tcp_server_create(&state->tcp_server_shutdown_complete, args,
&tcp_server);
if (err != GRPC_ERROR_NONE) {
goto error;
}
state->server = server;
state->tcp_server = tcp_server;
state->args = args;
state->shutdown = true;
gpr_mu_init(&state->mu);
// TODO(yangg) channelz
arg = grpc_channel_args_find(args, name);
GPR_ASSERT(arg->type == GRPC_ARG_POINTER);
arg_val = static_cast<grpc_core::TcpServerFdHandler**>(arg->value.pointer.p);
*arg_val = grpc_tcp_server_create_fd_handler(tcp_server);
grpc_server_add_listener(server, state, server_start_listener,
server_destroy_listener, /* node */ nullptr);
return err;
/* Error path: cleanup and return */
error:
GPR_ASSERT(err != GRPC_ERROR_NONE);
if (tcp_server) {
grpc_tcp_server_unref(tcp_server);
} else {
grpc_channel_args_destroy(args);
gpr_free(state);
}
return err;
}
} // namespace
grpc_error* grpc_chttp2_server_add_port(grpc_server* server, const char* addr,
grpc_channel_args* args,
int* port_num) {
grpc_resolved_addresses* resolved = nullptr;
grpc_tcp_server* tcp_server = nullptr;
size_t i;
size_t count = 0;
int port_temp;
grpc_error* err = GRPC_ERROR_NONE;
server_state* state = nullptr;
grpc_error** errors = nullptr;
size_t naddrs = 0;
const grpc_arg* arg = nullptr;
*port_num = -1;
//
// Chttp2ServerAddPort()
//
grpc_error* Chttp2ServerAddPort(grpc_server* server, const char* addr,
grpc_channel_args* args, int* port_num) {
if (strncmp(addr, "external:", 9) == 0) {
return chttp2_server_add_acceptor(server, addr, args);
}
/* resolve address */
err = grpc_blocking_resolve_address(addr, "https", &resolved);
if (err != GRPC_ERROR_NONE) {
goto error;
}
state = static_cast<server_state*>(gpr_zalloc(sizeof(*state)));
GRPC_CLOSURE_INIT(&state->tcp_server_shutdown_complete,
tcp_server_shutdown_complete, state,
grpc_schedule_on_exec_ctx);
err = grpc_tcp_server_create(&state->tcp_server_shutdown_complete, args,
&tcp_server);
if (err != GRPC_ERROR_NONE) {
goto error;
}
state->server = server;
state->tcp_server = tcp_server;
state->args = args;
state->shutdown = true;
gpr_mu_init(&state->mu);
naddrs = resolved->naddrs;
errors = static_cast<grpc_error**>(gpr_malloc(sizeof(*errors) * naddrs));
for (i = 0; i < naddrs; i++) {
errors[i] =
grpc_tcp_server_add_port(tcp_server, &resolved->addrs[i], &port_temp);
if (errors[i] == GRPC_ERROR_NONE) {
if (*port_num == -1) {
*port_num = port_temp;
} else {
GPR_ASSERT(*port_num == port_temp);
}
count++;
}
return grpc_core::Chttp2ServerListener::CreateWithAcceptor(server, addr,
args);
}
if (count == 0) {
char* msg;
gpr_asprintf(&msg, "No address added out of total %" PRIuPTR " resolved",
naddrs);
err = GRPC_ERROR_CREATE_REFERENCING_FROM_COPIED_STRING(msg, errors, naddrs);
gpr_free(msg);
goto error;
} else if (count != naddrs) {
char* msg;
gpr_asprintf(&msg,
"Only %" PRIuPTR " addresses added out of total %" PRIuPTR
" resolved",
count, naddrs);
err = GRPC_ERROR_CREATE_REFERENCING_FROM_COPIED_STRING(msg, errors, naddrs);
gpr_free(msg);
const char* warning_message = grpc_error_string(err);
gpr_log(GPR_INFO, "WARNING: %s", warning_message);
/* we managed to bind some addresses: continue */
}
grpc_resolved_addresses_destroy(resolved);
arg = grpc_channel_args_find(args, GRPC_ARG_ENABLE_CHANNELZ);
if (grpc_channel_arg_get_bool(arg, GRPC_ENABLE_CHANNELZ_DEFAULT)) {
state->channelz_listen_socket =
grpc_core::MakeRefCounted<grpc_core::channelz::ListenSocketNode>(
addr, absl::StrFormat("chttp2 listener %s", addr));
}
/* Register with the server only upon success */
grpc_server_add_listener(server, state, server_start_listener,
server_destroy_listener,
state->channelz_listen_socket);
goto done;
/* Error path: cleanup and return */
error:
GPR_ASSERT(err != GRPC_ERROR_NONE);
if (resolved) {
grpc_resolved_addresses_destroy(resolved);
}
if (tcp_server) {
grpc_tcp_server_unref(tcp_server);
} else {
grpc_channel_args_destroy(args);
gpr_free(state);
}
*port_num = 0;
done:
if (errors != nullptr) {
for (i = 0; i < naddrs; i++) {
GRPC_ERROR_UNREF(errors[i]);
}
gpr_free(errors);
}
return err;
return grpc_core::Chttp2ServerListener::Create(server, addr, args, port_num);
}
} // namespace grpc_core

@ -25,9 +25,13 @@
#include "src/core/lib/iomgr/error.h"
namespace grpc_core {
/// Adds a port to \a server. Sets \a port_num to the port number.
/// Takes ownership of \a args.
grpc_error* grpc_chttp2_server_add_port(grpc_server* server, const char* addr,
grpc_channel_args* args, int* port_num);
grpc_error* Chttp2ServerAddPort(grpc_server* server, const char* addr,
grpc_channel_args* args, int* port_num);
} // namespace grpc_core
#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_SERVER_CHTTP2_SERVER_H */

@ -32,7 +32,7 @@ int grpc_server_add_insecure_http2_port(grpc_server* server, const char* addr) {
int port_num = 0;
GRPC_API_TRACE("grpc_server_add_insecure_http2_port(server=%p, addr=%s)", 2,
(server, addr));
grpc_error* err = grpc_chttp2_server_add_port(
grpc_error* err = grpc_core::Chttp2ServerAddPort(
server, addr,
grpc_channel_args_copy(grpc_server_get_channel_args(server)), &port_num);
if (err != GRPC_ERROR_NONE) {

@ -72,7 +72,7 @@ int grpc_server_add_secure_http2_port(grpc_server* server, const char* addr,
grpc_channel_args_copy_and_add(grpc_server_get_channel_args(server),
args_to_add, GPR_ARRAY_SIZE(args_to_add));
// Add server port.
err = grpc_chttp2_server_add_port(server, addr, args, &port_num);
err = grpc_core::Chttp2ServerAddPort(server, addr, args, &port_num);
done:
sc.reset(DEBUG_LOCATION, "server");

@ -1525,6 +1525,7 @@ static void perform_stream_op_locked(void* stream_op,
s->send_trailing_metadata_finished = add_closure_barrier(on_complete);
s->send_trailing_metadata =
op_payload->send_trailing_metadata.send_trailing_metadata;
s->sent_trailing_metadata_op = op_payload->send_trailing_metadata.sent;
s->write_buffering = false;
const size_t metadata_size =
grpc_metadata_batch_size(s->send_trailing_metadata);
@ -1550,6 +1551,7 @@ static void perform_stream_op_locked(void* stream_op,
}
if (s->write_closed) {
s->send_trailing_metadata = nullptr;
s->sent_trailing_metadata_op = nullptr;
grpc_chttp2_complete_closure_step(
t, s, &s->send_trailing_metadata_finished,
grpc_metadata_batch_is_empty(
@ -2185,6 +2187,7 @@ void grpc_chttp2_fail_pending_writes(grpc_chttp2_transport* t,
"send_initial_metadata_finished");
s->send_trailing_metadata = nullptr;
s->sent_trailing_metadata_op = nullptr;
grpc_chttp2_complete_closure_step(t, s, &s->send_trailing_metadata_finished,
GRPC_ERROR_REF(error),
"send_trailing_metadata_finished");

@ -527,6 +527,13 @@ struct grpc_chttp2_stream {
grpc_metadata_batch* send_initial_metadata = nullptr;
grpc_closure* send_initial_metadata_finished = nullptr;
grpc_metadata_batch* send_trailing_metadata = nullptr;
// TODO(yashykt): Find a better name for the below field and others in this
// struct to betteer distinguish inputs, return values, and
// internal state.
// sent_trailing_metadata_op allows the transport to fill in to the upper
// layer whether this stream was able to send its trailing metadata (used for
// detecting cancellation on the server-side)..
bool* sent_trailing_metadata_op = nullptr;
grpc_closure* send_trailing_metadata_finished = nullptr;
grpc_core::OrphanablePtr<grpc_core::ByteStream> fetching_send_message;

@ -606,6 +606,10 @@ class StreamWriteContext {
void SentLastFrame() {
s_->send_trailing_metadata = nullptr;
if (s_->sent_trailing_metadata_op) {
*s_->sent_trailing_metadata_op = true;
s_->sent_trailing_metadata_op = nullptr;
}
s_->sent_trailing_metadata = true;
s_->eos_sent = true;

@ -317,6 +317,17 @@ static void maybe_flush_read(stream_obj* s) {
}
}
static void read_grpc_header(stream_obj* s) {
s->state.rs.read_buffer = s->state.rs.grpc_header_bytes;
s->state.rs.remaining_bytes = GRPC_HEADER_SIZE_IN_BYTES;
s->state.rs.received_bytes = 0;
s->state.rs.compressed = false;
CRONET_LOG(GPR_DEBUG, "bidirectional_stream_read(%p)", s->cbs);
bidirectional_stream_read(s->cbs, s->state.rs.read_buffer,
s->state.rs.remaining_bytes);
s->state.pending_read_from_cronet = true;
}
static grpc_error* make_error_with_desc(int error_code, const char* desc) {
grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(desc);
error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS, error_code);
@ -555,6 +566,11 @@ static void on_response_headers_received(
for (size_t i = 0; i < headers->count; i++) {
if (0 == strcmp("grpc-status", headers->headers[i].key)) {
on_response_trailers_received(stream, headers);
/* Do an extra read for a trailer-only stream with grpc_status = 0
to trigger on_succeeded() callback */
if (0 == strcmp(headers->headers[i].value, "0")) {
read_grpc_header(s);
}
return;
}
}
@ -567,14 +583,7 @@ static void on_response_headers_received(
/* Do an extra read to trigger on_succeeded() callback in case connection
is closed */
GPR_ASSERT(s->state.rs.length_field_received == false);
s->state.rs.read_buffer = s->state.rs.grpc_header_bytes;
s->state.rs.compressed = false;
s->state.rs.received_bytes = 0;
s->state.rs.remaining_bytes = GRPC_HEADER_SIZE_IN_BYTES;
CRONET_LOG(GPR_DEBUG, "bidirectional_stream_read(%p)", s->cbs);
bidirectional_stream_read(s->cbs, s->state.rs.read_buffer,
s->state.rs.remaining_bytes);
s->state.pending_read_from_cronet = true;
read_grpc_header(s);
}
gpr_mu_unlock(&s->mu);
execute_from_storage(s);
@ -1260,17 +1269,10 @@ static enum e_op_result execute_stream_op(struct op_and_state* oas) {
oas->state.state_op_done[OP_RECV_MESSAGE] = true;
/* Extra read to trigger on_succeed */
stream_state->rs.read_buffer = stream_state->rs.grpc_header_bytes;
stream_state->rs.remaining_bytes = GRPC_HEADER_SIZE_IN_BYTES;
stream_state->rs.received_bytes = 0;
stream_state->rs.compressed = false;
stream_state->rs.length_field_received = false;
CRONET_LOG(GPR_DEBUG, "bidirectional_stream_read(%p)", s->cbs);
stream_state->state_op_done[OP_READ_REQ_MADE] =
true; /* Indicates that at least one read request has been made */
bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer,
stream_state->rs.remaining_bytes);
stream_state->pending_read_from_cronet = true;
read_grpc_header(s);
result = ACTION_TAKEN_NO_CALLBACK;
}
} else if (stream_state->rs.remaining_bytes == 0) {
@ -1316,15 +1318,8 @@ static enum e_op_result execute_stream_op(struct op_and_state* oas) {
oas->state.state_op_done[OP_RECV_MESSAGE] = true;
/* Do an extra read to trigger on_succeeded() callback in case connection
is closed */
stream_state->rs.read_buffer = stream_state->rs.grpc_header_bytes;
stream_state->rs.compressed = false;
stream_state->rs.received_bytes = 0;
stream_state->rs.remaining_bytes = GRPC_HEADER_SIZE_IN_BYTES;
stream_state->rs.length_field_received = false;
CRONET_LOG(GPR_DEBUG, "bidirectional_stream_read(%p)", s->cbs);
bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer,
stream_state->rs.remaining_bytes);
stream_state->pending_read_from_cronet = true;
read_grpc_header(s);
result = ACTION_TAKEN_NO_CALLBACK;
}
} else if (stream_op->recv_trailing_metadata &&

@ -652,6 +652,9 @@ void op_state_machine_locked(inproc_stream* s, grpc_error* error) {
0, dest, nullptr, destfilled);
}
s->trailing_md_sent = true;
if (s->send_trailing_md_op->payload->send_trailing_metadata.sent) {
*s->send_trailing_md_op->payload->send_trailing_metadata.sent = true;
}
if (!s->t->is_client && s->trailing_md_recvd && s->recv_trailing_md_op) {
INPROC_LOG(GPR_INFO,
"op_state_machine %p scheduling trailing-metadata-ready", s);

@ -0,0 +1,173 @@
/* This file was generated by upbc (the upb compiler) from the input
* file:
*
* envoy/config/rbac/v2/rbac.proto
*
* Do not edit -- your changes will be discarded when the file is
* regenerated. */
#include <stddef.h>
#include "upb/msg.h"
#include "envoy/config/rbac/v2/rbac.upb.h"
#include "envoy/api/v2/core/address.upb.h"
#include "envoy/api/v2/route/route_components.upb.h"
#include "envoy/type/matcher/metadata.upb.h"
#include "envoy/type/matcher/path.upb.h"
#include "envoy/type/matcher/string.upb.h"
#include "google/api/expr/v1alpha1/syntax.upb.h"
#include "udpa/annotations/status.upb.h"
#include "validate/validate.upb.h"
#include "upb/port_def.inc"
static const upb_msglayout *const envoy_config_rbac_v2_RBAC_submsgs[1] = {
&envoy_config_rbac_v2_RBAC_PoliciesEntry_msginit,
};
static const upb_msglayout_field envoy_config_rbac_v2_RBAC__fields[2] = {
{1, UPB_SIZE(0, 0), 0, 0, 14, 1},
{2, UPB_SIZE(8, 8), 0, 0, 11, 3},
};
const upb_msglayout envoy_config_rbac_v2_RBAC_msginit = {
&envoy_config_rbac_v2_RBAC_submsgs[0],
&envoy_config_rbac_v2_RBAC__fields[0],
UPB_SIZE(16, 16), 2, false,
};
static const upb_msglayout *const envoy_config_rbac_v2_RBAC_PoliciesEntry_submsgs[1] = {
&envoy_config_rbac_v2_Policy_msginit,
};
static const upb_msglayout_field envoy_config_rbac_v2_RBAC_PoliciesEntry__fields[2] = {
{1, UPB_SIZE(0, 0), 0, 0, 9, 1},
{2, UPB_SIZE(8, 16), 0, 0, 11, 1},
};
const upb_msglayout envoy_config_rbac_v2_RBAC_PoliciesEntry_msginit = {
&envoy_config_rbac_v2_RBAC_PoliciesEntry_submsgs[0],
&envoy_config_rbac_v2_RBAC_PoliciesEntry__fields[0],
UPB_SIZE(16, 32), 2, false,
};
static const upb_msglayout *const envoy_config_rbac_v2_Policy_submsgs[3] = {
&envoy_config_rbac_v2_Permission_msginit,
&envoy_config_rbac_v2_Principal_msginit,
&google_api_expr_v1alpha1_Expr_msginit,
};
static const upb_msglayout_field envoy_config_rbac_v2_Policy__fields[3] = {
{1, UPB_SIZE(4, 8), 0, 0, 11, 3},
{2, UPB_SIZE(8, 16), 0, 1, 11, 3},
{3, UPB_SIZE(0, 0), 0, 2, 11, 1},
};
const upb_msglayout envoy_config_rbac_v2_Policy_msginit = {
&envoy_config_rbac_v2_Policy_submsgs[0],
&envoy_config_rbac_v2_Policy__fields[0],
UPB_SIZE(12, 24), 3, false,
};
static const upb_msglayout *const envoy_config_rbac_v2_Permission_submsgs[8] = {
&envoy_api_v2_core_CidrRange_msginit,
&envoy_api_v2_route_HeaderMatcher_msginit,
&envoy_config_rbac_v2_Permission_msginit,
&envoy_config_rbac_v2_Permission_Set_msginit,
&envoy_type_matcher_MetadataMatcher_msginit,
&envoy_type_matcher_PathMatcher_msginit,
&envoy_type_matcher_StringMatcher_msginit,
};
static const upb_msglayout_field envoy_config_rbac_v2_Permission__fields[10] = {
{1, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 3, 11, 1},
{2, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 3, 11, 1},
{3, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 0, 8, 1},
{4, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 1, 11, 1},
{5, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 0, 11, 1},
{6, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 0, 13, 1},
{7, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 4, 11, 1},
{8, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 2, 11, 1},
{9, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 6, 11, 1},
{10, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 5, 11, 1},
};
const upb_msglayout envoy_config_rbac_v2_Permission_msginit = {
&envoy_config_rbac_v2_Permission_submsgs[0],
&envoy_config_rbac_v2_Permission__fields[0],
UPB_SIZE(8, 16), 10, false,
};
static const upb_msglayout *const envoy_config_rbac_v2_Permission_Set_submsgs[1] = {
&envoy_config_rbac_v2_Permission_msginit,
};
static const upb_msglayout_field envoy_config_rbac_v2_Permission_Set__fields[1] = {
{1, UPB_SIZE(0, 0), 0, 0, 11, 3},
};
const upb_msglayout envoy_config_rbac_v2_Permission_Set_msginit = {
&envoy_config_rbac_v2_Permission_Set_submsgs[0],
&envoy_config_rbac_v2_Permission_Set__fields[0],
UPB_SIZE(4, 8), 1, false,
};
static const upb_msglayout *const envoy_config_rbac_v2_Principal_submsgs[10] = {
&envoy_api_v2_core_CidrRange_msginit,
&envoy_api_v2_route_HeaderMatcher_msginit,
&envoy_config_rbac_v2_Principal_msginit,
&envoy_config_rbac_v2_Principal_Authenticated_msginit,
&envoy_config_rbac_v2_Principal_Set_msginit,
&envoy_type_matcher_MetadataMatcher_msginit,
&envoy_type_matcher_PathMatcher_msginit,
};
static const upb_msglayout_field envoy_config_rbac_v2_Principal__fields[11] = {
{1, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 4, 11, 1},
{2, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 4, 11, 1},
{3, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 0, 8, 1},
{4, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 3, 11, 1},
{5, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 0, 11, 1},
{6, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 1, 11, 1},
{7, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 5, 11, 1},
{8, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 2, 11, 1},
{9, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 6, 11, 1},
{10, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 0, 11, 1},
{11, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 0, 11, 1},
};
const upb_msglayout envoy_config_rbac_v2_Principal_msginit = {
&envoy_config_rbac_v2_Principal_submsgs[0],
&envoy_config_rbac_v2_Principal__fields[0],
UPB_SIZE(8, 16), 11, false,
};
static const upb_msglayout *const envoy_config_rbac_v2_Principal_Set_submsgs[1] = {
&envoy_config_rbac_v2_Principal_msginit,
};
static const upb_msglayout_field envoy_config_rbac_v2_Principal_Set__fields[1] = {
{1, UPB_SIZE(0, 0), 0, 0, 11, 3},
};
const upb_msglayout envoy_config_rbac_v2_Principal_Set_msginit = {
&envoy_config_rbac_v2_Principal_Set_submsgs[0],
&envoy_config_rbac_v2_Principal_Set__fields[0],
UPB_SIZE(4, 8), 1, false,
};
static const upb_msglayout *const envoy_config_rbac_v2_Principal_Authenticated_submsgs[1] = {
&envoy_type_matcher_StringMatcher_msginit,
};
static const upb_msglayout_field envoy_config_rbac_v2_Principal_Authenticated__fields[1] = {
{2, UPB_SIZE(0, 0), 0, 0, 11, 1},
};
const upb_msglayout envoy_config_rbac_v2_Principal_Authenticated_msginit = {
&envoy_config_rbac_v2_Principal_Authenticated_submsgs[0],
&envoy_config_rbac_v2_Principal_Authenticated__fields[0],
UPB_SIZE(4, 8), 1, false,
};
#include "upb/port_undef.inc"

@ -0,0 +1,615 @@
/* This file was generated by upbc (the upb compiler) from the input
* file:
*
* envoy/config/rbac/v2/rbac.proto
*
* Do not edit -- your changes will be discarded when the file is
* regenerated. */
#ifndef ENVOY_CONFIG_RBAC_V2_RBAC_PROTO_UPB_H_
#define ENVOY_CONFIG_RBAC_V2_RBAC_PROTO_UPB_H_
#include "upb/generated_util.h"
#include "upb/msg.h"
#include "upb/decode.h"
#include "upb/encode.h"
#include "upb/port_def.inc"
#ifdef __cplusplus
extern "C" {
#endif
struct envoy_config_rbac_v2_RBAC;
struct envoy_config_rbac_v2_RBAC_PoliciesEntry;
struct envoy_config_rbac_v2_Policy;
struct envoy_config_rbac_v2_Permission;
struct envoy_config_rbac_v2_Permission_Set;
struct envoy_config_rbac_v2_Principal;
struct envoy_config_rbac_v2_Principal_Set;
struct envoy_config_rbac_v2_Principal_Authenticated;
typedef struct envoy_config_rbac_v2_RBAC envoy_config_rbac_v2_RBAC;
typedef struct envoy_config_rbac_v2_RBAC_PoliciesEntry envoy_config_rbac_v2_RBAC_PoliciesEntry;
typedef struct envoy_config_rbac_v2_Policy envoy_config_rbac_v2_Policy;
typedef struct envoy_config_rbac_v2_Permission envoy_config_rbac_v2_Permission;
typedef struct envoy_config_rbac_v2_Permission_Set envoy_config_rbac_v2_Permission_Set;
typedef struct envoy_config_rbac_v2_Principal envoy_config_rbac_v2_Principal;
typedef struct envoy_config_rbac_v2_Principal_Set envoy_config_rbac_v2_Principal_Set;
typedef struct envoy_config_rbac_v2_Principal_Authenticated envoy_config_rbac_v2_Principal_Authenticated;
extern const upb_msglayout envoy_config_rbac_v2_RBAC_msginit;
extern const upb_msglayout envoy_config_rbac_v2_RBAC_PoliciesEntry_msginit;
extern const upb_msglayout envoy_config_rbac_v2_Policy_msginit;
extern const upb_msglayout envoy_config_rbac_v2_Permission_msginit;
extern const upb_msglayout envoy_config_rbac_v2_Permission_Set_msginit;
extern const upb_msglayout envoy_config_rbac_v2_Principal_msginit;
extern const upb_msglayout envoy_config_rbac_v2_Principal_Set_msginit;
extern const upb_msglayout envoy_config_rbac_v2_Principal_Authenticated_msginit;
struct envoy_api_v2_core_CidrRange;
struct envoy_api_v2_route_HeaderMatcher;
struct envoy_type_matcher_MetadataMatcher;
struct envoy_type_matcher_PathMatcher;
struct envoy_type_matcher_StringMatcher;
struct google_api_expr_v1alpha1_Expr;
extern const upb_msglayout envoy_api_v2_core_CidrRange_msginit;
extern const upb_msglayout envoy_api_v2_route_HeaderMatcher_msginit;
extern const upb_msglayout envoy_type_matcher_MetadataMatcher_msginit;
extern const upb_msglayout envoy_type_matcher_PathMatcher_msginit;
extern const upb_msglayout envoy_type_matcher_StringMatcher_msginit;
extern const upb_msglayout google_api_expr_v1alpha1_Expr_msginit;
typedef enum {
envoy_config_rbac_v2_RBAC_ALLOW = 0,
envoy_config_rbac_v2_RBAC_DENY = 1
} envoy_config_rbac_v2_RBAC_Action;
/* envoy.config.rbac.v2.RBAC */
UPB_INLINE envoy_config_rbac_v2_RBAC *envoy_config_rbac_v2_RBAC_new(upb_arena *arena) {
return (envoy_config_rbac_v2_RBAC *)upb_msg_new(&envoy_config_rbac_v2_RBAC_msginit, arena);
}
UPB_INLINE envoy_config_rbac_v2_RBAC *envoy_config_rbac_v2_RBAC_parse(const char *buf, size_t size,
upb_arena *arena) {
envoy_config_rbac_v2_RBAC *ret = envoy_config_rbac_v2_RBAC_new(arena);
return (ret && upb_decode(buf, size, ret, &envoy_config_rbac_v2_RBAC_msginit, arena)) ? ret : NULL;
}
UPB_INLINE char *envoy_config_rbac_v2_RBAC_serialize(const envoy_config_rbac_v2_RBAC *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &envoy_config_rbac_v2_RBAC_msginit, arena, len);
}
UPB_INLINE int32_t envoy_config_rbac_v2_RBAC_action(const envoy_config_rbac_v2_RBAC *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)); }
UPB_INLINE const envoy_config_rbac_v2_RBAC_PoliciesEntry* const* envoy_config_rbac_v2_RBAC_policies(const envoy_config_rbac_v2_RBAC *msg, size_t *len) { return (const envoy_config_rbac_v2_RBAC_PoliciesEntry* const*)_upb_array_accessor(msg, UPB_SIZE(8, 8), len); }
UPB_INLINE void envoy_config_rbac_v2_RBAC_set_action(envoy_config_rbac_v2_RBAC *msg, int32_t value) {
UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)) = value;
}
UPB_INLINE envoy_config_rbac_v2_RBAC_PoliciesEntry** envoy_config_rbac_v2_RBAC_mutable_policies(envoy_config_rbac_v2_RBAC *msg, size_t *len) {
return (envoy_config_rbac_v2_RBAC_PoliciesEntry**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 8), len);
}
UPB_INLINE envoy_config_rbac_v2_RBAC_PoliciesEntry** envoy_config_rbac_v2_RBAC_resize_policies(envoy_config_rbac_v2_RBAC *msg, size_t len, upb_arena *arena) {
return (envoy_config_rbac_v2_RBAC_PoliciesEntry**)_upb_array_resize_accessor(msg, UPB_SIZE(8, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct envoy_config_rbac_v2_RBAC_PoliciesEntry* envoy_config_rbac_v2_RBAC_add_policies(envoy_config_rbac_v2_RBAC *msg, upb_arena *arena) {
struct envoy_config_rbac_v2_RBAC_PoliciesEntry* sub = (struct envoy_config_rbac_v2_RBAC_PoliciesEntry*)upb_msg_new(&envoy_config_rbac_v2_RBAC_PoliciesEntry_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(8, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
return sub;
}
/* envoy.config.rbac.v2.RBAC.PoliciesEntry */
UPB_INLINE envoy_config_rbac_v2_RBAC_PoliciesEntry *envoy_config_rbac_v2_RBAC_PoliciesEntry_new(upb_arena *arena) {
return (envoy_config_rbac_v2_RBAC_PoliciesEntry *)upb_msg_new(&envoy_config_rbac_v2_RBAC_PoliciesEntry_msginit, arena);
}
UPB_INLINE envoy_config_rbac_v2_RBAC_PoliciesEntry *envoy_config_rbac_v2_RBAC_PoliciesEntry_parse(const char *buf, size_t size,
upb_arena *arena) {
envoy_config_rbac_v2_RBAC_PoliciesEntry *ret = envoy_config_rbac_v2_RBAC_PoliciesEntry_new(arena);
return (ret && upb_decode(buf, size, ret, &envoy_config_rbac_v2_RBAC_PoliciesEntry_msginit, arena)) ? ret : NULL;
}
UPB_INLINE char *envoy_config_rbac_v2_RBAC_PoliciesEntry_serialize(const envoy_config_rbac_v2_RBAC_PoliciesEntry *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &envoy_config_rbac_v2_RBAC_PoliciesEntry_msginit, arena, len);
}
UPB_INLINE upb_strview envoy_config_rbac_v2_RBAC_PoliciesEntry_key(const envoy_config_rbac_v2_RBAC_PoliciesEntry *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); }
UPB_INLINE const envoy_config_rbac_v2_Policy* envoy_config_rbac_v2_RBAC_PoliciesEntry_value(const envoy_config_rbac_v2_RBAC_PoliciesEntry *msg) { return UPB_FIELD_AT(msg, const envoy_config_rbac_v2_Policy*, UPB_SIZE(8, 16)); }
UPB_INLINE void envoy_config_rbac_v2_RBAC_PoliciesEntry_set_key(envoy_config_rbac_v2_RBAC_PoliciesEntry *msg, upb_strview value) {
UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value;
}
UPB_INLINE void envoy_config_rbac_v2_RBAC_PoliciesEntry_set_value(envoy_config_rbac_v2_RBAC_PoliciesEntry *msg, envoy_config_rbac_v2_Policy* value) {
UPB_FIELD_AT(msg, envoy_config_rbac_v2_Policy*, UPB_SIZE(8, 16)) = value;
}
UPB_INLINE struct envoy_config_rbac_v2_Policy* envoy_config_rbac_v2_RBAC_PoliciesEntry_mutable_value(envoy_config_rbac_v2_RBAC_PoliciesEntry *msg, upb_arena *arena) {
struct envoy_config_rbac_v2_Policy* sub = (struct envoy_config_rbac_v2_Policy*)envoy_config_rbac_v2_RBAC_PoliciesEntry_value(msg);
if (sub == NULL) {
sub = (struct envoy_config_rbac_v2_Policy*)upb_msg_new(&envoy_config_rbac_v2_Policy_msginit, arena);
if (!sub) return NULL;
envoy_config_rbac_v2_RBAC_PoliciesEntry_set_value(msg, sub);
}
return sub;
}
/* envoy.config.rbac.v2.Policy */
UPB_INLINE envoy_config_rbac_v2_Policy *envoy_config_rbac_v2_Policy_new(upb_arena *arena) {
return (envoy_config_rbac_v2_Policy *)upb_msg_new(&envoy_config_rbac_v2_Policy_msginit, arena);
}
UPB_INLINE envoy_config_rbac_v2_Policy *envoy_config_rbac_v2_Policy_parse(const char *buf, size_t size,
upb_arena *arena) {
envoy_config_rbac_v2_Policy *ret = envoy_config_rbac_v2_Policy_new(arena);
return (ret && upb_decode(buf, size, ret, &envoy_config_rbac_v2_Policy_msginit, arena)) ? ret : NULL;
}
UPB_INLINE char *envoy_config_rbac_v2_Policy_serialize(const envoy_config_rbac_v2_Policy *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &envoy_config_rbac_v2_Policy_msginit, arena, len);
}
UPB_INLINE const envoy_config_rbac_v2_Permission* const* envoy_config_rbac_v2_Policy_permissions(const envoy_config_rbac_v2_Policy *msg, size_t *len) { return (const envoy_config_rbac_v2_Permission* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); }
UPB_INLINE const envoy_config_rbac_v2_Principal* const* envoy_config_rbac_v2_Policy_principals(const envoy_config_rbac_v2_Policy *msg, size_t *len) { return (const envoy_config_rbac_v2_Principal* const*)_upb_array_accessor(msg, UPB_SIZE(8, 16), len); }
UPB_INLINE const struct google_api_expr_v1alpha1_Expr* envoy_config_rbac_v2_Policy_condition(const envoy_config_rbac_v2_Policy *msg) { return UPB_FIELD_AT(msg, const struct google_api_expr_v1alpha1_Expr*, UPB_SIZE(0, 0)); }
UPB_INLINE envoy_config_rbac_v2_Permission** envoy_config_rbac_v2_Policy_mutable_permissions(envoy_config_rbac_v2_Policy *msg, size_t *len) {
return (envoy_config_rbac_v2_Permission**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len);
}
UPB_INLINE envoy_config_rbac_v2_Permission** envoy_config_rbac_v2_Policy_resize_permissions(envoy_config_rbac_v2_Policy *msg, size_t len, upb_arena *arena) {
return (envoy_config_rbac_v2_Permission**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct envoy_config_rbac_v2_Permission* envoy_config_rbac_v2_Policy_add_permissions(envoy_config_rbac_v2_Policy *msg, upb_arena *arena) {
struct envoy_config_rbac_v2_Permission* sub = (struct envoy_config_rbac_v2_Permission*)upb_msg_new(&envoy_config_rbac_v2_Permission_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
return sub;
}
UPB_INLINE envoy_config_rbac_v2_Principal** envoy_config_rbac_v2_Policy_mutable_principals(envoy_config_rbac_v2_Policy *msg, size_t *len) {
return (envoy_config_rbac_v2_Principal**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len);
}
UPB_INLINE envoy_config_rbac_v2_Principal** envoy_config_rbac_v2_Policy_resize_principals(envoy_config_rbac_v2_Policy *msg, size_t len, upb_arena *arena) {
return (envoy_config_rbac_v2_Principal**)_upb_array_resize_accessor(msg, UPB_SIZE(8, 16), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct envoy_config_rbac_v2_Principal* envoy_config_rbac_v2_Policy_add_principals(envoy_config_rbac_v2_Policy *msg, upb_arena *arena) {
struct envoy_config_rbac_v2_Principal* sub = (struct envoy_config_rbac_v2_Principal*)upb_msg_new(&envoy_config_rbac_v2_Principal_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(8, 16), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
return sub;
}
UPB_INLINE void envoy_config_rbac_v2_Policy_set_condition(envoy_config_rbac_v2_Policy *msg, struct google_api_expr_v1alpha1_Expr* value) {
UPB_FIELD_AT(msg, struct google_api_expr_v1alpha1_Expr*, UPB_SIZE(0, 0)) = value;
}
UPB_INLINE struct google_api_expr_v1alpha1_Expr* envoy_config_rbac_v2_Policy_mutable_condition(envoy_config_rbac_v2_Policy *msg, upb_arena *arena) {
struct google_api_expr_v1alpha1_Expr* sub = (struct google_api_expr_v1alpha1_Expr*)envoy_config_rbac_v2_Policy_condition(msg);
if (sub == NULL) {
sub = (struct google_api_expr_v1alpha1_Expr*)upb_msg_new(&google_api_expr_v1alpha1_Expr_msginit, arena);
if (!sub) return NULL;
envoy_config_rbac_v2_Policy_set_condition(msg, sub);
}
return sub;
}
/* envoy.config.rbac.v2.Permission */
UPB_INLINE envoy_config_rbac_v2_Permission *envoy_config_rbac_v2_Permission_new(upb_arena *arena) {
return (envoy_config_rbac_v2_Permission *)upb_msg_new(&envoy_config_rbac_v2_Permission_msginit, arena);
}
UPB_INLINE envoy_config_rbac_v2_Permission *envoy_config_rbac_v2_Permission_parse(const char *buf, size_t size,
upb_arena *arena) {
envoy_config_rbac_v2_Permission *ret = envoy_config_rbac_v2_Permission_new(arena);
return (ret && upb_decode(buf, size, ret, &envoy_config_rbac_v2_Permission_msginit, arena)) ? ret : NULL;
}
UPB_INLINE char *envoy_config_rbac_v2_Permission_serialize(const envoy_config_rbac_v2_Permission *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &envoy_config_rbac_v2_Permission_msginit, arena, len);
}
typedef enum {
envoy_config_rbac_v2_Permission_rule_and_rules = 1,
envoy_config_rbac_v2_Permission_rule_or_rules = 2,
envoy_config_rbac_v2_Permission_rule_any = 3,
envoy_config_rbac_v2_Permission_rule_header = 4,
envoy_config_rbac_v2_Permission_rule_url_path = 10,
envoy_config_rbac_v2_Permission_rule_destination_ip = 5,
envoy_config_rbac_v2_Permission_rule_destination_port = 6,
envoy_config_rbac_v2_Permission_rule_metadata = 7,
envoy_config_rbac_v2_Permission_rule_not_rule = 8,
envoy_config_rbac_v2_Permission_rule_requested_server_name = 9,
envoy_config_rbac_v2_Permission_rule_NOT_SET = 0
} envoy_config_rbac_v2_Permission_rule_oneofcases;
UPB_INLINE envoy_config_rbac_v2_Permission_rule_oneofcases envoy_config_rbac_v2_Permission_rule_case(const envoy_config_rbac_v2_Permission* msg) { return (envoy_config_rbac_v2_Permission_rule_oneofcases)UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 8)); }
UPB_INLINE bool envoy_config_rbac_v2_Permission_has_and_rules(const envoy_config_rbac_v2_Permission *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 1); }
UPB_INLINE const envoy_config_rbac_v2_Permission_Set* envoy_config_rbac_v2_Permission_and_rules(const envoy_config_rbac_v2_Permission *msg) { return UPB_READ_ONEOF(msg, const envoy_config_rbac_v2_Permission_Set*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 1, NULL); }
UPB_INLINE bool envoy_config_rbac_v2_Permission_has_or_rules(const envoy_config_rbac_v2_Permission *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 2); }
UPB_INLINE const envoy_config_rbac_v2_Permission_Set* envoy_config_rbac_v2_Permission_or_rules(const envoy_config_rbac_v2_Permission *msg) { return UPB_READ_ONEOF(msg, const envoy_config_rbac_v2_Permission_Set*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 2, NULL); }
UPB_INLINE bool envoy_config_rbac_v2_Permission_has_any(const envoy_config_rbac_v2_Permission *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 3); }
UPB_INLINE bool envoy_config_rbac_v2_Permission_any(const envoy_config_rbac_v2_Permission *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 3, false); }
UPB_INLINE bool envoy_config_rbac_v2_Permission_has_header(const envoy_config_rbac_v2_Permission *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 4); }
UPB_INLINE const struct envoy_api_v2_route_HeaderMatcher* envoy_config_rbac_v2_Permission_header(const envoy_config_rbac_v2_Permission *msg) { return UPB_READ_ONEOF(msg, const struct envoy_api_v2_route_HeaderMatcher*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 4, NULL); }
UPB_INLINE bool envoy_config_rbac_v2_Permission_has_destination_ip(const envoy_config_rbac_v2_Permission *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 5); }
UPB_INLINE const struct envoy_api_v2_core_CidrRange* envoy_config_rbac_v2_Permission_destination_ip(const envoy_config_rbac_v2_Permission *msg) { return UPB_READ_ONEOF(msg, const struct envoy_api_v2_core_CidrRange*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 5, NULL); }
UPB_INLINE bool envoy_config_rbac_v2_Permission_has_destination_port(const envoy_config_rbac_v2_Permission *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 6); }
UPB_INLINE uint32_t envoy_config_rbac_v2_Permission_destination_port(const envoy_config_rbac_v2_Permission *msg) { return UPB_READ_ONEOF(msg, uint32_t, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 6, 0); }
UPB_INLINE bool envoy_config_rbac_v2_Permission_has_metadata(const envoy_config_rbac_v2_Permission *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 7); }
UPB_INLINE const struct envoy_type_matcher_MetadataMatcher* envoy_config_rbac_v2_Permission_metadata(const envoy_config_rbac_v2_Permission *msg) { return UPB_READ_ONEOF(msg, const struct envoy_type_matcher_MetadataMatcher*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 7, NULL); }
UPB_INLINE bool envoy_config_rbac_v2_Permission_has_not_rule(const envoy_config_rbac_v2_Permission *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 8); }
UPB_INLINE const envoy_config_rbac_v2_Permission* envoy_config_rbac_v2_Permission_not_rule(const envoy_config_rbac_v2_Permission *msg) { return UPB_READ_ONEOF(msg, const envoy_config_rbac_v2_Permission*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 8, NULL); }
UPB_INLINE bool envoy_config_rbac_v2_Permission_has_requested_server_name(const envoy_config_rbac_v2_Permission *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 9); }
UPB_INLINE const struct envoy_type_matcher_StringMatcher* envoy_config_rbac_v2_Permission_requested_server_name(const envoy_config_rbac_v2_Permission *msg) { return UPB_READ_ONEOF(msg, const struct envoy_type_matcher_StringMatcher*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 9, NULL); }
UPB_INLINE bool envoy_config_rbac_v2_Permission_has_url_path(const envoy_config_rbac_v2_Permission *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 10); }
UPB_INLINE const struct envoy_type_matcher_PathMatcher* envoy_config_rbac_v2_Permission_url_path(const envoy_config_rbac_v2_Permission *msg) { return UPB_READ_ONEOF(msg, const struct envoy_type_matcher_PathMatcher*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 10, NULL); }
UPB_INLINE void envoy_config_rbac_v2_Permission_set_and_rules(envoy_config_rbac_v2_Permission *msg, envoy_config_rbac_v2_Permission_Set* value) {
UPB_WRITE_ONEOF(msg, envoy_config_rbac_v2_Permission_Set*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 1);
}
UPB_INLINE struct envoy_config_rbac_v2_Permission_Set* envoy_config_rbac_v2_Permission_mutable_and_rules(envoy_config_rbac_v2_Permission *msg, upb_arena *arena) {
struct envoy_config_rbac_v2_Permission_Set* sub = (struct envoy_config_rbac_v2_Permission_Set*)envoy_config_rbac_v2_Permission_and_rules(msg);
if (sub == NULL) {
sub = (struct envoy_config_rbac_v2_Permission_Set*)upb_msg_new(&envoy_config_rbac_v2_Permission_Set_msginit, arena);
if (!sub) return NULL;
envoy_config_rbac_v2_Permission_set_and_rules(msg, sub);
}
return sub;
}
UPB_INLINE void envoy_config_rbac_v2_Permission_set_or_rules(envoy_config_rbac_v2_Permission *msg, envoy_config_rbac_v2_Permission_Set* value) {
UPB_WRITE_ONEOF(msg, envoy_config_rbac_v2_Permission_Set*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 2);
}
UPB_INLINE struct envoy_config_rbac_v2_Permission_Set* envoy_config_rbac_v2_Permission_mutable_or_rules(envoy_config_rbac_v2_Permission *msg, upb_arena *arena) {
struct envoy_config_rbac_v2_Permission_Set* sub = (struct envoy_config_rbac_v2_Permission_Set*)envoy_config_rbac_v2_Permission_or_rules(msg);
if (sub == NULL) {
sub = (struct envoy_config_rbac_v2_Permission_Set*)upb_msg_new(&envoy_config_rbac_v2_Permission_Set_msginit, arena);
if (!sub) return NULL;
envoy_config_rbac_v2_Permission_set_or_rules(msg, sub);
}
return sub;
}
UPB_INLINE void envoy_config_rbac_v2_Permission_set_any(envoy_config_rbac_v2_Permission *msg, bool value) {
UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 3);
}
UPB_INLINE void envoy_config_rbac_v2_Permission_set_header(envoy_config_rbac_v2_Permission *msg, struct envoy_api_v2_route_HeaderMatcher* value) {
UPB_WRITE_ONEOF(msg, struct envoy_api_v2_route_HeaderMatcher*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 4);
}
UPB_INLINE struct envoy_api_v2_route_HeaderMatcher* envoy_config_rbac_v2_Permission_mutable_header(envoy_config_rbac_v2_Permission *msg, upb_arena *arena) {
struct envoy_api_v2_route_HeaderMatcher* sub = (struct envoy_api_v2_route_HeaderMatcher*)envoy_config_rbac_v2_Permission_header(msg);
if (sub == NULL) {
sub = (struct envoy_api_v2_route_HeaderMatcher*)upb_msg_new(&envoy_api_v2_route_HeaderMatcher_msginit, arena);
if (!sub) return NULL;
envoy_config_rbac_v2_Permission_set_header(msg, sub);
}
return sub;
}
UPB_INLINE void envoy_config_rbac_v2_Permission_set_destination_ip(envoy_config_rbac_v2_Permission *msg, struct envoy_api_v2_core_CidrRange* value) {
UPB_WRITE_ONEOF(msg, struct envoy_api_v2_core_CidrRange*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 5);
}
UPB_INLINE struct envoy_api_v2_core_CidrRange* envoy_config_rbac_v2_Permission_mutable_destination_ip(envoy_config_rbac_v2_Permission *msg, upb_arena *arena) {
struct envoy_api_v2_core_CidrRange* sub = (struct envoy_api_v2_core_CidrRange*)envoy_config_rbac_v2_Permission_destination_ip(msg);
if (sub == NULL) {
sub = (struct envoy_api_v2_core_CidrRange*)upb_msg_new(&envoy_api_v2_core_CidrRange_msginit, arena);
if (!sub) return NULL;
envoy_config_rbac_v2_Permission_set_destination_ip(msg, sub);
}
return sub;
}
UPB_INLINE void envoy_config_rbac_v2_Permission_set_destination_port(envoy_config_rbac_v2_Permission *msg, uint32_t value) {
UPB_WRITE_ONEOF(msg, uint32_t, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 6);
}
UPB_INLINE void envoy_config_rbac_v2_Permission_set_metadata(envoy_config_rbac_v2_Permission *msg, struct envoy_type_matcher_MetadataMatcher* value) {
UPB_WRITE_ONEOF(msg, struct envoy_type_matcher_MetadataMatcher*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 7);
}
UPB_INLINE struct envoy_type_matcher_MetadataMatcher* envoy_config_rbac_v2_Permission_mutable_metadata(envoy_config_rbac_v2_Permission *msg, upb_arena *arena) {
struct envoy_type_matcher_MetadataMatcher* sub = (struct envoy_type_matcher_MetadataMatcher*)envoy_config_rbac_v2_Permission_metadata(msg);
if (sub == NULL) {
sub = (struct envoy_type_matcher_MetadataMatcher*)upb_msg_new(&envoy_type_matcher_MetadataMatcher_msginit, arena);
if (!sub) return NULL;
envoy_config_rbac_v2_Permission_set_metadata(msg, sub);
}
return sub;
}
UPB_INLINE void envoy_config_rbac_v2_Permission_set_not_rule(envoy_config_rbac_v2_Permission *msg, envoy_config_rbac_v2_Permission* value) {
UPB_WRITE_ONEOF(msg, envoy_config_rbac_v2_Permission*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 8);
}
UPB_INLINE struct envoy_config_rbac_v2_Permission* envoy_config_rbac_v2_Permission_mutable_not_rule(envoy_config_rbac_v2_Permission *msg, upb_arena *arena) {
struct envoy_config_rbac_v2_Permission* sub = (struct envoy_config_rbac_v2_Permission*)envoy_config_rbac_v2_Permission_not_rule(msg);
if (sub == NULL) {
sub = (struct envoy_config_rbac_v2_Permission*)upb_msg_new(&envoy_config_rbac_v2_Permission_msginit, arena);
if (!sub) return NULL;
envoy_config_rbac_v2_Permission_set_not_rule(msg, sub);
}
return sub;
}
UPB_INLINE void envoy_config_rbac_v2_Permission_set_requested_server_name(envoy_config_rbac_v2_Permission *msg, struct envoy_type_matcher_StringMatcher* value) {
UPB_WRITE_ONEOF(msg, struct envoy_type_matcher_StringMatcher*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 9);
}
UPB_INLINE struct envoy_type_matcher_StringMatcher* envoy_config_rbac_v2_Permission_mutable_requested_server_name(envoy_config_rbac_v2_Permission *msg, upb_arena *arena) {
struct envoy_type_matcher_StringMatcher* sub = (struct envoy_type_matcher_StringMatcher*)envoy_config_rbac_v2_Permission_requested_server_name(msg);
if (sub == NULL) {
sub = (struct envoy_type_matcher_StringMatcher*)upb_msg_new(&envoy_type_matcher_StringMatcher_msginit, arena);
if (!sub) return NULL;
envoy_config_rbac_v2_Permission_set_requested_server_name(msg, sub);
}
return sub;
}
UPB_INLINE void envoy_config_rbac_v2_Permission_set_url_path(envoy_config_rbac_v2_Permission *msg, struct envoy_type_matcher_PathMatcher* value) {
UPB_WRITE_ONEOF(msg, struct envoy_type_matcher_PathMatcher*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 10);
}
UPB_INLINE struct envoy_type_matcher_PathMatcher* envoy_config_rbac_v2_Permission_mutable_url_path(envoy_config_rbac_v2_Permission *msg, upb_arena *arena) {
struct envoy_type_matcher_PathMatcher* sub = (struct envoy_type_matcher_PathMatcher*)envoy_config_rbac_v2_Permission_url_path(msg);
if (sub == NULL) {
sub = (struct envoy_type_matcher_PathMatcher*)upb_msg_new(&envoy_type_matcher_PathMatcher_msginit, arena);
if (!sub) return NULL;
envoy_config_rbac_v2_Permission_set_url_path(msg, sub);
}
return sub;
}
/* envoy.config.rbac.v2.Permission.Set */
UPB_INLINE envoy_config_rbac_v2_Permission_Set *envoy_config_rbac_v2_Permission_Set_new(upb_arena *arena) {
return (envoy_config_rbac_v2_Permission_Set *)upb_msg_new(&envoy_config_rbac_v2_Permission_Set_msginit, arena);
}
UPB_INLINE envoy_config_rbac_v2_Permission_Set *envoy_config_rbac_v2_Permission_Set_parse(const char *buf, size_t size,
upb_arena *arena) {
envoy_config_rbac_v2_Permission_Set *ret = envoy_config_rbac_v2_Permission_Set_new(arena);
return (ret && upb_decode(buf, size, ret, &envoy_config_rbac_v2_Permission_Set_msginit, arena)) ? ret : NULL;
}
UPB_INLINE char *envoy_config_rbac_v2_Permission_Set_serialize(const envoy_config_rbac_v2_Permission_Set *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &envoy_config_rbac_v2_Permission_Set_msginit, arena, len);
}
UPB_INLINE const envoy_config_rbac_v2_Permission* const* envoy_config_rbac_v2_Permission_Set_rules(const envoy_config_rbac_v2_Permission_Set *msg, size_t *len) { return (const envoy_config_rbac_v2_Permission* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); }
UPB_INLINE envoy_config_rbac_v2_Permission** envoy_config_rbac_v2_Permission_Set_mutable_rules(envoy_config_rbac_v2_Permission_Set *msg, size_t *len) {
return (envoy_config_rbac_v2_Permission**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
}
UPB_INLINE envoy_config_rbac_v2_Permission** envoy_config_rbac_v2_Permission_Set_resize_rules(envoy_config_rbac_v2_Permission_Set *msg, size_t len, upb_arena *arena) {
return (envoy_config_rbac_v2_Permission**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct envoy_config_rbac_v2_Permission* envoy_config_rbac_v2_Permission_Set_add_rules(envoy_config_rbac_v2_Permission_Set *msg, upb_arena *arena) {
struct envoy_config_rbac_v2_Permission* sub = (struct envoy_config_rbac_v2_Permission*)upb_msg_new(&envoy_config_rbac_v2_Permission_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
return sub;
}
/* envoy.config.rbac.v2.Principal */
UPB_INLINE envoy_config_rbac_v2_Principal *envoy_config_rbac_v2_Principal_new(upb_arena *arena) {
return (envoy_config_rbac_v2_Principal *)upb_msg_new(&envoy_config_rbac_v2_Principal_msginit, arena);
}
UPB_INLINE envoy_config_rbac_v2_Principal *envoy_config_rbac_v2_Principal_parse(const char *buf, size_t size,
upb_arena *arena) {
envoy_config_rbac_v2_Principal *ret = envoy_config_rbac_v2_Principal_new(arena);
return (ret && upb_decode(buf, size, ret, &envoy_config_rbac_v2_Principal_msginit, arena)) ? ret : NULL;
}
UPB_INLINE char *envoy_config_rbac_v2_Principal_serialize(const envoy_config_rbac_v2_Principal *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &envoy_config_rbac_v2_Principal_msginit, arena, len);
}
typedef enum {
envoy_config_rbac_v2_Principal_identifier_and_ids = 1,
envoy_config_rbac_v2_Principal_identifier_or_ids = 2,
envoy_config_rbac_v2_Principal_identifier_any = 3,
envoy_config_rbac_v2_Principal_identifier_authenticated = 4,
envoy_config_rbac_v2_Principal_identifier_source_ip = 5,
envoy_config_rbac_v2_Principal_identifier_direct_remote_ip = 10,
envoy_config_rbac_v2_Principal_identifier_remote_ip = 11,
envoy_config_rbac_v2_Principal_identifier_header = 6,
envoy_config_rbac_v2_Principal_identifier_url_path = 9,
envoy_config_rbac_v2_Principal_identifier_metadata = 7,
envoy_config_rbac_v2_Principal_identifier_not_id = 8,
envoy_config_rbac_v2_Principal_identifier_NOT_SET = 0
} envoy_config_rbac_v2_Principal_identifier_oneofcases;
UPB_INLINE envoy_config_rbac_v2_Principal_identifier_oneofcases envoy_config_rbac_v2_Principal_identifier_case(const envoy_config_rbac_v2_Principal* msg) { return (envoy_config_rbac_v2_Principal_identifier_oneofcases)UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 8)); }
UPB_INLINE bool envoy_config_rbac_v2_Principal_has_and_ids(const envoy_config_rbac_v2_Principal *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 1); }
UPB_INLINE const envoy_config_rbac_v2_Principal_Set* envoy_config_rbac_v2_Principal_and_ids(const envoy_config_rbac_v2_Principal *msg) { return UPB_READ_ONEOF(msg, const envoy_config_rbac_v2_Principal_Set*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 1, NULL); }
UPB_INLINE bool envoy_config_rbac_v2_Principal_has_or_ids(const envoy_config_rbac_v2_Principal *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 2); }
UPB_INLINE const envoy_config_rbac_v2_Principal_Set* envoy_config_rbac_v2_Principal_or_ids(const envoy_config_rbac_v2_Principal *msg) { return UPB_READ_ONEOF(msg, const envoy_config_rbac_v2_Principal_Set*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 2, NULL); }
UPB_INLINE bool envoy_config_rbac_v2_Principal_has_any(const envoy_config_rbac_v2_Principal *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 3); }
UPB_INLINE bool envoy_config_rbac_v2_Principal_any(const envoy_config_rbac_v2_Principal *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 3, false); }
UPB_INLINE bool envoy_config_rbac_v2_Principal_has_authenticated(const envoy_config_rbac_v2_Principal *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 4); }
UPB_INLINE const envoy_config_rbac_v2_Principal_Authenticated* envoy_config_rbac_v2_Principal_authenticated(const envoy_config_rbac_v2_Principal *msg) { return UPB_READ_ONEOF(msg, const envoy_config_rbac_v2_Principal_Authenticated*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 4, NULL); }
UPB_INLINE bool envoy_config_rbac_v2_Principal_has_source_ip(const envoy_config_rbac_v2_Principal *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 5); }
UPB_INLINE const struct envoy_api_v2_core_CidrRange* envoy_config_rbac_v2_Principal_source_ip(const envoy_config_rbac_v2_Principal *msg) { return UPB_READ_ONEOF(msg, const struct envoy_api_v2_core_CidrRange*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 5, NULL); }
UPB_INLINE bool envoy_config_rbac_v2_Principal_has_header(const envoy_config_rbac_v2_Principal *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 6); }
UPB_INLINE const struct envoy_api_v2_route_HeaderMatcher* envoy_config_rbac_v2_Principal_header(const envoy_config_rbac_v2_Principal *msg) { return UPB_READ_ONEOF(msg, const struct envoy_api_v2_route_HeaderMatcher*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 6, NULL); }
UPB_INLINE bool envoy_config_rbac_v2_Principal_has_metadata(const envoy_config_rbac_v2_Principal *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 7); }
UPB_INLINE const struct envoy_type_matcher_MetadataMatcher* envoy_config_rbac_v2_Principal_metadata(const envoy_config_rbac_v2_Principal *msg) { return UPB_READ_ONEOF(msg, const struct envoy_type_matcher_MetadataMatcher*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 7, NULL); }
UPB_INLINE bool envoy_config_rbac_v2_Principal_has_not_id(const envoy_config_rbac_v2_Principal *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 8); }
UPB_INLINE const envoy_config_rbac_v2_Principal* envoy_config_rbac_v2_Principal_not_id(const envoy_config_rbac_v2_Principal *msg) { return UPB_READ_ONEOF(msg, const envoy_config_rbac_v2_Principal*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 8, NULL); }
UPB_INLINE bool envoy_config_rbac_v2_Principal_has_url_path(const envoy_config_rbac_v2_Principal *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 9); }
UPB_INLINE const struct envoy_type_matcher_PathMatcher* envoy_config_rbac_v2_Principal_url_path(const envoy_config_rbac_v2_Principal *msg) { return UPB_READ_ONEOF(msg, const struct envoy_type_matcher_PathMatcher*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 9, NULL); }
UPB_INLINE bool envoy_config_rbac_v2_Principal_has_direct_remote_ip(const envoy_config_rbac_v2_Principal *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 10); }
UPB_INLINE const struct envoy_api_v2_core_CidrRange* envoy_config_rbac_v2_Principal_direct_remote_ip(const envoy_config_rbac_v2_Principal *msg) { return UPB_READ_ONEOF(msg, const struct envoy_api_v2_core_CidrRange*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 10, NULL); }
UPB_INLINE bool envoy_config_rbac_v2_Principal_has_remote_ip(const envoy_config_rbac_v2_Principal *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 11); }
UPB_INLINE const struct envoy_api_v2_core_CidrRange* envoy_config_rbac_v2_Principal_remote_ip(const envoy_config_rbac_v2_Principal *msg) { return UPB_READ_ONEOF(msg, const struct envoy_api_v2_core_CidrRange*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 11, NULL); }
UPB_INLINE void envoy_config_rbac_v2_Principal_set_and_ids(envoy_config_rbac_v2_Principal *msg, envoy_config_rbac_v2_Principal_Set* value) {
UPB_WRITE_ONEOF(msg, envoy_config_rbac_v2_Principal_Set*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 1);
}
UPB_INLINE struct envoy_config_rbac_v2_Principal_Set* envoy_config_rbac_v2_Principal_mutable_and_ids(envoy_config_rbac_v2_Principal *msg, upb_arena *arena) {
struct envoy_config_rbac_v2_Principal_Set* sub = (struct envoy_config_rbac_v2_Principal_Set*)envoy_config_rbac_v2_Principal_and_ids(msg);
if (sub == NULL) {
sub = (struct envoy_config_rbac_v2_Principal_Set*)upb_msg_new(&envoy_config_rbac_v2_Principal_Set_msginit, arena);
if (!sub) return NULL;
envoy_config_rbac_v2_Principal_set_and_ids(msg, sub);
}
return sub;
}
UPB_INLINE void envoy_config_rbac_v2_Principal_set_or_ids(envoy_config_rbac_v2_Principal *msg, envoy_config_rbac_v2_Principal_Set* value) {
UPB_WRITE_ONEOF(msg, envoy_config_rbac_v2_Principal_Set*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 2);
}
UPB_INLINE struct envoy_config_rbac_v2_Principal_Set* envoy_config_rbac_v2_Principal_mutable_or_ids(envoy_config_rbac_v2_Principal *msg, upb_arena *arena) {
struct envoy_config_rbac_v2_Principal_Set* sub = (struct envoy_config_rbac_v2_Principal_Set*)envoy_config_rbac_v2_Principal_or_ids(msg);
if (sub == NULL) {
sub = (struct envoy_config_rbac_v2_Principal_Set*)upb_msg_new(&envoy_config_rbac_v2_Principal_Set_msginit, arena);
if (!sub) return NULL;
envoy_config_rbac_v2_Principal_set_or_ids(msg, sub);
}
return sub;
}
UPB_INLINE void envoy_config_rbac_v2_Principal_set_any(envoy_config_rbac_v2_Principal *msg, bool value) {
UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 3);
}
UPB_INLINE void envoy_config_rbac_v2_Principal_set_authenticated(envoy_config_rbac_v2_Principal *msg, envoy_config_rbac_v2_Principal_Authenticated* value) {
UPB_WRITE_ONEOF(msg, envoy_config_rbac_v2_Principal_Authenticated*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 4);
}
UPB_INLINE struct envoy_config_rbac_v2_Principal_Authenticated* envoy_config_rbac_v2_Principal_mutable_authenticated(envoy_config_rbac_v2_Principal *msg, upb_arena *arena) {
struct envoy_config_rbac_v2_Principal_Authenticated* sub = (struct envoy_config_rbac_v2_Principal_Authenticated*)envoy_config_rbac_v2_Principal_authenticated(msg);
if (sub == NULL) {
sub = (struct envoy_config_rbac_v2_Principal_Authenticated*)upb_msg_new(&envoy_config_rbac_v2_Principal_Authenticated_msginit, arena);
if (!sub) return NULL;
envoy_config_rbac_v2_Principal_set_authenticated(msg, sub);
}
return sub;
}
UPB_INLINE void envoy_config_rbac_v2_Principal_set_source_ip(envoy_config_rbac_v2_Principal *msg, struct envoy_api_v2_core_CidrRange* value) {
UPB_WRITE_ONEOF(msg, struct envoy_api_v2_core_CidrRange*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 5);
}
UPB_INLINE struct envoy_api_v2_core_CidrRange* envoy_config_rbac_v2_Principal_mutable_source_ip(envoy_config_rbac_v2_Principal *msg, upb_arena *arena) {
struct envoy_api_v2_core_CidrRange* sub = (struct envoy_api_v2_core_CidrRange*)envoy_config_rbac_v2_Principal_source_ip(msg);
if (sub == NULL) {
sub = (struct envoy_api_v2_core_CidrRange*)upb_msg_new(&envoy_api_v2_core_CidrRange_msginit, arena);
if (!sub) return NULL;
envoy_config_rbac_v2_Principal_set_source_ip(msg, sub);
}
return sub;
}
UPB_INLINE void envoy_config_rbac_v2_Principal_set_header(envoy_config_rbac_v2_Principal *msg, struct envoy_api_v2_route_HeaderMatcher* value) {
UPB_WRITE_ONEOF(msg, struct envoy_api_v2_route_HeaderMatcher*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 6);
}
UPB_INLINE struct envoy_api_v2_route_HeaderMatcher* envoy_config_rbac_v2_Principal_mutable_header(envoy_config_rbac_v2_Principal *msg, upb_arena *arena) {
struct envoy_api_v2_route_HeaderMatcher* sub = (struct envoy_api_v2_route_HeaderMatcher*)envoy_config_rbac_v2_Principal_header(msg);
if (sub == NULL) {
sub = (struct envoy_api_v2_route_HeaderMatcher*)upb_msg_new(&envoy_api_v2_route_HeaderMatcher_msginit, arena);
if (!sub) return NULL;
envoy_config_rbac_v2_Principal_set_header(msg, sub);
}
return sub;
}
UPB_INLINE void envoy_config_rbac_v2_Principal_set_metadata(envoy_config_rbac_v2_Principal *msg, struct envoy_type_matcher_MetadataMatcher* value) {
UPB_WRITE_ONEOF(msg, struct envoy_type_matcher_MetadataMatcher*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 7);
}
UPB_INLINE struct envoy_type_matcher_MetadataMatcher* envoy_config_rbac_v2_Principal_mutable_metadata(envoy_config_rbac_v2_Principal *msg, upb_arena *arena) {
struct envoy_type_matcher_MetadataMatcher* sub = (struct envoy_type_matcher_MetadataMatcher*)envoy_config_rbac_v2_Principal_metadata(msg);
if (sub == NULL) {
sub = (struct envoy_type_matcher_MetadataMatcher*)upb_msg_new(&envoy_type_matcher_MetadataMatcher_msginit, arena);
if (!sub) return NULL;
envoy_config_rbac_v2_Principal_set_metadata(msg, sub);
}
return sub;
}
UPB_INLINE void envoy_config_rbac_v2_Principal_set_not_id(envoy_config_rbac_v2_Principal *msg, envoy_config_rbac_v2_Principal* value) {
UPB_WRITE_ONEOF(msg, envoy_config_rbac_v2_Principal*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 8);
}
UPB_INLINE struct envoy_config_rbac_v2_Principal* envoy_config_rbac_v2_Principal_mutable_not_id(envoy_config_rbac_v2_Principal *msg, upb_arena *arena) {
struct envoy_config_rbac_v2_Principal* sub = (struct envoy_config_rbac_v2_Principal*)envoy_config_rbac_v2_Principal_not_id(msg);
if (sub == NULL) {
sub = (struct envoy_config_rbac_v2_Principal*)upb_msg_new(&envoy_config_rbac_v2_Principal_msginit, arena);
if (!sub) return NULL;
envoy_config_rbac_v2_Principal_set_not_id(msg, sub);
}
return sub;
}
UPB_INLINE void envoy_config_rbac_v2_Principal_set_url_path(envoy_config_rbac_v2_Principal *msg, struct envoy_type_matcher_PathMatcher* value) {
UPB_WRITE_ONEOF(msg, struct envoy_type_matcher_PathMatcher*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 9);
}
UPB_INLINE struct envoy_type_matcher_PathMatcher* envoy_config_rbac_v2_Principal_mutable_url_path(envoy_config_rbac_v2_Principal *msg, upb_arena *arena) {
struct envoy_type_matcher_PathMatcher* sub = (struct envoy_type_matcher_PathMatcher*)envoy_config_rbac_v2_Principal_url_path(msg);
if (sub == NULL) {
sub = (struct envoy_type_matcher_PathMatcher*)upb_msg_new(&envoy_type_matcher_PathMatcher_msginit, arena);
if (!sub) return NULL;
envoy_config_rbac_v2_Principal_set_url_path(msg, sub);
}
return sub;
}
UPB_INLINE void envoy_config_rbac_v2_Principal_set_direct_remote_ip(envoy_config_rbac_v2_Principal *msg, struct envoy_api_v2_core_CidrRange* value) {
UPB_WRITE_ONEOF(msg, struct envoy_api_v2_core_CidrRange*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 10);
}
UPB_INLINE struct envoy_api_v2_core_CidrRange* envoy_config_rbac_v2_Principal_mutable_direct_remote_ip(envoy_config_rbac_v2_Principal *msg, upb_arena *arena) {
struct envoy_api_v2_core_CidrRange* sub = (struct envoy_api_v2_core_CidrRange*)envoy_config_rbac_v2_Principal_direct_remote_ip(msg);
if (sub == NULL) {
sub = (struct envoy_api_v2_core_CidrRange*)upb_msg_new(&envoy_api_v2_core_CidrRange_msginit, arena);
if (!sub) return NULL;
envoy_config_rbac_v2_Principal_set_direct_remote_ip(msg, sub);
}
return sub;
}
UPB_INLINE void envoy_config_rbac_v2_Principal_set_remote_ip(envoy_config_rbac_v2_Principal *msg, struct envoy_api_v2_core_CidrRange* value) {
UPB_WRITE_ONEOF(msg, struct envoy_api_v2_core_CidrRange*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 11);
}
UPB_INLINE struct envoy_api_v2_core_CidrRange* envoy_config_rbac_v2_Principal_mutable_remote_ip(envoy_config_rbac_v2_Principal *msg, upb_arena *arena) {
struct envoy_api_v2_core_CidrRange* sub = (struct envoy_api_v2_core_CidrRange*)envoy_config_rbac_v2_Principal_remote_ip(msg);
if (sub == NULL) {
sub = (struct envoy_api_v2_core_CidrRange*)upb_msg_new(&envoy_api_v2_core_CidrRange_msginit, arena);
if (!sub) return NULL;
envoy_config_rbac_v2_Principal_set_remote_ip(msg, sub);
}
return sub;
}
/* envoy.config.rbac.v2.Principal.Set */
UPB_INLINE envoy_config_rbac_v2_Principal_Set *envoy_config_rbac_v2_Principal_Set_new(upb_arena *arena) {
return (envoy_config_rbac_v2_Principal_Set *)upb_msg_new(&envoy_config_rbac_v2_Principal_Set_msginit, arena);
}
UPB_INLINE envoy_config_rbac_v2_Principal_Set *envoy_config_rbac_v2_Principal_Set_parse(const char *buf, size_t size,
upb_arena *arena) {
envoy_config_rbac_v2_Principal_Set *ret = envoy_config_rbac_v2_Principal_Set_new(arena);
return (ret && upb_decode(buf, size, ret, &envoy_config_rbac_v2_Principal_Set_msginit, arena)) ? ret : NULL;
}
UPB_INLINE char *envoy_config_rbac_v2_Principal_Set_serialize(const envoy_config_rbac_v2_Principal_Set *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &envoy_config_rbac_v2_Principal_Set_msginit, arena, len);
}
UPB_INLINE const envoy_config_rbac_v2_Principal* const* envoy_config_rbac_v2_Principal_Set_ids(const envoy_config_rbac_v2_Principal_Set *msg, size_t *len) { return (const envoy_config_rbac_v2_Principal* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); }
UPB_INLINE envoy_config_rbac_v2_Principal** envoy_config_rbac_v2_Principal_Set_mutable_ids(envoy_config_rbac_v2_Principal_Set *msg, size_t *len) {
return (envoy_config_rbac_v2_Principal**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
}
UPB_INLINE envoy_config_rbac_v2_Principal** envoy_config_rbac_v2_Principal_Set_resize_ids(envoy_config_rbac_v2_Principal_Set *msg, size_t len, upb_arena *arena) {
return (envoy_config_rbac_v2_Principal**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct envoy_config_rbac_v2_Principal* envoy_config_rbac_v2_Principal_Set_add_ids(envoy_config_rbac_v2_Principal_Set *msg, upb_arena *arena) {
struct envoy_config_rbac_v2_Principal* sub = (struct envoy_config_rbac_v2_Principal*)upb_msg_new(&envoy_config_rbac_v2_Principal_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
return sub;
}
/* envoy.config.rbac.v2.Principal.Authenticated */
UPB_INLINE envoy_config_rbac_v2_Principal_Authenticated *envoy_config_rbac_v2_Principal_Authenticated_new(upb_arena *arena) {
return (envoy_config_rbac_v2_Principal_Authenticated *)upb_msg_new(&envoy_config_rbac_v2_Principal_Authenticated_msginit, arena);
}
UPB_INLINE envoy_config_rbac_v2_Principal_Authenticated *envoy_config_rbac_v2_Principal_Authenticated_parse(const char *buf, size_t size,
upb_arena *arena) {
envoy_config_rbac_v2_Principal_Authenticated *ret = envoy_config_rbac_v2_Principal_Authenticated_new(arena);
return (ret && upb_decode(buf, size, ret, &envoy_config_rbac_v2_Principal_Authenticated_msginit, arena)) ? ret : NULL;
}
UPB_INLINE char *envoy_config_rbac_v2_Principal_Authenticated_serialize(const envoy_config_rbac_v2_Principal_Authenticated *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &envoy_config_rbac_v2_Principal_Authenticated_msginit, arena, len);
}
UPB_INLINE const struct envoy_type_matcher_StringMatcher* envoy_config_rbac_v2_Principal_Authenticated_principal_name(const envoy_config_rbac_v2_Principal_Authenticated *msg) { return UPB_FIELD_AT(msg, const struct envoy_type_matcher_StringMatcher*, UPB_SIZE(0, 0)); }
UPB_INLINE void envoy_config_rbac_v2_Principal_Authenticated_set_principal_name(envoy_config_rbac_v2_Principal_Authenticated *msg, struct envoy_type_matcher_StringMatcher* value) {
UPB_FIELD_AT(msg, struct envoy_type_matcher_StringMatcher*, UPB_SIZE(0, 0)) = value;
}
UPB_INLINE struct envoy_type_matcher_StringMatcher* envoy_config_rbac_v2_Principal_Authenticated_mutable_principal_name(envoy_config_rbac_v2_Principal_Authenticated *msg, upb_arena *arena) {
struct envoy_type_matcher_StringMatcher* sub = (struct envoy_type_matcher_StringMatcher*)envoy_config_rbac_v2_Principal_Authenticated_principal_name(msg);
if (sub == NULL) {
sub = (struct envoy_type_matcher_StringMatcher*)upb_msg_new(&envoy_type_matcher_StringMatcher_msginit, arena);
if (!sub) return NULL;
envoy_config_rbac_v2_Principal_Authenticated_set_principal_name(msg, sub);
}
return sub;
}
#ifdef __cplusplus
} /* extern "C" */
#endif
#include "upb/port_undef.inc"
#endif /* ENVOY_CONFIG_RBAC_V2_RBAC_PROTO_UPB_H_ */

@ -0,0 +1,33 @@
/* This file was generated by upbc (the upb compiler) from the input
* file:
*
* envoy/type/matcher/path.proto
*
* Do not edit -- your changes will be discarded when the file is
* regenerated. */
#include <stddef.h>
#include "upb/msg.h"
#include "envoy/type/matcher/path.upb.h"
#include "envoy/type/matcher/string.upb.h"
#include "udpa/annotations/status.upb.h"
#include "validate/validate.upb.h"
#include "upb/port_def.inc"
static const upb_msglayout *const envoy_type_matcher_PathMatcher_submsgs[1] = {
&envoy_type_matcher_StringMatcher_msginit,
};
static const upb_msglayout_field envoy_type_matcher_PathMatcher__fields[1] = {
{1, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 0, 11, 1},
};
const upb_msglayout envoy_type_matcher_PathMatcher_msginit = {
&envoy_type_matcher_PathMatcher_submsgs[0],
&envoy_type_matcher_PathMatcher__fields[0],
UPB_SIZE(8, 16), 1, false,
};
#include "upb/port_undef.inc"

@ -0,0 +1,72 @@
/* This file was generated by upbc (the upb compiler) from the input
* file:
*
* envoy/type/matcher/path.proto
*
* Do not edit -- your changes will be discarded when the file is
* regenerated. */
#ifndef ENVOY_TYPE_MATCHER_PATH_PROTO_UPB_H_
#define ENVOY_TYPE_MATCHER_PATH_PROTO_UPB_H_
#include "upb/generated_util.h"
#include "upb/msg.h"
#include "upb/decode.h"
#include "upb/encode.h"
#include "upb/port_def.inc"
#ifdef __cplusplus
extern "C" {
#endif
struct envoy_type_matcher_PathMatcher;
typedef struct envoy_type_matcher_PathMatcher envoy_type_matcher_PathMatcher;
extern const upb_msglayout envoy_type_matcher_PathMatcher_msginit;
struct envoy_type_matcher_StringMatcher;
extern const upb_msglayout envoy_type_matcher_StringMatcher_msginit;
/* envoy.type.matcher.PathMatcher */
UPB_INLINE envoy_type_matcher_PathMatcher *envoy_type_matcher_PathMatcher_new(upb_arena *arena) {
return (envoy_type_matcher_PathMatcher *)upb_msg_new(&envoy_type_matcher_PathMatcher_msginit, arena);
}
UPB_INLINE envoy_type_matcher_PathMatcher *envoy_type_matcher_PathMatcher_parse(const char *buf, size_t size,
upb_arena *arena) {
envoy_type_matcher_PathMatcher *ret = envoy_type_matcher_PathMatcher_new(arena);
return (ret && upb_decode(buf, size, ret, &envoy_type_matcher_PathMatcher_msginit, arena)) ? ret : NULL;
}
UPB_INLINE char *envoy_type_matcher_PathMatcher_serialize(const envoy_type_matcher_PathMatcher *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &envoy_type_matcher_PathMatcher_msginit, arena, len);
}
typedef enum {
envoy_type_matcher_PathMatcher_rule_path = 1,
envoy_type_matcher_PathMatcher_rule_NOT_SET = 0
} envoy_type_matcher_PathMatcher_rule_oneofcases;
UPB_INLINE envoy_type_matcher_PathMatcher_rule_oneofcases envoy_type_matcher_PathMatcher_rule_case(const envoy_type_matcher_PathMatcher* msg) { return (envoy_type_matcher_PathMatcher_rule_oneofcases)UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 8)); }
UPB_INLINE bool envoy_type_matcher_PathMatcher_has_path(const envoy_type_matcher_PathMatcher *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 1); }
UPB_INLINE const struct envoy_type_matcher_StringMatcher* envoy_type_matcher_PathMatcher_path(const envoy_type_matcher_PathMatcher *msg) { return UPB_READ_ONEOF(msg, const struct envoy_type_matcher_StringMatcher*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 1, NULL); }
UPB_INLINE void envoy_type_matcher_PathMatcher_set_path(envoy_type_matcher_PathMatcher *msg, struct envoy_type_matcher_StringMatcher* value) {
UPB_WRITE_ONEOF(msg, struct envoy_type_matcher_StringMatcher*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 1);
}
UPB_INLINE struct envoy_type_matcher_StringMatcher* envoy_type_matcher_PathMatcher_mutable_path(envoy_type_matcher_PathMatcher *msg, upb_arena *arena) {
struct envoy_type_matcher_StringMatcher* sub = (struct envoy_type_matcher_StringMatcher*)envoy_type_matcher_PathMatcher_path(msg);
if (sub == NULL) {
sub = (struct envoy_type_matcher_StringMatcher*)upb_msg_new(&envoy_type_matcher_StringMatcher_msginit, arena);
if (!sub) return NULL;
envoy_type_matcher_PathMatcher_set_path(msg, sub);
}
return sub;
}
#ifdef __cplusplus
} /* extern "C" */
#endif
#include "upb/port_undef.inc"
#endif /* ENVOY_TYPE_MATCHER_PATH_PROTO_UPB_H_ */

@ -0,0 +1,234 @@
/* This file was generated by upbc (the upb compiler) from the input
* file:
*
* google/api/expr/v1alpha1/syntax.proto
*
* Do not edit -- your changes will be discarded when the file is
* regenerated. */
#include <stddef.h>
#include "upb/msg.h"
#include "google/api/expr/v1alpha1/syntax.upb.h"
#include "google/protobuf/duration.upb.h"
#include "google/protobuf/struct.upb.h"
#include "google/protobuf/timestamp.upb.h"
#include "upb/port_def.inc"
static const upb_msglayout *const google_api_expr_v1alpha1_ParsedExpr_submsgs[2] = {
&google_api_expr_v1alpha1_Expr_msginit,
&google_api_expr_v1alpha1_SourceInfo_msginit,
};
static const upb_msglayout_field google_api_expr_v1alpha1_ParsedExpr__fields[2] = {
{2, UPB_SIZE(0, 0), 0, 0, 11, 1},
{3, UPB_SIZE(4, 8), 0, 1, 11, 1},
};
const upb_msglayout google_api_expr_v1alpha1_ParsedExpr_msginit = {
&google_api_expr_v1alpha1_ParsedExpr_submsgs[0],
&google_api_expr_v1alpha1_ParsedExpr__fields[0],
UPB_SIZE(8, 16), 2, false,
};
static const upb_msglayout *const google_api_expr_v1alpha1_Expr_submsgs[7] = {
&google_api_expr_v1alpha1_Constant_msginit,
&google_api_expr_v1alpha1_Expr_Call_msginit,
&google_api_expr_v1alpha1_Expr_Comprehension_msginit,
&google_api_expr_v1alpha1_Expr_CreateList_msginit,
&google_api_expr_v1alpha1_Expr_CreateStruct_msginit,
&google_api_expr_v1alpha1_Expr_Ident_msginit,
&google_api_expr_v1alpha1_Expr_Select_msginit,
};
static const upb_msglayout_field google_api_expr_v1alpha1_Expr__fields[8] = {
{2, UPB_SIZE(0, 0), 0, 0, 3, 1},
{3, UPB_SIZE(8, 8), UPB_SIZE(-13, -17), 0, 11, 1},
{4, UPB_SIZE(8, 8), UPB_SIZE(-13, -17), 5, 11, 1},
{5, UPB_SIZE(8, 8), UPB_SIZE(-13, -17), 6, 11, 1},
{6, UPB_SIZE(8, 8), UPB_SIZE(-13, -17), 1, 11, 1},
{7, UPB_SIZE(8, 8), UPB_SIZE(-13, -17), 3, 11, 1},
{8, UPB_SIZE(8, 8), UPB_SIZE(-13, -17), 4, 11, 1},
{9, UPB_SIZE(8, 8), UPB_SIZE(-13, -17), 2, 11, 1},
};
const upb_msglayout google_api_expr_v1alpha1_Expr_msginit = {
&google_api_expr_v1alpha1_Expr_submsgs[0],
&google_api_expr_v1alpha1_Expr__fields[0],
UPB_SIZE(16, 24), 8, false,
};
static const upb_msglayout_field google_api_expr_v1alpha1_Expr_Ident__fields[1] = {
{1, UPB_SIZE(0, 0), 0, 0, 9, 1},
};
const upb_msglayout google_api_expr_v1alpha1_Expr_Ident_msginit = {
NULL,
&google_api_expr_v1alpha1_Expr_Ident__fields[0],
UPB_SIZE(8, 16), 1, false,
};
static const upb_msglayout *const google_api_expr_v1alpha1_Expr_Select_submsgs[1] = {
&google_api_expr_v1alpha1_Expr_msginit,
};
static const upb_msglayout_field google_api_expr_v1alpha1_Expr_Select__fields[3] = {
{1, UPB_SIZE(12, 24), 0, 0, 11, 1},
{2, UPB_SIZE(4, 8), 0, 0, 9, 1},
{3, UPB_SIZE(0, 0), 0, 0, 8, 1},
};
const upb_msglayout google_api_expr_v1alpha1_Expr_Select_msginit = {
&google_api_expr_v1alpha1_Expr_Select_submsgs[0],
&google_api_expr_v1alpha1_Expr_Select__fields[0],
UPB_SIZE(16, 32), 3, false,
};
static const upb_msglayout *const google_api_expr_v1alpha1_Expr_Call_submsgs[2] = {
&google_api_expr_v1alpha1_Expr_msginit,
};
static const upb_msglayout_field google_api_expr_v1alpha1_Expr_Call__fields[3] = {
{1, UPB_SIZE(8, 16), 0, 0, 11, 1},
{2, UPB_SIZE(0, 0), 0, 0, 9, 1},
{3, UPB_SIZE(12, 24), 0, 0, 11, 3},
};
const upb_msglayout google_api_expr_v1alpha1_Expr_Call_msginit = {
&google_api_expr_v1alpha1_Expr_Call_submsgs[0],
&google_api_expr_v1alpha1_Expr_Call__fields[0],
UPB_SIZE(16, 32), 3, false,
};
static const upb_msglayout *const google_api_expr_v1alpha1_Expr_CreateList_submsgs[1] = {
&google_api_expr_v1alpha1_Expr_msginit,
};
static const upb_msglayout_field google_api_expr_v1alpha1_Expr_CreateList__fields[1] = {
{1, UPB_SIZE(0, 0), 0, 0, 11, 3},
};
const upb_msglayout google_api_expr_v1alpha1_Expr_CreateList_msginit = {
&google_api_expr_v1alpha1_Expr_CreateList_submsgs[0],
&google_api_expr_v1alpha1_Expr_CreateList__fields[0],
UPB_SIZE(4, 8), 1, false,
};
static const upb_msglayout *const google_api_expr_v1alpha1_Expr_CreateStruct_submsgs[1] = {
&google_api_expr_v1alpha1_Expr_CreateStruct_Entry_msginit,
};
static const upb_msglayout_field google_api_expr_v1alpha1_Expr_CreateStruct__fields[2] = {
{1, UPB_SIZE(0, 0), 0, 0, 9, 1},
{2, UPB_SIZE(8, 16), 0, 0, 11, 3},
};
const upb_msglayout google_api_expr_v1alpha1_Expr_CreateStruct_msginit = {
&google_api_expr_v1alpha1_Expr_CreateStruct_submsgs[0],
&google_api_expr_v1alpha1_Expr_CreateStruct__fields[0],
UPB_SIZE(16, 32), 2, false,
};
static const upb_msglayout *const google_api_expr_v1alpha1_Expr_CreateStruct_Entry_submsgs[2] = {
&google_api_expr_v1alpha1_Expr_msginit,
};
static const upb_msglayout_field google_api_expr_v1alpha1_Expr_CreateStruct_Entry__fields[4] = {
{1, UPB_SIZE(0, 0), 0, 0, 3, 1},
{2, UPB_SIZE(12, 16), UPB_SIZE(-21, -33), 0, 9, 1},
{3, UPB_SIZE(12, 16), UPB_SIZE(-21, -33), 0, 11, 1},
{4, UPB_SIZE(8, 8), 0, 0, 11, 1},
};
const upb_msglayout google_api_expr_v1alpha1_Expr_CreateStruct_Entry_msginit = {
&google_api_expr_v1alpha1_Expr_CreateStruct_Entry_submsgs[0],
&google_api_expr_v1alpha1_Expr_CreateStruct_Entry__fields[0],
UPB_SIZE(24, 48), 4, false,
};
static const upb_msglayout *const google_api_expr_v1alpha1_Expr_Comprehension_submsgs[5] = {
&google_api_expr_v1alpha1_Expr_msginit,
};
static const upb_msglayout_field google_api_expr_v1alpha1_Expr_Comprehension__fields[7] = {
{1, UPB_SIZE(0, 0), 0, 0, 9, 1},
{2, UPB_SIZE(16, 32), 0, 0, 11, 1},
{3, UPB_SIZE(8, 16), 0, 0, 9, 1},
{4, UPB_SIZE(20, 40), 0, 0, 11, 1},
{5, UPB_SIZE(24, 48), 0, 0, 11, 1},
{6, UPB_SIZE(28, 56), 0, 0, 11, 1},
{7, UPB_SIZE(32, 64), 0, 0, 11, 1},
};
const upb_msglayout google_api_expr_v1alpha1_Expr_Comprehension_msginit = {
&google_api_expr_v1alpha1_Expr_Comprehension_submsgs[0],
&google_api_expr_v1alpha1_Expr_Comprehension__fields[0],
UPB_SIZE(40, 80), 7, false,
};
static const upb_msglayout *const google_api_expr_v1alpha1_Constant_submsgs[2] = {
&google_protobuf_Duration_msginit,
&google_protobuf_Timestamp_msginit,
};
static const upb_msglayout_field google_api_expr_v1alpha1_Constant__fields[9] = {
{1, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 14, 1},
{2, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 8, 1},
{3, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 3, 1},
{4, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 4, 1},
{5, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 1, 1},
{6, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 9, 1},
{7, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 12, 1},
{8, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 11, 1},
{9, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 1, 11, 1},
};
const upb_msglayout google_api_expr_v1alpha1_Constant_msginit = {
&google_api_expr_v1alpha1_Constant_submsgs[0],
&google_api_expr_v1alpha1_Constant__fields[0],
UPB_SIZE(16, 32), 9, false,
};
static const upb_msglayout *const google_api_expr_v1alpha1_SourceInfo_submsgs[1] = {
&google_api_expr_v1alpha1_SourceInfo_PositionsEntry_msginit,
};
static const upb_msglayout_field google_api_expr_v1alpha1_SourceInfo__fields[4] = {
{1, UPB_SIZE(0, 0), 0, 0, 9, 1},
{2, UPB_SIZE(8, 16), 0, 0, 9, 1},
{3, UPB_SIZE(16, 32), 0, 0, 5, 3},
{4, UPB_SIZE(20, 40), 0, 0, 11, 3},
};
const upb_msglayout google_api_expr_v1alpha1_SourceInfo_msginit = {
&google_api_expr_v1alpha1_SourceInfo_submsgs[0],
&google_api_expr_v1alpha1_SourceInfo__fields[0],
UPB_SIZE(24, 48), 4, false,
};
static const upb_msglayout_field google_api_expr_v1alpha1_SourceInfo_PositionsEntry__fields[2] = {
{1, UPB_SIZE(0, 0), 0, 0, 3, 1},
{2, UPB_SIZE(8, 8), 0, 0, 5, 1},
};
const upb_msglayout google_api_expr_v1alpha1_SourceInfo_PositionsEntry_msginit = {
NULL,
&google_api_expr_v1alpha1_SourceInfo_PositionsEntry__fields[0],
UPB_SIZE(16, 16), 2, false,
};
static const upb_msglayout_field google_api_expr_v1alpha1_SourcePosition__fields[4] = {
{1, UPB_SIZE(12, 16), 0, 0, 9, 1},
{2, UPB_SIZE(0, 0), 0, 0, 5, 1},
{3, UPB_SIZE(4, 4), 0, 0, 5, 1},
{4, UPB_SIZE(8, 8), 0, 0, 5, 1},
};
const upb_msglayout google_api_expr_v1alpha1_SourcePosition_msginit = {
NULL,
&google_api_expr_v1alpha1_SourcePosition__fields[0],
UPB_SIZE(24, 32), 4, false,
};
#include "upb/port_undef.inc"

@ -0,0 +1,760 @@
/* This file was generated by upbc (the upb compiler) from the input
* file:
*
* google/api/expr/v1alpha1/syntax.proto
*
* Do not edit -- your changes will be discarded when the file is
* regenerated. */
#ifndef GOOGLE_API_EXPR_V1ALPHA1_SYNTAX_PROTO_UPB_H_
#define GOOGLE_API_EXPR_V1ALPHA1_SYNTAX_PROTO_UPB_H_
#include "upb/generated_util.h"
#include "upb/msg.h"
#include "upb/decode.h"
#include "upb/encode.h"
#include "upb/port_def.inc"
#ifdef __cplusplus
extern "C" {
#endif
struct google_api_expr_v1alpha1_ParsedExpr;
struct google_api_expr_v1alpha1_Expr;
struct google_api_expr_v1alpha1_Expr_Ident;
struct google_api_expr_v1alpha1_Expr_Select;
struct google_api_expr_v1alpha1_Expr_Call;
struct google_api_expr_v1alpha1_Expr_CreateList;
struct google_api_expr_v1alpha1_Expr_CreateStruct;
struct google_api_expr_v1alpha1_Expr_CreateStruct_Entry;
struct google_api_expr_v1alpha1_Expr_Comprehension;
struct google_api_expr_v1alpha1_Constant;
struct google_api_expr_v1alpha1_SourceInfo;
struct google_api_expr_v1alpha1_SourceInfo_PositionsEntry;
struct google_api_expr_v1alpha1_SourcePosition;
typedef struct google_api_expr_v1alpha1_ParsedExpr google_api_expr_v1alpha1_ParsedExpr;
typedef struct google_api_expr_v1alpha1_Expr google_api_expr_v1alpha1_Expr;
typedef struct google_api_expr_v1alpha1_Expr_Ident google_api_expr_v1alpha1_Expr_Ident;
typedef struct google_api_expr_v1alpha1_Expr_Select google_api_expr_v1alpha1_Expr_Select;
typedef struct google_api_expr_v1alpha1_Expr_Call google_api_expr_v1alpha1_Expr_Call;
typedef struct google_api_expr_v1alpha1_Expr_CreateList google_api_expr_v1alpha1_Expr_CreateList;
typedef struct google_api_expr_v1alpha1_Expr_CreateStruct google_api_expr_v1alpha1_Expr_CreateStruct;
typedef struct google_api_expr_v1alpha1_Expr_CreateStruct_Entry google_api_expr_v1alpha1_Expr_CreateStruct_Entry;
typedef struct google_api_expr_v1alpha1_Expr_Comprehension google_api_expr_v1alpha1_Expr_Comprehension;
typedef struct google_api_expr_v1alpha1_Constant google_api_expr_v1alpha1_Constant;
typedef struct google_api_expr_v1alpha1_SourceInfo google_api_expr_v1alpha1_SourceInfo;
typedef struct google_api_expr_v1alpha1_SourceInfo_PositionsEntry google_api_expr_v1alpha1_SourceInfo_PositionsEntry;
typedef struct google_api_expr_v1alpha1_SourcePosition google_api_expr_v1alpha1_SourcePosition;
extern const upb_msglayout google_api_expr_v1alpha1_ParsedExpr_msginit;
extern const upb_msglayout google_api_expr_v1alpha1_Expr_msginit;
extern const upb_msglayout google_api_expr_v1alpha1_Expr_Ident_msginit;
extern const upb_msglayout google_api_expr_v1alpha1_Expr_Select_msginit;
extern const upb_msglayout google_api_expr_v1alpha1_Expr_Call_msginit;
extern const upb_msglayout google_api_expr_v1alpha1_Expr_CreateList_msginit;
extern const upb_msglayout google_api_expr_v1alpha1_Expr_CreateStruct_msginit;
extern const upb_msglayout google_api_expr_v1alpha1_Expr_CreateStruct_Entry_msginit;
extern const upb_msglayout google_api_expr_v1alpha1_Expr_Comprehension_msginit;
extern const upb_msglayout google_api_expr_v1alpha1_Constant_msginit;
extern const upb_msglayout google_api_expr_v1alpha1_SourceInfo_msginit;
extern const upb_msglayout google_api_expr_v1alpha1_SourceInfo_PositionsEntry_msginit;
extern const upb_msglayout google_api_expr_v1alpha1_SourcePosition_msginit;
struct google_protobuf_Duration;
struct google_protobuf_Timestamp;
extern const upb_msglayout google_protobuf_Duration_msginit;
extern const upb_msglayout google_protobuf_Timestamp_msginit;
/* google.api.expr.v1alpha1.ParsedExpr */
UPB_INLINE google_api_expr_v1alpha1_ParsedExpr *google_api_expr_v1alpha1_ParsedExpr_new(upb_arena *arena) {
return (google_api_expr_v1alpha1_ParsedExpr *)upb_msg_new(&google_api_expr_v1alpha1_ParsedExpr_msginit, arena);
}
UPB_INLINE google_api_expr_v1alpha1_ParsedExpr *google_api_expr_v1alpha1_ParsedExpr_parse(const char *buf, size_t size,
upb_arena *arena) {
google_api_expr_v1alpha1_ParsedExpr *ret = google_api_expr_v1alpha1_ParsedExpr_new(arena);
return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_ParsedExpr_msginit, arena)) ? ret : NULL;
}
UPB_INLINE char *google_api_expr_v1alpha1_ParsedExpr_serialize(const google_api_expr_v1alpha1_ParsedExpr *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_api_expr_v1alpha1_ParsedExpr_msginit, arena, len);
}
UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_ParsedExpr_expr(const google_api_expr_v1alpha1_ParsedExpr *msg) { return UPB_FIELD_AT(msg, const google_api_expr_v1alpha1_Expr*, UPB_SIZE(0, 0)); }
UPB_INLINE const google_api_expr_v1alpha1_SourceInfo* google_api_expr_v1alpha1_ParsedExpr_source_info(const google_api_expr_v1alpha1_ParsedExpr *msg) { return UPB_FIELD_AT(msg, const google_api_expr_v1alpha1_SourceInfo*, UPB_SIZE(4, 8)); }
UPB_INLINE void google_api_expr_v1alpha1_ParsedExpr_set_expr(google_api_expr_v1alpha1_ParsedExpr *msg, google_api_expr_v1alpha1_Expr* value) {
UPB_FIELD_AT(msg, google_api_expr_v1alpha1_Expr*, UPB_SIZE(0, 0)) = value;
}
UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_ParsedExpr_mutable_expr(google_api_expr_v1alpha1_ParsedExpr *msg, upb_arena *arena) {
struct google_api_expr_v1alpha1_Expr* sub = (struct google_api_expr_v1alpha1_Expr*)google_api_expr_v1alpha1_ParsedExpr_expr(msg);
if (sub == NULL) {
sub = (struct google_api_expr_v1alpha1_Expr*)upb_msg_new(&google_api_expr_v1alpha1_Expr_msginit, arena);
if (!sub) return NULL;
google_api_expr_v1alpha1_ParsedExpr_set_expr(msg, sub);
}
return sub;
}
UPB_INLINE void google_api_expr_v1alpha1_ParsedExpr_set_source_info(google_api_expr_v1alpha1_ParsedExpr *msg, google_api_expr_v1alpha1_SourceInfo* value) {
UPB_FIELD_AT(msg, google_api_expr_v1alpha1_SourceInfo*, UPB_SIZE(4, 8)) = value;
}
UPB_INLINE struct google_api_expr_v1alpha1_SourceInfo* google_api_expr_v1alpha1_ParsedExpr_mutable_source_info(google_api_expr_v1alpha1_ParsedExpr *msg, upb_arena *arena) {
struct google_api_expr_v1alpha1_SourceInfo* sub = (struct google_api_expr_v1alpha1_SourceInfo*)google_api_expr_v1alpha1_ParsedExpr_source_info(msg);
if (sub == NULL) {
sub = (struct google_api_expr_v1alpha1_SourceInfo*)upb_msg_new(&google_api_expr_v1alpha1_SourceInfo_msginit, arena);
if (!sub) return NULL;
google_api_expr_v1alpha1_ParsedExpr_set_source_info(msg, sub);
}
return sub;
}
/* google.api.expr.v1alpha1.Expr */
UPB_INLINE google_api_expr_v1alpha1_Expr *google_api_expr_v1alpha1_Expr_new(upb_arena *arena) {
return (google_api_expr_v1alpha1_Expr *)upb_msg_new(&google_api_expr_v1alpha1_Expr_msginit, arena);
}
UPB_INLINE google_api_expr_v1alpha1_Expr *google_api_expr_v1alpha1_Expr_parse(const char *buf, size_t size,
upb_arena *arena) {
google_api_expr_v1alpha1_Expr *ret = google_api_expr_v1alpha1_Expr_new(arena);
return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Expr_msginit, arena)) ? ret : NULL;
}
UPB_INLINE char *google_api_expr_v1alpha1_Expr_serialize(const google_api_expr_v1alpha1_Expr *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_api_expr_v1alpha1_Expr_msginit, arena, len);
}
typedef enum {
google_api_expr_v1alpha1_Expr_expr_kind_const_expr = 3,
google_api_expr_v1alpha1_Expr_expr_kind_ident_expr = 4,
google_api_expr_v1alpha1_Expr_expr_kind_select_expr = 5,
google_api_expr_v1alpha1_Expr_expr_kind_call_expr = 6,
google_api_expr_v1alpha1_Expr_expr_kind_list_expr = 7,
google_api_expr_v1alpha1_Expr_expr_kind_struct_expr = 8,
google_api_expr_v1alpha1_Expr_expr_kind_comprehension_expr = 9,
google_api_expr_v1alpha1_Expr_expr_kind_NOT_SET = 0
} google_api_expr_v1alpha1_Expr_expr_kind_oneofcases;
UPB_INLINE google_api_expr_v1alpha1_Expr_expr_kind_oneofcases google_api_expr_v1alpha1_Expr_expr_kind_case(const google_api_expr_v1alpha1_Expr* msg) { return (google_api_expr_v1alpha1_Expr_expr_kind_oneofcases)UPB_FIELD_AT(msg, int32_t, UPB_SIZE(12, 16)); }
UPB_INLINE int64_t google_api_expr_v1alpha1_Expr_id(const google_api_expr_v1alpha1_Expr *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)); }
UPB_INLINE bool google_api_expr_v1alpha1_Expr_has_const_expr(const google_api_expr_v1alpha1_Expr *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 16), 3); }
UPB_INLINE const google_api_expr_v1alpha1_Constant* google_api_expr_v1alpha1_Expr_const_expr(const google_api_expr_v1alpha1_Expr *msg) { return UPB_READ_ONEOF(msg, const google_api_expr_v1alpha1_Constant*, UPB_SIZE(8, 8), UPB_SIZE(12, 16), 3, NULL); }
UPB_INLINE bool google_api_expr_v1alpha1_Expr_has_ident_expr(const google_api_expr_v1alpha1_Expr *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 16), 4); }
UPB_INLINE const google_api_expr_v1alpha1_Expr_Ident* google_api_expr_v1alpha1_Expr_ident_expr(const google_api_expr_v1alpha1_Expr *msg) { return UPB_READ_ONEOF(msg, const google_api_expr_v1alpha1_Expr_Ident*, UPB_SIZE(8, 8), UPB_SIZE(12, 16), 4, NULL); }
UPB_INLINE bool google_api_expr_v1alpha1_Expr_has_select_expr(const google_api_expr_v1alpha1_Expr *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 16), 5); }
UPB_INLINE const google_api_expr_v1alpha1_Expr_Select* google_api_expr_v1alpha1_Expr_select_expr(const google_api_expr_v1alpha1_Expr *msg) { return UPB_READ_ONEOF(msg, const google_api_expr_v1alpha1_Expr_Select*, UPB_SIZE(8, 8), UPB_SIZE(12, 16), 5, NULL); }
UPB_INLINE bool google_api_expr_v1alpha1_Expr_has_call_expr(const google_api_expr_v1alpha1_Expr *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 16), 6); }
UPB_INLINE const google_api_expr_v1alpha1_Expr_Call* google_api_expr_v1alpha1_Expr_call_expr(const google_api_expr_v1alpha1_Expr *msg) { return UPB_READ_ONEOF(msg, const google_api_expr_v1alpha1_Expr_Call*, UPB_SIZE(8, 8), UPB_SIZE(12, 16), 6, NULL); }
UPB_INLINE bool google_api_expr_v1alpha1_Expr_has_list_expr(const google_api_expr_v1alpha1_Expr *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 16), 7); }
UPB_INLINE const google_api_expr_v1alpha1_Expr_CreateList* google_api_expr_v1alpha1_Expr_list_expr(const google_api_expr_v1alpha1_Expr *msg) { return UPB_READ_ONEOF(msg, const google_api_expr_v1alpha1_Expr_CreateList*, UPB_SIZE(8, 8), UPB_SIZE(12, 16), 7, NULL); }
UPB_INLINE bool google_api_expr_v1alpha1_Expr_has_struct_expr(const google_api_expr_v1alpha1_Expr *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 16), 8); }
UPB_INLINE const google_api_expr_v1alpha1_Expr_CreateStruct* google_api_expr_v1alpha1_Expr_struct_expr(const google_api_expr_v1alpha1_Expr *msg) { return UPB_READ_ONEOF(msg, const google_api_expr_v1alpha1_Expr_CreateStruct*, UPB_SIZE(8, 8), UPB_SIZE(12, 16), 8, NULL); }
UPB_INLINE bool google_api_expr_v1alpha1_Expr_has_comprehension_expr(const google_api_expr_v1alpha1_Expr *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 16), 9); }
UPB_INLINE const google_api_expr_v1alpha1_Expr_Comprehension* google_api_expr_v1alpha1_Expr_comprehension_expr(const google_api_expr_v1alpha1_Expr *msg) { return UPB_READ_ONEOF(msg, const google_api_expr_v1alpha1_Expr_Comprehension*, UPB_SIZE(8, 8), UPB_SIZE(12, 16), 9, NULL); }
UPB_INLINE void google_api_expr_v1alpha1_Expr_set_id(google_api_expr_v1alpha1_Expr *msg, int64_t value) {
UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)) = value;
}
UPB_INLINE void google_api_expr_v1alpha1_Expr_set_const_expr(google_api_expr_v1alpha1_Expr *msg, google_api_expr_v1alpha1_Constant* value) {
UPB_WRITE_ONEOF(msg, google_api_expr_v1alpha1_Constant*, UPB_SIZE(8, 8), value, UPB_SIZE(12, 16), 3);
}
UPB_INLINE struct google_api_expr_v1alpha1_Constant* google_api_expr_v1alpha1_Expr_mutable_const_expr(google_api_expr_v1alpha1_Expr *msg, upb_arena *arena) {
struct google_api_expr_v1alpha1_Constant* sub = (struct google_api_expr_v1alpha1_Constant*)google_api_expr_v1alpha1_Expr_const_expr(msg);
if (sub == NULL) {
sub = (struct google_api_expr_v1alpha1_Constant*)upb_msg_new(&google_api_expr_v1alpha1_Constant_msginit, arena);
if (!sub) return NULL;
google_api_expr_v1alpha1_Expr_set_const_expr(msg, sub);
}
return sub;
}
UPB_INLINE void google_api_expr_v1alpha1_Expr_set_ident_expr(google_api_expr_v1alpha1_Expr *msg, google_api_expr_v1alpha1_Expr_Ident* value) {
UPB_WRITE_ONEOF(msg, google_api_expr_v1alpha1_Expr_Ident*, UPB_SIZE(8, 8), value, UPB_SIZE(12, 16), 4);
}
UPB_INLINE struct google_api_expr_v1alpha1_Expr_Ident* google_api_expr_v1alpha1_Expr_mutable_ident_expr(google_api_expr_v1alpha1_Expr *msg, upb_arena *arena) {
struct google_api_expr_v1alpha1_Expr_Ident* sub = (struct google_api_expr_v1alpha1_Expr_Ident*)google_api_expr_v1alpha1_Expr_ident_expr(msg);
if (sub == NULL) {
sub = (struct google_api_expr_v1alpha1_Expr_Ident*)upb_msg_new(&google_api_expr_v1alpha1_Expr_Ident_msginit, arena);
if (!sub) return NULL;
google_api_expr_v1alpha1_Expr_set_ident_expr(msg, sub);
}
return sub;
}
UPB_INLINE void google_api_expr_v1alpha1_Expr_set_select_expr(google_api_expr_v1alpha1_Expr *msg, google_api_expr_v1alpha1_Expr_Select* value) {
UPB_WRITE_ONEOF(msg, google_api_expr_v1alpha1_Expr_Select*, UPB_SIZE(8, 8), value, UPB_SIZE(12, 16), 5);
}
UPB_INLINE struct google_api_expr_v1alpha1_Expr_Select* google_api_expr_v1alpha1_Expr_mutable_select_expr(google_api_expr_v1alpha1_Expr *msg, upb_arena *arena) {
struct google_api_expr_v1alpha1_Expr_Select* sub = (struct google_api_expr_v1alpha1_Expr_Select*)google_api_expr_v1alpha1_Expr_select_expr(msg);
if (sub == NULL) {
sub = (struct google_api_expr_v1alpha1_Expr_Select*)upb_msg_new(&google_api_expr_v1alpha1_Expr_Select_msginit, arena);
if (!sub) return NULL;
google_api_expr_v1alpha1_Expr_set_select_expr(msg, sub);
}
return sub;
}
UPB_INLINE void google_api_expr_v1alpha1_Expr_set_call_expr(google_api_expr_v1alpha1_Expr *msg, google_api_expr_v1alpha1_Expr_Call* value) {
UPB_WRITE_ONEOF(msg, google_api_expr_v1alpha1_Expr_Call*, UPB_SIZE(8, 8), value, UPB_SIZE(12, 16), 6);
}
UPB_INLINE struct google_api_expr_v1alpha1_Expr_Call* google_api_expr_v1alpha1_Expr_mutable_call_expr(google_api_expr_v1alpha1_Expr *msg, upb_arena *arena) {
struct google_api_expr_v1alpha1_Expr_Call* sub = (struct google_api_expr_v1alpha1_Expr_Call*)google_api_expr_v1alpha1_Expr_call_expr(msg);
if (sub == NULL) {
sub = (struct google_api_expr_v1alpha1_Expr_Call*)upb_msg_new(&google_api_expr_v1alpha1_Expr_Call_msginit, arena);
if (!sub) return NULL;
google_api_expr_v1alpha1_Expr_set_call_expr(msg, sub);
}
return sub;
}
UPB_INLINE void google_api_expr_v1alpha1_Expr_set_list_expr(google_api_expr_v1alpha1_Expr *msg, google_api_expr_v1alpha1_Expr_CreateList* value) {
UPB_WRITE_ONEOF(msg, google_api_expr_v1alpha1_Expr_CreateList*, UPB_SIZE(8, 8), value, UPB_SIZE(12, 16), 7);
}
UPB_INLINE struct google_api_expr_v1alpha1_Expr_CreateList* google_api_expr_v1alpha1_Expr_mutable_list_expr(google_api_expr_v1alpha1_Expr *msg, upb_arena *arena) {
struct google_api_expr_v1alpha1_Expr_CreateList* sub = (struct google_api_expr_v1alpha1_Expr_CreateList*)google_api_expr_v1alpha1_Expr_list_expr(msg);
if (sub == NULL) {
sub = (struct google_api_expr_v1alpha1_Expr_CreateList*)upb_msg_new(&google_api_expr_v1alpha1_Expr_CreateList_msginit, arena);
if (!sub) return NULL;
google_api_expr_v1alpha1_Expr_set_list_expr(msg, sub);
}
return sub;
}
UPB_INLINE void google_api_expr_v1alpha1_Expr_set_struct_expr(google_api_expr_v1alpha1_Expr *msg, google_api_expr_v1alpha1_Expr_CreateStruct* value) {
UPB_WRITE_ONEOF(msg, google_api_expr_v1alpha1_Expr_CreateStruct*, UPB_SIZE(8, 8), value, UPB_SIZE(12, 16), 8);
}
UPB_INLINE struct google_api_expr_v1alpha1_Expr_CreateStruct* google_api_expr_v1alpha1_Expr_mutable_struct_expr(google_api_expr_v1alpha1_Expr *msg, upb_arena *arena) {
struct google_api_expr_v1alpha1_Expr_CreateStruct* sub = (struct google_api_expr_v1alpha1_Expr_CreateStruct*)google_api_expr_v1alpha1_Expr_struct_expr(msg);
if (sub == NULL) {
sub = (struct google_api_expr_v1alpha1_Expr_CreateStruct*)upb_msg_new(&google_api_expr_v1alpha1_Expr_CreateStruct_msginit, arena);
if (!sub) return NULL;
google_api_expr_v1alpha1_Expr_set_struct_expr(msg, sub);
}
return sub;
}
UPB_INLINE void google_api_expr_v1alpha1_Expr_set_comprehension_expr(google_api_expr_v1alpha1_Expr *msg, google_api_expr_v1alpha1_Expr_Comprehension* value) {
UPB_WRITE_ONEOF(msg, google_api_expr_v1alpha1_Expr_Comprehension*, UPB_SIZE(8, 8), value, UPB_SIZE(12, 16), 9);
}
UPB_INLINE struct google_api_expr_v1alpha1_Expr_Comprehension* google_api_expr_v1alpha1_Expr_mutable_comprehension_expr(google_api_expr_v1alpha1_Expr *msg, upb_arena *arena) {
struct google_api_expr_v1alpha1_Expr_Comprehension* sub = (struct google_api_expr_v1alpha1_Expr_Comprehension*)google_api_expr_v1alpha1_Expr_comprehension_expr(msg);
if (sub == NULL) {
sub = (struct google_api_expr_v1alpha1_Expr_Comprehension*)upb_msg_new(&google_api_expr_v1alpha1_Expr_Comprehension_msginit, arena);
if (!sub) return NULL;
google_api_expr_v1alpha1_Expr_set_comprehension_expr(msg, sub);
}
return sub;
}
/* google.api.expr.v1alpha1.Expr.Ident */
UPB_INLINE google_api_expr_v1alpha1_Expr_Ident *google_api_expr_v1alpha1_Expr_Ident_new(upb_arena *arena) {
return (google_api_expr_v1alpha1_Expr_Ident *)upb_msg_new(&google_api_expr_v1alpha1_Expr_Ident_msginit, arena);
}
UPB_INLINE google_api_expr_v1alpha1_Expr_Ident *google_api_expr_v1alpha1_Expr_Ident_parse(const char *buf, size_t size,
upb_arena *arena) {
google_api_expr_v1alpha1_Expr_Ident *ret = google_api_expr_v1alpha1_Expr_Ident_new(arena);
return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Expr_Ident_msginit, arena)) ? ret : NULL;
}
UPB_INLINE char *google_api_expr_v1alpha1_Expr_Ident_serialize(const google_api_expr_v1alpha1_Expr_Ident *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_api_expr_v1alpha1_Expr_Ident_msginit, arena, len);
}
UPB_INLINE upb_strview google_api_expr_v1alpha1_Expr_Ident_name(const google_api_expr_v1alpha1_Expr_Ident *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); }
UPB_INLINE void google_api_expr_v1alpha1_Expr_Ident_set_name(google_api_expr_v1alpha1_Expr_Ident *msg, upb_strview value) {
UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value;
}
/* google.api.expr.v1alpha1.Expr.Select */
UPB_INLINE google_api_expr_v1alpha1_Expr_Select *google_api_expr_v1alpha1_Expr_Select_new(upb_arena *arena) {
return (google_api_expr_v1alpha1_Expr_Select *)upb_msg_new(&google_api_expr_v1alpha1_Expr_Select_msginit, arena);
}
UPB_INLINE google_api_expr_v1alpha1_Expr_Select *google_api_expr_v1alpha1_Expr_Select_parse(const char *buf, size_t size,
upb_arena *arena) {
google_api_expr_v1alpha1_Expr_Select *ret = google_api_expr_v1alpha1_Expr_Select_new(arena);
return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Expr_Select_msginit, arena)) ? ret : NULL;
}
UPB_INLINE char *google_api_expr_v1alpha1_Expr_Select_serialize(const google_api_expr_v1alpha1_Expr_Select *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_api_expr_v1alpha1_Expr_Select_msginit, arena, len);
}
UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Select_operand(const google_api_expr_v1alpha1_Expr_Select *msg) { return UPB_FIELD_AT(msg, const google_api_expr_v1alpha1_Expr*, UPB_SIZE(12, 24)); }
UPB_INLINE upb_strview google_api_expr_v1alpha1_Expr_Select_field(const google_api_expr_v1alpha1_Expr_Select *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); }
UPB_INLINE bool google_api_expr_v1alpha1_Expr_Select_test_only(const google_api_expr_v1alpha1_Expr_Select *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)); }
UPB_INLINE void google_api_expr_v1alpha1_Expr_Select_set_operand(google_api_expr_v1alpha1_Expr_Select *msg, google_api_expr_v1alpha1_Expr* value) {
UPB_FIELD_AT(msg, google_api_expr_v1alpha1_Expr*, UPB_SIZE(12, 24)) = value;
}
UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Select_mutable_operand(google_api_expr_v1alpha1_Expr_Select *msg, upb_arena *arena) {
struct google_api_expr_v1alpha1_Expr* sub = (struct google_api_expr_v1alpha1_Expr*)google_api_expr_v1alpha1_Expr_Select_operand(msg);
if (sub == NULL) {
sub = (struct google_api_expr_v1alpha1_Expr*)upb_msg_new(&google_api_expr_v1alpha1_Expr_msginit, arena);
if (!sub) return NULL;
google_api_expr_v1alpha1_Expr_Select_set_operand(msg, sub);
}
return sub;
}
UPB_INLINE void google_api_expr_v1alpha1_Expr_Select_set_field(google_api_expr_v1alpha1_Expr_Select *msg, upb_strview value) {
UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value;
}
UPB_INLINE void google_api_expr_v1alpha1_Expr_Select_set_test_only(google_api_expr_v1alpha1_Expr_Select *msg, bool value) {
UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)) = value;
}
/* google.api.expr.v1alpha1.Expr.Call */
UPB_INLINE google_api_expr_v1alpha1_Expr_Call *google_api_expr_v1alpha1_Expr_Call_new(upb_arena *arena) {
return (google_api_expr_v1alpha1_Expr_Call *)upb_msg_new(&google_api_expr_v1alpha1_Expr_Call_msginit, arena);
}
UPB_INLINE google_api_expr_v1alpha1_Expr_Call *google_api_expr_v1alpha1_Expr_Call_parse(const char *buf, size_t size,
upb_arena *arena) {
google_api_expr_v1alpha1_Expr_Call *ret = google_api_expr_v1alpha1_Expr_Call_new(arena);
return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Expr_Call_msginit, arena)) ? ret : NULL;
}
UPB_INLINE char *google_api_expr_v1alpha1_Expr_Call_serialize(const google_api_expr_v1alpha1_Expr_Call *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_api_expr_v1alpha1_Expr_Call_msginit, arena, len);
}
UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Call_target(const google_api_expr_v1alpha1_Expr_Call *msg) { return UPB_FIELD_AT(msg, const google_api_expr_v1alpha1_Expr*, UPB_SIZE(8, 16)); }
UPB_INLINE upb_strview google_api_expr_v1alpha1_Expr_Call_function(const google_api_expr_v1alpha1_Expr_Call *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); }
UPB_INLINE const google_api_expr_v1alpha1_Expr* const* google_api_expr_v1alpha1_Expr_Call_args(const google_api_expr_v1alpha1_Expr_Call *msg, size_t *len) { return (const google_api_expr_v1alpha1_Expr* const*)_upb_array_accessor(msg, UPB_SIZE(12, 24), len); }
UPB_INLINE void google_api_expr_v1alpha1_Expr_Call_set_target(google_api_expr_v1alpha1_Expr_Call *msg, google_api_expr_v1alpha1_Expr* value) {
UPB_FIELD_AT(msg, google_api_expr_v1alpha1_Expr*, UPB_SIZE(8, 16)) = value;
}
UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Call_mutable_target(google_api_expr_v1alpha1_Expr_Call *msg, upb_arena *arena) {
struct google_api_expr_v1alpha1_Expr* sub = (struct google_api_expr_v1alpha1_Expr*)google_api_expr_v1alpha1_Expr_Call_target(msg);
if (sub == NULL) {
sub = (struct google_api_expr_v1alpha1_Expr*)upb_msg_new(&google_api_expr_v1alpha1_Expr_msginit, arena);
if (!sub) return NULL;
google_api_expr_v1alpha1_Expr_Call_set_target(msg, sub);
}
return sub;
}
UPB_INLINE void google_api_expr_v1alpha1_Expr_Call_set_function(google_api_expr_v1alpha1_Expr_Call *msg, upb_strview value) {
UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value;
}
UPB_INLINE google_api_expr_v1alpha1_Expr** google_api_expr_v1alpha1_Expr_Call_mutable_args(google_api_expr_v1alpha1_Expr_Call *msg, size_t *len) {
return (google_api_expr_v1alpha1_Expr**)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len);
}
UPB_INLINE google_api_expr_v1alpha1_Expr** google_api_expr_v1alpha1_Expr_Call_resize_args(google_api_expr_v1alpha1_Expr_Call *msg, size_t len, upb_arena *arena) {
return (google_api_expr_v1alpha1_Expr**)_upb_array_resize_accessor(msg, UPB_SIZE(12, 24), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Call_add_args(google_api_expr_v1alpha1_Expr_Call *msg, upb_arena *arena) {
struct google_api_expr_v1alpha1_Expr* sub = (struct google_api_expr_v1alpha1_Expr*)upb_msg_new(&google_api_expr_v1alpha1_Expr_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(12, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
return sub;
}
/* google.api.expr.v1alpha1.Expr.CreateList */
UPB_INLINE google_api_expr_v1alpha1_Expr_CreateList *google_api_expr_v1alpha1_Expr_CreateList_new(upb_arena *arena) {
return (google_api_expr_v1alpha1_Expr_CreateList *)upb_msg_new(&google_api_expr_v1alpha1_Expr_CreateList_msginit, arena);
}
UPB_INLINE google_api_expr_v1alpha1_Expr_CreateList *google_api_expr_v1alpha1_Expr_CreateList_parse(const char *buf, size_t size,
upb_arena *arena) {
google_api_expr_v1alpha1_Expr_CreateList *ret = google_api_expr_v1alpha1_Expr_CreateList_new(arena);
return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Expr_CreateList_msginit, arena)) ? ret : NULL;
}
UPB_INLINE char *google_api_expr_v1alpha1_Expr_CreateList_serialize(const google_api_expr_v1alpha1_Expr_CreateList *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_api_expr_v1alpha1_Expr_CreateList_msginit, arena, len);
}
UPB_INLINE const google_api_expr_v1alpha1_Expr* const* google_api_expr_v1alpha1_Expr_CreateList_elements(const google_api_expr_v1alpha1_Expr_CreateList *msg, size_t *len) { return (const google_api_expr_v1alpha1_Expr* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); }
UPB_INLINE google_api_expr_v1alpha1_Expr** google_api_expr_v1alpha1_Expr_CreateList_mutable_elements(google_api_expr_v1alpha1_Expr_CreateList *msg, size_t *len) {
return (google_api_expr_v1alpha1_Expr**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
}
UPB_INLINE google_api_expr_v1alpha1_Expr** google_api_expr_v1alpha1_Expr_CreateList_resize_elements(google_api_expr_v1alpha1_Expr_CreateList *msg, size_t len, upb_arena *arena) {
return (google_api_expr_v1alpha1_Expr**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_CreateList_add_elements(google_api_expr_v1alpha1_Expr_CreateList *msg, upb_arena *arena) {
struct google_api_expr_v1alpha1_Expr* sub = (struct google_api_expr_v1alpha1_Expr*)upb_msg_new(&google_api_expr_v1alpha1_Expr_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
return sub;
}
/* google.api.expr.v1alpha1.Expr.CreateStruct */
UPB_INLINE google_api_expr_v1alpha1_Expr_CreateStruct *google_api_expr_v1alpha1_Expr_CreateStruct_new(upb_arena *arena) {
return (google_api_expr_v1alpha1_Expr_CreateStruct *)upb_msg_new(&google_api_expr_v1alpha1_Expr_CreateStruct_msginit, arena);
}
UPB_INLINE google_api_expr_v1alpha1_Expr_CreateStruct *google_api_expr_v1alpha1_Expr_CreateStruct_parse(const char *buf, size_t size,
upb_arena *arena) {
google_api_expr_v1alpha1_Expr_CreateStruct *ret = google_api_expr_v1alpha1_Expr_CreateStruct_new(arena);
return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Expr_CreateStruct_msginit, arena)) ? ret : NULL;
}
UPB_INLINE char *google_api_expr_v1alpha1_Expr_CreateStruct_serialize(const google_api_expr_v1alpha1_Expr_CreateStruct *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_api_expr_v1alpha1_Expr_CreateStruct_msginit, arena, len);
}
UPB_INLINE upb_strview google_api_expr_v1alpha1_Expr_CreateStruct_message_name(const google_api_expr_v1alpha1_Expr_CreateStruct *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); }
UPB_INLINE const google_api_expr_v1alpha1_Expr_CreateStruct_Entry* const* google_api_expr_v1alpha1_Expr_CreateStruct_entries(const google_api_expr_v1alpha1_Expr_CreateStruct *msg, size_t *len) { return (const google_api_expr_v1alpha1_Expr_CreateStruct_Entry* const*)_upb_array_accessor(msg, UPB_SIZE(8, 16), len); }
UPB_INLINE void google_api_expr_v1alpha1_Expr_CreateStruct_set_message_name(google_api_expr_v1alpha1_Expr_CreateStruct *msg, upb_strview value) {
UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value;
}
UPB_INLINE google_api_expr_v1alpha1_Expr_CreateStruct_Entry** google_api_expr_v1alpha1_Expr_CreateStruct_mutable_entries(google_api_expr_v1alpha1_Expr_CreateStruct *msg, size_t *len) {
return (google_api_expr_v1alpha1_Expr_CreateStruct_Entry**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len);
}
UPB_INLINE google_api_expr_v1alpha1_Expr_CreateStruct_Entry** google_api_expr_v1alpha1_Expr_CreateStruct_resize_entries(google_api_expr_v1alpha1_Expr_CreateStruct *msg, size_t len, upb_arena *arena) {
return (google_api_expr_v1alpha1_Expr_CreateStruct_Entry**)_upb_array_resize_accessor(msg, UPB_SIZE(8, 16), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_api_expr_v1alpha1_Expr_CreateStruct_Entry* google_api_expr_v1alpha1_Expr_CreateStruct_add_entries(google_api_expr_v1alpha1_Expr_CreateStruct *msg, upb_arena *arena) {
struct google_api_expr_v1alpha1_Expr_CreateStruct_Entry* sub = (struct google_api_expr_v1alpha1_Expr_CreateStruct_Entry*)upb_msg_new(&google_api_expr_v1alpha1_Expr_CreateStruct_Entry_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(8, 16), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
return sub;
}
/* google.api.expr.v1alpha1.Expr.CreateStruct.Entry */
UPB_INLINE google_api_expr_v1alpha1_Expr_CreateStruct_Entry *google_api_expr_v1alpha1_Expr_CreateStruct_Entry_new(upb_arena *arena) {
return (google_api_expr_v1alpha1_Expr_CreateStruct_Entry *)upb_msg_new(&google_api_expr_v1alpha1_Expr_CreateStruct_Entry_msginit, arena);
}
UPB_INLINE google_api_expr_v1alpha1_Expr_CreateStruct_Entry *google_api_expr_v1alpha1_Expr_CreateStruct_Entry_parse(const char *buf, size_t size,
upb_arena *arena) {
google_api_expr_v1alpha1_Expr_CreateStruct_Entry *ret = google_api_expr_v1alpha1_Expr_CreateStruct_Entry_new(arena);
return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Expr_CreateStruct_Entry_msginit, arena)) ? ret : NULL;
}
UPB_INLINE char *google_api_expr_v1alpha1_Expr_CreateStruct_Entry_serialize(const google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_api_expr_v1alpha1_Expr_CreateStruct_Entry_msginit, arena, len);
}
typedef enum {
google_api_expr_v1alpha1_Expr_CreateStruct_Entry_key_kind_field_key = 2,
google_api_expr_v1alpha1_Expr_CreateStruct_Entry_key_kind_map_key = 3,
google_api_expr_v1alpha1_Expr_CreateStruct_Entry_key_kind_NOT_SET = 0
} google_api_expr_v1alpha1_Expr_CreateStruct_Entry_key_kind_oneofcases;
UPB_INLINE google_api_expr_v1alpha1_Expr_CreateStruct_Entry_key_kind_oneofcases google_api_expr_v1alpha1_Expr_CreateStruct_Entry_key_kind_case(const google_api_expr_v1alpha1_Expr_CreateStruct_Entry* msg) { return (google_api_expr_v1alpha1_Expr_CreateStruct_Entry_key_kind_oneofcases)UPB_FIELD_AT(msg, int32_t, UPB_SIZE(20, 32)); }
UPB_INLINE int64_t google_api_expr_v1alpha1_Expr_CreateStruct_Entry_id(const google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)); }
UPB_INLINE bool google_api_expr_v1alpha1_Expr_CreateStruct_Entry_has_field_key(const google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(20, 32), 2); }
UPB_INLINE upb_strview google_api_expr_v1alpha1_Expr_CreateStruct_Entry_field_key(const google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(12, 16), UPB_SIZE(20, 32), 2, upb_strview_make("", strlen(""))); }
UPB_INLINE bool google_api_expr_v1alpha1_Expr_CreateStruct_Entry_has_map_key(const google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(20, 32), 3); }
UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_CreateStruct_Entry_map_key(const google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg) { return UPB_READ_ONEOF(msg, const google_api_expr_v1alpha1_Expr*, UPB_SIZE(12, 16), UPB_SIZE(20, 32), 3, NULL); }
UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_CreateStruct_Entry_value(const google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg) { return UPB_FIELD_AT(msg, const google_api_expr_v1alpha1_Expr*, UPB_SIZE(8, 8)); }
UPB_INLINE void google_api_expr_v1alpha1_Expr_CreateStruct_Entry_set_id(google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg, int64_t value) {
UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)) = value;
}
UPB_INLINE void google_api_expr_v1alpha1_Expr_CreateStruct_Entry_set_field_key(google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg, upb_strview value) {
UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(12, 16), value, UPB_SIZE(20, 32), 2);
}
UPB_INLINE void google_api_expr_v1alpha1_Expr_CreateStruct_Entry_set_map_key(google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg, google_api_expr_v1alpha1_Expr* value) {
UPB_WRITE_ONEOF(msg, google_api_expr_v1alpha1_Expr*, UPB_SIZE(12, 16), value, UPB_SIZE(20, 32), 3);
}
UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_CreateStruct_Entry_mutable_map_key(google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg, upb_arena *arena) {
struct google_api_expr_v1alpha1_Expr* sub = (struct google_api_expr_v1alpha1_Expr*)google_api_expr_v1alpha1_Expr_CreateStruct_Entry_map_key(msg);
if (sub == NULL) {
sub = (struct google_api_expr_v1alpha1_Expr*)upb_msg_new(&google_api_expr_v1alpha1_Expr_msginit, arena);
if (!sub) return NULL;
google_api_expr_v1alpha1_Expr_CreateStruct_Entry_set_map_key(msg, sub);
}
return sub;
}
UPB_INLINE void google_api_expr_v1alpha1_Expr_CreateStruct_Entry_set_value(google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg, google_api_expr_v1alpha1_Expr* value) {
UPB_FIELD_AT(msg, google_api_expr_v1alpha1_Expr*, UPB_SIZE(8, 8)) = value;
}
UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_CreateStruct_Entry_mutable_value(google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg, upb_arena *arena) {
struct google_api_expr_v1alpha1_Expr* sub = (struct google_api_expr_v1alpha1_Expr*)google_api_expr_v1alpha1_Expr_CreateStruct_Entry_value(msg);
if (sub == NULL) {
sub = (struct google_api_expr_v1alpha1_Expr*)upb_msg_new(&google_api_expr_v1alpha1_Expr_msginit, arena);
if (!sub) return NULL;
google_api_expr_v1alpha1_Expr_CreateStruct_Entry_set_value(msg, sub);
}
return sub;
}
/* google.api.expr.v1alpha1.Expr.Comprehension */
UPB_INLINE google_api_expr_v1alpha1_Expr_Comprehension *google_api_expr_v1alpha1_Expr_Comprehension_new(upb_arena *arena) {
return (google_api_expr_v1alpha1_Expr_Comprehension *)upb_msg_new(&google_api_expr_v1alpha1_Expr_Comprehension_msginit, arena);
}
UPB_INLINE google_api_expr_v1alpha1_Expr_Comprehension *google_api_expr_v1alpha1_Expr_Comprehension_parse(const char *buf, size_t size,
upb_arena *arena) {
google_api_expr_v1alpha1_Expr_Comprehension *ret = google_api_expr_v1alpha1_Expr_Comprehension_new(arena);
return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Expr_Comprehension_msginit, arena)) ? ret : NULL;
}
UPB_INLINE char *google_api_expr_v1alpha1_Expr_Comprehension_serialize(const google_api_expr_v1alpha1_Expr_Comprehension *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_api_expr_v1alpha1_Expr_Comprehension_msginit, arena, len);
}
UPB_INLINE upb_strview google_api_expr_v1alpha1_Expr_Comprehension_iter_var(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); }
UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Comprehension_iter_range(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return UPB_FIELD_AT(msg, const google_api_expr_v1alpha1_Expr*, UPB_SIZE(16, 32)); }
UPB_INLINE upb_strview google_api_expr_v1alpha1_Expr_Comprehension_accu_var(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)); }
UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Comprehension_accu_init(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return UPB_FIELD_AT(msg, const google_api_expr_v1alpha1_Expr*, UPB_SIZE(20, 40)); }
UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Comprehension_loop_condition(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return UPB_FIELD_AT(msg, const google_api_expr_v1alpha1_Expr*, UPB_SIZE(24, 48)); }
UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Comprehension_loop_step(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return UPB_FIELD_AT(msg, const google_api_expr_v1alpha1_Expr*, UPB_SIZE(28, 56)); }
UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Comprehension_result(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return UPB_FIELD_AT(msg, const google_api_expr_v1alpha1_Expr*, UPB_SIZE(32, 64)); }
UPB_INLINE void google_api_expr_v1alpha1_Expr_Comprehension_set_iter_var(google_api_expr_v1alpha1_Expr_Comprehension *msg, upb_strview value) {
UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value;
}
UPB_INLINE void google_api_expr_v1alpha1_Expr_Comprehension_set_iter_range(google_api_expr_v1alpha1_Expr_Comprehension *msg, google_api_expr_v1alpha1_Expr* value) {
UPB_FIELD_AT(msg, google_api_expr_v1alpha1_Expr*, UPB_SIZE(16, 32)) = value;
}
UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Comprehension_mutable_iter_range(google_api_expr_v1alpha1_Expr_Comprehension *msg, upb_arena *arena) {
struct google_api_expr_v1alpha1_Expr* sub = (struct google_api_expr_v1alpha1_Expr*)google_api_expr_v1alpha1_Expr_Comprehension_iter_range(msg);
if (sub == NULL) {
sub = (struct google_api_expr_v1alpha1_Expr*)upb_msg_new(&google_api_expr_v1alpha1_Expr_msginit, arena);
if (!sub) return NULL;
google_api_expr_v1alpha1_Expr_Comprehension_set_iter_range(msg, sub);
}
return sub;
}
UPB_INLINE void google_api_expr_v1alpha1_Expr_Comprehension_set_accu_var(google_api_expr_v1alpha1_Expr_Comprehension *msg, upb_strview value) {
UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)) = value;
}
UPB_INLINE void google_api_expr_v1alpha1_Expr_Comprehension_set_accu_init(google_api_expr_v1alpha1_Expr_Comprehension *msg, google_api_expr_v1alpha1_Expr* value) {
UPB_FIELD_AT(msg, google_api_expr_v1alpha1_Expr*, UPB_SIZE(20, 40)) = value;
}
UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Comprehension_mutable_accu_init(google_api_expr_v1alpha1_Expr_Comprehension *msg, upb_arena *arena) {
struct google_api_expr_v1alpha1_Expr* sub = (struct google_api_expr_v1alpha1_Expr*)google_api_expr_v1alpha1_Expr_Comprehension_accu_init(msg);
if (sub == NULL) {
sub = (struct google_api_expr_v1alpha1_Expr*)upb_msg_new(&google_api_expr_v1alpha1_Expr_msginit, arena);
if (!sub) return NULL;
google_api_expr_v1alpha1_Expr_Comprehension_set_accu_init(msg, sub);
}
return sub;
}
UPB_INLINE void google_api_expr_v1alpha1_Expr_Comprehension_set_loop_condition(google_api_expr_v1alpha1_Expr_Comprehension *msg, google_api_expr_v1alpha1_Expr* value) {
UPB_FIELD_AT(msg, google_api_expr_v1alpha1_Expr*, UPB_SIZE(24, 48)) = value;
}
UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Comprehension_mutable_loop_condition(google_api_expr_v1alpha1_Expr_Comprehension *msg, upb_arena *arena) {
struct google_api_expr_v1alpha1_Expr* sub = (struct google_api_expr_v1alpha1_Expr*)google_api_expr_v1alpha1_Expr_Comprehension_loop_condition(msg);
if (sub == NULL) {
sub = (struct google_api_expr_v1alpha1_Expr*)upb_msg_new(&google_api_expr_v1alpha1_Expr_msginit, arena);
if (!sub) return NULL;
google_api_expr_v1alpha1_Expr_Comprehension_set_loop_condition(msg, sub);
}
return sub;
}
UPB_INLINE void google_api_expr_v1alpha1_Expr_Comprehension_set_loop_step(google_api_expr_v1alpha1_Expr_Comprehension *msg, google_api_expr_v1alpha1_Expr* value) {
UPB_FIELD_AT(msg, google_api_expr_v1alpha1_Expr*, UPB_SIZE(28, 56)) = value;
}
UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Comprehension_mutable_loop_step(google_api_expr_v1alpha1_Expr_Comprehension *msg, upb_arena *arena) {
struct google_api_expr_v1alpha1_Expr* sub = (struct google_api_expr_v1alpha1_Expr*)google_api_expr_v1alpha1_Expr_Comprehension_loop_step(msg);
if (sub == NULL) {
sub = (struct google_api_expr_v1alpha1_Expr*)upb_msg_new(&google_api_expr_v1alpha1_Expr_msginit, arena);
if (!sub) return NULL;
google_api_expr_v1alpha1_Expr_Comprehension_set_loop_step(msg, sub);
}
return sub;
}
UPB_INLINE void google_api_expr_v1alpha1_Expr_Comprehension_set_result(google_api_expr_v1alpha1_Expr_Comprehension *msg, google_api_expr_v1alpha1_Expr* value) {
UPB_FIELD_AT(msg, google_api_expr_v1alpha1_Expr*, UPB_SIZE(32, 64)) = value;
}
UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Comprehension_mutable_result(google_api_expr_v1alpha1_Expr_Comprehension *msg, upb_arena *arena) {
struct google_api_expr_v1alpha1_Expr* sub = (struct google_api_expr_v1alpha1_Expr*)google_api_expr_v1alpha1_Expr_Comprehension_result(msg);
if (sub == NULL) {
sub = (struct google_api_expr_v1alpha1_Expr*)upb_msg_new(&google_api_expr_v1alpha1_Expr_msginit, arena);
if (!sub) return NULL;
google_api_expr_v1alpha1_Expr_Comprehension_set_result(msg, sub);
}
return sub;
}
/* google.api.expr.v1alpha1.Constant */
UPB_INLINE google_api_expr_v1alpha1_Constant *google_api_expr_v1alpha1_Constant_new(upb_arena *arena) {
return (google_api_expr_v1alpha1_Constant *)upb_msg_new(&google_api_expr_v1alpha1_Constant_msginit, arena);
}
UPB_INLINE google_api_expr_v1alpha1_Constant *google_api_expr_v1alpha1_Constant_parse(const char *buf, size_t size,
upb_arena *arena) {
google_api_expr_v1alpha1_Constant *ret = google_api_expr_v1alpha1_Constant_new(arena);
return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Constant_msginit, arena)) ? ret : NULL;
}
UPB_INLINE char *google_api_expr_v1alpha1_Constant_serialize(const google_api_expr_v1alpha1_Constant *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_api_expr_v1alpha1_Constant_msginit, arena, len);
}
typedef enum {
google_api_expr_v1alpha1_Constant_constant_kind_null_value = 1,
google_api_expr_v1alpha1_Constant_constant_kind_bool_value = 2,
google_api_expr_v1alpha1_Constant_constant_kind_int64_value = 3,
google_api_expr_v1alpha1_Constant_constant_kind_uint64_value = 4,
google_api_expr_v1alpha1_Constant_constant_kind_double_value = 5,
google_api_expr_v1alpha1_Constant_constant_kind_string_value = 6,
google_api_expr_v1alpha1_Constant_constant_kind_bytes_value = 7,
google_api_expr_v1alpha1_Constant_constant_kind_duration_value = 8,
google_api_expr_v1alpha1_Constant_constant_kind_timestamp_value = 9,
google_api_expr_v1alpha1_Constant_constant_kind_NOT_SET = 0
} google_api_expr_v1alpha1_Constant_constant_kind_oneofcases;
UPB_INLINE google_api_expr_v1alpha1_Constant_constant_kind_oneofcases google_api_expr_v1alpha1_Constant_constant_kind_case(const google_api_expr_v1alpha1_Constant* msg) { return (google_api_expr_v1alpha1_Constant_constant_kind_oneofcases)UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 16)); }
UPB_INLINE bool google_api_expr_v1alpha1_Constant_has_null_value(const google_api_expr_v1alpha1_Constant *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 1); }
UPB_INLINE int32_t google_api_expr_v1alpha1_Constant_null_value(const google_api_expr_v1alpha1_Constant *msg) { return UPB_READ_ONEOF(msg, int32_t, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 1, google_protobuf_NULL_VALUE); }
UPB_INLINE bool google_api_expr_v1alpha1_Constant_has_bool_value(const google_api_expr_v1alpha1_Constant *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 2); }
UPB_INLINE bool google_api_expr_v1alpha1_Constant_bool_value(const google_api_expr_v1alpha1_Constant *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 2, false); }
UPB_INLINE bool google_api_expr_v1alpha1_Constant_has_int64_value(const google_api_expr_v1alpha1_Constant *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 3); }
UPB_INLINE int64_t google_api_expr_v1alpha1_Constant_int64_value(const google_api_expr_v1alpha1_Constant *msg) { return UPB_READ_ONEOF(msg, int64_t, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 3, 0); }
UPB_INLINE bool google_api_expr_v1alpha1_Constant_has_uint64_value(const google_api_expr_v1alpha1_Constant *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 4); }
UPB_INLINE uint64_t google_api_expr_v1alpha1_Constant_uint64_value(const google_api_expr_v1alpha1_Constant *msg) { return UPB_READ_ONEOF(msg, uint64_t, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 4, 0); }
UPB_INLINE bool google_api_expr_v1alpha1_Constant_has_double_value(const google_api_expr_v1alpha1_Constant *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 5); }
UPB_INLINE double google_api_expr_v1alpha1_Constant_double_value(const google_api_expr_v1alpha1_Constant *msg) { return UPB_READ_ONEOF(msg, double, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 5, 0); }
UPB_INLINE bool google_api_expr_v1alpha1_Constant_has_string_value(const google_api_expr_v1alpha1_Constant *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 6); }
UPB_INLINE upb_strview google_api_expr_v1alpha1_Constant_string_value(const google_api_expr_v1alpha1_Constant *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 6, upb_strview_make("", strlen(""))); }
UPB_INLINE bool google_api_expr_v1alpha1_Constant_has_bytes_value(const google_api_expr_v1alpha1_Constant *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 7); }
UPB_INLINE upb_strview google_api_expr_v1alpha1_Constant_bytes_value(const google_api_expr_v1alpha1_Constant *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 7, upb_strview_make("", strlen(""))); }
UPB_INLINE bool google_api_expr_v1alpha1_Constant_has_duration_value(const google_api_expr_v1alpha1_Constant *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 8); }
UPB_INLINE const struct google_protobuf_Duration* google_api_expr_v1alpha1_Constant_duration_value(const google_api_expr_v1alpha1_Constant *msg) { return UPB_READ_ONEOF(msg, const struct google_protobuf_Duration*, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 8, NULL); }
UPB_INLINE bool google_api_expr_v1alpha1_Constant_has_timestamp_value(const google_api_expr_v1alpha1_Constant *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 9); }
UPB_INLINE const struct google_protobuf_Timestamp* google_api_expr_v1alpha1_Constant_timestamp_value(const google_api_expr_v1alpha1_Constant *msg) { return UPB_READ_ONEOF(msg, const struct google_protobuf_Timestamp*, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 9, NULL); }
UPB_INLINE void google_api_expr_v1alpha1_Constant_set_null_value(google_api_expr_v1alpha1_Constant *msg, int32_t value) {
UPB_WRITE_ONEOF(msg, int32_t, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 1);
}
UPB_INLINE void google_api_expr_v1alpha1_Constant_set_bool_value(google_api_expr_v1alpha1_Constant *msg, bool value) {
UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 2);
}
UPB_INLINE void google_api_expr_v1alpha1_Constant_set_int64_value(google_api_expr_v1alpha1_Constant *msg, int64_t value) {
UPB_WRITE_ONEOF(msg, int64_t, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 3);
}
UPB_INLINE void google_api_expr_v1alpha1_Constant_set_uint64_value(google_api_expr_v1alpha1_Constant *msg, uint64_t value) {
UPB_WRITE_ONEOF(msg, uint64_t, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 4);
}
UPB_INLINE void google_api_expr_v1alpha1_Constant_set_double_value(google_api_expr_v1alpha1_Constant *msg, double value) {
UPB_WRITE_ONEOF(msg, double, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 5);
}
UPB_INLINE void google_api_expr_v1alpha1_Constant_set_string_value(google_api_expr_v1alpha1_Constant *msg, upb_strview value) {
UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 6);
}
UPB_INLINE void google_api_expr_v1alpha1_Constant_set_bytes_value(google_api_expr_v1alpha1_Constant *msg, upb_strview value) {
UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 7);
}
UPB_INLINE void google_api_expr_v1alpha1_Constant_set_duration_value(google_api_expr_v1alpha1_Constant *msg, struct google_protobuf_Duration* value) {
UPB_WRITE_ONEOF(msg, struct google_protobuf_Duration*, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 8);
}
UPB_INLINE struct google_protobuf_Duration* google_api_expr_v1alpha1_Constant_mutable_duration_value(google_api_expr_v1alpha1_Constant *msg, upb_arena *arena) {
struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)google_api_expr_v1alpha1_Constant_duration_value(msg);
if (sub == NULL) {
sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena);
if (!sub) return NULL;
google_api_expr_v1alpha1_Constant_set_duration_value(msg, sub);
}
return sub;
}
UPB_INLINE void google_api_expr_v1alpha1_Constant_set_timestamp_value(google_api_expr_v1alpha1_Constant *msg, struct google_protobuf_Timestamp* value) {
UPB_WRITE_ONEOF(msg, struct google_protobuf_Timestamp*, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 9);
}
UPB_INLINE struct google_protobuf_Timestamp* google_api_expr_v1alpha1_Constant_mutable_timestamp_value(google_api_expr_v1alpha1_Constant *msg, upb_arena *arena) {
struct google_protobuf_Timestamp* sub = (struct google_protobuf_Timestamp*)google_api_expr_v1alpha1_Constant_timestamp_value(msg);
if (sub == NULL) {
sub = (struct google_protobuf_Timestamp*)upb_msg_new(&google_protobuf_Timestamp_msginit, arena);
if (!sub) return NULL;
google_api_expr_v1alpha1_Constant_set_timestamp_value(msg, sub);
}
return sub;
}
/* google.api.expr.v1alpha1.SourceInfo */
UPB_INLINE google_api_expr_v1alpha1_SourceInfo *google_api_expr_v1alpha1_SourceInfo_new(upb_arena *arena) {
return (google_api_expr_v1alpha1_SourceInfo *)upb_msg_new(&google_api_expr_v1alpha1_SourceInfo_msginit, arena);
}
UPB_INLINE google_api_expr_v1alpha1_SourceInfo *google_api_expr_v1alpha1_SourceInfo_parse(const char *buf, size_t size,
upb_arena *arena) {
google_api_expr_v1alpha1_SourceInfo *ret = google_api_expr_v1alpha1_SourceInfo_new(arena);
return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_SourceInfo_msginit, arena)) ? ret : NULL;
}
UPB_INLINE char *google_api_expr_v1alpha1_SourceInfo_serialize(const google_api_expr_v1alpha1_SourceInfo *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_api_expr_v1alpha1_SourceInfo_msginit, arena, len);
}
UPB_INLINE upb_strview google_api_expr_v1alpha1_SourceInfo_syntax_version(const google_api_expr_v1alpha1_SourceInfo *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); }
UPB_INLINE upb_strview google_api_expr_v1alpha1_SourceInfo_location(const google_api_expr_v1alpha1_SourceInfo *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)); }
UPB_INLINE int32_t const* google_api_expr_v1alpha1_SourceInfo_line_offsets(const google_api_expr_v1alpha1_SourceInfo *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); }
UPB_INLINE const google_api_expr_v1alpha1_SourceInfo_PositionsEntry* const* google_api_expr_v1alpha1_SourceInfo_positions(const google_api_expr_v1alpha1_SourceInfo *msg, size_t *len) { return (const google_api_expr_v1alpha1_SourceInfo_PositionsEntry* const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); }
UPB_INLINE void google_api_expr_v1alpha1_SourceInfo_set_syntax_version(google_api_expr_v1alpha1_SourceInfo *msg, upb_strview value) {
UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value;
}
UPB_INLINE void google_api_expr_v1alpha1_SourceInfo_set_location(google_api_expr_v1alpha1_SourceInfo *msg, upb_strview value) {
UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)) = value;
}
UPB_INLINE int32_t* google_api_expr_v1alpha1_SourceInfo_mutable_line_offsets(google_api_expr_v1alpha1_SourceInfo *msg, size_t *len) {
return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
}
UPB_INLINE int32_t* google_api_expr_v1alpha1_SourceInfo_resize_line_offsets(google_api_expr_v1alpha1_SourceInfo *msg, size_t len, upb_arena *arena) {
return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena);
}
UPB_INLINE bool google_api_expr_v1alpha1_SourceInfo_add_line_offsets(google_api_expr_v1alpha1_SourceInfo *msg, int32_t val, upb_arena *arena) {
return _upb_array_append_accessor(
msg, UPB_SIZE(16, 32), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena);
}
UPB_INLINE google_api_expr_v1alpha1_SourceInfo_PositionsEntry** google_api_expr_v1alpha1_SourceInfo_mutable_positions(google_api_expr_v1alpha1_SourceInfo *msg, size_t *len) {
return (google_api_expr_v1alpha1_SourceInfo_PositionsEntry**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len);
}
UPB_INLINE google_api_expr_v1alpha1_SourceInfo_PositionsEntry** google_api_expr_v1alpha1_SourceInfo_resize_positions(google_api_expr_v1alpha1_SourceInfo *msg, size_t len, upb_arena *arena) {
return (google_api_expr_v1alpha1_SourceInfo_PositionsEntry**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_api_expr_v1alpha1_SourceInfo_PositionsEntry* google_api_expr_v1alpha1_SourceInfo_add_positions(google_api_expr_v1alpha1_SourceInfo *msg, upb_arena *arena) {
struct google_api_expr_v1alpha1_SourceInfo_PositionsEntry* sub = (struct google_api_expr_v1alpha1_SourceInfo_PositionsEntry*)upb_msg_new(&google_api_expr_v1alpha1_SourceInfo_PositionsEntry_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(20, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
return sub;
}
/* google.api.expr.v1alpha1.SourceInfo.PositionsEntry */
UPB_INLINE google_api_expr_v1alpha1_SourceInfo_PositionsEntry *google_api_expr_v1alpha1_SourceInfo_PositionsEntry_new(upb_arena *arena) {
return (google_api_expr_v1alpha1_SourceInfo_PositionsEntry *)upb_msg_new(&google_api_expr_v1alpha1_SourceInfo_PositionsEntry_msginit, arena);
}
UPB_INLINE google_api_expr_v1alpha1_SourceInfo_PositionsEntry *google_api_expr_v1alpha1_SourceInfo_PositionsEntry_parse(const char *buf, size_t size,
upb_arena *arena) {
google_api_expr_v1alpha1_SourceInfo_PositionsEntry *ret = google_api_expr_v1alpha1_SourceInfo_PositionsEntry_new(arena);
return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_SourceInfo_PositionsEntry_msginit, arena)) ? ret : NULL;
}
UPB_INLINE char *google_api_expr_v1alpha1_SourceInfo_PositionsEntry_serialize(const google_api_expr_v1alpha1_SourceInfo_PositionsEntry *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_api_expr_v1alpha1_SourceInfo_PositionsEntry_msginit, arena, len);
}
UPB_INLINE int64_t google_api_expr_v1alpha1_SourceInfo_PositionsEntry_key(const google_api_expr_v1alpha1_SourceInfo_PositionsEntry *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)); }
UPB_INLINE int32_t google_api_expr_v1alpha1_SourceInfo_PositionsEntry_value(const google_api_expr_v1alpha1_SourceInfo_PositionsEntry *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); }
UPB_INLINE void google_api_expr_v1alpha1_SourceInfo_PositionsEntry_set_key(google_api_expr_v1alpha1_SourceInfo_PositionsEntry *msg, int64_t value) {
UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)) = value;
}
UPB_INLINE void google_api_expr_v1alpha1_SourceInfo_PositionsEntry_set_value(google_api_expr_v1alpha1_SourceInfo_PositionsEntry *msg, int32_t value) {
UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value;
}
/* google.api.expr.v1alpha1.SourcePosition */
UPB_INLINE google_api_expr_v1alpha1_SourcePosition *google_api_expr_v1alpha1_SourcePosition_new(upb_arena *arena) {
return (google_api_expr_v1alpha1_SourcePosition *)upb_msg_new(&google_api_expr_v1alpha1_SourcePosition_msginit, arena);
}
UPB_INLINE google_api_expr_v1alpha1_SourcePosition *google_api_expr_v1alpha1_SourcePosition_parse(const char *buf, size_t size,
upb_arena *arena) {
google_api_expr_v1alpha1_SourcePosition *ret = google_api_expr_v1alpha1_SourcePosition_new(arena);
return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_SourcePosition_msginit, arena)) ? ret : NULL;
}
UPB_INLINE char *google_api_expr_v1alpha1_SourcePosition_serialize(const google_api_expr_v1alpha1_SourcePosition *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &google_api_expr_v1alpha1_SourcePosition_msginit, arena, len);
}
UPB_INLINE upb_strview google_api_expr_v1alpha1_SourcePosition_location(const google_api_expr_v1alpha1_SourcePosition *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 16)); }
UPB_INLINE int32_t google_api_expr_v1alpha1_SourcePosition_offset(const google_api_expr_v1alpha1_SourcePosition *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)); }
UPB_INLINE int32_t google_api_expr_v1alpha1_SourcePosition_line(const google_api_expr_v1alpha1_SourcePosition *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); }
UPB_INLINE int32_t google_api_expr_v1alpha1_SourcePosition_column(const google_api_expr_v1alpha1_SourcePosition *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); }
UPB_INLINE void google_api_expr_v1alpha1_SourcePosition_set_location(google_api_expr_v1alpha1_SourcePosition *msg, upb_strview value) {
UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 16)) = value;
}
UPB_INLINE void google_api_expr_v1alpha1_SourcePosition_set_offset(google_api_expr_v1alpha1_SourcePosition *msg, int32_t value) {
UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)) = value;
}
UPB_INLINE void google_api_expr_v1alpha1_SourcePosition_set_line(google_api_expr_v1alpha1_SourcePosition *msg, int32_t value) {
UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value;
}
UPB_INLINE void google_api_expr_v1alpha1_SourcePosition_set_column(google_api_expr_v1alpha1_SourcePosition *msg, int32_t value) {
UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value;
}
#ifdef __cplusplus
} /* extern "C" */
#endif
#include "upb/port_undef.inc"
#endif /* GOOGLE_API_EXPR_V1ALPHA1_SYNTAX_PROTO_UPB_H_ */

@ -33,19 +33,6 @@
#endif
#if defined(GRPC_CUSTOM_SOCKET)
// Do Nothing
#elif defined(GPR_MANYLINUX1)
#define GRPC_HAVE_ARPA_NAMESER 1
#define GRPC_HAVE_IFADDRS 1
#define GRPC_HAVE_IPV6_RECVPKTINFO 1
#define GRPC_HAVE_IP_PKTINFO 1
#define GRPC_HAVE_MSG_NOSIGNAL 1
#define GRPC_HAVE_UNIX_SOCKET 1
#define GRPC_POSIX_FORK 1
#define GRPC_POSIX_NO_SPECIAL_WAKEUP_FD 1
#define GRPC_POSIX_SOCKET 1
#define GRPC_POSIX_SOCKETUTILS 1
#define GRPC_POSIX_WAKEUP_FD 1
#define GRPC_LINUX_EPOLL 1
#elif defined(GPR_WINDOWS)
#define GRPC_WINSOCK_SOCKET 1
#define GRPC_WINDOWS_SOCKETUTILS 1

@ -320,9 +320,9 @@ static bool rq_alloc(grpc_resource_quota* resource_quota) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) {
gpr_log(GPR_INFO,
"RQ: check allocation for user %p shutdown=%" PRIdPTR
" free_pool=%" PRId64,
" free_pool=%" PRId64 " outstanding_allocations=%" PRId64,
resource_user, gpr_atm_no_barrier_load(&resource_user->shutdown),
resource_user->free_pool);
resource_user->free_pool, resource_user->outstanding_allocations);
}
if (gpr_atm_no_barrier_load(&resource_user->shutdown)) {
resource_user->allocating = false;
@ -334,7 +334,9 @@ static bool rq_alloc(grpc_resource_quota* resource_quota) {
resource_user->free_pool += aborted_allocations;
grpc_core::ExecCtx::RunList(DEBUG_LOCATION, &resource_user->on_allocated);
gpr_mu_unlock(&resource_user->mu);
ru_unref_by(resource_user, static_cast<gpr_atm>(aborted_allocations));
if (aborted_allocations > 0) {
ru_unref_by(resource_user, static_cast<gpr_atm>(aborted_allocations));
}
continue;
}
if (resource_user->free_pool < 0 &&

@ -46,6 +46,8 @@ grpc_server_security_connector::grpc_server_security_connector(
: grpc_security_connector(url_scheme),
server_creds_(std::move(server_creds)) {}
grpc_server_security_connector::~grpc_server_security_connector() = default;
grpc_channel_security_connector::grpc_channel_security_connector(
const char* url_scheme,
grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,

@ -151,7 +151,7 @@ class grpc_server_security_connector : public grpc_security_connector {
grpc_server_security_connector(
const char* url_scheme,
grpc_core::RefCountedPtr<grpc_server_credentials> server_creds);
~grpc_server_security_connector() override = default;
~grpc_server_security_connector() override;
virtual void add_handshakers(const grpc_channel_args* args,
grpc_pollset_set* interested_parties,

@ -225,7 +225,9 @@ struct grpc_call {
grpc_closure receiving_initial_metadata_ready;
grpc_closure receiving_trailing_metadata_ready;
uint32_t test_only_last_message_flags = 0;
gpr_atm cancelled = 0;
// Status about operation of call
bool sent_server_trailing_metadata = false;
gpr_atm cancelled_with_error = 0;
grpc_closure release_call;
@ -686,7 +688,7 @@ static void done_termination(void* arg, grpc_error* /*error*/) {
}
static void cancel_with_error(grpc_call* c, grpc_error* error) {
if (!gpr_atm_rel_cas(&c->cancelled, 0, 1)) {
if (!gpr_atm_rel_cas(&c->cancelled_with_error, 0, 1)) {
GRPC_ERROR_UNREF(error);
return;
}
@ -751,13 +753,13 @@ static void set_final_status(grpc_call* call, grpc_error* error) {
}
} else {
*call->final_op.server.cancelled =
error != GRPC_ERROR_NONE ||
reinterpret_cast<grpc_error*>(gpr_atm_acq_load(&call->status_error)) !=
GRPC_ERROR_NONE;
error != GRPC_ERROR_NONE || !call->sent_server_trailing_metadata;
grpc_core::channelz::ServerNode* channelz_server =
grpc_server_get_channelz_node(call->final_op.server.server);
if (channelz_server != nullptr) {
if (*call->final_op.server.cancelled) {
if (*call->final_op.server.cancelled ||
reinterpret_cast<grpc_error*>(
gpr_atm_acq_load(&call->status_error)) != GRPC_ERROR_NONE) {
channelz_server->RecordCallFailed();
} else {
channelz_server->RecordCallSucceeded();
@ -1791,6 +1793,8 @@ static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops,
}
stream_op_payload->send_trailing_metadata.send_trailing_metadata =
&call->metadata_batch[0 /* is_receiving */][1 /* is_trailing */];
stream_op_payload->send_trailing_metadata.sent =
&call->sent_server_trailing_metadata;
has_send_ops = true;
break;
}

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

Loading…
Cancel
Save