xref: /aosp_15_r20/external/grpc-grpc/src/php/lib/Grpc/BaseStub.php (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1*cc02d7e2SAndroid Build Coastguard Worker<?php
2*cc02d7e2SAndroid Build Coastguard Worker/*
3*cc02d7e2SAndroid Build Coastguard Worker *
4*cc02d7e2SAndroid Build Coastguard Worker * Copyright 2015 gRPC authors.
5*cc02d7e2SAndroid Build Coastguard Worker *
6*cc02d7e2SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
7*cc02d7e2SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
8*cc02d7e2SAndroid Build Coastguard Worker * You may obtain a copy of the License at
9*cc02d7e2SAndroid Build Coastguard Worker *
10*cc02d7e2SAndroid Build Coastguard Worker *     http://www.apache.org/licenses/LICENSE-2.0
11*cc02d7e2SAndroid Build Coastguard Worker *
12*cc02d7e2SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
13*cc02d7e2SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
14*cc02d7e2SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15*cc02d7e2SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
16*cc02d7e2SAndroid Build Coastguard Worker * limitations under the License.
17*cc02d7e2SAndroid Build Coastguard Worker *
18*cc02d7e2SAndroid Build Coastguard Worker */
19*cc02d7e2SAndroid Build Coastguard Worker
20*cc02d7e2SAndroid Build Coastguard Workernamespace Grpc;
21*cc02d7e2SAndroid Build Coastguard Worker
22*cc02d7e2SAndroid Build Coastguard Worker/**
23*cc02d7e2SAndroid Build Coastguard Worker * Base class for generated client stubs. Stub methods are expected to call
24*cc02d7e2SAndroid Build Coastguard Worker * _simpleRequest or _streamRequest and return the result.
25*cc02d7e2SAndroid Build Coastguard Worker */
26*cc02d7e2SAndroid Build Coastguard Workerclass BaseStub
27*cc02d7e2SAndroid Build Coastguard Worker{
28*cc02d7e2SAndroid Build Coastguard Worker    private $hostname;
29*cc02d7e2SAndroid Build Coastguard Worker    private $hostname_override;
30*cc02d7e2SAndroid Build Coastguard Worker    private $channel;
31*cc02d7e2SAndroid Build Coastguard Worker    private $call_invoker;
32*cc02d7e2SAndroid Build Coastguard Worker
33*cc02d7e2SAndroid Build Coastguard Worker    // a callback function
34*cc02d7e2SAndroid Build Coastguard Worker    private $update_metadata;
35*cc02d7e2SAndroid Build Coastguard Worker
36*cc02d7e2SAndroid Build Coastguard Worker    /**
37*cc02d7e2SAndroid Build Coastguard Worker     * @param string  $hostname
38*cc02d7e2SAndroid Build Coastguard Worker     * @param array   $opts
39*cc02d7e2SAndroid Build Coastguard Worker     *  - 'update_metadata': (optional) a callback function which takes in a
40*cc02d7e2SAndroid Build Coastguard Worker     * metadata array, and returns an updated metadata array
41*cc02d7e2SAndroid Build Coastguard Worker     *  - 'grpc.primary_user_agent': (optional) a user-agent string
42*cc02d7e2SAndroid Build Coastguard Worker     * @param Channel|InterceptorChannel $channel An already created Channel or InterceptorChannel object (optional)
43*cc02d7e2SAndroid Build Coastguard Worker     */
44*cc02d7e2SAndroid Build Coastguard Worker    public function __construct($hostname, $opts, $channel = null)
45*cc02d7e2SAndroid Build Coastguard Worker    {
46*cc02d7e2SAndroid Build Coastguard Worker        if (!method_exists('Grpc\ChannelCredentials', 'isDefaultRootsPemSet') ||
47*cc02d7e2SAndroid Build Coastguard Worker            !ChannelCredentials::isDefaultRootsPemSet()) {
48*cc02d7e2SAndroid Build Coastguard Worker            $ssl_roots = file_get_contents(
49*cc02d7e2SAndroid Build Coastguard Worker                dirname(__FILE__).'/../../../../etc/roots.pem'
50*cc02d7e2SAndroid Build Coastguard Worker            );
51*cc02d7e2SAndroid Build Coastguard Worker            ChannelCredentials::setDefaultRootsPem($ssl_roots);
52*cc02d7e2SAndroid Build Coastguard Worker        }
53*cc02d7e2SAndroid Build Coastguard Worker
54*cc02d7e2SAndroid Build Coastguard Worker        $this->hostname = $hostname;
55*cc02d7e2SAndroid Build Coastguard Worker        $this->update_metadata = null;
56*cc02d7e2SAndroid Build Coastguard Worker        if (isset($opts['update_metadata'])) {
57*cc02d7e2SAndroid Build Coastguard Worker            if (is_callable($opts['update_metadata'])) {
58*cc02d7e2SAndroid Build Coastguard Worker                $this->update_metadata = $opts['update_metadata'];
59*cc02d7e2SAndroid Build Coastguard Worker            }
60*cc02d7e2SAndroid Build Coastguard Worker            unset($opts['update_metadata']);
61*cc02d7e2SAndroid Build Coastguard Worker        }
62*cc02d7e2SAndroid Build Coastguard Worker        if (!empty($opts['grpc.ssl_target_name_override'])) {
63*cc02d7e2SAndroid Build Coastguard Worker            $this->hostname_override = $opts['grpc.ssl_target_name_override'];
64*cc02d7e2SAndroid Build Coastguard Worker        }
65*cc02d7e2SAndroid Build Coastguard Worker        if (isset($opts['grpc_call_invoker'])) {
66*cc02d7e2SAndroid Build Coastguard Worker            $this->call_invoker = $opts['grpc_call_invoker'];
67*cc02d7e2SAndroid Build Coastguard Worker            unset($opts['grpc_call_invoker']);
68*cc02d7e2SAndroid Build Coastguard Worker            $channel_opts = $this->updateOpts($opts);
69*cc02d7e2SAndroid Build Coastguard Worker            // If the grpc_call_invoker is defined, use the channel created by the call invoker.
70*cc02d7e2SAndroid Build Coastguard Worker            $this->channel = $this->call_invoker->createChannelFactory($hostname, $channel_opts);
71*cc02d7e2SAndroid Build Coastguard Worker            return;
72*cc02d7e2SAndroid Build Coastguard Worker        }
73*cc02d7e2SAndroid Build Coastguard Worker        $this->call_invoker = new DefaultCallInvoker();
74*cc02d7e2SAndroid Build Coastguard Worker        if ($channel) {
75*cc02d7e2SAndroid Build Coastguard Worker            if (!is_a($channel, 'Grpc\Channel') &&
76*cc02d7e2SAndroid Build Coastguard Worker                !is_a($channel, 'Grpc\Internal\InterceptorChannel')) {
77*cc02d7e2SAndroid Build Coastguard Worker                throw new \Exception('The channel argument is not a Channel object '.
78*cc02d7e2SAndroid Build Coastguard Worker                    'or an InterceptorChannel object created by '.
79*cc02d7e2SAndroid Build Coastguard Worker                    'Interceptor::intercept($channel, Interceptor|Interceptor[] $interceptors)');
80*cc02d7e2SAndroid Build Coastguard Worker            }
81*cc02d7e2SAndroid Build Coastguard Worker            $this->channel = $channel;
82*cc02d7e2SAndroid Build Coastguard Worker            return;
83*cc02d7e2SAndroid Build Coastguard Worker        }
84*cc02d7e2SAndroid Build Coastguard Worker
85*cc02d7e2SAndroid Build Coastguard Worker        $this->channel = static::getDefaultChannel($hostname, $opts);
86*cc02d7e2SAndroid Build Coastguard Worker    }
87*cc02d7e2SAndroid Build Coastguard Worker
88*cc02d7e2SAndroid Build Coastguard Worker    private static function updateOpts($opts) {
89*cc02d7e2SAndroid Build Coastguard Worker        if (!empty($opts['grpc.primary_user_agent'])) {
90*cc02d7e2SAndroid Build Coastguard Worker            $opts['grpc.primary_user_agent'] .= ' ';
91*cc02d7e2SAndroid Build Coastguard Worker        } else {
92*cc02d7e2SAndroid Build Coastguard Worker            $opts['grpc.primary_user_agent'] = '';
93*cc02d7e2SAndroid Build Coastguard Worker        }
94*cc02d7e2SAndroid Build Coastguard Worker        if (defined('\Grpc\VERSION')) {
95*cc02d7e2SAndroid Build Coastguard Worker            $version_str = \Grpc\VERSION;
96*cc02d7e2SAndroid Build Coastguard Worker        } else {
97*cc02d7e2SAndroid Build Coastguard Worker            if (!file_exists($composerFile = __DIR__.'/../../composer.json')) {
98*cc02d7e2SAndroid Build Coastguard Worker                // for grpc/grpc-php subpackage
99*cc02d7e2SAndroid Build Coastguard Worker                $composerFile = __DIR__.'/../composer.json';
100*cc02d7e2SAndroid Build Coastguard Worker            }
101*cc02d7e2SAndroid Build Coastguard Worker            $package_config = json_decode(file_get_contents($composerFile), true);
102*cc02d7e2SAndroid Build Coastguard Worker            $version_str = $package_config['version'];
103*cc02d7e2SAndroid Build Coastguard Worker        }
104*cc02d7e2SAndroid Build Coastguard Worker        $opts['grpc.primary_user_agent'] .= 'grpc-php/'.$version_str;
105*cc02d7e2SAndroid Build Coastguard Worker        if (!array_key_exists('credentials', $opts)) {
106*cc02d7e2SAndroid Build Coastguard Worker            throw new \Exception("The opts['credentials'] key is now ".
107*cc02d7e2SAndroid Build Coastguard Worker                'required. Please see one of the '.
108*cc02d7e2SAndroid Build Coastguard Worker                'ChannelCredentials::create methods');
109*cc02d7e2SAndroid Build Coastguard Worker        }
110*cc02d7e2SAndroid Build Coastguard Worker        return $opts;
111*cc02d7e2SAndroid Build Coastguard Worker    }
112*cc02d7e2SAndroid Build Coastguard Worker
113*cc02d7e2SAndroid Build Coastguard Worker    /**
114*cc02d7e2SAndroid Build Coastguard Worker     * Creates and returns the default Channel
115*cc02d7e2SAndroid Build Coastguard Worker     *
116*cc02d7e2SAndroid Build Coastguard Worker     * @param array $opts Channel constructor options
117*cc02d7e2SAndroid Build Coastguard Worker     *
118*cc02d7e2SAndroid Build Coastguard Worker     * @return Channel The channel
119*cc02d7e2SAndroid Build Coastguard Worker     */
120*cc02d7e2SAndroid Build Coastguard Worker    public static function getDefaultChannel($hostname, array $opts)
121*cc02d7e2SAndroid Build Coastguard Worker    {
122*cc02d7e2SAndroid Build Coastguard Worker        $channel_opts = self::updateOpts($opts);
123*cc02d7e2SAndroid Build Coastguard Worker        return new Channel($hostname, $channel_opts);
124*cc02d7e2SAndroid Build Coastguard Worker    }
125*cc02d7e2SAndroid Build Coastguard Worker
126*cc02d7e2SAndroid Build Coastguard Worker    /**
127*cc02d7e2SAndroid Build Coastguard Worker     * @return string The URI of the endpoint
128*cc02d7e2SAndroid Build Coastguard Worker     */
129*cc02d7e2SAndroid Build Coastguard Worker    public function getTarget()
130*cc02d7e2SAndroid Build Coastguard Worker    {
131*cc02d7e2SAndroid Build Coastguard Worker        return $this->channel->getTarget();
132*cc02d7e2SAndroid Build Coastguard Worker    }
133*cc02d7e2SAndroid Build Coastguard Worker
134*cc02d7e2SAndroid Build Coastguard Worker    /**
135*cc02d7e2SAndroid Build Coastguard Worker     * @param bool $try_to_connect (optional)
136*cc02d7e2SAndroid Build Coastguard Worker     *
137*cc02d7e2SAndroid Build Coastguard Worker     * @return int The grpc connectivity state
138*cc02d7e2SAndroid Build Coastguard Worker     */
139*cc02d7e2SAndroid Build Coastguard Worker    public function getConnectivityState($try_to_connect = false)
140*cc02d7e2SAndroid Build Coastguard Worker    {
141*cc02d7e2SAndroid Build Coastguard Worker        return $this->channel->getConnectivityState($try_to_connect);
142*cc02d7e2SAndroid Build Coastguard Worker    }
143*cc02d7e2SAndroid Build Coastguard Worker
144*cc02d7e2SAndroid Build Coastguard Worker    /**
145*cc02d7e2SAndroid Build Coastguard Worker     * @param int $timeout in microseconds
146*cc02d7e2SAndroid Build Coastguard Worker     *
147*cc02d7e2SAndroid Build Coastguard Worker     * @return bool true if channel is ready
148*cc02d7e2SAndroid Build Coastguard Worker     * @throws Exception if channel is in FATAL_ERROR state
149*cc02d7e2SAndroid Build Coastguard Worker     */
150*cc02d7e2SAndroid Build Coastguard Worker    public function waitForReady($timeout)
151*cc02d7e2SAndroid Build Coastguard Worker    {
152*cc02d7e2SAndroid Build Coastguard Worker        $new_state = $this->getConnectivityState(true);
153*cc02d7e2SAndroid Build Coastguard Worker        if ($this->_checkConnectivityState($new_state)) {
154*cc02d7e2SAndroid Build Coastguard Worker            return true;
155*cc02d7e2SAndroid Build Coastguard Worker        }
156*cc02d7e2SAndroid Build Coastguard Worker
157*cc02d7e2SAndroid Build Coastguard Worker        $now = Timeval::now();
158*cc02d7e2SAndroid Build Coastguard Worker        $delta = new Timeval($timeout);
159*cc02d7e2SAndroid Build Coastguard Worker        $deadline = $now->add($delta);
160*cc02d7e2SAndroid Build Coastguard Worker
161*cc02d7e2SAndroid Build Coastguard Worker        while ($this->channel->watchConnectivityState($new_state, $deadline)) {
162*cc02d7e2SAndroid Build Coastguard Worker            // state has changed before deadline
163*cc02d7e2SAndroid Build Coastguard Worker            $new_state = $this->getConnectivityState();
164*cc02d7e2SAndroid Build Coastguard Worker            if ($this->_checkConnectivityState($new_state)) {
165*cc02d7e2SAndroid Build Coastguard Worker                return true;
166*cc02d7e2SAndroid Build Coastguard Worker            }
167*cc02d7e2SAndroid Build Coastguard Worker        }
168*cc02d7e2SAndroid Build Coastguard Worker        // deadline has passed
169*cc02d7e2SAndroid Build Coastguard Worker        $new_state = $this->getConnectivityState();
170*cc02d7e2SAndroid Build Coastguard Worker
171*cc02d7e2SAndroid Build Coastguard Worker        return $this->_checkConnectivityState($new_state);
172*cc02d7e2SAndroid Build Coastguard Worker    }
173*cc02d7e2SAndroid Build Coastguard Worker
174*cc02d7e2SAndroid Build Coastguard Worker    /**
175*cc02d7e2SAndroid Build Coastguard Worker     * Close the communication channel associated with this stub.
176*cc02d7e2SAndroid Build Coastguard Worker     */
177*cc02d7e2SAndroid Build Coastguard Worker    public function close()
178*cc02d7e2SAndroid Build Coastguard Worker    {
179*cc02d7e2SAndroid Build Coastguard Worker        $this->channel->close();
180*cc02d7e2SAndroid Build Coastguard Worker    }
181*cc02d7e2SAndroid Build Coastguard Worker
182*cc02d7e2SAndroid Build Coastguard Worker    /**
183*cc02d7e2SAndroid Build Coastguard Worker     * @param $new_state Connect state
184*cc02d7e2SAndroid Build Coastguard Worker     *
185*cc02d7e2SAndroid Build Coastguard Worker     * @return bool true if state is CHANNEL_READY
186*cc02d7e2SAndroid Build Coastguard Worker     * @throws Exception if state is CHANNEL_FATAL_FAILURE
187*cc02d7e2SAndroid Build Coastguard Worker     */
188*cc02d7e2SAndroid Build Coastguard Worker    private function _checkConnectivityState($new_state)
189*cc02d7e2SAndroid Build Coastguard Worker    {
190*cc02d7e2SAndroid Build Coastguard Worker        if ($new_state == \Grpc\CHANNEL_READY) {
191*cc02d7e2SAndroid Build Coastguard Worker            return true;
192*cc02d7e2SAndroid Build Coastguard Worker        }
193*cc02d7e2SAndroid Build Coastguard Worker        if ($new_state == \Grpc\CHANNEL_FATAL_FAILURE) {
194*cc02d7e2SAndroid Build Coastguard Worker            throw new \Exception('Failed to connect to server');
195*cc02d7e2SAndroid Build Coastguard Worker        }
196*cc02d7e2SAndroid Build Coastguard Worker
197*cc02d7e2SAndroid Build Coastguard Worker        return false;
198*cc02d7e2SAndroid Build Coastguard Worker    }
199*cc02d7e2SAndroid Build Coastguard Worker
200*cc02d7e2SAndroid Build Coastguard Worker    /**
201*cc02d7e2SAndroid Build Coastguard Worker     * constructs the auth uri for the jwt.
202*cc02d7e2SAndroid Build Coastguard Worker     *
203*cc02d7e2SAndroid Build Coastguard Worker     * @param string $method The method string
204*cc02d7e2SAndroid Build Coastguard Worker     *
205*cc02d7e2SAndroid Build Coastguard Worker     * @return string The URL string
206*cc02d7e2SAndroid Build Coastguard Worker     */
207*cc02d7e2SAndroid Build Coastguard Worker    private function _get_jwt_aud_uri($method)
208*cc02d7e2SAndroid Build Coastguard Worker    {
209*cc02d7e2SAndroid Build Coastguard Worker        // TODO(jtattermusch): This is not the correct implementation
210*cc02d7e2SAndroid Build Coastguard Worker        // of extracting JWT "aud" claim. We should rely on
211*cc02d7e2SAndroid Build Coastguard Worker        // grpc_metadata_credentials_plugin which
212*cc02d7e2SAndroid Build Coastguard Worker        // also provides the correct value of "aud" claim
213*cc02d7e2SAndroid Build Coastguard Worker        // in the grpc_auth_metadata_context.service_url field.
214*cc02d7e2SAndroid Build Coastguard Worker        // Trying to do the construction of "aud" field ourselves
215*cc02d7e2SAndroid Build Coastguard Worker        // is bad.
216*cc02d7e2SAndroid Build Coastguard Worker        $last_slash_idx = strrpos($method, '/');
217*cc02d7e2SAndroid Build Coastguard Worker        if ($last_slash_idx === false) {
218*cc02d7e2SAndroid Build Coastguard Worker            throw new \InvalidArgumentException(
219*cc02d7e2SAndroid Build Coastguard Worker                'service name must have a slash'
220*cc02d7e2SAndroid Build Coastguard Worker            );
221*cc02d7e2SAndroid Build Coastguard Worker        }
222*cc02d7e2SAndroid Build Coastguard Worker        $service_name = substr($method, 0, $last_slash_idx);
223*cc02d7e2SAndroid Build Coastguard Worker
224*cc02d7e2SAndroid Build Coastguard Worker        if ($this->hostname_override) {
225*cc02d7e2SAndroid Build Coastguard Worker            $hostname = $this->hostname_override;
226*cc02d7e2SAndroid Build Coastguard Worker        } else {
227*cc02d7e2SAndroid Build Coastguard Worker            $hostname = $this->hostname;
228*cc02d7e2SAndroid Build Coastguard Worker        }
229*cc02d7e2SAndroid Build Coastguard Worker
230*cc02d7e2SAndroid Build Coastguard Worker        // Remove the port if it is 443
231*cc02d7e2SAndroid Build Coastguard Worker        // See https://github.com/grpc/grpc/blob/07c9f7a36b2a0d34fcffebc85649cf3b8c339b5d/src/core/lib/security/transport/client_auth_filter.cc#L205
232*cc02d7e2SAndroid Build Coastguard Worker        if ((strlen($hostname) > 4) && (substr($hostname, -4) === ":443")) {
233*cc02d7e2SAndroid Build Coastguard Worker            $hostname = substr($hostname, 0, -4);
234*cc02d7e2SAndroid Build Coastguard Worker        }
235*cc02d7e2SAndroid Build Coastguard Worker
236*cc02d7e2SAndroid Build Coastguard Worker        return 'https://'.$hostname.$service_name;
237*cc02d7e2SAndroid Build Coastguard Worker    }
238*cc02d7e2SAndroid Build Coastguard Worker
239*cc02d7e2SAndroid Build Coastguard Worker    /**
240*cc02d7e2SAndroid Build Coastguard Worker     * validate and normalize the metadata array.
241*cc02d7e2SAndroid Build Coastguard Worker     *
242*cc02d7e2SAndroid Build Coastguard Worker     * @param array $metadata The metadata map
243*cc02d7e2SAndroid Build Coastguard Worker     *
244*cc02d7e2SAndroid Build Coastguard Worker     * @return array $metadata Validated and key-normalized metadata map
245*cc02d7e2SAndroid Build Coastguard Worker     * @throws InvalidArgumentException if key contains invalid characters
246*cc02d7e2SAndroid Build Coastguard Worker     */
247*cc02d7e2SAndroid Build Coastguard Worker    private function _validate_and_normalize_metadata($metadata)
248*cc02d7e2SAndroid Build Coastguard Worker    {
249*cc02d7e2SAndroid Build Coastguard Worker        $metadata_copy = [];
250*cc02d7e2SAndroid Build Coastguard Worker        foreach ($metadata as $key => $value) {
251*cc02d7e2SAndroid Build Coastguard Worker            if (!preg_match('/^[.A-Za-z\d_-]+$/', $key)) {
252*cc02d7e2SAndroid Build Coastguard Worker                throw new \InvalidArgumentException(
253*cc02d7e2SAndroid Build Coastguard Worker                    'Metadata keys must be nonempty strings containing only '.
254*cc02d7e2SAndroid Build Coastguard Worker                    'alphanumeric characters, hyphens, underscores and dots'
255*cc02d7e2SAndroid Build Coastguard Worker                );
256*cc02d7e2SAndroid Build Coastguard Worker            }
257*cc02d7e2SAndroid Build Coastguard Worker            $metadata_copy[strtolower($key)] = $value;
258*cc02d7e2SAndroid Build Coastguard Worker        }
259*cc02d7e2SAndroid Build Coastguard Worker
260*cc02d7e2SAndroid Build Coastguard Worker        return $metadata_copy;
261*cc02d7e2SAndroid Build Coastguard Worker    }
262*cc02d7e2SAndroid Build Coastguard Worker
263*cc02d7e2SAndroid Build Coastguard Worker    /**
264*cc02d7e2SAndroid Build Coastguard Worker     * Create a function which can be used to create UnaryCall
265*cc02d7e2SAndroid Build Coastguard Worker     *
266*cc02d7e2SAndroid Build Coastguard Worker     * @param Channel|InterceptorChannel   $channel
267*cc02d7e2SAndroid Build Coastguard Worker     * @param callable $deserialize A function that deserializes the response
268*cc02d7e2SAndroid Build Coastguard Worker     *
269*cc02d7e2SAndroid Build Coastguard Worker     * @return \Closure
270*cc02d7e2SAndroid Build Coastguard Worker     */
271*cc02d7e2SAndroid Build Coastguard Worker    private function _GrpcUnaryUnary($channel)
272*cc02d7e2SAndroid Build Coastguard Worker    {
273*cc02d7e2SAndroid Build Coastguard Worker        return function ($method,
274*cc02d7e2SAndroid Build Coastguard Worker                         $argument,
275*cc02d7e2SAndroid Build Coastguard Worker                         $deserialize,
276*cc02d7e2SAndroid Build Coastguard Worker                         array $metadata = [],
277*cc02d7e2SAndroid Build Coastguard Worker                         array $options = []) use ($channel) {
278*cc02d7e2SAndroid Build Coastguard Worker            $call = $this->call_invoker->UnaryCall(
279*cc02d7e2SAndroid Build Coastguard Worker                $channel,
280*cc02d7e2SAndroid Build Coastguard Worker                $method,
281*cc02d7e2SAndroid Build Coastguard Worker                $deserialize,
282*cc02d7e2SAndroid Build Coastguard Worker                $options
283*cc02d7e2SAndroid Build Coastguard Worker            );
284*cc02d7e2SAndroid Build Coastguard Worker            $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
285*cc02d7e2SAndroid Build Coastguard Worker            if (is_callable($this->update_metadata)) {
286*cc02d7e2SAndroid Build Coastguard Worker                $metadata = call_user_func(
287*cc02d7e2SAndroid Build Coastguard Worker                    $this->update_metadata,
288*cc02d7e2SAndroid Build Coastguard Worker                    $metadata,
289*cc02d7e2SAndroid Build Coastguard Worker                    $jwt_aud_uri
290*cc02d7e2SAndroid Build Coastguard Worker                );
291*cc02d7e2SAndroid Build Coastguard Worker            }
292*cc02d7e2SAndroid Build Coastguard Worker            $metadata = $this->_validate_and_normalize_metadata(
293*cc02d7e2SAndroid Build Coastguard Worker                $metadata
294*cc02d7e2SAndroid Build Coastguard Worker            );
295*cc02d7e2SAndroid Build Coastguard Worker            $call->start($argument, $metadata, $options);
296*cc02d7e2SAndroid Build Coastguard Worker            return $call;
297*cc02d7e2SAndroid Build Coastguard Worker        };
298*cc02d7e2SAndroid Build Coastguard Worker    }
299*cc02d7e2SAndroid Build Coastguard Worker
300*cc02d7e2SAndroid Build Coastguard Worker    /**
301*cc02d7e2SAndroid Build Coastguard Worker     * Create a function which can be used to create ServerStreamingCall
302*cc02d7e2SAndroid Build Coastguard Worker     *
303*cc02d7e2SAndroid Build Coastguard Worker     * @param Channel|InterceptorChannel   $channel
304*cc02d7e2SAndroid Build Coastguard Worker     * @param callable $deserialize A function that deserializes the response
305*cc02d7e2SAndroid Build Coastguard Worker     *
306*cc02d7e2SAndroid Build Coastguard Worker     * @return \Closure
307*cc02d7e2SAndroid Build Coastguard Worker     */
308*cc02d7e2SAndroid Build Coastguard Worker    private function _GrpcStreamUnary($channel)
309*cc02d7e2SAndroid Build Coastguard Worker    {
310*cc02d7e2SAndroid Build Coastguard Worker        return function ($method,
311*cc02d7e2SAndroid Build Coastguard Worker                         $deserialize,
312*cc02d7e2SAndroid Build Coastguard Worker                         array $metadata = [],
313*cc02d7e2SAndroid Build Coastguard Worker                         array $options = []) use ($channel) {
314*cc02d7e2SAndroid Build Coastguard Worker            $call = $this->call_invoker->ClientStreamingCall(
315*cc02d7e2SAndroid Build Coastguard Worker                $channel,
316*cc02d7e2SAndroid Build Coastguard Worker                $method,
317*cc02d7e2SAndroid Build Coastguard Worker                $deserialize,
318*cc02d7e2SAndroid Build Coastguard Worker                $options
319*cc02d7e2SAndroid Build Coastguard Worker            );
320*cc02d7e2SAndroid Build Coastguard Worker            $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
321*cc02d7e2SAndroid Build Coastguard Worker            if (is_callable($this->update_metadata)) {
322*cc02d7e2SAndroid Build Coastguard Worker                $metadata = call_user_func(
323*cc02d7e2SAndroid Build Coastguard Worker                    $this->update_metadata,
324*cc02d7e2SAndroid Build Coastguard Worker                    $metadata,
325*cc02d7e2SAndroid Build Coastguard Worker                    $jwt_aud_uri
326*cc02d7e2SAndroid Build Coastguard Worker                );
327*cc02d7e2SAndroid Build Coastguard Worker            }
328*cc02d7e2SAndroid Build Coastguard Worker            $metadata = $this->_validate_and_normalize_metadata(
329*cc02d7e2SAndroid Build Coastguard Worker                $metadata
330*cc02d7e2SAndroid Build Coastguard Worker            );
331*cc02d7e2SAndroid Build Coastguard Worker            $call->start($metadata);
332*cc02d7e2SAndroid Build Coastguard Worker            return $call;
333*cc02d7e2SAndroid Build Coastguard Worker        };
334*cc02d7e2SAndroid Build Coastguard Worker    }
335*cc02d7e2SAndroid Build Coastguard Worker
336*cc02d7e2SAndroid Build Coastguard Worker    /**
337*cc02d7e2SAndroid Build Coastguard Worker     * Create a function which can be used to create ClientStreamingCall
338*cc02d7e2SAndroid Build Coastguard Worker     *
339*cc02d7e2SAndroid Build Coastguard Worker     * @param Channel|InterceptorChannel   $channel
340*cc02d7e2SAndroid Build Coastguard Worker     * @param callable $deserialize A function that deserializes the response
341*cc02d7e2SAndroid Build Coastguard Worker     *
342*cc02d7e2SAndroid Build Coastguard Worker     * @return \Closure
343*cc02d7e2SAndroid Build Coastguard Worker     */
344*cc02d7e2SAndroid Build Coastguard Worker    private function _GrpcUnaryStream($channel)
345*cc02d7e2SAndroid Build Coastguard Worker    {
346*cc02d7e2SAndroid Build Coastguard Worker        return function ($method,
347*cc02d7e2SAndroid Build Coastguard Worker                         $argument,
348*cc02d7e2SAndroid Build Coastguard Worker                         $deserialize,
349*cc02d7e2SAndroid Build Coastguard Worker                         array $metadata = [],
350*cc02d7e2SAndroid Build Coastguard Worker                         array $options = []) use ($channel) {
351*cc02d7e2SAndroid Build Coastguard Worker            $call = $this->call_invoker->ServerStreamingCall(
352*cc02d7e2SAndroid Build Coastguard Worker                $channel,
353*cc02d7e2SAndroid Build Coastguard Worker                $method,
354*cc02d7e2SAndroid Build Coastguard Worker                $deserialize,
355*cc02d7e2SAndroid Build Coastguard Worker                $options
356*cc02d7e2SAndroid Build Coastguard Worker            );
357*cc02d7e2SAndroid Build Coastguard Worker            $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
358*cc02d7e2SAndroid Build Coastguard Worker            if (is_callable($this->update_metadata)) {
359*cc02d7e2SAndroid Build Coastguard Worker                $metadata = call_user_func(
360*cc02d7e2SAndroid Build Coastguard Worker                    $this->update_metadata,
361*cc02d7e2SAndroid Build Coastguard Worker                    $metadata,
362*cc02d7e2SAndroid Build Coastguard Worker                    $jwt_aud_uri
363*cc02d7e2SAndroid Build Coastguard Worker                );
364*cc02d7e2SAndroid Build Coastguard Worker            }
365*cc02d7e2SAndroid Build Coastguard Worker            $metadata = $this->_validate_and_normalize_metadata(
366*cc02d7e2SAndroid Build Coastguard Worker                $metadata
367*cc02d7e2SAndroid Build Coastguard Worker            );
368*cc02d7e2SAndroid Build Coastguard Worker            $call->start($argument, $metadata, $options);
369*cc02d7e2SAndroid Build Coastguard Worker            return $call;
370*cc02d7e2SAndroid Build Coastguard Worker        };
371*cc02d7e2SAndroid Build Coastguard Worker    }
372*cc02d7e2SAndroid Build Coastguard Worker
373*cc02d7e2SAndroid Build Coastguard Worker    /**
374*cc02d7e2SAndroid Build Coastguard Worker     * Create a function which can be used to create BidiStreamingCall
375*cc02d7e2SAndroid Build Coastguard Worker     *
376*cc02d7e2SAndroid Build Coastguard Worker     * @param Channel|InterceptorChannel   $channel
377*cc02d7e2SAndroid Build Coastguard Worker     * @param callable $deserialize A function that deserializes the response
378*cc02d7e2SAndroid Build Coastguard Worker     *
379*cc02d7e2SAndroid Build Coastguard Worker     * @return \Closure
380*cc02d7e2SAndroid Build Coastguard Worker     */
381*cc02d7e2SAndroid Build Coastguard Worker    private function _GrpcStreamStream($channel)
382*cc02d7e2SAndroid Build Coastguard Worker    {
383*cc02d7e2SAndroid Build Coastguard Worker        return function ($method,
384*cc02d7e2SAndroid Build Coastguard Worker                         $deserialize,
385*cc02d7e2SAndroid Build Coastguard Worker                         array $metadata = [],
386*cc02d7e2SAndroid Build Coastguard Worker                         array $options = []) use ($channel) {
387*cc02d7e2SAndroid Build Coastguard Worker            $call = $this->call_invoker->BidiStreamingCall(
388*cc02d7e2SAndroid Build Coastguard Worker                $channel,
389*cc02d7e2SAndroid Build Coastguard Worker                $method,
390*cc02d7e2SAndroid Build Coastguard Worker                $deserialize,
391*cc02d7e2SAndroid Build Coastguard Worker                $options
392*cc02d7e2SAndroid Build Coastguard Worker            );
393*cc02d7e2SAndroid Build Coastguard Worker            $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
394*cc02d7e2SAndroid Build Coastguard Worker            if (is_callable($this->update_metadata)) {
395*cc02d7e2SAndroid Build Coastguard Worker                $metadata = call_user_func(
396*cc02d7e2SAndroid Build Coastguard Worker                    $this->update_metadata,
397*cc02d7e2SAndroid Build Coastguard Worker                    $metadata,
398*cc02d7e2SAndroid Build Coastguard Worker                    $jwt_aud_uri
399*cc02d7e2SAndroid Build Coastguard Worker                );
400*cc02d7e2SAndroid Build Coastguard Worker            }
401*cc02d7e2SAndroid Build Coastguard Worker            $metadata = $this->_validate_and_normalize_metadata(
402*cc02d7e2SAndroid Build Coastguard Worker                $metadata
403*cc02d7e2SAndroid Build Coastguard Worker            );
404*cc02d7e2SAndroid Build Coastguard Worker            $call->start($metadata);
405*cc02d7e2SAndroid Build Coastguard Worker
406*cc02d7e2SAndroid Build Coastguard Worker            return $call;
407*cc02d7e2SAndroid Build Coastguard Worker        };
408*cc02d7e2SAndroid Build Coastguard Worker    }
409*cc02d7e2SAndroid Build Coastguard Worker
410*cc02d7e2SAndroid Build Coastguard Worker    /**
411*cc02d7e2SAndroid Build Coastguard Worker     * Create a function which can be used to create UnaryCall
412*cc02d7e2SAndroid Build Coastguard Worker     *
413*cc02d7e2SAndroid Build Coastguard Worker     * @param Channel|InterceptorChannel   $channel
414*cc02d7e2SAndroid Build Coastguard Worker     * @param callable $deserialize A function that deserializes the response
415*cc02d7e2SAndroid Build Coastguard Worker     *
416*cc02d7e2SAndroid Build Coastguard Worker     * @return \Closure
417*cc02d7e2SAndroid Build Coastguard Worker     */
418*cc02d7e2SAndroid Build Coastguard Worker    private function _UnaryUnaryCallFactory($channel)
419*cc02d7e2SAndroid Build Coastguard Worker    {
420*cc02d7e2SAndroid Build Coastguard Worker        if (is_a($channel, 'Grpc\Internal\InterceptorChannel')) {
421*cc02d7e2SAndroid Build Coastguard Worker            return function ($method,
422*cc02d7e2SAndroid Build Coastguard Worker                             $argument,
423*cc02d7e2SAndroid Build Coastguard Worker                             $deserialize,
424*cc02d7e2SAndroid Build Coastguard Worker                             array $metadata = [],
425*cc02d7e2SAndroid Build Coastguard Worker                             array $options = []) use ($channel) {
426*cc02d7e2SAndroid Build Coastguard Worker                return $channel->getInterceptor()->interceptUnaryUnary(
427*cc02d7e2SAndroid Build Coastguard Worker                    $method,
428*cc02d7e2SAndroid Build Coastguard Worker                    $argument,
429*cc02d7e2SAndroid Build Coastguard Worker                    $deserialize,
430*cc02d7e2SAndroid Build Coastguard Worker                    $this->_UnaryUnaryCallFactory($channel->getNext()),
431*cc02d7e2SAndroid Build Coastguard Worker                    $metadata,
432*cc02d7e2SAndroid Build Coastguard Worker                    $options
433*cc02d7e2SAndroid Build Coastguard Worker                );
434*cc02d7e2SAndroid Build Coastguard Worker            };
435*cc02d7e2SAndroid Build Coastguard Worker        }
436*cc02d7e2SAndroid Build Coastguard Worker        return $this->_GrpcUnaryUnary($channel);
437*cc02d7e2SAndroid Build Coastguard Worker    }
438*cc02d7e2SAndroid Build Coastguard Worker
439*cc02d7e2SAndroid Build Coastguard Worker    /**
440*cc02d7e2SAndroid Build Coastguard Worker     * Create a function which can be used to create ServerStreamingCall
441*cc02d7e2SAndroid Build Coastguard Worker     *
442*cc02d7e2SAndroid Build Coastguard Worker     * @param Channel|InterceptorChannel   $channel
443*cc02d7e2SAndroid Build Coastguard Worker     * @param callable $deserialize A function that deserializes the response
444*cc02d7e2SAndroid Build Coastguard Worker     *
445*cc02d7e2SAndroid Build Coastguard Worker     * @return \Closure
446*cc02d7e2SAndroid Build Coastguard Worker     */
447*cc02d7e2SAndroid Build Coastguard Worker    private function _UnaryStreamCallFactory($channel)
448*cc02d7e2SAndroid Build Coastguard Worker    {
449*cc02d7e2SAndroid Build Coastguard Worker        if (is_a($channel, 'Grpc\Internal\InterceptorChannel')) {
450*cc02d7e2SAndroid Build Coastguard Worker            return function ($method,
451*cc02d7e2SAndroid Build Coastguard Worker                             $argument,
452*cc02d7e2SAndroid Build Coastguard Worker                             $deserialize,
453*cc02d7e2SAndroid Build Coastguard Worker                             array $metadata = [],
454*cc02d7e2SAndroid Build Coastguard Worker                             array $options = []) use ($channel) {
455*cc02d7e2SAndroid Build Coastguard Worker                return $channel->getInterceptor()->interceptUnaryStream(
456*cc02d7e2SAndroid Build Coastguard Worker                    $method,
457*cc02d7e2SAndroid Build Coastguard Worker                    $argument,
458*cc02d7e2SAndroid Build Coastguard Worker                    $deserialize,
459*cc02d7e2SAndroid Build Coastguard Worker                    $this->_UnaryStreamCallFactory($channel->getNext()),
460*cc02d7e2SAndroid Build Coastguard Worker                    $metadata,
461*cc02d7e2SAndroid Build Coastguard Worker                    $options
462*cc02d7e2SAndroid Build Coastguard Worker                );
463*cc02d7e2SAndroid Build Coastguard Worker            };
464*cc02d7e2SAndroid Build Coastguard Worker        }
465*cc02d7e2SAndroid Build Coastguard Worker        return $this->_GrpcUnaryStream($channel);
466*cc02d7e2SAndroid Build Coastguard Worker    }
467*cc02d7e2SAndroid Build Coastguard Worker
468*cc02d7e2SAndroid Build Coastguard Worker    /**
469*cc02d7e2SAndroid Build Coastguard Worker     * Create a function which can be used to create ClientStreamingCall
470*cc02d7e2SAndroid Build Coastguard Worker     *
471*cc02d7e2SAndroid Build Coastguard Worker     * @param Channel|InterceptorChannel   $channel
472*cc02d7e2SAndroid Build Coastguard Worker     * @param callable $deserialize A function that deserializes the response
473*cc02d7e2SAndroid Build Coastguard Worker     *
474*cc02d7e2SAndroid Build Coastguard Worker     * @return \Closure
475*cc02d7e2SAndroid Build Coastguard Worker     */
476*cc02d7e2SAndroid Build Coastguard Worker    private function _StreamUnaryCallFactory($channel)
477*cc02d7e2SAndroid Build Coastguard Worker    {
478*cc02d7e2SAndroid Build Coastguard Worker        if (is_a($channel, 'Grpc\Internal\InterceptorChannel')) {
479*cc02d7e2SAndroid Build Coastguard Worker            return function ($method,
480*cc02d7e2SAndroid Build Coastguard Worker                             $deserialize,
481*cc02d7e2SAndroid Build Coastguard Worker                             array $metadata = [],
482*cc02d7e2SAndroid Build Coastguard Worker                             array $options = []) use ($channel) {
483*cc02d7e2SAndroid Build Coastguard Worker                return $channel->getInterceptor()->interceptStreamUnary(
484*cc02d7e2SAndroid Build Coastguard Worker                    $method,
485*cc02d7e2SAndroid Build Coastguard Worker                    $deserialize,
486*cc02d7e2SAndroid Build Coastguard Worker                    $this->_StreamUnaryCallFactory($channel->getNext()),
487*cc02d7e2SAndroid Build Coastguard Worker                    $metadata,
488*cc02d7e2SAndroid Build Coastguard Worker                    $options
489*cc02d7e2SAndroid Build Coastguard Worker                );
490*cc02d7e2SAndroid Build Coastguard Worker            };
491*cc02d7e2SAndroid Build Coastguard Worker        }
492*cc02d7e2SAndroid Build Coastguard Worker        return $this->_GrpcStreamUnary($channel);
493*cc02d7e2SAndroid Build Coastguard Worker    }
494*cc02d7e2SAndroid Build Coastguard Worker
495*cc02d7e2SAndroid Build Coastguard Worker    /**
496*cc02d7e2SAndroid Build Coastguard Worker     * Create a function which can be used to create BidiStreamingCall
497*cc02d7e2SAndroid Build Coastguard Worker     *
498*cc02d7e2SAndroid Build Coastguard Worker     * @param Channel|InterceptorChannel   $channel
499*cc02d7e2SAndroid Build Coastguard Worker     * @param callable $deserialize A function that deserializes the response
500*cc02d7e2SAndroid Build Coastguard Worker     *
501*cc02d7e2SAndroid Build Coastguard Worker     * @return \Closure
502*cc02d7e2SAndroid Build Coastguard Worker     */
503*cc02d7e2SAndroid Build Coastguard Worker    private function _StreamStreamCallFactory($channel)
504*cc02d7e2SAndroid Build Coastguard Worker    {
505*cc02d7e2SAndroid Build Coastguard Worker        if (is_a($channel, 'Grpc\Internal\InterceptorChannel')) {
506*cc02d7e2SAndroid Build Coastguard Worker            return function ($method,
507*cc02d7e2SAndroid Build Coastguard Worker                             $deserialize,
508*cc02d7e2SAndroid Build Coastguard Worker                             array $metadata = [],
509*cc02d7e2SAndroid Build Coastguard Worker                             array $options = []) use ($channel) {
510*cc02d7e2SAndroid Build Coastguard Worker                return $channel->getInterceptor()->interceptStreamStream(
511*cc02d7e2SAndroid Build Coastguard Worker                    $method,
512*cc02d7e2SAndroid Build Coastguard Worker                    $deserialize,
513*cc02d7e2SAndroid Build Coastguard Worker                    $this->_StreamStreamCallFactory($channel->getNext()),
514*cc02d7e2SAndroid Build Coastguard Worker                    $metadata,
515*cc02d7e2SAndroid Build Coastguard Worker                    $options
516*cc02d7e2SAndroid Build Coastguard Worker                );
517*cc02d7e2SAndroid Build Coastguard Worker            };
518*cc02d7e2SAndroid Build Coastguard Worker        }
519*cc02d7e2SAndroid Build Coastguard Worker        return $this->_GrpcStreamStream($channel);
520*cc02d7e2SAndroid Build Coastguard Worker    }
521*cc02d7e2SAndroid Build Coastguard Worker
522*cc02d7e2SAndroid Build Coastguard Worker    /* This class is intended to be subclassed by generated code, so
523*cc02d7e2SAndroid Build Coastguard Worker     * all functions begin with "_" to avoid name collisions. */
524*cc02d7e2SAndroid Build Coastguard Worker    /**
525*cc02d7e2SAndroid Build Coastguard Worker     * Call a remote method that takes a single argument and has a
526*cc02d7e2SAndroid Build Coastguard Worker     * single output.
527*cc02d7e2SAndroid Build Coastguard Worker     *
528*cc02d7e2SAndroid Build Coastguard Worker     * @param string   $method      The name of the method to call
529*cc02d7e2SAndroid Build Coastguard Worker     * @param mixed    $argument    The argument to the method
530*cc02d7e2SAndroid Build Coastguard Worker     * @param callable $deserialize A function that deserializes the response
531*cc02d7e2SAndroid Build Coastguard Worker     * @param array    $metadata    A metadata map to send to the server
532*cc02d7e2SAndroid Build Coastguard Worker     *                              (optional)
533*cc02d7e2SAndroid Build Coastguard Worker     * @param array    $options     An array of options (optional)
534*cc02d7e2SAndroid Build Coastguard Worker     *
535*cc02d7e2SAndroid Build Coastguard Worker     * @return UnaryCall The active call object
536*cc02d7e2SAndroid Build Coastguard Worker     */
537*cc02d7e2SAndroid Build Coastguard Worker    protected function _simpleRequest(
538*cc02d7e2SAndroid Build Coastguard Worker        $method,
539*cc02d7e2SAndroid Build Coastguard Worker        $argument,
540*cc02d7e2SAndroid Build Coastguard Worker        $deserialize,
541*cc02d7e2SAndroid Build Coastguard Worker        array $metadata = [],
542*cc02d7e2SAndroid Build Coastguard Worker        array $options = []
543*cc02d7e2SAndroid Build Coastguard Worker    ) {
544*cc02d7e2SAndroid Build Coastguard Worker        $call_factory = $this->_UnaryUnaryCallFactory($this->channel);
545*cc02d7e2SAndroid Build Coastguard Worker        $call = $call_factory($method, $argument, $deserialize, $metadata, $options);
546*cc02d7e2SAndroid Build Coastguard Worker        return $call;
547*cc02d7e2SAndroid Build Coastguard Worker    }
548*cc02d7e2SAndroid Build Coastguard Worker
549*cc02d7e2SAndroid Build Coastguard Worker    /**
550*cc02d7e2SAndroid Build Coastguard Worker     * Call a remote method that takes a stream of arguments and has a single
551*cc02d7e2SAndroid Build Coastguard Worker     * output.
552*cc02d7e2SAndroid Build Coastguard Worker     *
553*cc02d7e2SAndroid Build Coastguard Worker     * @param string   $method      The name of the method to call
554*cc02d7e2SAndroid Build Coastguard Worker     * @param callable $deserialize A function that deserializes the response
555*cc02d7e2SAndroid Build Coastguard Worker     * @param array    $metadata    A metadata map to send to the server
556*cc02d7e2SAndroid Build Coastguard Worker     *                              (optional)
557*cc02d7e2SAndroid Build Coastguard Worker     * @param array    $options     An array of options (optional)
558*cc02d7e2SAndroid Build Coastguard Worker     *
559*cc02d7e2SAndroid Build Coastguard Worker     * @return ClientStreamingCall The active call object
560*cc02d7e2SAndroid Build Coastguard Worker     */
561*cc02d7e2SAndroid Build Coastguard Worker    protected function _clientStreamRequest(
562*cc02d7e2SAndroid Build Coastguard Worker        $method,
563*cc02d7e2SAndroid Build Coastguard Worker        $deserialize,
564*cc02d7e2SAndroid Build Coastguard Worker        array $metadata = [],
565*cc02d7e2SAndroid Build Coastguard Worker        array $options = []
566*cc02d7e2SAndroid Build Coastguard Worker    ) {
567*cc02d7e2SAndroid Build Coastguard Worker        $call_factory = $this->_StreamUnaryCallFactory($this->channel);
568*cc02d7e2SAndroid Build Coastguard Worker        $call = $call_factory($method, $deserialize, $metadata, $options);
569*cc02d7e2SAndroid Build Coastguard Worker        return $call;
570*cc02d7e2SAndroid Build Coastguard Worker    }
571*cc02d7e2SAndroid Build Coastguard Worker
572*cc02d7e2SAndroid Build Coastguard Worker    /**
573*cc02d7e2SAndroid Build Coastguard Worker     * Call a remote method that takes a single argument and returns a stream
574*cc02d7e2SAndroid Build Coastguard Worker     * of responses.
575*cc02d7e2SAndroid Build Coastguard Worker     *
576*cc02d7e2SAndroid Build Coastguard Worker     * @param string   $method      The name of the method to call
577*cc02d7e2SAndroid Build Coastguard Worker     * @param mixed    $argument    The argument to the method
578*cc02d7e2SAndroid Build Coastguard Worker     * @param callable $deserialize A function that deserializes the responses
579*cc02d7e2SAndroid Build Coastguard Worker     * @param array    $metadata    A metadata map to send to the server
580*cc02d7e2SAndroid Build Coastguard Worker     *                              (optional)
581*cc02d7e2SAndroid Build Coastguard Worker     * @param array    $options     An array of options (optional)
582*cc02d7e2SAndroid Build Coastguard Worker     *
583*cc02d7e2SAndroid Build Coastguard Worker     * @return ServerStreamingCall The active call object
584*cc02d7e2SAndroid Build Coastguard Worker     */
585*cc02d7e2SAndroid Build Coastguard Worker    protected function _serverStreamRequest(
586*cc02d7e2SAndroid Build Coastguard Worker        $method,
587*cc02d7e2SAndroid Build Coastguard Worker        $argument,
588*cc02d7e2SAndroid Build Coastguard Worker        $deserialize,
589*cc02d7e2SAndroid Build Coastguard Worker        array $metadata = [],
590*cc02d7e2SAndroid Build Coastguard Worker        array $options = []
591*cc02d7e2SAndroid Build Coastguard Worker    ) {
592*cc02d7e2SAndroid Build Coastguard Worker        $call_factory = $this->_UnaryStreamCallFactory($this->channel);
593*cc02d7e2SAndroid Build Coastguard Worker        $call = $call_factory($method, $argument, $deserialize, $metadata, $options);
594*cc02d7e2SAndroid Build Coastguard Worker        return $call;
595*cc02d7e2SAndroid Build Coastguard Worker    }
596*cc02d7e2SAndroid Build Coastguard Worker
597*cc02d7e2SAndroid Build Coastguard Worker    /**
598*cc02d7e2SAndroid Build Coastguard Worker     * Call a remote method with messages streaming in both directions.
599*cc02d7e2SAndroid Build Coastguard Worker     *
600*cc02d7e2SAndroid Build Coastguard Worker     * @param string   $method      The name of the method to call
601*cc02d7e2SAndroid Build Coastguard Worker     * @param callable $deserialize A function that deserializes the responses
602*cc02d7e2SAndroid Build Coastguard Worker     * @param array    $metadata    A metadata map to send to the server
603*cc02d7e2SAndroid Build Coastguard Worker     *                              (optional)
604*cc02d7e2SAndroid Build Coastguard Worker     * @param array    $options     An array of options (optional)
605*cc02d7e2SAndroid Build Coastguard Worker     *
606*cc02d7e2SAndroid Build Coastguard Worker     * @return BidiStreamingCall The active call object
607*cc02d7e2SAndroid Build Coastguard Worker     */
608*cc02d7e2SAndroid Build Coastguard Worker    protected function _bidiRequest(
609*cc02d7e2SAndroid Build Coastguard Worker        $method,
610*cc02d7e2SAndroid Build Coastguard Worker        $deserialize,
611*cc02d7e2SAndroid Build Coastguard Worker        array $metadata = [],
612*cc02d7e2SAndroid Build Coastguard Worker        array $options = []
613*cc02d7e2SAndroid Build Coastguard Worker    ) {
614*cc02d7e2SAndroid Build Coastguard Worker        $call_factory = $this->_StreamStreamCallFactory($this->channel);
615*cc02d7e2SAndroid Build Coastguard Worker        $call = $call_factory($method, $deserialize, $metadata, $options);
616*cc02d7e2SAndroid Build Coastguard Worker        return $call;
617*cc02d7e2SAndroid Build Coastguard Worker    }
618*cc02d7e2SAndroid Build Coastguard Worker}
619