grpc 1.60.2 → 1.61.0.pre2

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 (279) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +208 -165
  3. data/include/grpc/event_engine/event_engine.h +59 -12
  4. data/include/grpc/event_engine/internal/memory_allocator_impl.h +6 -0
  5. data/include/grpc/event_engine/internal/slice_cast.h +12 -0
  6. data/include/grpc/event_engine/memory_allocator.h +3 -1
  7. data/include/grpc/event_engine/slice.h +5 -0
  8. data/include/grpc/grpc_security.h +22 -1
  9. data/include/grpc/impl/call.h +29 -0
  10. data/include/grpc/impl/channel_arg_names.h +12 -1
  11. data/include/grpc/impl/slice_type.h +1 -1
  12. data/include/grpc/module.modulemap +1 -0
  13. data/src/core/ext/filters/backend_metrics/backend_metric_filter.cc +54 -7
  14. data/src/core/ext/filters/backend_metrics/backend_metric_filter.h +20 -6
  15. data/src/core/ext/filters/channel_idle/channel_idle_filter.cc +10 -13
  16. data/src/core/ext/filters/channel_idle/channel_idle_filter.h +18 -10
  17. data/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.cc +326 -0
  18. data/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.h +143 -0
  19. data/src/core/ext/filters/client_channel/backend_metric.cc +2 -2
  20. data/src/core/ext/filters/client_channel/client_channel.cc +32 -6
  21. data/src/core/ext/filters/client_channel/client_channel_internal.h +2 -0
  22. data/src/core/ext/filters/client_channel/global_subchannel_pool.cc +1 -1
  23. data/src/core/ext/filters/client_channel/lb_policy/address_filtering.cc +54 -21
  24. data/src/core/ext/filters/client_channel/lb_policy/address_filtering.h +3 -2
  25. data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc +2 -1
  26. data/src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc +12 -15
  27. data/src/core/ext/filters/client_channel/lb_policy/endpoint_list.h +8 -5
  28. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +139 -92
  29. data/src/core/ext/filters/client_channel/lb_policy/health_check_client.cc +9 -4
  30. data/src/core/ext/filters/client_channel/lb_policy/oob_backend_metric.cc +9 -4
  31. data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.cc +10 -11
  32. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +94 -93
  33. data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +5 -3
  34. data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +12 -15
  35. data/src/core/ext/filters/client_channel/lb_policy/rls/rls.cc +38 -16
  36. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +25 -28
  37. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +10 -10
  38. data/src/core/ext/filters/client_channel/lb_policy/weighted_round_robin/weighted_round_robin.cc +37 -35
  39. data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +11 -9
  40. data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +504 -461
  41. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc +232 -122
  42. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +8 -6
  43. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.cc +642 -251
  44. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.h +2 -6
  45. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_wrr_locality.cc +7 -8
  46. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +2 -1
  47. data/src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc +3 -1
  48. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +2 -2
  49. data/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc +2 -2
  50. data/src/core/ext/filters/client_channel/resolver/polling_resolver.cc +6 -8
  51. data/src/core/ext/filters/client_channel/resolver/xds/xds_dependency_manager.cc +1031 -0
  52. data/src/core/ext/filters/client_channel/resolver/xds/xds_dependency_manager.h +277 -0
  53. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +128 -270
  54. data/src/core/ext/filters/client_channel/resolver/xds/{xds_resolver.h → xds_resolver_attributes.h} +5 -4
  55. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver_trace.cc +25 -0
  56. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver_trace.h +30 -0
  57. data/src/core/ext/filters/client_channel/retry_filter.cc +1 -0
  58. data/src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc +35 -17
  59. data/src/core/ext/filters/deadline/deadline_filter.cc +12 -0
  60. data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +17 -13
  61. data/src/core/ext/filters/fault_injection/fault_injection_filter.h +13 -4
  62. data/src/core/ext/filters/http/client/http_client_filter.cc +23 -32
  63. data/src/core/ext/filters/http/client/http_client_filter.h +10 -5
  64. data/src/core/ext/filters/http/client_authority_filter.cc +14 -14
  65. data/src/core/ext/filters/http/client_authority_filter.h +12 -4
  66. data/src/core/ext/filters/http/http_filters_plugin.cc +42 -20
  67. data/src/core/ext/filters/http/message_compress/compression_filter.cc +55 -80
  68. data/src/core/ext/filters/http/message_compress/compression_filter.h +54 -12
  69. data/src/core/ext/filters/http/message_compress/legacy_compression_filter.cc +325 -0
  70. data/src/core/ext/filters/http/message_compress/legacy_compression_filter.h +139 -0
  71. data/src/core/ext/filters/http/server/http_server_filter.cc +41 -41
  72. data/src/core/ext/filters/http/server/http_server_filter.h +11 -4
  73. data/src/core/ext/filters/message_size/message_size_filter.cc +56 -76
  74. data/src/core/ext/filters/message_size/message_size_filter.h +35 -23
  75. data/src/core/ext/filters/rbac/rbac_filter.cc +15 -11
  76. data/src/core/ext/filters/rbac/rbac_filter.h +11 -4
  77. data/src/core/ext/filters/server_config_selector/server_config_selector_filter.cc +25 -13
  78. data/src/core/ext/filters/stateful_session/stateful_session_filter.cc +47 -50
  79. data/src/core/ext/filters/stateful_session/stateful_session_filter.h +21 -4
  80. data/src/core/ext/transport/chttp2/alpn/alpn.cc +1 -1
  81. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +2 -2
  82. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +11 -2
  83. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +68 -145
  84. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +3 -3
  85. data/src/core/ext/transport/chttp2/transport/flow_control.cc +21 -82
  86. data/src/core/ext/transport/chttp2/transport/flow_control.h +1 -8
  87. data/src/core/ext/transport/chttp2/transport/frame.cc +506 -0
  88. data/src/core/ext/transport/chttp2/transport/frame.h +214 -0
  89. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +1 -1
  90. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +33 -79
  91. data/src/core/ext/transport/chttp2/transport/frame_settings.h +4 -7
  92. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +27 -36
  93. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +0 -2
  94. data/src/core/ext/transport/chttp2/transport/http2_settings.cc +122 -32
  95. data/src/core/ext/transport/chttp2/transport/http2_settings.h +142 -37
  96. data/src/core/ext/transport/chttp2/transport/internal.h +1 -22
  97. data/src/core/ext/transport/chttp2/transport/parsing.cc +23 -37
  98. data/src/core/ext/transport/chttp2/transport/writing.cc +26 -58
  99. data/src/core/ext/transport/inproc/inproc_transport.cc +172 -13
  100. data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb.h +712 -0
  101. data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c +151 -0
  102. data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.h +33 -0
  103. data/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c +133 -0
  104. data/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.h +50 -0
  105. data/src/core/ext/xds/certificate_provider_store.cc +2 -1
  106. data/src/core/ext/xds/certificate_provider_store.h +0 -5
  107. data/src/core/ext/xds/xds_api.cc +31 -18
  108. data/src/core/ext/xds/xds_api.h +2 -2
  109. data/src/core/ext/xds/xds_bootstrap.h +3 -0
  110. data/src/core/ext/xds/xds_certificate_provider.cc +88 -287
  111. data/src/core/ext/xds/xds_certificate_provider.h +44 -111
  112. data/src/core/ext/xds/xds_client.cc +420 -414
  113. data/src/core/ext/xds/xds_client.h +31 -22
  114. data/src/core/ext/xds/xds_client_grpc.cc +3 -1
  115. data/src/core/ext/xds/xds_cluster.cc +104 -11
  116. data/src/core/ext/xds/xds_cluster.h +9 -1
  117. data/src/core/ext/xds/xds_cluster_specifier_plugin.cc +9 -5
  118. data/src/core/ext/xds/xds_common_types.cc +14 -10
  119. data/src/core/ext/xds/xds_endpoint.cc +9 -4
  120. data/src/core/ext/xds/xds_endpoint.h +5 -1
  121. data/src/core/ext/xds/xds_health_status.cc +12 -2
  122. data/src/core/ext/xds/xds_health_status.h +4 -2
  123. data/src/core/ext/xds/xds_http_rbac_filter.cc +5 -3
  124. data/src/core/ext/xds/xds_listener.cc +14 -8
  125. data/src/core/ext/xds/xds_resource_type_impl.h +6 -4
  126. data/src/core/ext/xds/xds_route_config.cc +34 -22
  127. data/src/core/ext/xds/xds_route_config.h +1 -0
  128. data/src/core/ext/xds/xds_server_config_fetcher.cc +61 -57
  129. data/src/core/ext/xds/xds_transport.h +3 -0
  130. data/src/core/ext/xds/xds_transport_grpc.cc +47 -50
  131. data/src/core/ext/xds/xds_transport_grpc.h +4 -0
  132. data/src/core/lib/channel/call_tracer.cc +12 -0
  133. data/src/core/lib/channel/call_tracer.h +17 -3
  134. data/src/core/lib/channel/channel_args.cc +24 -14
  135. data/src/core/lib/channel/channel_args.h +74 -13
  136. data/src/core/lib/channel/channel_stack.cc +27 -0
  137. data/src/core/lib/channel/channel_stack.h +10 -10
  138. data/src/core/lib/channel/connected_channel.cc +64 -18
  139. data/src/core/lib/channel/promise_based_filter.h +1041 -1
  140. data/src/core/lib/channel/server_call_tracer_filter.cc +43 -35
  141. data/src/core/lib/compression/compression_internal.cc +0 -3
  142. data/src/core/lib/event_engine/ares_resolver.cc +35 -14
  143. data/src/core/lib/event_engine/ares_resolver.h +9 -10
  144. data/src/core/lib/event_engine/cf_engine/dns_service_resolver.cc +8 -1
  145. data/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc +132 -0
  146. data/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h +61 -0
  147. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +52 -36
  148. data/src/core/lib/event_engine/posix_engine/posix_engine.h +4 -9
  149. data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc +11 -3
  150. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc +9 -2
  151. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +7 -0
  152. data/src/core/lib/event_engine/posix_engine/timer_manager.cc +17 -27
  153. data/src/core/lib/event_engine/posix_engine/timer_manager.h +0 -3
  154. data/src/core/lib/event_engine/ref_counted_dns_resolver_interface.h +55 -0
  155. data/src/core/lib/event_engine/windows/native_windows_dns_resolver.cc +114 -0
  156. data/src/core/lib/event_engine/windows/native_windows_dns_resolver.h +51 -0
  157. data/src/core/lib/event_engine/windows/windows_engine.cc +7 -7
  158. data/src/core/lib/experiments/config.cc +13 -0
  159. data/src/core/lib/experiments/config.h +3 -0
  160. data/src/core/lib/experiments/experiments.cc +245 -366
  161. data/src/core/lib/experiments/experiments.h +50 -156
  162. data/src/core/lib/gprpp/debug_location.h +13 -0
  163. data/src/core/lib/gprpp/dual_ref_counted.h +36 -7
  164. data/src/core/lib/gprpp/orphanable.h +27 -0
  165. data/src/core/lib/gprpp/ref_counted.h +63 -22
  166. data/src/core/lib/gprpp/ref_counted_ptr.h +70 -27
  167. data/src/core/lib/gprpp/ref_counted_string.h +13 -0
  168. data/src/core/lib/gprpp/status_helper.cc +1 -2
  169. data/src/core/lib/iomgr/combiner.cc +15 -51
  170. data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +31 -0
  171. data/src/core/lib/iomgr/event_engine_shims/endpoint.h +16 -0
  172. data/src/core/lib/iomgr/tcp_client_posix.cc +4 -3
  173. data/src/core/lib/load_balancing/lb_policy.h +1 -1
  174. data/src/core/lib/promise/activity.cc +17 -2
  175. data/src/core/lib/promise/activity.h +5 -4
  176. data/src/core/lib/promise/all_ok.h +80 -0
  177. data/src/core/lib/promise/detail/join_state.h +2077 -0
  178. data/src/core/lib/promise/detail/promise_factory.h +1 -0
  179. data/src/core/lib/promise/detail/promise_like.h +8 -1
  180. data/src/core/lib/promise/detail/seq_state.h +3458 -150
  181. data/src/core/lib/promise/detail/status.h +42 -5
  182. data/src/core/lib/promise/for_each.h +13 -1
  183. data/src/core/lib/promise/if.h +4 -0
  184. data/src/core/lib/promise/latch.h +6 -3
  185. data/src/core/lib/promise/party.cc +33 -31
  186. data/src/core/lib/promise/party.h +142 -6
  187. data/src/core/lib/promise/poll.h +39 -13
  188. data/src/core/lib/promise/promise.h +4 -0
  189. data/src/core/lib/promise/seq.h +107 -7
  190. data/src/core/lib/promise/status_flag.h +196 -0
  191. data/src/core/lib/promise/try_join.h +132 -0
  192. data/src/core/lib/promise/try_seq.h +132 -10
  193. data/src/core/lib/resolver/endpoint_addresses.cc +0 -1
  194. data/src/core/lib/resolver/endpoint_addresses.h +48 -0
  195. data/src/core/lib/resource_quota/arena.h +2 -2
  196. data/src/core/lib/resource_quota/memory_quota.cc +57 -8
  197. data/src/core/lib/resource_quota/memory_quota.h +6 -0
  198. data/src/core/lib/security/authorization/grpc_server_authz_filter.cc +14 -11
  199. data/src/core/lib/security/authorization/grpc_server_authz_filter.h +14 -5
  200. data/src/core/lib/security/credentials/external/aws_external_account_credentials.cc +4 -0
  201. data/src/core/lib/security/credentials/external/aws_external_account_credentials.h +4 -0
  202. data/src/core/lib/security/credentials/external/external_account_credentials.cc +28 -20
  203. data/src/core/lib/security/credentials/external/external_account_credentials.h +4 -0
  204. data/src/core/lib/security/credentials/external/file_external_account_credentials.cc +4 -0
  205. data/src/core/lib/security/credentials/external/file_external_account_credentials.h +4 -0
  206. data/src/core/lib/security/credentials/external/url_external_account_credentials.cc +4 -0
  207. data/src/core/lib/security/credentials/external/url_external_account_credentials.h +4 -0
  208. data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +2 -1
  209. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h +0 -3
  210. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc +12 -0
  211. data/src/core/lib/security/credentials/tls/grpc_tls_crl_provider.cc +22 -5
  212. data/src/core/lib/security/credentials/tls/grpc_tls_crl_provider.h +1 -5
  213. data/src/core/lib/security/credentials/tls/tls_credentials.cc +16 -0
  214. data/src/core/lib/security/credentials/xds/xds_credentials.cc +21 -28
  215. data/src/core/lib/security/credentials/xds/xds_credentials.h +2 -4
  216. data/src/core/lib/security/security_connector/tls/tls_security_connector.cc +4 -3
  217. data/src/core/lib/security/transport/auth_filters.h +71 -4
  218. data/src/core/lib/security/transport/client_auth_filter.cc +2 -4
  219. data/src/core/lib/security/transport/legacy_server_auth_filter.cc +244 -0
  220. data/src/core/lib/security/transport/server_auth_filter.cc +70 -90
  221. data/src/core/lib/slice/slice_buffer.h +3 -0
  222. data/src/core/lib/surface/builtins.cc +1 -1
  223. data/src/core/lib/surface/call.cc +683 -196
  224. data/src/core/lib/surface/call.h +26 -13
  225. data/src/core/lib/surface/call_trace.cc +42 -1
  226. data/src/core/lib/surface/channel.cc +0 -1
  227. data/src/core/lib/surface/channel.h +0 -6
  228. data/src/core/lib/surface/channel_init.h +26 -0
  229. data/src/core/lib/surface/init.cc +14 -8
  230. data/src/core/lib/surface/server.cc +256 -237
  231. data/src/core/lib/surface/server.h +26 -54
  232. data/src/core/lib/surface/version.cc +2 -2
  233. data/src/core/lib/surface/wait_for_cq_end_op.h +94 -0
  234. data/src/core/lib/transport/call_final_info.cc +38 -0
  235. data/src/core/lib/transport/call_final_info.h +54 -0
  236. data/src/core/lib/transport/connectivity_state.cc +3 -2
  237. data/src/core/lib/transport/connectivity_state.h +4 -0
  238. data/src/core/lib/transport/metadata_batch.h +4 -4
  239. data/src/core/lib/transport/transport.cc +70 -19
  240. data/src/core/lib/transport/transport.h +395 -25
  241. data/src/core/plugin_registry/grpc_plugin_registry.cc +3 -0
  242. data/src/core/plugin_registry/grpc_plugin_registry_extra.cc +0 -3
  243. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +1 -1
  244. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +1 -1
  245. data/src/core/tsi/alts/handshaker/transport_security_common_api.cc +1 -1
  246. data/src/core/tsi/ssl_transport_security.cc +65 -43
  247. data/src/ruby/ext/grpc/rb_channel_args.c +3 -1
  248. data/src/ruby/ext/grpc/rb_grpc.c +0 -1
  249. data/src/ruby/ext/grpc/rb_grpc.h +0 -2
  250. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +4 -0
  251. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +6 -0
  252. data/src/ruby/lib/grpc/version.rb +1 -1
  253. data/third_party/upb/upb/reflection/def_pool.h +2 -2
  254. data/third_party/zlib/adler32.c +5 -27
  255. data/third_party/zlib/compress.c +5 -16
  256. data/third_party/zlib/crc32.c +86 -162
  257. data/third_party/zlib/deflate.c +233 -336
  258. data/third_party/zlib/deflate.h +8 -8
  259. data/third_party/zlib/gzguts.h +11 -12
  260. data/third_party/zlib/infback.c +7 -23
  261. data/third_party/zlib/inffast.c +1 -4
  262. data/third_party/zlib/inffast.h +1 -1
  263. data/third_party/zlib/inflate.c +30 -99
  264. data/third_party/zlib/inftrees.c +6 -11
  265. data/third_party/zlib/inftrees.h +3 -3
  266. data/third_party/zlib/trees.c +224 -302
  267. data/third_party/zlib/uncompr.c +4 -12
  268. data/third_party/zlib/zconf.h +6 -2
  269. data/third_party/zlib/zlib.h +191 -188
  270. data/third_party/zlib/zutil.c +16 -44
  271. data/third_party/zlib/zutil.h +10 -10
  272. metadata +35 -13
  273. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +0 -1173
  274. data/src/core/lib/event_engine/memory_allocator.cc +0 -74
  275. data/src/core/lib/transport/pid_controller.cc +0 -51
  276. data/src/core/lib/transport/pid_controller.h +0 -116
  277. data/third_party/upb/upb/collections/array.h +0 -17
  278. data/third_party/upb/upb/collections/map.h +0 -17
  279. data/third_party/upb/upb/upb.hpp +0 -18
