grpc 1.74.1 → 1.75.0.pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (368) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +83 -41
  3. data/include/grpc/credentials.h +7 -1
  4. data/src/core/call/client_call.cc +4 -4
  5. data/src/core/call/filter_fusion.h +1230 -0
  6. data/src/core/call/metadata.cc +22 -0
  7. data/src/core/call/metadata.h +24 -2
  8. data/src/core/channelz/channelz.cc +10 -17
  9. data/src/core/channelz/channelz.h +58 -19
  10. data/src/core/channelz/channelz_registry.cc +0 -162
  11. data/src/core/channelz/channelz_registry.h +14 -7
  12. data/src/core/channelz/property_list.cc +19 -23
  13. data/src/core/channelz/property_list.h +3 -1
  14. data/src/core/channelz/v2tov1/convert.cc +683 -0
  15. data/src/core/channelz/v2tov1/convert.h +58 -0
  16. data/src/core/channelz/v2tov1/legacy_api.cc +425 -0
  17. data/src/core/channelz/v2tov1/legacy_api.h +32 -0
  18. data/src/core/channelz/v2tov1/property_list.cc +118 -0
  19. data/src/core/channelz/v2tov1/property_list.h +52 -0
  20. data/src/core/client_channel/client_channel_filter.cc +5 -4
  21. data/src/core/client_channel/client_channel_filter.h +2 -2
  22. data/src/core/client_channel/client_channel_internal.h +2 -1
  23. data/src/core/client_channel/load_balanced_call_destination.cc +6 -5
  24. data/src/core/client_channel/subchannel.cc +14 -6
  25. data/src/core/client_channel/subchannel.h +2 -0
  26. data/src/core/config/core_configuration.cc +3 -1
  27. data/src/core/config/core_configuration.h +12 -0
  28. data/src/core/credentials/transport/alts/alts_credentials.cc +5 -0
  29. data/src/core/credentials/transport/alts/check_gcp_environment_windows.cc +2 -0
  30. data/src/core/credentials/transport/channel_creds_registry_init.cc +3 -1
  31. data/src/core/credentials/transport/ssl/ssl_credentials.cc +1 -1
  32. data/src/core/credentials/transport/ssl/ssl_security_connector.cc +8 -3
  33. data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.cc +29 -24
  34. data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.h +19 -8
  35. data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.cc +96 -54
  36. data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.h +15 -2
  37. data/src/core/credentials/transport/tls/spiffe_utils.cc +371 -0
  38. data/src/core/credentials/transport/tls/spiffe_utils.h +171 -0
  39. data/src/core/credentials/transport/tls/ssl_utils.cc +11 -10
  40. data/src/core/credentials/transport/tls/ssl_utils.h +4 -2
  41. data/src/core/credentials/transport/tls/tls_credentials.cc +2 -0
  42. data/src/core/credentials/transport/tls/tls_security_connector.cc +11 -26
  43. data/src/core/credentials/transport/tls/tls_security_connector.h +12 -12
  44. data/src/core/ext/filters/backend_metrics/backend_metric_filter.cc +1 -2
  45. data/src/core/ext/filters/http/client/http_client_filter.cc +3 -6
  46. data/src/core/ext/filters/http/client_authority_filter.cc +1 -2
  47. data/src/core/ext/filters/http/message_compress/compression_filter.cc +8 -8
  48. data/src/core/ext/filters/http/server/http_server_filter.cc +3 -6
  49. data/src/core/ext/filters/message_size/message_size_filter.cc +4 -4
  50. data/src/core/ext/filters/rbac/rbac_filter.cc +1 -1
  51. data/src/core/ext/filters/stateful_session/stateful_session_filter.cc +3 -5
  52. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +3 -2
  53. data/src/core/ext/transport/chttp2/transport/flow_control.cc +1 -0
  54. data/src/core/ext/transport/chttp2/transport/flow_control.h +1 -0
  55. data/src/core/ext/transport/chttp2/transport/frame.cc +89 -6
  56. data/src/core/ext/transport/chttp2/transport/frame.h +38 -0
  57. data/src/core/ext/transport/chttp2/transport/header_assembler.h +5 -14
  58. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +4 -1
  59. data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +294 -78
  60. data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +128 -9
  61. data/src/core/ext/transport/chttp2/transport/http2_settings.cc +11 -38
  62. data/src/core/ext/transport/chttp2/transport/http2_settings.h +52 -35
  63. data/src/core/ext/transport/chttp2/transport/http2_settings_manager.cc +61 -0
  64. data/src/core/ext/transport/chttp2/transport/http2_settings_manager.h +142 -0
  65. data/src/core/ext/transport/chttp2/transport/http2_transport.cc +81 -3
  66. data/src/core/ext/transport/chttp2/transport/http2_transport.h +12 -1
  67. data/src/core/ext/transport/chttp2/transport/message_assembler.h +2 -2
  68. data/src/core/ext/transport/chttp2/transport/parsing.cc +2 -1
  69. data/src/core/ext/transport/chttp2/transport/ping_promise.cc +2 -1
  70. data/src/core/ext/transport/chttp2/transport/ping_promise.h +22 -5
  71. data/src/core/ext/transport/chttp2/transport/stream_data_queue.h +607 -0
  72. data/src/core/ext/transport/chttp2/transport/writable_streams.h +254 -0
  73. data/src/core/ext/transport/chttp2/transport/writing.cc +6 -4
  74. data/src/core/ext/upb-gen/src/proto/grpc/channelz/channelz.upb.h +4959 -0
  75. data/src/core/ext/upb-gen/src/proto/grpc/channelz/channelz.upb_minitable.c +1111 -0
  76. data/src/core/ext/upb-gen/src/proto/grpc/channelz/channelz.upb_minitable.h +108 -0
  77. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb.h +142 -54
  78. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.c +18 -14
  79. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.h +2 -2
  80. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/channelz.upbdefs.c +716 -0
  81. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/channelz.upbdefs.h +227 -0
  82. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.c +86 -88
  83. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.h +2 -2
  84. data/src/core/filter/auth/auth_filters.h +2 -2
  85. data/src/core/filter/fused_filters.cc +154 -0
  86. data/src/core/handshaker/security/legacy_secure_endpoint.cc +1 -1
  87. data/src/core/handshaker/security/pipelined_secure_endpoint.cc +965 -0
  88. data/src/core/handshaker/security/secure_endpoint.cc +28 -13
  89. data/src/core/handshaker/security/secure_endpoint.h +8 -0
  90. data/src/core/lib/channel/promise_based_filter.cc +15 -25
  91. data/src/core/lib/channel/promise_based_filter.h +6 -5
  92. data/src/core/lib/event_engine/ares_resolver.h +3 -1
  93. data/src/core/lib/event_engine/cf_engine/cf_engine.cc +9 -5
  94. data/src/core/lib/event_engine/cf_engine/cf_engine.h +2 -1
  95. data/src/core/lib/event_engine/cf_engine/cfsocket_listener.cc +263 -0
  96. data/src/core/lib/event_engine/cf_engine/cfsocket_listener.h +107 -0
  97. data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc +31 -3
  98. data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.h +12 -0
  99. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc +12 -10
  100. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h +6 -4
  101. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +15 -14
  102. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.h +7 -5
  103. data/src/core/lib/event_engine/posix_engine/event_poller.h +0 -8
  104. data/src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc +11 -5
  105. data/src/core/lib/event_engine/posix_engine/event_poller_posix_default.h +3 -2
  106. data/src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h +1 -0
  107. data/src/core/lib/event_engine/posix_engine/lockfree_event.cc +4 -4
  108. data/src/core/lib/event_engine/posix_engine/lockfree_event.h +3 -4
  109. data/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +2 -2
  110. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +188 -199
  111. data/src/core/lib/event_engine/posix_engine/posix_engine.h +30 -45
  112. data/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc +1 -1
  113. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +1 -1
  114. data/src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc +2 -1
  115. data/src/core/lib/experiments/experiments.cc +120 -6
  116. data/src/core/lib/experiments/experiments.h +46 -3
  117. data/src/core/lib/iomgr/combiner.cc +1 -1
  118. data/src/core/lib/iomgr/exec_ctx.h +3 -9
  119. data/src/core/lib/iomgr/socket_mutator.cc +1 -1
  120. data/src/core/lib/iomgr/socket_utils_posix.cc +1 -1
  121. data/src/core/lib/iomgr/socket_utils_posix.h +1 -1
  122. data/src/core/lib/iomgr/tcp_client_posix.cc +1 -1
  123. data/src/core/lib/iomgr/tcp_posix.cc +3 -3
  124. data/src/core/lib/promise/activity.h +2 -2
  125. data/src/core/lib/promise/mpsc.cc +8 -8
  126. data/src/core/lib/promise/party.cc +7 -7
  127. data/src/core/lib/promise/party.h +4 -4
  128. data/src/core/lib/promise/poll.h +10 -0
  129. data/src/core/lib/resource_quota/memory_quota.cc +90 -3
  130. data/src/core/lib/resource_quota/memory_quota.h +20 -9
  131. data/src/core/lib/resource_quota/periodic_update.cc +14 -0
  132. data/src/core/lib/resource_quota/periodic_update.h +8 -0
  133. data/src/core/lib/resource_quota/resource_quota.cc +15 -4
  134. data/src/core/lib/resource_quota/resource_quota.h +3 -0
  135. data/src/core/lib/security/authorization/grpc_server_authz_filter.cc +1 -2
  136. data/src/core/lib/surface/call.cc +5 -5
  137. data/src/core/lib/surface/call.h +6 -5
  138. data/src/core/lib/surface/completion_queue.cc +2 -4
  139. data/src/core/lib/surface/filter_stack_call.cc +1 -1
  140. data/src/core/lib/surface/version.cc +2 -2
  141. data/src/core/lib/transport/promise_endpoint.cc +2 -2
  142. data/src/core/lib/transport/promise_endpoint.h +3 -3
  143. data/src/core/load_balancing/endpoint_list.cc +29 -2
  144. data/src/core/load_balancing/grpclb/client_load_reporting_filter.cc +3 -3
  145. data/src/core/load_balancing/grpclb/client_load_reporting_filter.h +1 -1
  146. data/src/core/load_balancing/pick_first/pick_first.cc +12 -5
  147. data/src/core/load_balancing/xds/xds_cluster_impl.cc +5 -3
  148. data/src/core/net/socket_mutator.cc +19 -0
  149. data/src/core/net/socket_mutator.h +25 -0
  150. data/src/core/plugin_registry/grpc_plugin_registry.cc +6 -0
  151. data/src/core/resolver/dns/c_ares/grpc_ares_ev_driver.h +6 -1
  152. data/src/core/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +2 -1
  153. data/src/core/resolver/dns/c_ares/grpc_ares_wrapper.cc +8 -5
  154. data/src/core/resolver/dns/c_ares/grpc_ares_wrapper.h +2 -1
  155. data/src/core/resolver/xds/xds_dependency_manager.cc +1 -1
  156. data/src/core/server/server.cc +1 -1
  157. data/src/core/server/server_call_tracer_filter.cc +0 -66
  158. data/src/core/server/server_call_tracer_filter.h +64 -0
  159. data/src/core/server/server_config_selector_filter.cc +1 -1
  160. data/src/core/service_config/service_config_channel_arg_filter.cc +3 -60
  161. data/src/core/service_config/service_config_channel_arg_filter.h +82 -0
  162. data/src/core/telemetry/call_tracer.cc +20 -14
  163. data/src/core/telemetry/call_tracer.h +22 -17
  164. data/src/core/telemetry/metrics.h +8 -8
  165. data/src/core/telemetry/stats_data.cc +151 -151
  166. data/src/core/telemetry/stats_data.h +87 -87
  167. data/src/core/transport/auth_context.cc +20 -0
  168. data/src/core/transport/auth_context.h +4 -0
  169. data/src/core/transport/auth_context_comparator_registry.h +69 -0
  170. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +2 -3
  171. data/src/core/tsi/ssl_transport_security.cc +202 -32
  172. data/src/core/tsi/ssl_transport_security.h +19 -10
  173. data/src/core/tsi/ssl_transport_security_utils.cc +21 -0
  174. data/src/core/tsi/ssl_transport_security_utils.h +4 -0
  175. data/src/core/util/http_client/httpcli_security_connector.cc +3 -1
  176. data/src/core/util/latent_see.cc +178 -146
  177. data/src/core/util/latent_see.h +245 -188
  178. data/src/core/util/single_set_ptr.h +5 -2
  179. data/src/core/util/useful.h +91 -0
  180. data/src/core/util/windows/directory_reader.cc +1 -0
  181. data/src/core/util/windows/thd.cc +1 -3
  182. data/src/core/util/work_serializer.cc +1 -1
  183. data/src/core/xds/grpc/file_watcher_certificate_provider_factory.cc +32 -5
  184. data/src/core/xds/grpc/file_watcher_certificate_provider_factory.h +5 -0
  185. data/src/core/xds/grpc/xds_certificate_provider.cc +5 -6
  186. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +1 -1
  187. data/src/ruby/lib/grpc/version.rb +1 -1
  188. data/third_party/cares/cares/include/ares.h +925 -460
  189. data/third_party/cares/cares/include/ares_dns.h +86 -71
  190. data/third_party/cares/cares/include/ares_dns_record.h +1118 -0
  191. data/third_party/cares/cares/include/ares_nameser.h +215 -189
  192. data/third_party/cares/cares/include/ares_version.h +37 -14
  193. data/third_party/cares/cares/src/lib/ares_addrinfo2hostent.c +305 -0
  194. data/third_party/cares/cares/src/lib/ares_addrinfo_localhost.c +245 -0
  195. data/third_party/cares/cares/src/lib/ares_android.c +216 -164
  196. data/third_party/cares/cares/src/lib/ares_android.h +25 -14
  197. data/third_party/cares/cares/src/lib/ares_cancel.c +68 -44
  198. data/third_party/cares/cares/src/lib/ares_close_sockets.c +137 -0
  199. data/third_party/cares/cares/src/lib/ares_conn.c +511 -0
  200. data/third_party/cares/cares/src/lib/ares_conn.h +196 -0
  201. data/third_party/cares/cares/src/lib/ares_cookie.c +461 -0
  202. data/third_party/cares/cares/src/lib/ares_data.c +93 -181
  203. data/third_party/cares/cares/src/lib/ares_data.h +50 -39
  204. data/third_party/cares/cares/src/lib/ares_destroy.c +127 -89
  205. data/third_party/cares/cares/src/lib/ares_free_hostent.c +35 -24
  206. data/third_party/cares/cares/src/lib/ares_free_string.c +24 -16
  207. data/third_party/cares/cares/src/lib/ares_freeaddrinfo.c +45 -38
  208. data/third_party/cares/cares/src/lib/ares_getaddrinfo.c +549 -663
  209. data/third_party/cares/cares/src/lib/ares_getenv.c +25 -15
  210. data/third_party/cares/cares/src/lib/ares_getenv.h +26 -18
  211. data/third_party/cares/cares/src/lib/ares_gethostbyaddr.c +163 -221
  212. data/third_party/cares/cares/src/lib/ares_gethostbyname.c +222 -223
  213. data/third_party/cares/cares/src/lib/ares_getnameinfo.c +328 -338
  214. data/third_party/cares/cares/src/lib/ares_hosts_file.c +952 -0
  215. data/third_party/cares/cares/src/lib/ares_inet_net_pton.h +25 -19
  216. data/third_party/cares/cares/src/lib/ares_init.c +425 -2091
  217. data/third_party/cares/cares/src/lib/ares_ipv6.h +63 -33
  218. data/third_party/cares/cares/src/lib/ares_library_init.c +110 -54
  219. data/third_party/cares/cares/src/lib/ares_metrics.c +261 -0
  220. data/third_party/cares/cares/src/lib/ares_options.c +418 -332
  221. data/third_party/cares/cares/src/lib/ares_parse_into_addrinfo.c +179 -0
  222. data/third_party/cares/cares/src/lib/ares_private.h +558 -356
  223. data/third_party/cares/cares/src/lib/ares_process.c +1224 -1369
  224. data/third_party/cares/cares/src/lib/ares_qcache.c +430 -0
  225. data/third_party/cares/cares/src/lib/ares_query.c +126 -121
  226. data/third_party/cares/cares/src/lib/ares_search.c +564 -262
  227. data/third_party/cares/cares/src/lib/ares_send.c +264 -93
  228. data/third_party/cares/cares/src/lib/ares_set_socket_functions.c +588 -0
  229. data/third_party/cares/cares/src/lib/ares_setup.h +115 -111
  230. data/third_party/cares/cares/src/lib/ares_socket.c +425 -0
  231. data/third_party/cares/cares/src/lib/ares_socket.h +163 -0
  232. data/third_party/cares/cares/src/lib/ares_sortaddrinfo.c +447 -0
  233. data/third_party/cares/cares/src/lib/ares_strerror.c +83 -48
  234. data/third_party/cares/cares/src/lib/ares_sysconfig.c +639 -0
  235. data/third_party/cares/cares/src/lib/ares_sysconfig_files.c +839 -0
  236. data/third_party/cares/cares/src/lib/ares_sysconfig_mac.c +373 -0
  237. data/third_party/cares/cares/src/lib/ares_sysconfig_win.c +621 -0
  238. data/third_party/cares/cares/src/lib/ares_timeout.c +136 -73
  239. data/third_party/cares/cares/src/lib/ares_update_servers.c +1362 -0
  240. data/third_party/cares/cares/src/lib/ares_version.c +29 -4
  241. data/third_party/cares/cares/src/lib/config-dos.h +88 -89
  242. data/third_party/cares/cares/src/lib/config-win32.h +122 -77
  243. data/third_party/cares/cares/src/lib/dsa/ares_array.c +394 -0
  244. data/third_party/cares/cares/src/lib/dsa/ares_htable.c +447 -0
  245. data/third_party/cares/cares/src/lib/dsa/ares_htable.h +174 -0
  246. data/third_party/cares/cares/src/lib/dsa/ares_htable_asvp.c +224 -0
  247. data/third_party/cares/cares/src/lib/dsa/ares_htable_dict.c +228 -0
  248. data/third_party/cares/cares/src/lib/dsa/ares_htable_strvp.c +210 -0
  249. data/third_party/cares/cares/src/lib/dsa/ares_htable_szvp.c +188 -0
  250. data/third_party/cares/cares/src/lib/dsa/ares_htable_vpstr.c +186 -0
  251. data/third_party/cares/cares/src/lib/dsa/ares_htable_vpvp.c +194 -0
  252. data/third_party/cares/cares/src/lib/dsa/ares_llist.c +382 -0
  253. data/third_party/cares/cares/src/lib/dsa/ares_slist.c +479 -0
  254. data/third_party/cares/cares/src/lib/dsa/ares_slist.h +207 -0
  255. data/third_party/cares/cares/src/lib/event/ares_event.h +191 -0
  256. data/third_party/cares/cares/src/lib/event/ares_event_configchg.c +743 -0
  257. data/third_party/cares/cares/src/lib/event/ares_event_epoll.c +192 -0
  258. data/third_party/cares/cares/src/lib/event/ares_event_kqueue.c +248 -0
  259. data/third_party/cares/cares/src/lib/event/ares_event_poll.c +140 -0
  260. data/third_party/cares/cares/src/lib/event/ares_event_select.c +159 -0
  261. data/third_party/cares/cares/src/lib/event/ares_event_thread.c +567 -0
  262. data/third_party/cares/cares/src/lib/event/ares_event_wake_pipe.c +166 -0
  263. data/third_party/cares/cares/src/lib/event/ares_event_win32.c +978 -0
  264. data/third_party/cares/cares/src/lib/event/ares_event_win32.h +161 -0
  265. data/third_party/cares/cares/src/lib/include/ares_array.h +276 -0
  266. data/third_party/cares/cares/src/lib/include/ares_buf.h +732 -0
  267. data/third_party/cares/cares/src/lib/include/ares_htable_asvp.h +130 -0
  268. data/third_party/cares/cares/src/lib/include/ares_htable_dict.h +123 -0
  269. data/third_party/cares/cares/src/lib/include/ares_htable_strvp.h +130 -0
  270. data/third_party/cares/cares/src/lib/include/ares_htable_szvp.h +118 -0
  271. data/third_party/cares/cares/src/lib/include/ares_htable_vpstr.h +111 -0
  272. data/third_party/cares/cares/src/lib/include/ares_htable_vpvp.h +128 -0
  273. data/third_party/cares/cares/src/lib/include/ares_llist.h +239 -0
  274. data/third_party/cares/cares/src/lib/include/ares_mem.h +38 -0
  275. data/third_party/cares/cares/src/lib/include/ares_str.h +244 -0
  276. data/third_party/cares/cares/src/lib/inet_net_pton.c +202 -157
  277. data/third_party/cares/cares/src/lib/inet_ntop.c +87 -69
  278. data/third_party/cares/cares/src/lib/legacy/ares_create_query.c +78 -0
  279. data/third_party/cares/cares/src/lib/legacy/ares_expand_name.c +99 -0
  280. data/third_party/cares/cares/src/lib/legacy/ares_expand_string.c +107 -0
  281. data/third_party/cares/cares/src/lib/legacy/ares_fds.c +80 -0
  282. data/third_party/cares/cares/src/lib/legacy/ares_getsock.c +85 -0
  283. data/third_party/cares/cares/src/lib/legacy/ares_parse_a_reply.c +107 -0
  284. data/third_party/cares/cares/src/lib/legacy/ares_parse_aaaa_reply.c +109 -0
  285. data/third_party/cares/cares/src/lib/legacy/ares_parse_caa_reply.c +137 -0
  286. data/third_party/cares/cares/src/lib/legacy/ares_parse_mx_reply.c +110 -0
  287. data/third_party/cares/cares/src/lib/legacy/ares_parse_naptr_reply.c +132 -0
  288. data/third_party/cares/cares/src/lib/legacy/ares_parse_ns_reply.c +154 -0
  289. data/third_party/cares/cares/src/lib/legacy/ares_parse_ptr_reply.c +213 -0
  290. data/third_party/cares/cares/src/lib/legacy/ares_parse_soa_reply.c +115 -0
  291. data/third_party/cares/cares/src/lib/legacy/ares_parse_srv_reply.c +114 -0
  292. data/third_party/cares/cares/src/lib/legacy/ares_parse_txt_reply.c +144 -0
  293. data/third_party/cares/cares/src/lib/legacy/ares_parse_uri_reply.c +113 -0
  294. data/third_party/cares/cares/src/lib/record/ares_dns_mapping.c +982 -0
  295. data/third_party/cares/cares/src/lib/record/ares_dns_multistring.c +307 -0
  296. data/third_party/cares/cares/src/lib/record/ares_dns_multistring.h +72 -0
  297. data/third_party/cares/cares/src/lib/record/ares_dns_name.c +673 -0
  298. data/third_party/cares/cares/src/lib/record/ares_dns_parse.c +1329 -0
  299. data/third_party/cares/cares/src/lib/record/ares_dns_private.h +273 -0
  300. data/third_party/cares/cares/src/lib/record/ares_dns_record.c +1661 -0
  301. data/third_party/cares/cares/src/lib/record/ares_dns_write.c +1229 -0
  302. data/third_party/cares/cares/src/lib/str/ares_buf.c +1498 -0
  303. data/third_party/cares/cares/src/lib/str/ares_str.c +508 -0
  304. data/third_party/cares/cares/src/lib/str/ares_strsplit.c +90 -0
  305. data/third_party/cares/cares/src/lib/str/ares_strsplit.h +51 -0
  306. data/third_party/cares/cares/src/lib/thirdparty/apple/dnsinfo.h +122 -0
  307. data/third_party/cares/cares/src/lib/util/ares_iface_ips.c +628 -0
  308. data/third_party/cares/cares/src/lib/util/ares_iface_ips.h +139 -0
  309. data/third_party/cares/cares/src/lib/util/ares_math.c +158 -0
  310. data/third_party/cares/cares/src/lib/util/ares_math.h +45 -0
  311. data/third_party/cares/cares/src/lib/util/ares_rand.c +389 -0
  312. data/third_party/cares/cares/src/lib/util/ares_rand.h +36 -0
  313. data/third_party/cares/cares/src/lib/util/ares_threads.c +614 -0
  314. data/third_party/cares/cares/src/lib/util/ares_threads.h +60 -0
  315. data/third_party/cares/cares/src/lib/util/ares_time.h +48 -0
  316. data/third_party/cares/cares/src/lib/util/ares_timeval.c +95 -0
  317. data/third_party/cares/cares/src/lib/util/ares_uri.c +1626 -0
  318. data/third_party/cares/cares/src/lib/util/ares_uri.h +252 -0
  319. data/third_party/cares/cares/src/lib/windows_port.c +16 -9
  320. metadata +121 -49
  321. data/src/core/util/ring_buffer.h +0 -122
  322. data/third_party/cares/cares/include/ares_rules.h +0 -125
  323. data/third_party/cares/cares/src/lib/ares__addrinfo2hostent.c +0 -266
  324. data/third_party/cares/cares/src/lib/ares__addrinfo_localhost.c +0 -240
  325. data/third_party/cares/cares/src/lib/ares__close_sockets.c +0 -61
  326. data/third_party/cares/cares/src/lib/ares__get_hostent.c +0 -260
  327. data/third_party/cares/cares/src/lib/ares__parse_into_addrinfo.c +0 -229
  328. data/third_party/cares/cares/src/lib/ares__read_line.c +0 -73
  329. data/third_party/cares/cares/src/lib/ares__readaddrinfo.c +0 -258
  330. data/third_party/cares/cares/src/lib/ares__sortaddrinfo.c +0 -507
  331. data/third_party/cares/cares/src/lib/ares__timeval.c +0 -111
  332. data/third_party/cares/cares/src/lib/ares_create_query.c +0 -197
  333. data/third_party/cares/cares/src/lib/ares_expand_name.c +0 -311
  334. data/third_party/cares/cares/src/lib/ares_expand_string.c +0 -67
  335. data/third_party/cares/cares/src/lib/ares_fds.c +0 -59
  336. data/third_party/cares/cares/src/lib/ares_getsock.c +0 -66
  337. data/third_party/cares/cares/src/lib/ares_iphlpapi.h +0 -221
  338. data/third_party/cares/cares/src/lib/ares_llist.c +0 -63
  339. data/third_party/cares/cares/src/lib/ares_llist.h +0 -39
  340. data/third_party/cares/cares/src/lib/ares_mkquery.c +0 -24
  341. data/third_party/cares/cares/src/lib/ares_nowarn.c +0 -260
  342. data/third_party/cares/cares/src/lib/ares_nowarn.h +0 -61
  343. data/third_party/cares/cares/src/lib/ares_parse_a_reply.c +0 -90
  344. data/third_party/cares/cares/src/lib/ares_parse_aaaa_reply.c +0 -92
  345. data/third_party/cares/cares/src/lib/ares_parse_caa_reply.c +0 -199
  346. data/third_party/cares/cares/src/lib/ares_parse_mx_reply.c +0 -164
  347. data/third_party/cares/cares/src/lib/ares_parse_naptr_reply.c +0 -183
  348. data/third_party/cares/cares/src/lib/ares_parse_ns_reply.c +0 -177
  349. data/third_party/cares/cares/src/lib/ares_parse_ptr_reply.c +0 -228
  350. data/third_party/cares/cares/src/lib/ares_parse_soa_reply.c +0 -179
  351. data/third_party/cares/cares/src/lib/ares_parse_srv_reply.c +0 -168
  352. data/third_party/cares/cares/src/lib/ares_parse_txt_reply.c +0 -214
  353. data/third_party/cares/cares/src/lib/ares_parse_uri_reply.c +0 -184
  354. data/third_party/cares/cares/src/lib/ares_platform.c +0 -11042
  355. data/third_party/cares/cares/src/lib/ares_platform.h +0 -43
  356. data/third_party/cares/cares/src/lib/ares_rand.c +0 -279
  357. data/third_party/cares/cares/src/lib/ares_strcasecmp.c +0 -66
  358. data/third_party/cares/cares/src/lib/ares_strcasecmp.h +0 -30
  359. data/third_party/cares/cares/src/lib/ares_strdup.c +0 -42
  360. data/third_party/cares/cares/src/lib/ares_strdup.h +0 -24
  361. data/third_party/cares/cares/src/lib/ares_strsplit.c +0 -94
  362. data/third_party/cares/cares/src/lib/ares_strsplit.h +0 -42
  363. data/third_party/cares/cares/src/lib/ares_writev.c +0 -79
  364. data/third_party/cares/cares/src/lib/ares_writev.h +0 -36
  365. data/third_party/cares/cares/src/lib/bitncmp.c +0 -59
  366. data/third_party/cares/cares/src/lib/bitncmp.h +0 -26
  367. data/third_party/cares/cares/src/lib/setup_once.h +0 -554
  368. data/third_party/cares/cares/src/tools/ares_getopt.h +0 -53
