grpc 1.60.2 → 1.61.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
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