@@ -43,6 +43,7 @@
43
43
  #include <grpc/support/log.h>
44
44
 
45
45
  #include "src/core/lib/channel/call_finalization.h"
46
+ #include "src/core/lib/channel/channel_args.h"
46
47
  #include "src/core/lib/channel/channel_fwd.h"
47
48
  #include "src/core/lib/channel/channel_stack.h"
48
49
  #include "src/core/lib/channel/context.h"
@@ -60,6 +61,9 @@
60
61
  #include "src/core/lib/promise/context.h"
61
62
  #include "src/core/lib/promise/pipe.h"
62
63
  #include "src/core/lib/promise/poll.h"
64
+ #include "src/core/lib/promise/promise.h"
65
+ #include "src/core/lib/promise/race.h"
66
+ #include "src/core/lib/promise/try_seq.h"
63
67
  #include "src/core/lib/resource_quota/arena.h"
64
68
  #include "src/core/lib/slice/slice_buffer.h"
65
69
  #include "src/core/lib/surface/call.h"
@@ -122,6 +126,997 @@ class ChannelFilter {
122
126
  grpc_event_engine::experimental::GetDefaultEventEngine();
123
127
  };
124
128
 
129
+ struct NoInterceptor {};
130
+
131
+ namespace promise_filter_detail {
132
+
133
+ // Determine if a list of interceptors has any that need to asyncronously error
134
+ // the promise. If so, we need to allocate a latch for the generated promise for
135
+ // the original promise stack polyfill code that's generated.
136
+
137
+ inline constexpr bool HasAsyncErrorInterceptor() { return false; }
138
+
139
+ inline constexpr bool HasAsyncErrorInterceptor(const NoInterceptor*) {
140
+ return false;
141
+ }
142
+
143
+ template <typename T, typename A0, typename... As>
144
+ inline constexpr bool HasAsyncErrorInterceptor(A0 (T::*)(A0, As...)) {
145
+ return false;
146
+ }
147
+
148
+ template <typename T, typename... A>
149
+ inline constexpr bool HasAsyncErrorInterceptor(absl::Status (T::*)(A...)) {
150
+ return true;
151
+ }
152
+
153
+ template <typename R, typename T, typename... A>
154
+ inline constexpr bool HasAsyncErrorInterceptor(absl::StatusOr<R> (T::*)(A...)) {
155
+ return true;
156
+ }
157
+
158
+ template <typename T, typename... A>
159
+ inline constexpr bool HasAsyncErrorInterceptor(
160
+ ServerMetadataHandle (T::*)(A...)) {
161
+ return true;
162
+ }
163
+
164
+ template <typename T, typename... A>
165
+ inline constexpr bool HasAsyncErrorInterceptor(void (T::*)(A...)) {
166
+ return false;
167
+ }
168
+
169
+ // For the list case we do two interceptors to avoid amiguities with the single
170
+ // argument forms above.
171
+ template <typename I1, typename I2, typename... Interceptors>
172
+ inline constexpr bool HasAsyncErrorInterceptor(I1 i1, I2 i2,
173
+ Interceptors... interceptors) {
174
+ return HasAsyncErrorInterceptor(i1) || HasAsyncErrorInterceptor(i2) ||
175
+ HasAsyncErrorInterceptor(interceptors...);
176
+ }
177
+
178
+ // Composite for a given channel type to determine if any of its interceptors
179
+ // fall into this category: later code should use this.
180
+ template <typename Derived>
181
+ inline constexpr bool CallHasAsyncErrorInterceptor() {
182
+ return HasAsyncErrorInterceptor(&Derived::Call::OnClientToServerMessage,
183
+ &Derived::Call::OnServerInitialMetadata,
184
+ &Derived::Call::OnServerToClientMessage);
185
+ }
186
+
187
+ // Determine if an interceptor needs to access the channel via one of its
188
+ // arguments. If so, we need to allocate a pointer to the channel for the
189
+ // generated polyfill promise for the original promise stack.
190
+
191
+ inline constexpr bool HasChannelAccess() { return false; }
192
+
193
+ inline constexpr bool HasChannelAccess(const NoInterceptor*) { return false; }
194
+
195
+ template <typename T, typename R, typename A>
196
+ inline constexpr bool HasChannelAccess(R (T::*)(A)) {
197
+ return false;
198
+ }
199
+
200
+ template <typename T, typename R, typename A>
201
+ inline constexpr bool HasChannelAccess(R (T::*)()) {
202
+ return false;
203
+ }
204
+
205
+ template <typename T, typename R, typename A, typename C>
206
+ inline constexpr bool HasChannelAccess(R (T::*)(A, C)) {
207
+ return true;
208
+ }
209
+
210
+ // For the list case we do two interceptors to avoid amiguities with the single
211
+ // argument forms above.
212
+ template <typename I1, typename I2, typename... Interceptors>
213
+ inline constexpr bool HasChannelAccess(I1 i1, I2 i2,
214
+ Interceptors... interceptors) {
215
+ return HasChannelAccess(i1) || HasChannelAccess(i2) ||
216
+ HasChannelAccess(interceptors...);
217
+ }
218
+
219
+ // Composite for a given channel type to determine if any of its interceptors
220
+ // fall into this category: later code should use this.
221
+ template <typename Derived>
222
+ inline constexpr bool CallHasChannelAccess() {
223
+ return HasChannelAccess(&Derived::Call::OnClientInitialMetadata,
224
+ &Derived::Call::OnClientToServerMessage,
225
+ &Derived::Call::OnServerInitialMetadata,
226
+ &Derived::Call::OnServerToClientMessage,
227
+ &Derived::Call::OnServerTrailingMetadata,
228
+ &Derived::Call::OnFinalize);
229
+ }
230
+
231
+ // Given a boolean X export a type:
232
+ // either T if X is true
233
+ // or an empty type if it is false
234
+ template <typename T, bool X>
235
+ struct TypeIfNeeded;
236
+
237
+ template <typename T>
238
+ struct TypeIfNeeded<T, false> {
239
+ struct Type {
240
+ Type() = default;
241
+ template <typename Whatever>
242
+ explicit Type(Whatever) : Type() {}
243
+ };
244
+ };
245
+
246
+ template <typename T>
247
+ struct TypeIfNeeded<T, true> {
248
+ using Type = T;
249
+ };
250
+
251
+ // For the original promise scheme polyfill:
252
+ // If a set of interceptors might fail asynchronously, wrap the main
253
+ // promise in a race with the cancellation latch.
254
+ // If not, just return the main promise.
255
+ template <bool X>
256
+ struct RaceAsyncCompletion;
257
+
258
+ template <>
259
+ struct RaceAsyncCompletion<false> {
260
+ template <typename Promise>
261
+ static Promise Run(Promise x, void*) {
262
+ return x;
263
+ }
264
+ };
265
+
266
+ template <>
267
+ struct RaceAsyncCompletion<true> {
268
+ template <typename Promise>
269
+ static Promise Run(Promise x, Latch<ServerMetadataHandle>* latch) {
270
+ return Race(latch->Wait(), std::move(x));
271
+ }
272
+ };
273
+
274
+ // Zero-member wrapper to make sure that Call always has a constructor
275
+ // that takes a channel pointer (even if it's thrown away)
276
+ template <typename Derived, typename SfinaeVoid = void>
277
+ class CallWrapper;
278
+
279
+ template <typename Derived>
280
+ class CallWrapper<Derived, absl::void_t<decltype(typename Derived::Call(
281
+ std::declval<Derived*>()))>>
282
+ : public Derived::Call {
283
+ public:
284
+ explicit CallWrapper(Derived* channel) : Derived::Call(channel) {}
285
+ };
286
+
287
+ template <typename Derived>
288
+ class CallWrapper<Derived, absl::void_t<decltype(typename Derived::Call())>>
289
+ : public Derived::Call {
290
+ public:
291
+ explicit CallWrapper(Derived*) : Derived::Call() {}
292
+ };
293
+
294
+ // For the original promise scheme polyfill: data associated with once call.
295
+ template <typename Derived>
296
+ struct FilterCallData {
297
+ explicit FilterCallData(Derived* channel) : call(channel), channel(channel) {}
298
+ GPR_NO_UNIQUE_ADDRESS CallWrapper<Derived> call;
299
+ GPR_NO_UNIQUE_ADDRESS
300
+ typename TypeIfNeeded<Latch<ServerMetadataHandle>,
301
+ CallHasAsyncErrorInterceptor<Derived>()>::Type
302
+ error_latch;
303
+ GPR_NO_UNIQUE_ADDRESS
304
+ typename TypeIfNeeded<Derived*, CallHasChannelAccess<Derived>()>::Type
305
+ channel;
306
+ };
307
+
308
+ template <typename Promise>
309
+ auto MapResult(const NoInterceptor*, Promise x, void*) {
310
+ return x;
311
+ }
312
+
313
+ template <typename Promise, typename Derived>
314
+ auto MapResult(absl::Status (Derived::Call::*fn)(ServerMetadata&), Promise x,
315
+ FilterCallData<Derived>* call_data) {
316
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnServerTrailingMetadata);
317
+ return Map(std::move(x), [call_data](ServerMetadataHandle md) {
318
+ auto status = call_data->call.OnServerTrailingMetadata(*md);
319
+ if (!status.ok()) return ServerMetadataFromStatus(status);
320
+ return md;
321
+ });
322
+ }
323
+
324
+ template <typename Promise, typename Derived>
325
+ auto MapResult(void (Derived::Call::*fn)(ServerMetadata&), Promise x,
326
+ FilterCallData<Derived>* call_data) {
327
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnServerTrailingMetadata);
328
+ return Map(std::move(x), [call_data](ServerMetadataHandle md) {
329
+ call_data->call.OnServerTrailingMetadata(*md);
330
+ return md;
331
+ });
332
+ }
333
+
334
+ template <typename Promise, typename Derived>
335
+ auto MapResult(void (Derived::Call::*fn)(ServerMetadata&, Derived*), Promise x,
336
+ FilterCallData<Derived>* call_data) {
337
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnServerTrailingMetadata);
338
+ return Map(std::move(x), [call_data](ServerMetadataHandle md) {
339
+ call_data->call.OnServerTrailingMetadata(*md, call_data->channel);
340
+ return md;
341
+ });
342
+ }
343
+
344
+ template <typename Interceptor, typename Derived, typename SfinaeVoid = void>
345
+ struct RunCallImpl;
346
+
347
+ template <typename Derived>
348
+ struct RunCallImpl<const NoInterceptor*, Derived> {
349
+ static auto Run(CallArgs call_args, NextPromiseFactory next_promise_factory,
350
+ void*) {
351
+ return next_promise_factory(std::move(call_args));
352
+ }
353
+ };
354
+
355
+ template <typename Derived>
356
+ struct RunCallImpl<void (Derived::Call::*)(ClientMetadata& md), Derived> {
357
+ static auto Run(CallArgs call_args, NextPromiseFactory next_promise_factory,
358
+ FilterCallData<Derived>* call_data) {
359
+ call_data->call.OnClientInitialMetadata(*call_args.client_initial_metadata);
360
+ return next_promise_factory(std::move(call_args));
361
+ }
362
+ };
363
+
364
+ template <typename Derived>
365
+ struct RunCallImpl<ServerMetadataHandle (Derived::Call::*)(ClientMetadata& md),
366
+ Derived> {
367
+ static auto Run(CallArgs call_args, NextPromiseFactory next_promise_factory,
368
+ FilterCallData<Derived>* call_data)
369
+ -> ArenaPromise<ServerMetadataHandle> {
370
+ auto return_md = call_data->call.OnClientInitialMetadata(
371
+ *call_args.client_initial_metadata);
372
+ if (return_md == nullptr) return next_promise_factory(std::move(call_args));
373
+ return Immediate(std::move(return_md));
374
+ }
375
+ };
376
+
377
+ template <typename Derived>
378
+ struct RunCallImpl<ServerMetadataHandle (Derived::Call::*)(ClientMetadata& md,
379
+ Derived* channel),
380
+ Derived> {
381
+ static auto Run(CallArgs call_args, NextPromiseFactory next_promise_factory,
382
+ FilterCallData<Derived>* call_data)
383
+ -> ArenaPromise<ServerMetadataHandle> {
384
+ auto return_md = call_data->call.OnClientInitialMetadata(
385
+ *call_args.client_initial_metadata, call_data->channel);
386
+ if (return_md == nullptr) return next_promise_factory(std::move(call_args));
387
+ return Immediate(std::move(return_md));
388
+ }
389
+ };
390
+
391
+ template <typename Derived>
392
+ struct RunCallImpl<absl::Status (Derived::Call::*)(ClientMetadata& md),
393
+ Derived> {
394
+ static auto Run(CallArgs call_args, NextPromiseFactory next_promise_factory,
395
+ FilterCallData<Derived>* call_data)
396
+ -> ArenaPromise<ServerMetadataHandle> {
397
+ auto status = call_data->call.OnClientInitialMetadata(
398
+ *call_args.client_initial_metadata);
399
+ if (status.ok()) return next_promise_factory(std::move(call_args));
400
+ return Immediate(ServerMetadataFromStatus(status));
401
+ }
402
+ };
403
+
404
+ template <typename Derived>
405
+ struct RunCallImpl<absl::Status (Derived::Call::*)(ClientMetadata& md,
406
+ Derived* channel),
407
+ Derived> {
408
+ static auto Run(CallArgs call_args, NextPromiseFactory next_promise_factory,
409
+ FilterCallData<Derived>* call_data)
410
+ -> ArenaPromise<ServerMetadataHandle> {
411
+ auto status = call_data->call.OnClientInitialMetadata(
412
+ *call_args.client_initial_metadata, call_data->channel);
413
+ if (status.ok()) return next_promise_factory(std::move(call_args));
414
+ return Immediate(ServerMetadataFromStatus(status));
415
+ }
416
+ };
417
+
418
+ template <typename Derived>
419
+ struct RunCallImpl<
420
+ void (Derived::Call::*)(ClientMetadata& md, Derived* channel), Derived> {
421
+ static auto Run(CallArgs call_args, NextPromiseFactory next_promise_factory,
422
+ FilterCallData<Derived>* call_data) {
423
+ call_data->call.OnClientInitialMetadata(*call_args.client_initial_metadata,
424
+ call_data->channel);
425
+ return next_promise_factory(std::move(call_args));
426
+ }
427
+ };
428
+
429
+ template <typename Derived, typename Promise>
430
+ struct RunCallImpl<
431
+ Promise (Derived::Call::*)(ClientMetadata& md, Derived* channel), Derived,
432
+ absl::void_t<decltype(StatusCast<ServerMetadataHandle>(
433
+ std::declval<PromiseResult<Promise>>))>> {
434
+ static auto Run(CallArgs call_args, NextPromiseFactory next_promise_factory,
435
+ FilterCallData<Derived>* call_data) {
436
+ ClientMetadata& md_ref = *call_args.client_initial_metadata;
437
+ return TrySeq(
438
+ call_data->call.OnClientInitialMetadata(md_ref, call_data->channel),
439
+ [call_args = std::move(call_args),
440
+ next_promise_factory = std::move(next_promise_factory)]() mutable {
441
+ return next_promise_factory(std::move(call_args));
442
+ });
443
+ }
444
+ };
445
+
446
+ template <typename Interceptor, typename Derived>
447
+ auto RunCall(Interceptor interceptor, CallArgs call_args,
448
+ NextPromiseFactory next_promise_factory,
449
+ FilterCallData<Derived>* call_data) {
450
+ GPR_DEBUG_ASSERT(interceptor == &Derived::Call::OnClientInitialMetadata);
451
+ return RunCallImpl<Interceptor, Derived>::Run(
452
+ std::move(call_args), std::move(next_promise_factory), call_data);
453
+ }
454
+
455
+ inline void InterceptClientToServerMessage(const NoInterceptor*, void*,
456
+ const CallArgs&) {}
457
+
458
+ template <typename Derived>
459
+ inline void InterceptClientToServerMessage(
460
+ ServerMetadataHandle (Derived::Call::*fn)(const Message&),
461
+ FilterCallData<Derived>* call_data, const CallArgs& call_args) {
462
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnClientToServerMessage);
463
+ call_args.client_to_server_messages->InterceptAndMap(
464
+ [call_data](MessageHandle msg) -> absl::optional<MessageHandle> {
465
+ auto return_md = call_data->call.OnClientToServerMessage(*msg);
466
+ if (return_md == nullptr) return std::move(msg);
467
+ if (call_data->error_latch.is_set()) return absl::nullopt;
468
+ call_data->error_latch.Set(std::move(return_md));
469
+ return absl::nullopt;
470
+ });
471
+ }
472
+
473
+ template <typename Derived>
474
+ inline void InterceptClientToServerMessage(
475
+ ServerMetadataHandle (Derived::Call::*fn)(const Message&, Derived*),
476
+ FilterCallData<Derived>* call_data, const CallArgs& call_args) {
477
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnClientToServerMessage);
478
+ call_args.client_to_server_messages->InterceptAndMap(
479
+ [call_data](MessageHandle msg) -> absl::optional<MessageHandle> {
480
+ auto return_md =
481
+ call_data->call.OnClientToServerMessage(*msg, call_data->channel);
482
+ if (return_md == nullptr) return std::move(msg);
483
+ if (call_data->error_latch.is_set()) return absl::nullopt;
484
+ call_data->error_latch.Set(std::move(return_md));
485
+ return absl::nullopt;
486
+ });
487
+ }
488
+
489
+ template <typename Derived>
490
+ inline void InterceptClientToServerMessage(
491
+ MessageHandle (Derived::Call::*fn)(MessageHandle, Derived*),
492
+ FilterCallData<Derived>* call_data, const CallArgs& call_args) {
493
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnClientToServerMessage);
494
+ call_args.client_to_server_messages->InterceptAndMap(
495
+ [call_data](MessageHandle msg) -> absl::optional<MessageHandle> {
496
+ return call_data->call.OnClientToServerMessage(std::move(msg),
497
+ call_data->channel);
498
+ });
499
+ }
500
+
501
+ template <typename Derived>
502
+ inline void InterceptClientToServerMessage(
503
+ absl::StatusOr<MessageHandle> (Derived::Call::*fn)(MessageHandle, Derived*),
504
+ FilterCallData<Derived>* call_data, const CallArgs& call_args) {
505
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnClientToServerMessage);
506
+ call_args.client_to_server_messages->InterceptAndMap(
507
+ [call_data](MessageHandle msg) -> absl::optional<MessageHandle> {
508
+ auto r = call_data->call.OnClientToServerMessage(std::move(msg),
509
+ call_data->channel);
510
+ if (r.ok()) return std::move(*r);
511
+ if (call_data->error_latch.is_set()) return absl::nullopt;
512
+ call_data->error_latch.Set(ServerMetadataFromStatus(r.status()));
513
+ return absl::nullopt;
514
+ });
515
+ }
516
+
517
+ inline void InterceptClientToServerMessage(const NoInterceptor*, void*, void*,
518
+ CallSpineInterface*) {}
519
+
520
+ template <typename Derived>
521
+ inline void InterceptClientToServerMessage(
522
+ ServerMetadataHandle (Derived::Call::*fn)(const Message&),
523
+ typename Derived::Call* call, Derived*, CallSpineInterface* call_spine) {
524
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnClientToServerMessage);
525
+ call_spine->client_to_server_messages().receiver.InterceptAndMap(
526
+ [call, call_spine](MessageHandle msg) -> absl::optional<MessageHandle> {
527
+ auto return_md = call->OnClientToServerMessage(*msg);
528
+ if (return_md == nullptr) return std::move(msg);
529
+ return call_spine->Cancel(std::move(return_md));
530
+ });
531
+ }
532
+
533
+ template <typename Derived>
534
+ inline void InterceptClientToServerMessage(
535
+ ServerMetadataHandle (Derived::Call::*fn)(const Message&, Derived*),
536
+ typename Derived::Call* call, Derived* channel,
537
+ CallSpineInterface* call_spine) {
538
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnClientToServerMessage);
539
+ call_spine->client_to_server_messages().receiver.InterceptAndMap(
540
+ [call, call_spine,
541
+ channel](MessageHandle msg) -> absl::optional<MessageHandle> {
542
+ auto return_md = call->OnClientToServerMessage(*msg, channel);
543
+ if (return_md == nullptr) return std::move(msg);
544
+ return call_spine->Cancel(std::move(return_md));
545
+ });
546
+ }
547
+
548
+ template <typename Derived>
549
+ inline void InterceptClientToServerMessage(
550
+ MessageHandle (Derived::Call::*fn)(MessageHandle, Derived*),
551
+ typename Derived::Call* call, Derived* channel,
552
+ CallSpineInterface* call_spine) {
553
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnClientToServerMessage);
554
+ call_spine->client_to_server_messages().receiver.InterceptAndMap(
555
+ [call, channel](MessageHandle msg) {
556
+ return call->OnClientToServerMessage(std::move(msg), channel);
557
+ });
558
+ }
559
+
560
+ template <typename Derived>
561
+ inline void InterceptClientToServerMessage(
562
+ absl::StatusOr<MessageHandle> (Derived::Call::*fn)(MessageHandle, Derived*),
563
+ typename Derived::Call* call, Derived* channel,
564
+ CallSpineInterface* call_spine) {
565
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnClientToServerMessage);
566
+ call_spine->client_to_server_messages().receiver.InterceptAndMap(
567
+ [call, call_spine,
568
+ channel](MessageHandle msg) -> absl::optional<MessageHandle> {
569
+ auto r = call->OnClientToServerMessage(std::move(msg), channel);
570
+ if (r.ok()) return std::move(*r);
571
+ return call_spine->Cancel(ServerMetadataFromStatus(r.status()));
572
+ });
573
+ }
574
+
575
+ inline void InterceptClientInitialMetadata(const NoInterceptor*, void*, void*,
576
+ CallSpineInterface*) {}
577
+
578
+ template <typename Derived>
579
+ inline void InterceptClientInitialMetadata(
580
+ void (Derived::Call::*fn)(ClientMetadata& md), typename Derived::Call* call,
581
+ Derived*, CallSpineInterface* call_spine) {
582
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnClientInitialMetadata);
583
+ call_spine->client_initial_metadata().receiver.InterceptAndMap(
584
+ [call](ClientMetadataHandle md) {
585
+ call->OnClientInitialMetadata(*md);
586
+ return md;
587
+ });
588
+ }
589
+
590
+ template <typename Derived>
591
+ inline void InterceptClientInitialMetadata(
592
+ void (Derived::Call::*fn)(ClientMetadata& md, Derived* channel),
593
+ typename Derived::Call* call, Derived* channel,
594
+ CallSpineInterface* call_spine) {
595
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnClientInitialMetadata);
596
+ call_spine->client_initial_metadata().receiver.InterceptAndMap(
597
+ [call, channel](ClientMetadataHandle md) {
598
+ call->OnClientInitialMetadata(*md, channel);
599
+ return md;
600
+ });
601
+ }
602
+
603
+ template <typename Derived>
604
+ inline void InterceptClientInitialMetadata(
605
+ ServerMetadataHandle (Derived::Call::*fn)(ClientMetadata& md),
606
+ typename Derived::Call* call, Derived*, CallSpineInterface* call_spine) {
607
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnClientInitialMetadata);
608
+ call_spine->client_initial_metadata().receiver.InterceptAndMap(
609
+ [call_spine,
610
+ call](ClientMetadataHandle md) -> absl::optional<ClientMetadataHandle> {
611
+ auto return_md = call->OnClientInitialMetadata(*md);
612
+ if (return_md == nullptr) return std::move(md);
613
+ return call_spine->Cancel(std::move(return_md));
614
+ });
615
+ }
616
+
617
+ template <typename Derived>
618
+ inline void InterceptClientInitialMetadata(
619
+ ServerMetadataHandle (Derived::Call::*fn)(ClientMetadata& md,
620
+ Derived* channel),
621
+ typename Derived::Call* call, Derived* channel,
622
+ CallSpineInterface* call_spine) {
623
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnClientInitialMetadata);
624
+ call_spine->client_initial_metadata().receiver.InterceptAndMap(
625
+ [call_spine, call, channel](
626
+ ClientMetadataHandle md) -> absl::optional<ClientMetadataHandle> {
627
+ auto return_md = call->OnClientInitialMetadata(*md, channel);
628
+ if (return_md == nullptr) return std::move(md);
629
+ return call_spine->Cancel(std::move(return_md));
630
+ });
631
+ }
632
+
633
+ template <typename Derived>
634
+ inline void InterceptClientInitialMetadata(
635
+ absl::Status (Derived::Call::*fn)(ClientMetadata& md),
636
+ typename Derived::Call* call, Derived*, CallSpineInterface* call_spine) {
637
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnClientInitialMetadata);
638
+ call_spine->client_initial_metadata().receiver.InterceptAndMap(
639
+ [call_spine,
640
+ call](ClientMetadataHandle md) -> absl::optional<ClientMetadataHandle> {
641
+ auto status = call->OnClientInitialMetadata(*md);
642
+ if (status.ok()) return std::move(md);
643
+ return call_spine->Cancel(ServerMetadataFromStatus(status));
644
+ });
645
+ }
646
+
647
+ template <typename Derived>
648
+ inline void InterceptClientInitialMetadata(
649
+ absl::Status (Derived::Call::*fn)(ClientMetadata& md, Derived* channel),
650
+ typename Derived::Call* call, Derived* channel,
651
+ CallSpineInterface* call_spine) {
652
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnClientInitialMetadata);
653
+ call_spine->client_initial_metadata().receiver.InterceptAndMap(
654
+ [call_spine, call, channel](
655
+ ClientMetadataHandle md) -> absl::optional<ClientMetadataHandle> {
656
+ auto status = call->OnClientInitialMetadata(*md, channel);
657
+ if (status.ok()) return std::move(md);
658
+ return call_spine->Cancel(ServerMetadataFromStatus(status));
659
+ });
660
+ }
661
+
662
+ // Returning a promise that resolves to something that can be cast to
663
+ // ServerMetadataHandle also counts
664
+ template <typename Promise, typename Derived>
665
+ absl::void_t<decltype(StatusCast<ServerMetadataHandle>(
666
+ std::declval<PromiseResult<Promise>>))>
667
+ InterceptClientInitialMetadata(Promise (Derived::Call::*promise_factory)(
668
+ ClientMetadata& md, Derived* channel),
669
+ typename Derived::Call* call, Derived* channel,
670
+ CallSpineInterface* call_spine) {
671
+ GPR_DEBUG_ASSERT(promise_factory == &Derived::Call::OnClientInitialMetadata);
672
+ call_spine->client_initial_metadata().receiver.InterceptAndMap(
673
+ [call, call_spine, channel](ClientMetadataHandle md) {
674
+ ClientMetadata& md_ref = *md;
675
+ return Map(call->OnClientInitialMetadata(md_ref, channel),
676
+ [md = std::move(md),
677
+ call_spine](PromiseResult<Promise> status) mutable
678
+ -> absl::optional<ClientMetadataHandle> {
679
+ if (IsStatusOk(status)) return std::move(md);
680
+ return call_spine->Cancel(
681
+ StatusCast<ServerMetadataHandle>(std::move(status)));
682
+ });
683
+ });
684
+ }
685
+
686
+ template <typename CallArgs>
687
+ inline void InterceptServerInitialMetadata(const NoInterceptor*, void*,
688
+ const CallArgs&) {}
689
+
690
+ template <typename Derived>
691
+ inline void InterceptServerInitialMetadata(
692
+ void (Derived::Call::*fn)(ServerMetadata&),
693
+ FilterCallData<Derived>* call_data, const CallArgs& call_args) {
694
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnServerInitialMetadata);
695
+ call_args.server_initial_metadata->InterceptAndMap(
696
+ [call_data](ServerMetadataHandle md) {
697
+ call_data->call.OnServerInitialMetadata(*md);
698
+ return md;
699
+ });
700
+ }
701
+
702
+ template <typename Derived>
703
+ inline void InterceptServerInitialMetadata(
704
+ absl::Status (Derived::Call::*fn)(ServerMetadata&),
705
+ FilterCallData<Derived>* call_data, const CallArgs& call_args) {
706
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnServerInitialMetadata);
707
+ call_args.server_initial_metadata->InterceptAndMap(
708
+ [call_data](
709
+ ServerMetadataHandle md) -> absl::optional<ServerMetadataHandle> {
710
+ auto status = call_data->call.OnServerInitialMetadata(*md);
711
+ if (!status.ok() && !call_data->error_latch.is_set()) {
712
+ call_data->error_latch.Set(ServerMetadataFromStatus(status));
713
+ return absl::nullopt;
714
+ }
715
+ return std::move(md);
716
+ });
717
+ }
718
+
719
+ template <typename Derived>
720
+ inline void InterceptServerInitialMetadata(
721
+ void (Derived::Call::*fn)(ServerMetadata&, Derived*),
722
+ FilterCallData<Derived>* call_data, const CallArgs& call_args) {
723
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnServerInitialMetadata);
724
+ call_args.server_initial_metadata->InterceptAndMap(
725
+ [call_data](ServerMetadataHandle md) {
726
+ call_data->call.OnServerInitialMetadata(*md, call_data->channel);
727
+ return md;
728
+ });
729
+ }
730
+
731
+ template <typename Derived>
732
+ inline void InterceptServerInitialMetadata(
733
+ absl::Status (Derived::Call::*fn)(ServerMetadata&, Derived*),
734
+ FilterCallData<Derived>* call_data, const CallArgs& call_args) {
735
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnServerInitialMetadata);
736
+ call_args.server_initial_metadata->InterceptAndMap(
737
+ [call_data](
738
+ ServerMetadataHandle md) -> absl::optional<ServerMetadataHandle> {
739
+ auto status =
740
+ call_data->call.OnServerInitialMetadata(*md, call_data->channel);
741
+ if (!status.ok() && !call_data->error_latch.is_set()) {
742
+ call_data->error_latch.Set(ServerMetadataFromStatus(status));
743
+ return absl::nullopt;
744
+ }
745
+ return std::move(md);
746
+ });
747
+ }
748
+
749
+ inline void InterceptServerInitialMetadata(const NoInterceptor*, void*, void*,
750
+ CallSpineInterface*) {}
751
+
752
+ template <typename Derived>
753
+ inline void InterceptServerInitialMetadata(
754
+ void (Derived::Call::*fn)(ServerMetadata&), typename Derived::Call* call,
755
+ Derived*, CallSpineInterface* call_spine) {
756
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnServerInitialMetadata);
757
+ call_spine->server_initial_metadata().sender.InterceptAndMap(
758
+ [call](ServerMetadataHandle md) {
759
+ call->OnServerInitialMetadata(*md);
760
+ return md;
761
+ });
762
+ }
763
+
764
+ template <typename Derived>
765
+ inline void InterceptServerInitialMetadata(
766
+ absl::Status (Derived::Call::*fn)(ServerMetadata&),
767
+ typename Derived::Call* call, Derived*, CallSpineInterface* call_spine) {
768
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnServerInitialMetadata);
769
+ call_spine->server_initial_metadata().sender.InterceptAndMap(
770
+ [call, call_spine](
771
+ ServerMetadataHandle md) -> absl::optional<ServerMetadataHandle> {
772
+ auto status = call->OnServerInitialMetadata(*md);
773
+ if (status.ok()) return std::move(md);
774
+ return call_spine->Cancel(ServerMetadataFromStatus(status));
775
+ });
776
+ }
777
+
778
+ template <typename Derived>
779
+ inline void InterceptServerInitialMetadata(
780
+ void (Derived::Call::*fn)(ServerMetadata&, Derived*),
781
+ typename Derived::Call* call, Derived* channel,
782
+ CallSpineInterface* call_spine) {
783
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnServerInitialMetadata);
784
+ call_spine->server_initial_metadata().sender.InterceptAndMap(
785
+ [call, channel](ServerMetadataHandle md) {
786
+ call->OnServerInitialMetadata(*md, channel);
787
+ return md;
788
+ });
789
+ }
790
+
791
+ template <typename Derived>
792
+ inline void InterceptServerInitialMetadata(
793
+ absl::Status (Derived::Call::*fn)(ServerMetadata&, Derived*),
794
+ typename Derived::Call* call, Derived* channel,
795
+ CallSpineInterface* call_spine) {
796
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnServerInitialMetadata);
797
+ call_spine->server_initial_metadata().sender.InterceptAndMap(
798
+ [call, call_spine, channel](
799
+ ServerMetadataHandle md) -> absl::optional<ServerMetadataHandle> {
800
+ auto status = call->OnServerInitialMetadata(*md, channel);
801
+ if (status.ok()) return std::move(md);
802
+ return call_spine->Cancel(ServerMetadataFromStatus(status));
803
+ });
804
+ }
805
+
806
+ inline void InterceptServerToClientMessage(const NoInterceptor*, void*,
807
+ const CallArgs&) {}
808
+
809
+ template <typename Derived>
810
+ inline void InterceptServerToClientMessage(
811
+ ServerMetadataHandle (Derived::Call::*fn)(const Message&),
812
+ FilterCallData<Derived>* call_data, const CallArgs& call_args) {
813
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnServerToClientMessage);
814
+ call_args.server_to_client_messages->InterceptAndMap(
815
+ [call_data](MessageHandle msg) -> absl::optional<MessageHandle> {
816
+ auto return_md = call_data->call.OnServerToClientMessage(*msg);
817
+ if (return_md == nullptr) return std::move(msg);
818
+ if (call_data->error_latch.is_set()) return absl::nullopt;
819
+ call_data->error_latch.Set(std::move(return_md));
820
+ return absl::nullopt;
821
+ });
822
+ }
823
+
824
+ template <typename Derived>
825
+ inline void InterceptServerToClientMessage(
826
+ ServerMetadataHandle (Derived::Call::*fn)(const Message&, Derived*),
827
+ FilterCallData<Derived>* call_data, const CallArgs& call_args) {
828
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnServerToClientMessage);
829
+ call_args.server_to_client_messages->InterceptAndMap(
830
+ [call_data](MessageHandle msg) -> absl::optional<MessageHandle> {
831
+ auto return_md =
832
+ call_data->call.OnServerToClientMessage(*msg, call_data->channel);
833
+ if (return_md == nullptr) return std::move(msg);
834
+ if (call_data->error_latch.is_set()) return absl::nullopt;
835
+ call_data->error_latch.Set(std::move(return_md));
836
+ return absl::nullopt;
837
+ });
838
+ }
839
+
840
+ template <typename Derived>
841
+ inline void InterceptServerToClientMessage(
842
+ MessageHandle (Derived::Call::*fn)(MessageHandle, Derived*),
843
+ FilterCallData<Derived>* call_data, const CallArgs& call_args) {
844
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnServerToClientMessage);
845
+ call_args.server_to_client_messages->InterceptAndMap(
846
+ [call_data](MessageHandle msg) -> absl::optional<MessageHandle> {
847
+ return call_data->call.OnServerToClientMessage(std::move(msg),
848
+ call_data->channel);
849
+ });
850
+ }
851
+
852
+ template <typename Derived>
853
+ inline void InterceptServerToClientMessage(
854
+ absl::StatusOr<MessageHandle> (Derived::Call::*fn)(MessageHandle, Derived*),
855
+ FilterCallData<Derived>* call_data, const CallArgs& call_args) {
856
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnServerToClientMessage);
857
+ call_args.server_to_client_messages->InterceptAndMap(
858
+ [call_data](MessageHandle msg) -> absl::optional<MessageHandle> {
859
+ auto r = call_data->call.OnServerToClientMessage(std::move(msg),
860
+ call_data->channel);
861
+ if (r.ok()) return std::move(*r);
862
+ if (call_data->error_latch.is_set()) return absl::nullopt;
863
+ call_data->error_latch.Set(ServerMetadataFromStatus(r.status()));
864
+ return absl::nullopt;
865
+ });
866
+ }
867
+
868
+ inline void InterceptServerToClientMessage(const NoInterceptor*, void*, void*,
869
+ CallSpineInterface*) {}
870
+
871
+ template <typename Derived>
872
+ inline void InterceptServerToClientMessage(
873
+ ServerMetadataHandle (Derived::Call::*fn)(const Message&),
874
+ typename Derived::Call* call, Derived*, CallSpineInterface* call_spine) {
875
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnServerToClientMessage);
876
+ call_spine->server_to_client_messages().sender.InterceptAndMap(
877
+ [call, call_spine](MessageHandle msg) -> absl::optional<MessageHandle> {
878
+ auto return_md = call->OnServerToClientMessage(*msg);
879
+ if (return_md == nullptr) return std::move(msg);
880
+ return call_spine->Cancel(std::move(return_md));
881
+ });
882
+ }
883
+
884
+ template <typename Derived>
885
+ inline void InterceptServerToClientMessage(
886
+ ServerMetadataHandle (Derived::Call::*fn)(const Message&, Derived*),
887
+ typename Derived::Call* call, Derived* channel,
888
+ CallSpineInterface* call_spine) {
889
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnServerToClientMessage);
890
+ call_spine->server_to_client_messages().sender.InterceptAndMap(
891
+ [call, call_spine,
892
+ channel](MessageHandle msg) -> absl::optional<MessageHandle> {
893
+ auto return_md = call->OnServerToClientMessage(*msg, channel);
894
+ if (return_md == nullptr) return std::move(msg);
895
+ return call_spine->Cancel(std::move(return_md));
896
+ });
897
+ }
898
+
899
+ template <typename Derived>
900
+ inline void InterceptServerToClientMessage(
901
+ MessageHandle (Derived::Call::*fn)(MessageHandle, Derived*),
902
+ typename Derived::Call* call, Derived* channel,
903
+ CallSpineInterface* call_spine) {
904
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnServerToClientMessage);
905
+ call_spine->server_to_client_messages().sender.InterceptAndMap(
906
+ [call, channel](MessageHandle msg) {
907
+ return call->OnServerToClientMessage(std::move(msg), channel);
908
+ });
909
+ }
910
+
911
+ template <typename Derived>
912
+ inline void InterceptServerToClientMessage(
913
+ absl::StatusOr<MessageHandle> (Derived::Call::*fn)(MessageHandle, Derived*),
914
+ typename Derived::Call* call, Derived* channel,
915
+ CallSpineInterface* call_spine) {
916
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnServerToClientMessage);
917
+ call_spine->server_to_client_messages().sender.InterceptAndMap(
918
+ [call, call_spine,
919
+ channel](MessageHandle msg) -> absl::optional<MessageHandle> {
920
+ auto r = call->OnServerToClientMessage(std::move(msg), channel);
921
+ if (r.ok()) return std::move(*r);
922
+ return call_spine->Cancel(ServerMetadataFromStatus(r.status()));
923
+ });
924
+ }
925
+
926
+ inline void InterceptServerTrailingMetadata(const NoInterceptor*, void*, void*,
927
+ CallSpineInterface*) {}
928
+
929
+ template <typename Derived>
930
+ inline void InterceptServerTrailingMetadata(
931
+ void (Derived::Call::*fn)(ServerMetadata&), typename Derived::Call* call,
932
+ Derived*, CallSpineInterface* call_spine) {
933
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnServerTrailingMetadata);
934
+ call_spine->server_trailing_metadata().sender.InterceptAndMap(
935
+ [call](ServerMetadataHandle md) {
936
+ call->OnServerTrailingMetadata(*md);
937
+ return md;
938
+ });
939
+ }
940
+
941
+ template <typename Derived>
942
+ inline void InterceptServerTrailingMetadata(
943
+ void (Derived::Call::*fn)(ServerMetadata&, Derived*),
944
+ typename Derived::Call* call, Derived* channel,
945
+ CallSpineInterface* call_spine) {
946
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnServerTrailingMetadata);
947
+ call_spine->server_trailing_metadata().sender.InterceptAndMap(
948
+ [call, channel](ServerMetadataHandle md) {
949
+ call->OnServerTrailingMetadata(*md, channel);
950
+ return md;
951
+ });
952
+ }
953
+
954
+ template <typename Derived>
955
+ inline void InterceptServerTrailingMetadata(
956
+ absl::Status (Derived::Call::*fn)(ServerMetadata&),
957
+ typename Derived::Call* call, Derived*, CallSpineInterface* call_spine) {
958
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnServerTrailingMetadata);
959
+ call_spine->server_trailing_metadata().sender.InterceptAndMap(
960
+ [call](ServerMetadataHandle md) -> absl::optional<ServerMetadataHandle> {
961
+ auto status = call->OnServerTrailingMetadata(*md);
962
+ if (status.ok()) return std::move(md);
963
+ return ServerMetadataFromStatus(status);
964
+ });
965
+ }
966
+
967
+ inline void InterceptFinalize(const NoInterceptor*, void*, void*) {}
968
+
969
+ template <class Call>
970
+ inline void InterceptFinalize(void (Call::*fn)(const grpc_call_final_info*),
971
+ void*, Call* call) {
972
+ GPR_DEBUG_ASSERT(fn == &Call::OnFinalize);
973
+ GetContext<CallFinalization>()->Add(
974
+ [call](const grpc_call_final_info* final_info) {
975
+ call->OnFinalize(final_info);
976
+ });
977
+ }
978
+
979
+ template <class Derived>
980
+ inline void InterceptFinalize(
981
+ void (Derived::Call::*fn)(const grpc_call_final_info*, Derived*),
982
+ Derived* channel, typename Derived::Call* call) {
983
+ GPR_DEBUG_ASSERT(fn == &Derived::Call::OnFinalize);
984
+ GetContext<CallFinalization>()->Add(
985
+ [call, channel](const grpc_call_final_info* final_info) {
986
+ call->OnFinalize(final_info, channel);
987
+ });
988
+ }
989
+
990
+ template <typename Derived>
991
+ absl::enable_if_t<std::is_empty<FilterCallData<Derived>>::value,
992
+ FilterCallData<Derived>*>
993
+ MakeFilterCall(Derived*) {
994
+ static FilterCallData<Derived> call{nullptr};
995
+ return &call;
996
+ }
997
+
998
+ template <typename Derived>
999
+ absl::enable_if_t<!std::is_empty<FilterCallData<Derived>>::value,
1000
+ FilterCallData<Derived>*>
1001
+ MakeFilterCall(Derived* derived) {
1002
+ return GetContext<Arena>()->ManagedNew<FilterCallData<Derived>>(derived);
1003
+ }
1004
+
1005
+ } // namespace promise_filter_detail
1006
+
1007
+ // Base class for promise-based channel filters.
1008
+ // Eventually this machinery will move elsewhere (the interception logic will
1009
+ // move directly into the channel stack, and so filters will just directly
1010
+ // derive from `ChannelFilter`)
1011
+ //
1012
+ // Implements new-style call filters, and polyfills them into the previous
1013
+ // scheme.
1014
+ //
1015
+ // Call filters:
1016
+ // Derived types should declare a class `Call` with the following members:
1017
+ // - OnClientInitialMetadata - $VALUE_TYPE = ClientMetadata
1018
+ // - OnServerInitialMetadata - $VALUE_TYPE = ServerMetadata
1019
+ // - OnServerToClientMessage - $VALUE_TYPE = Message
1020
+ // - OnClientToServerMessage - $VALUE_TYPE = Message
1021
+ // - OnServerTrailingMetadata - $VALUE_TYPE = ServerMetadata
1022
+ // - OnFinalize - special, see below
1023
+ // These members define an interception point for a particular event in
1024
+ // the call lifecycle.
1025
+ // The type of these members matters, and is selectable by the class
1026
+ // author. For $INTERCEPTOR_NAME in the above list:
1027
+ // - static const NoInterceptor $INTERCEPTOR_NAME:
1028
+ // defines that this filter does not intercept this event.
1029
+ // there is zero runtime cost added to handling that event by this filter.
1030
+ // - void $INTERCEPTOR_NAME($VALUE_TYPE&):
1031
+ // the filter intercepts this event, and can modify the value.
1032
+ // it never fails.
1033
+ // - absl::Status $INTERCEPTOR_NAME($VALUE_TYPE&):
1034
+ // the filter intercepts this event, and can modify the value.
1035
+ // it can fail, in which case the call will be aborted.
1036
+ // - ServerMetadataHandle $INTERCEPTOR_NAME($VALUE_TYPE&)
1037
+ // the filter intercepts this event, and can modify the value.
1038
+ // the filter can return nullptr for success, or a metadata handle for
1039
+ // failure (in which case the call will be aborted).
1040
+ // useful for cases where the exact metadata returned needs to be customized.
1041
+ // - void $INTERCEPTOR_NAME($VALUE_TYPE&, Derived*):
1042
+ // the filter intercepts this event, and can modify the value.
1043
+ // it can access the channel via the second argument.
1044
+ // it never fails.
1045
+ // - absl::Status $INTERCEPTOR_NAME($VALUE_TYPE&, Derived*):
1046
+ // the filter intercepts this event, and can modify the value.
1047
+ // it can access the channel via the second argument.
1048
+ // it can fail, in which case the call will be aborted.
1049
+ // - ServerMetadataHandle $INTERCEPTOR_NAME($VALUE_TYPE&, Derived*)
1050
+ // the filter intercepts this event, and can modify the value.
1051
+ // it can access the channel via the second argument.
1052
+ // the filter can return nullptr for success, or a metadata handle for
1053
+ // failure (in which case the call will be aborted).
1054
+ // useful for cases where the exact metadata returned needs to be customized.
1055
+ // It's also acceptable to return a promise that resolves to the
1056
+ // relevant return type listed above.
1057
+ // Finally, OnFinalize can be added to intecept call finalization.
1058
+ // It must have one of the signatures:
1059
+ // - static const NoInterceptor OnFinalize:
1060
+ // the filter does not intercept call finalization.
1061
+ // - void OnFinalize(const grpc_call_final_info*):
1062
+ // the filter intercepts call finalization.
1063
+ template <typename Derived>
1064
+ class ImplementChannelFilter : public ChannelFilter {
1065
+ public:
1066
+ // Natively construct a v3 call.
1067
+ void InitCall(CallSpineInterface* call_spine) {
1068
+ typename Derived::Call* call =
1069
+ GetContext<Arena>()
1070
+ ->ManagedNew<promise_filter_detail::CallWrapper<Derived>>(
1071
+ static_cast<Derived*>(this));
1072
+ promise_filter_detail::InterceptClientInitialMetadata(
1073
+ &Derived::Call::OnClientInitialMetadata, call,
1074
+ static_cast<Derived*>(this), call_spine);
1075
+ promise_filter_detail::InterceptClientToServerMessage(
1076
+ &Derived::Call::OnClientToServerMessage, call,
1077
+ static_cast<Derived*>(this), call_spine);
1078
+ promise_filter_detail::InterceptServerInitialMetadata(
1079
+ &Derived::Call::OnServerInitialMetadata, call,
1080
+ static_cast<Derived*>(this), call_spine);
1081
+ promise_filter_detail::InterceptServerToClientMessage(
1082
+ &Derived::Call::OnServerToClientMessage, call,
1083
+ static_cast<Derived*>(this), call_spine);
1084
+ promise_filter_detail::InterceptServerTrailingMetadata(
1085
+ &Derived::Call::OnServerTrailingMetadata, call,
1086
+ static_cast<Derived*>(this), call_spine);
1087
+ promise_filter_detail::InterceptFinalize(&Derived::Call::OnFinalize,
1088
+ static_cast<Derived*>(this), call);
1089
+ }
1090
+
1091
+ // Polyfill for the original promise scheme.
1092
+ // Allows writing v3 filters that work with v2 stacks.
1093
+ // (and consequently also v1 stacks since we can polyfill back to that too).
1094
+ ArenaPromise<ServerMetadataHandle> MakeCallPromise(
1095
+ CallArgs call_args, NextPromiseFactory next_promise_factory) final {
1096
+ auto* call = promise_filter_detail::MakeFilterCall<Derived>(
1097
+ static_cast<Derived*>(this));
1098
+ promise_filter_detail::InterceptClientToServerMessage(
1099
+ &Derived::Call::OnClientToServerMessage, call, call_args);
1100
+ promise_filter_detail::InterceptServerInitialMetadata(
1101
+ &Derived::Call::OnServerInitialMetadata, call, call_args);
1102
+ promise_filter_detail::InterceptServerToClientMessage(
1103
+ &Derived::Call::OnServerToClientMessage, call, call_args);
1104
+ promise_filter_detail::InterceptFinalize(
1105
+ &Derived::Call::OnFinalize, static_cast<Derived*>(this),
1106
+ static_cast<typename Derived::Call*>(&call->call));
1107
+ return promise_filter_detail::MapResult(
1108
+ &Derived::Call::OnServerTrailingMetadata,
1109
+ promise_filter_detail::RaceAsyncCompletion<
1110
+ promise_filter_detail::CallHasAsyncErrorInterceptor<Derived>()>::
1111
+ Run(promise_filter_detail::RunCall(
1112
+ &Derived::Call::OnClientInitialMetadata,
1113
+ std::move(call_args), std::move(next_promise_factory),
1114
+ call),
1115
+ &call->error_latch),
1116
+ call);
1117
+ }
1118
+ };
1119
+
125
1120
  // Designator for whether a filter is client side or server side.
