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. 40
      doc/grpc_xds_features.md
  17. 1
      doc/health-checking.md
  18. 4
      doc/python/sphinx/grpc.rst
  19. 44
      doc/xds-test-descriptions.md
  20. 4
      examples/cpp/README.md
  21. 2
      examples/cpp/helloworld/README.md
  22. 2
      examples/cpp/route_guide/README.md
  23. 2
      examples/csharp/Helloworld/README.md
  24. 2
      examples/csharp/HelloworldLegacyCsproj/README.md
  25. 2
      examples/csharp/RouteGuide/README.md
  26. 2
      examples/node/README.md
  27. 2
      examples/node/dynamic_codegen/route_guide/README.md
  28. 2
      examples/node/static_codegen/route_guide/README.md
  29. 2
      examples/objective-c/auth_sample/README.md
  30. 2
      examples/objective-c/helloworld/README.md
  31. 2
      examples/objective-c/route_guide/README.md
  32. 2
      examples/php/README.md
  33. 2
      examples/php/route_guide/README.md
  34. 2
      examples/python/README.md
  35. 2
      examples/python/helloworld/README.md
  36. 2
      examples/python/metadata/README.md
  37. 2
      examples/python/multiplex/README.md
  38. 2
      examples/python/route_guide/README.md
  39. 2
      examples/ruby/README.md
  40. 2
      examples/ruby/route_guide/README.md
  41. 3
      gRPC-C++.podspec
  42. 4
      gRPC-Core.podspec
  43. 3
      grpc.gemspec
  44. 6
      grpc.gyp
  45. 6
      include/grpc/impl/codegen/grpc_types.h
  46. 25
      include/grpc/impl/codegen/port_platform.h
  47. 545
      include/grpcpp/impl/codegen/client_callback_impl.h
  48. 18
      include/grpcpp/impl/codegen/server_context_impl.h
  49. 3
      package.xml
  50. 4
      requirements.bazel.txt
  51. 2
      requirements.txt
  52. 4
      setup.py
  53. 5
      src/compiler/objective_c_plugin.cc
  54. 588
      src/core/ext/filters/client_channel/client_channel.cc
  55. 62
      src/core/ext/filters/client_channel/config_selector.cc
  56. 91
      src/core/ext/filters/client_channel/config_selector.h
  57. 61
      src/core/ext/filters/client_channel/resolving_lb_policy.cc
  58. 57
      src/core/ext/filters/client_channel/resolving_lb_policy.h
  59. 142
      src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc
  60. 7
      src/core/ext/filters/client_channel/xds/xds_api.cc
  61. 3
      src/core/ext/filters/http/http_filters_plugin.cc
  62. 92
      src/core/ext/filters/http/message_compress/message_decompress_filter.cc
  63. 4
      src/core/ext/filters/http/message_compress/message_decompress_filter.h
  64. 106
      src/core/ext/filters/message_size/message_size_filter.cc
  65. 6
      src/core/ext/filters/message_size/message_size_filter.h
  66. 724
      src/core/ext/transport/chttp2/server/chttp2_server.cc
  67. 8
      src/core/ext/transport/chttp2/server/chttp2_server.h
  68. 2
      src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc
  69. 2
      src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc
  70. 3
      src/core/ext/transport/chttp2/transport/chttp2_transport.cc
  71. 7
      src/core/ext/transport/chttp2/transport/internal.h
  72. 4
      src/core/ext/transport/chttp2/transport/writing.cc
  73. 43
      src/core/ext/transport/cronet/transport/cronet_transport.cc
  74. 3
      src/core/ext/transport/inproc/inproc_transport.cc
  75. 173
      src/core/ext/upb-generated/envoy/config/rbac/v2/rbac.upb.c
  76. 615
      src/core/ext/upb-generated/envoy/config/rbac/v2/rbac.upb.h
  77. 33
      src/core/ext/upb-generated/envoy/type/matcher/path.upb.c
  78. 72
      src/core/ext/upb-generated/envoy/type/matcher/path.upb.h
  79. 234
      src/core/ext/upb-generated/google/api/expr/v1alpha1/syntax.upb.c
  80. 760
      src/core/ext/upb-generated/google/api/expr/v1alpha1/syntax.upb.h
  81. 13
      src/core/lib/iomgr/port.h
  82. 8
      src/core/lib/iomgr/resource_quota.cc
  83. 2
      src/core/lib/security/security_connector/security_connector.cc
  84. 2
      src/core/lib/security/security_connector/security_connector.h
  85. 16
      src/core/lib/surface/call.cc
  86. 149
      src/core/lib/surface/server.cc
  87. 35
      src/core/lib/surface/server.h
  88. 2
      src/core/lib/surface/version.cc
  89. 6
      src/core/lib/transport/transport.h
  90. 4
      src/core/plugin_registry/grpc_plugin_registry.cc
  91. 4
      src/core/plugin_registry/grpc_unsecure_plugin_registry.cc
  92. 4
      src/cpp/README.md
  93. 52
      src/cpp/client/client_callback.cc
  94. 55
      src/cpp/server/server_context.cc
  95. 47
      src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj
  96. 71
      src/csharp/Grpc.Tools.Tests/MsBuildAssemblyHelper.cs
  97. 9
      src/csharp/Grpc.Tools.Tests/NUnitMain.cs
  98. 15
      src/csharp/Grpc.Tools/Grpc.Tools.csproj
  99. 2
      src/csharp/README.md
  100. 7
      src/objective-c/BUILD
  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)

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

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

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

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