@@ -0,0 +1,1230 @@
1
+ // Copyright 2025 gRPC authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #ifndef GRPC_SRC_CORE_CALL_FILTER_FUSION_H
16
+ #define GRPC_SRC_CORE_CALL_FILTER_FUSION_H
17
+ #include <grpc/impl/grpc_types.h>
18
+
19
+ #include <cstddef>
20
+ #include <memory>
21
+ #include <string>
22
+ #include <tuple>
23
+ #include <type_traits>
24
+ #include <utility>
25
+
26
+ #include "absl/log/check.h"
27
+ #include "absl/log/log.h"
28
+ #include "absl/memory/memory.h"
29
+ #include "absl/status/status.h"
30
+ #include "absl/strings/str_join.h"
31
+ #include "src/core/call/call_filters.h"
32
+ #include "src/core/call/metadata.h"
33
+ #include "src/core/lib/channel/channel_args.h"
34
+ #include "src/core/lib/channel/promise_based_filter.h"
35
+ #include "src/core/lib/promise/promise.h"
36
+ #include "src/core/lib/transport/call_final_info.h"
37
+ #include "src/core/lib/transport/transport.h"
38
+ #include "src/core/util/manual_constructor.h"
39
+ #include "src/core/util/status_helper.h"
40
+ #include "src/core/util/type_list.h"
41
+
42
+ struct grpc_transport_op;
43
+
44
+ namespace grpc_core {
45
+ namespace filters_detail {
46
+
47
+ template <typename... Ts>
48
+ constexpr bool AllNoInterceptor =
49
+ (std::is_same_v<Ts, const NoInterceptor*> && ...);
50
+
51
+ enum class MethodVariant {
52
+ kNoInterceptor,
53
+ kSimple,
54
+ kChannelAccess,
55
+ };
56
+
57
+ template <typename... Ts>
58
+ constexpr MethodVariant MethodVariantForFilters() {
59
+ if constexpr (AllNoInterceptor<Ts...>) {
60
+ return MethodVariant::kNoInterceptor;
61
+ } else if constexpr (!AnyMethodHasChannelAccess<Ts...>) {
62
+ return MethodVariant::kSimple;
63
+ } else {
64
+ return MethodVariant::kChannelAccess;
65
+ }
66
+ }
67
+
68
+ template <typename T>
69
+ using Hdl = Arena::PoolPtr<T>;
70
+
71
+ template <typename T, typename A>
72
+ constexpr bool IsSameExcludingCVRef =
73
+ std::is_same<promise_detail::RemoveCVRef<A>, T>::value;
74
+
75
+ template <typename T, typename A>
76
+ using EnableIfSameExcludingCVRef =
77
+ std::enable_if_t<std::is_same<promise_detail::RemoveCVRef<A>, T>::value,
78
+ void>;
79
+
80
+ template <typename T, typename MethodType, MethodType method,
81
+ typename Ignored = void>
82
+ class AdaptMethod;
83
+
84
+ template <typename T, const NoInterceptor* method>
85
+ class AdaptMethod<T, const NoInterceptor*, method> {
86
+ public:
87
+ explicit AdaptMethod(void* /*call*/, void* /*filter*/ = nullptr) {}
88
+ auto operator()(Hdl<T> x) {
89
+ return Immediate(ServerMetadataOrHandle<T>::Ok(std::move(x)));
90
+ }
91
+ void operator()(T* /*x*/) {}
92
+ };
93
+
94
+ // Overrides for Filter methods with void Return types.
95
+ template <typename T, typename A, typename Call, void (Call::*method)(A)>
96
+ class AdaptMethod<T, void (Call::*)(A), method,
97
+ EnableIfSameExcludingCVRef<T, A>> {
98
+ public:
99
+ explicit AdaptMethod(Call* call, void* /*filter*/ = nullptr) : call_(call) {}
100
+
101
+ auto operator()(Hdl<T> x) {
102
+ (call_->*method)(*x);
103
+ return Immediate(ServerMetadataOrHandle<T>::Ok(std::move(x)));
104
+ }
105
+
106
+ private:
107
+ Call* call_;
108
+ };
109
+
110
+ template <typename T, typename Call, void (Call::*method)()>
111
+ class AdaptMethod<T, void (Call::*)(), method> {
112
+ public:
113
+ explicit AdaptMethod(Call* call, void* /*filter*/ = nullptr) : call_(call) {}
114
+ auto operator()(Hdl<T> x) {
115
+ (call_->*method)();
116
+ return Immediate(ServerMetadataOrHandle<T>::Ok(std::move(x)));
117
+ }
118
+
119
+ private:
120
+ Call* call_;
121
+ };
122
+
123
+ template <typename T, typename A, typename Call, typename Derived,
124
+ void (Call::*method)(A, Derived*)>
125
+ class AdaptMethod<T, void (Call::*)(A, Derived*), method,
126
+ EnableIfSameExcludingCVRef<T, A>> {
127
+ public:
128
+ explicit AdaptMethod(Call* call, Derived* filter)
129
+ : call_(call), filter_(filter) {}
130
+ auto operator()(Hdl<T> x) {
131
+ (call_->*method)(*x, filter_);
132
+ return Immediate(ServerMetadataOrHandle<T>::Ok(std::move(x)));
133
+ }
134
+
135
+ private:
136
+ Call* call_;
137
+ Derived* filter_;
138
+ };
139
+
140
+ // primary template handles types that have no nested ::Call member:
141
+ template <class, class = void>
142
+ constexpr const bool kHasCallMember = false;
143
+
144
+ // specialization recognizes types that have a nested ::Call member:
145
+ template <class T>
146
+ constexpr const bool kHasCallMember<T, std::void_t<typename T::Call>> = true;
147
+
148
+ // Override for filter method types that take a pointer to the filter along
149
+ // with another arbitrary pointer type. Expected to be used to handle
150
+ // OnFinalize methods.
151
+ template <typename A, typename Call, typename Derived,
152
+ void (Call::*method)(const A*, Derived*)>
153
+ class AdaptMethod<
154
+ A, void (Call::*)(const A*, Derived*), method,
155
+ std::enable_if_t<std::is_same<typename Derived::Call, Call>::value, void>> {
156
+ public:
157
+ explicit AdaptMethod(Call* call, Derived* filter)
158
+ : call_(call), filter_(filter) {}
159
+ void operator()(A* arg) { (call_->*method)(arg, filter_); }
160
+
161
+ private:
162
+ Call* call_;
163
+ Derived* filter_;
164
+ };
165
+
166
+ // Same as above with the const qualifiers removed.
167
+ template <typename A, typename Call, typename Derived,
168
+ void (Call::*method)(A*, Derived*)>
169
+ class AdaptMethod<
170
+ A, void (Call::*)(A*, Derived*), method,
171
+ std::enable_if_t<std::is_same<typename Derived::Call, Call>::value, void>> {
172
+ public:
173
+ explicit AdaptMethod(Call* call, Derived* filter)
174
+ : call_(call), filter_(filter) {}
175
+ void operator()(A* arg) { (call_->*method)(arg, filter_); }
176
+
177
+ private:
178
+ Call* call_;
179
+ Derived* filter_;
180
+ };
181
+
182
+ // Override for filter method types that another arbitrary pointer type.
183
+ // Expected to be used to handle OnFinalize methods.
184
+ template <typename A, typename Call, void (Call::*method)(const A*)>
185
+ class AdaptMethod<A, void (Call::*)(const A*), method,
186
+ std::enable_if_t<!kHasCallMember<A>, void>> {
187
+ public:
188
+ explicit AdaptMethod(Call* call, void* /*filter*/) : call_(call) {}
189
+ void operator()(A* arg) { (call_->*method)(arg); }
190
+
191
+ private:
192
+ Call* call_;
193
+ };
194
+
195
+ // Same as above with the const qualifiers removed.
196
+ template <typename A, typename Call, void (Call::*method)(A*)>
197
+ class AdaptMethod<A, void (Call::*)(A*), method,
198
+ std::enable_if_t<!kHasCallMember<A>, void>> {
199
+ public:
200
+ explicit AdaptMethod(Call* call, void* /*filter*/) : call_(call) {}
201
+ void operator()(A* arg) { (call_->*method)(arg); }
202
+
203
+ private:
204
+ Call* call_;
205
+ };
206
+
207
+ template <typename T, typename AnyType = void>
208
+ struct TakeValueExists {
209
+ static constexpr bool value = false;
210
+ };
211
+
212
+ template <typename T>
213
+ struct TakeValueExists<T,
214
+ absl::void_t<decltype(TakeValue(std::declval<T>()))>> {
215
+ static constexpr bool value = true;
216
+ };
217
+
218
+ template <typename T, typename AnyType = void>
219
+ struct StatusType {
220
+ static constexpr bool value = false;
221
+ };
222
+
223
+ template <typename T>
224
+ struct StatusType<
225
+ T, absl::enable_if_t<
226
+ std::is_same<decltype(IsStatusOk(std::declval<T>())), bool>::value &&
227
+ !std::is_same<T, ServerMetadataHandle>::value &&
228
+ !TakeValueExists<T>::value,
229
+ void>> {
230
+ static constexpr bool value = true;
231
+ };
232
+
233
+ template <typename T, typename = void>
234
+ struct HasStatusMethod {
235
+ static constexpr bool value = false;
236
+ };
237
+
238
+ template <typename T>
239
+ struct HasStatusMethod<
240
+ T, std::enable_if_t<!std::is_void_v<decltype(std::declval<T>().status())>,
241
+ void>> {
242
+ static constexpr bool value = true;
243
+ };
244
+
245
+ template <typename T>
246
+ constexpr bool IsPromise = std::is_invocable_v<T>;
247
+
248
+ // For types T which are of the form StatusOr<U>. Type TakeValue on Type T
249
+ // must return a value of type U. Further type T must have a method called
250
+ // status() and must return a bool when IsStatusOk is called on an object of
251
+ // type T.
252
+ template <typename T, typename U, typename AnyType = void>
253
+ struct StatusOrType {
254
+ static constexpr bool value = false;
255
+ };
256
+ template <typename T, typename U>
257
+ struct StatusOrType<
258
+ T, U,
259
+ absl::enable_if_t<
260
+ std::is_same<decltype(IsStatusOk(std::declval<T>())), bool>::value &&
261
+ TakeValueExists<T>::value && HasStatusMethod<T>::value &&
262
+ std::is_same<decltype(TakeValue(std::declval<T>())), U>::value,
263
+ void>> {
264
+ static constexpr bool value = true;
265
+ };
266
+
267
+ // Overrides for Filter methods with a Return type supporting a bool ok()
268
+ // method without holding a value within e.g., for absl::Status or StatusFlag
269
+ // return types.
270
+ template <typename T, typename A, typename R, typename Call,
271
+ R (Call::*method)(A)>
272
+ class AdaptMethod<
273
+ T, R (Call::*)(A), method,
274
+ absl::enable_if_t<StatusType<R>::value && IsSameExcludingCVRef<T, A>,
275
+ void>> {
276
+ public:
277
+ explicit AdaptMethod(Call* call, void* /*filter*/ = nullptr) : call_(call) {}
278
+ auto operator()(Hdl<T> x) {
279
+ R result = (call_->*method)(*x);
280
+ if (IsStatusOk(result)) {
281
+ return Immediate(ServerMetadataOrHandle<T>::Ok(std::move(x)));
282
+ }
283
+ return Immediate(
284
+ ServerMetadataOrHandle<T>::Failure(ServerMetadataFromStatus(result)));
285
+ }
286
+
287
+ private:
288
+ Call* call_;
289
+ };
290
+
291
+ template <typename T, typename R, typename Call, R (Call::*method)()>
292
+ class AdaptMethod<T, R (Call::*)(), method,
293
+ absl::enable_if_t<StatusType<R>::value, void>> {
294
+ public:
295
+ explicit AdaptMethod(Call* call, void* /*filter*/ = nullptr) : call_(call) {}
296
+ auto operator()(Hdl<T> x) {
297
+ R result = (call_->*method)();
298
+ if (IsStatusOk(result)) {
299
+ return Immediate(ServerMetadataOrHandle<T>::Ok(std::move(x)));
300
+ };
301
+ return Immediate(
302
+ ServerMetadataOrHandle<T>::Failure(ServerMetadataFromStatus(result)));
303
+ }
304
+
305
+ private:
306
+ Call* call_;
307
+ };
308
+
309
+ template <typename T, typename A, typename R, typename Call, typename Derived,
310
+ R (Call::*method)(A, Derived*)>
311
+ class AdaptMethod<
312
+ T, R (Call::*)(A, Derived*), method,
313
+ absl::enable_if_t<StatusType<R>::value && IsSameExcludingCVRef<T, A>,
314
+ void>> {
315
+ public:
316
+ explicit AdaptMethod(Call* call, Derived* filter)
317
+ : call_(call), filter_(filter) {}
318
+ auto operator()(Hdl<T> x) {
319
+ R result = (call_->*method)(*x, filter_);
320
+ if (IsStatusOk(result)) {
321
+ return Immediate(ServerMetadataOrHandle<T>::Ok(std::move(x)));
322
+ }
323
+ return Immediate(
324
+ ServerMetadataOrHandle<T>::Failure(ServerMetadataFromStatus(result)));
325
+ }
326
+
327
+ private:
328
+ Call* call_;
329
+ Derived* filter_;
330
+ };
331
+
332
+ // Overrides for Filter methods with a Return type supporting a bool ok()
333
+ // method and holding a value within e.g., for absl::StatusOr<T> return types.
334
+ template <typename T, typename A, typename R, typename Call,
335
+ R (Call::*method)(A)>
336
+ class AdaptMethod<
337
+ T, R (Call::*)(A), method,
338
+ absl::enable_if_t<StatusOrType<R, T>::value && IsSameExcludingCVRef<T, A>,
339
+ void>> {
340
+ public:
341
+ explicit AdaptMethod(Call* call, void* /*filter*/ = nullptr) : call_(call) {}
342
+ auto operator()(Hdl<T> x) {
343
+ R result = (call_->*method)(*x);
344
+ if (IsStatusOk(result)) {
345
+ return Immediate(
346
+ ServerMetadataOrHandle<T>::Ok(TakeValue(std::move(result))));
347
+ }
348
+ return Immediate(ServerMetadataOrHandle<T>::Failure(
349
+ ServerMetadataFromStatus(std::move(result.status()))));
350
+ }
351
+
352
+ private:
353
+ Call* call_;
354
+ };
355
+
356
+ template <typename T, typename R, typename Call, R (Call::*method)()>
357
+ class AdaptMethod<T, R (Call::*)(), method,
358
+ absl::enable_if_t<StatusOrType<R, T>::value, void>> {
359
+ public:
360
+ explicit AdaptMethod(Call* call, void* /*filter*/ = nullptr) : call_(call) {}
361
+ auto operator()(Hdl<T> /*x*/) {
362
+ R result = (call_->*method)();
363
+ if (IsStatusOk(result)) {
364
+ return Immediate(
365
+ ServerMetadataOrHandle<T>::Ok(TakeValue(std::move(result))));
366
+ }
367
+ return Immediate(ServerMetadataOrHandle<T>::Failure(
368
+ ServerMetadataFromStatus(std::move(result.status()))));
369
+ }
370
+
371
+ private:
372
+ Call* call_;
373
+ };
374
+
375
+ template <typename T, typename A, typename R, typename Call, typename Derived,
376
+ R (Call::*method)(A, Derived*)>
377
+ class AdaptMethod<
378
+ T, R (Call::*)(A, Derived*), method,
379
+ absl::enable_if_t<StatusOrType<R, T>::value && IsSameExcludingCVRef<T, A>,
380
+ void>> {
381
+ public:
382
+ using UnwrappedType = decltype(TakeValue(std::declval<R>()));
383
+ static_assert(std::is_same<UnwrappedType, T>::value);
384
+ explicit AdaptMethod(Call* call, Derived* filter)
385
+ : call_(call), filter_(filter) {}
386
+ auto operator()(Hdl<T> x) {
387
+ R result = (call_->*method)(*x, filter_);
388
+ if (IsStatusOk(result)) {
389
+ return Immediate(
390
+ ServerMetadataOrHandle<T>::Ok(TakeValue(std::move(result))));
391
+ }
392
+ return Immediate(ServerMetadataOrHandle<T>::Failure(
393
+ ServerMetadataFromStatus(std::move(result.status()))));
394
+ }
395
+
396
+ private:
397
+ Call* call_;
398
+ Derived* filter_;
399
+ };
400
+
401
+ // Overrides for filter methods which take a Hdl<T> type or void as input and
402
+ // return a StatusOr<Hdl<T>> type as output
403
+ template <typename T, typename R, typename Call, R (Call::*method)(Hdl<T>)>
404
+ class AdaptMethod<T, R (Call::*)(Hdl<T>), method,
405
+ absl::enable_if_t<StatusOrType<R, Hdl<T>>::value, void>> {
406
+ public:
407
+ explicit AdaptMethod(Call* call, void* /*filter*/ = nullptr) : call_(call) {}
408
+ auto operator()(Hdl<T> x) {
409
+ R result = (call_->*method)(std::move(x));
410
+ if (IsStatusOk(result)) {
411
+ return Immediate(ServerMetadataOrHandle<T>::Ok(std::move(*result)));
412
+ }
413
+
414
+ return Immediate(ServerMetadataOrHandle<T>::Failure(
415
+ ServerMetadataFromStatus(result.status())));
416
+ }
417
+
418
+ private:
419
+ Call* call_;
420
+ };
421
+
422
+ template <typename T, typename R, typename Call, R (Call::*method)()>
423
+ class AdaptMethod<T, R (Call::*)(), method,
424
+ absl::enable_if_t<StatusOrType<R, Hdl<T>>::value, void>> {
425
+ public:
426
+ explicit AdaptMethod(Call* call, void* /*filter*/ = nullptr) : call_(call) {}
427
+ auto operator()(Hdl<T> /*x*/) {
428
+ R result = (call_->*method)();
429
+ if (IsStatusOk(result)) {
430
+ return Immediate(ServerMetadataOrHandle<T>::Ok(std::move(*result)));
431
+ }
432
+
433
+ return Immediate(ServerMetadataOrHandle<T>::Failure(
434
+ ServerMetadataFromStatus(result.status())));
435
+ }
436
+
437
+ private:
438
+ Call* call_;
439
+ };
440
+
441
+ template <typename T, typename R, typename Call, typename Derived,
442
+ R (Call::*method)(Hdl<T>, Derived*)>
443
+ class AdaptMethod<T, R (Call::*)(Hdl<T>, Derived*), method,
444
+ absl::enable_if_t<StatusOrType<R, Hdl<T>>::value, void>> {
445
+ public:
446
+ explicit AdaptMethod(Call* call, Derived* filter)
447
+ : call_(call), filter_(filter) {}
448
+ auto operator()(Hdl<T> x) {
449
+ R result = (call_->*method)(std::move(x), filter_);
450
+ if (IsStatusOk(result)) {
451
+ return Immediate(ServerMetadataOrHandle<T>::Ok(std::move(*result)));
452
+ }
453
+
454
+ return Immediate(ServerMetadataOrHandle<T>::Failure(
455
+ ServerMetadataFromStatus(result.status())));
456
+ }
457
+
458
+ private:
459
+ Call* call_;
460
+ Derived* filter_;
461
+ };
462
+
463
+ // For methods which return a promise where the result of the promise
464
+ template <typename T, typename R, typename Call, typename Derived,
465
+ R (Call::*method)(Hdl<T>, Derived*)>
466
+ class AdaptMethod<
467
+ T, R (Call::*)(Hdl<T>, Derived*), method,
468
+ std::enable_if_t<IsPromise<R> && std::is_same_v<PromiseResult<R>,
469
+ absl::StatusOr<Hdl<T>>>,
470
+ void>> {
471
+ public:
472
+ explicit AdaptMethod(Call* call, Derived* filter)
473
+ : call_(call), filter_(filter) {}
474
+ auto operator()(Hdl<T> x) {
475
+ return Map((call_->*method)(std::move(x), filter_),
476
+ [](absl::StatusOr<Hdl<T>> result) {
477
+ if (result.ok()) {
478
+ return ServerMetadataOrHandle<T>::Ok(std::move(*result));
479
+ }
480
+ return ServerMetadataOrHandle<T>::Failure(
481
+ ServerMetadataFromStatus(result.status()));
482
+ });
483
+ }
484
+
485
+ private:
486
+ Call* call_;
487
+ Derived* filter_;
488
+ };
489
+
490
+ template <typename T, typename R, typename Call, typename Derived,
491
+ R (Call::*method)(T&, Derived*)>
492
+ class AdaptMethod<
493
+ T, R (Call::*)(T&, Derived*), method,
494
+ std::enable_if_t<
495
+ IsPromise<R> && std::is_same_v<absl::Status, PromiseResult<R>>, void>> {
496
+ public:
497
+ explicit AdaptMethod(Call* call, Derived* filter)
498
+ : call_(call), filter_(filter) {}
499
+ auto operator()(Hdl<T> x) {
500
+ return Map((call_->*method)(*x, filter_),
501
+ [hdl = std::move(x)](absl::Status status) mutable {
502
+ if (status.ok()) {
503
+ return ServerMetadataOrHandle<T>::Ok(std::move(hdl));
504
+ }
505
+ return ServerMetadataOrHandle<T>::Failure(
506
+ ServerMetadataFromStatus(status));
507
+ });
508
+ }
509
+
510
+ private:
511
+ Call* call_;
512
+ Derived* filter_;
513
+ };
514
+
515
+ template <typename T, typename Call, typename Derived,
516
+ Hdl<T> (Call::*method)(Hdl<T>, Derived*)>
517
+ class AdaptMethod<T, Hdl<T> (Call::*)(Hdl<T>, Derived*), method> {
518
+ public:
519
+ explicit AdaptMethod(Call* call, Derived* filter)
520
+ : call_(call), filter_(filter) {}
521
+ auto operator()(Hdl<T> x) {
522
+ Hdl<T> result = (call_->*method)(std::move(x), filter_);
523
+ return Immediate(ServerMetadataOrHandle<T>::Ok(std::move(result)));
524
+ }
525
+
526
+ private:
527
+ Call* call_;
528
+ Derived* filter_;
529
+ };
530
+
531
+ // Overrides for filter methods which return a ServerMetadataHandle type as
532
+ // output.
533
+ template <typename T, typename A, typename Call,
534
+ ServerMetadataHandle (Call::*method)(A)>
535
+ class AdaptMethod<T, ServerMetadataHandle (Call::*)(A), method,
536
+ EnableIfSameExcludingCVRef<T, A>> {
537
+ public:
538
+ explicit AdaptMethod(Call* call, void* /*filter*/ = nullptr) : call_(call) {}
539
+ auto operator()(Hdl<T> x) {
540
+ ServerMetadataHandle handle = (call_->*method)(*x);
541
+ if (handle == nullptr) {
542
+ return Immediate(ServerMetadataOrHandle<T>::Ok(std::move(x)));
543
+ }
544
+
545
+ return Immediate(ServerMetadataOrHandle<T>::Failure(std::move(handle)));
546
+ }
547
+
548
+ private:
549
+ Call* call_;
550
+ };
551
+
552
+ template <typename T, typename Call, ServerMetadataHandle (Call::*method)()>
553
+ class AdaptMethod<T, ServerMetadataHandle (Call::*)(), method> {
554
+ public:
555
+ explicit AdaptMethod(Call* call, void* /*filter*/ = nullptr) : call_(call) {}
556
+ auto operator()(Hdl<T> x) {
557
+ ServerMetadataHandle handle = (call_->*method)();
558
+ if (handle == nullptr) {
559
+ return Immediate(ServerMetadataOrHandle<T>::Ok(std::move(x)));
560
+ }
561
+
562
+ return Immediate(ServerMetadataOrHandle<T>::Failure(std::move(handle)));
563
+ }
564
+
565
+ private:
566
+ Call* call_;
567
+ };
568
+
569
+ template <typename T, typename A, typename Call, typename Derived,
570
+ ServerMetadataHandle (Call::*method)(A, Derived*)>
571
+ class AdaptMethod<T, ServerMetadataHandle (Call::*)(A, Derived*), method,
572
+ EnableIfSameExcludingCVRef<T, A>> {
573
+ public:
574
+ explicit AdaptMethod(Call* call, Derived* filter)
575
+ : call_(call), filter_(filter) {}
576
+ auto operator()(Hdl<T> x) {
577
+ ServerMetadataHandle handle = (call_->*method)(*x, filter_);
578
+ if (handle == nullptr) {
579
+ return Immediate(ServerMetadataOrHandle<T>::Ok(std::move(x)));
580
+ }
581
+
582
+ return Immediate(ServerMetadataOrHandle<T>::Failure(std::move(handle)));
583
+ }
584
+
585
+ private:
586
+ Call* call_;
587
+ Derived* filter_;
588
+ };
589
+
590
+ template <typename T, typename MethodType, MethodType method,
591
+ typename Ignored = void>
592
+ class AdaptOnServerTrailingMetadataMethod;
593
+
594
+ template <typename T, const NoInterceptor* method>
595
+ class AdaptOnServerTrailingMetadataMethod<T, const NoInterceptor*, method> {
596
+ public:
597
+ explicit AdaptOnServerTrailingMetadataMethod(void* /*call*/,
598
+ void* /*filter*/ = nullptr) {}
599
+ auto operator()(T& /*x*/) {}
600
+ void operator()(T* /*x*/) {}
601
+ };
602
+
603
+ template <typename T, typename A, typename Call, typename Derived,
604
+ void (Call::*method)(A, Derived*)>
605
+ class AdaptOnServerTrailingMetadataMethod<
606
+ T, void (Call::*)(A, Derived*), method, EnableIfSameExcludingCVRef<T, A>> {
607
+ public:
608
+ explicit AdaptOnServerTrailingMetadataMethod(Call* call, Derived* filter)
609
+ : call_(call), filter_(filter) {}
610
+ void operator()(T& x) { (call_->*method)(x, filter_); }
611
+
612
+ private:
613
+ Call* call_;
614
+ Derived* filter_;
615
+ };
616
+
617
+ template <typename T, typename A, typename Call, typename Derived,
618
+ absl::Status (Call::*method)(A, Derived*)>
619
+ class AdaptOnServerTrailingMetadataMethod<
620
+ T, absl::Status (Call::*)(A, Derived*), method,
621
+ EnableIfSameExcludingCVRef<T, A>> {
622
+ public:
623
+ explicit AdaptOnServerTrailingMetadataMethod(Call* call, Derived* filter)
624
+ : call_(call), filter_(filter) {}
625
+ void operator()(T& x) {
626
+ absl::Status status = (call_->*method)(x, filter_);
627
+ if (!status.ok()) {
628
+ SetServerMetadataFromStatus(x, status);
629
+ }
630
+ }
631
+
632
+ private:
633
+ Call* call_;
634
+ Derived* filter_;
635
+ };
636
+
637
+ template <typename T, typename A, typename Call, void (Call::*method)(A)>
638
+ class AdaptOnServerTrailingMetadataMethod<T, void (Call::*)(A), method,
639
+ EnableIfSameExcludingCVRef<T, A>> {
640
+ public:
641
+ explicit AdaptOnServerTrailingMetadataMethod(Call* call, void* /*filter*/)
642
+ : call_(call) {}
643
+ void operator()(T& x) { (call_->*method)(x); }
644
+
645
+ private:
646
+ Call* call_;
647
+ };
648
+
649
+ template <typename T, typename A, typename Call,
650
+ absl::Status (Call::*method)(A)>
651
+ class AdaptOnServerTrailingMetadataMethod<T, absl::Status (Call::*)(A), method,
652
+ EnableIfSameExcludingCVRef<T, A>> {
653
+ public:
654
+ explicit AdaptOnServerTrailingMetadataMethod(Call* call, void* /*filter*/)
655
+ : call_(call) {}
656
+ void operator()(T& x) {
657
+ absl::Status status = (call_->*method)(x);
658
+ if (!status.ok()) {
659
+ SetServerMetadataFromStatus(x, status);
660
+ }
661
+ }
662
+
663
+ private:
664
+ Call* call_;
665
+ };
666
+
667
+ template <typename MethodType, MethodType method, typename Ignored = void>
668
+ class AdaptOnClientToServerHalfCloseMethod;
669
+
670
+ template <const NoInterceptor* method>
671
+ class AdaptOnClientToServerHalfCloseMethod<const NoInterceptor*, method> {
672
+ public:
673
+ explicit AdaptOnClientToServerHalfCloseMethod(void* /*call*/) {}
674
+ void operator()() {}
675
+ };
676
+
677
+ template <typename Call, void (Call::*method)()>
678
+ class AdaptOnClientToServerHalfCloseMethod<void (Call::*)(), method> {
679
+ public:
680
+ explicit AdaptOnClientToServerHalfCloseMethod(Call* call) : call_(call) {}
681
+ void operator()() { (call_->*method)(); }
682
+
683
+ private:
684
+ Call* call_;
685
+ };
686
+
687
+ template <auto... filter_methods>
688
+ struct FilterMethods {
689
+ using Methods = Valuelist<filter_methods...>;
690
+ using Idxs = std::make_index_sequence<sizeof...(filter_methods)>;
691
+ };
692
+
693
+ template <typename... Filters>
694
+ struct FilterTypes {
695
+ using Types = Typelist<Filters...>;
696
+ using Idxs = std::make_index_sequence<sizeof...(Filters)>;
697
+ };
698
+
699
+ template <std::size_t, typename FilterTypeList, typename Ignored = void>
700
+ struct TypesFromIdx;
701
+
702
+ template <typename... Filters>
703
+ struct TypesFromIdx<0, Typelist<Filters...>> {
704
+ using Types = Typelist<Filters...>;
705
+ };
706
+
707
+ template <std::size_t N, typename Filter0, typename... Filters>
708
+ struct TypesFromIdx<N, Typelist<Filter0, Filters...>,
709
+ std::enable_if_t<N != 0>> {
710
+ using Types = typename TypesFromIdx<N - 1, Typelist<Filters...>>::Types;
711
+ };
712
+
713
+ template <std::size_t, typename>
714
+ struct make_reverse_index_sequence_helper;
715
+
716
+ template <std::size_t N, std::size_t... NN>
717
+ struct make_reverse_index_sequence_helper<N, std::index_sequence<NN...>>
718
+ : std::index_sequence<(N - NN)...> {};
719
+
720
+ template <size_t N>
721
+ struct make_reverse_index_sequence
722
+ : make_reverse_index_sequence_helper<
723
+ N - 1, decltype(std::make_index_sequence<N>{})> {};
724
+
725
+ template <auto... filter_methods>
726
+ struct ReverseFilterMethods {
727
+ using Methods = ReverseValues<filter_methods...>;
728
+ using Idxs = make_reverse_index_sequence<sizeof...(filter_methods)>;
729
+ };
730
+
731
+ template <typename... Filters>
732
+ struct ReverseFilterTypes {
733
+ using Types = Reverse<Filters...>;
734
+ using Idxs = make_reverse_index_sequence<sizeof...(Filters)>;
735
+ template <bool forward, auto... filter_methods>
736
+ struct ForwardOrReverse;
737
+ };
738
+
739
+ template <bool forward, auto... filter_methods>
740
+ struct ForwardOrReverse;
741
+
742
+ template <auto... filter_methods>
743
+ struct ForwardOrReverse<true, filter_methods...> {
744
+ using OrderMethod = FilterMethods<filter_methods...>;
745
+ };
746
+
747
+ template <auto... filter_methods>
748
+ struct ForwardOrReverse<false, filter_methods...> {
749
+ using OrderMethod = ReverseFilterMethods<filter_methods...>;
750
+ };
751
+
752
+ template <bool forward, typename... filter_types>
753
+ struct ForwardOrReverseTypes;
754
+
755
+ template <typename... filter_types>
756
+ struct ForwardOrReverseTypes<true, filter_types...> {
757
+ using OrderMethod = FilterTypes<filter_types...>;
758
+ };
759
+
760
+ template <typename... filter_types>
761
+ struct ForwardOrReverseTypes<false, filter_types...> {
762
+ using OrderMethod = ReverseFilterTypes<filter_types...>;
763
+ };
764
+
765
+ // Combine the result of a series of filter methods into a single method.
766
+ template <typename Call, typename T, auto filter_method_0,
767
+ auto... filter_methods, size_t I0, size_t... Is>
768
+ auto ExecuteCombined(Call* call, Hdl<T> hdl,
769
+ Valuelist<filter_method_0, filter_methods...>,
770
+ std::index_sequence<I0, Is...>) {
771
+ return TrySeq(AdaptMethod<T, decltype(filter_method_0), filter_method_0>(
772
+ call->template fused_child<I0>())(std::move(hdl)),
773
+ AdaptMethod<T, decltype(filter_methods), filter_methods>(
774
+ call->template fused_child<Is>())...);
775
+ }
776
+
777
+ template <typename FilterMethods, typename Call, typename T>
778
+ auto ExecuteCombined(Call* call, Hdl<T> hdl) {
779
+ return ExecuteCombined(call, std::move(hdl),
780
+ typename FilterMethods::Methods(),
781
+ typename FilterMethods::Idxs());
782
+ }
783
+
784
+ // Combine the result of a series of filter methods into a single method.
785
+ template <typename Call, typename Derived, typename T, typename Filter0,
786
+ typename... Filters, auto filter_method_0, auto... filter_methods,
787
+ size_t I0, size_t... Is>
788
+ auto ExecuteCombinedWithChannelAccess(
789
+ Call* call, Derived* channel, Hdl<T> hdl, Typelist<Filter0, Filters...>,
790
+ Valuelist<filter_method_0, filter_methods...>,
791
+ std::index_sequence<I0, Is...>) {
792
+ return TrySeq(
793
+ AdaptMethod<T, decltype(filter_method_0), filter_method_0>(
794
+ call->template fused_child<I0>(),
795
+ reinterpret_cast<Filter0*>(channel->template get_fused_filter<I0>()))(
796
+ std::move(hdl)),
797
+ AdaptMethod<T, decltype(filter_methods), filter_methods>(
798
+ call->template fused_child<Is>(),
799
+ reinterpret_cast<Filters*>(
800
+ channel->template get_fused_filter<Is>()))...);
801
+ }
802
+
803
+ template <typename FilterMethods, typename FilterTypes, typename Call,
804
+ typename Derived, typename T>
805
+ auto ExecuteCombinedWithChannelAccess(Call* call, Derived* channel,
806
+ Hdl<T> hdl) {
807
+ return ExecuteCombinedWithChannelAccess(
808
+ call, channel, std::move(hdl), typename FilterTypes::Types(),
809
+ typename FilterMethods::Methods(), typename FilterMethods::Idxs());
810
+ }
811
+
812
+ // Combine the result of a series of OnFinalize filter methods into a single
813
+ // method.
814
+ template <typename Call, typename Derived, typename T, typename... Filters,
815
+ auto... filter_methods, size_t... Is>
816
+ void ExecuteCombinedOnFinalizeWithChannelAccess(Call* call, Derived* channel,
817
+ T* call_final_info,
818
+ Typelist<Filters...>,
819
+ Valuelist<filter_methods...>,
820
+ std::index_sequence<Is...>) {
821
+ (AdaptMethod<T, decltype(filter_methods), filter_methods>(
822
+ call->template fused_child<Is>(),
823
+ reinterpret_cast<Filters*>(channel->template get_fused_filter<Is>()))(
824
+ call_final_info),
825
+ ...);
826
+ }
827
+
828
+ template <typename Call, typename T, auto... filter_methods, size_t... Is>
829
+ void ExecuteCombinedOnFinalize(Call* call, T* call_final_info,
830
+ Valuelist<filter_methods...>,
831
+ std::index_sequence<Is...>) {
832
+ (AdaptMethod<T, decltype(filter_methods), filter_methods>(
833
+ call->template fused_child<Is>(), nullptr)(call_final_info),
834
+ ...);
835
+ }
836
+
837
+ // Combine the result of a series of OnServerTrailingMetadata filter methods
838
+ // into a single method.
839
+ template <typename Call, typename Derived, typename T, typename... Filters,
840
+ auto... filter_methods, size_t... Is>
841
+ void ExecuteCombinedOnServerTrailingMetadataWithChannelAccess(
842
+ Call* call, Derived* channel, T& metadata, Typelist<Filters...>,
843
+ Valuelist<filter_methods...>, std::index_sequence<Is...>) {
844
+ (AdaptOnServerTrailingMetadataMethod<T, decltype(filter_methods),
845
+ filter_methods>(
846
+ call->template fused_child<Is>(),
847
+ reinterpret_cast<Filters*>(channel->template get_fused_filter<Is>()))(
848
+ metadata),
849
+ ...);
850
+ }
851
+
852
+ template <typename FilterMethods, typename FilterTypes, typename Call,
853
+ typename Derived, typename T>
854
+ void ExecuteCombinedOnServerTrailingMetadataWithChannelAccess(Call* call,
855
+ Derived* channel,
856
+ T& metadata) {
857
+ ExecuteCombinedOnServerTrailingMetadataWithChannelAccess(
858
+ call, channel, metadata, typename FilterTypes::Types(),
859
+ typename FilterMethods::Methods(), typename FilterMethods::Idxs());
860
+ }
861
+
862
+ template <typename Call, typename T, auto... filter_methods, size_t... Is>
863
+ void ExecuteCombinedOnServerTrailingMetadata(Call* call, T& metadata,
864
+ Valuelist<filter_methods...>,
865
+ std::index_sequence<Is...>) {
866
+ (AdaptOnServerTrailingMetadataMethod<T, decltype(filter_methods),
867
+ filter_methods>(
868
+ call->template fused_child<Is>(), nullptr)(metadata),
869
+ ...);
870
+ }
871
+
872
+ template <typename FilterMethods, typename Call, typename T>
873
+ void ExecuteCombinedOnServerTrailingMetadata(Call* call, T& metadata) {
874
+ ExecuteCombinedOnServerTrailingMetadata(call, metadata,
875
+ typename FilterMethods::Methods(),
876
+ typename FilterMethods::Idxs());
877
+ }
878
+
879
+ template <typename Call, auto... filter_methods, size_t... Is>
880
+ void ExecuteCombinedOnClientToServerHalfClose(Call* call,
881
+ Valuelist<filter_methods...>,
882
+ std::index_sequence<Is...>) {
883
+ (AdaptOnClientToServerHalfCloseMethod<decltype(filter_methods),
884
+ filter_methods>(
885
+ call->template fused_child<Is>())(),
886
+ ...);
887
+ }
888
+
889
+ template <typename FilterMethods, typename Call>
890
+ void ExecuteCombinedOnClientToServerHalfClose(Call* call) {
891
+ ExecuteCombinedOnClientToServerHalfClose(
892
+ call, typename FilterMethods::Methods(), typename FilterMethods::Idxs());
893
+ }
894
+
895
+ template <typename FilterMethods, typename FilterTypes, typename Call,
896
+ typename Derived, typename T>
897
+ void ExecuteCombinedWithChannelAccess(Call* call, Derived* channel,
898
+ T* call_final_info) {
899
+ ExecuteCombinedOnFinalizeWithChannelAccess(
900
+ call, channel, call_final_info, typename FilterTypes::Types(),
901
+ typename FilterMethods::Methods(), typename FilterMethods::Idxs());
902
+ }
903
+
904
+ template <typename FilterMethods, typename Call, typename T>
905
+ void ExecuteCombined(Call* call, T* call_final_info) {
906
+ ExecuteCombinedOnFinalize(call, call_final_info,
907
+ typename FilterMethods::Methods(),
908
+ typename FilterMethods::Idxs());
909
+ }
910
+
911
+ #define GRPC_FUSE_METHOD(name, type, forward) \
912
+ template <MethodVariant variant, typename Derived, typename... Filters> \
913
+ class FuseImpl##name; \
914
+ template <typename Derived, typename... Filters> \
915
+ class FuseImpl##name<MethodVariant::kNoInterceptor, Derived, Filters...> { \
916
+ public: \
917
+ static inline const NoInterceptor name; \
918
+ }; \
919
+ template <typename Derived, typename... Filters> \
920
+ class FuseImpl##name<MethodVariant::kSimple, Derived, Filters...> { \
921
+ public: \
922
+ auto name(type x) { \
923
+ return ExecuteCombined<typename ForwardOrReverse< \
924
+ forward, &Filters::Call::name...>::OrderMethod>( \
925
+ static_cast<typename Derived::Call*>(this), std::move(x)); \
926
+ } \
927
+ }; \
928
+ template <typename Derived, typename... Filters> \
929
+ class FuseImpl##name<MethodVariant::kChannelAccess, Derived, Filters...> { \
930
+ public: \
931
+ auto name(type x, Derived* channel) { \
932
+ return ExecuteCombinedWithChannelAccess< \
933
+ typename ForwardOrReverse<forward, \
934
+ &Filters::Call::name...>::OrderMethod, \
935
+ typename ForwardOrReverseTypes<forward, Filters...>::OrderMethod>( \
936
+ static_cast<typename Derived::Call*>(this), channel, std::move(x)); \
937
+ } \
938
+ }; \
939
+ template <typename Derived, typename... Filters> \
940
+ using Fuse##name = FuseImpl##name< \
941
+ MethodVariantForFilters<decltype(&Filters::Call::name)...>(), Derived, \
942
+ Filters...>
943
+
944
+ template <MethodVariant variant, typename Derived, typename... Filters>
945
+ class FuseImplOnServerTrailingMetadata;
946
+
947
+ template <typename Derived, typename... Filters>
948
+ class FuseImplOnServerTrailingMetadata<MethodVariant::kNoInterceptor, Derived,
949
+ Filters...> {
950
+ public:
951
+ static inline const NoInterceptor OnServerTrailingMetadata;
952
+ };
953
+
954
+ template <typename Derived, typename... Filters>
955
+ class FuseImplOnServerTrailingMetadata<MethodVariant::kSimple, Derived,
956
+ Filters...> {
957
+ public:
958
+ void OnServerTrailingMetadata(ServerMetadata& x) {
959
+ return ExecuteCombinedOnServerTrailingMetadata<typename ForwardOrReverse<
960
+ false, &Filters::Call::OnServerTrailingMetadata...>::OrderMethod>(
961
+ static_cast<typename Derived::Call*>(this), x);
962
+ }
963
+ };
964
+
965
+ template <typename Derived, typename... Filters>
966
+ class FuseImplOnServerTrailingMetadata<MethodVariant::kChannelAccess, Derived,
967
+ Filters...> {
968
+ public:
969
+ void OnServerTrailingMetadata(ServerMetadata& x, Derived* channel) {
970
+ return ExecuteCombinedOnServerTrailingMetadataWithChannelAccess<
971
+ typename ForwardOrReverse<
972
+ false, &Filters::Call::OnServerTrailingMetadata...>::OrderMethod,
973
+ typename ForwardOrReverseTypes<false, Filters...>::OrderMethod>(
974
+ static_cast<typename Derived::Call*>(this), channel, x);
975
+ }
976
+ };
977
+
978
+ template <typename Derived, typename... Filters>
979
+ using FuseOnServerTrailingMetadata = FuseImplOnServerTrailingMetadata<
980
+ MethodVariantForFilters<
981
+ decltype(&Filters::Call::OnServerTrailingMetadata)...>(),
982
+ Derived, Filters...>;
983
+
984
+ template <bool is_no_interceptor, typename Derived, typename... Filters>
985
+ class FuseImplOnClientToServerHalfClose;
986
+
987
+ template <typename Derived, typename... Filters>
988
+ class FuseImplOnClientToServerHalfClose<true, Derived, Filters...> {
989
+ public:
990
+ static inline const NoInterceptor OnClientToServerHalfClose;
991
+ };
992
+
993
+ template <typename Derived, typename... Filters>
994
+ class FuseImplOnClientToServerHalfClose<false, Derived, Filters...> {
995
+ public:
996
+ void OnClientToServerHalfClose() {
997
+ return ExecuteCombinedOnClientToServerHalfClose<typename ForwardOrReverse<
998
+ true, &Filters::Call::OnClientToServerHalfClose...>::OrderMethod>(
999
+ static_cast<typename Derived::Call*>(this));
1000
+ }
1001
+ };
1002
+
1003
+ template <typename Derived, typename... Filters>
1004
+ using FuseOnClientToServerHalfClose = FuseImplOnClientToServerHalfClose<
1005
+ AllNoInterceptor<decltype(&Filters::Call::OnClientToServerHalfClose)...>,
1006
+ Derived, Filters...>;
1007
+
1008
+ GRPC_FUSE_METHOD(OnClientInitialMetadata, ClientMetadataHandle, true);
1009
+ GRPC_FUSE_METHOD(OnServerInitialMetadata, ServerMetadataHandle, false);
1010
+ GRPC_FUSE_METHOD(OnClientToServerMessage, MessageHandle, true);
1011
+ GRPC_FUSE_METHOD(OnServerToClientMessage, MessageHandle, false);
1012
+ GRPC_FUSE_METHOD(OnFinalize, const grpc_call_final_info*, true);
1013
+
1014
+ template <typename FilterTypelist>
1015
+ struct FilterWrapper;
1016
+
1017
+ template <typename Filter>
1018
+ struct FilterWrapper<Typelist<Filter>> {
1019
+ FilterWrapper(const ChannelArgs& args, ChannelFilter::Args filter_args)
1020
+ : filter_(Filter::Create(args, filter_args)) {}
1021
+
1022
+ absl::Status status() const { return filter_.status(); }
1023
+ bool StartTransportOp(grpc_transport_op* op) {
1024
+ CHECK(filter_.ok());
1025
+ return (*filter_)->StartTransportOp(op);
1026
+ }
1027
+
1028
+ Filter* get_filter() { return (*filter_).get(); }
1029
+
1030
+ bool GetChannelInfo(const grpc_channel_info* info) {
1031
+ CHECK(filter_.ok());
1032
+ return (*filter_)->GetChannelInfo(info);
1033
+ }
1034
+
1035
+ private:
1036
+ absl::StatusOr<std::unique_ptr<Filter>> filter_;
1037
+ };
1038
+
1039
+ template <typename Filter0, typename... Filters>
1040
+ struct FilterWrapper<Typelist<Filter0, Filters...>>
1041
+ : public FilterWrapper<Typelist<Filters...>> {
1042
+ FilterWrapper(const ChannelArgs& args, ChannelFilter::Args filter_args)
1043
+ : FilterWrapper<Typelist<Filters...>>(args, filter_args),
1044
+ filter0_(Filter0::Create(args, filter_args)) {}
1045
+
1046
+ absl::Status status() const {
1047
+ if (filter0_.ok()) {
1048
+ return FilterWrapper<Typelist<Filters...>>::status();
1049
+ }
1050
+ return filter0_.status();
1051
+ }
1052
+
1053
+ Filter0* get_filter() { return (*filter0_).get(); }
1054
+
1055
+ bool StartTransportOp(grpc_transport_op* op) {
1056
+ CHECK(filter0_.ok());
1057
+ return (*filter0_)->StartTransportOp(op) ||
1058
+ FilterWrapper<Typelist<Filters...>>::StartTransportOp(op);
1059
+ }
1060
+
1061
+ bool GetChannelInfo(const grpc_channel_info* info) {
1062
+ CHECK(filter0_.ok());
1063
+ return (*filter0_)->GetChannelInfo(info) ||
1064
+ FilterWrapper<Typelist<Filters...>>::GetChannelInfo(info);
1065
+ }
1066
+
1067
+ private:
1068
+ absl::StatusOr<std::unique_ptr<Filter0>> filter0_;
1069
+ };
1070
+
1071
+ template <typename Derived, typename SfinaeVoid = void>
1072
+ struct ConstructCall;
1073
+
1074
+ template <typename Derived>
1075
+ struct ConstructCall<Derived, absl::void_t<decltype(typename Derived::Call(
1076
+ std::declval<Derived*>()))>> {
1077
+ public:
1078
+ using Call = typename Derived::Call;
1079
+ static void Run(ManualConstructor<Call>& call, Derived* channel) {
1080
+ call.Init(channel);
1081
+ }
1082
+ };
1083
+
1084
+ template <typename Derived>
1085
+ struct ConstructCall<Derived,
1086
+ absl::void_t<decltype(typename Derived::Call())>> {
1087
+ public:
1088
+ using Call = typename Derived::Call;
1089
+ static void Run(ManualConstructor<Call>& call, Derived* /*channel*/) {
1090
+ call.Init();
1091
+ }
1092
+ };
1093
+
1094
+ template <typename FilterTypelist>
1095
+ struct CallWrapper;
1096
+
1097
+ template <typename Filter>
1098
+ struct CallWrapper<Typelist<Filter>> {
1099
+ using Call = typename Filter::Call;
1100
+ explicit CallWrapper(FilterWrapper<Typelist<Filter>>* channel) {
1101
+ ConstructCall<Filter>::Run(call_, channel->get_filter());
1102
+ }
1103
+
1104
+ Call* get_call() { return call_.get(); }
1105
+
1106
+ ~CallWrapper() { call_.Destroy(); }
1107
+
1108
+ private:
1109
+ ManualConstructor<Call> call_;
1110
+ };
1111
+
1112
+ template <typename Filter0, typename... Filters>
1113
+ struct CallWrapper<Typelist<Filter0, Filters...>>
1114
+ : public CallWrapper<Typelist<Filters...>> {
1115
+ using Call = typename Filter0::Call;
1116
+ explicit CallWrapper(FilterWrapper<Typelist<Filter0, Filters...>>* channel)
1117
+ : CallWrapper<Typelist<Filters...>>(
1118
+ reinterpret_cast<FilterWrapper<Typelist<Filters...>>*>(channel)) {
1119
+ ConstructCall<Filter0>::Run(call_, channel->get_filter());
1120
+ }
1121
+
1122
+ Call* get_call() { return call_.get(); }
1123
+
1124
+ ~CallWrapper() { call_.Destroy(); }
1125
+
1126
+ private:
1127
+ ManualConstructor<Call> call_;
1128
+ };
1129
+
1130
+ #undef GRPC_FUSE_METHOD
1131
+
1132
+ template <FilterEndpoint ep, uint8_t kFlags, typename... Filters>
1133
+ class FusedFilter
1134
+ : public ImplementChannelFilter<FusedFilter<ep, kFlags, Filters...>> {
1135
+ public:
1136
+ static const grpc_channel_filter kFilter;
1137
+
1138
+ static absl::string_view TypeName() {
1139
+ static const std::string kName =
1140
+ absl::StrCat(absl::StrJoin(std::tuple(Filters::TypeName()...), "+"));
1141
+ return kName;
1142
+ }
1143
+
1144
+ template <size_t I>
1145
+ auto* get_fused_filter() {
1146
+ return reinterpret_cast<FilterWrapper<
1147
+ typename TypesFromIdx<I, Typelist<Filters...>>::Types>*>(filters_.get())
1148
+ ->get_filter();
1149
+ }
1150
+
1151
+ FilterWrapper<Typelist<Filters...>>* get_wrapper() { return filters_.get(); }
1152
+
1153
+ static absl::StatusOr<std::unique_ptr<FusedFilter<ep, kFlags, Filters...>>>
1154
+ Create(const ChannelArgs& args, ChannelFilter::Args filter_args) {
1155
+ auto filters_wrapper =
1156
+ std::make_unique<FilterWrapper<Typelist<Filters...>>>(args,
1157
+ filter_args);
1158
+ GRPC_RETURN_IF_ERROR(filters_wrapper->status());
1159
+ return absl::WrapUnique<FusedFilter<ep, kFlags, Filters...>>(
1160
+ new FusedFilter<ep, kFlags, Filters...>(std::move(filters_wrapper)));
1161
+ }
1162
+
1163
+ static constexpr bool IsFused = true;
1164
+
1165
+ class Call : public FuseOnClientInitialMetadata<FusedFilter, Filters...>,
1166
+ public FuseOnServerInitialMetadata<FusedFilter, Filters...>,
1167
+ public FuseOnClientToServerMessage<FusedFilter, Filters...>,
1168
+ public FuseOnServerToClientMessage<FusedFilter, Filters...>,
1169
+ public FuseOnServerTrailingMetadata<FusedFilter, Filters...>,
1170
+ public FuseOnClientToServerHalfClose<FusedFilter, Filters...>,
1171
+ public FuseOnFinalize<FusedFilter, Filters...> {
1172
+ public:
1173
+ using Idxs = std::make_index_sequence<sizeof...(Filters)>;
1174
+ template <size_t I>
1175
+ auto* fused_child() {
1176
+ return reinterpret_cast<CallWrapper<
1177
+ typename TypesFromIdx<I, Typelist<Filters...>>::Types>*>(
1178
+ &filter_calls_)
1179
+ ->get_call();
1180
+ }
1181
+
1182
+ explicit Call(FusedFilter<ep, kFlags, Filters...>* filter)
1183
+ : filter_calls_(filter->get_wrapper()) {};
1184
+
1185
+ using FuseOnClientInitialMetadata<FusedFilter,
1186
+ Filters...>::OnClientInitialMetadata;
1187
+ using FuseOnServerInitialMetadata<FusedFilter,
1188
+ Filters...>::OnServerInitialMetadata;
1189
+ using FuseOnClientToServerMessage<FusedFilter,
1190
+ Filters...>::OnClientToServerMessage;
1191
+ using FuseOnServerToClientMessage<FusedFilter,
1192
+ Filters...>::OnServerToClientMessage;
1193
+ using FuseOnServerTrailingMetadata<FusedFilter,
1194
+ Filters...>::OnServerTrailingMetadata;
1195
+ using FuseOnClientToServerHalfClose<FusedFilter,
1196
+ Filters...>::OnClientToServerHalfClose;
1197
+ using FuseOnFinalize<FusedFilter, Filters...>::OnFinalize;
1198
+
1199
+ private:
1200
+ CallWrapper<Typelist<Filters...>> filter_calls_;
1201
+ };
1202
+
1203
+ bool StartTransportOp(grpc_transport_op* op) override {
1204
+ return filters_->StartTransportOp(op);
1205
+ }
1206
+
1207
+ bool GetChannelInfo(const grpc_channel_info* info) override {
1208
+ return filters_->GetChannelInfo(info);
1209
+ }
1210
+
1211
+ private:
1212
+ explicit FusedFilter(
1213
+ std::unique_ptr<FilterWrapper<Typelist<Filters...>>> filters)
1214
+ : filters_(std::move(filters)) {};
1215
+
1216
+ std::unique_ptr<FilterWrapper<Typelist<Filters...>>> filters_;
1217
+ };
1218
+
1219
+ template <FilterEndpoint ep, uint8_t kFlags, typename... Filters>
1220
+ const grpc_channel_filter FusedFilter<ep, kFlags, Filters...>::kFilter =
1221
+ MakePromiseBasedFilter<FusedFilter<ep, kFlags, Filters...>, ep, kFlags>();
1222
+
1223
+ } // namespace filters_detail
1224
+
1225
+ template <FilterEndpoint ep, uint8_t kFlags, typename... Filters>
1226
+ using FusedFilter = filters_detail::FusedFilter<ep, kFlags, Filters...>;
1227
+
1228
+ } // namespace grpc_core
1229
+
1230
+ #endif // GRPC_SRC_CORE_CALL_FILTER_FUSION_H