126
1121
  // Please don't use this outside calls to MakePromiseBasedFilter - it's
127
1122
  // intended to be deleted once the promise conversion is complete.
@@ -912,7 +1907,49 @@ struct ChannelFilterWithFlagsMethods {
912
1907
  // ChannelArgs channel_args, ChannelFilter::Args filter_args);
913
1908
  // };
914
1909
  template <typename F, FilterEndpoint kEndpoint, uint8_t kFlags = 0>
915
- absl::enable_if_t<std::is_base_of<ChannelFilter, F>::value, grpc_channel_filter>
1910
+ absl::enable_if_t<std::is_base_of<ChannelFilter, F>::value &&
1911
+ !std::is_base_of<ImplementChannelFilter<F>, F>::value,
1912
+ grpc_channel_filter>
1913
+ MakePromiseBasedFilter(const char* name) {
1914
+ using CallData = promise_filter_detail::CallData<kEndpoint>;
1915
+
1916
+ return grpc_channel_filter{
1917
+ // start_transport_stream_op_batch
1918
+ promise_filter_detail::BaseCallDataMethods::StartTransportStreamOpBatch,
1919
+ // make_call_promise
1920
+ promise_filter_detail::ChannelFilterMethods::MakeCallPromise,
1921
+ nullptr,
1922
+ // start_transport_op
1923
+ promise_filter_detail::ChannelFilterMethods::StartTransportOp,
1924
+ // sizeof_call_data
1925
+ sizeof(CallData),
1926
+ // init_call_elem
1927
+ promise_filter_detail::CallDataFilterWithFlagsMethods<
1928
+ CallData, kFlags>::InitCallElem,
1929
+ // set_pollset_or_pollset_set
1930
+ promise_filter_detail::BaseCallDataMethods::SetPollsetOrPollsetSet,
1931
+ // destroy_call_elem
1932
+ promise_filter_detail::CallDataFilterWithFlagsMethods<
1933
+ CallData, kFlags>::DestroyCallElem,
1934
+ // sizeof_channel_data
1935
+ sizeof(F),
1936
+ // init_channel_elem
1937
+ promise_filter_detail::ChannelFilterWithFlagsMethods<
1938
+ F, kFlags>::InitChannelElem,
1939
+ // post_init_channel_elem
1940
+ promise_filter_detail::ChannelFilterMethods::PostInitChannelElem,
1941
+ // destroy_channel_elem
1942
+ promise_filter_detail::ChannelFilterMethods::DestroyChannelElem,
1943
+ // get_channel_info
1944
+ promise_filter_detail::ChannelFilterMethods::GetChannelInfo,
1945
+ // name
1946
+ name,
1947
+ };
1948
+ }
1949
+
1950
+ template <typename F, FilterEndpoint kEndpoint, uint8_t kFlags = 0>
1951
+ absl::enable_if_t<std::is_base_of<ImplementChannelFilter<F>, F>::value,
1952
+ grpc_channel_filter>
916
1953
  MakePromiseBasedFilter(const char* name) {
917
1954
  using CallData = promise_filter_detail::CallData<kEndpoint>;
918
1955
 
@@ -921,6 +1958,9 @@ MakePromiseBasedFilter(const char* name) {
921
1958
  promise_filter_detail::BaseCallDataMethods::StartTransportStreamOpBatch,
922
1959
  // make_call_promise
923
1960
  promise_filter_detail::ChannelFilterMethods::MakeCallPromise,
1961
+ [](grpc_channel_element* elem, CallSpineInterface* args) {
1962
+ static_cast<F*>(elem->channel_data)->InitCall(args);
1963
+ },
924
1964
  // start_transport_op
925
1965
  promise_filter_detail::ChannelFilterMethods::StartTransportOp,
926
1966
  // sizeof_call_data