@ -24,12 +24,14 @@
#include <stdlib.h>
#include <string.h>
#include <list>
#include <utility>
#include <vector>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <utility>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channelz.h"
#include "src/core/lib/channel/connected_channel.h"
@ -57,13 +59,12 @@ namespace {
void server_on_recv_initial_metadata(void* ptr, grpc_error* error);
void server_recv_trailing_metadata_ready(void* user_data, grpc_error* error);
struct listener {
void* arg;
void (*start)(grpc_server* server, void* arg, grpc_pollset** pollsets,
size_t pollset_count);
void (*destroy)(grpc_server* server, void* arg, grpc_closure* closure);
struct listener* next;
intptr_t socket_uuid;
struct Listener {
explicit Listener(
grpc_core::OrphanablePtr<grpc_core::ServerListenerInterface> l)
: listener(std::move(l)) {}
grpc_core::OrphanablePtr<grpc_core::ServerListenerInterface> listener;
grpc_closure destroy_done;
};
@ -297,15 +298,15 @@ struct channel_broadcaster {
} // namespace
struct grpc_server {
grpc_channel_args* channel_args;
grpc_channel_args* channel_args = nullptr;
grpc_resource_user* default_resource_user;
grpc_resource_user* default_resource_user = nullptr;
grpc_completion_queue** cqs;
grpc_pollset** pollsets;
size_t cq_count;
size_t pollset_count;
bool started;
grpc_completion_queue** cqs = nullptr;
grpc_pollset** pollsets = nullptr;
size_t cq_count = 0;
size_t pollset_count = 0;
bool started = false;
/* The two following mutexes control access to server-state
mu_global controls access to non-call-related state (e.g., channel state)
@ -319,26 +320,26 @@ struct grpc_server {
/* startup synchronization: flag is protected by mu_global, signals whether
we are doing the listener start routine or not */
bool starting;
bool starting = false;
gpr_cv starting_cv;
// TODO(vjpai): Convert from a linked-list head pointer to a std::vector once
// grpc_server has a real constructor/destructor
registered_method* registered_methods;
registered_method* registered_methods = nullptr;
/** one request matcher for unregistered methods */
// TODO(vjpai): Convert to a std::unique_ptr once grpc_server has a real
// constructor and destructor.
RequestMatcherInterface* unregistered_request_matcher;
RequestMatcherInterface* unregistered_request_matcher = nullptr;
gpr_atm shutdown_flag;
uint8_t shutdown_published;
size_t num_shutdown_tags;
shutdown_tag* shutdown_tags;
gpr_atm shutdown_flag = 0;
uint8_t shutdown_published = 0;
size_t num_shutdown_tags = 0;
shutdown_tag* shutdown_tags = nullptr;
channel_data root_channel_data;
listener* listeners;
int listeners_destroyed;
std::list<Listener> listeners;
int listeners_destroyed = 0;
grpc_core::RefCount internal_refcount;
/** when did we print the last shutdown progress message */
@ -675,7 +676,6 @@ void server_ref(grpc_server* server) { server->internal_refcount.Ref(); }
void server_delete(grpc_server* server) {
registered_method* rm;
size_t i;
server->channelz_server.reset();
grpc_channel_args_destroy(server->channel_args);
gpr_mu_destroy(&server->mu_global);
gpr_mu_destroy(&server->mu_call);
@ -691,7 +691,7 @@ void server_delete(grpc_server* server) {
gpr_free(server->cqs);
gpr_free(server->pollsets);
gpr_free(server->shutdown_tags);
gpr_free(server);
delete server;
}
void server_unref(grpc_server* server) {
@ -881,15 +881,6 @@ void start_new_rpc(grpc_call_element* elem) {
GRPC_SRM_PAYLOAD_NONE);
}
int num_listeners(grpc_server* server) {
listener* l;
int n = 0;
for (l = server->listeners; l; l = l->next) {
n++;
}
return n;
}
void done_shutdown_event(void* server, grpc_cq_completion* /*completion*/) {
server_unref(static_cast<grpc_server*>(server));
}
@ -929,17 +920,17 @@ void maybe_finish_shutdown(grpc_server* server) {
gpr_mu_unlock(&server->mu_call);
if (server->root_channel_data.next != &server->root_channel_data ||
server->listeners_destroyed < num_listeners(server)) {
server->listeners_destroyed < server->listeners.size()) {
if (gpr_time_cmp(gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME),
server->last_shutdown_message_time),
gpr_time_from_seconds(1, GPR_TIMESPAN)) >= 0) {
server->last_shutdown_message_time = gpr_now(GPR_CLOCK_REALTIME);
gpr_log(GPR_DEBUG,
"Waiting for %d channels and %d/%d listeners to be destroyed"
" before shutting down server",
"Waiting for %d channels and %" PRIuPTR "/%" PRIuPTR
" listeners to be destroyed before shutting down server",
num_channels(server),
num_listeners(server) - server->listeners_destroyed,
num_listeners(server));
server->listeners.size() - server->listeners_destroyed,
server->listeners.size());
}
return;
}
@ -1312,26 +1303,21 @@ grpc_server* grpc_server_create(const grpc_channel_args* args, void* reserved) {
grpc_core::ExecCtx exec_ctx;
GRPC_API_TRACE("grpc_server_create(%p, %p)", 2, (args, reserved));
grpc_server* server =
static_cast<grpc_server*>(gpr_zalloc(sizeof(grpc_server)));
grpc_server* server = new grpc_server;
gpr_mu_init(&server->mu_global);
gpr_mu_init(&server->mu_call);
gpr_cv_init(&server->starting_cv);
/* decremented by grpc_server_destroy */
new (&server->internal_refcount) grpc_core::RefCount();
server->root_channel_data.next = server->root_channel_data.prev =
&server->root_channel_data;
server->channel_args = grpc_channel_args_copy(args);
const grpc_arg* arg = grpc_channel_args_find(args, GRPC_ARG_ENABLE_CHANNELZ);
if (grpc_channel_arg_get_bool(arg, GRPC_ENABLE_CHANNELZ_DEFAULT)) {
arg = grpc_channel_args_find(
args, GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE);
size_t channel_tracer_max_memory = grpc_channel_arg_get_integer(
arg,
if (grpc_channel_args_find_bool(args, GRPC_ARG_ENABLE_CHANNELZ,
GRPC_ENABLE_CHANNELZ_DEFAULT)) {
size_t channel_tracer_max_memory = grpc_channel_args_find_integer(
args, GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE,
{GRPC_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE_DEFAULT, 0, INT_MAX});
server->channelz_server =
grpc_core::MakeRefCounted<grpc_core::channelz::ServerNode>(
@ -1414,8 +1400,8 @@ void grpc_server_start(grpc_server* server) {
server->starting = true;
gpr_mu_unlock(&server->mu_global);
for (listener* l = server->listeners; l; l = l->next) {
l->start(server, l->arg, server->pollsets, server->pollset_count);
for (auto& listener : server->listeners) {
listener.listener->Start(server, server->pollsets, server->pollset_count);
}
gpr_mu_lock(&server->mu_global);
@ -1547,7 +1533,6 @@ void grpc_server_setup_transport(
*/
void grpc_server_shutdown_and_notify(grpc_server* server,
grpc_completion_queue* cq, void* tag) {
listener* l;
shutdown_tag* sdt;
channel_broadcaster broadcaster;
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
@ -1599,13 +1584,18 @@ void grpc_server_shutdown_and_notify(grpc_server* server,
gpr_mu_unlock(&server->mu_global);
/* Shutdown listeners */
for (l = server->listeners; l; l = l->next) {
GRPC_CLOSURE_INIT(&l->destroy_done, listener_destroy_done, server,
grpc_schedule_on_exec_ctx);
l->destroy(server, l->arg, &l->destroy_done);
if (server->channelz_server != nullptr && l->socket_uuid != 0) {
server->channelz_server->RemoveChildListenSocket(l->socket_uuid);
for (auto& listener : server->listeners) {
grpc_core::channelz::ListenSocketNode* channelz_listen_socket_node =
listener.listener->channelz_listen_socket_node();
if (server->channelz_server != nullptr &&
channelz_listen_socket_node != nullptr) {
server->channelz_server->RemoveChildListenSocket(
channelz_listen_socket_node->uuid());
}
GRPC_CLOSURE_INIT(&listener.destroy_done, listener_destroy_done, server,
grpc_schedule_on_exec_ctx);
listener.listener->SetOnDestroyDone(&listener.destroy_done);
listener.listener.reset();
}
channel_broadcaster_shutdown(&broadcaster, true /* send_goaway */,
@ -1636,46 +1626,29 @@ void grpc_server_cancel_all_calls(grpc_server* server) {
}
void grpc_server_destroy(grpc_server* server) {
listener* l;
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
grpc_core::ExecCtx exec_ctx;
GRPC_API_TRACE("grpc_server_destroy(server=%p)", 1, (server));
gpr_mu_lock(&server->mu_global);
GPR_ASSERT(gpr_atm_acq_load(&server->shutdown_flag) || !server->listeners);
GPR_ASSERT(server->listeners_destroyed == num_listeners(server));
while (server->listeners) {
l = server->listeners;
server->listeners = l->next;
gpr_free(l);
}
GPR_ASSERT(gpr_atm_acq_load(&server->shutdown_flag) ||
server->listeners.empty());
GPR_ASSERT(server->listeners_destroyed == server->listeners.size());
gpr_mu_unlock(&server->mu_global);
server_unref(server);
}
void grpc_server_add_listener(
grpc_server* server, void* listener_arg,
void (*start)(grpc_server* server, void* arg, grpc_pollset** pollsets,
size_t pollset_count),
void (*destroy)(grpc_server* server, void* arg, grpc_closure* on_done),
grpc_core::RefCountedPtr<grpc_core::channelz::ListenSocketNode> node) {
listener* l = static_cast<listener*>(gpr_malloc(sizeof(listener)));
l->arg = listener_arg;
l->start = start;
l->destroy = destroy;
l->socket_uuid = 0;
if (node != nullptr) {
l->socket_uuid = node->uuid();
if (server->channelz_server != nullptr) {
server->channelz_server->AddChildListenSocket(std::move(node));
}
}
l->next = server->listeners;
server->listeners = l;
grpc_server* server,
grpc_core::OrphanablePtr<grpc_core::ServerListenerInterface> listener) {
grpc_core::channelz::ListenSocketNode* listen_socket_node =
listener->channelz_listen_socket_node();
if (listen_socket_node != nullptr && server->channelz_server != nullptr) {
server->channelz_server->AddChildListenSocket(listen_socket_node->Ref());
}
server->listeners.emplace_back(std::move(listener));
}
namespace {

@ -32,14 +32,35 @@ extern const grpc_channel_filter grpc_server_top_filter;
/** Lightweight tracing of server channel state */
extern grpc_core::TraceFlag grpc_server_channel_trace;
/* Add a listener to the server: when the server starts, it will call start,
and when it shuts down, it will call destroy */
namespace grpc_core {
/// Interface for listeners.
/// Implementations must override the Orphan() method, which should stop
/// listening and initiate destruction of the listener.
class ServerListenerInterface : public Orphanable {
public:
virtual ~ServerListenerInterface() = default;
/// Starts listening.
virtual void Start(grpc_server* server, grpc_pollset** pollsets,
size_t npollsets) = 0;
/// Returns the channelz node for the listen socket, or null if not
/// supported.
virtual channelz::ListenSocketNode* channelz_listen_socket_node() const = 0;
/// Sets a closure to be invoked by the listener when its destruction
/// is complete.
virtual void SetOnDestroyDone(grpc_closure* on_destroy_done) = 0;
};
} // namespace grpc_core
/* Add a listener to the server: when the server starts, it will call Start(),
and when it shuts down, it will orphan the listener. */
void grpc_server_add_listener(
grpc_server* server, void* listener_arg,
void (*start)(grpc_server* server, void* arg, grpc_pollset** pollsets,
size_t npollsets),
void (*destroy)(grpc_server* server, void* arg, grpc_closure* on_done),
grpc_core::RefCountedPtr<grpc_core::channelz::ListenSocketNode> node);
grpc_server* server,
grpc_core::OrphanablePtr<grpc_core::ServerListenerInterface> listener);
/* Setup a transport - creates a channel stack, binds the transport to the
server */

@ -23,6 +23,6 @@
#include <grpc/grpc.h>
const char* grpc_version_string(void) { return "10.0.0"; }
const char* grpc_version_string(void) { return "11.0.0"; }
const char* grpc_g_stands_for(void) { return "galore"; }

@ -242,6 +242,12 @@ struct grpc_transport_stream_op_batch_payload {
struct {
grpc_metadata_batch* send_trailing_metadata = nullptr;
// Set by the transport to true if the stream successfully wrote the
// trailing metadata. If this is not set but there was a send trailing
// metadata op present, this can indicate that a server call can be marked
// as a cancellation (since the stream was write-closed before status could
// be delivered).
bool* sent = nullptr;
} send_trailing_metadata;
struct {

@ -64,6 +64,8 @@ void grpc_max_age_filter_init(void);
void grpc_max_age_filter_shutdown(void);
void grpc_message_size_filter_init(void);
void grpc_message_size_filter_shutdown(void);
void grpc_service_config_channel_arg_filter_init(void);
void grpc_service_config_channel_arg_filter_shutdown(void);
void grpc_client_authority_filter_init(void);
void grpc_client_authority_filter_shutdown(void);
void grpc_workaround_cronet_compression_filter_init(void);
@ -114,6 +116,8 @@ void grpc_register_built_in_plugins(void) {
grpc_max_age_filter_shutdown);
grpc_register_plugin(grpc_message_size_filter_init,
grpc_message_size_filter_shutdown);
grpc_register_plugin(grpc_service_config_channel_arg_filter_init,
grpc_service_config_channel_arg_filter_shutdown);
grpc_register_plugin(grpc_client_authority_filter_init,
grpc_client_authority_filter_shutdown);
grpc_register_plugin(grpc_workaround_cronet_compression_filter_init,

@ -64,6 +64,8 @@ void grpc_max_age_filter_init(void);
void grpc_max_age_filter_shutdown(void);
void grpc_message_size_filter_init(void);
void grpc_message_size_filter_shutdown(void);
void grpc_service_config_channel_arg_filter_init(void);
void grpc_service_config_channel_arg_filter_shutdown(void);
void grpc_client_authority_filter_init(void);
void grpc_client_authority_filter_shutdown(void);
void grpc_workaround_cronet_compression_filter_init(void);
@ -114,6 +116,8 @@ void grpc_register_built_in_plugins(void) {
grpc_max_age_filter_shutdown);
grpc_register_plugin(grpc_message_size_filter_init,
grpc_message_size_filter_shutdown);
grpc_register_plugin(grpc_service_config_channel_arg_filter_init,
grpc_service_config_channel_arg_filter_shutdown);
grpc_register_plugin(grpc_client_authority_filter_init,
grpc_client_authority_filter_shutdown);
grpc_register_plugin(grpc_workaround_cronet_compression_filter_init,

@ -167,10 +167,10 @@ documentation site at [grpc.io](https://grpc.io), specifically:
* [Overview](https://grpc.io/docs): An introduction to gRPC with a simple
Hello World example in all our supported languages, including C++.
* [gRPC Basics - C++](https://grpc.io/docs/tutorials/basic/cpp):
* [gRPC Basics - C++](https://grpc.io/docs/languages/cpp/basics):
A tutorial that steps you through creating a simple gRPC C++ example
application.
* [Asynchronous Basics - C++](https://grpc.io/docs/tutorials/async/helloasync-cpp):
* [Asynchronous Basics - C++](https://grpc.io/docs/languages/cpp/async):
A tutorial that shows you how to use gRPC C++'s asynchronous/non-blocking
APIs.

@ -0,0 +1,52 @@
/*
* Copyright 2019 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 <grpcpp/impl/codegen/client_callback_impl.h>
#include "src/core/lib/iomgr/closure.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/executor.h"
namespace grpc_impl {
namespace internal {
void ClientReactor::InternalScheduleOnDone(grpc::Status s) {
// Unlike other uses of closure, do not Ref or Unref here since the reactor
// object's lifetime is controlled by user code.
grpc_core::ExecCtx exec_ctx;
struct ClosureWithArg {
grpc_closure closure;
ClientReactor* const reactor;
const grpc::Status status;
ClosureWithArg(ClientReactor* reactor_arg, grpc::Status s)
: reactor(reactor_arg), status(std::move(s)) {
GRPC_CLOSURE_INIT(&closure,
[](void* void_arg, grpc_error*) {
ClosureWithArg* arg =
static_cast<ClosureWithArg*>(void_arg);
arg->reactor->OnDone(arg->status);
delete arg;
},
this, grpc_schedule_on_exec_ctx);
}
};
ClosureWithArg* arg = new ClosureWithArg(this, std::move(s));
grpc_core::Executor::Run(&arg->closure, GRPC_ERROR_NONE);
}
} // namespace internal
} // namespace grpc_impl

@ -174,31 +174,32 @@ void ServerContextBase::CompletionOp::FillOps(::grpc::internal::Call* call) {
}
bool ServerContextBase::CompletionOp::FinalizeResult(void** tag, bool* status) {
bool ret = false;
grpc_core::ReleasableMutexLock lock(&mu_);
if (done_intercepting_) {
/* We are done intercepting. */
if (has_tag_) {
*tag = tag_;
ret = true;
}
Unref();
return ret;
}
finalized_ = true;
// Decide whether to call the cancel callback within the lock
bool call_cancel;
// If for some reason the incoming status is false, mark that as a
// cancellation.
// TODO(vjpai): does this ever happen?
if (!*status) {
cancelled_ = 1;
}
{
grpc_core::MutexLock lock(&mu_);
if (done_intercepting_) {
// We are done intercepting.
bool has_tag = has_tag_;
if (has_tag) {
*tag = tag_;
}
Unref();
return has_tag;
}
finalized_ = true;
// Decide whether to call the cancel callback before releasing the lock
bool call_cancel = (cancelled_ != 0);
// If for some reason the incoming status is false, mark that as a
// cancellation.
// TODO(vjpai): does this ever happen?
if (!*status) {
cancelled_ = 1;
}
// Release the lock since we may call a callback and interceptors now.
lock.Unlock();
call_cancel = (cancelled_ != 0);
// Release the lock since we may call a callback and interceptors.
}
if (call_cancel && callback_controller_ != nullptr) {
callback_controller_->MaybeCallOnCancel();
@ -207,15 +208,15 @@ bool ServerContextBase::CompletionOp::FinalizeResult(void** tag, bool* status) {
interceptor_methods_.AddInterceptionHookPoint(
::grpc::experimental::InterceptionHookPoints::POST_RECV_CLOSE);
if (interceptor_methods_.RunInterceptors()) {
/* No interceptors were run */
if (has_tag_) {
// No interceptors were run
bool has_tag = has_tag_;
if (has_tag) {
*tag = tag_;
ret = true;
}
Unref();
return ret;
return has_tag;
}
/* There are interceptors to be run. Return false for now */
// There are interceptors to be run. Return false for now.
return false;
}

@ -7,14 +7,13 @@
<Import Project="..\Grpc.Core\SourceLink.csproj.include" />
<PropertyGroup Condition=" '$(OS)' != 'Windows_NT' and '$(MSBuildRuntimeType)' == 'Core' ">
<!-- Use Mono reference assemblies in SDK build: https://github.com/dotnet/sdk/issues/335.
This is a different approach than used in Grpc.Core/Common.csproj.include because
the workaround used there doesn't seem to be working for Microsoft.Build.* assemblies -->
<FrameworkPathOverride Condition="Exists('/usr/lib/mono/4.5-api')">/usr/lib/mono/4.5-api</FrameworkPathOverride>
<FrameworkPathOverride Condition="Exists('/usr/local/lib/mono/4.5-api')">/usr/local/lib/mono/4.5-api</FrameworkPathOverride>
<FrameworkPathOverride Condition="Exists('/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5-api')">/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5-api</FrameworkPathOverride>
</PropertyGroup>
<!-- Needed for the net45 build to work on Unix. See https://github.com/dotnet/designs/pull/33 -->
<ItemGroup>
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Grpc.Tools\Grpc.Tools.csproj" />
@ -38,36 +37,4 @@
<PackageReference Include="Microsoft.Build.Framework; Microsoft.Build.Utilities.Core" Version="15.6.*" />
</ItemGroup>
<!-- Groups below is a hack to allow the test to run under Mono Framework build.
========================================================================== -->
<!-- Mono unfortunately comes with broken Microsoft.Build.* assemblies installed in
the GAC, but fortunately searches for runtime assemblies in a different order
than Windows CLR host: the GAC assemblies have the lowest search priority, (see
https://www.mono-project.com/docs/advanced/assemblies-and-the-gac/), not the
highest as is in Windows (documented at
https://docs.microsoft.com/dotnet/framework/deployment/how-the-runtime-locates-assemblies).
To run the tests under Mono, we need correct assemblies in the same directory as
the test executable. Correct versions are in the MSBuild directory under Mono. -->
<ItemGroup Condition=" '$(TargetFramework)' == 'net45' and '$(OS)' != 'Windows_NT' ">
<None Include="$(_MSBuildAssemblyPath)/Microsoft.Build.Framework.dll;
$(_MSBuildAssemblyPath)/Microsoft.Build.Utilities.v4.0.dll;
$(_MSBuildAssemblyPath)/Microsoft.Build.Utilities.Core.dll"
CopyToOutputDirectory="Always" Visible="false" />
</ItemGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net45' and '$(OS)' != 'Windows_NT' ">
<!-- The None items are included into assembly candidate resolution by default, and
we do not want that, as they are not valid as reference assemblies (the version of
Microsoft.Build.Utilities.v4.0 is a pure facade for Microsoft.Build.Utilities.Core,
and does not define any types at all). Exclude them from assembly resolution. See
https://github.com/Microsoft/msbuild/blob/50639058f/documentation/wiki/ResolveAssemblyReference.md -->
<AssemblySearchPaths>{HintPathFromItem};{TargetFrameworkDirectory};{RawFileName}</AssemblySearchPaths>
<!-- Mono knows better where its MSBuild is. -->
<_MSBuildAssemblyPath Condition=" '$(MSBuildRuntimeType)' != 'Core' "
>$(MSBuildToolsPath)</_MSBuildAssemblyPath>
<!-- Under dotnet, make the best guess we can. -->
<_MSBuildAssemblyPath Condition=" '$(MSBuildRuntimeType)' == 'Core' "
>$(FrameworkPathOverride)/../msbuild/$(MSBuildToolsVersion)/bin</_MSBuildAssemblyPath>
</PropertyGroup>
</Project>

@ -0,0 +1,71 @@
#region Copyright notice and license
// Copyright 2018 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.
#endregion
using System.Reflection;
using NUnitLite;
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace Grpc.Tools.Tests
{
static class MsBuildAssemblyHelper
{
[DllImport("__Internal")]
extern static void mono_set_assemblies_path(string path);
public static void TweakAssemblyPathIfOnMono()
{
// Below is a hack to allow the tests to run under Mono Framework build.
// Mono unfortunately comes with broken Microsoft.Build.* assemblies installed in
// the GAC, so we need to tweak the assembly search path to make sure the right
// msbuild assemblies are loaded (and the tests work).
#if NET45
// only run this under .NET framework; under mono
bool isMono = Type.GetType("Mono.Runtime") != null;
if (isMono)
{
var mscorlibDir = Path.GetDirectoryName(typeof(Array).Assembly.Location);
// Construct the location of MsBuild assemblies from the location of mscorlib assembly.
var msbuildToolPath = Path.Combine(mscorlibDir, "..", "msbuild", "Current", "bin");
if (!Directory.Exists(msbuildToolPath))
{
// with older versions of mono for Mac (e.g. mono 5.16.0 which is currently
// installed on the kokoro mac workers) the "Current" symlink doesn't exist
// so also try specifying the msbuild version explicitly
msbuildToolPath = Path.Combine(mscorlibDir, "..", "msbuild", "15.0", "bin");
}
// To make sure we've constructed the right path, make sure the assemblies we're interested
// in are there.
foreach(var assemblyName in new [] {"Microsoft.Build.Framework.dll", "Microsoft.Build.Utilities.v4.0.dll", "Microsoft.Build.Utilities.Core.dll"})
{
if (!File.Exists(Path.Combine(msbuildToolPath, assemblyName)))
{
throw new InvalidOperationException($"Could not locate assembly {assemblyName} under {msbuildToolPath}");
}
}
// Normally the assembly search path can be changed by MONO_PATH environment variable, but it needs to be done
// before the process starts. The following internal method allows us to do the same thing.
mono_set_assemblies_path(msbuildToolPath);
}
#endif
}
}
}

@ -23,7 +23,10 @@ namespace Grpc.Tools.Tests
{
static class NUnitMain
{
public static int Main(string[] args) =>
new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args);
};
public static int Main(string[] args)
{
MsBuildAssemblyHelper.TweakAssemblyPathIfOnMono();
return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args);
}
}
}

@ -7,14 +7,13 @@
<TargetFrameworks>net45;netstandard1.3</TargetFrameworks>
</PropertyGroup>
<PropertyGroup Condition=" '$(OS)' != 'Windows_NT' and '$(MSBuildRuntimeType)' == 'Core' ">
<!-- Use Mono reference assemblies in SDK build: https://github.com/dotnet/sdk/issues/335.
This is a different approach than used in Grpc.Core/Common.csproj.include because
the workaround used there doesn't seem to be working for Microsoft.Build.* assemblies -->
<FrameworkPathOverride Condition="Exists('/usr/lib/mono/4.5-api')">/usr/lib/mono/4.5-api</FrameworkPathOverride>
<FrameworkPathOverride Condition="Exists('/usr/local/lib/mono/4.5-api')">/usr/local/lib/mono/4.5-api</FrameworkPathOverride>
<FrameworkPathOverride Condition="Exists('/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5-api')">/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5-api</FrameworkPathOverride>
</PropertyGroup>
<!-- Needed for the net45 build to work on Unix. See https://github.com/dotnet/designs/pull/33 -->
<ItemGroup>
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
<PropertyGroup Label="Asset root folders. TODO(kkm): Change with package separation.">
<!-- TODO(kkm): Rework whole section when splitting packages. -->

@ -126,4 +126,4 @@ Internally, gRPC C# uses a native library written in C (gRPC C core) and invokes
[API Reference]: https://grpc.io/grpc/csharp/api/Grpc.Core.html
[Helloworld Example]: ../../examples/csharp/Helloworld
[RouteGuide Tutorial]: https://grpc.io/docs/tutorials/basic/csharp.html
[RouteGuide Tutorial]: https://grpc.io/docs/languages/csharp/basics

@ -14,12 +14,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
load("//bazel:grpc_build_system.bzl", "grpc_generate_objc_one_off_targets", "grpc_objc_library")
load("@build_bazel_rules_apple//apple:resources.bzl", "apple_resource_bundle")
licenses(["notice"]) # Apache v2
package(default_visibility = ["//visibility:public"])
load("//bazel:grpc_build_system.bzl", "grpc_generate_objc_one_off_targets", "grpc_objc_library")
exports_files(["LICENSE"])
grpc_generate_objc_one_off_targets()
@ -195,8 +196,6 @@ grpc_objc_library(
],
)
load("@build_bazel_rules_apple//apple:resources.bzl", "apple_resource_bundle")
apple_resource_bundle(
# The choice of name is signicant here, since it determines the bundle name.
name = "gRPCCertificates",

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

Loading…
Cancel
Save